Initial Xegl check-in. Works on EGL fbdev driver Input is totally broken.
This commit is contained in:
parent
88d49bed00
commit
aa95967286
|
@ -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@
|
||||
|
|
@ -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,
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue