1706f2543Smrg/* 2706f2543Smrg * Xephyr - A kdrive X server thats runs in a host X window. 3706f2543Smrg * Authored by Matthew Allum <mallum@openedhand.com> 4706f2543Smrg * 5706f2543Smrg * Copyright � 2004 Nokia 6706f2543Smrg * 7706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 8706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 9706f2543Smrg * the above copyright notice appear in all copies and that both that 10706f2543Smrg * copyright notice and this permission notice appear in supporting 11706f2543Smrg * documentation, and that the name of Nokia not be used in 12706f2543Smrg * advertising or publicity pertaining to distribution of the software without 13706f2543Smrg * specific, written prior permission. Nokia makes no 14706f2543Smrg * representations about the suitability of this software for any purpose. It 15706f2543Smrg * is provided "as is" without express or implied warranty. 16706f2543Smrg * 17706f2543Smrg * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19706f2543Smrg * EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 24706f2543Smrg */ 25706f2543Smrg 26706f2543Smrg#ifdef HAVE_CONFIG_H 27706f2543Smrg#include <kdrive-config.h> 28706f2543Smrg#endif 29706f2543Smrg#include "ephyr.h" 30706f2543Smrg 31706f2543Smrg#include "inputstr.h" 32706f2543Smrg#include "scrnintstr.h" 33706f2543Smrg#include "ephyrlog.h" 34706f2543Smrg 35706f2543Smrg#ifdef XF86DRI 36706f2543Smrg#include "ephyrdri.h" 37706f2543Smrg#include "ephyrdriext.h" 38706f2543Smrg#include "ephyrglxext.h" 39706f2543Smrg#endif /* XF86DRI */ 40706f2543Smrg 41706f2543Smrg#include "xkbsrv.h" 42706f2543Smrg 43706f2543Smrgextern int KdTsPhyScreen; 44706f2543Smrg#ifdef GLXEXT 45706f2543Smrgextern Bool noGlxVisualInit; 46706f2543Smrg#endif 47706f2543Smrg 48706f2543SmrgKdKeyboardInfo *ephyrKbd; 49706f2543SmrgKdPointerInfo *ephyrMouse; 50706f2543SmrgEphyrKeySyms ephyrKeySyms; 51706f2543SmrgBool ephyrNoDRI=FALSE ; 52706f2543SmrgBool ephyrNoXV=FALSE ; 53706f2543Smrg 54706f2543Smrgstatic int mouseState = 0; 55706f2543Smrg 56706f2543Smrgtypedef struct _EphyrInputPrivate { 57706f2543Smrg Bool enabled; 58706f2543Smrg} EphyrKbdPrivate, EphyrPointerPrivate; 59706f2543Smrg 60706f2543SmrgBool EphyrWantGrayScale = 0; 61706f2543Smrg 62706f2543Smrg 63706f2543SmrgBool 64706f2543SmrgephyrInitialize (KdCardInfo *card, EphyrPriv *priv) 65706f2543Smrg{ 66706f2543Smrg OsSignal(SIGUSR1, hostx_handle_signal); 67706f2543Smrg 68706f2543Smrg priv->base = 0; 69706f2543Smrg priv->bytes_per_line = 0; 70706f2543Smrg return TRUE; 71706f2543Smrg} 72706f2543Smrg 73706f2543SmrgBool 74706f2543SmrgephyrCardInit (KdCardInfo *card) 75706f2543Smrg{ 76706f2543Smrg EphyrPriv *priv; 77706f2543Smrg 78706f2543Smrg priv = (EphyrPriv *) malloc(sizeof (EphyrPriv)); 79706f2543Smrg if (!priv) 80706f2543Smrg return FALSE; 81706f2543Smrg 82706f2543Smrg if (!ephyrInitialize (card, priv)) 83706f2543Smrg { 84706f2543Smrg free(priv); 85706f2543Smrg return FALSE; 86706f2543Smrg } 87706f2543Smrg card->driver = priv; 88706f2543Smrg 89706f2543Smrg return TRUE; 90706f2543Smrg} 91706f2543Smrg 92706f2543SmrgBool 93706f2543SmrgephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv) 94706f2543Smrg{ 95706f2543Smrg int width = 640, height = 480; 96706f2543Smrg CARD32 redMask, greenMask, blueMask; 97706f2543Smrg 98706f2543Smrg if (hostx_want_screen_size(screen, &width, &height) 99706f2543Smrg || !screen->width || !screen->height) 100706f2543Smrg { 101706f2543Smrg screen->width = width; 102706f2543Smrg screen->height = height; 103706f2543Smrg } 104706f2543Smrg 105706f2543Smrg if (EphyrWantGrayScale) 106706f2543Smrg screen->fb.depth = 8; 107706f2543Smrg 108706f2543Smrg if (screen->fb.depth && screen->fb.depth != hostx_get_depth()) 109706f2543Smrg { 110706f2543Smrg if (screen->fb.depth < hostx_get_depth() 111706f2543Smrg && (screen->fb.depth == 24 || screen->fb.depth == 16 112706f2543Smrg || screen->fb.depth == 8)) 113706f2543Smrg { 114706f2543Smrg hostx_set_server_depth(screen, screen->fb.depth); 115706f2543Smrg } 116706f2543Smrg else 117706f2543Smrg ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n"); 118706f2543Smrg } 119706f2543Smrg 120706f2543Smrg screen->fb.depth = hostx_get_server_depth(screen); 121706f2543Smrg screen->rate = 72; 122706f2543Smrg 123706f2543Smrg if (screen->fb.depth <= 8) 124706f2543Smrg { 125706f2543Smrg if (EphyrWantGrayScale) 126706f2543Smrg screen->fb.visuals = ((1 << StaticGray) | (1 << GrayScale)); 127706f2543Smrg else 128706f2543Smrg screen->fb.visuals = ((1 << StaticGray) | 129706f2543Smrg (1 << GrayScale) | 130706f2543Smrg (1 << StaticColor) | 131706f2543Smrg (1 << PseudoColor) | 132706f2543Smrg (1 << TrueColor) | 133706f2543Smrg (1 << DirectColor)); 134706f2543Smrg 135706f2543Smrg screen->fb.redMask = 0x00; 136706f2543Smrg screen->fb.greenMask = 0x00; 137706f2543Smrg screen->fb.blueMask = 0x00; 138706f2543Smrg screen->fb.depth = 8; 139706f2543Smrg screen->fb.bitsPerPixel = 8; 140706f2543Smrg } 141706f2543Smrg else 142706f2543Smrg { 143706f2543Smrg screen->fb.visuals = (1 << TrueColor); 144706f2543Smrg 145706f2543Smrg if (screen->fb.depth <= 15) 146706f2543Smrg { 147706f2543Smrg screen->fb.depth = 15; 148706f2543Smrg screen->fb.bitsPerPixel = 16; 149706f2543Smrg } 150706f2543Smrg else if (screen->fb.depth <= 16) 151706f2543Smrg { 152706f2543Smrg screen->fb.depth = 16; 153706f2543Smrg screen->fb.bitsPerPixel = 16; 154706f2543Smrg } 155706f2543Smrg else if (screen->fb.depth <= 24) 156706f2543Smrg { 157706f2543Smrg screen->fb.depth = 24; 158706f2543Smrg screen->fb.bitsPerPixel = 32; 159706f2543Smrg } 160706f2543Smrg else if (screen->fb.depth <= 30) 161706f2543Smrg { 162706f2543Smrg screen->fb.depth = 30; 163706f2543Smrg screen->fb.bitsPerPixel = 32; 164706f2543Smrg } 165706f2543Smrg else 166706f2543Smrg { 167706f2543Smrg ErrorF("\nXephyr: Unsupported screen depth %d\n", 168706f2543Smrg screen->fb.depth); 169706f2543Smrg return FALSE; 170706f2543Smrg } 171706f2543Smrg 172706f2543Smrg hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask); 173706f2543Smrg 174706f2543Smrg screen->fb.redMask = (Pixel) redMask; 175706f2543Smrg screen->fb.greenMask = (Pixel) greenMask; 176706f2543Smrg screen->fb.blueMask = (Pixel) blueMask; 177706f2543Smrg 178706f2543Smrg } 179706f2543Smrg 180706f2543Smrg scrpriv->randr = screen->randr; 181706f2543Smrg 182706f2543Smrg return ephyrMapFramebuffer (screen); 183706f2543Smrg} 184706f2543Smrg 185706f2543SmrgBool 186706f2543SmrgephyrScreenInit (KdScreenInfo *screen) 187706f2543Smrg{ 188706f2543Smrg EphyrScrPriv *scrpriv; 189706f2543Smrg 190706f2543Smrg scrpriv = calloc(1, sizeof (EphyrScrPriv)); 191706f2543Smrg 192706f2543Smrg if (!scrpriv) 193706f2543Smrg return FALSE; 194706f2543Smrg 195706f2543Smrg screen->driver = scrpriv; 196706f2543Smrg 197706f2543Smrg if (!ephyrScreenInitialize (screen, scrpriv)) 198706f2543Smrg { 199706f2543Smrg screen->driver = 0; 200706f2543Smrg free(scrpriv); 201706f2543Smrg return FALSE; 202706f2543Smrg } 203706f2543Smrg 204706f2543Smrg return TRUE; 205706f2543Smrg} 206706f2543Smrg 207706f2543Smrgvoid* 208706f2543SmrgephyrWindowLinear (ScreenPtr pScreen, 209706f2543Smrg CARD32 row, 210706f2543Smrg CARD32 offset, 211706f2543Smrg int mode, 212706f2543Smrg CARD32 *size, 213706f2543Smrg void *closure) 214706f2543Smrg{ 215706f2543Smrg KdScreenPriv(pScreen); 216706f2543Smrg EphyrPriv *priv = pScreenPriv->card->driver; 217706f2543Smrg 218706f2543Smrg if (!pScreenPriv->enabled) 219706f2543Smrg return 0; 220706f2543Smrg 221706f2543Smrg *size = priv->bytes_per_line; 222706f2543Smrg return priv->base + row * priv->bytes_per_line + offset; 223706f2543Smrg} 224706f2543Smrg 225706f2543Smrg/** 226706f2543Smrg * Figure out display buffer size. If fakexa is enabled, allocate a larger 227706f2543Smrg * buffer so that fakexa has space to put offscreen pixmaps. 228706f2543Smrg */ 229706f2543Smrgint 230706f2543SmrgephyrBufferHeight(KdScreenInfo *screen) 231706f2543Smrg{ 232706f2543Smrg int buffer_height; 233706f2543Smrg if (ephyrFuncs.initAccel == NULL) 234706f2543Smrg buffer_height = screen->height; 235706f2543Smrg else 236706f2543Smrg buffer_height = 3 * screen->height; 237706f2543Smrg return buffer_height; 238706f2543Smrg} 239706f2543Smrg 240706f2543Smrg 241706f2543SmrgBool 242706f2543SmrgephyrMapFramebuffer (KdScreenInfo *screen) 243706f2543Smrg{ 244706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 245706f2543Smrg EphyrPriv *priv = screen->card->driver; 246706f2543Smrg KdPointerMatrix m; 247706f2543Smrg int buffer_height; 248706f2543Smrg 249706f2543Smrg EPHYR_LOG("screen->width: %d, screen->height: %d index=%d", 250706f2543Smrg screen->width, screen->height, screen->mynum); 251706f2543Smrg 252706f2543Smrg KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height); 253706f2543Smrg KdSetPointerMatrix (&m); 254706f2543Smrg 255706f2543Smrg priv->bytes_per_line = ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2; 256706f2543Smrg 257706f2543Smrg buffer_height = ephyrBufferHeight(screen); 258706f2543Smrg 259706f2543Smrg priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height); 260706f2543Smrg 261706f2543Smrg if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All)) 262706f2543Smrg { 263706f2543Smrg scrpriv->shadow = FALSE; 264706f2543Smrg 265706f2543Smrg screen->fb.byteStride = priv->bytes_per_line; 266706f2543Smrg screen->fb.pixelStride = screen->width; 267706f2543Smrg screen->fb.frameBuffer = (CARD8 *) (priv->base); 268706f2543Smrg } 269706f2543Smrg else 270706f2543Smrg { 271706f2543Smrg /* Rotated/Reflected so we need to use shadow fb */ 272706f2543Smrg scrpriv->shadow = TRUE; 273706f2543Smrg 274706f2543Smrg EPHYR_LOG("allocing shadow"); 275706f2543Smrg 276706f2543Smrg KdShadowFbAlloc (screen, 277706f2543Smrg scrpriv->randr & (RR_Rotate_90|RR_Rotate_270)); 278706f2543Smrg } 279706f2543Smrg 280706f2543Smrg return TRUE; 281706f2543Smrg} 282706f2543Smrg 283706f2543Smrgvoid 284706f2543SmrgephyrSetScreenSizes (ScreenPtr pScreen) 285706f2543Smrg{ 286706f2543Smrg KdScreenPriv(pScreen); 287706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 288706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 289706f2543Smrg 290706f2543Smrg if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180)) 291706f2543Smrg { 292706f2543Smrg pScreen->width = screen->width; 293706f2543Smrg pScreen->height = screen->height; 294706f2543Smrg pScreen->mmWidth = screen->width_mm; 295706f2543Smrg pScreen->mmHeight = screen->height_mm; 296706f2543Smrg } 297706f2543Smrg else 298706f2543Smrg { 299706f2543Smrg pScreen->width = screen->height; 300706f2543Smrg pScreen->height = screen->width; 301706f2543Smrg pScreen->mmWidth = screen->height_mm; 302706f2543Smrg pScreen->mmHeight = screen->width_mm; 303706f2543Smrg } 304706f2543Smrg} 305706f2543Smrg 306706f2543SmrgBool 307706f2543SmrgephyrUnmapFramebuffer (KdScreenInfo *screen) 308706f2543Smrg{ 309706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 310706f2543Smrg 311706f2543Smrg if (scrpriv->shadow) 312706f2543Smrg KdShadowFbFree (screen); 313706f2543Smrg 314706f2543Smrg /* Note, priv->base will get freed when XImage recreated */ 315706f2543Smrg 316706f2543Smrg return TRUE; 317706f2543Smrg} 318706f2543Smrg 319706f2543Smrgvoid 320706f2543SmrgephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) 321706f2543Smrg{ 322706f2543Smrg KdScreenPriv(pScreen); 323706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 324706f2543Smrg 325706f2543Smrg EPHYR_LOG("slow paint"); 326706f2543Smrg 327706f2543Smrg /* FIXME: Slow Rotated/Reflected updates could be much 328706f2543Smrg * much faster efficiently updating via tranforming 329706f2543Smrg * pBuf->pDamage regions 330706f2543Smrg */ 331706f2543Smrg shadowUpdateRotatePacked(pScreen, pBuf); 332706f2543Smrg hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height); 333706f2543Smrg} 334706f2543Smrg 335706f2543Smrgstatic void 336706f2543SmrgephyrInternalDamageRedisplay (ScreenPtr pScreen) 337706f2543Smrg{ 338706f2543Smrg KdScreenPriv(pScreen); 339706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 340706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 341706f2543Smrg RegionPtr pRegion; 342706f2543Smrg 343706f2543Smrg if (!scrpriv || !scrpriv->pDamage) 344706f2543Smrg return; 345706f2543Smrg 346706f2543Smrg pRegion = DamageRegion (scrpriv->pDamage); 347706f2543Smrg 348706f2543Smrg if (RegionNotEmpty(pRegion)) 349706f2543Smrg { 350706f2543Smrg int nbox; 351706f2543Smrg BoxPtr pbox; 352706f2543Smrg 353706f2543Smrg nbox = RegionNumRects (pRegion); 354706f2543Smrg pbox = RegionRects (pRegion); 355706f2543Smrg 356706f2543Smrg while (nbox--) 357706f2543Smrg { 358706f2543Smrg hostx_paint_rect(screen, 359706f2543Smrg pbox->x1, pbox->y1, 360706f2543Smrg pbox->x1, pbox->y1, 361706f2543Smrg pbox->x2 - pbox->x1, 362706f2543Smrg pbox->y2 - pbox->y1); 363706f2543Smrg pbox++; 364706f2543Smrg } 365706f2543Smrg DamageEmpty (scrpriv->pDamage); 366706f2543Smrg } 367706f2543Smrg} 368706f2543Smrg 369706f2543Smrgstatic void 370706f2543SmrgephyrInternalDamageBlockHandler (pointer data, 371706f2543Smrg OSTimePtr pTimeout, 372706f2543Smrg pointer pRead) 373706f2543Smrg{ 374706f2543Smrg ScreenPtr pScreen = (ScreenPtr) data; 375706f2543Smrg 376706f2543Smrg ephyrInternalDamageRedisplay (pScreen); 377706f2543Smrg} 378706f2543Smrg 379706f2543Smrgstatic void 380706f2543SmrgephyrInternalDamageWakeupHandler (pointer data, int i, pointer LastSelectMask) 381706f2543Smrg{ 382706f2543Smrg /* FIXME: Not needed ? */ 383706f2543Smrg} 384706f2543Smrg 385706f2543SmrgBool 386706f2543SmrgephyrSetInternalDamage (ScreenPtr pScreen) 387706f2543Smrg{ 388706f2543Smrg KdScreenPriv(pScreen); 389706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 390706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 391706f2543Smrg PixmapPtr pPixmap = NULL; 392706f2543Smrg 393706f2543Smrg scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0, 394706f2543Smrg (DamageDestroyFunc) 0, 395706f2543Smrg DamageReportNone, 396706f2543Smrg TRUE, 397706f2543Smrg pScreen, 398706f2543Smrg pScreen); 399706f2543Smrg 400706f2543Smrg if (!RegisterBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler, 401706f2543Smrg ephyrInternalDamageWakeupHandler, 402706f2543Smrg (pointer) pScreen)) 403706f2543Smrg return FALSE; 404706f2543Smrg 405706f2543Smrg pPixmap = (*pScreen->GetScreenPixmap) (pScreen); 406706f2543Smrg 407706f2543Smrg DamageRegister (&pPixmap->drawable, scrpriv->pDamage); 408706f2543Smrg 409706f2543Smrg return TRUE; 410706f2543Smrg} 411706f2543Smrg 412706f2543Smrgvoid 413706f2543SmrgephyrUnsetInternalDamage (ScreenPtr pScreen) 414706f2543Smrg{ 415706f2543Smrg KdScreenPriv(pScreen); 416706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 417706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 418706f2543Smrg PixmapPtr pPixmap = NULL; 419706f2543Smrg 420706f2543Smrg pPixmap = (*pScreen->GetScreenPixmap) (pScreen); 421706f2543Smrg DamageUnregister (&pPixmap->drawable, scrpriv->pDamage); 422706f2543Smrg DamageDestroy (scrpriv->pDamage); 423706f2543Smrg 424706f2543Smrg RemoveBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler, 425706f2543Smrg ephyrInternalDamageWakeupHandler, 426706f2543Smrg (pointer) pScreen); 427706f2543Smrg} 428706f2543Smrg 429706f2543Smrg#ifdef RANDR 430706f2543SmrgBool 431706f2543SmrgephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) 432706f2543Smrg{ 433706f2543Smrg KdScreenPriv(pScreen); 434706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 435706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 436706f2543Smrg RRScreenSizePtr pSize; 437706f2543Smrg Rotation randr; 438706f2543Smrg int n = 0; 439706f2543Smrg 440706f2543Smrg struct { int width, height; } sizes[] = 441706f2543Smrg { 442706f2543Smrg { 1600, 1200 }, 443706f2543Smrg { 1400, 1050 }, 444706f2543Smrg { 1280, 960 }, 445706f2543Smrg { 1280, 1024 }, 446706f2543Smrg { 1152, 864 }, 447706f2543Smrg { 1024, 768 }, 448706f2543Smrg { 832, 624 }, 449706f2543Smrg { 800, 600 }, 450706f2543Smrg { 720, 400 }, 451706f2543Smrg { 480, 640 }, 452706f2543Smrg { 640, 480 }, 453706f2543Smrg { 640, 400 }, 454706f2543Smrg { 320, 240 }, 455706f2543Smrg { 240, 320 }, 456706f2543Smrg { 160, 160 }, 457706f2543Smrg { 0, 0 } 458706f2543Smrg }; 459706f2543Smrg 460706f2543Smrg EPHYR_LOG("mark"); 461706f2543Smrg 462706f2543Smrg *rotations = RR_Rotate_All|RR_Reflect_All; 463706f2543Smrg 464706f2543Smrg if (!hostx_want_preexisting_window (screen) 465706f2543Smrg && !hostx_want_fullscreen ()) /* only if no -parent switch */ 466706f2543Smrg { 467706f2543Smrg while (sizes[n].width != 0 && sizes[n].height != 0) 468706f2543Smrg { 469706f2543Smrg RRRegisterSize (pScreen, 470706f2543Smrg sizes[n].width, 471706f2543Smrg sizes[n].height, 472706f2543Smrg (sizes[n].width * screen->width_mm)/screen->width, 473706f2543Smrg (sizes[n].height *screen->height_mm)/screen->height 474706f2543Smrg ); 475706f2543Smrg n++; 476706f2543Smrg } 477706f2543Smrg } 478706f2543Smrg 479706f2543Smrg pSize = RRRegisterSize (pScreen, 480706f2543Smrg screen->width, 481706f2543Smrg screen->height, 482706f2543Smrg screen->width_mm, 483706f2543Smrg screen->height_mm); 484706f2543Smrg 485706f2543Smrg randr = KdSubRotation (scrpriv->randr, screen->randr); 486706f2543Smrg 487706f2543Smrg RRSetCurrentConfig (pScreen, randr, 0, pSize); 488706f2543Smrg 489706f2543Smrg return TRUE; 490706f2543Smrg} 491706f2543Smrg 492706f2543SmrgBool 493706f2543SmrgephyrRandRSetConfig (ScreenPtr pScreen, 494706f2543Smrg Rotation randr, 495706f2543Smrg int rate, 496706f2543Smrg RRScreenSizePtr pSize) 497706f2543Smrg{ 498706f2543Smrg KdScreenPriv(pScreen); 499706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 500706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 501706f2543Smrg Bool wasEnabled = pScreenPriv->enabled; 502706f2543Smrg EphyrScrPriv oldscr; 503706f2543Smrg int oldwidth, oldheight, oldmmwidth, oldmmheight; 504706f2543Smrg Bool oldshadow; 505706f2543Smrg int newwidth, newheight; 506706f2543Smrg 507706f2543Smrg if (screen->randr & (RR_Rotate_0|RR_Rotate_180)) 508706f2543Smrg { 509706f2543Smrg newwidth = pSize->width; 510706f2543Smrg newheight = pSize->height; 511706f2543Smrg } 512706f2543Smrg else 513706f2543Smrg { 514706f2543Smrg newwidth = pSize->height; 515706f2543Smrg newheight = pSize->width; 516706f2543Smrg } 517706f2543Smrg 518706f2543Smrg if (wasEnabled) 519706f2543Smrg KdDisableScreen (pScreen); 520706f2543Smrg 521706f2543Smrg oldscr = *scrpriv; 522706f2543Smrg 523706f2543Smrg oldwidth = screen->width; 524706f2543Smrg oldheight = screen->height; 525706f2543Smrg oldmmwidth = pScreen->mmWidth; 526706f2543Smrg oldmmheight = pScreen->mmHeight; 527706f2543Smrg oldshadow = scrpriv->shadow; 528706f2543Smrg 529706f2543Smrg /* 530706f2543Smrg * Set new configuration 531706f2543Smrg */ 532706f2543Smrg 533706f2543Smrg scrpriv->randr = KdAddRotation (screen->randr, randr); 534706f2543Smrg 535706f2543Smrg ephyrUnmapFramebuffer (screen); 536706f2543Smrg 537706f2543Smrg screen->width = newwidth; 538706f2543Smrg screen->height = newheight; 539706f2543Smrg 540706f2543Smrg if (!ephyrMapFramebuffer (screen)) 541706f2543Smrg goto bail4; 542706f2543Smrg 543706f2543Smrg /* FIXME below should go in own call */ 544706f2543Smrg 545706f2543Smrg if (oldshadow) 546706f2543Smrg KdShadowUnset (screen->pScreen); 547706f2543Smrg else 548706f2543Smrg ephyrUnsetInternalDamage(screen->pScreen); 549706f2543Smrg 550706f2543Smrg if (scrpriv->shadow) 551706f2543Smrg { 552706f2543Smrg if (!KdShadowSet (screen->pScreen, 553706f2543Smrg scrpriv->randr, 554706f2543Smrg ephyrShadowUpdate, 555706f2543Smrg ephyrWindowLinear)) 556706f2543Smrg goto bail4; 557706f2543Smrg } 558706f2543Smrg else 559706f2543Smrg { 560706f2543Smrg /* Without shadow fb ( non rotated ) we need 561706f2543Smrg * to use damage to efficiently update display 562706f2543Smrg * via signal regions what to copy from 'fb'. 563706f2543Smrg */ 564706f2543Smrg if (!ephyrSetInternalDamage(screen->pScreen)) 565706f2543Smrg goto bail4; 566706f2543Smrg } 567706f2543Smrg 568706f2543Smrg ephyrSetScreenSizes (screen->pScreen); 569706f2543Smrg 570706f2543Smrg /* 571706f2543Smrg * Set frame buffer mapping 572706f2543Smrg */ 573706f2543Smrg (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen), 574706f2543Smrg pScreen->width, 575706f2543Smrg pScreen->height, 576706f2543Smrg screen->fb.depth, 577706f2543Smrg screen->fb.bitsPerPixel, 578706f2543Smrg screen->fb.byteStride, 579706f2543Smrg screen->fb.frameBuffer); 580706f2543Smrg 581706f2543Smrg /* set the subpixel order */ 582706f2543Smrg 583706f2543Smrg KdSetSubpixelOrder (pScreen, scrpriv->randr); 584706f2543Smrg 585706f2543Smrg if (wasEnabled) 586706f2543Smrg KdEnableScreen (pScreen); 587706f2543Smrg 588706f2543Smrg return TRUE; 589706f2543Smrg 590706f2543Smrg bail4: 591706f2543Smrg EPHYR_LOG("bailed"); 592706f2543Smrg 593706f2543Smrg ephyrUnmapFramebuffer (screen); 594706f2543Smrg *scrpriv = oldscr; 595706f2543Smrg (void) ephyrMapFramebuffer (screen); 596706f2543Smrg 597706f2543Smrg pScreen->width = oldwidth; 598706f2543Smrg pScreen->height = oldheight; 599706f2543Smrg pScreen->mmWidth = oldmmwidth; 600706f2543Smrg pScreen->mmHeight = oldmmheight; 601706f2543Smrg 602706f2543Smrg if (wasEnabled) 603706f2543Smrg KdEnableScreen (pScreen); 604706f2543Smrg return FALSE; 605706f2543Smrg} 606706f2543Smrg 607706f2543SmrgBool 608706f2543SmrgephyrRandRInit (ScreenPtr pScreen) 609706f2543Smrg{ 610706f2543Smrg rrScrPrivPtr pScrPriv; 611706f2543Smrg 612706f2543Smrg if (!RRScreenInit (pScreen)) 613706f2543Smrg return FALSE; 614706f2543Smrg 615706f2543Smrg pScrPriv = rrGetScrPriv(pScreen); 616706f2543Smrg pScrPriv->rrGetInfo = ephyrRandRGetInfo; 617706f2543Smrg pScrPriv->rrSetConfig = ephyrRandRSetConfig; 618706f2543Smrg return TRUE; 619706f2543Smrg} 620706f2543Smrg#endif 621706f2543Smrg 622706f2543SmrgBool 623706f2543SmrgephyrCreateColormap (ColormapPtr pmap) 624706f2543Smrg{ 625706f2543Smrg return fbInitializeColormap (pmap); 626706f2543Smrg} 627706f2543Smrg 628706f2543SmrgBool 629706f2543SmrgephyrInitScreen (ScreenPtr pScreen) 630706f2543Smrg{ 631706f2543Smrg KdScreenPriv(pScreen); 632706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 633706f2543Smrg 634706f2543Smrg EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ; 635706f2543Smrg hostx_set_screen_number (screen, pScreen->myNum); 636706f2543Smrg hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ; 637706f2543Smrg pScreen->CreateColormap = ephyrCreateColormap; 638706f2543Smrg 639706f2543Smrg#ifdef XV 640706f2543Smrg if (!ephyrNoXV) { 641706f2543Smrg if (!ephyrInitVideo (pScreen)) { 642706f2543Smrg EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ; 643706f2543Smrg } else { 644706f2543Smrg EPHYR_LOG ("initialized xvideo okay\n") ; 645706f2543Smrg } 646706f2543Smrg } 647706f2543Smrg#endif /*XV*/ 648706f2543Smrg 649706f2543Smrg#ifdef XF86DRI 650706f2543Smrg if (!ephyrNoDRI && !hostx_has_dri ()) { 651706f2543Smrg EPHYR_LOG ("host x does not support DRI. Disabling DRI forwarding\n") ; 652706f2543Smrg ephyrNoDRI = TRUE ; 653706f2543Smrg#ifdef GLXEXT 654706f2543Smrg noGlxVisualInit = FALSE ; 655706f2543Smrg#endif 656706f2543Smrg } 657706f2543Smrg if (!ephyrNoDRI) { 658706f2543Smrg ephyrDRIExtensionInit (pScreen) ; 659706f2543Smrg ephyrHijackGLXExtension () ; 660706f2543Smrg } 661706f2543Smrg#endif 662706f2543Smrg 663706f2543Smrg#ifdef GLXEXT 664706f2543Smrg if (ephyrNoDRI) { 665706f2543Smrg noGlxVisualInit = FALSE ; 666706f2543Smrg } 667706f2543Smrg#endif 668706f2543Smrg 669706f2543Smrg return TRUE; 670706f2543Smrg} 671706f2543Smrg 672706f2543SmrgBool 673706f2543SmrgephyrFinishInitScreen (ScreenPtr pScreen) 674706f2543Smrg{ 675706f2543Smrg /* FIXME: Calling this even if not using shadow. 676706f2543Smrg * Seems harmless enough. But may be safer elsewhere. 677706f2543Smrg */ 678706f2543Smrg if (!shadowSetup (pScreen)) 679706f2543Smrg return FALSE; 680706f2543Smrg 681706f2543Smrg#ifdef RANDR 682706f2543Smrg if (!ephyrRandRInit (pScreen)) 683706f2543Smrg return FALSE; 684706f2543Smrg#endif 685706f2543Smrg 686706f2543Smrg return TRUE; 687706f2543Smrg} 688706f2543Smrg 689706f2543SmrgBool 690706f2543SmrgephyrCreateResources (ScreenPtr pScreen) 691706f2543Smrg{ 692706f2543Smrg KdScreenPriv(pScreen); 693706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 694706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 695706f2543Smrg 696706f2543Smrg EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d", 697706f2543Smrg pScreen, pScreen->myNum, scrpriv->shadow); 698706f2543Smrg 699706f2543Smrg if (scrpriv->shadow) 700706f2543Smrg return KdShadowSet (pScreen, 701706f2543Smrg scrpriv->randr, 702706f2543Smrg ephyrShadowUpdate, 703706f2543Smrg ephyrWindowLinear); 704706f2543Smrg else 705706f2543Smrg return ephyrSetInternalDamage(pScreen); 706706f2543Smrg} 707706f2543Smrg 708706f2543Smrgvoid 709706f2543SmrgephyrPreserve (KdCardInfo *card) 710706f2543Smrg{ 711706f2543Smrg} 712706f2543Smrg 713706f2543SmrgBool 714706f2543SmrgephyrEnable (ScreenPtr pScreen) 715706f2543Smrg{ 716706f2543Smrg return TRUE; 717706f2543Smrg} 718706f2543Smrg 719706f2543SmrgBool 720706f2543SmrgephyrDPMS (ScreenPtr pScreen, int mode) 721706f2543Smrg{ 722706f2543Smrg return TRUE; 723706f2543Smrg} 724706f2543Smrg 725706f2543Smrgvoid 726706f2543SmrgephyrDisable (ScreenPtr pScreen) 727706f2543Smrg{ 728706f2543Smrg} 729706f2543Smrg 730706f2543Smrgvoid 731706f2543SmrgephyrRestore (KdCardInfo *card) 732706f2543Smrg{ 733706f2543Smrg} 734706f2543Smrg 735706f2543Smrgvoid 736706f2543SmrgephyrScreenFini (KdScreenInfo *screen) 737706f2543Smrg{ 738706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 739706f2543Smrg if (scrpriv->shadow) { 740706f2543Smrg KdShadowFbFree (screen); 741706f2543Smrg } 742706f2543Smrg free(screen->driver); 743706f2543Smrg screen->driver = NULL; 744706f2543Smrg} 745706f2543Smrg 746706f2543Smrg/* 747706f2543Smrg * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug. 748706f2543Smrg * See https://bugs.freedesktop.org/show_bug.cgi?id=3030 749706f2543Smrg */ 750706f2543Smrgvoid 751706f2543SmrgephyrUpdateModifierState(unsigned int state) 752706f2543Smrg{ 753706f2543Smrg 754706f2543Smrg DeviceIntPtr pDev = inputInfo.keyboard; 755706f2543Smrg KeyClassPtr keyc = pDev->key; 756706f2543Smrg int i; 757706f2543Smrg CARD8 mask; 758706f2543Smrg int xkb_state; 759706f2543Smrg 760706f2543Smrg if (!pDev) 761706f2543Smrg return; 762706f2543Smrg 763706f2543Smrg xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); 764706f2543Smrg state = state & 0xff; 765706f2543Smrg 766706f2543Smrg if (xkb_state == state) 767706f2543Smrg return; 768706f2543Smrg 769706f2543Smrg for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { 770706f2543Smrg int key; 771706f2543Smrg 772706f2543Smrg /* Modifier is down, but shouldn't be 773706f2543Smrg */ 774706f2543Smrg if ((xkb_state & mask) && !(state & mask)) { 775706f2543Smrg int count = keyc->modifierKeyCount[i]; 776706f2543Smrg 777706f2543Smrg for (key = 0; key < MAP_LENGTH; key++) 778706f2543Smrg if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 779706f2543Smrg if (key_is_down(pDev, key, KEY_PROCESSED)) 780706f2543Smrg KdEnqueueKeyboardEvent (ephyrKbd, key, TRUE); 781706f2543Smrg 782706f2543Smrg if (--count == 0) 783706f2543Smrg break; 784706f2543Smrg } 785706f2543Smrg } 786706f2543Smrg 787706f2543Smrg /* Modifier shoud be down, but isn't 788706f2543Smrg */ 789706f2543Smrg if (!(xkb_state & mask) && (state & mask)) 790706f2543Smrg for (key = 0; key < MAP_LENGTH; key++) 791706f2543Smrg if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 792706f2543Smrg KdEnqueueKeyboardEvent (ephyrKbd, key, FALSE); 793706f2543Smrg break; 794706f2543Smrg } 795706f2543Smrg } 796706f2543Smrg} 797706f2543Smrg 798706f2543Smrgstatic void 799706f2543SmrgephyrBlockSigio (void) 800706f2543Smrg{ 801706f2543Smrg sigset_t set; 802706f2543Smrg 803706f2543Smrg sigemptyset (&set); 804706f2543Smrg sigaddset (&set, SIGIO); 805706f2543Smrg sigprocmask (SIG_BLOCK, &set, 0); 806706f2543Smrg} 807706f2543Smrg 808706f2543Smrgstatic void 809706f2543SmrgephyrUnblockSigio (void) 810706f2543Smrg{ 811706f2543Smrg sigset_t set; 812706f2543Smrg 813706f2543Smrg sigemptyset (&set); 814706f2543Smrg sigaddset (&set, SIGIO); 815706f2543Smrg sigprocmask (SIG_UNBLOCK, &set, 0); 816706f2543Smrg} 817706f2543Smrg 818706f2543Smrgstatic Bool 819706f2543SmrgephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) 820706f2543Smrg{ 821706f2543Smrg return FALSE; 822706f2543Smrg} 823706f2543Smrg 824706f2543Smrgstatic void 825706f2543SmrgephyrCrossScreen (ScreenPtr pScreen, Bool entering) 826706f2543Smrg{ 827706f2543Smrg} 828706f2543Smrg 829706f2543Smrgint ephyrCurScreen; /*current event screen*/ 830706f2543Smrg 831706f2543Smrgstatic void 832706f2543SmrgephyrWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 833706f2543Smrg{ 834706f2543Smrg ephyrBlockSigio (); 835706f2543Smrg ephyrCurScreen = pScreen->myNum; 836706f2543Smrg miPointerWarpCursor (inputInfo.pointer, pScreen, x, y); 837706f2543Smrg ephyrUnblockSigio (); 838706f2543Smrg} 839706f2543Smrg 840706f2543SmrgmiPointerScreenFuncRec ephyrPointerScreenFuncs = 841706f2543Smrg{ 842706f2543Smrg ephyrCursorOffScreen, 843706f2543Smrg ephyrCrossScreen, 844706f2543Smrg ephyrWarpCursor, 845706f2543Smrg NULL, 846706f2543Smrg NULL 847706f2543Smrg}; 848706f2543Smrg 849706f2543Smrg#ifdef XF86DRI 850706f2543Smrg/** 851706f2543Smrg * find if the remote window denoted by a_remote 852706f2543Smrg * is paired with an internal Window within the Xephyr server. 853706f2543Smrg * If the remove window is paired with an internal window, send an 854706f2543Smrg * expose event to the client insterested in the internal window expose event. 855706f2543Smrg * 856706f2543Smrg * Pairing happens when a drawable inside Xephyr is associated with 857706f2543Smrg * a GL surface in a DRI environment. 858706f2543Smrg * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to 859706f2543Smrg * know a paired window is created. 860706f2543Smrg * 861706f2543Smrg * This is useful to make GL drawables (only windows for now) handle 862706f2543Smrg * expose events and send those events to clients. 863706f2543Smrg */ 864706f2543Smrgstatic void 865706f2543SmrgephyrExposePairedWindow (int a_remote) 866706f2543Smrg{ 867706f2543Smrg EphyrWindowPair *pair = NULL; 868706f2543Smrg RegionRec reg; 869706f2543Smrg ScreenPtr screen; 870706f2543Smrg 871706f2543Smrg if (!findWindowPairFromRemote (a_remote, &pair)) { 872706f2543Smrg EPHYR_LOG ("did not find a pair for this window\n"); 873706f2543Smrg return; 874706f2543Smrg } 875706f2543Smrg screen = pair->local->drawable.pScreen; 876706f2543Smrg RegionNull(®); 877706f2543Smrg RegionCopy(®, &pair->local->clipList); 878706f2543Smrg screen->WindowExposures (pair->local, ®, NullRegion); 879706f2543Smrg RegionUninit(®); 880706f2543Smrg} 881706f2543Smrg#endif /* XF86DRI */ 882706f2543Smrg 883706f2543Smrgvoid 884706f2543SmrgephyrPoll(void) 885706f2543Smrg{ 886706f2543Smrg EphyrHostXEvent ev; 887706f2543Smrg 888706f2543Smrg while (hostx_get_event(&ev)) 889706f2543Smrg { 890706f2543Smrg switch (ev.type) 891706f2543Smrg { 892706f2543Smrg case EPHYR_EV_MOUSE_MOTION: 893706f2543Smrg if (!ephyrMouse || 894706f2543Smrg !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) { 895706f2543Smrg EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ; 896706f2543Smrg continue; 897706f2543Smrg } 898706f2543Smrg { 899706f2543Smrg if (ev.data.mouse_motion.screen >=0 900706f2543Smrg && (ephyrCurScreen != ev.data.mouse_motion.screen)) 901706f2543Smrg { 902706f2543Smrg EPHYR_LOG ("warping mouse cursor. " 903706f2543Smrg "cur_screen%d, motion_screen:%d\n", 904706f2543Smrg ephyrCurScreen, ev.data.mouse_motion.screen) ; 905706f2543Smrg if (ev.data.mouse_motion.screen >= 0) 906706f2543Smrg { 907706f2543Smrg ephyrWarpCursor 908706f2543Smrg (inputInfo.pointer, screenInfo.screens[ev.data.mouse_motion.screen], 909706f2543Smrg ev.data.mouse_motion.x, 910706f2543Smrg ev.data.mouse_motion.y ); 911706f2543Smrg } 912706f2543Smrg } 913706f2543Smrg else 914706f2543Smrg { 915706f2543Smrg int x=0, y=0; 916706f2543Smrg#ifdef XF86DRI 917706f2543Smrg EphyrWindowPair *pair = NULL; 918706f2543Smrg#endif 919706f2543Smrg EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ; 920706f2543Smrg x = ev.data.mouse_motion.x; 921706f2543Smrg y = ev.data.mouse_motion.y; 922706f2543Smrg EPHYR_LOG ("initial (x,y):(%d,%d)\n", x, y) ; 923706f2543Smrg#ifdef XF86DRI 924706f2543Smrg EPHYR_LOG ("is this window peered by a gl drawable ?\n") ; 925706f2543Smrg if (findWindowPairFromRemote (ev.data.mouse_motion.window, 926706f2543Smrg &pair)) 927706f2543Smrg { 928706f2543Smrg EPHYR_LOG ("yes, it is peered\n") ; 929706f2543Smrg x += pair->local->drawable.x; 930706f2543Smrg y += pair->local->drawable.y; 931706f2543Smrg } 932706f2543Smrg else 933706f2543Smrg { 934706f2543Smrg EPHYR_LOG ("no, it is not peered\n") ; 935706f2543Smrg } 936706f2543Smrg EPHYR_LOG ("final (x,y):(%d,%d)\n", x, y) ; 937706f2543Smrg#endif 938706f2543Smrg KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0); 939706f2543Smrg } 940706f2543Smrg } 941706f2543Smrg break; 942706f2543Smrg 943706f2543Smrg case EPHYR_EV_MOUSE_PRESS: 944706f2543Smrg if (!ephyrMouse || 945706f2543Smrg !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) { 946706f2543Smrg EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ; 947706f2543Smrg continue; 948706f2543Smrg } 949706f2543Smrg EPHYR_LOG ("enqueuing mouse press:%d\n", ephyrCurScreen) ; 950706f2543Smrg ephyrUpdateModifierState(ev.key_state); 951706f2543Smrg mouseState |= ev.data.mouse_down.button_num; 952706f2543Smrg KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0); 953706f2543Smrg break; 954706f2543Smrg 955706f2543Smrg case EPHYR_EV_MOUSE_RELEASE: 956706f2543Smrg if (!ephyrMouse || 957706f2543Smrg !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) 958706f2543Smrg continue; 959706f2543Smrg ephyrUpdateModifierState(ev.key_state); 960706f2543Smrg mouseState &= ~ev.data.mouse_up.button_num; 961706f2543Smrg EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ; 962706f2543Smrg KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0); 963706f2543Smrg break; 964706f2543Smrg 965706f2543Smrg case EPHYR_EV_KEY_PRESS: 966706f2543Smrg if (!ephyrKbd || 967706f2543Smrg !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) 968706f2543Smrg continue; 969706f2543Smrg ephyrUpdateModifierState(ev.key_state); 970706f2543Smrg KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_down.scancode, FALSE); 971706f2543Smrg break; 972706f2543Smrg 973706f2543Smrg case EPHYR_EV_KEY_RELEASE: 974706f2543Smrg if (!ephyrKbd || 975706f2543Smrg !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) 976706f2543Smrg continue; 977706f2543Smrg ephyrUpdateModifierState(ev.key_state); 978706f2543Smrg KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE); 979706f2543Smrg break; 980706f2543Smrg 981706f2543Smrg#ifdef XF86DRI 982706f2543Smrg case EPHYR_EV_EXPOSE: 983706f2543Smrg /* 984706f2543Smrg * We only receive expose events when the expose event have 985706f2543Smrg * be generated for a drawable that is a host X window managed 986706f2543Smrg * by Xephyr. Host X windows managed by Xephyr exists for instance 987706f2543Smrg * when Xephyr is asked to create a GL drawable in a DRI environment. 988706f2543Smrg */ 989706f2543Smrg ephyrExposePairedWindow (ev.data.expose.window); 990706f2543Smrg break; 991706f2543Smrg#endif /* XF86DRI */ 992706f2543Smrg 993706f2543Smrg default: 994706f2543Smrg break; 995706f2543Smrg } 996706f2543Smrg } 997706f2543Smrg} 998706f2543Smrg 999706f2543Smrgvoid 1000706f2543SmrgephyrCardFini (KdCardInfo *card) 1001706f2543Smrg{ 1002706f2543Smrg EphyrPriv *priv = card->driver; 1003706f2543Smrg free(priv); 1004706f2543Smrg} 1005706f2543Smrg 1006706f2543Smrgvoid 1007706f2543SmrgephyrGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs) 1008706f2543Smrg{ 1009706f2543Smrg /* XXX Not sure if this is right */ 1010706f2543Smrg 1011706f2543Smrg EPHYR_LOG("mark"); 1012706f2543Smrg 1013706f2543Smrg while (n--) 1014706f2543Smrg { 1015706f2543Smrg pdefs->red = 0; 1016706f2543Smrg pdefs->green = 0; 1017706f2543Smrg pdefs->blue = 0; 1018706f2543Smrg pdefs++; 1019706f2543Smrg } 1020706f2543Smrg 1021706f2543Smrg} 1022706f2543Smrg 1023706f2543Smrgvoid 1024706f2543SmrgephyrPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs) 1025706f2543Smrg{ 1026706f2543Smrg int min, max, p; 1027706f2543Smrg 1028706f2543Smrg /* XXX Not sure if this is right */ 1029706f2543Smrg 1030706f2543Smrg min = 256; 1031706f2543Smrg max = 0; 1032706f2543Smrg 1033706f2543Smrg while (n--) 1034706f2543Smrg { 1035706f2543Smrg p = pdefs->pixel; 1036706f2543Smrg if (p < min) 1037706f2543Smrg min = p; 1038706f2543Smrg if (p > max) 1039706f2543Smrg max = p; 1040706f2543Smrg 1041706f2543Smrg hostx_set_cmap_entry(p, 1042706f2543Smrg pdefs->red >> 8, 1043706f2543Smrg pdefs->green >> 8, 1044706f2543Smrg pdefs->blue >> 8); 1045706f2543Smrg pdefs++; 1046706f2543Smrg } 1047706f2543Smrg} 1048706f2543Smrg 1049706f2543Smrg/* Mouse calls */ 1050706f2543Smrg 1051706f2543Smrgstatic Status 1052706f2543SmrgMouseInit (KdPointerInfo *pi) 1053706f2543Smrg{ 1054706f2543Smrg pi->driverPrivate = (EphyrPointerPrivate *) 1055706f2543Smrg calloc(sizeof(EphyrPointerPrivate), 1); 1056706f2543Smrg ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE; 1057706f2543Smrg pi->nAxes = 3; 1058706f2543Smrg pi->nButtons = 32; 1059706f2543Smrg free(pi->name); 1060706f2543Smrg pi->name = strdup("Xephyr virtual mouse"); 1061706f2543Smrg ephyrMouse = pi; 1062706f2543Smrg return Success; 1063706f2543Smrg} 1064706f2543Smrg 1065706f2543Smrgstatic Status 1066706f2543SmrgMouseEnable (KdPointerInfo *pi) 1067706f2543Smrg{ 1068706f2543Smrg ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = TRUE; 1069706f2543Smrg return Success; 1070706f2543Smrg} 1071706f2543Smrg 1072706f2543Smrgstatic void 1073706f2543SmrgMouseDisable (KdPointerInfo *pi) 1074706f2543Smrg{ 1075706f2543Smrg ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE; 1076706f2543Smrg return; 1077706f2543Smrg} 1078706f2543Smrg 1079706f2543Smrgstatic void 1080706f2543SmrgMouseFini (KdPointerInfo *pi) 1081706f2543Smrg{ 1082706f2543Smrg ephyrMouse = NULL; 1083706f2543Smrg return; 1084706f2543Smrg} 1085706f2543Smrg 1086706f2543SmrgKdPointerDriver EphyrMouseDriver = { 1087706f2543Smrg "ephyr", 1088706f2543Smrg MouseInit, 1089706f2543Smrg MouseEnable, 1090706f2543Smrg MouseDisable, 1091706f2543Smrg MouseFini, 1092706f2543Smrg NULL, 1093706f2543Smrg}; 1094706f2543Smrg 1095706f2543Smrg/* Keyboard */ 1096706f2543Smrg 1097706f2543Smrgstatic Status 1098706f2543SmrgEphyrKeyboardInit (KdKeyboardInfo *ki) 1099706f2543Smrg{ 1100706f2543Smrg ki->driverPrivate = (EphyrKbdPrivate *) 1101706f2543Smrg calloc(sizeof(EphyrKbdPrivate), 1); 1102706f2543Smrg hostx_load_keymap(); 1103706f2543Smrg if (!ephyrKeySyms.map) { 1104706f2543Smrg ErrorF("Couldn't load keymap from host\n"); 1105706f2543Smrg return BadAlloc; 1106706f2543Smrg } 1107706f2543Smrg ki->minScanCode = ephyrKeySyms.minKeyCode; 1108706f2543Smrg ki->maxScanCode = ephyrKeySyms.maxKeyCode; 1109706f2543Smrg free(ki->name); 1110706f2543Smrg ki->name = strdup("Xephyr virtual keyboard"); 1111706f2543Smrg ephyrKbd = ki; 1112706f2543Smrg return Success; 1113706f2543Smrg} 1114706f2543Smrg 1115706f2543Smrgstatic Status 1116706f2543SmrgEphyrKeyboardEnable (KdKeyboardInfo *ki) 1117706f2543Smrg{ 1118706f2543Smrg ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = TRUE; 1119706f2543Smrg 1120706f2543Smrg return Success; 1121706f2543Smrg} 1122706f2543Smrg 1123706f2543Smrgstatic void 1124706f2543SmrgEphyrKeyboardDisable (KdKeyboardInfo *ki) 1125706f2543Smrg{ 1126706f2543Smrg ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = FALSE; 1127706f2543Smrg} 1128706f2543Smrg 1129706f2543Smrgstatic void 1130706f2543SmrgEphyrKeyboardFini (KdKeyboardInfo *ki) 1131706f2543Smrg{ 1132706f2543Smrg ephyrKbd = NULL; 1133706f2543Smrg return; 1134706f2543Smrg} 1135706f2543Smrg 1136706f2543Smrgstatic void 1137706f2543SmrgEphyrKeyboardLeds (KdKeyboardInfo *ki, int leds) 1138706f2543Smrg{ 1139706f2543Smrg} 1140706f2543Smrg 1141706f2543Smrgstatic void 1142706f2543SmrgEphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration) 1143706f2543Smrg{ 1144706f2543Smrg} 1145706f2543Smrg 1146706f2543Smrg 1147706f2543SmrgKdKeyboardDriver EphyrKeyboardDriver = { 1148706f2543Smrg "ephyr", 1149706f2543Smrg EphyrKeyboardInit, 1150706f2543Smrg EphyrKeyboardEnable, 1151706f2543Smrg EphyrKeyboardLeds, 1152706f2543Smrg EphyrKeyboardBell, 1153706f2543Smrg EphyrKeyboardDisable, 1154706f2543Smrg EphyrKeyboardFini, 1155706f2543Smrg NULL, 1156706f2543Smrg}; 1157