1 /* wmusic - an MPRIS-compatible media player remote-controlling DockApp
2 * Copyright (C) 2000-2001 Bastien Nocera <hadess@hadess.net>
3 * Copyright (C) 2002-2004 John Chapin <john+wmusic@jtan.com>
4 * Copyright (C) 2018-2023 Window Maker Team <wmaker-dev@googlegroups.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #define DBL_CLICK_INTERVAL 250 /* double click interval in milliseconds */
22 #define ARROW_INTERVAL 100 /* arrow update interval in milliseconds */
23 #define SCROLL_INTERVAL 300 /* scroll update interval in milliseconds */
24 #define SEPARATOR " ** " /* The separator for the scrolling title */
25 #define DISPLAYSIZE 6 /* width of text to display (running title) */
27 #define PLAYER_INSTANCE_FROM_LIST(x) ((PlayerctlPlayerName *)x->data)->instance
29 #include <libdockapp/dockapp.h>
30 #include <playerctl/playerctl.h>
39 #include "wmusic-master.xpm"
40 #include "wmusic-digits.xpm"
42 /*---------------------------------------------------------------------------*/
44 /*---------------------------------------------------------------------------*/
46 void copyNumArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
);
47 void ActionPlay(int x
, int y
, DARect rect
, void *data
);
48 void ActionPause(int x
, int y
, DARect rect
, void *data
);
49 void ActionEject(int x
, int y
, DARect rect
, void *data
);
50 void ActionPrev(int x
, int y
, DARect rect
, void *data
);
51 void ActionNext(int x
, int y
, DARect rect
, void *data
);
52 void ActionStop(int x
, int y
, DARect rect
, void *data
);
53 void ActionFastr(int x
, int y
, DARect rect
, void *data
);
54 void ActionFastf(int x
, int y
, DARect rect
, void *data
);
55 void ToggleWins(int x
, int y
, DARect rect
, void *data
);
56 void ToggleVol(int x
, int y
, DARect rect
, void *data
);
57 void ChangeVol(int x
, int y
, DARect rect
, void *data
);
58 void ToggleTime(int x
, int y
, DARect rect
, void *data
);
59 void buttonPress(int button
, int state
, int x
, int y
);
60 void buttonRelease(int button
, int state
, int x
, int y
);
61 int PlayerConnect(void);
62 void DisplayRoutine();
63 void DrawTrackNum (int track_num
);
64 void DrawTime(gint64 time
);
66 void DrawVolume(void);
67 void DrawTitle(char *title
);
68 void ExecuteXmms(void);
70 /*----------------------------------------------------------------------------*/
72 /*----------------------------------------------------------------------------*/
75 char *displayName
= "";
79 /* Dockapp variables */
80 PlayerctlPlayer
*player
;
81 char *xmms_cmd
= "xmms";
82 Bool main_vis
=0, pl_vis
=0, eq_vis
=0;
83 unsigned int volume_step
= 5;
88 unsigned int arrow_pos
= 0;
89 Bool pause_norotate
= 0;
92 Pixmap pixmap
, mask
; /* Pixmap that is displayed */
93 Pixmap pixnum
, masknum
; /* Pixmap source */
95 int left_pressed
= 0; /* for pseudo drag callback */
96 int motion_event
= 0; /* on motion events we do not want(too fast) display update */
98 static DAActionRect buttonRects
[] = {
99 {{5, 39, 14, 9}, ActionPrev
},
100 {{19, 39, 14, 9}, ActionNext
},
101 {{33, 39, 13, 9}, ActionFastr
},
102 {{46, 39, 13, 9}, ActionFastf
},
103 {{5, 48, 11, 11}, ActionEject
},
104 {{16, 48, 21, 11}, ActionPlay
},
105 {{37, 48, 11, 11}, ActionPause
},
106 {{48, 48, 11, 11}, ActionStop
}
109 static DAActionRect toggleRect
[] = {
110 {{5, 5, 54, 30}, ToggleWins
}
113 static DAActionRect globRect
[] = {
114 {{0, 0, 64, 64}, ToggleVol
}
117 static DAActionRect displayRects
[] = {
118 {{5, 5, 54, 12}, ToggleTime
},
121 static DAActionRect volumeRects
[] = {
122 {{5, 17, 38, 8 }, ChangeVol
}
125 static DAProgramOption options
[] = {
126 {"-c", "--command", "Command to launch the media player", DOString
,
127 False
, {&xmms_cmd
} },
128 {"-d", "--display", "Display to use", DOString
, False
, {&displayName
} },
129 {"-r", "--run", "Run the media player on startup", DONone
, False
,
131 {"-V", "--volume", "Stepping of the wheel volume control (in percent)",
132 DONatural
, False
, {&volume_step
} },
133 {"-a", "--rotate-arrow", "Do not rotate the arrow, when paused",
134 DONone
, False
, {NULL
} },
135 {"-l", "--time-left", "Show time left instead of time remaining by default",
136 DONone
, False
, {NULL
} },
137 {"-R", "--run-excusive", "Run media player on startup, "
138 "exit when it exits", DONone
, False
, {NULL
} }
148 static glyphdescr glyphs
[] = {
149 {L
'-', 67, 83}, {L
'.', 73, 83}, {L
'\x27', 79, 83},
150 {L
'(', 85, 83}, {L
')', 91, 83}, {L
'*', 97, 83}, {L
'/', 103, 83},
152 {L
'0', 1, 83}, {L
'1', 7, 83}, {L
'2', 13, 83}, {L
'3', 19, 83}, {L
'4', 25, 83},
153 {L
'5', 31, 83}, {L
'6', 37, 83}, {L
'7', 43, 83}, {L
'8', 49, 83}, {L
'9', 55, 83},
157 {L
'A', 1, 73}, {L
'a', 1, 73},
158 {L
'B', 7, 73}, {L
'b', 7, 73},
159 {L
'C', 13, 73}, {L
'c', 13, 73},
160 {L
'D', 19, 73}, {L
'd', 19, 73},
161 {L
'E', 25, 73}, {L
'e', 25, 73},
163 {L
'F', 31, 73}, {L
'f', 31, 73},
164 {L
'G', 37, 73}, {L
'g', 37, 73},
165 {L
'H', 43, 73}, {L
'h', 43, 73},
166 {L
'I', 49, 73}, {L
'i', 49, 73},
167 {L
'J', 55, 73}, {L
'j', 55, 73},
169 {L
'K', 61, 73}, {L
'k', 61, 73},
170 {L
'L', 67, 73}, {L
'l', 67, 73},
171 {L
'M', 73, 73}, {L
'm', 73, 73},
172 {L
'N', 79, 73}, {L
'n', 79, 73},
173 {L
'O', 85, 73}, {L
'o', 85, 73},
175 {L
'P', 91, 73}, {L
'p', 91, 73},
176 {L
'Q', 97, 73}, {L
'q', 97, 73},
177 {L
'R',103, 73}, {L
'r',103, 73},
178 {L
'S',109, 73}, {L
's',109, 73},
179 {L
'T',115, 73}, {L
't',115, 73},
181 {L
'U',121, 73}, {L
'u',121, 73},
182 {L
'V',127, 73}, {L
'v',127, 73},
183 {L
'W',133, 73}, {L
'w',133, 73},
184 {L
'X',139, 73}, {L
'x',139, 73},
185 {L
'Y',145, 73}, {L
'y',145, 73},
187 {L
'Z',151, 73}, {L
'z',151, 73},
190 {L
'\x42e', 1, 93}, {L
'\x44e', 1, 93}, /* cyrillic Yu */
192 {L
'\x410', 7, 93}, {L
'\x430', 7, 93}, /* cyrillic A */
193 {L
'\x411', 13, 93}, {L
'\x431', 13, 93}, /* cyrillic Be */
194 {L
'\x426', 19, 93}, {L
'\x446', 19, 93}, /* cyrillic Ce */
195 {L
'\x414', 25, 93}, {L
'\x434', 25, 93}, /* cyrillic De */
196 {L
'\x415', 31, 93}, {L
'\x435', 31, 93}, /* cyrillic Ye */
198 {L
'\x424', 37, 93}, {L
'\x444', 37, 93}, /* cyrillic eF */
199 {L
'\x413', 43, 93}, {L
'\x433', 43, 93}, /* cyrillic Ge */
200 {L
'\x425', 49, 93}, {L
'\x445', 49, 93}, /* cyrillic Ha */
201 {L
'\x418', 55, 93}, {L
'\x438', 55, 93}, /* cyrillic I */
202 {L
'\x419', 61, 93}, {L
'\x439', 61, 93}, /* cyrillic I-kratkoe */
204 {L
'\x41a', 67, 93}, {L
'\x43a', 67, 93}, /* cyrillic Ka */
205 {L
'\x41b', 73, 93}, {L
'\x43b', 73, 93}, /* cyrillic eL */
206 {L
'\x41c', 79, 93}, {L
'\x43c', 79, 93}, /* cyrillic eM */
207 {L
'\x41d', 85, 93}, {L
'\x43d', 85, 93}, /* cyrillic eN */
208 {L
'\x41e', 91, 93}, {L
'\x43e', 91, 93}, /* cyrillic O */
210 {L
'\x41f', 97, 93}, {L
'\x43f', 97, 93}, /* cyrillic Pe */
211 {L
'\x42f',103, 93}, {L
'\x44f',103, 93}, /* cyrillic Ya */
212 {L
'\x420',109, 93}, {L
'\x440',109, 93}, /* cyrillic eR */
213 {L
'\x421',115, 93}, {L
'\x441',115, 93}, /* cyrillic eS */
214 {L
'\x422',121, 93}, {L
'\x442',121, 93}, /* cyrillic Te */
216 {L
'\x423',127, 93}, {L
'\x443',127, 93}, /* cyrillic U */
217 {L
'\x416',133, 93}, {L
'\x436',133, 93}, /* cyrillic Je */
218 {L
'\x412',139, 93}, {L
'\x432',139, 93}, /* cyrillic Ve */
219 {L
'\x42c',145, 93}, {L
'\x44c',145, 93}, /* cyrillic MyagkijZnak */
220 {L
'\x42b',151, 93}, {L
'\x44b',151, 93}, /* cyrillic Y */
222 {L
'\x417',157, 93}, {L
'\x437',157, 93}, /* cyrillic Ze */
223 {L
'\x428',163, 93}, {L
'\x448',163, 93}, /* cyrillic Sha */
224 {L
'\x42d',169, 93}, {L
'\x44d',169, 93}, /* cyrillic E */
225 {L
'\x429',175, 93}, {L
'\x449',175, 93}, /* cyrillic Scha */
226 {L
'\x427',181, 93}, {L
'\x447',181, 93}, /* cyrillic Che */
228 {L
'\x42a',187, 93}, {L
'\x44a',187, 93}, /* cyrillic TvyordyiZnak */
229 {L
'\x404',115, 83}, {L
'\x454',115, 83}, /* ukrainian IE */
230 {L
'\x406', 49, 73}, {L
'\x456', 49, 73}, /* ukrainian I */
231 {L
'\x407',109, 83}, {L
'\x457',109, 83}, /* ukrainian YI */
232 {L
'\x491', 43, 93}, {L
'\x490', 43, 93}, /* ukrainian GHE with upturn */
234 {L
'\x401',121, 83}, {L
'\x451',121, 83}, /* cyrillic Yo */
239 /*----------------------------------------------------------------------------*/
241 /*----------------------------------------------------------------------------*/
243 void copyNumArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
)
245 XCopyArea(DADisplay
, pixnum
, pixmap
, gc
, x
, y
, sx
, sy
, dx
, dy
);
248 void buttonDraw(DARect rect
)
250 copyNumArea((rect
.x
)-5, (rect
.y
)-8, rect
.width
, rect
.height
,
255 void ActionPlay(int x
, int y
, DARect rect
, void *data
)
260 GError
*error
= NULL
;
262 playerctl_player_play(player
, &error
);
264 DAWarning("Could not execute command: %s",
266 g_clear_error(&error
);
270 void ActionPause(int x
, int y
, DARect rect
, void *data
)
275 GError
*error
= NULL
;
277 playerctl_player_pause(player
, &error
);
279 DAWarning("Could not execute command: %s",
281 g_clear_error(&error
);
285 int CurrentPlayerIndex(GList
*players
)
288 char *player_instance
;
291 n
= g_list_length(players
);
292 g_object_get(player
, "player-instance", &player_instance
, NULL
);
295 if (g_strcmp0(PLAYER_INSTANCE_FROM_LIST(
296 g_list_nth(players
, i
)),
297 player_instance
) == 0)
304 g_free(player_instance
);
309 void ActionEject(int x
, int y
, DARect rect
, void *data
)
319 players
= playerctl_list_players(&error
);
321 DAWarning("%s", error
->message
);
322 g_clear_error(&error
);
324 n
= g_list_length(players
);
329 i
= CurrentPlayerIndex(players
);
331 if (i
== -1) /* can't find current player */
336 g_object_unref(player
);
338 player
= playerctl_player_new_from_name(
339 g_list_nth_data(players
, i
), &error
);
341 DAWarning("Connection to player "
342 "failed: %s", error
->message
);
343 g_clear_error(&error
);
345 DAWarning("Connected to %s",
346 PLAYER_INSTANCE_FROM_LIST(
347 g_list_nth(players
, i
)));
351 g_list_free_full(players
,
352 (GDestroyNotify
)playerctl_player_name_free
);
356 void ActionPrev(int x
, int y
, DARect rect
, void *data
)
361 GError
*error
= NULL
;
363 playerctl_player_previous(player
, &error
);
365 DAWarning("Could not execute command: %s",
367 g_clear_error(&error
);
371 void ActionNext(int x
, int y
, DARect rect
, void *data
)
376 GError
*error
= NULL
;
378 playerctl_player_next(player
, &error
);
380 DAWarning("Could not execute command: %s",
382 g_clear_error(&error
);
386 void ActionStop(int x
, int y
, DARect rect
, void *data
)
391 GError
*error
= NULL
;
393 playerctl_player_stop(player
, &error
);
395 DAWarning("Could not execute command: %s",
397 g_clear_error(&error
);
401 void ActionFastr(int x
, int y
, DARect rect
, void *data
)
406 GError
*error
= NULL
;
408 playerctl_player_seek(player
, -10000000, &error
);
410 DAWarning("Could not execute command: %s",
412 g_clear_error(&error
);
416 void ActionFastf(int x
, int y
, DARect rect
, void *data
)
421 GError
*error
= NULL
;
423 playerctl_player_seek(player
, 10000000, &error
);
425 DAWarning("Could not execute command: %s",
427 g_clear_error(&error
);
431 void ToggleWins(int x
, int y
, DARect rect
, void *data
)
434 if ( (ev
.xbutton
.time
-click_time
) <= DBL_CLICK_INTERVAL
)
439 click_time
=ev
.xbutton
.time
;
444 void ToggleVol(int x
, int y
, DARect rect
, void *data
)
450 g_object_get(player
, "volume", &volume
, NULL
);
452 if (*(int*)data
== 1)
453 factor
= 0.01 * volume_step
;
455 factor
= -0.01 * volume_step
;
464 playerctl_player_set_volume(player
, volume
, &err
);
466 DAWarning("Error setting volume: %s", err
->message
);
470 void ChangeVol(int x
, int y
, DARect rect
, void *data
)
472 float volume
= ((float)x
)/38;
476 playerctl_player_set_volume(player
, volume
, &err
);
478 DAWarning("Error setting volume: %s", err
->message
);
482 void ToggleTime(int x
, int y
, DARect rect
, void *data
)
489 void buttonPress(int button
, int state
, int x
, int y
)
498 DAProcessActionRects(x
, y
, buttonRects
, sizeof(buttonRects
)/sizeof(DAActionRect
), tmp
);
499 DAProcessActionRects(x
, y
, displayRects
, sizeof(displayRects
)/sizeof(DAActionRect
), tmp
);
503 DAProcessActionRects(x
, y
, toggleRect
, sizeof(toggleRect
)/sizeof(DAActionRect
), NULL
);
508 DAProcessActionRects(x
, y
, toggleRect
, sizeof(toggleRect
)/sizeof(DAActionRect
), tmp
);
510 if ((button
== 4) || (button
== 5))
514 /* Wheel scrolls down */
516 DAProcessActionRects(x
, y
, globRect
, sizeof(globRect
)/sizeof(DAActionRect
), &tmp
);
518 /* Wheel scrolls up */
520 DAProcessActionRects(x
, y
, globRect
, sizeof(globRect
)/sizeof(DAActionRect
), &tmp
);
525 DAProcessActionRects(x
, y
, toggleRect
, sizeof(toggleRect
)/sizeof(DAActionRect
), NULL
);
528 void buttonRelease(int button
, int state
, int x
, int y
)
536 copyNumArea(0,51, 54, 20, 5,39);
538 DAProcessActionRects(x
, y
, buttonRects
, sizeof(buttonRects
)/sizeof(DAActionRect
), NULL
);
543 void buttonDrag(int x
, int y
)
546 if (left_pressed
==1) {
547 DAProcessActionRects(x
,y
, volumeRects
, 1, NULL
);
553 int PlayerConnect(void)
555 GError
*error
= NULL
;
556 static int previous_error_code
= 0;
559 players
= playerctl_list_players(&error
);
561 DAWarning("%s", error
->message
);
562 g_clear_error(&error
);
564 /* check that current player is still connected */
565 if (player
&& CurrentPlayerIndex(players
) == -1) {
566 DAWarning("Disconnected from player");
567 g_object_unref(player
);
571 if (!player
&& g_list_length(players
) > 0) {
572 player
= playerctl_player_new_from_name(
573 g_list_nth_data(players
, 0), &error
);
575 /* don't spam error message */
576 if (error
->code
!= previous_error_code
)
577 DAWarning("Connection to player failed: %s",
579 previous_error_code
= error
->code
;
583 g_object_get(player
, "player-name",
586 DAWarning("Connected to %s", player_name
);
589 g_clear_error(&error
);
591 g_main_context_iteration(NULL
, FALSE
);
593 g_list_free_full(players
,
594 (GDestroyNotify
)playerctl_player_name_free
);
596 return player
? 1 : 0;
599 void DisplayRoutine()
601 gint64 position
= 0, length
= 0;
604 GError
*error
= NULL
;
613 title
= strdup("--");
617 char *length_str
, *track_num_str
;
618 PlayerctlPlaybackStatus status
;
620 g_object_get(player
, "playback-status", &status
, NULL
);
621 if (status
== PLAYERCTL_PLAYBACK_STATUS_PLAYING
||
622 status
== PLAYERCTL_PLAYBACK_STATUS_PAUSED
) {
623 if (status
== PLAYERCTL_PLAYBACK_STATUS_PAUSED
&&
627 position
= playerctl_player_get_position(player
,
630 DAWarning("%s", error
->message
);
631 g_clear_error(&error
);
633 title
= playerctl_player_get_title(player
,
636 DAWarning("%s", error
->message
);
637 g_clear_error(&error
);
640 playerctl_player_print_metadata_prop(
641 player
, "mpris:length", &error
);
643 DAWarning("%s", error
->message
);
644 g_clear_error(&error
);
646 length
= g_ascii_strtoull(length_str
,
653 playerctl_player_print_metadata_prop(
654 player
, "xesam:trackNumber",
657 DAWarning("%s", error
->message
);
658 g_clear_error(&error
);
660 track_num
= atoi(track_num_str
);
661 g_free(track_num_str
);
664 } else { /* not playing or paused */
665 title
= strdup("--");
672 DrawTime(t_time
&& length
? length
- position
: position
);
673 DrawTrackNum(track_num
);
684 void DrawTrackNum (int track_num
)
686 char track_num_str
[16];
687 char *p
= track_num_str
;
692 sprintf(track_num_str
, "%02d", track_num
);
696 copyNumArea((*p
-'0')*6 + 1, 1, 6, 7, (i
*6)+39, 7);
701 void DrawTime(gint64 time
)
710 * up to 99 minutes and 59 seconds
711 * up to 99 hours and 59 minutes
716 int m
= time
/ 60, s
= time
% 60;
718 sprintf(timestr
, "%02d%02d", m
, s
);
720 else if (time
< 360000)
722 int h
= time
/ 3600, m
= time
% 3600;
724 sprintf(timestr
, "%02d%02d", h
, m
);
727 strcpy (timestr
, "0000");
731 copyNumArea((*p
-'0')*7 + 2, 11, 7, 9, i
<2 ?(i
*7)+7:(i
*7)+12, 7);
738 copyNumArea((arrow_pos
*8)+30, 22, 8, 9, 47, 19);
740 if (arrow_pos
> 4) arrow_pos
= 0;
743 void DrawVolume(void)
746 double volume_double
= 0.0;
749 g_object_get(player
, "volume", &volume_double
, NULL
);
751 volume
= (int)(36 * volume_double
);
754 copyNumArea(61, 0, volume
, 6, 7, 18);
755 copyNumArea(98, 0, 36-volume
, 6, 7+volume
, 18);
758 void DrawKbps(int bps
)
764 if (bps
> 999000) bps
=0;
765 sprintf(kbpstr
, "%03d", bps
/ 1000);
769 copyNumArea((*p
-'0')*6 + 1, 1, 6, 7, (i
*6)+1, 26);
772 copyNumArea(55, 39, 18, 8, 25, 26);
775 void DrawChar(wchar_t wc
, int x
, int y
)
778 for(i
= 0; i
< sizeof(glyphs
)/sizeof(glyphdescr
) - 1; ++i
)
780 if(wc
== glyphs
[i
].c
)
783 copyNumArea(glyphs
[i
].x
, glyphs
[i
].y
, 6, 8, x
, y
);
786 int DrawChars(char *title
, int tpos
, int pos
)
790 mbtowc(NULL
, NULL
, 0);
791 while(*title
&& (pos
<= (tpos
+ DISPLAYSIZE
)))
793 int len
= mbtowc(&wc
, title
, MB_CUR_MAX
);
796 DrawChar(wc
, (pos
- tpos
)*6 + 7, 26);
802 void DrawTitle(char *name
)
804 int len
, pos
, tpos
= title_pos
;
809 len
= pos
= DrawChars(name
, tpos
, 0);
813 DrawChars(" ", tpos
, pos
);
817 if(pos
<= tpos
+ DISPLAYSIZE
)
818 pos
= DrawChars(SEPARATOR
, tpos
, pos
);
820 if(pos
<= tpos
+ DISPLAYSIZE
)
821 DrawChars(name
, tpos
, pos
);
823 if(tpos
>= len
+ strlen(SEPARATOR
))
826 title_pos
= title_pos
+ 0.5;
829 void ExecuteXmms(void)
834 command
=malloc(strlen(xmms_cmd
)+5);
835 sprintf(command
, "%s &", xmms_cmd
);
836 status
= system(command
);
839 fprintf(stderr
, "XMMS can't be launched, exiting...");
842 while (!PlayerConnect())
846 /*----------------------------------------------------------------------------*/
848 /*----------------------------------------------------------------------------*/
850 int main(int argc
, char **argv
)
852 short unsigned int height
, width
;
853 DACallbacks callbacks
={NULL
, buttonPress
, buttonRelease
, buttonDrag
,
857 DAParseArguments(argc
, argv
, options
,
858 sizeof(options
)/sizeof(DAProgramOption
),
859 "MPRIS-compatible media player remote control\n"
860 "by Bastien Nocera <hadess@hadess.net>\n"
861 "maintained by the Window Maker Team "
862 "<wmaker-dev@googlegroups.com>",
865 setlocale(LC_ALL
, "");
866 DAInitialize(displayName
, "wmusic", 64, 64, argc
, argv
);
867 DASetCallbacks(&callbacks
);
870 DAMakePixmapFromData(wmusic_master_xpm
, &pixmap
,
871 &mask
, &height
, &width
);
872 DAMakePixmapFromData(wmusic_digits_xpm
, &pixnum
,
873 &masknum
, &height
, &width
);
874 gc
= DefaultGC(DADisplay
, DefaultScreen(DADisplay
));
875 DASetShapeWithOffset(mask
, 0, 0);
880 /* End of initialization */
882 if (options
[4].used
) pause_norotate
=1;
883 if (options
[5].used
) t_time
=1;
884 if (options
[6].used
) run_excusive
=1;
888 /* Launch xmms if it's not running and -r or -R was used */
889 if ((!player
) && (options
[2].used
|| run_excusive
))
894 /* Update the display */
898 if (DANextEventOrTimeout(&ev
, 100))