"Fossies" - the Fresh Open Source Software Archive

Member "alec64-1.13/src/key_x11.c" (21 Jul 1996, 14195 Bytes) of package /linux/misc/old/alec64-1.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  *  The C64 emulator
    3  *
    4  *  Copyright 1992-96 by ALE.
    5  *  written by Lutz Sammer.
    6  *
    7  *  Keyboard emulation for X11.
    8  *  Written by Edgar Törnig
    9  *  R6 Version
   10  *------------------------------------------------------------------------------
   11  * $Id: key_x11.c,v 1.2 1996/07/01 22:12:20 johns Exp root $
   12  * $Log: key_x11.c,v $
   13  * Revision 1.2  1996/07/01 22:12:20  johns
   14  * Added keycodes for older XFree and SERVER_NUM_LOCK. Moved some common
   15  * functions to key.c
   16  *
   17  * Revision 1.1  1996/05/10 20:04:20  froese
   18  * Initial revision
   19  *
   20  *------------------------------------------------------------------------------
   21  */
   22 
   23 #include "c64.h"
   24 #include "vic.h"
   25 #include "sid.h"
   26 
   27 #include <stdio.h>
   28 #include <memory.h>
   29 #include <X11/Xlib.h>
   30 #include <X11/Xutil.h>
   31 #define XK_MISCELLANY
   32 #define XK_LATIN1
   33 #include <X11/keysymdef.h>
   34 
   35 extern Display *display;
   36 extern Atom WM_Delete_Window;
   37 static unsigned char x11keymap[32];
   38 
   39 static void GetLeds(void);
   40 extern void VideoArrange(int,int);
   41 
   42 #define KEY_PRESSED(k)  (x11keymap[(k)>>3]&(1<<((k)&7)))
   43 #define KEY_RELEASED(k) (!KEY_PRESSED(k))
   44 
   45 
   46 static void
   47 C64Key(int pressed, int bit, int mask)
   48 {
   49     int i, j;
   50 
   51     if (bit == 0 || mask == 0)
   52     return;
   53 
   54     if (pressed)
   55     for (j = 0; j < 256; j += bit)
   56         for (i = 0; i < bit; ++i)
   57         KeyMatrix[j++] &= ~mask;
   58     else
   59     for (j = 0; j < 256; j += bit)
   60         for (i = 0; i < bit; ++i)
   61         KeyMatrix[j++] |= mask;
   62 }
   63 
   64 
   65 /*
   66  *      Set/Reset C64 Leftshift key.
   67  */
   68 static
   69 void C64LeftShift(int pressed)
   70 {
   71     C64Key(pressed | KEY_PRESSED(50), 0x02, 0x80);
   72 }
   73 
   74 
   75 static void
   76 MapX11Key(int pressed, int keycode)
   77 {
   78     char buf[256];
   79 
   80     if (pressed)
   81     x11keymap[keycode / 8] |= 1 << (keycode % 8);
   82     else
   83     x11keymap[keycode / 8] &= ~(1 << (keycode % 8));
   84 
   85     switch (keycode)
   86     {
   87     case  49: /* ^ */       C64Key(pressed, 0x80, 0x02);    break;
   88     case  10: /* 1 */       C64Key(pressed, 0x80, 0x01);    break;
   89     case  11: /* 2 */       C64Key(pressed, 0x80, 0x08);    break;
   90     case  12: /* 3 */       C64Key(pressed, 0x02, 0x01);    break;
   91     case  13: /* 4 */       C64Key(pressed, 0x02, 0x08);    break;
   92     case  14: /* 5 */       C64Key(pressed, 0x04, 0x01);    break;
   93     case  15: /* 6 */       C64Key(pressed, 0x04, 0x08);    break;
   94     case  16: /* 7 */       C64Key(pressed, 0x08, 0x01);    break;
   95     case  17: /* 8 */       C64Key(pressed, 0x08, 0x08);    break;
   96     case  18: /* 9 */       C64Key(pressed, 0x10, 0x01);    break;
   97     case  19: /* 0 */       C64Key(pressed, 0x10, 0x08);    break;
   98     case  20: /* ß */       C64Key(pressed, 0x20, 0x01);    break;
   99     case  21: /* ' */       C64Key(pressed, 0x20, 0x08);    break;
  100     case  97: /* home */        C64Key(pressed, 0x40, 0x08);    break;
  101     case  22: /* backspace */   C64Key(pressed, 0x01, 0x01);    break;
  102 
  103     case  23: /* tab */     C64Key(pressed, 0x80, 0x04);    break;
  104     case  24: /* q */       C64Key(pressed, 0x80, 0x40);    break;
  105     case  25: /* w */       C64Key(pressed, 0x02, 0x02);    break;
  106     case  26: /* e */       C64Key(pressed, 0x02, 0x40);    break;
  107     case  27: /* r */       C64Key(pressed, 0x04, 0x02);    break;
  108     case  28: /* t */       C64Key(pressed, 0x04, 0x40);    break;
  109     case  29: /* z */       C64Key(pressed, 0x08, 0x02);    break;
  110     case  30: /* u */       C64Key(pressed, 0x08, 0x40);    break;
  111     case  31: /* i */       C64Key(pressed, 0x10, 0x02);    break;
  112     case  32: /* o */       C64Key(pressed, 0x10, 0x40);    break;
  113     case  33: /* p */       C64Key(pressed, 0x20, 0x02);    break;
  114     case  34: /* ü */       C64Key(pressed, 0x20, 0x40);    break;
  115     case  35: /* + */       C64Key(pressed, 0x40, 0x02);    break;
  116 
  117     case  94: /* < (NOT on 101 keyboards!) */
  118     case 105: /* page-down */   C64Key(pressed, 0x40, 0x40);    break;
  119     case  99: /* page-up */     C64Key(pressed, 0x40, 0x01);    break;
  120 
  121     case  66: /* caps-lock */   C64Key(pressed, 0x80, 0x80);    break;
  122     case  38: /* a */       C64Key(pressed, 0x02, 0x04);    break;
  123     case  39: /* s */       C64Key(pressed, 0x02, 0x20);    break;
  124     case  40: /* d */       C64Key(pressed, 0x04, 0x04);    break;
  125     case  41: /* f */       C64Key(pressed, 0x04, 0x20);    break;
  126     case  42: /* g */       C64Key(pressed, 0x08, 0x04);    break;
  127     case  43: /* h */       C64Key(pressed, 0x08, 0x20);    break;
  128     case  44: /* j */       C64Key(pressed, 0x10, 0x04);    break;
  129     case  45: /* k */       C64Key(pressed, 0x10, 0x20);    break;
  130     case  46: /* l */       C64Key(pressed, 0x20, 0x04);    break;
  131     case  47: /* ö */       C64Key(pressed, 0x20, 0x20);    break;
  132     case  48: /* ä */       C64Key(pressed, 0x40, 0x04);    break;
  133     case  51: /* # */       C64Key(pressed, 0x40, 0x20);    break;
  134     case 108: /* kp-enter */
  135     case  36: /* return */      C64Key(pressed, 0x01, 0x02);    break;
  136 
  137     case  50: /* l-shift */     C64Key(pressed, 0x02, 0x80);    break;
  138     case  52: /* y */       C64Key(pressed, 0x02, 0x10);    break;
  139     case  53: /* x */       C64Key(pressed, 0x04, 0x80);    break;
  140     case  54: /* c */       C64Key(pressed, 0x04, 0x10);    break;
  141     case  55: /* v */       C64Key(pressed, 0x08, 0x80);    break;
  142     case  56: /* b */       C64Key(pressed, 0x08, 0x10);    break;
  143     case  57: /* n */       C64Key(pressed, 0x10, 0x80);    break;
  144     case  58: /* m */       C64Key(pressed, 0x10, 0x10);    break;
  145     case  59: /* , */       C64Key(pressed, 0x20, 0x80);    break;
  146     case  60: /* . */       C64Key(pressed, 0x20, 0x10);    break;
  147     case 112: /* kp-/ */
  148     case  61: /* - */       C64Key(pressed, 0x40, 0x80);    break;
  149     case  62: /* r-shift */     C64Key(pressed, 0x40, 0x10);    break;
  150 
  151     case  65: /* space */       C64Key(pressed, 0x80, 0x10);    break;
  152 
  153     case  37: /* l-control */   C64Key(pressed, 0x80, 0x04);    break;
  154 
  155     case  64: /* l-alt */
  156     case 113: /* r-alt */       C64Key(pressed, 0x80, 0x20);    break;
  157 
  158     case  92: /* alt-sys-req */ if (!pressed) Exit(0);      break;
  159     case 103: /* end */     if (!pressed) Nmi();        break;
  160     case 114: /* ctrl-break */  if (!pressed) Reset();      break;
  161 
  162     case 106: /* insert */
  163         C64LeftShift(pressed);
  164     case 107: /* delete */
  165         C64Key(pressed, 0x01, 0x01);    break;
  166 
  167     case  98: /* up */
  168         C64LeftShift(pressed);
  169     case 104:
  170         C64Key(pressed, 0x01, 0x80);    break;
  171 
  172     case 100: /* left */
  173         C64LeftShift(pressed);
  174     case 102:
  175         C64Key(pressed, 0x01, 0x04);    break;
  176 
  177     case  68: /* f2 */
  178         C64LeftShift(pressed);
  179     case  67: /* f1 */
  180         C64Key(pressed, 0x01, 0x10);    break;
  181 
  182     case  70: /* f4 */
  183         C64LeftShift(pressed);
  184     case  69: /* f3 */
  185         C64Key(pressed, 0x01, 0x20);    break;
  186 
  187     case  72: /* f6 */
  188         C64LeftShift(pressed);
  189     case  71: /* f5 */
  190         C64Key(pressed, 0x01, 0x40);    break;
  191 
  192     case  74: /* f8 */
  193         C64LeftShift(pressed);
  194     case  73: /* f7 */
  195         C64Key(pressed, 0x01, 0x08);    break;
  196 
  197     case  75: /* f9 */
  198         if (!pressed) {
  199             if (KEY_PRESSED(50))
  200             ++VicFetch;
  201             else
  202             --VicFetch;
  203             sprintf(buf,"%d fetch",VicFetch);
  204             VicMessage(buf,FRAMES_PER_SECOND);
  205         }
  206         break;
  207 
  208     case  76: /* f10 */
  209         if (!pressed) {
  210             if (KEY_PRESSED(50))
  211             ++VicFetchAdd;
  212             else
  213             --VicFetchAdd;
  214             sprintf(buf,"%d add",VicFetchAdd);
  215             VicMessage(buf,FRAMES_PER_SECOND);
  216         }
  217         break;
  218 
  219     case  95: /* f11 */
  220         if( !pressed ) {
  221             ToggleSound();
  222             if( SidSoundOff ) {
  223             VicMessage("sound off",FRAMES_PER_SECOND);
  224             } else {
  225             VicMessage("sound on",FRAMES_PER_SECOND);
  226             }
  227         }
  228         break;
  229 
  230     case  96: /* f12 */
  231         if( !pressed )
  232             MonitorOn();
  233         break;
  234 
  235     case 147: /* other X11 */
  236     case  79: /* kp-7 */        /* Joystick Left+Up */
  237         if (!pressed) {
  238         if( KEY_RELEASED(80) )
  239             *JoyStick|=0x1;
  240         if( KEY_RELEASED(83) )
  241             *JoyStick|=0x4;
  242         } else {
  243         *JoyStick&=~0x5;
  244         }
  245         break;
  246     case 148: /* other X11 */
  247     case  80: /* kp-8 */        /* Joystick Up */
  248         if( !pressed ) {
  249         if( KEY_RELEASED(79) && KEY_RELEASED(81) )
  250             *JoyStick|=0x1;
  251         } else {
  252         *JoyStick&=~0x1;
  253         }
  254         break;
  255     case 149: /* other X11 */
  256     case  81: /* kp-9 */        /* Joystick Right+Up */
  257         if( !pressed ) {
  258         if( KEY_RELEASED(80) )
  259             *JoyStick|=0x1;
  260         if( KEY_RELEASED(85) )
  261             *JoyStick|=0x8;
  262         } else {
  263         *JoyStick&=~0x9;
  264         }
  265         break;
  266     case 150: /* other X11 */
  267     case  83: /* kp-4 */        /* Joystick Left */
  268         if( !pressed ) {
  269         if( KEY_RELEASED(79) && KEY_RELEASED(87) )
  270             *JoyStick|=0x4;
  271         } else {
  272         *JoyStick&=~0x4;
  273         }
  274         break;
  275     case 152: /* other X11 */
  276     case  85: /* kp-6 */        /* Joystick Right */
  277         if( !pressed ) {
  278         if( KEY_RELEASED(81) && KEY_RELEASED(89) )
  279             *JoyStick|=0x8;
  280         } else {
  281         *JoyStick&=~0x8;
  282         }
  283         break;
  284     case 153: /* other X11 */
  285     case  87: /* kp-1 */        /* Joystick Left+Down */
  286         if( !pressed ) {
  287         if( KEY_RELEASED(83) )
  288             *JoyStick|=0x4;
  289         if( KEY_RELEASED(88) )
  290             *JoyStick|=0x2;
  291         } else {
  292         *JoyStick&=~0x6;
  293         }
  294         break;
  295     case 154: /* other X11 */
  296     case  88: /* kp-2 */        /* Joystick Down */
  297         if( !pressed ) {
  298         if( KEY_RELEASED(87) && KEY_RELEASED(89) )
  299             *JoyStick|=0x2;
  300         } else {
  301         *JoyStick&=~0x2;
  302         }
  303         break;
  304     case 155: /* other X11 */
  305     case  89: /* kp-3 */        /* Joystick Right+Down */
  306         if( !pressed ) {
  307         if( KEY_RELEASED(85) )
  308             *JoyStick|=0x8;
  309         if( KEY_RELEASED(88) )
  310             *JoyStick|=0x2;
  311         } else {
  312         *JoyStick&=~0xA;
  313         }
  314         break;
  315     case 109: /* r-control */
  316     case   9: /* Escape */
  317     case 151: /* other X11 */
  318     case  84: /* kp-5 */        /* Joystick Fire */
  319         if( !pressed ) {
  320         *JoyStick|=0x10;
  321         } else {
  322         *JoyStick&=~0x10;
  323         }
  324         break;
  325     case  77: /* num-lock */    /* Joystick emulation toggle */
  326 #ifdef XSERVER_NUM_LOCK
  327         if( !pressed ) {        /* generate normal up/down */
  328         if( JoyStick==&JoyStick2 ) {
  329             JoyStick=&JoyStick1, OtherJoyStick=&JoyStick2;
  330             VicMessage("Joystick 1",FRAMES_PER_SECOND);
  331         } else {
  332             JoyStick=&JoyStick2, OtherJoyStick=&JoyStick1;
  333             VicMessage("Joystick 2",FRAMES_PER_SECOND);
  334         }
  335         }
  336 #else
  337         if (pressed) {      /* XF86 gen. down/up depending on led */
  338         JoyStick = &JoyStick2, OtherJoyStick = &JoyStick1;
  339         VicMessage("Joystick 2",FRAMES_PER_SECOND);
  340         } else {
  341         JoyStick = &JoyStick1, OtherJoyStick = &JoyStick2;
  342         VicMessage("Joystick 1",FRAMES_PER_SECOND);
  343         }
  344 #endif
  345         JoyStick2 = JoyStick1 = 0xFF;
  346         ShowLeds(0100);
  347         break;
  348 
  349     case 111: /* druck */       /* Autofire on/off toggle */
  350         if( !pressed ) {
  351         AutoFire^=1;
  352         if( !AutoFire ) {
  353             if( KEY_PRESSED(9) )
  354             *JoyStick|=0x10;
  355             VicMessage("Autofire off",FRAMES_PER_SECOND);
  356         } else {
  357             VicMessage("Autofire on",FRAMES_PER_SECOND);
  358         }
  359         ShowLeds(0010);
  360         }
  361         break;
  362 
  363     case  78: /* scroll-lock */
  364         if( !pressed ) {
  365         if( KEY_PRESSED(50) ) {
  366             VicEmulateRate=(VicEmulateRate&3)+1;
  367             sprintf(buf,"1/%d emulate",VicEmulateRate);
  368             VicMessage(buf,FRAMES_PER_SECOND);
  369             ShowLeds(0001);
  370         } else {
  371             VicRefreshRate=(VicRefreshRate&3)+1;
  372             sprintf(buf,"1/%d updates",VicRefreshRate);
  373             VicMessage(buf,FRAMES_PER_SECOND);
  374             ShowLeds(0001);
  375         }
  376         }
  377         break;
  378 
  379     case  63: /* kp-* */    HandleKey(pressed,KEY_FASTLOADER_TOGGLE);break;
  380     case  86: /* kp-+ */    HandleKey(pressed,KEY_NEXT_DISC);   break;
  381     case  82: /* kp-- */    HandleKey(pressed,KEY_PREV_DISC);   break;
  382 
  383     case  90: /* kp-0 */        C64Key(pressed, 0x00, 0x00);    break;
  384     case  91: /* kp-, */        C64Key(pressed, 0x00, 0x00);    break;
  385     case 110: /* pause */       C64Key(pressed, 0x00, 0x00);    break;
  386 
  387     case  93: /* ??? */     C64Key(pressed, 0x00, 0x00);    break;
  388     case 101: /* ??? */     C64Key(pressed, 0x00, 0x00);    break;
  389     default: break;
  390     }
  391 }
  392 
  393 /*
  394  * Resync the matrix with the current X11 keymap
  395  */
  396 static void
  397 RebuildMatrix()
  398 {
  399     int i;
  400 
  401     memset(KeyMatrix, 0xFF, sizeof(KeyMatrix));
  402 
  403     for (i = 0; i < 256; ++i)
  404     if (x11keymap[i / 8] & (1 << (i % 8)))
  405         MapX11Key(1, i);
  406 }
  407 
  408 
  409 
  410 void
  411 EnterKey(void)
  412 {
  413     GetLeds();
  414 }
  415 
  416 void
  417 LeaveKey(void)
  418 {
  419     if( display ) {
  420 #ifdef XREPEATOFF
  421     XAutoRepeatOn(display);     /* restore autorepeat */
  422 #endif
  423     ShowLeds(0000);         /* all leds off */
  424     }
  425 }
  426 
  427 /*
  428  *      Look for keyboard events.
  429  *
  430  *      Translate system keyboard events -> c64 keyboard matrix
  431  *
  432  *      Called with 50hz/60hz in video blank.
  433  */
  434 void EmulKeyboard(void)
  435 {
  436     XEvent ev;
  437     int n;
  438 
  439 #if 0
  440     // n = XEventsQueued(display, QueuedAfterReading);
  441     n = XEventsQueued(display, QueuedAfterFlush);
  442     if( n )
  443     printf("Events %d\n",n);
  444     for (; n; --n)
  445 #else
  446     for (n = XEventsQueued(display, QueuedAfterReading); n; --n)
  447 #endif
  448     {
  449     XNextEvent(display, &ev);
  450 
  451     switch (ev.xany.type)
  452     {
  453         case KeyPress:
  454         case KeyRelease:
  455         MapX11Key(ev.xkey.type == KeyPress, ev.xkey.keycode);
  456         break;
  457         case FocusIn:
  458 #ifdef XREPEATOFF
  459         XAutoRepeatOff(display);
  460 #endif
  461         memset(x11keymap, 0, sizeof(x11keymap));
  462         RebuildMatrix();
  463         break;
  464         case FocusOut:
  465 #ifdef XREPEATOFF
  466         XAutoRepeatOn(display);
  467 #endif
  468         memset(x11keymap, 0, sizeof(x11keymap));
  469         RebuildMatrix();
  470         break;
  471         case KeymapNotify:
  472         memcpy(x11keymap, ev.xkeymap.key_vector, sizeof(x11keymap));
  473         RebuildMatrix();
  474         break;
  475         case Expose:
  476         VicDrawOverscan=1;
  477         break;
  478         case ConfigureNotify:
  479         VideoArrange(ev.xconfigure.width,ev.xconfigure.height);
  480         break;
  481         case ClientMessage:
  482         if (ev.xclient.format != 32 || ev.xclient.data.l[0] != WM_Delete_Window)
  483             break;
  484         Exit(0);
  485         break;
  486         default:
  487         break;
  488     }
  489     }
  490 
  491     /*
  492     **  Autofire on and ESCAPE pressed toggles fire button
  493     */
  494     if( AutoFire && (KEY_PRESSED(9) || KEY_PRESSED(109)) ) {
  495     *JoyStick^=0x10;
  496     }
  497 }
  498 
  499 /*
  500 **  Suspend keyboard.
  501 */
  502 void SuspendKeyboard(void)
  503 {
  504 #ifdef XREPEATOFF
  505     XAutoRepeatOn(display);
  506     XFlush(display);
  507 #endif
  508 }
  509 
  510 /*
  511 **  Resume keyboard.
  512 */
  513 void ResumeKeyboard(void)
  514 {
  515 }
  516 
  517 void
  518 ShowLeds(int flags)
  519 {
  520     XKeyboardControl kbctrl;
  521 
  522     if (flags == 0000) {
  523     kbctrl.led_mode = LedModeOff;
  524     XChangeKeyboardControl(display, KBLedMode, &kbctrl);
  525     return;
  526     }
  527 
  528     if (flags & 0100) {
  529     kbctrl.led = 2; /* num-lock led */
  530     kbctrl.led_mode = (JoyStick == &JoyStick2) ? LedModeOn : LedModeOff;
  531     XChangeKeyboardControl(display, KBLed | KBLedMode, &kbctrl);
  532     }
  533 
  534     if (flags & 0010) {
  535     kbctrl.led = 1; /* caps-lock led */
  536     kbctrl.led_mode = AutoFire ? LedModeOn : LedModeOff;
  537     XChangeKeyboardControl(display, KBLed | KBLedMode, &kbctrl);
  538     }
  539 
  540     if (flags & 0001) {
  541     kbctrl.led = 3; /* scroll-lock led */
  542     kbctrl.led_mode = (VicRefreshRate==1) ? LedModeOn : LedModeOff;
  543     XChangeKeyboardControl(display, KBLed | KBLedMode, &kbctrl);
  544     }
  545 }
  546 
  547 
  548 
  549 static void
  550 GetLeds(void)
  551 {
  552     XKeyboardState kbstate;
  553 
  554 #ifndef XSERVER_NUM_LOCK
  555     /* get num-lock state */
  556 
  557     if( !JoystickGiven ) {  /* commandline overwrites setting */
  558     XGetKeyboardControl(display, &kbstate);
  559 
  560     if (kbstate.led_mask & 2)
  561         JoyStick = &JoyStick2, OtherJoyStick = &JoyStick1;
  562     else
  563         JoyStick = &JoyStick1, OtherJoyStick = &JoyStick2;
  564 
  565     }
  566 #endif
  567     JoyStick2=JoyStick1=0xFF;
  568 
  569     ShowLeds(0111);
  570 }