Mercurial > audlegacy-plugins
comparison src/hotkey/plugin.c @ 2274:d9706e29e968
Hotkey: Added grabbing of mouse buttons with modificators so you can control it with the mouse from any application
| author | Sascha Hlusiak <contact@saschahlusiak.de> |
|---|---|
| date | Mon, 31 Dec 2007 19:45:28 +0100 |
| parents | f893d05f707b |
| children | 6ca0d83ce51d |
comparison
equal
deleted
inserted
replaced
| 2273:f893d05f707b | 2274:d9706e29e968 |
|---|---|
| 59 void x_display_init (void); | 59 void x_display_init (void); |
| 60 static void get_offending_modifiers (Display * dpy); | 60 static void get_offending_modifiers (Display * dpy); |
| 61 static void init (void); | 61 static void init (void); |
| 62 static void grab_keys (); | 62 static void grab_keys (); |
| 63 static void ungrab_keys (); | 63 static void ungrab_keys (); |
| 64 static gboolean handle_keyevent(int keycode, int state); | 64 static gboolean handle_keyevent(int keycode, int state, int type); |
| 65 static gboolean setup_filter(); | 65 static gboolean setup_filter(); |
| 66 static void release_filter(); | 66 static void release_filter(); |
| 67 | 67 |
| 68 static void load_config (void); | 68 static void load_config (void); |
| 69 static void save_config (void); | 69 static void save_config (void); |
| 207 if (modmap) | 207 if (modmap) |
| 208 XFreeModifiermap (modmap); | 208 XFreeModifiermap (modmap); |
| 209 } | 209 } |
| 210 | 210 |
| 211 /* handle keys */ | 211 /* handle keys */ |
| 212 static gboolean handle_keyevent (int keycode, int state) | 212 static gboolean handle_keyevent (int keycode, int state, int type) |
| 213 { | 213 { |
| 214 gint current_volume, old_volume; | 214 gint current_volume, old_volume; |
| 215 static gint volume_static = 0; | 215 static gint volume_static = 0; |
| 216 gboolean play, mute; | 216 gboolean play, mute; |
| 217 | 217 |
| 231 } | 231 } |
| 232 | 232 |
| 233 state &= ~(scrolllock_mask | numlock_mask | capslock_mask); | 233 state &= ~(scrolllock_mask | numlock_mask | capslock_mask); |
| 234 | 234 |
| 235 /* mute the playback */ | 235 /* mute the playback */ |
| 236 if ((keycode == plugin_cfg.mute.key) && (state == plugin_cfg.mute.mask)) | 236 if ((keycode == plugin_cfg.mute.key) && (state == plugin_cfg.mute.mask) && (type == plugin_cfg.mute.type)) |
| 237 { | 237 { |
| 238 if (!mute) | 238 if (!mute) |
| 239 { | 239 { |
| 240 volume_static = current_volume; | 240 volume_static = current_volume; |
| 241 audacious_drct_set_main_volume (0); | 241 audacious_drct_set_main_volume (0); |
| 246 } | 246 } |
| 247 return TRUE; | 247 return TRUE; |
| 248 } | 248 } |
| 249 | 249 |
| 250 /* decreace volume */ | 250 /* decreace volume */ |
| 251 if ((keycode == plugin_cfg.vol_down.key) && (state == plugin_cfg.vol_down.mask)) | 251 if ((keycode == plugin_cfg.vol_down.key) && (state == plugin_cfg.vol_down.mask) && (type == plugin_cfg.vol_down.type)) |
| 252 { | 252 { |
| 253 if (mute) | 253 if (mute) |
| 254 { | 254 { |
| 255 current_volume = old_volume; | 255 current_volume = old_volume; |
| 256 old_volume = 0; | 256 old_volume = 0; |
| 270 old_volume = current_volume; | 270 old_volume = current_volume; |
| 271 return TRUE; | 271 return TRUE; |
| 272 } | 272 } |
| 273 | 273 |
| 274 /* increase volume */ | 274 /* increase volume */ |
| 275 if ((keycode == plugin_cfg.vol_up.key) && (state == plugin_cfg.vol_up.mask)) | 275 if ((keycode == plugin_cfg.vol_up.key) && (state == plugin_cfg.vol_up.mask) && (type == plugin_cfg.vol_up.type)) |
| 276 { | 276 { |
| 277 if (mute) | 277 if (mute) |
| 278 { | 278 { |
| 279 current_volume = old_volume; | 279 current_volume = old_volume; |
| 280 old_volume = 0; | 280 old_volume = 0; |
| 294 old_volume = current_volume; | 294 old_volume = current_volume; |
| 295 return TRUE; | 295 return TRUE; |
| 296 } | 296 } |
| 297 | 297 |
| 298 /* play */ | 298 /* play */ |
| 299 if ((keycode == plugin_cfg.play.key) && (state == plugin_cfg.play.mask)) | 299 if ((keycode == plugin_cfg.play.key) && (state == plugin_cfg.play.mask) && (type == plugin_cfg.play.type)) |
| 300 { | 300 { |
| 301 if (!play) | 301 if (!play) |
| 302 { | 302 { |
| 303 audacious_drct_play (); | 303 audacious_drct_play (); |
| 304 } else { | 304 } else { |
| 306 } | 306 } |
| 307 return TRUE; | 307 return TRUE; |
| 308 } | 308 } |
| 309 | 309 |
| 310 /* pause */ | 310 /* pause */ |
| 311 if ((keycode == plugin_cfg.pause.key) && (state == plugin_cfg.pause.mask)) | 311 if ((keycode == plugin_cfg.pause.key) && (state == plugin_cfg.pause.mask) && (type == plugin_cfg.pause.type)) |
| 312 { | 312 { |
| 313 if (!play) audacious_drct_play (); | 313 if (!play) audacious_drct_play (); |
| 314 else audacious_drct_pause (); | 314 else audacious_drct_pause (); |
| 315 | 315 |
| 316 return TRUE; | 316 return TRUE; |
| 317 } | 317 } |
| 318 | 318 |
| 319 /* stop */ | 319 /* stop */ |
| 320 if ((keycode == plugin_cfg.stop.key) && (state == plugin_cfg.stop.mask)) | 320 if ((keycode == plugin_cfg.stop.key) && (state == plugin_cfg.stop.mask) && (type == plugin_cfg.stop.type)) |
| 321 { | 321 { |
| 322 audacious_drct_stop (); | 322 audacious_drct_stop (); |
| 323 return TRUE; | 323 return TRUE; |
| 324 } | 324 } |
| 325 | 325 |
| 326 /* prev track */ | 326 /* prev track */ |
| 327 if ((keycode == plugin_cfg.prev_track.key) && (state == plugin_cfg.prev_track.mask)) | 327 if ((keycode == plugin_cfg.prev_track.key) && (state == plugin_cfg.prev_track.mask) && (type == plugin_cfg.prev_track.type)) |
| 328 { | 328 { |
| 329 audacious_drct_playlist_prev (); | 329 audacious_drct_playlist_prev (); |
| 330 return TRUE; | 330 return TRUE; |
| 331 } | 331 } |
| 332 | 332 |
| 333 /* next track */ | 333 /* next track */ |
| 334 if ((keycode == plugin_cfg.next_track.key) && (state == plugin_cfg.next_track.mask)) | 334 if ((keycode == plugin_cfg.next_track.key) && (state == plugin_cfg.next_track.mask) && (type == plugin_cfg.next_track.type)) |
| 335 { | 335 { |
| 336 audacious_drct_playlist_next (); | 336 audacious_drct_playlist_next (); |
| 337 return TRUE; | 337 return TRUE; |
| 338 } | 338 } |
| 339 | 339 |
| 340 /* forward */ | 340 /* forward */ |
| 341 if ((keycode == plugin_cfg.forward.key) && (state == plugin_cfg.forward.mask)) | 341 if ((keycode == plugin_cfg.forward.key) && (state == plugin_cfg.forward.mask) && (type == plugin_cfg.forward.type)) |
| 342 { | 342 { |
| 343 gint time = audacious_drct_get_output_time(); | 343 gint time = audacious_drct_get_output_time(); |
| 344 time += 5000; /* Jump 5s into future */ | 344 time += 5000; /* Jump 5s into future */ |
| 345 audacious_drct_jump_to_time(time); | 345 audacious_drct_jump_to_time(time); |
| 346 return TRUE; | 346 return TRUE; |
| 347 } | 347 } |
| 348 | 348 |
| 349 /* backward */ | 349 /* backward */ |
| 350 if ((keycode == plugin_cfg.backward.key) && (state == plugin_cfg.backward.mask)) | 350 if ((keycode == plugin_cfg.backward.key) && (state == plugin_cfg.backward.mask) && (type == plugin_cfg.backward.type)) |
| 351 { | 351 { |
| 352 gint time = audacious_drct_get_output_time(); | 352 gint time = audacious_drct_get_output_time(); |
| 353 if (time > 5000) time -= 5000; /* Jump 5s back */ | 353 if (time > 5000) time -= 5000; /* Jump 5s back */ |
| 354 else time = 0; | 354 else time = 0; |
| 355 audacious_drct_jump_to_time(time); | 355 audacious_drct_jump_to_time(time); |
| 356 return TRUE; | 356 return TRUE; |
| 357 } | 357 } |
| 358 | 358 |
| 359 /* Open Jump-To-File dialog */ | 359 /* Open Jump-To-File dialog */ |
| 360 if ((keycode == plugin_cfg.jump_to_file.key) && (state == plugin_cfg.jump_to_file.mask)) | 360 if ((keycode == plugin_cfg.jump_to_file.key) && (state == plugin_cfg.jump_to_file.mask) && (type == plugin_cfg.jump_to_file.type)) |
| 361 { | 361 { |
| 362 audacious_drct_show_jtf_box(); | 362 audacious_drct_show_jtf_box(); |
| 363 return TRUE; | 363 return TRUE; |
| 364 } | 364 } |
| 365 | 365 |
| 366 /* Toggle Windows */ | 366 /* Toggle Windows */ |
| 367 if ((keycode == plugin_cfg.toggle_win.key) && (state == plugin_cfg.toggle_win.mask)) | 367 if ((keycode == plugin_cfg.toggle_win.key) && (state == plugin_cfg.toggle_win.mask) && (type == plugin_cfg.toggle_win.type)) |
| 368 { | 368 { |
| 369 static gboolean is_main, is_eq, is_pl; | 369 static gboolean is_main, is_eq, is_pl; |
| 370 is_main = audacious_drct_main_win_is_visible(); | 370 is_main = audacious_drct_main_win_is_visible(); |
| 371 if (is_main) { | 371 if (is_main) { |
| 372 is_pl = audacious_drct_pl_win_is_visible(); | 372 is_pl = audacious_drct_pl_win_is_visible(); |
| 388 static GdkFilterReturn | 388 static GdkFilterReturn |
| 389 gdk_filter(GdkXEvent *xevent, | 389 gdk_filter(GdkXEvent *xevent, |
| 390 GdkEvent *event, | 390 GdkEvent *event, |
| 391 gpointer data) | 391 gpointer data) |
| 392 { | 392 { |
| 393 XKeyEvent *keyevent = (XKeyEvent*)xevent; | 393 switch (((XEvent*)xevent)->type) |
| 394 | 394 { |
| 395 if (((XEvent*)keyevent)->type != KeyPress) | 395 case KeyPress: |
| 396 { | |
| 397 XKeyEvent *keyevent = (XKeyEvent*)xevent; | |
| 398 if (handle_keyevent(keyevent->keycode, keyevent->state, TYPE_KEY)) | |
| 399 return GDK_FILTER_REMOVE; | |
| 400 break; | |
| 401 } | |
| 402 case ButtonPress: | |
| 403 { | |
| 404 XButtonEvent *buttonevent = (XButtonEvent*)xevent; | |
| 405 if (handle_keyevent(buttonevent->button, buttonevent->state, TYPE_MOUSE)) | |
| 406 return GDK_FILTER_REMOVE; | |
| 407 break; | |
| 408 } | |
| 409 default: | |
| 396 return -1; | 410 return -1; |
| 397 | 411 } |
| 398 if (handle_keyevent(keyevent->keycode, keyevent->state)) | |
| 399 return GDK_FILTER_REMOVE; | |
| 400 | 412 |
| 401 return GDK_FILTER_CONTINUE; | 413 return GDK_FILTER_CONTINUE; |
| 402 } | 414 } |
| 403 | 415 |
| 404 static gboolean | 416 static gboolean |
| 489 static int x11_error_handler (Display *dpy, XErrorEvent *error) | 501 static int x11_error_handler (Display *dpy, XErrorEvent *error) |
| 490 { | 502 { |
| 491 return 0; | 503 return 0; |
| 492 } | 504 } |
| 493 | 505 |
| 494 /* grab requied keys */ | 506 /* grab required keys */ |
| 495 static void grab_key(HotkeyConfiguration hotkey) | 507 static void grab_key(HotkeyConfiguration hotkey) |
| 496 { | 508 { |
| 497 unsigned int modifier = hotkey.mask & ~(numlock_mask | capslock_mask | scrolllock_mask); | 509 unsigned int modifier = hotkey.mask & ~(numlock_mask | capslock_mask | scrolllock_mask); |
| 498 | 510 |
| 499 if (hotkey.key == 0) return; | 511 if (hotkey.key == 0) return; |
| 500 | 512 |
| 501 XGrabKey (xdisplay, hotkey.key, modifier, x_root_window, | 513 if (hotkey.type == TYPE_KEY) |
| 502 False, GrabModeAsync, GrabModeAsync); | 514 { |
| 503 | 515 XGrabKey (xdisplay, hotkey.key, modifier, x_root_window, |
| 504 if (modifier == AnyModifier) | |
| 505 return; | |
| 506 | |
| 507 if (numlock_mask) | |
| 508 XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask, | |
| 509 x_root_window, | |
| 510 False, GrabModeAsync, GrabModeAsync); | 516 False, GrabModeAsync, GrabModeAsync); |
| 511 | 517 |
| 512 if (capslock_mask) | 518 if (modifier == AnyModifier) |
| 513 XGrabKey (xdisplay, hotkey.key, modifier | capslock_mask, | 519 return; |
| 514 x_root_window, | 520 |
| 515 False, GrabModeAsync, GrabModeAsync); | 521 if (numlock_mask) |
| 516 | 522 XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask, |
| 517 if (scrolllock_mask) | 523 x_root_window, |
| 518 XGrabKey (xdisplay, hotkey.key, modifier | scrolllock_mask, | 524 False, GrabModeAsync, GrabModeAsync); |
| 519 x_root_window, | 525 |
| 520 False, GrabModeAsync, GrabModeAsync); | 526 if (capslock_mask) |
| 521 | 527 XGrabKey (xdisplay, hotkey.key, modifier | capslock_mask, |
| 522 if (numlock_mask && capslock_mask) | 528 x_root_window, |
| 523 XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask, | 529 False, GrabModeAsync, GrabModeAsync); |
| 524 x_root_window, | 530 |
| 525 False, GrabModeAsync, GrabModeAsync); | 531 if (scrolllock_mask) |
| 526 | 532 XGrabKey (xdisplay, hotkey.key, modifier | scrolllock_mask, |
| 527 if (numlock_mask && scrolllock_mask) | 533 x_root_window, |
| 528 XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask | scrolllock_mask, | 534 False, GrabModeAsync, GrabModeAsync); |
| 529 x_root_window, | 535 |
| 530 False, GrabModeAsync, GrabModeAsync); | 536 if (numlock_mask && capslock_mask) |
| 531 | 537 XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask, |
| 532 if (capslock_mask && scrolllock_mask) | 538 x_root_window, |
| 533 XGrabKey (xdisplay, hotkey.key, modifier | capslock_mask | scrolllock_mask, | 539 False, GrabModeAsync, GrabModeAsync); |
| 534 x_root_window, | 540 |
| 535 False, GrabModeAsync, GrabModeAsync); | 541 if (numlock_mask && scrolllock_mask) |
| 536 | 542 XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask | scrolllock_mask, |
| 537 if (numlock_mask && capslock_mask && scrolllock_mask) | 543 x_root_window, |
| 538 XGrabKey (xdisplay, hotkey.key, | 544 False, GrabModeAsync, GrabModeAsync); |
| 539 modifier | numlock_mask | capslock_mask | scrolllock_mask, | 545 |
| 540 x_root_window, False, GrabModeAsync, | 546 if (capslock_mask && scrolllock_mask) |
| 541 GrabModeAsync); | 547 XGrabKey (xdisplay, hotkey.key, modifier | capslock_mask | scrolllock_mask, |
| 542 } | 548 x_root_window, |
| 543 | 549 False, GrabModeAsync, GrabModeAsync); |
| 550 | |
| 551 if (numlock_mask && capslock_mask && scrolllock_mask) | |
| 552 XGrabKey (xdisplay, hotkey.key, | |
| 553 modifier | numlock_mask | capslock_mask | scrolllock_mask, | |
| 554 x_root_window, False, GrabModeAsync, | |
| 555 GrabModeAsync); | |
| 556 } | |
| 557 if (hotkey.type == TYPE_MOUSE) | |
| 558 { | |
| 559 XGrabButton (xdisplay, hotkey.key, modifier, x_root_window, | |
| 560 False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); | |
| 561 | |
| 562 if (modifier == AnyModifier) | |
| 563 return; | |
| 564 | |
| 565 if (numlock_mask) | |
| 566 XGrabButton (xdisplay, hotkey.key, modifier | numlock_mask, | |
| 567 x_root_window, | |
| 568 False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); | |
| 569 | |
| 570 if (capslock_mask) | |
| 571 XGrabButton (xdisplay, hotkey.key, modifier | capslock_mask, | |
| 572 x_root_window, | |
| 573 False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); | |
| 574 | |
| 575 if (scrolllock_mask) | |
| 576 XGrabButton (xdisplay, hotkey.key, modifier | scrolllock_mask, | |
| 577 x_root_window, | |
| 578 False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); | |
| 579 | |
| 580 if (numlock_mask && capslock_mask) | |
| 581 XGrabButton (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask, | |
| 582 x_root_window, | |
| 583 False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); | |
| 584 | |
| 585 if (numlock_mask && scrolllock_mask) | |
| 586 XGrabButton (xdisplay, hotkey.key, modifier | numlock_mask | scrolllock_mask, | |
| 587 x_root_window, | |
| 588 False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); | |
| 589 | |
| 590 if (capslock_mask && scrolllock_mask) | |
| 591 XGrabButton (xdisplay, hotkey.key, modifier | capslock_mask | scrolllock_mask, | |
| 592 x_root_window, | |
| 593 False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); | |
| 594 | |
| 595 if (numlock_mask && capslock_mask && scrolllock_mask) | |
| 596 XGrabButton (xdisplay, hotkey.key, | |
| 597 modifier | numlock_mask | capslock_mask | scrolllock_mask, | |
| 598 x_root_window, False, ButtonPressMask, GrabModeAsync, | |
| 599 GrabModeAsync, None, None); | |
| 600 } | |
| 601 } | |
| 544 | 602 |
| 545 static void grab_keys () | 603 static void grab_keys () |
| 546 { | 604 { |
| 547 if (grabbed) return; | 605 if (grabbed) return; |
| 548 if (xdisplay == NULL) x_display_init(); | 606 if (xdisplay == NULL) x_display_init(); |
| 585 static char *modifier_string[] = { "Control", "Shift", "Alt", "Mod2", "Mod3", "Super", "Mod5" }; | 643 static char *modifier_string[] = { "Control", "Shift", "Alt", "Mod2", "Mod3", "Super", "Mod5" }; |
| 586 static unsigned int modifiers[] = { ControlMask, ShiftMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; | 644 static unsigned int modifiers[] = { ControlMask, ShiftMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; |
| 587 gchar *strings[9]; | 645 gchar *strings[9]; |
| 588 gchar *keytext = NULL; | 646 gchar *keytext = NULL; |
| 589 int i, j; | 647 int i, j; |
| 590 KeySym keysym; | 648 if (type == TYPE_KEY) |
| 591 | 649 { |
| 592 keysym = XKeycodeToKeysym(xdisplay, key, 0); | 650 KeySym keysym; |
| 593 if (keysym == 0 || keysym == NoSymbol) | 651 keysym = XKeycodeToKeysym(xdisplay, key, 0); |
| 594 { | 652 if (keysym == 0 || keysym == NoSymbol) |
| 595 keytext = g_strdup_printf("#%3d", key); | 653 { |
| 596 } else { | 654 keytext = g_strdup_printf("#%d", key); |
| 597 keytext = g_strdup(XKeysymToString(keysym)); | 655 } else { |
| 656 keytext = g_strdup(XKeysymToString(keysym)); | |
| 657 } | |
| 658 } | |
| 659 if (type == TYPE_MOUSE) | |
| 660 { | |
| 661 keytext = g_strdup_printf("Button%d", key); | |
| 598 } | 662 } |
| 599 | 663 |
| 600 for (i = 0, j=0; j<7; j++) | 664 for (i = 0, j=0; j<7; j++) |
| 601 { | 665 { |
| 602 if (mask & modifiers[j]) | 666 if (mask & modifiers[j]) |
| 622 KeyControls *controls = (KeyControls*) user_data; | 686 KeyControls *controls = (KeyControls*) user_data; |
| 623 int is_mod; | 687 int is_mod; |
| 624 int mod; | 688 int mod; |
| 625 | 689 |
| 626 if (event->keyval == GDK_Tab) return FALSE; | 690 if (event->keyval == GDK_Tab) return FALSE; |
| 691 | |
| 627 mod = 0; | 692 mod = 0; |
| 628 is_mod = 0; | 693 is_mod = 0; |
| 629 | 694 |
| 630 if ((event->state & GDK_CONTROL_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R)))) | 695 if ((event->state & GDK_CONTROL_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R)))) |
| 631 mod |= ControlMask; | 696 mod |= ControlMask; |
| 647 controls->hotkey.mask = mod; | 712 controls->hotkey.mask = mod; |
| 648 controls->hotkey.type = TYPE_KEY; | 713 controls->hotkey.type = TYPE_KEY; |
| 649 } else controls->hotkey.key = 0; | 714 } else controls->hotkey.key = 0; |
| 650 | 715 |
| 651 set_keytext(controls->keytext, is_mod ? 0 : event->hardware_keycode, mod, TYPE_KEY); | 716 set_keytext(controls->keytext, is_mod ? 0 : event->hardware_keycode, mod, TYPE_KEY); |
| 652 return FALSE; | 717 return TRUE; |
| 653 } | 718 } |
| 654 | 719 |
| 655 static gboolean | 720 static gboolean |
| 656 on_entry_key_release_event(GtkWidget * widget, | 721 on_entry_key_release_event(GtkWidget * widget, |
| 657 GdkEventKey * event, | 722 GdkEventKey * event, |
| 658 gpointer user_data) | 723 gpointer user_data) |
| 659 { | 724 { |
| 660 KeyControls *controls = (KeyControls*) user_data; | 725 KeyControls *controls = (KeyControls*) user_data; |
| 661 if (controls->hotkey.key == 0) { | 726 if (controls->hotkey.key == 0) { |
| 662 controls->hotkey.mask = 0; | 727 controls->hotkey.mask = 0; |
| 728 return TRUE; | |
| 663 } | 729 } |
| 664 set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); | 730 set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); |
| 665 return FALSE; | 731 return TRUE; |
| 666 } | 732 } |
| 667 | 733 |
| 734 static gboolean | |
| 735 on_entry_button_press_event(GtkWidget * widget, | |
| 736 GdkEventButton * event, | |
| 737 gpointer user_data) | |
| 738 { | |
| 739 KeyControls *controls = (KeyControls*) user_data; | |
| 740 int mod; | |
| 741 | |
| 742 if (!gtk_widget_is_focus(widget)) return FALSE; | |
| 743 | |
| 744 mod = 0; | |
| 745 if (event->state & GDK_CONTROL_MASK) | |
| 746 mod |= ControlMask; | |
| 747 | |
| 748 if (event->state & GDK_MOD1_MASK) | |
| 749 mod |= Mod1Mask; | |
| 750 | |
| 751 if (event->state & GDK_SHIFT_MASK) | |
| 752 mod |= ShiftMask; | |
| 753 | |
| 754 if (event->state & GDK_MOD5_MASK) | |
| 755 mod |= Mod5Mask; | |
| 756 | |
| 757 if (event->state & GDK_MOD4_MASK) | |
| 758 mod |= Mod4Mask; | |
| 759 | |
| 760 if ((event->button <= 3) && (mod == 0)) | |
| 761 { | |
| 762 GtkWidget* dialog; | |
| 763 GtkResponseType response; | |
| 764 dialog = gtk_message_dialog_new (GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
| 765 GTK_DIALOG_MODAL, | |
| 766 GTK_MESSAGE_WARNING, | |
| 767 GTK_BUTTONS_YES_NO, | |
| 768 _("It is not recommended to bind the primary mouse buttons without modificators.\n\n" | |
| 769 "Do you want to continue?")); | |
| 770 gtk_window_set_title(GTK_WINDOW(dialog), _("Binding mouse buttons")); | |
| 771 response = gtk_dialog_run(GTK_DIALOG(dialog)); | |
| 772 gtk_widget_destroy (dialog); | |
| 773 if (response != GTK_RESPONSE_YES) return TRUE; | |
| 774 } | |
| 775 | |
| 776 controls->hotkey.key = event->button; | |
| 777 controls->hotkey.mask = mod; | |
| 778 controls->hotkey.type = TYPE_MOUSE; | |
| 779 set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); | |
| 780 return TRUE; | |
| 781 } | |
| 782 | |
| 783 static gboolean | |
| 784 on_entry_scroll_event(GtkWidget * widget, | |
| 785 GdkEventScroll * event, | |
| 786 gpointer user_data) | |
| 787 { | |
| 788 KeyControls *controls = (KeyControls*) user_data; | |
| 789 int mod; | |
| 790 | |
| 791 if (!gtk_widget_is_focus(widget)) return FALSE; | |
| 792 | |
| 793 mod = 0; | |
| 794 if (event->state & GDK_CONTROL_MASK) | |
| 795 mod |= ControlMask; | |
| 796 | |
| 797 if (event->state & GDK_MOD1_MASK) | |
| 798 mod |= Mod1Mask; | |
| 799 | |
| 800 if (event->state & GDK_SHIFT_MASK) | |
| 801 mod |= ShiftMask; | |
| 802 | |
| 803 if (event->state & GDK_MOD5_MASK) | |
| 804 mod |= Mod5Mask; | |
| 805 | |
| 806 if (event->state & GDK_MOD4_MASK) | |
| 807 mod |= Mod4Mask; | |
| 808 | |
| 809 if (event->direction == GDK_SCROLL_UP) | |
| 810 controls->hotkey.key = 4; | |
| 811 else if (event->direction == GDK_SCROLL_DOWN) | |
| 812 controls->hotkey.key = 5; | |
| 813 else if (event->direction == GDK_SCROLL_LEFT) | |
| 814 controls->hotkey.key = 6; | |
| 815 else if (event->direction == GDK_SCROLL_RIGHT) | |
| 816 controls->hotkey.key = 7; | |
| 817 else return FALSE; | |
| 818 | |
| 819 controls->hotkey.mask = mod; | |
| 820 controls->hotkey.type = TYPE_MOUSE; | |
| 821 set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); | |
| 822 return TRUE; | |
| 823 } | |
| 668 | 824 |
| 669 static void add_event_controls(GtkWidget *table, | 825 static void add_event_controls(GtkWidget *table, |
| 670 KeyControls *controls, | 826 KeyControls *controls, |
| 671 int row, | 827 int row, |
| 672 char* descr, | 828 char* descr, |
| 675 GtkWidget *label; | 831 GtkWidget *label; |
| 676 GtkWidget *button; | 832 GtkWidget *button; |
| 677 | 833 |
| 678 controls->hotkey.key = hotkey.key; | 834 controls->hotkey.key = hotkey.key; |
| 679 controls->hotkey.mask = hotkey.mask; | 835 controls->hotkey.mask = hotkey.mask; |
| 836 controls->hotkey.type = hotkey.type; | |
| 837 if (controls->hotkey.key == 0) | |
| 838 controls->hotkey.mask = 0; | |
| 680 | 839 |
| 681 label = gtk_label_new (_(descr)); | 840 label = gtk_label_new (_(descr)); |
| 682 gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, | 841 gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, |
| 683 (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); | 842 (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); |
| 684 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); | 843 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); |
| 692 set_keytext(controls->keytext, hotkey.key, hotkey.mask, hotkey.type); | 851 set_keytext(controls->keytext, hotkey.key, hotkey.mask, hotkey.type); |
| 693 g_signal_connect((gpointer)controls->keytext, "key_press_event", | 852 g_signal_connect((gpointer)controls->keytext, "key_press_event", |
| 694 G_CALLBACK(on_entry_key_press_event), controls); | 853 G_CALLBACK(on_entry_key_press_event), controls); |
| 695 g_signal_connect((gpointer)controls->keytext, "key_release_event", | 854 g_signal_connect((gpointer)controls->keytext, "key_release_event", |
| 696 G_CALLBACK(on_entry_key_release_event), controls); | 855 G_CALLBACK(on_entry_key_release_event), controls); |
| 856 g_signal_connect((gpointer)controls->keytext, "button_press_event", | |
| 857 G_CALLBACK(on_entry_button_press_event), controls); | |
| 858 g_signal_connect((gpointer)controls->keytext, "scroll_event", | |
| 859 G_CALLBACK(on_entry_scroll_event), controls); | |
| 697 | 860 |
| 698 button = gtk_button_new_with_label (_("None")); | 861 button = gtk_button_new_with_label (_("None")); |
| 699 gtk_table_attach (GTK_TABLE (table), button, 2, 3, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); | 862 gtk_table_attach (GTK_TABLE (table), button, 2, 3, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); |
| 700 g_signal_connect (G_OBJECT (button), "clicked", | 863 g_signal_connect (G_OBJECT (button), "clicked", |
| 701 G_CALLBACK (clear_keyboard), controls); | 864 G_CALLBACK (clear_keyboard), controls); |
| 954 if (!loaded) return; | 1117 if (!loaded) return; |
| 955 ungrab_keys (); | 1118 ungrab_keys (); |
| 956 release_filter(); | 1119 release_filter(); |
| 957 loaded = FALSE; | 1120 loaded = FALSE; |
| 958 } | 1121 } |
| 959 | 1122 |
| 1123 /* grab required keys */ | |
| 1124 static void ungrab_key(HotkeyConfiguration hotkey) | |
| 1125 { | |
| 1126 unsigned int modifier = hotkey.mask & ~(numlock_mask | capslock_mask | scrolllock_mask); | |
| 1127 | |
| 1128 if (hotkey.key == 0) return; | |
| 1129 | |
| 1130 if (hotkey.type == TYPE_KEY) | |
| 1131 { | |
| 1132 XUngrabKey (xdisplay, hotkey.key, modifier, x_root_window); | |
| 1133 | |
| 1134 if (modifier == AnyModifier) | |
| 1135 return; | |
| 1136 | |
| 1137 if (numlock_mask) | |
| 1138 XUngrabKey (xdisplay, hotkey.key, modifier | numlock_mask, x_root_window); | |
| 1139 | |
| 1140 if (capslock_mask) | |
| 1141 XUngrabKey (xdisplay, hotkey.key, modifier | capslock_mask, x_root_window); | |
| 1142 | |
| 1143 if (scrolllock_mask) | |
| 1144 XUngrabKey (xdisplay, hotkey.key, modifier | scrolllock_mask, x_root_window); | |
| 1145 | |
| 1146 if (numlock_mask && capslock_mask) | |
| 1147 XUngrabKey (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask, x_root_window); | |
| 1148 | |
| 1149 if (numlock_mask && scrolllock_mask) | |
| 1150 XUngrabKey (xdisplay, hotkey.key, modifier | numlock_mask | scrolllock_mask, x_root_window); | |
| 1151 | |
| 1152 if (capslock_mask && scrolllock_mask) | |
| 1153 XUngrabKey (xdisplay, hotkey.key, modifier | capslock_mask | scrolllock_mask, x_root_window); | |
| 1154 | |
| 1155 if (numlock_mask && capslock_mask && scrolllock_mask) | |
| 1156 XUngrabKey (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window); | |
| 1157 } | |
| 1158 if (hotkey.type == TYPE_MOUSE) | |
| 1159 { | |
| 1160 XUngrabButton (xdisplay, hotkey.key, modifier, x_root_window); | |
| 1161 | |
| 1162 if (modifier == AnyModifier) | |
| 1163 return; | |
| 1164 | |
| 1165 if (numlock_mask) | |
| 1166 XUngrabButton (xdisplay, hotkey.key, modifier | numlock_mask, x_root_window); | |
| 1167 | |
| 1168 if (capslock_mask) | |
| 1169 XUngrabButton (xdisplay, hotkey.key, modifier | capslock_mask, x_root_window); | |
| 1170 | |
| 1171 if (scrolllock_mask) | |
| 1172 XUngrabButton (xdisplay, hotkey.key, modifier | scrolllock_mask, x_root_window); | |
| 1173 | |
| 1174 if (numlock_mask && capslock_mask) | |
| 1175 XUngrabButton (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask, x_root_window); | |
| 1176 | |
| 1177 if (numlock_mask && scrolllock_mask) | |
| 1178 XUngrabButton (xdisplay, hotkey.key, modifier | numlock_mask | scrolllock_mask, x_root_window); | |
| 1179 | |
| 1180 if (capslock_mask && scrolllock_mask) | |
| 1181 XUngrabButton (xdisplay, hotkey.key, modifier | capslock_mask | scrolllock_mask, x_root_window); | |
| 1182 | |
| 1183 if (numlock_mask && capslock_mask && scrolllock_mask) | |
| 1184 XUngrabButton (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window); | |
| 1185 } | |
| 1186 } | |
| 1187 | |
| 960 static void ungrab_keys () | 1188 static void ungrab_keys () |
| 961 { | 1189 { |
| 1190 XErrorHandler old_handler = 0; | |
| 1191 | |
| 962 if (!grabbed) return; | 1192 if (!grabbed) return; |
| 963 if (!xdisplay) return; | 1193 if (!xdisplay) return; |
| 964 | 1194 |
| 965 XUngrabKey (xdisplay, AnyKey, AnyModifier, x_root_window); | 1195 XSync(xdisplay, False); |
| 966 | 1196 old_handler = XSetErrorHandler (x11_error_handler); |
| 1197 | |
| 1198 ungrab_key(plugin_cfg.mute); | |
| 1199 ungrab_key(plugin_cfg.vol_up); | |
| 1200 ungrab_key(plugin_cfg.vol_down); | |
| 1201 ungrab_key(plugin_cfg.play); | |
| 1202 ungrab_key(plugin_cfg.pause); | |
| 1203 ungrab_key(plugin_cfg.stop); | |
| 1204 ungrab_key(plugin_cfg.prev_track); | |
| 1205 ungrab_key(plugin_cfg.next_track); | |
| 1206 ungrab_key(plugin_cfg.jump_to_file); | |
| 1207 ungrab_key(plugin_cfg.forward); | |
| 1208 ungrab_key(plugin_cfg.backward); | |
| 1209 ungrab_key(plugin_cfg.toggle_win); | |
| 1210 | |
| 1211 XSync(xdisplay, False); | |
| 1212 XSetErrorHandler (old_handler); | |
| 1213 | |
| 967 grabbed = 0; | 1214 grabbed = 0; |
| 968 } | 1215 } |
