Annotation of uae/src/xwin.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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