/***************************************************************************** * Close: *****************************************************************************/ static void Close( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t *)p_this; intf_sys_t *p_sys = p_intf->p_sys; if( !p_sys ) return; /* if we were running disabled */ vlc_cancel( p_sys->thread ); vlc_join( p_sys->thread, NULL ); if( p_sys->p_map ) { free( p_sys->p_map->p_keys ); free( p_sys->p_map ); } xcb_key_symbols_free( p_sys->p_symbols ); xcb_disconnect( p_sys->p_connection ); free( p_sys ); }
static int _e_alert_handle_key_press(xcb_generic_event_t *event) { xcb_key_symbols_t *symbols; xcb_key_press_event_t *ev; xcb_keysym_t key; int r = 0; ev = (xcb_key_press_event_t *)event; symbols = xcb_key_symbols_alloc(conn); key = xcb_key_symbols_get_keysym(symbols, ev->detail, 0); if (key == XK_F1) r = 1; else if (key == XK_F12) r = 2; xcb_key_symbols_free(symbols); return r; }
void WindowSelector::handleKeyPress(xcb_keycode_t keycode, uint16_t state) { xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(connection()); xcb_keysym_t kc = xcb_key_symbols_get_keysym(symbols, keycode, 0); int mx = 0; int my = 0; const bool returnPressed = (kc == XK_Return) || (kc == XK_space); const bool escapePressed = (kc == XK_Escape); if (kc == XK_Left) { mx = -10; } if (kc == XK_Right) { mx = 10; } if (kc == XK_Up) { my = -10; } if (kc == XK_Down) { my = 10; } if (state & XCB_MOD_MASK_CONTROL) { mx /= 10; my /= 10; } Cursor::setPos(Cursor::pos() + QPoint(mx, my)); if (returnPressed) { selectWindowUnderPointer(); } if (returnPressed || escapePressed) { if (escapePressed) { m_callback(nullptr); } release(); } xcb_key_symbols_free(symbols); }
int main(int argc, char *argv[]) { char opt; char *fifo_path = NULL; char *socket_path = NULL; status_fifo = NULL; config_path = NULL; mapping_count = 0; timeout = TIMEOUT; grabbed = false; sock_address.sun_family = AF_UNIX; sock_address.sun_path[0] = 0; snprintf(motion_msg_tpl, sizeof(motion_msg_tpl), "%s", MOTION_MSG_TPL); unsigned int max_freq = 0; motion_interval = 0; last_motion_time = 0; redir_fd = -1; while ((opt = getopt(argc, argv, "vhm:t:c:r:s:f:o:g:")) != (char)-1) { switch (opt) { case 'v': printf("%s\n", VERSION); exit(EXIT_SUCCESS); break; case 'h': printf("sxhkd [-h|-v|-m COUNT|-t TIMEOUT|-c CONFIG_FILE|-r REDIR_FILE|-s STATUS_FIFO|-o MOTION_SOCKET|-g MOTION_MSG_TPL] [EXTRA_CONFIG ...]\n"); exit(EXIT_SUCCESS); break; case 'm': if (sscanf(optarg, "%i", &mapping_count) != 1) warn("Can't parse mapping count.\n"); break; case 't': timeout = atoi(optarg); break; case 'c': config_path = optarg; break; case 'r': redir_fd = open(optarg, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (redir_fd == -1) warn("Failed to open the command redirection file.\n"); break; case 's': fifo_path = optarg; break; case 'o': socket_path = optarg; break; case 'g': snprintf(motion_msg_tpl, sizeof(motion_msg_tpl), "%s", optarg); break; case 'f': if (sscanf(optarg, "%u", &max_freq) != 1) warn("Can't parse maximum pointer frequency.\n"); break; } } num_extra_confs = argc - optind; extra_confs = argv + optind; if (config_path == NULL) { char *config_home = getenv(CONFIG_HOME_ENV); if (config_home != NULL) snprintf(config_file, sizeof(config_file), "%s/%s", config_home, CONFIG_PATH); else snprintf(config_file, sizeof(config_file), "%s/%s/%s", getenv("HOME"), ".config", CONFIG_PATH); } else { snprintf(config_file, sizeof(config_file), "%s", config_path); } if (socket_path == NULL) { socket_path = getenv(SOCKET_ENV); } if (socket_path == NULL) { char *host = NULL; int dn = 0, sn = 0; if (xcb_parse_display(NULL, &host, &dn, &sn) != 0) { snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), SOCKET_PATH_TPL, host, dn, sn); } else { warn("Failed to set motion socket address."); } free(host); } else { snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), "%s", socket_path); } if (fifo_path != NULL) { int fifo_fd = open(fifo_path, O_RDWR | O_NONBLOCK); if (fifo_fd != -1) status_fifo = fdopen(fifo_fd, "w"); else warn("Couldn't open status fifo.\n"); } if (max_freq != 0) motion_interval = 1000.0 / max_freq; signal(SIGINT, hold); signal(SIGHUP, hold); signal(SIGTERM, hold); signal(SIGUSR1, hold); signal(SIGUSR2, hold); signal(SIGALRM, hold); setup(); get_standard_keysyms(); get_lock_fields(); escape_chord = make_chord(ESCAPE_KEYSYM, XCB_NONE, 0, XCB_KEY_PRESS, false, false); load_config(config_file); for (int i = 0; i < num_extra_confs; i++) load_config(extra_confs[i]); grab(); xcb_generic_event_t *evt; int fd = xcb_get_file_descriptor(dpy); fd_set descriptors; reload = toggle_grab = bell = chained = locked = false; running = true; xcb_flush(dpy); while (running) { FD_ZERO(&descriptors); FD_SET(fd, &descriptors); if (select(fd + 1, &descriptors, NULL, NULL, NULL) > 0) { while ((evt = xcb_poll_for_event(dpy)) != NULL) { uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(evt); switch (event_type) { case XCB_KEY_PRESS: case XCB_KEY_RELEASE: case XCB_BUTTON_PRESS: case XCB_BUTTON_RELEASE: key_button_event(evt, event_type); break; case XCB_MOTION_NOTIFY: motion_notify(evt); break; case XCB_MAPPING_NOTIFY: mapping_notify(evt); break; default: PRINTF("received event %u\n", event_type); break; } free(evt); } } if (reload) { signal(SIGUSR1, hold); reload_cmd(); reload = false; } if (toggle_grab) { signal(SIGUSR2, hold); toggle_grab_cmd(); toggle_grab = false; } if (bell) { signal(SIGALRM, hold); abort_chain(); if (status_fifo != NULL) put_status(TIMEOUT_PREFIX, "Timeout reached"); bell = false; } if (xcb_connection_has_error(dpy)) { warn("The server closed the connection.\n"); running = false; } } if (redir_fd != -1) close(redir_fd); if (status_fifo != NULL) fclose(status_fifo); ungrab(); cleanup(); destroy_chord(escape_chord); xcb_key_symbols_free(symbols); xcb_disconnect(dpy); return EXIT_SUCCESS; }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t *)p_this; intf_sys_t *p_sys; int ret = VLC_EGENERIC; p_intf->p_sys = p_sys = calloc( 1, sizeof(*p_sys) ); if( !p_sys ) return VLC_ENOMEM; int i_screen_default; p_sys->p_connection = xcb_connect( NULL, &i_screen_default ); if( xcb_connection_has_error( p_sys->p_connection ) ) goto error; /* Get the root windows of the default screen */ const xcb_setup_t* xcbsetup = xcb_get_setup( p_sys->p_connection ); if( !xcbsetup ) goto error; xcb_screen_iterator_t iter = xcb_setup_roots_iterator( xcbsetup ); for( int i = 0; i < i_screen_default; i++ ) { if( !iter.rem ) break; xcb_screen_next( &iter ); } if( !iter.rem ) goto error; p_sys->root = iter.data->root; /* */ p_sys->p_symbols = xcb_key_symbols_alloc( p_sys->p_connection ); // FIXME if( !p_sys->p_symbols ) goto error; if( !Mapping( p_intf ) ) { ret = VLC_SUCCESS; p_intf->p_sys = NULL; /* for Close() */ goto error; } Register( p_intf ); if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) ) { if( p_sys->p_map ) { free( p_sys->p_map->p_keys ); free( p_sys->p_map ); } goto error; } return VLC_SUCCESS; error: if( p_sys->p_symbols ) xcb_key_symbols_free( p_sys->p_symbols ); xcb_disconnect( p_sys->p_connection ); free( p_sys ); return ret; }
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); }
void XCB_keyHandler_Destroy (key_handler_t *ctx) { xcb_key_symbols_free (ctx->syms); free (ctx); }
keyboard::~keyboard( void ) { if ( _keysyms ) xcb_key_symbols_free( _keysyms ); }
void DestroyKeyHandler (key_handler_t *ctx) { xcb_key_symbols_free (ctx->syms); free (ctx); }