diff options
author | Matthew Allum <breakfast@10.am> | 2004-08-31 16:33:05 +0000 |
---|---|---|
committer | Matthew Allum <breakfast@10.am> | 2004-08-31 16:33:05 +0000 |
commit | 2d065c4c33b9ec17c4c791070cf8189cb57bbb9c (patch) | |
tree | 3c8b69c3ef10a2910cccd539b68299a9ea0a7525 | |
parent | 6ec9ecd591fba9e9b69b8ebbd2fa08c0a2beac08 (diff) |
Added ephyr server sources
-rw-r--r-- | hw/kdrive/Makefile.am | 6 | ||||
-rw-r--r-- | hw/kdrive/ephyr/Makefile.am | 35 | ||||
-rw-r--r-- | hw/kdrive/ephyr/README | 71 | ||||
-rw-r--r-- | hw/kdrive/ephyr/ephyr.c | 677 | ||||
-rw-r--r-- | hw/kdrive/ephyr/ephyr.h | 156 | ||||
-rw-r--r-- | hw/kdrive/ephyr/ephyrinit.c | 183 | ||||
-rw-r--r-- | hw/kdrive/ephyr/hostx.c | 566 | ||||
-rw-r--r-- | hw/kdrive/ephyr/hostx.h | 137 | ||||
-rw-r--r-- | hw/kdrive/ephyr/os.c | 67 |
9 files changed, 1898 insertions, 0 deletions
diff --git a/hw/kdrive/Makefile.am b/hw/kdrive/Makefile.am index 7c5c406e0..27cd1ed63 100644 --- a/hw/kdrive/Makefile.am +++ b/hw/kdrive/Makefile.am @@ -10,12 +10,18 @@ if XSDLSERVER XSDL_SUBDIRS=sdl endif +if XEPHYR +XEPHYR_SUBDIRS = ephyr +endif + SUBDIRS = \ src \ linux \ $(XSDL_SUBDIRS) \ $(FBDEV_SUBDIRS) \ $(VESA_SUBDIRS) \ + $(XEPHYR_SUBDIRS) \ ati \ fake \ + ephyr \ i810 diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am new file mode 100644 index 000000000..1a38e5934 --- /dev/null +++ b/hw/kdrive/ephyr/Makefile.am @@ -0,0 +1,35 @@ +INCLUDES = \ + @KDRIVE_INCS@ \ + @XSERVER_CFLAGS@ + +noinst_LIBRARIES = libxephyr.a libxephyr-hostx.a + +bin_PROGRAMS = Xephyr + +libxephyr_a_SOURCES = \ + ephyr.c \ + os.c \ + hostx.h \ + ephyr.h + +libxephyr_hostx_a_SOURCES = \ + hostx.c \ + hostx.h + +libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@ + +Xephyr_SOURCES = \ + ephyrinit.c + +Xephyr_LDADD = \ + libxephyr.a \ + libxephyr-hostx.a \ + @KDRIVE_LIBS@ \ + @XSERVER_LIBS@ \ + @XEPHYR_LIBS@ + +Xephyr_DEPENDENCIES = \ + libxephyr.a \ + libxephyr-hostx.a \ + @KDRIVE_LIBS@ + diff --git a/hw/kdrive/ephyr/README b/hw/kdrive/ephyr/README new file mode 100644 index 000000000..309b73d6f --- /dev/null +++ b/hw/kdrive/ephyr/README @@ -0,0 +1,71 @@ +Xephyr README +============= + + +What Is It ? +============ + +Xephyr is a a kdrive server that outputs to a window on a pre-existing +'host' X display. Think Xnest but with support for modern extensions +like composite, damage and randr. + +Unlike Xnest which is an X proxy, i.e. limited to the +capabilities of the host X server, Xephyr is a real X server which +uses the host X server window as "framebuffer" via fast SHM XImages. + +It also has support for 'visually' debugging what the server is +painting. + + +How To Use +========== + +You probably want to run like; + +Xephyr :1 -ac -screen 800x600 & + +Then set DISPLAY=:1 and run whatever X apps you like. + +Use 'xrandr' to change to orientation/size. + +There is a '-parent' switch which works just like Xnests ( for use +with things like matchbox-nest - http://matchbox.handhelds.org ). + +There is also a '-host-cursor' switch to set 'cursor acceleration' - +The host's cursor is reused. This is only really there to aid +debugging by avoiding server paints for the cursor. Performance +improvement is negiable. + +Send a SIGUSR1 to the server ( eg kill -USR1 `pidof Xephyr` ) to +toggle the debugging mode. In this mode red rectangles are painted to +screen areas getting painted before painting the actual content. The +delay between this can be altered by setting a XEPHYR_PAUSE env var to +a value in nano seconds. + + +Caveats +======= + + - Depth is limited to being the same as the host. + + - Rotated displays are currently updated via full blits. This + is slower than a normal oprientated display. Debug mode will + therefor not be of much use rotated. + + - The '-host-cursor' cursor is static in its appearence. + + - The build gets a warning about 'nanosleep'. I think the various '-D' + build flags are causing this. I havn't figured as yet how to work + round it. It doesn't appear to break anything however. + + - Keyboard handling is basic but works. + + - Mouse button 5 probably wont work. + + + + + +Matthew Allum <mallum@o-hand.com> 2004 + + diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c new file mode 100644 index 000000000..ffee350c3 --- /dev/null +++ b/hw/kdrive/ephyr/ephyr.c @@ -0,0 +1,677 @@ +/* + * 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. + */ + +/* TODO: + * + * POSSIBLES + * - much improve keyboard handling *kind of done* + * - '-fullscreen' switch ? + * - full keyboard grab option somehow ? - use for testing WM key shortcuts + * with out host WM getting them instead. + * - Make cursor 'accel' better. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "ephyr.h" + +extern int KdTsPhyScreen; + +static int mouseState = 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; + + if (hostx_want_screen_size(&width, &height) + || !screen->width || !screen->height) + { + screen->width = width; + screen->height = height; + } + + screen->width_mm = screen->width * hostx_mm_per_pixel_horizontal(); + screen->height_mm = screen->height * hostx_mm_per_pixel_vertical(); + + screen->fb[0].depth = hostx_get_depth(); + screen->rate = 72; + + if (screen->fb[0].depth <= 8) + { + screen->fb[0].visuals = ((1 << StaticGray) | + (1 << GrayScale) | + (1 << StaticColor) | + (1 << PseudoColor) | + (1 << TrueColor) | + (1 << DirectColor)); + } + else + { + screen->fb[0].visuals = (1 << TrueColor); + + if (screen->fb[0].depth <= 15) + { + screen->fb[0].depth = 15; + screen->fb[0].bitsPerPixel = 16; + + hostx_get_visual_masks (&screen->fb[0].redMask, + &screen->fb[0].greenMask, + &screen->fb[0].blueMask); + + } + else if (screen->fb[0].depth <= 16) + { + screen->fb[0].depth = 16; + screen->fb[0].bitsPerPixel = 16; + + hostx_get_visual_masks (&screen->fb[0].redMask, + &screen->fb[0].greenMask, + &screen->fb[0].blueMask); + } + else + { + screen->fb[0].depth = 24; + screen->fb[0].bitsPerPixel = 32; + + hostx_get_visual_masks (&screen->fb[0].redMask, + &screen->fb[0].greenMask, + &screen->fb[0].blueMask); + } + } + + scrpriv->randr = screen->randr; + + return ephyrMapFramebuffer (screen); +} + +Bool +ephyrScreenInit (KdScreenInfo *screen) +{ + EphyrScrPriv *scrpriv; + + scrpriv = xalloc (sizeof (EphyrScrPriv)); + if (!scrpriv) + return FALSE; + memset (scrpriv, 0, sizeof (EphyrScrPriv)); + 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; + KdMouseMatrix m; + + EPHYR_DBG(" screen->width: %d, screen->height: %d", + screen->width, screen->height); + + /* Always use shadow so we get damage notifications */ + scrpriv->shadow = TRUE; + + KdComputeMouseMatrix (&m, scrpriv->randr, screen->width, screen->height); + + KdSetMouseMatrix (&m); + + priv->bytes_per_line = ((screen->width * screen->fb[0].bitsPerPixel + 31) >> 5) << 2; + + /* point the framebuffer to the data in an XImage */ + priv->base = hostx_screen_init (screen->width, screen->height); + + screen->memory_base = (CARD8 *) (priv->base); + screen->memory_size = 0; + screen->off_screen_base = 0; + + 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) +{ + 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; + EphyrScrPriv *scrpriv = screen->driver; + int nbox; + BoxPtr pbox; + + RegionPtr damage; + + if (!(scrpriv->randr & RR_Rotate_0) || (scrpriv->randr & RR_Reflect_All)) + { + /* Rotated. + * TODO: Fix this to use damage as well so much faster. + * Sledgehammer approach atm. + * + * Catch reflects here too - though thats wrong ... + */ + EPHYR_DBG("slow paint"); + shadowUpdateRotatePacked(pScreen, pBuf); + hostx_paint_rect(0,0,0,0, screen->width, screen->height); + return; + } + else shadowUpdatePacked(pScreen, pBuf); + + /* Figure out what rects have changed and update em. */ + + if (!pBuf || !pBuf->pDamage) + return; + + damage = DamageRegion (pBuf->pDamage); + + if (!REGION_NOTEMPTY (pScreen, damage)) + return; + + nbox = REGION_NUM_RECTS (damage); + pbox = REGION_RECTS (damage); + + while (nbox--) + { + hostx_paint_rect(pbox->x1, pbox->y1, + pbox->x1, pbox->y1, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + pbox++; + } +} + +Bool +ephyrSetShadow (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + EphyrScrPriv *scrpriv = screen->driver; + ShadowUpdateProc update; + ShadowWindowProc window; + + window = ephyrWindowLinear; + update = ephyrShadowUpdate; + + return KdShadowSet (pScreen, scrpriv->randr, update, window); +} + +#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; + + EPHYR_DBG("mark"); + + struct { int width, height; } sizes[] = + { + { 1600, 1200 }, + { 1400, 1050 }, + { 1280, 960 }, + { 1280, 1024 }, + { 1152, 768 }, + { 1024, 768 }, + { 832, 624 }, + { 800, 600 }, + { 720, 400 }, + { 480, 640 }, + { 640, 480 }, + { 640, 400 }, + { 320, 240 }, + { 240, 320 }, + { 160, 160 }, + { 0, 0 } + }; + + *rotations = RR_Rotate_All|RR_Reflect_All; + + if (!hostx_want_preexisting_window()) /* 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 * hostx_mm_per_pixel_horizontal(), + sizes[n].height * hostx_mm_per_pixel_vertical()); + 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; + int oldheight; + int oldmmwidth; + int oldmmheight; + 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; + + /* + * Set new configuration + */ + + scrpriv->randr = KdAddRotation (screen->randr, randr); + + KdOffscreenSwapOut (screen->pScreen); + + ephyrUnmapFramebuffer (screen); + + screen->width = newwidth; + screen->height = newheight; + + if (!ephyrMapFramebuffer (screen)) + goto bail4; + + KdShadowUnset (screen->pScreen); + + if (!ephyrSetShadow (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_DBG("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) +{ +#ifdef TOUCHSCREEN + KdTsPhyScreen = pScreen->myNum; +#endif + + pScreen->CreateColormap = ephyrCreateColormap; + return TRUE; +} + +Bool +ephyrFinishInitScreen (ScreenPtr pScreen) +{ + if (!shadowSetup (pScreen)) + return FALSE; + +#ifdef RANDR + if (!ephyrRandRInit (pScreen)) + return FALSE; +#endif + + return TRUE; +} + +Bool +ephyrCreateResources (ScreenPtr pScreen) +{ + return ephyrSetShadow (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) +{ +} + +void +ephyrPoll(void) +{ + EphyrHostXEvent ev; + + while (hostx_get_event(&ev)) + { + switch (ev.type) + { + case EPHYR_EV_MOUSE_MOTION: + KdEnqueueMouseEvent(kdMouseInfo, mouseState, + ev.data.mouse_motion.x, + ev.data.mouse_motion.y); + break; + + case EPHYR_EV_MOUSE_PRESS: + + mouseState |= ev.data.mouse_down.button_num; + KdEnqueueMouseEvent(kdMouseInfo, mouseState|KD_MOUSE_DELTA, 0, 0); + break; + + case EPHYR_EV_MOUSE_RELEASE: + + mouseState &= ~ev.data.mouse_up.button_num; + KdEnqueueMouseEvent(kdMouseInfo, mouseState|KD_MOUSE_DELTA, 0, 0); + break; + + case EPHYR_EV_KEY_PRESS: + + KdEnqueueKeyboardEvent (ev.data.key_down.scancode, FALSE); + break; + + case EPHYR_EV_KEY_RELEASE: + + KdEnqueueKeyboardEvent (ev.data.key_up.scancode, TRUE); + break; + + default: + break; + } + } +} + +void +ephyrCardFini (KdCardInfo *card) +{ + EphyrPriv *priv = card->driver; + xfree (priv); +} + +void +ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) +{ + while (n--) + { + pdefs->red = 0; + pdefs->green = 0; + pdefs->blue = 0; + pdefs++; + } +} + +void +ephyrPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) +{ +} + +/* Mouse calls */ + +static Bool +MouseInit (void) +{ + return TRUE; +} + +static void +MouseFini (void) +{ + ; +} + +KdMouseFuncs EphyrMouseFuncs = { + MouseInit, + MouseFini, +}; + +/* Keyboard */ + +static void +EphyrKeyboardLoad (void) +{ + EPHYR_DBG("mark"); + + hostx_load_keymap(); +} + +static int +EphyrKeyboardInit (void) +{ + return 0; +} + +static void +EphyrKeyboardFini (void) +{ +} + +static void +EphyrKeyboardLeds (int leds) +{ +} + +static void +EphyrKeyboardBell (int volume, int frequency, int duration) +{ +} + +KdKeyboardFuncs EphyrKeyboardFuncs = { + EphyrKeyboardLoad, + EphyrKeyboardInit, + EphyrKeyboardLeds, + EphyrKeyboardBell, + EphyrKeyboardFini, + 0, +}; diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h new file mode 100644 index 000000000..d7c9ecdb4 --- /dev/null +++ b/hw/kdrive/ephyr/ephyr.h @@ -0,0 +1,156 @@ +/* + * 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. + */ + +#ifndef _EPHYR_H_ +#define _EPHYR_H_ +#include <stdio.h> +#include <unistd.h> +#include <signal.h> + +#include "os.h" /* for OsSignal() */ +#include "kdrive.h" +#include "kkeymap.h" +#include "hostx.h" + +#ifdef RANDR +#include "randrstr.h" +#endif + +typedef struct _ephyrPriv { + CARD8 *base; + int bytes_per_line; +} EphyrPriv; + +typedef struct _ephyrScrPriv { + Rotation randr; + Bool shadow; + PixmapPtr pShadow; +} EphyrScrPriv; + +extern KdCardFuncs ephyrFuncs; + +Bool +ephyrInitialize (KdCardInfo *card, EphyrPriv *priv); + +Bool +ephyrCardInit (KdCardInfo *card); + +Bool +ephyrScreenInit (KdScreenInfo *screen); + +Bool +ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv); + +Bool +ephyrInitScreen (ScreenPtr pScreen); + +Bool +ephyrFinishInitScreen (ScreenPtr pScreen); + +Bool +ephyrCreateResources (ScreenPtr pScreen); + +void +ephyrPreserve (KdCardInfo *card); + +Bool +ephyrEnable (ScreenPtr pScreen); + +Bool +ephyrDPMS (ScreenPtr pScreen, int mode); + +void +ephyrDisable (ScreenPtr pScreen); + +void +ephyrRestore (KdCardInfo *card); + +void +ephyrScreenFini (KdScreenInfo *screen); + +void +ephyrCardFini (KdCardInfo *card); + +void +ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs); + +void +ephyrPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs); + +Bool +ephyrMapFramebuffer (KdScreenInfo *screen); + +void * +ephyrWindowLinear (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure); + +void +ephyrSetScreenSizes (ScreenPtr pScreen); + +Bool +ephyrUnmapFramebuffer (KdScreenInfo *screen); + +Bool +ephyrSetShadow (ScreenPtr pScreen); + +Bool +ephyrCreateColormap (ColormapPtr pmap); + +void +ephyrPoll(void); + +#ifdef RANDR +Bool +ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations); + +Bool +ephyrRandRSetConfig (ScreenPtr pScreen, + Rotation randr, + int rate, + RRScreenSizePtr pSize); +Bool +ephyrRandRInit (ScreenPtr pScreen); + +void +ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf); + +#endif + +extern KdMouseFuncs EphyrMouseFuncs; + +extern KdKeyboardFuncs EphyrKeyboardFuncs; + +extern KdOsFuncs EphyrOsFuncs; + +extern Bool ephyrCursorInit(ScreenPtr pScreen); + +extern void ephyrCursorEnable(ScreenPtr pScreen); + + +#endif diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c new file mode 100644 index 000000000..76df5885e --- /dev/null +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -0,0 +1,183 @@ +/* + * 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 <config.h> +#endif +#include "ephyr.h" + +extern Window EphyrPreExistingHostWin; + +void +InitCard (char *name) +{ + KdCardAttr attr; + + EPHYR_DBG("mark"); + + if (hostx_want_host_cursor()) + { + ephyrFuncs.initCursor = &ephyrCursorInit; + ephyrFuncs.enableCursor = &ephyrCursorEnable; + } + + KdCardInfoAdd (&ephyrFuncs, &attr, 0); +} + +void +InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) +{ + KdInitOutput (pScreenInfo, argc, argv); +} + +void +InitInput (int argc, char **argv) +{ + KdInitInput (&EphyrMouseFuncs, &EphyrKeyboardFuncs); +} + +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("\n"); + + exit(1); +} + +int +ddxProcessArgument (int argc, char **argv, int i) +{ + EPHYR_DBG("mark"); + + if (!strcmp (argv[i], "-parent")) + { + if(i+1 < argc) + { + hostx_use_preexisting_window(strtol(argv[i+1], NULL, 0)); + return 2; + } + + UseMsg(); + exit(1); + } + else if (!strcmp (argv[i], "-host-cursor")) + { + hostx_use_host_cursor(); + return 1; + } + + return KdProcessArgument (argc, argv, i); +} + +void +OsVendorInit (void) +{ + EPHYR_DBG("mark"); + KdOsInit (&EphyrOsFuncs); +} + +/* 'Fake' cursor stuff, could be improved */ + +static Bool +ephyrRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + +static Bool +ephyrUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + +static void +ephyrSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +{ + ; +} + +static void +ephyrMoveCursor(ScreenPtr pScreen, int x, int y) +{ + ; +} + +miPointerSpriteFuncRec EphyrPointerSpriteFuncs = { + ephyrRealizeCursor, + ephyrUnrealizeCursor, + ephyrSetCursor, + ephyrMoveCursor, +}; + + +Bool +ephyrCursorInit(ScreenPtr pScreen) +{ + miPointerInitialize(pScreen, &EphyrPointerSpriteFuncs, + &kdPointerScreenFuncs, 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, /* syncAccel */ + 0, /* disableAccel */ + 0, /* finiAccel */ + + ephyrGetColors, /* getColors */ + ephyrPutColors, /* putColors */ +}; diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c new file mode 100644 index 000000000..a4aea3f3f --- /dev/null +++ b/hw/kdrive/ephyr/hostx.c @@ -0,0 +1,566 @@ +/* + * Xephyr - A kdrive X server thats runs in a host X window. + * Authored by Matthew Allum <mallum@o-hand.com> + * + * Copyright © 2004 Nokia + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Nokia not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Nokia makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "hostx.h" + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> /* for memset */ +#include <time.h> + +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/time.h> + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <X11/extensions/XShm.h> + +/* + * All xlib calls go here, which gets built as its own .a . + * Mixing kdrive and xlib headers causes all sorts of types + * to get clobbered. + */ + +struct EphyrHostXVars +{ + Display *dpy; + int screen; + Visual *visual; + Window win, winroot; + Window win_pre_existing; /* Set via -parent option like xnest */ + GC gc; + int depth; + XImage *ximg; + int win_width, win_height; + double mm_per_pixel_vertical, mm_per_pixel_horizontal; + + Bool use_host_cursor; + Bool have_shm; + long damage_debug_nsec; + + XShmSegmentInfo shminfo; +}; + +static EphyrHostXVars HostX = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; /* defaults */ + +static int HostXWantDamageDebug = 0; + +extern KeySym EphyrKeymap[]; + +extern KeySym kdKeymap[]; +extern int kdMinScanCode; +extern int kdMaxScanCode; +extern int kdMinKeyCode; +extern int kdMaxKeyCode; +extern int kdKeymapWidth; + +/* X Error traps */ + +static int trapped_error_code = 0; +static int (*old_error_handler) (Display *d, XErrorEvent *e); + +static int +error_handler(Display *display, + XErrorEvent *error) +{ + trapped_error_code = error->error_code; + return 0; +} + +static void +hostx_errors_trap(void) +{ + trapped_error_code = 0; + old_error_handler = XSetErrorHandler(error_handler); +} + +static int +hostx_errors_untrap(void) +{ + XSetErrorHandler(old_error_handler); + return trapped_error_code; +} + +int +hostx_want_screen_size(int *width, int *height) +{ + if (HostX.win_pre_existing != None) + { + *width = HostX.win_width; + *height = HostX.win_height; + return 1; + } + + return 0; +} + +int +hostx_want_host_cursor(void) +{ + return HostX.use_host_cursor; +} + +void +hostx_use_host_cursor(void) +{ + HostX.use_host_cursor = True; +} + +int +hostx_want_preexisting_window(void) +{ + if (HostX.win_pre_existing) + return 1; + else + return 0; +} + +void +hostx_use_preexisting_window(unsigned long win_id) +{ + HostX.win_pre_existing = win_id; +} + +static void +hostx_toggle_damage_debug(void) +{ + HostXWantDamageDebug ^= 1; +} + +void +hostx_handle_signal(int signum) +{ + hostx_toggle_damage_debug(); + EPHYR_DBG("Signal caught. Damage Debug:%i\n", HostXWantDamageDebug); +} + +int +hostx_init(void) +{ + XSetWindowAttributes attr; + Cursor empty_cursor; + Pixmap cursor_pxm; + XColor col; + + attr.event_mask = + ButtonPressMask + |ButtonReleaseMask + |PointerMotionMask + |KeyPressMask + |KeyReleaseMask + |ExposureMask; + + EPHYR_DBG("mark"); + + if ((HostX.dpy = XOpenDisplay(getenv("DISPLAY"))) == NULL) + { + fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n"); + exit(1); + } + + HostX.screen = DefaultScreen(HostX.dpy); + HostX.winroot = RootWindow(HostX.dpy, HostX.screen); + HostX.gc = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL); + HostX.depth = DefaultDepth(HostX.dpy, HostX.screen); + HostX.visual = DefaultVisual(HostX.dpy, HostX.screen); + + HostX.mm_per_pixel_vertical = (double)DisplayHeightMM(HostX.dpy, HostX.screen) + / DisplayHeight(HostX.dpy, HostX.screen); + + HostX.mm_per_pixel_horizontal = (double)DisplayWidthMM(HostX.dpy, HostX.screen) + / DisplayWidth(HostX.dpy, HostX.screen); + + if (HostX.win_pre_existing != None) + { + Status result; + XWindowAttributes attr; + + /* Get screen size from existing window */ + + HostX.win = HostX.win_pre_existing; + + hostx_errors_trap(); + + result = XGetWindowAttributes(HostX.dpy, HostX.win, &attr); + + if (hostx_errors_untrap() || !result) + { + fprintf(stderr, "\nXephyr -parent window' does not exist!\n"); + exit(1); + } + + HostX.win_width = attr.width; + HostX.win_height = attr.height; + } + else + { + HostX.win = XCreateWindow(HostX.dpy, + HostX.winroot, + 0,0,100,100, /* will resize */ + 0, + CopyFromParent, + CopyFromParent, + CopyFromParent, + CWEventMask, + &attr); + + XStoreName(HostX.dpy, HostX.win, "Xephyr"); + } + + HostX.gc = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL); + + XParseColor(HostX.dpy, DefaultColormap(HostX.dpy,HostX.screen), "red", &col); + XAllocColor(HostX.dpy, DefaultColormap(HostX.dpy, HostX.screen), &col); + XSetForeground(HostX.dpy, HostX.gc, col.pixel); + + if (!hostx_want_host_cursor()) + { + /* Ditch the cursor, we provide our 'own' */ + cursor_pxm = XCreatePixmap (HostX.dpy, HostX.winroot, 1, 1, 1); + memset (&col, 0, sizeof (col)); + empty_cursor = XCreatePixmapCursor (HostX.dpy, + cursor_pxm, cursor_pxm, + &col, &col, 1, 1); + XDefineCursor (HostX.dpy, HostX.win, empty_cursor); + XFreePixmap (HostX.dpy, cursor_pxm); + } + + HostX.ximg = NULL; + + /* Try to get share memory ximages for a little bit more speed */ + + if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM")) + { + fprintf(stderr, "\nXephyr unable to use SHM XImages\n"); + HostX.have_shm = False; + } + else + { + /* Really really check we have shm - better way ?*/ + XShmSegmentInfo shminfo; + + HostX.have_shm = True; + + shminfo.shmid=shmget(IPC_PRIVATE, 1, IPC_CREAT|0777); + shminfo.shmaddr=shmat(shminfo.shmid,0,0); + shminfo.readOnly=True; + + hostx_errors_trap(); + + XShmAttach(HostX.dpy, &shminfo); + XSync(HostX.dpy, False); + + if (hostx_errors_untrap()) + { + fprintf(stderr, "\nXephyr unable to use SHM XImages\n"); + HostX.have_shm = False; + } + + shmdt(shminfo.shmaddr); + shmctl(shminfo.shmid, IPC_RMID, 0); + } + + XFlush(HostX.dpy); + + /* Setup the pause time between paints when debugging updates */ + + HostX.damage_debug_nsec = 10^8; + + if (getenv("XEPHYR_PAUSE")) + HostX.damage_debug_nsec = strtol(getenv("XEPHYR_PAUSE"), NULL, 0); + + return 1; +} + +int +hostx_get_depth (void) +{ + return HostX.depth; +} + +int +hostx_get_bpp(void) +{ + return HostX.visual->bits_per_rgb; +} + +void +hostx_get_visual_masks (unsigned long *rmsk, + unsigned long *gmsk, + unsigned long *bmsk) +{ + *rmsk = HostX.visual->red_mask; + *gmsk = HostX.visual->green_mask; + *bmsk = HostX.visual->blue_mask; +} + +double +hostx_mm_per_pixel_vertical(void) +{ + return HostX.mm_per_pixel_vertical; +} + +double +hostx_mm_per_pixel_horizontal(void) +{ + return HostX.mm_per_pixel_horizontal; +} + + +void* +hostx_screen_init (int width, int height) +{ + int bitmap_pad; + Bool shm_success = False; + XSizeHints *size_hints; + + EPHYR_DBG("mark"); + + if (HostX.ximg != NULL) + { + /* Free up the image data if previously used + * i.ie called by server reset + */ + + if (HostX.have_shm) + { + XShmDetach(HostX.dpy, &HostX.shminfo); + XDestroyImage (HostX.ximg); + shmdt(HostX.shminfo.shmaddr); + shmctl(HostX.shminfo.shmid, IPC_RMID, 0); + } + else + { + if (HostX.ximg->data) + { + free(HostX.ximg->data); + HostX.ximg->data = NULL; + } + + XDestroyImage(HostX.ximg); + } + } + + if (HostX.have_shm) + { + HostX.ximg = XShmCreateImage(HostX.dpy, HostX.visual, HostX.depth, + ZPixmap, NULL, &HostX.shminfo, + width, height ); + + HostX.shminfo.shmid = shmget(IPC_PRIVATE, + HostX.ximg->bytes_per_line * height, + IPC_CREAT|0777); + HostX.shminfo.shmaddr = HostX.ximg->data = shmat(HostX.shminfo.shmid, + 0, 0); + + if (HostX.ximg->data == (char *)-1) + { + EPHYR_DBG("Can't attach SHM Segment, falling back to plain XImages"); + HostX.have_shm = False; + XDestroyImage(HostX.ximg); + shmctl(HostX.shminfo.shmid, IPC_RMID, 0); + } + else + { + EPHYR_DBG("SHM segment attached"); + HostX.shminfo.readOnly = False; + XShmAttach(HostX.dpy, &HostX.shminfo); + shm_success = True; + } + } + + if (!shm_success) + { + bitmap_pad = ( HostX.depth > 16 )? 32 : (( HostX.depth > 8 )? 16 : 8 ); + + HostX.ximg = XCreateImage( HostX.dpy, + HostX.visual, + HostX.depth, + ZPixmap, 0, 0, + width, + height, + bitmap_pad, + 0); + + HostX.ximg->data = malloc( HostX.ximg->bytes_per_line * height ); + } + + + XResizeWindow(HostX.dpy, HostX.win, width, height); + + /* Ask the WM to keep our size static */ + size_hints = XAllocSizeHints(); + size_hints->max_width = size_hints->min_width = width; + size_hints->max_height = size_hints->min_height = height; + size_hints->flags = PMinSize|PMaxSize; + XSetWMNormalHints(HostX.dpy, HostX.win, size_hints); + XFree(size_hints); + + XMapWindow(HostX.dpy, HostX.win); + + XSync(HostX.dpy, False); + + HostX.win_width = width; + HostX.win_height = height; + + return HostX.ximg->data; +} + +void +hostx_paint_rect(int sx, int sy, + int dx, int dy, + int width, int height) +{ + /* + * Copy the image data updated by the shadow layer + * on to the window + */ + + if (HostXWantDamageDebug) + { + hostx_paint_debug_rect(dx, dy, width, height); + } + + if (HostX.have_shm) + { + XShmPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg, + sx, sy, dx, dy, width, height, False); + } + else + { + XPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg, + sx, sy, dx, dy, width, height); + } + + XSync(HostX.dpy, False); +} + +void +hostx_paint_debug_rect(int x, int y, + int width, int height) +{ + struct timespec tspec; + + tspec.tv_sec = 0; + tspec.tv_nsec = HostX.damage_debug_nsec; + + XFillRectangle(HostX.dpy, HostX.win, HostX.gc, x, y, width,height); + XSync(HostX.dpy, False); + + nanosleep(&tspec, NULL); +} + +void +hostx_load_keymap(void) +{ + KeySym *keymap; + int mapWidth, min_keycode, max_keycode; + + XDisplayKeycodes(HostX.dpy, &min_keycode, &max_keycode); + + EPHYR_DBG("min: %d, max: %d", min_keycode, max_keycode); + + keymap = XGetKeyboardMapping(HostX.dpy, + min_keycode, + max_keycode - min_keycode + 1, + &mapWidth); + + memcpy (kdKeymap, keymap, + (max_keycode - min_keycode + 1)*mapWidth*sizeof(KeySym)); + + EPHYR_DBG("keymap width: %d", mapWidth); + + /* all kdrive vars - see kkeymap.c */ + + kdMinScanCode = min_keycode; + kdMaxScanCode = max_keycode; + kdMinKeyCode = min_keycode; + kdMaxKeyCode = max_keycode; + kdKeymapWidth = mapWidth; + + XFree(keymap); +} + +int +hostx_get_event(EphyrHostXEvent *ev) +{ + XEvent xev; + + if (XPending(HostX.dpy)) + { + XNextEvent(HostX.dpy, &xev); + + switch (xev.type) + { + case Expose: + /* Not so great event compression, but works ok */ + while (XCheckTypedWindowEvent(HostX.dpy, xev.xexpose.window, + Expose, &xev)); + hostx_paint_rect(0, 0, 0, 0, HostX.win_width, HostX.win_height); + return 0; + + case MotionNotify: + ev->type = EPHYR_EV_MOUSE_MOTION; + ev->data.mouse_motion.x = xev.xmotion.x; + ev->data.mouse_motion.y = xev.xmotion.y; + return 1; + + case ButtonPress: + ev->type = EPHYR_EV_MOUSE_PRESS; + /* + * This is a bit hacky. will break for button 5 ( defined as 0x10 ) + * Check KD_BUTTON defines in kdrive.h + */ + ev->data.mouse_down.button_num = 1<<(xev.xbutton.button-1); + return 1; + + case ButtonRelease: + ev->type = EPHYR_EV_MOUSE_RELEASE; + ev->data.mouse_up.button_num = 1<<(xev.xbutton.button-1); + return 1; + + case KeyPress: + { + ev->type = EPHYR_EV_KEY_PRESS; + ev->data.key_down.scancode = xev.xkey.keycode; + return 1; + } + case KeyRelease: + ev->type = EPHYR_EV_KEY_RELEASE; + ev->data.key_up.scancode = xev.xkey.keycode; + + return 1; + + default: + break; + + } + } + return 0; +} + diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h new file mode 100644 index 000000000..69607e73d --- /dev/null +++ b/hw/kdrive/ephyr/hostx.h @@ -0,0 +1,137 @@ +/* + * 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. + */ + +#ifndef _XLIBS_STUFF_H_ +#define _XLIBS_STUFF_H_ + +#define EPHYR_WANT_DEBUG 0 + +#if (EPHYR_WANT_DEBUG) +#define EPHYR_DBG(x, a...) \ + fprintf(stderr, __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a) +#else +#define EPHYR_DBG(x, a...) do {} while (0) +#endif + +typedef struct EphyrHostXVars EphyrHostXVars; +typedef struct EphyrHostXEvent EphyrHostXEvent; + +typedef enum EphyrHostXEventType +{ + EPHYR_EV_MOUSE_MOTION, + EPHYR_EV_MOUSE_PRESS, + EPHYR_EV_MOUSE_RELEASE, + EPHYR_EV_KEY_PRESS, + EPHYR_EV_KEY_RELEASE +} +EphyrHostXEventType; + +struct EphyrHostXEvent +{ + EphyrHostXEventType type; + + union + { + struct mouse_motion { + int x; + int y; + } mouse_motion; + + struct mouse_down { + int button_num; + } mouse_down; + + struct mouse_up { + int button_num; + } mouse_up; + + struct key_up { + int scancode; + } key_up; + + struct key_down { + int scancode; + } key_down; + + } data; + +}; + +int +hostx_want_screen_size(int *width, int *height); + +int +hostx_want_host_cursor(void); + +void +hostx_use_host_cursor(void); + +int +hostx_want_preexisting_window(void); + +void +hostx_use_preexisting_window(unsigned long win_id); + +void +hostx_handle_signal(int signum); + +int +hostx_init(void); + +int +hostx_get_depth (void); + +int +hostx_get_bpp(void); + +void +hostx_get_visual_masks (unsigned long *rmsk, + unsigned long *gmsk, + unsigned long *bmsk); + +double +hostx_mm_per_pixel_vertical(void); + +double +hostx_mm_per_pixel_horizontal(void); + +void* +hostx_screen_init (int width, int height); + +void +hostx_paint_rect(int sx, int sy, + int dx, int dy, + int width, int height); +void +hostx_paint_debug_rect(int x, int y, + int width, int height); + +void +hostx_load_keymap(void); + +int +hostx_get_event(EphyrHostXEvent *ev); + +#endif diff --git a/hw/kdrive/ephyr/os.c b/hw/kdrive/ephyr/os.c new file mode 100644 index 000000000..2ee556155 --- /dev/null +++ b/hw/kdrive/ephyr/os.c @@ -0,0 +1,67 @@ +/* + * 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 <config.h> +#endif +#include "ephyr.h" + +static int +EphyrInit (void) +{ + return hostx_init(); +} + +static void +EphyrEnable (void) +{ + EPHYR_DBG("mark"); +} + +static Bool +EphyrSpecialKey (KeySym sym) +{ + return FALSE; +} + +static void +EphyrDisable (void) +{ +} + +static void +EphyrFini (void) +{ +} + +KdOsFuncs EphyrOsFuncs = { + EphyrInit, + EphyrEnable, + EphyrSpecialKey, + EphyrDisable, + EphyrFini, + ephyrPoll +}; + |