--- uae/src/xwin.c 2018/04/24 16:48:36 1.1.1.8 +++ uae/src/xwin.c 2018/04/24 17:21:44 1.1.1.22 @@ -8,6 +8,7 @@ * Copyright 1998 Marcus Sundberg * DGA support by Kai Kollmorgen * X11/DGA merge, hotkeys and grabmouse by Marcus Sundberg + * Copyright 2003-2004 Richard Drummond */ #include "sysconfig.h" @@ -21,21 +22,21 @@ #include #include -#include "config.h" #include "options.h" -#include "threaddep/penguin.h" +#include "threaddep/thread.h" #include "uae.h" #include "memory.h" #include "xwin.h" #include "custom.h" #include "drawing.h" -#include "readcpu.h" #include "newcpu.h" #include "keyboard.h" #include "keybuf.h" #include "gui.h" #include "debug.h" #include "picasso96.h" +#include "inputdevice.h" +#include "hotkeys.h" #ifdef __cplusplus #define VI_CLASS c_class @@ -65,7 +66,7 @@ #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \ do { \ - if (currprefs.x11_use_mitshm) \ + if (currprefs.x11_use_mitshm && shmavail) \ XShmPutImage (display, mywin, mygc, (IMG), (SRCX), (SRCY), (DSTX), (DSTY), (WIDTH), (HEIGHT), 0); \ else \ XPutImage (display, mywin, mygc, (IMG), (SRCX), (SRCY), (DSTX), (DSTY), (WIDTH), (HEIGHT)); \ @@ -130,7 +131,6 @@ static int dga_colormap_installed; static int need_dither; -static int screen_is_picasso; static char picasso_invalid_lines[1201]; static int picasso_has_invalid_lines; static int picasso_invalid_start, picasso_invalid_stop; @@ -150,44 +150,19 @@ static int current_width, current_height static int x11_init_ok; static int dgaavail = 0, vidmodeavail = 0, shmavail = 0; static int dgamode; - -/* Keyboard and mouse */ - -static int keystate[256]; - -static int oldx, oldy; static int grabbed; -struct uae_hotkeys { - KeySym syms[4]; - void (*handler)(void); - int retval; - int mask; -}; +void toggle_mousegrab (void); +void framerate_up (void); +void framerate_down (void); +int xkeysym2amiga (int); +struct uae_hotkeyseq *get_x11_default_hotkeys (void); -static void handle_modeswitch (void); -static void handle_mousegrab (void); -static void handle_inhibit (void); -static void framerate_up (void); -static void framerate_down (void); - -static void handle_interpol (void); -static struct uae_hotkeys hotkeys[] = { -#ifdef USE_DGA_EXTENSION - {{ XK_F12, XK_s, 0 }, handle_modeswitch, -1, 0 }, -#endif - {{ XK_F12, XK_q, 0 }, uae_quit, -1, 0 }, - {{ XK_F12, XK_m, 0 }, togglemouse, -1, 0 }, - {{ XK_F12, XK_g, 0 }, handle_mousegrab, -1, 0 }, - {{ XK_F12, XK_i, 0 }, handle_inhibit, -1, 0 }, - {{ XK_F12, XK_p, 0 }, handle_interpol, -1, 0 }, - {{ XK_F12, XK_KP_Add, 0 }, framerate_up, -1, 0 }, - {{ XK_F12, XK_KP_Subtract, 0 }, framerate_down, -1, 0 }, - {{ XK_Scroll_Lock, 0 }, handle_inhibit, -1, 0 }, - {{ 0 }, NULL, -1, 0 } /* List must be terminated */ -}; +int pause_emulation; +static int oldx, oldy; static int inwindow; + #define EVENTMASK (KeyPressMask|KeyReleaseMask|ButtonPressMask \ |ButtonReleaseMask|PointerMotionMask \ |FocusChangeMask|EnterWindowMask \ @@ -238,12 +213,12 @@ static void get_image (int w, int h, str XDestroyImage (new_img); shminfo->shmid = -1; shmavail = 0; - fprintf (stderr, "MIT-SHM extension failed, trying fallback.\n"); + write_log ("MIT-SHM extension failed, trying fallback.\n"); } else { /* now deleting means making it temporary */ shmctl (shminfo->shmid, IPC_RMID, 0); dispi->ximg = new_img; - printf ("Using MIT-SHM extension.\n"); + write_log ("Using MIT-SHM extension.\n"); return; } } @@ -253,12 +228,12 @@ static void get_image (int w, int h, str * after creating the image and then do new_img->data = buffer, as above in * the SHM case? */ - printf ("Using normal image buffer.\n"); + write_log ("Using normal image buffer.\n"); p = (char *)xmalloc (h * w * ((bit_unit + 7) / 8)); /* ??? */ new_img = XCreateImage (display, vis, bitdepth, ZPixmap, 0, p, w, h, 32, 0); if (new_img->bytes_per_line != w * ((bit_unit + 7) / 8)) - fprintf (stderr, "Possible bug here... graphics may look strange.\n"); + write_log ("Possible bug here... graphics may look strange.\n"); dispi->image_mem = p; dispi->ximg = new_img; @@ -268,9 +243,30 @@ static void get_image (int w, int h, str static XF86VidModeModeInfo **allmodes; static int vidmodecount; +static int sortfn (const void *a, const void *b) +{ + XF86VidModeInfo **ppa = a, *ppb = b; + XF86VidModeInfo *pa = *ppa, *pb = *ppb; + if (pa->hdisplay != pb->hdisplay) + return pa->hdisplay - pb->hdisplay; + return pa->vdisplay - pb->vdisplay; +} + static int get_vidmodes (void) { - return XF86VidModeGetAllModeLines (display, screen, &vidmodecount, &allmodes); + int i; + + if (!XF86VidModeGetAllModeLines (display, screen, &vidmodecount, &allmodes)) + return 0; + + qsort (allmodes, vidmodecount, sizeof *allmode, sortfn); + + gfx_fullscreen_modes = sizeof (struct uae_rect) * vidmodecount; + n_fullscreen_modes = vidmodecount; + for (i = 0; i < vidmodecount; i++) { + gfx_fullscreen_modes[i].w = allmodes[i].hdisplay; + gfx_fullscreen_modes[i].h = allmodes[i].vdisplay; + } } #endif @@ -282,8 +278,12 @@ static int fb_width; static void switch_to_best_mode (void) { - int i, best; + Screen *scr = ScreenOfDisplay (display, screen); + int w = WidthOfScreen (scr); + int h = HeightOfScreen (scr); + int d = DefaultDepthOfScreen (scr); #ifdef USE_VIDMODE_EXTENSION + int i, best; if (vidmodeavail) { best = 0; for (i = 1; i < vidmodecount; i++) { @@ -293,7 +293,7 @@ static void switch_to_best_mode (void) && allmodes[i]->vdisplay <= allmodes[best]->vdisplay) best = i; } - printf ("entering DGA mode: %dx%d (%d, %d)\n", + write_log ("entering DGA mode: %dx%d (%d, %d)\n", allmodes[best]->hdisplay, allmodes[best]->vdisplay, current_width, current_height); XF86VidModeSwitchToMode (display, screen, allmodes[best]); @@ -304,15 +304,11 @@ static void switch_to_best_mode (void) XWarpPointer (display, None, rootwin, 0, 0, 0, 0, 0, 0); XF86DGADirectVideo (display, screen, XF86DGADirectGraphics | XF86DGADirectMouse | XF86DGADirectKeyb); XF86DGASetViewPort (display, screen, 0, 0); - memset (fb_addr, 0, fb_mem * 1024); + memset (fb_addr, 0, (w * h) * (d / 8)); } static void enter_dga_mode (void) { - Screen *scr = ScreenOfDisplay (display, screen); - int w = WidthOfScreen (scr); - int h = HeightOfScreen (scr); - XRaiseWindow (display, mywin); /* We want all the key presses */ @@ -334,13 +330,13 @@ static void enter_dga_mode (void) static void leave_dga_mode (void) { + XF86DGADirectVideo (display, screen, 0); + XUngrabPointer (display, CurrentTime); + XUngrabKeyboard (display, CurrentTime); #ifdef USE_VIDMODE_EXTENSION if (vidmodeavail) XF86VidModeSwitchToMode (display, screen, allmodes[0]); #endif - XF86DGADirectVideo (display, screen, 0); - XUngrabPointer (display, CurrentTime); - XUngrabKeyboard (display, CurrentTime); } #endif @@ -420,10 +416,10 @@ void flush_line (int y) memcpy (dst, src, len * gfxvidinfo.pixbytes); } else if (need_dither) { uae_u8 *target = (uae_u8 *)ami_dinfo.image_mem + ami_dinfo.ximg->bytes_per_line * y; - len = currprefs.gfx_width; + len = gfxvidinfo.width; DitherLine (target, (uae_u16 *)linebuf, 0, y, gfxvidinfo.width, bit_unit); } else { - fprintf (stderr, "Bug!\n"); + write_log ("Bug!\n"); abort(); } @@ -444,11 +440,16 @@ void flush_screen (int ystart, int ystop return; #if SHM_SUPPORT_LINKS == 1 - if (currprefs.x11_use_mitshm) + if (currprefs.x11_use_mitshm && shmavail) XSync (display, 0); #endif } +void flush_clear_screen (void) +{ + flush_screen(0,0); +} + STATIC_INLINE int bitsInMask (unsigned long mask) { /* count bits in mask */ @@ -519,7 +520,7 @@ static int init_colors (void) } else { if (bitdepth != 8 && bitdepth != 12 && bitdepth != 15 && bitdepth != 16 && bitdepth != 24) { - fprintf (stderr, "Unsupported bit depth (%d)\n", bitdepth); + write_log ("Unsupported bit depth (%d)\n", bitdepth); return 0; } @@ -530,10 +531,10 @@ static int init_colors (void) XParseColor (display, cmap, "#000000", &black); if (! XAllocColor (display, cmap, &black)) - fprintf (stderr, "Whoops??\n"); + write_log ("Whoops??\n"); XParseColor (display, cmap, "#ffffff", &white); if (! XAllocColor (display, cmap, &white)) - fprintf (stderr, "Whoops??\n"); + write_log ("Whoops??\n"); break; case GrayScale: @@ -542,7 +543,7 @@ static int init_colors (void) break; default: - fprintf (stderr, "Unsupported visual class (%d)\n", visualInfo.VI_CLASS); + write_log ("Unsupported visual class (%d)\n", visualInfo.VI_CLASS); return 0; } } @@ -587,35 +588,35 @@ static int dga_available (void) int EventBase, ErrorBase; if (! XF86DGAQueryVersion (display, &MajorVersion, &MinorVersion)) { - fprintf (stderr, "Unable to query video extension version\n"); + write_log ("Unable to query video extension version\n"); return 0; } if (! XF86DGAQueryExtension (display, &EventBase, &ErrorBase)) { - fprintf (stderr, "Unable to query video extension information\n"); + write_log ("Unable to query video extension information\n"); return 0; } /* Fail if the extension version in the server is too old */ if (MajorVersion < DGA_MINMAJOR || (MajorVersion == DGA_MINMAJOR && MinorVersion < DGA_MINMINOR)) { - fprintf (stderr, + write_log ( "Xserver is running an old XFree86-DGA version" " (%d.%d)\n", MajorVersion, MinorVersion); - fprintf (stderr, "Minimum required version is %d.%d\n", + write_log ("Minimum required version is %d.%d\n", DGA_MINMAJOR, DGA_MINMINOR); return 0; } if (geteuid () != 0) { - fprintf (stderr, "UAE is not running as root, DGA extension disabled.\n"); + write_log ("UAE is not running as root, DGA extension disabled.\n"); return 0; } if (! XF86DGAGetVideo (display, screen, &fb_addr, &fb_width, &fb_bank, &fb_mem) || fb_bank < fb_mem) { - fprintf (stderr, "Problems with DGA - disabling DGA extension.\n"); + write_log ("Problems with DGA - disabling DGA extension.\n"); return 0; } - fprintf (stderr, "DGA extension: addr:%X, width %d, bank size %d mem size %d\n", + write_log ("DGA extension: addr:%X, width %d, bank size %d mem size %d\n", fb_addr, fb_width, fb_bank, fb_mem); return 1; @@ -633,24 +634,24 @@ static int vid_mode_available (void) if (! dgaavail) return 0; if (! XF86VidModeQueryVersion (display, &MajorVersion, &MinorVersion)) { - fprintf (stderr, "Unable to query video extension version\n"); + write_log ("Unable to query video extension version\n"); return 0; } if (! XF86VidModeQueryExtension (display, &EventBase, &ErrorBase)) { - fprintf (stderr, "Unable to query video extension information\n"); + write_log ("Unable to query video extension information\n"); return 0; } if (MajorVersion < VidMode_MINMAJOR || (MajorVersion == VidMode_MINMAJOR && MinorVersion < VidMode_MINMINOR)) { /* Fail if the extension version in the server is too old */ - fprintf (stderr, "Xserver is running an old XFree86-VidMode version (%d.%d)\n", + write_log ("Xserver is running an old XFree86-VidMode version (%d.%d)\n", MajorVersion, MinorVersion); - fprintf (stderr, "Minimum required version is %d.%d\n", + write_log ("Minimum required version is %d.%d\n", VidMode_MINMAJOR, VidMode_MINMINOR); return 0; } if (! get_vidmodes ()) { - fprintf (stderr, "Error getting video mode information\n"); + write_log ("Error getting video mode information\n"); return 0; } return 1; @@ -674,7 +675,7 @@ int graphics_setup (void) display = XOpenDisplay (display_name); if (display == 0) { - fprintf (stderr, "Can't connect to X server %s\n", XDisplayName (display_name)); + write_log ("Can't connect to X server %s\n", XDisplayName (display_name)); return 0; } @@ -715,7 +716,18 @@ static void init_dispinfo (struct disp_i disp->ximg = 0; } -static void graphics_subinit (void) +static void reset_cursor (void) +{ + if (! dgamode) { + if (! currprefs.x11_hide_cursor) + XDefineCursor (display, mywin, xhairCursor); + else + XDefineCursor (display, mywin, blankCursor); + cursorOn = 1; + } +} + +int graphics_subinit (void) { int i, j; XSetWindowAttributes wattr; @@ -723,8 +735,27 @@ static void graphics_subinit (void) XWMHints *hints; unsigned long valuemask; - dgamode = screen_is_picasso ? currprefs.gfx_pfullscreen : currprefs.gfx_afullscreen; - dgamode = dgamode && dgaavail; + if (screen_is_picasso) { + // Set height, width for Picasso gfx + current_width = picasso_vidinfo.width; + current_height = picasso_vidinfo.height; + dgamode = currprefs.gfx_pfullscreen && dgaavail; + curr_gfx = 0; + } else { + // Set height, width for Amiga gfx + dgamode = currprefs.gfx_afullscreen && dgaavail; + if (dgamode) + curr_gfx = &currprefs.gfx_f; + else + curr_gfx = &currprefs.gfx_w; + + current_width = curr_gfx->width; + current_height = curr_gfx->height; + } + if (!screen_is_picasso) { + gfxvidinfo.width = current_width; + gfxvidinfo.height = current_height; + } wattr.background_pixel = /*black.pixel*/0; wattr.backing_store = Always; @@ -755,8 +786,8 @@ static void graphics_subinit (void) /* set class hint */ classhint.res_name = "UAE"; classhint.res_class = "UAEScreen"; - XSetClassHint(display, mywin, &classhint); - + XSetClassHint (display, mywin, &classhint); + hints = XAllocWMHints(); /* Set window group leader to self to become an application * that can be hidden by e.g. WindowMaker. @@ -764,7 +795,8 @@ static void graphics_subinit (void) * (optional) GTK+ window ID is :-/ */ hints->window_group = mywin; hints->flags = WindowGroupHint; - XSetWMHints(display, mywin, hints); + XSetWMHints (display, mywin, hints); + XFree (hints); XMapRaised (display, mywin); XSync (display, 0); @@ -788,7 +820,7 @@ static void graphics_subinit (void) if (need_dither) { gfxvidinfo.maxblocklines = 0; - gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * currprefs.gfx_width; + gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * current_width; gfxvidinfo.linemem = (char *)malloc (gfxvidinfo.rowbytes); } else if (! dgamode) { gfxvidinfo.emergmem = 0; @@ -818,13 +850,7 @@ static void graphics_subinit (void) } #endif - if (! dgamode) { - if (! currprefs.x11_hide_cursor) - XDefineCursor (display, mywin, xhairCursor); - else - XDefineCursor (display, mywin, blankCursor); - cursorOn = 1; - } + reset_cursor (); if (screen_is_picasso) { picasso_has_invalid_lines = 0; @@ -833,14 +859,59 @@ static void graphics_subinit (void) memset (picasso_invalid_lines, 0, sizeof picasso_invalid_lines); } - lastmx = lastmy = 0; - newmousecounters = 0; inwindow = 0; - for (i = 0; hotkeys[i].syms[0] != 0; i++) { - hotkeys[i].mask = 0; - for (j = 0; hotkeys[i].syms[j] != 0; j++) - hotkeys[i].mask |= (1 << j); + inputdevice_release_all_keys (); + reset_hotkeys (); + + XWarpPointer (display, None, mywin, 0, 0, 0, 0, + current_width / 2, current_height / 2); + return 1; +} + +static int get_best_visual (XVisualInfo *vi) +{ + 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, vi)) { + } else if (XMatchVisualInfo (display, screen, 15, TrueColor, vi)) { + } else if (XMatchVisualInfo (display, screen, 16, TrueColor, vi)) { + } else if (XMatchVisualInfo (display, screen, 24, TrueColor, vi)) { + } else if (XMatchVisualInfo (display, screen, 8, PseudoColor, vi)) { + /* for our HP boxes */ + } else if (XMatchVisualInfo (display, screen, 8, GrayScale, vi)) { + } else if (XMatchVisualInfo (display, screen, 4, PseudoColor, vi)) { + /* VGA16 server. Argh. */ + } else if (XMatchVisualInfo (display, screen, 1, StaticGray, vi)) { + /* Mono server. Yuk */ + } else { + write_log ("Can't obtain appropriate X visual.\n"); + return 0; + } + return 1; +} + +static int get_visual_bit_unit (XVisualInfo *vi, int bitdepth) +{ + int bit_unit = 0; + XPixmapFormatValues *xpfvs; + int i,j; + + /* 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[j].depth != bitdepth; j++) + ; + if (j < i) + bit_unit = xpfvs[j].bits_per_pixel; + XFree (xpfvs); + if (j == i) { + write_log ("Your X server is feeling ill.\n"); } + + return bit_unit; } int graphics_init (void) @@ -849,10 +920,10 @@ int graphics_init (void) XPixmapFormatValues *xpfvs; if (currprefs.x11_use_mitshm && ! shmavail) { - fprintf (stderr, "MIT-SHM extension not supported by X server.\n"); + write_log ("MIT-SHM extension not supported by X server.\n"); } if (currprefs.color_mode > 5) - fprintf (stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0; + write_log ("Bad color mode selected. Using default.\n"), currprefs.color_mode = 0; x11_init_ok = 0; need_dither = 0; @@ -865,48 +936,18 @@ int graphics_init (void) 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, 15, 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; - } + if (!get_best_visual (&visualInfo)) 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[j].depth != bitdepth; j++) - ; - if (j < i) - bit_unit = xpfvs[j].bits_per_pixel; - XFree (xpfvs); - if (j == i) { - fprintf (stderr, "Your X server is feeling ill.\n"); - return 0; - } + if (!(bit_unit = get_visual_bit_unit (&visualInfo, bitdepth))) return 0; - fprintf (stderr, "Using %d bit visual, %d bits per pixel\n", bitdepth, bit_unit); + write_log ("Using %d bit visual, %d bits per pixel\n", bitdepth, bit_unit); - fixup_prefs_dimensions (&currprefs); + fixup_prefs_dimensions (&currprefs.gfx_w, gfx_windowed_modes, n_windowed_modes); + fixup_prefs_dimensions (&currprefs.gfx_f, gfx_fullscreen_modes, n_fullscreen_modes); - gfxvidinfo.width = currprefs.gfx_width; - gfxvidinfo.height = currprefs.gfx_height; - current_width = currprefs.gfx_width; - current_height = currprefs.gfx_height; - cmap = XCreateColormap (display, rootwin, vis, AllocNone); cmap2 = XCreateColormap (display, rootwin, vis, AllocNone); if (visualInfo.VI_CLASS == GrayScale || visualInfo.VI_CLASS == PseudoColor) { @@ -918,8 +959,10 @@ int graphics_init (void) gfxvidinfo.pixbytes = 2; currprefs.x11_use_low_bandwidth = 0; need_dither = 1; + picasso_vidinfo.pixbytes = 1 /* ??? */; } else { gfxvidinfo.pixbytes = bit_unit >> 3; + picasso_vidinfo.pixbytes = bit_unit >> 3; } if (! init_colors ()) @@ -933,9 +976,6 @@ int graphics_init (void) graphics_subinit (); - buttonstate[0] = buttonstate[1] = buttonstate[2] = 0; - for (i = 0; i < 256; i++) - keystate[i] = 0; grabbed = 0; return x11_init_ok = 1; @@ -954,7 +994,7 @@ static void destroy_dinfo (struct disp_i dinfo->ximg = NULL; } -static void graphics_subshutdown (void) +void graphics_subshutdown (int final) { XSync (display, 0); #ifdef USE_DGA_EXTENSION @@ -965,7 +1005,10 @@ static void graphics_subshutdown (void) destroy_dinfo (&ami_dinfo); destroy_dinfo (&pic_dinfo); - XDestroyWindow (display, mywin); + if (mywin) { + XDestroyWindow (display, mywin); + mywin = 0; + } if (gfxvidinfo.linemem != NULL) free (gfxvidinfo.linemem); @@ -978,8 +1021,8 @@ void graphics_leave (void) if (! x11_init_ok) return; - graphics_subshutdown (); - + graphics_subshutdown (1); + if (autorepeatoff) XAutoRepeatOn (display); @@ -989,384 +1032,10 @@ void graphics_leave (void) XFreeColormap (display, cmap); XFreeColormap (display, cmap2); - XCloseDisplay (display); - dumpcustom (); -} - -/* 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_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: return AK_CTRL; - case XK_Control_R: return AK_RCTRL; - 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_HELP; - case XK_Home: return AK_NPLPAREN; - case XK_End: return AK_NPRPAREN; - 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; -#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_W: case XK_w: return AK_Z; - case XK_Z: case XK_z: return AK_W; #if 0 - 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; -#else - /* not sure for this one: my X 3.3 server doesn't handle this key always - * correctly... But anyway, on new french keyboards, no more bracket key - * at this place. - */ - case XK_dead_circumflex: - case XK_dead_diaeresis: return AK_LBRACKET; - case XK_dollar: - case XK_sterling: return AK_RBRACKET; - case XK_comma: case XK_question: return AK_M; - case XK_less: case XK_greater: return AK_LTGT; - case XK_semicolon: case XK_period: return AK_COMMA; - case XK_parenright: case XK_degree: return AK_MINUS; - case XK_equal: case XK_plus: return AK_SLASH; - case XK_numbersign: return AK_NUMBERSIGN; - case XK_colon: case XK_slash: return AK_PERIOD; - case XK_minus: case XK_6: return AK_6; - case XK_ugrave: case XK_percent: return AK_QUOTE; - /* found a spare key - I hope it deserves this place. */ - case XK_asterisk: case XK_mu: return AK_BACKSLASH; - case XK_exclam: case XK_section: return AK_EQUAL; - case XK_twosuperior: case XK_asciitilde: return AK_BACKQUOTE; - case XK_Multi_key: return AK_RAMI; - case XK_Mode_switch: return AK_RALT; + XCloseDisplay (display); #endif - } - - 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_W: case XK_w: return AK_W; - 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_BACKSLASH; - } - - 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_W: case XK_w: return AK_W; - 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_W: case XK_w: return AK_W; - 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_W: case XK_w: return AK_W; - 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 decode_es (KeySym ks) -{ - switch(ks) { - /* ES 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_W: case XK_w: return AK_W; - case XK_Y: case XK_y: return AK_Y; - case XK_Z: case XK_z: return AK_Z; - case XK_ntilde: case XK_Ntilde: return AK_SEMICOLON; -#ifdef XK_dead_acute - case XK_dead_acute: case XK_dead_diaeresis: return AK_QUOTE; - case XK_dead_grave: case XK_dead_circumflex: return AK_LBRACKET; -#endif - 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 { - int hkreturn = -1, returnnow = 0; - ks = XLookupKeysym (event, index); - if (event->type == KeyPress) { - int i, j; - for (i = 0; hotkeys[i].syms[0] != 0; i++) { - for (j = 0; hotkeys[i].syms[j] != 0; j++) { - if (ks == hotkeys[i].syms[j]) { - hotkeys[i].mask &= ~(1 << j); - if (hotkeys[i].mask == 0) { - returnnow = 1; - hkreturn = hotkeys[i].retval; - } - } - } - } - } else { - int i, j; - for (i = 0; hotkeys[i].syms[0] != 0; i++) { - for (j = 0; hotkeys[i].syms[j] != 0; j++) { - if (ks == hotkeys[i].syms[j]) { - hotkeys[i].mask |= (1 << j); - } - } - } - } - if (returnnow) - return -2; - as = kc_decode (ks); - - if (as == -1) { - switch (currprefs.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; - - case KBD_LANG_ES: - as = decode_es (ks); - break; - - default: - as = -1; - break; - } - } - if (-1 != as) - return as; - index++; - } while (ks != NoSymbol); - return -1; + dumpcustom (); } static struct timeval lastMotionTime; @@ -1375,7 +1044,6 @@ static int refresh_necessary = 0; void handle_events (void) { - newmousecounters = 0; gui_handle_events (); for (;;) { @@ -1390,105 +1058,101 @@ void handle_events (void) XNextEvent (display, &event); switch (event.type) { - case KeyPress: { - int i; - int kc = keycode2amiga ((XKeyEvent *)&event); - - if (kc == -2) { - for (i = 0; hotkeys[i].syms[0] != 0; i++) { - if (hotkeys[i].mask == 0) { - if (hotkeys[i].handler != NULL) - hotkeys[i].handler(); - } - } - break; - } - - if (kc == -1) - break; - if (! keystate[kc]) { - keystate[kc] = 1; - record_key (kc << 1); - } - break; - } + case KeyPress: case KeyRelease: { - int kc = keycode2amiga ((XKeyEvent *)&event); - if (kc < 0) - break; - keystate[kc] = 0; - record_key ((kc << 1) | 1); - break; + int state = (event.type == KeyPress); + KeySym keysym; + int index = 0; + int ievent, amiga_keycode; + do { + keysym = XLookupKeysym ((XKeyEvent *)&event, index); + if ((ievent = match_hotkey_sequence (keysym, state))) { + handle_hotkey_event (ievent, state); + break; + } else + if ((amiga_keycode = xkeysym2amiga (keysym)) >= 0) { + inputdevice_do_keyboard (amiga_keycode, state); + break; + } + index++; + } while (keysym != NoSymbol); + break; } case ButtonPress: - buttonstate[((XButtonEvent *)&event)->button-1] = 1; - break; - case ButtonRelease: - buttonstate[((XButtonEvent *)&event)->button-1] = 0; + case ButtonRelease: { + int state = (event.type == ButtonPress); + int buttonno = -1; + switch ((int)((XButtonEvent *)&event)->button) { + case 1: buttonno = 0; break; + case 2: buttonno = 2; break; + case 3: buttonno = 1; break; + /* buttons 4 and 5 report mousewheel events */ + case 4: if (state) record_key (0x7a << 1); break; + case 5: if (state) record_key (0x7b << 1); break; + } + if (buttonno >=0) + setmousebuttonstate(0, buttonno, state); break; + } case MotionNotify: if (dgamode) { - newmousecounters = 0; - lastmx += ((XMotionEvent *)&event)->x_root; - lastmy += ((XMotionEvent *)&event)->y_root; + int tx = ((XMotionEvent *)&event)->x_root; + int ty = ((XMotionEvent *)&event)->y_root; + setmousestate (0, 0, tx, 0); + setmousestate (0, 1, ty, 0); } else if (grabbed) { int realmove = 0; - int tx, ty; - + int tx, ty,ttx,tty; + tx = ((XMotionEvent *)&event)->x; ty = ((XMotionEvent *)&event)->y; - if (! event.xmotion.send_event) { - newmousecounters = 0; - lastmx += tx - oldx; - lastmy += ty - oldy; + setmousestate (0, 0, tx - oldx, 0); + setmousestate (0, 1, ty - oldy, 0); realmove = 1; #undef ABS #define ABS(a) (((a)<0) ? -(a) : (a) ) if (ABS(current_width / 2 - tx) > 3 * current_width / 8 - || ABS(current_height / 2 - ty) > 3 * current_height / 8) + || ABS(current_height / 2 - ty) > 3 * current_height / 8) { #undef ABS XEvent event; - tx = current_width / 2; - ty = current_height / 2; + ttx = current_width / 2; + tty = current_height / 2; event.type = MotionNotify; event.xmotion.display = display; event.xmotion.window = mywin; - event.xmotion.x = tx; - event.xmotion.y = ty; + event.xmotion.x = ttx; + event.xmotion.y = tty; XSendEvent (display, mywin, False, PointerMotionMask, &event); - XWarpPointer (display, None, mywin, 0, 0, 0, 0, tx, ty); + XWarpPointer (display, None, mywin, 0, 0, 0, 0, ttx, tty); } + } else { + tx = event.xmotion.x; + ty = event.xmotion.y; } oldx = tx; oldy = ty; } else if (inwindow) { - lastmx = ((XMotionEvent *)&event)->x; - lastmy = ((XMotionEvent *)&event)->y; + int tx = ((XMotionEvent *)&event)->x; + int ty = ((XMotionEvent *)&event)->y; + setmousestate(0, 0, tx, 1); + setmousestate(0, 1, ty, 1); if (! cursorOn && !currprefs.x11_hide_cursor) { XDefineCursor(display, mywin, xhairCursor); cursorOn = 1; } gettimeofday(&lastMotionTime, NULL); } - - if (ievent_alive) { - if (lastmx < 0) - lastmx = 0; - if (lastmx > current_width) - lastmx = current_width; - if (lastmy < 0) - lastmy = 0; - if (lastmy > current_height) - lastmy = current_height; - } break; case EnterNotify: - newmousecounters = 1; - lastmx = ((XCrossingEvent *)&event)->x; - lastmy = ((XCrossingEvent *)&event)->y; + { + int tx = ((XCrossingEvent *)&event)->x; + int ty = ((XCrossingEvent *)&event)->y; + setmousestate (0, 0, tx, 1); + setmousestate (0, 1, ty, 1); + } inwindow = 1; break; case LeaveNotify: @@ -1507,11 +1171,11 @@ void handle_events (void) case Expose: refresh_necessary = 1; break; - case ClientMessage: - if (event.xclient.data.l[0]==delete_win) { + case ClientMessage: + if (((Atom)event.xclient.data.l[0]) == delete_win) { uae_quit (); - } - break; + } + break; } } @@ -1549,10 +1213,10 @@ void handle_events (void) picasso_invalid_start = picasso_vidinfo.height + 1; picasso_invalid_stop = -1; #endif - + if (! dgamode) { if (! screen_is_picasso && refresh_necessary) { - DO_PUTIMAGE (ami_dinfo.ximg, 0, 0, 0, 0, currprefs.gfx_width, currprefs.gfx_height); + DO_PUTIMAGE (ami_dinfo.ximg, 0, 0, 0, 0, current_width, current_height); refresh_necessary = 0; } if (cursorOn && !currprefs.x11_hide_cursor) { @@ -1567,49 +1231,6 @@ void handle_events (void) } } } - /* "Affengriff" */ - if ((keystate[AK_CTRL] || keystate[AK_RCTRL]) && keystate[AK_LAMI] && keystate[AK_RAMI]) - uae_reset (); -} - -int check_prefs_changed_gfx (void) -{ - if (changed_prefs.gfx_width != currprefs.gfx_width - || changed_prefs.gfx_height != currprefs.gfx_height) - fixup_prefs_dimensions (&changed_prefs); - - if (changed_prefs.gfx_width == currprefs.gfx_width - && changed_prefs.gfx_height == currprefs.gfx_height - && changed_prefs.gfx_lores == currprefs.gfx_lores - && changed_prefs.gfx_linedbl == currprefs.gfx_linedbl - && changed_prefs.gfx_correct_aspect == currprefs.gfx_correct_aspect - && changed_prefs.gfx_xcenter == currprefs.gfx_xcenter - && changed_prefs.gfx_ycenter == currprefs.gfx_ycenter - && changed_prefs.gfx_afullscreen == currprefs.gfx_afullscreen - && changed_prefs.gfx_pfullscreen == currprefs.gfx_pfullscreen) - return 0; - - graphics_subshutdown (); - currprefs.gfx_width = changed_prefs.gfx_width; - currprefs.gfx_height = changed_prefs.gfx_height; - currprefs.gfx_lores = changed_prefs.gfx_lores; - currprefs.gfx_linedbl = changed_prefs.gfx_linedbl; - currprefs.gfx_correct_aspect = changed_prefs.gfx_correct_aspect; - currprefs.gfx_xcenter = changed_prefs.gfx_xcenter; - currprefs.gfx_ycenter = changed_prefs.gfx_ycenter; - currprefs.gfx_afullscreen = changed_prefs.gfx_afullscreen; - currprefs.gfx_pfullscreen = changed_prefs.gfx_pfullscreen; - graphics_subinit (); - - if (! inwindow) - XWarpPointer (display, None, mywin, 0, 0, 0, 0, - current_width / 2, current_height / 2); - - notice_screen_contents_lost (); - init_row_map (); - if (screen_is_picasso) - picasso_enablescreen (1); - return 0; } int debuggable (void) @@ -1619,12 +1240,17 @@ int debuggable (void) int needmousehack (void) { - if (dgamode) + if (dgamode || grabbed) return 0; else return 1; } +int mousehack_allowed (void) +{ + return 1; +} + void LED (int on) { #if 0 /* Maybe that is responsible for the joystick emulation problems on SunOS? */ @@ -1656,7 +1282,7 @@ void DX_Invalidate (int first, int last) while (first <= last) { picasso_invalid_lines[first] = 1; first++; - } + } } int DX_BitsPerCannon (void) @@ -1664,7 +1290,10 @@ int DX_BitsPerCannon (void) return 8; } -void DX_SetPalette (int start, int count) +static int palette_update_start=256; +static int palette_update_end=0; + +static void DX_SetPalette_real (int start, int count) { if (! screen_is_picasso || picasso96_state.RGBFormat != RGBFB_CHUNKY) return; @@ -1681,7 +1310,7 @@ void DX_SetPalette (int start, int count } return; } - + while (count-- > 0) { XColor col = parsed_xcolors[start]; col.red = picasso96_state.CLUT[start].Red * 0x0101; @@ -1701,11 +1330,49 @@ void DX_SetPalette (int start, int count } #endif } +void DX_SetPalette (int start, int count) +{ + DX_SetPalette_real (start, count); +} + +static void DX_SetPalette_delayed (int start, int count) +{ + if (bit_unit!=8) { + DX_SetPalette_real(start,count); + return; + } + if (startpalette_update_end) + palette_update_end=start+count; +} + +void DX_SetPalette_vsync(void) +{ + if (palette_update_end>palette_update_start) { + DX_SetPalette_real(palette_update_start, + palette_update_end-palette_update_start); + palette_update_end=0; + palette_update_start=256; + } +} + +int DX_Fill (int dstx, int dsty, int width, int height, uae_u32 color, RGBFTYPE rgbtype) +{ + /* not implemented yet */ + return 0; +} + +int DX_Blit (int srcx, int srcy, int dstx, int dsty, int width, int height, BLIT_OPCODE opcode) +{ + /* not implemented yet */ + return 0; +} -#define MAX_SCREEN_MODES 11 +#define MAX_SCREEN_MODES 12 -static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 320, 640, 640, 640, 800, 1024, 1152, 1280 }; -static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 256, 400, 350, 480, 512, 600, 768, 864, 1024 }; +static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 320, 640, 640, 640, 800, 1024, 1152, 1280, 1280 }; +static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 256, 400, 350, 480, 512, 600, 768, 864, 960, 1024 }; int DX_FillResolutions (uae_u16 *ppixel_format) { @@ -1715,15 +1382,30 @@ int DX_FillResolutions (uae_u16 *ppixel_ int h = HeightOfScreen (scr); int emulate_chunky = 0; + /* we now need to find display depth first */ + XVisualInfo vi; + if (!get_best_visual (&vi)) return 0; + bitdepth = vi.depth; + bit_unit = get_visual_bit_unit (&vi, bitdepth); + + if (ImageByteOrder (display) == LSBFirst) { picasso_vidinfo.rgbformat = (bit_unit == 8 ? RGBFB_CHUNKY : bitdepth == 15 && bit_unit == 16 ? RGBFB_R5G5B5PC : bitdepth == 16 && bit_unit == 16 ? RGBFB_R5G6B5PC : bit_unit == 24 ? RGBFB_B8G8R8 : bit_unit == 32 ? RGBFB_B8G8R8A8 : RGBFB_NONE); + } else { + picasso_vidinfo.rgbformat = (bit_unit == 8 ? RGBFB_CHUNKY + : bitdepth == 15 && bit_unit == 16 ? RGBFB_R5G5B5 + : bitdepth == 16 && bit_unit == 16 ? RGBFB_R5G6B5 + : bit_unit == 24 ? RGBFB_R8G8B8 + : bit_unit == 32 ? RGBFB_A8R8G8B8 + : RGBFB_NONE); + } *ppixel_format = 1 << picasso_vidinfo.rgbformat; - if (visualInfo.VI_CLASS == TrueColor && (bit_unit == 16 || bit_unit == 32)) + if (vi.VI_CLASS == TrueColor && (bit_unit == 16 || bit_unit == 32)) *ppixel_format |= RGBFF_CHUNKY, emulate_chunky = 1; #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION @@ -1762,53 +1444,6 @@ int DX_FillResolutions (uae_u16 *ppixel_ return count; } -static void set_window_for_picasso (void) -{ - if (current_width == picasso_vidinfo.width && current_height == picasso_vidinfo.height) - return; - - current_width = picasso_vidinfo.width; - current_height = picasso_vidinfo.height; - XResizeWindow (display, mywin, current_width, current_height); -#if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION - if (dgamode && vidmodeavail) - switch_to_best_mode (); -#endif -} - -void gfx_set_picasso_modeinfo (int w, int h, int depth, int rgbfmt) -{ - picasso_vidinfo.width = w; - picasso_vidinfo.height = h; - picasso_vidinfo.depth = depth; - picasso_vidinfo.pixbytes = bit_unit >> 3; - - if (screen_is_picasso) - set_window_for_picasso (); -} - -void gfx_set_picasso_baseaddr (uaecptr a) -{ -} - -void gfx_set_picasso_state (int on) -{ - if (on == screen_is_picasso) - return; - graphics_subshutdown (); - screen_is_picasso = on; - if (on) { - current_width = picasso_vidinfo.width; - current_height = picasso_vidinfo.height; - } else { - current_width = gfxvidinfo.width; - current_height = gfxvidinfo.height; - } - graphics_subinit (); - if (on) - DX_SetPalette (0, 256); -} - uae_u8 *gfx_lock_picasso (void) { #ifdef USE_DGA_EXTENSION @@ -1818,6 +1453,7 @@ uae_u8 *gfx_lock_picasso (void) #endif return pic_dinfo.ximg->data; } + void gfx_unlock_picasso (void) { } @@ -1832,11 +1468,12 @@ void unlockscr (void) { } -static void handle_mousegrab (void) +void toggle_mousegrab (void) { if (grabbed) { XUngrabPointer (display, CurrentTime); XUndefineCursor (display, mywin); + reset_cursor (); grabbed = 0; } else if (! dgamode) { XGrabPointer (display, mywin, 1, 0, GrabModeAsync, GrabModeAsync, @@ -1848,59 +1485,232 @@ static void handle_mousegrab (void) } } -static void handle_inhibit (void) +void framerate_up (void) +{ + if (currprefs.gfx_framerate < 20) + changed_prefs.gfx_framerate = currprefs.gfx_framerate + 1; +} + +void framerate_down (void) { - toggle_inhibit_frame (IHF_SCROLLLOCK); + if (currprefs.gfx_framerate > 1) + changed_prefs.gfx_framerate = currprefs.gfx_framerate - 1; } -#include "gensound.h" -#include "sounddep/sound.h" -#include "events.h" -#include "audio.h" +int is_fullscreen (void) +{ +#ifdef USE_DGA_EXTENSION + return dgamode; +#else + return 0; +#endif +} -static void handle_interpol (void) +void toggle_fullscreen (void) { - if (currprefs.sound_interpol == 0) { - currprefs.sound_interpol = 1; - printf ("Interpol on: rh\n"); +#ifdef USE_DGA_EXTENSION + changed_prefs.gfx_afullscreen = changed_prefs.gfx_pfullscreen = !dgamode; +#endif +} + +void screenshot (int type) +{ + write_log ("Screenshot not implemented yet\n"); +} + +/* + * Mouse inputdevice functions + */ + +/* Hardwire for 3 axes and 3 buttons + * There is no 3rd axis as such - mousewheel events are + * supplied by X on buttons 4 and 5. + */ +#define MAX_BUTTONS 3 +#define MAX_AXES 3 +#define FIRST_AXIS 0 +#define FIRST_BUTTON MAX_AXES + +static int init_mouse (void) +{ + return 1; +} + +static void close_mouse (void) +{ + return; +} + +static int acquire_mouse (unsigned int num, int flags) +{ + return 1; +} + +static void unacquire_mouse (unsigned int num) +{ + return; +} + +static int get_mouse_num (void) +{ + return 1; +} + +static const char *get_mouse_name (unsigned int mouse) +{ + return 0; +} + +static int get_mouse_widget_num (unsigned int mouse) +{ + return MAX_AXES + MAX_BUTTONS; +} + +static int get_mouse_widget_first (unsigned int mouse, int type) +{ + switch (type) { + case IDEV_WIDGET_BUTTON: + return FIRST_BUTTON; + case IDEV_WIDGET_AXIS: + return FIRST_AXIS; } - else if (currprefs.sound_interpol == 1) { - currprefs.sound_interpol = 2; - printf ("Interpol on: crux\n"); + return -1; +} + +static int get_mouse_widget_type (unsigned int mouse, unsigned int num, char *name, uae_u32 *code) +{ + if (num >= MAX_AXES && num < MAX_AXES + MAX_BUTTONS) { + if (name) + sprintf (name, "Button %d", num + 1 + MAX_AXES); + return IDEV_WIDGET_BUTTON; + } else if (num < MAX_AXES) { + if (name) + sprintf (name, "Axis %d", num + 1); + return IDEV_WIDGET_AXIS; } - else { - currprefs.sound_interpol = 0; - printf ("Interpol off\n"); - } + return IDEV_WIDGET_NONE; } -static void framerate_up (void) +static void read_mouse (void) { - if (currprefs.gfx_framerate < 20) - changed_prefs.gfx_framerate = currprefs.gfx_framerate + 1; + /* We handle mouse input in handle_events() */ } -static void framerate_down (void) +struct inputdevice_functions inputdevicefunc_mouse = { + init_mouse, close_mouse, acquire_mouse, unacquire_mouse, read_mouse, + get_mouse_num, get_mouse_name, + get_mouse_widget_num, get_mouse_widget_type, + get_mouse_widget_first +}; + +/* + * Keyboard inputdevice functions + */ +static int get_kb_num (void) { - if (currprefs.gfx_framerate > 1) - changed_prefs.gfx_framerate = currprefs.gfx_framerate - 1; + return 1; } -static void handle_modeswitch (void) +static const char *get_kb_name (unsigned int kb) { - changed_prefs.gfx_afullscreen = changed_prefs.gfx_pfullscreen = !dgamode; + return "Default keyboard"; } -void target_save_options (FILE *f, struct uae_prefs *p) +static int get_kb_widget_num (unsigned int kb) +{ + return 255; // fix me +} + +static int get_kb_widget_first (unsigned int kb, int type) +{ + return 0; +} + +static int get_kb_widget_type (unsigned int kb, unsigned int num, char *name, uae_u32 *code) +{ + // fix me + *code = num; + return IDEV_WIDGET_KEY; +} + +static int keyhack (int scancode, int pressed, int num) +{ + return scancode; +} + +static void read_kb (void) +{ +} +static int init_kb (void) +{ + set_default_hotkeys (get_x11_default_hotkeys()); + return 1; +} + +static void close_kb (void) +{ +} + +static int acquire_kb (unsigned int num, int flags) +{ + return 1; +} + +static void unacquire_kb (unsigned int num) +{ +} + +/* + * Default inputdevice config for X11 mouse + */ +void input_get_default_mouse (struct uae_input_device *uid) +{ + /* Supports only one mouse */ + uid[0].eventid[ID_AXIS_OFFSET + 0][0] = INPUTEVENT_MOUSE1_HORIZ; + uid[0].eventid[ID_AXIS_OFFSET + 1][0] = INPUTEVENT_MOUSE1_VERT; + uid[0].eventid[ID_AXIS_OFFSET + 2][0] = INPUTEVENT_MOUSE1_WHEEL; + uid[0].eventid[ID_BUTTON_OFFSET + 0][0] = INPUTEVENT_JOY1_FIRE_BUTTON; + uid[0].eventid[ID_BUTTON_OFFSET + 1][0] = INPUTEVENT_JOY1_2ND_BUTTON; + uid[0].eventid[ID_BUTTON_OFFSET + 2][0] = INPUTEVENT_JOY1_3RD_BUTTON; + uid[0].enabled = 1; +} + +struct inputdevice_functions inputdevicefunc_keyboard = +{ + init_kb, close_kb, acquire_kb, unacquire_kb, + read_kb, get_kb_num, get_kb_name, get_kb_widget_num, + get_kb_widget_type, get_kb_widget_first +}; + +int getcapslockstate (void) +{ + return 0; +} + +void setcapslockstate (int state) +{ +} + +/* + * Handle gfx cfgfile options + */ +void target_save_options (FILE *f, const struct uae_prefs *p) { fprintf (f, "x11.low_bandwidth=%s\n", p->x11_use_low_bandwidth ? "true" : "false"); fprintf (f, "x11.use_mitshm=%s\n", p->x11_use_mitshm ? "true" : "false"); fprintf (f, "x11.hide_cursor=%s\n", p->x11_hide_cursor ? "true" : "false"); } -int target_parse_option (struct uae_prefs *p, char *option, char *value) +int target_parse_option (struct uae_prefs *p, const char *option, const char *value) { return (cfgfile_yesno (option, value, "low_bandwidth", &p->x11_use_low_bandwidth) || cfgfile_yesno (option, value, "use_mitshm", &p->x11_use_mitshm) || cfgfile_yesno (option, value, "hide_cursor", &p->x11_hide_cursor)); } + +void target_default_options (struct uae_prefs *p) +{ + p->x11_use_low_bandwidth = 0; + p->x11_use_mitshm = 1; + p->x11_hide_cursor = 1; +}