Merge in "keycodes" support from Basilisk II. e.g. make French keyboard

layout work correctly for me.
This commit is contained in:
gbeauche 2003-11-21 17:01:33 +00:00
parent 45df157a5e
commit 1dbe1179c6
5 changed files with 164 additions and 16 deletions

View File

@ -44,6 +44,7 @@ static bool start_clicked = true; // Return value of PrefsEditor() function
// Prototypes
static void create_volumes_pane(GtkWidget *top);
static void create_graphics_pane(GtkWidget *top);
static void create_input_pane(GtkWidget *top);
static void create_serial_pane(GtkWidget *top);
static void create_memory_pane(GtkWidget *top);
static void read_settings(void);
@ -170,6 +171,11 @@ static GtkWidget *make_entry(GtkWidget *top, int label_id, const char *prefs_ite
return entry;
}
static char *get_file_entry_path(GtkWidget *entry)
{
return gtk_entry_get_text(GTK_ENTRY(entry));
}
static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func)
{
GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
@ -313,6 +319,7 @@ bool PrefsEditor(void)
create_volumes_pane(notebook);
create_graphics_pane(notebook);
create_input_pane(notebook);
create_serial_pane(notebook);
create_memory_pane(notebook);
@ -630,6 +637,50 @@ static void create_graphics_pane(GtkWidget *top)
}
/*
* "Input" pane
*/
static GtkWidget *w_keycode_file;
// Set sensitivity of widgets
static void set_input_sensitive(void)
{
gtk_widget_set_sensitive(w_keycode_file, PrefsFindBool("keycodes"));
}
// "Use Raw Keycodes" button toggled
static void tb_keycodes(GtkWidget *widget)
{
PrefsReplaceBool("keycodes", GTK_TOGGLE_BUTTON(widget)->active);
set_input_sensitive();
}
// Read settings from widgets and set preferences
static void read_input_settings(void)
{
const char *str = get_file_entry_path(w_keycode_file);
if (str && strlen(str))
PrefsReplaceString("keycodefile", str);
else
PrefsRemoveItem("keycodefile");
}
// Create "Input" pane
static void create_input_pane(GtkWidget *top)
{
GtkWidget *box, *hbox, *menu, *label;
GtkObject *adj;
box = make_pane(top, STR_INPUT_PANE_TITLE);
make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
w_keycode_file = make_entry(box, STR_KEYCODE_FILE_CTRL, "keycodefile");
set_input_sensitive();
}
/*
* "Serial/Network" pane
*/

View File

@ -30,6 +30,8 @@
// Platform-specific preferences items
prefs_desc platform_prefs_items[] = {
{"ether", TYPE_STRING, false, "device name of Mac ethernet adapter"},
{"keycodes", TYPE_BOOLEAN, false, "use keycodes rather than keysyms to decode keyboard"},
{"keycodefile", TYPE_STRING, false, "path of keycode translation file"},
{NULL, TYPE_END, false, NULL} // End of list
};
@ -91,6 +93,7 @@ void SavePrefs(void)
void AddPlatformPrefsDefaults(void)
{
PrefsAddBool("keycodes", false);
PrefsReplaceString("extfs", "/");
PrefsAddInt32("windowmodes", 3);
PrefsAddInt32("screenmodes", 0x3f);

View File

@ -55,6 +55,8 @@ user_string_def platform_strings[] = {
{STR_AUDIO_FORMAT_WARN, "/dev/dsp doesn't support signed 16 bit format. Audio output will be disabled."},
{STR_SCSI_DEVICE_OPEN_WARN, "Cannot open %s (%s). SCSI Manager access to this device will be disabled."},
{STR_SCSI_DEVICE_NOT_SCSI_WARN, "%s doesn't seem to comply to the Generic SCSI API. SCSI Manager access to this device will be disabled."},
{STR_KEYCODE_FILE_WARN, "Cannot open keycode translation file %s (%s)."},
{STR_KEYCODE_VENDOR_WARN, "Cannot find vendor '%s' in keycode translation file %s."},
{STR_PREFS_MENU_FILE_GTK, "/_File"},
{STR_PREFS_ITEM_START_GTK, "/File/_Start SheepShaver"},
{STR_PREFS_ITEM_ZAP_PRAM_GTK, "/File/_Zap PRAM File"},
@ -62,6 +64,9 @@ user_string_def platform_strings[] = {
{STR_PREFS_ITEM_QUIT_GTK, "/File/_Quit SheepShaver"},
{STR_HELP_MENU_GTK, "/_Help"},
{STR_HELP_ITEM_ABOUT_GTK, "/Help/_About SheepShaver"},
{STR_INPUT_PANE_TITLE, "Keyboard"},
{STR_KEYCODES_CTRL, "Use Raw Keycodes"},
{STR_KEYCODE_FILE_CTRL, "Keycode Translation File"},
{STR_SUSPEND_WINDOW_TITLE, "SheepShaver suspended. Press Space to reactivate."},
{STR_VOSF_INIT_ERR, "Cannot initialize Video on SEGV signals."},

View File

@ -37,6 +37,8 @@ enum {
STR_NO_XSERVER_ERR,
STR_NO_XVISUAL_ERR,
STR_UNSUPP_DEPTH_ERR,
STR_VOSF_INIT_ERR,
STR_PROC_CPUINFO_WARN,
STR_NO_SHEEP_NET_DRIVER_WARN,
STR_SHEEP_NET_ATTACH_WARN,
@ -46,6 +48,9 @@ enum {
STR_AUDIO_FORMAT_WARN,
STR_SCSI_DEVICE_OPEN_WARN,
STR_SCSI_DEVICE_NOT_SCSI_WARN,
STR_KEYCODE_FILE_WARN,
STR_KEYCODE_VENDOR_WARN,
STR_PREFS_MENU_FILE_GTK,
STR_PREFS_ITEM_START_GTK,
STR_PREFS_ITEM_ZAP_PRAM_GTK,
@ -54,7 +59,9 @@ enum {
STR_HELP_MENU_GTK,
STR_HELP_ITEM_ABOUT_GTK,
STR_SUSPEND_WINDOW_TITLE,
STR_VOSF_INIT_ERR
STR_INPUT_PANE_TITLE,
STR_KEYCODES_CTRL,
STR_KEYCODE_FILE_CTRL
};
#endif

View File

@ -18,15 +18,28 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XShm.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
#include <errno.h>
#ifdef HAVE_PTHREADS
# include <pthread.h>
#endif
#ifdef ENABLE_XF86_DGA
#include <X11/extensions/xf86dga.h>
#endif
#ifdef ENABLE_XF86_VIDMODE
# include <X11/extensions/xf86vmode.h>
#endif
#include "sysdeps.h"
#include "main.h"
#include "adb.h"
#include "prefs.h"
@ -38,14 +51,9 @@
#define DEBUG 0
#include "debug.h"
#ifdef ENABLE_XF86_DGA
#include <X11/extensions/xf86dga.h>
#endif
#ifdef ENABLE_XF86_VIDMODE
#include <X11/extensions/xf86vmode.h>
#endif
// Constants
const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes";
// Global variables
static int32 frame_skip;
@ -74,6 +82,8 @@ static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit req
static bool emul_suspended = false; // Flag: emulator suspended
static Window suspend_win; // "Suspend" window
static void *fb_save = NULL; // Saved frame buffer for suspend
static bool use_keycodes = false; // Flag: Use keycodes rather than keysyms
static int keycode_table[256]; // X keycode -> Mac keycode translation table
// X11 variables
static int screen; // Screen number
@ -534,6 +544,71 @@ static void close_display(void)
* Initialization
*/
// Init keycode translation table
static void keycode_init(void)
{
bool use_kc = PrefsFindBool("keycodes");
if (use_kc) {
// Get keycode file path from preferences
const char *kc_path = PrefsFindString("keycodefile");
// Open keycode table
FILE *f = fopen(kc_path ? kc_path : KEYCODE_FILE_NAME, "r");
if (f == NULL) {
char str[256];
sprintf(str, GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno));
WarningAlert(str);
return;
}
// Default translation table
for (int i=0; i<256; i++)
keycode_table[i] = -1;
// Search for server vendor string, then read keycodes
const char *vendor = ServerVendor(x_display);
bool vendor_found = false;
char line[256];
while (fgets(line, 255, f)) {
// Read line
int len = strlen(line);
if (len == 0)
continue;
line[len-1] = 0;
// Comments begin with "#" or ";"
if (line[0] == '#' || line[0] == ';' || line[0] == 0)
continue;
if (vendor_found) {
// Read keycode
int x_code, mac_code;
if (sscanf(line, "%d %d", &x_code, &mac_code) == 2)
keycode_table[x_code & 0xff] = mac_code;
else
break;
} else {
// Search for vendor string
if (strstr(vendor, line) == vendor)
vendor_found = true;
}
}
// Keycode file completely read
fclose(f);
use_keycodes = vendor_found;
// Vendor not found? Then display warning
if (!vendor_found) {
char str[256];
sprintf(str, GetString(STR_KEYCODE_VENDOR_WARN), vendor, kc_path ? kc_path : KEYCODE_FILE_NAME);
WarningAlert(str);
return;
}
}
}
static void add_mode(VideoInfo *&p, uint32 allow, uint32 test, long apple_mode, long apple_id, int type)
{
if (allow & test) {
@ -607,6 +682,9 @@ bool VideoInit(void)
local_X11 = (strncmp(XDisplayName(x_display_name), ":", 1) == 0)
|| (strncmp(XDisplayName(x_display_name), "unix:", 5) == 0);
// Init keycode translation
keycode_init();
// Init variables
private_data = NULL;
cur_mode = 0; // Window 640x480
@ -1078,14 +1156,14 @@ static int kc_decode(KeySym ks)
return -1;
}
static int event2keycode(XKeyEvent *ev)
static int event2keycode(XKeyEvent &ev)
{
KeySym ks;
int as;
int i = 0;
do {
ks = XLookupKeysym(ev, i++);
ks = XLookupKeysym(&ev, i++);
as = kc_decode(ks);
if (as != -1)
return as;
@ -1128,8 +1206,10 @@ static void handle_events(void)
// Keyboard
case KeyPress: {
int code;
if ((code = event2keycode((XKeyEvent *)&event)) != -1) {
int code = event2keycode(event.xkey);
if (use_keycodes && code != -1)
code = keycode_table[event.xkey.keycode & 0xff];
if (code != -1) {
if (!emul_suspended) {
ADBKeyDown(code);
if (code == 0x36)
@ -1142,8 +1222,10 @@ static void handle_events(void)
break;
}
case KeyRelease: {
int code;
if ((code = event2keycode((XKeyEvent *)&event)) != -1) {
int code = event2keycode(event.xkey);
if (use_keycodes && code != 1)
code = keycode_table[event.xkey.keycode & 0xff];
if (code != -1) {
ADBKeyUp(code);
if (code == 0x36)
ctrl_down = false;