static void process_console_records(void) { INPUT_RECORD record; DWORD bytesRead; DWORD n = 0; if (FALSE == GetNumberOfConsoleInputEvents(SLw32_Hstdin, &n)) return; while (n > 0) { ReadConsoleInput(SLw32_Hstdin, &record, 1, &bytesRead); switch (record.EventType) { case KEY_EVENT: (void) process_key_event(&record.Event.KeyEvent); break; case MOUSE_EVENT: process_mouse_event(&record.Event.MouseEvent); break; case WINDOW_BUFFER_SIZE_EVENT: /* process_resize_records(&record.Event.WindowBufferSizeEvent); */ break; } n--; } }
int main (int argc, char **argv) { /* generic purpose counter */ int i, j, count; signed char ch; unsigned short cmd_opts = 0; char *devnode = NULL; active = 1; /* must be set to true to run binds */ /* default conf_file */ /* fixme: what if there's no HOME environ var? */ conf_file = calloc(strlen(getenv("HOME")) + strlen("/.ebindkeysrc"), sizeof(char)); sprintf(conf_file, "%s/.ebindkeysrc", getenv("HOME")); /* work through command line options */ while( (ch = getopt(argc, argv, "f:dslrhne:")) != -1) { switch (ch) { case 'f': /* override default conf file */ free(conf_file); conf_file = strdup(optarg); break; case 'd': /* don't fork at startup */ cmd_opts |= EBK_NODAEMON; break; case 's': /* don't fork when executing actions. */ cmd_opts |= EBK_NOFORK; break; case 'l': /* list the names of keys */ break; case 'r': /* report key presses / releases */ cmd_opts |= EBK_SHOWKEYS; break; case 'n': devnode = strdup(optarg); break; case ':': exit(1); break; case 'h': break; case 'e': cmd_opts |= EBK_EXPERIMENTAL; break; /*default: printf("Usage: %s [options]\n", argv[0]); exit(1); break; */ } } /* check if a conf file exists, if not, bitch at user */ FILE *conf_check; if (! (conf_check = fopen(conf_file, "r")) ) // check home or command line dir first { fprintf(stderr, "%s: could not open config file %s\n", argv[0], conf_file); free(conf_file); conf_file = "/etc/ebindkeysrc"; if (! (conf_check = fopen(conf_file, "r")) ) // check etc { fprintf(stderr, "%s: could not open config file %s\n", argv[0], conf_file); exit(2); } else fclose(conf_check); } else fclose(conf_check); printf("%s: Loaded config file %s\n", argv[0], conf_file); settings *conf = load_settings(conf_file); /* combine command line options with setting file options. * command line options override conf file */ conf->opts |= cmd_opts; if (devnode != NULL) conf->dev = devnode; event *event_first = conf->event_first; event_list_global = &event_first; /* initialize key_press list */ key_press *list_start = calloc(1,sizeof(key_press)); list_start->next = NULL; /* points to the last struct in the linked list */ key_press *list_end = list_start; key_press *list_cur, *list_prev; struct input_event ievent; /* No buffering, for now. */ int eventfh; int ufile; int ufile_mouse; /* open uinput for exclusive access to the input device */ if(!openUInput(&ufile, &ufile_mouse, &eventfh, conf->dev)) exit(3); /* How does a good parent prevent his children from becoming * part of the zombie hoard? He ignores them! */ signal(SIGCHLD, SIG_IGN); signal(SIGUSR1, reload_settings); if ( ! ( ISSET(conf->opts, EBK_NODAEMON) ) ) if (fork()) exit(0); for(;;) { if ( read(eventfh, &ievent, sizeof(struct input_event)) == -1 ) { /* read() will always get sizeof(struct input_event) number * of bytes, the kernel gurantees this, so we only worry * about reads error. */ perror("Error reading device"); exit(3); } /* Do nothing if lid is closed */ if ( lidstate() != LID_CLOSED ) { int bFiltered = 0; if(bProcessMouse || bTempProcessMouse){ bFiltered = process_mouse_event(ufile_mouse, &ievent); if(bFiltered) continue; } /* Key has been pressed */ if ( ievent.type == EV_KEY && ievent.value == EBK_KEY_DOWN ) { if ( ISSET(conf->opts, EBK_SHOWKEYS) ) { printf(">%X<\n", ievent.code); fflush(stdout); } /*reset the keyboard timer and turn on the lights */ onKeyPress(); /* if no other keys are pressed, filter the keystroke */ if(list_start->next == NULL) bFiltered = filterKeyStroke(ufile, ufile_mouse, &ievent, ISSET(conf->opts, EBK_EXPERIMENTAL)); // if(bFiltered) continue; /* add to depressed struct */ list_end->code = ievent.code; list_end->next = calloc(1,sizeof(key_press)); list_end = list_end->next; list_end->next = NULL; Match_keysToEvent(list_start, event_first, (ISSET(conf->opts, EBK_NOFORK)), cfg_false); } /* Key has been released */ if ( ievent.type == EV_KEY && ievent.value == EBK_KEY_UP ) { if ( ISSET(conf->opts,EBK_SHOWKEYS) ) { printf("<%X>\n", ievent.code); fflush(stdout); } Match_keysToEvent(list_start, event_first, (ISSET(conf->opts, EBK_NOFORK)), cfg_true); /* remove from depressed struct */ list_cur = list_start; list_prev = NULL; while (list_cur->code != ievent.code && list_cur->next != NULL) { list_prev = list_cur; list_cur = list_cur->next; } /* if the bellow is true, most likely, a key was released * but ebindkeys didn't detect the press */ if (list_cur->next == NULL) continue; if (list_prev == NULL) { /* no previous? we're at start! */ list_start = list_cur->next; } else { list_prev->next = list_cur->next; } free(list_cur); if(ievent.code == KEY_LEFTCTRL) bTempProcessMouse=0; } if(!bFiltered) write(ufile, &ievent, sizeof(struct input_event)); } } if(ioctl(ufile, UI_DEV_DESTROY) < 0) fprintf(stderr, "Error destroying uinput device!"); if(ioctl(ufile_mouse, UI_DEV_DESTROY) < 0) fprintf(stderr, "Error destroying uinput device!"); close(eventfh); close(ufile); close(ufile_mouse); return 0; }