Re,
Bon ça passe pas. Voici mon fichier après ton patch Sam. Ptetr j'y fais
une bêtise.
Merci d ton aide ++ JP
/*
* BRLTTY - A background process providing access to the console screen (when in
* text mode) for a blind person using a refreshable braille display.
*
* Copyright (C) 1995-2005 by The BRLTTY Team. All rights reserved.
*
* BRLTTY comes with ABSOLUTELY NO WARRANTY.
*
* This is free software, placed under the terms of the
* GNU General Public License, as published by the Free Software
* Foundation. Please see the file COPYING for details.
*
* Web Page: http://mielke.cc/brltty/
*
* This software is maintained by Dave Mielke <[EMAIL PROTECTED]>.
*/
#include "prologue.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/tty.h>
#include <linux/vt.h>
#include <linux/kd.h>
#include "Programs/misc.h"
#include "Programs/brldefs.h"
typedef enum {
PARM_ACM,
PARM_DEBUGACM,
PARM_DEBUGSFM,
PARM_DEBUGCTT
} ScreenParameters;
#define SCRPARMS "acm", "debugacm", "debugsfm", "debugctt"
#include "Programs/scr_driver.h"
#include "screen.h"
static const char *problemText;
static unsigned int debugCharacterTranslationTable = 0;
static unsigned int debugApplicationCharacterMap = 0;
static unsigned int debugScreenFontMap = 0;
static unsigned int debugScreenTextTranslation = 0;
/* Copied from linux-2.2.17/drivers/char/consolemap.c: translations[0]
* 8-bit Latin-1 mapped to Unicode -- trivial mapping
*/
static const ApplicationCharacterMap iso01Map = {
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
};
/* Copied from linux-2.2.17/drivers/char/consolemap.c: translations[1]
* VT100 graphics mapped to Unicode
*/
static const ApplicationCharacterMap vt100Map = {
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f,
0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0xf800,
0xf801, 0x2500, 0xf803, 0xf804, 0x251c, 0x2524, 0x2534, 0x252c,
0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
};
/* Copied from linux-2.2.17/drivers/char/consolemap.c: translations[2]
* IBM Codepage 437 mapped to Unicode
*/
static const ApplicationCharacterMap cp437Map = {
0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
};
static const char *
findDevicePath (const char *paths, const char *description, int mode) {
char *devices = strdupWrapper(paths);
char *tokens = devices;
const char *delimiters = " ";
char *path = NULL;
int exists = 0;
char *device;
while ((device = strtok(tokens, delimiters))) {
tokens = NULL;
device = strdupWrapper(device);
LogPrint(LOG_DEBUG, "Checking %s Device: %s",
description, device);
if (access(device, mode) == -1) {
LogPrint(LOG_DEBUG, "%s Device access error: %s: %s",
description, device, strerror(errno));
} else {
struct stat status;
if (stat(device, &status) == -1) {
LogPrint(LOG_ERR, "%s Device stat error: %s: %s",
description, device, strerror(errno));
} else if (!S_ISCHR(status.st_mode)) {
LogPrint(LOG_ERR, "%s Device not character special: %s",
description, device);
} else {
if (path) free(path);
path = device;
exists = 1;
break;
}
}
if (errno != ENOENT) {
if (!exists) {
exists = 1;
if (path) {
free(path);
path = NULL;
}
}
}
if (path)
free(device);
else
path = device;
}
free(devices);
return path;
}
static int
setDevicePath (const char **path, const char *paths, const char *description,
int mode) {
LogPrint(LOG_DEBUG, "%s Device List: %s", description, paths);
if ((*path = findDevicePath(paths, description, mode))) {
LogPrint(LOG_INFO, "%s Device: %s", description, *path);
return 1;
} else {
LogPrint(LOG_ERR, "%s Device not specified.", description);
}
return 0;
}
static char *
vtPath (const char *base, unsigned char vt) {
if (vt) {
size_t length = strlen(base);
char buffer[length+4];
if (base[length-1] == '0') --length;
strncpy(buffer, base, length);
sprintf(buffer+length, "%u", vt);
return strdup(buffer);
}
return strdup(base);
}
static int
openDevice (const char *path, const char *description, int flags, int major,
int minor) {
int file;
LogPrint(LOG_DEBUG, "Opening %s device: %s", description, path);
if ((file = open(path, flags)) == -1) {
LogPrint(LOG_ERR, "Cannot open %s device: %s: %s",
description, path, strerror(errno));
if (errno == ENOENT) {
mode_t mode = S_IFCHR | S_IRUSR | S_IWUSR;
LogPrint(LOG_NOTICE, "Creating %s device: %s mode=%06o major=%d minor=%d",
description, path, mode, major, minor);
if (mknod(path, mode, makedev(major, minor)) == -1) {
LogPrint(LOG_ERR, "Cannot create %s device: %s: %s",
description, path, strerror(errno));
} else if ((file = open(path, flags)) == -1) {
LogPrint(LOG_ERR, "Cannot open %s device: %s: %s",
description, path, strerror(errno));
if (unlink(path) == -1)
LogPrint(LOG_ERR, "Cannot remove %s device: %s: %s",
description, path, strerror(errno));
else
LogPrint(LOG_NOTICE, "Removed %s device: %s",
description, path);
}
}
}
return file;
}
static const char *consolePath;
static int consoleDescriptor;
static int
setConsolePath (void) {
return setDevicePath(&consolePath, LINUX_CONSOLE_DEVICES, "Console",
R_OK|W_OK);
}
static void
closeConsole (void) {
if (consoleDescriptor != -1) {
if (close(consoleDescriptor) == -1) {
LogError("Console close");
}
LogPrint(LOG_DEBUG, "Console closed: fd=%d", consoleDescriptor);
consoleDescriptor = -1;
}
}
static int
openConsole (unsigned char vt) {
char *path = vtPath(consolePath, vt);
if (path) {
int console = openDevice(path, "console", O_RDWR|O_NOCTTY, 4, vt);
if (console != -1) {
closeConsole();
consoleDescriptor = console;
LogPrint(LOG_DEBUG, "Console opened: %s: fd=%d", path, consoleDescriptor);
free(path);
return 1;
}
free(path);
}
return 0;
}
static const char *screenPath;
static int screenDescriptor;
static unsigned char virtualTerminal;
static int
setScreenPath (void) {
return setDevicePath(&screenPath, LINUX_SCREEN_DEVICES, "Screen", R_OK|W_OK);
}
static void
closeScreen (void) {
if (screenDescriptor != -1) {
if (close(screenDescriptor) == -1) {
LogError("Screen close");
}
LogPrint(LOG_DEBUG, "Screen closed: fd=%d", screenDescriptor);
screenDescriptor = -1;
}
}
static int
openScreen (unsigned char vt) {
char *path = vtPath(screenPath, vt);
if (path) {
int screen = openDevice(path, "screen", O_RDWR, 7, 0X80|vt);
if (screen != -1) {
LogPrint(LOG_DEBUG, "Screen opened: %s: fd=%d", path, screenDescriptor);
if (openConsole(vt)) {
closeScreen();
screenDescriptor = screen;
virtualTerminal = vt;
free(path);
return 1;
}
close(screen);
LogPrint(LOG_DEBUG, "Screen closed: fd=%d", screen);
}
free(path);
}
return 0;
}
static int
rebindConsole (void) {
return virtualTerminal? 1: openConsole(0);
}
static int
controlConsole (int operation, void *argument) {
int result = ioctl(consoleDescriptor, operation, argument);
if (result == -1)
if (errno == EIO)
if (openConsole(virtualTerminal))
result = ioctl(consoleDescriptor, operation, argument);
return result;
}
static ApplicationCharacterMap applicationCharacterMap;
static int (*setApplicationCharacterMap) (int force);
static void
logApplicationCharacterMap (void) {
if (debugApplicationCharacterMap) {
char buffer[0X80];
char *address = NULL;
unsigned char character = 0;
while (1) {
if (!(character % 8)) {
if (address) {
LogPrint(LOG_DEBUG, "%s", buffer);
if (!character) break;
}
address = buffer;
address += sprintf(address, "acm[%02X]:", character);
}
address += sprintf(address, " %4.4X",
applicationCharacterMap[character++]);
}
}
}
static int
getUserAcm (int force) {
ApplicationCharacterMap map;
if (controlConsole(GIO_UNISCRNMAP, &map) != -1) {
if (force || (memcmp(applicationCharacterMap, map,
sizeof(applicationCharacterMap)) != 0)) {
memcpy(applicationCharacterMap, map, sizeof(applicationCharacterMap));
if (!force) LogPrint(LOG_DEBUG, "User application character map
changed.");
logApplicationCharacterMap();
return 1;
}
} else {
LogError("ioctl GIO_UNISCRNMAP");
}
return 0;
}
static int
determineApplicationCharacterMap (int force) {
const char *name = NULL;
if (!getUserAcm(force)) return 0;
{
unsigned short character;
for (character=0; character<0X100; ++character) {
if (applicationCharacterMap[character] != (character | 0XF000)) {
setApplicationCharacterMap = &getUserAcm;
name = "user";
break;
}
}
}
if (!name) {
memcpy(applicationCharacterMap, iso01Map, sizeof(applicationCharacterMap));
setApplicationCharacterMap = NULL;
logApplicationCharacterMap();
name = "iso01";
}
LogPrint(LOG_INFO, "Application Character Map: %s", name);
return 1;
}
static struct unipair *screenFontMapTable;
static unsigned short screenFontMapCount;
static unsigned short screenFontMapSize;
static int
setScreenFontMap (int force) {
struct unimapdesc sfm;
unsigned short size = force? 0: screenFontMapCount;
if (!size) size = 0X100;
while (1) {
sfm.entry_ct = size;
if (!(sfm.entries = malloc(sfm.entry_ct * sizeof(*sfm.entries)))) {
LogError("Screen font map allocation");
return 0;
}
if (controlConsole(GIO_UNIMAP, &sfm) != -1) break;
free(sfm.entries);
if (errno != ENOMEM) {
LogError("ioctl GIO_UNIMAP");
return 0;
}
if (!(size <<= 1)) {
LogPrint(LOG_ERR, "Screen font map too big.");
return 0;
}
}
if (!force) {
if (sfm.entry_ct == screenFontMapCount) {
if (memcmp(sfm.entries, screenFontMapTable,
sfm.entry_ct*sizeof(sfm.entries[0])) == 0) {
if (size == screenFontMapSize) {
free(sfm.entries);
} else {
free(screenFontMapTable);
screenFontMapTable = sfm.entries;
screenFontMapSize = size;
}
return 0;
}
}
free(screenFontMapTable);
}
screenFontMapTable = sfm.entries;
screenFontMapCount = sfm.entry_ct;
screenFontMapSize = size;
LogPrint(LOG_INFO, "Screen Font Map Size: %d", screenFontMapCount);
if (debugScreenFontMap) {
int i;
for (i=0; i<screenFontMapCount; ++i) {
const struct unipair *map = &screenFontMapTable[i];
LogPrint(LOG_DEBUG, "sfm[%03u]: unum=%4.4X fpos=%4.4X",
i, map->unicode, map->fontpos);
}
}
return 1;
}
static int vgaCharacterCount;
static int vgaLargeTable;
static int
setVgaCharacterCount (int force) {
int oldCount = vgaCharacterCount;
{
struct console_font_op cfo;
memset(&cfo, 0, sizeof(cfo));
cfo.op = KD_FONT_OP_GET;
cfo.height = 32;
cfo.width = 16;
if (controlConsole(KDFONTOP, &cfo) != -1) {
vgaCharacterCount = cfo.charcount;
} else {
vgaCharacterCount = 0;
if (errno != EINVAL) {
LogPrint(LOG_WARNING, "ioctl KDFONTOP[GET]: %s", strerror(errno));
}
}
}
if (!vgaCharacterCount) {
int index;
for (index=0; index<screenFontMapCount; ++index) {
const struct unipair *map = &screenFontMapTable[index];
if (vgaCharacterCount <= map->fontpos) vgaCharacterCount = map->fontpos +
1;
}
}
vgaCharacterCount = ((vgaCharacterCount - 1) | 0XFF) + 1;
vgaLargeTable = vgaCharacterCount > 0X100;
if (!force)
if (vgaCharacterCount == oldCount)
return 0;
LogPrint(LOG_INFO, "VGA Character Count: %d(%s)",
vgaCharacterCount,
vgaLargeTable? "large": "small");
return 1;
}
static int
prepare_LinuxScreen (char **parameters) {
validateYesNo(&debugApplicationCharacterMap, "debug application character map
flag", parameters[PARM_DEBUGACM]);
validateYesNo(&debugScreenFontMap, "debug screen font map flag",
parameters[PARM_DEBUGSFM]);
validateYesNo(&debugCharacterTranslationTable, "debug character translation
table flag", parameters[PARM_DEBUGCTT]);
setApplicationCharacterMap = &determineApplicationCharacterMap;
{
static const char *choices[] = {"auto", "iso01", "vt100", "cp437", "user",
NULL};
unsigned int choice;
if (validateChoice(&choice, "character set", parameters[PARM_ACM],
choices)) {
if (choice) {
static const unsigned short *maps[] = {iso01Map, vt100Map, cp437Map,
NULL};
const unsigned short *map = maps[choice-1];
if (map) {
memcpy(applicationCharacterMap, map, sizeof(applicationCharacterMap));
setApplicationCharacterMap = NULL;
logApplicationCharacterMap();
} else {
setApplicationCharacterMap = &getUserAcm;
}
}
}
}
if (setScreenPath()) {
screenDescriptor = -1;
if (setConsolePath()) {
consoleDescriptor = -1;
return 1;
}
}
return 0;
}
static int currentConsoleNumber;
static int
open_LinuxScreen (void) {
currentConsoleNumber = 0;
return openScreen(0);
}
/*
* The virtual screen devices return the actual font positions of the glyphs to
* be drawn on the screen. The problem is that the font may not have been
* designed for the character set being used. Most PC video cards have a
* built-in font defined for the CP437 character set, but Linux users often use
* the ISO-Latin-1 character set. In addition, the PSF format used by the newer
* font files, which contains an internal unicode to font-position table,
* allows the actual font positions to be unrelated to any known character set.
* The kernel translates each character to be written to the screen from the
* character set being used into unicode, and then from unicode into the
* position within the font being used of the glyph to be drawn on the screen.
* We need to reverse this translation in order to get the character code in
* the expected character set.
*/
static unsigned char translationTable[0X200];
static int
setTranslationTable (int force) {
int acmChanged = setApplicationCharacterMap &&
setApplicationCharacterMap(force);
int sfmChanged = setScreenFontMap(force);
int vccChanged = (sfmChanged || force)? setVgaCharacterCount(force): 0;
if (acmChanged || sfmChanged || vccChanged) {
unsigned short directPosition = 0XFF;
if (vgaLargeTable) directPosition |= 0X100;
memset(translationTable, '?', sizeof(translationTable));
{
int character;
for (character=0XFF; character>=0; --character) {
unsigned short unicode = applicationCharacterMap[character];
int position = -1;
if (!screenFontMapCount) {
if (unicode < 0X100) position = unicode;
} else if ((unicode & ~directPosition) == 0XF000) {
position = unicode & directPosition;
} else {
int first = 0;
int last = screenFontMapCount-1;
while (first <= last) {
int current = (first + last) / 2;
struct unipair *map = &screenFontMapTable[current];
if (map->unicode < unicode)
first = current + 1;
else if (map->unicode > unicode)
last = current - 1;
else {
if (map->fontpos < vgaCharacterCount) position = map->fontpos;
break;
}
}
}
if (position < 0) {
if (debugCharacterTranslationTable) {
LogPrint(LOG_DEBUG, "No character mapping: char=%2.2X unum=%4.4X",
character, unicode);
}
} else {
translationTable[position] = character;
if (debugCharacterTranslationTable) {
LogPrint(LOG_DEBUG, "Character mapping: char=%2.2X unum=%4.4X
fpos=%2.2X",
character, unicode, position);
}
}
}
}
if (debugCharacterTranslationTable) {
const unsigned int count = 0X10;
int position;
for (position=0; position<vgaCharacterCount; position+=count) {
char description[0X20];
sprintf(description, "c2f[%02X]", position);
LogBytes(description, &translationTable[position], count);
}
}
return 1;
}
return 0;
}
static int
setup_LinuxScreen (void) {
if (setTranslationTable(1)) {
return 1;
}
return 0;
}
static void
close_LinuxScreen (void) {
closeConsole();
closeScreen();
}
static int
uservt_LinuxScreen (int number) {
return MAX_NR_CONSOLES + 1 + number;
}
static int
getScreenDescription (ScreenDescription *description) {
if (!problemText) {
if (lseek(screenDescriptor, 0, SEEK_SET) != -1) {
unsigned char buffer[4];
int count = read(screenDescriptor, buffer, sizeof(buffer));
if (count == sizeof(buffer)) {
description->rows = buffer[0];
description->cols = buffer[1];
description->posx = buffer[2];
description->posy = buffer[3];
return 1;
} else if (count == -1) {
LogError("Screen header read");
} else {
long int expected = sizeof(buffer);
LogPrint(LOG_ERR, "Truncated screen header: expected %ld bytes, read
%d.",
expected, count);
}
} else {
LogError("Screen seek");
}
problemText = "screen header read error";
}
description->rows = 1;
description->cols = strlen(problemText);
description->posx = 0;
description->posy = 0;
return 0;
}
static int
getConsoleDescription (ScreenDescription *description) {
if (virtualTerminal) {
description->no = virtualTerminal;
} else {
struct vt_stat state;
if (controlConsole(VT_GETSTATE, &state) == -1) {
LogError("ioctl VT_GETSTATE");
description->no = 0;
problemText = "can't get virtual terminal number";
return 0;
}
description->no = state.v_active;
if (currentConsoleNumber && (description->no != currentConsoleNumber) &&
!rebindConsole()) {
problemText = "can't access console";
return 0;
}
currentConsoleNumber = description->no;
}
{
int mode;
if (controlConsole(KDGETMODE, &mode) == -1) {
LogError("ioctl KDGETMODE");
} else if (mode == KD_TEXT) {
problemText = NULL;
return 1;
}
problemText = "screen not in text mode";
return 0;
}
}
static void
describe_LinuxScreen (ScreenDescription *description) {
getConsoleDescription(description);
getScreenDescription(description);
/* Periodically recalculate font mapping. I don't know any way to be
* notified when it changes, and the recalculation is not too
* long/difficult.
*/
{
static int timer = 0;
if (++timer > 100) {
setTranslationTable(0);
timer = 0;
}
}
}
static int
read_LinuxScreen (ScreenBox box, unsigned char *buffer, ScreenMode mode) {
ScreenDescription description;
describe_LinuxScreen(&description);
if (validateScreenBox(&box, description.cols, description.rows)) {
int text = mode == SCR_TEXT;
if (problemText) {
if (text) {
memcpy(buffer, problemText+box.left, box.width);
} else {
memset(buffer, 0X07, box.width);
}
return 1;
}
{
off_t start = 4 + (box.top * description.cols + box.left) * 2;
if (lseek(screenDescriptor, start, SEEK_SET) != -1) {
int length = box.width * 2;
unsigned char line[length];
unsigned char *target = buffer;
off_t increment = description.cols * 2 - length;
int row;
for (row=0; row<box.height; ++row) {
int count;
unsigned char *source;
if (row) {
if (lseek(screenDescriptor, increment, SEEK_CUR) == -1) {
LogError("Screen seek");
return 0;
}
}
count = read(screenDescriptor, line, length);
if (count != length) {
if (count == -1) {
LogError("Screen data read");
} else {
LogPrint(LOG_ERR, "Truncated screen data: expected %d bytes, read
%d.",
length, count);
}
return 0;
}
source = line;
if (text) {
unsigned char src[box.width];
unsigned char *trg = target;
int column;
for (column=0; column<box.width; ++column) {
int position = *source;
if (vgaLargeTable)
if (source[1] & 0X08)
position |= 0X100;
src[column] = *source;
*target++ = translationTable[position];
source += 2;
}
if (debugScreenTextTranslation) {
char desc[0X20];
sprintf(desc, "fpos[%03d,%03d]", box.left, box.top+row);
LogBytes(desc, src, box.width);
memcpy(desc, "char", 4);
LogBytes(desc, trg, box.width);
}
} else {
int column;
source++;
for (column=0; column<box.width; ++column) {
if (vgaLargeTable) *source &= 0XF7;
*target++ = *source;
source += 2;
}
}
}
return 1;
} else {
LogError("Screen seek");
}
}
} else {
LogPrint(LOG_ERR, "Invalid screen area: cols=%d left=%d width=%d rows=%d
top=%d height=%d",
description.cols, box.left, box.width,
description.rows, box.top, box.height);
}
return 0;
}
static int
insertByte (unsigned char byte) {
if (controlConsole(TIOCSTI, &byte) != -1) {
return 1;
} else {
LogError("ioctl TIOCSTI");
}
return 0;
}
static int
insertCode (ScreenKey key, int raw) {
unsigned char prefix = 0X00;
unsigned char code;
int modShift = 0;
int modControl = 0;
int modMeta = 0;
if (key < SCR_KEY_ENTER) {
if (key & SCR_KEY_MOD_META) {
key &= ~SCR_KEY_MOD_META;
modMeta = 1;
}
if ((key >= 'A') && (key <= 'Z')) {
key = (key - 'A') + 'a';
modShift = 1;
} else if (!(key & 0XE0)) {
key |= 0X60;
modControl = 1;
}
}
switch (key) {
case SCR_KEY_ESCAPE: code = 0X01; break;
case SCR_KEY_FUNCTION + 0: code = 0X3B; break;
case SCR_KEY_FUNCTION + 1: code = 0X3C; break;
case SCR_KEY_FUNCTION + 2: code = 0X3D; break;
case SCR_KEY_FUNCTION + 3: code = 0X3E; break;
case SCR_KEY_FUNCTION + 4: code = 0X3F; break;
case SCR_KEY_FUNCTION + 5: code = 0X40; break;
case SCR_KEY_FUNCTION + 6: code = 0X41; break;
case SCR_KEY_FUNCTION + 7: code = 0X42; break;
case SCR_KEY_FUNCTION + 8: code = 0X43; break;
case SCR_KEY_FUNCTION + 9: code = 0X44; break;
case SCR_KEY_FUNCTION + 10: code = 0X57; break;
case SCR_KEY_FUNCTION + 11: code = 0X58; break;
case '`': code = 0X29; break;
case '1': code = 0X02; break;
case '2': code = 0X03; break;
case '3': code = 0X04; break;
case '4': code = 0X05; break;
case '5': code = 0X06; break;
case '6': code = 0X07; break;
case '7': code = 0X08; break;
case '8': code = 0X09; break;
case '9': code = 0X0A; break;
case '0': code = 0X0B; break;
case '-': code = 0X0C; break;
case '=': code = 0X0D; break;
case SCR_KEY_BACKSPACE: code = 0X0E; break;
case SCR_KEY_TAB: code = 0X0F; break;
case 'q': code = 0X10; break;
case 'w': code = 0X11; break;
case 'e': code = 0X12; break;
case 'r': code = 0X13; break;
case 't': code = 0X14; break;
case 'y': code = 0X15; break;
case 'u': code = 0X16; break;
case 'i': code = 0X17; break;
case 'o': code = 0X18; break;
case 'p': code = 0X19; break;
case '[': code = 0X1A; break;
case ']': code = 0X1B; break;
case '\\': code = 0X2B; break;
case 'a': code = 0X1E; break;
case 's': code = 0X1F; break;
case 'd': code = 0X20; break;
case 'f': code = 0X21; break;
case 'g': code = 0X22; break;
case 'h': code = 0X23; break;
case 'j': code = 0X24; break;
case 'k': code = 0X25; break;
case 'l': code = 0X26; break;
case ';': code = 0X27; break;
case '\'': code = 0X28; break;
case SCR_KEY_ENTER: code = 0X1C; break;
case 'z': code = 0X2C; break;
case 'x': code = 0X2D; break;
case 'c': code = 0X2E; break;
case 'v': code = 0X2F; break;
case 'b': code = 0X30; break;
case 'n': code = 0X31; break;
case 'm': code = 0X32; break;
case ',': code = 0X33; break;
case '.': code = 0X34; break;
case '/': code = 0X35; break;
case ' ': code = 0X39; break;
default:
if (raw) {
prefix = 0XE0;
switch (key) {
case SCR_KEY_INSERT: code = 0X52; break;
case SCR_KEY_HOME: code = 0X47; break;
case SCR_KEY_PAGE_UP: code = 0X49; break;
case SCR_KEY_DELETE: code = 0X53; break;
case SCR_KEY_END: code = 0X4F; break;
case SCR_KEY_PAGE_DOWN: code = 0X51; break;
case SCR_KEY_CURSOR_UP: code = 0X48; break;
case SCR_KEY_CURSOR_LEFT: code = 0X4B; break;
case SCR_KEY_CURSOR_DOWN: code = 0X50; break;
case SCR_KEY_CURSOR_RIGHT: code = 0X4D; break;
default:
LogPrint(LOG_WARNING, "Key %4.4X not suported in scancode mode.",
key);
return 0;
}
} else {
switch (key) {
case SCR_KEY_INSERT: code = 0X6E; break;
case SCR_KEY_HOME: code = 0X66; break;
case SCR_KEY_PAGE_UP: code = 0X68; break;
case SCR_KEY_DELETE: code = 0X6F; break;
case SCR_KEY_END: code = 0X6B; break;
case SCR_KEY_PAGE_DOWN: code = 0X6D; break;
case SCR_KEY_CURSOR_UP: code = 0X67; break;
case SCR_KEY_CURSOR_LEFT: code = 0X69; break;
case SCR_KEY_CURSOR_DOWN: code = 0X6C; break;
case SCR_KEY_CURSOR_RIGHT: code = 0X6A; break;
default:
LogPrint(LOG_WARNING, "Key %4.4X not suported in keycode mode.",
key);
return 0;
}
}
break;
}
{
unsigned char buffer[10];
unsigned short count = 0;
const unsigned char *byte = buffer;
if (modControl) buffer[count++] = 0X1D;
if (modMeta) buffer[count++] = 0X38;
if (modShift) buffer[count++] = 0X2A;
if (prefix) buffer[count++] = prefix;
buffer[count++] = code;
if (prefix) buffer[count++] = prefix;
buffer[count++] = code | 0X80;
if (modShift) buffer[count++] = 0X2A | 0X80;
if (modMeta) buffer[count++] = 0X38 | 0X80;
if (modControl) buffer[count++] = 0X1D | 0X80;
while (count--) {
if (!insertByte(*byte++)) return 0;
}
}
return 1;
}
static int
insertMapped (ScreenKey key, int (*byteInserter)(unsigned char byte)) {
char buffer[2];
char *sequence;
char *end;
if (key < SCR_KEY_ENTER) {
sequence = end = buffer + sizeof(buffer);
*--sequence = key & 0XFF;
if (key & SCR_KEY_MOD_META) {
int meta;
if (controlConsole(KDGKBMETA, &meta) == -1) return 0;
switch (meta) {
case K_METABIT:
*sequence |= 0X80;
break;
case K_ESCPREFIX:
*--sequence = 0X1B;
break;
default:
LogPrint(LOG_WARNING, "Unsupported keyboard meta mode: %d", meta);
return 0;
}
}
} else {
switch (key) {
case SCR_KEY_ENTER:
sequence = "\r";
break;
case SCR_KEY_TAB:
sequence = "\t";
break;
case SCR_KEY_BACKSPACE:
sequence = "\x7f";
break;
case SCR_KEY_ESCAPE:
sequence = "\x1b";
break;
case SCR_KEY_CURSOR_LEFT:
sequence = "\x1b[D";
break;
case SCR_KEY_CURSOR_RIGHT:
sequence = "\x1b[C";
break;
case SCR_KEY_CURSOR_UP:
sequence = "\x1b[A";
break;
case SCR_KEY_CURSOR_DOWN:
sequence = "\x1b[B";
break;
case SCR_KEY_PAGE_UP:
sequence = "\x1b[5~";
break;
case SCR_KEY_PAGE_DOWN:
sequence = "\x1b[6~";
break;
case SCR_KEY_HOME:
sequence = "\x1b[1~";
break;
case SCR_KEY_END:
sequence = "\x1b[4~";
break;
case SCR_KEY_INSERT:
sequence = "\x1b[2~";
break;
case SCR_KEY_DELETE:
sequence = "\x1b[3~";
break;
case SCR_KEY_FUNCTION + 1:
sequence = "\x1b[[[A";
break;
case SCR_KEY_FUNCTION + 2:
sequence = "\x1b[[[B";
break;
case SCR_KEY_FUNCTION + 3:
sequence = "\x1b[[[C";
break;
case SCR_KEY_FUNCTION + 4:
sequence = "\x1b[[[D";
break;
case SCR_KEY_FUNCTION + 5:
sequence = "\x1b[[[E";
break;
case SCR_KEY_FUNCTION + 6:
sequence = "\x1b[17~";
break;
case SCR_KEY_FUNCTION + 7:
sequence = "\x1b[18~";
break;
case SCR_KEY_FUNCTION + 8:
sequence = "\x1b[19~";
break;
case SCR_KEY_FUNCTION + 9:
sequence = "\x1b[20~";
break;
case SCR_KEY_FUNCTION + 10:
sequence = "\x1b[21~";
break;
case SCR_KEY_FUNCTION + 11:
sequence = "\x1b[23~";
break;
case SCR_KEY_FUNCTION + 12:
sequence = "\x1b[24~";
break;
case SCR_KEY_FUNCTION + 13:
sequence = "\x1b[25~";
break;
case SCR_KEY_FUNCTION + 14:
sequence = "\x1b[26~";
break;
case SCR_KEY_FUNCTION + 15:
sequence = "\x1b[28~";
break;
case SCR_KEY_FUNCTION + 16:
sequence = "\x1b[29~";
break;
case SCR_KEY_FUNCTION + 17:
sequence = "\x1b[31~";
break;
case SCR_KEY_FUNCTION + 18:
sequence = "\x1b[32~";
break;
case SCR_KEY_FUNCTION + 19:
sequence = "\x1b[33~";
break;
case SCR_KEY_FUNCTION + 20:
sequence = "\x1b[34~";
break;
default:
LogPrint(LOG_WARNING, "Key %4.4X not suported in ANSI mode.", key);
return 0;
}
end = sequence + strlen(sequence);
}
while (sequence != end)
if (!byteInserter(*sequence++))
return 0;
return 1;
}
static int
insertUtf8 (unsigned char byte) {
if (byte & 0X80) {
if (!insertByte(0XC0 | (byte >> 6))) return 0;
byte &= 0XBF;
}
if (!insertByte(byte)) return 0;
return 1;
}
static int
insert_LinuxScreen (ScreenKey key) {
int ok = 0;
LogPrint(LOG_DEBUG, "Insert key: %4.4X", key);
if (rebindConsole()) {
int mode;
if (controlConsole(KDGKBMODE, &mode) != -1) {
switch (mode) {
case K_RAW:
if (insertCode(key, 1)) ok = 1;
break;
case K_MEDIUMRAW:
if (insertCode(key, 0)) ok = 1;
break;
case K_XLATE:
if (insertMapped(key, &insertByte)) ok = 1;
break;
case K_UNICODE:
if (insertMapped(key, &insertUtf8)) ok = 1;
break;
default:
LogPrint(LOG_WARNING, "Unsupported keyboard mode: %d", mode);
break;
}
} else {
LogError("ioctl KDGKBMODE");
}
}
return ok;
}
static int
validateVt (int vt) {
if ((vt >= 1) && (vt <= 0X3F)) return 1;
LogPrint(LOG_DEBUG, "Virtual terminal %d is out of range.", vt);
return 0;
}
static int
selectvt_LinuxScreen (int vt) {
if (vt == virtualTerminal) return 1;
if (vt && !validateVt(vt)) return 0;
return openScreen(vt);
}
static int
switchvt_LinuxScreen (int vt) {
if (validateVt(vt)) {
if (selectvt_LinuxScreen(0)) {
if (ioctl(consoleDescriptor, VT_ACTIVATE, vt) != -1) {
LogPrint(LOG_DEBUG, "Switched to virtual tertminal %d.", vt);
return 1;
} else {
LogError("ioctl VT_ACTIVATE");
}
}
}
return 0;
}
static int
currentvt_LinuxScreen (void) {
ScreenDescription description;
getConsoleDescription(&description);
return description.no;
}
#ifdef HAVE_LINUX_INPUT_H
#include <linux/input.h>
typedef unsigned char At2KeyTable[0X100];
static const At2KeyTable at2KeysOriginal = {
[0X76] = KEY_ESC,
[0X05] = KEY_F1,
[0X06] = KEY_F2,
[0X04] = KEY_F3,
[0X0C] = KEY_F4,
[0X03] = KEY_F5,
[0X0B] = KEY_F6,
[0X83] = KEY_F7,
[0X0A] = KEY_F8,
[0X01] = KEY_F9,
[0X09] = KEY_F10,
[0X78] = KEY_F11,
[0X07] = KEY_F12,
[0X7E] = KEY_SCROLLLOCK,
[0X0E] = KEY_GRAVE,
[0X16] = KEY_1,
[0X1E] = KEY_2,
[0X26] = KEY_3,
[0X25] = KEY_4,
[0X2E] = KEY_5,
[0X36] = KEY_6,
[0X3D] = KEY_7,
[0X3E] = KEY_8,
[0X46] = KEY_9,
[0X45] = KEY_0,
[0X4E] = KEY_MINUS,
[0X55] = KEY_EQUAL,
[0X66] = KEY_BACKSPACE,
[0X0D] = KEY_TAB,
[0X15] = KEY_Q,
[0X1D] = KEY_W,
[0X24] = KEY_E,
[0X2D] = KEY_R,
[0X2C] = KEY_T,
[0X35] = KEY_Y,
[0X3C] = KEY_U,
[0X43] = KEY_I,
[0X44] = KEY_O,
[0X4D] = KEY_P,
[0X54] = KEY_LEFTBRACE,
[0X5B] = KEY_RIGHTBRACE,
[0X5D] = KEY_BACKSLASH,
[0X58] = KEY_CAPSLOCK,
[0X1C] = KEY_A,
[0X1B] = KEY_S,
[0X23] = KEY_D,
[0X2B] = KEY_F,
[0X34] = KEY_G,
[0X33] = KEY_H,
[0X3B] = KEY_J,
[0X42] = KEY_K,
[0X4B] = KEY_L,
[0X4C] = KEY_SEMICOLON,
[0X52] = KEY_APOSTROPHE,
[0X5A] = KEY_ENTER,
[0X12] = KEY_LEFTSHIFT,
[0X61] = KEY_102ND,
[0X1A] = KEY_Z,
[0X22] = KEY_X,
[0X21] = KEY_C,
[0X2A] = KEY_V,
[0X32] = KEY_B,
[0X31] = KEY_N,
[0X3A] = KEY_M,
[0X41] = KEY_COMMA,
[0X49] = KEY_DOT,
[0X4A] = KEY_SLASH,
[0X59] = KEY_RIGHTSHIFT,
[0X14] = KEY_LEFTCTRL,
[0X11] = KEY_LEFTALT,
[0X29] = KEY_SPACE,
[0X77] = KEY_NUMLOCK,
[0X7C] = KEY_KPASTERISK,
[0X7B] = KEY_KPMINUS,
[0X79] = KEY_KPPLUS,
[0X71] = KEY_KPDOT,
[0X70] = KEY_KP0,
[0X69] = KEY_KP1,
[0X72] = KEY_KP2,
[0X7A] = KEY_KP3,
[0X6B] = KEY_KP4,
[0X73] = KEY_KP5,
[0X74] = KEY_KP6,
[0X6C] = KEY_KP7,
[0X75] = KEY_KP8,
[0X7D] = KEY_KP9
};
static const At2KeyTable at2KeysE0 = {
[0X1F] = KEY_LEFTMETA,
[0X11] = KEY_RIGHTALT,
[0X27] = KEY_RIGHTMETA,
[0X2F] = KEY_COMPOSE,
[0X14] = KEY_RIGHTCTRL,
[0X70] = KEY_INSERT,
[0X71] = KEY_DELETE,
[0X6C] = KEY_HOME,
[0X69] = KEY_END,
[0X7D] = KEY_PAGEUP,
[0X7A] = KEY_PAGEDOWN,
[0X75] = KEY_UP,
[0X6B] = KEY_LEFT,
[0X72] = KEY_DOWN,
[0X74] = KEY_RIGHT,
[0X4A] = KEY_KPSLASH,
[0X5A] = KEY_KPENTER
};
static const unsigned char *at2Keys;
static int at2Pressed;
#endif /* HAVE_LINUX_INPUT_H */
#ifdef HAVE_LINUX_UINPUT_H
#include <linux/uinput.h>
static int uinputDevice = -1;
static int
openUinputDevice (void) {
if (uinputDevice != -1) return 1;
if ((uinputDevice = openDevice("/dev/uinput", "uinput", O_WRONLY, 10, 223))
!= -1) {
struct uinput_user_dev device;
memset(&device, 0, sizeof(device));
strcpy(device.name, "brltty");
if (write(uinputDevice, &device, sizeof(device)) == sizeof(device)) {
ioctl(uinputDevice, UI_SET_EVBIT, EV_KEY);
ioctl(uinputDevice, UI_SET_EVBIT, EV_REP);
{
int key;
for (key=KEY_RESERVED; key<KEY_UNKNOWN; key++) {
ioctl(uinputDevice, UI_SET_KEYBIT, key);
}
}
if (ioctl(uinputDevice, UI_DEV_CREATE) != -1) {
return 1;
} else {
LogError("ioctl UI_DEV_CREATE");
}
} else {
LogError("uinput_user_dev write");
}
close(uinputDevice);
uinputDevice = -1;
}
return 0;
}
#endif /* HAVE_LINUX_UINPUT_H */
static int
execute_LinuxScreen (int command) {
int blk = command & BRL_MSK_BLK;
int arg
#ifdef HAVE_ATTRIBUTE_UNUSED
__attribute__((unused))
#endif /* HAVE_ATTRIBUTE_UNUSED */
= command & BRL_MSK_ARG;
switch (blk) {
case BRL_BLK_PASSAT2:
#ifdef HAVE_LINUX_INPUT_H
if (arg == 0XF0) {
at2Pressed = 0;
} else if (arg == 0XE0) {
at2Keys = at2KeysE0;
} else {
unsigned char key = at2Keys[arg];
int pressed
#ifdef HAVE_ATTRIBUTE_UNUSED
__attribute__((unused))
#endif /* HAVE_ATTRIBUTE_UNUSED */
= at2Pressed;
at2Keys = at2KeysOriginal;
at2Pressed = 1;
if (key) {
#ifdef HAVE_LINUX_UINPUT_H
if (openUinputDevice()) {
struct input_event event;
event.type = EV_KEY;
event.code = key;
event.value = pressed;
write(uinputDevice, &event, sizeof(event));
return 1;
}
#endif /* HAVE_LINUX_UINPUT_H */
}
}
#endif /* HAVE_LINUX_INPUT_H */
break;
}
return 0;
}
static void
scr_initialize (MainScreen *main) {
initializeRealScreen(main);
main->base.describe = describe_LinuxScreen;
main->base.read = read_LinuxScreen;
main->base.insert = insert_LinuxScreen;
main->base.selectvt = selectvt_LinuxScreen;
main->base.switchvt = switchvt_LinuxScreen;
main->base.currentvt = currentvt_LinuxScreen;
main->base.execute = execute_LinuxScreen;
main->prepare = prepare_LinuxScreen;
main->open = open_LinuxScreen;
main->setup = setup_LinuxScreen;
main->close = close_LinuxScreen;
main->uservt = uservt_LinuxScreen;
#ifdef HAVE_LINUX_INPUT_H
at2Keys = at2KeysOriginal;
at2Pressed = 1;
#endif /* HAVE_LINUX_INPUT_H */
}
_______________________________________________
Liste de diffusion CarrefourBLinuX
[email protected]
http://lists.freearchive.org/mailman/listinfo/carrefourblinux
Fiches EDU : http://blinuxwiki.pbwiki.com/FichesEdu
Signets : http://fr.groups.yahoo.com/group/carrefourblinux/links/
Archives : http://lists.freearchive.org/pipermail//carrefourblinux
Anciennes archives (Yahoogroupes) :
http://fr.groups.yahoo.com/group/carrefourblinux/messages
Rechercher : http://lists.freearchive.org/cgi-bin/search.cgi
Pour s'inscire par courriel :
'mailto:[EMAIL PROTECTED]'
Pour se desinscrire par courriel :
'mailto:[EMAIL PROTECTED]'