[lcd4linux @ 2006-07-12 20:45:30 by reinelt]

G15 and thread patch by Anton

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@667 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
This commit is contained in:
reinelt
2006-07-12 20:45:30 +00:00
parent a2bb31e88b
commit 0c45f59043
3 changed files with 287 additions and 10 deletions
+271 -8
View File
@@ -1,4 +1,4 @@
/* $Id: drv_G15.c,v 1.6 2006/02/27 06:14:46 reinelt Exp $
/* $Id: drv_G15.c,v 1.7 2006/07/12 20:45:30 reinelt Exp $
*
* Driver for Logitech G-15 keyboard LCD screen
*
@@ -24,6 +24,9 @@
*
*
* $Log: drv_G15.c,v $
* Revision 1.7 2006/07/12 20:45:30 reinelt
* G15 and thread patch by Anton
*
* Revision 1.6 2006/02/27 06:14:46 reinelt
* graphic bug resulting in all black pixels solved
*
@@ -60,6 +63,10 @@
#include <errno.h>
#include <usb.h>
#include <fcntl.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <signal.h>
#include "debug.h"
#include "cfg.h"
@@ -68,6 +75,7 @@
#include "plugin.h"
#include "drv.h"
#include "drv_generic_graphic.h"
#include "thread.h"
#define G15_VENDOR 0x046d
#define G15_DEVICE 0xc222
@@ -78,16 +86,252 @@
#define DEBUG(x)
#endif
#define KB_UPDOWN_PRESS
static char Name[] = "G-15";
static usb_dev_handle *g15_lcd;
static unsigned char *g15_image;
unsigned char g_key_states[18];
unsigned char m_key_states[4];
unsigned char l_key_states[5];
static int uinput_fd;
static int kb_mutex;
static int kb_thread_pid;
static int kb_single_keypress=0;
/****************************************/
/*** hardware dependant functions ***/
/****************************************/
void drv_G15_keyDown(unsigned char scancode)
{
struct input_event event;
memset(&event, 0, sizeof(event));
event.type = EV_KEY;
event.code = scancode;
event.value = 1;
write (uinput_fd, &event, sizeof(event));
}
void drv_G15_keyUp(unsigned char scancode)
{
struct input_event event;
memset(&event, 0, sizeof(event));
event.type = EV_KEY;
event.code = scancode;
event.value = 0;
write (uinput_fd, &event, sizeof(event));
}
void drv_G15_keyDownUp(unsigned char scancode)
{
drv_G15_keyDown(scancode);
drv_G15_keyUp(scancode);
}
inline unsigned char drv_G15_evalScanCode(int key)
{
// first 12 G keys produce F1 - F12, thats 0x3a + key
if (key < 12)
{
return 0x3a + key;
}
// the other keys produce Key '1' (above letters) + key, thats 0x1e + key
else
{
return 0x1e + key - 12; // sigh, half an hour to find -12 ....
}
}
void drv_G15_processKeyEvent(unsigned char *buffer)
{
const int g_scancode_offset = 167;
const int m_scancode_offset = 187;
const int l_scancode_offset = 191;
int i;
int is_set;
unsigned char m_key_new_states[4];
unsigned char l_key_new_states[5];
unsigned char orig_scancode;
// printf("%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx \n\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7],buffer[8]);
// usleep(100);
if (buffer[0] == 0x01)
{
DEBUG("Checking keys: ");
for (i=0;i<18;++i)
{
orig_scancode = drv_G15_evalScanCode(i);
is_set = 0;
if (buffer[1] == orig_scancode || buffer[2] == orig_scancode || buffer[3] == orig_scancode ||
buffer[4] == orig_scancode || buffer[5] == orig_scancode)
is_set = 1;
if (!is_set && g_key_states[i] != 0)
{
// key was pressed but is no more
if (!kb_single_keypress)
drv_G15_keyUp( g_scancode_offset + i);
g_key_states[i] = 0;
debug("G%d going up",(i+1));
}
else if (is_set && g_key_states[i] == 0)
{
if (!kb_single_keypress)
drv_G15_keyDown ( g_scancode_offset + i);
else
drv_G15_keyDownUp ( g_scancode_offset + i);
g_key_states[i] = 1;
debug("G%d going down",(i+1));
}
}
}
else
{
if (buffer[0] == 0x02)
{
memset(m_key_new_states,0,sizeof(m_key_new_states));
if (buffer[6]&0x01)
m_key_new_states[0] = 1;
if (buffer[7]&0x02)
m_key_new_states[1] = 1;
if (buffer[8]&0x04)
m_key_new_states[2] = 1;
if (buffer[7]&0x40)
m_key_new_states[3] = 1;
for (i=0;i<4;++i)
{
if (!m_key_new_states[i] && m_key_states[i] != 0)
{
// key was pressed but is no more
if (!kb_single_keypress)
drv_G15_keyUp( m_scancode_offset + i);
m_key_states[i] = 0;
debug("M%d going up",(i+1));
}
else if (m_key_new_states[i] && m_key_states[i] == 0)
{
if (!kb_single_keypress)
drv_G15_keyDown ( m_scancode_offset + i);
else
drv_G15_keyDownUp ( m_scancode_offset + i);
m_key_states[i] = 1;
debug("M%d going down",(i+1));
}
}
memset(l_key_new_states,0,sizeof(l_key_new_states));
if (buffer[8]&0x80)
l_key_new_states[0] = 1;
if (buffer[2]&0x80)
l_key_new_states[1] = 1;
if (buffer[3]&0x80)
l_key_new_states[2] = 1;
if (buffer[4]&0x80)
l_key_new_states[3] = 1;
if (buffer[5]&0x80)
l_key_new_states[4] = 1;
for (i=0;i<5;++i)
{
if (!l_key_new_states[i] && l_key_states[i] != 0)
{
// key was pressed but is no more
if (!kb_single_keypress)
drv_G15_keyUp( l_scancode_offset + i);
l_key_states[i] = 0;
debug("L%d going up",(i+1));
}
else if (l_key_new_states[i] && l_key_states[i] == 0)
{
if (!kb_single_keypress)
drv_G15_keyDown ( l_scancode_offset + i);
else
drv_G15_keyDownUp ( l_scancode_offset + i);
l_key_states[i] = 1;
debug("L%d going down",(i+1));
}
}
}
}
}
void drv_G15_closeUIDevice()
{
DEBUG("closing device");
ioctl(uinput_fd, UI_DEV_DESTROY);
close(uinput_fd);
}
void drv_G15_initKeyHandling(char *device_filename)
{
struct uinput_user_dev device;
int i;
DEBUG("Key Handling init")
uinput_fd = open(device_filename, O_RDWR);
if (uinput_fd < 0)
{
info("Error, could not open the uinput device");
info("Compile your kernel for uinput, calling it a day now");
info("mknod uinput c 10 223");
abort();
}
memset(&device,0,sizeof(device));
strncpy(device.name, "G15 Keys", UINPUT_MAX_NAME_SIZE);
device.id.bustype = BUS_USB;
device.id.version = 4;
ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY);
for (i=0;i<256;++i)
ioctl(uinput_fd, UI_SET_KEYBIT, i);
write(uinput_fd, &device, sizeof(device));
if (ioctl(uinput_fd, UI_DEV_CREATE))
{
info("Failed to create input device");
abort();
}
// atexit(&closeDevice);
memset(g_key_states, 0, sizeof(g_key_states));
memset(m_key_states, 0, sizeof(m_key_states));
memset(l_key_states, 0, sizeof(l_key_states));
}
static void drv_G15_KBThread(void __attribute__ ((unused)) * notused)
{
unsigned char buffer[9];
int ret;
while (1)
{
mutex_lock(kb_mutex);
ret = usb_bulk_read(g15_lcd, 0x81, (char*)buffer, 9, 10);
// ret = usb_interrupt_read(g15_lcd, 0x81, (char*)buffer, 9, 10);
mutex_unlock(kb_mutex);
if (ret == 9)
{
drv_G15_processKeyEvent(buffer);
}
}
}
static int drv_G15_open()
{
struct usb_bus *bus;
@@ -164,8 +408,9 @@ static void drv_G15_update_img()
}
DEBUG("output array prepared");
usb_bulk_write(g15_lcd, 0x02, (char *) output, 992, 1000);
mutex_lock(kb_mutex);
usb_interrupt_write(g15_lcd, 0x02, (char *) output, 992, 1000);
mutex_unlock(kb_mutex);
usleep(300);
DEBUG("data written to LCD");
@@ -185,8 +430,8 @@ static void drv_G15_blit(const int row, const int col, const int height, const i
DEBUG("entered");
for (r = row; r < row + height; r++) {
for (c = col; c < col + width; c++) {
for (r = row; r < row + height && r < DROWS; r++) {
for (c = col; c < col + width && c < DCOLS; c++) {
g15_image[r * 160 + c] = drv_generic_graphic_black(r, c);
}
}
@@ -207,8 +452,8 @@ static int drv_G15_start(const char *section)
DEBUG("entered");
/* read display size from config */
DROWS = 160;
DCOLS = 43;
DROWS = 43;
DCOLS = 160;
DEBUG("display size set");
@@ -260,7 +505,17 @@ static int drv_G15_start(const char *section)
drv_G15_contrast(contrast);
}
*/
s = cfg_get(section, "Uinput", "");
if (s!=NULL && *s!='\0' ){
cfg_number(section, "SingleKeyPress", 0, 0, 1, &kb_single_keypress);
drv_G15_initKeyHandling(s);
DEBUG("creating thread for keyboard");
kb_mutex=mutex_create();
kb_thread_pid=thread_create("G15_KBThread", drv_G15_KBThread, NULL);
DEBUG("done");
}
DEBUG("left");
return 0;
@@ -292,7 +547,7 @@ int drv_G15_init(const char *section, const int quiet)
{
int ret;
info("%s: %s", Name, "$Revision: 1.6 $");
info("%s: %s", Name, "$Revision: 1.7 $");
DEBUG("entered");
@@ -346,6 +601,14 @@ int drv_G15_quit(const int quiet)
DEBUG("generic_graphic_quit()");
drv_generic_graphic_quit();
mutex_destroy(kb_mutex);
usleep(10*1000);
kill(kb_thread_pid,SIGKILL);
drv_G15_closeUIDevice();
DEBUG("closing UInputDev");
DEBUG("closing connection");
drv_G15_close();
+10
View File
@@ -4,6 +4,16 @@ Variables {
minute 60000
}
Display G15 {
Driver 'G-15'
Font '6x8'
Contrast 10
Inverted 0
UInput '/dev/input/uinput'
SingleKeyPress 1
}
Display SerDispLib {
Driver 'serdisplib'
Port 'PAR:/dev/parports/0'
+6 -2
View File
@@ -1,4 +1,4 @@
/* $Id: plugin_exec.c,v 1.9 2005/05/08 04:32:44 reinelt Exp $
/* $Id: plugin_exec.c,v 1.10 2006/07/12 20:45:30 reinelt Exp $
*
* plugin for external processes
*
@@ -27,6 +27,9 @@
*
*
* $Log: plugin_exec.c,v $
* Revision 1.10 2006/07/12 20:45:30 reinelt
* G15 and thread patch by Anton
*
* Revision 1.9 2005/05/08 04:32:44 reinelt
* CodingStyle added and applied
*
@@ -80,6 +83,7 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include "debug.h"
#include "plugin.h"
@@ -182,7 +186,7 @@ static void destroy_exec_thread(const int n)
free(Thread[n].key);
if (Thread[n].ret)
shm_destroy(Thread[n].shmid, Thread[n].ret);
kill(Thread[n].pid,SIGKILL);
Thread[n].delay = 0;
Thread[n].mutex = 0;
Thread[n].pid = 0;