1 // wmcdplay - A cd player designed for WindowMaker
2 // Copyright (C) 1998 Sam Hawker <shawkie@geocities.com>
3 // This software comes with ABSOLUTELY NO WARRANTY
4 // This software is free software, and you are welcome to redistribute it
5 // under certain conditions
6 // See the README file for a more complete notice.
9 // Defines, includes and global variables
10 // --------------------------------------
12 // User defines - standard
13 #define WINDOWMAKER false
14 #define USESHAPE false
15 #define AFTERSTEP false
18 #define NAME "wmcdplay"
19 #define CLASS "WMCDPlay"
21 // User defines - custom
22 #define CDDEV "/dev/cdrom"
23 #define BACKCOLOR "#282828"
24 #define LEDCOLOR "green"
25 #define POSRELABS 0 // 0=relative position, 1=absolute position
26 #define UINTERVAL_N 1 // 20ths of a second
27 #define UINTERVAL_E 20 // 20ths of a second
29 // Includes - standard
36 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
37 #include "cdctl_freebsd.h"
42 // X-Windows includes - standard
45 #include <X11/Xutil.h>
46 #include <X11/Xproto.h>
48 #include <X11/extensions/shape.h>
64 // Xpm images - standard
65 #include "XPM/tile.xpm"
67 // Xpm images - artwork
68 #include "XPM/standard.art"
70 // Variables for command-line arguments - standard
71 bool wmaker
=WINDOWMAKER
;
75 char position
[256]="";
78 // Variables for command-line arguments - custom
79 char cddev
[256]=CDDEV
;
80 char backcolor
[256]=BACKCOLOR
;
81 char ledcolor
[256]=LEDCOLOR
;
85 int vol
=-1; // -1 means don't set volume
86 int uinterval_e
=UINTERVAL_E
;
88 // X-Windows basics - standard
89 Atom _XA_GNUSTEP_WM_FUNC
;
97 // X-Windows basics - custom
99 unsigned long color
[4];
102 // Misc custom global variables
103 // ----------------------------
105 // For artwork loading
112 int mode
=-1, track
=-1, pos
=-1;
113 int tdisplay
=POSRELABS
;
117 char chrset
[]="00112233445566778899 DDAATTNNOOCC--PPEE:;_";
122 // Procedures and functions
123 // ------------------------
125 // Procedures and functions - standard
126 void initXWin(int argc
, char **argv
);
128 void createWin(Window
*win
, int x
, int y
);
129 unsigned long getColor(char *colorname
);
130 unsigned long mixColor(char *colorname1
, int prop1
, char *colorname2
, int prop2
);
132 // Procedures and functions - custom
133 void scanArgs(int argc
, char **argv
);
134 void checkStatus(bool forced
);
135 void pressEvent(XButtonEvent
*xev
);
138 void drawText(int x
, int y
, char *text
);
140 // Procedures and functions - artwork basics
141 bool readArtwork(char *artfilen
);
142 char *readBlock(FILE *dfile
);
143 int arrayItems(char *buf
);
144 void readArrayInt(char *buf
, int *array
, int n
);
145 void readArrayBool(char *buf
, bool *array
, int n
);
147 // Procedures and functions - artwork specials
148 void createPixmap(const char **data
, char *buf
, Pixmap
*image
, Pixmap
*mask
, int *width
, int *height
);
149 void setBtnList(int *bset
);
150 bool inPolygon(int *points
, int px
, int py
);
156 int main(int argc
, char **argv
)
158 scanArgs(argc
, argv
);
159 initXWin(argc
, argv
);
161 color
[0]=mixColor(ledcolor
, 0, backcolor
, 100);
162 color
[1]=mixColor(ledcolor
, 100, backcolor
, 0);
163 color
[2]=mixColor(ledcolor
, 60, backcolor
, 40);
164 color
[3]=mixColor(ledcolor
, 25, backcolor
, 75);
167 artwrk
=readArtwork(artwrkf
);
170 createPixmap(cdplayer_xpm
, NULL
, &pm_cd
, &pm_cdmask
, NULL
, NULL
);
171 createPixmap(symbols_xpm
, NULL
, &pm_sym
, &pm_symmask
, &w
, &h
);
172 art_symsize
[0]=(w
+1)/11-1;
174 createPixmap(led_xpm
, NULL
, &pm_led
, NULL
, &w
, &h
);
175 art_ledsize
[0]=(w
+1)/strlen(chrset
)-1;
177 createPixmap(ledsym_xpm
, NULL
, &pm_sled
, NULL
, &w
, &h
);
178 art_ledsize
[2]=(w
+1)/6-1;
180 createPixmap(ledtsel_xpm
, NULL
, &pm_tled
, NULL
, &w
, &h
);
181 art_ledsize
[4]=(w
+1)/5-1;
184 art_actptr
=art_actions
;
186 setBtnList(art_btnptr
);
187 createPixmap(tile_xpm
, NULL
, &pm_tile
, NULL
, NULL
, NULL
);
188 pm_disp
= XCreatePixmap(d_display
, w_root
, 64, 64, DefaultDepth(d_display
, DefaultScreen(d_display
)));
189 pm_mask
= XCreatePixmap(d_display
, w_root
, 64, 64, 1);
193 gcm
=GCGraphicsExposures
;
194 gcv
.graphics_exposures
=false;
195 gc_gc
=XCreateGC(d_display
, w_root
, gcm
, &gcv
);
196 gc_bitgc
=XCreateGC(d_display
, pm_mask
, gcm
, &gcv
);
198 cdctl
=new CDCtl(cddev
);
201 fprintf(stderr
, "%s : Unable to open cdrom device '%s'.\n", NAME
, cddev
);
204 cdctl
->setVolume(vol
, vol
);
205 int tsels
[] = { tsNone
, tsNext
, tsRepeat
, tsRepeatCD
, tsRandom
};
206 cdctl
->setTrackSelection(tsels
[tsel
]);
211 XSelectInput(d_display
, w_activewin
, ButtonPress
| ExposureMask
);
212 XMapWindow(d_display
, w_main
);
216 while(XPending(d_display
)){
217 XNextEvent(d_display
, &xev
);
223 pressEvent(&xev
.xbutton
);
226 if((Atom
) xev
.xclient
.data
.l
[0]==deleteWin
)
232 if(ucount
>=((mode
==ssNoCD
|| mode
==ssTrayOpen
) ? uinterval_e
: UINTERVAL_N
))
238 XFreeGC(d_display
, gc_gc
);
239 XFreeGC(d_display
, gc_bitgc
);
240 XFreePixmap(d_display
, pm_tile
);
241 XFreePixmap(d_display
, pm_disp
);
242 XFreePixmap(d_display
, pm_mask
);
243 XFreePixmap(d_display
, pm_cd
);
244 XFreePixmap(d_display
, pm_cdmask
);
245 XFreePixmap(d_display
, pm_sym
);
246 XFreePixmap(d_display
, pm_symmask
);
247 XFreePixmap(d_display
, pm_led
);
248 XFreePixmap(d_display
, pm_sled
);
249 XFreePixmap(d_display
, pm_tled
);
260 void initXWin(int argc
, char **argv
){
261 winsize
=astep
? ASTEPSIZE
: NORMSIZE
;
263 if((d_display
=XOpenDisplay(display
))==NULL
){
264 fprintf(stderr
,"%s : Unable to open X display '%s'.\n", NAME
, XDisplayName(display
));
267 _XA_GNUSTEP_WM_FUNC
=XInternAtom(d_display
, "_GNUSTEP_WM_FUNCTION", false);
268 deleteWin
=XInternAtom(d_display
, "WM_DELETE_WINDOW", false);
270 w_root
=DefaultRootWindow(d_display
);
277 bool pos
=(XWMGeometry(d_display
, DefaultScreen(d_display
), position
, NULL
, 0, &shints
, &shints
.x
, &shints
.y
,
278 &shints
.width
, &shints
.height
, &shints
.win_gravity
) & (XValue
| YValue
));
279 shints
.min_width
=winsize
;
280 shints
.min_height
=winsize
;
281 shints
.max_width
=winsize
;
282 shints
.max_height
=winsize
;
283 shints
.base_width
=winsize
;
284 shints
.base_height
=winsize
;
285 shints
.flags
=PMinSize
| PMaxSize
| PBaseSize
;
287 createWin(&w_main
, shints
.x
, shints
.y
);
289 if(wmaker
|| astep
|| pos
)
290 shints
.flags
|= USPosition
;
292 wmhints
.initial_state
=WithdrawnState
;
293 wmhints
.flags
=WindowGroupHint
| StateHint
| IconWindowHint
;
294 createWin(&w_icon
, shints
.x
, shints
.y
);
296 wmhints
.icon_window
=w_icon
;
299 wmhints
.initial_state
=NormalState
;
300 wmhints
.flags
=WindowGroupHint
| StateHint
;
303 wmhints
.window_group
=w_main
;
304 XSetWMHints(d_display
, w_main
, &wmhints
);
305 XSetWMNormalHints(d_display
, w_main
, &shints
);
306 XSetCommand(d_display
, w_main
, argv
, argc
);
307 XStoreName(d_display
, w_main
, NAME
);
308 XSetIconName(d_display
, w_main
, NAME
);
309 XSetWMProtocols(d_display
, w_activewin
, &deleteWin
, 1);
313 XDestroyWindow(d_display
, w_main
);
315 XDestroyWindow(d_display
, w_icon
);
316 XCloseDisplay(d_display
);
319 void createWin(Window
*win
, int x
, int y
){
320 XClassHint classHint
;
321 *win
=XCreateSimpleWindow(d_display
, w_root
, x
, y
, winsize
, winsize
, 0, 0, 0);
322 classHint
.res_name
=const_cast<char *>(NAME
);
323 classHint
.res_class
=const_cast<char *>(CLASS
);
324 XSetClassHint(d_display
, *win
, &classHint
);
327 unsigned long getColor(char *colorname
){
329 XWindowAttributes winattr
;
330 XGetWindowAttributes(d_display
, w_root
, &winattr
);
332 XParseColor(d_display
, winattr
.colormap
, colorname
, &color
);
333 color
.flags
=DoRed
| DoGreen
| DoBlue
;
334 XAllocColor(d_display
, winattr
.colormap
, &color
);
338 unsigned long mixColor(char *colorname1
, int prop1
, char *colorname2
, int prop2
){
339 XColor color
, color1
, color2
;
340 XWindowAttributes winattr
;
341 XGetWindowAttributes(d_display
, w_root
, &winattr
);
342 XParseColor(d_display
, winattr
.colormap
, colorname1
, &color1
);
343 XParseColor(d_display
, winattr
.colormap
, colorname2
, &color2
);
345 color
.red
=(color1
.red
*prop1
+color2
.red
*prop2
)/(prop1
+prop2
);
346 color
.green
=(color1
.green
*prop1
+color2
.green
*prop2
)/(prop1
+prop2
);
347 color
.blue
=(color1
.blue
*prop1
+color2
.blue
*prop2
)/(prop1
+prop2
);
348 color
.flags
=DoRed
| DoGreen
| DoBlue
;
349 XAllocColor(d_display
, winattr
.colormap
, &color
);
353 void scanArgs(int argc
, char **argv
){
354 for(int i
=1;i
<argc
;i
++){
355 if(strcmp(argv
[i
], "-h")==0 || strcmp(argv
[i
], "-help")==0 || strcmp(argv
[i
], "--help")==0){
356 fprintf(stderr
, "wmcdplay - A cd player designed for WindowMaker\nRelease "VERSION
"\n");
357 fprintf(stderr
, "Copyright (C) 1998 Sam Hawker <shawkie@geocities.com>\n");
358 fprintf(stderr
, "This software comes with ABSOLUTELY NO WARRANTY\n");
359 fprintf(stderr
, "This software is free software, and you are welcome to redistribute it\n");
360 fprintf(stderr
, "under certain conditions\n");
361 fprintf(stderr
, "See the README file for a more complete notice.\n\n");
362 fprintf(stderr
, "usage:\n\n %s [options]\n\noptions:\n\n",argv
[0]);
363 fprintf(stderr
, " -h | -help | --help display this help screen\n");
364 fprintf(stderr
, " -w use WithdrawnState (for WindowMaker)\n");
365 fprintf(stderr
, " -s shaped window\n");
366 fprintf(stderr
, " -a use smaller window (for AfterStep Wharf)\n");
367 fprintf(stderr
, " -f artwork_file load the specified artwork file\n");
368 fprintf(stderr
, " -t track_selection set track selection (between 0 and 4)\n");
369 fprintf(stderr
, " -v volume set the cdrom volume (between 0 and 255)\n");
370 fprintf(stderr
, " -i interval interval in 1/20 seconds between cd polls when empty\n");
371 fprintf(stderr
, " -l led_color use the specified color for led displays\n");
372 fprintf(stderr
, " -b back_color use the specified color for backgrounds\n");
373 fprintf(stderr
, " -d cd_device use specified device (rather than /dev/cdrom)\n");
374 fprintf(stderr
, " -position position set window position (see X manual pages)\n");
375 fprintf(stderr
, " -display display select target display (see X manual pages)\n\n");
378 if(strcmp(argv
[i
], "-w")==0)
380 if(strcmp(argv
[i
], "-s")==0)
382 if(strcmp(argv
[i
], "-a")==0)
384 if(strcmp(argv
[i
], "-t")==0){
387 sscanf(argv
[i
], "%i", &tsel
);
391 if(strcmp(argv
[i
], "-v")==0){
394 sscanf(argv
[i
], "%i", &vol
);
398 if(strcmp(argv
[i
], "-i")==0){
401 sscanf(argv
[i
], "%i", &uinterval_e
);
405 if(strcmp(argv
[i
], "-f")==0){
409 sprintf(artwrkf
, "%s", argv
[i
]);
413 if(strcmp(argv
[i
], "-d")==0){
416 sprintf(cddev
, "%s", argv
[i
]);
420 if(strcmp(argv
[i
], "-l")==0){
423 sprintf(ledcolor
, "%s", argv
[i
]);
427 if(strcmp(argv
[i
], "-b")==0){
430 sprintf(backcolor
, "%s", argv
[i
]);
434 if(strcmp(argv
[i
], "-position")==0){
437 sprintf(position
, "%s", argv
[i
]);
441 if(strcmp(argv
[i
], "-display")==0){
444 sprintf(display
, "%s", argv
[i
]);
451 void checkStatus(bool forced
){
458 mode
=cdctl
->getStatusState();
459 track
=cdctl
->getStatusTrack();
465 pos
=cdctl
->getTrackStart(track
);
467 if(mode
==ssPlaying
|| mode
==ssPaused
){
469 pos
=cdctl
->getStatusPosRel();
471 pos
=cdctl
->getStatusPosAbs();
474 bool umode
=mode
!=oldmode
|| forced
;
475 bool utrack
=umode
|| (!(mode
==ssNoCD
|| mode
==ssTrayOpen
) && track
!=oldtrack
);
476 bool utimer
=utrack
|| ((mode
==ssPlaying
|| mode
==ssPaused
|| mode
==ssStopped
) && (int)(pos
/75)!=(int)(oldpos
/75));
482 if(mode
==ssNoCD
|| mode
==ssTrayOpen
)
483 sprintf(trackstr
, " ");
485 sprintf(trackstr
, "%2d", cdctl
->getStatusTrack());
487 drawText(art_ledpos
[1][0], art_ledpos
[1][1], trackstr
);
489 if(mode
==ssPlaying
|| mode
==ssPaused
|| mode
==ssStopped
){
492 remain
=cdctl
->getTrackLen(cdctl
->getStatusTrack())-pos
;
494 remain
=cdctl
->getCDLen()-pos
;
496 sprintf(timestr
, " -;%02d", remain
/75);
498 sprintf(timestr
, "%2d:%02d", (pos
/75)/60, (pos
/75)%60);
501 drawText(art_ledpos
[0][0], art_ledpos
[0][1], timestr
);
506 void pressEvent(XButtonEvent
*xev
){
507 int x
=xev
->x
-(winsize
/2-32);
508 int y
=xev
->y
-(winsize
/2-32);
510 for(int i
=0;i
<art_nbtns
;i
++){
511 if(inPolygon(&art_btnlist
[i
][2], x
, y
))
516 if(x
>=art_ledpos
[3][0] && y
>=art_ledpos
[3][1] && x
<=art_ledpos
[3][0]+art_ledsize
[4] && y
<=art_ledpos
[3][1]+art_ledsize
[5]){
517 int tsels
[] = { tsNone
, tsNext
, tsRepeat
, tsRepeatCD
, tsRandom
};
521 cdctl
->setTrackSelection(tsels
[tsel
]);
522 XCopyArea(d_display
, pm_tled
, pm_disp
, gc_gc
, (art_ledsize
[4]+1)*tsel
, 0, art_ledsize
[4], art_ledsize
[5], art_ledpos
[3][0], art_ledpos
[3][1]);
528 if(x
>=art_ledpos
[0][0] && y
>=art_ledpos
[0][1] && x
<=art_ledpos
[0][0]+(art_ledsize
[0]+1)*9-1 && y
<=art_ledpos
[0][1]+art_ledsize
[1]){
538 int action
=art_actptr
[6*btn
+mode
];
539 int acmds
[]={ acStop
, acPlay
, acPause
, acResume
, acPrev
, acNext
, acRewd
, acFFwd
, acEject
, acClose
};
541 int acmd
=acmds
[action
-1];
542 cdctl
->doAudioCommand(acmd
);
549 XCopyArea(d_display
, pm_disp
, w_activewin
, gc_gc
, 0, 0, 64, 64, winsize
/2-32, winsize
/2-32);
551 while(XCheckTypedEvent(d_display
, Expose
, &xev
));
556 sprintf(timestr
, "DA_TA");
558 sprintf(timestr
, "NO;CD");
560 sprintf(timestr
, "OP_EN");
562 XPoint mply
[art_nbtns
];
564 XSetForeground(d_display
, gc_bitgc
, 0);
565 XCopyArea(d_display
, pm_cdmask
, pm_mask
, gc_bitgc
, 0, 0, 64, 64, 0, 0);
566 for(int i
=0; i
<art_nbtns
; i
++){
567 if(art_actptr
[6*i
+mode
]==0 && art_hidebtns
){
568 for(int k
=0;k
<art_btnlist
[i
][2];k
++){
569 mply
[k
].x
=art_btnlist
[i
][k
*2+3];
570 mply
[k
].y
=art_btnlist
[i
][k
*2+4];
572 XFillPolygon(d_display
, pm_mask
, gc_bitgc
, (XPoint
*)mply
, art_btnlist
[i
][2], Convex
, CoordModeOrigin
);
575 if(!(wmaker
|| ushape
|| astep
)){
576 XCopyArea(d_display
, pm_tile
, pm_disp
, gc_gc
, 0, 0, 64, 64, 0, 0);
577 XSetClipMask(d_display
, gc_gc
, pm_mask
);
580 XCopyArea(d_display
, pm_cd
, pm_disp
, gc_gc
, 0, 0, 64, 64, 0, 0);
581 if(pm_symmask
!=None
){
582 XSetClipMask(d_display
, gc_gc
, pm_symmask
);
583 XSetClipMask(d_display
, gc_bitgc
, pm_symmask
);
585 XSetForeground(d_display
, gc_bitgc
, 1);
586 for(int i
=0;i
<art_nbtns
;i
++){
587 if(!(art_actptr
[6*i
+mode
]==0 && art_hidebtns
)){
588 int sympos
=(art_symsize
[0]+1)*(art_actptr
[6*i
+mode
]);
589 XSetClipOrigin(d_display
, gc_gc
, art_btnlist
[i
][0]-sympos
, art_btnlist
[i
][1]);
590 XSetClipOrigin(d_display
, gc_bitgc
, art_btnlist
[i
][0]-sympos
, art_btnlist
[i
][1]);
591 XCopyArea(d_display
, pm_sym
, pm_disp
, gc_gc
, sympos
, 0, art_symsize
[0], art_symsize
[1], art_btnlist
[i
][0], art_btnlist
[i
][1]);
592 XFillRectangle(d_display
, pm_mask
, gc_bitgc
, art_btnlist
[i
][0], art_btnlist
[i
][1], art_symsize
[0], art_symsize
[1]);
595 if(wmaker
|| ushape
|| astep
)
596 XShapeCombineMask(d_display
, w_activewin
, ShapeBounding
, winsize
/2-32, winsize
/2-32, pm_mask
, ShapeSet
);
597 XSetClipOrigin(d_display
, gc_gc
, 0, 0);
598 XSetClipOrigin(d_display
, gc_bitgc
, 0, 0);
599 XSetClipMask(d_display
, gc_gc
, None
);
600 XSetClipMask(d_display
, gc_bitgc
, None
);
602 XCopyArea(d_display
, pm_sled
, pm_disp
, gc_gc
, (art_ledsize
[2]+1)*mode
, 0, art_ledsize
[2], art_ledsize
[3], art_ledpos
[2][0], art_ledpos
[2][1]);
604 XCopyArea(d_display
, pm_tled
, pm_disp
, gc_gc
, (art_ledsize
[4]+1)*tsel
, 0, art_ledsize
[4], art_ledsize
[5], art_ledpos
[3][0], art_ledpos
[3][1]);
607 void drawText(int x
, int y
, char *text
){
609 for(size_t i
=0;i
<strlen(text
);i
++){
610 char *chrptr
=strchr(chrset
,text
[i
]);
612 int chrindex
=chrptr
-chrset
;
613 int chrwidth
=art_ledsize
[0];
614 if(chrset
[chrindex
+1]==text
[i
])
615 chrwidth
=2*art_ledsize
[0]+1;
616 XCopyArea(d_display
, pm_led
, pm_disp
, gc_gc
, chrindex
*(art_ledsize
[0]+1), 0, chrwidth
, art_ledsize
[1], drawx
, y
);
622 bool readArtwork(char *artfilen
){
624 char artfilenbuf
[256];
625 artfile
=fopen(artfilen
, "r");
627 if(strchr(artfilen
, '/')!=NULL
){
628 fprintf(stderr
, "%s : Unable to open artwork file '%s'.\n", NAME
, artfilen
);
631 sprintf(artfilenbuf
, "%s/.wmcdplay/%s", getenv("HOME"), artfilen
);
632 artfile
=fopen(artfilenbuf
, "r");
634 sprintf(artfilenbuf
, "%s%s", SYSARTDIR
, artfilen
);
635 artfile
=fopen(artfilenbuf
, "r");
637 fprintf(stderr
,"%s : Tried to find artwork file, but failed.\n", NAME
);
646 if (fgets(buf
, 250, artfile
) == NULL
) {
647 fprintf(stderr
,"%s : Error reading artwork file.\n", NAME
);
650 done
=(feof(artfile
)!=0);
654 const char *keystr
[]={ "int art_nbtns=",
655 "bool art_hidebtns=",
656 "bool art_showled[4]=",
657 "int art_ledpos[4][2]=",
659 "int art_actions[]=",
661 for(int i
=0;i
<7;i
++){
662 if(strncmp(buf
, keystr
[i
], strlen(keystr
[i
]))==0){
669 sscanf(buf
+strlen(keystr
[keynum
-1]), "%d", &art_nbtns
);
672 art_hidebtns
=(strstr(buf
+strlen(keystr
[keynum
-1]), "true")!=NULL
);
675 readArrayBool((char *)buf
, (bool *)art_showled
, 4);
678 readArrayInt((char *)buf
, (int *)art_ledpos
, 8);
681 fseek(artfile
, -strlen(buf
), SEEK_CUR
);
682 char *block
=readBlock(artfile
);
685 int items
=arrayItems(block
);
686 art_btnptr
=(int *)malloc(sizeof(int)*items
);
687 readArrayInt(block
, art_btnptr
, items
);
691 int items
=arrayItems(block
);
692 art_actptr
=(int *)malloc(sizeof(int)*items
);
693 readArrayInt(block
, art_actptr
, items
);
698 strncpy(buf
, strchr(block
+strlen(keystr
[keynum
-1]), '\n')+1, 250);
699 *strchr(buf
, '\n')='\0';
702 if(strncmp(buf
, "static const char * cdplayer_xpm", strlen("static const char * cdplayer_xpm"))==0)
703 createPixmap(NULL
, block
, &pm_cd
, &pm_cdmask
, NULL
, NULL
);
704 if(strncmp(buf
, "static const char * symbols_xpm", strlen("static const char * symbols_xpm"))==0){
705 createPixmap(NULL
, block
, &pm_sym
, &pm_symmask
, &w
, &h
);
706 art_symsize
[0]=(w
+1)/11-1;
709 if(strncmp(buf
, "static const char * led_xpm", strlen("static const char * led_xpm"))==0){
710 createPixmap(NULL
, block
, &pm_led
, NULL
, &w
, &h
);
711 art_ledsize
[0]=(w
+1)/strlen(chrset
)-1;
714 if(strncmp(buf
, "static const char * ledsym_xpm", strlen("static const char * ledsym_xpm"))==0){
715 createPixmap(NULL
, block
, &pm_sled
, NULL
, &w
, &h
);
716 art_ledsize
[2]=(w
+1)/6-1;
719 if(strncmp(buf
, "static const char * ledtsel_xpm", strlen("static const char * ledtsel_xpm"))==0){
720 createPixmap(NULL
, block
, &pm_tled
, NULL
, &w
, &h
);
721 art_ledsize
[4]=(w
+1)/5-1;
734 char *readBlock(FILE *dfile
){
739 if (fgets(buf
, 250, dfile
) == NULL
) {
740 fprintf(stderr
,"%s : Error reading artwork file.\n", NAME
);
743 int buflen
=strlen(buf
);
744 block
=(char *)realloc(block
, sizeof(char)*(bytes
+buflen
+1));
745 strcpy(block
+bytes
, buf
);
747 } while(strstr(buf
, "}")==NULL
);
751 int arrayItems(char *buf
){
754 while((bufptr
=strstr(bufptr
, ","))!=NULL
){
761 void readArrayInt(char *buf
, int *array
, int n
){
763 bufptr
=strtok(buf
, "{,}");
764 for(int i
=0;i
<n
;i
++){
765 bufptr
=strtok(NULL
, "{,}");
766 sscanf(bufptr
, "%d", &array
[i
]);
770 void readArrayBool(char *buf
, bool *array
, int n
){
772 bufptr
=strtok(buf
, "{,}");
773 for(int i
=0;i
<n
;i
++){
774 bufptr
=strtok(NULL
, "{,}");
775 array
[i
]=(strstr(bufptr
, "true")!=NULL
);
779 void createPixmap(const char **data
, char *buf
, Pixmap
*image
, Pixmap
*mask
, int *width
, int *height
){
780 XpmAttributes xpmattr
;
781 XpmColorSymbol xpmcsym
[4]={
782 {const_cast<char *>("back_color"), NULL
, color
[0]},
783 {const_cast<char *>("led_color_high"), NULL
, color
[1]},
784 {const_cast<char *>("led_color_med"), NULL
, color
[2]},
785 {const_cast<char *>("led_color_low"), NULL
, color
[3]}};
786 xpmattr
.numsymbols
=4;
787 xpmattr
.colorsymbols
=xpmcsym
;
788 xpmattr
.exactColors
=false;
789 xpmattr
.closeness
=40000;
790 xpmattr
.valuemask
=XpmColorSymbols
| XpmExactColors
| XpmCloseness
| XpmSize
;
792 XpmCreatePixmapFromData(d_display
, w_root
, const_cast<char **>(data
),
793 image
, mask
, &xpmattr
);
795 XpmCreatePixmapFromBuffer(d_display
, w_root
, buf
, image
, mask
, &xpmattr
);
797 *width
=xpmattr
.width
;
799 *height
=xpmattr
.height
;
802 void setBtnList(int *bset
){
803 // Create a list of pointers to button data.
804 // So, for example, data for button 2 can be accessed as art_btnlist[2];
805 // Also, the y co-ordinate of its symbol would be art_btnlist[2][1]
807 art_btnlist
=(int **)malloc(art_nbtns
*sizeof(int *));
809 for(int i
=0;i
<art_nbtns
;i
++){
810 art_btnlist
[i
]=&bset
[0+curpos
];
811 curpos
+=2*art_btnlist
[i
][2]+3;
815 bool inPolygon(int *points
, int px
, int py
){
819 for(int i
=1;i
<=points
[0];i
++){