int toggle_g15lights(int g15screen_fd, int lightstatus, int fg_check) { int dummy=0; if(lightstatus) { usleep(500); g15_send_cmd (g15screen_fd, G15DAEMON_BACKLIGHT, G15_BRIGHTNESS_MEDIUM); usleep(500); g15_send_cmd (g15screen_fd, G15DAEMON_KB_BACKLIGHT, G15_BRIGHTNESS_MEDIUM); if (bright) { // Fade up to bright usleep(500); g15_send_cmd (g15screen_fd, G15DAEMON_BACKLIGHT, G15_BRIGHTNESS_BRIGHT); usleep(500); g15_send_cmd (g15screen_fd, G15DAEMON_KB_BACKLIGHT, G15_BRIGHTNESS_BRIGHT); } } else { g15_send_cmd (g15screen_fd, G15DAEMON_SWITCH_PRIORITIES, dummy); usleep(500); g15_send_cmd (g15screen_fd, G15DAEMON_BACKLIGHT, G15_BRIGHTNESS_DARK); usleep(500); g15_send_cmd (g15screen_fd, G15DAEMON_KB_BACKLIGHT, G15_BRIGHTNESS_DARK); } return 0; }
void cleanup() { int i; if(recording){ recording = 0; XUngrabKeyboard(dpy,CurrentTime); } memset(configpath,0,sizeof(configpath)); strcpy(configpath,configDir); strncat(configpath,configs[currConfig]->configfile,sizeof(configpath)-strlen(configpath)); save_macros(configpath); for (i = 0; i < MAX_CONFIGS; ++i) { if(configs[i]) { if (configs[i]->configfile) { free(configs[i]->configfile); configs[i]->configfile = NULL; } free(configs[i]); } configs[i] = NULL; } g15_send_cmd (g15screen_fd,G15DAEMON_MKEYLEDS,0); pthread_join(Xkeys,NULL); pthread_join(Lkeys,NULL); pthread_mutex_destroy(&x11mutex); pthread_mutex_destroy(&config_mutex); pthread_mutex_destroy(&gui_select); /* revert the keymap to g15daemon default on exit */ change_keymap(0); close(g15screen_fd); emptyMstates(1); free(mstates[0]); free(mstates[1]); free(mstates[2]); }
void record_complete(unsigned long keystate) { char tmpstr[1024]; int gkey = map_gkey(keystate); pthread_mutex_lock(&config_mutex); if(!rec_index) // nothing recorded - delete prior recording memset(mstates[mkey_state]->gkeys[gkey].keysequence.recorded_keypress,0,sizeof(keysequence_t)); else memcpy(mstates[mkey_state]->gkeys[gkey].keysequence.recorded_keypress, ¤t_recording, sizeof(keysequence_t)); mstates[mkey_state]->gkeys[gkey].keysequence.record_steps=rec_index; pthread_mutex_unlock(&config_mutex); g15r_clearScreen(canvas,G15_COLOR_WHITE); if(rec_index){ strcpy(tmpstr,"For key "); strcat(tmpstr,gkeystring[map_gkey(keystate)]); g15macro_log("Recording Complete %s\n",tmpstr); g15r_renderString (canvas, (unsigned char *)"Recording", 0, G15_TEXT_LARGE, 80-((strlen("Recording")/2)*8), 4); g15r_renderString (canvas, (unsigned char *)"Complete", 0, G15_TEXT_LARGE, 80-((strlen("Complete")/2)*8), 18); }else{ strcpy(tmpstr,"From Key "); printf("%lu\n",keystate); strcat(tmpstr,gkeystring[map_gkey(keystate)]); g15macro_log("Macro deleted %s\n",tmpstr); g15r_renderString (canvas, (unsigned char *)"Macro", 0, G15_TEXT_LARGE, 80-((strlen("Macro")/2)*8), 4); g15r_renderString (canvas, (unsigned char *)"Deleted", 0, G15_TEXT_LARGE, 80-((strlen("Deleted")/2)*8), 18); } g15r_renderString (canvas, (unsigned char *)tmpstr, 0, G15_TEXT_LARGE, 80-((strlen(tmpstr)/2)*8), 32); g15_send(g15screen_fd,(char *)canvas->buffer,G15_BUFFER_LEN); record_cleanup(); g15_send_cmd (g15screen_fd,G15DAEMON_MKEYLEDS,mled_state); save_macros(configpath); }
void handle_mkey_switch(unsigned int mkey) { int mkey_offset = 0; switch(mkey) { case G15_KEY_M1: mled_state=G15_LED_M1; mkey_state=0; break; case G15_KEY_M2: mled_state=G15_LED_M2; mkey_state=1; break; case G15_KEY_M3: mled_state=G15_LED_M3; mkey_state=2; break; } mkey_offset = calc_mkey_offset(); if(recording) record_cancel(); g15_send_cmd (g15screen_fd,G15DAEMON_MKEYLEDS,mled_state); change_keymap(mkey_offset); }
int main(int argc, char **argv) { Display *dpy; int g15screen_fd; int event; int error; BOOL enabled = True; CARD16 power = 0; int dummy = 0, lights = True, change = 0; int i; struct sigaction new_action; char * enable_cmd = NULL; char * disable_cmd = NULL; int dpms_timeout = 0; for (i=0;i<argc;i++) { char argument[20]; memset(argument,0,20); strncpy(argument,argv[i],19); if (!strncmp(argument, "-a",2) || !strncmp(argument, "--activate",10)) { if(argv[i+1]!=NULL){ sscanf(argv[i+1],"%i",&dpms_timeout); i++; }else{ printf("%s --activate requires an argument <minutes to activation>\n",argv[0]); exit(1); } } if (!strncmp(argument, "-e",2) || !strncmp(argument, "--cmd-enable",12)) { if(argv[i+1]!=NULL){ enable_cmd = malloc(strlen(argv[i+1])+1); memcpy(enable_cmd, argv[i+1], strlen(argv[i+1])); i++; } } if (!strncmp(argument, "-d",2) || !strncmp(argument, "--cmd-disable",13)) { if(argv[i+1]!=NULL){ disable_cmd = malloc(strlen(argv[i+1])+1); memcpy(disable_cmd, argv[i+1], strlen(argv[i+1])); i++; } } if (!strncmp(argument, "-v",2) || !strncmp(argument, "--version",9)) { printf("%s version %s\n",argv[0],VERSION); exit(0); } if (!strncmp(argument, "-b",2) || !strncmp(argument, "--bright",13)) { bright=1; } if (!strncmp(argument, "-h",2) || !strncmp(argument, "--help",6)) { printf(" %s version %s\n (c)2007 Mike Lampard\n\n",argv[0],VERSION); printf(" -a or --activate <minutes> - cause DPMS to be activated in <minutes> if no activity.\n"); printf(" By default, %s will simply monitor DPMS status, and\n",argv[0]); printf(" requires a screensaver to activate. \n"); printf(" In this mode, no screensver is needed.\n"); printf(" %s will shut the monitor down on its own after <minutes>\n",argv[0]); printf(" with no keyboard or mouse activity.\n"); printf(" -e or --cmd-enable <cmd to run> - Run program <cmd> when DPMS is activated.\n\n"); printf(" -d or --cmd-disable <cmd to run> - Run program <cmd> when DPMS is de-activated.\n\n"); printf(" -b or --bright - When the keyboard is woken up, set the LEDs to bright.\n\n"); printf(" -v or --version - Show program version\n\n"); printf(" -h or --help - This page\n\n"); exit(0); } } dpy = XOpenDisplay(getenv("DISPLAY")); if (!dpy) { printf("Unable to open display %s - exiting\n",getenv("DISPLAY")); return 1; } do { if((g15screen_fd = new_g15_screen(G15_G15RBUF))<0){ printf("Sorry, cant connect to the G15daemon - retrying\n"); sleep(2); } }while(g15screen_fd<0); if (!DPMSQueryExtension (dpy, &event, &error)) { printf ("XDPMS extension not supported.\n"); return 1; } if (!DPMSCapable(dpy)) { printf("DPMS is not enabled... exiting\n"); return 1; } if (dpms_timeout>0) { DPMSEnable(dpy); DPMSSetTimeouts(dpy,dpms_timeout*60,dpms_timeout*60,0); } new_action.sa_handler = sighandler; new_action.sa_flags = 0; sigaction(SIGINT, &new_action, NULL); sigaction(SIGQUIT, &new_action, NULL); while(!leaving) { int fg_check = g15_send_cmd (g15screen_fd, G15DAEMON_IS_FOREGROUND, dummy); if (! DPMSInfo (dpy, &power, &enabled)) { printf ("unable to get DPMS state.\n"); return 1; } switch(power) { case DPMSModeOn: { if (lights == False) { change = 1; fork_child(enable_cmd); } lights = True; break; } case DPMSModeStandby: case DPMSModeSuspend: case DPMSModeOff: { if(lights == True){ change = 1; fork_child(disable_cmd); } lights = False; break; } } if (fg_check==1 && lights == True && change == 0) { // foreground g15_send_cmd (g15screen_fd, G15DAEMON_SWITCH_PRIORITIES, dummy); } if(change) { toggle_g15lights(g15screen_fd,lights,fg_check); change=0; } sleep (1); } close(g15screen_fd); if(enable_cmd!=NULL) free(enable_cmd); if(disable_cmd!=NULL) free(disable_cmd); XCloseDisplay(dpy); return 0; }
void *Lkeys_thread() { int keystate = 0; int volume; struct pollfd fds; char ver[5]; strncpy(ver,G15DAEMON_VERSION,3); float g15v; sscanf(ver,"%f",&g15v); fds.fd = g15screen_fd; fds.events = POLLIN; while(!leaving){ int foo=0; current_fg_check = g15_send_cmd (g15screen_fd, G15DAEMON_IS_FOREGROUND, foo); static int last_fg_check = 0; if(playlist_mode && last_fg_check != current_fg_check){ if(own_keyboard){ if(current_fg_check==0){ own_keyboard=0; } }else if(current_fg_check && !own_keyboard) { own_keyboard=1; } last_fg_check = current_fg_check; } /* g15daemon series 1.2 need key request packets */ pthread_mutex_lock(&daemon_mutex); if((g15v*10)<=18) { keystate = g15_send_cmd (g15screen_fd, G15DAEMON_GET_KEYSTATE, foo); } else { if ((poll(&fds, 1, 5)) > 0) read (g15screen_fd, &keystate, sizeof (keystate)); } pthread_mutex_unlock(&daemon_mutex); if (keystate) { switch (keystate) { case G15_KEY_L1: exit(1); // FIXME quick hack to exit break; case G15_KEY_L2: menulevel++; if(menulevel>=MAX_MENU_MODES) menulevel=0; break; case G15_KEY_L3: if(!own_keyboard){ own_keyboard=playlist_mode=1; mpd_Song *song = mpd_playlist_get_current_song(obj); if(song) if(song->pos) track_info.currentsong=song->pos; }else{ //de-activate own_keyboard=playlist_mode=0; } break; case G15_KEY_L4: if(menulevel==MENU_MODE1){ mpd_player_set_random(obj,mpd_player_get_random(obj)^1); } if(menulevel==MENU_MODE2){ volume=mpd_status_get_volume(obj); if(volume>0) volume-=10; mpd_status_set_volume (obj,volume); } break; case G15_KEY_L5: if(menulevel==MENU_MODE1){ mpd_player_set_repeat(obj, mpd_player_get_repeat(obj)^1); } if(menulevel==MENU_MODE2){ volume=mpd_status_get_volume(obj); if(volume<100) volume+=10; mpd_status_set_volume (obj,volume); } break; default: break; } keystate = 0; } usleep(100*1000); } return NULL; }
int main(int argc, char **argv) { // init vars have_xtest = False; numConfigs = 0; currConfig = 0; gui_selectConfig = 0; G15Version = 0; config_fd = 0; mled_state = G15_LED_M1; mkey_state = 0; recording = 0; // this is for keeping track of when to redraw gui_oldConfig = MAX_CONFIGS+1; // To make sure it will be redrawn at first was_recording = 1; #ifdef USE_XTEST int xtest_major_version = 0; int xtest_minor_version = 0; #endif struct sigaction new_action; int dummy=0,i=0; unsigned char user[256]; struct passwd *username; char splashpath[1024]; unsigned int dump = 0; unsigned int keysonly = 0; FILE *config; unsigned int convert = 0; memset(configDir,0,sizeof(configDir)); strncpy(configDir,getenv("HOME"),1024); strncat(configDir,"/.g15macro/",1024-strlen(configDir)); strncpy(configpath,getenv("HOME"),1024); memset(user,0,256); for(i=0;i<argc;i++){ if (!strncmp(argv[i], "-u",2) || !strncmp(argv[i], "--user",6)) { if(argv[i+1]!=NULL){ strncpy((char*)user,argv[i+1],128); i++; } } if (!strncmp(argv[i], "-d",2) || !strncmp(argv[i], "--dump",6)) { dump = 1; } if (!strncmp(argv[i], "-h",2) || !strncmp(argv[i], "--help",6)) { helptext(); exit(0); } if (!strncmp(argv[i], "-k",2) || !strncmp(argv[i], "--keysonly",10)) { keysonly = 1; } if (!strncmp(argv[i], "-g",2) || !strncmp(argv[i], "--debug",7)) { printf("Debugging Enabled\n"); debug = 1; } if (!strncmp(argv[i], "-v",2) || !strncmp(argv[i], "--version",9)) { printf("G15Macro version %s\n\n",PACKAGE_VERSION); exit(0); } if (!strncmp(argv[i], "-2",2) || !strncmp(argv[i], "--g15version2",13)) { G15Version = 1; // See declaration for info } } if(strlen((char*)user)){ username = getpwnam((char*)user); if (username==NULL) { username = getpwuid(geteuid()); printf("BEWARE: running as effective uid %i\n",username->pw_uid); } else { if(0==setuid(username->pw_uid)) { setgid(username->pw_gid); strncpy(configpath,username->pw_dir,1024); strncpy(configDir,username->pw_dir,1024); printf("running as user %s\n",username->pw_name); } else printf("Unable to run as user \"%s\" - you dont have permissions for that.\nRunning as \"%s\"\n",username->pw_name,getenv("USER")); } printf("BEWARE: this program will run files WITHOUT dropping any kind of privilegies.\n"); } canvas = (g15canvas *) malloc (sizeof (g15canvas)); if (canvas != NULL) { g15r_initCanvas(canvas); } else { printf("Unable to initialise the libg15render canvas\nExiting\n"); return 1; } do { dpy = XOpenDisplay(getenv("DISPLAY")); if (!dpy) { printf("Unable to open display %s - retrying\n",getenv("DISPLAY")); sleep(2); } }while(!dpy); /* completely ignore errors and carry on */ XSetErrorHandler(myx_error_handler); // Get keycodes for all keys strcpy(GKeyCodeCfg,configDir); strncat(GKeyCodeCfg,"GKeyCodes.cfg",1024-strlen(GKeyCodeCfg)); printf("%s\n",GKeyCodeCfg); getKeyDefs(GKeyCodeCfg); configure_mmediakeys(); change_keymap(0); XFlush(dpy); if(keysonly>0) goto close_and_exit; /* old binary config format */ strncat(configpath,"/.g15macro",1024-strlen(configpath)); strncat(configpath,"/g15macro-data",1024-strlen(configpath)); config_fd = open(configpath,O_RDONLY|O_SYNC); mstates[0] = malloc(sizeof(mstates_t)); mstates[1] = (mstates_t*)malloc(sizeof(mstates_t)); mstates[2] = (mstates_t*)malloc(sizeof(mstates_t)); if(config_fd>0) { printf("Converting old data\n"); read(config_fd,mstates[0],sizeof(mstates_t)); read(config_fd,mstates[1],sizeof(mstates_t)); read(config_fd,mstates[2],sizeof(mstates_t)); close(config_fd); strncpy(configpath,getenv("HOME"),1024); strncat(configpath,"/.g15macro",1024-strlen(configpath)); char configbak[1024]; strcpy(configbak,configpath); strncat(configpath,"/g15macro-data",1024-strlen(configpath)); strncat(configbak,"/g15macro-data.old",1024-strlen(configpath)); rename(configpath,configbak); convert = 1; } else cleanMstates(0); //0 = only NULL the pointers /* new format */ strncpy(configpath,getenv("HOME"),1024); strncat(configpath,"/.g15macro",1024-strlen(configpath)); mkdir(configpath,0777); strncat(configpath,"/g15macro.conf",1024-strlen(configpath)); config=fopen(configpath,"a"); fclose(config); do { if((g15screen_fd = new_g15_screen(G15_G15RBUF))<0){ printf("Sorry, cant connect to the G15daemon - retrying\n"); sleep(2); } }while(g15screen_fd<0); loadMultiConfig(); printf("I've now got the following macro files:\n"); for(i=0; i < MAX_CONFIGS;++i) { if(!configs[i]) continue; printf("%i:%s%s\n",i,configDir,configs[i]->configfile); } if(!convert) { memset(configpath,0,sizeof(configpath)); strcpy(configpath,configDir); strncat(configpath,configs[currConfig]->configfile,1024-strlen(configpath)); restore_config(configpath); } if(dump){ printf("G15Macro Dumping Codes..."); dump_config(stderr); exit(0); } g15_send_cmd (g15screen_fd,G15DAEMON_KEY_HANDLER, dummy); usleep(1000); g15_send_cmd (g15screen_fd,G15DAEMON_MKEYLEDS,mled_state); usleep(1000); root_win = DefaultRootWindow(dpy); if (!root_win) { printf("Cant find root window\n"); return 1; } have_xtest = False; #ifdef HAVE_XTEST #ifdef USE_XTEST have_xtest = XTestQueryExtension(dpy, &dummy, &dummy, &xtest_major_version, &xtest_minor_version); if(have_xtest == False || xtest_major_version < 2 || (xtest_major_version <= 2 && xtest_minor_version < 2)) { printf("Warning: XTEST extension not supported by Xserver. This is not fatal.\nReverting to XSendEvent for keypress emulation\n"); } #else //USE_XTEST printf("XTest disabled by configure option. Using XSendEvent instead.\n"); #endif //USE_XTEST #else //HAVE_XTEST printf("XTest disabled by configure: no devel package was found. Using XSendEvent instead.\n"); #endif //HAVE_XTEST printf("XTest enabled. Using XTest.\n"); new_action.sa_handler = g15macro_sighandler; new_action.sa_flags = 0; sigaction(SIGINT, &new_action, NULL); sigaction(SIGQUIT, &new_action, NULL); sigaction(SIGTERM, &new_action, NULL); sigaction(SIGPIPE, &new_action, NULL); sigaction(SIGHUP, &new_action, NULL); // So that forked processes that die can actually die instead of going defunct. struct sigaction act; memset(&act,0,sizeof(act)); act.sa_handler = &cleanupChildren; sigaction(SIGCHLD,&act,NULL); snprintf((char*)splashpath,1024,"%s/%s",DATADIR,"g15macro/splash/g15macro.wbmp"); g15r_loadWbmpSplash(canvas, splashpath); g15_send(g15screen_fd,(char *)canvas->buffer,G15_BUFFER_LEN); // Following piece of code is not documented (what i could find anyway) // But makes so that the user can never bring this screen to front. // TODO: Document it // #ifdef G15DAEMON_NEVER_SELECT // g15_send_cmd (g15screen_fd, G15DAEMON_NEVER_SELECT, dummy); // #endif usleep(1000); pthread_mutex_init(&x11mutex,NULL); pthread_mutex_init(&config_mutex,NULL); pthread_mutex_init(&gui_select,NULL); pthread_attr_t attr; pthread_attr_init(&attr); int thread_policy=SCHED_FIFO; pthread_attr_setschedpolicy(&attr,thread_policy); pthread_attr_setstacksize(&attr,32*1024); /* set stack to 32k - dont need 8Mb !! */ pthread_create(&Xkeys, &attr, xevent_thread, NULL); pthread_create(&Lkeys, &attr, Lkeys_thread, NULL); mainLoop(); cleanup(); close_and_exit: /* XCloseDisplay(dpy); */ return 0; }
void *Lkeys_thread() { unsigned long keystate = 0; struct pollfd fds; char ver[5]; int foo = 0; float g15v; memset(ver,0x0,sizeof(ver)); strncpy(ver,G15DAEMON_VERSION,3); sscanf(ver,"%f",&g15v); g15macro_log("Using version %.2f as keypress protocol\n",g15v); while(!leaving){ /* g15daemon series 1.2 need key request packets */ if((g15v*10)<=18) { keystate = g15_send_cmd (g15screen_fd, G15DAEMON_GET_KEYSTATE, foo); } else { fds.fd = g15screen_fd; fds.events = POLLIN; fds.revents=0; keystate=0; if ((poll(&fds, 1, 1000)) > 0) { read (g15screen_fd, &keystate, sizeof (keystate)); } } if (keystate!=0) { g15macro_log("Received Keystate == %lu\n",keystate); switch (keystate) { case G15_KEY_L2: { int fg_check = g15_send_cmd (g15screen_fd, G15DAEMON_IS_FOREGROUND, foo); if(!fg_check) break; // Go to default/g15macro.conf = id =0 gui_selectChange(0); break; } case G15_KEY_L3: { int fg_check = g15_send_cmd (g15screen_fd, G15DAEMON_IS_FOREGROUND, foo); if(!fg_check) break; // Scroll up gui_selectChange(-1); break; } case G15_KEY_L4: { int fg_check = g15_send_cmd (g15screen_fd, G15DAEMON_IS_FOREGROUND, foo); if(!fg_check) break; // Scroll down gui_selectChange(+1); break; } case G15_KEY_L5: { int fg_check = g15_send_cmd (g15screen_fd, G15DAEMON_IS_FOREGROUND, foo); if(!fg_check) break; // Change to selected char newConfig[1024]; memset(newConfig,0,sizeof(newConfig)); strcpy(newConfig,configDir); strncat(newConfig,configs[currConfig]->configfile,sizeof(newConfig)-strlen(newConfig)); // Actually not the newConfig, it's the old, but didn't come up with a good name. save_macros(newConfig); // Purge all old data cleanMstates(1); // Now load the new config currConfig = gui_selectConfig; memset(newConfig,0,sizeof(newConfig)); strcpy(newConfig,configDir); strncat(newConfig,configs[currConfig]->configfile,sizeof(newConfig)-strlen(newConfig)); restore_config(newConfig); // Set the configpath to reflect the change memset(configpath,0,sizeof(configpath)); strcpy(configpath,configDir); strncat(configpath,configs[currConfig]->configfile,sizeof(configpath)-strlen(configpath)); gui_oldConfig = MAX_CONFIGS+1; break; } case G15_KEY_MR: { g15macro_log("Key pressed is MR\n"); if(!recording) { if(0==g15_send_cmd (g15screen_fd, G15DAEMON_IS_FOREGROUND, foo)){ usleep(1000); g15_send_cmd (g15screen_fd, G15DAEMON_SWITCH_PRIORITIES, foo); g15macro_log("Switching to LCD foreground\n"); } usleep(1000); g15_send_cmd (g15screen_fd,G15DAEMON_MKEYLEDS, G15_LED_MR | mled_state); g15r_initCanvas (canvas); g15r_renderString (canvas, (unsigned char *)"Recording", 0, G15_TEXT_LARGE, 80-((strlen("Recording")/2)*8), 1); g15_send(g15screen_fd,(char *)canvas->buffer,G15_BUFFER_LEN); g15macro_log("Recording Enabled\n"); recording = 1; pthread_mutex_lock(&x11mutex); XGrabKeyboard(dpy, root_win, True, GrabModeAsync, GrabModeAsync, CurrentTime); pthread_mutex_unlock(&x11mutex); memset(¤t_recording,0,sizeof(current_recording)); } else { record_cancel(); g15_send_cmd (g15screen_fd,G15DAEMON_MKEYLEDS,mled_state); } break; } case G15_KEY_M1: handle_mkey_switch(G15_KEY_M1); g15macro_log("Key pressed is M1\n"); break; case G15_KEY_M2: handle_mkey_switch(G15_KEY_M2); g15macro_log("Key pressed is M2\n"); break; case G15_KEY_M3: handle_mkey_switch(G15_KEY_M3); g15macro_log("Key pressed is M3\n"); break; default: if(keystate >=G15_KEY_G1 && keystate <=G15_KEY_G18){ if(recording==1){ record_complete(keystate); } else { macro_playback(keystate); } } break; } keystate = 0; } } return NULL; }