First import
[xorg_rtime.git] / xorg-server-1.4 / hw / kdrive / ephyr / ephyr.c
blobe8001df738606e84dbbd3599ff4a7ce0b6b58150
1 /*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2004 Nokia
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of Nokia not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. Nokia makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
17 * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
26 /* TODO:
28 * o Support multiple screens, shouldn't be hard just alot of rejigging.
31 #ifdef HAVE_CONFIG_H
32 #include <kdrive-config.h>
33 #endif
34 #include "ephyr.h"
36 #include "inputstr.h"
38 extern int KdTsPhyScreen;
39 KdKeyboardInfo *ephyrKbd;
40 KdPointerInfo *ephyrMouse;
41 EphyrKeySyms ephyrKeySyms;
43 static int mouseState = 0;
45 typedef struct _EphyrInputPrivate {
46 Bool enabled;
47 } EphyrKbdPrivate, EphyrPointerPrivate;
49 Bool EphyrWantGrayScale = 0;
51 Bool
52 ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
54 OsSignal(SIGUSR1, hostx_handle_signal);
56 priv->base = 0;
57 priv->bytes_per_line = 0;
58 return TRUE;
61 Bool
62 ephyrCardInit (KdCardInfo *card)
64 EphyrPriv *priv;
66 priv = (EphyrPriv *) xalloc (sizeof (EphyrPriv));
67 if (!priv)
68 return FALSE;
70 if (!ephyrInitialize (card, priv))
72 xfree (priv);
73 return FALSE;
75 card->driver = priv;
77 return TRUE;
80 Bool
81 ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
83 int width = 640, height = 480;
84 unsigned long redMask, greenMask, blueMask;
86 if (hostx_want_screen_size(&width, &height)
87 || !screen->width || !screen->height)
89 screen->width = width;
90 screen->height = height;
93 if (EphyrWantGrayScale)
94 screen->fb[0].depth = 8;
96 if (screen->fb[0].depth && screen->fb[0].depth != hostx_get_depth())
98 if (screen->fb[0].depth < hostx_get_depth()
99 && (screen->fb[0].depth == 24 || screen->fb[0].depth == 16
100 || screen->fb[0].depth == 8))
102 hostx_set_server_depth(screen->fb[0].depth);
104 else
105 ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n");
108 screen->fb[0].depth = hostx_get_server_depth();
109 screen->rate = 72;
111 if (screen->fb[0].depth <= 8)
113 if (EphyrWantGrayScale)
114 screen->fb[0].visuals = ((1 << StaticGray) | (1 << GrayScale));
115 else
116 screen->fb[0].visuals = ((1 << StaticGray) |
117 (1 << GrayScale) |
118 (1 << StaticColor) |
119 (1 << PseudoColor) |
120 (1 << TrueColor) |
121 (1 << DirectColor));
123 screen->fb[0].redMask = 0x00;
124 screen->fb[0].greenMask = 0x00;
125 screen->fb[0].blueMask = 0x00;
126 screen->fb[0].depth = 8;
127 screen->fb[0].bitsPerPixel = 8;
129 else
131 screen->fb[0].visuals = (1 << TrueColor);
133 if (screen->fb[0].depth <= 15)
135 screen->fb[0].depth = 15;
136 screen->fb[0].bitsPerPixel = 16;
138 else if (screen->fb[0].depth <= 16)
140 screen->fb[0].depth = 16;
141 screen->fb[0].bitsPerPixel = 16;
143 else
145 screen->fb[0].depth = 24;
146 screen->fb[0].bitsPerPixel = 32;
149 hostx_get_visual_masks (&redMask, &greenMask, &blueMask);
151 screen->fb[0].redMask = (Pixel) redMask;
152 screen->fb[0].greenMask = (Pixel) greenMask;
153 screen->fb[0].blueMask = (Pixel) blueMask;
157 scrpriv->randr = screen->randr;
159 return ephyrMapFramebuffer (screen);
162 Bool
163 ephyrScreenInit (KdScreenInfo *screen)
165 EphyrScrPriv *scrpriv;
167 scrpriv = xalloc (sizeof (EphyrScrPriv));
169 if (!scrpriv)
170 return FALSE;
172 memset (scrpriv, 0, sizeof (EphyrScrPriv));
173 screen->driver = scrpriv;
175 if (!ephyrScreenInitialize (screen, scrpriv))
177 screen->driver = 0;
178 xfree (scrpriv);
179 return FALSE;
182 return TRUE;
185 void*
186 ephyrWindowLinear (ScreenPtr pScreen,
187 CARD32 row,
188 CARD32 offset,
189 int mode,
190 CARD32 *size,
191 void *closure)
193 KdScreenPriv(pScreen);
194 EphyrPriv *priv = pScreenPriv->card->driver;
196 if (!pScreenPriv->enabled)
198 return 0;
201 *size = priv->bytes_per_line;
202 return priv->base + row * priv->bytes_per_line + offset;
205 Bool
206 ephyrMapFramebuffer (KdScreenInfo *screen)
208 EphyrScrPriv *scrpriv = screen->driver;
209 EphyrPriv *priv = screen->card->driver;
210 KdPointerMatrix m;
211 int buffer_height;
213 EPHYR_DBG(" screen->width: %d, screen->height: %d",
214 screen->width, screen->height);
216 KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
217 KdSetPointerMatrix (&m);
219 priv->bytes_per_line = ((screen->width * screen->fb[0].bitsPerPixel + 31) >> 5) << 2;
221 /* point the framebuffer to the data in an XImage */
222 /* If fakexa is enabled, allocate a larger buffer so that fakexa has space to
223 * put offscreen pixmaps.
225 if (ephyrFuncs.initAccel == NULL)
226 buffer_height = screen->height;
227 else
228 buffer_height = 3 * screen->height;
230 priv->base = hostx_screen_init (screen->width, screen->height, buffer_height);
232 screen->memory_base = (CARD8 *) (priv->base);
233 screen->memory_size = priv->bytes_per_line * buffer_height;
234 screen->off_screen_base = priv->bytes_per_line * screen->height;
236 if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All))
238 scrpriv->shadow = FALSE;
240 screen->fb[0].byteStride = priv->bytes_per_line;
241 screen->fb[0].pixelStride = screen->width;
242 screen->fb[0].frameBuffer = (CARD8 *) (priv->base);
244 else
246 /* Rotated/Reflected so we need to use shadow fb */
247 scrpriv->shadow = TRUE;
249 EPHYR_DBG("allocing shadow");
251 KdShadowFbAlloc (screen, 0,
252 scrpriv->randr & (RR_Rotate_90|RR_Rotate_270));
255 return TRUE;
258 void
259 ephyrSetScreenSizes (ScreenPtr pScreen)
261 KdScreenPriv(pScreen);
262 KdScreenInfo *screen = pScreenPriv->screen;
263 EphyrScrPriv *scrpriv = screen->driver;
265 if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
267 pScreen->width = screen->width;
268 pScreen->height = screen->height;
269 pScreen->mmWidth = screen->width_mm;
270 pScreen->mmHeight = screen->height_mm;
272 else
274 pScreen->width = screen->height;
275 pScreen->height = screen->width;
276 pScreen->mmWidth = screen->height_mm;
277 pScreen->mmHeight = screen->width_mm;
281 Bool
282 ephyrUnmapFramebuffer (KdScreenInfo *screen)
284 EphyrScrPriv *scrpriv = screen->driver;
286 if (scrpriv->shadow)
287 KdShadowFbFree (screen, 0);
289 /* Note, priv->base will get freed when XImage recreated */
291 return TRUE;
294 void
295 ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
297 KdScreenPriv(pScreen);
298 KdScreenInfo *screen = pScreenPriv->screen;
300 EPHYR_DBG("slow paint");
302 /* FIXME: Slow Rotated/Reflected updates could be much
303 * much faster efficiently updating via tranforming
304 * pBuf->pDamage regions
306 shadowUpdateRotatePacked(pScreen, pBuf);
307 hostx_paint_rect(0,0,0,0, screen->width, screen->height);
310 static void
311 ephyrInternalDamageRedisplay (ScreenPtr pScreen)
313 KdScreenPriv(pScreen);
314 KdScreenInfo *screen = pScreenPriv->screen;
315 EphyrScrPriv *scrpriv = screen->driver;
316 RegionPtr pRegion;
318 if (!scrpriv || !scrpriv->pDamage)
319 return;
321 pRegion = DamageRegion (scrpriv->pDamage);
323 if (REGION_NOTEMPTY (pScreen, pRegion))
325 int nbox;
326 BoxPtr pbox;
328 nbox = REGION_NUM_RECTS (pRegion);
329 pbox = REGION_RECTS (pRegion);
331 while (nbox--)
333 hostx_paint_rect(pbox->x1, pbox->y1,
334 pbox->x1, pbox->y1,
335 pbox->x2 - pbox->x1,
336 pbox->y2 - pbox->y1);
337 pbox++;
340 DamageEmpty (scrpriv->pDamage);
344 static void
345 ephyrInternalDamageBlockHandler (pointer data,
346 OSTimePtr pTimeout,
347 pointer pRead)
349 ScreenPtr pScreen = (ScreenPtr) data;
351 ephyrInternalDamageRedisplay (pScreen);
354 static void
355 ephyrInternalDamageWakeupHandler (pointer data, int i, pointer LastSelectMask)
357 /* FIXME: Not needed ? */
360 Bool
361 ephyrSetInternalDamage (ScreenPtr pScreen)
363 KdScreenPriv(pScreen);
364 KdScreenInfo *screen = pScreenPriv->screen;
365 EphyrScrPriv *scrpriv = screen->driver;
366 PixmapPtr pPixmap = NULL;
368 scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0,
369 (DamageDestroyFunc) 0,
370 DamageReportNone,
371 TRUE,
372 pScreen,
373 pScreen);
375 if (!RegisterBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
376 ephyrInternalDamageWakeupHandler,
377 (pointer) pScreen))
378 return FALSE;
380 pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
382 DamageRegister (&pPixmap->drawable, scrpriv->pDamage);
384 return TRUE;
387 void
388 ephyrUnsetInternalDamage (ScreenPtr pScreen)
390 KdScreenPriv(pScreen);
391 KdScreenInfo *screen = pScreenPriv->screen;
392 EphyrScrPriv *scrpriv = screen->driver;
393 PixmapPtr pPixmap = NULL;
395 pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
396 DamageUnregister (&pPixmap->drawable, scrpriv->pDamage);
398 RemoveBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
399 ephyrInternalDamageWakeupHandler,
400 (pointer) pScreen);
403 #ifdef RANDR
404 Bool
405 ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
407 KdScreenPriv(pScreen);
408 KdScreenInfo *screen = pScreenPriv->screen;
409 EphyrScrPriv *scrpriv = screen->driver;
410 RRScreenSizePtr pSize;
411 Rotation randr;
412 int n = 0;
414 EPHYR_DBG("mark");
416 struct { int width, height; } sizes[] =
418 { 1600, 1200 },
419 { 1400, 1050 },
420 { 1280, 960 },
421 { 1280, 1024 },
422 { 1152, 864 },
423 { 1024, 768 },
424 { 832, 624 },
425 { 800, 600 },
426 { 720, 400 },
427 { 480, 640 },
428 { 640, 480 },
429 { 640, 400 },
430 { 320, 240 },
431 { 240, 320 },
432 { 160, 160 },
433 { 0, 0 }
436 *rotations = RR_Rotate_All|RR_Reflect_All;
438 if (!hostx_want_preexisting_window()
439 && !hostx_want_fullscreen()) /* only if no -parent switch */
441 while (sizes[n].width != 0 && sizes[n].height != 0)
443 RRRegisterSize (pScreen,
444 sizes[n].width,
445 sizes[n].height,
446 (sizes[n].width * screen->width_mm)/screen->width,
447 (sizes[n].height *screen->height_mm)/screen->height
449 n++;
453 pSize = RRRegisterSize (pScreen,
454 screen->width,
455 screen->height,
456 screen->width_mm,
457 screen->height_mm);
459 randr = KdSubRotation (scrpriv->randr, screen->randr);
461 RRSetCurrentConfig (pScreen, randr, 0, pSize);
463 return TRUE;
466 Bool
467 ephyrRandRSetConfig (ScreenPtr pScreen,
468 Rotation randr,
469 int rate,
470 RRScreenSizePtr pSize)
472 KdScreenPriv(pScreen);
473 KdScreenInfo *screen = pScreenPriv->screen;
474 EphyrScrPriv *scrpriv = screen->driver;
475 Bool wasEnabled = pScreenPriv->enabled;
476 EphyrScrPriv oldscr;
477 int oldwidth, oldheight, oldmmwidth, oldmmheight;
478 Bool oldshadow;
479 int newwidth, newheight;
481 if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
483 newwidth = pSize->width;
484 newheight = pSize->height;
486 else
488 newwidth = pSize->height;
489 newheight = pSize->width;
492 if (wasEnabled)
493 KdDisableScreen (pScreen);
495 oldscr = *scrpriv;
497 oldwidth = screen->width;
498 oldheight = screen->height;
499 oldmmwidth = pScreen->mmWidth;
500 oldmmheight = pScreen->mmHeight;
501 oldshadow = scrpriv->shadow;
504 * Set new configuration
507 scrpriv->randr = KdAddRotation (screen->randr, randr);
509 KdOffscreenSwapOut (screen->pScreen);
511 ephyrUnmapFramebuffer (screen);
513 screen->width = newwidth;
514 screen->height = newheight;
516 if (!ephyrMapFramebuffer (screen))
517 goto bail4;
519 /* FIXME below should go in own call */
521 if (oldshadow)
522 KdShadowUnset (screen->pScreen);
523 else
524 ephyrUnsetInternalDamage(screen->pScreen);
526 if (scrpriv->shadow)
528 if (!KdShadowSet (screen->pScreen,
529 scrpriv->randr,
530 ephyrShadowUpdate,
531 ephyrWindowLinear))
532 goto bail4;
534 else
536 /* Without shadow fb ( non rotated ) we need
537 * to use damage to efficiently update display
538 * via signal regions what to copy from 'fb'.
540 if (!ephyrSetInternalDamage(screen->pScreen))
541 goto bail4;
544 ephyrSetScreenSizes (screen->pScreen);
547 * Set frame buffer mapping
549 (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
550 pScreen->width,
551 pScreen->height,
552 screen->fb[0].depth,
553 screen->fb[0].bitsPerPixel,
554 screen->fb[0].byteStride,
555 screen->fb[0].frameBuffer);
557 /* set the subpixel order */
559 KdSetSubpixelOrder (pScreen, scrpriv->randr);
561 if (wasEnabled)
562 KdEnableScreen (pScreen);
564 return TRUE;
566 bail4:
567 EPHYR_DBG("bailed");
569 ephyrUnmapFramebuffer (screen);
570 *scrpriv = oldscr;
571 (void) ephyrMapFramebuffer (screen);
573 pScreen->width = oldwidth;
574 pScreen->height = oldheight;
575 pScreen->mmWidth = oldmmwidth;
576 pScreen->mmHeight = oldmmheight;
578 if (wasEnabled)
579 KdEnableScreen (pScreen);
580 return FALSE;
583 Bool
584 ephyrRandRInit (ScreenPtr pScreen)
586 rrScrPrivPtr pScrPriv;
588 if (!RRScreenInit (pScreen))
590 return FALSE;
593 pScrPriv = rrGetScrPriv(pScreen);
594 pScrPriv->rrGetInfo = ephyrRandRGetInfo;
595 pScrPriv->rrSetConfig = ephyrRandRSetConfig;
596 return TRUE;
598 #endif
600 Bool
601 ephyrCreateColormap (ColormapPtr pmap)
603 return fbInitializeColormap (pmap);
606 Bool
607 ephyrInitScreen (ScreenPtr pScreen)
609 pScreen->CreateColormap = ephyrCreateColormap;
610 return TRUE;
613 Bool
614 ephyrFinishInitScreen (ScreenPtr pScreen)
616 /* FIXME: Calling this even if not using shadow.
617 * Seems harmless enough. But may be safer elsewhere.
619 if (!shadowSetup (pScreen))
620 return FALSE;
622 #ifdef RANDR
623 if (!ephyrRandRInit (pScreen))
624 return FALSE;
625 #endif
627 return TRUE;
630 Bool
631 ephyrCreateResources (ScreenPtr pScreen)
633 KdScreenPriv(pScreen);
634 KdScreenInfo *screen = pScreenPriv->screen;
635 EphyrScrPriv *scrpriv = screen->driver;
637 EPHYR_DBG("mark");
639 if (scrpriv->shadow)
640 return KdShadowSet (pScreen,
641 scrpriv->randr,
642 ephyrShadowUpdate,
643 ephyrWindowLinear);
644 else
645 return ephyrSetInternalDamage(pScreen);
648 void
649 ephyrPreserve (KdCardInfo *card)
653 Bool
654 ephyrEnable (ScreenPtr pScreen)
656 return TRUE;
659 Bool
660 ephyrDPMS (ScreenPtr pScreen, int mode)
662 return TRUE;
665 void
666 ephyrDisable (ScreenPtr pScreen)
670 void
671 ephyrRestore (KdCardInfo *card)
675 void
676 ephyrScreenFini (KdScreenInfo *screen)
678 xfree(screen->driver);
679 screen->driver = NULL;
683 * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug.
684 * See https://bugs.freedesktop.org/show_bug.cgi?id=3030
686 void
687 ephyrUpdateModifierState(unsigned int state)
689 DeviceIntPtr pkeydev;
690 KeyClassPtr keyc;
691 int i;
692 CARD8 mask;
694 pkeydev = (DeviceIntPtr)LookupKeyboardDevice();
696 if (!pkeydev)
697 return;
699 keyc = pkeydev->key;
701 state = state & 0xff;
703 if (keyc->state == state)
704 return;
706 for (i = 0, mask = 1; i < 8; i++, mask <<= 1)
708 int key;
710 /* Modifier is down, but shouldn't be */
711 if ((keyc->state & mask) && !(state & mask))
713 int count = keyc->modifierKeyCount[i];
715 for (key = 0; key < MAP_LENGTH; key++)
716 if (keyc->modifierMap[key] & mask)
718 int bit;
719 BYTE *kptr;
721 kptr = &keyc->down[key >> 3];
722 bit = 1 << (key & 7);
724 if (*kptr & bit && ephyrKbd &&
725 ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
726 KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */
728 if (--count == 0)
729 break;
733 /* Modifier shoud be down, but isn't */
734 if (!(keyc->state & mask) && (state & mask))
735 for (key = 0; key < MAP_LENGTH; key++)
736 if (keyc->modifierMap[key] & mask)
738 if (keyc->modifierMap[key] & mask && ephyrKbd &&
739 ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
740 KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
741 break;
746 void
747 ephyrPoll(void)
749 EphyrHostXEvent ev;
751 while (hostx_get_event(&ev))
753 switch (ev.type)
755 case EPHYR_EV_MOUSE_MOTION:
756 if (!ephyrMouse ||
757 !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
758 continue;
759 KdEnqueuePointerEvent(ephyrMouse, mouseState,
760 ev.data.mouse_motion.x,
761 ev.data.mouse_motion.y,
763 break;
765 case EPHYR_EV_MOUSE_PRESS:
766 if (!ephyrMouse ||
767 !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
768 continue;
769 ephyrUpdateModifierState(ev.key_state);
770 mouseState |= ev.data.mouse_down.button_num;
771 KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
772 break;
774 case EPHYR_EV_MOUSE_RELEASE:
775 if (!ephyrMouse ||
776 !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
777 continue;
778 ephyrUpdateModifierState(ev.key_state);
779 mouseState &= ~ev.data.mouse_up.button_num;
780 KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
781 break;
783 case EPHYR_EV_KEY_PRESS:
784 if (!ephyrKbd ||
785 !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
786 continue;
787 ephyrUpdateModifierState(ev.key_state);
788 KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_down.scancode, FALSE);
789 break;
791 case EPHYR_EV_KEY_RELEASE:
792 if (!ephyrKbd ||
793 !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
794 continue;
795 ephyrUpdateModifierState(ev.key_state);
796 KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
797 break;
799 default:
800 break;
805 void
806 ephyrCardFini (KdCardInfo *card)
808 EphyrPriv *priv = card->driver;
809 xfree (priv);
812 void
813 ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
815 /* XXX Not sure if this is right */
817 EPHYR_DBG("mark");
819 while (n--)
821 pdefs->red = 0;
822 pdefs->green = 0;
823 pdefs->blue = 0;
824 pdefs++;
829 void
830 ephyrPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
832 int min, max, p;
834 /* XXX Not sure if this is right */
836 min = 256;
837 max = 0;
839 while (n--)
841 p = pdefs->pixel;
842 if (p < min)
843 min = p;
844 if (p > max)
845 max = p;
847 hostx_set_cmap_entry(p,
848 pdefs->red >> 8,
849 pdefs->green >> 8,
850 pdefs->blue >> 8);
851 pdefs++;
855 /* Mouse calls */
857 static Status
858 MouseInit (KdPointerInfo *pi)
860 pi->driverPrivate = (EphyrPointerPrivate *)
861 xcalloc(sizeof(EphyrPointerPrivate), 1);
862 ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
863 pi->nAxes = 3;
864 pi->nButtons = 32;
865 pi->name = KdSaveString("Xephyr virtual mouse");
866 ephyrMouse = pi;
867 return Success;
870 static Status
871 MouseEnable (KdPointerInfo *pi)
873 ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = TRUE;
874 return Success;
877 static void
878 MouseDisable (KdPointerInfo *pi)
880 ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
881 return;
884 static void
885 MouseFini (KdPointerInfo *pi)
887 ephyrMouse = NULL;
888 return;
891 KdPointerDriver EphyrMouseDriver = {
892 "ephyr",
893 MouseInit,
894 MouseEnable,
895 MouseDisable,
896 MouseFini,
897 NULL,
900 /* Keyboard */
902 static Status
903 EphyrKeyboardInit (KdKeyboardInfo *ki)
905 ki->driverPrivate = (EphyrKbdPrivate *)
906 xcalloc(sizeof(EphyrKbdPrivate), 1);
907 hostx_load_keymap();
908 if (!ephyrKeySyms.map) {
909 ErrorF("Couldn't load keymap from host\n");
910 return BadAlloc;
912 ki->keySyms.minKeyCode = ephyrKeySyms.minKeyCode;
913 ki->keySyms.maxKeyCode = ephyrKeySyms.maxKeyCode;
914 ki->minScanCode = ki->keySyms.minKeyCode;
915 ki->maxScanCode = ki->keySyms.maxKeyCode;
916 ki->keySyms.mapWidth = ephyrKeySyms.mapWidth;
917 ki->keySyms.map = ephyrKeySyms.map;
918 ki->name = KdSaveString("Xephyr virtual keyboard");
919 ephyrKbd = ki;
920 return Success;
923 static Status
924 EphyrKeyboardEnable (KdKeyboardInfo *ki)
926 ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = TRUE;
928 return Success;
931 static void
932 EphyrKeyboardDisable (KdKeyboardInfo *ki)
934 ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = FALSE;
937 static void
938 EphyrKeyboardFini (KdKeyboardInfo *ki)
940 /* not xfree: we call malloc from hostx.c. */
941 free(ki->keySyms.map);
942 ephyrKbd = NULL;
943 return;
946 static void
947 EphyrKeyboardLeds (KdKeyboardInfo *ki, int leds)
951 static void
952 EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
956 KdKeyboardDriver EphyrKeyboardDriver = {
957 "ephyr",
958 EphyrKeyboardInit,
959 EphyrKeyboardEnable,
960 EphyrKeyboardLeds,
961 EphyrKeyboardBell,
962 EphyrKeyboardDisable,
963 EphyrKeyboardFini,
964 NULL,