comparison src/hotkey/plugin.c @ 2273:f893d05f707b

Hotkey: some cleaning and simplifying
author Sascha Hlusiak <contact@saschahlusiak.de>
date Mon, 31 Dec 2007 17:38:27 +0100
parents b8da6a0b0da2
children d9706e29e968
comparison
equal deleted inserted replaced
2272:a7c0e58fa489 2273:f893d05f707b
1 /* -*- Mode: C; indent-tabs: t; c-basic-offset: 9; tab-width: 9 -*- */ 1 /* -*- Mode: C; indent-tabs: t; c-basic-offset: 9; tab-width: 9 -*- */
2 /* 2 /*
3 * This file is part of audacious-hotkey plugin for audacious 3 * This file is part of audacious-hotkey plugin for audacious
4 * 4 *
5 * Copyright (c) 2007 Sascha Hlusiak <contact@saschahlusiak.de> 5 * Copyright (c) 2007 - 2008 Sascha Hlusiak <contact@saschahlusiak.de>
6 * Name: plugin.c 6 * Name: plugin.c
7 * Description: plugin.c 7 * Description: plugin.c
8 * 8 *
9 * Part of this code is from itouch-ctrl plugin. 9 * Part of this code is from itouch-ctrl plugin.
10 * Authors of itouch-ctrl are listed below: 10 * Authors of itouch-ctrl are listed below:
73 void cancel_callback (GtkWidget *widget, gpointer data); 73 void cancel_callback (GtkWidget *widget, gpointer data);
74 void ok_callback (GtkWidget *widget, gpointer data); 74 void ok_callback (GtkWidget *widget, gpointer data);
75 static void about (void); 75 static void about (void);
76 static void cleanup (void); 76 static void cleanup (void);
77 77
78 #define TYPE_KEY 0
79 #define TYPE_MOUSE 1
80
81
82 typedef struct {
83 gint key, mask;
84 gint type;
85 } HotkeyConfiguration;
86
78 typedef struct { 87 typedef struct {
79 gint vol_increment; 88 gint vol_increment;
80 gint vol_decrement; 89 gint vol_decrement;
81 90
82 /* keyboard */ 91 /* keyboard */
83 gint mute, mute_mask; 92 HotkeyConfiguration mute;
84 gint vol_down, vol_down_mask; 93 HotkeyConfiguration vol_down;
85 gint vol_up, vol_up_mask; 94 HotkeyConfiguration vol_up;
86 gint play, play_mask; 95 HotkeyConfiguration play;
87 gint stop, stop_mask; 96 HotkeyConfiguration stop;
88 gint pause, pause_mask; 97 HotkeyConfiguration pause;
89 gint prev_track, prev_track_mask; 98 HotkeyConfiguration prev_track;
90 gint next_track, next_track_mask; 99 HotkeyConfiguration next_track;
91 gint jump_to_file, jump_to_file_mask; 100 HotkeyConfiguration jump_to_file;
92 gint toggle_win, toggle_win_mask; 101 HotkeyConfiguration toggle_win;
93 102 HotkeyConfiguration forward;
94 gint forward, forward_mask; 103 HotkeyConfiguration backward;
95 gint backward, backward_mask;
96 } PluginConfig; 104 } PluginConfig;
97 105
98 PluginConfig plugin_cfg; 106 PluginConfig plugin_cfg;
99 107
100 static Display *xdisplay = NULL; 108 static Display *xdisplay = NULL;
107 115
108 116
109 117
110 typedef struct { 118 typedef struct {
111 GtkWidget *keytext; 119 GtkWidget *keytext;
112 gint key, mask; 120 HotkeyConfiguration hotkey;
113 } KeyControls; 121 } KeyControls;
114 122
115 typedef struct { 123 typedef struct {
116 KeyControls play; 124 KeyControls play;
117 KeyControls stop; 125 KeyControls stop;
118 KeyControls pause; 126 KeyControls pause;
119 KeyControls prev; 127 KeyControls prev_track;
120 KeyControls next; 128 KeyControls next_track;
121 KeyControls up; 129 KeyControls vol_up;
122 KeyControls down; 130 KeyControls vol_down;
123 KeyControls mute; 131 KeyControls mute;
124 KeyControls jump_to_file; 132 KeyControls jump_to_file;
125 KeyControls forward; 133 KeyControls forward;
126 KeyControls backward; 134 KeyControls backward;
127 KeyControls toggle_win; 135 KeyControls toggle_win;
223 } 231 }
224 232
225 state &= ~(scrolllock_mask | numlock_mask | capslock_mask); 233 state &= ~(scrolllock_mask | numlock_mask | capslock_mask);
226 234
227 /* mute the playback */ 235 /* mute the playback */
228 if ((keycode == plugin_cfg.mute) && (state == plugin_cfg.mute_mask)) 236 if ((keycode == plugin_cfg.mute.key) && (state == plugin_cfg.mute.mask))
229 { 237 {
230 if (!mute) 238 if (!mute)
231 { 239 {
232 volume_static = current_volume; 240 volume_static = current_volume;
233 audacious_drct_set_main_volume (0); 241 audacious_drct_set_main_volume (0);
238 } 246 }
239 return TRUE; 247 return TRUE;
240 } 248 }
241 249
242 /* decreace volume */ 250 /* decreace volume */
243 if ((keycode == plugin_cfg.vol_down) && (state == plugin_cfg.vol_down_mask)) 251 if ((keycode == plugin_cfg.vol_down.key) && (state == plugin_cfg.vol_down.mask))
244 { 252 {
245 if (mute) 253 if (mute)
246 { 254 {
247 current_volume = old_volume; 255 current_volume = old_volume;
248 old_volume = 0; 256 old_volume = 0;
262 old_volume = current_volume; 270 old_volume = current_volume;
263 return TRUE; 271 return TRUE;
264 } 272 }
265 273
266 /* increase volume */ 274 /* increase volume */
267 if ((keycode == plugin_cfg.vol_up) && (state == plugin_cfg.vol_up_mask)) 275 if ((keycode == plugin_cfg.vol_up.key) && (state == plugin_cfg.vol_up.mask))
268 { 276 {
269 if (mute) 277 if (mute)
270 { 278 {
271 current_volume = old_volume; 279 current_volume = old_volume;
272 old_volume = 0; 280 old_volume = 0;
286 old_volume = current_volume; 294 old_volume = current_volume;
287 return TRUE; 295 return TRUE;
288 } 296 }
289 297
290 /* play */ 298 /* play */
291 if ((keycode == plugin_cfg.play) && (state == plugin_cfg.play_mask)) 299 if ((keycode == plugin_cfg.play.key) && (state == plugin_cfg.play.mask))
292 { 300 {
293 if (!play) 301 if (!play)
294 { 302 {
295 audacious_drct_play (); 303 audacious_drct_play ();
296 } else { 304 } else {
298 } 306 }
299 return TRUE; 307 return TRUE;
300 } 308 }
301 309
302 /* pause */ 310 /* pause */
303 if ((keycode == plugin_cfg.pause) && (state == plugin_cfg.pause_mask)) 311 if ((keycode == plugin_cfg.pause.key) && (state == plugin_cfg.pause.mask))
304 { 312 {
305 if (!play) audacious_drct_play (); 313 if (!play) audacious_drct_play ();
306 else audacious_drct_pause (); 314 else audacious_drct_pause ();
307 315
308 return TRUE; 316 return TRUE;
309 } 317 }
310 318
311 /* stop */ 319 /* stop */
312 if ((keycode == plugin_cfg.stop) && (state == plugin_cfg.stop_mask)) 320 if ((keycode == plugin_cfg.stop.key) && (state == plugin_cfg.stop.mask))
313 { 321 {
314 audacious_drct_stop (); 322 audacious_drct_stop ();
315 return TRUE; 323 return TRUE;
316 } 324 }
317 325
318 /* prev track */ 326 /* prev track */
319 if ((keycode == plugin_cfg.prev_track) && (state == plugin_cfg.prev_track_mask)) 327 if ((keycode == plugin_cfg.prev_track.key) && (state == plugin_cfg.prev_track.mask))
320 { 328 {
321 audacious_drct_playlist_prev (); 329 audacious_drct_playlist_prev ();
322 return TRUE; 330 return TRUE;
323 } 331 }
324 332
325 /* next track */ 333 /* next track */
326 if ((keycode == plugin_cfg.next_track) && (state == plugin_cfg.next_track_mask)) 334 if ((keycode == plugin_cfg.next_track.key) && (state == plugin_cfg.next_track.mask))
327 { 335 {
328 audacious_drct_playlist_next (); 336 audacious_drct_playlist_next ();
329 return TRUE; 337 return TRUE;
330 } 338 }
331 339
332 /* forward */ 340 /* forward */
333 if ((keycode == plugin_cfg.forward) && (state == plugin_cfg.forward_mask)) 341 if ((keycode == plugin_cfg.forward.key) && (state == plugin_cfg.forward.mask))
334 { 342 {
335 gint time = audacious_drct_get_output_time(); 343 gint time = audacious_drct_get_output_time();
336 time += 5000; /* Jump 5s into future */ 344 time += 5000; /* Jump 5s into future */
337 audacious_drct_jump_to_time(time); 345 audacious_drct_jump_to_time(time);
338 return TRUE; 346 return TRUE;
339 } 347 }
340 348
341 /* backward */ 349 /* backward */
342 if ((keycode == plugin_cfg.backward) && (state == plugin_cfg.backward_mask)) 350 if ((keycode == plugin_cfg.backward.key) && (state == plugin_cfg.backward.mask))
343 { 351 {
344 gint time = audacious_drct_get_output_time(); 352 gint time = audacious_drct_get_output_time();
345 if (time > 5000) time -= 5000; /* Jump 5s back */ 353 if (time > 5000) time -= 5000; /* Jump 5s back */
346 else time = 0; 354 else time = 0;
347 audacious_drct_jump_to_time(time); 355 audacious_drct_jump_to_time(time);
348 return TRUE; 356 return TRUE;
349 } 357 }
350 358
351 /* Open Jump-To-File dialog */ 359 /* Open Jump-To-File dialog */
352 if ((keycode == plugin_cfg.jump_to_file) && (state == plugin_cfg.jump_to_file_mask)) 360 if ((keycode == plugin_cfg.jump_to_file.key) && (state == plugin_cfg.jump_to_file.mask))
353 { 361 {
354 audacious_drct_show_jtf_box(); 362 audacious_drct_show_jtf_box();
355 return TRUE; 363 return TRUE;
356 } 364 }
357 365
358 /* Toggle Windows */ 366 /* Toggle Windows */
359 if ((keycode == plugin_cfg.toggle_win) && (state == plugin_cfg.toggle_win_mask)) 367 if ((keycode == plugin_cfg.toggle_win.key) && (state == plugin_cfg.toggle_win.mask))
360 { 368 {
361 static gboolean is_main, is_eq, is_pl; 369 static gboolean is_main, is_eq, is_pl;
362 is_main = audacious_drct_main_win_is_visible(); 370 is_main = audacious_drct_main_win_is_visible();
363 if (is_main) { 371 if (is_main) {
364 is_pl = audacious_drct_pl_win_is_visible(); 372 is_pl = audacious_drct_pl_win_is_visible();
419 427
420 /* default volume level */ 428 /* default volume level */
421 plugin_cfg.vol_increment = 4; 429 plugin_cfg.vol_increment = 4;
422 plugin_cfg.vol_decrement = 4; 430 plugin_cfg.vol_decrement = 4;
423 431
424 plugin_cfg.mute = XKeysymToKeycode(xdisplay, XF86XK_AudioMute); 432 #define load_key(hotkey,default) \
425 plugin_cfg.mute_mask = 0; 433 plugin_cfg.hotkey.key = (default)?(XKeysymToKeycode(xdisplay, (default))):0; \
426 plugin_cfg.vol_down = XKeysymToKeycode(xdisplay, XF86XK_AudioLowerVolume); 434 plugin_cfg.hotkey.mask = 0; \
427 plugin_cfg.vol_down_mask = 0; 435 plugin_cfg.hotkey.type = TYPE_KEY; \
428 plugin_cfg.vol_up = XKeysymToKeycode(xdisplay, XF86XK_AudioRaiseVolume); 436 aud_cfg_db_get_int (cfdb, "globalHotkey", #hotkey, &plugin_cfg.hotkey.key); \
429 plugin_cfg.vol_up_mask = 0; 437 aud_cfg_db_get_int (cfdb, "globalHotkey", #hotkey "_mask", &plugin_cfg.hotkey.mask); \
430 plugin_cfg.play = XKeysymToKeycode(xdisplay, XF86XK_AudioPlay); 438 aud_cfg_db_get_int (cfdb, "globalHotkey", #hotkey "_type", &plugin_cfg.hotkey.type);
431 plugin_cfg.play_mask = 0; 439
432 plugin_cfg.pause = XKeysymToKeycode(xdisplay, XF86XK_AudioPause);
433 plugin_cfg.pause_mask = 0;
434 plugin_cfg.stop = XKeysymToKeycode(xdisplay, XF86XK_AudioStop);
435 plugin_cfg.stop_mask = 0;
436 plugin_cfg.prev_track = XKeysymToKeycode(xdisplay, XF86XK_AudioPrev);
437 plugin_cfg.prev_track_mask = 0;
438 plugin_cfg.next_track = XKeysymToKeycode(xdisplay, XF86XK_AudioNext);
439 plugin_cfg.next_track_mask = 0;
440 plugin_cfg.jump_to_file = XKeysymToKeycode(xdisplay, XF86XK_AudioMedia);
441 plugin_cfg.jump_to_file_mask = 0;
442 plugin_cfg.forward = 0;
443 plugin_cfg.forward_mask = 0;
444 plugin_cfg.backward = XKeysymToKeycode(xdisplay, XF86XK_AudioRewind);
445 plugin_cfg.backward_mask = 0;
446 plugin_cfg.toggle_win = 0;
447 plugin_cfg.toggle_win_mask = 0;
448 440
449 /* open configuration database */ 441 /* open configuration database */
450 cfdb = aud_cfg_db_open ( ); 442 cfdb = aud_cfg_db_open ( );
451 443
452 aud_cfg_db_get_int (cfdb, "globalHotkey", "mute", &plugin_cfg.mute); 444 load_key(mute, XF86XK_AudioMute);
453 aud_cfg_db_get_int (cfdb, "globalHotkey", "mute_mask", &plugin_cfg.mute_mask); 445 load_key(vol_down, XF86XK_AudioLowerVolume);
454 aud_cfg_db_get_int (cfdb, "globalHotkey", "vol_down", &plugin_cfg.vol_down); 446 load_key(vol_up, XF86XK_AudioRaiseVolume);
455 aud_cfg_db_get_int (cfdb, "globalHotkey", "vol_down_mask", &plugin_cfg.vol_down_mask); 447 load_key(play, XF86XK_AudioPlay);
456 aud_cfg_db_get_int (cfdb, "globalHotkey", "vol_up", &plugin_cfg.vol_up); 448 load_key(pause, XF86XK_AudioPause);
457 aud_cfg_db_get_int (cfdb, "globalHotkey", "vol_up_mask", &plugin_cfg.vol_up_mask); 449 load_key(stop, XF86XK_AudioStop);
458 aud_cfg_db_get_int (cfdb, "globalHotkey", "play", &plugin_cfg.play); 450 load_key(prev_track, XF86XK_AudioPrev);
459 aud_cfg_db_get_int (cfdb, "globalHotkey", "play_mask", &plugin_cfg.play_mask); 451 load_key(next_track, XF86XK_AudioNext);
460 aud_cfg_db_get_int (cfdb, "globalHotkey", "pause", &plugin_cfg.pause); 452 load_key(jump_to_file, XF86XK_AudioMedia);
461 aud_cfg_db_get_int (cfdb, "globalHotkey", "pause_mask", &plugin_cfg.pause_mask); 453 load_key(toggle_win, 0);
462 aud_cfg_db_get_int (cfdb, "globalHotkey", "stop", &plugin_cfg.stop); 454 load_key(forward, 0);
463 aud_cfg_db_get_int (cfdb, "globalHotkey", "stop_mask", &plugin_cfg.stop_mask); 455 load_key(backward, XF86XK_AudioRewind);
464 aud_cfg_db_get_int (cfdb, "globalHotkey", "prev_track", &plugin_cfg.prev_track);
465 aud_cfg_db_get_int (cfdb, "globalHotkey", "prev_track_mask", &plugin_cfg.prev_track_mask);
466 aud_cfg_db_get_int (cfdb, "globalHotkey", "next_track", &plugin_cfg.next_track);
467 aud_cfg_db_get_int (cfdb, "globalHotkey", "next_track_mask", &plugin_cfg.next_track_mask);
468 aud_cfg_db_get_int (cfdb, "globalHotkey", "jump_to_file", &plugin_cfg.jump_to_file);
469 aud_cfg_db_get_int (cfdb, "globalHotkey", "jump_to_file_mask", &plugin_cfg.jump_to_file_mask);
470 aud_cfg_db_get_int (cfdb, "globalHotkey", "forward", &plugin_cfg.forward);
471 aud_cfg_db_get_int (cfdb, "globalHotkey", "forward_mask", &plugin_cfg.forward_mask);
472 aud_cfg_db_get_int (cfdb, "globalHotkey", "backward", &plugin_cfg.backward);
473 aud_cfg_db_get_int (cfdb, "globalHotkey", "backward_mask", &plugin_cfg.backward_mask);
474 aud_cfg_db_get_int (cfdb, "globalHotkey", "toggle_win", &plugin_cfg.toggle_win);
475 aud_cfg_db_get_int (cfdb, "globalHotkey", "toggle_win_mask", &plugin_cfg.toggle_win_mask);
476 456
477 aud_cfg_db_close (cfdb); 457 aud_cfg_db_close (cfdb);
478 } 458 }
479 459
480 /* save plugin configuration */ 460 /* save plugin configuration */
481 static void save_config (void) 461 static void save_config (void)
482 { 462 {
483 ConfigDb *cfdb; 463 ConfigDb *cfdb;
464
465 #define save_key(hotkey) \
466 aud_cfg_db_set_int (cfdb, "globalHotkey", #hotkey, plugin_cfg.hotkey.key); \
467 aud_cfg_db_set_int (cfdb, "globalHotkey", #hotkey "_mask", plugin_cfg.hotkey.mask); \
468 aud_cfg_db_set_int (cfdb, "globalHotkey", #hotkey "_type", plugin_cfg.hotkey.type);
484 469
485 /* open configuration database */ 470 /* open configuration database */
486 cfdb = aud_cfg_db_open ( ); 471 cfdb = aud_cfg_db_open ( );
487 472
488 aud_cfg_db_set_int (cfdb, "globalHotkey", "mute", plugin_cfg.mute); 473 save_key(mute);
489 aud_cfg_db_set_int (cfdb, "globalHotkey", "mute_mask", plugin_cfg.mute_mask); 474 save_key(vol_up);
490 aud_cfg_db_set_int (cfdb, "globalHotkey", "vol_up", plugin_cfg.vol_up); 475 save_key(vol_down);
491 aud_cfg_db_set_int (cfdb, "globalHotkey", "vol_up_mask", plugin_cfg.vol_up_mask); 476 save_key(play);
492 aud_cfg_db_set_int (cfdb, "globalHotkey", "vol_down", plugin_cfg.vol_down); 477 save_key(pause);
493 aud_cfg_db_set_int (cfdb, "globalHotkey", "vol_down_mask", plugin_cfg.vol_down_mask); 478 save_key(stop);
494 aud_cfg_db_set_int (cfdb, "globalHotkey", "play", plugin_cfg.play); 479 save_key(prev_track);
495 aud_cfg_db_set_int (cfdb, "globalHotkey", "play_mask", plugin_cfg.play_mask); 480 save_key(next_track);
496 aud_cfg_db_set_int (cfdb, "globalHotkey", "pause", plugin_cfg.pause); 481 save_key(jump_to_file);
497 aud_cfg_db_set_int (cfdb, "globalHotkey", "pause_mask", plugin_cfg.pause_mask); 482 save_key(forward);
498 aud_cfg_db_set_int (cfdb, "globalHotkey", "stop", plugin_cfg.stop); 483 save_key(backward);
499 aud_cfg_db_set_int (cfdb, "globalHotkey", "stop_mask", plugin_cfg.stop_mask); 484 save_key(toggle_win);
500 aud_cfg_db_set_int (cfdb, "globalHotkey", "prev_track", plugin_cfg.prev_track); 485
501 aud_cfg_db_set_int (cfdb, "globalHotkey", "prev_track_mask", plugin_cfg.prev_track_mask);
502 aud_cfg_db_set_int (cfdb, "globalHotkey", "next_track", plugin_cfg.next_track);
503 aud_cfg_db_set_int (cfdb, "globalHotkey", "next_track_mask", plugin_cfg.next_track_mask);
504 aud_cfg_db_set_int (cfdb, "globalHotkey", "jump_to_file", plugin_cfg.jump_to_file);
505 aud_cfg_db_set_int (cfdb, "globalHotkey", "jump_to_file_mask", plugin_cfg.jump_to_file_mask);
506 aud_cfg_db_set_int (cfdb, "globalHotkey", "forward", plugin_cfg.forward);
507 aud_cfg_db_set_int (cfdb, "globalHotkey", "forward_mask", plugin_cfg.forward_mask);
508 aud_cfg_db_set_int (cfdb, "globalHotkey", "backward", plugin_cfg.backward);
509 aud_cfg_db_set_int (cfdb, "globalHotkey", "backward_mask", plugin_cfg.backward_mask);
510 aud_cfg_db_set_int (cfdb, "globalHotkey", "toggle_win", plugin_cfg.toggle_win);
511 aud_cfg_db_set_int (cfdb, "globalHotkey", "toggle_win_mask", plugin_cfg.toggle_win_mask);
512 aud_cfg_db_close (cfdb); 486 aud_cfg_db_close (cfdb);
513 } 487 }
514 488
515 static int x11_error_handler (Display *dpy, XErrorEvent *error) 489 static int x11_error_handler (Display *dpy, XErrorEvent *error)
516 { 490 {
517 return 0; 491 return 0;
518 } 492 }
519 493
520 /* grab requied keys */ 494 /* grab requied keys */
521 static void grab_key(KeyCode keycode, unsigned int modifier) 495 static void grab_key(HotkeyConfiguration hotkey)
522 { 496 {
523 modifier &= ~(numlock_mask | capslock_mask | scrolllock_mask); 497 unsigned int modifier = hotkey.mask & ~(numlock_mask | capslock_mask | scrolllock_mask);
524 498
525 XGrabKey (xdisplay, keycode, modifier, x_root_window, 499 if (hotkey.key == 0) return;
500
501 XGrabKey (xdisplay, hotkey.key, modifier, x_root_window,
526 False, GrabModeAsync, GrabModeAsync); 502 False, GrabModeAsync, GrabModeAsync);
527 503
528 if (modifier == AnyModifier) 504 if (modifier == AnyModifier)
529 return; 505 return;
530 506
531 if (numlock_mask) 507 if (numlock_mask)
532 XGrabKey (xdisplay, keycode, modifier | numlock_mask, 508 XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask,
533 x_root_window, 509 x_root_window,
534 False, GrabModeAsync, GrabModeAsync); 510 False, GrabModeAsync, GrabModeAsync);
535 511
536 if (capslock_mask) 512 if (capslock_mask)
537 XGrabKey (xdisplay, keycode, modifier | capslock_mask, 513 XGrabKey (xdisplay, hotkey.key, modifier | capslock_mask,
538 x_root_window, 514 x_root_window,
539 False, GrabModeAsync, GrabModeAsync); 515 False, GrabModeAsync, GrabModeAsync);
540 516
541 if (scrolllock_mask) 517 if (scrolllock_mask)
542 XGrabKey (xdisplay, keycode, modifier | scrolllock_mask, 518 XGrabKey (xdisplay, hotkey.key, modifier | scrolllock_mask,
543 x_root_window, 519 x_root_window,
544 False, GrabModeAsync, GrabModeAsync); 520 False, GrabModeAsync, GrabModeAsync);
545 521
546 if (numlock_mask && capslock_mask) 522 if (numlock_mask && capslock_mask)
547 XGrabKey (xdisplay, keycode, modifier | numlock_mask | capslock_mask, 523 XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask,
548 x_root_window, 524 x_root_window,
549 False, GrabModeAsync, GrabModeAsync); 525 False, GrabModeAsync, GrabModeAsync);
550 526
551 if (numlock_mask && scrolllock_mask) 527 if (numlock_mask && scrolllock_mask)
552 XGrabKey (xdisplay, keycode, modifier | numlock_mask | scrolllock_mask, 528 XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask | scrolllock_mask,
553 x_root_window, 529 x_root_window,
554 False, GrabModeAsync, GrabModeAsync); 530 False, GrabModeAsync, GrabModeAsync);
555 531
556 if (capslock_mask && scrolllock_mask) 532 if (capslock_mask && scrolllock_mask)
557 XGrabKey (xdisplay, keycode, modifier | capslock_mask | scrolllock_mask, 533 XGrabKey (xdisplay, hotkey.key, modifier | capslock_mask | scrolllock_mask,
558 x_root_window, 534 x_root_window,
559 False, GrabModeAsync, GrabModeAsync); 535 False, GrabModeAsync, GrabModeAsync);
560 536
561 if (numlock_mask && capslock_mask && scrolllock_mask) 537 if (numlock_mask && capslock_mask && scrolllock_mask)
562 XGrabKey (xdisplay, keycode, 538 XGrabKey (xdisplay, hotkey.key,
563 modifier | numlock_mask | capslock_mask | scrolllock_mask, 539 modifier | numlock_mask | capslock_mask | scrolllock_mask,
564 x_root_window, False, GrabModeAsync, 540 x_root_window, False, GrabModeAsync,
565 GrabModeAsync); 541 GrabModeAsync);
566 } 542 }
567 543
573 549
574 XErrorHandler old_handler = 0; 550 XErrorHandler old_handler = 0;
575 551
576 XSync(xdisplay, False); 552 XSync(xdisplay, False);
577 old_handler = XSetErrorHandler (x11_error_handler); 553 old_handler = XSetErrorHandler (x11_error_handler);
578 554
579 if (plugin_cfg.mute) grab_key(plugin_cfg.mute, plugin_cfg.mute_mask); 555 grab_key(plugin_cfg.mute);
580 if (plugin_cfg.vol_up) grab_key(plugin_cfg.vol_up, plugin_cfg.vol_up_mask); 556 grab_key(plugin_cfg.vol_up);
581 if (plugin_cfg.vol_down) grab_key(plugin_cfg.vol_down, plugin_cfg.vol_down_mask); 557 grab_key(plugin_cfg.vol_down);
582 if (plugin_cfg.play) grab_key(plugin_cfg.play, plugin_cfg.play_mask); 558 grab_key(plugin_cfg.play);
583 if (plugin_cfg.pause) grab_key(plugin_cfg.pause, plugin_cfg.pause_mask); 559 grab_key(plugin_cfg.pause);
584 if (plugin_cfg.stop) grab_key(plugin_cfg.stop, plugin_cfg.stop_mask); 560 grab_key(plugin_cfg.stop);
585 if (plugin_cfg.prev_track) grab_key(plugin_cfg.prev_track, plugin_cfg.prev_track_mask); 561 grab_key(plugin_cfg.prev_track);
586 if (plugin_cfg.next_track) grab_key(plugin_cfg.next_track, plugin_cfg.next_track_mask); 562 grab_key(plugin_cfg.next_track);
587 if (plugin_cfg.jump_to_file) grab_key(plugin_cfg.jump_to_file, plugin_cfg.jump_to_file_mask); 563 grab_key(plugin_cfg.jump_to_file);
588 if (plugin_cfg.forward) grab_key(plugin_cfg.forward, plugin_cfg.forward_mask); 564 grab_key(plugin_cfg.forward);
589 if (plugin_cfg.backward) grab_key(plugin_cfg.backward, plugin_cfg.backward_mask); 565 grab_key(plugin_cfg.backward);
590 if (plugin_cfg.toggle_win) grab_key(plugin_cfg.toggle_win, plugin_cfg.toggle_win_mask); 566 grab_key(plugin_cfg.toggle_win);
591 567
592 XSync(xdisplay, False); 568 XSync(xdisplay, False);
593 XSetErrorHandler (old_handler); 569 XSetErrorHandler (old_handler);
594 570
595 grabbed = 1; 571 grabbed = 1;
596 } 572 }
597 /* 573 /*
598 * plugin init end 574 * plugin init end
599 */ 575 */
600 576
601 static void set_keytext (GtkWidget *entry, gint key, gint mask) 577 static void set_keytext (GtkWidget *entry, gint key, gint mask, gint type)
602 { 578 {
603 gchar *text = NULL; 579 gchar *text = NULL;
604 580
605 if (key == 0 && mask == 0) 581 if (key == 0 && mask == 0)
606 { 582 {
665 641
666 if ((event->state & GDK_MOD4_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Super_L || event->keyval == GDK_Super_R)))) 642 if ((event->state & GDK_MOD4_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Super_L || event->keyval == GDK_Super_R))))
667 mod |= Mod4Mask; 643 mod |= Mod4Mask;
668 644
669 if (!is_mod) { 645 if (!is_mod) {
670 controls->key = event->hardware_keycode; 646 controls->hotkey.key = event->hardware_keycode;
671 controls->mask = mod; 647 controls->hotkey.mask = mod;
672 } else controls->key = 0; 648 controls->hotkey.type = TYPE_KEY;
673 649 } else controls->hotkey.key = 0;
674 set_keytext(controls->keytext, is_mod ? 0 : event->hardware_keycode, mod); 650
651 set_keytext(controls->keytext, is_mod ? 0 : event->hardware_keycode, mod, TYPE_KEY);
675 return FALSE; 652 return FALSE;
676 } 653 }
677 654
678 static gboolean 655 static gboolean
679 on_entry_key_release_event(GtkWidget * widget, 656 on_entry_key_release_event(GtkWidget * widget,
680 GdkEventKey * event, 657 GdkEventKey * event,
681 gpointer user_data) 658 gpointer user_data)
682 { 659 {
683 KeyControls *controls = (KeyControls*) user_data; 660 KeyControls *controls = (KeyControls*) user_data;
684 if (controls->key == 0) { 661 if (controls->hotkey.key == 0) {
685 controls->mask = 0; 662 controls->hotkey.mask = 0;
686 } 663 }
687 set_keytext(controls->keytext, controls->key, controls->mask); 664 set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
688 return FALSE; 665 return FALSE;
689 } 666 }
690 667
691 668
692 static void add_event_controls(GtkWidget *table, KeyControls *controls, int row, char* descr, gint key, gint mask) 669 static void add_event_controls(GtkWidget *table,
670 KeyControls *controls,
671 int row,
672 char* descr,
673 HotkeyConfiguration hotkey)
693 { 674 {
694 GtkWidget *label; 675 GtkWidget *label;
695 GtkWidget *button; 676 GtkWidget *button;
696 677
697 controls->key = key; 678 controls->hotkey.key = hotkey.key;
698 controls->mask = mask; 679 controls->hotkey.mask = hotkey.mask;
699 680
700 label = gtk_label_new (_(descr)); 681 label = gtk_label_new (_(descr));
701 gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, 682 gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1,
702 (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); 683 (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
703 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); 684 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
706 controls->keytext = gtk_entry_new (); 687 controls->keytext = gtk_entry_new ();
707 gtk_table_attach (GTK_TABLE (table), controls->keytext, 1, 2, row, row+1, 688 gtk_table_attach (GTK_TABLE (table), controls->keytext, 1, 2, row, row+1,
708 (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (GTK_EXPAND), 0, 0); 689 (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (GTK_EXPAND), 0, 0);
709 gtk_entry_set_editable (GTK_ENTRY (controls->keytext), FALSE); 690 gtk_entry_set_editable (GTK_ENTRY (controls->keytext), FALSE);
710 691
711 set_keytext(controls->keytext, key, mask); 692 set_keytext(controls->keytext, hotkey.key, hotkey.mask, hotkey.type);
712 g_signal_connect((gpointer)controls->keytext, "key_press_event", 693 g_signal_connect((gpointer)controls->keytext, "key_press_event",
713 G_CALLBACK(on_entry_key_press_event), controls); 694 G_CALLBACK(on_entry_key_press_event), controls);
714 g_signal_connect((gpointer)controls->keytext, "key_release_event", 695 g_signal_connect((gpointer)controls->keytext, "key_release_event",
715 G_CALLBACK(on_entry_key_release_event), controls); 696 G_CALLBACK(on_entry_key_release_event), controls);
716 697
790 gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0); 771 gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
791 gtk_table_set_col_spacings (GTK_TABLE (table), 2); 772 gtk_table_set_col_spacings (GTK_TABLE (table), 2);
792 gtk_table_set_row_spacings (GTK_TABLE (table), 2); 773 gtk_table_set_row_spacings (GTK_TABLE (table), 2);
793 774
794 /* prev track */ 775 /* prev track */
795 add_event_controls(table, &controls->prev, 0, _("Previous Track:"), 776 add_event_controls(table, &controls->prev_track, 0, _("Previous Track:"),
796 plugin_cfg.prev_track, plugin_cfg.prev_track_mask); 777 plugin_cfg.prev_track);
797 778
798 add_event_controls(table, &controls->play, 1, _("Play/Pause:"), 779 add_event_controls(table, &controls->play, 1, _("Play/Pause:"),
799 plugin_cfg.play, plugin_cfg.play_mask); 780 plugin_cfg.play);
800 781
801 add_event_controls(table, &controls->pause, 2, _("Pause:"), 782 add_event_controls(table, &controls->pause, 2, _("Pause:"),
802 plugin_cfg.pause, plugin_cfg.pause_mask); 783 plugin_cfg.pause);
803 784
804 add_event_controls(table, &controls->stop, 3, _("Stop:"), 785 add_event_controls(table, &controls->stop, 3, _("Stop:"),
805 plugin_cfg.stop, plugin_cfg.stop_mask); 786 plugin_cfg.stop);
806 787
807 add_event_controls(table, &controls->next, 4, _("Next Track:"), 788 add_event_controls(table, &controls->next_track, 4, _("Next Track:"),
808 plugin_cfg.next_track, plugin_cfg.next_track_mask); 789 plugin_cfg.next_track);
809 790
810 add_event_controls(table, &controls->forward, 5, _("Forward 5 sec.:"), 791 add_event_controls(table, &controls->forward, 5, _("Forward 5 sec.:"),
811 plugin_cfg.forward, plugin_cfg.forward_mask); 792 plugin_cfg.forward);
812 793
813 add_event_controls(table, &controls->backward, 6, _("Rewind 5 sec.:"), 794 add_event_controls(table, &controls->backward, 6, _("Rewind 5 sec.:"),
814 plugin_cfg.backward, plugin_cfg.backward_mask); 795 plugin_cfg.backward);
815 796
816 797
817 label = gtk_label_new (NULL); 798 label = gtk_label_new (NULL);
818 gtk_label_set_markup (GTK_LABEL (label), _("<b>Volume Control:</b>")); 799 gtk_label_set_markup (GTK_LABEL (label), _("<b>Volume Control:</b>"));
819 frame = gtk_frame_new (NULL); 800 frame = gtk_frame_new (NULL);
833 _("<i>Configure keys which controls music volume.</i>")); 814 _("<i>Configure keys which controls music volume.</i>"));
834 table = gtk_table_new (3, 3, FALSE); 815 table = gtk_table_new (3, 3, FALSE);
835 gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0); 816 gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
836 gtk_table_set_col_spacings (GTK_TABLE (table), 2); 817 gtk_table_set_col_spacings (GTK_TABLE (table), 2);
837 gtk_table_set_row_spacings (GTK_TABLE (table), 2); 818 gtk_table_set_row_spacings (GTK_TABLE (table), 2);
838
839
840 819
841 add_event_controls(table, &controls->mute, 0, _("Mute:"), 820 add_event_controls(table, &controls->mute, 0, _("Mute:"),
842 plugin_cfg.mute, plugin_cfg.mute_mask); 821 plugin_cfg.mute);
843 822
844 add_event_controls(table, &controls->up, 1, _("Volume Up:"), 823 add_event_controls(table, &controls->vol_up, 1, _("Volume Up:"),
845 plugin_cfg.vol_up, plugin_cfg.vol_up_mask); 824 plugin_cfg.vol_up);
846 825
847 add_event_controls(table, &controls->down, 2, _("Volume Down:"), 826 add_event_controls(table, &controls->vol_down, 2, _("Volume Down:"),
848 plugin_cfg.vol_down, plugin_cfg.vol_down_mask); 827 plugin_cfg.vol_down);
849 828
850 829
851 label = gtk_label_new (NULL); 830 label = gtk_label_new (NULL);
852 gtk_label_set_markup (GTK_LABEL (label), _("<b>Player:</b>")); 831 gtk_label_set_markup (GTK_LABEL (label), _("<b>Player:</b>"));
853 frame = gtk_frame_new (NULL); 832 frame = gtk_frame_new (NULL);
869 gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0); 848 gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
870 gtk_table_set_col_spacings (GTK_TABLE (table), 2); 849 gtk_table_set_col_spacings (GTK_TABLE (table), 2);
871 gtk_table_set_row_spacings (GTK_TABLE (table), 2); 850 gtk_table_set_row_spacings (GTK_TABLE (table), 2);
872 851
873 add_event_controls(table, &controls->jump_to_file, 0, _("Jump to File:"), 852 add_event_controls(table, &controls->jump_to_file, 0, _("Jump to File:"),
874 plugin_cfg.jump_to_file, plugin_cfg.jump_to_file_mask); 853 plugin_cfg.jump_to_file);
875 854
876 add_event_controls(table, &controls->toggle_win, 1, _("Toggle Player Windows:"), 855 add_event_controls(table, &controls->toggle_win, 1, _("Toggle Player Windows:"),
877 plugin_cfg.toggle_win, plugin_cfg.toggle_win_mask); 856 plugin_cfg.toggle_win);
878 857
879 858
880 button_box = gtk_hbutton_box_new ( ); 859 button_box = gtk_hbutton_box_new ( );
881 gtk_box_pack_start (GTK_BOX (main_vbox), button_box, FALSE, TRUE, 6); 860 gtk_box_pack_start (GTK_BOX (main_vbox), button_box, FALSE, TRUE, 6);
882 gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), GTK_BUTTONBOX_END); 861 gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), GTK_BUTTONBOX_END);
901 static GtkWidget *dialog; 880 static GtkWidget *dialog;
902 881
903 dialog = audacious_info_dialog (_("About Global Hotkey Plugin"), 882 dialog = audacious_info_dialog (_("About Global Hotkey Plugin"),
904 _("Global Hotkey Plugin\n" 883 _("Global Hotkey Plugin\n"
905 "Control the player with global key combinations or multimedia keys.\n\n" 884 "Control the player with global key combinations or multimedia keys.\n\n"
906 "Copyright (C) 2007 Sascha Hlusiak <contact@saschahlusiak.de>\n\n" 885 "Copyright (C) 2007-2008 Sascha Hlusiak <contact@saschahlusiak.de>\n\n"
907 "Contributers include:\n" 886 "Contributers include:\n"
908 "Copyright (C) 2006 - 2007 Vladimir Paskov <vlado.paskov@gmail.com>\n" 887 "Copyright (C) 2006-2007 Vladimir Paskov <vlado.paskov@gmail.com>\n"
909 "Copyright (C) 2000-2002 Ville Syrjälä <syrjala@sci.fi>\n" 888 "Copyright (C) 2000-2002 Ville Syrjälä <syrjala@sci.fi>\n"
910 " Bryn Davies <curious@ihug.com.au>\n" 889 " Bryn Davies <curious@ihug.com.au>\n"
911 " Jonathan A. Davis <davis@jdhouse.org>\n" 890 " Jonathan A. Davis <davis@jdhouse.org>\n"
912 " Jeremy Tan <nsx@nsx.homeip.net>\n\n" 891 " Jeremy Tan <nsx@nsx.homeip.net>\n\n"
913 ), 892 ),
919 898
920 /* Clear keys */ 899 /* Clear keys */
921 static void clear_keyboard (GtkWidget *widget, gpointer data) 900 static void clear_keyboard (GtkWidget *widget, gpointer data)
922 { 901 {
923 KeyControls *spins = (KeyControls*)data; 902 KeyControls *spins = (KeyControls*)data;
924 spins->key = 0; 903 spins->hotkey.key = 0;
925 spins->mask = 0; 904 spins->hotkey.mask = 0;
926 set_keytext(spins->keytext, 0, 0); 905 spins->hotkey.type = TYPE_KEY;
906 set_keytext(spins->keytext, 0, 0, TYPE_KEY);
927 } 907 }
928 908
929 void cancel_callback (GtkWidget *widget, gpointer data) 909 void cancel_callback (GtkWidget *widget, gpointer data)
930 { 910 {
931 if (loaded) 911 if (loaded)
939 919
940 void ok_callback (GtkWidget *widget, gpointer data) 920 void ok_callback (GtkWidget *widget, gpointer data)
941 { 921 {
942 ConfigurationControls *controls= (ConfigurationControls*)data; 922 ConfigurationControls *controls= (ConfigurationControls*)data;
943 923
944 plugin_cfg.play = controls->play.key; 924 plugin_cfg.play = controls->play.hotkey;
945 plugin_cfg.play_mask = controls->play.mask; 925 plugin_cfg.pause = controls->pause.hotkey;
946 926 plugin_cfg.stop= controls->stop.hotkey;
947 plugin_cfg.pause = controls->pause.key; 927 plugin_cfg.prev_track= controls->prev_track.hotkey;
948 plugin_cfg.pause_mask = controls->pause.mask; 928 plugin_cfg.next_track = controls->next_track.hotkey;
949 929 plugin_cfg.forward = controls->forward.hotkey;
950 plugin_cfg.stop = controls->stop.key; 930 plugin_cfg.backward = controls->backward.hotkey;
951 plugin_cfg.stop_mask = controls->stop.mask; 931 plugin_cfg.vol_up= controls->vol_up.hotkey;
952 932 plugin_cfg.vol_down = controls->vol_down.hotkey;
953 plugin_cfg.prev_track = controls->prev.key; 933 plugin_cfg.mute = controls->mute.hotkey;
954 plugin_cfg.prev_track_mask = controls->prev.mask; 934 plugin_cfg.jump_to_file= controls->jump_to_file.hotkey;
955 935 plugin_cfg.toggle_win = controls->toggle_win.hotkey;
956 plugin_cfg.next_track = controls->next.key; 936
957 plugin_cfg.next_track_mask = controls->next.mask;
958
959 plugin_cfg.forward = controls->forward.key;
960 plugin_cfg.forward_mask = controls->forward.mask;
961
962 plugin_cfg.backward = controls->backward.key;
963 plugin_cfg.backward_mask = controls->backward.mask;
964
965 plugin_cfg.vol_up = controls->up.key;
966 plugin_cfg.vol_up_mask = controls->up.mask;
967
968 plugin_cfg.vol_down = controls->down.key;
969 plugin_cfg.vol_down_mask = controls->down.mask;
970
971 plugin_cfg.mute = controls->mute.key;
972 plugin_cfg.mute_mask = controls->mute.mask;
973
974 plugin_cfg.jump_to_file = controls->jump_to_file.key;
975 plugin_cfg.jump_to_file_mask = controls->jump_to_file.mask;
976
977 plugin_cfg.toggle_win= controls->toggle_win.key;
978 plugin_cfg.toggle_win_mask = controls->toggle_win.mask;
979
980 save_config ( ); 937 save_config ( );
981 938
982 if (loaded) 939 if (loaded)
983 { 940 {
984 grab_keys (); 941 grab_keys ();