int main(int argc,char **argv) { char manufacturer[256],product[256]; const char *map_filename = 0,*map_mouse_filename = 0; int mode = MODE_MAP; int lookup_mode = LOOKUP_MODE_NAME; // Check we are root uid_t uid; uid = geteuid(); if(uid!=0) { fprintf(stderr,"hid_mapper must be run as root\n"); return EXIT_FAILURE; } // Init hid_device init_hid_device(&hid_device); // Setup signal handler signal(SIGTERM,sigterm_handler); signal(SIGINT,sigterm_handler); if(argc==1) { print_usage(); return -1; } if(argc==2 && strcmp(argv[1],"--list-devices")==0) return lookup_hid_product(LOOKUP_MODE_NAME,0,0,0); if(argc==3 && strcmp(argv[1],"--list-devices")==0 && strcmp(argv[2],"--lookup-id")==0) return lookup_hid_product(LOOKUP_MODE_ID,0,0,0); manufacturer[0] = '\0'; product[0] = '\0'; if(argc>=5) { for(int i=1;i<argc;i++) { if(strcmp(argv[i],"--learn")==0) mode = MODE_LEARN; if(strcmp(argv[i],"--lookup-id")==0) lookup_mode = LOOKUP_MODE_ID; } for(int i=1;i<argc-1;i++) { if(strcmp(argv[i],"--manufacturer")==0) { strcpy(manufacturer,argv[i+1]); i++; } else if(strcmp(argv[i],"--product")==0) { strcpy(product,argv[i+1]); i++; } else if(strcmp(argv[i],"--map")==0) { map_filename = argv[i+1]; i++; } else if(strcmp(argv[i],"--map-mouse")==0) { map_mouse_filename = argv[i+1]; i++; } } } if(manufacturer[0]=='\0' && product[0]=='\0') { print_usage(); return -1; } if(mode==MODE_MAP && map_filename==0 && map_mouse_filename==0) { print_usage(); return -1; } // Load map file EventMapping *map = new EventMapping(); if(mode==MODE_MAP) { if(map_filename!=0) { try { MapReader::LoadMap(map_filename,map); } catch(Exception e) { fprintf(stderr,"Error loading map file\n"); e.Print(); return EXIT_FAILURE; } printf("Loaded map file %s\n",map_filename); } if(map_mouse_filename!=0) { try { MapReaderMouse::LoadMap(map_mouse_filename,map); } catch(Exception e) { fprintf(stderr,"Error loading mouse map file\n"); e.Print(); return EXIT_FAILURE; } printf("Loaded mouse map file %s\n",map_mouse_filename); } } // Lookup for specified HID device int re,max_hid_fd; re = lookup_hid_product(lookup_mode,manufacturer,product,&hid_device); if(re<0) { fprintf(stderr,"Unable to find specified HID device: %d\n", re); return EXIT_FAILURE; } printf("Found HID device\n"); // HID re = open_hid_device(&hid_device); if(re<0) { fprintf(stderr,"Unable to open HID device\n"); return EXIT_FAILURE; } // Setup event device if(mode==MODE_MAP) { uinput_fd = setup_device(Keys::GetMaxKey()); if(uinput_fd==-1) { fprintf(stderr,"Unable to setup event device\n"); return EXIT_FAILURE; } printf("Generic USB mapper driver setup\n"); } LinkedList<event_mapping> *event_map_list; const event_mapping *event_map; unsigned int event_length; char event[EVENT_MAXLENGTH]; int last_key_down = 0; while(1) { event_length = EVENT_MAXLENGTH; re = read_hid_event(&hid_device,event,&event_length); if(re<0) { fprintf(stderr,"Error reading HID event\n"); continue; } if(mode==MODE_LEARN) { for(int i=0;i<event_length;i++) printf("%02x ",(unsigned char)event[i]); printf("\n"); } else { if(last_key_down!=0) { send_key_up_event(uinput_fd,last_key_down); last_key_down = 0; } else { event_map_list = map->LookupEvent(event,event_length); event_map_list->StartEnum(); while(event_map = event_map_list->Enum()) { switch(event_map->type) { case EVENT_TYPE_KEYBOARD: send_key_down_event(uinput_fd,event_map->value); last_key_down = event_map->value; break; case EVENT_TYPE_MOUSE_X: send_mouse_X_event(uinput_fd,event_map->value); break; case EVENT_TYPE_MOUSE_Y: send_mouse_Y_event(uinput_fd,event_map->value); break; } } } } } return 0; }
int main(int argc,char **argv) { char manufacturer[256],product[256]; const char *map_filename = 0,*map_mouse_filename = 0; int mode = MODE_MAP; int lookup_mode = LOOKUP_MODE_NAME; int wait = -1; bool disable_repetition = false; // Check we are root uid_t uid; uid = geteuid(); if(uid!=0) { error("hid_mapper must be run as root\n"); return EXIT_FAILURE; } // Init hid_device init_hid_device(&hid_device); // Setup signal handler signal(SIGTERM,sigterm_handler); signal(SIGINT,sigterm_handler); if(argc==1) { print_usage(); return -1; } if(argc==2 && strcmp(argv[1],"--list-devices")==0) return lookup_hid_product(LOOKUP_MODE_NAME,0,0,0); if(argc==3 && strcmp(argv[1],"--list-devices")==0 && strcmp(argv[2],"--lookup-id")==0) return lookup_hid_product(LOOKUP_MODE_ID,0,0,0); manufacturer[0] = '\0'; product[0] = '\0'; if(argc>=5) { for(int i=1;i<argc;i++) { if(strcmp(argv[i],"--learn")==0) mode = MODE_LEARN; else if(strcmp(argv[i],"--lookup-id")==0) lookup_mode = LOOKUP_MODE_ID; else if(strcmp(argv[i],"--disable-repetition")==0) disable_repetition = true; } for(int i=1;i<argc-1;i++) { if(strcmp(argv[i],"--manufacturer")==0) { strcpy(manufacturer,argv[i+1]); i++; } else if(strcmp(argv[i],"--product")==0) { strcpy(product,argv[i+1]); i++; } else if(strcmp(argv[i],"--map")==0) { map_filename = argv[i+1]; i++; } else if(strcmp(argv[i],"--map-mouse")==0) { map_mouse_filename = argv[i+1]; i++; } else if(strcmp(argv[i],"--wait-device")==0) { wait = atoi(argv[i+1]); i++; } } } if(manufacturer[0]=='\0' && product[0]=='\0') { print_usage(); return -1; } if(mode==MODE_MAP && map_filename==0 && map_mouse_filename==0) { print_usage(); return -1; } if(wait==0) { print_usage(); return -1; } // Load map file EventMapping *map = new EventMapping(); if((mode==MODE_MAP)||(mode==MODE_LEARN)) { if(map_filename!=0) { try { MapReader::LoadMap(map_filename,map); } catch(Exception e) { error("Error loading map file %s", map_filename); e.Print(); return EXIT_FAILURE; } info("Loaded map file %s",map_filename); } if(map_mouse_filename!=0) { try { MapReaderMouse::LoadMap(map_mouse_filename,map); } catch(Exception e) { error("Error loading mouse map file %s", map_mouse_filename); e.Print(); return EXIT_FAILURE; } info("Loaded mouse map file %s",map_mouse_filename); } } // Lookup for specified HID device int re,max_hid_fd; if(wait>0) fprintf(stderr,"Waiting device for %d second(s)\n",wait); while(true) { re = lookup_hid_product(lookup_mode,manufacturer,product,&hid_device); if(re>=0 || wait<=0) break; wait--; sleep(1); } if(re<0) { error("Unable to find specified HID device (%s; %s)", manufacturer,product); return EXIT_FAILURE; } if(wait!=-1) { re = lookup_hid_product(lookup_mode,manufacturer,product,&hid_device); } else { re = lookup_hid_product(lookup_mode,manufacturer,product,&hid_device); } info("Found HID device"); // HID re = open_hid_device(&hid_device); if(re<0) { error("Unable to open HID device"); return EXIT_FAILURE; } // Setup event device if(mode==MODE_MAP) { uinput_fd = setup_device(Keys::GetMaxKey()); if(uinput_fd==-1) { error("Unable to setup event device"); return EXIT_FAILURE; } info("Generic USB mapper driver setup"); } LinkedList<event_mapping> *event_map_list; const event_mapping *event_map = NULL; unsigned int event_length; char event[EVENT_MAXLENGTH]; int last_key_down = 0, last_key_code = 0; unsigned int count = 0; // otput "standard" header when learning new map if((mode==MODE_LEARN) && (map_filename)) { printf("#\n"); printf("# manufacturer : %s\n", manufacturer); printf("# product : %s\n", product); printf("#\n"); } while(1) { // assume two events per key pressed (down & up) if((mode==MODE_LEARN) && (map_filename) && (!(count&1))) { event_map = map->EnumEvent(); if (!event_map) break; if ((event_map->length ==1))//&&(event_map->event[0]==0)) fprintf(stderr, "%d, Press %s(%d)\n",event_map->length,Keys::ReverseLookup(event_map->value),event_map->value); } event_length = EVENT_MAXLENGTH; re = read_hid_event(&hid_device,event,&event_length); if(re<0) { warn("Error reading HID event"); continue; } ++count; if(mode==MODE_LEARN) { if (event_map) { if ((count&1)) { for(int i=0;i<event_length;i++) printf("%02x",(unsigned char)event[i]); printf(":%s\n", Keys::ReverseLookup(event_map->value)); } } else { for(int i=0;i<event_length;i++) printf("%02x ",(unsigned char)event[i]); printf("\n"); } } else { if(last_key_down!=0) { send_key_up_event(uinput_fd,last_key_down); last_key_down = 0; } else { event_map_list = map->LookupEvent(event,event_length); event_map_list->StartEnum(); while(event_map = event_map_list->Enum()) { switch(event_map->type) { case EVENT_TYPE_KEYBOARD: send_key_down_event(uinput_fd,event_map->value); last_key_code = event_map->value; if(disable_repetition) send_key_up_event(uinput_fd,last_key_code); else last_key_down = last_key_code; break; case EVENT_TYPE_MOUSE_X: send_mouse_X_event(uinput_fd,event_map->value); break; case EVENT_TYPE_MOUSE_Y: send_mouse_Y_event(uinput_fd,event_map->value); break; case EVENT_TYPE_CORE: switch(event_map->value) { case EVENT_CORE_LAST_KEY: if(!last_key_code) break; send_key_down_event(uinput_fd,last_key_code); if(disable_repetition) send_key_up_event(uinput_fd,last_key_code); else last_key_down = last_key_code; break; } break; } } } } } return 0; }