Esempio n. 1
0
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;
}
Esempio n. 2
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]);
}
Esempio n. 3
0
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, &current_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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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(&current_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;
}