Annotation of uae/xwin.c, revision 1.1.1.2

1.1       root        1:  /* 
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   * 
                      4:   * X interface
                      5:   * 
                      6:   * Copyright 1995, 1996 Bernd Schmidt
1.1.1.2 ! root        7:   * Copyright 1996 Ed Hanway, Andre Beck, Samuel Devulder, Bruno Coste
1.1       root        8:   */
                      9: 
1.1.1.2 ! root       10: #include "sysconfig.h"
        !            11: #include "sysdeps.h"
        !            12: 
1.1       root       13: #include <X11/Xlib.h>
                     14: #include <X11/Xutil.h>
                     15: #include <X11/keysym.h>
                     16: #include <X11/cursorfont.h>
                     17: 
                     18: #ifndef DONT_WANT_SHM
                     19: #include <sys/ipc.h>
                     20: #include <sys/shm.h>
                     21: #include <X11/extensions/XShm.h>
                     22: #endif
                     23: 
                     24: #include "config.h"
                     25: #include "options.h"
                     26: #include "memory.h"
                     27: #include "custom.h"
                     28: #include "newcpu.h"
                     29: #include "xwin.h"
                     30: #include "keyboard.h"
                     31: #include "keybuf.h"
1.1.1.2 ! root       32: #include "gui.h"
1.1       root       33: 
                     34: static Display *display;
                     35: static int screen;
                     36: static Window rootwin, mywin;
                     37: 
                     38: static GC whitegc,blackgc;
                     39: static XColor black,white;
                     40: static Colormap cmap;
                     41: 
                     42: static XImage *img;
                     43: static Visual *vis;
                     44: static XVisualInfo visualInfo;
                     45: static int bitdepth;
                     46: #ifndef DONT_WANT_SHM
                     47: static XShmSegmentInfo shminfo;
                     48: #endif
                     49: static Cursor blankCursor, xhairCursor;
1.1.1.2 ! root       50: static int cursorOn;
        !            51: 
        !            52: xcolnr xcolors[4096];
1.1       root       53: 
                     54:  /* Keyboard and mouse */
                     55: 
1.1.1.2 ! root       56: static int keystate[256];
1.1       root       57: 
1.1.1.2 ! root       58: int buttonstate[3];
1.1       root       59: int lastmx, lastmy;
1.1.1.2 ! root       60: int newmousecounters;
        !            61: 
        !            62: static int inwindow;
1.1       root       63: const long int eventmask = (KeyPressMask|KeyReleaseMask|ButtonPressMask
                     64:                            |ButtonReleaseMask|PointerMotionMask
                     65:                            |FocusChangeMask|EnterWindowMask
1.1.1.2 ! root       66:                            |ExposureMask
1.1       root       67:                            |LeaveWindowMask);
                     68: 
1.1.1.2 ! root       69: static int vsize, hsize, hpixels;
        !            70: static char *oldpixbuf;
        !            71: 
        !            72: struct vidbuf_description gfxvidinfo;
1.1       root       73: 
1.1.1.2 ! root       74: void flush_line(int y)
1.1       root       75: {
1.1.1.2 ! root       76:     int xs = 0, xe = hsize - 1;
        !            77:     int len;
        !            78:     char *linebuf = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
        !            79:     
        !            80: #ifndef LOW_BANDWIDTH
        !            81:     fprintf(stderr, "Bug!\n");
1.1       root       82: #endif
1.1.1.2 ! root       83:        
        !            84:     switch(bitdepth) {
        !            85:      case 24: case 32:
        !            86:        {
        !            87:            int *newp = (int *)linebuf;
        !            88:            int *oldp = (int *)(oldpixbuf + y*gfxvidinfo.rowbytes);
        !            89:            while (newp[xs] == oldp[xs]) {
        !            90:                if (xs == xe)
        !            91:                    return;
        !            92:                xs++;
        !            93:            }
        !            94:            while (newp[xe] == oldp[xe]) xe--;
1.1       root       95: 
1.1.1.2 ! root       96:            memcpy (oldp + xs, newp + xs, 4 * (xe - xs + 1));                      
        !            97:        }
        !            98:        break;
        !            99:      case 16: case 12:
        !           100:        {
        !           101:            short *newp = (short *)linebuf;
        !           102:            short *oldp = (short *)(oldpixbuf + y*gfxvidinfo.rowbytes);
        !           103:            while (newp[xs] == oldp[xs]) {
        !           104:                if (xs == xe)
        !           105:                    return;
        !           106:                xs++;
        !           107:            }
        !           108:            while (newp[xe] == oldp[xe]) xe--;
        !           109: 
        !           110:            memcpy (oldp + xs, newp + xs, 2 * (xe - xs + 1));
        !           111:        }
        !           112:        break;
        !           113:      case 8:
        !           114:        {
        !           115:            char *newp = (char *)linebuf;
        !           116:            char *oldp = (char *)(oldpixbuf + y*gfxvidinfo.rowbytes);
        !           117:            while (newp[xs] == oldp[xs]) {
        !           118:                if (xs == xe)
        !           119:                    return;
        !           120:                xs++;
        !           121:            }
        !           122:            while (newp[xe] == oldp[xe]) xe--;
        !           123: 
        !           124:            memcpy (oldp + xs, newp + xs, 1 * (xe - xs + 1));
        !           125:        }
        !           126:        break;
        !           127:     }
        !           128: 
        !           129:     len = xe - xs + 1;
1.1       root      130:     
                    131: #ifdef DONT_WANT_SHM
1.1.1.2 ! root      132:     XPutImage(display, mywin, blackgc, img, xs, y, xs, y, len, 1);
1.1       root      133: #else
1.1.1.2 ! root      134:     XShmPutImage(display, mywin, blackgc, img, xs, y, xs, y, len, 1, 0);
1.1       root      135: #endif
                    136: }
                    137: 
1.1.1.2 ! root      138: void flush_block (int ystart, int ystop)
1.1       root      139: {
1.1.1.2 ! root      140:     int len, xs;
        !           141:     if (use_lores) {
        !           142:        len = 320;
        !           143:        xs = prev_max_diwstop - 328;
        !           144:     } else {
        !           145:        len = hpixels;
        !           146:        xs = 0;
        !           147:     }
1.1       root      148: #ifdef DONT_WANT_SHM
1.1.1.2 ! root      149:     XPutImage(display, mywin, blackgc, img, xs, ystart, 0, ystart, len, 
        !           150:              ystop - ystart + 1);
1.1       root      151: #else
1.1.1.2 ! root      152:     XShmPutImage(display, mywin, blackgc, img, xs, ystart, 0, ystart, len,
        !           153:                 ystop - ystart + 1, 0);
1.1       root      154: #endif
                    155: }
                    156: 
1.1.1.2 ! root      157: void flush_screen (int ystart, int ystop)
1.1       root      158: {
1.1.1.2 ! root      159: #ifndef DONT_WANT_SHM
        !           160:     XSync(display, 0);
1.1       root      161: #endif
                    162: }
                    163: 
                    164: #ifndef DONT_WANT_SHM
                    165: static void initShm(int depth)
                    166: {
                    167:     img = XShmCreateImage(display, vis, depth,
1.1.1.2 ! root      168:                          ZPixmap, 0, &shminfo, hsize, vsize);
1.1       root      169:     
1.1.1.2 ! root      170:     shminfo.shmid = shmget(IPC_PRIVATE, vsize * img->bytes_per_line,
        !           171:                           IPC_CREAT | 0777);
1.1       root      172:     shminfo.shmaddr = img->data = (char *)shmat(shminfo.shmid, 0, 0);
                    173:     shminfo.readOnly = False;
                    174:     /* let the xserver attach */
                    175:     XShmAttach(display, &shminfo);
                    176:     /* NOW ! */
                    177:     XSync(display,0);
                    178:     /* now deleting means making it temporary */
                    179:     shmctl(shminfo.shmid, IPC_RMID, 0);
                    180:     
1.1.1.2 ! root      181:     gfxvidinfo.bufmem = img->data;
        !           182:     gfxvidinfo.rowbytes = img->bytes_per_line;
1.1       root      183: }
                    184: #endif
                    185: 
                    186: static __inline__ int bitsInMask(unsigned long mask)
                    187: {
                    188:     /* count bits in mask */
                    189:     int n = 0;
                    190:     while(mask) {
                    191:        n += mask&1;
                    192:        mask >>= 1;
                    193:     }
                    194:     return n;
                    195: }
                    196: 
                    197: static __inline__ int maskShift(unsigned long mask)
                    198: {
                    199:     /* determine how far mask is shifted */
                    200:     int n = 0;
                    201:     while(!(mask&1)) {
                    202:        n++;
                    203:        mask >>= 1;
                    204:     }
                    205:     return n;
                    206: }
                    207: 
1.1.1.2 ! root      208: static int get_color(int r, int g, int b, xcolnr *cnp)
1.1       root      209: {
1.1.1.2 ! root      210:     XColor col;
        !           211:     char str[10];
        !           212:     sprintf(str, "rgb:%x/%x/%x", r, g, b);
        !           213:     XParseColor(display, cmap, str, &col);
        !           214:     if (XAllocColor(display, cmap, &col)) {
        !           215:        *cnp = col.pixel;
        !           216:        return 1;
        !           217:     }
        !           218:     return 0;
1.1       root      219: }
                    220: 
1.1.1.2 ! root      221: static int init_colors(void)
1.1       root      222: {
1.1.1.2 ! root      223:     if (visualInfo.depth != 8 && visualInfo.depth != 12 
        !           224:        && visualInfo.depth != 16 && visualInfo.depth != 24) {
1.1       root      225:        fprintf(stderr, "Unsupported bit depth (%d)\n", visualInfo.depth);
1.1.1.2 ! root      226:        return 0;
1.1       root      227:     }
                    228:     
                    229: #ifdef __cplusplus
1.1.1.2 ! root      230:     switch(visualInfo.c_class) 
1.1       root      231: #else
1.1.1.2 ! root      232:     switch(visualInfo.class) 
1.1       root      233: #endif
1.1.1.2 ! root      234:     {
1.1       root      235:      case TrueColor: 
                    236:        {           
                    237:            int red_bits = bitsInMask(visualInfo.red_mask);
                    238:            int green_bits = bitsInMask(visualInfo.green_mask);
                    239:            int blue_bits = bitsInMask(visualInfo.blue_mask);
                    240:            int red_shift = maskShift(visualInfo.red_mask);
                    241:            int green_shift = maskShift(visualInfo.green_mask);
                    242:            int blue_shift = maskShift(visualInfo.blue_mask);
1.1.1.2 ! root      243:            alloc_colors64k(red_bits, green_bits, blue_bits, red_shift, 
        !           244:                            green_shift, blue_shift);
1.1       root      245:        }
                    246:        break;
                    247: 
                    248:      case GrayScale:
                    249:      case PseudoColor:
1.1.1.2 ! root      250:        alloc_colors256(get_color);
1.1       root      251:        break;
                    252:        
                    253:      default:
                    254: #ifdef __cplusplus
1.1.1.2 ! root      255:        fprintf(stderr, "Unsupported visual class (%d)\n", visualInfo.c_class);
1.1       root      256: #else
1.1.1.2 ! root      257:        fprintf(stderr, "Unsupported visual class (%d)\n", visualInfo.class);
1.1       root      258: #endif
1.1.1.2 ! root      259:        return 0;
1.1       root      260:     }
1.1.1.2 ! root      261:     return 1;
1.1       root      262: }
                    263: 
1.1.1.2 ! root      264: int graphics_init(void)
1.1       root      265: {
                    266:     int i;
                    267:     char *display_name = 0;
                    268:     XSetWindowAttributes wattr;
                    269: 
1.1.1.2 ! root      270:     if (screen_res < 3) {
        !           271: #ifdef LOW_BANDWIDTH
        !           272:        fprintf(stderr, "Low resolution mode not supported with LOW_BANDWIDTH.\n");
        !           273:        return 0;
        !           274: #else
        !           275:        fprintf(stderr, "Low resolution mode selected. Forcing 320x300.\n");
        !           276: #endif
        !           277:     }
        !           278:     
1.1       root      279:     display = XOpenDisplay(display_name);
                    280:     if (display == 0)  {
                    281:        fprintf(stderr, "Can't connect to X server %s\n", XDisplayName(display_name));
1.1.1.2 ! root      282:        return 0;
1.1       root      283:     }
                    284:     screen = XDefaultScreen(display);
                    285:     rootwin = XRootWindow(display,screen);
1.1.1.2 ! root      286:     
1.1       root      287:     /* try for a 12 bit visual first, then a 16 bit, then a 24 bit, then 8 bit */
                    288:     if (XMatchVisualInfo(display, screen, 12, TrueColor, &visualInfo)) {
                    289:     } else if (XMatchVisualInfo(display, screen, 16, TrueColor, &visualInfo)) {
                    290:     } else if (XMatchVisualInfo(display, screen, 24, TrueColor, &visualInfo)) {
                    291:     } else if (XMatchVisualInfo(display, screen, 8, PseudoColor, &visualInfo)) {
1.1.1.2 ! root      292:        /* for our HP boxes */
1.1       root      293:     } else if (XMatchVisualInfo(display, screen, 8, GrayScale, &visualInfo)) {
                    294:     } else {
                    295:        fprintf(stderr, "Can't obtain appropriate X visual\n");
1.1.1.2 ! root      296:        return 0;
1.1       root      297:     }
                    298: 
                    299:     vis = visualInfo.visual;
                    300:     bitdepth = visualInfo.depth;
                    301: 
1.1.1.2 ! root      302:     gfxvidinfo.pixbytes = (bitdepth == 24 || bitdepth == 32 ? 4
        !           303:                           : bitdepth == 12 || bitdepth == 16 ? 2
        !           304:                           : 1);
        !           305:     vsize = dont_want_aspect ? numscrlines : 2*numscrlines;
        !           306:     hsize = use_lores ? 400 : 800;
        !           307:     hpixels = use_lores ? 320 : 796;
1.1       root      308:     fprintf(stderr, "Using %d bit visual\n", bitdepth);
                    309: 
                    310:     cmap = XCreateColormap(display, rootwin, vis, AllocNone);
                    311:     XParseColor(display, cmap, "#000000", &black);
                    312:     if (!XAllocColor(display, cmap, &black))
                    313:        fprintf(stderr, "Whoops??\n");
                    314:     XParseColor(display, cmap, "#ffffff", &white);
                    315:     if (!XAllocColor(display, cmap, &white))
                    316:        fprintf(stderr, "Whoops??\n");
                    317: 
                    318:     wattr.event_mask = eventmask;
                    319:     wattr.background_pixel = black.pixel;
                    320:     wattr.backing_store = Always;
                    321:     wattr.backing_planes = bitdepth;
                    322:     wattr.border_pixmap = None;
                    323:     wattr.border_pixel = black.pixel;
                    324:     wattr.colormap = cmap;
                    325: 
1.1.1.2 ! root      326:     mywin = XCreateWindow(display, rootwin, 0, 0, hpixels, vsize, 0,
1.1       root      327:                          bitdepth, InputOutput, vis,
                    328:                          CWEventMask|CWBackPixel|CWBorderPixel|CWBackingStore
                    329:                          |CWBackingPlanes|CWColormap,
                    330:                          &wattr);
                    331:     XMapWindow(display,mywin);
1.1.1.2 ! root      332:     XStoreName(display, mywin, "UAE");
1.1       root      333:     
                    334:     blankCursor = XCreatePixmapCursor(display,
                    335:                                      XCreatePixmap(display, mywin, 1, 1, 1),
                    336:                                      XCreatePixmap(display, mywin, 1, 1, 1), 
                    337:                                      &black, &white, 0, 0);
                    338:     xhairCursor = XCreateFontCursor(display, XC_crosshair);
                    339: 
                    340:     whitegc = XCreateGC(display,mywin,0,0);
                    341:     blackgc = XCreateGC(display,mywin,0,0);
                    342:     
                    343:     XSetForeground(display,blackgc,black.pixel);
                    344:     XSetForeground(display,whitegc,white.pixel);
                    345: 
                    346: #ifdef DONT_WANT_SHM
1.1.1.2 ! root      347:     gfxvidinfo.rowbytes = hsize * gfxvidinfo.pixbytes;
        !           348:     gfxvidinfo.bufmem = (char *)malloc(gfxvidinfo.rowbytes * vsize);
        !           349:     img = XCreateImage(display, vis, bitdepth, ZPixmap, 0, gfxvidinfo.bufmem, 
        !           350:                       hsize, vsize, 32, 0);
1.1       root      351: #else
                    352:     initShm (bitdepth);
                    353: #endif
1.1.1.2 ! root      354: #ifdef LOW_BANDWIDTH
        !           355:     gfxvidinfo.maxblocklines = 0;
        !           356:     oldpixbuf = (char *)malloc(gfxvidinfo.rowbytes * vsize);
        !           357: #else
        !           358:     gfxvidinfo.maxblocklines = 100; /* whatever... */
        !           359: #endif
        !           360: 
        !           361:     if (!init_colors())
        !           362:        return 0;
        !           363:     
        !           364:     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
        !           365:     for(i=0; i<256; i++)
        !           366:        keystate[i] = 0;
1.1       root      367:     
1.1.1.2 ! root      368:     lastmx = lastmy = 0; 
        !           369:     newmousecounters = 0;
        !           370:     inwindow = 0;
        !           371:     
        !           372:     if (use_xhair)
1.1       root      373:        XDefineCursor(display, mywin, xhairCursor);
1.1.1.2 ! root      374:     else
        !           375:        XDefineCursor(display, mywin, blankCursor);
        !           376:     cursorOn = 1;
        !           377:     return 1;
1.1       root      378: }
                    379: 
                    380: void graphics_leave(void)
                    381: {
                    382:     XAutoRepeatOn(display);
                    383: }
                    384: 
                    385: /* Decode KeySyms. This function knows about all keys that are common 
                    386:  * between different keyboard languages. */
                    387: static int kc_decode (KeySym ks)
                    388: {
                    389:     switch (ks) {      
                    390:      case XK_B: case XK_b: return AK_B;
                    391:      case XK_C: case XK_c: return AK_C;
                    392:      case XK_D: case XK_d: return AK_D;
                    393:      case XK_E: case XK_e: return AK_E;
                    394:      case XK_F: case XK_f: return AK_F;
                    395:      case XK_G: case XK_g: return AK_G;
                    396:      case XK_H: case XK_h: return AK_H;
                    397:      case XK_I: case XK_i: return AK_I;
                    398:      case XK_J: case XK_j: return AK_J;
                    399:      case XK_K: case XK_k: return AK_K;
                    400:      case XK_L: case XK_l: return AK_L;
                    401:      case XK_N: case XK_n: return AK_N;
                    402:      case XK_O: case XK_o: return AK_O;
                    403:      case XK_P: case XK_p: return AK_P;
                    404:      case XK_R: case XK_r: return AK_R;
                    405:      case XK_S: case XK_s: return AK_S;
                    406:      case XK_T: case XK_t: return AK_T;
                    407:      case XK_U: case XK_u: return AK_U;
                    408:      case XK_V: case XK_v: return AK_V;
                    409:      case XK_W: case XK_w: return AK_W;
                    410:      case XK_X: case XK_x: return AK_X;
                    411:        
                    412:      case XK_0: return AK_0;
                    413:      case XK_1: return AK_1;
                    414:      case XK_2: return AK_2;
                    415:      case XK_3: return AK_3;
                    416:      case XK_4: return AK_4;
                    417:      case XK_5: return AK_5;
                    418:      case XK_6: return AK_6;
                    419:      case XK_7: return AK_7;
                    420:      case XK_8: return AK_8;
                    421:      case XK_9: return AK_9;
                    422:        
1.1.1.2 ! root      423:        /* You never know which Keysyms might be missing on some workstation
        !           424:         * This #ifdef should be enough. */
        !           425: #if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End)
        !           426:      case XK_KP_0: case XK_KP_Insert: return AK_NP0;
        !           427:      case XK_KP_1: case XK_KP_End: return AK_NP1;
        !           428:      case XK_KP_2: case XK_KP_Down: return AK_NP2;
        !           429:      case XK_KP_3: case XK_KP_Next: return AK_NP3;
        !           430:      case XK_KP_4: case XK_KP_Left: return AK_NP4;
        !           431:      case XK_KP_5: case XK_KP_Begin: return AK_NP5;
        !           432:      case XK_KP_6: case XK_KP_Right: return AK_NP6;
        !           433:      case XK_KP_7: case XK_KP_Home: return AK_NP7;
        !           434:      case XK_KP_8: case XK_KP_Up: return AK_NP8;
        !           435:      case XK_KP_9: case XK_KP_Prior: return AK_NP9;
        !           436: #else
1.1       root      437:      case XK_KP_0: return AK_NP0;
                    438:      case XK_KP_1: return AK_NP1;
                    439:      case XK_KP_2: return AK_NP2;
                    440:      case XK_KP_3: return AK_NP3;
                    441:      case XK_KP_4: return AK_NP4;
                    442:      case XK_KP_5: return AK_NP5;
                    443:      case XK_KP_6: return AK_NP6;
                    444:      case XK_KP_7: return AK_NP7;
                    445:      case XK_KP_8: return AK_NP8;
                    446:      case XK_KP_9: return AK_NP9;
1.1.1.2 ! root      447: #endif
        !           448:      case XK_KP_Divide: return AK_NPDIV;
        !           449:      case XK_KP_Multiply: return AK_NPMUL;
        !           450:      case XK_KP_Subtract: return AK_NPSUB;
        !           451:      case XK_KP_Add: return AK_NPADD;
        !           452:      case XK_KP_Decimal: return AK_NPDEL;
        !           453:      case XK_KP_Enter: return AK_ENT;
        !           454: 
1.1       root      455:      case XK_F1: return AK_F1;
                    456:      case XK_F2: return AK_F2;
                    457:      case XK_F3: return AK_F3;
                    458:      case XK_F4: return AK_F4;
                    459:      case XK_F5: return AK_F5;
                    460:      case XK_F6: return AK_F6;
                    461:      case XK_F7: return AK_F7;
                    462:      case XK_F8: return AK_F8;
                    463:      case XK_F9: return AK_F9;
                    464:      case XK_F10: return AK_F10;
                    465:            
1.1.1.2 ! root      466:      case XK_BackSpace: return AK_BS;
        !           467:      case XK_Delete: return AK_DEL;
        !           468:      case XK_Control_L: case XK_Control_R: return AK_CTRL;
1.1       root      469:      case XK_Tab: return AK_TAB;
1.1.1.2 ! root      470:      case XK_Alt_L: return AK_LALT;
        !           471:      case XK_Alt_R: return AK_RALT;
        !           472:      case XK_Meta_R: case XK_Hyper_R: return AK_RAMI;
        !           473:      case XK_Meta_L: case XK_Hyper_L: return AK_LAMI;
1.1       root      474:      case XK_Return: return AK_RET;
                    475:      case XK_space: return AK_SPC;
                    476:      case XK_Shift_L: return AK_LSH;
                    477:      case XK_Shift_R: return AK_RSH;
                    478:      case XK_Escape: return AK_ESC;
                    479: 
1.1.1.2 ! root      480:      case XK_Insert: return AK_BACKSLASH;
        !           481:      case XK_End: return AK_HELP;
        !           482:      case XK_Caps_Lock: return AK_CAPSLOCK;
        !           483:        
1.1       root      484:      case XK_Up: return AK_UP;
                    485:      case XK_Down: return AK_DN;
                    486:      case XK_Left: return AK_LF;
                    487:      case XK_Right: return AK_RT;
                    488:        
                    489:      case XK_F11: return AK_BACKSLASH;
                    490:      case XK_F12: return AK_mousestuff;
1.1.1.2 ! root      491: #ifdef XK_F14
        !           492:      case XK_F14:
        !           493: #endif
1.1       root      494:      case XK_Scroll_Lock: return AK_inhibit;
                    495: 
                    496: #ifdef XK_Page_Up /* These are missing occasionally */
                    497:      case XK_Page_Up: return AK_RAMI;          /* PgUp mapped to right amiga */
                    498:      case XK_Page_Down: return AK_LAMI;        /* PgDn mapped to left amiga */
                    499: #endif
                    500:     }
                    501:     return -1;
                    502: }
                    503: 
1.1.1.2 ! root      504: static int decode_fr(KeySym ks)
        !           505: {
        !           506:     switch(ks) {        /* FR specific */
        !           507:      case XK_A: case XK_a: return AK_Q;
        !           508:      case XK_M: case XK_m: return AK_SEMICOLON; 
        !           509:      case XK_Q: case XK_q: return AK_A;        
        !           510:      case XK_Y: case XK_y: return AK_Y;
        !           511:      case XK_Z: case XK_z: return AK_Z;
        !           512:      case XK_bracketleft: return AK_LBRACKET;
        !           513:      case XK_bracketright: return AK_RBRACKET;
        !           514:      case XK_comma: return AK_M;
        !           515:      case XK_less: case XK_greater: return AK_LTGT;
        !           516:      case XK_period: return AK_COMMA;
        !           517:      case XK_parenright: return AK_MINUS;
        !           518:      case XK_equal: return AK_SLASH;
        !           519:      case XK_numbersign: return AK_NUMBERSIGN;
        !           520:      case XK_slash: return AK_PERIOD;
        !           521:      case XK_minus: return AK_EQUAL;
        !           522:      case XK_backslash: return AK_BACKSLASH;
        !           523:     }
        !           524: 
        !           525:     return -1;
        !           526: }
        !           527: 
1.1       root      528: static int decode_us(KeySym ks)
                    529: {
                    530:     switch(ks) {       /* US specific */       
1.1.1.2 ! root      531:      case XK_A: case XK_a: return AK_A;
        !           532:      case XK_M: case XK_m: return AK_M;
        !           533:      case XK_Q: case XK_q: return AK_Q;
1.1       root      534:      case XK_Y: case XK_y: return AK_Y;
                    535:      case XK_Z: case XK_z: return AK_Z;
                    536:      case XK_bracketleft: return AK_LBRACKET;
                    537:      case XK_bracketright: return AK_RBRACKET;
                    538:      case XK_comma: return AK_COMMA;
                    539:      case XK_period: return AK_PERIOD;
                    540:      case XK_slash: return AK_SLASH;
                    541:      case XK_semicolon: return AK_SEMICOLON;
                    542:      case XK_minus: return AK_MINUS;
                    543:      case XK_equal: return AK_EQUAL;
                    544:        /* this doesn't work: */
1.1.1.2 ! root      545:      case XK_quoteright: return AK_QUOTE;
        !           546:      case XK_quoteleft: return AK_BACKQUOTE;
        !           547:      case XK_backslash: return AK_NUMBERSIGN;
1.1       root      548:     }
                    549: 
                    550:     return -1;
                    551: }
                    552: 
                    553: static int decode_de(KeySym ks)
                    554: {
                    555:     switch(ks) {
                    556:        /* DE specific */
1.1.1.2 ! root      557:      case XK_A: case XK_a: return AK_A;
        !           558:      case XK_M: case XK_m: return AK_M;
        !           559:      case XK_Q: case XK_q: return AK_Q;
1.1       root      560:      case XK_Y: case XK_y: return AK_Z;
                    561:      case XK_Z: case XK_z: return AK_Y;
                    562:      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
                    563:      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
                    564:      case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
                    565:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
                    566:      case XK_comma: return AK_COMMA;
                    567:      case XK_period: return AK_PERIOD;
                    568:      case XK_less: case XK_greater: return AK_LTGT;
                    569:      case XK_numbersign: return AK_NUMBERSIGN;
                    570:      case XK_ssharp: return AK_MINUS;
                    571:      case XK_apostrophe: return AK_EQUAL;
1.1.1.2 ! root      572:      case XK_asciicircum: return AK_BACKQUOTE;
        !           573:      case XK_minus: return AK_SLASH;
        !           574:     }
        !           575: 
        !           576:     return -1;
        !           577: }
        !           578: 
        !           579: static int decode_se(KeySym ks)
        !           580: {
        !           581:     switch(ks) {
        !           582:        /* SE specific */
        !           583:      case XK_A: case XK_a: return AK_A;
        !           584:      case XK_M: case XK_m: return AK_M;
        !           585:      case XK_Q: case XK_q: return AK_Q;
        !           586:      case XK_Y: case XK_y: return AK_Y;
        !           587:      case XK_Z: case XK_z: return AK_Z;
        !           588:      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
        !           589:      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
        !           590:      case XK_Aring: case XK_aring: return AK_LBRACKET;
        !           591:      case XK_comma: return AK_COMMA;
        !           592:      case XK_period: return AK_PERIOD;
        !           593:      case XK_minus: return AK_SLASH;
        !           594:      case XK_less: case XK_greater: return AK_LTGT;
        !           595:      case XK_plus: case XK_question: return AK_EQUAL;
        !           596:      case XK_at: case XK_onehalf: return AK_BACKQUOTE;
        !           597:      case XK_asciitilde: case XK_asciicircum: return AK_RBRACKET;
        !           598:      case XK_backslash: case XK_bar: return AK_MINUS;
        !           599:        
        !           600:      case XK_numbersign: return AK_NUMBERSIGN;
        !           601:     }
        !           602: 
        !           603:     return -1;
        !           604:  }
        !           605: 
        !           606: static int decode_it(KeySym ks)
        !           607: {
        !           608:     switch(ks) {
        !           609:        /* IT specific */
        !           610:      case XK_A: case XK_a: return AK_A;
        !           611:      case XK_M: case XK_m: return AK_M;
        !           612:      case XK_Q: case XK_q: return AK_Q;
        !           613:      case XK_Y: case XK_y: return AK_Y;
        !           614:      case XK_Z: case XK_z: return AK_Z;
        !           615:      case XK_Ograve: case XK_ograve: return AK_SEMICOLON;
        !           616:      case XK_Agrave: case XK_agrave: return AK_QUOTE;
        !           617:      case XK_Egrave: case XK_egrave: return AK_LBRACKET;
        !           618:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
        !           619:      case XK_comma: return AK_COMMA;
        !           620:      case XK_period: return AK_PERIOD;
        !           621:      case XK_less: case XK_greater: return AK_LTGT;
        !           622:      case XK_backslash: case XK_bar: return AK_BACKQUOTE;               
        !           623:      case XK_apostrophe: return AK_MINUS;           
        !           624:      case XK_Igrave: case XK_igrave: return AK_EQUAL;
        !           625:      case XK_minus: return AK_SLASH;
        !           626:      case XK_numbersign: return AK_NUMBERSIGN;
1.1       root      627:     }
                    628: 
                    629:     return -1;
                    630: }
                    631: 
                    632: static int keycode2amiga(XKeyEvent *event)
                    633: {
                    634:     KeySym ks;
                    635:     int as;
                    636:     int index = 0;
                    637:     
                    638:     do {
                    639:        ks = XLookupKeysym(event, index);
                    640:        as = kc_decode (ks);
                    641:        
                    642:        if (as == -1) {     
                    643:            switch(keyboard_lang) {
1.1.1.2 ! root      644: 
        !           645:            case KBD_LANG_FR:
        !           646:                as = decode_fr(ks);
        !           647:                break;
        !           648: 
        !           649:            case KBD_LANG_US:
1.1       root      650:                as = decode_us(ks);
                    651:                break;
                    652:                
                    653:             case KBD_LANG_DE:
                    654:                as = decode_de(ks);
                    655:                break;
                    656:                
1.1.1.2 ! root      657:             case KBD_LANG_SE:
        !           658:                as = decode_se(ks);
        !           659:                break;
        !           660:                
        !           661:             case KBD_LANG_IT:
        !           662:                as = decode_it(ks);
        !           663:                break;
        !           664: 
1.1       root      665:             default:
                    666:                as = -1;
                    667:                break;
                    668:            }
                    669:        }
                    670:        if(-1 != as)
                    671:                return as;
                    672:        index++;
                    673:     } while (ks != NoSymbol);
                    674:     return -1;
                    675: }
                    676: 
                    677: static struct timeval lastMotionTime;
                    678: 
                    679: void handle_events(void)
                    680: {
1.1.1.2 ! root      681:     int repeat, refresh = 0;
        !           682:     newmousecounters = 0;
        !           683:     gui_handle_events();
        !           684:     
1.1       root      685:     do {
                    686:        XEvent event;
                    687:        if (!XCheckMaskEvent(display, eventmask, &event)) break;
1.1.1.2 ! root      688:        repeat = 0;
1.1       root      689:        
                    690:        switch(event.type) {
                    691:         case KeyPress: {               
                    692:             int kc = keycode2amiga((XKeyEvent *)&event);
                    693:             if (kc == -1) break;
                    694:             switch (kc) {
                    695:              case AK_mousestuff:
1.1.1.2 ! root      696:                 togglemouse();
1.1       root      697:                 break;
                    698: 
                    699:              case AK_inhibit:
                    700:                 inhibit_frame ^= 1;
                    701:                 break;
                    702: 
                    703:              default:
                    704:                 if (!keystate[kc]) {
1.1.1.2 ! root      705:                     keystate[kc] = 1;
1.1       root      706:                     record_key (kc << 1);
                    707:                 }
                    708:                 break;
                    709:             }
                    710:             break;
                    711:         }
                    712:         case KeyRelease: {          
                    713:             int kc = keycode2amiga((XKeyEvent *)&event);
                    714:             if (kc == -1) break;
1.1.1.2 ! root      715:             keystate[kc] = 0;
1.1       root      716:             record_key ((kc << 1) | 1);
                    717:             break;
                    718:         }
                    719:         case ButtonPress:
1.1.1.2 ! root      720:            buttonstate[((XButtonEvent *)&event)->button-1] = 1;
1.1       root      721:            break;
                    722:         case ButtonRelease:
1.1.1.2 ! root      723:            buttonstate[((XButtonEvent *)&event)->button-1] = 0;
1.1       root      724:            break;
                    725:         case EnterNotify:
1.1.1.2 ! root      726:            newmousecounters = 1;
1.1       root      727:            lastmx = ((XCrossingEvent *)&event)->x;
                    728:            lastmy = ((XCrossingEvent *)&event)->y;
1.1.1.2 ! root      729:            repeat = 1;
        !           730:            inwindow = 1;
1.1       root      731:            break;
                    732:         case LeaveNotify:
1.1.1.2 ! root      733:            inwindow = 0;
        !           734:            repeat = 1;
1.1       root      735:            break;
                    736:         case FocusIn:
                    737:            XAutoRepeatOff(display);
1.1.1.2 ! root      738:            repeat = 1;
1.1       root      739:            break;
                    740:         case FocusOut:
                    741:            XAutoRepeatOn(display);
1.1.1.2 ! root      742:            repeat = 1;
1.1       root      743:            break;
                    744:         case MotionNotify:
                    745:            if (inwindow) {             
                    746:                lastmx = ((XMotionEvent *)&event)->x;
                    747:                lastmy = ((XMotionEvent *)&event)->y;
1.1.1.2 ! root      748:                if(!cursorOn && use_xhair) {
1.1       root      749:                    XDefineCursor(display, mywin, xhairCursor);
1.1.1.2 ! root      750:                    cursorOn = 1;
1.1       root      751:                }
                    752:                gettimeofday(&lastMotionTime, NULL);
                    753:            }
1.1.1.2 ! root      754:            repeat = 1;
        !           755:            break;
        !           756:         case Expose:
        !           757:            refresh = 1;
        !           758:            repeat  = 1;
1.1       root      759:            break;
                    760:        }
                    761:     } while (repeat);
1.1.1.2 ! root      762: 
        !           763: #ifdef DONT_WANT_SHM
        !           764:     if(refresh) 
        !           765:        XPutImage(display, mywin, blackgc, img, 0, 0, 0, 0, hpixels, vsize);
        !           766: #else
        !           767:     if(refresh)
        !           768:        XShmPutImage(display, mywin, blackgc, img, 0, 0, 0, 0, hpixels, vsize, 0);
        !           769: #endif
        !           770:     if(cursorOn && use_xhair) {
1.1       root      771:        struct timeval now;
                    772:        int diff;
                    773:        gettimeofday(&now, NULL);
                    774:        diff = (now.tv_sec - lastMotionTime.tv_sec) * 1000000 + 
                    775:            (now.tv_usec - lastMotionTime.tv_usec);
                    776:        if(diff > 1000000) {
                    777:            XDefineCursor(display, mywin, blankCursor);
1.1.1.2 ! root      778:            cursorOn = 0;
1.1       root      779:        }
                    780:     }
                    781:        
                    782:     /* "Affengriff" */
                    783:     if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
                    784:        MC68000_reset();
                    785: }
                    786: 
1.1.1.2 ! root      787: int debuggable(void)
1.1       root      788: {
1.1.1.2 ! root      789:     return 1;
1.1       root      790: }
                    791: 
1.1.1.2 ! root      792: int needmousehack(void)
1.1       root      793: {
1.1.1.2 ! root      794:     return 1;
1.1       root      795: }
                    796: 
                    797: void LED(int on)
                    798: {
1.1.1.2 ! root      799:     XKeyboardControl control;
        !           800:     control.led = 1; /* implementation defined */
        !           801:     control.led_mode = on ? LedModeOn : LedModeOff;
        !           802:     XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
1.1       root      803: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.