mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-01-12 01:30:03 +00:00
Merge in "keycodes" support from Basilisk II. e.g. make French keyboard
layout work correctly for me.
This commit is contained in:
parent
45df157a5e
commit
1dbe1179c6
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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."},
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user