home *** CD-ROM | disk | FTP | other *** search
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * X interface
- *
- * Copyright 1995, 1996 Bernd Schmidt
- * Copyright 1996 Ed Hanway, Andre Beck, Samuel Devulder, Bruno Coste
- */
-
- #include "sysconfig.h"
- #include "sysdeps.h"
-
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/keysym.h>
- #include <X11/cursorfont.h>
-
- #ifndef DONT_WANT_SHM
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <X11/extensions/XShm.h>
- #endif
-
- #include "config.h"
- #include "options.h"
- #include "memory.h"
- #include "custom.h"
- #include "newcpu.h"
- #include "xwin.h"
- #include "keyboard.h"
- #include "keybuf.h"
- #include "gui.h"
-
- static Display *display;
- static int screen;
- static Window rootwin, mywin;
-
- static GC whitegc,blackgc;
- static XColor black,white;
- static Colormap cmap;
-
- static int need_dither;
-
- static char *image_mem;
- static XImage *img;
- static Visual *vis;
- static XVisualInfo visualInfo;
- static int bitdepth, bit_unit;
- #ifndef DONT_WANT_SHM
- static int use_shm = 1;
- static XShmSegmentInfo shminfo;
- #endif
- static Cursor blankCursor, xhairCursor;
- static int cursorOn;
-
- #ifdef LOW_BANDWIDTH
- static int use_low_bandwidth = 1;
- #else
- static int use_low_bandwidth = 0;
- #endif
-
- xcolnr xcolors[4096];
-
- /* Keyboard and mouse */
-
- static int keystate[256];
-
- int buttonstate[3];
- int lastmx, lastmy;
- int newmousecounters;
-
- static int inwindow;
- const long int eventmask = (KeyPressMask|KeyReleaseMask|ButtonPressMask
- |ButtonReleaseMask|PointerMotionMask
- |FocusChangeMask|EnterWindowMask
- |ExposureMask
- |LeaveWindowMask);
-
- static int vsize, hsize, hpixels;
- static char *oldpixbuf;
-
- struct vidbuf_description gfxvidinfo;
-
- void flush_line(int y)
- {
- int xs = 0, xe;
- int len, factor;
- char *linebuf = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
- char *src, *dst;
- if (gfxvidinfo.maxlinetoscr)
- xe = gfxvidinfo.maxlinetoscr-1;
- else
- xe = hsize-1;
-
- if (!use_low_bandwidth)
- fprintf(stderr, "Bug!\n");
-
- switch(gfxvidinfo.pixbytes) {
- case 4:
- {
- int *newp = (int *)linebuf;
- int *oldp = (int *)(oldpixbuf + y*gfxvidinfo.rowbytes);
- while (newp[xs] == oldp[xs]) {
- if (xs == xe)
- return;
- xs++;
- }
- while (newp[xe] == oldp[xe]) xe--;
-
- dst = (char *)(oldp + xs); src = (char *)(newp + xs);
- }
- break;
- case 2:
- {
- short *newp = (short *)linebuf;
- short *oldp = (short *)(oldpixbuf + y*gfxvidinfo.rowbytes);
- while (newp[xs] == oldp[xs]) {
- if (xs == xe)
- return;
- xs++;
- }
- while (newp[xe] == oldp[xe]) xe--;
-
- dst = (char *)(oldp + xs); src = (char *)(newp + xs);
- }
- break;
- case 1:
- {
- char *newp = (char *)linebuf;
- char *oldp = (char *)(oldpixbuf + y*gfxvidinfo.rowbytes);
- while (newp[xs] == oldp[xs]) {
- if (xs == xe)
- return;
- xs++;
- }
- while (newp[xe] == oldp[xe]) xe--;
-
- dst = (char *)(oldp + xs); src = (char *)(newp + xs);
- }
- break;
-
- default:
- abort();
- break;
- }
-
- len = xe - xs + 1;
- memcpy (dst, src, len * gfxvidinfo.pixbytes);
-
- if (need_dither) {
- UBYTE *target = (UBYTE *)image_mem + img->bytes_per_line * y;
- xs &= ~(8/bit_unit - 1);
- len = xe - xs + 1;
- len += 3; len &= ~3;
- len += (8/bit_unit - 1); len &= ~(8/bit_unit-1);
- if (len & 3)
- printf("%d\n",len);
- DitherLine(target + xs*bit_unit/8, (UWORD *)linebuf + xs, xs, y, len, bit_unit);
- }
- #ifndef DONT_WANT_SHM
- if (use_shm)
- XShmPutImage(display, mywin, blackgc, img, xs, y, xs, y, len, 1, 0);
- else
- #endif
- XPutImage(display, mywin, blackgc, img, xs, y, xs, y, len, 1);
- }
-
- void flush_block (int ystart, int ystop)
- {
- int len, xs = 0;
-
- if (gfxvidinfo.maxlinetoscr)
- len = gfxvidinfo.maxlinetoscr;
- else
- len = hsize;
- #ifndef DONT_WANT_SHM
- if (use_shm)
- XShmPutImage(display, mywin, blackgc, img, xs, ystart, 0, ystart, len,
- ystop - ystart + 1, 0);
- else
- #endif
- XPutImage(display, mywin, blackgc, img, xs, ystart, 0, ystart, len,
- ystop - ystart + 1);
- }
-
- void flush_screen (int ystart, int ystop)
- {
- #ifndef DONT_WANT_SHM
- if (use_shm) XSync(display, 0);
- #endif
- }
-
- void calc_adjustment(void)
- {
- switch (screen_res) {
- case 0: case 1: case 2: /* LoRes, 320x300 */
- gfxvidinfo.x_adjust = prev_max_diwstop - 320;
- break;
-
- case 3: /* 640x480 */
- gfxvidinfo.x_adjust = prev_max_diwstop - 640;
- break;
- default:
- gfxvidinfo.x_adjust = 0;
- break;
- }
- }
-
- static __inline__ int bitsInMask(unsigned long mask)
- {
- /* count bits in mask */
- int n = 0;
- while(mask) {
- n += mask&1;
- mask >>= 1;
- }
- return n;
- }
-
- static __inline__ int maskShift(unsigned long mask)
- {
- /* determine how far mask is shifted */
- int n = 0;
- while(!(mask&1)) {
- n++;
- mask >>= 1;
- }
- return n;
- }
-
- static int get_color(int r, int g, int b, xcolnr *cnp)
- {
- XColor col;
- char str[10];
- sprintf(str, "rgb:%x/%x/%x", r, g, b);
- XParseColor(display, cmap, str, &col);
- if (XAllocColor(display, cmap, &col)) {
- *cnp = col.pixel;
- return 1;
- }
- return 0;
- }
-
- static int init_colors(void)
- {
- if (need_dither) {
- if (bitdepth == 1)
- setup_greydither (1, get_color);
- else
- setup_dither (bitdepth, get_color);
- return 1;
- }
-
- if (bitdepth != 8 && bitdepth != 12
- && bitdepth != 16 && bitdepth != 24) {
- fprintf(stderr, "Unsupported bit depth (%d)\n", bitdepth);
- return 0;
- }
-
- #ifdef __cplusplus
- switch(visualInfo.c_class)
- #else
- switch(visualInfo.class)
- #endif
- {
- case TrueColor:
- {
- int red_bits = bitsInMask(visualInfo.red_mask);
- int green_bits = bitsInMask(visualInfo.green_mask);
- int blue_bits = bitsInMask(visualInfo.blue_mask);
- int red_shift = maskShift(visualInfo.red_mask);
- int green_shift = maskShift(visualInfo.green_mask);
- int blue_shift = maskShift(visualInfo.blue_mask);
- alloc_colors64k(red_bits, green_bits, blue_bits, red_shift,
- green_shift, blue_shift);
- }
- break;
-
- case GrayScale:
- case PseudoColor:
- alloc_colors256(get_color);
- break;
-
- default:
- #ifdef __cplusplus
- fprintf(stderr, "Unsupported visual class (%d)\n", visualInfo.c_class);
- #else
- fprintf(stderr, "Unsupported visual class (%d)\n", visualInfo.class);
- #endif
- return 0;
- }
- return 1;
- }
-
- int graphics_init(void)
- {
- int i,j;
- char *display_name = 0;
- XSetWindowAttributes wattr;
- XPixmapFormatValues *xpfvs;
- need_dither = 0;
-
- if (screen_res < 3) {
- fprintf(stderr, "Low resolution mode selected. Forcing 320x300.\n");
- }
-
- display = XOpenDisplay(display_name);
- if (display == 0) {
- fprintf(stderr, "Can't connect to X server %s\n", XDisplayName(display_name));
- return 0;
- }
- screen = XDefaultScreen(display);
- rootwin = XRootWindow(display,screen);
-
- /* try for a 12 bit visual first, then a 16 bit, then a 24 bit, then 8 bit */
- if (XMatchVisualInfo(display, screen, 12, TrueColor, &visualInfo)) {
- } else if (XMatchVisualInfo(display, screen, 16, TrueColor, &visualInfo)) {
- } else if (XMatchVisualInfo(display, screen, 24, TrueColor, &visualInfo)) {
- } else if (XMatchVisualInfo(display, screen, 8, PseudoColor, &visualInfo)) {
- /* for our HP boxes */
- } else if (XMatchVisualInfo(display, screen, 8, GrayScale, &visualInfo)) {
- } else if (XMatchVisualInfo(display, screen, 4, PseudoColor, &visualInfo)) {
- /* VGA16 server. Argh. */
- } else if (XMatchVisualInfo(display, screen, 1, StaticGray, &visualInfo)) {
- /* Mono server. Yuk */
- } else {
- fprintf(stderr, "Can't obtain appropriate X visual.\n");
- return 0;
- }
- vis = visualInfo.visual;
- bitdepth = visualInfo.depth;
-
- /* We now have the bitdepth of the display, but that doesn't tell us yet
- * how many bits to use per pixel. The VGA16 server has a bitdepth of 4,
- * but uses 1 byte per pixel. */
- xpfvs = XListPixmapFormats(display, &i);
- for (j = 0; j < i && xpfvs->depth != bitdepth; j++, xpfvs++)
- ;
- if (j == i) {
- fprintf(stderr, "Your X server is feeling ill.\n");
- return 0;
- }
-
- bit_unit = xpfvs->bits_per_pixel;
- fprintf(stderr, "Using %d bit visual, %d bits per pixel\n", bitdepth, bit_unit);
-
- vsize = correct_aspect ? 2*numscrlines : numscrlines;
- switch (screen_res) {
- case 0: case 1: case 2:
- hsize = hpixels = 320;
- break;
- case 3:
- hsize = hpixels = 640;
- break;
- case 4:
- hpixels = 796; hsize = 800; /* ??? */
- break;
- }
-
- cmap = XCreateColormap(display, rootwin, vis, AllocNone);
- XParseColor(display, cmap, "#000000", &black);
- if (!XAllocColor(display, cmap, &black))
- fprintf(stderr, "Whoops??\n");
- XParseColor(display, cmap, "#ffffff", &white);
- if (!XAllocColor(display, cmap, &white))
- fprintf(stderr, "Whoops??\n");
-
- wattr.event_mask = eventmask;
- wattr.background_pixel = black.pixel;
- wattr.backing_store = Always;
- wattr.backing_planes = bitdepth;
- wattr.border_pixmap = None;
- wattr.border_pixel = black.pixel;
- wattr.colormap = cmap;
-
- mywin = XCreateWindow(display, rootwin, 0, 0, hpixels, vsize, 0,
- bitdepth, InputOutput, vis,
- CWEventMask|CWBackPixel|CWBorderPixel|CWBackingStore
- |CWBackingPlanes|CWColormap,
- &wattr);
- XMapWindow(display,mywin);
- XStoreName(display, mywin, "UAE");
-
- blankCursor = XCreatePixmapCursor(display,
- XCreatePixmap(display, mywin, 1, 1, 1),
- XCreatePixmap(display, mywin, 1, 1, 1),
- &black, &white, 0, 0);
- xhairCursor = XCreateFontCursor(display, XC_crosshair);
-
- whitegc = XCreateGC(display,mywin,0,0);
- blackgc = XCreateGC(display,mywin,0,0);
-
- XSetForeground(display,blackgc,black.pixel);
- XSetForeground(display,whitegc,white.pixel);
-
- if (bitdepth < 8 || (bitdepth == 8 && color_mode == 3)) {
- gfxvidinfo.pixbytes = 2;
- use_low_bandwidth = 1;
- need_dither = 1;
- #ifndef DONT_WANT_SHM
- use_shm = 0;
- #endif
- } else {
- gfxvidinfo.pixbytes = (bitdepth == 24 || bitdepth == 32 ? 4
- : bitdepth == 12 || bitdepth == 16 ? 2
- : 1);
- }
-
- #ifndef DONT_WANT_SHM
- if (use_shm) {
- img = XShmCreateImage(display, vis, bitdepth, ZPixmap, 0, &shminfo, hsize, vsize);
-
- shminfo.shmid = shmget(IPC_PRIVATE, vsize * img->bytes_per_line,
- IPC_CREAT | 0777);
- shminfo.shmaddr = img->data = image_mem = (char *)shmat(shminfo.shmid, 0, 0);
- shminfo.readOnly = False;
- /* let the xserver attach */
- XShmAttach(display, &shminfo);
- XSync(display,0);
- /* now deleting means making it temporary */
- shmctl(shminfo.shmid, IPC_RMID, 0);
- } else
- #endif
- {
- /* Question for people who know about X: Could we allocate the buffer
- * after creating the image and then do img->data = buffer, as below in
- * the SHM case?
- */
- image_mem = (char *)malloc(vsize * hsize * bit_unit / 8); /* ??? */
- img = XCreateImage(display, vis, bitdepth, ZPixmap, 0, image_mem,
- hsize, vsize, 32, 0);
- if (img->bytes_per_line != hsize * bit_unit / 8)
- fprintf (stderr, "Possible bug here... graphics may look strange.\n");
- }
-
- if (need_dither) {
- gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * hsize;
- gfxvidinfo.bufmem = (char *)malloc(gfxvidinfo.rowbytes * vsize);
- } else {
- gfxvidinfo.rowbytes = img->bytes_per_line;
- gfxvidinfo.bufmem = image_mem;
- }
-
- gfxvidinfo.maxline = 100000; /* no limit */
-
- if (use_low_bandwidth) {
- gfxvidinfo.maxblocklines = 0;
- oldpixbuf = (char *)malloc(gfxvidinfo.rowbytes * vsize);
- } else {
- gfxvidinfo.maxblocklines = 100; /* whatever... */
- }
-
- if (!init_colors())
- return 0;
-
- buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
- for(i=0; i<256; i++)
- keystate[i] = 0;
-
- lastmx = lastmy = 0;
- newmousecounters = 0;
- inwindow = 0;
-
- if (use_xhair)
- XDefineCursor(display, mywin, xhairCursor);
- else
- XDefineCursor(display, mywin, blankCursor);
- cursorOn = 1;
- return 1;
- }
-
- void graphics_leave(void)
- {
- XAutoRepeatOn(display);
- }
-
- /* Decode KeySyms. This function knows about all keys that are common
- * between different keyboard languages. */
- static int kc_decode (KeySym ks)
- {
- switch (ks) {
- case XK_B: case XK_b: return AK_B;
- case XK_C: case XK_c: return AK_C;
- case XK_D: case XK_d: return AK_D;
- case XK_E: case XK_e: return AK_E;
- case XK_F: case XK_f: return AK_F;
- case XK_G: case XK_g: return AK_G;
- case XK_H: case XK_h: return AK_H;
- case XK_I: case XK_i: return AK_I;
- case XK_J: case XK_j: return AK_J;
- case XK_K: case XK_k: return AK_K;
- case XK_L: case XK_l: return AK_L;
- case XK_N: case XK_n: return AK_N;
- case XK_O: case XK_o: return AK_O;
- case XK_P: case XK_p: return AK_P;
- case XK_R: case XK_r: return AK_R;
- case XK_S: case XK_s: return AK_S;
- case XK_T: case XK_t: return AK_T;
- case XK_U: case XK_u: return AK_U;
- case XK_V: case XK_v: return AK_V;
- case XK_W: case XK_w: return AK_W;
- case XK_X: case XK_x: return AK_X;
-
- case XK_0: return AK_0;
- case XK_1: return AK_1;
- case XK_2: return AK_2;
- case XK_3: return AK_3;
- case XK_4: return AK_4;
- case XK_5: return AK_5;
- case XK_6: return AK_6;
- case XK_7: return AK_7;
- case XK_8: return AK_8;
- case XK_9: return AK_9;
-
- /* You never know which Keysyms might be missing on some workstation
- * This #ifdef should be enough. */
- #if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End)
- case XK_KP_0: case XK_KP_Insert: return AK_NP0;
- case XK_KP_1: case XK_KP_End: return AK_NP1;
- case XK_KP_2: case XK_KP_Down: return AK_NP2;
- case XK_KP_3: case XK_KP_Next: return AK_NP3;
- case XK_KP_4: case XK_KP_Left: return AK_NP4;
- case XK_KP_5: case XK_KP_Begin: return AK_NP5;
- case XK_KP_6: case XK_KP_Right: return AK_NP6;
- case XK_KP_7: case XK_KP_Home: return AK_NP7;
- case XK_KP_8: case XK_KP_Up: return AK_NP8;
- case XK_KP_9: case XK_KP_Prior: return AK_NP9;
- #else
- case XK_KP_0: return AK_NP0;
- case XK_KP_1: return AK_NP1;
- case XK_KP_2: return AK_NP2;
- case XK_KP_3: return AK_NP3;
- case XK_KP_4: return AK_NP4;
- case XK_KP_5: return AK_NP5;
- case XK_KP_6: return AK_NP6;
- case XK_KP_7: return AK_NP7;
- case XK_KP_8: return AK_NP8;
- case XK_KP_9: return AK_NP9;
- #endif
- case XK_KP_Divide: return AK_NPDIV;
- case XK_KP_Multiply: return AK_NPMUL;
- case XK_KP_Subtract: return AK_NPSUB;
- case XK_KP_Add: return AK_NPADD;
- case XK_KP_Decimal: return AK_NPDEL;
- case XK_KP_Enter: return AK_ENT;
-
- case XK_F1: return AK_F1;
- case XK_F2: return AK_F2;
- case XK_F3: return AK_F3;
- case XK_F4: return AK_F4;
- case XK_F5: return AK_F5;
- case XK_F6: return AK_F6;
- case XK_F7: return AK_F7;
- case XK_F8: return AK_F8;
- case XK_F9: return AK_F9;
- case XK_F10: return AK_F10;
-
- case XK_BackSpace: return AK_BS;
- case XK_Delete: return AK_DEL;
- case XK_Control_L: case XK_Control_R: return AK_CTRL;
- case XK_Tab: return AK_TAB;
- case XK_Alt_L: return AK_LALT;
- case XK_Alt_R: return AK_RALT;
- case XK_Meta_R: case XK_Hyper_R: return AK_RAMI;
- case XK_Meta_L: case XK_Hyper_L: return AK_LAMI;
- case XK_Return: return AK_RET;
- case XK_space: return AK_SPC;
- case XK_Shift_L: return AK_LSH;
- case XK_Shift_R: return AK_RSH;
- case XK_Escape: return AK_ESC;
-
- case XK_Insert: return AK_BACKSLASH;
- case XK_End: return AK_HELP;
- case XK_Caps_Lock: return AK_CAPSLOCK;
-
- case XK_Up: return AK_UP;
- case XK_Down: return AK_DN;
- case XK_Left: return AK_LF;
- case XK_Right: return AK_RT;
-
- case XK_F11: return AK_BACKSLASH;
- case XK_F12: return AK_mousestuff;
- #ifdef XK_F14
- case XK_F14:
- #endif
- case XK_Scroll_Lock: return AK_inhibit;
-
- #ifdef XK_Page_Up /* These are missing occasionally */
- case XK_Page_Up: return AK_RAMI; /* PgUp mapped to right amiga */
- case XK_Page_Down: return AK_LAMI; /* PgDn mapped to left amiga */
- #endif
- }
- return -1;
- }
-
- static int decode_fr(KeySym ks)
- {
- switch(ks) { /* FR specific */
- case XK_A: case XK_a: return AK_Q;
- case XK_M: case XK_m: return AK_SEMICOLON;
- case XK_Q: case XK_q: return AK_A;
- case XK_Y: case XK_y: return AK_Y;
- case XK_Z: case XK_z: return AK_Z;
- case XK_bracketleft: return AK_LBRACKET;
- case XK_bracketright: return AK_RBRACKET;
- case XK_comma: return AK_M;
- case XK_less: case XK_greater: return AK_LTGT;
- case XK_period: return AK_COMMA;
- case XK_parenright: return AK_MINUS;
- case XK_equal: return AK_SLASH;
- case XK_numbersign: return AK_NUMBERSIGN;
- case XK_slash: return AK_PERIOD;
- case XK_minus: return AK_EQUAL;
- case XK_backslash: return AK_BACKSLASH;
- }
-
- return -1;
- }
-
- static int decode_us(KeySym ks)
- {
- switch(ks) { /* US specific */
- case XK_A: case XK_a: return AK_A;
- case XK_M: case XK_m: return AK_M;
- case XK_Q: case XK_q: return AK_Q;
- case XK_Y: case XK_y: return AK_Y;
- case XK_Z: case XK_z: return AK_Z;
- case XK_bracketleft: return AK_LBRACKET;
- case XK_bracketright: return AK_RBRACKET;
- case XK_comma: return AK_COMMA;
- case XK_period: return AK_PERIOD;
- case XK_slash: return AK_SLASH;
- case XK_semicolon: return AK_SEMICOLON;
- case XK_minus: return AK_MINUS;
- case XK_equal: return AK_EQUAL;
- /* this doesn't work: */
- case XK_quoteright: return AK_QUOTE;
- case XK_quoteleft: return AK_BACKQUOTE;
- case XK_backslash: return AK_NUMBERSIGN;
- }
-
- return -1;
- }
-
- static int decode_de(KeySym ks)
- {
- switch(ks) {
- /* DE specific */
- case XK_A: case XK_a: return AK_A;
- case XK_M: case XK_m: return AK_M;
- case XK_Q: case XK_q: return AK_Q;
- case XK_Y: case XK_y: return AK_Z;
- case XK_Z: case XK_z: return AK_Y;
- case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
- case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
- case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
- case XK_plus: case XK_asterisk: return AK_RBRACKET;
- case XK_comma: return AK_COMMA;
- case XK_period: return AK_PERIOD;
- case XK_less: case XK_greater: return AK_LTGT;
- case XK_numbersign: return AK_NUMBERSIGN;
- case XK_ssharp: return AK_MINUS;
- case XK_apostrophe: return AK_EQUAL;
- case XK_asciicircum: return AK_BACKQUOTE;
- case XK_minus: return AK_SLASH;
- }
-
- return -1;
- }
-
- static int decode_se(KeySym ks)
- {
- switch(ks) {
- /* SE specific */
- case XK_A: case XK_a: return AK_A;
- case XK_M: case XK_m: return AK_M;
- case XK_Q: case XK_q: return AK_Q;
- case XK_Y: case XK_y: return AK_Y;
- case XK_Z: case XK_z: return AK_Z;
- case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
- case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
- case XK_Aring: case XK_aring: return AK_LBRACKET;
- case XK_comma: return AK_COMMA;
- case XK_period: return AK_PERIOD;
- case XK_minus: return AK_SLASH;
- case XK_less: case XK_greater: return AK_LTGT;
- case XK_plus: case XK_question: return AK_EQUAL;
- case XK_at: case XK_onehalf: return AK_BACKQUOTE;
- case XK_asciitilde: case XK_asciicircum: return AK_RBRACKET;
- case XK_backslash: case XK_bar: return AK_MINUS;
-
- case XK_numbersign: return AK_NUMBERSIGN;
- }
-
- return -1;
- }
-
- static int decode_it(KeySym ks)
- {
- switch(ks) {
- /* IT specific */
- case XK_A: case XK_a: return AK_A;
- case XK_M: case XK_m: return AK_M;
- case XK_Q: case XK_q: return AK_Q;
- case XK_Y: case XK_y: return AK_Y;
- case XK_Z: case XK_z: return AK_Z;
- case XK_Ograve: case XK_ograve: return AK_SEMICOLON;
- case XK_Agrave: case XK_agrave: return AK_QUOTE;
- case XK_Egrave: case XK_egrave: return AK_LBRACKET;
- case XK_plus: case XK_asterisk: return AK_RBRACKET;
- case XK_comma: return AK_COMMA;
- case XK_period: return AK_PERIOD;
- case XK_less: case XK_greater: return AK_LTGT;
- case XK_backslash: case XK_bar: return AK_BACKQUOTE;
- case XK_apostrophe: return AK_MINUS;
- case XK_Igrave: case XK_igrave: return AK_EQUAL;
- case XK_minus: return AK_SLASH;
- case XK_numbersign: return AK_NUMBERSIGN;
- }
-
- return -1;
- }
-
- static int keycode2amiga(XKeyEvent *event)
- {
- KeySym ks;
- int as;
- int index = 0;
-
- do {
- ks = XLookupKeysym(event, index);
- as = kc_decode (ks);
-
- if (as == -1) {
- switch(keyboard_lang) {
-
- case KBD_LANG_FR:
- as = decode_fr(ks);
- break;
-
- case KBD_LANG_US:
- as = decode_us(ks);
- break;
-
- case KBD_LANG_DE:
- as = decode_de(ks);
- break;
-
- case KBD_LANG_SE:
- as = decode_se(ks);
- break;
-
- case KBD_LANG_IT:
- as = decode_it(ks);
- break;
-
- default:
- as = -1;
- break;
- }
- }
- if(-1 != as)
- return as;
- index++;
- } while (ks != NoSymbol);
- return -1;
- }
-
- static struct timeval lastMotionTime;
-
- void handle_events(void)
- {
- int repeat, refresh = 0;
- newmousecounters = 0;
- gui_handle_events();
-
- do {
- XEvent event;
- if (!XCheckMaskEvent(display, eventmask, &event)) break;
- repeat = 0;
-
- switch(event.type) {
- case KeyPress: {
- int kc = keycode2amiga((XKeyEvent *)&event);
- if (kc == -1) break;
- switch (kc) {
- case AK_mousestuff:
- togglemouse();
- break;
-
- case AK_inhibit:
- inhibit_frame ^= 1;
- break;
-
- default:
- if (!keystate[kc]) {
- keystate[kc] = 1;
- record_key (kc << 1);
- }
- break;
- }
- break;
- }
- case KeyRelease: {
- int kc = keycode2amiga((XKeyEvent *)&event);
- if (kc == -1) break;
- keystate[kc] = 0;
- record_key ((kc << 1) | 1);
- break;
- }
- case ButtonPress:
- buttonstate[((XButtonEvent *)&event)->button-1] = 1;
- break;
- case ButtonRelease:
- buttonstate[((XButtonEvent *)&event)->button-1] = 0;
- break;
- case EnterNotify:
- newmousecounters = 1;
- lastmx = ((XCrossingEvent *)&event)->x;
- lastmy = ((XCrossingEvent *)&event)->y;
- repeat = 1;
- inwindow = 1;
- break;
- case LeaveNotify:
- inwindow = 0;
- repeat = 1;
- break;
- case FocusIn:
- XAutoRepeatOff(display);
- repeat = 1;
- break;
- case FocusOut:
- XAutoRepeatOn(display);
- repeat = 1;
- break;
- case MotionNotify:
- if (inwindow) {
- lastmx = ((XMotionEvent *)&event)->x;
- lastmy = ((XMotionEvent *)&event)->y;
- if(!cursorOn && use_xhair) {
- XDefineCursor(display, mywin, xhairCursor);
- cursorOn = 1;
- }
- gettimeofday(&lastMotionTime, NULL);
- }
- repeat = 1;
- break;
- case Expose:
- refresh = 1;
- repeat = 1;
- break;
- }
- } while (repeat);
-
- if(refresh) {
- #ifndef DONT_WANT_SHM
- if (use_shm)
- XShmPutImage(display, mywin, blackgc, img, 0, 0, 0, 0, hpixels, vsize, 0);
- else
- #endif
- XPutImage(display, mywin, blackgc, img, 0, 0, 0, 0, hpixels, vsize);
- }
- if(cursorOn && use_xhair) {
- struct timeval now;
- int diff;
- gettimeofday(&now, NULL);
- diff = (now.tv_sec - lastMotionTime.tv_sec) * 1000000 +
- (now.tv_usec - lastMotionTime.tv_usec);
- if(diff > 1000000) {
- XDefineCursor(display, mywin, blankCursor);
- cursorOn = 0;
- }
- }
-
- /* "Affengriff" */
- if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
- MC68000_reset();
- }
-
- int debuggable(void)
- {
- return 1;
- }
-
- int needmousehack(void)
- {
- return 1;
- }
-
- void LED(int on)
- {
- XKeyboardControl control;
- control.led = 1; /* implementation defined */
- control.led_mode = on ? LedModeOn : LedModeOff;
- XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
- }
-
- void target_specific_usage(void)
- {
- printf(" -S : Turn off sound support (if it is configured)\n");
- printf(" -x : Use visible cross-hair cursor\n");
- printf(" -l lang : Set keyboard language to lang, where lang is\n"
- " DE, SE, US, FR or IT\n");
- printf(" -p command : Use command to pipe printer output to.\n");
- }
-