Initial Xegl check-in. Works on EGL fbdev driver Input is totally broken.

This commit is contained in:
Jon Smirl 2005-06-04 23:33:03 +00:00
parent 88d49bed00
commit aa95967286
7 changed files with 3497 additions and 0 deletions

16
hw/xgl/egl/Makefile.am Normal file
View File

@ -0,0 +1,16 @@
INCLUDES = \
@XGL_INCS@ \
@XEGLSERVER_CFLAGS@ \
@XSERVER_CFLAGS@
bin_PROGRAMS = Xegl
Xegl_SOURCES = xegl.c xeglinput.c kinput.c evdev.c
Xegl_LDADD = \
@XGL_LIBS@ \
@XEGLSERVER_LIBS@ \
@XSERVER_LIBS@
Xegl_DEPENDENCIES = @XGL_LIBS@

643
hw/xgl/egl/evdev.c Normal file
View File

@ -0,0 +1,643 @@
/*
* $Id$
*
* Copyright © 2004 Keith Packard
*
* 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 Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD 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
#define NEED_EVENTS
#include <errno.h>
#include <linux/input.h>
#include <X11/X.h>
#include <X11/Xproto.h>
#include <X11/Xpoll.h>
#define XK_PUBLISHING
#include <X11/keysym.h>
#include "inputstr.h"
#include "kkeymap.h"
#include "scrnintstr.h"
#include "xegl.h"
#define NUM_EVENTS 128
#define ABS_UNSET -65535
#define BITS_PER_LONG (sizeof(long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y))
#define OFF(x) ((x)%BITS_PER_LONG)
#define LONG(x) ((x)/BITS_PER_LONG)
#define BIT(x) (1 << OFF(x))
#define SETBIT(x,y) ((x)[LONG(y)] |= BIT(y))
#define CLRBIT(x,y) ((x)[LONG(y)] &= ~BIT(y))
#define ASSIGNBIT(x,y,z) ((x)[LONG(y)] = ((x)[LONG(y)] & ~BIT(y)) | (z << OFF(y)))
typedef struct _kevdevMouse {
/* current device state */
int rel[REL_MAX + 1];
int abs[ABS_MAX + 1];
int prevabs[ABS_MAX + 1];
long key[NBITS(KEY_MAX + 1)];
/* supported device info */
long relbits[NBITS(REL_MAX + 1)];
long absbits[NBITS(ABS_MAX + 1)];
long keybits[NBITS(KEY_MAX + 1)];
struct input_absinfo absinfo[ABS_MAX + 1];
int max_rel;
int max_abs;
} Kevdev;
static int flags = 0;
static void
EvdevMotion (KdMouseInfo *mi)
{
Kevdev *ke = mi->driver;
int i;
for (i = 0; i <= ke->max_rel; i++)
if (ke->rel[i])
{
KdEnqueueMouseEvent (mi, flags | KD_MOUSE_DELTA, ke->rel[0], ke->rel[1]);
int a;
// ErrorF ("rel");
for (a = 0; a <= ke->max_rel; a++)
{
// if (ISBITSET (ke->relbits, a))
// ErrorF (" %d=%d", a, ke->rel[a]);
ke->rel[a] = 0;
}
// ErrorF ("\n");
break;
}
for (i = 0; i < ke->max_abs; i++)
if (ke->abs[i] != ke->prevabs[i])
{
KdEnqueueMouseEvent (mi, flags, ke->abs[0], ke->abs[1]);
int a;
// ErrorF ("abs");
for (a = 0; a <= ke->max_abs; a++)
{
// if (ISBITSET (ke->absbits, a))
// ErrorF (" %d=%d", a, ke->abs[a]);
ke->prevabs[a] = ke->abs[a];
}
// ErrorF ("\n");
break;
}
}
static void
EvdevRead (int evdevPort, void *closure)
{
KdMouseInfo *mi = closure;
Kevdev *ke = mi->driver;
int i, n, f;
struct input_event events[NUM_EVENTS];
n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
if (n <= 0)
return;
n /= sizeof (struct input_event);
for (i = 0; i < n; i++)
{
switch (events[i].type) {
case EV_SYN:
break;
case EV_KEY:
EvdevMotion (mi);
ASSIGNBIT(ke->key,events[i].code, events[i].value);
if (events[i].code < 0x100)
ErrorF ("key %d %d\n", events[i].code, events[i].value);
else
ErrorF ("key 0x%x %d\n", events[i].code, events[i].value);
switch (events[i].code) {
case BTN_LEFT:
f = KD_BUTTON_1;
break;
case BTN_RIGHT:
f = KD_BUTTON_2;
break;
case BTN_MIDDLE:
f = KD_BUTTON_3;
break;
case BTN_FORWARD:
f = KD_BUTTON_4;
break;
case BTN_BACK:
f = KD_BUTTON_5;
break;
}
flags |= f;
KdEnqueueMouseEvent (mi, KD_MOUSE_DELTA | flags, 0, 0);
ErrorF("Flags is %x\n", flags);
break;
case EV_REL:
ErrorF("EV_REL\n");
ke->rel[events[i].code] += events[i].value;
break;
case EV_ABS:
ErrorF("EV_ABS\n");
ke->abs[events[i].code] = events[i].value;
break;
}
}
EvdevMotion (mi);
}
int EvdevInputType;
char *kdefaultEvdev[] = {
// "/dev/input/event0",
// "/dev/input/event1",
// "/dev/input/event2",
// "/dev/input/event3",
// "/dev/input/event4",
"/dev/input/event5",
};
#define NUM_DEFAULT_EVDEV (sizeof (kdefaultEvdev) / sizeof (kdefaultEvdev[0]))
static Bool
EvdevInit (void)
{
int i;
int fd;
KdMouseInfo *mi, *next;
int n = 0;
char *prot;
char name[100];
if (!EvdevInputType)
EvdevInputType = KdAllocInputType ();
for (mi = kdMouseInfo; mi; mi = next)
{
next = mi->next;
prot = mi->prot;
if (mi->inputType)
continue;
if (!mi->name)
{
for (i = 0; i < NUM_DEFAULT_EVDEV; i++)
{
fd = open (kdefaultEvdev[i], 2);
if (fd >= 0)
{
ioctl(fd, EVIOCGRAB, 1);
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
ErrorF("Name is %s\n", name);
ioctl(fd, EVIOCGPHYS(sizeof(name)), name);
ErrorF("Phys Loc is %s\n", name);
ioctl(fd, EVIOCGUNIQ(sizeof(name)), name);
ErrorF("Unique is %s\n", name);
mi->name = KdSaveString (kdefaultEvdev[i]);
break;
}
}
}
else
fd = open (mi->name, 2);
if (fd >= 0)
{
unsigned long ev[NBITS(EV_MAX)];
Kevdev *ke;
if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0)
{
perror ("EVIOCGBIT 0");
close (fd);
continue;
}
ke = xalloc (sizeof (Kevdev));
if (!ke)
{
close (fd);
continue;
}
memset (ke, '\0', sizeof (Kevdev));
if (ISBITSET (ev, EV_KEY))
{
if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)),
ke->keybits) < 0)
{
perror ("EVIOCGBIT EV_KEY");
xfree (ke);
close (fd);
continue;
}
}
if (ISBITSET (ev, EV_REL))
{
if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)),
ke->relbits) < 0)
{
perror ("EVIOCGBIT EV_REL");
xfree (ke);
close (fd);
continue;
}
for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--)
if (ISBITSET(ke->relbits, ke->max_rel))
break;
}
if (ISBITSET (ev, EV_ABS))
{
int i;
if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)),
ke->absbits) < 0)
{
perror ("EVIOCGBIT EV_ABS");
xfree (ke);
close (fd);
continue;
}
for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--)
if (ISBITSET(ke->absbits, ke->max_abs))
break;
for (i = 0; i <= ke->max_abs; i++)
{
if (ISBITSET (ke->absbits, i))
if (ioctl (fd, EVIOCGABS(i), &ke->absinfo[i]) < 0)
{
perror ("EVIOCGABS");
break;
}
ke->prevabs[i] = ABS_UNSET;
}
if (i <= ke->max_abs)
{
xfree (ke);
close (fd);
continue;
}
}
mi->driver = ke;
mi->inputType = EvdevInputType;
if (KdRegisterFd (EvdevInputType, fd, EvdevRead, (void *) mi))
n++;
}
}
return TRUE;
}
static void
EvdevFini (void)
{
KdMouseInfo *mi;
KdUnregisterFds (EvdevInputType, TRUE);
for (mi = kdMouseInfo; mi; mi = mi->next)
{
if (mi->inputType == EvdevInputType)
{
xfree (mi->driver);
mi->driver = 0;
mi->inputType = 0;
}
}
}
KdMouseFuncs LinuxEvdevMouseFuncs = {
EvdevInit,
EvdevFini,
};
static void EvdevKbdLoad(void)
{
}
static const KeySym linux_to_x[128] = {
/*KEY_RESERVED*/ NoSymbol,
/*KEY_ESC*/ XK_Escape,
/*KEY_1*/ XK_1,
/*KEY_2*/ XK_2,
/*KEY_3*/ XK_3,
/*KEY_4*/ XK_4,
/*KEY_5*/ XK_5,
/*KEY_6*/ XK_6,
/*KEY_7*/ XK_7,
/*KEY_8*/ XK_8,
/*KEY_9*/ XK_9,
/*KEY_0*/ XK_0,
/*KEY_MINUS*/ XK_minus,
/*KEY_EQUAL*/ XK_equal,
/*KEY_BACKSPACE*/ XK_BackSpace,
/*KEY_TAB*/ XK_Tab,
/*KEY_Q*/ XK_Q,
/*KEY_W*/ XK_W,
/*KEY_E*/ XK_E,
/*KEY_R*/ XK_R,
/*KEY_T*/ XK_T,
/*KEY_Y*/ XK_Y,
/*KEY_U*/ XK_U,
/*KEY_I*/ XK_I,
/*KEY_O*/ XK_O,
/*KEY_P*/ XK_P,
/*KEY_LEFTBRACE*/ XK_braceleft,
/*KEY_RIGHTBRACE*/ XK_braceright,
/*KEY_ENTER*/ XK_Return,
/*KEY_LEFTCTRL*/ XK_Control_L,
/*KEY_A*/ XK_A,
/*KEY_S*/ XK_S,
/*KEY_D*/ XK_D,
/*KEY_F*/ XK_F,
/*KEY_G*/ XK_G,
/*KEY_H*/ XK_H,
/*KEY_J*/ XK_J,
/*KEY_K*/ XK_K,
/*KEY_L*/ XK_L,
/*KEY_SEMICOLON*/ XK_semicolon,
/*KEY_APOSTROPHE*/ XK_apostrophe,
/*KEY_GRAVE*/ XK_grave,
/*KEY_LEFTSHIFT*/ XK_Shift_L,
/*KEY_BACKSLASH*/ XK_backslash,
/*KEY_Z*/ XK_Z,
/*KEY_X*/ XK_X,
/*KEY_C*/ XK_C,
/*KEY_V*/ XK_V,
/*KEY_B*/ XK_B,
/*KEY_N*/ XK_N,
/*KEY_M*/ XK_M,
/*KEY_COMMA*/ XK_comma,
/*KEY_DOT*/ XK_period,
/*KEY_SLASH*/ XK_slash,
/*KEY_RIGHTSHIFT*/ XK_Shift_R,
/*KEY_KPASTERISK*/ XK_KP_Multiply,
/*KEY_LEFTALT*/ XK_Alt_L,
/*KEY_SPACE*/ XK_space,
/*KEY_CAPSLOCK*/ XK_Caps_Lock,
/*KEY_F1*/ XK_F1,
/*KEY_F2*/ XK_F2,
/*KEY_F3*/ XK_F3,
/*KEY_F4*/ XK_F4,
/*KEY_F5*/ XK_F5,
/*KEY_F6*/ XK_F6,
/*KEY_F7*/ XK_F7,
/*KEY_F8*/ XK_F8,
/*KEY_F9*/ XK_F9,
/*KEY_F10*/ XK_F10,
/*KEY_NUMLOCK*/ XK_Num_Lock,
/*KEY_SCROLLLOCK*/ XK_Scroll_Lock,
/*KEY_KP7*/ XK_KP_7,
/*KEY_KP8*/ XK_KP_8,
/*KEY_KP9*/ XK_KP_9,
/*KEY_KPMINUS*/ XK_KP_Subtract,
/*KEY_KP4*/ XK_KP_4,
/*KEY_KP5*/ XK_KP_5,
/*KEY_KP6*/ XK_KP_6,
/*KEY_KPPLUS*/ XK_KP_Add,
/*KEY_KP1*/ XK_KP_1,
/*KEY_KP2*/ XK_KP_2,
/*KEY_KP3*/ XK_KP_3,
/*KEY_KP0*/ XK_KP_0,
/*KEY_KPDOT*/ XK_KP_Decimal,
/*KEY_ZENKAKUHANKAKU*/ NoSymbol,
/*KEY_102ND*/ NoSymbol,
/*KEY_F11*/ XK_F11,
/*KEY_F12*/ XK_F12,
/*KEY_RO*/ NoSymbol,
/*KEY_KATAKANA*/ NoSymbol,
/*KEY_HIRAGANA*/ NoSymbol,
/*KEY_HENKAN*/ NoSymbol,
/*KEY_KATAKANAHIRAGANA*/ NoSymbol,
/*KEY_MUHENKAN*/ NoSymbol,
/*KEY_KPJPCOMMA*/ NoSymbol,
/*KEY_KPENTER*/ XK_KP_Enter,
/*KEY_RIGHTCTRL*/ XK_Control_R,
/*KEY_KPSLASH*/ XK_KP_Divide,
/*KEY_SYSRQ*/ NoSymbol,
/*KEY_RIGHTALT*/ XK_Alt_R,
/*KEY_LINEFEED*/ XK_Linefeed,
/*KEY_HOME*/ XK_Home,
/*KEY_UP*/ XK_Up,
/*KEY_PAGEUP*/ XK_Prior,
/*KEY_LEFT*/ XK_Left,
/*KEY_RIGHT*/ XK_Right,
/*KEY_END*/ XK_End,
/*KEY_DOWN*/ XK_Down,
/*KEY_PAGEDOWN*/ XK_Next,
/*KEY_INSERT*/ XK_Insert,
/*KEY_DELETE*/ XK_Delete,
/*KEY_MACRO*/ NoSymbol,
/*KEY_MUTE*/ NoSymbol,
/*KEY_VOLUMEDOWN*/ NoSymbol,
/*KEY_VOLUMEUP*/ NoSymbol,
/*KEY_POWER*/ NoSymbol,
/*KEY_KPEQUAL*/ NoSymbol,
/*KEY_KPPLUSMINUS*/ NoSymbol,
/*KEY_PAUSE*/ NoSymbol,
/*KEY_KPCOMMA*/ XK_KP_Separator,
/*KEY_HANGUEL*/ NoSymbol,
/*KEY_HANJA*/ NoSymbol,
/*KEY_YEN*/ NoSymbol,
/*KEY_LEFTMETA*/ NoSymbol,
/*KEY_RIGHTMETA*/ NoSymbol,
/*KEY_COMPOSE*/ NoSymbol,
};
static void
EvdevRead1 (int evdevPort, void *closure)
{
int i, n, xk;
struct input_event events[NUM_EVENTS];
n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
if (n <= 0)
return;
n /= sizeof (struct input_event);
for (i = 0; i < n; i++)
{
switch (events[i].type) {
case EV_SYN:
break;
case EV_KEY:
xk = NoSymbol;
if (events[i].code < 128)
xk = linux_to_x[events[i].code];
if (events[i].code < 0x100)
ErrorF ("key %d %d xk %d\n", events[i].code, events[i].value, xk);
else
ErrorF ("key 0x%x %d xk %d\n", events[i].code, events[i].value, xk);
if (events[i].value == 2) {
KdEnqueueKeyboardEvent (xk - KD_MIN_KEYCODE, 0);
KdEnqueueKeyboardEvent (xk - KD_MIN_KEYCODE, 1);
} else
KdEnqueueKeyboardEvent (xk - KD_MIN_KEYCODE, !events[i].value);
break;
}
}
}
char *kdefaultEvdev1[] = {
// "/dev/input/event0",
// "/dev/input/event1",
// "/dev/input/event2",
"/dev/input/event3",
// "/dev/input/event4",
// "/dev/input/event5",
};
#define NUM_DEFAULT_EVDEV1 (sizeof (kdefaultEvdev1) / sizeof (kdefaultEvdev1[0]))
static Bool
EvdevKbdInit (void)
{
int i;
int fd;
int n = 0;
char name[100];
kdMinScanCode = 0;
kdMaxScanCode = 255;
if (!EvdevInputType)
EvdevInputType = KdAllocInputType ();
for (i = 0; i < NUM_DEFAULT_EVDEV; i++)
{
fd = open (kdefaultEvdev1[i], 2);
if (fd >= 0)
{
ioctl(fd, EVIOCGRAB, 1);
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
ErrorF("Name is %s\n", name);
ioctl(fd, EVIOCGPHYS(sizeof(name)), name);
ErrorF("Phys Loc is %s\n", name);
ioctl(fd, EVIOCGUNIQ(sizeof(name)), name);
ErrorF("Unique is %s\n", name);
}
if (fd >= 0)
{
unsigned long ev[NBITS(EV_MAX)];
Kevdev *ke;
if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0)
{
perror ("EVIOCGBIT 0");
close (fd);
continue;
}
ke = xalloc (sizeof (Kevdev));
if (!ke)
{
close (fd);
continue;
}
memset (ke, '\0', sizeof (Kevdev));
if (ISBITSET (ev, EV_KEY))
{
if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)),
ke->keybits) < 0)
{
perror ("EVIOCGBIT EV_KEY");
xfree (ke);
close (fd);
continue;
}
}
if (ISBITSET (ev, EV_REL))
{
if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)),
ke->relbits) < 0)
{
perror ("EVIOCGBIT EV_REL");
xfree (ke);
close (fd);
continue;
}
for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--)
if (ISBITSET(ke->relbits, ke->max_rel))
break;
}
if (ISBITSET (ev, EV_ABS))
{
int i;
if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)),
ke->absbits) < 0)
{
perror ("EVIOCGBIT EV_ABS");
xfree (ke);
close (fd);
continue;
}
for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--)
if (ISBITSET(ke->absbits, ke->max_abs))
break;
for (i = 0; i <= ke->max_abs; i++)
{
if (ISBITSET (ke->absbits, i))
if (ioctl (fd, EVIOCGABS(i), &ke->absinfo[i]) < 0)
{
perror ("EVIOCGABS");
break;
}
ke->prevabs[i] = ABS_UNSET;
}
if (i <= ke->max_abs)
{
xfree (ke);
close (fd);
continue;
}
}
if (KdRegisterFd (EvdevInputType, fd, EvdevRead1, NULL))
n++;
}
}
return TRUE;
}
static void
EvdevKbdFini (void)
{
}
static void
EvdevKbdLeds (int leds)
{
}
static void EvdevKbdBell(int volume, int pitch, int duration)
{
}
KdKeyboardFuncs LinuxEvdevKeyboardFuncs = {
EvdevKbdLoad,
EvdevKbdInit,
EvdevKbdLeds,
EvdevKbdBell,
EvdevKbdFini,
0,
};

1683
hw/xgl/egl/kinput.c Normal file

File diff suppressed because it is too large Load Diff

58
hw/xgl/egl/kkeymap.h Normal file
View File

@ -0,0 +1,58 @@
/*
* Id: kkeymap.h,v 1.1 1999/11/02 03:54:46 keithp Exp $
*
* Copyright 1999 Keith Packard
*
* 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 Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD 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.
*/
/* $RCSId: xc/programs/Xserver/hw/kdrive/kkeymap.h,v 1.1 1999/11/19 13:53:50 hohndel Exp $ */
/*
* All global variables and functions pertaining to keyboard key mapping
* live in this header file.
*/
#ifndef _KKEYMAP_H
#define _KKEYMAP_H
/* Offset of MIN_SCANCODE to 8 (X minimum scancode value) */
#define KD_KEY_OFFSET (8 - kdMinScanCode)
#define KD_MIN_KEYCODE 8
#define KD_MAX_KEYCODE 254
#define KD_MAX_WIDTH 4
#define KD_MAX_LENGTH (KD_MAX_KEYCODE - KD_MIN_KEYCODE + 1)
extern int kdMinScanCode;
extern int kdMaxScanCode;
extern int kdMinKeyCode;
extern int kdMaxKeyCode;
extern int kdKeymapWidth;
extern KeySym kdKeymap[KD_MAX_LENGTH * KD_MAX_WIDTH];
extern CARD8 kdModMap[MAP_LENGTH];
extern KeySymsRec kdKeySyms;
typedef struct {
KeySym modsym;
int modbit;
} KdKeySymModsRec;
#endif /* _KKEYMAP_H */

798
hw/xgl/egl/xegl.c Normal file
View File

@ -0,0 +1,798 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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.
*
* Author: David Reveman <davidr@novell.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <math.h>
#include <glitz-egl.h>
#include "xgl.h"
#include "inputstr.h"
#include "cursorstr.h"
#include "mipointer.h"
#include "xegl.h"
#define XEGL_DEFAULT_SCREEN_WIDTH 800
#define XEGL_DEFAULT_SCREEN_HEIGHT 600
int xeglScreenGeneration = -1;
int xeglScreenPrivateIndex;
#define XEGL_GET_SCREEN_PRIV(pScreen) \
((xeglScreenPtr) (pScreen)->devPrivates[xeglScreenPrivateIndex].ptr)
#define XEGL_SET_SCREEN_PRIV(pScreen, v) \
((pScreen)->devPrivates[xeglScreenPrivateIndex].ptr = (pointer) v)
#define XEGL_SCREEN_PRIV(pScreen) \
xeglScreenPtr pScreenPriv = XEGL_GET_SCREEN_PRIV (pScreen)
typedef struct _xeglCursor {
Cursor cursor;
} xeglCursorRec, *xeglCursorPtr;
#define XEGL_GET_CURSOR_PRIV(pCursor, pScreen) \
((xeglCursorPtr) (pCursor)->devPriv[(pScreen)->myNum])
#define XEGL_SET_CURSOR_PRIV(pCursor, pScreen, v) \
((pCursor)->devPriv[(pScreen)->myNum] = (pointer) v)
#define XEGL_CURSOR_PRIV(pCursor, pScreen) \
xeglCursorPtr pCursorPriv = XEGL_GET_CURSOR_PRIV (pCursor, pScreen)
char *xDisplayName = NULL;
EGLDisplay xdisplay;
EGLScreenMESA xscreen;
glitz_format_t *xeglCurrentFormat;
CARD32 lastEventTime = 0;
ScreenPtr currentScreen = NULL;
Bool softCursor = TRUE;
xglScreenInfoRec xglScreenInfo = {
NULL, 0, 0, 0, 0, FALSE,
DEFAULT_GEOMETRY_DATA_TYPE,
DEFAULT_GEOMETRY_USAGE,
FALSE,
XGL_DEFAULT_PBO_MASK,
FALSE
};
extern miPointerScreenFuncRec kdPointerScreenFuncs;
static Bool
xeglAllocatePrivates (ScreenPtr pScreen)
{
xeglScreenPtr pScreenPriv;
if (xeglScreenGeneration != serverGeneration)
{
xeglScreenPrivateIndex = AllocateScreenPrivateIndex ();
if (xeglScreenPrivateIndex < 0)
return FALSE;
xeglScreenGeneration = serverGeneration;
}
pScreenPriv = xalloc (sizeof (xeglScreenRec));
if (!pScreenPriv)
return FALSE;
XEGL_SET_SCREEN_PRIV (pScreen, pScreenPriv);
return TRUE;
}
static void
xeglConstrainCursor (ScreenPtr pScreen,
BoxPtr pBox)
{
}
static void
xeglCursorLimits (ScreenPtr pScreen,
CursorPtr pCursor,
BoxPtr pHotBox,
BoxPtr pTopLeftBox)
{
*pTopLeftBox = *pHotBox;
}
static Bool
xeglDisplayCursor (ScreenPtr pScreen,
CursorPtr pCursor)
{
#if 0
XEGL_SCREEN_PRIV (pScreen);
XEGL_CURSOR_PRIV (pCursor, pScreen);
XDefineCursor (xdisplay, pScreenPriv->win, pCursorPriv->cursor);
#endif
return TRUE;
}
#ifdef ARGB_CURSOR
static Bool
xeglARGBCursorSupport (void);
static Cursor
xeglCreateARGBCursor (ScreenPtr pScreen,
CursorPtr pCursor);
#endif
static Bool
xeglRealizeCursor (ScreenPtr pScreen,
CursorPtr pCursor)
{
#if 0
xeglCursorPtr pCursorPriv;
XImage *ximage;
Pixmap source, mask;
XColor fgColor, bgColor;
GC xgc;
unsigned long valuemask;
XGCValues values;
XEGL_SCREEN_PRIV (pScreen);
valuemask = GCForeground | GCBackground;
values.foreground = 1L;
values.background = 0L;
pCursorPriv = xalloc (sizeof (xeglCursorRec));
if (!pCursorPriv)
return FALSE;
XEGL_SET_CURSOR_PRIV (pCursor, pScreen, pCursorPriv);
#ifdef ARGB_CURSOR
if (pCursor->bits->argb)
{
pCursorPriv->cursor = xeglCreateARGBCursor (pScreen, pCursor);
if (pCursorPriv->cursor)
return TRUE;
}
#endif
source = XCreatePixmap (xdisplay,
pScreenPriv->win,
pCursor->bits->width,
pCursor->bits->height,
1);
mask = XCreatePixmap (xdisplay,
pScreenPriv->win,
pCursor->bits->width,
pCursor->bits->height,
1);
xgc = XCreateGC (xdisplay, source, valuemask, &values);
ximage = XCreateImage (xdisplay,
DefaultVisual (xdisplay, xscreen),
1, XYBitmap, 0,
(char *) pCursor->bits->source,
pCursor->bits->width,
pCursor->bits->height,
BitmapPad (xdisplay), 0);
XPutImage (xdisplay, source, xgc, ximage,
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
XFree (ximage);
ximage = XCreateImage (xdisplay,
DefaultVisual (xdisplay, xscreen),
1, XYBitmap, 0,
(char *) pCursor->bits->mask,
pCursor->bits->width,
pCursor->bits->height,
BitmapPad (xdisplay), 0);
XPutImage (xdisplay, mask, xgc, ximage,
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
XFree (ximage);
XFreeGC (xdisplay, xgc);
fgColor.red = pCursor->foreRed;
fgColor.green = pCursor->foreGreen;
fgColor.blue = pCursor->foreBlue;
bgColor.red = pCursor->backRed;
bgColor.green = pCursor->backGreen;
bgColor.blue = pCursor->backBlue;
pCursorPriv->cursor =
XCreatePixmapCursor (xdisplay, source, mask, &fgColor, &bgColor,
pCursor->bits->xhot, pCursor->bits->yhot);
XFreePixmap (xdisplay, mask);
XFreePixmap (xdisplay, source);
#endif
return TRUE;
}
static Bool
xeglUnrealizeCursor (ScreenPtr pScreen,
CursorPtr pCursor)
{
#if 0
XEGL_CURSOR_PRIV (pCursor, pScreen);
XFreeCursor (xdisplay, pCursorPriv->cursor);
xfree (pCursorPriv);
#endif
return TRUE;
}
static void
xeglRecolorCursor (ScreenPtr pScreen,
CursorPtr pCursor,
Bool displayed)
{
#if 0
XColor fgColor, bgColor;
XEGL_CURSOR_PRIV (pCursor, pScreen);
fgColor.red = pCursor->foreRed;
fgColor.green = pCursor->foreGreen;
fgColor.blue = pCursor->foreBlue;
bgColor.red = pCursor->backRed;
bgColor.green = pCursor->backGreen;
bgColor.blue = pCursor->backBlue;
XRecolorCursor (xdisplay, pCursorPriv->cursor, &fgColor, &bgColor);
#endif
}
static Bool
xeglSetCursorPosition (ScreenPtr pScreen,
int x,
int y,
Bool generateEvent)
{
#if 0
XEGL_SCREEN_PRIV (pScreen);
XWarpPointer (xdisplay, pScreenPriv->win, pScreenPriv->win,
0, 0, 0, 0, x, y);
#endif
return TRUE;
}
static Bool
xeglCloseScreen (int index,
ScreenPtr pScreen)
{
glitz_drawable_t *drawable;
XEGL_SCREEN_PRIV (pScreen);
drawable = XGL_GET_SCREEN_PRIV (pScreen)->drawable;
if (drawable)
glitz_drawable_destroy (drawable);
xglClearVisualTypes ();
#if 0
if (pScreenPriv->win)
XDestroyWindow (xdisplay, pScreenPriv->win);
if (pScreenPriv->colormap)
XFreeColormap (xdisplay, pScreenPriv->colormap);
#endif
XGL_SCREEN_UNWRAP (CloseScreen);
xfree (pScreenPriv);
return (*pScreen->CloseScreen) (index, pScreen);
}
static Bool
xeglCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
{
return FALSE;
}
static void
xeglCrossScreen (ScreenPtr pScreen, Bool entering)
{
}
static void
xeglWarpCursor (ScreenPtr pScreen, int x, int y)
{
miPointerWarpCursor (pScreen, x, y);
}
miPointerScreenFuncRec xeglPointerScreenFuncs = {
xeglCursorOffScreen,
xeglCrossScreen,
xeglWarpCursor
};
static void
xeglMoveCursor(ScreenPtr pScreen, int x, int y)
{
}
#define FB_CUR_SETIMAGE 0x01
#define FB_CUR_SETPOS 0x02
#define FB_CUR_SETHOT 0x04
#define FB_CUR_SETCMAP 0x08
#define FB_CUR_SETSHAPE 0x10
#define FB_CUR_SETSIZE 0x20
#define FB_CUR_SETALL 0xFF
struct fbcurpos {
unsigned short x, y;
};
struct fb_cmap_user {
unsigned long start; /* First entry */
unsigned long len; /* Number of entries */
unsigned short *red; /* Red values */
unsigned short *green;
unsigned short *blue;
unsigned short *transp; /* transparency, can be NULL */
};
struct fb_image_user {
unsigned long dx; /* Where to place image */
unsigned long dy;
unsigned long width; /* Size of image */
unsigned long height;
unsigned long fg_color; /* Only used when a mono bitmap */
unsigned long bg_color;
unsigned char depth; /* Depth of the image */
const char *data; /* Pointer to image data */
struct fb_cmap_user cmap; /* color map info */
};
struct fb_cursor_user {
unsigned short set; /* what to set */
unsigned short enable; /* cursor on/off */
unsigned short rop; /* bitop operation */
const char *mask; /* cursor mask bits */
struct fbcurpos hot; /* cursor hot spot */
struct fb_image_user image; /* Cursor image */
};
#define FBIO_CURSOR _IOWR('F', 0x08, struct fb_cursor_user)
static void
xeglSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
{
#if 0
int fd, err;
struct fb_cursor_user cursor;
fd = open("/dev/fb0", O_RDWR);
memset(&cursor, 0, sizeof(cursor));
cursor.set = FB_CUR_SETPOS;
cursor.image.dx = 50;
cursor.image.dy = 50;
cursor.enable = 1;
err = ioctl(fd, FBIO_CURSOR, &cursor);
err = errno;
printf("errno %d\n", err);
close(fd);
#endif
}
miPointerSpriteFuncRec eglPointerSpriteFuncs = {
xeglRealizeCursor,
xeglUnrealizeCursor,
xeglSetCursor,
xeglMoveCursor,
};
static Bool
xeglScreenInit (int index,
ScreenPtr pScreen,
int argc,
char **argv)
{
EGLSurface screen_surf;
EGLModeMESA mode;
int count;
xeglScreenPtr pScreenPriv;
glitz_drawable_format_t *format;
glitz_drawable_t *drawable;
const EGLint screenAttribs[] = {
EGL_WIDTH, 1024,
EGL_HEIGHT, 768,
EGL_NONE
};
xglScreenInfo.width = 1024;
xglScreenInfo.height = 768;
format = xglVisuals[0].format;
if (!xeglAllocatePrivates (pScreen))
return FALSE;
currentScreen = pScreen;
pScreenPriv = XEGL_GET_SCREEN_PRIV (pScreen);
if (xglScreenInfo.fullscreen)
{
// xglScreenInfo.width = DisplayWidth (xdisplay, xscreen);
// xglScreenInfo.height = DisplayHeight (xdisplay, xscreen);
// xglScreenInfo.widthMm = DisplayWidthMM (xdisplay, xscreen);
// xglScreenInfo.heightMm = DisplayHeightMM (xdisplay, xscreen);
}
else if (xglScreenInfo.width == 0 || xglScreenInfo.height == 0)
{
xglScreenInfo.width = XEGL_DEFAULT_SCREEN_WIDTH;
xglScreenInfo.height = XEGL_DEFAULT_SCREEN_HEIGHT;
}
eglGetModesMESA(xdisplay, xscreen, &mode, 1, &count);
screen_surf = eglCreateScreenSurfaceMESA(xdisplay, format->id, screenAttribs);
if (screen_surf == EGL_NO_SURFACE) {
printf("failed to create screen surface\n");
return FALSE;
}
eglShowSurfaceMESA(xdisplay, xscreen, screen_surf, mode);
drawable = glitz_egl_create_surface (xdisplay, xscreen, format, screen_surf,
xglScreenInfo.width, xglScreenInfo.height);
if (!drawable)
{
ErrorF ("[%d] couldn't create glitz drawable for window\n", index);
return FALSE;
}
// XSelectInput (xdisplay, pScreenPriv->win, ExposureMask);
// XMapWindow (xdisplay, pScreenPriv->win);
if (xglScreenInfo.fullscreen)
{
#if 0
XClientMessageEvent xev;
memset (&xev, 0, sizeof (xev));
xev.type = ClientMessage;
xev.message_type = XInternAtom (xdisplay, "_NET_WM_STATE", FALSE);
xev.display = xdisplay;
xev.window = pScreenPriv->win;
xev.format = 32;
xev.data.l[0] = 1;
xev.data.l[1] =
XInternAtom (xdisplay, "_NET_WM_STATE_FULLSCREEN", FALSE);
XSendEvent (xdisplay, root, FALSE, SubstructureRedirectMask,
(XEvent *) &xev);
#endif
}
xglScreenInfo.drawable = drawable;
if (!xglScreenInit (pScreen, &xglScreenInfo))
return FALSE;
XGL_SCREEN_WRAP (CloseScreen, xeglCloseScreen);
#ifdef ARGB_CURSOR
if (!xeglARGBCursorSupport ())
softCursor = TRUE;
#endif
miDCInitialize (pScreen, &xeglPointerScreenFuncs);
// miPointerInitialize(pScreen, &eglPointerSpriteFuncs,
// &kdPointerScreenFuncs, FALSE);
if (!xglFinishScreenInit (pScreen))
return FALSE;
// while (XNextEvent (xdisplay, &xevent))
// if (xevent.type == Expose)
// break;
// XSelectInput (xdisplay, pScreenPriv->win,
// ButtonPressMask | ButtonReleaseMask |
// KeyPressMask | KeyReleaseMask | EnterWindowMask |
// PointerMotionMask);
return TRUE;
}
void
InitOutput (ScreenInfo *pScreenInfo,
int argc,
char **argv)
{
glitz_drawable_format_t *format, templ;
int i, maj, min, count;
unsigned long mask;
unsigned long extraMask[] = {
GLITZ_FORMAT_PBUFFER_MASK |
GLITZ_FORMAT_DOUBLEBUFFER_MASK,
0
};
xglSetPixmapFormats (pScreenInfo);
if (!xdisplay)
{
xdisplay = eglGetDisplay("!fb_dri");
assert(xdisplay);
if (!eglInitialize(xdisplay, &maj, &min))
FatalError ("can't open display");
eglGetScreensMESA(xdisplay, &xscreen, 1, &count);
glitz_egl_init (NULL);
}
templ.types.window = 1;
templ.types.pbuffer = 1;
templ.samples = 1;
templ.doublebuffer = 1;
templ.color.alpha_size = 8;
mask =
GLITZ_FORMAT_WINDOW_MASK |
GLITZ_FORMAT_SAMPLES_MASK;
for (i = 0; i < sizeof (extraMask) / sizeof (extraMask[0]); i++)
{
format = glitz_egl_find_config (xdisplay, xscreen,
mask | extraMask[i],
&templ, 0);
if (format)
break;
}
if (!format)
FatalError ("no visual format found");
xglSetVisualTypesAndMasks (pScreenInfo, format, (1 << TrueColor));
xglInitVisuals (pScreenInfo);
AddScreen (xeglScreenInit, argc, argv);
}
static void
xeglBlockHandler (pointer blockData,
OSTimePtr pTimeout,
pointer pReadMask)
{
XGL_SCREEN_PRIV (currentScreen);
if (!xglSyncSurface (&pScreenPriv->pScreenPixmap->drawable))
FatalError (XGL_SW_FAILURE_STRING);
glitz_surface_flush (pScreenPriv->surface);
glitz_drawable_finish (pScreenPriv->drawable);
// XSync (xdisplay, FALSE);
}
static void
xeglWakeupHandler (pointer blockData,
int result,
pointer pReadMask)
{
#if 0
ScreenPtr pScreen = currentScreen;
XEvent X;
xEvent x;
while (XPending (xdisplay)) {
XNextEvent (xdisplay, &X);
switch (X.type) {
case KeyPress:
x.u.u.type = KeyPress;
x.u.u.detail = X.xkey.keycode;
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
mieqEnqueue (&x);
break;
case KeyRelease:
x.u.u.type = KeyRelease;
x.u.u.detail = X.xkey.keycode;
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
mieqEnqueue (&x);
break;
case ButtonPress:
x.u.u.type = ButtonPress;
x.u.u.detail = X.xbutton.button;
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
mieqEnqueue (&x);
break;
case ButtonRelease:
x.u.u.type = ButtonRelease;
x.u.u.detail = X.xbutton.button;
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
mieqEnqueue (&x);
break;
case MotionNotify:
x.u.u.type = MotionNotify;
x.u.keyButtonPointer.rootX = X.xmotion.x;
x.u.keyButtonPointer.rootY = X.xmotion.y;
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
miPointerAbsoluteCursor (X.xmotion.x, X.xmotion.y, lastEventTime);
mieqEnqueue (&x);
break;
case EnterNotify:
if (X.xcrossing.detail != NotifyInferior) {
if (pScreen) {
NewCurrentScreen (pScreen, X.xcrossing.x, X.xcrossing.y);
x.u.u.type = MotionNotify;
x.u.keyButtonPointer.rootX = X.xcrossing.x;
x.u.keyButtonPointer.rootY = X.xcrossing.y;
x.u.keyButtonPointer.time = lastEventTime =
GetTimeInMillis ();
mieqEnqueue (&x);
}
}
break;
default:
break;
}
}
#endif
}
void
InitInput (int argc, char **argv)
{
eglInitInput (&LinuxEvdevMouseFuncs, &LinuxEvdevKeyboardFuncs);
RegisterBlockAndWakeupHandlers (xeglBlockHandler,
KdWakeupHandler,
NULL);
}
void
ddxUseMsg (void)
{
ErrorF ("\nXegl usage:\n");
ErrorF ("-display string display name of the real server\n");
ErrorF ("-softcursor force software cursor\n");
xglUseMsg ();
}
int
ddxProcessArgument (int argc, char **argv, int i)
{
if (!strcmp (argv[i], "-display"))
{
if (++i < argc) {
xDisplayName = argv[i];
return 2;
}
return 0;
}
else if (!strcmp (argv[i], "-softcursor"))
{
softCursor = TRUE;
return 1;
}
return xglProcessArgument (&xglScreenInfo, argc, argv, i);
}
void
AbortDDX (void)
{
}
void
ddxGiveUp ()
{
AbortDDX ();
}
void
OsVendorInit (void)
{
}
#ifdef ARGB_CURSOR
//#include <X11/extensions/Xrender.h>
static Bool
xeglARGBCursorSupport (void)
{
#if 0
int renderMajor, renderMinor;
if (!XRenderQueryVersion (xdisplay, &renderMajor, &renderMinor))
renderMajor = renderMinor = -1;
return (renderMajor > 0 || renderMinor > 4);
#endif
return TRUE;
}
static Cursor
xeglCreateARGBCursor (ScreenPtr pScreen,
CursorPtr pCursor)
{
Cursor cursor;
#if 0
Pixmap xpixmap;
GC xgc;
XImage *ximage;
XRenderPictFormat *xformat;
Picture xpicture;
XEGL_SCREEN_PRIV (pScreen);
xpixmap = XCreatePixmap (xdisplay,
pScreenPriv->win,
pCursor->bits->width,
pCursor->bits->height,
32);
xgc = XCreateGC (xdisplay, xpixmap, 0, NULL);
ximage = XCreateImage (xdisplay,
DefaultVisual (xdisplay, xscreen),
32, ZPixmap, 0,
(char *) pCursor->bits->argb,
pCursor->bits->width,
pCursor->bits->height,
32, pCursor->bits->width * 4);
XPutImage (xdisplay, xpixmap, xgc, ximage,
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
XFree (ximage);
XFreeGC (xdisplay, xgc);
xformat = XRenderFindStandardFormat (xdisplay, PictStandardARGB32);
xpicture = XRenderCreatePicture (xdisplay, xpixmap, xformat, 0, 0);
cursor = XRenderCreateCursor (xdisplay, xpicture,
pCursor->bits->xhot,
pCursor->bits->yhot);
XRenderFreePicture (xdisplay, xpicture);
XFreePixmap (xdisplay, xpixmap);
#endif
return cursor;
}
#endif

131
hw/xgl/egl/xegl.h Normal file
View File

@ -0,0 +1,131 @@
#include "randrstr.h"
#define KD_BUTTON_1 0x01
#define KD_BUTTON_2 0x02
#define KD_BUTTON_3 0x04
#define KD_BUTTON_4 0x08
#define KD_BUTTON_5 0x10
#define KD_MOUSE_DELTA 0x80000000
typedef struct _KdMouseFuncs {
Bool (*Init) (void);
void (*Fini) (void);
} KdMouseFuncs;
typedef struct _KdKeyboardFuncs {
void (*Load) (void);
int (*Init) (void);
void (*Leds) (int);
void (*Bell) (int, int, int);
void (*Fini) (void);
int LockLed;
} KdKeyboardFuncs;
typedef struct _KdOsFuncs {
int (*Init) (void);
void (*Enable) (void);
Bool (*SpecialKey) (KeySym);
void (*Disable) (void);
void (*Fini) (void);
void (*pollEvents) (void);
} KdOsFuncs;
typedef struct _KdMouseMatrix {
int matrix[2][3];
} KdMouseMatrix;
typedef enum _kdMouseState {
start,
button_1_pend,
button_1_down,
button_2_down,
button_3_pend,
button_3_down,
synth_2_down_13,
synth_2_down_3,
synth_2_down_1,
num_input_states
} KdMouseState;
#define KD_MAX_BUTTON 7
typedef struct _KdMouseInfo {
struct _KdMouseInfo *next;
void *driver;
void *closure;
char *name;
char *prot;
char map[KD_MAX_BUTTON];
int nbutton;
Bool emulateMiddleButton;
unsigned long emulationTimeout;
Bool timeoutPending;
KdMouseState mouseState;
Bool eventHeld;
xEvent heldEvent;
unsigned char buttonState;
int emulationDx, emulationDy;
int inputType;
Bool transformCoordinates;
} KdMouseInfo;
typedef struct _KdScreenInfo {
struct _KdScreenInfo *next;
ScreenPtr pScreen;
void *driver;
Rotation randr; /* rotation and reflection */
int width;
int height;
int rate;
int width_mm;
int height_mm;
int subpixel_order;
Bool dumb;
Bool softCursor;
int mynum;
DDXPointRec origin;
} KdScreenInfo;
#define KD_MAX_FB 2
#define KD_MAX_PSEUDO_DEPTH 8
#define KD_MAX_PSEUDO_SIZE (1 << KD_MAX_PSEUDO_DEPTH)
typedef struct _xeglScreen {
Window win;
Colormap colormap;
CloseScreenProcPtr CloseScreen;
KdScreenInfo *screen;
ColormapPtr pInstalledmap[KD_MAX_FB]; /* current colormap */
} xeglScreenRec, *xeglScreenPtr;
extern KdMouseInfo *kdMouseInfo;
extern KdOsFuncs *kdOsFuncs;
extern Bool kdDontZap;
extern Bool kdDisableZaphod;
extern int kdScreenPrivateIndex;
extern KdMouseFuncs LinuxEvdevMouseFuncs;
extern KdKeyboardFuncs LinuxEvdevKeyboardFuncs;
#define RR_Rotate_All (RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270)
#define RR_Reflect_All (RR_Reflect_X|RR_Reflect_Y)
#define KdGetScreenPriv(pScreen) ((xeglScreenPtr) \
(pScreen)->devPrivates[kdScreenPrivateIndex].ptr)
#define KdScreenPriv(pScreen) xeglScreenPtr pScreenPriv = KdGetScreenPriv(pScreen)
extern void eglInitInput(KdMouseFuncs *pMouseFuncs, KdKeyboardFuncs *pKeyboardFuncs);
extern void KdParseMouse(char *arg);
extern KdMouseInfo *KdMouseInfoAdd(void);
extern void KdMouseInfoDispose(KdMouseInfo *mi);
extern int KdAllocInputType(void);
extern char *KdSaveString (char *str);
extern Bool KdRegisterFd(int type, int fd, void (*read) (int fd, void *closure), void *closure);
extern void KdUnregisterFds(int type, Bool do_close);
extern void KdEnqueueKeyboardEvent(unsigned char scan_code, unsigned char is_up);
extern void KdEnqueueMouseEvent(KdMouseInfo *mi, unsigned long flags, int rx, int ry);
extern void KdRegisterFdEnableDisable(int fd,
int (*enable)(int fd, void *closure),
void (*disable)(int fd, void *closure));
extern void KdWakeupHandler(int screen, pointer data, unsigned long lresult, pointer readmask);

168
hw/xgl/egl/xeglinput.c Normal file
View File

@ -0,0 +1,168 @@
#include "xgl.h"
#include "xegl.h"
KdOsFuncs *kdOsFuncs;
Bool kdEmulateMiddleButton;
Bool kdRawPointerCoordinates;
Bool kdDontZap;
Bool kdDisableZaphod;
int kdScreenPrivateIndex;
static char *
KdParseFindNext (char *cur, char *delim, char *save, char *last)
{
while (*cur && !strchr (delim, *cur))
{
*save++ = *cur++;
}
*save = 0;
*last = *cur;
if (*cur)
cur++;
return cur;
}
/*
* Mouse argument syntax:
*
* device,protocol,options...
*
* Options are any of:
* 1-5 n button mouse
* 2button emulate middle button
* {NMO} Reorder buttons
*/
char *
KdSaveString (char *str)
{
char *n = (char *) xalloc (strlen (str) + 1);
if (!n)
return 0;
strcpy (n, str);
return n;
}
/*
* Parse mouse information. Syntax:
*
* <device>,<nbutton>,<protocol>{,<option>}...
*
* options: {nmo} pointer mapping (e.g. {321})
* 2button emulate middle button
* 3button dont emulate middle button
*/
void
KdParseMouse (char *arg)
{
char save[1024];
char delim;
KdMouseInfo *mi;
int i;
mi = KdMouseInfoAdd ();
if (!mi)
return;
mi->name = 0;
mi->prot = 0;
mi->emulateMiddleButton = kdEmulateMiddleButton;
mi->transformCoordinates = !kdRawPointerCoordinates;
mi->nbutton = 3;
for (i = 0; i < KD_MAX_BUTTON; i++)
mi->map[i] = i + 1;
if (!arg)
return;
if (strlen (arg) >= sizeof (save))
return;
arg = KdParseFindNext (arg, ",", save, &delim);
if (!save[0])
return;
mi->name = KdSaveString (save);
if (delim != ',')
return;
arg = KdParseFindNext (arg, ",", save, &delim);
if (!save[0])
return;
if ('1' <= save[0] && save[0] <= '0' + KD_MAX_BUTTON && save[1] == '\0')
{
mi->nbutton = save[0] - '0';
if (mi->nbutton > KD_MAX_BUTTON)
{
UseMsg ();
return;
}
}
if (!delim != ',')
return;
arg = KdParseFindNext (arg, ",", save, &delim);
if (save[0])
mi->prot = KdSaveString (save);
while (delim == ',')
{
arg = KdParseFindNext (arg, ",", save, &delim);
if (save[0] == '{')
{
char *s = save + 1;
i = 0;
while (*s && *s != '}')
{
if ('1' <= *s && *s <= '0' + mi->nbutton)
mi->map[i] = *s - '0';
else
UseMsg ();
s++;
}
}
else if (!strcmp (save, "2button"))
mi->emulateMiddleButton = TRUE;
else if (!strcmp (save, "3button"))
mi->emulateMiddleButton = FALSE;
else if (!strcmp (save, "rawcoord"))
mi->transformCoordinates = FALSE;
else if (!strcmp (save, "transform"))
mi->transformCoordinates = TRUE;
else
UseMsg ();
}
}
KdMouseInfo *kdMouseInfo;
KdMouseInfo *
KdMouseInfoAdd (void)
{
KdMouseInfo *mi, **prev;
mi = (KdMouseInfo *) xalloc (sizeof (KdMouseInfo));
if (!mi)
return 0;
bzero (mi, sizeof (KdMouseInfo));
for (prev = &kdMouseInfo; *prev; prev = &(*prev)->next);
*prev = mi;
return mi;
}
void
KdMouseInfoDispose (KdMouseInfo *mi)
{
KdMouseInfo **prev;
for (prev = &kdMouseInfo; *prev; prev = &(*prev)->next)
if (*prev == mi)
{
*prev = mi->next;
if (mi->name)
xfree (mi->name);
if (mi->prot)
xfree (mi->prot);
xfree (mi);
break;
}
}