User:Paolo Liberatore/Xf1shift.c

From Wikipedia, the free encyclopedia

/*
  This is an X Window program that adds or removes F1 as a new
  shift modifier. It illustrates how the modifier map can be
  changed by a client. By executing
        xf1shift +f1
  the F1 key on a PC keyboard will be interpreted by the
  server as a third shift modifier. This effect can be
  reversed by:
        xf1shift -f1
  
  A modifier is a key that changes the interpretation of other
  keys when kept pressing. The most common modifier is the
  "Shift" key: the key that normally produce a lowercase "a"
  produces an uppercase "A" when the Shift key is pressed.
  Other common modifiers are "Control", "Alt", and "Meta".
  
  The X server works with at most eight modifiers. However,
  every modifier can be associated with more than one key. For
  example, many keyboards have two "Shift" keys (one on the
  left and one on the right). These two key produce two
  different keycodes when pressed. However, for the X server
  there is only a single "Shift" modifier, and the two keys
  are both associated with this modifier.
  
  For each of the eight modifiers, the X server maintains a
  list of the keycodes that it consider to be that modifier.
  As an example, if the list of the first modifier (the
  "Shift" modifier) contains the keycode 0x37,
  then the key that produces the keycode 0x37 is
  taken to be a shift key by the X server.
*/

#include<X11/Xlib.h>
#include<X11/keysym.h>

void usage() {
  printf("Usage:\n\txf1shift [+f1] [-f1]\n");
  printf("Adds F1 as a shift key on a PC keyboard\n");
}

/* print the modifier mapping table */

void printModifierMapping(XModifierKeymap *mmap) {
  int i, j;
  int m;

  m=mmap->max_keypermod;
  for(i=0; i<8; i++) {
    printf("Modifier %d: ", i);
    for(j=0; j<m; j++)
      if(mmap->modifiermap[i*m+j]!=0)
        printf("0x%02x ", mmap->modifiermap[i*m+j]);
    printf("\n");
  }
}

int main(int argn, char *argv[]) {
  Display *d;
  XModifierKeymap *mmap, *new;
  int add;
  KeyCode f1;

                        /* get arguments */
  if(argn-1<=0) {
    usage();
    exit(1);
  }
  if(!strcmp(argv[1],"+f1"))
    add=1;
  else if(!strcmp(argv[1],"-f1"))
    add=0;
  else {
    usage();
    exit(1);
  }


                       /* open connection with the server */
  d=XOpenDisplay(NULL);
  if(d==NULL) {
    printf("Cannot open display\n");
    exit(1);
  }

                        /* get keycode of the F1 key */
  f1=XKeysymToKeycode(d, XK_F1);
  printf("Keycode of f1=0x%02X\n", f1);
  if(f1==0) {
    printf("No keycode is associated to F1, change not done\n");
    exit(1);
  }

                        /* get modifier mapping */
  mmap=XGetModifierMapping(d);
  printf("Current modifier mapping:\n");
  printModifierMapping(mmap);

                        /* create or delete F1 as a shift modifier */
  if(add)
    new=XInsertModifiermapEntry(mmap, f1, 0);
  else
    new=XDeleteModifiermapEntry(mmap, f1, 0);

                        /* print and set the modifier with the server */
  printf("\nNew modifier mapping:\n");
  printModifierMapping(new);
  XSetModifierMapping(d, new);


                        /* free modifier and close connection */
  XFreeModifiermap(mmap);
  XCloseDisplay(d);

  return 0;
}