diff options
Diffstat (limited to 'xorg-server/hw/kdrive')
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyr.c | 2363 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyr.h | 4 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyrinit.c | 830 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyrlog.h | 4 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/hostx.c | 40 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/hostx.h | 4 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/makefile | 6 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/src/kdrive.c | 6 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/src/kinput.c | 4727 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/src/kmap.c | 9 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/src/makefile | 14 |
11 files changed, 4066 insertions, 3941 deletions
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c index 254fcbc54..87e48afaf 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.c +++ b/xorg-server/hw/kdrive/ephyr/ephyr.c @@ -1,1176 +1,1187 @@ -/* - * Xephyr - A kdrive X server thats runs in a host X window. - * Authored by Matthew Allum <mallum@openedhand.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. - */ - -#ifdef HAVE_CONFIG_H -#include <kdrive-config.h> -#endif -#include "ephyr.h" - -#include "inputstr.h" -#include "scrnintstr.h" -#include "ephyrlog.h" - -#ifdef XF86DRI -#include "ephyrdri.h" -#include "ephyrdriext.h" -#include "ephyrglxext.h" -#endif /* XF86DRI */ - -extern int KdTsPhyScreen; -#ifdef GLXEXT -extern Bool noGlxVisualInit; -#endif - -KdKeyboardInfo *ephyrKbd; -KdPointerInfo *ephyrMouse; -EphyrKeySyms ephyrKeySyms; -Bool ephyrNoDRI=FALSE ; -Bool ephyrNoXV=FALSE ; - -static int mouseState = 0; - -typedef struct _EphyrInputPrivate { - Bool enabled; -} EphyrKbdPrivate, EphyrPointerPrivate; - -Bool EphyrWantGrayScale = 0; - - -Bool -ephyrInitialize (KdCardInfo *card, EphyrPriv *priv) -{ - OsSignal(SIGUSR1, hostx_handle_signal); - - priv->base = 0; - priv->bytes_per_line = 0; - return TRUE; -} - -Bool -ephyrCardInit (KdCardInfo *card) -{ - EphyrPriv *priv; - - priv = (EphyrPriv *) xalloc (sizeof (EphyrPriv)); - if (!priv) - return FALSE; - - if (!ephyrInitialize (card, priv)) - { - xfree (priv); - return FALSE; - } - card->driver = priv; - - return TRUE; -} - -Bool -ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv) -{ - int width = 640, height = 480; - CARD32 redMask, greenMask, blueMask; - - if (hostx_want_screen_size(screen, &width, &height) - || !screen->width || !screen->height) - { - screen->width = width; - screen->height = height; - } - - if (EphyrWantGrayScale) - screen->fb[0].depth = 8; - - if (screen->fb[0].depth && screen->fb[0].depth != hostx_get_depth()) - { - if (screen->fb[0].depth < hostx_get_depth() - && (screen->fb[0].depth == 24 || screen->fb[0].depth == 16 - || screen->fb[0].depth == 8)) - { - hostx_set_server_depth(screen, screen->fb[0].depth); - } - else - ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n"); - } - - screen->fb[0].depth = hostx_get_server_depth(screen); - screen->rate = 72; - - if (screen->fb[0].depth <= 8) - { - if (EphyrWantGrayScale) - screen->fb[0].visuals = ((1 << StaticGray) | (1 << GrayScale)); - else - screen->fb[0].visuals = ((1 << StaticGray) | - (1 << GrayScale) | - (1 << StaticColor) | - (1 << PseudoColor) | - (1 << TrueColor) | - (1 << DirectColor)); - - screen->fb[0].redMask = 0x00; - screen->fb[0].greenMask = 0x00; - screen->fb[0].blueMask = 0x00; - screen->fb[0].depth = 8; - screen->fb[0].bitsPerPixel = 8; - } - else - { - screen->fb[0].visuals = (1 << TrueColor); - - if (screen->fb[0].depth <= 15) - { - screen->fb[0].depth = 15; - screen->fb[0].bitsPerPixel = 16; - } - else if (screen->fb[0].depth <= 16) - { - screen->fb[0].depth = 16; - screen->fb[0].bitsPerPixel = 16; - } - else if (screen->fb[0].depth <= 24) - { - screen->fb[0].depth = 24; - screen->fb[0].bitsPerPixel = 32; - } - else if (screen->fb[0].depth <= 30) - { - screen->fb[0].depth = 30; - screen->fb[0].bitsPerPixel = 32; - } - else - { - ErrorF("\nXephyr: Unsupported screen depth %d\n", - screen->fb[0].depth); - return FALSE; - } - - hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask); - - screen->fb[0].redMask = (Pixel) redMask; - screen->fb[0].greenMask = (Pixel) greenMask; - screen->fb[0].blueMask = (Pixel) blueMask; - - } - - scrpriv->randr = screen->randr; - - return ephyrMapFramebuffer (screen); -} - -Bool -ephyrScreenInit (KdScreenInfo *screen) -{ - EphyrScrPriv *scrpriv; - - scrpriv = xcalloc (1, sizeof (EphyrScrPriv)); - - if (!scrpriv) - return FALSE; - - screen->driver = scrpriv; - - if (!ephyrScreenInitialize (screen, scrpriv)) - { - screen->driver = 0; - xfree (scrpriv); - return FALSE; - } - - return TRUE; -} - -void* -ephyrWindowLinear (ScreenPtr pScreen, - CARD32 row, - CARD32 offset, - int mode, - CARD32 *size, - void *closure) -{ - KdScreenPriv(pScreen); - EphyrPriv *priv = pScreenPriv->card->driver; - - if (!pScreenPriv->enabled) - return 0; - - *size = priv->bytes_per_line; - return priv->base + row * priv->bytes_per_line + offset; -} - -Bool -ephyrMapFramebuffer (KdScreenInfo *screen) -{ - EphyrScrPriv *scrpriv = screen->driver; - EphyrPriv *priv = screen->card->driver; - KdPointerMatrix m; - int buffer_height; - - EPHYR_LOG("screen->width: %d, screen->height: %d index=%d", - screen->width, screen->height, screen->mynum); - - KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height); - KdSetPointerMatrix (&m); - - priv->bytes_per_line = ((screen->width * screen->fb[0].bitsPerPixel + 31) >> 5) << 2; - - /* point the framebuffer to the data in an XImage */ - /* If fakexa is enabled, allocate a larger buffer so that fakexa has space to - * put offscreen pixmaps. - */ - if (ephyrFuncs.initAccel == NULL) - buffer_height = screen->height; - else - buffer_height = 3 * screen->height; - - priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height); - - screen->memory_base = (CARD8 *) (priv->base); - screen->memory_size = priv->bytes_per_line * buffer_height; - screen->off_screen_base = priv->bytes_per_line * screen->height; - - if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All)) - { - scrpriv->shadow = FALSE; - - screen->fb[0].byteStride = priv->bytes_per_line; - screen->fb[0].pixelStride = screen->width; - screen->fb[0].frameBuffer = (CARD8 *) (priv->base); - } - else - { - /* Rotated/Reflected so we need to use shadow fb */ - scrpriv->shadow = TRUE; - - EPHYR_LOG("allocing shadow"); - - KdShadowFbAlloc (screen, 0, - scrpriv->randr & (RR_Rotate_90|RR_Rotate_270)); - } - - return TRUE; -} - -void -ephyrSetScreenSizes (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - - if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180)) - { - pScreen->width = screen->width; - pScreen->height = screen->height; - pScreen->mmWidth = screen->width_mm; - pScreen->mmHeight = screen->height_mm; - } - else - { - pScreen->width = screen->height; - pScreen->height = screen->width; - pScreen->mmWidth = screen->height_mm; - pScreen->mmHeight = screen->width_mm; - } -} - -Bool -ephyrUnmapFramebuffer (KdScreenInfo *screen) -{ - EphyrScrPriv *scrpriv = screen->driver; - - if (scrpriv->shadow) - KdShadowFbFree (screen, 0); - - /* Note, priv->base will get freed when XImage recreated */ - - return TRUE; -} - -void -ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - - EPHYR_LOG("slow paint"); - - /* FIXME: Slow Rotated/Reflected updates could be much - * much faster efficiently updating via tranforming - * pBuf->pDamage regions - */ - shadowUpdateRotatePacked(pScreen, pBuf); - hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height); -} - -static void -ephyrInternalDamageRedisplay (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - RegionPtr pRegion; - - if (!scrpriv || !scrpriv->pDamage) - return; - - pRegion = DamageRegion (scrpriv->pDamage); - - if (REGION_NOTEMPTY (pScreen, pRegion)) - { - int nbox; - BoxPtr pbox; - - nbox = REGION_NUM_RECTS (pRegion); - pbox = REGION_RECTS (pRegion); - - while (nbox--) - { - hostx_paint_rect(screen, - pbox->x1, pbox->y1, - pbox->x1, pbox->y1, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - pbox++; - } - DamageEmpty (scrpriv->pDamage); - } -} - -static void -ephyrInternalDamageBlockHandler (pointer data, - OSTimePtr pTimeout, - pointer pRead) -{ - ScreenPtr pScreen = (ScreenPtr) data; - - ephyrInternalDamageRedisplay (pScreen); -} - -static void -ephyrInternalDamageWakeupHandler (pointer data, int i, pointer LastSelectMask) -{ - /* FIXME: Not needed ? */ -} - -Bool -ephyrSetInternalDamage (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - PixmapPtr pPixmap = NULL; - - scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0, - (DamageDestroyFunc) 0, - DamageReportNone, - TRUE, - pScreen, - pScreen); - - if (!RegisterBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler, - ephyrInternalDamageWakeupHandler, - (pointer) pScreen)) - return FALSE; - - pPixmap = (*pScreen->GetScreenPixmap) (pScreen); - - DamageRegister (&pPixmap->drawable, scrpriv->pDamage); - - return TRUE; -} - -void -ephyrUnsetInternalDamage (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - PixmapPtr pPixmap = NULL; - - pPixmap = (*pScreen->GetScreenPixmap) (pScreen); - DamageUnregister (&pPixmap->drawable, scrpriv->pDamage); - DamageDestroy (scrpriv->pDamage); - - RemoveBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler, - ephyrInternalDamageWakeupHandler, - (pointer) pScreen); -} - -#ifdef RANDR -Bool -ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - RRScreenSizePtr pSize; - Rotation randr; - int n = 0; - - struct { int width, height; } sizes[] = - { - { 1600, 1200 }, - { 1400, 1050 }, - { 1280, 960 }, - { 1280, 1024 }, - { 1152, 864 }, - { 1024, 768 }, - { 832, 624 }, - { 800, 600 }, - { 720, 400 }, - { 480, 640 }, - { 640, 480 }, - { 640, 400 }, - { 320, 240 }, - { 240, 320 }, - { 160, 160 }, - { 0, 0 } - }; - - EPHYR_LOG("mark"); - - *rotations = RR_Rotate_All|RR_Reflect_All; - - if (!hostx_want_preexisting_window (screen) - && !hostx_want_fullscreen ()) /* only if no -parent switch */ - { - while (sizes[n].width != 0 && sizes[n].height != 0) - { - RRRegisterSize (pScreen, - sizes[n].width, - sizes[n].height, - (sizes[n].width * screen->width_mm)/screen->width, - (sizes[n].height *screen->height_mm)/screen->height - ); - n++; - } - } - - pSize = RRRegisterSize (pScreen, - screen->width, - screen->height, - screen->width_mm, - screen->height_mm); - - randr = KdSubRotation (scrpriv->randr, screen->randr); - - RRSetCurrentConfig (pScreen, randr, 0, pSize); - - return TRUE; -} - -Bool -ephyrRandRSetConfig (ScreenPtr pScreen, - Rotation randr, - int rate, - RRScreenSizePtr pSize) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - Bool wasEnabled = pScreenPriv->enabled; - EphyrScrPriv oldscr; - int oldwidth, oldheight, oldmmwidth, oldmmheight; - Bool oldshadow; - int newwidth, newheight; - - if (screen->randr & (RR_Rotate_0|RR_Rotate_180)) - { - newwidth = pSize->width; - newheight = pSize->height; - } - else - { - newwidth = pSize->height; - newheight = pSize->width; - } - - if (wasEnabled) - KdDisableScreen (pScreen); - - oldscr = *scrpriv; - - oldwidth = screen->width; - oldheight = screen->height; - oldmmwidth = pScreen->mmWidth; - oldmmheight = pScreen->mmHeight; - oldshadow = scrpriv->shadow; - - /* - * Set new configuration - */ - - scrpriv->randr = KdAddRotation (screen->randr, randr); - - ephyrUnmapFramebuffer (screen); - - screen->width = newwidth; - screen->height = newheight; - - if (!ephyrMapFramebuffer (screen)) - goto bail4; - - /* FIXME below should go in own call */ - - if (oldshadow) - KdShadowUnset (screen->pScreen); - else - ephyrUnsetInternalDamage(screen->pScreen); - - if (scrpriv->shadow) - { - if (!KdShadowSet (screen->pScreen, - scrpriv->randr, - ephyrShadowUpdate, - ephyrWindowLinear)) - goto bail4; - } - else - { - /* Without shadow fb ( non rotated ) we need - * to use damage to efficiently update display - * via signal regions what to copy from 'fb'. - */ - if (!ephyrSetInternalDamage(screen->pScreen)) - goto bail4; - } - - ephyrSetScreenSizes (screen->pScreen); - - /* - * Set frame buffer mapping - */ - (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen), - pScreen->width, - pScreen->height, - screen->fb[0].depth, - screen->fb[0].bitsPerPixel, - screen->fb[0].byteStride, - screen->fb[0].frameBuffer); - - /* set the subpixel order */ - - KdSetSubpixelOrder (pScreen, scrpriv->randr); - - if (wasEnabled) - KdEnableScreen (pScreen); - - return TRUE; - - bail4: - EPHYR_LOG("bailed"); - - ephyrUnmapFramebuffer (screen); - *scrpriv = oldscr; - (void) ephyrMapFramebuffer (screen); - - pScreen->width = oldwidth; - pScreen->height = oldheight; - pScreen->mmWidth = oldmmwidth; - pScreen->mmHeight = oldmmheight; - - if (wasEnabled) - KdEnableScreen (pScreen); - return FALSE; -} - -Bool -ephyrRandRInit (ScreenPtr pScreen) -{ - rrScrPrivPtr pScrPriv; - - if (!RRScreenInit (pScreen)) - return FALSE; - - pScrPriv = rrGetScrPriv(pScreen); - pScrPriv->rrGetInfo = ephyrRandRGetInfo; - pScrPriv->rrSetConfig = ephyrRandRSetConfig; - return TRUE; -} -#endif - -Bool -ephyrCreateColormap (ColormapPtr pmap) -{ - return fbInitializeColormap (pmap); -} - -Bool -ephyrInitScreen (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - - EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ; - hostx_set_screen_number (screen, pScreen->myNum); - hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ; - pScreen->CreateColormap = ephyrCreateColormap; - -#ifdef XV - if (!ephyrNoXV) { - if (!ephyrInitVideo (pScreen)) { - EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ; - } else { - EPHYR_LOG ("initialized xvideo okay\n") ; - } - } -#endif /*XV*/ - -#ifdef XF86DRI - if (!ephyrNoDRI && !hostx_has_dri ()) { - EPHYR_LOG ("host x does not support DRI. Disabling DRI forwarding\n") ; - ephyrNoDRI = TRUE ; -#ifdef GLXEXT - noGlxVisualInit = FALSE ; -#endif - } - if (!ephyrNoDRI) { - ephyrDRIExtensionInit (pScreen) ; - ephyrHijackGLXExtension () ; - } -#endif - -#ifdef GLXEXT - if (ephyrNoDRI) { - noGlxVisualInit = FALSE ; - } -#endif - - return TRUE; -} - -Bool -ephyrFinishInitScreen (ScreenPtr pScreen) -{ - /* FIXME: Calling this even if not using shadow. - * Seems harmless enough. But may be safer elsewhere. - */ - if (!shadowSetup (pScreen)) - return FALSE; - -#ifdef RANDR - if (!ephyrRandRInit (pScreen)) - return FALSE; -#endif - - return TRUE; -} - -Bool -ephyrCreateResources (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - - EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d", - pScreen, pScreen->myNum, scrpriv->shadow); - - if (scrpriv->shadow) - return KdShadowSet (pScreen, - scrpriv->randr, - ephyrShadowUpdate, - ephyrWindowLinear); - else - return ephyrSetInternalDamage(pScreen); -} - -void -ephyrPreserve (KdCardInfo *card) -{ -} - -Bool -ephyrEnable (ScreenPtr pScreen) -{ - return TRUE; -} - -Bool -ephyrDPMS (ScreenPtr pScreen, int mode) -{ - return TRUE; -} - -void -ephyrDisable (ScreenPtr pScreen) -{ -} - -void -ephyrRestore (KdCardInfo *card) -{ -} - -void -ephyrScreenFini (KdScreenInfo *screen) -{ - EphyrScrPriv *scrpriv = screen->driver; - if (scrpriv->shadow) { - KdShadowFbFree (screen, 0); - } - xfree(screen->driver); - screen->driver = NULL; -} - -/* - * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug. - * See https://bugs.freedesktop.org/show_bug.cgi?id=3030 - */ -void -ephyrUpdateModifierState(unsigned int state) -{ -#if 0 - DeviceIntPtr pkeydev; - KeyClassPtr keyc; - int i; - CARD8 mask; - - pkeydev = inputInfo.keyboard; - - if (!pkeydev) - return; - -/* This is pretty broken. - * - * What should happen is that focus out should do as a VT switch does in - * traditional servers: fake releases for all keys (and buttons too, come - * to think of it) currently down. Then, on focus in, get the state from - * the host, and fake keypresses for everything currently down. - * - * So I'm leaving this broken for a little while. Sorry, folks. - * - * -daniels - */ - - keyc = pkeydev->key; - - state = state & 0xff; - - if (keyc->state == state) - return; - - for (i = 0, mask = 1; i < 8; i++, mask <<= 1) - { - int key; - - /* Modifier is down, but shouldn't be */ - if ((keyc->state & mask) && !(state & mask)) - { - int count = keyc->modifierKeyCount[i]; - - for (key = 0; key < MAP_LENGTH; key++) - if (keyc->xkbInfo->desc->map->modmap[key] & mask) - { - int bit; - BYTE *kptr; - - kptr = &keyc->down[key >> 3]; - bit = 1 << (key & 7); - - if (*kptr & bit && ephyrKbd && - ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) - KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */ - - if (--count == 0) - break; - } - } - - /* Modifier shoud be down, but isn't */ - if (!(keyc->state & mask) && (state & mask)) - for (key = 0; key < MAP_LENGTH; key++) - if (keyc->xkbInfo->desc->map->modmap[key] & mask) - { - if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd && - ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) - KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */ - break; - } - } -#endif -} - -static void -ephyrBlockSigio (void) -{ - sigset_t set; - - sigemptyset (&set); - sigaddset (&set, SIGIO); - sigprocmask (SIG_BLOCK, &set, 0); -} - -static void -ephyrUnblockSigio (void) -{ - sigset_t set; - - sigemptyset (&set); - sigaddset (&set, SIGIO); - sigprocmask (SIG_UNBLOCK, &set, 0); -} - -static Bool -ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) -{ - return FALSE; -} - -static void -ephyrCrossScreen (ScreenPtr pScreen, Bool entering) -{ -} - -int ephyrCurScreen; /*current event screen*/ - -static void -ephyrWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ - ephyrBlockSigio (); - ephyrCurScreen = pScreen->myNum; - miPointerWarpCursor (inputInfo.pointer, pScreen, x, y); - ephyrUnblockSigio (); -} - -miPointerScreenFuncRec ephyrPointerScreenFuncs = -{ - ephyrCursorOffScreen, - ephyrCrossScreen, - ephyrWarpCursor, - NULL, - NULL -}; - -#ifdef XF86DRI -/** - * find if the remote window denoted by a_remote - * is paired with an internal Window within the Xephyr server. - * If the remove window is paired with an internal window, send an - * expose event to the client insterested in the internal window expose event. - * - * Pairing happens when a drawable inside Xephyr is associated with - * a GL surface in a DRI environment. - * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to - * know a paired window is created. - * - * This is useful to make GL drawables (only windows for now) handle - * expose events and send those events to clients. - */ -static void -ephyrExposePairedWindow (int a_remote) -{ - EphyrWindowPair *pair = NULL; - RegionRec reg; - ScreenPtr screen; - - if (!findWindowPairFromRemote (a_remote, &pair)) { - EPHYR_LOG ("did not find a pair for this window\n"); - return; - } - screen = pair->local->drawable.pScreen; - REGION_NULL (screen, ®); - REGION_COPY (screen, ®, &pair->local->clipList); - screen->WindowExposures (pair->local, ®, NullRegion); - REGION_UNINIT (screen, ®); -} -#endif /* XF86DRI */ - -void -ephyrPoll(void) -{ - EphyrHostXEvent ev; - - while (hostx_get_event(&ev)) - { - switch (ev.type) - { - case EPHYR_EV_MOUSE_MOTION: - if (!ephyrMouse || - !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) { - EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ; - continue; - } - { - if (ev.data.mouse_motion.screen >=0 - && (ephyrCurScreen != ev.data.mouse_motion.screen)) - { - EPHYR_LOG ("warping mouse cursor. " - "cur_screen%d, motion_screen:%d\n", - ephyrCurScreen, ev.data.mouse_motion.screen) ; - if (ev.data.mouse_motion.screen >= 0) - { - ephyrWarpCursor - (inputInfo.pointer, screenInfo.screens[ev.data.mouse_motion.screen], - ev.data.mouse_motion.x, - ev.data.mouse_motion.y ); - } - } - else - { - int x=0, y=0; -#ifdef XF86DRI - EphyrWindowPair *pair = NULL; -#endif - EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ; - x = ev.data.mouse_motion.x; - y = ev.data.mouse_motion.y; - EPHYR_LOG ("initial (x,y):(%d,%d)\n", x, y) ; -#ifdef XF86DRI - EPHYR_LOG ("is this window peered by a gl drawable ?\n") ; - if (findWindowPairFromRemote (ev.data.mouse_motion.window, - &pair)) - { - EPHYR_LOG ("yes, it is peered\n") ; - x += pair->local->drawable.x; - y += pair->local->drawable.y; - } - else - { - EPHYR_LOG ("no, it is not peered\n") ; - } - EPHYR_LOG ("final (x,y):(%d,%d)\n", x, y) ; -#endif - KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0); - } - } - break; - - case EPHYR_EV_MOUSE_PRESS: - if (!ephyrMouse || - !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) { - EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ; - continue; - } - EPHYR_LOG ("enqueuing mouse press:%d\n", ephyrCurScreen) ; - ephyrUpdateModifierState(ev.key_state); - mouseState |= ev.data.mouse_down.button_num; - KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0); - break; - - case EPHYR_EV_MOUSE_RELEASE: - if (!ephyrMouse || - !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) - continue; - ephyrUpdateModifierState(ev.key_state); - mouseState &= ~ev.data.mouse_up.button_num; - EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ; - KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0); - break; - - case EPHYR_EV_KEY_PRESS: - if (!ephyrKbd || - !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) - continue; - ephyrUpdateModifierState(ev.key_state); - KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_down.scancode, FALSE); - break; - - case EPHYR_EV_KEY_RELEASE: - if (!ephyrKbd || - !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) - continue; - KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE); - break; - -#ifdef XF86DRI - case EPHYR_EV_EXPOSE: - /* - * We only receive expose events when the expose event have - * be generated for a drawable that is a host X window managed - * by Xephyr. Host X windows managed by Xephyr exists for instance - * when Xephyr is asked to create a GL drawable in a DRI environment. - */ - ephyrExposePairedWindow (ev.data.expose.window); - break; -#endif /* XF86DRI */ - - default: - break; - } - } -} - -void -ephyrCardFini (KdCardInfo *card) -{ - EphyrPriv *priv = card->driver; - xfree (priv); -} - -void -ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) -{ - /* XXX Not sure if this is right */ - - EPHYR_LOG("mark"); - - while (n--) - { - pdefs->red = 0; - pdefs->green = 0; - pdefs->blue = 0; - pdefs++; - } - -} - -void -ephyrPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) -{ - int min, max, p; - - /* XXX Not sure if this is right */ - - min = 256; - max = 0; - - while (n--) - { - p = pdefs->pixel; - if (p < min) - min = p; - if (p > max) - max = p; - - hostx_set_cmap_entry(p, - pdefs->red >> 8, - pdefs->green >> 8, - pdefs->blue >> 8); - pdefs++; - } -} - -/* Mouse calls */ - -static Status -MouseInit (KdPointerInfo *pi) -{ - pi->driverPrivate = (EphyrPointerPrivate *) - xcalloc(sizeof(EphyrPointerPrivate), 1); - ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE; - pi->nAxes = 3; - pi->nButtons = 32; - if (pi->name) - xfree(pi->name); - pi->name = strdup("Xephyr virtual mouse"); - ephyrMouse = pi; - return Success; -} - -static Status -MouseEnable (KdPointerInfo *pi) -{ - ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = TRUE; - return Success; -} - -static void -MouseDisable (KdPointerInfo *pi) -{ - ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE; - return; -} - -static void -MouseFini (KdPointerInfo *pi) -{ - ephyrMouse = NULL; - return; -} - -KdPointerDriver EphyrMouseDriver = { - "ephyr", - MouseInit, - MouseEnable, - MouseDisable, - MouseFini, - NULL, -}; - -/* Keyboard */ - -static Status -EphyrKeyboardInit (KdKeyboardInfo *ki) -{ - ki->driverPrivate = (EphyrKbdPrivate *) - xcalloc(sizeof(EphyrKbdPrivate), 1); - hostx_load_keymap(); - if (!ephyrKeySyms.map) { - ErrorF("Couldn't load keymap from host\n"); - return BadAlloc; - } - ki->minScanCode = ephyrKeySyms.minKeyCode; - ki->maxScanCode = ephyrKeySyms.maxKeyCode; - if (ki->name) - xfree(ki->name); - ki->name = strdup("Xephyr virtual keyboard"); - ephyrKbd = ki; - return Success; -} - -static Status -EphyrKeyboardEnable (KdKeyboardInfo *ki) -{ - ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = TRUE; - - return Success; -} - -static void -EphyrKeyboardDisable (KdKeyboardInfo *ki) -{ - ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = FALSE; -} - -static void -EphyrKeyboardFini (KdKeyboardInfo *ki) -{ - ephyrKbd = NULL; - return; -} - -static void -EphyrKeyboardLeds (KdKeyboardInfo *ki, int leds) -{ -} - -static void -EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration) -{ -} - - -KdKeyboardDriver EphyrKeyboardDriver = { - "ephyr", - EphyrKeyboardInit, - EphyrKeyboardEnable, - EphyrKeyboardLeds, - EphyrKeyboardBell, - EphyrKeyboardDisable, - EphyrKeyboardFini, - NULL, -}; +/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "ephyr.h"
+
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "ephyrlog.h"
+
+#ifdef XF86DRI
+#include "ephyrdri.h"
+#include "ephyrdriext.h"
+#include "ephyrglxext.h"
+#endif /* XF86DRI */
+
+extern int KdTsPhyScreen;
+#ifdef GLXEXT
+extern Bool noGlxVisualInit;
+#endif
+
+KdKeyboardInfo *ephyrKbd;
+KdPointerInfo *ephyrMouse;
+EphyrKeySyms ephyrKeySyms;
+Bool ephyrNoDRI=FALSE ;
+Bool ephyrNoXV=FALSE ;
+
+static int mouseState = 0;
+
+typedef struct _EphyrInputPrivate {
+ Bool enabled;
+} EphyrKbdPrivate, EphyrPointerPrivate;
+
+Bool EphyrWantGrayScale = 0;
+
+
+Bool
+ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ OsSignal(SIGUSR1, hostx_handle_signal);
+#endif
+ priv->base = 0;
+ priv->bytes_per_line = 0;
+ return TRUE;
+}
+
+Bool
+ephyrCardInit (KdCardInfo *card)
+{
+ EphyrPriv *priv;
+
+ priv = (EphyrPriv *) xalloc (sizeof (EphyrPriv));
+ if (!priv)
+ return FALSE;
+
+ if (!ephyrInitialize (card, priv))
+ {
+ xfree (priv);
+ return FALSE;
+ }
+ card->driver = priv;
+
+ return TRUE;
+}
+
+Bool
+ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
+{
+ int width = 640, height = 480;
+ CARD32 redMask, greenMask, blueMask;
+
+ if (hostx_want_screen_size(screen, &width, &height)
+ || !screen->width || !screen->height)
+ {
+ screen->width = width;
+ screen->height = height;
+ }
+
+ if (EphyrWantGrayScale)
+ screen->fb[0].depth = 8;
+
+ if (screen->fb[0].depth && screen->fb[0].depth != hostx_get_depth())
+ {
+ if (screen->fb[0].depth < hostx_get_depth()
+ && (screen->fb[0].depth == 24 || screen->fb[0].depth == 16
+ || screen->fb[0].depth == 8))
+ {
+ hostx_set_server_depth(screen, screen->fb[0].depth);
+ }
+ else
+ ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n");
+ }
+
+ screen->fb[0].depth = hostx_get_server_depth(screen);
+ screen->rate = 72;
+
+ if (screen->fb[0].depth <= 8)
+ {
+ if (EphyrWantGrayScale)
+ screen->fb[0].visuals = ((1 << StaticGray) | (1 << GrayScale));
+ else
+ screen->fb[0].visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+
+ screen->fb[0].redMask = 0x00;
+ screen->fb[0].greenMask = 0x00;
+ screen->fb[0].blueMask = 0x00;
+ screen->fb[0].depth = 8;
+ screen->fb[0].bitsPerPixel = 8;
+ }
+ else
+ {
+ screen->fb[0].visuals = (1 << TrueColor);
+
+ if (screen->fb[0].depth <= 15)
+ {
+ screen->fb[0].depth = 15;
+ screen->fb[0].bitsPerPixel = 16;
+ }
+ else if (screen->fb[0].depth <= 16)
+ {
+ screen->fb[0].depth = 16;
+ screen->fb[0].bitsPerPixel = 16;
+ }
+ else if (screen->fb[0].depth <= 24)
+ {
+ screen->fb[0].depth = 24;
+ screen->fb[0].bitsPerPixel = 32;
+ }
+ else if (screen->fb[0].depth <= 30)
+ {
+ screen->fb[0].depth = 30;
+ screen->fb[0].bitsPerPixel = 32;
+ }
+ else
+ {
+ ErrorF("\nXephyr: Unsupported screen depth %d\n",
+ screen->fb[0].depth);
+ return FALSE;
+ }
+
+ hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask);
+
+ screen->fb[0].redMask = (Pixel) redMask;
+ screen->fb[0].greenMask = (Pixel) greenMask;
+ screen->fb[0].blueMask = (Pixel) blueMask;
+
+ }
+
+ scrpriv->randr = screen->randr;
+
+ return ephyrMapFramebuffer (screen);
+}
+
+Bool
+ephyrScreenInit (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv;
+
+ scrpriv = xcalloc (1, sizeof (EphyrScrPriv));
+
+ if (!scrpriv)
+ return FALSE;
+
+ screen->driver = scrpriv;
+
+ if (!ephyrScreenInitialize (screen, scrpriv))
+ {
+ screen->driver = 0;
+ xfree (scrpriv);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void*
+ephyrWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure)
+{
+ KdScreenPriv(pScreen);
+ EphyrPriv *priv = pScreenPriv->card->driver;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+
+ *size = priv->bytes_per_line;
+ return priv->base + row * priv->bytes_per_line + offset;
+}
+
+Bool
+ephyrMapFramebuffer (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrPriv *priv = screen->card->driver;
+ KdPointerMatrix m;
+ int buffer_height;
+
+ EPHYR_LOG("screen->width: %d, screen->height: %d index=%d",
+ screen->width, screen->height, screen->mynum);
+
+ KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
+ KdSetPointerMatrix (&m);
+
+ priv->bytes_per_line = ((screen->width * screen->fb[0].bitsPerPixel + 31) >> 5) << 2;
+
+ /* point the framebuffer to the data in an XImage */
+ /* If fakexa is enabled, allocate a larger buffer so that fakexa has space to
+ * put offscreen pixmaps.
+ */
+ if (ephyrFuncs.initAccel == NULL)
+ buffer_height = screen->height;
+ else
+ buffer_height = 3 * screen->height;
+
+ priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height);
+
+ screen->memory_base = (CARD8 *) (priv->base);
+ screen->memory_size = priv->bytes_per_line * buffer_height;
+ screen->off_screen_base = priv->bytes_per_line * screen->height;
+
+ if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All))
+ {
+ scrpriv->shadow = FALSE;
+
+ screen->fb[0].byteStride = priv->bytes_per_line;
+ screen->fb[0].pixelStride = screen->width;
+ screen->fb[0].frameBuffer = (CARD8 *) (priv->base);
+ }
+ else
+ {
+ /* Rotated/Reflected so we need to use shadow fb */
+ scrpriv->shadow = TRUE;
+
+ EPHYR_LOG("allocing shadow");
+
+ KdShadowFbAlloc (screen, 0,
+ scrpriv->randr & (RR_Rotate_90|RR_Rotate_270));
+ }
+
+ return TRUE;
+}
+
+void
+ephyrSetScreenSizes (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ pScreen->width = screen->width;
+ pScreen->height = screen->height;
+ pScreen->mmWidth = screen->width_mm;
+ pScreen->mmHeight = screen->height_mm;
+ }
+ else
+ {
+ pScreen->width = screen->height;
+ pScreen->height = screen->width;
+ pScreen->mmWidth = screen->height_mm;
+ pScreen->mmHeight = screen->width_mm;
+ }
+}
+
+Bool
+ephyrUnmapFramebuffer (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ if (scrpriv->shadow)
+ KdShadowFbFree (screen, 0);
+
+ /* Note, priv->base will get freed when XImage recreated */
+
+ return TRUE;
+}
+
+void
+ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+
+ EPHYR_LOG("slow paint");
+
+ /* FIXME: Slow Rotated/Reflected updates could be much
+ * much faster efficiently updating via tranforming
+ * pBuf->pDamage regions
+ */
+ shadowUpdateRotatePacked(pScreen, pBuf);
+ hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height);
+}
+
+static void
+ephyrInternalDamageRedisplay (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ RegionPtr pRegion;
+
+ if (!scrpriv || !scrpriv->pDamage)
+ return;
+
+ pRegion = DamageRegion (scrpriv->pDamage);
+
+ if (REGION_NOTEMPTY (pScreen, pRegion))
+ {
+ int nbox;
+ BoxPtr pbox;
+
+ nbox = REGION_NUM_RECTS (pRegion);
+ pbox = REGION_RECTS (pRegion);
+
+ while (nbox--)
+ {
+ hostx_paint_rect(screen,
+ pbox->x1, pbox->y1,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
+ DamageEmpty (scrpriv->pDamage);
+ }
+}
+
+static void
+ephyrInternalDamageBlockHandler (pointer data,
+ OSTimePtr pTimeout,
+ pointer pRead)
+{
+ ScreenPtr pScreen = (ScreenPtr) data;
+
+ ephyrInternalDamageRedisplay (pScreen);
+}
+
+static void
+ephyrInternalDamageWakeupHandler (pointer data, int i, pointer LastSelectMask)
+{
+ /* FIXME: Not needed ? */
+}
+
+Bool
+ephyrSetInternalDamage (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ PixmapPtr pPixmap = NULL;
+
+ scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0,
+ (DamageDestroyFunc) 0,
+ DamageReportNone,
+ TRUE,
+ pScreen,
+ pScreen);
+
+ if (!RegisterBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
+ ephyrInternalDamageWakeupHandler,
+ (pointer) pScreen))
+ return FALSE;
+
+ pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+
+ DamageRegister (&pPixmap->drawable, scrpriv->pDamage);
+
+ return TRUE;
+}
+
+void
+ephyrUnsetInternalDamage (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ PixmapPtr pPixmap = NULL;
+
+ pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ DamageUnregister (&pPixmap->drawable, scrpriv->pDamage);
+ DamageDestroy (scrpriv->pDamage);
+
+ RemoveBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
+ ephyrInternalDamageWakeupHandler,
+ (pointer) pScreen);
+}
+
+#ifdef RANDR
+Bool
+ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ RRScreenSizePtr pSize;
+ Rotation randr;
+ int n = 0;
+
+ struct { int width, height; } sizes[] =
+ {
+ { 1600, 1200 },
+ { 1400, 1050 },
+ { 1280, 960 },
+ { 1280, 1024 },
+ { 1152, 864 },
+ { 1024, 768 },
+ { 832, 624 },
+ { 800, 600 },
+ { 720, 400 },
+ { 480, 640 },
+ { 640, 480 },
+ { 640, 400 },
+ { 320, 240 },
+ { 240, 320 },
+ { 160, 160 },
+ { 0, 0 }
+ };
+
+ EPHYR_LOG("mark");
+
+ *rotations = RR_Rotate_All|RR_Reflect_All;
+
+ if (!hostx_want_preexisting_window (screen)
+ && !hostx_want_fullscreen ()) /* only if no -parent switch */
+ {
+ while (sizes[n].width != 0 && sizes[n].height != 0)
+ {
+ RRRegisterSize (pScreen,
+ sizes[n].width,
+ sizes[n].height,
+ (sizes[n].width * screen->width_mm)/screen->width,
+ (sizes[n].height *screen->height_mm)/screen->height
+ );
+ n++;
+ }
+ }
+
+ pSize = RRRegisterSize (pScreen,
+ screen->width,
+ screen->height,
+ screen->width_mm,
+ screen->height_mm);
+
+ randr = KdSubRotation (scrpriv->randr, screen->randr);
+
+ RRSetCurrentConfig (pScreen, randr, 0, pSize);
+
+ return TRUE;
+}
+
+Bool
+ephyrRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ Bool wasEnabled = pScreenPriv->enabled;
+ EphyrScrPriv oldscr;
+ int oldwidth, oldheight, oldmmwidth, oldmmheight;
+ Bool oldshadow;
+ int newwidth, newheight;
+
+ if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ newwidth = pSize->width;
+ newheight = pSize->height;
+ }
+ else
+ {
+ newwidth = pSize->height;
+ newheight = pSize->width;
+ }
+
+ if (wasEnabled)
+ KdDisableScreen (pScreen);
+
+ oldscr = *scrpriv;
+
+ oldwidth = screen->width;
+ oldheight = screen->height;
+ oldmmwidth = pScreen->mmWidth;
+ oldmmheight = pScreen->mmHeight;
+ oldshadow = scrpriv->shadow;
+
+ /*
+ * Set new configuration
+ */
+
+ scrpriv->randr = KdAddRotation (screen->randr, randr);
+
+ ephyrUnmapFramebuffer (screen);
+
+ screen->width = newwidth;
+ screen->height = newheight;
+
+ if (!ephyrMapFramebuffer (screen))
+ goto bail4;
+
+ /* FIXME below should go in own call */
+
+ if (oldshadow)
+ KdShadowUnset (screen->pScreen);
+ else
+ ephyrUnsetInternalDamage(screen->pScreen);
+
+ if (scrpriv->shadow)
+ {
+ if (!KdShadowSet (screen->pScreen,
+ scrpriv->randr,
+ ephyrShadowUpdate,
+ ephyrWindowLinear))
+ goto bail4;
+ }
+ else
+ {
+ /* Without shadow fb ( non rotated ) we need
+ * to use damage to efficiently update display
+ * via signal regions what to copy from 'fb'.
+ */
+ if (!ephyrSetInternalDamage(screen->pScreen))
+ goto bail4;
+ }
+
+ ephyrSetScreenSizes (screen->pScreen);
+
+ /*
+ * Set frame buffer mapping
+ */
+ (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
+ pScreen->width,
+ pScreen->height,
+ screen->fb[0].depth,
+ screen->fb[0].bitsPerPixel,
+ screen->fb[0].byteStride,
+ screen->fb[0].frameBuffer);
+
+ /* set the subpixel order */
+
+ KdSetSubpixelOrder (pScreen, scrpriv->randr);
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+
+ return TRUE;
+
+ bail4:
+ EPHYR_LOG("bailed");
+
+ ephyrUnmapFramebuffer (screen);
+ *scrpriv = oldscr;
+ (void) ephyrMapFramebuffer (screen);
+
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ pScreen->mmWidth = oldmmwidth;
+ pScreen->mmHeight = oldmmheight;
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+ return FALSE;
+}
+
+Bool
+ephyrRandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRScreenInit (pScreen))
+ return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = ephyrRandRGetInfo;
+ pScrPriv->rrSetConfig = ephyrRandRSetConfig;
+ return TRUE;
+}
+#endif
+
+Bool
+ephyrCreateColormap (ColormapPtr pmap)
+{
+ return fbInitializeColormap (pmap);
+}
+
+Bool
+ephyrInitScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+
+ EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ;
+ hostx_set_screen_number (screen, pScreen->myNum);
+ hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
+ pScreen->CreateColormap = ephyrCreateColormap;
+
+#ifdef XV
+ if (!ephyrNoXV) {
+ if (!ephyrInitVideo (pScreen)) {
+ EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
+ } else {
+ EPHYR_LOG ("initialized xvideo okay\n") ;
+ }
+ }
+#endif /*XV*/
+
+#ifdef XF86DRI
+ if (!ephyrNoDRI && !hostx_has_dri ()) {
+ EPHYR_LOG ("host x does not support DRI. Disabling DRI forwarding\n") ;
+ ephyrNoDRI = TRUE ;
+#ifdef GLXEXT
+ noGlxVisualInit = FALSE ;
+#endif
+ }
+ if (!ephyrNoDRI) {
+ ephyrDRIExtensionInit (pScreen) ;
+ ephyrHijackGLXExtension () ;
+ }
+#endif
+
+#ifdef GLXEXT
+ if (ephyrNoDRI) {
+ noGlxVisualInit = FALSE ;
+ }
+#endif
+
+ return TRUE;
+}
+
+Bool
+ephyrFinishInitScreen (ScreenPtr pScreen)
+{
+ /* FIXME: Calling this even if not using shadow.
+ * Seems harmless enough. But may be safer elsewhere.
+ */
+ if (!shadowSetup (pScreen))
+ return FALSE;
+
+#ifdef RANDR
+ if (!ephyrRandRInit (pScreen))
+ return FALSE;
+#endif
+
+ return TRUE;
+}
+
+Bool
+ephyrCreateResources (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
+ pScreen, pScreen->myNum, scrpriv->shadow);
+
+ if (scrpriv->shadow)
+ return KdShadowSet (pScreen,
+ scrpriv->randr,
+ ephyrShadowUpdate,
+ ephyrWindowLinear);
+ else
+ return ephyrSetInternalDamage(pScreen);
+}
+
+void
+ephyrPreserve (KdCardInfo *card)
+{
+}
+
+Bool
+ephyrEnable (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+Bool
+ephyrDPMS (ScreenPtr pScreen, int mode)
+{
+ return TRUE;
+}
+
+void
+ephyrDisable (ScreenPtr pScreen)
+{
+}
+
+void
+ephyrRestore (KdCardInfo *card)
+{
+}
+
+void
+ephyrScreenFini (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+ if (scrpriv->shadow) {
+ KdShadowFbFree (screen, 0);
+ }
+ xfree(screen->driver);
+ screen->driver = NULL;
+}
+
+/*
+ * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug.
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=3030
+ */
+void
+ephyrUpdateModifierState(unsigned int state)
+{
+#if 0
+ DeviceIntPtr pkeydev;
+ KeyClassPtr keyc;
+ int i;
+ CARD8 mask;
+
+ pkeydev = inputInfo.keyboard;
+
+ if (!pkeydev)
+ return;
+
+/* This is pretty broken.
+ *
+ * What should happen is that focus out should do as a VT switch does in
+ * traditional servers: fake releases for all keys (and buttons too, come
+ * to think of it) currently down. Then, on focus in, get the state from
+ * the host, and fake keypresses for everything currently down.
+ *
+ * So I'm leaving this broken for a little while. Sorry, folks.
+ *
+ * -daniels
+ */
+
+ keyc = pkeydev->key;
+
+ state = state & 0xff;
+
+ if (keyc->state == state)
+ return;
+
+ for (i = 0, mask = 1; i < 8; i++, mask <<= 1)
+ {
+ int key;
+
+ /* Modifier is down, but shouldn't be */
+ if ((keyc->state & mask) && !(state & mask))
+ {
+ int count = keyc->modifierKeyCount[i];
+
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask)
+ {
+ int bit;
+ BYTE *kptr;
+
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+
+ if (*kptr & bit && ephyrKbd &&
+ ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */
+
+ if (--count == 0)
+ break;
+ }
+ }
+
+ /* Modifier shoud be down, but isn't */
+ if (!(keyc->state & mask) && (state & mask))
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask)
+ {
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd &&
+ ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
+ break;
+ }
+ }
+#endif
+}
+
+static void
+ephyrBlockSigio (void)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_BLOCK, &set, 0);
+#endif
+}
+
+static void
+ephyrUnblockSigio (void)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_UNBLOCK, &set, 0);
+#endif
+}
+
+static Bool
+ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ return FALSE;
+}
+
+static void
+ephyrCrossScreen (ScreenPtr pScreen, Bool entering)
+{
+}
+
+int ephyrCurScreen; /*current event screen*/
+
+static void
+ephyrWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ ephyrBlockSigio ();
+ ephyrCurScreen = pScreen->myNum;
+ miPointerWarpCursor (inputInfo.pointer, pScreen, x, y);
+ ephyrUnblockSigio ();
+}
+
+miPointerScreenFuncRec ephyrPointerScreenFuncs =
+{
+ ephyrCursorOffScreen,
+ ephyrCrossScreen,
+ ephyrWarpCursor,
+ NULL,
+ NULL
+};
+
+#ifdef XF86DRI
+/**
+ * find if the remote window denoted by a_remote
+ * is paired with an internal Window within the Xephyr server.
+ * If the remove window is paired with an internal window, send an
+ * expose event to the client insterested in the internal window expose event.
+ *
+ * Pairing happens when a drawable inside Xephyr is associated with
+ * a GL surface in a DRI environment.
+ * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to
+ * know a paired window is created.
+ *
+ * This is useful to make GL drawables (only windows for now) handle
+ * expose events and send those events to clients.
+ */
+static void
+ephyrExposePairedWindow (int a_remote)
+{
+ EphyrWindowPair *pair = NULL;
+ RegionRec reg;
+ ScreenPtr screen;
+
+ if (!findWindowPairFromRemote (a_remote, &pair)) {
+ EPHYR_LOG ("did not find a pair for this window\n");
+ return;
+ }
+ screen = pair->local->drawable.pScreen;
+ REGION_NULL (screen, ®);
+ REGION_COPY (screen, ®, &pair->local->clipList);
+ screen->WindowExposures (pair->local, ®, NullRegion);
+ REGION_UNINIT (screen, ®);
+}
+#endif /* XF86DRI */
+
+void
+ephyrPoll(void)
+{
+ EphyrHostXEvent ev;
+
+ while (hostx_get_event(&ev))
+ {
+ switch (ev.type)
+ {
+ case EPHYR_EV_MOUSE_MOTION:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+ EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
+ continue;
+ }
+ {
+ if (ev.data.mouse_motion.screen >=0
+ && (ephyrCurScreen != ev.data.mouse_motion.screen))
+ {
+ EPHYR_LOG ("warping mouse cursor. "
+ "cur_screen%d, motion_screen:%d\n",
+ ephyrCurScreen, ev.data.mouse_motion.screen) ;
+ if (ev.data.mouse_motion.screen >= 0)
+ {
+ ephyrWarpCursor
+ (inputInfo.pointer, screenInfo.screens[ev.data.mouse_motion.screen],
+ ev.data.mouse_motion.x,
+ ev.data.mouse_motion.y );
+ }
+ }
+ else
+ {
+ int x=0, y=0;
+#ifdef XF86DRI
+ EphyrWindowPair *pair = NULL;
+#endif
+ EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
+ x = ev.data.mouse_motion.x;
+ y = ev.data.mouse_motion.y;
+ EPHYR_LOG ("initial (x,y):(%d,%d)\n", x, y) ;
+#ifdef XF86DRI
+ EPHYR_LOG ("is this window peered by a gl drawable ?\n") ;
+ if (findWindowPairFromRemote (ev.data.mouse_motion.window,
+ &pair))
+ {
+ EPHYR_LOG ("yes, it is peered\n") ;
+ x += pair->local->drawable.x;
+ y += pair->local->drawable.y;
+ }
+ else
+ {
+ EPHYR_LOG ("no, it is not peered\n") ;
+ }
+ EPHYR_LOG ("final (x,y):(%d,%d)\n", x, y) ;
+#endif
+ KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0);
+ }
+ }
+ break;
+
+ case EPHYR_EV_MOUSE_PRESS:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+ EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ;
+ continue;
+ }
+ EPHYR_LOG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
+ ephyrUpdateModifierState(ev.key_state);
+ mouseState |= ev.data.mouse_down.button_num;
+ KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
+ break;
+
+ case EPHYR_EV_MOUSE_RELEASE:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
+ continue;
+ ephyrUpdateModifierState(ev.key_state);
+ mouseState &= ~ev.data.mouse_up.button_num;
+ EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
+ KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
+ break;
+
+ case EPHYR_EV_KEY_PRESS:
+ if (!ephyrKbd ||
+ !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ continue;
+ ephyrUpdateModifierState(ev.key_state);
+ KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_down.scancode, FALSE);
+ break;
+
+ case EPHYR_EV_KEY_RELEASE:
+ if (!ephyrKbd ||
+ !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ continue;
+ KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
+ break;
+
+#ifdef XF86DRI
+ case EPHYR_EV_EXPOSE:
+ /*
+ * We only receive expose events when the expose event have
+ * be generated for a drawable that is a host X window managed
+ * by Xephyr. Host X windows managed by Xephyr exists for instance
+ * when Xephyr is asked to create a GL drawable in a DRI environment.
+ */
+ ephyrExposePairedWindow (ev.data.expose.window);
+ break;
+#endif /* XF86DRI */
+
+ default:
+ break;
+ }
+ }
+}
+
+void
+ephyrCardFini (KdCardInfo *card)
+{
+ EphyrPriv *priv = card->driver;
+ xfree (priv);
+}
+
+void
+ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
+{
+ /* XXX Not sure if this is right */
+
+ EPHYR_LOG("mark");
+
+ while (n--)
+ {
+ pdefs->red = 0;
+ pdefs->green = 0;
+ pdefs->blue = 0;
+ pdefs++;
+ }
+
+}
+
+void
+ephyrPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
+{
+ int min, max, p;
+
+ /* XXX Not sure if this is right */
+
+ min = 256;
+ max = 0;
+
+ while (n--)
+ {
+ p = pdefs->pixel;
+ if (p < min)
+ min = p;
+ if (p > max)
+ max = p;
+
+ hostx_set_cmap_entry(p,
+ pdefs->red >> 8,
+ pdefs->green >> 8,
+ pdefs->blue >> 8);
+ pdefs++;
+ }
+}
+
+/* Mouse calls */
+
+static Status
+MouseInit (KdPointerInfo *pi)
+{
+ pi->driverPrivate = (EphyrPointerPrivate *)
+ xcalloc(sizeof(EphyrPointerPrivate), 1);
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
+ pi->nAxes = 3;
+ pi->nButtons = 32;
+ if (pi->name)
+ xfree(pi->name);
+ pi->name = strdup("Xephyr virtual mouse");
+ ephyrMouse = pi;
+ return Success;
+}
+
+static Status
+MouseEnable (KdPointerInfo *pi)
+{
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = TRUE;
+ return Success;
+}
+
+static void
+MouseDisable (KdPointerInfo *pi)
+{
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
+ return;
+}
+
+static void
+MouseFini (KdPointerInfo *pi)
+{
+ ephyrMouse = NULL;
+ return;
+}
+
+KdPointerDriver EphyrMouseDriver = {
+ "ephyr",
+ MouseInit,
+ MouseEnable,
+ MouseDisable,
+ MouseFini,
+ NULL,
+};
+
+/* Keyboard */
+
+static Status
+EphyrKeyboardInit (KdKeyboardInfo *ki)
+{
+ ki->driverPrivate = (EphyrKbdPrivate *)
+ xcalloc(sizeof(EphyrKbdPrivate), 1);
+ hostx_load_keymap();
+ if (!ephyrKeySyms.map) {
+ ErrorF("Couldn't load keymap from host\n");
+ return BadAlloc;
+ }
+ ki->minScanCode = ephyrKeySyms.minKeyCode;
+ ki->maxScanCode = ephyrKeySyms.maxKeyCode;
+ if (ki->name)
+ xfree(ki->name);
+ ki->name = strdup("Xephyr virtual keyboard");
+ ephyrKbd = ki;
+ return Success;
+}
+
+static Status
+EphyrKeyboardEnable (KdKeyboardInfo *ki)
+{
+ ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = TRUE;
+
+ return Success;
+}
+
+static void
+EphyrKeyboardDisable (KdKeyboardInfo *ki)
+{
+ ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = FALSE;
+}
+
+static void
+EphyrKeyboardFini (KdKeyboardInfo *ki)
+{
+ ephyrKbd = NULL;
+ return;
+}
+
+static void
+EphyrKeyboardLeds (KdKeyboardInfo *ki, int leds)
+{
+}
+
+static void
+EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
+{
+}
+
+
+KdKeyboardDriver EphyrKeyboardDriver = {
+ "ephyr",
+ EphyrKeyboardInit,
+ EphyrKeyboardEnable,
+ EphyrKeyboardLeds,
+ EphyrKeyboardBell,
+ EphyrKeyboardDisable,
+ EphyrKeyboardFini,
+ NULL,
+};
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.h b/xorg-server/hw/kdrive/ephyr/ephyr.h index 5d58a216c..dd22bd150 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.h +++ b/xorg-server/hw/kdrive/ephyr/ephyr.h @@ -26,9 +26,11 @@ #ifndef _EPHYR_H_ #define _EPHYR_H_ #include <stdio.h> +#ifndef _MSC_VER #include <unistd.h> -#include <signal.h> #include <libgen.h> +#endif +#include <signal.h> #include "os.h" /* for OsSignal() */ #include "kdrive.h" diff --git a/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c index 2b72b4e0a..0c638e98d 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrinit.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c @@ -1,409 +1,421 @@ -/* - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <kdrive-config.h> -#endif -#include "ephyr.h" -#include "ephyrlog.h" - -extern Window EphyrPreExistingHostWin; -extern Bool EphyrWantGrayScale; -extern Bool kdHasPointer; -extern Bool kdHasKbd; - -#ifdef GLXEXT -extern Bool ephyrNoDRI; -extern Bool noGlxVisualInit; -#endif -extern Bool ephyrNoXV; - -void processScreenArg (char *screen_size, char *parent_id) ; - -void -InitCard (char *name) -{ - KdCardAttr attr; - - EPHYR_DBG("mark"); - - - KdCardInfoAdd (&ephyrFuncs, &attr, 0); -} - -void -InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) -{ - KdInitOutput (pScreenInfo, argc, argv); -} - -void -InitInput (int argc, char **argv) -{ - KdKeyboardInfo *ki; - KdPointerInfo *pi; - - KdAddKeyboardDriver(&EphyrKeyboardDriver); -#ifdef linux - KdAddKeyboardDriver(&LinuxEvdevKeyboardDriver); -#endif - KdAddPointerDriver(&EphyrMouseDriver); -#ifdef linux - KdAddPointerDriver(&LinuxEvdevMouseDriver); -#endif - - if (!kdHasKbd) { - ki = KdNewKeyboard(); - if (!ki) - FatalError("Couldn't create Xephyr keyboard\n"); - ki->driver = &EphyrKeyboardDriver; - KdAddKeyboard(ki); - } - - if (!kdHasPointer) { - pi = KdNewPointer(); - if (!pi) - FatalError("Couldn't create Xephyr pointer\n"); - pi->driver = &EphyrMouseDriver; - KdAddPointer(pi); - } - - KdInitInput(); -} - -#ifdef DDXBEFORERESET -void -ddxBeforeReset (void) -{ -} -#endif - -void -ddxUseMsg (void) -{ - KdUseMsg(); - - ErrorF("\nXephyr Option Usage:\n"); - ErrorF("-parent <XID> Use existing window as Xephyr root win\n"); - ErrorF("-host-cursor Re-use exisiting X host server cursor\n"); - ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n"); - ErrorF("-grayscale Simulate 8bit grayscale\n"); - ErrorF("-fakexa Simulate acceleration using software rendering\n"); - ErrorF("-verbosity <level> Set log verbosity level\n"); -#ifdef GLXEXT - ErrorF("-nodri do not use DRI\n"); -#endif - ErrorF("-noxv do not use XV\n"); - ErrorF("-name [name] define the name in the WM_CLASS property\n"); - ErrorF("-title [title] set the window title in the WM_NAME property\n"); - ErrorF("\n"); - - exit(1); -} - -void -processScreenArg (char *screen_size, char *parent_id) -{ - KdCardInfo *card; - - InitCard (0); /*Put each screen on a separate card*/ - card = KdCardInfoLast (); - - if (card) - { - KdScreenInfo *screen; - unsigned long p_id = 0; - - screen = KdScreenInfoAdd (card); - KdParseScreen (screen, screen_size); - - if (parent_id) - { - p_id = strtol (parent_id, NULL, 0); - } - EPHYR_DBG ("screen number:%d\n", screen->mynum) ; - hostx_add_screen (screen, p_id, screen->mynum); - } - else - { - ErrorF("No matching card found!\n"); - } -} - -int -ddxProcessArgument (int argc, char **argv, int i) -{ - static char* parent = NULL; - EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] ); - - if (i == 1) - { - hostx_use_resname(basename(argv[0]), 0); - } - - if (!strcmp (argv[i], "-parent")) - { - if(i+1 < argc) - { - int j; - /* If parent is specified and a screen argument follows, don't do - * anything, let the -screen handling init the rest */ - for (j = i; j < argc; j++) - { - if (!strcmp(argv[j], "-screen")) - { - parent = argv[i + 1]; - return 2; - } - } - - processScreenArg ("100x100", argv[i+1]); - return 2; - } - - UseMsg(); - exit(1); - } - else if (!strcmp (argv[i], "-screen")) - { - if ((i+1) < argc) - { - processScreenArg (argv[i+1], parent); - parent = NULL; - return 2; - } - - UseMsg(); - exit(1); - } - else if (!strcmp (argv[i], "-host-cursor")) - { - hostx_use_host_cursor(); - return 1; - } - else if (!strcmp (argv[i], "-fullscreen")) - { - hostx_use_fullscreen(); - return 1; - } - else if (!strcmp (argv[i], "-grayscale")) - { - EphyrWantGrayScale = 1; - return 1; - } - else if (!strcmp (argv[i], "-fakexa")) - { - ephyrFuncs.initAccel = ephyrDrawInit; - ephyrFuncs.enableAccel = ephyrDrawEnable; - ephyrFuncs.disableAccel = ephyrDrawDisable; - ephyrFuncs.finiAccel = ephyrDrawFini; - return 1; - } - else if (!strcmp (argv[i], "-verbosity")) - { - if(i+1 < argc && argv[i+1][0] != '-') - { - int verbosity=atoi (argv[i+1]) ; - LogSetParameter (XLOG_VERBOSITY, verbosity) ; - EPHYR_LOG ("set verbosiry to %d\n", verbosity) ; - return 2 ; - } - else - { - UseMsg() ; - exit(1) ; - } - } -#ifdef GLXEXT - else if (!strcmp (argv[i], "-nodri")) - { - noGlxVisualInit = FALSE ; - ephyrNoDRI = TRUE ; - EPHYR_LOG ("no direct rendering enabled\n") ; - return 1 ; - } -#endif - else if (!strcmp (argv[i], "-noxv")) - { - ephyrNoXV = TRUE ; - EPHYR_LOG ("no XVideo enabled\n") ; - return 1 ; - } - else if (!strcmp (argv[i], "-name")) - { - if (i+1 < argc && argv[i+1][0] != '-') - { - hostx_use_resname(argv[i+1], 1); - return 2; - } - else - { - UseMsg(); - return 0; - } - } - else if (!strcmp (argv[i], "-title")) - { - if (i+1 < argc && argv[i+1][0] != '-') - { - hostx_set_title(argv[i+1]); - return 2; - } - else - { - UseMsg(); - return 0; - } - } - else if (argv[i][0] == ':') - { - hostx_set_display_name(argv[i]); - } - /* Xnest compatibility */ - else if (!strcmp(argv[i], "-display")) - { - hostx_set_display_name(argv[i+1]); - return 2; - } - else if (!strcmp(argv[i], "-sync") || - !strcmp(argv[i], "-full") || - !strcmp(argv[i], "-sss") || - !strcmp(argv[i], "-install")) - { - return 1; - } - else if (!strcmp(argv[i], "-bw") || - !strcmp(argv[i], "-class") || - !strcmp(argv[i], "-geometry") || - !strcmp(argv[i], "-scrns")) - { - return 2; - } - /* end Xnest compat */ - - return KdProcessArgument (argc, argv, i); -} - -void -OsVendorInit (void) -{ - EPHYR_DBG("mark"); - - if (hostx_want_host_cursor()) - { - ephyrFuncs.initCursor = &ephyrCursorInit; - ephyrFuncs.enableCursor = &ephyrCursorEnable; - } - - KdOsInit (&EphyrOsFuncs); -} - -/* 'Fake' cursor stuff, could be improved */ - -static Bool -ephyrRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -{ - return TRUE; -} - -static Bool -ephyrUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -{ - return TRUE; -} - -static void -ephyrSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) -{ - ; -} - -static void -ephyrMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ - ; -} - -static Bool -ephyrDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) -{ - return TRUE; -} - -miPointerSpriteFuncRec EphyrPointerSpriteFuncs = { - ephyrRealizeCursor, - ephyrUnrealizeCursor, - ephyrSetCursor, - ephyrMoveCursor, - ephyrDeviceCursorInitialize, - NULL -}; - - -Bool -ephyrCursorInit(ScreenPtr pScreen) -{ - miPointerInitialize(pScreen, - &EphyrPointerSpriteFuncs, - &ephyrPointerScreenFuncs, - FALSE); - - return TRUE; -} - -void -ephyrCursorEnable(ScreenPtr pScreen) -{ - ; -} - -KdCardFuncs ephyrFuncs = { - ephyrCardInit, /* cardinit */ - ephyrScreenInit, /* scrinit */ - ephyrInitScreen, /* initScreen */ - ephyrFinishInitScreen, /* finishInitScreen */ - ephyrCreateResources, /* createRes */ - ephyrPreserve, /* preserve */ - ephyrEnable, /* enable */ - ephyrDPMS, /* dpms */ - ephyrDisable, /* disable */ - ephyrRestore, /* restore */ - ephyrScreenFini, /* scrfini */ - ephyrCardFini, /* cardfini */ - - 0, /* initCursor */ - 0, /* enableCursor */ - 0, /* disableCursor */ - 0, /* finiCursor */ - 0, /* recolorCursor */ - - 0, /* initAccel */ - 0, /* enableAccel */ - 0, /* disableAccel */ - 0, /* finiAccel */ - - ephyrGetColors,/* getColors */ - ephyrPutColors, /* putColors */ -}; +/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "ephyr.h"
+#include "ephyrlog.h"
+
+extern Window EphyrPreExistingHostWin;
+extern Bool EphyrWantGrayScale;
+extern Bool kdHasPointer;
+extern Bool kdHasKbd;
+
+#ifdef GLXEXT
+extern Bool ephyrNoDRI;
+extern Bool noGlxVisualInit;
+#endif
+extern Bool ephyrNoXV;
+
+void processScreenArg (char *screen_size, char *parent_id) ;
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+
+ EPHYR_DBG("mark");
+
+
+ KdCardInfoAdd (&ephyrFuncs, &attr, 0);
+}
+
+#ifndef _MSC_VER
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdKeyboardInfo *ki;
+ KdPointerInfo *pi;
+
+ KdAddKeyboardDriver(&EphyrKeyboardDriver);
+#ifdef linux
+ KdAddKeyboardDriver(&LinuxEvdevKeyboardDriver);
+#endif
+ KdAddPointerDriver(&EphyrMouseDriver);
+#ifdef linux
+ KdAddPointerDriver(&LinuxEvdevMouseDriver);
+#endif
+
+ if (!kdHasKbd) {
+ ki = KdNewKeyboard();
+ if (!ki)
+ FatalError("Couldn't create Xephyr keyboard\n");
+ ki->driver = &EphyrKeyboardDriver;
+ KdAddKeyboard(ki);
+ }
+
+ if (!kdHasPointer) {
+ pi = KdNewPointer();
+ if (!pi)
+ FatalError("Couldn't create Xephyr pointer\n");
+ pi->driver = &EphyrMouseDriver;
+ KdAddPointer(pi);
+ }
+
+ KdInitInput();
+}
+
+#ifdef DDXBEFORERESET
+void
+ddxBeforeReset (void)
+{
+}
+#endif
+
+void
+ddxUseMsg (void)
+{
+ KdUseMsg();
+
+ ErrorF("\nXephyr Option Usage:\n");
+ ErrorF("-parent <XID> Use existing window as Xephyr root win\n");
+ ErrorF("-host-cursor Re-use exisiting X host server cursor\n");
+ ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
+ ErrorF("-grayscale Simulate 8bit grayscale\n");
+ ErrorF("-fakexa Simulate acceleration using software rendering\n");
+ ErrorF("-verbosity <level> Set log verbosity level\n");
+#ifdef GLXEXT
+ ErrorF("-nodri do not use DRI\n");
+#endif
+ ErrorF("-noxv do not use XV\n");
+ ErrorF("-name [name] define the name in the WM_CLASS property\n");
+ ErrorF("-title [title] set the window title in the WM_NAME property\n");
+ ErrorF("\n");
+
+ exit(1);
+}
+#endif
+
+void
+processScreenArg (char *screen_size, char *parent_id)
+{
+ KdCardInfo *card;
+
+ InitCard (0); /*Put each screen on a separate card*/
+ card = KdCardInfoLast ();
+
+ if (card)
+ {
+ KdScreenInfo *screen;
+ unsigned long p_id = 0;
+
+ screen = KdScreenInfoAdd (card);
+ KdParseScreen (screen, screen_size);
+
+ if (parent_id)
+ {
+ p_id = strtol (parent_id, NULL, 0);
+ }
+ EPHYR_DBG ("screen number:%d\n", screen->mynum) ;
+ hostx_add_screen (screen, p_id, screen->mynum);
+ }
+ else
+ {
+ ErrorF("No matching card found!\n");
+ }
+}
+
+#ifndef _MSC_VER
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ static char* parent = NULL;
+ EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] );
+
+ if (i == 1)
+ {
+ hostx_use_resname(basename(argv[0]), 0);
+ }
+
+ if (!strcmp (argv[i], "-parent"))
+ {
+ if(i+1 < argc)
+ {
+ int j;
+ /* If parent is specified and a screen argument follows, don't do
+ * anything, let the -screen handling init the rest */
+ for (j = i; j < argc; j++)
+ {
+ if (!strcmp(argv[j], "-screen"))
+ {
+ parent = argv[i + 1];
+ return 2;
+ }
+ }
+
+ processScreenArg ("100x100", argv[i+1]);
+ return 2;
+ }
+
+ UseMsg();
+ exit(1);
+ }
+ else if (!strcmp (argv[i], "-screen"))
+ {
+ if ((i+1) < argc)
+ {
+ processScreenArg (argv[i+1], parent);
+ parent = NULL;
+ return 2;
+ }
+
+ UseMsg();
+ exit(1);
+ }
+ else if (!strcmp (argv[i], "-host-cursor"))
+ {
+ hostx_use_host_cursor();
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-fullscreen"))
+ {
+ hostx_use_fullscreen();
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-grayscale"))
+ {
+ EphyrWantGrayScale = 1;
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-fakexa"))
+ {
+ ephyrFuncs.initAccel = ephyrDrawInit;
+ ephyrFuncs.enableAccel = ephyrDrawEnable;
+ ephyrFuncs.disableAccel = ephyrDrawDisable;
+ ephyrFuncs.finiAccel = ephyrDrawFini;
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-verbosity"))
+ {
+ if(i+1 < argc && argv[i+1][0] != '-')
+ {
+ int verbosity=atoi (argv[i+1]) ;
+ LogSetParameter (XLOG_VERBOSITY, verbosity) ;
+ EPHYR_LOG ("set verbosiry to %d\n", verbosity) ;
+ return 2 ;
+ }
+ else
+ {
+ UseMsg() ;
+ exit(1) ;
+ }
+ }
+#ifdef GLXEXT
+ else if (!strcmp (argv[i], "-nodri"))
+ {
+ noGlxVisualInit = FALSE ;
+ ephyrNoDRI = TRUE ;
+ EPHYR_LOG ("no direct rendering enabled\n") ;
+ return 1 ;
+ }
+#endif
+ else if (!strcmp (argv[i], "-noxv"))
+ {
+ ephyrNoXV = TRUE ;
+ EPHYR_LOG ("no XVideo enabled\n") ;
+ return 1 ;
+ }
+ else if (!strcmp (argv[i], "-name"))
+ {
+ if (i+1 < argc && argv[i+1][0] != '-')
+ {
+ hostx_use_resname(argv[i+1], 1);
+ return 2;
+ }
+ else
+ {
+ UseMsg();
+ return 0;
+ }
+ }
+ else if (!strcmp (argv[i], "-title"))
+ {
+ if (i+1 < argc && argv[i+1][0] != '-')
+ {
+ hostx_set_title(argv[i+1]);
+ return 2;
+ }
+ else
+ {
+ UseMsg();
+ return 0;
+ }
+ }
+ else if (argv[i][0] == ':')
+ {
+ hostx_set_display_name(argv[i]);
+ }
+ /* Xnest compatibility */
+ else if (!strcmp(argv[i], "-display"))
+ {
+ hostx_set_display_name(argv[i+1]);
+ return 2;
+ }
+ else if (!strcmp(argv[i], "-sync") ||
+ !strcmp(argv[i], "-full") ||
+ !strcmp(argv[i], "-sss") ||
+ !strcmp(argv[i], "-install"))
+ {
+ return 1;
+ }
+ else if (!strcmp(argv[i], "-bw") ||
+ !strcmp(argv[i], "-class") ||
+ !strcmp(argv[i], "-geometry") ||
+ !strcmp(argv[i], "-scrns"))
+ {
+ return 2;
+ }
+ /* end Xnest compat */
+
+ return KdProcessArgument (argc, argv, i);
+}
+
+void
+OsVendorInit (void)
+{
+ EPHYR_DBG("mark");
+
+ if (hostx_want_host_cursor())
+ {
+ ephyrFuncs.initCursor = &ephyrCursorInit;
+ ephyrFuncs.enableCursor = &ephyrCursorEnable;
+ }
+
+ KdOsInit (&EphyrOsFuncs);
+}
+
+#ifdef DDXOSFATALERROR
+void
+OsVendorFatalError(void)
+{
+}
+#endif
+
+#endif
+
+/* 'Fake' cursor stuff, could be improved */
+
+static Bool
+ephyrRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static Bool
+ephyrUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static void
+ephyrSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ ;
+}
+
+static void
+ephyrMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ ;
+}
+
+static Bool
+ephyrDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
+ ephyrRealizeCursor,
+ ephyrUnrealizeCursor,
+ ephyrSetCursor,
+ ephyrMoveCursor,
+ ephyrDeviceCursorInitialize,
+ NULL
+};
+
+
+Bool
+ephyrCursorInit(ScreenPtr pScreen)
+{
+ miPointerInitialize(pScreen,
+ &EphyrPointerSpriteFuncs,
+ &ephyrPointerScreenFuncs,
+ FALSE);
+
+ return TRUE;
+}
+
+void
+ephyrCursorEnable(ScreenPtr pScreen)
+{
+ ;
+}
+
+KdCardFuncs ephyrFuncs = {
+ ephyrCardInit, /* cardinit */
+ ephyrScreenInit, /* scrinit */
+ ephyrInitScreen, /* initScreen */
+ ephyrFinishInitScreen, /* finishInitScreen */
+ ephyrCreateResources, /* createRes */
+ ephyrPreserve, /* preserve */
+ ephyrEnable, /* enable */
+ ephyrDPMS, /* dpms */
+ ephyrDisable, /* disable */
+ ephyrRestore, /* restore */
+ ephyrScreenFini, /* scrfini */
+ ephyrCardFini, /* cardfini */
+
+ 0, /* initCursor */
+ 0, /* enableCursor */
+ 0, /* disableCursor */
+ 0, /* finiCursor */
+ 0, /* recolorCursor */
+
+ 0, /* initAccel */
+ 0, /* enableAccel */
+ 0, /* disableAccel */
+ 0, /* finiAccel */
+
+ ephyrGetColors,/* getColors */
+ ephyrPutColors, /* putColors */
+};
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrlog.h b/xorg-server/hw/kdrive/ephyr/ephyrlog.h index a07a0a097..ba52a3bce 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrlog.h +++ b/xorg-server/hw/kdrive/ephyr/ephyrlog.h @@ -43,14 +43,14 @@ #ifndef EPHYR_LOG #define EPHYR_LOG(...) \ LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, "in %s:%d:%s: ",\ - __FILE__, __LINE__, __func__) ; \ + __FILE__, __LINE__, __FUNCTION__) ; \ LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, __VA_ARGS__) #endif /*nomadik_log*/ #ifndef EPHYR_LOG_ERROR #define EPHYR_LOG_ERROR(...) \ LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, "Error:in %s:%d:%s: ",\ - __FILE__, __LINE__, __func__) ; \ + __FILE__, __LINE__, __FUNCTION__) ; \ LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, __VA_ARGS__) #endif /*EPHYR_LOG_ERROR*/ diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c index d546370ba..7a828eb31 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.c +++ b/xorg-server/hw/kdrive/ephyr/hostx.c @@ -47,9 +47,11 @@ #include <string.h> /* for memset */ #include <time.h> +#ifndef _MSC_VER #include <sys/ipc.h> #include <sys/shm.h> #include <sys/time.h> +#endif #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -208,7 +210,11 @@ hostx_add_screen (EphyrScreenInfo screen, void hostx_set_display_name (char *name) { +#ifdef _MSC_VER + __asm int 3; +#else HostX.server_dpy_name = strdup (name); +#endif } void @@ -475,6 +481,9 @@ hostx_init (void) } /* Try to get share memory ximages for a little bit more speed */ +#ifdef _MSC_VER + __asm int 3; +#else if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM")) { fprintf(stderr, "\nXephyr unable to use SHM XImages\n"); @@ -505,6 +514,7 @@ hostx_init (void) shmdt(shminfo.shmaddr); shmctl(shminfo.shmid, IPC_RMID, 0); } +#endif XFlush(HostX.dpy); @@ -647,7 +657,7 @@ hostx_screen_init (EphyrScreenInfo screen, struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen); if (!host_screen) { - fprintf (stderr, "%s: Error in accessing hostx data\n", __func__ ); + fprintf (stderr, "%s: Error in accessing hostx data\n", __FUNCTION__ ); exit(1); } @@ -662,10 +672,14 @@ hostx_screen_init (EphyrScreenInfo screen, if (HostX.have_shm) { +#ifdef _MSC_VER + __asm int 3; +#else XShmDetach(HostX.dpy, &host_screen->shminfo); XDestroyImage (host_screen->ximg); shmdt(host_screen->shminfo.shmaddr); shmctl(host_screen->shminfo.shmid, IPC_RMID, 0); +#endif } else { @@ -681,6 +695,9 @@ hostx_screen_init (EphyrScreenInfo screen, if (HostX.have_shm) { +#ifdef _MSC_VER +__asm int 3; +#else host_screen->ximg = XShmCreateImage (HostX.dpy, HostX.visual, HostX.depth, ZPixmap, NULL, &host_screen->shminfo, width, buffer_height ); @@ -706,6 +723,7 @@ hostx_screen_init (EphyrScreenInfo screen, XShmAttach(HostX.dpy, &host_screen->shminfo); shm_success = True; } +#endif } if (!shm_success) @@ -834,9 +852,13 @@ hostx_paint_rect (EphyrScreenInfo screen, if (HostX.have_shm) { +#ifdef _MSC_VER + __asm int 3; +#else XShmPutImage (HostX.dpy, host_screen->win, HostX.gc, host_screen->ximg, sx, sy, dx, dy, width, height, False); +#endif } else { @@ -852,6 +874,9 @@ hostx_paint_debug_rect (struct EphyrHostScreen *host_screen, int x, int y, int width, int height) { +#ifdef _MSC_VER + __asm int 3; +#else struct timespec tspec; tspec.tv_sec = HostX.damage_debug_msec / (1000000); @@ -867,6 +892,7 @@ hostx_paint_debug_rect (struct EphyrHostScreen *host_screen, /* nanosleep seems to work better than usleep for me... */ nanosleep(&tspec, NULL); +#endif } void @@ -1288,8 +1314,12 @@ hostx_set_window_bounding_rectangles (int a_window, rects[i].width, rects[i].height) ; } /*this aways returns 1*/ +#ifdef _MSC_VER + __asm int 3; +#else XShapeCombineRectangles (dpy, a_window, ShapeBounding, 0, 0, rects, a_num_rects, ShapeSet, YXBanded) ; +#endif is_ok = TRUE ; if (rects) { @@ -1325,8 +1355,12 @@ hostx_set_window_clipping_rectangles (int a_window, rects[i].width, rects[i].height) ; } /*this aways returns 1*/ +#ifdef _MSC_VER + __asm int 3; +#else XShapeCombineRectangles (dpy, a_window, ShapeClip, 0, 0, rects, a_num_rects, ShapeSet, YXBanded) ; +#endif is_ok = TRUE ; if (rects) { @@ -1341,12 +1375,16 @@ int hostx_has_xshape (void) { int event_base=0, error_base=0 ; +#ifdef _MSC_VER + __asm int 3; +#else Display *dpy=hostx_get_display () ; if (!XShapeQueryExtension (dpy, &event_base, &error_base)) { return FALSE ; } +#endif return TRUE; } diff --git a/xorg-server/hw/kdrive/ephyr/hostx.h b/xorg-server/hw/kdrive/ephyr/hostx.h index e65e0c9bc..f455b3003 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.h +++ b/xorg-server/hw/kdrive/ephyr/hostx.h @@ -35,8 +35,12 @@ #define EPHYR_DBG(x, a...) \ fprintf(stderr, __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a) #else +#ifdef _MSC_VER +#define EPHYR_DBG() +#else #define EPHYR_DBG(x, a...) do {} while (0) #endif +#endif typedef struct EphyrHostXVars EphyrHostXVars; typedef struct EphyrHostXEvent EphyrHostXEvent; diff --git a/xorg-server/hw/kdrive/ephyr/makefile b/xorg-server/hw/kdrive/ephyr/makefile new file mode 100644 index 000000000..eba9a93e1 --- /dev/null +++ b/xorg-server/hw/kdrive/ephyr/makefile @@ -0,0 +1,6 @@ +LIBRARY = libxephyr + +CSRCS=ephyrinit.c ephyr.c hostx.c + +INCLUDES += ..\src ..\..\..\exa + diff --git a/xorg-server/hw/kdrive/src/kdrive.c b/xorg-server/hw/kdrive/src/kdrive.c index 5cfe54ff8..f79b96f6f 100644 --- a/xorg-server/hw/kdrive/src/kdrive.c +++ b/xorg-server/hw/kdrive/src/kdrive.c @@ -321,6 +321,7 @@ KdProcessSwitch (void) KdEnableScreens (); } +#ifndef _MSC_VER void AbortDDX(void) { @@ -343,6 +344,7 @@ ddxGiveUp (void) { AbortDDX (); } +#endif Bool kdDumbDriver; Bool kdSoftCursor; @@ -1310,11 +1312,14 @@ KdInitOutput (ScreenInfo *pScreenInfo, OsRegisterSigWrapper(KdSignalWrapper); } +#ifndef _MSC_VER void OsVendorFatalError(void) { } +#endif +#ifndef _MSC_VER int DPMSSet(ClientPtr client, int level) { @@ -1326,3 +1331,4 @@ DPMSSupported (void) { return FALSE; } +#endif diff --git a/xorg-server/hw/kdrive/src/kinput.c b/xorg-server/hw/kdrive/src/kinput.c index 65fc75a54..5222e9509 100644 --- a/xorg-server/hw/kdrive/src/kinput.c +++ b/xorg-server/hw/kdrive/src/kinput.c @@ -1,2351 +1,2376 @@ -/* - * Copyright © 1999 Keith Packard - * Copyright © 2006 Nokia Corporation - * - * 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 the authors not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. The authors make no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE AUTHORS 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. - */ - -#ifdef HAVE_CONFIG_H -#include <kdrive-config.h> -#endif -#include "kdrive.h" -#include "inputstr.h" - -#define XK_PUBLISHING -#include <X11/keysym.h> -#if HAVE_X11_XF86KEYSYM_H -#include <X11/XF86keysym.h> -#endif -#include <signal.h> -#include <stdio.h> -#ifdef sun -#include <sys/file.h> /* needed for FNONBLOCK & FASYNC */ -#endif - -#include "xkbsrv.h" - -#include <X11/extensions/XI.h> -#include <X11/extensions/XIproto.h> -#include "XIstubs.h" /* even though we don't use stubs. cute, no? */ -#include "exevents.h" -#include "extinit.h" -#include "exglobals.h" -#include "eventstr.h" -#include "xserver-properties.h" - -#define AtomFromName(x) MakeAtom(x, strlen(x), 1) - -struct KdConfigDevice { - char *line; - struct KdConfigDevice *next; -}; - -/* kdKeyboards and kdPointers hold all the real devices. */ -static KdKeyboardInfo *kdKeyboards = NULL; -static KdPointerInfo *kdPointers = NULL; -static struct KdConfigDevice *kdConfigKeyboards = NULL; -static struct KdConfigDevice *kdConfigPointers = NULL; - -static KdKeyboardDriver *kdKeyboardDrivers = NULL; -static KdPointerDriver *kdPointerDrivers = NULL; - -static EventListPtr kdEvents = NULL; - -static Bool kdInputEnabled; -static Bool kdOffScreen; -static unsigned long kdOffScreenTime; -static KdPointerMatrix kdPointerMatrix = { - { { 1, 0, 0 }, - { 0, 1, 0 } } -}; - -void KdResetInputMachine (void); - -#define KD_MAX_INPUT_FDS 8 - -typedef struct _kdInputFd { - int fd; - void (*read) (int fd, void *closure); - int (*enable) (int fd, void *closure); - void (*disable) (int fd, void *closure); - void *closure; -} KdInputFd; - -static KdInputFd kdInputFds[KD_MAX_INPUT_FDS]; -static int kdNumInputFds; - -extern Bool kdRawPointerCoordinates; - -static void -KdSigio (int sig) -{ - int i; - - for (i = 0; i < kdNumInputFds; i++) - (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); -} - -static void -KdBlockSigio (void) -{ - sigset_t set; - - sigemptyset (&set); - sigaddset (&set, SIGIO); - sigprocmask (SIG_BLOCK, &set, 0); -} - -static void -KdUnblockSigio (void) -{ - sigset_t set; - - sigemptyset (&set); - sigaddset (&set, SIGIO); - sigprocmask (SIG_UNBLOCK, &set, 0); -} - -#ifdef DEBUG_SIGIO - -void -KdAssertSigioBlocked (char *where) -{ - sigset_t set, old; - - sigemptyset (&set); - sigprocmask (SIG_BLOCK, &set, &old); - if (!sigismember (&old, SIGIO)) { - ErrorF ("SIGIO not blocked at %s\n", where); - KdBacktrace(0); - } -} - -#else - -#define KdAssertSigioBlocked(s) - -#endif - -static int kdnFds; - -#ifdef FNONBLOCK -#define NOBLOCK FNONBLOCK -#else -#define NOBLOCK FNDELAY -#endif - -void -KdResetInputMachine (void) -{ - KdPointerInfo *pi; - - for (pi = kdPointers; pi; pi = pi->next) { - pi->mouseState = start; - pi->eventHeld = FALSE; - } -} - -static void -KdNonBlockFd (int fd) -{ - int flags; - flags = fcntl (fd, F_GETFL); - flags |= FASYNC|NOBLOCK; - fcntl (fd, F_SETFL, flags); -} - -static void -KdAddFd (int fd) -{ - struct sigaction act; - sigset_t set; - - kdnFds++; - fcntl (fd, F_SETOWN, getpid()); - KdNonBlockFd (fd); - AddEnabledDevice (fd); - memset (&act, '\0', sizeof act); - act.sa_handler = KdSigio; - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGIO); - sigaddset (&act.sa_mask, SIGALRM); - sigaddset (&act.sa_mask, SIGVTALRM); - sigaction (SIGIO, &act, 0); - sigemptyset (&set); - sigprocmask (SIG_SETMASK, &set, 0); -} - -static void -KdRemoveFd (int fd) -{ - struct sigaction act; - int flags; - - kdnFds--; - RemoveEnabledDevice (fd); - flags = fcntl (fd, F_GETFL); - flags &= ~(FASYNC|NOBLOCK); - fcntl (fd, F_SETFL, flags); - if (kdnFds == 0) - { - memset (&act, '\0', sizeof act); - act.sa_handler = SIG_IGN; - sigemptyset (&act.sa_mask); - sigaction (SIGIO, &act, 0); - } -} - -Bool -KdRegisterFd (int fd, void (*read) (int fd, void *closure), void *closure) -{ - if (kdNumInputFds == KD_MAX_INPUT_FDS) - return FALSE; - kdInputFds[kdNumInputFds].fd = fd; - kdInputFds[kdNumInputFds].read = read; - kdInputFds[kdNumInputFds].enable = 0; - kdInputFds[kdNumInputFds].disable = 0; - kdInputFds[kdNumInputFds].closure = closure; - kdNumInputFds++; - if (kdInputEnabled) - KdAddFd (fd); - return TRUE; -} - -void -KdUnregisterFd (void *closure, int fd, Bool do_close) -{ - int i, j; - - for (i = 0; i < kdNumInputFds; i++) { - if (kdInputFds[i].closure == closure && - (fd == -1 || kdInputFds[i].fd == fd)) { - if (kdInputEnabled) - KdRemoveFd (kdInputFds[i].fd); - if (do_close) - close (kdInputFds[i].fd); - kdNumInputFds--; - for (j = i; j < kdNumInputFds; j++) - kdInputFds[j] = kdInputFds[j+1]; - break; - } - } -} - -void -KdUnregisterFds (void *closure, Bool do_close) -{ - KdUnregisterFd(closure, -1, do_close); -} - -void -KdDisableInput (void) -{ - KdKeyboardInfo *ki; - KdPointerInfo *pi; - int found = 0, i = 0; - - KdBlockSigio(); - - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->driver && ki->driver->Disable) - (*ki->driver->Disable) (ki); - } - - for (pi = kdPointers; pi; pi = pi->next) { - if (pi->driver && pi->driver->Disable) - (*pi->driver->Disable) (pi); - } - - if (kdNumInputFds) { - ErrorF("[KdDisableInput] Buggy drivers: still %d input fds left!", - kdNumInputFds); - i = 0; - while (i < kdNumInputFds) { - found = 0; - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki == kdInputFds[i].closure) { - ErrorF(" fd %d belongs to keybd driver %s\n", - kdInputFds[i].fd, - ki->driver && ki->driver->name ? - ki->driver->name : "(unnamed!)"); - found = 1; - break; - } - } - - if (found) { - i++; - continue; - } - - for (pi = kdPointers; pi; pi = pi->next) { - if (pi == kdInputFds[i].closure) { - ErrorF(" fd %d belongs to pointer driver %s\n", - kdInputFds[i].fd, - pi->driver && pi->driver->name ? - pi->driver->name : "(unnamed!)"); - break; - } - } - - if (found) { - i++; - continue; - } - - ErrorF(" fd %d not claimed by any active device!\n", - kdInputFds[i].fd); - KdUnregisterFd(kdInputFds[i].closure, kdInputFds[i].fd, TRUE); - } - } - - kdInputEnabled = FALSE; -} - -void -KdEnableInput (void) -{ - InternalEvent ev; - KdKeyboardInfo *ki; - KdPointerInfo *pi; - - kdInputEnabled = TRUE; - - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->driver && ki->driver->Enable) - (*ki->driver->Enable) (ki); - } - - for (pi = kdPointers; pi; pi = pi->next) { - if (pi->driver && pi->driver->Enable) - (*pi->driver->Enable) (pi); - } - - /* reset screen saver */ - ev.any.time = GetTimeInMillis (); - NoticeEventTime (&ev); - - KdUnblockSigio (); -} - -static KdKeyboardDriver * -KdFindKeyboardDriver (char *name) -{ - KdKeyboardDriver *ret; - - /* ask a stupid question ... */ - if (!name) - return NULL; - - for (ret = kdKeyboardDrivers; ret; ret = ret->next) { - if (strcmp(ret->name, name) == 0) - return ret; - } - - return NULL; -} - -static KdPointerDriver * -KdFindPointerDriver (char *name) -{ - KdPointerDriver *ret; - - /* ask a stupid question ... */ - if (!name) - return NULL; - - for (ret = kdPointerDrivers; ret; ret = ret->next) { - if (strcmp(ret->name, name) == 0) - return ret; - } - - return NULL; -} - -static int -KdPointerProc(DeviceIntPtr pDevice, int onoff) -{ - DevicePtr pDev = (DevicePtr)pDevice; - KdPointerInfo *pi; - Atom xiclass; - Atom *btn_labels; - Atom *axes_labels; - - if (!pDev) - return BadImplementation; - - for (pi = kdPointers; pi; pi = pi->next) { - if (pi->dixdev && pi->dixdev->id == pDevice->id) - break; - } - - if (!pi || !pi->dixdev || pi->dixdev->id != pDevice->id) { - ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n", - pDevice->id); - return BadImplementation; - } - - switch (onoff) - { - case DEVICE_INIT: -#ifdef DEBUG - ErrorF("initialising pointer %s ...\n", pi->name); -#endif - if (!pi->driver) { - if (!pi->driverPrivate) { - ErrorF("no driver specified for %s\n", pi->name); - return BadImplementation; - } - - pi->driver = KdFindPointerDriver(pi->driverPrivate); - if (!pi->driver) { - ErrorF("Couldn't find pointer driver %s\n", - pi->driverPrivate ? (char *) pi->driverPrivate : - "(unnamed)"); - return !Success; - } - xfree(pi->driverPrivate); - pi->driverPrivate = NULL; - } - - if (!pi->driver->Init) { - ErrorF("no init function\n"); - return BadImplementation; - } - - if ((*pi->driver->Init) (pi) != Success) { - return !Success; - } - - btn_labels = xcalloc(pi->nButtons, sizeof(Atom)); - if (!btn_labels) - return BadAlloc; - axes_labels = xcalloc(pi->nAxes, sizeof(Atom)); - if (!axes_labels) { - xfree(btn_labels); - return BadAlloc; - } - - switch(pi->nAxes) - { - default: - case 7: - btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); - case 6: - btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); - case 5: - btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); - case 4: - btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); - case 3: - btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); - case 2: - btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); - case 1: - btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); - case 0: - break; - } - - if (pi->nAxes >= 2) { - axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); - axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); - } - - InitPointerDeviceStruct(pDev, pi->map, pi->nButtons, btn_labels, - (PtrCtrlProcPtr)NoopDDA, - GetMotionHistorySize(), pi->nAxes, axes_labels); - - xfree(btn_labels); - xfree(axes_labels); - - if (pi->inputClass == KD_TOUCHSCREEN) { - InitAbsoluteClassDeviceStruct(pDevice); - xiclass = AtomFromName(XI_TOUCHSCREEN); - } - else { - xiclass = AtomFromName(XI_MOUSE); - } - - AssignTypeAndName(pi->dixdev, xiclass, - pi->name ? pi->name : "Generic KDrive Pointer"); - - return Success; - - case DEVICE_ON: - if (pDev->on == TRUE) - return Success; - - if (!pi->driver->Enable) { - ErrorF("no enable function\n"); - return BadImplementation; - } - - if ((*pi->driver->Enable) (pi) == Success) { - pDev->on = TRUE; - return Success; - } - else { - return BadImplementation; - } - - return Success; - - case DEVICE_OFF: - if (pDev->on == FALSE) { - return Success; - } - - if (!pi->driver->Disable) { - return BadImplementation; - } - else { - (*pi->driver->Disable) (pi); - pDev->on = FALSE; - return Success; - } - - return Success; - - case DEVICE_CLOSE: - if (pDev->on) { - if (!pi->driver->Disable) { - return BadImplementation; - } - (*pi->driver->Disable) (pi); - pDev->on = FALSE; - } - - if (!pi->driver->Fini) - return BadImplementation; - - (*pi->driver->Fini) (pi); - - KdRemovePointer(pi); - - return Success; - } - - /* NOTREACHED */ - return BadImplementation; -} - -Bool -LegalModifier(unsigned int key, DeviceIntPtr pDev) -{ - return TRUE; -} - -static void -KdBell (int volume, DeviceIntPtr pDev, pointer arg, int something) -{ - KeybdCtrl *ctrl = arg; - KdKeyboardInfo *ki = NULL; - - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->dixdev && ki->dixdev->id == pDev->id) - break; - } - - if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver) - return; - - KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration); -} - -void -DDXRingBell(int volume, int pitch, int duration) -{ - KdKeyboardInfo *ki = NULL; - - if (kdOsFuncs->Bell) { - (*kdOsFuncs->Bell)(volume, pitch, duration); - } - else { - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->dixdev->coreEvents) - KdRingBell(ki, volume, pitch, duration); - } - } -} - -void -KdRingBell(KdKeyboardInfo *ki, int volume, int pitch, int duration) -{ - if (!ki || !ki->driver || !ki->driver->Bell) - return; - - if (kdInputEnabled) - (*ki->driver->Bell) (ki, volume, pitch, duration); -} - - -static void -KdSetLeds (KdKeyboardInfo *ki, int leds) -{ - if (!ki || !ki->driver) - return; - - if (kdInputEnabled) { - if (ki->driver->Leds) - (*ki->driver->Leds) (ki, leds); - } -} - -void -KdSetLed (KdKeyboardInfo *ki, int led, Bool on) -{ - if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed) - return; - - NoteLedState (ki->dixdev, led, on); - KdSetLeds (ki, ki->dixdev->kbdfeed->ctrl.leds); -} - -void -KdSetPointerMatrix (KdPointerMatrix *matrix) -{ - kdPointerMatrix = *matrix; -} - -void -KdComputePointerMatrix (KdPointerMatrix *m, Rotation randr, int width, - int height) -{ - int x_dir = 1, y_dir = 1; - int i, j; - int size[2]; - - size[0] = width; size[1] = height; - if (randr & RR_Reflect_X) - x_dir = -1; - if (randr & RR_Reflect_Y) - y_dir = -1; - switch (randr & (RR_Rotate_All)) { - case RR_Rotate_0: - m->matrix[0][0] = x_dir; m->matrix[0][1] = 0; - m->matrix[1][0] = 0; m->matrix[1][1] = y_dir; - break; - case RR_Rotate_90: - m->matrix[0][0] = 0; m->matrix[0][1] = -x_dir; - m->matrix[1][0] = y_dir; m->matrix[1][1] = 0; - break; - case RR_Rotate_180: - m->matrix[0][0] = -x_dir; m->matrix[0][1] = 0; - m->matrix[1][0] = 0; m->matrix[1][1] = -y_dir; - break; - case RR_Rotate_270: - m->matrix[0][0] = 0; m->matrix[0][1] = x_dir; - m->matrix[1][0] = -y_dir; m->matrix[1][1] = 0; - break; - } - for (i = 0; i < 2; i++) - { - m->matrix[i][2] = 0; - for (j = 0 ; j < 2; j++) - if (m->matrix[i][j] < 0) - m->matrix[i][2] = size[j] - 1; - } -} - -void -KdScreenToPointerCoords (int *x, int *y) -{ - int (*m)[3] = kdPointerMatrix.matrix; - int div = m[0][1] * m[1][0] - m[1][1] * m[0][0]; - int sx = *x; - int sy = *y; - - *x = (m[0][1] * sy - m[0][1] * m[1][2] + m[1][1] * m[0][2] - m[1][1] * sx) / div; - *y = (m[1][0] * sx + m[0][0] * m[1][2] - m[1][0] * m[0][2] - m[0][0] * sy) / div; -} - -static void -KdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl) -{ - KdKeyboardInfo *ki; - - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->dixdev && ki->dixdev->id == pDevice->id) - break; - } - - if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver) - return; - - KdSetLeds(ki, ctrl->leds); - ki->bellPitch = ctrl->bell_pitch; - ki->bellDuration = ctrl->bell_duration; -} - -extern KeybdCtrl defaultKeyboardControl; - -static int -KdKeyboardProc(DeviceIntPtr pDevice, int onoff) -{ - Bool ret; - DevicePtr pDev = (DevicePtr)pDevice; - KdKeyboardInfo *ki; - Atom xiclass; - XkbRMLVOSet rmlvo; - - if (!pDev) - return BadImplementation; - - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->dixdev && ki->dixdev->id == pDevice->id) - break; - } - - if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id) { - return BadImplementation; - } - - switch (onoff) - { - case DEVICE_INIT: -#ifdef DEBUG - ErrorF("initialising keyboard %s\n", ki->name); -#endif - if (!ki->driver) { - if (!ki->driverPrivate) { - ErrorF("no driver specified!\n"); - return BadImplementation; - } - - ki->driver = KdFindKeyboardDriver(ki->driverPrivate); - if (!ki->driver) { - ErrorF("Couldn't find keyboard driver %s\n", - ki->driverPrivate ? (char *) ki->driverPrivate : - "(unnamed)"); - return !Success; - } - xfree(ki->driverPrivate); - ki->driverPrivate = NULL; - } - - if (!ki->driver->Init) { - ErrorF("Keyboard %s: no init function\n", ki->name); - return BadImplementation; - } - - if ((*ki->driver->Init) (ki) != Success) { - return !Success; - } - - memset(&rmlvo, 0, sizeof(rmlvo)); - rmlvo.rules = ki->xkbRules; - rmlvo.model = ki->xkbModel; - rmlvo.layout = ki->xkbLayout; - rmlvo.variant = ki->xkbVariant; - rmlvo.options = ki->xkbOptions; - ret = InitKeyboardDeviceStruct (pDevice, &rmlvo, KdBell, KdKbdCtrl); - if (!ret) { - ErrorF("Couldn't initialise keyboard %s\n", ki->name); - return BadImplementation; - } - - xiclass = AtomFromName(XI_KEYBOARD); - AssignTypeAndName(pDevice, xiclass, - ki->name ? ki->name : "Generic KDrive Keyboard"); - - KdResetInputMachine(); - - return Success; - - case DEVICE_ON: - if (pDev->on == TRUE) - return Success; - - if (!ki->driver->Enable) - return BadImplementation; - - if ((*ki->driver->Enable) (ki) != Success) { - return BadMatch; - } - - pDev->on = TRUE; - return Success; - - case DEVICE_OFF: - if (pDev->on == FALSE) - return Success; - - if (!ki->driver->Disable) - return BadImplementation; - - (*ki->driver->Disable) (ki); - pDev->on = FALSE; - - return Success; - - break; - - case DEVICE_CLOSE: - if (pDev->on) { - if (!ki->driver->Disable) - return BadImplementation; - - (*ki->driver->Disable) (ki); - pDev->on = FALSE; - } - - if (!ki->driver->Fini) - return BadImplementation; - - (*ki->driver->Fini) (ki); - - KdRemoveKeyboard(ki); - - return Success; - } - - /* NOTREACHED */ - return BadImplementation; -} - -void -KdAddPointerDriver (KdPointerDriver *driver) -{ - KdPointerDriver **prev; - - if (!driver) - return; - - for (prev = &kdPointerDrivers; *prev; prev = &(*prev)->next) { - if (*prev == driver) - return; - } - *prev = driver; -} - -void -KdRemovePointerDriver (KdPointerDriver *driver) -{ - KdPointerDriver *tmp; - - if (!driver) - return; - - /* FIXME remove all pointers using this driver */ - for (tmp = kdPointerDrivers; tmp; tmp = tmp->next) { - if (tmp->next == driver) - tmp->next = driver->next; - } - if (tmp == driver) - tmp = NULL; -} - -void -KdAddKeyboardDriver (KdKeyboardDriver *driver) -{ - KdKeyboardDriver **prev; - - if (!driver) - return; - - for (prev = &kdKeyboardDrivers; *prev; prev = &(*prev)->next) { - if (*prev == driver) - return; - } - *prev = driver; -} - -void -KdRemoveKeyboardDriver (KdKeyboardDriver *driver) -{ - KdKeyboardDriver *tmp; - - if (!driver) - return; - - /* FIXME remove all keyboards using this driver */ - for (tmp = kdKeyboardDrivers; tmp; tmp = tmp->next) { - if (tmp->next == driver) - tmp->next = driver->next; - } - if (tmp == driver) - tmp = NULL; -} - -KdKeyboardInfo * -KdNewKeyboard (void) -{ - KdKeyboardInfo *ki = xcalloc(sizeof(KdKeyboardInfo), 1); - if (!ki) - return NULL; - - ki->minScanCode = 0; - ki->maxScanCode = 0; - ki->leds = 0; - ki->bellPitch = 1000; - ki->bellDuration = 200; - ki->next = NULL; - ki->options = NULL; - ki->xkbRules = strdup(XKB_DFLT_RULES); - ki->xkbModel = strdup(XKB_DFLT_MODEL); - ki->xkbLayout = strdup(XKB_DFLT_LAYOUT); - ki->xkbVariant = strdup(XKB_DFLT_VARIANT); - ki->xkbOptions = strdup(XKB_DFLT_OPTIONS); - - return ki; -} - -int -KdAddConfigKeyboard (char *keyboard) -{ - struct KdConfigDevice **prev, *new; - - if (!keyboard) - return Success; - - new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1); - if (!new) - return BadAlloc; - - new->line = xstrdup(keyboard); - new->next = NULL; - - for (prev = &kdConfigKeyboards; *prev; prev = &(*prev)->next); - *prev = new; - - return Success; -} - -int -KdAddKeyboard (KdKeyboardInfo *ki) -{ - KdKeyboardInfo **prev; - - if (!ki) - return !Success; - - ki->dixdev = AddInputDevice(serverClient, KdKeyboardProc, TRUE); - if (!ki->dixdev) { - ErrorF("Couldn't register keyboard device %s\n", - ki->name ? ki->name : "(unnamed)"); - return !Success; - } - - ki->dixdev->deviceGrab.ActivateGrab = ActivateKeyboardGrab; - ki->dixdev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; - RegisterOtherDevice(ki->dixdev); - -#ifdef DEBUG - ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id); -#endif - - for (prev = &kdKeyboards; *prev; prev = &(*prev)->next); - *prev = ki; - - return Success; -} - -void -KdRemoveKeyboard (KdKeyboardInfo *ki) -{ - KdKeyboardInfo **prev; - - if (!ki) - return; - - for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) { - if (*prev == ki) { - *prev = ki->next; - break; - } - } - - KdFreeKeyboard(ki); -} - -int -KdAddConfigPointer (char *pointer) -{ - struct KdConfigDevice **prev, *new; - - if (!pointer) - return Success; - - new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1); - if (!new) - return BadAlloc; - - new->line = xstrdup(pointer); - new->next = NULL; - - for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next); - *prev = new; - - return Success; -} - -int -KdAddPointer (KdPointerInfo *pi) -{ - KdPointerInfo **prev; - - if (!pi) - return Success; - - pi->mouseState = start; - pi->eventHeld = FALSE; - - pi->dixdev = AddInputDevice(serverClient, KdPointerProc, TRUE); - if (!pi->dixdev) { - ErrorF("Couldn't add pointer device %s\n", - pi->name ? pi->name : "(unnamed)"); - return BadDevice; - } - - pi->dixdev->deviceGrab.ActivateGrab = ActivatePointerGrab; - pi->dixdev->deviceGrab.DeactivateGrab = DeactivatePointerGrab; - RegisterOtherDevice(pi->dixdev); - - for (prev = &kdPointers; *prev; prev = &(*prev)->next); - *prev = pi; - - return Success; -} - -void -KdRemovePointer (KdPointerInfo *pi) -{ - KdPointerInfo **prev; - - if (!pi) - return; - - for (prev = &kdPointers; *prev; prev = &(*prev)->next) { - if (*prev == pi) { - *prev = pi->next; - break; - } - } - - KdFreePointer(pi); -} - -/* - * You can call your kdriver server with something like: - * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd - * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br - */ -static Bool -KdGetOptions (InputOption **options, char *string) -{ - InputOption *newopt = NULL, **tmpo = NULL; - int tam_key = 0; - - newopt = xcalloc(1, sizeof (InputOption)); - if (!newopt) - return FALSE; - - for (tmpo = options; *tmpo; tmpo = &(*tmpo)->next) - ; /* Hello, I'm here */ - *tmpo = newopt; - - if (strchr(string, '=')) - { - tam_key = (strchr(string, '=') - string); - newopt->key = (char *)xalloc(tam_key); - strncpy(newopt->key, string, tam_key); - newopt->key[tam_key] = '\0'; - newopt->value = xstrdup(strchr(string, '=') + 1); - } - else - { - newopt->key = xstrdup(string); - newopt->value = NULL; - } - newopt->next = NULL; - - return TRUE; -} - -static void -KdParseKbdOptions (KdKeyboardInfo *ki) -{ - InputOption *option = NULL; - - for (option = ki->options; option; option = option->next) - { - if (strcasecmp(option->key, "XkbRules") == 0) - ki->xkbRules = option->value; - else if (strcasecmp(option->key, "XkbModel") == 0) - ki->xkbModel = option->value; - else if (strcasecmp(option->key, "XkbLayout") == 0) - ki->xkbLayout = option->value; - else if (strcasecmp(option->key, "XkbVariant") == 0) - ki->xkbVariant = option->value; - else if (strcasecmp(option->key, "XkbOptions") == 0) - ki->xkbOptions = option->value; - else if (!strcasecmp (option->key, "device")) - ki->path = strdup(option->value); - else - ErrorF("Kbd option key (%s) of value (%s) not assigned!\n", - option->key, option->value); - } -} - -KdKeyboardInfo * -KdParseKeyboard (char *arg) -{ - char save[1024]; - char delim; - InputOption *options = NULL; - KdKeyboardInfo *ki = NULL; - - ki = KdNewKeyboard(); - if (!ki) - return NULL; - - ki->name = strdup("Unknown KDrive Keyboard"); - ki->path = NULL; - ki->driver = NULL; - ki->driverPrivate = NULL; - ki->next = NULL; - - if (!arg) - { - ErrorF("keybd: no arg\n"); - KdFreeKeyboard (ki); - return NULL; - } - - if (strlen (arg) >= sizeof (save)) - { - ErrorF("keybd: arg too long\n"); - KdFreeKeyboard (ki); - return NULL; - } - - arg = KdParseFindNext (arg, ",", save, &delim); - if (!save[0]) - { - ErrorF("keybd: failed on save[0]\n"); - KdFreeKeyboard (ki); - return NULL; - } - - if (strcmp (save, "auto") == 0) - ki->driverPrivate = NULL; - else - ki->driverPrivate = xstrdup(save); - - if (delim != ',') - { - return ki; - } - - arg = KdParseFindNext (arg, ",", save, &delim); - - while (delim == ',') - { - arg = KdParseFindNext (arg, ",", save, &delim); - - if (!KdGetOptions(&options, save)) - { - KdFreeKeyboard(ki); - return NULL; - } - } - - if (options) - { - ki->options = options; - KdParseKbdOptions(ki); - } - - return ki; -} - -static void -KdParsePointerOptions (KdPointerInfo *pi) -{ - InputOption *option = NULL; - - for (option = pi->options; option; option = option->next) - { - if (!strcmp (option->key, "emulatemiddle")) - pi->emulateMiddleButton = TRUE; - else if (!strcmp (option->key, "noemulatemiddle")) - pi->emulateMiddleButton = FALSE; - else if (!strcmp (option->key, "transformcoord")) - pi->transformCoordinates = TRUE; - else if (!strcmp (option->key, "rawcoord")) - pi->transformCoordinates = FALSE; - else if (!strcasecmp (option->key, "device")) - pi->path = strdup(option->value); - else if (!strcasecmp (option->key, "protocol")) - pi->protocol = strdup(option->value); - else - ErrorF("Pointer option key (%s) of value (%s) not assigned!\n", - option->key, option->value); - } -} - -KdPointerInfo * -KdParsePointer (char *arg) -{ - char save[1024]; - char delim; - KdPointerInfo *pi = NULL; - InputOption *options = NULL; - int i = 0; - - pi = KdNewPointer(); - if (!pi) - return NULL; - pi->emulateMiddleButton = kdEmulateMiddleButton; - pi->transformCoordinates = !kdRawPointerCoordinates; - pi->protocol = NULL; - pi->nButtons = 5; /* XXX should not be hardcoded */ - pi->inputClass = KD_MOUSE; - - if (!arg) - { - ErrorF("mouse: no arg\n"); - KdFreePointer (pi); - return NULL; - } - - if (strlen (arg) >= sizeof (save)) - { - ErrorF("mouse: arg too long\n"); - KdFreePointer (pi); - return NULL; - } - arg = KdParseFindNext (arg, ",", save, &delim); - if (!save[0]) - { - ErrorF("failed on save[0]\n"); - KdFreePointer (pi); - return NULL; - } - - if (strcmp(save, "auto") == 0) - pi->driverPrivate = NULL; - else - pi->driverPrivate = xstrdup(save); - - if (delim != ',') - { - return pi; - } - - arg = KdParseFindNext (arg, ",", save, &delim); - - while (delim == ',') - { - arg = KdParseFindNext (arg, ",", save, &delim); - if (save[0] == '{') - { - char *s = save + 1; - i = 0; - while (*s && *s != '}') - { - if ('1' <= *s && *s <= '0' + pi->nButtons) - pi->map[i] = *s - '0'; - else - UseMsg (); - s++; - } - } - else - { - if (!KdGetOptions(&options, save)) - { - KdFreePointer(pi); - return NULL; - } - } - } - - if (options) - { - pi->options = options; - KdParsePointerOptions(pi); - } - - return pi; -} - - -void -KdInitInput (void) -{ - KdPointerInfo *pi; - KdKeyboardInfo *ki; - struct KdConfigDevice *dev; - - kdInputEnabled = TRUE; - - for (dev = kdConfigPointers; dev; dev = dev->next) { - pi = KdParsePointer(dev->line); - if (!pi) - ErrorF("Failed to parse pointer\n"); - if (KdAddPointer(pi) != Success) - ErrorF("Failed to add pointer!\n"); - } - for (dev = kdConfigKeyboards; dev; dev = dev->next) { - ki = KdParseKeyboard(dev->line); - if (!ki) - ErrorF("Failed to parse keyboard\n"); - if (KdAddKeyboard(ki) != Success) - ErrorF("Failed to add keyboard!\n"); - } - - mieqInit(); -} - -/* - * Middle button emulation state machine - * - * Possible transitions: - * Button 1 press v1 - * Button 1 release ^1 - * Button 2 press v2 - * Button 2 release ^2 - * Button 3 press v3 - * Button 3 release ^3 - * Button other press vo - * Button other release ^o - * Mouse motion <> - * Keyboard event k - * timeout ... - * outside box <-> - * - * States: - * start - * button_1_pend - * button_1_down - * button_2_down - * button_3_pend - * button_3_down - * synthetic_2_down_13 - * synthetic_2_down_3 - * synthetic_2_down_1 - * - * Transition diagram - * - * start - * v1 -> (hold) (settimeout) button_1_pend - * ^1 -> (deliver) start - * v2 -> (deliver) button_2_down - * ^2 -> (deliever) start - * v3 -> (hold) (settimeout) button_3_pend - * ^3 -> (deliver) start - * vo -> (deliver) start - * ^o -> (deliver) start - * <> -> (deliver) start - * k -> (deliver) start - * - * button_1_pend (button 1 is down, timeout pending) - * ^1 -> (release) (deliver) start - * v2 -> (release) (deliver) button_1_down - * ^2 -> (release) (deliver) button_1_down - * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13 - * ^3 -> (release) (deliver) button_1_down - * vo -> (release) (deliver) button_1_down - * ^o -> (release) (deliver) button_1_down - * <-> -> (release) (deliver) button_1_down - * <> -> (deliver) button_1_pend - * k -> (release) (deliver) button_1_down - * ... -> (release) button_1_down - * - * button_1_down (button 1 is down) - * ^1 -> (deliver) start - * v2 -> (deliver) button_1_down - * ^2 -> (deliver) button_1_down - * v3 -> (deliver) button_1_down - * ^3 -> (deliver) button_1_down - * vo -> (deliver) button_1_down - * ^o -> (deliver) button_1_down - * <> -> (deliver) button_1_down - * k -> (deliver) button_1_down - * - * button_2_down (button 2 is down) - * v1 -> (deliver) button_2_down - * ^1 -> (deliver) button_2_down - * ^2 -> (deliver) start - * v3 -> (deliver) button_2_down - * ^3 -> (deliver) button_2_down - * vo -> (deliver) button_2_down - * ^o -> (deliver) button_2_down - * <> -> (deliver) button_2_down - * k -> (deliver) button_2_down - * - * button_3_pend (button 3 is down, timeout pending) - * v1 -> (generate v2) synthetic_2_down - * ^1 -> (release) (deliver) button_3_down - * v2 -> (release) (deliver) button_3_down - * ^2 -> (release) (deliver) button_3_down - * ^3 -> (release) (deliver) start - * vo -> (release) (deliver) button_3_down - * ^o -> (release) (deliver) button_3_down - * <-> -> (release) (deliver) button_3_down - * <> -> (deliver) button_3_pend - * k -> (release) (deliver) button_3_down - * ... -> (release) button_3_down - * - * button_3_down (button 3 is down) - * v1 -> (deliver) button_3_down - * ^1 -> (deliver) button_3_down - * v2 -> (deliver) button_3_down - * ^2 -> (deliver) button_3_down - * ^3 -> (deliver) start - * vo -> (deliver) button_3_down - * ^o -> (deliver) button_3_down - * <> -> (deliver) button_3_down - * k -> (deliver) button_3_down - * - * synthetic_2_down_13 (button 1 and 3 are down) - * ^1 -> (generate ^2) synthetic_2_down_3 - * v2 -> synthetic_2_down_13 - * ^2 -> synthetic_2_down_13 - * ^3 -> (generate ^2) synthetic_2_down_1 - * vo -> (deliver) synthetic_2_down_13 - * ^o -> (deliver) synthetic_2_down_13 - * <> -> (deliver) synthetic_2_down_13 - * k -> (deliver) synthetic_2_down_13 - * - * synthetic_2_down_3 (button 3 is down) - * v1 -> (deliver) synthetic_2_down_3 - * ^1 -> (deliver) synthetic_2_down_3 - * v2 -> synthetic_2_down_3 - * ^2 -> synthetic_2_down_3 - * ^3 -> start - * vo -> (deliver) synthetic_2_down_3 - * ^o -> (deliver) synthetic_2_down_3 - * <> -> (deliver) synthetic_2_down_3 - * k -> (deliver) synthetic_2_down_3 - * - * synthetic_2_down_1 (button 1 is down) - * ^1 -> start - * v2 -> synthetic_2_down_1 - * ^2 -> synthetic_2_down_1 - * v3 -> (deliver) synthetic_2_down_1 - * ^3 -> (deliver) synthetic_2_down_1 - * vo -> (deliver) synthetic_2_down_1 - * ^o -> (deliver) synthetic_2_down_1 - * <> -> (deliver) synthetic_2_down_1 - * k -> (deliver) synthetic_2_down_1 - */ - -typedef enum _inputClass { - down_1, up_1, - down_2, up_2, - down_3, up_3, - down_o, up_o, - motion, outside_box, - keyboard, timeout, - num_input_class -} KdInputClass; - -typedef enum _inputAction { - noop, - hold, - setto, - deliver, - release, - clearto, - gen_down_2, - gen_up_2 -} KdInputAction; - -#define MAX_ACTIONS 2 - -typedef struct _inputTransition { - KdInputAction actions[MAX_ACTIONS]; - KdPointerState nextState; -} KdInputTransition; - -static const -KdInputTransition kdInputMachine[num_input_states][num_input_class] = { - /* start */ - { - { { hold, setto }, button_1_pend }, /* v1 */ - { { deliver, noop }, start }, /* ^1 */ - { { deliver, noop }, button_2_down }, /* v2 */ - { { deliver, noop }, start }, /* ^2 */ - { { hold, setto }, button_3_pend }, /* v3 */ - { { deliver, noop }, start }, /* ^3 */ - { { deliver, noop }, start }, /* vo */ - { { deliver, noop }, start }, /* ^o */ - { { deliver, noop }, start }, /* <> */ - { { deliver, noop }, start }, /* <-> */ - { { noop, noop }, start }, /* k */ - { { noop, noop }, start }, /* ... */ - }, - /* button_1_pend */ - { - { { noop, noop }, button_1_pend }, /* v1 */ - { { release, deliver }, start }, /* ^1 */ - { { release, deliver }, button_1_down }, /* v2 */ - { { release, deliver }, button_1_down }, /* ^2 */ - { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */ - { { release, deliver }, button_1_down }, /* ^3 */ - { { release, deliver }, button_1_down }, /* vo */ - { { release, deliver }, button_1_down }, /* ^o */ - { { deliver, noop }, button_1_pend }, /* <> */ - { { release, deliver }, button_1_down }, /* <-> */ - { { noop, noop }, button_1_down }, /* k */ - { { release, noop }, button_1_down }, /* ... */ - }, - /* button_1_down */ - { - { { noop, noop }, button_1_down }, /* v1 */ - { { deliver, noop }, start }, /* ^1 */ - { { deliver, noop }, button_1_down }, /* v2 */ - { { deliver, noop }, button_1_down }, /* ^2 */ - { { deliver, noop }, button_1_down }, /* v3 */ - { { deliver, noop }, button_1_down }, /* ^3 */ - { { deliver, noop }, button_1_down }, /* vo */ - { { deliver, noop }, button_1_down }, /* ^o */ - { { deliver, noop }, button_1_down }, /* <> */ - { { deliver, noop }, button_1_down }, /* <-> */ - { { noop, noop }, button_1_down }, /* k */ - { { noop, noop }, button_1_down }, /* ... */ - }, - /* button_2_down */ - { - { { deliver, noop }, button_2_down }, /* v1 */ - { { deliver, noop }, button_2_down }, /* ^1 */ - { { noop, noop }, button_2_down }, /* v2 */ - { { deliver, noop }, start }, /* ^2 */ - { { deliver, noop }, button_2_down }, /* v3 */ - { { deliver, noop }, button_2_down }, /* ^3 */ - { { deliver, noop }, button_2_down }, /* vo */ - { { deliver, noop }, button_2_down }, /* ^o */ - { { deliver, noop }, button_2_down }, /* <> */ - { { deliver, noop }, button_2_down }, /* <-> */ - { { noop, noop }, button_2_down }, /* k */ - { { noop, noop }, button_2_down }, /* ... */ - }, - /* button_3_pend */ - { - { { clearto, gen_down_2 }, synth_2_down_13 }, /* v1 */ - { { release, deliver }, button_3_down }, /* ^1 */ - { { release, deliver }, button_3_down }, /* v2 */ - { { release, deliver }, button_3_down }, /* ^2 */ - { { release, deliver }, button_3_down }, /* v3 */ - { { release, deliver }, start }, /* ^3 */ - { { release, deliver }, button_3_down }, /* vo */ - { { release, deliver }, button_3_down }, /* ^o */ - { { deliver, noop }, button_3_pend }, /* <> */ - { { release, deliver }, button_3_down }, /* <-> */ - { { release, noop }, button_3_down }, /* k */ - { { release, noop }, button_3_down }, /* ... */ - }, - /* button_3_down */ - { - { { deliver, noop }, button_3_down }, /* v1 */ - { { deliver, noop }, button_3_down }, /* ^1 */ - { { deliver, noop }, button_3_down }, /* v2 */ - { { deliver, noop }, button_3_down }, /* ^2 */ - { { noop, noop }, button_3_down }, /* v3 */ - { { deliver, noop }, start }, /* ^3 */ - { { deliver, noop }, button_3_down }, /* vo */ - { { deliver, noop }, button_3_down }, /* ^o */ - { { deliver, noop }, button_3_down }, /* <> */ - { { deliver, noop }, button_3_down }, /* <-> */ - { { noop, noop }, button_3_down }, /* k */ - { { noop, noop }, button_3_down }, /* ... */ - }, - /* synthetic_2_down_13 */ - { - { { noop, noop }, synth_2_down_13 }, /* v1 */ - { { gen_up_2, noop }, synth_2_down_3 }, /* ^1 */ - { { noop, noop }, synth_2_down_13 }, /* v2 */ - { { noop, noop }, synth_2_down_13 }, /* ^2 */ - { { noop, noop }, synth_2_down_13 }, /* v3 */ - { { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */ - { { deliver, noop }, synth_2_down_13 }, /* vo */ - { { deliver, noop }, synth_2_down_13 }, /* ^o */ - { { deliver, noop }, synth_2_down_13 }, /* <> */ - { { deliver, noop }, synth_2_down_13 }, /* <-> */ - { { noop, noop }, synth_2_down_13 }, /* k */ - { { noop, noop }, synth_2_down_13 }, /* ... */ - }, - /* synthetic_2_down_3 */ - { - { { deliver, noop }, synth_2_down_3 }, /* v1 */ - { { deliver, noop }, synth_2_down_3 }, /* ^1 */ - { { deliver, noop }, synth_2_down_3 }, /* v2 */ - { { deliver, noop }, synth_2_down_3 }, /* ^2 */ - { { noop, noop }, synth_2_down_3 }, /* v3 */ - { { noop, noop }, start }, /* ^3 */ - { { deliver, noop }, synth_2_down_3 }, /* vo */ - { { deliver, noop }, synth_2_down_3 }, /* ^o */ - { { deliver, noop }, synth_2_down_3 }, /* <> */ - { { deliver, noop }, synth_2_down_3 }, /* <-> */ - { { noop, noop }, synth_2_down_3 }, /* k */ - { { noop, noop }, synth_2_down_3 }, /* ... */ - }, - /* synthetic_2_down_1 */ - { - { { noop, noop }, synth_2_down_1 }, /* v1 */ - { { noop, noop }, start }, /* ^1 */ - { { deliver, noop }, synth_2_down_1 }, /* v2 */ - { { deliver, noop }, synth_2_down_1 }, /* ^2 */ - { { deliver, noop }, synth_2_down_1 }, /* v3 */ - { { deliver, noop }, synth_2_down_1 }, /* ^3 */ - { { deliver, noop }, synth_2_down_1 }, /* vo */ - { { deliver, noop }, synth_2_down_1 }, /* ^o */ - { { deliver, noop }, synth_2_down_1 }, /* <> */ - { { deliver, noop }, synth_2_down_1 }, /* <-> */ - { { noop, noop }, synth_2_down_1 }, /* k */ - { { noop, noop }, synth_2_down_1 }, /* ... */ - }, -}; - -#define EMULATION_WINDOW 10 -#define EMULATION_TIMEOUT 100 - -static int -KdInsideEmulationWindow (KdPointerInfo *pi, int x, int y, int z) -{ - pi->emulationDx = pi->heldEvent.x - x; - pi->emulationDy = pi->heldEvent.y - y; - - return (abs (pi->emulationDx) < EMULATION_WINDOW && - abs (pi->emulationDy) < EMULATION_WINDOW); -} - -static KdInputClass -KdClassifyInput (KdPointerInfo *pi, int type, int x, int y, int z, int b) -{ - switch (type) { - case ButtonPress: - switch (b) { - case 1: return down_1; - case 2: return down_2; - case 3: return down_3; - default: return down_o; - } - break; - case ButtonRelease: - switch (b) { - case 1: return up_1; - case 2: return up_2; - case 3: return up_3; - default: return up_o; - } - break; - case MotionNotify: - if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z)) - return outside_box; - else - return motion; - default: - return keyboard; - } - return keyboard; -} - -#ifdef DEBUG -char *kdStateNames[] = { - "start", - "button_1_pend", - "button_1_down", - "button_2_down", - "button_3_pend", - "button_3_down", - "synth_2_down_13", - "synth_2_down_3", - "synthetic_2_down_1", - "num_input_states" -}; - -char *kdClassNames[] = { - "down_1", "up_1", - "down_2", "up_2", - "down_3", "up_3", - "motion", "ouside_box", - "keyboard", "timeout", - "num_input_class" -}; - -char *kdActionNames[] = { - "noop", - "hold", - "setto", - "deliver", - "release", - "clearto", - "gen_down_2", - "gen_up_2", -}; -#endif /* DEBUG */ - -static void -KdQueueEvent (DeviceIntPtr pDev, InternalEvent *ev) -{ - KdAssertSigioBlocked ("KdQueueEvent"); - mieqEnqueue (pDev, ev); -} - -/* We return true if we're stealing the event. */ -static Bool -KdRunMouseMachine (KdPointerInfo *pi, KdInputClass c, int type, int x, int y, - int z, int b, int absrel) -{ - const KdInputTransition *t; - int a; - - c = KdClassifyInput(pi, type, x, y, z, b); - t = &kdInputMachine[pi->mouseState][c]; - for (a = 0; a < MAX_ACTIONS; a++) - { - switch (t->actions[a]) { - case noop: - break; - case hold: - pi->eventHeld = TRUE; - pi->emulationDx = 0; - pi->emulationDy = 0; - pi->heldEvent.type = type; - pi->heldEvent.x = x; - pi->heldEvent.y = y; - pi->heldEvent.z = z; - pi->heldEvent.flags = b; - pi->heldEvent.absrel = absrel; - return TRUE; - break; - case setto: - pi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT; - pi->timeoutPending = TRUE; - break; - case deliver: - _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, - pi->heldEvent.y, pi->heldEvent.z, - pi->heldEvent.flags, pi->heldEvent.absrel, - TRUE); - break; - case release: - pi->eventHeld = FALSE; - pi->timeoutPending = FALSE; - _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, - pi->heldEvent.y, pi->heldEvent.z, - pi->heldEvent.flags, pi->heldEvent.absrel, - TRUE); - return TRUE; - break; - case clearto: - pi->timeoutPending = FALSE; - break; - case gen_down_2: - _KdEnqueuePointerEvent (pi, ButtonPress, x, y, z, 2, absrel, - TRUE); - pi->eventHeld = FALSE; - return TRUE; - break; - case gen_up_2: - _KdEnqueuePointerEvent (pi, ButtonRelease, x, y, z, 2, absrel, - TRUE); - return TRUE; - break; - } - } - pi->mouseState = t->nextState; - return FALSE; -} - -static int -KdHandlePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b, - int absrel) -{ - if (pi->emulateMiddleButton) - return KdRunMouseMachine (pi, KdClassifyInput(pi, type, x, y, z, b), - type, x, y, z, b, absrel); - return FALSE; -} - -static void -KdReceiveTimeout (KdPointerInfo *pi) -{ - KdRunMouseMachine (pi, timeout, 0, 0, 0, 0, 0, 0); -} - -/* - * kdCheckTermination - * - * This function checks for the key sequence that terminates the server. When - * detected, it sets the dispatchException flag and returns. The key sequence - * is: - * Control-Alt - * It's assumed that the server will be waken up by the caller when this - * function returns. - */ - -extern int nClients; - -void -KdReleaseAllKeys (void) -{ -#if 0 - int key, nEvents, i; - KdKeyboardInfo *ki; - - KdBlockSigio (); - - for (ki = kdKeyboards; ki; ki = ki->next) { - for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode; - key++) { - if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) { - KdHandleKeyboardEvent(ki, KeyRelease, key); - GetEventList(&kdEvents); - nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key); - for (i = 0; i < nEvents; i++) - KdQueueEvent (ki->dixdev, (kdEvents + i)->event); - } - } - } - - KdUnblockSigio (); -#endif -} - -static void -KdCheckLock (void) -{ - KeyClassPtr keyc = NULL; - Bool isSet = FALSE, shouldBeSet = FALSE; - KdKeyboardInfo *tmp = NULL; - - for (tmp = kdKeyboards; tmp; tmp = tmp->next) { - if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) { - keyc = tmp->dixdev->key; - isSet = (tmp->leds & (1 << (tmp->LockLed-1))) != 0; - /* FIXME: Just use XKB indicators! */ - shouldBeSet = !!(XkbStateFieldFromRec(&keyc->xkbInfo->state) & LockMask); - if (isSet != shouldBeSet) - KdSetLed (tmp, tmp->LockLed, shouldBeSet); - } - } -} - -void -KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, - unsigned char scan_code, - unsigned char is_up) -{ - unsigned char key_code; - KeyClassPtr keyc = NULL; - KeybdCtrl *ctrl = NULL; - int type, nEvents, i; - - if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key) - return; - - keyc = ki->dixdev->key; - ctrl = &ki->dixdev->kbdfeed->ctrl; - - if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) - { - key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode; - - /* - * Set up this event -- the type may be modified below - */ - if (is_up) - type = KeyRelease; - else - type = KeyPress; - - GetEventList(&kdEvents); - - nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code); - for (i = 0; i < nEvents; i++) - KdQueueEvent(ki->dixdev, (InternalEvent *)((kdEvents + i)->event)); - } - else { - ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", - ki->name, scan_code, ki->minScanCode, ki->maxScanCode); - } -} - -/* - * kdEnqueuePointerEvent - * - * This function converts hardware mouse event information into X event - * information. A mouse movement event is passed off to MI to generate - * a MotionNotify event, if appropriate. Button events are created and - * passed off to MI for enqueueing. - */ - -/* FIXME do something a little more clever to deal with multiple axes here */ -void -KdEnqueuePointerEvent(KdPointerInfo *pi, unsigned long flags, int rx, int ry, - int rz) -{ - CARD32 ms; - unsigned char buttons; - int x, y, z; - int (*matrix)[3] = kdPointerMatrix.matrix; - unsigned long button; - int n; - int dixflags = 0; - - if (!pi) - return; - - ms = GetTimeInMillis(); - - /* we don't need to transform z, so we don't. */ - if (flags & KD_MOUSE_DELTA) { - if (pi->transformCoordinates) { - x = matrix[0][0] * rx + matrix[0][1] * ry; - y = matrix[1][0] * rx + matrix[1][1] * ry; - } - else { - x = rx; - y = ry; - } - } - else { - if (pi->transformCoordinates) { - x = matrix[0][0] * rx + matrix[0][1] * ry + matrix[0][2]; - y = matrix[1][0] * rx + matrix[1][1] * ry + matrix[1][2]; - } - else { - x = rx; - y = ry; - } - } - z = rz; - - if (flags & KD_MOUSE_DELTA) - { - if (x || y || z) - { - dixflags = POINTER_RELATIVE | POINTER_ACCELERATE; - _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE); - } - } else - { - dixflags = POINTER_ABSOLUTE; - if (x != pi->dixdev->last.valuators[0] || - y != pi->dixdev->last.valuators[1]) - _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE); - } - - buttons = flags; - - for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; - button <<= 1, n++) { - if (((pi->buttonState & button) ^ (buttons & button)) && - !(buttons & button)) { - _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n, - dixflags, FALSE); - } - } - for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; - button <<= 1, n++) { - if (((pi->buttonState & button) ^ (buttons & button)) && - (buttons & button)) { - _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n, - dixflags, FALSE); - } - } - - pi->buttonState = buttons; -} - -void -_KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, - int b, int absrel, Bool force) -{ - int nEvents = 0, i = 0; - int valuators[3] = { x, y, z }; - - /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */ - if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel)) - return; - - GetEventList(&kdEvents); - nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, - 0, 3, valuators); - for (i = 0; i < nEvents; i++) - KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event)); -} - -void -KdBlockHandler (int screen, - pointer blockData, - pointer timeout, - pointer readmask) -{ - KdPointerInfo *pi; - int myTimeout=0; - - for (pi = kdPointers; pi; pi = pi->next) - { - if (pi->timeoutPending) - { - int ms; - - ms = pi->emulationTimeout - GetTimeInMillis (); - if (ms < 1) - ms = 1; - if(ms<myTimeout || myTimeout==0) - myTimeout=ms; - } - } - /* if we need to poll for events, do that */ - if(kdOsFuncs->pollEvents) - { - (*kdOsFuncs->pollEvents)(); - myTimeout=20; - } - if(myTimeout>0) - AdjustWaitForDelay (timeout, myTimeout); -} - -void -KdWakeupHandler (int screen, - pointer data, - unsigned long lresult, - pointer readmask) -{ - int result = (int) lresult; - fd_set *pReadmask = (fd_set *) readmask; - int i; - KdPointerInfo *pi; - - if (kdInputEnabled && result > 0) - { - for (i = 0; i < kdNumInputFds; i++) - if (FD_ISSET (kdInputFds[i].fd, pReadmask)) - { - KdBlockSigio (); - (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); - KdUnblockSigio (); - } - } - for (pi = kdPointers; pi; pi = pi->next) - { - if (pi->timeoutPending) - { - if ((long) (GetTimeInMillis () - pi->emulationTimeout) >= 0) - { - pi->timeoutPending = FALSE; - KdBlockSigio (); - KdReceiveTimeout (pi); - KdUnblockSigio (); - } - } - } - if (kdSwitchPending) - KdProcessSwitch (); -} - -#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin)) - -static Bool -KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) -{ - ScreenPtr pScreen = *ppScreen; - ScreenPtr pNewScreen; - int n; - int dx, dy; - int best_x, best_y; - int n_best_x, n_best_y; - CARD32 ms; - - if (kdDisableZaphod || screenInfo.numScreens <= 1) - return FALSE; - - if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height) - return FALSE; - - ms = GetTimeInMillis (); - if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000) - return FALSE; - kdOffScreen = TRUE; - kdOffScreenTime = ms; - n_best_x = -1; - best_x = 32767; - n_best_y = -1; - best_y = 32767; - for (n = 0; n < screenInfo.numScreens; n++) - { - pNewScreen = screenInfo.screens[n]; - if (pNewScreen == pScreen) - continue; - dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x; - dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y; - if (*x < 0) - { - if (dx <= 0 && -dx < best_x) - { - best_x = -dx; - n_best_x = n; - } - } - else if (*x >= pScreen->width) - { - if (dx >= 0 && dx < best_x) - { - best_x = dx; - n_best_x = n; - } - } - if (*y < 0) - { - if (dy <= 0 && -dy < best_y) - { - best_y = -dy; - n_best_y = n; - } - } - else if (*y >= pScreen->height) - { - if (dy >= 0 && dy < best_y) - { - best_y = dy; - n_best_y = n; - } - } - } - if (best_y < best_x) - n_best_x = n_best_y; - if (n_best_x == -1) - return FALSE; - pNewScreen = screenInfo.screens[n_best_x]; - - if (*x < 0) - *x += pNewScreen->width; - if (*y < 0) - *y += pNewScreen->height; - - if (*x >= pScreen->width) - *x -= pScreen->width; - if (*y >= pScreen->height) - *y -= pScreen->height; - - *ppScreen = pNewScreen; - return TRUE; -} - -static void -KdCrossScreen(ScreenPtr pScreen, Bool entering) -{ -#ifndef XIPAQ - if (entering) - KdEnableScreen (pScreen); - else - KdDisableScreen (pScreen); -#endif -} - -int KdCurScreen; /* current event screen */ - -static void -KdWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ - KdBlockSigio (); - KdCurScreen = pScreen->myNum; - miPointerWarpCursor(pDev, pScreen, x, y); - KdUnblockSigio (); -} - -miPointerScreenFuncRec kdPointerScreenFuncs = -{ - KdCursorOffScreen, - KdCrossScreen, - KdWarpCursor -}; - -void -ProcessInputEvents (void) -{ - mieqProcessInputEvents(); - miPointerUpdateSprite(inputInfo.pointer); - if (kdSwitchPending) - KdProcessSwitch (); - KdCheckLock (); -} - -/* FIXME use XSECURITY to work out whether the client should be allowed to - * open and close. */ -void -OpenInputDevice(DeviceIntPtr pDev, ClientPtr client, int *status) -{ - if (!pDev) - *status = BadDevice; - else - *status = Success; -} - -void -CloseInputDevice(DeviceIntPtr pDev, ClientPtr client) -{ - return; -} - -/* We initialise all input devices at startup. */ -void -AddOtherInputDevices(void) -{ - return; -} - -/* At the moment, absolute/relative is up to the client. */ -int -SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode) -{ - return BadMatch; -} - -int -SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev, - int *valuators, int first_valuator, int num_valuators) -{ - return BadMatch; -} - -int -ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev, - xDeviceCtl *control) -{ - switch (control->control) { - case DEVICE_RESOLUTION: - /* FIXME do something more intelligent here */ - return BadMatch; - - case DEVICE_ABS_CALIB: - case DEVICE_ABS_AREA: - return Success; - - case DEVICE_CORE: - return BadMatch; - case DEVICE_ENABLE: - return Success; - - default: - return BadMatch; - } - - /* NOTREACHED */ - return BadImplementation; -} - -int -NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) -{ - InputOption *option = NULL; - KdPointerInfo *pi = NULL; - KdKeyboardInfo *ki = NULL; - - for (option = options; option; option = option->next) { - if (strcmp(option->key, "type") == 0) { - if (strcmp(option->value, "pointer") == 0) { - pi = KdNewPointer(); - if (!pi) - return BadAlloc; - } - else if (strcmp(option->value, "keyboard") == 0) { - ki = KdNewKeyboard(); - if (!ki) - return BadAlloc; - } - else { - ErrorF("unrecognised device type!\n"); - return BadValue; - } - } -#ifdef CONFIG_HAL - else if (strcmp(option->key, "_source") == 0 && - strcmp(option->value, "server/hal") == 0) - { - ErrorF("Ignoring device from HAL.\n"); - return BadValue; - } -#endif - } - - if (!ki && !pi) { - ErrorF("unrecognised device identifier!\n"); - return BadValue; - } - - /* FIXME: change this code below to use KdParseKbdOptions and - * KdParsePointerOptions */ - for (option = options; option; option = option->next) { - if (strcmp(option->key, "device") == 0) { - if (pi && option->value) - pi->path = strdup(option->value); - else if (ki && option->value) - ki->path = strdup(option->value); - } - else if (strcmp(option->key, "driver") == 0) { - if (pi) { - pi->driver = KdFindPointerDriver(option->value); - if (!pi->driver) { - ErrorF("couldn't find driver!\n"); - KdFreePointer(pi); - return BadValue; - } - pi->options = options; - } - else if (ki) { - ki->driver = KdFindKeyboardDriver(option->value); - if (!ki->driver) { - ErrorF("couldn't find driver!\n"); - KdFreeKeyboard(ki); - return BadValue; - } - ki->options = options; - } - } - } - - if (pi) { - if (KdAddPointer(pi) != Success || - ActivateDevice(pi->dixdev, TRUE) != Success || - EnableDevice(pi->dixdev, TRUE) != TRUE) { - ErrorF("couldn't add or enable pointer\n"); - return BadImplementation; - } - } - else if (ki) { - if (KdAddKeyboard(ki) != Success || - ActivateDevice(ki->dixdev, TRUE) != Success || - EnableDevice(ki->dixdev, TRUE) != TRUE) { - ErrorF("couldn't add or enable keyboard\n"); - return BadImplementation; - } - } - - if (pi) { - *pdev = pi->dixdev; - } else if(ki) { - *pdev = ki->dixdev; - } - - return Success; -} - -void -DeleteInputDeviceRequest(DeviceIntPtr pDev) -{ - RemoveDevice(pDev, TRUE); -} +/*
+ * Copyright © 1999 Keith Packard
+ * Copyright © 2006 Nokia Corporation
+ *
+ * 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 the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "kdrive.h"
+#include "inputstr.h"
+
+#define XK_PUBLISHING
+#include <X11/keysym.h>
+#if HAVE_X11_XF86KEYSYM_H
+#include <X11/XF86keysym.h>
+#endif
+#include <signal.h>
+#include <stdio.h>
+#ifdef sun
+#include <sys/file.h> /* needed for FNONBLOCK & FASYNC */
+#endif
+
+#include "xkbsrv.h"
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "XIstubs.h" /* even though we don't use stubs. cute, no? */
+#include "exevents.h"
+#include "extinit.h"
+#include "exglobals.h"
+#include "eventstr.h"
+#include "xserver-properties.h"
+
+#define AtomFromName(x) MakeAtom(x, strlen(x), 1)
+
+struct KdConfigDevice {
+ char *line;
+ struct KdConfigDevice *next;
+};
+
+/* kdKeyboards and kdPointers hold all the real devices. */
+static KdKeyboardInfo *kdKeyboards = NULL;
+static KdPointerInfo *kdPointers = NULL;
+static struct KdConfigDevice *kdConfigKeyboards = NULL;
+static struct KdConfigDevice *kdConfigPointers = NULL;
+
+static KdKeyboardDriver *kdKeyboardDrivers = NULL;
+static KdPointerDriver *kdPointerDrivers = NULL;
+
+static EventListPtr kdEvents = NULL;
+
+static Bool kdInputEnabled;
+static Bool kdOffScreen;
+static unsigned long kdOffScreenTime;
+static KdPointerMatrix kdPointerMatrix = {
+ { { 1, 0, 0 },
+ { 0, 1, 0 } }
+};
+
+void KdResetInputMachine (void);
+
+#define KD_MAX_INPUT_FDS 8
+
+typedef struct _kdInputFd {
+ int fd;
+ void (*read) (int fd, void *closure);
+ int (*enable) (int fd, void *closure);
+ void (*disable) (int fd, void *closure);
+ void *closure;
+} KdInputFd;
+
+static KdInputFd kdInputFds[KD_MAX_INPUT_FDS];
+static int kdNumInputFds;
+
+extern Bool kdRawPointerCoordinates;
+
+static void
+KdSigio (int sig)
+{
+ int i;
+
+ for (i = 0; i < kdNumInputFds; i++)
+ (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
+}
+
+static void
+KdBlockSigio (void)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_BLOCK, &set, 0);
+#endif
+}
+
+static void
+KdUnblockSigio (void)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_UNBLOCK, &set, 0);
+#endif
+}
+
+#ifdef DEBUG_SIGIO
+
+void
+KdAssertSigioBlocked (char *where)
+{
+ sigset_t set, old;
+
+ sigemptyset (&set);
+ sigprocmask (SIG_BLOCK, &set, &old);
+ if (!sigismember (&old, SIGIO)) {
+ ErrorF ("SIGIO not blocked at %s\n", where);
+ KdBacktrace(0);
+ }
+}
+
+#else
+
+#define KdAssertSigioBlocked(s)
+
+#endif
+
+static int kdnFds;
+
+#ifdef FNONBLOCK
+#define NOBLOCK FNONBLOCK
+#else
+#define NOBLOCK FNDELAY
+#endif
+
+void
+KdResetInputMachine (void)
+{
+ KdPointerInfo *pi;
+
+ for (pi = kdPointers; pi; pi = pi->next) {
+ pi->mouseState = start;
+ pi->eventHeld = FALSE;
+ }
+}
+
+static void
+KdNonBlockFd (int fd)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ int flags;
+ flags = fcntl (fd, F_GETFL);
+ flags |= FASYNC|NOBLOCK;
+ fcntl (fd, F_SETFL, flags);
+#endif
+}
+
+static void
+KdAddFd (int fd)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ struct sigaction act;
+ sigset_t set;
+
+ kdnFds++;
+ fcntl (fd, F_SETOWN, getpid());
+ KdNonBlockFd (fd);
+ AddEnabledDevice (fd);
+ memset (&act, '\0', sizeof act);
+ act.sa_handler = KdSigio;
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGIO);
+ sigaddset (&act.sa_mask, SIGALRM);
+ sigaddset (&act.sa_mask, SIGVTALRM);
+ sigaction (SIGIO, &act, 0);
+ sigemptyset (&set);
+ sigprocmask (SIG_SETMASK, &set, 0);
+#endif
+}
+
+static void
+KdRemoveFd (int fd)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ struct sigaction act;
+ int flags;
+
+ kdnFds--;
+ RemoveEnabledDevice (fd);
+ flags = fcntl (fd, F_GETFL);
+ flags &= ~(FASYNC|NOBLOCK);
+ fcntl (fd, F_SETFL, flags);
+ if (kdnFds == 0)
+ {
+ memset (&act, '\0', sizeof act);
+ act.sa_handler = SIG_IGN;
+ sigemptyset (&act.sa_mask);
+ sigaction (SIGIO, &act, 0);
+ }
+#endif
+}
+
+Bool
+KdRegisterFd (int fd, void (*read) (int fd, void *closure), void *closure)
+{
+ if (kdNumInputFds == KD_MAX_INPUT_FDS)
+ return FALSE;
+ kdInputFds[kdNumInputFds].fd = fd;
+ kdInputFds[kdNumInputFds].read = read;
+ kdInputFds[kdNumInputFds].enable = 0;
+ kdInputFds[kdNumInputFds].disable = 0;
+ kdInputFds[kdNumInputFds].closure = closure;
+ kdNumInputFds++;
+ if (kdInputEnabled)
+ KdAddFd (fd);
+ return TRUE;
+}
+
+void
+KdUnregisterFd (void *closure, int fd, Bool do_close)
+{
+ int i, j;
+
+ for (i = 0; i < kdNumInputFds; i++) {
+ if (kdInputFds[i].closure == closure &&
+ (fd == -1 || kdInputFds[i].fd == fd)) {
+ if (kdInputEnabled)
+ KdRemoveFd (kdInputFds[i].fd);
+ if (do_close)
+ close (kdInputFds[i].fd);
+ kdNumInputFds--;
+ for (j = i; j < kdNumInputFds; j++)
+ kdInputFds[j] = kdInputFds[j+1];
+ break;
+ }
+ }
+}
+
+void
+KdUnregisterFds (void *closure, Bool do_close)
+{
+ KdUnregisterFd(closure, -1, do_close);
+}
+
+void
+KdDisableInput (void)
+{
+ KdKeyboardInfo *ki;
+ KdPointerInfo *pi;
+ int found = 0, i = 0;
+
+ KdBlockSigio();
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->driver && ki->driver->Disable)
+ (*ki->driver->Disable) (ki);
+ }
+
+ for (pi = kdPointers; pi; pi = pi->next) {
+ if (pi->driver && pi->driver->Disable)
+ (*pi->driver->Disable) (pi);
+ }
+
+ if (kdNumInputFds) {
+ ErrorF("[KdDisableInput] Buggy drivers: still %d input fds left!",
+ kdNumInputFds);
+ i = 0;
+ while (i < kdNumInputFds) {
+ found = 0;
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki == kdInputFds[i].closure) {
+ ErrorF(" fd %d belongs to keybd driver %s\n",
+ kdInputFds[i].fd,
+ ki->driver && ki->driver->name ?
+ ki->driver->name : "(unnamed!)");
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ i++;
+ continue;
+ }
+
+ for (pi = kdPointers; pi; pi = pi->next) {
+ if (pi == kdInputFds[i].closure) {
+ ErrorF(" fd %d belongs to pointer driver %s\n",
+ kdInputFds[i].fd,
+ pi->driver && pi->driver->name ?
+ pi->driver->name : "(unnamed!)");
+ break;
+ }
+ }
+
+ if (found) {
+ i++;
+ continue;
+ }
+
+ ErrorF(" fd %d not claimed by any active device!\n",
+ kdInputFds[i].fd);
+ KdUnregisterFd(kdInputFds[i].closure, kdInputFds[i].fd, TRUE);
+ }
+ }
+
+ kdInputEnabled = FALSE;
+}
+
+void
+KdEnableInput (void)
+{
+ InternalEvent ev;
+ KdKeyboardInfo *ki;
+ KdPointerInfo *pi;
+
+ kdInputEnabled = TRUE;
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->driver && ki->driver->Enable)
+ (*ki->driver->Enable) (ki);
+ }
+
+ for (pi = kdPointers; pi; pi = pi->next) {
+ if (pi->driver && pi->driver->Enable)
+ (*pi->driver->Enable) (pi);
+ }
+
+ /* reset screen saver */
+ ev.any.time = GetTimeInMillis ();
+ NoticeEventTime (&ev);
+
+ KdUnblockSigio ();
+}
+
+static KdKeyboardDriver *
+KdFindKeyboardDriver (char *name)
+{
+ KdKeyboardDriver *ret;
+
+ /* ask a stupid question ... */
+ if (!name)
+ return NULL;
+
+ for (ret = kdKeyboardDrivers; ret; ret = ret->next) {
+ if (strcmp(ret->name, name) == 0)
+ return ret;
+ }
+
+ return NULL;
+}
+
+static KdPointerDriver *
+KdFindPointerDriver (char *name)
+{
+ KdPointerDriver *ret;
+
+ /* ask a stupid question ... */
+ if (!name)
+ return NULL;
+
+ for (ret = kdPointerDrivers; ret; ret = ret->next) {
+ if (strcmp(ret->name, name) == 0)
+ return ret;
+ }
+
+ return NULL;
+}
+
+static int
+KdPointerProc(DeviceIntPtr pDevice, int onoff)
+{
+ DevicePtr pDev = (DevicePtr)pDevice;
+ KdPointerInfo *pi;
+ Atom xiclass;
+ Atom *btn_labels;
+ Atom *axes_labels;
+
+ if (!pDev)
+ return BadImplementation;
+
+ for (pi = kdPointers; pi; pi = pi->next) {
+ if (pi->dixdev && pi->dixdev->id == pDevice->id)
+ break;
+ }
+
+ if (!pi || !pi->dixdev || pi->dixdev->id != pDevice->id) {
+ ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n",
+ pDevice->id);
+ return BadImplementation;
+ }
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+#ifdef DEBUG
+ ErrorF("initialising pointer %s ...\n", pi->name);
+#endif
+ if (!pi->driver) {
+ if (!pi->driverPrivate) {
+ ErrorF("no driver specified for %s\n", pi->name);
+ return BadImplementation;
+ }
+
+ pi->driver = KdFindPointerDriver(pi->driverPrivate);
+ if (!pi->driver) {
+ ErrorF("Couldn't find pointer driver %s\n",
+ pi->driverPrivate ? (char *) pi->driverPrivate :
+ "(unnamed)");
+ return !Success;
+ }
+ xfree(pi->driverPrivate);
+ pi->driverPrivate = NULL;
+ }
+
+ if (!pi->driver->Init) {
+ ErrorF("no init function\n");
+ return BadImplementation;
+ }
+
+ if ((*pi->driver->Init) (pi) != Success) {
+ return !Success;
+ }
+
+ btn_labels = xcalloc(pi->nButtons, sizeof(Atom));
+ if (!btn_labels)
+ return BadAlloc;
+ axes_labels = xcalloc(pi->nAxes, sizeof(Atom));
+ if (!axes_labels) {
+ xfree(btn_labels);
+ return BadAlloc;
+ }
+
+ switch(pi->nAxes)
+ {
+ default:
+ case 7:
+ btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
+ case 6:
+ btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
+ case 5:
+ btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
+ case 4:
+ btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
+ case 3:
+ btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+ case 2:
+ btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+ case 1:
+ btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+ case 0:
+ break;
+ }
+
+ if (pi->nAxes >= 2) {
+ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
+ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+ }
+
+ InitPointerDeviceStruct(pDev, pi->map, pi->nButtons, btn_labels,
+ (PtrCtrlProcPtr)NoopDDA,
+ GetMotionHistorySize(), pi->nAxes, axes_labels);
+
+ xfree(btn_labels);
+ xfree(axes_labels);
+
+ if (pi->inputClass == KD_TOUCHSCREEN) {
+ InitAbsoluteClassDeviceStruct(pDevice);
+ xiclass = AtomFromName(XI_TOUCHSCREEN);
+ }
+ else {
+ xiclass = AtomFromName(XI_MOUSE);
+ }
+
+ AssignTypeAndName(pi->dixdev, xiclass,
+ pi->name ? pi->name : "Generic KDrive Pointer");
+
+ return Success;
+
+ case DEVICE_ON:
+ if (pDev->on == TRUE)
+ return Success;
+
+ if (!pi->driver->Enable) {
+ ErrorF("no enable function\n");
+ return BadImplementation;
+ }
+
+ if ((*pi->driver->Enable) (pi) == Success) {
+ pDev->on = TRUE;
+ return Success;
+ }
+ else {
+ return BadImplementation;
+ }
+
+ return Success;
+
+ case DEVICE_OFF:
+ if (pDev->on == FALSE) {
+ return Success;
+ }
+
+ if (!pi->driver->Disable) {
+ return BadImplementation;
+ }
+ else {
+ (*pi->driver->Disable) (pi);
+ pDev->on = FALSE;
+ return Success;
+ }
+
+ return Success;
+
+ case DEVICE_CLOSE:
+ if (pDev->on) {
+ if (!pi->driver->Disable) {
+ return BadImplementation;
+ }
+ (*pi->driver->Disable) (pi);
+ pDev->on = FALSE;
+ }
+
+ if (!pi->driver->Fini)
+ return BadImplementation;
+
+ (*pi->driver->Fini) (pi);
+
+ KdRemovePointer(pi);
+
+ return Success;
+ }
+
+ /* NOTREACHED */
+ return BadImplementation;
+}
+
+#ifndef _MSC_VER
+Bool
+LegalModifier(unsigned int key, DeviceIntPtr pDev)
+{
+ return TRUE;
+}
+#endif
+
+static void
+KdBell (int volume, DeviceIntPtr pDev, pointer arg, int something)
+{
+ KeybdCtrl *ctrl = arg;
+ KdKeyboardInfo *ki = NULL;
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->dixdev && ki->dixdev->id == pDev->id)
+ break;
+ }
+
+ if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver)
+ return;
+
+ KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration);
+}
+
+#ifndef _MSC_VER
+void
+DDXRingBell(int volume, int pitch, int duration)
+{
+ KdKeyboardInfo *ki = NULL;
+
+ if (kdOsFuncs->Bell) {
+ (*kdOsFuncs->Bell)(volume, pitch, duration);
+ }
+ else {
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->dixdev->coreEvents)
+ KdRingBell(ki, volume, pitch, duration);
+ }
+ }
+}
+#endif
+void
+KdRingBell(KdKeyboardInfo *ki, int volume, int pitch, int duration)
+{
+ if (!ki || !ki->driver || !ki->driver->Bell)
+ return;
+
+ if (kdInputEnabled)
+ (*ki->driver->Bell) (ki, volume, pitch, duration);
+}
+
+
+static void
+KdSetLeds (KdKeyboardInfo *ki, int leds)
+{
+ if (!ki || !ki->driver)
+ return;
+
+ if (kdInputEnabled) {
+ if (ki->driver->Leds)
+ (*ki->driver->Leds) (ki, leds);
+ }
+}
+
+void
+KdSetLed (KdKeyboardInfo *ki, int led, Bool on)
+{
+ if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed)
+ return;
+
+ NoteLedState (ki->dixdev, led, on);
+ KdSetLeds (ki, ki->dixdev->kbdfeed->ctrl.leds);
+}
+
+void
+KdSetPointerMatrix (KdPointerMatrix *matrix)
+{
+ kdPointerMatrix = *matrix;
+}
+
+void
+KdComputePointerMatrix (KdPointerMatrix *m, Rotation randr, int width,
+ int height)
+{
+ int x_dir = 1, y_dir = 1;
+ int i, j;
+ int size[2];
+
+ size[0] = width; size[1] = height;
+ if (randr & RR_Reflect_X)
+ x_dir = -1;
+ if (randr & RR_Reflect_Y)
+ y_dir = -1;
+ switch (randr & (RR_Rotate_All)) {
+ case RR_Rotate_0:
+ m->matrix[0][0] = x_dir; m->matrix[0][1] = 0;
+ m->matrix[1][0] = 0; m->matrix[1][1] = y_dir;
+ break;
+ case RR_Rotate_90:
+ m->matrix[0][0] = 0; m->matrix[0][1] = -x_dir;
+ m->matrix[1][0] = y_dir; m->matrix[1][1] = 0;
+ break;
+ case RR_Rotate_180:
+ m->matrix[0][0] = -x_dir; m->matrix[0][1] = 0;
+ m->matrix[1][0] = 0; m->matrix[1][1] = -y_dir;
+ break;
+ case RR_Rotate_270:
+ m->matrix[0][0] = 0; m->matrix[0][1] = x_dir;
+ m->matrix[1][0] = -y_dir; m->matrix[1][1] = 0;
+ break;
+ }
+ for (i = 0; i < 2; i++)
+ {
+ m->matrix[i][2] = 0;
+ for (j = 0 ; j < 2; j++)
+ if (m->matrix[i][j] < 0)
+ m->matrix[i][2] = size[j] - 1;
+ }
+}
+
+void
+KdScreenToPointerCoords (int *x, int *y)
+{
+ int (*m)[3] = kdPointerMatrix.matrix;
+ int div = m[0][1] * m[1][0] - m[1][1] * m[0][0];
+ int sx = *x;
+ int sy = *y;
+
+ *x = (m[0][1] * sy - m[0][1] * m[1][2] + m[1][1] * m[0][2] - m[1][1] * sx) / div;
+ *y = (m[1][0] * sx + m[0][0] * m[1][2] - m[1][0] * m[0][2] - m[0][0] * sy) / div;
+}
+
+static void
+KdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl)
+{
+ KdKeyboardInfo *ki;
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->dixdev && ki->dixdev->id == pDevice->id)
+ break;
+ }
+
+ if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver)
+ return;
+
+ KdSetLeds(ki, ctrl->leds);
+ ki->bellPitch = ctrl->bell_pitch;
+ ki->bellDuration = ctrl->bell_duration;
+}
+
+extern KeybdCtrl defaultKeyboardControl;
+
+static int
+KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
+{
+ Bool ret;
+ DevicePtr pDev = (DevicePtr)pDevice;
+ KdKeyboardInfo *ki;
+ Atom xiclass;
+ XkbRMLVOSet rmlvo;
+
+ if (!pDev)
+ return BadImplementation;
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->dixdev && ki->dixdev->id == pDevice->id)
+ break;
+ }
+
+ if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id) {
+ return BadImplementation;
+ }
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+#ifdef DEBUG
+ ErrorF("initialising keyboard %s\n", ki->name);
+#endif
+ if (!ki->driver) {
+ if (!ki->driverPrivate) {
+ ErrorF("no driver specified!\n");
+ return BadImplementation;
+ }
+
+ ki->driver = KdFindKeyboardDriver(ki->driverPrivate);
+ if (!ki->driver) {
+ ErrorF("Couldn't find keyboard driver %s\n",
+ ki->driverPrivate ? (char *) ki->driverPrivate :
+ "(unnamed)");
+ return !Success;
+ }
+ xfree(ki->driverPrivate);
+ ki->driverPrivate = NULL;
+ }
+
+ if (!ki->driver->Init) {
+ ErrorF("Keyboard %s: no init function\n", ki->name);
+ return BadImplementation;
+ }
+
+ if ((*ki->driver->Init) (ki) != Success) {
+ return !Success;
+ }
+
+ memset(&rmlvo, 0, sizeof(rmlvo));
+ rmlvo.rules = ki->xkbRules;
+ rmlvo.model = ki->xkbModel;
+ rmlvo.layout = ki->xkbLayout;
+ rmlvo.variant = ki->xkbVariant;
+ rmlvo.options = ki->xkbOptions;
+ ret = InitKeyboardDeviceStruct (pDevice, &rmlvo, KdBell, KdKbdCtrl);
+ if (!ret) {
+ ErrorF("Couldn't initialise keyboard %s\n", ki->name);
+ return BadImplementation;
+ }
+
+ xiclass = AtomFromName(XI_KEYBOARD);
+ AssignTypeAndName(pDevice, xiclass,
+ ki->name ? ki->name : "Generic KDrive Keyboard");
+
+ KdResetInputMachine();
+
+ return Success;
+
+ case DEVICE_ON:
+ if (pDev->on == TRUE)
+ return Success;
+
+ if (!ki->driver->Enable)
+ return BadImplementation;
+
+ if ((*ki->driver->Enable) (ki) != Success) {
+ return BadMatch;
+ }
+
+ pDev->on = TRUE;
+ return Success;
+
+ case DEVICE_OFF:
+ if (pDev->on == FALSE)
+ return Success;
+
+ if (!ki->driver->Disable)
+ return BadImplementation;
+
+ (*ki->driver->Disable) (ki);
+ pDev->on = FALSE;
+
+ return Success;
+
+ break;
+
+ case DEVICE_CLOSE:
+ if (pDev->on) {
+ if (!ki->driver->Disable)
+ return BadImplementation;
+
+ (*ki->driver->Disable) (ki);
+ pDev->on = FALSE;
+ }
+
+ if (!ki->driver->Fini)
+ return BadImplementation;
+
+ (*ki->driver->Fini) (ki);
+
+ KdRemoveKeyboard(ki);
+
+ return Success;
+ }
+
+ /* NOTREACHED */
+ return BadImplementation;
+}
+
+void
+KdAddPointerDriver (KdPointerDriver *driver)
+{
+ KdPointerDriver **prev;
+
+ if (!driver)
+ return;
+
+ for (prev = &kdPointerDrivers; *prev; prev = &(*prev)->next) {
+ if (*prev == driver)
+ return;
+ }
+ *prev = driver;
+}
+
+void
+KdRemovePointerDriver (KdPointerDriver *driver)
+{
+ KdPointerDriver *tmp;
+
+ if (!driver)
+ return;
+
+ /* FIXME remove all pointers using this driver */
+ for (tmp = kdPointerDrivers; tmp; tmp = tmp->next) {
+ if (tmp->next == driver)
+ tmp->next = driver->next;
+ }
+ if (tmp == driver)
+ tmp = NULL;
+}
+
+void
+KdAddKeyboardDriver (KdKeyboardDriver *driver)
+{
+ KdKeyboardDriver **prev;
+
+ if (!driver)
+ return;
+
+ for (prev = &kdKeyboardDrivers; *prev; prev = &(*prev)->next) {
+ if (*prev == driver)
+ return;
+ }
+ *prev = driver;
+}
+
+void
+KdRemoveKeyboardDriver (KdKeyboardDriver *driver)
+{
+ KdKeyboardDriver *tmp;
+
+ if (!driver)
+ return;
+
+ /* FIXME remove all keyboards using this driver */
+ for (tmp = kdKeyboardDrivers; tmp; tmp = tmp->next) {
+ if (tmp->next == driver)
+ tmp->next = driver->next;
+ }
+ if (tmp == driver)
+ tmp = NULL;
+}
+
+KdKeyboardInfo *
+KdNewKeyboard (void)
+{
+ KdKeyboardInfo *ki = xcalloc(sizeof(KdKeyboardInfo), 1);
+ if (!ki)
+ return NULL;
+
+ ki->minScanCode = 0;
+ ki->maxScanCode = 0;
+ ki->leds = 0;
+ ki->bellPitch = 1000;
+ ki->bellDuration = 200;
+ ki->next = NULL;
+ ki->options = NULL;
+ ki->xkbRules = strdup(XKB_DFLT_RULES);
+ ki->xkbModel = strdup(XKB_DFLT_MODEL);
+ ki->xkbLayout = strdup(XKB_DFLT_LAYOUT);
+ ki->xkbVariant = strdup(XKB_DFLT_VARIANT);
+ ki->xkbOptions = strdup(XKB_DFLT_OPTIONS);
+
+ return ki;
+}
+
+int
+KdAddConfigKeyboard (char *keyboard)
+{
+ struct KdConfigDevice **prev, *new;
+
+ if (!keyboard)
+ return Success;
+
+ new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1);
+ if (!new)
+ return BadAlloc;
+
+ new->line = xstrdup(keyboard);
+ new->next = NULL;
+
+ for (prev = &kdConfigKeyboards; *prev; prev = &(*prev)->next);
+ *prev = new;
+
+ return Success;
+}
+
+int
+KdAddKeyboard (KdKeyboardInfo *ki)
+{
+ KdKeyboardInfo **prev;
+
+ if (!ki)
+ return !Success;
+
+ ki->dixdev = AddInputDevice(serverClient, KdKeyboardProc, TRUE);
+ if (!ki->dixdev) {
+ ErrorF("Couldn't register keyboard device %s\n",
+ ki->name ? ki->name : "(unnamed)");
+ return !Success;
+ }
+
+ ki->dixdev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+ ki->dixdev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+ RegisterOtherDevice(ki->dixdev);
+
+#ifdef DEBUG
+ ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id);
+#endif
+
+ for (prev = &kdKeyboards; *prev; prev = &(*prev)->next);
+ *prev = ki;
+
+ return Success;
+}
+
+void
+KdRemoveKeyboard (KdKeyboardInfo *ki)
+{
+ KdKeyboardInfo **prev;
+
+ if (!ki)
+ return;
+
+ for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) {
+ if (*prev == ki) {
+ *prev = ki->next;
+ break;
+ }
+ }
+
+ KdFreeKeyboard(ki);
+}
+
+int
+KdAddConfigPointer (char *pointer)
+{
+ struct KdConfigDevice **prev, *new;
+
+ if (!pointer)
+ return Success;
+
+ new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1);
+ if (!new)
+ return BadAlloc;
+
+ new->line = xstrdup(pointer);
+ new->next = NULL;
+
+ for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next);
+ *prev = new;
+
+ return Success;
+}
+
+int
+KdAddPointer (KdPointerInfo *pi)
+{
+ KdPointerInfo **prev;
+
+ if (!pi)
+ return Success;
+
+ pi->mouseState = start;
+ pi->eventHeld = FALSE;
+
+ pi->dixdev = AddInputDevice(serverClient, KdPointerProc, TRUE);
+ if (!pi->dixdev) {
+ ErrorF("Couldn't add pointer device %s\n",
+ pi->name ? pi->name : "(unnamed)");
+ return BadDevice;
+ }
+
+ pi->dixdev->deviceGrab.ActivateGrab = ActivatePointerGrab;
+ pi->dixdev->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
+ RegisterOtherDevice(pi->dixdev);
+
+ for (prev = &kdPointers; *prev; prev = &(*prev)->next);
+ *prev = pi;
+
+ return Success;
+}
+
+void
+KdRemovePointer (KdPointerInfo *pi)
+{
+ KdPointerInfo **prev;
+
+ if (!pi)
+ return;
+
+ for (prev = &kdPointers; *prev; prev = &(*prev)->next) {
+ if (*prev == pi) {
+ *prev = pi->next;
+ break;
+ }
+ }
+
+ KdFreePointer(pi);
+}
+
+/*
+ * You can call your kdriver server with something like:
+ * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd
+ * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br
+ */
+static Bool
+KdGetOptions (InputOption **options, char *string)
+{
+ InputOption *newopt = NULL, **tmpo = NULL;
+ int tam_key = 0;
+
+ newopt = xcalloc(1, sizeof (InputOption));
+ if (!newopt)
+ return FALSE;
+
+ for (tmpo = options; *tmpo; tmpo = &(*tmpo)->next)
+ ; /* Hello, I'm here */
+ *tmpo = newopt;
+
+ if (strchr(string, '='))
+ {
+ tam_key = (strchr(string, '=') - string);
+ newopt->key = (char *)xalloc(tam_key);
+ strncpy(newopt->key, string, tam_key);
+ newopt->key[tam_key] = '\0';
+ newopt->value = xstrdup(strchr(string, '=') + 1);
+ }
+ else
+ {
+ newopt->key = xstrdup(string);
+ newopt->value = NULL;
+ }
+ newopt->next = NULL;
+
+ return TRUE;
+}
+
+static void
+KdParseKbdOptions (KdKeyboardInfo *ki)
+{
+ InputOption *option = NULL;
+
+ for (option = ki->options; option; option = option->next)
+ {
+ if (strcasecmp(option->key, "XkbRules") == 0)
+ ki->xkbRules = option->value;
+ else if (strcasecmp(option->key, "XkbModel") == 0)
+ ki->xkbModel = option->value;
+ else if (strcasecmp(option->key, "XkbLayout") == 0)
+ ki->xkbLayout = option->value;
+ else if (strcasecmp(option->key, "XkbVariant") == 0)
+ ki->xkbVariant = option->value;
+ else if (strcasecmp(option->key, "XkbOptions") == 0)
+ ki->xkbOptions = option->value;
+ else if (!strcasecmp (option->key, "device"))
+ ki->path = strdup(option->value);
+ else
+ ErrorF("Kbd option key (%s) of value (%s) not assigned!\n",
+ option->key, option->value);
+ }
+}
+
+KdKeyboardInfo *
+KdParseKeyboard (char *arg)
+{
+ char save[1024];
+ char delim;
+ InputOption *options = NULL;
+ KdKeyboardInfo *ki = NULL;
+
+ ki = KdNewKeyboard();
+ if (!ki)
+ return NULL;
+
+ ki->name = strdup("Unknown KDrive Keyboard");
+ ki->path = NULL;
+ ki->driver = NULL;
+ ki->driverPrivate = NULL;
+ ki->next = NULL;
+
+ if (!arg)
+ {
+ ErrorF("keybd: no arg\n");
+ KdFreeKeyboard (ki);
+ return NULL;
+ }
+
+ if (strlen (arg) >= sizeof (save))
+ {
+ ErrorF("keybd: arg too long\n");
+ KdFreeKeyboard (ki);
+ return NULL;
+ }
+
+ arg = KdParseFindNext (arg, ",", save, &delim);
+ if (!save[0])
+ {
+ ErrorF("keybd: failed on save[0]\n");
+ KdFreeKeyboard (ki);
+ return NULL;
+ }
+
+ if (strcmp (save, "auto") == 0)
+ ki->driverPrivate = NULL;
+ else
+ ki->driverPrivate = xstrdup(save);
+
+ if (delim != ',')
+ {
+ return ki;
+ }
+
+ arg = KdParseFindNext (arg, ",", save, &delim);
+
+ while (delim == ',')
+ {
+ arg = KdParseFindNext (arg, ",", save, &delim);
+
+ if (!KdGetOptions(&options, save))
+ {
+ KdFreeKeyboard(ki);
+ return NULL;
+ }
+ }
+
+ if (options)
+ {
+ ki->options = options;
+ KdParseKbdOptions(ki);
+ }
+
+ return ki;
+}
+
+static void
+KdParsePointerOptions (KdPointerInfo *pi)
+{
+ InputOption *option = NULL;
+
+ for (option = pi->options; option; option = option->next)
+ {
+ if (!strcmp (option->key, "emulatemiddle"))
+ pi->emulateMiddleButton = TRUE;
+ else if (!strcmp (option->key, "noemulatemiddle"))
+ pi->emulateMiddleButton = FALSE;
+ else if (!strcmp (option->key, "transformcoord"))
+ pi->transformCoordinates = TRUE;
+ else if (!strcmp (option->key, "rawcoord"))
+ pi->transformCoordinates = FALSE;
+ else if (!strcasecmp (option->key, "device"))
+ pi->path = strdup(option->value);
+ else if (!strcasecmp (option->key, "protocol"))
+ pi->protocol = strdup(option->value);
+ else
+ ErrorF("Pointer option key (%s) of value (%s) not assigned!\n",
+ option->key, option->value);
+ }
+}
+
+KdPointerInfo *
+KdParsePointer (char *arg)
+{
+ char save[1024];
+ char delim;
+ KdPointerInfo *pi = NULL;
+ InputOption *options = NULL;
+ int i = 0;
+
+ pi = KdNewPointer();
+ if (!pi)
+ return NULL;
+ pi->emulateMiddleButton = kdEmulateMiddleButton;
+ pi->transformCoordinates = !kdRawPointerCoordinates;
+ pi->protocol = NULL;
+ pi->nButtons = 5; /* XXX should not be hardcoded */
+ pi->inputClass = KD_MOUSE;
+
+ if (!arg)
+ {
+ ErrorF("mouse: no arg\n");
+ KdFreePointer (pi);
+ return NULL;
+ }
+
+ if (strlen (arg) >= sizeof (save))
+ {
+ ErrorF("mouse: arg too long\n");
+ KdFreePointer (pi);
+ return NULL;
+ }
+ arg = KdParseFindNext (arg, ",", save, &delim);
+ if (!save[0])
+ {
+ ErrorF("failed on save[0]\n");
+ KdFreePointer (pi);
+ return NULL;
+ }
+
+ if (strcmp(save, "auto") == 0)
+ pi->driverPrivate = NULL;
+ else
+ pi->driverPrivate = xstrdup(save);
+
+ if (delim != ',')
+ {
+ return pi;
+ }
+
+ arg = KdParseFindNext (arg, ",", save, &delim);
+
+ while (delim == ',')
+ {
+ arg = KdParseFindNext (arg, ",", save, &delim);
+ if (save[0] == '{')
+ {
+ char *s = save + 1;
+ i = 0;
+ while (*s && *s != '}')
+ {
+ if ('1' <= *s && *s <= '0' + pi->nButtons)
+ pi->map[i] = *s - '0';
+ else
+ UseMsg ();
+ s++;
+ }
+ }
+ else
+ {
+ if (!KdGetOptions(&options, save))
+ {
+ KdFreePointer(pi);
+ return NULL;
+ }
+ }
+ }
+
+ if (options)
+ {
+ pi->options = options;
+ KdParsePointerOptions(pi);
+ }
+
+ return pi;
+}
+
+
+void
+KdInitInput (void)
+{
+ KdPointerInfo *pi;
+ KdKeyboardInfo *ki;
+ struct KdConfigDevice *dev;
+
+ kdInputEnabled = TRUE;
+
+ for (dev = kdConfigPointers; dev; dev = dev->next) {
+ pi = KdParsePointer(dev->line);
+ if (!pi)
+ ErrorF("Failed to parse pointer\n");
+ if (KdAddPointer(pi) != Success)
+ ErrorF("Failed to add pointer!\n");
+ }
+ for (dev = kdConfigKeyboards; dev; dev = dev->next) {
+ ki = KdParseKeyboard(dev->line);
+ if (!ki)
+ ErrorF("Failed to parse keyboard\n");
+ if (KdAddKeyboard(ki) != Success)
+ ErrorF("Failed to add keyboard!\n");
+ }
+
+ mieqInit();
+}
+
+/*
+ * Middle button emulation state machine
+ *
+ * Possible transitions:
+ * Button 1 press v1
+ * Button 1 release ^1
+ * Button 2 press v2
+ * Button 2 release ^2
+ * Button 3 press v3
+ * Button 3 release ^3
+ * Button other press vo
+ * Button other release ^o
+ * Mouse motion <>
+ * Keyboard event k
+ * timeout ...
+ * outside box <->
+ *
+ * States:
+ * start
+ * button_1_pend
+ * button_1_down
+ * button_2_down
+ * button_3_pend
+ * button_3_down
+ * synthetic_2_down_13
+ * synthetic_2_down_3
+ * synthetic_2_down_1
+ *
+ * Transition diagram
+ *
+ * start
+ * v1 -> (hold) (settimeout) button_1_pend
+ * ^1 -> (deliver) start
+ * v2 -> (deliver) button_2_down
+ * ^2 -> (deliever) start
+ * v3 -> (hold) (settimeout) button_3_pend
+ * ^3 -> (deliver) start
+ * vo -> (deliver) start
+ * ^o -> (deliver) start
+ * <> -> (deliver) start
+ * k -> (deliver) start
+ *
+ * button_1_pend (button 1 is down, timeout pending)
+ * ^1 -> (release) (deliver) start
+ * v2 -> (release) (deliver) button_1_down
+ * ^2 -> (release) (deliver) button_1_down
+ * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13
+ * ^3 -> (release) (deliver) button_1_down
+ * vo -> (release) (deliver) button_1_down
+ * ^o -> (release) (deliver) button_1_down
+ * <-> -> (release) (deliver) button_1_down
+ * <> -> (deliver) button_1_pend
+ * k -> (release) (deliver) button_1_down
+ * ... -> (release) button_1_down
+ *
+ * button_1_down (button 1 is down)
+ * ^1 -> (deliver) start
+ * v2 -> (deliver) button_1_down
+ * ^2 -> (deliver) button_1_down
+ * v3 -> (deliver) button_1_down
+ * ^3 -> (deliver) button_1_down
+ * vo -> (deliver) button_1_down
+ * ^o -> (deliver) button_1_down
+ * <> -> (deliver) button_1_down
+ * k -> (deliver) button_1_down
+ *
+ * button_2_down (button 2 is down)
+ * v1 -> (deliver) button_2_down
+ * ^1 -> (deliver) button_2_down
+ * ^2 -> (deliver) start
+ * v3 -> (deliver) button_2_down
+ * ^3 -> (deliver) button_2_down
+ * vo -> (deliver) button_2_down
+ * ^o -> (deliver) button_2_down
+ * <> -> (deliver) button_2_down
+ * k -> (deliver) button_2_down
+ *
+ * button_3_pend (button 3 is down, timeout pending)
+ * v1 -> (generate v2) synthetic_2_down
+ * ^1 -> (release) (deliver) button_3_down
+ * v2 -> (release) (deliver) button_3_down
+ * ^2 -> (release) (deliver) button_3_down
+ * ^3 -> (release) (deliver) start
+ * vo -> (release) (deliver) button_3_down
+ * ^o -> (release) (deliver) button_3_down
+ * <-> -> (release) (deliver) button_3_down
+ * <> -> (deliver) button_3_pend
+ * k -> (release) (deliver) button_3_down
+ * ... -> (release) button_3_down
+ *
+ * button_3_down (button 3 is down)
+ * v1 -> (deliver) button_3_down
+ * ^1 -> (deliver) button_3_down
+ * v2 -> (deliver) button_3_down
+ * ^2 -> (deliver) button_3_down
+ * ^3 -> (deliver) start
+ * vo -> (deliver) button_3_down
+ * ^o -> (deliver) button_3_down
+ * <> -> (deliver) button_3_down
+ * k -> (deliver) button_3_down
+ *
+ * synthetic_2_down_13 (button 1 and 3 are down)
+ * ^1 -> (generate ^2) synthetic_2_down_3
+ * v2 -> synthetic_2_down_13
+ * ^2 -> synthetic_2_down_13
+ * ^3 -> (generate ^2) synthetic_2_down_1
+ * vo -> (deliver) synthetic_2_down_13
+ * ^o -> (deliver) synthetic_2_down_13
+ * <> -> (deliver) synthetic_2_down_13
+ * k -> (deliver) synthetic_2_down_13
+ *
+ * synthetic_2_down_3 (button 3 is down)
+ * v1 -> (deliver) synthetic_2_down_3
+ * ^1 -> (deliver) synthetic_2_down_3
+ * v2 -> synthetic_2_down_3
+ * ^2 -> synthetic_2_down_3
+ * ^3 -> start
+ * vo -> (deliver) synthetic_2_down_3
+ * ^o -> (deliver) synthetic_2_down_3
+ * <> -> (deliver) synthetic_2_down_3
+ * k -> (deliver) synthetic_2_down_3
+ *
+ * synthetic_2_down_1 (button 1 is down)
+ * ^1 -> start
+ * v2 -> synthetic_2_down_1
+ * ^2 -> synthetic_2_down_1
+ * v3 -> (deliver) synthetic_2_down_1
+ * ^3 -> (deliver) synthetic_2_down_1
+ * vo -> (deliver) synthetic_2_down_1
+ * ^o -> (deliver) synthetic_2_down_1
+ * <> -> (deliver) synthetic_2_down_1
+ * k -> (deliver) synthetic_2_down_1
+ */
+
+typedef enum _inputClass {
+ down_1, up_1,
+ down_2, up_2,
+ down_3, up_3,
+ down_o, up_o,
+ motion, outside_box,
+ keyboard, timeout,
+ num_input_class
+} KdInputClass;
+
+typedef enum _inputAction {
+ noop,
+ hold,
+ setto,
+ deliver,
+ release,
+ clearto,
+ gen_down_2,
+ gen_up_2
+} KdInputAction;
+
+#define MAX_ACTIONS 2
+
+typedef struct _inputTransition {
+ KdInputAction actions[MAX_ACTIONS];
+ KdPointerState nextState;
+} KdInputTransition;
+
+static const
+KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
+ /* start */
+ {
+ { { hold, setto }, button_1_pend }, /* v1 */
+ { { deliver, noop }, start }, /* ^1 */
+ { { deliver, noop }, button_2_down }, /* v2 */
+ { { deliver, noop }, start }, /* ^2 */
+ { { hold, setto }, button_3_pend }, /* v3 */
+ { { deliver, noop }, start }, /* ^3 */
+ { { deliver, noop }, start }, /* vo */
+ { { deliver, noop }, start }, /* ^o */
+ { { deliver, noop }, start }, /* <> */
+ { { deliver, noop }, start }, /* <-> */
+ { { noop, noop }, start }, /* k */
+ { { noop, noop }, start }, /* ... */
+ },
+ /* button_1_pend */
+ {
+ { { noop, noop }, button_1_pend }, /* v1 */
+ { { release, deliver }, start }, /* ^1 */
+ { { release, deliver }, button_1_down }, /* v2 */
+ { { release, deliver }, button_1_down }, /* ^2 */
+ { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */
+ { { release, deliver }, button_1_down }, /* ^3 */
+ { { release, deliver }, button_1_down }, /* vo */
+ { { release, deliver }, button_1_down }, /* ^o */
+ { { deliver, noop }, button_1_pend }, /* <> */
+ { { release, deliver }, button_1_down }, /* <-> */
+ { { noop, noop }, button_1_down }, /* k */
+ { { release, noop }, button_1_down }, /* ... */
+ },
+ /* button_1_down */
+ {
+ { { noop, noop }, button_1_down }, /* v1 */
+ { { deliver, noop }, start }, /* ^1 */
+ { { deliver, noop }, button_1_down }, /* v2 */
+ { { deliver, noop }, button_1_down }, /* ^2 */
+ { { deliver, noop }, button_1_down }, /* v3 */
+ { { deliver, noop }, button_1_down }, /* ^3 */
+ { { deliver, noop }, button_1_down }, /* vo */
+ { { deliver, noop }, button_1_down }, /* ^o */
+ { { deliver, noop }, button_1_down }, /* <> */
+ { { deliver, noop }, button_1_down }, /* <-> */
+ { { noop, noop }, button_1_down }, /* k */
+ { { noop, noop }, button_1_down }, /* ... */
+ },
+ /* button_2_down */
+ {
+ { { deliver, noop }, button_2_down }, /* v1 */
+ { { deliver, noop }, button_2_down }, /* ^1 */
+ { { noop, noop }, button_2_down }, /* v2 */
+ { { deliver, noop }, start }, /* ^2 */
+ { { deliver, noop }, button_2_down }, /* v3 */
+ { { deliver, noop }, button_2_down }, /* ^3 */
+ { { deliver, noop }, button_2_down }, /* vo */
+ { { deliver, noop }, button_2_down }, /* ^o */
+ { { deliver, noop }, button_2_down }, /* <> */
+ { { deliver, noop }, button_2_down }, /* <-> */
+ { { noop, noop }, button_2_down }, /* k */
+ { { noop, noop }, button_2_down }, /* ... */
+ },
+ /* button_3_pend */
+ {
+ { { clearto, gen_down_2 }, synth_2_down_13 }, /* v1 */
+ { { release, deliver }, button_3_down }, /* ^1 */
+ { { release, deliver }, button_3_down }, /* v2 */
+ { { release, deliver }, button_3_down }, /* ^2 */
+ { { release, deliver }, button_3_down }, /* v3 */
+ { { release, deliver }, start }, /* ^3 */
+ { { release, deliver }, button_3_down }, /* vo */
+ { { release, deliver }, button_3_down }, /* ^o */
+ { { deliver, noop }, button_3_pend }, /* <> */
+ { { release, deliver }, button_3_down }, /* <-> */
+ { { release, noop }, button_3_down }, /* k */
+ { { release, noop }, button_3_down }, /* ... */
+ },
+ /* button_3_down */
+ {
+ { { deliver, noop }, button_3_down }, /* v1 */
+ { { deliver, noop }, button_3_down }, /* ^1 */
+ { { deliver, noop }, button_3_down }, /* v2 */
+ { { deliver, noop }, button_3_down }, /* ^2 */
+ { { noop, noop }, button_3_down }, /* v3 */
+ { { deliver, noop }, start }, /* ^3 */
+ { { deliver, noop }, button_3_down }, /* vo */
+ { { deliver, noop }, button_3_down }, /* ^o */
+ { { deliver, noop }, button_3_down }, /* <> */
+ { { deliver, noop }, button_3_down }, /* <-> */
+ { { noop, noop }, button_3_down }, /* k */
+ { { noop, noop }, button_3_down }, /* ... */
+ },
+ /* synthetic_2_down_13 */
+ {
+ { { noop, noop }, synth_2_down_13 }, /* v1 */
+ { { gen_up_2, noop }, synth_2_down_3 }, /* ^1 */
+ { { noop, noop }, synth_2_down_13 }, /* v2 */
+ { { noop, noop }, synth_2_down_13 }, /* ^2 */
+ { { noop, noop }, synth_2_down_13 }, /* v3 */
+ { { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */
+ { { deliver, noop }, synth_2_down_13 }, /* vo */
+ { { deliver, noop }, synth_2_down_13 }, /* ^o */
+ { { deliver, noop }, synth_2_down_13 }, /* <> */
+ { { deliver, noop }, synth_2_down_13 }, /* <-> */
+ { { noop, noop }, synth_2_down_13 }, /* k */
+ { { noop, noop }, synth_2_down_13 }, /* ... */
+ },
+ /* synthetic_2_down_3 */
+ {
+ { { deliver, noop }, synth_2_down_3 }, /* v1 */
+ { { deliver, noop }, synth_2_down_3 }, /* ^1 */
+ { { deliver, noop }, synth_2_down_3 }, /* v2 */
+ { { deliver, noop }, synth_2_down_3 }, /* ^2 */
+ { { noop, noop }, synth_2_down_3 }, /* v3 */
+ { { noop, noop }, start }, /* ^3 */
+ { { deliver, noop }, synth_2_down_3 }, /* vo */
+ { { deliver, noop }, synth_2_down_3 }, /* ^o */
+ { { deliver, noop }, synth_2_down_3 }, /* <> */
+ { { deliver, noop }, synth_2_down_3 }, /* <-> */
+ { { noop, noop }, synth_2_down_3 }, /* k */
+ { { noop, noop }, synth_2_down_3 }, /* ... */
+ },
+ /* synthetic_2_down_1 */
+ {
+ { { noop, noop }, synth_2_down_1 }, /* v1 */
+ { { noop, noop }, start }, /* ^1 */
+ { { deliver, noop }, synth_2_down_1 }, /* v2 */
+ { { deliver, noop }, synth_2_down_1 }, /* ^2 */
+ { { deliver, noop }, synth_2_down_1 }, /* v3 */
+ { { deliver, noop }, synth_2_down_1 }, /* ^3 */
+ { { deliver, noop }, synth_2_down_1 }, /* vo */
+ { { deliver, noop }, synth_2_down_1 }, /* ^o */
+ { { deliver, noop }, synth_2_down_1 }, /* <> */
+ { { deliver, noop }, synth_2_down_1 }, /* <-> */
+ { { noop, noop }, synth_2_down_1 }, /* k */
+ { { noop, noop }, synth_2_down_1 }, /* ... */
+ },
+};
+
+#define EMULATION_WINDOW 10
+#define EMULATION_TIMEOUT 100
+
+static int
+KdInsideEmulationWindow (KdPointerInfo *pi, int x, int y, int z)
+{
+ pi->emulationDx = pi->heldEvent.x - x;
+ pi->emulationDy = pi->heldEvent.y - y;
+
+ return (abs (pi->emulationDx) < EMULATION_WINDOW &&
+ abs (pi->emulationDy) < EMULATION_WINDOW);
+}
+
+static KdInputClass
+KdClassifyInput (KdPointerInfo *pi, int type, int x, int y, int z, int b)
+{
+ switch (type) {
+ case ButtonPress:
+ switch (b) {
+ case 1: return down_1;
+ case 2: return down_2;
+ case 3: return down_3;
+ default: return down_o;
+ }
+ break;
+ case ButtonRelease:
+ switch (b) {
+ case 1: return up_1;
+ case 2: return up_2;
+ case 3: return up_3;
+ default: return up_o;
+ }
+ break;
+ case MotionNotify:
+ if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z))
+ return outside_box;
+ else
+ return motion;
+ default:
+ return keyboard;
+ }
+ return keyboard;
+}
+
+#ifdef DEBUG
+char *kdStateNames[] = {
+ "start",
+ "button_1_pend",
+ "button_1_down",
+ "button_2_down",
+ "button_3_pend",
+ "button_3_down",
+ "synth_2_down_13",
+ "synth_2_down_3",
+ "synthetic_2_down_1",
+ "num_input_states"
+};
+
+char *kdClassNames[] = {
+ "down_1", "up_1",
+ "down_2", "up_2",
+ "down_3", "up_3",
+ "motion", "ouside_box",
+ "keyboard", "timeout",
+ "num_input_class"
+};
+
+char *kdActionNames[] = {
+ "noop",
+ "hold",
+ "setto",
+ "deliver",
+ "release",
+ "clearto",
+ "gen_down_2",
+ "gen_up_2",
+};
+#endif /* DEBUG */
+
+static void
+KdQueueEvent (DeviceIntPtr pDev, InternalEvent *ev)
+{
+ KdAssertSigioBlocked ("KdQueueEvent");
+ mieqEnqueue (pDev, ev);
+}
+
+/* We return true if we're stealing the event. */
+static Bool
+KdRunMouseMachine (KdPointerInfo *pi, KdInputClass c, int type, int x, int y,
+ int z, int b, int absrel)
+{
+ const KdInputTransition *t;
+ int a;
+
+ c = KdClassifyInput(pi, type, x, y, z, b);
+ t = &kdInputMachine[pi->mouseState][c];
+ for (a = 0; a < MAX_ACTIONS; a++)
+ {
+ switch (t->actions[a]) {
+ case noop:
+ break;
+ case hold:
+ pi->eventHeld = TRUE;
+ pi->emulationDx = 0;
+ pi->emulationDy = 0;
+ pi->heldEvent.type = type;
+ pi->heldEvent.x = x;
+ pi->heldEvent.y = y;
+ pi->heldEvent.z = z;
+ pi->heldEvent.flags = b;
+ pi->heldEvent.absrel = absrel;
+ return TRUE;
+ break;
+ case setto:
+ pi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT;
+ pi->timeoutPending = TRUE;
+ break;
+ case deliver:
+ _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x,
+ pi->heldEvent.y, pi->heldEvent.z,
+ pi->heldEvent.flags, pi->heldEvent.absrel,
+ TRUE);
+ break;
+ case release:
+ pi->eventHeld = FALSE;
+ pi->timeoutPending = FALSE;
+ _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x,
+ pi->heldEvent.y, pi->heldEvent.z,
+ pi->heldEvent.flags, pi->heldEvent.absrel,
+ TRUE);
+ return TRUE;
+ break;
+ case clearto:
+ pi->timeoutPending = FALSE;
+ break;
+ case gen_down_2:
+ _KdEnqueuePointerEvent (pi, ButtonPress, x, y, z, 2, absrel,
+ TRUE);
+ pi->eventHeld = FALSE;
+ return TRUE;
+ break;
+ case gen_up_2:
+ _KdEnqueuePointerEvent (pi, ButtonRelease, x, y, z, 2, absrel,
+ TRUE);
+ return TRUE;
+ break;
+ }
+ }
+ pi->mouseState = t->nextState;
+ return FALSE;
+}
+
+static int
+KdHandlePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b,
+ int absrel)
+{
+ if (pi->emulateMiddleButton)
+ return KdRunMouseMachine (pi, KdClassifyInput(pi, type, x, y, z, b),
+ type, x, y, z, b, absrel);
+ return FALSE;
+}
+
+static void
+KdReceiveTimeout (KdPointerInfo *pi)
+{
+ KdRunMouseMachine (pi, timeout, 0, 0, 0, 0, 0, 0);
+}
+
+/*
+ * kdCheckTermination
+ *
+ * This function checks for the key sequence that terminates the server. When
+ * detected, it sets the dispatchException flag and returns. The key sequence
+ * is:
+ * Control-Alt
+ * It's assumed that the server will be waken up by the caller when this
+ * function returns.
+ */
+
+extern int nClients;
+
+void
+KdReleaseAllKeys (void)
+{
+#if 0
+ int key, nEvents, i;
+ KdKeyboardInfo *ki;
+
+ KdBlockSigio ();
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode;
+ key++) {
+ if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) {
+ KdHandleKeyboardEvent(ki, KeyRelease, key);
+ GetEventList(&kdEvents);
+ nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key);
+ for (i = 0; i < nEvents; i++)
+ KdQueueEvent (ki->dixdev, (kdEvents + i)->event);
+ }
+ }
+ }
+
+ KdUnblockSigio ();
+#endif
+}
+
+static void
+KdCheckLock (void)
+{
+ KeyClassPtr keyc = NULL;
+ Bool isSet = FALSE, shouldBeSet = FALSE;
+ KdKeyboardInfo *tmp = NULL;
+
+ for (tmp = kdKeyboards; tmp; tmp = tmp->next) {
+ if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) {
+ keyc = tmp->dixdev->key;
+ isSet = (tmp->leds & (1 << (tmp->LockLed-1))) != 0;
+ /* FIXME: Just use XKB indicators! */
+ shouldBeSet = !!(XkbStateFieldFromRec(&keyc->xkbInfo->state) & LockMask);
+ if (isSet != shouldBeSet)
+ KdSetLed (tmp, tmp->LockLed, shouldBeSet);
+ }
+ }
+}
+
+void
+KdEnqueueKeyboardEvent(KdKeyboardInfo *ki,
+ unsigned char scan_code,
+ unsigned char is_up)
+{
+ unsigned char key_code;
+ KeyClassPtr keyc = NULL;
+ KeybdCtrl *ctrl = NULL;
+ int type, nEvents, i;
+
+ if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key)
+ return;
+
+ keyc = ki->dixdev->key;
+ ctrl = &ki->dixdev->kbdfeed->ctrl;
+
+ if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode)
+ {
+ key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode;
+
+ /*
+ * Set up this event -- the type may be modified below
+ */
+ if (is_up)
+ type = KeyRelease;
+ else
+ type = KeyPress;
+
+ GetEventList(&kdEvents);
+
+ nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code);
+ for (i = 0; i < nEvents; i++)
+ KdQueueEvent(ki->dixdev, (InternalEvent *)((kdEvents + i)->event));
+ }
+ else {
+ ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n",
+ ki->name, scan_code, ki->minScanCode, ki->maxScanCode);
+ }
+}
+
+/*
+ * kdEnqueuePointerEvent
+ *
+ * This function converts hardware mouse event information into X event
+ * information. A mouse movement event is passed off to MI to generate
+ * a MotionNotify event, if appropriate. Button events are created and
+ * passed off to MI for enqueueing.
+ */
+
+/* FIXME do something a little more clever to deal with multiple axes here */
+void
+KdEnqueuePointerEvent(KdPointerInfo *pi, unsigned long flags, int rx, int ry,
+ int rz)
+{
+ CARD32 ms;
+ unsigned char buttons;
+ int x, y, z;
+ int (*matrix)[3] = kdPointerMatrix.matrix;
+ unsigned long button;
+ int n;
+ int dixflags = 0;
+
+ if (!pi)
+ return;
+
+ ms = GetTimeInMillis();
+
+ /* we don't need to transform z, so we don't. */
+ if (flags & KD_MOUSE_DELTA) {
+ if (pi->transformCoordinates) {
+ x = matrix[0][0] * rx + matrix[0][1] * ry;
+ y = matrix[1][0] * rx + matrix[1][1] * ry;
+ }
+ else {
+ x = rx;
+ y = ry;
+ }
+ }
+ else {
+ if (pi->transformCoordinates) {
+ x = matrix[0][0] * rx + matrix[0][1] * ry + matrix[0][2];
+ y = matrix[1][0] * rx + matrix[1][1] * ry + matrix[1][2];
+ }
+ else {
+ x = rx;
+ y = ry;
+ }
+ }
+ z = rz;
+
+ if (flags & KD_MOUSE_DELTA)
+ {
+ if (x || y || z)
+ {
+ dixflags = POINTER_RELATIVE | POINTER_ACCELERATE;
+ _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE);
+ }
+ } else
+ {
+ dixflags = POINTER_ABSOLUTE;
+ if (x != pi->dixdev->last.valuators[0] ||
+ y != pi->dixdev->last.valuators[1])
+ _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE);
+ }
+
+ buttons = flags;
+
+ for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons;
+ button <<= 1, n++) {
+ if (((pi->buttonState & button) ^ (buttons & button)) &&
+ !(buttons & button)) {
+ _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n,
+ dixflags, FALSE);
+ }
+ }
+ for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons;
+ button <<= 1, n++) {
+ if (((pi->buttonState & button) ^ (buttons & button)) &&
+ (buttons & button)) {
+ _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n,
+ dixflags, FALSE);
+ }
+ }
+
+ pi->buttonState = buttons;
+}
+
+void
+_KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z,
+ int b, int absrel, Bool force)
+{
+ int nEvents = 0, i = 0;
+ int valuators[3] = { x, y, z };
+
+ /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */
+ if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel))
+ return;
+
+ GetEventList(&kdEvents);
+ nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel,
+ 0, 3, valuators);
+ for (i = 0; i < nEvents; i++)
+ KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event));
+}
+
+void
+KdBlockHandler (int screen,
+ pointer blockData,
+ pointer timeout,
+ pointer readmask)
+{
+ KdPointerInfo *pi;
+ int myTimeout=0;
+
+ for (pi = kdPointers; pi; pi = pi->next)
+ {
+ if (pi->timeoutPending)
+ {
+ int ms;
+
+ ms = pi->emulationTimeout - GetTimeInMillis ();
+ if (ms < 1)
+ ms = 1;
+ if(ms<myTimeout || myTimeout==0)
+ myTimeout=ms;
+ }
+ }
+ /* if we need to poll for events, do that */
+ if(kdOsFuncs->pollEvents)
+ {
+ (*kdOsFuncs->pollEvents)();
+ myTimeout=20;
+ }
+ if(myTimeout>0)
+ AdjustWaitForDelay (timeout, myTimeout);
+}
+
+void
+KdWakeupHandler (int screen,
+ pointer data,
+ unsigned long lresult,
+ pointer readmask)
+{
+ int result = (int) lresult;
+ fd_set *pReadmask = (fd_set *) readmask;
+ int i;
+ KdPointerInfo *pi;
+
+ if (kdInputEnabled && result > 0)
+ {
+ for (i = 0; i < kdNumInputFds; i++)
+ if (FD_ISSET (kdInputFds[i].fd, pReadmask))
+ {
+ KdBlockSigio ();
+ (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
+ KdUnblockSigio ();
+ }
+ }
+ for (pi = kdPointers; pi; pi = pi->next)
+ {
+ if (pi->timeoutPending)
+ {
+ if ((long) (GetTimeInMillis () - pi->emulationTimeout) >= 0)
+ {
+ pi->timeoutPending = FALSE;
+ KdBlockSigio ();
+ KdReceiveTimeout (pi);
+ KdUnblockSigio ();
+ }
+ }
+ }
+ if (kdSwitchPending)
+ KdProcessSwitch ();
+}
+
+#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin))
+
+static Bool
+KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ ScreenPtr pScreen = *ppScreen;
+ ScreenPtr pNewScreen;
+ int n;
+ int dx, dy;
+ int best_x, best_y;
+ int n_best_x, n_best_y;
+ CARD32 ms;
+
+ if (kdDisableZaphod || screenInfo.numScreens <= 1)
+ return FALSE;
+
+ if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height)
+ return FALSE;
+
+ ms = GetTimeInMillis ();
+ if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000)
+ return FALSE;
+ kdOffScreen = TRUE;
+ kdOffScreenTime = ms;
+ n_best_x = -1;
+ best_x = 32767;
+ n_best_y = -1;
+ best_y = 32767;
+ for (n = 0; n < screenInfo.numScreens; n++)
+ {
+ pNewScreen = screenInfo.screens[n];
+ if (pNewScreen == pScreen)
+ continue;
+ dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x;
+ dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y;
+ if (*x < 0)
+ {
+ if (dx <= 0 && -dx < best_x)
+ {
+ best_x = -dx;
+ n_best_x = n;
+ }
+ }
+ else if (*x >= pScreen->width)
+ {
+ if (dx >= 0 && dx < best_x)
+ {
+ best_x = dx;
+ n_best_x = n;
+ }
+ }
+ if (*y < 0)
+ {
+ if (dy <= 0 && -dy < best_y)
+ {
+ best_y = -dy;
+ n_best_y = n;
+ }
+ }
+ else if (*y >= pScreen->height)
+ {
+ if (dy >= 0 && dy < best_y)
+ {
+ best_y = dy;
+ n_best_y = n;
+ }
+ }
+ }
+ if (best_y < best_x)
+ n_best_x = n_best_y;
+ if (n_best_x == -1)
+ return FALSE;
+ pNewScreen = screenInfo.screens[n_best_x];
+
+ if (*x < 0)
+ *x += pNewScreen->width;
+ if (*y < 0)
+ *y += pNewScreen->height;
+
+ if (*x >= pScreen->width)
+ *x -= pScreen->width;
+ if (*y >= pScreen->height)
+ *y -= pScreen->height;
+
+ *ppScreen = pNewScreen;
+ return TRUE;
+}
+
+static void
+KdCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+#ifndef XIPAQ
+ if (entering)
+ KdEnableScreen (pScreen);
+ else
+ KdDisableScreen (pScreen);
+#endif
+}
+
+int KdCurScreen; /* current event screen */
+
+static void
+KdWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ KdBlockSigio ();
+ KdCurScreen = pScreen->myNum;
+ miPointerWarpCursor(pDev, pScreen, x, y);
+ KdUnblockSigio ();
+}
+
+miPointerScreenFuncRec kdPointerScreenFuncs =
+{
+ KdCursorOffScreen,
+ KdCrossScreen,
+ KdWarpCursor
+};
+
+#ifndef _MSC_VER
+void
+ProcessInputEvents (void)
+{
+ mieqProcessInputEvents();
+ miPointerUpdateSprite(inputInfo.pointer);
+ if (kdSwitchPending)
+ KdProcessSwitch ();
+ KdCheckLock ();
+}
+#endif
+
+/* FIXME use XSECURITY to work out whether the client should be allowed to
+ * open and close. */
+void
+OpenInputDevice(DeviceIntPtr pDev, ClientPtr client, int *status)
+{
+ if (!pDev)
+ *status = BadDevice;
+ else
+ *status = Success;
+}
+
+void
+CloseInputDevice(DeviceIntPtr pDev, ClientPtr client)
+{
+ return;
+}
+
+/* We initialise all input devices at startup. */
+void
+AddOtherInputDevices(void)
+{
+ return;
+}
+
+/* At the moment, absolute/relative is up to the client. */
+int
+SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode)
+{
+ return BadMatch;
+}
+
+int
+SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev,
+ int *valuators, int first_valuator, int num_valuators)
+{
+ return BadMatch;
+}
+
+int
+ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev,
+ xDeviceCtl *control)
+{
+ switch (control->control) {
+ case DEVICE_RESOLUTION:
+ /* FIXME do something more intelligent here */
+ return BadMatch;
+
+ case DEVICE_ABS_CALIB:
+ case DEVICE_ABS_AREA:
+ return Success;
+
+ case DEVICE_CORE:
+ return BadMatch;
+ case DEVICE_ENABLE:
+ return Success;
+
+ default:
+ return BadMatch;
+ }
+
+ /* NOTREACHED */
+ return BadImplementation;
+}
+
+int
+NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev)
+{
+ InputOption *option = NULL;
+ KdPointerInfo *pi = NULL;
+ KdKeyboardInfo *ki = NULL;
+
+ for (option = options; option; option = option->next) {
+ if (strcmp(option->key, "type") == 0) {
+ if (strcmp(option->value, "pointer") == 0) {
+ pi = KdNewPointer();
+ if (!pi)
+ return BadAlloc;
+ }
+ else if (strcmp(option->value, "keyboard") == 0) {
+ ki = KdNewKeyboard();
+ if (!ki)
+ return BadAlloc;
+ }
+ else {
+ ErrorF("unrecognised device type!\n");
+ return BadValue;
+ }
+ }
+#ifdef CONFIG_HAL
+ else if (strcmp(option->key, "_source") == 0 &&
+ strcmp(option->value, "server/hal") == 0)
+ {
+ ErrorF("Ignoring device from HAL.\n");
+ return BadValue;
+ }
+#endif
+ }
+
+ if (!ki && !pi) {
+ ErrorF("unrecognised device identifier!\n");
+ return BadValue;
+ }
+
+ /* FIXME: change this code below to use KdParseKbdOptions and
+ * KdParsePointerOptions */
+ for (option = options; option; option = option->next) {
+ if (strcmp(option->key, "device") == 0) {
+ if (pi && option->value)
+ pi->path = strdup(option->value);
+ else if (ki && option->value)
+ ki->path = strdup(option->value);
+ }
+ else if (strcmp(option->key, "driver") == 0) {
+ if (pi) {
+ pi->driver = KdFindPointerDriver(option->value);
+ if (!pi->driver) {
+ ErrorF("couldn't find driver!\n");
+ KdFreePointer(pi);
+ return BadValue;
+ }
+ pi->options = options;
+ }
+ else if (ki) {
+ ki->driver = KdFindKeyboardDriver(option->value);
+ if (!ki->driver) {
+ ErrorF("couldn't find driver!\n");
+ KdFreeKeyboard(ki);
+ return BadValue;
+ }
+ ki->options = options;
+ }
+ }
+ }
+
+ if (pi) {
+ if (KdAddPointer(pi) != Success ||
+ ActivateDevice(pi->dixdev, TRUE) != Success ||
+ EnableDevice(pi->dixdev, TRUE) != TRUE) {
+ ErrorF("couldn't add or enable pointer\n");
+ return BadImplementation;
+ }
+ }
+ else if (ki) {
+ if (KdAddKeyboard(ki) != Success ||
+ ActivateDevice(ki->dixdev, TRUE) != Success ||
+ EnableDevice(ki->dixdev, TRUE) != TRUE) {
+ ErrorF("couldn't add or enable keyboard\n");
+ return BadImplementation;
+ }
+ }
+
+ if (pi) {
+ *pdev = pi->dixdev;
+ } else if(ki) {
+ *pdev = ki->dixdev;
+ }
+
+ return Success;
+}
+
+void
+DeleteInputDeviceRequest(DeviceIntPtr pDev)
+{
+ RemoveDevice(pDev, TRUE);
+}
diff --git a/xorg-server/hw/kdrive/src/kmap.c b/xorg-server/hw/kdrive/src/kmap.c index 60e8ae134..a10c9ec09 100644 --- a/xorg-server/hw/kdrive/src/kmap.c +++ b/xorg-server/hw/kdrive/src/kmap.c @@ -24,6 +24,7 @@ #include "kdrive.h" #include <errno.h> +#ifndef _MSC_VER #include <unistd.h> #include <sys/mman.h> #ifdef HAVE_ASM_MTRR_H @@ -31,6 +32,9 @@ #endif #include <sys/ioctl.h> +#else +#define DRAW_DEBUG(a) +#endif void * KdMapDevice (CARD32 addr, CARD32 size) @@ -39,7 +43,8 @@ KdMapDevice (CARD32 addr, CARD32 size) void *a; void *d; - d = VirtualAlloc (NULL, size, MEM_RESERVE, PAGE_NOACCESS); + d = VirtualAlloc (NULL, size, MEM_RESERVE, PAGE_READWRITE|PAGE_NOCACHE); +/* if (!d) return NULL; DRAW_DEBUG ((DEBUG_S3INIT, "Virtual address of 0x%x is 0x%x", addr, d)); @@ -53,6 +58,8 @@ KdMapDevice (CARD32 addr, CARD32 size) return NULL; } DRAW_DEBUG ((DEBUG_S3INIT, "Device mapped successfully")); +*/ + __asm int 3; return d; #endif #ifdef linux diff --git a/xorg-server/hw/kdrive/src/makefile b/xorg-server/hw/kdrive/src/makefile new file mode 100644 index 000000000..e3a826faa --- /dev/null +++ b/xorg-server/hw/kdrive/src/makefile @@ -0,0 +1,14 @@ +LIBRARY = libkdrive + +CSRCS = \ + kcmap.c \ + kcurscol.c \ + kdrive.c \ + kinfo.c \ + kinput.c \ + kmap.c \ + kmode.c \ + kshadow.c + + + |