mirror of
https://github.com/netfun2000/lcd4linux.git
synced 2026-02-27 09:44:34 +08:00
[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:
@@ -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();
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user