* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
* Utility to create mapping from X keycodes to Allegro scancodes.
*
* By Michael Bukin, modified by Elias Pschernig.
*
* See readme.txt for copyright information.
*/
#include <stdio.h>
#include <allegro5.h>
#include <xalleg.h>
#include <allegro/internal/aintern.h>
#define FILENAME_LENGTH 1024
char unicode_description[256] = "";
static DIALOG main_dialog[];
static DIALOG keymap_dialog[];
static int black = 0;
static int white = 1;
static int red = 2;
static int yellow = 3;
static volatile int waiting_for_key = 0;
static volatile int new_keycode = 0;
static int keycode_to_scancode[256];
static void get_raw_keycode(int pressed, int keycode)
{
if (pressed && waiting_for_key) {
new_keycode = keycode;
waiting_for_key = 0;
}
}
static const char *keycode_getter(int index, int *list_size)
{
if (index >= 0) {
return scancode_to_name(index + 1);
}
else {
*list_size = KEY_MAX - 1;
return NULL;
}
}
static DIALOG keymap_dialog[] = {
{d_clear_proc, 0, 0, 250, 230, 0, 0, 0, 0, 0, 0, 0, NULL, NULL},
{d_ctext_proc, 125, 10, 0, 16, 0, 255, 0, 0, 0, 0, "Select Keycode:", NULL, NULL},
{d_list_proc, 0, 32, 230, 92, 0, 255, 0, D_EXIT, 0, 0, (void *)keycode_getter, NULL, NULL},
{d_ctext_proc, 125, 142, 0, 16, 0, 255, 0, 0, 0, 0, unicode_description, NULL, NULL},
{d_button_proc, 10, 164, 230, 16, 0, 255, 0, D_EXIT, 0, 0, "Define &X Key !", NULL, NULL},
{d_button_proc, 10, 186, 110, 16, 0, 255, 27, D_EXIT, 0, 0, "&Cancel", NULL, NULL},
{d_button_proc, 130, 186, 110, 16 , 0, 255, 0, D_EXIT, 0, 0, "&Done", NULL, NULL},
{d_ctext_proc, 125, 208, 0, 16, 0, 255, 0, 0, 0, 0, "", NULL, NULL},
{d_yield_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL},
{NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL}
};
static void setup_all_keys(void)
{
int focus = 2;
int i;
set_dialog_color(keymap_dialog, black, white);
centre_dialog(keymap_dialog);
while (1) {
focus = do_dialog(keymap_dialog, focus);
switch (focus) {
case 2:
case 4:
textprintf_centre_ex (screen, font,
keymap_dialog[7].x, keymap_dialog[7].y, red, -1,
"Press a key to map to the current scancode");
textprintf_centre_ex (screen, font,
keymap_dialog[7].x, keymap_dialog[7].y + 8, red, -1,
"(or a mouse button to leave it unchanged)");
new_keycode = -1;
waiting_for_key = 1;
do {
poll_keyboard();
poll_mouse();
if (mouse_b)
waiting_for_key = 0;
}
while (waiting_for_key);
if ((new_keycode >= 0) && (new_keycode < 256)) {
keycode_to_scancode[new_keycode] = keymap_dialog[2].d1 + 1;
}
clear_keybuf();
break;
case 5:
return;
case 6:
for (i = 0; i < 256; i++) {
if (keycode_to_scancode[i] >= 0)
_xwin.keycode_to_scancode[i] = keycode_to_scancode[i];
}
return;
}
}
}
static void test_key_map(void)
{
int i, k, u;
static int key_was_pressed[KEY_MAX + 1] = {0};
static int key_is_pressed[KEY_MAX + 1] = {0};
static char *welcome[] = {
"Key that is pressed now is marked with red",
"Key that was pressed is marked with yellow",
"Press mouse button or Escape to exit test",
0
};
clear_to_color(screen, white);
for (i = 0; welcome[i] != 0; i++)
textout_ex(screen, font, welcome[i], 8, i * 8 + 8, black, -1);
clear_to_color(screen, white);
for (i = 0; i < KEY_MAX; i++)
textprintf_ex(screen, font, 32 + (i % 4) * 160,
32 + (i / 4) * 14, black, -1, "%s", scancode_to_name (i));
do {
poll_keyboard();
poll_mouse();
}
while ((key[KEY_ESC]) || (mouse_b));
do {
while (keypressed()) {
u = ureadkey (&k);
textprintf_centre_ex (screen, font, SCREEN_W / 2, 8,
red, white, "> %c <", u);
}
poll_keyboard();
poll_mouse();
for (i = 0; i < KEY_MAX; i++) {
if (key[i])
key_was_pressed[i] = key_is_pressed[i] = 1;
else
key_is_pressed[i] = 0;
}
for (i = 0; i < KEY_MAX; i++) {
int x = 16 + (i % 4) * 160;
int y = 32 + (i / 4) * 14;
if (key_is_pressed[i])
rectfill(screen, x, y, x + 7, y + 7, red);
else if (key_was_pressed[i])
rectfill(screen, x, y, x + 7, y + 7, yellow);
else
rectfill(screen, x, y, x + 7, y + 7, white);
}
rest(1);
}
while ((!key[KEY_ESC]) && (!mouse_b));
do {
poll_keyboard();
poll_mouse();
}
while ((key[KEY_ESC]) || (mouse_b));
clear_keybuf();
}
static void save_key_map(void)
{
int i;
char *section, *option_format, option[80], tmp1[80], tmp2[80];
set_config_file("xkeymap.cfg");
section = uconvert_ascii("xkeymap", tmp1);
option_format = uconvert_ascii("keycode%d", tmp2);
for (i = 0; i < 256; i++) {
if (keycode_to_scancode[i] > 0) {
uszprintf(option, sizeof(option), option_format, i);
set_config_int(section, option, keycode_to_scancode[i]);
}
}
}
void load_table(unsigned short *table, char *section)
{
char name[80];
int i;
for (i=0; i<KEY_MAX; i++) {
sprintf(name, "key%d", i);
table[i] = get_config_int(section, name, table[i]);
}
}
static DIALOG main_dialog[] = {
{d_clear_proc, 0, 0, 250, 102, 0, 0, 0, 0, 0, 0, 0, NULL, NULL},
{d_ctext_proc, 120, 10, 0, 16, 0, 255, 0, 0, 0, 0, "X Key Mapping Utility", NULL, NULL},
{d_ctext_proc, 10, 32, 230, 16, 0, 255, 0, D_EXIT, 0, 0, "~", NULL, NULL},
{d_button_proc, 10, 54, 230, 16, 0, 255, 'm', D_EXIT, 0, 0, "Setup X key &mappings", NULL, NULL},
{d_button_proc, 10, 76, 230, 16, 0, 255, 't', D_EXIT, 0, 0, "&Test X key mappings", NULL, NULL},
{d_button_proc, 10, 98, 230, 16, 0, 255, 's', D_EXIT, 0, 0, "&Save and exit", NULL, NULL},
{d_button_proc, 10, 120, 230, 16, 0, 255, 27, D_EXIT, 0, 0, "E&xit", NULL, NULL},
{d_yield_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL},
{NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL}
};
static void show_main_dialog(void)
{
int focus = 1;
set_dialog_color(main_dialog, black, white);
centre_dialog(main_dialog);
while (1) {
focus = do_dialog(main_dialog, focus);
switch (focus) {
case 3:
setup_all_keys();
break;
case 4:
test_key_map();
break;
case 5:
save_key_map();
return;
case 6:
return;
}
}
}
int main(void)
{
int i;
allegro_init();
install_keyboard();
install_mouse();
install_timer();
if (set_gfx_mode(GFX_SAFE, 640, 480, 0, 0) != 0) {
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
allegro_message("Unable to set any graphic mode\n%s\n", allegro_error);
exit(EXIT_FAILURE);
}
set_palette(desktop_palette);
gui_fg_color = palette_color[255];
gui_bg_color = palette_color[16];
black = makecol(0, 0, 0);
white = makecol(255, 255, 255);
red = makecol(255, 0, 0);
yellow = makecol(255, 255, 0);
for (i = 0; i < 256; i++)
keycode_to_scancode[i] = -1;
_xwin_keyboard_callback = get_raw_keycode;
show_main_dialog();
return 0;
}
END_OF_MAIN()