]> git.webhop.me Git - lcd4linux.git/commitdiff
[lcd4linux @ 2006-07-12 20:45:30 by reinelt]
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Wed, 12 Jul 2006 20:45:30 +0000 (20:45 +0000)
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Wed, 12 Jul 2006 20:45:30 +0000 (20:45 +0000)
G15 and thread patch by Anton

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@667 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

drv_G15.c
lcd4linux.conf.sample
plugin_exec.c

index ef7bbaee45b1d0047480452c641e4667403972c2..73bf033e4bf7b875657f4f1f786cd329cce0c4b7 100644 (file)
--- a/drv_G15.c
+++ b/drv_G15.c
@@ -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
  *
 #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
 #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();
 
index 78538f89278fd58c4357df4b3c86108d307d7654..123a14d577286996f59a6435725164a4e1451d54 100644 (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'
index f9576e224f51a6eb5feebd2250e02c0ffb3f19cb..ec7806d85b44eeaea2c9d79e6e5aa823df826370 100644 (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;