Clients must now request keys using either client_add_key or screen_add_key to receive key events. If a screen is active (on the display) and it has registered a key with "screen_add_key" it will be the only client to get that key. If the current screen doesn't want the key, it will be sent to all clients that have registered that key using "client_add_key". If you want to define a "hot button" for your client, you should probably register that "hot key" with "client_add_key" and then list the keys that control your client with "screen_add_key" on each screen. If you don't have a "hot key", then just register keys with "screen_add_key" and you'll get keystrokes only when your screen is active. Also fixed some formatting (spaces versus tabs) in a couple of places.
660 lines
17 KiB
C
660 lines
17 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <termios.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <sys/errno.h>
|
|
#include <sys/time.h>
|
|
|
|
#include "lcd.h"
|
|
#include "../../shared/str.h"
|
|
#include "glk.h"
|
|
#include "glkproto.h"
|
|
|
|
static GLKDisplay * PortFD ;
|
|
/* Initialize pseudo-CGRAM to empty */
|
|
static unsigned char CGRAM[8] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' };
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////// Matrix Orbital Graphical Driver /////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
lcd_logical_driver *glk;
|
|
|
|
static unsigned char * screen_contents = NULL ;
|
|
int fontselected = 0 ;
|
|
int gpo_count = 0 ;
|
|
|
|
// TODO: Get lcd.framebuf to properly work as whatever driver is running...
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// init() should set up any device-specific stuff, and
|
|
// point all the function pointers.
|
|
int glk_init(struct lcd_logical_driver *driver, char *args)
|
|
{
|
|
char * argv[64];
|
|
int argc;
|
|
char * device = "/dev/lcd" ;
|
|
int contrast = 140;
|
|
speed_t speed = B19200 ;
|
|
|
|
int i ;
|
|
int width ;
|
|
int height ;
|
|
|
|
// printf("glk_init()\n");
|
|
|
|
glk = driver;
|
|
|
|
argc = get_args( argv, args, 64 );
|
|
for( i = 0 ; i < argc; ++i ) {
|
|
if( 0 == strcmp( argv[i], "-d")
|
|
|| 0 == strcmp( argv[i], "--device" )
|
|
) {
|
|
if( i+1 >= argc ) {
|
|
fprintf( stderr, "glk: %s requires an argument\n", argv[i]);
|
|
return( -1 );
|
|
};
|
|
device = argv[i+1] ;
|
|
++i ;
|
|
} else if( 0 == strcmp( argv[i], "-c" )
|
|
|| 0 == strcmp( argv[i], "--contrast" )
|
|
) {
|
|
int tmp ;
|
|
if( i+1 >= argc ) {
|
|
fprintf( stderr, "glk: %s requires an argument\n", argv[i]);
|
|
return( -1 );
|
|
};
|
|
tmp = atoi( argv[i+1] );
|
|
if( tmp < 0 || tmp > 255 ) {
|
|
fprintf( stderr, "glk: %s argument must be between 0 and 255\n", argv[i]);
|
|
} else {
|
|
contrast = tmp ;
|
|
};
|
|
++i ;
|
|
} else if( 0 == strcmp( argv[i], "-s" )
|
|
|| 0 == strcmp( argv[i], "--speed" )
|
|
) {
|
|
int tmp ;
|
|
if( i+1 >= argc ) {
|
|
fprintf( stderr, "glk: %s requires an argument\n", argv[i]);
|
|
return( -1 );
|
|
};
|
|
tmp = atoi( argv[i+1] );
|
|
if( tmp == 9600 ) {
|
|
speed = B9600 ;
|
|
} else if( tmp == 19200 ) {
|
|
speed = B19200 ;
|
|
} else if( tmp == 38400 ) {
|
|
speed = B38400 ;
|
|
} else {
|
|
fprintf( stderr, "glk: %s argument (%s) not a valid speed.\n", argv[i], argv[i+1] );
|
|
};
|
|
++i ;
|
|
} else if( 0 == strcmp( argv[i], "-h" )
|
|
|| 0 == strcmp( argv[i], "--help" )
|
|
) {
|
|
printf(
|
|
"LCDproc Matrix-Orbital GLK Graphical LCD driver\n"
|
|
"\n"
|
|
"-d, --device select the serial device to use [/dev/lcd]\n"
|
|
"-c, --contrast set the initial contrast value [140]\n"
|
|
"-s, --speed set the serial port speed [19200]\n"
|
|
"-h, --help display this help text\n"
|
|
);
|
|
return( -1 );
|
|
} else {
|
|
fprintf( stderr, "glk: Invalid parameter: %s\n", argv[i] );
|
|
};
|
|
};
|
|
|
|
PortFD = glkopen( device, speed );
|
|
if( PortFD == NULL ) {
|
|
return -1 ;
|
|
};
|
|
|
|
// Query the module for a device type
|
|
glkputl( PortFD, GLKCommand, 0x37, EOF );
|
|
i = glkget( PortFD );
|
|
if( i < 0 ) {
|
|
fprintf( stderr, "glk: GLK did not respond to READ MODULE TYPE.\n" );
|
|
return -1 ;
|
|
} else {
|
|
switch( i ) {
|
|
case 0x10 : // GLC12232
|
|
width = 20 ; height = 4 ; break ;
|
|
case 0x11 : // GLC12864
|
|
width = 20 ; height = 8 ; break ;
|
|
case 0x12 : // GLC128128
|
|
width = 20 ; height = 16 ; break ;
|
|
case 0x13 : // GLC24064
|
|
width = 40 ; height = 8 ; gpo_count = 1 ; break ;
|
|
case 0x14 : // GLK12864-25
|
|
width = 20 ; height = 8 ; break ;
|
|
case 0x15 : // GLK24064-25
|
|
width = 40 ; height = 8 ; gpo_count = 1 ; break ;
|
|
case 0x21 : // GLK128128-25
|
|
width = 20 ; height = 16 ; break ;
|
|
case 0x22 : // GLK12232-25
|
|
width = 20 ; height = 4 ; gpo_count = 2 ; break ;
|
|
case 0x23 : // GLK12232-25SM
|
|
width = 20 ; height = 4 ; gpo_count = 2 ; break ;
|
|
case 0x24 : // GLK12232-25SM-Penguin
|
|
width = 20 ; height = 4 ; gpo_count = 2 ; break ;
|
|
default :
|
|
fprintf( stderr, "glk: Unrecognized module type: 0x%02x\n", i );
|
|
return( -1 );
|
|
};
|
|
};
|
|
driver->wid = width ;
|
|
driver->hgt = height ;
|
|
|
|
// You must use driver->framebuf here, but may use lcd.framebuf later.
|
|
if(!driver->framebuf) {
|
|
driver->framebuf = malloc(driver->wid * driver->hgt);
|
|
};
|
|
screen_contents = malloc( driver->wid * driver->hgt );
|
|
|
|
if(driver->framebuf == NULL || screen_contents == NULL ) {
|
|
fprintf( stderr, "glk: Unable to allocate memory for screen buffers\n" );
|
|
glk_close();
|
|
return -1;
|
|
}
|
|
|
|
memset(driver->framebuf, ' ', driver->wid*driver->hgt);
|
|
|
|
// glk_clear();
|
|
// glkputl( PortFD, GLKCommand, 0x58, EOF );
|
|
|
|
// No font selected
|
|
fontselected = -1 ;
|
|
|
|
// Enable flow control
|
|
glkflow( PortFD, 40, 2 );
|
|
|
|
// Set read character timeout to 0
|
|
glktimeout( PortFD, 0 );
|
|
|
|
// Enable auto-transmit of up/down key events
|
|
// This allows us to generate REPEAT keys distinct from
|
|
// normal keys using timeouts. (see glk_getkey)
|
|
glkputl( PortFD, GLKCommand, 0x7e, 1, GLKCommand, 0x41, EOF );
|
|
|
|
// Set contrast
|
|
glk_contrast( contrast );
|
|
|
|
driver->cellwid = 5;
|
|
driver->cellhgt = 8;
|
|
|
|
driver->clear = glk_clear;
|
|
driver->string = glk_string;
|
|
driver->chr = glk_chr;
|
|
driver->vbar = glk_vbar;
|
|
driver->init_vbar = glk_init_vbar;
|
|
driver->hbar = glk_hbar;
|
|
driver->init_hbar = glk_init_hbar;
|
|
driver->num = glk_num ;
|
|
driver->init_num = glk_init_num ;
|
|
|
|
driver->init = glk_init;
|
|
driver->close = glk_close;
|
|
driver->flush = glk_flush;
|
|
driver->flush_box = glk_flush_box;
|
|
driver->contrast = glk_contrast;
|
|
driver->backlight = glk_backlight;
|
|
driver->output = glk_output;
|
|
driver->set_char = glk_set_char;
|
|
driver->icon = glk_icon;
|
|
driver->draw_frame = glk_draw_frame;
|
|
|
|
driver->getkey = glk_getkey;
|
|
|
|
|
|
return 200; // 200 is arbitrary. (must be 1 or more)
|
|
}
|
|
|
|
|
|
// Below here, you may use either lcd.framebuf or driver->framebuf..
|
|
// lcd.framebuf will be set to the appropriate buffer before calling
|
|
// your driver.
|
|
|
|
void glk_close()
|
|
{
|
|
if(lcd.framebuf != NULL) free(lcd.framebuf);
|
|
|
|
lcd.framebuf = NULL;
|
|
|
|
glkclose( PortFD ) ;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Clears the LCD screen
|
|
//
|
|
#define CLEARCOUNT (1000000)
|
|
static int clearcount = 0 ;
|
|
void glk_clear_forced()
|
|
{
|
|
// puts( "REALLY CLEARING the display" );
|
|
clearcount = CLEARCOUNT ;
|
|
glkputl( PortFD, GLKCommand, 0x58, EOF );
|
|
memset(screen_contents, ' ', lcd.wid*lcd.hgt);
|
|
}
|
|
void glk_clear()
|
|
{
|
|
// puts( "glk_clear( )" );
|
|
memset(lcd.framebuf, ' ', lcd.wid*lcd.hgt);
|
|
if( --clearcount < 0 ) {
|
|
glk_clear_forced( );
|
|
};
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Flushes all output to the lcd...
|
|
//
|
|
void glk_flush()
|
|
{
|
|
// puts( "glk_flush( )" );
|
|
lcd.draw_frame(lcd.framebuf);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Prints a string on the lcd display, at position (x,y). The
|
|
// upper-left is (1,1), and the lower right should be (20,4).
|
|
//
|
|
void glk_string(int x, int y, char string[])
|
|
{
|
|
char * p ;
|
|
|
|
// printf( "glk_string( %d, %d, \"%s\" )\n", x, y, string );
|
|
|
|
if( x > lcd.wid || y > lcd.hgt ) {
|
|
return ;
|
|
};
|
|
|
|
for( p = string ; *p && x <= lcd.wid ; ++x, ++p ) {
|
|
glk_chr( x, y, *p );
|
|
};
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Prints a character on the lcd display, at position (x,y). The
|
|
// upper-left is (1,1), and the lower right should be (20,4).
|
|
//
|
|
void glk_chr(int x, int y, char c)
|
|
{
|
|
int myc = (unsigned char) c ;
|
|
x -= 1; // Convert 1-based coords to 0-based...
|
|
y -= 1;
|
|
|
|
if( fontselected != 2 ) {
|
|
// puts( "Switching to font 2" );
|
|
/* Select font 2 */
|
|
glkputl( PortFD, GLKCommand, 0x31, 2, EOF );
|
|
fontselected = 2 ;
|
|
/* Set font metrics */
|
|
glkputl( PortFD, GLKCommand, 0x32, 1, 0, 1, 1, 32, EOF );
|
|
/* Clear the screen */
|
|
glk_clear_forced( );
|
|
};
|
|
|
|
if( myc >= 0 && myc <= 15 ) {
|
|
/* CGRAM */
|
|
// if( myc != 0 ) {
|
|
// printf( "CGRAM changing %d => %d\n", myc, CGRAM[myc&7] );
|
|
// };
|
|
myc = CGRAM[myc&7] ;
|
|
} else if( myc == 255 || myc == -1 ) {
|
|
/* Solid block */
|
|
myc = 133 ;
|
|
} else if( (myc > 15 && myc < 32) || myc > 143 ) {
|
|
fprintf( stderr, "Attempt to write %d to (%d,%d)\n", myc, x, y );
|
|
myc = 133 ;
|
|
};
|
|
|
|
lcd.framebuf[(y*lcd.wid) + x] = myc;
|
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Sets the contrast of the display. Value is 0-255, where 140 is
|
|
// what I consider "just right".
|
|
//
|
|
int glk_contrast(int contrast)
|
|
{
|
|
static int saved_contrast = 140 ;
|
|
|
|
if( contrast > 0 && contrast < 256 ) {
|
|
saved_contrast = contrast ;
|
|
// printf("Contrast: %i\n", contrast);
|
|
glkputl( PortFD, GLKCommand, 0x50, contrast, EOF );
|
|
};
|
|
return( saved_contrast );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Turns the lcd backlight on or off...
|
|
//
|
|
void glk_backlight(int on)
|
|
{
|
|
/*
|
|
if(on)
|
|
{
|
|
// printf("Backlight ON\n");
|
|
glkputl( PortFD, GLKCommand, 0x42, 0, EOF );
|
|
}
|
|
else
|
|
{
|
|
// printf("Backlight OFF\n");
|
|
glkputl( PortFD, GLKCommand, 0x46, EOF );
|
|
}
|
|
*/
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Sets general purpose outputs on or off
|
|
void
|
|
glk_output(int on)
|
|
{
|
|
if( gpo_count < 2 ) {
|
|
if( on ) { glkputl( PortFD, GLKCommand, 'W', EOF );
|
|
} else { glkputl( PortFD, GLKCommand, 'V', EOF );
|
|
};
|
|
} else {
|
|
int i;
|
|
for( i = 1 ; i <= gpo_count ; ++i, on >>= 1 ) {
|
|
if( on & 1 ) {
|
|
glkputl( PortFD, GLKCommand, 'W', i, EOF );
|
|
} else {
|
|
glkputl( PortFD, GLKCommand, 'V', i, EOF );
|
|
};
|
|
};
|
|
};
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Tells the driver to get ready for vertical bargraphs.
|
|
//
|
|
void glk_init_vbar()
|
|
{
|
|
// printf("Vertical bars.\n");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Tells the driver to get ready for horizontal bargraphs.
|
|
//
|
|
void glk_init_hbar()
|
|
{
|
|
// printf("Horizontal bars.\n");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Tells the driver to get ready for big numbers, if possible.
|
|
//
|
|
void glk_init_num()
|
|
{
|
|
// printf("Big Numbers.\n");
|
|
if( fontselected != 3 ) {
|
|
/* Select Big Numbers font */
|
|
glkputl( PortFD, GLKCommand, 0x31, 3, EOF );
|
|
fontselected = 3 ;
|
|
/* Set font metrics */
|
|
glkputl( PortFD, GLKCommand, 0x32, 1, 0, 1, 1, 32, EOF );
|
|
/* Clear the screen */
|
|
glk_clear_forced( );
|
|
};
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Draws a big (4-row) number.
|
|
//
|
|
void glk_num(int x, int num)
|
|
{
|
|
// printf("BigNum(%i, %i)\n", x, num);
|
|
lcd.framebuf[x-1] = num + '0' ;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Changes the font data of character n.
|
|
//
|
|
void glk_set_char(int n, char *dat)
|
|
{
|
|
printf("Set Character %i\n", n);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Draws a vertical bar, from the bottom of the screen up.
|
|
//
|
|
void glk_vbar(int x, int len)
|
|
{
|
|
int y = lcd.hgt ;
|
|
|
|
// printf( "glk_vbar( %d, %d )\n", x, len );
|
|
while( len > lcd.cellhgt ) {
|
|
glk_chr( x, y, 255 );
|
|
--y ;
|
|
len -= lcd.cellhgt ;
|
|
};
|
|
|
|
if( y >= 0 ) {
|
|
int lastc ;
|
|
switch( len ) {
|
|
case 0 : return ; break ; /* Don't output a char */
|
|
case 1 : lastc = 138 ; break ; /* One bar */
|
|
case 2 : lastc = 139 ; break ;
|
|
case 3 : lastc = 140 ; break ;
|
|
case 4 : lastc = 141 ; break ;
|
|
case 5 : lastc = 142 ; break ;
|
|
case 6 : lastc = 143 ; break ;
|
|
default: lastc = 133 ; break ;
|
|
};
|
|
glk_chr( x, y, lastc );
|
|
};
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Draws a horizontal bar to the right.
|
|
//
|
|
void glk_hbar(int x, int y, int len)
|
|
{
|
|
// printf( "glk_hbar( %d, %d, %d )\n", x, y, len );
|
|
while( len > lcd.cellwid ) {
|
|
glk_chr( x, y, 255 );
|
|
++x ;
|
|
len -= lcd.cellwid ;
|
|
};
|
|
|
|
if( x <= lcd.wid ) {
|
|
int lastc ;
|
|
switch( len ) {
|
|
case 0 : lastc = ' ' ; break ;
|
|
case 1 : lastc = 134 ; break ; /* One bar */
|
|
case 2 : lastc = 135 ; break ;
|
|
case 3 : lastc = 136 ; break ;
|
|
case 4 : lastc = 137 ; break ;
|
|
default: lastc = 133 ; break ;
|
|
};
|
|
glk_chr( x, y, lastc );
|
|
};
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Sets character 0 to an icon...
|
|
//
|
|
void glk_icon(int which, char dest)
|
|
{
|
|
unsigned char old, new ;
|
|
unsigned char * p ;
|
|
unsigned char * q ;
|
|
int count ;
|
|
|
|
// printf("Char %i set to icon %i\n", dest, which);
|
|
|
|
if( dest < 0 || dest > 7 ) {
|
|
/* Illegal custom character */
|
|
return ;
|
|
};
|
|
|
|
/* which == 0 => empty heart => 131
|
|
* which == 1 => filled heart => 132
|
|
* which == 2 => ellipsis => 128
|
|
*/
|
|
switch( which ) {
|
|
case 0: new = 131 ; break ;
|
|
case 1: new = 132 ; break ;
|
|
case 2: new = 128 ; break ;
|
|
default: return ; /* ERROR */
|
|
};
|
|
|
|
old = CGRAM[(int)dest] ;
|
|
CGRAM[(int)dest] = new ;
|
|
p = lcd.framebuf ;
|
|
q = screen_contents ;
|
|
|
|
/* Replace all old icons with new icon in new frame */
|
|
for( count = lcd.wid * lcd.hgt ; count ; --count ) {
|
|
if( *q == old ) {
|
|
// printf( "icon %d to %d at %d\n", old, new, q - screen_contents );
|
|
*p = new ;
|
|
};
|
|
++q ; ++p ;
|
|
};
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Send a rectangular area to the display.
|
|
//
|
|
// I've just called glk_flush() because there's not much point yet
|
|
// in flushing less than the entire framebuffer.
|
|
//
|
|
void glk_flush_box(int lft, int top, int rgt, int bot)
|
|
{
|
|
// printf("glk_flush_box( %d, %d, %d, %d )\n", lft, top, rgt, bot );
|
|
glk_flush( );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Draws the framebuffer on the display.
|
|
//
|
|
// The commented-out code is from the text driver.
|
|
//
|
|
void glk_draw_frame(char *dat)
|
|
{
|
|
char * p ;
|
|
char * q ;
|
|
int x, y ;
|
|
int xs ;
|
|
char * ps = NULL ;
|
|
|
|
// printf( "glk_draw_frame( %p ) lcd.framebuf = %p\n", dat, lcd.framebuf );
|
|
|
|
p = lcd.framebuf ;
|
|
q = screen_contents ;
|
|
|
|
for( y = 0 ; y < lcd.hgt ; ++y ) {
|
|
xs = -1 ; /* XStart not set */
|
|
for( x = 0 ; x < lcd.wid ; ++x ) {
|
|
if( *q == *p && xs >= 0 ) {
|
|
/* Write accumulated string */
|
|
glkputl( PortFD, GLKCommand, 0x79, xs*6+1, y*8, EOF );
|
|
glkputa( PortFD, x - xs, ps );
|
|
// printf( "draw_frame: Writing at (%d,%d) for %d\n", xs, y, x-xs );
|
|
xs = -1 ;
|
|
} else if( *q != *p && xs < 0 ) {
|
|
/* Start new string of changes */
|
|
ps = p ;
|
|
xs = x ;
|
|
};
|
|
*q++ = *p++ ; /* Update screen_contents from lcd.framebuf */
|
|
};
|
|
if( xs >= 0 ) {
|
|
/* Write accumulated line */
|
|
glkputl( PortFD, GLKCommand, 0x79, xs*6+1, y*8, EOF );
|
|
glkputa( PortFD, lcd.wid - xs, ps );
|
|
// printf( "draw_frame: Writing at (%d,%d) for %d\n", xs, y, lcd.wid-xs );
|
|
};
|
|
|
|
}; /* For y */
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Tries to read a character from an input device...
|
|
//
|
|
// Return 0 for "nothing available".
|
|
//
|
|
char glk_getkey()
|
|
{
|
|
int c ;
|
|
static int key = -1 ;
|
|
static struct timeval lastkey ;
|
|
struct timeval now ;
|
|
|
|
// puts( "glk_getkey( )" );
|
|
|
|
c = glkgetc( PortFD );
|
|
|
|
if( c >= 'A' && c <= 'Z' ) {
|
|
/* Key down event */
|
|
key = c ;
|
|
gettimeofday( &lastkey, NULL );
|
|
// printf( "KEY %c at %ld.%06ld\n", c, lastkey.tv_sec, lastkey.tv_usec );
|
|
} else if( c >= 'a' && c <= 'z' ) {
|
|
/* Key up event */
|
|
// printf( "KEY %c UP\n", c );
|
|
key = -1 ;
|
|
c = 0 ;
|
|
} else {
|
|
/* Assume timeout */
|
|
c = 0 ;
|
|
if( key > 0 ) {
|
|
int msec_diff ;
|
|
/* A key is down */
|
|
gettimeofday( &now, NULL );
|
|
msec_diff = (now.tv_sec - lastkey.tv_sec) * 1000 ;
|
|
msec_diff += (now.tv_usec - lastkey.tv_usec) / 1000 ;
|
|
// printf( "KEY %c down for %d msec\n", key, msec_diff );
|
|
if( msec_diff > 2000 ) {
|
|
/* Generate repeat event */
|
|
c = key | 0x20 ; /* Upper case to lower case */
|
|
++lastkey.tv_sec ; /* HACK HACK. repeat at 1 sec intervals */
|
|
// printf( "KEY %c REPEAT\n", c );
|
|
};
|
|
};
|
|
};
|
|
|
|
/* Remap keys according to what LCDproc expects */
|
|
switch( c ) {
|
|
default : break ;
|
|
case 'V' : c = 'A' ; break ; /* Hold/Select */
|
|
case 'P' : c = 'B' ; break ; /* Left -- Minus */
|
|
case 'Q' : c = 'C' ; break ; /* Right -- Plus */
|
|
case 'L' : c = 'D' ; break ; /* Menu/Exit */
|
|
case 'U' : c = 'E' ; break ; /* Up */
|
|
case 'K' : c = 'F' ; break ; /* Down */
|
|
case 'v' : c = 'N' ; break ;
|
|
case 'p' : c = 'O' ; break ;
|
|
case 'q' : c = 'P' ; break ;
|
|
case 'l' : c = 'Q' ; break ;
|
|
case 'u' : c = 'R' ; break ;
|
|
case 'k' : c = 'S' ; break ;
|
|
};
|
|
|
|
// if( c ) {
|
|
// printf( "KEY %c\n", c );
|
|
// };
|
|
|
|
return( c );
|
|
}
|