2000-05-31 21:50:38 +00:00
|
|
|
/* GDK - The GIMP Drawing Kit
|
|
|
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
2000-07-26 11:33:08 +00:00
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
2000-05-31 21:50:38 +00:00
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
2000-07-26 11:33:08 +00:00
|
|
|
* Lesser General Public License for more details.
|
2000-05-31 21:50:38 +00:00
|
|
|
*
|
2000-07-26 11:33:08 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2000-05-31 21:50:38 +00:00
|
|
|
* License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <gdk/gdk.h>
|
|
|
|
#include <gdk/gdkinternals.h>
|
|
|
|
#include "gdkinputprivate.h"
|
|
|
|
#include "gdkkeysyms.h"
|
|
|
|
#include "gdkprivate-fb.h"
|
|
|
|
#include <unistd.h>
|
2000-08-09 16:12:06 +00:00
|
|
|
#include <errno.h>
|
2000-05-31 21:50:38 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <termios.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/vt.h>
|
2000-11-13 17:40:23 +00:00
|
|
|
#include <sys/time.h>
|
2000-05-31 21:50:38 +00:00
|
|
|
#include <sys/kd.h>
|
2000-11-13 17:40:23 +00:00
|
|
|
#include <sys/types.h>
|
2000-05-31 21:50:38 +00:00
|
|
|
#include <ctype.h>
|
2000-08-04 01:30:54 +00:00
|
|
|
#include <stdlib.h>
|
2000-08-07 03:26:05 +00:00
|
|
|
#include <string.h>
|
2000-08-07 18:19:43 +00:00
|
|
|
#include <math.h>
|
2000-08-09 17:24:47 +00:00
|
|
|
#include <linux/fb.h>
|
|
|
|
|
|
|
|
/* Two minutes */
|
|
|
|
#define BLANKING_TIMEOUT 120*1000
|
2000-08-07 03:31:12 +00:00
|
|
|
|
2000-05-31 21:50:38 +00:00
|
|
|
/*
|
2000-07-26 11:33:08 +00:00
|
|
|
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
2000-05-31 21:50:38 +00:00
|
|
|
* file for a list of people on the GTK+ Team. See the ChangeLog
|
|
|
|
* files for a list of changes. These files are distributed with
|
|
|
|
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
gint fd, fd_tag, consfd;
|
|
|
|
|
|
|
|
int vtnum, prev_vtnum;
|
2000-11-07 14:18:47 +00:00
|
|
|
guint modifier_state;
|
2000-05-31 21:50:38 +00:00
|
|
|
gboolean caps_lock : 1;
|
|
|
|
} Keyboard;
|
|
|
|
|
2000-08-09 17:24:47 +00:00
|
|
|
static guint blanking_timer = 0;
|
|
|
|
|
2000-05-31 21:50:38 +00:00
|
|
|
static Keyboard * tty_keyboard_open(void);
|
|
|
|
|
|
|
|
static Keyboard *keyboard = NULL;
|
|
|
|
|
2000-08-09 17:24:47 +00:00
|
|
|
#ifndef VESA_NO_BLANKING
|
|
|
|
#define VESA_NO_BLANKING 0
|
|
|
|
#define VESA_VSYNC_SUSPEND 1
|
|
|
|
#define VESA_HSYNC_SUSPEND 2
|
|
|
|
#define VESA_POWERDOWN 3
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
static gboolean
|
|
|
|
input_activity_timeout(gpointer p)
|
|
|
|
{
|
|
|
|
blanking_timer = 0;
|
|
|
|
ioctl(gdk_display->fd, FBIOBLANK, VESA_POWERDOWN);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* This is all very broken :( */
|
|
|
|
static void
|
2000-11-13 17:40:23 +00:00
|
|
|
input_activity (void)
|
2000-08-09 17:24:47 +00:00
|
|
|
{
|
|
|
|
#if 0
|
2000-11-13 17:40:23 +00:00
|
|
|
if (blanking_timer)
|
|
|
|
g_source_remove (blanking_timer);
|
2000-08-09 17:24:47 +00:00
|
|
|
else
|
2000-11-13 17:40:23 +00:00
|
|
|
gdk_fb_redraw_all ();
|
2000-08-09 17:24:47 +00:00
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
blanking_timer = g_timeout_add (BLANKING_TIMEOUT, input_activity_timeout, NULL);
|
2000-08-09 17:24:47 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2000-05-31 21:50:38 +00:00
|
|
|
void
|
|
|
|
gdk_input_init (void)
|
|
|
|
{
|
2000-07-24 16:19:00 +00:00
|
|
|
gdk_input_devices = g_list_append (NULL, gdk_core_pointer);
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
gdk_input_ignore_core = FALSE;
|
|
|
|
|
2000-12-06 17:27:52 +00:00
|
|
|
gdk_fb_mouse_open ();
|
2000-05-31 21:50:38 +00:00
|
|
|
}
|
|
|
|
|
2000-08-07 23:00:38 +00:00
|
|
|
GdkWindow *
|
2000-11-13 17:40:23 +00:00
|
|
|
gdk_window_find_focus (void)
|
2000-05-31 21:50:38 +00:00
|
|
|
{
|
2000-11-13 17:40:23 +00:00
|
|
|
if (_gdk_fb_keyboard_grab_window)
|
2000-05-31 21:50:38 +00:00
|
|
|
return _gdk_fb_keyboard_grab_window;
|
2000-11-13 17:40:23 +00:00
|
|
|
else if (GDK_WINDOW_P (gdk_parent_root)->children)
|
2000-06-20 20:20:38 +00:00
|
|
|
{
|
|
|
|
GList *item;
|
2000-11-13 17:40:23 +00:00
|
|
|
for (item = GDK_WINDOW_P (gdk_parent_root)->children; item; item = item->next)
|
2000-06-20 20:20:38 +00:00
|
|
|
{
|
2000-11-13 17:40:23 +00:00
|
|
|
GdkWindowObject *priv = item->data;
|
2000-06-20 20:20:38 +00:00
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
if (priv->mapped)
|
2000-06-20 20:20:38 +00:00
|
|
|
return item->data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return gdk_parent_root;
|
2000-05-31 21:50:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-06 12:11:45 +00:00
|
|
|
/* Bogus implementation */
|
|
|
|
gboolean
|
|
|
|
gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap,
|
|
|
|
guint hardware_keycode,
|
|
|
|
GdkKeymapKey **keys,
|
|
|
|
guint **keyvals,
|
|
|
|
gint *n_entries)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2000-07-24 16:19:00 +00:00
|
|
|
static const guint trans_table[256][3] = {
|
|
|
|
/* 0x00 */
|
|
|
|
{0, 0, 0},
|
|
|
|
{GDK_Escape, 0, 0},
|
|
|
|
{'1', '!', 0},
|
|
|
|
{'2', '@', 0},
|
|
|
|
{'3', '#', 0},
|
|
|
|
{'4', '$', 0},
|
|
|
|
{'5', '%', 0},
|
|
|
|
{'6', '^', 0},
|
|
|
|
{'7', '&', 0},
|
|
|
|
{'8', '*', 0},
|
|
|
|
{'9', '(', 0},
|
|
|
|
{'0', ')', 0},
|
|
|
|
{'-', '_', 0},
|
|
|
|
{'=', '+', 0},
|
|
|
|
{GDK_BackSpace, 0, 0},
|
|
|
|
{GDK_Tab, 0, 0},
|
|
|
|
|
|
|
|
/* 0x10 */
|
|
|
|
{'q', 'Q', 0},
|
|
|
|
{'w', 'W', 0},
|
|
|
|
{'e', 'E', 0},
|
|
|
|
{'r', 'R', 0},
|
|
|
|
{'t', 'T', 0},
|
|
|
|
{'y', 'Y', 0},
|
|
|
|
{'u', 'U', 0},
|
|
|
|
{'i', 'I', 0},
|
|
|
|
{'o', 'O', 0},
|
|
|
|
{'p', 'P', 0},
|
|
|
|
{'[', '{', 0},
|
|
|
|
{']', '}', 0},
|
|
|
|
{GDK_Return, 0, 0},
|
|
|
|
{GDK_Control_L, 0, 0}, /* mod */
|
|
|
|
{'a', 'A', 0},
|
|
|
|
{'s', 'S', 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0x20 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{'d', 'D', 0},
|
|
|
|
{'f', 'F', 0},
|
|
|
|
{'g', 'G', 0},
|
|
|
|
{'h', 'H', 0},
|
|
|
|
{'j', 'J', 0},
|
|
|
|
{'k', 'K', 0},
|
|
|
|
{'l', 'L', 0},
|
|
|
|
{';', ':', 0},
|
|
|
|
{'\'', '"', 0},
|
|
|
|
{'`', '~', 0},
|
|
|
|
{GDK_Shift_L, 0, 0}, /* mod */
|
|
|
|
{'\\', 0, 0},
|
|
|
|
{'z', 0, 0},
|
|
|
|
{'x', 0, 0},
|
|
|
|
{'c', 0, 0},
|
|
|
|
|
|
|
|
{'v', 'V', 0},
|
2000-06-20 20:20:38 +00:00
|
|
|
|
|
|
|
/* 0x30 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{'b', 'B', 0},
|
|
|
|
{'n', 'N', 0},
|
|
|
|
{'m', 'M', 0},
|
|
|
|
{',', 0, 0},
|
|
|
|
{'.', 0, 0},
|
|
|
|
{'/', 0, 0},
|
|
|
|
{GDK_Shift_R, 0, 0}, /* mod */
|
|
|
|
{GDK_KP_Multiply, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{GDK_space, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{GDK_F1, 0, 0},
|
|
|
|
{GDK_F2, 0, 0},
|
|
|
|
{GDK_F3, 0, 0},
|
|
|
|
{GDK_F4, 0, 0},
|
|
|
|
{GDK_F5, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0x40 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{GDK_F6, 0, 0},
|
|
|
|
{GDK_F7, 0, 0},
|
|
|
|
{GDK_F8, 0, 0},
|
|
|
|
{GDK_F9, 0, 0},
|
|
|
|
{GDK_F10, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-08-09 19:58:10 +00:00
|
|
|
{'7', 0, 0},
|
|
|
|
{'8', 0, 0},
|
|
|
|
{'9', 0, 0},
|
|
|
|
{'-', 0, 0},
|
|
|
|
{'4', 0, 0},
|
|
|
|
{'5', 0, 0},
|
|
|
|
{'6', 0, 0},
|
|
|
|
{'+', 0, 0},
|
|
|
|
{'1', 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0x50 */
|
2000-08-09 19:58:10 +00:00
|
|
|
{'2', 0, 0},
|
|
|
|
{'3', 0, 0},
|
|
|
|
{'0', 0, 0},
|
|
|
|
{'.', 0, 0},
|
2000-07-24 16:19:00 +00:00
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{GDK_F11, 0, 0},
|
|
|
|
{GDK_F12, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0x60 */
|
2000-08-09 19:58:10 +00:00
|
|
|
{GDK_Return, 0, 0},
|
2000-07-24 16:19:00 +00:00
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0x70 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0x80 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0x90 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0xA0 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0xB0 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0xC0 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{GDK_Up, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{GDK_Left, 0, 0},
|
2000-08-09 01:36:37 +00:00
|
|
|
{0, 0, 0},
|
2000-07-24 16:19:00 +00:00
|
|
|
{GDK_Right, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0xD0 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{GDK_Down, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0xE0 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* 0xF0 */
|
2000-07-24 16:19:00 +00:00
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
};
|
2000-11-07 14:18:47 +00:00
|
|
|
|
|
|
|
#define TRANS_TABLE_SIZE (sizeof(trans_table)/sizeof(trans_table[0]))
|
|
|
|
|
2000-07-24 16:19:00 +00:00
|
|
|
static gboolean
|
2000-11-13 17:40:23 +00:00
|
|
|
handle_mediumraw_keyboard_input (GIOChannel *gioc,
|
|
|
|
GIOCondition cond,
|
|
|
|
gpointer data)
|
2000-07-24 16:19:00 +00:00
|
|
|
{
|
|
|
|
guchar buf[128];
|
|
|
|
int i, n;
|
|
|
|
Keyboard *k = data;
|
2000-11-22 10:07:34 +00:00
|
|
|
guint32 now;
|
2000-07-24 16:19:00 +00:00
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
n = read (k->fd, buf, sizeof(buf));
|
|
|
|
if (n <= 0)
|
2000-07-24 16:19:00 +00:00
|
|
|
g_error("Nothing from keyboard!");
|
|
|
|
|
|
|
|
/* Now turn this into a keyboard event */
|
2000-11-22 10:07:34 +00:00
|
|
|
now = gdk_fb_get_time ();
|
2000-07-24 16:19:00 +00:00
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
for (i = 0; i < n; i++)
|
2000-07-24 16:19:00 +00:00
|
|
|
{
|
2000-11-07 14:18:47 +00:00
|
|
|
guchar keycode;
|
|
|
|
gboolean key_up;
|
2000-05-31 21:50:38 +00:00
|
|
|
GdkEvent *event;
|
|
|
|
GdkWindow *win;
|
|
|
|
char dummy[2];
|
|
|
|
int mod;
|
2000-11-07 14:18:47 +00:00
|
|
|
guint keyval;
|
2000-05-31 21:50:38 +00:00
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
keycode = buf[i] & 0x7F;
|
|
|
|
key_up = buf[i] & 0x80;
|
2000-05-31 21:50:38 +00:00
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
if (keycode > TRANS_TABLE_SIZE)
|
|
|
|
{
|
2000-11-13 17:40:23 +00:00
|
|
|
g_warning ("Unknown keycode\n");
|
2000-11-07 14:18:47 +00:00
|
|
|
continue;
|
2000-05-31 21:50:38 +00:00
|
|
|
}
|
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
if ( (keycode == 0x1D) /* left Ctrl */
|
|
|
|
|| (keycode == 0x9D) /* right Ctrl */
|
|
|
|
|| (keycode == 0x38) /* left Alt */
|
|
|
|
|| (keycode == 0xB8) /* right Alt */
|
|
|
|
|| (keycode == 0x2A) /* left Shift */
|
|
|
|
|| (keycode == 0x36) /* right Shift */)
|
2000-05-31 21:50:38 +00:00
|
|
|
{
|
2000-11-07 14:18:47 +00:00
|
|
|
switch (keycode)
|
|
|
|
{
|
|
|
|
case 0x1D: /* Left Ctrl */
|
|
|
|
case 0x9D: /* Right Ctrl */
|
|
|
|
if (key_up)
|
|
|
|
k->modifier_state &= ~GDK_CONTROL_MASK;
|
|
|
|
else
|
|
|
|
k->modifier_state |= GDK_CONTROL_MASK;
|
|
|
|
break;
|
|
|
|
case 0x38: /* Left Alt */
|
|
|
|
case 0xB8: /* Right Alt */
|
|
|
|
if (key_up)
|
|
|
|
k->modifier_state &= ~GDK_MOD1_MASK;
|
|
|
|
else
|
|
|
|
k->modifier_state |= GDK_MOD1_MASK;
|
|
|
|
break;
|
|
|
|
case 0x2A: /* Left Shift */
|
|
|
|
case 0x36: /* Right Shift */
|
|
|
|
if (key_up)
|
|
|
|
k->modifier_state &= ~GDK_SHIFT_MASK;
|
|
|
|
else
|
|
|
|
k->modifier_state |= GDK_SHIFT_MASK;
|
|
|
|
break;
|
|
|
|
}
|
2000-05-31 21:50:38 +00:00
|
|
|
continue; /* Don't generate events for modifiers */
|
|
|
|
}
|
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
if (keycode == 0x3A /* Caps lock */)
|
2000-05-31 21:50:38 +00:00
|
|
|
{
|
2000-11-13 17:40:23 +00:00
|
|
|
if (!key_up)
|
2000-05-31 21:50:38 +00:00
|
|
|
k->caps_lock = !k->caps_lock;
|
2000-11-07 14:18:47 +00:00
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
ioctl (k->fd, KDSETLED, k->caps_lock ? LED_CAP : 0);
|
2000-05-31 21:50:38 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
if (trans_table[keycode][0] >= GDK_F1 &&
|
|
|
|
trans_table[keycode][0] <= GDK_F35 &&
|
|
|
|
(k->modifier_state & GDK_MOD1_MASK))
|
2000-05-31 21:50:38 +00:00
|
|
|
{
|
2000-11-13 17:40:23 +00:00
|
|
|
if (key_up) /* Only switch on release */
|
2000-05-31 21:50:38 +00:00
|
|
|
{
|
2000-11-07 14:18:47 +00:00
|
|
|
gint vtnum = trans_table[keycode][0] - GDK_F1 + 1;
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
/* Do the whole funky VT switch thing */
|
2000-11-13 17:40:23 +00:00
|
|
|
ioctl (k->consfd, VT_ACTIVATE, vtnum);
|
|
|
|
ioctl (k->consfd, VT_WAITACTIVE, k->vtnum);
|
|
|
|
gdk_fb_redraw_all ();
|
2000-05-31 21:50:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
keyval = 0;
|
|
|
|
mod = 0;
|
2000-11-07 14:18:47 +00:00
|
|
|
if (k->modifier_state & GDK_CONTROL_MASK)
|
2000-05-31 21:50:38 +00:00
|
|
|
mod = 2;
|
2000-11-07 14:18:47 +00:00
|
|
|
else if (k->modifier_state & GDK_SHIFT_MASK)
|
2000-05-31 21:50:38 +00:00
|
|
|
mod = 1;
|
|
|
|
do {
|
2000-11-07 14:18:47 +00:00
|
|
|
keyval = trans_table[keycode][mod--];
|
|
|
|
} while (!keyval && (mod >= 0));
|
2000-05-31 21:50:38 +00:00
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
if (k->caps_lock && (keyval >= 'a') && (keyval <= 'z'))
|
2000-11-07 14:18:47 +00:00
|
|
|
keyval = toupper (keyval);
|
2000-05-31 21:50:38 +00:00
|
|
|
|
2000-07-24 16:19:00 +00:00
|
|
|
/* handle some magic keys */
|
2000-11-07 14:18:47 +00:00
|
|
|
if (k->modifier_state & (GDK_CONTROL_MASK|GDK_MOD1_MASK))
|
2000-07-24 16:19:00 +00:00
|
|
|
{
|
2000-11-07 14:18:47 +00:00
|
|
|
if (key_up)
|
2000-07-24 16:19:00 +00:00
|
|
|
{
|
2000-11-07 14:18:47 +00:00
|
|
|
if (keyval == GDK_BackSpace)
|
2000-11-13 17:40:23 +00:00
|
|
|
exit (1);
|
2000-07-24 16:19:00 +00:00
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
if (keyval == GDK_Return)
|
2000-11-13 17:40:23 +00:00
|
|
|
gdk_fb_redraw_all ();
|
2000-07-24 16:19:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
keyval = 0;
|
|
|
|
}
|
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
if (!keyval)
|
2000-07-24 16:19:00 +00:00
|
|
|
continue;
|
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
win = gdk_window_find_focus ();
|
2000-11-13 17:40:23 +00:00
|
|
|
event = gdk_event_make (win,
|
|
|
|
key_up ? GDK_KEY_RELEASE : GDK_KEY_PRESS,
|
|
|
|
TRUE);
|
2000-11-07 14:18:47 +00:00
|
|
|
if (event)
|
|
|
|
{
|
|
|
|
/* Find focused window */
|
|
|
|
event->key.time = now;
|
|
|
|
event->key.state = k->modifier_state;
|
|
|
|
event->key.keyval = keyval;
|
2000-11-13 17:40:23 +00:00
|
|
|
event->key.length = isprint (event->key.keyval) ? 1 : 0;
|
2000-11-07 14:18:47 +00:00
|
|
|
dummy[0] = event->key.keyval;
|
|
|
|
dummy[1] = 0;
|
2000-11-13 17:40:23 +00:00
|
|
|
event->key.string = event->key.length ? g_strdup(dummy) : NULL;
|
2000-11-07 14:18:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
input_activity ();
|
2000-11-07 14:18:47 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2000-11-13 17:40:23 +00:00
|
|
|
handle_xlate_keyboard_input (GIOChannel *gioc,
|
|
|
|
GIOCondition cond,
|
|
|
|
gpointer data)
|
2000-11-07 14:18:47 +00:00
|
|
|
{
|
|
|
|
guchar buf[128];
|
|
|
|
int i, n;
|
|
|
|
Keyboard *k = data;
|
2000-11-22 10:07:34 +00:00
|
|
|
guint32 now;
|
2000-11-07 14:18:47 +00:00
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
n = read (k->fd, buf, sizeof(buf));
|
|
|
|
if (n <= 0)
|
|
|
|
g_error ("Nothing from keyboard!");
|
2000-11-07 14:18:47 +00:00
|
|
|
|
|
|
|
/* Now turn this into a keyboard event */
|
2000-11-22 10:07:34 +00:00
|
|
|
now = gdk_fb_get_time ();
|
2000-11-07 14:18:47 +00:00
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
for (i = 0; i < n; i++)
|
2000-11-07 14:18:47 +00:00
|
|
|
{
|
|
|
|
GdkEvent *event;
|
|
|
|
GdkWindow *win;
|
|
|
|
char dummy[2];
|
|
|
|
guint keyval;
|
|
|
|
|
|
|
|
keyval = buf[i];
|
|
|
|
|
|
|
|
switch (keyval) {
|
|
|
|
case '\n':
|
|
|
|
keyval = GDK_Return;
|
|
|
|
break;
|
|
|
|
case '\t':
|
|
|
|
keyval = GDK_Tab;
|
|
|
|
break;
|
|
|
|
case 127:
|
|
|
|
keyval = GDK_BackSpace;
|
|
|
|
break;
|
|
|
|
case 27:
|
|
|
|
keyval = GDK_Escape;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
win = gdk_window_find_focus ();
|
|
|
|
|
|
|
|
/* Send key down: */
|
|
|
|
event = gdk_event_make (win, GDK_KEY_PRESS, TRUE);
|
|
|
|
if (event)
|
|
|
|
{
|
|
|
|
/* Find focused window */
|
|
|
|
event->key.time = now;
|
|
|
|
event->key.state = k->modifier_state;
|
|
|
|
event->key.keyval = keyval;
|
2000-11-13 17:40:23 +00:00
|
|
|
event->key.length = isprint (event->key.keyval) ? 1 : 0;
|
2000-11-07 14:18:47 +00:00
|
|
|
dummy[0] = event->key.keyval;
|
|
|
|
dummy[1] = 0;
|
2000-11-13 17:40:23 +00:00
|
|
|
event->key.string = event->key.length ? g_strdup(dummy) : NULL;
|
2000-11-07 14:18:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Send key up: */
|
|
|
|
event = gdk_event_make (win, GDK_KEY_RELEASE, TRUE);
|
|
|
|
if (event)
|
2000-05-31 21:50:38 +00:00
|
|
|
{
|
|
|
|
/* Find focused window */
|
|
|
|
event->key.time = now;
|
2000-11-07 14:18:47 +00:00
|
|
|
event->key.state = k->modifier_state;
|
2000-05-31 21:50:38 +00:00
|
|
|
event->key.keyval = keyval;
|
2000-11-13 17:40:23 +00:00
|
|
|
event->key.length = isprint (event->key.keyval) ? 1 : 0;
|
2000-05-31 21:50:38 +00:00
|
|
|
dummy[0] = event->key.keyval;
|
|
|
|
dummy[1] = 0;
|
2000-11-13 17:40:23 +00:00
|
|
|
event->key.string = event->key.length ? g_strdup(dummy) : NULL;
|
2000-05-31 21:50:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
input_activity ();
|
2000-08-09 17:24:47 +00:00
|
|
|
|
2000-05-31 21:50:38 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
|
2000-05-31 21:50:38 +00:00
|
|
|
static Keyboard *
|
2000-11-13 17:40:23 +00:00
|
|
|
tty_keyboard_open (void)
|
2000-05-31 21:50:38 +00:00
|
|
|
{
|
2000-11-13 17:40:23 +00:00
|
|
|
Keyboard *retval = g_new0 (Keyboard, 1);
|
2000-05-31 21:50:38 +00:00
|
|
|
GIOChannel *gioc;
|
|
|
|
const char cursoroff_str[] = "\033[?1;0;0c";
|
|
|
|
int n;
|
|
|
|
struct vt_stat vs;
|
|
|
|
char buf[32];
|
|
|
|
struct termios ts;
|
2000-11-07 14:18:47 +00:00
|
|
|
gboolean raw_keyboard;
|
2000-05-31 21:50:38 +00:00
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
retval->modifier_state = 0;
|
|
|
|
retval->caps_lock = 0;
|
|
|
|
|
2000-05-31 21:50:38 +00:00
|
|
|
setsid();
|
2000-11-07 14:18:47 +00:00
|
|
|
retval->consfd = open ("/dev/console", O_RDWR);
|
|
|
|
ioctl (retval->consfd, VT_GETSTATE, &vs);
|
2000-05-31 21:50:38 +00:00
|
|
|
retval->prev_vtnum = vs.v_active;
|
2000-11-07 14:18:47 +00:00
|
|
|
g_snprintf (buf, sizeof(buf), "/dev/tty%d", retval->prev_vtnum);
|
|
|
|
ioctl (retval->consfd, KDSKBMODE, K_XLATE);
|
2000-05-31 21:50:38 +00:00
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
n = ioctl (retval->consfd, VT_OPENQRY, &retval->vtnum);
|
|
|
|
if (n < 0 || retval->vtnum == -1)
|
2000-05-31 21:50:38 +00:00
|
|
|
g_error("Cannot allocate VT");
|
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
ioctl (retval->consfd, VT_ACTIVATE, retval->vtnum);
|
|
|
|
ioctl (retval->consfd, VT_WAITACTIVE, retval->vtnum);
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
#if 0
|
2000-11-07 14:18:47 +00:00
|
|
|
close (0);
|
|
|
|
close (1);
|
|
|
|
close (2);
|
2000-05-31 21:50:38 +00:00
|
|
|
#endif
|
2000-11-13 17:40:23 +00:00
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
g_snprintf (buf, sizeof(buf), "/dev/tty%d", retval->vtnum);
|
|
|
|
retval->fd = open (buf, O_RDWR|O_NONBLOCK);
|
|
|
|
if (retval->fd < 0)
|
2000-05-31 21:50:38 +00:00
|
|
|
return NULL;
|
2000-11-07 14:18:47 +00:00
|
|
|
raw_keyboard = TRUE;
|
|
|
|
if (ioctl (retval->fd, KDSKBMODE, K_MEDIUMRAW) < 0)
|
|
|
|
{
|
|
|
|
raw_keyboard = FALSE;
|
2000-11-13 17:40:23 +00:00
|
|
|
g_warning ("K_MEDIUMRAW failed, using broken XLATE keyboard driver");
|
2000-11-07 14:18:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Disable normal text on the console */
|
|
|
|
ioctl (retval->fd, KDSETMODE, KD_GRAPHICS);
|
2000-05-31 21:50:38 +00:00
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
/* Set controlling tty */
|
|
|
|
ioctl (0, TIOCNOTTY, 0);
|
|
|
|
ioctl (retval->fd, TIOCSCTTY, 0);
|
|
|
|
tcgetattr (retval->fd, &ts);
|
2000-05-31 21:50:38 +00:00
|
|
|
ts.c_cc[VTIME] = 0;
|
|
|
|
ts.c_cc[VMIN] = 1;
|
|
|
|
ts.c_lflag &= ~(ICANON|ECHO|ISIG);
|
|
|
|
ts.c_iflag = 0;
|
2000-11-07 14:18:47 +00:00
|
|
|
tcsetattr (retval->fd, TCSAFLUSH, &ts);
|
2000-05-31 21:50:38 +00:00
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
tcsetpgrp (retval->fd, getpgrp());
|
2000-05-31 21:50:38 +00:00
|
|
|
|
2000-11-13 17:40:23 +00:00
|
|
|
write (retval->fd, cursoroff_str, strlen (cursoroff_str));
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
#if 0
|
2000-11-07 14:18:47 +00:00
|
|
|
if (retval->fd != 0)
|
|
|
|
dup2 (retval->fd, 0);
|
|
|
|
if (retval->fd != 1)
|
|
|
|
dup2 (retval->fd, 1);
|
|
|
|
if (retval->fd != 2)
|
|
|
|
dup2 (retval->fd, 2);
|
2000-05-31 21:50:38 +00:00
|
|
|
#endif
|
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
gioc = g_io_channel_unix_new (retval->fd);
|
|
|
|
retval->fd_tag = g_io_add_watch (gioc,
|
2000-11-13 17:40:23 +00:00
|
|
|
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
|
|
|
|
(raw_keyboard) ? handle_mediumraw_keyboard_input : handle_xlate_keyboard_input,
|
2000-11-07 14:18:47 +00:00
|
|
|
retval);
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2000-08-09 16:12:06 +00:00
|
|
|
void
|
|
|
|
gdk_beep (void)
|
|
|
|
{
|
|
|
|
static int pitch = 600, duration = 100;
|
|
|
|
gulong arg;
|
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
if (!keyboard)
|
2000-08-09 16:12:06 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Thank you XFree86 */
|
|
|
|
arg = ((1193190 / pitch) & 0xffff) |
|
|
|
|
(((unsigned long)duration) << 16);
|
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
ioctl (keyboard->fd, KDMKTONE, arg);
|
2000-08-09 16:12:06 +00:00
|
|
|
}
|
|
|
|
|
2000-05-31 21:50:38 +00:00
|
|
|
void
|
2000-11-13 17:40:23 +00:00
|
|
|
keyboard_init (void)
|
2000-05-31 21:50:38 +00:00
|
|
|
{
|
2000-11-13 17:40:23 +00:00
|
|
|
keyboard = tty_keyboard_open ();
|
2000-05-31 21:50:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-11-13 17:40:23 +00:00
|
|
|
keyboard_shutdown (void)
|
2000-05-31 21:50:38 +00:00
|
|
|
{
|
|
|
|
int tmpfd;
|
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
ioctl (keyboard->fd, KDSETMODE, KD_TEXT);
|
|
|
|
ioctl (keyboard->fd, KDSKBMODE, K_XLATE);
|
|
|
|
close (keyboard->fd);
|
|
|
|
g_source_remove (keyboard->fd_tag);
|
2000-05-31 21:50:38 +00:00
|
|
|
|
|
|
|
tmpfd = keyboard->consfd;
|
2000-11-07 14:18:47 +00:00
|
|
|
ioctl (tmpfd, VT_ACTIVATE, keyboard->prev_vtnum);
|
|
|
|
ioctl (tmpfd, VT_WAITACTIVE, keyboard->prev_vtnum);
|
|
|
|
ioctl (tmpfd, VT_DISALLOCATE, keyboard->vtnum);
|
|
|
|
close (tmpfd);
|
2000-05-31 21:50:38 +00:00
|
|
|
|
2000-11-07 14:18:47 +00:00
|
|
|
g_free (keyboard);
|
2000-05-31 21:50:38 +00:00
|
|
|
keyboard = NULL;
|
|
|
|
}
|
2000-11-07 14:18:47 +00:00
|
|
|
|
|
|
|
|