Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Dorota Czaplejewicz
squeekboard
Commits
7298d320
Commit
7298d320
authored
Mar 29, 2012
by
Daiki Ueno
Browse files
Refine keysym handling.
parent
39154fa5
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/client-main.c
View file @
7298d320
...
...
@@ -71,18 +71,14 @@ static void
on_context_destroyed
(
EekboardContext
*
context
,
gpointer
user_data
)
{
GMainLoop
*
loop
=
user_data
;
g_main_loop_quit
(
loop
);
gtk_main_quit
();
}
static
void
on_destroyed
(
EekboardClient
*
eekboard
,
gpointer
user_data
)
{
GMainLoop
*
loop
=
user_data
;
g_main_loop_quit
(
loop
);
gtk_main_quit
();
}
enum
FocusListenerType
{
...
...
@@ -121,7 +117,6 @@ main (int argc, char **argv)
GDBusConnection
*
connection
;
GError
*
error
;
GOptionContext
*
option_context
;
GMainLoop
*
loop
=
NULL
;
gint
focus
;
GSettings
*
settings
=
NULL
;
gchar
**
keyboards
=
NULL
;
...
...
@@ -283,12 +278,10 @@ main (int argc, char **argv)
}
#endif
/* HAVE_XTEST */
loop
=
g_main_loop_new
(
NULL
,
FALSE
);
if
(
!
opt_focus
)
{
g_object_get
(
client
,
"context"
,
&
context
,
NULL
);
g_signal_connect
(
context
,
"destroyed"
,
G_CALLBACK
(
on_context_destroyed
),
loop
);
G_CALLBACK
(
on_context_destroyed
),
NULL
);
g_object_unref
(
context
);
}
...
...
@@ -301,7 +294,7 @@ main (int argc, char **argv)
g_object_get
(
client
,
"eekboard"
,
&
eekboard
,
NULL
);
g_signal_connect
(
eekboard
,
"destroyed"
,
G_CALLBACK
(
on_destroyed
),
loop
);
G_CALLBACK
(
on_destroyed
),
NULL
);
g_object_unref
(
eekboard
);
if
(
opt_keyboards
!=
NULL
)
{
...
...
@@ -315,11 +308,9 @@ main (int argc, char **argv)
g_strfreev
(
keyboards
);
}
g_main
_loop_run
(
loop
);
g
tk
_main
(
);
out:
if
(
loop
)
g_main_loop_unref
(
loop
);
if
(
client
)
g_object_unref
(
client
);
if
(
settings
)
...
...
src/client.c
View file @
7298d320
...
...
@@ -92,8 +92,6 @@ struct _Client {
#ifdef HAVE_XTEST
guint
modifier_keycodes
[
8
];
XkbDescRec
*
xkb
;
GSList
*
replaced_keycodes
;
gulong
reset_replaced_keycodes_timeout_handler
;
#endif
/* HAVE_XTEST */
GSettings
*
settings
;
...
...
@@ -837,19 +835,6 @@ on_xkl_state_changed (XklEngine *xklengine,
}
#ifdef HAVE_XTEST
struct
_KeycodeReplacement
{
guint
keycode
;
guint
new_keysym
;
guint
old_keysym
;
};
typedef
struct
_KeycodeReplacement
KeycodeReplacement
;
static
void
keycode_replacement_free
(
KeycodeReplacement
*
replacement
)
{
g_slice_free
(
KeycodeReplacement
,
replacement
);
}
/* The following functions for keyboard mapping change are direct
translation of the code in Caribou (in libcaribou/xadapter.vala):
...
...
@@ -868,14 +853,7 @@ get_replaced_keycode (Client *client)
guint
offset
=
client
->
xkb
->
map
->
key_sym_map
[
keycode
].
offset
;
if
(
client
->
xkb
->
map
->
key_sym_map
[
keycode
].
kt_index
[
0
]
==
XkbOneLevelIndex
&&
client
->
xkb
->
map
->
syms
[
offset
]
!=
NoSymbol
)
{
GSList
*
head
;
for
(
head
=
client
->
replaced_keycodes
;
head
;
head
=
head
->
next
)
{
KeycodeReplacement
*
replacement
=
head
->
data
;
if
(
replacement
->
keycode
==
keycode
)
break
;
}
if
(
head
==
NULL
)
return
keycode
;
return
keycode
;
}
}
...
...
@@ -896,26 +874,21 @@ replace_keycode (Client *client,
{
GdkDisplay
*
display
=
gdk_display_get_default
();
Display
*
xdisplay
=
GDK_DISPLAY_XDISPLAY
(
display
);
guint
offset
;
XkbMapChangesRec
changes
;
guint
old_keysym
;
int
keysyms_per_keycode
;
KeySym
*
syms
;
g_return_val_if_fail
(
client
->
xkb
->
min_key_code
<=
keycode
&&
client
->
xkb
->
max_key_code
,
keycode
<=
client
->
xkb
->
max_key_code
,
FALSE
);
g_return_val_if_fail
(
keysym
!=
NULL
,
FALSE
);
offset
=
client
->
xkb
->
map
->
key_sym_map
[
keycode
].
offset
;
old_keysym
=
client
->
xkb
->
map
->
syms
[
offset
];
client
->
xkb
->
map
->
syms
[
offset
]
=
*
keysym
;
changes
.
changed
=
XkbKeySymsMask
;
changes
.
first_key_sym
=
keycode
;
changes
.
num_key_syms
=
1
;
XkbChangeMap
(
xdisplay
,
client
->
xkb
,
&
changes
);
syms
=
XGetKeyboardMapping
(
xdisplay
,
keycode
,
1
,
&
keysyms_per_keycode
);
old_keysym
=
syms
[
0
];
syms
[
0
]
=
*
keysym
;
XChangeKeyboardMapping
(
xdisplay
,
keycode
,
1
,
syms
,
1
);
XSync
(
xdisplay
,
False
);
XFree
(
syms
);
*
keysym
=
old_keysym
;
return
TRUE
;
...
...
@@ -956,6 +929,7 @@ send_fake_modifier_key_event (Client *client,
gboolean
is_pressed
)
{
GdkDisplay
*
display
=
gdk_display_get_default
();
Display
*
xdisplay
=
GDK_DISPLAY_XDISPLAY
(
display
);
gint
i
;
for
(
i
=
0
;
i
<
G_N_ELEMENTS
(
client
->
modifier_keycodes
);
i
++
)
{
...
...
@@ -964,79 +938,39 @@ send_fake_modifier_key_event (Client *client,
g_return_if_fail
(
keycode
>
0
);
XTestFakeKeyEvent
(
GDK_DISPLAY_XDISPLAY
(
display
)
,
XTestFakeKeyEvent
(
x
display
,
keycode
,
is_pressed
,
CurrentTime
);
XSync
(
xdisplay
,
False
);
}
}
}
static
gboolean
reset_replaced_keycodes
(
gpointer
data
)
{
Client
*
client
=
data
;
GSList
*
head
;
for
(
head
=
client
->
replaced_keycodes
;
head
;
head
=
head
->
next
)
{
KeycodeReplacement
*
replacement
=
head
->
data
;
guint
keysym
=
replacement
->
old_keysym
;
replace_keycode
(
client
,
replacement
->
keycode
,
&
keysym
);
}
g_slist_free_full
(
client
->
replaced_keycodes
,
(
GDestroyNotify
)
keycode_replacement_free
);
client
->
replaced_keycodes
=
NULL
;
client
->
reset_replaced_keycodes_timeout_handler
=
0
;
return
FALSE
;
}
static
void
send_fake_key_event
(
Client
*
client
,
guint
xkeysym
,
guint
keyboard_modifiers
,
gboolean
is_pressed
)
guint
keyboard_modifiers
)
{
GdkDisplay
*
display
=
gdk_display_get_default
();
Display
*
xdisplay
=
GDK_DISPLAY_XDISPLAY
(
display
);
EekModifierType
modifiers
;
guint
keycode
;
guint
old_keysym
=
0
;
GSList
*
head
;
guint
old_keysym
=
xkeysym
;
g_return_if_fail
(
xkeysym
>
0
);
keycode
=
0
;
for
(
head
=
client
->
replaced_keycodes
;
head
;
head
=
head
->
next
)
{
KeycodeReplacement
*
replacement
=
head
->
data
;
if
(
replacement
->
new_keysym
==
xkeysym
)
{
keycode
=
replacement
->
keycode
;
break
;
}
}
modifiers
=
0
;
if
(
keycode
==
0
)
{
if
(
!
get_keycode_from_gdk_keymap
(
client
,
xkeysym
,
&
keycode
,
&
modifiers
))
{
KeycodeReplacement
*
replacement
;
keycode
=
get_replaced_keycode
(
client
);
if
(
keycode
==
0
)
{
g_warning
(
"no available keycode to replace"
);
return
;
}
old_keysym
=
xkeysym
;
if
(
!
replace_keycode
(
client
,
keycode
,
&
old_keysym
))
{
g_warning
(
"failed to lookup X keysym %X"
,
xkeysym
);
return
;
}
if
(
!
get_keycode_from_gdk_keymap
(
client
,
xkeysym
,
&
keycode
,
&
modifiers
))
{
keycode
=
get_replaced_keycode
(
client
);
if
(
keycode
==
0
)
{
g_warning
(
"no available keycode to replace"
);
return
;
}
replacement
=
g_slice_new0
(
KeycodeReplacement
);
replacement
->
keycode
=
keycode
;
replacement
->
new_keysym
=
xkeysym
;
replacement
->
old_keysym
=
old_keysym
;
client
->
replaced_keycodes
=
g_slist_prepend
(
client
->
replaced_keycodes
,
replacement
);
if
(
!
replace_keycode
(
client
,
keycode
,
&
old_keysym
))
{
g_warning
(
"failed to lookup X keysym %X"
,
xkeysym
);
return
;
}
}
...
...
@@ -1052,18 +986,15 @@ send_fake_key_event (Client *client,
modifiers
|=
keyboard_modifiers
;
send_fake_modifier_key_event
(
client
,
modifiers
,
is_pressed
);
XTestFakeKeyEvent
(
xdisplay
,
keycode
,
is_pressed
,
CurrentTime
);
if
(
client
->
reset_replaced_keycodes_timeout_handler
==
0
&&
old_keysym
!=
0
)
{
/* Queue a timer to restore the old keycode. Ugly, but
* required due to races / asynchronous X delivery. Long-term
* fix is to extend the X keymap here instead of replace
* entries. */
client
->
reset_replaced_keycodes_timeout_handler
=
g_timeout_add
(
500
,
reset_replaced_keycodes
,
client
);
}
send_fake_modifier_key_event
(
client
,
modifiers
,
TRUE
);
XTestFakeKeyEvent
(
xdisplay
,
keycode
,
TRUE
,
20
);
XSync
(
xdisplay
,
False
);
XTestFakeKeyEvent
(
xdisplay
,
keycode
,
FALSE
,
20
);
XSync
(
xdisplay
,
False
);
send_fake_modifier_key_event
(
client
,
modifiers
,
FALSE
);
if
(
old_keysym
!=
xkeysym
)
replace_keycode
(
client
,
keycode
,
&
old_keysym
);
}
static
void
...
...
@@ -1102,8 +1033,7 @@ send_fake_key_events (Client *client,
if
(
EEK_IS_KEYSYM
(
symbol
))
{
guint
xkeysym
=
eek_keysym_get_xkeysym
(
EEK_KEYSYM
(
symbol
));
send_fake_key_event
(
client
,
xkeysym
,
keyboard_modifiers
,
TRUE
);
send_fake_key_event
(
client
,
xkeysym
,
keyboard_modifiers
,
FALSE
);
send_fake_key_event
(
client
,
xkeysym
,
keyboard_modifiers
);
}
}
...
...
@@ -1210,10 +1140,5 @@ client_disable_xtest (Client *client)
XkbFreeKeyboard
(
client
->
xkb
,
0
,
TRUE
);
/* free_all = TRUE */
client
->
xkb
=
NULL
;
}
if
(
client
->
replaced_keycodes
)
{
g_slist_free_full
(
client
->
replaced_keycodes
,
(
GDestroyNotify
)
keycode_replacement_free
);
client
->
replaced_keycodes
=
NULL
;
}
}
#endif
/* HAVE_XTEST */
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment