First keyboard driver for X
This commit is contained in:
parent
610cc917cb
commit
d51ce4e00e
1 changed files with 184 additions and 42 deletions
|
@ -9,21 +9,45 @@
|
||||||
|
|
||||||
#if GFX_USE_GDISP
|
#if GFX_USE_GDISP
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xresource.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define GDISP_DRIVER_VMT GDISPVMT_X11
|
#define GDISP_DRIVER_VMT GDISPVMT_X11
|
||||||
#include "gdisp_lld_config.h"
|
#include "gdisp_lld_config.h"
|
||||||
#include "src/gdisp/driver.h"
|
#include "src/gdisp/driver.h"
|
||||||
|
|
||||||
|
// Configuration parameters for this driver
|
||||||
#ifndef GDISP_FORCE_24BIT
|
#ifndef GDISP_FORCE_24BIT
|
||||||
#define GDISP_FORCE_24BIT FALSE
|
#define GDISP_FORCE_24BIT FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GDISP_SCREEN_HEIGHT
|
|
||||||
#define GDISP_SCREEN_HEIGHT 480
|
|
||||||
#endif
|
|
||||||
#ifndef GDISP_SCREEN_WIDTH
|
#ifndef GDISP_SCREEN_WIDTH
|
||||||
#define GDISP_SCREEN_WIDTH 640
|
#define GDISP_SCREEN_WIDTH 640
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef GDISP_SCREEN_HEIGHT
|
||||||
|
#define GDISP_SCREEN_HEIGHT 480
|
||||||
|
#endif
|
||||||
|
#ifndef GKEYBOARD_X_NO_LAYOUT
|
||||||
|
/**
|
||||||
|
* Setting this to TRUE turns off the layout engine.
|
||||||
|
* In this situation "cooked" characters are returned but
|
||||||
|
* shift states etc are lost.
|
||||||
|
* As only a limited number of keyboard layouts are currently
|
||||||
|
* defined for X in uGFX (currently none), setting this
|
||||||
|
* to TRUE enables the X keyboard mapping to be pass non-English
|
||||||
|
* characters to uGFX or to handle non-standard keyboard layouts at
|
||||||
|
* the expense of losing special function keys etc.
|
||||||
|
*/
|
||||||
|
// We set this to TRUE by default as currently the X layout code is not complete!
|
||||||
|
#define GKEYBOARD_X_NO_LAYOUT TRUE
|
||||||
|
#endif
|
||||||
|
#ifndef GKEYBOARD_X_DEFAULT_LAYOUT
|
||||||
|
#define GKEYBOARD_X_DEFAULT_LAYOUT KeyboardLayout_X_US
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Driver status flags
|
||||||
#define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0)
|
#define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0)
|
||||||
|
|
||||||
#if GINPUT_NEED_MOUSE
|
#if GINPUT_NEED_MOUSE
|
||||||
|
@ -68,11 +92,73 @@
|
||||||
}};
|
}};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#if GINPUT_NEED_KEYBOARD
|
||||||
#include <X11/Xutil.h>
|
// Include mouse support code
|
||||||
#include <X11/Xresource.h>
|
#define GKEYBOARD_DRIVER_VMT GKEYBOARDVMT_X
|
||||||
#include <stdio.h>
|
#include "src/ginput/driver_keyboard.h"
|
||||||
#include <stdlib.h>
|
|
||||||
|
#if !GKEYBOARD_X_NO_LAYOUT
|
||||||
|
#if GKEYBOARD_LAYOUT_OFF
|
||||||
|
#error "The X keyboard driver is using the layout engine. Please set GKEYBOARD_LAYOUT_OFF=FALSE or GKEYBOARD_X_NO_LAYOUT=TRUE."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Forward definitions
|
||||||
|
extern uint8_t GKEYBOARD_X_DEFAULT_LAYOUT[];
|
||||||
|
|
||||||
|
#include "src/ginput/keyboard_microcode.h"
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
|
||||||
|
// This is the layout code for the English US keyboard.
|
||||||
|
// We make it public so that a user can switch to a different layout if required.
|
||||||
|
uint8_t KeyboardLayout_X_US[] = {
|
||||||
|
KMC_HEADERSTART, KMC_HEADER_ID1, KMC_HEADER_ID2, KMC_HEADER_VER_1,
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
#error "The code to do keyboard layouts in X is not complete."
|
||||||
|
|
||||||
|
// Transient Shifters: SHIFT, CTRL, ALT, WINKEY
|
||||||
|
// Locking Shifters: CAPSLOCK, NUMLOCK and SCROLLLOCK
|
||||||
|
// Keyup, Repeat
|
||||||
|
// 0 - 9
|
||||||
|
// A - Z
|
||||||
|
// Number pad
|
||||||
|
// Symbols
|
||||||
|
// Special Keys
|
||||||
|
// Anything else
|
||||||
|
// EOF
|
||||||
|
KMC_RECORDSTART, 0
|
||||||
|
};
|
||||||
|
#elif !GKEYBOARD_LAYOUT_OFF
|
||||||
|
#warning "The X keyboard driver is not using the layout engine. If no other keyboard is using it consider defining GKEYBOARD_LAYOUT_OFF=TRUE to save code size."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Forward definitions
|
||||||
|
static bool_t XKeyboardInit(GKeyboard *k, unsigned driverinstance);
|
||||||
|
static int XKeyboardGetData(GKeyboard *k, uint8_t *pch, int sz);
|
||||||
|
|
||||||
|
const GKeyboardVMT const GKEYBOARD_DRIVER_VMT[1] = {{
|
||||||
|
{
|
||||||
|
GDRIVER_TYPE_KEYBOARD,
|
||||||
|
GKEYBOARD_VFLG_NOPOLL, // GKEYBOARD_VFLG_DYNAMICONLY
|
||||||
|
sizeof(GKeyboard),
|
||||||
|
_gkeyboardInitDriver, _gkeyboardPostInitDriver, _gkeyboardDeInitDriver
|
||||||
|
},
|
||||||
|
// The default keyboard layout
|
||||||
|
#if GKEYBOARD_X_NO_LAYOUT
|
||||||
|
0,
|
||||||
|
#else
|
||||||
|
GKEYBOARD_X_DEFAULT_LAYOUT,
|
||||||
|
#endif
|
||||||
|
XKeyboardInit, // init
|
||||||
|
0, // deinit
|
||||||
|
XKeyboardGetData, // getdata
|
||||||
|
0 // putdata void (*putdata)(GKeyboard *k, char ch); Optional
|
||||||
|
}};
|
||||||
|
|
||||||
|
static int keypos;
|
||||||
|
static uint8_t keybuffer[8];
|
||||||
|
static GKeyboard *keyboard;
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool_t initdone;
|
static bool_t initdone;
|
||||||
static Display *dis;
|
static Display *dis;
|
||||||
|
@ -97,7 +183,8 @@ typedef struct xPriv {
|
||||||
static void ProcessEvent(GDisplay *g, xPriv *priv) {
|
static void ProcessEvent(GDisplay *g, xPriv *priv) {
|
||||||
switch(evt.type) {
|
switch(evt.type) {
|
||||||
case MapNotify:
|
case MapNotify:
|
||||||
XSelectInput(dis, evt.xmap.window, StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
|
XSelectInput(dis, evt.xmap.window,
|
||||||
|
StructureNotifyMask|ExposureMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|KeymapStateMask);
|
||||||
g->flags |= GDISP_FLG_READY;
|
g->flags |= GDISP_FLG_READY;
|
||||||
break;
|
break;
|
||||||
case UnmapNotify:
|
case UnmapNotify:
|
||||||
|
@ -145,6 +232,33 @@ static void ProcessEvent(GDisplay *g, xPriv *priv) {
|
||||||
_gmouseWakeup(priv->mouse);
|
_gmouseWakeup(priv->mouse);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if GINPUT_NEED_KEYBOARD
|
||||||
|
case KeymapNotify:
|
||||||
|
XRefreshKeyboardMapping(&evt.xmapping);
|
||||||
|
break;
|
||||||
|
case KeyPress:
|
||||||
|
#if !GKEYBOARD_X_NO_LAYOUT
|
||||||
|
// TODO
|
||||||
|
#error "The code to do keyboard layouts in X is not complete."
|
||||||
|
#endif
|
||||||
|
/* ignore these when there is no layout engine */
|
||||||
|
break;
|
||||||
|
case KeyRelease:
|
||||||
|
#if !GKEYBOARD_X_NO_LAYOUT
|
||||||
|
// TODO
|
||||||
|
#error "The code to do keyboard layouts in X is not complete."
|
||||||
|
#endif
|
||||||
|
if (keyboard && !keyboard->pLayout && keypos < (int)sizeof(keybuffer)) {
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = XLookupString(&evt.xkey, (char *)(keybuffer+keypos), sizeof(keybuffer)-keypos, /*&keysym*/0, NULL);
|
||||||
|
if (len > 0) {
|
||||||
|
keypos += len;
|
||||||
|
_gkeyboardWakeup(keyboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,4 +490,32 @@ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g)
|
||||||
}
|
}
|
||||||
#endif /* GINPUT_NEED_MOUSE */
|
#endif /* GINPUT_NEED_MOUSE */
|
||||||
|
|
||||||
|
#if GINPUT_NEED_KEYBOARD
|
||||||
|
static bool_t XKeyboardInit(GKeyboard *k, unsigned driverinstance) {
|
||||||
|
(void) driverinstance;
|
||||||
|
|
||||||
|
// Only one please
|
||||||
|
if (keyboard)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
keyboard = k;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int XKeyboardGetData(GKeyboard *k, uint8_t *pch, int sz) {
|
||||||
|
int i, j;
|
||||||
|
(void) k;
|
||||||
|
|
||||||
|
if (!keypos)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(i = 0; i < keypos && i < sz; i++)
|
||||||
|
pch[i] = keybuffer[i];
|
||||||
|
keypos -= i;
|
||||||
|
for(j=0; j < keypos; j++)
|
||||||
|
keybuffer[j] = keybuffer[i+j];
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
#endif /* GINPUT_NEED_KEYBOARD */
|
||||||
|
|
||||||
#endif /* GFX_USE_GDISP */
|
#endif /* GFX_USE_GDISP */
|
||||||
|
|
Loading…
Add table
Reference in a new issue