// Find the proper usb device and initialize it // MODULE_EXPORT int g15_init (Driver *drvthis) { PrivateData *p; /* Allocate and store private data */ p = (PrivateData *) calloc(1, sizeof(PrivateData)); if (p == NULL) return -1; if (drvthis->store_private_ptr(drvthis, p)) return -1; /* Initialize the PrivateData structure */ p->width = G15_CHAR_WIDTH; p->height = G15_CHAR_HEIGHT; p->cellwidth = G15_CELL_WIDTH; p->cellheight = G15_CELL_HEIGHT; p->backlight_state = BACKLIGHT_ON; p->g15screen_fd = 0; p->g15d_ver = g15daemon_version(); if((p->g15screen_fd = new_g15_screen(G15_G15RBUF)) < 0) { report(RPT_ERR, "%s: Sorry, cant connect to the G15daemon", drvthis->name); return -1; } /* make sure the canvas is there... */ p->canvas = (g15canvas *) malloc(sizeof(g15canvas)); if (p->canvas == NULL) { report(RPT_ERR, "%s: unable to create canvas", drvthis->name); return -1; } /* make sure the backingstore is there... */ p->backingstore = (g15canvas *) malloc(sizeof(g15canvas)); if (p->backingstore == NULL) { report(RPT_ERR, "%s: unable to create framebuffer backing store", drvthis->name); return -1; } g15r_initCanvas(p->canvas); g15r_initCanvas(p->backingstore); p->canvas->buffer[0] = G15_LCD_WRITE_CMD; p->backingstore->buffer[0] = G15_LCD_WRITE_CMD; // ret = setLCDBrightness(G15_BRIGHTNESS_BRIGHT); return 0; }
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; }