Added ephyr server sources
This commit is contained in:
parent
6ec9ecd591
commit
2d065c4c33
|
@ -10,12 +10,18 @@ if XSDLSERVER
|
||||||
XSDL_SUBDIRS=sdl
|
XSDL_SUBDIRS=sdl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if XEPHYR
|
||||||
|
XEPHYR_SUBDIRS = ephyr
|
||||||
|
endif
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
src \
|
src \
|
||||||
linux \
|
linux \
|
||||||
$(XSDL_SUBDIRS) \
|
$(XSDL_SUBDIRS) \
|
||||||
$(FBDEV_SUBDIRS) \
|
$(FBDEV_SUBDIRS) \
|
||||||
$(VESA_SUBDIRS) \
|
$(VESA_SUBDIRS) \
|
||||||
|
$(XEPHYR_SUBDIRS) \
|
||||||
ati \
|
ati \
|
||||||
fake \
|
fake \
|
||||||
|
ephyr \
|
||||||
i810
|
i810
|
||||||
|
|
|
@ -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@
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
|
@ -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
|
|
@ -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 */
|
||||||
|
};
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue