diff options
Diffstat (limited to 'hw/kdrive/ephyr/hostx.c')
-rw-r--r-- | hw/kdrive/ephyr/hostx.c | 564 |
1 files changed, 0 insertions, 564 deletions
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c deleted file mode 100644 index af8b10b97..000000000 --- a/hw/kdrive/ephyr/hostx.c +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Xephyr - A kdrive X server thats runs in a host X window. - * Authored by Matthew Allum <mallum@o-hand.com> - * - * Copyright © 2004 Nokia - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Nokia not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Nokia makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#include "hostx.h" - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> /* for memset */ -#include <time.h> - -#include <sys/ipc.h> -#include <sys/shm.h> -#include <sys/time.h> - -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/Xatom.h> -#include <X11/extensions/XShm.h> - -/* - * All xlib calls go here, which gets built as its own .a . - * Mixing kdrive and xlib headers causes all sorts of types - * to get clobbered. - */ - -struct EphyrHostXVars -{ - Display *dpy; - int screen; - Visual *visual; - Window win, winroot; - Window win_pre_existing; /* Set via -parent option like xnest */ - GC gc; - int depth; - XImage *ximg; - int win_width, win_height; - Bool use_host_cursor; - Bool have_shm; - long damage_debug_msec; - - XShmSegmentInfo shminfo; -}; - -static EphyrHostXVars HostX = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; /* defaults */ - -static int HostXWantDamageDebug = 0; - -extern KeySym EphyrKeymap[]; - -extern KeySym kdKeymap[]; -extern int kdMinScanCode; -extern int kdMaxScanCode; -extern int kdMinKeyCode; -extern int kdMaxKeyCode; -extern int kdKeymapWidth; -extern int monitorResolution; - -/* X Error traps */ - -static int trapped_error_code = 0; -static int (*old_error_handler) (Display *d, XErrorEvent *e); - -static int -error_handler(Display *display, - XErrorEvent *error) -{ - trapped_error_code = error->error_code; - return 0; -} - -static void -hostx_errors_trap(void) -{ - trapped_error_code = 0; - old_error_handler = XSetErrorHandler(error_handler); -} - -static int -hostx_errors_untrap(void) -{ - XSetErrorHandler(old_error_handler); - return trapped_error_code; -} - -int -hostx_want_screen_size(int *width, int *height) -{ - if (HostX.win_pre_existing != None) - { - *width = HostX.win_width; - *height = HostX.win_height; - return 1; - } - - return 0; -} - -int -hostx_want_host_cursor(void) -{ - return HostX.use_host_cursor; -} - -void -hostx_use_host_cursor(void) -{ - HostX.use_host_cursor = True; -} - -int -hostx_want_preexisting_window(void) -{ - if (HostX.win_pre_existing) - return 1; - else - return 0; -} - -void -hostx_use_preexisting_window(unsigned long win_id) -{ - HostX.win_pre_existing = win_id; -} - -static void -hostx_toggle_damage_debug(void) -{ - HostXWantDamageDebug ^= 1; -} - -void -hostx_handle_signal(int signum) -{ - hostx_toggle_damage_debug(); - EPHYR_DBG("Signal caught. Damage Debug:%i\n", HostXWantDamageDebug); -} - -int -hostx_init(void) -{ - XSetWindowAttributes attr; - Cursor empty_cursor; - Pixmap cursor_pxm; - XColor col; - - attr.event_mask = - ButtonPressMask - |ButtonReleaseMask - |PointerMotionMask - |KeyPressMask - |KeyReleaseMask - |ExposureMask; - - EPHYR_DBG("mark"); - - if ((HostX.dpy = XOpenDisplay(getenv("DISPLAY"))) == NULL) - { - fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n"); - exit(1); - } - - HostX.screen = DefaultScreen(HostX.dpy); - HostX.winroot = RootWindow(HostX.dpy, HostX.screen); - HostX.gc = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL); - HostX.depth = DefaultDepth(HostX.dpy, HostX.screen); - HostX.visual = DefaultVisual(HostX.dpy, HostX.screen); - - /* old way of getting dpi - HostX.mm_per_pixel_vertical = (double)DisplayHeightMM(HostX.dpy, HostX.screen) - / DisplayHeight(HostX.dpy, HostX.screen); - - HostX.mm_per_pixel_horizontal = (double)DisplayWidthMM(HostX.dpy, HostX.screen) - / DisplayWidth(HostX.dpy, HostX.screen); - */ - - if (HostX.win_pre_existing != None) - { - Status result; - XWindowAttributes prewin_attr; - - /* Get screen size from existing window */ - - HostX.win = HostX.win_pre_existing; - - hostx_errors_trap(); - - result = XGetWindowAttributes(HostX.dpy, HostX.win, &prewin_attr); - - if (hostx_errors_untrap() || !result) - { - fprintf(stderr, "\nXephyr -parent window' does not exist!\n"); - exit(1); - } - - HostX.win_width = prewin_attr.width; - HostX.win_height = prewin_attr.height; - - XSelectInput(HostX.dpy, HostX.win, attr.event_mask); - } - else - { - HostX.win = XCreateWindow(HostX.dpy, - HostX.winroot, - 0,0,100,100, /* will resize */ - 0, - CopyFromParent, - CopyFromParent, - CopyFromParent, - CWEventMask, - &attr); - - XStoreName(HostX.dpy, HostX.win, "Xephyr"); - } - - HostX.gc = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL); - - XParseColor(HostX.dpy, DefaultColormap(HostX.dpy,HostX.screen), "red", &col); - XAllocColor(HostX.dpy, DefaultColormap(HostX.dpy, HostX.screen), &col); - XSetForeground(HostX.dpy, HostX.gc, col.pixel); - - if (!hostx_want_host_cursor()) - { - /* Ditch the cursor, we provide our 'own' */ - cursor_pxm = XCreatePixmap (HostX.dpy, HostX.winroot, 1, 1, 1); - memset (&col, 0, sizeof (col)); - empty_cursor = XCreatePixmapCursor (HostX.dpy, - cursor_pxm, cursor_pxm, - &col, &col, 1, 1); - XDefineCursor (HostX.dpy, HostX.win, empty_cursor); - XFreePixmap (HostX.dpy, cursor_pxm); - } - - HostX.ximg = NULL; - - /* Try to get share memory ximages for a little bit more speed */ - - if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM")) - { - fprintf(stderr, "\nXephyr unable to use SHM XImages\n"); - HostX.have_shm = False; - } - else - { - /* Really really check we have shm - better way ?*/ - XShmSegmentInfo shminfo; - - HostX.have_shm = True; - - shminfo.shmid=shmget(IPC_PRIVATE, 1, IPC_CREAT|0777); - shminfo.shmaddr=shmat(shminfo.shmid,0,0); - shminfo.readOnly=True; - - hostx_errors_trap(); - - XShmAttach(HostX.dpy, &shminfo); - XSync(HostX.dpy, False); - - if (hostx_errors_untrap()) - { - fprintf(stderr, "\nXephyr unable to use SHM XImages\n"); - HostX.have_shm = False; - } - - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid, IPC_RMID, 0); - } - - XFlush(HostX.dpy); - - /* Setup the pause time between paints when debugging updates */ - - HostX.damage_debug_msec = 20000; /* 1/50 th of a second */ - - if (getenv("XEPHYR_PAUSE")) - { - HostX.damage_debug_msec = strtol(getenv("XEPHYR_PAUSE"), NULL, 0); - EPHYR_DBG("pause is %li\n", HostX.damage_debug_msec); - } - - return 1; -} - -int -hostx_get_depth (void) -{ - return HostX.depth; -} - -int -hostx_get_bpp(void) -{ - return HostX.visual->bits_per_rgb; -} - -void -hostx_get_visual_masks (unsigned long *rmsk, - unsigned long *gmsk, - unsigned long *bmsk) -{ - *rmsk = HostX.visual->red_mask; - *gmsk = HostX.visual->green_mask; - *bmsk = HostX.visual->blue_mask; -} - - -void* -hostx_screen_init (int width, int height) -{ - int bitmap_pad; - Bool shm_success = False; - XSizeHints *size_hints; - - EPHYR_DBG("mark"); - - if (HostX.ximg != NULL) - { - /* Free up the image data if previously used - * i.ie called by server reset - */ - - if (HostX.have_shm) - { - XShmDetach(HostX.dpy, &HostX.shminfo); - XDestroyImage (HostX.ximg); - shmdt(HostX.shminfo.shmaddr); - shmctl(HostX.shminfo.shmid, IPC_RMID, 0); - } - else - { - if (HostX.ximg->data) - { - free(HostX.ximg->data); - HostX.ximg->data = NULL; - } - - XDestroyImage(HostX.ximg); - } - } - - if (HostX.have_shm) - { - HostX.ximg = XShmCreateImage(HostX.dpy, HostX.visual, HostX.depth, - ZPixmap, NULL, &HostX.shminfo, - width, height ); - - HostX.shminfo.shmid = shmget(IPC_PRIVATE, - HostX.ximg->bytes_per_line * height, - IPC_CREAT|0777); - HostX.shminfo.shmaddr = HostX.ximg->data = shmat(HostX.shminfo.shmid, - 0, 0); - - if (HostX.ximg->data == (char *)-1) - { - EPHYR_DBG("Can't attach SHM Segment, falling back to plain XImages"); - HostX.have_shm = False; - XDestroyImage(HostX.ximg); - shmctl(HostX.shminfo.shmid, IPC_RMID, 0); - } - else - { - EPHYR_DBG("SHM segment attached"); - HostX.shminfo.readOnly = False; - XShmAttach(HostX.dpy, &HostX.shminfo); - shm_success = True; - } - } - - if (!shm_success) - { - bitmap_pad = ( HostX.depth > 16 )? 32 : (( HostX.depth > 8 )? 16 : 8 ); - - HostX.ximg = XCreateImage( HostX.dpy, - HostX.visual, - HostX.depth, - ZPixmap, 0, 0, - width, - height, - bitmap_pad, - 0); - - HostX.ximg->data = malloc( HostX.ximg->bytes_per_line * height ); - } - - - XResizeWindow(HostX.dpy, HostX.win, width, height); - - /* Ask the WM to keep our size static */ - size_hints = XAllocSizeHints(); - size_hints->max_width = size_hints->min_width = width; - size_hints->max_height = size_hints->min_height = height; - size_hints->flags = PMinSize|PMaxSize; - XSetWMNormalHints(HostX.dpy, HostX.win, size_hints); - XFree(size_hints); - - XMapWindow(HostX.dpy, HostX.win); - - XSync(HostX.dpy, False); - - HostX.win_width = width; - HostX.win_height = height; - - return HostX.ximg->data; -} - -void -hostx_paint_rect(int sx, int sy, - int dx, int dy, - int width, int height) -{ - /* - * Copy the image data updated by the shadow layer - * on to the window - */ - - if (HostXWantDamageDebug) - { - hostx_paint_debug_rect(dx, dy, width, height); - } - - if (HostX.have_shm) - { - XShmPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg, - sx, sy, dx, dy, width, height, False); - } - else - { - XPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg, - sx, sy, dx, dy, width, height); - } - - XSync(HostX.dpy, False); -} - -void -hostx_paint_debug_rect(int x, int y, - int width, int height) -{ - struct timespec tspec; - - tspec.tv_sec = HostX.damage_debug_msec / (1000000); - tspec.tv_nsec = (HostX.damage_debug_msec % 1000000) * 1000; - - EPHYR_DBG("msec: %li tv_sec %li, tv_msec %li", - HostX.damage_debug_msec, tspec.tv_sec, tspec.tv_nsec); - - XFillRectangle(HostX.dpy, HostX.win, HostX.gc, x, y, width,height); - XSync(HostX.dpy, False); - - /* nanosleep seems to work better than usleep for me... */ - nanosleep(&tspec, NULL); -} - -void -hostx_load_keymap(void) -{ - KeySym *keymap; - int mapWidth, min_keycode, max_keycode; - - XDisplayKeycodes(HostX.dpy, &min_keycode, &max_keycode); - - EPHYR_DBG("min: %d, max: %d", min_keycode, max_keycode); - - keymap = XGetKeyboardMapping(HostX.dpy, - min_keycode, - max_keycode - min_keycode + 1, - &mapWidth); - - memcpy (kdKeymap, keymap, - (max_keycode - min_keycode + 1)*mapWidth*sizeof(KeySym)); - - EPHYR_DBG("keymap width: %d", mapWidth); - - /* all kdrive vars - see kkeymap.c */ - - kdMinScanCode = min_keycode; - kdMaxScanCode = max_keycode; - kdMinKeyCode = min_keycode; - kdMaxKeyCode = max_keycode; - kdKeymapWidth = mapWidth; - - XFree(keymap); -} - -int -hostx_get_event(EphyrHostXEvent *ev) -{ - XEvent xev; - - if (XPending(HostX.dpy)) - { - XNextEvent(HostX.dpy, &xev); - - switch (xev.type) - { - case Expose: - /* Not so great event compression, but works ok */ - while (XCheckTypedWindowEvent(HostX.dpy, xev.xexpose.window, - Expose, &xev)); - hostx_paint_rect(0, 0, 0, 0, HostX.win_width, HostX.win_height); - return 0; - - case MotionNotify: - ev->type = EPHYR_EV_MOUSE_MOTION; - ev->data.mouse_motion.x = xev.xmotion.x; - ev->data.mouse_motion.y = xev.xmotion.y; - return 1; - - case ButtonPress: - ev->type = EPHYR_EV_MOUSE_PRESS; - /* - * This is a bit hacky. will break for button 5 ( defined as 0x10 ) - * Check KD_BUTTON defines in kdrive.h - */ - ev->data.mouse_down.button_num = 1<<(xev.xbutton.button-1); - return 1; - - case ButtonRelease: - ev->type = EPHYR_EV_MOUSE_RELEASE; - ev->data.mouse_up.button_num = 1<<(xev.xbutton.button-1); - return 1; - - case KeyPress: - { - ev->type = EPHYR_EV_KEY_PRESS; - ev->data.key_down.scancode = xev.xkey.keycode; - return 1; - } - case KeyRelease: - ev->type = EPHYR_EV_KEY_RELEASE; - ev->data.key_up.scancode = xev.xkey.keycode; - - return 1; - - default: - break; - - } - } - return 0; -} - |