1 // wmcdplay - A cd player designed for WindowMaker
2 // 05/09/98 Release 1.0 Beta1
3 // Copyright (C) 1998 Sam Hawker <shawkie@geocities.com>
4 // This software comes with ABSOLUTELY NO WARRANTY
5 // This software is free software, and you are welcome to redistribute it
6 // under certain conditions
7 // See the README file for a more complete notice.
10 // Defines, includes and global variables
11 // --------------------------------------
13 // User defines - standard
14 #define WINDOWMAKER false
15 #define USESHAPE false
16 #define AFTERSTEP false
19 #define NAME "wmcdplay"
20 #define CLASS "WMCDPlay"
22 // User defines - custom
23 #define SYSARTDIR "/usr/X11R6/lib/X11/wmcdplay/"
24 #define CDDEV "/dev/cdrom"
25 #define BACKCOLOR "#282828"
26 #define LEDCOLOR "green"
27 #define POSRELABS 0 // 0=relative position, 1=absolute position
28 #define UINTERVAL_N 1 // 20ths of a second
29 #define UINTERVAL_E 20 // 20ths of a second
31 // Includes - standard
40 // X-Windows includes - standard
43 #include <X11/Xutil.h>
44 #include <X11/Xproto.h>
46 #include <X11/extensions/shape.h>
62 // Xpm images - standard
63 #include "XPM/tile.xpm"
65 // Xpm images - artwork
66 #include "XPM/standard.art"
68 // Variables for command-line arguments - standard
69 bool wmaker
=WINDOWMAKER
;
73 char position
[256]="";
76 // Variables for command-line arguments - custom
77 char cddev
[256]=CDDEV
;
78 char backcolor
[256]=BACKCOLOR
;
79 char ledcolor
[256]=LEDCOLOR
;
83 int vol
=-1; // -1 means don't set volume
84 int uinterval_e
=UINTERVAL_E
;
86 // X-Windows basics - standard
87 Atom _XA_GNUSTEP_WM_FUNC
;
95 // X-Windows basics - custom
97 unsigned long color
[4];
100 // Misc custom global variables
101 // ----------------------------
103 // For artwork loading
110 int mode
=-1, track
=-1, pos
=-1;
111 int tdisplay
=POSRELABS
;
115 char chrset
[]="00112233445566778899 DDAATTNNOOCC--PPEE:;_";
120 // Procedures and functions
121 // ------------------------
123 // Procedures and functions - standard
124 void initXWin(int argc
, char **argv
);
126 void createWin(Window
*win
, int x
, int y
);
127 unsigned long getColor(char *colorname
);
128 unsigned long mixColor(char *colorname1
, int prop1
, char *colorname2
, int prop2
);
130 // Procedures and functions - custom
131 void scanArgs(int argc
, char **argv
);
132 void checkStatus(bool forced
);
133 void pressEvent(XButtonEvent
*xev
);
136 void drawText(int x
, int y
, char *text
);
138 // Procedures and functions - artwork basics
139 bool readArtwork(char *artfilen
);
140 char *readBlock(FILE *dfile
);
141 int arrayItems(char *buf
);
142 void readArrayInt(char *buf
, int *array
, int n
);
143 void readArrayBool(char *buf
, bool *array
, int n
);
145 // Procedures and functions - artwork specials
146 void createPixmap(char **data
, char *buf
, Pixmap
*image
, Pixmap
*mask
, int *width
, int *height
);
147 void setBtnList(int *bset
);
148 bool inPolygon(int *points
, int px
, int py
);
154 int main(int argc
, char **argv
)
156 scanArgs(argc
, argv
);
157 initXWin(argc
, argv
);
159 color
[0]=mixColor(ledcolor
, 0, backcolor
, 100);
160 color
[1]=mixColor(ledcolor
, 100, backcolor
, 0);
161 color
[2]=mixColor(ledcolor
, 60, backcolor
, 40);
162 color
[3]=mixColor(ledcolor
, 25, backcolor
, 75);
165 artwrk
=readArtwork(artwrkf
);
168 createPixmap(cdplayer_xpm
, NULL
, &pm_cd
, &pm_cdmask
, NULL
, NULL
);
169 createPixmap(symbols_xpm
, NULL
, &pm_sym
, &pm_symmask
, &w
, &h
);
170 art_symsize
[0]=(w
+1)/11-1;
172 createPixmap(led_xpm
, NULL
, &pm_led
, NULL
, &w
, &h
);
173 art_ledsize
[0]=(w
+1)/strlen(chrset
)-1;
175 createPixmap(ledsym_xpm
, NULL
, &pm_sled
, NULL
, &w
, &h
);
176 art_ledsize
[2]=(w
+1)/6-1;
178 createPixmap(ledtsel_xpm
, NULL
, &pm_tled
, NULL
, &w
, &h
);
179 art_ledsize
[4]=(w
+1)/5-1;
182 art_actptr
=art_actions
;
184 setBtnList(art_btnptr
);
185 createPixmap(tile_xpm
, NULL
, &pm_tile
, NULL
, NULL
, NULL
);
186 pm_disp
= XCreatePixmap(d_display
, w_root
, 64, 64, DefaultDepth(d_display
, DefaultScreen(d_display
)));
187 pm_mask
= XCreatePixmap(d_display
, w_root
, 64, 64, 1);
191 gcm
=GCGraphicsExposures
;
192 gcv
.graphics_exposures
=false;
193 gc_gc
=XCreateGC(d_display
, w_root
, gcm
, &gcv
);
194 gc_bitgc
=XCreateGC(d_display
, pm_mask
, gcm
, &gcv
);
196 cdctl
=new CDCtl(cddev
);
199 fprintf(stderr
, "%s : Unable to open cdrom device '%s'.\n", NAME
, cddev
);
202 cdctl
->setVolume(vol
, vol
);
203 int tsels
[] = { tsNone
, tsNext
, tsRepeat
, tsRepeatCD
, tsRandom
};
204 cdctl
->setTrackSelection(tsels
[tsel
]);
209 XSelectInput(d_display
, w_activewin
, ButtonPress
| ExposureMask
);
210 XMapWindow(d_display
, w_main
);
214 while(XPending(d_display
)){
215 XNextEvent(d_display
, &xev
);
221 pressEvent(&xev
.xbutton
);
224 if(xev
.xclient
.data
.l
[0]==deleteWin
)
230 if(ucount
>=((mode
==ssNoCD
|| mode
==ssTrayOpen
) ? uinterval_e
: UINTERVAL_N
))
236 XFreeGC(d_display
, gc_gc
);
237 XFreeGC(d_display
, gc_bitgc
);
238 XFreePixmap(d_display
, pm_tile
);
239 XFreePixmap(d_display
, pm_disp
);
240 XFreePixmap(d_display
, pm_mask
);
241 XFreePixmap(d_display
, pm_cd
);
242 XFreePixmap(d_display
, pm_cdmask
);
243 XFreePixmap(d_display
, pm_sym
);
244 XFreePixmap(d_display
, pm_symmask
);
245 XFreePixmap(d_display
, pm_led
);
246 XFreePixmap(d_display
, pm_sled
);
247 XFreePixmap(d_display
, pm_tled
);
258 void initXWin(int argc
, char **argv
){
259 winsize
=astep
? ASTEPSIZE
: NORMSIZE
;
261 if((d_display
=XOpenDisplay(display
))==NULL
){
262 fprintf(stderr
,"%s : Unable to open X display '%s'.\n", NAME
, XDisplayName(display
));
265 _XA_GNUSTEP_WM_FUNC
=XInternAtom(d_display
, "_GNUSTEP_WM_FUNCTION", false);
266 deleteWin
=XInternAtom(d_display
, "WM_DELETE_WINDOW", false);
268 w_root
=DefaultRootWindow(d_display
);
275 bool pos
=(XWMGeometry(d_display
, DefaultScreen(d_display
), position
, NULL
, 0, &shints
, &shints
.x
, &shints
.y
,
276 &shints
.width
, &shints
.height
, &shints
.win_gravity
) & (XValue
| YValue
));
277 shints
.min_width
=winsize
;
278 shints
.min_height
=winsize
;
279 shints
.max_width
=winsize
;
280 shints
.max_height
=winsize
;
281 shints
.base_width
=winsize
;
282 shints
.base_height
=winsize
;
283 shints
.flags
=PMinSize
| PMaxSize
| PBaseSize
;
285 createWin(&w_main
, shints
.x
, shints
.y
);
287 if(wmaker
|| astep
|| pos
)
288 shints
.flags
|= USPosition
;
290 wmhints
.initial_state
=WithdrawnState
;
291 wmhints
.flags
=WindowGroupHint
| StateHint
| IconWindowHint
;
292 createWin(&w_icon
, shints
.x
, shints
.y
);
294 wmhints
.icon_window
=w_icon
;
297 wmhints
.initial_state
=NormalState
;
298 wmhints
.flags
=WindowGroupHint
| StateHint
;
301 wmhints
.window_group
=w_main
;
302 XSetWMHints(d_display
, w_main
, &wmhints
);
303 XSetWMNormalHints(d_display
, w_main
, &shints
);
304 XSetCommand(d_display
, w_main
, argv
, argc
);
305 XStoreName(d_display
, w_main
, NAME
);
306 XSetIconName(d_display
, w_main
, NAME
);
307 XSetWMProtocols(d_display
, w_activewin
, &deleteWin
, 1);
311 XDestroyWindow(d_display
, w_main
);
313 XDestroyWindow(d_display
, w_icon
);
314 XCloseDisplay(d_display
);
317 void createWin(Window
*win
, int x
, int y
){
318 XClassHint classHint
;
319 *win
=XCreateSimpleWindow(d_display
, w_root
, x
, y
, winsize
, winsize
, 0, 0, 0);
320 classHint
.res_name
=NAME
;
321 classHint
.res_class
=CLASS
;
322 XSetClassHint(d_display
, *win
, &classHint
);
325 unsigned long getColor(char *colorname
){
327 XWindowAttributes winattr
;
328 XGetWindowAttributes(d_display
, w_root
, &winattr
);
330 XParseColor(d_display
, winattr
.colormap
, colorname
, &color
);
331 color
.flags
=DoRed
| DoGreen
| DoBlue
;
332 XAllocColor(d_display
, winattr
.colormap
, &color
);
336 unsigned long mixColor(char *colorname1
, int prop1
, char *colorname2
, int prop2
){
337 XColor color
, color1
, color2
;
338 XWindowAttributes winattr
;
339 XGetWindowAttributes(d_display
, w_root
, &winattr
);
340 XParseColor(d_display
, winattr
.colormap
, colorname1
, &color1
);
341 XParseColor(d_display
, winattr
.colormap
, colorname2
, &color2
);
343 color
.red
=(color1
.red
*prop1
+color2
.red
*prop2
)/(prop1
+prop2
);
344 color
.green
=(color1
.green
*prop1
+color2
.green
*prop2
)/(prop1
+prop2
);
345 color
.blue
=(color1
.blue
*prop1
+color2
.blue
*prop2
)/(prop1
+prop2
);
346 color
.flags
=DoRed
| DoGreen
| DoBlue
;
347 XAllocColor(d_display
, winattr
.colormap
, &color
);
351 void scanArgs(int argc
, char **argv
){
352 for(int i
=1;i
<argc
;i
++){
353 if(strcmp(argv
[i
], "-h")==0 || strcmp(argv
[i
], "-help")==0 || strcmp(argv
[i
], "--help")==0){
354 fprintf(stderr
, "wmcdplay - A cd player designed for WindowMaker\n05/09/98 Release 1.0 Beta1\n");
355 fprintf(stderr
, "Copyright (C) 1998 Sam Hawker <shawkie@geocities.com>\n");
356 fprintf(stderr
, "This software comes with ABSOLUTELY NO WARRANTY\n");
357 fprintf(stderr
, "This software is free software, and you are welcome to redistribute it\n");
358 fprintf(stderr
, "under certain conditions\n");
359 fprintf(stderr
, "See the README file for a more complete notice.\n\n");
360 fprintf(stderr
, "usage:\n\n %s [options]\n\noptions:\n\n",argv
[0]);
361 fprintf(stderr
, " -h | -help | --help display this help screen\n");
362 fprintf(stderr
, " -w use WithdrawnState (for WindowMaker)\n");
363 fprintf(stderr
, " -s shaped window\n");
364 fprintf(stderr
, " -a use smaller window (for AfterStep Wharf)\n");
365 fprintf(stderr
, " -f artwork_file load the specified artwork file\n");
366 fprintf(stderr
, " -t track_selection set track selection (between 0 and 4)\n");
367 fprintf(stderr
, " -v volume set the cdrom volume (between 0 and 255)\n");
368 fprintf(stderr
, " -i interval interval in 1/20 seconds between cd polls when empty\n");
369 fprintf(stderr
, " -l led_color use the specified color for led displays\n");
370 fprintf(stderr
, " -b back_color use the specified color for backgrounds\n");
371 fprintf(stderr
, " -d cd_device use specified device (rather than /dev/cdrom)\n");
372 fprintf(stderr
, " -position position set window position (see X manual pages)\n");
373 fprintf(stderr
, " -display display select target display (see X manual pages)\n\n");
376 if(strcmp(argv
[i
], "-w")==0)
378 if(strcmp(argv
[i
], "-s")==0)
380 if(strcmp(argv
[i
], "-a")==0)
382 if(strcmp(argv
[i
], "-t")==0){
385 sscanf(argv
[i
], "%i", &tsel
);
389 if(strcmp(argv
[i
], "-v")==0){
392 sscanf(argv
[i
], "%i", &vol
);
396 if(strcmp(argv
[i
], "-i")==0){
399 sscanf(argv
[i
], "%i", &uinterval_e
);
403 if(strcmp(argv
[i
], "-f")==0){
407 sprintf(artwrkf
, "%s", argv
[i
]);
411 if(strcmp(argv
[i
], "-d")==0){
414 sprintf(cddev
, "%s", argv
[i
]);
418 if(strcmp(argv
[i
], "-l")==0){
421 sprintf(ledcolor
, "%s", argv
[i
]);
425 if(strcmp(argv
[i
], "-b")==0){
428 sprintf(backcolor
, "%s", argv
[i
]);
432 if(strcmp(argv
[i
], "-position")==0){
435 sprintf(position
, "%s", argv
[i
]);
439 if(strcmp(argv
[i
], "-display")==0){
442 sprintf(display
, "%s", argv
[i
]);
449 void checkStatus(bool forced
){
456 mode
=cdctl
->getStatusState();
457 track
=cdctl
->getStatusTrack();
463 pos
=cdctl
->getTrackStart(track
);
465 if(mode
==ssPlaying
|| mode
==ssPaused
){
467 pos
=cdctl
->getStatusPosRel();
469 pos
=cdctl
->getStatusPosAbs();
472 bool umode
=mode
!=oldmode
|| forced
;
473 bool utrack
=umode
|| (!(mode
==ssNoCD
|| mode
==ssTrayOpen
) && track
!=oldtrack
);
474 bool utimer
=utrack
|| ((mode
==ssPlaying
|| mode
==ssPaused
|| mode
==ssStopped
) && (int)(pos
/75)!=(int)(oldpos
/75));
480 if(mode
==ssNoCD
|| mode
==ssTrayOpen
)
481 sprintf(trackstr
, " ");
483 sprintf(trackstr
, "%2d", cdctl
->getStatusTrack());
485 drawText(art_ledpos
[1][0], art_ledpos
[1][1], trackstr
);
487 if(mode
==ssPlaying
|| mode
==ssPaused
|| mode
==ssStopped
){
490 remain
=cdctl
->getTrackLen(cdctl
->getStatusTrack())-pos
;
492 remain
=cdctl
->getCDLen()-pos
;
494 sprintf(timestr
, " -;%02d", remain
/75);
496 sprintf(timestr
, "%2d:%02d", (pos
/75)/60, (pos
/75)%60);
499 drawText(art_ledpos
[0][0], art_ledpos
[0][1], timestr
);
504 void pressEvent(XButtonEvent
*xev
){
505 int x
=xev
->x
-(winsize
/2-32);
506 int y
=xev
->y
-(winsize
/2-32);
508 for(int i
=0;i
<art_nbtns
;i
++){
509 if(inPolygon(&art_btnlist
[i
][2], x
, y
))
514 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]){
515 int tsels
[] = { tsNone
, tsNext
, tsRepeat
, tsRepeatCD
, tsRandom
};
519 cdctl
->setTrackSelection(tsels
[tsel
]);
520 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]);
526 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]){
536 int action
=art_actptr
[6*btn
+mode
];
537 int acmds
[]={ acStop
, acPlay
, acPause
, acResume
, acPrev
, acNext
, acRewd
, acFFwd
, acEject
, acClose
};
539 int acmd
=acmds
[action
-1];
540 cdctl
->doAudioCommand(acmd
);
547 XCopyArea(d_display
, pm_disp
, w_activewin
, gc_gc
, 0, 0, 64, 64, winsize
/2-32, winsize
/2-32);
549 while(XCheckTypedEvent(d_display
, Expose
, &xev
));
554 sprintf(timestr
, "DA_TA");
556 sprintf(timestr
, "NO;CD");
558 sprintf(timestr
, "OP_EN");
560 XPoint mply
[art_nbtns
];
562 XSetForeground(d_display
, gc_bitgc
, 0);
563 XCopyArea(d_display
, pm_cdmask
, pm_mask
, gc_bitgc
, 0, 0, 64, 64, 0, 0);
564 for(int i
=0; i
<art_nbtns
; i
++){
565 if(art_actptr
[6*i
+mode
]==0 && art_hidebtns
){
566 for(int k
=0;k
<art_btnlist
[i
][2];k
++){
567 mply
[k
].x
=art_btnlist
[i
][k
*2+3];
568 mply
[k
].y
=art_btnlist
[i
][k
*2+4];
570 XFillPolygon(d_display
, pm_mask
, gc_bitgc
, (XPoint
*)mply
, art_btnlist
[i
][2], Convex
, CoordModeOrigin
);
573 if(!(wmaker
|| ushape
|| astep
)){
574 XCopyArea(d_display
, pm_tile
, pm_disp
, gc_gc
, 0, 0, 64, 64, 0, 0);
575 XSetClipMask(d_display
, gc_gc
, pm_mask
);
578 XCopyArea(d_display
, pm_cd
, pm_disp
, gc_gc
, 0, 0, 64, 64, 0, 0);
579 if(pm_symmask
!=None
){
580 XSetClipMask(d_display
, gc_gc
, pm_symmask
);
581 XSetClipMask(d_display
, gc_bitgc
, pm_symmask
);
583 XSetForeground(d_display
, gc_bitgc
, 1);
584 for(int i
=0;i
<art_nbtns
;i
++){
585 if(!(art_actptr
[6*i
+mode
]==0 && art_hidebtns
)){
586 int sympos
=(art_symsize
[0]+1)*(art_actptr
[6*i
+mode
]);
587 XSetClipOrigin(d_display
, gc_gc
, art_btnlist
[i
][0]-sympos
, art_btnlist
[i
][1]);
588 XSetClipOrigin(d_display
, gc_bitgc
, art_btnlist
[i
][0]-sympos
, art_btnlist
[i
][1]);
589 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]);
590 XFillRectangle(d_display
, pm_mask
, gc_bitgc
, art_btnlist
[i
][0], art_btnlist
[i
][1], art_symsize
[0], art_symsize
[1]);
593 if(wmaker
|| ushape
|| astep
)
594 XShapeCombineMask(d_display
, w_activewin
, ShapeBounding
, winsize
/2-32, winsize
/2-32, pm_mask
, ShapeSet
);
595 XSetClipOrigin(d_display
, gc_gc
, 0, 0);
596 XSetClipOrigin(d_display
, gc_bitgc
, 0, 0);
597 XSetClipMask(d_display
, gc_gc
, None
);
598 XSetClipMask(d_display
, gc_bitgc
, None
);
600 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]);
602 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]);
605 void drawText(int x
, int y
, char *text
){
607 for(int i
=0;i
<strlen(text
);i
++){
608 char *chrptr
=strchr(chrset
,text
[i
]);
610 int chrindex
=chrptr
-chrset
;
611 int chrwidth
=art_ledsize
[0];
612 if(chrset
[chrindex
+1]==text
[i
])
613 chrwidth
=2*art_ledsize
[0]+1;
614 XCopyArea(d_display
, pm_led
, pm_disp
, gc_gc
, chrindex
*(art_ledsize
[0]+1), 0, chrwidth
, art_ledsize
[1], drawx
, y
);
620 bool readArtwork(char *artfilen
){
622 char artfilenbuf
[256];
623 artfile
=fopen(artfilen
, "r");
625 if(strchr(artfilen
, '/')!=NULL
){
626 fprintf(stderr
, "%s : Unable to open artwork file '%s'.\n", NAME
, artfilen
);
629 sprintf(artfilenbuf
, "%s/.wmcdplay/%s", getenv("HOME"), artfilen
);
630 artfile
=fopen(artfilenbuf
, "r");
632 sprintf(artfilenbuf
, "%s%s", SYSARTDIR
, artfilen
);
633 artfile
=fopen(artfilenbuf
, "r");
635 fprintf(stderr
,"%s : Tried to find artwork file, but failed.\n", NAME
);
644 fgets(buf
, 250, artfile
);
645 done
=(feof(artfile
)!=0);
649 char *keystr
[]={ "int art_nbtns=",
650 "bool art_hidebtns=",
651 "bool art_showled[4]=",
652 "int art_ledpos[4][2]=",
654 "int art_actions[]=",
656 for(int i
=0;i
<7;i
++){
657 if(strncmp(buf
, keystr
[i
], strlen(keystr
[i
]))==0){
664 sscanf(buf
+strlen(keystr
[keynum
-1]), "%d", &art_nbtns
);
667 art_hidebtns
=(strstr(buf
+strlen(keystr
[keynum
-1]), "true")!=NULL
);
670 readArrayBool((char *)buf
, (bool *)art_showled
, 4);
673 readArrayInt((char *)buf
, (int *)art_ledpos
, 8);
676 fseek(artfile
, -strlen(buf
), SEEK_CUR
);
677 char *block
=readBlock(artfile
);
680 int items
=arrayItems(block
);
681 art_btnptr
=(int *)malloc(sizeof(int)*items
);
682 readArrayInt(block
, art_btnptr
, items
);
686 int items
=arrayItems(block
);
687 art_actptr
=(int *)malloc(sizeof(int)*items
);
688 readArrayInt(block
, art_actptr
, items
);
693 strncpy(buf
, strchr(block
+strlen(keystr
[keynum
-1]), '\n')+1, 250);
694 *strchr(buf
, '\n')='\0';
697 if(strncmp(buf
, "static char * cdplayer_xpm", strlen("static char * cdplayer_xpm"))==0)
698 createPixmap(NULL
, block
, &pm_cd
, &pm_cdmask
, NULL
, NULL
);
699 if(strncmp(buf
, "static char * symbols_xpm", strlen("static char * symbols_xpm"))==0){
700 createPixmap(NULL
, block
, &pm_sym
, &pm_symmask
, &w
, &h
);
701 art_symsize
[0]=(w
+1)/11-1;
704 if(strncmp(buf
, "static char * led_xpm", strlen("static char * led_xpm"))==0){
705 createPixmap(NULL
, block
, &pm_led
, NULL
, &w
, &h
);
706 art_ledsize
[0]=(w
+1)/strlen(chrset
)-1;
709 if(strncmp(buf
, "static char * ledsym_xpm", strlen("static char * ledsym_xpm"))==0){
710 createPixmap(NULL
, block
, &pm_sled
, NULL
, &w
, &h
);
711 art_ledsize
[2]=(w
+1)/6-1;
714 if(strncmp(buf
, "static char * ledtsel_xpm", strlen("static char * ledtsel_xpm"))==0){
715 createPixmap(NULL
, block
, &pm_tled
, NULL
, &w
, &h
);
716 art_ledsize
[4]=(w
+1)/5-1;
729 char *readBlock(FILE *dfile
){
734 fgets(buf
, 250, dfile
);
735 int buflen
=strlen(buf
);
736 block
=(char *)realloc(block
, sizeof(char)*(bytes
+buflen
+1));
737 strcpy(block
+bytes
, buf
);
739 } while(strstr(buf
, "}")==NULL
);
743 int arrayItems(char *buf
){
746 while((bufptr
=strstr(bufptr
, ","))!=NULL
){
753 void readArrayInt(char *buf
, int *array
, int n
){
755 bufptr
=strtok(buf
, "{,}");
756 for(int i
=0;i
<n
;i
++){
757 bufptr
=strtok(NULL
, "{,}");
758 sscanf(bufptr
, "%d", &array
[i
]);
762 void readArrayBool(char *buf
, bool *array
, int n
){
764 bufptr
=strtok(buf
, "{,}");
765 for(int i
=0;i
<n
;i
++){
766 bufptr
=strtok(NULL
, "{,}");
767 array
[i
]=(strstr(bufptr
, "true")!=NULL
);
771 void createPixmap(char **data
, char *buf
, Pixmap
*image
, Pixmap
*mask
, int *width
, int *height
){
772 XpmAttributes xpmattr
;
773 XpmColorSymbol xpmcsym
[4]={{"back_color", NULL
, color
[0]},
774 {"led_color_high", NULL
, color
[1]},
775 {"led_color_med", NULL
, color
[2]},
776 {"led_color_low", NULL
, color
[3]}};
777 xpmattr
.numsymbols
=4;
778 xpmattr
.colorsymbols
=xpmcsym
;
779 xpmattr
.exactColors
=false;
780 xpmattr
.closeness
=40000;
781 xpmattr
.valuemask
=XpmColorSymbols
| XpmExactColors
| XpmCloseness
| XpmSize
;
783 XpmCreatePixmapFromData(d_display
, w_root
, data
, image
, mask
, &xpmattr
);
785 XpmCreatePixmapFromBuffer(d_display
, w_root
, buf
, image
, mask
, &xpmattr
);
787 *width
=xpmattr
.width
;
789 *height
=xpmattr
.height
;
792 void setBtnList(int *bset
){
793 // Create a list of pointers to button data.
794 // So, for example, data for button 2 can be accessed as art_btnlist[2];
795 // Also, the y co-ordinate of its symbol would be art_btnlist[2][1]
797 art_btnlist
=(int **)malloc(art_nbtns
*sizeof(int *));
799 for(int i
=0;i
<art_nbtns
;i
++){
800 art_btnlist
[i
]=&bset
[0+curpos
];
801 curpos
+=2*art_btnlist
[i
][2]+3;
805 bool inPolygon(int *points
, int px
, int py
){
809 for(int i
=1;i
<=points
[0];i
++){