wmusic: Print message when connecting to new player.
[dockapps.git] / cputnik / src / docklib.c
blob5b760b46105c6b7f2cf4f4004086102e9a5f6106
2 /*
3 * DOCKLIB - a simple dockapp library
5 * Copyright (C) 2000-2005 some people...
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "docklib.h"
24 /******************************************************************************
25 * variables
26 ******************************************************************************/
28 XSizeHints mysizehints;
29 XWMHints mywmhints;
30 Window Root, iconwin, win;
31 Display *display;
32 GC NormalGC;
33 XpmIcon wmgen, fonts_wmgen, leds_wmgen;
34 Pixmap pixmask;
35 Pixel back_pix, fore_pix;
36 int screen, x_fd, d_depth;
37 MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
39 FILE *prefs_filehandle;
40 char *Geometry = "";
41 char *fonts_xpm[], *leds_xpm[];
44 /******************************************************************************
46 * dcl_get_xpm
48 ******************************************************************************/
50 void dcl_get_xpm (XpmIcon *wmgen, char *pixmap_bytes[])
52 XWindowAttributes attributes;
53 int err;
55 /* For the colormap */
56 XGetWindowAttributes(display, Root, &attributes);
58 wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
60 err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
61 &(wmgen->mask), &(wmgen->attributes));
63 if (err != XpmSuccess) {
64 fprintf(stderr, "ERROR: Not enough free colorcells.\n");
65 exit(1);
70 /******************************************************************************
72 * dcl_get_color
74 ******************************************************************************/
76 Pixel dcl_get_color (char *name)
78 XColor color;
79 XWindowAttributes attributes;
81 XGetWindowAttributes(display, Root, &attributes);
83 color.pixel = 0;
84 if (!XParseColor(display, attributes.colormap, name, &color)) {
85 fprintf(stderr, "ERROR: can't parse %s.\n", name);
86 } else if (!XAllocColor(display, attributes.colormap, &color)) {
87 fprintf(stderr, "ERROR: can't allocate %s.\n", name);
90 return color.pixel;
93 /******************************************************************************
95 * dcl_flush_expose
97 ******************************************************************************/
99 int dcl_flush_expose (Window w)
101 XEvent dummy;
102 int i=0;
104 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
105 i++;
107 return i;
110 /******************************************************************************
112 * dcl_redraw_window
114 ******************************************************************************/
116 void dcl_redraw_window (void)
119 dcl_flush_expose(iconwin);
120 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
121 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
122 dcl_flush_expose(win);
123 XCopyArea(display, wmgen.pixmap, win, NormalGC,
124 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
127 /******************************************************************************
129 * dcl_redraw_window_xy
131 ******************************************************************************/
133 void dcl_redraw_window_xy (int x, int y)
136 dcl_flush_expose(iconwin);
137 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
138 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
139 dcl_flush_expose(win);
140 XCopyArea(display, wmgen.pixmap, win, NormalGC,
141 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
144 /******************************************************************************
146 * dcl_add_mouse_region
148 ******************************************************************************/
150 void dcl_add_mouse_region (int index, int left, int top, int right, int bottom)
152 if (index < MAX_MOUSE_REGION) {
153 mouse_region[index].enable = 1;
154 mouse_region[index].top = top;
155 mouse_region[index].left = left;
156 mouse_region[index].bottom = bottom;
157 mouse_region[index].right = right;
161 /******************************************************************************
163 * dcl_check_mouse_region
165 ******************************************************************************/
167 int dcl_check_mouse_region (int x, int y)
169 int i, found;
171 found = 0;
173 for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
174 if (mouse_region[i].enable &&
175 x <= mouse_region[i].right &&
176 x >= mouse_region[i].left &&
177 y <= mouse_region[i].bottom &&
178 y >= mouse_region[i].top)
179 found = 1;
182 if (!found) return -1;
183 return (i-1);
186 /******************************************************************************
188 * dcl_copy_xpm_area
190 ******************************************************************************/
192 void dcl_copy_xpm_area (int x, int y, int sx, int sy, int dx, int dy)
195 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
200 /******************************************************************************
202 * dcl_copy_font_xpm_area
204 ******************************************************************************/
206 void dcl_copy_font_xpm_area (int x, int y, int sx, int sy, int dx, int dy)
208 XCopyArea(display, fonts_wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
213 /******************************************************************************
215 * dcl_copy_led_xpm_area
217 ******************************************************************************/
219 void dcl_copy_led_xpm_area (int x, int y, int sx, int sy, int dx, int dy)
222 XCopyArea(display, leds_wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
226 /******************************************************************************
228 * dcl_copy_xbm_area
230 ******************************************************************************/
232 void dcl_copy_xbm_area (int x, int y, int sx, int sy, int dx, int dy)
234 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
238 /******************************************************************************
240 * dcl_set_mask_xy
242 ******************************************************************************/
244 void dcl_set_mask_xy (int x, int y)
246 XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
247 XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
250 /******************************************************************************
252 * dcl_open_x_window
254 ******************************************************************************/
256 void dcl_open_x_window (int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height)
258 unsigned int borderwidth = 1;
259 XClassHint classHint;
260 char *display_name = NULL;
261 char *wname = argv[0];
262 XTextProperty name;
263 XGCValues gcv;
264 unsigned long gcm;
265 int dummy=0, i, flags;
267 for (i=1; argv[i]; i++) {
268 if (!strcmp(argv[i], "-display"))
269 display_name = argv[i+1];
272 if (!(display = XOpenDisplay(display_name))) {
273 fprintf(stderr, "ERROR: can't open display %s\n", XDisplayName(display_name));
274 exit(1);
277 screen = DefaultScreen(display);
278 Root = RootWindow(display, screen);
279 d_depth = DefaultDepth(display, screen);
280 x_fd = XConnectionNumber(display);
282 /* Convert XPM to XImage */
283 dcl_get_xpm(&wmgen, pixmap_bytes);
284 dcl_get_xpm(&fonts_wmgen, fonts_xpm);
285 dcl_get_xpm(&leds_wmgen, leds_xpm);
287 /* Create a window to hold the stuff */
288 mysizehints.flags = USSize | USPosition;
289 mysizehints.x = 0;
290 mysizehints.y = 0;
292 back_pix = dcl_get_color("white");
293 fore_pix = dcl_get_color("black");
295 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
296 &mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
298 mysizehints.width = 64;
299 mysizehints.height = 64;
301 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
302 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
304 iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
305 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
307 /* Activate hints */
308 XSetWMNormalHints(display, win, &mysizehints);
309 classHint.res_name = wname;
310 classHint.res_class = wname;
311 XSetClassHint(display, win, &classHint);
313 flags = ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask;
315 XSelectInput(display, win, flags);
316 XSelectInput(display, iconwin, flags);
318 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
319 fprintf(stderr, "ERROR: can't allocate window name\n");
320 exit(1);
323 XSetWMName(display, win, &name);
325 /* Create GC for drawing */
327 gcm = GCForeground | GCBackground | GCGraphicsExposures;
328 gcv.foreground = fore_pix;
329 gcv.background = back_pix;
330 gcv.graphics_exposures = 0;
331 NormalGC = XCreateGC(display, Root, gcm, &gcv);
333 /* ONLYSHAPE ON */
335 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
337 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
338 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
340 /* ONLYSHAPE OFF */
342 mywmhints.initial_state = WithdrawnState;
343 mywmhints.icon_window = iconwin;
344 mywmhints.icon_x = mysizehints.x;
345 mywmhints.icon_y = mysizehints.y;
346 mywmhints.window_group = win;
347 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
349 XSetWMHints(display, win, &mywmhints);
351 XSetCommand(display, win, argv, argc);
352 XMapWindow(display, win);
357 /******************************************************************************
359 * dcl_getdir_config
361 ******************************************************************************/
363 char* dcl_getdir_config (char *cdirectory)
365 static char cfgdir[PATH_MAX];
366 struct stat cfg;
368 dcl_strcpy (cfgdir, getenv ("HOME"), PATH_MAX);
369 dcl_strcat (cfgdir, "/", PATH_MAX);
370 dcl_strcat (cfgdir, cdirectory, PATH_MAX);
372 if(stat(cfgdir, &cfg) < 0)
373 mkdir(cfgdir, S_IRUSR | S_IWUSR | S_IXUSR);
375 return cfgdir;
379 /******************************************************************************
381 * dcl_getfilename_config
383 ******************************************************************************/
385 char* dcl_getfilename_config (char *config_dir, char *config_filename)
387 static char filename[PATH_MAX];
389 dcl_strcpy (filename, dcl_getdir_config(config_dir), PATH_MAX);
390 dcl_strcat (filename, "/", PATH_MAX);
391 dcl_strcat (filename, config_filename, PATH_MAX);
393 return filename;
397 /******************************************************************************
399 * dcl_prefs_openfile
401 ******************************************************************************/
403 void* dcl_prefs_openfile (char *filename, int openmode)
405 prefs_filehandle = NULL;
407 if (openmode == P_READ)
408 prefs_filehandle = fopen (filename, "rb");
409 else if (openmode == P_WRITE)
410 prefs_filehandle = fopen (filename, "wb");
412 return prefs_filehandle;
416 /******************************************************************************
418 * dcl_prefs_closefile
420 ******************************************************************************/
422 void dcl_prefs_closefile (void)
424 fclose (prefs_filehandle);
428 /******************************************************************************
430 * dcl_prefs_put_int
432 ******************************************************************************/
434 void dcl_prefs_put_int (char *tagname, int value)
436 fprintf (prefs_filehandle, "%s=%d\n", tagname, value);
440 /******************************************************************************
442 * dcl_prefs_put_float
444 ******************************************************************************/
446 void dcl_prefs_put_float (char *tagname, float value)
448 fprintf (prefs_filehandle, "%s=%f\n", tagname, value);
452 /******************************************************************************
454 * dcl_prefs_put_string
456 ******************************************************************************/
458 void dcl_prefs_put_string (char *tagname, char *value)
460 fprintf (prefs_filehandle, "%s=%s\n", tagname, value);
464 /******************************************************************************
466 * dcl_prefs_put_lf
468 ******************************************************************************/
470 void dcl_prefs_put_lf (void)
472 fprintf (prefs_filehandle, "\n");
476 /******************************************************************************
478 * dcl_prefs_put_comment
480 ******************************************************************************/
482 void dcl_prefs_put_comment (char *comment)
484 char text[MAX_LINE_LEN];
486 dcl_strcpy (text, "# ", MAX_LINE_LEN);
487 dcl_strcat (text, comment, MAX_LINE_LEN);
488 fprintf (prefs_filehandle, text);
492 /******************************************************************************
494 * dcl_prefs_get_line_with_tag
496 ******************************************************************************/
498 char* dcl_prefs_get_line_with_tag (char *tagname)
500 static char prfline[MAX_LINE_LEN];
501 int i;
502 char c;
504 fseek (prefs_filehandle, 0, SEEK_SET);
506 while (!feof (prefs_filehandle)) {
507 i = 0;
509 while (((c = fgetc (prefs_filehandle)) != '\n') && c!= EOF && i < MAX_LINE_LEN)
510 prfline[i++] = c;
512 prfline[i] = '\0';
514 if (prfline[0] != '#')
515 if (!strncmp (tagname, prfline, strlen (tagname))) break;
518 return prfline;
522 /******************************************************************************
524 * dcl_prefs_get_value_field
526 ******************************************************************************/
528 char* dcl_prefs_get_value_field (char *tagname)
530 static char valuestr[MAX_VALUE_LEN];
531 char *valpos, c;
532 int i;
534 i = 0;
536 if ((valpos = strchr (dcl_prefs_get_line_with_tag (tagname), '='))) {
537 while((c = valpos[i+1]) != '\0' && i < MAX_VALUE_LEN) valuestr[i++] = c;
540 valuestr[i] = '\0';
541 return valuestr;
545 /******************************************************************************
547 * dcl_prefs_get_int
549 ******************************************************************************/
551 int dcl_prefs_get_int (char *tagname)
553 return (atoi (dcl_prefs_get_value_field (tagname)));
557 /******************************************************************************
559 * dcl_prefs_get_float
561 ******************************************************************************/
563 float dcl_prefs_get_float (char *tagname)
565 return (atof (dcl_prefs_get_value_field (tagname)));
569 /******************************************************************************
571 * dcl_prefs_get_string
573 ******************************************************************************/
575 char* dcl_prefs_get_string (char *tagname)
577 return (dcl_prefs_get_value_field (tagname));
581 /******************************************************************************
583 * dcl_strcpy
585 ******************************************************************************/
587 char* dcl_strcpy (char *dest, const char *src, int maxlength)
589 int len;
591 if (!dest) {
592 fprintf (stderr, "ERROR: NULL dest in safe_strcpy\n");
593 return NULL;
596 if (!src) {
597 *dest = 0;
598 return dest;
601 len = strlen(src);
603 if (len > maxlength) {
604 fprintf (stderr, "ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
605 (int)(len-maxlength), src);
606 len = maxlength;
609 memcpy(dest, src, len);
610 dest[len] = 0;
611 return dest;
615 /******************************************************************************
617 * dcl_strcat
619 ******************************************************************************/
621 char* dcl_strcat (char *dest, const char *src, int maxlength)
623 int src_len, dest_len;
625 if (!dest) {
626 fprintf (stderr, "ERROR: NULL dest in safe_strcat\n");
627 return NULL;
630 if (!src) {
631 return dest;
634 src_len = strlen(src);
635 dest_len = strlen(dest);
637 if (src_len + dest_len > maxlength) {
638 fprintf (stderr, "ERROR: string overflow by %d in safe_strcat [%.50s]\n",
639 (int)(src_len + dest_len - maxlength), src);
640 src_len = maxlength - dest_len;
643 memcpy(&dest[dest_len], src, src_len);
644 dest[dest_len + src_len] = 0;
645 return dest;
649 /******************************************************************************
651 * dcl_draw_char
653 ******************************************************************************/
655 int dcl_draw_char(int x, int y, char z, int font_type)
657 char *ctable = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.[]-_:'@" };
658 int ctable_len = 44;
659 int k, font_line, font_width, font_height;
661 switch(font_type) {
663 case FONT_SMALL:
664 font_width = 4;
665 font_height = 5;
666 font_line = 12;
667 break;
669 case FONT_NORMAL:
670 font_width = 5;
671 font_height = 5;
672 font_line = 7;
673 break;
675 case FONT_LARGE:
676 font_width = 5;
677 font_height = 7;
678 font_line = 0;
679 break;
681 default:
682 fprintf(stderr, "ERROR: Unknown font type...\n");
683 return false;
686 for(k=0; k < ctable_len; k++)
687 if(toupper(z)==ctable[k]) {
689 dcl_copy_font_xpm_area(k*font_width, font_line, font_width, font_height, x, y);
690 break;
694 return true;
697 /******************************************************************************
699 * dcl_draw_string
701 ******************************************************************************/
703 int dcl_draw_string(int x, int y, char *string, int font_type, int length)
705 int j, len, font_width;
706 char a;
708 if(length == -1)
709 len = strlen(string);
710 else
711 len = length;
713 if(len <= 0 || len > MAX_STRING_LEN) {
715 fprintf(stderr, "ERROR: Wrong string length...\n");
716 return false;
720 switch(font_type) {
722 case FONT_SMALL:
723 font_width = 4;
724 break;
726 case FONT_NORMAL:
727 font_width = 5;
728 break;
730 case FONT_LARGE:
731 font_width = 5;
732 break;
734 default:
735 fprintf(stderr, "ERROR: Unknown font type...\n");
736 return false;
739 for(j=0; j<len; j++) {
741 if((a=string[j]) == '\0') break;
742 dcl_draw_char(x+j*(font_width+1), y, a, font_type);
746 return true;
750 /******************************************************************************
752 * dcl_draw_led
754 ******************************************************************************/
756 int dcl_draw_led(int x, int y, int color)
759 if(color > NUM_COLORS) {
760 fprintf(stderr,"ERROR: Color doesn't exist...");
761 return false;
764 dcl_copy_led_xpm_area(5*color, 0, 5, 5, x, y);
766 return true;
770 /******************************************************************************
772 * dcl_execute_command
774 ******************************************************************************/
776 void dcl_execute_command(char *command, int flag)
778 char *cmdline[4];
779 pid_t pid, pid_status;
781 pid = fork();
783 if (pid == 0) {
785 cmdline[0] = "sh";
786 cmdline[1] = "-c";
787 cmdline[2] = command;
788 cmdline[3] = 0;
789 execvp("/bin/sh", cmdline);
790 _exit(121);
792 } else
793 if(flag)
794 waitpid(pid, &pid_status, 0);
798 /******************************************************************************
800 * dcl_check_file
802 ******************************************************************************/
804 int dcl_check_file(char *filename)
806 struct stat ftype;
807 int state = F_NOT_AVAILABLE;
809 if(stat(filename, &ftype)==-1)
810 state = F_NOT_AVAILABLE;
812 else if(S_ISREG(ftype.st_mode))
813 state = F_REGULAR;
815 else if(S_ISDIR(ftype.st_mode))
816 state = F_DIRECTORY;
818 else if(S_ISCHR(ftype.st_mode))
819 state = F_CHAR_DEVICE;
821 else if(S_ISBLK(ftype.st_mode))
822 state = F_BLOCK_DEVICE;
824 else if(S_ISLNK(ftype.st_mode))
825 state = F_LINK;
827 else if(S_ISFIFO(ftype.st_mode))
828 state = F_FIFO;
830 else if(S_ISSOCK(ftype.st_mode))
831 state = F_SOCK;
833 return state;
837 /******************************************************************************
839 * dcl_draw_point
841 ******************************************************************************/
843 void dcl_draw_point(int x, int y, Pixel color)
845 XSetForeground(display, NormalGC, color);
846 XDrawPoint(display, wmgen.pixmap, NormalGC, x, y);
849 /******************************************************************************
851 * dcl_draw_line
853 ******************************************************************************/
855 void dcl_draw_line(int x0, int y0, int x1, int y1, Pixel color)
857 XSetForeground(display, NormalGC, color);
858 XDrawLine(display, wmgen.pixmap, NormalGC, x0, y0, x1, y1);
861 /*-------------------------------------------------------------------------------------------
862 * fonts and leds definitions
863 * gfx by sill
864 *-------------------------------------------------------------------------------------------*/
866 char * fonts_xpm[] = {
867 "220 17 8 1",
868 " c None",
869 ". c #145B53",
870 "+ c #20B2AE",
871 "@ c #004941",
872 "# c #007D71",
873 "$ c #188A86",
874 "% c #202020",
875 "& c #22332F",
876 ".+++.++++.@+++#++++@#+++##+++#@+++$+@%@+%#+#%#+++#+%%%++%%%%+%%%++@%%+@+++@++++@@+++@++++@@++++++++++%%%++%%%++%%%++%%%++%%%+++++#%%%#%#+++##+++##%%%##+++##+++##+++##+++##+++##+++#%%%%%+++$%%$+++%%%%%%%%%%%%%%%%%%%%@+++@",
877 "+%%%++%%%++@%%%+%%@++%%%%+%%%%+%%%@+@%@+%%+%%%%%%++%%##+%%%%+@%@+++%%++@%@++%%@++@%@++%%@++%%%@@%+%@+%%%++%%%++%%%++@%@++%%%+@%%@+%%%+%%%%%+%%%%++%%%++%%%%+%%%%%%%%++%%%++%%%++%%%+%%%%%+%%%%%%%%+%%%%%%%%%%%++%%%+$%%+@%@+",
878 "+%%%++%%%++%%%%+%%%++%%%%+%%%%+%%%%+@%@+%%+%%%%%%++@@+%+%%%%++@++++.%++%%%++%%%++%%%++%%%++%%%%%%+%%+%%%++%%%++%%%+%+@+%+@%@+%%@+.%%%+%%%%%+%%%%++%%%++%%%%+%%%%%%%%++%%%++%%%++%%%+%%%%%+%%%%%%%%+%%%%%%%%%%%$$%%%+$%%+%#%+",
879 "+%%%+++++%+%%%%+%%%++++#%+++#%+%++$+++++%%+%%%%%%++++%%+%%%%+@+@++%+%++%%%++%%@++%#%++%%@+@+++@%%+%%+%%%++@%@++%#%+%@+@%@+.+@%.+.%%%%#%#+++#%+++##+++##+++##+++#%%%%#%+++%#+++##%%%#%%%%%+%%%%%%%%+$+++$%%%%%%%%%%%$.%%+%+@+",
880 "++++++%%%++%%%%+%%%++%%%%+%%%%+%%%++@%@+%%+%%%%%%++@@+%+%%%%+%@%++%.+++%%%+++++@+%+@+++++%%%%%+%%+%%+%%%+##%##+@+@+%+@+%%@+@%.+@%%%%%+%+%%%%%%%%+%%%%+%%%%++%%%+%%%%++%%%+%%%%++%%%+%%%%%+%%%%%%%%+%%%%%%%%%%%%%%%%%%%%+%#+@",
881 "+%%%++%%%++@%%%+%%@++%%%%+%%%%+%%%++@%@+%%+%%+%%@++%%##+@%%%+%%%++%%+++@%@++%%%%+@@+.+%%@+@%%%+%%+%%+@%@+%+@+%++@+++@%@+%%+%%+@%%@%%%+%+%%%%%%%%+%%%%+%%%%++%%%+%%%%++%%%+%%%%++%%%+%$$%%+%%%%%%%%+%%%%%%%%%%%$$%%%%%%%+@%%%",
882 "+%%%+++++.@+++#++++@#+++#+%%%%@+++.+@%@+%#+#%@+++@+%%%+.+++#+%%%++%%@+@+++@+%%%%@++.++%%%+++++@%%+%%@+++@%@+@%+@%@++%%%+%%+%%#++++%%%#%#+++##+++#%%%%##+++##+++#%%%%##+++##+++##+++#%++%%+++$%%$+++%%%%%$+++$%++%%%%%%%@+++@",
883 "&+++&++++&&+++$++++&$+++$$+++$.+++.+%%%+%&+&%$+++$+%%%++%%%%++&+++%%%+&+++&++++&&+++&++++&&+++$$+++$+%%%++%%%++%%%++%%%++%%%+$++++%%%$%$++$%$++$%$%%$%$++$%$++$%$++$%$++$%$++$%$++$%%%%%%%++&%%&++%%%%%%%%%%%%$$%%%+$%%@+++@",
884 "+%%%++%%%++%%%%+%%%++%%%%+%%%%+%%%%+%%%+%%+%%%%%%++%%+%+%%%%+&+&+++%%++%%%++%%%++%%%++%%%++%%%%%%+%%+%%%++%%%++%+%+%+%+%+%%%+%%%+%%%%+%%%%+%%%%+%+%%+%+%%%%+%%%%%%%+%+%%+%+%%+%+%%+%%%%%%%+%%%%%%+%%%%%%%%%%%%++%%%+$%%+$$@+",
885 "+%%%+++++&+%%%%+%%%++++$%+++$%+%%+++++++%%+%%%%%%++++%%+%%%%+%+%++%+%++%%%++%%%++%+%++%%%+&+++&%%+%%+%%%+&+%+&+%+%+%%+%%%+%+%%%+%%%%%$%$++$%%++$%$++$%$++$%$++$%%%%$%$++$%$++$%$%%$%%%%%%%+%%%%%%+%$+++$%%%%%%%%%%%$.%%+%++$",
886 "++++++%%%++%%%%+%%%++%%%%+%%%%+%%%++%%%+%%+%%+%%%++%%+%+%%%%+%&%++%%+++%%%+++++&+%%+$++++&%%%%+%%+%%+%%%+%+%+%+&+&+%+%+%%%+%%%+%%%%%%+%+%%%%%%%+%%%%+%%%%+%+%%+%%%%+%+%%+%%%%+%+%%+%%$$%%%+%%%%%%+%%%%%%%%%%%%$$%%%%%%%+@@@%",
887 "+%%%+++++&&+++$++++&$+++$+%%%%.+++.+%%%+%&+&%&+++&+%%%+&+++++%%%++%%%+&+++&+%%%%&++$++%%%+$+++&%%+%%&+++&%&+&%&+&+&+%%%+%%+%%++++$%%%$%$++$%$++$%%%%$%$++$%$++$%%%%$%$++$%$++$%$++$%%++%%%++&%%&++%%%%%%$+++$%++%%%%%%%@+++@",
888 ".++.+++.&++$$++.$++$$++$.++$$%%$%$.%$++$$%%$$%%%$%%$$%%$.++.+++..++.+++..++$++++$%%$$%%$$%%$$%%$$%%$$++$%%.$$++.$++.$%%$$++$.++$$++..++..++..++.%%%%++&%%&++%%%%%%%%%$$%%+$%@++@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%",
889 "+%%++%%++%%%+%%++%%%+%%%+%%%+%%+%+.%%%%++%+.+%%%+$$+++%++%%++%%++%%++%%++%%%%$$%+%%++%%++%%++%%++%%+%%+%%.++%%%+%%%++%%++%%%+%%%%%%++%%++%%++%%+%%%%+%%%%%%+%%%%%%%%%++%%+$%+$@+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%",
890 "+%%++++&+%%%+%%+++$%++$%+%+$++++%+.%%%%+++.%+%%%+..++&+++%%++%%++%$++%%+.++.%$$%+%%+$%%$+..+&++&%++%%+%%%%%+.++.%++$.+++$++.+++.%%%+.++..++++%%+%%%%+%%%%%%+$++$%%%%%%%%%$.%+%+$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%",
891 "+++++%%++%%%+%%++%%%+%%%+%%++%%+%+.%+%%++%+.+%%%+%%++%&++%%++++.+%+$+++&%%%+%$$%+%%+$..$+++++%%+%&+%+%%%%%%++%%%%%%+%%%+%%%++%%+%%%++%%+%%%++%%+%$$%+%%%%%%+%%%%%%%%%$$%%%%%+@@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%",
892 "+%%++++.&++$$++.$++$+%%%.++.$%%$%$.%.++.$%%$$++$$%%$$%%$.++.+%%%.+$++%%+$++.%$$%.++.&++&$&&$$%%$%&$%$++$%%%$$++$$++.%%%$$++..++.%%%$.++..++..++.%++%++&%%&++%%%%$++$%++%%%%%@++@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"};
894 char * leds_xpm[] = {
895 "50 5 72 1",
896 " c #262626",
897 ". c #3F4D4A",
898 "+ c #4A5754",
899 "@ c #3E3E1B",
900 "# c #B2B26F",
901 "$ c #DCDC30",
902 "% c #97970A",
903 "& c #1F431F",
904 "* c #5CA65C",
905 "= c #2DE02D",
906 "- c #0F8D0F",
907 "; c #282828",
908 "> c #448986",
909 ", c #4EA9A5",
910 "' c #3B7F7D",
911 ") c #032E50",
912 "! c #2776E2",
913 "~ c #6CA5EB",
914 "{ c #396CC4",
915 "] c #662F00",
916 "^ c #E58325",
917 "/ c #F2AF74",
918 "( c #C66100",
919 "_ c #4A1F1F",
920 ": c #BB4545",
921 "< c #FF2424",
922 "[ c #B61111",
923 "} c #630000",
924 "| c #C32284",
925 "1 c #C2519E",
926 "2 c #B4197C",
927 "3 c #650000",
928 "4 c #9B4B55",
929 "5 c #AB6A72",
930 "6 c #8C434E",
931 "7 c #3D3D3D",
932 "8 c #898989",
933 "9 c #CDCDCD",
934 "0 c #F3F3DD",
935 "a c #F3F3BA",
936 "b c #D4D400",
937 "c c #D8F9D8",
938 "d c #8BEE8B",
939 "e c #17D717",
940 "f c #D6FAF9",
941 "g c #6ADAD7",
942 "h c #46A19E",
943 "i c #BFE0EC",
944 "j c #A5CEEB",
945 "k c #4C93FB",
946 "l c #F7E4D4",
947 "m c #FFDCBA",
948 "n c #FFA147",
949 "o c #F7DADA",
950 "p c #FF7373",
951 "q c #F81515",
952 "r c #FBFAFD",
953 "s c #D6ACD9",
954 "t c #C13E9E",
955 "u c #FBFEFD",
956 "v c #CBBCBF",
957 "w c #9F626C",
958 "x c #EBEBEB",
959 "y c #FFFFFF",
960 "z c #EBEB8B",
961 "A c #72EA72",
962 "B c #55B7B3",
963 "C c #93C2EB",
964 "D c #FFD1A5",
965 "E c #FF5454",
966 "F c #C170AD",
967 "G c #B57D85",
968 " .+. @#$%@&*=-&;>,';)!~{)]^/(]_:<[_}|12}3456378987",
969 ".+++.#0ab%*cde->fgh'!ijk{^lmn(:opq[|rst24uvw68xyx8",
970 "+++++$az$b=dA=e,gB,h~jC~k/mD/n<pE<q1sF1t5vG5w9yyy9",
971 ".+++.%b$b%-e=e-'h,h'{k~k{(n/n([q<q[2t1t26w5w68xyx8",
972 " .+. @%b%@&-e-&;'h';){k{)](n(]_[q[_}2t2}36w6378987"};
976 * Created: Sat 26 Mar 2005 05:45:53 PM CET
977 * Last Modified: Sat 26 Mar 2005 10:53:38 PM CET