Compare commits

...

303 Commits

Author SHA1 Message Date
76d1b8f7fb 0.90.4 released. 2011-03-08 11:27:49 +09:00
2bbc65958a Doc and typo fix for eekboard_context_set_fullscreen(). 2011-03-08 11:27:20 +09:00
cbdd0fd2ba Add eekboard/eekboard-eekboard.c to POTFILES.skip. 2011-03-08 11:26:49 +09:00
2f7aa77c11 Fix focus listener logic. 2011-03-08 11:26:15 +09:00
bed39570ff Add eek-theme-private.h in distribution. 2011-03-08 11:25:59 +09:00
8bc3b204b4 Add credit. 2011-03-08 11:25:19 +09:00
fa030ebcbb Fix fullscreen code. 2011-03-08 11:03:48 +09:00
af365024b7 Update default theme. 2011-03-08 10:43:17 +09:00
c742877b77 Add "SetFullscreen" D-Bus method. 2011-03-08 10:42:57 +09:00
ace4391b79 Use font from style. 2011-03-08 10:41:45 +09:00
627cbf2898 Pass base_font during size calculation. 2011-03-08 07:04:12 +09:00
baae80fa41 Port st-theme-context.[ch] to eek-theme-context.[ch]. 2011-03-08 06:58:20 +09:00
9be07710dd Fix clutter build. 2011-03-08 06:27:59 +09:00
163e005561 Simplify "blank background" code. 2011-03-08 06:04:41 +09:00
d8e691d3f5 Optimize redraw on key release. 2011-03-08 05:53:00 +09:00
85a1a6ba24 Abolish EekThemeNodePrivate. 2011-03-08 05:17:20 +09:00
828a59b298 Fix typo. 2011-03-07 19:17:32 +09:00
f1b91c0223 Add border style configuration (WIP). 2011-03-07 19:01:10 +09:00
cadb0f18a9 Fix gradient drawing. 2011-03-07 16:51:01 +09:00
2a8d7cf0a8 Revert to use fakekey_send_event. 2011-03-07 16:49:38 +09:00
c9b54ba87f Remove eek-theme-private.h. 2011-03-07 14:40:04 +09:00
d57ae91995 Move level change logic from key-pressed to key-released handler. 2011-03-07 14:39:35 +09:00
dd86b132ce Set pseudo class "active" to EekKey if the key is pressed. 2011-03-07 12:38:32 +09:00
3967558bae Add setter function of pseudo class. 2011-03-07 12:37:58 +09:00
668ce51f3c Mark EekKey::pressed as G_SIGNAL_RUN_FIRST. 2011-03-07 12:37:25 +09:00
1db2a4aeea Use g_object_set_qdata() to attach theme-node to element. 2011-03-07 10:42:27 +09:00
e20425f385 Add eek-theme-private.h. 2011-03-04 19:35:50 +09:00
a20224f969 Add default theme. 2011-03-04 19:23:08 +09:00
d66318a031 Fix the last commit. 2011-03-04 19:04:39 +09:00
37c2579253 Merge theme handling code (WIP). 2011-03-04 18:52:25 +09:00
23ab2a343f Fix coding style. 2011-03-04 14:28:20 +09:00
e6dfc595ab Lower gobject-introspection version requirement. 2011-03-04 13:01:17 +09:00
98e15d7741 Resolve AltGr modifier at run time. 2011-03-04 10:42:31 +09:00
38b226b46f Clear allocation box when drawing keyboard. 2011-03-03 18:18:04 +09:00
c53b4d398e Remove floating ref from a serialized keyboard. 2011-03-03 17:31:09 +09:00
fbcf6b6c65 Fix infloop when multiple clients are disconnected after another. 2011-03-03 17:02:12 +09:00
09c95b20da Add "Destroy" D-Bus signal to server for debug. 2011-03-03 16:36:10 +09:00
a7f81c3cfb Destroy clutter texture cache properly. 2011-03-03 16:04:24 +09:00
a66256f390 Fix coding style. 2011-03-03 15:53:51 +09:00
8b7da18641 Make eekboard-xml build with clutter. 2011-03-03 15:25:39 +09:00
a9c0356611 Fix XML serialization of EekOutline to include corner_radius. 2011-03-03 15:06:03 +09:00
b25a9a5407 Add comments. 2011-03-03 15:06:03 +09:00
8b632356e9 Fix memleaks. 2011-03-03 15:05:59 +09:00
b8a01d794e Check if the server is active. 2011-03-03 12:23:31 +09:00
cfd33921a1 Fix crash with clutter build. 2011-03-02 18:49:39 +09:00
979aa010b9 Update gobject-introspection version requirement. 2011-03-02 18:40:01 +09:00
de064ba0c0 Update version to 0.90.3. 2011-03-02 17:05:01 +09:00
ff200d9562 Add xklutil.h to noinst_HEADERS. 2011-03-02 17:05:01 +09:00
a8148683d3 Fix typo in desktop-client.c. 2011-03-02 17:01:09 +09:00
838a15d31a Add doc for EekKeysym. 2011-03-02 16:56:16 +09:00
2d66bf24fb Add doc for EekSymbol. 2011-03-02 16:52:30 +09:00
64bc7cc955 Fix commit ab08955a. 2011-03-02 16:45:35 +09:00
362f8ec0cb Add xkl options to eekboard-desktop-client. 2011-03-02 16:39:13 +09:00
d99a40df94 Compile xklutil.c at once. 2011-03-02 16:38:40 +09:00
ab08955a5f Make the return value of eek_symbol_get_label const. 2011-03-02 16:15:16 +09:00
577fcd7f9e Add files to POTFILES.*. 2011-03-02 16:10:56 +09:00
7da92bf04c Make the window not maximizable (RHBZ#680406). 2011-03-02 16:05:51 +09:00
f7caf6fe49 Handle Num_Lock correctly (RHBZ#680826). 2011-03-02 15:44:35 +09:00
d111edd76a Update doc index. 2011-03-02 11:49:30 +09:00
b2657c06a8 Move symbol-index property per-element instead of per-keyboard. 2011-03-02 11:47:09 +09:00
fccf9e8805 Fix icon position calculation. 2011-03-01 16:25:37 +09:00
7fc80705dd Fix serializing nullable properties of EekSymbol. 2011-03-01 12:51:59 +09:00
9007f31c0a Fix icon size calculation. 2011-03-01 12:51:46 +09:00
18f8e5b98b Draw key with icon if EekSymbol has "icon-name" property. 2011-03-01 11:57:07 +09:00
0087f74178 Make input context have multiple keyboards. 2011-02-28 18:19:04 +09:00
639ad8df91 Add -g option to eekboard-xml. 2011-02-28 12:24:27 +09:00
e8af3dacf1 Assign LETTER category to letter keysyms. 2011-02-28 12:24:16 +09:00
5d42fb8294 Read keysym label from XML attribute. 2011-02-25 18:18:05 +09:00
4440a2f1ac Release dragged key when gtk keyboard is disposed. 2011-02-25 18:17:05 +09:00
c9cee89d7e Fix translation. 2011-02-25 13:14:17 +09:00
1c3d20ad6f Add command-line option to specify D-Bus type and address. 2011-02-25 11:10:36 +09:00
40862fcf12 0.90.2 released. 2011-02-24 17:40:24 +09:00
110b25a64b Update translation. 2011-02-24 17:39:15 +09:00
f1a44ddebb Rebuild eek.types when compiling doc from tarball. 2011-02-24 17:38:22 +09:00
fc00d86c7e Avoid I_() from being translated. 2011-02-24 17:37:42 +09:00
4a822fe52c Fix typo. 2011-02-24 14:45:19 +09:00
6587f00c2a Reuse window. 2011-02-24 14:43:13 +09:00
3b77502b97 Add Python binding. 2011-02-24 13:14:33 +09:00
d7554b9735 Doc fix. 2011-02-24 11:43:15 +09:00
798df5c136 Use g_intern_static_string for signal names. 2011-02-24 10:37:48 +09:00
22c70976db Remove unused get_keyboard function. 2011-02-24 10:37:48 +09:00
3eeb7cd8ab Rename EekboardServer to EekboardEekboard. 2011-02-24 10:37:48 +09:00
7ef245d739 Fix clutter build. 2011-02-24 10:36:00 +09:00
9a6b3b3e2d Update ServerContext#enabled before showing/hiding window. 2011-02-23 19:40:01 +09:00
715c9ca022 Add padding to EekboardServerClass and EekboardContextClass. 2011-02-23 18:48:40 +09:00
5f57ea7fe6 0.90.1 released. 2011-02-23 15:12:39 +09:00
37b2e60e99 Minor fixes for make distcheck. 2011-02-23 15:11:33 +09:00
95024543cc Rename system-client to desktop-client. 2011-02-23 14:52:40 +09:00
3f1abe8350 Add some keysym labels. 2011-02-23 14:52:32 +09:00
50895d08e1 Avoid to send KeyboardVisibilityChanged on SetKeyboard and SetGroup. 2011-02-23 14:51:25 +09:00
6747e07166 Quit system-client when user closed a keyboard window. 2011-02-23 14:31:42 +09:00
994d0a9a7e Show keyboard if --listen-focus is not passed to eekboard-system-client. 2011-02-23 13:16:12 +09:00
3f7562809e Clear all input contexts associated with disconnected client. 2011-02-23 13:15:39 +09:00
5fd8477a21 Add icons. 2011-02-23 13:13:49 +09:00
faa5d60bea Make the default border width to 1. 2011-02-23 05:45:46 +09:00
02d41b8dfe Add aliases of known keysyms. 2011-02-23 05:45:27 +09:00
caf105cbd9 Add doc. 2011-02-23 05:14:14 +09:00
2c067482de Enable the previous context if the current context is vanished. 2011-02-22 22:55:20 +09:00
bf8d119a0e Make sure to remove context from the stack if the client is disconnected. 2011-02-22 22:41:12 +09:00
3f83b578de Add some libs to avoid implicit DSO linking. 2011-02-22 22:08:17 +09:00
16fe4a3565 Fix fakekey modifier handling. 2011-02-22 19:33:39 +09:00
abf16370ad Update README. 2011-02-22 19:18:55 +09:00
a93b84c32e Add D-Bus service entry. 2011-02-22 19:07:36 +09:00
267f983ca1 Fix window title and icon. 2011-02-22 18:59:52 +09:00
50e9f3186a Tune input context suspend/resume behavior. 2011-02-22 18:38:11 +09:00
d25114b370 Allow the server to have multiple input contexts. 2011-02-22 17:22:36 +09:00
12cc310e38 Make sure that a key is not pressed when sending new "pressed" event of it. 2011-02-21 16:13:19 +09:00
bf2b9c968d Move name owning code from server.c to server-main.c. 2011-02-21 16:13:14 +09:00
4a0cda72a2 Maintain group in EekboardKeyboard. 2011-02-18 19:13:25 +09:00
e3e3b60f1e Add VisibilityChanged signal. 2011-02-18 18:06:42 +09:00
ddfc0422b4 Add assertions. 2011-02-18 17:18:48 +09:00
42bf50f6a3 Fix indent. 2011-02-18 17:13:45 +09:00
47428b8959 Define eek_symbol_is_modifier as function. 2011-02-18 17:13:14 +09:00
0965ed680d Make eek-xml-layout.h public. 2011-02-18 17:12:30 +09:00
8f8139e7dc Maintain EekKeyboard in EekboardKeyboardPrivate. 2011-02-18 17:11:16 +09:00
c3e10343b4 Cosmetic fixes. 2011-02-18 14:03:51 +09:00
3aa2e6f425 Strip prefix "Eekboard". 2011-02-18 14:03:37 +09:00
66bfa4da1d Fix GI annotation. 2011-02-18 14:03:19 +09:00
d09ca88101 Export class definitions to eekboard-keyboard.h 2011-02-18 12:19:28 +09:00
453429f860 Fix include path for GISCAN and GICOMP. 2011-02-18 11:42:53 +09:00
fdd9c3d0ee Rename EekboardDevice to EekboardKeyboard. 2011-02-18 11:39:16 +09:00
22a51a2813 Fix the last commit. 2011-02-14 18:49:28 +09:00
89c5c46dbb Rename EekboardProxy to EekboardDevice. 2011-02-14 18:47:23 +09:00
ab43010a98 Seperate out GDBus proxy into libeekboard from src/. 2011-02-14 18:27:49 +09:00
7916930160 Implement serialization to GVariant. 2011-02-14 14:13:02 +09:00
11026923bd Ignore some files. 2011-02-07 03:50:00 +01:00
2d50b96881 Don't mention --listen-keystroke option. 2011-02-06 11:45:33 +01:00
23d1819f40 Make sure to include config.h to check HAVE_CSPI and HAVE_FAKEKEY. 2011-02-05 03:36:46 +01:00
b631f54a54 Implement serialization to GVariant (WIP). 2011-02-02 18:41:26 +09:00
453c3fee79 Make EekLayout abstract. 2011-02-02 16:59:13 +09:00
d7c9626df9 Remove debug print. 2011-02-02 13:10:25 +09:00
c7a2be629f Set empty keysym matrix if keycode is 0. 2011-02-02 13:10:07 +09:00
a2c9aa6742 Add libxklavier option to eekboard-xml. 2011-02-02 13:09:39 +09:00
56abc55bb2 Make fakekey and CSPI optional. 2011-02-02 06:51:27 +09:00
d2fc32f2a7 Doc fix. 2011-02-01 22:50:14 +09:00
b221010800 Doc fix. 2011-02-01 22:39:24 +09:00
8537c42756 Rename eek-example-xml to eekboard-xml. 2011-02-01 19:04:43 +09:00
aae296696d Doc fix. 2011-02-01 18:28:04 +09:00
74eb0f3c35 Set "keep-above" property to the window. 2011-02-01 18:27:39 +09:00
68b0d64fee Use 0 as EEK_INVALID_KEYCODE/KEYSYM instead of -1. 2011-02-01 18:27:13 +09:00
fd6035c54a Hide window when focus listener detects focus out. 2011-02-01 17:54:15 +09:00
a1dd32b121 Ignore modifier keys in AccessibleKeystrokeListener. 2011-02-01 17:37:52 +09:00
c9c9a3297b Coding style fix. 2011-02-01 16:54:31 +09:00
0422352139 Make sure to disconnect signal handlers in dispose(). 2011-02-01 16:48:15 +09:00
4b590dc05d Fix modifier handling using libfakekey. 2011-02-01 16:40:49 +09:00
0f33ced9bc Doc fix. 2011-02-01 15:20:36 +09:00
2831d58dcd Reimplement keystroke listener. 2011-02-01 13:04:48 +09:00
eb646ff769 Separate --listen-focus/--listen-keystroke option of eekboard-system-client. 2011-02-01 12:43:33 +09:00
aed12cd831 Make sure to disconnect signal handlers on dispose. 2011-02-01 12:25:34 +09:00
30d88ceb78 Add Clutter support to eekboard-server. 2011-02-01 11:24:51 +09:00
f66d20972d Doc fix: keycode is not necessarily the same as the X keycode. 2011-02-01 11:07:39 +09:00
7055f5fa50 Fix doc. 2011-02-01 11:01:16 +09:00
6bbbe27c9a Add eekboard-client. 2011-02-01 11:01:03 +09:00
5cb5e057e7 Don't use libnotify. 2011-02-01 07:48:39 +09:00
134faacb5e Reimplement eekboard as a D-Bus server. 2011-02-01 07:48:02 +09:00
b2ad88bd01 Fix #include ordering. 2011-02-01 07:35:35 +09:00
e999883c58 Generate unique id for <key id="...">. 2011-02-01 07:33:44 +09:00
6258476713 Don't ignore unknown keysym category. 2011-02-01 07:32:23 +09:00
53b96d3f44 Fix unicode keysym. 2011-02-01 07:31:48 +09:00
da4552c61c Use 0 as fallback group, instead of -1. 2011-02-01 07:31:20 +09:00
8b563740f5 Simplify test-keyboard.xml. 2011-01-31 23:49:30 +09:00
6137b7e1f5 Add a sample program eek-example-xml. 2011-01-31 23:39:56 +09:00
a7b276c3c4 Use "M" to calculate font size if a keyboard has no letter key. 2011-01-29 10:59:34 +09:00
6a063c9d76 Uncomment XML layout scaling code. 2011-01-29 10:58:37 +09:00
ac71ea0035 Make sure to chain-up finalize method. 2011-01-28 21:19:43 +09:00
879c50a6b8 Fix typo. 2011-01-28 21:17:01 +09:00
4e1ad08e90 Doc fix. 2011-01-28 18:49:16 +09:00
45b18c7ada Embed keycode as <key id="key<keycode>"> in the XML output. 2011-01-28 17:39:37 +09:00
ca5873022a Add license text. 2011-01-28 17:06:17 +09:00
b004a92e8a Fix EEK_MODIFIER_BEHAVIOR_LATCH when pressing Shift twice. 2011-01-28 16:55:01 +09:00
e6df7d90fe Use GObject instead of guint to represent keysyms. 2011-01-28 16:19:18 +09:00
4ff254df97 Remove unused funcdecl. 2011-01-28 15:53:17 +09:00
0c77bd45f2 Don't embed native keycode/keysym values in XML layout data. 2011-01-27 19:06:59 +09:00
880ba76bd8 Update copyright year. 2011-01-27 16:58:59 +09:00
327817e7ea Add license header to eek-xml*.[ch]. 2011-01-27 16:56:16 +09:00
2c98207799 Add --xml option to eekboard. 2011-01-27 16:49:45 +09:00
6c2ef567c4 Doc fix. 2011-01-27 16:49:35 +09:00
4f9b504d90 Add version macro for XML schema. 2011-01-27 16:48:48 +09:00
b811796bbc Finish XML layout engine. 2011-01-27 16:27:06 +09:00
4008706bb0 Remove useless get_group method and group_changed signal of EekLayout. 2011-01-27 11:09:24 +09:00
20acd11425 Don't use floating object for EekElement. 2011-01-27 09:55:24 +09:00
b36e2f09de Fix outline caching in XML layout. 2011-01-26 19:28:10 +09:00
d29e83e5f6 Add XML layout engine (WIP). 2011-01-26 19:24:06 +09:00
0dd37a39b9 Add XML layout engine (WIP). 2011-01-26 19:17:32 +09:00
b22858f9cf Remove useless assertion. 2011-01-26 19:16:52 +09:00
4accb1e952 Doc fix. 2011-01-26 12:50:22 +09:00
5e4a6b2c8e Port modifier handling code from application into library. 2011-01-26 11:59:12 +09:00
79986e47b6 Remove unused variables. 2011-01-26 11:12:21 +09:00
45cd7958d0 Don't cache group/level in EekKey. 2011-01-26 07:57:44 +09:00
7bdc984933 Add new symbols to GTK-Doc sections.txt. 2011-01-25 18:43:07 +09:00
76f3ef75d5 Fix eek_keyboard_new arglist. 2011-01-25 18:42:29 +09:00
13e4d1cdb3 Add convenient function to get/set per-keyboard group/level. 2011-01-25 18:32:52 +09:00
70df392647 Avoid to use Clutter scaling feature. 2011-01-25 18:10:42 +09:00
ae857f5981 Fix typo in eek_clutter_renderer_new. 2011-01-25 18:09:02 +09:00
cb49214667 Update README. 2011-01-25 18:08:36 +09:00
48e64f1c32 Move eek_keyboard_new to eek-layout.c; add utility functions. 2011-01-25 16:17:34 +09:00
9b1a53510e Delay the initialization of EekClutter* until ClutterActor::realize. 2011-01-25 15:20:20 +09:00
c6aa173202 Add EekGtkKeyboard:keyboard property. 2011-01-25 14:41:57 +09:00
907fc3f872 Define EekLayout as a class instead of an interface. 2011-01-25 14:29:57 +09:00
406a59277f Remove duplicate files in $(libeek_public_headers) in Makefile.am. 2011-01-25 11:28:13 +09:00
f094466d64 Add license text. 2011-01-25 11:10:53 +09:00
af8274f305 Fix GTK-Doc comment. 2011-01-25 11:06:03 +09:00
420b8014f8 Revive Clutter support. 2011-01-25 10:40:25 +09:00
9e5fa977a5 Split eek_renderer_render_key to e_r_r_key_label and e_r_r_key_outline. 2011-01-25 10:38:56 +09:00
fe101ff0e8 Rename eek_renderer_set_preferred_size to e_r_s_allocation_size. 2011-01-23 17:29:10 +09:00
0ba067aa15 Fix memleak; fix eek_gtk_keyboard_new doc. 2011-01-23 16:59:05 +09:00
192cab67e9 Fix "keysym-index-changed" callback of EekGtkKeyboard. 2011-01-22 16:50:15 +09:00
fa08da847a Don't install eek-clutter*.pc if Clutter build is disabled. 2011-01-22 16:27:59 +09:00
81d40c829d Add doc. 2011-01-22 16:24:38 +09:00
6e978cae63 Move "blank background" code from EekGtkKeyboard to EekRenderer. 2011-01-22 16:13:53 +09:00
a0167c4cc2 Re-organize API.
EekGtkKeyboard is now a subclass of GtkWidget not EekKeyboard.  Widget
creation is done as follows:

layout = eek_xkl_layout_new (...);
keyboard = eek_keyboard_new (layout, 640, 480);
widget = eek_gtk_keyboard_new (keyboard);

Broken Clutter support is temporarily disabled.
2011-01-22 11:55:29 +09:00
cab893b4aa Remove unused EekContainer#find_element_by_position. 2011-01-22 11:42:56 +09:00
8399acda83 libeek: add EekKey#is_pressed. 2011-01-22 11:42:56 +09:00
12550f4bc3 Re-implement Cairo-based rendering. 2011-01-22 11:42:56 +09:00
2ec76cad54 Bump API version; ignore eek-marshallers.[ch]. 2011-01-22 11:42:52 +09:00
47602652e4 Fix coding-style. 2011-01-22 11:25:55 +09:00
158ddf2269 libeek: add new signal "keysym-index-changed" to EekKeyboard 2011-01-22 11:25:55 +09:00
71d5259f85 libeek: define new boxed type EekColor for colors 2011-01-22 11:25:51 +09:00
1ddf39b3da eekboard: replace GTK2_* with GTK_*. 2011-01-19 13:14:04 +09:00
8b9981970d Reorganize build infrastructure.
Generate glib marshallers for libeek, check for pangocairo instead of checking
pango and cairo individually, and link libeek against pango and cairo.
2011-01-19 12:37:06 +09:00
4accc5e2ac eekboard: don't use deprecated gtk_quit_add. 2011-01-13 16:05:54 +09:00
dc4e802bd1 libeek/gtk: add compatibility macro for gdk_cairo_create (>= 2.91.5) 2011-01-13 15:20:44 +09:00
7b368057e3 eekboard: set window opacity based on the gconf setting 2011-01-12 15:59:45 +09:00
2ea6fa9611 eekboard: support fullscreen mode 2011-01-12 15:59:16 +09:00
125fd4c65c libeek/gtk: fix scale and geometry calculation 2011-01-12 15:45:36 +09:00
cf4d1109d3 Update to 0.0.7. 2010-12-06 14:44:01 +09:00
c7c6d06907 eekboard: Reset modifiers just after normal key press. 2010-12-06 14:42:14 +09:00
384d43bb80 libeek: Fix gtk keyboard rendering. 2010-12-06 13:06:11 +09:00
29c55b6ca3 Suppress compiler warnings. 2010-12-06 12:12:52 +09:00
910b0be5a5 eekboard: listen xklavier status events. 2010-12-06 12:09:17 +09:00
706fa6310b Define AM_SILENT_RULES. 2010-12-06 11:33:32 +09:00
248699d771 eekboard: change the default behavior to "standalone" mode. 2010-12-06 11:19:47 +09:00
6343e37bc1 eekboard: reduce the number of allocs when parsing a config file. 2010-12-06 11:18:18 +09:00
f562e8c212 0.0.6 released. 2010-11-15 14:37:57 +09:00
8ff00226e2 Correct GTK API version in *.pc.in. 2010-11-15 14:35:03 +09:00
c72c75083c Fix typo. 2010-11-15 12:49:12 +09:00
862a54eac3 Fix build against libnotify >= 0.7.0. 2010-11-15 12:49:01 +09:00
12bc18e1ba Add compatibility code for GTK2. 2010-11-15 12:01:17 +09:00
f045bd0d50 Add --with-gtk configure option. 2010-11-15 11:46:12 +09:00
dfe06468ed Fix build against 2.91.5. 2010-11-12 15:12:56 +09:00
3fda8da1a5 libeek: forward decl structs to let g-ir-scanner inspect their fields. 2010-10-13 16:58:31 +09:00
d0a5715f8c libeek: Add setter for position/size of EekElement. 2010-10-13 16:21:12 +09:00
6b83bb8503 Clean up action groups on quit. 2010-10-13 15:04:41 +09:00
69f1dba96a Require clutter-gtk-1.0. 2010-09-08 10:13:33 +09:00
dcbdd7ff63 eekboard: fix AltGr handling. 2010-08-25 18:46:02 +09:00
9b28a011e7 Ignore generated files. 2010-08-23 14:50:00 +09:00
350598dc55 eekboard: handle AltGr 2010-08-20 18:39:06 +09:00
ae9df021c2 libeek: eek_keyboard_find_key_by_position(): consider overlapped sections. 2010-08-13 11:43:10 +09:00
d7cb78ecf5 libeek: suppress debug message if DEBUG is not set. 2010-08-13 10:44:08 +09:00
ef2e9acf1e Update TODO. 2010-08-13 10:43:17 +09:00
7f52069e41 libeek: terminate args of eek_xkb_layout_set_names_full() with NULL instead of -1. 2010-08-13 08:11:40 +09:00
9a5c0d9cdc libeek: more distcheck fixes. 2010-08-13 08:10:47 +09:00
551fb17e02 Fix for distcheck. 2010-08-12 17:10:34 +09:00
b5b9864033 0.0.5 released. 2010-08-12 16:54:06 +09:00
a2d2ef3a5e libeek: add eek_xkb_layout_set_names_full_valist(). 2010-08-12 12:03:21 +09:00
b09a586357 eekboard: add eekboard-sample.conf. 2010-08-12 10:19:54 +09:00
70f3bc5308 libeek: make GTK key event handling robuster. 2010-08-11 17:45:52 +09:00
8bc7b754bc eekboard: react to key events by default. 2010-08-11 17:36:33 +09:00
3d5160455a eekboard: error if config file cannot be read. 2010-08-11 16:50:10 +09:00
983cc22761 eekboard: config file support. 2010-08-11 16:45:57 +09:00
6d80e4cacb eekboard: add --toolkit and --standalone. 2010-08-11 11:49:52 +09:00
1c5a271177 eekboard: refile focus event handling. 2010-08-10 16:32:17 +09:00
e4891ccf6b eekboard: don't hide the eekboard window on a11y focus event. 2010-08-10 14:44:50 +09:00
48bfc7485f eekboard: set icon on notification. 2010-08-10 14:23:04 +09:00
2e297ab1ef Merge branch 'a11y' of github.com:ueno/eekboard into a11y 2010-08-09 12:14:30 +09:00
828fc553b4 eekboard: use libnotify to display notification. 2010-08-09 11:10:52 +09:00
08e1a6c69a Merge branch 'master' into a11y
Conflicts:
	eek/eek-gtk-keyboard.c
2010-08-05 12:38:01 +09:00
039ea44520 libeek: add eek_keyboard_find_key_by_position(). 2010-08-05 12:32:14 +09:00
65c1abbe27 eekboard: hide window by default if GNOME a11y is enabled. 2010-07-29 18:53:43 +09:00
0ab5a0f114 Implement "Monitor Key Typing" using AT-SPI C. 2010-07-22 17:34:09 +09:00
94219bd31e Ignore motion event when button is pressed. 2010-07-22 15:56:43 +09:00
7c2457e659 Remove workaround for Clutter Bug #2137. 2010-07-05 13:04:12 +09:00
a156453301 0.0.4 released. 2010-07-01 11:08:49 +09:00
c2e53ec9a9 Update translation. 2010-07-01 11:03:34 +09:00
687b2a83b4 Port GLX_INTEL_swap_event work around from Clutter-Gtk to eekboard.c. 2010-07-01 11:02:54 +09:00
a1f7d628bb Add more TODO. 2010-06-23 16:09:17 +09:00
789ee66836 Update TODO. 2010-06-23 16:06:02 +09:00
9ec42b66f3 eekboard: add command-line options 2010-06-23 16:05:52 +09:00
b2b44a0810 libeek: make temporary copies of config parameters in #set_model() etc. 2010-06-23 16:02:07 +09:00
59076afcb5 eekboard: release fakekey on quit 2010-06-23 12:14:52 +09:00
5ab24250bc libeek: check widget is realized when preparing pixmap 2010-06-23 12:14:07 +09:00
273b0653da 0.0.3 released. 2010-06-23 11:01:12 +09:00
b583cfb9f6 Fix parallel build. 2010-06-23 10:57:32 +09:00
84cdf6ec78 libeek: don't generate EekClutter-0.1.gir if --disable-clutter is given 2010-06-22 17:57:24 +09:00
4623d78e0d Cosmetic fix. 2010-06-22 17:29:55 +09:00
89cc9ffa46 0.0.2 released 2010-06-22 17:19:36 +09:00
27ddc144e0 libeek: add Since: doc-comment 2010-06-22 17:19:25 +09:00
6e54383d1d libeek: update the project URL in *.pc 2010-06-22 17:18:46 +09:00
e955bb11fa libeek: fix memory leak 2010-06-22 17:14:08 +09:00
f08c926945 eekboard: quit gracefully 2010-06-22 17:01:53 +09:00
fdb083bb12 libeek: supress compiler warning 2010-06-22 17:01:43 +09:00
e604e6af22 libeek: fix memory leak 2010-06-22 17:01:24 +09:00
9aabdc0812 Fix coding style. 2010-06-22 16:29:24 +09:00
a388d9e6e1 libeek: add wrapper functions to avoid exposing XKB/XKL structures to GIR 2010-06-22 16:14:28 +09:00
4dab7af44d Minor fix for Vala binding. 2010-06-22 14:07:44 +09:00
60a0c199eb Fix doc. 2010-06-22 13:06:42 +09:00
de7f31f067 Refine "Usage Overview". 2010-06-22 13:00:47 +09:00
ae4e29a968 Add Vala language binding. 2010-06-22 12:24:18 +09:00
f50a8a98f4 Generate gobject-introspection files. 2010-06-22 10:44:19 +09:00
b3903bcc7f libeek: draw rotated section with GTK UI 2010-06-22 10:10:24 +09:00
bc38ac837b Add a TODO entry. 2010-06-21 17:52:04 +09:00
c2c1a79046 Add more TODO entries. 2010-06-21 17:48:41 +09:00
b902e759cb eekboard: use widget allocation size for initial keyboard size 2010-06-21 17:46:44 +09:00
165 changed files with 24548 additions and 6843 deletions

30
.gitignore vendored
View File

@ -30,13 +30,23 @@ libkeyactor*.tar.*
mkinstalldirs mkinstalldirs
m4/*.m4 m4/*.m4
gtk-doc.make gtk-doc.make
eek/eek-special-keysym-labels.h eek/eek-special-keysym-entries.h
eek/eek-unicode-keysym-labels.h eek/eek-unicode-keysym-entries.h
eek/eek-keyname-keysym-labels.h eek/eek-xkeysym-keysym-entries.h
eek/eek-marshalers.[ch]
eek/*.pc eek/*.pc
eek/*.gir
eek/*.typelib
eekboard/*.pc
eekboard/*.gir
eekboard/*.typelib
tests/eek-simple-test tests/eek-simple-test
tests/eek-xkb-test tests/eek-xkb-test
src/eekboard tests/eek-xml-test
src/eekboard-server
src/eekboard-client
src/eekboard-system-client
src/eekboard-xml
docs/reference/eek/*.stamp docs/reference/eek/*.stamp
docs/reference/eek/*.txt docs/reference/eek/*.txt
!/docs/reference/eek/eek-sections.txt !/docs/reference/eek/eek-sections.txt
@ -47,8 +57,18 @@ docs/reference/eek/eek.args
docs/reference/eek/eek.hierarchy docs/reference/eek/eek.hierarchy
docs/reference/eek/eek.interfaces docs/reference/eek/eek.interfaces
docs/reference/eek/eek.prerequisites docs/reference/eek/eek.prerequisites
docs/reference/eekboard/*.stamp
docs/reference/eekboard/*.txt
!/docs/reference/eekboard/eekboard-sections.txt
docs/reference/eekboard/xml
docs/reference/eekboard/html
docs/reference/eekboard/eekboard.signals
docs/reference/eekboard/eekboard.args
docs/reference/eekboard/eekboard.hierarchy
docs/reference/eekboard/eekboard.interfaces
docs/reference/eekboard/eekboard.prerequisites
po/*.gmo po/*.gmo
po/Makefile.in.in po/Makefile.in.in
po/POTFILES po/POTFILES
po/stamp-it po/stamp-it
bindings/vala/*.vapi

38
AUTHORS
View File

@ -1,6 +1,36 @@
eekboard is written by Daiki Ueno <ueno@unixuser.org> eekboard is written by Daiki Ueno <ueno@unixuser.org>. The following
files contain code derived from other free software packages:
Cairo keyboard drawing functions are borrowed from the libgnomekbd eek/eek-keyboard-drawing.h
library by Sergey V. Udaltsov <svu@gnome.org>. See the comments in eek/eek-keyboard-drawing.c
eek/eek-drawing.c for detail.
These files contain code derived from the libgnomekbd library.
Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
eek/eek-theme.h
eek/eek-theme.c
eek/eek-theme-context.h
eek/eek-theme-context.c
eek/eek-theme-node.h
eek/eek-theme-node.c
These files contain code derived from gnome-shell.
Copyright 2008-2010 Red Hat, Inc.
Copyright 2009 Steve Frécinaux
Copyright 2009, 2010 Florian Müllner
Copyright 2010 Adel Gadllah
Copyright 2010 Giovanni Campagna
Copyright 2003-2004 Dodji Seketeli
data/icons/8x8/Makefile.am
data/icons/16x16/Makefile.am
data/icons/22x22/Makefile.am
data/icons/24x24/Makefile.am
data/icons/32x32/Makefile.am
data/icons/48x48/Makefile.am
data/icons/scalable/Makefile.am
These files contain code derived from im-chooser.
Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.

View File

@ -1,5 +1,5 @@
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> # Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010 Red Hat, Inc. # Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License # modify it under the terms of the GNU Lesser General Public License
@ -17,4 +17,5 @@
# 02110-1301 USA # 02110-1301 USA
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
SUBDIRS = eek src tests docs po SUBDIRS = eek eekboard src tests bindings docs po data
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-introspection

80
README
View File

@ -1,29 +1,75 @@
eekboard - a virtual keyboard for GNOME -*- outline -*- eekboard - an easy to use virtual keyboard toolkit -*- outline -*-
eekboard is a virtual keyboard software package which ships with a eekboard is a virtual keyboard software package, including a set of
standalone virtual keyboard application ("eekboard"), and a library to tools to implement desktop virtual keyboards.
create keyboard-like UI ("libeek").
* Requirements * How to build
* GLib2, GTK2, Cairo, Pango, Libxklavier... ** Dependencies
* Clutter (optional)
* Clutter-Gtk (optional)
* How to test REQUIRED: GLib2, GTK, GConf2, PangoCairo, libxklavier, libcroco
OPTIONAL: fakekey, CSPI, Clutter, Clutter-Gtk, Vala, gobject-introspection
If you build from git repo: ** Build from git repo
$ git clone git://github.com/ueno/eekboard.git $ git clone git://github.com/ueno/eekboard.git
$ cd eekboard $ cd eekboard
$ ./autogen.sh --prefix=/usr --enable-gtk-doc $ ./autogen.sh --prefix=/usr --enable-gtk-doc
Otherwise start from here:
$ ./configure
$ make $ make
$ sudo make install $ sudo make install
$ eekboard
*NOTE* some version combination of Clutter & Clutter-Gtk does not ** Build from tarball
cooperate well. Try "EEKBOARD_DISABLE_CLUTTER=1 eekboard"
$ ./configure --prefix=/usr
$ make
$ sudo make install
* How to test
eekboard currently includes 4 tools to implement your own virtual
keyboard.
** eekboard-server
eekboard-server is a D-Bus server which is responsible for drawing
interactive on-screen keyboards. Since it has a D-Bus service
activation entry, you will not need to start it manually, but you can
do that with:
$ eekboard-server &
** eekboard-desktop-client
eekboard-desktop-client is a client of eekboard-server. It listens
desktop events (keyboard change, focus in/out, and keystroke) and
generates key events when some keys are pressed on the on-screen
keyboard. It can be started with:
$ eekboard-desktop-client
** eekboard-xml
eekboard-xml is a tool to manipulate XML keyboard description used by
eekboard-client tool and in the eekboard library.
To dump the current system keyboard layout into an XML file:
$ eekboard-xml --dump > keyboard.xml
You can display the dumped layout with:
$ eekboard-xml --load keyboard.xml
** eekboard-client
eekboard-client is a simple test client of eekboard-server. To upload
the keyboard description to the server, display it, and listen
key events.
$ eekboard-client --set-keyboard keyboard.xml --show-keyboard --listen
KeyPressed XXXXX
KeyReleased XXXXX
* Documentation
See file:docs/reference/eek/html/index.html

13
TODO
View File

@ -1,12 +1 @@
- packaging See https://github.com/ueno/eekboard/wiki/TODO
-- GIR
-- .spec
-- debian
-- add more tests
- eekboard
-- a11y
- libeek
-- matchbox-keyboard layout engine
-- delay initialization of XKB and XKL layouts

View File

@ -19,6 +19,7 @@ which gnome-autogen.sh || {
} }
ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4" ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
REQUIRED_AUTOMAKE_VERSION=1.8 REQUIRED_AUTOMAKE_VERSION=1.10
REQUIRED_AUTOCONF_VERSION=2.60
. gnome-autogen.sh . gnome-autogen.sh

27
bindings/Makefile.am Normal file
View File

@ -0,0 +1,27 @@
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public 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
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
SUBDIRS =
if ENABLE_PYTHON
SUBDIRS += python
endif
if ENABLE_VALA
SUBDIRS += vala
endif

View File

@ -0,0 +1,18 @@
# Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2011 Red Hat, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program 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
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
SUBDIRS = eekboard

View File

@ -0,0 +1,21 @@
# Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2011 Red Hat, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program 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
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
pkgpython_PYTHON = \
__init__.py \
eekboard.py \
context.py

View File

@ -0,0 +1,63 @@
# Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2011 Red Hat, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program 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
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
from gi.repository import Eek, EekXkl, Gio
from eekboard import Eekboard
from context import Context
Keyboard = Eek.Keyboard
Section = Eek.Section
Key = Eek.Key
Symbol = Eek.Symbol
Keysym = Eek.Keysym
MODIFIER_BEHAVIOR_NONE, \
MODIFIER_BEHAVIOR_LOCK, \
MODIFIER_BEHAVIOR_LATCH = \
(Eek.ModifierBehavior.NONE,
Eek.ModifierBehavior.LOCK,
Eek.ModifierBehavior.LATCH)
CSW = 640
CSH = 480
def XmlKeyboard(path, modifier_behavior=MODIFIER_BEHAVIOR_NONE):
_file = Gio.file_new_for_path(path)
layout = Eek.XmlLayout.new(_file.read())
keyboard = Eek.Keyboard.new(layout, CSW, CSH)
keyboard.set_modifier_behavior(modifier_behavior)
return keyboard
def XklKeyboard(modifier_behavior=MODIFIER_BEHAVIOR_NONE):
layout = EekXkl.Layout.new()
keyboard = Eek.Keyboard.new(layout, CSW, CSH)
keyboard.set_modifier_behavior(modifier_behavior)
return keyboard
__all__ = ['Eekboard',
'Context',
'Keyboard',
'Section',
'Key',
'Symbol',
'Keysym',
'MODIFIER_BEHAVIOR_NONE',
'MODIFIER_BEHAVIOR_LOCK',
'MODIFIER_BEHAVIOR_LATCH',
'XmlKeyboard',
'XklKeyboard']

View File

@ -0,0 +1,79 @@
# Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2011 Red Hat, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program 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
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
from gi.repository import Eekboard
import gobject
class Context(gobject.GObject):
__gtype_name__ = "PYEekboardContext"
__gsignals__ = {
'enabled': (
gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
()),
'disabled': (
gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
()),
'key-pressed': (
gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
(gobject.TYPE_UINT,)),
'key-released': (
gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
(gobject.TYPE_UINT,))
}
def __init__(self, giobject):
super(Context, self).__init__()
import sys
self.__giobject = giobject
self.__giobject.connect('enabled', lambda *args: self.emit('enabled'))
self.__giobject.connect('disabled', lambda *args: self.emit('disabled'))
self.__giobject.connect('key-pressed', lambda *args: self.emit('key-pressed', args[1]))
self.__giobject.connect('key-released', lambda *args: self.emit('key-released', args[1]))
def get_giobject(self):
return self.__giobject
def add_keyboard(self, keyboard):
return self.__giobject.add_keyboard(keyboard, None)
def remove_keyboard(self, keyboard_id):
return self.__giobject.remove_keyboard(keyboard_id, None)
def set_keyboard(self, keyboard_id):
self.__giobject.set_keyboard(keyboard_id, None)
def show_keyboard(self):
self.__giobject.show_keyboard(None)
def hide_keyboard(self):
self.__giobject.hide_keyboard(None)
def set_group(self, group):
self.__giobject.set_group(group, None)
def press_key(self, keycode):
self.__giobject.press_key(keycode, None)
def release_key(self, keycode):
self.__giobject.release_key(keycode, None)
def is_enabled(self):
return self.__giobject.is_enabled()

View File

@ -0,0 +1,42 @@
# Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2011 Red Hat, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program 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
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
from gi.repository import Gio
import gi.repository
import gobject
from context import Context
class Eekboard(gobject.GObject):
__gtype_name__ = "PYEekboardEekboard"
def __init__(self):
super(Eekboard, self).__init__()
self.__connection = Gio.bus_get_sync(Gio.BusType.SESSION, None)
self.__eekboard = gi.repository.Eekboard.Eekboard.new(self.__connection, None);
def create_context(self, client_name):
context = self.__eekboard.create_context(client_name, None)
return Context(context)
def push_context(self, context):
self.__eekboard.push_context(context.get_giobject(), None)
def pop_context(self):
self.__eekboard.pop_context(None)
def destroy_context(self, context):
self.__eekboard.destroy_context(context.get_giobject(), None)

50
bindings/vala/Makefile.am Normal file
View File

@ -0,0 +1,50 @@
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public 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
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
vapidir = $(datadir)/vala/vapi
dist_vapi_DATA = \
eek-$(EEK_API_VERSION).vapi \
eek-clutter-$(EEK_API_VERSION).vapi \
eek-gtk-$(EEK_API_VERSION).vapi \
eek-xkb-$(EEK_API_VERSION).vapi \
eek-xkl-$(EEK_API_VERSION).vapi
MAINTAINERCLEANFILES = $(dist_vapi_DATA)
eek-$(EEK_API_VERSION).vapi:
vapigen --library eek-$(EEK_API_VERSION) \
eek-$(EEK_API_VERSION)/eek-$(EEK_API_VERSION).gi
eek-clutter-$(EEK_API_VERSION).vapi: eek-$(EEK_API_VERSION).vapi
vapigen --vapidir=$(builddir) --library eek-clutter-$(EEK_API_VERSION) \
--pkg eek-$(EEK_API_VERSION) --pkg clutter-1.0 \
eek-clutter-$(EEK_API_VERSION)/eek-clutter-$(EEK_API_VERSION).gi
eek-gtk-$(EEK_API_VERSION).vapi: eek-$(EEK_API_VERSION).vapi
vapigen --vapidir=$(builddir) --library eek-gtk-$(EEK_API_VERSION) \
--pkg eek-$(EEK_API_VERSION) --pkg gtk+-2.0 \
eek-gtk-$(EEK_API_VERSION)/eek-gtk-$(EEK_API_VERSION).gi
eek-xkb-$(EEK_API_VERSION).vapi: eek-$(EEK_API_VERSION).vapi
vapigen --vapidir=$(builddir) --library eek-xkb-$(EEK_API_VERSION) \
--pkg eek-$(EEK_API_VERSION) \
eek-xkb-$(EEK_API_VERSION)/eek-xkb-$(EEK_API_VERSION).gi
eek-xkl-$(EEK_API_VERSION).vapi: eek-xkb-$(EEK_API_VERSION).vapi
vapigen --vapidir=$(builddir) --library eek-xkl-$(EEK_API_VERSION) \
--pkg eek-$(EEK_API_VERSION) --pkg eek-xkb-$(EEK_API_VERSION) \
eek-xkl-$(EEK_API_VERSION)/eek-xkl-$(EEK_API_VERSION).gi

View File

@ -0,0 +1,9 @@
include/eek-0.1/eek/eek-layout.h
include/eek-0.1/eek/eek-element.h
include/eek-0.1/eek/eek-container.h
include/eek-0.1/eek/eek-keyboard.h
include/eek-0.1/eek/eek-section.h
include/eek-0.1/eek/eek-key.h
include/eek-0.1/eek/eek-types.h
include/eek-0.1/eek/eek-keysym.h
lib/libeek.so

View File

@ -0,0 +1,680 @@
<?xml version="1.0"?>
<api version="1.0">
<namespace name="Eek">
<function name="keysym_get_category" symbol="eek_keysym_get_category">
<return-type type="EekKeysymCategory"/>
<parameters>
<parameter name="keysym" type="guint"/>
</parameters>
</function>
<function name="keysym_to_string" symbol="eek_keysym_to_string">
<return-type type="gchar*"/>
<parameters>
<parameter name="keysym" type="guint"/>
</parameters>
</function>
<callback name="EekCallback">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</callback>
<callback name="EekCompareFunc">
<return-type type="gint"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</callback>
<boxed name="EekBounds" type-name="EekBounds" get-type="eek_bounds_get_type">
<field name="x" type="gdouble"/>
<field name="y" type="gdouble"/>
<field name="width" type="gdouble"/>
<field name="height" type="gdouble"/>
</boxed>
<boxed name="EekKeysymMatrix" type-name="EekKeysymMatrix" get-type="eek_keysym_matrix_get_type">
<field name="data" type="guint*"/>
<field name="num_groups" type="gint"/>
<field name="num_levels" type="gint"/>
</boxed>
<boxed name="EekOutline" type-name="EekOutline" get-type="eek_outline_get_type">
<field name="corner_radius" type="gdouble"/>
<field name="points" type="EekPoint*"/>
<field name="num_points" type="gint"/>
</boxed>
<boxed name="EekPoint" type-name="EekPoint" get-type="eek_point_get_type">
<field name="x" type="gdouble"/>
<field name="y" type="gdouble"/>
</boxed>
<enum name="EekKeysymCategory">
<member name="EEK_KEYSYM_CATEGORY_LETTER" value="0"/>
<member name="EEK_KEYSYM_CATEGORY_FUNCTION" value="1"/>
<member name="EEK_KEYSYM_CATEGORY_KEYNAME" value="2"/>
<member name="EEK_KEYSYM_CATEGORY_UNKNOWN" value="3"/>
<member name="EEK_KEYSYM_CATEGORY_LAST" value="3"/>
</enum>
<enum name="EekOrientation">
<member name="EEK_ORIENTATION_VERTICAL" value="0"/>
<member name="EEK_ORIENTATION_HORIZONTAL" value="1"/>
<member name="EEK_ORIENTATION_INVALID" value="-1"/>
</enum>
<object name="EekContainer" parent="EekElement" type-name="EekContainer" get-type="eek_container_get_type">
<method name="find" symbol="eek_container_find">
<return-type type="EekElement*"/>
<parameters>
<parameter name="container" type="EekContainer*"/>
<parameter name="func" type="EekCompareFunc"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</method>
<method name="find_by_position" symbol="eek_container_find_by_position">
<return-type type="EekElement*"/>
<parameters>
<parameter name="container" type="EekContainer*"/>
<parameter name="x" type="gdouble"/>
<parameter name="y" type="gdouble"/>
</parameters>
</method>
<method name="foreach_child" symbol="eek_container_foreach_child">
<return-type type="void"/>
<parameters>
<parameter name="container" type="EekContainer*"/>
<parameter name="callback" type="EekCallback"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</method>
<signal name="child-added" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="element" type="EekElement*"/>
</parameters>
</signal>
<signal name="child-removed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="element" type="EekElement*"/>
</parameters>
</signal>
<vfunc name="add_child">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="element" type="EekElement*"/>
</parameters>
</vfunc>
<vfunc name="find">
<return-type type="EekElement*"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="func" type="EekCompareFunc"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</vfunc>
<vfunc name="foreach_child">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="callback" type="EekCallback"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</vfunc>
<vfunc name="remove_child">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="element" type="EekElement*"/>
</parameters>
</vfunc>
</object>
<object name="EekElement" parent="GInitiallyUnowned" type-name="EekElement" get-type="eek_element_get_type">
<method name="get_absolute_position" symbol="eek_element_get_absolute_position">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="x" type="gdouble*"/>
<parameter name="y" type="gdouble*"/>
</parameters>
</method>
<method name="get_bounds" symbol="eek_element_get_bounds">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="bounds" type="EekBounds*"/>
</parameters>
</method>
<method name="get_name" symbol="eek_element_get_name">
<return-type type="gchar*"/>
<parameters>
<parameter name="element" type="EekElement*"/>
</parameters>
</method>
<method name="get_parent" symbol="eek_element_get_parent">
<return-type type="EekElement*"/>
<parameters>
<parameter name="element" type="EekElement*"/>
</parameters>
</method>
<method name="set_bounds" symbol="eek_element_set_bounds">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="bounds" type="EekBounds*"/>
</parameters>
</method>
<method name="set_name" symbol="eek_element_set_name">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="name" type="gchar*"/>
</parameters>
</method>
<method name="set_parent" symbol="eek_element_set_parent">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="parent" type="EekElement*"/>
</parameters>
</method>
<property name="bounds" type="EekBounds*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="name" type="char*" readable="1" writable="1" construct="0" construct-only="0"/>
<vfunc name="get_bounds">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekElement*"/>
<parameter name="bounds" type="EekBounds*"/>
</parameters>
</vfunc>
<vfunc name="get_name">
<return-type type="gchar*"/>
<parameters>
<parameter name="self" type="EekElement*"/>
</parameters>
</vfunc>
<vfunc name="get_parent">
<return-type type="EekElement*"/>
<parameters>
<parameter name="self" type="EekElement*"/>
</parameters>
</vfunc>
<vfunc name="set_bounds">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekElement*"/>
<parameter name="bounds" type="EekBounds*"/>
</parameters>
</vfunc>
<vfunc name="set_name">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekElement*"/>
<parameter name="name" type="gchar*"/>
</parameters>
</vfunc>
<vfunc name="set_parent">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekElement*"/>
<parameter name="parent" type="EekElement*"/>
</parameters>
</vfunc>
</object>
<object name="EekKey" parent="EekElement" type-name="EekKey" get-type="eek_key_get_type">
<method name="get_index" symbol="eek_key_get_index">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="column" type="gint*"/>
<parameter name="row" type="gint*"/>
</parameters>
</method>
<method name="get_keycode" symbol="eek_key_get_keycode">
<return-type type="guint"/>
<parameters>
<parameter name="key" type="EekKey*"/>
</parameters>
</method>
<method name="get_keysym" symbol="eek_key_get_keysym">
<return-type type="guint"/>
<parameters>
<parameter name="key" type="EekKey*"/>
</parameters>
</method>
<method name="get_keysym_index" symbol="eek_key_get_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="group" type="gint*"/>
<parameter name="level" type="gint*"/>
</parameters>
</method>
<method name="get_keysyms" symbol="eek_key_get_keysyms">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="keysyms" type="guint**"/>
<parameter name="num_groups" type="gint*"/>
<parameter name="num_levels" type="gint*"/>
</parameters>
</method>
<method name="get_outline" symbol="eek_key_get_outline">
<return-type type="EekOutline*"/>
<parameters>
<parameter name="key" type="EekKey*"/>
</parameters>
</method>
<method name="set_index" symbol="eek_key_set_index">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="column" type="gint"/>
<parameter name="row" type="gint"/>
</parameters>
</method>
<method name="set_keycode" symbol="eek_key_set_keycode">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</method>
<method name="set_keysym_index" symbol="eek_key_set_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="group" type="gint"/>
<parameter name="level" type="gint"/>
</parameters>
</method>
<method name="set_keysyms" symbol="eek_key_set_keysyms">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="keysyms" type="guint*"/>
<parameter name="num_groups" type="gint"/>
<parameter name="num_levels" type="gint"/>
</parameters>
</method>
<method name="set_outline" symbol="eek_key_set_outline">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="outline" type="EekOutline*"/>
</parameters>
</method>
<property name="column" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="group" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="keycode" type="guint" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="keysyms" type="EekKeysymMatrix*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="level" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="outline" type="gpointer" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="row" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<signal name="pressed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
</parameters>
</signal>
<signal name="released" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
</parameters>
</signal>
<vfunc name="get_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="column" type="gint*"/>
<parameter name="row" type="gint*"/>
</parameters>
</vfunc>
<vfunc name="get_keycode">
<return-type type="guint"/>
<parameters>
<parameter name="self" type="EekKey*"/>
</parameters>
</vfunc>
<vfunc name="get_keysym">
<return-type type="guint"/>
<parameters>
<parameter name="self" type="EekKey*"/>
</parameters>
</vfunc>
<vfunc name="get_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="group" type="gint*"/>
<parameter name="level" type="gint*"/>
</parameters>
</vfunc>
<vfunc name="get_keysyms">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="keysyms" type="guint**"/>
<parameter name="num_groups" type="gint*"/>
<parameter name="num_levels" type="gint*"/>
</parameters>
</vfunc>
<vfunc name="get_outline">
<return-type type="EekOutline*"/>
<parameters>
<parameter name="self" type="EekKey*"/>
</parameters>
</vfunc>
<vfunc name="set_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="column" type="gint"/>
<parameter name="row" type="gint"/>
</parameters>
</vfunc>
<vfunc name="set_keycode">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</vfunc>
<vfunc name="set_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="group" type="gint"/>
<parameter name="level" type="gint"/>
</parameters>
</vfunc>
<vfunc name="set_keysyms">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="keysyms" type="guint*"/>
<parameter name="num_groups" type="gint"/>
<parameter name="num_levels" type="gint"/>
</parameters>
</vfunc>
<vfunc name="set_outline">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="outline" type="EekOutline*"/>
</parameters>
</vfunc>
</object>
<object name="EekKeyboard" parent="EekContainer" type-name="EekKeyboard" get-type="eek_keyboard_get_type">
<method name="create_section" symbol="eek_keyboard_create_section">
<return-type type="EekSection*"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
</parameters>
</method>
<method name="find_key_by_keycode" symbol="eek_keyboard_find_key_by_keycode">
<return-type type="EekKey*"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</method>
<method name="get_keysym_index" symbol="eek_keyboard_get_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
<parameter name="group" type="gint*"/>
<parameter name="level" type="gint*"/>
</parameters>
</method>
<method name="realize" symbol="eek_keyboard_realize">
<return-type type="void"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
</parameters>
</method>
<method name="set_keysym_index" symbol="eek_keyboard_set_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
<parameter name="group" type="gint"/>
<parameter name="level" type="gint"/>
</parameters>
</method>
<method name="set_layout" symbol="eek_keyboard_set_layout">
<return-type type="void"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
<parameter name="layout" type="EekLayout*"/>
</parameters>
</method>
<property name="group" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="level" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<signal name="key-pressed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="object" type="EekKeyboard*"/>
<parameter name="p0" type="EekKey*"/>
</parameters>
</signal>
<signal name="key-released" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="object" type="EekKeyboard*"/>
<parameter name="p0" type="EekKey*"/>
</parameters>
</signal>
<vfunc name="create_section">
<return-type type="EekSection*"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
</parameters>
</vfunc>
<vfunc name="find_key_by_keycode">
<return-type type="EekKey*"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</vfunc>
<vfunc name="get_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
<parameter name="group" type="gint*"/>
<parameter name="level" type="gint*"/>
</parameters>
</vfunc>
<vfunc name="realize">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
</parameters>
</vfunc>
<vfunc name="set_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
<parameter name="group" type="gint"/>
<parameter name="level" type="gint"/>
</parameters>
</vfunc>
<vfunc name="set_layout">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
<parameter name="layout" type="EekLayout*"/>
</parameters>
</vfunc>
</object>
<object name="EekSection" parent="EekContainer" type-name="EekSection" get-type="eek_section_get_type">
<method name="add_row" symbol="eek_section_add_row">
<return-type type="void"/>
<parameters>
<parameter name="section" type="EekSection*"/>
<parameter name="num_columns" type="gint"/>
<parameter name="orientation" type="EekOrientation"/>
</parameters>
</method>
<method name="create_key" symbol="eek_section_create_key">
<return-type type="EekKey*"/>
<parameters>
<parameter name="section" type="EekSection*"/>
<parameter name="column" type="gint"/>
<parameter name="row" type="gint"/>
</parameters>
</method>
<method name="find_key_by_keycode" symbol="eek_section_find_key_by_keycode">
<return-type type="EekKey*"/>
<parameters>
<parameter name="section" type="EekSection*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</method>
<method name="get_angle" symbol="eek_section_get_angle">
<return-type type="gint"/>
<parameters>
<parameter name="section" type="EekSection*"/>
</parameters>
</method>
<method name="get_n_rows" symbol="eek_section_get_n_rows">
<return-type type="gint"/>
<parameters>
<parameter name="section" type="EekSection*"/>
</parameters>
</method>
<method name="get_row" symbol="eek_section_get_row">
<return-type type="void"/>
<parameters>
<parameter name="section" type="EekSection*"/>
<parameter name="index" type="gint"/>
<parameter name="num_columns" type="gint*"/>
<parameter name="orientation" type="EekOrientation*"/>
</parameters>
</method>
<method name="set_angle" symbol="eek_section_set_angle">
<return-type type="void"/>
<parameters>
<parameter name="section" type="EekSection*"/>
<parameter name="angle" type="gint"/>
</parameters>
</method>
<property name="angle" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<signal name="key-pressed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="object" type="EekSection*"/>
<parameter name="p0" type="EekKey*"/>
</parameters>
</signal>
<signal name="key-released" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="object" type="EekSection*"/>
<parameter name="p0" type="EekKey*"/>
</parameters>
</signal>
<vfunc name="add_row">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekSection*"/>
<parameter name="num_columns" type="gint"/>
<parameter name="orientation" type="EekOrientation"/>
</parameters>
</vfunc>
<vfunc name="create_key">
<return-type type="EekKey*"/>
<parameters>
<parameter name="self" type="EekSection*"/>
<parameter name="row" type="gint"/>
<parameter name="column" type="gint"/>
</parameters>
</vfunc>
<vfunc name="find_key_by_keycode">
<return-type type="EekKey*"/>
<parameters>
<parameter name="self" type="EekSection*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</vfunc>
<vfunc name="get_angle">
<return-type type="gint"/>
<parameters>
<parameter name="self" type="EekSection*"/>
</parameters>
</vfunc>
<vfunc name="get_n_rows">
<return-type type="gint"/>
<parameters>
<parameter name="self" type="EekSection*"/>
</parameters>
</vfunc>
<vfunc name="get_row">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekSection*"/>
<parameter name="index" type="gint"/>
<parameter name="num_columns" type="gint*"/>
<parameter name="orientation" type="EekOrientation*"/>
</parameters>
</vfunc>
<vfunc name="set_angle">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekSection*"/>
<parameter name="angle" type="gint"/>
</parameters>
</vfunc>
</object>
<interface name="EekLayout" type-name="EekLayout" get-type="eek_layout_get_type">
<method name="apply" symbol="eek_layout_apply">
<return-type type="void"/>
<parameters>
<parameter name="layout" type="EekLayout*"/>
<parameter name="keyboard" type="EekKeyboard*"/>
</parameters>
</method>
<method name="get_group" symbol="eek_layout_get_group">
<return-type type="gint"/>
<parameters>
<parameter name="layout" type="EekLayout*"/>
</parameters>
</method>
<signal name="changed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekLayout*"/>
</parameters>
</signal>
<signal name="group-changed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekLayout*"/>
<parameter name="group" type="gint"/>
</parameters>
</signal>
<vfunc name="apply">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekLayout*"/>
<parameter name="keyboard" type="EekKeyboard*"/>
</parameters>
</vfunc>
<vfunc name="get_group">
<return-type type="gint"/>
<parameters>
<parameter name="self" type="EekLayout*"/>
</parameters>
</vfunc>
</interface>
<constant name="EEK_CONTAINER_H" type="int" value="1"/>
<constant name="EEK_ELEMENT_H" type="int" value="1"/>
<constant name="EEK_KEYBOARD_H" type="int" value="1"/>
<constant name="EEK_KEYSYM_H" type="int" value="1"/>
<constant name="EEK_KEY_H" type="int" value="1"/>
<constant name="EEK_LAYOUT_H" type="int" value="1"/>
<constant name="EEK_SECTION_H" type="int" value="1"/>
<constant name="EEK_TYPES_H" type="int" value="1"/>
</namespace>
</api>

View File

@ -0,0 +1 @@
Eek cheader_filename="eek/eek.h"

View File

@ -0,0 +1 @@
Eek

View File

@ -0,0 +1,6 @@
include/eek-0.1/eek/eek-clutter-keyboard.h
include/eek-0.1/eek/eek-clutter-section.h
include/eek-0.1/eek/eek-clutter-key.h
include/eek-0.1/eek/eek-clutter-drawing-context.h
lib/libeek-clutter.so

View File

@ -0,0 +1,85 @@
<?xml version="1.0"?>
<api version="1.0">
<namespace name="EekClutter">
<object name="EekClutterDrawingContext" parent="GInitiallyUnowned" type-name="EekClutterDrawingContext" get-type="eek_clutter_drawing_context_get_type">
<method name="get_category_font" symbol="eek_clutter_drawing_context_get_category_font">
<return-type type="PangoFontDescription*"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
<parameter name="category" type="EekKeysymCategory"/>
</parameters>
</method>
<method name="get_outline_texture" symbol="eek_clutter_drawing_context_get_outline_texture">
<return-type type="ClutterActor*"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
<parameter name="outline" type="EekOutline*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_clutter_drawing_context_new">
<return-type type="EekClutterDrawingContext*"/>
</constructor>
<method name="set_category_font" symbol="eek_clutter_drawing_context_set_category_font">
<return-type type="void"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
<parameter name="category" type="EekKeysymCategory"/>
<parameter name="fonts" type="PangoFontDescription*"/>
</parameters>
</method>
<method name="set_outline_texture" symbol="eek_clutter_drawing_context_set_outline_texture">
<return-type type="void"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
<parameter name="outline" type="EekOutline*"/>
<parameter name="texture" type="ClutterActor*"/>
</parameters>
</method>
</object>
<object name="EekClutterKey" parent="EekKey" type-name="EekClutterKey" get-type="eek_clutter_key_get_type">
<method name="get_actor" symbol="eek_clutter_key_get_actor">
<return-type type="ClutterActor*"/>
<parameters>
<parameter name="key" type="EekClutterKey*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_clutter_key_new">
<return-type type="EekKey*"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
<parameter name="column" type="gint"/>
<parameter name="row" type="gint"/>
</parameters>
</constructor>
</object>
<object name="EekClutterKeyboard" parent="EekKeyboard" type-name="EekClutterKeyboard" get-type="eek_clutter_keyboard_get_type">
<method name="get_actor" symbol="eek_clutter_keyboard_get_actor">
<return-type type="ClutterActor*"/>
<parameters>
<parameter name="keyboard" type="EekClutterKeyboard*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_clutter_keyboard_new">
<return-type type="EekKeyboard*"/>
</constructor>
</object>
<object name="EekClutterSection" parent="EekSection" type-name="EekClutterSection" get-type="eek_clutter_section_get_type">
<method name="get_actor" symbol="eek_clutter_section_get_actor">
<return-type type="ClutterActor*"/>
<parameters>
<parameter name="section" type="EekClutterSection*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_clutter_section_new">
<return-type type="EekSection*"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
</parameters>
</constructor>
</object>
<constant name="EEK_CLUTTER_DRAWING_CONTEXT_H" type="int" value="1"/>
<constant name="EEK_CLUTTER_KEYBOARD_H" type="int" value="1"/>
<constant name="EEK_CLUTTER_KEY_H" type="int" value="1"/>
<constant name="EEK_CLUTTER_SECTION_H" type="int" value="1"/>
</namespace>
</api>

View File

@ -0,0 +1 @@
EekClutter cheader_filename="eek/eek-clutter.h"

View File

@ -0,0 +1 @@
EekClutter

View File

@ -0,0 +1,3 @@
include/eek-0.1/eek/eek-gtk-keyboard.h
include/eek-0.1/eek/eek-gtk.h
lib/libeek-gtk.so

View File

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<api version="1.0">
<namespace name="EekGtk">
<object name="EekGtkKeyboard" parent="EekKeyboard" type-name="EekGtkKeyboard" get-type="eek_gtk_keyboard_get_type">
<method name="get_widget" symbol="eek_gtk_keyboard_get_widget">
<return-type type="GtkWidget*"/>
<parameters>
<parameter name="keyboard" type="EekGtkKeyboard*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_gtk_keyboard_new">
<return-type type="EekKeyboard*"/>
</constructor>
</object>
<constant name="EEK_GTK_H" type="int" value="1"/>
<constant name="EEK_GTK_KEYBOARD_H" type="int" value="1"/>
</namespace>
</api>

View File

@ -0,0 +1 @@
EekGtk cheader_filename="eek/eek-gtk.h"

View File

@ -0,0 +1 @@
EekGtk

View File

@ -0,0 +1,2 @@
include/eek-0.1/eek/eek-xkb-layout.h
lib/libeek-xkb.so

View File

@ -0,0 +1,65 @@
<?xml version="1.0"?>
<api version="1.0">
<namespace name="EekXkb">
<object name="EekXkbLayout" parent="GInitiallyUnowned" type-name="EekXkbLayout" get-type="eek_xkb_layout_get_type">
<implements>
<interface name="EekLayout"/>
</implements>
<method name="get_geometry" symbol="eek_xkb_layout_get_geometry">
<return-type type="gchar*"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
</parameters>
</method>
<method name="get_keycodes" symbol="eek_xkb_layout_get_keycodes">
<return-type type="gchar*"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
</parameters>
</method>
<method name="get_symbols" symbol="eek_xkb_layout_get_symbols">
<return-type type="gchar*"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_xkb_layout_new">
<return-type type="EekLayout*"/>
</constructor>
<method name="set_geometry" symbol="eek_xkb_layout_set_geometry">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
<parameter name="geometry" type="gchar*"/>
</parameters>
</method>
<method name="set_keycodes" symbol="eek_xkb_layout_set_keycodes">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
<parameter name="keycodes" type="gchar*"/>
</parameters>
</method>
<!--
<method name="set_names" symbol="eek_xkb_layout_set_names">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
<parameter name="names" type="XkbComponentNamesRec*"/>
</parameters>
</method>
-->
<method name="set_symbols" symbol="eek_xkb_layout_set_symbols">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
<parameter name="symbols" type="gchar*"/>
</parameters>
</method>
<property name="geometry" type="char*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="keycodes" type="char*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="symbols" type="char*" readable="1" writable="1" construct="0" construct-only="0"/>
</object>
<constant name="EEK_XKB_LAYOUT_H" type="int" value="1"/>
</namespace>
</api>

View File

@ -0,0 +1 @@
EekXkb cheader_filename="eek/eek-xkb.h"

View File

@ -0,0 +1 @@
EekXkb

View File

@ -0,0 +1,3 @@
include/eek-0.1/eek/eek-xkl-layout.h
lib/libeek-xkl.so

View File

@ -0,0 +1,91 @@
<?xml version="1.0"?>
<api version="1.0">
<namespace name="EekXkl">
<object name="EekXklLayout" parent="EekXkbLayout" type-name="EekXklLayout" get-type="eek_xkl_layout_get_type">
<implements>
<interface name="EekLayout"/>
</implements>
<method name="disable_option" symbol="eek_xkl_layout_disable_option">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="option" type="gchar*"/>
</parameters>
</method>
<method name="enable_option" symbol="eek_xkl_layout_enable_option">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="option" type="gchar*"/>
</parameters>
</method>
<method name="get_layouts" symbol="eek_xkl_layout_get_layouts">
<return-type type="gchar**"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
</parameters>
</method>
<method name="get_model" symbol="eek_xkl_layout_get_model">
<return-type type="gchar*"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
</parameters>
</method>
<method name="get_option" symbol="eek_xkl_layout_get_option">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="option" type="gchar*"/>
</parameters>
</method>
<method name="get_options" symbol="eek_xkl_layout_get_options">
<return-type type="gchar**"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
</parameters>
</method>
<method name="get_variants" symbol="eek_xkl_layout_get_variants">
<return-type type="gchar**"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_xkl_layout_new">
<return-type type="EekLayout*"/>
</constructor>
<method name="set_layouts" symbol="eek_xkl_layout_set_layouts">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="layouts" type="gchar**"/>
</parameters>
</method>
<method name="set_model" symbol="eek_xkl_layout_set_model">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="model" type="gchar*"/>
</parameters>
</method>
<method name="set_options" symbol="eek_xkl_layout_set_options">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="options" type="gchar**"/>
</parameters>
</method>
<method name="set_variants" symbol="eek_xkl_layout_set_variants">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="variants" type="gchar**"/>
</parameters>
</method>
<property name="layouts" type="GStrv*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="model" type="char*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="options" type="GStrv*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="variants" type="GStrv*" readable="1" writable="1" construct="0" construct-only="0"/>
</object>
<constant name="EEK_XKL_LAYOUT_H" type="int" value="1"/>
</namespace>
</api>

View File

@ -0,0 +1 @@
EekXkl cheader_filename="eek/eek-xkl.h"

View File

@ -0,0 +1 @@
EekXkl

View File

@ -1,5 +1,5 @@
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> # Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010 Red Hat, Inc. # Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License # modify it under the terms of the GNU Lesser General Public License
@ -16,32 +16,165 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA # 02110-1301 USA
AC_INIT([eekboard], [0.0.1], [ueno@unixuser.org])
AC_CONFIG_SRCDIR([configure.ac])
AC_PREREQ(2.63) AC_PREREQ(2.63)
AM_INIT_AUTOMAKE dnl AC_CONFIG_SRCDIR([configure.ac])
AM_PROG_CC_C_O
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_INIT([eekboard], [0.90.4], [ueno@unixuser.org])
dnl Init automake
AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE([enable])
AC_GNU_SOURCE
dnl Support silent build
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
dnl Check for programs
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CC_STDC
AC_PROG_INSTALL
AC_PROG_CXX
# define PACKAGE_VERSION_* variables
AM_DISABLE_STATIC
AC_ISC_POSIX
AC_HEADER_STDC
LT_INIT LT_INIT
IT_PROG_INTLTOOL([0.35.0]) IT_PROG_INTLTOOL([0.35.0])
PKG_CHECK_MODULES([GLIB2], [glib-2.0], , AC_MSG_CHECKING([which gtk+ version to compile against])
AC_ARG_WITH([gtk],
[AS_HELP_STRING([--with-gtk=2.0|3.0],[which gtk+ version to compile against (default: 2.0)])],
[case "$with_gtk" in
2.0|3.0) ;;
*) AC_MSG_ERROR([invalid gtk version specified]) ;;
esac],
[with_gtk=2.0])
AC_MSG_RESULT([$with_gtk])
case "$with_gtk" in
2.0) GTK_API_VERSION=2.0
GTK_REQUIRED=2.14.0
EEK_API_VERSION=0.90
EEK_API_MAJOR_VERSION=0
EEK_API_MINOR_VERSION=90
EEK_API_PC_VERSION=0.90
EEK_LIBRARY_SUFFIX="-$EEK_API_VERSION"
;;
3.0) GTK_API_VERSION=3.0
GTK_REQUIRED=2.91.0
EEK_API_VERSION=0.90
EEK_API_MAJOR_VERSION=0
EEK_API_MINOR_VERSION=90
EEK_API_PC_VERSION=0.90
EEK_LIBRARY_SUFFIX="-$EEK_API_VERSION"
;;
esac
AC_SUBST([GTK_API_VERSION])
AC_SUBST([EEK_API_VERSION])
AC_SUBST([EEK_API_MAJOR_VERSION])
AC_SUBST([EEK_API_MINOR_VERSION])
AC_SUBST([EEK_API_PC_VERSION])
AC_SUBST([EEK_LIBRARY_SUFFIX])
AC_SUBST([EEK_LIBRARY_SUFFIX_U],[AS_TR_SH([$EEK_LIBRARY_SUFFIX])])
AM_CONDITIONAL([HAVE_GTK_2],[test "$with_gtk" = "2.0"])
AM_CONDITIONAL([HAVE_GTK_3],[test "$with_gtk" = "3.0"])
AM_PATH_GLIB_2_0
PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.25.4], ,
[AC_MSG_ERROR([GLib2 not found])]) [AC_MSG_ERROR([GLib2 not found])])
PKG_CHECK_MODULES([GOBJECT2], [gobject-2.0], , PKG_CHECK_MODULES([GIO2], [gio-2.0], ,
[AC_MSG_ERROR([GObject2 not found])]) [AC_MSG_ERROR([Gio2 not found])])
PKG_CHECK_MODULES([CAIRO], [cairo], , PKG_CHECK_MODULES([PANGOCAIRO], [pangocairo], ,
[AC_MSG_ERROR([Cairo not found])]) [AC_MSG_ERROR([PangoCairo not found])])
PKG_CHECK_MODULES([PANGO], [pango], , PKG_CHECK_MODULES([GTK], [
[AC_MSG_ERROR([Pango not found])]) gtk+-$GTK_API_VERSION >= $GTK_REQUIRED
PKG_CHECK_MODULES([GTK2], [gtk+-2.0 gdk-2.0], , gdk-$GTK_API_VERSION >= $GTK_REQUIRED], ,
[AC_MSG_ERROR([GTK2 not found])]) [AC_MSG_ERROR([GTK not found])])
PKG_CHECK_MODULES([GCONF2], [gconf-2.0], ,
[AC_MSG_ERROR([GConf not found])])
PKG_CHECK_MODULES([XKB], [x11], , PKG_CHECK_MODULES([XKB], [x11], ,
[AC_MSG_ERROR([XKB support not found])]) [AC_MSG_ERROR([XKB support not found])])
PKG_CHECK_MODULES([LIBXKLAVIER], [libxklavier x11], , PKG_CHECK_MODULES([LIBXKLAVIER], [libxklavier x11], ,
[AC_MSG_ERROR([Libxklavier not found])]) [AC_MSG_ERROR([Libxklavier not found])])
PKG_CHECK_MODULES([LIBFAKEKEY], [libfakekey], , PKG_CHECK_MODULES([LIBCROCO], [libcroco-0.6], ,
[AC_MSG_ERROR([libfakekey not found])]) [AC_MSG_ERROR([libcroco not found])])
dnl use libfakekey to generate key events
AC_MSG_CHECKING([whether you enable fakekey])
AC_ARG_ENABLE(fakekey,
AS_HELP_STRING([--enable-fakekey=no/yes],
[Enable fakekey default=yes]),,
enable_fakekey=yes)
if test x$enable_fakekey = xyes; then
PKG_CHECK_MODULES([FAKEKEY], [libfakekey], ,
[AC_MSG_ERROR([fakekey not found])])
AC_DEFINE([HAVE_FAKEKEY], [1], [Define if fakekey is found])
fi
AM_CONDITIONAL(ENABLE_FAKEKEY, [test x$enable_fakekey = xyes])
AC_MSG_RESULT($enable_fakekey)
dnl use AT-SPI to capture focus/keystroke events
AC_MSG_CHECKING([whether you enable AT-SPI event handling])
AC_ARG_ENABLE(cspi,
AS_HELP_STRING([--enable-cspi=no/yes],
[Enable AT-SPI event handling default=yes]),,
enable_cspi=yes)
if test x$enable_cspi = xyes; then
PKG_CHECK_MODULES([CSPI], [cspi-1.0], ,
[AC_MSG_ERROR([AT-SPI C not found])])
AC_DEFINE([HAVE_CSPI], [1], [Define if CSPI is found])
fi
AC_MSG_RESULT($enable_cspi)
AM_CONDITIONAL(ENABLE_CSPI, [test x$enable_cspi = xyes])
dnl Python language binding
AC_MSG_CHECKING([whether you enable Python language support])
AC_ARG_ENABLE(python,
AS_HELP_STRING([--enable-python=no/yes],
[Enable Python language binding default=yes]),,
enable_python=yes)
AC_MSG_RESULT($enable_python)
AM_CONDITIONAL(ENABLE_PYTHON, [test x$enable_python = xyes])
if test x"$enable_python" = x"yes"; then
# check python
AM_PATH_PYTHON([2.5])
AC_PATH_PROG(PYTHON_CONFIG, python$PYTHON_VERSION-config)
if test x"$PYTHON_CONFIG" = x""; then
AC_PATH_PROG(PYTHON_CONFIG, python-config)
fi
if test x"$PYTHON_CONFIG" != x""; then
PYTHON_CFLAGS=`$PYTHON_CONFIG --includes`
PYTHON_LIBS=`$PYTHON_CONFIG --libs`
else
PYTHON_CFLAGS=`$PYTHON $srcdir/python-config.py --includes`
PYTHON_LIBS=`$PYTHON $srcdir/python-config.py --libs`
fi
PYTHON_INCLUDES="$PYTHON_CFLAGS"
AC_SUBST(PYTHON_CFLAGS)
AC_SUBST(PYTHON_INCLUDES)
AC_SUBST(PYTHON_LIBS)
else
enable_python="no (disabled, use --enable-python to enable)"
fi
dnl Vala langauge binding
AC_MSG_CHECKING([whether you enable Vala language support])
AC_ARG_ENABLE(vala,
AS_HELP_STRING([--enable-vala=no/yes],
[Enable Vala language binding default=yes]),,
enable_vala=yes)
AC_MSG_RESULT($enable_vala)
AM_CONDITIONAL(ENABLE_VALA, [test x$enable_vala = xyes])
dnl standalone application
AC_MSG_CHECKING([whether you enable eekboard]) AC_MSG_CHECKING([whether you enable eekboard])
AC_ARG_ENABLE(eekboard, AC_ARG_ENABLE(eekboard,
AS_HELP_STRING([--enable-eekboard=no/yes], AS_HELP_STRING([--enable-eekboard=no/yes],
@ -50,35 +183,32 @@ AC_ARG_ENABLE(eekboard,
AC_MSG_RESULT($enable_eekboard) AC_MSG_RESULT($enable_eekboard)
AM_CONDITIONAL(ENABLE_EEKBOARD, [test x$enable_eekboard = xyes]) AM_CONDITIONAL(ENABLE_EEKBOARD, [test x$enable_eekboard = xyes])
dnl Clutter
AC_MSG_CHECKING([whether you enable Clutter]) AC_MSG_CHECKING([whether you enable Clutter])
AC_ARG_ENABLE(clutter, AC_ARG_ENABLE(clutter,
AS_HELP_STRING([--enable-clutter=no/yes], AS_HELP_STRING([--enable-clutter=no/yes],
[Enable Clutter user interface default=yes]),, [Enable Clutter user interface default=yes]),,
enable_clutter=yes) enable_clutter=no)
AC_MSG_RESULT($enable_clutter) AC_MSG_RESULT($enable_clutter)
if test x$enable_clutter = xyes; then if test x$enable_clutter = xyes; then
PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], , PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], ,
[AC_MSG_ERROR([Clutter not found -- install it or add --disable-clutter])]) [AC_MSG_ERROR([Clutter not found -- install it or add --disable-clutter])])
AC_DEFINE([HAVE_CLUTTER], [1], [Define if Clutter is found]) AC_DEFINE([HAVE_CLUTTER], [1], [Define if Clutter is found])
PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.90], have_clutter_gtk=0
[enable_clutter_gtk=yes]) need_swap_event_workaround=0
if test x$enable_clutter_gtk = xno; then PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-1.0], [have_clutter_gtk=1],
PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.10], [PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.10 clutter-x11-1.0],
[enable_clutter_gtk=yes]) [have_clutter_gtk=1; need_swap_event_workaround=1])])
fi AC_DEFINE_UNQUOTED([HAVE_CLUTTER_GTK], $have_clutter_gtk,
if test x$enable_clutter_gtk = xyes; then [Define if Clutter-Gtk is found])
AC_DEFINE([HAVE_CLUTTER_GTK], [1], [Define if Clutter-Gtk is found]) AC_DEFINE_UNQUOTED([NEED_SWAP_EVENT_WORKAROUND], $need_swap_event_workaround,
fi [Define if GLX_INTEL_swap_event work around is needed])
fi fi
AM_CONDITIONAL(HAVE_CLUTTER, [test x$enable_clutter = xyes]) AM_CONDITIONAL(ENABLE_CLUTTER, [test x$enable_clutter = xyes])
AM_CONDITIONAL(HAVE_CLUTTER_GTK, [test x$enable_clutter_gtk = xyes])
GTK_DOC_CHECK([1.14],[--flavour no-tmpl]) GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
EEK_API_VERSION=0.1
AC_SUBST(EEK_API_VERSION)
dnl to re-generate eek/*-keysym-labels.txt dnl to re-generate eek/*-keysym-labels.txt
AC_CHECK_PROGS([PYTHON], [python]) AC_CHECK_PROGS([PYTHON], [python])
@ -89,18 +219,46 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Define to the read-only
AM_GLIB_GNU_GETTEXT AM_GLIB_GNU_GETTEXT
AM_GLIB_DEFINE_LOCALEDIR(EEKBOARD_LOCALEDIR) AM_GLIB_DEFINE_LOCALEDIR(EEKBOARD_LOCALEDIR)
AC_CONFIG_HEADERS([eek/config.h]) GOBJECT_INTROSPECTION_CHECK([0.9.0])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile
eek/Makefile eek/Makefile
eekboard/Makefile
src/Makefile src/Makefile
tests/Makefile tests/Makefile
bindings/Makefile
bindings/python/Makefile
bindings/python/eekboard/Makefile
bindings/vala/Makefile
docs/Makefile docs/Makefile
docs/reference/Makefile docs/reference/Makefile
docs/reference/eek/Makefile docs/reference/eek/Makefile
docs/reference/eekboard/Makefile
po/Makefile.in po/Makefile.in
eek/libeek.pc data/Makefile
eek/libeek-clutter.pc data/icons/Makefile
eek/libeek-gtk.pc data/icons/16x16/Makefile
eek/libeek-xkb.pc data/icons/22x22/Makefile
eek/libeek-xkl.pc]) data/icons/24x24/Makefile
data/icons/32x32/Makefile
data/icons/48x48/Makefile
data/icons/scalable/Makefile
data/themes/Makefile
eek/eek-${EEK_API_VERSION}.pc
eek/eek-clutter-${EEK_API_VERSION}.pc
eek/eek-gtk-${EEK_API_VERSION}.pc
eek/eek-xkb-${EEK_API_VERSION}.pc
eek/eek-xkl-${EEK_API_VERSION}.pc
eekboard/eekboard-${EEK_API_VERSION}.pc])
AC_OUTPUT AC_OUTPUT
AC_MSG_RESULT([
Build options:
Version $VERSION
Install prefix $prefix
Build shared libs $enable_shared
Build static libs $enable_static
CFLAGS $CFLAGS
Build vala binding $enable_vala
Build document $enable_gtk_doc
])

1
data/Makefile.am Normal file
View File

@ -0,0 +1 @@
SUBDIRS = icons themes

View File

@ -0,0 +1,16 @@
size = 16x16
icondir = $(datadir)/icons/hicolor/$(size)/apps
dist_icon_DATA = eekboard.png
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
install-data-hook:
@-if test -z "$(DESTDIR)"; then \
echo "Updating Gtk icon cache."; \
$(gtk_update_icon_cache); \
else \
echo "*** Icon cache not updated. After install, run this:"; \
echo "*** $(gtk_update_icon_cache)"; \
fi

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

View File

@ -0,0 +1,16 @@
size = 22x22
icondir = $(datadir)/icons/hicolor/$(size)/apps
dist_icon_DATA = eekboard.png
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
install-data-hook:
@-if test -z "$(DESTDIR)"; then \
echo "Updating Gtk icon cache."; \
$(gtk_update_icon_cache); \
else \
echo "*** Icon cache not updated. After install, run this:"; \
echo "*** $(gtk_update_icon_cache)"; \
fi

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 B

View File

@ -0,0 +1,16 @@
size = 24x24
icondir = $(datadir)/icons/hicolor/$(size)/apps
dist_icon_DATA = eekboard.png
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
install-data-hook:
@-if test -z "$(DESTDIR)"; then \
echo "Updating Gtk icon cache."; \
$(gtk_update_icon_cache); \
else \
echo "*** Icon cache not updated. After install, run this:"; \
echo "*** $(gtk_update_icon_cache)"; \
fi

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

View File

@ -0,0 +1,16 @@
size = 32x32
icondir = $(datadir)/icons/hicolor/$(size)/apps
dist_icon_DATA = eekboard.png
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
install-data-hook:
@-if test -z "$(DESTDIR)"; then \
echo "Updating Gtk icon cache."; \
$(gtk_update_icon_cache); \
else \
echo "*** Icon cache not updated. After install, run this:"; \
echo "*** $(gtk_update_icon_cache)"; \
fi

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,16 @@
size = 48x48
icondir = $(datadir)/icons/hicolor/$(size)/apps
dist_icon_DATA = eekboard.png
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
install-data-hook:
@-if test -z "$(DESTDIR)"; then \
echo "Updating Gtk icon cache."; \
$(gtk_update_icon_cache); \
else \
echo "*** Icon cache not updated. After install, run this:"; \
echo "*** $(gtk_update_icon_cache)"; \
fi

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

1
data/icons/Makefile.am Normal file
View File

@ -0,0 +1 @@
SUBDIRS = 16x16 22x22 24x24 32x32 48x48 scalable

View File

@ -0,0 +1,14 @@
icondir = $(datadir)/icons/hicolor/scalable/apps
dist_icon_DATA = eekboard.svg
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
install-data-hook:
@-if test -z "$(DESTDIR)"; then \
echo "Updating Gtk icon cache."; \
$(gtk_update_icon_cache); \
else \
echo "*** Icon cache not updated. After install, run this:"; \
echo "*** $(gtk_update_icon_cache)"; \
fi

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 472 KiB

2
data/themes/Makefile.am Normal file
View File

@ -0,0 +1,2 @@
themedir = $(pkgdatadir)/themes
dist_theme_DATA = default.css

22
data/themes/default.css Normal file
View File

@ -0,0 +1,22 @@
.keyboard {
background-color: rgba(0, 0, 0, 255);
color: #ffffff;
font-family: cantarell, sans-serif;
}
.key {
color: #ffffff;
background-gradient-direction: vertical;
background-gradient-start: rgba(0, 0, 0, 255);
background-gradient-end: rgba(64, 64, 64, 255);
border-width: 2px;
border-color: rgba(128, 128, 128, 255);
border-radius: 3px;
}
.key:active {
background-gradient-direction: vertical;
background-gradient-start: rgba(0, 0, 255, 255);
background-gradient-end: rgba(64, 64, 255, 255);
border-color: rgba(160, 160, 255, 255);
}

View File

@ -1,5 +1,5 @@
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> # Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010 Red Hat, Inc. # Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License # modify it under the terms of the GNU Lesser General Public License

View File

@ -1,5 +1,5 @@
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> # Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010 Red Hat, Inc. # Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License # modify it under the terms of the GNU Lesser General Public License
@ -16,4 +16,4 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA # 02110-1301 USA
SUBDIRS = eek SUBDIRS = eek eekboard

View File

@ -1,5 +1,5 @@
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> # Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010 Red Hat, Inc. # Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License # modify it under the terms of the GNU Lesser General Public License
@ -47,7 +47,7 @@ SCANGOBJ_OPTIONS=
# Extra options to supply to gtkdoc-scan. # Extra options to supply to gtkdoc-scan.
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
SCAN_OPTIONS= SCAN_OPTIONS=--rebuild-types
# Extra options to supply to gtkdoc-mkdb. # Extra options to supply to gtkdoc-mkdb.
# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
@ -76,13 +76,16 @@ EXTRA_HFILES=
# Header files to ignore when scanning. Use base file name, no paths # Header files to ignore when scanning. Use base file name, no paths
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
IGNORE_HFILES= eek-private.h \ IGNORE_HFILES = \
eek-drawing.h \ config.h \
eek-clutter-key.h \ eek-renderer.h \
eek-clutter-renderer.h \
eek-clutter-section.h \ eek-clutter-section.h \
eek-clutter-key-actor.h \ eek-clutter-key.h \
eek-clutter-drawing-context.h \ eek-gtk-renderer.h
config.h if !ENABLE_CLUTTER
IGNORE_HFILES += eek-clutter-keyboard.h eek-clutter.h
endif
# Images to copy into HTML directory. # Images to copy into HTML directory.
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
@ -102,16 +105,19 @@ expand_content_files=eek-overview.xml
# signals and properties. # signals and properties.
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS = $(GOBJECT2_CFLAGS) GTKDOC_CFLAGS = $(GIO2_CFLAGS)
GTKDOC_LIBS = $(top_srcdir)/eek/libeek.la \ GTKDOC_LIBS = $(top_builddir)/eek/libeek.la \
$(top_srcdir)/eek/libeek-gtk.la \ $(top_builddir)/eek/libeek-gtk.la \
$(top_srcdir)/eek/libeek-xkb.la \ $(top_builddir)/eek/libeek-xkb.la \
$(top_srcdir)/eek/libeek-xkl.la \ $(top_builddir)/eek/libeek-xkl.la \
$(GOBJECT2_LIBS) \ $(GIO2_LIBS) \
$(GTK_LIBS) \
$(XKB_LIBS) $(XKB_LIBS)
if HAVE_CLUTTER if ENABLE_CLUTTER
GTKDOC_LIBS += $(top_srcdir)/eek/libeek-clutter.la $(CLUTTER_LIBS) GTKDOC_LIBS += \
$(top_builddir)/eek/libeek-clutter.la \
$(CLUTTER_LIBS)
endif endif
# This includes the standard gtk-doc make rules, copied by gtkdocize. # This includes the standard gtk-doc make rules, copied by gtkdocize.

View File

@ -8,15 +8,15 @@
<bookinfo> <bookinfo>
<title>libeek Reference Manual</title> <title>libeek Reference Manual</title>
<releaseinfo> <releaseinfo>
for libeek 0.0.1. for libeek 0.90.0.
</releaseinfo> </releaseinfo>
<copyright> <copyright>
<year>2010</year> <year>2010-2011</year>
<holder>Daiki Ueno</holder> <holder>Daiki Ueno</holder>
</copyright> </copyright>
<copyright> <copyright>
<year>2010</year> <year>2010-2011</year>
<holder>Red Hat, Inc.</holder> <holder>Red Hat, Inc.</holder>
</copyright> </copyright>
@ -37,14 +37,16 @@
<title>API Manual</title> <title>API Manual</title>
<chapter> <chapter>
<title>Base Classes, Interfaces, and Utilities</title> <title>Base Classes, Interfaces, and Utilities</title>
<xi:include href="xml/eek-serializable.xml"/>
<xi:include href="xml/eek-element.xml"/> <xi:include href="xml/eek-element.xml"/>
<xi:include href="xml/eek-container.xml"/> <xi:include href="xml/eek-container.xml"/>
<xi:include href="xml/eek-keyboard.xml"/> <xi:include href="xml/eek-keyboard.xml"/>
<xi:include href="xml/eek-section.xml"/> <xi:include href="xml/eek-section.xml"/>
<xi:include href="xml/eek-key.xml"/> <xi:include href="xml/eek-key.xml"/>
<xi:include href="xml/eek-symbol.xml"/>
<xi:include href="xml/eek-keysym.xml"/>
<xi:include href="xml/eek-layout.xml"/> <xi:include href="xml/eek-layout.xml"/>
<xi:include href="xml/eek-types.xml"/> <xi:include href="xml/eek-types.xml"/>
<xi:include href="xml/eek-keysym.xml"/>
</chapter> </chapter>
<chapter> <chapter>
<title>Clutter Keyboard</title> <title>Clutter Keyboard</title>
@ -62,6 +64,11 @@
<title>XKB Layout Engine</title> <title>XKB Layout Engine</title>
<xi:include href="xml/eek-xkb-layout.xml"/> <xi:include href="xml/eek-xkb-layout.xml"/>
</chapter> </chapter>
<chapter>
<title>XML Layout Engine</title>
<xi:include href="xml/eek-xml-layout.xml"/>
<xi:include href="xml/eek-xml.xml"/>
</chapter>
<chapter id="object-tree"> <chapter id="object-tree">
<title>Object Hierarchy</title> <title>Object Hierarchy</title>
<xi:include href="xml/tree_index.sgml"/> <xi:include href="xml/tree_index.sgml"/>

View File

@ -4,50 +4,60 @@
<para>libeek is a library to create keyboard-like user interface. <para>libeek is a library to create keyboard-like user interface.
Since it is designed as simple as possible, it provides only two Since it is designed as simple as possible, it provides only two
kinds of objects. One is <emphasis>keyboard element</emphasis> kind of objects. One is <emphasis>keyboard element</emphasis>
(derived from #EekElement) and another is <emphasis>keyboard (objects derived from #EekElement) and another is
layout engine</emphasis> (which implements the #EekLayout <emphasis>keyboard layout engine</emphasis> (objects which
interface).</para> implements the #EekLayout interface).</para>
<para>A keyboard element represents either a keyboard <para>A keyboard element represents either a keyboard
(#EekKeyboard), a section (#EekSection), or a key (#EekKey). Each (#EekKeyboard), a section (#EekSection), or a key (#EekKey). Each
element implements the Builder design pattern so that it can be element implements the Builder design pattern so that it can map
converted into a UI widget (#ClutterActor, #GtkDrawingArea, itself to different UI widgets (#ClutterActor, #GtkDrawingArea,
aso).</para> aso).</para>
<para>A layout engine arranges keyboard elements using information <para>A layout engine arranges keyboard elements using information
from external configuration mechanisms (libxklavier, XKB, from external configuration mechanisms (libxklavier, XKB,
matchbox-keyboard layouts in XML, aso)</para> matchbox-keyboard layouts in XML, aso)</para>
<para>Here is a sample code which creates a keyboard-like #ClutterActor using the system keyboard layout using libxklavier:</para> <para>Here is a sample code which demonstrates (1) keyboard
elements are arranged with the system keyboard layout using
libxklavier and (2) keyboard elements are mapped into
#ClutterActor:</para>
<informalexample> <informalexample>
<programlisting> <programlisting>
EekKeyboard *keyboard;
EekLayout *layout; EekLayout *layout;
EekKeyboard *keyboard;
ClutterActor *actor;
/* Create a keyboard layout using libxklavier configuration. */ /* Create a layout engine based on libxklavier configuration. */
layout = eek_xkl_layout_new (); layout = eek_xkl_layout_new ();
/* Create a keyboard implemented as ClutterActor. */ /* Create a keyboard from the given layout. */
keyboard = eek_clutter_keyboard_new (); keyboard = eek_keyboard_new (layout, initial_width, initial_height);
/* Apply the layout to the keyboard. */ /* Create a ClutterActor. */
eek_keyboard_set_layout (keyboard, layout); actor = eek_clutter_keyboard_new (eekboard->keyboard);
clutter_group_add (CLUTTER_GROUP(stage), /* Add the actor to a stage. */
eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard))); clutter_group_add (CLUTTER_GROUP(stage), actor);
</programlisting> </programlisting>
</informalexample> </informalexample>
<para>One of the most interesting features of libeek is that UI <para>libeek currently supports GTK+ and Clutter as UI toolkits.
backends can be switched easily. For example, to create a To create a keyboard-like #GtkWidget instead of #ClutterActor,
keyboard-like #GtkWidget instead of #ClutterActor, all you need is replace eek_clutter_keyboard_new() with eek_gtk_keyboard_new().
to replace eek_clutter_keyboard_new() with eek_gtk_keyboard_new() Similarly, if you want to use XKB configuration directly (without
and eek_clutter_keyboard_get_actor() with libxklavier), you will only need to replace eek_xkl_layout_new ()
eek_gtk_keyboard_get_widget().</para> with eek_xkb_layout_new().</para>
<para>There is logical represention (model) of keyboard distinct from the UI widget (view). More precisely, a keyboard is represented as a tree of #EekElement -- #EekKeyboard contains one or more #EekSection's and #EekSection contains one or more #EekKey's. Each element can be event source when user events on the UI widget occurs. For example, with the following code, when a user pushed a key widget with keycode 0x38 assigned, on_a_pressed will be called.</para> <para>In the above example, a keyboard is represented as a tree of
#EekElement -- #EekKeyboard contains one or more #EekSection's and
#EekSection contains one or more #EekKey's. Each element may emit
events when user pushes the corresponding UI widget.</para>
<para>
Here is another sample code which demonstrates logical events on
#EekElement:
</para>
<informalexample> <informalexample>
<programlisting> <programlisting>
/* Find a key element in the logical keyboard. */ /* Find a key element in the logical keyboard. */
@ -55,6 +65,6 @@ EekKey *key = eek_keyboard_find_key_by_keycode (keyboard, 0x38);
g_signal_connect (key, "pressed", on_a_pressed); g_signal_connect (key, "pressed", on_a_pressed);
</programlisting> </programlisting>
</informalexample> </informalexample>
<para>In this way, application developers do not need to know the differences between the underlying UI widgets after creation.</para> <para>When user pushed a widget which looks like "a" key (i.e. keycode 0x38), on_a_pressed will be called.</para>
</partintro> </partintro>
</part> </part>

View File

@ -4,12 +4,23 @@
EekKeyboardClass EekKeyboardClass
EekKeyboardPrivate EekKeyboardPrivate
EekKeyboard EekKeyboard
eek_keyboard_set_keysym_index eek_keyboard_new
eek_keyboard_get_keysym_index eek_keyboard_get_layout
eek_keyboard_get_size
eek_keyboard_set_size
eek_keyboard_set_symbol_index
eek_keyboard_get_symbol_index
eek_keyboard_set_group
eek_keyboard_set_level
eek_keyboard_get_group
eek_keyboard_get_level
eek_keyboard_set_modifier_behavior
eek_keyboard_get_modifier_behavior
eek_keyboard_get_modifiers
eek_keyboard_create_section eek_keyboard_create_section
eek_keyboard_set_layout
eek_keyboard_realize
eek_keyboard_find_key_by_keycode eek_keyboard_find_key_by_keycode
eek_keyboard_add_outline
eek_keyboard_get_outline
<SUBSECTION Standard> <SUBSECTION Standard>
EEK_KEYBOARD EEK_KEYBOARD
EEK_IS_KEYBOARD EEK_IS_KEYBOARD
@ -23,16 +34,16 @@ EEK_KEYBOARD_GET_CLASS
<SECTION> <SECTION>
<FILE>eek-layout</FILE> <FILE>eek-layout</FILE>
<TITLE>EekLayout</TITLE> <TITLE>EekLayout</TITLE>
EekLayoutIface EekLayoutClass
EekLayout EekLayout
eek_layout_apply
eek_layout_get_group
<SUBSECTION Standard> <SUBSECTION Standard>
EEK_LAYOUT EEK_LAYOUT
EEK_IS_LAYOUT EEK_IS_LAYOUT
EEK_TYPE_LAYOUT EEK_TYPE_LAYOUT
eek_layout_get_type eek_layout_get_type
EEK_LAYOUT_GET_IFACE EEK_LAYOUT_CLASS
EEK_IS_LAYOUT_CLASS
EEK_LAYOUT_GET_CLASS
</SECTION> </SECTION>
<SECTION> <SECTION>
@ -42,7 +53,6 @@ EekGtkKeyboard
EekGtkKeyboardClass EekGtkKeyboardClass
EekGtkKeyboardPrivate EekGtkKeyboardPrivate
eek_gtk_keyboard_new eek_gtk_keyboard_new
eek_gtk_keyboard_get_widget
<SUBSECTION Standard> <SUBSECTION Standard>
EEK_GTK_KEYBOARD EEK_GTK_KEYBOARD
EEK_IS_GTK_KEYBOARD EEK_IS_GTK_KEYBOARD
@ -86,7 +96,7 @@ EekCompareFunc
EekContainer EekContainer
eek_container_foreach_child eek_container_foreach_child
eek_container_find eek_container_find
eek_container_find_by_position eek_container_add_child
<SUBSECTION Standard> <SUBSECTION Standard>
EEK_CONTAINER EEK_CONTAINER
EEK_IS_CONTAINER EEK_IS_CONTAINER
@ -98,21 +108,32 @@ EEK_CONTAINER_GET_CLASS
</SECTION> </SECTION>
<SECTION> <SECTION>
<FILE>eek-clutter-keyboard</FILE> <FILE>eek-symbol</FILE>
<TITLE>EekClutterKeyboard</TITLE> <TITLE>EekSymbol</TITLE>
EekClutterKeyboard EekSymbolCategory
EekClutterKeyboardClass EekSymbolClass
EekClutterKeyboardPrivate EekSymbolPrivate
eek_clutter_keyboard_new EekSymbol
eek_clutter_keyboard_get_actor eek_symbol_new
eek_symbol_set_name
eek_symbol_get_name
eek_symbol_set_label
eek_symbol_get_label
eek_symbol_set_category
eek_symbol_get_category
eek_symbol_get_modifier_mask
eek_symbol_set_modifier_mask
eek_symbol_is_modifier
eek_symbol_set_icon_name
eek_symbol_get_icon_name
<SUBSECTION Standard> <SUBSECTION Standard>
EEK_CLUTTER_KEYBOARD EEK_SYMBOL
EEK_IS_CLUTTER_KEYBOARD EEK_IS_SYMBOL
EEK_TYPE_CLUTTER_KEYBOARD EEK_TYPE_SYMBOL
eek_clutter_keyboard_get_type eek_symbol_get_type
EEK_CLUTTER_KEYBOARD_CLASS EEK_SYMBOL_CLASS
EEK_IS_CLUTTER_KEYBOARD_CLASS EEK_IS_SYMBOL_CLASS
EEK_CLUTTER_KEYBOARD_GET_CLASS EEK_SYMBOL_GET_CLASS
</SECTION> </SECTION>
<SECTION> <SECTION>
@ -123,14 +144,18 @@ EekXklLayoutClass
EekXklLayoutPrivate EekXklLayoutPrivate
eek_xkl_layout_new eek_xkl_layout_new
eek_xkl_layout_set_config eek_xkl_layout_set_config
eek_xkl_layout_set_config_full
eek_xkl_layout_set_model eek_xkl_layout_set_model
eek_xkl_layout_set_layouts eek_xkl_layout_set_layouts
eek_xkl_layout_set_variants eek_xkl_layout_set_variants
eek_xkl_layout_set_options eek_xkl_layout_set_options
eek_xkl_layout_enable_option
eek_xkl_layout_disable_option
eek_xkl_layout_get_model eek_xkl_layout_get_model
eek_xkl_layout_get_layouts eek_xkl_layout_get_layouts
eek_xkl_layout_get_variants eek_xkl_layout_get_variants
eek_xkl_layout_get_options eek_xkl_layout_get_options
eek_xkl_layout_get_option
<SUBSECTION Standard> <SUBSECTION Standard>
EEK_XKL_LAYOUT EEK_XKL_LAYOUT
EEK_IS_XKL_LAYOUT EEK_IS_XKL_LAYOUT
@ -149,6 +174,8 @@ EekXkbLayoutClass
EekXkbLayoutPrivate EekXkbLayoutPrivate
eek_xkb_layout_new eek_xkb_layout_new
eek_xkb_layout_set_names eek_xkb_layout_set_names
eek_xkb_layout_set_names_full
eek_xkb_layout_set_names_full_valist
eek_xkb_layout_set_keycodes eek_xkb_layout_set_keycodes
eek_xkb_layout_set_geometry eek_xkb_layout_set_geometry
eek_xkb_layout_set_symbols eek_xkb_layout_set_symbols
@ -173,15 +200,16 @@ EekKeyPrivate
EekKey EekKey
eek_key_set_keycode eek_key_set_keycode
eek_key_get_keycode eek_key_get_keycode
eek_key_set_keysyms eek_key_set_symbol_matrix
eek_key_get_keysyms eek_key_get_symbol_matrix
eek_key_get_keysym eek_key_get_symbol
eek_key_get_symbol_with_fallback
eek_key_get_symbol_at_index
eek_key_set_index eek_key_set_index
eek_key_get_index eek_key_get_index
eek_key_set_outline eek_key_set_oref
eek_key_get_outline eek_key_get_oref
eek_key_set_keysym_index eek_key_is_pressed
eek_key_get_keysym_index
<SUBSECTION Standard> <SUBSECTION Standard>
EEK_KEY EEK_KEY
EEK_IS_KEY EEK_IS_KEY
@ -192,6 +220,21 @@ EEK_IS_KEY_CLASS
EEK_KEY_GET_CLASS EEK_KEY_GET_CLASS
</SECTION> </SECTION>
<SECTION>
<FILE>eek-serializable</FILE>
<TITLE>EekSerializable</TITLE>
EekSerializable
EekSerializableIface
eek_serializable_serialize
eek_serializable_deserialize
<SUBSECTION Standard>
EEK_SERIALIZABLE
EEK_IS_SERIALIZABLE
EEK_TYPE_SERIALIZABLE
eek_serializable_get_type
EEK_SERIALIZABLE_GET_IFACE
</SECTION>
<SECTION> <SECTION>
<FILE>eek-element</FILE> <FILE>eek-element</FILE>
<TITLE>EekElement</TITLE> <TITLE>EekElement</TITLE>
@ -204,7 +247,15 @@ eek_element_set_name
eek_element_get_name eek_element_get_name
eek_element_set_bounds eek_element_set_bounds
eek_element_get_bounds eek_element_get_bounds
eek_element_set_position
eek_element_set_size
eek_element_get_absolute_position eek_element_get_absolute_position
eek_element_set_symbol_index
eek_element_get_symbol_index
eek_element_set_group
eek_element_set_level
eek_element_get_group
eek_element_get_level
<SUBSECTION Standard> <SUBSECTION Standard>
EEK_ELEMENT EEK_ELEMENT
EEK_IS_ELEMENT EEK_IS_ELEMENT
@ -216,28 +267,79 @@ EEK_ELEMENT_GET_CLASS
</SECTION> </SECTION>
<SECTION> <SECTION>
<FILE>eek-types</FILE> <FILE>eek-xml-layout</FILE>
EekOrientation <TITLE>EekXmlLayout</TITLE>
EekKeysymMatrix EekXmlLayout
EEK_TYPE_KEYSYM_MATRIX EekXmlLayoutClass
eek_keysym_matrix_get_type EekXmlLayoutPrivate
EekPoint eek_xml_layout_new
EEK_TYPE_POINT eek_xml_layout_set_source
eek_point_get_type eek_xml_layout_get_source
EekBounds <SUBSECTION Standard>
EEK_TYPE_BOUNDS EEK_XML_LAYOUT
eek_bounds_get_type EEK_IS_XML_LAYOUT
eek_bounds_long_side EEK_TYPE_XML_LAYOUT
EekOutline eek_xml_layout_get_type
EEK_TYPE_OUTLINE EEK_XML_LAYOUT_CLASS
eek_outline_get_type EEK_IS_XML_LAYOUT_CLASS
EEK_XML_LAYOUT_GET_CLASS
</SECTION> </SECTION>
<SECTION> <SECTION>
<FILE>eek-keysym</FILE> <FILE>eek-keysym</FILE>
<TITLE>EekKeysym</TITLE>
EEK_KEYSYM
EekKeysymClass
EekKeysymPrivate
EekKeysym
eek_keysym_new
eek_keysym_get_xkeysym
eek_keysym_new_from_name
<SUBSECTION Standard>
EEK_INVALID_KEYSYM EEK_INVALID_KEYSYM
EEK_INVALID_KEYCODE EEK_IS_KEYSYM
EekKeysymCategory EEK_TYPE_KEYSYM
eek_keysym_to_string eek_keysym_get_type
eek_keysym_get_category EEK_KEYSYM_CLASS
EEK_IS_KEYSYM_CLASS
EEK_KEYSYM_GET_CLASS
</SECTION> </SECTION>
<SECTION>
<FILE>eek-xml</FILE>
EEK_XML_SCHEMA_VERSION
eek_keyboard_output
</SECTION>
<SECTION>
<FILE>eek-types</FILE>
I_
EEK_TYPE_SYMBOL_MATRIX
EEK_TYPE_POINT
EEK_TYPE_BOUNDS
EEK_TYPE_OUTLINE
EEK_TYPE_COLOR
EekOrientation
EekModifierBehavior
EekModifierType
EEK_INVALID_KEYCODE
EekSymbolMatrix
EekPoint
EekBounds
EekOutline
EekColor
eek_symbol_matrix_get_type
eek_symbol_matrix_new
eek_symbol_matrix_copy
eek_symbol_matrix_free
eek_point_get_type
eek_point_rotate
eek_bounds_get_type
eek_bounds_long_side
eek_outline_get_type
eek_outline_copy
eek_outline_free
eek_color_get_type
eek_color_new
</SECTION>

View File

@ -0,0 +1,120 @@
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public 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
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
## Process this file with automake to produce Makefile.in
# We require automake 1.6 at least.
AUTOMAKE_OPTIONS = 1.6
# This is a blank Makefile.am for using gtk-doc.
# Copy this to your project's API docs directory and modify the variables to
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
# of using the various options.
# The name of the module, e.g. 'glib'.
DOC_MODULE=eekboard
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
#DOC_MODULE_VERSION=2
# The top-level SGML file. You can change this if you want to.
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
# The directory containing the source code. Relative to $(srcdir).
# gtk-doc will search all .c & .h files beneath here for inline comments
# documenting the functions and macros.
# e.g. DOC_SOURCE_DIR=../../../gtk
DOC_SOURCE_DIR=../../../eekboard
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
SCANGOBJ_OPTIONS=
# Extra options to supply to gtkdoc-scan.
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
SCAN_OPTIONS=
# Extra options to supply to gtkdoc-mkdb.
# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
MKDB_OPTIONS=--sgml-mode --output-format=xml
# Extra options to supply to gtkdoc-mktmpl
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
MKTMPL_OPTIONS=
# Extra options to supply to gtkdoc-mkhtml
MKHTML_OPTIONS=
# Extra options to supply to gtkdoc-fixref. Not normally needed.
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
FIXXREF_OPTIONS=
# Used for dependencies. The docs will be rebuilt if any of these change.
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
HFILE_GLOB=$(top_srcdir)/eekboard/*.h
CFILE_GLOB=$(top_srcdir)/eekboard/*.c
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
EXTRA_HFILES=
# Header files to ignore when scanning. Use base file name, no paths
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
IGNORE_HFILES=config.h eekboard.h
# Images to copy into HTML directory.
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
HTML_IMAGES=
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
# content_files=eekboard-overview.xml
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
# These files must be listed here *and* in content_files
# e.g. expand_content_files=running.sgml
# expand_content_files=eekboard-overview.xml
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
# signals and properties.
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS = $(GIO2_CFLAGS)
GTKDOC_LIBS = $(top_builddir)/eekboard/libeekboard.la $(GIO2_LIBS)
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make
# Other files to distribute
# e.g. EXTRA_DIST += version.xml.in
# EXTRA_DIST +=
# Files not to distribute
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
#DISTCLEANFILES +=
# Comment this out if you want your docs-status tested during 'make check'
if ENABLE_GTK_DOC
#TESTS_ENVIRONMENT = cd $(srcsrc) &&
#TESTS = $(GTKDOC_CHECK)
endif
-include $(top_srcdir)/gtk-doc.mk

View File

@ -0,0 +1,51 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
[
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
]>
<book id="index">
<bookinfo>
<title>eekboard Reference Manual</title>
<releaseinfo>
for eekboard 0.90.0.
</releaseinfo>
<copyright>
<year>2011</year>
<holder>Daiki Ueno</holder>
</copyright>
<copyright>
<year>2011</year>
<holder>Red Hat, Inc.</holder>
</copyright>
<legalnotice>
<para>
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License,
Version 1.3 or any later version published by the Free Software
Foundation; with no Invariant Sections, no Front-Cover Texts and
no Back-Cover Texts. A copy of the license is included in the
section entitled "GNU Free Documentation License".
</para>
</legalnotice>
</bookinfo>
<part id="apireference">
<title>API Manual</title>
<chapter>
<title>D-Bus client interface to eekboard-server</title>
<xi:include href="xml/eekboard-eekboard.xml"/>
<xi:include href="xml/eekboard-context.xml"/>
</chapter>
<chapter id="object-tree">
<title>Object Hierarchy</title>
<xi:include href="xml/tree_index.sgml"/>
</chapter>
<index id="api-index-full">
<title>API Index</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
</index>
</part>
</book>

View File

@ -0,0 +1,47 @@
<SECTION>
<FILE>eekboard-eekboard</FILE>
<TITLE>EekboardEekboard</TITLE>
EekboardEekboard
EekboardEekboardClass
EekboardEekboardPrivate
eekboard_eekboard_new
eekboard_eekboard_create_context
eekboard_eekboard_push_context
eekboard_eekboard_pop_context
eekboard_eekboard_destroy_context
<SUBSECTION Standard>
EEKBOARD_EEKBOARD
EEKBOARD_IS_EEKBOARD
EEKBOARD_TYPE_EEKBOARD
eekboard_eekboard_get_type
EEKBOARD_EEKBOARD_CLASS
EEKBOARD_IS_EEKBOARD_CLASS
EEKBOARD_EEKBOARD_GET_CLASS
</SECTION>
<SECTION>
<FILE>eekboard-context</FILE>
<TITLE>EekboardContext</TITLE>
EekboardContext
EekboardContextClass
EekboardContextPrivate
eekboard_context_new
eekboard_context_set_keyboard
eekboard_context_show_keyboard
eekboard_context_hide_keyboard
eekboard_context_set_group
eekboard_context_press_key
eekboard_context_release_key
eekboard_context_is_keyboard_visible
eekboard_context_set_enabled
eekboard_context_is_enabled
<SUBSECTION Standard>
EEKBOARD_CONTEXT
EEKBOARD_IS_CONTEXT
EEKBOARD_TYPE_CONTEXT
eekboard_context_get_type
EEKBOARD_CONTEXT_CLASS
EEKBOARD_IS_CONTEXT_CLASS
EEKBOARD_CONTEXT_GET_CLASS
</SECTION>

View File

@ -0,0 +1,2 @@
eekboard_context_get_type
eekboard_eekboard_get_type

View File

@ -1,5 +1,5 @@
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> # Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010 Red Hat, Inc. # Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License # modify it under the terms of the GNU Lesser General Public License
@ -16,132 +16,253 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA # 02110-1301 USA
lib_LTLIBRARIES = \ lib_LTLIBRARIES = \
libeek.la \ libeek.la \
libeek-gtk.la \ libeek-gtk.la \
libeek-xkb.la \ libeek-xkb.la \
libeek-xkl.la libeek-xkl.la
if HAVE_CLUTTER if ENABLE_CLUTTER
lib_LTLIBRARIES += libeek-clutter.la lib_LTLIBRARIES += libeek-clutter.la
endif endif
libeek_la_SOURCES = \ libeek_public_headers = \
eek-layout.c \ $(srcdir)/eek-layout.h \
eek-layout.h \ $(srcdir)/eek-element.h \
eek-element.c \ $(srcdir)/eek-container.h \
eek-element.h \ $(srcdir)/eek-keyboard.h \
eek-container.c \ $(srcdir)/eek-section.h \
eek-container.h \ $(srcdir)/eek-key.h \
eek-keyboard.c \ $(srcdir)/eek-symbol.h \
eek-keyboard.h \ $(srcdir)/eek-keysym.h \
eek-section.c \ $(srcdir)/eek-types.h \
eek-section.h \ $(srcdir)/eek-xml.h \
eek-key.c \ $(srcdir)/eek-xml-layout.h \
eek-key.h \ $(srcdir)/eek-serializable.h \
eek-types.h \ $(srcdir)/eek-theme.h \
eek-types.c \ $(srcdir)/eek.h
eek-keysym.h \
eek-keysym.c \
eek-special-keysym-labels.h \
eek-unicode-keysym-labels.h \
eek-keyname-keysym-labels.h
libeek_la_CFLAGS = $(GOBJECT2_CFLAGS) $(CAIRO_CFLAGS) $(PANGO_CFLAGS) libeek_private_headers = \
libeek_la_LIBADD = $(GOBJECT2_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS) $(srcdir)/eek-renderer.h \
$(srcdir)/eek-special-keysym-entries.h \
$(srcdir)/eek-unicode-keysym-entries.h \
$(srcdir)/eek-xkeysym-keysym-entries.h \
$(srcdir)/eek-marshalers.h \
$(srcdir)/eek-theme-context.h \
$(srcdir)/eek-theme-private.h \
$(srcdir)/eek-theme-node.h
if HAVE_CLUTTER libeek_sources = \
libeek_clutter_la_SOURCES = \ $(srcdir)/eek-layout.c \
eek-clutter-keyboard.c \ $(srcdir)/eek-element.c \
eek-clutter-keyboard.h \ $(srcdir)/eek-container.c \
eek-clutter-section.c \ $(srcdir)/eek-keyboard.c \
eek-clutter-section.h \ $(srcdir)/eek-section.c \
eek-clutter-key.c \ $(srcdir)/eek-key.c \
eek-clutter-key.h \ $(srcdir)/eek-symbol.c \
eek-clutter-key-actor.c \ $(srcdir)/eek-keysym.c \
eek-clutter-key-actor.h \ $(srcdir)/eek-types.c \
eek-clutter-drawing-context.c \ $(srcdir)/eek-serializable.c \
eek-clutter-drawing-context.h \ $(srcdir)/eek-xml.c \
eek-drawing.h \ $(srcdir)/eek-xml-layout.c \
eek-drawing.c \ $(srcdir)/eek-renderer.c \
eek-clutter.h $(srcdir)/eek-keyboard-drawing.c \
$(srcdir)/eek-theme.c \
$(srcdir)/eek-theme-context.c \
$(srcdir)/eek-theme-node.c
libeek_keysym_sources = \
$(srcdir)/eek-special-keysym-entries.h \
$(srcdir)/eek-unicode-keysym-entries.h \
$(srcdir)/eek-xkeysym-keysym-entries.h
libeek_enumtypes_sources = \
$(srcdir)/eek-enumtypes.c \
$(srcdir)/eek-enumtypes.h
libeek_marshalers_sources = \
$(srcdir)/eek-marshalers.c \
$(srcdir)/eek-marshalers.h
BUILT_SOURCES = \
$(libeek_keysym_sources) \
$(libeek_marshalers_sources)
libeek_la_SOURCES = \
$(libeek_sources) \
$(srcdir)/eek-marshalers.c
libeek_la_CFLAGS = $(GIO2_CFLAGS) $(PANGOCAIRO_CFLAGS) $(LIBCROCO_CFLAGS)
libeek_la_LIBADD = $(GIO2_LIBS) $(PANGOCAIRO_LIBS) $(LIBCROCO_LIBS) -lm
if ENABLE_CLUTTER
libeek_clutter_public_headers = \
$(srcdir)/eek-clutter-keyboard.h \
$(srcdir)/eek-clutter.h
libeek_clutter_private_headers = \
$(srcdir)/eek-clutter-section.h \
$(srcdir)/eek-clutter-key.h \
$(srcdir)/eek-clutter-renderer.h
libeek_clutter_sources = \
$(srcdir)/eek-clutter-keyboard.c \
$(srcdir)/eek-clutter-section.c \
$(srcdir)/eek-clutter-key.c \
$(srcdir)/eek-clutter-renderer.c
libeek_clutter_la_SOURCES = $(libeek_clutter_sources)
libeek_clutter_la_CFLAGS = $(CLUTTER_CFLAGS) libeek_clutter_la_CFLAGS = $(CLUTTER_CFLAGS)
libeek_clutter_la_LIBADD = libeek.la $(CLUTTER_LIBS) libeek_clutter_la_LIBADD = libeek.la $(CLUTTER_LIBS)
endif endif
libeek_gtk_la_SOURCES = \ libeek_gtk_public_headers = \
eek-gtk-keyboard.c \ $(srcdir)/eek-gtk-keyboard.h \
eek-gtk-keyboard.h \ $(srcdir)/eek-gtk.h
eek-drawing.h \ libeek_gtk_private_headers = \
eek-drawing.c \ $(srcdir)/eek-gtk-renderer.h
eek-gtk.h libeek_gtk_sources = \
$(srcdir)/eek-gtk-keyboard.c \
$(srcdir)/eek-gtk-renderer.c
libeek_gtk_la_CFLAGS = $(GTK2_CFLAGS) libeek_gtk_la_SOURCES = $(libeek_gtk_sources)
libeek_gtk_la_LIBADD = libeek.la $(GTK2_LIBS) libeek_gtk_la_CFLAGS = $(GTK_CFLAGS)
libeek_gtk_la_LIBADD = libeek.la $(GTK_LIBS)
libeek_xkb_la_SOURCES = \ libeek_xkb_public_headers = \
eek-xkb-layout.h \ $(srcdir)/eek-xkb-layout.h \
eek-xkb-layout.c $(srcdir)/eek-xkb.h
libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS) libeek_xkb_sources = \
libeek_xkb_la_LIBADD = libeek.la $(GTK2_LIBS) $(XKB_LIBS) $(srcdir)/eek-xkb-layout.c
libeek_xkl_la_SOURCES = \ libeek_xkb_la_SOURCES = $(libeek_xkb_sources)
eek-xkl-layout.h \ libeek_xkb_la_CFLAGS = $(XKB_CFLAGS) $(GTK_CFLAGS)
eek-xkl-layout.c libeek_xkb_la_LIBADD = libeek.la $(XKB_LIBS) $(GTK_LIBS)
libeek_xkl_la_CFLAGS = $(GTK2_CFLAGS) $(LIBXKLAVIER_CFLAGS) libeek_xkl_public_headers = \
libeek_xkl_la_LIBADD = libeek-xkb.la $(GTK2_LIBS) $(LIBXKLAVIER_LIBS) $(srcdir)/eek-xkl-layout.h \
$(srcdir)/eek-xkl.h
libeek_xkl_sources = \
$(srcdir)/eek-xkl-layout.c
libeek_xkl_la_SOURCES = $(libeek_xkl_sources)
libeek_xkl_la_CFLAGS = $(LIBXKLAVIER_CFLAGS) $(GTK_CFLAGS)
libeek_xkl_la_LIBADD = libeek-xkb.la $(LIBXKLAVIER_LIBS) $(GTK_LIBS)
eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek
eek_HEADERS = \ eek_HEADERS = \
$(top_srcdir)/eek/eek-element.h \ $(libeek_public_headers) \
$(top_srcdir)/eek/eek-container.h \ $(libeek_clutter_public_headers) \
$(top_srcdir)/eek/eek-keyboard.h \ $(libeek_gtk_public_headers) \
$(top_srcdir)/eek/eek-section.h \ $(libeek_xkb_public_headers) \
$(top_srcdir)/eek/eek-key.h \ $(libeek_xkl_public_headers)
$(top_srcdir)/eek/eek-layout.h \
$(top_srcdir)/eek/eek-keysym.h \
$(top_srcdir)/eek/eek-types.h \
$(top_srcdir)/eek/eek-xkb-layout.h \
$(top_srcdir)/eek/eek-xkl-layout.h \
$(top_srcdir)/eek/eek.h \
$(top_srcdir)/eek/eek-xkb.h \
$(top_srcdir)/eek/eek-xkl.h
if HAVE_CLUTTER noinst_HEADERS = \
eek_HEADERS += \ $(libeek_private_headers) \
$(top_srcdir)/eek/eek-clutter-keyboard.h \ $(libeek_clutter_private_headers) \
$(top_srcdir)/eek/eek-clutter-section.h \ $(libeek_gtk_private_headers) \
$(top_srcdir)/eek/eek-clutter-key.h \ $(libeek_xkb_private_headers) \
$(top_srcdir)/eek/eek-clutter.h $(libeek_xkl_private_headers)
endif
eek-keysym.c: eek-special-keysym-labels.h eek-unicode-keysym-labels.h eek-keyname-keysym-labels.h eek-special-keysym-entries.h: special-keysym-entries.txt
$(PYTHON) ./gen-keysym-entries.py special_keysym_entries < $< > $@
eek-unicode-keysym-entries.h: unicode-keysym-entries.txt
$(PYTHON) ./gen-keysym-entries.py unicode_keysym_entries < $< > $@
eek-xkeysym-keysym-entries.h: xkeysym-keysym-entries.txt
$(PYTHON) ./gen-keysym-entries.py xkeysym_keysym_entries < $< > $@
eek-special-keysym-labels.h: special-keysym-labels.txt # gen marshal
$(PYTHON) ./gen-keysym-labels.py special_keysym_labels < $< > $@ eek-marshalers.h: eek-marshalers.list
eek-unicode-keysym-labels.h: unicode-keysym-labels.txt $(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=_eek_marshal $(srcdir)/eek-marshalers.list --header --internal > $@.tmp && \
$(PYTHON) ./gen-keysym-labels.py unicode_keysym_labels < $< > $@ mv $@.tmp $@
eek-keyname-keysym-labels.h: keyname-keysym-labels.txt
$(PYTHON) ./gen-keysym-labels.py keyname_keysym_labels < $< > $@ eek-marshalers.c: eek-marshalers.list eek-marshalers.h
$(AM_V_GEN) (echo "#include \"eek-marshalers.h\""; \
$(GLIB_GENMARSHAL) --prefix=_eek_marshal $(srcdir)/eek-marshalers.list --body --internal) > $@.tmp && \
mv $@.tmp $@
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libeek.pc \ pkgconfig_DATA = \
libeek-clutter.pc \ eek-$(EEK_API_VERSION).pc \
libeek-gtk.pc \ eek-gtk-$(EEK_API_VERSION).pc \
libeek-xkb.pc \ eek-xkb-$(EEK_API_VERSION).pc \
libeek-xkl.pc eek-xkl-$(EEK_API_VERSION).pc
DISTCLEANFILES = \ if ENABLE_CLUTTER
eek-special-keysym-labels.h \ pkgconfig_DATA += eek-clutter-$(EEK_API_VERSION).pc
eek-unicode-keysym-labels.h \ endif
eek-keyname-keysym-labels.h \
CLEANFILES =
DISTCLEANFILES = \
$(BUILT_SOURCES) \
$(pkgconfig_DATA) $(pkgconfig_DATA)
EXTRA_DIST = \ EXTRA_DIST = \
gen-keysym-labels.py \ gen-keysym-entries.py \
special-keysym-labels.txt \ special-keysym-entries.txt \
unicode-keysym-labels.txt \ unicode-keysym-entries.txt \
keyname-keysym-labels.txt xkeysym-keysym-entries.txt \
eek-marshalers.list
-include $(INTROSPECTION_MAKEFILE)
INTROSPECTION_GIRS =
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(builddir)
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
if HAVE_INTROSPECTION
Eek@EEK_LIBRARY_SUFFIX@.gir: libeek.la
Eek@EEK_LIBRARY_SUFFIX_U@_gir_SCANNERFLAGS = --strip-prefix=Eek --pkg=glib-2.0
Eek@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GLib-2.0 GObject-2.0 Gio-2.0
Eek@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_la_CFLAGS)
Eek@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek.la
Eek@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_sources) $(libeek_public_headers)
EekGtk@EEK_LIBRARY_SUFFIX@.gir: libeek-gtk.la Eek@EEK_LIBRARY_SUFFIX@.gir
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 Gtk-@GTK_API_VERSION@ Eek@EEK_LIBRARY_SUFFIX@
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_gtk_la_CFLAGS)
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-gtk.la
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_gtk_sources) $(libeek_gtk_public_headers)
if ENABLE_CLUTTER
EekClutter@EEK_LIBRARY_SUFFIX@.gir: libeek-clutter.la Eek@EEK_LIBRARY_SUFFIX@.gir
EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 Clutter-1.0 Eek@EEK_LIBRARY_SUFFIX@
EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_clutter_la_CFLAGS)
EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-clutter.la
EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_clutter_sources) $(libeek_clutter_public_headers)
endif
EekXkb@EEK_LIBRARY_SUFFIX@.gir: libeek-xkb.la Eek@EEK_LIBRARY_SUFFIX@.gir
EekXkb@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 Eek@EEK_LIBRARY_SUFFIX@
EekXkb@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_xkb_la_CFLAGS)
EekXkb@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-xkb.la
EekXkb@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_xkb_sources) $(libeek_xkb_public_headers)
EekXkl@EEK_LIBRARY_SUFFIX@.gir: libeek-xkl.la EekXkb@EEK_LIBRARY_SUFFIX@.gir
EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 EekXkb@EEK_LIBRARY_SUFFIX@
EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_xkl_la_CFLAGS)
EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-xkl.la
EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_xkl_sources) $(libeek_xkl_public_headers)
INTROSPECTION_GIRS += \
Eek@EEK_LIBRARY_SUFFIX@.gir \
EekGtk@EEK_LIBRARY_SUFFIX@.gir \
EekXkb@EEK_LIBRARY_SUFFIX@.gir \
EekXkl@EEK_LIBRARY_SUFFIX@.gir
if ENABLE_CLUTTER
INTROSPECTION_GIRS += \
EekClutter@EEK_LIBRARY_SUFFIX@.gir
endif
girdir = $(datadir)/gir-1.0
gir_DATA = $(INTROSPECTION_GIRS)
typelibdir = $(libdir)/girepository-1.0
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
CLEANFILES += $(gir_DATA) $(typelib_DATA)
endif

View File

@ -1,5 +1,5 @@
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> # Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010 Red Hat, Inc. # Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License # modify it under the terms of the GNU Lesser General Public License
@ -23,8 +23,8 @@ includedir=@includedir@
Name: EEK Name: EEK
Description: A Library to Create Keyboard-like UI Description: A Library to Create Keyboard-like UI
URL: http://github.com/ueno/eekboard URL: http://ueno.github.com/eekboard/
Version: @VERSION@ Version: @VERSION@
Requires: gobject-2.0
Libs: -L${libdir} -leek Libs: -L${libdir} -leek
Libs.private: @GOBJECT2_LIBS@
Cflags: -I${includedir}/eek-@EEK_API_VERSION@ Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -1,5 +1,5 @@
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> # Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010 Red Hat, Inc. # Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License # modify it under the terms of the GNU Lesser General Public License
@ -23,8 +23,8 @@ includedir=@includedir@
Name: libeek-clutter Name: libeek-clutter
Description: A Library to Create Keyboard-like UI (Clutter Support) Description: A Library to Create Keyboard-like UI (Clutter Support)
URL: http://github.com/ueno/eekboard URL: http://ueno.github.com/eekboard/
Version: @VERSION@ Version: @VERSION@
Libs: -L${libdir} -leek -leek-clutter Requires: eek-@EEK_API_VERSION@ clutter-1.0
Libs.private: @GOBJECT2_LIBS@ @CLUTTER_LIBS@ Libs: -L${libdir} -leek-clutter
Cflags: -I${includedir}/eek-@EEK_API_VERSION@ Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -1,138 +0,0 @@
/*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <string.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-clutter-drawing-context.h"
G_DEFINE_TYPE (EekClutterDrawingContext, eek_clutter_drawing_context,
G_TYPE_INITIALLY_UNOWNED);
#define EEK_CLUTTER_DRAWING_CONTEXT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_DRAWING_CONTEXT, EekClutterDrawingContextPrivate))
struct _EekClutterDrawingContextPrivate
{
/* outline pointer -> ClutterTexture */
GHashTable *outline_textures;
/* keysym category -> PangoFontDescription * */
PangoFontDescription *category_fonts[EEK_KEYSYM_CATEGORY_LAST];
};
static void
eek_clutter_drawing_context_dispose (GObject *object)
{
EekClutterDrawingContextPrivate *priv =
EEK_CLUTTER_DRAWING_CONTEXT_GET_PRIVATE(object);
if (priv->outline_textures) {
g_hash_table_unref (priv->outline_textures);
priv->outline_textures = NULL;
}
}
static void
eek_clutter_drawing_context_finalize (GObject *object)
{
EekClutterDrawingContextPrivate *priv =
EEK_CLUTTER_DRAWING_CONTEXT_GET_PRIVATE(object);
gint i;
for (i = 0; i < EEK_KEYSYM_CATEGORY_LAST; i++)
pango_font_description_free (priv->category_fonts[i]);
}
static void
eek_clutter_drawing_context_class_init (EekClutterDrawingContextClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (gobject_class,
sizeof (EekClutterDrawingContextPrivate));
gobject_class->finalize = eek_clutter_drawing_context_finalize;
gobject_class->dispose = eek_clutter_drawing_context_dispose;
}
static void
eek_clutter_drawing_context_init (EekClutterDrawingContext *self)
{
EekClutterDrawingContextPrivate *priv;
priv = self->priv = EEK_CLUTTER_DRAWING_CONTEXT_GET_PRIVATE(self);
priv->outline_textures = g_hash_table_new (g_direct_hash, g_direct_equal);
memset (priv->category_fonts, 0, sizeof *priv->category_fonts);
}
void
eek_clutter_drawing_context_set_outline_texture
(EekClutterDrawingContext *context,
EekOutline *outline,
ClutterActor *texture)
{
EekClutterDrawingContextPrivate *priv =
EEK_CLUTTER_DRAWING_CONTEXT_GET_PRIVATE(context);
g_return_if_fail (priv);
g_hash_table_insert (context->priv->outline_textures, outline, texture);
}
ClutterActor *
eek_clutter_drawing_context_get_outline_texture
(EekClutterDrawingContext *context,
EekOutline *outline)
{
EekClutterDrawingContextPrivate *priv =
EEK_CLUTTER_DRAWING_CONTEXT_GET_PRIVATE(context);
g_return_val_if_fail (priv, NULL);
return g_hash_table_lookup (context->priv->outline_textures, outline);
}
void
eek_clutter_drawing_context_set_category_font
(EekClutterDrawingContext *context,
EekKeysymCategory category,
PangoFontDescription *font)
{
EekClutterDrawingContextPrivate *priv =
EEK_CLUTTER_DRAWING_CONTEXT_GET_PRIVATE(context);
g_return_if_fail (priv);
priv->category_fonts[category] = pango_font_description_copy (font);
}
PangoFontDescription *
eek_clutter_drawing_context_get_category_font
(EekClutterDrawingContext *context,
EekKeysymCategory category)
{
EekClutterDrawingContextPrivate *priv =
EEK_CLUTTER_DRAWING_CONTEXT_GET_PRIVATE(context);
g_return_val_if_fail (priv, NULL);
return priv->category_fonts[category];
}
EekClutterDrawingContext *
eek_clutter_drawing_context_new (void)
{
return g_object_new (EEK_TYPE_CLUTTER_DRAWING_CONTEXT, NULL);
}

View File

@ -1,82 +0,0 @@
/*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef EEK_CLUTTER_DRAWING_CONTEXT_H
#define EEK_CLUTTER_DRAWING_CONTEXT_H 1
#include <clutter/clutter.h>
#include <pango/pango.h>
#include "eek-keysym.h"
#include "eek-types.h"
G_BEGIN_DECLS
#define EEK_TYPE_CLUTTER_DRAWING_CONTEXT (eek_clutter_drawing_context_get_type())
#define EEK_CLUTTER_DRAWING_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_DRAWING_CONTEXT, EekClutterDrawingContext))
#define EEK_CLUTTER_DRAWING_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_DRAWING_CONTEXT, EekClutterDrawingContextClass))
#define EEK_IS_CLUTTER_DRAWING_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_DRAWING_CONTEXT))
#define EEK_IS_CLUTTER_DRAWING_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_DRAWING_CONTEXT))
#define EEK_CLUTTER_DRAWING_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_DRAWING_CONTEXT, EekClutterDrawingContextClass))
typedef struct _EekClutterDrawingContext EekClutterDrawingContext;
typedef struct _EekClutterDrawingContextClass EekClutterDrawingContextClass;
typedef struct _EekClutterDrawingContextPrivate EekClutterDrawingContextPrivate;
struct _EekClutterDrawingContext
{
/*< private >*/
GInitiallyUnowned parent;
/*< private >*/
EekClutterDrawingContextPrivate *priv;
};
struct _EekClutterDrawingContextClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
/*< private >*/
/* padding */
gpointer pdummy[24];
};
GType eek_clutter_drawing_context_get_type
(void) G_GNUC_CONST;
EekClutterDrawingContext *eek_clutter_drawing_context_new
(void);
void eek_clutter_drawing_context_set_outline_texture
(EekClutterDrawingContext *context,
EekOutline *outline,
ClutterActor *texture);
ClutterActor *eek_clutter_drawing_context_get_outline_texture
(EekClutterDrawingContext *context,
EekOutline *outline);
void eek_clutter_drawing_context_set_category_font
(EekClutterDrawingContext *context,
EekKeysymCategory category,
PangoFontDescription *fonts);
PangoFontDescription *eek_clutter_drawing_context_get_category_font
(EekClutterDrawingContext *context,
EekKeysymCategory category);
G_END_DECLS
#endif /* EEK_CLUTTER_DRAWING_CONTEXT_H */

View File

@ -1,375 +0,0 @@
/*
* Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <cogl/cogl.h>
#include <cogl/cogl-pango.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-clutter-key-actor.h"
#include "eek-keysym.h"
#include "eek-drawing.h"
#include "eek-section.h"
#include "eek-keyboard.h"
#define noKBDRAW_DEBUG
enum {
PRESSED,
RELEASED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (EekClutterKeyActor, eek_clutter_key_actor,
CLUTTER_TYPE_GROUP);
#define EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActorPrivate))
struct _EekClutterKeyActorPrivate
{
EekClutterDrawingContext *context;
EekKey *key;
ClutterActor *texture;
};
static ClutterActor *get_texture (EekClutterKeyActor *actor);
static void draw_key_on_layout (EekClutterKeyActor *actor,
PangoLayout *layout);
static void key_enlarge (ClutterActor *actor);
static void key_shrink (ClutterActor *actor);
static void
eek_clutter_key_actor_real_paint (ClutterActor *self)
{
EekClutterKeyActorPrivate *priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE (self);
PangoLayout *layout;
PangoRectangle logical_rect = { 0, };
CoglColor color;
ClutterGeometry geom;
EekBounds bounds;
eek_element_get_bounds (EEK_ELEMENT(priv->key), &bounds);
clutter_actor_set_anchor_point_from_gravity (self,
CLUTTER_GRAVITY_CENTER);
clutter_actor_set_position (self,
bounds.x + bounds.width / 2,
bounds.y + bounds.height / 2);
if (!priv->texture) {
priv->texture = get_texture (EEK_CLUTTER_KEY_ACTOR(self));
clutter_actor_set_position (priv->texture, 0, 0);
clutter_container_add_actor (CLUTTER_CONTAINER(self), priv->texture);
}
CLUTTER_ACTOR_CLASS (eek_clutter_key_actor_parent_class)->
paint (self);
/* Draw the label on the key. */
layout = clutter_actor_create_pango_layout (self, NULL);
draw_key_on_layout (EEK_CLUTTER_KEY_ACTOR(self), layout);
pango_layout_get_extents (layout, NULL, &logical_rect);
/* FIXME: Color should be configurable through a property. */
cogl_color_set_from_4ub (&color, 0x80, 0x00, 0x00, 0xff);
clutter_actor_get_allocation_geometry (self, &geom);
cogl_pango_render_layout
(layout,
(geom.width - logical_rect.width / PANGO_SCALE) / 2,
(geom.height - logical_rect.height / PANGO_SCALE) / 2,
&color,
0);
g_object_unref (layout);
}
/* FIXME: This is a workaround for the bug
* http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer
* says this is not a right way to solve the original problem.
*/
static void
eek_clutter_key_actor_real_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
PangoLayout *layout;
/* Draw the label on the key - just to validate the glyph cache. */
layout = clutter_actor_create_pango_layout (self, NULL);
draw_key_on_layout (EEK_CLUTTER_KEY_ACTOR(self), layout);
cogl_pango_ensure_glyph_cache_for_layout (layout);
g_object_unref (layout);
CLUTTER_ACTOR_CLASS (eek_clutter_key_actor_parent_class)->
get_preferred_width (self, for_height, min_width_p, natural_width_p);
}
static void
eek_clutter_key_actor_real_pressed (EekClutterKeyActor *self)
{
ClutterActor *actor, *section;
actor = CLUTTER_ACTOR(self);
/* Make sure the enlarged key show up on the keys which belong
to other sections. */
section = clutter_actor_get_parent (actor);
clutter_actor_raise_top (section);
clutter_actor_raise_top (actor);
key_enlarge (actor);
}
static void
eek_clutter_key_actor_real_released (EekClutterKeyActor *self)
{
ClutterActor *actor, *section;
actor = CLUTTER_ACTOR(self);
/* Make sure the enlarged key show up on the keys which belong
to other sections. */
section = clutter_actor_get_parent (actor);
clutter_actor_raise_top (section);
clutter_actor_raise_top (actor);
key_shrink (actor);
}
static void
eek_clutter_key_actor_dispose (GObject *object)
{
EekClutterKeyActorPrivate *priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(object);
if (priv->context) {
g_object_unref (priv->context);
priv->context = NULL;
}
if (priv->key) {
g_object_unref (priv->key);
priv->key = NULL;
}
G_OBJECT_CLASS (eek_clutter_key_actor_parent_class)->dispose (object);
}
static void
eek_clutter_key_actor_class_init (EekClutterKeyActorClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
g_type_class_add_private (gobject_class,
sizeof (EekClutterKeyActorPrivate));
actor_class->paint = eek_clutter_key_actor_real_paint;
/* FIXME: This is a workaround for the bug
* http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer
* says this is not a right way to solve the original problem.
*/
actor_class->get_preferred_width =
eek_clutter_key_actor_real_get_preferred_width;
gobject_class->dispose = eek_clutter_key_actor_dispose;
/* signals */
klass->pressed = eek_clutter_key_actor_real_pressed;
klass->released = eek_clutter_key_actor_real_released;
signals[PRESSED] =
g_signal_new ("pressed",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekClutterKeyActorClass, pressed),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[RELEASED] =
g_signal_new ("released",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekClutterKeyActorClass, released),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void
on_button_press_event (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
EekClutterKeyActorPrivate *priv =
EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor);
/* priv->key will send back PRESSED event of actor. */
g_signal_emit_by_name (priv->key, "pressed");
}
static void
on_button_release_event (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
EekClutterKeyActorPrivate *priv =
EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor);
/* priv->key will send back RELEASED event of actor. */
g_signal_emit_by_name (priv->key, "released");
}
static void
eek_clutter_key_actor_init (EekClutterKeyActor *self)
{
EekClutterKeyActorPrivate *priv;
priv = self->priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(self);
priv->key = NULL;
priv->texture = NULL;
clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE);
g_signal_connect (self, "button-press-event",
G_CALLBACK (on_button_press_event), NULL);
g_signal_connect (self, "button-release-event",
G_CALLBACK (on_button_release_event), NULL);
}
ClutterActor *
eek_clutter_key_actor_new (EekClutterDrawingContext *context, EekKey *key)
{
EekClutterKeyActor *actor;
actor = g_object_new (EEK_TYPE_CLUTTER_KEY_ACTOR, NULL);
actor->priv->context = context;
g_object_ref_sink (actor->priv->context);
actor->priv->key = key;
g_object_ref_sink (actor->priv->key);
return CLUTTER_ACTOR(actor);
}
#if 0
static void
on_key_animate_complete (ClutterAnimation *animation,
gpointer user_data)
{
ClutterActor *actor = (ClutterActor*)user_data;
/* reset after effect */
clutter_actor_set_opacity (actor, 0xff);
clutter_actor_set_scale (actor, 1.0, 1.0);
}
#endif
static void
key_enlarge (ClutterActor *actor)
{
clutter_actor_set_scale (actor, 1.0, 1.0);
clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 150,
"scale-x", 1.5,
"scale-y", 1.5,
NULL);
}
static void
key_shrink (ClutterActor *actor)
{
clutter_actor_set_scale (actor, 1.5, 1.5);
clutter_actor_animate (actor, CLUTTER_EASE_OUT_SINE, 150,
"scale-x", 1.0,
"scale-y", 1.0,
NULL);
}
static ClutterActor *
create_texture_for_key (EekKey *key)
{
ClutterActor *texture;
cairo_t *cr;
EekOutline *outline;
EekBounds bounds;
outline = eek_key_get_outline (EEK_KEY(key));
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
texture = clutter_cairo_texture_new (bounds.width, bounds.height);
cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE(texture));
eek_draw_outline (cr, outline);
cairo_destroy (cr);
return texture;
}
static ClutterActor *
get_texture (EekClutterKeyActor *actor)
{
ClutterActor *texture;
EekOutline *outline;
outline = eek_key_get_outline (actor->priv->key);
texture =
eek_clutter_drawing_context_get_outline_texture (actor->priv->context,
outline);
if (texture == NULL) {
texture = create_texture_for_key (actor->priv->key);
eek_clutter_drawing_context_set_outline_texture (actor->priv->context,
outline,
texture);
} else
texture = clutter_clone_new (texture);
return texture;
}
static void
draw_key_on_layout (EekClutterKeyActor *self,
PangoLayout *layout)
{
EekClutterKeyActorPrivate *priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE (self);
guint keysym;
const gchar *label, *empty_label = "";
EekKeysymCategory category;
EekBounds bounds;
PangoFontDescription *font;
keysym = eek_key_get_keysym (priv->key);
if (keysym == EEK_INVALID_KEYSYM)
return;
category = eek_keysym_get_category (keysym);
if (category == EEK_KEYSYM_CATEGORY_UNKNOWN)
return;
font = eek_clutter_drawing_context_get_category_font (priv->context,
category);
pango_layout_set_font_description (layout, font);
eek_element_get_bounds (EEK_ELEMENT(priv->key), &bounds);
pango_layout_set_width (layout, PANGO_SCALE * bounds.width);
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
label = eek_keysym_to_string (keysym);
if (!label)
label = empty_label;
eek_draw_text_on_layout (layout, label);
if (label != empty_label)
g_free ((gpointer)label);
}

View File

@ -1,68 +0,0 @@
/*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef EEK_CLUTTER_KEY_ACTOR_H
#define EEK_CLUTTER_KEY_ACTOR_H 1
#include <clutter/clutter.h>
#include "eek-clutter-drawing-context.h"
#include "eek-key.h"
G_BEGIN_DECLS
#define EEK_TYPE_CLUTTER_KEY_ACTOR (eek_clutter_key_actor_get_type())
#define EEK_CLUTTER_KEY_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActor))
#define EEK_CLUTTER_KEY_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActorClass))
#define EEK_IS_CLUTTER_KEY_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR))
#define EEK_IS_CLUTTER_KEY_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_KEY_ACTOR))
#define EEK_CLUTTER_KEY_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActorClass))
typedef struct _EekClutterKeyActor EekClutterKeyActor;
typedef struct _EekClutterKeyActorClass EekClutterKeyActorClass;
typedef struct _EekClutterKeyActorPrivate EekClutterKeyActorPrivate;
struct _EekClutterKeyActor
{
/*< private >*/
ClutterGroup parent;
/*< private >*/
EekClutterKeyActorPrivate *priv;
};
struct _EekClutterKeyActorClass
{
/*< private >*/
ClutterGroupClass parent_class;
/* signals */
void (* pressed) (EekClutterKeyActor *self);
void (* released) (EekClutterKeyActor *self);
/*< private >*/
/* padding */
gpointer pdummy[24];
};
GType eek_clutter_key_actor_get_type
(void) G_GNUC_CONST;
ClutterActor *eek_clutter_key_actor_new (EekClutterDrawingContext *context,
EekKey *key);
G_END_DECLS
#endif /* EEK_CLUTTER_KEY_ACTOR_H */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -23,98 +23,269 @@
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-clutter-key.h" #include "eek-clutter-key.h"
#include "eek-clutter-key-actor.h"
G_DEFINE_TYPE (EekClutterKey, eek_clutter_key, EEK_TYPE_KEY); enum {
PROP_0,
PROP_KEY,
PROP_RENDERER,
PROP_LAST
};
G_DEFINE_TYPE (EekClutterKey, eek_clutter_key, CLUTTER_TYPE_ACTOR);
#define EEK_CLUTTER_KEY_GET_PRIVATE(obj) \ #define EEK_CLUTTER_KEY_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY, EekClutterKeyPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY, EekClutterKeyPrivate))
struct _EekClutterKeyPrivate struct _EekClutterKeyPrivate
{ {
EekClutterDrawingContext *context; EekKey *key;
ClutterActor *actor; EekClutterRenderer *renderer;
gulong pressed_handler;
gulong released_handler;
}; };
static void static void
eek_clutter_key_real_set_name (EekElement *self, on_pressed (EekKey *key, gpointer user_data)
const gchar *name)
{ {
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); ClutterActor *actor = user_data, *parent;
EEK_ELEMENT_CLASS (eek_clutter_key_parent_class)-> parent = clutter_actor_get_parent (actor);
set_name (self, name); clutter_actor_raise_top (parent);
clutter_actor_raise_top (actor);
clutter_actor_set_scale_with_gravity (actor,
1.0,
1.0,
CLUTTER_GRAVITY_CENTER);
if (priv->actor) clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 150,
clutter_actor_set_name (CLUTTER_ACTOR(priv->actor), name); "scale-x", 1.5,
"scale-y", 1.5,
NULL);
} }
static void static void
eek_clutter_key_real_set_bounds (EekElement *self, on_released (EekKey *key, gpointer user_data)
EekBounds *bounds) {
ClutterActor *actor = user_data, *parent;
parent = clutter_actor_get_parent (actor);
clutter_actor_raise_top (parent);
clutter_actor_raise_top (actor);
clutter_actor_set_scale_with_gravity (actor,
1.5,
1.5,
CLUTTER_GRAVITY_CENTER);
clutter_actor_animate (actor, CLUTTER_EASE_OUT_SINE, 150,
"scale-x", 1.0,
"scale-y", 1.0,
NULL);
}
static void
set_position (ClutterActor *self)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
EekBounds bounds;
gdouble scale;
eek_element_get_bounds (EEK_ELEMENT(priv->key), &bounds);
scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer));
clutter_actor_set_position (self, bounds.x * scale, bounds.y * scale);
}
static void
eek_clutter_key_real_realize (ClutterActor *self)
{ {
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
EEK_ELEMENT_CLASS (eek_clutter_key_parent_class)-> set_position (self);
set_bounds (self, bounds); clutter_actor_set_reactive (self, TRUE);
if (priv->actor) { priv->pressed_handler =
clutter_actor_set_position (priv->actor, bounds->x, bounds->y); g_signal_connect (priv->key, "pressed",
clutter_actor_set_size (priv->actor, bounds->width, bounds->height); G_CALLBACK(on_pressed), self);
priv->released_handler =
g_signal_connect (priv->key, "released",
G_CALLBACK(on_released), self);
}
static void
eek_clutter_key_real_paint (ClutterActor *self)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
set_position (self);
eek_clutter_renderer_render_key (priv->renderer, self, priv->key);
}
static void
eek_clutter_key_real_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
EekBounds bounds;
gdouble scale;
scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer));
eek_element_get_bounds (EEK_ELEMENT(priv->key), &bounds);
*min_width_p = 0.0f;
*natural_width_p = bounds.width * scale;
}
static void
eek_clutter_key_real_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
EekBounds bounds;
gdouble scale;
scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer));
eek_element_get_bounds (EEK_ELEMENT(priv->key), &bounds);
*min_height_p = 0.0f;
*natural_height_p = bounds.height * scale;
}
static void
eek_clutter_key_real_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
CLUTTER_ACTOR_CLASS (eek_clutter_key_parent_class)->
allocate (self, box, flags);
}
static gboolean
eek_clutter_key_real_button_press_event (ClutterActor *self,
ClutterButtonEvent *event)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_signal_emit_by_name (priv->key, "pressed");
return TRUE;
}
static gboolean
eek_clutter_key_real_button_release_event (ClutterActor *self,
ClutterButtonEvent *event)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_signal_emit_by_name (priv->key, "released");
return TRUE;
}
static gboolean
eek_clutter_key_real_leave_event (ClutterActor *self,
ClutterCrossingEvent *event)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
if (eek_key_is_pressed (priv->key))
g_signal_emit_by_name (priv->key, "released");
return TRUE;
}
static void
eek_clutter_key_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object);
switch (prop_id) {
case PROP_KEY:
priv->key = g_value_get_object (value);
g_object_ref (priv->key);
break;
case PROP_RENDERER:
priv->renderer = g_value_get_object (value);
g_object_ref (priv->renderer);
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
} }
} }
static void
eek_clutter_key_real_pressed (EekKey *key)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(key);
if (priv->actor)
g_signal_emit_by_name (priv->actor, "pressed");
}
static void
eek_clutter_key_real_released (EekKey *key)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(key);
if (priv->actor)
g_signal_emit_by_name (priv->actor, "released");
}
static void static void
eek_clutter_key_dispose (GObject *object) eek_clutter_key_dispose (GObject *object)
{ {
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object);
if (priv->context) { if (priv->renderer) {
g_object_unref (priv->context); g_object_unref (priv->renderer);
priv->context = NULL; priv->renderer = NULL;
} }
if (priv->actor) {
g_object_unref (priv->actor); if (priv->key) {
priv->actor = NULL; if (g_signal_handler_is_connected (priv->key, priv->pressed_handler))
g_signal_handler_disconnect (priv->key, priv->pressed_handler);
if (g_signal_handler_is_connected (priv->key, priv->released_handler))
g_signal_handler_disconnect (priv->key, priv->released_handler);
g_object_unref (priv->key);
priv->key = NULL;
} }
G_OBJECT_CLASS (eek_clutter_key_parent_class)->dispose (object); G_OBJECT_CLASS (eek_clutter_key_parent_class)->dispose (object);
} }
static void static void
eek_clutter_key_class_init (EekClutterKeyClass *klass) eek_clutter_key_class_init (EekClutterKeyClass *klass)
{ {
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
EekElementClass *element_class = EEK_ELEMENT_CLASS (klass); GParamSpec *pspec;
EekKeyClass *key_class = EEK_KEY_CLASS (klass);
g_type_class_add_private (gobject_class, g_type_class_add_private (gobject_class,
sizeof (EekClutterKeyPrivate)); sizeof (EekClutterKeyPrivate));
element_class->set_name = eek_clutter_key_real_set_name; actor_class->realize = eek_clutter_key_real_realize;
element_class->set_bounds = eek_clutter_key_real_set_bounds; actor_class->paint = eek_clutter_key_real_paint;
gobject_class->dispose = eek_clutter_key_dispose; actor_class->get_preferred_width =
eek_clutter_key_real_get_preferred_width;
actor_class->get_preferred_height =
eek_clutter_key_real_get_preferred_height;
actor_class->allocate = eek_clutter_key_real_allocate;
/* signals */ /* signals */
key_class->pressed = eek_clutter_key_real_pressed; actor_class->button_press_event =
key_class->released = eek_clutter_key_real_released; eek_clutter_key_real_button_press_event;
actor_class->button_release_event =
eek_clutter_key_real_button_release_event;
actor_class->leave_event =
eek_clutter_key_real_leave_event;
gobject_class->set_property = eek_clutter_key_set_property;
gobject_class->dispose = eek_clutter_key_dispose;
pspec = g_param_spec_object ("key",
"Key",
"Key",
EEK_TYPE_KEY,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
g_object_class_install_property (gobject_class,
PROP_KEY,
pspec);
pspec = g_param_spec_object ("renderer",
"Renderer",
"Renderer",
EEK_TYPE_RENDERER,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
g_object_class_install_property (gobject_class,
PROP_RENDERER,
pspec);
} }
static void static void
@ -122,33 +293,15 @@ eek_clutter_key_init (EekClutterKey *self)
{ {
EekClutterKeyPrivate *priv; EekClutterKeyPrivate *priv;
priv = self->priv = EEK_CLUTTER_KEY_GET_PRIVATE (self); priv = self->priv = EEK_CLUTTER_KEY_GET_PRIVATE (self);
priv->actor = NULL; priv->key = NULL;
priv->renderer = NULL;
} }
ClutterActor * ClutterActor *
eek_clutter_key_get_actor (EekClutterKey *key) eek_clutter_key_new (EekKey *key, EekClutterRenderer *renderer)
{ {
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(key); return g_object_new (EEK_TYPE_CLUTTER_KEY,
"key", key,
if (!priv->actor) { "renderer", renderer,
g_return_val_if_fail (priv->context, NULL); NULL);
priv->actor = eek_clutter_key_actor_new (priv->context, EEK_KEY(key));
g_object_ref_sink (priv->actor);
}
return priv->actor;
}
EekKey *
eek_clutter_key_new (EekClutterDrawingContext *context, gint column, gint row)
{
EekClutterKey *key;
g_return_val_if_fail (context, NULL);
key = g_object_new (EEK_TYPE_CLUTTER_KEY,
"column", column,
"row", row,
NULL);
key->priv->context = context;
g_object_ref_sink (key->priv->context);
return EEK_KEY(key);
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -21,8 +21,8 @@
#define EEK_CLUTTER_KEY_H 1 #define EEK_CLUTTER_KEY_H 1
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include "eek-clutter-drawing-context.h"
#include "eek-key.h" #include "eek-key.h"
#include "eek-clutter-renderer.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define EEK_TYPE_CLUTTER_KEY (eek_clutter_key_get_type()) #define EEK_TYPE_CLUTTER_KEY (eek_clutter_key_get_type())
@ -39,7 +39,7 @@ typedef struct _EekClutterKeyPrivate EekClutterKeyPrivate;
struct _EekClutterKey struct _EekClutterKey
{ {
/*< private >*/ /*< private >*/
EekKey parent; ClutterActor parent;
/*< private >*/ /*< private >*/
EekClutterKeyPrivate *priv; EekClutterKeyPrivate *priv;
@ -48,18 +48,16 @@ struct _EekClutterKey
struct _EekClutterKeyClass struct _EekClutterKeyClass
{ {
/*< private >*/ /*< private >*/
EekKeyClass parent_class; ClutterActorClass parent_class;
/*< private >*/ /*< private >*/
/* padding */ /* padding */
gpointer pdummy[24]; gpointer pdummy[24];
}; };
GType eek_clutter_key_get_type (void) G_GNUC_CONST; GType eek_clutter_key_get_type (void) G_GNUC_CONST;
EekKey * eek_clutter_key_new (EekClutterDrawingContext *context, ClutterActor *eek_clutter_key_new (EekKey *key,
gint column, EekClutterRenderer *renderer);
gint row);
ClutterActor *eek_clutter_key_get_actor (EekClutterKey *key);
G_END_DECLS G_END_DECLS
#endif /* EEK_CLUTTER_KEY_H */ #endif /* EEK_CLUTTER_KEY_H */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -20,107 +20,165 @@
/** /**
* SECTION:eek-clutter-keyboard * SECTION:eek-clutter-keyboard
* @short_description: #EekKeyboard that can be converted into a #ClutterActor * @short_description: a #ClutterActor displaying #EekKeyboard
*/ */
#include <string.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-clutter-keyboard.h" #include <string.h>
#include "eek-clutter-drawing-context.h" #include <gdk-pixbuf/gdk-pixbuf.h>
#include "eek-keyboard.h"
#include "eek-drawing.h"
G_DEFINE_TYPE (EekClutterKeyboard, eek_clutter_keyboard, EEK_TYPE_KEYBOARD); #include "eek-clutter-keyboard.h"
#include "eek-clutter-section.h"
#include "eek-clutter-renderer.h"
#include "eek-keyboard.h"
enum {
PROP_0,
PROP_KEYBOARD,
PROP_LAST
};
G_DEFINE_TYPE (EekClutterKeyboard, eek_clutter_keyboard, CLUTTER_TYPE_GROUP);
#define EEK_CLUTTER_KEYBOARD_GET_PRIVATE(obj) \ #define EEK_CLUTTER_KEYBOARD_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardPrivate))
struct _EekClutterKeyboardPrivate struct _EekClutterKeyboardPrivate
{ {
EekClutterDrawingContext *context; EekKeyboard *keyboard;
ClutterActor *actor; EekClutterRenderer *renderer;
EekTheme *theme;
guint key_press_event_handler;
guint key_release_event_handler;
}; };
static void struct _CreateSectionCallbackData {
eek_clutter_keyboard_real_set_name (EekElement *self,
const gchar *name)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
EEK_ELEMENT_CLASS (eek_clutter_keyboard_parent_class)->
set_name (self, name);
if (priv->actor)
clutter_actor_set_name (priv->actor, name);
}
static void
eek_clutter_keyboard_real_set_bounds (EekElement *self,
EekBounds *bounds)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
EEK_ELEMENT_CLASS (eek_clutter_keyboard_parent_class)->
set_bounds (self, bounds);
if (priv->actor) {
clutter_actor_set_position (priv->actor, bounds->x, bounds->y);
clutter_actor_set_size (priv->actor, bounds->width, bounds->height);
}
}
static void
key_pressed_event (EekSection *section,
EekKey *key,
EekKeyboard *keyboard)
{
g_signal_emit_by_name (keyboard, "key-pressed", key);
}
static void
key_released_event (EekSection *section,
EekKey *key,
EekKeyboard *keyboard)
{
g_signal_emit_by_name (keyboard, "key-released", key);
}
static EekSection *
eek_clutter_keyboard_real_create_section (EekKeyboard *self)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
EekSection *section;
ClutterActor *actor; ClutterActor *actor;
EekClutterRenderer *renderer;
};
typedef struct _CreateSectionCallbackData CreateSectionCallbackData;
if (!priv->context) { static void
priv->context = eek_clutter_drawing_context_new (); create_section (EekElement *element, gpointer user_data)
g_object_ref_sink (G_OBJECT(priv->context)); {
CreateSectionCallbackData *data = user_data;
ClutterActor *section;
section = eek_clutter_section_new (EEK_SECTION(element), data->renderer);
clutter_container_add_actor (CLUTTER_CONTAINER(data->actor), section);
}
static void
eek_clutter_keyboard_real_realize (ClutterActor *self)
{
EekClutterKeyboardPrivate *priv;
CreateSectionCallbackData data;
EekBounds bounds;
gdouble scale;
priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
if (priv->theme)
eek_renderer_set_theme (EEK_RENDERER(priv->renderer), priv->theme);
scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer));
clutter_actor_set_position (CLUTTER_ACTOR(self),
bounds.x * scale,
bounds.y * scale);
data.actor = CLUTTER_ACTOR(self);
data.renderer = priv->renderer;
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
create_section,
&data);
}
static void
eek_clutter_keyboard_real_get_preferred_width (ClutterActor *self,
float for_height,
float *min_width_p,
float *natural_width_p)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
gdouble width;
eek_renderer_get_size (EEK_RENDERER(priv->renderer), &width, NULL);
*min_width_p = 0.0f;
*natural_width_p = width;
}
static void
eek_clutter_keyboard_real_get_preferred_height (ClutterActor *self,
float for_width,
float *min_height_p,
float *natural_height_p)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
gdouble height;
eek_renderer_get_size (EEK_RENDERER(priv->renderer), NULL, &height);
*min_height_p = 0.0f;
*natural_height_p = height;
}
static void
eek_clutter_keyboard_real_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
eek_renderer_set_allocation_size (EEK_RENDERER(priv->renderer),
box->x2 - box->x1,
box->y2 - box->y1);
CLUTTER_ACTOR_CLASS (eek_clutter_keyboard_parent_class)->
allocate (self, box, flags);
}
static void
create_renderer (EekClutterKeyboard *self)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
PangoContext *pcontext;
PangoFontDescription *font;
EekBounds bounds;
pcontext = clutter_actor_get_pango_context (CLUTTER_ACTOR(self));
font = pango_font_description_from_string ("Sans 48px");
pango_context_set_font_description (pcontext, font);
pango_font_description_free (font);
priv->renderer = eek_clutter_renderer_new (priv->keyboard, pcontext);
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
eek_renderer_set_allocation_size (EEK_RENDERER(priv->renderer),
bounds.width,
bounds.height);
}
static void
eek_clutter_keyboard_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object);
switch (prop_id) {
case PROP_KEYBOARD:
priv->keyboard = g_value_get_object (value);
g_object_ref (priv->keyboard);
create_renderer (EEK_CLUTTER_KEYBOARD(object));
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
} }
section = eek_clutter_section_new (priv->context);
g_return_val_if_fail (section, NULL);
g_signal_connect (section, "key-pressed",
G_CALLBACK(key_pressed_event), self);
g_signal_connect (section, "key-released",
G_CALLBACK(key_released_event), self);
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
EEK_ELEMENT(section));
actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(self));
clutter_container_add_actor
(CLUTTER_CONTAINER(actor),
eek_clutter_section_get_actor (EEK_CLUTTER_SECTION(section)));
return section;
} }
static void static void
@ -128,40 +186,53 @@ eek_clutter_keyboard_dispose (GObject *object)
{ {
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object); EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object);
if (priv->context) { if (priv->renderer) {
g_object_unref (G_OBJECT(priv->context)); g_object_unref (G_OBJECT(priv->renderer));
priv->context = NULL; priv->renderer = NULL;
} }
if (priv->actor) {
ClutterActor *stage;
stage = clutter_actor_get_stage (priv->actor); if (priv->keyboard) {
if (stage) { g_object_unref (priv->keyboard);
g_signal_handler_disconnect (stage, priv->keyboard = NULL;
priv->key_press_event_handler);
g_signal_handler_disconnect (stage,
priv->key_release_event_handler);
}
g_object_unref (priv->actor);
priv->actor = NULL;
} }
if (priv->theme) {
g_object_unref (priv->theme);
priv->keyboard = NULL;
}
G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->dispose (object); G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->dispose (object);
} }
static void static void
eek_clutter_keyboard_class_init (EekClutterKeyboardClass *klass) eek_clutter_keyboard_class_init (EekClutterKeyboardClass *klass)
{ {
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
EekElementClass *element_class = EEK_ELEMENT_CLASS (klass); GParamSpec *pspec;
EekKeyboardClass *keyboard_class = EEK_KEYBOARD_CLASS (klass);
g_type_class_add_private (gobject_class, g_type_class_add_private (gobject_class,
sizeof (EekClutterKeyboardPrivate)); sizeof (EekClutterKeyboardPrivate));
keyboard_class->create_section = eek_clutter_keyboard_real_create_section; actor_class->realize =
element_class->set_name = eek_clutter_keyboard_real_set_name; eek_clutter_keyboard_real_realize;
element_class->set_bounds = eek_clutter_keyboard_real_set_bounds; actor_class->get_preferred_width =
eek_clutter_keyboard_real_get_preferred_width;
actor_class->get_preferred_height =
eek_clutter_keyboard_real_get_preferred_height;
actor_class->allocate = eek_clutter_keyboard_real_allocate;
gobject_class->set_property = eek_clutter_keyboard_set_property;
gobject_class->dispose = eek_clutter_keyboard_dispose; gobject_class->dispose = eek_clutter_keyboard_dispose;
pspec = g_param_spec_object ("keyboard",
"Keyboard",
"Keyboard",
EEK_TYPE_KEYBOARD,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
g_object_class_install_property (gobject_class,
PROP_KEYBOARD,
pspec);
} }
static void static void
@ -170,147 +241,32 @@ eek_clutter_keyboard_init (EekClutterKeyboard *self)
EekClutterKeyboardPrivate *priv; EekClutterKeyboardPrivate *priv;
priv = self->priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); priv = self->priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
priv->actor = NULL; priv->keyboard = NULL;
priv->renderer = NULL;
} }
/** /**
* eek_clutter_keyboard_new: * eek_clutter_keyboard_new:
* @keyboard: an #EekKeyboard
* *
* Create a new #EekClutterKeyboard. * Create a new #ClutterActor displaying @keyboard.
* Returns: a #ClutterActor
*/ */
EekKeyboard*
eek_clutter_keyboard_new (void)
{
return g_object_new (EEK_TYPE_CLUTTER_KEYBOARD, NULL);
}
static gboolean
on_clutter_key_press_event (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
guint keycode;
EekKey *key;
keycode = clutter_event_get_key_code (event);
key = eek_keyboard_find_key_by_keycode (user_data, keycode);
if (key) {
g_signal_emit_by_name (key, "pressed", NULL);
return TRUE;
}
return FALSE;
}
static gboolean
on_clutter_key_release_event (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
guint keycode;
EekKey *key;
keycode = clutter_event_get_key_code (event);
key = eek_keyboard_find_key_by_keycode (user_data, keycode);
if (key) {
g_signal_emit_by_name (key, "released", NULL);
return TRUE;
}
return FALSE;
}
static void
on_clutter_stage_resize (GObject *object,
GParamSpec *param_spec,
gpointer user_data)
{
ClutterActor *stage = CLUTTER_ACTOR(object);
EekClutterKeyboard *keyboard = user_data;
GValue value = {0};
gfloat width, height, scale;
EekBounds bounds;
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
g_object_get (G_OBJECT(stage), "width", &width, NULL);
g_object_get (G_OBJECT(stage), "height", &height, NULL);
g_value_init (&value, G_TYPE_DOUBLE);
scale = width > height ? width / bounds.width : height / bounds.height;
g_value_set_double (&value, scale);
g_object_set_property (G_OBJECT (stage),
"scale-x",
&value);
g_value_set_double (&value, scale);
g_object_set_property (G_OBJECT (stage),
"scale-y",
&value);
}
static void
on_clutter_realize (ClutterActor *actor,
gpointer user_data)
{
EekClutterKeyboard *keyboard = user_data;
EekClutterKeyboardPrivate *priv =
EEK_CLUTTER_KEYBOARD_GET_PRIVATE(keyboard);
ClutterActor *stage;
stage = clutter_actor_get_stage (priv->actor);
priv->key_press_event_handler =
g_signal_connect (stage, "key-press-event",
G_CALLBACK (on_clutter_key_press_event), keyboard);
priv->key_release_event_handler =
g_signal_connect (stage, "key-release-event",
G_CALLBACK (on_clutter_key_release_event), keyboard);
g_signal_connect (stage, "notify::width",
G_CALLBACK (on_clutter_stage_resize), keyboard);
g_signal_connect (stage, "notify::height",
G_CALLBACK (on_clutter_stage_resize), keyboard);
}
static void
update_category_fonts (EekClutterKeyboard *keyboard)
{
EekClutterKeyboardPrivate *priv =
EEK_CLUTTER_KEYBOARD_GET_PRIVATE(keyboard);
PangoContext *context;
PangoLayout *layout;
PangoFontDescription *fonts[EEK_KEYSYM_CATEGORY_LAST], *base_font;
gint i;
context = clutter_actor_get_pango_context (priv->actor);
layout = pango_layout_new (context);
base_font = pango_font_description_from_string ("Sans");
pango_layout_set_font_description (layout, base_font);
pango_font_description_free (base_font);
eek_get_fonts (EEK_KEYBOARD(keyboard),
layout,
(PangoFontDescription **)&fonts);
for (i = 0; i < EEK_KEYSYM_CATEGORY_LAST; i++) {
eek_clutter_drawing_context_set_category_font (priv->context,
i,
fonts[i]);
pango_font_description_free (fonts[i]);
}
g_object_unref (G_OBJECT(layout));
}
ClutterActor * ClutterActor *
eek_clutter_keyboard_get_actor (EekClutterKeyboard *keyboard) eek_clutter_keyboard_new (EekKeyboard *keyboard)
{ {
EekClutterKeyboardPrivate *priv = return g_object_new (EEK_TYPE_CLUTTER_KEYBOARD, "keyboard", keyboard, NULL);
EEK_CLUTTER_KEYBOARD_GET_PRIVATE(keyboard); }
if (!priv->actor) {
priv->actor = clutter_group_new (); void
g_object_ref_sink (priv->actor); eek_clutter_keyboard_set_theme (EekClutterKeyboard *keyboard,
g_signal_connect (priv->actor, "realize", EekTheme *theme)
G_CALLBACK (on_clutter_realize), keyboard); {
g_return_val_if_fail (priv->actor, NULL); EekClutterKeyboardPrivate *priv;
eek_keyboard_realize (EEK_KEYBOARD(keyboard)); g_return_if_fail (EEK_IS_CLUTTER_KEYBOARD(keyboard));
update_category_fonts (keyboard); g_return_if_fail (EEK_IS_THEME(theme));
}
return priv->actor; priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(keyboard);
priv->theme = g_object_ref (theme);
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -20,7 +20,7 @@
#ifndef EEK_CLUTTER_KEYBOARD_H #ifndef EEK_CLUTTER_KEYBOARD_H
#define EEK_CLUTTER_KEYBOARD_H 1 #define EEK_CLUTTER_KEYBOARD_H 1
#include "eek-clutter-section.h" #include <clutter/clutter.h>
#include "eek-keyboard.h" #include "eek-keyboard.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -38,7 +38,7 @@ typedef struct _EekClutterKeyboardPrivate EekClutterKeyboardPrivate;
struct _EekClutterKeyboard struct _EekClutterKeyboard
{ {
/*< private >*/ /*< private >*/
EekKeyboard parent; ClutterGroup parent;
EekClutterKeyboardPrivate *priv; EekClutterKeyboardPrivate *priv;
}; };
@ -46,7 +46,7 @@ struct _EekClutterKeyboard
struct _EekClutterKeyboardClass struct _EekClutterKeyboardClass
{ {
/*< private >*/ /*< private >*/
EekKeyboardClass parent_class; ClutterGroupClass parent_class;
/*< private >*/ /*< private >*/
/* padding */ /* padding */
@ -54,8 +54,9 @@ struct _EekClutterKeyboardClass
}; };
GType eek_clutter_keyboard_get_type (void) G_GNUC_CONST; GType eek_clutter_keyboard_get_type (void) G_GNUC_CONST;
EekKeyboard *eek_clutter_keyboard_new (void); ClutterActor *eek_clutter_keyboard_new (EekKeyboard *keyboard);
ClutterActor *eek_clutter_keyboard_get_actor (EekClutterKeyboard *keyboard); void eek_clutter_keyboard_set_theme (EekClutterKeyboard *keyboard,
EekTheme *theme);
G_END_DECLS G_END_DECLS
#endif /* EEK_CLUTTER_KEYBOARD_H */ #endif /* EEK_CLUTTER_KEYBOARD_H */

235
eek/eek-clutter-renderer.c Normal file
View File

@ -0,0 +1,235 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <string.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <cogl/cogl.h>
#include <cogl/cogl-pango.h>
#include <clutter/clutter.h>
#include "eek-clutter-renderer.h"
#include "eek-key.h"
G_DEFINE_TYPE (EekClutterRenderer, eek_clutter_renderer, EEK_TYPE_RENDERER);
#define EEK_CLUTTER_RENDERER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_RENDERER, EekClutterRendererPrivate))
struct _EekClutterRendererPrivate
{
GHashTable *outline_texture_cache;
};
/* This routine is copied from librsvg:
Copyright © 2005 Dom Lachowicz <cinamod@hotmail.com>
Copyright © 2005 Caleb Moore <c.moore@student.unsw.edu.au>
Copyright © 2005 Red Hat, Inc.
*/
static void
cairo_pixels_to_pixbuf (guint8 *pixels,
int rowstride,
int height)
{
int row;
/* un-premultiply data */
for (row = 0; row < height; row++) {
guint8 *row_data = (pixels + (row * rowstride));
int i;
for (i = 0; i < rowstride; i += 4) {
guint8 *b = &row_data[i];
guint32 pixel;
guint8 alpha;
memcpy (&pixel, b, sizeof (guint32));
alpha = (pixel & 0xff000000) >> 24;
if (alpha == 0) {
b[0] = b[1] = b[2] = b[3] = 0;
} else {
b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
b[2] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
b[3] = alpha;
}
}
}
}
static void
eek_clutter_renderer_finalize (GObject *object)
{
EekClutterRendererPrivate *priv = EEK_CLUTTER_RENDERER_GET_PRIVATE(object);
g_hash_table_destroy (priv->outline_texture_cache);
G_OBJECT_CLASS (eek_clutter_renderer_parent_class)->finalize (object);
}
static void
eek_clutter_renderer_class_init (EekClutterRendererClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (gobject_class,
sizeof (EekClutterRendererPrivate));
gobject_class->finalize = eek_clutter_renderer_finalize;
}
static void
eek_clutter_renderer_init (EekClutterRenderer *self)
{
EekClutterRendererPrivate *priv;
priv = self->priv = EEK_CLUTTER_RENDERER_GET_PRIVATE(self);
priv->outline_texture_cache =
g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
cogl_handle_unref);
}
void
eek_clutter_renderer_render_key (EekClutterRenderer *renderer,
ClutterActor *actor,
EekKey *key)
{
EekClutterRendererPrivate *priv;
EekOutline *outline;
CoglHandle *outline_texture;
PangoLayout *layout;
PangoRectangle extents = { 0, };
EekColor foreground;
CoglColor color;
ClutterGeometry geom;
gulong oref;
EekKeyboard *keyboard;
g_assert (EEK_IS_CLUTTER_RENDERER(renderer));
g_assert (CLUTTER_IS_ACTOR(actor));
g_assert (EEK_IS_KEY(key));
oref = eek_key_get_oref (key);
g_object_get (renderer, "keyboard", &keyboard, NULL);
outline = eek_keyboard_get_outline (keyboard, oref);
g_object_unref (keyboard);
priv = EEK_CLUTTER_RENDERER_GET_PRIVATE(renderer);
outline_texture = g_hash_table_lookup (priv->outline_texture_cache,
outline);
if (!outline_texture) {
gint rowstride;
guint8 *data;
cairo_surface_t *surface;
cairo_t *cr;
EekBounds bounds;
gdouble scale;
GdkPixbuf *pixbuf;
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
scale = eek_renderer_get_scale (EEK_RENDERER(renderer));
rowstride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
bounds.width * scale);
data = g_malloc0 (rowstride * bounds.height);
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
bounds.width * scale,
bounds.height * scale,
rowstride);
cr = cairo_create (surface);
eek_renderer_render_key_outline (EEK_RENDERER(renderer),
cr,
key,
1.0,
FALSE);
cairo_destroy (cr);
cairo_surface_destroy (surface);
cairo_pixels_to_pixbuf (data, rowstride, bounds.height * scale);
pixbuf = gdk_pixbuf_new_from_data (data,
GDK_COLORSPACE_RGB,
TRUE,
8,
bounds.width * scale,
bounds.height * scale,
rowstride,
(GdkPixbufDestroyNotify) g_free,
data);
outline_texture =
cogl_texture_new_from_data (gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf),
COGL_TEXTURE_NONE,
gdk_pixbuf_get_has_alpha (pixbuf)
? COGL_PIXEL_FORMAT_RGBA_8888
: COGL_PIXEL_FORMAT_RGB_888,
COGL_PIXEL_FORMAT_ANY,
gdk_pixbuf_get_rowstride (pixbuf),
gdk_pixbuf_get_pixels (pixbuf));
g_object_unref (pixbuf);
g_hash_table_insert (priv->outline_texture_cache,
outline,
outline_texture);
}
clutter_actor_get_allocation_geometry (actor, &geom);
cogl_set_source_texture (outline_texture);
cogl_rectangle (0.0f, 0.0f, geom.width, geom.height);
layout = eek_renderer_create_pango_layout (EEK_RENDERER(renderer));
eek_renderer_render_key_label (EEK_RENDERER(renderer), layout, key);
pango_layout_get_extents (layout, NULL, &extents);
eek_renderer_get_foreground_color (EEK_RENDERER(renderer),
EEK_ELEMENT(key),
&foreground);
cogl_color_set_from_4f (&color,
foreground.red,
foreground.green,
foreground.blue,
foreground.alpha);
cogl_pango_render_layout (layout,
(geom.width - extents.width / PANGO_SCALE) / 2,
(geom.height - extents.height / PANGO_SCALE) / 2,
&color,
0);
g_object_unref (layout);
}
EekClutterRenderer *
eek_clutter_renderer_new (EekKeyboard *keyboard,
PangoContext *pcontext)
{
EekClutterRenderer *renderer;
renderer = g_object_new (EEK_TYPE_CLUTTER_RENDERER,
"keyboard", keyboard,
"pango-context", pcontext,
NULL);
return renderer;
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef EEK_CLUTTER_RENDERER_H
#define EEK_CLUTTER_RENDERER_H 1
#include "eek-renderer.h"
G_BEGIN_DECLS
#define EEK_TYPE_CLUTTER_RENDERER (eek_clutter_renderer_get_type())
#define EEK_CLUTTER_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_RENDERER, EekClutterRenderer))
#define EEK_CLUTTER_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_RENDERER, EekClutterRendererClass))
#define EEK_IS_CLUTTER_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_RENDERER))
#define EEK_IS_CLUTTER_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_RENDERER))
#define EEK_CLUTTER_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_RENDERER, EekClutterRendererClass))
typedef struct _EekClutterRenderer EekClutterRenderer;
typedef struct _EekClutterRendererClass EekClutterRendererClass;
typedef struct _EekClutterRendererPrivate EekClutterRendererPrivate;
struct _EekClutterRenderer {
EekRenderer parent;
EekClutterRendererPrivate *priv;
};
struct _EekClutterRendererClass
{
EekRendererClass parent_class;
/*< private >*/
/* padding */
gpointer pdummy[24];
};
GType eek_clutter_renderer_get_type
(void) G_GNUC_CONST;
EekClutterRenderer *eek_clutter_renderer_new (EekKeyboard *keyboard,
PangoContext *pcontext);
void eek_clutter_renderer_render_key
(EekClutterRenderer *renderer,
ClutterActor *actor,
EekKey *key);
G_END_DECLS
#endif /* EEK_CLUTTER_RENDERER_H */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -23,106 +23,135 @@
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-clutter-section.h" #include "eek-clutter-section.h"
#include "eek-clutter-key.h"
G_DEFINE_TYPE (EekClutterSection, eek_clutter_section, EEK_TYPE_SECTION); enum {
PROP_0,
PROP_SECTION,
PROP_RENDERER,
PROP_LAST
};
G_DEFINE_TYPE (EekClutterSection, eek_clutter_section, CLUTTER_TYPE_GROUP);
#define EEK_CLUTTER_SECTION_GET_PRIVATE(obj) \ #define EEK_CLUTTER_SECTION_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_SECTION, EekClutterSectionPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_SECTION, EekClutterSectionPrivate))
struct _EekClutterSectionPrivate struct _EekClutterSectionPrivate
{ {
EekClutterDrawingContext *context; EekSection *section;
ClutterActor *actor; EekClutterRenderer *renderer;
}; };
static void struct _CreateKeyCallbackData {
eek_clutter_section_real_set_name (EekElement *self,
const gchar *name)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
EEK_ELEMENT_CLASS (eek_clutter_section_parent_class)->
set_name (self, name);
if (priv->actor)
clutter_actor_set_name (priv->actor, name);
}
static void
eek_clutter_section_real_set_bounds (EekElement *self,
EekBounds *bounds)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
EEK_ELEMENT_CLASS (eek_clutter_section_parent_class)->
set_bounds (self, bounds);
if (priv->actor) {
clutter_actor_set_position (priv->actor, bounds->x, bounds->y);
clutter_actor_set_size (priv->actor, bounds->width, bounds->height);
}
}
static void
eek_clutter_section_real_set_angle (EekSection *self,
gint angle)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
EEK_SECTION_CLASS (eek_clutter_section_parent_class)->
set_angle (self, angle);
g_return_if_fail (priv->actor);
clutter_actor_set_rotation (priv->actor,
CLUTTER_Z_AXIS,
eek_section_get_angle (self),
0, 0, 0);
}
static void
pressed_event (EekKey *key, gpointer user_data)
{
g_signal_emit_by_name (user_data, "key-pressed", key);
}
static void
released_event (EekKey *key, gpointer user_data)
{
g_signal_emit_by_name (user_data, "key-released", key);
}
static EekKey *
eek_clutter_section_real_create_key (EekSection *self,
gint column,
gint row)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
EekKey *key;
gint num_columns, num_rows;
EekOrientation orientation;
ClutterActor *actor; ClutterActor *actor;
EekClutterRenderer *renderer;
};
typedef struct _CreateKeyCallbackData CreateKeyCallbackData;
num_rows = eek_section_get_n_rows (self); static void
g_return_val_if_fail (0 <= row && row < num_rows, NULL); create_key (EekElement *element, gpointer user_data)
eek_section_get_row (self, row, &num_columns, &orientation); {
g_return_val_if_fail (column < num_columns, NULL); CreateKeyCallbackData *data = user_data;
ClutterActor *key;
key = eek_clutter_key_new (priv->context, column, row); key = eek_clutter_key_new (EEK_KEY(element), data->renderer);
g_return_val_if_fail (key, NULL); clutter_container_add_actor (CLUTTER_CONTAINER(data->actor), key);
}
g_signal_connect (key, "pressed", G_CALLBACK(pressed_event), self);
g_signal_connect (key, "released", G_CALLBACK(released_event), self);
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), static void
EEK_ELEMENT(key)); set_position (ClutterActor *self)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
EekBounds bounds;
gdouble scale;
actor = eek_clutter_section_get_actor (EEK_CLUTTER_SECTION(self)); eek_element_get_bounds (EEK_ELEMENT(priv->section), &bounds);
clutter_container_add_actor scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer));
(CLUTTER_CONTAINER(actor), clutter_actor_set_position (self, bounds.x * scale, bounds.y * scale);
eek_clutter_key_get_actor (EEK_CLUTTER_KEY(key))); }
return key; static void
eek_clutter_section_real_realize (ClutterActor *self)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
CreateKeyCallbackData data;
clutter_actor_set_rotation (self,
CLUTTER_Z_AXIS,
eek_section_get_angle (priv->section),
0.0f, 0.0f, 0.0f);
set_position (self);
data.actor = self;
data.renderer = priv->renderer;
eek_container_foreach_child (EEK_CONTAINER(priv->section),
create_key,
&data);
}
static void
eek_clutter_section_real_paint (ClutterActor *self)
{
set_position (self);
CLUTTER_ACTOR_CLASS (eek_clutter_section_parent_class)->
paint (self);
}
static void
eek_clutter_section_real_get_preferred_width (ClutterActor *self,
float for_height,
float *min_width_p,
float *natural_width_p)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
EekBounds bounds;
gdouble scale;
scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer));
eek_element_get_bounds (EEK_ELEMENT(priv->section), &bounds);
*min_width_p = 0.0f;
*natural_width_p = bounds.width * scale;
}
static void
eek_clutter_section_real_get_preferred_height (ClutterActor *self,
float for_width,
float *min_height_p,
float *natural_height_p)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
EekBounds bounds;
gdouble scale;
scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer));
eek_element_get_bounds (EEK_ELEMENT(priv->section), &bounds);
*min_height_p = 0.0f;
*natural_height_p = bounds.height * scale;
}
static void
eek_clutter_section_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object);
switch (prop_id) {
case PROP_SECTION:
priv->section = g_value_get_object (value);
g_object_ref (priv->section);
break;
case PROP_RENDERER:
priv->renderer = g_value_get_object (value);
g_object_ref (priv->renderer);
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
} }
static void static void
@ -130,31 +159,57 @@ eek_clutter_section_dispose (GObject *object)
{ {
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object); EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object);
if (priv->context) { if (priv->renderer) {
g_object_unref (priv->context); g_object_unref (priv->renderer);
priv->context = NULL; priv->renderer = NULL;
} }
if (priv->actor) {
g_object_unref (priv->actor); if (priv->section) {
priv->actor = NULL; g_object_unref (priv->section);
priv->section = NULL;
} }
G_OBJECT_CLASS (eek_clutter_section_parent_class)->dispose (object); G_OBJECT_CLASS (eek_clutter_section_parent_class)->dispose (object);
} }
static void static void
eek_clutter_section_class_init (EekClutterSectionClass *klass) eek_clutter_section_class_init (EekClutterSectionClass *klass)
{ {
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
EekElementClass *element_class = EEK_ELEMENT_CLASS (klass); GParamSpec *pspec;
EekSectionClass *section_class = EEK_SECTION_CLASS (klass);
g_type_class_add_private (gobject_class, sizeof (EekClutterSectionPrivate)); g_type_class_add_private (gobject_class, sizeof (EekClutterSectionPrivate));
section_class->set_angle = eek_clutter_section_real_set_angle; actor_class->realize =
section_class->create_key = eek_clutter_section_real_create_key; eek_clutter_section_real_realize;
element_class->set_name = eek_clutter_section_real_set_name; actor_class->paint =
element_class->set_bounds = eek_clutter_section_real_set_bounds; eek_clutter_section_real_paint;
actor_class->get_preferred_width =
eek_clutter_section_real_get_preferred_width;
actor_class->get_preferred_height =
eek_clutter_section_real_get_preferred_height;
gobject_class->set_property = eek_clutter_section_set_property;
gobject_class->dispose = eek_clutter_section_dispose; gobject_class->dispose = eek_clutter_section_dispose;
pspec = g_param_spec_object ("section",
"Section",
"Section",
EEK_TYPE_SECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
g_object_class_install_property (gobject_class,
PROP_SECTION,
pspec);
pspec = g_param_spec_object ("renderer",
"Renderer",
"Renderer",
EEK_TYPE_RENDERER,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
g_object_class_install_property (gobject_class,
PROP_RENDERER,
pspec);
} }
static void static void
@ -162,29 +217,16 @@ eek_clutter_section_init (EekClutterSection *self)
{ {
EekClutterSectionPrivate *priv; EekClutterSectionPrivate *priv;
priv = self->priv = EEK_CLUTTER_SECTION_GET_PRIVATE (self); priv = self->priv = EEK_CLUTTER_SECTION_GET_PRIVATE (self);
priv->actor = NULL; priv->section = NULL;
priv->renderer = NULL;
} }
ClutterActor * ClutterActor *
eek_clutter_section_get_actor (EekClutterSection *section) eek_clutter_section_new (EekSection *section,
EekClutterRenderer *renderer)
{ {
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(section); return g_object_new (EEK_TYPE_CLUTTER_SECTION,
if (!priv->actor) { "section", section,
priv->actor = clutter_group_new (); "renderer", renderer,
g_object_ref_sink (priv->actor); NULL);
}
return priv->actor;
}
EekSection *
eek_clutter_section_new (EekClutterDrawingContext *context)
{
EekClutterSection *section;
g_return_val_if_fail (context, NULL);
section = g_object_new (EEK_TYPE_CLUTTER_SECTION, NULL);
section->priv->context = context;
g_object_ref_sink (G_OBJECT(section->priv->context));
return EEK_SECTION(section);
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -20,9 +20,9 @@
#ifndef EEK_CLUTTER_SECTION_H #ifndef EEK_CLUTTER_SECTION_H
#define EEK_CLUTTER_SECTION_H 1 #define EEK_CLUTTER_SECTION_H 1
#include "eek-clutter-drawing-context.h" #include <clutter/clutter.h>
#include "eek-clutter-key.h"
#include "eek-section.h" #include "eek-section.h"
#include "eek-clutter-renderer.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define EEK_TYPE_CLUTTER_SECTION (eek_clutter_section_get_type()) #define EEK_TYPE_CLUTTER_SECTION (eek_clutter_section_get_type())
@ -39,7 +39,7 @@ typedef struct _EekClutterSectionPrivate EekClutterSectionPrivate;
struct _EekClutterSection struct _EekClutterSection
{ {
/*< private >*/ /*< private >*/
EekSection parent; ClutterGroup parent;
EekClutterSectionPrivate *priv; EekClutterSectionPrivate *priv;
}; };
@ -47,16 +47,16 @@ struct _EekClutterSection
struct _EekClutterSectionClass struct _EekClutterSectionClass
{ {
/*< private >*/ /*< private >*/
EekSectionClass parent_class; ClutterGroupClass parent_class;
/*< private >*/ /*< private >*/
/* padding */ /* padding */
gpointer pdummy[24]; gpointer pdummy[24];
}; };
GType eek_clutter_section_get_type (void) G_GNUC_CONST; GType eek_clutter_section_get_type (void) G_GNUC_CONST;
EekSection * eek_clutter_section_new (EekClutterDrawingContext *context); ClutterActor *eek_clutter_section_new (EekSection *section,
ClutterActor *eek_clutter_section_get_actor (EekClutterSection *section); EekClutterRenderer *renderer);
G_END_DECLS G_END_DECLS
#endif /* EEK_CLUTTER_SECTION_H */ #endif /* EEK_CLUTTER_SECTION_H */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -31,6 +31,7 @@
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-container.h" #include "eek-container.h"
#include "eek-serializable.h"
enum { enum {
CHILD_ADDED, CHILD_ADDED,
@ -40,7 +41,11 @@ enum {
static guint signals[LAST_SIGNAL] = { 0, }; static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_ABSTRACT_TYPE (EekContainer, eek_container, EEK_TYPE_ELEMENT); static void eek_serializable_iface_init (EekSerializableIface *iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (EekContainer, eek_container, EEK_TYPE_ELEMENT,
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
eek_serializable_iface_init));
#define EEK_CONTAINER_GET_PRIVATE(obj) \ #define EEK_CONTAINER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CONTAINER, EekContainerPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CONTAINER, EekContainerPrivate))
@ -51,6 +56,60 @@ struct _EekContainerPrivate
GSList *children; GSList *children;
}; };
static EekSerializableIface *eek_container_parent_serializable_iface;
static void
eek_container_real_serialize (EekSerializable *self,
GVariantBuilder *builder)
{
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
GSList *head;
GVariantBuilder array;
eek_container_parent_serializable_iface->serialize (self, builder);
g_variant_builder_init (&array, G_VARIANT_TYPE("av"));
for (head = priv->children; head; head = g_slist_next (head)) {
GVariant *variant =
eek_serializable_serialize (EEK_SERIALIZABLE(head->data));
g_variant_builder_add (&array, "v", variant);
}
g_variant_builder_add (builder, "v", g_variant_builder_end (&array));
}
static gsize
eek_container_real_deserialize (EekSerializable *self,
GVariant *variant,
gsize index)
{
GVariant *array, *child;
GVariantIter iter;
index = eek_container_parent_serializable_iface->deserialize (self,
variant,
index);
g_variant_get_child (variant, index++, "v", &array);
g_variant_iter_init (&iter, array);
while (g_variant_iter_next (&iter, "v", &child)) {
EekSerializable *serializable = eek_serializable_deserialize (child);
eek_container_add_child (EEK_CONTAINER(self),
EEK_ELEMENT(serializable));
}
return index;
}
static void
eek_serializable_iface_init (EekSerializableIface *iface)
{
eek_container_parent_serializable_iface =
g_type_interface_peek_parent (iface);
iface->serialize = eek_container_real_serialize;
iface->deserialize = eek_container_real_deserialize;
}
static void static void
eek_container_real_add_child (EekContainer *self, eek_container_real_add_child (EekContainer *self,
EekElement *child) EekElement *child)
@ -58,10 +117,11 @@ eek_container_real_add_child (EekContainer *self,
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self); EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
g_return_if_fail (EEK_IS_ELEMENT(child)); g_return_if_fail (EEK_IS_ELEMENT(child));
g_object_ref_sink (child); g_object_ref (child);
priv->children = g_slist_prepend (priv->children, child); priv->children = g_slist_prepend (priv->children, child);
eek_element_set_parent (child, EEK_ELEMENT(self)); eek_element_set_parent (child, EEK_ELEMENT(self));
g_signal_emit_by_name (self, "child-added", child);
} }
static void static void
@ -77,6 +137,7 @@ eek_container_real_remove_child (EekContainer *self,
g_object_unref (child); g_object_unref (child);
priv->children = g_slist_remove_link (priv->children, head); priv->children = g_slist_remove_link (priv->children, head);
eek_element_set_parent (child, NULL); eek_element_set_parent (child, NULL);
g_signal_emit_by_name (self, "child-removed", child);
} }
static void static void
@ -111,24 +172,14 @@ eek_container_dispose (GObject *object)
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(object); EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(object);
GSList *head; GSList *head;
for (head = priv->children; head; head = g_slist_next (head)) { for (head = priv->children; head; head = priv->children) {
if (head->data) { g_object_unref (head->data);
g_object_unref (head->data); priv->children = g_slist_next (head);
head->data = NULL; g_slist_free1 (head);
}
} }
G_OBJECT_CLASS(eek_container_parent_class)->dispose (object); G_OBJECT_CLASS(eek_container_parent_class)->dispose (object);
} }
static void
eek_container_finalize (GObject *object)
{
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(object);
g_slist_free (priv->children);
G_OBJECT_CLASS(eek_container_parent_class)->finalize (object);
}
static void static void
eek_container_class_init (EekContainerClass *klass) eek_container_class_init (EekContainerClass *klass)
{ {
@ -142,7 +193,10 @@ eek_container_class_init (EekContainerClass *klass)
klass->foreach_child = eek_container_real_foreach_child; klass->foreach_child = eek_container_real_foreach_child;
klass->find = eek_container_real_find; klass->find = eek_container_real_find;
gobject_class->finalize = eek_container_finalize; /* signals */
klass->child_added = NULL;
klass->child_removed = NULL;
gobject_class->dispose = eek_container_dispose; gobject_class->dispose = eek_container_dispose;
/** /**
@ -154,7 +208,7 @@ eek_container_class_init (EekContainerClass *klass)
* added to @container. * added to @container.
*/ */
signals[CHILD_ADDED] = signals[CHILD_ADDED] =
g_signal_new ("child-added", g_signal_new (I_("child-added"),
G_TYPE_FROM_CLASS(gobject_class), G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekContainerClass, child_added), G_STRUCT_OFFSET(EekContainerClass, child_added),
@ -172,7 +226,7 @@ eek_container_class_init (EekContainerClass *klass)
* removed from @container. * removed from @container.
*/ */
signals[CHILD_REMOVED] = signals[CHILD_REMOVED] =
g_signal_new ("child-removed", g_signal_new (I_("child-removed"),
G_TYPE_FROM_CLASS(gobject_class), G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekContainerClass, child_removed), G_STRUCT_OFFSET(EekContainerClass, child_removed),
@ -231,40 +285,10 @@ eek_container_find (EekContainer *container,
user_data); user_data);
} }
struct _FbpData void
eek_container_add_child (EekContainer *container, EekElement *element)
{ {
EekKey *key; g_return_if_fail (EEK_IS_CONTAINER(container));
gint x, y; g_return_if_fail (EEK_IS_ELEMENT(element));
}; return EEK_CONTAINER_GET_CLASS(container)->add_child (container, element);
typedef struct _FbpData FbpData;
static gint
compare_element_by_position (EekElement *element, gpointer user_data)
{
EekBounds bounds;
FbpData *data = user_data;
eek_element_get_bounds (element, &bounds);
if (bounds.x <= data->x && bounds.y <= data->y &&
data->x <= (bounds.x + bounds.width) &&
data->y <= (bounds.y + bounds.height))
return 0;
return -1;
}
EekElement *
eek_container_find_by_position (EekContainer *container,
gdouble x,
gdouble y)
{
EekBounds bounds;
FbpData data;
g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
eek_element_get_bounds (EEK_ELEMENT(container), &bounds);
data.x = x - bounds.x;
data.y = y - bounds.y;
return eek_container_find (container,
compare_element_by_position,
&data);
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -57,42 +57,40 @@ struct _EekContainerClass
/*< private >*/ /*< private >*/
EekElementClass parent_class; EekElementClass parent_class;
void (* add_child) (EekContainer *self, void (* add_child) (EekContainer *self,
EekElement *element); EekElement *element);
void (* remove_child) (EekContainer *self, void (* remove_child) (EekContainer *self,
EekElement *element); EekElement *element);
/*< public >*/ /*< public >*/
void (* foreach_child) (EekContainer *self, void (* foreach_child) (EekContainer *self,
EekCallback callback, EekCallback callback,
gpointer user_data); gpointer user_data);
EekElement *(* find) (EekContainer *self, EekElement *(* find) (EekContainer *self,
EekCompareFunc func, EekCompareFunc func,
gpointer user_data); gpointer data);
/* signals */ /* signals */
void (* child_added) (EekContainer *self, void (* child_added) (EekContainer *self,
EekElement *element); EekElement *element);
void (* child_removed) (EekContainer *self, void (* child_removed) (EekContainer *self,
EekElement *element); EekElement *element);
/*< private >*/ /*< private >*/
/* padding */ /* padding */
gpointer pdummy[24]; gpointer pdummy[24];
}; };
GType eek_container_get_type (void) G_GNUC_CONST; GType eek_container_get_type (void) G_GNUC_CONST;
void eek_container_foreach_child (EekContainer *container, void eek_container_foreach_child (EekContainer *container,
EekCallback callback, EekCallback callback,
gpointer user_data); gpointer user_data);
EekElement *eek_container_find (EekContainer *container, EekElement *eek_container_find (EekContainer *container,
EekCompareFunc func, EekCompareFunc func,
gpointer user_data); gpointer user_data);
EekElement *eek_container_find_by_position (EekContainer *container, void eek_container_add_child (EekContainer *container,
gdouble x, EekElement *element);
gdouble y);
G_END_DECLS G_END_DECLS
#endif /* EEK_CONTAINER_H */ #endif /* EEK_CONTAINER_H */

View File

@ -1,462 +0,0 @@
/*
* Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <math.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-keyboard.h"
#include "eek-key.h"
#include "eek-drawing.h"
#include "eek-keysym.h"
void
eek_draw_text_on_layout (PangoLayout *layout,
const gchar *text)
{
/* pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); */
pango_layout_set_text (layout, text, -1);
}
struct _GetFontSizeCallbackData
{
PangoLayout *layout;
EekKeysymCategory category;
gint minimum_font_size;
gint font_size;
};
typedef struct _GetFontSizeCallbackData GetFontSizeCallbackData;
static gint
get_font_size (const gchar *text,
EekBounds *bounds,
PangoLayout *layout)
{
gdouble scale_x, scale_y;
const PangoFontDescription *base_font_desc;
PangoFontDescription *font_desc;
PangoRectangle logical_rect = { 0, };
gint font_size;
layout = pango_layout_copy (layout);
base_font_desc = pango_layout_get_font_description (layout);
font_desc = pango_font_description_copy (base_font_desc);
font_size = eek_bounds_long_side (bounds) * PANGO_SCALE;
pango_font_description_set_size (font_desc, font_size);
pango_layout_set_font_description (layout, font_desc);
pango_font_description_free (font_desc);
eek_draw_text_on_layout (layout, text);
pango_layout_get_extents (layout, NULL, &logical_rect);
scale_x = scale_y = 1.0;
if (logical_rect.width > bounds->width * PANGO_SCALE)
scale_x = bounds->width * PANGO_SCALE / logical_rect.width;
if (logical_rect.height > bounds->height * PANGO_SCALE)
scale_y = bounds->height * PANGO_SCALE / logical_rect.height;
g_object_unref (layout);
return font_size * (scale_x < scale_y ? scale_x : scale_y);
}
static void
egf_key_callback (EekElement *element,
gpointer user_data)
{
EekKey *key = EEK_KEY(element);
GetFontSizeCallbackData *data = user_data;
gdouble font_size;
guint keysym;
EekBounds bounds;
const gchar *label;
keysym = eek_key_get_keysym (key);
if (keysym == EEK_INVALID_KEYSYM ||
eek_keysym_get_category (keysym) != data->category)
return;
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
label = eek_keysym_to_string (keysym);
font_size = get_font_size (label, &bounds, data->layout);
if (font_size < data->font_size && font_size >= data->minimum_font_size)
data->font_size = font_size;
}
static void
egf_section_callback (EekElement *element,
gpointer user_data)
{
eek_container_foreach_child (EEK_CONTAINER(element),
egf_key_callback,
user_data);
}
static PangoFontDescription *
get_font_for_category (EekKeyboard *keyboard,
EekKeysymCategory category,
PangoLayout *layout,
gdouble minimum_font_size,
gdouble maximum_font_size)
{
GetFontSizeCallbackData data;
PangoFontDescription *font_desc;
const PangoFontDescription *base_font_desc;
data.layout = layout;
data.category = category;
data.minimum_font_size = minimum_font_size;
data.font_size = maximum_font_size;
eek_container_foreach_child (EEK_CONTAINER(keyboard),
egf_section_callback,
&data);
base_font_desc = pango_layout_get_font_description (layout);
font_desc = pango_font_description_copy (base_font_desc);
pango_font_description_set_size (font_desc, data.font_size);
return font_desc;
}
void
eek_get_fonts (EekKeyboard *keyboard,
PangoLayout *layout,
PangoFontDescription **fonts)
{
EekBounds bounds;
PangoFontDescription *font_desc;
gint font_size;
/* font for EEK_KEYSYM_CATEGORY_LETTER */
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
font_desc = get_font_for_category (keyboard,
EEK_KEYSYM_CATEGORY_LETTER,
layout,
0,
eek_bounds_long_side (&bounds) *
PANGO_SCALE);
font_size = pango_font_description_get_size (font_desc);
fonts[EEK_KEYSYM_CATEGORY_LETTER] = font_desc;
/* font for EEK_KEYSYM_CATEGORY_FUNCTION */
font_desc = get_font_for_category (keyboard,
EEK_KEYSYM_CATEGORY_FUNCTION,
layout,
font_size * 0.3,
font_size);
fonts[EEK_KEYSYM_CATEGORY_FUNCTION] = font_desc;
/* font for EEK_KEYSYM_CATEGORY_KEYNAME */
font_desc = get_font_for_category (keyboard,
EEK_KEYSYM_CATEGORY_KEYNAME,
layout,
font_size * 0.3,
font_size);
fonts[EEK_KEYSYM_CATEGORY_KEYNAME] = font_desc;
}
void
eek_draw_outline (cairo_t *cr, EekOutline *outline)
{
cairo_pattern_t *pat;
cairo_set_line_width (cr, 1);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0);
cairo_pattern_add_color_stop_rgba (pat, 1, 0.5, 0.5, 0.5, 1);
cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
cairo_set_source (cr, pat);
eek_draw_rounded_polygon (cr,
TRUE,
outline->corner_radius,
outline->points,
outline->num_points);
cairo_pattern_destroy (pat);
cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 0.5);
eek_draw_rounded_polygon (cr,
FALSE,
outline->corner_radius,
outline->points,
outline->num_points);
}
void
eek_draw_key_label (cairo_t *cr,
EekKey *key,
PangoFontDescription **fonts)
{
guint keysym;
EekKeysymCategory category;
const gchar *label;
PangoLayout *layout;
PangoRectangle logical_rect = { 0, };
EekBounds bounds;
keysym = eek_key_get_keysym (key);
if (keysym == EEK_INVALID_KEYSYM)
return;
category = eek_keysym_get_category (keysym);
if (category == EEK_KEYSYM_CATEGORY_UNKNOWN)
return;
label = eek_keysym_to_string (keysym);
if (!label)
return;
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
layout = pango_cairo_create_layout (cr);
pango_layout_set_font_description (layout, fonts[category]);
pango_layout_set_width (layout, PANGO_SCALE * bounds.width);
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
pango_layout_set_text (layout, label, -1);
pango_layout_get_extents (layout, NULL, &logical_rect);
cairo_rel_move_to (cr,
(bounds.width - logical_rect.width / PANGO_SCALE) / 2,
(bounds.height - logical_rect.height / PANGO_SCALE) / 2);
pango_cairo_show_layout (cr, layout);
g_object_unref (layout);
}
/*
* The functions below are borrowed from
* libgnomekbd/gkbd-keyboard-drawing.c.
* Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
*
* length(), point_line_distance(), normal_form(), inverse(), multiply(),
* intersect(), rounded_corner(), draw_rounded_polygon()
*/
static gdouble
length (gdouble x, gdouble y)
{
return sqrt (x * x + y * y);
}
static gdouble
point_line_distance (gdouble ax, gdouble ay, gdouble nx, gdouble ny)
{
return ax * nx + ay * ny;
}
static void
normal_form (gdouble ax, gdouble ay,
gdouble bx, gdouble by,
gdouble * nx, gdouble * ny, gdouble * d)
{
gdouble l;
*nx = by - ay;
*ny = ax - bx;
l = length (*nx, *ny);
*nx /= l;
*ny /= l;
*d = point_line_distance (ax, ay, *nx, *ny);
}
static void
inverse (gdouble a, gdouble b, gdouble c, gdouble d,
gdouble * e, gdouble * f, gdouble * g, gdouble * h)
{
gdouble det;
det = a * d - b * c;
*e = d / det;
*f = -b / det;
*g = -c / det;
*h = a / det;
}
static void
multiply (gdouble a, gdouble b, gdouble c, gdouble d,
gdouble e, gdouble f, gdouble * x, gdouble * y)
{
*x = a * e + b * f;
*y = c * e + d * f;
}
static void
intersect (gdouble n1x, gdouble n1y, gdouble d1,
gdouble n2x, gdouble n2y, gdouble d2, gdouble * x, gdouble * y)
{
gdouble e, f, g, h;
inverse (n1x, n1y, n2x, n2y, &e, &f, &g, &h);
multiply (e, f, g, h, d1, d2, x, y);
}
/* draw an angle from the current point to b and then to c,
* with a rounded corner of the given radius.
*/
static void
rounded_corner (cairo_t * cr,
gdouble bx, gdouble by,
gdouble cx, gdouble cy, gdouble radius)
{
gdouble ax, ay;
gdouble n1x, n1y, d1;
gdouble n2x, n2y, d2;
gdouble pd1, pd2;
gdouble ix, iy;
gdouble dist1, dist2;
gdouble nx, ny, d;
gdouble a1x, a1y, c1x, c1y;
gdouble phi1, phi2;
cairo_get_current_point (cr, &ax, &ay);
#ifdef KBDRAW_DEBUG
printf (" current point: (%f, %f), radius %f:\n", ax, ay,
radius);
#endif
/* make sure radius is not too large */
dist1 = length (bx - ax, by - ay);
dist2 = length (cx - bx, cy - by);
radius = MIN (radius, MIN (dist1, dist2));
/* construct normal forms of the lines */
normal_form (ax, ay, bx, by, &n1x, &n1y, &d1);
normal_form (bx, by, cx, cy, &n2x, &n2y, &d2);
/* find which side of the line a,b the point c is on */
if (point_line_distance (cx, cy, n1x, n1y) < d1)
pd1 = d1 - radius;
else
pd1 = d1 + radius;
/* find which side of the line b,c the point a is on */
if (point_line_distance (ax, ay, n2x, n2y) < d2)
pd2 = d2 - radius;
else
pd2 = d2 + radius;
/* intersect the parallels to find the center of the arc */
intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy);
nx = (bx - ax) / dist1;
ny = (by - ay) / dist1;
d = point_line_distance (ix, iy, nx, ny);
/* a1 is the point on the line a-b where the arc starts */
intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y);
nx = (cx - bx) / dist2;
ny = (cy - by) / dist2;
d = point_line_distance (ix, iy, nx, ny);
/* c1 is the point on the line b-c where the arc ends */
intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y);
/* determine the first angle */
if (a1x - ix == 0)
phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
else if (a1x - ix > 0)
phi1 = atan ((a1y - iy) / (a1x - ix));
else
phi1 = M_PI + atan ((a1y - iy) / (a1x - ix));
/* determine the second angle */
if (c1x - ix == 0)
phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
else if (c1x - ix > 0)
phi2 = atan ((c1y - iy) / (c1x - ix));
else
phi2 = M_PI + atan ((c1y - iy) / (c1x - ix));
/* compute the difference between phi2 and phi1 mod 2pi */
d = phi2 - phi1;
while (d < 0)
d += 2 * M_PI;
while (d > 2 * M_PI)
d -= 2 * M_PI;
#ifdef KBDRAW_DEBUG
printf (" line 1 to: (%f, %f):\n", a1x, a1y);
#endif
if (!(isnan (a1x) || isnan (a1y)))
cairo_line_to (cr, a1x, a1y);
/* pick the short arc from phi1 to phi2 */
if (d < M_PI)
cairo_arc (cr, ix, iy, radius, phi1, phi2);
else
cairo_arc_negative (cr, ix, iy, radius, phi1, phi2);
#ifdef KBDRAW_DEBUG
printf (" line 2 to: (%f, %f):\n", cx, cy);
#endif
cairo_line_to (cr, cx, cy);
}
void
eek_draw_rounded_polygon (cairo_t *cr,
gboolean filled,
gdouble radius,
EekPoint *points,
gint num_points)
{
gint i, j;
cairo_move_to (cr,
(gdouble) (points[num_points - 1].x +
points[0].x) / 2,
(gdouble) (points[num_points - 1].y +
points[0].y) / 2);
#ifdef KBDRAW_DEBUG
printf (" rounded polygon of radius %f:\n", radius);
#endif
for (i = 0; i < num_points; i++) {
j = (i + 1) % num_points;
rounded_corner (cr, (gdouble) points[i].x,
(gdouble) points[i].y,
(gdouble) (points[i].x + points[j].x) / 2,
(gdouble) (points[i].y + points[j].y) / 2,
radius);
#ifdef KBDRAW_DEBUG
printf (" corner (%d, %d) -> (%d, %d):\n",
points[i].x, points[i].y, points[j].x,
points[j].y);
#endif
};
cairo_close_path (cr);
if (filled)
cairo_fill (cr);
else
cairo_stroke (cr);
}

View File

@ -1,32 +0,0 @@
#ifndef EEK_DRAWING_H
#define EEK_DRAWING_H 1
#include <pango/pangocairo.h>
#include "eek-keyboard.h"
#include "eek-keysym.h"
#include "eek-types.h"
G_BEGIN_DECLS
void eek_draw_text_on_layout (PangoLayout *layout,
const gchar *text);
void eek_get_fonts (EekKeyboard *keyboard,
PangoLayout *layout,
PangoFontDescription **fonts);
void eek_draw_outline (cairo_t *cr,
EekOutline *outline);
void eek_draw_key_label (cairo_t *cr,
EekKey *key,
PangoFontDescription **fonts);
void eek_draw_rounded_polygon (cairo_t *cr,
gboolean filled,
gdouble radius,
EekPoint *points,
gint num_points);
G_END_DECLS
#endif /* EEK_DRAWING_H */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -26,23 +26,38 @@
* shall be used to implement #EekKeyboard, #EekSection, or #EekKey. * shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
*/ */
#include <string.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <string.h>
#include "eek-element.h" #include "eek-element.h"
#include "eek-container.h" #include "eek-container.h"
#include "eek-marshalers.h"
#include "eek-serializable.h"
enum { enum {
PROP_0, PROP_0,
PROP_NAME, PROP_NAME,
PROP_BOUNDS, PROP_BOUNDS,
PROP_GROUP,
PROP_LEVEL,
PROP_LAST PROP_LAST
}; };
G_DEFINE_ABSTRACT_TYPE (EekElement, eek_element, G_TYPE_INITIALLY_UNOWNED); enum {
SYMBOL_INDEX_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
static void eek_serializable_iface_init (EekSerializableIface *iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (EekElement, eek_element, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
eek_serializable_iface_init));
#define EEK_ELEMENT_GET_PRIVATE(obj) \ #define EEK_ELEMENT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_ELEMENT, EekElementPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_ELEMENT, EekElementPrivate))
@ -53,8 +68,65 @@ struct _EekElementPrivate
gchar *name; gchar *name;
EekBounds bounds; EekBounds bounds;
EekElement *parent; EekElement *parent;
gint group;
gint level;
}; };
static GVariant *
_g_variant_new_bounds (EekBounds *bounds)
{
GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("ad"));
g_variant_builder_add (&builder, "d", bounds->x);
g_variant_builder_add (&builder, "d", bounds->y);
g_variant_builder_add (&builder, "d", bounds->width);
g_variant_builder_add (&builder, "d", bounds->height);
return g_variant_builder_end (&builder);
}
static void
_g_variant_get_bounds (GVariant *variant, EekBounds *bounds)
{
g_variant_get_child (variant, 0, "d", &bounds->x);
g_variant_get_child (variant, 1, "d", &bounds->y);
g_variant_get_child (variant, 2, "d", &bounds->width);
g_variant_get_child (variant, 3, "d", &bounds->height);
}
static void
eek_element_real_serialize (EekSerializable *self,
GVariantBuilder *builder)
{
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
g_variant_builder_add (builder, "s", priv->name == NULL ? "" : priv->name);
g_variant_builder_add (builder, "v", _g_variant_new_bounds (&priv->bounds));
}
static gsize
eek_element_real_deserialize (EekSerializable *self,
GVariant *variant,
gsize index)
{
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
GVariant *bounds;
g_variant_get_child (variant, index++, "s", &priv->name);
g_variant_get_child (variant, index++, "v", &bounds);
_g_variant_get_bounds (bounds, &priv->bounds);
return index;
}
static void
eek_serializable_iface_init (EekSerializableIface *iface)
{
iface->serialize = eek_element_real_serialize;
iface->deserialize = eek_element_real_deserialize;
}
static void static void
eek_element_real_set_parent (EekElement *self, eek_element_real_set_parent (EekElement *self,
EekElement *parent) EekElement *parent)
@ -68,7 +140,7 @@ eek_element_real_set_parent (EekElement *self,
priv->parent = NULL; priv->parent = NULL;
} else { } else {
g_return_if_fail (!priv->parent); g_return_if_fail (!priv->parent);
g_object_ref_sink (self); g_object_ref (self);
priv->parent = parent; priv->parent = parent;
} }
} }
@ -122,12 +194,48 @@ eek_element_real_get_bounds (EekElement *self,
g_object_notify (G_OBJECT(self), "bounds"); g_object_notify (G_OBJECT(self), "bounds");
} }
static void
eek_element_real_set_symbol_index (EekElement *self,
gint group,
gint level)
{
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
if (priv->group != group || priv->level != level) {
priv->group = group;
priv->level = level;
g_signal_emit_by_name (self, "symbol-index-changed", group, level);
}
}
static void
eek_element_real_get_symbol_index (EekElement *self,
gint *group,
gint *level)
{
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
if (group)
*group = priv->group;
if (level)
*level = priv->level;
}
static void
eek_element_real_symbol_index_changed (EekElement *self,
gint group,
gint level)
{
// g_debug ("symbol-index-changed");
}
static void static void
eek_element_finalize (GObject *object) eek_element_finalize (GObject *object)
{ {
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(object); EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(object);
g_free (priv->name); g_free (priv->name);
G_OBJECT_CLASS (eek_element_parent_class)->finalize (object);
} }
static void static void
@ -136,7 +244,6 @@ eek_element_set_property (GObject *object,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
g_return_if_fail (EEK_IS_ELEMENT(object));
switch (prop_id) { switch (prop_id) {
case PROP_NAME: case PROP_NAME:
eek_element_set_name (EEK_ELEMENT(object), eek_element_set_name (EEK_ELEMENT(object),
@ -146,6 +253,13 @@ eek_element_set_property (GObject *object,
eek_element_set_bounds (EEK_ELEMENT(object), eek_element_set_bounds (EEK_ELEMENT(object),
g_value_get_boxed (value)); g_value_get_boxed (value));
break; break;
case PROP_GROUP:
eek_element_set_group (EEK_ELEMENT(object),
g_value_get_int (value));
break;
case PROP_LEVEL:
eek_element_set_level (EEK_ELEMENT(object),
g_value_get_int (value));
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -160,7 +274,6 @@ eek_element_get_property (GObject *object,
{ {
EekBounds bounds; EekBounds bounds;
g_return_if_fail (EEK_IS_ELEMENT(object));
switch (prop_id) { switch (prop_id) {
case PROP_NAME: case PROP_NAME:
g_value_set_string (value, eek_element_get_name (EEK_ELEMENT(object))); g_value_set_string (value, eek_element_get_name (EEK_ELEMENT(object)));
@ -169,6 +282,12 @@ eek_element_get_property (GObject *object,
eek_element_get_bounds (EEK_ELEMENT(object), &bounds); eek_element_get_bounds (EEK_ELEMENT(object), &bounds);
g_value_set_boxed (value, &bounds); g_value_set_boxed (value, &bounds);
break; break;
case PROP_GROUP:
g_value_set_int (value, eek_element_get_group (EEK_ELEMENT(object)));
break;
case PROP_LEVEL:
g_value_set_int (value, eek_element_get_level (EEK_ELEMENT(object)));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -190,6 +309,11 @@ eek_element_class_init (EekElementClass *klass)
klass->get_name = eek_element_real_get_name; klass->get_name = eek_element_real_get_name;
klass->set_bounds = eek_element_real_set_bounds; klass->set_bounds = eek_element_real_set_bounds;
klass->get_bounds = eek_element_real_get_bounds; klass->get_bounds = eek_element_real_get_bounds;
klass->set_symbol_index = eek_element_real_set_symbol_index;
klass->get_symbol_index = eek_element_real_get_symbol_index;
/* signals */
klass->symbol_index_changed = eek_element_real_symbol_index_changed;
gobject_class->set_property = eek_element_set_property; gobject_class->set_property = eek_element_set_property;
gobject_class->get_property = eek_element_get_property; gobject_class->get_property = eek_element_get_property;
@ -222,6 +346,56 @@ eek_element_class_init (EekElementClass *klass)
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_BOUNDS, PROP_BOUNDS,
pspec); pspec);
/**
* EekElement:group:
*
* The group value of the symbol index of #EekElement.
*/
pspec = g_param_spec_int ("group",
"Group",
"Group value of the symbol index",
-1, G_MAXINT, -1,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_GROUP,
pspec);
/**
* EekElement:level:
*
* The level value of the symbol index of #EekElement.
*/
pspec = g_param_spec_int ("level",
"Level",
"Level value of the symbol index",
-1, G_MAXINT, -1,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_LEVEL,
pspec);
/**
* EekElement::symbol-index-changed:
* @element: an #EekElement
* @group: row index of the symbol matrix of keys on @element
* @level: column index of the symbol matrix of keys on @element
*
* The ::symbol-index-changed signal is emitted each time the
* global configuration of group/level index changes.
*/
signals[SYMBOL_INDEX_CHANGED] =
g_signal_new (I_("symbol-index-changed"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekElementClass, symbol_index_changed),
NULL,
NULL,
_eek_marshal_VOID__INT_INT,
G_TYPE_NONE,
2,
G_TYPE_INT,
G_TYPE_INT);
} }
static void static void
@ -232,6 +406,8 @@ eek_element_init (EekElement *self)
priv = self->priv = EEK_ELEMENT_GET_PRIVATE(self); priv = self->priv = EEK_ELEMENT_GET_PRIVATE(self);
priv->name = NULL; priv->name = NULL;
memset (&priv->bounds, 0, sizeof priv->bounds); memset (&priv->bounds, 0, sizeof priv->bounds);
priv->group = -1;
priv->level = -1;
} }
/** /**
@ -351,3 +527,159 @@ eek_element_get_absolute_position (EekElement *element,
*x = ax; *x = ax;
*y = ay; *y = ay;
} }
/**
* eek_element_set_position:
* @element: an #EekElement
* @x: X coordinate of top left corner
* @y: Y coordinate of top left corner
*
* Set the relative position of @element.
*/
void
eek_element_set_position (EekElement *element,
gdouble x,
gdouble y)
{
EekBounds bounds;
eek_element_get_bounds (element, &bounds);
bounds.x = x;
bounds.y = y;
eek_element_set_bounds (element, &bounds);
}
/**
* eek_element_set_size:
* @element: an #EekElement
* @width: width of @element
* @height: height of @element
*
* Set the size of @element.
*/
void
eek_element_set_size (EekElement *element,
gdouble width,
gdouble height)
{
EekBounds bounds;
eek_element_get_bounds (element, &bounds);
bounds.width = width;
bounds.height = height;
eek_element_set_bounds (element, &bounds);
}
/**
* eek_element_set_symbol_index:
* @element: an #EekElement
* @group: row index of the symbol matrix
* @level: column index of the symbol matrix
*
* Set the default index of the symbol matrices of @element. The
* setting affects the child, if child does not have the index set, as
* well as this element. To unset, pass -1 as group/level.
*/
void
eek_element_set_symbol_index (EekElement *element,
gint group,
gint level)
{
g_return_if_fail (EEK_IS_ELEMENT(element));
EEK_ELEMENT_GET_CLASS(element)->set_symbol_index (element, group, level);
}
/**
* eek_element_get_symbol_index:
* @element: an #EekElement
* @group: a pointer where the group value of the symbol index will be stored
* @level: a pointer where the level value of the symbol index will be stored
*
* Get the default index of the symbol matrices of @element.
* If the index is not set, -1 will be returned.
*/
void
eek_element_get_symbol_index (EekElement *element,
gint *group,
gint *level)
{
g_return_if_fail (EEK_IS_ELEMENT(element));
g_return_if_fail (group || level);
EEK_ELEMENT_GET_CLASS(element)->get_symbol_index (element, group, level);
}
/**
* eek_element_set_group:
* @element: an #EekElement
* @group: group index of @element
*
* Set the group value of the default symbol index of @element. To
* unset, pass -1 as @group.
*
* See also: eek_element_set_symbol_index()
*/
void
eek_element_set_group (EekElement *element,
gint group)
{
gint level;
level = eek_element_get_level (element);
eek_element_set_symbol_index (element, group, level);
}
/**
* eek_element_set_level:
* @element: an #EekElement
* @level: level index of @element
*
* Set the level value of the default symbol index of @element. To
* unset, pass -1 as @level.
*
* See also: eek_element_set_symbol_index()
*/
void
eek_element_set_level (EekElement *element,
gint level)
{
gint group;
group = eek_element_get_group (element);
eek_element_set_symbol_index (element, group, level);
}
/**
* eek_element_get_group:
* @element: an #EekElement
*
* Return the group value of the default symbol index of @element.
* If the value is not set, -1 will be returned.
*
* See also: eek_element_get_symbol_index()
*/
gint
eek_element_get_group (EekElement *element)
{
gint group;
eek_element_get_symbol_index (element, &group, NULL);
return group;
}
/**
* eek_element_get_level:
* @element: an #EekElement
*
* Return the level value of the default symbol index of @element.
* If the value is not set, -1 will be returned.
*
* See also: eek_element_get_symbol_index()
*/
gint
eek_element_get_level (EekElement *element)
{
gint level;
eek_element_get_symbol_index (element, NULL, &level);
return level;
}

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -37,7 +37,7 @@ typedef struct _EekElementPrivate EekElementPrivate;
struct _EekElement struct _EekElement
{ {
/*< private >*/ /*< private >*/
GInitiallyUnowned parent; GObject parent;
EekElementPrivate *priv; EekElementPrivate *priv;
}; };
@ -45,24 +45,36 @@ struct _EekElement
struct _EekElementClass struct _EekElementClass
{ {
/*< private >*/ /*< private >*/
GInitiallyUnownedClass parent_class; GObjectClass parent_class;
void (* set_parent) (EekElement *self, void (* set_parent) (EekElement *self,
EekElement *parent); EekElement *parent);
EekElement *(* get_parent) (EekElement *self); EekElement *(* get_parent) (EekElement *self);
void (* set_name) (EekElement *self, void (* set_name) (EekElement *self,
const gchar *name); const gchar *name);
G_CONST_RETURN gchar *(* get_name) (EekElement *self); G_CONST_RETURN gchar *(* get_name) (EekElement *self);
void (* set_bounds) (EekElement *self, void (* set_bounds) (EekElement *self,
EekBounds *bounds); EekBounds *bounds);
void (* get_bounds) (EekElement *self, void (* get_bounds) (EekElement *self,
EekBounds *bounds); EekBounds *bounds);
void (* set_symbol_index) (EekElement *self,
gint group,
gint level);
void (* get_symbol_index) (EekElement *self,
gint *group,
gint *level);
/* signals */
void (* symbol_index_changed) (EekElement *self,
gint group,
gint level);
/*< private >*/ /*< private >*/
/* padding */ /* padding */
gpointer pdummy[24]; gpointer pdummy[21];
}; };
GType eek_element_get_type (void) G_GNUC_CONST; GType eek_element_get_type (void) G_GNUC_CONST;
@ -81,9 +93,29 @@ void eek_element_set_bounds (EekElement *element,
void eek_element_get_bounds (EekElement *element, void eek_element_get_bounds (EekElement *element,
EekBounds *bounds); EekBounds *bounds);
void eek_element_set_position (EekElement *element,
gdouble x,
gdouble y);
void eek_element_set_size (EekElement *element,
gdouble width,
gdouble height);
void eek_element_get_absolute_position (EekElement *element, void eek_element_get_absolute_position (EekElement *element,
gdouble *x, gdouble *x,
gdouble *y); gdouble *y);
void eek_element_set_symbol_index (EekElement *element,
gint group,
gint level);
void eek_element_get_symbol_index (EekElement *element,
gint *group,
gint *level);
void eek_element_set_group (EekElement *element,
gint group);
void eek_element_set_level (EekElement *element,
gint level);
gint eek_element_get_group (EekElement *element);
gint eek_element_get_level (EekElement *element);
G_END_DECLS G_END_DECLS
#endif /* EEK_ELEMENT_H */ #endif /* EEK_ELEMENT_H */

View File

@ -1,5 +1,5 @@
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> # Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010 Red Hat, Inc. # Copyright (C) 2010-2011 Red Hat, Inc.
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License # modify it under the terms of the GNU Lesser General Public License
@ -23,8 +23,8 @@ includedir=@includedir@
Name: libeek-gtk Name: libeek-gtk
Description: A Library to Create Keyboard-like UI (GTK Support) Description: A Library to Create Keyboard-like UI (GTK Support)
URL: http://github.com/ueno/eekboard URL: http://ueno.github.com/eekboard/
Version: @VERSION@ Version: @VERSION@
Libs: -L${libdir} -leek -leek-gtk Requires: eek-@EEK_API_VERSION@ gtk+-@GTK_API_VERSION@
Libs.private: @GOBJECT2_LIBS@ @GTK2_LIBS@ Libs: -L${libdir} -leek-gtk
Cflags: -I${includedir}/eek-@EEK_API_VERSION@ Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -20,74 +20,237 @@
/** /**
* SECTION:eek-gtk-keyboard * SECTION:eek-gtk-keyboard
* @short_description: #EekKeyboard that can be converted into a #GtkWidget * @short_description: a #GtkWidget displaying #EekKeyboard
*/ */
#include <string.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <string.h>
#include "eek-gtk-keyboard.h" #include "eek-gtk-keyboard.h"
#include "eek-drawing.h" #include "eek-gtk-renderer.h"
#include "eek-keyboard.h" #include "eek-keyboard.h"
#include "eek-section.h" #include "eek-section.h"
#include "eek-key.h" #include "eek-key.h"
#include "eek-keysym.h" #include "eek-symbol.h"
G_DEFINE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, EEK_TYPE_KEYBOARD); enum {
PROP_0,
PROP_KEYBOARD,
PROP_LAST
};
G_DEFINE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA);
#define EEK_GTK_KEYBOARD_GET_PRIVATE(obj) \ #define EEK_GTK_KEYBOARD_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardPrivate))
#define SCALE 1.5 /* since 2.91.5 GDK_DRAWABLE was removed and gdk_cairo_create takes
GdkWindow as the argument */
#ifndef GDK_DRAWABLE
#define GDK_DRAWABLE(x) (x)
#endif
struct _EekGtkKeyboardPrivate struct _EekGtkKeyboardPrivate
{ {
GtkWidget *widget; EekRenderer *renderer;
EekKeyboard *keyboard;
/* pixmap of entire keyboard (for expose event) */ EekKey *dragged_key;
GdkPixmap *pixmap; gulong key_pressed_handler;
gulong key_released_handler;
/* mapping from outline pointer to pixmap */ gulong symbol_index_changed_handler;
GHashTable *outline_textures; EekTheme *theme;
/* mapping from outline pointer to large pixmap */
GHashTable *large_outline_textures;
PangoFontDescription *fonts[EEK_KEYSYM_CATEGORY_LAST];
gdouble scale;
}; };
static void prepare_keyboard_pixmap (EekGtkKeyboard *keyboard); static EekColor * color_from_gdk_color (GdkColor *gdk_color);
static void on_key_pressed (EekKeyboard *keyboard,
EekKey *key,
gpointer user_data);
static void on_key_released (EekKeyboard *keyboard,
EekKey *key,
gpointer user_data);
static void on_symbol_index_changed (EekKeyboard *keyboard,
gint group,
gint level,
gpointer user_data);
static void render_pressed_key (GtkWidget *widget,
EekKey *key);
static void static void
eek_gtk_keyboard_real_set_keysym_index (EekKeyboard *self, eek_gtk_keyboard_real_realize (GtkWidget *self)
gint group,
gint level)
{ {
gint g, l; gtk_widget_set_double_buffered (self, FALSE);
gtk_widget_set_events (self,
GDK_EXPOSURE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK);
eek_keyboard_get_keysym_index (self, &g, &l); GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->realize (self);
EEK_KEYBOARD_CLASS(eek_gtk_keyboard_parent_class)-> }
set_keysym_index (self, group, level);
if (g != group || l != level) { static gboolean
EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD(self); eek_gtk_keyboard_real_draw (GtkWidget *self,
EekGtkKeyboardPrivate *priv = cairo_t *cr)
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); {
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
GtkAllocation allocation;
EekColor background;
gtk_widget_get_allocation (self, &allocation);
if (!priv->renderer) {
GtkStyle *style;
GtkStateType state; GtkStateType state;
GtkAllocation allocation; PangoContext *pcontext;
EekColor *color;
prepare_keyboard_pixmap (keyboard); pcontext = gtk_widget_get_pango_context (self);
state = gtk_widget_get_state (GTK_WIDGET (priv->widget)); priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
gtk_widget_get_allocation (GTK_WIDGET (priv->widget), &allocation); if (priv->theme)
gdk_draw_drawable (gtk_widget_get_window (priv->widget), eek_renderer_set_theme (priv->renderer, priv->theme);
gtk_widget_get_style (priv->widget)->fg_gc[state],
priv->pixmap, eek_renderer_set_allocation_size (priv->renderer,
0, 0, allocation.width,
0, 0, allocation.height);
allocation.width, allocation.height);
style = gtk_widget_get_style (self);
state = gtk_widget_get_state (self);
color = color_from_gdk_color (&style->fg[state]);
eek_renderer_set_default_foreground_color (priv->renderer, color);
eek_color_free (color);
color = color_from_gdk_color (&style->bg[state]);
eek_renderer_set_default_background_color (priv->renderer, color);
eek_color_free (color);
}
/* blank background */
eek_renderer_get_background_color (priv->renderer,
EEK_ELEMENT(priv->keyboard),
&background);
cairo_set_source_rgba (cr,
background.red,
background.green,
background.blue,
background.alpha);
cairo_paint (cr);
eek_renderer_render_keyboard (priv->renderer, cr);
/* redraw dragged key */
if (priv->dragged_key)
render_pressed_key (self, priv->dragged_key);
return FALSE;
}
#if !GTK_CHECK_VERSION (2, 91, 2)
static gboolean
eek_gtk_keyboard_real_expose_event (GtkWidget *self,
GdkEventExpose *event)
{
gboolean retval;
cairo_t *cr;
cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (self)));
retval = eek_gtk_keyboard_real_draw (self, cr);
cairo_destroy (cr);
return retval;
}
#endif /* !GTK_CHECK_VERSION (2, 91, 2) */
static void
eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
GtkAllocation *allocation)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
if (priv->renderer)
eek_renderer_set_allocation_size (priv->renderer,
allocation->width,
allocation->height);
GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->
size_allocate (self, allocation);
}
static gboolean
eek_gtk_keyboard_real_button_press_event (GtkWidget *self,
GdkEventButton *event)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
EekKey *key;
key = eek_renderer_find_key_by_position (priv->renderer,
(gdouble)event->x,
(gdouble)event->y);
if (priv->dragged_key && priv->dragged_key != key)
g_signal_emit_by_name (priv->dragged_key, "released", priv->keyboard);
if (key && !eek_key_is_pressed (key)) {
priv->dragged_key = key;
g_signal_emit_by_name (key, "pressed", priv->keyboard);
}
return TRUE;
}
static gboolean
eek_gtk_keyboard_real_button_release_event (GtkWidget *self,
GdkEventButton *event)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
if (priv->dragged_key) {
g_signal_emit_by_name (priv->dragged_key, "released", priv->keyboard);
priv->dragged_key = NULL;
}
return TRUE;
}
static void
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
EekKeyboard *keyboard)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
priv->keyboard = g_object_ref (keyboard);
priv->key_pressed_handler =
g_signal_connect (priv->keyboard, "key-pressed",
G_CALLBACK(on_key_pressed), self);
priv->key_released_handler =
g_signal_connect (priv->keyboard, "key-released",
G_CALLBACK(on_key_released), self);
priv->symbol_index_changed_handler =
g_signal_connect (priv->keyboard, "symbol-index-changed",
G_CALLBACK(on_symbol_index_changed), self);
}
static void
eek_gtk_keyboard_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekKeyboard *keyboard;
switch (prop_id) {
case PROP_KEYBOARD:
keyboard = g_value_get_object (value);
eek_gtk_keyboard_set_keyboard (EEK_GTK_KEYBOARD(object), keyboard);
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
} }
} }
@ -96,38 +259,77 @@ eek_gtk_keyboard_dispose (GObject *object)
{ {
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object); EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object);
if (priv->widget) { if (priv->renderer) {
g_object_unref (priv->widget); g_object_unref (priv->renderer);
priv->widget = NULL; priv->renderer = NULL;
} }
if (priv->keyboard) {
if (g_signal_handler_is_connected (priv->keyboard,
priv->key_pressed_handler))
g_signal_handler_disconnect (priv->keyboard,
priv->key_pressed_handler);
if (g_signal_handler_is_connected (priv->keyboard,
priv->key_released_handler))
g_signal_handler_disconnect (priv->keyboard,
priv->key_released_handler);
if (g_signal_handler_is_connected (priv->keyboard,
priv->symbol_index_changed_handler))
g_signal_handler_disconnect (priv->keyboard,
priv->symbol_index_changed_handler);
if (priv->dragged_key) {
g_signal_emit_by_name (priv->dragged_key,
"released",
priv->keyboard);
priv->dragged_key = NULL;
}
g_object_unref (priv->keyboard);
priv->keyboard = NULL;
}
if (priv->theme) {
g_object_unref (priv->theme);
priv->theme = NULL;
}
G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object); G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
} }
static void
eek_gtk_keyboard_finalize (GObject *object)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object);
gint i;
g_hash_table_unref (priv->outline_textures);
g_hash_table_unref (priv->large_outline_textures);
for (i = 0; i < EEK_KEYSYM_CATEGORY_LAST; i++)
pango_font_description_free (priv->fonts[i]);
}
static void static void
eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass) eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
{ {
EekKeyboardClass *keyboard_class = EEK_KEYBOARD_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (gobject_class, g_type_class_add_private (gobject_class,
sizeof (EekGtkKeyboardPrivate)); sizeof (EekGtkKeyboardPrivate));
keyboard_class->set_keysym_index = eek_gtk_keyboard_real_set_keysym_index; widget_class->realize = eek_gtk_keyboard_real_realize;
#if GTK_CHECK_VERSION (2, 91, 2)
widget_class->draw = eek_gtk_keyboard_real_draw;
#else /* GTK_CHECK_VERSION (2, 91, 2) */
widget_class->expose_event = eek_gtk_keyboard_real_expose_event;
#endif /* !GTK_CHECK_VERSION (2, 91, 2) */
widget_class->size_allocate = eek_gtk_keyboard_real_size_allocate;
widget_class->button_press_event =
eek_gtk_keyboard_real_button_press_event;
widget_class->button_release_event =
eek_gtk_keyboard_real_button_release_event;
gobject_class->set_property = eek_gtk_keyboard_set_property;
gobject_class->dispose = eek_gtk_keyboard_dispose; gobject_class->dispose = eek_gtk_keyboard_dispose;
gobject_class->finalize = eek_gtk_keyboard_finalize;
pspec = g_param_spec_object ("keyboard",
"Keyboard",
"Keyboard",
EEK_TYPE_KEYBOARD,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
g_object_class_install_property (gobject_class,
PROP_KEYBOARD,
pspec);
} }
static void static void
@ -136,355 +338,127 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
EekGtkKeyboardPrivate *priv; EekGtkKeyboardPrivate *priv;
priv = self->priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); priv = self->priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
priv->widget = NULL; priv->renderer = NULL;
priv->pixmap = NULL; priv->keyboard = NULL;
priv->outline_textures = priv->dragged_key = NULL;
g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
g_object_unref);
priv->large_outline_textures =
g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
g_object_unref);
memset (priv->fonts, 0, sizeof priv->fonts);
priv->scale = 1.0;
} }
/** /**
* eek_gtk_keyboard_new: * eek_gtk_keyboard_new:
* @keyboard: an #EekKeyboard
* *
* Create a new #EekGtkKeyboard. * Create a new #GtkWidget displaying @keyboard.
* Returns: a #GtkWidget
*/ */
EekKeyboard*
eek_gtk_keyboard_new (void)
{
return g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL);
}
struct _DrawingContext
{
EekGtkKeyboard *keyboard;
cairo_t *cr;
GdkColor *fg, *bg;
};
typedef struct _DrawingContext DrawingContext;
static void
prepare_keyboard_pixmap_key_callback (EekElement *element,
gpointer user_data)
{
DrawingContext *context = user_data;
EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(context->keyboard);
EekKey *key = EEK_KEY(element);
EekBounds bounds;
EekOutline *outline;
GdkPixmap *texture;
eek_element_get_bounds (element, &bounds);
outline = eek_key_get_outline (key);
texture = g_hash_table_lookup (priv->outline_textures, outline);
if (!texture) {
cairo_t *cr;
texture =
gdk_pixmap_new (gtk_widget_get_window (GTK_WIDGET (priv->widget)),
bounds.width, bounds.height, -1);
cr = gdk_cairo_create (GDK_DRAWABLE (texture));
gdk_cairo_set_source_color (cr, context->bg);
cairo_rectangle (cr, 0, 0, bounds.width, bounds.height);
gdk_cairo_set_source_color (cr, context->fg);
eek_draw_outline (cr, outline);
cairo_destroy (cr);
g_hash_table_insert (priv->outline_textures, outline, texture);
}
cairo_save (context->cr);
cairo_translate (context->cr, bounds.x, bounds.y);
gdk_cairo_set_source_pixmap (context->cr, texture, 0, 0);
cairo_rectangle (context->cr, 0, 0, bounds.width, bounds.height);
cairo_fill (context->cr);
cairo_move_to (context->cr, 0, 0);
gdk_cairo_set_source_color (context->cr, context->fg);
eek_draw_key_label (context->cr, key, priv->fonts);
cairo_restore (context->cr);
}
static void
prepare_keyboard_pixmap_section_callback (EekElement *element,
gpointer user_data)
{
DrawingContext *context = user_data;
EekBounds bounds;
eek_element_get_bounds (element, &bounds);
cairo_save (context->cr);
cairo_translate (context->cr,
bounds.x,
bounds.y);
eek_container_foreach_child (EEK_CONTAINER(element),
prepare_keyboard_pixmap_key_callback,
context);
cairo_restore (context->cr);
}
static void
drawing_context_init (DrawingContext *context, EekGtkKeyboard *keyboard)
{
EekGtkKeyboardPrivate *priv = keyboard->priv;
GtkStateType state;
state = gtk_widget_get_state (GTK_WIDGET (priv->widget));
context->keyboard = keyboard;
context->fg = &gtk_widget_get_style (GTK_WIDGET (priv->widget))->fg[state];
context->bg = &gtk_widget_get_style (GTK_WIDGET (priv->widget))->bg[state];
}
static void
prepare_keyboard_pixmap (EekGtkKeyboard *keyboard)
{
EekGtkKeyboardPrivate *priv = keyboard->priv;
GtkAllocation allocation;
GtkStateType state;
DrawingContext context;
gtk_widget_get_allocation (GTK_WIDGET (priv->widget), &allocation);
priv->pixmap =
gdk_pixmap_new (gtk_widget_get_window (GTK_WIDGET (priv->widget)),
allocation.width, allocation.height, -1);
/* blank background */
state = gtk_widget_get_state (GTK_WIDGET (priv->widget));
gdk_draw_rectangle
(priv->pixmap,
gtk_widget_get_style (GTK_WIDGET(priv->widget))->base_gc[state],
TRUE,
0, 0, allocation.width, allocation.height);
/* draw sections on the canvas */
drawing_context_init (&context, keyboard);
context.cr = gdk_cairo_create (GDK_DRAWABLE (priv->pixmap));
cairo_scale (context.cr, priv->scale, priv->scale);
eek_container_foreach_child (EEK_CONTAINER(keyboard),
prepare_keyboard_pixmap_section_callback,
&context);
cairo_destroy (context.cr);
}
static gboolean
on_expose_event (GtkWidget *widget,
GdkEventExpose *event,
gpointer user_data)
{
EekGtkKeyboard *keyboard = user_data;
EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
GtkStateType state = gtk_widget_get_state (widget);
if (!priv->pixmap) {
/* compute font sizes which fit in each key shape */
PangoFontDescription *base_font;
PangoContext *context;
PangoLayout *layout;
context = gtk_widget_get_pango_context (priv->widget);
layout = pango_layout_new (context);
base_font = gtk_widget_get_style (priv->widget)->font_desc;
pango_layout_set_font_description (layout, base_font);
eek_get_fonts (EEK_KEYBOARD(keyboard), layout, priv->fonts);
prepare_keyboard_pixmap (keyboard);
}
g_return_val_if_fail (priv->pixmap, FALSE);
gdk_draw_drawable (gtk_widget_get_window (widget),
gtk_widget_get_style (widget)->fg_gc[state],
priv->pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
return TRUE;
}
static void
key_enlarge (EekGtkKeyboard *keyboard, EekKey *key)
{
EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
EekBounds bounds;
EekOutline *outline;
gdouble ax, ay;
GdkPixmap *pixmap, *texture;
DrawingContext context;
GtkStateType state;
cairo_t *cr;
drawing_context_init (&context, keyboard);
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
eek_element_get_absolute_position (EEK_ELEMENT(key), &ax, &ay);
outline = eek_key_get_outline (key);
texture = g_hash_table_lookup (priv->large_outline_textures, outline);
if (!texture) {
texture =
gdk_pixmap_new (gtk_widget_get_window (GTK_WIDGET (priv->widget)),
bounds.width * SCALE, bounds.height * SCALE, -1);
cr = gdk_cairo_create (GDK_DRAWABLE (texture));
cairo_scale (cr, SCALE, SCALE);
gdk_cairo_set_source_color (cr, context.bg);
cairo_rectangle (cr, 0, 0, bounds.width, bounds.height);
gdk_cairo_set_source_color (cr, context.fg);
eek_draw_outline (cr, outline);
cairo_destroy (cr);
g_hash_table_insert (priv->large_outline_textures, outline, texture);
}
pixmap =
gdk_pixmap_new (gtk_widget_get_window (GTK_WIDGET (priv->widget)),
bounds.width * SCALE * priv->scale,
bounds.height * SCALE * priv->scale, -1);
cr = gdk_cairo_create (GDK_DRAWABLE (pixmap));
cairo_scale (cr, priv->scale, priv->scale);
gdk_cairo_set_source_pixmap (cr, texture, 0, 0);
cairo_rectangle (cr, 0, 0, bounds.width * SCALE, bounds.height * SCALE);
cairo_fill (cr);
cairo_move_to (cr, 0, 0);
cairo_scale (cr, SCALE, SCALE);
gdk_cairo_set_source_color (cr, context.fg);
eek_draw_key_label (cr, key, priv->fonts);
cairo_destroy (cr);
state = gtk_widget_get_state (GTK_WIDGET (priv->widget));
gdk_draw_drawable (gtk_widget_get_window (priv->widget),
gtk_widget_get_style (priv->widget)->fg_gc[state],
pixmap,
0, 0,
(ax - (bounds.width * SCALE - bounds.width) / 2) *
priv->scale,
(ay - (bounds.height * SCALE - bounds.height) / 2) *
priv->scale,
bounds.width * SCALE * priv->scale,
bounds.height * SCALE * priv->scale);
g_object_unref (pixmap);
}
static void
key_shrink (EekGtkKeyboard *keyboard, EekKey *key)
{
EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
EekBounds bounds;
gdouble ax, ay;
GtkStateType state;
g_return_if_fail (priv->pixmap);
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
eek_element_get_absolute_position (EEK_ELEMENT(key), &ax, &ay);
state = gtk_widget_get_state (GTK_WIDGET (priv->widget));
ax -= (bounds.width * SCALE - bounds.width) / 2;
ay -= (bounds.height * SCALE - bounds.height) / 2;
gdk_draw_drawable (gtk_widget_get_window (priv->widget),
gtk_widget_get_style (priv->widget)->fg_gc[state],
priv->pixmap,
ax * priv->scale, ay * priv->scale,
ax * priv->scale, ay * priv->scale,
bounds.width * SCALE * priv->scale,
bounds.height * SCALE * priv->scale);
}
static gboolean
on_button_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
EekElement *keyboard = user_data, *section, *key;
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
EekBounds bounds;
gdouble x, y;
x = (gdouble)event->x / priv->scale;
y = (gdouble)event->y / priv->scale;
section = eek_container_find_by_position (EEK_CONTAINER(keyboard), x, y);
if (section) {
eek_element_get_bounds (keyboard, &bounds);
x -= bounds.x;
y -= bounds.y;
key = eek_container_find_by_position (EEK_CONTAINER(section),
x,
y);
if (key)
switch (event->type) {
case GDK_BUTTON_PRESS:
key_enlarge (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(key));
g_signal_emit_by_name (keyboard, "key-pressed", key);
return TRUE;
case GDK_BUTTON_RELEASE:
key_shrink (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(key));
g_signal_emit_by_name (keyboard, "key-released", key);
return TRUE;
default:
return FALSE;
}
}
return FALSE;
}
static void
on_size_allocate (GtkWidget *widget,
GtkAllocation *allocation,
gpointer user_data)
{
EekGtkKeyboard *keyboard = user_data;
EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
EekBounds bounds;
GdkPixmap *pixmap;
if (priv->pixmap) {
pixmap = priv->pixmap;
priv->pixmap = NULL;
g_object_unref (pixmap);
}
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
priv->scale = allocation->width > allocation->height ?
allocation->width / bounds.width :
allocation->height / bounds.height;
}
GtkWidget * GtkWidget *
eek_gtk_keyboard_get_widget (EekGtkKeyboard *keyboard) eek_gtk_keyboard_new (EekKeyboard *keyboard)
{ {
EekGtkKeyboardPrivate *priv = return g_object_new (EEK_TYPE_GTK_KEYBOARD, "keyboard", keyboard, NULL);
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); }
if (!priv->widget) { static EekColor *
priv->widget = gtk_drawing_area_new (); color_from_gdk_color (GdkColor *gdk_color)
g_object_ref_sink (priv->widget); {
return eek_color_new (gdk_color->red / (gdouble)0xFFFF,
gtk_widget_set_double_buffered (priv->widget, FALSE); gdk_color->green / (gdouble)0xFFFF,
gtk_widget_set_events (priv->widget, gdk_color->blue / (gdouble)0xFFFF,
GDK_EXPOSURE_MASK | 1.0);
GDK_KEY_PRESS_MASK | }
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK); static void
g_signal_connect (priv->widget, "expose_event", magnify_bounds (EekBounds *bounds, EekBounds *large_bounds, gdouble scale)
G_CALLBACK (on_expose_event), keyboard); {
g_signal_connect (priv->widget, "size-allocate", g_assert (scale >= 1.0);
G_CALLBACK (on_size_allocate), keyboard);
g_signal_connect (priv->widget, "button-press-event", large_bounds->width = bounds->width * scale;
G_CALLBACK (on_button_event), keyboard); large_bounds->height = bounds->height * scale;
g_signal_connect (priv->widget, "button-release-event",
G_CALLBACK (on_button_event), keyboard); large_bounds->x = bounds->x - (large_bounds->width - bounds->width) / 2;
eek_keyboard_realize (EEK_KEYBOARD(keyboard)); large_bounds->y = bounds->y - (large_bounds->height - bounds->height) / 2;
} }
return priv->widget;
static void
render_pressed_key (GtkWidget *widget,
EekKey *key)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
EekBounds bounds, large_bounds;
cairo_t *cr;
cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
magnify_bounds (&bounds, &large_bounds, 1.5);
cairo_translate (cr, large_bounds.x, large_bounds.y);
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
cairo_destroy (cr);
}
static void
on_key_pressed (EekKeyboard *keyboard,
EekKey *key,
gpointer user_data)
{
GtkWidget *widget = user_data;
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
/* renderer may have not been set yet if the widget is a popup */
if (!priv->renderer)
return;
render_pressed_key (widget, key);
}
static void
on_key_released (EekKeyboard *keyboard,
EekKey *key,
gpointer user_data)
{
GtkWidget *widget = user_data;
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
cairo_t *cr;
EekBounds bounds, large_bounds;
/* renderer may have not been set yet if the widget is a popup */
if (!priv->renderer)
return;
cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
magnify_bounds (&bounds, &large_bounds, 2.0);
cairo_rectangle (cr,
large_bounds.x,
large_bounds.y,
large_bounds.width,
large_bounds.height);
cairo_clip (cr);
eek_renderer_render_keyboard (priv->renderer, cr);
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_destroy (cr);
}
static void
on_symbol_index_changed (EekKeyboard *keyboard,
gint group,
gint level,
gpointer user_data)
{
GtkWidget *widget = user_data;
gtk_widget_queue_draw (widget);
}
void
eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
EekTheme *theme)
{
EekGtkKeyboardPrivate *priv;
g_return_if_fail (EEK_IS_GTK_KEYBOARD(keyboard));
g_return_if_fail (EEK_IS_THEME(theme));
priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
priv->theme = g_object_ref (theme);
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -20,7 +20,9 @@
#ifndef EEK_GTK_KEYBOARD_H #ifndef EEK_GTK_KEYBOARD_H
#define EEK_GTK_KEYBOARD_H 1 #define EEK_GTK_KEYBOARD_H 1
#include <glib.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "eek-keyboard.h" #include "eek-keyboard.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -38,7 +40,7 @@ typedef struct _EekGtkKeyboardPrivate EekGtkKeyboardPrivate;
struct _EekGtkKeyboard struct _EekGtkKeyboard
{ {
/*< private >*/ /*< private >*/
EekKeyboard parent; GtkDrawingArea parent;
EekGtkKeyboardPrivate *priv; EekGtkKeyboardPrivate *priv;
}; };
@ -46,16 +48,17 @@ struct _EekGtkKeyboard
struct _EekGtkKeyboardClass struct _EekGtkKeyboardClass
{ {
/*< private >*/ /*< private >*/
EekKeyboardClass parent_class; GtkDrawingAreaClass parent_class;
/*< private >*/ /*< private >*/
/* padding */ /* padding */
gpointer pdummy[24]; gpointer pdummy[24];
}; };
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST; GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
EekKeyboard *eek_gtk_keyboard_new (void); GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard);
GtkWidget *eek_gtk_keyboard_get_widget (EekGtkKeyboard *keyboard); void eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
EekTheme *theme);
G_END_DECLS G_END_DECLS
#endif /* EEK_GTK_KEYBOARD_H */ #endif /* EEK_GTK_KEYBOARD_H */

134
eek/eek-gtk-renderer.c Normal file
View File

@ -0,0 +1,134 @@
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <string.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "eek-gtk-renderer.h"
#include "eek-key.h"
G_DEFINE_TYPE (EekGtkRenderer, eek_gtk_renderer, EEK_TYPE_RENDERER);
static cairo_surface_t *
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
{
cairo_surface_t *dummy_surface;
cairo_pattern_t *pattern;
cairo_surface_t *surface;
cairo_t *cr;
dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
cr = cairo_create (dummy_surface);
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
pattern = cairo_get_source (cr);
cairo_pattern_get_surface (pattern, &surface);
cairo_surface_reference (surface);
cairo_destroy (cr);
cairo_surface_destroy (dummy_surface);
return surface;
}
static void
eek_gtk_renderer_real_render_key_icon (EekRenderer *self,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate)
{
EekBounds bounds;
EekSymbol *symbol;
const gchar *icon_name;
GdkPixbuf *pixbuf;
cairo_surface_t *surface;
GError *error;
gint width, height;
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
g_return_if_fail (symbol);
icon_name = eek_symbol_get_icon_name (symbol);
g_return_if_fail (icon_name);
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
bounds.width *= scale;
bounds.height *= scale;
error = NULL;
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
icon_name,
MIN(bounds.width, bounds.height),
0,
&error);
g_return_if_fail (pixbuf);
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
if (bounds.width * height < bounds.height * width)
scale = bounds.width / width;
else
scale = bounds.height / height;
cairo_save (cr);
cairo_translate (cr,
(bounds.width - width * scale) / 2,
(bounds.height - height * scale) / 2);
eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
surface = pixbuf_to_cairo_surface (pixbuf);
g_object_unref (pixbuf);
cairo_set_source_surface (cr, surface, 0.0, 0.0);
cairo_paint (cr);
cairo_restore (cr);
}
static void
eek_gtk_renderer_class_init (EekGtkRendererClass *klass)
{
EekRendererClass *renderer_class = EEK_RENDERER_CLASS (klass);
renderer_class->render_key_icon = eek_gtk_renderer_real_render_key_icon;
}
static void
eek_gtk_renderer_init (EekGtkRenderer *self)
{
}
EekRenderer *
eek_gtk_renderer_new (EekKeyboard *keyboard,
PangoContext *pcontext,
GtkWidget *widget)
{
EekRenderer *renderer;
renderer = g_object_new (EEK_TYPE_GTK_RENDERER,
"keyboard", keyboard,
"pango-context", pcontext,
NULL);
return renderer;
}

61
eek/eek-gtk-renderer.h Normal file
View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef EEK_GTK_RENDERER_H
#define EEK_GTK_RENDERER_H 1
#include <gtk/gtk.h>
#include "eek-renderer.h"
G_BEGIN_DECLS
#define EEK_TYPE_GTK_RENDERER (eek_gtk_renderer_get_type())
#define EEK_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRenderer))
#define EEK_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
#define EEK_IS_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_RENDERER))
#define EEK_IS_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_RENDERER))
#define EEK_GTK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
typedef struct _EekGtkRenderer EekGtkRenderer;
typedef struct _EekGtkRendererClass EekGtkRendererClass;
typedef struct _EekGtkRendererPrivate EekGtkRendererPrivate;
struct _EekGtkRenderer {
EekRenderer parent;
EekGtkRendererPrivate *priv;
};
struct _EekGtkRendererClass
{
EekRendererClass parent_class;
/*< private >*/
/* padding */
gpointer pdummy[24];
};
GType eek_gtk_renderer_get_type (void) G_GNUC_CONST;
EekRenderer *eek_gtk_renderer_new (EekKeyboard *keyboard,
PangoContext *pcontext,
GtkWidget *widget);
G_END_DECLS
#endif /* EEK_GTK_RENDERER_H */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -25,27 +25,29 @@
* The #EekKeyClass class represents a key. * The #EekKeyClass class represents a key.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <string.h> #include <string.h>
#define DEBUG 0 #define DEBUG 0
#if DEBUG #if DEBUG
#include <stdio.h> #include <stdio.h>
#endif #endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-key.h" #include "eek-key.h"
#include "eek-keysym.h" #include "eek-section.h"
#include "eek-keyboard.h"
#include "eek-symbol.h"
#include "eek-serializable.h"
enum { enum {
PROP_0, PROP_0,
PROP_KEYCODE, PROP_KEYCODE,
PROP_KEYSYMS, PROP_SYMBOL_MATRIX,
PROP_COLUMN, PROP_COLUMN,
PROP_ROW, PROP_ROW,
PROP_OUTLINE, PROP_OREF,
PROP_GROUP,
PROP_LEVEL,
PROP_LAST PROP_LAST
}; };
@ -57,7 +59,11 @@ enum {
static guint signals[LAST_SIGNAL] = { 0, }; static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (EekKey, eek_key, EEK_TYPE_ELEMENT); static void eek_serializable_iface_init (EekSerializableIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekKey, eek_key, EEK_TYPE_ELEMENT,
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
eek_serializable_iface_init));
#define EEK_KEY_GET_PRIVATE(obj) \ #define EEK_KEY_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEY, EekKeyPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEY, EekKeyPrivate))
@ -66,14 +72,111 @@ G_DEFINE_TYPE (EekKey, eek_key, EEK_TYPE_ELEMENT);
struct _EekKeyPrivate struct _EekKeyPrivate
{ {
guint keycode; guint keycode;
EekKeysymMatrix keysyms; EekSymbolMatrix *symbol_matrix;
gint column; gint column;
gint row; gint row;
EekOutline *outline; gulong oref;
gint group; gboolean is_pressed;
gint level;
}; };
static EekSerializableIface *eek_key_parent_serializable_iface;
static GVariant *
_g_variant_new_symbol_matrix (EekSymbolMatrix *symbol_matrix)
{
GVariantBuilder builder, array;
gint i, num_symbols = symbol_matrix->num_groups * symbol_matrix->num_levels;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("(iiv)"));
g_variant_builder_add (&builder, "i", symbol_matrix->num_groups);
g_variant_builder_add (&builder, "i", symbol_matrix->num_levels);
g_variant_builder_init (&array, G_VARIANT_TYPE ("av"));
for (i = 0; i < num_symbols; i++) {
GVariant *symbol = eek_serializable_serialize
(EEK_SERIALIZABLE(symbol_matrix->data[i]));
g_variant_builder_add (&array, "v", symbol);
}
g_variant_builder_add (&builder, "v", g_variant_builder_end (&array));
return g_variant_builder_end (&builder);
}
static EekSymbolMatrix *
_g_variant_get_symbol_matrix (GVariant *variant)
{
gint num_groups, num_levels, i;
EekSymbolMatrix *symbol_matrix;
GVariant *array, *child;
GVariantIter iter;
g_variant_get_child (variant, 0, "i", &num_groups);
g_variant_get_child (variant, 1, "i", &num_levels);
symbol_matrix = eek_symbol_matrix_new (num_groups, num_levels);
g_variant_get_child (variant, 2, "v", &array);
g_variant_iter_init (&iter, array);
for (i = 0; i < num_groups * num_levels; i++) {
EekSerializable *serializable;
if (!g_variant_iter_next (&iter, "v", &child)) {
eek_symbol_matrix_free (symbol_matrix);
g_return_val_if_reached (NULL);
}
serializable = eek_serializable_deserialize (child);
symbol_matrix->data[i] = EEK_SYMBOL(serializable);
}
return symbol_matrix;
}
static void
eek_key_real_serialize (EekSerializable *self,
GVariantBuilder *builder)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
eek_key_parent_serializable_iface->serialize (self, builder);
g_variant_builder_add (builder, "u", priv->keycode);
g_variant_builder_add (builder, "v",
_g_variant_new_symbol_matrix (priv->symbol_matrix));
g_variant_builder_add (builder, "i", priv->column);
g_variant_builder_add (builder, "i", priv->row);
g_variant_builder_add (builder, "u", priv->oref);
}
static gsize
eek_key_real_deserialize (EekSerializable *self,
GVariant *variant,
gsize index)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
GVariant *symbol_matrix;
index = eek_key_parent_serializable_iface->deserialize (self,
variant,
index);
g_variant_get_child (variant, index++, "u", &priv->keycode);
g_variant_get_child (variant, index++, "v", &symbol_matrix);
eek_symbol_matrix_free (priv->symbol_matrix);
priv->symbol_matrix = _g_variant_get_symbol_matrix (symbol_matrix);
g_variant_get_child (variant, index++, "i", &priv->column);
g_variant_get_child (variant, index++, "i", &priv->row);
g_variant_get_child (variant, index++, "u", &priv->oref);
return index;
}
static void
eek_serializable_iface_init (EekSerializableIface *iface)
{
eek_key_parent_serializable_iface =
g_type_interface_peek_parent (iface);
iface->serialize = eek_key_real_serialize;
iface->deserialize = eek_key_real_deserialize;
}
static void static void
eek_key_real_set_keycode (EekKey *self, guint keycode) eek_key_real_set_keycode (EekKey *self, guint keycode)
{ {
@ -89,66 +192,19 @@ eek_key_real_get_keycode (EekKey *self)
} }
static void static void
eek_key_real_set_keysyms (EekKey *self, eek_key_real_set_symbol_matrix (EekKey *self,
guint *keysyms, EekSymbolMatrix *matrix)
gint num_groups,
gint num_levels)
{ {
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
gint num_keysyms = num_groups * num_levels; eek_symbol_matrix_free (priv->symbol_matrix);
priv->symbol_matrix = eek_symbol_matrix_copy (matrix);
if (num_keysyms > 0) {
priv->keysyms.data =
g_slice_alloc (num_keysyms * sizeof(guint));
memcpy (priv->keysyms.data, keysyms,
num_keysyms * sizeof(guint));
}
priv->keysyms.num_groups = num_groups;
priv->keysyms.num_levels = num_levels;
#if DEBUG
{
const gchar *name;
gint i;
name = eek_element_get_name (EEK_ELEMENT(self));
fprintf (stderr, "%s: ", name);
for (i = 0; i < priv->keysyms.num_groups * priv->keysyms.num_levels; i++)
fprintf (stderr, "\"%s\" ", eek_keysym_to_string (priv->keysyms.data[i]));
fprintf (stderr, "\n");
}
#endif
} }
static void static EekSymbolMatrix *
eek_key_real_get_keysyms (EekKey *self, eek_key_real_get_symbol_matrix (EekKey *self)
guint **keysyms,
gint *num_groups,
gint *num_levels)
{ {
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels; return priv->symbol_matrix;
if (num_groups)
*num_groups = priv->keysyms.num_groups;
if (num_levels)
*num_levels = priv->keysyms.num_levels;
if (keysyms && num_keysyms > 0) {
*keysyms = g_slice_alloc (num_keysyms * sizeof(guint));
memcpy (*keysyms, priv->keysyms.data, num_keysyms * sizeof(guint));
}
}
static guint
eek_key_real_get_keysym (EekKey *self)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels;
if (num_keysyms == 0)
return EEK_INVALID_KEYSYM;
return priv->keysyms.data[priv->group * priv->keysyms.num_levels +
priv->level];
} }
static void static void
@ -178,70 +234,53 @@ eek_key_real_get_index (EekKey *self,
} }
static void static void
eek_key_real_set_outline (EekKey *self, EekOutline *outline) eek_key_real_set_oref (EekKey *self, gulong oref)
{ {
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
priv->outline = outline; priv->oref = oref;
} }
static EekOutline * static gulong
eek_key_real_get_outline (EekKey *self) eek_key_real_get_oref (EekKey *self)
{ {
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
return priv->outline; return priv->oref;
}
static gboolean
eek_key_real_is_pressed (EekKey *self)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
return priv->is_pressed;
} }
static void static void
eek_key_real_set_keysym_index (EekKey *self, eek_key_real_pressed (EekKey *self)
gint group,
gint level)
{ {
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
g_return_if_fail (0 <= group); priv->is_pressed = TRUE;
if (group >= priv->keysyms.num_groups) #if DEBUG
group = 0; g_debug ("pressed %X", eek_key_get_keycode (self));
g_return_if_fail (0 <= level); #endif
if (level >= priv->keysyms.num_levels)
level = 0;
priv->group = group;
priv->level = level;
} }
static void static void
eek_key_real_get_keysym_index (EekKey *self, eek_key_real_released (EekKey *self)
gint *group,
gint *level)
{ {
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
g_return_if_fail (group); priv->is_pressed = FALSE;
g_return_if_fail (level); #if DEBUG
if (group) g_debug ("released %X", eek_key_get_keycode (self));
*group = priv->group; #endif
if (level)
*level = priv->level;
}
static void
eek_key_real_pressed (EekKey *key)
{
g_debug ("pressed %X", eek_key_get_keycode (key));
}
static void
eek_key_real_released (EekKey *key)
{
g_debug ("released %X", eek_key_get_keycode (key));
} }
static void static void
eek_key_finalize (GObject *object) eek_key_finalize (GObject *object)
{ {
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(object); EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(object);
gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels; eek_symbol_matrix_free (priv->symbol_matrix);
g_slice_free1 (num_keysyms * sizeof (guint), priv->keysyms.data);
G_OBJECT_CLASS (eek_key_parent_class)->finalize (object); G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
} }
@ -251,21 +290,16 @@ eek_key_set_property (GObject *object,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
EekKeysymMatrix *matrix; EekSymbolMatrix *matrix;
gint column, row; gint column, row;
gint group, level;
g_return_if_fail (EEK_IS_KEY(object));
switch (prop_id) { switch (prop_id) {
case PROP_KEYCODE: case PROP_KEYCODE:
eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value)); eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
break; break;
case PROP_KEYSYMS: case PROP_SYMBOL_MATRIX:
matrix = g_value_get_boxed (value); matrix = g_value_get_boxed (value);
eek_key_set_keysyms (EEK_KEY(object), eek_key_set_symbol_matrix (EEK_KEY(object), matrix);
matrix->data,
matrix->num_groups,
matrix->num_levels);
break; break;
case PROP_COLUMN: case PROP_COLUMN:
eek_key_get_index (EEK_KEY(object), &column, &row); eek_key_get_index (EEK_KEY(object), &column, &row);
@ -275,18 +309,8 @@ eek_key_set_property (GObject *object,
eek_key_get_index (EEK_KEY(object), &column, &row); eek_key_get_index (EEK_KEY(object), &column, &row);
eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value)); eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value));
break; break;
case PROP_OUTLINE: case PROP_OREF:
eek_key_set_outline (EEK_KEY(object), g_value_get_pointer (value)); eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
break;
case PROP_GROUP:
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
eek_key_set_keysym_index (EEK_KEY(object), g_value_get_int (value),
level);
break;
case PROP_LEVEL:
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
eek_key_set_keysym_index (EEK_KEY(object), group,
g_value_get_int (value));
break; break;
default: default:
g_object_set_property (object, g_object_set_property (object,
@ -302,19 +326,16 @@ eek_key_get_property (GObject *object,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
EekKeysymMatrix matrix;
gint column, row; gint column, row;
gint group, level;
g_return_if_fail (EEK_IS_KEY(object)); g_return_if_fail (EEK_IS_KEY(object));
switch (prop_id) { switch (prop_id) {
case PROP_KEYCODE: case PROP_KEYCODE:
g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object))); g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
break; break;
case PROP_KEYSYMS: case PROP_SYMBOL_MATRIX:
eek_key_get_keysyms (EEK_KEY(object), &matrix.data, &matrix.num_groups, g_value_set_boxed (value,
&matrix.num_levels); eek_key_get_symbol_matrix (EEK_KEY(object)));
g_value_set_boxed (value, &matrix);
break; break;
case PROP_COLUMN: case PROP_COLUMN:
eek_key_get_index (EEK_KEY(object), &column, &row); eek_key_get_index (EEK_KEY(object), &column, &row);
@ -324,16 +345,8 @@ eek_key_get_property (GObject *object,
eek_key_get_index (EEK_KEY(object), &column, &row); eek_key_get_index (EEK_KEY(object), &column, &row);
g_value_set_int (value, row); g_value_set_int (value, row);
break; break;
case PROP_OUTLINE: case PROP_OREF:
g_value_set_pointer (value, eek_key_get_outline (EEK_KEY(object))); g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
break;
case PROP_GROUP:
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
g_value_set_int (value, group);
break;
case PROP_LEVEL:
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
g_value_set_int (value, level);
break; break;
default: default:
g_object_get_property (object, g_object_get_property (object,
@ -354,15 +367,13 @@ eek_key_class_init (EekKeyClass *klass)
klass->get_keycode = eek_key_real_get_keycode; klass->get_keycode = eek_key_real_get_keycode;
klass->set_keycode = eek_key_real_set_keycode; klass->set_keycode = eek_key_real_set_keycode;
klass->set_keysyms = eek_key_real_set_keysyms; klass->set_symbol_matrix = eek_key_real_set_symbol_matrix;
klass->get_keysyms = eek_key_real_get_keysyms; klass->get_symbol_matrix = eek_key_real_get_symbol_matrix;
klass->get_keysym = eek_key_real_get_keysym;
klass->set_index = eek_key_real_set_index; klass->set_index = eek_key_real_set_index;
klass->get_index = eek_key_real_get_index; klass->get_index = eek_key_real_get_index;
klass->set_outline = eek_key_real_set_outline; klass->set_oref = eek_key_real_set_oref;
klass->get_outline = eek_key_real_get_outline; klass->get_oref = eek_key_real_get_oref;
klass->set_keysym_index = eek_key_real_set_keysym_index; klass->is_pressed = eek_key_real_is_pressed;
klass->get_keysym_index = eek_key_real_get_keysym_index;
gobject_class->set_property = eek_key_set_property; gobject_class->set_property = eek_key_set_property;
gobject_class->get_property = eek_key_get_property; gobject_class->get_property = eek_key_get_property;
@ -385,16 +396,16 @@ eek_key_class_init (EekKeyClass *klass)
g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec); g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec);
/** /**
* EekKey:keysyms: * EekKey:symbol-matrix:
* *
* The symbol matrix of #EekKey. * The symbol matrix of #EekKey.
*/ */
pspec = g_param_spec_boxed ("keysyms", pspec = g_param_spec_boxed ("symbol-matrix",
"Keysyms", "Symbol matrix",
"Symbol matrix of the key", "Symbol matrix of the key",
EEK_TYPE_KEYSYM_MATRIX, EEK_TYPE_SYMBOL_MATRIX,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_KEYSYMS, pspec); g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec);
/** /**
* EekKey:column: * EekKey:column:
@ -421,52 +432,28 @@ eek_key_class_init (EekKeyClass *klass)
g_object_class_install_property (gobject_class, PROP_ROW, pspec); g_object_class_install_property (gobject_class, PROP_ROW, pspec);
/** /**
* EekKey:outline: * EekKey:oref:
* *
* The pointer to the outline shape of #EekKey. * The outline id of #EekKey.
*/ */
/* Use pointer instead of boxed to avoid copy, since we can pspec = g_param_spec_ulong ("oref",
assume that only a few outline shapes are used in a whole "Oref",
keyboard (unlike keysyms and bounds). */ "Outline id of the key",
pspec = g_param_spec_pointer ("outline", 0, G_MAXULONG, 0,
"Outline", G_PARAM_READWRITE);
"Pointer to outline shape of the key", g_object_class_install_property (gobject_class, PROP_OREF, pspec);
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_OUTLINE, pspec);
/**
* EekKey:group:
*
* The column index of #EekKey in the symbol matrix #EekKey:keysyms.
*/
pspec = g_param_spec_int ("group",
"Group",
"Current group of the key",
0, 64, 0,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_GROUP, pspec);
/**
* EekKey:level:
*
* The row index of #EekKey in the symbol matrix #EekKey:keysyms.
*/
pspec = g_param_spec_int ("level",
"Level",
"Current level of the key",
0, 3, 0,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_LEVEL, pspec);
/** /**
* EekKey::pressed: * EekKey::pressed:
* @key: an #EekKey * @key: an #EekKey
* *
* The ::pressed signal is emitted each time @key is shifted to * The ::pressed signal is emitted each time @key is shifted to
* the pressed state. * the pressed state. The class handler runs before signal
* handlers to allow signal handlers to read the status of @key
* with eek_key_is_pressed().
*/ */
signals[PRESSED] = signals[PRESSED] =
g_signal_new ("pressed", g_signal_new (I_("pressed"),
G_TYPE_FROM_CLASS(gobject_class), G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekKeyClass, pressed), G_STRUCT_OFFSET(EekKeyClass, pressed),
@ -483,9 +470,9 @@ eek_key_class_init (EekKeyClass *klass)
* the released state. * the released state.
*/ */
signals[RELEASED] = signals[RELEASED] =
g_signal_new ("released", g_signal_new (I_("released"),
G_TYPE_FROM_CLASS(gobject_class), G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekKeyClass, released), G_STRUCT_OFFSET(EekKeyClass, released),
NULL, NULL,
NULL, NULL,
@ -500,10 +487,9 @@ eek_key_init (EekKey *self)
priv = self->priv = EEK_KEY_GET_PRIVATE(self); priv = self->priv = EEK_KEY_GET_PRIVATE(self);
priv->keycode = 0; priv->keycode = 0;
memset (&priv->keysyms, 0, sizeof priv->keysyms); priv->symbol_matrix = eek_symbol_matrix_new (0, 0);
priv->column = priv->row = 0; priv->column = priv->row = 0;
priv->outline = NULL; priv->oref = 0;
priv->group = priv->level = 0;
} }
/** /**
@ -511,7 +497,11 @@ eek_key_init (EekKey *self)
* @key: an #EekKey * @key: an #EekKey
* @keycode: keycode * @keycode: keycode
* *
* Set keycode of @key to @keycode. * Set the keycode of @key to @keycode. Since typically the keycode
* value is used to find a key in a keyboard by calling
* eek_keyboard_find_key_by_keycode, it is not necessarily the same as
* the X keycode but it should be unique in the keyboard @key belongs
* to.
*/ */
void void
eek_key_set_keycode (EekKey *key, eek_key_set_keycode (EekKey *key,
@ -536,59 +526,152 @@ eek_key_get_keycode (EekKey *key)
} }
/** /**
* eek_key_set_keysyms: * eek_key_set_symbol_matrix:
* @key: an #EekKey * @key: an #EekKey
* @keysyms: symbol matrix of @key * @matrix: an #EekSymbolMatrix
* @num_groups: number of groups (rows) of @keysyms
* @num_levels: number of levels (columns) of @keysyms
* *
* Set the symbol matrix of @key to @keysyms. The length of @keysyms * Set the symbol matrix of @key to @matrix.
* is @num_groups * @num_levels.
*/ */
void void
eek_key_set_keysyms (EekKey *key, eek_key_set_symbol_matrix (EekKey *key,
guint *keysyms, EekSymbolMatrix *matrix)
gint num_groups,
gint num_levels)
{ {
g_return_if_fail (EEK_IS_KEY(key)); g_return_if_fail (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->set_keysyms (key, keysyms, num_groups, num_levels); EEK_KEY_GET_CLASS(key)->set_symbol_matrix (key, matrix);
} }
/** /**
* eek_key_get_keysyms: * eek_key_get_symbol_matrix:
* @key: an #EekKey * @key: an #EekKey
* @keysyms: pointer where symbol matrix of @key will be stored
* @num_groups: pointer where the number of groups (rows) of @keysyms
* will be stored
* @num_levels: pointer where the number of levels (columns) of
* @keysyms will be stored
* *
* Get the symbol matrix of @key. If either @keysyms, @num_groups, or * Get the symbol matrix of @key.
* @num_levels are NULL, this function does not try to get the value. * Returns: #EekSymbolMatrix or %NULL
*/ */
void EekSymbolMatrix *
eek_key_get_keysyms (EekKey *key, eek_key_get_symbol_matrix (EekKey *key)
guint **keysyms,
gint *num_groups,
gint *num_levels)
{ {
g_return_if_fail (EEK_IS_KEY(key)); g_return_val_if_fail (EEK_IS_KEY(key), NULL);
EEK_KEY_GET_CLASS(key)->get_keysyms (key, keysyms, num_groups, num_levels); return EEK_KEY_GET_CLASS(key)->get_symbol_matrix (key);
} }
/** /**
* eek_key_get_keysym: * eek_key_get_symbol:
* @key: an #EekKey * @key: an #EekKey
* @returns: (transfer none): the current #EekSymbol or %NULL on failure
* *
* Get the current symbol of @key. * Get the current symbol of @key.
* Returns: a symbol or %EEK_INVALID_KEYSYM on failure
*/ */
guint EekSymbol *
eek_key_get_keysym (EekKey *key) eek_key_get_symbol (EekKey *key)
{ {
g_return_val_if_fail (EEK_IS_KEY(key), EEK_INVALID_KEYSYM); return eek_key_get_symbol_with_fallback (key, 0, 0);
return EEK_KEY_GET_CLASS(key)->get_keysym (key); }
/**
* eek_key_get_symbol_with_fallback:
* @key: an #EekKey
* @fallback_group: fallback group index
* @fallback_level: fallback level index
* @returns: (transfer none): the current #EekSymbol or %NULL on failure
*
* Get the current symbol of @key.
*/
EekSymbol *
eek_key_get_symbol_with_fallback (EekKey *key,
gint fallback_group,
gint fallback_level)
{
gint group, level;
g_return_val_if_fail (EEK_IS_KEY (key), NULL);
g_return_val_if_fail (fallback_group >= 0, NULL);
g_return_val_if_fail (fallback_level >= 0, NULL);
eek_element_get_symbol_index (EEK_ELEMENT(key), &group, &level);
if (group < 0 || level < 0) {
EekElement *section;
section = eek_element_get_parent (EEK_ELEMENT(key));
g_return_val_if_fail (EEK_IS_SECTION (section), NULL);
if (group < 0)
group = eek_element_get_group (section);
if (level < 0)
level = eek_element_get_level (section);
if (group < 0 || level < 0) {
EekElement *keyboard;
keyboard = eek_element_get_parent (section);
g_return_val_if_fail (EEK_IS_KEYBOARD (keyboard), NULL);
if (group < 0)
group = eek_element_get_group (keyboard);
if (level < 0)
level = eek_element_get_level (keyboard);
}
}
return eek_key_get_symbol_at_index (key,
group,
level,
fallback_group,
fallback_level);
}
/**
* eek_key_get_symbol_at_index:
* @key: an #EekKey
* @group: group index of the symbol matrix
* @level: level index of the symbol matrix
* @fallback_group: fallback group index
* @fallback_level: fallback level index
* @returns: (transfer none): an #EekSymbol at (@group, @level), or %NULL
*
* Get the symbol at (@group, @level) in the symbol matrix of @key.
*/
EekSymbol *
eek_key_get_symbol_at_index (EekKey *key,
gint group,
gint level,
gint fallback_group,
gint fallback_level)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(key);
gint num_symbols;
g_return_val_if_fail (fallback_group >= 0, NULL);
g_return_val_if_fail (fallback_level >= 0, NULL);
if (group < 0)
group = fallback_group;
if (level < 0)
level = fallback_level;
if (!priv->symbol_matrix)
return NULL;
num_symbols = priv->symbol_matrix->num_groups *
priv->symbol_matrix->num_levels;
if (num_symbols == 0)
return NULL;
if (group >= priv->symbol_matrix->num_groups) {
if (fallback_group < 0)
return NULL;
group = fallback_group;
}
if (level >= priv->symbol_matrix->num_levels) {
if (fallback_level < 0)
return NULL;
level = fallback_level;
}
return priv->symbol_matrix->data[group * priv->symbol_matrix->num_levels +
level];
} }
/** /**
@ -597,8 +680,7 @@ eek_key_get_keysym (EekKey *key)
* @column: column index of @key in #EekSection * @column: column index of @key in #EekSection
* @row: row index of @key in #EekSection * @row: row index of @key in #EekSection
* *
* Set the index of @key (i.e. logical location of @key in * Set the location of @key in #EekSection with @column and @row.
* #EekSection) to @column and @row.
*/ */
void void
eek_key_set_index (EekKey *key, eek_key_set_index (EekKey *key,
@ -615,8 +697,7 @@ eek_key_set_index (EekKey *key,
* @column: pointer where the column index of @key in #EekSection will be stored * @column: pointer where the column index of @key in #EekSection will be stored
* @row: pointer where the row index of @key in #EekSection will be stored * @row: pointer where the row index of @key in #EekSection will be stored
* *
* Get the index of @key (i.e. logical location of @key in * Get the location of @key in #EekSection.
* #EekSection).
*/ */
void void
eek_key_get_index (EekKey *key, eek_key_get_index (EekKey *key,
@ -628,66 +709,43 @@ eek_key_get_index (EekKey *key,
} }
/** /**
* eek_key_set_outline: * eek_key_set_oref:
* @key: an #EekKey * @key: an #EekKey
* @outline: outline of @key * @oref: outline id of @key
* *
* Set the outline shape of @key to @outline. * Set the outline id of @key to @oref.
*/ */
void void
eek_key_set_outline (EekKey *key, eek_key_set_oref (EekKey *key,
EekOutline *outline) gulong oref)
{ {
g_return_if_fail (EEK_IS_KEY(key)); g_return_if_fail (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->set_outline (key, outline); EEK_KEY_GET_CLASS(key)->set_oref (key, oref);
} }
/** /**
* eek_key_get_outline: * eek_key_get_oref:
* @key: an #EekKey * @key: an #EekKey
* *
* Get the outline shape of @key. * Get the outline id of @key.
* Returns: an #EekOutline pointer or NULL on failure * Returns: a non-zero unsigned integer on success, 0 if the id is not set
*/ */
EekOutline * gulong
eek_key_get_outline (EekKey *key) eek_key_get_oref (EekKey *key)
{ {
g_return_val_if_fail (EEK_IS_KEY (key), NULL); g_return_val_if_fail (EEK_IS_KEY (key), 0);
return EEK_KEY_GET_CLASS(key)->get_outline (key); return EEK_KEY_GET_CLASS(key)->get_oref (key);
} }
/** /**
* eek_key_set_keysym_index: * eek_key_is_pressed:
* @key: an #EekKey * @key: an #EekKey
* @group: group (row) index of @key
* @level: level (column) index of @key
* *
* Set the current group and/or level index of @key in its symbol * Return %TRUE if key is marked as pressed.
* matrix to @group and @level.
*/ */
void gboolean
eek_key_set_keysym_index (EekKey *key, eek_key_is_pressed (EekKey *key)
gint group,
gint level)
{ {
g_return_if_fail (EEK_IS_KEY(key)); g_assert (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->set_keysym_index (key, group, level); return EEK_KEY_GET_CLASS(key)->is_pressed (key);
}
/**
* eek_key_get_keysym_index:
* @key: an #EekKey
* @group: pointer where group (row) index of @key will be stored
* @level: pointer where level (column) index of @key will be stored
*
* Get the current group and/or level index of @key in its symbol
* matrix.
*/
void
eek_key_get_keysym_index (EekKey *key,
gint *group,
gint *level)
{
g_return_if_fail (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->get_keysym_index (key, group, level);
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -48,19 +48,17 @@ struct _EekKey
* EekKeyClass: * EekKeyClass:
* @set_keycode: virtual function for setting keycode of the key * @set_keycode: virtual function for setting keycode of the key
* @get_keycode: virtual function for getting keycode of the key * @get_keycode: virtual function for getting keycode of the key
* @set_keysyms: virtual function for setting symbol matrix of the key * @set_symbol_matrix: virtual function for setting symbol matrix of the key
* @get_keysyms: virtual function for getting symbol matrix of the key * @get_symbol_matrix: virtual function for getting symbol matrix of the key
* @get_keysym: virtual function for getting the current symbol of the key
* @set_index: virtual function for setting position of the key in the * @set_index: virtual function for setting position of the key in the
* section * section
* @get_index: virtual function for getting position of the key in the * @get_index: virtual function for getting position of the key in the
* section * section
* @set_outline: virtual function for setting outline shape of the key * @set_oref: virtual function for setting outline id of the key
* @get_outline: virtual function for getting outline shape of the key * @get_oref: virtual function for getting outline id of the key
* @set_keysym_index: virtual function for setting group and level of the key
* @get_keysym_index: virtual function for getting group and level of the key
* @pressed: class handler for #EekKey::pressed signal * @pressed: class handler for #EekKey::pressed signal
* @released: class handler for #EekKey::released signal * @released: class handler for #EekKey::released signal
* @is_pressed: virtual function for getting whether the key is pressed
*/ */
struct _EekKeyClass struct _EekKeyClass
{ {
@ -68,74 +66,66 @@ struct _EekKeyClass
EekElementClass parent_class; EekElementClass parent_class;
/*< public >*/ /*< public >*/
void (* set_keycode) (EekKey *self, void (* set_keycode) (EekKey *self,
guint keycode); guint keycode);
guint (* get_keycode) (EekKey *self); guint (* get_keycode) (EekKey *self);
void (* set_keysyms) (EekKey *self, void (* set_symbol_matrix) (EekKey *self,
guint *keysyms, EekSymbolMatrix *matrix);
gint num_groups, EekSymbolMatrix *(* get_symbol_matrix) (EekKey *self);
gint num_levels);
void (* get_keysyms) (EekKey *self,
guint **keysyms,
gint *num_groups,
gint *num_levels);
guint (* get_keysym) (EekKey *self);
void (* set_index) (EekKey *self, void (* set_index) (EekKey *self,
gint column, gint column,
gint row); gint row);
void (* get_index) (EekKey *self, void (* get_index) (EekKey *self,
gint *column, gint *column,
gint *row); gint *row);
void (* set_outline) (EekKey *self, void (* set_oref) (EekKey *self,
EekOutline *outline); gulong oref);
EekOutline *(* get_outline) (EekKey *self); gulong (* get_oref) (EekKey *self);
void (* set_keysym_index) (EekKey *self, gboolean (* is_pressed) (EekKey *self);
gint group,
gint level);
void (* get_keysym_index) (EekKey *self,
gint *group,
gint *level);
/* signals */ /* signals */
void (* pressed) (EekKey *key); void (* pressed) (EekKey *key);
void (* released) (EekKey *key); void (* released) (EekKey *key);
/*< private >*/
/* padding */
gpointer pdummy[24];
}; };
GType eek_key_get_type (void) G_GNUC_CONST; GType eek_key_get_type (void) G_GNUC_CONST;
void eek_key_set_keycode (EekKey *key, void eek_key_set_keycode (EekKey *key,
guint keycode); guint keycode);
guint eek_key_get_keycode (EekKey *key); guint eek_key_get_keycode (EekKey *key);
void eek_key_set_keysyms (EekKey *key, void eek_key_set_symbol_matrix (EekKey *key,
guint *keysyms, EekSymbolMatrix *matrix);
gint num_groups, EekSymbolMatrix *eek_key_get_symbol_matrix (EekKey *key);
gint num_levels); EekSymbol *eek_key_get_symbol (EekKey *key);
void eek_key_get_keysyms (EekKey *key, EekSymbol *eek_key_get_symbol_with_fallback
guint **keysyms, (EekKey *key,
gint *num_groups, gint fallback_group,
gint *num_levels); gint fallback_level);
guint eek_key_get_keysym (EekKey *key); EekSymbol *eek_key_get_symbol_at_index (EekKey *key,
gint group,
gint level,
gint fallback_group,
gint fallback_level);
void eek_key_set_index (EekKey *key, void eek_key_set_index (EekKey *key,
gint column, gint column,
gint row); gint row);
void eek_key_get_index (EekKey *key, void eek_key_get_index (EekKey *key,
gint *column, gint *column,
gint *row); gint *row);
void eek_key_set_outline (EekKey *key, void eek_key_set_oref (EekKey *key,
EekOutline *outline); gulong oref);
EekOutline *eek_key_get_outline (EekKey *key); gulong eek_key_get_oref (EekKey *key);
void eek_key_set_keysym_index (EekKey *key, gboolean eek_key_is_pressed (EekKey *key);
gint group,
gint level);
void eek_key_get_keysym_index (EekKey *key,
gint *group,
gint *level);
G_END_DECLS G_END_DECLS
#endif /* EEK_KEY_H */ #endif /* EEK_KEY_H */

230
eek/eek-keyboard-drawing.c Normal file
View File

@ -0,0 +1,230 @@
/*
* Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <math.h>
#include <pango/pangocairo.h>
#include "eek-types.h"
static gdouble
length (gdouble x, gdouble y)
{
return sqrt (x * x + y * y);
}
static gdouble
point_line_distance (gdouble ax, gdouble ay, gdouble nx, gdouble ny)
{
return ax * nx + ay * ny;
}
static void
normal_form (gdouble ax, gdouble ay,
gdouble bx, gdouble by,
gdouble * nx, gdouble * ny, gdouble * d)
{
gdouble l;
*nx = by - ay;
*ny = ax - bx;
l = length (*nx, *ny);
*nx /= l;
*ny /= l;
*d = point_line_distance (ax, ay, *nx, *ny);
}
static void
inverse (gdouble a, gdouble b, gdouble c, gdouble d,
gdouble * e, gdouble * f, gdouble * g, gdouble * h)
{
gdouble det;
det = a * d - b * c;
*e = d / det;
*f = -b / det;
*g = -c / det;
*h = a / det;
}
static void
multiply (gdouble a, gdouble b, gdouble c, gdouble d,
gdouble e, gdouble f, gdouble * x, gdouble * y)
{
*x = a * e + b * f;
*y = c * e + d * f;
}
static void
intersect (gdouble n1x, gdouble n1y, gdouble d1,
gdouble n2x, gdouble n2y, gdouble d2, gdouble * x, gdouble * y)
{
gdouble e, f, g, h;
inverse (n1x, n1y, n2x, n2y, &e, &f, &g, &h);
multiply (e, f, g, h, d1, d2, x, y);
}
/* draw an angle from the current point to b and then to c,
* with a rounded corner of the given radius.
*/
static void
rounded_corner (cairo_t * cr,
gdouble bx, gdouble by,
gdouble cx, gdouble cy, gdouble radius)
{
gdouble ax, ay;
gdouble n1x, n1y, d1;
gdouble n2x, n2y, d2;
gdouble pd1, pd2;
gdouble ix, iy;
gdouble dist1, dist2;
gdouble nx, ny, d;
gdouble a1x, a1y, c1x, c1y;
gdouble phi1, phi2;
cairo_get_current_point (cr, &ax, &ay);
#ifdef KBDRAW_DEBUG
printf (" current point: (%f, %f), radius %f:\n", ax, ay,
radius);
#endif
/* make sure radius is not too large */
dist1 = length (bx - ax, by - ay);
dist2 = length (cx - bx, cy - by);
radius = MIN (radius, MIN (dist1, dist2));
/* construct normal forms of the lines */
normal_form (ax, ay, bx, by, &n1x, &n1y, &d1);
normal_form (bx, by, cx, cy, &n2x, &n2y, &d2);
/* find which side of the line a,b the point c is on */
if (point_line_distance (cx, cy, n1x, n1y) < d1)
pd1 = d1 - radius;
else
pd1 = d1 + radius;
/* find which side of the line b,c the point a is on */
if (point_line_distance (ax, ay, n2x, n2y) < d2)
pd2 = d2 - radius;
else
pd2 = d2 + radius;
/* intersect the parallels to find the center of the arc */
intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy);
nx = (bx - ax) / dist1;
ny = (by - ay) / dist1;
d = point_line_distance (ix, iy, nx, ny);
/* a1 is the point on the line a-b where the arc starts */
intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y);
nx = (cx - bx) / dist2;
ny = (cy - by) / dist2;
d = point_line_distance (ix, iy, nx, ny);
/* c1 is the point on the line b-c where the arc ends */
intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y);
/* determine the first angle */
if (a1x - ix == 0)
phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
else if (a1x - ix > 0)
phi1 = atan ((a1y - iy) / (a1x - ix));
else
phi1 = M_PI + atan ((a1y - iy) / (a1x - ix));
/* determine the second angle */
if (c1x - ix == 0)
phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
else if (c1x - ix > 0)
phi2 = atan ((c1y - iy) / (c1x - ix));
else
phi2 = M_PI + atan ((c1y - iy) / (c1x - ix));
/* compute the difference between phi2 and phi1 mod 2pi */
d = phi2 - phi1;
while (d < 0)
d += 2 * M_PI;
while (d > 2 * M_PI)
d -= 2 * M_PI;
#ifdef KBDRAW_DEBUG
printf (" line 1 to: (%f, %f):\n", a1x, a1y);
#endif
if (!(isnan (a1x) || isnan (a1y)))
cairo_line_to (cr, a1x, a1y);
/* pick the short arc from phi1 to phi2 */
if (d < M_PI)
cairo_arc (cr, ix, iy, radius, phi1, phi2);
else
cairo_arc_negative (cr, ix, iy, radius, phi1, phi2);
#ifdef KBDRAW_DEBUG
printf (" line 2 to: (%f, %f):\n", cx, cy);
#endif
cairo_line_to (cr, cx, cy);
}
/* renamed from rounded_polygon, use EekPoint instead of GdkPoint not
to depend on GTK+, and exported */
void
_eek_rounded_polygon (cairo_t *cr,
gdouble radius,
EekPoint *points,
gint num_points)
{
gint i, j;
cairo_move_to (cr,
(gdouble) (points[num_points - 1].x +
points[0].x) / 2,
(gdouble) (points[num_points - 1].y +
points[0].y) / 2);
#ifdef KBDRAW_DEBUG
printf (" rounded polygon of radius %f:\n", radius);
#endif
for (i = 0; i < num_points; i++) {
j = (i + 1) % num_points;
rounded_corner (cr, (gdouble) points[i].x,
(gdouble) points[i].y,
(gdouble) (points[i].x + points[j].x) / 2,
(gdouble) (points[i].y + points[j].y) / 2,
radius);
#ifdef KBDRAW_DEBUG
printf (" corner (%d, %d) -> (%d, %d):\n",
points[i].x, points[i].y, points[j].x,
points[j].y);
#endif
};
cairo_close_path (cr);
}

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -34,11 +34,13 @@
#include "eek-keyboard.h" #include "eek-keyboard.h"
#include "eek-section.h" #include "eek-section.h"
#include "eek-key.h" #include "eek-key.h"
#include "eek-symbol.h"
#include "eek-serializable.h"
enum { enum {
PROP_0, PROP_0,
PROP_GROUP, PROP_LAYOUT,
PROP_LEVEL, PROP_MODIFIER_BEHAVIOR,
PROP_LAST PROP_LAST
}; };
@ -50,7 +52,11 @@ enum {
static guint signals[LAST_SIGNAL] = { 0, }; static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER); static void eek_serializable_iface_init (EekSerializableIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
eek_serializable_iface_init));
#define EEK_KEYBOARD_GET_PRIVATE(obj) \ #define EEK_KEYBOARD_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate))
@ -58,84 +64,153 @@ G_DEFINE_TYPE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
struct _EekKeyboardPrivate struct _EekKeyboardPrivate
{ {
gint group;
gint level;
EekLayout *layout; EekLayout *layout;
gboolean is_realized; EekModifierBehavior modifier_behavior;
EekModifierType modifiers;
GArray *outline_array;
/* modifiers dynamically assigned at run time */
EekModifierType num_lock_mask;
EekModifierType alt_gr_mask;
}; };
struct keysym_index { static EekSerializableIface *eek_keyboard_parent_serializable_iface;
gint group;
gint level;
};
static void static GVariant *_g_variant_new_outline (EekOutline *outline);
set_keysym_index_for_key (EekElement *element, static EekOutline *_g_variant_get_outline (GVariant *variant);
gpointer user_data)
static GVariant *
_g_variant_new_outline (EekOutline *outline)
{ {
struct keysym_index *ki; GVariantBuilder builder, array;
gint i;
g_return_if_fail (EEK_IS_KEY(element)); g_variant_builder_init (&builder, G_VARIANT_TYPE ("(div)"));
g_variant_builder_add (&builder, "d", outline->corner_radius);
g_variant_builder_add (&builder, "i", outline->num_points);
g_variant_builder_init (&array, G_VARIANT_TYPE ("a(dd)"));
for (i = 0; i < outline->num_points; i++)
g_variant_builder_add (&array,
"(dd)",
outline->points[i].x,
outline->points[i].y);
g_variant_builder_add (&builder, "v", g_variant_builder_end (&array));
return g_variant_builder_end (&builder);
}
ki = user_data; static EekOutline *
eek_key_set_keysym_index (EEK_KEY(element), ki->group, ki->level); _g_variant_get_outline (GVariant *variant)
{
EekOutline *outline;
GVariant *array;
GVariantIter iter;
gdouble x, y;
gint i;
outline = g_slice_new0 (EekOutline);
g_variant_get_child (variant, 0, "d", &outline->corner_radius);
g_variant_get_child (variant, 1, "i", &outline->num_points);
outline->points = g_slice_alloc0 (sizeof (EekPoint) * outline->num_points);
g_variant_get_child (variant, 2, "v", &array);
g_variant_iter_init (&iter, array);
for (i = 0; i < outline->num_points; i++) {
if (!g_variant_iter_next (&iter, "(dd)", &x, &y)) {
eek_outline_free (outline);
g_return_val_if_reached (NULL);
}
outline->points[i].x = x;
outline->points[i].y = y;
}
return outline;
} }
static void static void
set_keysym_index_for_section (EekElement *element, eek_keyboard_real_serialize (EekSerializable *self,
gpointer user_data) GVariantBuilder *builder)
{
eek_container_foreach_child (EEK_CONTAINER(element),
set_keysym_index_for_key,
user_data);
}
static void
eek_keyboard_real_set_keysym_index (EekKeyboard *self,
gint group,
gint level)
{ {
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self); EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
struct keysym_index ki; GVariantBuilder array;
guint i;
ki.group = priv->group = group; eek_keyboard_parent_serializable_iface->serialize (self, builder);
ki.level = priv->level = level;
eek_container_foreach_child (EEK_CONTAINER(self), g_variant_builder_init (&array, G_VARIANT_TYPE ("av"));
set_keysym_index_for_section, for (i = 0; i < priv->outline_array->len; i++) {
&ki); EekOutline *outline =
eek_keyboard_get_outline (EEK_KEYBOARD(self), i + 1);
g_variant_builder_add (&array, "v",
_g_variant_new_outline (outline));
}
g_variant_builder_add (builder, "v", g_variant_builder_end (&array));
g_variant_builder_add (builder, "u", priv->num_lock_mask);
} }
void static gsize
eek_keyboard_real_get_keysym_index (EekKeyboard *self, eek_keyboard_real_deserialize (EekSerializable *self,
gint *group, GVariant *variant,
gint *level) gsize index)
{ {
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self); EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
GVariant *array, *outline;
GVariantIter iter;
g_return_if_fail (group || level); index = eek_keyboard_parent_serializable_iface->deserialize (self,
if (group) variant,
*group = priv->group; index);
if (level)
*level = priv->level; g_variant_get_child (variant, index++, "v", &array);
g_variant_iter_init (&iter, array);
while (g_variant_iter_next (&iter, "v", &outline)) {
EekOutline *_outline = _g_variant_get_outline (outline);
g_array_append_val (priv->outline_array, *_outline);
/* don't use eek_outline_free here, so as to keep _outline->points */
g_slice_free (EekOutline, _outline);
}
g_variant_get_child (variant, index++, "u", &priv->num_lock_mask);
return index;
} }
static void static void
key_pressed_event (EekSection *section, eek_serializable_iface_init (EekSerializableIface *iface)
EekKey *key, {
EekKeyboard *keyboard) eek_keyboard_parent_serializable_iface =
g_type_interface_peek_parent (iface);
iface->serialize = eek_keyboard_real_serialize;
iface->deserialize = eek_keyboard_real_deserialize;
}
static void
on_key_pressed (EekSection *section,
EekKey *key,
EekKeyboard *keyboard)
{ {
g_signal_emit_by_name (keyboard, "key-pressed", key); g_signal_emit_by_name (keyboard, "key-pressed", key);
} }
static void static void
key_released_event (EekSection *section, on_key_released (EekSection *section,
EekKey *key, EekKey *key,
EekKeyboard *keyboard) EekKeyboard *keyboard)
{ {
g_signal_emit_by_name (keyboard, "key-released", key); g_signal_emit_by_name (keyboard, "key-released", key);
} }
static void
on_symbol_index_changed (EekSection *section,
gint group,
gint level,
EekKeyboard *keyboard)
{
g_signal_emit_by_name (keyboard, "symbol-index-changed", group, level);
}
static EekSection * static EekSection *
eek_keyboard_real_create_section (EekKeyboard *self) eek_keyboard_real_create_section (EekKeyboard *self)
{ {
@ -144,64 +219,21 @@ eek_keyboard_real_create_section (EekKeyboard *self)
section = g_object_new (EEK_TYPE_SECTION, NULL); section = g_object_new (EEK_TYPE_SECTION, NULL);
g_return_val_if_fail (section, NULL); g_return_val_if_fail (section, NULL);
g_signal_connect (section, "key-pressed",
G_CALLBACK(key_pressed_event), self);
g_signal_connect (section, "key-released",
G_CALLBACK(key_released_event), self);
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
EEK_ELEMENT(section)); EEK_ELEMENT(section));
return section; return section;
} }
static void struct _FindKeyByKeycodeCallbackData {
on_group_changed (EekLayout *layout,
gint new_group,
gpointer user_data)
{
EekKeyboard *keyboard = user_data;
gint group, level;
eek_keyboard_get_keysym_index (keyboard, &group, &level);
eek_keyboard_set_keysym_index (keyboard, new_group, level);
}
static void
eek_keyboard_real_set_layout (EekKeyboard *self,
EekLayout *layout)
{
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (EEK_IS_LAYOUT(layout));
priv->layout = layout;
g_object_ref_sink (priv->layout);
g_signal_connect (priv->layout, "group_changed",
G_CALLBACK(on_group_changed), self);
}
static void
eek_keyboard_real_realize (EekKeyboard *self)
{
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (priv->layout);
g_return_if_fail (!priv->is_realized);
EEK_LAYOUT_GET_IFACE(priv->layout)->apply (priv->layout, self);
/* apply the initial group setting */
on_group_changed (priv->layout, eek_layout_get_group (priv->layout), self);
priv->is_realized = TRUE;
}
struct _FkbkData {
EekKey *key; EekKey *key;
guint keycode; guint keycode;
}; };
typedef struct _FkbkData FkbkData; typedef struct _FindKeyByKeycodeCallbackData FindKeyByKeycodeCallbackData;
static gint static gint
compare_section_by_keycode (EekElement *element, gpointer user_data) find_key_by_keycode_section_callback (EekElement *element, gpointer user_data)
{ {
FkbkData *data = user_data; FindKeyByKeycodeCallbackData *data = user_data;
data->key = eek_section_find_key_by_keycode (EEK_SECTION(element), data->key = eek_section_find_key_by_keycode (EEK_SECTION(element),
data->keycode); data->keycode);
@ -214,49 +246,33 @@ static EekKey *
eek_keyboard_real_find_key_by_keycode (EekKeyboard *self, eek_keyboard_real_find_key_by_keycode (EekKeyboard *self,
guint keycode) guint keycode)
{ {
FkbkData data; FindKeyByKeycodeCallbackData data;
data.keycode = keycode; data.keycode = keycode;
if (eek_container_find (EEK_CONTAINER(self), if (eek_container_find (EEK_CONTAINER(self),
compare_section_by_keycode, find_key_by_keycode_section_callback,
&data)) &data))
return data.key; return data.key;
return NULL; return NULL;
} }
static void static void
eek_keyboard_dispose (GObject *object) eek_keyboard_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{ {
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object); EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
if (priv->layout) {
g_object_unref (priv->layout);
priv->layout = NULL;
}
G_OBJECT_CLASS(eek_keyboard_parent_class)->dispose (object);
}
static void
eek_keyboard_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
gint group, level;
g_return_if_fail (EEK_IS_KEYBOARD(object));
switch (prop_id) { switch (prop_id) {
case PROP_GROUP: case PROP_LAYOUT:
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level); priv->layout = g_value_get_object (value);
eek_keyboard_set_keysym_index (EEK_KEYBOARD(object), if (priv->layout)
g_value_get_int (value), g_object_ref (priv->layout);
level);
break; break;
case PROP_LEVEL: case PROP_MODIFIER_BEHAVIOR:
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level); eek_keyboard_set_modifier_behavior (EEK_KEYBOARD(object),
eek_keyboard_set_keysym_index (EEK_KEYBOARD(object), g_value_get_int (value));
group,
g_value_get_int (value));
break; break;
default: default:
g_object_set_property (object, g_object_set_property (object,
@ -272,17 +288,15 @@ eek_keyboard_get_property (GObject *object,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
gint group, level; EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
g_return_if_fail (EEK_IS_KEYBOARD(object));
switch (prop_id) { switch (prop_id) {
case PROP_GROUP: case PROP_LAYOUT:
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level); g_value_set_object (value, priv->layout);
g_value_set_int (value, group);
break; break;
case PROP_LEVEL: case PROP_MODIFIER_BEHAVIOR:
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &level, &level); g_value_set_int (value,
g_value_set_int (value, level); eek_keyboard_get_modifier_behavior (EEK_KEYBOARD(object)));
break; break;
default: default:
g_object_get_property (object, g_object_get_property (object,
@ -292,52 +306,167 @@ eek_keyboard_get_property (GObject *object,
} }
} }
static void
set_level_from_modifiers (EekKeyboard *self)
{
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
gint level = 0;
if (priv->modifiers & priv->alt_gr_mask)
level |= 2;
if (priv->modifiers & EEK_SHIFT_MASK)
level |= 1;
eek_element_set_level (EEK_ELEMENT(self), level);
}
static void
eek_keyboard_real_key_pressed (EekKeyboard *self,
EekKey *key)
{
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
EekSymbol *symbol;
EekModifierType modifier;
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
if (!symbol)
return;
modifier = eek_symbol_get_modifier_mask (symbol);
if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
priv->modifiers |= modifier;
set_level_from_modifiers (self);
}
}
static void
eek_keyboard_real_key_released (EekKeyboard *self,
EekKey *key)
{
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
EekSymbol *symbol;
EekModifierType modifier;
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
if (!symbol)
return;
modifier = eek_symbol_get_modifier_mask (symbol);
switch (priv->modifier_behavior) {
case EEK_MODIFIER_BEHAVIOR_NONE:
priv->modifiers &= ~modifier;
break;
case EEK_MODIFIER_BEHAVIOR_LOCK:
priv->modifiers ^= modifier;
break;
case EEK_MODIFIER_BEHAVIOR_LATCH:
priv->modifiers = (priv->modifiers ^ modifier) & modifier;
break;
}
set_level_from_modifiers (self);
}
static void
eek_keyboard_dispose (GObject *object)
{
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
if (priv->layout) {
g_object_unref (priv->layout);
priv->layout = NULL;
}
G_OBJECT_CLASS (eek_keyboard_parent_class)->dispose (object);
}
static void
eek_keyboard_finalize (GObject *object)
{
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
gint i;
for (i = 0; i < priv->outline_array->len; i++) {
EekOutline *outline = &g_array_index (priv->outline_array,
EekOutline,
i);
g_slice_free1 (sizeof (EekPoint) * outline->num_points,
outline->points);
}
g_array_free (priv->outline_array, TRUE);
G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object);
}
static void
eek_keyboard_real_child_added (EekContainer *self,
EekElement *element)
{
g_signal_connect (element, "key-pressed",
G_CALLBACK(on_key_pressed), self);
g_signal_connect (element, "key-released",
G_CALLBACK(on_key_released), self);
g_signal_connect (element, "symbol-index-changed",
G_CALLBACK(on_symbol_index_changed), self);
}
static void
eek_keyboard_real_child_removed (EekContainer *self,
EekElement *element)
{
g_signal_handlers_disconnect_by_func (element, on_key_pressed, self);
g_signal_handlers_disconnect_by_func (element, on_key_released, self);
}
static void static void
eek_keyboard_class_init (EekKeyboardClass *klass) eek_keyboard_class_init (EekKeyboardClass *klass)
{ {
EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec; GParamSpec *pspec;
g_type_class_add_private (gobject_class, g_type_class_add_private (gobject_class,
sizeof (EekKeyboardPrivate)); sizeof (EekKeyboardPrivate));
klass->set_keysym_index = eek_keyboard_real_set_keysym_index;
klass->get_keysym_index = eek_keyboard_real_get_keysym_index;
klass->create_section = eek_keyboard_real_create_section; klass->create_section = eek_keyboard_real_create_section;
klass->set_layout = eek_keyboard_real_set_layout;
klass->realize = eek_keyboard_real_realize;
klass->find_key_by_keycode = eek_keyboard_real_find_key_by_keycode; klass->find_key_by_keycode = eek_keyboard_real_find_key_by_keycode;
/* signals */
klass->key_pressed = eek_keyboard_real_key_pressed;
klass->key_released = eek_keyboard_real_key_released;
container_class->child_added = eek_keyboard_real_child_added;
container_class->child_removed = eek_keyboard_real_child_removed;
gobject_class->get_property = eek_keyboard_get_property; gobject_class->get_property = eek_keyboard_get_property;
gobject_class->set_property = eek_keyboard_set_property; gobject_class->set_property = eek_keyboard_set_property;
gobject_class->dispose = eek_keyboard_dispose; gobject_class->dispose = eek_keyboard_dispose;
gobject_class->finalize = eek_keyboard_finalize;
/** /**
* EekKeyboard:group: * EekKeyboard:layout:
* *
* The group (row) index of symbol matrix of #EekKeyboard. * The layout used to create this #EekKeyboard.
*/ */
pspec = g_param_spec_int ("group", pspec = g_param_spec_object ("layout",
"Group", "Layout",
"Group index of symbol matrix of the keyboard", "Layout used to create the keyboard",
0, G_MAXINT, 0, EEK_TYPE_LAYOUT,
G_PARAM_READWRITE); G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_GROUP, PROP_LAYOUT,
pspec); pspec);
/** /**
* EekKeyboard:level: * EekKeyboard:modifier-behavior:
* *
* The level (row) index of symbol matrix of #EekKeyboard. * The modifier handling mode of #EekKeyboard.
*/ */
pspec = g_param_spec_int ("level", pspec = g_param_spec_int ("modifier-behavior",
"Level", "Modifier behavior",
"Level index of symbol matrix of the keyboard", "Modifier handling mode of the keyboard",
0, G_MAXINT, 0, 0, G_MAXINT, EEK_MODIFIER_BEHAVIOR_NONE,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_LEVEL, PROP_MODIFIER_BEHAVIOR,
pspec); pspec);
/** /**
@ -349,10 +478,10 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
* is shifted to the pressed state. * is shifted to the pressed state.
*/ */
signals[KEY_PRESSED] = signals[KEY_PRESSED] =
g_signal_new ("key-pressed", g_signal_new (I_("key-pressed"),
G_TYPE_FROM_CLASS(gobject_class), G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_LAST,
0, G_STRUCT_OFFSET(EekKeyboardClass, key_pressed),
NULL, NULL,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, g_cclosure_marshal_VOID__OBJECT,
@ -369,10 +498,10 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
* is shifted to the released state. * is shifted to the released state.
*/ */
signals[KEY_RELEASED] = signals[KEY_RELEASED] =
g_signal_new ("key-released", g_signal_new (I_("key-released"),
G_TYPE_FROM_CLASS(gobject_class), G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_LAST,
0, G_STRUCT_OFFSET(EekKeyboardClass, key_released),
NULL, NULL,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, g_cclosure_marshal_VOID__OBJECT,
@ -387,45 +516,120 @@ eek_keyboard_init (EekKeyboard *self)
EekKeyboardPrivate *priv; EekKeyboardPrivate *priv;
priv = self->priv = EEK_KEYBOARD_GET_PRIVATE(self); priv = self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
priv->group = priv->level = 0;
priv->layout = NULL; priv->layout = NULL;
priv->is_realized = FALSE; priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
priv->modifiers = 0;
priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
priv->num_lock_mask = 0;
eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
} }
/** /**
* eek_keyboard_set_keysym_index: * eek_keyboard_set_symbol_index:
* @keyboard: an #EekKeyboard * @keyboard: an #EekKeyboard
* @group: row index of the symbol matrix of keys on @keyboard * @group: row index of the symbol matrix of keys on @keyboard
* @level: column index of the symbol matrix of keys on @keyboard * @level: column index of the symbol matrix of keys on @keyboard
* *
* Select a cell of the symbol matrix of each key on @keyboard. * Set the default index of the symbol matrices of keys in @keyboard.
* To unset, pass -1 as group/level.
*
* Deprecated: 1.0: Use eek_element_set_symbol_index()
*/ */
void void
eek_keyboard_set_keysym_index (EekKeyboard *keyboard, eek_keyboard_set_symbol_index (EekKeyboard *keyboard,
gint group, gint group,
gint level) gint level)
{ {
g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
EEK_KEYBOARD_GET_CLASS(keyboard)->set_keysym_index (keyboard, group, level); eek_element_set_symbol_index (EEK_ELEMENT(keyboard), group, level);
} }
/** /**
* eek_keyboard_get_keysym_index: * eek_keyboard_get_symbol_index:
* @keyboard: an #EekKeyboard * @keyboard: an #EekKeyboard
* @group: a pointer where row index of the symbol matrix of keys on * @group: a pointer where the group value of the symbol index will be stored
* @keyboard will be stored * @level: a pointer where the level value of the symbol index will be stored
* @level: a pointer where column index of the symbol matrix of keys
* on @keyboard will be stored
* *
* Get the current cell position of the symbol matrix of each key on @keyboard. * Get the default index of the symbol matrices of keys in @keyboard.
* If the index is not set, -1 will be returned.
*
* Deprecated: 1.0: Use eek_element_get_symbol_index()
*/ */
void void
eek_keyboard_get_keysym_index (EekKeyboard *keyboard, eek_keyboard_get_symbol_index (EekKeyboard *keyboard,
gint *group, gint *group,
gint *level) gint *level)
{ {
g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
EEK_KEYBOARD_GET_CLASS(keyboard)->get_keysym_index (keyboard, group, level); eek_element_get_symbol_index(EEK_ELEMENT(keyboard), group, level);
}
/**
* eek_keyboard_set_group:
* @keyboard: an #EekKeyboard
* @group: group index of @keyboard
*
* Set the group value of the default symbol index of @keyboard. To
* unset, pass -1 as @group.
*
* See also: eek_keyboard_set_symbol_index()
* Deprecated: 1.0: Use eek_element_set_group()
*/
void
eek_keyboard_set_group (EekKeyboard *keyboard,
gint group)
{
eek_element_set_group (EEK_ELEMENT(keyboard), group);
}
/**
* eek_keyboard_set_level:
* @keyboard: an #EekKeyboard
* @level: level index of @keyboard
*
* Set the level value of the default symbol index of @keyboard. To
* unset, pass -1 as @level.
*
* See also: eek_keyboard_set_symbol_index()
* Deprecated: 1.0: Use eek_element_set_level()
*/
void
eek_keyboard_set_level (EekKeyboard *keyboard,
gint level)
{
eek_element_set_level (EEK_ELEMENT(keyboard), level);
}
/**
* eek_keyboard_get_group:
* @keyboard: an #EekKeyboard
*
* Return the group value of the default symbol index of @keyboard.
* If the value is not set, -1 will be returned.
*
* See also: eek_keyboard_get_symbol_index()
* Deprecated: 1.0: Use eek_element_get_group()
*/
gint
eek_keyboard_get_group (EekKeyboard *keyboard)
{
return eek_element_get_group (EEK_ELEMENT(keyboard));
}
/**
* eek_keyboard_get_level:
* @keyboard: an #EekKeyboard
*
* Return the level value of the default symbol index of @keyboard.
* If the value is not set, -1 will be returned.
*
* See also: eek_keyboard_get_symbol_index()
* Deprecated: 1.0: Use eek_element_get_level()
*/
gint
eek_keyboard_get_level (EekKeyboard *keyboard)
{
return eek_element_get_level (EEK_ELEMENT(keyboard));
} }
/** /**
@ -445,42 +649,234 @@ eek_keyboard_create_section (EekKeyboard *keyboard)
return section; return section;
} }
/**
* eek_keyboard_set_layout:
* @keyboard: an #EekKeyboard
* @layout: an #EekLayout
*
* Set the layout of @keyboard to @layout. This actually turns
* @keyboard to be ready to be drawn on the screen.
*/
void
eek_keyboard_set_layout (EekKeyboard *keyboard,
EekLayout *layout)
{
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
EEK_KEYBOARD_GET_CLASS(keyboard)->set_layout (keyboard, layout);
}
void
eek_keyboard_realize (EekKeyboard *keyboard)
{
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
EEK_KEYBOARD_GET_CLASS(keyboard)->realize (keyboard);
}
/** /**
* eek_keyboard_find_key_by_keycode: * eek_keyboard_find_key_by_keycode:
* @keyboard: an #EekKeyboard * @keyboard: an #EekKeyboard
* @keycode: a keycode * @keycode: a keycode
* @returns: (transfer none): #EekKey whose keycode is @keycode
* *
* Find an #EekKey whose keycode is @keycode. * Find an #EekKey whose keycode is @keycode.
* Returns: an #EekKey or NULL (if not found)
*/ */
EekKey * EekKey *
eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
guint keycode) guint keycode)
{ {
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL); g_assert (EEK_IS_KEYBOARD(keyboard));
return EEK_KEYBOARD_GET_CLASS(keyboard)->find_key_by_keycode (keyboard, return EEK_KEYBOARD_GET_CLASS(keyboard)->
keycode); find_key_by_keycode (keyboard, keycode);
}
/**
* eek_keyboard_get_layout:
* @keyboard: an #EekKeyboard
*
* Get the layout used to create @keyboard.
* Returns: an #EekLayout
*/
EekLayout *
eek_keyboard_get_layout (EekKeyboard *keyboard)
{
EekKeyboardPrivate *priv;
g_assert (EEK_IS_KEYBOARD(keyboard));
priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
return priv->layout;
}
/**
* eek_keyboard_get_size:
* @keyboard: an #EekKeyboard
* @width: width of @keyboard
* @height: height of @keyboard
*
* Get the size of @keyboard.
*/
void
eek_keyboard_get_size (EekKeyboard *keyboard,
gdouble *width,
gdouble *height)
{
EekBounds bounds;
g_assert (EEK_IS_KEYBOARD(keyboard));
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
*width = bounds.width;
*height = bounds.height;
}
/**
* eek_keyboard_set_modifier_behavior:
* @keyboard: an #EekKeyboard
* @modifier_behavior: modifier behavior of @keyboard
*
* Set the modifier handling mode of @keyboard.
*/
void
eek_keyboard_set_modifier_behavior (EekKeyboard *keyboard,
EekModifierBehavior modifier_behavior)
{
EekKeyboardPrivate *priv;
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
priv->modifier_behavior = modifier_behavior;
}
/**
* eek_keyboard_get_modifier_behavior:
* @keyboard: an #EekKeyboard
*
* Get the modifier handling mode of @keyboard.
* Returns: #EekModifierBehavior
*/
EekModifierBehavior
eek_keyboard_get_modifier_behavior (EekKeyboard *keyboard)
{
EekKeyboardPrivate *priv;
g_assert (EEK_IS_KEYBOARD(keyboard));
priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
return priv->modifier_behavior;
}
/**
* eek_keyboard_get_modifiers:
* @keyboard: an #EekKeyboard
*
* Get the current modifier status of @keyboard.
* Returns: #EekModifierType
*/
EekModifierType
eek_keyboard_get_modifiers (EekKeyboard *keyboard)
{
EekKeyboardPrivate *priv;
g_assert (EEK_IS_KEYBOARD(keyboard));
priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
return priv->modifiers;
}
/**
* eek_keyboard_add_outline:
* @keyboard: an #EekKeyboard
* @outline: an #EekOutline
*
* Register an outline of @keyboard.
* Returns: an unsigned long id of the registered outline, for later reference
*/
gulong
eek_keyboard_add_outline (EekKeyboard *keyboard,
EekOutline *outline)
{
EekKeyboardPrivate *priv;
EekOutline *_outline;
g_assert (EEK_IS_KEYBOARD(keyboard));
priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
_outline = eek_outline_copy (outline);
g_array_append_val (priv->outline_array, *_outline);
/* don't use eek_outline_free here, so as to keep _outline->points */
g_slice_free (EekOutline, _outline);
return priv->outline_array->len;
}
/**
* eek_keyboard_get_outline:
* @keyboard: an #EekKeyboard
* @oref: an unsigned long id
*
* Get an outline associated with @oref in @keyboard.
* Returns: an #EekOutline, which should not be released
*/
EekOutline *
eek_keyboard_get_outline (EekKeyboard *keyboard,
gulong oref)
{
EekKeyboardPrivate *priv;
g_assert (EEK_IS_KEYBOARD(keyboard));
priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
if (oref > priv->outline_array->len)
return NULL;
return &g_array_index (priv->outline_array, EekOutline, oref - 1);
}
/**
* eek_keyboard_set_num_lock_mask:
* @keyboard: an #EekKeyboard
* @num_lock_mask: an #EekModifierType
*
* Set modifier mask used as Num_Lock.
*/
void
eek_keyboard_set_num_lock_mask (EekKeyboard *keyboard,
EekModifierType num_lock_mask)
{
EekKeyboardPrivate *priv;
g_assert (EEK_IS_KEYBOARD(keyboard));
priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
priv->num_lock_mask = num_lock_mask;
}
/**
* eek_keyboard_get_num_lock_mask:
* @keyboard: an #EekKeyboard
*
* Get modifier mask used as Num_Lock.
* Returns: an #EekModifierType
*/
EekModifierType
eek_keyboard_get_num_lock_mask (EekKeyboard *keyboard)
{
EekKeyboardPrivate *priv;
g_assert (EEK_IS_KEYBOARD(keyboard));
priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
return priv->num_lock_mask;
}
/**
* eek_keyboard_set_alt_gr_mask:
* @keyboard: an #EekKeyboard
* @alt_gr_mask: an #EekModifierType
*
* Set modifier mask used as Alt_Gr.
*/
void
eek_keyboard_set_alt_gr_mask (EekKeyboard *keyboard,
EekModifierType alt_gr_mask)
{
EekKeyboardPrivate *priv;
g_assert (EEK_IS_KEYBOARD(keyboard));
priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
priv->alt_gr_mask = alt_gr_mask;
}
/**
* eek_keyboard_get_alt_gr_mask:
* @keyboard: an #EekKeyboard
*
* Get modifier mask used as Alt_Gr.
* Returns: an #EekModifierType
*/
EekModifierType
eek_keyboard_get_alt_gr_mask (EekKeyboard *keyboard)
{
EekKeyboardPrivate *priv;
g_assert (EEK_IS_KEYBOARD(keyboard));
priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
return priv->alt_gr_mask;
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -37,6 +37,12 @@ G_BEGIN_DECLS
typedef struct _EekKeyboardClass EekKeyboardClass; typedef struct _EekKeyboardClass EekKeyboardClass;
typedef struct _EekKeyboardPrivate EekKeyboardPrivate; typedef struct _EekKeyboardPrivate EekKeyboardPrivate;
/**
* EekKeyboard:
*
* The #EekKeyboard structure contains only private data and should
* only be accessed using the provided API.
*/
struct _EekKeyboard struct _EekKeyboard
{ {
/*< private >*/ /*< private >*/
@ -47,58 +53,111 @@ struct _EekKeyboard
/** /**
* EekKeyboardClass: * EekKeyboardClass:
* @set_keysym_index: virtual function for setting group and level of
* the entire keyboard
* @get_keysym_index: virtual function for getting group and level of
* the entire keyboard
* @create_section: virtual function for creating a section * @create_section: virtual function for creating a section
* @set_layout: virtual function for setting layout engine
* @find_key_by_keycode: virtual function for finding a key in the * @find_key_by_keycode: virtual function for finding a key in the
* keyboard by keycode * keyboard by keycode
* @realize: virtual function for applying a layout to the keyboard * @key_pressed: class handler for #EekKeyboard::key-pressed signal
* @key_released: class handler for #EekKeyboard::key-released signal
*/ */
struct _EekKeyboardClass struct _EekKeyboardClass
{ {
/*< private >*/ /*< private >*/
EekContainerClass parent_class; EekContainerClass parent_class;
/* obsolete members moved to EekElement */
gpointer set_symbol_index;
gpointer get_symbol_index;
/*< public >*/ /*< public >*/
void (* set_keysym_index) (EekKeyboard *self, EekSection *(* create_section) (EekKeyboard *self);
gint group,
gint level);
void (* get_keysym_index) (EekKeyboard *self,
gint *group,
gint *level);
EekSection *(* create_section) (EekKeyboard *self); EekKey *(* find_key_by_keycode) (EekKeyboard *self,
guint keycode);
void (* set_layout) (EekKeyboard *self, /* signals */
EekLayout *layout); void (* key_pressed) (EekKeyboard *self,
EekKey *(* find_key_by_keycode) (EekKeyboard *self, EekKey *key);
guint keycode); void (* key_released) (EekKeyboard *self,
void (* realize) (EekKeyboard *self); EekKey *key);
/*< private >*/ /*< private >*/
/* obsolete members moved to EekElement */
gpointer symbol_index_changed;
/* padding */ /* padding */
gpointer pdummy[24]; gpointer pdummy[24];
}; };
GType eek_keyboard_get_type (void) G_GNUC_CONST; GType eek_keyboard_get_type
(void) G_GNUC_CONST;
void eek_keyboard_set_keysym_index (EekKeyboard *keyboard, EekKeyboard *eek_keyboard_new (EekLayout *layout,
gint group, gdouble initial_width,
gint level); gdouble initial_height);
void eek_keyboard_get_keysym_index (EekKeyboard *keyboard, EekLayout *eek_keyboard_get_layout
gint *group, (EekKeyboard *keyboard);
gint *level); void eek_keyboard_get_size
(EekKeyboard *keyboard,
gdouble *width,
gdouble *height);
void eek_keyboard_set_size
(EekKeyboard *keyboard,
gdouble width,
gdouble height);
void eek_keyboard_set_symbol_index
(EekKeyboard *keyboard,
gint group,
gint level);
void eek_keyboard_get_symbol_index
(EekKeyboard *keyboard,
gint *group,
gint *level);
EekSection *eek_keyboard_create_section (EekKeyboard *keyboard); void eek_keyboard_set_group
(EekKeyboard *keyboard,
gint group);
void eek_keyboard_set_level
(EekKeyboard *keyboard,
gint level);
gint eek_keyboard_get_group
(EekKeyboard *keyboard);
gint eek_keyboard_get_level
(EekKeyboard *keyboard);
void eek_keyboard_set_layout (EekKeyboard *keyboard, void eek_keyboard_set_modifier_behavior
EekLayout *layout); (EekKeyboard *keyboard,
void eek_keyboard_realize (EekKeyboard *keyboard); EekModifierBehavior modifier_behavior);
EekKey *eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, EekModifierBehavior eek_keyboard_get_modifier_behavior
guint keycode); (EekKeyboard *keyboard);
EekModifierType eek_keyboard_get_modifiers
(EekKeyboard *keyboard);
EekSection *eek_keyboard_create_section
(EekKeyboard *keyboard);
EekKey *eek_keyboard_find_key_by_keycode
(EekKeyboard *keyboard,
guint keycode);
gulong eek_keyboard_add_outline
(EekKeyboard *keyboard,
EekOutline *outline);
EekOutline *eek_keyboard_get_outline
(EekKeyboard *keyboard,
gulong oref);
void eek_keyboard_set_num_lock_mask
(EekKeyboard *keyboard,
EekModifierType num_lock_mask);
EekModifierType eek_keyboard_get_num_lock_mask
(EekKeyboard *keyboard);
void eek_keyboard_set_alt_gr_mask
(EekKeyboard *keyboard,
EekModifierType alt_gr_mask);
EekModifierType eek_keyboard_get_alt_gr_mask
(EekKeyboard *keyboard);
G_END_DECLS G_END_DECLS
#endif /* EEK_KEYBOARD_H */ #endif /* EEK_KEYBOARD_H */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -20,28 +20,101 @@
/** /**
* SECTION:eek-keysym * SECTION:eek-keysym
* @short_description: Keysym conversion utilities * @short_description: an #EekSymbol represents an X keysym
*/ */
#include <glib.h>
#include <stdlib.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-keysym.h"
struct eek_keysym_label { #include <string.h>
guint keysym; #include <stdlib.h>
const gchar *label;
EekKeysymCategory category; #include "eek-keysym.h"
#include "eek-serializable.h"
/* modifier keys */
#define EEK_KEYSYM_Shift_L 0xffe1
#define EEK_KEYSYM_Shift_R 0xffe2
#define EEK_KEYSYM_ISO_Level3_Shift 0xfe03
#define EEK_KEYSYM_Caps_Lock 0xffe5
#define EEK_KEYSYM_Shift_Lock 0xffe6
#define EEK_KEYSYM_Control_L 0xffe3
#define EEK_KEYSYM_Control_R 0xffe4
#define EEK_KEYSYM_Alt_L 0xffe9
#define EEK_KEYSYM_Alt_R 0xffea
#define EEK_KEYSYM_Meta_L 0xffe7
#define EEK_KEYSYM_Meta_R 0xffe8
#define EEK_KEYSYM_Super_L 0xffeb
#define EEK_KEYSYM_Super_R 0xffec
#define EEK_KEYSYM_Hyper_L 0xffed
#define EEK_KEYSYM_Hyper_R 0xffee
struct _EekKeysymPrivate {
guint xkeysym;
}; };
#include "eek-special-keysym-labels.h" struct _EekKeysymEntry {
#include "eek-unicode-keysym-labels.h" guint xkeysym;
#include "eek-keyname-keysym-labels.h" const gchar *name;
EekSymbolCategory category;
};
static G_CONST_RETURN gchar * typedef struct _EekKeysymEntry EekKeysymEntry;
#include "eek-special-keysym-entries.h"
#include "eek-unicode-keysym-entries.h"
#include "eek-xkeysym-keysym-entries.h"
static void eek_serializable_iface_init (EekSerializableIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
eek_serializable_iface_init));
#define EEK_KEYSYM_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYSYM, EekKeysymPrivate))
static EekSerializableIface *eek_keysym_parent_serializable_iface;
static void
eek_keysym_real_serialize (EekSerializable *self,
GVariantBuilder *builder)
{
EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self);
eek_keysym_parent_serializable_iface->serialize (self, builder);
g_variant_builder_add (builder, "u", priv->xkeysym);
}
static gsize
eek_keysym_real_deserialize (EekSerializable *self,
GVariant *variant,
gsize index)
{
EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self);
index = eek_keysym_parent_serializable_iface->deserialize (self,
variant,
index);
g_variant_get_child (variant, index++, "u", &priv->xkeysym);
return index;
}
static void
eek_serializable_iface_init (EekSerializableIface *iface)
{
eek_keysym_parent_serializable_iface =
g_type_interface_peek_parent (iface);
iface->serialize = eek_keysym_real_serialize;
iface->deserialize = eek_keysym_real_deserialize;
}
static gchar *
unichar_to_utf8 (gunichar uc) unichar_to_utf8 (gunichar uc)
{ {
if (g_unichar_isgraph (uc)) { if (g_unichar_isgraph (uc)) {
@ -57,115 +130,223 @@ unichar_to_utf8 (gunichar uc)
} }
static int static int
keysym_label_compare (const void *key0, const void *key1) keysym_entry_compare_by_xkeysym (const void *key0, const void *key1)
{ {
const struct eek_keysym_label *entry0 = key0, *entry1 = key1; const EekKeysymEntry *entry0 = key0, *entry1 = key1;
return (gint)entry0->keysym - (gint)entry1->keysym; return (gint) (entry0->xkeysym - entry1->xkeysym);
}
static EekKeysymEntry *
find_keysym_entry_by_xkeysym (guint xkeysym,
const EekKeysymEntry *entries,
gint num_entries)
{
EekKeysymEntry key;
key.xkeysym = xkeysym;
return bsearch (&key, entries, num_entries, sizeof (EekKeysymEntry),
keysym_entry_compare_by_xkeysym);
} }
static gboolean static gboolean
find_keysym (guint keysym, get_unichar (guint xkeysym, gunichar *uc) {
const gchar **label,
EekKeysymCategory *category)
{
struct eek_keysym_label bsearch_key, *bsearch_val;
/* First, search special keysyms. */
bsearch_key.keysym = keysym;
bsearch_val = bsearch (&bsearch_key,
special_keysym_labels,
G_N_ELEMENTS(special_keysym_labels),
sizeof (struct eek_keysym_label),
keysym_label_compare);
if (bsearch_val) {
if (label)
*label = g_strdup (bsearch_val->label);
if (category)
*category = bsearch_val->category;
return TRUE;
}
/* Check for Latin-1 characters (1:1 mapping) */ /* Check for Latin-1 characters (1:1 mapping) */
if ((keysym >= 0x0020 && keysym <= 0x007e) || if ((xkeysym >= 0x0020 && xkeysym <= 0x007e) ||
(keysym >= 0x00a0 && keysym <= 0x00ff)) { (xkeysym >= 0x00a0 && xkeysym <= 0x00ff)) {
if (label) *uc = xkeysym;
*label = unichar_to_utf8 (keysym);
if (category)
*category = EEK_KEYSYM_CATEGORY_LETTER;
return TRUE; return TRUE;
} }
/* Also check for directly encoded 24-bit UCS characters: /* Also check for directly encoded 24-bit UCS characters:
*/ */
if ((keysym & 0xff000000) == 0x01000000) { if ((xkeysym & 0xff000000) == 0x01000000) {
if (label) *uc = xkeysym & 0x00ffffff;
*label = unichar_to_utf8 (keysym & 0x00ffffff);
if (category)
*category = EEK_KEYSYM_CATEGORY_LETTER;
return TRUE;
}
/* Search known unicode keysyms. */
bsearch_key.keysym = keysym;
bsearch_val = bsearch (&bsearch_key,
unicode_keysym_labels,
G_N_ELEMENTS(unicode_keysym_labels),
sizeof (struct eek_keysym_label),
keysym_label_compare);
if (bsearch_val) {
if (label)
*label = g_strdup (bsearch_val->label);
if (category)
*category = bsearch_val->category;
return TRUE;
}
/* Finally, search keynames. */
bsearch_key.keysym = keysym;
bsearch_val = bsearch (&bsearch_key,
keyname_keysym_labels,
G_N_ELEMENTS(keyname_keysym_labels),
sizeof (struct eek_keysym_label),
keysym_label_compare);
if (bsearch_val) {
if (label)
*label = g_strdup (bsearch_val->label);
if (category)
*category = bsearch_val->category;
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
/** G_INLINE_FUNC EekModifierType
* eek_keysym_to_string: get_modifier_mask (guint xkeysym)
* @keysym: keysym ID
*
* Return a string representation of @keysym.
*/
G_CONST_RETURN gchar *
eek_keysym_to_string (guint keysym)
{ {
const gchar *label; switch (xkeysym) {
case EEK_KEYSYM_Shift_L:
case EEK_KEYSYM_Shift_R:
case EEK_KEYSYM_Caps_Lock:
case EEK_KEYSYM_Shift_Lock:
return EEK_SHIFT_MASK;
case EEK_KEYSYM_ISO_Level3_Shift:
return EEK_MOD5_MASK;
case EEK_KEYSYM_Control_L:
case EEK_KEYSYM_Control_R:
return EEK_CONTROL_MASK;
case EEK_KEYSYM_Alt_L:
case EEK_KEYSYM_Alt_R:
return EEK_MOD1_MASK;
case EEK_KEYSYM_Meta_L:
case EEK_KEYSYM_Meta_R:
return EEK_META_MASK;
case EEK_KEYSYM_Super_L:
case EEK_KEYSYM_Super_R:
return EEK_SUPER_MASK;
case EEK_KEYSYM_Hyper_L:
case EEK_KEYSYM_Hyper_R:
return EEK_HYPER_MASK;
}
return 0;
}
if (find_keysym (keysym, &label, NULL)) static void
return label; eek_keysym_class_init (EekKeysymClass *klass)
return g_strdup (""); {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (gobject_class, sizeof (EekKeysymPrivate));
}
static void
eek_keysym_init (EekKeysym *self)
{
EekKeysymPrivate *priv;
priv = self->priv = EEK_KEYSYM_GET_PRIVATE(self);
priv->xkeysym = EEK_INVALID_KEYSYM;
} }
/** /**
* eek_keysym_get_category: * eek_keysym_new_with_modifier:
* @keysym: keysym ID * @xkeysym: an X keysym value
* @modifier_mask: modifier assigned to @xkeysym
* *
* Return a string representation of @keysym. * Create an #EekKeysym with given X keysym value @xkeysym and
* modifier @modifier_mask.
*/ */
EekKeysymCategory EekKeysym *
eek_keysym_get_category (guint keysym) eek_keysym_new_with_modifier (guint xkeysym, EekModifierType modifier_mask)
{ {
EekKeysymCategory category; EekKeysym *keysym;
EekKeysymPrivate *priv;
EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
*unichar_entry;
gchar *name, *label;
EekSymbolCategory category;
gunichar uc;
if (find_keysym (keysym, NULL, &category)) special_entry =
return category; find_keysym_entry_by_xkeysym (xkeysym,
return EEK_KEYSYM_CATEGORY_UNKNOWN; special_keysym_entries,
G_N_ELEMENTS(special_keysym_entries));
xkeysym_entry =
find_keysym_entry_by_xkeysym (xkeysym,
xkeysym_keysym_entries,
G_N_ELEMENTS(xkeysym_keysym_entries));
unicode_entry =
find_keysym_entry_by_xkeysym (xkeysym,
unicode_keysym_entries,
G_N_ELEMENTS(unicode_keysym_entries));
unichar_entry = NULL;
if (get_unichar (xkeysym, &uc)) {
unichar_entry = g_slice_new (EekKeysymEntry);
unichar_entry->xkeysym = xkeysym;
unichar_entry->name = unichar_to_utf8 (uc);
unichar_entry->category = EEK_SYMBOL_CATEGORY_LETTER;
}
/* name and category */
name = NULL;
if (xkeysym_entry) {
name = g_strdup (xkeysym_entry->name);
category = xkeysym_entry->category;
} else if (unichar_entry) {
name = g_strdup (unichar_entry->name);
category = unichar_entry->category;
} else if (unicode_entry) {
name = g_strdup (unicode_entry->name);
category = unicode_entry->category;
} else {
name = g_strdup ("");
category = EEK_SYMBOL_CATEGORY_UNKNOWN;
}
/* label */
if (special_entry)
label = g_strdup (special_entry->name);
else if (unichar_entry)
label = g_strdup (unichar_entry->name);
else if (unicode_entry)
label = g_strdup (unicode_entry->name);
else
label = g_strdup (name);
keysym = g_object_new (EEK_TYPE_KEYSYM,
"name", name,
"label", label,
"category", category,
"modifier-mask", modifier_mask,
NULL);
g_free (name);
g_free (label);
if (unichar_entry) {
g_free ((gpointer) unichar_entry->name);
g_slice_free (EekKeysymEntry, unichar_entry);
}
priv = EEK_KEYSYM_GET_PRIVATE(keysym);
priv->xkeysym = xkeysym;
return keysym;
}
/**
* eek_keysym_new:
* @xkeysym: an X keysym value
*
* Create an #EekKeysym with given X keysym value @xkeysym.
*/
EekKeysym *
eek_keysym_new (guint xkeysym)
{
return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
}
/**
* eek_keysym_new_from_name:
* @name: an X keysym name
*
* Create an #EekKeysym with an X keysym value looked up by @name.
*/
EekKeysym *
eek_keysym_new_from_name (const gchar *name)
{
gint i;
for (i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
// g_warning ("can't find keysym entry for %s", name);
return g_object_new (EEK_TYPE_KEYSYM,
"name", name,
"label", name,
"category", EEK_SYMBOL_CATEGORY_UNKNOWN,
"modifier-mask", 0,
NULL);
}
/**
* eek_keysym_get_xkeysym:
* @keysym: an #EekKeysym
*
* Get an X keysym value associated with @keysym
*/
guint
eek_keysym_get_xkeysym (EekKeysym *keysym)
{
EekKeysymPrivate *priv;
g_assert (EEK_IS_KEYSYM(keysym));
priv = EEK_KEYSYM_GET_PRIVATE(keysym);
return priv->xkeysym;
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -20,41 +20,48 @@
#ifndef EEK_KEYSYM_H #ifndef EEK_KEYSYM_H
#define EEK_KEYSYM_H 1 #define EEK_KEYSYM_H 1
#include <glib-object.h> #include <X11/XKBlib.h>
#include "eek-symbol.h"
G_BEGIN_DECLS
/** /**
* EEK_INVALID_KEYSYM: * EEK_INVALID_KEYSYM:
* *
* Pseudo keysym used for error reporting. * Pseudo keysym used for error reporting.
*/ */
#define EEK_INVALID_KEYSYM ((guint)(-1)) #define EEK_INVALID_KEYSYM (0)
/** #define EEK_TYPE_KEYSYM (eek_keysym_get_type())
* EEK_INVALID_KEYCODE: #define EEK_KEYSYM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYSYM, EekKeysym))
* #define EEK_KEYSYM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEYSYM, EekKeysymClass))
* Pseudo keycode used for error reporting. #define EEK_IS_KEYSYM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYSYM))
*/ #define EEK_IS_KEYSYM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEYSYM))
#define EEK_INVALID_KEYCODE ((guint)(-1)) #define EEK_KEYSYM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEYSYM, EekKeysymClass))
/** typedef struct _EekKeysymClass EekKeysymClass;
* EekKeysymCategory: typedef struct _EekKeysymPrivate EekKeysymPrivate;
* @EEK_KEYSYM_CATEGORY_LETTER: the symbol represents an alphabet letter
* @EEK_KEYSYM_CATEGORY_FUNCTION: the symbol represents a function
* @EEK_KEYSYM_CATEGORY_KEYNAME: the symbol does not have meaning but
* have a name
* @EEK_KEYSYM_CATEGORY_UNKNOWN: used for error reporting
*
* Category of the key symbols.
*/
typedef enum {
EEK_KEYSYM_CATEGORY_LETTER,
EEK_KEYSYM_CATEGORY_FUNCTION,
EEK_KEYSYM_CATEGORY_KEYNAME,
EEK_KEYSYM_CATEGORY_UNKNOWN,
EEK_KEYSYM_CATEGORY_LAST = EEK_KEYSYM_CATEGORY_UNKNOWN
} EekKeysymCategory;
G_CONST_RETURN gchar *eek_keysym_to_string (guint keysym); struct _EekKeysym {
EekKeysymCategory eek_keysym_get_category (guint keysym); /*< private >*/
EekSymbol parent;
EekKeysymPrivate *priv;
};
struct _EekKeysymClass {
/*< private >*/
EekSymbolClass parent_class;
};
GType eek_keysym_get_type (void) G_GNUC_CONST;
EekKeysym *eek_keysym_new (guint xkeysym);
guint eek_keysym_get_xkeysym (EekKeysym *keysym);
EekKeysym *eek_keysym_new_from_name (const gchar *name);
EekKeysym *eek_keysym_new_with_modifier (guint xkeysym,
EekModifierType modifier);
G_END_DECLS
#endif /* EEK_KEYSYM_H */ #endif /* EEK_KEYSYM_H */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -20,9 +20,9 @@
/** /**
* SECTION:eek-layout * SECTION:eek-layout
* @short_description: Base interface of a layout engine * @short_description: Base class of a layout engine
* *
* The #EekLayout class is a base interface of layout engine which * The #EekLayout class is a base class of layout engine which
* arranges keyboard elements. * arranges keyboard elements.
*/ */
@ -33,103 +33,36 @@
#include "eek-layout.h" #include "eek-layout.h"
#include "eek-keyboard.h" #include "eek-keyboard.h"
enum { G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT);
GROUP_CHANGED,
CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
static void static void
eek_layout_base_init (gpointer gobject_class) eek_layout_class_init (EekLayoutClass *klass)
{ {
static gboolean is_initialized = FALSE; klass->create_keyboard = NULL;
if (!is_initialized) {
/**
* EekLayout::group-changed:
* @layout: an #EekLayout that received the signal
* @group: group index
*
* The ::group-changed signal is emitted each time group
* configuration of @layout changed.
*/
signals[GROUP_CHANGED] =
g_signal_new ("group-changed",
G_TYPE_FROM_INTERFACE(gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekLayoutIface, group_changed),
NULL,
NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1,
G_TYPE_INT);
/**
* EekLayout::changed:
* @layout: an #EekLayout that received the signal
*
* The ::changed signal is emitted each time @layout changed
* and re-layout of #EekKeyboard is needed.
*/
signals[CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_INTERFACE(gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekLayoutIface, changed),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
is_initialized = TRUE;
}
} }
GType
eek_layout_get_type (void)
{
static GType iface_type = 0;
if (iface_type == 0) {
static const GTypeInfo info = {
sizeof (EekLayoutIface),
eek_layout_base_init,
NULL,
};
iface_type = g_type_register_static (G_TYPE_INTERFACE,
"EekLayout",
&info, 0);
}
return iface_type;
}
/**
* eek_layout_apply:
* @layout: an #EekLayout
* @keyboard: an #EekKeyboard
*
* Apply @layout to @keyboard. This function is rarely called by user
* programs but called by the subclasses of #EekKeyboard.
*/
void void
eek_layout_apply (EekLayout *layout, eek_layout_init (EekLayout *self)
EekKeyboard *keyboard)
{ {
g_return_if_fail (EEK_IS_LAYOUT(layout));
EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard);
} }
/** /**
* eek_layout_get_group: * eek_keyboard_new:
* @layout: an #EekLayout * @layout: an #EekLayout
* @initial_width: initial width of the keyboard
* @initial_height: initial height of the keyboard
* *
* Get the group index from the @layout. This function normally * Create a new #EekKeyboard based on @layout.
* called after #EekLayout::group-changed signal to change group index
* of all the keys in #EekKeyboard at a time.
*/ */
gint EekKeyboard *
eek_layout_get_group (EekLayout *layout) eek_keyboard_new (EekLayout *layout,
gdouble initial_width,
gdouble initial_height)
{ {
g_return_val_if_fail (EEK_IS_LAYOUT(layout), -1); g_assert (EEK_IS_LAYOUT(layout));
return EEK_LAYOUT_GET_IFACE(layout)->get_group (layout); g_assert (EEK_LAYOUT_GET_CLASS(layout)->create_keyboard);
return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (layout,
initial_width,
initial_height);
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org> * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010-2011 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -28,44 +28,40 @@ G_BEGIN_DECLS
#define EEK_TYPE_LAYOUT (eek_layout_get_type()) #define EEK_TYPE_LAYOUT (eek_layout_get_type())
#define EEK_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_LAYOUT, EekLayout)) #define EEK_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_LAYOUT, EekLayout))
#define EEK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_LAYOUT, EekLayoutClass))
#define EEK_IS_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_LAYOUT)) #define EEK_IS_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_LAYOUT))
#define EEK_LAYOUT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_LAYOUT, EekLayoutIface)) #define EEK_IS_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_LAYOUT))
#define EEK_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_LAYOUT, EekLayoutClass))
typedef struct _EekLayoutIface EekLayoutIface; typedef struct _EekLayoutClass EekLayoutClass;
typedef struct _EekLayout EekLayout; typedef struct _EekLayout EekLayout;
/** struct _EekLayout
* EekLayoutIface:
* @apply: virtual function for applying the layout to a keyboard
* @get_group: virtual function for getting the current group setting
* of the layout
* @group_changed: class handler for #EekLayout::group-changed signal
* @changed: class handler for #EekLayout::changed signal
*/
struct _EekLayoutIface
{ {
/*< private >*/ /*< private >*/
GTypeInterface parent_iface; GObject parent;
};
/**
* EekLayoutClass:
* @create_keyboard: virtual function for creating a keyboard
*/
struct _EekLayoutClass
{
/*< private >*/
GObjectClass parent_class;
/*< public >*/ /*< public >*/
void (* apply) (EekLayout *self, EekKeyboard* (* create_keyboard) (EekLayout *self,
EekKeyboard *keyboard); gdouble initial_width,
gint (* get_group) (EekLayout *self); gdouble initial_height);
/* signals */
void (* group_changed) (EekLayout *self,
gint group);
void (* changed) (EekLayout *self);
/*< private >*/ /*< private >*/
/* padding */ /* padding */
gpointer pdummy[24]; gpointer pdummy[24];
}; };
GType eek_layout_get_type (void) G_GNUC_CONST; GType eek_layout_get_type (void) G_GNUC_CONST;
void eek_layout_apply (EekLayout *layout,
EekKeyboard *keyboard);
gint eek_layout_get_group (EekLayout *layout);
G_END_DECLS G_END_DECLS
#endif /* EEK_LAYOUT_H */ #endif /* EEK_LAYOUT_H */

1
eek/eek-marshalers.list Normal file
View File

@ -0,0 +1 @@
VOID:INT,INT

1375
eek/eek-renderer.c Normal file

File diff suppressed because it is too large Load Diff

160
eek/eek-renderer.h Normal file
View File

@ -0,0 +1,160 @@
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef EEK_RENDERER_H
#define EEK_RENDERER_H 1
#include <pango/pangocairo.h>
#include "eek-keyboard.h"
#include "eek-keysym.h"
#include "eek-types.h"
#include "eek-theme.h"
#include "eek-theme-context.h"
G_BEGIN_DECLS
#define EEK_TYPE_RENDERER (eek_renderer_get_type())
#define EEK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_RENDERER, EekRenderer))
#define EEK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_RENDERER, EekRendererClass))
#define EEK_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_RENDERER))
#define EEK_IS_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_RENDERER))
#define EEK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_RENDERER, EekRendererClass))
typedef struct _EekRenderer EekRenderer;
typedef struct _EekRendererClass EekRendererClass;
typedef struct _EekRendererPrivate EekRendererPrivate;
struct _EekRenderer {
GObject parent;
EekRendererPrivate *priv;
};
struct _EekRendererClass
{
GObjectClass parent_class;
void (* render_key_label) (EekRenderer *self,
PangoLayout *layout,
EekKey *key);
void (* render_key_outline) (EekRenderer *self,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate);
void (* render_key) (EekRenderer *self,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate);
void (* render_keyboard) (EekRenderer *self,
cairo_t *cr);
void (* render_key_icon) (EekRenderer *self,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate);
/*< private >*/
/* padding */
gpointer pdummy[23];
};
GType eek_renderer_get_type (void) G_GNUC_CONST;
EekRenderer *eek_renderer_new (EekKeyboard *keyboard,
PangoContext *pcontext);
void eek_renderer_set_allocation_size (EekRenderer *renderer,
gdouble width,
gdouble height);
void eek_renderer_get_size (EekRenderer *renderer,
gdouble *width,
gdouble *height);
void eek_renderer_get_key_bounds (EekRenderer *renderer,
EekKey *key,
EekBounds *bounds,
gboolean rotate);
gdouble eek_renderer_get_scale (EekRenderer *renderer);
PangoLayout *eek_renderer_create_pango_layout (EekRenderer *renderer);
void eek_renderer_render_key_label (EekRenderer *renderer,
PangoLayout *layout,
EekKey *key);
void eek_renderer_render_key_outline (EekRenderer *renderer,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate);
void eek_renderer_render_key (EekRenderer *renderer,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate);
void eek_renderer_render_key_icon (EekRenderer *renderer,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate);
void eek_renderer_render_keyboard (EekRenderer *renderer,
cairo_t *cr);
void eek_renderer_set_default_foreground_color
(EekRenderer *renderer,
const EekColor *color);
void eek_renderer_set_default_background_color
(EekRenderer *renderer,
const EekColor *color);
void eek_renderer_get_foreground_color (EekRenderer *renderer,
EekElement *element,
EekColor *color);
void eek_renderer_get_background_color (EekRenderer *renderer,
EekElement *element,
EekColor *color);
void eek_renderer_get_background_gradient
(EekRenderer *renderer,
EekElement *element,
EekGradientType *type,
EekColor *start,
EekColor *end);
void eek_renderer_set_border_width (EekRenderer *renderer,
gdouble border_width);
EekKey *eek_renderer_find_key_by_position (EekRenderer *renderer,
gdouble x,
gdouble y);
void eek_renderer_apply_transformation_for_key
(EekRenderer *renderer,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate);
void eek_renderer_set_theme (EekRenderer *renderer,
EekTheme *theme);
G_END_DECLS
#endif /* EEK_RENDERER_H */

Some files were not shown because too many files have changed in this diff Show More