wmcliphist: fix FTCBFS by making pkg-config configurable.
[dockapps.git] / wmusic / src / wmusic.c
blob04bd49de3c98b9deb9be5c1feb4a04e5a7ff563b
1 /* wmusic - a xmms remote-controlling DockApp
2 * Copyright (C) 2000-2001 Bastien Nocera <hadess@hadess.net>
3 * Maintained by John Chapin <john+wmusic@jtan.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #define DBL_CLICK_INTERVAL 250 /* double click interval in milliseconds */
21 #define ARROW_INTERVAL 100 /* arrow update interval in milliseconds */
22 #define SCROLL_INTERVAL 300 /* scroll update interval in milliseconds */
23 #define SEPARATOR " ** " /* The separator for the scrolling title */
24 #define DISPLAYSIZE 6 /* width of text to display (running title) */
26 #include <libdockapp/dockapp.h>
27 #include <playerctl/playerctl.h>
28 #include <unistd.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <locale.h>
33 #include <X11/X.h>
34 #include <X11/Xlib.h>
36 #include "wmusic-master.xpm"
37 #include "wmusic-digits.xpm"
39 /*---------------------------------------------------------------------------*/
40 /* Prototypes */
41 /*---------------------------------------------------------------------------*/
43 void copyNumArea(int x, int y, int sx, int sy, int dx, int dy);
44 void ActionPlay(int x, int y, DARect rect, void *data);
45 void ActionPause(int x, int y, DARect rect, void *data);
46 void ActionEject(int x, int y, DARect rect, void *data);
47 void ActionPrev(int x, int y, DARect rect, void *data);
48 void ActionNext(int x, int y, DARect rect, void *data);
49 void ActionStop(int x, int y, DARect rect, void *data);
50 void ActionFastr(int x, int y, DARect rect, void *data);
51 void ActionFastf(int x, int y, DARect rect, void *data);
52 void ToggleWins(int x, int y, DARect rect, void *data);
53 void ToggleVol(int x, int y, DARect rect, void *data);
54 void ChangeVol(int x, int y, DARect rect, void *data);
55 void ToggleTime(int x, int y, DARect rect, void *data);
56 void buttonPress(int button, int state, int x, int y);
57 void buttonRelease(int button, int state, int x, int y);
58 int PlayerConnect(void);
59 void DisplayRoutine();
60 void DrawPos (int pos);
61 void DrawTime(int time);
62 void DrawArrow(void);
63 void DrawVolume(void);
64 void DrawTitle(char *title);
65 void ExecuteXmms(void);
67 /*----------------------------------------------------------------------------*/
68 /* Variables */
69 /*----------------------------------------------------------------------------*/
71 /* X11 variables */
72 char *displayName = "";
73 GC gc;
74 XEvent ev;
76 /* Dockapp variables */
77 PlayerctlPlayer *player;
78 char *xmms_cmd = "xmms";
79 Bool main_vis=0, pl_vis=0, eq_vis=0;
80 unsigned int volume_step = 5;
81 Bool run_excusive=0;
83 Bool t_time=0;
84 float title_pos = 0;
85 unsigned int arrow_pos = 0;
86 Bool pause_norotate = 0;
87 Time click_time=0;
89 Pixmap pixmap, mask; /* Pixmap that is displayed */
90 Pixmap pixnum, masknum; /* Pixmap source */
92 int left_pressed = 0; /* for pseudo drag callback */
93 int motion_event = 0; /* on motion events we do not want(too fast) display update */
95 static DAActionRect buttonRects[] = {
96 {{5, 39, 14, 9}, ActionPrev},
97 {{19, 39, 14, 9}, ActionNext},
98 {{33, 39, 13, 9}, ActionFastr},
99 {{46, 39, 13, 9}, ActionFastf},
100 {{5, 48, 11, 11}, ActionEject},
101 {{16, 48, 21, 11}, ActionPlay},
102 {{37, 48, 11, 11}, ActionPause},
103 {{48, 48, 11, 11}, ActionStop}
106 static DAActionRect toggleRect[] = {
107 {{5, 5, 54, 30}, ToggleWins}
110 static DAActionRect globRect[] = {
111 {{0, 0, 64, 64}, ToggleVol}
114 static DAActionRect displayRects[] = {
115 {{5, 5, 54, 12}, ToggleTime},
118 static DAActionRect volumeRects[] = {
119 {{5, 17, 38, 8 }, ChangeVol}
122 static DAProgramOption options[] = {
123 {"-c", "--command", "Command to launch the media player", DOString,
124 False, {&xmms_cmd} },
125 {"-d", "--display", "Display to use", DOString, False, {&displayName} },
126 {"-r", "--run", "Run the media player on startup", DONone, False,
127 {NULL} },
128 {"-V", "--volume", "Stepping of the wheel volume control (in percent)",
129 DONatural, False, {&volume_step} },
130 {"-a", "--rotate-arrow", "Do not rotate the arrow, when paused",
131 DONone, False, {NULL} },
132 {"-l", "--time-left", "Show time left instead of time remaining by default",
133 DONone, False, {NULL} },
134 {"-R", "--run-excusive", "Run media player on startup, "
135 "exit when it exits", DONone, False, {NULL} }
138 typedef struct
140 wchar_t c;
141 int x;
142 int y;
143 } glyphdescr;
145 static glyphdescr glyphs[] = {
146 {L'-', 67, 83}, {L'.', 73, 83}, {L'\x27', 79, 83},
147 {L'(', 85, 83}, {L')', 91, 83}, {L'*', 97, 83}, {L'/', 103, 83},
149 {L'0', 1, 83}, {L'1', 7, 83}, {L'2', 13, 83}, {L'3', 19, 83}, {L'4', 25, 83},
150 {L'5', 31, 83}, {L'6', 37, 83}, {L'7', 43, 83}, {L'8', 49, 83}, {L'9', 55, 83},
154 {L'A', 1, 73}, {L'a', 1, 73},
155 {L'B', 7, 73}, {L'b', 7, 73},
156 {L'C', 13, 73}, {L'c', 13, 73},
157 {L'D', 19, 73}, {L'd', 19, 73},
158 {L'E', 25, 73}, {L'e', 25, 73},
160 {L'F', 31, 73}, {L'f', 31, 73},
161 {L'G', 37, 73}, {L'g', 37, 73},
162 {L'H', 43, 73}, {L'h', 43, 73},
163 {L'I', 49, 73}, {L'i', 49, 73},
164 {L'J', 55, 73}, {L'j', 55, 73},
166 {L'K', 61, 73}, {L'k', 61, 73},
167 {L'L', 67, 73}, {L'l', 67, 73},
168 {L'M', 73, 73}, {L'm', 73, 73},
169 {L'N', 79, 73}, {L'n', 79, 73},
170 {L'O', 85, 73}, {L'o', 85, 73},
172 {L'P', 91, 73}, {L'p', 91, 73},
173 {L'Q', 97, 73}, {L'q', 97, 73},
174 {L'R',103, 73}, {L'r',103, 73},
175 {L'S',109, 73}, {L's',109, 73},
176 {L'T',115, 73}, {L't',115, 73},
178 {L'U',121, 73}, {L'u',121, 73},
179 {L'V',127, 73}, {L'v',127, 73},
180 {L'W',133, 73}, {L'w',133, 73},
181 {L'X',139, 73}, {L'x',139, 73},
182 {L'Y',145, 73}, {L'y',145, 73},
184 {L'Z',151, 73}, {L'z',151, 73},
187 {L'\x42e', 1, 93}, {L'\x44e', 1, 93}, /* cyrillic Yu */
189 {L'\x410', 7, 93}, {L'\x430', 7, 93}, /* cyrillic A */
190 {L'\x411', 13, 93}, {L'\x431', 13, 93}, /* cyrillic Be */
191 {L'\x426', 19, 93}, {L'\x446', 19, 93}, /* cyrillic Ce */
192 {L'\x414', 25, 93}, {L'\x434', 25, 93}, /* cyrillic De */
193 {L'\x415', 31, 93}, {L'\x435', 31, 93}, /* cyrillic Ye */
195 {L'\x424', 37, 93}, {L'\x444', 37, 93}, /* cyrillic eF */
196 {L'\x413', 43, 93}, {L'\x433', 43, 93}, /* cyrillic Ge */
197 {L'\x425', 49, 93}, {L'\x445', 49, 93}, /* cyrillic Ha */
198 {L'\x418', 55, 93}, {L'\x438', 55, 93}, /* cyrillic I */
199 {L'\x419', 61, 93}, {L'\x439', 61, 93}, /* cyrillic I-kratkoe */
201 {L'\x41a', 67, 93}, {L'\x43a', 67, 93}, /* cyrillic Ka */
202 {L'\x41b', 73, 93}, {L'\x43b', 73, 93}, /* cyrillic eL */
203 {L'\x41c', 79, 93}, {L'\x43c', 79, 93}, /* cyrillic eM */
204 {L'\x41d', 85, 93}, {L'\x43d', 85, 93}, /* cyrillic eN */
205 {L'\x41e', 91, 93}, {L'\x43e', 91, 93}, /* cyrillic O */
207 {L'\x41f', 97, 93}, {L'\x43f', 97, 93}, /* cyrillic Pe */
208 {L'\x42f',103, 93}, {L'\x44f',103, 93}, /* cyrillic Ya */
209 {L'\x420',109, 93}, {L'\x440',109, 93}, /* cyrillic eR */
210 {L'\x421',115, 93}, {L'\x441',115, 93}, /* cyrillic eS */
211 {L'\x422',121, 93}, {L'\x442',121, 93}, /* cyrillic Te */
213 {L'\x423',127, 93}, {L'\x443',127, 93}, /* cyrillic U */
214 {L'\x416',133, 93}, {L'\x436',133, 93}, /* cyrillic Je */
215 {L'\x412',139, 93}, {L'\x432',139, 93}, /* cyrillic Ve */
216 {L'\x42c',145, 93}, {L'\x44c',145, 93}, /* cyrillic MyagkijZnak */
217 {L'\x42b',151, 93}, {L'\x44b',151, 93}, /* cyrillic Y */
219 {L'\x417',157, 93}, {L'\x437',157, 93}, /* cyrillic Ze */
220 {L'\x428',163, 93}, {L'\x448',163, 93}, /* cyrillic Sha */
221 {L'\x42d',169, 93}, {L'\x44d',169, 93}, /* cyrillic E */
222 {L'\x429',175, 93}, {L'\x449',175, 93}, /* cyrillic Scha */
223 {L'\x427',181, 93}, {L'\x447',181, 93}, /* cyrillic Che */
225 {L'\x42a',187, 93}, {L'\x44a',187, 93}, /* cyrillic TvyordyiZnak */
226 {L'\x404',115, 83}, {L'\x454',115, 83}, /* ukrainian IE */
227 {L'\x406', 49, 73}, {L'\x456', 49, 73}, /* ukrainian I */
228 {L'\x407',109, 83}, {L'\x457',109, 83}, /* ukrainian YI */
229 {L'\x491', 43, 93}, {L'\x490', 43, 93}, /* ukrainian GHE with upturn */
231 {L'\x401',121, 83}, {L'\x451',121, 83}, /* cyrillic Yo */
233 {L' ', 61, 83}
236 /*----------------------------------------------------------------------------*/
237 /* Functions */
238 /*----------------------------------------------------------------------------*/
240 void copyNumArea(int x, int y, int sx, int sy, int dx, int dy)
242 XCopyArea(DADisplay, pixnum, pixmap, gc, x, y, sx, sy, dx, dy);
245 void buttonDraw(DARect rect)
247 copyNumArea((rect.x)-5, (rect.y)-8, rect.width, rect.height,
248 rect.x, rect.y);
249 DASetPixmap(pixmap);
252 void ActionPlay(int x, int y, DARect rect, void *data)
254 if (data) {
255 buttonDraw(rect);
256 } else {
257 GError *error = NULL;
259 playerctl_player_play(player, &error);
260 if (error != NULL)
261 DAWarning("Could not execute command: %s",
262 error->message);
266 void ActionPause(int x, int y, DARect rect, void *data)
268 if (data) {
269 buttonDraw(rect);
270 } else {
271 GError *error = NULL;
273 playerctl_player_pause(player, &error);
274 if (error != NULL)
275 DAWarning("Could not execute command: %s",
276 error->message);
280 void ActionEject(int x, int y, DARect rect, void *data)
282 if (data) {
283 buttonDraw(rect);
284 } else {
285 DAWarning("Eject function is no longer supported.");
289 void ActionPrev(int x, int y, DARect rect, void *data)
291 if (data) {
292 buttonDraw(rect);
293 } else {
294 GError *error = NULL;
296 playerctl_player_previous(player, &error);
297 if (error != NULL)
298 DAWarning("Could not execute command: %s",
299 error->message);
303 void ActionNext(int x, int y, DARect rect, void *data)
305 if (data) {
306 buttonDraw(rect);
307 } else {
308 GError *error = NULL;
310 playerctl_player_next(player, &error);
311 if (error != NULL)
312 DAWarning("Could not execute command: %s",
313 error->message);
317 void ActionStop(int x, int y, DARect rect, void *data)
319 if (data) {
320 buttonDraw(rect);
321 } else {
322 GError *error = NULL;
324 playerctl_player_stop(player, &error);
325 if (error != NULL)
326 DAWarning("Could not execute command: %s",
327 error->message);
331 void ActionFastr(int x, int y, DARect rect, void *data)
333 if (data) {
334 buttonDraw(rect);
335 } else {
336 GError *error = NULL;
338 playerctl_player_seek(player, -10000000, &error);
339 if (error != NULL)
340 DAWarning("Could not execute command: %s",
341 error->message);
345 void ActionFastf(int x, int y, DARect rect, void *data)
347 if (data) {
348 buttonDraw(rect);
349 } else {
350 GError *error = NULL;
352 playerctl_player_seek(player, 10000000, &error);
353 if (error != NULL)
354 DAWarning("Could not execute command: %s",
355 error->message);
359 void ToggleWins(int x, int y, DARect rect, void *data)
361 if (!player) {
362 if ( (ev.xbutton.time-click_time) <= DBL_CLICK_INTERVAL )
364 click_time=0;
365 ExecuteXmms();
366 } else {
367 click_time=ev.xbutton.time;
372 void ToggleVol(int x, int y, DARect rect, void *data)
374 double volume;
375 double factor;
377 g_object_get(player, "volume", &volume, NULL);
379 if (*(int*)data == 1)
380 factor = 0.01 * volume_step;
381 else
382 factor = -0.01 * volume_step;
383 volume += factor;
385 if (volume > 1)
386 volume = 1;
387 if (volume < 0)
388 volume = 0;
390 g_object_set(player, "volume", volume, NULL);
393 void ChangeVol(int x, int y, DARect rect, void *data)
395 float volume = ((float)x)/38;
396 g_object_set(player, "volume", volume, NULL);
399 void ToggleTime(int x, int y, DARect rect, void *data)
401 if (t_time)
402 t_time = 0;
403 else t_time =1;
406 void buttonPress(int button, int state, int x, int y)
408 if (button==1)
409 left_pressed=1;
410 if (player)
412 if (button == 1)
414 char *tmp="1";
415 DAProcessActionRects(x, y, buttonRects, sizeof(buttonRects)/sizeof(DAActionRect), tmp);
416 DAProcessActionRects(x, y, displayRects, sizeof(displayRects)/sizeof(DAActionRect), tmp);
418 if (button == 2)
420 DAProcessActionRects(x, y, toggleRect, sizeof(toggleRect)/sizeof(DAActionRect), NULL);
422 if (button == 3)
424 char *tmp="1";
425 DAProcessActionRects(x, y, toggleRect, sizeof(toggleRect)/sizeof(DAActionRect), tmp);
427 if ((button == 4) || (button == 5))
429 if (button == 5)
431 /* Wheel scrolls down */
432 int tmp=2;
433 DAProcessActionRects(x, y, globRect, sizeof(globRect)/sizeof(DAActionRect), &tmp);
434 } else {
435 /* Wheel scrolls up */
436 int tmp=1;
437 DAProcessActionRects(x, y, globRect, sizeof(globRect)/sizeof(DAActionRect), &tmp);
441 else
442 DAProcessActionRects(x, y, toggleRect, sizeof(toggleRect)/sizeof(DAActionRect), NULL);
445 void buttonRelease(int button, int state, int x, int y)
447 if (button==1)
448 left_pressed=0;
449 if (player)
451 if (button == 1)
453 copyNumArea(0,51, 54, 20, 5,39);
454 DASetPixmap(pixmap);
455 DAProcessActionRects(x, y, buttonRects, sizeof(buttonRects)/sizeof(DAActionRect), NULL);
460 void buttonDrag(int x, int y)
462 motion_event=1;
463 if (left_pressed==1) {
464 DAProcessActionRects(x,y, volumeRects, 1, NULL);
465 DrawVolume();
466 DASetPixmap(pixmap);
470 int PlayerConnect(void)
472 GError *error = NULL;
473 static int previous_error_code = 0;
474 static char* player_name = NULL;
476 player = playerctl_player_new(NULL, &error);
477 if (error != NULL) {
478 /* don't spam error message */
479 if (error->code != previous_error_code)
480 DAWarning("Connection to player failed: %s",
481 error->message);
482 previous_error_code = error->code;
483 player_name = NULL;
484 return 0;
485 } else {
486 previous_error_code = 0;
487 if (!player_name) {
488 g_object_get(player, "player_name", &player_name, NULL);
489 player_name++; /* get rid of opening dot */
490 if (player_name)
491 DAWarning("Connected to %s", player_name);
493 return 1;
497 void DisplayRoutine()
499 int time = 0, length = 0, position = 100;
500 char *title = NULL;
501 GError *error = NULL;
503 PlayerConnect();
505 /* Compute diplay */
506 if (!player)
508 if (run_excusive)
509 exit(0);
510 title = strdup("--");
511 title_pos = 0;
512 arrow_pos = 5;
513 } else {
514 char *length_str, *position_str, *status;
516 g_object_get(player, "status", &status, NULL);
517 if (status) {
518 if (!strcmp(status, "Playing") ||
519 !strcmp(status, "Paused")) {
520 g_object_get(player, "position", &time, NULL);
522 title = playerctl_player_get_title(player,
523 &error);
524 if (error != NULL)
525 DAWarning("%s", error->message);
527 length_str =
528 playerctl_player_print_metadata_prop(
529 player, "mpris:length", &error);
530 if (error != NULL)
531 DAWarning("%s", error->message);
532 if (length_str)
533 length = atoi(length_str);
534 else
535 length = 0;
537 position_str =
538 playerctl_player_print_metadata_prop(
539 player, "xesam:trackNumber",
540 &error);
541 if (error != NULL)
542 DAWarning("%s", error->message);
543 if (position_str)
544 position = atoi(position_str);
545 else
546 position = 0;
548 if (!strcmp(status, "Paused") && pause_norotate)
549 arrow_pos = 5;
550 } else { /* not playing or paused */
551 title = strdup("--");
552 title_pos = 0;
553 arrow_pos = 5;
556 } else { /* status undefined */
557 title = strdup("--");
558 title_pos = 0;
559 arrow_pos = 5;
563 /*Draw everything */
564 if (t_time && length) DrawTime((length-time) / 1000);
565 else DrawTime(time / 1000);
566 DrawPos(position);
567 DrawArrow();
568 DrawVolume();
569 DrawTitle(title);
571 DASetPixmap(pixmap);
573 if (title != NULL)
574 free(title);
577 void DrawPos (int pos)
579 char posstr[16];
580 char *p = posstr;
581 int i=1;
583 if (pos > 99) pos=0;
584 sprintf(posstr, "%02d", pos);
586 for (;i<3; i++)
588 copyNumArea((*p-'0')*6 + 1, 1, 6, 7, (i*6)+39, 7);
589 p++;
593 void DrawTime(int time)
595 char timestr[16];
596 char *p = timestr;
597 int i=0;
599 time = time / 1000;
601 /* 3 cases:
602 * up to 99 minutes and 59 seconds
603 * up to 99 hours and 59 minutes
604 * more
606 if (time < 6000)
608 sprintf(timestr, "%02d%02d", time / 60, time % 60);
609 } else {
610 if (time < 360000)
612 sprintf(timestr, "%02d%02d", time / 3600,
613 time % 3600 / 60);
614 } else {
615 sprintf(timestr, "%02d%02d", 0, 0);
619 for (;i<4; i++)
621 copyNumArea((*p-'0')*7 + 2, 11, 7, 9, i<2 ?(i*7)+7:(i*7)+12, 7);
622 p++;
626 void DrawArrow(void)
628 copyNumArea((arrow_pos*8)+30, 22, 8, 9, 47, 19);
629 arrow_pos++;
630 if (arrow_pos > 4) arrow_pos = 0;
633 void DrawVolume(void)
635 int volume;
636 double volume_double = 0.0;
638 if (player)
639 g_object_get(player, "volume", &volume_double, NULL);
641 volume = (int)(36 * volume_double);
642 if (volume > 36)
643 volume = 36;
644 copyNumArea(61, 0, volume, 6, 7, 18);
645 copyNumArea(98, 0, 36-volume, 6, 7+volume, 18);
648 void DrawKbps(int bps)
650 char kbpstr[16];
651 char *p = kbpstr;
652 int i=1;
654 if (bps > 999000) bps=0;
655 sprintf(kbpstr, "%03d", bps / 1000);
657 for (;i<4; i++)
659 copyNumArea((*p-'0')*6 + 1, 1, 6, 7, (i*6)+1, 26);
660 p++;
662 copyNumArea(55, 39, 18, 8, 25, 26);
665 void DrawChar(wchar_t wc, int x, int y)
667 int i;
668 for(i = 0; i < sizeof(glyphs)/sizeof(glyphdescr) - 1; ++i)
670 if(wc == glyphs[i].c)
671 break;
673 copyNumArea(glyphs[i].x, glyphs[i].y, 6, 8, x, y);
676 int DrawChars(char *title, int tpos, int pos)
678 wchar_t wc;
680 mbtowc(NULL, NULL, 0);
681 while(*title && (pos <= (tpos + DISPLAYSIZE)))
683 int len = mbtowc(&wc, title, MB_CUR_MAX);
684 title += len;
685 if(pos >= tpos)
686 DrawChar(wc, (pos - tpos)*6 + 7, 26);
687 ++pos;
689 return pos;
692 void DrawTitle(char *name)
694 int len, pos, tpos = title_pos;
696 if (name == NULL)
697 return;
699 len = pos = DrawChars(name, tpos, 0);
701 if(pos < 6)
703 DrawChars(" ", tpos, pos);
704 return;
707 if(pos <= tpos + DISPLAYSIZE)
708 pos = DrawChars(SEPARATOR, tpos, pos);
710 if(pos <= tpos + DISPLAYSIZE)
711 DrawChars(name, tpos, pos);
713 if(tpos >= len + strlen(SEPARATOR))
714 title_pos = 0;
716 title_pos = title_pos + 0.5;
719 void ExecuteXmms(void)
721 char *command;
722 int status;
724 command=malloc(strlen(xmms_cmd)+5);
725 sprintf(command, "%s &", xmms_cmd);
726 status = system(command);
727 if (status)
729 fprintf(stderr, "XMMS can't be launched, exiting...");
730 exit(1);
732 while (!PlayerConnect())
733 usleep(10000L);
734 free(command);
736 /*----------------------------------------------------------------------------*/
737 /* Main */
738 /*----------------------------------------------------------------------------*/
740 int main(int argc, char **argv)
742 short unsigned int height, width;
743 DACallbacks callbacks={NULL, buttonPress, buttonRelease, buttonDrag,
744 NULL, NULL, NULL};
746 /* Initialization */
747 DAParseArguments(argc, argv, options,
748 sizeof(options)/sizeof(DAProgramOption),
749 "MPRIS-compatible media player remote control\n"
750 "by Bastien Nocera <hadess@hadess.net>\n"
751 "maintained by the Window Maker Team "
752 "<wmaker-dev@googlegroups.com>",
753 PACKAGE_STRING);
755 setlocale(LC_ALL, "");
756 DAInitialize(displayName, "wmusic", 64, 64, argc, argv);
757 DASetCallbacks(&callbacks);
758 DASetTimeout(100);
760 DAMakePixmapFromData(wmusic_master_xpm, &pixmap,
761 &mask, &height, &width);
762 DAMakePixmapFromData(wmusic_digits_xpm, &pixnum,
763 &masknum, &height, &width);
764 gc = DefaultGC(DADisplay, DefaultScreen(DADisplay));
765 DASetShapeWithOffset(mask, 0, 0);
767 DASetPixmap(pixmap);
768 DAShow();
770 /* End of initialization */
772 if (options[4].used) pause_norotate=1;
773 if (options[5].used) t_time=1;
774 if (options[6].used) run_excusive=1;
776 PlayerConnect();
778 /* Launch xmms if it's not running and -r or -R was used */
779 if ((!player) && (options[2].used || run_excusive))
781 ExecuteXmms();
784 /* Update the display */
785 DisplayRoutine();
787 while (1) {
788 if (DANextEventOrTimeout(&ev, 100))
789 DAProcessEvent(&ev);
790 if (!motion_event)
791 DisplayRoutine();
792 else
793 motion_event=0;
795 return 0;