void keyboard::update_mapping( void ) { auto cookie = xcb_get_modifier_mapping_unchecked( _connection ); if ( _keysyms ) xcb_key_symbols_free( _keysyms ); _keysyms = xcb_key_symbols_alloc( _connection ); auto numlockcodes = core::wrap_cptr( xcb_key_symbols_get_keycode( _keysyms, XK_Num_Lock ) ); auto shiftlockcodes = core::wrap_cptr( xcb_key_symbols_get_keycode( _keysyms, XK_Shift_Lock ) ); auto capslockcodes = core::wrap_cptr( xcb_key_symbols_get_keycode( _keysyms, XK_Caps_Lock ) ); auto modeswitchcodes = core::wrap_cptr( xcb_key_symbols_get_keycode( _keysyms, XK_Mode_switch ) ); auto modmap_r = core::wrap_cptr( xcb_get_modifier_mapping_reply( _connection, cookie, nullptr ) ); xcb_keycode_t *modmap = xcb_get_modifier_mapping_keycodes( modmap_r.get() ); _numlock = 0; _shiftlock = 0; _capslock = 0; _modeswitch = 0; for( int i = 0; i < 8; i++ ) { for( int j = 0; j < modmap_r->keycodes_per_modifier; j++ ) { xcb_keycode_t kc = modmap[i * modmap_r->keycodes_per_modifier + j]; look_for( _numlock, numlockcodes, kc, i ); look_for( _shiftlock, shiftlockcodes, kc, i ); look_for( _capslock, capslockcodes, kc, i ); look_for( _modeswitch, modeswitchcodes, kc, i ); } } }
/* * Finds out which modifier mask is the one for numlock, as the user may change this. * */ void xcb_get_numlock_mask(xcb_connection_t *conn) { xcb_key_symbols_t *keysyms; xcb_get_modifier_mapping_cookie_t cookie; xcb_get_modifier_mapping_reply_t *reply; xcb_keycode_t *modmap; int mask, i; const int masks[8] = { XCB_MOD_MASK_SHIFT, XCB_MOD_MASK_LOCK, XCB_MOD_MASK_CONTROL, XCB_MOD_MASK_1, XCB_MOD_MASK_2, XCB_MOD_MASK_3, XCB_MOD_MASK_4, XCB_MOD_MASK_5 }; /* Request the modifier map */ cookie = xcb_get_modifier_mapping_unchecked(conn); /* Get the keysymbols */ keysyms = xcb_key_symbols_alloc(conn); if ((reply = xcb_get_modifier_mapping_reply(conn, cookie, NULL)) == NULL) { xcb_key_symbols_free(keysyms); return; } modmap = xcb_get_modifier_mapping_keycodes(reply); /* Get the keycode for numlock */ #ifdef OLD_XCB_KEYSYMS_API xcb_keycode_t numlock = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK); #else /* For now, we only use the first keysymbol. */ xcb_keycode_t *numlock_syms = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK); if (numlock_syms == NULL) return; xcb_keycode_t numlock = *numlock_syms; free(numlock_syms); #endif /* Check all modifiers (Mod1-Mod5, Shift, Control, Lock) */ for (mask = 0; mask < 8; mask++) for (i = 0; i < reply->keycodes_per_modifier; i++) if (modmap[(mask * reply->keycodes_per_modifier) + i] == numlock) xcb_numlock_mask = masks[mask]; xcb_key_symbols_free(keysyms); free(reply); }
/** Grab key on the root windows. * \param k The keybinding. */ void window_root_grabkey(keybinding_t *k) { int phys_screen = 0; int nscreen = xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); xcb_screen_t *s; xcb_keycode_t kc; if((kc = k->keycode) || (k->keysym && (kc = xcb_key_symbols_get_keycode(globalconf.keysyms, k->keysym)))) do { s = xutil_screen_get(globalconf.connection, phys_screen); xcb_grab_key(globalconf.connection, true, s->root, k->mod, kc, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_key(globalconf.connection, true, s->root, k->mod | XCB_MOD_MASK_LOCK, kc, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_key(globalconf.connection, true, s->root, k->mod | globalconf.numlockmask, kc, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_key(globalconf.connection, true, s->root, k->mod | globalconf.numlockmask | XCB_MOD_MASK_LOCK, kc, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); phys_screen++; } while(phys_screen < nscreen); }
/* * Returns the mask for Mode_switch (to be used for looking up keysymbols by * keycode). * */ uint32_t get_mod_mask(xcb_connection_t *conn, uint32_t keycode) { xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(conn); xcb_get_modifier_mapping_reply_t *modmap_r; xcb_keycode_t *modmap, kc; xcb_keycode_t *modeswitchcodes = xcb_key_symbols_get_keycode(symbols, keycode); if (modeswitchcodes == NULL) return 0; modmap_r = xcb_get_modifier_mapping_reply(conn, xcb_get_modifier_mapping(conn), NULL); modmap = xcb_get_modifier_mapping_keycodes(modmap_r); for (int i = 0; i < 8; i++) for (int j = 0; j < modmap_r->keycodes_per_modifier; j++) { kc = modmap[i * modmap_r->keycodes_per_modifier + j]; for (xcb_keycode_t *ktest = modeswitchcodes; *ktest; ktest++) { if (*ktest != kc) continue; free(modeswitchcodes); free(modmap_r); return (1 << i); } } return 0; }
/* * Returns the modifier mask (XCB_MOD_MASK_*) for the given keysymbol, for * example for XCB_NUM_LOCK (usually configured to mod2). * * This function does not initiate any round-trips. * */ uint32_t get_mod_mask_for(uint32_t keysym, xcb_key_symbols_t *symbols, xcb_get_modifier_mapping_reply_t *modmap_reply) { xcb_keycode_t *codes, *modmap; xcb_keycode_t mod_code; modmap = xcb_get_modifier_mapping_keycodes(modmap_reply); /* Get the list of keycodes for the given symbol */ if (!(codes = xcb_key_symbols_get_keycode(symbols, keysym))) return 0; /* Loop through all modifiers (Mod1-Mod5, Shift, Control, Lock) */ for (int mod = 0; mod < 8; mod++) for (int j = 0; j < modmap_reply->keycodes_per_modifier; j++) { /* Store the current keycode (for modifier 'mod') */ mod_code = modmap[(mod * modmap_reply->keycodes_per_modifier) + j]; /* Check if that keycode is in the list of previously resolved * keycodes for our symbol. If so, return the modifier mask. */ for (xcb_keycode_t *code = codes; *code; code++) { if (*code != mod_code) continue; free(codes); /* This corresponds to the XCB_MOD_MASK_* constants */ return (1 << mod); } } return 0; }
int16_t modfield_from_keysym(xcb_keysym_t keysym) { uint16_t modfield = 0; xcb_keycode_t *keycodes = NULL, *mod_keycodes = NULL; xcb_get_modifier_mapping_reply_t *reply = NULL; xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(dpy); if ((keycodes = xcb_key_symbols_get_keycode(symbols, keysym)) == NULL || (reply = xcb_get_modifier_mapping_reply(dpy, xcb_get_modifier_mapping(dpy), NULL)) == NULL || reply->keycodes_per_modifier < 1 || (mod_keycodes = xcb_get_modifier_mapping_keycodes(reply)) == NULL) { goto end; } unsigned int num_mod = xcb_get_modifier_mapping_keycodes_length(reply) / reply->keycodes_per_modifier; for (unsigned int i = 0; i < num_mod; i++) { for (unsigned int j = 0; j < reply->keycodes_per_modifier; j++) { xcb_keycode_t mk = mod_keycodes[i * reply->keycodes_per_modifier + j]; if (mk == XCB_NO_SYMBOL) { continue; } for (xcb_keycode_t *k = keycodes; *k != XCB_NO_SYMBOL; k++) { if (*k == mk) { modfield |= (1 << i); } } } } end: xcb_key_symbols_free(symbols); free(keycodes); free(reply); return modfield; }
static unsigned GetModifier( xcb_connection_t *p_connection, xcb_key_symbols_t *p_symbols, xcb_keysym_t sym ) { static const unsigned pi_mask[8] = { XCB_MOD_MASK_SHIFT, XCB_MOD_MASK_LOCK, XCB_MOD_MASK_CONTROL, XCB_MOD_MASK_1, XCB_MOD_MASK_2, XCB_MOD_MASK_3, XCB_MOD_MASK_4, XCB_MOD_MASK_5 }; const xcb_keycode_t key = xcb_key_symbols_get_keycode( p_symbols, sym ); if( key == 0 ) return 0; xcb_get_modifier_mapping_cookie_t r = xcb_get_modifier_mapping( p_connection ); xcb_get_modifier_mapping_reply_t *p_map = xcb_get_modifier_mapping_reply( p_connection, r, NULL ); if( !p_map ) return 0; xcb_keycode_t *p_keycode = xcb_get_modifier_mapping_keycodes( p_map ); if( !p_keycode ) return 0; unsigned i_mask = 0; for( int i = 0; i < 8; i++ ) { for( int j = 0; j < p_map->keycodes_per_modifier; j++ ) { if( p_keycode[i * p_map->keycodes_per_modifier + j] == key ) i_mask = pi_mask[i]; } } free( p_map ); // FIXME to check return i_mask; }
/** * g_paste_keybinding_activate: * @self: a #GPasteKeybinding instance * * Activate the keybinding * * Returns: */ G_PASTE_VISIBLE void g_paste_keybinding_activate (GPasteKeybinding *self) { g_return_if_fail (G_PASTE_IS_KEYBINDING (self)); GPasteKeybindingPrivate *priv = self->priv; g_return_if_fail (!priv->active); GPasteXcbWrapper *xcb_wrapper = priv->xcb_wrapper; xcb_connection_t *connection = (xcb_connection_t *) g_paste_xcb_wrapper_get_connection (xcb_wrapper); xcb_screen_t *screen = (xcb_screen_t *) g_paste_xcb_wrapper_get_screen (xcb_wrapper); guint keysym; g_return_if_fail (screen); /* This should never happen */ gtk_accelerator_parse (priv->binding, &keysym, (GdkModifierType *) &priv->modifiers); priv->keycodes = xcb_key_symbols_get_keycode ((xcb_key_symbols_t *) g_paste_xcb_wrapper_get_keysyms (xcb_wrapper), keysym); gdk_error_trap_push (); for (xcb_keycode_t *keycode = priv->keycodes; *keycode; ++keycode) { xcb_grab_key (connection, FALSE, screen->root, priv->modifiers, *keycode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); } xcb_flush (connection); gdk_error_trap_pop_ignored (); priv->active = TRUE; }
int output_string(xcb_generic_event_t* event) { xcb_button_press_event_t *bp = (xcb_button_press_event_t *)event; static char* string; xcb_key_symbols_t sym; printf("%i %c\n", bp->detail,xcb_key_symbols_get_keycode(bp->detail,&sym, 0)); return 0; }
static unsigned GetModifier( xcb_connection_t *p_connection, xcb_key_symbols_t *p_symbols, xcb_keysym_t sym ) { static const unsigned pi_mask[8] = { XCB_MOD_MASK_SHIFT, XCB_MOD_MASK_LOCK, XCB_MOD_MASK_CONTROL, XCB_MOD_MASK_1, XCB_MOD_MASK_2, XCB_MOD_MASK_3, XCB_MOD_MASK_4, XCB_MOD_MASK_5 }; if( sym == 0 ) return 0; /* no modifier */ xcb_get_modifier_mapping_cookie_t r = xcb_get_modifier_mapping( p_connection ); xcb_get_modifier_mapping_reply_t *p_map = xcb_get_modifier_mapping_reply( p_connection, r, NULL ); if( !p_map ) return 0; xcb_keycode_t *p_keys = xcb_key_symbols_get_keycode( p_symbols, sym ); if( !p_keys ) goto end; int i = 0; bool no_modifier = true; while( p_keys[i] != XCB_NO_SYMBOL ) { if( p_keys[i] != 0 ) { no_modifier = false; break; } i++; } if( no_modifier ) goto end; xcb_keycode_t *p_keycode = xcb_get_modifier_mapping_keycodes( p_map ); if( !p_keycode ) goto end; for( int i = 0; i < 8; i++ ) for( int j = 0; j < p_map->keycodes_per_modifier; j++ ) for( int k = 0; p_keys[k] != XCB_NO_SYMBOL; k++ ) if( p_keycode[i*p_map->keycodes_per_modifier + j] == p_keys[k]) { free( p_keys ); free( p_map ); return pi_mask[i]; } end: free( p_keys ); free( p_map ); // FIXME to check return 0; }
static void Mapping( intf_thread_t *p_intf ) { static const xcb_keysym_t p_x11_modifier_ignored[] = { 0, XK_Num_Lock, XK_Scroll_Lock, XK_Caps_Lock, }; intf_sys_t *p_sys = p_intf->p_sys; p_sys->i_map = 0; p_sys->p_map = NULL; /* Registering of Hotkeys */ for( struct hotkey *p_hotkey = p_intf->p_libvlc->p_hotkeys; p_hotkey->psz_action != NULL; p_hotkey++ ) { char *psz_hotkey; if( asprintf( &psz_hotkey, "global-%s", p_hotkey->psz_action ) < 0 ) break; const int i_vlc_action = p_hotkey->i_action; const int i_vlc_key = config_GetInt( p_intf, psz_hotkey ); free( psz_hotkey ); if( !i_vlc_key ) continue; const xcb_keycode_t key = xcb_key_symbols_get_keycode( p_sys->p_symbols, GetX11Key( i_vlc_key & ~KEY_MODIFIER ) ); const unsigned i_modifier = GetX11Modifier( p_sys->p_connection, p_sys->p_symbols, i_vlc_key & KEY_MODIFIER ); for( int j = 0; j < sizeof(p_x11_modifier_ignored)/sizeof(*p_x11_modifier_ignored); j++ ) { const unsigned i_ignored = GetModifier( p_sys->p_connection, p_sys->p_symbols, p_x11_modifier_ignored[j] ); if( j != 0 && i_ignored == 0x00) continue; hotkey_mapping_t *p_map_old = p_sys->p_map; p_sys->p_map = realloc( p_sys->p_map, sizeof(*p_sys->p_map) * (p_sys->i_map+1) ); if( !p_sys->p_map ) { p_sys->p_map = p_map_old; break; } hotkey_mapping_t *p_map = &p_sys->p_map[p_sys->i_map++]; p_map->i_x11 = key; p_map->i_modifier = i_modifier|i_ignored; p_map->i_action = i_vlc_action; } } }
xcb_keycode_t* xcb_get_keycodes(xcb_keysym_t keysym) { // wrapper to get xcb keycodes from keysymbol xcb_key_symbols_t *keysyms; keysyms = xcb_key_symbols_alloc(SWM.xcb_conn); if (!keysyms) { return NULL; } xcb_keycode_t *keycode = xcb_key_symbols_get_keycode(keysyms, keysym); xcb_key_symbols_free(keysyms); return keycode; }
/** Get the first keycode */ xcb_keycode_t get_keycode(xcb_keysym_t keysym) { xcb_keycode_t k, *pk; /* only use the first one */ pk = xcb_key_symbols_get_keycode(nil_.key_syms, keysym); if (pk == 0) { NIL_ERR("no keycode: 0x%x", keysym); return 0; } k = *pk; free(pk); return k; }
static xcb_keycode_t * xcb_get_keycode (xcb_keysym_t keysym) { xcb_key_symbols_t *keysyms; xcb_keycode_t *keycode; if (!(keysyms = xcb_key_symbols_alloc(conn))) return 0; keycode = xcb_key_symbols_get_keycode(keysyms, keysym); xcb_key_symbols_free(keysyms); return keycode; }
void UGlobalHotkeys::regLinuxHotkey(const UKeySequence &keySeq, size_t id) { UHotkeyData data; UKeyData keyData = QtKeyToLinux(keySeq); xcb_keycode_t *keyC = xcb_key_symbols_get_keycode(X11KeySymbs, keyData.key); data.keyCode = *keyC; data.mods = keyData.mods; xcb_grab_key(X11Connection, 1, X11Wid, data.mods, data.keyCode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); // NumLk xcb_grab_key(X11Connection, 1, X11Wid, data.mods | XCB_MOD_MASK_2, data.keyCode,XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); Registered.insert(id, data); }
static xcb_keycode_t _string_to_key_code(const char *s) { xcb_keysym_t keysym; xcb_keycode_t *keycodes; keysym = XStringToKeysym(s); keycodes = xcb_key_symbols_get_keycode(globalconf.keysyms, keysym); if(keycodes) { return keycodes[0]; /* XXX only returning the first is probably not * the best */ } else { return 0; } }
quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) { quint32 native = 0; KeySym keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data()); if (keysym == XCB_NO_SYMBOL) keysym = static_cast<ushort>(key); xcb_key_symbols_t *xcbKeySymbols = xcb_key_symbols_alloc(QX11Info::connection()); QScopedPointer<xcb_keycode_t, QScopedPointerPodDeleter> keycodes( xcb_key_symbols_get_keycode(xcbKeySymbols, keysym)); native = keycodes.data()[0]; // Use the first keycode xcb_key_symbols_free(xcbKeySymbols); return native; }
void App::grabKey() { Q_FOREACH(const TriggerKey& key, m_triggersList) { xcb_keysym_t sym = key.first; uint modifiers = key.second; xcb_keycode_t* keycode = xcb_key_symbols_get_keycode(m_syms, sym); if (!keycode) { g_warning ("Can not convert keyval=%lu to keycode!", sym); } else { xcb_grab_key(QX11Info::connection(), true, QX11Info::appRootWindow(), modifiers, keycode[0], XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); if ((modifiers & XCB_MOD_MASK_SHIFT) == 0) { xcb_grab_key(QX11Info::connection(), true, QX11Info::appRootWindow(), modifiers | XCB_MOD_MASK_SHIFT, keycode[0], XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); } } free(keycode); }
/** Grab key on a window. * \param win The window. * \param k The key. */ static void xwindow_grabkey(xcb_window_t win, keyb_t *k) { if(k->keycode) xcb_grab_key(globalconf.connection, true, win, k->modifiers, k->keycode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); else if(k->keysym) { xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(globalconf.keysyms, k->keysym); if(keycodes) { for(xcb_keycode_t *kc = keycodes; *kc; kc++) xcb_grab_key(globalconf.connection, true, win, k->modifiers, *kc, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); p_delete(&keycodes); } } }
int bind_key(xcb_key_but_mask_t mod_mask, xcb_keysym_t keysym, SCM proc) { xcb_grab_server(wm_conf.connection); xcb_keycode_t *keycode_array = xcb_key_symbols_get_keycode(wm_conf.key_syms, keysym); xcb_keycode_t keycode; int i = 0; if (keycode_array) { while ((keycode = keycode_array[i++]) != XCB_NO_SYMBOL) { xcb_grab_key(wm_conf.connection, 1, wm_conf.screen->root, mod_mask, keycode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); } free(keycode_array); keybinding_t *binding = keybinding_init(keybinding_alloc()); binding->keysym = keysym; binding->mod_mask = mod_mask; binding->scm_proc = proc; sglib_keybinding_t_add(&keybinding_list, binding); } xcb_ungrab_server(wm_conf.connection); xcb_flush(wm_conf.connection); return 1; }
void fill_keycodes() { struct xkb_keymap *keymap; struct xkb_context *context; const struct xkb_rule_names rules={ .rules=xkb_names[0], .model=xkb_names[1], .layout=xkb_names[2], .variant=xkb_names[3], .options=xkb_names[4] }; struct xkb_state *state; enum xkb_state_component current_state; int counter; int i,j,k; char mods[256]; char keysym_asc[256]; char file_path[256]; char command[15]; uint32_t max_keys; int w,h,retval; int jumpto; context=xkb_context_new(0); keymap=xkb_keymap_new_from_names(context,&rules,0); state=NULL; // Get all the modifier keys for(i=8;i<256;i++) { state=xkb_state_new(keymap); current_state=xkb_state_update_key(state, i,XKB_KEY_DOWN); if (current_state!=0) { mods[i]=1; } else { mods[i]=0; } xkb_state_unref(state); } mods[7]=1; // fake mod, used for "no mod" // Read the keyboard definition files sprintf(file_path,"%s/%s.keymap",BASE_CONFIG_DIR,lang_onscreen); FILE *keyboard_file=fopen(file_path,"r"); if (keyboard_file==NULL) { printf("Can't open keyboard definition file %s. Trying with US file\n",file_path); sprintf(file_path,"%s/us.keymap",BASE_CONFIG_DIR); keyboard_file=fopen(file_path,"r"); if (keyboard_file==NULL) { printf("Also failed to open the US keymap file. Aborting.\n"); exit(-1); } } retval=fscanf(keyboard_file,"%s %d",command,&keyboard_blocks); if (retval!=2) { printf("Can't read the number of blocks\n"); } else { max_keys=keyboard_blocks*4*KEYS_PER_ROW; keyboard_lowercase=(struct key_element *)malloc(max_keys*sizeof(struct key_element)); memset(keyboard_lowercase,0,max_keys*sizeof(struct key_element)); for(counter=0;(!feof(keyboard_file))&&(counter<max_keys);counter++) { retval=fscanf(keyboard_file,"%s %d %d",command,&w,&h); if(retval!=3) { break; } keyboard_lowercase[counter].size=KEYS_FONT_SIZE; keyboard_lowercase[counter].g_element[0]=0; keyboard_lowercase[counter].w=w; keyboard_lowercase[counter].h=h; keyboard_lowercase[counter].keycode=0; keyboard_lowercase[counter].modifier=0; if (!strcmp(command,"BLANK")) { keyboard_lowercase[counter].type=KEY_BLANK; keyboard_lowercase[counter].keysym=0; } else if (!strcmp(command,"KEY")) { keyboard_lowercase[counter].type=KEY_PH; retval=fscanf(keyboard_file,"%s",keyboard_lowercase[counter].g_element); keyboard_lowercase[counter].keysym=init_utf8_to_keysym(keyboard_lowercase[counter].g_element); if (keyboard_lowercase[counter].keysym==0) { keyboard_lowercase[counter].type=KEY_BLANK; } } else if ((!strcmp(command,"KEYSYM"))||(!strcmp(command,"KEYSYMTEXT"))) { keyboard_lowercase[counter].type=KEY_PH; retval=fscanf(keyboard_file,"%s",keysym_asc); keyboard_lowercase[counter].keysym=xkb_keysym_from_name(keysym_asc,0); if (keyboard_lowercase[counter].keysym==0) { printf("Unknown keysym %s\n",keysym_asc); keyboard_lowercase[counter].type=KEY_BLANK; } else { if (!strcmp(command,"KEYSYMTEXT")) { retval=fscanf(keyboard_file,"%s",keyboard_lowercase[counter].g_element); keyboard_lowercase[counter].size=KEYS_TEXT_FONT_SIZE; } else { retval=xkb_keysym_to_utf8(keyboard_lowercase[counter].keysym,keyboard_lowercase[counter].g_element,7); if (retval==-1) { retval++; } keyboard_lowercase[counter].g_element[retval]=0;// terminate string } } } else if (!strcmp(command,"TAB")) { keyboard_lowercase[counter].type=KEY_TAB; keyboard_lowercase[counter].keysym=XK_Tab; } else if (!strcmp(command,"SPACE")) { keyboard_lowercase[counter].type=KEY_SPACE; keyboard_lowercase[counter].keysym=XK_space; } else if (!strcmp(command,"RETURN")) { keyboard_lowercase[counter].type=KEY_RETURN; keyboard_lowercase[counter].keysym=XK_Return; } else if (!strcmp(command,"DELETE")) { keyboard_lowercase[counter].type=KEY_DELETE; keyboard_lowercase[counter].keysym=XK_BackSpace; } else if (!strcmp(command,"JUMPTO")) { retval=fscanf(keyboard_file,"%d %s",&jumpto,command); keyboard_lowercase[counter].type=KEY_JUMPTO; keyboard_lowercase[counter].keycode=jumpto; keyboard_lowercase[counter].keysym=0; if (!strcmp(command,"GEN")) { keyboard_lowercase[counter].modifier=0; } else if (!strcmp(command,"SHIFT")) { keyboard_lowercase[counter].modifier=1; } else if (!strcmp(command,"SYMBOLS")) { keyboard_lowercase[counter].modifier=2; } else if (!strcmp(command,"LETTERS")) { keyboard_lowercase[counter].modifier=3; } if (jumpto>=keyboard_blocks) { printf("Ilegal jump to block %d (max. is %d)\n",jumpto,keyboard_blocks); keyboard_lowercase[counter].type=KEY_BLANK; } } else if (!strcmp(command,"UP")) { keyboard_lowercase[counter].type=KEY_UP; keyboard_lowercase[counter].keysym=XK_Up; } else if (!strcmp(command,"DOWN")) { keyboard_lowercase[counter].type=KEY_DOWN; keyboard_lowercase[counter].keysym=XK_Down; } else if (!strcmp(command,"LEFT")) { keyboard_lowercase[counter].type=KEY_LEFT; keyboard_lowercase[counter].keysym=XK_Left; } else if (!strcmp(command,"RIGHT")) { keyboard_lowercase[counter].type=KEY_RIGHT; keyboard_lowercase[counter].keysym=XK_Right; } else { printf("Unknown command %s\n",command); keyboard_lowercase[counter].type=KEY_BLANK; keyboard_lowercase[counter].keysym=0; } } xkb_keysym_t keysym; xkb_keycode_t keycode_mod; for(i=7;i<256;i++) { // do a loop on every modifier if (!mods[i]) { continue; // In this loop we test each modifier with each keycode } state=xkb_state_new(keymap); if (i!=7) { xkb_state_update_key(state, i,XKB_KEY_DOWN); // press the modifier key keycode_mod=i; } else { keycode_mod=0; } for(j=8;j<256;j++) { if (mods[j]) { continue; // Don't test modifiers; we want "normal" keys } keysym=xkb_state_key_get_one_sym(state, j); if (keysym==XKB_KEY_NoSymbol) { continue; } for(k=0;k<counter;k++) { // and now we check each desired key with the keysymbol obtained if ((keyboard_lowercase[k].keycode==0)&&(keyboard_lowercase[k].type!=KEY_BLANK)&&(keyboard_lowercase[k].keysym==keysym)) { keyboard_lowercase[k].keycode=j; keyboard_lowercase[k].modifier=keycode_mod; } } } xkb_state_unref(state); } /*for(k=0;k<counter;k++) { // and now we check each desired key with the keysymbol obtained printf("Texto: %s, Keysym: %d, mod: %d\n",keyboard_lowercase[k].g_element,keyboard_lowercase[k].keycode,keyboard_lowercase[k].modifier); }*/ // Now assign new keysyms to keycodes not used, to allow other keysyms not available in US keyboards xcb_key_symbols_t *symbols; symbols=xcb_key_symbols_alloc(conn); xcb_flush(conn); xcb_keycode_t keycode=8; xcb_keycode_t keycode_found; xcb_keysym_t keysyms[4]; xcb_keycode_t keycode_shift; struct lower_upper_t {xcb_keysym_t upper_first; xcb_keysym_t upper_last; xcb_keysym_t lower_first; xcb_keysym_t lower_last; }; struct lower_upper_t lower_upper[] = { {XKB_KEY_Agrave,XKB_KEY_Odiaeresis,XKB_KEY_agrave,XKB_KEY_odiaeresis}, {XKB_KEY_Oslash,XKB_KEY_THORN,XKB_KEY_oslash,XKB_KEY_thorn}, {0,0,0,0} }; struct lower_upper_t *iter_lu; keycode_shift=*xcb_key_symbols_get_keycode(symbols,XKB_KEY_Shift_L); for(k=0;k<max_keys;k++) { // and now we check each desired key with the keysymbol obtained if ((keyboard_lowercase[k].keycode==0)&&(keyboard_lowercase[k].type!=KEY_BLANK)&&(keyboard_lowercase[k].type!=KEY_JUMPTO)) { // this key is not available in US keyboards; let's redefine a keycode for it keycode_found=0; while(keycode<256) { if ((0==xcb_key_symbols_get_keysym(symbols,keycode,0))&& (0==xcb_key_symbols_get_keysym(symbols,keycode,1))&& (0==xcb_key_symbols_get_keysym(symbols,keycode,2))&& (0==xcb_key_symbols_get_keysym(symbols,keycode,3))) { keycode_found=keycode; break; } keycode++; } if (keycode_found==0) { printf("No more codes available\n"); break; // there are no more free keycodes available } keycode=keycode_found; keysyms[0]=keyboard_lowercase[k].keysym; keysyms[1]=0; keysyms[2]=keyboard_lowercase[k].keysym; keysyms[3]=0; for(iter_lu=lower_upper;iter_lu->upper_first;iter_lu++) { if ((keysyms[0]>=iter_lu->upper_first)&&(keysyms[0]<=iter_lu->upper_last)) { // it's an uppercase special character keysyms[0]|=0x20; // first character as lowercase break; } if ((keysyms[0]>=iter_lu->lower_first)&&(keysyms[0]<=iter_lu->lower_last)) { // it's a lowercase special character keysyms[2]&=0xDF; // second character as uppercase break; } } xcb_change_keyboard_mapping(conn,1,keycode,4,keysyms); // insert the new keysym for(j=k;j<max_keys;j++) { // set the keycode and the shift modifier, if needed, to all keys with that keysyms if (keyboard_lowercase[j].keysym==keysyms[0]) { keyboard_lowercase[j].keycode=keycode; keyboard_lowercase[j].modifier=0; continue; } if (keyboard_lowercase[j].keysym==keysyms[2]) { keyboard_lowercase[j].keycode=keycode; keyboard_lowercase[j].modifier=keycode_shift; continue; } } keycode++; } } xcb_key_symbols_free(symbols); } fclose(keyboard_file); keyboard_current_block=0; xkb_keymap_unref(keymap); xkb_context_unref(context); }
// http://svn.tribler.org/vlc/trunk/modules/control/globalhotkeys/xcb.c // Copyright (C) 2009 the VideoLAN team static unsigned GetModifier( xcb_connection_t *p_connection, xcb_key_symbols_t *p_symbols, xcb_keysym_t sym ) { static const unsigned pi_mask[8] = { XCB_MOD_MASK_SHIFT, XCB_MOD_MASK_LOCK, XCB_MOD_MASK_CONTROL, XCB_MOD_MASK_1, XCB_MOD_MASK_2, XCB_MOD_MASK_3, XCB_MOD_MASK_4, XCB_MOD_MASK_5 }; if( sym == 0 ) return 0; /* no modifier */ #ifdef XCB_KEYSYM_OLD_API /* as seen in Debian Lenny */ const xcb_keycode_t key = xcb_key_symbols_get_keycode( p_symbols, sym ); if( key == 0 ) return 0; #else const xcb_keycode_t *p_keys = xcb_key_symbols_get_keycode( p_symbols, sym ); if( !p_keys ) return 0; int i = 0; bool no_modifier = true; while( p_keys[i] != XCB_NO_SYMBOL ) { if( p_keys[i] != 0 ) { no_modifier = false; break; } i++; } if( no_modifier ) return 0; #endif xcb_get_modifier_mapping_cookie_t r = xcb_get_modifier_mapping( p_connection ); xcb_get_modifier_mapping_reply_t *p_map = xcb_get_modifier_mapping_reply( p_connection, r, NULL ); if( !p_map ) return 0; xcb_keycode_t *p_keycode = xcb_get_modifier_mapping_keycodes( p_map ); if( !p_keycode ) return 0; for( int i = 0; i < 8; i++ ) for( int j = 0; j < p_map->keycodes_per_modifier; j++ ) #ifdef XCB_KEYSYM_OLD_API /* as seen in Debian Lenny */ if( p_keycode[i * p_map->keycodes_per_modifier + j] == key ) { free( p_map ); return pi_mask[i]; } #else for( int k = 0; p_keys[k] != XCB_NO_SYMBOL; k++ ) if( p_keycode[i*p_map->keycodes_per_modifier + j] == p_keys[k]) { free( p_map ); return pi_mask[i]; } #endif free( p_map ); // FIXME to check return 0; }
bool ZealNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) { enabled = true; #ifdef WIN32 MSG* msg = static_cast<MSG*>(message); if(WM_HOTKEY == msg->message && msg->wParam == 10) { emit gotHotKey(); return true; } #elsif LINUX // WIN32 or LINUX xcb_generic_event_t* ev = static_cast<xcb_generic_event_t*>(message); if(((ev->response_type&127) == XCB_KEY_PRESS || (ev->response_type&127) == XCB_KEY_RELEASE) && !hotKey.isEmpty()) { // XCB_KEY_RELEASE must be ignored by Qt because otherwise it causes SIGSEGV in QXcbKeyboard::handleKeyReleaseEvent xcb_connection_t *c = static_cast<xcb_connection_t*>( ((QGuiApplication*)QGuiApplication::instance())-> platformNativeInterface()->nativeResourceForWindow("connection", 0)); xcb_key_press_event_t *event = (xcb_key_press_event_t *)ev; xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(c); xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(keysyms, GetX11Key(hotKey[0])); bool found = false; // found=true means either (a) complete hotkey was pressed, or (b) any of its separate // keys was released. We return true in both cases, because key releases while window // is not present cause SIGSEGV in QXcbKeyboard::handleKeyReleaseEvent if((ev->response_type&127) == XCB_KEY_RELEASE) { QList<QPair<int, Qt::Modifier> > modifiers; modifiers.append(qMakePair(XK_Alt_L, Qt::ALT)); modifiers.append(qMakePair(XK_Alt_R, Qt::ALT)); modifiers.append(qMakePair(XK_Control_L, Qt::CTRL)); modifiers.append(qMakePair(XK_Control_R, Qt::CTRL)); modifiers.append(qMakePair(XK_Meta_L, Qt::META)); modifiers.append(qMakePair(XK_Meta_R, Qt::META)); for(auto modifier : modifiers) { if(!(hotKey[0] & modifier.second)) { continue; } xcb_keycode_t *mod_keycodes = xcb_key_symbols_get_keycode(keysyms, modifier.first); if(mod_keycodes == nullptr) continue; int i = 0; while(mod_keycodes[i] != XCB_NO_SYMBOL) { if(event->detail == mod_keycodes[i]) { found = true; } i += 1; } free(mod_keycodes); } } int i = 0; while(keycodes[i] != XCB_NO_SYMBOL) { if(event->detail == keycodes[i]) { bool modifiers_present = true; if(hotKey[0] & Qt::ALT) { if(!(event->state & GetModifier(c, keysyms, XK_Alt_L) || event->state & GetModifier(c, keysyms, XK_Alt_R))) { modifiers_present = false; } } if(hotKey[0] & Qt::CTRL) { if(!(event->state & GetModifier(c, keysyms, XK_Control_L) || event->state & GetModifier(c, keysyms, XK_Control_R))) { modifiers_present = false; } } if(hotKey[0] & Qt::META) { if(!(event->state & GetModifier(c, keysyms, XK_Meta_L) || event->state & GetModifier(c, keysyms, XK_Meta_R))) { modifiers_present = false; } } if(hotKey[0] & Qt::SHIFT) { if(!(event->state & GetModifier(c, keysyms, XK_Shift_L) || event->state & GetModifier(c, keysyms, XK_Shift_R))) { modifiers_present = false; } } if(enabled && modifiers_present) { xcb_allow_events(c, XCB_ALLOW_ASYNC_KEYBOARD, event->time); if((ev->response_type&127) == XCB_KEY_PRESS) { emit gotHotKey(); } found = true; } else { if((ev->response_type&127) == XCB_KEY_RELEASE) { found = true; } xcb_allow_events(c, XCB_ALLOW_REPLAY_KEYBOARD, event->time); } break; } i += 1; } free(keysyms); free(keycodes); if(found) return true; } #endif // WIN32 or LINUX return false; }
bool GetXCBKeyState(int key) { if(symbols == NULL) return false; KeySym ks = 0; if(key >= eRENDERDOC_Key_A && key <= eRENDERDOC_Key_Z) ks = key; if(key >= eRENDERDOC_Key_0 && key <= eRENDERDOC_Key_9) ks = key; switch(key) { case eRENDERDOC_Key_Divide: ks = XK_KP_Divide; break; case eRENDERDOC_Key_Multiply: ks = XK_KP_Multiply; break; case eRENDERDOC_Key_Subtract: ks = XK_KP_Subtract; break; case eRENDERDOC_Key_Plus: ks = XK_KP_Add; break; case eRENDERDOC_Key_F1: ks = XK_F1; break; case eRENDERDOC_Key_F2: ks = XK_F2; break; case eRENDERDOC_Key_F3: ks = XK_F3; break; case eRENDERDOC_Key_F4: ks = XK_F4; break; case eRENDERDOC_Key_F5: ks = XK_F5; break; case eRENDERDOC_Key_F6: ks = XK_F6; break; case eRENDERDOC_Key_F7: ks = XK_F7; break; case eRENDERDOC_Key_F8: ks = XK_F8; break; case eRENDERDOC_Key_F9: ks = XK_F9; break; case eRENDERDOC_Key_F10: ks = XK_F10; break; case eRENDERDOC_Key_F11: ks = XK_F11; break; case eRENDERDOC_Key_F12: ks = XK_F12; break; case eRENDERDOC_Key_Home: ks = XK_Home; break; case eRENDERDOC_Key_End: ks = XK_End; break; case eRENDERDOC_Key_Insert: ks = XK_Insert; break; case eRENDERDOC_Key_Delete: ks = XK_Delete; break; case eRENDERDOC_Key_PageUp: ks = XK_Prior; break; case eRENDERDOC_Key_PageDn: ks = XK_Next; break; case eRENDERDOC_Key_Backspace: ks = XK_BackSpace; break; case eRENDERDOC_Key_Tab: ks = XK_Tab; break; case eRENDERDOC_Key_PrtScrn: ks = XK_Print; break; case eRENDERDOC_Key_Pause: ks = XK_Pause; break; default: break; } if(ks == 0) return false; xcb_keycode_t *keyCodes = xcb_key_symbols_get_keycode(symbols, ks); if(!keyCodes) return false; xcb_query_keymap_cookie_t keymapcookie = xcb_query_keymap(connection); xcb_query_keymap_reply_t *keys = xcb_query_keymap_reply(connection, keymapcookie, NULL); bool ret = false; if(keys && keyCodes[0] != XCB_NO_SYMBOL) { int byteIdx = (keyCodes[0] / 8); int bitMask = 1 << (keyCodes[0] % 8); ret = (keys->keys[byteIdx] & bitMask) != 0; } free(keyCodes); free(keys); return ret; }
void MainWindow::setHotKey(const QKeySequence& hotKey_) { // platform-specific code for global key grabbing #ifdef WIN32 UINT i_vk, i_mod = 0; if(!hotKey.isEmpty()) { // disable previous hotkey UnregisterHotKey(NULL, 10); } hotKey = hotKey_; nativeFilter.setHotKey(hotKey); settings.setValue("hotkey", hotKey); if(hotKey.isEmpty()) return; int key = hotKey[0]; if(key & Qt::ALT) i_mod |= MOD_ALT; if(key & Qt::CTRL) i_mod |= MOD_CONTROL; if(key & Qt::SHIFT) i_mod |= MOD_SHIFT; key = key & ~(Qt::ALT | Qt::CTRL | Qt::SHIFT | Qt::META); #ifndef VK_VOLUME_DOWN #define VK_VOLUME_DOWN 0xAE #define VK_VOLUME_UP 0xAF #endif #ifndef VK_MEDIA_NEXT_TRACK #define VK_MEDIA_NEXT_TRACK 0xB0 #define VK_MEDIA_PREV_TRACK 0xB1 #define VK_MEDIA_STOP 0xB2 #define VK_MEDIA_PLAY_PAUSE 0xB3 #endif #ifndef VK_PAGEUP #define VK_PAGEUP 0x21 #define VK_PAGEDOWN 0x22 #endif switch(key) { case Qt::Key_Left: i_vk = VK_LEFT; break; case Qt::Key_Right: i_vk = VK_RIGHT; break; case Qt::Key_Up: i_vk = VK_UP; break; case Qt::Key_Down: i_vk = VK_DOWN; break; case Qt::Key_Space: i_vk = VK_SPACE; break; case Qt::Key_Escape: i_vk = VK_ESCAPE; break; case Qt::Key_Enter: i_vk = VK_RETURN; break; case Qt::Key_Return: i_vk = VK_RETURN; break; case Qt::Key_F1: i_vk = VK_F1; break; case Qt::Key_F2: i_vk = VK_F2; break; case Qt::Key_F3: i_vk = VK_F3; break; case Qt::Key_F4: i_vk = VK_F4; break; case Qt::Key_F5: i_vk = VK_F5; break; case Qt::Key_F6: i_vk = VK_F6; break; case Qt::Key_F7: i_vk = VK_F7; break; case Qt::Key_F8: i_vk = VK_F8; break; case Qt::Key_F9: i_vk = VK_F9; break; case Qt::Key_F10: i_vk = VK_F10; break; case Qt::Key_F11: i_vk = VK_F11; break; case Qt::Key_F12: i_vk = VK_F12; break; case Qt::Key_PageUp: i_vk = VK_PAGEUP; break; case Qt::Key_PageDown: i_vk = VK_PAGEDOWN; break; case Qt::Key_Home: i_vk = VK_HOME; break; case Qt::Key_End: i_vk = VK_END; break; case Qt::Key_Insert: i_vk = VK_INSERT; break; case Qt::Key_Delete: i_vk = VK_DELETE; break; case Qt::Key_VolumeDown: i_vk = VK_VOLUME_DOWN; break; case Qt::Key_VolumeUp: i_vk = VK_VOLUME_UP; break; case Qt::Key_MediaTogglePlayPause: i_vk = VK_MEDIA_PLAY_PAUSE; break; case Qt::Key_MediaStop: i_vk = VK_MEDIA_STOP; break; case Qt::Key_MediaPrevious: i_vk = VK_MEDIA_PREV_TRACK; break; case Qt::Key_MediaNext: i_vk = VK_MEDIA_NEXT_TRACK; break; default: i_vk = toupper( key ); break; } if(!RegisterHotKey(NULL, 10, i_mod, i_vk)) { hotKey = QKeySequence(); nativeFilter.setHotKey(hotKey); settings.setValue("hotkey", hotKey); QMessageBox::warning(this, "Key binding failed", "Binding global hotkey failed."); } #elif LINUX auto platform = qApp->platformNativeInterface(); xcb_connection_t *c = static_cast<xcb_connection_t*>(platform->nativeResourceForWindow("connection", 0)); xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(c); if(!hotKey.isEmpty()) { // remove previous bindings from all screens xcb_screen_iterator_t iter; iter = xcb_setup_roots_iterator (xcb_get_setup (c)); for (; iter.rem; xcb_screen_next (&iter)) { xcb_ungrab_key(c, XCB_GRAB_ANY, iter.data->root, XCB_MOD_MASK_ANY); } } hotKey = hotKey_; nativeFilter.setHotKey(hotKey); settings.setValue("hotkey", hotKey); if(hotKey.isEmpty()) return; xcb_keysym_t keysym = GetX11Key(hotKey[0]); xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(keysyms, keysym), keycode; if(!keycodes) { hotKey = QKeySequence(); nativeFilter.setHotKey(hotKey); settings.setValue("hotkey", hotKey); QMessageBox::warning(this, "Key binding failed", "Binding global hotkey failed."); free(keysyms); return; } // add bindings for all screens xcb_screen_iterator_t iter; iter = xcb_setup_roots_iterator (xcb_get_setup (c)); bool any_failed = false; for (; iter.rem; xcb_screen_next (&iter)) { int i = 0; while(keycodes[i] != XCB_NO_SYMBOL) { keycode = keycodes[i]; for(auto modifier : GetX11Modifier(c, keysyms, hotKey[0])) { auto cookie = xcb_grab_key_checked(c, true, iter.data->root, modifier, keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_SYNC); if(xcb_request_check(c, cookie)) { any_failed = true; } } i += 1; } } if(any_failed) { QMessageBox::warning(this, "Key binding warning", "Warning: Global hotkey binding problem detected. Some other program might have a conflicting " "key binding. If the hotkey doesn't work, try closing some programs or using a different hotkey."); } free(keysyms); free(keycodes); #endif // WIN32 or LINUX }
static bool Mapping( intf_thread_t *p_intf ) { static const xcb_keysym_t p_x11_modifier_ignored[] = { 0, XK_Num_Lock, XK_Scroll_Lock, XK_Caps_Lock, }; intf_sys_t *p_sys = p_intf->p_sys; bool active = false; p_sys->i_map = 0; p_sys->p_map = NULL; /* Registering of Hotkeys */ for( const struct hotkey *p_hotkey = p_intf->p_libvlc->p_hotkeys; p_hotkey->psz_action != NULL; p_hotkey++ ) { char varname[12 + strlen( p_hotkey->psz_action )]; sprintf( varname, "global-key-%s", p_hotkey->psz_action ); char *key = var_InheritString( p_intf, varname ); if( key == NULL ) continue; uint_fast32_t i_vlc_key = vlc_str2keycode( key ); free( key ); if( i_vlc_key == KEY_UNSET ) continue; xcb_keycode_t *p_keys = xcb_key_symbols_get_keycode( p_sys->p_symbols, GetX11Key( i_vlc_key & ~KEY_MODIFIER ) ); if( !p_keys ) continue; const unsigned i_modifier = GetX11Modifier( p_sys->p_connection, p_sys->p_symbols, i_vlc_key & KEY_MODIFIER ); const size_t max = sizeof(p_x11_modifier_ignored) / sizeof(*p_x11_modifier_ignored); for( unsigned int i = 0; i < max; i++ ) { const unsigned i_ignored = GetModifier( p_sys->p_connection, p_sys->p_symbols, p_x11_modifier_ignored[i] ); if( i != 0 && i_ignored == 0) continue; hotkey_mapping_t *p_map_old = p_sys->p_map; p_sys->p_map = realloc( p_sys->p_map, sizeof(*p_sys->p_map) * (p_sys->i_map+1) ); if( !p_sys->p_map ) { p_sys->p_map = p_map_old; break; } hotkey_mapping_t *p_map = &p_sys->p_map[p_sys->i_map++]; p_map->p_keys = p_keys; p_map->i_modifier = i_modifier|i_ignored; p_map->i_vlc = i_vlc_key; active = true; } } return active; }