From 9e2e66c13b779c0c0d55e9e02383f80b32f03e1a Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Tue, 8 Sep 2015 22:44:25 +0900 Subject: [PATCH] tizen 2.3.1 release --- AUTHORS | 6 + COPYING | 2 +- ChangeLog | 227 + Makefile.am | 33 +- NEWS | 112 +- README | 2 +- configure.ac | 76 +- debian/changelog | 1346 -- debian/compat | 1 - debian/control | 244 - debian/copyright | 44 - debian/ecore_config.1 | 54 - debian/jobs | 0 debian/libecore-bin.install | 1 - debian/libecore-con-svn-01.install | 1 - debian/libecore-con-svn-01.shlibs | 1 - debian/libecore-con.install | 1 - debian/libecore-config-svn-01.install | 1 - debian/libecore-config-svn-01.shlibs | 1 - debian/libecore-config.install | 1 - debian/libecore-dev.install | 14 - debian/libecore-doc.doc-base | 10 - debian/libecore-evas-svn-01.install | 1 - debian/libecore-evas-svn-01.shlibs | 1 - debian/libecore-evas.install | 1 - debian/libecore-fb-svn-01.install | 1 - debian/libecore-fb-svn-01.shlibs | 1 - debian/libecore-fb.install | 1 - debian/libecore-file-svn-01.install | 1 - debian/libecore-file-svn-01.shlibs | 1 - debian/libecore-file.install | 1 - debian/libecore-imf-svn-01.install | 2 - debian/libecore-imf-svn-01.shlibs | 2 - debian/libecore-imf.install | 2 - debian/libecore-input-svn-01.install | 1 - debian/libecore-input-svn-01.shlibs | 1 - debian/libecore-input.install | 1 - debian/libecore-ipc-svn-01.install | 1 - debian/libecore-ipc-svn-01.shlibs | 1 - debian/libecore-ipc.install | 1 - debian/libecore-svn-01.install | 1 - debian/libecore-svn-01.shlibs | 1 - debian/libecore-x-svn-01.install | 1 - debian/libecore-x-svn-01.shlibs | 1 - debian/libecore-x.install | 1 - debian/libecore.install | 1 - debian/rules | 43 - doc/Doxyfile.in | 2 +- doc/{examples.dox => ecore_examples.dox} | 54 +- ecore-con.manifest | 5 + ecore-evas.manifest | 5 + ecore-fb.manifest | 5 + ecore-file.manifest | 5 + ecore-imf-evas.manifest | 5 + ecore-imf.manifest | 5 + ecore-input-evas.manifest | 5 + ecore-input.manifest | 5 + ecore-ipc.manifest | 5 + ecore-x.manifest | 5 + ecore.manifest | 5 + m4/efl_coverage.m4 | 62 + packaging/ecore.spec | 46 +- po/LINGUAS | 2 +- po/cs.po | 9 +- po/de.po | 2 +- po/el.po | 2 +- po/fr.po | 2 +- po/it.po | 2 +- po/ko.po | 185 + po/nl.po | 2 +- po/pt.po | 18 +- po/sl.po | 2 +- src/examples/Makefile.am | 6 + src/examples/ecore_con_client_example.c | 4 +- src/examples/ecore_con_server_example.c | 4 +- src/examples/ecore_con_url_download_example.c | 2 +- src/examples/ecore_evas_extn_plug_example.c | 226 + src/examples/ecore_evas_extn_socket_example.c | 202 + src/examples/ecore_imf_example.c | 3 +- src/examples/ecore_thread_example.c | 1 - src/lib/ecore/Ecore.h | 4324 +++-- src/lib/ecore/Ecore_Getopt.h | 41 +- src/lib/ecore/ecore.c | 118 +- src/lib/ecore/ecore_alloc.c | 28 +- src/lib/ecore/ecore_anim.c | 165 +- src/lib/ecore/ecore_events.c | 1 + src/lib/ecore/ecore_exe.c | 34 +- src/lib/ecore/ecore_getopt.c | 43 +- src/lib/ecore/ecore_glib.c | 10 +- src/lib/ecore/ecore_idler.c | 1 + src/lib/ecore/ecore_main.c | 194 +- src/lib/ecore/ecore_pipe.c | 5 + src/lib/ecore/ecore_poll.c | 839 +- src/lib/ecore/ecore_private.h | 2 + src/lib/ecore/ecore_thread.c | 102 +- src/lib/ecore/ecore_timer.c | 15 +- src/lib/ecore_cocoa/Ecore_Cocoa.h | 4 +- src/lib/ecore_con/Ecore_Con.h | 1432 +- src/lib/ecore_con/Ecore_Con_Eet.h | 73 + src/lib/ecore_con/Makefile.am | 8 +- src/lib/ecore_con/dns.c | 36 +- src/lib/ecore_con/ecore_con.c | 177 +- src/lib/ecore_con/ecore_con_alloc.c | 28 +- src/lib/ecore_con/ecore_con_dns.c | 2 +- src/lib/ecore_con/ecore_con_eet.c | 796 + src/lib/ecore_con/ecore_con_info.c | 55 +- src/lib/ecore_con/ecore_con_local.c | 46 +- src/lib/ecore_con/ecore_con_local_win32.c | 26 + src/lib/ecore_con/ecore_con_socks.c | 28 +- src/lib/ecore_con/ecore_con_ssl.c | 31 +- src/lib/ecore_con/ecore_con_url.c | 60 +- src/lib/ecore_config/Ecore_Config.h | 400 +- src/lib/ecore_config/ecore_config.c | 26 + src/lib/ecore_directfb/Ecore_DirectFB.h | 18 +- src/lib/ecore_evas/.gitignore | 1 + src/lib/ecore_evas/Ecore_Evas.h | 2507 +-- src/lib/ecore_evas/Makefile.am | 18 + src/lib/ecore_evas/ecore_evas.c | 471 +- src/lib/ecore_evas/ecore_evas_buffer.c | 144 +- src/lib/ecore_evas/ecore_evas_cocoa.c | 11 +- src/lib/ecore_evas/ecore_evas_convert.c | 125 + src/lib/ecore_evas/ecore_evas_directfb.c | 9 +- src/lib/ecore_evas/ecore_evas_ews.c | 11 +- src/lib/ecore_evas/ecore_evas_extn.c | 1641 +- src/lib/ecore_evas/ecore_evas_fb.c | 11 +- src/lib/ecore_evas/ecore_evas_private.h | 133 +- src/lib/ecore_evas/ecore_evas_psl1ght.c | 11 +- src/lib/ecore_evas/ecore_evas_sdl.c | 19 +- src/lib/ecore_evas/ecore_evas_util.c | 8 +- src/lib/ecore_evas/ecore_evas_wayland_common.c | 657 + src/lib/ecore_evas/ecore_evas_wayland_egl.c | 841 +- src/lib/ecore_evas/ecore_evas_wayland_shm.c | 1002 +- src/lib/ecore_evas/ecore_evas_win32.c | 11 +- src/lib/ecore_evas/ecore_evas_wince.c | 9 +- src/lib/ecore_evas/ecore_evas_x.c | 1740 +- src/lib/ecore_fb/Ecore_Fb.h | 17 +- src/lib/ecore_fb/ecore_fb_li.c | 1 + src/lib/ecore_fb/ecore_fb_vt.c | 26 + src/lib/ecore_file/Ecore_File.h | 37 +- src/lib/ecore_file/ecore_file.c | 74 +- src/lib/ecore_file/ecore_file_download.c | 6 + src/lib/ecore_file/ecore_file_monitor.c | 26 + src/lib/ecore_file/ecore_file_monitor_inotify.c | 16 +- src/lib/ecore_file/ecore_file_path.c | 32 +- src/lib/ecore_imf/Ecore_IMF.h | 1581 +- src/lib/ecore_imf/ecore_imf.c | 35 +- src/lib/ecore_imf/ecore_imf_context.c | 1163 +- src/lib/ecore_imf/ecore_imf_module.c | 10 +- src/lib/ecore_imf/ecore_imf_private.h | 15 + src/lib/ecore_imf_evas/Ecore_IMF_Evas.h | 134 + src/lib/ecore_imf_evas/ecore_imf_evas.c | 17 +- src/lib/ecore_input/Ecore_Input.h | 347 +- src/lib/ecore_input/ecore_input.c | 6 + src/lib/ecore_input/ecore_input_compose.c | 69 +- src/lib/ecore_input/ecore_input_compose.h | 19793 +++++++++++----------- src/lib/ecore_input_evas/ecore_input_evas.c | 210 +- src/lib/ecore_ipc/Ecore_Ipc.h | 17 +- src/lib/ecore_ipc/ecore_ipc.c | 53 +- src/lib/ecore_ipc/ecore_ipc_private.h | 1 - src/lib/ecore_psl1ght/Ecore_Psl1ght.h | 37 +- src/lib/ecore_sdl/Ecore_Sdl.h | 37 +- src/lib/ecore_sdl/ecore_sdl.c | 12 +- src/lib/ecore_wayland/Ecore_Wayland.h | 65 +- src/lib/ecore_wayland/ecore_wl.c | 43 + src/lib/ecore_wayland/ecore_wl_dnd.c | 314 +- src/lib/ecore_wayland/ecore_wl_input.c | 344 +- src/lib/ecore_wayland/ecore_wl_output.c | 26 + src/lib/ecore_wayland/ecore_wl_private.h | 14 + src/lib/ecore_wayland/ecore_wl_window.c | 83 +- src/lib/ecore_win32/Ecore_Win32.h | 138 +- src/lib/ecore_win32/ecore_win32_window.c | 26 + src/lib/ecore_wince/Ecore_WinCE.h | 82 +- src/lib/ecore_wince/ecore_wince_window.c | 26 + src/lib/ecore_x/Ecore_X.h | 535 +- src/lib/ecore_x/Ecore_X_Atoms.h | 74 +- src/lib/ecore_x/Ecore_X_Cursor.h | 3 +- src/lib/ecore_x/ecore_x_atoms_decl.h | 102 +- src/lib/ecore_x/xcb/ecore_xcb.c | 6 + src/lib/ecore_x/xcb/ecore_xcb_atoms.c | 4 - src/lib/ecore_x/xcb/ecore_xcb_dnd.c | 174 +- src/lib/ecore_x/xcb/ecore_xcb_e.c | 168 +- src/lib/ecore_x/xcb/ecore_xcb_events.c | 33 +- src/lib/ecore_x/xcb/ecore_xcb_image.c | 148 +- src/lib/ecore_x/xcb/ecore_xcb_randr.c | 5 +- src/lib/ecore_x/xcb/ecore_xcb_screensaver.c | 34 +- src/lib/ecore_x/xcb/ecore_xcb_selection.c | 85 +- src/lib/ecore_x/xcb/ecore_xcb_window.c | 122 + src/lib/ecore_x/xcb/ecore_xcb_xfixes.c | 6 - src/lib/ecore_x/xlib/Makefile.am | 1 + src/lib/ecore_x/xlib/ecore_x.c | 111 +- src/lib/ecore_x/xlib/ecore_x_atoms.c | 35 +- src/lib/ecore_x/xlib/ecore_x_dnd.c | 65 +- src/lib/ecore_x/xlib/ecore_x_e.c | 597 +- src/lib/ecore_x/xlib/ecore_x_events.c | 50 +- src/lib/ecore_x/xlib/ecore_x_gesture.c | 4 +- src/lib/ecore_x/xlib/ecore_x_icccm.c | 12 +- src/lib/ecore_x/xlib/ecore_x_image.c | 146 +- src/lib/ecore_x/xlib/ecore_x_netwm.c | 10 +- src/lib/ecore_x/xlib/ecore_x_private.h | 3 + src/lib/ecore_x/xlib/ecore_x_randr_12.c | 97 +- src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c | 12 +- src/lib/ecore_x/xlib/ecore_x_screensaver.c | 33 +- src/lib/ecore_x/xlib/ecore_x_selection.c | 83 +- src/lib/ecore_x/xlib/ecore_x_vsync.c | 313 +- src/lib/ecore_x/xlib/ecore_x_window.c | 105 +- src/lib/ecore_x/xlib/ecore_x_window_prop.c | 26 + src/lib/ecore_x/xlib/ecore_x_window_shape.c | 55 +- src/lib/ecore_x/xlib/ecore_x_xi2.c | 293 +- src/lib/ecore_x/xlib/ioctl.h | 105 + src/modules/immodules/ibus/ibus_imcontext.c | 16 +- src/modules/immodules/scim/scim_imcontext.cpp | 1 + src/modules/immodules/xim/ecore_imf_xim.c | 32 +- 212 files changed, 30457 insertions(+), 19869 deletions(-) delete mode 100644 debian/changelog delete mode 100644 debian/compat delete mode 100755 debian/control delete mode 100644 debian/copyright delete mode 100644 debian/ecore_config.1 delete mode 100644 debian/jobs delete mode 100644 debian/libecore-bin.install delete mode 100644 debian/libecore-con-svn-01.install delete mode 100644 debian/libecore-con-svn-01.shlibs delete mode 100644 debian/libecore-con.install delete mode 100644 debian/libecore-config-svn-01.install delete mode 100644 debian/libecore-config-svn-01.shlibs delete mode 100644 debian/libecore-config.install delete mode 100755 debian/libecore-dev.install delete mode 100644 debian/libecore-doc.doc-base delete mode 100644 debian/libecore-evas-svn-01.install delete mode 100644 debian/libecore-evas-svn-01.shlibs delete mode 100644 debian/libecore-evas.install delete mode 100644 debian/libecore-fb-svn-01.install delete mode 100644 debian/libecore-fb-svn-01.shlibs delete mode 100644 debian/libecore-fb.install delete mode 100644 debian/libecore-file-svn-01.install delete mode 100644 debian/libecore-file-svn-01.shlibs delete mode 100644 debian/libecore-file.install delete mode 100644 debian/libecore-imf-svn-01.install delete mode 100644 debian/libecore-imf-svn-01.shlibs delete mode 100644 debian/libecore-imf.install delete mode 100644 debian/libecore-input-svn-01.install delete mode 100644 debian/libecore-input-svn-01.shlibs delete mode 100644 debian/libecore-input.install delete mode 100644 debian/libecore-ipc-svn-01.install delete mode 100644 debian/libecore-ipc-svn-01.shlibs delete mode 100644 debian/libecore-ipc.install delete mode 100644 debian/libecore-svn-01.install delete mode 100644 debian/libecore-svn-01.shlibs delete mode 100644 debian/libecore-x-svn-01.install delete mode 100644 debian/libecore-x-svn-01.shlibs delete mode 100644 debian/libecore-x.install delete mode 100644 debian/libecore.install delete mode 100755 debian/rules rename doc/{examples.dox => ecore_examples.dox} (98%) create mode 100644 ecore-con.manifest create mode 100644 ecore-evas.manifest create mode 100644 ecore-fb.manifest create mode 100644 ecore-file.manifest create mode 100644 ecore-imf-evas.manifest create mode 100644 ecore-imf.manifest create mode 100644 ecore-input-evas.manifest create mode 100644 ecore-input.manifest create mode 100644 ecore-ipc.manifest create mode 100644 ecore-x.manifest create mode 100644 ecore.manifest create mode 100644 m4/efl_coverage.m4 create mode 100644 po/ko.po mode change 100644 => 100755 src/examples/ecore_con_client_example.c mode change 100644 => 100755 src/examples/ecore_con_server_example.c mode change 100644 => 100755 src/examples/ecore_con_url_download_example.c create mode 100644 src/examples/ecore_evas_extn_plug_example.c create mode 100644 src/examples/ecore_evas_extn_socket_example.c mode change 100644 => 100755 src/examples/ecore_imf_example.c mode change 100644 => 100755 src/examples/ecore_thread_example.c create mode 100644 src/lib/ecore_con/Ecore_Con_Eet.h create mode 100644 src/lib/ecore_con/ecore_con_eet.c create mode 100644 src/lib/ecore_evas/.gitignore mode change 100644 => 100755 src/lib/ecore_evas/Ecore_Evas.h create mode 100644 src/lib/ecore_evas/ecore_evas_convert.c mode change 100644 => 100755 src/lib/ecore_evas/ecore_evas_extn.c create mode 100644 src/lib/ecore_evas/ecore_evas_wayland_common.c mode change 100644 => 100755 src/lib/ecore_evas/ecore_evas_x.c mode change 100644 => 100755 src/lib/ecore_x/Ecore_X.h mode change 100644 => 100755 src/lib/ecore_x/Ecore_X_Atoms.h mode change 100644 => 100755 src/lib/ecore_x/ecore_x_atoms_decl.h mode change 100644 => 100755 src/lib/ecore_x/xcb/ecore_xcb_e.c mode change 100644 => 100755 src/lib/ecore_x/xlib/ecore_x_e.c mode change 100644 => 100755 src/lib/ecore_x/xlib/ecore_x_window.c mode change 100644 => 100755 src/lib/ecore_x/xlib/ecore_x_xi2.c create mode 100755 src/lib/ecore_x/xlib/ioctl.h diff --git a/AUTHORS b/AUTHORS index f531462..e360d24 100644 --- a/AUTHORS +++ b/AUTHORS @@ -52,3 +52,9 @@ Doyoun Kang Haifeng Deng Jérémy Zurcher Vikram Narayanan +Seong-ho Cho (DarkCircle) +Patryk Kaczmarek +Daniel Willmann +Michal Pakula vel Rutka +Alexey Yakovenko +Robert David diff --git a/COPYING b/COPYING index fb8c49d..32f2a80 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ Copyright notice for Ecore: -Copyright (C) 2000-2011 Carsten Haitzler and various contributors (see AUTHORS) +Copyright (C) 2000-2014 Carsten Haitzler and various contributors (see AUTHORS) All rights reserved. diff --git a/ChangeLog b/ChangeLog index c9f654b..88785f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -851,3 +851,230 @@ 2012-08-09 Cedric Bail * Correctly shutdown Ecore_Thread. + * Add a way to reset Ecore_Thread internal pipe after a fork via ecore_fork_reset. + +2012-08-13 Carsten Haitzler (The Rasterman) + + * Fix ecore fork reset function to allow for callbacks to be + attached so ecore-evas can reset evas async fd on fork. + +2012-08-13 Vincent Torri + + * Fix segmentation fault when fd_set pointers are NULL on Windows + +2012-08-18 Carsten Haitzler (The Rasterman) + + * Add xkb change events patch from trac. + +2012-08-27 Carsten Haitzler (The Rasterman) + + * Add ecore_x custom blanker screensaver enable/disable - cant + do e17 properly without so add in even in freeze. + +2012-08-27 Vincent Torri + + * Fix segmentation fault in ecore_thread on Windows as PHS + was returning a wrong value. + +2012-08-29 Cedric Bail + + * Always call evas_render_update_free to prevent leak in Ecore_Evas X backend. + +2012-08-29 Mike Blumenkrantz + + * Fix leak in ecore_ipc servers + +2012-08-29 Christopher Michael + + * Add Copy-N-Paste support for Ecore_Wayland. + +2012-08-30 Carsten Haitzler (The Rasterman) + + 1.7.0 release + +2012-08-31 Cedric Bail + + * Add Ecore_Con_Eet API to help using Eet_Data with Ecore_Con + +2012-09-03 Shinwoo Kim (kimcinoo) + + * Add ecore_x illume access messages: + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN + +2012-09-04 Jihoon Kim (jihoon) + + * Add ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN + +2012-09-05 Mike Blumenkrantz + + * Fix crash that could occur in ecore_con_ssl with privkeys and certificates on failure + +2012-09-06 Mike Blumenkrantz + + * Fix race condition in ecore-con where events could sometimes be sent for freed clients + * Fix ssl servers using openssl + * Fix ssl connections overall + +2012-09-07 Christopher Michael + + * Fix ecore_x_randr to actually return outputs properly. + +2012-09-08 Vincent Torri + + * Fix readlink usage in ecore_file. + +2012-09-12 Jihoon Kim (jihoon) + + * Add ECORE_IMF_PREEDIT_TYPE_SUB4~7 style. + +2012-09-10 Christopher Michael + + * Fix ecore_x_randr to actually return crtcs properly. + +2012-09-11 Christopher Michael + + * Fix ecore_x_randr to actually return crtcs possible outputs properly. + * Fix ecore_x_randr to actually return crtcs outputs properly. + +2012-09-13 Mike Blumenkrantz + + * Return -1 for ecore_con_server_fd_get() in the case that the server has already been deleted + +2012-09-13 Carsten Haitzler (The Rasterman) + + * Fix ecore-evas rotation handling for canvases that shows up + only on some drivers and GL implementations. + +2012-09-14 Doyoun Kang + + * Add string to atom_items for ECORE_X_ATOM_E_ILLUME_WINDOW_STATE, + ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL, ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING + +2012-09-18 Patryk Kaczmarek + + * Fix escaping in ecore_file_escape_name() to handle tab and + newline right. + +2012-09-21 Carsten Haitzler (The Rasterman) + + * Fix ecore_x_image_is_argb32_get() to return correctly on + endianess. + +2012-09-21 Christopher Michael + + * Fix ecore_x_randr to properly return output modes from + ecore_x_randr_output_modes_get(). + +2012-09-27 Carsten Haitzler (The Rasterman) + + * Fix ecore_imf buf in the ibus module where it may segv + accessing a wrong context handle. + +2012-10-02 Daniel Willmann + + * Fix memory allocation size in ecore_thread_feedback() + +2012-10-03 Daniel Wilmann + * Fix memory allocation size in ecore_x xcb randr function + +2012-10-04 Cedric Bail + + * Add ecore_x_input_raw_select and ECORE_X_RAW_*. + +2012-10-04 Sebastian Dransfeld + + * Expose ecore_x_selection_converter_text + +2012-10-05 Cedric Bail + + * Properly reschedule call to curl. + +2012-10-05 Eduardo Lima (Etrunko) + + * Wayland SHM now features a mechanism to synchronize rendering with + the compositor, removing tearing effect in animations when using that + engine. + +2012-10-10 Michal Pakula vel Rutka + + * Fix: Send ECORE_X_EVENT_SELECTION_NOTIFY even if there is no data. + +2012-11-23 Sebastian Dransfeld + + * Correctly define alloca + * Minor build fixes for solaris + +2012-11-27 Alexey Yakovenko + + * Fix ecore_evas_sdl window resize bug. + +2012-12-05 Robert David + + * Fix Ecore_Evas_Extn on Solaris 11. + +2012-12-07 Cedric Bail + + * Don't leak fd on exec. + +2012-12-07 Luis Felipe Strano Moraes + + * 1.7.3 release + +2012-12-09 Cedric Bail + + * Fix build without IPv6. + +2012-12-12 Daniel Willmann + + * Fix possible memory corruption in xrandr EDID functions. + +2012-12-12 Nicolas Aguirre + + * Fix build on win32 + +2012-12-17 Vincent Torri + + * Add XML output to doc + * Add installation rule for doc + +2012-12-19 Luis Felip Strano Moraes + + * Backport 81304 which fixes memory errors on ecore_evas_extn + +2012-12-19 Christopher Michael + + * Fix XCB compile with screensaver support + +2012-12-20 Carsten Haitzler (The Rasterman) + + * Fixed 24bpp ximage convert back from 24bpp to 32bpp in + ecore-x. Only shows itself in qemu/kvm. + + +2012-12-21 Luis Felipe Strano Moraes + + * 1.7.4 release + +2013-01-03 Carsten Haitzler (The Rasterman) + + * Fixed ecore_con case where freeing server double-frees clients + + +2013-01-04 Luis Felipe Strano Moraes + + * 1.7.5 release + +2013-01-13 Boris Faure (billiob) + + * Fixed condition based on uninitialized value in ecore_x_selection + (both xlib and xcb). + * Fixed a leaked when no selection converter matches. + +2013-05-21 Daniel Willmann + + * Backport (6d54f46) from Raster: + Ecore-X: Fix selection parser to not use longs - wrong on + 64bit as the rest of ecore-x keeps types to their REAL sizes (ints), + but xlib uses longs (change size - eg 64bit even though protocol-wise + the data is DEFINEd as 32bit) diff --git a/Makefile.am b/Makefile.am index b7be982..9f16aeb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -117,6 +117,7 @@ m4/ecore_check_options.m4 \ m4/efl_doxygen.m4 \ m4/efl_path_max.m4 \ m4/efl_shm_open.m4 \ +m4/efl_coverage.m4 \ m4/efl_tests.m4 \ m4/efl_threads.m4 @@ -196,7 +197,7 @@ if BUILD_ECORE_WAYLAND pkgconfig_DATA += ecore-wayland.pc endif -.PHONY: doc +.PHONY: doc coverage # Documentation @@ -217,3 +218,33 @@ check-local: @echo "reconfigure with --enable-tests" endif + +# Coverage report + +if EFL_ENABLE_COVERAGE +lcov-reset: + @rm -rf $(top_builddir)/coverage + @find $(top_builddir) -name "*.gcda" -delete + @lcov --zerocounters --directory $(top_builddir) + +lcov-report: + @mkdir $(top_builddir)/coverage + lcov --capture --compat-libtool --output-file $(top_builddir)/coverage/coverage.info --directory $(top_builddir) + lcov --remove $(top_builddir)/coverage/coverage.info '*.h' --output-file $(top_builddir)/coverage/coverage.cleaned.info + genhtml -t "$(PACKAGE_STRING)" -o $(top_builddir)/coverage/html $(top_builddir)/coverage/coverage.cleaned.info + @echo "Coverage Report at $(top_builddir)/coverage/html" + +coverage: + @$(MAKE) lcov-reset + @$(MAKE) check + @$(MAKE) lcov-report +else +lcov-reset: + @echo "reconfigure with --enable-coverage" + +lcov-report: + @echo "reconfigure with --enable-coverage" + +coverage: + @echo "reconfigure with --enable-tests --enable-coverage" +endif diff --git a/NEWS b/NEWS index 0500358..8660202 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,109 @@ -Ecore 1.3.0 +Ecore 1.8.0 + + +Ecore 1.7.99 + +Changes since Ecore 1.7.98: +-------------------------- + +Additions: + * ecore_con: + - Add Ecore_Con_Eet API to help using Eet_Data with Ecore_Con. + * ecore_x: + - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP. + - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN. + - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ENABLE. + - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DISABLE. + - ecore_x_input_raw_select. + - +ecore_x_selection_converter_text. + - ECORE_X_RAW_MOTION, ECORE_X_RAW_BUTTON_PRESS and ECORE_X_RAW_BUTTON_RELEASE. + * ecore_imf: + - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN. + - ECORE_IMF_PREEDIT_TYPE_SUB4~7 style. + * ecore_evas: + - Wayland SHM engine now features a mechanism to synchronize rendering with + the compositor, removing the tearing effect in animations when using that + engine. + +Fixes: + * ecore_con_url: + - Timeouts are handled correctly now (passing HTTP status 408 to + completion callback). + - properly reschedule call to curl. + * ecore_evas rotation handling on some driver implementations + * ecore_file_escape_name() escape taba nd newline right. + * ecore_imf ibus module potential segv fixed. + * ecore_thread_feedback() memory allocation and corruption fixed. + * ecore_x: + - ecore_x_image_is_argb32_get() returns correctly given endianness. + - ecore_x_randr to actually return outputs properly. + - ecore_x_randr to actually return crtcs properly. + - ecore_x_randr to actually return crtcs possible outputs properly. + - ecore_x_randr to actually return crtcs outputs properly. + * send ECORE_X_EVENT_SELECTION_NOTIFY even if there is no data. + * Ecore-X: Fix selection parser to not overrun buffer read by using longs on 64bit. + +Improvements: + + +Ecore 1.7.5 + +Changes since Ecore 1.7.4: +-------------------------- + +Fixes: + * Fix ecore_con case where freeing server double-frees clients + +Ecore 1.7.4 + +Changes since Ecore 1.7.3: +-------------------------- + +Fixes: + * Fix XCB compile with screensaver support + * Fix build without IPv6. + * Fix possible memory corruption in xrandr EDID functions. + * Backport 81304, which fixes memory errors in ecore_evas_extn + * Fix big rendering/conversion problem in kvm/qemu 24bpp. + +Ecore 1.7.3 + +Changes since Ecore 1.7.2: +-------------------------- + +Fixes: + * Fix small leak in Ecore Wayland. + * Fix Ecore_Evas_SDL resize bug. + * Fix Ecore_Evas_Extn build on Solaris 11. + * Fix Wayland support to latest API. + * Don't leak fd on exec. + +Ecore 1.7.2 + +Changes since Ecore 1.7.1: +-------------------------- + +No Changes, just updating to keep in sync with last release. + +Changes since Ecore 1.7.0 +-------------------------- + +Fixes: + * ecore_con_ssl: fix crash on failure with privkeys and certificate. + * ecore_con_ssl: fix ssl connections. + * ecore_con: fix race condition with event from disconnected clients. + * ecore_con_url: properly reschedule call to curl. + * ecore_evas: rotation handling on some driver implementations + * ecore_file: ecore_file_escape_name() escape taba nd newline right. + * ecore_x_image_is_argb32_get() returns correctly given endianness. + * ecore_x: fix ecore_x_randr. + * ecore_x: send ECORE_X_EVENT_SELECTION_NOTIFY even if there is no data. + * ecore_imf: ibus module potential segv fixed. + * ecore: ecore_thread_feedback() memory allocation and corruption fixed. + * ecore_wayland: + - Update to work with latest wayland (0.99) from git. + - Fix leak of struct wl_registry + * ecore_evas: fix Ecore_Evas_Extn build on Solaris 11. Changes since Ecore 1.2.0: -------------------------- @@ -6,6 +111,7 @@ Changes since Ecore 1.2.0: Additions: * ecore: - Add ecore_main_fd_handler_file_add() + - Add ecore_fork_reset() * ecore_evas: - Add transparency support on Windows (GDI engine only) - Add API functions to get/set an Ecore_Evas's profile. @@ -28,9 +134,13 @@ Fixes: - Force cancel of all running Ecore_Thread on shutdown. - Make Ecore_Thread work reliably when called without a running main loop. - Correctly shutdown Ecore_Thread. + - Fix usage of FD_SET and al. when fd_set pointers are NULL (Windows) + - Fix ecore_thread seg fault on Windows where PHS() was returning a wrong value + - Always call evas_render_update_free to prevent leak in Ecore_Evas X bakcend. * ecore_x - Fix unitialized Ecore_X_Atom use. + * send ECORE_X_EVENT_SELECTION_NOTIFY even if there is no data. Ecore 1.2.0 diff --git a/README b/README index e0712b4..e9cedf3 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -Ecore 1.7.0 +Ecore 1.7.99 ****************************************************************************** diff --git a/configure.ac b/configure.ac index f7af9d6..4514600 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## m4_define([v_maj], [1]) -m4_define([v_min], [6]) +m4_define([v_min], [7]) m4_define([v_mic], [99]) m4_define([v_rev], m4_esyscmd([(svnversion "${SVN_REPO_PATH:-.}" | grep -v '\(export\|Unversioned directory\)' || echo 0) | awk -F : '{printf("%s\n", $1);}' | tr -d ' :MSP\n' | sed 's/Unversioneddirectory/0/' | tr -d '\n'])) m4_if(v_rev, [0], [m4_define([v_rev], m4_esyscmd([git log 2> /dev/null | (grep -m1 git-svn-id || echo 0) | sed -e 's/.*@\([0-9]*\).*/\1/' | tr -d '\n']))]) @@ -114,6 +114,7 @@ want_glib="no" # core modules want_ecore_con="yes" +want_ecore_con_eet="yes" want_ecore_ipc="yes" want_ecore_file="yes" #want_ecore_config="no" @@ -184,6 +185,7 @@ want_ecore_imf_ibus="no" case "$host_os" in mingw32ce*) want_ecore_con="no" + want_ecore_con_eet="no" want_ecore_ipc="no" want_ecore_wince="yes" want_ecore_evas_software_16_wince="yes" @@ -558,7 +560,7 @@ requirements_ecore_input_evas="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_eco requirements_ecore_ipc="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_ipc}" requirements_ecore_cocoa="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_cocoa}" requirements_ecore_sdl="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_sdl}" -requirements_ecore_psl1ght="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_sdl}" +requirements_ecore_psl1ght="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_psl1ght}" requirements_ecore_win32="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_win32}" requirements_ecore_wince="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_wince}" requirements_ecore_x="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_x}" @@ -622,11 +624,10 @@ PKG_CHECK_MODULES([DIRECTFB], # Eet library (ecore_config) -#PKG_CHECK_MODULES([EET], -# [eet >= 1.6.99], -# [have_eet="yes"], -# [have_eet="no"]) - +PKG_CHECK_MODULES([EET], + [eet >= 1.6.99], + [have_eet="yes"], + [have_eet="no"]) # Xlib and XCB (ecore_x) @@ -1182,6 +1183,7 @@ if ! test "x$have_ecore_x_xcb" = "xyes" ; then ECORE_CHECK_X_EXTENSION([Xtest], [XTest.h], [Xtst], [XTestFakeKeyEvent], [$want_ecore_x_xtest]) ECORE_CHECK_X_EXTENSION([Xss], [scrnsaver.h], [Xss], [XScreenSaverSelectInput], [$want_ecore_x_screensaver]) ECORE_CHECK_X_EXTENSION([Xi2], [XInput2.h], [Xi], [XIQueryDevice], [$want_ecore_x_input]) + ECORE_CHECK_X_EXTENSION([Xi2_2], [XInput2.h], [Xi], [XIGrabTouchBegin], [$want_ecore_x_input]) ecore_x_libs_private="${Xcursor_libs} ${XKB_LIBS} ${XCOMPOSITE_LIBS} ${XGESTURE_LIBS} ${XDAMAGE_LIBS} ${XDPMS_LIBS} ${XFIXES_LIBS} ${XINERAMA_LIBS} ${XPRINT_LIBS} ${XRANDR_LIBS} ${XRENDER_LIBS} ${XTEST_LIBS} ${XSS_LIBS} ${XI2_LIBS}" @@ -1248,7 +1250,22 @@ AC_CHECK_HEADERS([net/if.h], [], [], # include #endif ]) -AC_CHECK_HEADERS([sys/un.h arpa/inet.h arpa/nameser.h netinet/tcp.h netinet/in.h ws2tcpip.h netdb.h errno.h]) +AC_CHECK_HEADERS([sys/un.h], [], [], +[ +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +]) +AC_CHECK_HEADERS([arpa/inet.h arpa/nameser.h netinet/tcp.h netinet/in.h ws2tcpip.h netdb.h errno.h]) if test "x${ac_cv_header_netdb_h}" = "xyes" ; then have_addrinfo="yes" @@ -1462,6 +1479,7 @@ have_openssl="no" have_cares="no" want_ipv6="yes" have_ipv6="no" +have_ecore_con_eet="no" AC_ARG_ENABLE([ipv6], [AC_HELP_STRING([--disable-ipv6], @@ -1494,7 +1512,12 @@ if test "x${have_ecore_con}" = "xyes" ; then if test "x${have_ipv6}" = "xyes" ; then AC_DEFINE(HAVE_IPV6, 1, [Define if IPV6 is supported]) fi - AM_CONDITIONAL([HAVE_IPV6], [test "x${have_ipv6}" = "xyes"]) + + if test "x${have_eet}" = "xyes" ; then + requirements_ecore_con="eet > 1.7 ${requirements_ecore_con}" + have_ecore_con_eet="yes" + AC_DEFINE(ECORE_HAVE_EET, 1, [Define if Ecore_Con Eet_Connection helper is supported]) + fi ECORE_CHECK_CURL([${want_curl}], [ @@ -1531,6 +1554,8 @@ if test "x${have_ecore_con}" = "xyes" ; then [have_cares="no"]) fi +AM_CONDITIONAL([HAVE_IPV6], [test "x${have_ipv6}" = "xyes"]) +AM_CONDITIONAL([ECORE_HAVE_EET], [test "x${have_ecore_con_eet}" = "xyes"]) EFL_CHECK_COMPILER_FLAGS([ECORE_CON], [-Wno-override-init -Wno-initializer-overrides]) @@ -1644,23 +1669,6 @@ fi ECORE_CHECK_MODULE([imf-ibus], [${want_ecore_imf}], [Imf_IBUS], [${ecore_imf_ibus_deps}], [requirements_ecore_imf_ibus="ecore-imf >= 1.6.99 ecore-x >= 1.6.99 ecore-input >= 1.6.99 ${requirements_ecore_imf_ibus}"]) -# ecore_imf_ibus -PKG_CHECK_MODULES([IBUS], [ibus-1.0 >= 1.3.99], [have_ibus="yes"], [have_ibus="no"]) - -AM_CONDITIONAL(BUILD_ECORE_IMF_IBUS, false) -ecore_imf_ibus_deps="no" -echo "have_ecore_x_xlib: ${have_ecore_x_xlib}" -if test "x${have_ecore_imf}" = "xyes" \ - -a "x${have_glib}" = "xyes" \ - -a "x${have_ibus}" = "xyes" \ - -a "x${have_ecore_input}" = "xyes" ; then - ecore_imf_ibus_deps="yes" - AC_DEFINE(BUILD_ECORE_IMF_IBUS, 1, [Ecore Imf IBUS Support]) -fi - -ECORE_CHECK_MODULE([imf-ibus], [${want_ecore_imf}], [Imf_IBUS], [${ecore_imf_ibus_deps}], - [requirements_ecore_imf_ibus="ecore-imf >= 1.2.0 ecore-x >= 1.2.0 ecore-input >= 1.2.0 ${requirements_ecore_imf_ibus}"]) - ## Graphic systems # ecore_x{cb} @@ -1729,7 +1737,7 @@ ECORE_CHECK_MODULE([directfb], [${want_ecore_directfb}], [DirectFB], [${have_dir # ecore_wince ECORE_CHECK_MODULE([wince], [${want_ecore_wince}], [WinCE], [${have_ecore_input}], - [requirements_ecore_win32="ecore-input >= 1.6.99 ${requirements_ecore_win32}"]) + [requirements_ecore_wince="ecore-input >= 1.6.99 ${requirements_ecore_wince}"]) ## Ecore Evas @@ -1966,7 +1974,7 @@ fi ECORE_CHECK_MODULE([wayland], [${want_ecore_wayland}], [Wayland], [${ecore_wayland_deps}]) if test "x${have_ecore_wayland}" = "xyes" ; then - requirements_ecore_wayland="ecore-input >= 1.6.99 wayland-client xkbcommon ${requirements_ecore_wayland}" + requirements_ecore_wayland="ecore-input >= 1.6.99 wayland-client wayland-cursor xkbcommon ${requirements_ecore_wayland}" fi ECORE_EVAS_CHECK_MODULE_FULL([wayland-shm], [wayland-shm], @@ -1986,10 +1994,17 @@ ECORE_EVAS_CHECK_MODULE_FULL([wayland-egl], [wayland-egl egl >= 7.10], fi ]) -### Unit tests +### Unit tests and coverage EFL_CHECK_TESTS([enable_tests="yes"], [enable_tests="no"]) +EFL_CHECK_COVERAGE([${enable_tests}], [enable_coverage="yes"], [enable_coverage="no"]) +CFLAGS="${CFLAGS} ${EFL_COVERAGE_CFLAGS}" +ECORE_LIBS="${ECORE_LIBS} ${EFL_COVERAGE_LIBS}" +if test "x$enable_coverage" = "xyes" ; then + CFLAGS="${CFLAGS} ${EFL_DEBUG_CFLAGS}" +fi + ### install and build examples EFL_CHECK_BUILD_EXAMPLES([enable_build_examples="yes"], [enable_build_examples="no"]) @@ -2108,6 +2123,7 @@ fi echo " IPv6.......................: $have_ipv6" echo " GnuTLS.....................: $have_gnutls" echo " CURL.......................: $have_curl" + echo " Eet........................: $have_ecore_con_eet" echo " Local Sockets..............: $want_ecore_con_local_sockets" if test "x$want_ecore_con_local_sockets" = "xyes" ; then echo " Abstract Sockets.........: $want_ecore_con_abstract_sockets" @@ -2183,6 +2199,7 @@ if test "x$have_ecore_x" = "xyes" ; then echo " Xtest......................: $use_xtest" echo " XIM........................: $want_xim" echo " Xi2........................: $use_xi2" + echo " Xi2.2......................: $use_xi2_2" fi else echo " Ecore_X......................: $have_ecore_x" @@ -2237,6 +2254,7 @@ if test "x${have_ecore_evas}" = "xyes" ; then fi echo echo " Tests................: ${enable_tests}" +echo " Coverage.............: ${enable_coverage}" echo " Maximum log level....: ${with_max_log_level}" echo "Documentation..........: ${build_doc}" echo "Examples...............: ${enable_build_examples}" diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index e01452c..0000000 --- a/debian/changelog +++ /dev/null @@ -1,1346 +0,0 @@ -ecore (1.2.0+svn.72988slp2+build02) unstable; urgency=low - - * [ecore_x] Add missing features in Ecore_X.h - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.72988slp2+build02 - - -- Doyoun Kang Thu, 05 Jul 2012 16:22:21 +0900 - -ecore (1.2.0+svn.72988slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.72988slp2+build01 - - -- Jiyoun Park Wed, 04 Jul 2012 18:31:50 +0900 - -ecore (1.2.0+svn.70444slp2+build06) unstable; urgency=low - - * Added per-window profile feature to support multi-head display. - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.70444slp2+build06 - - -- Gwanglim Lee Tue, 19 Jun 2012 18:34:11 +0900 - -ecore (1.2.0+svn.70444slp2+build05) unstable; urgency=low - - * Add feature - floating mode (app-in-app) - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.70444slp2+build05 - - -- Doyoun Kang Tue, 05 Jun 2012 15:17:17 +0900 - -ecore (1.2.0+svn.70444slp2+build04) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.70444slp2+build04 - - -- Jiyoun Park Tue, 29 May 2012 17:07:07 +0900 - -ecore (1.2.0+svn.70444slp2+build03) unstable; urgency=low - - * add disable-ecore-imf-xim option - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.70444slp2+build03 - - -- Jihoon Kim Tue, 22 May 2012 16:05:56 +0900 - -ecore (1.2.0+svn.70444slp2+build02) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.70444slp2+build02 - - -- Myungjae Lee Wed, 25 Apr 2012 17:28:30 +0900 - -ecore (1.2.0+svn.70444slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.70444slp2+build01 - - -- Myungjae Lee Wed, 25 Apr 2012 15:13:33 +0900 - -ecore (1.2.0+svn.70302slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.70302slp2+build01 - - -- Jaehwan Kim Mon, 23 Apr 2012 15:28:49 +0900 - -ecore (1.2.0+svn.70251slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.70251slp2+build01 - - -- Hyoyoung Chang Wed, 18 Apr 2012 18:03:09 +0900 - -ecore (1.2.0+svn.70159slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.70159slp2+build01 - - -- Jiyoun Park Fri, 13 Apr 2012 18:31:50 +0900 - -ecore (1.2.0+svn.69928slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.2.0+svn.69928slp2+build01 - - -- Jeonghyun Yun Fri, 06 Apr 2012 18:14:52 +0900 - -ecore (1.1.0+svn.69655slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.69655slp2+build01 - - -- Jeonghyun Yun Wed, 28 Mar 2012 14:28:49 +0900 - -ecore (1.1.0+svn.69424slp2+build03) unstable; urgency=low - - * [ECORE_X] remove feature - illume window state for app-in-app - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.69424slp2+build03 - - -- Doyoun Kang Mon, 26 Mar 2012 13:56:33 +0900 - -ecore (1.1.0+svn.69424slp2+build02) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.69424slp2+build02 - - -- Jeonghyun Yun Sun, 18 Mar 2012 14:02:16 +0900 - -ecore (1.1.0+svn.69424slp2+build01) unstable; urgency=low - - * EFL migration - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.69424slp2+build01 - - -- Jeonghyun Yun Fri, 16 Mar 2012 21:50:01 +0900 - -ecore (1.1.0+svn.69115slp2+build04) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.69115slp2+build04 - - -- WooHyun Jung Thu, 15 Mar 2012 21:23:10 +0900 - -ecore (1.1.0+svn.69115slp2+build03) unstable; urgency=low - - * [Ecore_X] Remove unused APIs, unused Atoms and duplicated Atoms - - ecore_x_e_comp_dri_buff_flip_supported_set - - ecore_x_e_comp_dri_buff_flip_supported_get - - ECORE_X_ATOM_E_USER_CREATED_WINDOW - - ECORE_X_ATOM_E_PARENT_BORDER_WINDOW - - ECORE_X_ATOM_E_COMP_DRI_BUFF_FLIP_SUPPORTED - - ECORE_X_ATOM_E_ILLUME_ROTATE_OPERATOR - - ECORE_X_ATOM_USER_CREATED_WINDOW - - ECORE_X_ATOM_PARENT_BORDER_WINDOW - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.69115slp2+build03 - - -- Doyoun Kang Wed, 14 Mar 2012 09:01:03 +0900 - -ecore (1.1.0+svn.69115slp2+build02) unstable; urgency=low - - * Change parameter of ecore_imf_context_input_panel_language_locale_get - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.69115slp2+build02 - - -- Jihoon Kim Mon, 12 Mar 2012 14:43:53 +0900 - -ecore (1.1.0+svn.69115slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.69115slp2+build01 - - -- Jeonghyun Yun Sat, 10 Mar 2012 13:51:23 +0900 - -ecore (1.1.0+svn.68762slp2+build02) unstable; urgency=low - - * 69115 - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.68762slp2+build02 - - -- Jeonghyun Yun Sat, 10 Mar 2012 13:20:45 +0900 - -ecore (1.1.0+svn.68762slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.68762slp2+build01 - - -- Jeonghyun Yun Wed, 07 Mar 2012 16:44:23 +0900 - -ecore (1.1.0+svn.68529slp2+build01) unstable; urgency=low - - * Package upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.68529slp2+build01 - - -- Jeonghyun Yun Fri, 02 Mar 2012 06:32:15 -0500 - -ecore (1.1.0+svn.67695slp2+build06) unstable; urgency=low - - * [ecore_imf] add language_locale_get, candidate_panel_geometry_get API - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.67695slp2+build06 - - -- Jihoon Kim Fri, 02 Mar 2012 11:44:15 +0900 - -ecore (1.1.0+svn.67695slp2+build05) unstable; urgency=low - - * [ecore_imf] add ecore_imf_context_input_panel_caps_lock_mode_set/get - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.67695slp2+build05 - - -- Jihoon Kim Wed, 29 Feb 2012 14:21:16 +0900 - -ecore (1.1.0+svn.67695slp2+build04) unstable; urgency=low - - * [ecore_imf] cleanup code - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.67695slp2+build04 - - -- Jihoon Kim Thu, 23 Feb 2012 17:36:50 +0900 - -ecore (1.1.0+svn.67695slp2+build03) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.67695slp2+build03 - - -- ChunEon Park Mon, 20 Feb 2012 20:15:54 +0900 - -ecore (1.1.0+svn.67695slp2+build02) unstable; urgency=low - - * Add APIs related to input panel control - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.67695slp2+build02 - - -- Jihoon Kim Mon, 20 Feb 2012 09:23:47 +0900 - -ecore (1.1.0+svn.67695slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.67695slp2+build01 - - -- Jaehwan Kim Wed, 15 Feb 2012 19:01:02 +0900 - -ecore (1.1.0+svn.66972slp2+build03) unstable; urgency=low - - * [ECORE_X] Add feature - illume window state for app-in-app - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.66972slp2+build03 - - -- Doyoun Kang Thu, 02 Feb 2012 15:04:12 +0900 - -ecore (1.1.0+svn.66972slp2+build02) unstable; urgency=low - - * Use synchronous ecore_imf callback API - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.66972slp2+build02 - - -- Jihoon Kim Tue, 31 Jan 2012 13:21:06 +0900 - -ecore (1.1.0+svn.66972slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.66972slp2+build01 - - -- Jaehwan Kim Mon, 16 Jan 2012 18:29:42 +0900 - -ecore (1.1.0+svn.65878slp2+build05) unstable; urgency=low - - * jpeg7 -> jpeg8 - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.65878slp2+build05 - - -- ChunEon Park Mon, 16 Jan 2012 11:14:18 +0900 - -ecore (1.1.0+svn.65878slp2+build04) unstable; urgency=low - - * Repackaging - * Git: slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.65878slp2+build04 - - -- ChunEon Park Fri, 30 Dec 2011 15:07:27 +0900 - -ecore (1.1.0+svn.65878slp2+build03) unstable; urgency=low - - * Just Bumped up version - * Git: slp-scm.sec.samsung.net:slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.65878slp2+build03 - - -- Tae-Hwan Kim Mon, 26 Dec 2011 15:20:31 +0900 - -ecore (1.1.0+svn.65878slp2+build02) unstable; urgency=low - - * Upstream sync related ecore_con (r66414, 66462, sync after r65934) - * ecore_timer_dump is disabled as default - * Git: slp-scm.sec.samsung.net:slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.65878slp2+build02 - - -- Tae-Hwan Kim Fri, 23 Dec 2011 18:07:06 +0900 - -ecore (1.1.0+svn.65878slp2+build01) unstable; urgency=low - - * Package Upload for migration - * Git: slp-scm.sec.samsung.net:slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.65878slp2+build01 - - -- Jaehwan Kim Thu, 08 Dec 2011 13:51:03 +0900 - -ecore (1.1.0+svn.65618slp2+build02) unstable; urgency=low - - * [Bug Fix] CQ H0100136744 - curl fd handler refactoring - * Git: slp-scm.sec.samsung.net:slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.65618slp2+build02 - - -- Tae-Hwan Kim Tue, 29 Nov 2011 17:43:36 +0900 - -ecore (1.1.0+svn.65618slp2+build01) unstable; urgency=low - - * Package Upload - * Git: slp-scm.sec.samsung.net:slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.65618slp2+build01 - - -- Jaehwan Kim Tue, 29 Nov 2011 14:11:22 +0900 - -ecore (1.1.0+svn.65303slp2+build04) unstable; urgency=low - - * Add a configure option to enable ecore x gesture extension support - * Add libxgesture-dev on Build-Depends section in debian/control - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.65303slp2+build04 - - -- Sung-Jin Park Fri, 18 Nov 2011 11:11:27 +0900 - -ecore (1.1.0+svn.65303slp2+build03) unstable; urgency=low - - * Package Upload : because of build error - * Important Changes - Rollback about dependency with cares - Caused some app's build error about no Elementary.h - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.1.0+svn.65303slp2+build03 - - -- WooHyun Jung Thu, 17 Nov 2011 19:10:33 +0900 - -ecore (1.1.0+svn.65303slp2+build02) unstable; urgency=low - - * Enable c-ARES based aync DNS resolution - - -- Mike McCormack Thu, 17 Nov 2011 17:46:57 +0900 - -ecore (1.1.0+svn.65303slp2+build01) unstable; urgency=low - - * Merge with upstream @65303 - - -- Mike McCormack Thu, 17 Nov 2011 09:05:24 +0900 - -ecore (1.0.0.001+svn.64964slp2+build02) unstable; urgency=low - - * [ecore_imf] remove unused interfaces - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.64964slp2+build02 - - -- Jihoon Kim Mon, 14 Nov 2011 15:19:52 +0900 - -ecore (1.0.0.001+svn.64964slp2+build01) unstable; urgency=low - - * Merge with upstream @64964 - - -- Mike McCormack Thu, 10 Nov 2011 12:12:11 +0900 - -ecore (1.0.0.001+svn.64661slp2+build04) unstable; urgency=low - - * [ecore_imf] remove depecated APIs - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.64661slp2+build04 - - -- Jihoon Kim Thu, 10 Nov 2011 09:28:41 +0900 - -ecore (1.0.0.001+svn.64661slp2+build03) unstable; urgency=low - - * Ecore, Ecore_con, Ecore_file: merge upstream r64851 - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.64661slp2+build03 - - -- Tae-Hwan Kim Tue, 08 Nov 2011 14:17:28 +0900 - -ecore (1.0.0.001+svn.64661slp2+build02) unstable; urgency=low - - * [ecore evas] fix rotation lockup problem - when application's window is unmapped - * [ecore evas] fix sync counter lockup problem with application - which rapidly maps and unmaps a window - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.64661slp2+build02 - - -- Gwanglim Lee Fri, 04 Nov 2011 13:45:05 +0900 - -ecore (1.0.0.001+svn.64661slp2+build01) unstable; urgency=low - - * Merge with upstream @64661 - - -- Mike McCormack Thu, 03 Nov 2011 11:19:25 +0900 - -ecore (1.0.0.001+svn.63888slp2+build07) unstable; urgency=low - - * [ecore con url] Change HTTP persistent --> normal - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.63888slp2+build07 - - -- Tae-Hwan Kim Wed, 02 Nov 2011 17:56:11 +0900 - -ecore (1.0.0.001+svn.63888slp2+build06) unstable; urgency=low - - * Deprecated some Ecore_IMF APIs - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.63888slp2+build06 - - -- Jihoon Kim Wed, 02 Nov 2011 12:41:49 +0900 - -ecore (1.0.0.001+svn.63888slp2+build05) unstable; urgency=low - - * Upload package - * Important Changes - Add new api related with get last recently requested geometry value - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.63888slp2+build05 - - -- Jiyoun Park Mon, 31 Oct 2011 15:23:33 +0900 - -ecore (1.0.0.001+svn.63888slp2+build04) unstable; urgency=low - - * Package Upload - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.63888slp2+build04 - - -- Tae-Hwan Kim Mon, 31 Oct 2011 10:25:07 +0900 - -ecore (1.0.0.001+svn.63888slp2+build03) unstable; urgency=low - - * Upload package - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.63888slp2+build03 - - -- Jihoon Kim Tue, 25 Oct 2011 20:51:15 +0900 - -ecore (1.0.0.001+svn.63888slp2+build02) unstable; urgency=low - - * Upload Package - * Important Changes - ecore evas util can send resize request even though X relpy - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.63888slp2+build02 - - -- Jiyoun Park Tue, 25 Oct 2011 18:08:02 +0900 - -ecore (1.0.0.001+svn.63888slp2+build01) unstable; urgency=low - - * Merge with upstream - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.63888slp2+build01 - - -- Mike McCormack Fri, 07 Oct 2011 11:41:21 +0900 - -ecore (1.0.0.001+svn.63811slp2+build01) unstable; urgency=low - - * merge with upstream - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.63811slp2+build01 - - -- Mike McCormack Wed, 05 Oct 2011 15:34:39 +0900 - -ecore (1.0.0.001+svn.62653slp2+build02) unstable; urgency=low - - * [SVN patch] ecore in SLP is merged with SVN r63475 patch only. - - fix bug in generic event handling on xlib side of ecore_x - * Ecore_IMF: remove unused enum ECORE_IMF_Autocorrection - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.62653slp2+build02 - - -- Doyoun Kang Mon, 26 Sep 2011 20:01:42 +0900 - -ecore (1.0.0.001+svn.62653slp2+build01) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r62653 - * Important Changes - [Migration upstream r62653] Merge branch 'svn_merge' - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.62653slp2+build01 - - -- Jaehwan Kim Fri, 02 Sep 2011 18:43:09 +0900 - -ecore (1.0.0.001+svn.61784slp2+build02) unstable; urgency=low - - * [ecore_x] fixed multi-touch double clicked - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.61784slp2+build02 - - -- ChunEon Park Wed, 31 Aug 2011 19:42:43 +0900 - -ecore (1.0.0.001+svn.61784slp2+build01) unstable; urgency=low - - * Merge with upstream ecore svn @61784 - - -- Mike McCormack Wed, 27 Jul 2011 14:43:58 +0900 - -ecore (1.0.0.001+svn.61150slp2+build03) unstable; urgency=low - - * [ecore_imf] set autocapital type - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.61150slp2+build03 - - -- Jihoon Kim Mon, 25 Jul 2011 14:30:29 +0900 - -ecore (1.0.0.001+svn.61150slp2+build02) unstable; urgency=low - - * [ecore_imf] add ecore_imf_context_cursor_location_set API - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.61150slp2+build02 - - -- Jihoon Kim Mon, 11 Jul 2011 16:13:56 +0900 - -ecore (1.0.0.001+svn.61150slp2+build01) unstable; urgency=low - - * Merge with SVN revision 61150 - - -- Mike McCormack Thu, 07 Jul 2011 15:10:51 +0900 - -ecore (1.0.0.001+svn.60286slp2+build02) unstable; urgency=low - - * [ecore_imf] add ecore_imf_context_input_panel_enalbed_set, get API - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.60286slp2+build02 - - -- Jihoon Kim Sat, 25 Jun 2011 15:11:35 +0900 - -ecore (1.0.0.001+svn.60286slp2+build01) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r60286 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.60286slp2+build01 - - -- Jaehwan Kim Fri, 24 Jun 2011 18:10:02 +0900 - -ecore (1.0.0.001+svn.58224slp2+build04) unstable; urgency=low - - * Fixed _ecore_main_loop_iterate_internal. Upstream merge. - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.58224slp2+build04 - - -- Daniel Juyung Seo Mon, 23 May 2011 14:20:58 +0900 - -ecore (1.0.0.001+svn.58224slp2+build03) unstable; urgency=low - - * Package upload - * Git: slp-scm.sec.samsung.net:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.58224slp2+build03 - - -- Jaehwan Kim Tue, 03 May 2011 20:48:31 +0900 - -ecore (1.0.0.001+svn.58224slp2+build02) unstable; urgency=low - - * Add shape input mask feature (upstream svn rev.58621) - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.58224slp2+build02 - - -- Doyoun Kang Mon, 11 Apr 2011 12:52:50 +0900 - -ecore (1.0.0.001+svn.58224slp2+build01) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r58224 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.58224slp2+build01 - - -- Jaehwan Kim Tue, 05 Apr 2011 15:55:04 +0900 - -ecore (1.0.0.001+svn.58047slp2+build02) unstable; urgency=low - - * Rollback - * Git: slp-scm.sec.samsung.net:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.58047slp2+build02 - - -- Shinwoo Kim Tue, 29 Mar 2011 23:52:57 +0900 - -ecore (1.0.0.001+svn.58047slp2+build01) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r58047 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.58047slp2+build01 - - -- Shinwoo Kim Tue, 29 Mar 2011 18:55:29 +0900 - -ecore (1.0.0.001+svn.57453slp2+build05) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r57453 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.57453slp2+build05 - - -- Myungjae Lee Wed, 09 Mar 2011 11:29:41 +0900 - -ecore (1.0.0.001+svn.57453slp2+build04) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r57453 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.57453slp2+build04 - - -- Myungjae Lee Wed, 09 Mar 2011 11:14:55 +0900 - -ecore (1.0.0.001+svn.57453slp2+build03) unstable; urgency=low - - * Package Uplaod : Rollback - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.57453slp2+build03 - - -- WooHyun Jung Tue, 08 Mar 2011 12:38:42 +0900 - -ecore (1.0.0.001+svn.57453slp2+build02) unstable; urgency=low - - * Package Upload : rollback - * Git: 165.213.180.234:/slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.57453slp2+build02 - - -- WooHyun Jung Tue, 08 Mar 2011 11:10:05 +0900 - -ecore (1.0.0.001+svn.57453slp2+build01) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r57453 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.57453slp2+build01 - - -- Myungjae Lee Mon, 07 Mar 2011 17:28:10 +0900 - -ecore (1.0.0.001+svn.56239slp2+build06) unstable; urgency=low - - * [SVN r56251] Bug fix - dont call pipe handler if its deleted. - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.56239slp2+build06 - - -- WooHyun Jung Fri, 11 Feb 2011 17:52:58 +0900 - -ecore (1.0.0.001+svn.56239slp2+build05) unstable; urgency=low - - * [SVN r56251] Bug fix - dont call pipe handler if its deleted. - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.56239slp2+build05 - - -- Myoungwoon Kim Tue, 08 Feb 2011 15:21:18 +0900 - -ecore (1.0.0.001+svn.56239slp2+build04) unstable; urgency=low - - * [ecore_evas_x.c] apply ECORE_EVAS_GL_SYNC_DRAW_DONE env. - + check whether GL driver sends SYNC_DRAW_DONE msg after buffer copy. - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.56239slp2+build04 - - -- Gwanglim Lee Sat, 05 Feb 2011 17:29:55 +0900 - -ecore (1.0.0.001+svn.56239slp2+build03) unstable; urgency=low - - * ee->no_comp_sync = 0 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.56239slp2+build03 - - -- WooHyun Jung Mon, 31 Jan 2011 18:26:53 +0900 - -ecore (1.0.0.001+svn.56239slp2+build02) unstable; urgency=low - - * ee->no_comp_sync = 0 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.56239slp2+build02 - - -- WooHyun Jung Mon, 31 Jan 2011 17:12:38 +0900 - -ecore (1.0.0.001+svn.56239slp2+build01) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r56239 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.56239slp2+build01 - - -- WooHyun Jung Thu, 27 Jan 2011 12:21:58 +0900 - -ecore (1.0.0.001+svn.56091slp2+build01) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r56091 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.56091slp2+build01 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.56091slp2+build01 - - -- WooHyun Jung Wed, 19 Jan 2011 16:16:45 +0900 - -ecore (1.0.0.001+svn.55755slp2+build02) unstable; urgency=low - - * [ecore_imf] bug fix : hide keyboard in ecore_imf_context_del - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.55755slp2+build02 - - -- Jihoon Kim Wed, 05 Jan 2011 08:44:58 +0900 - -ecore (1.0.0.001+svn.55755slp2+build01) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r55755 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.55755slp2+build01 - - -- Jaehwan Kim Mon, 03 Jan 2011 21:19:00 +0900 - -ecore (1.0.0.001+svn.55594slp2+build02) unstable; urgency=low - - * Bug patch - ecore_x_xregion_is_empty() - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.55594slp2+build02 - - -- Doyoun Kang Mon, 03 Jan 2011 12:56:39 +0900 - -ecore (1.0.0.001+svn.55594slp2+build01) unstable; urgency=low - - * [SVN EFL Migration] ecore in SLP is merged with SVN r55594 - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.55594slp2+build01 - - -- Jaehwan Kim Wed, 22 Dec 2010 20:01:47 +0900 - -ecore (1.0.0.001+svn.55371slp2+build02) unstable; urgency=low - - * epoll disabled. - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.55371slp2+build02 - - -- WooHyun Jung Wed, 15 Dec 2010 16:37:29 +0900 - -ecore (1.0.0.001+svn.55371slp2+build01) unstable; urgency=low - - * [SVN's EFL Migration] ecore in SLP is merged with SVN r55371. - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.55371slp2+build01 - - -- Juyung Seo Tue, 14 Dec 2010 17:50:20 +0900 - -ecore (1.0.0.001+svn.55079slp2+build03) unstable; urgency=low - - * [SVN's EFL Migration] ecore in SLP is merged with SVN r55371. - * Git: 165.213.180.234:slp/pkgs/e/ecore - * Tag: ecore_1.0.0.001+svn.55079slp2+build03 - - -- Juyung Seo Tue, 14 Dec 2010 14:54:04 +0900 - -ecore (1.0.0.001+svn.55079slp2+build02) unstable; urgency=low - - * remove epoll - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.55079slp2+build02 - - -- Jaehwan Kim Thu, 02 Dec 2010 17:28:23 +0900 - -ecore (1.0.0.001+svn.55079slp2+build01) unstable; urgency=low - - * [SVN 55079 Merge] - * Update to SVN Revision 55079. - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.55079slp2+build01 - - -- Myoungwoon Kim Thu, 02 Dec 2010 09:18:09 +0900 - -ecore (1.0.0.001+svn.51480slp2+build28) unstable; urgency=low - - * [ecore_evas] Patch code for rotation. - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build28 - - -- Doyoun Kang Mon, 29 Nov 2010 10:14:56 +0900 - -ecore (1.0.0.001+svn.51480slp2+build27) unstable; urgency=low - - * [ecore_evas.c] change FPS rate print it every 0.1 sec - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build27 - - -- Seokjae Jeong Sat, 27 Nov 2010 15:06:21 +0900 - -ecore (1.0.0.001+svn.51480slp2+build26) unstable; urgency=low - - * [ecore_imf] remove unused typedefs - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build26 - - -- Jihoon Kim Fri, 26 Nov 2010 17:56:05 +0900 - -ecore (1.0.0.001+svn.51480slp2+build25) unstable; urgency=low - - * [SVN 54830 Merge] - * Update to SVN Revision 54830. - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build25 - - -- Juyung Seo Fri, 26 Nov 2010 15:31:53 +0900 - -ecore (1.0.0.001+svn.51480slp2+build19) unstable; urgency=low - - * libcurl-dev -> libcurl4-openssl-dev - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build19 - - -- ChunEon Park Thu, 18 Nov 2010 21:26:21 +0900 - -ecore (1.0.0.001+svn.51480slp2+build18) unstable; urgency=low - - * [ecore_x] Add feature for sliding window - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build18 - - -- Doyoun Kang Thu, 11 Nov 2010 10:53:35 +0900 - -ecore (1.0.0.001+svn.51480slp2+build17) unstable; urgency=low - - * [ecore_imf] ecore_imf_context_input_panel_language_set - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build17 - - -- Jihoon Kim Tue, 09 Nov 2010 15:08:12 +0900 - -ecore (1.0.0.001+svn.51480slp2+build16) unstable; urgency=low - - * fix documentation of ecore_imf - * [src/lib/ecore_evas/Ecore_Evas.h] svn merge v51740. - * [svn merge] r51678~r51707 - * [svn merge] Changeset 51650 - Revert and reapply badnull patch - * [ecore_evas] svn 51618 : Add UNUSED where missing. - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build16 - - -- Jihoon Kim Wed, 13 Oct 2010 16:54:37 +0900 - -ecore (1.0.0.001+svn.51480slp2+build15) unstable; urgency=low - - * fixed epoll - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build15 - - -- ChunEon Park Tue, 05 Oct 2010 10:39:49 +0900 - -ecore (1.0.0.001+svn.51480slp2+build14) unstable; urgency=low - - * [ecore_x_events.c] fixed double / triple click - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build14 - - -- ChunEon Park Mon, 04 Oct 2010 21:38:13 +0900 - -ecore (1.0.0.001+svn.51480slp2+build13) unstable; urgency=low - - * [ecore_evas] add EFL window rotation effect - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build13 - - -- Gwanglim Lee Sat, 02 Oct 2010 03:37:56 +0900 - -ecore (1.0.0.001+svn.51480slp2+build12) unstable; urgency=low - - * [ecore_imf] svn merge 52773 - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build12 - - -- Jihoon Kim Wed, 30 Sep 2010 09:56:30 +0900 - -ecore (1.0.0.001+svn.51480slp2+build10) unstable; urgency=low - - * update x_selection from upstream - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build10 - - -- Hyoyoung Chang Mon, 27 Sep 2010 17:27:38 +0900 - -ecore (1.0.0.001+svn.51480slp2+build09) unstable; urgency=low - - * repackaging - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build09 - - -- ChunEon Park Mon, 20 Sep 2010 21:42:20 +0900 - -ecore (1.0.0.001+svn.51480slp2+build08) unstable; urgency=low - - * Add ecore_imf_context_input_panel_caps_mode_set - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build08 - - -- Jihoon Kim Fri, 17 Sep 2010 15:48:17 +0900 - -ecore (1.0.0.001+svn.51480slp2+build07) unstable; urgency=low - - * Repackage for epoll disable - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build07 - - -- Hyoyoung Chang Fri, 17 Sep 2010 12:03:07 +0900 - -ecore (1.0.0.001+svn.51480slp2+build06) unstable; urgency=low - - * Repackage for epoll disable - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build06 - - -- WooHyun Jung Wed, 15 Sep 2010 18:15:43 +0900 - -ecore (1.0.0.001+svn.51480slp2+build05) unstable; urgency=low - - * Repackage for epoll disable - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build05 - - -- WooHyun Jung Wed, 15 Sep 2010 11:39:28 +0900 - -ecore (1.0.0.001+svn.51480slp2+build04) unstable; urgency=low - - * add as-needed - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build04 - - -- Jaehwan Kim Wed, 15 Sep 2010 10:00:16 +0900 - -ecore (1.0.0.001+svn.51480slp2+build03) unstable; urgency=low - - * repackage for stopping EPOLL fucntionality - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build03 - - -- WooHyun Jung Tue, 14 Sep 2010 16:05:25 +0900 - -ecore (1.0.0.001+svn.51480slp2+build02) unstable; urgency=low - - * repackage - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build02 - - -- Jaehwan Kim Fri, 10 Sep 2010 22:38:46 +0900 - -ecore (1.0.0.001+svn.51480slp2+build01) unstable; urgency=low - - * [ecore] Merge slp with SVN - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_1.0.0.001+svn.51480slp2+build01 - - -- Jaehwan Kim Wed, 01 Sep 2010 10:31:12 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build15) unstable; urgency=low - - * [rules] add disable-xim (from Wonkuk Jung) - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build15 - - -- Juyung Seo Wed, 01 Sep 2010 21:52:08 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build14) unstable; urgency=low - - * [ecore_x] fix sync issue in 1 special event re-order case. ( Changeset r51609 ) - * Reference : http://trac.enlightenment.org/e/changeset/51609 - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build14 - - -- Gwan-gyeong Mun Mon, 30 Aug 2010 08:46:33 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build13) unstable; urgency=low - - * [ecore_imf] add MONTH, NUMBERONLY Layout - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build13 - - -- Jihoon Kim Fri, 20 Aug 2010 11:23:12 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build12) unstable; urgency=low - - * [ecore_imf] change parameter type of event_callback_add - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build12 - - -- Jihoon Kim Fri, 30 Jul 2010 14:57:28 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build11) unstable; urgency=low - - * [ecore_imf] fix memory leak when private key or disable key func is used - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build11 - - -- Jihoon Kim Fri, 30 Jul 2010 14:32:07 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build10) unstable; urgency=low - - * Remove deprecated Ecore_IMF APIs. - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build10 - - -- Jihoon Kim Tue, 20 Jul 2010 18:17:00 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build09) unstable; urgency=low - - * Repackage for beat release. - * Git: 165.213.180.234:/git/slp/pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build09 - - -- WooHyun Jung Mon, 19 Jul 2010 10:47:44 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build08) unstable; urgency=low - - * add the ECORE_X_ATOM_PARENT_BORDER_WINDOW atom. - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build08 - - -- Gwanglim Lee Wed, 14 Jul 2010 15:41:35 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build07) unstable; urgency=low - - * Ecore_IMF API is revised. - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build07 - - -- Jihoon Kim Thu, 08 Jul 2010 17:14:29 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build06) unstable; urgency=low - - * add ecore_evas_gl_x11_no_swap_set for supporting lock/unlock feature. - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build06 - - -- ChunEon Park Wed, 07 Jul 2010 20:03:15 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build05) unstable; urgency=low - - * add ecore_evas_gl_x11_no_swap_set for supporting lock/unlock feature. - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build05 - - -- Gwanglim Lee Tue, 29 Jun 2010 18:58:38 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build04) unstable; urgency=low - - * Packaging. - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build04 - - -- Daniel Juyung Seo Thu, 10 Jun 2010 21:09:25 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build03) unstable; urgency=low - - * Packaging. - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build03 - - -- Daniel Juyung Seo Thu, 10 Jun 2010 21:04:09 +0900 - -ecore (0.9.9.060+svn.49540slp2+3build02) unstable; urgency=low - - * Packaging. - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3build02 - - -- Daniel Juyung Seo 목, 10 6월 2010 21:00:51 +0900 - -ecore (0.9.9.060+svn.49540slp2+3) unstable; urgency=low - - * Packaging. - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+3 - - -- Daniel Juyung Seo Thu, 10 Jun 2010 20:46:54 +0900 - -ecore (0.9.9.060+svn.49540slp2+2) unstable; urgency=low - - * Packaging. - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+2 - - -- Daniel Juyung Seo Thu, 10 Jun 2010 20:46:08 +0900 - -ecore (0.9.9.060+svn.49540slp2+1) unstable; urgency=low - - * Packaging. - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/ecore - * Tag: ecore_0.9.9.060+svn.49540slp2+1 - - -- Daniel Juyung Seo Thu, 10 Jun 2010 20:45:22 +0900 - -ecore (0.9.9.060+svn.49540slp2+0) unstable; urgency=low - - * Update opensource EFL from SVN - * SVN revision: 49540 (Total EFL revision: 49550) - * Tag: 0.9.9.060+svn.49540slp2+0 - - -- Daniel Juyung Seo Thu, 10 Jun 2010 15:50:38 +0900 - -ecore (0.9.9.060+svn20100304slp2+4) unstable; urgency=low - - * Enable curl - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL - * Tag: ecore_0.9.9.060+svn20100304slp2+4 - - -- Sangjin Lee Wed, 14 Apr 2010 17:54:37 +0900 - -ecore (0.9.9.060+svn20100304slp2+3) unstable; urgency=low - - * change control - add libeina-svn-04 dependency to libecore-svn-01 - * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL - * Tag: 9.9.060+svn20100304slp2+3 - - -- Jaehwan Kim Thu, 01 Apr 2010 16:50:07 +0900 - -ecore (0.9.9.060+svn20100304slp2+2) unstable; urgency=low - - * add document in ecore_imf and cleanup - - -- Jihoon Kim Tue, 30 Mar 2010 16:55:51 +0900 - -ecore (0.9.9.060+svn20100304slp2+1) unstable; urgency=low - - * change package version - - -- Jaehwan Kim Thu, 25 Mar 2010 15:05:10 +0900 - -ecore (0.9.9.060+svn20100304-5) unstable; urgency=low - - * Upgrade ecore to 47360 - - -- Sangjin Lee Mon, 22 Mar 2010 20:52:51 +0900 - -ecore (0.9.9.060+svn20100304-4) unstable; urgency=low - - * Modifed keydefs.h for resolving macro name conflicts - - -- Ji-hoon Lee Mon, 22 Mar 2010 16:03:48 +0900 - -ecore (0.9.9.060+svn20100304-3) unstable; urgency=low - - * Added keydefs.h for identifying key index - - -- Ji-hoon Lee Fri, 19 Mar 2010 20:20:43 +0900 - -ecore (0.9.9.060+svn20100304-2) unstable; urgency=low - - * Fix debian/libecore-dev.install not to omit symbolic links for shared objects - - -- Sung-Jin Park Tue, 16 Mar 2010 21:26:16 +0900 - -ecore (0.9.9.060+svn20100304-1) unstable; urgency=low - - * EFL_update_revision_46864 - - -- Jaehwan Kim Thu, 11 Mar 2010 10:50:35 +0900 - -ecore (0.9.9.060+svn20100203-16) unstable; urgency=low - - * Modify shape input mask - - -- Sangjin Lee Thu, 11 Mar 2010 10:42:52 +0900 - -ecore (0.9.9.060+svn20100203-15) unstable; urgency=low - - * Modify ecore_x_window_hide(). - + In order to avoid ISE lockup problem, we ensure that root window - receives UnmapNotify event. - - -- Gwanglim Lee Wed, 10 Mar 2010 17:07:18 +0900 - -ecore (0.9.9.060+svn20100203-14) unstable; urgency=low - - * Merge source (based on SVN rev.46421). - * Add ecore_data library. - - -- Doyoun Kang Thu, 04 Mar 2010 20:17:30 +0900 - -ecore (0.9.9.060+svn20100203-13) unstable; urgency=low - - * Rollback to source (0.9.9.060+svn20100203-10) - - -- Doyoun Kang Thu, 04 Mar 2010 14:26:58 +0900 - -ecore (0.9.9.060+svn20100203-12) unstable; urgency=low - - * Merge the latest ecore_imf - - -- Jihoon Kim Thu, 04 Mar 2010 13:21:57 +0900 - -ecore (0.9.9.060+svn20100203-11) unstable; urgency=low - - * Merge source (based on SVN rev.46421) - - -- Doyoun Kang Thu, 04 Mar 2010 12:17:19 +0900 - -ecore (0.9.9.060+svn20100203-10) unstable; urgency=low - - * Add ecore_imf_context_ise_event_callback_set API. ise_state_add_listener, remove_listener, change_listener will be deprecated. - - -- Jihoon Kim Tue, 02 Mar 2010 17:52:58 +0900 - -ecore (0.9.9.060+svn20100203-9) unstable; urgency=low - - * Patch for ecore_evas_x_alpha_set - - -- Sangjin Lee Sat, 27 Feb 2010 20:44:34 +0900 - -ecore (0.9.9.060+svn20100203-8) unstable; urgency=low - - * add more ISE_EVENT types - - -- Jihoon Kim Thu, 25 Feb 2010 17:09:28 +0900 - -ecore (0.9.9.060+svn20100203-7) unstable; urgency=low - - * add ecore_imf_context_ise_get_window_rect API - - -- Jihoon Kim Tue, 23 Feb 2010 20:42:39 +0900 - -ecore (0.9.9.060+svn20100203-6) unstable; urgency=low - - * revision update to 46263. (partial merge) - * add atoms for rotation. - - -- Doyoun Kang Thu, 18 Feb 2010 19:37:45 +0900 - -ecore (0.9.9.060+svn20100203-5) unstable; urgency=low - - * elm_win_transparent apply - - -- Jaehwan Kim Thu, 11 Feb 2010 15:12:01 +0900 - -ecore (0.9.9.060+svn20100203-4) unstable; urgency=low - - * Add rotate with resize. - - -- Doyoun Kang Mon, 08 Feb 2010 14:14:00 +0900 - -ecore (0.9.9.060+svn20100203-3) unstable; urgency=low - - * repack - - -- sangho park Thu, 04 Feb 2010 22:04:12 +0900 - -ecore (0.9.9.060+svn20100203-2) unstable; urgency=low - - * repack - - -- Jaehwan Kim Thu, 04 Feb 2010 20:27:43 +0900 - -ecore (0.9.9.060+svn20100203-1) unstable; urgency=low - - * EFL_update_revision_45828 - - -- Jaehwan Kim Wed, 03 Feb 2010 16:39:21 +0900 - -ecore (0.9.9.060+svn20100119-2) unstable; urgency=low - - * updated ISF files - - -- sehwan Thu, 21 Jan 2010 23:23:29 +0900 - -ecore (0.9.9.060+svn20100119-1) unstable; urgency=low - - * EFL_update_revision_45322 - - -- Jihoon Kim Tue, 19 Jan 2010 20:44:48 +0900 - -ecore (0.9.9.060+svn20100111-4) unstable; urgency=low - - * changed ecore-imf for isf - - -- sehwan Fri, 15 Jan 2010 15:06:31 +0900 - -ecore (0.9.9.060+svn20100111-3) unstable; urgency=low - - * reupload EFL i686 - - -- Jaehwan Kim Tue, 12 Jan 2010 17:35:33 +0900 - -ecore (0.9.9.060+svn20100111-2) unstable; urgency=low - - * reupload EFL - - -- Jaehwan Kim Mon, 11 Jan 2010 22:16:49 +0900 - -ecore (0.9.9.060+svn20100111-1) unstable; urgency=low - - * update EFL revision 45026 - - -- Jaehwan Kim Mon, 11 Jan 2010 13:28:04 +0900 - -ecore (0.9.9.060+svn20091229-3) unstable; urgency=low - - * To solve version mismatch between i386 and armel. - * No source code changed. - - -- Jongwoo Chae Thu, 07 Jan 2010 21:47:34 +0900 - -ecore (0.9.9.060+svn20091229-2) unstable; urgency=low - - * Changed ecore_imf for isf package - - -- Ji-hoon Lee Wed, 06 Jan 2010 13:55:00 +0900 - -ecore (0.9.9.060+svn20091229-1) unstable; urgency=low - - * update EFL - - -- Jaehwan Kim Tue, 29 Dec 2009 14:27:03 +0900 - -ecore (0.9.9.060+svn20091112-6) unstable; urgency=low - - * modified debian/control to link libcurl - - -- Jihoon Kim Tue, 29 Dec 2009 19:31:19 +0900 - - -ecore (0.9.9.060+svn20091112-5) unstable; urgency=low - - * modified debian/control : changed Architecture all to any (by Juyung Seo) - - -- Sangho Park Fri, 27 Nov 2009 15:59:07 +0900 - -ecore (0.9.9.060+svn20091112-4) unstable; urgency=low - - * svn stable version - - -- Sangho Park Thu, 19 Nov 2009 18:50:08 +0900 - -ecore (0.9.9.060+svn20091112-3) unstable; urgency=low - - * add build dependency glib - - -- Sangho Park Tue, 17 Nov 2009 21:37:23 +0900 - -ecore (0.9.9.060+svn20091112-2) unstable; urgency=low - - * add glib dependency - - -- Sangho Park Tue, 17 Nov 2009 16:27:18 +0900 - -ecore (0.9.9.060+svn20091112-1) unstable; urgency=low - - * New version - - -- Sangho Park Thu, 12 Nov 2009 23:44:06 +0900 - -ecore (0.9.9.060+svnYYYYMMDD-1) unstable; urgency=low - - * New version - - -- quaker Thu, 22 Apr 2009 18:12:06 +0100 - -ecore (0.9.9.050+svnYYYYMMDD-1) unstable; urgency=low - - * Clean up changelog - - -- quaker Tue, 21 Apr 2009 19:14:37 +0100 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index 7ed6ff8..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -5 diff --git a/debian/control b/debian/control deleted file mode 100755 index 7e8abae..0000000 --- a/debian/control +++ /dev/null @@ -1,244 +0,0 @@ -Source: ecore -Section: libs -Priority: optional -Maintainer: Jaehwan Kim , - Jihoon Kim , - Sangjin Lee , - Doyoun Kang , - Sung-Jin Park , - Juyung Seo , - Seokjae Jeong , - ChunEon Park , - WooHyun Jung , - Gwanglim Lee , - Ji-hoon Lee , - Gwan-gyeong Mun , - Hyoyoung Chang , - Myoungwoon Kim , - Seokjae Jeong , - Mike McCormack , - Jeonghyun Yun -Uploaders: Tae-Hwan Kim -Build-Depends: dpkg-dev, - debhelper (>= 6), - cdbs, - libeina-dev (>= 0.0.2.060+svn20100304), - libeet-dev (>= 1.0.0), - libxgesture-dev, - libevas-dev , - libglib2.0-dev, - libxcursor-dev, - libxrender-dev, - libxinerama-dev, - libxrandr-dev, - libxext-dev, - libxcomposite-dev, - libjpeg8-dev, - libxdamage-dev, - x11proto-xext-dev, - libxtst-dev, - doxygen, - pkg-config, - libtool, - libcurl-dev, -Standards-Version: 3.8.1 -Homepage: http://enlightenment.org - -Package: libecore -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends}, libeina -Description: Core abstraction layer for enlightenment DR 0.17 - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - -Package: libecore-con -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Ecore Connection Library - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package contains the Ecore Connection Library. - -Package: libecore-config -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Ecore Enlightened Property Library - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package contains the Enlightened Property Library. - -Package: libecore-evas -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Ecore Evas Wrapper Library - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package contains the Ecore Evas wrapper functions. - -Package: libecore-fb -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Ecore frame buffer system functions - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package contains the Ecore frame buffer system functions. - -Package: libecore-file -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Ecore File Library - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package contains the Ecore File Library. - -Package: libecore-imf -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Ecore Input Method Framework module - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package contains the Ecore Input Method Framework module, and the Evas - helper functions for it. - -Package: libecore-input -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Ecore input functions - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package contains the Ecore Input Library. - -Package: libecore-ipc -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Ecore inter-process communication functions - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package contains the Ecore inter-process communication functions. - -Package: libecore-data -Architecture: any -Depends: ${misc:Depends} -Description: Ecore data functions - -Package: libecore-x -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Ecore functions for dealing with the X Windows System - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package contains the Ecore wrapper and convenience functions for using - the X Windows System. - -Package: libecore-dev -Architecture: any -Section: libdevel -Suggests: libecore-doc -Depends: ${misc:Depends}, libecore (= ${binary:Version}), - libecore-con (= ${binary:Version}), - libecore-config (= ${binary:Version}), - libecore-evas (= ${binary:Version}), - libecore-fb (= ${binary:Version}), - libecore-file (= ${binary:Version}), - libecore-imf (= ${binary:Version}), - libecore-input (= ${binary:Version}), - libecore-ipc (= ${binary:Version}), - libecore-x (= ${binary:Version}), - libecore-data (= ${binary:Version}), - libxgesture-dev, - libeet-dev, libevas-dev (>= 0.9.9.060), libeina-dev, pkg-config, libcurl-dev, - libxcursor-dev, libxrender-dev, libxinerama-dev, libxrandr-dev, libxext-dev, - libxcomposite-dev, libxdamage-dev, x11proto-xext-dev, libxtst-dev, libglib2.0-dev -Description: Ecore headers and static libraries - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package contains headers and static libraries for the Ecore library. - -Package: libecore-doc -Architecture: any -Section: doc -Depends: ${misc:Depends} -Enhances: libecore-dev -Description: Ecore API Documentation - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package provides development documentation (html and manpages)for the - Ecore library. - -Package: libecore-bin -Architecture: any -Section: utils -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Tools that support Ecore - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications. - . - This package includes: - - ecore_config: allows creation/editing of ecore_config databases - -Package: libecore-dbg -Architecture: any -Section: libdevel -Priority: extra -Depends: ${misc:Depends}, libecore (= ${binary:Version}) -Description: Debugging symbols for libecore - This is the core event abstraction layer and X abstraction layer that makes - doing selections, Xdnd, general X stuff, and event loops, timeouts and idle - handlers fast, optimized, and convenient. It's a separate library so anyone - can make use of the work put into Ecore to make this job easy for - applications - . - This package contains unstripped shared libraries. It is provided primarily - to provide a backtrace with names in a debugger, this makes it somewhat easier - to interpret core dumps. The libraries are installed in /usr/lib/debug and - are automatically used by gdb. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 57d5703..0000000 --- a/debian/copyright +++ /dev/null @@ -1,44 +0,0 @@ -This package was debianized by Debian Pkg-e Team -Sat, 07 Jul 2007 09:29:10 +0000. - -It was downloaded from http://download.enlightenment.org/ - -Upstream Authors: - - Enlightenment team - -Copyright: - - Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS) - - Additional Copyright: - src/lib/ecore/ecore_str.c: Copyright (c) 1998 Todd C. Miller - - src/lib/ecore/ecore_value.c: Copyright (C) 2001 - Christopher Rosendahl - Nathan Ingersoll - src/lib/ecore_fb/ecore_fb_li.c: Copyright (C) 1999-2002 Brad Hards - -License: - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies of the Software, its documentation and marketing & publicity - materials, and acknowledgment shall be given in the documentation, - materials and software packages that this Software was used. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -On Debian systems, the complete text of the BSD License can be found -in `/usr/share/common-licenses/BSD'. diff --git a/debian/ecore_config.1 b/debian/ecore_config.1 deleted file mode 100644 index ea857f4..0000000 --- a/debian/ecore_config.1 +++ /dev/null @@ -1,54 +0,0 @@ -.\"Created with GNOME Manpages Editor Wizard -.\"http://gmanedit.sourceforge.net -.\"Sergio Rua -.\" -.TH ecore_config 1 "January 18, 2007" "Ecore" - -.SH NAME -ecore_config \-that allow creation and editing of ecore_config databases - -.SH SYNOPSIS -.B ecore_config -.RI \-a\ |\ \-k\ [\-g|\-d|\-b|\-f|\-i|\-r|\-s|\-t]\ [\-c] -.br - -.SH DESCRIPTION -.PP -\fBecore_config\fP is a tool that allows creation and editing of -ecore_config databases used by the programs relying on libecore - -.SH OPTIONS -\fIecore_config\fP accepts the following options: -.TP -.B \-c, \-\-file=FILE -Specify the config file to read -.TP -.B \-k, \-\-key=KEY -Select the key KEY. Must be given for all commands except \-a -.TP -.B \-g, \-\-get -get key -.TP -.B \-d, \-\-del -delete key -.TP -.B \-b, \-\-bool=VALUE -set boolean -.TP -.B \-f, \-\-float=VALUE -set float -.TP -.B \-i, \-\-int=VALUE -set integer -.TP -.B \-r, \-\-rgb=VALUE -set RGBA -.TP -.B \-s, \-\-string=VALUE -set string -.TP -.B \-t, \-\-theme=VALUE -set theme -.SH AUTHOR -This manual page was written by Albin Tonnerre -for the Debian GNU/Linux system (but may be used by others). diff --git a/debian/jobs b/debian/jobs deleted file mode 100644 index e69de29..0000000 diff --git a/debian/libecore-bin.install b/debian/libecore-bin.install deleted file mode 100644 index 24d1f12..0000000 --- a/debian/libecore-bin.install +++ /dev/null @@ -1 +0,0 @@ -#debian/tmp/usr/bin/ecore_config diff --git a/debian/libecore-con-svn-01.install b/debian/libecore-con-svn-01.install deleted file mode 100644 index 4e6f99e..0000000 --- a/debian/libecore-con-svn-01.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_con-*.so.* diff --git a/debian/libecore-con-svn-01.shlibs b/debian/libecore-con-svn-01.shlibs deleted file mode 100644 index d5353f3..0000000 --- a/debian/libecore-con-svn-01.shlibs +++ /dev/null @@ -1 +0,0 @@ -libecore_con-ver-pre-svn-01 0 libecore-con-svn-01 (>= 0.9.9.060+svnYYYYMMDD) diff --git a/debian/libecore-con.install b/debian/libecore-con.install deleted file mode 100644 index 1c47c56..0000000 --- a/debian/libecore-con.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_con.so.* diff --git a/debian/libecore-config-svn-01.install b/debian/libecore-config-svn-01.install deleted file mode 100644 index d497998..0000000 --- a/debian/libecore-config-svn-01.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_config-*.so.* diff --git a/debian/libecore-config-svn-01.shlibs b/debian/libecore-config-svn-01.shlibs deleted file mode 100644 index ec0e971..0000000 --- a/debian/libecore-config-svn-01.shlibs +++ /dev/null @@ -1 +0,0 @@ -libecore_config-ver-pre-svn-01 0 libecore-config-svn-01 (>= 0.9.9.060+svnYYYYMMDD) diff --git a/debian/libecore-config.install b/debian/libecore-config.install deleted file mode 100644 index 8f31d99..0000000 --- a/debian/libecore-config.install +++ /dev/null @@ -1 +0,0 @@ -#debian/tmp/usr/lib/libecore_config.so.* diff --git a/debian/libecore-dev.install b/debian/libecore-dev.install deleted file mode 100755 index e6def58..0000000 --- a/debian/libecore-dev.install +++ /dev/null @@ -1,14 +0,0 @@ -debian/tmp/usr/include/ecore-1/Ecore*.h -debian/tmp/usr/lib/libecore*.a -debian/tmp/usr/lib/libecore*.la -debian/tmp/usr/lib/libecore*.so -#debian/tmp/usr/lib/libecore_config*.so -debian/tmp/usr/lib/libecore_con*.so -debian/tmp/usr/lib/libecore_evas*.so -debian/tmp/usr/lib/libecore_file*.so -debian/tmp/usr/lib/libecore_imf_evas*.so -debian/tmp/usr/lib/libecore_imf*.so -debian/tmp/usr/lib/libecore_input*.so -debian/tmp/usr/lib/libecore_ipc*.so -debian/tmp/usr/lib/libecore_x*.so -debian/tmp/usr/lib/pkgconfig/ecore*.pc diff --git a/debian/libecore-doc.doc-base b/debian/libecore-doc.doc-base deleted file mode 100644 index 9ab7e32..0000000 --- a/debian/libecore-doc.doc-base +++ /dev/null @@ -1,10 +0,0 @@ -Document: ecore -Title: Ecore Guide -Author: Carsten Haitzler -Abstract: This document describes Ecore API - and provides sample C code. -Section: Programming/C - -Format: HTML -Index: /usr/share/doc/libecore-doc/html/index.html -Files: /usr/share/doc/libecore-doc/html/*.html diff --git a/debian/libecore-evas-svn-01.install b/debian/libecore-evas-svn-01.install deleted file mode 100644 index ceb9f01..0000000 --- a/debian/libecore-evas-svn-01.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_evas-*.so.* diff --git a/debian/libecore-evas-svn-01.shlibs b/debian/libecore-evas-svn-01.shlibs deleted file mode 100644 index 92c2b6d..0000000 --- a/debian/libecore-evas-svn-01.shlibs +++ /dev/null @@ -1 +0,0 @@ -libecore_evas-ver-pre-svn-01 0 libecore-evas-svn-01 (>= 0.9.9.060+svnYYYYMMDD) diff --git a/debian/libecore-evas.install b/debian/libecore-evas.install deleted file mode 100644 index 12d49fb..0000000 --- a/debian/libecore-evas.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_evas*.so.* diff --git a/debian/libecore-fb-svn-01.install b/debian/libecore-fb-svn-01.install deleted file mode 100644 index 72ceee2..0000000 --- a/debian/libecore-fb-svn-01.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_fb-*.so.* diff --git a/debian/libecore-fb-svn-01.shlibs b/debian/libecore-fb-svn-01.shlibs deleted file mode 100644 index 2593f16..0000000 --- a/debian/libecore-fb-svn-01.shlibs +++ /dev/null @@ -1 +0,0 @@ -libecore_fb-ver-pre-svn-01 0 libecore-fb-svn-01 (>= 0.9.9.060+svnYYYYMMDD) diff --git a/debian/libecore-fb.install b/debian/libecore-fb.install deleted file mode 100644 index f228623..0000000 --- a/debian/libecore-fb.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_fb*.so.* diff --git a/debian/libecore-file-svn-01.install b/debian/libecore-file-svn-01.install deleted file mode 100644 index a115a75..0000000 --- a/debian/libecore-file-svn-01.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_file-*.so.* diff --git a/debian/libecore-file-svn-01.shlibs b/debian/libecore-file-svn-01.shlibs deleted file mode 100644 index 868a4f6..0000000 --- a/debian/libecore-file-svn-01.shlibs +++ /dev/null @@ -1 +0,0 @@ -libecore_file-ver-pre-svn-01 0 libecore-file-svn-01 (>= 0.9.9.060+svnYYYYMMDD) diff --git a/debian/libecore-file.install b/debian/libecore-file.install deleted file mode 100644 index 74419ea..0000000 --- a/debian/libecore-file.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_file*.so.* diff --git a/debian/libecore-imf-svn-01.install b/debian/libecore-imf-svn-01.install deleted file mode 100644 index 8da8885..0000000 --- a/debian/libecore-imf-svn-01.install +++ /dev/null @@ -1,2 +0,0 @@ -debian/tmp/usr/lib/libecore_imf-*.so.* -debian/tmp/usr/lib/libecore_imf_evas-*.so.* diff --git a/debian/libecore-imf-svn-01.shlibs b/debian/libecore-imf-svn-01.shlibs deleted file mode 100644 index 15aeb84..0000000 --- a/debian/libecore-imf-svn-01.shlibs +++ /dev/null @@ -1,2 +0,0 @@ -libecore_imf-ver-pre-svn-01 0 libecore-imf-svn-01 (>= 0.9.9.060+svnYYYYMMDD) -libecore_imf_evas-ver-pre-svn-01 0 libecore-imf-svn-01 (>= 0.9.9.060+svnYYYYMMDD) diff --git a/debian/libecore-imf.install b/debian/libecore-imf.install deleted file mode 100644 index 88f91c5..0000000 --- a/debian/libecore-imf.install +++ /dev/null @@ -1,2 +0,0 @@ -debian/tmp/usr/lib/libecore_imf*.so.* -debian/tmp/usr/lib/libecore_imf_evas*.so.* diff --git a/debian/libecore-input-svn-01.install b/debian/libecore-input-svn-01.install deleted file mode 100644 index 34d8efb..0000000 --- a/debian/libecore-input-svn-01.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_input-*.so.* diff --git a/debian/libecore-input-svn-01.shlibs b/debian/libecore-input-svn-01.shlibs deleted file mode 100644 index b95c6bb..0000000 --- a/debian/libecore-input-svn-01.shlibs +++ /dev/null @@ -1 +0,0 @@ -libecore_input-ver-pre-svn-01 0 libecore-input-svn-01 (>= 0.9.9.060+svnYYYYMMDD) diff --git a/debian/libecore-input.install b/debian/libecore-input.install deleted file mode 100644 index 4509237..0000000 --- a/debian/libecore-input.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_input*.so.* diff --git a/debian/libecore-ipc-svn-01.install b/debian/libecore-ipc-svn-01.install deleted file mode 100644 index e118708..0000000 --- a/debian/libecore-ipc-svn-01.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_ipc-*.so.* diff --git a/debian/libecore-ipc-svn-01.shlibs b/debian/libecore-ipc-svn-01.shlibs deleted file mode 100644 index 6a9ae5a..0000000 --- a/debian/libecore-ipc-svn-01.shlibs +++ /dev/null @@ -1 +0,0 @@ -libecore_ipc-ver-pre-svn-01 0 libecore-ipc-svn-01 (>= 0.9.9.060+svnYYYYMMDD) diff --git a/debian/libecore-ipc.install b/debian/libecore-ipc.install deleted file mode 100644 index f0421a3..0000000 --- a/debian/libecore-ipc.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_ipc*.so.* diff --git a/debian/libecore-svn-01.install b/debian/libecore-svn-01.install deleted file mode 100644 index 22c55a3..0000000 --- a/debian/libecore-svn-01.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore-*.so.* diff --git a/debian/libecore-svn-01.shlibs b/debian/libecore-svn-01.shlibs deleted file mode 100644 index 43565e1..0000000 --- a/debian/libecore-svn-01.shlibs +++ /dev/null @@ -1 +0,0 @@ -libecore-ver-pre-svn-01 0 libecore-svn-01 (>= 0.9.9.060+svnYYYYMMDD) diff --git a/debian/libecore-x-svn-01.install b/debian/libecore-x-svn-01.install deleted file mode 100644 index 8c8007e..0000000 --- a/debian/libecore-x-svn-01.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_x-*.so.* diff --git a/debian/libecore-x-svn-01.shlibs b/debian/libecore-x-svn-01.shlibs deleted file mode 100644 index b5a9660..0000000 --- a/debian/libecore-x-svn-01.shlibs +++ /dev/null @@ -1 +0,0 @@ -libecore_x-ver-pre-svn-01 0 libecore-x-svn-01 (>= 0.9.9.060+svnYYYYMMDD) diff --git a/debian/libecore-x.install b/debian/libecore-x.install deleted file mode 100644 index e098222..0000000 --- a/debian/libecore-x.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore_x*.so.* diff --git a/debian/libecore.install b/debian/libecore.install deleted file mode 100644 index 7eef82a..0000000 --- a/debian/libecore.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libecore.so.* diff --git a/debian/rules b/debian/rules deleted file mode 100755 index 494fe33..0000000 --- a/debian/rules +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/make -f - -include /usr/share/cdbs/1/class/autotools.mk -include /usr/share/cdbs/1/rules/debhelper.mk - -DEB_CONFIGURE_SCRIPT := ./autogen.sh -#DEB_INSTALL_MANPAGES_libecore-bin := debian/ecore_config.1 -DEB_DH_STRIP_ARGS := --dbg-package=libecore-dbg -DEB_CONFIGURE_EXTRA_FLAGS := --enable-ecore-fb \ - --enable-dependency-tracking \ - --disable-ecore-directfb \ - --enable-ecore-evas-fb \ - --disable-rpath \ - --disable-openssl \ - --disable-gnutls \ - --disable-tslib \ - --disable-doc \ - --enable-simple-x11 \ - --enable-ecore-evas-opengl-x11 \ - --disable-ecore-evas-xrender-x11 \ - --enable-curl \ - --disable-openssl \ - --enable-glib-integration-always \ - --enable-ecore-x-gesture \ - --disable-xim \ - --disable-ecore-imf-xim \ - --disable-ecore-imf-scim -DEB_MAKE_EXTRA_ARGS := V=0 - -DEB_MAKE_CLEAN_TARGET := distclean -CFLAGS += -fvisibility=hidden -fPIC -LDFLAGS += -fvisibility=hidden -Wl,--hash-style=both -Wl,--as-needed - -#build/libecore-doc:: -# cd $(DEB_SRCDIR)/doc && make doc - -#install/libecore-doc:: -# mkdir -p debian/libecore-doc/usr/share/doc/libecore-doc -# cp -R $(DEB_SRCDIR)/doc/html debian/libecore-doc/usr/share/doc/libecore-doc/ - -clean:: - [ ! -f Makefile ] || make distclean - rm -f ecore-*.tar.bz2 ecore-*.tar.bz2.cdbs-config_list diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 43e73c1..3b0d790 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -74,7 +74,7 @@ WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = INPUT = @builddir@/ecore.dox \ @top_srcdir@/src/lib \ - @srcdir@/examples.dox + @srcdir@/ecore_examples.dox INPUT_ENCODING = UTF-8 FILE_PATTERNS = RECURSIVE = YES diff --git a/doc/examples.dox b/doc/ecore_examples.dox similarity index 98% rename from doc/examples.dox rename to doc/ecore_examples.dox index cc7ec9d..3237490 100644 --- a/doc/examples.dox +++ b/doc/ecore_examples.dox @@ -1,5 +1,5 @@ /** - * @page Examples Examples + * @page ecore_examples Ecore Example * * Here is a page with some Ecore examples explained: * @@ -11,6 +11,7 @@ * @li @ref ecore_event_example_02_c * @li @ref ecore_fd_handler_example_c * @li @ref ecore_poller_example_c + * @internal * @li @ref ecore_con_lookup_example_c * @li @ref ecore_con_url_download_example_c * @li @ref ecore_con_server_simple_example_c @@ -23,6 +24,9 @@ * @li @ref Ecore_Evas_Buffer_Example_02_c * @li @ref Ecore_exe_simple_example_c * @li @ref ecore_imf_example_c + * @li @ref ecore_evas_extn_socket_example + * @li @ref ecore_evas_extn_plug_example + * @endinternal */ /** @@ -505,6 +509,7 @@ */ /** + * @internal * @page ecore_con_lookup_example_c Ecore_Con - DNS lookup * * This is a very simple example that shows how to make a simple DNS lookup @@ -538,6 +543,7 @@ */ /** + * @internal * @page ecore_con_url_download_example_c Ecore_Con_Url - downloading a file * * This is a simple example that shows how to download a file using @ref @@ -586,6 +592,7 @@ */ /** + * @internal * @page ecore_con_url_cookies_example_c Ecore_Con_Url - Managing cookies * * This example shows how to use an @ref Ecore_Con_Url and enable it to @@ -654,6 +661,7 @@ */ /** + * @internal * @page ecore_con_url_headers_example_c Ecore_Con_Url - customizing a request * * This is a simple example that shows how to make a custom request using @ref @@ -704,6 +712,7 @@ */ /** + * @internal * @page ecore_con_server_simple_example_c Ecore_Con - Creating a server * * In this example we are going to create a server that listens for connections @@ -814,12 +823,12 @@ * This example will start a server and start accepting connections from clients, as * demonstrated in the following diagram: * @htmlonly - * * Full size * @endhtmlonly * + * @image html ecore_con-client-server-example.png * @image rtf ecore_con-client-server-example.png - * @image latex ecore_con-client-server-example.eps width=\textwidth + * @image latex ecore_con-client-server-example.eps "ecore con client server example" width=\textwidth * * @note This example contains a serious security flaw: it doesn't check for the * size of data being received, thus allowing to the string to be exploited in @@ -828,6 +837,7 @@ */ /** + * @internal * @page ecore_con_client_simple_example_c Ecore_Con - Creating a client * * Following the same idea as the @ref ecore_con_server_simple_example_c , this @@ -878,12 +888,12 @@ * This example will connect to the server and start comunicating with it, as * demonstrated in the following diagram: * @htmlonly - * * Full size * @endhtmlonly * + * @image html ecore_con-client-server-example2.png * @image rtf ecore_con-client-server-example2.png - * @image latex ecore_con-client-server-example2.eps width=\textwidth + * @image latex ecore_con-client-server-example2.eps "ecore con client server example 2" width=\textwidth * * @note This example contains a serious security flaw: it doesn't check for the * size of data being received, thus allowing to the string to be exploited in @@ -917,6 +927,7 @@ */ /** + * @internal * @example ecore_exe_example_child.c * This is a child process used to receive messages and send it back * to its father. @@ -924,6 +935,7 @@ */ /** + * @internal * @example ecore_exe_example.c * This is a process that will send messages to a child and it will stop * when it receives "quit". @@ -955,29 +967,28 @@ */ /** - * @example ecore_fd_handler_gnutls_example.c - * Shows how to use fd handlers. - */ - -/** + * @internal * @example ecore_con_lookup_example.c * Shows how to make a simple DNS lookup. See the complete example description * at @ref ecore_con_lookup_example_c */ /** + * @internal * @example ecore_con_url_download_example.c * Shows how to download a file using an @ref Ecore_Con_Url object. See the * complete example description at @ref ecore_con_url_download_example_c */ /** + * @internal * @example ecore_con_url_cookies_example.c * Shows how to manage cookies on a @ref Ecore_Con_Url object. See the complete * example description at @ref ecore_con_url_cookies_example_c. */ /** + * @internal * @example ecore_con_server_simple_example.c * Shows how to setup a simple server that accepts client connections and sends * a "hello" string to them. See the complete example description at @ref @@ -985,6 +996,7 @@ */ /** + * @internal * @example ecore_con_client_simple_example.c * Shows how to setup a simple client that connects to a server and sends a * "hello" string to it. See the complete example description at @ref @@ -992,6 +1004,7 @@ */ /** + * @internal * @example ecore_con_url_headers_example.c * Shows how to make GET or POST requests using an @ref Ecore_Con_Url object, * and make use of most of its API. See the complete example description at @@ -999,6 +1012,7 @@ */ /** + * @internal * @page tutorial_ecore_pipe_gstreamer_example * * Here is an example that uses the pipe wrapper with a Gstreamer @@ -1261,6 +1275,7 @@ */ /** + * @internal * @page ecore_evas_callbacks_example_c Ecore Evas Callbacks * @dontinclude ecore_evas_callbacks.c * @@ -1284,6 +1299,7 @@ */ /** + * @internal * @page Ecore_Evas_Window_Sizes_Example_c Ecore_Evas window size hints * * On this example, we show you how to deal with @c Ecore_Evas window @@ -1356,6 +1372,7 @@ */ /** + * @internal * @page ecore_evas_object_example_c Ecore Evas Object example * @dontinclude ecore_evas_object_example.c * @@ -1388,6 +1405,7 @@ */ /** + * @internal * @page ecore_evas_basics_example_c Ecore Evas basics example * @dontinclude ecore_evas_basics_example.c * @@ -1460,6 +1478,7 @@ */ /** + * @internal * @page Ecore_Evas_Buffer_Example_01_c Ecore_Evas buffer example * * Between the Evas examples, there is one in which one creates a @@ -1510,6 +1529,7 @@ */ /** + * @internal * @page Ecore_Evas_Buffer_Example_02_c Ecore_Evas (image) buffer example * * In this example, we'll demonstrate the use of @@ -1545,6 +1565,7 @@ */ /** + * @internal * @page Ecore_exe_simple_example_c Ecore_exe * Creating a processes and IPC (Inter process communication) * @@ -1670,6 +1691,7 @@ */ /** + * @internal * @page ecore_imf_example_c ecore_imf - How to handle preedit and commit string from Input Method Framework * * This example demonstrates how to connect input method framework and handle preedit and commit string from input method framework. @@ -1690,3 +1712,15 @@ * * @include ecore_imf_example.c */ + + /** + * @internal + * @page ecore_evas_extn_socket_example + * @include ecore_evas_extn_socket_example.c + */ + + /** + * @internal + * @page ecore_evas_extn_plug_example + * @include ecore_evas_extn_plug_example.c + */ diff --git a/ecore-con.manifest b/ecore-con.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore-con.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/ecore-evas.manifest b/ecore-evas.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore-evas.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/ecore-fb.manifest b/ecore-fb.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore-fb.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/ecore-file.manifest b/ecore-file.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore-file.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/ecore-imf-evas.manifest b/ecore-imf-evas.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore-imf-evas.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/ecore-imf.manifest b/ecore-imf.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore-imf.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/ecore-input-evas.manifest b/ecore-input-evas.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore-input-evas.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/ecore-input.manifest b/ecore-input.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore-input.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/ecore-ipc.manifest b/ecore-ipc.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore-ipc.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/ecore-x.manifest b/ecore-x.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore-x.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/ecore.manifest b/ecore.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/ecore.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/m4/efl_coverage.m4 b/m4/efl_coverage.m4 new file mode 100644 index 0000000..85d0321 --- /dev/null +++ b/m4/efl_coverage.m4 @@ -0,0 +1,62 @@ +dnl Copyright (C) 2008 Vincent Torri +dnl That code is public domain and can be freely used or copied. + +dnl Macro that check if coverage support is wanted and, if yes, if +dnl lcov is available. + +dnl Usage: EFL_CHECK_COVERAGE(tests [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl The parameter 'tests' is used if a dependency is needed. If set to "yes", +dnl the dependency is available. +dnl Defines EFL_COVERAGE_CFLAGS and EFL_COVERAGE_LIBS variables +dnl Defines the automake conditionnal EFL_ENABLE_COVERAGE + +AC_DEFUN([EFL_CHECK_COVERAGE], +[ + +dnl configure option + +AC_ARG_ENABLE([coverage], + [AC_HELP_STRING([--enable-coverage], [enable coverage profiling instrumentation @<:@default=disabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + _efl_enable_coverage="yes" + else + _efl_enable_coverage="no" + fi + ], + [_efl_enable_coverage="no"]) + +AC_MSG_CHECKING([whether to use profiling instrumentation]) +AC_MSG_RESULT([$_efl_enable_coverage]) + +dnl lcov check + +if test "x$_efl_enable_coverage" = "xyes" && test ! "x$1" = "xyes" ; then + AC_MSG_WARN([Coverage report requested but tests not being built, disable profiling instrumentation.]) + AC_MSG_WARN([Run configure with --enable-tests]) + _efl_enable_coverage="no" +fi + +if test "x$_efl_enable_coverage" = "xyes" ; then + AC_CHECK_PROG(have_lcov, [lcov], [yes], [no]) + if test "x$have_lcov" = "xyes" ; then + EFL_COVERAGE_CFLAGS="-fprofile-arcs -ftest-coverage" + EFL_COVERAGE_LIBS="-lgcov" +# remove any optimisation flag and force debug symbols + EFL_DEBUG_CFLAGS="-g -O0 -DDEBUG" + else + AC_MSG_WARN([lcov is not found, disable profiling instrumentation]) + _efl_enable_coverage="no" + fi +fi + +dnl Substitution +AC_SUBST(EFL_COVERAGE_CFLAGS) +AC_SUBST(EFL_COVERAGE_LIBS) + +AM_CONDITIONAL(EFL_ENABLE_COVERAGE, test "x${_efl_enable_coverage}" = "xyes") + +AS_IF([test "x$_efl_enable_coverage" = "xyes"], [$2], [$3]) +]) + +dnl End of efl_coverage.m4 diff --git a/packaging/ecore.spec b/packaging/ecore.spec index 71171d8..7f034c3 100644 --- a/packaging/ecore.spec +++ b/packaging/ecore.spec @@ -1,9 +1,9 @@ Name: ecore Summary: Enlightened Core X interface library -Version: 1.6.0+svn.74576slp2+build05 -Release: 1 +Version: 1.7.1+svn.77580+build125 +Release: 2 Group: System/Libraries -License: BSD +License: BSD 2-Clause URL: http://www.enlightenment.org Source0: %{name}-%{version}.tar.gz Requires(post): /sbin/ldconfig @@ -165,8 +165,7 @@ Core abstraction layer for enlightenment (fb) export CFLAGS+=" -fvisibility=hidden -fPIC" export LDFLAGS+=" -fvisibility=hidden -Wl,--hash-style=both -Wl,--as-needed" -%autogen -%configure --disable-static \ +%autogen --disable-static \ --enable-ecore-fb \ --enable-dependency-tracking \ --disable-ecore-directfb \ @@ -177,7 +176,6 @@ export LDFLAGS+=" -fvisibility=hidden -Wl,--hash-style=both -Wl,--as-needed" --disable-tslib \ --enable-simple-x11 \ --enable-ecore-evas-opengl-x11 \ - --disable-ecore-evas-xrender-x11 \ --enable-curl \ --enable-glib-integration-always \ --enable-ecore-x-gesture \ @@ -190,7 +188,18 @@ make %{?jobs:-j%jobs} %install rm -rf %{buildroot} %make_install - +mkdir -p %{buildroot}/usr/share/license +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name} +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}-con +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}-evas +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}-file +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}-imf +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}-imf-evas +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}-input +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}-input-evas +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}-ipc +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}-x +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}-fb %post -p /sbin/ldconfig @@ -247,7 +256,9 @@ rm -rf %{buildroot} %files %defattr(-,root,root,-) %{_libdir}/libecore.so.* +%manifest %{name}.manifest /usr/share/locale/* +/usr/share/license/%{name} %files devel %defattr(-,root,root,-) @@ -268,44 +279,65 @@ rm -rf %{buildroot} %files tools %defattr(-,root,root,-) #/usr/bin/ecore_test +%{_bindir}/ecore_evas_convert %files con %defattr(-,root,root,-) %{_libdir}/libecore_con.so.* +%manifest %{name}-con.manifest +/usr/share/license/%{name}-con %files evas %defattr(-,root,root,-) %{_libdir}/libecore_evas.so.* +%manifest %{name}-evas.manifest +/usr/share/license/%{name}-evas %files file %defattr(-,root,root,-) %{_libdir}/libecore_file.so.* +%manifest %{name}-file.manifest +/usr/share/license/%{name}-file %files imf %defattr(-,root,root,-) %{_libdir}/libecore_imf.so.* +%manifest %{name}-imf.manifest +/usr/share/license/%{name}-imf %files imf-evas %defattr(-,root,root,-) %{_libdir}/libecore_imf_evas.so.* +%manifest %{name}-imf-evas.manifest +/usr/share/license/%{name}-imf-evas %files input %defattr(-,root,root,-) %{_libdir}/libecore_input.so.* +%manifest %{name}-input.manifest +/usr/share/license/%{name}-input %files input-evas %defattr(-,root,root,-) %{_libdir}/libecore_input_evas.so.* +%manifest %{name}-input-evas.manifest +/usr/share/license/%{name}-input-evas %files ipc %defattr(-,root,root,-) %{_libdir}/libecore_ipc.so.* +%manifest %{name}-ipc.manifest +/usr/share/license/%{name}-ipc %files x %defattr(-,root,root,-) %{_libdir}/libecore_x.so.* +%manifest %{name}-x.manifest +/usr/share/license/%{name}-x %files fb %defattr(-,root,root,-) %{_libdir}/libecore_fb.so.* +%manifest %{name}-fb.manifest +/usr/share/license/%{name}-fb diff --git a/po/LINGUAS b/po/LINGUAS index 3665c31..c58c323 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -1,2 +1,2 @@ -cs de el fr it nl pt sl +cs de el fr it ko nl pt sl diff --git a/po/cs.po b/po/cs.po index eeb2844..2d3ec63 100644 --- a/po/cs.po +++ b/po/cs.po @@ -1,10 +1,11 @@ # ecore czech translation # quaker66@gmail.com +# Vít Pelčák , 2011. msgid "" msgstr "" "Project-Id-Version: ecore\n" "Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-07-09 19:11+0900\n" +"POT-Creation-Date: 2012-08-27 19:14+0900\n" "PO-Revision-Date: 2011-10-23 01:28+0100\n" "Last-Translator: Daniel Kolesa \n" "Language-Team: Czech \n" @@ -12,6 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" #: src/lib/ecore/ecore_getopt.c:95 msgid "Version:" @@ -153,12 +156,12 @@ msgstr "CHYBA: nalezeny neplatné volby." #: src/lib/ecore/ecore_getopt.c:1839 #, c-format msgid " See --%s.\n" -msgstr " viz. --%s.\n" +msgstr " Viz --%s.\n" #: src/lib/ecore/ecore_getopt.c:1841 #, c-format msgid " See -%c.\n" -msgstr " viz. -%c.\n" +msgstr " Viz -%c.\n" #: src/lib/ecore/ecore_getopt.c:1887 #, c-format diff --git a/po/de.po b/po/de.po index 5977fd3..b00169e 100644 --- a/po/de.po +++ b/po/de.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ecore 0.9.9.063-2\n" "Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-07-09 19:11+0900\n" +"POT-Creation-Date: 2012-08-27 19:14+0900\n" "PO-Revision-Date: 2010-01-03 21:52+GMT\n" "Last-Translator: Fabian Nowak \n" "Language-Team: German \n" diff --git a/po/el.po b/po/el.po index 9dd9d63..f0dc8fb 100644 --- a/po/el.po +++ b/po/el.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Ecore\n" "Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-07-09 19:11+0900\n" +"POT-Creation-Date: 2012-08-27 19:14+0900\n" "PO-Revision-Date: 2011-11-20 22:42+0200\n" "Last-Translator: George Rizopoulos \n" "Language-Team: Greek\n" diff --git a/po/fr.po b/po/fr.po index 1f9bfb9..8d7f719 100644 --- a/po/fr.po +++ b/po/fr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Ecore\n" "Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-07-09 19:11+0900\n" +"POT-Creation-Date: 2012-08-27 19:14+0900\n" "PO-Revision-Date: 2010-07-11 11:01+0400\n" "Last-Translator: batden \n" "Language-Team: Enlightenment French Team \n" diff --git a/po/it.po b/po/it.po index 0ce2aa0..ae044da 100644 --- a/po/it.po +++ b/po/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Ecore\n" "Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-07-09 19:11+0900\n" +"POT-Creation-Date: 2012-08-27 19:14+0900\n" "PO-Revision-Date: 2009-10-27 19:36+0100\n" "Last-Translator: quaker66 \n" "Language-Team: none\n" diff --git a/po/ko.po b/po/ko.po new file mode 100644 index 0000000..abc5e37 --- /dev/null +++ b/po/ko.po @@ -0,0 +1,185 @@ +# Korean translation for the Enlightenment ecore. +# Copyright (C) 2000-2012 Enlightenment development team +# This file is distributed under the same license as the Enlightenment package. +# Seong-ho Cho , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: Enlightenment Ecore 1.7.0\n" +"Report-Msgid-Bugs-To: Enlightenment-Devel \n" +"POT-Creation-Date: 2012-08-30 22:29+0900\n" +"PO-Revision-Date: 2012-08-30 22:50+0900\n" +"Last-Translator: Seong-ho Cho \n" +"Language-Team: Enlightenment-Intl \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Poedit-Language: Korean\n" +"X-Poedit-Country: KOREA, REPUBLIC OF\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: src/lib/ecore/ecore_getopt.c:95 +msgid "Version:" +msgstr "버전:" + +#: src/lib/ecore/ecore_getopt.c:104 +msgid "Usage:" +msgstr "사용법:" + +#: src/lib/ecore/ecore_getopt.c:109 +#, c-format +msgid "%s [options]\n" +msgstr "%s <옵션>\n" + +#: src/lib/ecore/ecore_getopt.c:264 +msgid "Copyright:" +msgstr "저작권 정보:" + +#: src/lib/ecore/ecore_getopt.c:276 +msgid "License:" +msgstr "라이선스:" + +#: src/lib/ecore/ecore_getopt.c:457 +msgid "Type: " +msgstr "형식: " + +#: src/lib/ecore/ecore_getopt.c:533 +msgid "Default: " +msgstr "기본값: " + +#: src/lib/ecore/ecore_getopt.c:560 +msgid "Choices: " +msgstr "선택: " + +#: src/lib/ecore/ecore_getopt.c:661 +msgid "Options:\n" +msgstr "옵션:\n" + +#: src/lib/ecore/ecore_getopt.c:788 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "오류: 알 수 없는 옵션 --%s 입니다.\n" + +#: src/lib/ecore/ecore_getopt.c:790 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "오류: 알 수 없는 옵션 -%c 입니다.\n" + +#: src/lib/ecore/ecore_getopt.c:848 +msgid "ERROR: " +msgstr "오류: " + +#: src/lib/ecore/ecore_getopt.c:931 +#: src/lib/ecore/ecore_getopt.c:1068 +#: src/lib/ecore/ecore_getopt.c:1084 +#: src/lib/ecore/ecore_getopt.c:1099 +#: src/lib/ecore/ecore_getopt.c:1116 +#: src/lib/ecore/ecore_getopt.c:1163 +#: src/lib/ecore/ecore_getopt.c:1283 +#: src/lib/ecore/ecore_getopt.c:1324 +msgid "value has no pointer set.\n" +msgstr "값에 포인터 집합이 없습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:963 +#: src/lib/ecore/ecore_getopt.c:1183 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "알 수 없는 부울린 값 %s 입니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1014 +#: src/lib/ecore/ecore_getopt.c:1271 +#, c-format +msgid "invalid number format %s\n" +msgstr "잘못된 숫자 형식 %s 입니다\n" + +#: src/lib/ecore/ecore_getopt.c:1129 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "잘못된 선택 \"%s\" 입니다. 유효한 값은 다음과 같습니다: " + +#: src/lib/ecore/ecore_getopt.c:1157 +msgid "missing parameter to append.\n" +msgstr "붙일 매개변수가 빠졌습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1261 +msgid "could not parse value.\n" +msgstr "값을 해석할 수 없습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1318 +msgid "missing parameter.\n" +msgstr "매개변수가 빠졌습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1331 +msgid "missing callback function!\n" +msgstr "콜백 함수가 빠졌습니다!\n" + +#: src/lib/ecore/ecore_getopt.c:1360 +msgid "no version was defined.\n" +msgstr "정의한 버전이 없습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1377 +msgid "no copyright was defined.\n" +msgstr "정의한 저작권 정보가 없습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1394 +msgid "no license was defined.\n" +msgstr "정의한 라이선스가 없습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1469 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "오류: 알 수 없는 --%s 옵션을 무시합니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1502 +#, c-format +msgid "ERROR: option --%s requires an argument!\n" +msgstr "오류: --%s 옵션에 인자가 필요합니다!\n" + +#: src/lib/ecore/ecore_getopt.c:1544 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "오류: 알 수 없는 -%c 옵션을 무시합니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1582 +#, c-format +msgid "ERROR: option -%c requires an argument!\n" +msgstr "오류: -%c 옵션에 인자가 필요합니다!\n" + +#: src/lib/ecore/ecore_getopt.c:1793 +msgid "ERROR: no parser provided.\n" +msgstr "오류: 해석 프로그램이 존재하지 않습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1798 +msgid "ERROR: no values provided.\n" +msgstr "오류: 값이 존재하지 않습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no arguments provided.\n" +msgstr "인자가 존재하지 않습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1833 +msgid "ERROR: invalid options found." +msgstr "오류: 잘못된 옵션이 있습니다." + +#: src/lib/ecore/ecore_getopt.c:1839 +#, c-format +msgid " See --%s.\n" +msgstr " --%s을(를) 참조하십시오.\n" + +#: src/lib/ecore/ecore_getopt.c:1841 +#, c-format +msgid " See -%c.\n" +msgstr " -%c을(를) 참조하십시오.\n" + +#: src/lib/ecore/ecore_getopt.c:1887 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "오류: '%s' 값의 좌표가 올바르지 않습니다\n" + +#: src/lib/ecore/ecore_getopt.c:1919 +#, c-format +msgid "ERROR: incorrect size value '%s'\n" +msgstr "오류: '%s' 값의 크기가 올바르지 않습니다\n" + diff --git a/po/nl.po b/po/nl.po index 92f3134..4dc3b6e 100644 --- a/po/nl.po +++ b/po/nl.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Ecore\n" "Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-07-09 19:11+0900\n" +"POT-Creation-Date: 2012-08-27 19:14+0900\n" "PO-Revision-Date: 2011-09-03 15:48+0100\n" "Last-Translator: Heimen Stoffels \n" "Language-Team: \n" diff --git a/po/pt.po b/po/pt.po index 3dac17a..01475f8 100644 --- a/po/pt.po +++ b/po/pt.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: ecore\n" "Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-07-09 19:11+0900\n" -"PO-Revision-Date: 2010-10-06 12:37-0000\n" +"POT-Creation-Date: 2012-08-27 19:14+0900\n" +"PO-Revision-Date: 2012-08-23 00:30+0100\n" "Last-Translator: Sérgio Marques \n" "Language-Team: \n" "Language: \n" @@ -45,7 +45,7 @@ msgstr "Tipo:" #: src/lib/ecore/ecore_getopt.c:533 msgid "Default: " -msgstr "Omissão:" +msgstr "Padrão:" #: src/lib/ecore/ecore_getopt.c:560 msgid "Choices: " @@ -84,7 +84,7 @@ msgstr "valor booleano desconhecido %s.\n" #: src/lib/ecore/ecore_getopt.c:1014 src/lib/ecore/ecore_getopt.c:1271 #, c-format msgid "invalid number format %s\n" -msgstr "formato do número inválido %s\n" +msgstr "formato numérico inválido %s\n" #: src/lib/ecore/ecore_getopt.c:1129 #, c-format @@ -97,7 +97,7 @@ msgstr "faltam os parâmetros a anexar.\n" #: src/lib/ecore/ecore_getopt.c:1261 msgid "could not parse value.\n" -msgstr "incapaz de analisar o valor.\n" +msgstr "incapaz de processar o valor.\n" #: src/lib/ecore/ecore_getopt.c:1318 msgid "missing parameter.\n" @@ -105,7 +105,7 @@ msgstr "parâmetro em falta.\n" #: src/lib/ecore/ecore_getopt.c:1331 msgid "missing callback function!\n" -msgstr "função de chamada em falta!\n" +msgstr "função de invocação em falta!\n" #: src/lib/ecore/ecore_getopt.c:1360 msgid "no version was defined.\n" @@ -141,7 +141,7 @@ msgstr "ERRO: a opção --%c requer um argumento!\n" #: src/lib/ecore/ecore_getopt.c:1793 msgid "ERROR: no parser provided.\n" -msgstr "ERRO: nenhum analisador fornecido.\n" +msgstr "ERRO: nenhum processador fornecido.\n" #: src/lib/ecore/ecore_getopt.c:1798 msgid "ERROR: no values provided.\n" @@ -158,12 +158,12 @@ msgstr "ERRO: encontradas opções inválidas." #: src/lib/ecore/ecore_getopt.c:1839 #, c-format msgid " See --%s.\n" -msgstr " Veja --%s.\n" +msgstr "Consulte --%s.\n" #: src/lib/ecore/ecore_getopt.c:1841 #, c-format msgid " See -%c.\n" -msgstr " Veja -%c.\n" +msgstr "Consulte -%c.\n" #: src/lib/ecore/ecore_getopt.c:1887 #, c-format diff --git a/po/sl.po b/po/sl.po index f67baf8..e5224d5 100644 --- a/po/sl.po +++ b/po/sl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ecore 1.0\n" "Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-07-09 19:11+0900\n" +"POT-Creation-Date: 2012-08-27 19:14+0900\n" "PO-Revision-Date: 2011-02-24 16:54+0100\n" "Last-Translator: r1to \n" "Language-Team: Slovenian \n" diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am index 00ea91d..89ec6d9 100644 --- a/src/examples/Makefile.am +++ b/src/examples/Makefile.am @@ -55,6 +55,8 @@ SRCS = \ ecore_evas_basics_example.c \ ecore_evas_buffer_example_01.c \ ecore_evas_buffer_example_02.c \ + ecore_evas_extn_socket_example.c \ + ecore_evas_extn_plug_example.c \ ecore_evas_ews_example.c \ ecore_exe_example.c \ ecore_exe_example_child.c @@ -95,6 +97,8 @@ examples_PROGRAMS += \ ecore_evas_basics_example \ ecore_evas_buffer_example_01 \ ecore_evas_buffer_example_02 \ + ecore_evas_extn_socket_example \ + ecore_evas_extn_plug_example \ ecore_evas_ews_example \ ecore_client_bench \ ecore_server_bench \ @@ -111,6 +115,8 @@ ecore_con_client_simple_example_LDADD = $(ECOREBASELDADD) $(top_builddir)/src/li ecore_evas_window_sizes_example_LDADD = $(ECOREBASELDADD) @EVAS_LIBS@ $(top_builddir)/src/lib/ecore_evas/libecore_evas.la ecore_evas_buffer_example_01_LDADD = $(ECOREBASELDADD) @EVAS_LIBS@ $(top_builddir)/src/lib/ecore_evas/libecore_evas.la ecore_evas_buffer_example_02_LDADD = $(ECOREBASELDADD) @EVAS_LIBS@ $(top_builddir)/src/lib/ecore_evas/libecore_evas.la +ecore_evas_extn_socket_example_LDADD = $(ECOREBASELDADD) @EVAS_LIBS@ $(top_builddir)/src/lib/ecore_evas/libecore_evas.la +ecore_evas_extn_plug_example_LDADD = $(ECOREBASELDADD) @EVAS_LIBS@ $(top_builddir)/src/lib/ecore_evas/libecore_evas.la ecore_client_bench_LDADD = $(ECOREBASELDADD) $(top_builddir)/src/lib/ecore_con/libecore_con.la ecore_server_bench_LDADD = $(ECOREBASELDADD) $(top_builddir)/src/lib/ecore_con/libecore_con.la diff --git a/src/examples/ecore_con_client_example.c b/src/examples/ecore_con_client_example.c old mode 100644 new mode 100755 index c6ab50d..7dd33ad --- a/src/examples/ecore_con_client_example.c +++ b/src/examples/ecore_con_client_example.c @@ -59,8 +59,8 @@ main() ecore_con_init(); /* comment if not using gnutls */ - gnutls_global_set_log_level(9); - gnutls_global_set_log_function(tls_log_func); +// gnutls_global_set_log_level(9); +// gnutls_global_set_log_function(tls_log_func); if (!(it = eina_file_ls("/etc/ssl/certs"))) exit(1); diff --git a/src/examples/ecore_con_server_example.c b/src/examples/ecore_con_server_example.c old mode 100644 new mode 100755 index 7333521..6b23697 --- a/src/examples/ecore_con_server_example.c +++ b/src/examples/ecore_con_server_example.c @@ -57,8 +57,8 @@ main() ecore_con_init(); /* comment if not using gnutls */ - gnutls_global_set_log_level(9); - gnutls_global_set_log_function(tls_log_func); +// gnutls_global_set_log_level(9); +// gnutls_global_set_log_function(tls_log_func); /* to use a PEM certificate with TLS and SSL3, uncomment the lines below */ if (!(svr = ecore_con_server_add(ECORE_CON_REMOTE_TCP | ECORE_CON_USE_TLS | ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT, "127.0.0.1", 8080, NULL))) diff --git a/src/examples/ecore_con_url_download_example.c b/src/examples/ecore_con_url_download_example.c old mode 100644 new mode 100755 index 2f95db4..11355b4 --- a/src/examples/ecore_con_url_download_example.c +++ b/src/examples/ecore_con_url_download_example.c @@ -103,7 +103,7 @@ free_ec_url: ecore_con_url_free(ec_url); end: - close(fd); +// close(fd); ecore_con_url_shutdown(); ecore_con_shutdown(); ecore_shutdown(); diff --git a/src/examples/ecore_evas_extn_plug_example.c b/src/examples/ecore_evas_extn_plug_example.c new file mode 100644 index 0000000..cee919e --- /dev/null +++ b/src/examples/ecore_evas_extn_plug_example.c @@ -0,0 +1,226 @@ +/** + * Ecore example illustrating the basics of ecore evas extn socket usage. + * + * You'll need at least one Evas engine built for it (excluding the + * buffer one). See stdout/stderr for output. + * You can check functions of ecore extn socket if you use ecore extn plug together. + * + * @verbatim + * gcc -o ecore_evas_extn_socket_example ecore_evas_extn_socket_example.c `pkg-config --libs --cflags ecore-evas` + * @endverbatim + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define EINA_UNUSED +#endif + +#include +#include +#include +// procotol version - change this as needed +#define MSG_DOMAIN_CONTROL_OBJECT 0x1004 +#define MSG_ID_BG_COLOR 0x1005 +#define MSG_ID_TEXT 0x1006 + +typedef struct _Msg_Color Msg_Color; + +struct _Msg_Color +{ + int r; + int g; + int b; + int a; +}; + +static void +_on_delete(Ecore_Evas *ee) +{ + Msg_Color *color = NULL; + + color = ecore_evas_data_get(ee, "color"); + if (color) free(color); + ecore_main_loop_quit(); +} + +static void +_button_1_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee; + Msg_Color *color = NULL; + int r = 0, g = 0, b = 0, a = 0; + + ee = data; + color = ecore_evas_data_get(ee, "color"); + + printf("Plug's button pressed\n"); + if (!color) + { + color = malloc(sizeof(Msg_Color)); + r = 255; + g = 0; + b = 0; + a = 255; + ecore_evas_data_set(ee, "color", color); + } + else + { + r = ((color->r) + 100) % 255; + g = ((color->g) + 100) % 255; + b = ((color->b) + 100) % 255; + a = color->a; + } + printf("Send color info (%x,%x,%x,%x)\n", r, g, b, a); + + color->r = r; + color->g = g; + color->b = b; + color->a = a; + + ecore_evas_msg_parent_send(ee, MSG_DOMAIN_CONTROL_OBJECT, MSG_ID_BG_COLOR, color, sizeof(Msg_Color)); +} + +static void +_ecore_evas_msg_handle(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size) +{ + if (!data) return; + printf("Receive msg from server msg_domain=%x msg_id=%x size=%d\n", msg_domain, msg_id, size); + + if (msg_domain == MSG_DOMAIN_CONTROL_OBJECT) + { + if (msg_id == MSG_ID_TEXT) + { + Evas_Object *text = NULL; + char *txt = data; + int len = 0; + len = strlen(txt); + printf("data len= (%d).\n", len); + + text = ecore_evas_data_get(ee, "text"); + if (text && (size == strlen(txt))) + { + printf("Receive msg is text (%s).\n", txt); + evas_object_text_text_set(text, txt); + } + } + } +} + +int +main(void) +{ + Ecore_Evas *ee, *ee_plug; + Evas *canvas; + Evas_Object *bg, *button1, *text, *noti_text; + Evas_Object *plug; + int w, h; + int x1, x2, y; //for button position + int plug_x, plug_y, plug_w = 0, plug_h = 0; //for button position + + if (ecore_evas_init() <= 0) + return 1; + + w = 480; + h = 500; + x1 = 20; + x2 = 170; + y = 100; + plug_x = 10; + plug_y = y + (h / 4) + 20; + plug_w = 460; + plug_h = 200; + + ee = ecore_evas_new(NULL, 0, 0, w, h, NULL); + ecore_evas_title_set(ee, "Ecore Evas Extn Plug Example"); + ecore_evas_show(ee); + + ecore_evas_callback_delete_request_set(ee, _on_delete); + + printf("Using %s engine! ee=%p\n", ecore_evas_engine_name_get(ee), ee); + + //create ecore evas to show info + canvas = ecore_evas_get(ee); + if (ecore_evas_ecore_evas_get(canvas) == ee) + printf("Everything is sane!\n"); + + bg = evas_object_rectangle_add(canvas); + evas_object_color_set(bg, 255, 0, 255, 255); + evas_object_resize(bg, w, h); + evas_object_show(bg); + + //button to change socket's bg + button1 = evas_object_rectangle_add(canvas); + evas_object_color_set(button1, 0, 255, 255, 255); + evas_object_resize(button1, w/4, 100); + evas_object_move(button1, x1, y); + evas_object_show(button1); + + text = evas_object_text_add(canvas); + evas_object_color_set(text, 0, 0, 0, 255); + evas_object_text_style_set(text, EVAS_TEXT_STYLE_PLAIN); + evas_object_text_font_set(text, "Sans", 15); + evas_object_text_text_set(text, "Chagne bg!!"); + evas_object_move(text, x1 + 5, y + 10); + evas_object_show(text); + + + //button to send msg1 to socket + bg = evas_object_rectangle_add(canvas); + evas_object_color_set(bg, 0, 255, 255, 255); + evas_object_resize(bg, w/2, 100); + evas_object_move(bg, x2, y); + evas_object_show(bg); + text = evas_object_text_add(canvas); + evas_object_color_set(text, 0, 0, 0, 255); + evas_object_text_style_set(text, EVAS_TEXT_STYLE_PLAIN); + evas_object_text_font_set(text, "Sans", 15); + evas_object_text_text_set(text, "No Message from server!!"); + evas_object_move(text, x2 + 5, y + 10); + evas_object_show(text); + + //text to noti plug area + noti_text = evas_object_text_add(canvas); + evas_object_color_set(noti_text, 0, 0, 0, 255); + evas_object_text_style_set(noti_text, EVAS_TEXT_STYLE_PLAIN); + evas_object_text_font_set(noti_text, "Sans", 15); + evas_object_text_text_set(noti_text, "Below is the plug area!!"); + evas_object_move(noti_text, x1, plug_y - 25); + evas_object_show(noti_text); + + //create ecore evas extn plug(image object) show socket area + plug = ecore_evas_extn_plug_new(ee); + ecore_evas_data_set(ee, "plug", plug); + if (!plug) + { + printf("Fail to create ecore extn plug!\n"); + return 0; + } + + ee_plug = ecore_evas_object_ecore_evas_get(plug); + ecore_evas_data_set(ee_plug, "text", text); + + if(!ecore_evas_extn_plug_connect(plug, "socket_exam_service", 0, EINA_FALSE)) + { + printf("Fail to connect socket_exam_service!\n"); + return 0; + } + + evas_object_event_callback_add(button1, EVAS_CALLBACK_MOUSE_UP, _button_1_up, ee_plug); + //callback to deal with extn socket message + ecore_evas_callback_msg_handle_set(ee_plug, _ecore_evas_msg_handle); + + ecore_evas_data_set(ee_plug, "text", text); + + evas_object_resize(plug, plug_w, plug_h); + evas_object_move(plug, plug_x, plug_y); + evas_object_show(plug); + + ecore_main_loop_begin(); + + ecore_evas_free(ee); + ecore_evas_shutdown(); + + return 0; +} + diff --git a/src/examples/ecore_evas_extn_socket_example.c b/src/examples/ecore_evas_extn_socket_example.c new file mode 100644 index 0000000..5697c57 --- /dev/null +++ b/src/examples/ecore_evas_extn_socket_example.c @@ -0,0 +1,202 @@ +/** + * Ecore example illustrating the basics of ecore evas extn socket usage. + * + * You'll need at least one Evas engine built for it (excluding the + * buffer one). See stdout/stderr for output. + * You can check functions of ecore extn socket if you use ecore extn plug together. + * + * @verbatim + * gcc -o ecore_evas_extn_socket_example ecore_evas_extn_socket_example.c `pkg-config --libs --cflags ecore-evas` + * @endverbatim + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define EINA_UNUSED +#endif + +#include +#include +#include + +// procotol version - change this as needed +#define MSG_DOMAIN_CONTROL_OBJECT 0x1004 +#define MSG_ID_BG_COLOR 0x1005 +#define MSG_ID_TEXT 0x1006 +static int num = 0; +typedef struct _Msg_Color Msg_Color; + +struct _Msg_Color +{ + int r; + int g; + int b; + int a; +}; + +static void +_on_delete(Ecore_Evas *ee) +{ + Ecore_Evas *ee_socket = NULL; + char *text = NULL; + ee_socket = ecore_evas_data_get(ee, "sock"); + if (ee_socket) + { + text = ecore_evas_data_get(ee_socket, "text"); + if (text) free(text); + } + ecore_main_loop_quit(); +} + +static void +_ecore_evas_msg_parent_handle(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size) +{ + printf("Receive msg from clien msg_domain=%x msg_id=%x size=%d\n", msg_domain, msg_id, size); + if (!data) return; + + if (msg_domain == MSG_DOMAIN_CONTROL_OBJECT) + { + if (msg_id == MSG_ID_BG_COLOR) + { + Evas_Object *bg = NULL; + Msg_Color *color = NULL; + int r = 0, g = 0, b = 0, a = 0; + + bg = ecore_evas_data_get(ee, "bg"); + if (bg && (size == sizeof(Msg_Color))) + { + color = data; + r = color->r; + g = color->g; + b = color->b; + a = color->a; + printf("Receive msg is color r=%x g=%x b=%x a=%x\n", r, g, b, a); + evas_object_color_set(bg, color->r, color->g, color->b, color->a); + } + } + } +} + +static void +_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + size_t len = 0; + char *buf = NULL;; + + num++; + + if (!ee) return; + buf = ecore_evas_data_get(ee, "text"); + if (!buf) free(buf); + + buf = (char *)malloc(40); + memset(buf, 0, 40); + sprintf(buf, "Hello. I'm server!! number=%d!!", num); + len = strlen(buf); + ecore_evas_data_set(ee, "text", buf); + + printf("ecore extn socket txt = \"%s\" len=%d.", buf, len); + ecore_evas_msg_send(ee, MSG_DOMAIN_CONTROL_OBJECT, MSG_ID_TEXT, buf, len); +} + +int +main(void) +{ + Ecore_Evas *ee; + Ecore_Evas *ee_socket = NULL; + Evas *canvas; + Evas_Object *bg, *text; + Evas_Object *sock_bg; + int w, h; + int socket_w, socket_h; + + if (ecore_evas_init() <= 0) + return 1; + + w = 480; + h = 200; + + ee = ecore_evas_new(NULL, 0, 0, w, h, NULL); + ecore_evas_title_set(ee, "Ecore Evas Extn Socket Example"); + ecore_evas_show(ee); + + ecore_evas_callback_delete_request_set(ee, _on_delete); + + printf("Using %s engine! ee=%p\n", ecore_evas_engine_name_get(ee), ee); + + //create ecore evas to show info + canvas = ecore_evas_get(ee); + if (ecore_evas_ecore_evas_get(canvas) == ee) + printf("Everything is sane!\n"); + + bg = evas_object_rectangle_add(canvas); + evas_object_color_set(bg, 255, 255, 0, 255); + evas_object_resize(bg, w, h); + evas_object_show(bg); + + text = evas_object_text_add(canvas); + evas_object_color_set(text, 0, 0, 0, 255); + evas_object_text_style_set(text, EVAS_TEXT_STYLE_PLAIN); + evas_object_text_font_set(text, "Sans", 15); + evas_object_text_text_set(text, "1. Run ecore_evas_extn_plug_examples!!"); + evas_object_move(text, 40, 30); + evas_object_show(text); + + text = evas_object_text_add(canvas); + evas_object_color_set(text, 0, 0, 0, 255); + evas_object_text_style_set(text, EVAS_TEXT_STYLE_PLAIN); + evas_object_text_font_set(text, "Sans", 15); + evas_object_text_text_set(text, "2. Press green rect to send msg to clients!!"); + evas_object_move(text, 40, 60); + evas_object_show(text); + + bg = evas_object_rectangle_add(canvas); + evas_object_color_set(bg, 0, 255, 0, 255); + evas_object_resize(bg, w/4, h/4); + evas_object_move(bg, w/4, h/2); + evas_object_show(bg); + + //create ecore evas extn socket + socket_w = 460; + socket_h = 250; + + ee_socket = ecore_evas_extn_socket_new(1, 1); + ecore_evas_data_set(ee, "sock", ee_socket); + + if (!ee_socket) + { + printf("Fail to create ecore extn socket!\n"); + return 0; + } + + if(!ecore_evas_extn_socket_listen(ee_socket, "socket_exam_service", 0, EINA_FALSE)) + { + printf("Fail to listen socket_exam_service!\n"); + return 0; + } + ecore_evas_resize(ee_socket, socket_w, socket_h); + ecore_evas_show(ee_socket); + + //callback to deal with cient extn's message + ecore_evas_callback_msg_parent_handle_set(ee_socket, _ecore_evas_msg_parent_handle); + //_mouse_up is function to send msg to client extn plug + evas_object_event_callback_add(bg, EVAS_CALLBACK_MOUSE_UP, _mouse_up, ee_socket); + + canvas = ecore_evas_get(ee_socket); + + sock_bg = evas_object_rectangle_add(canvas); + evas_object_color_set(sock_bg, 0, 0, 255, 255); + evas_object_resize(sock_bg, socket_w, socket_h); + evas_object_move(sock_bg, 0, 0); + evas_object_show(sock_bg); + ecore_evas_data_set(ee_socket, "bg", sock_bg); + + ecore_main_loop_begin(); + + ecore_evas_free(ee); + ecore_evas_shutdown(); + + return 0; +} diff --git a/src/examples/ecore_imf_example.c b/src/examples/ecore_imf_example.c old mode 100644 new mode 100755 index c2d02a0..37a31b4 --- a/src/examples/ecore_imf_example.c +++ b/src/examples/ecore_imf_example.c @@ -131,7 +131,7 @@ _ecore_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx, char **te Entry *en = data; const char *str; - if (!en) return; + if (!en) return EINA_FALSE; str = evas_object_textblock_text_markup_get(en->txt_obj); *text = str ? strdup(str) : strdup(""); @@ -426,7 +426,6 @@ create_input_field(Evas *evas, Entry *en, Evas_Coord x, Evas_Coord y, Evas_Coord return; en->imf_context = ecore_imf_context_add(default_id); - ecore_imf_context_client_window_set(en->imf_context, (void *)ecore_evas_window_get(ecore_evas_ecore_evas_get(evas))); ecore_imf_context_client_canvas_set(en->imf_context, evas); evas_object_event_callback_add(en->rect, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, en); diff --git a/src/examples/ecore_thread_example.c b/src/examples/ecore_thread_example.c old mode 100644 new mode 100755 index f02d007..30555d0 --- a/src/examples/ecore_thread_example.c +++ b/src/examples/ecore_thread_example.c @@ -79,7 +79,6 @@ _short_job(void *data, Ecore_Thread *th) snprintf(buf, sizeof(buf), "Thread %p: String number %d", th, i); td->list = eina_list_append(td->list, strdup(buf)); - sleep(1); } } diff --git a/src/lib/ecore/Ecore.h b/src/lib/ecore/Ecore.h index ef79a21..d218271 100644 --- a/src/lib/ecore/Ecore.h +++ b/src/lib/ecore/Ecore.h @@ -1,139 +1,69 @@ /** - @brief Ecore Library Public API Calls - - These routines are used for Ecore Library interaction - */ - -/** - - @mainpage Ecore - - @version 1.2 - @date 2000-2012 - - Please see the @ref authors page for contact details. - - @section intro Introduction - - Ecore is a library of convenience functions. A brief explanation of how to use - it can be found in @ref Ecore_Main_Loop_Page. - - The Ecore library provides the following modules: - @li @ref Ecore_Main_Loop_Group - @li @ref Ecore_File_Group - @li @ref Ecore_Con_Group - @li @ref Ecore_Evas_Group - @li @ref Ecore_FB_Group - @li @ref Ecore_IMF_Lib_Group - @li @ref Ecore_IMF_Context_Group - @li @ref Ecore_IMF_Context_Module_Group - @li @ref Ecore_IMF_Evas_Group - @li @link Ecore_Ipc.h Ecore_IPC - Inter Process Communication functions. @endlink - @li @link Ecore_X.h Ecore_X - X Windows System wrapper. @endlink - @li @ref Ecore_Win32_Group - @li @ref Ecore_WinCE_Group - - For more info on Ecore usage, there are these @ref Examples. - - @section compiling How to compile using Ecore? - pkgconfig (.pc) files are installed for every ecore module. - Thus, to compile using any of them, you can use something like the following: - -@verbatim -gcc *.c $(pkg-config ecore ecore-$x ecore-$y [...] --cflags --libs) -@endverbatim - - @section install How is it installed? - - Suggested configure options for ecore for a Linux desktop X display - with OpenGL and Software support, communication (networking) and - IPC (inter process communication): - -@verbatim -./configure \ - --enable-ecore-con \ - --enable-ecore-ipc \ - --enable-ecore-file \ - --enable-ecore-input \ - --enable-ecore-input-evas \ - --enable-ecore-x \ - --enable-ecore-evas \ - --enable-ecore-evas-software-buffer \ - --enable-ecore-evas-software-x11 \ - --enable-ecore-evas-opengl-x11 -make -sudo make install -@endverbatim - - */ - -/** - @page authors Authors - @author Carsten Haitzler - @author Tom Gilbert - @author Burra - @author Chris Ross - @author Term - @author Tilman Sauerbeck - @author Ibukun Olumuyiwa - @author Yuri - @author Nicholas Curran - @author Howell Tam - @author Nathan Ingersoll - @author Andrew Elcock - @author Kim Woelders - @author Sebastian Dransfeld - @author Simon Poole - @author Jorge Luis Zapata Muga - @author dan sinclair - @author Michael 'Mickey' Lauer - @author David 'onefang' Seikel - @author Hisham 'CodeWarrior' Mardam Bey - @author Brian 'rephorm' Mattern - @author Tim Horton - @author Arnaud de Turckheim 'quarium' - @author Matt Barclay - @author Peter Wehrfritz - @author Albin "Lutin" Tonnerre - @author Vincent Torri - @author Lars Munch - @author Andre Dieb - @author Mathieu Taillefumier - @author Rui Miguel Silva Seabra - @author Samsung Electronics - @author Samsung SAIT - @author Nicolas Aguirre - @author Brett Nash - @author Mike Blumenkrantz - @author Leif Middelschulte - @author Mike McCormack - @author Sangho Park - @author Jihoon Kim - @author PnB - @author Daniel Juyung Seo - @author Christopher 'devilhorns' Michael - @author ChunEon Park - @author xlopez@igalia.com - @author Rafael Antognolli - @author Kim Yunhan - @author Youness Alaoui - @author Bluezery - @author Doyoun Kang - @author Haifeng Deng - @author Jérémy Zurcher - @author Vikram Narayanan - - Please contact to get in - contact with the developers and maintainers. + * @defgroup Ecore_Group Ecore + * @ingroup EFL_Group + * + * @brief Ecore Library Public API Calls + * + * @remarks These routines are used for Ecore Library interaction. + * + * See @ref ecore_main for more details + * + * @page ecore_main Ecore + * + * @date 2000 (created) + * + * @section toc Table of Contents + * + * @li @ref ecore_main_intro + * @li @ref ecore_main_next_steps + * + * @section ecore_main_intro Introduction + * + * Ecore is a library of convenience functions. A brief explanation of how to use + * it can be found in @ref Ecore_Main_Loop_Page. + * + * The Ecore library provides the following modules: + * @li @ref Ecore_Main_Loop_Group + * @internal + * @li @ref Ecore_File_Group + * @li @ref Ecore_Con_Group + * @li @ref Ecore_Evas_Group + * @li @ref Ecore_FB_Group + * @li @ref Ecore_IMF_Group + * @li @ref Ecore_IMF_Context_Group + * @li @ref Ecore_IMF_Evas_Group + * @endinternal + * @li @link Ecore_Ipc.h Ecore_IPC - Inter Process Communication functions. @endlink + * @internal + * @li @link Ecore_X.h Ecore_X - X Windows System wrapper. @endlink + * @endinternal + * + * @section ecore_main_next_steps Next Steps + * + * After you understood what Ecore is and installed it in your system + * you should proceed understanding the programming interface. We'd + * recommend you to take a while to learn @ref Eina_Group as it is very + * convenient and optimized, and Ecore uses it extensively. + * + * Recommended reading: + * + * @li @ref Ecore_Timer_Group + * @li @ref Ecore_Idle_Group + * @li @ref Ecore_FD_Handler_Group + * @li @ref Ecore_Event_Group + * @internal + * @li @ref Ecore_Exe_Group + * @endinternal + * */ /** * @page Ecore_Main_Loop_Page The Ecore Main Loop * - * @section intro What is Ecore? + * @section Ecore_Main_Loop_Page_intro What is Ecore? * * Ecore is a clean and tiny event loop library with many modules to do lots of - * convenient things for a programmer, to save time and effort. It's small and + * convenient things for a programmer as well as to save time and effort. It's small and * lean, designed to work from embedded systems all the way up to large and * powerful multi-cpu workstations. The main loop has a number of primitives to * be used with its main loop. It serializes all the primitives and allows for @@ -145,40 +75,40 @@ sudo make install * repeatedly doing something with a set interval. * @see Ecore_Timer_Group * - * @subsection poolers Poolers + * @subsection pollers Pollers * - * Poolers allow for pooling to be centralized into a single place therefore + * Pollers allow for polling to be centralized into a single place. Therefore, * alleviating the need for different parts of the program to wake up at - * different times to do pooling, thereby making the code simpler and more + * different times to do polling, thereby making the code simpler and more * efficient. * @see Ecore_Poller_Group * * @subsection idler Idlers * - * There are three types of idlers, enterers, idlers(proper) and exiters, they - * are called, respectively, when the program is about to enter an idle state, - * when the program is idle and when the program is leaving an idle state. Idler + * There are three types of idlers: enterers, idlers(proper), and exiters, they + * are called respectively when the program is about to enter an idle state, + * when the program is idle, and when the program is leaving an idle state. Idler * enterers are usually a good place to update the program state. Proper idlers * are the appropriate place to do heavy computational tasks thereby using what * would otherwise be wasted CPU cycles. Exiters are the perfect place to do - * anything your program should do just before processing events(also timers, - * poolers, file descriptor handlers and animators) + * anything that your program should do just before processing events(also timers, + * poolers, file descriptor handlers, and animators) * @see Ecore_Idle_Group * * @subsection fd_handler File descriptor handlers * * File descriptor handlers allow you to monitor when there is data available to - * read on file descriptors, when writing will not block or if there was an - * error. Any valid file descriptor can be used with this API, regardless of if - * was gotten with an OS specific API or from ecore. + * read on file descriptors, when writing is not blocked or when there is an + * error. Any valid file descriptor can be used with this API, regardless of whether + * it is obtained with an OS specific API or from ecore. * @see Ecore_FD_Handler_Group * * @subsection animators Animators * * Ecore provides a facility called animators, so named since the intended use - * was in animations, that facilitates knowing what percentage of a given + * is in animations, that facilitates knowing what percentage of a given * interval has elapsed. This is perfect for performing animations, but is not - * limited to that use, it can, for example, also be used to create a progress + * limited to that use. It can, for example, also be used to create a progress * bar. * @see Ecore_Animator_Group * @@ -186,97 +116,40 @@ sudo make install * * Event handlers are, arguably, the most important feature of the ecore main * loop, they are what allows the programmer to easily handle user interaction. - * Events however are not only things the user does, events can represent + * Events, however, are not the only things that the user does. Events can represent * anything for which a type is created. * @see Ecore_Event_Group * * All of these primitives are discussed in more detail in their respective - * pages linked above. + * pages that are linked above. * * Here is a diagram of the main loop flow of a simple program: * * @image html prog_flow.png - * @image latex prog_flow.eps width=\textwidth - * + * @image latex prog_flow.eps "prog flow" width=\textwidth * - * - * @section work How does Ecore work? + * @section Ecore_Main_Loop_Page_work How does Ecore work? * * Ecore is very easy to learn and use. All the function calls are designed to * be easy to remember, explicit in describing what they do, and heavily - * name-spaced. Ecore programs can start and be very simple. + * name-spaced. Ecore programs can start easily and are very simple. * * For example: * - * @code - * #include - * - * int - * main(int argc, const char **argv) - * { - * ecore_init(); - * ecore_app_args_set(argc, argv); - * ecore_main_loop_begin(); - * ecore_shutdown(); - * return 0; - * } - * @endcode - * * This program is very simple and doesn't check for errors, but it does start up - * and begin a main loop waiting for events or timers to tick off. This program + * and begin a main loop that is waiting for events or timers to tick off. This program * doesn't set up any, but now we can expand on this simple program a little * more by adding some event handlers and timers. * - * @code - * #include - * - * Ecore_Timer *timer1 = NULL; - * Ecore_Event_Handler *handler1 = NULL; - * double start_time = 0.0; - * - * int - * timer_func(void *data) - * { - * printf("Tick timer. Sec: %3.2f\n", ecore_time_get() - start_time); - * return 1; - * } - * - * int - * exit_func(void *data, int ev_type, void *ev) - * { - * Ecore_Event_Signal_Exit *e; - * - * e = (Ecore_Event_Signal_Exit *)ev; - * if (e->interrupt) printf("Exit: interrupt\n"); - * else if (e->quit) printf("Exit: quit\n"); - * else if (e->terminate) printf("Exit: terminate\n"); - * ecore_main_loop_quit(); - * return 1; - * } - * - * int - * main(int argc, const char **argv) - * { - * ecore_init(); - * ecore_app_args_set(argc, argv); - * start_time = ecore_time_get(); - * handler1 = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, NULL); - * timer1 = ecore_timer_add(0.5, timer_func, NULL); - * ecore_main_loop_begin(); - * ecore_shutdown(); - * return 0; - * } - * @endcode - * * In the previous example, we initialize our application and get the time at - * which our program has started so we can calculate an offset. We set - * up a timer to tick off in 0.5 seconds, and since it returns 1, will - * keep ticking off every 0.5 seconds until it returns 0, or is deleted + * which our program has started so that we can calculate an offset. We set + * up a timer to tick off in @c 0.5 seconds, and since it returns @c 1, it + * keeps ticking off every @c 0.5 seconds until it returns @c 0, or is deleted * by hand. An event handler is set up to call a function - * exit_func(), * whenever an event of type ECORE_EVENT_SIGNAL_EXIT is received (CTRL-C - * on the command line will cause such an event to happen). If this event - * occurs it tells you what kind of exit signal was received, and asks + * on the command line causes such an event to happen). If this event + * occurs it tells you what kind of exit signal is received, and asks * the main loop to quit when it is finished by calling * ecore_main_loop_quit(). * @@ -284,11 +157,11 @@ sudo make install * ecore_event_handler_add() are * only stored here as an example. If you don't need to address the timer or * event handler again you don't need to store the result, so just call the - * function, and don't assign the result to any variable. + * function and don't assign the result to any variable. * * This program looks slightly more complex than needed to do these simple * things, but in principle, programs don't get any more complex. You add more - * event handlers, for more events, will have more timers and such, BUT it all + * event handlers for more events, you have more timers, BUT it all * follows the same principles as shown in this example. * */ @@ -302,21 +175,9 @@ sudo make install To use the library, you: @li Set the default values of your properties. - @li Load the configuration from a file. You must set the default values + @li Load the configuration from a file. You must set the default values first, so that the library knows the correct type of each argument. - The following examples show how to use the Enlightened Property Library: - @li @link config_basic_example.c config_basic_example.c @endlink - @li @link config_listener_example.c config_listener_example.c @endlink - - */ - -/** - @page X_Window_System_Page X Window System - - The Ecore library includes a wrapper for handling the X window system. - This page briefly explains what the X window system is and various terms - that are used. */ #ifndef _ECORE_H @@ -359,6 +220,8 @@ sudo make install #elif defined (__FreeBSD__) || defined (__OpenBSD__) # include # include +#elif defined (__ANDROID__) +# include #else # include # if !defined (EXOTIC_NO_SIGNAL) @@ -373,12 +236,73 @@ extern "C" { #endif /** - * @defgroup Ecore_Init_Group Ecore initialization and shutdown functions. + * @internal + * @defgroup Ecore_Init_Group Ecore initialization, shutdown functions and reset on fork. + * @ingroup Ecore_Group * * @{ */ +/** + * @brief Initialize the Ecore library. + * + * @details This function sets up connections, sockets, all singal handlers and + * the basic event loop, etc. If it succeeds, 1 or greater will be + * returned, otherwise 0 will be returned. + * + * @remarks This function initializes the Ecore library, making the proper calls + * to internal initialization functions. It will also initialize its + * @b dependencies, making calls to @c eina_init(). + * So, there is no need to call those functions again, in your code. + * To shutdown Ecore, there is the function ecore_shutdown(). + * + * @code + * #include + * + * int main(int argc, char **argv) + * { + * if (!ecore_init()) + * { + * printf("ERROR: Cannot init Ecore!\n"); + * return -1; + * } + * ecore_main_loop_begin(); + * ecore_shutdown(); + * } + * @endcode + * + * @return 1 or greater on success, 0 otherwise + * + * @see ecore_shutdown() + * @see eina_init() + */ EAPI int ecore_init(void); + +/** + * @brief Shutdown the Ecore library. + * + * @details Shut down connections, signal handlers sockets etc. + * + * @remarks This function shuts down all things set up in ecore_init() and + * cleans up all event queues, handlers, filters, timers, idlers, + * idle enterers/exiters etc. set up after ecore_init() was called. + * + * @remarks Do not call this function from any callback that may be called + * from the main loop, as the main loop will then fall over and not + * function properly. + * + * @details This function shuts down the Edje library. It will also call the + * shutdown functions of its @b dependencies, which is @c + * eina_shutdown(). + * so there is no need to call these functions again in your code. + * This returns The number of times the library has been initialised + * without being shutdown. + * + * @return 0 if ecore shuts down, greater than 0 otherwise. + * + * @see ecore_init() + * @see eina_shutdown() + */ EAPI int ecore_shutdown(void); /** @@ -386,21 +310,38 @@ EAPI int ecore_shutdown(void); */ /** - * @defgroup Ecore_Main_Loop_Group Ecore main loop + * @internal + * @defgroup Ecore_Application_Group Ecore Application + * @ingroup Ecore_Group + * + * @{ + */ + +EAPI void ecore_app_args_set(int argc, const char **argv); +EAPI void ecore_app_args_get(int *argc, char ***argv); +EAPI void ecore_app_restart(void); + +/** + * @} + */ + +/** + * @defgroup Ecore_Main_Loop_Group Ecore Main Loop + * @ingroup Ecore_Group * - * This group discusses functions that are acting on Ecore's main loop itself or - * on events and infrastructure directly linked to it. Most programs only need - * to start and end the main loop, the rest of the function discussed here are - * meant to be used in special situations, and with great care. + * @brief This group discusses functions that are acting on Ecore's main loop itself or + * on events and infrastructure directly linked to it. Most programs only need + * to start and end the main loop, the rest of the function discussed here is + * meant to be used in special situations, and with great care. * - * For details on the usage of ecore's main loop and how it interacts with other - * ecore facilities see: @ref Ecore_Main_Loop_Page. + * For details on the usage of ecore's main loop and how it interacts with other + * ecore facilities see: @ref Ecore_Main_Loop_Page. * * @{ */ #define ECORE_VERSION_MAJOR 1 -#define ECORE_VERSION_MINOR 6 +#define ECORE_VERSION_MINOR 8 typedef struct _Ecore_Version { @@ -415,109 +356,330 @@ EAPI extern Ecore_Version *ecore_version; #define ECORE_CALLBACK_CANCEL EINA_FALSE /**< Return value to remove a callback */ #define ECORE_CALLBACK_RENEW EINA_TRUE /**< Return value to keep a callback */ -#define ECORE_CALLBACK_PASS_ON EINA_TRUE /**< Return value to pass event to next handler */ +#define ECORE_CALLBACK_PASS_ON EINA_TRUE /**< Return value to pass an event to the next handler */ #define ECORE_CALLBACK_DONE EINA_FALSE /**< Return value to stop event handling */ /** * @typedef Ecore_Task_Cb Ecore_Task_Cb - * A callback run for a task (timer, idler, poller, animator, etc) + * @brief The boolean type for a callback that is run for a task (timer, idler, poller, animator, and so on). */ typedef Eina_Bool (*Ecore_Task_Cb)(void *data); /** + * @typedef Ecore_Cb Ecore_Cb + * @brief Called as a hook when a certain point in the execution is reached. + */ +typedef void (*Ecore_Cb)(void *data); + +/** + * @typedef Ecore_Data_Cb Ecore_Data_Cb + * @brief Called to return data to the main function. + */ +typedef void *(*Ecore_Data_Cb)(void *data); + +/** * @typedef Ecore_Select_Function - * A function which can be used to replace select() in the main loop + * @brief The integer type for a function that can be used to replace select() in the main loop. */ typedef int (*Ecore_Select_Function)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); +/** + * @brief Adds a function to be called by ecore_fork_reset(). + * + * @details This queues @a func to be called (and passes @a data as its argument) when + * ecore_fork_reset() is called. This allows other libraries and subsystems + * to also reset their internal state after a fork. + * + * @param[in] func The function to be called + * @param[in] data A data pointer to pass to the called function @a func + * @return #EINA_TRUE if succeed, otherwise #EINA_FALSE. + * + * @since 1.7 + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + */ +EAPI Eina_Bool ecore_fork_reset_callback_add(Ecore_Cb func, const void *data); + +/** + * @brief Removes the specified callback. + * + * @details This deletes the callback added by ecore_fork_reset_callback_add() using + * the function and data pointer to specify which callback to remove. + * + * @param[in] func The function to be called + * @param[in] data A data pointer to pass to the called function @a func + * @return #EINA_TRUE if succeed, otherwise #EINA_FALSE. + * + * @since 1.7 + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + */ +EAPI Eina_Bool ecore_fork_reset_callback_del(Ecore_Cb func, const void *data); + +/** + * @brief Resets the ecore's internal state after a fork. + * + * @since 1.7 + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks Ecore maintains the internal data that can be affected by the fork() system call, + * which creates a duplicate of the current process. This also duplicates + * file descriptors, which is problematic as these file descriptors still + * point to their original sources. This function makes ecore's reset internal + * state (e.g. pipes used for signalling between threads) so they function + * correctly afterwards. + * + * @remarks It is highly suggested that you call this function after any fork() + * system call inside the child process. If you intend to use ecore features + * after this point and not call exec() family functions. Not doing so + * causes a possible misbehaviour. + */ +EAPI void ecore_fork_reset(void); + +/** + * @brief Runs a single iteration of the main loop to process everything on the + * queue. + * + * @details It does everything that is already done inside an @c Ecore main loop, + * like checking for expired timers, idlers, etc. But it will do it + * only once and return, instead of keep watching for new events. + * + * @remarks DO NOT use this function unless you are the person God comes to ask + * for advice when He has trouble managing the Universe. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + */ EAPI void ecore_main_loop_iterate(void); +/** + * @brief Sets the function to use when monitoring multiple file descriptors, + * and waiting until one of more of the file descriptors before ready + * for some class of I/O operation. + * + * @remarks This function will be used instead of the system call select and + * could possible be used to integrate the Ecore event loop with an + * external event loop. + * + * @remarks you don't know how to use, don't even try to use it. + * + * @param func The function to be used. + * + * @see ecore_main_loop_select_func_get() + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + */ EAPI void ecore_main_loop_select_func_set(Ecore_Select_Function func); + +/** + * @brief Gets the select function set by ecore_select_func_set(), + * or the native select function if none was set. + * + * @return The select function + * + * @see ecore_main_loop_select_func_get() + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + */ EAPI Ecore_Select_Function ecore_main_loop_select_func_get(void); +/** + * @brief Request ecore to integrate GLib's main loop. + * + * @details This will add a small overhead during every main loop interaction + * by checking glib's default main context (used by its main loop). If + * it have events to be checked (timers, file descriptors or idlers), + * then these will be polled alongside with Ecore's own events, then + * dispatched before Ecore's. This is done by calling + * ecore_main_loop_select_func_set(). + * + * @remarks This will cooperate with previously set + * ecore_main_loop_select_func_set() by calling the old function. + * Similarly, if you want to override + * ecore_main_loop_select_func_set() after main loop is integrated, + * call the new select function set by this call (get it by calling + * ecore_main_loop_select_func_get() right after + * ecore_main_loop_glib_integrate()). + * + * @remarks This is useful to use GMainLoop libraries, like GTK, GUPnP, + * LibSoup, GConf and more. Adobe Flash plugin and other plugins + * systems depend on this as well. + * + * @remarks Once initialized/integrated, it will be valid until Ecore is + * completely shut down. + * + * @remarks This is only available if Ecore was compiled with GLib support. + * @remarks You don't need to call this function if Ecore was compiled with + * --with-glib=always. + * + * @return #EINA_TRUE on success of @c EINA_FALSE if it failed, + * likely no GLib support in Ecore. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + */ EAPI Eina_Bool ecore_main_loop_glib_integrate(void); -EAPI void ecore_main_loop_glib_always_integrate_disable(void); -EAPI void ecore_main_loop_begin(void); -EAPI void ecore_main_loop_quit(void); +/** + * @brief Disable always integrating glib + * + * @remarks If ecore is compiled with --with-glib=always (to always call + * ecore_main_loop_glib_integrate()), + * This is for apps that explicitly do not want this + * to happen for whatever reasons they may have. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + */ +EAPI void ecore_main_loop_glib_always_integrate_disable(void); /** - * @typedef Ecore_Cb Ecore_Cb - * A generic callback called as a hook when a certain point in - * execution is reached. + * @brief Runs the application main loop. + * + * @details This function will not return until @ref ecore_main_loop_quit is + * called. It will check for expired timers, idlers, file descriptors + * being watched by fd handlers, etc. Once everything is done, before + * entering again on idle state, any callback set as @c Idle_Enterer + * will be called. + * + * @remarks Each main loop iteration is done by calling + * ecore_main_loop_iterate() internally. + * + * @remarks The polling (select) function used can be changed with + * ecore_main_loop_select_func_set(). + * + * @remarks The function used to check for file descriptors, events, and that + * has a timeout for the timers can be changed using + * ecore_main_loop_select_func_set(). + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * */ -typedef void (*Ecore_Cb)(void *data); +EAPI void ecore_main_loop_begin(void); /** - * @typedef Ecore_Data_Cb Ecore_Data_Cb - * A callback which is used to return data to the main function + * @brief Quits the main loop once all the events currently on the queue have + * been processed. + * + * @details This function returns immediately, but will mark the + * ecore_main_loop_begin() function to return at the end of the + * current main loop iteration. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * */ -typedef void *(*Ecore_Data_Cb)(void *data); +EAPI void ecore_main_loop_quit(void); /** - * @brief Call callback asynchronously in the main loop. + * @brief Called asynchronously in the main loop. + * * @since 1.1.0 * + * @remarks For all calls that need to happen in the main loop (most EFL functions do), + * this helper function provides the infrastructure needed to do it safely + * by avoiding a dead lock, race condition, and by properly waking up the main loop. + * + * @remarks Remember that after the function call, you should never touch the @a data + * in the thread again, it is owned by the main loop and your callback should take + * care of freeing it, if necessary. + * * @param callback The callback to call in the main loop - * @param data The data to give to that call back + * @param data The data to give to that call * - * For all calls that need to happen in the main loop (most EFL functions do), - * this helper function provides the infrastructure needed to do it safely - * by avoiding dead lock, race condition and properly wake up the main loop. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * Remember after that function call, you should never touch again the @p data - * in the thread, it is owned by the main loop and your callback should take - * care of freeing it if necessary. */ EAPI void ecore_main_loop_thread_safe_call_async(Ecore_Cb callback, void *data); /** - * @brief Call callback synchronously in the main loop. + * @brief Called synchronously in the main loop. + * * @since 1.1.0 * + * @remarks For all calls that need to happen in the main loop (most EFL functions do), + * this helper function provides the infrastructure needed to do it safely + * by avoiding a dead lock, race condition, and by properly waking up the main loop. + * + * @remarks Remember that this function blocks until the callback is executed in the + * main loop. It can take time and you have no guarantee about the timeline. + * * @param callback The callback to call in the main loop - * @param data The data to give to that call back - * @return the value returned by the callback in the main loop + * @param data The data to give to that call + * @return The value returned by the callback in the main loop * - * For all calls that need to happen in the main loop (most EFL functions do), - * this helper function provides the infrastructure needed to do it safely - * by avoiding dead lock, race condition and properly wake up the main loop. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * Remember this function will block until the callback is executed in the - * main loop. It can take time and you have no guaranty about the timeline. */ EAPI void *ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback, void *data); /** - * @brief This function suspend the main loop in a know state + * @brief Suspends the main loop in the know state. + * + * @details This function suspends the main loop in the know state. This lets you + * use any EFL call that you want after it returns. Be careful, the main loop + * is blocked until you call ecore_thread_main_loop_end(). This is + * the only way to achieve pseudo thread safety. + * * @since 1.1.0 * - * @result the number of time ecore_thread_main_loop_begin() has been called - * in this thread, if the main loop was suspended correctly. If not, it return @c -1. + * @remarks Notice that till the main loop is blocked, the thread is blocked + * and there is no way around that. * - * This function suspend the main loop in a know state, this let you - * use any EFL call you want after it return. Be carefully, the main loop - * is blocked until you call ecore_thread_main_loop_end(). This is - * the only sane way to achieve pseudo thread safety. + * @remarks We still advise you, if possible, to use ecore_main_loop_thread_safe_call_async() + * as it does not block the thread or the main loop. * - * Notice that until the main loop is blocked, the thread is blocked - * and their is noway around that. + * @return The number of times ecore_thread_main_loop_begin() has been called + * in this thread, if the main loop is suspended correctly \n + * If not, it returns @c -1. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * We still advise you, when possible, to use ecore_main_loop_thread_safe_call_async() - * as it will not block the thread nor the main loop. */ EAPI int ecore_thread_main_loop_begin(void); /** - * @brief Unlock the main loop. + * @brief Unlocks the main loop. + * * @since 1.1.0 * - * @result the number of time ecore_thread_main_loop_end() need to be called before - * the main loop is unlocked again. @c -1 will be returned if you are trying to unlock - * when there wasn't enough call to ecore_thread_main_loop_begin(). + * @remarks After a call to ecore_thread_main_loop_begin(), you need to absolutely + * call ecore_thread_main_loop_end(), or your application stays frozen. + * + * @return The number of times ecore_thread_main_loop_end() needs to be called before + * the main loop is unlocked again \n + * @c -1 is retured if you are trying to unlock + * when there aren't enough calls to ecore_thread_main_loop_begin(). + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * After a call to ecore_thread_main_loop_begin(), you need to absolutely - * call ecore_thread_main_loop_end(), or you application will stay frozen. */ EAPI int ecore_thread_main_loop_end(void); @@ -526,15 +688,18 @@ EAPI int ecore_thread_main_loop_end(void); */ /** - * @defgroup Ecore_Event_Group Ecore Event functions + * @defgroup Ecore_Event_Group Ecore Event + * @ingroup Ecore_Main_Loop_Group + * + * @brief Ecore event are a helper to create events are being notified of events. * * Ecore events provide two main features that are of use to those using ecore: - * creating events and being notified of events. Those two will usually be used + * creating events and being notified of events. Those two are usually used * in different contexts, creating events is mainly done by libraries wrapping * some system functionality while being notified of events is mainly a * necessity of applications. * - * For a program to be notified of events it's interested in it needs to have a + * For a program to be notified of events it's interested in, it needs to have a * function to process the event and to register that function as the callback * to the event, that's all: * @code @@ -543,53 +708,52 @@ EAPI int ecore_thread_main_loop_end(void); * static Eina_Bool * _my_event_handler(void *data, int type, void *event) * { - * //data is some_data - * //event is provided by whoever created the event - * //Do really cool stuff with event + * //Data is some_data + * //Event is provided by whoever created the event + * //Do really cool stuff with the event * } * @endcode * - * One very important thing to note here is the @c EVENT_TYPE, to register a - * handler for an event you must know its type before hand. Ecore provides - * the following events which are emitted in response to POSIX + * One very important thing to note here is the @c EVENT_TYPE. To register a + * handler for an event, you must know its type before hand. Ecore provides + * the following events that are emitted in response to POSIX * signals(https://en.wikipedia.org/wiki/Signal_%28computing%29): * @li @b ECORE_EVENT_SIGNAL_USER * @li @b ECORE_EVENT_SIGNAL_HUP * @li @b ECORE_EVENT_SIGNAL_POWER * @li @b ECORE_EVENT_SIGNAL_EXIT * - * @warning Don't override these using the @c signal or @c sigaction calls. + * Don't override these using the @c signal or @c sigaction calls. * These, however, aren't the only signals one can handle. Many * libraries(including ecore modules) have their own signals that can be - * listened for and handled, to do that one only needs to know the type of the + * listened to and handled. To do that one only needs to know the type of the * event. This information can be found on the documentation of the library - * emitting the signal, so, for example, for events related to windowing one - * would look in @ref Ecore_Evas_Group. + * emitting the signal. + * @internal + * So, for example, for events related to windowing one + * would use @ref Ecore_Evas_Group. * * Examples of libraries that integrate into ecore's main loop by providing - * events are @ref Ecore_Con_Group, @ref Ecore_Evas_Group and @ref - * Ecore_Exe_Group, amongst others. This usage can be divided into two parts, - * setup and adding events. The setup is very simple, all that needs doing is - * getting a type id for the event: + * events are @ref Ecore_Con_Group, @ref Ecore_Evas_Group, and @ref + * Ecore_Exe_Group, amongst others. + * @endinternal + * + * This usage can be divided into two parts, + * setup and adding events. The setup is very simple, all that needs to be done is + * getting a type ID for the event: * @code * int MY_EV_TYPE = ecore_event_type_new(); * @endcode - * @note This variable should be declared in the header since it'll be needed by + * This variable should be declared in the header since it is needed by * anyone wishing to register a handler to your event. * - * The complexity of adding of an event to the queue depends on whether that - * event sends uses @c event, if it doesn't it a one-liner: + * The complexity of adding an event to the queue depends on whether that + * event sends or uses @a event, if it doesn't it is a one-liner: * @code * ecore_event_add(MY_EV_TYPE, NULL, NULL, NULL); * @endcode - * The usage when an @c event is needed is not that much more complex and can be - * seen in @ref ecore_event_add. - * - * Examples that deals with events: - * @li @ref ecore_event_example_01_c - * @li @ref ecore_event_example_02_c - * - * @ingroup Ecore_Main_Loop_Group + * The usage when an @c event is needed is not that complex and can be + * seen in @ref ecore_event_add. * * @{ */ @@ -602,33 +766,31 @@ EAPI int ecore_thread_main_loop_end(void); #define ECORE_EVENT_SIGNAL_REALTIME 5 /**< Realtime signal event */ #define ECORE_EVENT_COUNT 6 -typedef struct _Ecore_Win32_Handler Ecore_Win32_Handler; /**< A handle for HANDLE handlers on Windows */ -typedef struct _Ecore_Event_Handler Ecore_Event_Handler; /**< A handle for an event handler */ -typedef struct _Ecore_Event_Filter Ecore_Event_Filter; /**< A handle for an event filter */ -typedef struct _Ecore_Event Ecore_Event; /**< A handle for an event */ -typedef struct _Ecore_Event_Signal_User Ecore_Event_Signal_User; /**< User signal event */ -typedef struct _Ecore_Event_Signal_Hup Ecore_Event_Signal_Hup; /**< Hup signal event */ -typedef struct _Ecore_Event_Signal_Exit Ecore_Event_Signal_Exit; /**< Exit signal event */ -typedef struct _Ecore_Event_Signal_Power Ecore_Event_Signal_Power; /**< Power signal event */ -typedef struct _Ecore_Event_Signal_Realtime Ecore_Event_Signal_Realtime; /**< Realtime signal event */ +typedef struct _Ecore_Win32_Handler Ecore_Win32_Handler; /**< @internal @brief A handle for HANDLE handlers on Windows */ +typedef struct _Ecore_Event_Handler Ecore_Event_Handler; /**< @brief A handle for an event handler */ +typedef struct _Ecore_Event_Filter Ecore_Event_Filter; /**< @brief A handle for an event filter */ +typedef struct _Ecore_Event Ecore_Event; /**< @brief A handle for an event */ +typedef struct _Ecore_Event_Signal_User Ecore_Event_Signal_User; /**< @brief User signal event */ +typedef struct _Ecore_Event_Signal_Hup Ecore_Event_Signal_Hup; /**< @brief Hup signal event */ +typedef struct _Ecore_Event_Signal_Exit Ecore_Event_Signal_Exit; /**< @brief Exit signal event */ +typedef struct _Ecore_Event_Signal_Power Ecore_Event_Signal_Power; /**< @brief Power signal event */ +typedef struct _Ecore_Event_Signal_Realtime Ecore_Event_Signal_Realtime; /**< @brief Realtime signal event */ /** * @typedef Ecore_Filter_Cb - * A callback used for filtering events from the main loop. + * @brief The boolean type for a callback used for filtering events from the main loop. */ typedef Eina_Bool (*Ecore_Filter_Cb)(void *data, void *loop_data, int type, void *event); /** * @typedef Ecore_End_Cb Ecore_End_Cb - * This is the callback which is called at the end of a function, - * usually for cleanup purposes. + * @brief Called at the end of a function, usually for cleanup purposes. */ typedef void (*Ecore_End_Cb)(void *user_data, void *func_data); /** * @typedef Ecore_Event_Handler_Cb Ecore_Event_Handler_Cb - * A callback used by the main loop to handle events of a specified - * type. + * @brief The boolean type used by the main loop to handle events of a specified type. */ typedef Eina_Bool (*Ecore_Event_Handler_Cb)(void *data, int type, void *event); @@ -653,9 +815,9 @@ struct _Ecore_Event_Signal_Hup /** Hup signal event */ struct _Ecore_Event_Signal_Exit /** Exit request event */ { - Eina_Bool interrupt : 1; /**< Set if the exit request was an interrupt signal*/ - Eina_Bool quit : 1; /**< set if the exit request was a quit signal */ - Eina_Bool terminate : 1; /**< Set if the exit request was a terminate signal */ + Eina_Bool interrupt : 1; /**< Set if the exit request is an interrupt signal*/ + Eina_Bool quit : 1; /**< Set if the exit request is a quit signal */ + Eina_Bool terminate : 1; /**< Set if the exit request is a terminate signal */ void *ext_data; /**< Extension data - not used */ #if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) @@ -682,155 +844,224 @@ struct _Ecore_Event_Signal_Realtime /** Realtime event */ }; /** - * @brief Add an event handler. - * @param type The type of the event this handler will get called for - * @param func The function to call when the event is found in the queue - * @param data A data pointer to pass to the called function @p func - * @return A new Event handler, or @c NULL on failure. - * - * Add an event handler to the list of handlers. This will, on success, return - * a handle to the event handler object that was created, that can be used - * later to remove the handler using ecore_event_handler_del(). The @p type - * parameter is the integer of the event type that will trigger this callback - * to be called. The callback @p func is called when this event is processed - * and will be passed the event type, a pointer to the private event - * structure that is specific to that event type, and a data pointer that is - * provided in this call as the @p data parameter. - * - * When the callback @p func is called, it must return 1 or 0. If it returns - * 1 (or ECORE_CALLBACK_PASS_ON), It will keep being called as per normal, for - * each handler set up for that event type. If it returns 0 (or - * ECORE_CALLBACK_DONE), it will cease processing handlers for that particular - * event, so all handler set to handle that event type that have not already - * been called, will not be. + * @brief Adds an event handler. + * + * @details This adds an event handler to the list of handlers. This, on success, returns + * a handle to the event handler object that is created, that can be used + * later to remove the handler using ecore_event_handler_del(). The @a type + * parameter is the integer of the event type that triggers this callback + * to be called. The callback @a func is called when this event is processed + * and is passed the event type, a pointer to the private event + * structure that is specific to that event type, and a data pointer that is + * provided in this call as the @a data parameter. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks When the callback @a func is called, it must return @c 1 or @c 0. If it returns + * @c 1 (or @c ECORE_CALLBACK_PASS_ON), it keeps being called as per normal, for + * each handler set up for that event type. If it returns @c 0 (or + * @c ECORE_CALLBACK_DONE), it ceases processing handlers for that particular + * event, so all handlers set to handle that event type that have not already + * been called, are not called. + * + * @param[in] type The type of the event that this handler gets called for + * @param[in] func The function to call when the event is found in the queue + * @param[in] data A data pointer to pass to the called function @a func + * @return A new Event handler, + * otherwise @c NULL on failure */ EAPI Ecore_Event_Handler *ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data); + /** - * @brief Delete an event handler. - * @param event_handler Event handler handle to delete - * @return Data passed to handler + * @brief Deletes an event handler. + * + * @details This deletes a specified event handler from the handler list. On success, this + * deletes the event handler and returns the pointer passed as @a data when the + * handler is added by ecore_event_handler_add(). On failure, @c NULL is + * returned. Once a handler is deleted it is no longer called. * - * Delete a specified event handler from the handler list. On success this will - * delete the event handler and return the pointer passed as @p data when the - * handler was added by ecore_event_handler_add(). On failure @c NULL will be - * returned. Once a handler is deleted it will no longer be called. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] event_handler The event handler handle to delete + * @return The data passed to the handler */ EAPI void *ecore_event_handler_del(Ecore_Event_Handler *event_handler); + /** - * @brief Add an event to the event queue. - * @param type The event type to add to the end of the event queue - * @param ev The data structure passed as @c event to event handlers - * @param func_free The function to be called to free @a ev - * @param data The data pointer to be passed to the free function - * @return A Handle for that event on success, otherwise NULL + * @brief Adds an event to the event queue. * - * If it succeeds, an event of type @a type will be added to the queue for - * processing by event handlers added by ecore_event_handler_add(). The @a ev - * parameter will be passed as the @c event parameter of the handler. When the - * event is no longer needed, @a func_free will be called and passed @a ev for - * cleaning up. If @p func_free is NULL, free() will be called with the private - * structure pointer. + * @remarks If it succeeds, an event of type @a type is added to the queue for + * processing by event handlers added by ecore_event_handler_add(). The @a ev + * parameter is passed as the @a event parameter of the handler. When the + * event is no longer needed, @a func_free is called and it passes @a ev for + * cleaning up. If @a func_free is @c NULL, free() is called with the private + * structure pointer. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] type The event type to add to the end of the event queue + * @param[in] ev The data structure passed as @a event to event handlers + * @param[in] func_free The function to be called to free @a ev + * @param[in] data The data pointer to be passed to the free function + * @return A Handle for that event on success, + * otherwise @c NULL on failure */ EAPI Ecore_Event *ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data); + /** - * @brief Delete an event from the queue. - * @param event The event handle to delete - * @return The data pointer originally set for the event free function + * @brief Deletes an event from the queue. * - * This deletes the event @p event from the event queue, and returns the - * @p data parameter originally set when adding it with ecore_event_add(). This - * does not immediately call the free function, and it may be called later on - * cleanup, and so if the free function depends on the data pointer to work, - * you should defer cleaning of this till the free function is called later. + * @details This deletes the event @a event from the event queue, and returns the + * @a data parameter originally set when adding it using ecore_event_add(). This + * does not immediately call the free function, and it may be called later for + * cleanup, and so if the free function depends on the data pointer to work, + * you should defer cleaning of this till the free function is called later. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] event The event handle to delete + * @return The data pointer originally set for the event free function */ EAPI void *ecore_event_del(Ecore_Event *event); + /** - * @brief Get the data associated with an #Ecore_Event_Handler - * @param eh The event handler - * @return The data + * @brief Gets the data associated with an #Ecore_Event_Handler. + * + * @details This function returns the data previously associated with @a eh by + * ecore_event_handler_add(). * - * This function returns the data previously associated with @p eh by - * ecore_event_handler_add(). + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] eh The event handler + * @return The data */ EAPI void *ecore_event_handler_data_get(Ecore_Event_Handler *eh); + /** - * @brief Set the data associated with an #Ecore_Event_Handler - * @param eh The event handler - * @param data The data to associate - * @return The previous data + * @brief Sets the data associated with an #Ecore_Event_Handler. + * + * @details This function sets @a data to @a eh and returns the old data pointer + * that had been previously associated with @a eh by ecore_event_handler_add(). + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * This function sets @p data to @p eh and returns the old data pointer - * which was previously associated with @p eh by ecore_event_handler_add(). + * @param[in] eh The event handler + * @param[in] data The data to associate + * @return The previous data */ EAPI void *ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *data); + /** - * @brief Allocate a new event type id sensibly and return the new id. - * @return A new event type id. + * @brief Allocates a new event type ID sensibly and returns the new ID. + * + * @details This function allocates a new event type ID and returns it. Once an event + * type has been allocated it can never be de-allocated during the life of + * the program. There is no guarantee of the contents of this event ID, or how + * it is calculated, except that the ID is unique to the current instance + * of the process. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @return A new event type ID * - * This function allocates a new event type id and returns it. Once an event - * type has been allocated it can never be de-allocated during the life of - * the program. There is no guarantee of the contents of this event ID, or how - * it is calculated, except that the ID will be unique to the current instance - * of the process. */ EAPI int ecore_event_type_new(void); + /** - * @brief Add a filter the current event queue. - * - * @param func_start Function to call just before filtering and return data - * @param func_filter Function to call on each event - * @param func_end Function to call after the queue has been filtered - * @param data Data to pass to the filter functions - * @return A filter handle on success, @c NULL otherwise. - * - * Adds a callback to filter events from the event queue. Filters are called on - * the queue just before Event handler processing to try and remove redundant - * events. Just as processing is about to start @a func_start is called and - * passed the @a data pointer, the return value of this functions is passed to - * @a func_filter as loop_data. @a func_filter is also passed @a data and the - * event type and event structure. If this @a func_filter returns - * @c EINA_FALSE, the event is removed from the queue, if it returns - * @c EINA_TRUE, the event is kept. When processing is finished @p func_end is - * called and is passed the loop_data(returned by @c func_start) and @p data - * pointer to clean up. + * @brief Adds a filter to the current event queue. + * + * @details This adds a callback to filter events from the event queue. Filters are called on + * the queue just before Event handler processing to try and remove redundant + * events. Just when processing is about to start @a func_start is called and + * passed the @a data pointer. The return value of this function is passed to + * @a func_filter as loop_data. @a func_filter is also passed @a data, the + * event type, and the event structure. If this @a func_filter returns + * @c EINA_FALSE, the event is removed from the queue. If it returns + * #EINA_TRUE, the event is kept. When processing is finished @a func_end is + * called and is passed the loop_data(returned by @a func_start) and @a data + * pointer to clean up. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] func_start The function to call just before filtering and returning data + * @param[in] func_filter The function to call on each event + * @param[in] func_end The function to call after the queue has been filtered + * @param[in] data The data to pass to the filter functions + * @return A filter handle on success, + * otherwise @c NULL on failure + * */ EAPI Ecore_Event_Filter *ecore_event_filter_add(Ecore_Data_Cb func_start, Ecore_Filter_Cb func_filter, Ecore_End_Cb func_end, const void *data); + /** - * @brief Delete an event filter. - * @param ef The event filter handle - * @return The data set for the filter on success, @c NULL otherwise. + * @brief Deletes an event filter. + * + * @details This deletes a filter that has been added by its @a ef handle. * - * Delete a filter that has been added by its @p ef handle. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] ef The event filter handle + * @return The data set for the filter on success, + * otherwise @c NULL */ EAPI void *ecore_event_filter_del(Ecore_Event_Filter *ef); + /** - * @brief Return the current event type being handled. - * @return The current event type being handled if inside a handler callback, - * ECORE_EVENT_NONE otherwise + * @brief Returns the current event type being handled. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * If the program is currently inside an Ecore event handler callback this - * will return the type of the current event being processed. + * @remarks If the program is currently inside an Ecore event handler callback this + * returns the type of the current event being processed. * - * This is useful when certain Ecore modules such as Ecore_Evas "swallow" - * events and not all the original information is passed on. In special cases - * this extra information may be useful or needed and using this call can let - * the program know if the event type being handled is one it wants to get more - * information about. + * This is useful when certain Ecore modules such as Ecore_Evas "swallow" + * events and not all the original information is passed on. In special cases, + * this extra information may be useful or needed and using this call can let + * the program know if the event type being handled is the one about which it wants to get more + * information. + * + * @return The current event type being handled if inside a handler callback, + * otherwise @c ECORE_EVENT_NONE */ EAPI int ecore_event_current_type_get(void); /** - * @brief Return the current event type pointer handled. - * @return The current event pointer being handled if inside a handler callback, - * @c NULL otherwise. + * @brief Returns the current event type pointer handled. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * If the program is currently inside an Ecore event handler callback this - * will return the pointer of the current event being processed. + * @remarks If the program is currently inside an Ecore event handler callback this + * returns the pointer of the current event being processed. * - * This is useful when certain Ecore modules such as Ecore_Evas "swallow" - * events and not all the original information is passed on. In special cases - * this extra information may be useful or needed and using this call can let - * the program access the event data if the type of the event is handled by - * the program. + * @remarks This is useful when certain Ecore modules such as Ecore_Evas "swallow" + * events and not all the original information is passed on. In special cases, + * this extra information may be useful or needed and using this call can let + * the program access the event data if the type of the event is handled by + * the program. + * + * @return The current event pointer being handled if inside a handler callback, + * otherwise @c NULL */ EAPI void *ecore_event_current_event_get(void); @@ -839,53 +1070,52 @@ EAPI void *ecore_event_current_event_get(void); */ /** - * @defgroup Ecore_Exe_Group Process Spawning Functions + * @internal + * @defgroup Ecore_Exe_Group Process Spawning + * @ingroup Ecore_Main_Loop_Group * * This module is responsible for managing portable processes using Ecore. - * With this module you're able to spawn processes and you also can pause, + * With this module you're able to spawn processes and you can also pause and * quit your spawned processes. * An interaction between your process and those spawned is possible * using pipes or signals. * - * Example - * @li @ref Ecore_exe_simple_example_c - * - * @ingroup Ecore_Main_Loop_Group - * * @{ */ -/** Inherit priority from parent process */ +/** Inherit priority from the parent process */ #define ECORE_EXE_PRIORITY_INHERIT 9999 -EAPI extern int ECORE_EXE_EVENT_ADD; /**< A child process has been added */ -EAPI extern int ECORE_EXE_EVENT_DEL; /**< A child process has been deleted (it exited, naming consistent with the rest of ecore). */ -EAPI extern int ECORE_EXE_EVENT_DATA; /**< Data from a child process. */ -EAPI extern int ECORE_EXE_EVENT_ERROR; /**< Errors from a child process. */ +EAPI extern int ECORE_EXE_EVENT_ADD; /**< @brief A child process has been added */ +EAPI extern int ECORE_EXE_EVENT_DEL; /**< @brief A child process has been deleted (it exited, naming is consistent with the rest of ecore) */ +EAPI extern int ECORE_EXE_EVENT_DATA; /**< @brief Data from a child process */ +EAPI extern int ECORE_EXE_EVENT_ERROR; /**< @brief Errors from a child process */ /** + * @internal * @enum _Ecore_Exe_Flags - * Flags for executing a child with its stdin and/or stdout piped back. + * @brief Enumeration that defines the flags for executing a child with its stdin and/or stdout piped back. */ -enum _Ecore_Exe_Flags /* flags for executing a child with its stdin and/or stdout piped back */ +enum _Ecore_Exe_Flags /* Flags for executing a child with its stdin and/or stdout piped back */ { ECORE_EXE_NONE = 0, /**< No exe flags at all */ ECORE_EXE_PIPE_READ = 1, /**< Exe Pipe Read mask */ ECORE_EXE_PIPE_WRITE = 2, /**< Exe Pipe Write mask */ ECORE_EXE_PIPE_ERROR = 4, /**< Exe Pipe error mask */ - ECORE_EXE_PIPE_READ_LINE_BUFFERED = 8, /**< Reads are buffered until a newline and split 1 line per Ecore_Exe_Event_Data_Line */ - ECORE_EXE_PIPE_ERROR_LINE_BUFFERED = 16, /**< Errors are buffered until a newline and split 1 line per Ecore_Exe_Event_Data_Line */ + ECORE_EXE_PIPE_READ_LINE_BUFFERED = 8, /**< Reads are buffered till a new line and 1 line is split per Ecore_Exe_Event_Data_Line */ + ECORE_EXE_PIPE_ERROR_LINE_BUFFERED = 16, /**< Errors are buffered till a new line and 1 line is split per Ecore_Exe_Event_Data_Line */ ECORE_EXE_PIPE_AUTO = 32, /**< stdout and stderr are buffered automatically */ ECORE_EXE_RESPAWN = 64, /**< FIXME: Exe is restarted if it dies */ - ECORE_EXE_USE_SH = 128, /**< Use /bin/sh to run the command. */ - ECORE_EXE_NOT_LEADER = 256, /**< Do not use setsid() to have the executed process be its own session leader */ - ECORE_EXE_TERM_WITH_PARENT = 512 /**< Makes child receive SIGTERM when parent dies. */ + ECORE_EXE_USE_SH = 128, /**< Use /bin/sh to run the command */ + ECORE_EXE_NOT_LEADER = 256, /**< Do not use setsid() to make the executed process its own session leader */ + ECORE_EXE_TERM_WITH_PARENT = 512 /**< Makes a child receive SIGTERM when the parent dies */ }; typedef enum _Ecore_Exe_Flags Ecore_Exe_Flags; /** + * @internal * @enum _Ecore_Exe_Win32_Priority - * Defines the priority of the proccess. + * @brief Enumeration that defines the priority of the proccess. */ enum _Ecore_Exe_Win32_Priority { @@ -893,25 +1123,29 @@ enum _Ecore_Exe_Win32_Priority ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL, /**< Below default priority */ ECORE_EXE_WIN32_PRIORITY_NORMAL, /**< Default priority */ ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL, /**< Above default priority */ - ECORE_EXE_WIN32_PRIORITY_HIGH, /**< High priority, use with care as other threads in the system will not get processor time */ + ECORE_EXE_WIN32_PRIORITY_HIGH, /**< High priority, use with care as other threads in the system do not get processor time */ ECORE_EXE_WIN32_PRIORITY_REALTIME /**< Realtime priority, should be almost never used as it can interrupt system threads that manage mouse input, keyboard input, and background disk flushing */ }; typedef enum _Ecore_Exe_Win32_Priority Ecore_Exe_Win32_Priority; -typedef struct _Ecore_Exe Ecore_Exe; /**< A handle for spawned processes */ +typedef struct _Ecore_Exe Ecore_Exe; /**< @brief A handle for spawned processes */ /** * @typedef Ecore_Exe_Cb Ecore_Exe_Cb - * A callback to run with the associated @ref Ecore_Exe, usually - * for cleanup purposes. + * @brief Called to run with the associated @ref Ecore_Exe, usually + * for cleanup purposes. */ typedef void (*Ecore_Exe_Cb)(void *data, const Ecore_Exe *exe); -typedef struct _Ecore_Exe_Event_Add Ecore_Exe_Event_Add; /**< Spawned Exe add event */ -typedef struct _Ecore_Exe_Event_Del Ecore_Exe_Event_Del; /**< Spawned Exe exit event */ -typedef struct _Ecore_Exe_Event_Data_Line Ecore_Exe_Event_Data_Line; /**< Lines from a child process */ -typedef struct _Ecore_Exe_Event_Data Ecore_Exe_Event_Data; /**< Data from a child process */ +typedef struct _Ecore_Exe_Event_Add Ecore_Exe_Event_Add; /**< @brief Spawned Exe add event */ +typedef struct _Ecore_Exe_Event_Del Ecore_Exe_Event_Del; /**< @brief Spawned Exe exit event */ +typedef struct _Ecore_Exe_Event_Data_Line Ecore_Exe_Event_Data_Line; /**< @brief Lines from a child process */ +typedef struct _Ecore_Exe_Event_Data Ecore_Exe_Event_Data; /**< @brief Data from a child process */ +/** +* @internal +* @brief Structure of Ecore Exe Event Add +*/ struct _Ecore_Exe_Event_Add /** Process add event */ { Ecore_Exe *exe; /**< The handle to the added process */ @@ -922,10 +1156,10 @@ struct _Ecore_Exe_Event_Del /** Process exit event */ { pid_t pid; /**< The process ID of the process that exited */ int exit_code; /**< The exit code of the process */ - Ecore_Exe *exe; /**< The handle to the exited process, or @c NULL if not found */ + Ecore_Exe *exe; /**< The handle to the exited process, otherwise @c NULL if not found */ int exit_signal; /** < The signal that caused the process to exit */ - Eina_Bool exited : 1; /** < set to 1 if the process exited of its own accord */ - Eina_Bool signalled : 1; /** < set to 1 id the process exited due to uncaught signal */ + Eina_Bool exited : 1; /** < Set to @c 1 if the process exited on its own */ + Eina_Bool signalled : 1; /** < Set to @c 1 if the process exited due to an uncaught signal */ void *ext_data; /**< Extension data - not used */ #if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) siginfo_t data; /**< Signal info */ @@ -941,9 +1175,9 @@ struct _Ecore_Exe_Event_Data_Line /**< Lines from a child process */ struct _Ecore_Exe_Event_Data /** Data from a child process event */ { Ecore_Exe *exe; /**< The handle to the process */ - void *data; /**< the raw binary data from the child process that was received */ - int size; /**< the size of this data in bytes */ - Ecore_Exe_Event_Data_Line *lines; /**< an array of line data if line buffered, the last one has it's line member set to @c NULL */ + void *data; /**< The raw binary data from the child process that is received */ + int size; /**< The size of this data in bytes */ + Ecore_Exe_Event_Data_Line *lines; /**< An array of line data if line buffered, the last one has its line member set to @c NULL */ }; EAPI void ecore_exe_run_priority_set(int pri); @@ -978,16 +1212,20 @@ EAPI void ecore_exe_hup(Ecore_Exe *exe); */ /** - * @defgroup Ecore_FD_Handler_Group File Descriptor Handling Functions + * @defgroup Ecore_FD_Handler_Group Ecore File Descriptor Handling + * @ingroup Ecore_Main_Loop_Group * - * @brief Functions that deal with file descriptor handlers. + * @brief This group discusses functions that deal with file descriptor handlers. * - * File descriptor handlers facilitate reading, writing and checking for errors + * File descriptor handlers facilitate reading, writing, and checking for errors * without blocking the program or doing expensive pooling. This can be used to - * monitor a socket, pipe, or other stream for which an FD can be had. + * monitor a socket, pipe, or some other stream for which an FD can be present. * - * @warning File descriptor handlers can't be used to monitor for file creation, - * modification or deletion, see @ref Ecore_File_Group for this. + * File descriptor handlers can't be used to monitor file creation, + * modification, or deletion, + * @internal + * see @ref Ecore_File_Group for this. + * @endinternal * * One common FD to be monitored is the standard input(stdin), monitoring it for * reading requires a single call: @@ -1002,143 +1240,222 @@ EAPI void ecore_exe_hup(Ecore_Exe *exe); * ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ, _my_cb_func, NULL, NULL, NULL); * @endcode * - * When using a socket, pipe or other stream it's important to remember that - * errors may occur and as such to monitor not only for reading/writing but also + * When using a socket, pipe, or some other stream it's important to remember that + * errors may occur and we must monitor not only for reading/writing, but also * for errors using the @ref ECORE_FD_ERROR flag. * - * Example of use of a file descriptor handler: - * @li @ref ecore_fd_handler_example_c - * - * @ingroup Ecore_Main_Loop_Group - * * @{ */ -typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler; /**< A handle for Fd handlers */ +/** + * @brief typedef to struct _Ecore_Fd_Handler + */ +typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler; /**< A handle for FD handlers */ /** * @enum _Ecore_Fd_Handler_Flags - * What to monitor the file descriptor for: reading, writing or error. + * @brief Enumeration that defines the handler flags to monitor the file descriptor for: reading, writing, or error. */ enum _Ecore_Fd_Handler_Flags { - ECORE_FD_READ = 1, /**< Fd Read mask */ - ECORE_FD_WRITE = 2, /**< Fd Write mask */ - ECORE_FD_ERROR = 4 /**< Fd Error mask */ + ECORE_FD_READ = 1, /**< FD Read mask */ + ECORE_FD_WRITE = 2, /**< FD Write mask */ + ECORE_FD_ERROR = 4 /**< FD Error mask */ }; + +/** + * @brief typedef to enum _Ecore_Fd_Handler_Flags + */ typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags; /** * @typedef Ecore_Fd_Cb Ecore_Fd_Cb - * A callback used by an @ref Ecore_Fd_Handler. + * @brief The boolean type for a callback used by an @ref Ecore_Fd_Handler. */ typedef Eina_Bool (*Ecore_Fd_Cb)(void *data, Ecore_Fd_Handler *fd_handler); /** * @typedef Ecore_Fd_Prep_Cb Ecore_Fd_Prep_Cb - * A callback used by an @ref Ecore_Fd_Handler. + * @brief Called to be used by an @ref Ecore_Fd_Handler. */ typedef void (*Ecore_Fd_Prep_Cb)(void *data, Ecore_Fd_Handler *fd_handler); /** + * @internal * @typedef Ecore_Win32_Handle_Cb Ecore_Win32_Handle_Cb - * A callback used by an @ref Ecore_Win32_Handler. + * @brief The boolean type for a callback used by an @ref Ecore_Win32_Handler. */ typedef Eina_Bool (*Ecore_Win32_Handle_Cb)(void *data, Ecore_Win32_Handler *wh); /** * @brief Adds a callback for activity on the given file descriptor. * - * @param fd The file descriptor to watch. - * @param flags To monitor it for reading use @c ECORE_FD_READ, for writing @c - * ECORE_FD_WRITE, and for error @c ECORE_FD_ERROR. Values by |(ored). - * @param func The callback function. - * @param data The data to pass to the callback. - * @param buf_func The function to call to check if any data has been buffered - * and already read from the fd. May be @c NULL. - * @param buf_data The data to pass to the @p buf_func function. - * @return A fd handler handle on success, @c NULL otherwise. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @a func will be called during the execution of @ref Ecore_Main_Loop_Page - * when the file descriptor is available for reading, writing, or there has been - * an error(depending on the given @a flags). + * @remarks @a func is called during the execution of @ref Ecore_Main_Loop_Page + * when the file descriptor is available for reading, writing, or there has been + * an error(depending on the given @a flags). * - * When @a func returns ECORE_CALLBACK_CANCEL, it indicates that the - * handler should be marked for deletion (identical to calling @ref - * ecore_main_fd_handler_del). + * @remarks When @a func returns @c ECORE_CALLBACK_CANCEL, it indicates that the + * handler should be marked for deletion (identical to calling @ref + * ecore_main_fd_handler_del). * - * @warning @a buf_func is meant for @b internal use only and should be @b - * avoided. + * @remarks @a buf_func is meant for @b internal use only and should be @b + * avoided. * - * The return value of @a buf_func has a different meaning, when it returns - * ECORE_CALLBACK_CANCEL, it indicates that @a func @b shouldn't be called, and - * when it returns ECORE_CALLBACK_RENEW it indicates @a func should be called. - * The return value of @a buf_func will not cause the FD handler to be deleted. + * @remarks The return value of @a buf_func has a different meaning, when it returns + * @c ECORE_CALLBACK_CANCEL, it indicates that @a func @b shouldn't be called, and + * when it returns @c ECORE_CALLBACK_RENEW it indicates @a func should be called. + * The return value of @a buf_func does not cause the FD handler to get deleted. * - * @a buf_func is called during event loop handling to check if data that has - * been read from the file descriptor is in a buffer and is available to read. - * Some systems, notably xlib, handle their own buffering, and would otherwise - * not work with select(). These systems should use a @a buf_func. This is a - * most annoying hack, only ecore_x uses it, so refer to that for an example. + * @remarks @a buf_func is called during event loop handling to check if data that has + * been read from the file descriptor is in a buffer and is available to read. + * Some systems, notably xlib, handle their own buffering, and would otherwise + * not work with select(). These systems should use a @a buf_func. This is the + * most annoying hack, only ecore_x uses it, so refer to that for an example. * - * @warning This function should @b not be used for monitoring "normal" files, like text files. + * @remarks This function should @b not be used for monitoring "normal" files, like text files. + * + * @param[in] fd The file descriptor to watch + * @param[in] flags The flags to monitor it, for reading use @c ECORE_FD_READ, for writing use @c + * ECORE_FD_WRITE, and for error use @c ECORE_FD_ERROR \n + * Values by |(ored). + * @param[in] func The callback function + * @param[in] data The data to pass to the callback + * @param[in] buf_func The function to call to check if any data has been buffered + * and already read from the fd \n + * May be @c NULL. + * @param[in] buf_data The data to pass to the @a buf_func function + * @return An fd handler handle on success, + * otherwise @c NULL on failure * */ EAPI Ecore_Fd_Handler *ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data, Ecore_Fd_Cb buf_func, const void *buf_data); + /** - * @brief Set the prepare callback with data for a given #Ecore_Fd_Handler + * @brief Adds a callback for activity on the given file descriptor. + * + * @since 1.7 * - * @param fd_handler The fd handler - * @param func The prep function - * @param data The data to pass to the prep function + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * This function will be called prior to any fd handler's callback function - * (even the other fd handlers), before entering the main loop select function. + * @remarks This function is identical to ecore_main_fd_handler_add, except that it supports regular files. * - * @note Once a prepare callback is set for a fd handler, it cannot be changed. - * You need to delete the fd handler and create a new one, to set another - * callback. - * @note You probably don't need this function. It is only necessary for very - * uncommon cases that need special behavior. + * @remarks This function should ONLY be called with @c ECORE_FD_ERROR, otherwise it calls the fd + * handler constantly. + * @remarks Do not use this function unless you know what you are doing. + * + * @param[in] fd The file descriptor to watch + * @param[in] flags The flags to monitor it, for reading use @c ECORE_FD_READ, for writing use @c + * ECORE_FD_WRITE, and for error use @c ECORE_FD_ERROR \n + * Values by |(ored). + * @param[in] func The callback function + * @param[in] data The data to pass to the callback + * @param[in] buf_func The function to call to check if any data has been buffered + * and already read from the fd \n + * May be @c NULL. + * @param[in] buf_data The data to pass to the @a buf_func function. + * @return An fd handler handle on success, + * otherwise @c NULL on failure */ -EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data); +EAPI Ecore_Fd_Handler *ecore_main_fd_handler_file_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data, Ecore_Fd_Cb buf_func, const void *buf_data); + /** - * @brief Marks an FD handler for deletion. - * @param fd_handler The FD handler. - * @return The data pointer set using @ref ecore_main_fd_handler_add, for - * @a fd_handler on success, @c NULL otherwise. - * This function marks an fd handler to be deleted during an iteration of the - * main loop. It does NOT close the associated fd! + * @brief Sets the prepare callback with data for a given #Ecore_Fd_Handler. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks This function is called prior to any fd handler's callback function + * (even the other fd handlers), before entering the main loop select function. + * + * @remarks Once a prepare callback is set for an fd handler, it cannot be changed. + * You need to delete the fd handler and create a new one, to set another + * callback. * - * @warning If the underlying fd is already closed ecore may complain if the - * main loop is using epoll internally, and also in some rare cases this may - * cause crashes and instability. Remember to delete your fd handlers before the - * fds they listen to are closed. + * @remarks You probably don't need this function. It is only necessary for very + * uncommon cases that need special behavior. + * + * @param[in] fd_handler The fd handler + * @param[in] func The prep function + * @param[in] data The data to pass to the prep function */ -EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); +EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data); + +/** + * @brief Marks an FD handler for deletion. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @details This function marks an fd handler to be deleted during an iteration of the + * main loop. It does NOT close the associated fd. + * + * @remarks If the underlying fd is already closed ecore may complain if the + * main loop is using epoll internally, and also in some rare cases this may + * cause crashes and instability. Remember to delete your fd handlers before the + * fds they listen to are closed. + * + * @param[in] fd_handler The fd handler + * @return The data pointer set using @ref ecore_main_fd_handler_add, for + * @a fd_handler on success, + * otherwise @c NULL on failure + */ +EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); + /** * @brief Retrieves the file descriptor that the given handler is handling. - * @param fd_handler The given FD handler. - * @return The file descriptor the handler is watching. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] fd_handler The given fd handler + * @return The file descriptor that the handler is watching */ EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler); + /** * @brief Gets which flags are active on an FD handler. - * @param fd_handler The given FD handler. - * @param flags The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE or - * @c ECORE_FD_ERROR to query. - * @return @c EINA_TRUE if any of the given flags are active, @c EINA_FALSE - * otherwise. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] fd_handler The given fd handler + * @param[in] flags The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE, or + * @c ECORE_FD_ERROR to query + * @return #EINA_TRUE if any of the given flags are active, + * otherwise @c EINA_FALSE */ EAPI Eina_Bool ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); + /** - * @brief Set what active streams the given FD handler should be monitoring. - * @param fd_handler The given FD handler. - * @param flags The flags to be watching. + * @brief Sets what active streams the given FD handler should be monitoring. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] fd_handler The given fd handler + * @param[in] flags The flags to be watching */ EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); +/** + * @internal + */ EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, Ecore_Win32_Handle_Cb func, const void *data); + +/** + * @internal + */ EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler); /** @@ -1146,521 +1463,1142 @@ EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler); */ /** - * @defgroup Ecore_Poller_Group Ecore Poll functions - * - * Ecore poller provides infrastructure for the creation of pollers. Pollers - * are, in essence, callbacks that share a single timer per type. Because not - * all pollers need to be called at the same frequency the user may specify the - * frequency in ticks(each expiration of the shared timer is called a tick, in - * ecore poller parlance) for each added poller. Ecore pollers should only be - * used when the poller doesn't have specific requirements on the exact times - * to poll. - * - * This architecture means that the main loop is only woken up once to handle - * all pollers of that type, this will save power as the CPU has more of a - * chance to go into a low power state the longer it is asleep for, so this - * should be used in situations where power usage is a concern. - * - * For now only 1 core poller type is supported: ECORE_POLLER_CORE, the default - * interval for ECORE_POLLER_CORE is 0.125(or 1/8th) second. - * - * The creation of a poller is extremely simple and only requires one line: - * @code - * ecore_poller_add(ECORE_POLLER_CORE, 1, my_poller_function, NULL); - * @endcode - * This sample creates a poller to call @c my_poller_function at every tick with - * @c NULL as data. - * - * Example: - * @li @ref ecore_poller_example_c - * + * @defgroup Ecore_Time_Group Ecore Time * @ingroup Ecore_Main_Loop_Group * + * @brief This group discusses the functions to retrieve time in a given format. + * * @{ */ /** - * @enum _Ecore_Poller_Type - * Defines the frequency of ticks for the poller. + * @brief Retrieves the current system time as a floating point value in seconds. + * + * @details This uses a monotonic clock and thus never goes back in time while + * machine is live (even if user changes time or timezone changes, + * however it may be reset whenever the machine is restarted). + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @return The number of seconds. Start time is not defined (it may be + * when the machine was booted, unix time, etc), all it is + * defined is that it never goes backwards (unless you got big critical + * messages when the application started). + * + * @see ecore_loop_time_get(). + * @see ecore_time_unix_get(). */ -enum _Ecore_Poller_Type /* Poller types */ -{ - ECORE_POLLER_CORE = 0 /**< The core poller interval */ -}; -typedef enum _Ecore_Poller_Type Ecore_Poller_Type; - -typedef struct _Ecore_Poller Ecore_Poller; /**< A handle for pollers */ +EAPI double ecore_time_get(void); /** - * @brief Sets the time(in seconds) between ticks for the given poller type. - * @param type The poller type to adjust. - * @param poll_time The time(in seconds) between ticks of the timer. + * @brief Retrieves the current UNIX time as a floating point value in seconds. * - * This will adjust the time between ticks of the given timer type defined by - * @p type to the time period defined by @p poll_time. - */ -EAPI void ecore_poller_poll_interval_set(Ecore_Poller_Type type, double poll_time); -/** - * @brief Gets the time(in seconds) between ticks for the given poller type. - * @param type The poller type to query. - * @return The time in seconds between ticks of the poller timer. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * This will get the time between ticks of the specified poller timer. - */ -EAPI double ecore_poller_poll_interval_get(Ecore_Poller_Type type); -/** - * @brief Changes the polling interval rate of @p poller. - * @param poller The Ecore_Poller to change the interval of. - * @param interval The tick interval to set; must be a power of 2 and <= 32768. - * @return Returns true on success, false on failure. + * @return The number of seconds since 12.00AM 1st January 1970. * - * This allows the changing of a poller's polling interval. It is useful when - * you want to alter a poll rate without deleting and re-creating a poller. + * @see ecore_time_get(). + * @see ecore_loop_time_get(). */ -EAPI Eina_Bool ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval); +EAPI double ecore_time_unix_get(void); + /** - * @brief Gets the polling interval rate of @p poller. - * @param poller The Ecore_Poller to change the interval of. - * @return Returns the interval, in ticks, that @p poller polls at. + * @brief Retrieves the time at which the last loop stopped waiting for + * timeouts or events. * - * This returns a poller's polling interval, or 0 on error. - */ -EAPI int ecore_poller_poller_interval_get(Ecore_Poller *poller); -/** - * @brief Creates a poller to call the given function at a particular tick interval. - * @param type The ticker type to attach the poller to. Must be ECORE_POLLER_CORE. - * @param interval The poll interval. - * @param func The poller function. - * @param data Data to pass to @a func when it is called. - * @return A poller object on success, @c NULL otherwise. - * - * This function adds @a func as a poller callback that will be called every @a - * interval ticks together with other pollers of type @a type. @a func will be - * passed the @p data pointer as a parameter. - * - * The @p interval must be between 1 and 32768 inclusive, and must be a power of - * 2 (i.e. 1, 2, 4, 8, 16, ... 16384, 32768). The exact tick in which @a func - * will be called is undefined, as only the interval between calls can be - * defined. Ecore will endeavor to keep pollers synchronized and to call as - * many in 1 wakeup event as possible. If @a interval is not a power of two, the - * closest power of 2 greater than @a interval will be used. - * - * When the poller @p func is called, it must return a value of either - * ECORE_CALLBACK_RENEW(or 1) or ECORE_CALLBACK_CANCEL(or 0). If it - * returns 1, it will be called again at the next tick, or if it returns - * 0 it will be deleted automatically making any references/handles for it - * invalid. - */ -EAPI Ecore_Poller *ecore_poller_add(Ecore_Poller_Type type, int interval, Ecore_Task_Cb func, const void *data); -/** - * @brief Delete the specified poller from the timer list. - * @param poller The poller to delete. - * @return The data pointer set for the timer when @ref ecore_poller_add was - * called on success, @c NULL otherwise. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @note @a poller must be a valid handle. If the poller function has already - * returned 0, the handle is no longer valid (and does not need to be deleted). + * @remarks This gets the time that the main loop ceased waiting for timouts + * and/or events to come in or for signals or any other interrupt + * source. This should be considered a reference point for all time + * based activity that should calculate its timepoint from the return + * of ecore_loop_time_get(). Use this UNLESS you absolutely must get + * the current actual timepoint - then use ecore_time_get(). + * Note that this time is meant to be used as relative to other times + * obtained on this run. If you need absolute time references, use + * ecore_time_unix_get() instead. + * + * @remarks This function can be called before any loop has ever been run, but + * ecore_time_get() must have been called once. + * + * @return The number of seconds. Start time is not defined (it may be + * when the machine was booted, unix time, etc), all it is + * defined is that it never goes backwards (unless you got big critical + * messages when the application started). */ -EAPI void *ecore_poller_del(Ecore_Poller *poller); +EAPI double ecore_loop_time_get(void); /** * @} */ /** - * @defgroup Ecore_Animator_Group Ecore Animator functions + * @defgroup Ecore_Thread_Group Ecore Thread + * @ingroup Ecore_Main_Loop_Group * - * @brief Ecore animators are a helper to simplify creating - * animations. + * @brief Facilities to run heavy tasks in different threads to avoid blocking + * the main loop. * - * Creating an animation is as simple as saying for how long it - * should be run and having a callback that does the animation, - * something like this: - * @code - * static Eina_Bool - * _do_animation(void *data, double pos) - * { - * evas_object_move(data, 100 * pos, 100 * pos); - * ... do some more animating ... - * } - * ... - *ecore_animator_timeline_add(2, _do_animation, my_evas_object); - * @endcode - * In the sample above we create an animation to move - * @c my_evas_object from position (0,0) to (100,100) in 2 seconds. + * The EFL is, for the most part, not thread safe. This means that if you + * have some task running in another thread and you have, for example, an + * Evas object to show the status progress of this task, you cannot update + * the object from within the thread. This can only be done from the main + * thread, the one running the main loop. This problem can be solved + * by running a thread that sends messages to the main one using an + * @ref Ecore_Pipe_Group "Ecore_Pipe", but when you need to handle other + * things like cancelling the thread, your code grows in complexity and gets + * much harder to maintain. * - * If your animation will run for an unspecified amount of time you - * can use ecore_animator_add(), which is like using - *ecore_timer_add() with the interval being the - * @ref ecore_animator_frametime_set "framerate". Note that this has - * tangible benefits to creating a timer for each animation in terms - * of performance. + * Ecore Thread is here to solve that problem. It is not a simple wrapper + * around standard POSIX threads (or an equivalent in other systems) and + * it's not meant to be used to run parallel tasks throughout the entire + * duration of the program, especially when these tasks are performance + * critical, as Ecore manages these tasks using a pool of threads based on + * system configuration. * - * For a more detailed example that show several animation see - * @ref tutorial_ecore_animator. + * What Ecore Thread does is it makes it a lot easier to dispatch a worker + * function to perform some heavy tasks and then get the result once it + * completes, without blocking the application's UI. In addition, cancelling + * and rescheduling comes practically for free and the developer need not + * worry about how many threads are launched, since Ecore schedules + * them according to the number of processors the system has and the maximum + * amount of concurrent threads set for the application. * - * @ingroup Ecore_Main_Loop_Group + * At the system level, Ecore starts a new thread on an as-needed basis + * until the maximum set is reached. When no more threads can be launched, + * new worker functions are queued in a waiting list until a thread + * becomes available. This way, system threads are shared throughout + * different worker functions, but running only one at a time. At the same + * time, a worker function that is rescheduled may be run on a different + * thread the next time. + * + * The ::Ecore_Thread handler has two meanings, depending on what context + * it is on. The one returned when starting a worker with any of the + * functions ecore_thread_run() or ecore_thread_feedback_run() is an + * identifier of that specific instance of the function and can be used from + * the main loop with the ecore_thread_cancel() and ecore_thread_check() + * functions. This handler must not be shared with the worker function + * running in the thread. This same handler is the one received + * on the @c end, @c cancel, and @c feedback callbacks. + * + * The worker function, that's the one running in the thread, also receives + * an ::Ecore_Thread handler that can be used with ecore_thread_cancel() and + * ecore_thread_check(), sharing the flag with the main loop. But this + * handler is also associated with the thread where the function is running. + * This has strong implications when working with thread local data. + * + * There are two kinds of worker threads that Ecore handles: simple or short, + * workers, and feedback workers. + * + * The first kind is for simple functions that perform a + * usually small but time consuming task. Ecore runs this function in + * a thread as soon as one becomes available and notifies the calling user of + * its completion once the task is done. + * + * The following image shows the flow of a program running four tasks on + * a pool of two threads. + * + * @image html ecore_thread.png + * @image rtf ecore_thread.png + * @image latex ecore_thread.eps "ecore thread" width=\textwidth + * + * For larger tasks that may require continuous communication with the main + * program, the feedback workers provide the same functionality plus a way + * for the function running in the thread to send messages to the main + * thread. + * + * The next diagram omits some details shown in the previous one regarding + * how threads are spawned and tasks are queued, but illustrates how feedback + * jobs communicate with the main loop and the special case of threads + * running out of the pool. + * + * @image html ecore_thread_feedback.png + * @image rtf ecore_thread_feedback.png + * @image latex ecore_thread_feedback.eps "ecore thread feedback" width=\textwidth * * @{ */ -typedef struct _Ecore_Animator Ecore_Animator; /**< A handle for animators */ +typedef struct _Ecore_Thread Ecore_Thread; /**< @brief A handle for threaded jobs */ /** - * @enum _Ecore_Pos_Map - * Defines the position mappings for the animation. + * @typedef Ecore_Thread_Cb Ecore_Thread_Cb + * @brief Called to be used by Ecore_Thread helper. */ -enum _Ecore_Pos_Map /* Position mappings */ -{ - ECORE_POS_MAP_LINEAR, /**< Linear 0.0 -> 1.0 */ - ECORE_POS_MAP_ACCELERATE, /**< Start slow then speed up */ - ECORE_POS_MAP_DECELERATE, /**< Start fast then slow down */ - ECORE_POS_MAP_SINUSOIDAL, /**< Start slow, speed up then slow down at end */ - ECORE_POS_MAP_ACCELERATE_FACTOR, /**< Start slow then speed up, v1 being a power factor, 0.0 being linear, 1.0 being normal accelerate, 2.0 being much more pronounced accelerate (squared), 3.0 being cubed, etc. */ - ECORE_POS_MAP_DECELERATE_FACTOR, /**< Start fast then slow down, v1 being a power factor, 0.0 being linear, 1.0 being normal decelerate, 2.0 being much more pronounced decelerate (squared), 3.0 being cubed, etc. */ - ECORE_POS_MAP_SINUSOIDAL_FACTOR, /**< Start slow, speed up then slow down at end, v1 being a power factor, 0.0 being linear, 1.0 being normal sinusoidal, 2.0 being much more pronounced sinusoidal (squared), 3.0 being cubed, etc. */ - ECORE_POS_MAP_DIVISOR_INTERP, /**< Start at gradient * v1, interpolated via power of v2 curve */ - ECORE_POS_MAP_BOUNCE, /**< Start at 0.0 then "drop" like a ball bouncing to the ground at 1.0, and bounce v2 times, with decay factor of v1 */ - ECORE_POS_MAP_SPRING /**< Start at 0.0 then "wobble" like a spring rest position 1.0, and wobble v2 times, with decay factor of v1 */ -}; -typedef enum _Ecore_Pos_Map Ecore_Pos_Map; +typedef void (*Ecore_Thread_Cb)(void *data, Ecore_Thread *thread); +/** + * @typedef Ecore_Thread_Notify_Cb Ecore_Thread_Notify_Cb + * @brief Called to be used by the main loop to receive data sent by an + * @ref Ecore_Thread_Group. + */ +typedef void (*Ecore_Thread_Notify_Cb)(void *data, Ecore_Thread *thread, void *msg_data); /** - * @enum _Ecore_Animator_Source - * Defines the timing sources for animators. + * @brief Schedules a task to run in a parallel thread to avoid locking the main loop. + * + * @details This function tries to create a new thread to run @a func_blocking in, + * or if the maximum number of concurrent threads has been reached it + * adds it to the pending list, where it waits until a thread becomes + * available. The return value is an ::Ecore_Thread handle that can + * be used to cancel the thread before its completion. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks This function should always return immediately, but in the rare + * case that Ecore is built with no thread support, @a func_blocking is + * be called here, actually blocking the main loop. + * + * @remarks Once a thread becomes available, @a func_blocking is run in it until + * it finishes, then @a func_end is called from the thread containing the + * main loop to inform the user of its completion. While in @a func_blocking, + * no functions from the EFL can be used, except for those from Eina that are + * marked to be thread-safe. Even for the latter, caution needs to be taken + * if the data is shared across several threads. + * + * @remarks @a func_end is called from the main thread when @a func_blocking ends, + * so here it's safe to use anything from the EFL freely. + * + * @remarks The thread can also be cancelled before its completion by calling + * ecore_thread_cancel(), either from the main thread or @a func_blocking. + * In this case, @a func_cancel is called, also from the main thread + * to inform of this happening. If the thread could not be created, this + * function is called and its @c thread parameter is @c NULL. It's + * also safe to call any EFL function here, as it is running in the + * main thread. + * + * @remarks Inside @a func_blocking, it's possible to call ecore_thread_reschedule() + * to tell Ecore that this function should be called again. + * + * @remarks Be aware that no assumptions can be made about the order in which the + * @a func_end callbacks for each task are called. Once the function is + * running in a different thread, it's the OS that handles its running + * schedule, and different functions may take longer to finish than others. + * Also remember that just starting several tasks together doesn't mean they + * are going to run at the same time. Ecore schedules them based on the + * number of threads available for the particular system it's running in, + * so some of the jobs started may be waiting until another one finishes + * before it can execute its own @a func_blocking. + * + * @param[in] func_blocking The function that should run in another thread + * @param[in] func_end The function to call from the main loop when @a func_blocking + * completes its task successfully (may be @c NULL) + * @param[in] func_cancel The function to call from the main loop if the thread running + * @a func_blocking is cancelled or fails to start (may be @c NULL) + * @param[in] data The user context data to pass to all callbacks + * @return A new thread handler, + * otherwise @c NULL on failure + * + * @see ecore_thread_feedback_run() + * @see ecore_thread_cancel() + * @see ecore_thread_reschedule() + * @see ecore_thread_max_set() */ -enum _Ecore_Animator_Source /* Timing sources for animators */ -{ - ECORE_ANIMATOR_SOURCE_TIMER, /**< The default system clock/timer based animator that ticks every "frametime" seconds */ - ECORE_ANIMATOR_SOURCE_CUSTOM /**< A custom animator trigger that you need to call ecore_animator_trigger() to make it tick */ -}; -typedef enum _Ecore_Animator_Source Ecore_Animator_Source; +EAPI Ecore_Thread *ecore_thread_run(Ecore_Thread_Cb func_blocking, Ecore_Thread_Cb func_end, Ecore_Thread_Cb func_cancel, const void *data); /** - * @typedef Ecore_Timeline_Cb Ecore_Timeline_Cb - * A callback run for a task (animators with runtimes) + * @brief Launches a thread to run a task that can talk back to the main thread. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks The difference in the above is that ecore_thread_run() is meant for + * tasks that don't need to communicate anything until they finish, while + * this function is provided with a new callback, @a func_notify, that is + * called from the main thread for every message sent from @a func_heavy + * with ecore_thread_feedback(). + * + * @remarks Like with ecore_thread_run(), a new thread is launched to run + * @a func_heavy unless the maximum number of simultaneous threads has been + * reached, in which case the function is scheduled to run whenever a + * running task ends and a thread becomes free. But if @a try_no_queue is + * set, Ecore first tries to launch a thread outside of the pool to run + * the task. If it fails, it reverts to the normal behaviour of using a + * thread from the pool as if @a try_no_queue had not been set. + * + * @remarks Keep in mind that Ecore handles the thread pool based on the number of + * CPUs available, but running a thread outside of the pool doesn't count for + * this, so having too many of them may have drastic effects over the + * program's performance. + * + * @remarks See ecore_thread_run() for a general description of this function. + * + * @param[in] func_heavy The function that should run in another thread + * @param[in] func_notify the function that receives the data sent from the thread + * @param[in] func_end The function to call from the main loop when @a func_heavy + * completes its task successfully + * @param[in] func_cancel The function to call from the main loop if the thread running + * @a func_heavy is cancelled or fails to start + * @param[in] data The user context data to pass to all callbacks + * @param[in] try_no_queue The boolean value that indicates whether to run outside the thread pool + * @return A new thread handler, + * otherwise @c NULL on failure + * + * @see ecore_thread_feedback() + * @see ecore_thread_run() + * @see ecore_thread_cancel() + * @see ecore_thread_reschedule() + * @see ecore_thread_max_set() */ -typedef Eina_Bool (*Ecore_Timeline_Cb)(void *data, double pos); +EAPI Ecore_Thread *ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy, Ecore_Thread_Notify_Cb func_notify, + Ecore_Thread_Cb func_end, Ecore_Thread_Cb func_cancel, + const void *data, Eina_Bool try_no_queue); /** - * @brief Add an animator to call @p func at every animation tick during main - * loop execution. + * @brief Cancels a running thread. * - * @param func The function to call when it ticks off - * @param data The data to pass to the function - * @return A handle to the new animator + * @details This function cancels a running thread. If @a thread can be immediately + * cancelled (its still pending execution after creation or rescheduling), + * then the @a cancel callback is called, @a thread is freed and + * the function returns #EINA_TRUE. * - * This function adds a animator and returns its handle on success and @c NULL - * on failure. The function @p func will be called every N seconds where N is - * the @p frametime interval set by ecore_animator_frametime_set(). The - * function will be passed the @p data pointer as its parameter. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks If the thread is already running, then this function returns @c EINA_FALSE + * after marking the @a thread as pending cancellation. For the thread to + * actually be terminated, it needs to return from the user function back + * into Ecore control. This can happen in several ways: + * @li The function ends and returns normally. If it hadn't been cancelled, + * @a func_end would be called here, but instead @a func_cancel happens. + * @li The function returns after requesting to be rescheduled with + * ecore_thread_reschedule(). + * @li The function is prepared to leave early by checking if + * ecore_thread_check() returns #EINA_TRUE. * - * When the animator @p func is called, it must return a value of either 1 or - * 0. If it returns 1 (or ECORE_CALLBACK_RENEW), it will be called again at - * the next tick, or if it returns 0 (or ECORE_CALLBACK_CANCEL) it will be - * deleted automatically making any references/handles for it invalid. + * @remarks The user function can cancel itself by calling ecore_thread_cancel(), but + * it should always use the ::Ecore_Thread handle passed to it and never + * share it with the main loop thread by means of shared user data or in any + * other way. * - * @note The default @p frametime value is 1/30th of a second. + * @remarks @a thread is freed and should not be used again if this function + * returns #EINA_TRUE or after the @a func_cancel callback returns. * - * @see ecore_animator_timeline_add() - * @see ecore_animator_frametime_set() + * @remarks This function can be called both in the main loop and in the running thread. + * + * @param[in] thread The thread to cancel + * @return #EINA_TRUE if the thread has been cancelled, + * otherwise @c EINA_FALSE if it is pending + * + * @see ecore_thread_check() */ -EAPI Ecore_Animator *ecore_animator_add(Ecore_Task_Cb func, const void *data); +EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread *thread); + /** - * @brief Add a animator that runs for a limited time + * @brief Checks whether a thread is in pending cancellation. * - * @param runtime The time to run in seconds - * @param func The function to call when it ticks off - * @param data The data to pass to the function - * @return A handle to the new animator + * @details This function can be called both in the main loop and in the running thread. * - * This function is just like ecore_animator_add() except the animator only - * runs for a limited time specified in seconds by @p runtime. Once the - * runtime the animator has elapsed (animator finished) it will automatically - * be deleted. The callback function @p func can return ECORE_CALLBACK_RENEW - * to keep the animator running or ECORE_CALLBACK_CANCEL ro stop it and have - * it be deleted automatically at any time. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * The @p func will ALSO be passed a position parameter that will be in value - * from 0.0 to 1.0 to indicate where along the timeline (0.0 start, 1.0 end) - * the animator run is at. If the callback wishes not to have a linear - * transition it can "map" this value to one of several curves and mappings - * via ecore_animator_pos_map(). + * @remarks When ecore_thread_cancel() is called on an already running task, the + * thread is marked as pending cancellation. This function returns #EINA_TRUE + * if this mark is set for the given @a thread and can be used from the + * main loop thread to check if a still active thread has been cancelled, + * or from the user function running in the thread to check if it should + * stop doing what it's doing and return early, effectively cancelling the + * task. * - * @note The default @p frametime value is 1/30th of a second. + * @param[in] thread The thread to test + * @return #EINA_TRUE if the thread is in pending cancellation, + * otherwise @c EINA_FALSE if it is not * - * @see ecore_animator_add() - * @see ecore_animator_pos_map() - * @since 1.1.0 + * @see ecore_thread_cancel() */ -EAPI Ecore_Animator *ecore_animator_timeline_add(double runtime, Ecore_Timeline_Cb func, const void *data); +EAPI Eina_Bool ecore_thread_check(Ecore_Thread *thread); + /** - * @brief Delete the specified animator from the animator list. + * @brief Sends data from the worker thread to the main loop. * - * @param animator The animator to delete - * @return The data pointer set for the animator on add + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks You should use this function only in the @a func_heavy call. * - * Delete the specified @p animator from the set of animators that are - * executed during main loop execution. This function returns the data - * parameter that was being passed to the callback on success, or @c NULL on - * failure. After this call returns the specified animator object @p animator - * is invalid and should not be used again. It will not get called again after - * deletion. + * @remarks Only the address to @a msg_data is sent and once this function + * returns #EINA_TRUE, the job running in the thread should never touch the + * contents of it again. The data sent should be malloc()'ed or something + * similar, as long as it's not the memory that is local to the thread that risks being + * overwritten or deleted once it goes out of scope or the thread finishes. + * + * @remarks Care must be taken that @a msg_data is properly freed in the @a func_notify + * callback set when creating the thread. + * + * @param[in] thread The current ::Ecore_Thread context to send data from + * @param[in] msg_data The data to be transmitted to the main loop + * @return #EINA_TRUE if @a msg_data is successfully sent to the main loop, + * otherwise @c EINA_FALSE if anything goes wrong + * + * @see ecore_thread_feedback_run() */ -EAPI void *ecore_animator_del(Ecore_Animator *animator); +EAPI Eina_Bool ecore_thread_feedback(Ecore_Thread *thread, const void *msg_data); + /** - * @brief Suspend the specified animator. + * @brief Asks for the function in the thread to be called again at a later period. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @param animator The animator to delete + * @remarks This function should be called only from the function represented + * by @a thread. * - * The specified @p animator will be temporarily removed from the set of - * animators that are executed during main loop. + * Calling this function marks the thread for a reschedule, so as soon + * as it returns, it is added to the end of the list of pending tasks. + * If no other tasks are waiting or there are sufficient threads available, + * the rescheduled task is launched again immediately. + * + * This should never return @c EINA_FALSE, unless it is called from the wrong + * thread or with the wrong arguments. + * + * @remarks The @a func_end callback set when the thread is created is not + * called until the function in the thread returns without being rescheduled. + * Similarly, if the @a thread is cancelled, the reschedule does not take + * effect. + * + * @param[in] thread The current ::Ecore_Thread context to reschedule + * @return #EINA_TRUE if the task is successfully rescheduled, + * otherwise @c EINA_FALSE if anything goes wrong * - * @warning Freezing an animator doesn't freeze accounting of how long that - * animator has been running. Therefore if the animator was created with - *ecore_animator_timeline_add() the @p pos argument given to the callback - * will increase as if the animator hadn't been frozen and the animator may - * have it's execution halted if @p runtime elapsed. */ -EAPI void ecore_animator_freeze(Ecore_Animator *animator); +EAPI Eina_Bool ecore_thread_reschedule(Ecore_Thread *thread); + /** - * @brief Restore execution of the specified animator. + * @brief Gets the number of active threads running jobs. + * + * @details This returns the number of threads currently running jobs of any type + * through the Ecore_Thread API. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @param animator The animator to delete + * @remarks Jobs started through the ecore_thread_feedback_run() function with + * the @a try_no_queue parameter set to #EINA_TRUE are not accounted for + * in the return of this function unless the thread creation fails and it + * falls back to using one from the pool. + * + * @return The number of active threads running jobs * - * The specified @p animator will be put back in the set of animators that are - * executed during main loop. */ -EAPI void ecore_animator_thaw(Ecore_Animator *animator); +EAPI int ecore_thread_active_get(void); + /** - * @brief Set the animator call interval in seconds. + * @brief Gets the number of short jobs waiting for a thread to run. * - * @param frametime The time in seconds in between animator ticks. + * @details This returns the number of tasks started with ecore_thread_run() that are + * pending and waiting for a thread to become available to run them. * - * This function sets the time interval (in seconds) between animator ticks. - * At every tick the callback of every existing animator will be called. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @warning Too small a value may cause performance issues and too high a - * value may cause your animation to seem "jerky". + * @return The number of pending threads running "short" jobs * - * @note The default @p frametime value is 1/30th of a second. */ -EAPI void ecore_animator_frametime_set(double frametime); +EAPI int ecore_thread_pending_get(void); + /** - * @brief Get the animator call interval in seconds. + * @brief Gets the number of feedback jobs waiting for a thread to run. * - * @return The time in second in between animator ticks. + * @details This returns the number of tasks started with ecore_thread_feedback_run() + * that are pending and waiting for a thread to become available to run them. * - * This function retrieves the time in seconds between animator ticks. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @return The number of pending threads running "feedback" jobs * - * @see ecore_animator_frametime_set() */ -EAPI double ecore_animator_frametime_get(void); +EAPI int ecore_thread_pending_feedback_get(void); + /** - * @brief Maps an input position from 0.0 to 1.0 along a timeline to a - * position in a different curve. + * @brief Gets the total number of pending jobs. * - * @param pos The input position to map - * @param map The mapping to use - * @param v1 A parameter use by the mapping (pass 0.0 if not used) - * @param v2 A parameter use by the mapping (pass 0.0 if not used) - * @return The mapped value + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * Takes an input position (0.0 to 1.0) and maps to a new position (normally - * between 0.0 and 1.0, but it may go above/below 0.0 or 1.0 to show that it - * has "overshot" the mark) using some interpolation (mapping) algorithm. + * @remarks This is same as the sum of ecore_thread_pending_get() and + * ecore_thread_pending_feedback_get(). * - * This function useful to create non-linear animations. It offers a variety - * of possible animation curves to be used: - * @li ECORE_POS_MAP_LINEAR - Linear, returns @p pos - * @li ECORE_POS_MAP_ACCELERATE - Start slow then speed up - * @li ECORE_POS_MAP_DECELERATE - Start fast then slow down - * @li ECORE_POS_MAP_SINUSOIDAL - Start slow, speed up then slow down at end - * @li ECORE_POS_MAP_ACCELERATE_FACTOR - Start slow then speed up, v1 being a - * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_ACCELERATE, 2.0 - * being much more pronounced accelerate (squared), 3.0 being cubed, etc. - * @li ECORE_POS_MAP_DECELERATE_FACTOR - Start fast then slow down, v1 being a - * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_DECELERATE, 2.0 - * being much more pronounced decelerate (squared), 3.0 being cubed, etc. - * @li ECORE_POS_MAP_SINUSOIDAL_FACTOR - Start slow, speed up then slow down - * at end, v1 being a power factor, 0.0 being linear, 1.0 being - * ECORE_POS_MAP_SINUSOIDAL, 2.0 being much more pronounced sinusoidal - * (squared), 3.0 being cubed, etc. - * @li ECORE_POS_MAP_DIVISOR_INTERP - Start at gradient * v1, interpolated via - * power of v2 curve - * @li ECORE_POS_MAP_BOUNCE - Start at 0.0 then "drop" like a ball bouncing to - * the ground at 1.0, and bounce v2 times, with decay factor of v1 - * @li ECORE_POS_MAP_SPRING - Start at 0.0 then "wobble" like a spring rest - * position 1.0, and wobble v2 times, with decay factor of v1 - * @note When not listed v1 and v2 have no effect. + * @return The number of pending threads running jobs * - * @image html ecore-pos-map.png - * @image latex ecore-pos-map.eps width=\textwidth + */ +EAPI int ecore_thread_pending_total_get(void); + +/** + * @brief Gets the maximum number of threads that can run simultaneously. * - * One way to use this would be: - * @code - * double pos; // input position in a timeline from 0.0 to 1.0 - * double out; // output position after mapping - * int x1, y1, x2, y2; // x1 & y1 are start position, x2 & y2 are end position - * int x, y; // x & y are the calculated position + * @details This returns the maximum number of Ecore_Thread's that may be running at + * the same time. If this number is reached, new jobs started by either + * ecore_thread_run() or ecore_thread_feedback_run() are added to the + * respective pending queues until one of the running threads finishes its + * task and becomes available to run a new one. * - * out = ecore_animator_pos_map(pos, ECORE_POS_MAP_BOUNCE, 1.8, 7); - * x = (x1 * out) + (x2 * (1.0 - out)); - * y = (y1 * out) + (y2 * (1.0 - out)); - * move_my_object_to(myobject, x, y); - * @endcode - * This will make an animation that bounces 7 each times diminishing by a - * factor of 1.8. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @see _Ecore_Pos_Map + * @remarks By default, this is the number of available CPUs for the + * running program, or @c 1 if this value + * could not be fetched. * - * @since 1.1.0 + * @return The maximum possible number of Ecore_Thread's running concurrently + * + * @see ecore_thread_max_set() + * @see ecore_thread_max_reset() */ -EAPI double ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2); +EAPI int ecore_thread_max_get(void); + /** - * @brief Set the source of animator ticks for the mainloop - * - * @param source The source of animator ticks to use - * - * This sets the source of animator ticks. When an animator is active the - * mainloop will "tick" over frame by frame calling all animators that are - * registered until none are. The mainloop will tick at a given rate based - * on the animator source. The default source is the system clock timer - * source - ECORE_ANIMATOR_SOURCE_TIMER. This source uses the system clock - * to tick over every N seconds (specified by ecore_animator_frametime_set(), - * with the default being 1/30th of a second unless set otherwise). You can - * set a custom tick source by setting the source to - * ECORE_ANIMATOR_SOURCE_CUSTOM and then drive it yourself based on some input - * tick source (like another application via ipc, some vertical blanking - * interrupt interrupt etc.) using - *ecore_animator_custom_source_tick_begin_callback_set() and - *ecore_animator_custom_source_tick_end_callback_set() to set the functions - * that will be called to start and stop the ticking source, which when it - * gets a "tick" should call ecore_animator_custom_tick() to make the "tick" over 1 - * frame. + * @brief Sets the maximum number of threads allowed to run simultaneously. + * + * @details This sets a new value for the maximum number of concurrently running + * Ecore_Thread's. It @b must be an integer between @c 1 and (@c 16 * @c x), where @c x + * is the number for CPUs available. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] num The new maximum + * + * @see ecore_thread_max_get() + * @see ecore_thread_max_reset() */ -EAPI void ecore_animator_source_set(Ecore_Animator_Source source); +EAPI void ecore_thread_max_set(int num); + /** - * @brief Get the animator source currently set. + * @brief Resets the maximum number of concurrently running threads to the default. * - * @return The current animator source + * @details This resets the value returned by ecore_thread_max_get() back to its + * default. * - * This gets the current animator source. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @see ecore_animator_source_set() + * @see ecore_thread_max_get() + * @see ecore_thread_max_set() */ -EAPI Ecore_Animator_Source ecore_animator_source_get(void); +EAPI void ecore_thread_max_reset(void); + /** - * @brief Set the function that begins a custom animator tick source + * @brief Gets the number of threads available for running tasks. * - * @param func The function to call when ticking is to begin - * @param data The data passed to the tick begin function as its parameter + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * The Ecore Animator infrastructure handles tracking if animators are needed - * or not and which ones need to be called and when, but when the tick source - * is custom, you have to provide a tick source by calling - *ecore_animator_custom_tick() to indicate a frame tick happened. In order - * to allow the source of ticks to be dynamically enabled or disabled as - * needed, the @p func when set is called to enable the tick source to - * produce tick events that call ecore_animator_custom_tick(). If @p func - * is @c NULL then no function is called to begin custom ticking. + * @remarks This is same as doing ecore_thread_max_get() - ecore_thread_active_get(). + * + * @remarks This function may return a negative number only in the case when the user + * changes the maximum number of running threads while other tasks are + * running. + * + * @return The number of available threads * - * @see ecore_animator_source_set() - * @see ecore_animator_custom_source_tick_end_callback_set() - * @see ecore_animator_custom_tick() */ -EAPI void ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, const void *data); +EAPI int ecore_thread_available_get(void); + /** - * @brief Set the function that ends a custom animator tick source + * @brief Adds some data present in the hash local to the thread. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks Ecore Thread has a mechanism to share data across several worker functions + * that run on the same system thread. That is, the data is stored per + * thread and for a worker function to have access to it, it must be run + * by the same thread that stored the data. + * + * @remarks When there are no more workers pending, the thread is destroyed + * along with the internal hash and any data left in it is freed with + * the given @a cb function. + * + * @ This set of functions is useful to share things around several instances + * of a function when that thing is costly to create and can be reused, but + * may only be used by one function at a time. + * + * For example, if you have a program doing requisitions to a database, + * these requisitions can be done in threads so that waiting for the + * database to respond doesn't block the UI. Each of these threads + * run a function, and each function is dependent on a connection to + * the database, which may not be able to handle more than one request at + * a time so for each running function you need one connection handle. + * + * The options then are: + * @li Each function opens a connection when it's called, does the work and + * closes the connection when it finishes. This may be costly, wasting a lot + * of time on resolving hostnames, negotiating permissions, and allocating + * memory. + * @li Open the connections in the main loop and pass it to the threads + * using the data pointer. Even worse, it's just as costly as before and now + * it may even be kept with connections open doing nothing until a thread + * becomes available to run the function. + * @li Have a way to share connection handles, so that each instance of the + * function can check if an available connection exists, and if it doesn't, + * create one and add it to the pool. When no more connections are needed, + * they are all closed. + * + * The last option is the most efficient, but it requires a lot of work to + * be implemented properly. Using thread local data helps to achieve the same + * result while avoiding all the tracking work on your code. The way + * to use it would be at the worker function, to ask for the connection + * using ecore_thread_local_data_find() and if it doesn't exist, then open + * a new one and save it with ecore_thread_local_data_add(). Complete the work and + * forget about the connection handle, when everything is done the function + * just ends. The next worker to run on that thread checks if a + * connection exists and finds that it does, so the process of opening a + * new one has been spared. When no more workers exist, the thread is + * destroyed and the callback used when saving the connection is called + * to close it. + * + * @remarks This function adds the data @a value to the thread data under the given + * @a key. No other value in the hash may have the same @a key. If you need to + * change the value under a @a key, or you don't know if one exists already, + * you can use ecore_thread_local_data_set(). + * + * Neither @a key nor @a value may be @c NULL and @a key gets copied in the + * hash, unless @a direct is set, in which case the string used should not + * be freed until the data is removed from the hash. + * + * @remarks The @a cb function is called when the data in the hash needs to be + * freed, be it because it got deleted by ecore_thread_local_data_del() or + * because @a thread got terminated and the hash got destroyed. This parameter + * may be @c NULL, in which case @a value needs to be manually freed after + * removing it from the hash with either ecore_thread_local_data_del() or + * ecore_thread_local_data_set(), but it's very unlikely that this is what + * you want. + * + * This function, and all of the others in the @a ecore_thread_local_data + * family of functions, can only be called within the worker function running + * in the thread. Do not call them from the main loop or from a thread + * other than the one represented by @a thread. + * + * @param[in] thread The thread context the data belongs to + * @param[in] key The name under which the data is stored + * @param[in] value The data to add + * @param[in] cb The function to free the data when removed from the hash + * @param[in] direct If @c true, this does not copy the key string (like eina_hash_direct_add()), + * otherwise @c false + * @return #EINA_TRUE on success, + * otherwise @c EINA_FALSE on failure * - * @param func The function to call when ticking is to end - * @param data The data passed to the tick end function as its parameter + * @see ecore_thread_local_data_set() + * @see ecore_thread_local_data_find() + * @see ecore_thread_local_data_del() + */ +EAPI Eina_Bool ecore_thread_local_data_add(Ecore_Thread *thread, const char *key, void *value, + Eina_Free_Cb cb, Eina_Bool direct); + +/** + * @brief Sets some data present in the hash local to the given thread. * - * This function is a matching pair to the function set by - * ecore_animator_custom_source_tick_begin_callback_set() and is called - * when ticking is to stop. If @p func is @c NULL then no function will be - * called to stop ticking. For more information please see - * ecore_animator_custom_source_tick_begin_callback_set(). + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @see ecore_animator_source_set() - * @see ecore_animator_custom_source_tick_begin_callback_set() - * @see ecore_animator_custom_tick() + * @remarks If no data exists in the hash under the @a key, this function adds + * @a value in the hash under the given @a key and returns @c NULL. + * The key itself is copied. + * + * If the hash already contains something under @a key, the data is + * replaced by @a value and the old value is returned. + * + * @c NULL is also returned if either @a key or @a value are @c NULL, or + * if an error occurs. + * + * @remarks This function, and all of the others in the @a ecore_thread_local_data + * family of functions, can only be called within the worker function running + * in the thread. Do not call them from the main loop or from a thread + * other than the one represented by @a thread. + * + * @param[in] thread The thread context the data belongs to + * @param[in] key The name under which the data is stored + * @param[in] value The data to add + * @param[in] cb The function to free the data when removed from the hash + * + * @see ecore_thread_local_data_add() + * @see ecore_thread_local_data_del() + * @see ecore_thread_local_data_find() */ -EAPI void ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, const void *data); +EAPI void *ecore_thread_local_data_set(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb); + /** - * @brief Trigger a custom animator tick + * @brief Gets data stored in the hash local to the given thread. * - * When animator source is set to ECORE_ANIMATOR_SOURCE_CUSTOM, then calling - * this function triggers a run of all animators currently registered with - * Ecore as this indicates a "frame tick" happened. This will do nothing if - * the animator source(set by ecore_animator_source_set()) is not set to - * ECORE_ANIMATOR_SOURCE_CUSTOM. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @see ecore_animator_source_set() - * @see ecore_animator_custom_source_tick_begin_callback_set - * @see ecore_animator_custom_source_tick_end_callback_set()() + * @details This finds and returns the data stored in the shared hash under the key @a key. + * + * @remarks This function, and all the others in the @a ecore_thread_local_data + * family of functions, can only be called within the worker function running + * in the thread. Do not call them from the main loop or from a thread + * other than the one represented by @a thread. + * + * @param[in] thread The thread context the data belongs to + * @param[in] key The name under which the data is stored + * @return The value under the given key, + * otherwise @c NULL on an error + * + * @see ecore_thread_local_data_add() + * @see ecore_thread_local_data_wait() */ -EAPI void ecore_animator_custom_tick(void); +EAPI void *ecore_thread_local_data_find(Ecore_Thread *thread, const char *key); /** - * @} + * @brief Deletes the data corresponding to the given key from the thread's hash. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks If there's any data associated with @a key that is stored in the global hash, + * this function removes it from the hash and returns #EINA_TRUE. If no data + * exists or an error occurs, it returns @c EINA_FALSE. + * + * @remarks If the data is added to the hash with a free function, then it is + * also freed after removing it from the hash, otherwise it requires + * to be manually freed by the user, which means that if no other reference + * to it exists before calling this function, it results in a memory + * leak. + * + * @remarks This function, and all the others in the @a ecore_thread_local_data + * family of functions, can only be called within the worker function running + * in the thread. Do not call them from the main loop or from a thread + * other than the one represented by @a thread. + * + * @param[in] thread The thread context the data belongs to + * @param[in] key The name under which the data is stored + * @return #EINA_TRUE on success, + * otherwise @c EINA_FALSE on failure + * + * @see ecore_thread_local_data_add() */ +EAPI Eina_Bool ecore_thread_local_data_del(Ecore_Thread *thread, const char *key); /** - * @defgroup Ecore_Time_Group Ecore time functions + * @brief Adds some data to a hash shared by all threads. * - * These are function to retrieve time in a given format. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * Examples: - * @li @ref ecore_time_functions_example_c - * @{ + * @remarks Ecore Thread keeps a hash that can be used to share data across several + * threads, including the main loop thread, without having to manually handle + * mutexes to do it safely. + * + * @remarks This function adds the data @a value to this hash under the given @a key. + * No other value in the hash may have the same @a key. If you need to + * change the value under a @a key, or you don't know if one exists already, + * you can use ecore_thread_global_data_set(). + * + * Neither @a key nor @a value may be @c NULL and @a key gets copied in the + * hash, unless @a direct is set, in which case the string used should not + * be freed until the data is removed from the hash. + * + * @remarks The @a cb function is called when the data in the hash needs to be + * freed, be it because it got deleted with ecore_thread_global_data_del() or + * because Ecore Thread got shut down and the hash got destroyed. This parameter + * may be @c NULL, in which case @a value needs to be manually freed after + * removing it from the hash with either by ecore_thread_global_data_del() or + * ecore_thread_global_data_set(). + * + * Manually freeing any data that is added to the hash with the @a cb function + * is likely to produce a segmentation fault, or any other strange + * happening at a later stage in the program. + * + * @param[in] key The name under which the data is stored + * @param[in] value The data to add + * @param[in] cb The function to free the data when removed from the hash + * @param[in] direct If @c true, this does not copy the key string (like eina_hash_direct_add()), + * otherwise @c false + * @return #EINA_TRUE on success, + * otherwise @c EINA_FALSE on failure + * + * @see ecore_thread_global_data_del() + * @see ecore_thread_global_data_set() + * @see ecore_thread_global_data_find() */ -EAPI double ecore_time_get(void); -EAPI double ecore_time_unix_get(void); -EAPI double ecore_loop_time_get(void); +EAPI Eina_Bool ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct); + +/** + * @brief Sets some data in the hash shared by all threads. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks If no data exists in the hash under the @a key, this function adds + * @a value in the hash under the given @a key and returns @c NULL. + * The key itself is copied. + * + * If the hash already contains something under @a key, the data is + * replaced by @a value and the old value is returned. + * + * @c NULL is also returned if either @a key or @a value is @c NULL, or + * if an error occurs. + * + * + * @param[in] key The name under which the data is stored + * @param[in] value The data to add + * @param[in] cb The function to free the data when removed from the hash + * + * @see ecore_thread_global_data_add() + * @see ecore_thread_global_data_del() + * @see ecore_thread_global_data_find() + */ +EAPI void *ecore_thread_global_data_set(const char *key, void *value, Eina_Free_Cb cb); + +/** + * @brief Gets data stored in the hash shared by all threads. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @details This finds and returns the data stored in the shared hash under the key @a key. + * + * @remarks Keep in mind that the data returned may be used by more than one thread + * at the same time and no reference counting is done on it by Ecore. + * Freeing the data or modifying its contents may require additional + * precautions to be considered, depending on the application's design. + * + * @param[in] key The name under which the data is stored + * @return The value under the given key, + * otherwise @c NULL on an error + * + * @see ecore_thread_global_data_add() + * @see ecore_thread_global_data_wait() + */ +EAPI void *ecore_thread_global_data_find(const char *key); + +/** + * @brief Deletes the data corresponding to the given key from the shared hash. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks If there's any data associated with @p key that is stored in the global hash, + * this function removes it from the hash and returns #EINA_TRUE. If no data + * exists or an error occurs, it returns @c EINA_FALSE. + * + * @remarks If the data is added to the hash with a free function, then it is + * also freed after removing it from the hash, otherwise it requires + * to be manually freed by the user, which means that if no other reference + * to it exists before calling this function, it results in a memory + * leak. + * + * Note, also, that freeing data that other threads may be using results + * in a crash, so appropriate care must be taken by the application when + * that possibility exists. + * + * @param[in] key The name under which the data is stored + * @return #EINA_TRUE on success, + * otherwise @c EINA_FALSE on failure + * + * @see ecore_thread_global_data_add() + */ +EAPI Eina_Bool ecore_thread_global_data_del(const char *key); + +/** + * @brief Gets data stored in the shared hash or waits for it if it doesn't exist. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks This finds and returns the data stored in the shared hash under the key @a key. + * + * If there's nothing in the hash under the given @a key, the function + * blocks and waits for @a seconds seconds for some other thread to + * add it with either ecore_thread_global_data_add() or + * ecore_thread_global_data_set(). If after waiting there's still no data + * to obtain, @c NULL is returned. + * + * If @a seconds is @c 0, then no waiting happens and this function works + * like ecore_thread_global_data_find(). If @a seconds is less than @c 0, then + * the function waits indefinitely. + * + * @remarks Keep in mind that the data returned may be used by more than one thread + * at the same time and no reference counting is done on it by Ecore. + * Freeing the data or modifying its contents may require additional + * precautions to be considered, depending on the application's design. + * + * @param[in] key The name under which the data is stored + * @param[in] seconds The amount of time in seconds to wait for the data + * @return The value under the given key, + * otherwise @c NULL on an error + * + * @see ecore_thread_global_data_add() + * @see ecore_thread_global_data_find() + */ +EAPI void *ecore_thread_global_data_wait(const char *key, double seconds); /** * @} */ /** - * @defgroup Ecore_Timer_Group Ecore Timer functions + * @defgroup Ecore_Timer_Group Ecore Timer + * @ingroup Ecore_Main_Loop_Group + * + * @brief Ecore provides very flexible timer functionality. * - * Ecore provides very flexible timer functionality. The basic usage of timers, - * to call a certain function at a certain interval can be achieved with a - * single line: + * The basic usage of timers is to call a certain function at a certain + * interval, which can be achieved with a single line: * @code * Eina_Bool my_func(void *data) { * do_funky_stuff_with_data(data); - * return EINA_TRUE; + * return ECORE_CALLBACK_RENEW; * } * ecore_timer_add(interval_in_seconds, my_func, data_given_to_function); * @endcode - * @note If the function was to be executed only once simply return - * @c EINA_FALSE instead. - * - * An example that shows the usage of a lot of these: - * @li @ref ecore_timer_example_c - * - * @ingroup Ecore_Main_Loop_Group + * If the function is to be executed only once simply return + * @c CORE_CALLBACK_CANCEL instead. * * @{ */ -typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */ +typedef struct _Ecore_Timer Ecore_Timer; /**< @brief A handle for timers */ +/** + * @brief Creates a timer to call the given function in the given period of time. + * + * @details This function adds a timer and returns its handle on success and NULL on + * failure. The function @p func will be called every @p in seconds. The + * function will be passed the @p data pointer as its parameter. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks When the timer @p func is called, it must return a value of either 1 + * (or ECORE_CALLBACK_RENEW) or 0 (or ECORE_CALLBACK_CANCEL). + * If it returns 1, it will be called again at the next tick, or if it returns + * 0 it will be deleted automatically making any references/handles for it + * invalid. + * + * @param[in] in The interval in seconds. + * @param[in] func The given function. If @p func returns 1, the timer is + * rescheduled for the next interval @p in. + * @param[in] data Data to pass to @p func when it is called. + * @return A timer object on success. @c NULL on failure. + */ EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, const void *data); + +/** + * @brief Creates a timer to call the given function in the given period of time. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks This is same as ecore_timer_add(), but "now" is the time from + * ecore_loop_time_get(), not ecore_time_get(), as ecore_timer_add() uses it. See + * ecore_timer_add() for more details. + * + * @param[in] in The interval in seconds from the current loop time + * @param[in] func The given function \n + * If @a func returns @c 1, the timer is + * rescheduled for the next interval @a in. + * @param[in] data The data to pass to @a func when it is called + * @return A timer object on success, + * otherwise @c NULL on failure + */ EAPI Ecore_Timer *ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data); + +/** + * @brief Deletes the specified timer from the timer list. + * + * @details This deletes the specified @a timer from the set of timer that are + * executed during main loop execution. This function returns the data + * parameter that is being passed to the callback on success, otherwise @c NULL on + * failure. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] timer The timer to delete + * @return The data pointer set for the timer on add + * + */ EAPI void *ecore_timer_del(Ecore_Timer *timer); + +/** + * @brief Change the interval the timer ticks off. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] timer The timer to change. + * @param[in] in The interval in seconds. + */ EAPI void ecore_timer_interval_set(Ecore_Timer *timer, double in); + +/** + * @brief Get the interval the timer ticks on. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] timer The timer to retrieve the interval from + * @return The interval on success. -1 on failure. + */ EAPI double ecore_timer_interval_get(Ecore_Timer *timer); + +/** + * @brief Pauses a running timer. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks The timer callback won't be called while the timer is paused. The remaining + * time until the timer expires will be saved, so the timer can be resumed with + * that same remaining time to expire, instead of expiring instantly. Use + * ecore_timer_thaw() to resume it. + * + * @remarks Nothing happens if the timer was already paused. + * + * @param[in] timer The timer to be paused. + * + * @see ecore_timer_thaw() + */ EAPI void ecore_timer_freeze(Ecore_Timer *timer); + +/** + * @brief Resumes a frozen (paused) timer. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks The timer will be resumed from its previous relative position in time. That + * means, if it had X seconds remaining until expire when it was paused, it will + * be started now with those same X seconds remaining to expire again. But + * notice that the interval time won't be touched by this call or by + * ecore_timer_freeze(). + * + * @param[in] timer The timer to be resumed. + * + * @see ecore_timer_freeze() + */ EAPI void ecore_timer_thaw(Ecore_Timer *timer); + +/** + * @brief Add some delay for the next occurrence of a timer. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks This doesn't affect the interval of a timer. + * + * @param[in] timer The timer to change. + * @param[in] add The delay to add to the next iteration. + */ EAPI void ecore_timer_delay(Ecore_Timer *timer, double add); + +/** + * @brief Reset a timer to its full interval. This effectively makes + * the timer start ticking off from zero now. + * + * @param[in] timer The timer + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + */ EAPI void ecore_timer_reset(Ecore_Timer *timer); + +/** + * @brief Get the pending time regarding a timer. + * + * @param[in] timer The timer + * @return The pending time + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + */ EAPI double ecore_timer_pending_get(Ecore_Timer *timer); + +/** + * @brief Retrieves the current precision used by timer infrastructure. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @return Current precision. + * + * @see ecore_timer_precision_set() + */ EAPI double ecore_timer_precision_get(void); + +/** + * @brief Sets the precision to be used by timer infrastructure. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks This sets the precision for @b all timers. The precision determines how much + * of an difference from the requested interval is acceptable. One common reason + * to use this function is to @b increase the allowed timeout and thus @b + * decrease precision of the timers, this is because less precise the timers + * result in the system waking up less often and thus consuming less resources. + * + * @remarks Be aware that kernel may delay delivery even further, these delays + * are always possible due other tasks having higher priorities or + * other scheduler policies. + * + * @remarks Example: + * We have 2 timers, one that expires in a 2.0s and another that + * expires in 2.1s, if precision is 0.1s, then the Ecore will request + * for the next expire to happen in 2.1s and not 2.0s and another one + * of 0.1 as it would before. + * + * @remarks Ecore is smart enough to see if there are timers in the + * precision range, if it does not, in our example if no second timer + * in (T + precision) existed, then it would use the minimum timeout. + + * @param[in] precision difference from the requested internval. + */ EAPI void ecore_timer_precision_set(double precision); + +/** + * @brief Dump the all timers. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @return The information of all timers + */ EAPI char *ecore_timer_dump(void); /** @@ -1668,25 +2606,26 @@ EAPI char *ecore_timer_dump(void); */ /** - * @defgroup Ecore_Idle_Group Ecore Idle functions + * @defgroup Ecore_Idle_Group Ecore Idle + * @ingroup Ecore_Main_Loop_Group * - * The idler functionality in Ecore allows for callbacks to be called when the - * program isn't handling @ref Ecore_Event_Group "events", @ref Ecore_Timer_Group - * "timers" or @ref Ecore_FD_Handler_Group "fd handlers". + * @brief The idler functionality in Ecore allows for callbacks to be called when the + * program isn't handling @ref Ecore_Event_Group "events", @ref Ecore_Timer_Group + * "timers", or @ref Ecore_FD_Handler_Group "fd handlers". * - * There are three types of idlers: Enterers, Idlers(proper) and Exiters. They - * are called, respectively, when the program is about to enter an idle state, + * There are three types of idlers: Enterers, Idlers(proper), and Exiters. They + * are called respectively when the program is about to enter an idle state, * when the program is in an idle state and when the program has just left an - * idle state and will begin processing @ref Ecore_Event_Group "events", @ref - * Ecore_Timer_Group "timers" or @ref Ecore_FD_Handler_Group "fd handlers". + * idle state and begins processing @ref Ecore_Event_Group "events", @ref + * Ecore_Timer_Group "timers", or @ref Ecore_FD_Handler_Group "fd handlers". * * Enterer callbacks are good for updating your program's state, if - * it has a state engine. Once all of the enterer handlers are - * called, the program will enter a "sleeping" state. + * it has a state engine. Once all of the enterer handlers are + * called, the program enters a "sleeping" state. * * Idler callbacks are called when the main loop has called all - * enterer handlers. They are useful for interfaces that require - * polling and timers would be too slow to use. + * enterer handlers. They are useful for interfaces that require + * polling and timers without which they would be too slow to use. * * Exiter callbacks are called when the main loop wakes up from an idle state. * @@ -1695,855 +2634,1064 @@ EAPI char *ecore_timer_dump(void); * continuously while the loop is "idle", using as much CPU as is * available to the process. * - * @note Idle state doesn't mean that the @b program is idle, but + * Idle state doesn't mean that the @b program is idle, but * that the main loop is idle. It doesn't have any timers, - * events, fd handlers or anything else to process (which in most + * events, fd handlers, or anything else to process (which in most * event driven programs also means that the @b program is * idle too, but it's not a rule). The program itself may be doing * a lot of processing in the idler, or in another thread, for * example. * - * Example with functions that deal with idle state: - * - * @li @ref ecore_idler_example_c - * - * @ingroup Ecore_Main_Loop_Group - * * @{ */ -typedef struct _Ecore_Idler Ecore_Idler; /**< A handle for idlers */ -typedef struct _Ecore_Idle_Enterer Ecore_Idle_Enterer; /**< A handle for idle enterers */ -typedef struct _Ecore_Idle_Exiter Ecore_Idle_Exiter; /**< A handle for idle exiters */ +typedef struct _Ecore_Idler Ecore_Idler; /**< @brief A handle for idlers */ +typedef struct _Ecore_Idle_Enterer Ecore_Idle_Enterer; /**< @brief A handle for idle enterers */ +typedef struct _Ecore_Idle_Exiter Ecore_Idle_Exiter; /**< @brief A handle for idle exiters */ /** - * Add an idler handler. - * @param func The function to call when idling. - * @param data The data to be passed to this @p func call. - * @return A idler handle if successfully added, @c NULL otherwise. + * @brief Adds an idler handler. + * + * @details This adds an idler handle to the event loop, returning a handle on + * success and @c NULL otherwise. The function @a func is called + * repeatedly while no other events are ready to be processed, as + * long as it returns @c 1 (or @c ECORE_CALLBACK_RENEW). A return of @c 0 + * (or @c ECORE_CALLBACK_CANCEL) deletes the idler. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * Add an idler handle to the event loop, returning a handle on - * success and @c NULL otherwise. The function @p func will be called - * repeatedly while no other events are ready to be processed, as - * long as it returns @c 1 (or ECORE_CALLBACK_RENEW). A return of @c 0 - * (or ECORE_CALLBACK_CANCEL) deletes the idler. + * @remarks Idlers are useful for progressively processing data without blocking. + * + * @param[in] func The function to call when idling + * @param[in] data The data to be passed to this @a func call + * @return A idler handle if successfully added, + * otherwise @c NULL * - * Idlers are useful for progressively prossessing data without blocking. */ EAPI Ecore_Idler *ecore_idler_add(Ecore_Task_Cb func, const void *data); /** - * Delete an idler callback from the list to be executed. - * @param idler The handle of the idler callback to delete - * @return The data pointer passed to the idler callback on success, @c NULL - * otherwise. + * @brief Deletes an idler callback from the list to be executed. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] idler The handle of the idler callback to delete + * @return The data pointer passed to the idler callback on success, + * otherwise @c NULL */ EAPI void *ecore_idler_del(Ecore_Idler *idler); +/** + * @brief Add an idle enterer handler. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks The function func will be called every time the main loop is entering + * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0 + * (or ECORE_CALLBACK_CANCEL) deletes the idle enterer. + * + * @param[in] func The function to call when entering an idle state. + * @param[in] data The data to be passed to the @p func call + * @return A handle to the idle enterer callback if successful. Otherwise, + * NULL is returned. + */ EAPI Ecore_Idle_Enterer *ecore_idle_enterer_add(Ecore_Task_Cb func, const void *data); -EAPI Ecore_Idle_Enterer *ecore_idle_enterer_before_add(Ecore_Task_Cb func, const void *data); -EAPI void *ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer); -EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(Ecore_Task_Cb func, const void *data); -EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter); +/** + * @brief Add an idle enterer handler at the start of the list so it gets called earlier than others. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks The function func will be called every time the main loop is entering + * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0 + * (or ECORE_CALLBACK_CANCEL) deletes the idle enterer. + * + * @param[in] func The function to call when entering an idle state. + * @param[in] data The data to be passed to the @p func call + * @return A handle to the idle enterer callback if successful. Otherwise, + * NULL is returned. + */ +EAPI Ecore_Idle_Enterer *ecore_idle_enterer_before_add(Ecore_Task_Cb func, const void *data); + +/** + * @brief Delete an idle enterer callback. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] idle_enterer The idle enterer to delete + * @return The data pointer passed to the idler enterer callback on success. + * NULL otherwise. + */ +EAPI void *ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer); + +/** + * @brief Add an idle exiter handler. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks The function func will be called every time the main loop is exiting + * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0 + * (or ECORE_CALLBACK_CANCEL) deletes the idle exiter. + * + * @param[in] func The function to call when exiting an idle state. + * @param[in] data The data to be passed to the @p func call + * @return A handle to the idle exiter callback on success. NULL otherwise. + */ +EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(Ecore_Task_Cb func, const void *data); + +/** + * @brief Delete an idle exiter handler from the list to be run on exiting idle state. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] idle_exiter The idle exiter to delete + * @return The data pointer that was being being passed to the handler if + * successful. NULL otherwise. + */ +EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter); /** * @} */ /** - * @defgroup Ecore_Thread_Group Ecore Thread functions + * @defgroup Ecore_Pipe_Group Ecore Pipe Wrapper + * @ingroup Ecore_Main_Loop_Group * - * Facilities to run heavy tasks in different threads to avoid blocking - * the main loop. + * @brief This group discusses the functions that wrap the write / read functions of the pipe to easily + * integrate its use into ecore's main loop. * - * The EFL is, for the most part, not thread safe. This means that if you - * have some task running in another thread and you have, for example, an - * Evas object to show the status progress of this task, you cannot update - * the object from within the thread. This can only be done from the main - * thread, the one running the main loop. This problem can be solved - * by running a thread that sends messages to the main one using an - * @ref Ecore_Pipe_Group "Ecore_Pipe", but when you need to handle other - * things like cancelling the thread, your code grows in complexity and gets - * much harder to maintain. + * @remarks The ecore_pipe_add() function creates file descriptors (sockets + * on Windows) and attaches a handle to the ecore main loop. That + * handle is called when data is read in the pipe. To write data in + * the pipe, just call ecore_pipe_write(). When you are done, just + * call ecore_pipe_del(). * - * Ecore Thread is here to solve that problem. It is @b not a simple wrapper - * around standard POSIX threads (or the equivalent in other systems) and - * it's not meant to be used to run parallel tasks throughout the entire - * duration of the program, especially when these tasks are performance - * critical, as Ecore manages these tasks using a pool of threads based on - * system configuration. + * @{ + */ + +typedef struct _Ecore_Pipe Ecore_Pipe; /**< @brief A handle for pipes */ + +/** + * @typedef Ecore_Pipe_Cb Ecore_Pipe_Cb + * @brief Called to send data written to the pipe. + */ +typedef void (*Ecore_Pipe_Cb)(void *data, void *buffer, unsigned int nbyte); + +/** + * @brief Create two file descriptors (sockets on Windows). * - * What Ecore Thread does, is make it a lot easier to dispatch a worker - * function to perform some heavy task and then get the result once it - * completes, without blocking the application's UI. In addition, cancelling - * and rescheduling comes practically for free and the developer needs not - * worry about how many threads are launched, since Ecore will schedule - * them according to the number of processors the system has and maximum - * amount of concurrent threads set for the application. + * @details Add a callback that will be called when the file descriptor that + * is listened receives data. An event is also put in the event + * queue when data is received. * - * At the system level, Ecore will start a new thread on an as-needed basis - * until the maximum set is reached. When no more threads can be launched, - * new worker functions will be queued in a waiting list until a thread - * becomes available. This way, system threads will be shared throughout - * different worker functions, but running only one at a time. At the same - * time, a worker function that is rescheduled may be run on a different - * thread the next time. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * The ::Ecore_Thread handler has two meanings, depending on what context - * it is on. The one returned when starting a worker with any of the - * functions ecore_thread_run() or ecore_thread_feedback_run() is an - * identifier of that specific instance of the function and can be used from - * the main loop with the ecore_thread_cancel() and ecore_thread_check() - * functions. This handler must not be shared with the worker function - * function running in the thread. This same handler will be the one received - * on the @c end, @c cancel and @c feedback callbacks. + * @param[in] handler The handler called when data is received. + * @param[in] data Data to pass to @p handler when it is called. + * @return A newly created Ecore_Pipe object if successful. + * @c NULL otherwise. + */ +EAPI Ecore_Pipe *ecore_pipe_add(Ecore_Pipe_Cb handler, const void *data); + +/** + * @brief Free an Ecore_Pipe object created with ecore_pipe_add(). * - * The worker function, that's the one running in the thread, also receives - * an ::Ecore_Thread handler that can be used with ecore_thread_cancel() and - *ecore_thread_check(), sharing the flag with the main loop. But this - * handler is also associated with the thread where the function is running. - * This has strong implications when working with thread local data. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * There are two kinds of worker threads Ecore handles: simple, or short, - * workers and feedback workers. + * @param[in] p The Ecore_Pipe object to be freed. + * @return The pointer to the private data + */ +EAPI void *ecore_pipe_del(Ecore_Pipe *p); + +/** + * @brief Write on the file descriptor the data passed as parameter. * - * The first kind is for simple functions that perform a - * usually small but time consuming task. Ecore will run this function in - * a thread as soon as one becomes available and notify the calling user of - * its completion once the task is done. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * The following image shows the flow of a program running four tasks on - * a pool of two threads. + * @param[in] p The Ecore_Pipe object. + * @param[in] buffer The data to write into the pipe. + * @param[in] nbytes The size of the @p buffer in bytes + * @return #EINA_TRUE on a successful write, @c EINA_FALSE on error. + */ +EAPI Eina_Bool ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes); + +/** + * @brief Close the write end of an Ecore_Pipe object created with ecore_pipe_add(). * - * @image html ecore_thread.png - * @image rtf ecore_thread.png - * @image latex ecore_thread.eps width=\textwidth + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * For larger tasks that may require continuous communication with the main - * program, the feedback workers provide the same functionality plus a way - * for the function running in the thread to send messages to the main - * thread. + * @param[in] p The Ecore_Pipe object. + */ +EAPI void ecore_pipe_write_close(Ecore_Pipe *p); + +/** + * @brief Close the read end of an Ecore_Pipe object created with + * ecore_pipe_add(). * - * The next diagram omits some details shown in the previous one regarding - * how threads are spawned and tasks are queued, but illustrates how feedback - * jobs communicate with the main loop and the special case of threads - * running out of pool. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @image html ecore_thread_feedback.png - * @image rtf ecore_thread_feedback.png - * @image latex ecore_thread_feedback.eps width=\textwidth + * @param[in] p The Ecore_Pipe object. + */ +EAPI void ecore_pipe_read_close(Ecore_Pipe *p); + +/** + * @brief Start monitoring again the pipe for reading. See ecore_pipe_freeze() + * for stopping the monitoring activity. This will not work if + * ecore_pipe_read_close() was previously called on the same pipe. + * + * @since 1.1 + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * See an overview example in @ref ecore_thread_example_c. + * @param[in] p The Ecore_Pipe object. + */ +EAPI void ecore_pipe_thaw(Ecore_Pipe *p); + +/** + * @brief Stop monitoring if necessary the pipe for reading. + * @since 1.1 + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * + * @param[in] p The Ecore_Pipe object. + * + * @see ecore_pipe_thaw() for monitoring it again. + * + */ +EAPI void ecore_pipe_freeze(Ecore_Pipe *p); + +/** + * @brief Wait from another thread on the read side of a pipe. + * @since 1.1 + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks Negative value for @p wait means infite wait. + * + * @param[in] p The pipe to watch on. + * @param[in] message_count The minimal number of message to wait before exiting. + * @param[in] wait The amount of time in second to wait before exiting. + * @return the number of message catched during that wait call. + * + */ +EAPI int ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait); + +/** + * @} + */ + +/** + * @internal + * @defgroup Ecore_Throttle_Group Ecore Throttle * @ingroup Ecore_Main_Loop_Group * * @{ */ -typedef struct _Ecore_Thread Ecore_Thread; /**< A handle for threaded jobs */ +/** + * @brief Increase throttle amount + * + * @details This will increase or decrease (if @p amount is positive or negative) the + * amount of "voluntary throttling" ecore will do to its main loop while + * running. This is intended to be used to limit animations and wakeups when + * in a strict power management state. The higher the current throttle value + * (which can be retrieved by ecore_throttle_get() ), the more throttling + * takes place. If the current throttle value is 0, then no throttling takes + * place at all. + * + * @remarks The value represents how long the ecore main loop will sleep (in seconds) + * before it goes into a fully idle state waiting for events, input or + * timing events to wake it up. For example, if the current throttle level + * is 0.5, then after every time the main loop cycles and goes into idle + * affter processing all events, the main loop will explicitly sleep for 0.5 + * seconds before sitting and waiting for incoming events or timeouts, thus + * preventing animation, async IO and network handling etc. for that period + * of time. Of course these events, data and timeouts will be buffered, + * thus not losing anything, simply delaying when they get handled by the + * throttle value. + * + * Example: + * @code + * void enter_powersave(void) { + * ecore_throttle_adjust(0.2); + * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); + * } + * + * void enter_deep_powersave(void) { + * ecore_throttle_adjust(0.5); + * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); + * } + * + * void exit_powersave(void) { + * ecore_throttle_adjust(-0.2); + * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); + * } + * + * void exit_deep_powersave(void) { + * ecore_throttle_adjust(-0.5); + * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); + * } + * @endcode + * + * @param[in] amount Amount (in seconds) to adjust by + */ + +EAPI void ecore_throttle_adjust(double amount); /** - * @typedef Ecore_Thread_Cb Ecore_Thread_Cb - * A callback used by Ecore_Thread helper. + * @brief Get current throttle level + * + * @remarks This gets the current throttling level, which can be adjusted by + * ecore_throttle_adjust(). The value is in seconds. + * + * @return The current throttle level + * + * @see ecore_throttle_adjust() for more information. + * */ -typedef void (*Ecore_Thread_Cb)(void *data, Ecore_Thread *thread); +EAPI double ecore_throttle_get(void); + /** - * @typedef Ecore_Thread_Notify_Cb Ecore_Thread_Notify_Cb - * A callback used by the main loop to receive data sent by an - * @ref Ecore_Thread_Group. + * @} + */ + +/** + * @defgroup Ecore_Poller_Group Ecore Poller + * @ingroup Ecore_Main_Loop_Group + * + * @brief Ecore poller provides infrastructure for the creation of pollers. + * + * Pollers are, in essence, callbacks that share a single timer per type. Because not + * all pollers need to be called at the same frequency the user may specify the + * frequency in ticks(each expiration of the shared timer is called a tick, in + * ecore poller parlance) for each added poller. Ecore pollers should only be + * used when the poller doesn't have specific requirements on the exact times + * to poll. + * + * This architecture means that the main loop is only woken up once to handle + * all pollers of that type, this saves power as the CPU has more of a + * chance to go into a low power state the longer it is asleep, so this + * should be used in situations where power usage is a concern. + * + * For now only 1 core poller type is supported: @c ECORE_POLLER_CORE. + * The default interval for @c ECORE_POLLER_CORE is @c 0.125(or 1/8th) second. + * + * The creation of a poller is extremely simple and only requires one line: + * @code + * ecore_poller_add(ECORE_POLLER_CORE, 1, my_poller_function, NULL); + * @endcode + * This sample creates a poller to call @a my_poller_function at every tick with + * @c NULL as data. + * + * @{ + */ + +/** + * @enum _Ecore_Poller_Type + * @brief Enumeration that defines the frequency of ticks for the poller. + */ +enum _Ecore_Poller_Type /* Poller types */ +{ + ECORE_POLLER_CORE = 0, /**< The core poller interval */ +#ifdef __linux + ECORE_POLLER_LAZY = 1, /**< Core poller based on timerfd, + timer is deferrable in case the kernel supports it (no fire at IDLE time) */ +#endif + ECORE_POLLER_TYPE_MAX +}; + +/** + * @brief typedef to enum _Ecore_Poller_Type + */ +typedef enum _Ecore_Poller_Type Ecore_Poller_Type; + +typedef struct _Ecore_Poller Ecore_Poller; /**< @brief A handle for pollers */ + +/** + * @brief Sets the time(in seconds) between ticks for the given poller type. + * + * @details This adjusts the time between ticks of the given timer type defined by + * @a type to the time period defined by @a poll_time. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] type The poller type to adjust + * @param[in] poll_time The time(in seconds) between ticks of the timer + * + */ +EAPI void ecore_poller_poll_interval_set(Ecore_Poller_Type type, double poll_time); + +/** + * @brief Gets the time(in seconds) between ticks for the given poller type. + * + * @details This gets the time between ticks of the specified poller timer. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] type The poller type to query + * @return The time in seconds between ticks of the poller timer + * + */ +EAPI double ecore_poller_poll_interval_get(Ecore_Poller_Type type); + +/** + * @brief Changes the polling interval rate of @a poller. + * + * @details This allows the changing of a poller's polling interval. It is useful when + * you want to alter a poll rate without deleting and re-creating a poller. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] poller The Ecore_Poller to change the interval of + * @param[in] interval The tick interval to set, must be a power of 2 and <= 32768 + * @return @c true on success, otherwise @c false on failure + * + */ +EAPI Eina_Bool ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval); + +/** + * @brief Gets the polling interval rate of @a poller. + * + * @details This returns a poller's polling interval, otherwise @c 0 on error. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @param[in] poller The Ecore_Poller to change the interval of + * @return The interval, in ticks, that @a poller polls at + * + */ +EAPI int ecore_poller_poller_interval_get(Ecore_Poller *poller); + +/** + * @brief Creates a poller to call the given function at a particular tick interval. + * + * @details This function adds @a func as a poller callback that is called every @a + * interval ticks together with other pollers of type @a type. @a func is + * passed the @a data pointer as a parameter. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks The @a interval must be between @c 1 and @c 32768 inclusive, and must be a power of + * @c 2 (i.e. 1, 2, 4, 8, 16, ... 16384, 32768). The exact tick in which @a func + * is called is undefined, as only the interval between calls can be + * defined. Ecore endeavors to keep pollers synchronized and calls as + * many in 1 wakeup event as possible. If @a interval is not a power of @c 2, the + * closest power of @c 2 greater than @a interval is used. + * + * @remarks When the poller @a func is called, it must return a value of either + * @c ECORE_CALLBACK_RENEW(or @c 1) or @c ECORE_CALLBACK_CANCEL(or @c 0). If it + * returns @c 1, it is called again at the next tick, or if it returns + * @c 0 it is deleted automatically making any references/handles for it + * invalid. + * + * @param[in] type The ticker type to attach the poller to \n + * Must be @c ECORE_POLLER_CORE. + * @param[in] interval The poll interval + * @param[in] func The poller function + * @param[in] data The data to pass to @a func when it is called + * @return A poller object on success, + * otherwise @c NULL on failure + * + */ +EAPI Ecore_Poller *ecore_poller_add(Ecore_Poller_Type type, int interval, Ecore_Task_Cb func, const void *data); + +/** + * @brief Deletes the specified poller from the timer list. + * + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks @a poller must be a valid handle. If the poller function has already + * returned @c 0, the handle is no longer valid (and does not need to be deleted). + * + * @param[in] poller The poller to delete + * @return The data pointer set for the timer when @ref ecore_poller_add is called on success, + * otherwise @c NULL on failure + */ +EAPI void *ecore_poller_del(Ecore_Poller *poller); + +/** + * @} + */ + +/** + * @defgroup Ecore_Animator_Group Ecore Animator + * @ingroup Ecore_Main_Loop_Group + * + * @brief Ecore animators are a helper to simplify creating animations. + * + * Creating an animation is as simple as saying for how long it + * should be run and having a callback that does the animation, + * something like this: + * @code + * static Eina_Bool + * _do_animation(void *data, double pos) + * { + * evas_object_move(data, 100 * pos, 100 * pos); + * ... do some more animating ... + * } + * ... + * ecore_animator_timeline_add(2, _do_animation, my_evas_object); + * @endcode + * + * In the sample above we create an animation to move + * @c my_evas_object from position (0,0) to (100,100) in @c 2 seconds. + * + * If your animation runs for an unspecified amount of time you + * can use ecore_animator_add(), which is like using + * ecore_timer_add() with the interval being the + * @ref ecore_animator_frametime_set "framerate". Note that this has + * tangible benefits of creating a timer for each animation in terms + * of performance. + * + * @{ + */ + +/** + * @brief handle for ecore animator. + */ +typedef struct _Ecore_Animator Ecore_Animator; + +/** + * @enum _Ecore_Pos_Map + * @brief Enumeration that defines the position mappings for the animation. + */ +enum _Ecore_Pos_Map /* Position mappings */ +{ + ECORE_POS_MAP_LINEAR, /**< Linear 0.0 -> 1.0 */ + ECORE_POS_MAP_ACCELERATE, /**< Start slow then speed up */ + ECORE_POS_MAP_DECELERATE, /**< Start fast then slow down */ + ECORE_POS_MAP_SINUSOIDAL, /**< Start slow, speed up then slow down at the end */ + ECORE_POS_MAP_ACCELERATE_FACTOR, /**< Start slow then speed up, v1 being a power factor, @c 0.0 being linear, @c 1.0 being normal accelerate, @c 2.0 being much more pronounced accelerate (squared), @c 3.0 being cubed, and so on */ + ECORE_POS_MAP_DECELERATE_FACTOR, /**< Start fast then slow down, v1 being a power factor, @c 0.0 being linear, @c 1.0 being normal decelerate, @c 2.0 being much more pronounced decelerate (squared), @c 3.0 being cubed, and so on */ + ECORE_POS_MAP_SINUSOIDAL_FACTOR, /**< Start slow, speed up then slow down at the end, v1 being a power factor, @c 0.0 being linear, @c 1.0 being normal sinusoidal, @c 2.0 being much more pronounced sinusoidal (squared), @c 3.0 being cubed, and so on */ + ECORE_POS_MAP_DIVISOR_INTERP, /**< Start at gradient * v1, interpolated via power of v2 curve */ + ECORE_POS_MAP_BOUNCE, /**< Start at @c 0.0 then "drop" like a ball bouncing to the ground at @c 1.0, and bounce v2 times, with decay factor of v1 */ + ECORE_POS_MAP_SPRING, /**< Start at @c 0.0 then "wobble" like a spring with rest position @c 1.0, and wobble v2 times, with decay factor of v1 */ + ECORE_POS_MAP_CUBIC_BEZIER /**< Follow the cubic-bezier curve calculated with the points (x1, y1), (x2, y2) */ +}; + +/** + * @brief typedef to enum _Ecore_Pos_Map + */ +typedef enum _Ecore_Pos_Map Ecore_Pos_Map; + +/** + * @enum _Ecore_Animator_Source + * @brief Enumeration that defines the timing sources for animators. */ -typedef void (*Ecore_Thread_Notify_Cb)(void *data, Ecore_Thread *thread, void *msg_data); +enum _Ecore_Animator_Source /* Timing sources for animators */ +{ + ECORE_ANIMATOR_SOURCE_TIMER, /**< The default system clock/timer based animator that ticks every "frametime" seconds */ + ECORE_ANIMATOR_SOURCE_CUSTOM /**< A custom animator trigger which ticks when you call ecore_animator_trigger() */ +}; /** - * Schedule a task to run in a parallel thread to avoid locking the main loop - * - * @param func_blocking The function that should run in another thread. - * @param func_end Function to call from main loop when @p func_blocking - * completes its task successfully (may be NULL) - * @param func_cancel Function to call from main loop if the thread running - * @p func_blocking is cancelled or fails to start (may be NULL) - * @param data User context data to pass to all callbacks. - * @return A new thread handler, or @c NULL on failure. - * - * This function will try to create a new thread to run @p func_blocking in, - * or if the maximum number of concurrent threads has been reached, will - * add it to the pending list, where it will wait until a thread becomes - * available. The return value will be an ::Ecore_Thread handle that can - * be used to cancel the thread before its completion. - * - * @note This function should always return immediately, but in the rare - * case that Ecore is built with no thread support, @p func_blocking will - * be called here, actually blocking the main loop. - * - * Once a thread becomes available, @p func_blocking will be run in it until - * it finishes, then @p func_end is called from the thread containing the - * main loop to inform the user of its completion. While in @p func_blocking, - * no functions from the EFL can be used, except for those from Eina that are - * marked to be thread-safe. Even for the latter, caution needs to be taken - * if the data is shared across several threads. - * - * @p func_end will be called from the main thread when @p func_blocking ends, - * so here it's safe to use anything from the EFL freely. - * - * The thread can also be cancelled before its completion calling - *ecore_thread_cancel(), either from the main thread or @p func_blocking. - * In this case, @p func_cancel will be called, also from the main thread - * to inform of this happening. If the thread could not be created, this - * function will be called and it's @c thread parameter will be NULL. It's - * also safe to call any EFL function here, as it will be running in the - * main thread. - * - * Inside @p func_blocking, it's possible to call ecore_thread_reschedule() - * to tell Ecore that this function should be called again. - * - * Be aware that no assumptions can be made about the order in which the - * @p func_end callbacks for each task will be called. Once the function is - * running in a different thread, it's the OS that will handle its running - * schedule, and different functions may take longer to finish than others. - * Also remember that just starting several tasks together doesn't mean they - * will be running at the same time. Ecore will schedule them based on the - * number of threads available for the particular system it's running in, - * so some of the jobs started may be waiting until another one finishes - * before it can execute its own @p func_blocking. - * - * @see ecore_thread_feedback_run() - * @see ecore_thread_cancel() - * @see ecore_thread_reschedule() - * @see ecore_thread_max_set() + * @brief typedef to enum _Ecore_Animator_Source */ -EAPI Ecore_Thread *ecore_thread_run(Ecore_Thread_Cb func_blocking, Ecore_Thread_Cb func_end, Ecore_Thread_Cb func_cancel, const void *data); +typedef enum _Ecore_Animator_Source Ecore_Animator_Source; + /** - * Launch a thread to run a task that can talk back to the main thread - * - * @param func_heavy The function that should run in another thread. - * @param func_notify Function that receives the data sent from the thread - * @param func_end Function to call from main loop when @p func_heavy - * completes its task successfully - * @param func_cancel Function to call from main loop if the thread running - * @p func_heavy is cancelled or fails to start - * @param data User context data to pass to all callback. - * @param try_no_queue If you want to run outside of the thread pool. - * @return A new thread handler, or @c NULL on failure. - * - * See ecore_thread_run() for a general description of this function. - * - * The difference with the above is that ecore_thread_run() is meant for - * tasks that don't need to communicate anything until they finish, while - * this function is provided with a new callback, @p func_notify, that will - * be called from the main thread for every message sent from @p func_heavy - * with ecore_thread_feedback(). - * - * Like with ecore_thread_run(), a new thread will be launched to run - * @p func_heavy unless the maximum number of simultaneous threads has been - * reached, in which case the function will be scheduled to run whenever a - * running task ends and a thread becomes free. But if @p try_no_queue is - * set, Ecore will first try to launch a thread outside of the pool to run - * the task. If it fails, it will revert to the normal behaviour of using a - * thread from the pool as if @p try_no_queue had not been set. - * - * Keep in mind that Ecore handles the thread pool based on the number of - * CPUs available, but running a thread outside of the pool doesn't count for - * this, so having too many of them may have drastic effects over the - * program's performance. - * - * @see ecore_thread_feedback() - * @see ecore_thread_run() - * @see ecore_thread_cancel() - * @see ecore_thread_reschedule() - * @see ecore_thread_max_set() + * @typedef Ecore_Timeline_Cb Ecore_Timeline_Cb + * @brief The boolean type for a callback run for a task (animators with runtimes) */ -EAPI Ecore_Thread *ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy, Ecore_Thread_Notify_Cb func_notify, - Ecore_Thread_Cb func_end, Ecore_Thread_Cb func_cancel, - const void *data, Eina_Bool try_no_queue); +typedef Eina_Bool (*Ecore_Timeline_Cb)(void *data, double pos); + /** - * Cancel a running thread. - * - * @param thread The thread to cancel. - * @return Will return @c EINA_TRUE if the thread has been cancelled, - * @c EINA_FALSE if it is pending. + * @brief Adds an animator to call @a func at every animation tick during main + * loop execution. * - * This function can be called both in the main loop or in the running thread. + * @details This function adds an animator and returns its handle on success, and @c NULL + * on failure. The function @a func is called every N seconds where N is + * the @a frametime interval set by ecore_animator_frametime_set(). The + * function is passed the @a data pointer as its parameter. * - * This function cancels a running thread. If @p thread can be immediately - * cancelled (it's still pending execution after creation or rescheduling), - * then the @c cancel callback will be called, @p thread will be freed and - * the function will return @c EINA_TRUE. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * If the thread is already running, then this function returns @c EINA_FALSE - * after marking the @p thread as pending cancellation. For the thread to - * actually be terminated, it needs to return from the user function back - * into Ecore control. This can happen in several ways: - * @li The function ends and returns normally. If it hadn't been cancelled, - * @c func_end would be called here, but instead @c func_cancel will happen. - * @li The function returns after requesting to be rescheduled with - * ecore_thread_reschedule(). - * @li The function is prepared to leave early by checking if - * ecore_thread_check() returns @c EINA_TRUE. + * @remarks When the animator @a func is called, it must return a value of either @c 1 or + * @c 0. If it returns @c 1 (or @c ECORE_CALLBACK_RENEW), it is called again at + * the next tick, or if it returns @c 0 (or @c ECORE_CALLBACK_CANCEL) it is + * deleted automatically making any references/handles for it invalid. * - * The user function can cancel itself by calling ecore_thread_cancel(), but - * it should always use the ::Ecore_Thread handle passed to it and never - * share it with the main loop thread by means of shared user data or any - * other way. + * @remarks The default @a frametime value is 1/30th of a second. * - * @p thread will be freed and should not be used again if this function - * returns @c EINA_TRUE or after the @c func_cancel callback returns. + * @param[in] func The function to call when it ticks off + * @param[in] data The data to pass to the function + * @return A handle to the new animator * - * @see ecore_thread_check() + * @see ecore_animator_timeline_add() + * @see ecore_animator_frametime_set() */ -EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread *thread); +EAPI Ecore_Animator *ecore_animator_add(Ecore_Task_Cb func, const void *data); + /** - * Checks if a thread is pending cancellation + * @brief Adds an animator that runs for a limited time. * - * @param thread The thread to test. - * @return @c EINA_TRUE if the thread is pending cancellation, - * @c EINA_FALSE if it is not. + * @details This function is just like ecore_animator_add() except that the animator only + * runs for a limited time specified in seconds by @a runtime. Once the + * runtime of the animator has elapsed (animator finished) it is automatically + * deleted. The callback function @a func can return @c ECORE_CALLBACK_RENEW + * to keep the animator running or @c ECORE_CALLBACK_CANCEL to stop it and have + * it deleted automatically at any time. * - * This function can be called both in the main loop or in the running thread. - * - * When ecore_thread_cancel() is called on an already running task, the - * thread is marked as pending cancellation. This function returns @c EINA_TRUE - * if this mark is set for the given @p thread and can be used from the - * main loop thread to check if a still active thread has been cancelled, - * or from the user function running in the thread to check if it should - * stop doing what it's doing and return early, effectively cancelling the - * task. - * - * @see ecore_thread_cancel() - */ -EAPI Eina_Bool ecore_thread_check(Ecore_Thread *thread); -/** - * Sends data from the worker thread to the main loop + * @since 1.1.0 * - * @param thread The current ::Ecore_Thread context to send data from - * @param msg_data Data to be transmitted to the main loop - * @return @c EINA_TRUE if @p msg_data was successfully sent to main loop, - * @c EINA_FALSE if anything goes wrong. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * You should use this function only in the @c func_heavy call. + * @remarks The @a func is ALSO passed a position parameter that has a value + * from @c 0.0 to @c 1.0 to indicate where along the timeline (@c 0.0 for start, @c 1.0 for end) + * is the animator run at. If the callback wishes not to have a linear + * transition it can "map" this value to one of the several curves and mappings + * via ecore_animator_pos_map(). * - * Only the address to @p msg_data will be sent and once this function - * returns @c EINA_TRUE, the job running in the thread should never touch the - * contents of it again. The data sent should be malloc()'ed or something - * similar, as long as it's not memory local to the thread that risks being - * overwritten or deleted once it goes out of scope or the thread finishes. + * @remarks The default @a frametime value is 1/30th of a second. * - * Care must be taken that @p msg_data is properly freed in the @c func_notify - * callback set when creating the thread. + * @param[in] runtime The time to run in seconds + * @param[in] func The function to call when it ticks off + * @param[in] data The data to pass to the function + * @return A handle to the new animator * - * @see ecore_thread_feedback_run() + * @see ecore_animator_add() + * @see ecore_animator_pos_map() */ -EAPI Eina_Bool ecore_thread_feedback(Ecore_Thread *thread, const void *msg_data); +EAPI Ecore_Animator *ecore_animator_timeline_add(double runtime, Ecore_Timeline_Cb func, const void *data); + /** - * Asks for the function in the thread to be called again at a later time - * - * @param thread The current ::Ecore_Thread context to rescheduled - * @return @c EINA_TRUE if the task was successfully rescheduled, - * @c EINA_FALSE if anything goes wrong. - * - * This function should be called only from the same function represented - * by @p thread. + * @brief Deletes the specified animator from the animator list. * - * Calling this function will mark the thread for a reschedule, so as soon - * as it returns, it will be added to the end of the list of pending tasks. - * If no other tasks are waiting or there are sufficient threads available, - * the rescheduled task will be launched again immediately. - * - * This should never return @c EINA_FALSE, unless it was called from the wrong - * thread or with the wrong arguments. - * - * The @c func_end callback set when the thread is created will not be - * called until the function in the thread returns without being rescheduled. - * Similarly, if the @p thread is cancelled, the reschedule will not take - * effect. - */ -EAPI Eina_Bool ecore_thread_reschedule(Ecore_Thread *thread); -/** - * Gets the number of active threads running jobs + * @details This deletes the specified @a animator from the set of animators that are + * executed during main loop execution. This function returns the data + * parameter that is being passed to the callback on success, otherwise @c NULL on + * failure. After this call returns the specified animator object @a animator + * is invalid and should not be used again. It does not get called again after + * deletion. * - * @return Number of active threads running jobs + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * This returns the number of threads currently running jobs of any type - * through the Ecore_Thread API. + * @param[in] animator The animator to delete + * @return The data pointer set for the animator on add * - * @note Jobs started through the ecore_thread_feedback_run() function with - * the @c try_no_queue parameter set to @c EINA_TRUE will not be accounted for - * in the return of this function unless the thread creation fails and it - * falls back to using one from the pool. */ -EAPI int ecore_thread_active_get(void); +EAPI void *ecore_animator_del(Ecore_Animator *animator); + /** - * Gets the number of short jobs waiting for a thread to run - * - * @return Number of pending threads running "short" jobs + * @brief Suspends the specified animator. * - * This returns the number of tasks started with ecore_thread_run() that are - * pending, waiting for a thread to become available to run them. - */ -EAPI int ecore_thread_pending_get(void); -/** - * Gets the number of feedback jobs waiting for a thread to run + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @return Number of pending threads running "feedback" jobs + * @remarks The specified @a animator is temporarily removed from the set of + * animators that are executed during the main loop. * - * This returns the number of tasks started with ecore_thread_feedback_run() - * that are pending, waiting for a thread to become available to run them. - */ -EAPI int ecore_thread_pending_feedback_get(void); -/** - * Gets the total number of pending jobs + * @remarks Freezing an animator doesn't freeze accounting of how long that + * animator has been running. Therefore if the animator is created with + * ecore_animator_timeline_add() the @a pos argument given to the callback + * increases as if the animator hadn't been frozen and the animator may + * have its execution halted if @a runtime elapses. * - * @return Number of pending threads running jobs + * @param[in] animator The animator to delete * - * Same as the sum of ecore_thread_pending_get() and - *ecore_thread_pending_feedback_get(). */ -EAPI int ecore_thread_pending_total_get(void); +EAPI void ecore_animator_freeze(Ecore_Animator *animator); + /** - * Gets the maximum number of threads that can run simultaneously - * - * @return Max possible number of Ecore_Thread's running concurrently + * @brief Restores execution of the specified animator. * - * This returns the maximum number of Ecore_Thread's that may be running at - * the same time. If this number is reached, new jobs started by either - *ecore_thread_run() or ecore_thread_feedback_run() will be added to the - * respective pending queue until one of the running threads finishes its - * task and becomes available to run a new one. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * By default, this will be the number of available CPUs for the - * running program (as returned by eina_cpu_count()), or 1 if this value - * could not be fetched. + * @remarks The specified @a animator is put back in the set of animators that are + * executed during the main loop. * - * @see ecore_thread_max_set() - * @see ecore_thread_max_reset() - */ -EAPI int ecore_thread_max_get(void); -/** - * Sets the maximum number of threads allowed to run simultaneously - * - * @param num The new maximum + * @param[in] animator The animator to delete * - * This sets a new value for the maximum number of concurrently running - * Ecore_Thread's. It @b must an integer between 1 and (16 * @c x), where @c x - * is the number for CPUs available. - * - * @see ecore_thread_max_get() - * @see ecore_thread_max_reset() */ -EAPI void ecore_thread_max_set(int num); +EAPI void ecore_animator_thaw(Ecore_Animator *animator); + /** - * Resets the maximum number of concurrently running threads to the default + * @brief Sets the animator call interval in seconds. * - * This resets the value returned by ecore_thread_max_get() back to its - * default. + * @details This function sets the time interval (in seconds) between animator ticks. + * At every tick the callback of every existing animator is called. * - * @see ecore_thread_max_get() - * @see ecore_thread_max_set() - */ -EAPI void ecore_thread_max_reset(void); -/** - * Gets the number of threads available for running tasks + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @return The number of available threads + * @remarks Too small a value may cause performance issues and too high a + * value may cause your animation to look "jerky". * - * Same as doing ecore_thread_max_get() - ecore_thread_active_get(). + * @remarks The default @a frametime value is 1/30th of a second. * - * This function may return a negative number only in the case the user - * changed the maximum number of running threads while other tasks are - * running. - */ -EAPI int ecore_thread_available_get(void); -/** - * Adds some data to a hash local to the thread - * - * @param thread The thread context the data belongs to - * @param key The name under which the data will be stored - * @param value The data to add - * @param cb Function to free the data when removed from the hash - * @param direct If true, this will not copy the key string (like - * eina_hash_direct_add()) - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. - * - * Ecore Thread has a mechanism to share data across several worker functions - * that run on the same system thread. That is, the data is stored per - * thread and for a worker function to have access to it, it must be run - * by the same thread that stored the data. - * - * When there are no more workers pending, the thread will be destroyed - * along with the internal hash and any data left in it will be freed with - * the @p cb function given. - * - * This set of functions is useful to share things around several instances - * of a function when that thing is costly to create and can be reused, but - * may only be used by one function at a time. - * - * For example, if you have a program doing requisitions to a database, - * these requisitions can be done in threads so that waiting for the - * database to respond doesn't block the UI. Each of these threads will - * run a function, and each function will be dependent on a connection to - * the database, which may not be able to handle more than one request at - * a time so for each running function you will need one connection handle. - * The options then are: - * @li Each function opens a connection when it's called, does the work and - * closes the connection when it finishes. This may be costly, wasting a lot - * of time on resolving hostnames, negotiating permissions and allocating - * memory. - * @li Open the connections in the main loop and pass it to the threads - * using the data pointer. Even worse, it's just as costly as before and now - * it may even be kept with connections open doing nothing until a thread - * becomes available to run the function. - * @li Have a way to share connection handles, so that each instance of the - * function can check if an available connection exists, and if it doesn't, - * create one and add it to the pool. When no more connections are needed, - * they are all closed. - * - * The last option is the most efficient, but it requires a lot of work to - * implement properly. Using thread local data helps to achieve the same - * result while avoiding doing all the tracking work on your code. The way - * to use it would be, at the worker function, to ask for the connection - * with ecore_thread_local_data_find() and if it doesn't exist, then open - * a new one and save it with ecore_thread_local_data_add(). Do the work and - * forget about the connection handle, when everything is done the function - * just ends. The next worker to run on that thread will check if a - * connection exists and find that it does, so the process of opening a - * new one has been spared. When no more workers exist, the thread is - * destroyed and the callback used when saving the connection will be called - * to close it. - * - * This function adds the data @p value to the thread data under the given - * @p key. - * No other value in the hash may have the same @p key. If you need to - * change the value under a @p key, or you don't know if one exists already, - * you can use ecore_thread_local_data_set(). - * - * Neither @p key nor @p value may be @c NULL and @p key will be copied in the - * hash, unless @p direct is set, in which case the string used should not - * be freed until the data is removed from the hash. - * - * The @p cb function will be called when the data in the hash needs to be - * freed, be it because it got deleted with ecore_thread_local_data_del() or - * because @p thread was terminated and the hash destroyed. This parameter - * may be NULL, in which case @p value needs to be manually freed after - * removing it from the hash with either ecore_thread_local_data_del() or - * ecore_thread_local_data_set(), but it's very unlikely that this is what - * you want. - * - * This function, and all of the others in the @c ecore_thread_local_data - * family of functions, can only be called within the worker function running - * in the thread. Do not call them from the main loop or from a thread - * other than the one represented by @p thread. + * @param[in] frametime The time in seconds between animator ticks * - * @see ecore_thread_local_data_set() - * @see ecore_thread_local_data_find() - * @see ecore_thread_local_data_del() */ -EAPI Eina_Bool ecore_thread_local_data_add(Ecore_Thread *thread, const char *key, void *value, - Eina_Free_Cb cb, Eina_Bool direct); +EAPI void ecore_animator_frametime_set(double frametime); + /** - * Sets some data in the hash local to the given thread + * @brief Gets the animator call interval in seconds. * - * @param thread The thread context the data belongs to - * @param key The name under which the data will be stored - * @param value The data to add - * @param cb Function to free the data when removed from the hash + * @details This function retrieves the time in seconds between animator ticks. * - * If no data exists in the hash under the @p key, this function adds - * @p value in the hash under the given @p key and returns NULL. - * The key itself is copied. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * If the hash already contains something under @p key, the data will be - * replaced by @p value and the old value will be returned. + * @return The time in seconds between animator ticks * - * @c NULL will also be returned if either @p key or @p value are @c NULL, or - * if an error occurred. - * - * This function, and all of the others in the @c ecore_thread_local_data - * family of functions, can only be called within the worker function running - * in the thread. Do not call them from the main loop or from a thread - * other than the one represented by @p thread. - * - * @see ecore_thread_local_data_add() - * @see ecore_thread_local_data_del() - * @see ecore_thread_local_data_find() + * @see ecore_animator_frametime_set() */ -EAPI void *ecore_thread_local_data_set(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb); +EAPI double ecore_animator_frametime_get(void); + /** - * Gets data stored in the hash local to the given thread + * @brief Maps an input position from @c 0.0 to @c 1.0 along a timeline to a + * position in a different curve. * - * @param thread The thread context the data belongs to - * @param key The name under which the data is stored - * @return The value under the given key, or @c NULL on error. + * @details This takes an input position (@c 0.0 to @c 1.0) and maps it to a new position (normally + * between @c 0.0 and @c 1.0, but it may go above/below @c 0.0 or @c 1.0 to show that it + * has "overshot" the mark) using some interpolation (mapping) algorithm. * - * Finds and return the data stored in the shared hash under the key @p key. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * This function, and all of the others in the @c ecore_thread_local_data - * family of functions, can only be called within the worker function running - * in the thread. Do not call them from the main loop or from a thread - * other than the one represented by @p thread. + * @remarks This function is useful to create non-linear animations. It offers a variety + * of possible animation curves to be used: + * @li ECORE_POS_MAP_LINEAR - Linear, returns @a pos. + * @li ECORE_POS_MAP_ACCELERATE - Start slow then speed up. + * @li ECORE_POS_MAP_DECELERATE - Start fast then slow down. + * @li ECORE_POS_MAP_SINUSOIDAL - Start slow, speed up then slow down at the end. + * @li ECORE_POS_MAP_ACCELERATE_FACTOR - Start slow then speed up, v1 being a + * power factor, @c 0.0 being linear, @c 1.0 being @c ECORE_POS_MAP_ACCELERATE, @c 2.0 + * being much more pronounced accelerate (squared), @c 3.0 being cubed, and so on. + * @li ECORE_POS_MAP_DECELERATE_FACTOR - Start fast then slow down, v1 being a + * power factor, @c 0.0 being linear, @c 1.0 being @c ECORE_POS_MAP_DECELERATE, @c 2.0 + * being much more pronounced decelerate (squared), @c 3.0 being cubed, and so on. + * @li ECORE_POS_MAP_SINUSOIDAL_FACTOR - Start slow, speed up then slow down + * at the end, v1 being a power factor, @c 0.0 being linear, @c 1.0 being + * @c ECORE_POS_MAP_SINUSOIDAL, @c 2.0 being much more pronounced sinusoidal + * (squared), @c 3.0 being cubed, and so on. + * @li ECORE_POS_MAP_DIVISOR_INTERP - Start at gradient * v1, interpolated via + * power of v2 curve. + * @li ECORE_POS_MAP_BOUNCE - Start at @c 0.0 then "drop" like a ball bouncing to + * the ground at @c 1.0, and bounce v2 times, with decay factor of v1. + * @li ECORE_POS_MAP_SPRING - Start at @c 0.0 then "wobble" like a spring with rest + * position @c 1.0, and wobble v2 times, with decay factor of v1 + * @remarks When not listed v1 and v2 have no effect. * - * @see ecore_thread_local_data_add() - * @see ecore_thread_local_data_wait() - */ -EAPI void *ecore_thread_local_data_find(Ecore_Thread *thread, const char *key); -/** - * Deletes from the thread's hash the data corresponding to the given key + * @image html ecore-pos-map.png + * @image latex ecore-pos-map.eps "ecore pos map" width=\textwidth * - * @param thread The thread context the data belongs to - * @param key The name under which the data is stored - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + * @remarks One way to use this would be: + * @code + * double pos; // input position in a timeline from 0.0 to 1.0 + * double out; // output position after mapping + * int x1, y1, x2, y2; // x1 & y1 are start position, x2 & y2 are end position + * int x, y; // x & y are the calculated position * - * If there's any data stored associated with @p key in the global hash, - * this function will remove it from it and return @c EINA_TRUE. If no data - * exists or an error occurs, it returns @c EINA_FALSE. + * out = ecore_animator_pos_map(pos, ECORE_POS_MAP_BOUNCE, 1.8, 7); + * x = (x1 * out) + (x2 * (1.0 - out)); + * y = (y1 * out) + (y2 * (1.0 - out)); + * move_my_object_to(myobject, x, y); + * @endcode + * This makes an animation that bounces @c 7 diminish each time by a + * factor of @c 1.8. * - * If the data was added to the hash with a free function, then it will - * also be freed after removing it from the hash, otherwise it requires - * to be manually freed by the user, which means that if no other reference - * to it exists before calling this function, it will result in a memory - * leak. + * @param[in] pos The input position to map + * @param[in] map The mapping to use + * @param[in] v1 A parameter used by the mapping (pass @c 0.0 if not used) + * @param[in] v2 A parameter used by the mapping (pass @c 0.0 if not used) + * @return The mapped value * - * This function, and all of the others in the @c ecore_thread_local_data - * family of functions, can only be called within the worker function running - * in the thread. Do not call them from the main loop or from a thread - * other than the one represented by @p thread. + * @see _Ecore_Pos_Map * - * @see ecore_thread_local_data_add() + * @since 1.1.0 */ -EAPI Eina_Bool ecore_thread_local_data_del(Ecore_Thread *thread, const char *key); +EAPI double ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2); /** - * Adds some data to a hash shared by all threads + * @internal * - * @param key The name under which the data will be stored - * @param value The data to add - * @param cb Function to free the data when removed from the hash - * @param direct If true, this will not copy the key string (like - * eina_hash_direct_add()) - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + * @brief Maps an input position from 0.0 to 1.0 along a timeline to a + * position in a different curve. * - * Ecore Thread keeps a hash that can be used to share data across several - * threads, including the main loop one, without having to manually handle - * mutexes to do so safely. + * @details Takes an input position (0.0 to 1.0) and maps to a new position (normally + * between 0.0 and 1.0, but it may go above/below 0.0 or 1.0 to show that it + * has "overshot" the mark) using some interpolation (mapping) algorithm. * - * This function adds the data @p value to this hash under the given @p key. - * No other value in the hash may have the same @p key. If you need to - * change the value under a @p key, or you don't know if one exists already, - * you can use ecore_thread_global_data_set(). + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * Neither @p key nor @p value may be @c NULL and @p key will be copied in the - * hash, unless @p direct is set, in which case the string used should not - * be freed until the data is removed from the hash. + * @remarks This function useful to create non-linear animations. It offers a variety + * of possible animation curves to be used: + * @li ECORE_POS_MAP_LINEAR - Linear, returns @p pos + * @li ECORE_POS_MAP_ACCELERATE - Start slow then speed up + * @li ECORE_POS_MAP_DECELERATE - Start fast then slow down + * @li ECORE_POS_MAP_SINUSOIDAL - Start slow, speed up then slow down at end + * @li ECORE_POS_MAP_ACCELERATE_FACTOR - Start slow then speed up, v[0] being a + * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_ACCELERATE, 2.0 + * being much more pronounced accelerate (squared), 3.0 being cubed, etc. + * @li ECORE_POS_MAP_DECELERATE_FACTOR - Start fast then slow down, v[0] being a + * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_DECELERATE, 2.0 + * being much more pronounced decelerate (squared), 3.0 being cubed, etc. + * @li ECORE_POS_MAP_SINUSOIDAL_FACTOR - Start slow, speed up then slow down + * at end, v[0] being a power factor, 0.0 being linear, 1.0 being + * ECORE_POS_MAP_SINUSOIDAL, 2.0 being much more pronounced sinusoidal + * (squared), 3.0 being cubed, etc. + * @li ECORE_POS_MAP_DIVISOR_INTERP - Start at gradient * v[0], interpolated via + * power of v2 curve + * @li ECORE_POS_MAP_BOUNCE - Start at 0.0 then "drop" like a ball bouncing to + * the ground at 1.0, and bounce v2 times, with decay factor of v[0] + * @li ECORE_POS_MAP_SPRING - Start at 0.0 then "wobble" like a spring rest + * position 1.0, and wobble v2 times, with decay factor of v[0] + * @li ECORE_POS_MAP_CUBIC_BEZIER - Use an interpolated cubic-bezier curve + * ajusted with parameters from v[0] to v[3]. + * @note When not listed v has no effect. * - * The @p cb function will be called when the data in the hash needs to be - * freed, be it because it got deleted with ecore_thread_global_data_del() or - * because Ecore Thread was shut down and the hash destroyed. This parameter - * may be NULL, in which case @p value needs to be manually freed after - * removing it from the hash with either ecore_thread_global_data_del() or - *ecore_thread_global_data_set(). + * @image html ecore-pos-map.png + * @image latex ecore-pos-map.eps width=\textwidth * - * Manually freeing any data that was added to the hash with a @p cb function - * is likely to produce a segmentation fault, or any other strange - * happenings, later on in the program. + * @remarks One way to use this would be: + * @code + * double pos; // input position in a timeline from 0.0 to 1.0 + * double out; // output position after mapping + * int x1, y1, x2, y2; // x1 & y1 are start position, x2 & y2 are end position + * int x, y; // x & y are the calculated position + * double v[2] = {1.8, 7}; * - * @see ecore_thread_global_data_del() - * @see ecore_thread_global_data_set() - * @see ecore_thread_global_data_find() + * out = ecore_animator_pos_map(pos, ECORE_POS_MAP_BOUNCE, 2, v); + * x = (x1 * out) + (x2 * (1.0 - out)); + * y = (y1 * out) + (y2 * (1.0 - out)); + * move_my_object_to(myobject, x, y); + * @endcode + * This will make an animation that bounces 7 each times diminishing by a + * factor of @c 1.8. + * + * @param[in] pos The input position to map + * @param[in] map The mapping to use + * @param[in] v_size The size of the v array. + * @param[in] v An array with the double parameters to be used by the mapping. + * NULL if not used. + * @return The mapped value + * + * @see _Ecore_Pos_Map */ -EAPI Eina_Bool ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct); +EAPI double ecore_animator_pos_map_n(double pos, Ecore_Pos_Map map, int v_size, double v[]); + /** - * Sets some data in the hash shared by all threads - * - * @param key The name under which the data will be stored - * @param value The data to add - * @param cb Function to free the data when removed from the hash + * @brief Sets the source of the animator ticks for the mainloop. * - * If no data exists in the hash under the @p key, this function adds - * @p value in the hash under the given @p key and returns NULL. - * The key itself is copied. + * @details This sets the source of the animator ticks. When an animator is active the + * mainloop will "tick" over frame by frame calling all animators that are + * registered until none are left. The mainloop ticks at a given rate based + * on the animator source. The default source is the system clock timer + * source - @c ECORE_ANIMATOR_SOURCE_TIMER. This source uses the system clock + * to tick over every N seconds (specified by ecore_animator_frametime_set(), + * with the default being 1/30th of a second unless set otherwise). You can + * set a custom tick source by setting the source to + * @c ECORE_ANIMATOR_SOURCE_CUSTOM and then driving it yourself based on some input + * tick source (like another application via ipc, some vertical blanking + * interrupt and so on) using ecore_animator_custom_source_tick_begin_callback_set() and + * ecore_animator_custom_source_tick_end_callback_set() to set the functions + * that are called to start and stop the ticking source, which when + * gets a "tick" should call ecore_animator_custom_tick() to make the "tick" over @c 1 + * frame. * - * If the hash already contains something under @p key, the data will be - * replaced by @p value and the old value will be returned. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @c NULL will also be returned if either @p key or @p value are @c NULL, or - * if an error occurred. + * @param[in] source The source of the animator ticks to use * - * @see ecore_thread_global_data_add() - * @see ecore_thread_global_data_del() - * @see ecore_thread_global_data_find() */ -EAPI void *ecore_thread_global_data_set(const char *key, void *value, Eina_Free_Cb cb); +EAPI void ecore_animator_source_set(Ecore_Animator_Source source); + /** - * Gets data stored in the hash shared by all threads + * @brief Gets the animator source currently set. * - * @param key The name under which the data is stored - * @return The value under the given key, or @c NULL on error. + * @details This gets the current animator source. * - * Finds and return the data stored in the shared hash under the key @p key. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * Keep in mind that the data returned may be used by more than one thread - * at the same time and no reference counting is done on it by Ecore. - * Freeing the data or modifying its contents may require additional - * precautions to be considered, depending on the application's design. + * @return The current animator source * - * @see ecore_thread_global_data_add() - * @see ecore_thread_global_data_wait() + * @see ecore_animator_source_set() */ -EAPI void *ecore_thread_global_data_find(const char *key); +EAPI Ecore_Animator_Source ecore_animator_source_get(void); + /** - * Deletes from the shared hash the data corresponding to the given key - * - * @param key The name under which the data is stored - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + * @brief Sets the function that begins a custom animator tick source. * - * If there's any data stored associated with @p key in the global hash, - * this function will remove it from it and return @c EINA_TRUE. If no data - * exists or an error occurs, it returns @c EINA_FALSE. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * If the data was added to the hash with a free function, then it will - * also be freed after removing it from the hash, otherwise it requires - * to be manually freed by the user, which means that if no other reference - * to it exists before calling this function, it will result in a memory - * leak. + * @remarks The Ecore Animator infrastructure handles tracking of whether animators are needed + * and which ones need to be called and when, but when the tick source + * is custom, you have to provide a tick source by calling + * ecore_animator_custom_tick() to indicate that a frame tick happened. In order + * to allow the source of ticks to be dynamically enabled or disabled as + * needed, @a func when set is called to enable the tick source to + * produce tick events that call ecore_animator_custom_tick(). If @a func + * is @c NULL then no function is called to begin custom ticking. * - * Note, also, that freeing data that other threads may be using will result - * in a crash, so appropriate care must be taken by the application when - * that possibility exists. + * @param[in] func The function to call when ticking is to begin + * @param[in] data The data passed to the tick begin function as its parameter * - * @see ecore_thread_global_data_add() + * @see ecore_animator_source_set() + * @see ecore_animator_custom_source_tick_end_callback_set() + * @see ecore_animator_custom_tick() */ -EAPI Eina_Bool ecore_thread_global_data_del(const char *key); +EAPI void ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, const void *data); + /** - * Gets data stored in the shared hash, or wait for it if it doesn't exist - * - * @param key The name under which the data is stored - * @param seconds The amount of time in seconds to wait for the data. - * @return The value under the given key, or @c NULL on error. + * @brief Sets the function that ends a custom animator tick source. * - * Finds and return the data stored in the shared hash under the key @p key. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * If there's nothing in the hash under the given @p key, the function - * will block and wait up to @p seconds seconds for some other thread to - * add it with either ecore_thread_global_data_add() or - * ecore_thread_global_data_set(). If after waiting there's still no data - * to get, @c NULL will be returned. + * @remarks This function is a matching pair to the function set by + * ecore_animator_custom_source_tick_begin_callback_set() and is called + * when ticking is to stop. If @a func is @c NULL then no function is + * called to stop ticking. For more information see + * ecore_animator_custom_source_tick_begin_callback_set(). * - * If @p seconds is 0, then no waiting will happen and this function works - * like ecore_thread_global_data_find(). If @p seconds is less than 0, then - * the function will wait indefinitely. + * @param[in] func The function to call when ticking is to end + * @param[in] data The data passed to the tick end function as its parameter * - * Keep in mind that the data returned may be used by more than one thread - * at the same time and no reference counting is done on it by Ecore. - * Freeing the data or modifying its contents may require additional - * precautions to be considered, depending on the application's design. - * - * @see ecore_thread_global_data_add() - * @see ecore_thread_global_data_find() - */ -EAPI void *ecore_thread_global_data_wait(const char *key, double seconds); - -/** - * @} + * @see ecore_animator_source_set() + * @see ecore_animator_custom_source_tick_begin_callback_set() + * @see ecore_animator_custom_tick() */ +EAPI void ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, const void *data); /** - * @defgroup Ecore_Pipe_Group Pipe wrapper + * @brief Triggers a custom animator tick. * - * These functions wrap the pipe / write / read functions to easily - * integrate its use into ecore's main loop. + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * The ecore_pipe_add() function creates file descriptors (sockets - * on Windows) and attach a handle to the ecore main loop. That - * handle is called when data is read in the pipe. To write data in - * the pipe, just call ecore_pipe_write(). When you are done, just - * call ecore_pipe_del(). + * @remarks When animator source is set to @c ECORE_ANIMATOR_SOURCE_CUSTOM, then calling + * this function triggers a run of all animators currently registered with + * Ecore as this indicates that a "frame tick" happened. This does nothing if + * the animator source(set by ecore_animator_source_set()) is not set to + * @c ECORE_ANIMATOR_SOURCE_CUSTOM. * - * For examples see here: - * @li @ref tutorial_ecore_pipe_gstreamer_example - * @li @ref tutorial_ecore_pipe_simple_example - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -typedef struct _Ecore_Pipe Ecore_Pipe; /**< A handle for pipes */ - -/** - * @typedef Ecore_Pipe_Cb Ecore_Pipe_Cb - * The callback that data written to the pipe is sent to. + * @see ecore_animator_source_set() + * @see ecore_animator_custom_source_tick_begin_callback_set + * @see ecore_animator_custom_source_tick_end_callback_set()() */ -typedef void (*Ecore_Pipe_Cb)(void *data, void *buffer, unsigned int nbyte); - -EAPI Ecore_Pipe *ecore_pipe_add(Ecore_Pipe_Cb handler, const void *data); -EAPI void *ecore_pipe_del(Ecore_Pipe *p); -EAPI Eina_Bool ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes); -EAPI void ecore_pipe_write_close(Ecore_Pipe *p); -EAPI void ecore_pipe_read_close(Ecore_Pipe *p); -EAPI void ecore_pipe_thaw(Ecore_Pipe *p); -EAPI void ecore_pipe_freeze(Ecore_Pipe *p); -EAPI int ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait); +EAPI void ecore_animator_custom_tick(void); /** * @} */ /** - * @defgroup Ecore_Job_Group Ecore Job functions + * @defgroup Ecore_Job_Group Ecore Job + * @ingroup Ecore_Main_Loop_Group * - * You can queue jobs that are to be done by the main loop when the - * current event is dealt with. + * @brief You can queue jobs that are to be done by the main loop when the + * current event is dealt with. * - * Jobs are processed by the main loop similarly to events. They - * also will be executed in the order in which they were added. + * Jobs are processed by the main loop in a manner which is similar to events. They + * are also executed in the order in which they are added. * * A good use for them is when you don't want to execute an action * immediately, but want to give the control back to the main loop - * so that it will call your job callback when jobs start being + * so that it calls your job callback when jobs start being * processed (and if there are other jobs added before yours, they - * will be processed first). This also gives the chance to other + * are processed first). This also gives a chance to other * actions in your program to cancel the job before it is started. * - * Examples of using @ref Ecore_Job : - * @li @ref ecore_job_example_c - * - * @ingroup Ecore_Main_Loop_Group - * * @{ */ -typedef struct _Ecore_Job Ecore_Job; /**< A job handle */ - -EAPI Ecore_Job *ecore_job_add(Ecore_Cb func, const void *data); -EAPI void *ecore_job_del(Ecore_Job *job); - -/** - * @} - */ +typedef struct _Ecore_Job Ecore_Job; /**< @brief A job handle */ /** - * @defgroup Ecore_Application_Group Ecore Application functions + * @brief Add a job to the event queue. * - * @{ - */ - -EAPI void ecore_app_args_set(int argc, const char **argv); -EAPI void ecore_app_args_get(int *argc, char ***argv); -EAPI void ecore_app_restart(void); - -/** - * @} + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif + * + * @remarks Once the job has been executed, the job handle is invalid. + * + * @param[in] func The function to call when the job gets handled. + * @param[in] data Data pointer to be passed to the job function when the job is + * handled. + * @return The handle of the job. @c NULL is returned if the job could not be + * added to the queue. */ +EAPI Ecore_Job *ecore_job_add(Ecore_Cb func, const void *data); /** - * @defgroup Ecore_Throttle_Group Ecore Throttle functions + * @brief Delete a queued job that has not yet been executed. * - * @ingroup Ecore_Main_Loop_Group + * @if MOBILE @since_tizen 2.3 + * @elseif WEARABLE @since_tizen 2.3.1 + * @endif * - * @{ + * @param[in] job Handle of the job to delete. + * @return The data pointer that was to be passed to the job. */ - -EAPI void ecore_throttle_adjust(double amount); -EAPI double ecore_throttle_get(void); +EAPI void *ecore_job_del(Ecore_Job *job); /** * @} diff --git a/src/lib/ecore/Ecore_Getopt.h b/src/lib/ecore/Ecore_Getopt.h index 0a11787..33661e4 100644 --- a/src/lib/ecore/Ecore_Getopt.h +++ b/src/lib/ecore/Ecore_Getopt.h @@ -31,20 +31,21 @@ #endif /* ! _WIN32 */ /** + * @internal * @file Ecore_Getopt.h * @brief Contains powerful getopt replacement. * * This replacement handles both short (-X) or long options (--ABC) * options, with various actions supported, like storing one value and * already converting to required type, counting number of - * occurrences, setting true or false values, show help, license, - * copyright and even support user-defined callbacks. + * occurrences, setting true or false values, showing help, license, + * copyright, and even supporting user-defined callbacks. * - * It is provided a set of C Pre Processor macros so definition is + * It is provided a set of C Pre Processor macros. So definition is * straightforward. * - * Values will be stored elsewhere indicated by an array of pointers - * to values, it is given in separate to parser description so you can + * Values are stored elsewhere indicated by an array of pointers + * to values. It is given separately to parser description. So you can * use multiple values with the same parser. */ @@ -109,7 +110,7 @@ union _Ecore_Getopt_Value struct _Ecore_Getopt_Desc_Store { - Ecore_Getopt_Type type; /**< type of data being handled */ + Ecore_Getopt_Type type; /**< Type of data being handled */ Ecore_Getopt_Desc_Arg_Requirement arg_req; union { @@ -139,12 +140,12 @@ struct _Ecore_Getopt_Desc_Callback struct _Ecore_Getopt_Desc { - char shortname; /**< used with a single dash */ - const char *longname; /**< used with double dashes */ - const char *help; /**< used by --help/ecore_getopt_help() */ - const char *metavar; /**< used by ecore_getopt_help() with nargs > 0 */ + char shortname; /**< Used with a single dash */ + const char *longname; /**< Used with double dashes */ + const char *help; /**< Used by -- help/ecore_getopt_help() */ + const char *metavar; /**< Used by ecore_getopt_help() with nargs > 0 */ - Ecore_Getopt_Action action; /**< define how to handle it */ + Ecore_Getopt_Action action; /**< Define how to handle it */ union { const Ecore_Getopt_Desc_Store store; @@ -158,14 +159,14 @@ struct _Ecore_Getopt_Desc struct _Ecore_Getopt { - const char *prog; /**< to be used when ecore_app_args_get() fails */ - const char *usage; /**< usage example, %prog is replaced */ - const char *version; /**< if exists, --version will work */ - const char *copyright; /**< if exists, --copyright will work */ - const char *license; /**< if exists, --license will work */ - const char *description; /**< long description, possible multiline */ - Eina_Bool strict : 1; /**< fail on errors */ - const Ecore_Getopt_Desc descs[]; /* NULL terminated. */ + const char *prog; /**< To be used when ecore_app_args_get() fails */ + const char *usage; /**< Usage example, %prog is replaced */ + const char *version; /**< If exists, --version works */ + const char *copyright; /**< If exists, --copyright works */ + const char *license; /**< If exists, --license works */ + const char *description; /**< Long description, possible multiline */ + Eina_Bool strict : 1; /**< Fail on errors */ + const Ecore_Getopt_Desc descs[]; /**< @c NULL terminated */ }; #define ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, arg_requirement, default_value) \ @@ -399,7 +400,7 @@ EAPI int EAPI Eina_List *ecore_getopt_list_free(Eina_List *list); -/* helper functions to be used with ECORE_GETOPT_CALLBACK_*() */ +/* Helper functions to be used with ECORE_GETOPT_CALLBACK_*() */ EAPI Eina_Bool ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, diff --git a/src/lib/ecore/ecore.c b/src/lib/ecore/ecore.c index b7e47dc..a79c166 100644 --- a/src/lib/ecore/ecore.c +++ b/src/lib/ecore/ecore.c @@ -80,6 +80,7 @@ static void _thread_callback(void *data, static Eina_List *_thread_cb = NULL; static Ecore_Pipe *_thread_call = NULL; static Eina_Lock _thread_safety; +static const int wakeup = 42; static int _thread_loop = 0; static Eina_Lock _thread_mutex; @@ -95,6 +96,8 @@ static int _thread_id_update = 0; Eina_Lock _ecore_main_loop_lock; int _ecore_main_lock_count; +extern int _ecore_thread_count_real; + /** OpenBSD does not define CODESET * FIXME ?? */ @@ -175,11 +178,8 @@ ecore_init(void) eina_condition_new(&_thread_cond, &_thread_mutex); eina_lock_new(&_thread_feedback_mutex); eina_condition_new(&_thread_feedback_cond, &_thread_feedback_mutex); - if (!_thread_call) - { - _thread_call = ecore_pipe_add(_thread_callback, NULL); - eina_lock_new(&_thread_safety); - } + _thread_call = ecore_pipe_add(_thread_callback, NULL); + eina_lock_new(&_thread_safety); eina_lock_new(&_thread_id_lock); @@ -224,7 +224,6 @@ shutdown_evil: EAPI int ecore_shutdown(void) { - Ecore_Pipe *p; /* * take a lock here because _ecore_event_shutdown() does callbacks */ @@ -259,10 +258,15 @@ ecore_shutdown(void) * It should be fine now as we do wait for thread to shutdown before * we try to destroy the pipe. */ - p = _thread_call; + do + { + ecore_pipe_wait(_thread_call, 1, 0.1); + // 0.1 seconds waiting for up to this delay for pending + // threads to still join + } + while (_ecore_thread_count_real > 0); + ecore_pipe_del(_thread_call); _thread_call = NULL; - ecore_pipe_wait(p, 1, 0.1); - ecore_pipe_del(p); eina_lock_free(&_thread_safety); eina_condition_free(&_thread_cond); eina_lock_free(&_thread_mutex); @@ -307,12 +311,92 @@ unlock: return _ecore_init_count; } +struct _Ecore_Fork_Cb +{ + Ecore_Cb func; + void *data; + Eina_Bool delete_me : 1; +}; + +typedef struct _Ecore_Fork_Cb Ecore_Fork_Cb; + +static int fork_cbs_walking = 0; +static Eina_List *fork_cbs = NULL; + +EAPI Eina_Bool +ecore_fork_reset_callback_add(Ecore_Cb func, const void *data) +{ + Ecore_Fork_Cb *fcb; + + fcb = calloc(1, sizeof(Ecore_Fork_Cb)); + if (!fcb) return EINA_FALSE; + fcb->func = func; + fcb->data = (void *)data; + fork_cbs = eina_list_append(fork_cbs, fcb); + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_fork_reset_callback_del(Ecore_Cb func, const void *data) +{ + Eina_List *l; + Ecore_Fork_Cb *fcb; + + EINA_LIST_FOREACH(fork_cbs, l, fcb) + { + if ((fcb->func == func) && (fcb->data == data)) + { + if (!fork_cbs_walking) + { + fork_cbs = eina_list_remove_list(fork_cbs, l); + free(fcb); + } + else + fcb->delete_me = EINA_TRUE; + return EINA_TRUE; + } + } + return EINA_FALSE; +} + +EAPI void +ecore_fork_reset(void) +{ + Eina_List *l, *ln; + Ecore_Fork_Cb *fcb; + + eina_lock_take(&_thread_safety); + + ecore_pipe_del(_thread_call); + _thread_call = ecore_pipe_add(_thread_callback, NULL); + /* If there was something in the pipe, trigger a wakeup again */ + if (_thread_cb) ecore_pipe_write(_thread_call, &wakeup, sizeof (int)); + + eina_lock_release(&_thread_safety); + + // should this be done withing the eina lock stuff? + + fork_cbs_walking++; + EINA_LIST_FOREACH(fork_cbs, l, fcb) + { + fcb->func(fcb->data); + } + fork_cbs_walking--; + + EINA_LIST_FOREACH_SAFE(fork_cbs, l, ln, fcb) + { + if (fcb->delete_me) + { + fork_cbs = eina_list_remove_list(fork_cbs, l); + free(fcb); + } + } +} + /** * @} */ -static int wakeup = 42; - EAPI void ecore_main_loop_thread_safe_call_async(Ecore_Cb callback, void *data) @@ -466,7 +550,11 @@ ecore_print_warning(const char *function __UNUSED__, "\tWith the parameter:\n\n" "\t%s\n\n" "\tbeing NULL. Please fix your program.", function, sparam); - if (getenv("ECORE_ERROR_ABORT")) abort(); + if (getenv("ECORE_ERROR_ABORT")) + { + ERR("### EFL abort on errors ###\n"); + abort(); + } } EAPI void @@ -491,7 +579,11 @@ _ecore_magic_fail(const void *d, ERR("*** NAUGHTY PROGRAMMER!!!\n" "*** SPANK SPANK SPANK!!!\n" "*** Now go fix your code. Tut tut tut!"); - if (getenv("ECORE_ERROR_ABORT")) abort(); + if (getenv("ECORE_ERROR_ABORT")) + { + ERR("### EFL abort on errors ###\n"); + abort(); + } } static const char * diff --git a/src/lib/ecore/ecore_alloc.c b/src/lib/ecore/ecore_alloc.c index c9e77cd..34f723f 100644 --- a/src/lib/ecore/ecore_alloc.c +++ b/src/lib/ecore/ecore_alloc.c @@ -2,6 +2,32 @@ # include "config.h" #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include @@ -102,7 +128,7 @@ ecore_mempool_init(void) mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 16); if (!mempool_array[i]->mp) { - if (!strcmp(choice, "pass_through")) + if (!(!strcmp(choice, "pass_through"))) { ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice); choice = "pass_through"; diff --git a/src/lib/ecore/ecore_anim.c b/src/lib/ecore/ecore_anim.c index 67bf8b1..ab23d86 100644 --- a/src/lib/ecore/ecore_anim.c +++ b/src/lib/ecore/ecore_anim.c @@ -76,23 +76,15 @@ _end_tick(void) { if (!ticking) return; ticking = 0; - switch (src) - { - case ECORE_ANIMATOR_SOURCE_TIMER: - if (timer) - { - _ecore_timer_del(timer); - timer = NULL; - } - break; - - case ECORE_ANIMATOR_SOURCE_CUSTOM: - if (end_tick_cb) end_tick_cb((void *)end_tick_data); - break; - default: - break; + if (timer) + { + _ecore_timer_del(timer); + timer = NULL; } + + if ((src == ECORE_ANIMATOR_SOURCE_CUSTOM) && end_tick_cb) + end_tick_cb((void *)end_tick_data); } static Eina_Bool @@ -260,6 +252,81 @@ _pos_map_spring(double pos, return _pos_map_sin((M_PI / 2.0) + (p2 * len)) * decay; } +static double +_cubic_bezier_a (double a1, double a2) +{ + return 1.0 - 3.0 * a2 + 3.0 * a1; +} + +static double +_cubic_bezier_b (double a1, double a2) +{ + return 3.0 * a2 - 6.0 * a1; +} + +static double +_cubic_bezier_c(double a1) +{ + return 3.0 * a1; +} + +static double +_cubic_bezier_calc(double t, + double a1, + double a2) +{ + return ((_cubic_bezier_a(a1, a2) * t + + _cubic_bezier_b(a1, a2)) * t + + _cubic_bezier_c(a1)) * t; +} + +static double +_cubic_bezier_slope_get(double t, + double a1, + double a2) +{ + return 3.0 * _cubic_bezier_a(a1, a2) * t * t + + 2.0 * _cubic_bezier_b(a1, a2) * t + + _cubic_bezier_c(a1); +} + +static double +_cubic_bezier_t_get(double a, + double x1, + double x2) +{ +#define APPROXIMATE_RANGE(val) \ + ((((val) < 0.01) && ((val) > -0.01)) ? EINA_TRUE : EINA_FALSE) + + const int LIMIT = 100; + double current_slope; + double change; + double current_x; + double guess_t = a; + + for (int i = 0; i < LIMIT; i++) + { + current_slope = _cubic_bezier_slope_get(guess_t, x1, x2); + if (current_slope == 0.0) return guess_t; + current_x = _cubic_bezier_calc(guess_t, x1, x2) - a; + change = current_x / current_slope; + guess_t -= change; + if (APPROXIMATE_RANGE(change)) break; + } + return guess_t; +} + +static double +_pos_map_cubic_bezier(double pos, + double x1, + double y1, + double x2, + double y2) +{ + if (x1 == y1 && x2 == y2) return pos; + return _cubic_bezier_calc(_cubic_bezier_t_get(pos, x1, x2), y1, y2); +} + #define DBL_TO(Fp) eina_f32p32_double_to(Fp) #define DBL_FROM(D) eina_f32p32_double_from(D) #define INT_FROM(I) eina_f32p32_int_from(I) @@ -270,15 +337,17 @@ _pos_map_spring(double pos, #define MUL(A, B) eina_f32p32_mul(A, B) EAPI double -ecore_animator_pos_map(double pos, - Ecore_Pos_Map map, - double v1, - double v2) +ecore_animator_pos_map_n(double pos, + Ecore_Pos_Map map, + int v_size, + double v[]) { + double v0 = 0, v1 = 0, v2 = 0, v3 = 0; + /* purely functional - locking not required */ - if (pos > 1.0) pos = 1.0; - else if (pos < 0.0) - pos = 0.0; + if (pos >= 1.0) return 1.0; + else if (pos <= 0.0) + return 0.0; switch (map) { case ECORE_POS_MAP_LINEAR: @@ -300,42 +369,74 @@ ecore_animator_pos_map(double pos, return pos; case ECORE_POS_MAP_ACCELERATE_FACTOR: - pos = _pos_map_accel_factor(pos, v1); + if (v_size > 0) v0 = v[0]; + pos = _pos_map_accel_factor(pos, v0); return pos; case ECORE_POS_MAP_DECELERATE_FACTOR: - pos = 1.0 - _pos_map_accel_factor(1.0 - pos, v1); + if (v_size > 0) v0 = v[0]; + pos = 1.0 - _pos_map_accel_factor(1.0 - pos, v0); return pos; case ECORE_POS_MAP_SINUSOIDAL_FACTOR: - if (pos < 0.5) pos = _pos_map_accel_factor(pos * 2.0, v1) / 2.0; - else pos = 1.0 - (_pos_map_accel_factor((1.0 - pos) * 2.0, v1) / 2.0); + if (v_size > 0) v0 = v[0]; + if (pos < 0.5) pos = _pos_map_accel_factor(pos * 2.0, v0) / 2.0; + else pos = 1.0 - (_pos_map_accel_factor((1.0 - pos) * 2.0, v0) / 2.0); return pos; case ECORE_POS_MAP_DIVISOR_INTERP: - pos = _pos_map_pow(pos, v1, (int)v2); + if (v_size > 0) v0 = v[0]; + if (v_size > 1) v1 = v[1]; + pos = _pos_map_pow(pos, v0, (int)v1); return pos; case ECORE_POS_MAP_BOUNCE: - pos = _pos_map_spring(pos, (int)v2, v1); + if (v_size > 0) v0 = v[0]; + if (v_size > 1) v1 = v[1]; + pos = _pos_map_spring(pos, (int)v1, v0); if (pos < 0.0) pos = -pos; pos = 1.0 - pos; return pos; case ECORE_POS_MAP_SPRING: - pos = 1.0 - _pos_map_spring(pos, (int)v2, v1); + if (v_size > 0) v0 = v[0]; + if (v_size > 1) v1 = v[1]; + pos = 1.0 - _pos_map_spring(pos, (int)v1, v0); + return pos; + + case ECORE_POS_MAP_CUBIC_BEZIER: + if (v_size > 0) v0 = v[0]; + if (v_size > 1) v1 = v[1]; + if (v_size > 2) v2 = v[2]; + if (v_size > 3) v3 = v[3]; + pos = _pos_map_cubic_bezier(pos, v0, v1, v2, v3); return pos; default: return pos; } + return pos; } +EAPI double +ecore_animator_pos_map(double pos, + Ecore_Pos_Map map, + double v1, + double v2) +{ + double v[2]; + + v[0] = v1; + v[1] = v2; + return ecore_animator_pos_map_n(pos, map, 2, v); +} + EAPI void * ecore_animator_del(Ecore_Animator *animator) { void *data = NULL; + if (!animator) return NULL; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); _ecore_lock(); @@ -421,8 +522,8 @@ ecore_animator_source_set(Ecore_Animator_Source source) { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); - src = source; _end_tick(); + src = source; if (animators) _begin_tick(); _ecore_unlock(); } @@ -440,9 +541,9 @@ ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); + _end_tick(); begin_tick_cb = func; begin_tick_data = data; - _end_tick(); if (animators) _begin_tick(); _ecore_unlock(); } @@ -453,9 +554,9 @@ ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); + _end_tick(); end_tick_cb = func; end_tick_data = data; - _end_tick(); if (animators) _begin_tick(); _ecore_unlock(); } diff --git a/src/lib/ecore/ecore_events.c b/src/lib/ecore/ecore_events.c index bbfa7a9..d0256c0 100644 --- a/src/lib/ecore/ecore_events.c +++ b/src/lib/ecore/ecore_events.c @@ -128,6 +128,7 @@ ecore_event_handler_del(Ecore_Event_Handler *event_handler) { void *data = NULL; + if (!event_handler) return NULL; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); _ecore_lock(); if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER)) diff --git a/src/lib/ecore/ecore_exe.c b/src/lib/ecore/ecore_exe.c index 7cc4b0f..deec7f0 100644 --- a/src/lib/ecore/ecore_exe.c +++ b/src/lib/ecore/ecore_exe.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include #include @@ -692,10 +718,12 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Event_Add *e; e = _ecore_exe_event_add_new(); - e->exe = exe; if (e) /* Send the event. */ - ecore_event_add(ECORE_EXE_EVENT_ADD, e, - _ecore_exe_event_add_free, NULL); + { + e->exe = exe; + ecore_event_add(ECORE_EXE_EVENT_ADD, e, + _ecore_exe_event_add_free, NULL); + } /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */ } diff --git a/src/lib/ecore/ecore_getopt.c b/src/lib/ecore/ecore_getopt.c index 64f5f9c..743f7f3 100644 --- a/src/lib/ecore/ecore_getopt.c +++ b/src/lib/ecore/ecore_getopt.c @@ -2,21 +2,30 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif #ifdef HAVE_ALLOCA_H # include -#elif defined __GNUC__ -# define alloca __builtin_alloca -#elif defined _AIX -# define alloca __alloca -#elif defined _MSC_VER -# include -# define alloca _alloca -#else -# include -# ifdef __cplusplus +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus extern "C" +# endif +void *alloca (size_t); # endif -void *alloca(size_t); #endif #include @@ -873,6 +882,9 @@ static Eina_Bool _ecore_getopt_parse_bool(const char *str, Eina_Bool *v) { + if (!str) + return EINA_FALSE; + if ((strcmp(str, "0") == 0) || (strcasecmp(str, "f") == 0) || (strcasecmp(str, "false") == 0) || @@ -902,6 +914,7 @@ _ecore_getopt_parse_long(const char *str, long int *v) { char *endptr = NULL; + if (!str) return EINA_FALSE; *v = strtol(str, &endptr, 0); return endptr > str; } @@ -911,6 +924,7 @@ _ecore_getopt_parse_double(const char *str, double *v) { char *endptr = NULL; + if (!str) return EINA_FALSE; *v = strtod(str, &endptr); return endptr > str; } @@ -1111,6 +1125,9 @@ _ecore_getopt_parse_choice(const Ecore_Getopt *parser __UNUSED__, { const char *const *pchoice; + if (!arg_val) + return EINA_FALSE; + if (!val->strp) { _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); @@ -1461,7 +1478,7 @@ _ecore_getopt_parse_arg_long(const Ecore_Getopt *parser, const char *arg_val; int desc_idx; Ecore_Getopt_Value *value; - Eina_Bool ret; + Eina_Bool ret = EINA_FALSE; desc = _ecore_getopt_parse_find_long(parser, arg); if (!desc) @@ -1535,7 +1552,7 @@ _ecore_getopt_parse_arg_short(const Ecore_Getopt *parser, const char *arg_val; int desc_idx; Ecore_Getopt_Value *value; - Eina_Bool ret; + Eina_Bool ret = EINA_FALSE; desc = _ecore_getopt_parse_find_short(parser, arg[0]); if (!desc) diff --git a/src/lib/ecore/ecore_glib.c b/src/lib/ecore/ecore_glib.c index a4db0ab..363b4d0 100644 --- a/src/lib/ecore/ecore_glib.c +++ b/src/lib/ecore/ecore_glib.c @@ -184,11 +184,15 @@ _ecore_glib_select(int ecore_fds, fd_set *efds, struct timeval *ecore_timeout) { - GStaticMutex lock = G_STATIC_MUTEX_INIT; - GMutex *mutex = g_static_mutex_get_mutex(&lock); - GMainContext *ctx = g_main_context_default(); + GStaticMutex lock; + GMutex *mutex; + GMainContext *ctx; int ret; + g_static_mutex_init(&lock); + mutex = g_static_mutex_get_mutex(&lock); + ctx = g_main_context_default(); + if (g_main_context_acquire(ctx)) { if (mutex) g_mutex_lock(mutex); diff --git a/src/lib/ecore/ecore_idler.c b/src/lib/ecore/ecore_idler.c index 62998b6..fd256c1 100644 --- a/src/lib/ecore/ecore_idler.c +++ b/src/lib/ecore/ecore_idler.c @@ -49,6 +49,7 @@ EAPI void * ecore_idler_del(Ecore_Idler *idler) { void *data = NULL; + if (!idler) return NULL; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); if (!ECORE_MAGIC_CHECK(idler, ECORE_MAGIC_IDLER)) diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c index a936a2b..a3b4245 100644 --- a/src/lib/ecore/ecore_main.c +++ b/src/lib/ecore/ecore_main.c @@ -65,7 +65,8 @@ # define HAVE_EPOLL 0 # define EPOLLIN 1 -# define EPOLLOUT 2 +# define EPOLLPRI 2 +# define EPOLLOUT 4 # define EPOLLERR 8 #define EPOLL_CTL_ADD 1 @@ -163,6 +164,7 @@ struct _Ecore_Fd_Handler Eina_Bool write_active : 1; Eina_Bool error_active : 1; Eina_Bool delete_me : 1; + Eina_Bool file : 1; #if defined(USE_G_MAIN_LOOP) GPollFD gfd; #endif @@ -213,6 +215,7 @@ static int do_quit = 0; static Ecore_Fd_Handler *fd_handlers = NULL; static Ecore_Fd_Handler *fd_handler_current = NULL; static Eina_List *fd_handlers_with_prep = NULL; +static Eina_List *file_fd_handlers = NULL; static Eina_List *fd_handlers_with_buffer = NULL; static Eina_List *fd_handlers_to_delete = NULL; @@ -259,6 +262,26 @@ static gboolean _ecore_glib_idle_enterer_called; static gboolean ecore_fds_ready; #endif +Eina_Bool +_ecore_fd_close_on_exec(int fd) +{ +#ifdef HAVE_EXECVP + int flags; + + flags = fcntl(fd, F_GETFD); + if (flags == -1) + return EINA_FALSE; + + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) + return EINA_FALSE; + return EINA_TRUE; +#else + (void) fd; + return EINA_FALSE; +#endif +} + static inline void _ecore_fd_valid(void) { @@ -276,18 +299,18 @@ static inline void _ecore_try_add_to_call_list(Ecore_Fd_Handler *fdh) { /* check if this fdh is already in the list */ - if (fdh->next_ready) - return; - if (fdh->read_active || fdh->write_active || fdh->error_active) - { - /* - * make sure next_ready is non-null by pointing to ourselves - * use that to indicate this fdh is in the ready list - * insert at the head of the list to avoid trouble - */ - fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh; - fd_handlers_to_call = fdh; - } + if (fdh->next_ready) + return; + if (fdh->read_active || fdh->write_active || fdh->error_active) + { + /* + * make sure next_ready is non-null by pointing to ourselves + * use that to indicate this fdh is in the ready list + * insert at the head of the list to avoid trouble + */ + fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh; + fd_handlers_to_call = fdh; + } } static inline int @@ -296,7 +319,7 @@ _ecore_get_epoll_fd(void) if (epoll_pid && epoll_pid != getpid()) { /* forked! */ - _ecore_main_loop_shutdown(); + _ecore_main_loop_shutdown(); } if (epoll_pid == 0 && epoll_fd < 0) { @@ -326,7 +349,7 @@ _ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh) int events = 0; if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN; if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT; - if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR; + if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR | EPOLLPRI; return events; } @@ -348,7 +371,7 @@ _ecore_main_fdh_poll_add(Ecore_Fd_Handler *fdh) { int r = 0; - if (HAVE_EPOLL && epoll_fd >= 0) + if ((!fdh->file) && HAVE_EPOLL && epoll_fd >= 0) { r = _ecore_epoll_add(_ecore_get_epoll_fd(), fdh->fd, _ecore_poll_events_from_fdh(fdh), fdh); @@ -369,7 +392,7 @@ _ecore_main_fdh_poll_add(Ecore_Fd_Handler *fdh) static inline void _ecore_main_fdh_poll_del(Ecore_Fd_Handler *fdh) { - if (HAVE_EPOLL && epoll_fd >= 0) + if ((!fdh->file) && HAVE_EPOLL && epoll_fd >= 0) { struct epoll_event ev; int efd = _ecore_get_epoll_fd(); @@ -408,7 +431,7 @@ static inline int _ecore_main_fdh_poll_modify(Ecore_Fd_Handler *fdh) { int r = 0; - if (HAVE_EPOLL && epoll_fd >= 0) + if ((!fdh->file) && HAVE_EPOLL && epoll_fd >= 0) { struct epoll_event ev; int efd = _ecore_get_epoll_fd(); @@ -743,6 +766,7 @@ _ecore_main_loop_init(void) if (epoll_fd < 0) WRN("Failed to create epoll fd!"); epoll_pid = getpid(); + _ecore_fd_close_on_exec(epoll_fd); /* add polls on all our file descriptors */ Ecore_Fd_Handler *fdh; @@ -778,6 +802,7 @@ _ecore_main_loop_init(void) WRN("failed to create timer fd!"); else { + _ecore_fd_close_on_exec(timer_fd); ecore_timer_fd.fd = timer_fd; ecore_timer_fd.events = G_IO_IN; ecore_timer_fd.revents = 0; @@ -1041,6 +1066,56 @@ unlock: return fdh; } +EAPI Ecore_Fd_Handler * +ecore_main_fd_handler_file_add(int fd, + Ecore_Fd_Handler_Flags flags, + Ecore_Fd_Cb func, + const void *data, + Ecore_Fd_Cb buf_func, + const void *buf_data) +{ + Ecore_Fd_Handler *fdh = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + + if ((fd < 0) || (flags == 0) || (!func)) goto unlock; + + fdh = ecore_fd_handler_calloc(1); + if (!fdh) goto unlock; + ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER); + fdh->next_ready = NULL; + fdh->fd = fd; + fdh->flags = flags; + fdh->file = EINA_TRUE; + if (_ecore_main_fdh_poll_add(fdh) < 0) + { + int err = errno; + ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err)); + ecore_fd_handler_mp_free(fdh); + fdh = NULL; + goto unlock; + } + fdh->read_active = EINA_FALSE; + fdh->write_active = EINA_FALSE; + fdh->error_active = EINA_FALSE; + fdh->delete_me = EINA_FALSE; + fdh->func = func; + fdh->data = (void *)data; + fdh->buf_func = buf_func; + if (buf_func) + fd_handlers_with_buffer = eina_list_append(fd_handlers_with_buffer, fdh); + fdh->buf_data = (void *)buf_data; + fd_handlers = (Ecore_Fd_Handler *) + eina_inlist_append(EINA_INLIST_GET(fd_handlers), + EINA_INLIST_GET(fdh)); + file_fd_handlers = eina_list_append(file_fd_handlers, fdh); +unlock: + _ecore_unlock(); + + return fdh; +} + #ifdef _WIN32 EAPI Ecore_Win32_Handler * ecore_main_win32_handler_add(void *h, @@ -1243,6 +1318,8 @@ _ecore_main_shutdown(void) fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep); if (fd_handlers_to_delete) fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete); + if (file_fd_handlers) + file_fd_handlers = eina_list_free(file_fd_handlers); fd_handlers_to_call = NULL; fd_handlers_to_call_current = NULL; @@ -1296,6 +1373,8 @@ _ecore_main_select(double timeout) { struct timeval tv, *t; fd_set rfds, wfds, exfds; + Ecore_Fd_Handler *fdh; + Eina_List *l; int max_fd; int ret; @@ -1333,8 +1412,6 @@ _ecore_main_select(double timeout) if (!HAVE_EPOLL || epoll_fd < 0) { - Ecore_Fd_Handler *fdh; - EINA_INLIST_FOREACH(fd_handlers, fdh) { if (!fdh->delete_me) @@ -1363,7 +1440,26 @@ _ecore_main_select(double timeout) max_fd = _ecore_get_epoll_fd(); FD_SET(max_fd, &rfds); } - + EINA_LIST_FOREACH(file_fd_handlers, l, fdh) + if (!fdh->delete_me) + { + if (fdh->flags & ECORE_FD_READ) + { + FD_SET(fdh->fd, &rfds); + if (fdh->fd > max_fd) max_fd = fdh->fd; + } + if (fdh->flags & ECORE_FD_WRITE) + { + FD_SET(fdh->fd, &wfds); + if (fdh->fd > max_fd) max_fd = fdh->fd; + } + if (fdh->flags & ECORE_FD_ERROR) + { + FD_SET(fdh->fd, &exfds); + if (fdh->fd > max_fd) max_fd = fdh->fd; + } + if (fdh->fd > max_fd) max_fd = fdh->fd; + } if (_ecore_signal_count_get()) return -1; _ecore_unlock(); @@ -1385,8 +1481,6 @@ _ecore_main_select(double timeout) _ecore_main_fdh_epoll_mark_active(); else { - Ecore_Fd_Handler *fdh; - EINA_INLIST_FOREACH(fd_handlers, fdh) { if (!fdh->delete_me) @@ -1401,7 +1495,19 @@ _ecore_main_select(double timeout) } } } - + EINA_LIST_FOREACH(file_fd_handlers, l, fdh) + { + if (!fdh->delete_me) + { + if (FD_ISSET(fdh->fd, &rfds)) + fdh->read_active = EINA_TRUE; + if (FD_ISSET(fdh->fd, &wfds)) + fdh->write_active = EINA_TRUE; + if (FD_ISSET(fdh->fd, &exfds)) + fdh->error_active = EINA_TRUE; + _ecore_try_add_to_call_list(fdh); + } + } _ecore_main_fd_handlers_cleanup(); #ifdef _WIN32 _ecore_main_win32_handlers_cleanup(); @@ -1498,6 +1604,8 @@ _ecore_main_fd_handlers_cleanup(void) fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fdh); fd_handlers = (Ecore_Fd_Handler *) eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh)); + if (fdh->file) + file_fd_handlers = eina_list_remove(file_fd_handlers, fdh); ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); ecore_fd_handler_mp_free(fdh); fd_handlers_to_delete = eina_list_remove_list(fd_handlers_to_delete, l); @@ -1855,12 +1963,21 @@ _ecore_main_win32_select(int nfds __UNUSED__, long network_event; network_event = 0; - if (FD_ISSET(fdh->fd, readfds)) - network_event |= FD_READ; - if (FD_ISSET(fdh->fd, writefds)) - network_event |= FD_WRITE; - if (FD_ISSET(fdh->fd, exceptfds)) - network_event |= FD_OOB; + if (readfds) + { + if (FD_ISSET(fdh->fd, readfds)) + network_event |= FD_READ; + } + if (writefds) + { + if (FD_ISSET(fdh->fd, writefds)) + network_event |= FD_WRITE; + } + if (exceptfds) + { + if (FD_ISSET(fdh->fd, exceptfds)) + network_event |= FD_OOB; + } if (network_event) { @@ -1900,9 +2017,12 @@ _ecore_main_win32_select(int nfds __UNUSED__, result = MsgWaitForMultipleObjects(objects_nbr, (const HANDLE *)objects, EINA_FALSE, timeout, QS_ALLINPUT); - FD_ZERO(readfds); - FD_ZERO(writefds); - FD_ZERO(exceptfds); + if (readfds) + FD_ZERO(readfds); + if (writefds) + FD_ZERO(writefds); + if (exceptfds) + FD_ZERO(exceptfds); /* The result tells us the type of event we have. */ if (result == WAIT_FAILED) @@ -1910,7 +2030,7 @@ _ecore_main_win32_select(int nfds __UNUSED__, char *m; m = evil_last_error_get(); - ERR(" * %s\n", m); + ERR("%s", m); free(m); res = -1; } @@ -1935,11 +2055,11 @@ _ecore_main_win32_select(int nfds __UNUSED__, WSAEnumNetworkEvents(sockets[result], objects[result], &network_event); - if (network_event.lNetworkEvents & FD_READ) + if ((network_event.lNetworkEvents & FD_READ) && readfds) FD_SET(sockets[result], readfds); - if (network_event.lNetworkEvents & FD_WRITE) + if ((network_event.lNetworkEvents & FD_WRITE) && writefds) FD_SET(sockets[result], writefds); - if (network_event.lNetworkEvents & FD_OOB) + if ((network_event.lNetworkEvents & FD_OOB) && exceptfds) FD_SET(sockets[result], exceptfds); res = 1; diff --git a/src/lib/ecore/ecore_pipe.c b/src/lib/ecore/ecore_pipe.c index debdbe8..b178ee4 100644 --- a/src/lib/ecore/ecore_pipe.c +++ b/src/lib/ecore/ecore_pipe.c @@ -143,6 +143,9 @@ ecore_pipe_add(Ecore_Pipe_Cb handler, p->handler = handler; p->data = data; + _ecore_fd_close_on_exec(fds[0]); + _ecore_fd_close_on_exec(fds[1]); + fcntl(p->fd_read, F_SETFL, O_NONBLOCK); p->fd_handler = ecore_main_fd_handler_add(p->fd_read, ECORE_FD_READ, @@ -543,6 +546,7 @@ _ecore_pipe_read(void *data, else if ((ret == PIPE_FD_ERROR) && ((errno == EINTR) || (errno == EAGAIN))) { + _ecore_pipe_unhandle(p); return ECORE_CALLBACK_RENEW; } else @@ -550,6 +554,7 @@ _ecore_pipe_read(void *data, ERR("An unhandled error (ret: %i errno: %i [%s])" "occurred while reading from the pipe the length", (int)ret, errno, strerror(errno)); + _ecore_pipe_unhandle(p); return ECORE_CALLBACK_RENEW; } #else diff --git a/src/lib/ecore/ecore_poll.c b/src/lib/ecore/ecore_poll.c index 384ee68..b84ecb1 100644 --- a/src/lib/ecore/ecore_poll.c +++ b/src/lib/ecore/ecore_poll.c @@ -2,11 +2,65 @@ # include #endif +#include "Ecore.h" + +#include #include +#include + +#ifdef __linux +#include +#include +#endif -#include "Ecore.h" #include "ecore_private.h" +/* Common declarations */ + +/* General fields for different backend type, + some type of base class but made by agregation, + TODO move some specific fields inside Backend */ +typedef struct +{ + int min_interval; + int interval_incr; + int at_tick; + int just_added_poller; + int poller_delete_count; + int poller_walking; + double poll_interval; + double poll_cur_interval; + struct timespec slast_tick; + double last_tick; + Ecore_Poller *pollers[16]; + unsigned short poller_counters[16]; +} _Backend_Data; + +typedef struct +{ + void (* set_poll_interval) ( _Backend_Data *data, + double poll_time); + + double (* get_poll_interval) (_Backend_Data *data); + + Ecore_Poller * (* add) (_Backend_Data *data, + int interval, Ecore_Task_Cb func, + const void *user_data); + + Eina_Bool (* set_poller_interval) (_Backend_Data *data, + Ecore_Poller *poller, int interval); + + int (* get_poller_interval) (_Backend_Data *data, Ecore_Poller *poller); + + void * (*delete) (_Backend_Data *data, Ecore_Poller *poller); + + void (* shutdown) (_Backend_Data *data); + + _Backend_Data data; +} Ecore_Poller_Backend; + +static Ecore_Poller_Backend *backends[ECORE_POLLER_TYPE_MAX]; + struct _Ecore_Poller { EINA_INLIST; @@ -15,201 +69,211 @@ struct _Ecore_Poller unsigned char delete_me : 1; Ecore_Task_Cb func; void *data; + Ecore_Poller_Type type; }; + GENERIC_ALLOC_SIZE_DECLARE(Ecore_Poller); -static Ecore_Timer *timer = NULL; -static int min_interval = -1; -static int interval_incr = 0; -static int at_tick = 0; -static int just_added_poller = 0; -static int poller_delete_count = 0; -static int poller_walking = 0; -static double poll_interval = 0.125; -static double poll_cur_interval = 0.0; -static double last_tick = 0.0; -static Ecore_Poller *pollers[16] = -{ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; -static unsigned short poller_counters[16] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; +/* TIMERFD part */ +#ifdef __linux +static Ecore_Fd_Handler *fdhandler; +/* TODO we could get it from fdhandler */ +static int timerfd; -static void _ecore_poller_next_tick_eval(void); -static Eina_Bool _ecore_poller_cb_timer(void *data); +/*TODO To common place */ +#ifndef SEC_TO_NSEC + #define SEC_TO_NSEC(x) ((x)*1000000000) +#endif + +#ifndef NSEC_TO_SEC + #define NSEC_TO_SEC(x) ((x)/1000000000) +#endif + + +#define TFD_ATTEMPTS 1 +#define TFD_TIMER_DEFERRABLE (2 << 1) + +static int flags = TFD_TIMER_ABSTIME | TFD_TIMER_DEFERRABLE; +#endif /* __linux */ +/* TIMERFD part */ + +/* common part */ static void -_ecore_poller_next_tick_eval(void) +_common_poller_next_tick_eval(_Backend_Data *bdata, + void (* timer_finalize) (void), + void (* timer_charge) (double interval, _Backend_Data *bdata), + void (* timer_recharge) (double interval, _Backend_Data *bdata), + bool (* timer_charged) (void)) { int i; double interval; + const bool was_charged = timer_charged(); - min_interval = -1; + bdata->min_interval = -1; for (i = 0; i < 15; i++) { - if (pollers[i]) + if (bdata->pollers[i]) { - min_interval = i; + bdata->min_interval = i; break; } } - if (min_interval < 0) + if (bdata->min_interval < 0) { /* no pollers */ - if (timer) - { - ecore_timer_del(timer); - timer = NULL; - } + timer_finalize(); return; } - interval_incr = (1 << min_interval); - interval = interval_incr * poll_interval; + bdata->interval_incr = (1 << bdata->min_interval); + interval = bdata->interval_incr * bdata->poll_interval; + + timer_charge(interval, bdata); /* we are at the tick callback - so no need to do inter-tick adjustments * so we can fasttrack this as t -= last_tick in theory is 0.0 (though * in practice it will be a very very very small value. also the tick - * callback will adjust the timer interval at the end anyway */ - if (at_tick) - { - if (!timer) - timer = ecore_timer_add(interval, _ecore_poller_cb_timer, NULL); - } - else - { - double t; - - if (!timer) - timer = ecore_timer_add(interval, _ecore_poller_cb_timer, NULL); - else - { - t = ecore_time_get(); - if (interval != poll_cur_interval) - { - t -= last_tick; /* time since we last ticked */ + * callback will adjust the timer interval at the end anyway + * if timer was charged at this iteration was_charged should be fasle + * */ + if (!bdata->at_tick && interval != bdata->poll_cur_interval && was_charged) + { + double t = ecore_time_get(); + t -= bdata->last_tick; /* time since we last ticked */ /* delete the timer and reset it to tick off in the new * time interval. at the tick this will be adjusted */ - ecore_timer_del(timer); - timer = ecore_timer_add(interval - t, - _ecore_poller_cb_timer, NULL); - } - } - } - poll_cur_interval = interval; + timer_recharge(interval - t, bdata); + } + bdata->poll_cur_interval = interval; } static Eina_Bool -_ecore_poller_cb_timer(void *data __UNUSED__) +_common_poller_cb(void *data, + void ( * _next_tick_eval) (_Backend_Data *bdata), + Eina_Bool (* _timer_interval_adjust) (double interval)) { int i; Ecore_Poller *poller, *l; + _Backend_Data *bdata = (_Backend_Data *)data; int changes = 0; - at_tick++; - last_tick = ecore_time_get(); + bdata->at_tick++; + bdata->last_tick = ecore_time_get(); /* we have 16 counters - each increments every time the poller counter * "ticks". it increments by the minimum interval (which can be 1, 2, 4, * 7, 16 etc. up to 32768) */ for (i = 0; i < 15; i++) { - poller_counters[i] += interval_incr; + bdata->poller_counters[i] += bdata->interval_incr; /* wrap back to 0 if we exceed out loop count for the counter */ - if (poller_counters[i] >= (1 << i)) poller_counters[i] = 0; + if (bdata->poller_counters[i] >= + (1 << i)) bdata->poller_counters[i] = 0; } - just_added_poller = 0; + bdata->just_added_poller = 0; /* walk the pollers now */ - poller_walking++; + bdata->poller_walking++; for (i = 0; i < 15; i++) { /* if the counter is @ 0 - this means that counter "went off" this * tick interval, so run all pollers hooked to that counter */ - if (poller_counters[i] == 0) + if (bdata->poller_counters[i] == 0) { - EINA_INLIST_FOREACH(pollers[i], poller) + EINA_INLIST_FOREACH(bdata->pollers[i], poller) { - if (!poller->delete_me) - { - if (!poller->func(poller->data)) - { - if (!poller->delete_me) - { - poller->delete_me = 1; - poller_delete_count++; - } - } - } + if (poller->delete_me) + continue; + + if (!poller->func(poller->data)) + { + if (!poller->delete_me) + { + poller->delete_me = 1; + bdata->poller_delete_count++; + } + } } } } - poller_walking--; + bdata->poller_walking--; /* handle deletes afterwards */ - if (poller_delete_count > 0) + if (bdata->poller_delete_count > 0) { /* FIXME: walk all pollers and remove deleted ones */ for (i = 0; i < 15; i++) { - for (l = pollers[i]; l; ) + for (l = bdata->pollers[i]; l; ) { poller = l; l = (Ecore_Poller *)EINA_INLIST_GET(l)->next; if (poller->delete_me) { - pollers[i] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(poller)); + bdata->pollers[i] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(bdata->pollers[i]), EINA_INLIST_GET(poller)); ecore_poller_mp_free(poller); - poller_delete_count--; + bdata->poller_delete_count--; changes++; - if (poller_delete_count <= 0) break; + if (bdata->poller_delete_count <= 0) break; } } - if (poller_delete_count <= 0) break; + if (bdata->poller_delete_count <= 0) break; } } /* if we deleted or added any pollers, then we need to re-evaluate our * minimum poll interval */ - if ((changes > 0) || (just_added_poller > 0)) - _ecore_poller_next_tick_eval(); + if ((changes > 0) || (bdata->just_added_poller > 0)) + _next_tick_eval(bdata); - just_added_poller = 0; - poller_delete_count = 0; + bdata->just_added_poller = 0; + bdata->poller_delete_count = 0; - at_tick--; + bdata->at_tick--; - /* if the timer was deleted then there is no point returning 1 - ambiguous - * if we do as it implies keep running me" but we have been deleted - * anyway */ - if (!timer) return ECORE_CALLBACK_CANCEL; - - /* adjust interval */ - ecore_timer_interval_set(timer, poll_cur_interval); - return ECORE_CALLBACK_RENEW; + return _timer_interval_adjust(bdata->poll_cur_interval); } -EAPI void -ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__, - double poll_time) +static Eina_Bool +_common_poller_poller_interval_set(_Backend_Data *bdata, Ecore_Poller *poller, int interval, void ( * _next_tick_eval) (_Backend_Data *bdata)) { - EINA_MAIN_LOOP_CHECK_RETURN; - poll_interval = poll_time; - _ecore_poller_next_tick_eval(); -} + int ibit; -EAPI double -ecore_poller_poll_interval_get(Ecore_Poller_Type type __UNUSED__) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0); - return poll_interval; + EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); + if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER)) + { + ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER, + "ecore_poller_poller_interval_set"); + return EINA_FALSE; + } + + /* interval MUST be a power of 2, so enforce it */ + if (interval < 1) interval = 1; + ibit = -1; + while (interval != 0) + { + ibit++; + interval >>= 1; + } + /* only allow up to 32768 - i.e. ibit == 15, so limit it */ + if (ibit > 15) ibit = 15; + /* if interval specified is the same as interval set, return true without wasting time */ + if (poller->ibit == ibit) + return EINA_TRUE; + bdata->pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(bdata->pollers[poller->ibit]), EINA_INLIST_GET(poller)); + poller->ibit = ibit; + bdata->pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_prepend(EINA_INLIST_GET(bdata->pollers[poller->ibit]), EINA_INLIST_GET(poller)); + if (bdata->poller_walking) + bdata->just_added_poller++; + else + _next_tick_eval(bdata); + return EINA_TRUE; } -EAPI Ecore_Poller * -ecore_poller_add(Ecore_Poller_Type type __UNUSED__, +static Ecore_Poller * +_common_poller_add(_Backend_Data *bdata, int interval, Ecore_Task_Cb func, - const void *data) + const void *data, + void ( * _next_tick_eval) (_Backend_Data *bdata) +) { Ecore_Poller *poller; int ibit; @@ -221,6 +285,7 @@ ecore_poller_add(Ecore_Poller_Type type __UNUSED__, poller = ecore_poller_calloc(1); if (!poller) return NULL; ECORE_MAGIC_SET(poller, ECORE_MAGIC_POLLER); + /* interval MUST be a power of 2, so enforce it */ if (interval < 1) interval = 1; ibit = -1; @@ -235,53 +300,45 @@ ecore_poller_add(Ecore_Poller_Type type __UNUSED__, poller->ibit = ibit; poller->func = func; poller->data = (void *)data; - pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller)); - if (poller_walking) - just_added_poller++; + bdata->pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_prepend(EINA_INLIST_GET(bdata->pollers[poller->ibit]), EINA_INLIST_GET(poller)); + if (bdata->poller_walking) + bdata->just_added_poller++; else - _ecore_poller_next_tick_eval(); + _next_tick_eval(bdata); return poller; } -EAPI Eina_Bool -ecore_poller_poller_interval_set(Ecore_Poller *poller, - int interval) +static void +_common_poller_core_shutdown(_Backend_Data *bdata, + void (* timer_finalize) (void)) { - int ibit; + int i; + Ecore_Poller *poller; - EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); - if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER)) + for (i = 0; i < 15; i++) { - ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER, - "ecore_poller_poller_interval_set"); - return EINA_FALSE; + while ((poller = bdata->pollers[i])) + { + bdata->pollers[i] = (Ecore_Poller *)eina_inlist_remove ( + EINA_INLIST_GET(bdata->pollers[i]), + EINA_INLIST_GET(bdata->pollers[i])); + ecore_poller_mp_free(poller); + } } - /* interval MUST be a power of 2, so enforce it */ - if (interval < 1) interval = 1; - ibit = -1; - while (interval != 0) - { - ibit++; - interval >>= 1; - } - /* only allow up to 32768 - i.e. ibit == 15, so limit it */ - if (ibit > 15) ibit = 15; - /* if interval specified is the same as interval set, return true without wasting time */ - if (poller->ibit == ibit) - return EINA_TRUE; - pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller)); - poller->ibit = ibit; - pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller)); - if (poller_walking) - just_added_poller++; - else - _ecore_poller_next_tick_eval(); - return EINA_TRUE; + if (timer_finalize) + timer_finalize(); } -EAPI int -ecore_poller_poller_interval_get(Ecore_Poller *poller) +static double +_common_poller_poll_interval_get(_Backend_Data *bdata) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0); + return bdata->poll_interval; +} + +static int +_common_poller_poller_interval_get(_Backend_Data *bdata __UNUSED__, Ecore_Poller *poller) { int ibit, interval = 1; @@ -302,8 +359,9 @@ ecore_poller_poller_interval_get(Ecore_Poller *poller) return interval; } -EAPI void * -ecore_poller_del(Ecore_Poller *poller) +static void * +_common_poller_del(_Backend_Data *bdata, Ecore_Poller *poller, + void ( * _next_tick_eval) (_Backend_Data *bdata)) { void *data; @@ -314,40 +372,489 @@ ecore_poller_del(Ecore_Poller *poller) "ecore_poller_del"); return NULL; } + /* we are walking the poller list - a bad idea to remove from it while * walking it, so just flag it as delete_me and come back to it after * the loop has finished */ - if (poller_walking > 0) + if (bdata->poller_walking > 0) { - poller_delete_count++; + bdata->poller_delete_count++; poller->delete_me = 1; return poller->data; } /* not in loop so safe - delete immediately */ data = poller->data; - pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller)); + bdata->pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(bdata->pollers[poller->ibit]), EINA_INLIST_GET(poller)); ecore_poller_mp_free(poller); - _ecore_poller_next_tick_eval(); + _next_tick_eval(bdata); return data; } +/* common part */ + +/* CORE part */ + +static Ecore_Timer *timer; +static Eina_Bool _ecore_poller_cb_timer(void *data); + +static void +_ecore_timer_finalize(void) +{ + if (!timer) return; + + ecore_timer_del(timer); + timer = NULL; +} + +static void +_ecore_timer_charge(double interval, _Backend_Data *bdata) +{ + if (!timer) + timer = ecore_timer_add(interval, _ecore_poller_cb_timer, bdata); +} + +static void +_ecore_timer_recharge(double interval, _Backend_Data *bdata) +{ + if (!timer) return; + + ecore_timer_del(timer); + timer = ecore_timer_add(interval, + _ecore_poller_cb_timer, bdata); +} + +static Eina_Bool +_ecore_interval_adjust(double interval) +{ + /* if the timer was deleted then there is no point returning 1 - ambiguous + * if we do as it implies keep running me" but we have been deleted + * anyway */ + if (!timer) return ECORE_CALLBACK_CANCEL; + + /* adjust interval */ + ecore_timer_interval_set(timer, interval); + return ECORE_CALLBACK_RENEW; +} + +static bool +_ecore_timer_charged(void) +{ + return timer; +} + +static void +_ecore_poller_next_tick_eval(_Backend_Data *bdata) +{ + _common_poller_next_tick_eval(bdata, _ecore_timer_finalize, _ecore_timer_charge, + _ecore_timer_recharge, _ecore_timer_charged); +} + +static Eina_Bool +_ecore_poller_cb_timer(void *data) +{ + return _common_poller_cb(data, _ecore_poller_next_tick_eval, _ecore_interval_adjust); +} + +static void +_ecore_poller_poll_interval_set(_Backend_Data *bdata, double poll_time) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + bdata->poll_interval = poll_time; + _ecore_poller_next_tick_eval(bdata); +} + +static Eina_Bool +_ecore_poller_poller_interval_set(_Backend_Data *bdata, Ecore_Poller *poller, int interval) +{ + return _common_poller_poller_interval_set(bdata, poller, interval, + _ecore_poller_next_tick_eval); +} + +static void * +_ecore_poller_del(_Backend_Data *bdata, Ecore_Poller *poller) +{ + return _common_poller_del(bdata, poller, _ecore_poller_next_tick_eval); +} + +static void +_ecore_poller_core_shutdown(_Backend_Data *bdata) +{ + _common_poller_core_shutdown(bdata, NULL); +} + +static Ecore_Poller * +_ecore_poller_add(_Backend_Data *bdata, + int interval, + Ecore_Task_Cb func, + const void *data) +{ + Ecore_Poller *poller = _common_poller_add(bdata, interval, func, data, + _ecore_poller_next_tick_eval); + EINA_SAFETY_ON_NULL_RETURN_VAL(poller, NULL); + poller->type = ECORE_POLLER_CORE; + return poller; +} + +/* end CORE part */ + +/* TIMERFD part */ + +#ifdef __linux + +static Eina_Bool _lazy_poller_cb_handler(void *data, + Ecore_Fd_Handler __UNUSED__ * fd_handler); + +static void +_timespec_ns_add(struct timespec *spec, double nsecs) +{ + double new_nsec = NSEC_TO_SEC(spec->tv_nsec + nsecs); + double new_sec; + new_nsec = modf(new_nsec, &new_sec); + spec->tv_sec += new_sec; + spec->tv_nsec += new_nsec; +} + /** - * @} + * @desc start/repetion timer interval + * @param new_value output itimerspec + * @param interval - time interval in microseconds */ +static int +_itimespec_prepare(struct itimerspec *new_value, const double interval) +{ + struct timespec now; + int ret; + double secs; + double usecs; + + if (!new_value) + { + ERR("Please provide valid pointer!"); + return -EINVAL; + } + + usecs = modf(interval, &secs); + + ret = clock_gettime(CLOCK_MONOTONIC, &now); + if (ret < 0) return -errno; + + new_value->it_value.tv_nsec = now.tv_nsec; + new_value->it_value.tv_sec = now.tv_sec; + + usecs = SEC_TO_NSEC(usecs); + _timespec_ns_add(&new_value->it_value, usecs); + new_value->it_value.tv_sec +=(int)secs; + + new_value->it_interval.tv_sec = (int)secs; + new_value->it_interval.tv_nsec = usecs; + return 0; +} + +static void +_fdhandler_interval_set(double interval, _Backend_Data __UNUSED__ *bdata) +{ + int ret; + int flags = TFD_TIMER_ABSTIME; + struct itimerspec new_value; + + _itimespec_prepare(&new_value, interval); + + /* use flags which was defined at add time, + * due it couldn't be changed w/o reboot */ + ret = timerfd_settime(timerfd, flags, &new_value, NULL); + if (ret < 0) + { + ERR("Couldn't set timer timerfd time %s", strerror(errno)); + } +} + +static void +_fdhandler_add(double interval, + _Backend_Data *bdata) +{ + struct itimerspec new_value; + int ret, i; + + if (timerfd && fdhandler) return; + + timerfd = timerfd_create(CLOCK_MONOTONIC, 0); + /* calculate new_value */ + ret = _itimespec_prepare(&new_value, interval); + if (ret < 0) + { + ERR("Couldn't calculate new timer value %s", strerror(ret)); + goto release_fd; + } + + for (i = 0; i < TFD_ATTEMPTS; ++i) + { + ret = timerfd_settime(timerfd, flags, &new_value, NULL); + if (ret < 0) + flags &= ~TFD_TIMER_DEFERRABLE; + else + break; + } + + if (ret < 0) + { + ERR("Couldn't set timerfd time %s", strerror(errno)); + goto release_fd; + } + + fdhandler = ecore_main_fd_handler_add(timerfd, + ECORE_FD_READ | ECORE_FD_ERROR, + _lazy_poller_cb_handler, + bdata, NULL, NULL); + if (fdhandler == 0) + { + ERR("Couldn't add ecore fd handler"); + goto release_fd; + } + + return; + +release_fd: + close(timerfd); +} + +static void +_fdhandler_finalize(void) +{ + /* no pollers */ + if (!fdhandler) return; + + ecore_main_fd_handler_del(fdhandler); + close(timerfd); + fdhandler = NULL; +} + +static bool +_fdhandler_charged(void) +{ + return fdhandler && timerfd; +} + +static void +_lazy_poller_next_tick_eval(_Backend_Data *bdata) +{ + _common_poller_next_tick_eval(bdata, _fdhandler_finalize, _fdhandler_add, + _fdhandler_interval_set, _fdhandler_charged); +} + +static Eina_Bool +_lazy_interval_adjust(double interval) +{ + /* if the timer was deleted then there is no point returning 1 - ambiguous + * if we do as it implies keep running me" but we have been deleted + * anyway */ + if (!fdhandler) return ECORE_CALLBACK_CANCEL; + + /* adjust interval */ + _fdhandler_interval_set(interval, NULL); + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_lazy_poller_cb_handler(void *data, Ecore_Fd_Handler __UNUSED__ * fd_handler) +{ + return _common_poller_cb(data, _lazy_poller_next_tick_eval, _lazy_interval_adjust); +} + +static void +_lazy_poller_poll_interval_set(_Backend_Data *bdata, double poll_time) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + bdata->poll_interval = poll_time; + _lazy_poller_next_tick_eval(bdata); +} + +static Ecore_Poller * +_lazy_poller_add(_Backend_Data *bdata, + int interval, + Ecore_Task_Cb func, + const void *data) +{ + Ecore_Poller *poller = _common_poller_add(bdata, interval, func, data, + _lazy_poller_next_tick_eval); + EINA_SAFETY_ON_NULL_RETURN_VAL(poller, NULL); + poller->type = ECORE_POLLER_LAZY; + return poller; +} + +static Eina_Bool +_lazy_poller_poller_interval_set(_Backend_Data *bdata, Ecore_Poller *poller, int interval) +{ + return _common_poller_poller_interval_set(bdata, poller, interval, + _lazy_poller_next_tick_eval); +} + +static void * +_lazy_poller_del(_Backend_Data *bdata, Ecore_Poller *poller) +{ + return _common_poller_del(bdata, poller, _lazy_poller_next_tick_eval); +} + +static void +_lazy_poller_core_shutdown(_Backend_Data *bdata) +{ + _common_poller_core_shutdown(bdata, _fdhandler_finalize); +} + +/* Without register just static for all */ +static Ecore_Poller_Backend ecore_poller_lazy = +{ + .set_poll_interval = _lazy_poller_poll_interval_set, + .get_poll_interval = _common_poller_poll_interval_get, + .add = _lazy_poller_add, + .set_poller_interval = _lazy_poller_poller_interval_set, + .get_poller_interval = _common_poller_poller_interval_get, + .delete = _lazy_poller_del, + .shutdown = _lazy_poller_core_shutdown, + .data = { + .min_interval = -1, + .interval_incr = 0, + .at_tick = 0, + .just_added_poller = 0, + .poller_delete_count = 0, + .poller_walking = 0, + .poll_interval = 0.125, + .poll_cur_interval = 0.0, + .last_tick = 0.0, + .pollers = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }, + .poller_counters = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + } + }, +}; + +#endif /* __linux */ + +/* TIMERFD part */ + +/** + * @} + */ void _ecore_poller_shutdown(void) { int i; - Ecore_Poller *poller; - - for (i = 0; i < 15; i++) + for (i = 0; i < ECORE_POLLER_TYPE_MAX; ++i) { - while ((poller = pollers[i])) - { - pollers[i] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(pollers[i])); - ecore_poller_mp_free(poller); - } + if (backends[i]) + continue; + backends[i]->shutdown(&backends[i]->data); } } +/* main part */ +static Ecore_Poller_Backend * +_ecore_poller_backend_by_type(Ecore_Poller_Type type) +{ + if (type < ECORE_POLLER_TYPE_MAX) + return backends[type]; + + ERR("Unknown poller"); + return NULL; +} + +static Ecore_Poller_Backend * +_ecore_poller_backend_by_poller(Ecore_Poller *poller) +{ + return _ecore_poller_backend_by_type(poller->type); +} + +EAPI void +ecore_poller_poll_interval_set(Ecore_Poller_Type type, + double poll_time) +{ + Ecore_Poller_Backend *backend = _ecore_poller_backend_by_type(type); + if (!backend) return; + + backend->set_poll_interval(&backend->data, poll_time); +} + +EAPI double +ecore_poller_poll_interval_get(Ecore_Poller_Type type) +{ + Ecore_Poller_Backend *backend = _ecore_poller_backend_by_type(type); + return backend ? backend->get_poll_interval(&backend->data) : 0; +} + +EAPI Ecore_Poller * +ecore_poller_add(Ecore_Poller_Type type, + int interval, + Ecore_Task_Cb func, + const void *data) +{ + Ecore_Poller_Backend *backend = _ecore_poller_backend_by_type(type); + return backend ? backend->add(&backend->data, interval, func, data) : NULL; +} + +EAPI Eina_Bool +ecore_poller_poller_interval_set(Ecore_Poller *poller, + int interval) +{ + Ecore_Poller_Backend *backend = _ecore_poller_backend_by_poller(poller); + return backend ? + backend->set_poller_interval(&backend->data, poller, interval) : EINA_FALSE; +} + +EAPI int +ecore_poller_poller_interval_get(Ecore_Poller *poller) +{ + Ecore_Poller_Backend *backend = _ecore_poller_backend_by_poller(poller); + return backend ? backend->get_poller_interval(&backend->data, poller) : + 0; +} + +EAPI void * +ecore_poller_del(Ecore_Poller *poller) +{ + Ecore_Poller_Backend *backend = _ecore_poller_backend_by_poller(poller); + return backend ? backend->delete(&backend->data, poller) : NULL; +} + +/* Without register just static for all */ +static Ecore_Poller_Backend ecore_poller_core = +{ + .set_poll_interval = _ecore_poller_poll_interval_set, + .get_poll_interval = _common_poller_poll_interval_get, + .add = _ecore_poller_add, + .set_poller_interval = _ecore_poller_poller_interval_set, + .get_poller_interval = _common_poller_poller_interval_get, + .delete = _ecore_poller_del, + .shutdown = _ecore_poller_core_shutdown, + .data = { + .min_interval = -1, + .interval_incr = 0, + .at_tick = 0, + .just_added_poller = 0, + .poller_delete_count = 0, + .poller_walking = 0, + .poll_interval = 0.125, + .poll_cur_interval = 0.0, + .last_tick = 0.0, + .pollers = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }, + .poller_counters = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + } + }, +}; + +static Ecore_Poller_Backend *backends[ECORE_POLLER_TYPE_MAX] = { + [ECORE_POLLER_CORE] = &ecore_poller_core, +#ifdef __linux + [ECORE_POLLER_LAZY] = &ecore_poller_lazy, +#endif +}; + diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h index d812e3a..6c4543c 100644 --- a/src/lib/ecore/ecore_private.h +++ b/src/lib/ecore/ecore_private.h @@ -172,6 +172,8 @@ void *_ecore_event_signal_realtime_new(void); void *_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); +Eina_Bool _ecore_fd_close_on_exec(int fd); + void _ecore_main_shutdown(void); #if defined (_WIN32) || defined (__lv2ppu__) || defined (HAVE_EXOTIC) diff --git a/src/lib/ecore/ecore_thread.c b/src/lib/ecore/ecore_thread.c index b91d0fe..7ece392 100644 --- a/src/lib/ecore/ecore_thread.c +++ b/src/lib/ecore/ecore_thread.c @@ -66,35 +66,62 @@ typedef struct void *val; } win32_thread; +static Eina_List *_ecore_thread_win32_threads = NULL; +static Eina_Lock _ecore_thread_win32_lock; + # define PH(x) win32_thread * x # define PHE(x, y) ((x) == (y)) -# define PHS() (HANDLE)GetCurrentThreadId() -int +static win32_thread * +_ecore_thread_win32_self() +{ + win32_thread *t; + Eina_List *l; + + LKL(_ecore_thread_win32_lock); + EINA_LIST_FOREACH(_ecore_thread_win32_threads, l, t) + if (t->thread == GetCurrentThread()) + { + LKU(_ecore_thread_win32_lock); + return t; + } + + LKU(_ecore_thread_win32_lock); + return NULL; +} + +# define PHS() _ecore_thread_win32_self() + +static int _ecore_thread_win32_create(win32_thread **x, LPTHREAD_START_ROUTINE f, void *d) { win32_thread *t; + t = (win32_thread *)calloc(1, sizeof(win32_thread)); if (!t) return -1; + LKL(_ecore_thread_win32_lock); (t)->thread = CreateThread(NULL, 0, f, d, 0, NULL); if (!t->thread) { free(t); + LKU(_ecore_thread_win32_lock); return -1; } t->val = d; *x = t; + _ecore_thread_win32_threads = eina_list_append(_ecore_thread_win32_threads, t); + LKU(_ecore_thread_win32_lock); return 0; } # define PHC(x, f, d) _ecore_thread_win32_create(&(x), (LPTHREAD_START_ROUTINE)f, d) -int +static int _ecore_thread_win32_join(win32_thread *x, void **res) { @@ -104,6 +131,7 @@ _ecore_thread_win32_join(win32_thread *x, CloseHandle(x->thread); } if (res) *res = x->val; + _ecore_thread_win32_threads = eina_list_remove(_ecore_thread_win32_threads, x); free(x); return 0; @@ -216,11 +244,13 @@ static int _ecore_thread_count_max = 0; static void _ecore_thread_handler(void *data); static int _ecore_thread_count = 0; +int _ecore_thread_count_real = 0; static Eina_List *_ecore_running_job = NULL; static Eina_List *_ecore_pending_job_threads = NULL; static Eina_List *_ecore_pending_job_threads_feedback = NULL; static LK(_ecore_pending_job_threads_mutex); +static LK(_ecore_running_job_mutex); static Eina_Hash *_ecore_thread_global_hash = NULL; static LRWK(_ecore_thread_global_hash_lock); @@ -281,6 +311,7 @@ static void _ecore_thread_join(PH(thread)) { PHJ(thread); + _ecore_thread_count_real--; } static void @@ -414,8 +445,11 @@ _ecore_short_job(PH(thread)) work = eina_list_data_get(_ecore_pending_job_threads); _ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads, _ecore_pending_job_threads); - _ecore_running_job = eina_list_append(_ecore_running_job, work); LKU(_ecore_pending_job_threads_mutex); + + LKL(_ecore_running_job_mutex); + _ecore_running_job = eina_list_append(_ecore_running_job, work); + LKU(_ecore_running_job_mutex); LKL(work->cancel_mutex); cancel = work->cancel; @@ -424,9 +458,9 @@ _ecore_short_job(PH(thread)) if (!cancel) work->u.short_run.func_blocking((void *) work->data, (Ecore_Thread*) work); - LKL(_ecore_pending_job_threads_mutex); + LKL(_ecore_running_job_mutex); _ecore_running_job = eina_list_remove(_ecore_running_job, work); - LKU(_ecore_pending_job_threads_mutex); + LKU(_ecore_running_job_mutex); if (work->reschedule) { @@ -459,8 +493,10 @@ _ecore_feedback_job(PH(thread)) work = eina_list_data_get(_ecore_pending_job_threads_feedback); _ecore_pending_job_threads_feedback = eina_list_remove_list(_ecore_pending_job_threads_feedback, _ecore_pending_job_threads_feedback); - _ecore_running_job = eina_list_append(_ecore_running_job, work); LKU(_ecore_pending_job_threads_mutex); + LKL(_ecore_running_job_mutex); + _ecore_running_job = eina_list_append(_ecore_running_job, work); + LKU(_ecore_running_job_mutex); LKL(work->cancel_mutex); cancel = work->cancel; @@ -469,9 +505,9 @@ _ecore_feedback_job(PH(thread)) if (!cancel) work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work); - LKL(_ecore_pending_job_threads_mutex); + LKL(_ecore_running_job_mutex); _ecore_running_job = eina_list_remove(_ecore_running_job, work); - LKU(_ecore_pending_job_threads_mutex); + LKU(_ecore_running_job_mutex); if (work->reschedule) { @@ -591,9 +627,13 @@ _ecore_thread_init(void) _ecore_thread_count_max = 1; #ifdef EFL_HAVE_THREADS +# ifdef EFL_HAVE_WIN32_THREADS + LKI(_ecore_thread_win32_lock); +# endif LKI(_ecore_pending_job_threads_mutex); LRWKI(_ecore_thread_global_hash_lock); LKI(_ecore_thread_global_hash_mutex); + LKI(_ecore_running_job_mutex); CDI(_ecore_thread_global_hash_cond, _ecore_thread_global_hash_mutex); #endif } @@ -624,10 +664,13 @@ _ecore_thread_shutdown(void) free(work); } + LKU(_ecore_pending_job_threads_mutex); + LKL(_ecore_running_job_mutex); + EINA_LIST_FOREACH(_ecore_running_job, l, work) ecore_thread_cancel((Ecore_Thread*) work); - LKU(_ecore_pending_job_threads_mutex); + LKU(_ecore_running_job_mutex); do { @@ -663,7 +706,11 @@ _ecore_thread_shutdown(void) LKD(_ecore_pending_job_threads_mutex); LRWKD(_ecore_thread_global_hash_lock); LKD(_ecore_thread_global_hash_mutex); + LKD(_ecore_running_job_mutex); CDD(_ecore_thread_global_hash_cond); +# ifdef EFL_HAVE_WIN32_THREADS + LKU(_ecore_thread_win32_lock); +# endif #endif } @@ -725,6 +772,7 @@ ecore_thread_run(Ecore_Thread_Cb func_blocking, retry: if (PHC(thread, _ecore_thread_worker, NULL) == 0) { + _ecore_thread_count_real++; _ecore_thread_count++; LKU(_ecore_pending_job_threads_mutex); return (Ecore_Thread *)work; @@ -928,7 +976,10 @@ ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy, retry_direct: if (PHC(t, _ecore_direct_worker, worker) == 0) - return (Ecore_Thread *)worker; + { + _ecore_thread_count_real++; + return (Ecore_Thread *)worker; + } if (!tried) { _ecore_main_call_flush(); @@ -965,6 +1016,7 @@ ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy, retry: if (PHC(thread, _ecore_thread_worker, NULL) == 0) { + _ecore_thread_count_real++; _ecore_thread_count++; LKU(_ecore_pending_job_threads_mutex); return (Ecore_Thread *)worker; @@ -1062,7 +1114,7 @@ ecore_thread_feedback(Ecore_Thread *thread, Ecore_Pthread_Message *msg; Ecore_Pthread_Notify *notify; - msg = malloc(sizeof (Ecore_Pthread_Message*)); + msg = malloc(sizeof (Ecore_Pthread_Message)); if (!msg) return EINA_FALSE; msg->data = data; msg->callback = EINA_FALSE; @@ -1344,9 +1396,14 @@ ecore_thread_local_data_set(Ecore_Thread *thread, r = eina_hash_set(worker->hash, key, d); CDB(worker->cond); - ret = r->data; - free(r); - return ret; + + if (r) + { + ret = r->data; + free(r); + return ret; + } + return NULL; #else (void) cb; return NULL; @@ -1426,7 +1483,10 @@ ecore_thread_global_data_add(const char *key, d->cb = cb; if (!_ecore_thread_global_hash) - return EINA_FALSE; + { + free(d); + return EINA_FALSE; + } LRWKWL(_ecore_thread_global_hash_lock); if (direct) ret = eina_hash_direct_add(_ecore_thread_global_hash, key, d); @@ -1474,9 +1534,13 @@ ecore_thread_global_data_set(const char *key, LRWKU(_ecore_thread_global_hash_lock); CDB(_ecore_thread_global_hash_cond); - ret = r->data; - free(r); - return ret; + if (r) + { + ret = r->data; + free(r); + return ret; + } + return NULL; #else (void) cb; return NULL; diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c index b5b6e6d..fef1b9c 100644 --- a/src/lib/ecore/ecore_timer.c +++ b/src/lib/ecore/ecore_timer.c @@ -161,18 +161,6 @@ unlock: return timer; } -/** - * Creates a timer to call the given function in the given period of time. - * @param in The interval in seconds from current loop time. - * @param func The given function. If @p func returns 1, the timer is - * rescheduled for the next interval @p in. - * @param data Data to pass to @p func when it is called. - * @return A timer object on success. @c NULL on failure. - * - * This is the same as ecore_timer_add(), but "now" is the time from - * ecore_loop_time_get() not ecore_time_get() as ecore_timer_add() uses. See - * ecore_timer_add() for more details. - */ EAPI Ecore_Timer * ecore_timer_loop_add(double in, Ecore_Task_Cb func, @@ -201,6 +189,7 @@ EAPI void * ecore_timer_del(Ecore_Timer *timer) { void *data = NULL; + if (!timer) return NULL; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); _ecore_lock(); @@ -232,7 +221,7 @@ ecore_timer_interval_set(Ecore_Timer *timer, { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); - + if (in < 0.0) in = 0.0; if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, diff --git a/src/lib/ecore_cocoa/Ecore_Cocoa.h b/src/lib/ecore_cocoa/Ecore_Cocoa.h index 51c8ead..c5d059a 100644 --- a/src/lib/ecore_cocoa/Ecore_Cocoa.h +++ b/src/lib/ecore_cocoa/Ecore_Cocoa.h @@ -2,13 +2,13 @@ #define __ECORE_COCOA_H__ /* - * DO NOT USE THIS HEADER. IT IS WORK IN PROGRESS. IT IS NOT FINAL AND + * DO NOT USE THIS HEADER. IT IS A WORK IN PROGRESS API. IT IS NOT FINAL AND * THE API MAY CHANGE. */ #ifndef ECORE_COCOA_WIP_GNSIDNQI # warning "You are using a work in progress API. This API is not stable" -# warning "and is subject to change. You use this at your own risk." +# warning "and is subject to change. You can use this at your own risk." #endif #ifdef EAPI diff --git a/src/lib/ecore_con/Ecore_Con.h b/src/lib/ecore_con/Ecore_Con.h index 0a832fc..a299c03 100644 --- a/src/lib/ecore_con/Ecore_Con.h +++ b/src/lib/ecore_con/Ecore_Con.h @@ -37,11 +37,13 @@ #endif /** + * @internal * @defgroup Ecore_Con_Group Ecore_Con - Connection functions + * @ingroup Ecore_Group * * The Ecore Connection Library ( @c Ecore_Con ) provides simple mechanisms - * for communications between programs using reliable sockets. It saves - * the programmer from having to worry about file descriptors and waiting + * for communications between programs using reliable sockets. It saves + * you from having to worry about file descriptors and waiting * for incoming connections. * * There are two main objects in the @c Ecore_Con library: the @c @@ -68,136 +70,140 @@ /** + * @internal * @defgroup Ecore_Con_Events_Group Ecore Connection Events Functions + * @ingroup Ecore_Con_Group * * @li ECORE_CON_CLIENT_ADD: Whenever a client connection is made to an * @c Ecore_Con_Server, an event of this type is emitted, allowing the - * retrieval of the client's ip with @ref ecore_con_client_ip_get and + * retrieval of the client's IP with @ref ecore_con_client_ip_get and * associating data with the client using ecore_con_client_data_set. * @li ECORE_CON_EVENT_CLIENT_DEL: Whenever a client connection to an - * @c Ecore_Con_Server, an event of this type is emitted. The contents of + * @c Ecore_Con_Server, an event of this type is emitted. The contents of * the data with this event are variable, but if the client object in the data * is non-null, it must be freed with @ref ecore_con_client_del. * @li ECORE_CON_EVENT_SERVER_ADD: Whenever a server object is created * with @ref ecore_con_server_connect, an event of this type is emitted, * allowing for data to be serialized and sent to the server using - * @ref ecore_con_server_send. At this point, the http handshake has + * @ref ecore_con_server_send. At this point, the HTTP handshake has * occurred. * @li ECORE_CON_EVENT_SERVER_DEL: Whenever a server object is destroyed, * usually by the server connection being refused or dropped, an event of this - * type is emitted. The contents of the data with this event are variable, + * type is emitted. The contents of the data with this event are variable, * but if the server object in the data is non-null, it must be freed * with @ref ecore_con_server_del. * @li ECORE_CON_EVENT_CLIENT_DATA: Whenever a client connects to your server - * object and sends data, an event of this type is emitted. The data will contain both - * the size and contents of the message sent by the client. It should be noted that + * object and sends data, an event of this type is emitted. The data contains both + * the size and contents of the message sent by the client. It should be noted that * data within this object is transient, so it must be duplicated in order to be - * retained. This event will continue to occur until the client has stopped sending its - * message, so a good option for storing this data is an Eina_Strbuf. Once the message has + * retained. This event continues to occur until the client has stopped sending its + * message, so a good option for storing this data is an Eina_Strbuf. Once the message has * been received in full, the client object must be freed with ecore_con_client_free. * @li ECORE_CON_EVENT_SERVER_DATA: Whenever your server object connects to its destination - * and receives data, an event of this type is emitted. The data will contain both - * the size and contents of the message sent by the server. It should be noted that + * and receives data, an event of this type is emitted. The data contains both + * the size and contents of the message sent by the server. It should be noted that * data within this object is transient, so it must be duplicated in order to be - * retained. This event will continue to occur until the server has stopped sending its - * message, so a good option for storing this data is an Eina_Strbuf. Once the message has + * retained. This event continues to occur until the server has stopped sending its + * message, so a good option for storing this data is an Eina_Strbuf. Once the message has * been received in full, the server object must be freed with ecore_con_server_free. * */ /** + * @internal * @defgroup Ecore_Con_Buffer Ecore Connection Buffering - * - * As Ecore_Con works on an event driven design, as data arrives, events will - * be produced containing the data that arrived. It is up to the user of + * @ingroup Ecore_Con_Group + * + * As Ecore_Con works on an event driven design, as data arrives, events are + * produced containing the data that arrived. It is up to the user of * Ecore_Con to either parse as they go, append to a file to later parse the * whole file in one go, or append to memory to parse or handle leter. - * - * To help with this Eina has some handy API's. The Eina_Binbuf and - * Eina_Strbuf APIs, abstract dynamic buffer management and make it trivial - * to handle buffers at runtime, without having to manage them. Eina_Binbuf - * makes it possible to create, expand, reset and slice a blob of memory - - * all via API. No system calls, no pointer manipulations and no size + * + * To help with this, Eina has some handy API's. The Eina_Binbuf and + * Eina_Strbuf APIs, abstract dynamic buffer management and make it trivial + * to handle buffers at runtime, without having to manage them. Eina_Binbuf + * makes it possible to create, expand, reset and slice a blob of memory - + * all via API. No system calls, no pointer manipulations and no size * calculation. - * - * Additional functions include adding content at specified byte positions in - * the buffer, escaping the inputs, find and replace strings. This provides + * + * Additional functions include adding content at specified byte positions in + * the buffer, escaping the inputs, find and replace strings. This provides * extreme flexibility to play around, with a dynamic blob of memory. - * + * * It is good to free it (using eina_binbuf_free()) after using it. - * + * * Eina_Binbuf compliments Ecore_Con use cases, where dynamic sizes of data * arrive from the network (think http download in chunks). Using * Eina_Binbuf provides enough flexibility to handle data as it arrives and * to defer its processing until desired, without having to think about * where to store the temporary data and how to manage its size. - * + * * An example of how to use these with Ecore_Con follows. - * + * * @code * #include * #include * #include - * + * * static Eina_Bool * data_callback(void *data, int type, void *event) * { * Ecore_Con_Event_Url_Data *url_data = event; * if ( url_data->size > 0) * { - * // append data as it arrives - don't worry where or how it gets stored. - * // Also don't worry about size, expanding, reallocing etc. - * // just keep appending - size is automatically handled. - * + * // Append data as it arrives - do not worry where or how it gets stored. + * // Also do not worry about size, expanding, reallocing etc. + * // Just keep appending - size is automatically handled. + * * eina_binbuf_append_length(data, url_data->data, url_data->size); - * + * * fprintf(stderr, "Appended %d \n", url_data->size); * } * return EINA_TRUE; * } - * - * - * + * + * + * * static Eina_Bool * completion_callback(void *data, int type, void *event) * { * Ecore_Con_Event_Url_Complete *url_complete = event; * printf("download completed with status code: %d\n", url_complete->status); - * - * // get the data back from Eina_Binbuf + * + * // Get the data back from Eina_Binbuf * char *ptr = eina_binbuf_string_get(data); * size_t size = eina_binbuf_length_get(data); - * - * // process data as required (write to file) + * + * // Process data as required (write to file) * fprintf(stderr, "Size of data = %d bytes\n", size); * int fd = open("./elm.png", O_CREAT); * write(fd, ptr, size); * close(fd); - * - * // free it when done. + * + * // Free it when done. * eina_binbuf_free(data); - * + * * ecore_main_loop_quit(); - * + * * return EINA_TRUE; * } - * - * + * + * * int * main(int argc, char **argv) * { - * + * * const char *url = "http://www.enlightenment.org/p/index/d/logo.png"; - * + * * ecore_init(); * ecore_con_init(); * ecore_con_url_init(); - * - * + * + * * // This is single additional line to manage dynamic network data. * Eina_Binbuf *data = eina_binbuf_new(); * Ecore_Con_Url *url_con = ecore_con_url_new(url); - * + * * ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, * completion_callback, * data); @@ -205,7 +211,7 @@ * data_callback, * data); * ecore_con_url_get(url_con); - * + * * ecore_main_loop_begin(); * return 0; * } @@ -221,148 +227,153 @@ extern "C" { /** * @typedef Ecore_Con_Server - * A connection handle to a server + * @brief The structure type containing a connection handle to a server. * @ingroup Ecore_Con_Server_Group */ typedef struct _Ecore_Con_Server Ecore_Con_Server; /** * @typedef Ecore_Con_Client - * A connection handle to a client + * @brief The structure type containing a connection handle to a client. * @ingroup Ecore_Con_Client_Group */ typedef struct _Ecore_Con_Client Ecore_Con_Client; /** * @typedef Ecore_Con_Socks - * An object representing a SOCKS proxy - * @ingroup Ecore_Con_Socks_Group + * @brief The structure type containing an object representing a SOCKS proxy. + * * @since 1.2 + * + * @ingroup Ecore_Con_Socks_Group */ typedef struct Ecore_Con_Socks Ecore_Con_Socks; /** * @typedef Ecore_Con_Url - * A handle to an http upload/download object + * @brief The structure type containing a handle to an HTTP upload/download object. * @ingroup Ecore_Con_Url_Group */ typedef struct _Ecore_Con_Url Ecore_Con_Url; /** + * @internal * @addtogroup Ecore_Con_Events_Group + * * @{ */ /** * @typedef Ecore_Con_Event_Client_Add - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event */ typedef struct _Ecore_Con_Event_Client_Add Ecore_Con_Event_Client_Add; /** * @typedef Ecore_Con_Event_Client_Upgrade - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. * @since 1.1 */ typedef struct _Ecore_Con_Event_Client_Upgrade Ecore_Con_Event_Client_Upgrade; /** * @typedef Ecore_Con_Event_Client_Del - * Used as the @p data param for the corresponding event + * @brief The structure type containing a connection used as the @a data param for the corresponding event. */ typedef struct _Ecore_Con_Event_Client_Del Ecore_Con_Event_Client_Del; /** * @typedef Ecore_Con_Event_Client_Error - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. * @since 1.1 */ typedef struct _Ecore_Con_Event_Client_Error Ecore_Con_Event_Client_Error; /** * @typedef Ecore_Con_Event_Server_Add - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. */ typedef struct _Ecore_Con_Event_Server_Add Ecore_Con_Event_Server_Add; /** * @typedef Ecore_Con_Event_Server_Upgrade - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. * @since 1.1 */ typedef struct _Ecore_Con_Event_Server_Upgrade Ecore_Con_Event_Server_Upgrade; /** * @typedef Ecore_Con_Event_Server_Del - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. */ typedef struct _Ecore_Con_Event_Server_Del Ecore_Con_Event_Server_Del; /** * @typedef Ecore_Con_Event_Server_Error - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. * @since 1.1 */ typedef struct _Ecore_Con_Event_Server_Error Ecore_Con_Event_Server_Error; /** * @typedef Ecore_Con_Event_Client_Data - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. */ typedef struct _Ecore_Con_Event_Client_Data Ecore_Con_Event_Client_Data; /** * @typedef Ecore_Con_Event_Server_Data - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. */ typedef struct _Ecore_Con_Event_Server_Data Ecore_Con_Event_Server_Data; /** * @typedef Ecore_Con_Event_Client_Write - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. * @since 1.1 */ typedef struct _Ecore_Con_Event_Client_Write Ecore_Con_Event_Client_Write; /** * @typedef Ecore_Con_Event_Server_Write - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. * @since 1.1 */ typedef struct _Ecore_Con_Event_Server_Write Ecore_Con_Event_Server_Write; /** * @typedef Ecore_Con_Event_Proxy_Bind - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. * @since 1.2 */ typedef struct _Ecore_Con_Event_Proxy_Bind Ecore_Con_Event_Proxy_Bind; /** * @typedef Ecore_Con_Event_Url_Data - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. * @ingroup Ecore_Con_Url_Group */ typedef struct _Ecore_Con_Event_Url_Data Ecore_Con_Event_Url_Data; /** * @typedef Ecore_Con_Event_Url_Complete - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. * @ingroup Ecore_Con_Url_Group */ typedef struct _Ecore_Con_Event_Url_Complete Ecore_Con_Event_Url_Complete; /** * @typedef Ecore_Con_Event_Url_Progress - * Used as the @p data param for the corresponding event + * @brief The structure type used as the @a data param for the corresponding event. * @ingroup Ecore_Con_Url_Group */ typedef struct _Ecore_Con_Event_Url_Progress Ecore_Con_Event_Url_Progress; /** + * @internal * @struct _Ecore_Con_Event_Client_Add - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_ADD event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_CLIENT_ADD event. */ struct _Ecore_Con_Event_Client_Add { @@ -370,168 +381,184 @@ struct _Ecore_Con_Event_Client_Add }; /** + * @internal * @struct _Ecore_Con_Event_Client_Upgrade - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_UPGRADE event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_CLIENT_UPGRADE event. * @since 1.1 */ struct _Ecore_Con_Event_Client_Upgrade { - Ecore_Con_Client *client; /** the client that completed handshake */ + Ecore_Con_Client *client; /** The client that completed handshake */ }; /** + * @internal * @struct _Ecore_Con_Event_Client_Del - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DEL event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_CLIENT_DEL event. */ struct _Ecore_Con_Event_Client_Del { - Ecore_Con_Client *client; /** the client that was lost */ + Ecore_Con_Client *client; /** The client that was lost */ }; /** + * @internal * @struct _Ecore_Con_Event_Client_Error - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_ERROR event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_CLIENT_ERROR event. */ struct _Ecore_Con_Event_Client_Error { - Ecore_Con_Client *client; /** the client for which an error occurred */ - char *error; /**< the error string describing what happened */ + Ecore_Con_Client *client; /** The client for which an error occurred */ + char *error; /**< The error string describing what happened */ }; /** + * @internal * @struct _Ecore_Con_Event_Server_Add - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_ADD event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_SERVER_ADD event. */ struct _Ecore_Con_Event_Server_Add { - Ecore_Con_Server *server; /** the server that was connected to */ + Ecore_Con_Server *server; /** The server that is connected to */ }; /** + * @internal * @struct _Ecore_Con_Event_Server_Upgrade - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_UPGRADE event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_SERVER_UPGRADE event. * @since 1.1 */ struct _Ecore_Con_Event_Server_Upgrade { - Ecore_Con_Server *server; /** the server that was connected to */ + Ecore_Con_Server *server; /** The server that is connected to */ }; /** + * @internal * @struct _Ecore_Con_Event_Server_Del - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DEL event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_SERVER_DEL event. */ struct _Ecore_Con_Event_Server_Del { - Ecore_Con_Server *server; /** the client that was lost */ + Ecore_Con_Server *server; /** The client that is lost */ }; /** + * @internal * @struct _Ecore_Con_Event_Server_Error - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_ERROR event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_SERVER_ERROR event. */ struct _Ecore_Con_Event_Server_Error { - Ecore_Con_Server *server; /** the server for which an error occurred */ - char *error; /**< the error string describing what happened */ + Ecore_Con_Server *server; /** The server for which an error occurred */ + char *error; /**< The error string describing what happened */ }; /** + * @internal * @struct _Ecore_Con_Event_Client_Data - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DATA event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_CLIENT_DATA event. */ struct _Ecore_Con_Event_Client_Data { - Ecore_Con_Client *client; /**< the client that connected */ - void *data; /**< the data that the client sent */ - int size; /**< the length of the data sent */ + Ecore_Con_Client *client; /**< The client that connected */ + void *data; /**< The data that the client sent */ + int size; /**< The length of the data sent */ }; /** + * @internal * @struct _Ecore_Con_Event_Server_Data - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DATA event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_SERVER_DATA event. */ struct _Ecore_Con_Event_Server_Data { - Ecore_Con_Server *server; /**< the server that was connected to */ - void *data; /**< the data that the server sent */ - int size; /**< the length of the data sent */ + Ecore_Con_Server *server; /**< The server that is connected to */ + void *data; /**< The data that the server sent */ + int size; /**< The length of the data sent */ }; /** + * @internal * @struct _Ecore_Con_Event_Client_Write - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_WRITE event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_CLIENT_WRITE event. */ struct _Ecore_Con_Event_Client_Write { - Ecore_Con_Client *client; /**< the client that connected */ - int size; /**< the length of the data sent */ + Ecore_Con_Client *client; /**< The client that connected */ + int size; /**< The length of the data sent */ }; /** + * @internal * @struct _Ecore_Con_Event_Server_Write - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_WRITE event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_SERVER_WRITE event. */ struct _Ecore_Con_Event_Server_Write { - Ecore_Con_Server *server; /**< the server that was connected to */ - int size; /**< the length of the data sent */ + Ecore_Con_Server *server; /**< The server that is connected to */ + int size; /**< The length of the data sent */ }; /** + * @internal * @struct _Ecore_Con_Event_Proxy_Bind - * Used as the @p data param for the @ref ECORE_CON_EVENT_PROXY_BIND event - * @ingroup Ecore_Con_Socks_Group + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_PROXY_BIND event. + * * @since 1.2 + * @ingroup Ecore_Con_Socks_Group */ struct _Ecore_Con_Event_Proxy_Bind { - Ecore_Con_Server *server; /**< the server object connected to the proxy */ - const char *ip; /**< the proxy-bound ip address */ - int port; /**< the proxy-bound port */ + Ecore_Con_Server *server; /**< The server object connected to the proxy */ + const char *ip; /**< The proxy-bound ip address */ + int port; /**< The proxy-bound port */ }; /** + * @internal * @struct _Ecore_Con_Event_Url_Data - * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_DATA event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_URL_DATA event. * @ingroup Ecore_Con_Url_Group */ struct _Ecore_Con_Event_Url_Data { - Ecore_Con_Url *url_con; /**< a pointer to the connection object */ - int size; /**< the size of the current received data (in bytes) */ - unsigned char data[1]; /**< the data received on this event */ + Ecore_Con_Url *url_con; /**< A pointer to the connection object */ + int size; /**< The size of the current received data (in bytes) */ + unsigned char data[1]; /**< The data received on this event */ }; /** + * @internal * @struct _Ecore_Con_Event_Url_Complete - * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_COMPLETE event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_URL_COMPLETE event. * @ingroup Ecore_Con_Url_Group */ struct _Ecore_Con_Event_Url_Complete { - Ecore_Con_Url *url_con; /**< a pointer to the connection object */ + Ecore_Con_Url *url_con; /**< A pointer to the connection object */ int status; /**< HTTP status code of the operation (200, 404, 401, etc.) */ }; /** + * @internal * @struct _Ecore_Con_Event_Url_Progress - * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_PROGRESS event + * @brief The structure type used as the @a data param for the @ref ECORE_CON_EVENT_URL_PROGRESS event. * @ingroup Ecore_Con_Url_Group */ struct _Ecore_Con_Event_Url_Progress { - Ecore_Con_Url *url_con; /**< a pointer to the connection object */ + Ecore_Con_Url *url_con; /**< A pointer to the connection object */ struct { - double total; /**< total size of the downloading data (in bytes) */ - double now; /**< current size of the downloading data (in bytes) */ - } down; /**< download info */ + double total; /**< Total size of the downloading data (in bytes) */ + double now; /**< Current size of the downloading data (in bytes) */ + } down; /**< Download info */ struct { - double total; /**< total size of the uploading data (in bytes) */ - double now; /**< current size of the uploading data (in bytes) */ - } up; /**< upload info */ + double total; /**< Total size of the uploading data (in bytes) */ + double now; /**< Current size of the uploading data (in bytes) */ + } up; /**< Upload info */ }; /** A client has connected to the server */ @@ -546,9 +573,9 @@ EAPI extern int ECORE_CON_EVENT_CLIENT_ERROR; * @since 1.1 */ EAPI extern int ECORE_CON_EVENT_CLIENT_UPGRADE; -/** A server was created */ +/** A server is created */ EAPI extern int ECORE_CON_EVENT_SERVER_ADD; -/** A server connection was lost */ +/** A server connection is lost */ EAPI extern int ECORE_CON_EVENT_SERVER_DEL; /** A server experienced an error * @since 1.1 @@ -586,17 +613,16 @@ EAPI extern int ECORE_CON_EVENT_URL_PROGRESS; */ /** + * @internal * @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions + * @ingroup Ecore_Con_Group * - * Utility functions that set up and shut down the Ecore Connection - * library. + * @brief This group provides utility functions that set up and shut down the Ecore Connection + * library. * - * There's also ecore_con_lookup() that can be used to make simple asynchronous + * There is also ecore_con_lookup() that can be used to make simple asynchronous * DNS lookups. * - * A simple example of how to use these functions: - * @li @ref ecore_con_lookup_example_c - * * @{ */ @@ -613,9 +639,9 @@ typedef void (*Ecore_Con_Dns_Cb)(const char *canonname, /** * @typedef Ecore_Con_Type * @enum _Ecore_Con_Type - * Types for an ecore_con client/server object. A correct way to set this type is - * with an ECORE_CON_$TYPE, optionally OR'ed with an ECORE_CON_$USE if encryption is desired, - * and LOAD_CERT if the previously loaded certificate should be used. + * @brief Enumeration of the types for an ecore_con client/server object. A correct way to set this type is + * with an ECORE_CON_$TYPE, optionally OR'ed with an ECORE_CON_$USE if encryption is desired, + * and LOAD_CERT if the previously loaded certificate should be used. * @code * ECORE_CON_REMOTE_TCP | ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT * @endcode @@ -662,41 +688,41 @@ typedef enum _Ecore_Con_Type } Ecore_Con_Type; /** - * Initialises the Ecore_Con library. - * @return Number of times the library has been initialised without being - * shut down. + * @brief Initialises the Ecore_Con library. * - * @note This function already calls ecore_init() internally, so you don't need - * to call it explicitly. + * @remarks This function already calls ecore_init() internally. So you do not need + * to call it explicitly. + * @return The number of times the library has been initialised without being shut down */ EAPI int ecore_con_init(void); /** - * Shuts down the Ecore_Con library. - * @return Number of times the library has been initialised without being - * shut down. - * @note This function already calls ecore_shutdown() internally, so you don't - * need to call it explicitly unless you called ecore_init() explicitly too. + * @brief Shuts down the Ecore_Con library. + * + * @remarks This function already calls ecore_shutdown() internally. So you do not + * need to call it explicitly unless you called ecore_init() explicitly too. + * + * @return The number of times the library has been initialised without being shut down */ EAPI int ecore_con_shutdown(void); /** - * Do an asynchronous DNS lookup. + * @brief Does an asynchronous DNS lookup. * - * @param name IP address or server name to translate. - * @param done_cb Callback to notify when done. - * @param data User data to be given to done_cb. - * @return @c EINA_TRUE if the request did not fail to be set up, @c EINA_FALSE - * if it failed. + * @details This function performs a DNS lookup on the hostname specified by @a name, + * then calls @a done_cb with the result and the @a data given as parameter. + * The result is given to the @a done_cb as follows: + * @li @c canonname - the canonical name of the address + * @li @c ip - the resolved IP address + * @li @c addr - a pointer to the socket address + * @li @c addrlen - the length of the socket address, in bytes + * @li @c data - the data pointer given as parameter to ecore_con_lookup() * - * This function performs a DNS lookup on the hostname specified by @p name, - * then calls @p done_cb with the result and the @p data given as parameter. - * The result will be given to the @p done_cb as follows: - * @li @c canonname - the canonical name of the address - * @li @c ip - the resolved ip address - * @li @c addr - a pointer to the socket address - * @li @c addrlen - the length of the socket address, in bytes - * @li @c data - the data pointer given as parameter to ecore_con_lookup() + * @param[in] name The IP address or server name to translate + * @param[in] done_cb The callback to notify when done + * @param[in] data The user data to be given to done_cb + * @return @c EINA_TRUE if the request did not fail to be set up, \n + * otherwise @c EINA_FALSE if it failed */ EAPI Eina_Bool ecore_con_lookup(const char *name, Ecore_Con_Dns_Cb done_cb, @@ -707,7 +733,9 @@ EAPI Eina_Bool ecore_con_lookup(const char *name, */ /** + * @internal * @defgroup Ecore_Con_SSL_Group Ecore Connection SSL Functions + * @ingroup Ecore_Con_Group * * @{ */ @@ -743,17 +771,19 @@ EAPI void ecore_con_socks_apply_once(Ecore_Con_Socks *ecs); EAPI void ecore_con_socks_apply_always(Ecore_Con_Socks *ecs); /** + * @internal * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions + * @ingroup Ecore_Con_Group * - * This group of functions is applied to an @ref Ecore_Con_Server object. It - * doesn't mean that they should be used in the server application, but on the - * server object. In fact, most of them should be used in the client - * application, when retrieving information or sending data. + * @brief This group of functions is applied to an @ref Ecore_Con_Server object. It + * does not mean that they should be used in the server application, but on the + * server object. In fact, most of them should be used in the client + * application, when retrieving information or sending data. * * Setting up a server is very simple: you just need to start it with * ecore_con_server_add() and setup some callbacks to the events * @ref ECORE_CON_EVENT_CLIENT_ADD, @ref ECORE_CON_EVENT_CLIENT_DEL and - * @ref ECORE_CON_EVENT_CLIENT_DATA, that will be called when a client is + * @ref ECORE_CON_EVENT_CLIENT_DATA, that is called when a client is * communicating with the server: * * @code @@ -768,7 +798,7 @@ EAPI void ecore_con_socks_apply_always(Ecore_Con_Socks *ecs); * @endcode * * The function ecore_con_server_connect() can be used to write a client that - * connects to a server. The resulting code will be very similar to the server + * connects to a server. The resulting code is very similar to the server * code: * * @code @@ -783,201 +813,194 @@ EAPI void ecore_con_socks_apply_always(Ecore_Con_Socks *ecs); * @endcode * * After these two pieces of code are executed, respectively, in the server and - * client code, the server will be up and running and the client will try to + * client code, the server is up and running and the client tries to * connect to it. The connection, with its subsequent messages being sent from * server to client and client to server, can be represented in the following * sequence diagram: * * @htmlonly - * * Full size * @endhtmlonly * + * @image html ecore_con-client-server.png * @image rtf ecore_con-client-server.png - * @image latex ecore_con-client-server.eps width=\textwidth + * @image latex ecore_con-client-server.eps "ecore con client server" width=\textwidth * - * Please notice the important difference between these two codes: the first is + * Note the important difference between these two codes: the first is * used for writing a @b server, while the second should be used for writing a * @b client. * * A reference for the @c client functions can be found at @ref * Ecore_Con_Client_Group. * - * Examples of usage for this API can be found here: - * @li @ref ecore_con_server_simple_example_c - * @li @ref ecore_con_client_simple_example_c - * * @{ */ /** - * Creates a server to listen for connections. + * @brief Creates a server to listen for connections. * - * @param type The connection type. - * @param name Name to associate with the socket. It is used when - * generating the socket name of a Unix socket, or for - * determining what host to listen on for TCP sockets. - * @c NULL will not be accepted. - * @param port Number to identify socket. When a Unix socket is used, - * it becomes part of the socket name. When a TCP socket - * is used, it is used as the TCP port. - * @param data Data to associate with the created Ecore_Con_Server - * object. - * @return A new Ecore_Con_Server. + * @remarks The socket on which the server listens depends on the connection type: + * @li If @a type is @c ECORE_CON_LOCAL_USER, the server listens on + * the Unix socket "~/.ecore/[name]/[port]". + * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the server listens + * on Unix socket "/tmp/.ecore_service|[name]|[port]". + * @li If @a type is @c ECORE_CON_REMOTE_TCP, the server listens + * on TCP port @c port. * - * The socket on which the server listens depends on the connection - * type: - * @li If @a type is @c ECORE_CON_LOCAL_USER, the server will listen on - * the Unix socket "~/.ecore/[name]/[port]". - * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen - * on Unix socket "/tmp/.ecore_service|[name]|[port]". - * @li If @a type is @c ECORE_CON_REMOTE_TCP, the server will listen - * on TCP port @c port. + * @remarks More information about the @a type can be found at @ref _Ecore_Con_Type. * - * More information about the @p type can be found at @ref _Ecore_Con_Type. + * @remarks The @a data parameter can be fetched later using ecore_con_server_data_get() + * or changed with ecore_con_server_data_set(). * - * The @p data parameter can be fetched later using ecore_con_server_data_get() - * or changed with ecore_con_server_data_set(). + * @param[in] type The connection type + * @param[in] name The name to associate with the socket \n + * It is used when generating the socket name of a Unix socket, or for + * determining what host to listen on for TCP sockets. + * @c NULL is not accepted. + * @param[in] port The number to identify socket \n + * When a Unix socket is used, it becomes part of the socket name. + * When a TCP socket is used, it is used as the TCP port. + * @param[in] data The data to associate with the created Ecore_Con_Server object + * @return A new Ecore_Con_Server */ EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type, const char *name, int port, const void *data); /** - * Creates a connection to the specified server and returns an associated object. + * @brief Creates a connection to the specified server and returns an associated object. * - * @param type The connection type. - * @param name Name used when determining what socket to connect to. - * It is used to generate the socket name when the socket - * is a Unix socket. It is used as the hostname when - * connecting with a TCP socket. - * @param port Number to identify the socket to connect to. Used when - * generating the socket name for a Unix socket, or as the - * TCP port when connecting to a TCP socket. - * @param data Data to associate with the created Ecore_Con_Server - * object. - * @return A new Ecore_Con_Server. + * @remarks The socket to which the connection is made depends on the connection type: + * @li If @a type is @c ECORE_CON_LOCAL_USER, the function + * connects to the server at the Unix socket + * "~/.ecore/[name]/[port]". + * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the function + * connects to the server at the Unix socket + * "/tmp/.ecore_service|[name]|[port]". + * @li If @a type is @c ECORE_CON_REMOTE_TCP, the function + * connects to the server at the TCP port "[name]:[port]". * - * The socket to which the connection is made depends on the connection type: - * @li If @a type is @c ECORE_CON_LOCAL_USER, the function will - * connect to the server at the Unix socket - * "~/.ecore/[name]/[port]". - * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the function will - * connect to the server at the Unix socket - * "/tmp/.ecore_service|[name]|[port]". - * @li If @a type is @c ECORE_CON_REMOTE_TCP, the function will - * connect to the server at the TCP port "[name]:[port]". + * @remarks More information about the @a type can be found at @ref _Ecore_Con_Type. * - * More information about the @p type can be found at @ref _Ecore_Con_Type. + * @remarks This function does not block. It either succeeds, or fails due to invalid + * parameters, failed memory allocation, etc., returning @c NULL in that case. * - * This function won't block. It will either succeed, or fail due to invalid - * parameters, failed memory allocation, etc., returning @c NULL on that case. + * @remarks However, even if this call returns a valid @ref Ecore_Con_Server, the + * connection is only successfully completed if an event of type + * @ref ECORE_CON_EVENT_SERVER_ADD is received. If it fails to complete, an + * @ref ECORE_CON_EVENT_SERVER_DEL is received. * - * However, even if this call returns a valid @ref Ecore_Con_Server, the - * connection will only be successfully completed if an event of type - * @ref ECORE_CON_EVENT_SERVER_ADD is received. If it fails to complete, an - * @ref ECORE_CON_EVENT_SERVER_DEL will be received. + * @remarks The @a data parameter can be fetched later using ecore_con_server_data_get() + * or changed with ecore_con_server_data_set(). * - * The @p data parameter can be fetched later using ecore_con_server_data_get() - * or changed with ecore_con_server_data_set(). + * @param[in] type The connection type + * @param[in] name The name used when determining what socket to connect to \n + * It is used to generate the socket name when the socket + * is a Unix socket. It is used as the hostname when + * connecting with a TCP socket. + * @param[in] port The number to identify the socket to connect to \n + * It is used when generating the socket name for a Unix socket, + * or as the TCP port when connecting to a TCP socket. + * @param[in] data The data to associate with the created Ecore_Con_Server object + * @return A new Ecore_Con_Server */ EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type, const char *name, int port, const void *data); /** - * Closes the connection and frees the given server. + * @brief Closes the connection and frees the given server. * - * @param svr The given server. - * @return Data associated with the server when it was created. + * @remarks All the clients connected to this server is disconnected. * - * All the clients connected to this server will be disconnected. + * @param[in] svr The given server + * @return The data associated with the server when it is created * * @see ecore_con_server_add, ecore_con_server_connect */ EAPI void * ecore_con_server_del(Ecore_Con_Server *svr); /** - * Retrieves the data associated with the given server. + * @brief Gets the data associated with the given server. * - * @param svr The given server. - * @return The associated data. + * @param[in] svr The given server + * @return The associated data * * @see ecore_con_server_data_set() */ EAPI void * ecore_con_server_data_get(Ecore_Con_Server *svr); /** - * Sets the data associated with the given server. + * @brief Sets the data associated with the given server. * - * @param svr The given server. - * @param data The data to associate with @p svr - * @return The previously associated data, if any. + * @param[in] svr The given server + * @param[in] data The data to associate with @a svr + * @return The previously associated data, if any * * @see ecore_con_server_data_get() */ EAPI void * ecore_con_server_data_set(Ecore_Con_Server *svr, void *data); /** - * Retrieves whether the given server is currently connected. + * @brief Checks whether the given server is currently connected. * - * @param svr The given server. - * @return @c EINA_TRUE if the server is connected, @c EINA_FALSE otherwise. + * @param[in] svr The given server + * @return @c EINA_TRUE if the server is connected, \n + * otherwise @c EINA_FALSE if the server is not connected */ EAPI Eina_Bool ecore_con_server_connected_get(Ecore_Con_Server *svr); /** - * Retrieves the current list of clients. + * @brief Gets the current list of clients. * - * @param svr The given server. - * @return The list of clients on this server. + * @remarks Each node in the returned list points to an @ref Ecore_Con_Client. This list + * cannot be modified or freed. It can also change if new clients are connected + * or disconnected, and becomes invalid when the server is deleted or freed. * - * Each node in the returned list points to an @ref Ecore_Con_Client. This list - * cannot be modified or freed. It can also change if new clients are connected - * or disconnected, and will become invalid when the server is deleted/freed. + * @param[in] svr The given server + * @return The list of clients on this server */ EAPI const Eina_List * ecore_con_server_clients_get(Ecore_Con_Server *svr); /** - * Retrieves the name of server. + * @brief Gets the name of server. * - * @param svr The given server. - * @return The name of the server. + * @remarks The name returned is the name used to connect on this server. * - * The name returned is the name used to connect on this server. + * @param[in] svr The given server + * @return The name of the server */ EAPI const char * ecore_con_server_name_get(Ecore_Con_Server *svr); /** - * Retrieves the server port in use. + * @brief Gets the server port in use. * - * @param svr The given server. - * @return The server port in use. + * @remarks The port where the server is listening for connections. * - * The port where the server is listening for connections. + * @param[in] svr The given server + * @return The server port in use */ EAPI int ecore_con_server_port_get(Ecore_Con_Server *svr); /** - * @brief Check how long a server has been connected + * @brief Checks how long a server has been connected. * - * @param svr The server to check - * @return The total time, in seconds, that the server has been - * connected/running + * @details This function is used to find out the time that has been elapsed since + * ecore_con_server_add() succeeded. * - * This function is used to find out the time that has been elapsed since - * ecore_con_server_add() succeeded. + * @param[in] svr The server to check + * @return The total time, in seconds, that the server has been connected or running */ EAPI double ecore_con_server_uptime_get(Ecore_Con_Server *svr); /** - * Sends the given data to the given server. + * @brief Sends the given data to the given server. * - * @param svr The given server. - * @param data The given data. - * @param size Length of the data, in bytes, to send. - * @return The number of bytes sent. @c 0 will be returned if there is an - * error. + * @details This function sends the given data to the server as soon as the program + * is back to the main loop. Thus, this function returns immediately + * (non-blocking). If the data needs to be sent @b now, call + * ecore_con_server_flush() after this one. * - * This function will send the given data to the server as soon as the program - * is back to the main loop. Thus, this function returns immediately - * (non-blocking). If the data needs to be sent @b now, call - * ecore_con_server_flush() after this one. + * @param[in] svr The given server + * @param[in] data The given data + * @param[in] size The length of the data, in bytes, to send + * @return The number of bytes sent, \n + * otherwise @c 0 if there is an error * * @see ecore_con_client_send() * @see ecore_con_server_flush() @@ -986,80 +1009,76 @@ EAPI int ecore_con_server_send(Ecore_Con_Server *svr, const void *data, int size); /** - * Sets a limit on the number of clients that can be handled concurrently - * by the given server, and a policy on what to do if excess clients try to - * connect. - * - * @param svr The given server. - * @param client_limit The maximum number of clients to handle - * concurrently. -1 means unlimited (default). 0 - * effectively disables the server. - * @param reject_excess_clients Set to 1 to automatically disconnect - * excess clients as soon as they connect if you are - * already handling client_limit clients. Set to 0 - * (default) to just hold off on the "accept()" - * system call until the number of active clients - * drops. This causes the kernel to queue up to 4096 - * connections (or your kernel's limit, whichever is - * lower). - * - * Beware that if you set this once ecore is already running, you may - * already have pending CLIENT_ADD events in your event queue. Those - * clients have already connected and will not be affected by this call. - * Only clients subsequently trying to connect will be affected. + * @brief Sets a limit on the number of clients that can be handled concurrently + * by the given server, and a policy on what to do if excess clients try to + * connect. + * + * @remarks Beware that if you set this once, ecore is already running. You may + * already have pending CLIENT_ADD events in your event queue. Those + * clients have already connected and is not affected by this call. + * Only clients subsequently trying to connect is affected. + * + * @param[in] svr The given server + * @param[in] client_limit The maximum number of clients to handle concurrently \n + * @c -1 means unlimited (default), @c 0 effectively disables the server. + * @param[in] reject_excess_clients Set to @c 1 to automatically disconnect excess clients + * as soon as they connect if you are already handling client_limit clients \n + * otherwise set to @c 0 (default) to just hold off on the "accept()" + * system call until the number of active clients drops \n + * This causes the kernel to queue up to 4096 + * connections (or your kernel's limit, whichever is lower). */ EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients); /** - * Gets the IP address of a server that has been connected to. + * @brief Gets the IP address of a server that has been connected to. * - * @param svr The given server. + * @param[in] svr The given server * @return A pointer to an internal string that contains the IP address of - * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation. + * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation \n * This string should not be modified or trusted to stay valid after - * deletion for the @p svr object. If no IP is known @c NULL is - * returned. + * deletion for the @a svr object. If no IP is known, @c NULL is returned. */ EAPI const char * ecore_con_server_ip_get(Ecore_Con_Server *svr); /** - * Flushes all pending data to the given server. + * @brief Flushes all pending data to the given server. * - * @param svr The given server. + * @details This function blocks until all data is sent to the server. * - * This function will block until all data is sent to the server. + * @param[in] svr The given server * * @see ecore_con_server_send() * @see ecore_con_client_flush() */ EAPI void ecore_con_server_flush(Ecore_Con_Server *svr); /** - * Set the default time after which an inactive client will be disconnected + * @brief Sets the default time after which an inactive client is disconnected. * - * @param svr The server object - * @param timeout The timeout, in seconds, to disconnect after + * @details This function is used by the server to set the default idle timeout on + * clients. If the any of the clients becomes idle for a time higher than this + * value, it is disconnected. A value of < @c 1 disables the idle timeout. * - * This function is used by the server to set the default idle timeout on - * clients. If the any of the clients becomes idle for a time higher than this - * value, it will be disconnected. A value of < 1 disables the idle timeout. + * @remarks This timeout is not affected by the one set by + * ecore_con_client_timeout_set(). A client is disconnected whenever the + * client or the server timeout is reached. That means, the lower timeout value + * is used for that client if ecore_con_client_timeout_set() is used on it. * - * This timeout is not affected by the one set by - * ecore_con_client_timeout_set(). A client will be disconnected whenever the - * client or the server timeout is reached. That means, the lower timeout value - * will be used for that client if ecore_con_client_timeout_set() is used on it. + * @param[in] svr The server object + * @param[in] timeout The timeout, in seconds, to disconnect after * * @see ecore_con_server_timeout_get() * @see ecore_con_client_timeout_set() */ EAPI void ecore_con_server_timeout_set(Ecore_Con_Server *svr, double timeout); /** - * Get the default time after which an inactive client will be disconnected + * @brief Gets the default time after which an inactive client is disconnected. * - * @param svr The server object - * @return The timeout, in seconds, to disconnect after + * @details This function is used to get the idle timeout for clients. A value of < @c 1 + * means the idle timeout is disabled. * - * This function is used to get the idle timeout for clients. A value of < 1 - * means the idle timeout is disabled. + * @param[in] svr The server object + * @return The timeout, in seconds, to disconnect after * * @see ecore_con_server_timeout_set() * @see ecore_con_client_timeout_get() @@ -1067,28 +1086,32 @@ EAPI void ecore_con_server_timeout_set(Ecore_Con_Server *svr, doubl EAPI double ecore_con_server_timeout_get(Ecore_Con_Server *svr); /** - * Get the fd that the server is connected to + * @brief Get the fd that the server is connected to. * - * @param svr The server object - * @return The fd, or -1 on failure + * @details This function returns the fd which is used by the underlying server connection. + * It should not be tampered with unless you REALLY know what you are doing. + * @since 1.1 * - * This function returns the fd which is used by the underlying server connection. - * It should not be tampered with unless you REALLY know what you are doing. - * @note This function is only valid for servers created with ecore_con_server_connect() - * @warning Seriously. Don't use this unless you know what you are doing. - * @since 1.1 + * @remarks This function is only valid for servers created with ecore_con_server_connect() + * @remarks Do not use this unless you know what you are doing. + * + * @param[in] svr The server object + * @return The fd, \n + * otherwise @c -1 on failure */ EAPI int ecore_con_server_fd_get(Ecore_Con_Server *svr); /** - * Get the fd that the client is connected to + * @brief Gets the fd that the client is connected to. * - * @param cl The client object - * @return The fd, or -1 on failure + * @details This function returns the fd which is used by the underlying client connection. + * It should not be tampered with unless you REALLY know what you are doing. + * + * @since 1.1 * - * This function returns the fd which is used by the underlying client connection. - * It should not be tampered with unless you REALLY know what you are doing. - * @since 1.1 + * @param[in] cl The client object + * @return The fd, \n + * otherwise @c -1 on failure */ EAPI int ecore_con_client_fd_get(Ecore_Con_Client *cl); /** @@ -1096,9 +1119,11 @@ EAPI int ecore_con_client_fd_get(Ecore_Con_Client *cl); */ /** + * @internal * @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions + * @ingroup Ecore_Con_Group * - * Functions to communicate with and/or set options on a client. + * @brief This group provides functions to communicate with and/or set options on a client. * * This set of functions, as explained in @ref Ecore_Con_Server_Group, is used * to send data to a client, or to set options and get information about this @@ -1108,25 +1133,22 @@ EAPI int ecore_con_client_fd_get(Ecore_Con_Client *cl); * If you need to implement a client, the way to connect to a server is * described in @ref Ecore_Con_Server_Group. * - * An example of usage of these functions can be found at: - * @li @ref ecore_con_client_simple_example_c - * * @{ */ /** - * Sends the given data to the given client. + * @brief Sends the given data to the given client. * - * @param cl The given client. - * @param data The given data. - * @param size Length of the data, in bytes, to send. - * @return The number of bytes sent. @c 0 will be returned if there is an - * error. + * @details This function sends the given data to the client as soon as the program + * is back to the main loop. Thus, this function returns immediately + * (non-blocking). If the data needs to be sent @b now, call + * ecore_con_client_flush() after this one. * - * This function will send the given data to the client as soon as the program - * is back to the main loop. Thus, this function returns immediately - * (non-blocking). If the data needs to be sent @b now, call - * ecore_con_client_flush() after this one. + * @param[in] cl The given client + * @param[in] data The given data + * @param[in] size The length of the data, in bytes, to send + * @return The number of bytes sent, \n + * otherwise @c 0 if there is an error * * @see ecore_con_server_send() * @see ecore_con_client_flush() @@ -1135,133 +1157,139 @@ EAPI int ecore_con_client_send(Ecore_Con_Client *cl, const void *data, int size); /** - * Retrieves the server representing the socket the client has - * connected to. + * @brief Gets the server representing the socket the client has connected to. * - * @param cl The given client. - * @return The server that the client connected to. + * @param[in] cl The given client + * @return The server that the client connected to */ EAPI Ecore_Con_Server *ecore_con_client_server_get(Ecore_Con_Client *cl); + /** - * Closes the connection and frees memory allocated to the given client. + * @brief Closes the connection and frees the memory allocated to the given client. * - * @param cl The given client. - * @return Data associated with the client. + * @param[in] cl The given client + * @return The data associated with the client */ EAPI void * ecore_con_client_del(Ecore_Con_Client *cl); + /** - * Sets the data associated with the given client to @p data. + * @brief Sets the data associated with the given client to @a data. * - * @param cl The given client. - * @param data What to set the data to. + * @param[in] cl The given client + * @param[in] data The data to set */ EAPI void ecore_con_client_data_set(Ecore_Con_Client *cl, const void *data); /** - * Retrieves the data associated with the given client. + * @brief Gets the data associated with the given client. * - * @param cl The given client. - * @return The data associated with @p cl. + * @param[in] cl The given client + * @return The data associated with @a cl */ EAPI void * ecore_con_client_data_get(Ecore_Con_Client *cl); /** - * Gets the IP address of a client that has connected. + * @brief Gets the IP address of a client that has connected. * - * @param cl The given client. - * @return A pointer to an internal string that contains the IP address of - * the connected client in the form "XXX.YYY.ZZZ.AAA" IP notation. + * @remarks The returned string should not be modified, freed or trusted to stay valid + * after deletion for the @a cl object. If no IP is known @c NULL is returned. * - * The returned string should not be modified, freed or trusted to stay valid - * after deletion for the @p cl object. If no IP is known @c NULL is returned. + * @param[in] cl The given client + * @return A pointer to an internal string that contains the IP address of + * the connected client in the form "XXX.YYY.ZZZ.AAA" IP notation */ EAPI const char * ecore_con_client_ip_get(Ecore_Con_Client *cl); + /** - * Flushes all pending data to the given client. + * @brief Flushes all pending data to the given client. * - * @param cl The given client. + * @details This function blocks until all data is sent to the server. * - * This function will block until all data is sent to the server. + * @param[in] cl The given client * * @see ecore_con_client_send() * @see ecore_con_server_flush() */ EAPI void ecore_con_client_flush(Ecore_Con_Client *cl); + /** - * @brief Check how long a client has been connected + * @brief Checks how long a client has been connected. * - * @param cl The client to check - * @return The total time, in seconds, that the client has been connected to - * the server + * @details This function is used to find out how long a client has been connected for. * - * This function is used to find out how long a client has been connected for. + * @param[in] cl The client to check + * @return The total time, in seconds, that the client has been connected to the server */ EAPI double ecore_con_client_uptime_get(Ecore_Con_Client *cl); + /** - * Get the default time after which the client will be disconnected when - * inactive + * @brief Gets the default time after which the client is disconnected when inactive. * - * @param cl The client object - * @return The timeout, in seconds, to disconnect after + * @details This function is used to get the idle timeout for a client. A value of < @c 1 + * means the idle timeout is disabled. * - * This function is used to get the idle timeout for a client. A value of < 1 - * means the idle timeout is disabled. + * @param[in] cl The client object + * @return The timeout, in seconds, to disconnect after * * @see ecore_con_client_timeout_set() */ EAPI double ecore_con_client_timeout_get(Ecore_Con_Client *cl); + /** - * Set the time after which the client will be disconnected when inactive + * @brief Sets the time after which the client is disconnected when inactive. * - * @param cl The client object - * @param timeout The timeout, in seconds, to disconnect after + * @details This function is used by the server to set the idle timeout on a specific + * client. If the client becomes idle for a time higher than this value, it is + * disconnected. A value of < @c 1 disables the idle timeout. * - * This function is used by the server to set the idle timeout on a specific - * client. If the client becomes idle for a time higher than this value, it will - * be disconnected. A value of < 1 disables the idle timeout. + * @details This timeout is not affected by the one set by + * ecore_con_server_timeout_set(). A client is disconnected whenever the + * client or the server timeout is reached. That means, the lower timeout value + * is used for that client if ecore_con_server_timeout_set() is used on the server. * - * This timeout is not affected by the one set by - * ecore_con_server_timeout_set(). A client will be disconnected whenever the - * client or the server timeout is reached. That means, the lower timeout value - * will be used for that client if ecore_con_server_timeout_set() is used on the - * server. + * @param[in] cl The client object + * @param[in] timeout The timeout, in seconds, to disconnect after * * @see ecore_con_client_timeout_get() * @see ecore_con_server_timeout_set() */ EAPI void ecore_con_client_timeout_set(Ecore_Con_Client *cl, double timeout); + /** - * Returns whether the client is still connected + * @brief Checks whether the client is still connected. * - * @param cl The given client. - * @return @c EINA_TRUE if connected, @c EINA_FALSE otherwise. + * @param[in] cl The given client + * @return @c EINA_TRUE if connected, \n + * otherwise @c EINA_FALSE if it is not connected */ EAPI Eina_Bool ecore_con_client_connected_get(Ecore_Con_Client *cl); /** - * @brief Return the port that the client has connected to + * @brief Gets the port that the client has connected to. + * + * @remarks Use this function to return the port on which a given client has connected. * - * @param cl The client - * @return The port that @p cl has connected to, or -1 on error - * Use this function to return the port on which a given client has connected. + * @param[in] cl The client + * @return The port that @a cl has connected to, \n + * otherwise @c -1 on error */ EAPI int ecore_con_client_port_get(Ecore_Con_Client *cl); - - /** * @} */ /** + * @internal * @defgroup Ecore_Con_Url_Group Ecore URL Connection Functions + * @ingroup Ecore_Con_Group * - * Utility functions that set up, use and shut down the Ecore URL - * Connection library. + * @brief This group provides utility functions that set up, use and shut down the Ecore URL + * Connection library. * - * These functions are a shortcut to make it easy to perform http requests + * These functions are shortcuts to make it easy to perform HTTP requests * (POST, GET, etc). * - * Brief usage: + * Brief usage details: * 1. Create an Ecore_Con_Url object with ecore_con_url_new(url); * 2. Register to receive the #ECORE_CON_EVENT_URL_COMPLETE event * (and optionally the #ECORE_CON_EVENT_URL_DATA and @@ -1274,7 +1302,7 @@ EAPI int ecore_con_client_port_get(Ecore_Con_Client *cl); * need to wait for the #ECORE_CON_EVENT_URL_COMPLETE event before re-using or * destroying the object. * - * If it's necessary to change the @ref Ecore_Con_Url object url, use + * If it is necessary to change the @ref Ecore_Con_Url object url, use * ecore_con_url_url_set(). * * Simple Usage 1 (HTTP GET): @@ -1309,18 +1337,14 @@ EAPI int ecore_con_client_port_get(Ecore_Con_Client *cl); * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass","dir"); * @endcode * - * These are complete examples for the API: - * @li @ref ecore_con_url_download_example.c "Downloading a file" - * @li @ref ecore_con_url_headers_example.c "Setting many options for the connection" - * * @{ */ /** * @typedef Ecore_Con_Url_Time * @enum _Ecore_Con_Url_Time - * The type of condition to use when making an HTTP request dependent on time, - * so that headers such as "If-Modified-Since" are used. + * @brief Enumeration for the type of condition to use when making an HTTP request dependent on time, + * so that headers such as "If-Modified-Since" are used. */ typedef enum _Ecore_Con_Url_Time { @@ -1345,7 +1369,7 @@ typedef enum _Ecore_Con_Url_Time /** * @typedef Ecore_Con_Url_Http_Version * @enum _Ecore_Con_Url_Http_Version - * The http version to use + * @brief Enumeration of the HTTP version to use. * @since 1.2 */ typedef enum _Ecore_Con_Url_Http_Version @@ -1363,84 +1387,87 @@ typedef enum _Ecore_Con_Url_Http_Version } Ecore_Con_Url_Http_Version; /** - * Change the HTTP version used for the request - * @param url_con Connection object through which the request will be sent. - * @param version The version to be used - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure to change version. - * @since 1.2 + * @brief Changes the HTTP version used for the request. + * @since 1.2 + * + * @param[in] url_con The connection object through which the request is sent + * @param[in] version The version to be used + * @return @c EINA_TRUE if the version is changed successfully, \n + * otherwise @c EINA_FALSE on failure to change version * @see ecore_con_url_pipeline_get() */ EAPI Eina_Bool ecore_con_url_http_version_set(Ecore_Con_Url *url_con, Ecore_Con_Url_Http_Version version); - + /** - * Initialises the Ecore_Con_Url library. - * @return Number of times the library has been initialised without being - * shut down. + * @brief Initialises the Ecore_Con_Url library. * - * @note This function doesn't call ecore_con_init(). You still need to call it - * explicitly before calling this one. + * @remarks This function does not call ecore_con_init(). You still need to call it + * explicitly before calling this one. + * @return The number of times the library has been initialised without being shut down */ EAPI int ecore_con_url_init(void); /** - * Shuts down the Ecore_Con_Url library. - * @return Number of calls that still uses Ecore_Con_Url + * @brief Shuts down the Ecore_Con_Url library. * - * @note This function doesn't call ecore_con_shutdown(). You still need to call - * it explicitly after calling this one. + * @remarks This function does not call ecore_con_shutdown(). You still need to call + * it explicitly after calling this one. + * @return The number of calls that still uses Ecore_Con_Url */ EAPI int ecore_con_url_shutdown(void); /** - * Enable or disable HTTP 1.1 pipelining. - * @param enable @c EINA_TRUE will turn it on, @c EINA_FALSE will disable it. + * @brief Enables or disables HTTP 1.1 pipelining. * - * Pipelining allows to send one request after another one, without having to - * wait for the reply of the first request. The respective replies are received - * in the order that the requests were sent. + * @remarks Pipelining allows to send one request after another one, without having to + * wait for the reply of the first request. The respective replies are received + * in the order that the requests were sent. * - * Enabling this feature will be valid for all requests done using @c - * ecore_con_url. + * @remarks Enabling this feature is valid for all requests done using @c ecore_con_url. * - * See http://en.wikipedia.org/wiki/HTTP_pipelining for more info. + * @remarks See http://en.wikipedia.org/wiki/HTTP_pipelining for more info. * + * @param[in] enable Set @c EINA_TRUE to turn it on, \n + * otherwise @c EINA_FALSE to disable it * @see ecore_con_url_pipeline_get() */ EAPI void ecore_con_url_pipeline_set(Eina_Bool enable); /** - * Is HTTP 1.1 pipelining enable ? - * @return @c EINA_TRUE if it is enable. + * @brief Checks whether HTTP 1.1 pipelining is enabled. + * + * @return @c EINA_TRUE if it is enabled, \n + * otherwise @c EINA_FALSE if it is not enabled * * @see ecore_con_url_pipeline_set() */ EAPI Eina_Bool ecore_con_url_pipeline_get(void); /** - * Creates and initializes a new Ecore_Con_Url connection object. - * - * @param url URL that will receive requests. Can be changed using - * ecore_con_url_url_set. + * @brief Creates and initializes a new Ecore_Con_Url connection object. * - * @return @c NULL on error, a new Ecore_Con_Url on success. + * @details This function creates and initializes a new Ecore_Con_Url connection object that can be + * used for sending requests. * - * Creates and initializes a new Ecore_Con_Url connection object that can be - * used for sending requests. + * @param[in] url The URL that receives requests \n + * This can be changed using ecore_con_url_url_set. + * @return A new Ecore_Con_Url, \n + * otherwise @c NULL on error * * @see ecore_con_url_custom_new() * @see ecore_con_url_url_set() */ EAPI Ecore_Con_Url * ecore_con_url_new(const char *url); /** - * Creates a custom connection object. + * @brief Creates a custom connection object. * - * @param url URL that will receive requests - * @param custom_request Custom request (e.g. GET, POST, HEAD, PUT, etc) + * @details This function creates and initializes a new Ecore_Con_Url for a custom request (e.g. HEAD, + * SUBSCRIBE and other obscure HTTP requests). This object should be used like + * the one created with ecore_con_url_new(). * - * @return @c NULL on error, a new Ecore_Con_Url on success. - * - * Creates and initializes a new Ecore_Con_Url for a custom request (e.g. HEAD, - * SUBSCRIBE and other obscure HTTP requests). This object should be used like - * one created with ecore_con_url_new(). + * @param[in] url The URL that receives requests + * @param[in] custom_request The custom request (e.g. GET, POST, HEAD, PUT, etc) + * @return A new Ecore_Con_Url, \n + * otherwise @c NULL on error * * @see ecore_con_url_new() * @see ecore_con_url_url_set() @@ -1448,70 +1475,74 @@ EAPI Ecore_Con_Url * ecore_con_url_new(const char *url); EAPI Ecore_Con_Url * ecore_con_url_custom_new(const char *url, const char *custom_request); /** - * Destroys a Ecore_Con_Url connection object. + * @brief Destroys an Ecore_Con_Url connection object. * - * @param url_con Connection object to free. + * @param[in] url_con The connection object to free * * @see ecore_con_url_new() */ EAPI void ecore_con_url_free(Ecore_Con_Url *url_con); + /** - * Sets the URL to send the request to. + * @brief Sets the URL to send the request to. * - * @param url_con Connection object through which the request will be sent. - * @param url URL that will receive the request + * @param[in] url_con The connection object through which the request is sent + * @param[in] url The URL that receives the request * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. + * @return @c EINA_TRUE if the URL is set successfully, \n + * otherwise @c EINA_FALSE on error */ EAPI Eina_Bool ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url); /** - * Gets the URL to send the request to. + * @brief Gets the URL to send the request to. + * @since 1.1 * - * @param url_con Connection object through which the request will be sent. - * @return URL that will receive the request, @c NULL on failure. URL is - * stringshared. - * @since 1.1 + * @param[in] url_con The connection object through which the request is sent + * @return The URL that receives the request, \n + * otherwise @c NULL on failure \n + * URL is stringshared. */ EAPI const char *ecore_con_url_url_get(Ecore_Con_Url *url_con); + /** - * Associates data with a connection object. + * @brief Associates data with a connection object. * - * @param url_con Connection object to associate data. - * @param data Data to be set. + * @remarks Associates data with a connection object, which can be retrieved later with + * ecore_con_url_data_get()). * - * Associates data with a connection object, which can be retrieved later with - * ecore_con_url_data_get()). + * @param[in] url_con The connection object to associate data + * @param[in] data The data to be set * * @see ecore_con_url_data_get() */ EAPI void ecore_con_url_data_set(Ecore_Con_Url *url_con, void *data); /** - * Retrieves data associated with a Ecore_Con_Url connection object. + * @brief Gets data associated with a Ecore_Con_Url connection object. * - * @param url_con Connection object to retrieve data from. + * @details This function gets data associated with a Ecore_Con_Url connection object (previously + * set with ecore_con_url_data_set()). * - * @return Data associated with the given object. - * - * Retrieves data associated with a Ecore_Con_Url connection object (previously - * set with ecore_con_url_data_set()). + * @param[in] url_con The connection object to retrieve data from + * @return The data associated with the given object * * @see ecore_con_url_data_set() */ EAPI void * ecore_con_url_data_get(Ecore_Con_Url *url_con); + /** - * Adds an additional header to the request connection object. + * @brief Adds an additional header to the request connection object. * - * @param url_con Connection object - * @param key Header key - * @param value Header value + * @details This function adds an additional header (User-Agent, Content-Type, etc.) to the request + * connection object. This addition is valid for only one + * ecore_con_url_get() or ecore_con_url_post() call. * - * Adds an additional header (User-Agent, Content-Type, etc.) to the request - * connection object. This addition will be valid for only one - * ecore_con_url_get() or ecore_con_url_post() call. + * @remarks Some functions like ecore_con_url_time() also add headers to the request. * - * Some functions like ecore_con_url_time() also add headers to the request. + * @param[in] url_con The connection object + * @param[in] key The header key + * @param[in] value The header value * * @see ecore_con_url_get() * @see ecore_con_url_post() @@ -1520,88 +1551,92 @@ EAPI void * ecore_con_url_data_get(Ecore_Con_Url *url_con); EAPI void ecore_con_url_additional_header_add(Ecore_Con_Url *url_con, const char *key, const char *value); + /** - * Cleans additional headers. + * @brief Cleans additional headers. * - * @param url_con Connection object to clean additional headers. + * @details This function cleans additional headers associated with a connection object (previously + * added with ecore_con_url_additional_header_add()). * - * Cleans additional headers associated with a connection object (previously - * added with ecore_con_url_additional_header_add()). + * @param[in] url_con The connection object to clean additional headers * * @see ecore_con_url_additional_header_add() * @see ecore_con_url_get() * @see ecore_con_url_post() */ EAPI void ecore_con_url_additional_headers_clear(Ecore_Con_Url *url_con); + /** - * Retrieves headers from last request sent. - * - * @param url_con Connection object to retrieve response headers from. + * @brief Gets headers from last request sent. * - * Retrieves a list containing the response headers. This function should be - * used after an ECORE_CON_EVENT_URL_COMPLETE event (headers should normally be - * ready at that time). + * @details This function retrieves a list containing the response headers. This function should be + * used after an ECORE_CON_EVENT_URL_COMPLETE event (headers should normally be + * ready at that time). * - * @return List of response headers. This list must not be modified by the user. + * @param[in] url_con The connection object to retrieve response headers from + * @return The list of response headers \n + * This list must not be modified by the user. */ EAPI const Eina_List * ecore_con_url_response_headers_get(Ecore_Con_Url *url_con); + /** - * Setup a file for receiving response data. + * @brief Sets up a file for receiving response data. * - * @param url_con Connection object to set file - * @param fd File descriptor associated with the file. A negative value will - * unset any previously set fd. + * @details This function sets up a file to have response data written into. Note that + * ECORE_CON_EVENT_URL_DATA events are not emitted if a file has been set to + * receive the response data. * - * Sets up a file to have response data written into. Note that - * ECORE_CON_EVENT_URL_DATA events will not be emitted if a file has been set to - * receive the response data. + * @remarks This function can be used to easily setup a file where the downloaded data + * is saved. * - * This call can be used to easily setup a file where the downloaded data will - * be saved. + * @param[in] url_con The connection object to set file + * @param[in] fd The file descriptor associated with the file \n + * A negative value unsets any previously set @a fd. */ EAPI void ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd); + /** - * Retrieves the number of bytes received. + * @brief Gets the number of bytes received. * - * Retrieves the number of bytes received on the last request of the given - * connection object. + * @details This function retrieves the number of bytes received on the last request of the given + * connection object. * - * @param url_con Connection object which the request was sent on. - * - * @return Number of bytes received on request. + * @param[in] url_con The connection object which the request is sent on + * @return The number of bytes received on request * * @see ecore_con_url_get() * @see ecore_con_url_post() */ EAPI int ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con); + /** - * Sets url_con to use http auth, with given username and password, "safely" or not. + * @brief Sets @a url_con to use http auth, with the given @a username and @a password, "safely" or not. * - * @param url_con Connection object to perform a request on, previously created - * with ecore_con_url_new() or ecore_con_url_custom_new(). - * @param username Username to use in authentication - * @param password Password to use in authentication - * @param safe Whether to use "safer" methods (eg, NOT http basic auth) + * @remarks This function requires libcurl >= 7.19.1 to work. Otherwise it always returns @c 0. * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. - * - * @attention Requires libcurl >= 7.19.1 to work, otherwise will always return - * @c 0. + * @param[in] url_con The connection object to perform a request on, previously created + * with ecore_con_url_new() or ecore_con_url_custom_new(). + * @param[in] username The username to use in authentication + * @param[in] password The password to use in authentication + * @param[in] safe Set @c EINA_TRUE to use "safer" methods (eg, NOT http basic auth), \n + * otherwise set @c EINA_FALSE to not use it + * @return @c EINA_TRUE if it is set successfully, + * otherwise @c EINA_FALSE on error */ EAPI Eina_Bool ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, const char *username, const char *password, Eina_Bool safe); /** - * Sends a get request. - * - * @param url_con Connection object to perform a request on, previously created + * @brief Sends a get request. * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. + * @remarks The request is performed immediately, but you need to setup event handlers + * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or + * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result. * - * The request is performed immediately, but you need to setup event handlers - * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or - * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result. + * @param[in] url_con The connection object to perform a request on, previously created + * @return @c EINA_TRUE if the request is sent successfully, \n + * otherwise @c EINA_FALSE on error * * @see ecore_con_url_custom_new() * @see ecore_con_url_additional_headers_clear() @@ -1613,24 +1648,27 @@ EAPI Eina_Bool ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, * @see ecore_con_url_post() */ EAPI Eina_Bool ecore_con_url_get(Ecore_Con_Url *url_con); + /** - * Sends a post request. - * - * @param url_con Connection object to perform a request on, previously created - * with ecore_con_url_new() or ecore_con_url_custom_new(). - * @param data Payload (data sent on the request). Can be @c NULL. - * @param length Payload length. If @c -1, rely on automatic length - * calculation via @c strlen() on @p data. - * @param content_type Content type of the payload (e.g. text/xml). Can be @c - * NULL. + * @brief Sends a post request. * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. + * @remarks The request starts immediately, but you need to setup event handlers + * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or + * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result. * - * The request starts immediately, but you need to setup event handlers - * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or - * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result. + * @remarks This call does not block your main loop. * - * This call won't block your main loop. + * @param[in] url_con The connection object to perform a request on, previously created + * with ecore_con_url_new() or ecore_con_url_custom_new(). + * @param[in] data The payload (data sent on the request) \n + * This can be @c NULL. + * @param[in] length The payload length \n + * If this is @c -1, it relies on automatic length + * calculation via @c strlen() on @a data. + * @param[in] content_type The content type of the payload (e.g. text/xml) \n + * This can be @c NULL. + * @return @c EINA_TRUE if the request is sent successfully, + * otherwise @c EINA_FALSE on error * * @see ecore_con_url_custom_new() * @see ecore_con_url_additional_headers_clear() @@ -1644,37 +1682,39 @@ EAPI Eina_Bool ecore_con_url_get(Ecore_Con_Url *url_con); EAPI Eina_Bool ecore_con_url_post(Ecore_Con_Url *url_con, const void *data, long length, const char *content_type); + /** - * Sets whether HTTP requests should be conditional, dependent on - * modification time. + * @brief Sets whether HTTP requests should be conditional, dependent on + * modification time. * - * @param url_con Ecore_Con_Url to act upon. - * @param time_condition Condition to use for HTTP requests. - * @param timestamp Time since 1 Jan 1970 to use in the condition. + * @details This function may set the header "If-Modified-Since" or + * "If-Unmodified-Since", depending on the value of @a time_condition, with the + * value @a timestamp. * - * This function may set the header "If-Modified-Since" or - * "If-Unmodified-Since", depending on the value of @p time_condition, with the - * value @p timestamp. + * @param[in] url_con The Ecore_Con_Url to act upon + * @param[in] time_condition The condition to use for HTTP requests + * @param[in] timestamp The time since 1 Jan 1970 to use in the condition * - * @sa ecore_con_url_get() - * @sa ecore_con_url_post() + * @see ecore_con_url_get() + * @see ecore_con_url_post() */ EAPI void ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time time_condition, double timestamp); /** - * @brief Uploads a file to an ftp site. + * @brief Uploads a file to an FTP site. * - * @param url_con The Ecore_Con_Url object to send with - * @param filename The path to the file to send - * @param user The username to log in with - * @param pass The password to log in with - * @param upload_dir The directory to which the file should be uploaded - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * @remarks Upload @a filename to an FTP server set in @a url_con using @a user + * and @a pass to directory @a upload_dir * - * Upload @p filename to an ftp server set in @p url_con using @p user - * and @p pass to directory @p upload_dir + * @param[in] url_con The Ecore_Con_Url object to send with + * @param[in] filename The path to the file to send + * @param[in] user The username to log in with + * @param[in] pass The password to log in with + * @param[in] upload_dir The directory to which the file should be uploaded + * @return @c EINA_TRUE if the file is uploaded successfully, \n + * otherwise @c EINA_FALSE on error */ EAPI Eina_Bool ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, const char *filename, @@ -1682,173 +1722,178 @@ EAPI Eina_Bool ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, const char *pass, const char *upload_dir); /** - * Toggle libcurl's verbose output. + * @brief Toggles libcurl's verbose output. * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * @param verbose Whether or not to enable libcurl's verbose output. + * @remarks If @a verbose is @c EINA_TRUE, libcurl outputs a lot of verbose + * information about its operations, which is useful for + * debugging. The verbose information is sent to stderr. * - * If @p verbose is @c EINA_TRUE, libcurl will output a lot of verbose - * information about its operations, which is useful for - * debugging. The verbose information will be sent to stderr. + * @param[in] url_con The Ecore_Con_Url instance which is acted upon + * @param[in] verbose Set @c EINA_TRUE to enable libcurl's verbose output, \n + * otherwise @c EINA_FALSE to disable verbose output */ EAPI void ecore_con_url_verbose_set(Ecore_Con_Url *url_con, Eina_Bool verbose); + /** - * Enable or disable EPSV extension - * @param url_con The Ecore_Con_Url instance which will be acted upon. - * @param use_epsv Boolean to enable/disable the EPSV extension. + * @brief Enables or disables EPSV extension. + * + * @param[in] url_con The Ecore_Con_Url instance which is acted upon + * @param[in] use_epsv Set @c EINA_TRUE to enable the EPSV extension, \n + * otherwise @c EINA_FALSE to disable it */ EAPI void ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, Eina_Bool use_epsv); /** - * Enables the cookie engine for subsequent HTTP requests. + * @brief Enables the cookie engine for subsequent HTTP requests. * - * @param url_con Ecore_Con_Url instance which will be acted upon. + * @remarks After this function is called, cookies set by the server in HTTP responses + * are parsed and stored, as well as sent back to the server in new HTTP requests. * - * After this function is called, cookies set by the server in HTTP responses - * will be parsed and stored, as well as sent back to the server in new HTTP - * requests. + * @remarks Even though this function is called @c ecore_con_url_cookies_init(), + * there is no symmetrical shutdown operation. * - * @note Even though this function is called @c ecore_con_url_cookies_init(), - * there is no symmetrical shutdown operation. + * @param[in] url_con The Ecore_Con_Url instance which is acted upon */ EAPI void ecore_con_url_cookies_init(Ecore_Con_Url *url_con); + /** - * Controls whether session cookies from previous sessions shall be loaded. + * @brief Sets whether session cookies from previous sessions shall be loaded. * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * @param ignore If @c EINA_TRUE, ignore session cookies when loading cookies - * from files. If @c EINA_FALSE, all cookies will be loaded. + * @remarks Session cookies are cookies with no expire date set, which usually means + * they are removed after the current session is closed. * - * Session cookies are cookies with no expire date set, which usually means - * they are removed after the current session is closed. + * @remarks By default, when Ecore_Con_Url loads cookies from a file, all cookies are + * loaded, including session cookies, which, most of the time, were supposed + * to be loaded and valid only for that session. * - * By default, when Ecore_Con_Url loads cookies from a file, all cookies are - * loaded, including session cookies, which, most of the time, were supposed - * to be loaded and valid only for that session. + * @remarks If @a ignore is set to @c EINA_TRUE, when Ecore_Con_Url loads cookies from + * the files passed to @c ecore_con_url_cookies_file_add(), session cookies + * are not loaded. * - * If @p ignore is set to @c EINA_TRUE, when Ecore_Con_Url loads cookies from - * the files passed to @c ecore_con_url_cookies_file_add(), session cookies - * will not be loaded. + * @param[in] url_con The Ecore_Con_Url instance which is acted upon + * @param[in] ignore Set @c EINA_TRUE to ignore session cookies when loading cookies from files, \n + * otherwise set @c EINA_FALSE to load all cookies * * @see ecore_con_url_cookies_file_add() */ EAPI void ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con, Eina_Bool ignore); + /** - * Clears currently loaded cookies. - * @param url_con Ecore_Con_Url instance which will be acted upon. + * @brief Clears currently loaded cookies. + * + * @remarks The cleared cookies are removed and not sent in subsequent HTTP + * requests, nor are they written to the cookiejar file set using + * @c ecore_con_url_cookies_jar_file_set(). * - * The cleared cookies are removed and will not be sent in subsequent HTTP - * requests, nor will they be written to the cookiejar file set via - * @c ecore_con_url_cookies_jar_file_set(). + * @remarks This function initializes the cookie engine if it has not been + * initialized yet. + * @remarks The cookie files set by ecore_con_url_cookies_file_add() are not loaded + * immediately, just when the request is started. Thus, if you ask to + * clear the cookies, but has a file already set by that function, the + * cookies are then loaded and you have old cookies set. In order + * to not have any old cookie set, you need to not call + * ecore_con_url_cookies_file_add() ever on the @a url_con handler, and + * call this function to clear any cookie set by a previous request on + * this handler. * - * @note This function will initialize the cookie engine if it has not been - * initialized yet. - * @note The cookie files set by ecore_con_url_cookies_file_add() aren't loaded - * immediately, just when the request is started. Thus, if you ask to - * clear the cookies, but has a file already set by that function, the - * cookies will then be loaded and you will have old cookies set. In order - * to don't have any old cookie set, you need to don't call - * ecore_con_url_cookies_file_add() ever on the @p url_con handler, and - * call this function to clear any cookie set by a previous request on - * this handler. + * @param[in] url_con The Ecore_Con_Url instance which are acted upon * * @see ecore_con_url_cookies_session_clear() * @see ecore_con_url_cookies_ignore_old_session_set() */ EAPI void ecore_con_url_cookies_clear(Ecore_Con_Url *url_con); + /** - * Clears currently loaded session cookies. + * @brief Clears currently loaded session cookies. * - * @param url_con Ecore_Con_Url instance which will be acted upon. + * @remarks Session cookies are cookies with no expire date set, which usually means + * they are removed after the current session is closed. * - * Session cookies are cookies with no expire date set, which usually means - * they are removed after the current session is closed. + * @remarks The cleared cookies are removed and not sent in subsequent HTTP + * requests, nor are they be written to the cookiejar file set using + * @c ecore_con_url_cookies_jar_file_set(). * - * The cleared cookies are removed and will not be sent in subsequent HTTP - * requests, nor will they be written to the cookiejar file set via - * @c ecore_con_url_cookies_jar_file_set(). + * @remarks This function initializes the cookie engine if it has not been + * initialized yet. + * @remarks The cookie files set by ecore_con_url_cookies_file_add() are not loaded + * immediately, just when the request is started. Thus, if you ask to + * clear the session cookies, but has a file already set by that function, + * the session cookies are then loaded and you have old cookies + * set. In order to not have any old session cookie set, you need to + * not call ecore_con_url_cookies_file_add() ever on the @a url_con + * handler, and call this function to clear any session cookie set by a + * previous request on this handler. An easier way to not use old + * session cookies is by using the function + * ecore_con_url_cookies_ignore_old_session_set(). * - * @note This function will initialize the cookie engine if it has not been - * initialized yet. - * @note The cookie files set by ecore_con_url_cookies_file_add() aren't loaded - * immediately, just when the request is started. Thus, if you ask to - * clear the session cookies, but has a file already set by that function, - * the session cookies will then be loaded and you will have old cookies - * set. In order to don't have any old session cookie set, you need to - * don't call ecore_con_url_cookies_file_add() ever on the @p url_con - * handler, and call this function to clear any session cookie set by a - * previous request on this handler. An easier way to don't use old - * session cookies is by using the function - * ecore_con_url_cookies_ignore_old_session_set(). + * @param[in] url_con The Ecore_Con_Url instance which are acted upon * * @see ecore_con_url_cookies_clear() * @see ecore_con_url_cookies_ignore_old_session_set() */ EAPI void ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con); + /** - * Adds a file to the list of files from which to load cookies. + * @brief Adds a file to the list of files from which to load cookies. * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * @param file_name Name of the file that will be added to the list. + * @remarks The files must contain cookies defined according to two possible formats: + * @li HTTP-style header ("Set-Cookie: ..."). + * @li Netscape/Mozilla cookie data format. * - * Files must contain cookies defined according to two possible formats: + * @remarks Cookies are only @b read from this file. If you want to save cookies to a + * file, use ecore_con_url_cookies_jar_file_set(). Also notice that this + * function supports the both types of cookie file cited above, while + * ecore_con_url_cookies_jar_file_set() saves only in the Netscape/Mozilla's format. * - * @li HTTP-style header ("Set-Cookie: ..."). - * @li Netscape/Mozilla cookie data format. + * @remarks Please notice that the file is not read immediately, but rather added + * to a list of files that is loaded and parsed at a later time. * - * Cookies will only be @b read from this file. If you want to save cookies to a - * file, use ecore_con_url_cookies_jar_file_set(). Also notice that this - * function supports the both types of cookie file cited above, while - * ecore_con_url_cookies_jar_file_set() will save only in the Netscape/Mozilla's - * format. + * @remarks This function initializes the cookie engine if it has not been + * initialized yet. * - * Please notice that the file will not be read immediately, but rather added - * to a list of files that will be loaded and parsed at a later time. - * - * @note This function will initialize the cookie engine if it has not been - * initialized yet. + * @param[in] url_con The Ecore_Con_Url instance which is acted upon + * @param[in] file_name The name of the file that is added to the list * * @see ecore_con_url_cookies_ignore_old_session_set() * @see ecore_con_url_cookies_jar_file_set() */ EAPI void ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con, const char * const file_name); + /** - * Sets the name of the file to which all current cookies will be written when - * either cookies are flushed or Ecore_Con is shut down. + * @brief Sets the name of the file to which all current cookies are written when + * either cookies are flushed or Ecore_Con is shut down. * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * @param cookiejar_file File to which the cookies will be written. + * @remarks Cookies are written following Netscape/Mozilla's data format, also known as + * cookie-jar. * - * @return @c EINA_TRUE is the file name has been set successfully, - * @c EINA_FALSE otherwise. + * @remarks Cookies are only @b saved to this file. If you need to read cookies from + * a file, use ecore_con_url_cookies_file_add() instead. * - * Cookies are written following Netscape/Mozilla's data format, also known as - * cookie-jar. + * @remarks This function initializes the cookie engine if it has not been initialized yet. * - * Cookies will only be @b saved to this file. If you need to read cookies from - * a file, use ecore_con_url_cookies_file_add() instead. - * - * @note This function will initialize the cookie engine if it has not been - * initialized yet. + * @param[in] url_con The Ecore_Con_Url instance which are acted upon + * @param[in] cookiejar_file The file to which the cookies are written + * @return @c EINA_TRUE is the file name has been set successfully, \n + * otherwise @c EINA_FALSE on failure * * @see ecore_con_url_cookies_jar_write() */ EAPI Eina_Bool ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con, const char * const cookiejar_file); + /** - * Writes all current cookies to the cookie jar immediately. + * @brief Writes all current cookies to the cookie jar immediately. * - * @param url_con Ecore_Con_Url instance which will be acted upon. + * @remarks A cookie-jar file must have been previously set by + * ecore_con_url_jar_file_set(), otherwise nothing is done. * - * A cookie-jar file must have been previously set by - * @c ecore_con_url_jar_file_set, otherwise nothing will be done. + * @remarks This function initializes the cookie engine if it has not been initialized yet. * - * @note This function will initialize the cookie engine if it has not been - * initialized yet. + * @param[in] url_con The Ecore_Con_Url instance which is acted upon * * @see ecore_con_url_cookies_jar_file_set() */ @@ -1860,81 +1905,86 @@ EAPI int ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path); /** - * Set HTTP proxy to use. + * @brief Sets the HTTP proxy to use. + * @since 1.2 * - * The parameter should be a char * to a zero terminated string holding - * the host name or dotted IP address. To specify port number in this string, - * append :[port] to the end of the host name. - * The proxy string may be prefixed with [protocol]:// since any such prefix - * will be ignored. - * The proxy's port number may optionally be specified with the separate option. - * If not specified, libcurl will default to using port 1080 for proxies. + * @remarks The parameter should be a char * to a zero terminated string holding + * the host name or dotted IP address. To specify port number in this string, + * append :[port] to the end of the host name. + * The proxy string may be prefixed with [protocol]:// since any such prefix + * is ignored. + * The proxy's port number may optionally be specified with the separate option. + * If not specified, libcurl defaults to using port 1080 for proxies. * - * @param url_con Connection object that will use the proxy. - * @param proxy Porxy string or @c NULL to disable - * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. - * @since 1.2 + * @param[in] url_con The connection object that uses the proxy + * @param[in] proxy The proxy string, \n + * otherwise set @c NULL to disable + * @return @c EINA_TRUE if the proxy is set successfully, + * otherwise @c EINA_FALSE on error */ EAPI Eina_Bool ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy); /** - * Set zero terminated username to use for proxy. + * @brief Sets zero terminated username to use for proxy. + * @since 1.2 * - * if socks protocol is used for proxy, protocol should be socks5 and above. + * @remarks If socks protocol is used for proxy, protocol should be socks5 and above. * - * @param url_con Connection object that will use the proxy. - * @param username Username string. + * @param[in] url_con The connection object that uses the proxy + * @param[in] username The username string * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. + * @return @c EINA_TRUE if the username is set successfully, \n + * otherwise @c EINA_FALSE on error * * @see ecore_con_url_proxy_set() * - * @since 1.2 */ EAPI Eina_Bool ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username); /** - * Set zero terminated password to use for proxy. + * @brief Sets zero terminated password to use for proxy. + * @since 1.2 * - * if socks protocol is used for proxy, protocol should be socks5 and above. + * @remarks If socks protocol is used for proxy, protocol should be socks5 and above. * - * @param url_con Connection object that will use the proxy. - * @param password Password string. + * @param[in] url_con The connection object that uses the proxy + * @param[in] password The password string * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. + * @return @c EINA_TRUE if the password is set successfully, \n + * otherwise @c EINA_FALSE on error * * @see ecore_con_url_proxy_set() * - * @since 1.2 */ EAPI Eina_Bool ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password); /** - * Set timeout in seconds. + * @brief Sets timeout in seconds. * - * the maximum time in seconds that you allow the ecore con url transfer - * operation to take. Normally, name lookups can take a considerable time - * and limiting operations to less than a few minutes risk aborting perfectly - * normal operations. + * @since 1.2 * - * @param url_con Connection object that will use the timeout. - * @param timeout time in seconds. + * @remarks The maximum time in seconds that you allow the ecore_con_url_transfer + * operation to take. Normally, name lookups can take a considerable time + * and limiting operations to less than a few minutes risk aborting perfectly + * normal operations. * - * @see ecore_con_url_cookies_jar_file_set() + * @param[in] url_con The connection object that uses the timeout + * @param[in] timeout The time in seconds * - * @since 1.2 + * @see ecore_con_url_cookies_jar_file_set() */ EAPI void ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout); /** - * Get the returned HTTP STATUS code + * @brief Gets the returned HTTP STATUS code. + * @since 1.2 * - * This is used to, at any time, try to return the status code for a transmission. - * @param url_con Connection object - * @return A valid HTTP STATUS code, or 0 on failure + * @remarks This is used to try to return the status code for a transmission. + * + * @param[in] url_con The connection object + * @return A valid HTTP STATUS code, \n + * otherwise @c 0 on failure * - * @since 1.2 */ EAPI int ecore_con_url_status_code_get(Ecore_Con_Url *url_con); /** diff --git a/src/lib/ecore_con/Ecore_Con_Eet.h b/src/lib/ecore_con/Ecore_Con_Eet.h new file mode 100644 index 0000000..bdf0d2d --- /dev/null +++ b/src/lib/ecore_con/Ecore_Con_Eet.h @@ -0,0 +1,73 @@ +#ifndef _ECORE_CON_EET +# define _ECORE_CON_EET + +#include +#include +#include + +#ifdef EAPI +# undef EAPI +#endif + +#ifdef _WIN32 +# ifdef EFL_ECORE_CON_BUILD +# ifdef DLL_EXPORT +# define EAPI __declspec(dllexport) +# else +# define EAPI +# endif +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef __GNUC__ +# if __GNUC__ >= 4 +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +# else +# define EAPI +# endif +#endif + +typedef struct _Ecore_Con_Eet Ecore_Con_Eet; +typedef struct _Ecore_Con_Reply Ecore_Con_Reply; + +typedef void (*Ecore_Con_Eet_Data_Cb)(void *data, Ecore_Con_Reply *reply, const char *protocol_name, void *value); +typedef void (*Ecore_Con_Eet_Raw_Data_Cb)(void *data, Ecore_Con_Reply *reply, const char *protocol_name, const char *section, void *value, size_t length); +typedef Eina_Bool (*Ecore_Con_Eet_Client_Cb)(void *data, Ecore_Con_Reply *reply, Ecore_Con_Client *conn); +typedef Eina_Bool (*Ecore_Con_Eet_Server_Cb)(void *data, Ecore_Con_Reply *reply, Ecore_Con_Server *conn); + +EAPI Ecore_Con_Eet *ecore_con_eet_server_new(Ecore_Con_Server *server); +EAPI Ecore_Con_Eet *ecore_con_eet_client_new(Ecore_Con_Server *server); +EAPI void ecore_con_eet_server_free(Ecore_Con_Eet *ece); + +EAPI void ecore_con_eet_register(Ecore_Con_Eet *ece, const char *name, Eet_Data_Descriptor *edd); + +EAPI void ecore_con_eet_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Data_Cb func, const void *data); +EAPI void ecore_con_eet_data_callback_del(Ecore_Con_Eet *ece, const char *name); + +EAPI void ecore_con_eet_raw_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Raw_Data_Cb func, const void *data); +EAPI void ecore_con_eet_raw_data_callback_del(Ecore_Con_Eet *ece, const char *name); + +EAPI void ecore_con_eet_client_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); +EAPI void ecore_con_eet_client_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); + +EAPI void ecore_con_eet_client_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); +EAPI void ecore_con_eet_client_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); + +EAPI void ecore_con_eet_server_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); +EAPI void ecore_con_eet_server_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); + +EAPI void ecore_con_eet_server_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); +EAPI void ecore_con_eet_server_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); + +EAPI void ecore_con_eet_data_set(Ecore_Con_Eet *ece, const void *data); +EAPI void *ecore_con_eet_data_get(Ecore_Con_Eet *ece); + +EAPI Ecore_Con_Eet *ecore_con_eet_reply(Ecore_Con_Reply *reply); +EAPI void ecore_con_eet_send(Ecore_Con_Reply *reply, const char *protocol_name, void *value); +EAPI void ecore_con_eet_raw_send(Ecore_Con_Reply *reply, const char *protocol_name, const char *section, void *value, unsigned int length); + +#endif diff --git a/src/lib/ecore_con/Makefile.am b/src/lib/ecore_con/Makefile.am index 0e8e071..ce656f7 100644 --- a/src/lib/ecore_con/Makefile.am +++ b/src/lib/ecore_con/Makefile.am @@ -12,6 +12,7 @@ AM_CPPFLAGS = \ @EINA_CFLAGS@ \ @TLS_CFLAGS@ \ @CARES_CFLAGS@ \ +@EET_CFLAGS@ \ @WIN32_CPPFLAGS@ lib_LTLIBRARIES = libecore_con.la @@ -44,9 +45,14 @@ libecore_con_la_SOURCES += ecore_con_info.c endif endif +if ECORE_HAVE_EET +libecore_con_la_SOURCES += ecore_con_eet.c +includes_HEADERS += Ecore_Con_Eet.h +endif + libecore_con_la_LIBADD = \ $(top_builddir)/src/lib/ecore/libecore.la \ -@SSL_LIBS@ @CURL_LIBS@ @EINA_LIBS@ @EVIL_LIBS@ @TLS_LIBS@ @CARES_LIBS@ @WIN32_LIBS@ +@SSL_LIBS@ @CURL_LIBS@ @EINA_LIBS@ @EVIL_LIBS@ @TLS_LIBS@ @CARES_LIBS@ @WIN32_LIBS@ @EET_LIBS@ libecore_con_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ diff --git a/src/lib/ecore_con/dns.c b/src/lib/ecore_con/dns.c index b92a315..1257b03 100644 --- a/src/lib/ecore_con/dns.c +++ b/src/lib/ecore_con/dns.c @@ -27,6 +27,32 @@ # include "config.h" #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #if !defined(__FreeBSD__) #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 @@ -2117,13 +2143,12 @@ size_t dns_rr_print(void *dst, size_t lim, struct dns_rr *rr, struct dns_packet if (cp < lim) { rd = &((unsigned char *)dst)[cp]; rdlen = lim - cp; + cp += dns_any_print(rd, rdlen, &any, rr->type); } else { rd = 0; rdlen = 0; } - cp += dns_any_print(rd, rdlen, &any, rr->type); - epilog: dns__printnul(dst, lim, cp); @@ -4774,8 +4799,9 @@ void dns_so_close(struct dns_socket *so) { void dns_so_reset(struct dns_socket *so) { - free(so->answer); + if (so->answer) free(so->answer); + so->answer = NULL; memset(&so->state, '\0', sizeof *so - offsetof(struct dns_socket, state)); } /* dns_so_reset() */ @@ -5285,7 +5311,7 @@ struct dns_resolver *dns_res_open(struct dns_resolv_conf *resconf, struct dns_ho * dns_resconf_local() by default would create undesirable surpises. */ if (!resconf || !hosts || !hints) - goto error; + goto _error; if (!(R = malloc(sizeof *R))) goto syerr; @@ -5306,7 +5332,7 @@ syerr: error = dns_syerr(); error: *error_ = error; - +_error: dns_res_close(R); dns_resconf_close(resconf); diff --git a/src/lib/ecore_con/ecore_con.c b/src/lib/ecore_con/ecore_con.c index b4e01cb..d7768d9 100644 --- a/src/lib/ecore_con/ecore_con.c +++ b/src/lib/ecore_con/ecore_con.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include #include @@ -318,11 +344,6 @@ on_error: * @{ */ -/** - * @example ecore_con_server_example.c - * Shows how to write a simple server using the Ecore_Con library. - */ - EAPI Ecore_Con_Server * ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, @@ -484,7 +505,14 @@ ecore_con_server_connect(Ecore_Con_Type compl_type, #ifdef _WIN32 EINA_SAFETY_ON_FALSE_GOTO(ecore_con_local_connect(svr, _ecore_con_cl_handler), error); #else - EINA_SAFETY_ON_FALSE_GOTO(ecore_con_local_connect(svr, _ecore_con_cl_handler, svr), error); + //EINA_SAFETY_ON_FALSE_GOTO(ecore_con_local_connect(svr, _ecore_con_cl_handler, svr), error); + { + if (ecore_con_local_connect(svr, _ecore_con_cl_handler, svr) == 0) + { + WRN("ecore_con_local_connect(svr, _ecore_con_cl_handler, svr) is false"); + goto error; + } + } #endif if ((type == ECORE_CON_REMOTE_TCP) || @@ -552,6 +580,7 @@ ecore_con_server_timeout_get(Ecore_Con_Server *svr) EAPI void * ecore_con_server_del(Ecore_Con_Server *svr) { + if (!svr) return NULL; if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) { ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del"); @@ -677,7 +706,7 @@ ecore_con_server_send(Ecore_Con_Server *svr, int state = 1; if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) /* realistically this isn't anything serious so we can just log and continue */ - ERR("corking failed! %s", strerror(errno)); + WRN("corking failed! %s", strerror(errno)); } #endif } @@ -750,11 +779,6 @@ ecore_con_server_flush(Ecore_Con_Server *svr) * @{ */ -/** - * @example ecore_con_client_example.c - * Shows how to write a simple client that connects to the example server. - */ - EAPI int ecore_con_client_send(Ecore_Con_Client *cl, const void *data, @@ -783,12 +807,12 @@ ecore_con_client_send(Ecore_Con_Client *cl, cl->buf = eina_binbuf_new(); EINA_SAFETY_ON_NULL_RETURN_VAL(cl->buf, 0); #ifdef TCP_CORK - if ((cl->fd >= 0) && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)) + if ((cl->fd >= 0) && (cl->host_server && (cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)) { int state = 1; if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) /* realistically this isn't anything serious so we can just log and continue */ - ERR("corking failed! %s", strerror(errno)); + WRN("corking failed! %s", strerror(errno)); } #endif } @@ -854,6 +878,7 @@ ecore_con_client_timeout_get(Ecore_Con_Client *cl) EAPI void * ecore_con_client_del(Ecore_Con_Client *cl) { + if (!cl) return NULL; if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) { ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del"); @@ -953,6 +978,7 @@ ecore_con_server_fd_get(Ecore_Con_Server *svr) return -1; } if (svr->created) return -1; + if (svr->delete_me) return -1; return ecore_main_fd_handler_fd_get(svr->fd_handler); } @@ -1068,7 +1094,7 @@ ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, e->data = malloc(num); if (!e->data) { - ERR("server data allocation failure !"); + WRN("server data allocation failure !"); _ecore_con_event_server_data_free(NULL, e); return; } @@ -1155,7 +1181,7 @@ ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, E e->data = malloc(num); if (!e->data) { - ERR("client data allocation failure !"); + WRN("client data allocation failure !"); _ecore_con_event_client_data_free(cl->host_server, e); return; } @@ -1186,7 +1212,7 @@ _ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool dupl e->server = svr; e->error = duplicate ? strdup(error) : error; - ERR("%s", error); + WRN("%s", error); svr->event_count = eina_list_append(svr->event_count, e); ecore_event_add(ECORE_CON_EVENT_SERVER_ERROR, e, (Ecore_End_Cb)_ecore_con_event_server_error_free, NULL); _ecore_con_event_count++; @@ -1202,7 +1228,8 @@ ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error) e->client = cl; e->error = strdup(error); - ERR("%s", error); +// givving errors like this is not a good thing - MAYBET his belongs in debug... but not err. +// ERR("%s", error); cl->event_count = eina_list_append(cl->event_count, e); cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); ecore_event_add(ECORE_CON_EVENT_CLIENT_ERROR, e, (Ecore_End_Cb)_ecore_con_event_client_error_free, cl->host_server); @@ -1745,7 +1772,7 @@ svr_try_connect_plain(Ecore_Con_Server *svr) { /* we lost our server! */ ecore_con_event_server_error(svr, strerror(so_err)); - ERR("Connection lost: %s", strerror(so_err)); + WRN("Connection lost: %s", strerror(so_err)); _ecore_con_server_kill(svr); return ECORE_CON_DISCONNECTED; } @@ -1882,6 +1909,15 @@ _ecore_con_svr_tcp_handler(void *data, error: if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler); if (cl->fd >= 0) close(cl->fd); + { + Ecore_Event *ev; + + EINA_LIST_FREE(cl->event_count, ev) + { + svr->event_count = eina_list_remove(svr->event_count, ev); + ecore_event_del(ev); + } + } free(cl); if (clerr || errno) ecore_con_event_server_error(svr, clerr ?: strerror(errno)); return ECORE_CALLBACK_RENEW; @@ -1969,7 +2005,7 @@ _ecore_con_cl_handler(void *data, #endif if (ecore_con_ssl_server_init(svr)) { - ERR("ssl handshaking failed!"); + WRN("ssl handshaking failed!"); svr->handshaking = EINA_FALSE; } else if (!svr->ssl_state) @@ -2011,7 +2047,7 @@ _ecore_con_cl_udp_handler(void *data, want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); svr = data; - if (svr->delete_me || svr->delete_me || ((!want_read) && (!want_write))) + if (svr->delete_me || ((!want_read) && (!want_write))) return ECORE_CALLBACK_RENEW; if (want_write) @@ -2052,7 +2088,6 @@ _ecore_con_svr_udp_handler(void *data, if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) { - _ecore_con_client_flush(cl); return ECORE_CALLBACK_RENEW; } @@ -2126,7 +2161,7 @@ _ecore_con_svr_cl_read(Ecore_Con_Client *cl) _ecore_con_cl_timer_update(cl); } - if (!(cl->host_server->type & ECORE_CON_SSL) || (!cl->upgrade)) + if (!(cl->host_server->type & ECORE_CON_SSL) && (!cl->upgrade)) { num = read(cl->fd, buf, sizeof(buf)); /* 0 is not a valid return value for a tcp socket */ @@ -2163,7 +2198,7 @@ _ecore_con_svr_cl_handler(void *data, { if (ecore_con_ssl_client_init(cl)) { - ERR("ssl handshaking failed!"); + WRN("ssl handshaking failed!"); _ecore_con_client_kill(cl); return ECORE_CALLBACK_RENEW; } @@ -2184,7 +2219,7 @@ _ecore_con_server_flush(Ecore_Con_Server *svr) { int count, num; size_t buf_len, buf_offset; - const void *buf; + const unsigned char *buf; DBG("(svr=%p,buf=%p)", svr, svr->buf); #ifdef _WIN32 @@ -2262,7 +2297,7 @@ _ecore_con_server_flush(Ecore_Con_Server *svr) int state = 0; if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) /* realistically this isn't anything serious so we can just log and continue */ - ERR("uncorking failed! %s", strerror(errno)); + WRN("uncorking failed! %s", strerror(errno)); } #endif } @@ -2302,7 +2337,7 @@ _ecore_con_client_flush(Ecore_Con_Client *cl) if (!cl->buf) return; num = eina_binbuf_length_get(cl->buf) - cl->buf_offset; if (num <= 0) return; - if (!(cl->host_server->type & ECORE_CON_SSL) || (!cl->upgrade)) + if (!(cl->host_server->type & ECORE_CON_SSL) && (!cl->upgrade)) count = write(cl->fd, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num); else count = ecore_con_ssl_client_write(cl, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num); @@ -2332,7 +2367,7 @@ _ecore_con_client_flush(Ecore_Con_Client *cl) int state = 0; if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) /* realistically this isn't anything serious so we can just log and continue */ - ERR("uncorking failed! %s", strerror(errno)); + WRN("uncorking failed! %s", strerror(errno)); } #endif if (cl->fd_handler) @@ -2351,15 +2386,23 @@ _ecore_con_event_client_add_free(Ecore_Con_Server *svr, e = ev; if (e->client) { + Eina_Bool svrfreed = EINA_FALSE; + e->client->event_count = eina_list_remove(e->client->event_count, e); if (e->client->host_server) { e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); if ((!svr->event_count) && (svr->delete_me)) - _ecore_con_server_free(svr); + { + _ecore_con_server_free(svr); + svrfreed = EINA_TRUE; + } + } + if (!svrfreed) + { + if ((!e->client->event_count) && (e->client->delete_me)) + ecore_con_client_del(e->client); } - if ((!e->client->event_count) && (e->client->delete_me)) - ecore_con_client_del(e->client); } ecore_con_event_client_add_free(e); @@ -2377,15 +2420,23 @@ _ecore_con_event_client_del_free(Ecore_Con_Server *svr, e = ev; if (e->client) { + Eina_Bool svrfreed = EINA_FALSE; + e->client->event_count = eina_list_remove(e->client->event_count, e); if (e->client->host_server) { e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); if ((!svr->event_count) && (svr->delete_me)) - _ecore_con_server_free(svr); + { + _ecore_con_server_free(svr); + svrfreed = EINA_TRUE; + } + } + if (!svrfreed) + { + if (!e->client->event_count) + _ecore_con_client_free(e->client); } - if (!e->client->event_count) - _ecore_con_client_free(e->client); } ecore_con_event_client_del_free(e); _ecore_con_event_count--; @@ -2399,18 +2450,26 @@ _ecore_con_event_client_write_free(Ecore_Con_Server *svr, { if (e->client) { + Eina_Bool svrfreed = EINA_FALSE; + e->client->event_count = eina_list_remove(e->client->event_count, e); if (e->client->host_server) { e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); if ((!svr->event_count) && (svr->delete_me)) - _ecore_con_server_free(svr); + { + _ecore_con_server_free(svr); + svrfreed = EINA_TRUE; + } + } + if (!svrfreed) + { + if (((!e->client->event_count) && (e->client->delete_me)) || + ((e->client->host_server && + ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || + (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) + ecore_con_client_del(e->client); } - if (((!e->client->event_count) && (e->client->delete_me)) || - ((e->client->host_server && - ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || - (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) - ecore_con_client_del(e->client); } ecore_con_event_client_write_free(e); _ecore_con_event_count--; @@ -2427,18 +2486,26 @@ _ecore_con_event_client_data_free(Ecore_Con_Server *svr, e = ev; if (e->client) { + Eina_Bool svrfreed = EINA_FALSE; + e->client->event_count = eina_list_remove(e->client->event_count, e); if (e->client->host_server) { e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); } if ((!svr->event_count) && (svr->delete_me)) - _ecore_con_server_free(svr); - if (((!e->client->event_count) && (e->client->delete_me)) || - ((e->client->host_server && - ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || - (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) - ecore_con_client_del(e->client); + { + _ecore_con_server_free(svr); + svrfreed = EINA_TRUE; + } + if (!svrfreed) + { + if (((!e->client->event_count) && (e->client->delete_me)) || + ((e->client->host_server && + ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || + (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) + ecore_con_client_del(e->client); + } } free(e->data); ecore_con_event_client_data_free(e); @@ -2545,12 +2612,20 @@ _ecore_con_event_client_error_free(Ecore_Con_Server *svr, Ecore_Con_Event_Client { if (e->client) { - e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); - if ((!e->client->event_count) && (e->client->delete_me)) - _ecore_con_client_free(e->client); - if (e->client->host_server) + Eina_Bool svrfreed = EINA_FALSE; + + if (eina_list_data_find(svr->clients, e->client)) + { + e->client->event_count = eina_list_remove(e->client->event_count, e); + if ((!e->client->event_count) && (e->client->delete_me)) + { + _ecore_con_client_free(e->client); + svrfreed = EINA_TRUE; + } + } + svr->event_count = eina_list_remove(svr->event_count, e); + if (!svrfreed) { - e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); if ((!svr->event_count) && (svr->delete_me)) _ecore_con_server_free(svr); } diff --git a/src/lib/ecore_con/ecore_con_alloc.c b/src/lib/ecore_con/ecore_con_alloc.c index 68f24cc..5fb248f 100644 --- a/src/lib/ecore_con/ecore_con_alloc.c +++ b/src/lib/ecore_con/ecore_con_alloc.c @@ -2,6 +2,32 @@ # include "config.h" #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "Ecore.h" #include "ecore_private.h" #include "Ecore_Con.h" @@ -72,7 +98,7 @@ ecore_con_mempool_init(void) mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 16); if (!mempool_array[i]->mp) { - if (strcmp(choice, "pass_through") != 0) + if (!(!strcmp(choice, "pass_through"))) { ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice); choice = "pass_through"; diff --git a/src/lib/ecore_con/ecore_con_dns.c b/src/lib/ecore_con/ecore_con_dns.c index 3671576..9bc396a 100644 --- a/src/lib/ecore_con/ecore_con_dns.c +++ b/src/lib/ecore_con/ecore_con_dns.c @@ -140,8 +140,8 @@ static Eina_Bool _dns_timer_cb(Ecore_Con_DNS *dns) { dns->done_cb(dns->data, NULL); - _ecore_con_dns_free(dns); dns->timer = NULL; + _ecore_con_dns_free(dns); return EINA_FALSE; } diff --git a/src/lib/ecore_con/ecore_con_eet.c b/src/lib/ecore_con/ecore_con_eet.c new file mode 100644 index 0000000..ece348e --- /dev/null +++ b/src/lib/ecore_con/ecore_con_eet.c @@ -0,0 +1,796 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "Ecore_Con_Eet.h" + +#define ECORE_CON_EET_RAW_MAGIC 0xDEAD007 + +typedef struct _Ecore_Con_Eet_Data Ecore_Con_Eet_Data; +typedef struct _Ecore_Con_Eet_Raw_Data Ecore_Con_Eet_Raw_Data; +typedef struct _Ecore_Con_Eet_Client Ecore_Con_Eet_Client; +typedef struct _Ecore_Con_Eet_Server Ecore_Con_Eet_Server; + +struct _Ecore_Con_Reply +{ + Ecore_Con_Eet *ece; + Ecore_Con_Client *client; + + Eet_Connection *econn; + + char *buffer_section; + unsigned char *buffer; + unsigned int buffer_length; + unsigned int buffer_current; + Ecore_Con_Eet_Raw_Data *buffer_handler; +}; + +struct _Ecore_Con_Eet_Data +{ + Ecore_Con_Eet_Data_Cb func; + const char *name; + const void *data; +}; + +struct _Ecore_Con_Eet_Raw_Data +{ + Ecore_Con_Eet_Raw_Data_Cb func; + const char *name; + const void *data; +}; + +struct _Ecore_Con_Eet_Client +{ + Ecore_Con_Eet_Client_Cb func; + const void *data; +}; + +struct _Ecore_Con_Eet_Server +{ + Ecore_Con_Eet_Server_Cb func; + const void *data; +}; + +struct _Ecore_Con_Eet +{ + Ecore_Con_Server *server; + + Ecore_Event_Handler *handler_add; + Ecore_Event_Handler *handler_del; + Ecore_Event_Handler *handler_data; + + Eet_Data_Descriptor *edd; + Eet_Data_Descriptor *matching; + + Eina_Hash *data_callbacks; + Eina_Hash *raw_data_callbacks; + + union { + struct { + Eina_List *connections; + Eina_List *client_connect_callbacks; + Eina_List *client_disconnect_callbacks; + } server; + struct { + Ecore_Con_Reply *r; + Eina_List *server_connect_callbacks; + Eina_List *server_disconnect_callbacks; + } client; + } u; + + const void *data; + + Eina_Bool client : 1; +}; + +static void +_ecore_con_eet_data_free(void *data) +{ + Ecore_Con_Eet_Data *eced = data; + + eina_stringshare_del(eced->name); + free(eced); +} + +static void +_ecore_con_eet_raw_data_free(void *data) +{ + Ecore_Con_Eet_Raw_Data *eced = data; + + eina_stringshare_del(eced->name); + free(eced); +} +static void +_ecore_con_eet_reply_cleanup(Ecore_Con_Reply *n) +{ + if (n->buffer_handler) free(n->buffer); + n->buffer = NULL; + n->buffer_handler = NULL; + free(n->buffer_section); + n->buffer_section = NULL; +} + +typedef struct _Ecore_Con_Eet_Protocol Ecore_Con_Eet_Protocol; +struct _Ecore_Con_Eet_Protocol { + const char *type; + void *data; +}; + +static const char * +_ecore_con_eet_data_type_get(const void *data, Eina_Bool *unknow EINA_UNUSED) +{ + const Ecore_Con_Eet_Protocol *p = data; + + return p->type; +} + +static Eina_Bool +_ecore_con_eet_data_type_set(const char *type, void *data, Eina_Bool unknow EINA_UNUSED) +{ + Ecore_Con_Eet_Protocol *p = data; + + p->type = type; + return EINA_TRUE; +} + +static void +_ecore_con_eet_data_descriptor_setup(Ecore_Con_Eet *ece) +{ + Eet_Data_Descriptor_Class eddc; + + EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Ecore_Con_Eet_Protocol); + ece->edd = eet_data_descriptor_stream_new(&eddc); + + eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION; + eddc.func.type_get = _ecore_con_eet_data_type_get; + eddc.func.type_set = _ecore_con_eet_data_type_set; + ece->matching = eet_data_descriptor_stream_new(&eddc); + + EET_DATA_DESCRIPTOR_ADD_VARIANT(ece->edd, Ecore_Con_Eet_Protocol, "data", data, type, ece->matching); +} + +/* Dealing with a server listening to connection */ +static Eina_Bool +_ecore_con_eet_read_cb(const void *eet_data, size_t size, void *user_data) +{ + Ecore_Con_Reply *n = user_data; + Ecore_Con_Eet_Protocol *protocol; + Ecore_Con_Eet_Data *cb; + + protocol = eet_data_descriptor_decode(n->ece->edd, eet_data, size); + if (!protocol) return EINA_TRUE; + + cb = eina_hash_find(n->ece->data_callbacks, protocol->type); + if (!cb) return EINA_TRUE; /* Should I report unknow protocol communication ? */ + + cb->func((void*)cb->data, n, cb->name, protocol->data); + + eina_stringshare_del(protocol->type); + free(protocol); + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_server_write_cb(const void *data, size_t size, void *user_data) +{ + Ecore_Con_Reply *n = user_data; + + if (ecore_con_client_send(n->client, data, size) != (int) size) + return EINA_FALSE; + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_client_write_cb(const void *data, size_t size, void *user_data) +{ + Ecore_Con_Reply *n = user_data; + + if (ecore_con_server_send(n->ece->server, data, size) != (int) size) + return EINA_FALSE; + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_server_connected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Add *ev) +{ + Ecore_Con_Eet_Client *ecec; + Eina_List *ll; + Ecore_Con_Eet *r = data; + Ecore_Con_Reply *n; + + if (ecore_con_client_server_get(ev->client) != r->server) + return EINA_TRUE; + + n = calloc(1, sizeof (Ecore_Con_Reply)); + if (!n) return EINA_TRUE; + + n->client = ev->client; + n->ece = r; + n->econn = eet_connection_new(_ecore_con_eet_read_cb, _ecore_con_eet_server_write_cb, n); + ecore_con_client_data_set(n->client, n); + + EINA_LIST_FOREACH(r->u.server.client_connect_callbacks, ll, ecec) + if (!ecec->func((void*) ecec->data, n, n->client)) + { + eet_connection_close(n->econn, NULL); + free(n); + return EINA_TRUE; + } + + r->u.server.connections = eina_list_append(r->u.server.connections, n); + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_server_disconnected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Del *ev) +{ + Ecore_Con_Eet *r = data; + Ecore_Con_Reply *n; + Eina_List *l; + + if (ecore_con_client_server_get(ev->client) != r->server) + return EINA_TRUE; + + EINA_LIST_FOREACH(r->u.server.connections, l, n) + if (n->client == ev->client) + { + Ecore_Con_Eet_Client *ecec; + Eina_List *ll; + + EINA_LIST_FOREACH(r->u.server.client_disconnect_callbacks, ll, ecec) + ecec->func((void*) ecec->data, n, n->client); + + eet_connection_close(n->econn, NULL); + free(n); + r->u.server.connections = eina_list_remove_list(r->u.server.connections, l); + return EINA_TRUE; + } + + return EINA_TRUE; +} + +static void +_ecore_con_eet_raw_data_push(Ecore_Con_Reply *n, void *data, int size) +{ + if (n->buffer_handler) + memcpy(n->buffer + n->buffer_current, data, size); + n->buffer_current += size; + + if (n->buffer_current == n->buffer_length) + { + if (n->buffer_handler) + n->buffer_handler->func((void*) n->buffer_handler->data, n, n->buffer_handler->name, n->buffer_section, n->buffer, n->buffer_length); + _ecore_con_eet_reply_cleanup(n); + } +} + +static void +_ecore_con_eet_data(Ecore_Con_Reply *n, void *data, unsigned int size) +{ + /* FIXME: Enforce detection of attack and kill connection on that case */ + if (n->buffer) + { + if (n->buffer_current + size > n->buffer_length) + { + _ecore_con_eet_reply_cleanup(n); + return ; + } + + _ecore_con_eet_raw_data_push(n, data, size); + return ; + } + else if (eet_connection_empty(n->econn) && size > (int) (4 * sizeof (unsigned int) + 2)) + { + unsigned int *tmp = data; + size -= 4 * sizeof (unsigned int) + 2; + + if (ntohl(tmp[0]) == ECORE_CON_EET_RAW_MAGIC) + { + unsigned int protocol_length = ntohl(tmp[1]); + unsigned int section_length = ntohl(tmp[2]); + unsigned int data_length = ntohl(tmp[3]); + + if (protocol_length > 1 && section_length > 1 && protocol_length + section_length <= size && data_length < 10 * 1024 * 1024) + { + char *buffer = (char*) &tmp[4]; + char *protocol; + char *section; + + protocol = buffer; + section = buffer + protocol_length; + + if (protocol[protocol_length - 1] == '\0' && + section[section_length - 1] == '\0') + { + size -= protocol_length + section_length; + buffer = section + section_length; + + n->buffer_handler = eina_hash_find(n->ece->raw_data_callbacks, protocol); + n->buffer_section = strdup(section); + n->buffer_length = data_length; + n->buffer_current = 0; + if (n->buffer_handler) + n->buffer = malloc(sizeof (data_length)); + else + n->buffer = (void*) 1; + if (n->buffer) + { + _ecore_con_eet_raw_data_push(n, buffer, size); + return ; + } + _ecore_con_eet_reply_cleanup(n); + + size += protocol_length + section_length; + } + } + } + + size += 4 * sizeof (unsigned int) + 2; + } + + eet_connection_received(n->econn, data, size); +} + +static Eina_Bool +_ecore_con_eet_server_data(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Data *ev) +{ + Ecore_Con_Eet *r = data; + Ecore_Con_Reply *n; + + if (ecore_con_client_server_get(ev->client) != r->server) + return EINA_TRUE; + + n = ecore_con_client_data_get(ev->client); + + _ecore_con_eet_data(n, ev->data, ev->size); + + return EINA_TRUE; +} + +/* Dealing connection to a server */ + +static Eina_Bool +_ecore_con_eet_client_connected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Add *ev) +{ + Ecore_Con_Eet_Server *eces; + Ecore_Con_Eet *r = data; + Ecore_Con_Reply *n; + Eina_List *ll; + + /* Client did connect */ + if (r->server != ev->server) return EINA_TRUE; + if (r->u.client.r) return EINA_TRUE; + + n = calloc(1, sizeof (Ecore_Con_Reply)); + if (!n) return EINA_TRUE; + + n->client = NULL; + n->ece = r; + n->econn = eet_connection_new(_ecore_con_eet_read_cb, _ecore_con_eet_client_write_cb, n); + + EINA_LIST_FOREACH(r->u.client.server_connect_callbacks, ll, eces) + if (!eces->func((void*) eces->data, n, n->ece->server)) + { + eet_connection_close(n->econn, NULL); + free(n); + return EINA_TRUE; + } + + r->u.client.r = n; + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_client_disconnected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Del *ev) +{ + Ecore_Con_Eet *r = data; + Ecore_Con_Eet_Server *eces; + Eina_List *ll; + + if (r->server != ev->server) return EINA_TRUE; + if (!r->u.client.r) return EINA_TRUE; + + /* Client disconnected */ + EINA_LIST_FOREACH(r->u.client.server_disconnect_callbacks, ll, eces) + eces->func((void*) eces->data, r->u.client.r, r->server); + + eet_connection_close(r->u.client.r->econn, NULL); + free(r->u.client.r); + r->u.client.r = NULL; + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_client_data(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Data *ev) +{ + Ecore_Con_Eet *r = data; + + if (r->server != ev->server) return EINA_TRUE; + if (!r->u.client.r) return EINA_TRUE; + + /* Got some data */ + _ecore_con_eet_data(r->u.client.r, ev->data, ev->size); + + return EINA_TRUE; +} + +/************** + * Global API * + **************/ + +EAPI Ecore_Con_Eet * +ecore_con_eet_server_new(Ecore_Con_Server *server) +{ + Ecore_Con_Eet *r; + + if (!server) return NULL; + + r = calloc(1, sizeof (Ecore_Con_Eet)); + if (!r) return NULL; + + r->server = server; + r->handler_add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, + (Ecore_Event_Handler_Cb)_ecore_con_eet_server_connected, r); + r->handler_del = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, + (Ecore_Event_Handler_Cb)_ecore_con_eet_server_disconnected, r); + r->handler_data = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, + (Ecore_Event_Handler_Cb)_ecore_con_eet_server_data, r); + r->data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_data_free); + r->raw_data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_raw_data_free); + + _ecore_con_eet_data_descriptor_setup(r); + + return r; +} + +EAPI Ecore_Con_Eet * +ecore_con_eet_client_new(Ecore_Con_Server *server) +{ + Ecore_Con_Eet *r; + + if (!server) return NULL; + + r = calloc(1, sizeof (Ecore_Con_Eet)); + if (!r) return NULL; + + r->client = EINA_TRUE; + r->server = server; + r->handler_add = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, + (Ecore_Event_Handler_Cb)_ecore_con_eet_client_connected, r); + r->handler_del = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, + (Ecore_Event_Handler_Cb)_ecore_con_eet_client_disconnected, r); + r->handler_data = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, + (Ecore_Event_Handler_Cb)_ecore_con_eet_client_data, r); + r->data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_data_free); + r->raw_data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_raw_data_free); + + _ecore_con_eet_data_descriptor_setup(r); + + return r; +} + +EAPI void +ecore_con_eet_server_free(Ecore_Con_Eet *r) +{ + if (!r) return ; + + eet_data_descriptor_free(r->edd); + eet_data_descriptor_free(r->matching); + eina_hash_free(r->data_callbacks); + eina_hash_free(r->raw_data_callbacks); + + if (r->client) + { + Ecore_Con_Eet_Server *s; + + if (r->u.client.r) + { + _ecore_con_eet_reply_cleanup(r->u.client.r); + eet_connection_close(r->u.client.r->econn, NULL); + free(r->u.client.r); + } + EINA_LIST_FREE(r->u.client.server_connect_callbacks, s) + free(s); + EINA_LIST_FREE(r->u.client.server_disconnect_callbacks, s) + free(s); + } + else + { + Ecore_Con_Reply *n; + Ecore_Con_Eet_Client *c; + + EINA_LIST_FREE(r->u.server.connections, n) + { + _ecore_con_eet_reply_cleanup(n); + eet_connection_close(n->econn, NULL); + free(n); + } + EINA_LIST_FREE(r->u.server.client_connect_callbacks, c) + free(c); + EINA_LIST_FREE(r->u.server.client_disconnect_callbacks, c) + free(c); + } + + ecore_event_handler_del(r->handler_add); + ecore_event_handler_del(r->handler_del); + ecore_event_handler_del(r->handler_data); + free(r); +} + +EAPI void +ecore_con_eet_register(Ecore_Con_Eet *ece, const char *name, Eet_Data_Descriptor *edd) +{ + if (!ece) return ; + + EET_DATA_DESCRIPTOR_ADD_MAPPING(ece->matching, name, edd); +} + +EAPI void +ecore_con_eet_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Data_Cb func, const void *data) +{ + Ecore_Con_Eet_Data *eced; + + if (!ece) return ; + + eced = calloc(1, sizeof (Ecore_Con_Eet_Data));; + if (!eced) return ; + + eced->func = func; + eced->data = data; + eced->name = eina_stringshare_add(name); + + eina_hash_direct_add(ece->data_callbacks, eced->name, eced); +} + +EAPI void +ecore_con_eet_data_callback_del(Ecore_Con_Eet *ece, const char *name) +{ + if (!ece) return ; + eina_hash_del(ece->data_callbacks, name, NULL); +} + +EAPI void +ecore_con_eet_raw_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Raw_Data_Cb func, const void *data) +{ + Ecore_Con_Eet_Raw_Data *eced; + + if (!ece) return ; + + eced = calloc(1, sizeof (Ecore_Con_Eet_Raw_Data));; + if (!eced) return ; + + eced->func = func; + eced->data = data; + eced->name = eina_stringshare_add(name); + + eina_hash_direct_add(ece->raw_data_callbacks, eced->name, eced); +} + +EAPI void +ecore_con_eet_raw_data_callback_del(Ecore_Con_Eet *ece, const char *name) +{ + if (!ece) return ; + + if (ece->client && ece->u.client.r->buffer_handler && !strcmp(ece->u.client.r->buffer_handler->name, name)) + { + ece->u.client.r->buffer_handler = NULL; + free(ece->u.client.r->buffer); + ece->u.client.r->buffer = (void*) 1; + } + eina_hash_del(ece->raw_data_callbacks, name, NULL); +} + +EAPI void +ecore_con_eet_client_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) +{ + Ecore_Con_Eet_Client *c; + + if (!ece || !func) return ; + + c = calloc(1, sizeof (Ecore_Con_Eet_Client)); + if (!c) return ; + + c->func = func; + c->data = data; + + ece->u.server.client_connect_callbacks = eina_list_append(ece->u.server.client_connect_callbacks, c); +} + +EAPI void +ecore_con_eet_client_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) +{ + Ecore_Con_Eet_Client *c; + Eina_List *l; + + if (!ece || !func) return ; + + EINA_LIST_FOREACH(ece->u.server.client_connect_callbacks, l, c) + if (c->func == func && c->data == data) + { + ece->u.server.client_connect_callbacks = eina_list_remove_list(ece->u.server.client_connect_callbacks, l); + free(c); + return ; + } +} + +EAPI void +ecore_con_eet_client_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) +{ + Ecore_Con_Eet_Client *c; + + if (!ece || !func) return ; + + c = calloc(1, sizeof (Ecore_Con_Eet_Client)); + if (!c) return ; + + c->func = func; + c->data = data; + + ece->u.server.client_connect_callbacks = eina_list_append(ece->u.server.client_disconnect_callbacks, c); +} + +EAPI void +ecore_con_eet_client_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) +{ + Ecore_Con_Eet_Client *c; + Eina_List *l; + + if (!ece || !func) return ; + + EINA_LIST_FOREACH(ece->u.server.client_disconnect_callbacks, l, c) + if (c->func == func && c->data == data) + { + ece->u.server.client_disconnect_callbacks = eina_list_remove_list(ece->u.server.client_disconnect_callbacks, + l); + free(c); + return ; + } +} + +EAPI void +ecore_con_eet_server_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) +{ + Ecore_Con_Eet_Server *s; + + if (!ece || !func) return ; + + s = calloc(1, sizeof (Ecore_Con_Eet_Server)); + if (!s) return ; + + s->func = func; + s->data = data; + + ece->u.client.server_connect_callbacks = eina_list_append(ece->u.client.server_connect_callbacks, s); +} + +EAPI void +ecore_con_eet_server_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) +{ + Ecore_Con_Eet_Server *s; + Eina_List *l; + + if (!ece || !func) return ; + + EINA_LIST_FOREACH(ece->u.client.server_connect_callbacks, l, s) + if (s->func == func && s->data == data) + { + ece->u.client.server_connect_callbacks = eina_list_remove_list(ece->u.client.server_connect_callbacks, l); + free(s); + return ; + } +} + +EAPI void +ecore_con_eet_server_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) +{ + Ecore_Con_Eet_Server *s; + + if (!ece || !func) return ; + + s = calloc(1, sizeof (Ecore_Con_Eet_Server)); + if (!s) return ; + + s->func = func; + s->data = data; + + ece->u.client.server_disconnect_callbacks = eina_list_append(ece->u.client.server_disconnect_callbacks, s); +} + +EAPI void +ecore_con_eet_server_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) +{ + Ecore_Con_Eet_Server *s; + Eina_List *l; + + if (!ece || !func) return ; + + EINA_LIST_FOREACH(ece->u.client.server_disconnect_callbacks, l, s) + if (s->func == func && s->data == data) + { + ece->u.client.server_disconnect_callbacks = eina_list_remove_list(ece->u.client.server_disconnect_callbacks, l); + free(s); + return ; + } +} + +EAPI void +ecore_con_eet_data_set(Ecore_Con_Eet *ece, const void *data) +{ + if (!ece) return; + + ece->data = data; +} + +EAPI void * +ecore_con_eet_data_get(Ecore_Con_Eet *ece) +{ + if (!ece) return NULL; + return (void*) ece->data; +} + +EAPI Ecore_Con_Eet * +ecore_con_eet_reply(Ecore_Con_Reply *reply) +{ + if (!reply) return NULL; + return reply->ece; +} + +EAPI void +ecore_con_eet_send(Ecore_Con_Reply *reply, const char *name, void *value) +{ + Ecore_Con_Eet_Protocol protocol; + + if (!reply) return ; + + protocol.type = name; + protocol.data = value; + + eet_connection_send(reply->econn, reply->ece->edd, &protocol, NULL); +} + +EAPI void +ecore_con_eet_raw_send(Ecore_Con_Reply *reply, const char *protocol_name, const char *section, void *value, unsigned int length) +{ + unsigned int protocol[4]; + unsigned int protocol_length; + unsigned int section_length; + unsigned int size; + char *tmp; + + if (!reply) return ; + if (!protocol_name) return ; + if (!section) return ; + + protocol_length = strlen(protocol_name) + 1; + if (protocol_length == 1) return ; + section_length = strlen(section) + 1; + + protocol[0] = htonl(ECORE_CON_EET_RAW_MAGIC); + protocol[1] = htonl(protocol_length); + protocol[2] = htonl(section_length); + protocol[3] = htonl(length); + + size = sizeof (protocol) + protocol_length + section_length; + tmp = alloca(size); + memcpy(tmp, protocol, sizeof (protocol)); + memcpy(tmp + sizeof (protocol), protocol, protocol_length); + memcpy(tmp + sizeof (protocol) + protocol_length, section, section_length); + + if (reply->client) + { + ecore_con_client_send(reply->client, tmp, size); + ecore_con_client_send(reply->client, value, length); + } + else + { + ecore_con_server_send(reply->ece->server, tmp, size); + ecore_con_server_send(reply->ece->server, value, length); + } +} + diff --git a/src/lib/ecore_con/ecore_con_info.c b/src/lib/ecore_con/ecore_con_info.c index fdcf0b9..4526c08 100644 --- a/src/lib/ecore_con/ecore_con_info.c +++ b/src/lib/ecore_con/ecore_con_info.c @@ -9,26 +9,36 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif #ifdef HAVE_ALLOCA_H # include -#elif defined __GNUC__ -# define alloca __builtin_alloca -#elif defined _AIX -# define alloca __alloca -#elif defined _MSC_VER -# include -# define alloca _alloca -#else -# include -# ifdef __cplusplus +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus extern "C" +# endif +void *alloca (size_t); # endif -void *alloca(size_t); #endif #include #include #include +#include #include #ifdef __OpenBSD__ # include @@ -196,6 +206,26 @@ ecore_con_info_mcast_listen(Ecore_Con_Server *svr, return ecore_con_info_get(svr, done_cb, data, &hints); } +Eina_Bool +_ecore_fd_close_on_exec(int fd) +{ +#ifdef HAVE_EXECVP + int flags; + + flags = fcntl(fd, F_GETFD); + if (flags == -1) + return EINA_FALSE; + + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) + return EINA_FALSE; + return EINA_TRUE; +#else + (void) fd; + return EINA_FALSE; +#endif +} + EAPI int ecore_con_info_get(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, @@ -211,6 +241,9 @@ ecore_con_info_get(Ecore_Con_Server *svr, return 0; } + _ecore_fd_close_on_exec(fd[0]); + _ecore_fd_close_on_exec(fd[1]); + cbdata = calloc(1, sizeof(CB_Data)); if (!cbdata) { diff --git a/src/lib/ecore_con/ecore_con_local.c b/src/lib/ecore_con/ecore_con_local.c index 7113b8c..03becd0 100644 --- a/src/lib/ecore_con/ecore_con_local.c +++ b/src/lib/ecore_con/ecore_con_local.c @@ -7,8 +7,13 @@ #include #include #include +#include #include +#ifdef HAVE_ERRNO_H +# include +#endif + #ifdef HAVE_SYS_SOCKET_H # include #endif @@ -85,7 +90,10 @@ ecore_con_local_connect(Ecore_Con_Server *svr, if (svr->port < 0) { if (svr->name[0] == '/') - strncpy(buf, svr->name, sizeof(buf)); + { + strncpy(buf, svr->name, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = 0; + } else snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s", svr->name); } @@ -144,7 +152,7 @@ ecore_con_local_connect(Ecore_Con_Server *svr, if (connect(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) { - ERR("local connection failed: %s", strerror(errno)); + WRN("local connection failed: %s", strerror(errno)); return 0; } @@ -240,8 +248,10 @@ ecore_con_local_listen( svr->port); } else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) - strncpy(buf, svr->name, - sizeof(buf)); + { + strncpy(buf, svr->name, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = 0; + } pmode = umask(mask); start: @@ -273,7 +283,7 @@ start: socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix, svr->name); #else - ERR("Your system does not support abstract sockets!"); + WRN("Your system does not support abstract sockets!"); goto error_umask; #endif } @@ -285,14 +295,24 @@ start: if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) { - if ((((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) || - ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)) && - (connect(svr->fd, (struct sockaddr *)&socket_unix, - socket_unix_len) < 0) && - (unlink(buf) >= 0)) - goto start; + WRN("bind error[%s].", strerror(errno)); + if (((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) || + ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)) + { + int u = unlink(buf); + if (u >= 0) + { + if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) + { + WRN("bind error[%s].", strerror(errno)); + goto error_umask; + } + } + } else - goto error_umask; + { + goto error_umask; + } } if (listen(svr->fd, 4096) < 0) @@ -315,6 +335,8 @@ error_umask: umask(pmode); error: #endif /* HAVE_LOCAL_SOCKETS */ + + WRN("error returned."); return 0; } diff --git a/src/lib/ecore_con/ecore_con_local_win32.c b/src/lib/ecore_con/ecore_con_local_win32.c index 2b7e5c5..9fa499a 100644 --- a/src/lib/ecore_con/ecore_con_local_win32.c +++ b/src/lib/ecore_con/ecore_con_local_win32.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include diff --git a/src/lib/ecore_con/ecore_con_socks.c b/src/lib/ecore_con/ecore_con_socks.c index e609a6a..9053efe 100644 --- a/src/lib/ecore_con/ecore_con_socks.c +++ b/src/lib/ecore_con/ecore_con_socks.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include #include @@ -566,7 +592,7 @@ ecore_con_socks_init(void) v5 = EINA_TRUE; } if ((!socks) || (!socks[0]) || (strlen(socks) > 512)) return; - strncpy(buf, socks, sizeof(buf)); + memcpy(buf, socks, strlen(socks) + 1); h = strchr(buf, '@'); /* username */ if (h && (h - buf > 0)) *h++ = 0, u = buf; diff --git a/src/lib/ecore_con/ecore_con_ssl.c b/src/lib/ecore_con/ecore_con_ssl.c index fd4c9dd..20fafcc 100644 --- a/src/lib/ecore_con/ecore_con_ssl.c +++ b/src/lib/ecore_con/ecore_con_ssl.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #if USE_GNUTLS # include # include @@ -1557,6 +1583,7 @@ _ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr, break; default: + svr->ssl_prepared = EINA_TRUE; return ECORE_CON_SSL_ERROR_NONE; } @@ -1577,6 +1604,7 @@ _ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr, else if (!svr->use_cert) SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:!ECDH:RSA:AES:!PSK:@STRENGTH")); + svr->ssl_prepared = EINA_TRUE; return ECORE_CON_SSL_ERROR_NONE; error: @@ -1741,6 +1769,7 @@ _ecore_con_ssl_server_privkey_add_openssl(Ecore_Con_Server *svr, SSL_ERROR_CHECK_GOTO_ERROR(!(privkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL))); fclose(fp); + fp = NULL; SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_PrivateKey(svr->ssl_ctx, privkey) < 1); SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_check_private_key(svr->ssl_ctx) < 1); @@ -1766,7 +1795,7 @@ _ecore_con_ssl_server_cert_add_openssl(Ecore_Con_Server *svr, SSL_ERROR_CHECK_GOTO_ERROR(!(cert = PEM_read_X509(fp, NULL, NULL, NULL))); fclose(fp); - + fp = NULL; SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_certificate(svr->ssl_ctx, cert) < 1); return EINA_TRUE; diff --git a/src/lib/ecore_con/ecore_con_url.c b/src/lib/ecore_con/ecore_con_url.c index 44c7bab..419cfca 100644 --- a/src/lib/ecore_con/ecore_con_url.c +++ b/src/lib/ecore_con/ecore_con_url.c @@ -56,7 +56,7 @@ static CURLM *_curlm = NULL; static int _init_count = 0; static Ecore_Timer *_curl_timer = NULL; static Eina_Bool pipelining = EINA_FALSE; - +Ecore_Idler *_curl_idler; #endif /** @@ -91,6 +91,7 @@ ecore_con_url_init(void) _curl_timer = ecore_timer_add((double)ms / 1000, _ecore_con_url_timer, NULL); ecore_timer_freeze(_curl_timer); + _curl_idler = NULL; return _init_count; #else @@ -114,6 +115,9 @@ ecore_con_url_shutdown(void) _curl_timer = NULL; } + if (_curl_idler) ecore_idler_del(_curl_idler); + _curl_idler = NULL; + EINA_LIST_FREE(_url_con_list, url_con) ecore_con_url_free(url_con); EINA_LIST_FREE(_fd_hd_list, fd_handler) @@ -1304,22 +1308,39 @@ static void _ecore_con_url_event_url_complete(Ecore_Con_Url *url_con, CURLMsg *curlmsg) { Ecore_Con_Event_Url_Complete *e; + int status = url_con->status; e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete)); if (!e) return; - if (curlmsg && (curlmsg->data.result == CURLE_OK)) + if (!curlmsg) + { + ERR("Event completed without CURL message handle. Shouldn't happen"); + } + else if ((curlmsg->msg == CURLMSG_DONE) && + (curlmsg->data.result == CURLE_OPERATION_TIMEDOUT) && + (!curlmsg->easy_handle)) + { + /* easy_handle is set to NULL on timeout messages */ + status = 408; /* Request Timeout */ + } + else if (curlmsg->data.result == CURLE_OK) { - if (!url_con->status) - _ecore_con_url_status_get(url_con); + if (!status) + { + _ecore_con_url_status_get(url_con); + status = url_con->status; + } } - else if (curlmsg) - ERR("Curl message have errors: %d", curlmsg->data.result); else - CRIT("THIS IS BAD."); + { + ERR("Curl message have errors: %d (%s)", + curlmsg->data.result, curl_easy_strerror(curlmsg->data.result)); + } - e->status = url_con->status; + e->status = status; e->url_con = url_con; + url_con->event_count++; ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con); } @@ -1338,6 +1359,7 @@ static Eina_Bool _ecore_con_url_timeout_cb(void *data) { Ecore_Con_Url *url_con = data; + CURLMsg timeout_msg; if (!url_con) return ECORE_CALLBACK_CANCEL; if (!url_con->curl_easy) return ECORE_CALLBACK_CANCEL; @@ -1350,7 +1372,11 @@ _ecore_con_url_timeout_cb(void *data) url_con->timer = NULL; - _ecore_con_url_event_url_complete(url_con, NULL); + timeout_msg.msg = CURLMSG_DONE; + timeout_msg.easy_handle = NULL; + timeout_msg.data.result = CURLE_OPERATION_TIMEDOUT; + + _ecore_con_url_event_url_complete(url_con, &timeout_msg); return ECORE_CALLBACK_CANCEL; } @@ -1519,8 +1545,18 @@ static Eina_Bool _ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__) { Ecore_Fd_Handler *fdh; + long ms; + EINA_LIST_FREE(_fd_hd_list, fdh) ecore_main_fd_handler_del(fdh); - ecore_timer_interval_set(_curl_timer, 0.1); + + curl_multi_timeout(_curlm, &ms); + if (ms >= CURL_MIN_TIMEOUT || ms <= 0) ms = CURL_MIN_TIMEOUT; + + ecore_timer_interval_set(_curl_timer, (double)ms / 1000); + + if (!_curl_timer) + _curl_idler = ecore_idler_add(_ecore_con_url_timer, NULL); + return ECORE_CALLBACK_CANCEL; } @@ -1583,6 +1619,8 @@ _ecore_con_url_timer(void *data __UNUSED__) ERR("curl_multi_perform() failed: %s", curl_multi_strerror(ret)); _ecore_con_url_curl_clear(); ecore_timer_freeze(_curl_timer); + if (_curl_idler) ecore_idler_del(_curl_idler); + _curl_idler = NULL; } if (still_running) @@ -1600,6 +1638,8 @@ _ecore_con_url_timer(void *data __UNUSED__) _ecore_con_url_info_read(); _ecore_con_url_curl_clear(); ecore_timer_freeze(_curl_timer); + if (_curl_idler) ecore_idler_del(_curl_idler); + _curl_idler = NULL; } return ECORE_CALLBACK_RENEW; diff --git a/src/lib/ecore_config/Ecore_Config.h b/src/lib/ecore_config/Ecore_Config.h index 6733d7b..51faab7 100644 --- a/src/lib/ecore_config/Ecore_Config.h +++ b/src/lib/ecore_config/Ecore_Config.h @@ -23,35 +23,43 @@ #endif /** - * @file + * @internal + * @file * @brief Provides the Enlightened Property Library. * - * This file provies all headers and structs for use with Ecore_Config. - * Using individual header files should not be necessary. + * @remarks This file provides all headers and structs for use with Ecore_Config. + * Using individual header files should not be necessary. */ +/** + * @internal + * @defgroup Ecore_Config_Group Ecore_Config + * @ingroup Ecore_Group + * + * @{ + */ # define DIR_DELIMITER '/' # define ECORE_CONFIG_FLOAT_PRECISION 1000 -/* FIXME: this should only be included if evas is present */ +/* FIXME: This should only be included if evas is present */ # include # define ECORE_CONFIG_GLOBAL_ID "_system" -/* structures */ +/* Structures */ /** - * Valid configuration property types. + * @brief Enumeration for configuration property types. */ typedef enum Ecore_Config_Type { - ECORE_CONFIG_NIL = 0, /**< Property with no value. */ - ECORE_CONFIG_INT = 1, /**< Integer property type. */ - ECORE_CONFIG_FLT = 2, /**< Float property type. */ - ECORE_CONFIG_STR = 3, /**< String property type. */ - ECORE_CONFIG_RGB = 4, /**< Colour property type. */ - ECORE_CONFIG_THM = 5, /**< Theme property type. */ - ECORE_CONFIG_BLN = 6, /**< Boolean property type. */ + ECORE_CONFIG_NIL = 0, /**< Property with no value */ + ECORE_CONFIG_INT = 1, /**< Integer property type */ + ECORE_CONFIG_FLT = 2, /**< Float property type */ + ECORE_CONFIG_STR = 3, /**< String property type */ + ECORE_CONFIG_RGB = 4, /**< Colour property type */ + ECORE_CONFIG_THM = 5, /**< Theme property type */ + ECORE_CONFIG_BLN = 6, /**< Boolean property type */ ECORE_CONFIG_SCT = 7, /**< Structure property type */ } Ecore_Config_Type; @@ -65,11 +73,11 @@ typedef enum Ecore_Config_Flag } Ecore_Config_Flag; /** - * Property change callback function prototype. + * @brief The integer type for the property change callback function prototype. */ typedef int (*Ecore_Config_Listener) (const char *key, - const Ecore_Config_Type type, - const int tag, void *data); + const Ecore_Config_Type type, + const int tag, void *data); typedef struct Ecore_Config_Listener_List { @@ -81,47 +89,47 @@ typedef struct Ecore_Config_Listener_List } Ecore_Config_Listener_List; /** - * The actual property for storing a key-value pair. + * @brief The structure type containing the actual property for storing a key-value pair. */ typedef struct Ecore_Config_Prop { - char *key; /* Property key. */ - char *description; /* Description set by ecore_config_descibe. */ - char short_opt; /* short identifier on command line (-f) */ - char *long_opt; /* long identifier on command line (--foo) */ - char *ptr; /* Used as the value when the property is a string or theme. */ - Ecore_Config_Type type; /* Property type. */ - long val; /* Used as the value when the property is an integer, float or colour. */ - long lo; /* Lower bound for the value when the property is an integer or float. */ - long hi; /* Higher bound for the value when the property is an integer or float. */ - long step; /* Increment for the value when the property is an integer or float. */ - Ecore_Config_Flag flags; /// < Configuration flags. - Ecore_Config_Listener_List *listeners; /* List of change listeners. */ - void *data; /// < Stores extra data for the property. - struct Ecore_Config_Prop *parent; /* if we are in a struct we have a parent to notify of changes etc */ - struct Ecore_Config_Prop *next; /* Pointer to the next property in the list. */ + char *key; /**< Property key */ + char *description; /**< Description set by ecore_config_descibe */ + char short_opt; /**< Short identifier on command line (-f) */ + char *long_opt; /**< Long identifier on command line (--foo) */ + char *ptr; /**< Used as the value when the property is a string or theme */ + Ecore_Config_Type type; /**< Property type */ + long val; /**< Used as the value when the property is an integer, float or colour */ + long lo; /**< Lower bound for the value when the property is an integer or float */ + long hi; /**< Higher bound for the value when the property is an integer or float */ + long step; /**< Increment for the value when the property is an integer or float */ + Ecore_Config_Flag flags; /**< Configuration flags */ + Ecore_Config_Listener_List *listeners; /**< List of change listeners */ + void *data; /**< Stores extra data for the property */ + struct Ecore_Config_Prop *parent; /**< Parent to notify of changes */ + struct Ecore_Config_Prop *next; /**< Pointer to the next property in the list */ } Ecore_Config_Prop; -/* - * A container for a list of properties. Provided so that an - * application can use different set of properties at any time. This - * is useful for multiple window support. +/** + * @brief The structure type of a container for a list of properties. This is provided so that an + * application can use different set of properties at any time. This + * is useful for multiple window support. */ typedef struct Ecore_Config_Bundle { - char *identifier; /* Identifier for this set of properties (window ID for example) */ - char *owner; /* This is used to store the application name related to the bundle */ - long serial; /* Unique identifier to identify bundle */ - Ecore_Config_Prop *data; /* Pointer to root of property list */ - void *user_data; /* App specific pointer to "other data" */ - struct Ecore_Config_Bundle *next; /* Pointer to next bundle in this application */ + char *identifier; /**< Identifier for this set of properties (window ID for example) */ + char *owner; /**< Application name related to the bundle */ + long serial; /**< Unique identifier to identify bundle */ + Ecore_Config_Prop *data; /**< Pointer to the root of property list */ + void *user_data; /**< App specific pointer to "other data" */ + struct Ecore_Config_Bundle *next; /**< Pointer to next bundle in this application */ } Ecore_Config_Bundle; typedef struct Ecore_Config_Server { void *server; char *name; - Ecore_Config_Bundle *bundles; /* data anchor */ + Ecore_Config_Bundle *bundles; /**< Data anchor */ struct Ecore_Config_Server *next; } Ecore_Config_Server; @@ -130,103 +138,103 @@ extern "C" { # endif -/* global ptrs to save passing them through the API */ - EAPI extern Ecore_Config_Server *__ecore_config_server_global; - EAPI extern Ecore_Config_Server *__ecore_config_server_local; - EAPI extern Ecore_Config_Bundle *__ecore_config_bundle_local; - EAPI extern char *__ecore_config_app_name; +/* Global pointers to save passing them through the API */ +EAPI extern Ecore_Config_Server *__ecore_config_server_global; +EAPI extern Ecore_Config_Server *__ecore_config_server_local; +EAPI extern Ecore_Config_Bundle *__ecore_config_bundle_local; +EAPI extern char *__ecore_config_app_name; - EAPI Ecore_Config_Prop *ecore_config_get(const char *key); - EAPI const char *ecore_config_type_get(const Ecore_Config_Prop *e); - EAPI int ecore_config_boolean_get(const char *key); - EAPI char *ecore_config_string_get(const char *key); - EAPI long ecore_config_int_get(const char *key); - EAPI int ecore_config_argb_get(const char *key, int *a, int *r, - int *g, int *b); - EAPI long ecore_config_argbint_get(const char *key); - EAPI char *ecore_config_argbstr_get(const char *key); - EAPI float ecore_config_float_get(const char *key); - EAPI char *ecore_config_theme_get(const char *key); - EAPI char *ecore_config_as_string_get(const char *key); - EAPI int ecore_config_bound(Ecore_Config_Prop *e); - EAPI int ecore_config_describe(const char *key, const char *desc); - EAPI int ecore_config_short_opt_set(const char *key, - char short_opt); - EAPI int ecore_config_long_opt_set(const char *key, - const char *long_opt); - EAPI int ecore_config_set(const char *key, const char *val); - EAPI int ecore_config_typed_set(const char *key, const void *val, - int type); - EAPI int ecore_config_boolean_set(const char *key, int val); - EAPI int ecore_config_string_set(const char *key, const char *val); - EAPI int ecore_config_int_set(const char *key, int val); - EAPI int ecore_config_argb_set(const char *key, int a, int r, int g, int b); - EAPI int ecore_config_argbint_set(const char *key, long argb); - EAPI int ecore_config_argbstr_set(const char *key, const char *val); - EAPI int ecore_config_float_set(const char *key, float val); - EAPI int ecore_config_theme_set(const char *key, const char *val); - EAPI int ecore_config_theme_preview_group_set(const char *key, - const char *group); - EAPI int ecore_config_as_string_set(const char *key, const char *val); +EAPI Ecore_Config_Prop *ecore_config_get(const char *key); +EAPI const char *ecore_config_type_get(const Ecore_Config_Prop *e); +EAPI int ecore_config_boolean_get(const char *key); +EAPI char *ecore_config_string_get(const char *key); +EAPI long ecore_config_int_get(const char *key); +EAPI int ecore_config_argb_get(const char *key, int *a, int *r, + int *g, int *b); +EAPI long ecore_config_argbint_get(const char *key); +EAPI char *ecore_config_argbstr_get(const char *key); +EAPI float ecore_config_float_get(const char *key); +EAPI char *ecore_config_theme_get(const char *key); +EAPI char *ecore_config_as_string_get(const char *key); +EAPI int ecore_config_bound(Ecore_Config_Prop *e); +EAPI int ecore_config_describe(const char *key, const char *desc); +EAPI int ecore_config_short_opt_set(const char *key, + char short_opt); +EAPI int ecore_config_long_opt_set(const char *key, + const char *long_opt); +EAPI int ecore_config_set(const char *key, const char *val); +EAPI int ecore_config_typed_set(const char *key, const void *val, + int type); +EAPI int ecore_config_boolean_set(const char *key, int val); +EAPI int ecore_config_string_set(const char *key, const char *val); +EAPI int ecore_config_int_set(const char *key, int val); +EAPI int ecore_config_argb_set(const char *key, int a, int r, int g, int b); +EAPI int ecore_config_argbint_set(const char *key, long argb); +EAPI int ecore_config_argbstr_set(const char *key, const char *val); +EAPI int ecore_config_float_set(const char *key, float val); +EAPI int ecore_config_theme_set(const char *key, const char *val); +EAPI int ecore_config_theme_preview_group_set(const char *key, + const char *group); +EAPI int ecore_config_as_string_set(const char *key, const char *val); - EAPI int ecore_config_default(const char *key, const char *val, - float lo, float hi, float step); - EAPI int ecore_config_typed_default(const char *key, const void *val, - int type); - EAPI int ecore_config_boolean_default(const char *key, int val); - EAPI int ecore_config_int_default(const char *key, int val); - EAPI int ecore_config_int_default_bound(const char *key, int val, - int lo, int hi, int step); - EAPI int ecore_config_string_default(const char *key, const char *val); - EAPI int ecore_config_float_default(const char *key, float val); - EAPI int ecore_config_float_default_bound(const char *key, - float val, float lo, - float hi, float step); - EAPI int ecore_config_argb_default(const char *key, int a, int r, int g, int b); - EAPI int ecore_config_argbint_default(const char *key, long argb); - EAPI int ecore_config_argbstr_default(const char *key, const char *val); - EAPI int ecore_config_theme_default(const char *key, const char *val); - EAPI int ecore_config_struct_default(const char *key); - EAPI int ecore_config_struct_int_add(const char *key, const char *name, int val); - EAPI int ecore_config_struct_float_add(const char *key, const char *name, float val); - EAPI int ecore_config_struct_create(const char *key); - EAPI int ecore_config_struct_string_add(const char *key, const char *name, const char* val); - EAPI int ecore_config_struct_theme_add(const char *key, const char *name, const char* val); - EAPI int ecore_config_struct_argb_add(const char *key, const char *name, int a, int r, int g, int b); - EAPI int ecore_config_struct_boolean_add(const char *key, const char *name, int val); - EAPI int ecore_config_struct_get(const char *key, void *data); +EAPI int ecore_config_default(const char *key, const char *val, + float lo, float hi, float step); +EAPI int ecore_config_typed_default(const char *key, const void *val, + int type); +EAPI int ecore_config_boolean_default(const char *key, int val); +EAPI int ecore_config_int_default(const char *key, int val); +EAPI int ecore_config_int_default_bound(const char *key, int val, + int lo, int hi, int step); +EAPI int ecore_config_string_default(const char *key, const char *val); +EAPI int ecore_config_float_default(const char *key, float val); +EAPI int ecore_config_float_default_bound(const char *key, + float val, float lo, + float hi, float step); +EAPI int ecore_config_argb_default(const char *key, int a, int r, int g, int b); +EAPI int ecore_config_argbint_default(const char *key, long argb); +EAPI int ecore_config_argbstr_default(const char *key, const char *val); +EAPI int ecore_config_theme_default(const char *key, const char *val); +EAPI int ecore_config_struct_default(const char *key); +EAPI int ecore_config_struct_int_add(const char *key, const char *name, int val); +EAPI int ecore_config_struct_float_add(const char *key, const char *name, float val); +EAPI int ecore_config_struct_create(const char *key); +EAPI int ecore_config_struct_string_add(const char *key, const char *name, const char* val); +EAPI int ecore_config_struct_theme_add(const char *key, const char *name, const char* val); +EAPI int ecore_config_struct_argb_add(const char *key, const char *name, int a, int r, int g, int b); +EAPI int ecore_config_struct_boolean_add(const char *key, const char *name, int val); +EAPI int ecore_config_struct_get(const char *key, void *data); - EAPI int ecore_config_listen(const char *name, const char *key, - Ecore_Config_Listener listener, - int tag, void *data); - EAPI int ecore_config_deaf(const char *name, const char *key, - Ecore_Config_Listener listener); - EAPI Ecore_Config_Prop *ecore_config_dst(Ecore_Config_Prop *e); - EAPI int ecore_config_type_guess(const char *key, const char *val); +EAPI int ecore_config_listen(const char *name, const char *key, + Ecore_Config_Listener listener, + int tag, void *data); +EAPI int ecore_config_deaf(const char *name, const char *key, + Ecore_Config_Listener listener); +EAPI Ecore_Config_Prop *ecore_config_dst(Ecore_Config_Prop *e); +EAPI int ecore_config_type_guess(const char *key, const char *val); - EAPI Ecore_Config_Bundle *ecore_config_bundle_new(Ecore_Config_Server *srv, - const char *id); - EAPI Ecore_Config_Bundle *ecore_config_bundle_1st_get(Ecore_Config_Server *srv); - EAPI Ecore_Config_Bundle *ecore_config_bundle_next_get(Ecore_Config_Bundle *ns); - EAPI Ecore_Config_Bundle *ecore_config_bundle_by_serial_get(Ecore_Config_Server *srv, - long serial); - EAPI Ecore_Config_Bundle *ecore_config_bundle_by_label_get(Ecore_Config_Server *srv, - const char *label); - EAPI long ecore_config_bundle_serial_get(Ecore_Config_Bundle *ns); - EAPI char *ecore_config_bundle_label_get(Ecore_Config_Bundle *ns); +EAPI Ecore_Config_Bundle *ecore_config_bundle_new(Ecore_Config_Server *srv, + const char *id); +EAPI Ecore_Config_Bundle *ecore_config_bundle_1st_get(Ecore_Config_Server *srv); +EAPI Ecore_Config_Bundle *ecore_config_bundle_next_get(Ecore_Config_Bundle *ns); +EAPI Ecore_Config_Bundle *ecore_config_bundle_by_serial_get(Ecore_Config_Server *srv, + long serial); +EAPI Ecore_Config_Bundle *ecore_config_bundle_by_label_get(Ecore_Config_Server *srv, + const char *label); +EAPI long ecore_config_bundle_serial_get(Ecore_Config_Bundle *ns); +EAPI char *ecore_config_bundle_label_get(Ecore_Config_Bundle *ns); - EAPI int ecore_config_init(const char *name); - EAPI int ecore_config_shutdown(void); +EAPI int ecore_config_init(const char *name); +EAPI int ecore_config_shutdown(void); - EAPI int ecore_config_system_init(void); - EAPI int ecore_config_system_shutdown(void); +EAPI int ecore_config_system_init(void); +EAPI int ecore_config_system_shutdown(void); - EAPI int ecore_config_load(void); - EAPI int ecore_config_file_load(const char *file); - EAPI int ecore_config_save(void); - EAPI int ecore_config_file_save(const char *file); +EAPI int ecore_config_load(void); +EAPI int ecore_config_file_load(const char *file); +EAPI int ecore_config_save(void); +EAPI int ecore_config_file_save(const char *file); -/* error codes */ +/* Definition for error codes */ # define ECORE_CONFIG_ERR_NOTSUPP (-16) # define ECORE_CONFIG_ERR_NOFILE (-15) # define ECORE_CONFIG_ERR_META_DLFAIL (-14) @@ -238,75 +246,79 @@ extern "C" # define ECORE_CONFIG_ERR_PATHEX (-8) # define ECORE_CONFIG_ERR_TYPEMISMATCH (-7) # define ECORE_CONFIG_ERR_MUTEX (-6) -# define ECORE_CONFIG_ERR_NOTFOUND (-5) /* Error indicating that the item searched for could not be found. */ -# define ECORE_CONFIG_ERR_OOM (-4) /* Error given when the program runs out of memory. */ -# define ECORE_CONFIG_ERR_IGNORED (-3) /* Error occurred, but was ignored. */ -# define ECORE_CONFIG_ERR_NODATA (-2) /* Error given when necessary data is not provided. */ -# define ECORE_CONFIG_ERR_FAIL (-1) /* Failure result. */ -# define ECORE_CONFIG_ERR_SUCC (0) /* Success result. */ +# define ECORE_CONFIG_ERR_NOTFOUND (-5) /* Error indicating that the item searched for could not be found */ +# define ECORE_CONFIG_ERR_OOM (-4) /* Error when the program runs out of memory */ +# define ECORE_CONFIG_ERR_IGNORED (-3) /* Error occurred, but is ignored */ +# define ECORE_CONFIG_ERR_NODATA (-2) /* Error given when necessary data is not provided */ +# define ECORE_CONFIG_ERR_FAIL (-1) /* Failure result */ +# define ECORE_CONFIG_ERR_SUCC (0) /* Success result */ -# define ECORE_CONFIG_PARSE_HELP (-2) /* Help was displayed */ +# define ECORE_CONFIG_PARSE_HELP (-2) /* Help is displayed */ # define ECORE_CONFIG_PARSE_EXIT (-1) /* An error occurred */ # define ECORE_CONFIG_PARSE_CONTINUE (0) /* Arguments parsed successfully */ -/* convenience mathods in convenience.c */ - /* FIXME: this should only be included if evas is present */ - EAPI int ecore_config_evas_font_path_apply(Evas *evas); - EAPI char *ecore_config_theme_search_path_get(void); - EAPI int ecore_config_theme_search_path_append(const char *append); - - EAPI char *ecore_config_theme_default_path_get(void); - EAPI char *ecore_config_theme_with_path_from_name_get(char *name); - EAPI char *ecore_config_theme_with_path_get(const char *key); - EAPI void ecore_config_args_display(void); - EAPI int ecore_config_args_parse(void); - EAPI void ecore_config_args_callback_str_add(char short_opt, - char *long_opt, char *desc, - void (*func)(char *val, void *data), - void *data); - EAPI void ecore_config_args_callback_noarg_add(char short_opt, - char *long_opt, char *desc, - void (*func)(char *val, void *data), - void *data); - EAPI void ecore_config_app_describe(char *description); +/* Convenience methods in convenience.c */ + /* FIXME: This should only be included if evas is present */ +EAPI int ecore_config_evas_font_path_apply(Evas *evas); +EAPI char *ecore_config_theme_search_path_get(void); +EAPI int ecore_config_theme_search_path_append(const char *append); + +EAPI char *ecore_config_theme_default_path_get(void); +EAPI char *ecore_config_theme_with_path_from_name_get(char *name); +EAPI char *ecore_config_theme_with_path_get(const char *key); +EAPI void ecore_config_args_display(void); +EAPI int ecore_config_args_parse(void); +EAPI void ecore_config_args_callback_str_add(char short_opt, + char *long_opt, char *desc, + void (*func)(char *val, void *data), + void *data); +EAPI void ecore_config_args_callback_noarg_add(char short_opt, + char *long_opt, char *desc, + void (*func)(char *val, void *data), + void *data); +EAPI void ecore_config_app_describe(char *description); - EAPI int ecore_config_create(const char *key, void *val, - char short_opt, char *long_opt, - char *desc); - EAPI int ecore_config_typed_create(const char *key, void *val, - int type, char short_opt, - char *long_opt, char *desc); - EAPI int ecore_config_boolean_create(const char *key, int val, - char short_opt, char *long_opt, - char *desc); - EAPI int ecore_config_int_create(const char *key, int val, - char short_opt, char *long_opt, - char *desc); - EAPI int ecore_config_int_create_bound(const char *key, int val, - int low, int high, - int step, char short_opt, - char *long_opt, - char *desc); - EAPI int ecore_config_string_create(const char *key, char *val, - char short_opt, - char *long_opt, char *desc); - EAPI int ecore_config_float_create(const char *key, float val, - char short_opt, char *long_opt, - char *desc); - EAPI int ecore_config_float_create_bound(const char *key, - float val, float low, - float high, float step, - char short_opt, - char *long_opt, - char *desc); - EAPI int ecore_config_argb_create(const char *key, char *val, - char short_opt, char *long_opt, - char *desc); - EAPI int ecore_config_theme_create(const char *key, char *val, - char short_opt, char *long_opt, - char *desc); +EAPI int ecore_config_create(const char *key, void *val, + char short_opt, char *long_opt, + char *desc); +EAPI int ecore_config_typed_create(const char *key, void *val, + int type, char short_opt, + char *long_opt, char *desc); +EAPI int ecore_config_boolean_create(const char *key, int val, + char short_opt, char *long_opt, + char *desc); +EAPI int ecore_config_int_create(const char *key, int val, + char short_opt, char *long_opt, + char *desc); +EAPI int ecore_config_int_create_bound(const char *key, int val, + int low, int high, + int step, char short_opt, + char *long_opt, + char *desc); +EAPI int ecore_config_string_create(const char *key, char *val, + char short_opt, + char *long_opt, char *desc); +EAPI int ecore_config_float_create(const char *key, float val, + char short_opt, char *long_opt, + char *desc); +EAPI int ecore_config_float_create_bound(const char *key, + float val, float low, + float high, float step, + char short_opt, + char *long_opt, + char *desc); +EAPI int ecore_config_argb_create(const char *key, char *val, + char short_opt, char *long_opt, + char *desc); +EAPI int ecore_config_theme_create(const char *key, char *val, + char short_opt, char *long_opt, + char *desc); # ifdef __cplusplus } # endif + +/** + * @} + */ #endif diff --git a/src/lib/ecore_config/ecore_config.c b/src/lib/ecore_config/ecore_config.c index e81538e..bb35700 100644 --- a/src/lib/ecore_config/ecore_config.c +++ b/src/lib/ecore_config/ecore_config.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include #include diff --git a/src/lib/ecore_directfb/Ecore_DirectFB.h b/src/lib/ecore_directfb/Ecore_DirectFB.h index 3b94816..4044043 100644 --- a/src/lib/ecore_directfb/Ecore_DirectFB.h +++ b/src/lib/ecore_directfb/Ecore_DirectFB.h @@ -54,9 +54,9 @@ typedef struct _Ecore_DirectFB_Event_Wheel Ecore_DirectFB_Event_Wheel; typedef struct _Ecore_DirectFB_Event_Got_Focus Ecore_DirectFB_Event_Got_Focus; typedef struct _Ecore_DirectFB_Event_Lost_Focus Ecore_DirectFB_Event_Lost_Focus; -/* this struct is to keep windows data (id, window itself and surface) in memory as every call - * to DirectFB for this values (e.g window->GetSurface(window,&surface)) will increment the - * reference count, then we will have to release N times the data, so better we just ask for +/* This struct is to keep windows data (id, window itself, and surface) in memory as every call + * to DirectFB for these values (e.g window->GetSurface(window,&surface)) increments the + * reference count, then we have to release N times the data, so it is better if we just ask for them once */ struct _Ecore_DirectFB_Window { @@ -75,18 +75,18 @@ struct _Ecore_DirectFB_Cursor struct _Ecore_DirectFB_Event_Key_Down /** DirectFB Key Down event */ { - char *name; /**< The name of the key that was released */ - char *string; /**< The logical symbol of the key that was pressed */ - char *key_compose; /**< The UTF-8 string conversion if any */ + char *name; /**< The name of the key that is released */ + char *string; /**< The logical symbol of the key that is pressed */ + char *key_compose; /**< The UTF-8 string conversion, if any */ unsigned int time; DFBWindowID win; }; struct _Ecore_DirectFB_Event_Key_Up /** DirectFB Key Up event */ { - char *name; /**< The name of the key that was released */ - char *string; /**< The logical symbol of the key that was pressed */ - char *key_compose; /**< The UTF-8 string conversion if any */ + char *name; /**< The name of the key that is released */ + char *string; /**< The logical symbol of the key that is pressed */ + char *key_compose; /**< The UTF-8 string conversion, if any */ unsigned int time; DFBWindowID win; }; diff --git a/src/lib/ecore_evas/.gitignore b/src/lib/ecore_evas/.gitignore new file mode 100644 index 0000000..977e708 --- /dev/null +++ b/src/lib/ecore_evas/.gitignore @@ -0,0 +1 @@ +ecore_evas_convert diff --git a/src/lib/ecore_evas/Ecore_Evas.h b/src/lib/ecore_evas/Ecore_Evas.h old mode 100644 new mode 100755 index db42d1d..f32a3aa --- a/src/lib/ecore_evas/Ecore_Evas.h +++ b/src/lib/ecore_evas/Ecore_Evas.h @@ -32,16 +32,9 @@ #endif /* ! _WIN32 */ /** + * @internal * @file Ecore_Evas.h * @brief Evas wrapper functions - * - * The following is a list of example that partially exemplify Ecore_Evas's API: - * @li @ref ecore_evas_callbacks_example_c - * @li @ref ecore_evas_object_example_c - * @li @ref ecore_evas_basics_example_c - * @li @ref Ecore_Evas_Window_Sizes_Example_c - * @li @ref Ecore_Evas_Buffer_Example_01_c - * @li @ref Ecore_Evas_Buffer_Example_02_c */ /* FIXME: @@ -61,12 +54,14 @@ extern "C" { #endif /** + * @internal * @defgroup Ecore_Evas_Group Ecore_Evas wrapper/helper set of functions + * @ingroup Ecore_Group * * Ecore evas is a set of functions that makes it easy to tie together ecore's - * main loop and input handling to evas. As such it's a natural base for EFL + * main loop and input handling to evas. As such it is a natural base for EFL * applications. While this combination makes it easy to create the basic - * aspects all applications need, for normal applications(ones with buttons, + * aspects all applications need, for normal applications (ones with buttons, * checkboxes and layouts) one should consider using Elementary. * * Ecore evas is extremely well suited for applications that are not based on @@ -75,19 +70,11 @@ extern "C" { * in conjunction with Edje or if doing custom drawing as, for example, is done * in games. * - * This is a list of examples of these functions: - * @li @ref ecore_evas_basics_example_c - * @li @ref ecore_evas_object_example_c - * @li @ref ecore_evas_callbacks_example_c - * @li @ref Ecore_Evas_Window_Sizes_Example_c - * @li @ref Ecore_Evas_Buffer_Example_01_c - * @li @ref Ecore_Evas_Buffer_Example_02_c - * * @{ */ -/* these are dummy and just tell u what API levels ecore_evas supports - not if - * the actual support is compiled in. you need to query for that separately. +/* These are dummy and just tells you what API levels ecore_evas supports - not + * the actual support is compiled in. You need to query for that separately. */ #define HAVE_ECORE_EVAS_X 1 #define HAVE_ECORE_EVAS_FB 1 @@ -148,6 +135,7 @@ typedef enum _Ecore_Evas_Object_Associate_Flags #ifndef _ECORE_X_H #define _ECORE_X_WINDOW_PREDEF typedef unsigned int Ecore_X_Window; +typedef unsigned int Ecore_X_Pixmap; #endif #ifndef _ECORE_DIRECTFB_H @@ -168,7 +156,7 @@ typedef struct _Ecore_Cocoa_Window Ecore_Cocoa_Window; #endif #ifndef _ECORE_EVAS_PRIVATE_H -/* basic data types */ +/* Basic data types */ typedef struct _Ecore_Evas Ecore_Evas; typedef void (*Ecore_Evas_Event_Cb) (Ecore_Evas *ee); /**< Callback used for several ecore evas events @since 1.2 */ #endif @@ -183,21 +171,24 @@ typedef struct _Ecore_Wl_Window Ecore_Wl_Window; EAPI int ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine); /** - * @brief Init the Ecore_Evas system. + * @brief Initializes the Ecore_Evas system. * - * @return How many times the lib has been initialized, 0 indicates failure. + * @details This function sets up the Evas wrapper system - initializes Evas and Ecore libraries. * - * Set up the Evas wrapper system. Init Evas and Ecore libraries. + * @return The number of time the lib has been initialized, \n + * otherwise @c 0 on failure * * @see ecore_evas_shutdown() */ EAPI int ecore_evas_init(void); + /** - * @brief Shut down the Ecore_Evas system. + * @brief Shuts down the Ecore_Evas system. * - * @return 0 if ecore evas is fully shut down, or > 0 if it still being used. + * @details This function closes the Evas wrapper system down - shuts down Evas and Ecore libraries. * - * This closes the Evas wrapper system down. Shut down Evas and Ecore libraries. + * @return @c 0 if ecore evas is fully shut down, \n + * otherwise > @c 0 if it still being used * * @see ecore_evas_init() */ @@ -207,490 +198,733 @@ EAPI void ecore_evas_app_comp_sync_set(Eina_Bool do_sync); EAPI Eina_Bool ecore_evas_app_comp_sync_get(void); /** - * @brief Returns a list of supported engines names. + * @brief Gets a list of supported engines names. * - * @return Newly allocated list with engines names. Engines names - * strings are internal and should be considered constants, do not - * free or modify them, to free the list use ecore_evas_engines_free(). + * @return The newly allocated list with engines names \n + * Engines names strings are internal and should be + * considered constants, do not free or modify them, + * to free the list use ecore_evas_engines_free(). */ EAPI Eina_List *ecore_evas_engines_get(void); + /** - * @brief Free list returned by ecore_evas_engines_get() + * @brief Frees the list returned by ecore_evas_engines_get(). * - * @param engines list with engines names + * @param[in] engines The list with engines names */ EAPI void ecore_evas_engines_free(Eina_List *engines); + /** - * @brief Creates a new Ecore_Evas based on engine name and common parameters. - * - * @param engine_name engine name as returned by - * ecore_evas_engines_get() or @c NULL to use environment variable - * ECORE_EVAS_ENGINE, that can be undefined and in this case - * this call will try to find the first working engine. - * @param x horizontal position of window (not supported in all engines) - * @param y vertical position of window (not supported in all engines) - * @param w width of window - * @param h height of window - * @param extra_options string with extra parameter, dependent on engines - * or @ NULL. String is usually in the form: 'key1=value1;key2=value2'. - * Pay attention that when getting that from shell commands, most - * consider ';' as the command terminator, so you need to escape - * it or use quotes. - * - * @return Ecore_Evas instance or @c NULL if creation failed. + * @brief Creates a new Ecore_Evas based on engine name and common parameters. + * + * @param[in] engine_name The engine name as returned by ecore_evas_engines_get(), \n + * otherwise set @c NULL to use environment variable @a ECORE_EVAS_ENGINE \n + * This can be undefined and in this case this call tries + * to find the first working engine. + * @param[in] x The horizontal position of window (not supported in all engines) + * @param[in] y The vertical position of window (not supported in all engines) + * @param[in] w The width of window + * @param[in] h The height of window + * @param[in] extra_options The string with extra parameter, dependent on engines or @ NULL \n + * The string is usually in the form: 'key1=value1;key2=value2'. + * Pay attention that when getting that from shell commands, most + * consider ';' as the command terminator, so you need to escape + * it or use quotes. + * @return The Ecore_Evas instance, \n + * otherwise @c NULL on failure */ EAPI Ecore_Evas *ecore_evas_new(const char *engine_name, int x, int y, int w, int h, const char *extra_options); + /** - * @brief Set whether an Ecore_Evas has an alpha channel or not. + * @brief Sets whether an Ecore_Evas has an alpha channel or not. * - * @param ee The Ecore_Evas to shape - * @param alpha @c EINA_TRUE to enable the alpha channel, @c EINA_FALSE to - * disable it + * @details This function allows you to make an Ecore_Evas translucent using an + * alpha channel. See ecore_evas_shaped_set() for details. The difference + * between a shaped window and a window with an alpha channel is that an + * alpha channel supports multiple levels of transparency, as opposed to + * the @c 1 bit transparency of a shaped window (a pixel is either opaque, or + * it is transparent). * - * This function allows you to make an Ecore_Evas translucent using an - * alpha channel. See ecore_evas_shaped_set() for details. The difference - * between a shaped window and a window with an alpha channel is that an - * alpha channel supports multiple levels of transparency, as opposed to - * the 1 bit transparency of a shaped window (a pixel is either opaque, or - * it's transparent). + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to shape + * @param[in] alpha Set @c EINA_TRUE to enable the alpha channel, \n + * otherwise @c EINA_FALSE to disable it */ EAPI void ecore_evas_alpha_set(Ecore_Evas *ee, Eina_Bool alpha); + /** - * @brief Query whether an Ecore_Evas has an alpha channel. - * @param ee The Ecore_Evas to query. - * @return @c EINA_TRUE if ee has an alpha channel, @c EINA_FALSE if it does - * not. + * @brief Checks whether an Ecore_Evas has an alpha channel. + * + * @remarks This function returns @c EINA_TRUE if @a ee has an alpha channel, and + * @c EINA_FALSE if it does not. * - * This function returns @c EINA_TRUE if @p ee has an alpha channel, and - * @c EINA_FALSE if it does not. + * @param[in] ee The Ecore_Evas to query + * @return @c EINA_TRUE if @a ee has an alpha channel, \n + * otherwise @c EINA_FALSE if it does not * * @see ecore_evas_alpha_set() */ EAPI Eina_Bool ecore_evas_alpha_get(const Ecore_Evas *ee); + /** - * @brief Set whether an Ecore_Evas has an transparent window or not. + * @brief Sets whether an Ecore_Evas has an transparent window or not. * - * @param ee The Ecore_Evas to shape - * @param transparent @c EINA_TRUE to enable the transparent window, - * @c EINA_FALSE to disable it + * @details This function sets some translucency options. * - * This function sets some translucency options, for more complete support see - * ecore_evas_alpha_set(). + * @remarks For more complete support see ecore_evas_alpha_set(). * - * @warning Support for this depends on the underlying windowing system. + * @remarks Support for this depends on the underlying windowing system. + * + * @param[in] ee The Ecore_Evas to shape + * @param[in] transparent @c EINA_TRUE to enable the transparent window, \n + * otherwise @c EINA_FALSE to disable it * * @see ecore_evas_alpha_set() */ EAPI void ecore_evas_transparent_set(Ecore_Evas *ee, Eina_Bool transparent); + /** - * @brief Query whether an Ecore_Evas is transparent. + * @brief Checks whether an Ecore_Evas is transparent. * - * @param ee The Ecore_Evas to query. - * @return @c EINA_TRUE if ee is transparent, @c EINA_FALSE if it isn't. + * @param[in] ee The Ecore_Evas to query + * @return @c EINA_TRUE if ee is transparent, \n + * otherwise @c EINA_FALSE if it is not * * @see ecore_evas_transparent_set() */ EAPI Eina_Bool ecore_evas_transparent_get(const Ecore_Evas *ee); + /** - * @brief Get the geometry of an Ecore_Evas. - * - * @param ee The Ecore_Evas whose geometry y - * @param x A pointer to an int to place the x coordinate in - * @param y A pointer to an int to place the y coordinate in - * @param w A pointer to an int to place the w size in - * @param h A pointer to an int to place the h size in + * @brief Gets the geometry of an Ecore_Evas. * - * This function takes four pointers to (already allocated) ints, and places - * the geometry of @p ee in them. If any of the parameters is not desired you - * may pass @c NULL on them. + * @details This function takes four pointers to (already allocated) int, and places + * the geometry of @a ee in them. If any of the parameters is not desired, you + * may pass @c NULL on them. * * @code * int x, y, w, h; * ecore_evas_geometry_get(ee, &x, &y, &w, &h); * @endcode * + * @param[in] ee The Ecore_Evas whose geometry y + * @param[out] x A pointer to an int to place the x coordinate in + * @param[out] y A pointer to an int to place the y coordinate in + * @param[out] w A pointer to an int to place the w size in + * @param[out] h A pointer to an int to place the h size in + * * @see ecore_evas_new() * @see ecore_evas_resize() * @see ecore_evas_move() * @see ecore_evas_move_resize() */ EAPI void ecore_evas_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); + /** - * @brief Get the geometry which an Ecore_Evas was latest recently requested. - * - * @param ee The Ecore_Evas whose geometry y - * @param x A pointer to an int to place the x coordinate in - * @param y A pointer to an int to place the y coordinate in - * @param w A pointer to an int to place the w size in - * @param h A pointer to an int to place the h size in + * @brief Gets the geometry recently requested by an Ecore_Evas. * - * This function takes four pointers to (already allocated) ints, and places - * the geometry which @p ee was latest recently requested . If any of the - * parameters is not desired you may pass @c NULL on them. - * This function can represent recently requested geometry. - * ecore_evas_geometry_get function returns the value is updated after engine - * finished request. By comparison, ecore_evas_request_geometry_get returns - * recently requested value. + * @details This function takes four pointers to (already allocated) ints, and places + * the geometry which @a ee recently requested. If any of the + * parameters is not desired, you may pass @c NULL on them. + * This function can represent the recently requested geometry. + * The ecore_evas_geometry_get function returns the value that is updated after engine + * finished the request. By comparison, ecore_evas_request_geometry_get returns + * the recently requested value. + * @since 1.1 * * @code * int x, y, w, h; * ecore_evas_request_geometry_get(ee, &x, &y, &w, &h); * @endcode * - * @since 1.1 + * @param[in] ee The Ecore_Evas whose geometry y + * @param[out] x A pointer to an int to place the x coordinate in + * @param[out] y A pointer to an int to place the y coordinate in + * @param[out] w A pointer to an int to place the w size in + * @param[out] h A pointer to an int to place the h size in */ EAPI void ecore_evas_request_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); + /** - * @brief Set the focus of an Ecore_Evas' window. + * @brief Sets the focus of an Ecore_Evas' window. * - * @param ee The Ecore_Evas - * @param on @c EINA_TRUE for focus, @c EINA_FALSE to defocus. + * @details This function focuses @a ee if @a on is @c EINA_TRUE, + * or unfocuses @a ee if @a on is @c EINA_FALSE. * - * This function focuses @p ee if @p on is @c EINA_TRUE, or unfocuses @p ee if - * @p on is @c EINA_FALSE. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] on Set @c EINA_TRUE for focus, \n + * otherwise set @c EINA_FALSE to defocus */ EAPI void ecore_evas_focus_set(Ecore_Evas *ee, Eina_Bool on); + /** - * @brief Query whether an Ecore_Evas' window is focused or not. + * @brief Checks whether an Ecore_Evas' window is focused. * - * @param ee The Ecore_Evas to set - * @return @c EINA_TRUE if @p ee if focused, @c EINA_FALSE if not. + * @param[in] ee The Ecore_Evas to check + * @return @c EINA_TRUE if @a ee is focused, \n + * otherwise @c EINA_FALSE if it is not focused. * * @see ecore_evas_focus_set() */ EAPI Eina_Bool ecore_evas_focus_get(const Ecore_Evas *ee); + /** - * @brief Iconify or uniconify an Ecore_Evas' window. + * @brief Iconifies or uniconifies an Ecore_Evas' window. * - * @param ee The Ecore_Evas - * @param on @c EINA_TRUE to iconify, @c EINA_FALSE to uniconify. + * @details This function iconifies @a ee if @a on is @c EINA_TRUE, or uniconifies @a ee + * if @a on is @c EINA_FALSE. * - * This function iconifies @p ee if @p on is @c EINA_TRUE, or uniconifies @p ee - * if @p on is @c EINA_FALSE. + * @remarks Iconify and minimize are synonyms. * - * @note Iconify and minimize are synonyms. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] on Set @c EINA_TRUE to iconify, \n + * otherwise set @c EINA_FALSE to uniconify */ EAPI void ecore_evas_iconified_set(Ecore_Evas *ee, Eina_Bool on); + /** - * @brief Query whether an Ecore_Evas' window is iconified or not. + * @brief Checks whether an Ecore_Evas' window is iconified. * - * @param ee The Ecore_Evas to set - * @return @c EINA_TRUE if @p ee is iconified, @c EINA_FALSE if not. + * @remarks Iconify and minimize are synonyms. * - * @note Iconify and minimize are synonyms. + * @param[in] ee The Ecore_Evas to check + * @return @c EINA_TRUE if @a ee is iconified, \n + * otherwise @c EINA_FALSE if it is not iconified * * @see ecore_evas_iconified_set() */ EAPI Eina_Bool ecore_evas_iconified_get(const Ecore_Evas *ee); + /** - * @brief Set whether an Ecore_Evas' window is borderless or not. + * @brief Sets whether an Ecore_Evas' window is borderless or not. * - * @param ee The Ecore_Evas - * @param on @c EINA_TRUE for borderless, @c EINA_FALSE for bordered. + * @details This function makes @a ee borderless if @a on is @c EINA_TRUE, or bordered + * if @a on is @c EINA_FALSE. * - * This function makes @p ee borderless if @p on is @c EINA_TRUE, or bordered - * if @p on is @c EINA_FALSE. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] on Set @c EINA_TRUE for borderless, \n + * otherwise set @c EINA_FALSE for bordered */ EAPI void ecore_evas_borderless_set(Ecore_Evas *ee, Eina_Bool on); + /** - * @brief Query whether an Ecore_Evas' window is borderless or not. + * @brief Checks whether an Ecore_Evas' window is borderless. * - * @param ee The Ecore_Evas to set - * @return @c EINA_TRUE if @p ee is borderless, @c EINA_FALSE if not. + * @param[in] ee The Ecore_Evas to check + * @return @c EINA_TRUE if @a ee is borderless, \n + * otherwise @c EINA_FALSE if it is not borderless * * @see ecore_evas_borderless_set() */ EAPI Eina_Bool ecore_evas_borderless_get(const Ecore_Evas *ee); + /** - * @brief Set whether or not an Ecore_Evas' window is fullscreen. + * @brief Sets whether or not an Ecore_Evas' window is fullscreen. * - * @param ee The Ecore_Evas - * @param on @c EINA_TRUE fullscreen, @c EINA_FALSE not. + * @details This function causes @a ee to be fullscreen if @a on is @c EINA_TRUE, and + * not to be fullscreen if @a on is @c EINA_FALSE. * - * This function causes @p ee to be fullscreen if @p on is @c EINA_TRUE, or - * not if @p on is @c EINA_FALSE. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] on Set @c EINA_TRUE for fullscreen, \n + * otherwise set @c EINA_FALSE */ EAPI void ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool on); + /** - * @brief Query whether an Ecore_Evas' window is fullscreen or not. + * @brief Checks whether an Ecore_Evas' window is fullscreen. * - * @param ee The Ecore_Evas to set - * @return @c EINA_TRUE if @p ee is fullscreen, @c EINA_FALSE if not. + * @param[in] ee The Ecore_Evas to check + * @return @c EINA_TRUE if @a ee is fullscreen, \n + * otherwise @c EINA_FALSE if it is not fullscreen * * @see ecore_evas_fullscreen_set() */ EAPI Eina_Bool ecore_evas_fullscreen_get(const Ecore_Evas *ee); + /** - * @brief Set another window that this window is a group member of + * @brief Sets another window that this window is a group member of. + * @since 1.2 * - * @param ee The Ecore_Evas - * @param ee_group The other group member + * @remarks If @a ee_group is @c NULL, @a ee is removed from the group, otherwise it is + * added. Note that if you free the @a ee_group canvas before @a ee, then + * getting the group canvas with ecore_evas_window_group_get() returns + * an invalid handle. * - * If @p ee_group is @c NULL, @p ee is removed from the group, otherwise it is - * added. Note that if you free the @p ee_group canvas before @p ee, then - * getting the group canvas with ecore_evas_window_group_get() will return - * an invalid handle. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 + * @param[in] ee The Ecore_Evas + * @param[in] ee_group The other group member */ EAPI void ecore_evas_window_group_set(Ecore_Evas *ee, const Ecore_Evas *ee_group); + /** - * @brief Get the canvas group set. + * @brief Gets the canvas group that is set. + * @details This returns the handle set by ecore_evas_window_group_set(). * - * This returns the handle set by ecore_evas_window_group_set(). + * @since 1.2 * - * @param ee The Ecore_Evas to set - * @return The Canvas group handle + * @param[in] ee The Ecore_Evas + * @return The Canvas group handle * * @see ecore_evas_window_group_set() - * @since 1.2 */ EAPI const Ecore_Evas *ecore_evas_window_group_get(const Ecore_Evas *ee); + /** - * @brief Set the aspect ratio of a canvas window + * @brief Sets the aspect ratio of a canvas window. * - * @param ee The Ecore_Evas - * @param aspect The aspect ratio (width divided by height), or 0 to disable + * @details This function sets the desired aspect ratio of a canvas window. + * @since 1.2 * - * This sets the desired aspect ratio of a canvas window + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 + * @param[in] ee The Ecore_Evas + * @param[in] aspect The aspect ratio (width divided by height), \n + * otherwise set @c 0 to disable */ EAPI void ecore_evas_aspect_set(Ecore_Evas *ee, double aspect); + /** - * @brief Get the aspect ratio of a canvas window + * @brief Gets the aspect ratio of a canvas window. * - * This returns the value set by ecore_evas_aspect_set(). + * @details This function returns the value set by ecore_evas_aspect_set(). + * @since 1.2 * - * @param ee The Ecore_Evas to set - * @return The aspect ratio + * @param[in] ee The Ecore_Evas to set + * @return The aspect ratio * * @see ecore_evas_aspect_set() - * @since 1.2 */ EAPI double ecore_evas_aspect_get(const Ecore_Evas *ee); + /** - * @brief Set The urgent hint flag + * @brief Sets the urgent hint flag. * - * @param ee The Ecore_Evas - * @param urgent The urgent state flag + * @details This function sets the "urgent" state hint on a window so that the desktop environment + * can highlight it somehow. + * @since 1.2 * - * This sets the "urgent" state hint on a window so the desktop environment - * can highlight it somehow. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 + * @param[in] ee The Ecore_Evas + * @param[in] urgent Set @c EINA_TRUE to set the urgent state flag, \n + * otherwise set @c EINA_FALSE to not set it */ EAPI void ecore_evas_urgent_set(Ecore_Evas *ee, Eina_Bool urgent); + /** - * @brief Get the urgent state on the cavas window + * @brief Gets the urgent state on the canvas window. * - * This returns the value set by ecore_evas_urgent_set() + * @details This returns the value set by ecore_evas_urgent_set(). + * @since 1.2 * - * @param ee The Ecore_Evas to set - * @return The urgent state set + * @param[in] ee The Ecore_Evas to set + * @return @c EINA_TRUE if the urgent state is set, \n + * otherwise @c EINA_FALSE if it is not set * * @see ecore_evas_urgent_set() - * @since 1.2 */ EAPI Eina_Bool ecore_evas_urgent_get(const Ecore_Evas *ee); + /** - * @brief Set the modal state flag on the canvas window + * @brief Sets the modal state flag on the canvas window. * - * @param ee The Ecore_Evas - * @param modal The modal hint flag + * @details This function hints if the window should be modal (for example, if it is also transient + * for another window, the other window maybe be denied focus by + * the desktop window manager). + * @since 1.2 * - * This hints if the window should be modal (eg if it is also transient - * for another window, the other window will maybe be denied focus by - * the desktop window manager). + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 + * @param[in] ee The Ecore_Evas + * @param[in] modal Set @c EINA_TRUE to set the window as modal, \n + * otherwise set @c EINA_FALSE to set the window as not modal */ EAPI void ecore_evas_modal_set(Ecore_Evas *ee, Eina_Bool modal); + /** - * @brief Get The modal flag + * @brief Checks whether the modal flag is set. * - * This returns the value set by ecore_evas_modal_set(). + * @details This returns the value set by ecore_evas_modal_set(). + * @since 1.2 * - * @param ee The Ecore_Evas to set - * @return The modal flag + * @param[in] ee The Ecore_Evas + * @return @c EINA_TRUE if the window is modal, \n + * otherwise @c EINA_FALSE if the window is not modal * * @see ecore_evas_modal_set() - * @since 1.2 */ EAPI Eina_Bool ecore_evas_modal_get(const Ecore_Evas *ee); + /** - * @brief Set the "i demand attention" flag on a canvas window + * @brief Sets the "i demand attention" flag on a canvas window. + * @since 1.2 * - * @param ee The Ecore_Evas - * @param demand The flag state to set + * @remarks A window may demand attention (for example, you must enter a password before + * continuing), and so you may flag a window with this function. * - * A window may demand attention now (eg you must enter a password before - * continuing), and so it may flag a window with this. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 + * @param[in] ee The Ecore_Evas + * @param[in] demand Set @c EINA_TRUE to set the flag, \n + * otherwise set @c EINA_FALSE to not set the flag */ EAPI void ecore_evas_demand_attention_set(Ecore_Evas *ee, Eina_Bool demand); + /** - * @brief Get the "i demand attention" flag + * @brief Checks whether the "i demand attention" flag is set. * - * This returns the value set by ecore_evas_demand_attention_set(). + * @details This function returns the value set by ecore_evas_demand_attention_set(). + * @since 1.2 * - * @param ee The Ecore_Evas to set - * @return The "i demand attention" flag. + * @param[in] ee The Ecore_Evas + * @return @c EINA_TRUE if the "i demand attention" flag is set, \n + * otherwise @c EINA_FALSE if the flag is not set * * @see ecore_evas_demand_attention_set() - * @since 1.2 */ EAPI Eina_Bool ecore_evas_demand_attention_get(const Ecore_Evas *ee); + /** - * @brief Set the "focus skip" flag + * @brief Sets the "focus skip" flag. + * @since 1.2 * - * @param ee The Ecore_Evas - * @param skip The "focus skip" state to set. + * @remarks A window may not want to accept focus, be in the taskbar or pager + * sometimes (example for a small notification window that hovers around + * a taskbar or panel, or hovers around a window until some activity + * dismisses it). * - * A window may not want to accept focus, be in the taskbar, pager etc. - * sometimes (example for a small notification window that hovers around - * a taskbar or panel, or hovers around a window until some activity - * dismisses it). + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 + * @param[in] ee The Ecore_Evas + * @param[in] skip Set @c EINA_TRUE to set the "focus skip", \n + * otherwise @c EINA_FALSE to not set the flag */ EAPI void ecore_evas_focus_skip_set(Ecore_Evas *ee, Eina_Bool skip); + /** - * @brief Get the "focus skip" flag + * @brief Checks whether the "focus skip" flag is set. * - * This returns the value set by ecore_evas_focus_skip_set(). + * @details This returns the value set by ecore_evas_focus_skip_set(). + * @since 1.2 * - * @param ee The Ecore_Evas to set - * @return The "focus skip" flag. + * @param[in] ee The Ecore_Evas to set + * @return @c EINA_TRUE if the "focus skip" flag is set, \n + * otherwise @c EINA_FALSE if the flag is not set * * @see ecore_evas_focus_skip_set() - * @since 1.2 */ EAPI Eina_Bool ecore_evas_focus_skip_get(const Ecore_Evas *ee); /** - * @brief Set if this evas should ignore @b all events. + * @brief Sets whether this evas should ignore @b all events. * - * @param ee The Ecore_Evas whose window's to ignore events. - * @param ignore The Ecore_Evas new ignore state. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] ignore Set @c EINA_TRUE for Ecore_Evas to ignore events, \n + * otherwise @c EINA_FALSE to not ignore the events */ EAPI void ecore_evas_ignore_events_set(Ecore_Evas *ee, Eina_Bool ignore); + /** - * @brief Returns the ignore state of an Ecore_Evas' window. + * @brief Checks whether the ignore state of the Ecore_Evas window is set. * - * @param ee The Ecore_Evas whose window's ignore events state is returned. - * @return The Ecore_Evas window's ignore state. + * @param[in] ee The Ecore_Evas + * @return @c EINA_TRUE if ignore state is set, \n + * otherwise @c EINA_FALSE if the ignore state is not set * * @see ecore_evas_ignore_events_set() */ EAPI Eina_Bool ecore_evas_ignore_events_get(const Ecore_Evas *ee); + /** - * @brief Query whether an Ecore_Evas' window is visible or not. + * @brief Checks whether an Ecore_Evas window is visible. * - * @param ee The Ecore_Evas to query. - * @return 1 if visible, 0 if not. + * @details This function queries @a ee and returns @c 1 if it is visible, + * and @c 0 if it is not visible. * - * This function queries @p ee and returns 1 if it is visible, and 0 if not. + * @param[in] ee The Ecore_Evas to query + * @return @c 1 if the window visible, \n + * otherwise @c 0 if it is not visible * * @see ecore_evas_show() * @see ecore_evas_hide() */ EAPI int ecore_evas_visibility_get(const Ecore_Evas *ee); + /** - * @brief Set the layer of an Ecore_Evas' window. + * @brief Sets the layer of an Ecore_Evas window. * - * @param ee The Ecore_Evas - * @param layer The layer to put @p ee on. + * @details This function moves @a ee to the layer @a layer. * - * This function moves @p ee to the layer @p layer. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] layer The layer to put @a ee on * * @see ecore_evas_lower() * @see ecore_evas_raise() */ EAPI void ecore_evas_layer_set(Ecore_Evas *ee, int layer); + /** - * @brief Get the layer of an Ecore_Evas' window. + * @brief Gets the layer of an Ecore_Evas window. * - * @param ee The Ecore_Evas to set - * @return the layer @p ee's window is on. + * @param[in] ee The Ecore_Evas to set + * @return The layer @a ee's window is on * * @see ecore_evas_layer_set() * @see ecore_evas_lower() * @see ecore_evas_raise() */ EAPI int ecore_evas_layer_get(const Ecore_Evas *ee); + /** - * @brief Maximize (or unmaximize) an Ecore_Evas' window. + * @brief Maximizes (or unmaximizes) an Ecore_Evas window. * - * @param ee The Ecore_Evas - * @param on @c EINA_TRUE to maximize, @c EINA_FALSE to unmaximize. + * @details This function maximizes @a ee if @a on is @c EINA_TRUE, + * or unmaximizes @a ee if @a on is @c EINA_FALSE. * - * This function maximizes @p ee if @p on is @c EINA_TRUE, or unmaximizes @p ee - * if @p on is @c EINA_FALSE. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] on Set @c EINA_TRUE to maximize, \n + * otherwise set @c EINA_FALSE to unmaximize */ EAPI void ecore_evas_maximized_set(Ecore_Evas *ee, Eina_Bool on); + /** - * @brief Query whether an Ecore_Evas' window is maximized or not. + * @brief Checks whether an Ecore_Evas window is maximized. * - * @param ee The Ecore_Evas to set - * @return @c EINA_TRUE if @p ee is maximized, @c EINA_FALSE if not. + * @param[in] ee The Ecore_Evas to set + * @return @c EINA_TRUE if @a ee is maximized, \n + * otherwise @c EINA_FALSE if is not maximized * * @see ecore_evas_maximized_set() */ EAPI Eina_Bool ecore_evas_maximized_get(const Ecore_Evas *ee); + /** - * @brief Set Ecore_Evas's window profile list. + * @brief Sets the Ecore_Evas window profile list. + * @since 1.7.0 * - * @param ee The Ecore_Evas - * @param profiles The profile name list - * @param num_profiles The number of profile names + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. - * @since 1.7.0 + * @param[in] ee The Ecore_Evas + * @param[in] profiles The profile name list + * @param[in] num_profiles The number of profile names */ EAPI void ecore_evas_profiles_set(Ecore_Evas *ee, const char **profiles, unsigned int num_profiles); + /** - * @brief Get Ecore_Evas's window profile name. - * - * @param ee The Ecore_Evas - * @return The profile name + * @brief Gets the Ecore_Evas window profile name. + * @since 1.7.0 * - * @since 1.7.0 + * @param[in] ee The Ecore_Evas + * @return The profile name */ EAPI const char *ecore_evas_profile_get(const Ecore_Evas *ee); + +EAPI Eina_Bool ecore_evas_wm_rotation_supported_get(const Ecore_Evas *ee); +EAPI void ecore_evas_wm_rotation_preferred_rotation_set(Ecore_Evas *ee, int rotation); +EAPI int ecore_evas_wm_rotation_preferred_rotation_get(const Ecore_Evas *ee); +EAPI void ecore_evas_wm_rotation_available_rotations_set(Ecore_Evas *ee, const int *rotations, unsigned int count); +EAPI Eina_Bool ecore_evas_wm_rotation_available_rotations_get(const Ecore_Evas *ee, int **rotations, unsigned int *count); + /** - * @brief Move an Ecore_Evas. + * @brief Sets manual rotation done mode for Ecore_Evas window. + * @since 1.8.0 * - * @param ee The Ecore_Evas to move - * @param x The x coordinate to move to - * @param y The y coordinate to move to + * @param[in] ee The Ecore_Evas + * @param[in] set Set @c EINA_TRUE if the window manager should not rotate the Ecore_Evas's window until + * the rotation done event is received by ecore_evas_wm_rotation_manual_rotation_done, \n + * otherwise set @c EINA_FALSE if the manual rotation mode should be disabled * - * This moves @p ee to the screen coordinates (@p x, @p y) + */ +EAPI void ecore_evas_wm_rotation_manual_rotation_done_set(Ecore_Evas *ee, Eina_Bool set); +/** + * @brief Gets manual rotation done mode of Ecore_Evas's window. + * @since 1.8.0 * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @return @c EINA_TRUE if the manual rotation done mode is enabled, \n + * otherwise @c EINA_FALSE if it is not enabled + */ +EAPI Eina_Bool ecore_evas_wm_rotation_manual_rotation_done_get(const Ecore_Evas *ee); +/** + * @brief Sets the rotation finish manually. + * @since 1.8.0 + * + * @param[in] ee The Ecore_Evas + * + */ +EAPI void ecore_evas_wm_rotation_manual_rotation_done(Ecore_Evas *ee); + +/** + * @brief Gets the list of supported auxiliary hint strings. + * @since 1.8.0 + * + * @remarks Do not change the returned list of its contents. Auxiliary hint + * strings are internal and should be considered constants, do not free or + * modify them. + * @remarks Support for this depends on the underlying windowing system. + * + * @remarks The window auxiliary hint is the value which is used to decide which actions should + * be made available to the user by the window manager. If you want to set specific hint + * to your window, then you should check whether it exists in the supported auxiliary + * hints that are registered in the root window by the window manager. Once you have added + * an auxiliary hint, you can get a new ID which is used to change value and delete hint. + * The window manager sends the response message to the application on receiving auxiliary + * hint change event. A list of auxiliary hint within the Ecore_Evas has this format: + * ID:HINT:VALUE,ID:HINT:VALUE,... + * + * @param[in] ee The Ecore_Evas + * @return The list of supported auxiliary hint strings + */ +EAPI const Eina_List *ecore_evas_aux_hints_supported_get(const Ecore_Evas *ee); + +/** + * @brief Gets the list of allowed auxiliary hint ID. + * + * @since 1.8.0 + * + * @remarks This function is low level. Instead of using it directly, consider + * using the callback mechanism in Elementary such as "aux,hint,allowed". + * @remarks Support for this depends on the underlying windowing system. + * + * @param[in] ee The Ecore_Evas + * @return The list of allowed auxiliary hint ID + */ +EAPI Eina_List *ecore_evas_aux_hints_allowed_get(const Ecore_Evas *ee); + +/** + * @brief Creates an auxiliary hint of the Ecore_Evas. + * + * @since 1.8.0 + * + * @remarks Support for this depends on the underlying windowing system. + * + * @param[in] ee The Ecore_Evas + * @param[in] hint The auxiliary hint string + * @param[in] val The value string + * @return The ID of created auxiliary hint, \n + * otherwise @c -1 on failure + */ +EAPI int ecore_evas_aux_hint_add(Ecore_Evas *ee, const char *hint, const char *val); + +/** + * @brief Deletes an auxiliary hint of the Ecore_Evas. + * + * @since 1.8.0 + * + * @remarks Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] id The ID of the auxiliary hint. + * @return @c EINA_TRUE if the hint is deleted successfully, \n + * otherwise @c EINA_FALSE in case of errors + */ +EAPI Eina_Bool ecore_evas_aux_hint_del(Ecore_Evas *ee, const int id); + +/** + * @brief Changes a value of the auxiliary hint. + * + * @since 1.8.0 + * + * @remarks Support for this depends on the underlying windowing system. + * + * @param[in] ee The Ecore_Evas + * @param[in] id The auxiliary hint ID + * @param[in] val The value string to be set + * @return @c EINA_TRUE if the value is changed successfully, \n + * otherwise @c EINA_FALSE in case of errors + */ +EAPI Eina_Bool ecore_evas_aux_hint_val_set(Ecore_Evas *ee, const int id, const char *val); + +/** + * @brief Sends message to parent ecore. + * @since 1.8.0 + * + * @remarks Support for this depends on the underlying windowing system. + * + * @param[in] ee The Ecore_Evas to set + * @param[in] msg_domain The domain of message + * @param[in] msg_id The ID of message + * @param[in] data The data of message + * @param[in] size The size of message data + * + * @see ecore_evas_msg_send() + * @see ecore_evas_callback_msg_parent_handle_set() + * @see eecore_evas_callback_msg_handle_set() + */ +EAPI void ecore_evas_msg_parent_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size); + +/** + * @brief Sends message to child ecore. + * @since 1.8.0 + * + * @remarks Support for this depends on the underlying windowing system. + * + * @param[in] ee The Ecore_Evas to set + * @param[in] msg_domain The domain of message + * @param[in] msg_id The ID of message + * @param[in] data The data of message + * @param[in] size The size of message data + * + * @see ecore_evas_msg_parent_send() + * @see ecore_evas_callback_msg_parent_handle_set() + * @see eecore_evas_callback_msg_handle_set() + */ +EAPI void ecore_evas_msg_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size); + +/** + * @brief Sets a callback for parent Ecore_Evas message. + * @since 1.8.0 + * + * @remarks Support for this depends on the underlying windowing system. + * + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func_parent_handle The handle to be called when message arrives + * + * @see ecore_evas_msg_parent_send() + * @see ecore_evas_msg_send() + * @see eecore_evas_callback_msg_handle_set() + */ +EAPI void ecore_evas_callback_msg_parent_handle_set(Ecore_Evas *ee, void (*func_parent_handle)(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)); + +/** + * @brief Sets a callback for child Ecore_Evas message. + * @since 1.8.0 + * + * @remarks Support for this depends on the underlying windowing system. + * + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func_handle The handle to be called when message arrives + * + * @see ecore_evas_msg_parent_send() + * @see ecore_evas_msg_send() + * @see ecore_evas_callback_msg_parent_handle_set() + */ +EAPI void ecore_evas_callback_msg_handle_set(Ecore_Evas *ee, void (*func_handle)(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)); + +/** + * @brief Moves an Ecore_Evas. + * + * @details This function moves @a ee to the screen coordinates (@a x, @a y). + * + * @remarks Support for this depends on the underlying windowing system. + * + * @param[in] ee The Ecore_Evas to move + * @param[in] x The x coordinate to move to + * @param[in] y The y coordinate to move to * * @see ecore_evas_new() * @see ecore_evas_resize() @@ -698,174 +932,228 @@ EAPI const char *ecore_evas_profile_get(const Ecore_Evas *ee); */ EAPI void ecore_evas_move(Ecore_Evas *ee, int x, int y); /** - * @brief Resize an Ecore_Evas. + * @brief Resizes an Ecore_Evas. * - * @param ee The Ecore_Evas to move - * @param w The w coordinate to resize to - * @param h The h coordinate to resize to + * @details This function resizes @a ee to @a w x @a h. * - * This resizes @p ee to @p w x @p h. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to move + * @param[in] w The w coordinate to resize to + * @param[in] h The h coordinate to resize to * * @see ecore_evas_new() * @see ecore_evas_move() * @see ecore_evas_move_resize() */ EAPI void ecore_evas_resize(Ecore_Evas *ee, int w, int h); + /** - * @brief Move and resize an Ecore_Evas + * @brief Moves and resizes an Ecore_Evas. * - * @param ee The Ecore_Evas to move and resize - * @param x The x coordinate to move to - * @param y The y coordinate to move to - * @param w The w coordinate to resize to - * @param h The h coordinate to resize to + * @details This moves @a ee to the screen coordinates (@a x, @a y) and resizes + * it to @a w x @a h. * - * This moves @p ee to the screen coordinates (@p x, @p y) and resizes - * it to @p w x @p h. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to move and resize + * @param[in] x The x coordinate to move to + * @param[in] y The y coordinate to move to + * @param[in] w The w coordinate to resize to + * @param[in] h The h coordinate to resize to * * @see ecore_evas_new() * @see ecore_evas_move() * @see ecore_evas_resize() */ EAPI void ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h); + /** - * @brief Set the rotation of an Ecore_Evas' window. + * @brief Sets the rotation of an Ecore_Evas window. * - * @param ee The Ecore_Evas - * @param rot the angle (in degrees) of rotation. + * @remarks The allowed values of @a rot depend on the engine being used. Most only + * allow multiples of @c 90. * - * The allowed values of @p rot depend on the engine being used. Most only - * allow multiples of 90. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] rot The angle (in degrees) of rotation * * @see ecore_evas_rotation_with_resize_set() */ EAPI void ecore_evas_rotation_set(Ecore_Evas *ee, int rot); + /** - * @brief Set the rotation of an Ecore_Evas' window + * @brief Sets the rotation of an Ecore_Evas window. * - * @param ee The Ecore_Evas - * @param rot the angle (in degrees) of rotation. + * @remarks Like ecore_evas_rotation_set(), but it also resizes the window's contents so + * that they fit inside the current window geometry. * - * Like ecore_evas_rotation_set(), but it also resizes the window's contents so - * that they fit inside the current window geometry. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] rot The angle (in degrees) of rotation * * @see ecore_evas_rotation_set() */ EAPI void ecore_evas_rotation_with_resize_set(Ecore_Evas *ee, int rot); + /** - * @brief Get the rotation of an Ecore_Evas' window + * @brief Gets the rotation of an Ecore_Evas window. * - * @param ee The Ecore_Evas - * @return the angle (in degrees) of rotation. + * @param[in] ee The Ecore_Evas + * @return The angle (in degrees) of rotation * * @see ecore_evas_rotation_set() * @see ecore_evas_rotation_with_resize_set() */ EAPI int ecore_evas_rotation_get(const Ecore_Evas *ee); + /** - * @brief Raise an Ecore_Evas' window. + * @brief Raises an Ecore_Evas window. * - * @param ee The Ecore_Evas to raise. + * @details This functions raises the Ecore_Evas to the front. * - * This functions raises the Ecore_Evas to the front. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to raise * * @see ecore_evas_lower() * @see ecore_evas_layer_set() */ EAPI void ecore_evas_raise(Ecore_Evas *ee); + /** - * @brief Lower an Ecore_Evas' window. + * @brief Lowers an Ecore_Evas window. * - * @param ee The Ecore_Evas to raise. + * @details This functions lowers the Ecore_Evas to the back. * - * This functions lowers the Ecore_Evas to the back. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to raise * * @see ecore_evas_raise() * @see ecore_evas_layer_set() */ EAPI void ecore_evas_lower(Ecore_Evas *ee); + /** - * @brief Set the title of an Ecore_Evas' window. + * @brief Sets the title of an Ecore_Evas window. * - * @param ee The Ecore_Evas whose title you wish to set. - * @param t The title + * @details This function sets the title of @a ee to @a t. * - * This function sets the title of @p ee to @p t. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas whose title you wish to set + * @param[in] t The title */ EAPI void ecore_evas_title_set(Ecore_Evas *ee, const char *t); + /** - * @brief Get the title of an Ecore_Evas' window. + * @brief Gets the title of an Ecore_Evas window. * - * @param ee The Ecore_Evas whose title you wish to get. - * @return The title of @p ee. + * @details This function returns the title of @a ee. * - * This function returns the title of @p ee. + * @param[in] ee The Ecore_Evas whose title you wish to get + * @return The title of @a ee * * @see ecore_evas_title_set() */ EAPI const char *ecore_evas_title_get(const Ecore_Evas *ee); + /** - * @brief Set the name and class of an Ecore_Evas' window. + * @brief Sets the name and class of an Ecore_Evas window. * - * @param ee the Ecore_Evas - * @param n the name - * @param c the class + * @details This function sets the name of @a ee to @a n, and its class to @a c. The + * meaning of @a name and @a class depends on the underlying windowing system. * - * This function sets the name of @p ee to @p n, and its class to @p c. The - * meaning of @p name and @p class depends on the underlying windowing system. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @param[in] n The name + * @param[in] c The class */ EAPI void ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c); + /** - * @brief Get the name and class of an Ecore_Evas' window + * @brief Gets the name and class of an Ecore_Evas window. * - * This function gets the name of @p ee into @p n, and its class into - * @p c. + * @details This function gets the name of @a ee into @a n, and its class into @a c. * - * @param ee The Ecore_Evas to query. - * @param n A pointer to a string to place the name in. - * @param c A pointer to a string to place the class in. + * @param[in] ee The Ecore_Evas to query + * @param[out] n A pointer to a string to place the name in + * @param[out] c A pointer to a string to place the class in * @see ecore_evas_name_class_set() */ EAPI void ecore_evas_name_class_get(const Ecore_Evas *ee, const char **n, const char **c); + /** - * @brief Returns a pointer to the underlying window. + * @brief Gets a pointer to the underlying window. * - * @param ee The Ecore_Evas whose window is desired. - * @return A pointer to the underlying window. + * @remarks Support for this depends on the underlying windowing system. * - * @warning Support for this depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas + * @return A pointer to the underlying window */ EAPI Ecore_Window ecore_evas_window_get(const Ecore_Evas *ee); -/* engine/target specific init calls */ +/* Engine/target specific init calls */ EAPI Ecore_Evas *ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h); EAPI Ecore_X_Window ecore_evas_software_x11_window_get(const Ecore_Evas *ee); EAPI void ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on); EAPI Eina_Bool ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee); EAPI void ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win); -#define ECORE_EVAS_GL_X11_OPT_NONE 0 -#define ECORE_EVAS_GL_X11_OPT_INDIRECT 1 -#define ECORE_EVAS_GL_X11_OPT_VSYNC 2 -#define ECORE_EVAS_GL_X11_OPT_LAST 3 +/** + * @brief Create a new Ecore_Evas which does not contain an XWindow. It will + * only contain an XPixmap to render to + * + * @warning The XPixmap ID can change with every frame after it is rendered, + * so you should ALWAYS call ecore_evas_software_x11_pixmap_get when you + * need the current pixmap id. + * + * @since 1.8 + */ +EAPI Ecore_Evas *ecore_evas_software_x11_pixmap_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h); +/** + * @brief Returns the underlying Ecore_X_Pixmap used in the Ecore_Evas + * + * @param[in] disp_name Display name. + * @param[in] parent X11 parent window. + * @param[in] x X cooridnate. + * @param[in] y Y coordinate. + * @param[in] w Width. + * @param[in] h Height. + * @return The underlying Ecore_X_Pixmap + * + * @warning Support for this depends on the underlying windowing system. + * + * @warning The XPixmap ID can change with every frame after it is rendered, + * so you should ALWAYS call ecore_evas_software_x11_pixmap_get when you + * need the current pixmap id. + * + * @since 1.8 + */ +EAPI Ecore_Evas * ecore_evas_software_x11_pixmap_new_internal(const char *disp_name, Ecore_X_Window parent,int x, int y, int w, int h); +EAPI Ecore_X_Pixmap ecore_evas_software_x11_pixmap_get(const Ecore_Evas *ee); + +#define ECORE_EVAS_GL_X11_OPT_NONE 0 +#define ECORE_EVAS_GL_X11_OPT_INDIRECT 1 +#define ECORE_EVAS_GL_X11_OPT_VSYNC 2 +#define ECORE_EVAS_GL_X11_OPT_SWAP_MODE 3 +#define ECORE_EVAS_GL_X11_OPT_GL_DEPTH 4 +#define ECORE_EVAS_GL_X11_OPT_GL_STENCIL 5 +#define ECORE_EVAS_GL_X11_OPT_GL_MSAA 6 +#define ECORE_EVAS_GL_X11_OPT_LAST 7 + +#define ECORE_EVAS_GL_X11_SWAP_MODE_AUTO 0 +#define ECORE_EVAS_GL_X11_SWAP_MODE_FULL 1 +#define ECORE_EVAS_GL_X11_SWAP_MODE_COPY 2 +#define ECORE_EVAS_GL_X11_SWAP_MODE_DOUBLE 3 +#define ECORE_EVAS_GL_X11_SWAP_MODE_TRIPLE 4 + EAPI Ecore_Evas *ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h); EAPI Ecore_Evas *ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h, const int *opt); EAPI Ecore_X_Window ecore_evas_gl_x11_window_get(const Ecore_Evas *ee); @@ -874,6 +1162,48 @@ EAPI Eina_Bool ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee); EAPI void ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win); EAPI void ecore_evas_gl_x11_pre_post_swap_callback_set(const Ecore_Evas *ee, void *data, void (*pre_cb) (void *data, Evas *e), void (*post_cb) (void *data, Evas *e)); +/** + * @brief Create a new Ecore_Evas which does not contain an XWindow. It will + * only contain an XPixmap to render to + * + * @since 1.8 + * + * @warning The XPixmap ID can change with every frame after it is rendered, + * so you should ALWAYS call ecore_evas_software_x11_pixmap_get when you + * need the current pixmap id. + * + * @param[in] disp_name Display name. + * @param[in] parent X11 parent window. + * @param[in] x X cooridnate. + * @param[in] y Y coordinate. + * @param[in] w Width. + * @param[in] h Height. + * @return The underlying Ecore_X_Pixmap + */ +EAPI Ecore_Evas *ecore_evas_gl_x11_pixmap_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h); + +/** + * @brief Returns the underlying Ecore_X_Pixmap used in the Ecore_Evas + * + * @param[in] disp_name Display name. + * @param[in] parent X11 parent window. + * @param[in] x X cooridnate. + * @param[in] y Y coordinate. + * @param[in] w Width. + * @param[in] h Height. + * @return The underlying Ecore_X_Pixmap + * + * @warning Support for this depends on the underlying windowing system. + * + * @warning The XPixmap ID can change with every frame after it is rendered, + * so you should ALWAYS call ecore_evas_software_x11_pixmap_get when you + * need the current pixmap id. + * + * @since 1.8 + */ +EAPI Ecore_Evas * ecore_evas_gl_x11_pixmap_new_internal(const char *disp_name, Ecore_X_Window parent,int x, int y, int w, int h); +EAPI Ecore_X_Pixmap ecore_evas_gl_x11_pixmap_get(const Ecore_Evas *ee); + EAPI Ecore_Evas *ecore_evas_xrender_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h); EAPI Ecore_X_Window ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee); EAPI void ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on); @@ -904,203 +1234,199 @@ EAPI Ecore_Evas *ecore_evas_wayland_egl_new(const char *disp_name, unsigned EAPI void ecore_evas_wayland_resize(Ecore_Evas *ee, int location); EAPI void ecore_evas_wayland_move(Ecore_Evas *ee, int x, int y); -/* EAPI void ecore_evas_wayland_drag_start(Ecore_Evas *ee, Ecore_Evas *drag_ee, void *source); */ EAPI void ecore_evas_wayland_pointer_set(Ecore_Evas *ee, int hot_x, int hot_y); EAPI void ecore_evas_wayland_type_set(Ecore_Evas *ee, int type); EAPI Ecore_Wl_Window *ecore_evas_wayland_window_get(const Ecore_Evas *ee); /** - * @brief Create a new @c Ecore_Evas canvas bound to the Evas - * @b buffer engine + * @brief Creates a new @c Ecore_Evas canvas bound to the Evas @b buffer engine. * - * @param w The width of the canvas, in pixels - * @param h The height of the canvas, in pixels - * @return A new @c Ecore_Evas instance or @c NULL, on failure + * @details This function creates a new buffer canvas wrapper, with image data array + * @b bound to the ARGB format, 8 bits per pixel. * - * This creates a new buffer canvas wrapper, with image data array - * @b bound to the ARGB format, 8 bits per pixel. + * @remarks This function allocates the needed pixels array with canonical + * @c malloc(). If you wish a custom function to allocate it, consider + * using ecore_evas_buffer_allocfunc_new(), instead. * - * This function will allocate the needed pixels array with canonical - * @c malloc(). If you wish a custom function to allocate it, consider - * using ecore_evas_buffer_allocfunc_new(), instead. + * @remarks This function actually is a wrapper on + * ecore_evas_buffer_allocfunc_new(), using the same @a w and @a h + * arguments and canonical @c malloc() and @c free() to the memory + * allocation and freeing functions. See the function's documentation + * for more details. * - * @note This function actually is a wrapper on - * ecore_evas_buffer_allocfunc_new(), using the same @a w and @a h - * arguments and canonical @c malloc() and @c free() to the memory - * allocation and freeing functions. See that function's documentation - * for more details. + * @param[in] w The width of the canvas, in pixels + * @param[in] h The height of the canvas, in pixels + * @return A new @c Ecore_Evas instance, \n + * otherwise @c NULL on failure */ EAPI Ecore_Evas *ecore_evas_buffer_new(int w, int h); /** - * @brief Create a new @c Ecore_Evas canvas bound to the Evas - * @b buffer engine, giving custom allocation and freeing functions for - * the canvas memory region + * @brief Creates a new @c Ecore_Evas canvas bound to the Evas + * @b buffer engine, giving custom allocation and freeing functions for + * the canvas memory region. * - * @param w The width of the canvas, in canvas units - * @param h The height of the canvas, in canvas units - * @param alloc_func Function to be called to allocate the memory - * needed for the new buffer canvas. @a data will be passed the same - * value as the @p data of this function, while @a size will be passed - * @p w times @p h times @c sizeof(int). - * @param free_func Function to be called to free the memory used by - * the new buffer canvas. @a data will be passed the same value as the - * @p data of this function, while @a pix will be passed the canvas - * memory pointer. - * @param data Custom data to be passed to the allocation and freeing - * functions - * @return A new @c Ecore_Evas instance or @c NULL, on failure + * @details This function creates a new buffer canvas wrapper, with image data array + * @b bound to the ARGB format, 8 bits per pixel. * - * This creates a new buffer canvas wrapper, with image data array - * @b bound to the ARGB format, 8 bits per pixel. + * @remarks This function is useful when one wants an @c Ecore_Evas buffer + * canvas with a custom allocation function, like one getting memory + * chunks from a memory pool, for example. * - * This function is useful when one wants an @c Ecore_Evas buffer - * canvas with a custom allocation function, like one getting memory - * chunks from a memory pool, for example. + * @remarks On any resizing of this @c Ecore_Evas buffer canvas, its image data + * is @b freed, to be allocated again with the new size. * - * On any resizing of this @c Ecore_Evas buffer canvas, its image data - * will be @b freed, to be allocated again with the new size. + * @remarks @a w and @a h sizes have to greater or equal to @c 1. Otherwise, + * they are interpreted as @c 1, exactly. * - * @note @p w and @p h sizes have to greater or equal to 1. Otherwise, - * they'll be interpreted as 1, exactly. + * @param[in] w The width of the canvas, in canvas units + * @param[in] h The height of the canvas, in canvas units + * @param[in] alloc_func The function to be called to allocate the memory + * needed for the new buffer canvas \n + * @a data is passed the same value as the @a data of this function, + * while @a size is passed @a w times @a h times @c sizeof(int). + * @param[in] free_func The function to be called to free the memory used by + * the new buffer canvas \n + * @a data is passed the same value as the @a data of this function, + * while @a pix is passed the canvas memory pointer. + * @param[in] data The custom data to be passed to the allocation and freeing functions + * @return A new @c Ecore_Evas instance, \n + * otherwise @c NULL on failure * * @see ecore_evas_buffer_new() */ EAPI Ecore_Evas *ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, int size), void (*free_func) (void *data, void *pix), const void *data); /** - * @brief Grab a pointer to the actual pixels array of a given - * @c Ecore_Evas @b buffer canvas/window. + * @brief Grabs a pointer to the actual pixels array of a given + * @c Ecore_Evas @b buffer canvas/window. * - * @param ee An @c Ecore_Evas handle - * @return A pointer to the internal pixels array of @p ee + * @remarks Besides returning a pointer to the actual pixel array of the given + * canvas, this call forces a rendering update on @a ee, first. * - * Besides returning a pointer to the actual pixel array of the given - * canvas, this call will force a rendering update on @p ee, - * first. + * @remarks A common use case for this call is to create an image object, from + * @b another canvas, to have as data @a ee's contents, thus taking a + * snapshot of the canvas. For that case, one can also use the + * ecore_evas_object_image_new() helper function. * - * A common use case for this call is to create an image object, from - * @b another canvas, to have as data @p ee's contents, thus - * snapshoting the canvas. For that case, one can also use the - * ecore_evas_object_image_new() helper function. + * @param[in] ee An @c Ecore_Evas handle + * @return A pointer to the internal pixels array of @a ee */ EAPI const void *ecore_evas_buffer_pixels_get(Ecore_Evas *ee); /** - * @brief Create a new @c Ecore_Evas canvas bound to the Evas - * @b ews (Ecore + Evas Single Process Windowing System) engine + * @brief Creates a new @c Ecore_Evas canvas bound to the Evas + * @b ews (Ecore + Evas Single Process Windowing System) engine. + * + * @since 1.1 * - * EWS is a simple single process windowing system. The backing store - * is also an @c Ecore_Evas that can be setup with - * ecore_evas_ews_setup() and retrieved with - * ecore_evas_ews_ecore_evas_get(). It will allow window management - * using events prefixed with @c ECORE_EVAS_EVENT_EWS_. + * @remarks EWS is a simple single process windowing system. The backing store + * is also an @c Ecore_Evas that can be setup with + * ecore_evas_ews_setup() and retrieved with + * ecore_evas_ews_ecore_evas_get(). It allows window management + * using events prefixed with @c ECORE_EVAS_EVENT_EWS_. * - * The EWS windows (returned by this function or - * ecore_evas_new("ews"...)) will all be software buffer windows - * automatic rendered to the backing store. + * @remarks The EWS windows (returned by this function or + * ecore_evas_new("ews"...)) is all software buffer windows + * automatic rendered to the backing store. * - * @param x horizontal position of window, in pixels - * @param y vertical position of window, in pixels - * @param w The width of the canvas, in pixels - * @param h The height of the canvas, in pixels - * @return A new @c Ecore_Evas instance or @c NULL, on failure + * @param[in] x The horizontal position of window, in pixels + * @param[in] y The vertical position of window, in pixels + * @param[in] w The width of the canvas, in pixels + * @param[in] h The height of the canvas, in pixels + * @return A new @c Ecore_Evas instance, \n + * otherwise @c NULL on failure * * @see ecore_evas_ews_setup() * @see ecore_evas_ews_ecore_evas_get() - * - * @since 1.1 */ EAPI Ecore_Evas *ecore_evas_ews_new(int x, int y, int w, int h); - /** - * Returns the backing store image object that represents the given - * window in EWS. - * @return The evas object of EWS backing store. + * @brief Gets the backing store image object that represents the given + * window in EWS. + * @since 1.1 * - * @note This should not be modified anyhow, but may be helpful to - * determine stacking and geometry of it for window managers - * that decorate windows. + * @remarks This should not be modified anyhow, but may be helpful to + * determine stacking and geometry of it for window managers + * that decorate windows. + * + * @param[in] ee The Ecore_Evas from which to get the backing store + * @return The evas object of EWS backing store * - * @param ee The Ecore_Evas from which to get the backing store. * @see ecore_evas_ews_manager_set() * @see ecore_evas_ews_evas_get() - * @since 1.1 */ EAPI Evas_Object *ecore_evas_ews_backing_store_get(const Ecore_Evas *ee); /** - * Calls the window to be deleted (freed), but can let user decide to - * forbid it by using ecore_evas_callback_delete_request_set() + * @brief Calls the window to be deleted (freed), but can let user decide to + * forbid it by using ecore_evas_callback_delete_request_set() + * @since 1.1 * - * @param ee The Ecore_Evas for which window will be deleted. - * @since 1.1 + * @param[in] ee The Ecore_Evas for which window is deleted */ EAPI void ecore_evas_ews_delete_request(Ecore_Evas *ee); /** - * @brief Create an Evas image object with image data bound to an - * own, internal @c Ecore_Evas canvas wrapper - * - * @param ee_target @c Ecore_Evas to have the canvas receiving the new - * image object - * @return A handle to the new image object - * - * This will create a @b special Evas image object. The image's pixel - * array will get bound to the same image data array of an @b internal - * @b buffer @c Ecore_Evas canvas. The user of this function is, then, - * supposed to grab that @c Ecore_Evas handle, with - * ecore_evas_object_ecore_evas_get(), and use its canvas to render - * whichever contents he/she wants, @b independently of the contents - * of the canvas owned by @p ee_target. Those contents will reflect on - * the canvas of @p ee, though, being exactly the image data of the - * object returned by this function. - * - * This is a helper function for the scenario of one wanting to grab a - * buffer canvas' contents (with ecore_evas_buffer_pixels_get()) to be - * used on another canvas, for whichever reason. The most common goal - * of this setup is to @b save an image file with a whole canvas as - * contents, which could not be achieved by using an image file within - * the target canvas. - * - * @warning Always resize the returned image and its underlying - * @c Ecore_Evas handle accordingly. They must be kept with same sizes - * for things to work as expected. Also, you @b must issue - * @c evas_object_image_size_set() on the image with that same size. If - * the image is to be shown in a canvas bound to an engine different - * than the buffer one, then you must also set this image's @b fill - * properties accordingly. - * - * @note The image returned will always be bound to the - * @c EVAS_COLORSPACE_ARGB8888 colorspace, always. - * - * @note Use ecore_evas_object_evas_get() to grab the image's internal - * own canvas directly. - * - * @note If snapshoting this image's internal canvas, remember to - * flush its internal @c Ecore_Evas firstly, with - * ecore_evas_manual_render(). + * @brief Creates an Evas image object with image data bound to an + * own, internal @c Ecore_Evas canvas wrapper. + * + * @remarks This creates a @b special Evas image object. The image's pixel + * array gets bound to the same image data array of an @b internal + * @b buffer @c Ecore_Evas canvas. The user of this function is, then, + * supposed to grab that @c Ecore_Evas handle, with + * ecore_evas_object_ecore_evas_get(), and use its canvas to render + * whichever contents he/she wants, @b independently of the contents + * of the canvas owned by @a ee_target. Those contents reflect on + * the canvas of @a ee, though, being exactly the image data of the + * object returned by this function. + * + * This is a helper function for the scenario of one wanting to grab a + * buffer canvas' contents (with ecore_evas_buffer_pixels_get()) to be + * used on another canvas, for whichever reason. The most common goal + * of this setup is to @b save an image file with a whole canvas as + * contents, which could not be achieved by using an image file within + * the target canvas. + * + * @remarks Always resize the returned image and its underlying + * @c Ecore_Evas handle accordingly. They must be kept with same sizes + * for things to work as expected. Also, you @b must issue + * @c evas_object_image_size_set() on the image with that same size. If + * the image is to be shown in a canvas bound to an engine different + * than the buffer one, then you must also set this image's @b fill + * properties accordingly. + * + * @remarks The image returned is always bound to the + * @c EVAS_COLORSPACE_ARGB8888 colorspace, always. + * + * @remarks Use ecore_evas_object_evas_get() to grab the image's internal + * own canvas directly. + * + * @remarks If you are taking a snapshot of this image's internal canvas, remember to + * flush its internal @c Ecore_Evas firstly, with + * ecore_evas_manual_render(). + * + * @param[in] ee_target The Ecore_Evas to have the canvas receiving the new image object + * @return A handle to the new image object */ EAPI Evas_Object *ecore_evas_object_image_new(Ecore_Evas *ee_target); /** - * @brief Retrieve the internal @c Ecore_Evas handle of an image - * object created via ecore_evas_object_image_new() + * @brief Gets the internal @c Ecore_Evas handle of an image + * object created using ecore_evas_object_image_new(). * - * @param obj A handle to an image object created via - * ecore_evas_object_image_new() - * @return The underlying @c Ecore_Evas handle in @p obj + * @param[in] obj A handle to an image object created using ecore_evas_object_image_new() + * @return The underlying @c Ecore_Evas handle in @a obj */ EAPI Ecore_Evas *ecore_evas_object_ecore_evas_get(Evas_Object *obj); /** - * @brief Retrieve the canvas bound to the internal @c Ecore_Evas - * handle of an image object created via ecore_evas_object_image_new() + * @brief Gets the canvas bound to the internal @c Ecore_Evas + * handle of an image object created using ecore_evas_object_image_new(). * - * @param obj A handle to an image object created via - * ecore_evas_object_image_new() - * @return A handle to @p obj's underlying @c Ecore_Evas's canvas + * @param[in] obj A handle to an image object created using ecore_evas_object_image_new() + * @return A handle to @a obj's underlying @c Ecore_Evas's canvas */ EAPI Evas *ecore_evas_object_evas_get(Evas_Object *obj); @@ -1173,68 +1499,69 @@ EAPI Ecore_Evas *ecore_evas_software_wince_gdi_new(Ecore_WinCE_Window *paren EAPI Ecore_WinCE_Window *ecore_evas_software_wince_window_get(const Ecore_Evas *ee); EAPI Ecore_Evas *ecore_evas_cocoa_new(Ecore_Cocoa_Window *parent, - int x, - int y, - int w, - int h); + int x, + int y, + int w, + int h); EAPI Ecore_Evas *ecore_evas_psl1ght_new(const char* name, int w, int h); -/* generic manipulation calls */ +/* Generic manipulation calls */ /** - * @brief Get the engine name used by this Ecore_Evas(window). + * @brief Gets the engine name used by this Ecore_Evas(window). * - * @param ee Ecore_Evas whose engine's name is desired. - * @return A string that can(usually) be used in ecore_evas_new() + * @param[in] ee The Ecore_Evas whose engine's name is desired + * @return A string that can(usually) be used in ecore_evas_new() * * @see ecore_evas_free() */ EAPI const char *ecore_evas_engine_name_get(const Ecore_Evas *ee); /** - * @brief Return the Ecore_Evas for this Evas + * @brief Gets the Ecore_Evas for this Evas. * - * @param e The Evas to get the Ecore_Evas from - * @return The Ecore_Evas that holds this Evas, or @c NULL if not held by one. + * @remarks Use this only on Evas created with ecore evas. * - * @warning Only use on Evas' created with ecore evas! + * @param[in] e The Evas to get the Ecore_Evas from + * @return The Ecore_Evas that holds this Evas, \n + * otherwise @c NULL if not held by one */ EAPI Ecore_Evas *ecore_evas_ecore_evas_get(const Evas *e); /** - * @brief Free an Ecore_Evas + * @brief Frees an Ecore_Evas. * - * @param ee The Ecore_Evas to free + * @details This function frees up any memory used by the Ecore_Evas. * - * This frees up any memory used by the Ecore_Evas. + * @param[in] ee The Ecore_Evas to free. */ EAPI void ecore_evas_free(Ecore_Evas *ee); /** - * @brief Retrieve user data associated with an Ecore_Evas. + * @brief Gets user data associated with an Ecore_Evas. * - * @param ee The Ecore_Evas to retrieve the user data from. - * @param key The key which the user data to be retrieved is associated with. + * @details This function retrieves user specific data that has been stored within an + * Ecore_Evas structure with ecore_evas_data_set(). * - * This function retrieves user specific data that has been stored within an - * Ecore_Evas structure with ecore_evas_data_set(). + * @return A pointer to the user data on success, \n + * otherwise @c NULL on error * - * @returns @c NULL on error or no data found, A pointer to the user data on - * success. + * @param[in] ee The Ecore_Evas to retrieve the user data from + * @param[in] key The key which the user data to be retrieved is associated with * * @see ecore_evas_data_set() */ EAPI void *ecore_evas_data_get(const Ecore_Evas *ee, const char *key); /** - * @brief Store user data in an Ecore_Evas structure. + * @brief Stores user data in an Ecore_Evas structure. * - * @param ee The Ecore_Evas to store the user data in. - * @param key A unique string to associate the user data against. Cannot - * be NULL. - * @param data A pointer to the user data to store. + * @details This function associates the @a data with a @a key which is stored by + * the Ecore_Evas @a ee. Be aware that a call to ecore_evas_free() does + * not free any memory for the associated user data. This is the responsibility + * of the caller. * - * This function associates the @p data with a @p key which is stored by - * the Ecore_Evas @p ee. Be aware that a call to ecore_evas_free() will - * not free any memory for the associated user data, this is the responsibility - * of the caller. + * @param[in] ee The Ecore_Evas to store the user data in + * @param[in] key A unique string to associate the user data against \n + * This must not be @c NULL. + * @param[in] data A pointer to the user data to store * * @see ecore_evas_callback_pre_free_set() * @see ecore_evas_free() @@ -1242,587 +1569,585 @@ EAPI void *ecore_evas_data_get(const Ecore_Evas *ee, const char *key); */ EAPI void ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data); /** - * Set a callback for Ecore_Evas resize events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee is resized. + * @brief Sets a callback for Ecore_Evas resize events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee is resized. + * + * @remarks If and when this function is called depends on the underlying + * windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas move events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee is moved. + * @brief Sets a callback for Ecore_Evas move events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee is moved. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_move_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas show events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee is shown. + * @brief Sets a callback for Ecore_Evas show events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee is shown. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_show_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas hide events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee is hidden. + * @brief Sets a callback for Ecore_Evas hide events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee is hidden. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_hide_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas delete request events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee gets a delete request. + * @brief Sets a callback for Ecore_Evas delete request events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee gets a delete request. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas destroy events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee is destroyed. + * @brief Sets a callback for Ecore_Evas destroy events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee is destroyed. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_destroy_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas focus in events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee gets focus. + * @brief Sets a callback for Ecore_Evas focus in events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee gets focus. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); -/** - * Set a callback for Ecore_Evas focus out events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee loses focus. +/** + * @brief Sets a callback for Ecore_Evas focus out events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee loses focus. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call */ EAPI void ecore_evas_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas sticky events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee becomes sticky. + * @brief Sets a callback for Ecore_Evas sticky events. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee becomes sticky. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks When this function is called depends on the underlying windowing system. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call */ EAPI void ecore_evas_callback_sticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); -/** - * Set a callback for Ecore_Evas un-sticky events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee becomes un-sticky. +/** + * @brief Sets a callback for Ecore_Evas focus out events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee becomes un-sticky. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call + */ EAPI void ecore_evas_callback_unsticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas mouse in events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever the mouse enters @p ee. + * @brief Sets a callback for Ecore_Evas mouse in events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever the mouse enters @a ee. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas mouse out events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever the mouse leaves @p ee. + * @brief Sets a callback for Ecore_Evas mouse out events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever the mouse leaves @a ee. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas pre render events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called just before the evas in @p ee is rendered. + * @brief Sets a callback for Ecore_Evas pre render events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called just before the evas in @a ee is rendered. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_pre_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas mouse post render events. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called just after the evas in @p ee is rendered. + * @brief Sets a callback for Ecore_Evas mouse post render events. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called just after the evas in @a ee is rendered. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_post_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas pre-free event. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call + * @brief Sets a callback for Ecore_Evas pre-free event. * - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called just before the instance @p ee is freed. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called just before the instance @a ee is freed. * - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_pre_free_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Set a callback for Ecore_Evas state changes. - * @param ee The Ecore_Evas to set callbacks on - * @param func The function to call - - * A call to this function will set a callback on an Ecore_Evas, causing - * @p func to be called whenever @p ee changes state. + * @brief Sets a callback for Ecore_Evas state changes. + * @since 1.2 * - * @since 1.2 - * @warning If and when this function is called depends on the underlying - * windowing system. + * @remarks A call to this function sets a callback on an Ecore_Evas, causing + * @a func to be called whenever @a ee changes state. + * + * @remarks When this function is called depends on the underlying windowing system. + * @param[in] ee The Ecore_Evas to set callbacks on + * @param[in] func The function to call */ EAPI void ecore_evas_callback_state_change_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** - * Get an Ecore_Evas's Evas - * @param ee The Ecore_Evas whose Evas you wish to get - * @return The Evas wrapped by @p ee + * @brief Gets an Ecore_Evas's Evas. * - * This function returns the Evas contained within @p ee. + * @details This function returns the Evas contained within @a ee. + * + * @param[in] ee The Ecore_Evas whose Evas you wish to get + * @return The Evas wrapped by @a ee */ EAPI Evas *ecore_evas_get(const Ecore_Evas *ee); /** - * Provide Managed move co-ordinates for an Ecore_Evas - * @param ee The Ecore_Evas to move - * @param x The x coordinate to set as the managed location - * @param y The y coordinate to set as the managed location + * @brief Provides managed move co-ordinates for an Ecore_Evas. + * + * @details This sets the managed geometry position of the @a ee to (@a x, @a y). * - * This sets the managed geometry position of the @p ee to (@p x, @p y) + * @param[in] ee The Ecore_Evas to move + * @param[in] x The x coordinate to set as the managed location + * @param[in] y The y coordinate to set as the managed location */ EAPI void ecore_evas_managed_move(Ecore_Evas *ee, int x, int y); /** - * Set whether an Ecore_Evas is shaped or not. + * @brief Sets whether an Ecore_Evas is shaped or not. * - * @param ee The Ecore_Evas to shape. - * @param shaped @c EINA_TRUE to shape, @c EINA_FALSE to not. + * @remarks This function allows one to make an Ecore_Evas shaped to the contents of the + * evas. If @a shaped is @c EINA_TRUE, @a ee is transparent in parts of + * the evas that contain no objects. If @a shaped is @c EINA_FALSE, then @a ee + * is rectangular, and parts with no data show random framebuffer + * artifacting. For non-shaped Ecore_Evases, it is recommended to cover the + * entire evas with a background object. * - * This function allows one to make an Ecore_Evas shaped to the contents of the - * evas. If @p shaped is @c EINA_TRUE, @p ee will be transparent in parts of - * the evas that contain no objects. If @p shaped is @c EINA_FALSE, then @p ee - * will be rectangular, and parts with no data will show random framebuffer - * artifacting. For non-shaped Ecore_Evases, it is recommended to cover the - * entire evas with a background object. + * @param[in] ee The Ecore_Evas to shape + * @param[in] shaped Set @c EINA_TRUE to shape, \n + * otherwise set @c EINA_FALSE to not shape */ EAPI void ecore_evas_shaped_set(Ecore_Evas *ee, Eina_Bool shaped); /** - * Query whether an Ecore_Evas is shaped or not. + * @brief Checks whether an Ecore_Evas is shaped. * - * @param ee The Ecore_Evas to query. - * @return @c EINA_TRUE if shaped, @c EINA_FALSE if not. + * @details This function returns @c EINA_TRUE if @a ee is shaped, and @c EINA_FALSE if not. * - * This function returns @c EINA_TRUE if @p ee is shaped, and @c EINA_FALSE if not. + * @param[in] ee The Ecore_Evas to query + * @return @c EINA_TRUE if shaped, \n + * otherwise @c EINA_FALSE if is not shaped */ EAPI Eina_Bool ecore_evas_shaped_get(const Ecore_Evas *ee); /** - * @brief Show an Ecore_Evas' window + * @brief Shows an Ecore_Evas window. * - * @param ee The Ecore_Evas to show. + * @details This function makes @a ee visible. * - * This function makes @p ee visible. + * @param[in] ee The Ecore_Evas to show */ EAPI void ecore_evas_show(Ecore_Evas *ee); /** - * @brief Hide an Ecore_Evas' window + * @brief Hides an Ecore_Evas' window. * - * @param ee The Ecore_Evas to hide. + * @details This function makes @a ee hidden (not visible). * - * This function makes @p ee hidden(not visible). + * @param[in] ee The Ecore_Evas to hide */ EAPI void ecore_evas_hide(Ecore_Evas *ee); /** - * Activate (set focus to, via the window manager) an Ecore_Evas' window. - * @param ee The Ecore_Evas to activate. + * @brief Activates (sets focus to, via the window manager) an Ecore_Evas' window. + * + * @details This functions activates the Ecore_Evas. * - * This functions activates the Ecore_Evas. + * @param[in] ee The Ecore_Evas to activate */ EAPI void ecore_evas_activate(Ecore_Evas *ee); /** - * Set the minimum size of a given @c Ecore_Evas window + * @brief Sets the minimum size of a given @c Ecore_Evas window. * - * @param ee An @c Ecore_Evas window's handle - * @param w The minimum width - * @param h The minimum height + * @details This function sets the minimum size of @a ee to be @a w x @a h. + * You cannot resize that window to dimensions smaller than + * the ones set. * - * This function sets the minimum size of @p ee to be @p w x @p h. - * One won't be able to resize that window to dimensions smaller than - * the ones set. + * @remarks When base sizes are set, using ecore_evas_size_base_set(), + * they are used to calculate a window's minimum size, instead of + * those set by this function. * - * @note When base sizes are set, via ecore_evas_size_base_set(), - * they'll be used to calculate a window's minimum size, instead of - * those set by this function. + * @param[in] ee An @c Ecore_Evas window's handle + * @param[in] w The minimum width + * @param[in] h The minimum height * * @see ecore_evas_size_min_get() */ EAPI void ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h); /** - * Get the minimum size set for a given @c Ecore_Evas window + * @brief Gets the minimum size set for a given @c Ecore_Evas window. * - * @param ee An @c Ecore_Evas window's handle - * @param w A pointer to an int to place the minimum width in. - * @param h A pointer to an int to place the minimum height in. + * @remarks Use @c NULL pointers on the size components that you are not + * interested in: they are ignored by the function. * - * @note Use @c NULL pointers on the size components you're not - * interested in: they'll be ignored by the function. + * @param[in] ee An @c Ecore_Evas window's handle + * @param[out] w A pointer to an int to place the minimum width in + * @param[out] h A pointer to an int to place the minimum height in * * @see ecore_evas_size_min_set() for more details */ EAPI void ecore_evas_size_min_get(const Ecore_Evas *ee, int *w, int *h); /** - * Set the maximum size of a given @c Ecore_Evas window + * @brief Sets the maximum size of a given @c Ecore_Evas window. * - * @param ee An @c Ecore_Evas window's handle - * @param w The maximum width - * @param h The maximum height + * @details This function sets the maximum size of @a ee to be @a w x @a h. + * You cannot resize that window to dimensions bigger than + * the ones set. * - * This function sets the maximum size of @p ee to be @p w x @p h. - * One won't be able to resize that window to dimensions bigger than - * the ones set. + * @param[in] ee An @c Ecore_Evas window's handle + * @param[in] w The maximum width + * @param[in] h The maximum height * * @see ecore_evas_size_max_get() */ EAPI void ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h); /** - * Get the maximum size set for a given @c Ecore_Evas window + * @brief Gets the maximum size set for a given @c Ecore_Evas window. * - * @param ee An @c Ecore_Evas window's handle - * @param w A pointer to an int to place the maximum width in. - * @param h A pointer to an int to place the maximum height in. + * @remarks Use @c NULL pointers on the size components that you are not + * interested in: they are ignored by the function. * - * @note Use @c NULL pointers on the size components you're not - * interested in: they'll be ignored by the function. + * @param[in] ee An @c Ecore_Evas window's handle + * @param[out] w A pointer to an int to place the maximum width in + * @param[out] h A pointer to an int to place the maximum height in * * @see ecore_evas_size_max_set() for more details */ EAPI void ecore_evas_size_max_get(const Ecore_Evas *ee, int *w, int *h); /** - * Set the base size for a given @c Ecore_Evas window + * @brief Sets the base size for a given @c Ecore_Evas window. * - * @param ee An @c Ecore_Evas window's handle - * @param w The base width - * @param h The base height + * @details This function sets the @b base size of @a ee to be @a w x @a h. + * When base sizes are set, they are used to calculate a window's + * @b minimum size, instead of those set by ecore_evas_size_min_get(). * - * This function sets the @b base size of @p ee to be @p w x @p h. - * When base sizes are set, they'll be used to calculate a window's - * @b minimum size, instead of those set by ecore_evas_size_min_get(). + * @param[in] ee An @c Ecore_Evas window's handle + * @param[in] w The base width + * @param[in] h The base height * * @see ecore_evas_size_base_get() */ EAPI void ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h); /** - * Get the base size set for a given @c Ecore_Evas window + * @brief Gets the base size set for a given @c Ecore_Evas window. * - * @param ee An @c Ecore_Evas window's handle - * @param w A pointer to an int to place the base width in. - * @param h A pointer to an int to place the base height in. + * @remarks Use @c NULL pointers on the size components that you are not + * interested in: they are ignored by the function. * - * @note Use @c NULL pointers on the size components you're not - * interested in: they'll be ignored by the function. + * @param[in] ee An @c Ecore_Evas window's handle + * @param[out] w A pointer to an int to place the base width in + * @param[out] h A pointer to an int to place the base height in * * @see ecore_evas_size_base_set() for more details */ EAPI void ecore_evas_size_base_get(const Ecore_Evas *ee, int *w, int *h); /** - * Set the "size step" for a given @c Ecore_Evas window + * @brief Sets the "size step" for a given @c Ecore_Evas window. * - * @param ee An @c Ecore_Evas window's handle - * @param w The step width - * @param h The step height + * @details This function sets the size steps of @a ee to be @a w x @a h. This + * limits the size of this @c Ecore_Evas window to be @b always an + * integer multiple of the step size, for each axis. * - * This function sets the size steps of @p ee to be @p w x @p h. This - * limits the size of this @c Ecore_Evas window to be @b always an - * integer multiple of the step size, for each axis. + * @param[in] ee An @c Ecore_Evas window's handle + * @param[in] w The step width + * @param[in] h The step height */ EAPI void ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h); /** - * Get the "size step" set for a given @c Ecore_Evas window + * @brief Gets the "size step" set for a given @c Ecore_Evas window. * - * @param ee An @c Ecore_Evas window's handle - * @param w A pointer to an int to place the step width in. - * @param h A pointer to an int to place the step height in. + * @remarks Use @c NULL pointers on the size components that you are not + * interested in: they are ignored by the function. * - * @note Use @c NULL pointers on the size components you're not - * interested in: they'll be ignored by the function. + * @param[in] ee An @c Ecore_Evas window's handle + * @param[out] w A pointer to an int to place the step width in + * @param[out] h A pointer to an int to place the step height in * * @see ecore_evas_size_base_set() for more details */ EAPI void ecore_evas_size_step_get(const Ecore_Evas *ee, int *w, int *h); /** - * @brief Set the cursor of an Ecore_Evas. + * @brief Sets the cursor of an Ecore_Evas. * - * @param ee The Ecore_Evas - * @param file The path to an image file for the cursor. - * @param layer The layer in which the cursor will appear. - * @param hot_x The x coordinate of the cursor's hot spot. - * @param hot_y The y coordinate of the cursor's hot spot. + * @details This function makes the mouse cursor over @a ee be the image specified by + * @a file. The actual point within the image that the mouse is at is specified + * by @a hot_x and @a hot_y, which are coordinates with respect to the top left + * corner of the cursor image. * - * This function makes the mouse cursor over @p ee be the image specified by - * @p file. The actual point within the image that the mouse is at is specified - * by @p hot_x and @p hot_y, which are coordinates with respect to the top left - * corner of the cursor image. + * @remarks This function creates an object from the image and uses ecore_evas_object_cursor_set(). * - * @note This function creates an object from the image and uses - * ecore_evas_object_cursor_set(). + * @param[in] ee The Ecore_Evas + * @param[in] file The path to an image file for the cursor + * @param[in] layer The layer in which the cursor appears + * @param[in] hot_x The x coordinate of the cursor's hot spot + * @param[in] hot_y The y coordinate of the cursor's hot spot * * @see ecore_evas_object_cursor_set() */ EAPI void ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y); /** - * @brief Get information about an Ecore_Evas' cursor + * @brief Gets information about an Ecore_Evas' cursor. * - * @param ee The Ecore_Evas to set - * @param obj A pointer to an Evas_Object to place the cursor Evas_Object. - * @param layer A pointer to an int to place the cursor's layer in. - * @param hot_x A pointer to an int to place the cursor's hot_x coordinate in. - * @param hot_y A pointer to an int to place the cursor's hot_y coordinate in. + * @details This function queries information about an Ecore_Evas' cursor. * - * This function queries information about an Ecore_Evas' cursor. + * @param[in] ee The Ecore_Evas to set + * @param[out] obj A pointer to an Evas_Object to place the cursor Evas_Object + * @param[out] layer A pointer to an int to place the cursor's layer in + * @param[out] hot_x A pointer to an int to place the cursor's hot_x coordinate in + * @param[out] hot_y A pointer to an int to place the cursor's hot_y coordinate in * * @see ecore_evas_cursor_set() * @see ecore_evas_object_cursor_set() */ EAPI void ecore_evas_cursor_get(const Ecore_Evas *ee, Evas_Object **obj, int *layer, int *hot_x, int *hot_y); + /** - * @brief Set the cursor of an Ecore_Evas - * - * @param ee The Ecore_Evas + * @brief Sets the cursor of an Ecore_Evas. * - * @param obj The Evas_Object which will be the cursor. - * @param layer The layer in which the cursor will appear. - * @param hot_x The x coordinate of the cursor's hot spot. - * @param hot_y The y coordinate of the cursor's hot spot. + * @details This function makes the mouse cursor over @a ee be the object specified by + * @a obj. The actual point within the object that the mouse is at is specified + * by @a hot_x and @a hot_y, which are coordinates with respect to the top left + * corner of the cursor object. * - * This function makes the mouse cursor over @p ee be the object specified by - * @p obj. The actual point within the object that the mouse is at is specified - * by @p hot_x and @p hot_y, which are coordinates with respect to the top left - * corner of the cursor object. + * @param[in] ee The Ecore_Evas + * @param[in] obj The Evas_Object which is the cursor + * @param[in] layer The layer in which the cursor appears + * @param[in] hot_x The x coordinate of the cursor's hot spot + * @param[in] hot_y The y coordinate of the cursor's hot spot * * @see ecore_evas_cursor_set() */ EAPI void ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y); /** - * Tell the WM whether or not to ignore an Ecore_Evas' window + * @brief Tells the WM whether or not to ignore an Ecore_Evas' window. * - * @param ee The Ecore_Evas. - * @param on @c EINA_TRUE to ignore, @c EINA_FALSE to not. + * @details This function causes the window manager to ignore @a ee if @a on is + * @c EINA_TRUE, or not ignore @a ee if @a on is @c EINA_FALSE. * - * This function causes the window manager to ignore @p ee if @p on is - * @c EINA_TRUE, or not ignore @p ee if @p on is @c EINA_FALSE. + * @param[in] ee The Ecore_Evas + * @param[in] on Set @c EINA_TRUE to ignore, \n + * otherwise set @c EINA_FALSE to not ignore */ EAPI void ecore_evas_override_set(Ecore_Evas *ee, Eina_Bool on); /** - * Query whether an Ecore_Evas' window is overridden or not + * @brief Checks whether an Ecore_Evas window is overridden or not. + * + * @param[in] ee The Ecore_Evas to set + * @return The type of the damage management * - * @param ee The Ecore_Evas to set. - * @return @c EINA_TRUE if @p ee is overridden, @c EINA_FALSE if not. */ -EAPI Eina_Bool ecore_evas_override_get(const Ecore_Evas *ee); +EAPI Ecore_Evas_Avoid_Damage_Type ecore_evas_avoid_damage_get(const Ecore_Evas *ee); /** - * Set whether or not an Ecore_Evas' window should avoid damage - * - * @param ee The Ecore_Evas - * @param on The type of the damage management + * @brief Sets the withdrawn state of an Ecore_Evas' window. * - * This option causes updates of the Ecore_Evas to be done on a pixmap, and - * then copied to the window, or the pixmap used directly on the window, - * depending on the setting. Possible options are: + * @param[in] ee The Ecore_Evas whose window's withdrawn state is set + * @param[in] withdrawn Set @c EINA_TRUE to set the withdrawn state, \n + * otherwise set @c EINA_FALSE to not set the state * - * @li @ref ECORE_EVAS_AVOID_DAMAGE_NONE - every expose event triggers a new - * damage and consequently render of the affected area. The rendering of things - * happens directly on the window; - * - * @li @ref ECORE_EVAS_AVOID_DAMAGE_EXPOSE - there's a pixmap where everything - * is rendered into, and then copied to the window. On expose events, there's - * no need to render things again, just to copy the exposed region to the - * window; - * - * @li @ref ECORE_EVAS_AVOID_DAMAGE_BUILT_IN - there's the same pixmap as the - * previous one, but it is set as a "background pixmap" of the window. The - * rendered things appear directly on the window, with no need to copy - * anything, but would stay stored on the pixmap, so there's no need to render - * things again on expose events. This option can be faster than the previous - * one, but may lead to artifacts during resize of the window. */ -EAPI void ecore_evas_avoid_damage_set(Ecore_Evas *ee, Ecore_Evas_Avoid_Damage_Type on); +EAPI void ecore_evas_withdrawn_set(Ecore_Evas *ee, Eina_Bool withdrawn); /** - * Query whether an Ecore_Evas' window avoids damage or not - * @param ee The Ecore_Evas to set - * @return The type of the damage management + * @brief Gets the withdrawn state of an Ecore_Evas' window. + * + * @param[in] ee The Ecore_Evas whose window's withdrawn state is returned + * @return @c EINA_TRUE if the Ecore_Evas window's withdrawn state is state, \n + * otherwise @c EINA_FALSE if it is not state * */ -EAPI Ecore_Evas_Avoid_Damage_Type ecore_evas_avoid_damage_get(const Ecore_Evas *ee); +EAPI Eina_Bool ecore_evas_withdrawn_get(const Ecore_Evas *ee); /** - * Set the withdrawn state of an Ecore_Evas' window. - * @param ee The Ecore_Evas whose window's withdrawn state is set. - * @param withdrawn The Ecore_Evas window's new withdrawn state. + * @brief Sets the sticky state of an Ecore_Evas window. + * + * @param[in] ee The Ecore_Evas whose window's sticky state is set + * @param[in] sticky Set @c EINA_TRUE to set the sticky state, \n + * otherwise set @c EINA_FALSE to not set it * */ -EAPI void ecore_evas_withdrawn_set(Ecore_Evas *ee, Eina_Bool withdrawn); +EAPI void ecore_evas_sticky_set(Ecore_Evas *ee, Eina_Bool sticky); /** - * Returns the withdrawn state of an Ecore_Evas' window. - * @param ee The Ecore_Evas whose window's withdrawn state is returned. - * @return The Ecore_Evas window's withdrawn state. + * @brief Gets the sticky state of an Ecore_Evas' window. + * + * @param[in] ee The Ecore_Evas whose window's sticky state is returned + * @return @c EINA_TRUE if the Ecore_Evas window's sticky state is set, \n + * otherwise @c EINA_FALSE if the state is not set * */ -EAPI Eina_Bool ecore_evas_withdrawn_get(const Ecore_Evas *ee); +EAPI Eina_Bool ecore_evas_sticky_get(const Ecore_Evas *ee); /** - * Set the sticky state of an Ecore_Evas window. + * @brief Enable/disable manual render * - * @param ee The Ecore_Evas whose window's sticky state is set. - * @param sticky The Ecore_Evas window's new sticky state. + * @details If @p manual_render is true, default ecore_evas render routine would be + * disabled and rendering will be done only manually. If @p manual_render is + * false, rendering will be done by default ecore_evas rendering routine, but + * still manual rendering is available. Call ecore_evas_manual_render() to + * force immediate render. * + * @param[in] ee An @c Ecore_Evas handle + * @param[in] manual_render Enable/disable manual render. @c EINA_TRUE to enable + * manual render, @c EINA_FALSE to disable manual render. @c EINA_FALSE by + * default + * + * @see ecore_evas_manual_render_get() + * @see ecore_evas_manual_render() */ -EAPI void ecore_evas_sticky_set(Ecore_Evas *ee, Eina_Bool sticky); +EAPI void ecore_evas_manual_render_set(Ecore_Evas *ee, Eina_Bool manual_render); /** - * Returns the sticky state of an Ecore_Evas' window. + * @brief Get enable/disable status of manual render * - * @param ee The Ecore_Evas whose window's sticky state is returned. - * @return The Ecore_Evas window's sticky state. + * @param[in] ee An @c Ecore_Evas handle + * @return @c EINA_TRUE if manual render is enabled, @c EINA_FALSE if manual + * render is disabled * + * @see ecore_evas_manual_render_set() + * @see ecore_evas_manual_render() */ -EAPI Eina_Bool ecore_evas_sticky_get(const Ecore_Evas *ee); -EAPI void ecore_evas_manual_render_set(Ecore_Evas *ee, Eina_Bool manual_render); EAPI Eina_Bool ecore_evas_manual_render_get(const Ecore_Evas *ee); /** - * @brief Registers an @c Ecore_Evas to receive events through ecore_input_evas. + * @brief Registers an @c Ecore_Evas to receive events through ecore_input_evas. * - * @param ee The @c Ecore_Evas handle. + * @details This function calls ecore_event_window_register() with the @a ee as its @a + * id argument, @a window argument, and uses its @a Evas too. It is useful when + * no @a window information is available on a given @a Ecore_Evas backend. + * @since 1.1 * - * This function calls ecore_event_window_register() with the @p ee as its @c - * id argument, @c window argument, and uses its @c Evas too. It is useful when - * no @c window information is available on a given @c Ecore_Evas backend. + * @param[in] ee The @c Ecore_Evas handle * * @see ecore_evas_input_event_unregister() - * @since 1.1 */ EAPI void ecore_evas_input_event_register(Ecore_Evas *ee); + /** - * @brief Unregisters an @c Ecore_Evas receiving events through ecore_input_evas. + * @brief Unregisters an @c Ecore_Evas receiving events through ecore_input_evas. + * @since 1.1 * - * @param ee The @c Ecore_Evas handle. + * @param[in] ee The @c Ecore_Evas handle * * @see ecore_evas_input_event_register() - * @since 1.1 */ EAPI void ecore_evas_input_event_unregister(Ecore_Evas *ee); /** - * @brief Force immediate rendering on a given @c Ecore_Evas window - * - * @param ee An @c Ecore_Evas handle + * @brief Forces immediate rendering on a given @c Ecore_Evas window. * - * Use this call to forcefully flush the @p ee's canvas rendering - * pipeline, thus bring its window to an up to date state. + * @remarks Use this call to forcefully flush the @a ee's canvas rendering + * pipeline, thus bringing its window to an up-to-date state. + * @param[in] ee An @c Ecore_Evas handle */ EAPI void ecore_evas_manual_render(Ecore_Evas *ee); EAPI void ecore_evas_comp_sync_set(Ecore_Evas *ee, Eina_Bool do_sync); EAPI Eina_Bool ecore_evas_comp_sync_get(const Ecore_Evas *ee); /** - * @brief Get geometry of screen associated with this Ecore_Evas. + * @brief Gets geometry of screen associated with this Ecore_Evas. * - * @param ee The Ecore_Evas whose window's to query container screen geometry. - * @param x where to return the horizontal offset value. May be @c NULL. - * @param y where to return the vertical offset value. May be @c NULL. - * @param w where to return the width value. May be @c NULL. - * @param h where to return the height value. May be @c NULL. + * @since 1.1 * - * @since 1.1 + * @param[in] ee The Ecore_Evas whose window's to query container screen geometry + * @param[out] x The horizontal offset value that is returned \n + * This may be @c NULL. + * @param[out] y The vertical offset value that is returned \n + * This may be @c NULL. + * @param[out] w The width value that is returned \n + * This may be @c NULL. + * @param[out] h The height value \n + * This may be @c NULL. */ EAPI void ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); /** - * @brief Get the dpi of the screen the Ecore_Evas is primarily on. + * @brief Gets the DPI of the screen the Ecore_Evas is primarily on. * - * @param ee The Ecore_Evas whose window's to query. - * @param xdpi Pointer to integer to store horizontal DPI. May be @c NULL. - * @param ydpi Pointer to integer to store vertical DPI. May be @c NULL. + * @since 1.7 * - * @since 1.7 + * @param[in] ee The Ecore_Evas whose window's to query + * @param[out] xdpi The pointer to integer to store horizontal DPI \n + * This may be @c NULL. + * @param[out] ydpi The pointer to integer to store vertical DPI \n + * This may be @c NULL. */ EAPI void ecore_evas_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi); @@ -1830,78 +2155,82 @@ EAPI void ecore_evas_draw_frame_set(Ecore_Evas *ee, Eina_Bool draw_frame) EAPI Eina_Bool ecore_evas_draw_frame_get(const Ecore_Evas *ee); /** - * @brief Associate the given object to this ecore evas. - * - * @param ee The Ecore_Evas to associate to @a obj - * @param obj The object to associate to @a ee - * @param flags The association flags. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * Association means that operations on one will affect the other, for - * example moving the object will move the window, resize the object will - * also affect the ecore evas window, hide and show applies as well. - * - * This is meant to simplify development, since you often need to associate - * these events with your "base" objects, background or bottom-most object. - * - * Be aware that some methods might not be what you would like, deleting - * either the window or the object will delete the other. If you want to - * change that behavior, let's say to hide window when it's closed, you - * must use ecore_evas_callback_delete_request_set() and set your own code, - * like ecore_evas_hide(). Just remember that if you override delete_request - * and still want to delete the window/object, you must do that yourself. - * - * Since we now define delete_request, deleting windows will not quit - * main loop, if you wish to do so, you should listen for EVAS_CALLBACK_FREE - * on the object, that way you get notified and you can call - * ecore_main_loop_quit(). - * - * Flags can be OR'ed of: - * @li ECORE_EVAS_OBJECT_ASSOCIATE_BASE (or 0): to listen to basic events - * like delete, resize and move, but no stacking or layer are used. - * @li ECORE_EVAS_OBJECT_ASSOCIATE_STACK: stacking operations will act - * on the Ecore_Evas, not the object. So evas_object_raise() will - * call ecore_evas_raise(). Relative operations (stack_above, stack_below) - * are still not implemented. - * @li ECORE_EVAS_OBJECT_ASSOCIATE_LAYER: stacking operations will act - * on the Ecore_Evas, not the object. So evas_object_layer_set() will - * call ecore_evas_layer_set(). - * @li ECORE_EVAS_OBJECT_ASSOCIATE_DEL: the object delete will delete the - * ecore_evas as well as delete_requests on the ecore_evas will delete - * etc. + * @brief Associates the given object to this ecore evas. + * + * @remarks Association means that operations on one affects the other. For + * example, moving the object moves the window, resizing the object + * also affects the ecore evas window, hide and show applies as well. + * + * @remarks This is meant to simplify development, since you often need to associate + * these events with your "base" objects, background or bottom-most object. + * + * @remarks Be aware that some methods might not be what you would like, deleting + * either the window or the object deletes the other. If you want to + * change that behavior, say to hide window when it is closed, you + * must use ecore_evas_callback_delete_request_set() and set your own code, + * like ecore_evas_hide(). Just remember that if you override delete_request + * and still want to delete the window or object, you must do that yourself. + * + * @remarks Since we now define delete_request, deleting windows does not quit + * main loop. If you wish to do so, you should listen for EVAS_CALLBACK_FREE + * on the object, that way you get notified and you can call + * ecore_main_loop_quit(). + * + * @remarks Flags can be OR'ed of: + * @li ECORE_EVAS_OBJECT_ASSOCIATE_BASE (or 0): to listen to basic events + * like delete, resize and move, but no stacking or layer are used. + * @li ECORE_EVAS_OBJECT_ASSOCIATE_STACK: stacking operations act + * on the Ecore_Evas, not the object. So evas_object_raise() + * calls ecore_evas_raise(). Relative operations (stack_above, stack_below) + * are still not implemented. + * @li ECORE_EVAS_OBJECT_ASSOCIATE_LAYER: stacking operations act + * on the Ecore_Evas, not the object. So evas_object_layer_set() + * calls ecore_evas_layer_set(). + * @li ECORE_EVAS_OBJECT_ASSOCIATE_DEL: the object delete deletes the + * ecore_evas and the delete_requests on the ecore_evas are also deleted. + * + * @param[in] ee The Ecore_Evas to associate to @a obj + * @param[in] obj The object to associate to @a ee + * @param[in] flags The association flags + * @return @c EINA_TRUE if associated successfully, \n + * otherwise @c EINA_FALSE on failure */ EAPI Eina_Bool ecore_evas_object_associate(Ecore_Evas *ee, Evas_Object *obj, Ecore_Evas_Object_Associate_Flags flags); + /** - * @brief Cancel the association set with ecore_evas_object_associate(). + * @brief Cancels the association set with ecore_evas_object_associate(). * - * @param ee The Ecore_Evas to dissociate from @a obj - * @param obj The object to dissociate from @a ee - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * @param[in] ee The Ecore_Evas to dissociate from @a obj + * @param[in] obj The object to dissociate from @a ee + * @return @c EINA_TRUE if the association is cancelled successfully, + * otherwise @c EINA_FALSE on failure */ EAPI Eina_Bool ecore_evas_object_dissociate(Ecore_Evas *ee, Evas_Object *obj); + /** - * @brief Get the object associated with @p ee + * @brief Gets the object associated with @a ee. * - * @param ee The Ecore_Evas to get the object from. - * @return The associated object, or @c NULL if there is no associated object. + * @param[in] ee The Ecore_Evas to get the object from. + * @return The associated object, \n + * otherwise @c NULL if there is no associated object */ EAPI Evas_Object *ecore_evas_object_associate_get(const Ecore_Evas *ee); -/* helper function to be used with ECORE_GETOPT_CALLBACK_*() */ +/* Helper function to be used with ECORE_GETOPT_CALLBACK_*() */ EAPI unsigned char ecore_getopt_callback_ecore_evas_list_engines(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage); /** - * @brief Get a list of all the ecore_evases. + * @brief Gets a list of all the ecore_evases. * - * @return A list of ecore_evases. + * @remarks The returned list of ecore evases is only valid until the canvases are + * destroyed (and should not be cached for instance). The list can be freed by + * just deleting the list. * - * The returned list of ecore evases is only valid until the canvases are - * destroyed (and should not be cached for instance). The list can be freed by - * just deleting the list. + * @return A list of ecore_evases */ EAPI Eina_List *ecore_evas_ecore_evas_list_get(void); -/* specific calls to an x11 environment ecore_evas */ +/* Specific calls to an x11 environment ecore_evas */ EAPI void ecore_evas_x11_leader_set(Ecore_Evas *ee, Ecore_X_Window win); EAPI Ecore_X_Window ecore_evas_x11_leader_get(Ecore_Evas *ee); EAPI void ecore_evas_x11_leader_default_set(Ecore_Evas *ee); @@ -1913,7 +2242,9 @@ EAPI void ecore_evas_x11_shape_input_reset(Ecore_Evas *ee); EAPI void ecore_evas_x11_shape_input_apply(Ecore_Evas *ee); /** + * @internal * @defgroup Ecore_Evas_Ews Ecore_Evas Single Process Windowing System. + * @ingroup Ecore_Evas_Group * * These are global scope functions to manage the EWS to be used by * ecore_evas_ews_new(). @@ -1923,156 +2254,163 @@ EAPI void ecore_evas_x11_shape_input_apply(Ecore_Evas *ee); */ /** - * Sets the engine to be used by the backing store engine. + * @brief Sets the engine to be used by the backing store engine. + * @since 1.1 * - * @param engine The engine to be set. - * @param options The options of the engine to be set. - * @return @c EINA_TRUE on success, @c EINA_FALSE if ews is already in use. - * @since 1.1 + * @param[in] engine The engine to be set + * @param[in] options The options of the engine to be set + * @return @c EINA_TRUE if the engine is set successfully, \n + * otherwise @c EINA_FALSE if ews is already in use */ EAPI Eina_Bool ecore_evas_ews_engine_set(const char *engine, const char *options); /** - * Reconfigure the backing store used. + * @brief Reconfigures the backing store used. + * @since 1.1 * - * @param x The X coordinate to be used. - * @param y The Y coordinate to be used. - * @param w The width of the Ecore_Evas to setup. - * @param h The height of the Ecore_Evas to setup. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * @since 1.1 + * @param[in] x The X coordinate to be used + * @param[in] y The Y coordinate to be used + * @param[in] w The width of the Ecore_Evas to setup + * @param[in] h The height of the Ecore_Evas to setup + * @return @c EINA_TRUE if the backing store is reconfigured successfully, \n + * otherwise @c EINA_FALSE on failure */ EAPI Eina_Bool ecore_evas_ews_setup(int x, int y, int w, int h); /** - * Return the internal backing store in use. + * @brief Gets the internal backing store in use. + * @since 1.1 * - * @return The internal backing store in use. - * @note this will forced it to be created, making future calls to - * ecore_evas_ews_engine_set() void. + * @remarks This forces it to be created, making future calls to + * ecore_evas_ews_engine_set() void. * + * @return The internal backing store in use * @see ecore_evas_ews_evas_get() - * @since 1.1 */ EAPI Ecore_Evas *ecore_evas_ews_ecore_evas_get(void); /** - * Return the internal backing store in use. + * @brief Gets the internal backing store in use. + * @since 1.1 * - * @return The internal backing store in use. - * @note this will forced it to be created, making future calls to - * ecore_evas_ews_engine_set() void. + * @remarks This forces it to be created, making future calls to + * ecore_evas_ews_engine_set() void. * + * @return The internal backing store in use * @see ecore_evas_ews_ecore_evas_get() - * @since 1.1 */ EAPI Evas *ecore_evas_ews_evas_get(void); /** - * Get the current background. + * @brief Gets the current background. + * + * @return The background object + * @see ecore_evas_ews_background_set() */ EAPI Evas_Object *ecore_evas_ews_background_get(void); /** - * Set the current background, must be created at evas ecore_evas_ews_evas_get() + * @brief Sets the current background. + * @details This must be created at evas ecore_evas_ews_evas_get(). * - * It will be kept at lowest layer (EVAS_LAYER_MIN) and below - * everything else. You can set any object, default is a black - * rectangle. + * @remarks It is kept at lowest layer (EVAS_LAYER_MIN) and below + * everything else. You can set any object, default is a black + * rectangle. * - * @note previous object will be deleted! - * @param o The Evas_Object for which to set the background. + * @remarks The previous object is deleted + * @param[in] o The Evas_Object for which to set the background */ EAPI void ecore_evas_ews_background_set(Evas_Object *o); /** - * Return all Ecore_Evas* created by EWS. + * @brief Gets all Ecore_Evas* created by EWS. + * @since 1.1 * - * @return An eina list of Ecore_evases. - e @note Do not change the returned list or its contents. - * @since 1.1 + * @remarks Do not change the returned list or its contents. + * + * @return An eina list of Ecore_evases */ EAPI const Eina_List *ecore_evas_ews_children_get(void); /** - * Set the identifier of the manager taking care of internal windows. + * @brief Sets the identifier of the manager taking care of internal windows. + * @since 1.1 * - * The ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE event is issued. Consider - * handling it to know if you should stop handling events yourself - * (ie: another manager took over) + * @remarks The ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE event is issued. Consider + * handling it to know if you should stop handling events yourself + * (that is, another manager took over). * - * @param manager any unique identifier address. + * @param[in] manager A unique identifier address * * @see ecore_evas_ews_manager_get() - * @since 1.1 */ EAPI void ecore_evas_ews_manager_set(const void *manager); /** - * Get the identifier of the manager taking care of internal windows. + * @brief Gets the identifier of the manager taking care of internal windows. + * @since 1.1 * - * @return the value set by ecore_evas_ews_manager_set() - * @since 1.1 + * @return The value set by ecore_evas_ews_manager_set() */ EAPI const void *ecore_evas_ews_manager_get(void); -EAPI extern int ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE; /**< manager was changed @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_ADD; /**< window was created @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_DEL; /**< window was deleted, pointer is already invalid but may be used as reference for further cleanup work. @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_RESIZE; /**< window was resized @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_MOVE; /**< window was moved @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_SHOW; /**< window become visible @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_HIDE; /**< window become hidden @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_FOCUS; /**< window was focused @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_UNFOCUS; /**< window lost focus @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_RAISE; /**< window was raised @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_LOWER; /**< window was lowered @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_ACTIVATE; /**< window was activated @since 1.1 */ - -EAPI extern int ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE; /**< window minimized/iconified changed @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE; /**< window maximized changed @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_LAYER_CHANGE; /**< window layer changed @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE; /**< window fullscreen changed @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE; /**< some other window property changed (title, name, class, alpha, transparent, shaped...) @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE; /**< Manager is changed @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_ADD; /**< Window is created @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_DEL; /**< Window is deleted, pointer is already invalid but may be used as reference for further cleanup work. @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_RESIZE; /**< Window is resized @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_MOVE; /**< Window is moved @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_SHOW; /**< Window becomes visible @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_HIDE; /**< Window becomes hidden @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_FOCUS; /**< Window is focused @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_UNFOCUS; /**< Window lost focus @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_RAISE; /**< Window is raised @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_LOWER; /**< Window is lowered @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_ACTIVATE; /**< Window is activated @since 1.1 */ + +EAPI extern int ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE; /**< Window minimized or iconified changed @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE; /**< Window maximized changed @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_LAYER_CHANGE; /**< Window layer changed @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE; /**< Window fullscreen changed @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE; /**< Some other window property changed (title, name, class, alpha, transparent, shaped etc) @since 1.1 */ /** * @} */ /** + * @internal * @defgroup Ecore_Evas_Extn External plug/socket infrastructure to remote canvases + * @ingroup Ecore_Evas_Group * - * These functions allow 1 process to create a "socket" was pluged into which another + * These functions allow one process to create a "socket" that is plugged into which another * process can create a "plug" remotely to plug into. - * Socket can provides content for several plugs. + * Socket can provide content for several plugs. * This is best for small sized objects (about the size range - * of a small icon up to a few large icons). Sine the plug is actually an - * image object, you can fetch the pixel data + * of a small icon up to a few large icons). Since the plug is actually an + * image object, you can fetch the pixel data. * * @since 1.2 * @{ */ -EAPI extern int ECORE_EVAS_EXTN_CLIENT_ADD; /**< this event is received when a plug has connected to an extn socket @since 1.2 */ -EAPI extern int ECORE_EVAS_EXTN_CLIENT_DEL; /**< this event is received when a plug has disconnected from an extn socket @since 1.2 */ +EAPI extern int ECORE_EVAS_EXTN_CLIENT_ADD; /**< This event is received when a plug has connected to an extn socket @since 1.2 */ +EAPI extern int ECORE_EVAS_EXTN_CLIENT_DEL; /**< This event is received when a plug has disconnected from an extn socket @since 1.2 */ /** - * @brief Create a new Ecore_Evas canvas for the new external ecore evas socket + * @brief Creates a new Ecore_Evas canvas for the new external ecore evas socket. * - * @param w The width of the canvas, in pixels - * @param h The height of the canvas, in pixels - * @return A new @c Ecore_Evas instance or @c NULL, on failure + * @since 1.2 * - * This creates a new extn_socket canvas wrapper, with image data array - * @b bound to the ARGB format, 8 bits per pixel. + * @remarks This function creates a new extn_socket canvas wrapper, with image data array + * @b bound to the ARGB format, 8 bits per pixel. * - * If creation is successful, an Ecore_Evas handle is returned or @c NULL if - * creation fails. Also focus, show, hide etc. callbacks will also be called - * if the plug object is shown, or already visible on connect, or if it is - * hidden later, focused or unfocused. + * @remarks If creation is successful, an Ecore_Evas handle is returned or @c NULL if + * creation fails. Also callbacks such as focus, show, and hide are also called + * if the plug object is shown, or already visible on connect, or if it is + * hidden later, focused or unfocused. * - * This function has to be flowed by ecore_evas_extn_socket_listen(), - * for starting ecore ipc service. + * @remarks This function has to be flowed by ecore_evas_extn_socket_listen(), + * for starting ecore ipc service. * * @code * Eina_Bool res = EINA_FALSE; @@ -2093,12 +2431,12 @@ EAPI extern int ECORE_EVAS_EXTN_CLIENT_DEL; /**< this event is received when a p * if (!res) return; * @endcode * - * When a client(plug) connects, you will get the ECORE_EVAS_EXTN_CLIENT_ADD event - * in the ecore event queue, with event_info being the image object pointer - * passed as a void pointer. When a client disconnects you will get the - * ECORE_EVAS_EXTN_CLIENT_DEL event. + * @remarks When a client(plug) connects, you get the ECORE_EVAS_EXTN_CLIENT_ADD event + * in the ecore event queue, with event_info being the image object pointer + * passed as a void pointer. When a client disconnects you get the + * ECORE_EVAS_EXTN_CLIENT_DEL event. * - * You can set up event handles for these events as follows: + * @remarks You can set up event handles for these events as follows: * * @code * static void client_add_cb(void *data, int event, void *event_info) @@ -2124,102 +2462,172 @@ EAPI extern int ECORE_EVAS_EXTN_CLIENT_DEL; /**< this event is received when a p * } * @endcode * - * Note that events come in later after the event happened. You may want to be - * careful as data structures you had associated with the image object - * may have been freed after deleting, but the object may still be around - * awating cleanup and thus still be valid.You can change the size with something like: + * @remarks Note that events come in later after the event happened. You may want to be + * careful as data structures you had associated with the image object + * may have been freed after deleting, but the object may still be around + * awaiting cleanup and thus still be valid. + * + * @param[in] w The width of the canvas, in pixels + * @param[in] h The height of the canvas, in pixels + * @return A new @c Ecore_Evas instance, \n + * otherwise @c NULL on failure * * @see ecore_evas_extn_socket_listen() * @see ecore_evas_extn_plug_new() * @see ecore_evas_extn_plug_object_data_lock() - * @see ecore_evas_extn_plug_object_data_unlock() - * - * @since 1.2 + * @see ecore_evas_extn_plug_object_data_unlock() */ EAPI Ecore_Evas *ecore_evas_extn_socket_new(int w, int h); /** - * @brief Create a socket to provide the service for external ecore evas - * socket. + * @brief Creates a socket to provide the service for external ecore evas socket. * - * @param ee The Ecore_Evas. - * @param svcname The name of the service to be advertised. ensure that it is - * unique (when combined with @p svcnum) otherwise creation may fail. - * @param svcnum A number (any value, @c 0 being the common default) to - * differentiate multiple instances of services with the same name. - * @param svcsys A boolean that if true, specifies to create a system-wide - * service all users can connect to, otherwise the service is private to the - * user ide that created the service. - * @return @c EINA_TRUE if creation is successful, @c EINA_FALSE if it does - * not. - * - * This creates socket specified by @p svcname, @p svcnum and @p svcsys. If - * creation is successful, @c EINA_TRUE is returned or @c EINA_FALSE if - * creation fails. + * @details This creates socket specified by @a svcname, @a svcnum and @a svcsys. If + * creation is successful, @c EINA_TRUE is returned or @c EINA_FALSE if + * creation fails. + * + * @since 1.2 + * + * @param[in] ee The Ecore_Evas + * @param[in] svcname The name of the service to be advertised \n + * Ensure that it is unique (when combined with @a svcnum). + * Otherwise creation may fail. + * @param[in] svcnum A number (any value, @c 0 being the common default) to + * differentiate multiple instances of services with the same name + * @param[in] svcsys Set @c EINA_TRUE to create a system-wide service all users can connect to, \n + * otherwise set @c EINA_FALSE if the service should be private to the + * user ID that created the service + * @return @c EINA_TRUE if created successfully, \n + * otherwise @c EINA_FALSE on failure * * @see ecore_evas_extn_socket_new() * @see ecore_evas_extn_plug_new() * @see ecore_evas_extn_plug_object_data_lock() * @see ecore_evas_extn_plug_object_data_unlock() - * - * @since 1.2 */ EAPI Eina_Bool ecore_evas_extn_socket_listen(Ecore_Evas *ee, const char *svcname, int svcnum, Eina_Bool svcsys); /** - * @brief Lock the pixel data so the socket cannot change it + * @brief Grabs a pointer to the actual pixels array of a given + * external ecore evas socket. + * + * @since 1.8 + * + * @param[in] ee The Ecore_Evas + * @return The pixel data + */ +EAPI void *ecore_evas_extn_socket_pixels_get(Ecore_Evas *ee); + +/** + * @brief Marks a region of the extn_socket canvas that has been updated. + * + * @since 1.8 + * + * @param[in] ee The Ecore_Evas + * @param[in] x The X-offset of the region to be updated + * @param[in] y The Y-offset of the region to be updated + * @param[in] w The width of the region to be updated + * @param[in] h The height of the region to be updated + */ +EAPI void ecore_evas_extn_socket_update_add(Ecore_Evas *ee, int x, int y, int w, int h); + +/** + * @brief Lock the pixel data so the plug cannot change it + * + * @param[in] ee The Ecore_Evas. + * + * @see ecore_evas_extn_socket_new() + * @see ecore_evas_extn_socket_unlock() + * + * @since 1.8 + */ +EAPI void ecore_evas_extn_socket_lock(Ecore_Evas *ee); + +/** + * @brief Unlock the pixel data so the plug can change it again + * + * @param[in] ee The Ecore_Evas. + * + * @see ecore_evas_extn_socket_new() + * @see ecore_evas_extn_socket_lock() + * + * @since 1.8 + */ +EAPI void ecore_evas_extn_socket_unlock(Ecore_Evas *ee); + +/** + * @brief Set the blocking about mouse events to Ecore Evas. + * + * @param ee The Ecore_Evas. + * @param events_block The blocking about mouse events. + * + * @see ecore_evas_extn_socket_events_block_get() + * + * @since 1.11 + */ +EINA_DEPRECATED EAPI void ecore_evas_extn_socket_events_block_set(Ecore_Evas *ee, Eina_Bool events_block); + +/** + * @brief Get the blocking about mouse events to Ecore Evas. + * + * @param ee The Ecore_Evas. + + * @return The blocking about mouse events. + * + * @see ecore_evas_extn_socket_events_block_set() + * + * @since 1.11 + */ +EINA_DEPRECATED EAPI Eina_Bool ecore_evas_extn_socket_events_block_get(Ecore_Evas *ee); + +/** + * @brief Locks the pixel data so the socket cannot change it. + * @since 1.2 * - * @param obj The image object returned by ecore_evas_extn_plug_new() to lock + * @remarks You may need to get the image pixel data with evas_object_image_data_get() + * from the image object, but need to ensure that it does not change while + * you are using the data. This function lets you set an advisory lock on the + * image data so the external plug process does not render to it or alter it. * - * You may need to get the image pixel data with evas_object_image_data_get() - * from the image object, but need to ensure that it does not change while - * you are using the data. This function lets you set an advisory lock on the - * image data so the external plug process will not render to it or alter it. + * @remarks You should only hold the lock for just as long as you need to read out the + * image data or otherwise deal with it, and then unlock it with + * ecore_evas_extn_plug_object_data_unlock(). Keeping a lock over more than + * one iteration of the main ecore loop is problematic, so avoid it. Also + * forgetting to unlock may cause the socket process to freeze and thus create + * odd behavior. * - * You should only hold the lock for just as long as you need to read out the - * image data or otherwise deal with it, and then unlock it with - * ecore_evas_extn_plug_object_data_unlock(). Keeping a lock over more than - * 1 iteration of the main ecore loop will be problematic, so avoid it. Also - * forgetting to unlock may cause the socket process to freeze and thus create - * odd behavior. + * @param[in] obj The image object returned by ecore_evas_extn_plug_new() to lock * * @see ecore_evas_extn_plug_new() * @see ecore_evas_extn_plug_object_data_unlock() - * - * @since 1.2 */ EAPI void ecore_evas_extn_plug_object_data_lock(Evas_Object *obj); /** - * @brief Unlock the pixel data so the socket can change it again. + * @brief Unlocks the pixel data so the socket can change it again. * - * @param obj The image object returned by ecore_evas_extn_plug_new() to unlock + * @details This function unlocks after an advisor lock has been taken by + * ecore_evas_extn_plug_object_data_lock(). + * @since 1.2 * - * This unlocks after an advisor lock has been taken by - * ecore_evas_extn_plug_object_data_lock(). + * @param[in] obj The image object returned by ecore_evas_extn_plug_new() to unlock * * @see ecore_evas_extn_plug_new() * @see ecore_evas_extn_plug_object_data_lock() - * - * @since 1.2 */ EAPI void ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj); /** - * @brief Create a new external ecore evas plug - * - * @param ee_target The Ecore_Evas containing the canvas in which the new image object will live. - * @return An evas image object that will contain the image output of a socket. - * - * This creates an image object that will contain the output of another - * processes socket canvas when it connects. All input will be sent back to - * this process as well, effectively swallowing or placing the socket process - * in the canvas of the plug process in place of the image object. The image - * object by default is created to be filled (equivalent of - * evas_object_image_filled_add() on creation) so image content will scale - * to fill the image unless otherwise reconfigured. The Ecore_Evas size - * of the plug is the master size and determines size in pixels of the - * plug canvas. You can change the size with something like: + * @brief Creates a new external ecore evas plug. + * @details This creates an image object that contains the output of another + * processes socket canvas when it connects. All input is sent back to + * this process as well, effectively swallowing or placing the socket process + * in the canvas of the plug process in place of the image object. The image + * object by default is created to be filled (equivalent of + * evas_object_image_filled_add() on creation) so image content scales + * to fill the image unless otherwise reconfigured. The Ecore_Evas size + * of the plug is the master size and determines size in pixels of the + * plug canvas. You can change the size with something like: * * @code * Eina_Bool res = EINA_FALSE; @@ -2230,32 +2638,81 @@ EAPI void ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj); * ecore_evas_resize(ee, 240, 400); * @endcode * + * @since 1.2 + * + * @param[in] ee_target The Ecore_Evas containing the canvas in which the new image object lives + * @return An evas image object that contains the image output of a socket + * * @see ecore_evas_extn_socket_new() * @see ecore_evas_extn_plug_connect() - * @since 1.2 */ EAPI Evas_Object *ecore_evas_extn_plug_new(Ecore_Evas *ee_target); /** - * @brief Connect an external ecore evas plug to service provided by external - * ecore evas socket. + * @brief Connects an external ecore evas plug to service provided by external + * ecore evas socket. * - * @param obj The Ecore_Evas containing the canvas in which the new image - * object will live. - * @param svcname The service name to connect to set up by the socket. - * @param svcnum The service number to connect to (set up by socket). - * @param svcsys Boolean to set if the service is a system one or not (set up - * by socket). - * @return @c EINA_TRUE if creation is successful, @c EINA_FALSE if it does - * not. + * @since 1.2 * - * @see ecore_evas_extn_plug_new() + * @param[in] obj The Ecore_Evas containing the canvas in which the new image + * object lives + * @param[in] svcname The service name to connect to set up by the socket + * @param[in] svcnum The service number to connect to (set up by socket) + * @param[in] svcsys Set @c EINA_TRUE to if the service is a system one, \n + * otherwise set @c EINA_FALSE if it is not a system one (set up by socket) + * @return @c EINA_TRUE if created successfully, + * otherwise @c EINA_FALSE on failure * - * @since 1.2 + * @see ecore_evas_extn_plug_new() */ EAPI Eina_Bool ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys); /** + * @brief Retrieve the Visual used for pixmap creation + * + * @since 1.8 + * + * @param[in] ee The Ecore_Evas containing the pixmap + * + * @return The Visual which was used when creating the pixmap + * + * @warning If and when this function is called depends on the underlying + * windowing system. This function should only be called if the Ecore_Evas was + * created using @c ecore_evas_software_x11_pixmap_new or @c ecore_evas_gl_x11_pixmap_new + */ +EAPI void *ecore_evas_pixmap_visual_get(const Ecore_Evas *ee); + +/** + * @brief Retrieve the Colormap used for pixmap creation + * + * @since 1.8 + * + * @param[in] ee The Ecore_Evas containing the pixmap + * + * @return The Colormap which was used when creating the pixmap + * + * @warning If and when this function is called depends on the underlying + * windowing system. This function should only be called if the Ecore_Evas was + * created using @c ecore_evas_software_x11_pixmap_new or @c ecore_evas_gl_x11_pixmap_new + */ +EAPI unsigned long ecore_evas_pixmap_colormap_get(const Ecore_Evas *ee); + +/** + * @brief Retrieve the depth used for pixmap creation + * + * @since 1.8 + * + * @param[in] ee The Ecore_Evas containing the pixmap + * + * @return The depth which was used when creating the pixmap + * + * @warning If and when this function is called depends on the underlying + * windowing system. This function should only be called if the Ecore_Evas was + * created using @c ecore_evas_software_x11_pixmap_new or @c ecore_evas_gl_x11_pixmap_new + */ +EAPI int ecore_evas_pixmap_depth_get(const Ecore_Evas *ee); + +/** * @} */ diff --git a/src/lib/ecore_evas/Makefile.am b/src/lib/ecore_evas/Makefile.am index cd7f37b..977cb00 100644 --- a/src/lib/ecore_evas/Makefile.am +++ b/src/lib/ecore_evas/Makefile.am @@ -132,6 +132,11 @@ ecore_evas_wayland_shm.c \ ecore_evas_wayland_egl.c \ ecore_evas_extn.c +if BUILD_ECORE_WAYLAND +libecore_evas_la_SOURCES += \ +ecore_evas_wayland_common.c +endif + libecore_evas_la_LIBADD = \ $(ECORE_X_LIB) \ $(ECORE_FB_LIB) \ @@ -156,5 +161,18 @@ $(top_builddir)/src/lib/ecore/libecore.la \ libecore_evas_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ +# Converter +ECORE_EVAS_CONVERT_PROG = ecore_evas_convert + +ecore_evas_convert_SOURCES = ecore_evas_convert.c +ecore_evas_convert_LDADD = libecore_evas.la \ +$(top_builddir)/src/lib/ecore/libecore.la \ +@EINA_LIBS@ @EVAS_LIBS@ + +ecore_evas_convert_DEPENDENCIES = libecore_evas.la \ +$(top_builddir)/src/lib/ecore/libecore.la + +bin_PROGRAMS = $(ECORE_EVAS_CONVERT_PROG) + EXTRA_DIST = \ ecore_evas_private.h diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c index 7789da7..8f69d74 100644 --- a/src/lib/ecore_evas/ecore_evas.c +++ b/src/lib/ecore_evas/ecore_evas.c @@ -218,6 +218,21 @@ ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine) }; } +static void +_ecore_evas_fork_cb(void *data __UNUSED__) +{ + int fd; + + if (_ecore_evas_async_events_fd) + ecore_main_fd_handler_del(_ecore_evas_async_events_fd); + fd = evas_async_events_fd_get(); + if (fd >= 0) + _ecore_evas_async_events_fd = + ecore_main_fd_handler_add(fd, ECORE_FD_READ, + _ecore_evas_async_events_fd_handler, NULL, + NULL, NULL); +} + EAPI int ecore_evas_init(void) { @@ -240,12 +255,13 @@ ecore_evas_init(void) goto shutdown_ecore; } + ecore_fork_reset_callback_add(_ecore_evas_fork_cb, NULL); fd = evas_async_events_fd_get(); - if (fd > 0) - _ecore_evas_async_events_fd = ecore_main_fd_handler_add(fd, - ECORE_FD_READ, - _ecore_evas_async_events_fd_handler, NULL, - NULL, NULL); + if (fd >= 0) + _ecore_evas_async_events_fd = + ecore_main_fd_handler_add(fd, ECORE_FD_READ, + _ecore_evas_async_events_fd_handler, NULL, + NULL, NULL); ecore_evas_idle_enterer = ecore_idle_enterer_add(_ecore_evas_idle_enter, NULL); @@ -308,6 +324,8 @@ ecore_evas_shutdown(void) if (_ecore_evas_async_events_fd) ecore_main_fd_handler_del(_ecore_evas_async_events_fd); + + ecore_fork_reset_callback_del(_ecore_evas_fork_cb, NULL); eina_log_domain_unregister(_ecore_evas_log_dom); _ecore_evas_log_dom = -1; @@ -588,7 +606,7 @@ static Ecore_Evas * _ecore_evas_constructor_wayland_shm(int x, int y, int w, int h, const char *extra_options) { char *disp_name = NULL; - unsigned int frame = 0, parent = 0; + unsigned int frame = 1, parent = 0; Ecore_Evas *ee; _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name); @@ -606,7 +624,7 @@ static Ecore_Evas * _ecore_evas_constructor_wayland_egl(int x, int y, int w, int h, const char *extra_options) { char *disp_name = NULL; - unsigned int frame = 0, parent = 0; + unsigned int frame = 1, parent = 0; Ecore_Evas *ee; _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name); @@ -875,6 +893,7 @@ ecore_evas_ecore_evas_get(const Evas *e) EAPI void ecore_evas_free(Ecore_Evas *ee) { + if (!ee) return; if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) { ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, @@ -1942,6 +1961,314 @@ ecore_evas_profile_get(const Ecore_Evas *ee) return ee->prop.profile; } +EAPI Eina_Bool +ecore_evas_wm_rotation_supported_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_wm_rotation_supported_get"); + return EINA_FALSE; + } + return ee->prop.wm_rot.supported; +} + +EAPI void +ecore_evas_wm_rotation_preferred_rotation_set(Ecore_Evas *ee, int rotation) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_wm_rotation_preferred_rotation_set"); + return; + } + if (rotation != -1) + { + if (ee->prop.wm_rot.available_rots) + { + Eina_Bool found = EINA_FALSE; + unsigned int i; + for (i = 0; i < ee->prop.wm_rot.count; i++) + { + if (ee->prop.wm_rot.available_rots[i] == rotation) + { + found = EINA_TRUE; + break; + } + } + if (!found) return; + } + } + IFC(ee, fn_wm_rot_preferred_rotation_set) (ee, rotation); + IFE; +} + +EAPI int +ecore_evas_wm_rotation_preferred_rotation_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_wm_rotation_preferred_rotation_get"); + return 0; + } + return ee->prop.wm_rot.preferred_rot; +} + +EAPI void +ecore_evas_wm_rotation_available_rotations_set(Ecore_Evas *ee, const int *rotations, unsigned int count) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_wm_rotation_available_rotations_set"); + return; + } + IFC(ee, fn_wm_rot_available_rotations_set) (ee, rotations, count); + IFE; +} + +EAPI Eina_Bool +ecore_evas_wm_rotation_available_rotations_get(const Ecore_Evas *ee, int **rotations, unsigned int *count) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_wm_rotation_available_rotations_get"); + return EINA_FALSE; + } + if ((!rotations) || (!count)) + return EINA_FALSE; + + if ((!ee->prop.wm_rot.available_rots) || (ee->prop.wm_rot.count == 0)) + return EINA_FALSE; + + *rotations = calloc(ee->prop.wm_rot.count, sizeof(int)); + if (!*rotations) return EINA_FALSE; + + memcpy(*rotations, ee->prop.wm_rot.available_rots, sizeof(int) * ee->prop.wm_rot.count); + *count = ee->prop.wm_rot.count; + + return EINA_TRUE; +} + +EAPI void +ecore_evas_wm_rotation_manual_rotation_done_set(Ecore_Evas *ee, Eina_Bool set) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_wm_rotation_manual_rotation_done_set"); + return; + } + + if (!ee->prop.wm_rot.app_set) + { + return; + } + + IFC(ee, fn_wm_rot_manual_rotation_done_set) (ee, set); + IFE; +} + +EAPI Eina_Bool +ecore_evas_wm_rotation_manual_rotation_done_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_wm_rotation_manual_rotation_done_get"); + return EINA_FALSE; + } + + if (!ee->prop.wm_rot.app_set) + { + return EINA_FALSE; + } + + return ee->prop.wm_rot.manual_mode.set; +} + +EAPI void +ecore_evas_wm_rotation_manual_rotation_done(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_wm_rotation_manual_rotation_done"); + return; + } + + if (!ee->prop.wm_rot.app_set) + { + return; + } + + IFC(ee, fn_wm_rot_manual_rotation_done) (ee); + IFE; +} + +EAPI const Eina_List * +ecore_evas_aux_hints_supported_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_aux_hints_supported_get"); + return NULL; + } + return ee->prop.aux_hint.supported_list; +} + +EAPI Eina_List * +ecore_evas_aux_hints_allowed_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_aux_hints_allowed_get"); + return NULL; + } + + Eina_List *list = NULL, *ll; + Ecore_Evas_Aux_Hint *aux; + EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux) + { + if ((aux->allowed) && !(aux->notified)) + { + list = eina_list_append(list, aux->id); + } + } + + return list; +} + +EAPI int +ecore_evas_aux_hint_add(Ecore_Evas *ee, const char *hint, const char *val) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_aux_hint_add"); + return -1; + } + + Eina_List *ll; + char *supported_hint; + EINA_LIST_FOREACH(ee->prop.aux_hint.supported_list, ll, supported_hint) + { + if (!strncmp(supported_hint, hint, strlen(hint))) + { + Ecore_Evas_Aux_Hint *aux= (Ecore_Evas_Aux_Hint *)calloc(1, sizeof(Ecore_Evas_Aux_Hint)); + if (aux) + { + aux->id = ee->prop.aux_hint.id; + aux->hint = eina_stringshare_add(hint); + aux->val = eina_stringshare_add(val); + + ee->prop.aux_hint.hints = eina_list_append(ee->prop.aux_hint.hints, aux); + + Eina_Strbuf *buf = _ecore_evas_aux_hints_string_get(ee); + if (buf) + { + if (ee->engine.func->fn_aux_hints_set) + ee->engine.func->fn_aux_hints_set(ee, eina_strbuf_string_get(buf)); + + eina_strbuf_free(buf); + + ee->prop.aux_hint.id++; + + return aux->id; + } + + eina_stringshare_del(aux->hint); + eina_stringshare_del(aux->val); + free(aux); + } + break; + } + } + + return -1; +} + +EAPI Eina_Bool +ecore_evas_aux_hint_del(Ecore_Evas *ee, const int id) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_aux_hint_del"); + return EINA_FALSE; + } + + Eina_List *ll; + Ecore_Evas_Aux_Hint *aux; + EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux) + { + if (id == aux->id) + { + ee->prop.aux_hint.hints = eina_list_remove(ee->prop.aux_hint.hints, aux); + + eina_stringshare_del(aux->hint); + eina_stringshare_del(aux->val); + free(aux); + + Eina_Strbuf *buf = _ecore_evas_aux_hints_string_get(ee); + if (buf) + { + if (ee->engine.func->fn_aux_hints_set) + ee->engine.func->fn_aux_hints_set(ee, eina_strbuf_string_get(buf)); + + eina_strbuf_free(buf); + + return EINA_TRUE; + } + break; + } + } + + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_evas_aux_hint_val_set(Ecore_Evas *ee, const int id, const char *val) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_aux_hint_val_set"); + return EINA_FALSE; + } + + Eina_List *ll; + Ecore_Evas_Aux_Hint *aux; + EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux) + { + if (id == aux->id) + { + eina_stringshare_del(aux->val); + aux->val = eina_stringshare_add(val); + aux->allowed = 0; + aux->notified = 0; + + Eina_Strbuf *buf = _ecore_evas_aux_hints_string_get(ee); + if (buf) + { + if (ee->engine.func->fn_aux_hints_set) + ee->engine.func->fn_aux_hints_set(ee, eina_strbuf_string_get(buf)); + + eina_strbuf_free(buf); + + return EINA_TRUE; + } + break; + } + } + + return EINA_TRUE; +} + EAPI void ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool on) { @@ -2264,6 +2591,60 @@ ecore_evas_manual_render(Ecore_Evas *ee) } EAPI void +ecore_evas_msg_parent_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_msg_parent_send"); + return; + } + DBG("Msg(to parent): ee=%p msg_domain=%x msg_id=%x size=%d", ee, msg_domain, msg_id, size); + IFC(ee, fn_msg_parent_send) (ee, msg_domain, msg_id, data, size); + IFE; +} + +EAPI void +ecore_evas_msg_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_msg_send"); + return; + } + DBG("Msg: ee=%p msg_domain=%x msg_id=%x size=%d", ee, msg_domain, msg_id, size); + IFC(ee, fn_msg_send) (ee, msg_domain, msg_id, data, size); + IFE; +} + +EAPI void +ecore_evas_callback_msg_parent_handle_set(Ecore_Evas *ee, void (*func_parent_handle)(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_msg_parent_handle"); + return; + } + DBG("Msg Parent handle: ee=%p", ee); + ee->func.fn_msg_parent_handle = func_parent_handle; +} + +EAPI void +ecore_evas_callback_msg_handle_set(Ecore_Evas *ee, void (*func_handle)(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_msg_handle"); + return; + } + DBG("Msg handle: ee=%p", ee); + ee->func.fn_msg_handle = func_handle; +} + +EAPI void ecore_evas_comp_sync_set(Ecore_Evas *ee, Eina_Bool do_sync) { if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) @@ -2516,6 +2897,12 @@ _ecore_evas_free(Ecore_Evas *ee) ee->prop.name = NULL; if (ee->prop.clas) free(ee->prop.clas); ee->prop.clas = NULL; + if (ee->prop.wm_rot.available_rots) free(ee->prop.wm_rot.available_rots); + ee->prop.wm_rot.available_rots = NULL; + if (ee->prop.wm_rot.manual_mode.timer) + ecore_timer_del(ee->prop.wm_rot.manual_mode.timer); + ee->prop.wm_rot.manual_mode.timer = NULL; + _ecore_evas_aux_hint_free(ee); if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object); ee->prop.cursor.object = NULL; if (ee->evas) evas_free(ee->evas); @@ -2524,6 +2911,7 @@ _ecore_evas_free(Ecore_Evas *ee) ee->driver = NULL; if (ee->engine.idle_flush_timer) ecore_timer_del(ee->engine.idle_flush_timer); + ee->engine.idle_flush_timer = NULL; if (ee->engine.func->fn_free) ee->engine.func->fn_free(ee); if (ee->registered) { @@ -2536,11 +2924,10 @@ _ecore_evas_free(Ecore_Evas *ee) static Eina_Bool _ecore_evas_cb_idle_flush(void *data) { - Ecore_Evas *ee; + Ecore_Evas *ee = data; - ee = (Ecore_Evas *)data; - evas_render_idle_flush(ee->evas); ee->engine.idle_flush_timer = NULL; + evas_render_idle_flush(ee->evas); return ECORE_CALLBACK_CANCEL; } @@ -2773,6 +3160,48 @@ ecore_evas_input_event_unregister(Ecore_Evas *ee) ecore_event_window_unregister((Ecore_Window)ee); } +Eina_Strbuf * +_ecore_evas_aux_hints_string_get(Ecore_Evas *ee) +{ + Eina_Strbuf *buf = eina_strbuf_new(); + if (buf) + { + if (eina_list_count(ee->prop.aux_hint.hints) > 0) + { + Eina_List *l; + Ecore_Evas_Aux_Hint *aux; + int i = 0; + + EINA_LIST_FOREACH(ee->prop.aux_hint.hints, l, aux) + { + /* add delimiter */ + if (i > 0) eina_strbuf_append_char(buf, ','); + eina_strbuf_append_printf(buf, "%d:%s:%s", aux->id, aux->hint, aux->val); + i++; + } + } + } + return buf; +} + +void +_ecore_evas_aux_hint_free(Ecore_Evas *ee) +{ + char *hint; + EINA_LIST_FREE(ee->prop.aux_hint.supported_list, hint) + { + eina_stringshare_del(hint); + } + + Ecore_Evas_Aux_Hint *aux; + EINA_LIST_FREE(ee->prop.aux_hint.hints, aux) + { + eina_stringshare_del(aux->hint); + eina_stringshare_del(aux->val); + free(aux); + } +} + #if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined (BUILD_ECORE_EVAS_WAYLAND_EGL) EAPI void ecore_evas_wayland_resize(Ecore_Evas *ee, int location) @@ -2796,17 +3225,13 @@ EAPI void ecore_evas_wayland_move(Ecore_Evas *ee, int x, int y) { if (!ee) return; - if (!strcmp(ee->driver, "wayland_shm")) - { -#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM - _ecore_evas_wayland_shm_move(ee, x, y); -#endif - } - else if (!strcmp(ee->driver, "wayland_egl")) + if (!strncmp(ee->driver, "wayland", 7)) { -#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL - _ecore_evas_wayland_egl_move(ee, x, y); -#endif + if (ee->engine.wl.win) + { + ee->engine.wl.win->moving = EINA_TRUE; + ecore_wl_window_move(ee->engine.wl.win, x, y); + } } } @@ -2827,12 +3252,9 @@ ecore_evas_wayland_window_get(const Ecore_Evas *ee) } EAPI void -ecore_evas_wayland_pointer_set(Ecore_Evas *ee, int hot_x, int hot_y) +ecore_evas_wayland_pointer_set(Ecore_Evas *ee __UNUSED__, int hot_x __UNUSED__, int hot_y __UNUSED__) { - Ecore_Wl_Window *win; - win = ecore_evas_wayland_window_get(ee); - /* ecore_wl_window_pointer_set(win, ee->engine.wl.buffer, hot_x, hot_y); */ } #else @@ -2865,4 +3287,5 @@ ecore_evas_wayland_pointer_set(Ecore_Evas *ee __UNUSED__, int hot_x __UNUSED__, { } + #endif diff --git a/src/lib/ecore_evas/ecore_evas_buffer.c b/src/lib/ecore_evas/ecore_evas_buffer.c index f15436c..5859c2d 100644 --- a/src/lib/ecore_evas/ecore_evas_buffer.c +++ b/src/lib/ecore_evas/ecore_evas_buffer.c @@ -1,7 +1,6 @@ #ifdef HAVE_CONFIG_H # include #endif - // NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! #include @@ -46,6 +45,7 @@ _ecore_evas_resize(Ecore_Evas *ee, int w, int h) { Evas_Engine_Info_Buffer *einfo; int stride = 0; + int bpp = 0; if (w < 1) w = 1; if (h < 1) h = 1; @@ -62,16 +62,26 @@ _ecore_evas_resize(Ecore_Evas *ee, int w, int h) { ee->engine.buffer.pixels = evas_object_image_data_get(ee->engine.buffer.image, 1); stride = evas_object_image_stride_get(ee->engine.buffer.image); + bpp = sizeof(int); /*need to be considered*/ } else { if (ee->engine.buffer.pixels) ee->engine.buffer.free_func(ee->engine.buffer.data, ee->engine.buffer.pixels); - ee->engine.buffer.pixels = - ee->engine.buffer.alloc_func(ee->engine.buffer.data, - ee->w * ee->h * sizeof(int)); - stride = ee->w * sizeof(int); + + if (ee->engine.buffer.alloc_func) + { + ee->engine.buffer.pixels = + ee->engine.buffer.alloc_func(ee->engine.buffer.data, + ee->w * ee->h * sizeof(int)); + } + + if (stride == 0) + { + stride = ee->w * sizeof(int); + bpp = sizeof(int); + } } einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); @@ -81,6 +91,7 @@ _ecore_evas_resize(Ecore_Evas *ee, int w, int h) einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; else einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + einfo->info.dest_buffer = ee->engine.buffer.pixels; einfo->info.dest_buffer_row_bytes = stride; einfo->info.use_color_key = 0; @@ -467,6 +478,42 @@ _ecore_evas_buffer_alpha_set(Ecore_Evas *ee, int alpha) } } +static void +_ecore_evas_buffer_msg_parent_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size) +{ + Ecore_Evas *parent_ee = NULL; + parent_ee = ecore_evas_data_get(ee, "parent"); + + if (parent_ee) + { + if (parent_ee->func.fn_msg_parent_handle) + parent_ee ->func.fn_msg_parent_handle(parent_ee, msg_domain, msg_id, data, size); + } + else + { + if (ee->func.fn_msg_parent_handle) + ee ->func.fn_msg_parent_handle(ee, msg_domain, msg_id, data, size); + } +} + +static void +_ecore_evas_buffer_msg_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size) +{ + Ecore_Evas *child_ee = NULL; + child_ee = ecore_evas_data_get(ee, "child"); + + if (child_ee) + { + if (child_ee->func.fn_msg_handle) + child_ee->func.fn_msg_handle(child_ee, msg_domain, msg_id, data, size); + } + else + { + if (ee->func.fn_msg_handle) + ee->func.fn_msg_handle(ee, msg_domain, msg_id, data, size); + } +} + static Ecore_Evas_Engine_Func _ecore_buffer_engine_func = { _ecore_evas_buffer_free, @@ -526,7 +573,16 @@ static Ecore_Evas_Engine_Func _ecore_buffer_engine_func = _ecore_evas_buffer_render, NULL, // screen_geometry_get - NULL // screen_dpi_get + NULL, // screen_dpi_get + _ecore_evas_buffer_msg_parent_send, + _ecore_evas_buffer_msg_send, + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; #endif @@ -542,19 +598,9 @@ _ecore_evas_buffer_pix_free(void *data __UNUSED__, void *pix) free(pix); } -EAPI Ecore_Evas * -ecore_evas_buffer_new(int w, int h) +static Ecore_Evas * +_ecore_evas_buffer_ecore_evas_create(int w, int h, void *alloc_func, void *free_func, const void *data, const Eina_Bool use_stride) { - return ecore_evas_buffer_allocfunc_new - (w, h, _ecore_evas_buffer_pix_alloc, _ecore_evas_buffer_pix_free, NULL); -} - -EAPI Ecore_Evas * -ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, int size), void (*free_func) (void *data, void *pix), const void *data) -{ -// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! -#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER - Evas_Engine_Info_Buffer *einfo; Ecore_Evas *ee; int rmethod; @@ -569,7 +615,9 @@ ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, i _ecore_evas_buffer_init(); ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_buffer_engine_func; + ee->engine.buffer.alloc_func = alloc_func; + ee->engine.buffer.free_func = free_func; ee->engine.buffer.data = (void *)data; @@ -595,16 +643,28 @@ ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, i ee->prop.withdrawn = 0; ee->prop.sticky = 0; - /* init evas here */ + return ee; +} + +static Eina_Bool +_ecore_evas_buffer_evas_create(Ecore_Evas* ee, int w,int h, const Eina_Bool use_stride) +{ + Evas_Engine_Info_Buffer *einfo; + int rmethod; + int buf_stride; + int buf_bpp; + + if (!ee) return EINA_FALSE; + + rmethod = evas_render_method_lookup("buffer"); + /* init evas here */ ee->evas = evas_new(); evas_data_attach_set(ee->evas, ee); evas_output_method_set(ee->evas, rmethod); evas_output_size_set(ee->evas, w, h); evas_output_viewport_set(ee->evas, 0, 0, w, h); - ee->engine.buffer.pixels = - ee->engine.buffer.alloc_func - (ee->engine.buffer.data, w * h * sizeof(int)); + ee->engine.buffer.pixels = ee->engine.buffer.alloc_func(ee->engine.buffer.data, w * h * sizeof(int)); einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); if (einfo) @@ -620,14 +680,14 @@ ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, i { ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); ecore_evas_free(ee); - return NULL; + return EINA_FALSE; } } else { ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); ecore_evas_free(ee); - return NULL; + return EINA_FALSE; } evas_key_modifier_add(ee->evas, "Shift"); evas_key_modifier_add(ee->evas, "Control"); @@ -644,7 +704,34 @@ ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, i _ecore_evas_register(ee); evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); - + + return EINA_TRUE; +} + +EAPI Ecore_Evas * +ecore_evas_buffer_new(int w, int h) +{ + return ecore_evas_buffer_allocfunc_new + (w, h, _ecore_evas_buffer_pix_alloc, _ecore_evas_buffer_pix_free, NULL); +} + +EAPI Ecore_Evas * +ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, int size), void (*free_func) (void *data, void *pix), const void *data) +{ +// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! +#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER + Ecore_Evas *ee; + + ee = _ecore_evas_buffer_ecore_evas_create(w,h,alloc_func,free_func,data,EINA_FALSE); + if (!ee) return NULL; + + /* init evas here */ + if (_ecore_evas_buffer_evas_create(ee,w,h,EINA_FALSE) == EINA_FALSE) + { + ERR("_ecore_evas_buffer_evas_create() is failed."); + ecore_evas_free(ee); + return NULL; + } return ee; #else return NULL; @@ -655,6 +742,11 @@ EAPI const void * ecore_evas_buffer_pixels_get(Ecore_Evas *ee) { #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER + if (!ee) + { + CRIT("Ecore_Evas is missing"); + return NULL; + } _ecore_evas_buffer_render(ee); return ee->engine.buffer.pixels; #else @@ -690,6 +782,8 @@ ecore_evas_object_image_new(Ecore_Evas *ee_target) int rmethod; int w = 1, h = 1; + if (!ee_target) return NULL; + rmethod = evas_render_method_lookup("buffer"); if (!rmethod) return NULL; ee = calloc(1, sizeof(Ecore_Evas)); diff --git a/src/lib/ecore_evas/ecore_evas_cocoa.c b/src/lib/ecore_evas/ecore_evas_cocoa.c index 96ea1d4..a2ec15c 100644 --- a/src/lib/ecore_evas/ecore_evas_cocoa.c +++ b/src/lib/ecore_evas/ecore_evas_cocoa.c @@ -474,7 +474,16 @@ static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func = NULL, // render NULL, - NULL // screen_dpi_get + NULL, // screen_dpi_get + NULL, + NULL, // msg_send + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; #endif diff --git a/src/lib/ecore_evas/ecore_evas_convert.c b/src/lib/ecore_evas/ecore_evas_convert.c new file mode 100644 index 0000000..8cf613e --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_convert.c @@ -0,0 +1,125 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include +#include +#include +#include +#include + +#undef EINA_LOG_DOMAIN_DEFAULT +#define EINA_LOG_DOMAIN_DEFAULT _log_dom +static int _log_dom = -1; + +const Ecore_Getopt optdesc = { + "ecore_evas_convert", + "%prog [options] ", + PACKAGE_VERSION, + "(C) 2014 Enlightenment", + "BSD with advertisement clause", + "Simple application to convert image.", + 0, + { + ECORE_GETOPT_STORE_INT('q', "quality", "define encoding quality in percent."), + ECORE_GETOPT_STORE_TRUE('c', "compress", "define if data should be compressed."), + ECORE_GETOPT_STORE_STR('e', "encoding", "define the codec (for TGV files: etc1, etc2)"), + ECORE_GETOPT_LICENSE('L', "license"), + ECORE_GETOPT_COPYRIGHT('C', "copyright"), + ECORE_GETOPT_VERSION('V', "version"), + ECORE_GETOPT_HELP('h', "help"), + ECORE_GETOPT_SENTINEL + } +}; + +int +main(int argc, char *argv[]) +{ + Ecore_Evas *ee; + Evas *e; + Evas_Object *im; + int arg_index; + int quality = -1; + int r = -1; + char *encoding = NULL; + Eina_Bool compress = 1; + Eina_Bool quit_option = EINA_FALSE; + Eina_Strbuf *flags = NULL; + + Ecore_Getopt_Value values[] = { + ECORE_GETOPT_VALUE_INT(quality), + ECORE_GETOPT_VALUE_BOOL(compress), + ECORE_GETOPT_VALUE_STR(encoding), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_NONE + }; + + eina_init(); + _log_dom = eina_log_domain_register(argv[0], EINA_COLOR_CYAN); + + ecore_init(); + ecore_evas_init(); + + arg_index = ecore_getopt_parse(&optdesc, values, argc, argv); + if (quit_option) goto end; + + if (arg_index < 0) + { + EINA_LOG_ERR("Could not parse argument."); + goto end; + } + if (arg_index + 2 != argc) + { + EINA_LOG_ERR("File not correctly specified."); + goto end; + } + + ee = ecore_evas_buffer_new(1, 1); + e = ecore_evas_get(ee); + if (!e) + { + EINA_LOG_ERR("Impossible to create a canvas to do the conversion."); + goto end; + } + + flags = eina_strbuf_new(); + eina_strbuf_append_printf(flags, "compress=%d", compress); + if (quality >= 0) + eina_strbuf_append_printf(flags, " quality=%d", quality); + if (encoding) + eina_strbuf_append_printf(flags, " encoding=%s", encoding); + + im = evas_object_image_add(e); + evas_object_image_file_set(im, argv[arg_index], NULL); + + if (evas_object_image_load_error_get(im) != EVAS_LOAD_ERROR_NONE) + { + EINA_LOG_ERR("Could not open '%s'. Error was \"%s\".", + argv[arg_index], + evas_load_error_str(evas_object_image_load_error_get(im))); + goto end; + } + + if (!evas_object_image_save(im, argv[arg_index + 1], NULL, + eina_strbuf_string_get(flags))) + { + EINA_LOG_ERR("Could not convert file to '%s'.", argv[arg_index + 1]); + goto end; + } + + r = 0; + + end: + if (flags) eina_strbuf_free(flags); + ecore_evas_shutdown(); + ecore_shutdown(); + + return r; +} diff --git a/src/lib/ecore_evas/ecore_evas_directfb.c b/src/lib/ecore_evas/ecore_evas_directfb.c index d9fb237..7e45d8b 100644 --- a/src/lib/ecore_evas/ecore_evas_directfb.c +++ b/src/lib/ecore_evas/ecore_evas_directfb.c @@ -500,7 +500,14 @@ static Ecore_Evas_Engine_Func _ecore_directfb_engine_func = NULL, // render NULL, // screen_geometry_get - NULL // screen_dpi_get + NULL, // screen_dpi_get + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; #endif diff --git a/src/lib/ecore_evas/ecore_evas_ews.c b/src/lib/ecore_evas/ecore_evas_ews.c index d6969cf..5652481 100644 --- a/src/lib/ecore_evas/ecore_evas_ews.c +++ b/src/lib/ecore_evas/ecore_evas_ews.c @@ -694,7 +694,16 @@ static const Ecore_Evas_Engine_Func _ecore_ews_engine_func = _ecore_evas_ews_render, _ecore_evas_ews_screen_geometry_get, - NULL // screen_dpi_get + NULL, // screen_dpi_get + NULL, + NULL, // msg_send + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; void diff --git a/src/lib/ecore_evas/ecore_evas_extn.c b/src/lib/ecore_evas/ecore_evas_extn.c old mode 100644 new mode 100755 index ff8db45..75d01f4 --- a/src/lib/ecore_evas/ecore_evas_extn.c +++ b/src/lib/ecore_evas/ecore_evas_extn.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include #include @@ -16,6 +42,7 @@ #include #include #include +#include #include #include "ecore_private.h" @@ -32,7 +59,11 @@ #ifdef BUILD_ECORE_EVAS_EXTN +///Jiyoun: This code will be modified after opensource fix lockup issue +#define EVAS_CALLBACK_CANVAS_OBJECT_RENDER_PRE 100 +#define EVAS_CALLBACK_CANVAS_OBJECT_RENDER_POST 101 +static void _ecore_evas_extn_plug_image_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info); typedef struct _Shmfile Shmfile; @@ -69,8 +100,6 @@ shmfile_new(const char *base, int id, int size, Eina_Bool sys) if (!sf->file) { close(sf->fd); - shm_unlink(sf->file); - eina_stringshare_del(sf->file); free(sf); return NULL; } @@ -149,6 +178,313 @@ shmfile_close(Shmfile *sf) free(sf); } +//////////////////////////////////// +// drm stuff (libdrm.so.2) +static void *drm_lib = NULL; +typedef unsigned int drm_magic_t; +static int (*sym_drmGetMagic)(int fd, drm_magic_t *magic) = NULL; + +//////////////////////////////////// +// dri2 stuff (libdri2.so.0) +static void *dri_lib = NULL; +#define DRI2BufferFrontLeft 0 + +typedef struct +{ + unsigned int attachment; + unsigned int name; + unsigned int pitch; + unsigned int cpp; + unsigned int flags; +} DRI2Buffer; + +static Bool (*sym_DRI2QueryExtension)(Display *display, int *eventBase, int *errorBase) = NULL; +static Bool (*sym_DRI2QueryVersion)(Display *display, int *major, int *minor) = NULL; +static Bool (*sym_DRI2Connect)(Display *display, XID window, char **driverName, char **deviceName) = NULL; +static Bool (*sym_DRI2Authenticate)(Display *display, XID window, drm_magic_t magic) = NULL; +static void (*sym_DRI2CreateDrawable) (Display *display, XID drawable) = NULL; +static void (*sym_DRI2DestroyDrawable) (Display *display, XID handle) = NULL; +static DRI2Buffer *(*sym_DRI2GetBuffers) (Display *display, XID drawable, int *width, int *height, unsigned int *attachments, int count, int *outCount) = NULL; + +//////////////////////////////////// +// tbm stuff (libtbm.so.1) +static void *tbm_lib = NULL; +typedef struct _tbm_bufmgr *tbm_bufmgr; +typedef struct _tbm_bo *tbm_bo; +typedef union _tbm_bo_handle +{ + void *ptr; + int32_t s32; + uint32_t u32; + int64_t s64; + uint64_t u64; +} tbm_bo_handle; + + +/* TBM_DEVICE_TYPE */ +#define TBM_DEVICE_DEFAULT 0 /**< device type to get the default handle */ +#define TBM_DEVICE_CPU 1 /**< device type to get the virtual memory */ +#define TBM_DEVICE_2D 2 /**< device type to get the 2D memory handle */ +#define TBM_DEVICE_3D 3 /**< device type to get the 3D memory handle */ +#define TBM_DEVICE_MM 4 /**< device type to get the multimedia handle */ + +/* TBM_OPTION */ +#define TBM_OPTION_READ (1 << 0) /**< access option to read */ +#define TBM_OPTION_WRITE (1 << 1) /**< access option to write */ +#define TBM_OPTION_VENDOR (0xffff0000) /**< vendor specific option: it depends on the backend */ + +static tbm_bufmgr (*sym_tbm_bufmgr_init) (int fd) = NULL; +static void (*sym_tbm_bufmgr_deinit) (tbm_bufmgr bufmgr) = NULL; +static tbm_bo_handle (*sym_tbm_bo_map) (tbm_bo bo, int device, int opt) = NULL; +static int (*sym_tbm_bo_unmap) (tbm_bo bo) = NULL; +static tbm_bo_handle (*sym_tbm_bo_get_handle) (tbm_bo bo, int device) = NULL; +static tbm_bo (*sym_tbm_bo_import) (tbm_bufmgr bufmgr, unsigned int key) = NULL; + +static int +_tbm_link(void) +{ + const char *tbm_libs[] = + { + "libtbm.so.1", + "libtbm.so.0", + NULL, + }; + int i, fail; +#define SYM(lib, xx) \ + do { \ + sym_ ## xx = dlsym(lib, #xx); \ + if (!(sym_ ## xx)) { \ + ERR("%s", dlerror()); \ + fail = 1; \ + } \ + } while (0) + + if (tbm_lib) return 1; + for (i = 0; tbm_libs[i]; i++) + { + tbm_lib = dlopen(tbm_libs[i], RTLD_LOCAL | RTLD_LAZY); + if (tbm_lib) + { + fail = 0; + SYM(tbm_lib, tbm_bufmgr_init); + SYM(tbm_lib, tbm_bufmgr_deinit); + SYM(tbm_lib, tbm_bo_map); + SYM(tbm_lib, tbm_bo_unmap); + SYM(tbm_lib, tbm_bo_get_handle); + SYM(tbm_lib, tbm_bo_import); + if (fail) + { + dlclose(tbm_lib); + tbm_lib = NULL; + } + else break; + } + } + if (!tbm_lib) return 0; + return 1; +} + +static void +_tbm_unlink(void) +{ + if (tbm_lib) + { + dlclose(tbm_lib); + tbm_lib = NULL; + } +} + +static int +_dri_drm_link(void) +{ + const char *drm_libs[] = + { + "libdrm.so.2", + "libdrm.so.1", + "libdrm.so.0", + "libdrm.so", + NULL, + }; + const char *dri_libs[] = + { + "libdri2.so.2", + "libdri2.so.1", + "libdri2.so.0", + "libdri2.so", + NULL, + }; + int i, fail; +#define SYM(lib, xx) \ + do { \ + sym_ ## xx = dlsym(lib, #xx); \ + if (!(sym_ ## xx)) { \ + ERR("%s", dlerror()); \ + fail = 1; \ + } \ + } while (0) + + if (dri_lib) return 1; + for (i = 0; drm_libs[i]; i++) + { + drm_lib = dlopen(drm_libs[i], RTLD_LOCAL | RTLD_LAZY); + if (drm_lib) + { + fail = 0; + SYM(drm_lib, drmGetMagic); + if (fail) + { + dlclose(drm_lib); + drm_lib = NULL; + } + else break; + } + } + if (!drm_lib) return 0; + for (i = 0; dri_libs[i]; i++) + { + dri_lib = dlopen(dri_libs[i], RTLD_LOCAL | RTLD_LAZY); + if (dri_lib) + { + fail = 0; + SYM(dri_lib, DRI2QueryExtension); + SYM(dri_lib, DRI2QueryVersion); + SYM(dri_lib, DRI2Connect); + SYM(dri_lib, DRI2Authenticate); + SYM(dri_lib, DRI2CreateDrawable); + SYM(dri_lib, DRI2DestroyDrawable); + SYM(dri_lib, DRI2GetBuffers); + if (fail) + { + dlclose(dri_lib); + dri_lib = NULL; + } + else break; + } + } + if (!dri_lib) + { + dlclose(drm_lib); + drm_lib = NULL; + return 0; + } + + return 1; +} + +static void +_dri_drm_unlink(void) +{ + if (dri_lib) + { + dlclose(dri_lib); + dri_lib = NULL; + } + + if (drm_lib) + { + dlclose(drm_lib); + drm_lib = NULL; + } +} + +typedef struct _Drm_Pixmap Drm_Pixmap; + +struct _Drm_Pixmap +{ + int fd; + tbm_bufmgr bufmgr; +}; + +static void +_dri_drm_shutdown(Drm_Pixmap *dp) +{ + if (dp) + { + if (dp->bufmgr) + sym_tbm_bufmgr_deinit(dp->bufmgr); + + if (dp->fd) + close(dp->fd); + + if (dp) + free(dp); + } + + _tbm_unlink(); + _dri_drm_unlink(); +} + +static Drm_Pixmap * +_dri_drm_init(Ecore_X_Display *display, Ecore_X_Window window) +{ + int dri2_ev_base, dri2_err_base, dri2_major, dri2_minor; + char *drv_name, *dev_name; + drm_magic_t magic; + Drm_Pixmap *dp = NULL; + + if (!display) return NULL; + if (!window) return NULL; + if (!_dri_drm_link()) goto error; + if (!_tbm_link()) goto error; + + dp = (Drm_Pixmap *)calloc(1, sizeof(Drm_Pixmap)); + if (!dp) goto error; + + if (!sym_DRI2QueryExtension(display, &dri2_ev_base, &dri2_err_base)) + { + ERR("Failed to get dri2 extension"); + goto error; + } + + if (!sym_DRI2QueryVersion(display, &dri2_major, &dri2_minor)) + { + ERR("Failed to get dri2 version"); + goto error; + } + + if (!sym_DRI2Connect(display, window, &drv_name, &dev_name)) + { + ERR("Failed to get dri2 version"); + goto error; + } + + dp->fd = open(dev_name, O_RDWR); + if (dp->fd < 0) + { + ERR("Cannot open fd"); + free(drv_name); + free(dev_name); + goto error; + } + + free(drv_name); + free(dev_name); + + if (sym_drmGetMagic(dp->fd, &magic)) + { + ERR("Cannot get magic in drmGetMagic"); + goto error; + } + + if (!sym_DRI2Authenticate(display, window, (unsigned int)magic)) + { + ERR("DRI2 authentication failed"); + goto error; + } + + dp->bufmgr = sym_tbm_bufmgr_init(dp->fd); + if (!dp->bufmgr) + { + ERR("tbm_bufmgr init failed"); + goto error; + } + + return dp; +error: + _dri_drm_shutdown(dp); + return NULL; +} + // procotol version - change this as needed #define MAJOR 0x1011 @@ -174,7 +510,11 @@ enum // opcodes OP_EV_MULTI_MOVE, OP_EV_KEY_UP, OP_EV_KEY_DOWN, - OP_EV_HOLD + OP_EV_HOLD, + OP_MSG_PARENT, + OP_MSG, + OP_PIXMAP_REF, + OP_PIXMAP_IDX, }; enum @@ -317,6 +657,8 @@ struct _Ipc_Data_Ev_Key_Down Evas_Event_Flags event_flags; }; +#define NBUF 2 + typedef struct _Extn Extn; struct _Extn @@ -333,16 +675,96 @@ struct _Extn Eina_Bool sys : 1; } svc; struct { - const char *lock; - int lockfd; - const char *shm; - int w, h; - Shmfile *shmfile; + const char *lock; + int lockfd; + int w, h, stride, size; + const char *shm; + Shmfile *shmfile; + Ecore_X_Pixmap pixmap; + tbm_bo bo; + Eina_Bool have_lock : 1; + } b[NBUF]; + int cur_b; + int max_b; + struct { + Drm_Pixmap *dp; Eina_List *updates; - Eina_Bool have_lock : 1; } file; }; +static void * +_dri_drm_get_buffers(Extn *extn) +{ + Drm_Pixmap *dp = extn->file.dp; + DRI2Buffer *buf = NULL; + unsigned int attach[1] = { DRI2BufferFrontLeft }; + Ecore_X_Display *display = ecore_x_display_get(); + Ecore_X_Drawable drawable = (Ecore_X_Drawable)extn->b[extn->cur_b].pixmap; + int num, width, height; + tbm_bo_handle handle; + handle.ptr = NULL; + + if (!dp) return NULL; + if (!display) return NULL; + if (!drawable) return NULL; + + XSync(display, 0); + + sym_DRI2CreateDrawable(display, drawable); + buf = sym_DRI2GetBuffers(display, drawable, &width, &height, attach, 1, &num); + if (!buf) goto error; + if (!buf->name) goto error; + + if (!dp->bufmgr) goto error; + extn->b[extn->cur_b].bo = sym_tbm_bo_import(dp->bufmgr, buf->name); + if (!extn->b[extn->cur_b].bo) goto error; + + extn->b[extn->cur_b].stride = buf->pitch; + handle = sym_tbm_bo_get_handle(extn->b[extn->cur_b].bo, TBM_DEVICE_CPU); + +error: + if (buf) XFree(buf); + sym_DRI2DestroyDrawable(display, drawable); + return handle.ptr; +} + +enum { + ECORE_EVAS_EXTN_TYPE_BUFFER_SHM = 0, /* shared memory-based buffer backend */ + ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP, /* dri2 pixmap-based buffer backend */ + ECORE_EVAS_EXTN_TYPE_EVASGL_PIXMAP, /* pixmap backend for Evas GL only */ + ECORE_EVAS_EXTN_TYPE_GL_PIXMAP, /* double buffered GL pixmap backend */ +}; + +static int +_ecore_evas_extn_type_get(Ecore_Evas *ee) +{ + int type = ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP; + char *engine = getenv("ECORE_EVAS_EXTN_SOCKET_ENGINE"); + + if (engine) + { + if ((!strcasecmp(engine, "opengl")) || + (!strcasecmp(engine, "gl")) || + (!strcasecmp(engine, "opengl-x11")) || + (!strcasecmp(engine, "opengl_x11")) || + (!strcasecmp(engine, "gl_x11"))) + type = ECORE_EVAS_EXTN_TYPE_EVASGL_PIXMAP; + else if ((!strcasecmp(engine, "gl_pixmap"))) + type = ECORE_EVAS_EXTN_TYPE_GL_PIXMAP; + else if ((!strcasecmp(engine, "x11")) || + (!strcasecmp(engine, "x")) || + (!strcasecmp(engine, "software-x11")) || + (!strcasecmp(engine, "software_x11"))) + type = ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP; + else if (!strcasecmp(engine, "buffer")) + type = ECORE_EVAS_EXTN_TYPE_BUFFER_SHM; + else + type = ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP; + } + + return type; +} + static Eina_List *extn_ee_list = NULL; EAPI int ECORE_EVAS_EXTN_CLIENT_ADD = 0; @@ -380,6 +802,30 @@ _ecore_evas_extn_event(Ecore_Evas *ee, int event) _ecore_evas_extn_event_free, ee); } +static Eina_Bool +_ecore_evas_lock_other_have(Ecore_Evas *ee) +{ + Eina_List *l; + Ecore_Evas *ee2; + Extn *extn, *extn2; + + extn = ee->engine.buffer.data; + if (!extn) return EINA_FALSE; + // brute force - i know. i expect extn_ee_list to be fairly short. could + // be improved with a hash of lockfiles + EINA_LIST_FOREACH(extn_ee_list, l, ee2) + { + if (ee == ee2) continue; + extn2 = ee2->engine.buffer.data; + if (!extn2) continue; + if ((extn->b[extn->cur_b].lock) && (extn2->b[extn2->cur_b].lock) && + (!strcmp(extn->b[extn->cur_b].lock, extn2->b[extn2->cur_b].lock)) && + (extn2->b[extn2->cur_b].have_lock)) + return EINA_TRUE; + } + return EINA_FALSE; +} + static void _ecore_evas_socket_lock(Ecore_Evas *ee) { @@ -387,10 +833,22 @@ _ecore_evas_socket_lock(Ecore_Evas *ee) extn = ee->engine.buffer.data; if (!extn) return; - if (extn->file.lockfd < 0) return; - if (extn->file.have_lock) return; - flock(extn->file.lockfd, LOCK_EX); - extn->file.have_lock = EINA_TRUE; + if (extn->b[extn->cur_b].have_lock) return; + if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_BUFFER_SHM || + _ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP || + _ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_GL_PIXMAP) + { + if (extn->b[extn->cur_b].lockfd < 0) return; + if (lockf(extn->b[extn->cur_b].lockfd, F_LOCK, 0) < 0) + return; + } + if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP) + { + // lock on pixmap(tbm) since the cpu will write into the buffer on the socket side + if (extn->ipc.am_server && extn->b[extn->cur_b].bo) + sym_tbm_bo_map(extn->b[extn->cur_b].bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE); + } + extn->b[extn->cur_b].have_lock = EINA_TRUE; } static void @@ -400,31 +858,107 @@ _ecore_evas_socket_unlock(Ecore_Evas *ee) extn = ee->engine.buffer.data; if (!extn) return; - if (extn->file.lockfd < 0) return; - if (!extn->file.have_lock) return; - flock(extn->file.lockfd, LOCK_UN); - extn->file.have_lock = EINA_FALSE; + if (!extn->b[extn->cur_b].have_lock) return; + if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_BUFFER_SHM || + _ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP || + _ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_GL_PIXMAP) + { + if (extn->b[extn->cur_b].lockfd < 0) return; + if (lockf(extn->b[extn->cur_b].lockfd, F_ULOCK, 0) < 0) + return; + } + if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP) + { + if (extn->ipc.am_server && extn->b[extn->cur_b].bo) + sym_tbm_bo_unmap(extn->b[extn->cur_b].bo); + } + extn->b[extn->cur_b].have_lock = EINA_FALSE; } static void -_ecore_evas_extn_plug_targer_render_pre(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__) +_ecore_evas_extn_plug_render_pre(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { Ecore_Evas *ee = data; - if (ee) _ecore_evas_socket_lock(ee); + + if(!ee) return; + + _ecore_evas_socket_lock(ee); + + Extn *extn = ee->engine.buffer.data; + + if (extn && extn->b[extn->cur_b].pixmap && ee->engine.buffer.image) + { + Evas_Native_Surface ns; + ns.type = EVAS_NATIVE_SURFACE_X11; + ns.version = EVAS_NATIVE_SURFACE_VERSION; + ns.data.x11.pixmap = extn->b[extn->cur_b].pixmap; + ns.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), + ecore_x_default_screen_get()); + evas_object_image_native_surface_set(ee->engine.buffer.image, &ns); + } } static void -_ecore_evas_extn_plug_targer_render_post(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__) +_ecore_evas_extn_plug_render_post(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { Ecore_Evas *ee = data; if (ee) _ecore_evas_socket_unlock(ee); } static void +_ecore_evas_extn_plug_target_render_pre(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Ecore_Evas *ee = data; +} + +static void +_ecore_evas_extn_plug_target_render_post(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Ecore_Evas *ee = data; +} + +static void +_ecore_evas_extn_plug_image_obj_callbacks_unregister(Ecore_Evas *ee) +{ + Ecore_Evas *ee2; + + evas_object_event_callback_del_full(ee->engine.buffer.image, + EVAS_CALLBACK_DEL, + _ecore_evas_extn_plug_image_obj_del, + ee); + + evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image), + EVAS_CALLBACK_RENDER_PRE, + _ecore_evas_extn_plug_render_pre, + ee); + evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image), + EVAS_CALLBACK_RENDER_POST, + _ecore_evas_extn_plug_render_post, + ee); + + evas_object_event_callback_del_full(ee->engine.buffer.image, + EVAS_CALLBACK_CANVAS_OBJECT_RENDER_PRE, + _ecore_evas_extn_plug_target_render_pre, + ee); + evas_object_event_callback_del_full(ee->engine.buffer.image, + EVAS_CALLBACK_CANVAS_OBJECT_RENDER_POST, + _ecore_evas_extn_plug_target_render_post, + ee); + ee2 = evas_object_data_get(ee->engine.buffer.image, "Ecore_Evas_Parent"); + if (ee2) + { + ee2->sub_ecore_evas = eina_list_remove(ee2->sub_ecore_evas, ee); + } +} + +static void _ecore_evas_extn_plug_image_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { Ecore_Evas *ee = data; - if (ee) ecore_evas_free(ee); + + _ecore_evas_extn_plug_image_obj_callbacks_unregister(ee); + + ecore_evas_free(ee); } static void @@ -475,17 +1009,45 @@ _ecore_evas_extn_free(Ecore_Evas *ee) if (extn) { Ecore_Event_Handler *hdl; + Ipc_Data_Update *ipc; + int i; - if (extn->file.have_lock) - _ecore_evas_socket_unlock(ee); - if (extn->file.lockfd) + for (i = 0; i < extn->max_b; i++) { - close(extn->file.lockfd); - if (extn->ipc.am_server) + if (extn->b[i].have_lock) + { + int tmp = extn->cur_b; + extn->cur_b = i; + _ecore_evas_socket_unlock(ee); + extn->cur_b = tmp; + } + if (extn->b[i].lockfd) + { + close(extn->b[i].lockfd); + if (extn->ipc.am_server) + { + if (extn->b[i].lock) unlink(extn->b[i].lock); + } + } + if (extn->b[i].lock) eina_stringshare_del(extn->b[i].lock); + if (extn->b[i].shm) eina_stringshare_del(extn->b[i].shm); + if (extn->b[i].shmfile) + { + if (extn->ipc.am_server) + shmfile_free(extn->b[i].shmfile); + else + shmfile_close(extn->b[i].shmfile); + } + if (extn->b[i].pixmap) { - if (extn->file.lock) unlink(extn->file.lock); + if (extn->ipc.am_server) + { + ecore_x_pixmap_free(extn->b[i].pixmap); + } + extn->b[i].pixmap = 0; } } + if (extn->svc.name) eina_stringshare_del(extn->svc.name); if (extn->ipc.clients) { @@ -493,16 +1055,16 @@ _ecore_evas_extn_free(Ecore_Evas *ee) ecore_ipc_client_del(client); } if (extn->ipc.server) ecore_ipc_server_del(extn->ipc.server); - if (extn->file.lock) eina_stringshare_del(extn->file.lock); - if (extn->file.shm) eina_stringshare_del(extn->file.shm); - if (extn->file.shmfile) + + if (extn->file.dp) { - if (extn->ipc.am_server) - shmfile_free(extn->file.shmfile); - else - shmfile_close(extn->file.shmfile); + _dri_drm_shutdown(extn->file.dp); + extn->file.dp = NULL; } + EINA_LIST_FREE(extn->file.updates, ipc) + free(ipc); + EINA_LIST_FREE(extn->ipc.handlers, hdl) ecore_event_handler_del(hdl); free(extn); @@ -511,26 +1073,10 @@ _ecore_evas_extn_free(Ecore_Evas *ee) } if (ee->engine.buffer.image) { - Ecore_Evas *ee2; - - evas_object_event_callback_del_full(ee->engine.buffer.image, - EVAS_CALLBACK_DEL, - _ecore_evas_extn_plug_image_obj_del, - ee); - evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image), - EVAS_CALLBACK_RENDER_PRE, - _ecore_evas_extn_plug_targer_render_pre, - ee); - evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image), - EVAS_CALLBACK_RENDER_POST, - _ecore_evas_extn_plug_targer_render_post, - ee); + evas_object_image_native_surface_set(ee->engine.buffer.image, NULL); + _ecore_evas_extn_plug_image_obj_callbacks_unregister(ee); evas_object_del(ee->engine.buffer.image); - ee2 = evas_object_data_get(ee->engine.buffer.image, "Ecore_Evas_Parent"); - if (ee2) - { - ee2->sub_ecore_evas = eina_list_remove(ee2->sub_ecore_evas, ee); - } + ee->engine.buffer.image = NULL; } extn_ee_list = eina_list_remove(extn_ee_list, ee); } @@ -633,6 +1179,7 @@ _ecore_evas_extn_cb_mouse_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __ if (extn->ipc.server) { Ipc_Data_Ev_Mouse_In ipc; + memset(&ipc, 0, sizeof(ipc)); ipc.timestamp = ev->timestamp; ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); @@ -653,6 +1200,7 @@ _ecore_evas_extn_cb_mouse_out(void *data, Evas *e __UNUSED__, Evas_Object *obj _ if (extn->ipc.server) { Ipc_Data_Ev_Mouse_Out ipc; + memset(&ipc, 0, sizeof(ipc)); ipc.timestamp = ev->timestamp; ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); @@ -675,6 +1223,7 @@ _ecore_evas_extn_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj /* We have send mouse move event before mouse down event */ { Ipc_Data_Ev_Mouse_Move ipc_move; + memset(&ipc_move, 0, sizeof(ipc_move)); Evas_Coord x, y; x = ev->canvas.x; @@ -686,15 +1235,18 @@ _ecore_evas_extn_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj ipc_move.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); ipc_move.event_flags = ev->event_flags; ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_MOVE, 0, 0, 0, &ipc_move, sizeof(ipc_move)); + ecore_ipc_server_flush(extn->ipc.server); } { Ipc_Data_Ev_Mouse_Down ipc; + memset(&ipc, 0, sizeof(ipc)); ipc.b = ev->button; ipc.flags = ev->flags; ipc.timestamp = ev->timestamp; ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); ipc.event_flags = ev->event_flags; ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_DOWN, 0, 0, 0, &ipc, sizeof(ipc)); + ecore_ipc_server_flush(extn->ipc.server); } } } @@ -711,6 +1263,7 @@ _ecore_evas_extn_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __ if (extn->ipc.server) { Ipc_Data_Ev_Mouse_Up ipc; + memset(&ipc, 0, sizeof(ipc)); ipc.b = ev->button; ipc.flags = ev->flags; @@ -718,6 +1271,7 @@ _ecore_evas_extn_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __ ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); ipc.event_flags = ev->event_flags; ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_UP, 0, 0, 0, &ipc, sizeof(ipc)); + ecore_ipc_server_flush(extn->ipc.server); } } @@ -733,6 +1287,7 @@ _ecore_evas_extn_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj if (extn->ipc.server) { Ipc_Data_Ev_Mouse_Move ipc; + memset(&ipc, 0, sizeof(ipc)); Evas_Coord x, y; x = ev->cur.canvas.x; @@ -744,6 +1299,7 @@ _ecore_evas_extn_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); ipc.event_flags = ev->event_flags; ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_MOVE, 0, 0, 0, &ipc, sizeof(ipc)); + ecore_ipc_server_flush(extn->ipc.server); } } @@ -759,6 +1315,7 @@ _ecore_evas_extn_cb_mouse_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj if (extn->ipc.server) { Ipc_Data_Ev_Mouse_Wheel ipc; + memset(&ipc, 0, sizeof(ipc)); ipc.direction = ev->direction; ipc.z = ev->z; @@ -781,6 +1338,7 @@ _ecore_evas_extn_cb_multi_down(void *data, Evas *e __UNUSED__, Evas_Object *obj if (extn->ipc.server) { Ipc_Data_Ev_Multi_Down ipc; + memset(&ipc, 0, sizeof(ipc)); Evas_Coord x, y; ipc.d = ev->device; @@ -817,6 +1375,7 @@ _ecore_evas_extn_cb_multi_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __ if (extn->ipc.server) { Ipc_Data_Ev_Multi_Up ipc; + memset(&ipc, 0, sizeof(ipc)); Evas_Coord x, y; ipc.d = ev->device; @@ -852,6 +1411,7 @@ _ecore_evas_extn_cb_multi_move(void *data, Evas *e __UNUSED__, Evas_Object *obj if (extn->ipc.server) { Ipc_Data_Ev_Multi_Move ipc; + memset(&ipc, 0, sizeof(ipc)); Evas_Coord x, y; ipc.d = ev->device; @@ -875,15 +1435,6 @@ _ecore_evas_extn_cb_multi_move(void *data, Evas *e __UNUSED__, Evas_Object *obj } static void -_ecore_evas_extn_cb_free(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) -{ - Ecore_Evas *ee; - - ee = data; - if (ee->driver) _ecore_evas_free(ee); -} - -static void _ecore_evas_extn_cb_key_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) { Ecore_Evas *ee = data; @@ -1007,6 +1558,7 @@ _ecore_evas_extn_cb_hold(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUS if (extn->ipc.server) { Ipc_Data_Ev_Hold ipc; + memset(&ipc, 0, sizeof(ipc)); ipc.hold = ev->hold; ipc.timestamp = ev->timestamp; @@ -1071,6 +1623,20 @@ _ecore_evas_extn_cb_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUS ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_HIDE, 0, 0, 0, NULL, 0); } +static void +_ecore_evas_extn_plug_msg_parent_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size) +{ + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (!extn->ipc.server) return; + + //ref = msg_domain + //ref_to = msg_id + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_MSG, msg_domain, msg_id, 0, data, size); +} + static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func = { _ecore_evas_extn_free, @@ -1129,7 +1695,16 @@ static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func = NULL, // render NULL, // screen_geometry_get - NULL // screen_dpi_get + NULL, // screen_dpi_get + _ecore_evas_extn_plug_msg_parent_send, + NULL, // msg_send + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; static Eina_Bool @@ -1155,22 +1730,37 @@ _ipc_server_del(void *data, int type __UNUSED__, void *event) Ecore_Ipc_Event_Server_Del *e = event; Ecore_Evas *ee = data; Extn *extn; + int i; extn = ee->engine.buffer.data; if (!extn) return ECORE_CALLBACK_PASS_ON; if (extn->ipc.server != e->server) return ECORE_CALLBACK_PASS_ON; + + evas_object_image_native_surface_set(ee->engine.buffer.image, NULL); evas_object_image_data_set(ee->engine.buffer.image, NULL); - ee->engine.buffer.pixels = NULL; - if (extn->file.shmfile) + + for (i = 0; i < extn->max_b; i++) { - shmfile_close(extn->file.shmfile); - extn->file.shmfile = NULL; + extn->b[i].pixmap = 0; + if (extn->b[i].shmfile) + { + shmfile_close(extn->b[i].shmfile); + extn->b[i].shmfile = NULL; + } + if (extn->b[i].shm) + { + eina_stringshare_del(extn->b[i].shm); + extn->b[i].shm = NULL; + } } - if (extn->file.shm) + + if (extn->file.dp) { - eina_stringshare_del(extn->file.shm); - extn->file.shm = NULL; + _dri_drm_shutdown(extn->file.dp); + extn->file.dp = NULL; } + ee->engine.buffer.pixels = NULL; + extn->ipc.server = NULL; if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee); return ECORE_CALLBACK_PASS_ON; @@ -1206,9 +1796,11 @@ _ipc_server_data(void *data, int type __UNUSED__, void *event) } break; case OP_UPDATE_DONE: + // e->response == display buffer # // updates finished being sent - done now. frame ready { Ipc_Data_Update *ipc; + int n = e->response; EINA_LIST_FREE(extn->file.updates, ipc) { @@ -1216,17 +1808,35 @@ _ipc_server_data(void *data, int type __UNUSED__, void *event) evas_object_image_data_update_add(ee->engine.buffer.image, ipc->x, ipc->y, ipc->w, ipc->h); + free(ipc); + } + if ((n >= 0) && (n < NBUF)) + { + extn->cur_b = n; } } break; case OP_LOCK_FILE: + // e->response == display buffer # if ((e->data) && (e->size > 0) && (((unsigned char *)e->data)[e->size - 1] == 0)) { - if (extn->file.lockfd) close(extn->file.lockfd); - if (extn->file.lock) eina_stringshare_del(extn->file.lock); - extn->file.lock = eina_stringshare_add(e->data); - extn->file.lockfd = open(extn->file.lock, O_RDONLY); + int n = e->response; + + if ((n >= 0) && (n < NBUF)) + { + if (extn->b[n].have_lock) + { + int tmp = extn->cur_b; + extn->cur_b = n; + _ecore_evas_socket_unlock(ee); + extn->cur_b = tmp; + } + if (extn->b[n].lockfd) close(extn->b[n].lockfd); + if (extn->b[n].lock) eina_stringshare_del(extn->b[n].lock); + extn->b[n].lock = eina_stringshare_add(e->data); + extn->b[n].lockfd = open(extn->b[n].lock, O_RDWR); + } } break; case OP_SHM_REF: @@ -1237,30 +1847,32 @@ _ipc_server_data(void *data, int type __UNUSED__, void *event) if ((e->data) && ((unsigned char *)e->data)[e->size - 1] == 0) { ee->engine.buffer.pixels = NULL; - if (extn->file.shmfile) + if (extn->b[extn->cur_b].shmfile) { - shmfile_close(extn->file.shmfile); - extn->file.shmfile = NULL; + shmfile_close(extn->b[extn->cur_b].shmfile); + extn->b[extn->cur_b].shmfile = NULL; } - if (extn->file.shm) + if (extn->b[extn->cur_b].shm) { - eina_stringshare_del(extn->file.shm); - extn->file.shm = NULL; + eina_stringshare_del(extn->b[extn->cur_b].shm); + extn->b[extn->cur_b].shm = NULL; } if ((e->ref > 0) && (e->ref_to > 0)) { - extn->file.w = e->ref; - extn->file.h = e->ref_to; - extn->file.shm = eina_stringshare_add(e->data); - extn->file.shmfile = shmfile_open(extn->file.shm, - extn->file.w * - extn->file.h * 4, + extn->b[extn->cur_b].w = e->ref; + extn->b[extn->cur_b].h = e->ref_to; + extn->b[extn->cur_b].shm = eina_stringshare_add(e->data); + extn->b[extn->cur_b].shmfile = shmfile_open(extn->b[extn->cur_b].shm, + extn->b[extn->cur_b].w * + extn->b[extn->cur_b].h * 4, EINA_TRUE); - if (extn->file.shmfile) + if (extn->b[extn->cur_b].shmfile) { - ee->engine.buffer.pixels = extn->file.shmfile->addr; + ee->engine.buffer.pixels = extn->b[extn->cur_b].shmfile->addr; if (ee->engine.buffer.image) { + evas_object_image_colorspace_set(ee->engine.buffer.image, + EVAS_COLORSPACE_ARGB8888); if (e->response) evas_object_image_alpha_set(ee->engine.buffer.image, EINA_TRUE); @@ -1268,17 +1880,17 @@ _ipc_server_data(void *data, int type __UNUSED__, void *event) evas_object_image_alpha_set(ee->engine.buffer.image, EINA_FALSE); evas_object_image_size_set(ee->engine.buffer.image, - extn->file.w, - extn->file.h); + extn->b[extn->cur_b].w, + extn->b[extn->cur_b].h); evas_object_image_data_set(ee->engine.buffer.image, ee->engine.buffer.pixels); evas_object_image_data_update_add(ee->engine.buffer.image, 0, 0, - extn->file.w, - extn->file.h); + extn->b[extn->cur_b].w, + extn->b[extn->cur_b].h); _ecore_evas_resize(ee, - extn->file.w, - extn->file.h); + extn->b[extn->cur_b].w, + extn->b[extn->cur_b].h); } else evas_object_image_data_set(ee->engine.buffer.image, NULL); @@ -1290,6 +1902,62 @@ _ipc_server_data(void *data, int type __UNUSED__, void *event) evas_object_image_data_set(ee->engine.buffer.image, NULL); } break; + case OP_PIXMAP_REF: + // e->ref == w + // e->ref_to == h + // e->response == alpha + // e->data = pixmap id + if ((e->data) && (e->size >= (int)sizeof(Ecore_X_Pixmap))) + { + if ((e->ref > 0) && (e->ref_to > 0)) + { + Ecore_X_Pixmap *pixmap = (Ecore_X_Pixmap *)e->data; + extn->b[extn->cur_b].w = e->ref; + extn->b[extn->cur_b].h = e->ref_to; + extn->b[extn->cur_b].pixmap = *pixmap; + + if (extn->b[extn->cur_b].pixmap) + { + Evas_Native_Surface ns; + ns.type = EVAS_NATIVE_SURFACE_X11; + ns.version = EVAS_NATIVE_SURFACE_VERSION; + ns.data.x11.pixmap = extn->b[extn->cur_b].pixmap; + ns.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), + ecore_x_default_screen_get()); + if (e->response) + evas_object_image_alpha_set(ee->engine.buffer.image, + EINA_TRUE); + else + evas_object_image_alpha_set(ee->engine.buffer.image, + EINA_FALSE); + evas_object_image_size_set(ee->engine.buffer.image, + extn->b[extn->cur_b].w, + extn->b[extn->cur_b].h); + evas_object_image_native_surface_set(ee->engine.buffer.image, &ns); + evas_object_image_data_update_add(ee->engine.buffer.image, + 0, 0, + extn->b[extn->cur_b].w, + extn->b[extn->cur_b].h); + _ecore_evas_resize(ee, + extn->b[extn->cur_b].w, + extn->b[extn->cur_b].h); + } + else + evas_object_image_native_surface_set(ee->engine.buffer.image, NULL); + } + } + break; + case OP_PIXMAP_IDX: + // e->response == display buffer # + { + int n = e->response; + + if ((n >= 0) && (n < NBUF)) + { + extn->cur_b = n; + } + } + break; case OP_RESIZE: if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize))) { @@ -1297,6 +1965,18 @@ _ipc_server_data(void *data, int type __UNUSED__, void *event) _ecore_evas_resize(ee, ipc->w, ipc->h); } break; + case OP_MSG_PARENT: + if ((e->data) && (e->size > 0)) + { + //ref = msg_domain + //ref_to = msg_id + if (ee->func.fn_msg_handle) + { + INF("Msg(from parent): msg_domain=%x msg_id=%x size=%d", e->ref, e->ref_to, e->size); + ee->func.fn_msg_handle(ee, e->ref, e->ref_to, e->data, e->size); + } + } + break; default: break; } @@ -1391,9 +2071,6 @@ ecore_evas_extn_plug_new(Ecore_Evas *ee_target) EVAS_CALLBACK_MULTI_MOVE, _ecore_evas_extn_cb_multi_move, ee); evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_FREE, - _ecore_evas_extn_cb_free, ee); - evas_object_event_callback_add(ee->engine.buffer.image, EVAS_CALLBACK_KEY_DOWN, _ecore_evas_extn_cb_key_down, ee); evas_object_event_callback_add(ee->engine.buffer.image, @@ -1424,9 +2101,14 @@ ecore_evas_extn_plug_new(Ecore_Evas *ee_target) ee_target->sub_ecore_evas = eina_list_append(ee_target->sub_ecore_evas, ee); evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_PRE, - _ecore_evas_extn_plug_targer_render_pre, ee); + _ecore_evas_extn_plug_render_pre, ee); evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_POST, - _ecore_evas_extn_plug_targer_render_post, ee); + _ecore_evas_extn_plug_render_post, ee); + + evas_object_event_callback_add(ee->engine.buffer.image, EVAS_CALLBACK_CANVAS_OBJECT_RENDER_PRE, + _ecore_evas_extn_plug_target_render_pre, ee); + evas_object_event_callback_add(ee->engine.buffer.image, EVAS_CALLBACK_CANVAS_OBJECT_RENDER_POST, + _ecore_evas_extn_plug_target_render_post, ee); return o; #else return NULL; @@ -1445,6 +2127,30 @@ ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, ee = evas_object_data_get(obj, "Ecore_Evas"); if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) return EINA_FALSE; + if (!svcname) + { + ee->engine.buffer.data = NULL; + return EINA_FALSE; + } + + //check already connected extn + if (ee->engine.buffer.data) + { + Extn *extn = ee->engine.buffer.data; + if(strcmp(extn->svc.name, svcname) || + (extn->svc.num != svcnum) || + (extn->svc.sys != svcsys)) + { + ERR("Extn plug already connected: svcname=%s, svcnum=%d, svcsys=%d", extn->svc.name, extn->svc.num, extn->svc.sys); + return EINA_FALSE; + } + else + { + INF("Extn plug connected: svcname=%s, svcnum=%d, svcsys=%d", svcname, svcnum, svcsys); + return EINA_TRUE; + } + } + extn = calloc(1, sizeof(Extn)); if (!extn) return EINA_FALSE; @@ -1460,6 +2166,8 @@ ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, extn->svc.num, ee); if (!extn->ipc.server) { + ERR("Extn plug failed to connect:ipctype=%d, svcname=%s, svcnum=%d, svcsys=%d", ipctype, svcname, svcnum, svcsys); + ee->engine.buffer.data = NULL; eina_stringshare_del(extn->svc.name); free(extn); ecore_ipc_shutdown(); @@ -1478,6 +2186,7 @@ ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, (extn->ipc.handlers, ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _ipc_server_data, ee)); + INF("Extn plug connected: svcname=%s, svcnum=%d, svcsys=%d", svcname, svcnum, svcsys); return EINA_TRUE; #else return EINA_FALSE; @@ -1513,7 +2222,6 @@ static void _ecore_evas_socket_resize(Ecore_Evas *ee, int w, int h) { Extn *extn; - Evas_Engine_Info_Buffer *einfo; int stride = 0; if (w < 1) w = 1; @@ -1529,50 +2237,143 @@ _ecore_evas_socket_resize(Ecore_Evas *ee, int w, int h) extn = ee->engine.buffer.data; if (extn) { - if (extn->file.shmfile) - shmfile_free(extn->file.shmfile); - ee->engine.buffer.pixels = NULL; - extn->file.shmfile = shmfile_new(extn->svc.name, extn->svc.num, - ee->w * ee->h * 4, extn->svc.sys); - if (extn->file.shmfile) - ee->engine.buffer.pixels = extn->file.shmfile->addr; - - stride = ee->w * 4; - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); - if (einfo) + if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_EVASGL_PIXMAP || + _ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP) { - if (ee->alpha) - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - else - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.dest_buffer = ee->engine.buffer.pixels; - einfo->info.dest_buffer_row_bytes = stride; - einfo->info.use_color_key = 0; - einfo->info.alpha_threshold = 0; - einfo->info.func.new_update_region = NULL; - einfo->info.func.free_update_region = NULL; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + unsigned int foreground = 0; + Ecore_X_GC gc; + if (extn->b[extn->cur_b].pixmap) { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_x_pixmap_free(extn->b[extn->cur_b].pixmap); + extn->b[extn->cur_b].pixmap = 0; + } + ee->engine.buffer.pixels = NULL; + extn->b[extn->cur_b].w = ee->w; + extn->b[extn->cur_b].h = ee->h; + extn->b[extn->cur_b].pixmap = ecore_x_pixmap_new(0, ee->w, ee->h, 32); + gc = ecore_x_gc_new(extn->b[extn->cur_b].pixmap, ECORE_X_GC_VALUE_MASK_FOREGROUND, &foreground); + ecore_x_drawable_rectangle_fill(extn->b[extn->cur_b].pixmap, gc, 0, 0, ee->w, ee->h); + ecore_x_gc_free(gc); + + if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP) + { + if (!extn->file.dp) + extn->file.dp = _dri_drm_init(ecore_x_display_get(), DefaultRootWindow(ecore_x_display_get())); + if (!extn->file.dp) return; + ee->engine.buffer.pixels = _dri_drm_get_buffers(extn); + evas_output_size_set(ee->evas, extn->b[extn->cur_b].stride/4, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, extn->b[extn->cur_b].stride/4, ee->h); + + Evas_Engine_Info_Buffer *einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->alpha) + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + else + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + einfo->info.dest_buffer = ee->engine.buffer.pixels; + einfo->info.dest_buffer_row_bytes = extn->b[extn->cur_b].stride; + einfo->info.use_color_key = 0; + einfo->info.alpha_threshold = 0; + einfo->info.func.new_update_region = NULL; + einfo->info.func.free_update_region = NULL; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + } + } + + if (extn->ipc.clients && extn->b[extn->cur_b].pixmap) + { + Ipc_Data_Resize ipc; + Eina_List *l; + Ecore_Ipc_Client *client; + + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_PIXMAP_REF, + ee->w, ee->h, ee->alpha, + &extn->b[extn->cur_b].pixmap, + sizeof(Ecore_X_Pixmap)); + ipc.w = ee->w; + ipc.h = ee->h; + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_RESIZE, + 0, 0, 0, &ipc, sizeof(ipc)); } } + else if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_GL_PIXMAP) + { + extn->b[extn->cur_b].pixmap = ecore_evas_gl_x11_pixmap_get(ee); - if (extn->ipc.clients && extn->file.shmfile) + if (extn->ipc.clients && extn->b[extn->cur_b].pixmap) + { + Ipc_Data_Resize ipc; + Eina_List *l; + Ecore_Ipc_Client *client; + + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + { + ecore_ipc_client_send(client, MAJOR, OP_PIXMAP_IDX, 0, 0, extn->cur_b, NULL, 0); + ecore_ipc_client_send(client, MAJOR, OP_PIXMAP_REF, + ee->w, ee->h, ee->alpha, + &extn->b[extn->cur_b].pixmap, + sizeof(Ecore_X_Pixmap)); + } + ipc.w = ee->w; + ipc.h = ee->h; + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_RESIZE, + 0, 0, 0, &ipc, sizeof(ipc)); + } + } + else { - Ipc_Data_Resize ipc; - Eina_List *l; - Ecore_Ipc_Client *client; + if (extn->b[extn->cur_b].shmfile) + shmfile_free(extn->b[extn->cur_b].shmfile); + ee->engine.buffer.pixels = NULL; + extn->b[extn->cur_b].shmfile = shmfile_new(extn->svc.name, extn->svc.num, + ee->w * ee->h * 4, extn->svc.sys); + if (extn->b[extn->cur_b].shmfile) + ee->engine.buffer.pixels = extn->b[extn->cur_b].shmfile->addr; + + stride = ee->w * 4; + Evas_Engine_Info_Buffer *einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->alpha) + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + else + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + einfo->info.dest_buffer = ee->engine.buffer.pixels; + einfo->info.dest_buffer_row_bytes = stride; + einfo->info.use_color_key = 0; + einfo->info.alpha_threshold = 0; + einfo->info.func.new_update_region = NULL; + einfo->info.func.free_update_region = NULL; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + } - EINA_LIST_FOREACH(extn->ipc.clients, l, client) - ecore_ipc_client_send(client, MAJOR, OP_SHM_REF, - ee->w, ee->h, ee->alpha, - extn->file.shmfile->file, - strlen(extn->file.shmfile->file) + 1); - ipc.w = ee->w; - ipc.h = ee->h; - EINA_LIST_FOREACH(extn->ipc.clients, l, client) - ecore_ipc_client_send(client, MAJOR, OP_RESIZE, - 0, 0, 0, &ipc, sizeof(ipc)); + if (extn->ipc.clients && extn->b[extn->cur_b].shmfile) + { + Ipc_Data_Resize ipc; + Eina_List *l; + Ecore_Ipc_Client *client; + + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_SHM_REF, + ee->w, ee->h, ee->alpha, + extn->b[extn->cur_b].shmfile->file, + strlen(extn->b[extn->cur_b].shmfile->file) + 1); + ipc.w = ee->w; + ipc.h = ee->h; + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_RESIZE, + 0, 0, 0, &ipc, sizeof(ipc)); + } } } if (ee->func.fn_resize) ee->func.fn_resize(ee); @@ -1595,6 +2396,7 @@ _ecore_evas_extn_socket_render(Ecore_Evas *ee) Ecore_Ipc_Client *client; extn = ee->engine.buffer.data; + if (!extn) return rend; EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) { if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); @@ -1604,12 +2406,15 @@ _ecore_evas_extn_socket_render(Ecore_Evas *ee) } if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); - if (ee->engine.buffer.pixels) + if (ee->engine.buffer.pixels || + _ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_GL_PIXMAP) { _ecore_evas_socket_lock(ee); updates = evas_render_updates(ee->evas); _ecore_evas_socket_unlock(ee); } + else evas_norender(ee->evas); + EINA_LIST_FOREACH(updates, l, r) { Ipc_Data_Update ipc; @@ -1626,11 +2431,30 @@ _ecore_evas_extn_socket_render(Ecore_Evas *ee) { evas_render_updates_free(updates); _ecore_evas_idle_timeout_update(ee); - EINA_LIST_FOREACH(extn->ipc.clients, ll, client) - ecore_ipc_client_send(client, MAJOR, OP_UPDATE_DONE, 0, 0, 0, NULL, 0); + if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_GL_PIXMAP) + { + extn->b[extn->cur_b].pixmap = ecore_evas_gl_x11_pixmap_get(ee); + EINA_LIST_FOREACH(extn->ipc.clients, ll, client) + { + ecore_ipc_client_send(client, MAJOR, OP_UPDATE_DONE, 0, 0, extn->cur_b, NULL, 0); + ecore_ipc_client_send(client, MAJOR, OP_PIXMAP_REF, + ee->w, ee->h, ee->alpha, + &extn->b[extn->cur_b].pixmap, + sizeof(Ecore_X_Pixmap)); + } + } + else + { + EINA_LIST_FOREACH(extn->ipc.clients, ll, client) + ecore_ipc_client_send(client, MAJOR, OP_UPDATE_DONE, 0, 0, 0, NULL, 0); + } + + extn->cur_b++; + if (extn->cur_b >= extn->max_b) extn->cur_b = 0; } if (ee->func.fn_post_render) ee->func.fn_post_render(ee); + return updates ? 1 : rend; } @@ -1640,6 +2464,7 @@ _ipc_client_add(void *data, int type __UNUSED__, void *event) Ecore_Ipc_Event_Client_Add *e = event; Ecore_Evas *ee = data; Extn *extn; + int i; if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client))) return ECORE_CALLBACK_PASS_ON; @@ -1649,22 +2474,43 @@ _ipc_client_add(void *data, int type __UNUSED__, void *event) if (!extn) return ECORE_CALLBACK_PASS_ON; extn->ipc.clients = eina_list_append(extn->ipc.clients, e->client); - ecore_ipc_client_send(e->client, MAJOR, OP_LOCK_FILE, 0, 0, 0, extn->file.lock, strlen(extn->file.lock) + 1); - if (extn->file.shmfile) + for (i = 0; i < extn->max_b; i++) { - Ipc_Data_Resize ipc; + ecore_ipc_client_send(e->client, MAJOR, OP_LOCK_FILE, 0, 0, i, extn->b[i].lock, strlen(extn->b[i].lock) + 1); + if (extn->b[i].shmfile) + { + Ipc_Data_Resize ipc; + + ecore_ipc_client_send(e->client, MAJOR, OP_SHM_REF, + ee->w, ee->h, ee->alpha, + extn->b[i].shmfile->file, + strlen(extn->b[i].shmfile->file) + 1); + ipc.w = ee->w; + ipc.h = ee->h; - ecore_ipc_client_send(e->client, MAJOR, OP_SHM_REF, - ee->w, ee->h, ee->alpha, - extn->file.shmfile->file, - strlen(extn->file.shmfile->file) + 1); - ipc.w = ee->w; - ipc.h = ee->h; + ecore_ipc_client_send(e->client, MAJOR, OP_RESIZE, + 0, 0, 0, &ipc, sizeof(ipc)); + } + else if (extn->b[i].pixmap) + { + Ipc_Data_Resize ipc; - ecore_ipc_client_send(e->client, MAJOR, OP_RESIZE, - 0, 0, 0, &ipc, sizeof(ipc)); + ecore_ipc_client_send(e->client, MAJOR, OP_PIXMAP_IDX, 0, 0, i, NULL, 0); + ecore_ipc_client_send(e->client, MAJOR, OP_PIXMAP_REF, + ee->w, ee->h, ee->alpha, + &extn->b[i].pixmap, + sizeof(Ecore_X_Pixmap)); + ipc.w = ee->w; + ipc.h = ee->h; + + ecore_ipc_client_send(e->client, MAJOR, OP_RESIZE, + 0, 0, 0, &ipc, sizeof(ipc)); + } } + ecore_ipc_client_send(e->client, MAJOR, OP_PIXMAP_IDX, 0, 0, extn->cur_b, NULL, 0); + + _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_ADD); return ECORE_CALLBACK_PASS_ON; } @@ -1742,6 +2588,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } break; case OP_EV_MOUSE_IN: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_In)) { Ipc_Data_Ev_Mouse_In *ipc = e->data; @@ -1755,6 +2602,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } break; case OP_EV_MOUSE_OUT: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Out)) { Ipc_Data_Ev_Mouse_Out *ipc = e->data; @@ -1768,6 +2616,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } break; case OP_EV_MOUSE_UP: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Up)) { Ipc_Data_Ev_Mouse_Up *ipc = e->data; @@ -1781,6 +2630,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } break; case OP_EV_MOUSE_DOWN: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Down)) { Ipc_Data_Ev_Mouse_Up *ipc = e->data; @@ -1794,6 +2644,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } break; case OP_EV_MOUSE_MOVE: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Move)) { Ipc_Data_Ev_Mouse_Move *ipc = e->data; @@ -1807,6 +2658,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } break; case OP_EV_MOUSE_WHEEL: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Wheel)) { Ipc_Data_Ev_Mouse_Wheel *ipc = e->data; @@ -1820,6 +2672,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } break; case OP_EV_MULTI_UP: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Up)) { Ipc_Data_Ev_Multi_Up *ipc = e->data; @@ -1833,6 +2686,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } break; case OP_EV_MULTI_DOWN: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Down)) { Ipc_Data_Ev_Multi_Down *ipc = e->data; @@ -1846,6 +2700,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } break; case OP_EV_MULTI_MOVE: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Move)) { Ipc_Data_Ev_Multi_Move *ipc = e->data; @@ -1868,6 +2723,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } while (0) case OP_EV_KEY_UP: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Up)) { if ((e->data) && (e->size > 0) && @@ -1889,6 +2745,7 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) } break; case OP_EV_KEY_DOWN: + if (ee->events_block) break; if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Down)) { if ((e->data) && (e->size > 0) && @@ -1921,6 +2778,18 @@ _ipc_client_data(void *data, int type __UNUSED__, void *event) evas_event_default_flags_set(ee->evas, flags); } break; + case OP_MSG: + if ((e->data) && (e->size > 0)) + { + //ref = msg_domain + //ref_to = msg_id + if (ee->func.fn_msg_parent_handle) + { + INF("Msg(from client): msg_domain=%x msg_id=%x size=%d", e->ref, e->ref_to, e->size); + ee->func.fn_msg_parent_handle(ee, e->ref, e->ref_to, e->data, e->size); + } + } + break; default: break; } @@ -1940,23 +2809,113 @@ _ecore_evas_extn_socket_alpha_set(Ecore_Evas *ee, int alpha) extn = ee->engine.buffer.data; if (extn) { - Evas_Engine_Info_Buffer *einfo; + if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_EVASGL_PIXMAP) + { + if (evas_output_method_get(ee->evas) == evas_render_method_lookup("gl_x11")) + { + Evas_Engine_Info_GL_X11 *einfo; + + einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.destination_alpha = alpha; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + } + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_PIXMAP_REF, + ee->w, ee->h, ee->alpha, + &extn->b[extn->cur_b].pixmap, + sizeof(Ecore_X_Pixmap)); + } + else if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_GL_PIXMAP) + { + if (evas_output_method_get(ee->evas) == evas_render_method_lookup("gl_x11")) + { + Evas_Engine_Info_GL_X11 *einfo; + + einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.destination_alpha = alpha; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + } + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + { + int i; + + for (i = 0; i < extn->max_b; i++) + { + ecore_ipc_client_send(client, MAJOR, OP_PIXMAP_IDX, 0, 0, i, NULL, 0); + ecore_ipc_client_send(client, MAJOR, OP_PIXMAP_REF, + ee->w, ee->h, ee->alpha, + &extn->b[i].pixmap, + sizeof(Ecore_X_Pixmap)); + } + ecore_ipc_client_send(client, MAJOR, OP_PIXMAP_IDX, 0, 0, extn->cur_b, NULL, 0); + } + } + else if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP) + { + Evas_Engine_Info_Buffer *einfo; - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); - if (einfo) + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->alpha) + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + else + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_PIXMAP_REF, + ee->w, ee->h, ee->alpha, + &extn->b[extn->cur_b].pixmap, + sizeof(Ecore_X_Pixmap)); + } + else { - if (ee->alpha) - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - else - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); - evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + Evas_Engine_Info_Buffer *einfo; + + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->alpha) + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + else + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_SHM_REF, + ee->w, ee->h, ee->alpha, + extn->b[extn->cur_b].shmfile->file, + strlen(extn->b[extn->cur_b].shmfile->file) + 1); } + } +} + +static void +_ecore_evas_extn_socket_msg_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size) +{ + Extn *extn; + Eina_List *l; + Ecore_Ipc_Client *client; + + extn = ee->engine.buffer.data; + if (extn) + { EINA_LIST_FOREACH(extn->ipc.clients, l, client) - ecore_ipc_client_send(client, MAJOR, OP_SHM_REF, - ee->w, ee->h, ee->alpha, - extn->file.shmfile->file, - strlen(extn->file.shmfile->file) + 1); + ecore_ipc_client_send(client, MAJOR, OP_MSG_PARENT, + msg_domain, msg_id, 0, + data, + size); } } @@ -2020,6 +2979,15 @@ static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func = _ecore_evas_extn_socket_render, // render NULL, // screen_geometry_get NULL, // screen_dpi_get + NULL, + _ecore_evas_extn_socket_msg_send, + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; #endif @@ -2028,72 +2996,117 @@ EAPI Ecore_Evas * ecore_evas_extn_socket_new(int w, int h) { #ifdef BUILD_ECORE_EVAS_EXTN - Evas_Engine_Info_Buffer *einfo; Ecore_Evas *ee; int rmethod; + char *engine = NULL; - rmethod = evas_render_method_lookup("buffer"); - if (!rmethod) return NULL; - ee = calloc(1, sizeof(Ecore_Evas)); - if (!ee) return NULL; - - ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); - - ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_socket_engine_func; - - ee->driver = "extn_socket"; - - ee->rotation = 0; - ee->visible = 0; - ee->w = w; - ee->h = h; - ee->req.w = ee->w; - ee->req.h = ee->h; - - ee->prop.max.w = 0; - ee->prop.max.h = 0; - ee->prop.layer = 0; - ee->prop.focused = 0; - ee->prop.borderless = 1; - ee->prop.override = 1; - ee->prop.maximized = 0; - ee->prop.fullscreen = 0; - ee->prop.withdrawn = 0; - ee->prop.sticky = 0; - - /* init evas here */ - ee->evas = evas_new(); - evas_data_attach_set(ee->evas, ee); - evas_output_method_set(ee->evas, rmethod); - evas_output_size_set(ee->evas, w, h); - evas_output_viewport_set(ee->evas, 0, 0, w, h); + engine = getenv("ECORE_EVAS_EXTN_SOCKET_ENGINE"); + if (engine) + { + if ((!strcasecmp(engine, "opengl")) || + (!strcasecmp(engine, "gl")) || + (!strcasecmp(engine, "opengl-x11")) || + (!strcasecmp(engine, "opengl_x11")) || + (!strcasecmp(engine, "gl_x11"))) + engine = "gl_x11"; + else if ((!strcasecmp(engine, "gl_pixmap"))) + engine = "gl_pixmap"; + else if ((!strcasecmp(engine, "x11")) || + (!strcasecmp(engine, "x")) || + (!strcasecmp(engine, "software-x11")) || + (!strcasecmp(engine, "software_x11"))) + engine = "software_x11"; + else if (!strcasecmp(engine, "buffer")) + engine = "buffer"; + else + engine = "software_x11"; + } + else + engine = "software_x11"; - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); - if (einfo) + if (!strcmp(engine, "gl_x11")) { - if (ee->alpha) - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + ee = ecore_evas_gl_x11_new(NULL, NULL, 0, 0, w, h); + if (!ee) return NULL; + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_socket_engine_func; + ee->visible = 0; + } + else if (!strcmp(engine, "gl_pixmap")) + { + ee = ecore_evas_gl_x11_pixmap_new(NULL, NULL, 0, 0, w, h); + if (!ee) return NULL; + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_socket_engine_func; + ee->visible = 0; + } + else + { + Evas_Engine_Info_Buffer *einfo; + rmethod = evas_render_method_lookup("buffer"); + if (!rmethod) return NULL; + if (!strcmp(engine, "software_x11") && !ecore_x_init(NULL)) return NULL; + ee = calloc(1, sizeof(Ecore_Evas)); + if (!ee) return NULL; + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_socket_engine_func; + + ee->driver = "extn_socket"; + + ee->rotation = 0; + ee->visible = 0; + ee->w = w; + ee->h = h; + ee->req.w = ee->w; + ee->req.h = ee->h; + + ee->prop.max.w = 0; + ee->prop.max.h = 0; + ee->prop.layer = 0; + ee->prop.focused = 0; + ee->prop.borderless = 1; + ee->prop.override = 1; + ee->prop.maximized = 0; + ee->prop.fullscreen = 0; + ee->prop.withdrawn = 0; + ee->prop.sticky = 0; + + /* init evas here */ + ee->evas = evas_new(); + evas_data_attach_set(ee->evas, ee); + evas_output_method_set(ee->evas, rmethod); + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->alpha) + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + else + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + einfo->info.dest_buffer = NULL; + einfo->info.dest_buffer_row_bytes = 0; + einfo->info.use_color_key = 0; + einfo->info.alpha_threshold = 0; + einfo->info.func.new_update_region = NULL; + einfo->info.func.free_update_region = NULL; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } else - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.dest_buffer = NULL; - einfo->info.dest_buffer_row_bytes = 0; - einfo->info.use_color_key = 0; - einfo->info.alpha_threshold = 0; - einfo->info.func.new_update_region = NULL; - einfo->info.func.free_update_region = NULL; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); ecore_evas_free(ee); return NULL; } + _ecore_evas_register(ee); } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } + evas_key_modifier_add(ee->evas, "Shift"); evas_key_modifier_add(ee->evas, "Control"); evas_key_modifier_add(ee->evas, "Alt"); @@ -2106,8 +3119,6 @@ ecore_evas_extn_socket_new(int w, int h) extn_ee_list = eina_list_append(extn_ee_list, ee); - _ecore_evas_register(ee); - return ee; #else return NULL; @@ -2118,75 +3129,145 @@ EAPI Eina_Bool ecore_evas_extn_socket_listen(Ecore_Evas *ee, const char *svcname, int svcnum, Eina_Bool svcsys) { #ifdef BUILD_ECORE_EVAS_EXTN - Extn *extn; + Extn *extn = NULL; + char buf[PATH_MAX]; + Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER; + int i; extn = calloc(1, sizeof(Extn)); - if (!extn) - { - return EINA_FALSE; - } + if (!extn) return EINA_FALSE; + + ecore_ipc_init(); + extn->svc.name = eina_stringshare_add(svcname); + extn->svc.num = svcnum; + extn->svc.sys = svcsys; + if (ecore_evas_gl_x11_pixmap_get(ee)) + extn->max_b = 2; else + extn->max_b = 1; + + for (i = 0; i < extn->max_b; i++) { - Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER; - char buf[PATH_MAX]; + snprintf(buf, sizeof(buf), "/tmp/ee-lock-XXXXXXX"); + extn->b[i].lockfd = mkstemp(buf); - ecore_ipc_init(); - extn->svc.name = eina_stringshare_add(svcname); - extn->svc.num = svcnum; - extn->svc.sys = svcsys; + if (extn->b[i].lockfd >= 0) + extn->b[i].lock = eina_stringshare_add(buf); - snprintf(buf, sizeof(buf), "/tmp/ee-lock-XXXXXX"); - extn->file.lockfd = mkstemp(buf); - if (extn->file.lockfd >= 0) - extn->file.lock = eina_stringshare_add(buf); - if ((extn->file.lockfd < 0) || (!extn->file.lock)) - { - if (extn->file.lockfd) - { - close(extn->file.lockfd); - unlink(buf); - } - eina_stringshare_del(extn->svc.name); - if (extn->file.lock) eina_stringshare_del(extn->file.lock); - free(extn); - ecore_ipc_shutdown(); - return EINA_FALSE; - } + if (!extn->b[i].lock) goto err; + } - if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM; - extn->ipc.am_server = EINA_TRUE; - extn->ipc.server = ecore_ipc_server_add(ipctype, - (char *)extn->svc.name, - extn->svc.num, ee); - if (!extn->ipc.server) - { - if (extn->file.lockfd) - { - close(extn->file.lockfd); - if (extn->file.lock) unlink(extn->file.lock); - } - eina_stringshare_del(extn->svc.name); - eina_stringshare_del(extn->file.lock); - free(extn); - ecore_ipc_shutdown(); - return EINA_FALSE; - } - ee->engine.buffer.data = extn; - extn->ipc.handlers = eina_list_append - (extn->ipc.handlers, - ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, - _ipc_client_add, ee)); - extn->ipc.handlers = eina_list_append - (extn->ipc.handlers, - ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, - _ipc_client_del, ee)); - extn->ipc.handlers = eina_list_append - (extn->ipc.handlers, - ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, - _ipc_client_data, ee)); + if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM; + extn->ipc.am_server = EINA_TRUE; + extn->ipc.server = ecore_ipc_server_add(ipctype, + (char *)extn->svc.name, + extn->svc.num, ee); + if (!extn->ipc.server) + { + ERR("Extn socket failed to listen:ipctype=%d, svcname=%s, svcnum=%d, svcsys=%d", ipctype, svcname, svcnum, svcsys); + goto err; } + + ee->engine.buffer.data = extn; + extn->ipc.handlers = eina_list_append + (extn->ipc.handlers, + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, + _ipc_client_add, ee)); + extn->ipc.handlers = eina_list_append + (extn->ipc.handlers, + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, + _ipc_client_del, ee)); + extn->ipc.handlers = eina_list_append + (extn->ipc.handlers, + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, + _ipc_client_data, ee)); + INF("Extn socket listened: svcname=%s, svcnum=%d, svcsys=%d", svcname, svcnum, svcsys); return EINA_TRUE; + +err: + for (i = 0; i < extn->max_b; i++) + { + if (extn->b[i].lockfd) + { + close(extn->b[i].lockfd); + if (extn->b[i].lock) + { + eina_stringshare_del(extn->b[i].lock); + unlink(extn->b[i].lock); + } + } + } + if (extn->svc.name) eina_stringshare_del(extn->svc.name); + ecore_ipc_shutdown(); + + free(extn); + + return EINA_FALSE; #else return EINA_FALSE; #endif } + +EAPI void * +ecore_evas_extn_socket_pixels_get(Ecore_Evas *ee) +{ + Extn *extn; + + extn = ee->engine.buffer.data; + if (extn && (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_EVASGL_PIXMAP || + _ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_BUFFER_PIXMAP)) + { + return extn->b[extn->cur_b].pixmap; + } + else if (_ecore_evas_extn_type_get(ee) == ECORE_EVAS_EXTN_TYPE_GL_PIXMAP) + return ecore_evas_gl_x11_pixmap_get(ee); + + return ee->engine.buffer.pixels; +} + +EAPI void +ecore_evas_extn_socket_update_add(Ecore_Evas *ee, int x, int y, int w, int h) +{ + Eina_List *ll; + Ecore_Ipc_Client *client; + Ipc_Data_Update ipc; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + + ipc.x = x; + ipc.y = y; + ipc.w = w; + ipc.h = h; + EINA_LIST_FOREACH(extn->ipc.clients, ll, client) + ecore_ipc_client_send(client, MAJOR, OP_UPDATE, 0, 0, 0, &ipc, sizeof(ipc)); + + _ecore_evas_idle_timeout_update(ee); + EINA_LIST_FOREACH(extn->ipc.clients, ll, client) + ecore_ipc_client_send(client, MAJOR, OP_UPDATE_DONE, 0, 0, 0, NULL, 0); +} + +EAPI void +ecore_evas_extn_socket_lock(Ecore_Evas *ee) +{ + _ecore_evas_socket_lock(ee); +} + +EAPI void +ecore_evas_extn_socket_unlock(Ecore_Evas *ee) +{ + _ecore_evas_socket_unlock(ee); +} + +EINA_DEPRECATED EAPI void +ecore_evas_extn_socket_events_block_set(Ecore_Evas *ee, Eina_Bool events_block) +{ + ee->events_block = events_block; +} + +EINA_DEPRECATED EAPI Eina_Bool +ecore_evas_extn_socket_events_block_get(Ecore_Evas *ee) +{ + return ee->events_block; +} diff --git a/src/lib/ecore_evas/ecore_evas_fb.c b/src/lib/ecore_evas/ecore_evas_fb.c index a8200a9..9387780 100644 --- a/src/lib/ecore_evas/ecore_evas_fb.c +++ b/src/lib/ecore_evas/ecore_evas_fb.c @@ -562,7 +562,16 @@ static Ecore_Evas_Engine_Func _ecore_fb_engine_func = NULL, // render NULL, // screen_geometry_get - NULL // screen_dpi_get + NULL, // screen_dpi_get + NULL, + NULL, // msg_send + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; #endif diff --git a/src/lib/ecore_evas/ecore_evas_private.h b/src/lib/ecore_evas/ecore_evas_private.h index 6d45999..39a4c92 100644 --- a/src/lib/ecore_evas/ecore_evas_private.h +++ b/src/lib/ecore_evas/ecore_evas_private.h @@ -79,13 +79,15 @@ # include #endif -#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined(BUILD_ECORE_EVAS_WAYLAND_EGL) # include "Ecore_Wayland.h" +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM # include #endif #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL -# include "Ecore_Wayland.h" # include #endif @@ -128,6 +130,7 @@ typedef void (*Ecore_Evas_Event_Cb) (Ecore_Evas *ee); typedef struct _Ecore_Evas_Engine Ecore_Evas_Engine; typedef struct _Ecore_Evas_Engine_Func Ecore_Evas_Engine_Func; +typedef struct _Ecore_Evas_Aux_Hint Ecore_Evas_Aux_Hint; struct _Ecore_Evas_Engine_Func { @@ -189,6 +192,15 @@ struct _Ecore_Evas_Engine_Func int (*fn_render) (Ecore_Evas *ee); void (*fn_screen_geometry_get) (const Ecore_Evas *ee, int *x, int *y, int *w, int *h); void (*fn_screen_dpi_get) (const Ecore_Evas *ee, int *xdpi, int *ydpi); + void (*fn_msg_parent_send) (Ecore_Evas *ee, int maj, int min, void *data, int size); + void (*fn_msg_send) (Ecore_Evas *ee, int maj, int min, void *data, int size); + + void (*fn_wm_rot_preferred_rotation_set) (Ecore_Evas *ee, int rot); + void (*fn_wm_rot_available_rotations_set) (Ecore_Evas *ee, const int *rots, unsigned int count); + void (*fn_wm_rot_manual_rotation_done_set) (Ecore_Evas *ee, Eina_Bool set); + void (*fn_wm_rot_manual_rotation_done) (Ecore_Evas *ee); + + void (*fn_aux_hints_set) (Ecore_Evas *ee, const char *hints); }; struct _Ecore_Evas_Engine @@ -221,6 +233,14 @@ struct _Ecore_Evas_Engine unsigned char netwm_sync_set : 1; unsigned char configure_coming : 1; struct { + unsigned char supported: 1; + unsigned char prepare : 1; + unsigned char request : 1; + unsigned char done : 1; + unsigned char configure_coming : 1; + Ecore_Job *manual_mode_job; + } wm_rot; + struct { unsigned char modal : 1; unsigned char sticky : 1; unsigned char maximized_v : 1; @@ -233,6 +253,23 @@ struct _Ecore_Evas_Engine unsigned char below : 1; } state; Ecore_X_Window win_shaped_input; + Ecore_Job *deiconify_job; + Ecore_Idle_Enterer *manual_render_idle_enterer; /**< idle enterer for manual render on + ECORE_X_ATOM_E_COMP_SYNC_BEGIN, + ECORE_X_EVENT_WINDOW_CONFIGURE, + and rotation. + */ + Eina_Bool manual_render_by_ecore_evas : 1; /**< mark this true if the manual render was set by ecore_evas */ + Eina_Bool deiconify_approve_after_manual_render : 1; /**< marked when deiconify approve should be sent after manual rendering in idle enterer */ + struct + { + unsigned int front, back; // front and back pixmaps (double-buffer) + Evas_Coord front_w, front_h; // store pixmap size for front pixmap + Evas_Coord back_w, back_h; // store pixmap size for back pixmap + int depth; // store depth to save us from fetching engine info pre_render + void *visual; // store visual used to create pixmap + unsigned long colormap; // store colormap used to create pixmap + } pixmap; } x; #endif #ifdef BUILD_ECORE_EVAS_FB @@ -313,6 +350,7 @@ struct _Ecore_Evas Eina_Bool alpha : 1; Eina_Bool transparent : 1; Eina_Bool in : 1; + Eina_Bool events_block : 1; Eina_Hash *data; @@ -332,7 +370,29 @@ struct _Ecore_Evas char *title; char *name; char *clas; - char *profile; + const char *profile; + struct { + Eina_Bool supported; + int angle; // v0 + Eina_Bool win_resize; // v0 + int w, h; // v0 + // added for the window manager rotation protocol + Eina_Bool app_set; // v1: app wants to communicate with the window manager to rotate + int rot; // v1: decided rotation by the window manager + int preferred_rot; // v1: app specified rotation + int *available_rots;// v1: app specified available rotations + unsigned int count; // v1: number of elements of available rotations + struct { + Eina_Bool set; // v1: app wants to send 'rotation_done' message manually + Eina_Bool wait_for_done; // v1: wait for app's 'rotation_done' + Ecore_Timer *timer; // v1: timer to check app's request has expired + } manual_mode; + } wm_rot; + struct { + Eina_List *supported_list; + Eina_List *hints; + int id; + } aux_hint; struct { int w, h; } min, @@ -386,6 +446,8 @@ struct _Ecore_Evas void (*fn_post_render) (Ecore_Evas *ee); void (*fn_pre_free) (Ecore_Evas *ee); void (*fn_state_change) (Ecore_Evas *ee); + void (*fn_msg_parent_handle) (Ecore_Evas *ee, int maj, int min, void *data, int size); + void (*fn_msg_handle) (Ecore_Evas *ee, int maj, int min, void *data, int size); } func; Ecore_Evas_Engine engine; @@ -399,7 +461,24 @@ struct _Ecore_Evas unsigned char no_comp_sync : 1; unsigned char semi_sync : 1; unsigned char deleted : 1; - int gl_sync_draw_done; // added by gl77.lee + + /* TIZEN ONLY + * Disable sync draw done from application side when it is needed. + * Currently this is set true when a back-end engine uses DRI2. + * This depends on engine so we need to check it from evas engine. + */ + Eina_Bool disable_sync_draw_done : 1; + + int gl_sync_draw_done; +}; + +struct _Ecore_Evas_Aux_Hint +{ + int id; // ID of aux hint + const char *hint; // hint string + const char *val; // value string + unsigned char allowed : 1; // received allowed event from the window manager + unsigned char notified : 1; // let caller know ee has got response for this aux hint }; void _ecore_evas_ref(Ecore_Evas *ee); @@ -429,20 +508,47 @@ void _ecore_evas_ews_events_init(void); int _ecore_evas_ews_shutdown(void); #endif +#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined(BUILD_ECORE_EVAS_WAYLAND_EGL) +int _ecore_evas_wl_common_init(void); +int _ecore_evas_wl_common_shutdown(void); +void _ecore_evas_wl_common_pre_free(Ecore_Evas *ee); +void _ecore_evas_wl_common_free(Ecore_Evas *ee); +void _ecore_evas_wl_common_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_move(Ecore_Evas *ee, int x, int y); +void _ecore_evas_wl_common_raise(Ecore_Evas *ee); +void _ecore_evas_wl_common_title_set(Ecore_Evas *ee, const char *title); +void _ecore_evas_wl_common_name_class_set(Ecore_Evas *ee, const char *n, const char *c); +void _ecore_evas_wl_common_size_min_set(Ecore_Evas *ee, int w, int h); +void _ecore_evas_wl_common_size_max_set(Ecore_Evas *ee, int w, int h); +void _ecore_evas_wl_common_size_base_set(Ecore_Evas *ee, int w, int h); +void _ecore_evas_wl_common_size_step_set(Ecore_Evas *ee, int w, int h); +void _ecore_evas_wl_common_layer_set(Ecore_Evas *ee, int layer); +void _ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, int iconify); +void _ecore_evas_wl_common_maximized_set(Ecore_Evas *ee, int max); +void _ecore_evas_wl_common_fullscreen_set(Ecore_Evas *ee, int full); +void _ecore_evas_wl_common_ignore_events_set(Ecore_Evas *ee, int ignore); +int _ecore_evas_wl_common_pre_render(Ecore_Evas *ee); +int _ecore_evas_wl_common_render_updates(Ecore_Evas *ee); +void _ecore_evas_wl_common_post_render(Ecore_Evas *ee); +int _ecore_evas_wl_common_render(Ecore_Evas *ee); +void _ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); +void _ecore_evas_wl_common_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi); + +Evas_Object * _ecore_evas_wl_common_frame_add(Evas *evas); + #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM void _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location); -void _ecore_evas_wayland_shm_move(Ecore_Evas *ee, int x, int y); -void _ecore_evas_wayland_shm_drag_start(Ecore_Evas *ee, Ecore_Evas *drag_ee, void *source); -void _ecore_evas_wayland_shm_pointer_set(Ecore_Evas *ee, int hot_x, int hot_y); -void _ecore_evas_wayland_shm_type_set(Ecore_Evas *ee, int type); #endif #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL void _ecore_evas_wayland_egl_resize(Ecore_Evas *ee, int location); -void _ecore_evas_wayland_egl_move(Ecore_Evas *ee, int x, int y); -void _ecore_evas_wayland_egl_drag_start(Ecore_Evas *ee, Ecore_Evas *drag_ee, void *source); -void _ecore_evas_wayland_egl_pointer_set(Ecore_Evas *ee, int hot_x, int hot_y); -void _ecore_evas_wayland_egl_type_set(Ecore_Evas *ee, int type); +#endif #endif void _ecore_evas_fps_debug_init(void); @@ -484,4 +590,7 @@ extern Eina_Bool _ecore_evas_app_comp_sync; void _ecore_evas_extn_init(void); void _ecore_evas_extn_shutdown(void); +Eina_Strbuf *_ecore_evas_aux_hints_string_get(Ecore_Evas *ee); +void _ecore_evas_aux_hint_free(Ecore_Evas *ee); + #endif diff --git a/src/lib/ecore_evas/ecore_evas_psl1ght.c b/src/lib/ecore_evas/ecore_evas_psl1ght.c index 98d570e..ca8f8fa 100644 --- a/src/lib/ecore_evas/ecore_evas_psl1ght.c +++ b/src/lib/ecore_evas/ecore_evas_psl1ght.c @@ -406,7 +406,16 @@ static Ecore_Evas_Engine_Func _ecore_psl1ght_engine_func = NULL, // render _ecore_evas_screen_geometry_get, // screen_geometry_get - NULL // screen_dpi_get + NULL, // screen_dpi_get + NULL, + NULL, //msg_send + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; EAPI Ecore_Evas * diff --git a/src/lib/ecore_evas/ecore_evas_sdl.c b/src/lib/ecore_evas/ecore_evas_sdl.c index da1ddbd..1b6a7e0 100644 --- a/src/lib/ecore_evas/ecore_evas_sdl.c +++ b/src/lib/ecore_evas/ecore_evas_sdl.c @@ -135,6 +135,8 @@ _ecore_evas_sdl_event_video_resize(void *data __UNUSED__, int type __UNUSED__, v ee->w = e->w; ee->h = e->h; + ee->req.w = e->w; + ee->req.h = e->h; evas_output_size_set(ee->evas, e->w, e->h); evas_output_viewport_set(ee->evas, 0, 0, e->w, e->h); @@ -274,6 +276,8 @@ _ecore_evas_resize(Ecore_Evas *ee, int w, int h) int rmethod; if ((w == ee->w) && (h == ee->h)) return; + ee->req.w = w; + ee->req.h = h; ee->w = w; ee->h = h; @@ -324,6 +328,8 @@ static void _ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h) { if ((w == ee->w) && (h == ee->h)) return; + ee->req.w = w; + ee->req.h = h; ee->w = w; ee->h = h; @@ -442,7 +448,16 @@ static Ecore_Evas_Engine_Func _ecore_sdl_engine_func = NULL, // render NULL, // screen_geometry_get - NULL // screen_dpi_get + NULL, // screen_dpi_get + NULL, + NULL, // msg_send + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; static Ecore_Evas* @@ -466,6 +481,8 @@ _ecore_evas_internal_sdl_new(int rmethod, const char* name, int w, int h, int fu if (w < 1) w = 1; if (h < 1) h = 1; ee->visible = 1; + ee->req.w = w; + ee->req.h = h; ee->w = w; ee->h = h; diff --git a/src/lib/ecore_evas/ecore_evas_util.c b/src/lib/ecore_evas/ecore_evas_util.c index 5aca86c..a860969 100644 --- a/src/lib/ecore_evas/ecore_evas_util.c +++ b/src/lib/ecore_evas/ecore_evas_util.c @@ -424,8 +424,14 @@ ecore_getopt_callback_ecore_evas_list_engines(const Ecore_Getopt *parser __UNUSE { Eina_List *lst, *n; const char *engine; - FILE *fp = data; + if (!storage) + { + ERR("Storage is missing"); + return 0; + } + + FILE *fp = data; if (!fp) fp = stdout; diff --git a/src/lib/ecore_evas/ecore_evas_wayland_common.c b/src/lib/ecore_evas/ecore_evas_wayland_common.c new file mode 100644 index 0000000..257fd6e --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_wayland_common.c @@ -0,0 +1,657 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + +/* local structures */ +typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data; +struct _EE_Wl_Smart_Data +{ + Evas_Object *frame; + Evas_Object *text; + Evas_Coord x, y, w, h; +}; + +static Evas_Smart *_ecore_evas_wl_common_smart = NULL; + +/* local variables */ + +static int _ecore_evas_wl_init_count = 0; +static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[5]; + +static Eina_Bool +_ecore_evas_wl_common_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Mouse_In *ev; + + ev = event; + ee = ecore_event_window_match(ev->window); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; + if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (!ee->in) + { + if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); + ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); + evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); + ee->in = EINA_TRUE; + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_common_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Mouse_Out *ev; + + ev = event; + ee = ecore_event_window_match(ev->window); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; + if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (ee->in) + { + ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); + evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL); + if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); + if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); + ee->in = EINA_FALSE; + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_common_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Focus_In *ev; + + ev = event; + ee = ecore_event_window_match(ev->win); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; + if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + ee->prop.focused = 1; + evas_focus_in(ee->evas); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_common_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Focus_In *ev; + + ev = event; + ee = ecore_event_window_match(ev->win); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; + if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + evas_focus_out(ee->evas); + ee->prop.focused = 0; + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_common_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Window_Configure *ev; + int nw = 0, nh = 0; + + ev = event; + ee = ecore_event_window_match(ev->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; + if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + + if (ee->prop.fullscreen) + { + _ecore_evas_wl_common_move(ee, ev->x, ev->y); + ee->engine.func->fn_resize(ee, ev->w, ev->h); + + return ECORE_CALLBACK_PASS_ON; + } + + if ((ee->x != ev->x) || (ee->y != ev->y)) + { + ee->req.x = ee->x; + ee->req.y = ee->y; + if (ee->func.fn_move) ee->func.fn_move(ee); + } + + nw = ev->w; + nh = ev->h; + + if ((ee->prop.maximized) || (!ee->prop.fullscreen)) + { + int fw = 0, fh = 0; + + evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); + nw = ev->w - fw; + nh = ev->h - fh; + } + + if (ee->prop.min.w > nw) nw = ee->prop.min.w; + else if (nw > ee->prop.max.w) nw = ee->prop.max.w; + if (ee->prop.min.h > nh) nh = ee->prop.min.h; + else if (nh > ee->prop.max.h) nh = ee->prop.max.h; + + if ((ee->w != nw) || (ee->h != nh)) + { + ee->req.w = nw; + ee->req.h = nh; + if (ee->func.fn_resize) ee->func.fn_resize(ee); + } + + return ECORE_CALLBACK_PASS_ON; +} + +int +_ecore_evas_wl_common_init(void) +{ + if (++_ecore_evas_wl_init_count != 1) + return _ecore_evas_wl_init_count; + + _ecore_evas_wl_event_hdls[0] = + ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN, + _ecore_evas_wl_common_cb_mouse_in, NULL); + _ecore_evas_wl_event_hdls[1] = + ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT, + _ecore_evas_wl_common_cb_mouse_out, NULL); + _ecore_evas_wl_event_hdls[2] = + ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, + _ecore_evas_wl_common_cb_focus_in, NULL); + _ecore_evas_wl_event_hdls[3] = + ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, + _ecore_evas_wl_common_cb_focus_out, NULL); + _ecore_evas_wl_event_hdls[4] = + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, + _ecore_evas_wl_common_cb_window_configure, NULL); + + ecore_event_evas_init(); + + return _ecore_evas_wl_init_count; +} + +int +_ecore_evas_wl_common_shutdown(void) +{ + unsigned int i = 0; + + if (--_ecore_evas_wl_init_count != 0) + return _ecore_evas_wl_init_count; + + for (i = 0; i < sizeof(_ecore_evas_wl_event_hdls) / sizeof(Ecore_Event_Handler *); i++) + { + if (_ecore_evas_wl_event_hdls[i]) + ecore_event_handler_del(_ecore_evas_wl_event_hdls[i]); + } + + ecore_event_evas_shutdown(); + + return _ecore_evas_wl_init_count; +} + +void +_ecore_evas_wl_common_pre_free(Ecore_Evas *ee) +{ + if (!ee) return; + if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame); +} + +void +_ecore_evas_wl_common_free(Ecore_Evas *ee) +{ + if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win); + ee->engine.wl.win = NULL; + + ecore_event_window_unregister(ee->prop.window); + ecore_evas_input_event_unregister(ee); + + _ecore_evas_wl_common_shutdown(); + ecore_wl_shutdown(); +} + +void +_ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h) +{ + if (w < 1) w = 1; + if (h < 1) h = 1; + + ee->req.w = w; + ee->req.h = h; + + if (!ee->prop.fullscreen) + { + int fw = 0, fh = 0; + + if (ee->prop.min.w > w) w = ee->prop.min.w; + else if (w > ee->prop.max.w) w = ee->prop.max.w; + if (ee->prop.min.h > h) h = ee->prop.min.h; + else if (h > ee->prop.max.h) h = ee->prop.max.h; + + evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); + w += fw; + h += fh; + } + + if ((ee->w != w) || (ee->h != h)) + { + ee->w = w; + ee->h = h; + + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + evas_output_size_set(ee->evas, h, w); + evas_output_viewport_set(ee->evas, 0, 0, h, w); + } + else + { + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + } + + if (ee->prop.avoid_damage) + { + int pdam = 0; + + pdam = ecore_evas_avoid_damage_get(ee); + ecore_evas_avoid_damage_set(ee, 0); + ecore_evas_avoid_damage_set(ee, pdam); + } + + if (ee->engine.wl.frame) + evas_object_resize(ee->engine.wl.frame, w, h); + } +} + +void +_ecore_evas_wl_common_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_resize = func; +} + +void +_ecore_evas_wl_common_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_move = func; +} + +void +_ecore_evas_wl_common_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_delete_request = func; +} + +void +_ecore_evas_wl_common_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_focus_in = func; +} + +void +_ecore_evas_wl_common_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_focus_out = func; +} + +void +_ecore_evas_wl_common_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_mouse_in = func; +} + +void +_ecore_evas_wl_common_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_mouse_out = func; +} + +void +_ecore_evas_wl_common_move(Ecore_Evas *ee, int x, int y) +{ + if (!ee) return; + + ee->req.x = x; + ee->req.y = y; + + if ((ee->x != x) || (ee->y != y)) + { + ee->x = x; + ee->y = y; + if (ee->engine.wl.win) + ecore_wl_window_update_location(ee->engine.wl.win, x, y); + if (ee->func.fn_move) ee->func.fn_move(ee); + } +} + +static void +_ecore_evas_wl_common_smart_add(Evas_Object *obj) +{ + EE_Wl_Smart_Data *sd; + Evas *evas; + + if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return; + + evas = evas_object_evas_get(obj); + + sd->x = 0; + sd->y = 0; + sd->w = 1; + sd->h = 1; + + sd->frame = evas_object_rectangle_add(evas); + evas_object_is_frame_object_set(sd->frame, EINA_TRUE); + evas_object_color_set(sd->frame, 249, 249, 249, 255); + evas_object_smart_member_add(sd->frame, obj); + + sd->text = evas_object_text_add(evas); + evas_object_color_set(sd->text, 0, 0, 0, 255); + evas_object_text_style_set(sd->text, EVAS_TEXT_STYLE_PLAIN); + evas_object_text_font_set(sd->text, "Sans", 10); + evas_object_text_text_set(sd->text, "Smart Test"); + + evas_object_smart_data_set(obj, sd); +} + +static void +_ecore_evas_wl_common_smart_del(Evas_Object *obj) +{ + EE_Wl_Smart_Data *sd; + + if (!(sd = evas_object_smart_data_get(obj))) return; + evas_object_del(sd->text); + evas_object_del(sd->frame); + free(sd); +} + +static void +_ecore_evas_wl_common_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) +{ + EE_Wl_Smart_Data *sd; + + if (!(sd = evas_object_smart_data_get(obj))) return; + if ((sd->w == w) && (sd->h == h)) return; + sd->w = w; + sd->h = h; + evas_object_resize(sd->frame, w, h); +} + +static void +_ecore_evas_wl_common_smart_show(Evas_Object *obj) +{ + EE_Wl_Smart_Data *sd; + + if (!(sd = evas_object_smart_data_get(obj))) return; + evas_object_show(sd->frame); + evas_object_show(sd->text); +} + +static void +_ecore_evas_wl_common_smart_hide(Evas_Object *obj) +{ + EE_Wl_Smart_Data *sd; + + if (!(sd = evas_object_smart_data_get(obj))) return; + evas_object_hide(sd->text); + evas_object_hide(sd->frame); +} + +static void +_ecore_evas_wl_common_smart_init(void) +{ + if (_ecore_evas_wl_common_smart) return; + { + static const Evas_Smart_Class sc = + { + "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION, + _ecore_evas_wl_common_smart_add, + _ecore_evas_wl_common_smart_del, + NULL, + _ecore_evas_wl_common_smart_resize, + _ecore_evas_wl_common_smart_show, + _ecore_evas_wl_common_smart_hide, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }; + _ecore_evas_wl_common_smart = evas_smart_class_new(&sc); + } +} + +Evas_Object * +_ecore_evas_wl_common_frame_add(Evas *evas) +{ + _ecore_evas_wl_common_smart_init(); + return evas_object_smart_add(evas, _ecore_evas_wl_common_smart); +} + +void +_ecore_evas_wl_common_raise(Ecore_Evas *ee) +{ + if ((!ee) || (!ee->visible)) return; + ecore_wl_window_raise(ee->engine.wl.win); +} + +void +_ecore_evas_wl_common_title_set(Ecore_Evas *ee, const char *title) +{ + if (!ee) return; + if (ee->prop.title) free(ee->prop.title); + ee->prop.title = NULL; + if (title) ee->prop.title = strdup(title); + if ((ee->prop.draw_frame) && (ee->engine.wl.frame)) + { + EE_Wl_Smart_Data *sd; + + if (!(sd = evas_object_smart_data_get(ee->engine.wl.frame))) return; + evas_object_text_text_set(sd->text, ee->prop.title); + } + + if ((ee->prop.title) && (ee->engine.wl.win->shell_surface)) + wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, + ee->prop.title); +} + +void +_ecore_evas_wl_common_name_class_set(Ecore_Evas *ee, const char *n, const char *c) +{ + if (!ee) return; + if (ee->prop.name) free(ee->prop.name); + if (ee->prop.clas) free(ee->prop.clas); + ee->prop.name = NULL; + ee->prop.clas = NULL; + if (n) ee->prop.name = strdup(n); + if (c) ee->prop.clas = strdup(c); + + if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) + wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, + ee->prop.clas); +} + +void +_ecore_evas_wl_common_size_min_set(Ecore_Evas *ee, int w, int h) +{ + if (!ee) return; + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return; + ee->prop.min.w = w; + ee->prop.min.h = h; +} + +void +_ecore_evas_wl_common_size_max_set(Ecore_Evas *ee, int w, int h) +{ + if (!ee) return; + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return; + ee->prop.max.w = w; + ee->prop.max.h = h; +} + +void +_ecore_evas_wl_common_size_base_set(Ecore_Evas *ee, int w, int h) +{ + if (!ee) return; + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return; + ee->prop.base.w = w; + ee->prop.base.h = h; +} + +void +_ecore_evas_wl_common_size_step_set(Ecore_Evas *ee, int w, int h) +{ + if (!ee) return; + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return; + ee->prop.step.w = w; + ee->prop.step.h = h; +} + +void +_ecore_evas_wl_common_layer_set(Ecore_Evas *ee, int layer) +{ + if (!ee) return; + if (ee->prop.layer == layer) return; + if (layer < 1) layer = 1; + else if (layer > 255) layer = 255; + ee->prop.layer = layer; +} + +void +_ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, int iconify) +{ + if (!ee) return; + if (ee->prop.iconified == iconify) return; + ee->prop.iconified = iconify; + /* FIXME: Implement this in Wayland someshow */ +} + +void +_ecore_evas_wl_common_maximized_set(Ecore_Evas *ee, int max) +{ + if (!ee) return; + if (ee->prop.maximized == max) return; + ee->prop.maximized = max; + ecore_wl_window_maximized_set(ee->engine.wl.win, max); +} + +void +_ecore_evas_wl_common_fullscreen_set(Ecore_Evas *ee, int full) +{ + if (!ee) return; + if (ee->prop.fullscreen == full) return; + ee->prop.fullscreen = full; + ecore_wl_window_fullscreen_set(ee->engine.wl.win, full); +} + +void +_ecore_evas_wl_common_ignore_events_set(Ecore_Evas *ee, int ignore) +{ + if (!ee) return; + ee->ignore_events = ignore; + /* NB: Hmmm, may need to pass this to ecore_wl_window in the future */ +} + +int +_ecore_evas_wl_common_pre_render(Ecore_Evas *ee) +{ + int rend = 0; + Eina_List *ll = NULL; + Ecore_Evas *ee2 = NULL; + + if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); + + EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) + { + if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); + if (ee2->engine.func->fn_render) + rend |= ee2->engine.func->fn_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + + return rend; +} + +int +_ecore_evas_wl_common_render_updates(Ecore_Evas *ee) +{ + int rend = 0; + Eina_List *updates = NULL; + + if ((updates = evas_render_updates(ee->evas))) + { + Eina_List *l = NULL; + Eina_Rectangle *r; + + EINA_LIST_FOREACH(updates, l, r) + ecore_wl_window_damage(ee->engine.wl.win, + r->x, r->y, r->w, r->h); + + ecore_wl_flush(); + + evas_render_updates_free(updates); + rend = 1; + } + + return rend; +} + +void +_ecore_evas_wl_common_post_render(Ecore_Evas *ee) +{ + _ecore_evas_idle_timeout_update(ee); + if (ee->func.fn_post_render) ee->func.fn_post_render(ee); +} + +int +_ecore_evas_wl_common_render(Ecore_Evas *ee) +{ + int rend = 0; + + if (!ee) return 0; + if (!ee->visible) + { + evas_norender(ee->evas); + return 0; + } + + rend = _ecore_evas_wl_common_pre_render(ee); + rend |= _ecore_evas_wl_common_render_updates(ee); + _ecore_evas_wl_common_post_render(ee); + + return rend; +} + +void +_ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h) +{ + if (x) *x = 0; + if (y) *y = 0; + ecore_wl_screen_size_get(w, h); +} + +void +_ecore_evas_wl_common_screen_dpi_get(const Ecore_Evas *ee __UNUSED__, int *xdpi, int *ydpi) +{ + int dpi = 0; + + if (xdpi) *xdpi = 0; + if (ydpi) *ydpi = 0; + /* FIXME: Ideally this needs to get the DPI from a specific screen */ + dpi = ecore_wl_dpi_get(); + if (xdpi) *xdpi = dpi; + if (ydpi) *ydpi = dpi; +} diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c b/src/lib/ecore_evas/ecore_evas_wayland_egl.c index 6b901a2..88f739c 100644 --- a/src/lib/ecore_evas/ecore_evas_wayland_egl.c +++ b/src/lib/ecore_evas/ecore_evas_wayland_egl.c @@ -2,7 +2,33 @@ # include "config.h" #endif -#define LOGFNS 1 +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +//#define LOGFNS 1 #ifdef LOGFNS # include @@ -21,98 +47,39 @@ #endif #include -#include -#include -#include "ecore_evas_private.h" #include "Ecore_Evas.h" #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +# include "ecore_evas_private.h" # include # include -/* local structures */ -typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data; -struct _EE_Wl_Smart_Data -{ - Evas_Object *frame; - Evas_Object *text; - Evas_Coord x, y, w, h; -}; - /* local function prototypes */ -static int _ecore_evas_wl_init(void); -static int _ecore_evas_wl_shutdown(void); -static void _ecore_evas_wl_pre_free(Ecore_Evas *ee); -static void _ecore_evas_wl_free(Ecore_Evas *ee); -static void _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y); static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h); static void _ecore_evas_wl_show(Ecore_Evas *ee); static void _ecore_evas_wl_hide(Ecore_Evas *ee); -static void _ecore_evas_wl_raise(Ecore_Evas *ee); -static void _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *title); -static void _ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c); -static void _ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer); -static void _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify); -static void _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max); -static void _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full); -static void _ecore_evas_wl_ignore_events_set(Ecore_Evas *ee, int ignore); static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha); static void _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent); -static int _ecore_evas_wl_render(Ecore_Evas *ee); -static void _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h); -static void _ecore_evas_wl_screen_dpi_get(const Ecore_Evas *ee __UNUSED__, int *xdpi, int *ydpi); -static Eina_Bool _ecore_evas_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event); -static Eina_Bool _ecore_evas_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event); -static Eina_Bool _ecore_evas_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event); -static Eina_Bool _ecore_evas_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event); -static Eina_Bool _ecore_evas_wl_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event); - -/* SMART stuff for frame */ -static Evas_Smart *_ecore_evas_wl_smart = NULL; - -static void _ecore_evas_wl_smart_init(void); -static void _ecore_evas_wl_smart_add(Evas_Object *obj); -static void _ecore_evas_wl_smart_del(Evas_Object *obj); -static void _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h); -static void _ecore_evas_wl_smart_show(Evas_Object *obj); -static void _ecore_evas_wl_smart_hide(Evas_Object *obj); - -static Evas_Object *_ecore_evas_wl_frame_add(Evas *evas); - -/* local variables */ -static int _ecore_evas_wl_init_count = 0; -static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[5]; static Ecore_Evas_Engine_Func _ecore_wl_engine_func = { - _ecore_evas_wl_free, - _ecore_evas_wl_callback_resize_set, - _ecore_evas_wl_callback_move_set, + _ecore_evas_wl_common_free, + _ecore_evas_wl_common_callback_resize_set, + _ecore_evas_wl_common_callback_move_set, NULL, NULL, - _ecore_evas_wl_callback_delete_request_set, + _ecore_evas_wl_common_callback_delete_request_set, NULL, - _ecore_evas_wl_callback_focus_in_set, - _ecore_evas_wl_callback_focus_out_set, - _ecore_evas_wl_callback_mouse_in_set, - _ecore_evas_wl_callback_mouse_out_set, + _ecore_evas_wl_common_callback_focus_in_set, + _ecore_evas_wl_common_callback_focus_out_set, + _ecore_evas_wl_common_callback_mouse_in_set, + _ecore_evas_wl_common_callback_mouse_out_set, NULL, // sticky_set NULL, // unsticky_set NULL, // pre_render_set NULL, // post_render_set - _ecore_evas_wl_move, + _ecore_evas_wl_common_move, NULL, // managed_move _ecore_evas_wl_resize, NULL, // move_resize @@ -120,39 +87,46 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func = NULL, // shaped_set _ecore_evas_wl_show, _ecore_evas_wl_hide, - _ecore_evas_wl_raise, + _ecore_evas_wl_common_raise, NULL, // lower NULL, // activate - _ecore_evas_wl_title_set, - _ecore_evas_wl_name_class_set, - _ecore_evas_wl_size_min_set, - _ecore_evas_wl_size_max_set, - _ecore_evas_wl_size_base_set, - _ecore_evas_wl_size_step_set, + _ecore_evas_wl_common_title_set, + _ecore_evas_wl_common_name_class_set, + _ecore_evas_wl_common_size_min_set, + _ecore_evas_wl_common_size_max_set, + _ecore_evas_wl_common_size_base_set, + _ecore_evas_wl_common_size_step_set, NULL, // object_cursor_set - _ecore_evas_wl_layer_set, + _ecore_evas_wl_common_layer_set, NULL, // focus set - _ecore_evas_wl_iconified_set, + _ecore_evas_wl_common_iconified_set, NULL, // borderless set NULL, // override set - _ecore_evas_wl_maximized_set, - _ecore_evas_wl_fullscreen_set, + _ecore_evas_wl_common_maximized_set, + _ecore_evas_wl_common_fullscreen_set, NULL, // func avoid_damage set NULL, // func withdrawn set NULL, // func sticky set - _ecore_evas_wl_ignore_events_set, + _ecore_evas_wl_common_ignore_events_set, _ecore_evas_wl_alpha_set, _ecore_evas_wl_transparent_set, NULL, // func profiles set + NULL, // window group set + NULL, // aspect set + NULL, // urgent set + NULL, // modal set + NULL, // demand attention set + NULL, // focus skip set + _ecore_evas_wl_common_render, + _ecore_evas_wl_common_screen_geometry_get, + _ecore_evas_wl_common_screen_dpi_get, NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - _ecore_evas_wl_render, - _ecore_evas_wl_screen_geometry_get, - _ecore_evas_wl_screen_dpi_get + NULL, // msg_send + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + NULL // aux_hints_set }; /* external variables */ @@ -186,13 +160,12 @@ ecore_evas_wayland_egl_new(const char *disp_name, unsigned int parent, int x, in if (!(ee = calloc(1, sizeof(Ecore_Evas)))) { ERR("Failed to allocate Ecore_Evas"); - ecore_wl_shutdown(); - return NULL; + goto ee_err; } ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); - _ecore_evas_wl_init(); + _ecore_evas_wl_common_init(); ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func; @@ -248,26 +221,20 @@ ecore_evas_wayland_egl_new(const char *disp_name, unsigned int parent, int x, in if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) { ERR("Failed to set Evas Engine Info for '%s'", ee->driver); - ecore_evas_free(ee); - _ecore_evas_wl_shutdown(); - ecore_wl_shutdown(); - return NULL; + goto err; } } else { ERR("Failed to get Evas Engine Info for '%s'", ee->driver); - ecore_evas_free(ee); - _ecore_evas_wl_shutdown(); - ecore_wl_shutdown(); - return NULL; + goto err; } - ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_pre_free); + ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_common_pre_free); if (ee->prop.draw_frame) { - ee->engine.wl.frame = _ecore_evas_wl_frame_add(ee->evas); + ee->engine.wl.frame = _ecore_evas_wl_common_frame_add(ee->evas); evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE); evas_object_move(ee->engine.wl.frame, 0, 0); } @@ -281,190 +248,42 @@ ecore_evas_wayland_egl_new(const char *disp_name, unsigned int parent, int x, in (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); - /* evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); */ - return ee; -} - -/* local functions */ -static int -_ecore_evas_wl_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (++_ecore_evas_wl_init_count != 1) - return _ecore_evas_wl_init_count; - - _ecore_evas_wl_event_hdls[0] = - ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN, - _ecore_evas_wl_cb_mouse_in, NULL); - _ecore_evas_wl_event_hdls[1] = - ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT, - _ecore_evas_wl_cb_mouse_out, NULL); - _ecore_evas_wl_event_hdls[2] = - ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, - _ecore_evas_wl_cb_focus_in, NULL); - _ecore_evas_wl_event_hdls[3] = - ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, - _ecore_evas_wl_cb_focus_out, NULL); - _ecore_evas_wl_event_hdls[4] = - ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, - _ecore_evas_wl_cb_window_configure, NULL); - - ecore_event_evas_init(); - - return _ecore_evas_wl_init_count; -} -static int -_ecore_evas_wl_shutdown(void) -{ - unsigned int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (--_ecore_evas_wl_init_count != 0) - return _ecore_evas_wl_init_count; - - for (i = 0; i < sizeof(_ecore_evas_wl_event_hdls) / sizeof(Ecore_Event_Handler *); i++) - { - if (_ecore_evas_wl_event_hdls[i]) - ecore_event_handler_del(_ecore_evas_wl_event_hdls[i]); - } - - ecore_event_evas_shutdown(); - - return _ecore_evas_wl_init_count; -} - -static void -_ecore_evas_wl_pre_free(Ecore_Evas *ee) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame); -} - -static void -_ecore_evas_wl_free(Ecore_Evas *ee) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); + err: + ecore_evas_free(ee); + _ecore_evas_wl_common_shutdown(); - if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win); - ee->engine.wl.win = NULL; - - ecore_event_window_unregister(ee->prop.window); - ecore_evas_input_event_unregister(ee); - - _ecore_evas_wl_shutdown(); + ee_err: ecore_wl_shutdown(); -} - -static void -_ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_resize = func; -} - -static void -_ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_move = func; -} - -static void -_ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_delete_request = func; -} - -static void -_ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_focus_in = func; -} - -static void -_ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_focus_out = func; -} - -static void -_ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_mouse_in = func; -} - -static void -_ecore_evas_wl_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_mouse_out = func; -} - -static void -_ecore_evas_wl_move(Ecore_Evas *ee, int x, int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->req.x = x; - ee->req.y = y; - if ((ee->x != x) || (ee->y != y)) - { - ee->x = x; - ee->y = y; - if (ee->engine.wl.win) - ecore_wl_window_update_location(ee->engine.wl.win, x, y); - if (ee->func.fn_move) ee->func.fn_move(ee); - } + return NULL; } static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) { LOGFN(__FILE__, __LINE__, __FUNCTION__); - int fw = 0, fh = 0; if (!ee) return; if (w < 1) w = 1; if (h < 1) h = 1; - if (ee->prop.min.w > w) w = ee->prop.min.w; - else if (w > ee->prop.max.w) w = ee->prop.max.w; - if (ee->prop.min.h > h) h = ee->prop.min.h; - else if (h > ee->prop.max.h) h = ee->prop.max.h; - ee->req.w = w; ee->req.h = h; - evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); - w += fw; - h += fh; + if (!ee->prop.fullscreen) + { + int fw = 0, fh = 0; -// ecore_wl_window_damage(ee->engine.wl.win, 0, 0, ee->w, ee->h); + if (ee->prop.min.w > w) w = ee->prop.min.w; + else if (w > ee->prop.max.w) w = ee->prop.max.w; + if (ee->prop.min.h > h) h = ee->prop.min.h; + else if (h > ee->prop.max.h) h = ee->prop.max.h; + + evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); + w += fw; + h += fh; + } if ((ee->w != w) || (ee->h != h)) { @@ -476,7 +295,7 @@ _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) evas_output_size_set(ee->evas, h, w); evas_output_viewport_set(ee->evas, 0, 0, h, w); } - else + else { evas_output_size_set(ee->evas, w, h); evas_output_viewport_set(ee->evas, 0, 0, w, h); @@ -492,18 +311,14 @@ _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) } if (ee->engine.wl.frame) - evas_object_resize(ee->engine.wl.frame, ee->w, ee->h); - - /* set new engine destination */ - /* evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); */ - - /* ecore_wl_window_damage(ee->engine.wl.win, 0, 0, ee->w, ee->h); */ + evas_object_resize(ee->engine.wl.frame, w, h); - // WAS ACTIVE - /* ecore_wl_flush(); */ if (ee->engine.wl.win) - ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); + { + ecore_wl_window_update_size(ee->engine.wl.win, w, h); + ecore_wl_window_buffer_attach(ee->engine.wl.win, NULL, 0, 0); + } if (ee->func.fn_resize) ee->func.fn_resize(ee); } @@ -522,7 +337,7 @@ _ecore_evas_wl_show(Ecore_Evas *ee) { ecore_wl_window_show(ee->engine.wl.win); ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); - /* ecore_wl_sync(); */ + ecore_wl_window_buffer_attach(ee->engine.wl.win, NULL, 0, 0); if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, @@ -554,8 +369,6 @@ _ecore_evas_wl_show(Ecore_Evas *ee) /* printf("Failed to get a Surface from Ecore_Wl\n"); */ } - /* ecore_wl_window_buffer_attach(ee->engine.wl.win, ee->engine.wl.buffer, 0, 0); */ - ee->visible = 1; if (ee->func.fn_show) ee->func.fn_show(ee); } @@ -586,162 +399,6 @@ _ecore_evas_wl_hide(Ecore_Evas *ee) } static void -_ecore_evas_wl_raise(Ecore_Evas *ee) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!ee) || (!ee->visible)) return; - ecore_wl_window_raise(ee->engine.wl.win); -} - -static void -_ecore_evas_wl_title_set(Ecore_Evas *ee, const char *title) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.title) free(ee->prop.title); - ee->prop.title = NULL; - if (title) ee->prop.title = strdup(title); - if ((ee->prop.draw_frame) && (ee->engine.wl.frame)) - { - EE_Wl_Smart_Data *sd; - - if (!(sd = evas_object_smart_data_get(ee->engine.wl.frame))) return; - evas_object_text_text_set(sd->text, ee->prop.title); - } - - if ((ee->prop.title) && (ee->engine.wl.win->shell_surface)) - wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, - ee->prop.title); -} - -static void -_ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.name) free(ee->prop.name); - if (ee->prop.clas) free(ee->prop.clas); - ee->prop.name = NULL; - ee->prop.clas = NULL; - if (n) ee->prop.name = strdup(n); - if (c) ee->prop.clas = strdup(c); - - if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) - wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, - ee->prop.clas); -} - -static void -_ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 0) w = 0; - if (h < 0) h = 0; - if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return; - ee->prop.min.w = w; - ee->prop.min.h = h; -} - -static void -_ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 0) w = 0; - if (h < 0) h = 0; - if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return; - ee->prop.max.w = w; - ee->prop.max.h = h; -} - -static void -_ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 0) w = 0; - if (h < 0) h = 0; - if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return; - ee->prop.base.w = w; - ee->prop.base.h = h; -} - -static void -_ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 0) w = 0; - if (h < 0) h = 0; - if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return; - ee->prop.step.w = w; - ee->prop.step.h = h; -} - -static void -_ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.layer == layer) return; - if (layer < 1) layer = 1; - else if (layer > 255) layer = 255; - ee->prop.layer = layer; -} - -static void -_ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.iconified == iconify) return; - ee->prop.iconified = iconify; - /* FIXME: Implement this in Wayland someshow */ -} - -static void -_ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.maximized == max) return; - ee->prop.maximized = max; - ecore_wl_window_maximized_set(ee->engine.wl.win, max); -} - -static void -_ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!ee) || (!ee->visible)) return; - if (ee->prop.fullscreen == full) return; - ee->prop.fullscreen = full; - ecore_wl_window_fullscreen_set(ee->engine.wl.win, full); -} - -static void -_ecore_evas_wl_ignore_events_set(Ecore_Evas *ee, int ignore) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->ignore_events = ignore; - /* NB: Hmmm, may need to pass this to ecore_wl_window in the future */ -} - -static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha) { Evas_Engine_Info_Wayland_Egl *einfo; @@ -780,77 +437,6 @@ _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent) } } -static int -_ecore_evas_wl_render(Ecore_Evas *ee) -{ - int rend = 0; - - if (!ee) return 0; - if (!ee->visible) - evas_norender(ee->evas); - else - { - Eina_List *ll = NULL, *updates = NULL; - Ecore_Evas *ee2 = NULL; - - if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); - - EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) - { - if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } - - if ((updates = evas_render_updates(ee->evas))) - { - Eina_List *l = NULL; - Eina_Rectangle *r; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - EINA_LIST_FOREACH(updates, l, r) - ecore_wl_window_damage(ee->engine.wl.win, - r->x, r->y, r->w, r->h); - - ecore_wl_flush(); - - evas_render_updates_free(updates); - _ecore_evas_idle_timeout_update(ee); - rend = 1; - } - - if (ee->func.fn_post_render) ee->func.fn_post_render(ee); - } - return rend; -} - -static void -_ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (x) *x = 0; - if (y) *y = 0; - ecore_wl_screen_size_get(w, h); -} - -static void -_ecore_evas_wl_screen_dpi_get(const Ecore_Evas *ee __UNUSED__, int *xdpi, int *ydpi) -{ - int dpi = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (xdpi) *xdpi = 0; - if (ydpi) *ydpi = 0; - /* FIXME: Ideally this needs to get the DPI from a specific screen */ - dpi = ecore_wl_dpi_get(); - if (xdpi) *xdpi = dpi; - if (ydpi) *ydpi = dpi; -} - void _ecore_evas_wayland_egl_resize(Ecore_Evas *ee, int location) { @@ -859,240 +445,19 @@ _ecore_evas_wayland_egl_resize(Ecore_Evas *ee, int location) if (!ee) return; if (ee->engine.wl.win) { - ee->engine.wl.win->resizing = EINA_TRUE; - ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location); - } -} - -void -_ecore_evas_wayland_egl_move(Ecore_Evas *ee, int x, int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->engine.wl.win) - { - ee->engine.wl.win->moving = EINA_TRUE; - ecore_wl_window_move(ee->engine.wl.win, x, y); - } -} - -static Eina_Bool -_ecore_evas_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Mouse_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->window); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); - ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); - evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); - _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Mouse_Out *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->window); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); - _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp); - evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL); - if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); - if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Focus_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->win); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - ee->prop.focused = 1; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Focus_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->win); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - evas_focus_out(ee->evas); - ee->prop.focused = 0; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Window_Configure *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->win); - if (!ee) return ECORE_CALLBACK_PASS_ON; - if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if ((ee->x != ev->x) || (ee->y != ev->y)) - { - /* ee->x = ev->x; */ - /* ee->y = ev->y; */ - ee->req.x = ee->x; - ee->req.y = ee->y; - if (ee->func.fn_move) ee->func.fn_move(ee); - } - if ((ee->req.w != ev->w) || (ee->req.h != ev->h)) - { - ee->req.w = ev->w; - ee->req.h = ev->h; - if (ee->func.fn_resize) ee->func.fn_resize(ee); - } + Evas_Engine_Info_Wayland_Egl *einfo; - return ECORE_CALLBACK_PASS_ON; -} - -static void -_ecore_evas_wl_smart_init(void) -{ - if (_ecore_evas_wl_smart) return; - { - static const Evas_Smart_Class sc = + if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) { - "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION, - _ecore_evas_wl_smart_add, - _ecore_evas_wl_smart_del, - NULL, - _ecore_evas_wl_smart_resize, - _ecore_evas_wl_smart_show, - _ecore_evas_wl_smart_hide, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - }; - _ecore_evas_wl_smart = evas_smart_class_new(&sc); - } -} - -static void -_ecore_evas_wl_smart_add(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - Evas *evas; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return; - - evas = evas_object_evas_get(obj); - - sd->x = 0; - sd->y = 0; - sd->w = 1; - sd->h = 1; - - sd->frame = evas_object_rectangle_add(evas); - evas_object_is_frame_object_set(sd->frame, EINA_TRUE); - evas_object_color_set(sd->frame, 249, 249, 249, 255); - evas_object_smart_member_add(sd->frame, obj); - - sd->text = evas_object_text_add(evas); - evas_object_color_set(sd->text, 0, 0, 0, 255); - evas_object_text_style_set(sd->text, EVAS_TEXT_STYLE_PLAIN); - evas_object_text_font_set(sd->text, "Sans", 10); - evas_object_text_text_set(sd->text, "Smart Test"); - - evas_object_smart_data_set(obj, sd); -} - -static void -_ecore_evas_wl_smart_del(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - evas_object_del(sd->text); - evas_object_del(sd->frame); - free(sd); -} - -static void -_ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - if ((sd->w == w) && (sd->h == h)) return; - sd->w = w; - sd->h = h; - evas_object_resize(sd->frame, w, h); -} - -static void -_ecore_evas_wl_smart_show(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - evas_object_show(sd->frame); - evas_object_show(sd->text); -} - -static void -_ecore_evas_wl_smart_hide(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - evas_object_hide(sd->text); - evas_object_hide(sd->frame); -} - -static Evas_Object * -_ecore_evas_wl_frame_add(Evas *evas) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); + einfo->info.edges = location; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } - _ecore_evas_wl_smart_init(); - return evas_object_smart_add(evas, _ecore_evas_wl_smart); + ee->engine.wl.win->resizing = EINA_TRUE; + ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location); + } } - #else EAPI Ecore_Evas * ecore_evas_wayland_egl_new(const char *disp_name __UNUSED__, unsigned int parent __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, Eina_Bool frame __UNUSED__) diff --git a/src/lib/ecore_evas/ecore_evas_wayland_shm.c b/src/lib/ecore_evas/ecore_evas_wayland_shm.c index b9c6d18..72edb5f 100644 --- a/src/lib/ecore_evas/ecore_evas_wayland_shm.c +++ b/src/lib/ecore_evas/ecore_evas_wayland_shm.c @@ -2,6 +2,32 @@ # include "config.h" #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + //#define LOGFNS 1 #ifdef LOGFNS @@ -21,104 +47,55 @@ #endif #include -#include -#include -#include "ecore_evas_private.h" #include "Ecore_Evas.h" #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +# include "ecore_evas_private.h" # include # include -/* local structures */ -typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data; -struct _EE_Wl_Smart_Data -{ - Evas_Object *frame; - Evas_Object *text; - Evas_Coord x, y, w, h; -}; - /* local function prototypes */ -static int _ecore_evas_wl_init(void); -static int _ecore_evas_wl_shutdown(void); -static void _ecore_evas_wl_pre_free(Ecore_Evas *ee); static void _ecore_evas_wl_free(Ecore_Evas *ee); -static void _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -static void _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y); static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h); static void _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h); static void _ecore_evas_wl_show(Ecore_Evas *ee); static void _ecore_evas_wl_hide(Ecore_Evas *ee); -static void _ecore_evas_wl_raise(Ecore_Evas *ee); -static void _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *title); -static void _ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c); -static void _ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer); -static void _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify); -static void _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max); -static void _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full); -static void _ecore_evas_wl_ignore_events_set(Ecore_Evas *ee, int ignore); static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha); static void _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent); -static int _ecore_evas_wl_render(Ecore_Evas *ee); -static void _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h); -static void _ecore_evas_wl_screen_dpi_get(const Ecore_Evas *ee __UNUSED__, int *xdpi, int *ydpi); -static void _ecore_evas_wl_ensure_pool_size(Ecore_Evas *ee, int w, int h); -static struct wl_shm_pool *_ecore_evas_wl_shm_pool_create(int size, void **data); - -static void _ecore_evas_wl_buffer_new(Ecore_Evas *ee, struct wl_shm_pool *pool); - -static Eina_Bool _ecore_evas_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event); -static Eina_Bool _ecore_evas_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event); -static Eina_Bool _ecore_evas_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event); -static Eina_Bool _ecore_evas_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event); -static Eina_Bool _ecore_evas_wl_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _ecore_evas_wl_render(Ecore_Evas *ee); -/* SMART stuff for frame */ -static Evas_Smart *_ecore_evas_wl_smart = NULL; +/* SHM Only */ +static void _ecore_evas_wl_shm_pool_free(Ecore_Evas *ee); +static void _ecore_evas_wl_shm_pool_create(Ecore_Evas *ee, size_t size); +static void _ecore_evas_wl_buffer_free(Ecore_Evas *ee); +static void _ecore_evas_wl_buffer_new(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_smart_init(void); -static void _ecore_evas_wl_smart_add(Evas_Object *obj); -static void _ecore_evas_wl_smart_del(Evas_Object *obj); -static void _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h); -static void _ecore_evas_wl_smart_show(Evas_Object *obj); -static void _ecore_evas_wl_smart_hide(Evas_Object *obj); - -static Evas_Object *_ecore_evas_wl_frame_add(Evas *evas); - -/* local variables */ -static int _ecore_evas_wl_init_count = 0; -static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[5]; +/* Frame listener */ +static void _ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t time); +static const struct wl_callback_listener frame_listener = +{ + _ecore_evas_wl_frame_complete, +}; static Ecore_Evas_Engine_Func _ecore_wl_engine_func = { _ecore_evas_wl_free, - _ecore_evas_wl_callback_resize_set, - _ecore_evas_wl_callback_move_set, + _ecore_evas_wl_common_callback_resize_set, + _ecore_evas_wl_common_callback_move_set, NULL, NULL, - _ecore_evas_wl_callback_delete_request_set, + _ecore_evas_wl_common_callback_delete_request_set, NULL, - _ecore_evas_wl_callback_focus_in_set, - _ecore_evas_wl_callback_focus_out_set, - _ecore_evas_wl_callback_mouse_in_set, - _ecore_evas_wl_callback_mouse_out_set, + _ecore_evas_wl_common_callback_focus_in_set, + _ecore_evas_wl_common_callback_focus_out_set, + _ecore_evas_wl_common_callback_mouse_in_set, + _ecore_evas_wl_common_callback_mouse_out_set, NULL, // sticky_set NULL, // unsticky_set NULL, // pre_render_set NULL, // post_render_set - _ecore_evas_wl_move, + _ecore_evas_wl_common_move, NULL, // managed_move _ecore_evas_wl_resize, _ecore_evas_wl_move_resize, @@ -126,27 +103,27 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func = NULL, // shaped_set _ecore_evas_wl_show, _ecore_evas_wl_hide, - _ecore_evas_wl_raise, + _ecore_evas_wl_common_raise, NULL, // lower NULL, // activate - _ecore_evas_wl_title_set, - _ecore_evas_wl_name_class_set, - _ecore_evas_wl_size_min_set, - _ecore_evas_wl_size_max_set, - _ecore_evas_wl_size_base_set, - _ecore_evas_wl_size_step_set, + _ecore_evas_wl_common_title_set, + _ecore_evas_wl_common_name_class_set, + _ecore_evas_wl_common_size_min_set, + _ecore_evas_wl_common_size_max_set, + _ecore_evas_wl_common_size_base_set, + _ecore_evas_wl_common_size_step_set, NULL, // object_cursor_set - _ecore_evas_wl_layer_set, + _ecore_evas_wl_common_layer_set, NULL, // focus set - _ecore_evas_wl_iconified_set, + _ecore_evas_wl_common_iconified_set, NULL, // borderless set NULL, // override set - _ecore_evas_wl_maximized_set, - _ecore_evas_wl_fullscreen_set, + _ecore_evas_wl_common_maximized_set, + _ecore_evas_wl_common_fullscreen_set, NULL, // func avoid_damage set NULL, // func withdrawn set NULL, // func sticky set - _ecore_evas_wl_ignore_events_set, + _ecore_evas_wl_common_ignore_events_set, _ecore_evas_wl_alpha_set, _ecore_evas_wl_transparent_set, NULL, // func profiles set @@ -156,9 +133,14 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func = NULL, // modal set NULL, // demand attention set NULL, // focus skip set - _ecore_evas_wl_render, - _ecore_evas_wl_screen_geometry_get, - _ecore_evas_wl_screen_dpi_get + _ecore_evas_wl_render, + _ecore_evas_wl_common_screen_geometry_get, + _ecore_evas_wl_common_screen_dpi_get, + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + NULL // aux_hints_set }; /* external variables */ @@ -192,13 +174,12 @@ ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent, int x, in if (!(ee = calloc(1, sizeof(Ecore_Evas)))) { ERR("Failed to allocate Ecore_Evas"); - ecore_wl_shutdown(); - return NULL; + goto ee_err; } ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); - _ecore_evas_wl_init(); + _ecore_evas_wl_common_init(); ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func; @@ -235,7 +216,8 @@ ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent, int x, in if (ee->prop.draw_frame) evas_output_framespace_set(ee->evas, 4, 18, 8, 22); - if (parent) p = ecore_wl_window_find(parent); + if (parent) + p = ecore_wl_window_find(parent); /* FIXME: Get if parent is alpha, and set */ @@ -246,33 +228,25 @@ ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent, int x, in if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) { - einfo->info.rotation = ee->rotation; einfo->info.destination_alpha = ee->alpha; einfo->info.rotation = ee->rotation; - einfo->info.debug = EINA_FALSE; if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) { ERR("Failed to set Evas Engine Info for '%s'", ee->driver); - ecore_evas_free(ee); - _ecore_evas_wl_shutdown(); - ecore_wl_shutdown(); - return NULL; + goto err; } } else { ERR("Failed to get Evas Engine Info for '%s'", ee->driver); - ecore_evas_free(ee); - _ecore_evas_wl_shutdown(); - ecore_wl_shutdown(); - return NULL; + goto err; } - ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_pre_free); + ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_common_pre_free); if (ee->prop.draw_frame) { - ee->engine.wl.frame = _ecore_evas_wl_frame_add(ee->evas); + ee->engine.wl.frame = _ecore_evas_wl_common_frame_add(ee->evas); evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE); evas_object_move(ee->engine.wl.frame, 0, 0); } @@ -286,169 +260,23 @@ ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent, int x, in (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); -// evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); - return ee; -} -/* local functions */ -static int -_ecore_evas_wl_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (++_ecore_evas_wl_init_count != 1) - return _ecore_evas_wl_init_count; - - _ecore_evas_wl_event_hdls[0] = - ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN, - _ecore_evas_wl_cb_mouse_in, NULL); - _ecore_evas_wl_event_hdls[1] = - ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT, - _ecore_evas_wl_cb_mouse_out, NULL); - _ecore_evas_wl_event_hdls[2] = - ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, - _ecore_evas_wl_cb_focus_in, NULL); - _ecore_evas_wl_event_hdls[3] = - ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, - _ecore_evas_wl_cb_focus_out, NULL); - _ecore_evas_wl_event_hdls[4] = - ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, - _ecore_evas_wl_cb_window_configure, NULL); - - ecore_event_evas_init(); - - return _ecore_evas_wl_init_count; -} + err: + ecore_evas_free(ee); + _ecore_evas_wl_common_shutdown(); -static int -_ecore_evas_wl_shutdown(void) -{ - unsigned int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (--_ecore_evas_wl_init_count != 0) - return _ecore_evas_wl_init_count; - - for (i = 0; i < sizeof(_ecore_evas_wl_event_hdls) / sizeof(Ecore_Event_Handler *); i++) - { - if (_ecore_evas_wl_event_hdls[i]) - ecore_event_handler_del(_ecore_evas_wl_event_hdls[i]); - } - - ecore_event_evas_shutdown(); - - return _ecore_evas_wl_init_count; -} - -static void -_ecore_evas_wl_pre_free(Ecore_Evas *ee) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame); -} - -static void -_ecore_evas_wl_free(Ecore_Evas *ee) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer); - ee->engine.wl.buffer = NULL; - - if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win); - ee->engine.wl.win = NULL; - - ecore_event_window_unregister(ee->prop.window); - ecore_evas_input_event_unregister(ee); - - _ecore_evas_wl_shutdown(); + ee_err: ecore_wl_shutdown(); + return NULL; } static void -_ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_resize = func; -} - -static void -_ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_move = func; -} - -static void -_ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_delete_request = func; -} - -static void -_ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_focus_in = func; -} - -static void -_ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_focus_out = func; -} - -static void -_ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_mouse_in = func; -} - -static void -_ecore_evas_wl_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +_ecore_evas_wl_free(Ecore_Evas *ee) { - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->func.fn_mouse_out = func; -} - -static void -_ecore_evas_wl_move(Ecore_Evas *ee, int x, int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - - ee->req.x = x; - ee->req.y = y; - if ((ee->x != x) || (ee->y != y)) - { - ee->x = x; - ee->y = y; - if (ee->engine.wl.win) - ecore_wl_window_update_location(ee->engine.wl.win, x, y); - if (ee->func.fn_move) ee->func.fn_move(ee); - } + _ecore_evas_wl_buffer_free(ee); + _ecore_evas_wl_shm_pool_free(ee); + _ecore_evas_wl_common_free(ee); } static void @@ -463,17 +291,22 @@ _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) if (w < 1) w = 1; if (h < 1) h = 1; - if (ee->prop.min.w > w) w = ee->prop.min.w; - else if (w > ee->prop.max.w) w = ee->prop.max.w; - if (ee->prop.min.h > h) h = ee->prop.min.h; - else if (h > ee->prop.max.h) h = ee->prop.max.h; - ee->req.w = w; ee->req.h = h; - evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); - w += fw; - h += fh; + if (!ee->prop.fullscreen) + { + int fw = 0, fh = 0; + + if (ee->prop.min.w > w) w = ee->prop.min.w; + else if (w > ee->prop.max.w) w = ee->prop.max.w; + if (ee->prop.min.h > h) h = ee->prop.min.h; + else if (h > ee->prop.max.h) h = ee->prop.max.h; + + evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); + w += fw; + h += fh; + } if ((ee->w != w) || (ee->h != h)) { @@ -503,13 +336,7 @@ _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) if (ee->engine.wl.frame) evas_object_resize(ee->engine.wl.frame, w, h); - if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer); - ee->engine.wl.buffer = NULL; - - _ecore_evas_wl_ensure_pool_size(ee, w, h); - - if (ee->engine.wl.pool) - _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool); + _ecore_evas_wl_buffer_new(ee, w, h); einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); if (!einfo) @@ -539,45 +366,12 @@ _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h) if (!ee) return; if ((ee->x != x) || (ee->y != y)) - _ecore_evas_wl_move(ee, x, y); + _ecore_evas_wl_common_move(ee, x, y); if ((ee->w != w) || (ee->h != h)) _ecore_evas_wl_resize(ee, w, h); } static void -_ecore_evas_wl_ensure_pool_size(Ecore_Evas *ee, int w, int h) -{ - int stride = 0; - size_t len = 0; - - stride = w * sizeof(int); - len = stride * h; - - if ((ee->engine.wl.pool) && (len < ee->engine.wl.pool_size)) - return; - else - { - struct wl_shm_pool *pool = NULL; - void *data; - int size; - - if (ee->engine.wl.pool) - wl_shm_pool_destroy(ee->engine.wl.pool); - - /* - * Make the pool 1.5 times the current requirement to allow growth - * without requiring a new pool allocation - */ - size = 1.5 * len; - pool = _ecore_evas_wl_shm_pool_create(size, &data); - - ee->engine.wl.pool = pool; - ee->engine.wl.pool_size = size; - ee->engine.wl.pool_data = data; - } -} - -static void _ecore_evas_wl_show(Ecore_Evas *ee) { Evas_Engine_Info_Wayland_Shm *einfo; @@ -586,10 +380,7 @@ _ecore_evas_wl_show(Ecore_Evas *ee) if ((!ee) || (ee->visible)) return; - _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h); - - if (ee->engine.wl.pool) - _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool); + _ecore_evas_wl_buffer_new(ee, ee->w, ee->h); einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); if (!einfo) @@ -601,14 +392,12 @@ _ecore_evas_wl_show(Ecore_Evas *ee) einfo->info.dest = ee->engine.wl.pool_data; evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); - /* ecore_wl_flush(); */ - if (ee->engine.wl.win) { ecore_wl_window_show(ee->engine.wl.win); + ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); ecore_wl_window_buffer_attach(ee->engine.wl.win, ee->engine.wl.buffer, 0, 0); - ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, @@ -637,8 +426,7 @@ _ecore_evas_wl_hide(Ecore_Evas *ee) if ((!ee) || (!ee->visible)) return; - if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer); - ee->engine.wl.buffer = NULL; + _ecore_evas_wl_buffer_free(ee); munmap(ee->engine.wl.pool_data, ee->engine.wl.pool_size); @@ -649,7 +437,8 @@ _ecore_evas_wl_hide(Ecore_Evas *ee) evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); } - ecore_wl_window_hide(ee->engine.wl.win); + if (ee->engine.wl.win) + ecore_wl_window_hide(ee->engine.wl.win); ee->visible = 0; ee->should_be_visible = 0; @@ -658,180 +447,42 @@ _ecore_evas_wl_hide(Ecore_Evas *ee) } static void -_ecore_evas_wl_raise(Ecore_Evas *ee) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!ee) || (!ee->visible)) return; - ecore_wl_window_raise(ee->engine.wl.win); -} - -static void -_ecore_evas_wl_title_set(Ecore_Evas *ee, const char *title) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.title) free(ee->prop.title); - ee->prop.title = NULL; - if (title) ee->prop.title = strdup(title); - if ((ee->prop.draw_frame) && (ee->engine.wl.frame)) - { - EE_Wl_Smart_Data *sd; - - if (!(sd = evas_object_smart_data_get(ee->engine.wl.frame))) return; - evas_object_text_text_set(sd->text, ee->prop.title); - } - - if ((ee->prop.title) && (ee->engine.wl.win->shell_surface)) - wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, - ee->prop.title); -} - -static void -_ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.name) free(ee->prop.name); - if (ee->prop.clas) free(ee->prop.clas); - ee->prop.name = NULL; - ee->prop.clas = NULL; - if (n) ee->prop.name = strdup(n); - if (c) ee->prop.clas = strdup(c); - - if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) - wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, - ee->prop.clas); -} - -static void -_ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 0) w = 0; - if (h < 0) h = 0; - if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return; - ee->prop.min.w = w; - ee->prop.min.h = h; -} - -static void -_ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 0) w = 0; - if (h < 0) h = 0; - if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return; - ee->prop.max.w = w; - ee->prop.max.h = h; -} - -static void -_ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 0) w = 0; - if (h < 0) h = 0; - if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return; - ee->prop.base.w = w; - ee->prop.base.h = h; -} - -static void -_ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 0) w = 0; - if (h < 0) h = 0; - if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return; - ee->prop.step.w = w; - ee->prop.step.h = h; -} - -static void -_ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.layer == layer) return; - if (layer < 1) layer = 1; - else if (layer > 255) layer = 255; - ee->prop.layer = layer; -} - -static void -_ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.iconified == iconify) return; - ee->prop.iconified = iconify; - /* FIXME: Implement this in Wayland someshow */ -} - -static void -_ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.maximized == max) return; - ee->prop.maximized = max; - ecore_wl_window_maximized_set(ee->engine.wl.win, max); -} - -static void -_ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!ee) || (!ee->visible)) return; - if (ee->prop.fullscreen == full) return; - ee->prop.fullscreen = full; - ecore_wl_window_fullscreen_set(ee->engine.wl.win, full); -} - -static void -_ecore_evas_wl_ignore_events_set(Ecore_Evas *ee, int ignore) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->ignore_events = ignore; - /* NB: Hmmm, may need to pass this to ecore_wl_window in the future */ -} - -static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha) { Evas_Engine_Info_Wayland_Shm *einfo; + Ecore_Wl_Window *win = NULL; LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!ee) return; if ((ee->alpha == alpha)) return; ee->alpha = alpha; - if (ee->engine.wl.win) - ecore_wl_window_transparent_set(ee->engine.wl.win, alpha); + + /* FIXME: NB: We should really add a ecore_wl_window_alpha_set function + * but we are in API freeze, so just hack it in for now and fix when + * freeze is over */ + if ((win = ee->engine.wl.win)) + win->alpha = alpha; + + /* if (ee->engine.wl.win) */ + /* ecore_wl_window_transparent_set(ee->engine.wl.win, alpha); */ + + _ecore_evas_wl_buffer_new(ee, ee->w, ee->h); + if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) { einfo->info.destination_alpha = alpha; + einfo->info.dest = ee->engine.wl.pool_data; if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); } + + if (win) + { + ecore_wl_window_update_size(win, ee->w, ee->h); + ecore_wl_window_buffer_attach(win, ee->engine.wl.buffer, 0, 0); + } } static void @@ -844,146 +495,176 @@ _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent) if (!ee) return; if ((ee->transparent == transparent)) return; ee->transparent = transparent; + if (ee->engine.wl.win) ecore_wl_window_transparent_set(ee->engine.wl.win, transparent); + + _ecore_evas_wl_buffer_new(ee, ee->w, ee->h); + if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) { einfo->info.destination_alpha = transparent; + einfo->info.dest = ee->engine.wl.pool_data; if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); } + + if (ee->engine.wl.win) + { + ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); + ecore_wl_window_buffer_attach(ee->engine.wl.win, + ee->engine.wl.buffer, 0, 0); + } +} + +static void +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t time __UNUSED__) +{ + Ecore_Evas *ee = data; + Ecore_Wl_Window *win = NULL; + + if (!ee) return; + if (!(win = ee->engine.wl.win)) return; + + win->frame_callback = NULL; + win->frame_pending = EINA_FALSE; + wl_callback_destroy(callback); + + if (win->surface) + { + win->frame_callback = wl_surface_frame(win->surface); + wl_callback_add_listener(win->frame_callback, &frame_listener, ee); + } } -static int +static int _ecore_evas_wl_render(Ecore_Evas *ee) { int rend = 0; + Ecore_Wl_Window *win = NULL; if (!ee) return 0; if (!ee->visible) - evas_norender(ee->evas); - else { - Eina_List *ll = NULL, *updates = NULL; - Ecore_Evas *ee2 = NULL; + evas_norender(ee->evas); + return 0; + } - if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); + if (!(win = ee->engine.wl.win)) return 0; - EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) - { - if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } + rend = _ecore_evas_wl_common_pre_render(ee); + if (!(win->frame_pending)) + { + /* FIXME - ideally have an evas_changed_get to return the value + * of evas->changed to avoid creating this callback and + * destroying it again + */ - if ((updates = evas_render_updates(ee->evas))) + if (!win->frame_callback) { - Eina_List *l = NULL; - Eina_Rectangle *r; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - EINA_LIST_FOREACH(updates, l, r) - ecore_wl_window_damage(ee->engine.wl.win, - r->x, r->y, r->w, r->h); - - ecore_wl_flush(); - - evas_render_updates_free(updates); - _ecore_evas_idle_timeout_update(ee); - rend = 1; + win->frame_callback = wl_surface_frame(win->surface); + wl_callback_add_listener(win->frame_callback, &frame_listener, ee); } - if (ee->func.fn_post_render) ee->func.fn_post_render(ee); + rend |= _ecore_evas_wl_common_render_updates(ee); + if (rend) + win->frame_pending = EINA_TRUE; } + _ecore_evas_wl_common_post_render(ee); return rend; } -static void -_ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (x) *x = 0; - if (y) *y = 0; - ecore_wl_screen_size_get(w, h); -} - -static void -_ecore_evas_wl_screen_dpi_get(const Ecore_Evas *ee __UNUSED__, int *xdpi, int *ydpi) +static void +_ecore_evas_wl_shm_pool_free(Ecore_Evas *ee) { - int dpi = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!ee->engine.wl.pool) return; - if (xdpi) *xdpi = 0; - if (ydpi) *ydpi = 0; - /* FIXME: Ideally this needs to get the DPI from a specific screen */ - dpi = ecore_wl_dpi_get(); - if (xdpi) *xdpi = dpi; - if (ydpi) *ydpi = dpi; + wl_shm_pool_destroy(ee->engine.wl.pool); + ee->engine.wl.pool = NULL; + ee->engine.wl.pool_size = 0; + ee->engine.wl.pool_data = NULL; } -static struct wl_shm_pool * -_ecore_evas_wl_shm_pool_create(int size, void **data) +static void +_ecore_evas_wl_shm_pool_create(Ecore_Evas *ee, size_t size) { struct wl_shm *shm; - struct wl_shm_pool *pool; + void *data; char tmp[PATH_MAX]; int fd; LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!(shm = ecore_wl_shm_get())) return NULL; + if (size <= ee->engine.wl.pool_size) + return; + + size *= 1.5; + _ecore_evas_wl_shm_pool_free(ee); + + if (!(shm = ecore_wl_shm_get())) + { + ERR("ecore_wl_shm_get returned NULL"); + return; + } strcpy(tmp, "/tmp/ecore-evas-wayland_shm-XXXXXX"); if ((fd = mkstemp(tmp)) < 0) { ERR("Could not create temporary file."); - return NULL; + return; } if (ftruncate(fd, size) < 0) { ERR("Could not truncate temporary file."); - close(fd); - return NULL; + goto end; } - *data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0); + data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0); unlink(tmp); - if (*data == MAP_FAILED) + if (data == MAP_FAILED) { ERR("mmap of temporary file failed."); - close(fd); - return NULL; + goto end; } - pool = wl_shm_create_pool(shm, fd, size); + ee->engine.wl.pool_size = size; + ee->engine.wl.pool_data = data; + ee->engine.wl.pool = wl_shm_create_pool(shm, fd, size); + end: close(fd); +} + +static void +_ecore_evas_wl_buffer_free(Ecore_Evas *ee) +{ + if (!ee->engine.wl.buffer) return; - return pool; + wl_buffer_destroy(ee->engine.wl.buffer); + ee->engine.wl.buffer = NULL; } static void -_ecore_evas_wl_buffer_new(Ecore_Evas *ee, struct wl_shm_pool *pool) +_ecore_evas_wl_buffer_new(Ecore_Evas *ee, int w, int h) { unsigned int format; int stride = 0; + stride = (w * sizeof(int)); + + _ecore_evas_wl_shm_pool_create(ee, stride * h); + if ((ee->alpha) || (ee->transparent)) format = WL_SHM_FORMAT_ARGB8888; else format = WL_SHM_FORMAT_XRGB8888; - stride = (ee->w * sizeof(int)); - + _ecore_evas_wl_buffer_free(ee); ee->engine.wl.buffer = - wl_shm_pool_create_buffer(pool, 0, ee->w, ee->h, stride, format); + wl_shm_pool_create_buffer(ee->engine.wl.pool, 0, w, h, stride, format); } void @@ -998,247 +679,6 @@ _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location) ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location); } } - -void -_ecore_evas_wayland_shm_move(Ecore_Evas *ee, int x, int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->engine.wl.win) - { - ee->engine.wl.win->moving = EINA_TRUE; - ecore_wl_window_move(ee->engine.wl.win, x, y); - } -} - -static Eina_Bool -_ecore_evas_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Mouse_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->window); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (!ee->in) - { - if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); - ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); - evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); -// _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp); - ee->in = EINA_TRUE; - } - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Mouse_Out *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->window); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->in) - { - ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); -// _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp); - evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL); - if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); - if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); - ee->in = EINA_FALSE; - } - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Focus_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->win); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - ee->prop.focused = 1; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Focus_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->win); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - evas_focus_out(ee->evas); - ee->prop.focused = 0; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Window_Configure *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->win); - if (!ee) return ECORE_CALLBACK_PASS_ON; - if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - - if ((ee->x != ev->x) || (ee->y != ev->y)) - { - /* ee->x = ev->x; */ - /* ee->y = ev->y; */ - ee->req.x = ee->x; - ee->req.y = ee->y; - if (ee->func.fn_move) ee->func.fn_move(ee); - } - if ((ee->req.w != ev->w) || (ee->req.h != ev->h)) - { - /* ee->w = ev->w; */ - /* ee->h = ev->h; */ - ee->req.w = ev->w; - ee->req.h = ev->h; - if (ee->func.fn_resize) ee->func.fn_resize(ee); - } - - return ECORE_CALLBACK_PASS_ON; -} - -static void -_ecore_evas_wl_smart_init(void) -{ - if (_ecore_evas_wl_smart) return; - { - static const Evas_Smart_Class sc = - { - "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION, - _ecore_evas_wl_smart_add, - _ecore_evas_wl_smart_del, - NULL, - _ecore_evas_wl_smart_resize, - _ecore_evas_wl_smart_show, - _ecore_evas_wl_smart_hide, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - }; - _ecore_evas_wl_smart = evas_smart_class_new(&sc); - } -} - -static void -_ecore_evas_wl_smart_add(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - Evas *evas; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return; - - evas = evas_object_evas_get(obj); - - sd->x = 0; - sd->y = 0; - sd->w = 1; - sd->h = 1; - - sd->frame = evas_object_rectangle_add(evas); - evas_object_is_frame_object_set(sd->frame, EINA_TRUE); - evas_object_color_set(sd->frame, 249, 249, 249, 255); - evas_object_smart_member_add(sd->frame, obj); - - sd->text = evas_object_text_add(evas); - evas_object_color_set(sd->text, 0, 0, 0, 255); - evas_object_text_style_set(sd->text, EVAS_TEXT_STYLE_PLAIN); - evas_object_text_font_set(sd->text, "Sans", 10); - evas_object_text_text_set(sd->text, "Smart Test"); - - evas_object_smart_data_set(obj, sd); -} - -static void -_ecore_evas_wl_smart_del(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - evas_object_del(sd->text); - evas_object_del(sd->frame); - free(sd); -} - -static void -_ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - if ((sd->w == w) && (sd->h == h)) return; - sd->w = w; - sd->h = h; - evas_object_resize(sd->frame, w, h); -} - -static void -_ecore_evas_wl_smart_show(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - evas_object_show(sd->frame); - evas_object_show(sd->text); -} - -static void -_ecore_evas_wl_smart_hide(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - evas_object_hide(sd->text); - evas_object_hide(sd->frame); -} - -static Evas_Object * -_ecore_evas_wl_frame_add(Evas *evas) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_evas_wl_smart_init(); - return evas_object_smart_add(evas, _ecore_evas_wl_smart); -} - #else EAPI Ecore_Evas * ecore_evas_wayland_shm_new(const char *disp_name __UNUSED__, unsigned int parent __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, Eina_Bool frame __UNUSED__) diff --git a/src/lib/ecore_evas/ecore_evas_win32.c b/src/lib/ecore_evas/ecore_evas_win32.c index 59d6ed8..286a1c5 100644 --- a/src/lib/ecore_evas/ecore_evas_win32.c +++ b/src/lib/ecore_evas/ecore_evas_win32.c @@ -1121,7 +1121,16 @@ static Ecore_Evas_Engine_Func _ecore_win32_engine_func = NULL, // render NULL, // screen_geometry_get - _ecore_evas_win32_screen_dpi_get + _ecore_evas_win32_screen_dpi_get, + NULL, + NULL, // msg_send + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; #endif /* BUILD_ECORE_EVAS_WIN32 */ diff --git a/src/lib/ecore_evas/ecore_evas_wince.c b/src/lib/ecore_evas/ecore_evas_wince.c index fe0054a..c6ba72b 100644 --- a/src/lib/ecore_evas/ecore_evas_wince.c +++ b/src/lib/ecore_evas/ecore_evas_wince.c @@ -802,7 +802,14 @@ static Ecore_Evas_Engine_Func _ecore_wince_engine_func = NULL, // render NULL, // screen_geometry_get - _ecore_evas_wince_screen_dpi_get + _ecore_evas_wince_screen_dpi_get, + + NULL, // wm_rot_preferred_rotation_set + NULL, // wm_rot_available_rotations_set + NULL, // wm_rot_manual_rotation_done_set + NULL, // wm_rot_manual_rotation_done + + NULL // aux_hints_set }; /* API */ diff --git a/src/lib/ecore_evas/ecore_evas_x.c b/src/lib/ecore_evas/ecore_evas_x.c old mode 100644 new mode 100755 index c86cecd..72521f7 --- a/src/lib/ecore_evas/ecore_evas_x.c +++ b/src/lib/ecore_evas/ecore_evas_x.c @@ -19,14 +19,21 @@ static Ecore_Event_Handler *ecore_evas_event_handlers[13]; static int leader_ref = 0; static Ecore_X_Window leader_win = 0; +static void _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize); +static Eina_Bool _ecore_evas_x_wm_rot_manual_rotation_done_timeout(void *data); +static void _ecore_evas_x_wm_rot_manual_rotation_done_timeout_update(Ecore_Evas *ee); +static void _ecore_evas_x_aux_hints_set(Ecore_Evas *ee, const char *hints); +static void _ecore_x_window_resize_wrapper(Ecore_Evas *ee, int w, int h); +static Eina_Bool _ecore_evas_x_manual_render_idle_enterer_cb(void *data); + static void _ecore_evas_x_hints_update(Ecore_Evas *ee) { ecore_x_icccm_hints_set (ee->prop.window, !ee->prop.focus_skip /* accepts_focus */, - ee->prop.iconified ? ECORE_X_WINDOW_STATE_HINT_ICONIC : - ee->prop.withdrawn ? ECORE_X_WINDOW_STATE_HINT_WITHDRAWN : + ee->prop.iconified ? ECORE_X_WINDOW_STATE_HINT_ICONIC : + ee->prop.withdrawn ? ECORE_X_WINDOW_STATE_HINT_WITHDRAWN : ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */, 0 /* icon_pixmap */, 0 /* icon_mask */, @@ -97,6 +104,17 @@ _ecore_evas_x_protocols_set(Ecore_Evas *ee) ecore_x_window_prop_card32_set(ee->prop.window, ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, &tmp, 1); + + // set property on window to say "I talk the deiconify approve protcol" + tmp = 1; + ecore_x_window_prop_card32_set(ee->prop.window, + ECORE_X_ATOM_E_DEICONIFY_APPROVE, + &tmp, 1); + + // to support aux hint protocol + ecore_x_window_prop_card32_set(ee->prop.window, + ECORE_X_ATOM_E_WINDOW_AUX_HINT_SUPPORT, + &tmp, 1); } static void @@ -133,6 +151,157 @@ _ecore_evas_x_sync_clear(Ecore_Evas *ee) ee->engine.x.sync_counter = 0; } +static void +_ecore_evas_x_wm_rotation_protocol_set(Ecore_Evas *ee) +{ + if (ecore_x_e_window_rotation_supported_get(ee->engine.x.win_root)) + ee->prop.wm_rot.supported = 1; + else + ee->prop.wm_rot.supported = 0; +} + +static void +_ecore_evas_x_aux_hints_supprted_update(Ecore_Evas *ee) +{ + Ecore_X_Window root = ecore_x_window_root_first_get(); + unsigned char *data = NULL; + unsigned int num = 0, i = 0; + int res = 0, n = 0; + char **str; + const char *hint; + + EINA_LIST_FREE(ee->prop.aux_hint.supported_list, hint) + { + eina_stringshare_del(hint); + } + + res = ecore_x_window_prop_property_get + (root, ECORE_X_ATOM_E_WINDOW_AUX_HINT_SUPPORTED_LIST, + ECORE_X_ATOM_STRING, 0, &data, &n); + + if ((res == 8) && (n >0)) + { + str = eina_str_split_full((char *)data, ",", -1, &num); + for (i = 0; i < num; i++) + { + hint = eina_stringshare_add(str[i]); + ee->prop.aux_hint.supported_list = + eina_list_append(ee->prop.aux_hint.supported_list, hint); + } + + if (str) + { + free(str[0]); + free(str); + } + } + + free(data); +} + +static void +_ecore_evas_x_aux_hints_update(Ecore_Evas *ee) +{ + Eina_Strbuf *buf = _ecore_evas_aux_hints_string_get(ee); + if (buf) + { + _ecore_evas_x_aux_hints_set(ee, eina_strbuf_string_get(buf)); + eina_strbuf_free(buf); + } +} + +static void +_ecore_evas_x_deiconify_job(void *data) +{ + Ecore_Evas *ee = data; + + ee->engine.x.deiconify_job = NULL; + + // Set manual render when deiconify_job is called. + // deiconify_job is added when ECORE_X_ATOM_E_DEICONIFY_APPROVE client + // message arrives. + if (!ecore_evas_manual_render_get(ee)) + { + ee->engine.x.manual_render_by_ecore_evas = EINA_TRUE; + ecore_evas_manual_render_set(ee, EINA_TRUE); + } + + // add a manual render idle enterer + if (ee->engine.x.manual_render_idle_enterer) + ecore_idle_enterer_del(ee->engine.x.manual_render_idle_enterer); + + // mark to send deiconify approve after manual rendering in idle enterer + ee->engine.x.deiconify_approve_after_manual_render = EINA_TRUE; + + /* queue an idle enterer to render manually until each object finishes + changing its size */ + ee->engine.x.manual_render_idle_enterer = + ecore_idle_enterer_add(_ecore_evas_x_manual_render_idle_enterer_cb, ee); +} + +/* idle enterer for manual render on + * 1. ECORE_X_ATOM_E_COMP_SYNC_BEGIN + * 2. ECORE_X_EVENT_WINDOW_CONFIGURE + * 3. rotation + * 4. deiconify + **/ +static Eina_Bool +_ecore_evas_x_manual_render_idle_enterer_cb(void *data) +{ + Ecore_Evas *ee = data; + int w, h; + + ee->engine.x.manual_render_idle_enterer = NULL; + + // first manual render + ecore_evas_manual_render(ee); + + // second manual render + evas_output_viewport_get(ecore_evas_get(ee), NULL, NULL, &w, &h); + evas_obscured_clear(ecore_evas_get(ee)); + evas_damage_rectangle_add(ecore_evas_get(ee), 0, 0, w, h); + ecore_evas_manual_render(ee); + + // unset the manual_render only when ecore_evas set the manual render + if (ee->engine.x.manual_render_by_ecore_evas) + { + ee->engine.x.manual_render_by_ecore_evas = EINA_FALSE; + ecore_evas_manual_render_set(ee, EINA_FALSE); + } + + // send deiconify approve after doing manual rending if it's set true + if (ee->engine.x.deiconify_approve_after_manual_render) + { + ee->engine.x.deiconify_approve_after_manual_render = EINA_FALSE; + + /* client sends immediately reply message using value 1 */ + ecore_x_client_message32_send(ee->prop.window, + ECORE_X_ATOM_E_DEICONIFY_APPROVE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + ee->prop.window, 1, + 0, 0, 0); + ecore_x_flush(); + } + + return ECORE_CALLBACK_CANCEL; +} + +static void +_ecore_evas_x_wm_rot_manual_rotation_done_job(void *data) +{ + Ecore_Evas *ee = (Ecore_Evas *)data; + + ee->engine.x.wm_rot.manual_mode_job = NULL; + ee->prop.wm_rot.manual_mode.wait_for_done = EINA_FALSE; + + ecore_x_e_window_rotation_change_done_send(ee->engine.x.win_root, + ee->prop.window, + ee->rotation, + ee->w, + ee->h); + ee->engine.x.wm_rot.done = 0; +} + # ifdef BUILD_ECORE_EVAS_OPENGL_X11 static Ecore_X_Window _ecore_evas_x_gl_window_new(Ecore_Evas *ee, Ecore_X_Window parent, int x, int y, int w, int h, int override, int argb, const int *opt) @@ -161,6 +330,32 @@ _ecore_evas_x_gl_window_new(Ecore_Evas *ee, Ecore_X_Window parent, int x, int y, op++; einfo->vsync = opt[op]; } +#ifdef EVAS_ENGINE_GL_X11_SWAP_MODE_EXISTS + else if (opt[op] == ECORE_EVAS_GL_X11_OPT_SWAP_MODE) + { + op++; + if ((evas_version->major >= 1) && + (evas_version->minor >= 7) && + (evas_version->micro >= 99)) + einfo->swap_mode = opt[op]; + } +#endif + else if (opt[op] == ECORE_EVAS_GL_X11_OPT_GL_DEPTH) + { + op++; + einfo->depth_bits = opt[op]; + } + else if (opt[op] == ECORE_EVAS_GL_X11_OPT_GL_STENCIL) + { + op++; + einfo->stencil_bits = opt[op]; + } + else if (opt[op] == ECORE_EVAS_GL_X11_OPT_GL_MSAA) + { + op++; + einfo->msaa_bits = opt[op]; + } + } } @@ -226,7 +421,6 @@ _ecore_evas_x_gl_window_new(Ecore_Evas *ee, Ecore_X_Window parent, int x, int y, } ecore_x_window_pixel_gravity_set(win, ECORE_X_GRAVITY_FORGET); - /* attr.backing_store = NotUseful; */ /* attr.override_redirect = override; */ /* attr.colormap = einfo->info.colormap; */ @@ -259,6 +453,12 @@ _ecore_evas_x_gl_window_new(Ecore_Evas *ee, Ecore_X_Window parent, int x, int y, else win = 0; + /* TIZEN ONLY check disable sync draw done */ + if (einfo && einfo->disable_sync_draw_done) + ee->disable_sync_draw_done = EINA_TRUE; + + INF("[ECORE_EVAS_X] disable_sync_draw_done is set to %d (GL)", ee->disable_sync_draw_done); + return win; } #endif @@ -307,7 +507,6 @@ _ecore_evas_x_render(Ecore_Evas *ee) { // ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask); } - evas_render_updates_free(updates); _ecore_evas_idle_timeout_update(ee); rend = 1; } @@ -362,42 +561,17 @@ _ecore_evas_x_render(Ecore_Evas *ee) } if (ee->engine.x.damages) { - /* if we have a damage pixmap - we can avoid exposures by - * disabling them just for setting the mask */ - ecore_x_event_mask_set(ee->prop.window, - ECORE_X_EVENT_MASK_KEY_DOWN | - ECORE_X_EVENT_MASK_KEY_UP | - ECORE_X_EVENT_MASK_MOUSE_DOWN | - ECORE_X_EVENT_MASK_MOUSE_UP | - ECORE_X_EVENT_MASK_MOUSE_IN | - ECORE_X_EVENT_MASK_MOUSE_OUT | - ECORE_X_EVENT_MASK_MOUSE_MOVE | - // ECORE_X_EVENT_MASK_WINDOW_DAMAGE | - ECORE_X_EVENT_MASK_WINDOW_VISIBILITY | - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE | - ECORE_X_EVENT_MASK_WINDOW_FOCUS_CHANGE | - ECORE_X_EVENT_MASK_WINDOW_PROPERTY | - ECORE_X_EVENT_MASK_WINDOW_COLORMAP - ); if (ee->shaped) - ecore_x_window_shape_mask_set(ee->prop.window, - ee->engine.x.mask); - /* and re-enable them again */ - ecore_x_event_mask_set(ee->prop.window, - ECORE_X_EVENT_MASK_KEY_DOWN | - ECORE_X_EVENT_MASK_KEY_UP | - ECORE_X_EVENT_MASK_MOUSE_DOWN | - ECORE_X_EVENT_MASK_MOUSE_UP | - ECORE_X_EVENT_MASK_MOUSE_IN | - ECORE_X_EVENT_MASK_MOUSE_OUT | - ECORE_X_EVENT_MASK_MOUSE_MOVE | - ECORE_X_EVENT_MASK_WINDOW_DAMAGE | - ECORE_X_EVENT_MASK_WINDOW_VISIBILITY | - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE | - ECORE_X_EVENT_MASK_WINDOW_FOCUS_CHANGE | - ECORE_X_EVENT_MASK_WINDOW_PROPERTY | - ECORE_X_EVENT_MASK_WINDOW_COLORMAP - ); + { + + /* if we have a damage pixmap - we can avoid exposures by + * disabling them just for setting the mask */ + ecore_x_event_mask_unset(ee->prop.window, ECORE_X_EVENT_MASK_WINDOW_DAMAGE); + ecore_x_window_shape_mask_set(ee->prop.window, + ee->engine.x.mask); + /* and re-enable them again */ + ecore_x_event_mask_set(ee->prop.window, ECORE_X_EVENT_MASK_WINDOW_DAMAGE); + } ecore_x_xregion_set(ee->engine.x.damages, ee->engine.x.gc); ecore_x_pixmap_paste(ee->engine.x.pmap, ee->prop.window, ee->engine.x.gc, 0, 0, ee->w, ee->h, @@ -405,7 +579,6 @@ _ecore_evas_x_render(Ecore_Evas *ee) ecore_x_xregion_free(ee->engine.x.damages); ee->engine.x.damages = NULL; } - evas_render_updates_free(updates); _ecore_evas_idle_timeout_update(ee); rend = 1; } @@ -426,13 +599,14 @@ _ecore_evas_x_render(Ecore_Evas *ee) { // ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask); } - evas_render_updates_free(updates); _ecore_evas_idle_timeout_update(ee); rend = 1; } } else evas_norender(ee->evas); + evas_render_updates_free(updates); + if (ee->func.fn_post_render) ee->func.fn_post_render(ee); /* if (rend) @@ -723,20 +897,19 @@ _ecore_evas_x_event_property_change(void *data __UNUSED__, int type __UNUSED__, { if (strcmp(p, ee->prop.profile) != 0) { - free(ee->prop.profile); - ee->prop.profile = strdup(p); + eina_stringshare_replace(&(ee->prop.profile), p); state_change = 1; } } else if ((!p) && (ee->prop.profile)) { - free(ee->prop.profile); + eina_stringshare_del(ee->prop.profile); ee->prop.profile = NULL; state_change = 1; } else if ((p) && (!ee->prop.profile)) { - ee->prop.profile = strdup(p); + ee->prop.profile = eina_stringshare_add(p); state_change = 1; } @@ -790,8 +963,23 @@ _ecore_evas_x_event_client_message(void *data __UNUSED__, int type __UNUSED__, v return ECORE_CALLBACK_PASS_ON; if (!ee->engine.x.sync_began) { - // qeue a damage + draw. work around an event re-ordering thing. + // We have to rerender twice if first rendering was skipped because of sync begin + // queue a damage + draw. work around an event re-ordering thing. evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + + // Set manual render when sync_begin client message arrived + if (!ecore_evas_manual_render_get(ee)) + { + ee->engine.x.manual_render_by_ecore_evas = EINA_TRUE; + ecore_evas_manual_render_set(ee, EINA_TRUE); + } + + // add manual render idle enterer + if (ee->engine.x.manual_render_idle_enterer) + ecore_idle_enterer_del(ee->engine.x.manual_render_idle_enterer); + + ee->engine.x.manual_render_idle_enterer = + ecore_idle_enterer_add(_ecore_evas_x_manual_render_idle_enterer_cb, ee); } ee->engine.x.sync_began = 1; ee->engine.x.sync_cancel = 0; @@ -823,6 +1011,160 @@ _ecore_evas_x_event_client_message(void *data __UNUSED__, int type __UNUSED__, v ee->engine.x.netwm_sync_val_hi = (int)e->data.l[3]; ee->engine.x.netwm_sync_set = 1; } + else if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE) + { + ee = ecore_event_window_match(e->data.l[0]); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->data.l[0] != (long)ee->prop.window) + return ECORE_CALLBACK_PASS_ON; + if (ee->prop.wm_rot.supported) + { + ee->prop.wm_rot.angle = (int)e->data.l[1]; + ee->prop.wm_rot.win_resize = (int)e->data.l[2]; + ee->prop.wm_rot.w = (int)e->data.l[3]; + ee->prop.wm_rot.h = (int)e->data.l[4]; + if ((ee->prop.wm_rot.win_resize) && + ((ee->w != ee->prop.wm_rot.w) || (ee->h != ee->prop.wm_rot.h))) + ee->engine.x.wm_rot.configure_coming = 1; + ee->engine.x.wm_rot.prepare = 1; + ee->engine.x.wm_rot.request = 0; + ee->engine.x.wm_rot.done = 0; + + if (ee->prop.wm_rot.app_set) + { + //change req value because wm change window size + ee->req.w = ee->prop.wm_rot.w; + ee->req.h = ee->prop.wm_rot.h; + } + INF("ROT_PREPARE w:0x%8x, a:%d, conf_coming:%d, resize:%d (%dx%d)", + ee->prop.window, ee->prop.wm_rot.angle, + ee->engine.x.wm_rot.configure_coming, + ee->prop.wm_rot.win_resize, ee->prop.wm_rot.w, + ee->prop.wm_rot.h); + } + } + else if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST) + { + ee = ecore_event_window_match(e->data.l[0]); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->data.l[0] != (long)ee->prop.window) + return ECORE_CALLBACK_PASS_ON; + if (ee->prop.wm_rot.supported) + { + INF("ROT_REQ win:0x%08x", ee->prop.window); + if (ee->prop.wm_rot.app_set) + { + int angle = ee->prop.wm_rot.angle; + Eina_Bool resize = ee->prop.wm_rot.win_resize; + // v1 + ee->engine.x.wm_rot.prepare = 0; + ee->engine.x.wm_rot.request = 1; + ee->engine.x.wm_rot.done = 0; + if (resize) + { + if ((ee->w == ee->prop.wm_rot.w) && + (ee->h == ee->prop.wm_rot.h)) + { + ee->engine.x.wm_rot.configure_coming = 0; + } + } + if (!ee->engine.x.wm_rot.configure_coming) + { + if (ee->prop.wm_rot.manual_mode.set) + { + ee->prop.wm_rot.manual_mode.wait_for_done = EINA_TRUE; + _ecore_evas_x_wm_rot_manual_rotation_done_timeout_update(ee); + } + _ecore_evas_x_rotation_set(ee, angle, (!resize)); + INF("ROT_SET win:0x%08x, a:%d, resize:%d, configure_coming:%d (%dx%d)", + ee->prop.window, angle, resize, ee->engine.x.wm_rot.configure_coming, + ee->prop.wm_rot.w, ee->prop.wm_rot.h); + /* the below flag "configure_coming" can be set by calling "_ecore_x_window_resize_wrapper", + * and this function can be called by trying to resize window. + * the purpose of below flag is for blocking render evas until recieving ConfigureNotify. + */ + if (ee->engine.x.wm_rot.configure_coming) + { + if (!ecore_evas_manual_render_get(ee)) + ecore_evas_manual_render_set(ee, EINA_TRUE); + // remove idle enterer that is for manual render, + // Do not render until recieving ConfigureNotify, + if (ee->engine.x.manual_render_idle_enterer) + { + ecore_idle_enterer_del(ee->engine.x.manual_render_idle_enterer); + ee->engine.x.manual_render_idle_enterer = NULL; + } + INF("SET MANUAL_RENDER win:0x%08x", ee->prop.window); + } + } + } + else + { + ee->engine.x.wm_rot.prepare = 0; + ee->engine.x.wm_rot.request = 1; + ee->engine.x.wm_rot.done = 0; + if (ee->prop.wm_rot.win_resize) + { + if ((ee->w == ee->prop.wm_rot.w) && + (ee->h == ee->prop.wm_rot.h)) + { + ee->engine.x.wm_rot.configure_coming = 0; + } + } + if (!ee->engine.x.wm_rot.configure_coming) + { + if (ee->prop.wm_rot.angle == ee->rotation) + { + if (ee->func.fn_state_change) ee->func.fn_state_change(ee); + ee->engine.x.wm_rot.request = 0; + ee->engine.x.wm_rot.done = 1; + } + } + } + } + } + else if (e->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL) + { + ///TODO after access structure determined + // if (ee->func.fn_msg_handle) + // ee->func.fn_msg_handle(ee, msg_domain, msg_id, data, size); + } + else if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE) + { + ee = ecore_event_window_match(e->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->data.l[1] != 0) //wm sends request message using value 0 + return ECORE_CALLBACK_PASS_ON; + + if (ee->engine.x.deiconify_job) + ecore_job_del(ee->engine.x.deiconify_job); + + /* queue a deiconify job to give the chance to other jobs */ + ee->engine.x.deiconify_job = ecore_job_add(_ecore_evas_x_deiconify_job, + ee); + } + else if (e->message_type == ECORE_X_ATOM_E_WINDOW_AUX_HINT_ALLOWED) + { + ee = ecore_event_window_match(e->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + + int id = e->data.l[1]; /* id of aux hint */ + Eina_List *ll; + Ecore_Evas_Aux_Hint *aux; + EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux) + { + if (id == aux->id) + { + aux->allowed = 1; + if (!aux->notified) + { + if (ee->func.fn_state_change) ee->func.fn_state_change(ee); + aux->notified = 1; + } + break; + } + } + } return ECORE_CALLBACK_PASS_ON; } @@ -1085,8 +1427,16 @@ _ecore_evas_x_event_window_configure(void *data __UNUSED__, int type __UNUSED__, if (ee->func.fn_move) ee->func.fn_move(ee); } } - if ((ee->w != e->w) || (ee->h != e->h)) + if ((ee->w != e->w) || (ee->h != e->h) || + (ee->req.w != e->w) || (ee->req.h != e->h)) { + // Set manual render when ecore_evas is resized + if (!ecore_evas_manual_render_get(ee)) + { + ee->engine.x.manual_render_by_ecore_evas = EINA_TRUE; + ecore_evas_manual_render_set(ee, EINA_TRUE); + } + ee->w = e->w; ee->h = e->h; ee->req.w = ee->w; @@ -1121,6 +1471,43 @@ _ecore_evas_x_event_window_configure(void *data __UNUSED__, int type __UNUSED__, ee->expecting_resize.h = 0; } if (ee->func.fn_resize) ee->func.fn_resize(ee); + + if (ee->prop.wm_rot.supported) + { + // should keep on doing of rotation job even if resize request is denied by wm. + // so, comparing requested size with notified size doesn't need no more. + INF("CONFIGURE_NOTI win:0x%08x (%d x %d)", + ee->prop.window, e->w, e->h); + + ee->prop.wm_rot.win_resize = 0; + ee->engine.x.wm_rot.configure_coming = 0; + if (ee->engine.x.wm_rot.request) + { + if (ee->prop.wm_rot.manual_mode.set) + { + ee->prop.wm_rot.manual_mode.wait_for_done = EINA_TRUE; + _ecore_evas_x_wm_rot_manual_rotation_done_timeout_update(ee); + } + if (ee->prop.wm_rot.angle != ee->rotation) + { + _ecore_evas_x_rotation_set(ee, ee->prop.wm_rot.angle, 1); + } + else + { + ee->engine.x.wm_rot.request = 0; + ee->engine.x.wm_rot.done = 1; + } + } + } + // add manual render idle enterer + if (ee->engine.x.manual_render_idle_enterer) + ecore_idle_enterer_del(ee->engine.x.manual_render_idle_enterer); + + /* queue an idle enterer to render manually until each object finishes + changing its size */ + ee->engine.x.manual_render_idle_enterer = + ecore_idle_enterer_add(_ecore_evas_x_manual_render_idle_enterer_cb, + ee); } return ECORE_CALLBACK_PASS_ON; } @@ -1150,16 +1537,17 @@ _ecore_evas_x_event_window_show(void *data __UNUSED__, int type __UNUSED__, void ee = ecore_event_window_match(e->win); if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + /* some GL drivers are doing buffer copy in a separate thread. * we need to check whether GL driver sends SYNC_DRAW_DONE msg afger copying - * that are required in order to exactly render. - added by gl77.lee + * that are required in order to exactly render. */ if (ee->gl_sync_draw_done < 0) { if (getenv("ECORE_EVAS_GL_SYNC_DRAW_DONE")) - ee->gl_sync_draw_done = atoi(getenv("ECORE_EVAS_GL_SYNC_DRAW_DONE")); + ee->gl_sync_draw_done = atoi(getenv("ECORE_EVAS_GL_SYNC_DRAW_DONE")); else - ee->gl_sync_draw_done = 0; + ee->gl_sync_draw_done = 0; } if (first_map_bug < 0) { @@ -1405,8 +1793,23 @@ _ecore_evas_x_init(void) static void _ecore_evas_x_free(Ecore_Evas *ee) { + if (ee->engine.x.pixmap.back) + ecore_x_pixmap_free(ee->engine.x.pixmap.back); + if (ee->engine.x.pixmap.front) + ecore_x_pixmap_free(ee->engine.x.pixmap.front); + _ecore_evas_x_group_leader_unset(ee); _ecore_evas_x_sync_set(ee); + if (ee->engine.x.deiconify_job) + { + ecore_job_del(ee->engine.x.deiconify_job); + ee->engine.x.deiconify_job = NULL; + } + if (ee->engine.x.manual_render_idle_enterer) + { + ecore_idle_enterer_del(ee->engine.x.manual_render_idle_enterer); + ee->engine.x.manual_render_idle_enterer = NULL; + } if (ee->engine.x.win_shaped_input) ecore_x_window_free(ee->engine.x.win_shaped_input); ecore_x_window_free(ee->prop.window); @@ -1414,6 +1817,12 @@ _ecore_evas_x_free(Ecore_Evas *ee) if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask); if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc); if (ee->engine.x.damages) ecore_x_xregion_free(ee->engine.x.damages); + if (ee->prop.profile) eina_stringshare_del(ee->prop.profile); + if (ee->engine.x.wm_rot.manual_mode_job) + { + ecore_job_del(ee->engine.x.wm_rot.manual_mode_job); + ee->engine.x.wm_rot.manual_mode_job = NULL; + } ee->engine.x.pmap = 0; ee->engine.x.mask = 0; ee->engine.x.gc = 0; @@ -1505,10 +1914,43 @@ _ecore_evas_x_managed_move(Ecore_Evas *ee, int x, int y) } static void +_ecore_x_window_resize_wrapper(Ecore_Evas *ee, int w, int h) +{ + if ((ee->w == w) && (ee->h == h)) return; + + ecore_x_window_resize(ee->prop.window, w, h); + + if (ee->engine.x.wm_rot.request) + { + ee->engine.x.wm_rot.configure_coming = 1; + INF("RESIZE_REQ win:0x%08x (%d x %d)", ee->prop.window, w, h); + } +} + +static void _ecore_evas_x_resize(Ecore_Evas *ee, int w, int h) { ee->req.w = w; ee->req.h = h; + + /* check for valid property window + * + * NB: If we do not have one, check for valid pixmap rendering */ + if (!ee->prop.window) + { + /* the ecore_evas was resized. we need to free the back pixmap */ + if ((ee->engine.x.pixmap.back_w != w) || (ee->engine.x.pixmap.back_h != h)) + { + /* free the backing pixmap */ + if (ee->engine.x.pixmap.back) + { + ecore_x_pixmap_free(ee->engine.x.pixmap.back); + ee->engine.x.pixmap.back_w = 0; + ee->engine.x.pixmap.back_h = 0; + } + } + } + if (ee->engine.x.direct_resize) { if ((ee->w != w) || (ee->h != h)) @@ -1543,7 +1985,7 @@ _ecore_evas_x_resize(Ecore_Evas *ee, int w, int h) (ee->engine.x.configure_coming)) { ee->engine.x.configure_coming = 1; - ecore_x_window_resize(ee->prop.window, w, h); + _ecore_x_window_resize_wrapper(ee, w, h); } } @@ -1613,6 +2055,11 @@ _ecore_evas_x_move_resize(Ecore_Evas *ee, int x, int y, int w, int h) ee->x = x; ee->y = y; } + if (ee->engine.x.wm_rot.request) + { + ee->engine.x.wm_rot.configure_coming = 1; + ERR("RESIZE_REQ (%d x %d)", w, h); + } } } @@ -1625,6 +2072,13 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize, rot_dif = ee->rotation - rotation; if (rot_dif < 0) rot_dif = -rot_dif; + // Set manual render when ecore_evas is rotated + if (!ecore_evas_manual_render_get(ee)) + { + ee->engine.x.manual_render_by_ecore_evas = EINA_TRUE; + ecore_evas_manual_render_set(ee, EINA_TRUE); + } + if (rot_dif != 180) { int minw, minh, maxw, maxh, basew, baseh, stepw, steph; @@ -1639,16 +2093,18 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize, ee->engine.x.configure_coming = 1; if (!ee->prop.fullscreen) { - ecore_x_window_resize(ee->prop.window, ee->req.h, ee->req.w); + _ecore_x_window_resize_wrapper(ee, ee->req.h, ee->req.w); ee->expecting_resize.w = ee->h; ee->expecting_resize.h = ee->w; + evas_output_size_set(ee->evas, ee->req.h, ee->req.w); + evas_output_viewport_set(ee->evas, 0, 0, ee->req.h, ee->req.w); } else { int w, h; ecore_x_window_size_get(ee->prop.window, &w, &h); - ecore_x_window_resize(ee->prop.window, h, w); + _ecore_x_window_resize_wrapper(ee, h, w); if ((rotation == 0) || (rotation == 180)) { evas_output_size_set(ee->evas, ee->req.w, ee->req.h); @@ -1687,6 +2143,7 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize, else evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); } + ecore_evas_size_min_get(ee, &minw, &minh); ecore_evas_size_max_get(ee, &maxw, &maxh); ecore_evas_size_base_get(ee, &basew, &baseh); @@ -1715,42 +2172,125 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize, else evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); } -} - -#define _USE_WIN_ROT_EFFECT 1 -#if _USE_WIN_ROT_EFFECT -static void _ecore_evas_x_flush_pre(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__); + if (ee->engine.x.manual_render_idle_enterer) + ecore_idle_enterer_del(ee->engine.x.manual_render_idle_enterer); -typedef struct _Ecore_Evas_X_Rotation_Effect Ecore_Evas_X_Rotation_Effect; -struct _Ecore_Evas_X_Rotation_Effect -{ - Eina_Bool wait_for_comp_reply; -}; + /* queue an idle enterer to render manually until each object finishes + changing its size */ + ee->engine.x.manual_render_idle_enterer = + ecore_idle_enterer_add(_ecore_evas_x_manual_render_idle_enterer_cb, ee); +} -static Ecore_Evas_X_Rotation_Effect _rot_effect = +static Eina_Bool +_ecore_evas_x_wm_rotation_check(Ecore_Evas *ee) { - EINA_FALSE -}; + if (ee->prop.wm_rot.supported) + { + if (ee->prop.wm_rot.app_set) + { + // v1 + if (ee->engine.x.wm_rot.request) + { + if (ee->prop.wm_rot.win_resize) + { + if (!((ee->w == ee->prop.wm_rot.w) && (ee->h == ee->prop.wm_rot.h))) + { + return EINA_FALSE; + } + else + ee->engine.x.wm_rot.configure_coming = 0; + } + } + } + else + { + if (ee->engine.x.wm_rot.request) + { + if (ee->prop.wm_rot.win_resize) + { + if (!((ee->w == ee->prop.wm_rot.w) && (ee->h == ee->prop.wm_rot.h))) + { + return EINA_FALSE; + } + else + ee->engine.x.wm_rot.configure_coming = 0; + } + } + } + } + return EINA_TRUE; +} static void -_ecore_evas_x_rotation_effect_setup(void) +_ecore_x_win_rotation_transform_hint_set(Ecore_X_Window win, int angle) { - _rot_effect.wait_for_comp_reply = EINA_TRUE; + unsigned int transform_hint; // Ecore_X_Window_Rotation_Transform_Hint + + switch (angle) + { + case 270: + transform_hint = ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_90; + break; + case 180: + transform_hint = ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_180; + break; + case 90: + transform_hint = ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_270; + break; + case 0: + default: + transform_hint = ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_0; + break; + } + + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_WINDOW_ROTATION_TRANSFORM_HINT, + &transform_hint, 1); } -#endif /* end of _USE_WIN_ROT_EFFECT */ + static void _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize) { - if (ee->rotation == rotation) return; + Eina_Bool ch_prop = EINA_FALSE; + if (!strcmp(ee->driver, "xrender_x11")) return; -#if _USE_WIN_ROT_EFFECT - int angles[2]; - angles[0] = rotation; - angles[1] = ee->rotation; -#endif /* end of _USE_WIN_ROT_EFFECT */ + /* send rotation done message to wm, even if window is already rotated. + * that's why wm must be wait for comming rotation done message + * after sending rotation request. + */ + if (ee->rotation == rotation) + { + if (ee->engine.x.wm_rot.request) + { + if (ee->prop.wm_rot.manual_mode.set) + { + ee->prop.wm_rot.manual_mode.wait_for_done = EINA_FALSE; + if (ee->prop.wm_rot.manual_mode.timer) + ecore_timer_del(ee->prop.wm_rot.manual_mode.timer); + ee->prop.wm_rot.manual_mode.timer = NULL; + } + + ecore_x_e_window_rotation_change_done_send(ee->engine.x.win_root, + ee->prop.window, + ee->rotation, + ee->w, + ee->h); + ee->engine.x.wm_rot.request = 0; + } + return; + } + + // If pre rotation is supported check here + // TODO: Find another way to check for prerotation support (note: EVAS_GL...) + if (getenv("EVAS_GL_WIN_PREROTATION")) + { + _ecore_x_win_rotation_transform_hint_set(ee->prop.window, rotation); + } + + if (ee->prop.wm_rot.supported) + if (!_ecore_evas_x_wm_rotation_check(ee)) return; if (!strcmp(ee->driver, "opengl_x11")) { @@ -1762,15 +2302,7 @@ _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize) einfo->info.rotation = rotation; _ecore_evas_x_rotation_set_internal(ee, rotation, resize, (Evas_Engine_Info *)einfo); -# if _USE_WIN_ROT_EFFECT - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &angles, 2); -# else - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &rotation, 1); -# endif + ch_prop = EINA_TRUE; #endif /* BUILD_ECORE_EVAS_OPENGL_X11 */ } else if (!strcmp(ee->driver, "software_x11")) @@ -1783,15 +2315,7 @@ _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize) einfo->info.rotation = rotation; _ecore_evas_x_rotation_set_internal(ee, rotation, resize, (Evas_Engine_Info *)einfo); -# if _USE_WIN_ROT_EFFECT - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &angles, 2); -# else - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &rotation, 1); -# endif + ch_prop = EINA_TRUE; #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */ } else if (!strcmp(ee->driver, "software_16_x11")) @@ -1804,15 +2328,7 @@ _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize) einfo->info.rotation = rotation; _ecore_evas_x_rotation_set_internal(ee, rotation, resize, (Evas_Engine_Info *)einfo); -# if _USE_WIN_ROT_EFFECT - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &angles, 2); -# else - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &rotation, 1); -# endif + ch_prop = EINA_TRUE; #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */ } else if (!strcmp(ee->driver, "software_8_x11")) @@ -1825,29 +2341,31 @@ _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize) einfo->info.rotation = rotation; _ecore_evas_x_rotation_set_internal(ee, rotation, resize, (Evas_Engine_Info *)einfo); -# if _USE_WIN_ROT_EFFECT - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &angles, 2); -# else - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &rotation, 1); -# endif + ch_prop = EINA_TRUE; #endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */ } -#if _USE_WIN_ROT_EFFECT - if ((ee->visible) && - ((ecore_x_e_comp_sync_supported_get(ee->engine.x.win_root)) && - (!ee->no_comp_sync) && (_ecore_evas_app_comp_sync)) && - (ee->engine.x.sync_counter) && - (ee->engine.x.sync_val > 0)) + if (ch_prop) { - _ecore_evas_x_rotation_effect_setup(); - _ecore_evas_x_flush_pre(ee, NULL, NULL); + if (ee->func.fn_state_change) ee->func.fn_state_change(ee); + + if (!ee->engine.x.wm_rot.configure_coming) + { + if (ee->prop.wm_rot.supported) + { + if (ee->engine.x.wm_rot.request) + { + ee->engine.x.wm_rot.request = 0; + ee->engine.x.wm_rot.done = 1; + } + } + } + + int angles[2] = { rotation, rotation }; + ecore_x_window_prop_property_set(ee->prop.window, + ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, + ECORE_X_ATOM_CARDINAL, 32, &angles, 2); } -#endif /* end of _USE_WIN_ROT_EFFECT */ } static void @@ -2006,6 +2524,7 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) ee->shaped = 0; ee->alpha = alpha; + _ecore_evas_x_sync_clear(ee); ecore_x_window_free(ee->prop.window); ecore_event_window_unregister(ee->prop.window); if (ee->alpha) @@ -2053,7 +2572,8 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); if (ee->prop.borderless) ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless); - if (ee->visible) ecore_x_window_show(ee->prop.window); + if (ee->visible || ee->should_be_visible) + ecore_x_window_show(ee->prop.window); if (ee->prop.focused) ecore_x_window_focus(ee->prop.window); if (ee->prop.title) { @@ -2067,6 +2587,12 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) _ecore_evas_x_group_leader_update(ee); ecore_x_window_defaults_set(ee->prop.window); _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_wm_rotation_protocol_set(ee); + _ecore_evas_x_aux_hints_supprted_update(ee); + _ecore_evas_x_aux_hints_update(ee); + //reset rotation info + if (ee->prop.wm_rot.app_set) + ecore_x_e_window_rotation_app_set(ee->prop.window, EINA_TRUE); _ecore_evas_x_sync_set(ee); _ecore_evas_x_size_pos_hints_update(ee); #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */ @@ -2091,6 +2617,7 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) ee->shaped = 0; ee->alpha = alpha; + _ecore_evas_x_sync_clear(ee); ecore_x_window_free(ee->prop.window); ecore_event_window_unregister(ee->prop.window); ee->prop.window = 0; @@ -2173,7 +2700,8 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); if (ee->prop.borderless) ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless); - if (ee->visible) ecore_x_window_show(ee->prop.window); + if (ee->visible || ee->should_be_visible) + ecore_x_window_show(ee->prop.window); if (ee->prop.focused) ecore_x_window_focus(ee->prop.window); if (ee->prop.title) { @@ -2187,6 +2715,12 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) _ecore_evas_x_group_leader_update(ee); ecore_x_window_defaults_set(ee->prop.window); _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_wm_rotation_protocol_set(ee); + _ecore_evas_x_aux_hints_supprted_update(ee); + _ecore_evas_x_aux_hints_update(ee); + //reset rotation info + if (ee->prop.wm_rot.app_set) + ecore_x_e_window_rotation_app_set(ee->prop.window, EINA_TRUE); _ecore_evas_x_sync_set(ee); _ecore_evas_x_size_pos_hints_update(ee); #endif /* BUILD_ECORE_EVAS_OPENGL_X11 */ @@ -2209,6 +2743,7 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) ee->shaped = 0; ee->alpha = alpha; + _ecore_evas_x_sync_clear(ee); ecore_x_window_free(ee->prop.window); ecore_event_window_unregister(ee->prop.window); if (ee->alpha) @@ -2256,7 +2791,8 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); if (ee->prop.borderless) ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless); - if (ee->visible) ecore_x_window_show(ee->prop.window); + if (ee->visible || ee->should_be_visible) + ecore_x_window_show(ee->prop.window); if (ee->prop.focused) ecore_x_window_focus(ee->prop.window); if (ee->prop.title) { @@ -2270,6 +2806,12 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) _ecore_evas_x_group_leader_update(ee); ecore_x_window_defaults_set(ee->prop.window); _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_wm_rotation_protocol_set(ee); + _ecore_evas_x_aux_hints_supprted_update(ee); + _ecore_evas_x_aux_hints_update(ee); + //reset rotation info + if (ee->prop.wm_rot.app_set) + ecore_x_e_window_rotation_app_set(ee->prop.window, EINA_TRUE); _ecore_evas_x_sync_set(ee); _ecore_evas_x_size_pos_hints_update(ee); #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */ @@ -2292,6 +2834,7 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) ee->shaped = 0; ee->alpha = alpha; + _ecore_evas_x_sync_clear(ee); ecore_x_window_free(ee->prop.window); ecore_event_window_unregister(ee->prop.window); if (ee->alpha) @@ -2339,7 +2882,8 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); if (ee->prop.borderless) ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless); - if (ee->visible) ecore_x_window_show(ee->prop.window); + if (ee->visible || ee->should_be_visible) + ecore_x_window_show(ee->prop.window); if (ee->prop.focused) ecore_x_window_focus(ee->prop.window); if (ee->prop.title) { @@ -2353,6 +2897,12 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) _ecore_evas_x_group_leader_update(ee); ecore_x_window_defaults_set(ee->prop.window); _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_wm_rotation_protocol_set(ee); + _ecore_evas_x_aux_hints_supprted_update(ee); + _ecore_evas_x_aux_hints_update(ee); + //reset rotation info + if (ee->prop.wm_rot.app_set) + ecore_x_e_window_rotation_app_set(ee->prop.window, EINA_TRUE); _ecore_evas_x_sync_set(ee); _ecore_evas_x_size_pos_hints_update(ee); @@ -2520,7 +3070,8 @@ _ecore_evas_x_title_set(Ecore_Evas *ee, const char *t) { if (ee->prop.title) free(ee->prop.title); ee->prop.title = NULL; - if (t) ee->prop.title = strdup(t); + if (!t) return; + ee->prop.title = strdup(t); ecore_x_icccm_title_set(ee->prop.window, ee->prop.title); ecore_x_netwm_name_set(ee->prop.window, ee->prop.title); } @@ -2659,7 +3210,8 @@ static void _ecore_evas_x_iconified_set(Ecore_Evas *ee, int on) { if (ee->prop.iconified == on) return; - ee->prop.iconified = on; + if (((ee->should_be_visible) && (!ee->visible)) || (!ee->visible)) + ee->prop.iconified = on; _ecore_evas_x_hints_update(ee); if (on) ecore_x_icccm_iconic_request_send(ee->prop.window, ee->engine.x.win_root); @@ -2681,8 +3233,12 @@ static void _ecore_evas_x_withdrawn_set(Ecore_Evas *ee, int withdrawn) { if (ee->prop.withdrawn == withdrawn) return; - ee->prop.withdrawn = withdrawn; +// ee->prop.withdrawn = withdrawn; _ecore_evas_x_hints_update(ee); + if (withdrawn) + ecore_evas_hide(ee); + else + ecore_evas_show(ee); } static void @@ -2695,7 +3251,7 @@ _ecore_evas_x_sticky_set(Ecore_Evas *ee, int sticky) * property change event. * ee->prop.sticky = sticky; */ - ee->engine.x.state.sticky = sticky; +// ee->engine.x.state.sticky = sticky; if (ee->should_be_visible) ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, ECORE_X_WINDOW_STATE_STICKY, -1, sticky); @@ -2758,6 +3314,24 @@ _ecore_evas_x_override_set(Ecore_Evas *ee, int on) } static void +_ecore_evas_x_maximized_set(Ecore_Evas *ee, int on) +{ + if (ee->prop.maximized == on) return; + ee->engine.x.state.maximized_h = 1; + ee->engine.x.state.maximized_v = 1; +// ee->prop.maximized = on; + if (ee->should_be_visible) + { + ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_MAXIMIZED_VERT, -1, on); + ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ, -1, on); + } + else + _ecore_evas_x_state_update(ee); +} + +static void _ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on) { if (ee->prop.fullscreen == on) return; @@ -2780,6 +3354,114 @@ _ecore_evas_x_profiles_set(Ecore_Evas *ee, const char **plist, int n) } static void +_ecore_evas_x_wm_rot_preferred_rotation_set(Ecore_Evas *ee, int rot) +{ + if (ee->prop.wm_rot.supported) + { + if (!ee->prop.wm_rot.app_set) + { + ecore_x_e_window_rotation_app_set(ee->prop.window, EINA_TRUE); + ee->prop.wm_rot.app_set = EINA_TRUE; + } + ecore_x_e_window_rotation_preferred_rotation_set(ee->prop.window, rot); + ee->prop.wm_rot.preferred_rot = rot; + } +} + +static void +_ecore_evas_x_wm_rot_available_rotations_set(Ecore_Evas *ee, const int *rots, unsigned int count) +{ + if (ee->prop.wm_rot.supported) + { + if (!ee->prop.wm_rot.app_set) + { + ecore_x_e_window_rotation_app_set(ee->prop.window, EINA_TRUE); + ee->prop.wm_rot.app_set = EINA_TRUE; + } + + if (ee->prop.wm_rot.available_rots) + { + free(ee->prop.wm_rot.available_rots); + ee->prop.wm_rot.available_rots = NULL; + } + + ee->prop.wm_rot.count = 0; + + if (count > 0) + { + ee->prop.wm_rot.available_rots = calloc(count, sizeof(int)); + if (!ee->prop.wm_rot.available_rots) return; + + memcpy(ee->prop.wm_rot.available_rots, rots, sizeof(int) * count); + } + + ee->prop.wm_rot.count = count; + + ecore_x_e_window_rotation_available_rotations_set(ee->prop.window, rots, count); + } +} + +static void +_ecore_evas_x_wm_rot_manual_rotation_done_set(Ecore_Evas *ee, Eina_Bool set) +{ + ee->prop.wm_rot.manual_mode.set = set; +} + +static void +_ecore_evas_x_wm_rot_manual_rotation_done(Ecore_Evas *ee) +{ + if ((ee->prop.wm_rot.supported) && + (ee->prop.wm_rot.app_set) && + (ee->prop.wm_rot.manual_mode.set)) + { + if (ee->prop.wm_rot.manual_mode.wait_for_done) + { + if (ee->prop.wm_rot.manual_mode.timer) + ecore_timer_del(ee->prop.wm_rot.manual_mode.timer); + ee->prop.wm_rot.manual_mode.timer = NULL; + + if (ee->engine.x.wm_rot.manual_mode_job) + ecore_job_del(ee->engine.x.wm_rot.manual_mode_job); + ee->engine.x.wm_rot.manual_mode_job = ecore_job_add(_ecore_evas_x_wm_rot_manual_rotation_done_job, ee); + } + } +} + +static Eina_Bool +_ecore_evas_x_wm_rot_manual_rotation_done_timeout(void *data) +{ + Ecore_Evas *ee = data; + + ee->prop.wm_rot.manual_mode.timer = NULL; + _ecore_evas_x_wm_rot_manual_rotation_done(ee); + return ECORE_CALLBACK_CANCEL; +} + +static void +_ecore_evas_x_aux_hints_set(Ecore_Evas *ee, const char *hints) +{ + if (hints) + ecore_x_window_prop_property_set + (ee->prop.window, ECORE_X_ATOM_E_WINDOW_AUX_HINT, + ECORE_X_ATOM_STRING, 8, (void *)hints, strlen(hints) + 1); + else + ecore_x_window_prop_property_del(ee->prop.window, + ECORE_X_ATOM_E_WINDOW_AUX_HINT); +} + +static void +_ecore_evas_x_wm_rot_manual_rotation_done_timeout_update(Ecore_Evas *ee) +{ + if (ee->prop.wm_rot.manual_mode.timer) + ecore_timer_del(ee->prop.wm_rot.manual_mode.timer); + + /* TODO: make time value configurable */ + ee->prop.wm_rot.manual_mode.timer = ecore_timer_add + (4.0f, _ecore_evas_x_wm_rot_manual_rotation_done_timeout, ee); +} + + +static void _ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on) { if (ee->prop.avoid_damage == on) return; @@ -2959,7 +3641,18 @@ _ecore_evas_x_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int * Ecore_X_Window root; Ecore_X_Randr_Output *out = NULL; Ecore_X_Randr_Crtc crtc; - + unsigned int val[4] = { 0 }; + + if (ecore_x_window_prop_card32_get + (ee->prop.window, ecore_x_atom_get("E_ZONE_GEOMETRY"), val, 4) == 4) + { + if (x) *x = (int)val[0]; + if (y) *y = (int)val[1]; + if (w) *w = (int)val[2]; + if (h) *h = (int)val[3]; + return; + } + root = ecore_x_window_root_get(ee->prop.window); out = ecore_x_randr_window_outputs_get(ee->prop.window, &outnum); if (!out) @@ -3072,7 +3765,7 @@ static Ecore_Evas_Engine_Func _ecore_x_engine_func = _ecore_evas_x_iconified_set, _ecore_evas_x_borderless_set, _ecore_evas_x_override_set, - NULL, + _ecore_evas_x_maximized_set, _ecore_evas_x_fullscreen_set, _ecore_evas_x_avoid_damage_set, _ecore_evas_x_withdrawn_set, @@ -3091,7 +3784,16 @@ static Ecore_Evas_Engine_Func _ecore_x_engine_func = NULL, // render _ecore_evas_x_screen_geometry_get, - _ecore_evas_x_screen_dpi_get + _ecore_evas_x_screen_dpi_get, + NULL, + NULL, //fn_msg_send + + _ecore_evas_x_wm_rot_preferred_rotation_set, + _ecore_evas_x_wm_rot_available_rotations_set, + _ecore_evas_x_wm_rot_manual_rotation_done_set, + _ecore_evas_x_wm_rot_manual_rotation_done, + + _ecore_evas_x_aux_hints_set }; #endif /* BUILD_ECORE_EVAS_X11 */ @@ -3102,34 +3804,159 @@ static Ecore_Evas_Engine_Func _ecore_x_engine_func = #if defined (BUILD_ECORE_EVAS_SOFTWARE_X11) || defined (BUILD_ECORE_EVAS_OPENGL_X11) || defined (BUILD_ECORE_EVAS_SOFTWARE_16_X11) || defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11) static void -_ecore_evas_x_flush_pre(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__) +_ecore_evas_x_render_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED) { Ecore_Evas *ee = data; - if (ee->no_comp_sync) return; - if (!_ecore_evas_app_comp_sync) return; - if (ee->engine.x.sync_counter) + /* before rendering to the back buffer pixmap, we should check the + * size. If the back buffer is not the proper size, destroy it and + * create a new one at the proper size */ + if ((ee->engine.x.pixmap.back_w != ee->w) || (ee->engine.x.pixmap.back_h != ee->h)) { - if (ee->engine.x.sync_began) + /* free the backing pixmap */ + if (ee->engine.x.pixmap.back) + ecore_x_pixmap_free(ee->engine.x.pixmap.back); + + ee->engine.x.pixmap.back = + ecore_x_pixmap_new(ee->engine.x.win_root, ee->w, ee->h, + ee->engine.x.pixmap.depth); + + ee->engine.x.pixmap.back_w = ee->w; + ee->engine.x.pixmap.back_h = ee->h; + + if (!strcmp(ee->driver, "software_x11")) + { +# ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 + Evas_Engine_Info_Software_X11 *einfo; + + einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.drawable = ee->engine.x.pixmap.back; + + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() init engine '%s' failed.", + ee->driver); + } + } +# endif + } + else if (!strcmp(ee->driver, "opengl_x11")) { - ee->engine.x.sync_val++; - if (!ee->engine.x.sync_cancel) +# ifdef BUILD_ECORE_EVAS_OPENGL_X11 + Evas_Engine_Info_GL_X11 *einfo; + + einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas); + if (einfo) { - if (!ee->semi_sync) - ecore_x_sync_counter_val_wait(ee->engine.x.sync_counter, - ee->engine.x.sync_val); + einfo->info.drawable = ee->engine.x.pixmap.back; + einfo->info.drawable_back = ee->engine.x.pixmap.front; + + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() init engine '%s' failed.", + ee->driver); + } } +# endif } } } + +static void +_ecore_evas_x_flush_pre(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__) +{ + Ecore_Evas *ee = data; + + if (ee->no_comp_sync) return; + if (!_ecore_evas_app_comp_sync) return; + if (!ee->engine.x.sync_counter) return; + if (!ee->engine.x.sync_began) return; + if (ee->disable_sync_draw_done) return; // TIZEN ONLY + + ee->engine.x.sync_val++; + if (!ee->engine.x.sync_cancel) + { + if (!ee->semi_sync) + ecore_x_sync_counter_val_wait(ee->engine.x.sync_counter, + ee->engine.x.sync_val); + } +} + static void _ecore_evas_x_flush_post(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__) { Ecore_Evas *ee = data; + if ((!ee->prop.window) && (ee->engine.x.pixmap.back)) + { + Ecore_X_Pixmap prev; + + /* done drawing to the back buffer. flip it to the front so that + * any calls to "fetch pixmap" will return the front buffer already + * pre-rendered */ + + /* record the current front buffer */ + prev = ee->engine.x.pixmap.front; + + /* flip them */ + ee->engine.x.pixmap.front = ee->engine.x.pixmap.back; + + /* reassign back buffer to be the old front one */ + ee->engine.x.pixmap.back = prev; + + int prev_w, prev_h; + prev_w = ee->engine.x.pixmap.front_w; + prev_h = ee->engine.x.pixmap.front_h; + ee->engine.x.pixmap.front_w = ee->engine.x.pixmap.back_w; + ee->engine.x.pixmap.front_h = ee->engine.x.pixmap.back_h; + ee->engine.x.pixmap.back_w = prev_w; + ee->engine.x.pixmap.back_h = prev_h; + + /* update evas drawable */ + if (!strcmp(ee->driver, "software_x11")) + { +# ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 + Evas_Engine_Info_Software_X11 *einfo; + + einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.drawable = ee->engine.x.pixmap.back; + + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() init engine '%s' failed.", + ee->driver); + } + } +# endif + } + else if (!strcmp(ee->driver, "opengl_x11")) + { +# ifdef BUILD_ECORE_EVAS_OPENGL_X11 + Evas_Engine_Info_GL_X11 *einfo; + + einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.offscreen = 1 - einfo->info.offscreen; + + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() init engine '%s' failed.", + ee->driver); + } + } +# endif + } + } + if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) && - (!ee->gl_sync_draw_done)) // added by gl77.lee + (ee->gl_sync_draw_done != 1) && + (!ee->disable_sync_draw_done)) // TIZEN ONLY { if (ee->engine.x.sync_counter) { @@ -3150,6 +3977,20 @@ _ecore_evas_x_flush_post(void *data, Evas *e __UNUSED__, void *event_info __UNUS ee->engine.x.netwm_sync_val_lo); ee->engine.x.netwm_sync_set = 0; } + if ((ee->prop.wm_rot.supported) && + (ee->engine.x.wm_rot.done)) + { + if (!ee->prop.wm_rot.manual_mode.set) + { + ecore_x_e_window_rotation_change_done_send(ee->engine.x.win_root, + ee->prop.window, + ee->rotation, + ee->w, + ee->h); + ee->engine.x.wm_rot.done = 0; + INF("SEND ROTATION CHANGE DONE win:0x%08x", ee->prop.window); + } + } } #endif @@ -3325,12 +4166,20 @@ ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent, ecore_evas_free(ee); return NULL; } + + /* TIZEN ONLY check disable sync draw done */ + if (einfo->disable_sync_draw_done) + ee->disable_sync_draw_done = EINA_TRUE; + + INF("[ECORE_EVAS_X] disable_sync_draw_done is set to %d (SW)", ee->disable_sync_draw_done); } _ecore_evas_x_hints_update(ee); _ecore_evas_x_group_leader_set(ee); ecore_x_window_defaults_set(ee->prop.window); _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_wm_rotation_protocol_set(ee); + _ecore_evas_x_aux_hints_supprted_update(ee); _ecore_evas_x_sync_set(ee); ee->engine.func->fn_render = _ecore_evas_x_render; @@ -3376,6 +4225,31 @@ ecore_evas_software_x11_window_get(const Ecore_Evas *ee __UNUSED__) #endif /** + * @brief Returns the underlying Ecore_X_Pixmap used in the Ecore_Evas + * + * @param ee The Ecore_Evas whose pixmap is desired. + * @return The underlying Ecore_X_Pixmap + * + * @warning Support for this depends on the underlying windowing system. + * + * @since 1.8 + */ +#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 +EAPI Ecore_X_Pixmap +ecore_evas_software_x11_pixmap_get(const Ecore_Evas *ee) +{ + if (!(!strcmp(ee->driver, "software_x11"))) return 0; + return (Ecore_X_Pixmap) ee->engine.x.pixmap.front; +} +#else +EAPI Ecore_X_Pixmap +ecore_evas_software_x11_pixmap_get(const Ecore_Evas *ee) +{ + return 0; +} +#endif + + /** * @brief Set the direct_resize of Ecore_Evas using software x11. * @note If ecore is not compiled with support to x11 then nothing is done. * @param ee The Ecore_Evas in which to set direct resize. @@ -3465,33 +4339,28 @@ ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_ #endif /** - * @brief Create Ecore_Evas using opengl x11. - * @note If ecore is not compiled with support to x11 then nothing is done and NULL is returned. - * @param disp_name The name of the display of the Ecore_Evas to be created. - * @param parent The parent of the Ecore_Evas to be created. - * @param x The X coordinate to be used. - * @param y The Y coordinate to be used. - * @param w The width of the Ecore_Evas to be created. - * @param h The height of the Ecore_Evas to be created. - * @return The new Ecore_Evas. + * @brief Create a new Ecore_Evas which does not contain an XWindow. It will + * only contain an XPixmap to render to + * + * @since 1.8 */ -#ifdef BUILD_ECORE_EVAS_OPENGL_X11 +#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 EAPI Ecore_Evas * -ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent, - int x, int y, int w, int h) +ecore_evas_software_x11_pixmap_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h) { - return ecore_evas_gl_x11_options_new(disp_name, parent, x, y, w, h, NULL); + return ecore_evas_software_x11_pixmap_new_internal(disp_name, parent, x, y, w, h); } EAPI Ecore_Evas * -ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent, - int x, int y, int w, int h, const int *opt) +ecore_evas_software_x11_pixmap_new_internal(const char *disp_name, Ecore_X_Window parent, + int x, int y, int w, int h) { + Evas_Engine_Info_Software_X11 *einfo; Ecore_Evas *ee; - int rmethod; - char *id = NULL; + int argb = 0, rmethod; + static int redraw_debug = -1; - rmethod = evas_render_method_lookup("gl_x11"); + rmethod = evas_render_method_lookup("software_x11"); if (!rmethod) return NULL; if (!ecore_x_init(disp_name)) return NULL; ee = calloc(1, sizeof(Ecore_Evas)); @@ -3499,20 +4368,11 @@ ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent, ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); - ee->gl_sync_draw_done = -1; // added by gl77.lee - _ecore_evas_x_init(); ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func; - ee->driver = "opengl_x11"; -#if 1 - ee->semi_sync = 0; // gl engine doesn't need to sync - its whole swaps -#else - if (!getenv("ECORE_EVAS_COMP_NOSEMISYNC")) - ee->semi_sync = 1; // gl engine doesn't need to sync - its whole swaps -// ee->no_comp_sync = 1; // gl engine doesn't need to sync - its whole swaps -#endif + ee->driver = "software_x11"; if (disp_name) ee->name = strdup(disp_name); if (w < 1) w = 1; @@ -3529,40 +4389,266 @@ ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent, ee->prop.max.w = 32767; ee->prop.max.h = 32767; ee->prop.layer = 4; - ee->prop.request_pos = 0; + ee->prop.request_pos = EINA_FALSE; ee->prop.sticky = 0; ee->engine.x.state.sticky = 0; /* init evas here */ ee->evas = evas_new(); - evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee); - evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee); + + evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, + _ecore_evas_x_flush_pre, ee); + evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, + _ecore_evas_x_flush_post, ee); + evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_PRE, + _ecore_evas_x_render_pre, ee); + evas_data_attach_set(ee->evas, ee); evas_output_method_set(ee->evas, rmethod); evas_output_size_set(ee->evas, w, h); evas_output_viewport_set(ee->evas, 0, 0, w, h); - if (parent == 0) parent = DefaultRootWindow(ecore_x_display_get()); ee->engine.x.win_root = parent; + ee->engine.x.screen_num = 0; + ee->engine.x.direct_resize = 1; - if (ee->engine.x.win_root != 0) + if (parent != 0) { ee->engine.x.screen_num = 1; /* FIXME: get real scren # */ /* FIXME: round trip in ecore_x_window_argb_get */ - if (ecore_x_window_argb_get(ee->engine.x.win_root)) - { - ee->prop.window = _ecore_evas_x_gl_window_new - (ee, ee->engine.x.win_root, x, y, w, h, 0, 1, opt); - } - else - ee->prop.window = _ecore_evas_x_gl_window_new - (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt); + if (ecore_x_window_argb_get(parent)) + argb = 1; } - else - ee->prop.window = _ecore_evas_x_gl_window_new - (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt); - if (!ee->prop.window) - { + + /* if ((id = getenv("DESKTOP_STARTUP_ID"))) */ + /* { */ + /* ecore_x_netwm_startup_id_set(ee->prop.window, id); */ + /* NB: on linux this may simply empty the env as opposed to completely + * unset it to being empty - unsure as solartis libc crashes looking + * for the '=' char */ +// putenv((char*)"DESKTOP_STARTUP_ID="); + /* } */ + + einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + Ecore_X_Screen *screen; + + /* FIXME: this is inefficient as its 1 or more round trips */ + screen = ecore_x_default_screen_get(); + if (ecore_x_screen_count_get() > 1) + { + Ecore_X_Window *roots; + int num, i; + + num = 0; + roots = ecore_x_window_root_list(&num); + if (roots) + { + Ecore_X_Window root; + + root = ecore_x_window_root_get(parent); + for (i = 0; i < num; i++) + { + if (root == roots[i]) + { + screen = ecore_x_screen_get(i); + break; + } + } + free(roots); + } + } + + einfo->info.destination_alpha = argb; + + if (redraw_debug < 0) + { + if (getenv("REDRAW_DEBUG")) + redraw_debug = atoi(getenv("REDRAW_DEBUG")); + else + redraw_debug = 0; + } + +# ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB + einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB; + einfo->info.connection = ecore_x_connection_get(); + einfo->info.screen = screen; +# else + einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB; + einfo->info.connection = ecore_x_display_get(); + einfo->info.screen = NULL; +# endif + + if ((argb) && (ee->prop.window)) + { + Ecore_X_Window_Attributes at; + + ecore_x_window_attributes_get(ee->prop.window, &at); + einfo->info.visual = at.visual; + einfo->info.colormap = at.colormap; + einfo->info.depth = at.depth; + einfo->info.destination_alpha = 1; + } + else + { + einfo->info.visual = + ecore_x_default_visual_get(einfo->info.connection, screen); + einfo->info.colormap = + ecore_x_default_colormap_get(einfo->info.connection, screen); + einfo->info.depth = + ecore_x_default_depth_get(einfo->info.connection, screen); + einfo->info.destination_alpha = 0; + } + + einfo->info.rotation = 0; + einfo->info.debug = redraw_debug; + + ee->engine.x.pixmap.depth = 32;//einfo->info.depth; + ee->engine.x.pixmap.visual = einfo->info.visual; + ee->engine.x.pixmap.colormap = einfo->info.colormap; + + /* create front and back pixmaps for double-buffer rendering */ + ee->engine.x.pixmap.front = + ecore_x_pixmap_new(parent, w, h, ee->engine.x.pixmap.depth); + ee->engine.x.pixmap.front_w = w; + ee->engine.x.pixmap.front_h = h; + ee->engine.x.pixmap.back = + ecore_x_pixmap_new(parent, w, h, ee->engine.x.pixmap.depth); + ee->engine.x.pixmap.back_w = w; + ee->engine.x.pixmap.back_h = h; + + einfo->info.drawable = ee->engine.x.pixmap.back; + + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + WRN("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + + ee->engine.func->fn_render = _ecore_evas_x_render; + _ecore_evas_register(ee); + + ee->draw_ok = 1; + + return ee; +} +#else +EAPI Ecore_Evas * +ecore_evas_software_x11_pixmap_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h) +{ + return 0; +} + +EAPI Ecore_Evas * +ecore_evas_software_x11_pixmap_new_internal(const char *disp_name, Ecore_X_Window parent, + int x, int y, int w, int h) +{ + return 0; +} +#endif + + /** + * @brief Create Ecore_Evas using opengl x11. + * @note If ecore is not compiled with support to x11 then nothing is done and NULL is returned. + * @param disp_name The name of the display of the Ecore_Evas to be created. + * @param parent The parent of the Ecore_Evas to be created. + * @param x The X coordinate to be used. + * @param y The Y coordinate to be used. + * @param w The width of the Ecore_Evas to be created. + * @param h The height of the Ecore_Evas to be created. + * @return The new Ecore_Evas. + */ +#ifdef BUILD_ECORE_EVAS_OPENGL_X11 +EAPI Ecore_Evas * +ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent, + int x, int y, int w, int h) +{ + return ecore_evas_gl_x11_options_new(disp_name, parent, x, y, w, h, NULL); +} + +EAPI Ecore_Evas * +ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent, + int x, int y, int w, int h, const int *opt) +{ + Ecore_Evas *ee; + int rmethod; + char *id = NULL; + + rmethod = evas_render_method_lookup("gl_x11"); + if (!rmethod) return NULL; + if (!ecore_x_init(disp_name)) return NULL; + ee = calloc(1, sizeof(Ecore_Evas)); + if (!ee) return NULL; + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + ee->gl_sync_draw_done = -1; + + _ecore_evas_x_init(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func; + + ee->driver = "opengl_x11"; +#if 1 + ee->semi_sync = 0; // gl engine doesn't need to sync - its whole swaps +#else + if (!getenv("ECORE_EVAS_COMP_NOSEMISYNC")) + ee->semi_sync = 1; // gl engine doesn't need to sync - its whole swaps +// ee->no_comp_sync = 1; // gl engine doesn't need to sync - its whole swaps +#endif + if (disp_name) ee->name = strdup(disp_name); + + if (w < 1) w = 1; + if (h < 1) h = 1; + ee->x = x; + ee->y = y; + ee->w = w; + ee->h = h; + ee->req.x = ee->x; + ee->req.y = ee->y; + ee->req.w = ee->w; + ee->req.h = ee->h; + + ee->prop.max.w = 32767; + ee->prop.max.h = 32767; + ee->prop.layer = 4; + ee->prop.request_pos = 0; + ee->prop.sticky = 0; + ee->engine.x.state.sticky = 0; + + /* init evas here */ + ee->evas = evas_new(); + evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee); + evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee); + evas_data_attach_set(ee->evas, ee); + evas_output_method_set(ee->evas, rmethod); + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + + if (parent == 0) parent = DefaultRootWindow(ecore_x_display_get()); + ee->engine.x.win_root = parent; + + if (ee->engine.x.win_root != 0) + { + ee->engine.x.screen_num = 1; /* FIXME: get real scren # */ + /* FIXME: round trip in ecore_x_window_argb_get */ + if (ecore_x_window_argb_get(ee->engine.x.win_root)) + { + ee->prop.window = _ecore_evas_x_gl_window_new + (ee, ee->engine.x.win_root, x, y, w, h, 0, 1, opt); + } + else + ee->prop.window = _ecore_evas_x_gl_window_new + (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt); + } + else + ee->prop.window = _ecore_evas_x_gl_window_new + (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt); + if (!ee->prop.window) + { ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); ecore_evas_free(ee); return NULL; @@ -3580,6 +4666,8 @@ ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent, _ecore_evas_x_group_leader_set(ee); ecore_x_window_defaults_set(ee->prop.window); _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_wm_rotation_protocol_set(ee); + _ecore_evas_x_aux_hints_supprted_update(ee); _ecore_evas_x_sync_set(ee); ee->engine.func->fn_render = _ecore_evas_x_render; @@ -3609,6 +4697,189 @@ ecore_evas_gl_x11_options_new(const char *disp_name __UNUSED__, Ecore_X_Window p #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ /** + * @brief Create a new Ecore_Evas which does not contain an XWindow. It will + * only contain an XPixmap to render to + * + * @since 1.8 + */ +#ifdef BUILD_ECORE_EVAS_OPENGL_X11 +EAPI Ecore_Evas * +ecore_evas_gl_x11_pixmap_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h) +{ + return ecore_evas_gl_x11_pixmap_new_internal(disp_name, parent, x, y, w, h); +} + +EAPI Ecore_Evas * +ecore_evas_gl_x11_pixmap_new_internal(const char *disp_name, Ecore_X_Window parent, + int x, int y, int w, int h) +{ + Ecore_Evas *ee; + Evas_Engine_Info_GL_X11 *einfo; + int rmethod, argb = 0; + static int redraw_debug = -1; + + rmethod = evas_render_method_lookup("gl_x11"); + if (!rmethod) return NULL; + if (!ecore_x_init(disp_name)) return NULL; + ee = calloc(1, sizeof(Ecore_Evas)); + if (!ee) return NULL; + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + ee->gl_sync_draw_done = -1; + + _ecore_evas_x_init(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func; + + ee->driver = "opengl_x11"; + ee->no_comp_sync = 1;; // gl engine doesn't need to sync - its whole swaps + + if (disp_name) ee->name = strdup(disp_name); + + if (w < 1) w = 1; + if (h < 1) h = 1; + ee->x = x; + ee->y = y; + ee->w = w; + ee->h = h; + ee->req.x = ee->x; + ee->req.y = ee->y; + ee->req.w = ee->w; + ee->req.h = ee->h; + + ee->prop.max.w = 32767; + ee->prop.max.h = 32767; + ee->prop.layer = 4; + ee->prop.request_pos = EINA_FALSE; + ee->prop.sticky = 0; + ee->engine.x.state.sticky = 0; + + /* init evas here */ + ee->evas = evas_new(); + evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, + _ecore_evas_x_flush_pre, ee); + evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, + _ecore_evas_x_flush_post, ee); + evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_PRE, + _ecore_evas_x_render_pre, ee); + evas_data_attach_set(ee->evas, ee); + evas_output_method_set(ee->evas, rmethod); + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + + if (parent == 0) parent = ecore_x_window_root_first_get(); + ee->engine.x.win_root = parent; + + if (parent != 0) + { + ee->engine.x.screen_num = 1; /* FIXME: get real scren # */ + /* FIXME: round trip in ecore_x_window_argb_get */ + if (ecore_x_window_argb_get(parent)) + argb = 1; + } + + ee->engine.x.direct_resize = 1; + + einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + int screen = 0; + + /* FIXME: this is inefficient as its 1 or more round trips */ + screen = ecore_x_screen_index_get(ecore_x_default_screen_get()); + if (ecore_x_screen_count_get() > 1) + { + Ecore_X_Window *roots; + int num, i; + + num = 0; + roots = ecore_x_window_root_list(&num); + if (roots) + { + Ecore_X_Window root; + + root = ecore_x_window_root_get(parent); + for (i = 0; i < num; i++) + { + if (root == roots[i]) + { + screen = i; + break; + } + } + free(roots); + } + } + + einfo->info.display = ecore_x_display_get(); + einfo->info.screen = screen; + + einfo->info.destination_alpha = argb; + + einfo->info.visual = einfo->func.best_visual_get(einfo); + einfo->info.colormap = einfo->func.best_colormap_get(einfo); + einfo->info.depth = einfo->func.best_depth_get(einfo); + + einfo->info.offscreen = 1; + einfo->swap_mode = EVAS_ENGINE_GL_X11_SWAP_MODE_DOUBLE; + + if (redraw_debug < 0) + { + if (getenv("REDRAW_DEBUG")) + redraw_debug = atoi(getenv("REDRAW_DEBUG")); + else + redraw_debug = 0; + } + + einfo->info.rotation = 0; + + ee->engine.x.pixmap.depth = 32;//einfo->info.depth; + ee->engine.x.pixmap.visual = einfo->info.visual; + ee->engine.x.pixmap.colormap = einfo->info.colormap; + + /* create front and back pixmaps for double-buffer rendering */ + ee->engine.x.pixmap.front = + ecore_x_pixmap_new(parent, w, h, ee->engine.x.pixmap.depth); + ee->engine.x.pixmap.front_w = w; + ee->engine.x.pixmap.front_h = h; + ee->engine.x.pixmap.back = + ecore_x_pixmap_new(parent, w, h, ee->engine.x.pixmap.depth); + ee->engine.x.pixmap.back_w = w; + ee->engine.x.pixmap.back_h = h; + + einfo->info.drawable = ee->engine.x.pixmap.back; + einfo->info.drawable_back = ee->engine.x.pixmap.front; + + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + WRN("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + + ee->engine.func->fn_render = _ecore_evas_x_render; + _ecore_evas_register(ee); + + return ee; +} +#else +EAPI Ecore_Evas * +ecore_evas_gl_x11_pixmap_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h) +{ + return NULL; +} + +EAPI Ecore_Evas * +ecore_evas_gl_x11_pixmap_new_internal(const char *disp_name, Ecore_X_Window parent, + int x, int y, int w, int h) +{ + return NULL; +} +#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ + +/** * @brief Get the window from Ecore_Evas using opengl x11. * @note If ecore is not compiled with support for x11 or if @p ee was not * created with ecore_evas_gl_x11_new() then nothing is done and @@ -3632,6 +4903,30 @@ ecore_evas_gl_x11_window_get(const Ecore_Evas *ee __UNUSED__) #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ /** + * @brief Returns the underlying Ecore_X_Pixmap used in the Ecore_Evas + * + * @param ee The Ecore_Evas whose pixmap is desired. + * @return The underlying Ecore_X_Pixmap + * + * @warning Support for this depends on the underlying windowing system. + * + * @since 1.8 + */ +#ifdef BUILD_ECORE_EVAS_OPENGL_X11 +EAPI Ecore_X_Pixmap +ecore_evas_gl_x11_pixmap_get(const Ecore_Evas *ee) +{ + if (!(!strcmp(ee->driver, "opengl_x11"))) return 0; + return (Ecore_X_Pixmap) ee->engine.x.pixmap.front; +} +#else +EAPI Ecore_X_Pixmap +ecore_evas_gl_x11_pixmap_get(const Ecore_Evas *ee) +{ + return NULL; +} +#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ +/** * @brief Set direct_resize for Ecore_Evas using opengl x11. * @note If ecore is not compiled with support to x11 then nothing is done. * @param ee The Ecore_Evas in which to set direct resize. @@ -3895,6 +5190,8 @@ ecore_evas_software_x11_16_new(const char *disp_name, Ecore_X_Window parent, _ecore_evas_x_group_leader_set(ee); ecore_x_window_defaults_set(ee->prop.window); _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_wm_rotation_protocol_set(ee); + _ecore_evas_x_aux_hints_supprted_update(ee); _ecore_evas_x_sync_set(ee); ee->engine.func->fn_render = _ecore_evas_x_render; @@ -4225,6 +5522,8 @@ ecore_evas_software_x11_8_new(const char *disp_name, Ecore_X_Window parent, _ecore_evas_x_group_leader_set(ee); ecore_x_window_defaults_set(ee->prop.window); _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_wm_rotation_protocol_set(ee); + _ecore_evas_x_aux_hints_supprted_update(ee); _ecore_evas_x_sync_set(ee); ee->engine.func->fn_render = _ecore_evas_x_render; @@ -4452,6 +5751,71 @@ _ecore_evas_x11_convert_rectangle_with_angle(Ecore_Evas *ee, Ecore_X_Rectangle * } #endif +#if defined (BUILD_ECORE_EVAS_SOFTWARE_X11) || defined (BUILD_ECORE_EVAS_OPENGL_X11) +EAPI void * +ecore_evas_pixmap_visual_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_pixmap_visual_get"); + return NULL; + } + + if ((!strcmp(ee->driver, "software_x11")) ||(!strcmp(ee->driver, "opengl_x11")) ) + return (Ecore_X_Pixmap) ee->engine.x.pixmap.visual; + + return NULL; +} + +EAPI unsigned long +ecore_evas_pixmap_colormap_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_pixmap_colormap_get"); + return 0; + } + + if ((!strcmp(ee->driver, "software_x11")) ||(!strcmp(ee->driver, "opengl_x11")) ) + return (Ecore_X_Pixmap) ee->engine.x.pixmap.colormap; + + return 0; +} + +EAPI int +ecore_evas_pixmap_depth_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_pixmap_depth_get"); + return 0; + } + + if ((!strcmp(ee->driver, "software_x11")) ||(!strcmp(ee->driver, "opengl_x11")) ) + return (Ecore_X_Pixmap) ee->engine.x.pixmap.depth; + + return 0; +} +#else +EAPI void * +ecore_evas_pixmap_visual_get(const Ecore_Evas *ee) +{ + return NULL; +} + +EAPI unsigned long +ecore_evas_pixmap_colormap_get(const Ecore_Evas *ee) +{ + return 0; +} + +EAPI int +ecore_evas_pixmap_depth_get(const Ecore_Evas *ee) +{ + return 0; +} +#endif + EAPI void ecore_evas_x11_shape_input_rectangle_set(Ecore_Evas *ee, int x, int y, int w, int h) { diff --git a/src/lib/ecore_fb/Ecore_Fb.h b/src/lib/ecore_fb/Ecore_Fb.h index 069cccd..fc73df4 100644 --- a/src/lib/ecore_fb/Ecore_Fb.h +++ b/src/lib/ecore_fb/Ecore_Fb.h @@ -18,15 +18,14 @@ #endif /* FIXME: - * maybe a new module? - * - code to get battery info - * - code to get thermal info + * Maybe a new module? + * - Code to get the battery info + * - Code to get the thermal info * ecore evas fb isn't good enough for weird things, like multiple fb's, same happens here. * backlight support using new kernel interface * absolute axis * joystick * ecore_fb_li_device_close_all ? or a shutdown of the subsystem? - * */ #ifdef __cplusplus @@ -34,22 +33,24 @@ extern "C" { #endif /** + * @internal * @defgroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions. + * @ingroup Ecore_Group * - * Functions used to set up and shut down the Ecore_Framebuffer functions. + * @brief This group discusses the functions used to set up and shut down the Ecore_Framebuffer functions. * * @{ */ /** * @typedef Ecore_Fb_Input_Device - * Input device handler. + * @brief The structure type containing the Input device handler. */ typedef struct _Ecore_Fb_Input_Device Ecore_Fb_Input_Device; /** * @enum _Ecore_Fb_Input_Device_Cap - * Device capabilities. + * @brief Enumeration that defines the device capabilities. */ enum _Ecore_Fb_Input_Device_Cap { @@ -61,7 +62,7 @@ enum _Ecore_Fb_Input_Device_Cap /** * @typedef Ecore_Fb_Input_Device_Cap - * Device capabilities. + * @brief Enumeration that defines the device capabilities. */ typedef enum _Ecore_Fb_Input_Device_Cap Ecore_Fb_Input_Device_Cap; diff --git a/src/lib/ecore_fb/ecore_fb_li.c b/src/lib/ecore_fb/ecore_fb_li.c index 23599c9..78a3e5b 100644 --- a/src/lib/ecore_fb/ecore_fb_li.c +++ b/src/lib/ecore_fb/ecore_fb_li.c @@ -369,6 +369,7 @@ _ecore_fb_li_device_event_syn(Ecore_Fb_Input_Device *dev, struct input_event *ie ev->root.x = ev->x; ev->root.y = ev->y; ev->timestamp = ecore_loop_time_get() * 1000.0; + ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); } else if (dev->mouse.event == ECORE_EVENT_MOUSE_BUTTON_DOWN) { diff --git a/src/lib/ecore_fb/ecore_fb_vt.c b/src/lib/ecore_fb/ecore_fb_vt.c index 09e3f37..0e05893 100644 --- a/src/lib/ecore_fb/ecore_fb_vt.c +++ b/src/lib/ecore_fb/ecore_fb_vt.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "Ecore_Fb.h" #include "ecore_fb_private.h" diff --git a/src/lib/ecore_file/Ecore_File.h b/src/lib/ecore_file/Ecore_File.h index 30f3bd7..35276de 100644 --- a/src/lib/ecore_file/Ecore_File.h +++ b/src/lib/ecore_file/Ecore_File.h @@ -35,6 +35,7 @@ #endif /* ! _WIN32 */ /** + * @internal * @file Ecore_File.h * @brief Files utility functions */ @@ -44,65 +45,67 @@ extern "C" { #endif /** + * @internal * @defgroup Ecore_File_Group Ecore_File - Files and directories convenience functions + * @ingroup Ecore_Group * * @{ */ /** * @typedef Ecore_File_Monitor - * Abstract type used when monitoring a directory. + * @brief The structure type containing the abstract type used to monitor a directory. */ typedef struct _Ecore_File_Monitor Ecore_File_Monitor; /** * @typedef Ecore_File_Download_Job - * Abstract type used when aborting a download. + * @brief The structure type containing the abstract type used to abort a download. */ typedef struct _Ecore_File_Download_Job Ecore_File_Download_Job; /** * @typedef _Ecore_File_Event - * The event type returned when a file or directory is monitored. + * @brief The structure type containing the event type returned when a file or directory is monitored. */ typedef enum _Ecore_File_Event { - ECORE_FILE_EVENT_NONE, /**< No event. */ - ECORE_FILE_EVENT_CREATED_FILE, /**< Created file event. */ - ECORE_FILE_EVENT_CREATED_DIRECTORY, /**< Created directory event. */ - ECORE_FILE_EVENT_DELETED_FILE, /**< Deleted file event. */ - ECORE_FILE_EVENT_DELETED_DIRECTORY, /**< Deleted directory event. */ - ECORE_FILE_EVENT_DELETED_SELF, /**< Deleted monitored directory event. */ - ECORE_FILE_EVENT_MODIFIED, /**< Modified file or directory event. */ + ECORE_FILE_EVENT_NONE, /**< No event */ + ECORE_FILE_EVENT_CREATED_FILE, /**< Created file event */ + ECORE_FILE_EVENT_CREATED_DIRECTORY, /**< Created directory event */ + ECORE_FILE_EVENT_DELETED_FILE, /**< Deleted file event */ + ECORE_FILE_EVENT_DELETED_DIRECTORY, /**< Deleted directory event */ + ECORE_FILE_EVENT_DELETED_SELF, /**< Deleted monitored directory event */ + ECORE_FILE_EVENT_MODIFIED, /**< Modified file or directory event */ ECORE_FILE_EVENT_CLOSED /**< Closed file event */ } Ecore_File_Event; /** * @typedef Ecore_File_Monitor_Cb - * Callback type used when a monitored directory has changes. + * @brief Called to be used when a monitored directory has changed. */ typedef void (*Ecore_File_Monitor_Cb)(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path); /** * @typedef Ecore_File_Download_Completion_Cb - * Callback type used when a download is finished. + * @brief Called to be used when a download has finished. */ typedef void (*Ecore_File_Download_Completion_Cb)(void *data, const char *file, int status); /** * @typedef _Ecore_File_Progress_Return - * What to do with the download as a return from the - * Ecore_File_Download_Progress_Cb function, if provided. + * @brief Enumeration on what to do with the download as a return from the + * Ecore_File_Download_Progress_Cb function, if provided. */ typedef enum _Ecore_File_Progress_Return { - ECORE_FILE_PROGRESS_CONTINUE = 0, /**< Continue the download. */ - ECORE_FILE_PROGRESS_ABORT = 1 /**< Abort the download. */ + ECORE_FILE_PROGRESS_CONTINUE = 0, /**< Continue the download */ + ECORE_FILE_PROGRESS_ABORT = 1 /**< Abort the download */ } Ecore_File_Progress_Return; /** * @typedef Ecore_File_Download_Progress_Cb - * Callback type used while a download is in progress. + * @brief Called to be used while a download is in progress. */ typedef int (*Ecore_File_Download_Progress_Cb)(void *data, const char *file, diff --git a/src/lib/ecore_file/ecore_file.c b/src/lib/ecore_file/ecore_file.c index fd06f7d..bcda0a0 100644 --- a/src/lib/ecore_file/ecore_file.c +++ b/src/lib/ecore_file/ecore_file.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include #include @@ -404,7 +430,7 @@ ecore_file_recursive_rm(const char *dir) struct stat st; int ret; - if (readlink(dir, buf, sizeof(buf)) > 0) + if (readlink(dir, buf, sizeof(buf) - 1) > 0) return ecore_file_unlink(dir); ret = stat(dir, &st); @@ -884,7 +910,11 @@ restart: p++; } exe2 = p; - if (exe2 == exe1) return NULL; + if (exe2 == exe1) + { + if (exe) free(exe); + return NULL; + } if (*exe1 == '~') { char *homedir; @@ -1011,25 +1041,49 @@ ecore_file_escape_name(const char *filename) char *q; char buf[PATH_MAX]; + EINA_SAFETY_ON_NULL_RETURN_VAL(filename, NULL); + p = filename; q = buf; while (*p) { if ((q - buf) > (PATH_MAX - 6)) return NULL; if ( - (*p == ' ') || (*p == '\t') || (*p == '\n') || - (*p == '\\') || (*p == '\'') || (*p == '\"') || - (*p == ';') || (*p == '!') || (*p == '#') || - (*p == '$') || (*p == '%') || (*p == '&') || - (*p == '*') || (*p == '(') || (*p == ')') || - (*p == '[') || (*p == ']') || (*p == '{') || - (*p == '}') || (*p == '|') || (*p == '<') || - (*p == '>') || (*p == '?') + (*p == ' ') || (*p == '\\') || (*p == '\'') || + (*p == '\"') || (*p == ';') || (*p == '!') || + (*p == '#') || (*p == '$') || (*p == '%') || + (*p == '&') || (*p == '*') || (*p == '(') || + (*p == ')') || (*p == '[') || (*p == ']') || + (*p == '{') || (*p == '}') || (*p == '|') || + (*p == '<') || (*p == '>') || (*p == '?') ) { *q = '\\'; q++; } + else if (*p == '\t') + { + *q = '\\'; + q++; + *q = '\\'; + q++; + *q = 't'; + q++; + p++; + continue; + } + else if (*p == '\n') + { + *q = '\\'; + q++; + *q = '\\'; + q++; + *q = 'n'; + q++; + p++; + continue; + } + *q = *p; q++; p++; diff --git a/src/lib/ecore_file/ecore_file_download.c b/src/lib/ecore_file/ecore_file_download.c index ea8550d..03e593b 100644 --- a/src/lib/ecore_file/ecore_file_download.c +++ b/src/lib/ecore_file/ecore_file_download.c @@ -110,6 +110,12 @@ _ecore_file_download(const char *url, Eina_Hash *headers) { #ifdef BUILD_ECORE_CON + if (!url) + { + CRIT("Download URL is null"); + return EINA_FALSE; + } + char *dir = ecore_file_dir_get(dst); if (!ecore_file_is_dir(dir)) diff --git a/src/lib/ecore_file/ecore_file_monitor.c b/src/lib/ecore_file/ecore_file_monitor.c index 8b07589..e7c1d1d 100644 --- a/src/lib/ecore_file/ecore_file_monitor.c +++ b/src/lib/ecore_file/ecore_file_monitor.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "ecore_file_private.h" typedef enum { diff --git a/src/lib/ecore_file/ecore_file_monitor_inotify.c b/src/lib/ecore_file/ecore_file_monitor_inotify.c index 30226d3..5f7abd8 100644 --- a/src/lib/ecore_file/ecore_file_monitor_inotify.c +++ b/src/lib/ecore_file/ecore_file_monitor_inotify.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "ecore_file_private.h" @@ -62,11 +63,20 @@ int ecore_file_monitor_inotify_init(void) { int fd; +#ifdef HAVE_EXECVP + int flags; +#endif fd = inotify_init(); if (fd < 0) return 0; +#ifdef HAVE_EXECVP + flags = fcntl(fd, F_GETFD); + flags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, flags); +#endif + _fdh = ecore_main_fd_handler_add(fd, ECORE_FD_READ, _ecore_file_monitor_inotify_handler, NULL, NULL, NULL); if (!_fdh) @@ -205,7 +215,11 @@ _ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask) if ((file) && (file[0])) snprintf(buf, sizeof(buf), "%s/%s", em->path, file); else - strcpy(buf, em->path); + { + strncpy(buf, em->path, sizeof(buf)); + buf[PATH_MAX - 1] = 0; + } + isdir = mask & IN_ISDIR; #if 0 diff --git a/src/lib/ecore_file/ecore_file_path.c b/src/lib/ecore_file/ecore_file_path.c index 3c06e9b..c1c54b7 100644 --- a/src/lib/ecore_file/ecore_file_path.c +++ b/src/lib/ecore_file/ecore_file_path.c @@ -2,22 +2,30 @@ # include #endif -#undef alloca +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif #ifdef HAVE_ALLOCA_H # include -#elif defined __GNUC__ -# define alloca __builtin_alloca -#elif defined _AIX -# define alloca __alloca -#elif defined _MSC_VER -# include -# define alloca _alloca -#else -# include -# ifdef __cplusplus +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus extern "C" -# endif +# endif void *alloca (size_t); +# endif #endif #include diff --git a/src/lib/ecore_imf/Ecore_IMF.h b/src/lib/ecore_imf/Ecore_IMF.h index 679aad4..b09b0b3 100644 --- a/src/lib/ecore_imf/Ecore_IMF.h +++ b/src/lib/ecore_imf/Ecore_IMF.h @@ -34,11 +34,56 @@ extern "C" { #endif /** + * @defgroup Ecore_IMF_Lib_Group Ecore_IMF - Ecore Input Method Library Functions + * @ingroup Ecore_Group + * + * Utility functions that set up and shut down the Ecore Input Method + * library. + */ + +/** + * @defgroup Ecore_IMF_Context_Group Ecore Input Method Context Functions + * @ingroup Ecore_IMF_Lib_Group + * + * Functions that operate on Ecore Input Method Context objects. + + * Ecore Input Method Context Function defines the interface for EFL input methods. + * An input method is used by EFL text input widgets like elm_entry + * (based on edje_entry) to map from key events to Unicode character strings. + * + * The default input method can be set through setting the ECORE_IMF_MODULE environment variable. + * eg) export ECORE_IMF_MODULE=xim (or scim or ibus) + * + * An input method may consume multiple key events in sequence and finally output the composed result. + * This is called preediting, and an input method may provide feedback about + * this process by displaying the intermediate composition states as preedit text. + * + * Immodule is plugin to connect your application and input method framework such as SCIM, ibus, and so on.@n + * ecore_imf_init() should be called to initialize and load immodule.@n + * ecore_imf_shutdown() is used for shutdowning and unloading immodule. + * + * An example of usage of these functions can be found at: + * @li @ref ecore_imf_example_c + */ + +/** * @addtogroup Ecore_IMF_Context_Group * * @{ */ + +/** + * @example ecore_imf_example.c + * Show how to write simple editor using the Ecore_IMF library + */ + /* ecore_imf_context_input_panel_event_callback_add() flag */ + +/** + * @typedef Ecore_IMF_Input_Panel_Event + * Enum containing input panel events. + * @since_tizen 2.3.1 + */ typedef enum { ECORE_IMF_INPUT_PANEL_STATE_EVENT, /**< called when the state of the input panel is changed. @since 1.7 */ @@ -49,6 +94,11 @@ typedef enum ECORE_IMF_CANDIDATE_PANEL_GEOMETRY_EVENT /**< called when the size of the candidate word panel is changed. @since 1.7 */ } Ecore_IMF_Input_Panel_Event; +/** + * @typedef Ecore_IMF_Input_Panel_State + * Enum containing input panel state notifications. + * @since_tizen 2.3.1 + */ typedef enum { ECORE_IMF_INPUT_PANEL_STATE_SHOW, /**< Notification after the display of the input panel @since 1.7 */ @@ -56,12 +106,22 @@ typedef enum ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW /**< Notification prior to the display of the input panel @since 1.7 */ } Ecore_IMF_Input_Panel_State; +/** + * @typedef Ecore_IMF_Input_Panel_Shift_Mode + * Enum containing input shift mode states. + * @since_tizen 2.3.1 + */ typedef enum { ECORE_IMF_INPUT_PANEL_SHIFT_MODE_OFF, /**< @since 1.7 */ ECORE_IMF_INPUT_PANEL_SHIFT_MODE_ON /**< @since 1.7 */ } Ecore_IMF_Input_Panel_Shift_Mode; +/** + * @typedef Ecore_IMF_Candidate_Panel_State + * Enum containing candidate word panel state notifications. + * @since_tizen 2.3.1 + */ typedef enum { ECORE_IMF_CANDIDATE_PANEL_SHOW, /**< Notification after the display of the candidate word panel @since 1.7 */ @@ -74,6 +134,7 @@ typedef struct _Ecore_IMF_Event_Preedit_End Ecore_IMF_Event_Preedit_End; typedef struct _Ecore_IMF_Event_Preedit_Changed Ecore_IMF_Event_Preedit_Changed; typedef struct _Ecore_IMF_Event_Commit Ecore_IMF_Event_Commit; typedef struct _Ecore_IMF_Event_Delete_Surrounding Ecore_IMF_Event_Delete_Surrounding; +typedef struct _Ecore_IMF_Event_Selection Ecore_IMF_Event_Selection; /* Events to filter */ typedef struct _Ecore_IMF_Event_Mouse_Down Ecore_IMF_Event_Mouse_Down; @@ -99,6 +160,13 @@ EAPI extern int ECORE_IMF_EVENT_PREEDIT_CHANGED; EAPI extern int ECORE_IMF_EVENT_COMMIT; EAPI extern int ECORE_IMF_EVENT_DELETE_SURROUNDING; +/** + * @typedef Ecore_IMF_Event_Cb + * + * @brief Called when a Ecore_IMF event happens. + * + * @see ecore_imf_context_event_callback_add() + */ typedef void (*Ecore_IMF_Event_Cb) (void *data, Ecore_IMF_Context *ctx, void *event_info); /** @@ -106,6 +174,8 @@ typedef void (*Ecore_IMF_Event_Cb) (void *data, Ecore_IMF_Context *ctx, void *ev * * Ecore IMF Event callback types. * + * @since_tizen 2.3.1 + * * @see ecore_imf_context_event_callback_add() */ typedef enum @@ -114,7 +184,9 @@ typedef enum ECORE_IMF_CALLBACK_PREEDIT_END, /**< "PREEDIT_END" is called when a preediting sequence has been completed or canceled. @since 1.2 */ ECORE_IMF_CALLBACK_PREEDIT_CHANGED, /**< "PREEDIT_CHANGED" is called whenever the preedit sequence currently being entered has changed. @since 1.2 */ ECORE_IMF_CALLBACK_COMMIT, /**< "COMMIT" is called when a complete input sequence has been entered by the user @since 1.2 */ - ECORE_IMF_CALLBACK_DELETE_SURROUNDING /**< "DELETE_SURROUNDING" is called when the input method needs to delete all or part of the context surrounding the cursor @since 1.2 */ + ECORE_IMF_CALLBACK_DELETE_SURROUNDING, /**< "DELETE_SURROUNDING" is called when the input method needs to delete all or part of the context surrounding the cursor @since 1.2 */ + ECORE_IMF_CALLBACK_SELECTION_SET, /**< "SELECTION_SET" is called when the input method needs to set the selection @since 1.9 */ + ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND /**< "PRIVATE_COMMAND_SEND" is called when the input method sends a private command @since 1.12 */ } Ecore_IMF_Callback_Type; /** @@ -122,6 +194,8 @@ typedef enum * * Ecore IMF event types. * + * @since_tizen 2.3.1 + * * @see ecore_imf_context_filter_event() */ typedef enum @@ -138,6 +212,7 @@ typedef enum /** * @typedef Ecore_IMF_Keyboard_Modifiers * Type for Ecore_IMF keyboard modifiers + * @since_tizen 2.3.1 */ typedef enum { @@ -152,6 +227,7 @@ typedef enum /** * @typedef Ecore_IMF_Keyboard_Locks * Type for Ecore_IMF keyboard locks + * @since_tizen 2.3.1 */ typedef enum { @@ -164,6 +240,7 @@ typedef enum /** * @typedef Ecore_IMF_Mouse_Flags * Type for Ecore_IMF mouse flags + * @since_tizen 2.3.1 */ typedef enum { @@ -172,6 +249,11 @@ typedef enum ECORE_IMF_MOUSE_TRIPLE_CLICK = 1 << 1 /**< A triple click */ } Ecore_IMF_Mouse_Flags; +/** + * @typedef Ecore_IMF_Input_Mode + * Type for Ecore_IMF input mode + * @since_tizen 2.3.1 + */ typedef enum { ECORE_IMF_INPUT_MODE_ALPHA = 1 << 0, @@ -189,6 +271,8 @@ typedef enum * * Ecore IMF Preedit style types * + * @since_tizen 2.3.1 + * * @see ecore_imf_context_preedit_string_with_attributes_get() */ typedef enum @@ -196,7 +280,11 @@ typedef enum ECORE_IMF_PREEDIT_TYPE_NONE, /**< None style @since 1.1 */ ECORE_IMF_PREEDIT_TYPE_SUB1, /**< Substring style 1 @since 1.1 */ ECORE_IMF_PREEDIT_TYPE_SUB2, /**< Substring style 2 @since 1.1 */ - ECORE_IMF_PREEDIT_TYPE_SUB3 /**< Substring style 3 @since 1.1 */ + ECORE_IMF_PREEDIT_TYPE_SUB3, /**< Substring style 3 @since 1.1 */ + ECORE_IMF_PREEDIT_TYPE_SUB4, /**< Substring style 4 @since 1.8 */ + ECORE_IMF_PREEDIT_TYPE_SUB5, /**< Substring style 5 @since 1.8 */ + ECORE_IMF_PREEDIT_TYPE_SUB6, /**< Substring style 6 @since 1.8 */ + ECORE_IMF_PREEDIT_TYPE_SUB7 /**< Substring style 7 @since 1.8 */ } Ecore_IMF_Preedit_Type; /** @@ -204,6 +292,8 @@ typedef enum * * Autocapitalization Types. * + * @since_tizen 2.3.1 + * * @see ecore_imf_context_autocapital_type_set() */ typedef enum @@ -219,6 +309,8 @@ typedef enum * * Input panel (virtual keyboard) layout types. * + * @since_tizen 2.3.1 + * * @see ecore_imf_context_input_panel_layout_set() */ typedef enum @@ -233,8 +325,10 @@ typedef enum ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY, /**< Number Only layout */ ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID, /**< Never use this */ ECORE_IMF_INPUT_PANEL_LAYOUT_HEX, /**< Hexadecimal layout @since 1.2 */ - ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL, /**< Command-line terminal layout @since 1.2 */ - ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD /**< Like normal, but no auto-correct, no auto-capitalization etc. @since 1.2 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL, /**< Command-line terminal layout including ESC, Alt, Ctrl key, so on (no auto-correct, no auto-capitalization) @since 1.2 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD, /**< Like normal, but no auto-correct, no auto-capitalization etc. @since 1.2 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_DATETIME, /**< Date and time layout @since 1.8 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_EMOTICON /**< Emoticon layout @since 1.10 */ } Ecore_IMF_Input_Panel_Layout; /** @@ -242,6 +336,8 @@ typedef enum * * Input panel (virtual keyboard) language modes. * + * @since_tizen 2.3.1 + * * @see ecore_imf_context_input_panel_language_set() */ typedef enum @@ -255,6 +351,8 @@ typedef enum * * "Return" Key types on the input panel (virtual keyboard). * + * @since_tizen 2.3.1 + * * @see ecore_imf_context_input_panel_return_key_type_set() */ typedef enum @@ -266,30 +364,103 @@ typedef enum ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN, /**< Login @since 1.2 */ ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT, /**< Next @since 1.2 */ ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH, /**< Search or magnifier icon @since 1.2 */ - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND /**< Send @since 1.2 */ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND, /**< Send @since 1.2 */ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN /**< Sign-in @since 1.8 */ } Ecore_IMF_Input_Panel_Return_Key_Type; +/** + * @typedef Ecore_IMF_Input_Hints + * @brief Enumeration that defines the types of Ecore_IMF Input Hints. + * @since_tizen 2.3.1 + * @since 1.12 + */ +typedef enum +{ + ECORE_IMF_INPUT_HINT_NONE = 0, /**< No active hints @since 1.12 */ + ECORE_IMF_INPUT_HINT_AUTO_COMPLETE = 1 << 0, /**< Suggest word auto completion @since 1.12 */ + ECORE_IMF_INPUT_HINT_SENSITIVE_DATA = 1 << 1, /**< Typed text should not be stored. @since 1.12 */ +} Ecore_IMF_Input_Hints; + +enum +{ + ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_NORMAL, /**< The plain normal layout @since 1.12 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_FILENAME, /**< Filename layout. Symbols such as '/' should be disabled. @since 1.12 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_PERSON_NAME /**< The name of a person. @since 1.12 */ +}; + +enum +{ + ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_NORMAL, /**< The plain normal number layout @since 1.8 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED, /**< The number layout to allow a positive or negative sign at the start @since 1.8 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_DECIMAL, /**< The number layout to allow decimal point to provide fractional value @since 1.8 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED_AND_DECIMAL /**< The number layout to allow decimal point and negative sign @since 1.8 */ +}; + +enum +{ + ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NORMAL, /**< The normal password layout @since 1.12 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NUMBERONLY /**< The password layout to allow only number @since 1.12 */ +}; + +/** + * @typedef Ecore_IMF_BiDi_Direction + * @brief Enumeration that defines the types of Ecore_IMF bidirectionality + * @since_tizen 2.3.1 + * @since 1.12 + */ +typedef enum +{ + ECORE_IMF_BIDI_DIRECTION_NEUTRAL, /**< The Neutral mode @since 1.12 */ + ECORE_IMF_BIDI_DIRECTION_LTR, /**< The Left to Right mode @since 1.12 */ + ECORE_IMF_BIDI_DIRECTION_RTL /**< The Right to Left mode @since 1.12 */ +} Ecore_IMF_BiDi_Direction; + +/** + * @struct _Ecore_IMF_Event_Preedit_Start + * @brief The structure type used with the Preedit_Start Input Method event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Preedit_Start { Ecore_IMF_Context *ctx; }; +/** + * @struct _Ecore_IMF_Event_Preedit_End + * @brief The structure type used with the Preedit_End Input Method event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Preedit_End { Ecore_IMF_Context *ctx; }; +/** + * @struct _Ecore_IMF_Event_Preedit_Changed + * @brief The structure type used with the Preedit_Changed Input Method event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Preedit_Changed { Ecore_IMF_Context *ctx; }; +/** + * @struct _Ecore_IMF_Event_Commit + * @brief The structure type used with the Commit Input Method event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Commit { Ecore_IMF_Context *ctx; char *str; }; +/** + * @struct _Ecore_IMF_Event_Delete_Surrounding + * @brief The structure type used with the Delete_Surrounding Input Method event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Delete_Surrounding { Ecore_IMF_Context *ctx; @@ -297,6 +468,23 @@ struct _Ecore_IMF_Event_Delete_Surrounding int n_chars; }; +/** + * @struct _Ecore_IMF_Event_Selection + * @brief The structure type used with the Selection Input Method event + * @since_tizen 2.3.1 + */ +struct _Ecore_IMF_Event_Selection +{ + Ecore_IMF_Context *ctx; + int start; + int end; +}; + +/** + * @struct _Ecore_IMF_Event_Mouse_Down + * @brief The structure type used with the Mouse_Down event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Mouse_Down { int button; /**< The button which has been pressed */ @@ -312,6 +500,11 @@ struct _Ecore_IMF_Event_Mouse_Down unsigned int timestamp; /**< The timestamp when the event occurred */ }; +/** + * @struct _Ecore_IMF_Event_Mouse_Up + * @brief The structure type used with the Mouse_Up event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Mouse_Up { int button; /**< The button which has been pressed */ @@ -327,6 +520,11 @@ struct _Ecore_IMF_Event_Mouse_Up unsigned int timestamp; /**< The timestamp when the event occurred */ }; +/** + * @struct _Ecore_IMF_Event_Mouse_In + * @brief The structure type used with the Mouse_In event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Mouse_In { int buttons; @@ -341,6 +539,11 @@ struct _Ecore_IMF_Event_Mouse_In unsigned int timestamp; /**< The timestamp when the event occurred */ }; +/** + * @struct _Ecore_IMF_Event_Mouse_Out + * @brief The structure type used with the Mouse_Out event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Mouse_Out { int buttons; @@ -355,6 +558,11 @@ struct _Ecore_IMF_Event_Mouse_Out unsigned int timestamp; /**< The timestamp when the event occurred */ }; +/** + * @struct _Ecore_IMF_Event_Mouse_Move + * @brief The structure type used with the Mouse_Move event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Mouse_Move { int buttons; @@ -371,6 +579,11 @@ struct _Ecore_IMF_Event_Mouse_Move unsigned int timestamp; /**< The timestamp when the event occurred */ }; +/** + * @struct _Ecore_IMF_Event_Mouse_Wheel + * @brief The structure type used with the Mouse_Wheel event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Mouse_Wheel { int direction; /* 0 = default up/down wheel */ @@ -386,6 +599,11 @@ struct _Ecore_IMF_Event_Mouse_Wheel unsigned int timestamp; /**< The timestamp when the event occurred */ }; +/** + * @struct _Ecore_IMF_Event_Key_Down + * @brief The structure type used with the Key_Down event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Key_Down { const char *keyname; /**< The string name of the key pressed */ @@ -397,6 +615,11 @@ struct _Ecore_IMF_Event_Key_Down unsigned int timestamp; /**< The timestamp when the event occurred */ }; +/** + * @struct _Ecore_IMF_Event_Key_Up + * @brief The structure type used with the Key_Up event + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Event_Key_Up { const char *keyname; /**< The string name of the key pressed */ @@ -408,6 +631,10 @@ struct _Ecore_IMF_Event_Key_Up unsigned int timestamp; /**< The timestamp when the event occurred */ }; +/** + * @brief A union of IMF events. + * @since_tizen 2.3.1 + */ union _Ecore_IMF_Event { Ecore_IMF_Event_Mouse_Down mouse_down; @@ -420,6 +647,11 @@ union _Ecore_IMF_Event Ecore_IMF_Event_Key_Up key_up; }; +/** + * @struct _Ecore_IMF_Preedit_Attr + * @brief Structure that contains preedit attribute information. + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Preedit_Attr { Ecore_IMF_Preedit_Type preedit_type; /**< preedit style type */ @@ -427,45 +659,60 @@ struct _Ecore_IMF_Preedit_Attr unsigned int end_index; /**< end index of the range (in bytes) */ }; +/** + * @struct _Ecore_IMF_Context_Class + * @brief Structure used when creating a new Input Method Context. This + * structure is mainly used by modules implementing the Input Method Context + * interface. + * @since_tizen 2.3.1 + * + */ struct _Ecore_IMF_Context_Class { - void (*add) (Ecore_IMF_Context *ctx); - void (*del) (Ecore_IMF_Context *ctx); - void (*client_window_set) (Ecore_IMF_Context *ctx, void *window); - void (*client_canvas_set) (Ecore_IMF_Context *ctx, void *canvas); - void (*show) (Ecore_IMF_Context *ctx); - void (*hide) (Ecore_IMF_Context *ctx); - void (*preedit_string_get) (Ecore_IMF_Context *ctx, char **str, int *cursor_pos); - void (*focus_in) (Ecore_IMF_Context *ctx); - void (*focus_out) (Ecore_IMF_Context *ctx); - void (*reset) (Ecore_IMF_Context *ctx); - void (*cursor_position_set) (Ecore_IMF_Context *ctx, int cursor_pos); - void (*use_preedit_set) (Ecore_IMF_Context *ctx, Eina_Bool use_preedit); - void (*input_mode_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); - Eina_Bool (*filter_event) (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); - void (*preedit_string_with_attributes_get) (Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos); - void (*prediction_allow_set)(Ecore_IMF_Context *ctx, Eina_Bool prediction); - void (*autocapital_type_set)(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type); - void (*control_panel_show) (Ecore_IMF_Context *ctx); - void (*control_panel_hide) (Ecore_IMF_Context *ctx); - void (*input_panel_layout_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout); - Ecore_IMF_Input_Panel_Layout (*input_panel_layout_get) (Ecore_IMF_Context *ctx); - void (*input_panel_language_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang); - Ecore_IMF_Input_Panel_Lang (*input_panel_language_get) (Ecore_IMF_Context *ctx); - void (*cursor_location_set) (Ecore_IMF_Context *ctx, int x, int y, int w, int h); - void (*input_panel_imdata_set)(Ecore_IMF_Context *ctx, const void* data, int len); - void (*input_panel_imdata_get)(Ecore_IMF_Context *ctx, void* data, int *len); - void (*input_panel_return_key_type_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type); - void (*input_panel_return_key_disabled_set) (Ecore_IMF_Context *ctx, Eina_Bool disabled); - void (*input_panel_caps_lock_mode_set) (Ecore_IMF_Context *ctx, Eina_Bool mode); - void (*input_panel_geometry_get)(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); - Ecore_IMF_Input_Panel_State (*input_panel_state_get) (Ecore_IMF_Context *ctx); - void (*input_panel_event_callback_add) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value), void *data); - void (*input_panel_event_callback_del) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value)); - void (*input_panel_language_locale_get) (Ecore_IMF_Context *ctx, char **lang); - void (*candidate_panel_geometry_get)(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); + void (*add) (Ecore_IMF_Context *ctx); /**< Create the Input Method Context */ + void (*del) (Ecore_IMF_Context *ctx); /**< Delete the Input Method Context */ + void (*client_window_set) (Ecore_IMF_Context *ctx, void *window); /**< Set the client window for the Input Method Context */ + void (*client_canvas_set) (Ecore_IMF_Context *ctx, void *canvas); /**< Set the client canvas for the Input Method Context */ + void (*show) (Ecore_IMF_Context *ctx); /**< Show the Input Method Context */ + void (*hide) (Ecore_IMF_Context *ctx); /**< Hide the Input Method Context */ + void (*preedit_string_get) (Ecore_IMF_Context *ctx, char **str, int *cursor_pos); /**< Return current preedit string and cursor position */ + void (*focus_in) (Ecore_IMF_Context *ctx); /**< Input Method context widget has gained focus */ + void (*focus_out) (Ecore_IMF_Context *ctx); /**< Input Method context widget has lost focus */ + void (*reset) (Ecore_IMF_Context *ctx); /**< A change has been made */ + void (*cursor_position_set) (Ecore_IMF_Context *ctx, int cursor_pos); /**< Cursor position changed */ + void (*use_preedit_set) (Ecore_IMF_Context *ctx, Eina_Bool use_preedit); /**< Use preedit string to display feedback */ + void (*input_mode_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); /**< Set the input mode */ + Eina_Bool (*filter_event) (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); /**< Internally handle an event */ + void (*preedit_string_with_attributes_get) (Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos); /**< return current preedit string, attributes, and cursor position */ + void (*prediction_allow_set)(Ecore_IMF_Context *ctx, Eina_Bool prediction); /**< Allow text prediction */ + void (*autocapital_type_set)(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type); /**< Set auto-capitalization type */ + void (*control_panel_show) (Ecore_IMF_Context *ctx); /**< Show the control panel */ + void (*control_panel_hide) (Ecore_IMF_Context *ctx); /**< Hide the control panel */ + void (*input_panel_layout_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout); /**< Set the layout of the input panel */ + Ecore_IMF_Input_Panel_Layout (*input_panel_layout_get) (Ecore_IMF_Context *ctx); /**< Return the current layout of the input panel */ + void (*input_panel_language_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang); /**< Set the language of the input panel */ + Ecore_IMF_Input_Panel_Lang (*input_panel_language_get) (Ecore_IMF_Context *ctx); /**< Get the current language of the input panel */ + void (*cursor_location_set) (Ecore_IMF_Context *ctx, int x, int y, int w, int h); /**< Set the cursor location */ + void (*input_panel_imdata_set)(Ecore_IMF_Context *ctx, const void* data, int len); /**< Set panel-specific data to the input panel */ + void (*input_panel_imdata_get)(Ecore_IMF_Context *ctx, void* data, int *len); /**< Get current panel-specific data from the input panel */ + void (*input_panel_return_key_type_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type); /**< Set the return key theme of the input panel based on return key type provided */ + void (*input_panel_return_key_disabled_set) (Ecore_IMF_Context *ctx, Eina_Bool disabled); /**< Disable return key of the input panel */ + void (*input_panel_caps_lock_mode_set) (Ecore_IMF_Context *ctx, Eina_Bool mode); /**< Set input panel caps lock mode */ + void (*input_panel_geometry_get)(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); /**< Return input panel geometry */ + Ecore_IMF_Input_Panel_State (*input_panel_state_get) (Ecore_IMF_Context *ctx); /**< Return input panel state */ + void (*input_panel_event_callback_add) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value), void *data); /**< Add a callback on input panel state,language,mode change */ + void (*input_panel_event_callback_del) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value)); /**< Delete the input panel event callback */ + void (*input_panel_language_locale_get) (Ecore_IMF_Context *ctx, char **lang); /**< Return the current language locale */ + void (*candidate_panel_geometry_get)(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); /**< Return the candidate panel geometry */ + void (*input_hint_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Hints input_hints); /**< Sets input hint to fine-tune input methods behavior */ + void (*bidi_direction_set) (Ecore_IMF_Context *ctx, Ecore_IMF_BiDi_Direction direction); /**< Set bidirectionality at the cursor position */ }; +/** + * @struct _Ecore_IMF_Context_Info + * @brief A IMF structure containing context information. + * @since_tizen 2.3.1 + */ struct _Ecore_IMF_Context_Info { const char *id; /* ID */ @@ -479,83 +726,1321 @@ struct _Ecore_IMF_Context_Info * @} */ +/** + * Initialises the Ecore_IMF library. + * + * @since_tizen 2.3.1 + * + * @return Number of times the library has been initialised without being + * shut down. + * @ingroup Ecore_IMF_Lib_Group + */ EAPI int ecore_imf_init(void); + +/** + * Shuts down the Ecore_IMF library. + * + * @since_tizen 2.3.1 + * + * @return Number of times the library has been initialised without being + * shut down. + * @ingroup Ecore_IMF_Lib_Group + */ EAPI int ecore_imf_shutdown(void); +/** + * Register an Ecore_IMF module. + * + * @since_tizen 2.3.1 + * + * @param info An Ecore_IMF_Context_Info structure + * @param imf_module_create A function to call at the creation + * @param imf_module_exit A function to call when exiting + * + * @ingroup Ecore_IMF_Lib_Group + */ EAPI void ecore_imf_module_register(const Ecore_IMF_Context_Info *info, Ecore_IMF_Context *(*imf_module_create)(void), Ecore_IMF_Context *(*imf_module_exit)(void)); +/** + * Hide the input panel. + * + * @since_tizen 2.3.1 + * + * @return EINA_TRUE if the input panel will be hidden + EINA_FALSE if the input panel is already in hidden state + * @ingroup Ecore_IMF_Lib_Group + * @since 1.8.0 + */ +EAPI Eina_Bool ecore_imf_input_panel_hide(void); + +/** + * Get the list of the available Input Method Context ids. + * + * @since_tizen 2.3.1 + * + * Note that the caller is responsible for freeing the Eina_List + * when finished with it. There is no need to finish the list strings. + * + * @return Return an Eina_List of strings; + * on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + */ EAPI Eina_List *ecore_imf_context_available_ids_get(void); + +/** + * Get the list of the available Input Method Context ids by canvas type. + * + * @since_tizen 2.3.1 + * + * Note that the caller is responsible for freeing the Eina_List + * when finished with it. There is no need to finish the list strings. + * + * @param canvas_type A string containing the canvas type. + * @return Return an Eina_List of strings; + * on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + */ EAPI Eina_List *ecore_imf_context_available_ids_by_canvas_type_get(const char *canvas_type); + +/** + * Get the id of the default Input Method Context. + * + * @since_tizen 2.3.1 + * + * The id may to used to create a new instance of an Input Method + * Context object. + * + * @return Return a string containing the id of the default Input + * Method Context; on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + */ EAPI const char *ecore_imf_context_default_id_get(void); + +/** + * Get the id of the default Input Method Context corresponding to a canvas + * type. + * + * @since_tizen 2.3.1 + * + * The id may be used to create a new instance of an Input Method + * Context object. + * + * @param canvas_type A string containing the canvas type. + * @return Return a string containing the id of the default Input + * Method Context; on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + */ EAPI const char *ecore_imf_context_default_id_by_canvas_type_get(const char *canvas_type); + +/** + * Retrieve the info for the Input Method Context with @p id. + * + * @since_tizen 2.3.1 + * + * @param id The Input Method Context id to query for. + * @return Return a #Ecore_IMF_Context_Info for the Input Method Context with @p id; + * on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + * + * Example + * @code + * + * const char *ctx_id; + * const Ecore_IMF_Context_Info *ctx_info; + * Ecore_IMF_Context *imf_context; + * ctx_id = ecore_imf_context_default_id_get(); + * if (ctx_id) + * { + * ctx_info = ecore_imf_context_info_by_id_get(ctx_id); + * if (!ctx_info->canvas_type || + * strcmp(ctx_info->canvas_type, "evas") == 0) + * { + * imf_context = ecore_imf_context_add(ctx_id); + * } + * else + * { + * ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas"); + * if (ctx_id) + * { + * imf_context = ecore_imf_context_add(ctx_id); + * } + * } + * } + * @endcode + */ EAPI const Ecore_IMF_Context_Info *ecore_imf_context_info_by_id_get(const char *id); +/** + * Create a new Input Method Context defined by the given id. + * + * @since_tizen 2.3.1 + * + * @param id The Input Method Context id. + * @return A newly allocated Input Method Context; + * on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + */ EAPI Ecore_IMF_Context *ecore_imf_context_add(const char *id); + +/** + * Retrieve the info for the given Input Method Context. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @return Return a #Ecore_IMF_Context_Info for the given Input Method Context; + * on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + */ EAPI const Ecore_IMF_Context_Info *ecore_imf_context_info_get(Ecore_IMF_Context *ctx); + +/** + * Delete the given Input Method Context and free its memory. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + */ EAPI void ecore_imf_context_del(Ecore_IMF_Context *ctx); + +/** + * Set the client window for the Input Method Context; this is the + * Ecore_X_Window when using X11, Ecore_Win32_Window when using Win32, etc. + * This window is used in order to correctly position status windows, and may + * also be used for purposes internal to the Input Method Context. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param window The client window. This may be @c NULL to indicate + * that the previous client window no longer exists. + * @ingroup Ecore_IMF_Context_Group + */ EAPI void ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window); + +/** + * Get the client window of the Input Method Context + * + * @since_tizen 2.3.1 + * + * See @ref ecore_imf_context_client_window_set for more details. + * + * @param ctx An #Ecore_IMF_Context. + * @return Return the client window. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void *ecore_imf_context_client_window_get(Ecore_IMF_Context *ctx); + +/** + * Set the client canvas for the Input Method Context; this is the + * canvas in which the input appears. + * + * @since_tizen 2.3.1 + * + * The canvas type can be determined by using the context canvas type. + * Actually only canvas with type "evas" (Evas *) is supported. + * This canvas may be used in order to correctly position status windows, and may + * also be used for purposes internal to the Input Method Context. + * + * @param ctx An #Ecore_IMF_Context. + * @param canvas The client canvas. This may be @c NULL to indicate + * that the previous client canvas no longer exists. + * @ingroup Ecore_IMF_Context_Group + */ EAPI void ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas); + +/** + * Get the client canvas of the Input Method Context. + * + * @since_tizen 2.3.1 + * + * See @ref ecore_imf_context_client_canvas_set for more details. + * + * @param ctx An #Ecore_IMF_Context. + * @return Return the client canvas. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void *ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx); + +/** + * Ask the Input Method Context to show itself. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + */ EAPI void ecore_imf_context_show(Ecore_IMF_Context *ctx); + +/** + * Ask the Input Method Context to hide itself. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + */ EAPI void ecore_imf_context_hide(Ecore_IMF_Context *ctx); + +/** + * Retrieve the current preedit string and cursor position + * for the Input Method Context. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param str Location to store the retrieved string. The + * string retrieved must be freed with free(). + * @param cursor_pos Location to store position of cursor (in characters) + * within the preedit string. + * @ingroup Ecore_IMF_Context_Group + */ EAPI void ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cursor_pos); + +/** + * Retrieve the current preedit string, attributes and + * cursor position for the Input Method Context. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param str Location to store the retrieved string. The + * string retrieved must be freed with free(). + * @param attrs an Eina_List of attributes + * @param cursor_pos Location to store position of cursor (in characters) + * within the preedit string. + * @ingroup Ecore_IMF_Context_Group + * + * Example + * @code + * char *preedit_string; + * int cursor_pos; + * Eina_List *attrs = NULL, *l = NULL; + * Ecore_IMF_Preedit_Attr *attr; + * + * ecore_imf_context_preedit_string_with_attributes_get(imf_context, + * &preedit_string, + * &attrs, &cursor_pos); + * if (!preedit_string) return; + * + * if (strlen(preedit_string) > 0) + * { + * if (attrs) + * { + * EINA_LIST_FOREACH(attrs, l, attr) + * { + * if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1) + * { + * // Something to do + * } + * else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2) + * { + * // Something to do + * } + * else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3) + * { + * // Something to do + * } + * } + * } + * } + * + * // delete attribute list + * EINA_LIST_FREE(attrs, attr) free(attr); + * + * free(preedit_string); + * @endcode + * @since 1.1.0 + */ EAPI void ecore_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos); + +/** + * Notify the Input Method Context that the widget to which its + * correspond has gained focus. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * + * Example + * @code + * static void + * _focus_in_cb(void *data, Evas_Object *o, const char *emission, const char *source) + * { + * Ecore_IMF_Context *imf_context = data; + * ecore_imf_context_focus_in(imf_context); + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _focus_in_cb, imf_context); + * @endcode + */ EAPI void ecore_imf_context_focus_in(Ecore_IMF_Context *ctx); + +/** + * Notify the Input Method Context that the widget to which its + * correspond has lost focus. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * + * Example + * @code + * static void + * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source) + * { + * Ecore_IMF_Context *imf_context = data; + * ecore_imf_context_reset(imf_context); + * ecore_imf_context_focus_out(imf_context); + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed); + * @endcode + */ EAPI void ecore_imf_context_focus_out(Ecore_IMF_Context *ctx); + +/** + * Notify the Input Method Context that a change such as a + * change in cursor position has been made. This will typically + * cause the Input Method Context to clear the preedit state or commit the preedit string. + * + * @since_tizen 2.3.1 + * + * The operation of ecore_imf_context_reset() depends on the specific characteristics of + * each language. For example, the preedit string is cleared in the Chinese and Japanese Input Method Engine. + * However, The preedit string is committed and then cleared in the Korean Input Method Engine. + * + * This function should be called in case of the focus-out and mouse down event callback function. + * In addition, it should be called before inserting some text. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * + * Example + * @code + * static void + * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source) + * { + * Ecore_IMF_Context *imf_context = data; + * ecore_imf_context_reset(imf_context); + * ecore_imf_context_focus_out(imf_context); + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, imf_context); + * @endcode + */ EAPI void ecore_imf_context_reset(Ecore_IMF_Context *ctx); + +/** + * Notify the Input Method Context that a change in the cursor + * position has been made. + * + * @since_tizen 2.3.1 + * + * This function should be called when cursor position is changed or mouse up event is generated. + * Some input methods that do a heavy job using this event can give a critical performance latency problem. + * For better typing performance, we suggest that the cursor position change events need to be occurred + * only if the cursor position is on a confirmed status not on moving status. + * + * @param ctx An #Ecore_IMF_Context. + * @param cursor_pos New cursor position in characters. + * @ingroup Ecore_IMF_Context_Group + */ EAPI void ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos); + +/** + * Notify the Input Method Context that a change in the cursor + * location has been made. The location is relative to the canvas. + * The cursor location can be used to determine the position of + * candidate word window in the immodule. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param x cursor x position. + * @param y cursor y position. + * @param w cursor width. + * @param h cursor height. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void ecore_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h); + +/** + * Set whether the IM context should use the preedit string + * to display feedback. If @c use_preedit is @c EINA_FALSE (default + * is @c EINA_TRUE), then the IM context may use some other method to display + * feedback, such as displaying it in a child of the root window. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param use_preedit Whether the IM context should use the preedit string. + * @ingroup Ecore_IMF_Context_Group + */ EAPI void ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit); -EAPI void ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, Eina_Bool (*func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos), const void *data); -EAPI void ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); -EAPI Ecore_IMF_Input_Mode ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx); -EAPI Eina_Bool ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); -/* plugin specific functions */ -EAPI Ecore_IMF_Context *ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc); -EAPI void ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data); +/** + * Set the callback to be used on surrounding_get request. + * + * @since_tizen 2.3.1 + * + * This callback will be called when the Input Method Context + * module requests the surrounding context. + * Input methods typically want context in order to constrain input text based on existing text; + * this is important for languages such as Thai where only some sequences of characters are allowed. + * + * @param ctx An #Ecore_IMF_Context. + * @param func The callback to be called. + * @param data The data pointer to be passed to @p func + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, Eina_Bool (*func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos), const void *data); + +/** + * Set the callback to be used on selection_get request. + * + * @since_tizen 2.3.1 + * + * This callback will be called when the Input Method Context + * module requests the selection context. + * + * @param ctx An #Ecore_IMF_Context. + * @param func The callback to be called. + * @param data The data pointer to be passed to @p func + * @ingroup Ecore_IMF_Context_Group + * @since 1.9.0 + */ +EAPI void ecore_imf_context_retrieve_selection_callback_set(Ecore_IMF_Context *ctx, Eina_Bool (*func)(void *data, Ecore_IMF_Context *ctx, char **text), const void *data); + +/** + * Set the input mode used by the Ecore Input Context. + * + * @since_tizen 2.3.1 + * + * The input mode can be one of the input modes defined in + * Ecore_IMF_Input_Mode. The default input mode is + * ECORE_IMF_INPUT_MODE_FULL. + * + * @param ctx An #Ecore_IMF_Context. + * @param input_mode The input mode to be used by @p ctx. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); + +/** + * Get the input mode being used by the Ecore Input Context. + * + * @since_tizen 2.3.1 + * + * See @ref ecore_imf_context_input_mode_set for more details. + * + * @param ctx An #Ecore_IMF_Context. + * @return The input mode being used by @p ctx. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI Ecore_IMF_Input_Mode ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx); + +/** + * Allow an Ecore Input Context to internally handle an event. + * If this function returns @c EINA_TRUE, then no further processing + * should be done for this event. + * + * @since_tizen 2.3.1 + * + * Input methods must be able to accept all types of events (simply + * returning @c EINA_FALSE if the event was not handled), but there is no + * obligation of any events to be submitted to this function. + * + * @param ctx An #Ecore_IMF_Context. + * @param type The type of event defined by #Ecore_IMF_Event_Type. + * @param event The event itself. + * @return @c EINA_TRUE if the event was handled; otherwise @c EINA_FALSE. + * @ingroup Ecore_IMF_Context_Group + * + * Example + * @code + * static void + * _key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) + * { + * Evas_Event_Key_Down *ev = event_info; + * if (!ev->key) return; + * + * if (imf_context) + * { + * Ecore_IMF_Event_Key_Down ecore_ev; + * ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev); + * if (ecore_imf_context_filter_event(imf_context, + * ECORE_IMF_EVENT_KEY_DOWN, + * (Ecore_IMF_Event *)&ecore_ev)) + * return; + * } + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, data); + * @endcode + */ +EAPI Eina_Bool ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); + +/* plugin specific functions */ + +/** + * @defgroup Ecore_IMF_Context_Module_Group Ecore Input Method Context Module Functions + * @ingroup Ecore_IMF_Lib_Group + * + * Functions that should be used by Ecore Input Method Context modules. + */ + +/** + * Creates a new Input Method Context with class specified by @p ctxc. + * + * @since_tizen 2.3.1 + * + * This method should be used by modules implementing the Input + * Method Context interface. + * + * @param ctxc An #Ecore_IMF_Context_Class. + * @return A new #Ecore_IMF_Context; on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI Ecore_IMF_Context *ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc); + +/** + * Set the Input Method Context specific data. + * + * @since_tizen 2.3.1 + * + * Note that this method should be used by modules to set + * the Input Method Context specific data and it's not meant to + * be used by applications to store application specific data. + * + * @param ctx An #Ecore_IMF_Context. + * @param data The Input Method Context specific data. + * @return A new #Ecore_IMF_Context; on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI void ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data); + +/** + * Get the Input Method Context specific data. + * + * @since_tizen 2.3.1 + * + * See @ref ecore_imf_context_data_set for more details. + * + * @param ctx An #Ecore_IMF_Context. + * @return The Input Method Context specific data. + * @ingroup Ecore_IMF_Context_Module_Group + */ EAPI void *ecore_imf_context_data_get(Ecore_IMF_Context *ctx); + +/** + * Retrieve context around insertion point. + * + * @since_tizen 2.3.1 + * + * Input methods typically want context in order to constrain input text based on existing text; + * this is important for languages such as Thai where only some sequences of characters are allowed. + * In addition, the text around the insertion point can be used for supporting autocapital feature. + * + * This function is implemented by calling the + * Ecore_IMF_Context::retrieve_surrounding_func ( + * set using #ecore_imf_context_retrieve_surrounding_callback_set). + * + * There is no obligation for a widget to respond to the + * retrieve_surrounding_func, so input methods must be prepared + * to function without context. + * + * @param ctx An #Ecore_IMF_Context. + * @param text Location to store a UTF-8 encoded string of text + * holding context around the insertion point. + * If the function returns @c EINA_TRUE, then you must free + * the result stored in this location with free(). + * @param cursor_pos Location to store the position in characters of + * the insertion cursor within @p text. + * @return @c EINA_TRUE if surrounding text was provided; otherwise + * @c EINA_FALSE. + * @ingroup Ecore_IMF_Context_Module_Group + */ EAPI Eina_Bool ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos); + +/** + * Retrieve the selected text. + * + * @since_tizen 2.3.1 + * + * This function is implemented by calling the + * Ecore_IMF_Context::retrieve_selection_func ( + * set using #ecore_imf_context_retrieve_selection_callback_set). + * + * There is no obligation for a widget to respond to the + * retrieve_surrounding_func, so input methods must be prepared + * to function without context. + * + * @param ctx An #Ecore_IMF_Context. + * @param text Location to store a UTF-8 encoded string of the selected text. + * If the function returns @c EINA_TRUE, then you must free + * the result stored in this location with free(). + * @return @c EINA_TRUE if selected text was provided; otherwise + * @c EINA_FALSE. + * @ingroup Ecore_IMF_Context_Module_Group + * @since 1.9.0 + */ +EAPI Eina_Bool ecore_imf_context_selection_get(Ecore_IMF_Context *ctx, char **text); + +/** + * Adds ECORE_IMF_EVENT_PREEDIT_START to the event queue. + * + * @since_tizen 2.3.1 + * + * ECORE_IMF_EVENT_PREEDIT_START should be added when a new preedit sequence starts. + * It's asynchronous method to put event to the event queue. + * ecore_imf_context_event_callback_call() can be used as synchronous method. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Module_Group + */ EAPI void ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx); + +/** + * Adds ECORE_IMF_EVENT_PREEDIT_END to the event queue. + * + * @since_tizen 2.3.1 + * + * ECORE_IMF_EVENT_PREEDIT_END should be added when a new preedit sequence has been completed or canceled. + * It's asynchronous method to put event to the event queue. + * ecore_imf_context_event_callback_call() can be used as synchronous method. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Module_Group + */ EAPI void ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx); + +/** + * Adds ECORE_IMF_EVENT_PREEDIT_CHANGED to the event queue. + * + * @since_tizen 2.3.1 + * + * It's asynchronous method to put event to the event queue. + * ecore_imf_context_event_callback_call() can be used as synchronous method. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Module_Group + */ EAPI void ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context *ctx); + +/** + * Adds ECORE_IMF_EVENT_COMMIT to the event queue. + * + * @since_tizen 2.3.1 + * + * It's asynchronous method to put event to the event queue. + * ecore_imf_context_event_callback_call() can be used as synchronous method. + * + * @param ctx An #Ecore_IMF_Context. + * @param str The committed string. + * @ingroup Ecore_IMF_Context_Module_Group + */ EAPI void ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str); + +/** + * Adds ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue. + * + * @since_tizen 2.3.1 + * + * Asks the widget that the input context is attached to to delete characters around the cursor position + * by adding the ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue. + * Note that offset and n_chars are in characters not in bytes. + * + * It's asynchronous method to put ECORE_IMF_EVENT_DELETE_SURROUNDING event to the event queue. + * ecore_imf_context_event_callback_call() can be used as synchronous method. + * + * @param ctx An #Ecore_IMF_Context. + * @param offset The start offset of surrounding to be deleted. + * @param n_chars The number of characters to be deleted. + * @ingroup Ecore_IMF_Context_Module_Group + */ EAPI void ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offset, int n_chars); + +/** + * Add (register) a callback function to a given context event. + * + * @since_tizen 2.3.1 + * + * This function adds a function callback to the context @p ctx when the + * event of type @p type occurs on it. The function pointer is @p + * func. + * + * The event type @p type to trigger the function may be one of + * #ECORE_IMF_CALLBACK_PREEDIT_START, #ECORE_IMF_CALLBACK_PREEDIT_END, + * #ECORE_IMF_CALLBACK_PREEDIT_CHANGED, #ECORE_IMF_CALLBACK_COMMIT and + * #ECORE_IMF_CALLBACK_DELETE_SURROUNDING. + * + * @param ctx Ecore_IMF_Context to attach a callback to. + * @param type The type of event that will trigger the callback + * @param func The (callback) function to be called when the event is + * triggered + * @param data The data pointer to be passed to @p func + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + * + * Example + * @code + * static void + * _imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info) + * { + * char *commit_str = event_info; + * // something to do + * } + * + * ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb, data); + * @endcode + */ EAPI void ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data); + +/** + * Delete (unregister) a callback function registered to a given + * context event. + * + * @since_tizen 2.3.1 + * + * This function removes a function callback from the context @p ctx when the + * event of type @p type occurs on it. The function pointer is @p + * func. + * + * @see ecore_imf_context_event_callback_add() for more details + * + * @param ctx Ecore_IMF_Context to remove a callback from. + * @param type The type of event that was triggering the callback + * @param func The (callback) function that was to be called when the event was triggered + * @return the data pointer + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ EAPI void *ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func); + +/** + * Call a given callback on the context @p ctx. + * + * @since_tizen 2.3.1 + * + * ecore_imf_context_preedit_start_event_add(), ecore_imf_context_preedit_end_event_add(), + * ecore_imf_context_preedit_changed_event_add(), ecore_imf_context_commit_event_add() and + * ecore_imf_context_delete_surrounding_event_add() APIs are asynchronous + * because those API adds each event to the event queue. + * + * This API provides the way to call each callback function immediately. + * + * @param ctx Ecore_IMF_Context. + * @param type The type of event that will trigger the callback + * @param event_info The pointer to event specific struct or information to + * pass to the callback functions registered on this event + * @ingroup Ecore_IMF_Context_Module_Group + * @since 1.2.0 + */ EAPI void ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info); + +/** + * Set whether the IM context should allow to use the text prediction. + * + * @since_tizen 2.3.1 + * + * If @p prediction is @c EINA_FALSE (default is @c EINA_TRUE), then the IM + * context will not display the text prediction window. + * + * @param ctx An #Ecore_IMF_Context. + * @param prediction Whether the IM context should allow to use the text prediction. + * @note Default value is EINA_TRUE. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction); + +/** + * Get whether the IM context should allow to use the text prediction. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @return @c EINA_TRUE if it allows to use the text prediction, otherwise + * @c EINA_FALSE. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI Eina_Bool ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx); + +/** + * Set the autocapitalization type on the immodule. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param autocapital_type the autocapitalization type. + * @note Default type is ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type); + +/** + * Get the autocapitalization type. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @return The autocapital type being used by @p ctx. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI Ecore_IMF_Autocapital_Type ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx); +/** + * @brief Sets the input hint which allows input methods to fine-tune their behavior. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context + * @param hints input hint + * @note The default input hint is @c ECORE_IMF_INPUT_HINT_AUTO_COMPLETE. + * @ingroup Ecore_IMF_Context_Group + * @since 1.12 + */ +EAPI void ecore_imf_context_input_hint_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Hints hints); + +/** + * @brief Gets the value of input hint. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context + * @return The value of input hint + * @ingroup Ecore_IMF_Context_Group + * @since 1.12 + */ +EAPI Ecore_IMF_Input_Hints ecore_imf_context_input_hint_get(Ecore_IMF_Context *ctx); + +/** + * Ask the Input Method Context to show the control panel of using Input Method. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx); + +/** + * Ask the Input Method Context to hide the control panel of using Input Method. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx); +/** + * Ask the Input Method Context to show the input panel (virtual keyboard). + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx); + +/** + * Ask the Input Method Context to hide the input panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx); + +/** + * Set the layout of the input panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param layout see #Ecore_IMF_Input_Panel_Layout + * @note Default layout type is ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout); + +/** + * Get the layout of the current active input panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @return layout see #Ecore_IMF_Input_Panel_Layout + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI Ecore_IMF_Input_Panel_Layout ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx); + +/** + * Set the layout variation of the current active input panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param variation the layout variation + * @note Default layout variation type is NORMAL. + * @ingroup Ecore_IMF_Context_Group + * @since 1.8.0 + */ +EAPI void ecore_imf_context_input_panel_layout_variation_set(Ecore_IMF_Context *ctx, int variation); + +/** + * Get the layout variation of the current active input panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @return the layout variation + * @ingroup Ecore_IMF_Context_Group + * @since 1.8.0 + */ +EAPI int ecore_imf_context_input_panel_layout_variation_get(Ecore_IMF_Context *ctx); + +/** + * Set the language of the input panel. + * This API can be used when you want to show the English keyboard. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param lang the language to be set to the input panel. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI void ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang); + +/** + * Get the language of the input panel. + * + * @since_tizen 2.3.1 + * + * See @ref ecore_imf_context_input_panel_language_set for more details. + * + * @param ctx An #Ecore_IMF_Context. + * @return Ecore_IMF_Input_Panel_Lang + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI Ecore_IMF_Input_Panel_Lang ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx, Eina_Bool enable); + +/** + * Set whether the Input Method Context should request to show the input panel automatically + * when the widget has focus. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param enabled If true, the input panel will be shown when the widget is clicked or has focus. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx, Eina_Bool enabled); + +/** + * Get whether the Input Method Context requests to show the input panel automatically. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @return Return the attribute to show the input panel automatically + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ EAPI Eina_Bool ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx); + +/** + * Set the input panel-specific data to deliver to the input panel. + * + * @since_tizen 2.3.1 + * + * This API is used by applications to deliver specific data to the input panel. + * The data format MUST be negotiated by both application and the input panel. + * The size and format of data are defined by the input panel. + * + * @param ctx An #Ecore_IMF_Context. + * @param data The specific data to be set to the input panel. + * @param len the length of data, in bytes, to send to the input panel + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ EAPI void ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int len); + +/** + * Get the specific data of the current active input panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param data The specific data to be got from the input panel + * @param len The length of data + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ EAPI void ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *len); + +/** + * Set the "return" key type. This type is used to set string or icon on the "return" key of the input panel. + * + * @since_tizen 2.3.1 + * + * An input panel displays the string or icon associated with this type + * + * @param ctx An #Ecore_IMF_Context. + * @param return_key_type The type of "return" key on the input panel + * @note Default type is ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT. + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ EAPI void ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type); + +/** + * Get the "return" key type. + * + * @since_tizen 2.3.1 + * + * @see ecore_imf_context_input_panel_return_key_type_set() for more details + * + * @param ctx An #Ecore_IMF_Context. + * @return The type of "return" key on the input panel + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ EAPI Ecore_IMF_Input_Panel_Return_Key_Type ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx); + +/** + * Set the return key on the input panel to be disabled. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param disabled The state + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ EAPI void ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Eina_Bool disabled); + +/** + * Get whether the return key on the input panel should be disabled or not. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @return @c EINA_TRUE if it should be disabled. + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ EAPI Eina_Bool ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx); + +/** + * Set the caps lock mode on the input panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param mode Turn on caps lock on the input panel if @c EINA_TRUE. + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ EAPI void ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bool mode); + +/** + * Get the caps lock mode on the input panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @return @c EINA_TRUE if the caps lock is turned on. + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ EAPI Eina_Bool ecore_imf_context_input_panel_caps_lock_mode_get(Ecore_IMF_Context *ctx); + +/** + * Get the position of the current active input panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param x top-left x co-ordinate of the input panel + * @param y top-left y co-ordinate of the input panel + * @param w width of the input panel + * @param h height of the input panel + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ EAPI void ecore_imf_context_input_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); + +/** + * Get state of current active input panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @return The state of input panel. + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ EAPI Ecore_IMF_Input_Panel_State ecore_imf_context_input_panel_state_get(Ecore_IMF_Context *ctx); + +/** + * Register a callback function which will be called if there is change in input panel state,language,mode etc. + * + * @since_tizen 2.3.1 + * + * In order to deregister the callback function + * Use @ref ecore_imf_context_input_panel_event_callback_del. + * + * @param ctx An #Ecore_IMF_Context + * @param type event type + * @param func the callback function + * @param data application-input panel specific data. + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ EAPI void ecore_imf_context_input_panel_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value), const void *data); + +/** + * Unregister a callback function which will be called if there is change in input panel state, language, mode etc. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param type An #Ecore_IMF_Input_Panel_Event. + * @param func the callback function + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ EAPI void ecore_imf_context_input_panel_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value)); + +/** + * Call a given input panel callback on the context @p ctx. + * + * @since_tizen 2.3.1 + * + * @param ctx Ecore_IMF_Context. + * @param type The type of event that will trigger the callback + * @param value the event value + * @ingroup Ecore_IMF_Context_Group + * @since 1.8.0 + */ +EAPI void ecore_imf_context_input_panel_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, int value); + +/** + * Delete all input panel callback on the context @p ctx. + * + * @since_tizen 2.3.1 + * + * Delete all input panel callback to be registered by ecore_imf_context_input_panel_event_callback_add() + * + * @param ctx Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * @since 1.8.0 + */ +EAPI void ecore_imf_context_input_panel_event_callback_clear(Ecore_IMF_Context *ctx); + +/** + * Get the current language locale of the input panel. + * + * @since_tizen 2.3.1 + * + * ex) fr_FR + * + * @param ctx An #Ecore_IMF_Context. + * @param lang Location to store the retrieved language string. The + * string retrieved must be freed with free(). + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ EAPI void ecore_imf_context_input_panel_language_locale_get(Ecore_IMF_Context *ctx, char **lang); + +/** + * Get the geometry information of the candidate panel. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param x top-left x co-ordinate of the candidate panel + * @param y top-left y co-ordinate of the candidate panel + * @param w width of the candidate panel + * @param h height of the candidate panel + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ EAPI void ecore_imf_context_candidate_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); +/** + * Set whether the Input Method Context should request to show the input panel in case of only an user's explicit Mouse Up event. + * It doesn't request to show the input panel even though the Input Method Context has focus. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @param ondemand If true, the input panel will be shown in case of only Mouse up event. (Focus event will be ignored.) + * @ingroup Ecore_IMF_Context_Group + * @since 1.8.0 + */ +EAPI void ecore_imf_context_input_panel_show_on_demand_set(Ecore_IMF_Context *ctx, Eina_Bool ondemand); + +/** + * Get whether the Input Method Context should request to show the input panel in case of only an user's explicit Mouse Up event. + * + * @since_tizen 2.3.1 + * + * @param ctx An #Ecore_IMF_Context. + * @return @c EINA_TRUE if the input panel will be shown in case of only Mouse up event. + * @ingroup Ecore_IMF_Context_Group + * @since 1.8.0 + */ +EAPI Eina_Bool ecore_imf_context_input_panel_show_on_demand_get(Ecore_IMF_Context *ctx); + +/** + * @brief Sets the bidirectionality at the current cursor position. + * + * @since_tizen 2.3.1 + * + * @ingroup Ecore_IMF_Context_Group + * @since 1.12.0 + * + * @param[in] ctx An #Ecore_IMF_Context + * @param[in] direction the direction mode + */ +EAPI void ecore_imf_context_bidi_direction_set(Ecore_IMF_Context *ctx, Ecore_IMF_BiDi_Direction direction); + +/** + * @brief Gets the bidirectionality at the current cursor position. + * + * @since_tizen 2.3.1 + * + * @ingroup Ecore_IMF_Context_Group + * @since 1.12.0 + * + * @param[in] ctx An #Ecore_IMF_Context + * @return the direction mode + */ +EAPI Ecore_IMF_BiDi_Direction ecore_imf_context_bidi_direction_get(Ecore_IMF_Context *ctx); + /* The following entry points must be exported by each input method module */ diff --git a/src/lib/ecore_imf/ecore_imf.c b/src/lib/ecore_imf/ecore_imf.c index 7cf8a4a..0f5b75f 100644 --- a/src/lib/ecore_imf/ecore_imf.c +++ b/src/lib/ecore_imf/ecore_imf.c @@ -16,20 +16,8 @@ EAPI int ECORE_IMF_EVENT_DELETE_SURROUNDING = 0; int _ecore_imf_log_dom = -1; static int _ecore_imf_init_count = 0; +extern Ecore_IMF_Context *show_req_ctx; -/** - * @defgroup Ecore_IMF_Lib_Group Ecore Input Method Library Functions - * - * Utility functions that set up and shut down the Ecore Input Method - * library. - */ - -/** - * Initialises the Ecore_IMF library. - * @return Number of times the library has been initialised without being - * shut down. - * @ingroup Ecore_IMF_Lib_Group - */ EAPI int ecore_imf_init(void) { @@ -55,12 +43,6 @@ ecore_imf_init(void) return _ecore_imf_init_count; } -/** - * Shuts down the Ecore_IMF library. - * @return Number of times the library has been initialised without being - * shut down. - * @ingroup Ecore_IMF_Lib_Group - */ EAPI int ecore_imf_shutdown(void) { @@ -71,3 +53,18 @@ ecore_imf_shutdown(void) ecore_shutdown(); return _ecore_imf_init_count; } + +EAPI Eina_Bool +ecore_imf_input_panel_hide(void) +{ + if (show_req_ctx) + { + if (ecore_imf_context_input_panel_state_get(show_req_ctx) != ECORE_IMF_INPUT_PANEL_STATE_HIDE) + { + ecore_imf_context_input_panel_hide(show_req_ctx); + return EINA_TRUE; + } + } + + return EINA_FALSE; +} diff --git a/src/lib/ecore_imf/ecore_imf_context.c b/src/lib/ecore_imf/ecore_imf_context.c index 0ae316a..dce7858 100644 --- a/src/lib/ecore_imf/ecore_imf_context.c +++ b/src/lib/ecore_imf/ecore_imf_context.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include #include @@ -12,39 +38,8 @@ #include "Ecore_IMF.h" #include "ecore_imf_private.h" -/** - * @defgroup Ecore_IMF_Context_Group Ecore Input Method Context Functions - * - * Functions that operate on Ecore Input Method Context objects. - - * Ecore Input Method Context Function defines the interface for EFL input methods. - * An input method is used by EFL text input widgets like elm_entry - * (based on edje_entry) to map from key events to Unicode character strings. - * - * The default input method can be set through setting the ECORE_IMF_MODULE environment variable. - * - * An input method may consume multiple key events in sequence and finally output the composed result. - * This is called preediting, and an input method may provide feedback about - * this process by displaying the intermediate composition states as preedit text. - * - * Immodule is plugin to connect your application and input method framework such as SCIM, ibus, and so on.@n - * ecore_imf_init() should be called to initialize and load immodule.@n - * ecore_imf_shutdown() is used for shutdowning and unloading immodule. - * - * An example of usage of these functions can be found at: - * @li @ref ecore_imf_example_c - */ +Ecore_IMF_Context *show_req_ctx = NULL; -/** - * Get the list of the available Input Method Context ids. - * - * Note that the caller is responsible for freeing the Eina_List - * when finished with it. There is no need to finish the list strings. - * - * @return Return an Eina_List of strings; - * on failure it returns NULL. - * @ingroup Ecore_IMF_Context_Group - */ EAPI Eina_List * ecore_imf_context_available_ids_get(void) { @@ -80,15 +75,6 @@ _ecore_imf_context_match_locale(const char *locale, const char *against, int aga return 0; } -/** - * Get the id of the default Input Method Context. - * The id may to used to create a new instance of an Input Method - * Context object. - * - * @return Return a string containing the id of the default Input - * Method Context; on failure it returns NULL. - * @ingroup Ecore_IMF_Context_Group - */ EAPI const char * ecore_imf_context_default_id_get(void) { @@ -153,40 +139,6 @@ ecore_imf_context_default_id_by_canvas_type_get(const char *canvas_type) return id; } -/** - * Retrieve the info for the Input Method Context with @p id. - * - * @param id The Input Method Context id to query for. - * @return Return a #Ecore_IMF_Context_Info for the Input Method Context with @p id; - * on failure it returns NULL. - * @ingroup Ecore_IMF_Context_Group - * - * Example - * @code - * - * const char *ctx_id; - * const Ecore_IMF_Context_Info *ctx_info; - * Ecore_IMF_Context *imf_context; - * ctx_id = ecore_imf_context_default_id_get(); - * if (ctx_id) - * { - * ctx_info = ecore_imf_context_info_by_id_get(ctx_id); - * if (!ctx_info->canvas_type || - * strcmp(ctx_info->canvas_type, "evas") == 0) - * { - * imf_context = ecore_imf_context_add(ctx_id); - * } - * else - * { - * ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas"); - * if (ctx_id) - * { - * imf_context = ecore_imf_context_add(ctx_id); - * } - * } - * } - * @endcode - */ EAPI const Ecore_IMF_Context_Info * ecore_imf_context_info_by_id_get(const char *id) { @@ -198,14 +150,6 @@ ecore_imf_context_info_by_id_get(const char *id) return module->info; } -/** - * Create a new Input Method Context defined by the given id. - * - * @param id The Input Method Context id. - * @return A newly allocated Input Method Context; - * on failure it returns NULL. - * @ingroup Ecore_IMF_Context_Group - */ EAPI Ecore_IMF_Context * ecore_imf_context_add(const char *id) { @@ -227,6 +171,9 @@ ecore_imf_context_add(const char *id) * set on the immodule */ ecore_imf_context_autocapital_type_set(ctx, ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE); + /* default input hint */ + ecore_imf_context_input_hint_set(ctx, ECORE_IMF_INPUT_HINT_AUTO_COMPLETE); + /* default input panel enabled status is EINA_TRUE, so let's make sure it's * set on the immodule */ ecore_imf_context_input_panel_enabled_set(ctx, EINA_TRUE); @@ -238,17 +185,12 @@ ecore_imf_context_add(const char *id) /* default input_mode is ECORE_IMF_INPUT_MODE_FULL, so let's make sure it's * set on the immodule */ ecore_imf_context_input_mode_set(ctx, ECORE_IMF_INPUT_MODE_FULL); + + ecore_imf_context_bidi_direction_set(ctx, ECORE_IMF_BIDI_DIRECTION_NEUTRAL); + return ctx; } -/** - * Retrieve the info for the given Input Method Context. - * - * @param ctx An #Ecore_IMF_Context. - * @return Return a #Ecore_IMF_Context_Info for the given Input Method Context; - * on failure it returns NULL. - * @ingroup Ecore_IMF_Context_Group - */ EAPI const Ecore_IMF_Context_Info * ecore_imf_context_info_get(Ecore_IMF_Context *ctx) { @@ -261,12 +203,6 @@ ecore_imf_context_info_get(Ecore_IMF_Context *ctx) return ctx->module->info; } -/** - * Delete the given Input Method Context and free its memory. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - */ EAPI void ecore_imf_context_del(Ecore_IMF_Context *ctx) { @@ -278,6 +214,10 @@ ecore_imf_context_del(Ecore_IMF_Context *ctx) "ecore_imf_context_del"); return; } + + if (show_req_ctx == ctx) + show_req_ctx = NULL; + if (ctx->klass->del) ctx->klass->del(ctx); if (ctx->callbacks) @@ -286,21 +226,16 @@ ecore_imf_context_del(Ecore_IMF_Context *ctx) free(fn); } + if (ctx->input_panel_callbacks) + { + EINA_LIST_FREE(ctx->input_panel_callbacks, fn) + free(fn); + } + ECORE_MAGIC_SET(ctx, ECORE_MAGIC_NONE); free(ctx); } -/** - * Set the client window for the Input Method Context; this is the - * Ecore_X_Window when using X11, Ecore_Win32_Window when using Win32, etc. - * This window is used in order to correctly position status windows, and may - * also be used for purposes internal to the Input Method Context. - * - * @param ctx An #Ecore_IMF_Context. - * @param window The client window. This may be @c NULL to indicate - * that the previous client window no longer exists. - * @ingroup Ecore_IMF_Context_Group - */ EAPI void ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window) { @@ -314,16 +249,6 @@ ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window) ctx->window = window; } -/** - * Get the client window of the Input Method Context - * - * See @ref ecore_imf_context_client_window_set for more details. - * - * @param ctx An #Ecore_IMF_Context. - * @return Return the client window. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI void * ecore_imf_context_client_window_get(Ecore_IMF_Context *ctx) { @@ -336,19 +261,6 @@ ecore_imf_context_client_window_get(Ecore_IMF_Context *ctx) return ctx->window; } -/** - * Set the client canvas for the Input Method Context; this is the - * canvas in which the input appears. - * The canvas type can be determined by using the context canvas type. - * Actually only canvas with type "evas" (Evas *) is supported. - * This canvas may be used in order to correctly position status windows, and may - * also be used for purposes internal to the Input Method Context. - * - * @param ctx An #Ecore_IMF_Context. - * @param canvas The client canvas. This may be @c NULL to indicate - * that the previous client canvas no longer exists. - * @ingroup Ecore_IMF_Context_Group - */ EAPI void ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas) { @@ -362,16 +274,6 @@ ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas) ctx->client_canvas = canvas; } -/** - * Get the client canvas of the Input Method Context. - * - * See @ref ecore_imf_context_client_canvas_set for more details. - * - * @param ctx An #Ecore_IMF_Context. - * @return Return the client canvas. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI void * ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx) { @@ -384,12 +286,6 @@ ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx) return ctx->client_canvas; } -/** - * Ask the Input Method Context to show itself. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - */ EAPI void ecore_imf_context_show(Ecore_IMF_Context *ctx) { @@ -399,15 +295,11 @@ ecore_imf_context_show(Ecore_IMF_Context *ctx) "ecore_imf_context_show"); return; } + + show_req_ctx = ctx; if (ctx->klass->show) ctx->klass->show(ctx); } -/** - * Ask the Input Method Context to hide itself. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - */ EAPI void ecore_imf_context_hide(Ecore_IMF_Context *ctx) { @@ -417,20 +309,10 @@ ecore_imf_context_hide(Ecore_IMF_Context *ctx) "ecore_imf_context_hide"); return; } + if (ctx->klass->hide) ctx->klass->hide(ctx); } -/** - * Retrieve the current preedit string and cursor position - * for the Input Method Context. - * - * @param ctx An #Ecore_IMF_Context. - * @param str Location to store the retrieved string. The - * string retrieved must be freed with free(). - * @param cursor_pos Location to store position of cursor (in characters) - * within the preedit string. - * @ingroup Ecore_IMF_Context_Group - */ EAPI void ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cursor_pos) { @@ -449,59 +331,6 @@ ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cu } } -/** - * Retrieve the current preedit string, attributes and - * cursor position for the Input Method Context. - * - * @param ctx An #Ecore_IMF_Context. - * @param str Location to store the retrieved string. The - * string retrieved must be freed with free(). - * @param attrs an Eina_List of attributes - * @param cursor_pos Location to store position of cursor (in characters) - * within the preedit string. - * @ingroup Ecore_IMF_Context_Group - * - * Example - * @code - * char *preedit_string; - * int cursor_pos; - * Eina_List *attrs = NULL, *l = NULL; - * Ecore_IMF_Preedit_Attr *attr; - * - * ecore_imf_context_preedit_string_with_attributes_get(imf_context, - * &preedit_string, - * &attrs, &cursor_pos); - * if (!preedit_string) return; - * - * if (strlen(preedit_string) > 0) - * { - * if (attrs) - * { - * EINA_LIST_FOREACH(attrs, l, attr) - * { - * if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1) - * { - * // Something to do - * } - * else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2) - * { - * // Something to do - * } - * else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3) - * { - * // Something to do - * } - * } - * } - * } - * - * // delete attribute list - * EINA_LIST_FREE(attrs, attr) free(attr); - * - * free(preedit_string); - * @endcode - * @since 1.1.0 - */ EAPI void ecore_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos) { @@ -521,25 +350,6 @@ ecore_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, cha } } -/** - * Notify the Input Method Context that the widget to which its - * correspond has gained focus. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * - * Example - * @code - * static void - * _focus_in_cb(void *data, Evas_Object *o, const char *emission, const char *source) - * { - * ecore_imf_context_reset(imf_context); - * ecore_imf_context_focus_in(imf_context); - * } - * - * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _focus_in_cb, ed); - * @endcode - */ EAPI void ecore_imf_context_focus_in(Ecore_IMF_Context *ctx) { @@ -552,25 +362,6 @@ ecore_imf_context_focus_in(Ecore_IMF_Context *ctx) if (ctx->klass->focus_in) ctx->klass->focus_in(ctx); } -/** - * Notify the Input Method Context that the widget to which its - * correspond has lost focus. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * - * Example - * @code - * static void - * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source) - * { - * ecore_imf_context_reset(imf_context); - * ecore_imf_context_focus_out(imf_context); - * } - * - * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed); - * @endcode - */ EAPI void ecore_imf_context_focus_out(Ecore_IMF_Context *ctx) { @@ -583,26 +374,6 @@ ecore_imf_context_focus_out(Ecore_IMF_Context *ctx) if (ctx->klass->focus_out) ctx->klass->focus_out(ctx); } -/** - * Notify the Input Method Context that a change such as a - * change in cursor position has been made. This will typically - * cause the Input Method Context to clear the preedit state. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * - * Example - * @code - * static void - * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source) - * { - * ecore_imf_context_reset(imf_context); - * ecore_imf_context_focus_out(imf_context); - * } - * - * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed); - * @endcode - */ EAPI void ecore_imf_context_reset(Ecore_IMF_Context *ctx) { @@ -615,14 +386,6 @@ ecore_imf_context_reset(Ecore_IMF_Context *ctx) if (ctx->klass->reset) ctx->klass->reset(ctx); } -/** - * Notify the Input Method Context that a change in the cursor - * position has been made. - * - * @param ctx An #Ecore_IMF_Context. - * @param cursor_pos New cursor position in characters. - * @ingroup Ecore_IMF_Context_Group - */ EAPI void ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos) { @@ -635,20 +398,6 @@ ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos) if (ctx->klass->cursor_position_set) ctx->klass->cursor_position_set(ctx, cursor_pos); } -/** - * Notify the Input Method Context that a change in the cursor - * location has been made. The location is relative to the canvas. - * The cursor location can be used to determine the position of - * candidate word window in the immodule. - * - * @param ctx An #Ecore_IMF_Context. - * @param x cursor x position. - * @param y cursor y position. - * @param w cursor width. - * @param h cursor height. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI void ecore_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h) { @@ -661,16 +410,6 @@ ecore_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int if (ctx->klass->cursor_location_set) ctx->klass->cursor_location_set(ctx, x, y, w, h); } -/** - * Set whether the IM context should use the preedit string - * to display feedback. If @c use_preedit is @c EINA_FALSE (default - * is @c EINA_TRUE), then the IM context may use some other method to display - * feedback, such as displaying it in a child of the root window. - * - * @param ctx An #Ecore_IMF_Context. - * @param use_preedit Whether the IM context should use the preedit string. - * @ingroup Ecore_IMF_Context_Group - */ EAPI void ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit) { @@ -683,16 +422,6 @@ ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit) if (ctx->klass->use_preedit_set) ctx->klass->use_preedit_set(ctx, use_preedit); } -/** - * Set whether the IM context should allow to use the text prediction. - * If @p prediction is @c EINA_FALSE (default is @c EINA_TRUE), then the IM - * context will not display the text prediction window. - * - * @param ctx An #Ecore_IMF_Context. - * @param prediction Whether the IM context should allow to use the text prediction. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI void ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction) { @@ -703,21 +432,15 @@ ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool predict return; } - ctx->allow_prediction = prediction; + if (ctx->allow_prediction != prediction) + { + ctx->allow_prediction = prediction; - if (ctx->klass->prediction_allow_set) - ctx->klass->prediction_allow_set(ctx, prediction); + if (ctx->klass->prediction_allow_set) + ctx->klass->prediction_allow_set(ctx, prediction); + } } -/** - * Get whether the IM context should allow to use the text prediction. - * - * @param ctx An #Ecore_IMF_Context. - * @return @c EINA_TRUE if it allows to use the text prediction, otherwise - * @c EINA_FALSE. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI Eina_Bool ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx) { @@ -731,14 +454,6 @@ ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx) return ctx->allow_prediction; } -/** - * Set the autocapitalization type on the immodule. - * - * @param ctx An #Ecore_IMF_Context. - * @param autocapital_type the autocapitalization type. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI void ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type) { @@ -749,19 +464,14 @@ ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocap return; } - ctx->autocapital_type = autocapital_type; + if (ctx->autocapital_type != autocapital_type) + { + ctx->autocapital_type = autocapital_type; - if (ctx->klass->autocapital_type_set) ctx->klass->autocapital_type_set(ctx, autocapital_type); + if (ctx->klass->autocapital_type_set) ctx->klass->autocapital_type_set(ctx, autocapital_type); + } } -/** - * Get the autocapitalization type. - * - * @param ctx An #Ecore_IMF_Context. - * @return The autocapital type being used by @p ctx. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI Ecore_IMF_Autocapital_Type ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx) { @@ -775,17 +485,6 @@ ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx) return ctx->autocapital_type; } -/** - * Set the callback to be used on surrounding_get request. - * - * This callback will be called when the Input Method Context - * module requests the surrounding context. - * - * @param ctx An #Ecore_IMF_Context. - * @param func The callback to be called. - * @param data The data pointer to be passed to @p func - * @ingroup Ecore_IMF_Context_Group - */ EAPI void ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, Eina_Bool (*func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos), const void *data) { @@ -800,17 +499,20 @@ ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, Eina ctx->retrieve_surrounding_data = (void *) data; } -/** - * Set the input mode used by the Ecore Input Context. - * - * The input mode can be one of the input modes defined in - * Ecore_IMF_Input_Mode. The default input mode is - * ECORE_IMF_INPUT_MODE_FULL. - * - * @param ctx An #Ecore_IMF_Context. - * @param input_mode The input mode to be used by @p ctx. - * @ingroup Ecore_IMF_Context_Group - */ +EAPI void +ecore_imf_context_retrieve_selection_callback_set(Ecore_IMF_Context *ctx, Eina_Bool (*func)(void *data, Ecore_IMF_Context *ctx, char **text), const void *data) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_retrieve_selection_callback_set"); + return; + } + + ctx->retrieve_selection_func = func; + ctx->retrieve_selection_data = (void *) data; +} + EAPI void ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode) { @@ -824,15 +526,6 @@ ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode in ctx->input_mode = input_mode; } -/** - * Get the input mode being used by the Ecore Input Context. - * - * See @ref ecore_imf_context_input_mode_set for more details. - * - * @param ctx An #Ecore_IMF_Context. - * @return The input mode being used by @p ctx. - * @ingroup Ecore_IMF_Context_Group - */ EAPI Ecore_IMF_Input_Mode ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx) { @@ -845,43 +538,6 @@ ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx) return ctx->input_mode; } -/** - * Allow an Ecore Input Context to internally handle an event. - * If this function returns @c EINA_TRUE, then no further processing - * should be done for this event. - * - * Input methods must be able to accept all types of events (simply - * returning @c EINA_FALSE if the event was not handled), but there is no - * obligation of any events to be submitted to this function. - * - * @param ctx An #Ecore_IMF_Context. - * @param type The type of event defined by #Ecore_IMF_Event_Type. - * @param event The event itself. - * @return @c EINA_TRUE if the event was handled; otherwise @c EINA_FALSE. - * @ingroup Ecore_IMF_Context_Group - * - * Example - * @code - * static void - * _key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) - * { - * Evas_Event_Key_Down *ev = event_info; - * if (!ev->keyname) return; - * - * if (imf_context) - * { - * Ecore_IMF_Event_Key_Down ecore_ev; - * ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev); - * if (ecore_imf_context_filter_event(imf_context, - * ECORE_IMF_EVENT_KEY_DOWN, - * (Ecore_IMF_Event *)&ecore_ev)) - * return; - * } - * } - * - * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, data); - * @endcode - */ EAPI Eina_Bool ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event) { @@ -895,22 +551,6 @@ ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type return EINA_FALSE; } -/** - * @defgroup Ecore_IMF_Context_Module_Group Ecore Input Method Context Module Functions - * - * Functions that should be used by Ecore Input Method Context modules. - */ - -/** - * Creates a new Input Method Context with klass specified by @p ctxc. - * - * This method should be used by modules implementing the Input - * Method Context interface. - * - * @param ctxc An #Ecore_IMF_Context_Class. - * @return A new #Ecore_IMF_Context; on failure it returns NULL. - * @ingroup Ecore_IMF_Context_Module_Group - */ EAPI Ecore_IMF_Context * ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc) { @@ -927,18 +567,6 @@ ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc) return ctx; } -/** - * Set the Input Method Context specific data. - * - * Note that this method should be used by modules to set - * the Input Method Context specific data and it's not meant to - * be used by applications to store application specific data. - * - * @param ctx An #Ecore_IMF_Context. - * @param data The Input Method Context specific data. - * @return A new #Ecore_IMF_Context; on failure it returns NULL. - * @ingroup Ecore_IMF_Context_Module_Group - */ EAPI void ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data) { @@ -951,16 +579,8 @@ ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data) ctx->data = data; } -/** - * Get the Input Method Context specific data. - * - * See @ref ecore_imf_context_data_set for more details. - * - * @param ctx An #Ecore_IMF_Context. - * @return The Input Method Context specific data. - * @ingroup Ecore_IMF_Context_Module_Group - */ -EAPI void *ecore_imf_context_data_get(Ecore_IMF_Context *ctx) +EAPI void * +ecore_imf_context_data_get(Ecore_IMF_Context *ctx) { if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) { @@ -971,31 +591,6 @@ EAPI void *ecore_imf_context_data_get(Ecore_IMF_Context *ctx) return ctx->data; } -/** - * Retrieve context around insertion point. - * Input methods typically want context in order to constrain input text based on existing text; - * this is important for languages such as Thai where only some sequences of characters are allowed. - * In addition, the text around the insertion point can be used for supporting autocapital feature. - * - * This function is implemented by calling the - * Ecore_IMF_Context::retrieve_surrounding_func ( - * set using #ecore_imf_context_retrieve_surrounding_callback_set). - * - * There is no obligation for a widget to respond to the - * retrieve_surrounding_func, so input methods must be prepared - * to function without context. - * - * @param ctx An #Ecore_IMF_Context. - * @param text Location to store a UTF-8 encoded string of text - * holding context around the insertion point. - * If the function returns @c EINA_TRUE, then you must free - * the result stored in this location with free(). - * @param cursor_pos Location to store the position in characters of - * the insertion cursor within @p text. - * @return @c EINA_TRUE if surrounding text was provided; otherwise - * @c EINA_FALSE. - * @ingroup Ecore_IMF_Context_Module_Group - */ EAPI Eina_Bool ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos) { @@ -1020,26 +615,39 @@ ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *curs return result; } +EAPI Eina_Bool +ecore_imf_context_selection_get(Ecore_IMF_Context *ctx, char **text) +{ + Eina_Bool result = EINA_FALSE; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_selection_get"); + return EINA_FALSE; + } + + if (ctx->retrieve_selection_func) + { + result = ctx->retrieve_selection_func(ctx->retrieve_selection_data, ctx, text); + if (!result) + { + if (text) *text = NULL; + } + } + return result; +} + static void _ecore_imf_event_free_preedit(void *data __UNUSED__, void *event) { free(event); } -/** - * Adds ECORE_IMF_EVENT_PREEDIT_START to the event queue. - * - * ECORE_IMF_EVENT_PREEDIT_START should be added when a new preedit sequence starts. - * It's asynchronous method to put event to the event queue. - * ecore_imf_context_event_callback_call() can be used as synchronous method. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Module_Group - */ EAPI void ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx) { - Ecore_IMF_Event_Commit *ev; + Ecore_IMF_Event_Preedit_Start *ev; if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) { @@ -1054,20 +662,10 @@ ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx) ev, _ecore_imf_event_free_preedit, NULL); } -/** - * Adds ECORE_IMF_EVENT_PREEDIT_END to the event queue. - * - * ECORE_IMF_EVENT_PREEDIT_END should be added when a new preedit sequence has been completed or canceled. - * It's asynchronous method to put event to the event queue. - * ecore_imf_context_event_callback_call() can be used as synchronous method. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Module_Group - */ EAPI void ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx) { - Ecore_IMF_Event_Commit *ev; + Ecore_IMF_Event_Preedit_End *ev; if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) { @@ -1082,19 +680,10 @@ ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx) ev, _ecore_imf_event_free_preedit, NULL); } -/** - * Adds ECORE_IMF_EVENT_PREEDIT_CHANGED to the event queue. - * - * It's asynchronous method to put event to the event queue. - * ecore_imf_context_event_callback_call() can be used as synchronous method. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Module_Group - */ EAPI void ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context *ctx) { - Ecore_IMF_Event_Commit *ev; + Ecore_IMF_Event_Preedit_Changed *ev; if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) { @@ -1119,16 +708,6 @@ _ecore_imf_event_free_commit(void *data __UNUSED__, void *event) free(ev); } -/** - * Adds ECORE_IMF_EVENT_COMMIT to the event queue. - * - * It's asynchronous method to put event to the event queue. - * ecore_imf_context_event_callback_call() can be used as synchronous method. - * - * @param ctx An #Ecore_IMF_Context. - * @param str The committed string. - * @ingroup Ecore_IMF_Context_Module_Group - */ EAPI void ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str) { @@ -1146,7 +725,6 @@ ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str) ev->str = str ? strdup(str) : NULL; ecore_event_add(ECORE_IMF_EVENT_COMMIT, ev, _ecore_imf_event_free_commit, NULL); - } static void @@ -1155,21 +733,6 @@ _ecore_imf_event_free_delete_surrounding(void *data __UNUSED__, void *event) free(event); } -/** - * Adds ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue. - * - * Asks the widget that the input context is attached to to delete characters around the cursor position - * by adding the ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue. - * Note that offset and n_chars are in characters not in bytes. - * - * It's asynchronous method to put ECORE_IMF_EVENT_DELETE_SURROUNDING event to the event queue. - * ecore_imf_context_event_callback_call() can be used as synchronous method. - * - * @param ctx An #Ecore_IMF_Context. - * @param offset The start offset of surrounding to be deleted. - * @param n_chars The number of characters to be deleted. - * @ingroup Ecore_IMF_Context_Module_Group - */ EAPI void ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offset, int n_chars) { @@ -1190,38 +753,6 @@ ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offse ev, _ecore_imf_event_free_delete_surrounding, NULL); } -/** - * Add (register) a callback function to a given context event. - * - * This function adds a function callback to the context @p ctx when the - * event of type @p type occurs on it. The function pointer is @p - * func. - * - * The event type @p type to trigger the function may be one of - * #ECORE_IMF_CALLBACK_PREEDIT_START, #ECORE_IMF_CALLBACK_PREEDIT_END, - * #ECORE_IMF_CALLBACK_PREEDIT_CHANGED, #ECORE_IMF_CALLBACK_COMMIT and - * #ECORE_IMF_CALLBACK_DELETE_SURROUNDING. - * - * @param ctx Ecore_IMF_Context to attach a callback to. - * @param type The type of event that will trigger the callback - * @param func The (callback) function to be called when the event is - * triggered - * @param data The data pointer to be passed to @p func - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - * - * Example - * @code - * static void - * _imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info) - * { - * char *commit_str = event_info; - * // something to do - * } - * - * ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb, data); - * @endcode - */ EAPI void ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data) { @@ -1246,23 +777,6 @@ ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_ ctx->callbacks = eina_list_append(ctx->callbacks, fn); } -/** - * Delete (unregister) a callback function registered to a given - * context event. - * - * This function removes a function callback from the context @p ctx when the - * event of type @p type occurs on it. The function pointer is @p - * func. - * - * @see ecore_imf_context_event_callback_add() for more details - * - * @param ctx Ecore_IMF_Context to remove a callback from. - * @param type The type of event that was triggering the callback - * @param func The (callback) function that was to be called when the event was triggered - * @return the data pointer - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ EAPI void * ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func) { @@ -1293,23 +807,6 @@ ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_ return NULL; } -/** - * Call a given callback on the context @p ctx. - * - * ecore_imf_context_preedit_start_event_add(), ecore_imf_context_preedit_end_event_add(), - * ecore_imf_context_preedit_changed_event_add(), ecore_imf_context_commit_event_add() and - * ecore_imf_context_delete_surrounding_event_add() APIs are asynchronous - * because those API adds each event to the event queue. - * - * This API provides the way to call each callback function immediately. - * - * @param ctx Ecore_IMF_Context. - * @param type The type of event that will trigger the callback - * @param event_info The pointer to event specific struct or information to - * pass to the callback functions registered on this event - * @ingroup Ecore_IMF_Context_Module_Group - * @since 1.2.0 - */ EAPI void ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info) { @@ -1330,13 +827,6 @@ ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback } } -/** - * Ask the Input Method Context to show the control panel of using Input Method. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI void ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx) { @@ -1350,13 +840,6 @@ ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx) if (ctx->klass->control_panel_show) ctx->klass->control_panel_show(ctx); } -/** - * Ask the Input Method Context to hide the control panel of using Input Method. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI void ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx) { @@ -1370,13 +853,38 @@ ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx) if (ctx->klass->control_panel_hide) ctx->klass->control_panel_hide(ctx); } -/** - * Ask the Input Method Context to show the input panel (virtual keyboard). - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ +EAPI void +ecore_imf_context_input_hint_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Hints input_hints) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_hint_set"); + return; + } + + if (ctx->input_hints != input_hints) + { + if (ctx->klass->input_hint_set) + ctx->klass->input_hint_set(ctx, input_hints); + + ctx->input_hints = input_hints; + } +} + +EAPI Ecore_IMF_Input_Hints +ecore_imf_context_input_hint_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_hint_get"); + return ECORE_IMF_INPUT_HINT_NONE; + } + + return ctx->input_hints; +} + EAPI void ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx) { @@ -1387,16 +895,10 @@ ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx) return; } + show_req_ctx = ctx; if (ctx->klass->show) ctx->klass->show(ctx); } -/** - * Ask the Input Method Context to hide the input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI void ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx) { @@ -1410,14 +912,6 @@ ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx) if (ctx->klass->hide) ctx->klass->hide(ctx); } -/** - * Set the layout of the input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param layout see #Ecore_IMF_Input_Panel_Layout - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI void ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout) { @@ -1428,20 +922,15 @@ ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input return; } - if (ctx->klass->input_panel_layout_set) - ctx->klass->input_panel_layout_set(ctx, layout); + if (ctx->input_panel_layout != layout) + { + if (ctx->klass->input_panel_layout_set) + ctx->klass->input_panel_layout_set(ctx, layout); - ctx->input_panel_layout = layout; + ctx->input_panel_layout = layout; + } } -/** - * Get the layout of the current active input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @return layout see #Ecore_IMF_Input_Panel_Layout - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI Ecore_IMF_Input_Panel_Layout ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx) { @@ -1458,15 +947,32 @@ ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx) return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID; } -/** - * Set the language of the input panel. - * This API can be used when you want to show the English keyboard. - * - * @param ctx An #Ecore_IMF_Context. - * @param lang the language to be set to the input panel. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ +EAPI void +ecore_imf_context_input_panel_layout_variation_set(Ecore_IMF_Context *ctx, int variation) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_layout_variation_set"); + return; + } + + ctx->input_panel_layout_variation = variation; +} + +EAPI int +ecore_imf_context_input_panel_layout_variation_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_layout_variation_get"); + return 0; + } + + return ctx->input_panel_layout_variation; +} + EAPI void ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang) { @@ -1477,20 +983,15 @@ ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Inp return; } - if (ctx->klass->input_panel_language_set) ctx->klass->input_panel_language_set(ctx, lang); - ctx->input_panel_lang = lang; + if (ctx->input_panel_lang != lang) + { + if (ctx->klass->input_panel_language_set) + ctx->klass->input_panel_language_set(ctx, lang); + + ctx->input_panel_lang = lang; + } } -/** - * Get the language of the input panel. - * - * See @ref ecore_imf_context_input_panel_language_set for more details. - * - * @param ctx An #Ecore_IMF_Context. - * @return Ecore_IMF_Input_Panel_Lang - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI Ecore_IMF_Input_Panel_Lang ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx) { @@ -1504,15 +1005,6 @@ ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx) return ctx->input_panel_lang; } -/** - * Set whether the Input Method Context should request to show the input panel automatically - * when the widget has focus. - * - * @param ctx An #Ecore_IMF_Context. - * @param enabled If true, the input panel will be shown when the widget is clicked or has focus. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI void ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx, Eina_Bool enabled) @@ -1527,14 +1019,6 @@ ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx, ctx->input_panel_enabled = enabled; } -/** - * Get whether the Input Method Context requests to show the input panel automatically. - * - * @param ctx An #Ecore_IMF_Context. - * @return Return the attribute to show the input panel automatically - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ EAPI Eina_Bool ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx) { @@ -1548,18 +1032,6 @@ ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx) return ctx->input_panel_enabled; } -/** - * Set the input panel-specific data to deliver to the input panel. - * This API is used by applications to deliver specific data to the input panel. - * The data format MUST be negotiated by both application and the input panel. - * The size and format of data are defined by the input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param data The specific data to be set to the input panel. - * @param len the length of data, in bytes, to send to the input panel - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ EAPI void ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int len) { @@ -1576,15 +1048,6 @@ ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *dat ctx->klass->input_panel_imdata_set(ctx, data, len); } -/** - * Get the specific data of the current active input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param data The specific data to be got from the input panel - * @param len The length of data - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ EAPI void ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *len) { @@ -1601,16 +1064,6 @@ ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int ctx->klass->input_panel_imdata_get(ctx, data, len); } -/** - * Set the "return" key type. This type is used to set string or icon on the "return" key of the input panel. - * - * An input panel displays the string or icon associated with this type - * - * @param ctx An #Ecore_IMF_Context. - * @param return_key_type The type of "return" key on the input panel - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ EAPI void ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type) { @@ -1621,20 +1074,14 @@ ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx, Ecore_ return; } - ctx->input_panel_return_key_type = return_key_type; - if (ctx->klass->input_panel_return_key_type_set) ctx->klass->input_panel_return_key_type_set(ctx, return_key_type); + if (ctx->input_panel_return_key_type != return_key_type) + { + ctx->input_panel_return_key_type = return_key_type; + if (ctx->klass->input_panel_return_key_type_set) + ctx->klass->input_panel_return_key_type_set(ctx, return_key_type); + } } -/** - * Get the "return" key type. - * - * @see ecore_imf_context_input_panel_return_key_type_set() for more details - * - * @param ctx An #Ecore_IMF_Context. - * @return The type of "return" key on the input panel - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ EAPI Ecore_IMF_Input_Panel_Return_Key_Type ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx) { @@ -1648,14 +1095,6 @@ ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx) return ctx->input_panel_return_key_type; } -/** - * Set the return key on the input panel to be disabled. - * - * @param ctx An #Ecore_IMF_Context. - * @param disabled The state - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ EAPI void ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Eina_Bool disabled) { @@ -1666,18 +1105,14 @@ ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Ei return; } - ctx->input_panel_return_key_disabled = disabled; - if (ctx->klass->input_panel_return_key_disabled_set) ctx->klass->input_panel_return_key_disabled_set(ctx, disabled); + if (ctx->input_panel_return_key_disabled != disabled) + { + ctx->input_panel_return_key_disabled = disabled; + if (ctx->klass->input_panel_return_key_disabled_set) + ctx->klass->input_panel_return_key_disabled_set(ctx, disabled); + } } -/** - * Get whether the return key on the input panel should be disabled or not. - * - * @param ctx An #Ecore_IMF_Context. - * @return @c EINA_TRUE if it should be disabled. - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ EAPI Eina_Bool ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx) { @@ -1691,14 +1126,6 @@ ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx) return ctx->input_panel_return_key_disabled; } -/** - * Set the caps lock mode on the input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param mode Turn on caps lock on the input panel if @c EINA_TRUE. - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ EAPI void ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bool mode) { @@ -1709,20 +1136,15 @@ ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bo return; } - if (ctx->klass->input_panel_caps_lock_mode_set) - ctx->klass->input_panel_caps_lock_mode_set(ctx, mode); + if (ctx->input_panel_caps_lock_mode != mode) + { + if (ctx->klass->input_panel_caps_lock_mode_set) + ctx->klass->input_panel_caps_lock_mode_set(ctx, mode); - ctx->input_panel_caps_lock_mode = mode; + ctx->input_panel_caps_lock_mode = mode; + } } -/** - * Get the caps lock mode on the input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @return @c EINA_TRUE if the caps lock is turned on. - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ EAPI Eina_Bool ecore_imf_context_input_panel_caps_lock_mode_get(Ecore_IMF_Context *ctx) { @@ -1736,17 +1158,6 @@ ecore_imf_context_input_panel_caps_lock_mode_get(Ecore_IMF_Context *ctx) return ctx->input_panel_caps_lock_mode; } -/** - * Get the position of the current active input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param x top-left x co-ordinate of the input panel - * @param y top-left y co-ordinate of the input panel - * @param w width of the input panel - * @param h height of the input panel - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ EAPI void ecore_imf_context_input_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h) { @@ -1761,14 +1172,6 @@ ecore_imf_context_input_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int * ctx->klass->input_panel_geometry_get(ctx, x, y, w, h); } -/** - * Get state of current active input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @return The state of input panel. - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ EAPI Ecore_IMF_Input_Panel_State ecore_imf_context_input_panel_state_get(Ecore_IMF_Context *ctx) { @@ -1786,24 +1189,14 @@ ecore_imf_context_input_panel_state_get(Ecore_IMF_Context *ctx) return state; } -/** - * Register a callback function which will be called if there is change in input panel state,language,mode etc. - * In order to deregister the callback function - * Use @ref ecore_imf_context_input_panel_event_callback_del. - * - * @param ctx An #Ecore_IMF_Context - * @param type event type - * @param func the callback function - * @param data application-input panel specific data. - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ EAPI void ecore_imf_context_input_panel_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value), const void *data) { + Ecore_IMF_Input_Panel_Callback_Node *fn = NULL; + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) { ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, @@ -1811,24 +1204,27 @@ ecore_imf_context_input_panel_event_callback_add(Ecore_IMF_Context *ctx, return; } - if (ctx->klass->input_panel_event_callback_add) - ctx->klass->input_panel_event_callback_add(ctx, type, func, (void *)data); + if (!func) return; + + fn = calloc(1, sizeof (Ecore_IMF_Input_Panel_Callback_Node)); + if (!fn) return; + + fn->func = func; + fn->data = data; + fn->type = type; + + ctx->input_panel_callbacks = eina_list_append(ctx->input_panel_callbacks, fn); } -/** - * Unregister a callback function which will be called if there is change in input panel state, language, mode etc. - * - * @param ctx An #Ecore_IMF_Context. - * @param type An #Ecore_IMF_Input_Panel_Event. - * @param func the callback function - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ EAPI void ecore_imf_context_input_panel_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value)) { + Eina_List *l = NULL; + Eina_List *l_next = NULL; + Ecore_IMF_Input_Panel_Callback_Node *fn = NULL; + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) { ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, @@ -1836,21 +1232,75 @@ ecore_imf_context_input_panel_event_callback_del(Ecore_IMF_Context *ctx, return; } - if (ctx->klass->input_panel_event_callback_del) - ctx->klass->input_panel_event_callback_del(ctx, type, func); + if (!func) return; + if (!ctx->input_panel_callbacks) return; + + EINA_LIST_FOREACH_SAFE(ctx->input_panel_callbacks, l, l_next, fn) + { + if ((fn) && (fn->func == func) && (fn->type == type)) + { + free(fn); + ctx->input_panel_callbacks = eina_list_remove_list(ctx->input_panel_callbacks, l); + return; + } + } +} + +EAPI void +ecore_imf_context_input_panel_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, int value) +{ + Ecore_IMF_Input_Panel_Callback_Node *fn = NULL; + Eina_List *l = NULL; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_event_callback_call"); + return; + } + + EINA_LIST_FOREACH(ctx->input_panel_callbacks, l, fn) + { + if ((fn) && (fn->type == type) && (fn->func)) + { + fn->func(fn->data, ctx, value); + if (type == ECORE_IMF_INPUT_PANEL_STATE_EVENT && + value == ECORE_IMF_INPUT_PANEL_STATE_HIDE && + show_req_ctx == ctx) + show_req_ctx = NULL; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + break; + } + } +} + +EAPI void +ecore_imf_context_input_panel_event_callback_clear(Ecore_IMF_Context *ctx) +{ + Ecore_IMF_Input_Panel_Callback_Node *fn = NULL; + Eina_List *l = NULL; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_event_callback_clear"); + return; + } + + for (l = ctx->input_panel_callbacks; l;) + { + fn = (Ecore_IMF_Input_Panel_Callback_Node *)l->data; + + if (fn) + { + ctx->input_panel_callbacks = eina_list_remove(ctx->input_panel_callbacks, fn); + free (fn); + } + l = l->next; + } } -/** - * Get the current language locale of the input panel. - * - * ex) fr_FR - * - * @param ctx An #Ecore_IMF_Context. - * @param lang Location to store the retrieved language string. The - * string retrieved must be freed with free(). - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ EAPI void ecore_imf_context_input_panel_language_locale_get(Ecore_IMF_Context *ctx, char **lang) { @@ -1869,17 +1319,6 @@ ecore_imf_context_input_panel_language_locale_get(Ecore_IMF_Context *ctx, char * } } -/** - * Get the geometry information of the candidate panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param x top-left x co-ordinate of the candidate panel - * @param y top-left y co-ordinate of the candidate panel - * @param w width of the candidate panel - * @param h height of the candidate panel - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ EAPI void ecore_imf_context_candidate_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h) { @@ -1894,3 +1333,61 @@ ecore_imf_context_candidate_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, i ctx->klass->candidate_panel_geometry_get(ctx, x, y, w, h); } +EAPI void +ecore_imf_context_input_panel_show_on_demand_set(Ecore_IMF_Context *ctx, Eina_Bool ondemand) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_show_on_demand_set"); + return; + } + + ctx->input_panel_show_on_demand = ondemand; +} + +EAPI Eina_Bool +ecore_imf_context_input_panel_show_on_demand_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_show_on_demand_get"); + return EINA_FALSE; + } + + return ctx->input_panel_show_on_demand; +} + +EAPI void +ecore_imf_context_bidi_direction_set(Ecore_IMF_Context *ctx, Ecore_IMF_BiDi_Direction direction) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_bidi_direction_set"); + return; + } + + if (ctx->bidi_direction != direction) + { + if (ctx->klass->bidi_direction_set) + ctx->klass->bidi_direction_set(ctx, direction); + + ctx->bidi_direction = direction; + } +} + +EAPI Ecore_IMF_BiDi_Direction +ecore_imf_context_bidi_direction_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_bidi_direction_get"); + return ECORE_IMF_BIDI_DIRECTION_NEUTRAL; + } + + return ctx->bidi_direction; +} + diff --git a/src/lib/ecore_imf/ecore_imf_module.c b/src/lib/ecore_imf/ecore_imf_module.c index 946f5bc..e21fdc1 100644 --- a/src/lib/ecore_imf/ecore_imf_module.c +++ b/src/lib/ecore_imf/ecore_imf_module.c @@ -28,15 +28,7 @@ static Eina_Array *module_list = NULL; void ecore_imf_module_init(void) { - char *homedir; - module_list = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/ecore/immodules", 0, NULL, NULL); - homedir = eina_module_environment_path_get("HOME", "/.ecore/immodules"); - if (homedir) - { - module_list = eina_module_list_get(module_list, homedir, 0, NULL, NULL); - free(homedir); - } eina_module_list_load(module_list); } @@ -98,7 +90,7 @@ ecore_imf_module_context_create(const char *ctx_id) module = eina_hash_find(modules, ctx_id); if (module) { - ctx = module->create(); + if (!(ctx = module->create())) return NULL; if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) { ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, diff --git a/src/lib/ecore_imf/ecore_imf_private.h b/src/lib/ecore_imf/ecore_imf_private.h index b4ff0f2..c294b20 100644 --- a/src/lib/ecore_imf/ecore_imf_private.h +++ b/src/lib/ecore_imf/ecore_imf_private.h @@ -36,6 +36,7 @@ extern int _ecore_imf_log_dom; typedef struct _Ecore_IMF_Module Ecore_IMF_Module; typedef struct _Ecore_IMF_Func_Node Ecore_IMF_Func_Node; +typedef struct _Ecore_IMF_Input_Panel_Callback_Node Ecore_IMF_Input_Panel_Callback_Node; struct _Ecore_IMF_Context { @@ -49,14 +50,21 @@ struct _Ecore_IMF_Context Eina_Bool (*retrieve_surrounding_func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos); void *retrieve_surrounding_data; Eina_List *callbacks; + Eina_List *input_panel_callbacks; Ecore_IMF_Autocapital_Type autocapital_type; Ecore_IMF_Input_Panel_Layout input_panel_layout; Ecore_IMF_Input_Panel_Lang input_panel_lang; Ecore_IMF_Input_Panel_Return_Key_Type input_panel_return_key_type; + Ecore_IMF_Input_Hints input_hints; + Ecore_IMF_BiDi_Direction bidi_direction; + int input_panel_layout_variation; + Eina_Bool (*retrieve_selection_func)(void *data, Ecore_IMF_Context *ctx, char **text); + void *retrieve_selection_data; Eina_Bool allow_prediction : 1; Eina_Bool input_panel_enabled : 1; Eina_Bool input_panel_return_key_disabled : 1; Eina_Bool input_panel_caps_lock_mode : 1; + Eina_Bool input_panel_show_on_demand : 1; }; struct _Ecore_IMF_Module @@ -73,6 +81,13 @@ struct _Ecore_IMF_Func_Node Ecore_IMF_Callback_Type type; }; +struct _Ecore_IMF_Input_Panel_Callback_Node +{ + void (*func) (); + const void *data; + Ecore_IMF_Input_Panel_Event type; +}; + void ecore_imf_module_init(void); void ecore_imf_module_shutdown(void); Eina_List *ecore_imf_module_available_get(void); diff --git a/src/lib/ecore_imf_evas/Ecore_IMF_Evas.h b/src/lib/ecore_imf_evas/Ecore_IMF_Evas.h index 5f7cdb9..931c0d7 100644 --- a/src/lib/ecore_imf_evas/Ecore_IMF_Evas.h +++ b/src/lib/ecore_imf_evas/Ecore_IMF_Evas.h @@ -30,17 +30,151 @@ # endif #endif /* ! _WIN32 */ +/** + * @defgroup Ecore_IMF_Evas_Group Ecore Input Method Context Evas Helper Functions + * @ingroup Ecore_IMF_Lib_Group + * + * Helper functions to make it easy to use Evas with Ecore_IMF. + * Converts each event from Evas to the corresponding event of Ecore_IMF. + * + * An example of usage of these functions can be found at: + * @li @ref ecore_imf_example_c + */ + #ifdef __cplusplus extern "C" { #endif +/** + * Converts a "mouse_in" event from Evas to the corresponding event of Ecore_IMF. + * + * @since_tizen 2.3.1 + * + * @param evas_event The received Evas event. + * @param imf_event The location to store the converted Ecore_IMF event. + * @ingroup Ecore_IMF_Evas_Group + */ EAPI void ecore_imf_evas_event_mouse_in_wrap(Evas_Event_Mouse_In *evas_event, Ecore_IMF_Event_Mouse_In *imf_event); + +/** + * Converts a "mouse_out" event from Evas to the corresponding event of Ecore_IMF. + * + * @since_tizen 2.3.1 + * + * @param evas_event The received Evas event. + * @param imf_event The location to store the converted Ecore_IMF event. + * @ingroup Ecore_IMF_Evas_Group + */ EAPI void ecore_imf_evas_event_mouse_out_wrap(Evas_Event_Mouse_Out *evas_event, Ecore_IMF_Event_Mouse_Out *imf_event); + +/** + * Converts a "mouse_move" event from Evas to the corresponding event of Ecore_IMF. + * + * @since_tizen 2.3.1 + * + * @param evas_event The received Evas event. + * @param imf_event The location to store the converted Ecore_IMF event. + * @ingroup Ecore_IMF_Evas_Group + */ EAPI void ecore_imf_evas_event_mouse_move_wrap(Evas_Event_Mouse_Move *evas_event, Ecore_IMF_Event_Mouse_Move *imf_event); + +/** + * Converts a "mouse_down" event from Evas to the corresponding event of Ecore_IMF. + * + * @since_tizen 2.3.1 + * + * @param evas_event The received Evas event. + * @param imf_event The location to store the converted Ecore_IMF event. + * @ingroup Ecore_IMF_Evas_Group + */ EAPI void ecore_imf_evas_event_mouse_down_wrap(Evas_Event_Mouse_Down *evas_event, Ecore_IMF_Event_Mouse_Down *imf_event); + +/** + * Converts a "mouse_up" event from Evas to the corresponding event of Ecore_IMF. + * + * @since_tizen 2.3.1 + * + * @param evas_event The received Evas event. + * @param imf_event The location to store the converted Ecore_IMF event. + * @ingroup Ecore_IMF_Evas_Group + */ EAPI void ecore_imf_evas_event_mouse_up_wrap(Evas_Event_Mouse_Up *evas_event, Ecore_IMF_Event_Mouse_Up *imf_event); + +/** + * Converts a "mouse_wheel" event from Evas to the corresponding event of Ecore_IMF. + * + * @since_tizen 2.3.1 + * + * @param evas_event The received Evas event. + * @param imf_event The location to store the converted Ecore_IMF event. + * @ingroup Ecore_IMF_Evas_Group + */ EAPI void ecore_imf_evas_event_mouse_wheel_wrap(Evas_Event_Mouse_Wheel *evas_event, Ecore_IMF_Event_Mouse_Wheel *imf_event); + +/** + * Converts a "key_down" event from Evas to the corresponding event of Ecore_IMF. + * + * @since_tizen 2.3.1 + * + * @param evas_event The received Evas event. + * @param imf_event The location to store the converted Ecore_IMF event. + * @ingroup Ecore_IMF_Evas_Group + * + * Example + * @code + * static void + * _key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) + * { + * Evas_Event_Key_Down *ev = event_info; + * if (!ev->key) return; + * + * if (imf_context) + * { + * Ecore_IMF_Event_Key_Down ecore_ev; + * ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev); + * if (ecore_imf_context_filter_event(imf_context, + * ECORE_IMF_EVENT_KEY_DOWN, + * (Ecore_IMF_Event *)&ecore_ev)) + * return; + * } + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, data); + * @endcode + */ EAPI void ecore_imf_evas_event_key_down_wrap(Evas_Event_Key_Down *evas_event, Ecore_IMF_Event_Key_Down *imf_event); + +/** + * Converts a "key_up" event from Evas to the corresponding event of Ecore_IMF. + * + * @since_tizen 2.3.1 + * + * @param evas_event The received Evas event. + * @param imf_event The location to store the converted Ecore_IMF event. + * @ingroup Ecore_IMF_Evas_Group + * + * Example + * @code + * static void + * _key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) + * { + * Evas_Event_Key_Up *ev = event_info; + * if (!ev->key) return; + * + * if (imf_context) + * { + * Ecore_IMF_Event_Key_Up ecore_ev; + * ecore_imf_evas_event_key_up_wrap(ev, &ecore_ev); + * if (ecore_imf_context_filter_event(imf_context, + * ECORE_IMF_EVENT_KEY_UP, + * (Ecore_IMF_Event *)&ecore_ev)) + * return; + * } + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_UP, _key_up_cb, data); + * @endcode + */ EAPI void ecore_imf_evas_event_key_up_wrap(Evas_Event_Key_Up *evas_event, Ecore_IMF_Event_Key_Up *imf_event); #ifdef __cplusplus diff --git a/src/lib/ecore_imf_evas/ecore_imf_evas.c b/src/lib/ecore_imf_evas/ecore_imf_evas.c index cd6ec41..a16d431 100644 --- a/src/lib/ecore_imf_evas/ecore_imf_evas.c +++ b/src/lib/ecore_imf_evas/ecore_imf_evas.c @@ -1,7 +1,10 @@ + #ifdef HAVE_CONFIG_H # include #endif +#include +#include "ecore_private.h" #include "Ecore_IMF_Evas.h" /** @@ -10,8 +13,6 @@ * Helper functions to make it easy to use Evas with Ecore_IMF. * Converts each event from Evas to the corresponding event of Ecore_IMF. * - * An example of usage of these functions can be found at: - * @li @ref ecore_imf_example_c */ static const char *_ecore_imf_evas_event_empty = ""; @@ -299,6 +300,18 @@ EAPI void ecore_imf_evas_event_key_up_wrap(Evas_Event_Key_Up *evas_event, Ecore_IMF_Event_Key_Up *imf_event) { + if (!evas_event) + { + EINA_LOG_ERR("Evas event is missing"); + return; + } + + if (!imf_event) + { + EINA_LOG_ERR("Imf event is missing"); + return; + } + imf_event->keyname = evas_event->keyname ? evas_event->keyname : _ecore_imf_evas_event_empty; imf_event->key = evas_event->key ? evas_event->key : _ecore_imf_evas_event_empty; imf_event->string = evas_event->string ? evas_event->string : _ecore_imf_evas_event_empty; diff --git a/src/lib/ecore_input/Ecore_Input.h b/src/lib/ecore_input/Ecore_Input.h index 376703c..98fbecc 100644 --- a/src/lib/ecore_input/Ecore_Input.h +++ b/src/lib/ecore_input/Ecore_Input.h @@ -7,6 +7,8 @@ # include #endif +#include + #ifdef EAPI # undef EAPI #endif @@ -37,14 +39,15 @@ extern "C" { #endif - EAPI extern int ECORE_EVENT_KEY_DOWN; - EAPI extern int ECORE_EVENT_KEY_UP; - EAPI extern int ECORE_EVENT_MOUSE_BUTTON_DOWN; - EAPI extern int ECORE_EVENT_MOUSE_BUTTON_UP; - EAPI extern int ECORE_EVENT_MOUSE_MOVE; - EAPI extern int ECORE_EVENT_MOUSE_WHEEL; - EAPI extern int ECORE_EVENT_MOUSE_IN; - EAPI extern int ECORE_EVENT_MOUSE_OUT; +EAPI extern int ECORE_EVENT_KEY_DOWN; +EAPI extern int ECORE_EVENT_KEY_UP; +EAPI extern int ECORE_EVENT_MOUSE_BUTTON_DOWN; +EAPI extern int ECORE_EVENT_MOUSE_BUTTON_UP; +EAPI extern int ECORE_EVENT_MOUSE_MOVE; +EAPI extern int ECORE_EVENT_MOUSE_WHEEL; +EAPI extern int ECORE_EVENT_MOUSE_IN; +EAPI extern int ECORE_EVENT_MOUSE_OUT; +EAPI extern int ECORE_EVENT_MOUSE_BUTTON_CANCEL; #define ECORE_EVENT_MODIFIER_SHIFT 0x0001 #define ECORE_EVENT_MODIFIER_CTRL 0x0002 @@ -59,174 +62,174 @@ extern "C" { #define ECORE_EVENT_LOCK_SHIFT 0x0300 #define ECORE_EVENT_MODIFIER_ALTGR 0x0400 /**< @since 1.7 */ - typedef uintptr_t Ecore_Window; - typedef struct _Ecore_Event_Key Ecore_Event_Key; - typedef struct _Ecore_Event_Mouse_Button Ecore_Event_Mouse_Button; - typedef struct _Ecore_Event_Mouse_Wheel Ecore_Event_Mouse_Wheel; - typedef struct _Ecore_Event_Mouse_Move Ecore_Event_Mouse_Move; - typedef struct _Ecore_Event_Mouse_IO Ecore_Event_Mouse_IO; - typedef struct _Ecore_Event_Modifiers Ecore_Event_Modifiers; - - typedef enum _Ecore_Event_Modifier - { - ECORE_NONE, - ECORE_SHIFT, - ECORE_CTRL, - ECORE_ALT, - ECORE_WIN, - ECORE_SCROLL, - ECORE_CAPS, - ECORE_MODE, /**< @since 1.7 */ - ECORE_LAST - } Ecore_Event_Modifier; - - typedef enum _Ecore_Event_Press - { - ECORE_DOWN, - ECORE_UP - } Ecore_Event_Press; - - typedef enum _Ecore_Event_IO - { - ECORE_IN, - ECORE_OUT - } Ecore_Event_IO; - - typedef enum _Ecore_Compose_State - { - ECORE_COMPOSE_NONE, - ECORE_COMPOSE_MIDDLE, - ECORE_COMPOSE_DONE - } Ecore_Compose_State; - - struct _Ecore_Event_Key - { - const char *keyname; - const char *key; - const char *string; - const char *compose; - Ecore_Window window; - Ecore_Window root_window; - Ecore_Window event_window; - - unsigned int timestamp; - unsigned int modifiers; - - int same_screen; - }; - - struct _Ecore_Event_Mouse_Button - { - Ecore_Window window; - Ecore_Window root_window; - Ecore_Window event_window; - - unsigned int timestamp; - unsigned int modifiers; - unsigned int buttons; - unsigned int double_click; - unsigned int triple_click; - int same_screen; - - int x; - int y; - struct { - int x; - int y; - } root; - - struct { - int device; /* 0 if normal mouse, 1+ for other mouse-devices (eg multi-touch - other fingers) */ - double radius, radius_x, radius_y; /* radius of press point - radius_x and y if its an ellipse (radius is the average of the 2) */ - double pressure; /* pressure - 1.0 == normal, > 1.0 == more, 0.0 == none */ - double angle; /* angle relative to perpendicular (0.0 == perpendicular), in degrees */ - double x, y; /* same as x, y root.x, root.y, but with sub-pixel precision, if available */ - struct { - double x, y; - } root; - } multi; - }; - - struct _Ecore_Event_Mouse_Wheel - { - Ecore_Window window; - Ecore_Window root_window; - Ecore_Window event_window; - - unsigned int timestamp; - unsigned int modifiers; - - int same_screen; - int direction; - int z; - - int x; - int y; +typedef uintptr_t Ecore_Window; +typedef struct _Ecore_Event_Key Ecore_Event_Key; +typedef struct _Ecore_Event_Mouse_Button Ecore_Event_Mouse_Button; +typedef struct _Ecore_Event_Mouse_Wheel Ecore_Event_Mouse_Wheel; +typedef struct _Ecore_Event_Mouse_Move Ecore_Event_Mouse_Move; +typedef struct _Ecore_Event_Mouse_IO Ecore_Event_Mouse_IO; +typedef struct _Ecore_Event_Modifiers Ecore_Event_Modifiers; + +typedef enum _Ecore_Event_Modifier + { + ECORE_NONE, + ECORE_SHIFT, + ECORE_CTRL, + ECORE_ALT, + ECORE_WIN, + ECORE_SCROLL, + ECORE_CAPS, + ECORE_MODE, /**< @since 1.7 */ + ECORE_LAST + } Ecore_Event_Modifier; + +typedef enum _Ecore_Event_Press + { + ECORE_DOWN, + ECORE_UP + } Ecore_Event_Press; + +typedef enum _Ecore_Event_IO + { + ECORE_IN, + ECORE_OUT + } Ecore_Event_IO; + +typedef enum _Ecore_Compose_State + { + ECORE_COMPOSE_NONE, + ECORE_COMPOSE_MIDDLE, + ECORE_COMPOSE_DONE + } Ecore_Compose_State; + +struct _Ecore_Event_Key + { + const char *keyname; + const char *key; + const char *string; + const char *compose; + Ecore_Window window; + Ecore_Window root_window; + Ecore_Window event_window; + + unsigned int timestamp; + unsigned int modifiers; + + int same_screen; + }; + +struct _Ecore_Event_Mouse_Button + { + Ecore_Window window; + Ecore_Window root_window; + Ecore_Window event_window; + + unsigned int timestamp; + unsigned int modifiers; + unsigned int buttons; + unsigned int double_click; + unsigned int triple_click; + int same_screen; + + int x; + int y; + struct { + int x; + int y; + } root; + + struct { + int device; /* @c 0 if normal mouse, @c 1+ for other mouse-devices (eg multi-touch - other fingers) */ + double radius, radius_x, radius_y; /* radius of press point - radius_x and radius_y if it is an ellipse (radius is the average of the 2) */ + double pressure; /* pressure - 1.0 == normal, > 1.0 == more, 0.0 == none */ + double angle; /* angle relative to the perpendicular (0.0 == perpendicular), in degrees */ + double x, y; /* same as x, y, root.x, root.y, but with sub-pixel precision, if available */ struct { - int x; - int y; + double x, y; } root; - }; - - struct _Ecore_Event_Mouse_Move - { - Ecore_Window window; - Ecore_Window root_window; - Ecore_Window event_window; - - unsigned int timestamp; - unsigned int modifiers; - - int same_screen; - - int x; - int y; + } multi; + }; + +struct _Ecore_Event_Mouse_Wheel + { + Ecore_Window window; + Ecore_Window root_window; + Ecore_Window event_window; + + unsigned int timestamp; + unsigned int modifiers; + + int same_screen; + int direction; + int z; + + int x; + int y; + struct { + int x; + int y; + } root; + }; + +struct _Ecore_Event_Mouse_Move + { + Ecore_Window window; + Ecore_Window root_window; + Ecore_Window event_window; + + unsigned int timestamp; + unsigned int modifiers; + + int same_screen; + + int x; + int y; + struct { + int x; + int y; + } root; + + struct { + int device; /* @c 0 if normal mouse, @c 1+ for other mouse-devices (eg multi-touch - other fingers) */ + double radius, radius_x, radius_y; /* radius of press point - radius_x and radius_y if it is an ellipse (radius is the average of the 2) */ + double pressure; /* pressure - 1.0 == normal, > 1.0 == more, 0.0 == none */ + double angle; /* angle relative to the perpendicular (0.0 == perpendicular), in degrees */ + double x, y; /* same as x, y, root.x, root.y, but with sub-pixel precision, if available */ struct { - int x; - int y; + double x, y; } root; - - struct { - int device; /* 0 if normal mouse, 1+ for other mouse-devices (eg multi-touch - other fingers) */ - double radius, radius_x, radius_y; /* radius of press point - radius_x and y if its an ellipse (radius is the average of the 2) */ - double pressure; /* pressure - 1.0 == normal, > 1.0 == more, 0.0 == none */ - double angle; /* angle relative to perpendicular (0.0 == perpendicular), in degrees */ - double x, y; /* same as x, y root.x, root.y, but with sub-pixel precision, if available */ - struct { - double x, y; - } root; - } multi; - }; - - struct _Ecore_Event_Mouse_IO - { - Ecore_Window window; - Ecore_Window event_window; - - unsigned int timestamp; - unsigned int modifiers; - - int x; - int y; - }; - - struct _Ecore_Event_Modifiers - { - unsigned int size; - unsigned int array[ECORE_LAST]; - }; - - EAPI int ecore_event_init(void); - EAPI int ecore_event_shutdown(void); - - EAPI unsigned int ecore_event_modifier_mask(Ecore_Event_Modifier modifier); - EAPI Ecore_Event_Modifier ecore_event_update_modifier(const char *key, Ecore_Event_Modifiers *modifiers, int inc); - - /** - * @since 1.7 - */ - EAPI Ecore_Compose_State ecore_compose_get(const Eina_List *seq, char **seqstr_ret); - + } multi; + }; + +struct _Ecore_Event_Mouse_IO + { + Ecore_Window window; + Ecore_Window event_window; + + unsigned int timestamp; + unsigned int modifiers; + + int x; + int y; + }; + +struct _Ecore_Event_Modifiers + { + unsigned int size; + unsigned int array[ECORE_LAST]; + }; + +EAPI int ecore_event_init(void); +EAPI int ecore_event_shutdown(void); +EAPI unsigned int ecore_event_modifier_mask(Ecore_Event_Modifier modifier); +EAPI Ecore_Event_Modifier ecore_event_update_modifier(const char *key, Ecore_Event_Modifiers *modifiers, int inc); + +/** + * @internal + * @since 1.7 + */ +EAPI Ecore_Compose_State ecore_compose_get(const Eina_List *seq, char **seqstr_ret); + #ifdef __cplusplus } #endif diff --git a/src/lib/ecore_input/ecore_input.c b/src/lib/ecore_input/ecore_input.c index 8917409..8f4b1f9 100644 --- a/src/lib/ecore_input/ecore_input.c +++ b/src/lib/ecore_input/ecore_input.c @@ -30,6 +30,11 @@ ecore_event_init(void) { if (++_ecore_event_init_count != 1) return _ecore_event_init_count; + if (!ecore_init()) + { + _ecore_event_init_count--; + return 0; + } _ecore_input_log_dom = eina_log_domain_register ("ecore_input", ECORE_INPUT_DEFAULT_LOG_COLOR); @@ -67,6 +72,7 @@ ecore_event_shutdown(void) ECORE_EVENT_MOUSE_OUT = 0; eina_log_domain_unregister(_ecore_input_log_dom); _ecore_input_log_dom = -1; + ecore_shutdown(); return _ecore_event_init_count; } diff --git a/src/lib/ecore_input/ecore_input_compose.c b/src/lib/ecore_input/ecore_input_compose.c index 5335a7f..1c52f55 100644 --- a/src/lib/ecore_input/ecore_input_compose.c +++ b/src/lib/ecore_input/ecore_input_compose.c @@ -19,39 +19,82 @@ EAPI Ecore_Compose_State ecore_compose_get(const Eina_List *seq, char **seqstr_ret) { - Comp *c, *cend; + const char *p, *pend; + const unsigned char *psz; Eina_List *l; const char *s; int i = 0; + static int complen = 0; if (!seq) return ECORE_COMPOSE_NONE; l = (Eina_List *)seq; s = l->data; - cend = (Comp *)comp + (sizeof(comp) / sizeof(comp[0])); - for (c = (Comp *)comp; c->s && s;) + + // calc comp string len first time around + if (complen == 0) { - // doesn't match -> jump to next level entry - if (!(!strcmp(s, c->s))) + int zeros = 0; + + for (p = comp; ; p++) { - c += c->jump + 1; - if (c >= cend) + if (!(*p)) zeros++; + else zeros = 0; + // end marker - 4 0 bytes in a row + if (zeros == 4) { - return ECORE_COMPOSE_NONE; + complen = p - comp - 3; + break; } } + } + // walk special comp string/byte array looking for our match + pend = comp + complen; + for (p = comp; (p < pend) && s;) + { + int len, jump = -1, bsize = -1; + + len = strlen(p); + psz = (unsigned char *)(p + len + 1); + // decode jump amount to next entry + if (!(psz[0] & 0x80)) // < 0x80 + { + jump = psz[0]; + bsize = 1; + } + else if ((psz[0] & 0xc0) == 0xc0) // < 0x200000 + { + jump = (((psz[0] & 0x1f) << 16) | (psz[1] << 8) | (psz[2])); + bsize = 3; + } + else // >= 0x4000 + { + jump = (((psz[0] & 0x3f) << 8) | (psz[1])); + bsize = 2; + } + + // doesn't match -> jump to next level entry + if (!(!strcmp(s, p))) + { + p = p + jump; + if (p >= pend) return ECORE_COMPOSE_NONE; + } + // matches else { - cend = c + c->jump; + pend = p + jump; // advance to next sequence member l = l->next; i++; if (l) s = l->data; else s = NULL; - c++; - // if advanced item jump is an endpoint - it's the string we want - if (c->jump == 0) + p = p + len + 1 + bsize; + len = strlen(p); + psz = (unsigned char *)(p + len + 1); + // leaf nodes all are short so psz[0] has the full value + if ((len + 2) == psz[0]) { - if (seqstr_ret) *seqstr_ret = strdup(c->s); + // final leaf node, so return string here + if (seqstr_ret) *seqstr_ret = strdup(p); return ECORE_COMPOSE_DONE; } } diff --git a/src/lib/ecore_input/ecore_input_compose.h b/src/lib/ecore_input/ecore_input_compose.h index 9fbfb76..50dd5ca 100644 --- a/src/lib/ecore_input/ecore_input_compose.h +++ b/src/lib/ecore_input/ecore_input_compose.h @@ -1,9895 +1,9900 @@ -typedef struct _Comp Comp; -struct _Comp { - const char *s; - int jump; -}; +/* a magic compose table stuffed into a big string. it is actually a tree + * of strings with a string plus a number (number is encoded as binary + * values with upper bit 0 if value < 0x80, upper bit 0x80 if < 0x4000 or + * upper bit 0xc0 if < 0x200000 - and in each case being 1 byte, 2 bytes or + * 3 bytes in length for a number sequence. most are 1 byte for compactness. + * being a const string means this string is SHARED between all processes so + * it's loaded into memory only once at most. it's about as compact as you + * get (a bit less than 64k) UNLESS you get into some exotic compression + * algorithms. + */ -static const Comp comp[] = { - {"dead_breve", 124}, - {"dead_breve", 1}, - {"˘", 0}, - {"g", 1}, - {"ğ", 0}, - {"a", 1}, - {"ă", 0}, - {"Greek_IOTA", 1}, - {"Ῐ", 0}, - {"dead_grave", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"Greek_iota", 1}, - {"ῐ", 0}, - {"e", 1}, - {"ĕ", 0}, - {"agrave", 1}, - {"ằ", 0}, - {"o", 1}, - {"ŏ", 0}, - {"Greek_upsilon", 1}, - {"ῠ", 0}, - {"ahook", 1}, - {"ẳ", 0}, - {"dead_belowdot", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"space", 1}, - {"˘", 0}, - {"Cyrillic_I", 1}, - {"Й", 0}, - {"Multi_key", 15}, - {"exclam", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"comma", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"i", 1}, - {"ĭ", 0}, - {"dead_tilde", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"Cyrillic_a", 1}, - {"ӑ", 0}, - {"Cyrillic_U", 1}, - {"Ў", 0}, - {"nobreakspace", 1}, - {"̆", 0}, - {"u", 1}, - {"ŭ", 0}, - {"G", 1}, - {"Ğ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾰ", 0}, - {"atilde", 1}, - {"ẵ", 0}, - {"Cyrillic_ie", 1}, - {"ӗ", 0}, - {"E", 1}, - {"Ĕ", 0}, - {"Cyrillic_i", 1}, - {"й", 0}, - {"Atilde", 1}, - {"Ẵ", 0}, - {"Cyrillic_zhe", 1}, - {"ӂ", 0}, - {"Greek_alpha", 1}, - {"ᾰ", 0}, - {"Ahook", 1}, - {"Ẳ", 0}, - {"O", 1}, - {"Ŏ", 0}, - {"A", 1}, - {"Ă", 0}, - {"Cyrillic_A", 1}, - {"Ӑ", 0}, - {"dead_hook", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"Cyrillic_ZHE", 1}, - {"Ӂ", 0}, - {"Cyrillic_IE", 1}, - {"Ӗ", 0}, - {"Aacute", 1}, - {"Ắ", 0}, - {"dead_cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"aacute", 1}, - {"ắ", 0}, - {"dead_acute", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"Agrave", 1}, - {"Ằ", 0}, - {"I", 1}, - {"Ĭ", 0}, - {"U", 1}, - {"Ŭ", 0}, - {"Cyrillic_u", 1}, - {"ў", 0}, - {"Greek_UPSILON", 1}, - {"Ῠ", 0}, - {"dead_grave", 351}, - {"W", 1}, - {"Ẁ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"a", 1}, - {"à", 0}, - {"Greek_IOTA", 1}, - {"Ὶ", 0}, - {"dead_grave", 1}, - {"`", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ờ", 0}, - {"u", 1}, - {"ừ", 0}, - {"O", 1}, - {"Ờ", 0}, - {"U", 1}, - {"Ừ", 0}, - {"Greek_iota", 1}, - {"ὶ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ầ", 0}, - {"e", 1}, - {"ề", 0}, - {"o", 1}, - {"ồ", 0}, - {"E", 1}, - {"Ề", 0}, - {"O", 1}, - {"Ồ", 0}, - {"A", 1}, - {"Ầ", 0}, - {"Greek_OMICRON", 1}, - {"Ὸ", 0}, - {"Acircumflex", 1}, - {"Ầ", 0}, - {"Cyrillic_er", 1}, - {"р̀", 0}, - {"e", 1}, - {"è", 0}, - {"o", 1}, - {"ò", 0}, - {"Udiaeresis", 1}, - {"Ǜ", 0}, - {"Greek_upsilon", 1}, - {"ὺ", 0}, - {"uhorn", 1}, - {"ừ", 0}, - {"space", 1}, - {"`", 0}, - {"dead_macron", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"acircumflex", 1}, - {"ầ", 0}, - {"Ecircumflex", 1}, - {"Ề", 0}, - {"Cyrillic_I", 1}, - {"Ѝ", 0}, - {"y", 1}, - {"ỳ", 0}, - {"Multi_key", 115}, - {"b", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"parenright", 26}, - {"Greek_IOTA", 1}, - {"Ἲ", 0}, - {"Greek_iota", 1}, - {"ἲ", 0}, - {"Greek_OMICRON", 1}, - {"Ὂ", 0}, - {"Greek_upsilon", 1}, - {"ὒ", 0}, - {"Greek_epsilon", 1}, - {"ἒ", 0}, - {"Greek_ALPHA", 1}, - {"Ἂ", 0}, - {"Greek_omicron", 1}, - {"ὂ", 0}, - {"Greek_eta", 1}, - {"ἢ", 0}, - {"Greek_alpha", 1}, - {"ἂ", 0}, - {"Greek_ETA", 1}, - {"Ἢ", 0}, - {"Greek_EPSILON", 1}, - {"Ἒ", 0}, - {"Greek_omega", 1}, - {"ὢ", 0}, - {"Greek_OMEGA", 1}, - {"Ὢ", 0}, - {"quotedbl", 8}, - {"Greek_iota", 1}, - {"ῒ", 0}, - {"Greek_upsilon", 1}, - {"ῢ", 0}, - {"u", 1}, - {"ǜ", 0}, - {"U", 1}, - {"Ǜ", 0}, - {"plus", 8}, - {"o", 1}, - {"ờ", 0}, - {"u", 1}, - {"ừ", 0}, - {"O", 1}, - {"Ờ", 0}, - {"U", 1}, - {"Ừ", 0}, - {"underscore", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"macron", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"parenleft", 28}, - {"Greek_IOTA", 1}, - {"Ἳ", 0}, - {"Greek_iota", 1}, - {"ἳ", 0}, - {"Greek_OMICRON", 1}, - {"Ὃ", 0}, - {"Greek_upsilon", 1}, - {"ὓ", 0}, - {"Greek_epsilon", 1}, - {"ἓ", 0}, - {"Greek_ALPHA", 1}, - {"Ἃ", 0}, - {"Greek_omicron", 1}, - {"ὃ", 0}, - {"Greek_eta", 1}, - {"ἣ", 0}, - {"Greek_alpha", 1}, - {"ἃ", 0}, - {"Greek_ETA", 1}, - {"Ἣ", 0}, - {"Greek_EPSILON", 1}, - {"Ἓ", 0}, - {"Greek_omega", 1}, - {"ὣ", 0}, - {"Greek_OMEGA", 1}, - {"Ὣ", 0}, - {"Greek_UPSILON", 1}, - {"Ὓ", 0}, - {"U", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ầ", 0}, - {"e", 1}, - {"ề", 0}, - {"o", 1}, - {"ồ", 0}, - {"E", 1}, - {"Ề", 0}, - {"O", 1}, - {"Ồ", 0}, - {"A", 1}, - {"Ầ", 0}, - {"Cyrillic_O", 1}, - {"О̀", 0}, - {"i", 1}, - {"ì", 0}, - {"n", 1}, - {"ǹ", 0}, - {"Cyrillic_a", 1}, - {"а̀", 0}, - {"Ohorn", 1}, - {"Ờ", 0}, - {"ohorn", 1}, - {"ờ", 0}, - {"Cyrillic_ER", 1}, - {"Р̀", 0}, - {"Greek_epsilon", 1}, - {"ὲ", 0}, - {"Cyrillic_U", 1}, - {"У̀", 0}, - {"nobreakspace", 1}, - {"̀", 0}, - {"V", 1}, - {"Ǜ", 0}, - {"Ocircumflex", 1}, - {"Ồ", 0}, - {"omacron", 1}, - {"ṑ", 0}, - {"ocircumflex", 1}, - {"ồ", 0}, - {"u", 1}, - {"ù", 0}, - {"Greek_ALPHA", 1}, - {"Ὰ", 0}, - {"Cyrillic_ie", 1}, - {"ѐ", 0}, - {"emacron", 1}, - {"ḕ", 0}, - {"E", 1}, - {"È", 0}, - {"Greek_iotadieresis", 1}, - {"ῒ", 0}, - {"Y", 1}, - {"Ỳ", 0}, - {"Cyrillic_i", 1}, - {"ѝ", 0}, - {"dead_dasia", 28}, - {"Greek_IOTA", 1}, - {"Ἳ", 0}, - {"Greek_iota", 1}, - {"ἳ", 0}, - {"Greek_OMICRON", 1}, - {"Ὃ", 0}, - {"Greek_upsilon", 1}, - {"ὓ", 0}, - {"Greek_epsilon", 1}, - {"ἓ", 0}, - {"Greek_ALPHA", 1}, - {"Ἃ", 0}, - {"Greek_omicron", 1}, - {"ὃ", 0}, - {"Greek_eta", 1}, - {"ἣ", 0}, - {"Greek_alpha", 1}, - {"ἃ", 0}, - {"Greek_ETA", 1}, - {"Ἣ", 0}, - {"Greek_EPSILON", 1}, - {"Ἓ", 0}, - {"Greek_omega", 1}, - {"ὣ", 0}, - {"Greek_OMEGA", 1}, - {"Ὣ", 0}, - {"Greek_UPSILON", 1}, - {"Ὓ", 0}, - {"Greek_upsilondieresis", 1}, - {"ῢ", 0}, - {"Greek_omicron", 1}, - {"ὸ", 0}, - {"Greek_eta", 1}, - {"ὴ", 0}, - {"Abreve", 1}, - {"Ằ", 0}, - {"dead_psili", 26}, - {"Greek_IOTA", 1}, - {"Ἲ", 0}, - {"Greek_iota", 1}, - {"ἲ", 0}, - {"Greek_OMICRON", 1}, - {"Ὂ", 0}, - {"Greek_upsilon", 1}, - {"ὒ", 0}, - {"Greek_epsilon", 1}, - {"ἒ", 0}, - {"Greek_ALPHA", 1}, - {"Ἂ", 0}, - {"Greek_omicron", 1}, - {"ὂ", 0}, - {"Greek_eta", 1}, - {"ἢ", 0}, - {"Greek_alpha", 1}, - {"ἂ", 0}, - {"Greek_ETA", 1}, - {"Ἢ", 0}, - {"Greek_EPSILON", 1}, - {"Ἒ", 0}, - {"Greek_omega", 1}, - {"ὢ", 0}, - {"Greek_OMEGA", 1}, - {"Ὢ", 0}, - {"Greek_alpha", 1}, - {"ὰ", 0}, - {"ecircumflex", 1}, - {"ề", 0}, - {"w", 1}, - {"ẁ", 0}, - {"Greek_ETA", 1}, - {"Ὴ", 0}, - {"Cyrillic_o", 1}, - {"о̀", 0}, - {"Emacron", 1}, - {"Ḕ", 0}, - {"v", 1}, - {"ǜ", 0}, - {"O", 1}, - {"Ò", 0}, - {"abreve", 1}, - {"ằ", 0}, - {"A", 1}, - {"À", 0}, - {"Greek_EPSILON", 1}, - {"Ὲ", 0}, - {"Cyrillic_A", 1}, - {"А̀", 0}, - {"Omacron", 1}, - {"Ṑ", 0}, - {"Cyrillic_IE", 1}, - {"Ѐ", 0}, - {"Greek_omega", 1}, - {"ὼ", 0}, - {"dead_diaeresis", 8}, - {"Greek_iota", 1}, - {"ῒ", 0}, - {"Greek_upsilon", 1}, - {"ῢ", 0}, - {"u", 1}, - {"ǜ", 0}, - {"U", 1}, - {"Ǜ", 0}, - {"Uhorn", 1}, - {"Ừ", 0}, - {"Greek_OMEGA", 1}, - {"Ὼ", 0}, - {"udiaeresis", 1}, - {"ǜ", 0}, - {"I", 1}, - {"Ì", 0}, - {"N", 1}, - {"Ǹ", 0}, - {"U", 1}, - {"Ù", 0}, - {"Cyrillic_u", 1}, - {"у̀", 0}, - {"Greek_UPSILON", 1}, - {"Ὺ", 0}, - {"dead_horn", 99}, - {"Uhook", 1}, - {"Ử", 0}, - {"Obelowdot", 1}, - {"Ợ", 0}, - {"Ograve", 1}, - {"Ờ", 0}, - {"dead_grave", 8}, - {"o", 1}, - {"ờ", 0}, - {"u", 1}, - {"ừ", 0}, - {"O", 1}, - {"Ờ", 0}, - {"U", 1}, - {"Ừ", 0}, - {"dead_horn", 1}, - {"̛", 0}, - {"Oacute", 1}, - {"Ớ", 0}, - {"ohook", 1}, - {"ở", 0}, - {"o", 1}, - {"ơ", 0}, - {"Utilde", 1}, - {"Ữ", 0}, - {"dead_belowdot", 8}, - {"o", 1}, - {"ợ", 0}, - {"u", 1}, - {"ự", 0}, - {"O", 1}, - {"Ợ", 0}, - {"U", 1}, - {"Ự", 0}, - {"space", 1}, - {"̛", 0}, - {"ubelowdot", 1}, - {"ự", 0}, - {"oacute", 1}, - {"ớ", 0}, - {"uhook", 1}, - {"ử", 0}, - {"dead_tilde", 8}, - {"o", 1}, - {"ỡ", 0}, - {"u", 1}, - {"ữ", 0}, - {"O", 1}, - {"Ỡ", 0}, - {"U", 1}, - {"Ữ", 0}, - {"Uacute", 1}, - {"Ứ", 0}, - {"Ugrave", 1}, - {"Ừ", 0}, - {"nobreakspace", 1}, - {"̛", 0}, - {"uacute", 1}, - {"ứ", 0}, - {"u", 1}, - {"ư", 0}, - {"otilde", 1}, - {"ỡ", 0}, - {"utilde", 1}, - {"ữ", 0}, - {"Otilde", 1}, - {"Ỡ", 0}, - {"ograve", 1}, - {"ờ", 0}, - {"Ohook", 1}, - {"Ở", 0}, - {"O", 1}, - {"Ơ", 0}, - {"Ubelowdot", 1}, - {"Ự", 0}, - {"dead_hook", 8}, - {"o", 1}, - {"ở", 0}, - {"u", 1}, - {"ử", 0}, - {"O", 1}, - {"Ở", 0}, - {"U", 1}, - {"Ử", 0}, - {"ugrave", 1}, - {"ừ", 0}, - {"obelowdot", 1}, - {"ợ", 0}, - {"dead_acute", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"U", 1}, - {"Ư", 0}, - {"dead_circumflex", 335}, - {"minus", 1}, - {"⁻", 0}, - {"W", 1}, - {"Ŵ", 0}, - {"g", 1}, - {"ĝ", 0}, - {"a", 1}, - {"â", 0}, - {"Ograve", 1}, - {"Ồ", 0}, - {"dead_circumflex", 1}, - {"^", 0}, - {"dead_grave", 12}, - {"a", 1}, - {"ầ", 0}, - {"e", 1}, - {"ề", 0}, - {"o", 1}, - {"ồ", 0}, - {"E", 1}, - {"Ề", 0}, - {"O", 1}, - {"Ồ", 0}, - {"A", 1}, - {"Ầ", 0}, - {"Ehook", 1}, - {"Ể", 0}, - {"1", 1}, - {"¹", 0}, - {"C", 1}, - {"Ĉ", 0}, - {"KP_4", 1}, - {"⁴", 0}, - {"Oacute", 1}, - {"Ố", 0}, - {"Cyrillic_er", 1}, - {"р̂", 0}, - {"ohook", 1}, - {"ổ", 0}, - {"e", 1}, - {"ê", 0}, - {"agrave", 1}, - {"ầ", 0}, - {"KP_6", 1}, - {"⁶", 0}, - {"o", 1}, - {"ô", 0}, - {"ahook", 1}, - {"ẩ", 0}, - {"dead_belowdot", 12}, - {"a", 1}, - {"ậ", 0}, - {"e", 1}, - {"ệ", 0}, - {"o", 1}, - {"ộ", 0}, - {"E", 1}, - {"Ệ", 0}, - {"O", 1}, - {"Ộ", 0}, - {"A", 1}, - {"Ậ", 0}, - {"space", 1}, - {"^", 0}, - {"KP_8", 1}, - {"⁸", 0}, - {"Etilde", 1}, - {"Ễ", 0}, - {"Cyrillic_I", 1}, - {"И̂", 0}, - {"y", 1}, - {"ŷ", 0}, - {"Multi_key", 83}, - {"exclam", 12}, - {"a", 1}, - {"ậ", 0}, - {"e", 1}, - {"ệ", 0}, - {"o", 1}, - {"ộ", 0}, - {"E", 1}, - {"Ệ", 0}, - {"O", 1}, - {"Ộ", 0}, - {"A", 1}, - {"Ậ", 0}, - {"t", 4}, - {"M", 1}, - {"™", 0}, - {"m", 1}, - {"™", 0}, - {"underbar", 24}, - {"a", 1}, - {"ª", 0}, - {"o", 1}, - {"º", 0}, - {"l", 1}, - {"ˡ", 0}, - {"y", 1}, - {"ʸ", 0}, - {"i", 1}, - {"ⁱ", 0}, - {"n", 1}, - {"ⁿ", 0}, - {"j", 1}, - {"ʲ", 0}, - {"x", 1}, - {"ˣ", 0}, - {"w", 1}, - {"ʷ", 0}, - {"r", 1}, - {"ʳ", 0}, - {"s", 1}, - {"ˢ", 0}, - {"h", 1}, - {"ʰ", 0}, - {"S", 4}, - {"M", 1}, - {"℠", 0}, - {"m", 1}, - {"℠", 0}, - {"underscore", 24}, - {"a", 1}, - {"ª", 0}, - {"o", 1}, - {"º", 0}, - {"l", 1}, - {"ˡ", 0}, - {"y", 1}, - {"ʸ", 0}, - {"i", 1}, - {"ⁱ", 0}, - {"n", 1}, - {"ⁿ", 0}, - {"j", 1}, - {"ʲ", 0}, - {"x", 1}, - {"ˣ", 0}, - {"w", 1}, - {"ʷ", 0}, - {"r", 1}, - {"ʳ", 0}, - {"s", 1}, - {"ˢ", 0}, - {"h", 1}, - {"ʰ", 0}, - {"s", 4}, - {"M", 1}, - {"℠", 0}, - {"m", 1}, - {"℠", 0}, - {"T", 4}, - {"M", 1}, - {"™", 0}, - {"m", 1}, - {"™", 0}, - {"oacute", 1}, - {"ố", 0}, - {"Cyrillic_O", 1}, - {"О̂", 0}, - {"i", 1}, - {"î", 0}, - {"KP_9", 1}, - {"⁹", 0}, - {"equal", 1}, - {"⁼", 0}, - {"KP_Space", 1}, - {"²", 0}, - {"dead_tilde", 12}, - {"a", 1}, - {"ẫ", 0}, - {"e", 1}, - {"ễ", 0}, - {"o", 1}, - {"ỗ", 0}, - {"E", 1}, - {"Ễ", 0}, - {"O", 1}, - {"Ỗ", 0}, - {"A", 1}, - {"Ẫ", 0}, - {"7", 1}, - {"⁷", 0}, - {"Cyrillic_a", 1}, - {"а̂", 0}, - {"j", 1}, - {"ĵ", 0}, - {"parenright", 1}, - {"⁾", 0}, - {"Eacute", 1}, - {"Ế", 0}, - {"Cyrillic_ER", 1}, - {"Р̂", 0}, - {"KP_7", 1}, - {"⁷", 0}, - {"Cyrillic_U", 1}, - {"У̂", 0}, - {"nobreakspace", 1}, - {"̂", 0}, - {"u", 1}, - {"û", 0}, - {"z", 1}, - {"ẑ", 0}, - {"G", 1}, - {"Ĝ", 0}, - {"otilde", 1}, - {"ỗ", 0}, - {"H", 1}, - {"Ĥ", 0}, - {"8", 1}, - {"⁸", 0}, - {"KP_1", 1}, - {"¹", 0}, - {"atilde", 1}, - {"ẫ", 0}, - {"3", 1}, - {"³", 0}, - {"Cyrillic_ie", 1}, - {"е̂", 0}, - {"E", 1}, - {"Ê", 0}, - {"S", 1}, - {"Ŝ", 0}, - {"2", 1}, - {"²", 0}, - {"Y", 1}, - {"Ŷ", 0}, - {"Cyrillic_i", 1}, - {"и̂", 0}, - {"Otilde", 1}, - {"Ỗ", 0}, - {"Atilde", 1}, - {"Ẫ", 0}, - {"egrave", 1}, - {"ề", 0}, - {"ograve", 1}, - {"ồ", 0}, - {"plus", 1}, - {"⁺", 0}, - {"6", 1}, - {"⁶", 0}, - {"Ahook", 1}, - {"Ẩ", 0}, - {"w", 1}, - {"ŵ", 0}, - {"Ohook", 1}, - {"Ổ", 0}, - {"Cyrillic_o", 1}, - {"о̂", 0}, - {"4", 1}, - {"⁴", 0}, - {"KP_3", 1}, - {"³", 0}, - {"eacute", 1}, - {"ế", 0}, - {"J", 1}, - {"Ĵ", 0}, - {"O", 1}, - {"Ô", 0}, - {"s", 1}, - {"ŝ", 0}, - {"Z", 1}, - {"Ẑ", 0}, - {"KP_0", 1}, - {"⁰", 0}, - {"A", 1}, - {"Â", 0}, - {"c", 1}, - {"ĉ", 0}, - {"KP_Add", 1}, - {"⁺", 0}, - {"KP_2", 1}, - {"²", 0}, - {"Cyrillic_A", 1}, - {"А̂", 0}, - {"dead_hook", 12}, - {"a", 1}, - {"ẩ", 0}, - {"e", 1}, - {"ể", 0}, - {"o", 1}, - {"ổ", 0}, - {"E", 1}, - {"Ể", 0}, - {"O", 1}, - {"Ổ", 0}, - {"A", 1}, - {"Ẩ", 0}, - {"5", 1}, - {"⁵", 0}, - {"KP_5", 1}, - {"⁵", 0}, - {"9", 1}, - {"⁹", 0}, - {"Cyrillic_IE", 1}, - {"Е̂", 0}, - {"Egrave", 1}, - {"Ề", 0}, - {"0", 1}, - {"⁰", 0}, - {"Aacute", 1}, - {"Ấ", 0}, - {"etilde", 1}, - {"ễ", 0}, - {"aacute", 1}, - {"ấ", 0}, - {"dead_acute", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Agrave", 1}, - {"Ầ", 0}, - {"parenleft", 1}, - {"⁽", 0}, - {"h", 1}, - {"ĥ", 0}, - {"I", 1}, - {"Î", 0}, - {"ehook", 1}, - {"ể", 0}, - {"U", 1}, - {"Û", 0}, - {"Cyrillic_u", 1}, - {"у̂", 0}, - {"KP_Equal", 1}, - {"⁼", 0}, - {"dead_currency", 103}, - {"W", 1}, - {"₩", 0}, - {"g", 1}, - {"₲", 0}, - {"a", 1}, - {"؋", 0}, - {"dead_currency", 1}, - {"¤", 0}, - {"C", 1}, - {"₡", 0}, - {"e", 1}, - {"€", 0}, - {"F", 1}, - {"₣", 0}, - {"o", 1}, - {"௹", 0}, - {"l", 1}, - {"£", 0}, - {"t", 1}, - {"৳", 0}, - {"thorn", 1}, - {"৲", 0}, - {"space", 1}, - {"¤", 0}, - {"y", 1}, - {"¥", 0}, - {"b", 1}, - {"฿", 0}, - {"i", 1}, - {"﷼", 0}, - {"k", 1}, - {"₭", 0}, - {"n", 1}, - {"₦", 0}, - {"ccedilla", 1}, - {"₵", 0}, - {"nobreakspace", 1}, - {"¤", 0}, - {"u", 1}, - {"元", 0}, - {"G", 1}, - {"₲", 0}, - {"H", 1}, - {"₴", 0}, - {"E", 1}, - {"₠", 0}, - {"S", 1}, - {"$", 0}, - {"Y", 1}, - {"円", 0}, - {"f", 1}, - {"ƒ", 0}, - {"d", 1}, - {"₫", 0}, - {"D", 1}, - {"₯", 0}, - {"w", 1}, - {"₩", 0}, - {"p", 1}, - {"₰", 0}, - {"P", 1}, - {"₧", 0}, - {"M", 1}, - {"ℳ", 0}, - {"O", 1}, - {"૱", 0}, - {"m", 1}, - {"₥", 0}, - {"r", 1}, - {"₢", 0}, - {"s", 1}, - {"₪", 0}, - {"A", 1}, - {"₳", 0}, - {"R", 1}, - {"₨", 0}, - {"THORN", 1}, - {"৲", 0}, - {"c", 1}, - {"¢", 0}, - {"L", 1}, - {"₤", 0}, - {"T", 1}, - {"₮", 0}, - {"Ccedilla", 1}, - {"₵", 0}, - {"K", 1}, - {"₭", 0}, - {"B", 1}, - {"₱", 0}, - {"dead_cedilla", 4}, - {"C", 1}, - {"₵", 0}, - {"c", 1}, - {"₵", 0}, - {"h", 1}, - {"₴", 0}, - {"I", 1}, - {"៛", 0}, - {"N", 1}, - {"₦", 0}, - {"U", 1}, - {"圓", 0}, - {"dead_belowdiaeresis", 7}, - {"u", 1}, - {"ṳ", 0}, - {"dead_diaeresis", 2}, - {"equal", 1}, - {"⩷", 0}, - {"U", 1}, - {"Ṳ", 0}, - {"dead_belowdot", 167}, - {"minus", 1}, - {"⨪", 0}, - {"W", 1}, - {"Ẉ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"a", 1}, - {"ạ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ậ", 0}, - {"e", 1}, - {"ệ", 0}, - {"o", 1}, - {"ộ", 0}, - {"E", 1}, - {"Ệ", 0}, - {"O", 1}, - {"Ộ", 0}, - {"A", 1}, - {"Ậ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ợ", 0}, - {"u", 1}, - {"ự", 0}, - {"O", 1}, - {"Ợ", 0}, - {"U", 1}, - {"Ự", 0}, - {"Acircumflex", 1}, - {"Ậ", 0}, - {"e", 1}, - {"ẹ", 0}, - {"o", 1}, - {"ọ", 0}, - {"l", 1}, - {"ḷ", 0}, - {"t", 1}, - {"ṭ", 0}, - {"dead_belowdot", 1}, - {"̣", 0}, - {"uhorn", 1}, - {"ự", 0}, - {"space", 1}, - {"̣", 0}, - {"dead_macron", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"acircumflex", 1}, - {"ậ", 0}, - {"Ecircumflex", 1}, - {"Ệ", 0}, - {"y", 1}, - {"ỵ", 0}, - {"b", 1}, - {"ḅ", 0}, - {"Multi_key", 9}, - {"plus", 8}, - {"o", 1}, - {"ợ", 0}, - {"u", 1}, - {"ự", 0}, - {"O", 1}, - {"Ợ", 0}, - {"U", 1}, - {"Ự", 0}, - {"i", 1}, - {"ị", 0}, - {"k", 1}, - {"ḳ", 0}, - {"n", 1}, - {"ṇ", 0}, - {"equal", 1}, - {"⩦", 0}, - {"Ohorn", 1}, - {"Ợ", 0}, - {"ohorn", 1}, - {"ợ", 0}, - {"sabovedot", 1}, - {"ṩ", 0}, - {"nobreakspace", 1}, - {"̣", 0}, - {"V", 1}, - {"Ṿ", 0}, - {"Ocircumflex", 1}, - {"Ộ", 0}, - {"ocircumflex", 1}, - {"ộ", 0}, - {"u", 1}, - {"ụ", 0}, - {"z", 1}, - {"ẓ", 0}, - {"H", 1}, - {"Ḥ", 0}, - {"E", 1}, - {"Ẹ", 0}, - {"S", 1}, - {"Ṣ", 0}, - {"Y", 1}, - {"Ỵ", 0}, - {"d", 1}, - {"ḍ", 0}, - {"D", 1}, - {"Ḍ", 0}, - {"Abreve", 1}, - {"Ặ", 0}, - {"plus", 1}, - {"⨥", 0}, - {"ecircumflex", 1}, - {"ệ", 0}, - {"dead_abovedot", 4}, - {"S", 1}, - {"Ṩ", 0}, - {"s", 1}, - {"ṩ", 0}, - {"w", 1}, - {"ẉ", 0}, - {"v", 1}, - {"ṿ", 0}, - {"M", 1}, - {"Ṃ", 0}, - {"O", 1}, - {"Ọ", 0}, - {"abreve", 1}, - {"ặ", 0}, - {"m", 1}, - {"ṃ", 0}, - {"r", 1}, - {"ṛ", 0}, - {"s", 1}, - {"ṣ", 0}, - {"Z", 1}, - {"Ẓ", 0}, - {"A", 1}, - {"Ạ", 0}, - {"R", 1}, - {"Ṛ", 0}, - {"L", 1}, - {"Ḷ", 0}, - {"T", 1}, - {"Ṭ", 0}, - {"K", 1}, - {"Ḳ", 0}, - {"B", 1}, - {"Ḅ", 0}, - {"Sabovedot", 1}, - {"Ṩ", 0}, - {"Uhorn", 1}, - {"Ự", 0}, - {"h", 1}, - {"ḥ", 0}, - {"I", 1}, - {"Ị", 0}, - {"N", 1}, - {"Ṇ", 0}, - {"U", 1}, - {"Ụ", 0}, - {"dead_macron", 224}, - {"adiaeresis", 1}, - {"ǟ", 0}, - {"g", 1}, - {"ḡ", 0}, - {"a", 1}, - {"ā", 0}, - {"Greek_IOTA", 1}, - {"Ῑ", 0}, - {"Ograve", 1}, - {"Ṑ", 0}, - {"dead_grave", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"Greek_iota", 1}, - {"ῑ", 0}, - {"Oacute", 1}, - {"Ṓ", 0}, - {"Cyrillic_er", 1}, - {"р̄", 0}, - {"e", 1}, - {"ē", 0}, - {"o", 1}, - {"ō", 0}, - {"Udiaeresis", 1}, - {"Ǖ", 0}, - {"Greek_upsilon", 1}, - {"ῡ", 0}, - {"dead_belowdot", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"space", 1}, - {"¯", 0}, - {"dead_macron", 1}, - {"¯", 0}, - {"Cyrillic_I", 1}, - {"Ӣ", 0}, - {"y", 1}, - {"ȳ", 0}, - {"Multi_key", 41}, - {"period", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"exclam", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"quotedbl", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"asciitilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"semicolon", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"oacute", 1}, - {"ṓ", 0}, - {"Cyrillic_O", 1}, - {"О̄", 0}, - {"i", 1}, - {"ī", 0}, - {"dead_tilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"Cyrillic_a", 1}, - {"а̄", 0}, - {"Eacute", 1}, - {"Ḗ", 0}, - {"Cyrillic_ER", 1}, - {"Р̄", 0}, - {"Cyrillic_U", 1}, - {"Ӯ", 0}, - {"nobreakspace", 1}, - {"̄", 0}, - {"V", 1}, - {"Ǖ", 0}, - {"AE", 1}, - {"Ǣ", 0}, - {"u", 1}, - {"ū", 0}, - {"G", 1}, - {"Ḡ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾱ", 0}, - {"otilde", 1}, - {"ȭ", 0}, - {"Cyrillic_ie", 1}, - {"е̄", 0}, - {"E", 1}, - {"Ē", 0}, - {"Y", 1}, - {"Ȳ", 0}, - {"Cyrillic_i", 1}, - {"ӣ", 0}, - {"dead_ogonek", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"odiaeresis", 1}, - {"ȫ", 0}, - {"Otilde", 1}, - {"Ȭ", 0}, - {"egrave", 1}, - {"ḕ", 0}, - {"dead_greek", 12}, - {"a", 1}, - {"ᾱ", 0}, - {"i", 1}, - {"ῑ", 0}, - {"u", 1}, - {"ῡ", 0}, - {"A", 1}, - {"Ᾱ", 0}, - {"I", 1}, - {"Ῑ", 0}, - {"U", 1}, - {"Ῡ", 0}, - {"ograve", 1}, - {"ṑ", 0}, - {"Greek_alpha", 1}, - {"ᾱ", 0}, - {"dead_abovedot", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"Cyrillic_o", 1}, - {"о̄", 0}, - {"eacute", 1}, - {"ḗ", 0}, - {"v", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ō", 0}, - {"A", 1}, - {"Ā", 0}, - {"Odiaeresis", 1}, - {"Ȫ", 0}, - {"Cyrillic_A", 1}, - {"А̄", 0}, - {"Cyrillic_IE", 1}, - {"Е̄", 0}, - {"Egrave", 1}, - {"Ḕ", 0}, - {"dead_diaeresis", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"Adiaeresis", 1}, - {"Ǟ", 0}, - {"dead_acute", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"udiaeresis", 1}, - {"ǖ", 0}, - {"I", 1}, - {"Ī", 0}, - {"U", 1}, - {"Ū", 0}, - {"Cyrillic_u", 1}, - {"ӯ", 0}, - {"ae", 1}, - {"ǣ", 0}, - {"Greek_UPSILON", 1}, - {"Ῡ", 0}, - {"dead_doublegrave", 24}, - {"Cyrillic_er", 1}, - {"р̏", 0}, - {"Cyrillic_I", 1}, - {"И̏", 0}, - {"Cyrillic_O", 1}, - {"О̏", 0}, - {"Cyrillic_a", 1}, - {"а̏", 0}, - {"Cyrillic_ER", 1}, - {"Р̏", 0}, - {"Cyrillic_U", 1}, - {"У̏", 0}, - {"Cyrillic_ie", 1}, - {"е̏", 0}, - {"Cyrillic_i", 1}, - {"и̏", 0}, - {"Cyrillic_o", 1}, - {"о̏", 0}, - {"Cyrillic_A", 1}, - {"А̏", 0}, - {"Cyrillic_IE", 1}, - {"Е̏", 0}, - {"Cyrillic_u", 1}, - {"у̏", 0}, - {"Multi_key", 5833}, - {"backslash", 5}, - {"minus", 1}, - {"⍀", 0}, - {"o", 2}, - {"slash", 1}, - {"🙌", 0}, - {"minus", 59}, - {"backslash", 1}, - {"⍀", 0}, - {"minus", 6}, - {"minus", 1}, - {"—", 0}, - {"period", 1}, - {"–", 0}, - {"space", 1}, - {"­", 0}, - {"a", 1}, - {"ā", 0}, - {"e", 1}, - {"ē", 0}, - {"o", 1}, - {"ō", 0}, - {"l", 1}, - {"£", 0}, - {"space", 1}, - {"~", 0}, - {"y", 1}, - {"¥", 0}, - {"i", 1}, - {"ī", 0}, - {"parenright", 1}, - {"}", 0}, - {"u", 1}, - {"ū", 0}, - {"E", 1}, - {"Ē", 0}, - {"Y", 1}, - {"¥", 0}, - {"d", 1}, - {"đ", 0}, - {"D", 1}, - {"Đ", 0}, - {"plus", 1}, - {"±", 0}, - {"colon", 1}, - {"÷", 0}, - {"O", 1}, - {"Ō", 0}, - {"A", 1}, - {"Ā", 0}, - {"L", 1}, - {"£", 0}, - {"comma", 1}, - {"¬", 0}, - {"slash", 1}, - {"⌿", 0}, - {"greater", 1}, - {"→", 0}, - {"parenleft", 1}, - {"{", 0}, - {"I", 1}, - {"Ī", 0}, - {"U", 1}, - {"Ū", 0}, - {"asciicircum", 1}, - {"¯", 0}, - {"period", 130}, - {"minus", 1}, - {"·", 0}, - {"period", 1}, - {"…", 0}, - {"W", 1}, - {"Ẇ", 0}, - {"g", 1}, - {"ġ", 0}, - {"a", 1}, - {"ȧ", 0}, - {"C", 1}, - {"Ċ", 0}, - {"exclam", 4}, - {"S", 1}, - {"Ṩ", 0}, - {"s", 1}, - {"ṩ", 0}, - {"less", 1}, - {"‹", 0}, - {"e", 1}, - {"ė", 0}, - {"F", 1}, - {"Ḟ", 0}, - {"o", 1}, - {"ȯ", 0}, - {"t", 1}, - {"ṫ", 0}, - {"dead_belowdot", 4}, - {"S", 1}, - {"Ṩ", 0}, - {"s", 1}, - {"ṩ", 0}, - {"y", 1}, - {"ẏ", 0}, - {"b", 1}, - {"ḃ", 0}, - {"i", 1}, - {"ı", 0}, - {"n", 1}, - {"ṅ", 0}, - {"equal", 1}, - {"•", 0}, - {"dead_caron", 4}, - {"S", 1}, - {"Ṧ", 0}, - {"s", 1}, - {"ṧ", 0}, - {"x", 1}, - {"ẋ", 0}, - {"z", 1}, - {"ż", 0}, - {"G", 1}, - {"Ġ", 0}, - {"Sacute", 1}, - {"Ṥ", 0}, - {"H", 1}, - {"Ḣ", 0}, - {"E", 1}, - {"Ė", 0}, - {"S", 1}, - {"Ṡ", 0}, - {"Y", 1}, - {"Ẏ", 0}, - {"scaron", 1}, - {"ṧ", 0}, - {"f", 1}, - {"ḟ", 0}, - {"d", 1}, - {"ḋ", 0}, - {"Scaron", 1}, - {"Ṧ", 0}, - {"D", 1}, - {"Ḋ", 0}, - {"acute", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"w", 1}, - {"ẇ", 0}, - {"p", 1}, - {"ṗ", 0}, - {"P", 1}, - {"Ṗ", 0}, - {"apostrophe", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"M", 1}, - {"Ṁ", 0}, - {"O", 1}, - {"Ȯ", 0}, - {"m", 1}, - {"ṁ", 0}, - {"r", 1}, - {"ṙ", 0}, - {"s", 1}, - {"ṡ", 0}, - {"Z", 1}, - {"Ż", 0}, - {"sacute", 1}, - {"ṥ", 0}, - {"A", 1}, - {"Ȧ", 0}, - {"R", 1}, - {"Ṙ", 0}, - {"c", 1}, - {"ċ", 0}, - {"T", 1}, - {"Ṫ", 0}, - {"greater", 1}, - {"›", 0}, - {"B", 1}, - {"Ḃ", 0}, - {"dead_acute", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"X", 1}, - {"Ẋ", 0}, - {"h", 1}, - {"ḣ", 0}, - {"I", 1}, - {"İ", 0}, - {"N", 1}, - {"Ṅ", 0}, - {"asciicircum", 1}, - {"·", 0}, - {"W", 4}, - {"equal", 1}, - {"₩", 0}, - {"asciicircum", 1}, - {"Ŵ", 0}, - {"g", 10}, - {"period", 1}, - {"ġ", 0}, - {"breve", 1}, - {"ğ", 0}, - {"comma", 1}, - {"ģ", 0}, - {"parenleft", 1}, - {"ğ", 0}, - {"U", 1}, - {"ğ", 0}, - {"a", 30}, - {"minus", 1}, - {"ā", 0}, - {"a", 1}, - {"å", 0}, - {"e", 1}, - {"æ", 0}, - {"diaeresis", 1}, - {"ä", 0}, - {"quotedbl", 1}, - {"ä", 0}, - {"acute", 1}, - {"á", 0}, - {"underscore", 1}, - {"ā", 0}, - {"apostrophe", 1}, - {"á", 0}, - {"asterisk", 1}, - {"å", 0}, - {"comma", 1}, - {"ą", 0}, - {"asciitilde", 1}, - {"ã", 0}, - {"greater", 1}, - {"â", 0}, - {"parenleft", 1}, - {"ă", 0}, - {"grave", 1}, - {"à", 0}, - {"asciicircum", 1}, - {"â", 0}, - {"Greek_IOTA", 4}, - {"quotedbl", 1}, - {"Ϊ", 0}, - {"apostrophe", 1}, - {"Ί", 0}, - {"Greek_iota", 485}, - {"dead_grave", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"Greek_eta", 1}, - {"ῂ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"Greek_alpha", 1}, - {"ᾲ", 0}, - {"Greek_omega", 1}, - {"ῲ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"dead_tilde", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"Greek_eta", 1}, - {"ῇ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"Greek_alpha", 1}, - {"ᾷ", 0}, - {"Greek_omega", 1}, - {"ῷ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾈ", 0}, - {"Greek_eta", 1}, - {"ᾐ", 0}, - {"Greek_alpha", 1}, - {"ᾀ", 0}, - {"Greek_ETA", 1}, - {"ᾘ", 0}, - {"Greek_omega", 1}, - {"ᾠ", 0}, - {"Greek_OMEGA", 1}, - {"ᾨ", 0}, - {"Greek_ALPHA", 1}, - {"ᾼ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾉ", 0}, - {"Greek_eta", 1}, - {"ᾑ", 0}, - {"Greek_alpha", 1}, - {"ᾁ", 0}, - {"Greek_ETA", 1}, - {"ᾙ", 0}, - {"Greek_omega", 1}, - {"ᾡ", 0}, - {"Greek_OMEGA", 1}, - {"ᾩ", 0}, - {"Greek_eta", 1}, - {"ῃ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾈ", 0}, - {"Greek_eta", 1}, - {"ᾐ", 0}, - {"Greek_alpha", 1}, - {"ᾀ", 0}, - {"Greek_ETA", 1}, - {"ᾘ", 0}, - {"Greek_omega", 1}, - {"ᾠ", 0}, - {"Greek_OMEGA", 1}, - {"ᾨ", 0}, - {"quotedbl", 1}, - {"ϊ", 0}, - {"Greek_alpha", 1}, - {"ᾳ", 0}, - {"acute", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_ETA", 1}, - {"ῌ", 0}, - {"apostrophe", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_omegaaccent", 1}, - {"ῴ", 0}, - {"asciitilde", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"Greek_eta", 1}, - {"ῇ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"Greek_alpha", 1}, - {"ᾷ", 0}, - {"Greek_omega", 1}, - {"ῷ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"Greek_omega", 1}, - {"ῳ", 0}, - {"Greek_OMEGA", 1}, - {"ῼ", 0}, - {"dead_acute", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_alphaaccent", 1}, - {"ᾴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾉ", 0}, - {"Greek_eta", 1}, - {"ᾑ", 0}, - {"Greek_alpha", 1}, - {"ᾁ", 0}, - {"Greek_ETA", 1}, - {"ᾙ", 0}, - {"Greek_omega", 1}, - {"ᾡ", 0}, - {"Greek_OMEGA", 1}, - {"ᾩ", 0}, - {"grave", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"Greek_eta", 1}, - {"ῂ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"Greek_alpha", 1}, - {"ᾲ", 0}, - {"Greek_omega", 1}, - {"ῲ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"Greek_etaaccent", 1}, - {"ῄ", 0}, - {"1", 21}, - {"1", 2}, - {"0", 1}, - {"⅒", 0}, - {"7", 1}, - {"⅐", 0}, - {"8", 1}, - {"⅛", 0}, - {"3", 1}, - {"⅓", 0}, - {"2", 1}, - {"½", 0}, - {"6", 1}, - {"⅙", 0}, - {"4", 1}, - {"¼", 0}, - {"5", 1}, - {"⅕", 0}, - {"9", 1}, - {"⅑", 0}, - {"asciicircum", 1}, - {"¹", 0}, - {"Greek_OMICRON", 2}, - {"apostrophe", 1}, - {"Ό", 0}, - {"C", 26}, - {"period", 1}, - {"Ċ", 0}, - {"C", 3}, - {"C", 2}, - {"P", 1}, - {"☭", 0}, - {"less", 1}, - {"Č", 0}, - {"o", 1}, - {"©", 0}, - {"equal", 1}, - {"€", 0}, - {"E", 1}, - {"₠", 0}, - {"apostrophe", 1}, - {"Ć", 0}, - {"O", 1}, - {"©", 0}, - {"r", 1}, - {"₢", 0}, - {"bar", 1}, - {"¢", 0}, - {"comma", 1}, - {"Ç", 0}, - {"slash", 1}, - {"₡", 0}, - {"exclam", 108}, - {"W", 1}, - {"Ẉ", 0}, - {"a", 1}, - {"ạ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ợ", 0}, - {"u", 1}, - {"ự", 0}, - {"O", 1}, - {"Ợ", 0}, - {"U", 1}, - {"Ự", 0}, - {"exclam", 1}, - {"¡", 0}, - {"e", 1}, - {"ẹ", 0}, - {"o", 1}, - {"ọ", 0}, - {"l", 1}, - {"ḷ", 0}, - {"t", 1}, - {"ṭ", 0}, - {"uhorn", 1}, - {"ự", 0}, - {"y", 1}, - {"ỵ", 0}, - {"b", 1}, - {"ḅ", 0}, - {"i", 1}, - {"ị", 0}, - {"k", 1}, - {"ḳ", 0}, - {"n", 1}, - {"ṇ", 0}, - {"Ohorn", 1}, - {"Ợ", 0}, - {"ohorn", 1}, - {"ợ", 0}, - {"V", 1}, - {"Ṿ", 0}, - {"u", 1}, - {"ụ", 0}, - {"z", 1}, - {"ẓ", 0}, - {"H", 1}, - {"Ḥ", 0}, - {"E", 1}, - {"Ẹ", 0}, - {"S", 1}, - {"Ṣ", 0}, - {"Y", 1}, - {"Ỵ", 0}, - {"d", 1}, - {"ḍ", 0}, - {"D", 1}, - {"Ḍ", 0}, - {"plus", 8}, - {"o", 1}, - {"ợ", 0}, - {"u", 1}, - {"ự", 0}, - {"O", 1}, - {"Ợ", 0}, - {"U", 1}, - {"Ự", 0}, - {"w", 1}, - {"ẉ", 0}, - {"v", 1}, - {"ṿ", 0}, - {"question", 1}, - {"‽", 0}, - {"M", 1}, - {"Ṃ", 0}, - {"O", 1}, - {"Ọ", 0}, - {"m", 1}, - {"ṃ", 0}, - {"r", 1}, - {"ṛ", 0}, - {"s", 1}, - {"ṣ", 0}, - {"Z", 1}, - {"Ẓ", 0}, - {"A", 1}, - {"Ạ", 0}, - {"R", 1}, - {"Ṛ", 0}, - {"L", 1}, - {"Ḷ", 0}, - {"T", 1}, - {"Ṭ", 0}, - {"K", 1}, - {"Ḳ", 0}, - {"B", 1}, - {"Ḅ", 0}, - {"Uhorn", 1}, - {"Ự", 0}, - {"h", 1}, - {"ḥ", 0}, - {"I", 1}, - {"Ị", 0}, - {"N", 1}, - {"Ṇ", 0}, - {"U", 1}, - {"Ụ", 0}, - {"asciicircum", 1}, - {"¦", 0}, - {"less", 56}, - {"minus", 1}, - {"←", 0}, - {"C", 1}, - {"Č", 0}, - {"less", 1}, - {"«", 0}, - {"e", 1}, - {"ě", 0}, - {"l", 1}, - {"ľ", 0}, - {"t", 1}, - {"ť", 0}, - {"space", 1}, - {"ˇ", 0}, - {"n", 1}, - {"ň", 0}, - {"equal", 1}, - {"≤", 0}, - {"z", 1}, - {"ž", 0}, - {"3", 1}, - {"♥", 0}, - {"E", 1}, - {"Ě", 0}, - {"S", 1}, - {"Š", 0}, - {"d", 1}, - {"ď", 0}, - {"D", 1}, - {"Ď", 0}, - {"quotedbl", 1}, - {"“", 0}, - {"underscore", 1}, - {"≤", 0}, - {"apostrophe", 1}, - {"‘", 0}, - {"r", 1}, - {"ř", 0}, - {"s", 1}, - {"š", 0}, - {"Z", 1}, - {"Ž", 0}, - {"R", 1}, - {"Ř", 0}, - {"c", 1}, - {"č", 0}, - {"L", 1}, - {"Ľ", 0}, - {"T", 1}, - {"Ť", 0}, - {"slash", 1}, - {"\\", 0}, - {"greater", 1}, - {"⋄", 0}, - {"N", 1}, - {"Ň", 0}, - {"KP_Divide", 46}, - {"g", 1}, - {"ǥ", 0}, - {"o", 1}, - {"ø", 0}, - {"l", 1}, - {"ł", 0}, - {"t", 1}, - {"ŧ", 0}, - {"b", 1}, - {"ƀ", 0}, - {"i", 1}, - {"ɨ", 0}, - {"Cyrillic_GHE", 1}, - {"Ғ", 0}, - {"leftarrow", 1}, - {"↚", 0}, - {"Cyrillic_KA", 1}, - {"Ҟ", 0}, - {"rightarrow", 1}, - {"↛", 0}, - {"z", 1}, - {"ƶ", 0}, - {"G", 1}, - {"Ǥ", 0}, - {"H", 1}, - {"Ħ", 0}, - {"d", 1}, - {"đ", 0}, - {"Cyrillic_ka", 1}, - {"ҟ", 0}, - {"D", 1}, - {"Đ", 0}, - {"O", 1}, - {"Ø", 0}, - {"Z", 1}, - {"Ƶ", 0}, - {"L", 1}, - {"Ł", 0}, - {"T", 1}, - {"Ŧ", 0}, - {"Cyrillic_ghe", 1}, - {"ғ", 0}, - {"h", 1}, - {"ħ", 0}, - {"I", 1}, - {"Ɨ", 0}, - {"F", 8}, - {"period", 1}, - {"Ḟ", 0}, - {"l", 1}, - {"ffl", 0}, - {"i", 1}, - {"ffi", 0}, - {"r", 1}, - {"₣", 0}, - {"e", 28}, - {"minus", 1}, - {"ē", 0}, - {"period", 1}, - {"ė", 0}, - {"less", 1}, - {"ě", 0}, - {"e", 1}, - {"ə", 0}, - {"diaeresis", 1}, - {"ë", 0}, - {"equal", 1}, - {"€", 0}, - {"quotedbl", 1}, - {"ë", 0}, - {"acute", 1}, - {"é", 0}, - {"underscore", 1}, - {"ē", 0}, - {"apostrophe", 1}, - {"é", 0}, - {"comma", 1}, - {"ę", 0}, - {"greater", 1}, - {"ê", 0}, - {"grave", 1}, - {"è", 0}, - {"asciicircum", 1}, - {"ê", 0}, - {"o", 52}, - {"minus", 1}, - {"ō", 0}, - {"a", 1}, - {"å", 0}, - {"C", 1}, - {"©", 0}, - {"e", 1}, - {"œ", 0}, - {"o", 1}, - {"°", 0}, - {"diaeresis", 1}, - {"ö", 0}, - {"y", 1}, - {"ẙ", 0}, - {"x", 1}, - {"¤", 0}, - {"u", 1}, - {"ů", 0}, - {"quotedbl", 1}, - {"ö", 0}, - {"acute", 1}, - {"ó", 0}, - {"w", 1}, - {"ẘ", 0}, - {"underscore", 1}, - {"ō", 0}, - {"apostrophe", 1}, - {"ó", 0}, - {"r", 1}, - {"®", 0}, - {"s", 1}, - {"§", 0}, - {"A", 1}, - {"Å", 0}, - {"R", 1}, - {"®", 0}, - {"c", 1}, - {"©", 0}, - {"asciitilde", 1}, - {"õ", 0}, - {"slash", 1}, - {"ø", 0}, - {"greater", 1}, - {"ô", 0}, - {"X", 1}, - {"¤", 0}, - {"grave", 1}, - {"ò", 0}, - {"U", 1}, - {"Ů", 0}, - {"asciicircum", 1}, - {"ô", 0}, - {"l", 12}, - {"minus", 1}, - {"£", 0}, - {"less", 1}, - {"ľ", 0}, - {"v", 1}, - {"|", 0}, - {"apostrophe", 1}, - {"ĺ", 0}, - {"comma", 1}, - {"ļ", 0}, - {"slash", 1}, - {"ł", 0}, - {"Greek_upsilon", 4}, - {"quotedbl", 1}, - {"ϋ", 0}, - {"apostrophe", 1}, - {"ύ", 0}, - {"t", 16}, - {"minus", 1}, - {"ŧ", 0}, - {"period", 1}, - {"ṫ", 0}, - {"less", 1}, - {"ť", 0}, - {"M", 1}, - {"™", 0}, - {"m", 1}, - {"™", 0}, - {"comma", 1}, - {"ţ", 0}, - {"slash", 1}, - {"ŧ", 0}, - {"h", 1}, - {"þ", 0}, - {"diaeresis", 42}, - {"a", 1}, - {"ä", 0}, - {"dead_grave", 1}, - {"῭", 0}, - {"e", 1}, - {"ë", 0}, - {"o", 1}, - {"ö", 0}, - {"y", 1}, - {"ÿ", 0}, - {"i", 1}, - {"ï", 0}, - {"dead_tilde", 1}, - {"῁", 0}, - {"u", 1}, - {"ü", 0}, - {"E", 1}, - {"Ë", 0}, - {"Y", 1}, - {"Ÿ", 0}, - {"acute", 1}, - {"΅", 0}, - {"apostrophe", 1}, - {"΅", 0}, - {"O", 1}, - {"Ö", 0}, - {"asterisk", 1}, - {"⍣", 0}, - {"A", 1}, - {"Ä", 0}, - {"asciitilde", 1}, - {"῁", 0}, - {"greater", 1}, - {"⍩", 0}, - {"dead_acute", 1}, - {"΅", 0}, - {"I", 1}, - {"Ï", 0}, - {"grave", 1}, - {"῭", 0}, - {"U", 1}, - {"Ü", 0}, - {"space", 22}, - {"minus", 1}, - {"~", 0}, - {"period", 1}, - {" ", 0}, - {"less", 1}, - {"ˇ", 0}, - {"space", 1}, - {" ", 0}, - {"apostrophe", 1}, - {"'", 0}, - {"comma", 1}, - {"¸", 0}, - {"asciitilde", 1}, - {"~", 0}, - {"greater", 1}, - {"^", 0}, - {"parenleft", 1}, - {"˘", 0}, - {"grave", 1}, - {"`", 0}, - {"asciicircum", 1}, - {"^", 0}, - {"percent", 2}, - {"o", 1}, - {"‰", 0}, - {"y", 14}, - {"minus", 1}, - {"¥", 0}, - {"diaeresis", 1}, - {"ÿ", 0}, - {"equal", 1}, - {"¥", 0}, - {"quotedbl", 1}, - {"ÿ", 0}, - {"acute", 1}, - {"ý", 0}, - {"apostrophe", 1}, - {"ý", 0}, - {"asciicircum", 1}, - {"ŷ", 0}, - {"b", 83}, - {"period", 1}, - {"ḃ", 0}, - {"g", 1}, - {"ğ", 0}, - {"a", 1}, - {"ă", 0}, - {"Greek_IOTA", 1}, - {"Ῐ", 0}, - {"Greek_iota", 1}, - {"ῐ", 0}, - {"exclam", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"e", 1}, - {"ĕ", 0}, - {"o", 1}, - {"ŏ", 0}, - {"Greek_upsilon", 1}, - {"ῠ", 0}, - {"dead_belowdot", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"Cyrillic_I", 1}, - {"Й", 0}, - {"i", 1}, - {"ĭ", 0}, - {"Cyrillic_a", 1}, - {"ӑ", 0}, - {"Cyrillic_U", 1}, - {"Ў", 0}, - {"u", 1}, - {"ŭ", 0}, - {"G", 1}, - {"Ğ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾰ", 0}, - {"Cyrillic_ie", 1}, - {"ӗ", 0}, - {"E", 1}, - {"Ĕ", 0}, - {"Cyrillic_i", 1}, - {"й", 0}, - {"Cyrillic_zhe", 1}, - {"ӂ", 0}, - {"cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"Greek_alpha", 1}, - {"ᾰ", 0}, - {"O", 1}, - {"Ŏ", 0}, - {"A", 1}, - {"Ă", 0}, - {"Cyrillic_A", 1}, - {"Ӑ", 0}, - {"comma", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"Cyrillic_ZHE", 1}, - {"Ӂ", 0}, - {"Cyrillic_IE", 1}, - {"Ӗ", 0}, - {"dead_cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"I", 1}, - {"Ĭ", 0}, - {"U", 1}, - {"Ŭ", 0}, - {"Cyrillic_u", 1}, - {"ў", 0}, - {"Greek_UPSILON", 1}, - {"Ῠ", 0}, - {"i", 28}, - {"minus", 1}, - {"ī", 0}, - {"period", 1}, - {"ı", 0}, - {"diaeresis", 1}, - {"ï", 0}, - {"j", 1}, - {"ij", 0}, - {"quotedbl", 1}, - {"ï", 0}, - {"acute", 1}, - {"í", 0}, - {"underscore", 1}, - {"ī", 0}, - {"apostrophe", 1}, - {"í", 0}, - {"comma", 1}, - {"į", 0}, - {"asciitilde", 1}, - {"ĩ", 0}, - {"greater", 1}, - {"î", 0}, - {"semicolon", 1}, - {"į", 0}, - {"grave", 1}, - {"ì", 0}, - {"asciicircum", 1}, - {"î", 0}, - {"k", 4}, - {"k", 1}, - {"ĸ", 0}, - {"comma", 1}, - {"ķ", 0}, - {"n", 10}, - {"g", 1}, - {"ŋ", 0}, - {"less", 1}, - {"ň", 0}, - {"apostrophe", 1}, - {"ń", 0}, - {"comma", 1}, - {"ņ", 0}, - {"asciitilde", 1}, - {"ñ", 0}, - {"equal", 40}, - {"W", 1}, - {"₩", 0}, - {"C", 1}, - {"€", 0}, - {"e", 1}, - {"€", 0}, - {"o", 1}, - {"ő", 0}, - {"y", 1}, - {"¥", 0}, - {"Cyrillic_U", 1}, - {"Ӳ", 0}, - {"u", 1}, - {"ű", 0}, - {"E", 1}, - {"€", 0}, - {"Y", 1}, - {"¥", 0}, - {"d", 1}, - {"₫", 0}, - {"underscore", 1}, - {"≡", 0}, - {"O", 1}, - {"Ő", 0}, - {"Cyrillic_ES", 1}, - {"€", 0}, - {"c", 1}, - {"€", 0}, - {"L", 1}, - {"₤", 0}, - {"slash", 1}, - {"≠", 0}, - {"Cyrillic_IE", 1}, - {"€", 0}, - {"N", 1}, - {"₦", 0}, - {"U", 1}, - {"Ű", 0}, - {"Cyrillic_u", 1}, - {"ӳ", 0}, - {"7", 2}, - {"8", 1}, - {"⅞", 0}, - {"parenright", 32}, - {"minus", 1}, - {"}", 0}, - {"Greek_IOTA", 1}, - {"Ἰ", 0}, - {"Greek_iota", 1}, - {"ἰ", 0}, - {"Greek_OMICRON", 1}, - {"Ὀ", 0}, - {"Greek_upsilon", 1}, - {"ὐ", 0}, - {"parenright", 1}, - {"]", 0}, - {"Greek_epsilon", 1}, - {"ἐ", 0}, - {"Greek_ALPHA", 1}, - {"Ἀ", 0}, - {"Greek_omicron", 1}, - {"ὀ", 0}, - {"Greek_eta", 1}, - {"ἠ", 0}, - {"Greek_rho", 1}, - {"ῤ", 0}, - {"Greek_alpha", 1}, - {"ἀ", 0}, - {"Greek_ETA", 1}, - {"Ἠ", 0}, - {"Greek_EPSILON", 1}, - {"Ἐ", 0}, - {"Greek_omega", 1}, - {"ὠ", 0}, - {"Greek_OMEGA", 1}, - {"Ὠ", 0}, - {"x", 6}, - {"o", 1}, - {"¤", 0}, - {"x", 1}, - {"×", 0}, - {"O", 1}, - {"¤", 0}, - {"Greek_epsilon", 2}, - {"apostrophe", 1}, - {"έ", 0}, - {"braceleft", 2}, - {"braceright", 1}, - {"∅", 0}, - {"underbar", 54}, - {"1", 1}, - {"₁", 0}, - {"KP_4", 1}, - {"₄", 0}, - {"KP_6", 1}, - {"₆", 0}, - {"KP_8", 1}, - {"₈", 0}, - {"KP_9", 1}, - {"₉", 0}, - {"equal", 1}, - {"₌", 0}, - {"KP_Space", 1}, - {"₂", 0}, - {"7", 1}, - {"₇", 0}, - {"parenright", 1}, - {"₎", 0}, - {"KP_7", 1}, - {"₇", 0}, - {"8", 1}, - {"₈", 0}, - {"KP_1", 1}, - {"₁", 0}, - {"3", 1}, - {"₃", 0}, - {"2", 1}, - {"₂", 0}, - {"plus", 1}, - {"₊", 0}, - {"6", 1}, - {"₆", 0}, - {"4", 1}, - {"₄", 0}, - {"KP_3", 1}, - {"₃", 0}, - {"KP_0", 1}, - {"₀", 0}, - {"KP_Add", 1}, - {"₊", 0}, - {"KP_2", 1}, - {"₂", 0}, - {"5", 1}, - {"₅", 0}, - {"KP_5", 1}, - {"₅", 0}, - {"9", 1}, - {"₉", 0}, - {"0", 1}, - {"₀", 0}, - {"parenleft", 1}, - {"₍", 0}, - {"KP_Equal", 1}, - {"₌", 0}, - {"V", 2}, - {"L", 1}, - {"|", 0}, - {"u", 28}, - {"minus", 1}, - {"ū", 0}, - {"diaeresis", 1}, - {"ü", 0}, - {"u", 1}, - {"ŭ", 0}, - {"quotedbl", 1}, - {"ü", 0}, - {"acute", 1}, - {"ú", 0}, - {"underscore", 1}, - {"ū", 0}, - {"apostrophe", 1}, - {"ú", 0}, - {"asterisk", 1}, - {"ů", 0}, - {"comma", 1}, - {"ų", 0}, - {"asciitilde", 1}, - {"ũ", 0}, - {"slash", 1}, - {"µ", 0}, - {"greater", 1}, - {"û", 0}, - {"grave", 1}, - {"ù", 0}, - {"asciicircum", 1}, - {"û", 0}, - {"breve", 4}, - {"g", 1}, - {"ğ", 0}, - {"G", 1}, - {"Ğ", 0}, - {"z", 6}, - {"period", 1}, - {"ż", 0}, - {"less", 1}, - {"ž", 0}, - {"apostrophe", 1}, - {"ź", 0}, - {"G", 10}, - {"period", 1}, - {"Ġ", 0}, - {"breve", 1}, - {"Ğ", 0}, - {"comma", 1}, - {"Ģ", 0}, - {"parenleft", 1}, - {"Ğ", 0}, - {"U", 1}, - {"Ğ", 0}, - {"Greek_ALPHA", 2}, - {"apostrophe", 1}, - {"Ά", 0}, - {"bracketleft", 2}, - {"bracketright", 1}, - {"⌷", 0}, - {"H", 2}, - {"comma", 1}, - {"Ḩ", 0}, - {"8", 2}, - {"8", 1}, - {"∞", 0}, - {"3", 8}, - {"8", 1}, - {"⅜", 0}, - {"4", 1}, - {"¾", 0}, - {"5", 1}, - {"⅗", 0}, - {"asciicircum", 1}, - {"³", 0}, - {"E", 26}, - {"minus", 1}, - {"Ē", 0}, - {"period", 1}, - {"Ė", 0}, - {"less", 1}, - {"Ě", 0}, - {"diaeresis", 1}, - {"Ë", 0}, - {"equal", 1}, - {"€", 0}, - {"quotedbl", 1}, - {"Ë", 0}, - {"acute", 1}, - {"É", 0}, - {"underscore", 1}, - {"Ē", 0}, - {"apostrophe", 1}, - {"É", 0}, - {"comma", 1}, - {"Ę", 0}, - {"greater", 1}, - {"Ê", 0}, - {"grave", 1}, - {"È", 0}, - {"asciicircum", 1}, - {"Ê", 0}, - {"S", 18}, - {"period", 1}, - {"Ṡ", 0}, - {"exclam", 1}, - {"§", 0}, - {"less", 1}, - {"Š", 0}, - {"S", 1}, - {"ẞ", 0}, - {"apostrophe", 1}, - {"Ś", 0}, - {"M", 1}, - {"℠", 0}, - {"O", 1}, - {"§", 0}, - {"m", 1}, - {"℠", 0}, - {"comma", 1}, - {"Ş", 0}, - {"2", 6}, - {"3", 1}, - {"⅔", 0}, - {"5", 1}, - {"⅖", 0}, - {"asciicircum", 1}, - {"²", 0}, - {"Y", 14}, - {"minus", 1}, - {"¥", 0}, - {"diaeresis", 1}, - {"Ÿ", 0}, - {"equal", 1}, - {"¥", 0}, - {"quotedbl", 1}, - {"Ÿ", 0}, - {"acute", 1}, - {"Ý", 0}, - {"apostrophe", 1}, - {"Ý", 0}, - {"asciicircum", 1}, - {"Ŷ", 0}, - {"f", 12}, - {"period", 1}, - {"ḟ", 0}, - {"l", 1}, - {"fl", 0}, - {"i", 1}, - {"fi", 0}, - {"S", 1}, - {"ſ", 0}, - {"f", 1}, - {"ff", 0}, - {"s", 1}, - {"ſ", 0}, - {"Greek_omicron", 2}, - {"apostrophe", 1}, - {"ό", 0}, - {"Greek_eta", 2}, - {"apostrophe", 1}, - {"ή", 0}, - {"d", 14}, - {"minus", 1}, - {"đ", 0}, - {"period", 1}, - {"ḋ", 0}, - {"less", 1}, - {"ď", 0}, - {"i", 1}, - {"⌀", 0}, - {"equal", 1}, - {"₫", 0}, - {"comma", 1}, - {"ḑ", 0}, - {"h", 1}, - {"ð", 0}, - {"D", 10}, - {"minus", 1}, - {"Đ", 0}, - {"period", 1}, - {"Ḋ", 0}, - {"less", 1}, - {"Ď", 0}, - {"H", 1}, - {"Ð", 0}, - {"comma", 1}, - {"Ḑ", 0}, - {"quotedbl", 137}, - {"W", 1}, - {"Ẅ", 0}, - {"a", 1}, - {"ä", 0}, - {"Greek_IOTA", 1}, - {"Ϊ", 0}, - {"Greek_iota", 1}, - {"ϊ", 0}, - {"less", 1}, - {"“", 0}, - {"Umacron", 1}, - {"Ṻ", 0}, - {"Cyrillic_ZE", 1}, - {"Ӟ", 0}, - {"e", 1}, - {"ë", 0}, - {"o", 1}, - {"ö", 0}, - {"Cyrillic_ze", 1}, - {"ӟ", 0}, - {"t", 1}, - {"ẗ", 0}, - {"Greek_upsilon", 1}, - {"ϋ", 0}, - {"dead_macron", 4}, - {"u", 1}, - {"ṻ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"Cyrillic_I", 1}, - {"Ӥ", 0}, - {"y", 1}, - {"ÿ", 0}, - {"Cyrillic_O", 1}, - {"Ӧ", 0}, - {"i", 1}, - {"ï", 0}, - {"Ukrainian_I", 1}, - {"Ї", 0}, - {"dead_tilde", 4}, - {"o", 1}, - {"ṏ", 0}, - {"O", 1}, - {"Ṏ", 0}, - {"Cyrillic_che", 1}, - {"ӵ", 0}, - {"Cyrillic_a", 1}, - {"ӓ", 0}, - {"x", 1}, - {"ẍ", 0}, - {"Cyrillic_U", 1}, - {"Ӱ", 0}, - {"u", 1}, - {"ü", 0}, - {"otilde", 1}, - {"ṏ", 0}, - {"H", 1}, - {"Ḧ", 0}, - {"Cyrillic_YERU", 1}, - {"Ӹ", 0}, - {"Cyrillic_ie", 1}, - {"ё", 0}, - {"E", 1}, - {"Ë", 0}, - {"Y", 1}, - {"Ÿ", 0}, - {"Cyrillic_i", 1}, - {"ӥ", 0}, - {"Otilde", 1}, - {"Ṏ", 0}, - {"Cyrillic_zhe", 1}, - {"ӝ", 0}, - {"quotedbl", 1}, - {"¨", 0}, - {"umacron", 1}, - {"ṻ", 0}, - {"Cyrillic_yeru", 1}, - {"ӹ", 0}, - {"acute", 1}, - {"̈́", 0}, - {"w", 1}, - {"ẅ", 0}, - {"Cyrillic_CHE", 1}, - {"Ӵ", 0}, - {"Cyrillic_o", 1}, - {"ӧ", 0}, - {"Ukrainian_i", 1}, - {"ї", 0}, - {"Cyrillic_E", 1}, - {"Ӭ", 0}, - {"underscore", 4}, - {"u", 1}, - {"ṻ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"apostrophe", 1}, - {"̈́", 0}, - {"O", 1}, - {"Ö", 0}, - {"macron", 4}, - {"u", 1}, - {"ṻ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"A", 1}, - {"Ä", 0}, - {"Cyrillic_A", 1}, - {"Ӓ", 0}, - {"comma", 1}, - {"„", 0}, - {"asciitilde", 4}, - {"o", 1}, - {"ṏ", 0}, - {"O", 1}, - {"Ṏ", 0}, - {"greater", 1}, - {"”", 0}, - {"Cyrillic_ZHE", 1}, - {"Ӝ", 0}, - {"Cyrillic_IE", 1}, - {"Ё", 0}, - {"Cyrillic_e", 1}, - {"ӭ", 0}, - {"dead_acute", 1}, - {"̈́", 0}, - {"X", 1}, - {"Ẍ", 0}, - {"h", 1}, - {"ḧ", 0}, - {"I", 1}, - {"Ï", 0}, - {"U", 1}, - {"Ü", 0}, - {"Cyrillic_u", 1}, - {"ӱ", 0}, - {"Greek_UPSILON", 1}, - {"Ϋ", 0}, - {"plus", 12}, - {"minus", 1}, - {"±", 0}, - {"o", 1}, - {"ơ", 0}, - {"u", 1}, - {"ư", 0}, - {"plus", 1}, - {"#", 0}, - {"O", 1}, - {"Ơ", 0}, - {"U", 1}, - {"Ư", 0}, - {"cedilla", 44}, - {"g", 1}, - {"ģ", 0}, - {"C", 1}, - {"Ç", 0}, - {"e", 1}, - {"ȩ", 0}, - {"l", 1}, - {"ļ", 0}, - {"t", 1}, - {"ţ", 0}, - {"k", 1}, - {"ķ", 0}, - {"n", 1}, - {"ņ", 0}, - {"G", 1}, - {"Ģ", 0}, - {"H", 1}, - {"Ḩ", 0}, - {"E", 1}, - {"Ȩ", 0}, - {"S", 1}, - {"Ş", 0}, - {"d", 1}, - {"ḑ", 0}, - {"D", 1}, - {"Ḑ", 0}, - {"r", 1}, - {"ŗ", 0}, - {"s", 1}, - {"ş", 0}, - {"R", 1}, - {"Ŗ", 0}, - {"c", 1}, - {"ç", 0}, - {"L", 1}, - {"Ļ", 0}, - {"T", 1}, - {"Ţ", 0}, - {"K", 1}, - {"Ķ", 0}, - {"h", 1}, - {"ḩ", 0}, - {"N", 1}, - {"Ņ", 0}, - {"Greek_alpha", 2}, - {"apostrophe", 1}, - {"ά", 0}, - {"dead_abovedot", 3}, - {"f", 2}, - {"s", 1}, - {"ẛ", 0}, - {"acute", 463}, - {"W", 1}, - {"Ẃ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"g", 1}, - {"ǵ", 0}, - {"a", 1}, - {"á", 0}, - {"Greek_IOTA", 1}, - {"Ί", 0}, - {"Greek_iota", 1}, - {"ί", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Greek_OMICRON", 1}, - {"Ό", 0}, - {"Acircumflex", 1}, - {"Ấ", 0}, - {"C", 1}, - {"Ć", 0}, - {"Cyrillic_er", 1}, - {"р́", 0}, - {"e", 1}, - {"é", 0}, - {"KP_Divide", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"Utilde", 1}, - {"Ṹ", 0}, - {"o", 1}, - {"ó", 0}, - {"l", 1}, - {"ĺ", 0}, - {"Udiaeresis", 1}, - {"Ǘ", 0}, - {"Greek_upsilon", 1}, - {"ύ", 0}, - {"uhorn", 1}, - {"ứ", 0}, - {"dead_macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"acircumflex", 1}, - {"ấ", 0}, - {"Ecircumflex", 1}, - {"Ế", 0}, - {"Cyrillic_I", 1}, - {"И́", 0}, - {"y", 1}, - {"ý", 0}, - {"b", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"idiaeresis", 1}, - {"ḯ", 0}, - {"Cyrillic_O", 1}, - {"О́", 0}, - {"i", 1}, - {"í", 0}, - {"k", 1}, - {"ḱ", 0}, - {"n", 1}, - {"ń", 0}, - {"ccedilla", 1}, - {"ḉ", 0}, - {"Cyrillic_GHE", 1}, - {"Ѓ", 0}, - {"dead_tilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"Cyrillic_a", 1}, - {"а́", 0}, - {"parenright", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"Ohorn", 1}, - {"Ớ", 0}, - {"ohorn", 1}, - {"ớ", 0}, - {"Cyrillic_ER", 1}, - {"Р́", 0}, - {"Greek_epsilon", 1}, - {"έ", 0}, - {"Cyrillic_KA", 1}, - {"Ќ", 0}, - {"Cyrillic_U", 1}, - {"У́", 0}, - {"dead_abovering", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"Ocircumflex", 1}, - {"Ố", 0}, - {"AE", 1}, - {"Ǽ", 0}, - {"omacron", 1}, - {"ṓ", 0}, - {"ocircumflex", 1}, - {"ố", 0}, - {"u", 1}, - {"ú", 0}, - {"z", 1}, - {"ź", 0}, - {"G", 1}, - {"Ǵ", 0}, - {"Greek_ALPHA", 1}, - {"Ά", 0}, - {"otilde", 1}, - {"ṍ", 0}, - {"utilde", 1}, - {"ṹ", 0}, - {"Cyrillic_ie", 1}, - {"е́", 0}, - {"emacron", 1}, - {"ḗ", 0}, - {"E", 1}, - {"É", 0}, - {"S", 1}, - {"Ś", 0}, - {"Greek_iotadieresis", 1}, - {"ΐ", 0}, - {"Y", 1}, - {"Ý", 0}, - {"Cyrillic_i", 1}, - {"и́", 0}, - {"dead_dasia", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"Greek_upsilondieresis", 1}, - {"ΰ", 0}, - {"Greek_omicron", 1}, - {"ό", 0}, - {"Greek_eta", 1}, - {"ή", 0}, - {"Otilde", 1}, - {"Ṍ", 0}, - {"Cyrillic_ka", 1}, - {"ќ", 0}, - {"Aring", 1}, - {"Ǻ", 0}, - {"Abreve", 1}, - {"Ắ", 0}, - {"dead_psili", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"quotedbl", 12}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"plus", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"Greek_alpha", 1}, - {"ά", 0}, - {"ecircumflex", 1}, - {"ế", 0}, - {"w", 1}, - {"ẃ", 0}, - {"Greek_ETA", 1}, - {"Ή", 0}, - {"Cyrillic_o", 1}, - {"о́", 0}, - {"Emacron", 1}, - {"Ḗ", 0}, - {"Ooblique", 1}, - {"Ǿ", 0}, - {"p", 1}, - {"ṕ", 0}, - {"underscore", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"P", 1}, - {"Ṕ", 0}, - {"M", 1}, - {"Ḿ", 0}, - {"O", 1}, - {"Ó", 0}, - {"abreve", 1}, - {"ắ", 0}, - {"m", 1}, - {"ḿ", 0}, - {"r", 1}, - {"ŕ", 0}, - {"s", 1}, - {"ś", 0}, - {"Z", 1}, - {"Ź", 0}, - {"macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"A", 1}, - {"Á", 0}, - {"R", 1}, - {"Ŕ", 0}, - {"c", 1}, - {"ć", 0}, - {"Idiaeresis", 1}, - {"Ḯ", 0}, - {"L", 1}, - {"Ĺ", 0}, - {"Greek_EPSILON", 1}, - {"Έ", 0}, - {"Cyrillic_A", 1}, - {"А́", 0}, - {"comma", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"asciitilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"Ccedilla", 1}, - {"Ḉ", 0}, - {"slash", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"aring", 1}, - {"ǻ", 0}, - {"K", 1}, - {"Ḱ", 0}, - {"Omacron", 1}, - {"Ṓ", 0}, - {"Cyrillic_IE", 1}, - {"Е́", 0}, - {"dead_cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"Greek_omega", 1}, - {"ώ", 0}, - {"dead_diaeresis", 12}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"Uhorn", 1}, - {"Ứ", 0}, - {"Greek_OMEGA", 1}, - {"Ώ", 0}, - {"oslash", 1}, - {"ǿ", 0}, - {"Cyrillic_ghe", 1}, - {"ѓ", 0}, - {"parenleft", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"udiaeresis", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Í", 0}, - {"N", 1}, - {"Ń", 0}, - {"U", 1}, - {"Ú", 0}, - {"Cyrillic_u", 1}, - {"у́", 0}, - {"ae", 1}, - {"ǽ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Greek_UPSILON", 1}, - {"Ύ", 0}, - {"Cyrillic_pe", 2}, - {"Cyrillic_a", 1}, - {"§", 0}, - {"w", 2}, - {"asciicircum", 1}, - {"ŵ", 0}, - {"Greek_ETA", 2}, - {"apostrophe", 1}, - {"Ή", 0}, - {"4", 2}, - {"5", 1}, - {"⅘", 0}, - {"bracketright", 2}, - {"bracketleft", 1}, - {"⌷", 0}, - {"colon", 6}, - {"minus", 1}, - {"÷", 0}, - {"parenright", 1}, - {"☺", 0}, - {"parenleft", 1}, - {"☹", 0}, - {"p", 4}, - {"period", 1}, - {"ṗ", 0}, - {"exclam", 1}, - {"¶", 0}, - {"underscore", 230}, - {"adiaeresis", 1}, - {"ǟ", 0}, - {"period", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"g", 1}, - {"ḡ", 0}, - {"a", 1}, - {"ā", 0}, - {"Greek_IOTA", 1}, - {"Ῑ", 0}, - {"Greek_iota", 1}, - {"ῑ", 0}, - {"1", 1}, - {"₁", 0}, - {"exclam", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"KP_4", 1}, - {"₄", 0}, - {"less", 1}, - {"≤", 0}, - {"Cyrillic_er", 1}, - {"р̄", 0}, - {"o", 1}, - {"ō", 0}, - {"e", 1}, - {"ē", 0}, - {"KP_6", 1}, - {"₆", 0}, - {"Udiaeresis", 1}, - {"Ǖ", 0}, - {"Greek_upsilon", 1}, - {"ῡ", 0}, - {"dead_belowdot", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"KP_8", 1}, - {"₈", 0}, - {"Cyrillic_I", 1}, - {"Ӣ", 0}, - {"y", 1}, - {"ȳ", 0}, - {"Cyrillic_O", 1}, - {"О̄", 0}, - {"i", 1}, - {"ī", 0}, - {"KP_9", 1}, - {"₉", 0}, - {"equal", 1}, - {"₌", 0}, - {"KP_Space", 1}, - {"₂", 0}, - {"dead_tilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"7", 1}, - {"₇", 0}, - {"Cyrillic_a", 1}, - {"а̄", 0}, - {"parenright", 1}, - {"₎", 0}, - {"Cyrillic_ER", 1}, - {"Р̄", 0}, - {"KP_7", 1}, - {"₇", 0}, - {"Cyrillic_U", 1}, - {"Ӯ", 0}, - {"AE", 1}, - {"Ǣ", 0}, - {"u", 1}, - {"ū", 0}, - {"G", 1}, - {"Ḡ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾱ", 0}, - {"otilde", 1}, - {"ȭ", 0}, - {"8", 1}, - {"₈", 0}, - {"KP_1", 1}, - {"₁", 0}, - {"3", 1}, - {"₃", 0}, - {"Cyrillic_ie", 1}, - {"е̄", 0}, - {"E", 1}, - {"Ē", 0}, - {"2", 1}, - {"₂", 0}, - {"Y", 1}, - {"Ȳ", 0}, - {"Cyrillic_i", 1}, - {"ӣ", 0}, - {"dead_ogonek", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"odiaeresis", 1}, - {"ȫ", 0}, - {"Otilde", 1}, - {"Ȭ", 0}, - {"quotedbl", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"plus", 1}, - {"₊", 0}, - {"6", 1}, - {"₆", 0}, - {"Greek_alpha", 1}, - {"ᾱ", 0}, - {"dead_abovedot", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"Cyrillic_o", 1}, - {"о̄", 0}, - {"4", 1}, - {"₄", 0}, - {"KP_3", 1}, - {"₃", 0}, - {"underscore", 1}, - {"¯", 0}, - {"apostrophe", 1}, - {"⍘", 0}, - {"O", 1}, - {"Ō", 0}, - {"KP_0", 1}, - {"₀", 0}, - {"A", 1}, - {"Ā", 0}, - {"KP_Add", 1}, - {"₊", 0}, - {"Odiaeresis", 1}, - {"Ȫ", 0}, - {"KP_2", 1}, - {"₂", 0}, - {"Cyrillic_A", 1}, - {"А̄", 0}, - {"asciitilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"5", 1}, - {"₅", 0}, - {"greater", 1}, - {"≥", 0}, - {"semicolon", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"KP_5", 1}, - {"₅", 0}, - {"9", 1}, - {"₉", 0}, - {"Cyrillic_IE", 1}, - {"Е̄", 0}, - {"0", 1}, - {"₀", 0}, - {"dead_diaeresis", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"Adiaeresis", 1}, - {"Ǟ", 0}, - {"parenleft", 1}, - {"₍", 0}, - {"udiaeresis", 1}, - {"ǖ", 0}, - {"I", 1}, - {"Ī", 0}, - {"U", 1}, - {"Ū", 0}, - {"Cyrillic_u", 1}, - {"ӯ", 0}, - {"ae", 1}, - {"ǣ", 0}, - {"asciicircum", 1}, - {"¯", 0}, - {"Greek_UPSILON", 1}, - {"Ῡ", 0}, - {"KP_Equal", 1}, - {"₌", 0}, - {"v", 8}, - {"l", 1}, - {"|", 0}, - {"z", 1}, - {"ž", 0}, - {"Z", 1}, - {"Ž", 0}, - {"slash", 1}, - {"√", 0}, - {"P", 8}, - {"period", 1}, - {"Ṗ", 0}, - {"exclam", 1}, - {"¶", 0}, - {"t", 1}, - {"₧", 0}, - {"P", 1}, - {"¶", 0}, - {"question", 106}, - {"dead_breve", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"a", 1}, - {"ả", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ẩ", 0}, - {"e", 1}, - {"ể", 0}, - {"o", 1}, - {"ổ", 0}, - {"E", 1}, - {"Ể", 0}, - {"O", 1}, - {"Ổ", 0}, - {"A", 1}, - {"Ẩ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ở", 0}, - {"u", 1}, - {"ử", 0}, - {"O", 1}, - {"Ở", 0}, - {"U", 1}, - {"Ử", 0}, - {"Acircumflex", 1}, - {"Ẩ", 0}, - {"exclam", 1}, - {"⸘", 0}, - {"e", 1}, - {"ẻ", 0}, - {"o", 1}, - {"ỏ", 0}, - {"uhorn", 1}, - {"ử", 0}, - {"acircumflex", 1}, - {"ẩ", 0}, - {"Ecircumflex", 1}, - {"Ể", 0}, - {"y", 1}, - {"ỷ", 0}, - {"b", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"i", 1}, - {"ỉ", 0}, - {"Ohorn", 1}, - {"Ở", 0}, - {"ohorn", 1}, - {"ở", 0}, - {"Ocircumflex", 1}, - {"Ổ", 0}, - {"ocircumflex", 1}, - {"ổ", 0}, - {"u", 1}, - {"ủ", 0}, - {"E", 1}, - {"Ẻ", 0}, - {"Y", 1}, - {"Ỷ", 0}, - {"Abreve", 1}, - {"Ẳ", 0}, - {"plus", 8}, - {"o", 1}, - {"ở", 0}, - {"u", 1}, - {"ử", 0}, - {"O", 1}, - {"Ở", 0}, - {"U", 1}, - {"Ử", 0}, - {"ecircumflex", 1}, - {"ể", 0}, - {"question", 1}, - {"¿", 0}, - {"O", 1}, - {"Ỏ", 0}, - {"abreve", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ả", 0}, - {"Uhorn", 1}, - {"Ử", 0}, - {"I", 1}, - {"Ỉ", 0}, - {"U", 1}, - {"Ủ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ẩ", 0}, - {"e", 1}, - {"ể", 0}, - {"o", 1}, - {"ổ", 0}, - {"E", 1}, - {"Ể", 0}, - {"O", 1}, - {"Ổ", 0}, - {"A", 1}, - {"Ẩ", 0}, - {"apostrophe", 470}, - {"W", 1}, - {"Ẃ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"g", 1}, - {"ǵ", 0}, - {"a", 1}, - {"á", 0}, - {"Greek_IOTA", 1}, - {"Ί", 0}, - {"Greek_iota", 1}, - {"ί", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Greek_OMICRON", 1}, - {"Ό", 0}, - {"Acircumflex", 1}, - {"Ấ", 0}, - {"C", 1}, - {"Ć", 0}, - {"less", 1}, - {"‘", 0}, - {"Cyrillic_er", 1}, - {"р́", 0}, - {"e", 1}, - {"é", 0}, - {"KP_Divide", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"Utilde", 1}, - {"Ṹ", 0}, - {"o", 1}, - {"ó", 0}, - {"l", 1}, - {"ĺ", 0}, - {"Udiaeresis", 1}, - {"Ǘ", 0}, - {"Greek_upsilon", 1}, - {"ύ", 0}, - {"uhorn", 1}, - {"ứ", 0}, - {"space", 1}, - {"'", 0}, - {"dead_macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"acircumflex", 1}, - {"ấ", 0}, - {"Ecircumflex", 1}, - {"Ế", 0}, - {"Cyrillic_I", 1}, - {"И́", 0}, - {"y", 1}, - {"ý", 0}, - {"b", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"idiaeresis", 1}, - {"ḯ", 0}, - {"Cyrillic_O", 1}, - {"О́", 0}, - {"i", 1}, - {"í", 0}, - {"k", 1}, - {"ḱ", 0}, - {"n", 1}, - {"ń", 0}, - {"ccedilla", 1}, - {"ḉ", 0}, - {"Cyrillic_GHE", 1}, - {"Ѓ", 0}, - {"dead_tilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"Cyrillic_a", 1}, - {"а́", 0}, - {"parenright", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"Ohorn", 1}, - {"Ớ", 0}, - {"ohorn", 1}, - {"ớ", 0}, - {"Cyrillic_ER", 1}, - {"Р́", 0}, - {"Greek_epsilon", 1}, - {"έ", 0}, - {"Cyrillic_KA", 1}, - {"Ќ", 0}, - {"Cyrillic_U", 1}, - {"У́", 0}, - {"dead_abovering", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"Ocircumflex", 1}, - {"Ố", 0}, - {"AE", 1}, - {"Ǽ", 0}, - {"omacron", 1}, - {"ṓ", 0}, - {"ocircumflex", 1}, - {"ố", 0}, - {"u", 1}, - {"ú", 0}, - {"z", 1}, - {"ź", 0}, - {"G", 1}, - {"Ǵ", 0}, - {"Greek_ALPHA", 1}, - {"Ά", 0}, - {"otilde", 1}, - {"ṍ", 0}, - {"utilde", 1}, - {"ṹ", 0}, - {"Cyrillic_ie", 1}, - {"е́", 0}, - {"emacron", 1}, - {"ḗ", 0}, - {"E", 1}, - {"É", 0}, - {"S", 1}, - {"Ś", 0}, - {"Greek_iotadieresis", 1}, - {"ΐ", 0}, - {"Y", 1}, - {"Ý", 0}, - {"Cyrillic_i", 1}, - {"и́", 0}, - {"dead_dasia", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"Greek_upsilondieresis", 1}, - {"ΰ", 0}, - {"Greek_omicron", 1}, - {"ό", 0}, - {"Greek_eta", 1}, - {"ή", 0}, - {"Otilde", 1}, - {"Ṍ", 0}, - {"Cyrillic_ka", 1}, - {"ќ", 0}, - {"Aring", 1}, - {"Ǻ", 0}, - {"Abreve", 1}, - {"Ắ", 0}, - {"dead_psili", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"quotedbl", 14}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"space", 1}, - {"΅", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"plus", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"Greek_alpha", 1}, - {"ά", 0}, - {"ecircumflex", 1}, - {"ế", 0}, - {"w", 1}, - {"ẃ", 0}, - {"Greek_ETA", 1}, - {"Ή", 0}, - {"Cyrillic_o", 1}, - {"о́", 0}, - {"Emacron", 1}, - {"Ḗ", 0}, - {"Ooblique", 1}, - {"Ǿ", 0}, - {"p", 1}, - {"ṕ", 0}, - {"underscore", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"P", 1}, - {"Ṕ", 0}, - {"apostrophe", 1}, - {"´", 0}, - {"M", 1}, - {"Ḿ", 0}, - {"O", 1}, - {"Ó", 0}, - {"abreve", 1}, - {"ắ", 0}, - {"m", 1}, - {"ḿ", 0}, - {"r", 1}, - {"ŕ", 0}, - {"s", 1}, - {"ś", 0}, - {"Z", 1}, - {"Ź", 0}, - {"macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"A", 1}, - {"Á", 0}, - {"R", 1}, - {"Ŕ", 0}, - {"c", 1}, - {"ć", 0}, - {"Idiaeresis", 1}, - {"Ḯ", 0}, - {"L", 1}, - {"Ĺ", 0}, - {"Greek_EPSILON", 1}, - {"Έ", 0}, - {"Cyrillic_A", 1}, - {"А́", 0}, - {"comma", 1}, - {"‚", 0}, - {"asciitilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"Ccedilla", 1}, - {"Ḉ", 0}, - {"slash", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"aring", 1}, - {"ǻ", 0}, - {"greater", 1}, - {"’", 0}, - {"K", 1}, - {"Ḱ", 0}, - {"Omacron", 1}, - {"Ṓ", 0}, - {"Cyrillic_IE", 1}, - {"Е́", 0}, - {"dead_cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"Greek_omega", 1}, - {"ώ", 0}, - {"dead_diaeresis", 12}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"Uhorn", 1}, - {"Ứ", 0}, - {"Greek_OMEGA", 1}, - {"Ώ", 0}, - {"oslash", 1}, - {"ǿ", 0}, - {"Cyrillic_ghe", 1}, - {"ѓ", 0}, - {"parenleft", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"udiaeresis", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Í", 0}, - {"N", 1}, - {"Ń", 0}, - {"U", 1}, - {"Ú", 0}, - {"Cyrillic_u", 1}, - {"у́", 0}, - {"ae", 1}, - {"ǽ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Greek_UPSILON", 1}, - {"Ύ", 0}, - {"M", 2}, - {"period", 1}, - {"Ṁ", 0}, - {"O", 40}, - {"minus", 1}, - {"Ō", 0}, - {"C", 1}, - {"©", 0}, - {"diaeresis", 1}, - {"Ö", 0}, - {"x", 1}, - {"¤", 0}, - {"E", 1}, - {"Œ", 0}, - {"S", 1}, - {"§", 0}, - {"quotedbl", 1}, - {"Ö", 0}, - {"acute", 1}, - {"Ó", 0}, - {"underscore", 1}, - {"Ō", 0}, - {"apostrophe", 1}, - {"Ó", 0}, - {"r", 1}, - {"®", 0}, - {"A", 1}, - {"Ⓐ", 0}, - {"R", 1}, - {"®", 0}, - {"c", 1}, - {"©", 0}, - {"asciitilde", 1}, - {"Õ", 0}, - {"slash", 1}, - {"Ø", 0}, - {"greater", 1}, - {"Ô", 0}, - {"X", 1}, - {"¤", 0}, - {"grave", 1}, - {"Ò", 0}, - {"asciicircum", 1}, - {"Ô", 0}, - {"m", 6}, - {"period", 1}, - {"ṁ", 0}, - {"u", 1}, - {"µ", 0}, - {"slash", 1}, - {"₥", 0}, - {"r", 6}, - {"less", 1}, - {"ř", 0}, - {"apostrophe", 1}, - {"ŕ", 0}, - {"comma", 1}, - {"ŗ", 0}, - {"s", 20}, - {"period", 1}, - {"ṡ", 0}, - {"exclam", 1}, - {"§", 0}, - {"less", 1}, - {"š", 0}, - {"o", 1}, - {"§", 0}, - {"cedilla", 1}, - {"ş", 0}, - {"apostrophe", 1}, - {"ś", 0}, - {"M", 1}, - {"℠", 0}, - {"m", 1}, - {"℠", 0}, - {"s", 1}, - {"ß", 0}, - {"comma", 1}, - {"ş", 0}, - {"asterisk", 17}, - {"a", 1}, - {"å", 0}, - {"diaeresis", 1}, - {"⍣", 0}, - {"u", 1}, - {"ů", 0}, - {"apostrophe", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"A", 1}, - {"Å", 0}, - {"0", 1}, - {"°", 0}, - {"U", 1}, - {"Ů", 0}, - {"Z", 6}, - {"period", 1}, - {"Ż", 0}, - {"less", 1}, - {"Ž", 0}, - {"apostrophe", 1}, - {"Ź", 0}, - {"bar", 6}, - {"C", 1}, - {"¢", 0}, - {"c", 1}, - {"¢", 0}, - {"asciitilde", 1}, - {"⍭", 0}, - {"macron", 166}, - {"adiaeresis", 1}, - {"ǟ", 0}, - {"period", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"g", 1}, - {"ḡ", 0}, - {"a", 1}, - {"ā", 0}, - {"Greek_IOTA", 1}, - {"Ῑ", 0}, - {"Greek_iota", 1}, - {"ῑ", 0}, - {"exclam", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"Cyrillic_er", 1}, - {"р̄", 0}, - {"e", 1}, - {"ē", 0}, - {"o", 1}, - {"ō", 0}, - {"Udiaeresis", 1}, - {"Ǖ", 0}, - {"Greek_upsilon", 1}, - {"ῡ", 0}, - {"dead_belowdot", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"Cyrillic_I", 1}, - {"Ӣ", 0}, - {"y", 1}, - {"ȳ", 0}, - {"Cyrillic_O", 1}, - {"О̄", 0}, - {"i", 1}, - {"ī", 0}, - {"dead_tilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"Cyrillic_a", 1}, - {"а̄", 0}, - {"Cyrillic_ER", 1}, - {"Р̄", 0}, - {"Cyrillic_U", 1}, - {"Ӯ", 0}, - {"AE", 1}, - {"Ǣ", 0}, - {"u", 1}, - {"ū", 0}, - {"G", 1}, - {"Ḡ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾱ", 0}, - {"otilde", 1}, - {"ȭ", 0}, - {"Cyrillic_ie", 1}, - {"е̄", 0}, - {"E", 1}, - {"Ē", 0}, - {"Y", 1}, - {"Ȳ", 0}, - {"Cyrillic_i", 1}, - {"ӣ", 0}, - {"dead_ogonek", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"odiaeresis", 1}, - {"ȫ", 0}, - {"Otilde", 1}, - {"Ȭ", 0}, - {"quotedbl", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"Greek_alpha", 1}, - {"ᾱ", 0}, - {"dead_abovedot", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"Cyrillic_o", 1}, - {"о̄", 0}, - {"O", 1}, - {"Ō", 0}, - {"A", 1}, - {"Ā", 0}, - {"Odiaeresis", 1}, - {"Ȫ", 0}, - {"Cyrillic_A", 1}, - {"А̄", 0}, - {"asciitilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"semicolon", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"Cyrillic_IE", 1}, - {"Е̄", 0}, - {"dead_diaeresis", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"Adiaeresis", 1}, - {"Ǟ", 0}, - {"udiaeresis", 1}, - {"ǖ", 0}, - {"I", 1}, - {"Ī", 0}, - {"U", 1}, - {"Ū", 0}, - {"Cyrillic_u", 1}, - {"ӯ", 0}, - {"ae", 1}, - {"ǣ", 0}, - {"Greek_UPSILON", 1}, - {"Ῡ", 0}, - {"A", 32}, - {"minus", 1}, - {"Ā", 0}, - {"diaeresis", 1}, - {"Ä", 0}, - {"E", 1}, - {"Æ", 0}, - {"quotedbl", 1}, - {"Ä", 0}, - {"acute", 1}, - {"Á", 0}, - {"underscore", 1}, - {"Ā", 0}, - {"apostrophe", 1}, - {"Á", 0}, - {"asterisk", 1}, - {"Å", 0}, - {"A", 1}, - {"Å", 0}, - {"comma", 1}, - {"Ą", 0}, - {"T", 1}, - {"@", 0}, - {"asciitilde", 1}, - {"Ã", 0}, - {"greater", 1}, - {"Â", 0}, - {"parenleft", 1}, - {"Ă", 0}, - {"grave", 1}, - {"À", 0}, - {"asciicircum", 1}, - {"Â", 0}, - {"R", 10}, - {"less", 1}, - {"Ř", 0}, - {"apostrophe", 1}, - {"Ŕ", 0}, - {"O", 1}, - {"®", 0}, - {"s", 1}, - {"₨", 0}, - {"comma", 1}, - {"Ŗ", 0}, - {"Cyrillic_ES", 2}, - {"equal", 1}, - {"€", 0}, - {"c", 98}, - {"period", 1}, - {"ċ", 0}, - {"g", 1}, - {"ǧ", 0}, - {"a", 1}, - {"ǎ", 0}, - {"ezh", 1}, - {"ǯ", 0}, - {"C", 1}, - {"Č", 0}, - {"less", 1}, - {"č", 0}, - {"e", 1}, - {"ě", 0}, - {"o", 1}, - {"ǒ", 0}, - {"l", 1}, - {"ľ", 0}, - {"Udiaeresis", 1}, - {"Ǚ", 0}, - {"t", 1}, - {"ť", 0}, - {"i", 1}, - {"ǐ", 0}, - {"k", 1}, - {"ǩ", 0}, - {"n", 1}, - {"ň", 0}, - {"equal", 1}, - {"€", 0}, - {"j", 1}, - {"ǰ", 0}, - {"u", 1}, - {"ǔ", 0}, - {"z", 1}, - {"ž", 0}, - {"G", 1}, - {"Ǧ", 0}, - {"H", 1}, - {"Ȟ", 0}, - {"E", 1}, - {"Ě", 0}, - {"S", 1}, - {"Š", 0}, - {"d", 1}, - {"ď", 0}, - {"D", 1}, - {"Ď", 0}, - {"quotedbl", 4}, - {"u", 1}, - {"ǚ", 0}, - {"U", 1}, - {"Ǚ", 0}, - {"apostrophe", 1}, - {"ć", 0}, - {"O", 1}, - {"Ǒ", 0}, - {"r", 1}, - {"ř", 0}, - {"s", 1}, - {"š", 0}, - {"Z", 1}, - {"Ž", 0}, - {"bar", 1}, - {"¢", 0}, - {"EZH", 1}, - {"Ǯ", 0}, - {"A", 1}, - {"Ǎ", 0}, - {"R", 1}, - {"Ř", 0}, - {"c", 1}, - {"č", 0}, - {"L", 1}, - {"Ľ", 0}, - {"comma", 1}, - {"ç", 0}, - {"T", 1}, - {"Ť", 0}, - {"slash", 1}, - {"¢", 0}, - {"K", 1}, - {"Ǩ", 0}, - {"dead_diaeresis", 4}, - {"u", 1}, - {"ǚ", 0}, - {"U", 1}, - {"Ǚ", 0}, - {"h", 1}, - {"ȟ", 0}, - {"udiaeresis", 1}, - {"ǚ", 0}, - {"I", 1}, - {"Ǐ", 0}, - {"N", 1}, - {"Ň", 0}, - {"U", 1}, - {"Ǔ", 0}, - {"numbersign", 14}, - {"e", 1}, - {"♪", 0}, - {"b", 1}, - {"♭", 0}, - {"q", 1}, - {"♩", 0}, - {"E", 1}, - {"♫", 0}, - {"S", 1}, - {"♬", 0}, - {"f", 1}, - {"♮", 0}, - {"numbersign", 1}, - {"♯", 0}, - {"L", 14}, - {"minus", 1}, - {"£", 0}, - {"less", 1}, - {"Ľ", 0}, - {"equal", 1}, - {"₤", 0}, - {"V", 1}, - {"|", 0}, - {"apostrophe", 1}, - {"Ĺ", 0}, - {"comma", 1}, - {"Ļ", 0}, - {"slash", 1}, - {"Ł", 0}, - {"Greek_EPSILON", 2}, - {"apostrophe", 1}, - {"Έ", 0}, - {"comma", 66}, - {"minus", 1}, - {"¬", 0}, - {"g", 1}, - {"ģ", 0}, - {"a", 1}, - {"ą", 0}, - {"C", 1}, - {"Ç", 0}, - {"e", 1}, - {"ę", 0}, - {"l", 1}, - {"ļ", 0}, - {"t", 1}, - {"ţ", 0}, - {"space", 1}, - {"¸", 0}, - {"i", 1}, - {"į", 0}, - {"k", 1}, - {"ķ", 0}, - {"n", 1}, - {"ņ", 0}, - {"u", 1}, - {"ų", 0}, - {"G", 1}, - {"Ģ", 0}, - {"H", 1}, - {"Ḩ", 0}, - {"E", 1}, - {"Ę", 0}, - {"S", 1}, - {"Ş", 0}, - {"d", 1}, - {"ḑ", 0}, - {"D", 1}, - {"Ḑ", 0}, - {"quotedbl", 1}, - {"„", 0}, - {"apostrophe", 1}, - {"‚", 0}, - {"r", 1}, - {"ŗ", 0}, - {"s", 1}, - {"ş", 0}, - {"A", 1}, - {"Ą", 0}, - {"R", 1}, - {"Ŗ", 0}, - {"c", 1}, - {"ç", 0}, - {"L", 1}, - {"Ļ", 0}, - {"comma", 1}, - {"¸", 0}, - {"T", 1}, - {"Ţ", 0}, - {"K", 1}, - {"Ķ", 0}, - {"h", 1}, - {"ḩ", 0}, - {"I", 1}, - {"Į", 0}, - {"N", 1}, - {"Ņ", 0}, - {"U", 1}, - {"Ų", 0}, - {"T", 16}, - {"minus", 1}, - {"Ŧ", 0}, - {"period", 1}, - {"Ṫ", 0}, - {"less", 1}, - {"Ť", 0}, - {"H", 1}, - {"Þ", 0}, - {"M", 1}, - {"™", 0}, - {"m", 1}, - {"™", 0}, - {"comma", 1}, - {"Ţ", 0}, - {"slash", 1}, - {"Ŧ", 0}, - {"asciitilde", 222}, - {"dead_breve", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"a", 1}, - {"ã", 0}, - {"Greek_iota", 1}, - {"ῖ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ỡ", 0}, - {"u", 1}, - {"ữ", 0}, - {"O", 1}, - {"Ỡ", 0}, - {"U", 1}, - {"Ữ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ẫ", 0}, - {"e", 1}, - {"ễ", 0}, - {"o", 1}, - {"ỗ", 0}, - {"E", 1}, - {"Ễ", 0}, - {"O", 1}, - {"Ỗ", 0}, - {"A", 1}, - {"Ẫ", 0}, - {"Acircumflex", 1}, - {"Ẫ", 0}, - {"e", 1}, - {"ẽ", 0}, - {"o", 1}, - {"õ", 0}, - {"Greek_upsilon", 1}, - {"ῦ", 0}, - {"diaeresis", 1}, - {"⍨", 0}, - {"uhorn", 1}, - {"ữ", 0}, - {"space", 1}, - {"~", 0}, - {"acircumflex", 1}, - {"ẫ", 0}, - {"Ecircumflex", 1}, - {"Ễ", 0}, - {"y", 1}, - {"ỹ", 0}, - {"b", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"i", 1}, - {"ĩ", 0}, - {"n", 1}, - {"ñ", 0}, - {"parenright", 18}, - {"Greek_IOTA", 1}, - {"Ἶ", 0}, - {"Greek_iota", 1}, - {"ἶ", 0}, - {"Greek_upsilon", 1}, - {"ὖ", 0}, - {"Greek_ALPHA", 1}, - {"Ἆ", 0}, - {"Greek_eta", 1}, - {"ἦ", 0}, - {"Greek_alpha", 1}, - {"ἆ", 0}, - {"Greek_ETA", 1}, - {"Ἦ", 0}, - {"Greek_omega", 1}, - {"ὦ", 0}, - {"Greek_OMEGA", 1}, - {"Ὦ", 0}, - {"Ohorn", 1}, - {"Ỡ", 0}, - {"ohorn", 1}, - {"ỡ", 0}, - {"Ocircumflex", 1}, - {"Ỗ", 0}, - {"V", 1}, - {"Ṽ", 0}, - {"ocircumflex", 1}, - {"ỗ", 0}, - {"u", 1}, - {"ũ", 0}, - {"E", 1}, - {"Ẽ", 0}, - {"Greek_iotadieresis", 1}, - {"ῗ", 0}, - {"Y", 1}, - {"Ỹ", 0}, - {"dead_dasia", 20}, - {"Greek_IOTA", 1}, - {"Ἷ", 0}, - {"Greek_iota", 1}, - {"ἷ", 0}, - {"Greek_upsilon", 1}, - {"ὗ", 0}, - {"Greek_ALPHA", 1}, - {"Ἇ", 0}, - {"Greek_eta", 1}, - {"ἧ", 0}, - {"Greek_alpha", 1}, - {"ἇ", 0}, - {"Greek_ETA", 1}, - {"Ἧ", 0}, - {"Greek_omega", 1}, - {"ὧ", 0}, - {"Greek_OMEGA", 1}, - {"Ὧ", 0}, - {"Greek_UPSILON", 1}, - {"Ὗ", 0}, - {"Greek_upsilondieresis", 1}, - {"ῧ", 0}, - {"Greek_eta", 1}, - {"ῆ", 0}, - {"Abreve", 1}, - {"Ẵ", 0}, - {"dead_psili", 18}, - {"Greek_IOTA", 1}, - {"Ἶ", 0}, - {"Greek_iota", 1}, - {"ἶ", 0}, - {"Greek_upsilon", 1}, - {"ὖ", 0}, - {"Greek_ALPHA", 1}, - {"Ἆ", 0}, - {"Greek_eta", 1}, - {"ἦ", 0}, - {"Greek_alpha", 1}, - {"ἆ", 0}, - {"Greek_ETA", 1}, - {"Ἦ", 0}, - {"Greek_omega", 1}, - {"ὦ", 0}, - {"Greek_OMEGA", 1}, - {"Ὦ", 0}, - {"quotedbl", 4}, - {"Greek_iota", 1}, - {"ῗ", 0}, - {"Greek_upsilon", 1}, - {"ῧ", 0}, - {"plus", 8}, - {"o", 1}, - {"ỡ", 0}, - {"u", 1}, - {"ữ", 0}, - {"O", 1}, - {"Ỡ", 0}, - {"U", 1}, - {"Ữ", 0}, - {"Greek_alpha", 1}, - {"ᾶ", 0}, - {"ecircumflex", 1}, - {"ễ", 0}, - {"v", 1}, - {"ṽ", 0}, - {"O", 1}, - {"Õ", 0}, - {"abreve", 1}, - {"ẵ", 0}, - {"bar", 1}, - {"⍭", 0}, - {"A", 1}, - {"Ã", 0}, - {"0", 1}, - {"⍬", 0}, - {"Greek_omega", 1}, - {"ῶ", 0}, - {"dead_diaeresis", 4}, - {"Greek_iota", 1}, - {"ῗ", 0}, - {"Greek_upsilon", 1}, - {"ῧ", 0}, - {"Uhorn", 1}, - {"Ữ", 0}, - {"parenleft", 20}, - {"Greek_IOTA", 1}, - {"Ἷ", 0}, - {"Greek_iota", 1}, - {"ἷ", 0}, - {"Greek_upsilon", 1}, - {"ὗ", 0}, - {"Greek_ALPHA", 1}, - {"Ἇ", 0}, - {"Greek_eta", 1}, - {"ἧ", 0}, - {"Greek_alpha", 1}, - {"ἇ", 0}, - {"Greek_ETA", 1}, - {"Ἧ", 0}, - {"Greek_omega", 1}, - {"ὧ", 0}, - {"Greek_OMEGA", 1}, - {"Ὧ", 0}, - {"Greek_UPSILON", 1}, - {"Ὗ", 0}, - {"I", 1}, - {"Ĩ", 0}, - {"N", 1}, - {"Ñ", 0}, - {"U", 1}, - {"Ũ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ẫ", 0}, - {"e", 1}, - {"ễ", 0}, - {"o", 1}, - {"ỗ", 0}, - {"E", 1}, - {"Ễ", 0}, - {"O", 1}, - {"Ỗ", 0}, - {"A", 1}, - {"Ẫ", 0}, - {"slash", 66}, - {"minus", 1}, - {"⌿", 0}, - {"g", 1}, - {"ǥ", 0}, - {"C", 1}, - {"₡", 0}, - {"less", 1}, - {"\\", 0}, - {"o", 1}, - {"ø", 0}, - {"l", 1}, - {"ł", 0}, - {"t", 1}, - {"ŧ", 0}, - {"b", 1}, - {"ƀ", 0}, - {"i", 1}, - {"ɨ", 0}, - {"equal", 1}, - {"≠", 0}, - {"Cyrillic_GHE", 1}, - {"Ғ", 0}, - {"leftarrow", 1}, - {"↚", 0}, - {"Cyrillic_KA", 1}, - {"Ҟ", 0}, - {"u", 1}, - {"µ", 0}, - {"rightarrow", 1}, - {"↛", 0}, - {"z", 1}, - {"ƶ", 0}, - {"G", 1}, - {"Ǥ", 0}, - {"H", 1}, - {"Ħ", 0}, - {"d", 1}, - {"đ", 0}, - {"Cyrillic_ka", 1}, - {"ҟ", 0}, - {"D", 1}, - {"Đ", 0}, - {"v", 1}, - {"√", 0}, - {"O", 1}, - {"Ø", 0}, - {"m", 1}, - {"₥", 0}, - {"Z", 1}, - {"Ƶ", 0}, - {"c", 1}, - {"¢", 0}, - {"L", 1}, - {"Ł", 0}, - {"T", 1}, - {"Ŧ", 0}, - {"slash", 1}, - {"\\", 0}, - {"Cyrillic_ghe", 1}, - {"ғ", 0}, - {"h", 1}, - {"ħ", 0}, - {"I", 1}, - {"Ɨ", 0}, - {"asciicircum", 1}, - {"|", 0}, - {"5", 4}, - {"8", 1}, - {"⅝", 0}, - {"6", 1}, - {"⅚", 0}, - {"Cyrillic_EN", 4}, - {"Cyrillic_O", 1}, - {"№", 0}, - {"Cyrillic_o", 1}, - {"№", 0}, - {"greater", 36}, - {"a", 1}, - {"â", 0}, - {"less", 1}, - {"⋄", 0}, - {"e", 1}, - {"ê", 0}, - {"o", 1}, - {"ô", 0}, - {"diaeresis", 1}, - {"⍩", 0}, - {"space", 1}, - {"^", 0}, - {"i", 1}, - {"î", 0}, - {"equal", 1}, - {"≥", 0}, - {"u", 1}, - {"û", 0}, - {"E", 1}, - {"Ê", 0}, - {"quotedbl", 1}, - {"”", 0}, - {"underscore", 1}, - {"≥", 0}, - {"apostrophe", 1}, - {"’", 0}, - {"O", 1}, - {"Ô", 0}, - {"A", 1}, - {"Â", 0}, - {"greater", 1}, - {"»", 0}, - {"I", 1}, - {"Î", 0}, - {"U", 1}, - {"Û", 0}, - {"semicolon", 22}, - {"a", 1}, - {"ą", 0}, - {"e", 1}, - {"ę", 0}, - {"o", 1}, - {"ǫ", 0}, - {"i", 1}, - {"į", 0}, - {"u", 1}, - {"ų", 0}, - {"E", 1}, - {"Ę", 0}, - {"underscore", 1}, - {"⍮", 0}, - {"O", 1}, - {"Ǫ", 0}, - {"A", 1}, - {"Ą", 0}, - {"I", 1}, - {"Į", 0}, - {"U", 1}, - {"Ų", 0}, - {"K", 2}, - {"comma", 1}, - {"Ķ", 0}, - {"Cyrillic_IE", 2}, - {"equal", 1}, - {"€", 0}, - {"B", 2}, - {"period", 1}, - {"Ḃ", 0}, - {"0", 6}, - {"3", 1}, - {"↉", 0}, - {"asterisk", 1}, - {"°", 0}, - {"asciitilde", 1}, - {"⍬", 0}, - {"Greek_omega", 2}, - {"apostrophe", 1}, - {"ώ", 0}, - {"Greek_OMEGA", 2}, - {"apostrophe", 1}, - {"Ώ", 0}, - {"X", 4}, - {"o", 1}, - {"¤", 0}, - {"O", 1}, - {"¤", 0}, - {"parenleft", 971}, - {"minus", 1}, - {"{", 0}, - {"W", 2}, - {"parenright", 1}, - {"Ⓦ", 0}, - {"g", 2}, - {"parenright", 1}, - {"ⓖ", 0}, - {"kana_KE", 2}, - {"parenright", 1}, - {"㋘", 0}, - {"a", 2}, - {"parenright", 1}, - {"ⓐ", 0}, - {"Greek_IOTA", 1}, - {"Ἱ", 0}, - {"Greek_iota", 1}, - {"ἱ", 0}, - {"1", 65}, - {"1", 2}, - {"parenright", 1}, - {"⑪", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"⑭", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"⑯", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"⑱", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"⑲", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"7", 2}, - {"parenright", 1}, - {"⑰", 0}, - {"parenright", 1}, - {"①", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"⑰", 0}, - {"8", 2}, - {"parenright", 1}, - {"⑱", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"⑪", 0}, - {"3", 2}, - {"parenright", 1}, - {"⑬", 0}, - {"2", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"6", 2}, - {"parenright", 1}, - {"⑯", 0}, - {"4", 2}, - {"parenright", 1}, - {"⑭", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"⑬", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⑩", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"5", 2}, - {"parenright", 1}, - {"⑮", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"⑮", 0}, - {"9", 2}, - {"parenright", 1}, - {"⑲", 0}, - {"0", 2}, - {"parenright", 1}, - {"⑩", 0}, - {"Greek_OMICRON", 1}, - {"Ὁ", 0}, - {"C", 2}, - {"parenright", 1}, - {"Ⓒ", 0}, - {"KP_4", 65}, - {"1", 2}, - {"parenright", 1}, - {"㊶", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㊹", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㊻", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㊽", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㊾", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"7", 2}, - {"parenright", 1}, - {"㊼", 0}, - {"parenright", 1}, - {"④", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㊼", 0}, - {"8", 2}, - {"parenright", 1}, - {"㊽", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㊶", 0}, - {"3", 2}, - {"parenright", 1}, - {"㊸", 0}, - {"2", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"6", 2}, - {"parenright", 1}, - {"㊻", 0}, - {"4", 2}, - {"parenright", 1}, - {"㊹", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㊸", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㊵", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"5", 2}, - {"parenright", 1}, - {"㊺", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㊺", 0}, - {"9", 2}, - {"parenright", 1}, - {"㊾", 0}, - {"0", 2}, - {"parenright", 1}, - {"㊵", 0}, - {"kana_SA", 2}, - {"parenright", 1}, - {"㋚", 0}, - {"e", 2}, - {"parenright", 1}, - {"ⓔ", 0}, - {"F", 2}, - {"parenright", 1}, - {"Ⓕ", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"⑥", 0}, - {"o", 2}, - {"parenright", 1}, - {"ⓞ", 0}, - {"l", 2}, - {"parenright", 1}, - {"ⓛ", 0}, - {"kana_SE", 2}, - {"parenright", 1}, - {"㋝", 0}, - {"kana_SU", 2}, - {"parenright", 1}, - {"㋜", 0}, - {"t", 2}, - {"parenright", 1}, - {"ⓣ", 0}, - {"kana_ME", 2}, - {"parenright", 1}, - {"㋱", 0}, - {"Greek_upsilon", 1}, - {"ὑ", 0}, - {"kana_WO", 2}, - {"parenright", 1}, - {"㋾", 0}, - {"space", 1}, - {"˘", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"⑧", 0}, - {"Greek_RHO", 1}, - {"Ῥ", 0}, - {"Q", 2}, - {"parenright", 1}, - {"Ⓠ", 0}, - {"y", 2}, - {"parenright", 1}, - {"ⓨ", 0}, - {"b", 2}, - {"parenright", 1}, - {"ⓑ", 0}, - {"kana_YO", 2}, - {"parenright", 1}, - {"㋵", 0}, - {"i", 2}, - {"parenright", 1}, - {"ⓘ", 0}, - {"kana_MA", 2}, - {"parenright", 1}, - {"㋮", 0}, - {"k", 2}, - {"parenright", 1}, - {"ⓚ", 0}, - {"n", 2}, - {"parenright", 1}, - {"ⓝ", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"⑨", 0}, - {"KP_Space", 65}, - {"1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"parenright", 1}, - {"②", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"kana_YU", 2}, - {"parenright", 1}, - {"㋴", 0}, - {"kana_TE", 2}, - {"parenright", 1}, - {"㋢", 0}, - {"7", 2}, - {"parenright", 1}, - {"⑦", 0}, - {"kana_NU", 2}, - {"parenright", 1}, - {"㋦", 0}, - {"kana_HO", 2}, - {"parenright", 1}, - {"㋭", 0}, - {"kana_HI", 2}, - {"parenright", 1}, - {"㋪", 0}, - {"j", 2}, - {"parenright", 1}, - {"ⓙ", 0}, - {"kana_E", 2}, - {"parenright", 1}, - {"㋓", 0}, - {"x", 2}, - {"parenright", 1}, - {"ⓧ", 0}, - {"Greek_epsilon", 1}, - {"ἑ", 0}, - {"q", 2}, - {"parenright", 1}, - {"ⓠ", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"⑦", 0}, - {"kana_I", 2}, - {"parenright", 1}, - {"㋑", 0}, - {"kana_WA", 2}, - {"parenright", 1}, - {"㋻", 0}, - {"kana_RU", 2}, - {"parenright", 1}, - {"㋸", 0}, - {"V", 2}, - {"parenright", 1}, - {"Ⓥ", 0}, - {"u", 2}, - {"parenright", 1}, - {"ⓤ", 0}, - {"kana_NI", 2}, - {"parenright", 1}, - {"㋥", 0}, - {"kana_MU", 2}, - {"parenright", 1}, - {"㋰", 0}, - {"kana_CHI", 2}, - {"parenright", 1}, - {"㋠", 0}, - {"kana_HA", 2}, - {"parenright", 1}, - {"㋩", 0}, - {"z", 2}, - {"parenright", 1}, - {"ⓩ", 0}, - {"G", 2}, - {"parenright", 1}, - {"Ⓖ", 0}, - {"Greek_ALPHA", 1}, - {"Ἁ", 0}, - {"H", 2}, - {"parenright", 1}, - {"Ⓗ", 0}, - {"8", 2}, - {"parenright", 1}, - {"⑧", 0}, - {"KP_1", 65}, - {"1", 2}, - {"parenright", 1}, - {"⑪", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"⑭", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"⑯", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"⑱", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"⑲", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"7", 2}, - {"parenright", 1}, - {"⑰", 0}, - {"parenright", 1}, - {"①", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"⑰", 0}, - {"8", 2}, - {"parenright", 1}, - {"⑱", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"⑪", 0}, - {"3", 2}, - {"parenright", 1}, - {"⑬", 0}, - {"2", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"6", 2}, - {"parenright", 1}, - {"⑯", 0}, - {"4", 2}, - {"parenright", 1}, - {"⑭", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"⑬", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⑩", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"5", 2}, - {"parenright", 1}, - {"⑮", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"⑮", 0}, - {"9", 2}, - {"parenright", 1}, - {"⑲", 0}, - {"0", 2}, - {"parenright", 1}, - {"⑩", 0}, - {"3", 65}, - {"1", 2}, - {"parenright", 1}, - {"㉛", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㉞", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㊱", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㊳", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㊴", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"7", 2}, - {"parenright", 1}, - {"㊲", 0}, - {"parenright", 1}, - {"③", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㊲", 0}, - {"8", 2}, - {"parenright", 1}, - {"㊳", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㉛", 0}, - {"3", 2}, - {"parenright", 1}, - {"㉝", 0}, - {"2", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"6", 2}, - {"parenright", 1}, - {"㊱", 0}, - {"4", 2}, - {"parenright", 1}, - {"㉞", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㉝", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㉚", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"5", 2}, - {"parenright", 1}, - {"㉟", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㉟", 0}, - {"9", 2}, - {"parenright", 1}, - {"㊴", 0}, - {"0", 2}, - {"parenright", 1}, - {"㉚", 0}, - {"E", 2}, - {"parenright", 1}, - {"Ⓔ", 0}, - {"S", 2}, - {"parenright", 1}, - {"Ⓢ", 0}, - {"2", 65}, - {"1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"parenright", 1}, - {"②", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"Y", 2}, - {"parenright", 1}, - {"Ⓨ", 0}, - {"kana_RA", 2}, - {"parenright", 1}, - {"㋶", 0}, - {"f", 2}, - {"parenright", 1}, - {"ⓕ", 0}, - {"Greek_omicron", 1}, - {"ὁ", 0}, - {"Greek_eta", 1}, - {"ἡ", 0}, - {"kana_HE", 2}, - {"parenright", 1}, - {"㋬", 0}, - {"Greek_rho", 1}, - {"ῥ", 0}, - {"kana_KO", 2}, - {"parenright", 1}, - {"㋙", 0}, - {"d", 2}, - {"parenright", 1}, - {"ⓓ", 0}, - {"kana_NE", 2}, - {"parenright", 1}, - {"㋧", 0}, - {"D", 2}, - {"parenright", 1}, - {"Ⓓ", 0}, - {"kana_FU", 2}, - {"parenright", 1}, - {"㋫", 0}, - {"6", 2}, - {"parenright", 1}, - {"⑥", 0}, - {"Greek_alpha", 1}, - {"ἁ", 0}, - {"kana_A", 2}, - {"parenright", 1}, - {"㋐", 0}, - {"w", 2}, - {"parenright", 1}, - {"ⓦ", 0}, - {"Greek_ETA", 1}, - {"Ἡ", 0}, - {"4", 65}, - {"1", 2}, - {"parenright", 1}, - {"㊶", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㊹", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㊻", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㊽", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㊾", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"7", 2}, - {"parenright", 1}, - {"㊼", 0}, - {"parenright", 1}, - {"④", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㊼", 0}, - {"8", 2}, - {"parenright", 1}, - {"㊽", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㊶", 0}, - {"3", 2}, - {"parenright", 1}, - {"㊸", 0}, - {"2", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"6", 2}, - {"parenright", 1}, - {"㊻", 0}, - {"4", 2}, - {"parenright", 1}, - {"㊹", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㊸", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㊵", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"5", 2}, - {"parenright", 1}, - {"㊺", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㊺", 0}, - {"9", 2}, - {"parenright", 1}, - {"㊾", 0}, - {"0", 2}, - {"parenright", 1}, - {"㊵", 0}, - {"kana_KU", 2}, - {"parenright", 1}, - {"㋗", 0}, - {"KP_3", 65}, - {"1", 2}, - {"parenright", 1}, - {"㉛", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㉞", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㊱", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㊳", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㊴", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"7", 2}, - {"parenright", 1}, - {"㊲", 0}, - {"parenright", 1}, - {"③", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㊲", 0}, - {"8", 2}, - {"parenright", 1}, - {"㊳", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㉛", 0}, - {"3", 2}, - {"parenright", 1}, - {"㉝", 0}, - {"2", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"6", 2}, - {"parenright", 1}, - {"㊱", 0}, - {"4", 2}, - {"parenright", 1}, - {"㉞", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㉝", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㉚", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"5", 2}, - {"parenright", 1}, - {"㉟", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㉟", 0}, - {"9", 2}, - {"parenright", 1}, - {"㊴", 0}, - {"0", 2}, - {"parenright", 1}, - {"㉚", 0}, - {"p", 2}, - {"parenright", 1}, - {"ⓟ", 0}, - {"J", 2}, - {"parenright", 1}, - {"Ⓙ", 0}, - {"kana_YA", 2}, - {"parenright", 1}, - {"㋳", 0}, - {"v", 2}, - {"parenright", 1}, - {"ⓥ", 0}, - {"P", 2}, - {"parenright", 1}, - {"Ⓟ", 0}, - {"M", 2}, - {"parenright", 1}, - {"Ⓜ", 0}, - {"O", 2}, - {"parenright", 1}, - {"Ⓞ", 0}, - {"m", 2}, - {"parenright", 1}, - {"ⓜ", 0}, - {"r", 2}, - {"parenright", 1}, - {"ⓡ", 0}, - {"s", 2}, - {"parenright", 1}, - {"ⓢ", 0}, - {"Z", 2}, - {"parenright", 1}, - {"Ⓩ", 0}, - {"kana_U", 2}, - {"parenright", 1}, - {"㋒", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⓪", 0}, - {"A", 2}, - {"parenright", 1}, - {"Ⓐ", 0}, - {"R", 2}, - {"parenright", 1}, - {"Ⓡ", 0}, - {"kana_TO", 2}, - {"parenright", 1}, - {"㋣", 0}, - {"kana_TA", 2}, - {"parenright", 1}, - {"㋟", 0}, - {"c", 2}, - {"parenright", 1}, - {"ⓒ", 0}, - {"kana_RO", 2}, - {"parenright", 1}, - {"㋺", 0}, - {"L", 2}, - {"parenright", 1}, - {"Ⓛ", 0}, - {"Greek_EPSILON", 1}, - {"Ἑ", 0}, - {"KP_2", 65}, - {"1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"parenright", 1}, - {"②", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"kana_O", 2}, - {"parenright", 1}, - {"㋔", 0}, - {"kana_RI", 2}, - {"parenright", 1}, - {"㋷", 0}, - {"T", 2}, - {"parenright", 1}, - {"Ⓣ", 0}, - {"kana_KA", 2}, - {"parenright", 1}, - {"㋕", 0}, - {"kana_MI", 2}, - {"parenright", 1}, - {"㋯", 0}, - {"5", 8}, - {"parenright", 1}, - {"⑤", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㊿", 0}, - {"0", 2}, - {"parenright", 1}, - {"㊿", 0}, - {"kana_KI", 2}, - {"parenright", 1}, - {"㋖", 0}, - {"KP_5", 8}, - {"parenright", 1}, - {"⑤", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㊿", 0}, - {"0", 2}, - {"parenright", 1}, - {"㊿", 0}, - {"K", 2}, - {"parenright", 1}, - {"Ⓚ", 0}, - {"9", 2}, - {"parenright", 1}, - {"⑨", 0}, - {"kana_SO", 2}, - {"parenright", 1}, - {"㋞", 0}, - {"B", 2}, - {"parenright", 1}, - {"Ⓑ", 0}, - {"kana_TSU", 2}, - {"parenright", 1}, - {"㋡", 0}, - {"0", 2}, - {"parenright", 1}, - {"⓪", 0}, - {"kana_MO", 2}, - {"parenright", 1}, - {"㋲", 0}, - {"Greek_omega", 1}, - {"ὡ", 0}, - {"kana_NO", 2}, - {"parenright", 1}, - {"㋨", 0}, - {"Greek_OMEGA", 1}, - {"Ὡ", 0}, - {"kana_NA", 2}, - {"parenright", 1}, - {"㋤", 0}, - {"X", 2}, - {"parenright", 1}, - {"Ⓧ", 0}, - {"parenleft", 1}, - {"[", 0}, - {"h", 2}, - {"parenright", 1}, - {"ⓗ", 0}, - {"I", 2}, - {"parenright", 1}, - {"Ⓘ", 0}, - {"N", 2}, - {"parenright", 1}, - {"Ⓝ", 0}, - {"kana_SHI", 2}, - {"parenright", 1}, - {"㋛", 0}, - {"U", 2}, - {"parenright", 1}, - {"Ⓤ", 0}, - {"kana_RE", 2}, - {"parenright", 1}, - {"㋹", 0}, - {"Greek_UPSILON", 1}, - {"Ὑ", 0}, - {"h", 2}, - {"comma", 1}, - {"ḩ", 0}, - {"I", 28}, - {"minus", 1}, - {"Ī", 0}, - {"period", 1}, - {"İ", 0}, - {"diaeresis", 1}, - {"Ï", 0}, - {"j", 1}, - {"IJ", 0}, - {"quotedbl", 1}, - {"Ï", 0}, - {"acute", 1}, - {"Í", 0}, - {"underscore", 1}, - {"Ī", 0}, - {"J", 1}, - {"IJ", 0}, - {"apostrophe", 1}, - {"Í", 0}, - {"comma", 1}, - {"Į", 0}, - {"asciitilde", 1}, - {"Ĩ", 0}, - {"greater", 1}, - {"Î", 0}, - {"grave", 1}, - {"Ì", 0}, - {"asciicircum", 1}, - {"Î", 0}, - {"N", 16}, - {"less", 1}, - {"Ň", 0}, - {"o", 1}, - {"№", 0}, - {"equal", 1}, - {"₦", 0}, - {"G", 1}, - {"Ŋ", 0}, - {"apostrophe", 1}, - {"Ń", 0}, - {"O", 1}, - {"№", 0}, - {"comma", 1}, - {"Ņ", 0}, - {"asciitilde", 1}, - {"Ñ", 0}, - {"grave", 362}, - {"W", 1}, - {"Ẁ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"a", 1}, - {"à", 0}, - {"Greek_IOTA", 1}, - {"Ὶ", 0}, - {"Greek_iota", 1}, - {"ὶ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ờ", 0}, - {"u", 1}, - {"ừ", 0}, - {"O", 1}, - {"Ờ", 0}, - {"U", 1}, - {"Ừ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ầ", 0}, - {"e", 1}, - {"ề", 0}, - {"o", 1}, - {"ồ", 0}, - {"E", 1}, - {"Ề", 0}, - {"O", 1}, - {"Ồ", 0}, - {"A", 1}, - {"Ầ", 0}, - {"Greek_OMICRON", 1}, - {"Ὸ", 0}, - {"Acircumflex", 1}, - {"Ầ", 0}, - {"Cyrillic_er", 1}, - {"р̀", 0}, - {"e", 1}, - {"è", 0}, - {"o", 1}, - {"ò", 0}, - {"Udiaeresis", 1}, - {"Ǜ", 0}, - {"Greek_upsilon", 1}, - {"ὺ", 0}, - {"uhorn", 1}, - {"ừ", 0}, - {"space", 1}, - {"`", 0}, - {"dead_macron", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"acircumflex", 1}, - {"ầ", 0}, - {"Ecircumflex", 1}, - {"Ề", 0}, - {"Cyrillic_I", 1}, - {"Ѝ", 0}, - {"y", 1}, - {"ỳ", 0}, - {"b", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"Cyrillic_O", 1}, - {"О̀", 0}, - {"i", 1}, - {"ì", 0}, - {"n", 1}, - {"ǹ", 0}, - {"Cyrillic_a", 1}, - {"а̀", 0}, - {"parenright", 26}, - {"Greek_IOTA", 1}, - {"Ἲ", 0}, - {"Greek_iota", 1}, - {"ἲ", 0}, - {"Greek_OMICRON", 1}, - {"Ὂ", 0}, - {"Greek_upsilon", 1}, - {"ὒ", 0}, - {"Greek_epsilon", 1}, - {"ἒ", 0}, - {"Greek_ALPHA", 1}, - {"Ἂ", 0}, - {"Greek_omicron", 1}, - {"ὂ", 0}, - {"Greek_eta", 1}, - {"ἢ", 0}, - {"Greek_alpha", 1}, - {"ἂ", 0}, - {"Greek_ETA", 1}, - {"Ἢ", 0}, - {"Greek_EPSILON", 1}, - {"Ἒ", 0}, - {"Greek_omega", 1}, - {"ὢ", 0}, - {"Greek_OMEGA", 1}, - {"Ὢ", 0}, - {"Ohorn", 1}, - {"Ờ", 0}, - {"ohorn", 1}, - {"ờ", 0}, - {"Cyrillic_ER", 1}, - {"Р̀", 0}, - {"Greek_epsilon", 1}, - {"ὲ", 0}, - {"Cyrillic_U", 1}, - {"У̀", 0}, - {"Ocircumflex", 1}, - {"Ồ", 0}, - {"omacron", 1}, - {"ṑ", 0}, - {"ocircumflex", 1}, - {"ồ", 0}, - {"u", 1}, - {"ù", 0}, - {"Greek_ALPHA", 1}, - {"Ὰ", 0}, - {"Cyrillic_ie", 1}, - {"ѐ", 0}, - {"emacron", 1}, - {"ḕ", 0}, - {"E", 1}, - {"È", 0}, - {"Greek_iotadieresis", 1}, - {"ῒ", 0}, - {"Y", 1}, - {"Ỳ", 0}, - {"Cyrillic_i", 1}, - {"ѝ", 0}, - {"dead_dasia", 28}, - {"Greek_IOTA", 1}, - {"Ἳ", 0}, - {"Greek_iota", 1}, - {"ἳ", 0}, - {"Greek_OMICRON", 1}, - {"Ὃ", 0}, - {"Greek_upsilon", 1}, - {"ὓ", 0}, - {"Greek_epsilon", 1}, - {"ἓ", 0}, - {"Greek_ALPHA", 1}, - {"Ἃ", 0}, - {"Greek_omicron", 1}, - {"ὃ", 0}, - {"Greek_eta", 1}, - {"ἣ", 0}, - {"Greek_alpha", 1}, - {"ἃ", 0}, - {"Greek_ETA", 1}, - {"Ἣ", 0}, - {"Greek_EPSILON", 1}, - {"Ἓ", 0}, - {"Greek_omega", 1}, - {"ὣ", 0}, - {"Greek_OMEGA", 1}, - {"Ὣ", 0}, - {"Greek_UPSILON", 1}, - {"Ὓ", 0}, - {"Greek_upsilondieresis", 1}, - {"ῢ", 0}, - {"Greek_omicron", 1}, - {"ὸ", 0}, - {"Greek_eta", 1}, - {"ὴ", 0}, - {"Abreve", 1}, - {"Ằ", 0}, - {"dead_psili", 26}, - {"Greek_IOTA", 1}, - {"Ἲ", 0}, - {"Greek_iota", 1}, - {"ἲ", 0}, - {"Greek_OMICRON", 1}, - {"Ὂ", 0}, - {"Greek_upsilon", 1}, - {"ὒ", 0}, - {"Greek_epsilon", 1}, - {"ἒ", 0}, - {"Greek_ALPHA", 1}, - {"Ἂ", 0}, - {"Greek_omicron", 1}, - {"ὂ", 0}, - {"Greek_eta", 1}, - {"ἢ", 0}, - {"Greek_alpha", 1}, - {"ἂ", 0}, - {"Greek_ETA", 1}, - {"Ἢ", 0}, - {"Greek_EPSILON", 1}, - {"Ἒ", 0}, - {"Greek_omega", 1}, - {"ὢ", 0}, - {"Greek_OMEGA", 1}, - {"Ὢ", 0}, - {"quotedbl", 8}, - {"Greek_iota", 1}, - {"ῒ", 0}, - {"Greek_upsilon", 1}, - {"ῢ", 0}, - {"u", 1}, - {"ǜ", 0}, - {"U", 1}, - {"Ǜ", 0}, - {"plus", 8}, - {"o", 1}, - {"ờ", 0}, - {"u", 1}, - {"ừ", 0}, - {"O", 1}, - {"Ờ", 0}, - {"U", 1}, - {"Ừ", 0}, - {"Greek_alpha", 1}, - {"ὰ", 0}, - {"ecircumflex", 1}, - {"ề", 0}, - {"w", 1}, - {"ẁ", 0}, - {"Greek_ETA", 1}, - {"Ὴ", 0}, - {"Cyrillic_o", 1}, - {"о̀", 0}, - {"Emacron", 1}, - {"Ḕ", 0}, - {"underscore", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"O", 1}, - {"Ò", 0}, - {"abreve", 1}, - {"ằ", 0}, - {"macron", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"A", 1}, - {"À", 0}, - {"Greek_EPSILON", 1}, - {"Ὲ", 0}, - {"Cyrillic_A", 1}, - {"А̀", 0}, - {"Omacron", 1}, - {"Ṑ", 0}, - {"Cyrillic_IE", 1}, - {"Ѐ", 0}, - {"Greek_omega", 1}, - {"ὼ", 0}, - {"dead_diaeresis", 8}, - {"Greek_iota", 1}, - {"ῒ", 0}, - {"Greek_upsilon", 1}, - {"ῢ", 0}, - {"u", 1}, - {"ǜ", 0}, - {"U", 1}, - {"Ǜ", 0}, - {"Uhorn", 1}, - {"Ừ", 0}, - {"Greek_OMEGA", 1}, - {"Ὼ", 0}, - {"parenleft", 28}, - {"Greek_IOTA", 1}, - {"Ἳ", 0}, - {"Greek_iota", 1}, - {"ἳ", 0}, - {"Greek_OMICRON", 1}, - {"Ὃ", 0}, - {"Greek_upsilon", 1}, - {"ὓ", 0}, - {"Greek_epsilon", 1}, - {"ἓ", 0}, - {"Greek_ALPHA", 1}, - {"Ἃ", 0}, - {"Greek_omicron", 1}, - {"ὃ", 0}, - {"Greek_eta", 1}, - {"ἣ", 0}, - {"Greek_alpha", 1}, - {"ἃ", 0}, - {"Greek_ETA", 1}, - {"Ἣ", 0}, - {"Greek_EPSILON", 1}, - {"Ἓ", 0}, - {"Greek_omega", 1}, - {"ὣ", 0}, - {"Greek_OMEGA", 1}, - {"Ὣ", 0}, - {"Greek_UPSILON", 1}, - {"Ὓ", 0}, - {"udiaeresis", 1}, - {"ǜ", 0}, - {"I", 1}, - {"Ì", 0}, - {"N", 1}, - {"Ǹ", 0}, - {"grave", 24}, - {"Cyrillic_er", 1}, - {"р̏", 0}, - {"Cyrillic_I", 1}, - {"И̏", 0}, - {"Cyrillic_O", 1}, - {"О̏", 0}, - {"Cyrillic_a", 1}, - {"а̏", 0}, - {"Cyrillic_ER", 1}, - {"Р̏", 0}, - {"Cyrillic_U", 1}, - {"У̏", 0}, - {"Cyrillic_ie", 1}, - {"е̏", 0}, - {"Cyrillic_i", 1}, - {"и̏", 0}, - {"Cyrillic_o", 1}, - {"о̏", 0}, - {"Cyrillic_A", 1}, - {"А̏", 0}, - {"Cyrillic_IE", 1}, - {"Е̏", 0}, - {"Cyrillic_u", 1}, - {"у̏", 0}, - {"U", 1}, - {"Ù", 0}, - {"Cyrillic_u", 1}, - {"у̀", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ầ", 0}, - {"e", 1}, - {"ề", 0}, - {"o", 1}, - {"ồ", 0}, - {"E", 1}, - {"Ề", 0}, - {"O", 1}, - {"Ồ", 0}, - {"A", 1}, - {"Ầ", 0}, - {"Greek_UPSILON", 1}, - {"Ὺ", 0}, - {"U", 106}, - {"minus", 1}, - {"Ū", 0}, - {"g", 1}, - {"ğ", 0}, - {"a", 1}, - {"ă", 0}, - {"Greek_IOTA", 1}, - {"Ῐ", 0}, - {"Greek_iota", 1}, - {"ῐ", 0}, - {"exclam", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"e", 1}, - {"ĕ", 0}, - {"o", 1}, - {"ŏ", 0}, - {"Greek_upsilon", 1}, - {"ῠ", 0}, - {"diaeresis", 1}, - {"Ü", 0}, - {"dead_belowdot", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"space", 5}, - {"comma", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"Cyrillic_I", 1}, - {"Й", 0}, - {"i", 1}, - {"ĭ", 0}, - {"Cyrillic_a", 1}, - {"ӑ", 0}, - {"Cyrillic_U", 1}, - {"Ў", 0}, - {"u", 1}, - {"ŭ", 0}, - {"G", 1}, - {"Ğ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾰ", 0}, - {"Cyrillic_ie", 1}, - {"ӗ", 0}, - {"E", 1}, - {"Ĕ", 0}, - {"Cyrillic_i", 1}, - {"й", 0}, - {"Cyrillic_zhe", 1}, - {"ӂ", 0}, - {"quotedbl", 1}, - {"Ü", 0}, - {"cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"Greek_alpha", 1}, - {"ᾰ", 0}, - {"acute", 1}, - {"Ú", 0}, - {"underscore", 1}, - {"Ū", 0}, - {"apostrophe", 1}, - {"Ú", 0}, - {"O", 1}, - {"Ŏ", 0}, - {"asterisk", 1}, - {"Ů", 0}, - {"A", 1}, - {"Ă", 0}, - {"Cyrillic_A", 1}, - {"Ӑ", 0}, - {"comma", 1}, - {"Ų", 0}, - {"asciitilde", 1}, - {"Ũ", 0}, - {"greater", 1}, - {"Û", 0}, - {"Cyrillic_ZHE", 1}, - {"Ӂ", 0}, - {"Cyrillic_IE", 1}, - {"Ӗ", 0}, - {"dead_cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"I", 1}, - {"Ĭ", 0}, - {"grave", 1}, - {"Ù", 0}, - {"U", 1}, - {"Ŭ", 0}, - {"Cyrillic_u", 1}, - {"ў", 0}, - {"asciicircum", 1}, - {"Û", 0}, - {"Greek_UPSILON", 1}, - {"Ῠ", 0}, - {"asciicircum", 214}, - {"minus", 1}, - {"¯", 0}, - {"period", 1}, - {"·", 0}, - {"W", 1}, - {"Ŵ", 0}, - {"g", 1}, - {"ĝ", 0}, - {"a", 1}, - {"â", 0}, - {"1", 1}, - {"¹", 0}, - {"C", 1}, - {"Ĉ", 0}, - {"KP_4", 1}, - {"⁴", 0}, - {"exclam", 12}, - {"a", 1}, - {"ậ", 0}, - {"e", 1}, - {"ệ", 0}, - {"o", 1}, - {"ộ", 0}, - {"E", 1}, - {"Ệ", 0}, - {"O", 1}, - {"Ộ", 0}, - {"A", 1}, - {"Ậ", 0}, - {"Cyrillic_er", 1}, - {"р̂", 0}, - {"o", 1}, - {"ô", 0}, - {"e", 1}, - {"ê", 0}, - {"KP_6", 1}, - {"⁶", 0}, - {"dead_belowdot", 12}, - {"a", 1}, - {"ậ", 0}, - {"e", 1}, - {"ệ", 0}, - {"o", 1}, - {"ộ", 0}, - {"E", 1}, - {"Ệ", 0}, - {"O", 1}, - {"Ộ", 0}, - {"A", 1}, - {"Ậ", 0}, - {"space", 1}, - {"^", 0}, - {"KP_8", 1}, - {"⁸", 0}, - {"Cyrillic_I", 1}, - {"И̂", 0}, - {"y", 1}, - {"ŷ", 0}, - {"Cyrillic_O", 1}, - {"О̂", 0}, - {"i", 1}, - {"î", 0}, - {"KP_9", 1}, - {"⁹", 0}, - {"equal", 1}, - {"⁼", 0}, - {"KP_Space", 1}, - {"²", 0}, - {"7", 1}, - {"⁷", 0}, - {"Cyrillic_a", 1}, - {"а̂", 0}, - {"j", 1}, - {"ĵ", 0}, - {"parenright", 1}, - {"⁾", 0}, - {"Cyrillic_ER", 1}, - {"Р̂", 0}, - {"KP_7", 1}, - {"⁷", 0}, - {"underbar", 24}, - {"a", 1}, - {"ª", 0}, - {"o", 1}, - {"º", 0}, - {"l", 1}, - {"ˡ", 0}, - {"y", 1}, - {"ʸ", 0}, - {"i", 1}, - {"ⁱ", 0}, - {"n", 1}, - {"ⁿ", 0}, - {"j", 1}, - {"ʲ", 0}, - {"x", 1}, - {"ˣ", 0}, - {"w", 1}, - {"ʷ", 0}, - {"r", 1}, - {"ʳ", 0}, - {"s", 1}, - {"ˢ", 0}, - {"h", 1}, - {"ʰ", 0}, - {"Cyrillic_U", 1}, - {"У̂", 0}, - {"u", 1}, - {"û", 0}, - {"z", 1}, - {"ẑ", 0}, - {"G", 1}, - {"Ĝ", 0}, - {"H", 1}, - {"Ĥ", 0}, - {"8", 1}, - {"⁸", 0}, - {"KP_1", 1}, - {"¹", 0}, - {"3", 1}, - {"³", 0}, - {"Cyrillic_ie", 1}, - {"е̂", 0}, - {"E", 1}, - {"Ê", 0}, - {"S", 1}, - {"Ŝ", 0}, - {"2", 1}, - {"²", 0}, - {"Y", 1}, - {"Ŷ", 0}, - {"Cyrillic_i", 1}, - {"и̂", 0}, - {"plus", 1}, - {"⁺", 0}, - {"6", 1}, - {"⁶", 0}, - {"w", 1}, - {"ŵ", 0}, - {"Cyrillic_o", 1}, - {"о̂", 0}, - {"4", 1}, - {"⁴", 0}, - {"KP_3", 1}, - {"³", 0}, - {"underscore", 24}, - {"a", 1}, - {"ª", 0}, - {"o", 1}, - {"º", 0}, - {"l", 1}, - {"ˡ", 0}, - {"y", 1}, - {"ʸ", 0}, - {"i", 1}, - {"ⁱ", 0}, - {"n", 1}, - {"ⁿ", 0}, - {"j", 1}, - {"ʲ", 0}, - {"x", 1}, - {"ˣ", 0}, - {"w", 1}, - {"ʷ", 0}, - {"r", 1}, - {"ʳ", 0}, - {"s", 1}, - {"ˢ", 0}, - {"h", 1}, - {"ʰ", 0}, - {"J", 1}, - {"Ĵ", 0}, - {"O", 1}, - {"Ô", 0}, - {"s", 1}, - {"ŝ", 0}, - {"Z", 1}, - {"Ẑ", 0}, - {"KP_0", 1}, - {"⁰", 0}, - {"A", 1}, - {"Â", 0}, - {"c", 1}, - {"ĉ", 0}, - {"KP_Add", 1}, - {"⁺", 0}, - {"KP_2", 1}, - {"²", 0}, - {"Cyrillic_A", 1}, - {"А̂", 0}, - {"slash", 1}, - {"|", 0}, - {"5", 1}, - {"⁵", 0}, - {"KP_5", 1}, - {"⁵", 0}, - {"9", 1}, - {"⁹", 0}, - {"Cyrillic_IE", 1}, - {"Е̂", 0}, - {"0", 1}, - {"⁰", 0}, - {"parenleft", 1}, - {"⁽", 0}, - {"h", 1}, - {"ĥ", 0}, - {"I", 1}, - {"Î", 0}, - {"U", 1}, - {"Û", 0}, - {"Cyrillic_u", 1}, - {"у̂", 0}, - {"KP_Equal", 1}, - {"⁼", 0}, - {"Greek_UPSILON", 4}, - {"quotedbl", 1}, - {"Ϋ", 0}, - {"apostrophe", 1}, - {"Ύ", 0}, - {"dead_belowcircumflex", 24}, - {"e", 1}, - {"ḙ", 0}, - {"l", 1}, - {"ḽ", 0}, - {"t", 1}, - {"ṱ", 0}, - {"n", 1}, - {"ṋ", 0}, - {"u", 1}, - {"ṷ", 0}, - {"E", 1}, - {"Ḙ", 0}, - {"d", 1}, - {"ḓ", 0}, - {"D", 1}, - {"Ḓ", 0}, - {"L", 1}, - {"Ḽ", 0}, - {"T", 1}, - {"Ṱ", 0}, - {"N", 1}, - {"Ṋ", 0}, - {"U", 1}, - {"Ṷ", 0}, - {"dead_caron", 134}, - {"minus", 1}, - {"₋", 0}, - {"g", 1}, - {"ǧ", 0}, - {"a", 1}, - {"ǎ", 0}, - {"1", 1}, - {"₁", 0}, - {"ezh", 1}, - {"ǯ", 0}, - {"C", 1}, - {"Č", 0}, - {"e", 1}, - {"ě", 0}, - {"o", 1}, - {"ǒ", 0}, - {"l", 1}, - {"ľ", 0}, - {"Udiaeresis", 1}, - {"Ǚ", 0}, - {"t", 1}, - {"ť", 0}, - {"space", 1}, - {"ˇ", 0}, - {"Multi_key", 5}, - {"quotedbl", 4}, - {"u", 1}, - {"ǚ", 0}, - {"U", 1}, - {"Ǚ", 0}, - {"i", 1}, - {"ǐ", 0}, - {"k", 1}, - {"ǩ", 0}, - {"n", 1}, - {"ň", 0}, - {"equal", 1}, - {"₌", 0}, - {"dead_caron", 1}, - {"ˇ", 0}, - {"7", 1}, - {"₇", 0}, - {"j", 1}, - {"ǰ", 0}, - {"parenright", 1}, - {"₎", 0}, - {"sabovedot", 1}, - {"ṧ", 0}, - {"nobreakspace", 1}, - {"̌", 0}, - {"V", 1}, - {"Ǚ", 0}, - {"u", 1}, - {"ǔ", 0}, - {"z", 1}, - {"ž", 0}, - {"G", 1}, - {"Ǧ", 0}, - {"H", 1}, - {"Ȟ", 0}, - {"8", 1}, - {"₈", 0}, - {"3", 1}, - {"₃", 0}, - {"E", 1}, - {"Ě", 0}, - {"S", 1}, - {"Š", 0}, - {"2", 1}, - {"₂", 0}, - {"d", 1}, - {"ď", 0}, - {"D", 1}, - {"Ď", 0}, - {"plus", 1}, - {"₊", 0}, - {"6", 1}, - {"₆", 0}, - {"dead_abovedot", 4}, - {"S", 1}, - {"Ṧ", 0}, - {"s", 1}, - {"ṧ", 0}, - {"4", 1}, - {"₄", 0}, - {"v", 1}, - {"ǚ", 0}, - {"O", 1}, - {"Ǒ", 0}, - {"r", 1}, - {"ř", 0}, - {"s", 1}, - {"š", 0}, - {"Z", 1}, - {"Ž", 0}, - {"EZH", 1}, - {"Ǯ", 0}, - {"A", 1}, - {"Ǎ", 0}, - {"R", 1}, - {"Ř", 0}, - {"c", 1}, - {"č", 0}, - {"L", 1}, - {"Ľ", 0}, - {"T", 1}, - {"Ť", 0}, - {"5", 1}, - {"₅", 0}, - {"K", 1}, - {"Ǩ", 0}, - {"9", 1}, - {"₉", 0}, - {"0", 1}, - {"₀", 0}, - {"Sabovedot", 1}, - {"Ṧ", 0}, - {"dead_diaeresis", 4}, - {"u", 1}, - {"ǚ", 0}, - {"U", 1}, - {"Ǚ", 0}, - {"parenleft", 1}, - {"₍", 0}, - {"h", 1}, - {"ȟ", 0}, - {"udiaeresis", 1}, - {"ǚ", 0}, - {"I", 1}, - {"Ǐ", 0}, - {"N", 1}, - {"Ň", 0}, - {"U", 1}, - {"Ǔ", 0}, - {"dead_tilde", 266}, - {"dead_breve", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"a", 1}, - {"ã", 0}, - {"Greek_iota", 1}, - {"ῖ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ỡ", 0}, - {"u", 1}, - {"ữ", 0}, - {"O", 1}, - {"Ỡ", 0}, - {"U", 1}, - {"Ữ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ẫ", 0}, - {"e", 1}, - {"ễ", 0}, - {"o", 1}, - {"ỗ", 0}, - {"E", 1}, - {"Ễ", 0}, - {"O", 1}, - {"Ỗ", 0}, - {"A", 1}, - {"Ẫ", 0}, - {"Acircumflex", 1}, - {"Ẫ", 0}, - {"less", 1}, - {"≲", 0}, - {"Oacute", 1}, - {"Ṍ", 0}, - {"e", 1}, - {"ẽ", 0}, - {"o", 1}, - {"õ", 0}, - {"Greek_upsilon", 1}, - {"ῦ", 0}, - {"uhorn", 1}, - {"ữ", 0}, - {"space", 1}, - {"~", 0}, - {"dead_macron", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"acircumflex", 1}, - {"ẫ", 0}, - {"Ecircumflex", 1}, - {"Ễ", 0}, - {"y", 1}, - {"ỹ", 0}, - {"Multi_key", 77}, - {"b", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"parenright", 18}, - {"Greek_IOTA", 1}, - {"Ἶ", 0}, - {"Greek_iota", 1}, - {"ἶ", 0}, - {"Greek_upsilon", 1}, - {"ὖ", 0}, - {"Greek_ALPHA", 1}, - {"Ἆ", 0}, - {"Greek_eta", 1}, - {"ἦ", 0}, - {"Greek_alpha", 1}, - {"ἆ", 0}, - {"Greek_ETA", 1}, - {"Ἦ", 0}, - {"Greek_omega", 1}, - {"ὦ", 0}, - {"Greek_OMEGA", 1}, - {"Ὦ", 0}, - {"quotedbl", 4}, - {"Greek_iota", 1}, - {"ῗ", 0}, - {"Greek_upsilon", 1}, - {"ῧ", 0}, - {"plus", 8}, - {"o", 1}, - {"ỡ", 0}, - {"u", 1}, - {"ữ", 0}, - {"O", 1}, - {"Ỡ", 0}, - {"U", 1}, - {"Ữ", 0}, - {"parenleft", 20}, - {"Greek_IOTA", 1}, - {"Ἷ", 0}, - {"Greek_iota", 1}, - {"ἷ", 0}, - {"Greek_upsilon", 1}, - {"ὗ", 0}, - {"Greek_ALPHA", 1}, - {"Ἇ", 0}, - {"Greek_eta", 1}, - {"ἧ", 0}, - {"Greek_alpha", 1}, - {"ἇ", 0}, - {"Greek_ETA", 1}, - {"Ἧ", 0}, - {"Greek_omega", 1}, - {"ὧ", 0}, - {"Greek_OMEGA", 1}, - {"Ὧ", 0}, - {"Greek_UPSILON", 1}, - {"Ὗ", 0}, - {"U", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ẫ", 0}, - {"e", 1}, - {"ễ", 0}, - {"o", 1}, - {"ỗ", 0}, - {"E", 1}, - {"Ễ", 0}, - {"O", 1}, - {"Ỗ", 0}, - {"A", 1}, - {"Ẫ", 0}, - {"oacute", 1}, - {"ṍ", 0}, - {"i", 1}, - {"ĩ", 0}, - {"n", 1}, - {"ñ", 0}, - {"equal", 1}, - {"≃", 0}, - {"dead_tilde", 1}, - {"~", 0}, - {"Uacute", 1}, - {"Ṹ", 0}, - {"Ohorn", 1}, - {"Ỡ", 0}, - {"ohorn", 1}, - {"ỡ", 0}, - {"nobreakspace", 1}, - {"̃", 0}, - {"V", 1}, - {"Ṽ", 0}, - {"Ocircumflex", 1}, - {"Ỗ", 0}, - {"omacron", 1}, - {"ȭ", 0}, - {"uacute", 1}, - {"ṹ", 0}, - {"ocircumflex", 1}, - {"ỗ", 0}, - {"u", 1}, - {"ũ", 0}, - {"E", 1}, - {"Ẽ", 0}, - {"Greek_iotadieresis", 1}, - {"ῗ", 0}, - {"Y", 1}, - {"Ỹ", 0}, - {"dead_dasia", 20}, - {"Greek_IOTA", 1}, - {"Ἷ", 0}, - {"Greek_iota", 1}, - {"ἷ", 0}, - {"Greek_upsilon", 1}, - {"ὗ", 0}, - {"Greek_ALPHA", 1}, - {"Ἇ", 0}, - {"Greek_eta", 1}, - {"ἧ", 0}, - {"Greek_alpha", 1}, - {"ἇ", 0}, - {"Greek_ETA", 1}, - {"Ἧ", 0}, - {"Greek_omega", 1}, - {"ὧ", 0}, - {"Greek_OMEGA", 1}, - {"Ὧ", 0}, - {"Greek_UPSILON", 1}, - {"Ὗ", 0}, - {"Greek_upsilondieresis", 1}, - {"ῧ", 0}, - {"odiaeresis", 1}, - {"ṏ", 0}, - {"Greek_eta", 1}, - {"ῆ", 0}, - {"Abreve", 1}, - {"Ẵ", 0}, - {"dead_psili", 18}, - {"Greek_IOTA", 1}, - {"Ἶ", 0}, - {"Greek_iota", 1}, - {"ἶ", 0}, - {"Greek_upsilon", 1}, - {"ὖ", 0}, - {"Greek_ALPHA", 1}, - {"Ἆ", 0}, - {"Greek_eta", 1}, - {"ἦ", 0}, - {"Greek_alpha", 1}, - {"ἆ", 0}, - {"Greek_ETA", 1}, - {"Ἦ", 0}, - {"Greek_omega", 1}, - {"ὦ", 0}, - {"Greek_OMEGA", 1}, - {"Ὦ", 0}, - {"Greek_alpha", 1}, - {"ᾶ", 0}, - {"ecircumflex", 1}, - {"ễ", 0}, - {"v", 1}, - {"ṽ", 0}, - {"O", 1}, - {"Õ", 0}, - {"abreve", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ã", 0}, - {"Odiaeresis", 1}, - {"Ṏ", 0}, - {"greater", 1}, - {"≳", 0}, - {"Omacron", 1}, - {"Ȭ", 0}, - {"Greek_omega", 1}, - {"ῶ", 0}, - {"dead_diaeresis", 8}, - {"Greek_iota", 1}, - {"ῗ", 0}, - {"o", 1}, - {"ṏ", 0}, - {"Greek_upsilon", 1}, - {"ῧ", 0}, - {"O", 1}, - {"Ṏ", 0}, - {"Uhorn", 1}, - {"Ữ", 0}, - {"dead_acute", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"I", 1}, - {"Ĩ", 0}, - {"N", 1}, - {"Ñ", 0}, - {"U", 1}, - {"Ũ", 0}, - {"dead_belowcomma", 14}, - {"t", 1}, - {"ț", 0}, - {"space", 1}, - {",", 0}, - {"dead_belowcomma", 1}, - {",", 0}, - {"nobreakspace", 1}, - {"̦", 0}, - {"S", 1}, - {"Ș", 0}, - {"s", 1}, - {"ș", 0}, - {"T", 1}, - {"Ț", 0}, - {"dead_doubleacute", 18}, - {"o", 1}, - {"ő", 0}, - {"space", 1}, - {"˝", 0}, - {"Cyrillic_U", 1}, - {"Ӳ", 0}, - {"dead_doubleacute", 1}, - {"˝", 0}, - {"nobreakspace", 1}, - {"̋", 0}, - {"u", 1}, - {"ű", 0}, - {"O", 1}, - {"Ő", 0}, - {"U", 1}, - {"Ű", 0}, - {"Cyrillic_u", 1}, - {"ӳ", 0}, - {"dead_abovering", 27}, - {"a", 1}, - {"å", 0}, - {"space", 1}, - {"°", 0}, - {"y", 1}, - {"ẙ", 0}, - {"dead_abovering", 1}, - {"°", 0}, - {"nobreakspace", 1}, - {"̊", 0}, - {"u", 1}, - {"ů", 0}, - {"w", 1}, - {"ẘ", 0}, - {"A", 1}, - {"Å", 0}, - {"Aacute", 1}, - {"Ǻ", 0}, - {"aacute", 1}, - {"ǻ", 0}, - {"dead_acute", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"U", 1}, - {"Ů", 0}, - {"Greek_accentdieresis", 4}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"dead_voiced_sound", 46}, - {"kana_KE", 1}, - {"ゲ", 0}, - {"kana_SA", 1}, - {"ザ", 0}, - {"kana_SE", 1}, - {"ゼ", 0}, - {"kana_SU", 1}, - {"ズ", 0}, - {"kana_WO", 1}, - {"ヺ", 0}, - {"kana_TE", 1}, - {"デ", 0}, - {"kana_HO", 1}, - {"ボ", 0}, - {"kana_HI", 1}, - {"ビ", 0}, - {"kana_WA", 1}, - {"ヷ", 0}, - {"kana_CHI", 1}, - {"ヂ", 0}, - {"kana_HA", 1}, - {"バ", 0}, - {"kana_HE", 1}, - {"ベ", 0}, - {"kana_KO", 1}, - {"ゴ", 0}, - {"kana_FU", 1}, - {"ブ", 0}, - {"kana_KU", 1}, - {"グ", 0}, - {"kana_U", 1}, - {"ヴ", 0}, - {"kana_TO", 1}, - {"ド", 0}, - {"kana_TA", 1}, - {"ダ", 0}, - {"kana_KA", 1}, - {"ガ", 0}, - {"kana_KI", 1}, - {"ギ", 0}, - {"kana_SO", 1}, - {"ゾ", 0}, - {"kana_TSU", 1}, - {"ヅ", 0}, - {"kana_SHI", 1}, - {"ジ", 0}, - {"dead_belowtilde", 14}, - {"e", 1}, - {"ḛ", 0}, - {"i", 1}, - {"ḭ", 0}, - {"u", 1}, - {"ṵ", 0}, - {"E", 1}, - {"Ḛ", 0}, - {"plus", 1}, - {"⨦", 0}, - {"I", 1}, - {"Ḭ", 0}, - {"U", 1}, - {"Ṵ", 0}, - {"dead_ogonek", 35}, - {"a", 1}, - {"ą", 0}, - {"e", 1}, - {"ę", 0}, - {"o", 1}, - {"ǫ", 0}, - {"space", 1}, - {"˛", 0}, - {"dead_macron", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"i", 1}, - {"į", 0}, - {"nobreakspace", 1}, - {"̨", 0}, - {"omacron", 1}, - {"ǭ", 0}, - {"u", 1}, - {"ų", 0}, - {"E", 1}, - {"Ę", 0}, - {"dead_ogonek", 1}, - {"˛", 0}, - {"O", 1}, - {"Ǫ", 0}, - {"A", 1}, - {"Ą", 0}, - {"Omacron", 1}, - {"Ǭ", 0}, - {"I", 1}, - {"Į", 0}, - {"U", 1}, - {"Ų", 0}, - {"dead_dasia", 32}, - {"Greek_IOTA", 1}, - {"Ἱ", 0}, - {"Greek_iota", 1}, - {"ἱ", 0}, - {"Greek_OMICRON", 1}, - {"Ὁ", 0}, - {"Greek_upsilon", 1}, - {"ὑ", 0}, - {"Greek_RHO", 1}, - {"Ῥ", 0}, - {"Greek_epsilon", 1}, - {"ἑ", 0}, - {"Greek_ALPHA", 1}, - {"Ἁ", 0}, - {"Greek_omicron", 1}, - {"ὁ", 0}, - {"Greek_eta", 1}, - {"ἡ", 0}, - {"Greek_rho", 1}, - {"ῥ", 0}, - {"Greek_alpha", 1}, - {"ἁ", 0}, - {"Greek_ETA", 1}, - {"Ἡ", 0}, - {"Greek_EPSILON", 1}, - {"Ἑ", 0}, - {"Greek_omega", 1}, - {"ὡ", 0}, - {"Greek_OMEGA", 1}, - {"Ὡ", 0}, - {"Greek_UPSILON", 1}, - {"Ὑ", 0}, - {"dead_iota", 491}, - {"dead_grave", 59}, - {"Multi_key", 26}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"Greek_eta", 1}, - {"ῂ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"Greek_alpha", 1}, - {"ᾲ", 0}, - {"Greek_omega", 1}, - {"ῲ", 0}, - {"space", 1}, - {"ͺ", 0}, - {"Multi_key", 262}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾈ", 0}, - {"Greek_eta", 1}, - {"ᾐ", 0}, - {"Greek_alpha", 1}, - {"ᾀ", 0}, - {"Greek_ETA", 1}, - {"ᾘ", 0}, - {"Greek_omega", 1}, - {"ᾠ", 0}, - {"Greek_OMEGA", 1}, - {"ᾨ", 0}, - {"acute", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"apostrophe", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"asciitilde", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"Greek_eta", 1}, - {"ῇ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"Greek_alpha", 1}, - {"ᾷ", 0}, - {"Greek_omega", 1}, - {"ῷ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾉ", 0}, - {"Greek_eta", 1}, - {"ᾑ", 0}, - {"Greek_alpha", 1}, - {"ᾁ", 0}, - {"Greek_ETA", 1}, - {"ᾙ", 0}, - {"Greek_omega", 1}, - {"ᾡ", 0}, - {"Greek_OMEGA", 1}, - {"ᾩ", 0}, - {"grave", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"Greek_eta", 1}, - {"ῂ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"Greek_alpha", 1}, - {"ᾲ", 0}, - {"Greek_omega", 1}, - {"ῲ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"dead_tilde", 59}, - {"Multi_key", 26}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"Greek_eta", 1}, - {"ῇ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"Greek_alpha", 1}, - {"ᾷ", 0}, - {"Greek_omega", 1}, - {"ῷ", 0}, - {"Greek_ALPHA", 1}, - {"ᾼ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾉ", 0}, - {"Greek_eta", 1}, - {"ᾑ", 0}, - {"Greek_alpha", 1}, - {"ᾁ", 0}, - {"Greek_ETA", 1}, - {"ᾙ", 0}, - {"Greek_omega", 1}, - {"ᾡ", 0}, - {"Greek_OMEGA", 1}, - {"ᾩ", 0}, - {"Greek_eta", 1}, - {"ῃ", 0}, - {"dead_iota", 1}, - {"ͺ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾈ", 0}, - {"Greek_eta", 1}, - {"ᾐ", 0}, - {"Greek_alpha", 1}, - {"ᾀ", 0}, - {"Greek_ETA", 1}, - {"ᾘ", 0}, - {"Greek_omega", 1}, - {"ᾠ", 0}, - {"Greek_OMEGA", 1}, - {"ᾨ", 0}, - {"Greek_alpha", 1}, - {"ᾳ", 0}, - {"Greek_ETA", 1}, - {"ῌ", 0}, - {"Greek_omegaaccent", 1}, - {"ῴ", 0}, - {"Greek_omega", 1}, - {"ῳ", 0}, - {"Greek_OMEGA", 1}, - {"ῼ", 0}, - {"dead_acute", 59}, - {"Multi_key", 26}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"Greek_alphaaccent", 1}, - {"ᾴ", 0}, - {"Greek_etaaccent", 1}, - {"ῄ", 0}, - {"dead_greek", 121}, - {"W", 1}, - {"Ω", 0}, - {"g", 1}, - {"γ", 0}, - {"a", 1}, - {"α", 0}, - {"e", 1}, - {"ε", 0}, - {"F", 1}, - {"Φ", 0}, - {"o", 1}, - {"ο", 0}, - {"l", 1}, - {"λ", 0}, - {"t", 1}, - {"τ", 0}, - {"space", 1}, - {"µ", 0}, - {"dead_macron", 12}, - {"a", 1}, - {"ᾱ", 0}, - {"i", 1}, - {"ῑ", 0}, - {"u", 1}, - {"ῡ", 0}, - {"A", 1}, - {"Ᾱ", 0}, - {"I", 1}, - {"Ῑ", 0}, - {"U", 1}, - {"Ῡ", 0}, - {"Q", 1}, - {"Χ", 0}, - {"y", 1}, - {"ψ", 0}, - {"b", 1}, - {"β", 0}, - {"i", 1}, - {"ι", 0}, - {"k", 1}, - {"κ", 0}, - {"n", 1}, - {"ν", 0}, - {"j", 1}, - {"θ", 0}, - {"x", 1}, - {"ξ", 0}, - {"q", 1}, - {"χ", 0}, - {"nobreakspace", 1}, - {"µ", 0}, - {"u", 1}, - {"υ", 0}, - {"z", 1}, - {"ζ", 0}, - {"G", 1}, - {"Γ", 0}, - {"H", 1}, - {"Η", 0}, - {"E", 1}, - {"Ε", 0}, - {"S", 1}, - {"Σ", 0}, - {"Y", 1}, - {"Ψ", 0}, - {"f", 1}, - {"φ", 0}, - {"d", 1}, - {"δ", 0}, - {"dead_greek", 1}, - {"µ", 0}, - {"D", 1}, - {"Δ", 0}, - {"w", 1}, - {"ω", 0}, - {"p", 1}, - {"π", 0}, - {"J", 1}, - {"Θ", 0}, - {"P", 1}, - {"Π", 0}, - {"M", 1}, - {"Μ", 0}, - {"O", 1}, - {"Ο", 0}, - {"m", 1}, - {"μ", 0}, - {"r", 1}, - {"ρ", 0}, - {"s", 1}, - {"σ", 0}, - {"Z", 1}, - {"Ζ", 0}, - {"dead_stroke", 2}, - {"r", 1}, - {"ϼ", 0}, - {"A", 1}, - {"Α", 0}, - {"R", 1}, - {"Ρ", 0}, - {"L", 1}, - {"Λ", 0}, - {"T", 1}, - {"Τ", 0}, - {"dead_hook", 2}, - {"U", 1}, - {"ϒ", 0}, - {"K", 1}, - {"Κ", 0}, - {"B", 1}, - {"Β", 0}, - {"X", 1}, - {"Ξ", 0}, - {"h", 1}, - {"η", 0}, - {"I", 1}, - {"Ι", 0}, - {"N", 1}, - {"Ν", 0}, - {"U", 1}, - {"Υ", 0}, - {"dead_invertedbreve", 24}, - {"Cyrillic_er", 1}, - {"р̑", 0}, - {"Cyrillic_I", 1}, - {"И̑", 0}, - {"Cyrillic_O", 1}, - {"О̑", 0}, - {"Cyrillic_a", 1}, - {"а̑", 0}, - {"Cyrillic_ER", 1}, - {"Р̑", 0}, - {"Cyrillic_U", 1}, - {"У̑", 0}, - {"Cyrillic_ie", 1}, - {"е̑", 0}, - {"Cyrillic_i", 1}, - {"и̑", 0}, - {"Cyrillic_o", 1}, - {"о̑", 0}, - {"Cyrillic_A", 1}, - {"А̑", 0}, - {"Cyrillic_IE", 1}, - {"Е̑", 0}, - {"Cyrillic_u", 1}, - {"у̑", 0}, - {"dead_psili", 28}, - {"Greek_IOTA", 1}, - {"Ἰ", 0}, - {"Greek_iota", 1}, - {"ἰ", 0}, - {"Greek_OMICRON", 1}, - {"Ὀ", 0}, - {"Greek_upsilon", 1}, - {"ὐ", 0}, - {"Greek_epsilon", 1}, - {"ἐ", 0}, - {"Greek_ALPHA", 1}, - {"Ἀ", 0}, - {"Greek_omicron", 1}, - {"ὀ", 0}, - {"Greek_eta", 1}, - {"ἠ", 0}, - {"Greek_rho", 1}, - {"ῤ", 0}, - {"Greek_alpha", 1}, - {"ἀ", 0}, - {"Greek_ETA", 1}, - {"Ἠ", 0}, - {"Greek_EPSILON", 1}, - {"Ἐ", 0}, - {"Greek_omega", 1}, - {"ὠ", 0}, - {"Greek_OMEGA", 1}, - {"Ὠ", 0}, - {"dead_abovedot", 159}, - {"W", 1}, - {"Ẇ", 0}, - {"g", 1}, - {"ġ", 0}, - {"a", 1}, - {"ȧ", 0}, - {"C", 1}, - {"Ċ", 0}, - {"e", 1}, - {"ė", 0}, - {"F", 1}, - {"Ḟ", 0}, - {"o", 1}, - {"ȯ", 0}, - {"l", 1}, - {"ŀ", 0}, - {"t", 1}, - {"ṫ", 0}, - {"dead_belowdot", 4}, - {"S", 1}, - {"Ṩ", 0}, - {"s", 1}, - {"ṩ", 0}, - {"space", 1}, - {"˙", 0}, - {"dead_macron", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"y", 1}, - {"ẏ", 0}, - {"b", 1}, - {"ḃ", 0}, - {"Multi_key", 23}, - {"exclam", 4}, - {"S", 1}, - {"Ṩ", 0}, - {"s", 1}, - {"ṩ", 0}, - {"f", 2}, - {"s", 1}, - {"ẛ", 0}, - {"acute", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"apostrophe", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"c", 4}, - {"S", 1}, - {"Ṧ", 0}, - {"s", 1}, - {"ṧ", 0}, - {"i", 1}, - {"ı", 0}, - {"n", 1}, - {"ṅ", 0}, - {"dead_caron", 4}, - {"S", 1}, - {"Ṧ", 0}, - {"s", 1}, - {"ṧ", 0}, - {"j", 1}, - {"ȷ", 0}, - {"x", 1}, - {"ẋ", 0}, - {"amacron", 1}, - {"ǡ", 0}, - {"nobreakspace", 1}, - {"̇", 0}, - {"omacron", 1}, - {"ȱ", 0}, - {"z", 1}, - {"ż", 0}, - {"G", 1}, - {"Ġ", 0}, - {"Sacute", 1}, - {"Ṥ", 0}, - {"H", 1}, - {"Ḣ", 0}, - {"E", 1}, - {"Ė", 0}, - {"S", 1}, - {"Ṡ", 0}, - {"Y", 1}, - {"Ẏ", 0}, - {"scaron", 1}, - {"ṧ", 0}, - {"f", 1}, - {"ḟ", 0}, - {"d", 1}, - {"ḋ", 0}, - {"Scaron", 1}, - {"Ṧ", 0}, - {"D", 1}, - {"Ḋ", 0}, - {"dead_abovedot", 1}, - {"˙", 0}, - {"w", 1}, - {"ẇ", 0}, - {"p", 1}, - {"ṗ", 0}, - {"P", 1}, - {"Ṗ", 0}, - {"M", 1}, - {"Ṁ", 0}, - {"O", 1}, - {"Ȯ", 0}, - {"m", 1}, - {"ṁ", 0}, - {"r", 1}, - {"ṙ", 0}, - {"s", 1}, - {"ṡ", 0}, - {"Z", 1}, - {"Ż", 0}, - {"sacute", 1}, - {"ṥ", 0}, - {"dead_stroke", 2}, - {"j", 1}, - {"ɟ", 0}, - {"A", 1}, - {"Ȧ", 0}, - {"R", 1}, - {"Ṙ", 0}, - {"c", 1}, - {"ċ", 0}, - {"L", 1}, - {"Ŀ", 0}, - {"T", 1}, - {"Ṫ", 0}, - {"Omacron", 1}, - {"Ȱ", 0}, - {"B", 1}, - {"Ḃ", 0}, - {"Amacron", 1}, - {"Ǡ", 0}, - {"dead_acute", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"X", 1}, - {"Ẋ", 0}, - {"h", 1}, - {"ḣ", 0}, - {"I", 1}, - {"İ", 0}, - {"N", 1}, - {"Ṅ", 0}, - {"dead_double_grave", 24}, - {"a", 1}, - {"ȁ", 0}, - {"e", 1}, - {"ȅ", 0}, - {"o", 1}, - {"ȍ", 0}, - {"i", 1}, - {"ȉ", 0}, - {"u", 1}, - {"ȕ", 0}, - {"E", 1}, - {"Ȅ", 0}, - {"O", 1}, - {"Ȍ", 0}, - {"r", 1}, - {"ȑ", 0}, - {"A", 1}, - {"Ȁ", 0}, - {"R", 1}, - {"Ȑ", 0}, - {"I", 1}, - {"Ȉ", 0}, - {"U", 1}, - {"Ȕ", 0}, - {"dead_semivoiced_sound", 10}, - {"kana_HO", 1}, - {"ポ", 0}, - {"kana_HI", 1}, - {"ピ", 0}, - {"kana_HA", 1}, - {"パ", 0}, - {"kana_HE", 1}, - {"ペ", 0}, - {"kana_FU", 1}, - {"プ", 0}, - {"dead_stroke", 101}, - {"g", 1}, - {"ǥ", 0}, - {"a", 1}, - {"ⱥ", 0}, - {"C", 1}, - {"Ȼ", 0}, - {"less", 1}, - {"≮", 0}, - {"Oacute", 1}, - {"Ǿ", 0}, - {"e", 1}, - {"ɇ", 0}, - {"o", 1}, - {"ø", 0}, - {"l", 1}, - {"ł", 0}, - {"t", 1}, - {"ŧ", 0}, - {"space", 1}, - {"/", 0}, - {"y", 1}, - {"ɏ", 0}, - {"b", 1}, - {"ƀ", 0}, - {"oacute", 1}, - {"ǿ", 0}, - {"i", 1}, - {"ɨ", 0}, - {"equal", 1}, - {"≠", 0}, - {"j", 1}, - {"ɉ", 0}, - {"nobreakspace", 1}, - {"̸", 0}, - {"u", 1}, - {"ʉ", 0}, - {"greaterthanequal", 1}, - {"≱", 0}, - {"z", 1}, - {"ƶ", 0}, - {"G", 1}, - {"Ǥ", 0}, - {"H", 1}, - {"Ħ", 0}, - {"E", 1}, - {"Ɇ", 0}, - {"2", 1}, - {"ƻ", 0}, - {"Y", 1}, - {"Ɏ", 0}, - {"d", 1}, - {"đ", 0}, - {"dead_greek", 2}, - {"r", 1}, - {"ϼ", 0}, - {"D", 1}, - {"Đ", 0}, - {"dead_abovedot", 2}, - {"j", 1}, - {"ɟ", 0}, - {"lessthanequal", 1}, - {"≰", 0}, - {"p", 1}, - {"ᵽ", 0}, - {"J", 1}, - {"Ɉ", 0}, - {"P", 1}, - {"Ᵽ", 0}, - {"O", 1}, - {"Ø", 0}, - {"r", 1}, - {"ɍ", 0}, - {"Z", 1}, - {"Ƶ", 0}, - {"dead_stroke", 1}, - {"/", 0}, - {"A", 1}, - {"Ⱥ", 0}, - {"R", 1}, - {"Ɍ", 0}, - {"c", 1}, - {"ȼ", 0}, - {"L", 1}, - {"Ł", 0}, - {"T", 1}, - {"Ŧ", 0}, - {"greater", 1}, - {"≯", 0}, - {"B", 1}, - {"Ƀ", 0}, - {"dead_acute", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"h", 1}, - {"ħ", 0}, - {"I", 1}, - {"Ɨ", 0}, - {"U", 1}, - {"Ʉ", 0}, - {"dead_hook", 179}, - {"W", 1}, - {"Ⱳ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"g", 1}, - {"ɠ", 0}, - {"a", 1}, - {"ả", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ẩ", 0}, - {"e", 1}, - {"ể", 0}, - {"o", 1}, - {"ổ", 0}, - {"E", 1}, - {"Ể", 0}, - {"O", 1}, - {"Ổ", 0}, - {"A", 1}, - {"Ẩ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ở", 0}, - {"u", 1}, - {"ử", 0}, - {"O", 1}, - {"Ở", 0}, - {"U", 1}, - {"Ử", 0}, - {"Acircumflex", 1}, - {"Ẩ", 0}, - {"C", 1}, - {"Ƈ", 0}, - {"e", 1}, - {"ẻ", 0}, - {"F", 1}, - {"Ƒ", 0}, - {"o", 1}, - {"ỏ", 0}, - {"t", 1}, - {"ƭ", 0}, - {"schwa", 1}, - {"ɚ", 0}, - {"uhorn", 1}, - {"ử", 0}, - {"space", 1}, - {"̉", 0}, - {"acircumflex", 1}, - {"ẩ", 0}, - {"Ecircumflex", 1}, - {"Ể", 0}, - {"y", 1}, - {"ỷ", 0}, - {"b", 1}, - {"ɓ", 0}, - {"Multi_key", 32}, - {"b", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"plus", 8}, - {"o", 1}, - {"ở", 0}, - {"u", 1}, - {"ử", 0}, - {"O", 1}, - {"Ở", 0}, - {"U", 1}, - {"Ử", 0}, - {"U", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ẩ", 0}, - {"e", 1}, - {"ể", 0}, - {"o", 1}, - {"ổ", 0}, - {"E", 1}, - {"Ể", 0}, - {"O", 1}, - {"Ổ", 0}, - {"A", 1}, - {"Ẩ", 0}, - {"i", 1}, - {"ỉ", 0}, - {"k", 1}, - {"ƙ", 0}, - {"n", 1}, - {"ɲ", 0}, - {"Ohorn", 1}, - {"Ở", 0}, - {"ohorn", 1}, - {"ở", 0}, - {"q", 1}, - {"ʠ", 0}, - {"nobreakspace", 1}, - {"̉", 0}, - {"V", 1}, - {"Ʋ", 0}, - {"Ocircumflex", 1}, - {"Ổ", 0}, - {"ocircumflex", 1}, - {"ổ", 0}, - {"u", 1}, - {"ủ", 0}, - {"z", 1}, - {"ȥ", 0}, - {"G", 1}, - {"Ɠ", 0}, - {"E", 1}, - {"Ẻ", 0}, - {"Y", 1}, - {"Ỷ", 0}, - {"f", 1}, - {"ƒ", 0}, - {"d", 1}, - {"ɗ", 0}, - {"dead_greek", 2}, - {"U", 1}, - {"ϒ", 0}, - {"D", 1}, - {"Ɗ", 0}, - {"Abreve", 1}, - {"Ẳ", 0}, - {"ecircumflex", 1}, - {"ể", 0}, - {"w", 1}, - {"ⱳ", 0}, - {"p", 1}, - {"ƥ", 0}, - {"v", 1}, - {"ʋ", 0}, - {"P", 1}, - {"Ƥ", 0}, - {"M", 1}, - {"Ɱ", 0}, - {"O", 1}, - {"Ỏ", 0}, - {"abreve", 1}, - {"ẳ", 0}, - {"m", 1}, - {"ɱ", 0}, - {"r", 1}, - {"ɼ", 0}, - {"s", 1}, - {"ʂ", 0}, - {"Z", 1}, - {"Ȥ", 0}, - {"A", 1}, - {"Ả", 0}, - {"c", 1}, - {"ƈ", 0}, - {"T", 1}, - {"Ƭ", 0}, - {"dead_hook", 1}, - {"̉", 0}, - {"K", 1}, - {"Ƙ", 0}, - {"B", 1}, - {"Ɓ", 0}, - {"Uhorn", 1}, - {"Ử", 0}, - {"h", 1}, - {"ɦ", 0}, - {"I", 1}, - {"Ỉ", 0}, - {"N", 1}, - {"Ɲ", 0}, - {"U", 1}, - {"Ủ", 0}, - {"dead_belowbreve", 4}, - {"H", 1}, - {"Ḫ", 0}, - {"h", 1}, - {"ḫ", 0}, - {"dead_cedilla", 73}, - {"dead_breve", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"g", 1}, - {"ģ", 0}, - {"dead_currency", 4}, - {"C", 1}, - {"₵", 0}, - {"c", 1}, - {"₵", 0}, - {"C", 1}, - {"Ç", 0}, - {"e", 1}, - {"ȩ", 0}, - {"l", 1}, - {"ļ", 0}, - {"t", 1}, - {"ţ", 0}, - {"ColonSign", 1}, - {"₵", 0}, - {"space", 1}, - {"¸", 0}, - {"k", 1}, - {"ķ", 0}, - {"n", 1}, - {"ņ", 0}, - {"nobreakspace", 1}, - {"̧", 0}, - {"G", 1}, - {"Ģ", 0}, - {"H", 1}, - {"Ḩ", 0}, - {"E", 1}, - {"Ȩ", 0}, - {"S", 1}, - {"Ş", 0}, - {"Cacute", 1}, - {"Ḉ", 0}, - {"d", 1}, - {"ḑ", 0}, - {"D", 1}, - {"Ḑ", 0}, - {"cent", 1}, - {"₵", 0}, - {"cacute", 1}, - {"ḉ", 0}, - {"r", 1}, - {"ŗ", 0}, - {"s", 1}, - {"ş", 0}, - {"R", 1}, - {"Ŗ", 0}, - {"c", 1}, - {"ç", 0}, - {"L", 1}, - {"Ļ", 0}, - {"T", 1}, - {"Ţ", 0}, - {"K", 1}, - {"Ķ", 0}, - {"dead_cedilla", 1}, - {"¸", 0}, - {"dead_acute", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"h", 1}, - {"ḩ", 0}, - {"N", 1}, - {"Ņ", 0}, - {"dead_inverted_breve", 24}, - {"a", 1}, - {"ȃ", 0}, - {"e", 1}, - {"ȇ", 0}, - {"o", 1}, - {"ȏ", 0}, - {"i", 1}, - {"ȋ", 0}, - {"u", 1}, - {"ȗ", 0}, - {"E", 1}, - {"Ȇ", 0}, - {"O", 1}, - {"Ȏ", 0}, - {"r", 1}, - {"ȓ", 0}, - {"A", 1}, - {"Ȃ", 0}, - {"R", 1}, - {"Ȓ", 0}, - {"I", 1}, - {"Ȋ", 0}, - {"U", 1}, - {"Ȗ", 0}, - {"dead_diaeresis", 190}, - {"W", 1}, - {"Ẅ", 0}, - {"a", 1}, - {"ä", 0}, - {"Greek_IOTA", 1}, - {"Ϊ", 0}, - {"dead_grave", 4}, - {"u", 1}, - {"ǜ", 0}, - {"U", 1}, - {"Ǜ", 0}, - {"Greek_iota", 1}, - {"ϊ", 0}, - {"Umacron", 1}, - {"Ṻ", 0}, - {"Cyrillic_ZE", 1}, - {"Ӟ", 0}, - {"dead_belowdiaeresis", 2}, - {"equal", 1}, - {"⩷", 0}, - {"e", 1}, - {"ë", 0}, - {"o", 1}, - {"ö", 0}, - {"iacute", 1}, - {"ḯ", 0}, - {"Cyrillic_ze", 1}, - {"ӟ", 0}, - {"t", 1}, - {"ẗ", 0}, - {"Greek_upsilon", 1}, - {"ϋ", 0}, - {"space", 1}, - {"\"", 0}, - {"dead_macron", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ṻ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"Cyrillic_I", 1}, - {"Ӥ", 0}, - {"y", 1}, - {"ÿ", 0}, - {"Multi_key", 15}, - {"underscore", 4}, - {"u", 1}, - {"ṻ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"macron", 4}, - {"u", 1}, - {"ṻ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"asciitilde", 4}, - {"o", 1}, - {"ṏ", 0}, - {"O", 1}, - {"Ṏ", 0}, - {"Cyrillic_O", 1}, - {"Ӧ", 0}, - {"i", 1}, - {"ï", 0}, - {"Ukrainian_I", 1}, - {"Ї", 0}, - {"dead_caron", 4}, - {"u", 1}, - {"ǚ", 0}, - {"U", 1}, - {"Ǚ", 0}, - {"dead_tilde", 4}, - {"o", 1}, - {"ṏ", 0}, - {"O", 1}, - {"Ṏ", 0}, - {"Cyrillic_che", 1}, - {"ӵ", 0}, - {"Uacute", 1}, - {"Ǘ", 0}, - {"Cyrillic_a", 1}, - {"ӓ", 0}, - {"Ugrave", 1}, - {"Ǜ", 0}, - {"x", 1}, - {"ẍ", 0}, - {"amacron", 1}, - {"ǟ", 0}, - {"Cyrillic_U", 1}, - {"Ӱ", 0}, - {"nobreakspace", 1}, - {"̈", 0}, - {"omacron", 1}, - {"ȫ", 0}, - {"uacute", 1}, - {"ǘ", 0}, - {"u", 1}, - {"ü", 0}, - {"otilde", 1}, - {"ṏ", 0}, - {"Iacute", 1}, - {"Ḯ", 0}, - {"H", 1}, - {"Ḧ", 0}, - {"Cyrillic_YERU", 1}, - {"Ӹ", 0}, - {"Cyrillic_ie", 1}, - {"ё", 0}, - {"E", 1}, - {"Ë", 0}, - {"Y", 1}, - {"Ÿ", 0}, - {"Cyrillic_i", 1}, - {"ӥ", 0}, - {"Otilde", 1}, - {"Ṏ", 0}, - {"Cyrillic_zhe", 1}, - {"ӝ", 0}, - {"umacron", 1}, - {"ṻ", 0}, - {"Cyrillic_yeru", 1}, - {"ӹ", 0}, - {"acute", 1}, - {"̈́", 0}, - {"w", 1}, - {"ẅ", 0}, - {"Cyrillic_CHE", 1}, - {"Ӵ", 0}, - {"Cyrillic_o", 1}, - {"ӧ", 0}, - {"Ukrainian_i", 1}, - {"ї", 0}, - {"Cyrillic_E", 1}, - {"Ӭ", 0}, - {"apostrophe", 1}, - {"̈́", 0}, - {"O", 1}, - {"Ö", 0}, - {"A", 1}, - {"Ä", 0}, - {"Cyrillic_A", 1}, - {"Ӓ", 0}, - {"ugrave", 1}, - {"ǜ", 0}, - {"Omacron", 1}, - {"Ȫ", 0}, - {"Cyrillic_ZHE", 1}, - {"Ӝ", 0}, - {"Cyrillic_IE", 1}, - {"Ё", 0}, - {"dead_diaeresis", 1}, - {"¨", 0}, - {"Amacron", 1}, - {"Ǟ", 0}, - {"Cyrillic_e", 1}, - {"ӭ", 0}, - {"dead_acute", 14}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"space", 1}, - {"΅", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"X", 1}, - {"Ẍ", 0}, - {"h", 1}, - {"ḧ", 0}, - {"I", 1}, - {"Ï", 0}, - {"U", 1}, - {"Ü", 0}, - {"Cyrillic_u", 1}, - {"ӱ", 0}, - {"Greek_UPSILON", 1}, - {"Ϋ", 0}, - {"dead_acute", 500}, - {"W", 1}, - {"Ẃ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"g", 1}, - {"ǵ", 0}, - {"a", 1}, - {"á", 0}, - {"Greek_IOTA", 1}, - {"Ί", 0}, - {"Greek_iota", 1}, - {"ί", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Greek_OMICRON", 1}, - {"Ό", 0}, - {"Acircumflex", 1}, - {"Ấ", 0}, - {"C", 1}, - {"Ć", 0}, - {"Cyrillic_er", 1}, - {"р́", 0}, - {"e", 1}, - {"é", 0}, - {"Utilde", 1}, - {"Ṹ", 0}, - {"o", 1}, - {"ó", 0}, - {"l", 1}, - {"ĺ", 0}, - {"Udiaeresis", 1}, - {"Ǘ", 0}, - {"Greek_upsilon", 1}, - {"ύ", 0}, - {"uhorn", 1}, - {"ứ", 0}, - {"space", 1}, - {"'", 0}, - {"dead_macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"acircumflex", 1}, - {"ấ", 0}, - {"Ecircumflex", 1}, - {"Ế", 0}, - {"Cyrillic_I", 1}, - {"И́", 0}, - {"y", 1}, - {"ý", 0}, - {"Multi_key", 153}, - {"KP_Divide", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"o", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"b", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"parenright", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"quotedbl", 12}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"plus", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"underscore", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"comma", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"asciitilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"slash", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"parenleft", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"U", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"idiaeresis", 1}, - {"ḯ", 0}, - {"Cyrillic_O", 1}, - {"О́", 0}, - {"i", 1}, - {"í", 0}, - {"k", 1}, - {"ḱ", 0}, - {"n", 1}, - {"ń", 0}, - {"ccedilla", 1}, - {"ḉ", 0}, - {"Cyrillic_GHE", 1}, - {"Ѓ", 0}, - {"dead_tilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"Cyrillic_a", 1}, - {"а́", 0}, - {"Ohorn", 1}, - {"Ớ", 0}, - {"ohorn", 1}, - {"ớ", 0}, - {"sabovedot", 1}, - {"ṥ", 0}, - {"Cyrillic_ER", 1}, - {"Р́", 0}, - {"Greek_epsilon", 1}, - {"έ", 0}, - {"Cyrillic_KA", 1}, - {"Ќ", 0}, - {"Cyrillic_U", 1}, - {"У́", 0}, - {"dead_abovering", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"nobreakspace", 1}, - {"́", 0}, - {"V", 1}, - {"Ǘ", 0}, - {"Ocircumflex", 1}, - {"Ố", 0}, - {"AE", 1}, - {"Ǽ", 0}, - {"omacron", 1}, - {"ṓ", 0}, - {"ocircumflex", 1}, - {"ố", 0}, - {"u", 1}, - {"ú", 0}, - {"z", 1}, - {"ź", 0}, - {"G", 1}, - {"Ǵ", 0}, - {"Greek_ALPHA", 1}, - {"Ά", 0}, - {"otilde", 1}, - {"ṍ", 0}, - {"utilde", 1}, - {"ṹ", 0}, - {"Cyrillic_ie", 1}, - {"е́", 0}, - {"emacron", 1}, - {"ḗ", 0}, - {"E", 1}, - {"É", 0}, - {"S", 1}, - {"Ś", 0}, - {"Greek_iotadieresis", 1}, - {"ΐ", 0}, - {"Y", 1}, - {"Ý", 0}, - {"Cyrillic_i", 1}, - {"и́", 0}, - {"dead_dasia", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"Greek_upsilondieresis", 1}, - {"ΰ", 0}, - {"Greek_omicron", 1}, - {"ό", 0}, - {"Greek_eta", 1}, - {"ή", 0}, - {"Otilde", 1}, - {"Ṍ", 0}, - {"Cyrillic_ka", 1}, - {"ќ", 0}, - {"Aring", 1}, - {"Ǻ", 0}, - {"Abreve", 1}, - {"Ắ", 0}, - {"dead_psili", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"Greek_alpha", 1}, - {"ά", 0}, - {"ecircumflex", 1}, - {"ế", 0}, - {"dead_abovedot", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"w", 1}, - {"ẃ", 0}, - {"Greek_ETA", 1}, - {"Ή", 0}, - {"Cyrillic_o", 1}, - {"о́", 0}, - {"Emacron", 1}, - {"Ḗ", 0}, - {"Ooblique", 1}, - {"Ǿ", 0}, - {"p", 1}, - {"ṕ", 0}, - {"v", 1}, - {"ǘ", 0}, - {"P", 1}, - {"Ṕ", 0}, - {"M", 1}, - {"Ḿ", 0}, - {"O", 1}, - {"Ó", 0}, - {"abreve", 1}, - {"ắ", 0}, - {"m", 1}, - {"ḿ", 0}, - {"r", 1}, - {"ŕ", 0}, - {"s", 1}, - {"ś", 0}, - {"Z", 1}, - {"Ź", 0}, - {"dead_stroke", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"A", 1}, - {"Á", 0}, - {"R", 1}, - {"Ŕ", 0}, - {"c", 1}, - {"ć", 0}, - {"Idiaeresis", 1}, - {"Ḯ", 0}, - {"L", 1}, - {"Ĺ", 0}, - {"Greek_EPSILON", 1}, - {"Έ", 0}, - {"Cyrillic_A", 1}, - {"А́", 0}, - {"Ccedilla", 1}, - {"Ḉ", 0}, - {"aring", 1}, - {"ǻ", 0}, - {"K", 1}, - {"Ḱ", 0}, - {"Omacron", 1}, - {"Ṓ", 0}, - {"Cyrillic_IE", 1}, - {"Е́", 0}, - {"Sabovedot", 1}, - {"Ṥ", 0}, - {"dead_cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"Greek_omega", 1}, - {"ώ", 0}, - {"dead_diaeresis", 14}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"space", 1}, - {"΅", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"Uhorn", 1}, - {"Ứ", 0}, - {"Greek_OMEGA", 1}, - {"Ώ", 0}, - {"dead_acute", 1}, - {"´", 0}, - {"oslash", 1}, - {"ǿ", 0}, - {"Cyrillic_ghe", 1}, - {"ѓ", 0}, - {"udiaeresis", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Í", 0}, - {"N", 1}, - {"Ń", 0}, - {"U", 1}, - {"Ú", 0}, - {"Cyrillic_u", 1}, - {"у́", 0}, - {"ae", 1}, - {"ǽ", 0}, - {"Greek_UPSILON", 1}, - {"Ύ", 0}, - {"dead_belowmacron", 34}, - {"l", 1}, - {"ḻ", 0}, - {"t", 1}, - {"ṯ", 0}, - {"b", 1}, - {"ḇ", 0}, - {"k", 1}, - {"ḵ", 0}, - {"n", 1}, - {"ṉ", 0}, - {"z", 1}, - {"ẕ", 0}, - {"d", 1}, - {"ḏ", 0}, - {"D", 1}, - {"Ḏ", 0}, - {"r", 1}, - {"ṟ", 0}, - {"Z", 1}, - {"Ẕ", 0}, - {"R", 1}, - {"Ṟ", 0}, - {"L", 1}, - {"Ḻ", 0}, - {"T", 1}, - {"Ṯ", 0}, - {"K", 1}, - {"Ḵ", 0}, - {"B", 1}, - {"Ḇ", 0}, - {"h", 1}, - {"ẖ", 0}, - {"N", 1}, - {"Ṉ", 0}, - {"dead_belowring", 6}, - {"a", 1}, - {"ḁ", 0}, - {"bar", 1}, - {"⫰", 0}, - {"A", 1}, - {"Ḁ", 0}, - {NULL, 0}, -}; +static const char *comp = + "dead_breve\x00" "\x83\x07" /* 'dead_breve' 775 */ + "dead_breve\x00" "\x10" /* 'dead_breve' 16 */ + "˘\x00" "\x04" /* '˘' 4 */ + "g\x00" "\x07" /* 'g' 7 */ + "ğ\x00" "\x04" /* 'ğ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "ă\x00" "\x04" /* 'ă' 4 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ῐ\x00" "\x05" /* 'Ῐ' 5 */ + "dead_grave\x00" "\x1c" /* 'dead_grave' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ằ\x00" "\x05" /* 'ằ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ằ\x00" "\x05" /* 'Ằ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῐ\x00" "\x05" /* 'ῐ' 5 */ + "e\x00" "\x07" /* 'e' 7 */ + "ĕ\x00" "\x04" /* 'ĕ' 4 */ + "agrave\x00" "\x0d" /* 'agrave' 13 */ + "ằ\x00" "\x05" /* 'ằ' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "ŏ\x00" "\x04" /* 'ŏ' 4 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῠ\x00" "\x05" /* 'ῠ' 5 */ + "ahook\x00" "\x0c" /* 'ahook' 12 */ + "ẳ\x00" "\x05" /* 'ẳ' 5 */ + "dead_belowdot\x00" "\x1f" /* 'dead_belowdot' 31 */ + "a\x00" "\x08" /* 'a' 8 */ + "ặ\x00" "\x05" /* 'ặ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ặ\x00" "\x05" /* 'Ặ' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "˘\x00" "\x04" /* '˘' 4 */ + "Cyrillic_I\x00" "\x10" /* 'Cyrillic_I' 16 */ + "Й\x00" "\x04" /* 'Й' 4 */ + "Multi_key\x00" "\x53" /* 'Multi_key' 83 */ + "exclam\x00" "\x18" /* 'exclam' 24 */ + "a\x00" "\x08" /* 'a' 8 */ + "ặ\x00" "\x05" /* 'ặ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ặ\x00" "\x05" /* 'Ặ' 5 */ + "cedilla\x00" "\x19" /* 'cedilla' 25 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḝ\x00" "\x05" /* 'ḝ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḝ\x00" "\x05" /* 'Ḝ' 5 */ + "comma\x00" "\x17" /* 'comma' 23 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḝ\x00" "\x05" /* 'ḝ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḝ\x00" "\x05" /* 'Ḝ' 5 */ + "i\x00" "\x07" /* 'i' 7 */ + "ĭ\x00" "\x04" /* 'ĭ' 4 */ + "dead_tilde\x00" "\x1c" /* 'dead_tilde' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẵ\x00" "\x05" /* 'ẵ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẵ\x00" "\x05" /* 'Ẵ' 5 */ + "Cyrillic_a\x00" "\x10" /* 'Cyrillic_a' 16 */ + "ӑ\x00" "\x04" /* 'ӑ' 4 */ + "Cyrillic_U\x00" "\x10" /* 'Cyrillic_U' 16 */ + "Ў\x00" "\x04" /* 'Ў' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̆\x00" "\x04" /* '̆' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ŭ\x00" "\x04" /* 'ŭ' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ğ\x00" "\x04" /* 'Ğ' 4 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ᾰ\x00" "\x05" /* 'Ᾰ' 5 */ + "atilde\x00" "\x0d" /* 'atilde' 13 */ + "ẵ\x00" "\x05" /* 'ẵ' 5 */ + "Cyrillic_ie\x00" "\x11" /* 'Cyrillic_ie' 17 */ + "ӗ\x00" "\x04" /* 'ӗ' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ĕ\x00" "\x04" /* 'Ĕ' 4 */ + "Cyrillic_i\x00" "\x10" /* 'Cyrillic_i' 16 */ + "й\x00" "\x04" /* 'й' 4 */ + "Atilde\x00" "\x0d" /* 'Atilde' 13 */ + "Ẵ\x00" "\x05" /* 'Ẵ' 5 */ + "Cyrillic_zhe\x00" "\x12" /* 'Cyrillic_zhe' 18 */ + "ӂ\x00" "\x04" /* 'ӂ' 4 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾰ\x00" "\x05" /* 'ᾰ' 5 */ + "Ahook\x00" "\x0c" /* 'Ahook' 12 */ + "Ẳ\x00" "\x05" /* 'Ẳ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ŏ\x00" "\x04" /* 'Ŏ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ă\x00" "\x04" /* 'Ă' 4 */ + "Cyrillic_A\x00" "\x10" /* 'Cyrillic_A' 16 */ + "Ӑ\x00" "\x04" /* 'Ӑ' 4 */ + "dead_hook\x00" "\x1b" /* 'dead_hook' 27 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẳ\x00" "\x05" /* 'ẳ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẳ\x00" "\x05" /* 'Ẳ' 5 */ + "Cyrillic_ZHE\x00" "\x12" /* 'Cyrillic_ZHE' 18 */ + "Ӂ\x00" "\x04" /* 'Ӂ' 4 */ + "Cyrillic_IE\x00" "\x11" /* 'Cyrillic_IE' 17 */ + "Ӗ\x00" "\x04" /* 'Ӗ' 4 */ + "Aacute\x00" "\x0d" /* 'Aacute' 13 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "dead_cedilla\x00" "\x1e" /* 'dead_cedilla' 30 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḝ\x00" "\x05" /* 'ḝ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḝ\x00" "\x05" /* 'Ḝ' 5 */ + "aacute\x00" "\x0d" /* 'aacute' 13 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "dead_acute\x00" "\x1c" /* 'dead_acute' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "Agrave\x00" "\x0d" /* 'Agrave' 13 */ + "Ằ\x00" "\x05" /* 'Ằ' 5 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ĭ\x00" "\x04" /* 'Ĭ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ŭ\x00" "\x04" /* 'Ŭ' 4 */ + "Cyrillic_u\x00" "\x10" /* 'Cyrillic_u' 16 */ + "ў\x00" "\x04" /* 'ў' 4 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ῠ\x00" "\x05" /* 'Ῠ' 5 */ + "dead_grave\x00" "\x8a\x04" /* 'dead_grave' 2564 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẁ\x00" "\x05" /* 'Ẁ' 5 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ằ\x00" "\x05" /* 'ằ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ằ\x00" "\x05" /* 'Ằ' 5 */ + "a\x00" "\x07" /* 'a' 7 */ + "à\x00" "\x04" /* 'à' 4 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ὶ\x00" "\x05" /* 'Ὶ' 5 */ + "dead_grave\x00" "\x0f" /* 'dead_grave' 15 */ + "`\x00" "\x03" /* '`' 3 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ờ\x00" "\x05" /* 'ờ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ừ\x00" "\x05" /* 'ừ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ờ\x00" "\x05" /* 'Ờ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ừ\x00" "\x05" /* 'Ừ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ὶ\x00" "\x05" /* 'ὶ' 5 */ + "dead_circumflex\x00" "\x41" /* 'dead_circumflex' 65 */ + "a\x00" "\x08" /* 'a' 8 */ + "ầ\x00" "\x05" /* 'ầ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ề\x00" "\x05" /* 'ề' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ồ\x00" "\x05" /* 'ồ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ề\x00" "\x05" /* 'Ề' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ồ\x00" "\x05" /* 'Ồ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ầ\x00" "\x05" /* 'Ầ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὸ\x00" "\x05" /* 'Ὸ' 5 */ + "Acircumflex\x00" "\x12" /* 'Acircumflex' 18 */ + "Ầ\x00" "\x05" /* 'Ầ' 5 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р̀\x00" "\x06" /* 'р̀' 6 */ + "e\x00" "\x07" /* 'e' 7 */ + "è\x00" "\x04" /* 'è' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ò\x00" "\x04" /* 'ò' 4 */ + "Udiaeresis\x00" "\x10" /* 'Udiaeresis' 16 */ + "Ǜ\x00" "\x04" /* 'Ǜ' 4 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὺ\x00" "\x05" /* 'ὺ' 5 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ừ\x00" "\x05" /* 'ừ' 5 */ + "space\x00" "\x0a" /* 'space' 10 */ + "`\x00" "\x03" /* '`' 3 */ + "dead_macron\x00" "\x2d" /* 'dead_macron' 45 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḕ\x00" "\x05" /* 'ḕ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṑ\x00" "\x05" /* 'ṑ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḕ\x00" "\x05" /* 'Ḕ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṑ\x00" "\x05" /* 'Ṑ' 5 */ + "acircumflex\x00" "\x12" /* 'acircumflex' 18 */ + "ầ\x00" "\x05" /* 'ầ' 5 */ + "Ecircumflex\x00" "\x12" /* 'Ecircumflex' 18 */ + "Ề\x00" "\x05" /* 'Ề' 5 */ + "Cyrillic_I\x00" "\x10" /* 'Cyrillic_I' 16 */ + "Ѝ\x00" "\x04" /* 'Ѝ' 4 */ + "y\x00" "\x08" /* 'y' 8 */ + "ỳ\x00" "\x05" /* 'ỳ' 5 */ + "Multi_key\x00" "\x83\x2f" /* 'Multi_key' 815 */ + "b\x00" "\x13" /* 'b' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ằ\x00" "\x05" /* 'ằ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ằ\x00" "\x05" /* 'Ằ' 5 */ + "parenright\x00" "\x80\xfb" /* 'parenright' 251 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἲ\x00" "\x05" /* 'Ἲ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἲ\x00" "\x05" /* 'ἲ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὂ\x00" "\x05" /* 'Ὂ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὒ\x00" "\x05" /* 'ὒ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἒ\x00" "\x05" /* 'ἒ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἂ\x00" "\x05" /* 'Ἂ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὂ\x00" "\x05" /* 'ὂ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἢ\x00" "\x05" /* 'ἢ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἂ\x00" "\x05" /* 'ἂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἢ\x00" "\x05" /* 'Ἢ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἒ\x00" "\x05" /* 'Ἒ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὢ\x00" "\x05" /* 'ὢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὢ\x00" "\x05" /* 'Ὢ' 5 */ + "quotedbl\x00" "\x3d" /* 'quotedbl' 61 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῒ\x00" "\x05" /* 'ῒ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῢ\x00" "\x05" /* 'ῢ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǜ\x00" "\x04" /* 'ǜ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǜ\x00" "\x04" /* 'Ǜ' 4 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ờ\x00" "\x05" /* 'ờ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ừ\x00" "\x05" /* 'ừ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ờ\x00" "\x05" /* 'Ờ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ừ\x00" "\x05" /* 'Ừ' 5 */ + "underscore\x00" "\x2c" /* 'underscore' 44 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḕ\x00" "\x05" /* 'ḕ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṑ\x00" "\x05" /* 'ṑ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḕ\x00" "\x05" /* 'Ḕ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṑ\x00" "\x05" /* 'Ṑ' 5 */ + "macron\x00" "\x28" /* 'macron' 40 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḕ\x00" "\x05" /* 'ḕ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṑ\x00" "\x05" /* 'ṑ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḕ\x00" "\x05" /* 'Ḕ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṑ\x00" "\x05" /* 'Ṑ' 5 */ + "parenleft\x00" "\x81\x0e" /* 'parenleft' 270 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἳ\x00" "\x05" /* 'Ἳ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἳ\x00" "\x05" /* 'ἳ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὃ\x00" "\x05" /* 'Ὃ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὓ\x00" "\x05" /* 'ὓ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἓ\x00" "\x05" /* 'ἓ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἃ\x00" "\x05" /* 'Ἃ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὃ\x00" "\x05" /* 'ὃ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἣ\x00" "\x05" /* 'ἣ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἃ\x00" "\x05" /* 'ἃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἣ\x00" "\x05" /* 'Ἣ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἓ\x00" "\x05" /* 'Ἓ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὣ\x00" "\x05" /* 'ὣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὣ\x00" "\x05" /* 'Ὣ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὓ\x00" "\x05" /* 'Ὓ' 5 */ + "U\x00" "\x13" /* 'U' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ằ\x00" "\x05" /* 'ằ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ằ\x00" "\x05" /* 'Ằ' 5 */ + "asciicircum\x00" "\x3d" /* 'asciicircum' 61 */ + "a\x00" "\x08" /* 'a' 8 */ + "ầ\x00" "\x05" /* 'ầ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ề\x00" "\x05" /* 'ề' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ồ\x00" "\x05" /* 'ồ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ề\x00" "\x05" /* 'Ề' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ồ\x00" "\x05" /* 'Ồ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ầ\x00" "\x05" /* 'Ầ' 5 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О̀\x00" "\x06" /* 'О̀' 6 */ + "i\x00" "\x07" /* 'i' 7 */ + "ì\x00" "\x04" /* 'ì' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ǹ\x00" "\x04" /* 'ǹ' 4 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а̀\x00" "\x06" /* 'а̀' 6 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ờ\x00" "\x05" /* 'Ờ' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ờ\x00" "\x05" /* 'ờ' 5 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р̀\x00" "\x06" /* 'Р̀' 6 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ὲ\x00" "\x05" /* 'ὲ' 5 */ + "Cyrillic_U\x00" "\x12" /* 'Cyrillic_U' 18 */ + "У̀\x00" "\x06" /* 'У̀' 6 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̀\x00" "\x04" /* '̀' 4 */ + "V\x00" "\x07" /* 'V' 7 */ + "Ǜ\x00" "\x04" /* 'Ǜ' 4 */ + "Ocircumflex\x00" "\x12" /* 'Ocircumflex' 18 */ + "Ồ\x00" "\x05" /* 'Ồ' 5 */ + "omacron\x00" "\x0e" /* 'omacron' 14 */ + "ṑ\x00" "\x05" /* 'ṑ' 5 */ + "ocircumflex\x00" "\x12" /* 'ocircumflex' 18 */ + "ồ\x00" "\x05" /* 'ồ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ù\x00" "\x04" /* 'ù' 4 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ὰ\x00" "\x05" /* 'Ὰ' 5 */ + "Cyrillic_ie\x00" "\x11" /* 'Cyrillic_ie' 17 */ + "ѐ\x00" "\x04" /* 'ѐ' 4 */ + "emacron\x00" "\x0e" /* 'emacron' 14 */ + "ḕ\x00" "\x05" /* 'ḕ' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "È\x00" "\x04" /* 'È' 4 */ + "Greek_iotadieresis\x00" "\x19" /* 'Greek_iotadieresis' 25 */ + "ῒ\x00" "\x05" /* 'ῒ' 5 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "Ỳ\x00" "\x05" /* 'Ỳ' 5 */ + "Cyrillic_i\x00" "\x10" /* 'Cyrillic_i' 16 */ + "ѝ\x00" "\x04" /* 'ѝ' 4 */ + "dead_dasia\x00" "\x81\x0f" /* 'dead_dasia' 271 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἳ\x00" "\x05" /* 'Ἳ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἳ\x00" "\x05" /* 'ἳ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὃ\x00" "\x05" /* 'Ὃ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὓ\x00" "\x05" /* 'ὓ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἓ\x00" "\x05" /* 'ἓ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἃ\x00" "\x05" /* 'Ἃ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὃ\x00" "\x05" /* 'ὃ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἣ\x00" "\x05" /* 'ἣ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἃ\x00" "\x05" /* 'ἃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἣ\x00" "\x05" /* 'Ἣ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἓ\x00" "\x05" /* 'Ἓ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὣ\x00" "\x05" /* 'ὣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὣ\x00" "\x05" /* 'Ὣ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὓ\x00" "\x05" /* 'Ὓ' 5 */ + "Greek_upsilondieresis\x00" "\x1c" /* 'Greek_upsilondieresis' 28 */ + "ῢ\x00" "\x05" /* 'ῢ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὸ\x00" "\x05" /* 'ὸ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ὴ\x00" "\x05" /* 'ὴ' 5 */ + "Abreve\x00" "\x0d" /* 'Abreve' 13 */ + "Ằ\x00" "\x05" /* 'Ằ' 5 */ + "dead_psili\x00" "\x80\xfb" /* 'dead_psili' 251 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἲ\x00" "\x05" /* 'Ἲ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἲ\x00" "\x05" /* 'ἲ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὂ\x00" "\x05" /* 'Ὂ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὒ\x00" "\x05" /* 'ὒ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἒ\x00" "\x05" /* 'ἒ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἂ\x00" "\x05" /* 'Ἂ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὂ\x00" "\x05" /* 'ὂ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἢ\x00" "\x05" /* 'ἢ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἂ\x00" "\x05" /* 'ἂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἢ\x00" "\x05" /* 'Ἢ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἒ\x00" "\x05" /* 'Ἒ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὢ\x00" "\x05" /* 'ὢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὢ\x00" "\x05" /* 'Ὢ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ὰ\x00" "\x05" /* 'ὰ' 5 */ + "ecircumflex\x00" "\x12" /* 'ecircumflex' 18 */ + "ề\x00" "\x05" /* 'ề' 5 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẁ\x00" "\x05" /* 'ẁ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ὴ\x00" "\x05" /* 'Ὴ' 5 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о̀\x00" "\x06" /* 'о̀' 6 */ + "Emacron\x00" "\x0e" /* 'Emacron' 14 */ + "Ḕ\x00" "\x05" /* 'Ḕ' 5 */ + "v\x00" "\x07" /* 'v' 7 */ + "ǜ\x00" "\x04" /* 'ǜ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ò\x00" "\x04" /* 'Ò' 4 */ + "abreve\x00" "\x0d" /* 'abreve' 13 */ + "ằ\x00" "\x05" /* 'ằ' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "À\x00" "\x04" /* 'À' 4 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ὲ\x00" "\x05" /* 'Ὲ' 5 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А̀\x00" "\x06" /* 'А̀' 6 */ + "Omacron\x00" "\x0e" /* 'Omacron' 14 */ + "Ṑ\x00" "\x05" /* 'Ṑ' 5 */ + "Cyrillic_IE\x00" "\x11" /* 'Cyrillic_IE' 17 */ + "Ѐ\x00" "\x04" /* 'Ѐ' 4 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὼ\x00" "\x05" /* 'ὼ' 5 */ + "dead_diaeresis\x00" "\x43" /* 'dead_diaeresis' 67 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῒ\x00" "\x05" /* 'ῒ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῢ\x00" "\x05" /* 'ῢ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǜ\x00" "\x04" /* 'ǜ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǜ\x00" "\x04" /* 'Ǜ' 4 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ừ\x00" "\x05" /* 'Ừ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὼ\x00" "\x05" /* 'Ὼ' 5 */ + "udiaeresis\x00" "\x10" /* 'udiaeresis' 16 */ + "ǜ\x00" "\x04" /* 'ǜ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ì\x00" "\x04" /* 'Ì' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ǹ\x00" "\x04" /* 'Ǹ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ù\x00" "\x04" /* 'Ù' 4 */ + "Cyrillic_u\x00" "\x12" /* 'Cyrillic_u' 18 */ + "у̀\x00" "\x06" /* 'у̀' 6 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὺ\x00" "\x05" /* 'Ὺ' 5 */ + "dead_horn\x00" "\x82\x3e" /* 'dead_horn' 574 */ + "Uhook\x00" "\x0c" /* 'Uhook' 12 */ + "Ử\x00" "\x05" /* 'Ử' 5 */ + "Obelowdot\x00" "\x10" /* 'Obelowdot' 16 */ + "Ợ\x00" "\x05" /* 'Ợ' 5 */ + "Ograve\x00" "\x0d" /* 'Ograve' 13 */ + "Ờ\x00" "\x05" /* 'Ờ' 5 */ + "dead_grave\x00" "\x2c" /* 'dead_grave' 44 */ + "o\x00" "\x08" /* 'o' 8 */ + "ờ\x00" "\x05" /* 'ờ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ừ\x00" "\x05" /* 'ừ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ờ\x00" "\x05" /* 'Ờ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ừ\x00" "\x05" /* 'Ừ' 5 */ + "dead_horn\x00" "\x0f" /* 'dead_horn' 15 */ + "̛\x00" "\x04" /* '̛' 4 */ + "Oacute\x00" "\x0d" /* 'Oacute' 13 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "ohook\x00" "\x0c" /* 'ohook' 12 */ + "ở\x00" "\x05" /* 'ở' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "ơ\x00" "\x04" /* 'ơ' 4 */ + "Utilde\x00" "\x0d" /* 'Utilde' 13 */ + "Ữ\x00" "\x05" /* 'Ữ' 5 */ + "dead_belowdot\x00" "\x2f" /* 'dead_belowdot' 47 */ + "o\x00" "\x08" /* 'o' 8 */ + "ợ\x00" "\x05" /* 'ợ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ự\x00" "\x05" /* 'ự' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ợ\x00" "\x05" /* 'Ợ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ự\x00" "\x05" /* 'Ự' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "̛\x00" "\x04" /* '̛' 4 */ + "ubelowdot\x00" "\x10" /* 'ubelowdot' 16 */ + "ự\x00" "\x05" /* 'ự' 5 */ + "oacute\x00" "\x0d" /* 'oacute' 13 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "uhook\x00" "\x0c" /* 'uhook' 12 */ + "ử\x00" "\x05" /* 'ử' 5 */ + "dead_tilde\x00" "\x2c" /* 'dead_tilde' 44 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỡ\x00" "\x05" /* 'ỡ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ữ\x00" "\x05" /* 'ữ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỡ\x00" "\x05" /* 'Ỡ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ữ\x00" "\x05" /* 'Ữ' 5 */ + "Uacute\x00" "\x0d" /* 'Uacute' 13 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "Ugrave\x00" "\x0d" /* 'Ugrave' 13 */ + "Ừ\x00" "\x05" /* 'Ừ' 5 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̛\x00" "\x04" /* '̛' 4 */ + "uacute\x00" "\x0d" /* 'uacute' 13 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ư\x00" "\x04" /* 'ư' 4 */ + "otilde\x00" "\x0d" /* 'otilde' 13 */ + "ỡ\x00" "\x05" /* 'ỡ' 5 */ + "utilde\x00" "\x0d" /* 'utilde' 13 */ + "ữ\x00" "\x05" /* 'ữ' 5 */ + "Otilde\x00" "\x0d" /* 'Otilde' 13 */ + "Ỡ\x00" "\x05" /* 'Ỡ' 5 */ + "ograve\x00" "\x0d" /* 'ograve' 13 */ + "ờ\x00" "\x05" /* 'ờ' 5 */ + "Ohook\x00" "\x0c" /* 'Ohook' 12 */ + "Ở\x00" "\x05" /* 'Ở' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ơ\x00" "\x04" /* 'Ơ' 4 */ + "Ubelowdot\x00" "\x10" /* 'Ubelowdot' 16 */ + "Ự\x00" "\x05" /* 'Ự' 5 */ + "dead_hook\x00" "\x2b" /* 'dead_hook' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ở\x00" "\x05" /* 'ở' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ử\x00" "\x05" /* 'ử' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ở\x00" "\x05" /* 'Ở' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ử\x00" "\x05" /* 'Ử' 5 */ + "ugrave\x00" "\x0d" /* 'ugrave' 13 */ + "ừ\x00" "\x05" /* 'ừ' 5 */ + "obelowdot\x00" "\x10" /* 'obelowdot' 16 */ + "ợ\x00" "\x05" /* 'ợ' 5 */ + "dead_acute\x00" "\x2c" /* 'dead_acute' 44 */ + "o\x00" "\x08" /* 'o' 8 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ư\x00" "\x04" /* 'Ư' 4 */ + "dead_circumflex\x00" "\x86\xae" /* 'dead_circumflex' 1710 */ + "minus\x00" "\x0c" /* 'minus' 12 */ + "⁻\x00" "\x05" /* '⁻' 5 */ + "W\x00" "\x07" /* 'W' 7 */ + "Ŵ\x00" "\x04" /* 'Ŵ' 4 */ + "g\x00" "\x07" /* 'g' 7 */ + "ĝ\x00" "\x04" /* 'ĝ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "â\x00" "\x04" /* 'â' 4 */ + "Ograve\x00" "\x0d" /* 'Ograve' 13 */ + "Ồ\x00" "\x05" /* 'Ồ' 5 */ + "dead_circumflex\x00" "\x14" /* 'dead_circumflex' 20 */ + "^\x00" "\x03" /* '^' 3 */ + "dead_grave\x00" "\x3c" /* 'dead_grave' 60 */ + "a\x00" "\x08" /* 'a' 8 */ + "ầ\x00" "\x05" /* 'ầ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ề\x00" "\x05" /* 'ề' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ồ\x00" "\x05" /* 'ồ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ề\x00" "\x05" /* 'Ề' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ồ\x00" "\x05" /* 'Ồ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ầ\x00" "\x05" /* 'Ầ' 5 */ + "Ehook\x00" "\x0c" /* 'Ehook' 12 */ + "Ể\x00" "\x05" /* 'Ể' 5 */ + "1\x00" "\x07" /* '1' 7 */ + "¹\x00" "\x04" /* '¹' 4 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ĉ\x00" "\x04" /* 'Ĉ' 4 */ + "KP_4\x00" "\x0b" /* 'KP_4' 11 */ + "⁴\x00" "\x05" /* '⁴' 5 */ + "Oacute\x00" "\x0d" /* 'Oacute' 13 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р̂\x00" "\x06" /* 'р̂' 6 */ + "ohook\x00" "\x0c" /* 'ohook' 12 */ + "ổ\x00" "\x05" /* 'ổ' 5 */ + "e\x00" "\x07" /* 'e' 7 */ + "ê\x00" "\x04" /* 'ê' 4 */ + "agrave\x00" "\x0d" /* 'agrave' 13 */ + "ầ\x00" "\x05" /* 'ầ' 5 */ + "KP_6\x00" "\x0b" /* 'KP_6' 11 */ + "⁶\x00" "\x05" /* '⁶' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "ô\x00" "\x04" /* 'ô' 4 */ + "ahook\x00" "\x0c" /* 'ahook' 12 */ + "ẩ\x00" "\x05" /* 'ẩ' 5 */ + "dead_belowdot\x00" "\x3f" /* 'dead_belowdot' 63 */ + "a\x00" "\x08" /* 'a' 8 */ + "ậ\x00" "\x05" /* 'ậ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ệ\x00" "\x05" /* 'ệ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ộ\x00" "\x05" /* 'ộ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ệ\x00" "\x05" /* 'Ệ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ộ\x00" "\x05" /* 'Ộ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ậ\x00" "\x05" /* 'Ậ' 5 */ + "space\x00" "\x0a" /* 'space' 10 */ + "^\x00" "\x03" /* '^' 3 */ + "KP_8\x00" "\x0b" /* 'KP_8' 11 */ + "⁸\x00" "\x05" /* '⁸' 5 */ + "Etilde\x00" "\x0d" /* 'Etilde' 13 */ + "Ễ\x00" "\x05" /* 'Ễ' 5 */ + "Cyrillic_I\x00" "\x12" /* 'Cyrillic_I' 18 */ + "И̂\x00" "\x06" /* 'И̂' 6 */ + "y\x00" "\x07" /* 'y' 7 */ + "ŷ\x00" "\x04" /* 'ŷ' 4 */ + "Multi_key\x00" "\x81\x52" /* 'Multi_key' 338 */ + "exclam\x00" "\x38" /* 'exclam' 56 */ + "a\x00" "\x08" /* 'a' 8 */ + "ậ\x00" "\x05" /* 'ậ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ệ\x00" "\x05" /* 'ệ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ộ\x00" "\x05" /* 'ộ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ệ\x00" "\x05" /* 'Ệ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ộ\x00" "\x05" /* 'Ộ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ậ\x00" "\x05" /* 'Ậ' 5 */ + "t\x00" "\x13" /* 't' 19 */ + "M\x00" "\x08" /* 'M' 8 */ + "™\x00" "\x05" /* '™' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "™\x00" "\x05" /* '™' 5 */ + "underbar\x00" "\x60" /* 'underbar' 96 */ + "a\x00" "\x07" /* 'a' 7 */ + "ª\x00" "\x04" /* 'ª' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "º\x00" "\x04" /* 'º' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ˡ\x00" "\x04" /* 'ˡ' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ʸ\x00" "\x04" /* 'ʸ' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ⁱ\x00" "\x05" /* 'ⁱ' 5 */ + "n\x00" "\x08" /* 'n' 8 */ + "ⁿ\x00" "\x05" /* 'ⁿ' 5 */ + "j\x00" "\x07" /* 'j' 7 */ + "ʲ\x00" "\x04" /* 'ʲ' 4 */ + "x\x00" "\x07" /* 'x' 7 */ + "ˣ\x00" "\x04" /* 'ˣ' 4 */ + "w\x00" "\x07" /* 'w' 7 */ + "ʷ\x00" "\x04" /* 'ʷ' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ʳ\x00" "\x04" /* 'ʳ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ˢ\x00" "\x04" /* 'ˢ' 4 */ + "h\x00" "\x07" /* 'h' 7 */ + "ʰ\x00" "\x04" /* 'ʰ' 4 */ + "S\x00" "\x13" /* 'S' 19 */ + "M\x00" "\x08" /* 'M' 8 */ + "℠\x00" "\x05" /* '℠' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "℠\x00" "\x05" /* '℠' 5 */ + "underscore\x00" "\x62" /* 'underscore' 98 */ + "a\x00" "\x07" /* 'a' 7 */ + "ª\x00" "\x04" /* 'ª' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "º\x00" "\x04" /* 'º' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ˡ\x00" "\x04" /* 'ˡ' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ʸ\x00" "\x04" /* 'ʸ' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ⁱ\x00" "\x05" /* 'ⁱ' 5 */ + "n\x00" "\x08" /* 'n' 8 */ + "ⁿ\x00" "\x05" /* 'ⁿ' 5 */ + "j\x00" "\x07" /* 'j' 7 */ + "ʲ\x00" "\x04" /* 'ʲ' 4 */ + "x\x00" "\x07" /* 'x' 7 */ + "ˣ\x00" "\x04" /* 'ˣ' 4 */ + "w\x00" "\x07" /* 'w' 7 */ + "ʷ\x00" "\x04" /* 'ʷ' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ʳ\x00" "\x04" /* 'ʳ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ˢ\x00" "\x04" /* 'ˢ' 4 */ + "h\x00" "\x07" /* 'h' 7 */ + "ʰ\x00" "\x04" /* 'ʰ' 4 */ + "s\x00" "\x13" /* 's' 19 */ + "M\x00" "\x08" /* 'M' 8 */ + "℠\x00" "\x05" /* '℠' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "℠\x00" "\x05" /* '℠' 5 */ + "T\x00" "\x13" /* 'T' 19 */ + "M\x00" "\x08" /* 'M' 8 */ + "™\x00" "\x05" /* '™' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "™\x00" "\x05" /* '™' 5 */ + "oacute\x00" "\x0d" /* 'oacute' 13 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О̂\x00" "\x06" /* 'О̂' 6 */ + "i\x00" "\x07" /* 'i' 7 */ + "î\x00" "\x04" /* 'î' 4 */ + "KP_9\x00" "\x0b" /* 'KP_9' 11 */ + "⁹\x00" "\x05" /* '⁹' 5 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "⁼\x00" "\x05" /* '⁼' 5 */ + "KP_Space\x00" "\x0e" /* 'KP_Space' 14 */ + "²\x00" "\x04" /* '²' 4 */ + "dead_tilde\x00" "\x3c" /* 'dead_tilde' 60 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẫ\x00" "\x05" /* 'ẫ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ễ\x00" "\x05" /* 'ễ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỗ\x00" "\x05" /* 'ỗ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ễ\x00" "\x05" /* 'Ễ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỗ\x00" "\x05" /* 'Ỗ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẫ\x00" "\x05" /* 'Ẫ' 5 */ + "7\x00" "\x08" /* '7' 8 */ + "⁷\x00" "\x05" /* '⁷' 5 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а̂\x00" "\x06" /* 'а̂' 6 */ + "j\x00" "\x07" /* 'j' 7 */ + "ĵ\x00" "\x04" /* 'ĵ' 4 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⁾\x00" "\x05" /* '⁾' 5 */ + "Eacute\x00" "\x0d" /* 'Eacute' 13 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р̂\x00" "\x06" /* 'Р̂' 6 */ + "KP_7\x00" "\x0b" /* 'KP_7' 11 */ + "⁷\x00" "\x05" /* '⁷' 5 */ + "Cyrillic_U\x00" "\x12" /* 'Cyrillic_U' 18 */ + "У̂\x00" "\x06" /* 'У̂' 6 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̂\x00" "\x04" /* '̂' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "û\x00" "\x04" /* 'û' 4 */ + "z\x00" "\x08" /* 'z' 8 */ + "ẑ\x00" "\x05" /* 'ẑ' 5 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ĝ\x00" "\x04" /* 'Ĝ' 4 */ + "otilde\x00" "\x0d" /* 'otilde' 13 */ + "ỗ\x00" "\x05" /* 'ỗ' 5 */ + "H\x00" "\x07" /* 'H' 7 */ + "Ĥ\x00" "\x04" /* 'Ĥ' 4 */ + "8\x00" "\x08" /* '8' 8 */ + "⁸\x00" "\x05" /* '⁸' 5 */ + "KP_1\x00" "\x0a" /* 'KP_1' 10 */ + "¹\x00" "\x04" /* '¹' 4 */ + "atilde\x00" "\x0d" /* 'atilde' 13 */ + "ẫ\x00" "\x05" /* 'ẫ' 5 */ + "3\x00" "\x07" /* '3' 7 */ + "³\x00" "\x04" /* '³' 4 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е̂\x00" "\x06" /* 'е̂' 6 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ê\x00" "\x04" /* 'Ê' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Ŝ\x00" "\x04" /* 'Ŝ' 4 */ + "2\x00" "\x07" /* '2' 7 */ + "²\x00" "\x04" /* '²' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ŷ\x00" "\x04" /* 'Ŷ' 4 */ + "Cyrillic_i\x00" "\x12" /* 'Cyrillic_i' 18 */ + "и̂\x00" "\x06" /* 'и̂' 6 */ + "Otilde\x00" "\x0d" /* 'Otilde' 13 */ + "Ỗ\x00" "\x05" /* 'Ỗ' 5 */ + "Atilde\x00" "\x0d" /* 'Atilde' 13 */ + "Ẫ\x00" "\x05" /* 'Ẫ' 5 */ + "egrave\x00" "\x0d" /* 'egrave' 13 */ + "ề\x00" "\x05" /* 'ề' 5 */ + "ograve\x00" "\x0d" /* 'ograve' 13 */ + "ồ\x00" "\x05" /* 'ồ' 5 */ + "plus\x00" "\x0b" /* 'plus' 11 */ + "⁺\x00" "\x05" /* '⁺' 5 */ + "6\x00" "\x08" /* '6' 8 */ + "⁶\x00" "\x05" /* '⁶' 5 */ + "Ahook\x00" "\x0c" /* 'Ahook' 12 */ + "Ẩ\x00" "\x05" /* 'Ẩ' 5 */ + "w\x00" "\x07" /* 'w' 7 */ + "ŵ\x00" "\x04" /* 'ŵ' 4 */ + "Ohook\x00" "\x0c" /* 'Ohook' 12 */ + "Ổ\x00" "\x05" /* 'Ổ' 5 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о̂\x00" "\x06" /* 'о̂' 6 */ + "4\x00" "\x08" /* '4' 8 */ + "⁴\x00" "\x05" /* '⁴' 5 */ + "KP_3\x00" "\x0a" /* 'KP_3' 10 */ + "³\x00" "\x04" /* '³' 4 */ + "eacute\x00" "\x0d" /* 'eacute' 13 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "J\x00" "\x07" /* 'J' 7 */ + "Ĵ\x00" "\x04" /* 'Ĵ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ô\x00" "\x04" /* 'Ô' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ŝ\x00" "\x04" /* 'ŝ' 4 */ + "Z\x00" "\x08" /* 'Z' 8 */ + "Ẑ\x00" "\x05" /* 'Ẑ' 5 */ + "KP_0\x00" "\x0b" /* 'KP_0' 11 */ + "⁰\x00" "\x05" /* '⁰' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Â\x00" "\x04" /* 'Â' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "ĉ\x00" "\x04" /* 'ĉ' 4 */ + "KP_Add\x00" "\x0d" /* 'KP_Add' 13 */ + "⁺\x00" "\x05" /* '⁺' 5 */ + "KP_2\x00" "\x0a" /* 'KP_2' 10 */ + "²\x00" "\x04" /* '²' 4 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А̂\x00" "\x06" /* 'А̂' 6 */ + "dead_hook\x00" "\x3b" /* 'dead_hook' 59 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẩ\x00" "\x05" /* 'ẩ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ể\x00" "\x05" /* 'ể' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ổ\x00" "\x05" /* 'ổ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ể\x00" "\x05" /* 'Ể' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ổ\x00" "\x05" /* 'Ổ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẩ\x00" "\x05" /* 'Ẩ' 5 */ + "5\x00" "\x08" /* '5' 8 */ + "⁵\x00" "\x05" /* '⁵' 5 */ + "KP_5\x00" "\x0b" /* 'KP_5' 11 */ + "⁵\x00" "\x05" /* '⁵' 5 */ + "9\x00" "\x08" /* '9' 8 */ + "⁹\x00" "\x05" /* '⁹' 5 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е̂\x00" "\x06" /* 'Е̂' 6 */ + "Egrave\x00" "\x0d" /* 'Egrave' 13 */ + "Ề\x00" "\x05" /* 'Ề' 5 */ + "0\x00" "\x08" /* '0' 8 */ + "⁰\x00" "\x05" /* '⁰' 5 */ + "Aacute\x00" "\x0d" /* 'Aacute' 13 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "etilde\x00" "\x0d" /* 'etilde' 13 */ + "ễ\x00" "\x05" /* 'ễ' 5 */ + "aacute\x00" "\x0d" /* 'aacute' 13 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "dead_acute\x00" "\x3c" /* 'dead_acute' 60 */ + "a\x00" "\x08" /* 'a' 8 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "Agrave\x00" "\x0d" /* 'Agrave' 13 */ + "Ầ\x00" "\x05" /* 'Ầ' 5 */ + "parenleft\x00" "\x10" /* 'parenleft' 16 */ + "⁽\x00" "\x05" /* '⁽' 5 */ + "h\x00" "\x07" /* 'h' 7 */ + "ĥ\x00" "\x04" /* 'ĥ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Î\x00" "\x04" /* 'Î' 4 */ + "ehook\x00" "\x0c" /* 'ehook' 12 */ + "ể\x00" "\x05" /* 'ể' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Û\x00" "\x04" /* 'Û' 4 */ + "Cyrillic_u\x00" "\x12" /* 'Cyrillic_u' 18 */ + "у̂\x00" "\x06" /* 'у̂' 6 */ + "KP_Equal\x00" "\x0f" /* 'KP_Equal' 15 */ + "⁼\x00" "\x05" /* '⁼' 5 */ + "dead_currency\x00" "\x81\xdd" /* 'dead_currency' 477 */ + "W\x00" "\x08" /* 'W' 8 */ + "₩\x00" "\x05" /* '₩' 5 */ + "g\x00" "\x08" /* 'g' 8 */ + "₲\x00" "\x05" /* '₲' 5 */ + "a\x00" "\x07" /* 'a' 7 */ + "؋\x00" "\x04" /* '؋' 4 */ + "dead_currency\x00" "\x13" /* 'dead_currency' 19 */ + "¤\x00" "\x04" /* '¤' 4 */ + "C\x00" "\x08" /* 'C' 8 */ + "₡\x00" "\x05" /* '₡' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "€\x00" "\x05" /* '€' 5 */ + "F\x00" "\x08" /* 'F' 8 */ + "₣\x00" "\x05" /* '₣' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "௹\x00" "\x05" /* '௹' 5 */ + "l\x00" "\x07" /* 'l' 7 */ + "£\x00" "\x04" /* '£' 4 */ + "t\x00" "\x08" /* 't' 8 */ + "৳\x00" "\x05" /* '৳' 5 */ + "thorn\x00" "\x0c" /* 'thorn' 12 */ + "৲\x00" "\x05" /* '৲' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "¤\x00" "\x04" /* '¤' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "¥\x00" "\x04" /* '¥' 4 */ + "b\x00" "\x08" /* 'b' 8 */ + "฿\x00" "\x05" /* '฿' 5 */ + "i\x00" "\x08" /* 'i' 8 */ + "﷼\x00" "\x05" /* '﷼' 5 */ + "k\x00" "\x08" /* 'k' 8 */ + "₭\x00" "\x05" /* '₭' 5 */ + "n\x00" "\x08" /* 'n' 8 */ + "₦\x00" "\x05" /* '₦' 5 */ + "ccedilla\x00" "\x0f" /* 'ccedilla' 15 */ + "₵\x00" "\x05" /* '₵' 5 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "¤\x00" "\x04" /* '¤' 4 */ + "u\x00" "\x08" /* 'u' 8 */ + "元\x00" "\x05" /* '元' 5 */ + "G\x00" "\x08" /* 'G' 8 */ + "₲\x00" "\x05" /* '₲' 5 */ + "H\x00" "\x08" /* 'H' 8 */ + "₴\x00" "\x05" /* '₴' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "₠\x00" "\x05" /* '₠' 5 */ + "S\x00" "\x06" /* 'S' 6 */ + "$\x00" "\x03" /* '$' 3 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "円\x00" "\x05" /* '円' 5 */ + "f\x00" "\x07" /* 'f' 7 */ + "ƒ\x00" "\x04" /* 'ƒ' 4 */ + "d\x00" "\x08" /* 'd' 8 */ + "₫\x00" "\x05" /* '₫' 5 */ + "D\x00" "\x08" /* 'D' 8 */ + "₯\x00" "\x05" /* '₯' 5 */ + "w\x00" "\x08" /* 'w' 8 */ + "₩\x00" "\x05" /* '₩' 5 */ + "p\x00" "\x08" /* 'p' 8 */ + "₰\x00" "\x05" /* '₰' 5 */ + "P\x00" "\x08" /* 'P' 8 */ + "₧\x00" "\x05" /* '₧' 5 */ + "M\x00" "\x08" /* 'M' 8 */ + "ℳ\x00" "\x05" /* 'ℳ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "૱\x00" "\x05" /* '૱' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "₥\x00" "\x05" /* '₥' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "₢\x00" "\x05" /* '₢' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "₪\x00" "\x05" /* '₪' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "₳\x00" "\x05" /* '₳' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "₨\x00" "\x05" /* '₨' 5 */ + "THORN\x00" "\x0c" /* 'THORN' 12 */ + "৲\x00" "\x05" /* '৲' 5 */ + "c\x00" "\x07" /* 'c' 7 */ + "¢\x00" "\x04" /* '¢' 4 */ + "L\x00" "\x08" /* 'L' 8 */ + "₤\x00" "\x05" /* '₤' 5 */ + "T\x00" "\x08" /* 'T' 8 */ + "₮\x00" "\x05" /* '₮' 5 */ + "Ccedilla\x00" "\x0f" /* 'Ccedilla' 15 */ + "₵\x00" "\x05" /* '₵' 5 */ + "K\x00" "\x08" /* 'K' 8 */ + "₭\x00" "\x05" /* '₭' 5 */ + "B\x00" "\x08" /* 'B' 8 */ + "₱\x00" "\x05" /* '₱' 5 */ + "dead_cedilla\x00" "\x1e" /* 'dead_cedilla' 30 */ + "C\x00" "\x08" /* 'C' 8 */ + "₵\x00" "\x05" /* '₵' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "₵\x00" "\x05" /* '₵' 5 */ + "h\x00" "\x08" /* 'h' 8 */ + "₴\x00" "\x05" /* '₴' 5 */ + "I\x00" "\x08" /* 'I' 8 */ + "៛\x00" "\x05" /* '៛' 5 */ + "N\x00" "\x08" /* 'N' 8 */ + "₦\x00" "\x05" /* '₦' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "圓\x00" "\x05" /* '圓' 5 */ + "dead_belowdiaeresis\x00" "\x41" /* 'dead_belowdiaeresis' 65 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṳ\x00" "\x05" /* 'ṳ' 5 */ + "dead_diaeresis\x00" "\x1c" /* 'dead_diaeresis' 28 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "⩷\x00" "\x05" /* '⩷' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṳ\x00" "\x05" /* 'Ṳ' 5 */ + "dead_belowdot\x00" "\x83\x6e" /* 'dead_belowdot' 878 */ + "minus\x00" "\x0c" /* 'minus' 12 */ + "⨪\x00" "\x05" /* '⨪' 5 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẉ\x00" "\x05" /* 'Ẉ' 5 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ặ\x00" "\x05" /* 'ặ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ặ\x00" "\x05" /* 'Ặ' 5 */ + "a\x00" "\x08" /* 'a' 8 */ + "ạ\x00" "\x05" /* 'ạ' 5 */ + "dead_circumflex\x00" "\x41" /* 'dead_circumflex' 65 */ + "a\x00" "\x08" /* 'a' 8 */ + "ậ\x00" "\x05" /* 'ậ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ệ\x00" "\x05" /* 'ệ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ộ\x00" "\x05" /* 'ộ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ệ\x00" "\x05" /* 'Ệ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ộ\x00" "\x05" /* 'Ộ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ậ\x00" "\x05" /* 'Ậ' 5 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ợ\x00" "\x05" /* 'ợ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ự\x00" "\x05" /* 'ự' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ợ\x00" "\x05" /* 'Ợ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ự\x00" "\x05" /* 'Ự' 5 */ + "Acircumflex\x00" "\x12" /* 'Acircumflex' 18 */ + "Ậ\x00" "\x05" /* 'Ậ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ẹ\x00" "\x05" /* 'ẹ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ọ\x00" "\x05" /* 'ọ' 5 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḷ\x00" "\x05" /* 'ḷ' 5 */ + "t\x00" "\x08" /* 't' 8 */ + "ṭ\x00" "\x05" /* 'ṭ' 5 */ + "dead_belowdot\x00" "\x13" /* 'dead_belowdot' 19 */ + "̣\x00" "\x04" /* '̣' 4 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ự\x00" "\x05" /* 'ự' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "̣\x00" "\x04" /* '̣' 4 */ + "dead_macron\x00" "\x2d" /* 'dead_macron' 45 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḹ\x00" "\x05" /* 'ḹ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṝ\x00" "\x05" /* 'ṝ' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṝ\x00" "\x05" /* 'Ṝ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḹ\x00" "\x05" /* 'Ḹ' 5 */ + "acircumflex\x00" "\x12" /* 'acircumflex' 18 */ + "ậ\x00" "\x05" /* 'ậ' 5 */ + "Ecircumflex\x00" "\x12" /* 'Ecircumflex' 18 */ + "Ệ\x00" "\x05" /* 'Ệ' 5 */ + "y\x00" "\x08" /* 'y' 8 */ + "ỵ\x00" "\x05" /* 'ỵ' 5 */ + "b\x00" "\x08" /* 'b' 8 */ + "ḅ\x00" "\x05" /* 'ḅ' 5 */ + "Multi_key\x00" "\x31" /* 'Multi_key' 49 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ợ\x00" "\x05" /* 'ợ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ự\x00" "\x05" /* 'ự' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ợ\x00" "\x05" /* 'Ợ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ự\x00" "\x05" /* 'Ự' 5 */ + "i\x00" "\x08" /* 'i' 8 */ + "ị\x00" "\x05" /* 'ị' 5 */ + "k\x00" "\x08" /* 'k' 8 */ + "ḳ\x00" "\x05" /* 'ḳ' 5 */ + "n\x00" "\x08" /* 'n' 8 */ + "ṇ\x00" "\x05" /* 'ṇ' 5 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "⩦\x00" "\x05" /* '⩦' 5 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ợ\x00" "\x05" /* 'Ợ' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ợ\x00" "\x05" /* 'ợ' 5 */ + "sabovedot\x00" "\x10" /* 'sabovedot' 16 */ + "ṩ\x00" "\x05" /* 'ṩ' 5 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̣\x00" "\x04" /* '̣' 4 */ + "V\x00" "\x08" /* 'V' 8 */ + "Ṿ\x00" "\x05" /* 'Ṿ' 5 */ + "Ocircumflex\x00" "\x12" /* 'Ocircumflex' 18 */ + "Ộ\x00" "\x05" /* 'Ộ' 5 */ + "ocircumflex\x00" "\x12" /* 'ocircumflex' 18 */ + "ộ\x00" "\x05" /* 'ộ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ụ\x00" "\x05" /* 'ụ' 5 */ + "z\x00" "\x08" /* 'z' 8 */ + "ẓ\x00" "\x05" /* 'ẓ' 5 */ + "H\x00" "\x08" /* 'H' 8 */ + "Ḥ\x00" "\x05" /* 'Ḥ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ẹ\x00" "\x05" /* 'Ẹ' 5 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṣ\x00" "\x05" /* 'Ṣ' 5 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "Ỵ\x00" "\x05" /* 'Ỵ' 5 */ + "d\x00" "\x08" /* 'd' 8 */ + "ḍ\x00" "\x05" /* 'ḍ' 5 */ + "D\x00" "\x08" /* 'D' 8 */ + "Ḍ\x00" "\x05" /* 'Ḍ' 5 */ + "Abreve\x00" "\x0d" /* 'Abreve' 13 */ + "Ặ\x00" "\x05" /* 'Ặ' 5 */ + "plus\x00" "\x0b" /* 'plus' 11 */ + "⨥\x00" "\x05" /* '⨥' 5 */ + "ecircumflex\x00" "\x12" /* 'ecircumflex' 18 */ + "ệ\x00" "\x05" /* 'ệ' 5 */ + "dead_abovedot\x00" "\x1f" /* 'dead_abovedot' 31 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṩ\x00" "\x05" /* 'Ṩ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṩ\x00" "\x05" /* 'ṩ' 5 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẉ\x00" "\x05" /* 'ẉ' 5 */ + "v\x00" "\x08" /* 'v' 8 */ + "ṿ\x00" "\x05" /* 'ṿ' 5 */ + "M\x00" "\x08" /* 'M' 8 */ + "Ṃ\x00" "\x05" /* 'Ṃ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ọ\x00" "\x05" /* 'Ọ' 5 */ + "abreve\x00" "\x0d" /* 'abreve' 13 */ + "ặ\x00" "\x05" /* 'ặ' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "ṃ\x00" "\x05" /* 'ṃ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṛ\x00" "\x05" /* 'ṛ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṣ\x00" "\x05" /* 'ṣ' 5 */ + "Z\x00" "\x08" /* 'Z' 8 */ + "Ẓ\x00" "\x05" /* 'Ẓ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ạ\x00" "\x05" /* 'Ạ' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṛ\x00" "\x05" /* 'Ṛ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḷ\x00" "\x05" /* 'Ḷ' 5 */ + "T\x00" "\x08" /* 'T' 8 */ + "Ṭ\x00" "\x05" /* 'Ṭ' 5 */ + "K\x00" "\x08" /* 'K' 8 */ + "Ḳ\x00" "\x05" /* 'Ḳ' 5 */ + "B\x00" "\x08" /* 'B' 8 */ + "Ḅ\x00" "\x05" /* 'Ḅ' 5 */ + "Sabovedot\x00" "\x10" /* 'Sabovedot' 16 */ + "Ṩ\x00" "\x05" /* 'Ṩ' 5 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ự\x00" "\x05" /* 'Ự' 5 */ + "h\x00" "\x08" /* 'h' 8 */ + "ḥ\x00" "\x05" /* 'ḥ' 5 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ị\x00" "\x05" /* 'Ị' 5 */ + "N\x00" "\x08" /* 'N' 8 */ + "Ṇ\x00" "\x05" /* 'Ṇ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ụ\x00" "\x05" /* 'Ụ' 5 */ + "dead_macron\x00" "\x84\xfc" /* 'dead_macron' 1276 */ + "adiaeresis\x00" "\x10" /* 'adiaeresis' 16 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "g\x00" "\x08" /* 'g' 8 */ + "ḡ\x00" "\x05" /* 'ḡ' 5 */ + "a\x00" "\x07" /* 'a' 7 */ + "ā\x00" "\x04" /* 'ā' 4 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ῑ\x00" "\x05" /* 'Ῑ' 5 */ + "Ograve\x00" "\x0d" /* 'Ograve' 13 */ + "Ṑ\x00" "\x05" /* 'Ṑ' 5 */ + "dead_grave\x00" "\x2c" /* 'dead_grave' 44 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḕ\x00" "\x05" /* 'ḕ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṑ\x00" "\x05" /* 'ṑ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḕ\x00" "\x05" /* 'Ḕ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṑ\x00" "\x05" /* 'Ṑ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῑ\x00" "\x05" /* 'ῑ' 5 */ + "Oacute\x00" "\x0d" /* 'Oacute' 13 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р̄\x00" "\x06" /* 'р̄' 6 */ + "e\x00" "\x07" /* 'e' 7 */ + "ē\x00" "\x04" /* 'ē' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ō\x00" "\x04" /* 'ō' 4 */ + "Udiaeresis\x00" "\x10" /* 'Udiaeresis' 16 */ + "Ǖ\x00" "\x04" /* 'Ǖ' 4 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῡ\x00" "\x05" /* 'ῡ' 5 */ + "dead_belowdot\x00" "\x2f" /* 'dead_belowdot' 47 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḹ\x00" "\x05" /* 'ḹ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṝ\x00" "\x05" /* 'ṝ' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṝ\x00" "\x05" /* 'Ṝ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḹ\x00" "\x05" /* 'Ḹ' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "¯\x00" "\x04" /* '¯' 4 */ + "dead_macron\x00" "\x11" /* 'dead_macron' 17 */ + "¯\x00" "\x04" /* '¯' 4 */ + "Cyrillic_I\x00" "\x10" /* 'Cyrillic_I' 16 */ + "Ӣ\x00" "\x04" /* 'Ӣ' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ȳ\x00" "\x04" /* 'ȳ' 4 */ + "Multi_key\x00" "\x80\xbf" /* 'Multi_key' 191 */ + "period\x00" "\x24" /* 'period' 36 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǡ\x00" "\x04" /* 'ǡ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȱ\x00" "\x04" /* 'ȱ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȱ\x00" "\x04" /* 'Ȱ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǡ\x00" "\x04" /* 'Ǡ' 4 */ + "exclam\x00" "\x28" /* 'exclam' 40 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḹ\x00" "\x05" /* 'ḹ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṝ\x00" "\x05" /* 'ṝ' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṝ\x00" "\x05" /* 'Ṝ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḹ\x00" "\x05" /* 'Ḹ' 5 */ + "quotedbl\x00" "\x34" /* 'quotedbl' 52 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǖ\x00" "\x04" /* 'ǖ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǖ\x00" "\x04" /* 'Ǖ' 4 */ + "asciitilde\x00" "\x1a" /* 'asciitilde' 26 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "semicolon\x00" "\x19" /* 'semicolon' 25 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǭ\x00" "\x04" /* 'ǭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǭ\x00" "\x04" /* 'Ǭ' 4 */ + "oacute\x00" "\x0d" /* 'oacute' 13 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О̄\x00" "\x06" /* 'О̄' 6 */ + "i\x00" "\x07" /* 'i' 7 */ + "ī\x00" "\x04" /* 'ī' 4 */ + "dead_tilde\x00" "\x1a" /* 'dead_tilde' 26 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а̄\x00" "\x06" /* 'а̄' 6 */ + "Eacute\x00" "\x0d" /* 'Eacute' 13 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р̄\x00" "\x06" /* 'Р̄' 6 */ + "Cyrillic_U\x00" "\x10" /* 'Cyrillic_U' 16 */ + "Ӯ\x00" "\x04" /* 'Ӯ' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̄\x00" "\x04" /* '̄' 4 */ + "V\x00" "\x07" /* 'V' 7 */ + "Ǖ\x00" "\x04" /* 'Ǖ' 4 */ + "AE\x00" "\x08" /* 'AE' 8 */ + "Ǣ\x00" "\x04" /* 'Ǣ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ū\x00" "\x04" /* 'ū' 4 */ + "G\x00" "\x08" /* 'G' 8 */ + "Ḡ\x00" "\x05" /* 'Ḡ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ᾱ\x00" "\x05" /* 'Ᾱ' 5 */ + "otilde\x00" "\x0c" /* 'otilde' 12 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е̄\x00" "\x06" /* 'е̄' 6 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ē\x00" "\x04" /* 'Ē' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ȳ\x00" "\x04" /* 'Ȳ' 4 */ + "Cyrillic_i\x00" "\x10" /* 'Cyrillic_i' 16 */ + "ӣ\x00" "\x04" /* 'ӣ' 4 */ + "dead_ogonek\x00" "\x1b" /* 'dead_ogonek' 27 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǭ\x00" "\x04" /* 'ǭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǭ\x00" "\x04" /* 'Ǭ' 4 */ + "odiaeresis\x00" "\x10" /* 'odiaeresis' 16 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "Otilde\x00" "\x0c" /* 'Otilde' 12 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "egrave\x00" "\x0d" /* 'egrave' 13 */ + "ḕ\x00" "\x05" /* 'ḕ' 5 */ + "dead_greek\x00" "\x3c" /* 'dead_greek' 60 */ + "a\x00" "\x08" /* 'a' 8 */ + "ᾱ\x00" "\x05" /* 'ᾱ' 5 */ + "i\x00" "\x08" /* 'i' 8 */ + "ῑ\x00" "\x05" /* 'ῑ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ῡ\x00" "\x05" /* 'ῡ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ᾱ\x00" "\x05" /* 'Ᾱ' 5 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ῑ\x00" "\x05" /* 'Ῑ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ῡ\x00" "\x05" /* 'Ῡ' 5 */ + "ograve\x00" "\x0d" /* 'ograve' 13 */ + "ṑ\x00" "\x05" /* 'ṑ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾱ\x00" "\x05" /* 'ᾱ' 5 */ + "dead_abovedot\x00" "\x2b" /* 'dead_abovedot' 43 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǡ\x00" "\x04" /* 'ǡ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȱ\x00" "\x04" /* 'ȱ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȱ\x00" "\x04" /* 'Ȱ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǡ\x00" "\x04" /* 'Ǡ' 4 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о̄\x00" "\x06" /* 'о̄' 6 */ + "eacute\x00" "\x0d" /* 'eacute' 13 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "v\x00" "\x07" /* 'v' 7 */ + "ǖ\x00" "\x04" /* 'ǖ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ō\x00" "\x04" /* 'Ō' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ā\x00" "\x04" /* 'Ā' 4 */ + "Odiaeresis\x00" "\x10" /* 'Odiaeresis' 16 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А̄\x00" "\x06" /* 'А̄' 6 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е̄\x00" "\x06" /* 'Е̄' 6 */ + "Egrave\x00" "\x0d" /* 'Egrave' 13 */ + "Ḕ\x00" "\x05" /* 'Ḕ' 5 */ + "dead_diaeresis\x00" "\x3a" /* 'dead_diaeresis' 58 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǖ\x00" "\x04" /* 'ǖ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǖ\x00" "\x04" /* 'Ǖ' 4 */ + "Adiaeresis\x00" "\x10" /* 'Adiaeresis' 16 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "dead_acute\x00" "\x2c" /* 'dead_acute' 44 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "udiaeresis\x00" "\x10" /* 'udiaeresis' 16 */ + "ǖ\x00" "\x04" /* 'ǖ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ī\x00" "\x04" /* 'Ī' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ū\x00" "\x04" /* 'Ū' 4 */ + "Cyrillic_u\x00" "\x10" /* 'Cyrillic_u' 16 */ + "ӯ\x00" "\x04" /* 'ӯ' 4 */ + "ae\x00" "\x08" /* 'ae' 8 */ + "ǣ\x00" "\x04" /* 'ǣ' 4 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ῡ\x00" "\x05" /* 'Ῡ' 5 */ + "dead_doublegrave\x00" "\x80\xef" /* 'dead_doublegrave' 239 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р̏\x00" "\x06" /* 'р̏' 6 */ + "Cyrillic_I\x00" "\x12" /* 'Cyrillic_I' 18 */ + "И̏\x00" "\x06" /* 'И̏' 6 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О̏\x00" "\x06" /* 'О̏' 6 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а̏\x00" "\x06" /* 'а̏' 6 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р̏\x00" "\x06" /* 'Р̏' 6 */ + "Cyrillic_U\x00" "\x12" /* 'Cyrillic_U' 18 */ + "У̏\x00" "\x06" /* 'У̏' 6 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е̏\x00" "\x06" /* 'е̏' 6 */ + "Cyrillic_i\x00" "\x12" /* 'Cyrillic_i' 18 */ + "и̏\x00" "\x06" /* 'и̏' 6 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о̏\x00" "\x06" /* 'о̏' 6 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А̏\x00" "\x06" /* 'А̏' 6 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е̏\x00" "\x06" /* 'Е̏' 6 */ + "Cyrillic_u\x00" "\x12" /* 'Cyrillic_u' 18 */ + "у̏\x00" "\x06" /* 'у̏' 6 */ + "Multi_key\x00" "\xc0\x92\xd5" /* 'Multi_key' 37589 */ + "backslash\x00" "\x27" /* 'backslash' 39 */ + "minus\x00" "\x0c" /* 'minus' 12 */ + "⍀\x00" "\x05" /* '⍀' 5 */ + "o\x00" "\x10" /* 'o' 16 */ + "slash\x00" "\x0d" /* 'slash' 13 */ + "🙌\x00" "\x06" /* '🙌' 6 */ + "minus\x00" "\x81\x25" /* 'minus' 293 */ + "backslash\x00" "\x10" /* 'backslash' 16 */ + "⍀\x00" "\x05" /* '⍀' 5 */ + "minus\x00" "\x2b" /* 'minus' 43 */ + "minus\x00" "\x0c" /* 'minus' 12 */ + "—\x00" "\x05" /* '—' 5 */ + "period\x00" "\x0d" /* 'period' 13 */ + "–\x00" "\x05" /* '–' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "­\x00" "\x04" /* '­' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "ā\x00" "\x04" /* 'ā' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ē\x00" "\x04" /* 'ē' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ō\x00" "\x04" /* 'ō' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "£\x00" "\x04" /* '£' 4 */ + "space\x00" "\x0a" /* 'space' 10 */ + "~\x00" "\x03" /* '~' 3 */ + "y\x00" "\x07" /* 'y' 7 */ + "¥\x00" "\x04" /* '¥' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ī\x00" "\x04" /* 'ī' 4 */ + "parenright\x00" "\x0f" /* 'parenright' 15 */ + "}\x00" "\x03" /* '}' 3 */ + "u\x00" "\x07" /* 'u' 7 */ + "ū\x00" "\x04" /* 'ū' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ē\x00" "\x04" /* 'Ē' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "¥\x00" "\x04" /* '¥' 4 */ + "d\x00" "\x07" /* 'd' 7 */ + "đ\x00" "\x04" /* 'đ' 4 */ + "D\x00" "\x07" /* 'D' 7 */ + "Đ\x00" "\x04" /* 'Đ' 4 */ + "plus\x00" "\x0a" /* 'plus' 10 */ + "±\x00" "\x04" /* '±' 4 */ + "colon\x00" "\x0b" /* 'colon' 11 */ + "÷\x00" "\x04" /* '÷' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ō\x00" "\x04" /* 'Ō' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ā\x00" "\x04" /* 'Ā' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "£\x00" "\x04" /* '£' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "¬\x00" "\x04" /* '¬' 4 */ + "slash\x00" "\x0c" /* 'slash' 12 */ + "⌿\x00" "\x05" /* '⌿' 5 */ + "greater\x00" "\x0e" /* 'greater' 14 */ + "→\x00" "\x05" /* '→' 5 */ + "parenleft\x00" "\x0e" /* 'parenleft' 14 */ + "{\x00" "\x03" /* '{' 3 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ī\x00" "\x04" /* 'Ī' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ū\x00" "\x04" /* 'Ū' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "¯\x00" "\x04" /* '¯' 4 */ + "period\x00" "\x82\x5f" /* 'period' 607 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "·\x00" "\x04" /* '·' 4 */ + "period\x00" "\x0d" /* 'period' 13 */ + "…\x00" "\x05" /* '…' 5 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẇ\x00" "\x05" /* 'Ẇ' 5 */ + "g\x00" "\x07" /* 'g' 7 */ + "ġ\x00" "\x04" /* 'ġ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "ȧ\x00" "\x04" /* 'ȧ' 4 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ċ\x00" "\x04" /* 'Ċ' 4 */ + "exclam\x00" "\x18" /* 'exclam' 24 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṩ\x00" "\x05" /* 'Ṩ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṩ\x00" "\x05" /* 'ṩ' 5 */ + "less\x00" "\x0b" /* 'less' 11 */ + "‹\x00" "\x05" /* '‹' 5 */ + "e\x00" "\x07" /* 'e' 7 */ + "ė\x00" "\x04" /* 'ė' 4 */ + "F\x00" "\x08" /* 'F' 8 */ + "Ḟ\x00" "\x05" /* 'Ḟ' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȯ\x00" "\x04" /* 'ȯ' 4 */ + "t\x00" "\x08" /* 't' 8 */ + "ṫ\x00" "\x05" /* 'ṫ' 5 */ + "dead_belowdot\x00" "\x1f" /* 'dead_belowdot' 31 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṩ\x00" "\x05" /* 'Ṩ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṩ\x00" "\x05" /* 'ṩ' 5 */ + "y\x00" "\x08" /* 'y' 8 */ + "ẏ\x00" "\x05" /* 'ẏ' 5 */ + "b\x00" "\x08" /* 'b' 8 */ + "ḃ\x00" "\x05" /* 'ḃ' 5 */ + "i\x00" "\x07" /* 'i' 7 */ + "ı\x00" "\x04" /* 'ı' 4 */ + "n\x00" "\x08" /* 'n' 8 */ + "ṅ\x00" "\x05" /* 'ṅ' 5 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "•\x00" "\x05" /* '•' 5 */ + "dead_caron\x00" "\x1c" /* 'dead_caron' 28 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṧ\x00" "\x05" /* 'Ṧ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṧ\x00" "\x05" /* 'ṧ' 5 */ + "x\x00" "\x08" /* 'x' 8 */ + "ẋ\x00" "\x05" /* 'ẋ' 5 */ + "z\x00" "\x07" /* 'z' 7 */ + "ż\x00" "\x04" /* 'ż' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ġ\x00" "\x04" /* 'Ġ' 4 */ + "Sacute\x00" "\x0d" /* 'Sacute' 13 */ + "Ṥ\x00" "\x05" /* 'Ṥ' 5 */ + "H\x00" "\x08" /* 'H' 8 */ + "Ḣ\x00" "\x05" /* 'Ḣ' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ė\x00" "\x04" /* 'Ė' 4 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṡ\x00" "\x05" /* 'Ṡ' 5 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "Ẏ\x00" "\x05" /* 'Ẏ' 5 */ + "scaron\x00" "\x0d" /* 'scaron' 13 */ + "ṧ\x00" "\x05" /* 'ṧ' 5 */ + "f\x00" "\x08" /* 'f' 8 */ + "ḟ\x00" "\x05" /* 'ḟ' 5 */ + "d\x00" "\x08" /* 'd' 8 */ + "ḋ\x00" "\x05" /* 'ḋ' 5 */ + "Scaron\x00" "\x0d" /* 'Scaron' 13 */ + "Ṧ\x00" "\x05" /* 'Ṧ' 5 */ + "D\x00" "\x08" /* 'D' 8 */ + "Ḋ\x00" "\x05" /* 'Ḋ' 5 */ + "acute\x00" "\x17" /* 'acute' 23 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṥ\x00" "\x05" /* 'Ṥ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṥ\x00" "\x05" /* 'ṥ' 5 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẇ\x00" "\x05" /* 'ẇ' 5 */ + "p\x00" "\x08" /* 'p' 8 */ + "ṗ\x00" "\x05" /* 'ṗ' 5 */ + "P\x00" "\x08" /* 'P' 8 */ + "Ṗ\x00" "\x05" /* 'Ṗ' 5 */ + "apostrophe\x00" "\x1c" /* 'apostrophe' 28 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṥ\x00" "\x05" /* 'Ṥ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṥ\x00" "\x05" /* 'ṥ' 5 */ + "M\x00" "\x08" /* 'M' 8 */ + "Ṁ\x00" "\x05" /* 'Ṁ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȯ\x00" "\x04" /* 'Ȯ' 4 */ + "m\x00" "\x08" /* 'm' 8 */ + "ṁ\x00" "\x05" /* 'ṁ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṙ\x00" "\x05" /* 'ṙ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṡ\x00" "\x05" /* 'ṡ' 5 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ż\x00" "\x04" /* 'Ż' 4 */ + "sacute\x00" "\x0d" /* 'sacute' 13 */ + "ṥ\x00" "\x05" /* 'ṥ' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ȧ\x00" "\x04" /* 'Ȧ' 4 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṙ\x00" "\x05" /* 'Ṙ' 5 */ + "c\x00" "\x07" /* 'c' 7 */ + "ċ\x00" "\x04" /* 'ċ' 4 */ + "T\x00" "\x08" /* 'T' 8 */ + "Ṫ\x00" "\x05" /* 'Ṫ' 5 */ + "greater\x00" "\x0e" /* 'greater' 14 */ + "›\x00" "\x05" /* '›' 5 */ + "B\x00" "\x08" /* 'B' 8 */ + "Ḃ\x00" "\x05" /* 'Ḃ' 5 */ + "dead_acute\x00" "\x1c" /* 'dead_acute' 28 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṥ\x00" "\x05" /* 'Ṥ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṥ\x00" "\x05" /* 'ṥ' 5 */ + "X\x00" "\x08" /* 'X' 8 */ + "Ẋ\x00" "\x05" /* 'Ẋ' 5 */ + "h\x00" "\x08" /* 'h' 8 */ + "ḣ\x00" "\x05" /* 'ḣ' 5 */ + "I\x00" "\x07" /* 'I' 7 */ + "İ\x00" "\x04" /* 'İ' 4 */ + "N\x00" "\x08" /* 'N' 8 */ + "Ṅ\x00" "\x05" /* 'Ṅ' 5 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "·\x00" "\x04" /* '·' 4 */ + "W\x00" "\x20" /* 'W' 32 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "₩\x00" "\x05" /* '₩' 5 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "Ŵ\x00" "\x04" /* 'Ŵ' 4 */ + "g\x00" "\x3b" /* 'g' 59 */ + "period\x00" "\x0c" /* 'period' 12 */ + "ġ\x00" "\x04" /* 'ġ' 4 */ + "breve\x00" "\x0b" /* 'breve' 11 */ + "ğ\x00" "\x04" /* 'ğ' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ģ\x00" "\x04" /* 'ģ' 4 */ + "parenleft\x00" "\x0f" /* 'parenleft' 15 */ + "ğ\x00" "\x04" /* 'ğ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "ğ\x00" "\x04" /* 'ğ' 4 */ + "a\x00" "\x80\xc6" /* 'a' 198 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "ā\x00" "\x04" /* 'ā' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "å\x00" "\x04" /* 'å' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "æ\x00" "\x04" /* 'æ' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "ä\x00" "\x04" /* 'ä' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "ä\x00" "\x04" /* 'ä' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "á\x00" "\x04" /* 'á' 4 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "ā\x00" "\x04" /* 'ā' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "á\x00" "\x04" /* 'á' 4 */ + "asterisk\x00" "\x0e" /* 'asterisk' 14 */ + "å\x00" "\x04" /* 'å' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ą\x00" "\x04" /* 'ą' 4 */ + "asciitilde\x00" "\x10" /* 'asciitilde' 16 */ + "ã\x00" "\x04" /* 'ã' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "â\x00" "\x04" /* 'â' 4 */ + "parenleft\x00" "\x0f" /* 'parenleft' 15 */ + "ă\x00" "\x04" /* 'ă' 4 */ + "grave\x00" "\x0b" /* 'grave' 11 */ + "à\x00" "\x04" /* 'à' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "â\x00" "\x04" /* 'â' 4 */ + "Greek_IOTA\x00" "\x2a" /* 'Greek_IOTA' 42 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "Ϊ\x00" "\x04" /* 'Ϊ' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ί\x00" "\x04" /* 'Ί' 4 */ + "Greek_iota\x00" "\x90\xfe" /* 'Greek_iota' 4350 */ + "dead_grave\x00" "\x82\x10" /* 'dead_grave' 528 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾊ\x00" "\x05" /* 'ᾊ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾒ\x00" "\x05" /* 'ᾒ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾂ\x00" "\x05" /* 'ᾂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾚ\x00" "\x05" /* 'ᾚ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾢ\x00" "\x05" /* 'ᾢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾪ\x00" "\x05" /* 'ᾪ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾋ\x00" "\x05" /* 'ᾋ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾓ\x00" "\x05" /* 'ᾓ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾃ\x00" "\x05" /* 'ᾃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾛ\x00" "\x05" /* 'ᾛ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾣ\x00" "\x05" /* 'ᾣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾫ\x00" "\x05" /* 'ᾫ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῂ\x00" "\x05" /* 'ῂ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾊ\x00" "\x05" /* 'ᾊ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾒ\x00" "\x05" /* 'ᾒ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾂ\x00" "\x05" /* 'ᾂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾚ\x00" "\x05" /* 'ᾚ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾢ\x00" "\x05" /* 'ᾢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾪ\x00" "\x05" /* 'ᾪ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾲ\x00" "\x05" /* 'ᾲ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῲ\x00" "\x05" /* 'ῲ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾋ\x00" "\x05" /* 'ᾋ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾓ\x00" "\x05" /* 'ᾓ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾃ\x00" "\x05" /* 'ᾃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾛ\x00" "\x05" /* 'ᾛ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾣ\x00" "\x05" /* 'ᾣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾫ\x00" "\x05" /* 'ᾫ' 5 */ + "dead_tilde\x00" "\x82\x10" /* 'dead_tilde' 528 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾎ\x00" "\x05" /* 'ᾎ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾖ\x00" "\x05" /* 'ᾖ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾆ\x00" "\x05" /* 'ᾆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾞ\x00" "\x05" /* 'ᾞ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾦ\x00" "\x05" /* 'ᾦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾮ\x00" "\x05" /* 'ᾮ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾏ\x00" "\x05" /* 'ᾏ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾗ\x00" "\x05" /* 'ᾗ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾇ\x00" "\x05" /* 'ᾇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾟ\x00" "\x05" /* 'ᾟ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾧ\x00" "\x05" /* 'ᾧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾯ\x00" "\x05" /* 'ᾯ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῇ\x00" "\x05" /* 'ῇ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾎ\x00" "\x05" /* 'ᾎ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾖ\x00" "\x05" /* 'ᾖ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾆ\x00" "\x05" /* 'ᾆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾞ\x00" "\x05" /* 'ᾞ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾦ\x00" "\x05" /* 'ᾦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾮ\x00" "\x05" /* 'ᾮ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾷ\x00" "\x05" /* 'ᾷ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῷ\x00" "\x05" /* 'ῷ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾏ\x00" "\x05" /* 'ᾏ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾗ\x00" "\x05" /* 'ᾗ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾇ\x00" "\x05" /* 'ᾇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾟ\x00" "\x05" /* 'ᾟ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾧ\x00" "\x05" /* 'ᾧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾯ\x00" "\x05" /* 'ᾯ' 5 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾈ\x00" "\x05" /* 'ᾈ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾐ\x00" "\x05" /* 'ᾐ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾀ\x00" "\x05" /* 'ᾀ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾘ\x00" "\x05" /* 'ᾘ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾠ\x00" "\x05" /* 'ᾠ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾨ\x00" "\x05" /* 'ᾨ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾼ\x00" "\x05" /* 'ᾼ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾉ\x00" "\x05" /* 'ᾉ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾑ\x00" "\x05" /* 'ᾑ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾁ\x00" "\x05" /* 'ᾁ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾙ\x00" "\x05" /* 'ᾙ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾡ\x00" "\x05" /* 'ᾡ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾩ\x00" "\x05" /* 'ᾩ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῃ\x00" "\x05" /* 'ῃ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾈ\x00" "\x05" /* 'ᾈ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾐ\x00" "\x05" /* 'ᾐ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾀ\x00" "\x05" /* 'ᾀ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾘ\x00" "\x05" /* 'ᾘ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾠ\x00" "\x05" /* 'ᾠ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾨ\x00" "\x05" /* 'ᾨ' 5 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "ϊ\x00" "\x04" /* 'ϊ' 4 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾳ\x00" "\x05" /* 'ᾳ' 5 */ + "acute\x00" "\x82\x0b" /* 'acute' 523 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῄ\x00" "\x05" /* 'ῄ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾴ\x00" "\x05" /* 'ᾴ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῴ\x00" "\x05" /* 'ῴ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ῌ\x00" "\x05" /* 'ῌ' 5 */ + "apostrophe\x00" "\x82\x10" /* 'apostrophe' 528 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῄ\x00" "\x05" /* 'ῄ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾴ\x00" "\x05" /* 'ᾴ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῴ\x00" "\x05" /* 'ῴ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "Greek_omegaaccent\x00" "\x18" /* 'Greek_omegaaccent' 24 */ + "ῴ\x00" "\x05" /* 'ῴ' 5 */ + "asciitilde\x00" "\x82\x10" /* 'asciitilde' 528 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾎ\x00" "\x05" /* 'ᾎ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾖ\x00" "\x05" /* 'ᾖ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾆ\x00" "\x05" /* 'ᾆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾞ\x00" "\x05" /* 'ᾞ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾦ\x00" "\x05" /* 'ᾦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾮ\x00" "\x05" /* 'ᾮ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾏ\x00" "\x05" /* 'ᾏ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾗ\x00" "\x05" /* 'ᾗ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾇ\x00" "\x05" /* 'ᾇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾟ\x00" "\x05" /* 'ᾟ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾧ\x00" "\x05" /* 'ᾧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾯ\x00" "\x05" /* 'ᾯ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῇ\x00" "\x05" /* 'ῇ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾎ\x00" "\x05" /* 'ᾎ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾖ\x00" "\x05" /* 'ᾖ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾆ\x00" "\x05" /* 'ᾆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾞ\x00" "\x05" /* 'ᾞ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾦ\x00" "\x05" /* 'ᾦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾮ\x00" "\x05" /* 'ᾮ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾷ\x00" "\x05" /* 'ᾷ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῷ\x00" "\x05" /* 'ῷ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾏ\x00" "\x05" /* 'ᾏ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾗ\x00" "\x05" /* 'ᾗ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾇ\x00" "\x05" /* 'ᾇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾟ\x00" "\x05" /* 'ᾟ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾧ\x00" "\x05" /* 'ᾧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾯ\x00" "\x05" /* 'ᾯ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῳ\x00" "\x05" /* 'ῳ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ῼ\x00" "\x05" /* 'ῼ' 5 */ + "dead_acute\x00" "\x82\x10" /* 'dead_acute' 528 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῄ\x00" "\x05" /* 'ῄ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾴ\x00" "\x05" /* 'ᾴ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῴ\x00" "\x05" /* 'ῴ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "Greek_alphaaccent\x00" "\x18" /* 'Greek_alphaaccent' 24 */ + "ᾴ\x00" "\x05" /* 'ᾴ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾉ\x00" "\x05" /* 'ᾉ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾑ\x00" "\x05" /* 'ᾑ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾁ\x00" "\x05" /* 'ᾁ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾙ\x00" "\x05" /* 'ᾙ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾡ\x00" "\x05" /* 'ᾡ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾩ\x00" "\x05" /* 'ᾩ' 5 */ + "grave\x00" "\x82\x0b" /* 'grave' 523 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾊ\x00" "\x05" /* 'ᾊ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾒ\x00" "\x05" /* 'ᾒ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾂ\x00" "\x05" /* 'ᾂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾚ\x00" "\x05" /* 'ᾚ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾢ\x00" "\x05" /* 'ᾢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾪ\x00" "\x05" /* 'ᾪ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾋ\x00" "\x05" /* 'ᾋ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾓ\x00" "\x05" /* 'ᾓ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾃ\x00" "\x05" /* 'ᾃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾛ\x00" "\x05" /* 'ᾛ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾣ\x00" "\x05" /* 'ᾣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾫ\x00" "\x05" /* 'ᾫ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῂ\x00" "\x05" /* 'ῂ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾊ\x00" "\x05" /* 'ᾊ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾒ\x00" "\x05" /* 'ᾒ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾂ\x00" "\x05" /* 'ᾂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾚ\x00" "\x05" /* 'ᾚ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾢ\x00" "\x05" /* 'ᾢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾪ\x00" "\x05" /* 'ᾪ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾲ\x00" "\x05" /* 'ᾲ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῲ\x00" "\x05" /* 'ῲ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾋ\x00" "\x05" /* 'ᾋ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾓ\x00" "\x05" /* 'ᾓ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾃ\x00" "\x05" /* 'ᾃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾛ\x00" "\x05" /* 'ᾛ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾣ\x00" "\x05" /* 'ᾣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾫ\x00" "\x05" /* 'ᾫ' 5 */ + "Greek_etaaccent\x00" "\x16" /* 'Greek_etaaccent' 22 */ + "ῄ\x00" "\x05" /* 'ῄ' 5 */ + "1\x00" "\x5d" /* '1' 93 */ + "1\x00" "\x0b" /* '1' 11 */ + "0\x00" "\x08" /* '0' 8 */ + "⅒\x00" "\x05" /* '⅒' 5 */ + "7\x00" "\x08" /* '7' 8 */ + "⅐\x00" "\x05" /* '⅐' 5 */ + "8\x00" "\x08" /* '8' 8 */ + "⅛\x00" "\x05" /* '⅛' 5 */ + "3\x00" "\x08" /* '3' 8 */ + "⅓\x00" "\x05" /* '⅓' 5 */ + "2\x00" "\x07" /* '2' 7 */ + "½\x00" "\x04" /* '½' 4 */ + "6\x00" "\x08" /* '6' 8 */ + "⅙\x00" "\x05" /* '⅙' 5 */ + "4\x00" "\x07" /* '4' 7 */ + "¼\x00" "\x04" /* '¼' 4 */ + "5\x00" "\x08" /* '5' 8 */ + "⅕\x00" "\x05" /* '⅕' 5 */ + "9\x00" "\x08" /* '9' 8 */ + "⅑\x00" "\x05" /* '⅑' 5 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "¹\x00" "\x04" /* '¹' 4 */ + "Greek_OMICRON\x00" "\x1f" /* 'Greek_OMICRON' 31 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ό\x00" "\x04" /* 'Ό' 4 */ + "C\x00" "\x80\x82" /* 'C' 130 */ + "period\x00" "\x0c" /* 'period' 12 */ + "Ċ\x00" "\x04" /* 'Ċ' 4 */ + "C\x00" "\x0e" /* 'C' 14 */ + "C\x00" "\x0b" /* 'C' 11 */ + "P\x00" "\x08" /* 'P' 8 */ + "☭\x00" "\x05" /* '☭' 5 */ + "less\x00" "\x0a" /* 'less' 10 */ + "Č\x00" "\x04" /* 'Č' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "©\x00" "\x04" /* '©' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "€\x00" "\x05" /* '€' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "₠\x00" "\x05" /* '₠' 5 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ć\x00" "\x04" /* 'Ć' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "©\x00" "\x04" /* '©' 4 */ + "r\x00" "\x08" /* 'r' 8 */ + "₢\x00" "\x05" /* '₢' 5 */ + "bar\x00" "\x09" /* 'bar' 9 */ + "¢\x00" "\x04" /* '¢' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ç\x00" "\x04" /* 'Ç' 4 */ + "slash\x00" "\x0c" /* 'slash' 12 */ + "₡\x00" "\x05" /* '₡' 5 */ + "exclam\x00" "\x81\xe6" /* 'exclam' 486 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẉ\x00" "\x05" /* 'Ẉ' 5 */ + "a\x00" "\x08" /* 'a' 8 */ + "ạ\x00" "\x05" /* 'ạ' 5 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ợ\x00" "\x05" /* 'ợ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ự\x00" "\x05" /* 'ự' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ợ\x00" "\x05" /* 'Ợ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ự\x00" "\x05" /* 'Ự' 5 */ + "exclam\x00" "\x0c" /* 'exclam' 12 */ + "¡\x00" "\x04" /* '¡' 4 */ + "e\x00" "\x08" /* 'e' 8 */ + "ẹ\x00" "\x05" /* 'ẹ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ọ\x00" "\x05" /* 'ọ' 5 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḷ\x00" "\x05" /* 'ḷ' 5 */ + "t\x00" "\x08" /* 't' 8 */ + "ṭ\x00" "\x05" /* 'ṭ' 5 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ự\x00" "\x05" /* 'ự' 5 */ + "y\x00" "\x08" /* 'y' 8 */ + "ỵ\x00" "\x05" /* 'ỵ' 5 */ + "b\x00" "\x08" /* 'b' 8 */ + "ḅ\x00" "\x05" /* 'ḅ' 5 */ + "i\x00" "\x08" /* 'i' 8 */ + "ị\x00" "\x05" /* 'ị' 5 */ + "k\x00" "\x08" /* 'k' 8 */ + "ḳ\x00" "\x05" /* 'ḳ' 5 */ + "n\x00" "\x08" /* 'n' 8 */ + "ṇ\x00" "\x05" /* 'ṇ' 5 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ợ\x00" "\x05" /* 'Ợ' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ợ\x00" "\x05" /* 'ợ' 5 */ + "V\x00" "\x08" /* 'V' 8 */ + "Ṿ\x00" "\x05" /* 'Ṿ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ụ\x00" "\x05" /* 'ụ' 5 */ + "z\x00" "\x08" /* 'z' 8 */ + "ẓ\x00" "\x05" /* 'ẓ' 5 */ + "H\x00" "\x08" /* 'H' 8 */ + "Ḥ\x00" "\x05" /* 'Ḥ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ẹ\x00" "\x05" /* 'Ẹ' 5 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṣ\x00" "\x05" /* 'Ṣ' 5 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "Ỵ\x00" "\x05" /* 'Ỵ' 5 */ + "d\x00" "\x08" /* 'd' 8 */ + "ḍ\x00" "\x05" /* 'ḍ' 5 */ + "D\x00" "\x08" /* 'D' 8 */ + "Ḍ\x00" "\x05" /* 'Ḍ' 5 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ợ\x00" "\x05" /* 'ợ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ự\x00" "\x05" /* 'ự' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ợ\x00" "\x05" /* 'Ợ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ự\x00" "\x05" /* 'Ự' 5 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẉ\x00" "\x05" /* 'ẉ' 5 */ + "v\x00" "\x08" /* 'v' 8 */ + "ṿ\x00" "\x05" /* 'ṿ' 5 */ + "question\x00" "\x0f" /* 'question' 15 */ + "‽\x00" "\x05" /* '‽' 5 */ + "M\x00" "\x08" /* 'M' 8 */ + "Ṃ\x00" "\x05" /* 'Ṃ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ọ\x00" "\x05" /* 'Ọ' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "ṃ\x00" "\x05" /* 'ṃ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṛ\x00" "\x05" /* 'ṛ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṣ\x00" "\x05" /* 'ṣ' 5 */ + "Z\x00" "\x08" /* 'Z' 8 */ + "Ẓ\x00" "\x05" /* 'Ẓ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ạ\x00" "\x05" /* 'Ạ' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṛ\x00" "\x05" /* 'Ṛ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḷ\x00" "\x05" /* 'Ḷ' 5 */ + "T\x00" "\x08" /* 'T' 8 */ + "Ṭ\x00" "\x05" /* 'Ṭ' 5 */ + "K\x00" "\x08" /* 'K' 8 */ + "Ḳ\x00" "\x05" /* 'Ḳ' 5 */ + "B\x00" "\x08" /* 'B' 8 */ + "Ḅ\x00" "\x05" /* 'Ḅ' 5 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ự\x00" "\x05" /* 'Ự' 5 */ + "h\x00" "\x08" /* 'h' 8 */ + "ḥ\x00" "\x05" /* 'ḥ' 5 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ị\x00" "\x05" /* 'Ị' 5 */ + "N\x00" "\x08" /* 'N' 8 */ + "Ṇ\x00" "\x05" /* 'Ṇ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ụ\x00" "\x05" /* 'Ụ' 5 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "¦\x00" "\x04" /* '¦' 4 */ + "less\x00" "\x81\x03" /* 'less' 259 */ + "minus\x00" "\x0c" /* 'minus' 12 */ + "←\x00" "\x05" /* '←' 5 */ + "C\x00" "\x07" /* 'C' 7 */ + "Č\x00" "\x04" /* 'Č' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "«\x00" "\x04" /* '«' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ě\x00" "\x04" /* 'ě' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ľ\x00" "\x04" /* 'ľ' 4 */ + "t\x00" "\x07" /* 't' 7 */ + "ť\x00" "\x04" /* 'ť' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + "ˇ\x00" "\x04" /* 'ˇ' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ň\x00" "\x04" /* 'ň' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "≤\x00" "\x05" /* '≤' 5 */ + "z\x00" "\x07" /* 'z' 7 */ + "ž\x00" "\x04" /* 'ž' 4 */ + "3\x00" "\x08" /* '3' 8 */ + "♥\x00" "\x05" /* '♥' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ě\x00" "\x04" /* 'Ě' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Š\x00" "\x04" /* 'Š' 4 */ + "d\x00" "\x07" /* 'd' 7 */ + "ď\x00" "\x04" /* 'ď' 4 */ + "D\x00" "\x07" /* 'D' 7 */ + "Ď\x00" "\x04" /* 'Ď' 4 */ + "quotedbl\x00" "\x0f" /* 'quotedbl' 15 */ + "“\x00" "\x05" /* '“' 5 */ + "underscore\x00" "\x11" /* 'underscore' 17 */ + "≤\x00" "\x05" /* '≤' 5 */ + "apostrophe\x00" "\x11" /* 'apostrophe' 17 */ + "‘\x00" "\x05" /* '‘' 5 */ + "r\x00" "\x07" /* 'r' 7 */ + "ř\x00" "\x04" /* 'ř' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "š\x00" "\x04" /* 'š' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ž\x00" "\x04" /* 'Ž' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ř\x00" "\x04" /* 'Ř' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "č\x00" "\x04" /* 'č' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ľ\x00" "\x04" /* 'Ľ' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ť\x00" "\x04" /* 'Ť' 4 */ + "slash\x00" "\x0a" /* 'slash' 10 */ + "\\\x00" "\x03" /* '\' 3 */ + "greater\x00" "\x0e" /* 'greater' 14 */ + "⋄\x00" "\x05" /* '⋄' 5 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ň\x00" "\x04" /* 'Ň' 4 */ + "KP_Divide\x00" "\x80\xea" /* 'KP_Divide' 234 */ + "g\x00" "\x07" /* 'g' 7 */ + "ǥ\x00" "\x04" /* 'ǥ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ø\x00" "\x04" /* 'ø' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ł\x00" "\x04" /* 'ł' 4 */ + "t\x00" "\x07" /* 't' 7 */ + "ŧ\x00" "\x04" /* 'ŧ' 4 */ + "b\x00" "\x07" /* 'b' 7 */ + "ƀ\x00" "\x04" /* 'ƀ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ɨ\x00" "\x04" /* 'ɨ' 4 */ + "Cyrillic_GHE\x00" "\x12" /* 'Cyrillic_GHE' 18 */ + "Ғ\x00" "\x04" /* 'Ғ' 4 */ + "leftarrow\x00" "\x10" /* 'leftarrow' 16 */ + "↚\x00" "\x05" /* '↚' 5 */ + "Cyrillic_KA\x00" "\x11" /* 'Cyrillic_KA' 17 */ + "Ҟ\x00" "\x04" /* 'Ҟ' 4 */ + "rightarrow\x00" "\x11" /* 'rightarrow' 17 */ + "↛\x00" "\x05" /* '↛' 5 */ + "z\x00" "\x07" /* 'z' 7 */ + "ƶ\x00" "\x04" /* 'ƶ' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ǥ\x00" "\x04" /* 'Ǥ' 4 */ + "H\x00" "\x07" /* 'H' 7 */ + "Ħ\x00" "\x04" /* 'Ħ' 4 */ + "d\x00" "\x07" /* 'd' 7 */ + "đ\x00" "\x04" /* 'đ' 4 */ + "Cyrillic_ka\x00" "\x11" /* 'Cyrillic_ka' 17 */ + "ҟ\x00" "\x04" /* 'ҟ' 4 */ + "D\x00" "\x07" /* 'D' 7 */ + "Đ\x00" "\x04" /* 'Đ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ø\x00" "\x04" /* 'Ø' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ƶ\x00" "\x04" /* 'Ƶ' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ł\x00" "\x04" /* 'Ł' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ŧ\x00" "\x04" /* 'Ŧ' 4 */ + "Cyrillic_ghe\x00" "\x12" /* 'Cyrillic_ghe' 18 */ + "ғ\x00" "\x04" /* 'ғ' 4 */ + "h\x00" "\x07" /* 'h' 7 */ + "ħ\x00" "\x04" /* 'ħ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ɨ\x00" "\x04" /* 'Ɨ' 4 */ + "F\x00" "\x28" /* 'F' 40 */ + "period\x00" "\x0d" /* 'period' 13 */ + "Ḟ\x00" "\x05" /* 'Ḟ' 5 */ + "l\x00" "\x08" /* 'l' 8 */ + "ffl\x00" "\x05" /* 'ffl' 5 */ + "i\x00" "\x08" /* 'i' 8 */ + "ffi\x00" "\x05" /* 'ffi' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "₣\x00" "\x05" /* '₣' 5 */ + "e\x00" "\x80\xb4" /* 'e' 180 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "ē\x00" "\x04" /* 'ē' 4 */ + "period\x00" "\x0c" /* 'period' 12 */ + "ė\x00" "\x04" /* 'ė' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "ě\x00" "\x04" /* 'ě' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ə\x00" "\x04" /* 'ə' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "ë\x00" "\x04" /* 'ë' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "€\x00" "\x05" /* '€' 5 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "ë\x00" "\x04" /* 'ë' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "é\x00" "\x04" /* 'é' 4 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "ē\x00" "\x04" /* 'ē' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "é\x00" "\x04" /* 'é' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ę\x00" "\x04" /* 'ę' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "ê\x00" "\x04" /* 'ê' 4 */ + "grave\x00" "\x0b" /* 'grave' 11 */ + "è\x00" "\x04" /* 'è' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "ê\x00" "\x04" /* 'ê' 4 */ + "o\x00" "\x81\x06" /* 'o' 262 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "ō\x00" "\x04" /* 'ō' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "å\x00" "\x04" /* 'å' 4 */ + "C\x00" "\x07" /* 'C' 7 */ + "©\x00" "\x04" /* '©' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "œ\x00" "\x04" /* 'œ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "°\x00" "\x04" /* '°' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "ö\x00" "\x04" /* 'ö' 4 */ + "y\x00" "\x08" /* 'y' 8 */ + "ẙ\x00" "\x05" /* 'ẙ' 5 */ + "x\x00" "\x07" /* 'x' 7 */ + "¤\x00" "\x04" /* '¤' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ů\x00" "\x04" /* 'ů' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "ö\x00" "\x04" /* 'ö' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "ó\x00" "\x04" /* 'ó' 4 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẘ\x00" "\x05" /* 'ẘ' 5 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "ō\x00" "\x04" /* 'ō' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ó\x00" "\x04" /* 'ó' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "®\x00" "\x04" /* '®' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "§\x00" "\x04" /* '§' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Å\x00" "\x04" /* 'Å' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "®\x00" "\x04" /* '®' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "©\x00" "\x04" /* '©' 4 */ + "asciitilde\x00" "\x10" /* 'asciitilde' 16 */ + "õ\x00" "\x04" /* 'õ' 4 */ + "slash\x00" "\x0b" /* 'slash' 11 */ + "ø\x00" "\x04" /* 'ø' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "ô\x00" "\x04" /* 'ô' 4 */ + "X\x00" "\x07" /* 'X' 7 */ + "¤\x00" "\x04" /* '¤' 4 */ + "grave\x00" "\x0b" /* 'grave' 11 */ + "ò\x00" "\x04" /* 'ò' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ů\x00" "\x04" /* 'Ů' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "ô\x00" "\x04" /* 'ô' 4 */ + "l\x00" "\x44" /* 'l' 68 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "£\x00" "\x04" /* '£' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "ľ\x00" "\x04" /* 'ľ' 4 */ + "v\x00" "\x06" /* 'v' 6 */ + "|\x00" "\x03" /* '|' 3 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ĺ\x00" "\x04" /* 'ĺ' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ļ\x00" "\x04" /* 'ļ' 4 */ + "slash\x00" "\x0b" /* 'slash' 11 */ + "ł\x00" "\x04" /* 'ł' 4 */ + "Greek_upsilon\x00" "\x2d" /* 'Greek_upsilon' 45 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "ϋ\x00" "\x04" /* 'ϋ' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ύ\x00" "\x04" /* 'ύ' 4 */ + "t\x00" "\x52" /* 't' 82 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "ŧ\x00" "\x04" /* 'ŧ' 4 */ + "period\x00" "\x0d" /* 'period' 13 */ + "ṫ\x00" "\x05" /* 'ṫ' 5 */ + "less\x00" "\x0a" /* 'less' 10 */ + "ť\x00" "\x04" /* 'ť' 4 */ + "M\x00" "\x08" /* 'M' 8 */ + "™\x00" "\x05" /* '™' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "™\x00" "\x05" /* '™' 5 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ţ\x00" "\x04" /* 'ţ' 4 */ + "slash\x00" "\x0b" /* 'slash' 11 */ + "ŧ\x00" "\x04" /* 'ŧ' 4 */ + "h\x00" "\x07" /* 'h' 7 */ + "þ\x00" "\x04" /* 'þ' 4 */ + "diaeresis\x00" "\x80\xe7" /* 'diaeresis' 231 */ + "a\x00" "\x07" /* 'a' 7 */ + "ä\x00" "\x04" /* 'ä' 4 */ + "dead_grave\x00" "\x11" /* 'dead_grave' 17 */ + "῭\x00" "\x05" /* '῭' 5 */ + "e\x00" "\x07" /* 'e' 7 */ + "ë\x00" "\x04" /* 'ë' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ö\x00" "\x04" /* 'ö' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ÿ\x00" "\x04" /* 'ÿ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ï\x00" "\x04" /* 'ï' 4 */ + "dead_tilde\x00" "\x11" /* 'dead_tilde' 17 */ + "῁\x00" "\x05" /* '῁' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ü\x00" "\x04" /* 'ü' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ë\x00" "\x04" /* 'Ë' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ÿ\x00" "\x04" /* 'Ÿ' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "΅\x00" "\x04" /* '΅' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "΅\x00" "\x04" /* '΅' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ö\x00" "\x04" /* 'Ö' 4 */ + "asterisk\x00" "\x0f" /* 'asterisk' 15 */ + "⍣\x00" "\x05" /* '⍣' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ä\x00" "\x04" /* 'Ä' 4 */ + "asciitilde\x00" "\x11" /* 'asciitilde' 17 */ + "῁\x00" "\x05" /* '῁' 5 */ + "greater\x00" "\x0e" /* 'greater' 14 */ + "⍩\x00" "\x05" /* '⍩' 5 */ + "dead_acute\x00" "\x10" /* 'dead_acute' 16 */ + "΅\x00" "\x04" /* '΅' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ï\x00" "\x04" /* 'Ï' 4 */ + "grave\x00" "\x0c" /* 'grave' 12 */ + "῭\x00" "\x05" /* '῭' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ü\x00" "\x04" /* 'Ü' 4 */ + "space\x00" "\x80\x92" /* 'space' 146 */ + "minus\x00" "\x0a" /* 'minus' 10 */ + "~\x00" "\x03" /* '~' 3 */ + "period\x00" "\x0d" /* 'period' 13 */ + " \x00" "\x05" /* ' ' 5 */ + "less\x00" "\x0a" /* 'less' 10 */ + "ˇ\x00" "\x04" /* 'ˇ' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + " \x00" "\x04" /* ' ' 4 */ + "apostrophe\x00" "\x0f" /* 'apostrophe' 15 */ + "'\x00" "\x03" /* ''' 3 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "¸\x00" "\x04" /* '¸' 4 */ + "asciitilde\x00" "\x0f" /* 'asciitilde' 15 */ + "~\x00" "\x03" /* '~' 3 */ + "greater\x00" "\x0c" /* 'greater' 12 */ + "^\x00" "\x03" /* '^' 3 */ + "parenleft\x00" "\x0f" /* 'parenleft' 15 */ + "˘\x00" "\x04" /* '˘' 4 */ + "grave\x00" "\x0a" /* 'grave' 10 */ + "`\x00" "\x03" /* '`' 3 */ + "asciicircum\x00" "\x10" /* 'asciicircum' 16 */ + "^\x00" "\x03" /* '^' 3 */ + "percent\x00" "\x11" /* 'percent' 17 */ + "o\x00" "\x08" /* 'o' 8 */ + "‰\x00" "\x05" /* '‰' 5 */ + "y\x00" "\x62" /* 'y' 98 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "¥\x00" "\x04" /* '¥' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "ÿ\x00" "\x04" /* 'ÿ' 4 */ + "equal\x00" "\x0b" /* 'equal' 11 */ + "¥\x00" "\x04" /* '¥' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "ÿ\x00" "\x04" /* 'ÿ' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "ý\x00" "\x04" /* 'ý' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ý\x00" "\x04" /* 'ý' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "ŷ\x00" "\x04" /* 'ŷ' 4 */ + "b\x00" "\x81\xfe" /* 'b' 510 */ + "period\x00" "\x0d" /* 'period' 13 */ + "ḃ\x00" "\x05" /* 'ḃ' 5 */ + "g\x00" "\x07" /* 'g' 7 */ + "ğ\x00" "\x04" /* 'ğ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "ă\x00" "\x04" /* 'ă' 4 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ῐ\x00" "\x05" /* 'Ῐ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῐ\x00" "\x05" /* 'ῐ' 5 */ + "exclam\x00" "\x18" /* 'exclam' 24 */ + "a\x00" "\x08" /* 'a' 8 */ + "ặ\x00" "\x05" /* 'ặ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ặ\x00" "\x05" /* 'Ặ' 5 */ + "e\x00" "\x07" /* 'e' 7 */ + "ĕ\x00" "\x04" /* 'ĕ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ŏ\x00" "\x04" /* 'ŏ' 4 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῠ\x00" "\x05" /* 'ῠ' 5 */ + "dead_belowdot\x00" "\x1f" /* 'dead_belowdot' 31 */ + "a\x00" "\x08" /* 'a' 8 */ + "ặ\x00" "\x05" /* 'ặ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ặ\x00" "\x05" /* 'Ặ' 5 */ + "Cyrillic_I\x00" "\x10" /* 'Cyrillic_I' 16 */ + "Й\x00" "\x04" /* 'Й' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ĭ\x00" "\x04" /* 'ĭ' 4 */ + "Cyrillic_a\x00" "\x10" /* 'Cyrillic_a' 16 */ + "ӑ\x00" "\x04" /* 'ӑ' 4 */ + "Cyrillic_U\x00" "\x10" /* 'Cyrillic_U' 16 */ + "Ў\x00" "\x04" /* 'Ў' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ŭ\x00" "\x04" /* 'ŭ' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ğ\x00" "\x04" /* 'Ğ' 4 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ᾰ\x00" "\x05" /* 'Ᾰ' 5 */ + "Cyrillic_ie\x00" "\x11" /* 'Cyrillic_ie' 17 */ + "ӗ\x00" "\x04" /* 'ӗ' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ĕ\x00" "\x04" /* 'Ĕ' 4 */ + "Cyrillic_i\x00" "\x10" /* 'Cyrillic_i' 16 */ + "й\x00" "\x04" /* 'й' 4 */ + "Cyrillic_zhe\x00" "\x12" /* 'Cyrillic_zhe' 18 */ + "ӂ\x00" "\x04" /* 'ӂ' 4 */ + "cedilla\x00" "\x19" /* 'cedilla' 25 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḝ\x00" "\x05" /* 'ḝ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḝ\x00" "\x05" /* 'Ḝ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾰ\x00" "\x05" /* 'ᾰ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ŏ\x00" "\x04" /* 'Ŏ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ă\x00" "\x04" /* 'Ă' 4 */ + "Cyrillic_A\x00" "\x10" /* 'Cyrillic_A' 16 */ + "Ӑ\x00" "\x04" /* 'Ӑ' 4 */ + "comma\x00" "\x17" /* 'comma' 23 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḝ\x00" "\x05" /* 'ḝ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḝ\x00" "\x05" /* 'Ḝ' 5 */ + "Cyrillic_ZHE\x00" "\x12" /* 'Cyrillic_ZHE' 18 */ + "Ӂ\x00" "\x04" /* 'Ӂ' 4 */ + "Cyrillic_IE\x00" "\x11" /* 'Cyrillic_IE' 17 */ + "Ӗ\x00" "\x04" /* 'Ӗ' 4 */ + "dead_cedilla\x00" "\x1e" /* 'dead_cedilla' 30 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḝ\x00" "\x05" /* 'ḝ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḝ\x00" "\x05" /* 'Ḝ' 5 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ĭ\x00" "\x04" /* 'Ĭ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ŭ\x00" "\x04" /* 'Ŭ' 4 */ + "Cyrillic_u\x00" "\x10" /* 'Cyrillic_u' 16 */ + "ў\x00" "\x04" /* 'ў' 4 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ῠ\x00" "\x05" /* 'Ῠ' 5 */ + "i\x00" "\x80\xbd" /* 'i' 189 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "ī\x00" "\x04" /* 'ī' 4 */ + "period\x00" "\x0c" /* 'period' 12 */ + "ı\x00" "\x04" /* 'ı' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "ï\x00" "\x04" /* 'ï' 4 */ + "j\x00" "\x07" /* 'j' 7 */ + "ij\x00" "\x04" /* 'ij' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "ï\x00" "\x04" /* 'ï' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "í\x00" "\x04" /* 'í' 4 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "ī\x00" "\x04" /* 'ī' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "í\x00" "\x04" /* 'í' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "į\x00" "\x04" /* 'į' 4 */ + "asciitilde\x00" "\x10" /* 'asciitilde' 16 */ + "ĩ\x00" "\x04" /* 'ĩ' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "î\x00" "\x04" /* 'î' 4 */ + "semicolon\x00" "\x0f" /* 'semicolon' 15 */ + "į\x00" "\x04" /* 'į' 4 */ + "grave\x00" "\x0b" /* 'grave' 11 */ + "ì\x00" "\x04" /* 'ì' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "î\x00" "\x04" /* 'î' 4 */ + "k\x00" "\x15" /* 'k' 21 */ + "k\x00" "\x07" /* 'k' 7 */ + "ĸ\x00" "\x04" /* 'ĸ' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ķ\x00" "\x04" /* 'ķ' 4 */ + "n\x00" "\x3f" /* 'n' 63 */ + "g\x00" "\x07" /* 'g' 7 */ + "ŋ\x00" "\x04" /* 'ŋ' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "ň\x00" "\x04" /* 'ň' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ń\x00" "\x04" /* 'ń' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ņ\x00" "\x04" /* 'ņ' 4 */ + "asciitilde\x00" "\x10" /* 'asciitilde' 16 */ + "ñ\x00" "\x04" /* 'ñ' 4 */ + "equal\x00" "\x80\xd3" /* 'equal' 211 */ + "W\x00" "\x08" /* 'W' 8 */ + "₩\x00" "\x05" /* '₩' 5 */ + "C\x00" "\x08" /* 'C' 8 */ + "€\x00" "\x05" /* '€' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "€\x00" "\x05" /* '€' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "ő\x00" "\x04" /* 'ő' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "¥\x00" "\x04" /* '¥' 4 */ + "Cyrillic_U\x00" "\x10" /* 'Cyrillic_U' 16 */ + "Ӳ\x00" "\x04" /* 'Ӳ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ű\x00" "\x04" /* 'ű' 4 */ + "E\x00" "\x08" /* 'E' 8 */ + "€\x00" "\x05" /* '€' 5 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "¥\x00" "\x04" /* '¥' 4 */ + "d\x00" "\x08" /* 'd' 8 */ + "₫\x00" "\x05" /* '₫' 5 */ + "underscore\x00" "\x11" /* 'underscore' 17 */ + "≡\x00" "\x05" /* '≡' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ő\x00" "\x04" /* 'Ő' 4 */ + "Cyrillic_ES\x00" "\x12" /* 'Cyrillic_ES' 18 */ + "€\x00" "\x05" /* '€' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "€\x00" "\x05" /* '€' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "₤\x00" "\x05" /* '₤' 5 */ + "slash\x00" "\x0c" /* 'slash' 12 */ + "≠\x00" "\x05" /* '≠' 5 */ + "Cyrillic_IE\x00" "\x12" /* 'Cyrillic_IE' 18 */ + "€\x00" "\x05" /* '€' 5 */ + "N\x00" "\x08" /* 'N' 8 */ + "₦\x00" "\x05" /* '₦' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ű\x00" "\x04" /* 'Ű' 4 */ + "Cyrillic_u\x00" "\x10" /* 'Cyrillic_u' 16 */ + "ӳ\x00" "\x04" /* 'ӳ' 4 */ + "7\x00" "\x0b" /* '7' 11 */ + "8\x00" "\x08" /* '8' 8 */ + "⅞\x00" "\x05" /* '⅞' 5 */ + "parenright\x00" "\x81\x24" /* 'parenright' 292 */ + "minus\x00" "\x0a" /* 'minus' 10 */ + "}\x00" "\x03" /* '}' 3 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἰ\x00" "\x05" /* 'Ἰ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἰ\x00" "\x05" /* 'ἰ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὀ\x00" "\x05" /* 'Ὀ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὐ\x00" "\x05" /* 'ὐ' 5 */ + "parenright\x00" "\x0f" /* 'parenright' 15 */ + "]\x00" "\x03" /* ']' 3 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἐ\x00" "\x05" /* 'ἐ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἀ\x00" "\x05" /* 'Ἀ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὀ\x00" "\x05" /* 'ὀ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἠ\x00" "\x05" /* 'ἠ' 5 */ + "Greek_rho\x00" "\x10" /* 'Greek_rho' 16 */ + "ῤ\x00" "\x05" /* 'ῤ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἀ\x00" "\x05" /* 'ἀ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἠ\x00" "\x05" /* 'Ἠ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἐ\x00" "\x05" /* 'Ἐ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὠ\x00" "\x05" /* 'ὠ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὠ\x00" "\x05" /* 'Ὠ' 5 */ + "x\x00" "\x18" /* 'x' 24 */ + "o\x00" "\x07" /* 'o' 7 */ + "¤\x00" "\x04" /* '¤' 4 */ + "x\x00" "\x07" /* 'x' 7 */ + "×\x00" "\x04" /* '×' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "¤\x00" "\x04" /* '¤' 4 */ + "Greek_epsilon\x00" "\x1f" /* 'Greek_epsilon' 31 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "έ\x00" "\x04" /* 'έ' 4 */ + "braceleft\x00" "\x1c" /* 'braceleft' 28 */ + "braceright\x00" "\x11" /* 'braceright' 17 */ + "∅\x00" "\x05" /* '∅' 5 */ + "underbar\x00" "\x81\x2c" /* 'underbar' 300 */ + "1\x00" "\x08" /* '1' 8 */ + "₁\x00" "\x05" /* '₁' 5 */ + "KP_4\x00" "\x0b" /* 'KP_4' 11 */ + "₄\x00" "\x05" /* '₄' 5 */ + "KP_6\x00" "\x0b" /* 'KP_6' 11 */ + "₆\x00" "\x05" /* '₆' 5 */ + "KP_8\x00" "\x0b" /* 'KP_8' 11 */ + "₈\x00" "\x05" /* '₈' 5 */ + "KP_9\x00" "\x0b" /* 'KP_9' 11 */ + "₉\x00" "\x05" /* '₉' 5 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "₌\x00" "\x05" /* '₌' 5 */ + "KP_Space\x00" "\x0f" /* 'KP_Space' 15 */ + "₂\x00" "\x05" /* '₂' 5 */ + "7\x00" "\x08" /* '7' 8 */ + "₇\x00" "\x05" /* '₇' 5 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "₎\x00" "\x05" /* '₎' 5 */ + "KP_7\x00" "\x0b" /* 'KP_7' 11 */ + "₇\x00" "\x05" /* '₇' 5 */ + "8\x00" "\x08" /* '8' 8 */ + "₈\x00" "\x05" /* '₈' 5 */ + "KP_1\x00" "\x0b" /* 'KP_1' 11 */ + "₁\x00" "\x05" /* '₁' 5 */ + "3\x00" "\x08" /* '3' 8 */ + "₃\x00" "\x05" /* '₃' 5 */ + "2\x00" "\x08" /* '2' 8 */ + "₂\x00" "\x05" /* '₂' 5 */ + "plus\x00" "\x0b" /* 'plus' 11 */ + "₊\x00" "\x05" /* '₊' 5 */ + "6\x00" "\x08" /* '6' 8 */ + "₆\x00" "\x05" /* '₆' 5 */ + "4\x00" "\x08" /* '4' 8 */ + "₄\x00" "\x05" /* '₄' 5 */ + "KP_3\x00" "\x0b" /* 'KP_3' 11 */ + "₃\x00" "\x05" /* '₃' 5 */ + "KP_0\x00" "\x0b" /* 'KP_0' 11 */ + "₀\x00" "\x05" /* '₀' 5 */ + "KP_Add\x00" "\x0d" /* 'KP_Add' 13 */ + "₊\x00" "\x05" /* '₊' 5 */ + "KP_2\x00" "\x0b" /* 'KP_2' 11 */ + "₂\x00" "\x05" /* '₂' 5 */ + "5\x00" "\x08" /* '5' 8 */ + "₅\x00" "\x05" /* '₅' 5 */ + "KP_5\x00" "\x0b" /* 'KP_5' 11 */ + "₅\x00" "\x05" /* '₅' 5 */ + "9\x00" "\x08" /* '9' 8 */ + "₉\x00" "\x05" /* '₉' 5 */ + "0\x00" "\x08" /* '0' 8 */ + "₀\x00" "\x05" /* '₀' 5 */ + "parenleft\x00" "\x10" /* 'parenleft' 16 */ + "₍\x00" "\x05" /* '₍' 5 */ + "KP_Equal\x00" "\x0f" /* 'KP_Equal' 15 */ + "₌\x00" "\x05" /* '₌' 5 */ + "V\x00" "\x09" /* 'V' 9 */ + "L\x00" "\x06" /* 'L' 6 */ + "|\x00" "\x03" /* '|' 3 */ + "u\x00" "\x80\xbb" /* 'u' 187 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "ū\x00" "\x04" /* 'ū' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "ü\x00" "\x04" /* 'ü' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ŭ\x00" "\x04" /* 'ŭ' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "ü\x00" "\x04" /* 'ü' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "ú\x00" "\x04" /* 'ú' 4 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "ū\x00" "\x04" /* 'ū' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ú\x00" "\x04" /* 'ú' 4 */ + "asterisk\x00" "\x0e" /* 'asterisk' 14 */ + "ů\x00" "\x04" /* 'ů' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ų\x00" "\x04" /* 'ų' 4 */ + "asciitilde\x00" "\x10" /* 'asciitilde' 16 */ + "ũ\x00" "\x04" /* 'ũ' 4 */ + "slash\x00" "\x0b" /* 'slash' 11 */ + "µ\x00" "\x04" /* 'µ' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "û\x00" "\x04" /* 'û' 4 */ + "grave\x00" "\x0b" /* 'grave' 11 */ + "ù\x00" "\x04" /* 'ù' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "û\x00" "\x04" /* 'û' 4 */ + "breve\x00" "\x15" /* 'breve' 21 */ + "g\x00" "\x07" /* 'g' 7 */ + "ğ\x00" "\x04" /* 'ğ' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ğ\x00" "\x04" /* 'Ğ' 4 */ + "z\x00" "\x29" /* 'z' 41 */ + "period\x00" "\x0c" /* 'period' 12 */ + "ż\x00" "\x04" /* 'ż' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "ž\x00" "\x04" /* 'ž' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ź\x00" "\x04" /* 'ź' 4 */ + "G\x00" "\x3b" /* 'G' 59 */ + "period\x00" "\x0c" /* 'period' 12 */ + "Ġ\x00" "\x04" /* 'Ġ' 4 */ + "breve\x00" "\x0b" /* 'breve' 11 */ + "Ğ\x00" "\x04" /* 'Ğ' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ģ\x00" "\x04" /* 'Ģ' 4 */ + "parenleft\x00" "\x0f" /* 'parenleft' 15 */ + "Ğ\x00" "\x04" /* 'Ğ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ğ\x00" "\x04" /* 'Ğ' 4 */ + "Greek_ALPHA\x00" "\x1d" /* 'Greek_ALPHA' 29 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ά\x00" "\x04" /* 'Ά' 4 */ + "bracketleft\x00" "\x20" /* 'bracketleft' 32 */ + "bracketright\x00" "\x13" /* 'bracketright' 19 */ + "⌷\x00" "\x05" /* '⌷' 5 */ + "H\x00" "\x0f" /* 'H' 15 */ + "comma\x00" "\x0c" /* 'comma' 12 */ + "Ḩ\x00" "\x05" /* 'Ḩ' 5 */ + "8\x00" "\x0b" /* '8' 11 */ + "8\x00" "\x08" /* '8' 8 */ + "∞\x00" "\x05" /* '∞' 5 */ + "3\x00" "\x2b" /* '3' 43 */ + "8\x00" "\x08" /* '8' 8 */ + "⅜\x00" "\x05" /* '⅜' 5 */ + "4\x00" "\x07" /* '4' 7 */ + "¾\x00" "\x04" /* '¾' 4 */ + "5\x00" "\x08" /* '5' 8 */ + "⅗\x00" "\x05" /* '⅗' 5 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "³\x00" "\x04" /* '³' 4 */ + "E\x00" "\x80\xad" /* 'E' 173 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "Ē\x00" "\x04" /* 'Ē' 4 */ + "period\x00" "\x0c" /* 'period' 12 */ + "Ė\x00" "\x04" /* 'Ė' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "Ě\x00" "\x04" /* 'Ě' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "Ë\x00" "\x04" /* 'Ë' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "€\x00" "\x05" /* '€' 5 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "Ë\x00" "\x04" /* 'Ë' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "É\x00" "\x04" /* 'É' 4 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "Ē\x00" "\x04" /* 'Ē' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "É\x00" "\x04" /* 'É' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ę\x00" "\x04" /* 'Ę' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "Ê\x00" "\x04" /* 'Ê' 4 */ + "grave\x00" "\x0b" /* 'grave' 11 */ + "È\x00" "\x04" /* 'È' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "Ê\x00" "\x04" /* 'Ê' 4 */ + "S\x00" "\x60" /* 'S' 96 */ + "period\x00" "\x0d" /* 'period' 13 */ + "Ṡ\x00" "\x05" /* 'Ṡ' 5 */ + "exclam\x00" "\x0c" /* 'exclam' 12 */ + "§\x00" "\x04" /* '§' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "Š\x00" "\x04" /* 'Š' 4 */ + "S\x00" "\x08" /* 'S' 8 */ + "ẞ\x00" "\x05" /* 'ẞ' 5 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ś\x00" "\x04" /* 'Ś' 4 */ + "M\x00" "\x08" /* 'M' 8 */ + "℠\x00" "\x05" /* '℠' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "§\x00" "\x04" /* '§' 4 */ + "m\x00" "\x08" /* 'm' 8 */ + "℠\x00" "\x05" /* '℠' 5 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ş\x00" "\x04" /* 'Ş' 4 */ + "2\x00" "\x24" /* '2' 36 */ + "3\x00" "\x08" /* '3' 8 */ + "⅔\x00" "\x05" /* '⅔' 5 */ + "5\x00" "\x08" /* '5' 8 */ + "⅖\x00" "\x05" /* '⅖' 5 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "²\x00" "\x04" /* '²' 4 */ + "Y\x00" "\x62" /* 'Y' 98 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "¥\x00" "\x04" /* '¥' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "Ÿ\x00" "\x04" /* 'Ÿ' 4 */ + "equal\x00" "\x0b" /* 'equal' 11 */ + "¥\x00" "\x04" /* '¥' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "Ÿ\x00" "\x04" /* 'Ÿ' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "Ý\x00" "\x04" /* 'Ý' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ý\x00" "\x04" /* 'Ý' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "Ŷ\x00" "\x04" /* 'Ŷ' 4 */ + "f\x00" "\x36" /* 'f' 54 */ + "period\x00" "\x0d" /* 'period' 13 */ + "ḟ\x00" "\x05" /* 'ḟ' 5 */ + "l\x00" "\x08" /* 'l' 8 */ + "fl\x00" "\x05" /* 'fl' 5 */ + "i\x00" "\x08" /* 'i' 8 */ + "fi\x00" "\x05" /* 'fi' 5 */ + "S\x00" "\x07" /* 'S' 7 */ + "ſ\x00" "\x04" /* 'ſ' 4 */ + "f\x00" "\x08" /* 'f' 8 */ + "ff\x00" "\x05" /* 'ff' 5 */ + "s\x00" "\x07" /* 's' 7 */ + "ſ\x00" "\x04" /* 'ſ' 4 */ + "Greek_omicron\x00" "\x1f" /* 'Greek_omicron' 31 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ό\x00" "\x04" /* 'ό' 4 */ + "Greek_eta\x00" "\x1b" /* 'Greek_eta' 27 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ή\x00" "\x04" /* 'ή' 4 */ + "d\x00" "\x4c" /* 'd' 76 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "đ\x00" "\x04" /* 'đ' 4 */ + "period\x00" "\x0d" /* 'period' 13 */ + "ḋ\x00" "\x05" /* 'ḋ' 5 */ + "less\x00" "\x0a" /* 'less' 10 */ + "ď\x00" "\x04" /* 'ď' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "⌀\x00" "\x05" /* '⌀' 5 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "₫\x00" "\x05" /* '₫' 5 */ + "comma\x00" "\x0c" /* 'comma' 12 */ + "ḑ\x00" "\x05" /* 'ḑ' 5 */ + "h\x00" "\x07" /* 'h' 7 */ + "ð\x00" "\x04" /* 'ð' 4 */ + "D\x00" "\x38" /* 'D' 56 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "Đ\x00" "\x04" /* 'Đ' 4 */ + "period\x00" "\x0d" /* 'period' 13 */ + "Ḋ\x00" "\x05" /* 'Ḋ' 5 */ + "less\x00" "\x0a" /* 'less' 10 */ + "Ď\x00" "\x04" /* 'Ď' 4 */ + "H\x00" "\x07" /* 'H' 7 */ + "Ð\x00" "\x04" /* 'Ð' 4 */ + "comma\x00" "\x0c" /* 'comma' 12 */ + "Ḑ\x00" "\x05" /* 'Ḑ' 5 */ + "quotedbl\x00" "\x83\x6e" /* 'quotedbl' 878 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẅ\x00" "\x05" /* 'Ẅ' 5 */ + "a\x00" "\x07" /* 'a' 7 */ + "ä\x00" "\x04" /* 'ä' 4 */ + "Greek_IOTA\x00" "\x10" /* 'Greek_IOTA' 16 */ + "Ϊ\x00" "\x04" /* 'Ϊ' 4 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ϊ\x00" "\x04" /* 'ϊ' 4 */ + "less\x00" "\x0b" /* 'less' 11 */ + "“\x00" "\x05" /* '“' 5 */ + "Umacron\x00" "\x0e" /* 'Umacron' 14 */ + "Ṻ\x00" "\x05" /* 'Ṻ' 5 */ + "Cyrillic_ZE\x00" "\x11" /* 'Cyrillic_ZE' 17 */ + "Ӟ\x00" "\x04" /* 'Ӟ' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ë\x00" "\x04" /* 'ë' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ö\x00" "\x04" /* 'ö' 4 */ + "Cyrillic_ze\x00" "\x11" /* 'Cyrillic_ze' 17 */ + "ӟ\x00" "\x04" /* 'ӟ' 4 */ + "t\x00" "\x08" /* 't' 8 */ + "ẗ\x00" "\x05" /* 'ẗ' 5 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ϋ\x00" "\x04" /* 'ϋ' 4 */ + "dead_macron\x00" "\x1d" /* 'dead_macron' 29 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṻ\x00" "\x05" /* 'ṻ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṻ\x00" "\x05" /* 'Ṻ' 5 */ + "Cyrillic_I\x00" "\x10" /* 'Cyrillic_I' 16 */ + "Ӥ\x00" "\x04" /* 'Ӥ' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ÿ\x00" "\x04" /* 'ÿ' 4 */ + "Cyrillic_O\x00" "\x10" /* 'Cyrillic_O' 16 */ + "Ӧ\x00" "\x04" /* 'Ӧ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ï\x00" "\x04" /* 'ï' 4 */ + "Ukrainian_I\x00" "\x11" /* 'Ukrainian_I' 17 */ + "Ї\x00" "\x04" /* 'Ї' 4 */ + "dead_tilde\x00" "\x1c" /* 'dead_tilde' 28 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṏ\x00" "\x05" /* 'ṏ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṏ\x00" "\x05" /* 'Ṏ' 5 */ + "Cyrillic_che\x00" "\x12" /* 'Cyrillic_che' 18 */ + "ӵ\x00" "\x04" /* 'ӵ' 4 */ + "Cyrillic_a\x00" "\x10" /* 'Cyrillic_a' 16 */ + "ӓ\x00" "\x04" /* 'ӓ' 4 */ + "x\x00" "\x08" /* 'x' 8 */ + "ẍ\x00" "\x05" /* 'ẍ' 5 */ + "Cyrillic_U\x00" "\x10" /* 'Cyrillic_U' 16 */ + "Ӱ\x00" "\x04" /* 'Ӱ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ü\x00" "\x04" /* 'ü' 4 */ + "otilde\x00" "\x0d" /* 'otilde' 13 */ + "ṏ\x00" "\x05" /* 'ṏ' 5 */ + "H\x00" "\x08" /* 'H' 8 */ + "Ḧ\x00" "\x05" /* 'Ḧ' 5 */ + "Cyrillic_YERU\x00" "\x13" /* 'Cyrillic_YERU' 19 */ + "Ӹ\x00" "\x04" /* 'Ӹ' 4 */ + "Cyrillic_ie\x00" "\x11" /* 'Cyrillic_ie' 17 */ + "ё\x00" "\x04" /* 'ё' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ë\x00" "\x04" /* 'Ë' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ÿ\x00" "\x04" /* 'Ÿ' 4 */ + "Cyrillic_i\x00" "\x10" /* 'Cyrillic_i' 16 */ + "ӥ\x00" "\x04" /* 'ӥ' 4 */ + "Otilde\x00" "\x0d" /* 'Otilde' 13 */ + "Ṏ\x00" "\x05" /* 'Ṏ' 5 */ + "Cyrillic_zhe\x00" "\x12" /* 'Cyrillic_zhe' 18 */ + "ӝ\x00" "\x04" /* 'ӝ' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "¨\x00" "\x04" /* '¨' 4 */ + "umacron\x00" "\x0e" /* 'umacron' 14 */ + "ṻ\x00" "\x05" /* 'ṻ' 5 */ + "Cyrillic_yeru\x00" "\x13" /* 'Cyrillic_yeru' 19 */ + "ӹ\x00" "\x04" /* 'ӹ' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "̈́\x00" "\x04" /* '̈́' 4 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẅ\x00" "\x05" /* 'ẅ' 5 */ + "Cyrillic_CHE\x00" "\x12" /* 'Cyrillic_CHE' 18 */ + "Ӵ\x00" "\x04" /* 'Ӵ' 4 */ + "Cyrillic_o\x00" "\x10" /* 'Cyrillic_o' 16 */ + "ӧ\x00" "\x04" /* 'ӧ' 4 */ + "Ukrainian_i\x00" "\x11" /* 'Ukrainian_i' 17 */ + "ї\x00" "\x04" /* 'ї' 4 */ + "Cyrillic_E\x00" "\x10" /* 'Cyrillic_E' 16 */ + "Ӭ\x00" "\x04" /* 'Ӭ' 4 */ + "underscore\x00" "\x1c" /* 'underscore' 28 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṻ\x00" "\x05" /* 'ṻ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṻ\x00" "\x05" /* 'Ṻ' 5 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "̈́\x00" "\x04" /* '̈́' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ö\x00" "\x04" /* 'Ö' 4 */ + "macron\x00" "\x18" /* 'macron' 24 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṻ\x00" "\x05" /* 'ṻ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṻ\x00" "\x05" /* 'Ṻ' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ä\x00" "\x04" /* 'Ä' 4 */ + "Cyrillic_A\x00" "\x10" /* 'Cyrillic_A' 16 */ + "Ӓ\x00" "\x04" /* 'Ӓ' 4 */ + "comma\x00" "\x0c" /* 'comma' 12 */ + "„\x00" "\x05" /* '„' 5 */ + "asciitilde\x00" "\x1c" /* 'asciitilde' 28 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṏ\x00" "\x05" /* 'ṏ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṏ\x00" "\x05" /* 'Ṏ' 5 */ + "greater\x00" "\x0e" /* 'greater' 14 */ + "”\x00" "\x05" /* '”' 5 */ + "Cyrillic_ZHE\x00" "\x12" /* 'Cyrillic_ZHE' 18 */ + "Ӝ\x00" "\x04" /* 'Ӝ' 4 */ + "Cyrillic_IE\x00" "\x11" /* 'Cyrillic_IE' 17 */ + "Ё\x00" "\x04" /* 'Ё' 4 */ + "Cyrillic_e\x00" "\x10" /* 'Cyrillic_e' 16 */ + "ӭ\x00" "\x04" /* 'ӭ' 4 */ + "dead_acute\x00" "\x10" /* 'dead_acute' 16 */ + "̈́\x00" "\x04" /* '̈́' 4 */ + "X\x00" "\x08" /* 'X' 8 */ + "Ẍ\x00" "\x05" /* 'Ẍ' 5 */ + "h\x00" "\x08" /* 'h' 8 */ + "ḧ\x00" "\x05" /* 'ḧ' 5 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ï\x00" "\x04" /* 'Ï' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ü\x00" "\x04" /* 'Ü' 4 */ + "Cyrillic_u\x00" "\x10" /* 'Cyrillic_u' 16 */ + "ӱ\x00" "\x04" /* 'ӱ' 4 */ + "Greek_UPSILON\x00" "\x13" /* 'Greek_UPSILON' 19 */ + "Ϋ\x00" "\x04" /* 'Ϋ' 4 */ + "plus\x00" "\x36" /* 'plus' 54 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "±\x00" "\x04" /* '±' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ơ\x00" "\x04" /* 'ơ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ư\x00" "\x04" /* 'ư' 4 */ + "plus\x00" "\x09" /* 'plus' 9 */ + "#\x00" "\x03" /* '#' 3 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ơ\x00" "\x04" /* 'Ơ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ư\x00" "\x04" /* 'Ư' 4 */ + "cedilla\x00" "\x80\xa8" /* 'cedilla' 168 */ + "g\x00" "\x07" /* 'g' 7 */ + "ģ\x00" "\x04" /* 'ģ' 4 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ç\x00" "\x04" /* 'Ç' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ȩ\x00" "\x04" /* 'ȩ' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ļ\x00" "\x04" /* 'ļ' 4 */ + "t\x00" "\x07" /* 't' 7 */ + "ţ\x00" "\x04" /* 'ţ' 4 */ + "k\x00" "\x07" /* 'k' 7 */ + "ķ\x00" "\x04" /* 'ķ' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ņ\x00" "\x04" /* 'ņ' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ģ\x00" "\x04" /* 'Ģ' 4 */ + "H\x00" "\x08" /* 'H' 8 */ + "Ḩ\x00" "\x05" /* 'Ḩ' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ȩ\x00" "\x04" /* 'Ȩ' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Ş\x00" "\x04" /* 'Ş' 4 */ + "d\x00" "\x08" /* 'd' 8 */ + "ḑ\x00" "\x05" /* 'ḑ' 5 */ + "D\x00" "\x08" /* 'D' 8 */ + "Ḑ\x00" "\x05" /* 'Ḑ' 5 */ + "r\x00" "\x07" /* 'r' 7 */ + "ŗ\x00" "\x04" /* 'ŗ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ş\x00" "\x04" /* 'ş' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ŗ\x00" "\x04" /* 'Ŗ' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "ç\x00" "\x04" /* 'ç' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ļ\x00" "\x04" /* 'Ļ' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ţ\x00" "\x04" /* 'Ţ' 4 */ + "K\x00" "\x07" /* 'K' 7 */ + "Ķ\x00" "\x04" /* 'Ķ' 4 */ + "h\x00" "\x08" /* 'h' 8 */ + "ḩ\x00" "\x05" /* 'ḩ' 5 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ņ\x00" "\x04" /* 'Ņ' 4 */ + "Greek_alpha\x00" "\x1d" /* 'Greek_alpha' 29 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ά\x00" "\x04" /* 'ά' 4 */ + "dead_abovedot\x00" "\x1a" /* 'dead_abovedot' 26 */ + "f\x00" "\x0b" /* 'f' 11 */ + "s\x00" "\x08" /* 's' 8 */ + "ẛ\x00" "\x05" /* 'ẛ' 5 */ + "acute\x00" "\x8c\x29" /* 'acute' 3113 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẃ\x00" "\x05" /* 'Ẃ' 5 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "g\x00" "\x07" /* 'g' 7 */ + "ǵ\x00" "\x04" /* 'ǵ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "á\x00" "\x04" /* 'á' 4 */ + "Greek_IOTA\x00" "\x10" /* 'Greek_IOTA' 16 */ + "Ί\x00" "\x04" /* 'Ί' 4 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ί\x00" "\x04" /* 'ί' 4 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "dead_circumflex\x00" "\x41" /* 'dead_circumflex' 65 */ + "a\x00" "\x08" /* 'a' 8 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "Greek_OMICRON\x00" "\x13" /* 'Greek_OMICRON' 19 */ + "Ό\x00" "\x04" /* 'Ό' 4 */ + "Acircumflex\x00" "\x12" /* 'Acircumflex' 18 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ć\x00" "\x04" /* 'Ć' 4 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р́\x00" "\x06" /* 'р́' 6 */ + "e\x00" "\x07" /* 'e' 7 */ + "é\x00" "\x04" /* 'é' 4 */ + "KP_Divide\x00" "\x19" /* 'KP_Divide' 25 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "Utilde\x00" "\x0d" /* 'Utilde' 13 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "ó\x00" "\x04" /* 'ó' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ĺ\x00" "\x04" /* 'ĺ' 4 */ + "Udiaeresis\x00" "\x10" /* 'Udiaeresis' 16 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ύ\x00" "\x04" /* 'ύ' 4 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "dead_macron\x00" "\x2d" /* 'dead_macron' 45 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "acircumflex\x00" "\x12" /* 'acircumflex' 18 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "Ecircumflex\x00" "\x12" /* 'Ecircumflex' 18 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "Cyrillic_I\x00" "\x12" /* 'Cyrillic_I' 18 */ + "И́\x00" "\x06" /* 'И́' 6 */ + "y\x00" "\x07" /* 'y' 7 */ + "ý\x00" "\x04" /* 'ý' 4 */ + "b\x00" "\x13" /* 'b' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "idiaeresis\x00" "\x11" /* 'idiaeresis' 17 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О́\x00" "\x06" /* 'О́' 6 */ + "i\x00" "\x07" /* 'i' 7 */ + "í\x00" "\x04" /* 'í' 4 */ + "k\x00" "\x08" /* 'k' 8 */ + "ḱ\x00" "\x05" /* 'ḱ' 5 */ + "n\x00" "\x07" /* 'n' 7 */ + "ń\x00" "\x04" /* 'ń' 4 */ + "ccedilla\x00" "\x0f" /* 'ccedilla' 15 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "Cyrillic_GHE\x00" "\x12" /* 'Cyrillic_GHE' 18 */ + "Ѓ\x00" "\x04" /* 'Ѓ' 4 */ + "dead_tilde\x00" "\x2c" /* 'dead_tilde' 44 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а́\x00" "\x06" /* 'а́' 6 */ + "parenright\x00" "\x80\xfb" /* 'parenright' 251 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἴ\x00" "\x05" /* 'Ἴ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἴ\x00" "\x05" /* 'ἴ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὄ\x00" "\x05" /* 'Ὄ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὔ\x00" "\x05" /* 'ὔ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἔ\x00" "\x05" /* 'ἔ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἄ\x00" "\x05" /* 'Ἄ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὄ\x00" "\x05" /* 'ὄ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἤ\x00" "\x05" /* 'ἤ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἄ\x00" "\x05" /* 'ἄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἤ\x00" "\x05" /* 'Ἤ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἔ\x00" "\x05" /* 'Ἔ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὤ\x00" "\x05" /* 'ὤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὤ\x00" "\x05" /* 'Ὤ' 5 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р́\x00" "\x06" /* 'Р́' 6 */ + "Greek_epsilon\x00" "\x13" /* 'Greek_epsilon' 19 */ + "έ\x00" "\x04" /* 'έ' 4 */ + "Cyrillic_KA\x00" "\x11" /* 'Cyrillic_KA' 17 */ + "Ќ\x00" "\x04" /* 'Ќ' 4 */ + "Cyrillic_U\x00" "\x12" /* 'Cyrillic_U' 18 */ + "У́\x00" "\x06" /* 'У́' 6 */ + "dead_abovering\x00" "\x1e" /* 'dead_abovering' 30 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǻ\x00" "\x04" /* 'ǻ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǻ\x00" "\x04" /* 'Ǻ' 4 */ + "Ocircumflex\x00" "\x12" /* 'Ocircumflex' 18 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "AE\x00" "\x08" /* 'AE' 8 */ + "Ǽ\x00" "\x04" /* 'Ǽ' 4 */ + "omacron\x00" "\x0e" /* 'omacron' 14 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "ocircumflex\x00" "\x12" /* 'ocircumflex' 18 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ú\x00" "\x04" /* 'ú' 4 */ + "z\x00" "\x07" /* 'z' 7 */ + "ź\x00" "\x04" /* 'ź' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ǵ\x00" "\x04" /* 'Ǵ' 4 */ + "Greek_ALPHA\x00" "\x11" /* 'Greek_ALPHA' 17 */ + "Ά\x00" "\x04" /* 'Ά' 4 */ + "otilde\x00" "\x0d" /* 'otilde' 13 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "utilde\x00" "\x0d" /* 'utilde' 13 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е́\x00" "\x06" /* 'е́' 6 */ + "emacron\x00" "\x0e" /* 'emacron' 14 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "É\x00" "\x04" /* 'É' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Ś\x00" "\x04" /* 'Ś' 4 */ + "Greek_iotadieresis\x00" "\x18" /* 'Greek_iotadieresis' 24 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ý\x00" "\x04" /* 'Ý' 4 */ + "Cyrillic_i\x00" "\x12" /* 'Cyrillic_i' 18 */ + "и́\x00" "\x06" /* 'и́' 6 */ + "dead_dasia\x00" "\x81\x0f" /* 'dead_dasia' 271 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἵ\x00" "\x05" /* 'Ἵ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἵ\x00" "\x05" /* 'ἵ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὅ\x00" "\x05" /* 'Ὅ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὕ\x00" "\x05" /* 'ὕ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἕ\x00" "\x05" /* 'ἕ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἅ\x00" "\x05" /* 'Ἅ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὅ\x00" "\x05" /* 'ὅ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἥ\x00" "\x05" /* 'ἥ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἅ\x00" "\x05" /* 'ἅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἥ\x00" "\x05" /* 'Ἥ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἕ\x00" "\x05" /* 'Ἕ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὥ\x00" "\x05" /* 'ὥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὥ\x00" "\x05" /* 'Ὥ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὕ\x00" "\x05" /* 'Ὕ' 5 */ + "Greek_upsilondieresis\x00" "\x1b" /* 'Greek_upsilondieresis' 27 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "Greek_omicron\x00" "\x13" /* 'Greek_omicron' 19 */ + "ό\x00" "\x04" /* 'ό' 4 */ + "Greek_eta\x00" "\x0f" /* 'Greek_eta' 15 */ + "ή\x00" "\x04" /* 'ή' 4 */ + "Otilde\x00" "\x0d" /* 'Otilde' 13 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "Cyrillic_ka\x00" "\x11" /* 'Cyrillic_ka' 17 */ + "ќ\x00" "\x04" /* 'ќ' 4 */ + "Aring\x00" "\x0b" /* 'Aring' 11 */ + "Ǻ\x00" "\x04" /* 'Ǻ' 4 */ + "Abreve\x00" "\x0d" /* 'Abreve' 13 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "dead_psili\x00" "\x80\xfb" /* 'dead_psili' 251 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἴ\x00" "\x05" /* 'Ἴ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἴ\x00" "\x05" /* 'ἴ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὄ\x00" "\x05" /* 'Ὄ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὔ\x00" "\x05" /* 'ὔ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἔ\x00" "\x05" /* 'ἔ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἄ\x00" "\x05" /* 'Ἄ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὄ\x00" "\x05" /* 'ὄ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἤ\x00" "\x05" /* 'ἤ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἄ\x00" "\x05" /* 'ἄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἤ\x00" "\x05" /* 'Ἤ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἔ\x00" "\x05" /* 'Ἔ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὤ\x00" "\x05" /* 'ὤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὤ\x00" "\x05" /* 'Ὤ' 5 */ + "quotedbl\x00" "\x4b" /* 'quotedbl' 75 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "cedilla\x00" "\x19" /* 'cedilla' 25 */ + "C\x00" "\x08" /* 'C' 8 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "Greek_alpha\x00" "\x11" /* 'Greek_alpha' 17 */ + "ά\x00" "\x04" /* 'ά' 4 */ + "ecircumflex\x00" "\x12" /* 'ecircumflex' 18 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẃ\x00" "\x05" /* 'ẃ' 5 */ + "Greek_ETA\x00" "\x0f" /* 'Greek_ETA' 15 */ + "Ή\x00" "\x04" /* 'Ή' 4 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о́\x00" "\x06" /* 'о́' 6 */ + "Emacron\x00" "\x0e" /* 'Emacron' 14 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "Ooblique\x00" "\x0e" /* 'Ooblique' 14 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "p\x00" "\x08" /* 'p' 8 */ + "ṕ\x00" "\x05" /* 'ṕ' 5 */ + "underscore\x00" "\x2c" /* 'underscore' 44 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "P\x00" "\x08" /* 'P' 8 */ + "Ṕ\x00" "\x05" /* 'Ṕ' 5 */ + "M\x00" "\x08" /* 'M' 8 */ + "Ḿ\x00" "\x05" /* 'Ḿ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ó\x00" "\x04" /* 'Ó' 4 */ + "abreve\x00" "\x0d" /* 'abreve' 13 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "ḿ\x00" "\x05" /* 'ḿ' 5 */ + "r\x00" "\x07" /* 'r' 7 */ + "ŕ\x00" "\x04" /* 'ŕ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ś\x00" "\x04" /* 'ś' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ź\x00" "\x04" /* 'Ź' 4 */ + "macron\x00" "\x28" /* 'macron' 40 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Á\x00" "\x04" /* 'Á' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ŕ\x00" "\x04" /* 'Ŕ' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "ć\x00" "\x04" /* 'ć' 4 */ + "Idiaeresis\x00" "\x11" /* 'Idiaeresis' 17 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ĺ\x00" "\x04" /* 'Ĺ' 4 */ + "Greek_EPSILON\x00" "\x13" /* 'Greek_EPSILON' 19 */ + "Έ\x00" "\x04" /* 'Έ' 4 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А́\x00" "\x06" /* 'А́' 6 */ + "comma\x00" "\x17" /* 'comma' 23 */ + "C\x00" "\x08" /* 'C' 8 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "asciitilde\x00" "\x2c" /* 'asciitilde' 44 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "Ccedilla\x00" "\x0f" /* 'Ccedilla' 15 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "slash\x00" "\x15" /* 'slash' 21 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "aring\x00" "\x0b" /* 'aring' 11 */ + "ǻ\x00" "\x04" /* 'ǻ' 4 */ + "K\x00" "\x08" /* 'K' 8 */ + "Ḱ\x00" "\x05" /* 'Ḱ' 5 */ + "Omacron\x00" "\x0e" /* 'Omacron' 14 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е́\x00" "\x06" /* 'Е́' 6 */ + "dead_cedilla\x00" "\x1e" /* 'dead_cedilla' 30 */ + "C\x00" "\x08" /* 'C' 8 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "Greek_omega\x00" "\x11" /* 'Greek_omega' 17 */ + "ώ\x00" "\x04" /* 'ώ' 4 */ + "dead_diaeresis\x00" "\x51" /* 'dead_diaeresis' 81 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "Greek_OMEGA\x00" "\x11" /* 'Greek_OMEGA' 17 */ + "Ώ\x00" "\x04" /* 'Ώ' 4 */ + "oslash\x00" "\x0c" /* 'oslash' 12 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "Cyrillic_ghe\x00" "\x12" /* 'Cyrillic_ghe' 18 */ + "ѓ\x00" "\x04" /* 'ѓ' 4 */ + "parenleft\x00" "\x81\x0e" /* 'parenleft' 270 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἵ\x00" "\x05" /* 'Ἵ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἵ\x00" "\x05" /* 'ἵ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὅ\x00" "\x05" /* 'Ὅ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὕ\x00" "\x05" /* 'ὕ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἕ\x00" "\x05" /* 'ἕ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἅ\x00" "\x05" /* 'Ἅ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὅ\x00" "\x05" /* 'ὅ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἥ\x00" "\x05" /* 'ἥ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἅ\x00" "\x05" /* 'ἅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἥ\x00" "\x05" /* 'Ἥ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἕ\x00" "\x05" /* 'Ἕ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὥ\x00" "\x05" /* 'ὥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὥ\x00" "\x05" /* 'Ὥ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὕ\x00" "\x05" /* 'Ὕ' 5 */ + "udiaeresis\x00" "\x10" /* 'udiaeresis' 16 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Í\x00" "\x04" /* 'Í' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ń\x00" "\x04" /* 'Ń' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ú\x00" "\x04" /* 'Ú' 4 */ + "Cyrillic_u\x00" "\x12" /* 'Cyrillic_u' 18 */ + "у́\x00" "\x06" /* 'у́' 6 */ + "ae\x00" "\x08" /* 'ae' 8 */ + "ǽ\x00" "\x04" /* 'ǽ' 4 */ + "asciicircum\x00" "\x3d" /* 'asciicircum' 61 */ + "a\x00" "\x08" /* 'a' 8 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "Greek_UPSILON\x00" "\x13" /* 'Greek_UPSILON' 19 */ + "Ύ\x00" "\x04" /* 'Ύ' 4 */ + "Cyrillic_pe\x00" "\x1d" /* 'Cyrillic_pe' 29 */ + "Cyrillic_a\x00" "\x10" /* 'Cyrillic_a' 16 */ + "§\x00" "\x04" /* '§' 4 */ + "w\x00" "\x14" /* 'w' 20 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "ŵ\x00" "\x04" /* 'ŵ' 4 */ + "Greek_ETA\x00" "\x1b" /* 'Greek_ETA' 27 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ή\x00" "\x04" /* 'Ή' 4 */ + "4\x00" "\x0b" /* '4' 11 */ + "5\x00" "\x08" /* '5' 8 */ + "⅘\x00" "\x05" /* '⅘' 5 */ + "bracketright\x00" "\x20" /* 'bracketright' 32 */ + "bracketleft\x00" "\x12" /* 'bracketleft' 18 */ + "⌷\x00" "\x05" /* '⌷' 5 */ + "colon\x00" "\x33" /* 'colon' 51 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "÷\x00" "\x04" /* '÷' 4 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "☺\x00" "\x05" /* '☺' 5 */ + "parenleft\x00" "\x10" /* 'parenleft' 16 */ + "☹\x00" "\x05" /* '☹' 5 */ + "p\x00" "\x1c" /* 'p' 28 */ + "period\x00" "\x0d" /* 'period' 13 */ + "ṗ\x00" "\x05" /* 'ṗ' 5 */ + "exclam\x00" "\x0c" /* 'exclam' 12 */ + "¶\x00" "\x04" /* '¶' 4 */ + "underscore\x00" "\x85\x23" /* 'underscore' 1315 */ + "adiaeresis\x00" "\x10" /* 'adiaeresis' 16 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "period\x00" "\x24" /* 'period' 36 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǡ\x00" "\x04" /* 'ǡ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȱ\x00" "\x04" /* 'ȱ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȱ\x00" "\x04" /* 'Ȱ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǡ\x00" "\x04" /* 'Ǡ' 4 */ + "g\x00" "\x08" /* 'g' 8 */ + "ḡ\x00" "\x05" /* 'ḡ' 5 */ + "a\x00" "\x07" /* 'a' 7 */ + "ā\x00" "\x04" /* 'ā' 4 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ῑ\x00" "\x05" /* 'Ῑ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῑ\x00" "\x05" /* 'ῑ' 5 */ + "1\x00" "\x08" /* '1' 8 */ + "₁\x00" "\x05" /* '₁' 5 */ + "exclam\x00" "\x28" /* 'exclam' 40 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḹ\x00" "\x05" /* 'ḹ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṝ\x00" "\x05" /* 'ṝ' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṝ\x00" "\x05" /* 'Ṝ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḹ\x00" "\x05" /* 'Ḹ' 5 */ + "KP_4\x00" "\x0b" /* 'KP_4' 11 */ + "₄\x00" "\x05" /* '₄' 5 */ + "less\x00" "\x0b" /* 'less' 11 */ + "≤\x00" "\x05" /* '≤' 5 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р̄\x00" "\x06" /* 'р̄' 6 */ + "o\x00" "\x07" /* 'o' 7 */ + "ō\x00" "\x04" /* 'ō' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ē\x00" "\x04" /* 'ē' 4 */ + "KP_6\x00" "\x0b" /* 'KP_6' 11 */ + "₆\x00" "\x05" /* '₆' 5 */ + "Udiaeresis\x00" "\x10" /* 'Udiaeresis' 16 */ + "Ǖ\x00" "\x04" /* 'Ǖ' 4 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῡ\x00" "\x05" /* 'ῡ' 5 */ + "dead_belowdot\x00" "\x2f" /* 'dead_belowdot' 47 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḹ\x00" "\x05" /* 'ḹ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṝ\x00" "\x05" /* 'ṝ' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṝ\x00" "\x05" /* 'Ṝ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḹ\x00" "\x05" /* 'Ḹ' 5 */ + "KP_8\x00" "\x0b" /* 'KP_8' 11 */ + "₈\x00" "\x05" /* '₈' 5 */ + "Cyrillic_I\x00" "\x10" /* 'Cyrillic_I' 16 */ + "Ӣ\x00" "\x04" /* 'Ӣ' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ȳ\x00" "\x04" /* 'ȳ' 4 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О̄\x00" "\x06" /* 'О̄' 6 */ + "i\x00" "\x07" /* 'i' 7 */ + "ī\x00" "\x04" /* 'ī' 4 */ + "KP_9\x00" "\x0b" /* 'KP_9' 11 */ + "₉\x00" "\x05" /* '₉' 5 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "₌\x00" "\x05" /* '₌' 5 */ + "KP_Space\x00" "\x0f" /* 'KP_Space' 15 */ + "₂\x00" "\x05" /* '₂' 5 */ + "dead_tilde\x00" "\x1a" /* 'dead_tilde' 26 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "7\x00" "\x08" /* '7' 8 */ + "₇\x00" "\x05" /* '₇' 5 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а̄\x00" "\x06" /* 'а̄' 6 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "₎\x00" "\x05" /* '₎' 5 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р̄\x00" "\x06" /* 'Р̄' 6 */ + "KP_7\x00" "\x0b" /* 'KP_7' 11 */ + "₇\x00" "\x05" /* '₇' 5 */ + "Cyrillic_U\x00" "\x10" /* 'Cyrillic_U' 16 */ + "Ӯ\x00" "\x04" /* 'Ӯ' 4 */ + "AE\x00" "\x08" /* 'AE' 8 */ + "Ǣ\x00" "\x04" /* 'Ǣ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ū\x00" "\x04" /* 'ū' 4 */ + "G\x00" "\x08" /* 'G' 8 */ + "Ḡ\x00" "\x05" /* 'Ḡ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ᾱ\x00" "\x05" /* 'Ᾱ' 5 */ + "otilde\x00" "\x0c" /* 'otilde' 12 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "8\x00" "\x08" /* '8' 8 */ + "₈\x00" "\x05" /* '₈' 5 */ + "KP_1\x00" "\x0b" /* 'KP_1' 11 */ + "₁\x00" "\x05" /* '₁' 5 */ + "3\x00" "\x08" /* '3' 8 */ + "₃\x00" "\x05" /* '₃' 5 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е̄\x00" "\x06" /* 'е̄' 6 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ē\x00" "\x04" /* 'Ē' 4 */ + "2\x00" "\x08" /* '2' 8 */ + "₂\x00" "\x05" /* '₂' 5 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ȳ\x00" "\x04" /* 'Ȳ' 4 */ + "Cyrillic_i\x00" "\x10" /* 'Cyrillic_i' 16 */ + "ӣ\x00" "\x04" /* 'ӣ' 4 */ + "dead_ogonek\x00" "\x1b" /* 'dead_ogonek' 27 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǭ\x00" "\x04" /* 'ǭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǭ\x00" "\x04" /* 'Ǭ' 4 */ + "odiaeresis\x00" "\x10" /* 'odiaeresis' 16 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "Otilde\x00" "\x0c" /* 'Otilde' 12 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "quotedbl\x00" "\x34" /* 'quotedbl' 52 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǖ\x00" "\x04" /* 'ǖ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǖ\x00" "\x04" /* 'Ǖ' 4 */ + "plus\x00" "\x0b" /* 'plus' 11 */ + "₊\x00" "\x05" /* '₊' 5 */ + "6\x00" "\x08" /* '6' 8 */ + "₆\x00" "\x05" /* '₆' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾱ\x00" "\x05" /* 'ᾱ' 5 */ + "dead_abovedot\x00" "\x2b" /* 'dead_abovedot' 43 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǡ\x00" "\x04" /* 'ǡ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȱ\x00" "\x04" /* 'ȱ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȱ\x00" "\x04" /* 'Ȱ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǡ\x00" "\x04" /* 'Ǡ' 4 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о̄\x00" "\x06" /* 'о̄' 6 */ + "4\x00" "\x08" /* '4' 8 */ + "₄\x00" "\x05" /* '₄' 5 */ + "KP_3\x00" "\x0b" /* 'KP_3' 11 */ + "₃\x00" "\x05" /* '₃' 5 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "¯\x00" "\x04" /* '¯' 4 */ + "apostrophe\x00" "\x11" /* 'apostrophe' 17 */ + "⍘\x00" "\x05" /* '⍘' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ō\x00" "\x04" /* 'Ō' 4 */ + "KP_0\x00" "\x0b" /* 'KP_0' 11 */ + "₀\x00" "\x05" /* '₀' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ā\x00" "\x04" /* 'Ā' 4 */ + "KP_Add\x00" "\x0d" /* 'KP_Add' 13 */ + "₊\x00" "\x05" /* '₊' 5 */ + "Odiaeresis\x00" "\x10" /* 'Odiaeresis' 16 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "KP_2\x00" "\x0b" /* 'KP_2' 11 */ + "₂\x00" "\x05" /* '₂' 5 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А̄\x00" "\x06" /* 'А̄' 6 */ + "asciitilde\x00" "\x1a" /* 'asciitilde' 26 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "5\x00" "\x08" /* '5' 8 */ + "₅\x00" "\x05" /* '₅' 5 */ + "greater\x00" "\x0e" /* 'greater' 14 */ + "≥\x00" "\x05" /* '≥' 5 */ + "semicolon\x00" "\x19" /* 'semicolon' 25 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǭ\x00" "\x04" /* 'ǭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǭ\x00" "\x04" /* 'Ǭ' 4 */ + "KP_5\x00" "\x0b" /* 'KP_5' 11 */ + "₅\x00" "\x05" /* '₅' 5 */ + "9\x00" "\x08" /* '9' 8 */ + "₉\x00" "\x05" /* '₉' 5 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е̄\x00" "\x06" /* 'Е̄' 6 */ + "0\x00" "\x08" /* '0' 8 */ + "₀\x00" "\x05" /* '₀' 5 */ + "dead_diaeresis\x00" "\x3a" /* 'dead_diaeresis' 58 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǖ\x00" "\x04" /* 'ǖ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǖ\x00" "\x04" /* 'Ǖ' 4 */ + "Adiaeresis\x00" "\x10" /* 'Adiaeresis' 16 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "parenleft\x00" "\x10" /* 'parenleft' 16 */ + "₍\x00" "\x05" /* '₍' 5 */ + "udiaeresis\x00" "\x10" /* 'udiaeresis' 16 */ + "ǖ\x00" "\x04" /* 'ǖ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ī\x00" "\x04" /* 'Ī' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ū\x00" "\x04" /* 'Ū' 4 */ + "Cyrillic_u\x00" "\x10" /* 'Cyrillic_u' 16 */ + "ӯ\x00" "\x04" /* 'ӯ' 4 */ + "ae\x00" "\x08" /* 'ae' 8 */ + "ǣ\x00" "\x04" /* 'ǣ' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "¯\x00" "\x04" /* '¯' 4 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ῡ\x00" "\x05" /* 'Ῡ' 5 */ + "KP_Equal\x00" "\x0f" /* 'KP_Equal' 15 */ + "₌\x00" "\x05" /* '₌' 5 */ + "v\x00" "\x23" /* 'v' 35 */ + "l\x00" "\x06" /* 'l' 6 */ + "|\x00" "\x03" /* '|' 3 */ + "z\x00" "\x07" /* 'z' 7 */ + "ž\x00" "\x04" /* 'ž' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ž\x00" "\x04" /* 'Ž' 4 */ + "slash\x00" "\x0c" /* 'slash' 12 */ + "√\x00" "\x05" /* '√' 5 */ + "P\x00" "\x2b" /* 'P' 43 */ + "period\x00" "\x0d" /* 'period' 13 */ + "Ṗ\x00" "\x05" /* 'Ṗ' 5 */ + "exclam\x00" "\x0c" /* 'exclam' 12 */ + "¶\x00" "\x04" /* '¶' 4 */ + "t\x00" "\x08" /* 't' 8 */ + "₧\x00" "\x05" /* '₧' 5 */ + "P\x00" "\x07" /* 'P' 7 */ + "¶\x00" "\x04" /* '¶' 4 */ + "question\x00" "\x82\x3a" /* 'question' 570 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẳ\x00" "\x05" /* 'ẳ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẳ\x00" "\x05" /* 'Ẳ' 5 */ + "a\x00" "\x08" /* 'a' 8 */ + "ả\x00" "\x05" /* 'ả' 5 */ + "dead_circumflex\x00" "\x41" /* 'dead_circumflex' 65 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẩ\x00" "\x05" /* 'ẩ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ể\x00" "\x05" /* 'ể' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ổ\x00" "\x05" /* 'ổ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ể\x00" "\x05" /* 'Ể' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ổ\x00" "\x05" /* 'Ổ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẩ\x00" "\x05" /* 'Ẩ' 5 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ở\x00" "\x05" /* 'ở' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ử\x00" "\x05" /* 'ử' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ở\x00" "\x05" /* 'Ở' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ử\x00" "\x05" /* 'Ử' 5 */ + "Acircumflex\x00" "\x12" /* 'Acircumflex' 18 */ + "Ẩ\x00" "\x05" /* 'Ẩ' 5 */ + "exclam\x00" "\x0d" /* 'exclam' 13 */ + "⸘\x00" "\x05" /* '⸘' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ẻ\x00" "\x05" /* 'ẻ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỏ\x00" "\x05" /* 'ỏ' 5 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ử\x00" "\x05" /* 'ử' 5 */ + "acircumflex\x00" "\x12" /* 'acircumflex' 18 */ + "ẩ\x00" "\x05" /* 'ẩ' 5 */ + "Ecircumflex\x00" "\x12" /* 'Ecircumflex' 18 */ + "Ể\x00" "\x05" /* 'Ể' 5 */ + "y\x00" "\x08" /* 'y' 8 */ + "ỷ\x00" "\x05" /* 'ỷ' 5 */ + "b\x00" "\x13" /* 'b' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẳ\x00" "\x05" /* 'ẳ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẳ\x00" "\x05" /* 'Ẳ' 5 */ + "i\x00" "\x08" /* 'i' 8 */ + "ỉ\x00" "\x05" /* 'ỉ' 5 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ở\x00" "\x05" /* 'Ở' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ở\x00" "\x05" /* 'ở' 5 */ + "Ocircumflex\x00" "\x12" /* 'Ocircumflex' 18 */ + "Ổ\x00" "\x05" /* 'Ổ' 5 */ + "ocircumflex\x00" "\x12" /* 'ocircumflex' 18 */ + "ổ\x00" "\x05" /* 'ổ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ủ\x00" "\x05" /* 'ủ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ẻ\x00" "\x05" /* 'Ẻ' 5 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "Ỷ\x00" "\x05" /* 'Ỷ' 5 */ + "Abreve\x00" "\x0d" /* 'Abreve' 13 */ + "Ẳ\x00" "\x05" /* 'Ẳ' 5 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ở\x00" "\x05" /* 'ở' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ử\x00" "\x05" /* 'ử' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ở\x00" "\x05" /* 'Ở' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ử\x00" "\x05" /* 'Ử' 5 */ + "ecircumflex\x00" "\x12" /* 'ecircumflex' 18 */ + "ể\x00" "\x05" /* 'ể' 5 */ + "question\x00" "\x0e" /* 'question' 14 */ + "¿\x00" "\x04" /* '¿' 4 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỏ\x00" "\x05" /* 'Ỏ' 5 */ + "abreve\x00" "\x0d" /* 'abreve' 13 */ + "ẳ\x00" "\x05" /* 'ẳ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ả\x00" "\x05" /* 'Ả' 5 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ử\x00" "\x05" /* 'Ử' 5 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ỉ\x00" "\x05" /* 'Ỉ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ủ\x00" "\x05" /* 'Ủ' 5 */ + "asciicircum\x00" "\x3d" /* 'asciicircum' 61 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẩ\x00" "\x05" /* 'ẩ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ể\x00" "\x05" /* 'ể' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ổ\x00" "\x05" /* 'ổ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ể\x00" "\x05" /* 'Ể' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ổ\x00" "\x05" /* 'Ổ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẩ\x00" "\x05" /* 'Ẩ' 5 */ + "apostrophe\x00" "\x8c\x61" /* 'apostrophe' 3169 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẃ\x00" "\x05" /* 'Ẃ' 5 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "g\x00" "\x07" /* 'g' 7 */ + "ǵ\x00" "\x04" /* 'ǵ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "á\x00" "\x04" /* 'á' 4 */ + "Greek_IOTA\x00" "\x10" /* 'Greek_IOTA' 16 */ + "Ί\x00" "\x04" /* 'Ί' 4 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ί\x00" "\x04" /* 'ί' 4 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "dead_circumflex\x00" "\x41" /* 'dead_circumflex' 65 */ + "a\x00" "\x08" /* 'a' 8 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "Greek_OMICRON\x00" "\x13" /* 'Greek_OMICRON' 19 */ + "Ό\x00" "\x04" /* 'Ό' 4 */ + "Acircumflex\x00" "\x12" /* 'Acircumflex' 18 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ć\x00" "\x04" /* 'Ć' 4 */ + "less\x00" "\x0b" /* 'less' 11 */ + "‘\x00" "\x05" /* '‘' 5 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р́\x00" "\x06" /* 'р́' 6 */ + "e\x00" "\x07" /* 'e' 7 */ + "é\x00" "\x04" /* 'é' 4 */ + "KP_Divide\x00" "\x19" /* 'KP_Divide' 25 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "Utilde\x00" "\x0d" /* 'Utilde' 13 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "ó\x00" "\x04" /* 'ó' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ĺ\x00" "\x04" /* 'ĺ' 4 */ + "Udiaeresis\x00" "\x10" /* 'Udiaeresis' 16 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ύ\x00" "\x04" /* 'ύ' 4 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "space\x00" "\x0a" /* 'space' 10 */ + "'\x00" "\x03" /* ''' 3 */ + "dead_macron\x00" "\x2d" /* 'dead_macron' 45 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "acircumflex\x00" "\x12" /* 'acircumflex' 18 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "Ecircumflex\x00" "\x12" /* 'Ecircumflex' 18 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "Cyrillic_I\x00" "\x12" /* 'Cyrillic_I' 18 */ + "И́\x00" "\x06" /* 'И́' 6 */ + "y\x00" "\x07" /* 'y' 7 */ + "ý\x00" "\x04" /* 'ý' 4 */ + "b\x00" "\x13" /* 'b' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "idiaeresis\x00" "\x11" /* 'idiaeresis' 17 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О́\x00" "\x06" /* 'О́' 6 */ + "i\x00" "\x07" /* 'i' 7 */ + "í\x00" "\x04" /* 'í' 4 */ + "k\x00" "\x08" /* 'k' 8 */ + "ḱ\x00" "\x05" /* 'ḱ' 5 */ + "n\x00" "\x07" /* 'n' 7 */ + "ń\x00" "\x04" /* 'ń' 4 */ + "ccedilla\x00" "\x0f" /* 'ccedilla' 15 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "Cyrillic_GHE\x00" "\x12" /* 'Cyrillic_GHE' 18 */ + "Ѓ\x00" "\x04" /* 'Ѓ' 4 */ + "dead_tilde\x00" "\x2c" /* 'dead_tilde' 44 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а́\x00" "\x06" /* 'а́' 6 */ + "parenright\x00" "\x80\xfb" /* 'parenright' 251 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἴ\x00" "\x05" /* 'Ἴ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἴ\x00" "\x05" /* 'ἴ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὄ\x00" "\x05" /* 'Ὄ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὔ\x00" "\x05" /* 'ὔ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἔ\x00" "\x05" /* 'ἔ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἄ\x00" "\x05" /* 'Ἄ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὄ\x00" "\x05" /* 'ὄ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἤ\x00" "\x05" /* 'ἤ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἄ\x00" "\x05" /* 'ἄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἤ\x00" "\x05" /* 'Ἤ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἔ\x00" "\x05" /* 'Ἔ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὤ\x00" "\x05" /* 'ὤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὤ\x00" "\x05" /* 'Ὤ' 5 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р́\x00" "\x06" /* 'Р́' 6 */ + "Greek_epsilon\x00" "\x13" /* 'Greek_epsilon' 19 */ + "έ\x00" "\x04" /* 'έ' 4 */ + "Cyrillic_KA\x00" "\x11" /* 'Cyrillic_KA' 17 */ + "Ќ\x00" "\x04" /* 'Ќ' 4 */ + "Cyrillic_U\x00" "\x12" /* 'Cyrillic_U' 18 */ + "У́\x00" "\x06" /* 'У́' 6 */ + "dead_abovering\x00" "\x1e" /* 'dead_abovering' 30 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǻ\x00" "\x04" /* 'ǻ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǻ\x00" "\x04" /* 'Ǻ' 4 */ + "Ocircumflex\x00" "\x12" /* 'Ocircumflex' 18 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "AE\x00" "\x08" /* 'AE' 8 */ + "Ǽ\x00" "\x04" /* 'Ǽ' 4 */ + "omacron\x00" "\x0e" /* 'omacron' 14 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "ocircumflex\x00" "\x12" /* 'ocircumflex' 18 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ú\x00" "\x04" /* 'ú' 4 */ + "z\x00" "\x07" /* 'z' 7 */ + "ź\x00" "\x04" /* 'ź' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ǵ\x00" "\x04" /* 'Ǵ' 4 */ + "Greek_ALPHA\x00" "\x11" /* 'Greek_ALPHA' 17 */ + "Ά\x00" "\x04" /* 'Ά' 4 */ + "otilde\x00" "\x0d" /* 'otilde' 13 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "utilde\x00" "\x0d" /* 'utilde' 13 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е́\x00" "\x06" /* 'е́' 6 */ + "emacron\x00" "\x0e" /* 'emacron' 14 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "É\x00" "\x04" /* 'É' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Ś\x00" "\x04" /* 'Ś' 4 */ + "Greek_iotadieresis\x00" "\x18" /* 'Greek_iotadieresis' 24 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ý\x00" "\x04" /* 'Ý' 4 */ + "Cyrillic_i\x00" "\x12" /* 'Cyrillic_i' 18 */ + "и́\x00" "\x06" /* 'и́' 6 */ + "dead_dasia\x00" "\x81\x0f" /* 'dead_dasia' 271 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἵ\x00" "\x05" /* 'Ἵ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἵ\x00" "\x05" /* 'ἵ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὅ\x00" "\x05" /* 'Ὅ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὕ\x00" "\x05" /* 'ὕ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἕ\x00" "\x05" /* 'ἕ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἅ\x00" "\x05" /* 'Ἅ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὅ\x00" "\x05" /* 'ὅ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἥ\x00" "\x05" /* 'ἥ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἅ\x00" "\x05" /* 'ἅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἥ\x00" "\x05" /* 'Ἥ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἕ\x00" "\x05" /* 'Ἕ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὥ\x00" "\x05" /* 'ὥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὥ\x00" "\x05" /* 'Ὥ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὕ\x00" "\x05" /* 'Ὕ' 5 */ + "Greek_upsilondieresis\x00" "\x1b" /* 'Greek_upsilondieresis' 27 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "Greek_omicron\x00" "\x13" /* 'Greek_omicron' 19 */ + "ό\x00" "\x04" /* 'ό' 4 */ + "Greek_eta\x00" "\x0f" /* 'Greek_eta' 15 */ + "ή\x00" "\x04" /* 'ή' 4 */ + "Otilde\x00" "\x0d" /* 'Otilde' 13 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "Cyrillic_ka\x00" "\x11" /* 'Cyrillic_ka' 17 */ + "ќ\x00" "\x04" /* 'ќ' 4 */ + "Aring\x00" "\x0b" /* 'Aring' 11 */ + "Ǻ\x00" "\x04" /* 'Ǻ' 4 */ + "Abreve\x00" "\x0d" /* 'Abreve' 13 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "dead_psili\x00" "\x80\xfb" /* 'dead_psili' 251 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἴ\x00" "\x05" /* 'Ἴ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἴ\x00" "\x05" /* 'ἴ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὄ\x00" "\x05" /* 'Ὄ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὔ\x00" "\x05" /* 'ὔ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἔ\x00" "\x05" /* 'ἔ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἄ\x00" "\x05" /* 'Ἄ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὄ\x00" "\x05" /* 'ὄ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἤ\x00" "\x05" /* 'ἤ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἄ\x00" "\x05" /* 'ἄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἤ\x00" "\x05" /* 'Ἤ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἔ\x00" "\x05" /* 'Ἔ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὤ\x00" "\x05" /* 'ὤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὤ\x00" "\x05" /* 'Ὤ' 5 */ + "quotedbl\x00" "\x56" /* 'quotedbl' 86 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + "΅\x00" "\x04" /* '΅' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "cedilla\x00" "\x19" /* 'cedilla' 25 */ + "C\x00" "\x08" /* 'C' 8 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "Greek_alpha\x00" "\x11" /* 'Greek_alpha' 17 */ + "ά\x00" "\x04" /* 'ά' 4 */ + "ecircumflex\x00" "\x12" /* 'ecircumflex' 18 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẃ\x00" "\x05" /* 'ẃ' 5 */ + "Greek_ETA\x00" "\x0f" /* 'Greek_ETA' 15 */ + "Ή\x00" "\x04" /* 'Ή' 4 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о́\x00" "\x06" /* 'о́' 6 */ + "Emacron\x00" "\x0e" /* 'Emacron' 14 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "Ooblique\x00" "\x0e" /* 'Ooblique' 14 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "p\x00" "\x08" /* 'p' 8 */ + "ṕ\x00" "\x05" /* 'ṕ' 5 */ + "underscore\x00" "\x2c" /* 'underscore' 44 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "P\x00" "\x08" /* 'P' 8 */ + "Ṕ\x00" "\x05" /* 'Ṕ' 5 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "´\x00" "\x04" /* '´' 4 */ + "M\x00" "\x08" /* 'M' 8 */ + "Ḿ\x00" "\x05" /* 'Ḿ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ó\x00" "\x04" /* 'Ó' 4 */ + "abreve\x00" "\x0d" /* 'abreve' 13 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "ḿ\x00" "\x05" /* 'ḿ' 5 */ + "r\x00" "\x07" /* 'r' 7 */ + "ŕ\x00" "\x04" /* 'ŕ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ś\x00" "\x04" /* 'ś' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ź\x00" "\x04" /* 'Ź' 4 */ + "macron\x00" "\x28" /* 'macron' 40 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Á\x00" "\x04" /* 'Á' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ŕ\x00" "\x04" /* 'Ŕ' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "ć\x00" "\x04" /* 'ć' 4 */ + "Idiaeresis\x00" "\x11" /* 'Idiaeresis' 17 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ĺ\x00" "\x04" /* 'Ĺ' 4 */ + "Greek_EPSILON\x00" "\x13" /* 'Greek_EPSILON' 19 */ + "Έ\x00" "\x04" /* 'Έ' 4 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А́\x00" "\x06" /* 'А́' 6 */ + "comma\x00" "\x0c" /* 'comma' 12 */ + "‚\x00" "\x05" /* '‚' 5 */ + "asciitilde\x00" "\x2c" /* 'asciitilde' 44 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "Ccedilla\x00" "\x0f" /* 'Ccedilla' 15 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "slash\x00" "\x15" /* 'slash' 21 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "aring\x00" "\x0b" /* 'aring' 11 */ + "ǻ\x00" "\x04" /* 'ǻ' 4 */ + "greater\x00" "\x0e" /* 'greater' 14 */ + "’\x00" "\x05" /* '’' 5 */ + "K\x00" "\x08" /* 'K' 8 */ + "Ḱ\x00" "\x05" /* 'Ḱ' 5 */ + "Omacron\x00" "\x0e" /* 'Omacron' 14 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е́\x00" "\x06" /* 'Е́' 6 */ + "dead_cedilla\x00" "\x1e" /* 'dead_cedilla' 30 */ + "C\x00" "\x08" /* 'C' 8 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "Greek_omega\x00" "\x11" /* 'Greek_omega' 17 */ + "ώ\x00" "\x04" /* 'ώ' 4 */ + "dead_diaeresis\x00" "\x51" /* 'dead_diaeresis' 81 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "Greek_OMEGA\x00" "\x11" /* 'Greek_OMEGA' 17 */ + "Ώ\x00" "\x04" /* 'Ώ' 4 */ + "oslash\x00" "\x0c" /* 'oslash' 12 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "Cyrillic_ghe\x00" "\x12" /* 'Cyrillic_ghe' 18 */ + "ѓ\x00" "\x04" /* 'ѓ' 4 */ + "parenleft\x00" "\x81\x0e" /* 'parenleft' 270 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἵ\x00" "\x05" /* 'Ἵ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἵ\x00" "\x05" /* 'ἵ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὅ\x00" "\x05" /* 'Ὅ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὕ\x00" "\x05" /* 'ὕ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἕ\x00" "\x05" /* 'ἕ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἅ\x00" "\x05" /* 'Ἅ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὅ\x00" "\x05" /* 'ὅ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἥ\x00" "\x05" /* 'ἥ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἅ\x00" "\x05" /* 'ἅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἥ\x00" "\x05" /* 'Ἥ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἕ\x00" "\x05" /* 'Ἕ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὥ\x00" "\x05" /* 'ὥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὥ\x00" "\x05" /* 'Ὥ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὕ\x00" "\x05" /* 'Ὕ' 5 */ + "udiaeresis\x00" "\x10" /* 'udiaeresis' 16 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Í\x00" "\x04" /* 'Í' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ń\x00" "\x04" /* 'Ń' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ú\x00" "\x04" /* 'Ú' 4 */ + "Cyrillic_u\x00" "\x12" /* 'Cyrillic_u' 18 */ + "у́\x00" "\x06" /* 'у́' 6 */ + "ae\x00" "\x08" /* 'ae' 8 */ + "ǽ\x00" "\x04" /* 'ǽ' 4 */ + "asciicircum\x00" "\x3d" /* 'asciicircum' 61 */ + "a\x00" "\x08" /* 'a' 8 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "Greek_UPSILON\x00" "\x13" /* 'Greek_UPSILON' 19 */ + "Ύ\x00" "\x04" /* 'Ύ' 4 */ + "M\x00" "\x10" /* 'M' 16 */ + "period\x00" "\x0d" /* 'period' 13 */ + "Ṁ\x00" "\x05" /* 'Ṁ' 5 */ + "O\x00" "\x80\xdb" /* 'O' 219 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "Ō\x00" "\x04" /* 'Ō' 4 */ + "C\x00" "\x07" /* 'C' 7 */ + "©\x00" "\x04" /* '©' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "Ö\x00" "\x04" /* 'Ö' 4 */ + "x\x00" "\x07" /* 'x' 7 */ + "¤\x00" "\x04" /* '¤' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Œ\x00" "\x04" /* 'Œ' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "§\x00" "\x04" /* '§' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "Ö\x00" "\x04" /* 'Ö' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "Ó\x00" "\x04" /* 'Ó' 4 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "Ō\x00" "\x04" /* 'Ō' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ó\x00" "\x04" /* 'Ó' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "®\x00" "\x04" /* '®' 4 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ⓐ\x00" "\x05" /* 'Ⓐ' 5 */ + "R\x00" "\x07" /* 'R' 7 */ + "®\x00" "\x04" /* '®' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "©\x00" "\x04" /* '©' 4 */ + "asciitilde\x00" "\x10" /* 'asciitilde' 16 */ + "Õ\x00" "\x04" /* 'Õ' 4 */ + "slash\x00" "\x0b" /* 'slash' 11 */ + "Ø\x00" "\x04" /* 'Ø' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "Ô\x00" "\x04" /* 'Ô' 4 */ + "X\x00" "\x07" /* 'X' 7 */ + "¤\x00" "\x04" /* '¤' 4 */ + "grave\x00" "\x0b" /* 'grave' 11 */ + "Ò\x00" "\x04" /* 'Ò' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "Ô\x00" "\x04" /* 'Ô' 4 */ + "m\x00" "\x23" /* 'm' 35 */ + "period\x00" "\x0d" /* 'period' 13 */ + "ṁ\x00" "\x05" /* 'ṁ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "µ\x00" "\x04" /* 'µ' 4 */ + "slash\x00" "\x0c" /* 'slash' 12 */ + "₥\x00" "\x05" /* '₥' 5 */ + "r\x00" "\x28" /* 'r' 40 */ + "less\x00" "\x0a" /* 'less' 10 */ + "ř\x00" "\x04" /* 'ř' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ŕ\x00" "\x04" /* 'ŕ' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ŗ\x00" "\x04" /* 'ŗ' 4 */ + "s\x00" "\x6c" /* 's' 108 */ + "period\x00" "\x0d" /* 'period' 13 */ + "ṡ\x00" "\x05" /* 'ṡ' 5 */ + "exclam\x00" "\x0c" /* 'exclam' 12 */ + "§\x00" "\x04" /* '§' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "š\x00" "\x04" /* 'š' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "§\x00" "\x04" /* '§' 4 */ + "cedilla\x00" "\x0d" /* 'cedilla' 13 */ + "ş\x00" "\x04" /* 'ş' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ś\x00" "\x04" /* 'ś' 4 */ + "M\x00" "\x08" /* 'M' 8 */ + "℠\x00" "\x05" /* '℠' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "℠\x00" "\x05" /* '℠' 5 */ + "s\x00" "\x07" /* 's' 7 */ + "ß\x00" "\x04" /* 'ß' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ş\x00" "\x04" /* 'ş' 4 */ + "asterisk\x00" "\x57" /* 'asterisk' 87 */ + "a\x00" "\x07" /* 'a' 7 */ + "å\x00" "\x04" /* 'å' 4 */ + "diaeresis\x00" "\x10" /* 'diaeresis' 16 */ + "⍣\x00" "\x05" /* '⍣' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ů\x00" "\x04" /* 'ů' 4 */ + "apostrophe\x00" "\x1a" /* 'apostrophe' 26 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǻ\x00" "\x04" /* 'ǻ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǻ\x00" "\x04" /* 'Ǻ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Å\x00" "\x04" /* 'Å' 4 */ + "0\x00" "\x07" /* '0' 7 */ + "°\x00" "\x04" /* '°' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ů\x00" "\x04" /* 'Ů' 4 */ + "Z\x00" "\x29" /* 'Z' 41 */ + "period\x00" "\x0c" /* 'period' 12 */ + "Ż\x00" "\x04" /* 'Ż' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "Ž\x00" "\x04" /* 'Ž' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ź\x00" "\x04" /* 'Ź' 4 */ + "bar\x00" "\x24" /* 'bar' 36 */ + "C\x00" "\x07" /* 'C' 7 */ + "¢\x00" "\x04" /* '¢' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "¢\x00" "\x04" /* '¢' 4 */ + "asciitilde\x00" "\x11" /* 'asciitilde' 17 */ + "⍭\x00" "\x05" /* '⍭' 5 */ + "macron\x00" "\x83\xb3" /* 'macron' 947 */ + "adiaeresis\x00" "\x10" /* 'adiaeresis' 16 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "period\x00" "\x24" /* 'period' 36 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǡ\x00" "\x04" /* 'ǡ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȱ\x00" "\x04" /* 'ȱ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȱ\x00" "\x04" /* 'Ȱ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǡ\x00" "\x04" /* 'Ǡ' 4 */ + "g\x00" "\x08" /* 'g' 8 */ + "ḡ\x00" "\x05" /* 'ḡ' 5 */ + "a\x00" "\x07" /* 'a' 7 */ + "ā\x00" "\x04" /* 'ā' 4 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ῑ\x00" "\x05" /* 'Ῑ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῑ\x00" "\x05" /* 'ῑ' 5 */ + "exclam\x00" "\x28" /* 'exclam' 40 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḹ\x00" "\x05" /* 'ḹ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṝ\x00" "\x05" /* 'ṝ' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṝ\x00" "\x05" /* 'Ṝ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḹ\x00" "\x05" /* 'Ḹ' 5 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р̄\x00" "\x06" /* 'р̄' 6 */ + "e\x00" "\x07" /* 'e' 7 */ + "ē\x00" "\x04" /* 'ē' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ō\x00" "\x04" /* 'ō' 4 */ + "Udiaeresis\x00" "\x10" /* 'Udiaeresis' 16 */ + "Ǖ\x00" "\x04" /* 'Ǖ' 4 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῡ\x00" "\x05" /* 'ῡ' 5 */ + "dead_belowdot\x00" "\x2f" /* 'dead_belowdot' 47 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḹ\x00" "\x05" /* 'ḹ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṝ\x00" "\x05" /* 'ṝ' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṝ\x00" "\x05" /* 'Ṝ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḹ\x00" "\x05" /* 'Ḹ' 5 */ + "Cyrillic_I\x00" "\x10" /* 'Cyrillic_I' 16 */ + "Ӣ\x00" "\x04" /* 'Ӣ' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ȳ\x00" "\x04" /* 'ȳ' 4 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О̄\x00" "\x06" /* 'О̄' 6 */ + "i\x00" "\x07" /* 'i' 7 */ + "ī\x00" "\x04" /* 'ī' 4 */ + "dead_tilde\x00" "\x1a" /* 'dead_tilde' 26 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а̄\x00" "\x06" /* 'а̄' 6 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р̄\x00" "\x06" /* 'Р̄' 6 */ + "Cyrillic_U\x00" "\x10" /* 'Cyrillic_U' 16 */ + "Ӯ\x00" "\x04" /* 'Ӯ' 4 */ + "AE\x00" "\x08" /* 'AE' 8 */ + "Ǣ\x00" "\x04" /* 'Ǣ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ū\x00" "\x04" /* 'ū' 4 */ + "G\x00" "\x08" /* 'G' 8 */ + "Ḡ\x00" "\x05" /* 'Ḡ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ᾱ\x00" "\x05" /* 'Ᾱ' 5 */ + "otilde\x00" "\x0c" /* 'otilde' 12 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е̄\x00" "\x06" /* 'е̄' 6 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ē\x00" "\x04" /* 'Ē' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ȳ\x00" "\x04" /* 'Ȳ' 4 */ + "Cyrillic_i\x00" "\x10" /* 'Cyrillic_i' 16 */ + "ӣ\x00" "\x04" /* 'ӣ' 4 */ + "dead_ogonek\x00" "\x1b" /* 'dead_ogonek' 27 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǭ\x00" "\x04" /* 'ǭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǭ\x00" "\x04" /* 'Ǭ' 4 */ + "odiaeresis\x00" "\x10" /* 'odiaeresis' 16 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "Otilde\x00" "\x0c" /* 'Otilde' 12 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "quotedbl\x00" "\x34" /* 'quotedbl' 52 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǖ\x00" "\x04" /* 'ǖ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǖ\x00" "\x04" /* 'Ǖ' 4 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾱ\x00" "\x05" /* 'ᾱ' 5 */ + "dead_abovedot\x00" "\x2b" /* 'dead_abovedot' 43 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǡ\x00" "\x04" /* 'ǡ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȱ\x00" "\x04" /* 'ȱ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȱ\x00" "\x04" /* 'Ȱ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǡ\x00" "\x04" /* 'Ǡ' 4 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о̄\x00" "\x06" /* 'о̄' 6 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ō\x00" "\x04" /* 'Ō' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ā\x00" "\x04" /* 'Ā' 4 */ + "Odiaeresis\x00" "\x10" /* 'Odiaeresis' 16 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А̄\x00" "\x06" /* 'А̄' 6 */ + "asciitilde\x00" "\x1a" /* 'asciitilde' 26 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "semicolon\x00" "\x19" /* 'semicolon' 25 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǭ\x00" "\x04" /* 'ǭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǭ\x00" "\x04" /* 'Ǭ' 4 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е̄\x00" "\x06" /* 'Е̄' 6 */ + "dead_diaeresis\x00" "\x3a" /* 'dead_diaeresis' 58 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǖ\x00" "\x04" /* 'ǖ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǖ\x00" "\x04" /* 'Ǖ' 4 */ + "Adiaeresis\x00" "\x10" /* 'Adiaeresis' 16 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "udiaeresis\x00" "\x10" /* 'udiaeresis' 16 */ + "ǖ\x00" "\x04" /* 'ǖ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ī\x00" "\x04" /* 'Ī' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ū\x00" "\x04" /* 'Ū' 4 */ + "Cyrillic_u\x00" "\x10" /* 'Cyrillic_u' 16 */ + "ӯ\x00" "\x04" /* 'ӯ' 4 */ + "ae\x00" "\x08" /* 'ae' 8 */ + "ǣ\x00" "\x04" /* 'ǣ' 4 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ῡ\x00" "\x05" /* 'Ῡ' 5 */ + "A\x00" "\x80\xcc" /* 'A' 204 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "Ā\x00" "\x04" /* 'Ā' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "Ä\x00" "\x04" /* 'Ä' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Æ\x00" "\x04" /* 'Æ' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "Ä\x00" "\x04" /* 'Ä' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "Á\x00" "\x04" /* 'Á' 4 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "Ā\x00" "\x04" /* 'Ā' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Á\x00" "\x04" /* 'Á' 4 */ + "asterisk\x00" "\x0e" /* 'asterisk' 14 */ + "Å\x00" "\x04" /* 'Å' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Å\x00" "\x04" /* 'Å' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ą\x00" "\x04" /* 'Ą' 4 */ + "T\x00" "\x06" /* 'T' 6 */ + "@\x00" "\x03" /* '@' 3 */ + "asciitilde\x00" "\x10" /* 'asciitilde' 16 */ + "Ã\x00" "\x04" /* 'Ã' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "Â\x00" "\x04" /* 'Â' 4 */ + "parenleft\x00" "\x0f" /* 'parenleft' 15 */ + "Ă\x00" "\x04" /* 'Ă' 4 */ + "grave\x00" "\x0b" /* 'grave' 11 */ + "À\x00" "\x04" /* 'À' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "Â\x00" "\x04" /* 'Â' 4 */ + "R\x00" "\x37" /* 'R' 55 */ + "less\x00" "\x0a" /* 'less' 10 */ + "Ř\x00" "\x04" /* 'Ř' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ŕ\x00" "\x04" /* 'Ŕ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "®\x00" "\x04" /* '®' 4 */ + "s\x00" "\x08" /* 's' 8 */ + "₨\x00" "\x05" /* '₨' 5 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ŗ\x00" "\x04" /* 'Ŗ' 4 */ + "Cyrillic_ES\x00" "\x19" /* 'Cyrillic_ES' 25 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "€\x00" "\x05" /* '€' 5 */ + "c\x00" "\x81\xa4" /* 'c' 420 */ + "period\x00" "\x0c" /* 'period' 12 */ + "ċ\x00" "\x04" /* 'ċ' 4 */ + "g\x00" "\x07" /* 'g' 7 */ + "ǧ\x00" "\x04" /* 'ǧ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǎ\x00" "\x04" /* 'ǎ' 4 */ + "ezh\x00" "\x09" /* 'ezh' 9 */ + "ǯ\x00" "\x04" /* 'ǯ' 4 */ + "C\x00" "\x07" /* 'C' 7 */ + "Č\x00" "\x04" /* 'Č' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "č\x00" "\x04" /* 'č' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ě\x00" "\x04" /* 'ě' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǒ\x00" "\x04" /* 'ǒ' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ľ\x00" "\x04" /* 'ľ' 4 */ + "Udiaeresis\x00" "\x10" /* 'Udiaeresis' 16 */ + "Ǚ\x00" "\x04" /* 'Ǚ' 4 */ + "t\x00" "\x07" /* 't' 7 */ + "ť\x00" "\x04" /* 'ť' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ǐ\x00" "\x04" /* 'ǐ' 4 */ + "k\x00" "\x07" /* 'k' 7 */ + "ǩ\x00" "\x04" /* 'ǩ' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ň\x00" "\x04" /* 'ň' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "€\x00" "\x05" /* '€' 5 */ + "j\x00" "\x07" /* 'j' 7 */ + "ǰ\x00" "\x04" /* 'ǰ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǔ\x00" "\x04" /* 'ǔ' 4 */ + "z\x00" "\x07" /* 'z' 7 */ + "ž\x00" "\x04" /* 'ž' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ǧ\x00" "\x04" /* 'Ǧ' 4 */ + "H\x00" "\x07" /* 'H' 7 */ + "Ȟ\x00" "\x04" /* 'Ȟ' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ě\x00" "\x04" /* 'Ě' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Š\x00" "\x04" /* 'Š' 4 */ + "d\x00" "\x07" /* 'd' 7 */ + "ď\x00" "\x04" /* 'ď' 4 */ + "D\x00" "\x07" /* 'D' 7 */ + "Ď\x00" "\x04" /* 'Ď' 4 */ + "quotedbl\x00" "\x18" /* 'quotedbl' 24 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǚ\x00" "\x04" /* 'ǚ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǚ\x00" "\x04" /* 'Ǚ' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ć\x00" "\x04" /* 'ć' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǒ\x00" "\x04" /* 'Ǒ' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ř\x00" "\x04" /* 'ř' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "š\x00" "\x04" /* 'š' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ž\x00" "\x04" /* 'Ž' 4 */ + "bar\x00" "\x09" /* 'bar' 9 */ + "¢\x00" "\x04" /* '¢' 4 */ + "EZH\x00" "\x09" /* 'EZH' 9 */ + "Ǯ\x00" "\x04" /* 'Ǯ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǎ\x00" "\x04" /* 'Ǎ' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ř\x00" "\x04" /* 'Ř' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "č\x00" "\x04" /* 'č' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ľ\x00" "\x04" /* 'Ľ' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "ç\x00" "\x04" /* 'ç' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ť\x00" "\x04" /* 'Ť' 4 */ + "slash\x00" "\x0b" /* 'slash' 11 */ + "¢\x00" "\x04" /* '¢' 4 */ + "K\x00" "\x07" /* 'K' 7 */ + "Ǩ\x00" "\x04" /* 'Ǩ' 4 */ + "dead_diaeresis\x00" "\x1e" /* 'dead_diaeresis' 30 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǚ\x00" "\x04" /* 'ǚ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǚ\x00" "\x04" /* 'Ǚ' 4 */ + "h\x00" "\x07" /* 'h' 7 */ + "ȟ\x00" "\x04" /* 'ȟ' 4 */ + "udiaeresis\x00" "\x10" /* 'udiaeresis' 16 */ + "ǚ\x00" "\x04" /* 'ǚ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ǐ\x00" "\x04" /* 'Ǐ' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ň\x00" "\x04" /* 'Ň' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǔ\x00" "\x04" /* 'Ǔ' 4 */ + "numbersign\x00" "\x4d" /* 'numbersign' 77 */ + "e\x00" "\x08" /* 'e' 8 */ + "♪\x00" "\x05" /* '♪' 5 */ + "b\x00" "\x08" /* 'b' 8 */ + "♭\x00" "\x05" /* '♭' 5 */ + "q\x00" "\x08" /* 'q' 8 */ + "♩\x00" "\x05" /* '♩' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "♫\x00" "\x05" /* '♫' 5 */ + "S\x00" "\x08" /* 'S' 8 */ + "♬\x00" "\x05" /* '♬' 5 */ + "f\x00" "\x08" /* 'f' 8 */ + "♮\x00" "\x05" /* '♮' 5 */ + "numbersign\x00" "\x11" /* 'numbersign' 17 */ + "♯\x00" "\x05" /* '♯' 5 */ + "L\x00" "\x50" /* 'L' 80 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "£\x00" "\x04" /* '£' 4 */ + "less\x00" "\x0a" /* 'less' 10 */ + "Ľ\x00" "\x04" /* 'Ľ' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "₤\x00" "\x05" /* '₤' 5 */ + "V\x00" "\x06" /* 'V' 6 */ + "|\x00" "\x03" /* '|' 3 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ĺ\x00" "\x04" /* 'Ĺ' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ļ\x00" "\x04" /* 'Ļ' 4 */ + "slash\x00" "\x0b" /* 'slash' 11 */ + "Ł\x00" "\x04" /* 'Ł' 4 */ + "Greek_EPSILON\x00" "\x1f" /* 'Greek_EPSILON' 31 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Έ\x00" "\x04" /* 'Έ' 4 */ + "comma\x00" "\x81\x11" /* 'comma' 273 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "¬\x00" "\x04" /* '¬' 4 */ + "g\x00" "\x07" /* 'g' 7 */ + "ģ\x00" "\x04" /* 'ģ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "ą\x00" "\x04" /* 'ą' 4 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ç\x00" "\x04" /* 'Ç' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ę\x00" "\x04" /* 'ę' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ļ\x00" "\x04" /* 'ļ' 4 */ + "t\x00" "\x07" /* 't' 7 */ + "ţ\x00" "\x04" /* 'ţ' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + "¸\x00" "\x04" /* '¸' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "į\x00" "\x04" /* 'į' 4 */ + "k\x00" "\x07" /* 'k' 7 */ + "ķ\x00" "\x04" /* 'ķ' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ņ\x00" "\x04" /* 'ņ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ų\x00" "\x04" /* 'ų' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ģ\x00" "\x04" /* 'Ģ' 4 */ + "H\x00" "\x08" /* 'H' 8 */ + "Ḩ\x00" "\x05" /* 'Ḩ' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ę\x00" "\x04" /* 'Ę' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Ş\x00" "\x04" /* 'Ş' 4 */ + "d\x00" "\x08" /* 'd' 8 */ + "ḑ\x00" "\x05" /* 'ḑ' 5 */ + "D\x00" "\x08" /* 'D' 8 */ + "Ḑ\x00" "\x05" /* 'Ḑ' 5 */ + "quotedbl\x00" "\x0f" /* 'quotedbl' 15 */ + "„\x00" "\x05" /* '„' 5 */ + "apostrophe\x00" "\x11" /* 'apostrophe' 17 */ + "‚\x00" "\x05" /* '‚' 5 */ + "r\x00" "\x07" /* 'r' 7 */ + "ŗ\x00" "\x04" /* 'ŗ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ş\x00" "\x04" /* 'ş' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ą\x00" "\x04" /* 'Ą' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ŗ\x00" "\x04" /* 'Ŗ' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "ç\x00" "\x04" /* 'ç' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ļ\x00" "\x04" /* 'Ļ' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "¸\x00" "\x04" /* '¸' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ţ\x00" "\x04" /* 'Ţ' 4 */ + "K\x00" "\x07" /* 'K' 7 */ + "Ķ\x00" "\x04" /* 'Ķ' 4 */ + "h\x00" "\x08" /* 'h' 8 */ + "ḩ\x00" "\x05" /* 'ḩ' 5 */ + "I\x00" "\x07" /* 'I' 7 */ + "Į\x00" "\x04" /* 'Į' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ņ\x00" "\x04" /* 'Ņ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ų\x00" "\x04" /* 'Ų' 4 */ + "T\x00" "\x52" /* 'T' 82 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "Ŧ\x00" "\x04" /* 'Ŧ' 4 */ + "period\x00" "\x0d" /* 'period' 13 */ + "Ṫ\x00" "\x05" /* 'Ṫ' 5 */ + "less\x00" "\x0a" /* 'less' 10 */ + "Ť\x00" "\x04" /* 'Ť' 4 */ + "H\x00" "\x07" /* 'H' 7 */ + "Þ\x00" "\x04" /* 'Þ' 4 */ + "M\x00" "\x08" /* 'M' 8 */ + "™\x00" "\x05" /* '™' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "™\x00" "\x05" /* '™' 5 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ţ\x00" "\x04" /* 'Ţ' 4 */ + "slash\x00" "\x0b" /* 'slash' 11 */ + "Ŧ\x00" "\x04" /* 'Ŧ' 4 */ + "asciitilde\x00" "\x86\x28" /* 'asciitilde' 1576 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẵ\x00" "\x05" /* 'ẵ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẵ\x00" "\x05" /* 'Ẵ' 5 */ + "a\x00" "\x07" /* 'a' 7 */ + "ã\x00" "\x04" /* 'ã' 4 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῖ\x00" "\x05" /* 'ῖ' 5 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỡ\x00" "\x05" /* 'ỡ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ữ\x00" "\x05" /* 'ữ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỡ\x00" "\x05" /* 'Ỡ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ữ\x00" "\x05" /* 'Ữ' 5 */ + "dead_circumflex\x00" "\x41" /* 'dead_circumflex' 65 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẫ\x00" "\x05" /* 'ẫ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ễ\x00" "\x05" /* 'ễ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỗ\x00" "\x05" /* 'ỗ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ễ\x00" "\x05" /* 'Ễ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỗ\x00" "\x05" /* 'Ỗ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẫ\x00" "\x05" /* 'Ẫ' 5 */ + "Acircumflex\x00" "\x12" /* 'Acircumflex' 18 */ + "Ẫ\x00" "\x05" /* 'Ẫ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ẽ\x00" "\x05" /* 'ẽ' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "õ\x00" "\x04" /* 'õ' 4 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῦ\x00" "\x05" /* 'ῦ' 5 */ + "diaeresis\x00" "\x10" /* 'diaeresis' 16 */ + "⍨\x00" "\x05" /* '⍨' 5 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ữ\x00" "\x05" /* 'ữ' 5 */ + "space\x00" "\x0a" /* 'space' 10 */ + "~\x00" "\x03" /* '~' 3 */ + "acircumflex\x00" "\x12" /* 'acircumflex' 18 */ + "ẫ\x00" "\x05" /* 'ẫ' 5 */ + "Ecircumflex\x00" "\x12" /* 'Ecircumflex' 18 */ + "Ễ\x00" "\x05" /* 'Ễ' 5 */ + "y\x00" "\x08" /* 'y' 8 */ + "ỹ\x00" "\x05" /* 'ỹ' 5 */ + "b\x00" "\x13" /* 'b' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẵ\x00" "\x05" /* 'ẵ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẵ\x00" "\x05" /* 'Ẵ' 5 */ + "i\x00" "\x07" /* 'i' 7 */ + "ĩ\x00" "\x04" /* 'ĩ' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ñ\x00" "\x04" /* 'ñ' 4 */ + "parenright\x00" "\x80\xab" /* 'parenright' 171 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἶ\x00" "\x05" /* 'Ἶ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἶ\x00" "\x05" /* 'ἶ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὖ\x00" "\x05" /* 'ὖ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἆ\x00" "\x05" /* 'Ἆ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἦ\x00" "\x05" /* 'ἦ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἆ\x00" "\x05" /* 'ἆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἦ\x00" "\x05" /* 'Ἦ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὦ\x00" "\x05" /* 'ὦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὦ\x00" "\x05" /* 'Ὦ' 5 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ỡ\x00" "\x05" /* 'Ỡ' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ỡ\x00" "\x05" /* 'ỡ' 5 */ + "Ocircumflex\x00" "\x12" /* 'Ocircumflex' 18 */ + "Ỗ\x00" "\x05" /* 'Ỗ' 5 */ + "V\x00" "\x08" /* 'V' 8 */ + "Ṽ\x00" "\x05" /* 'Ṽ' 5 */ + "ocircumflex\x00" "\x12" /* 'ocircumflex' 18 */ + "ỗ\x00" "\x05" /* 'ỗ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ũ\x00" "\x04" /* 'ũ' 4 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ẽ\x00" "\x05" /* 'Ẽ' 5 */ + "Greek_iotadieresis\x00" "\x19" /* 'Greek_iotadieresis' 25 */ + "ῗ\x00" "\x05" /* 'ῗ' 5 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "Ỹ\x00" "\x05" /* 'Ỹ' 5 */ + "dead_dasia\x00" "\x80\xbf" /* 'dead_dasia' 191 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἷ\x00" "\x05" /* 'Ἷ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἷ\x00" "\x05" /* 'ἷ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὗ\x00" "\x05" /* 'ὗ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἇ\x00" "\x05" /* 'Ἇ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἧ\x00" "\x05" /* 'ἧ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἇ\x00" "\x05" /* 'ἇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἧ\x00" "\x05" /* 'Ἧ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὧ\x00" "\x05" /* 'ὧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὧ\x00" "\x05" /* 'Ὧ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὗ\x00" "\x05" /* 'Ὗ' 5 */ + "Greek_upsilondieresis\x00" "\x1c" /* 'Greek_upsilondieresis' 28 */ + "ῧ\x00" "\x05" /* 'ῧ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῆ\x00" "\x05" /* 'ῆ' 5 */ + "Abreve\x00" "\x0d" /* 'Abreve' 13 */ + "Ẵ\x00" "\x05" /* 'Ẵ' 5 */ + "dead_psili\x00" "\x80\xab" /* 'dead_psili' 171 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἶ\x00" "\x05" /* 'Ἶ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἶ\x00" "\x05" /* 'ἶ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὖ\x00" "\x05" /* 'ὖ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἆ\x00" "\x05" /* 'Ἆ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἦ\x00" "\x05" /* 'ἦ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἆ\x00" "\x05" /* 'ἆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἦ\x00" "\x05" /* 'Ἦ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὦ\x00" "\x05" /* 'ὦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὦ\x00" "\x05" /* 'Ὦ' 5 */ + "quotedbl\x00" "\x2f" /* 'quotedbl' 47 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῗ\x00" "\x05" /* 'ῗ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῧ\x00" "\x05" /* 'ῧ' 5 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỡ\x00" "\x05" /* 'ỡ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ữ\x00" "\x05" /* 'ữ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỡ\x00" "\x05" /* 'Ỡ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ữ\x00" "\x05" /* 'Ữ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾶ\x00" "\x05" /* 'ᾶ' 5 */ + "ecircumflex\x00" "\x12" /* 'ecircumflex' 18 */ + "ễ\x00" "\x05" /* 'ễ' 5 */ + "v\x00" "\x08" /* 'v' 8 */ + "ṽ\x00" "\x05" /* 'ṽ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Õ\x00" "\x04" /* 'Õ' 4 */ + "abreve\x00" "\x0d" /* 'abreve' 13 */ + "ẵ\x00" "\x05" /* 'ẵ' 5 */ + "bar\x00" "\x0a" /* 'bar' 10 */ + "⍭\x00" "\x05" /* '⍭' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ã\x00" "\x04" /* 'Ã' 4 */ + "0\x00" "\x08" /* '0' 8 */ + "⍬\x00" "\x05" /* '⍬' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῶ\x00" "\x05" /* 'ῶ' 5 */ + "dead_diaeresis\x00" "\x35" /* 'dead_diaeresis' 53 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῗ\x00" "\x05" /* 'ῗ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῧ\x00" "\x05" /* 'ῧ' 5 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ữ\x00" "\x05" /* 'Ữ' 5 */ + "parenleft\x00" "\x80\xbe" /* 'parenleft' 190 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἷ\x00" "\x05" /* 'Ἷ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἷ\x00" "\x05" /* 'ἷ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὗ\x00" "\x05" /* 'ὗ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἇ\x00" "\x05" /* 'Ἇ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἧ\x00" "\x05" /* 'ἧ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἇ\x00" "\x05" /* 'ἇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἧ\x00" "\x05" /* 'Ἧ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὧ\x00" "\x05" /* 'ὧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὧ\x00" "\x05" /* 'Ὧ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὗ\x00" "\x05" /* 'Ὗ' 5 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ĩ\x00" "\x04" /* 'Ĩ' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ñ\x00" "\x04" /* 'Ñ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ũ\x00" "\x04" /* 'Ũ' 4 */ + "asciicircum\x00" "\x3d" /* 'asciicircum' 61 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẫ\x00" "\x05" /* 'ẫ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ễ\x00" "\x05" /* 'ễ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỗ\x00" "\x05" /* 'ỗ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ễ\x00" "\x05" /* 'Ễ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỗ\x00" "\x05" /* 'Ỗ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẫ\x00" "\x05" /* 'Ẫ' 5 */ + "slash\x00" "\x81\x47" /* 'slash' 327 */ + "minus\x00" "\x0c" /* 'minus' 12 */ + "⌿\x00" "\x05" /* '⌿' 5 */ + "g\x00" "\x07" /* 'g' 7 */ + "ǥ\x00" "\x04" /* 'ǥ' 4 */ + "C\x00" "\x08" /* 'C' 8 */ + "₡\x00" "\x05" /* '₡' 5 */ + "less\x00" "\x09" /* 'less' 9 */ + "\\\x00" "\x03" /* '\' 3 */ + "o\x00" "\x07" /* 'o' 7 */ + "ø\x00" "\x04" /* 'ø' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ł\x00" "\x04" /* 'ł' 4 */ + "t\x00" "\x07" /* 't' 7 */ + "ŧ\x00" "\x04" /* 'ŧ' 4 */ + "b\x00" "\x07" /* 'b' 7 */ + "ƀ\x00" "\x04" /* 'ƀ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ɨ\x00" "\x04" /* 'ɨ' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "≠\x00" "\x05" /* '≠' 5 */ + "Cyrillic_GHE\x00" "\x12" /* 'Cyrillic_GHE' 18 */ + "Ғ\x00" "\x04" /* 'Ғ' 4 */ + "leftarrow\x00" "\x10" /* 'leftarrow' 16 */ + "↚\x00" "\x05" /* '↚' 5 */ + "Cyrillic_KA\x00" "\x11" /* 'Cyrillic_KA' 17 */ + "Ҟ\x00" "\x04" /* 'Ҟ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "µ\x00" "\x04" /* 'µ' 4 */ + "rightarrow\x00" "\x11" /* 'rightarrow' 17 */ + "↛\x00" "\x05" /* '↛' 5 */ + "z\x00" "\x07" /* 'z' 7 */ + "ƶ\x00" "\x04" /* 'ƶ' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ǥ\x00" "\x04" /* 'Ǥ' 4 */ + "H\x00" "\x07" /* 'H' 7 */ + "Ħ\x00" "\x04" /* 'Ħ' 4 */ + "d\x00" "\x07" /* 'd' 7 */ + "đ\x00" "\x04" /* 'đ' 4 */ + "Cyrillic_ka\x00" "\x11" /* 'Cyrillic_ka' 17 */ + "ҟ\x00" "\x04" /* 'ҟ' 4 */ + "D\x00" "\x07" /* 'D' 7 */ + "Đ\x00" "\x04" /* 'Đ' 4 */ + "v\x00" "\x08" /* 'v' 8 */ + "√\x00" "\x05" /* '√' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ø\x00" "\x04" /* 'Ø' 4 */ + "m\x00" "\x08" /* 'm' 8 */ + "₥\x00" "\x05" /* '₥' 5 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ƶ\x00" "\x04" /* 'Ƶ' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "¢\x00" "\x04" /* '¢' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ł\x00" "\x04" /* 'Ł' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ŧ\x00" "\x04" /* 'Ŧ' 4 */ + "slash\x00" "\x0a" /* 'slash' 10 */ + "\\\x00" "\x03" /* '\' 3 */ + "Cyrillic_ghe\x00" "\x12" /* 'Cyrillic_ghe' 18 */ + "ғ\x00" "\x04" /* 'ғ' 4 */ + "h\x00" "\x07" /* 'h' 7 */ + "ħ\x00" "\x04" /* 'ħ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ɨ\x00" "\x04" /* 'Ɨ' 4 */ + "asciicircum\x00" "\x10" /* 'asciicircum' 16 */ + "|\x00" "\x03" /* '|' 3 */ + "5\x00" "\x13" /* '5' 19 */ + "8\x00" "\x08" /* '8' 8 */ + "⅝\x00" "\x05" /* '⅝' 5 */ + "6\x00" "\x08" /* '6' 8 */ + "⅚\x00" "\x05" /* '⅚' 5 */ + "Cyrillic_EN\x00" "\x2f" /* 'Cyrillic_EN' 47 */ + "Cyrillic_O\x00" "\x11" /* 'Cyrillic_O' 17 */ + "№\x00" "\x05" /* '№' 5 */ + "Cyrillic_o\x00" "\x11" /* 'Cyrillic_o' 17 */ + "№\x00" "\x05" /* '№' 5 */ + "greater\x00" "\x80\xbf" /* 'greater' 191 */ + "a\x00" "\x07" /* 'a' 7 */ + "â\x00" "\x04" /* 'â' 4 */ + "less\x00" "\x0b" /* 'less' 11 */ + "⋄\x00" "\x05" /* '⋄' 5 */ + "e\x00" "\x07" /* 'e' 7 */ + "ê\x00" "\x04" /* 'ê' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ô\x00" "\x04" /* 'ô' 4 */ + "diaeresis\x00" "\x10" /* 'diaeresis' 16 */ + "⍩\x00" "\x05" /* '⍩' 5 */ + "space\x00" "\x0a" /* 'space' 10 */ + "^\x00" "\x03" /* '^' 3 */ + "i\x00" "\x07" /* 'i' 7 */ + "î\x00" "\x04" /* 'î' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "≥\x00" "\x05" /* '≥' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "û\x00" "\x04" /* 'û' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ê\x00" "\x04" /* 'Ê' 4 */ + "quotedbl\x00" "\x0f" /* 'quotedbl' 15 */ + "”\x00" "\x05" /* '”' 5 */ + "underscore\x00" "\x11" /* 'underscore' 17 */ + "≥\x00" "\x05" /* '≥' 5 */ + "apostrophe\x00" "\x11" /* 'apostrophe' 17 */ + "’\x00" "\x05" /* '’' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ô\x00" "\x04" /* 'Ô' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Â\x00" "\x04" /* 'Â' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "»\x00" "\x04" /* '»' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Î\x00" "\x04" /* 'Î' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Û\x00" "\x04" /* 'Û' 4 */ + "semicolon\x00" "\x62" /* 'semicolon' 98 */ + "a\x00" "\x07" /* 'a' 7 */ + "ą\x00" "\x04" /* 'ą' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ę\x00" "\x04" /* 'ę' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǫ\x00" "\x04" /* 'ǫ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "į\x00" "\x04" /* 'į' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ų\x00" "\x04" /* 'ų' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ę\x00" "\x04" /* 'Ę' 4 */ + "underscore\x00" "\x11" /* 'underscore' 17 */ + "⍮\x00" "\x05" /* '⍮' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǫ\x00" "\x04" /* 'Ǫ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ą\x00" "\x04" /* 'Ą' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Į\x00" "\x04" /* 'Į' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ų\x00" "\x04" /* 'Ų' 4 */ + "K\x00" "\x0e" /* 'K' 14 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ķ\x00" "\x04" /* 'Ķ' 4 */ + "Cyrillic_IE\x00" "\x19" /* 'Cyrillic_IE' 25 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "€\x00" "\x05" /* '€' 5 */ + "B\x00" "\x10" /* 'B' 16 */ + "period\x00" "\x0d" /* 'period' 13 */ + "Ḃ\x00" "\x05" /* 'Ḃ' 5 */ + "0\x00" "\x2a" /* '0' 42 */ + "3\x00" "\x08" /* '3' 8 */ + "↉\x00" "\x05" /* '↉' 5 */ + "asterisk\x00" "\x0e" /* 'asterisk' 14 */ + "°\x00" "\x04" /* '°' 4 */ + "asciitilde\x00" "\x11" /* 'asciitilde' 17 */ + "⍬\x00" "\x05" /* '⍬' 5 */ + "Greek_omega\x00" "\x1d" /* 'Greek_omega' 29 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "ώ\x00" "\x04" /* 'ώ' 4 */ + "Greek_OMEGA\x00" "\x1d" /* 'Greek_OMEGA' 29 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ώ\x00" "\x04" /* 'Ώ' 4 */ + "X\x00" "\x11" /* 'X' 17 */ + "o\x00" "\x07" /* 'o' 7 */ + "¤\x00" "\x04" /* '¤' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "¤\x00" "\x04" /* '¤' 4 */ + "parenleft\x00" "\x9c\x2a" /* 'parenleft' 7210 */ + "minus\x00" "\x0a" /* 'minus' 10 */ + "{\x00" "\x03" /* '{' 3 */ + "W\x00" "\x14" /* 'W' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓦ\x00" "\x05" /* 'Ⓦ' 5 */ + "g\x00" "\x14" /* 'g' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓖ\x00" "\x05" /* 'ⓖ' 5 */ + "kana_KE\x00" "\x1a" /* 'kana_KE' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋘\x00" "\x05" /* '㋘' 5 */ + "a\x00" "\x14" /* 'a' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓐ\x00" "\x05" /* 'ⓐ' 5 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἱ\x00" "\x05" /* 'Ἱ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἱ\x00" "\x05" /* 'ἱ' 5 */ + "1\x00" "\x81\xde" /* '1' 478 */ + "1\x00" "\x14" /* '1' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑪\x00" "\x05" /* '⑪' 5 */ + "KP_4\x00" "\x17" /* 'KP_4' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑭\x00" "\x05" /* '⑭' 5 */ + "KP_6\x00" "\x17" /* 'KP_6' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑯\x00" "\x05" /* '⑯' 5 */ + "KP_8\x00" "\x17" /* 'KP_8' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑱\x00" "\x05" /* '⑱' 5 */ + "KP_9\x00" "\x17" /* 'KP_9' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑲\x00" "\x05" /* '⑲' 5 */ + "KP_Space\x00" "\x1b" /* 'KP_Space' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑫\x00" "\x05" /* '⑫' 5 */ + "7\x00" "\x14" /* '7' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑰\x00" "\x05" /* '⑰' 5 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "①\x00" "\x05" /* '①' 5 */ + "KP_7\x00" "\x17" /* 'KP_7' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑰\x00" "\x05" /* '⑰' 5 */ + "8\x00" "\x14" /* '8' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑱\x00" "\x05" /* '⑱' 5 */ + "KP_1\x00" "\x17" /* 'KP_1' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑪\x00" "\x05" /* '⑪' 5 */ + "3\x00" "\x14" /* '3' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑬\x00" "\x05" /* '⑬' 5 */ + "2\x00" "\x14" /* '2' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑫\x00" "\x05" /* '⑫' 5 */ + "6\x00" "\x14" /* '6' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑯\x00" "\x05" /* '⑯' 5 */ + "4\x00" "\x14" /* '4' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑭\x00" "\x05" /* '⑭' 5 */ + "KP_3\x00" "\x17" /* 'KP_3' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑬\x00" "\x05" /* '⑬' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑩\x00" "\x05" /* '⑩' 5 */ + "KP_2\x00" "\x17" /* 'KP_2' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑫\x00" "\x05" /* '⑫' 5 */ + "5\x00" "\x14" /* '5' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑮\x00" "\x05" /* '⑮' 5 */ + "KP_5\x00" "\x17" /* 'KP_5' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑮\x00" "\x05" /* '⑮' 5 */ + "9\x00" "\x14" /* '9' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑲\x00" "\x05" /* '⑲' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑩\x00" "\x05" /* '⑩' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὁ\x00" "\x05" /* 'Ὁ' 5 */ + "C\x00" "\x14" /* 'C' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓒ\x00" "\x05" /* 'Ⓒ' 5 */ + "KP_4\x00" "\x81\xe1" /* 'KP_4' 481 */ + "1\x00" "\x14" /* '1' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊶\x00" "\x05" /* '㊶' 5 */ + "KP_4\x00" "\x17" /* 'KP_4' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊹\x00" "\x05" /* '㊹' 5 */ + "KP_6\x00" "\x17" /* 'KP_6' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊻\x00" "\x05" /* '㊻' 5 */ + "KP_8\x00" "\x17" /* 'KP_8' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊽\x00" "\x05" /* '㊽' 5 */ + "KP_9\x00" "\x17" /* 'KP_9' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊾\x00" "\x05" /* '㊾' 5 */ + "KP_Space\x00" "\x1b" /* 'KP_Space' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊷\x00" "\x05" /* '㊷' 5 */ + "7\x00" "\x14" /* '7' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊼\x00" "\x05" /* '㊼' 5 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "④\x00" "\x05" /* '④' 5 */ + "KP_7\x00" "\x17" /* 'KP_7' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊼\x00" "\x05" /* '㊼' 5 */ + "8\x00" "\x14" /* '8' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊽\x00" "\x05" /* '㊽' 5 */ + "KP_1\x00" "\x17" /* 'KP_1' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊶\x00" "\x05" /* '㊶' 5 */ + "3\x00" "\x14" /* '3' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊸\x00" "\x05" /* '㊸' 5 */ + "2\x00" "\x14" /* '2' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊷\x00" "\x05" /* '㊷' 5 */ + "6\x00" "\x14" /* '6' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊻\x00" "\x05" /* '㊻' 5 */ + "4\x00" "\x14" /* '4' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊹\x00" "\x05" /* '㊹' 5 */ + "KP_3\x00" "\x17" /* 'KP_3' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊸\x00" "\x05" /* '㊸' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊵\x00" "\x05" /* '㊵' 5 */ + "KP_2\x00" "\x17" /* 'KP_2' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊷\x00" "\x05" /* '㊷' 5 */ + "5\x00" "\x14" /* '5' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊺\x00" "\x05" /* '㊺' 5 */ + "KP_5\x00" "\x17" /* 'KP_5' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊺\x00" "\x05" /* '㊺' 5 */ + "9\x00" "\x14" /* '9' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊾\x00" "\x05" /* '㊾' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊵\x00" "\x05" /* '㊵' 5 */ + "kana_SA\x00" "\x1a" /* 'kana_SA' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋚\x00" "\x05" /* '㋚' 5 */ + "e\x00" "\x14" /* 'e' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓔ\x00" "\x05" /* 'ⓔ' 5 */ + "F\x00" "\x14" /* 'F' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓕ\x00" "\x05" /* 'Ⓕ' 5 */ + "KP_6\x00" "\x17" /* 'KP_6' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑥\x00" "\x05" /* '⑥' 5 */ + "o\x00" "\x14" /* 'o' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓞ\x00" "\x05" /* 'ⓞ' 5 */ + "l\x00" "\x14" /* 'l' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓛ\x00" "\x05" /* 'ⓛ' 5 */ + "kana_SE\x00" "\x1a" /* 'kana_SE' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋝\x00" "\x05" /* '㋝' 5 */ + "kana_SU\x00" "\x1a" /* 'kana_SU' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋜\x00" "\x05" /* '㋜' 5 */ + "t\x00" "\x14" /* 't' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓣ\x00" "\x05" /* 'ⓣ' 5 */ + "kana_ME\x00" "\x1a" /* 'kana_ME' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋱\x00" "\x05" /* '㋱' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὑ\x00" "\x05" /* 'ὑ' 5 */ + "kana_WO\x00" "\x1a" /* 'kana_WO' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋾\x00" "\x05" /* '㋾' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "˘\x00" "\x04" /* '˘' 4 */ + "KP_8\x00" "\x17" /* 'KP_8' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑧\x00" "\x05" /* '⑧' 5 */ + "Greek_RHO\x00" "\x10" /* 'Greek_RHO' 16 */ + "Ῥ\x00" "\x05" /* 'Ῥ' 5 */ + "Q\x00" "\x14" /* 'Q' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓠ\x00" "\x05" /* 'Ⓠ' 5 */ + "y\x00" "\x14" /* 'y' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓨ\x00" "\x05" /* 'ⓨ' 5 */ + "b\x00" "\x14" /* 'b' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓑ\x00" "\x05" /* 'ⓑ' 5 */ + "kana_YO\x00" "\x1a" /* 'kana_YO' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋵\x00" "\x05" /* '㋵' 5 */ + "i\x00" "\x14" /* 'i' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓘ\x00" "\x05" /* 'ⓘ' 5 */ + "kana_MA\x00" "\x1a" /* 'kana_MA' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋮\x00" "\x05" /* '㋮' 5 */ + "k\x00" "\x14" /* 'k' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓚ\x00" "\x05" /* 'ⓚ' 5 */ + "n\x00" "\x14" /* 'n' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓝ\x00" "\x05" /* 'ⓝ' 5 */ + "KP_9\x00" "\x17" /* 'KP_9' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑨\x00" "\x05" /* '⑨' 5 */ + "KP_Space\x00" "\x81\xe5" /* 'KP_Space' 485 */ + "1\x00" "\x14" /* '1' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉑\x00" "\x05" /* '㉑' 5 */ + "KP_4\x00" "\x17" /* 'KP_4' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉔\x00" "\x05" /* '㉔' 5 */ + "KP_6\x00" "\x17" /* 'KP_6' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉖\x00" "\x05" /* '㉖' 5 */ + "KP_8\x00" "\x17" /* 'KP_8' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉘\x00" "\x05" /* '㉘' 5 */ + "KP_9\x00" "\x17" /* 'KP_9' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉙\x00" "\x05" /* '㉙' 5 */ + "KP_Space\x00" "\x1b" /* 'KP_Space' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉒\x00" "\x05" /* '㉒' 5 */ + "7\x00" "\x14" /* '7' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉗\x00" "\x05" /* '㉗' 5 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "②\x00" "\x05" /* '②' 5 */ + "KP_7\x00" "\x17" /* 'KP_7' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉗\x00" "\x05" /* '㉗' 5 */ + "8\x00" "\x14" /* '8' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉘\x00" "\x05" /* '㉘' 5 */ + "KP_1\x00" "\x17" /* 'KP_1' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉑\x00" "\x05" /* '㉑' 5 */ + "3\x00" "\x14" /* '3' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉓\x00" "\x05" /* '㉓' 5 */ + "2\x00" "\x14" /* '2' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉒\x00" "\x05" /* '㉒' 5 */ + "6\x00" "\x14" /* '6' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉖\x00" "\x05" /* '㉖' 5 */ + "4\x00" "\x14" /* '4' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉔\x00" "\x05" /* '㉔' 5 */ + "KP_3\x00" "\x17" /* 'KP_3' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉓\x00" "\x05" /* '㉓' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑳\x00" "\x05" /* '⑳' 5 */ + "KP_2\x00" "\x17" /* 'KP_2' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉒\x00" "\x05" /* '㉒' 5 */ + "5\x00" "\x14" /* '5' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉕\x00" "\x05" /* '㉕' 5 */ + "KP_5\x00" "\x17" /* 'KP_5' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉕\x00" "\x05" /* '㉕' 5 */ + "9\x00" "\x14" /* '9' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉙\x00" "\x05" /* '㉙' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑳\x00" "\x05" /* '⑳' 5 */ + "kana_YU\x00" "\x1a" /* 'kana_YU' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋴\x00" "\x05" /* '㋴' 5 */ + "kana_TE\x00" "\x1a" /* 'kana_TE' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋢\x00" "\x05" /* '㋢' 5 */ + "7\x00" "\x14" /* '7' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑦\x00" "\x05" /* '⑦' 5 */ + "kana_NU\x00" "\x1a" /* 'kana_NU' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋦\x00" "\x05" /* '㋦' 5 */ + "kana_HO\x00" "\x1a" /* 'kana_HO' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋭\x00" "\x05" /* '㋭' 5 */ + "kana_HI\x00" "\x1a" /* 'kana_HI' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋪\x00" "\x05" /* '㋪' 5 */ + "j\x00" "\x14" /* 'j' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓙ\x00" "\x05" /* 'ⓙ' 5 */ + "kana_E\x00" "\x19" /* 'kana_E' 25 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋓\x00" "\x05" /* '㋓' 5 */ + "x\x00" "\x14" /* 'x' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓧ\x00" "\x05" /* 'ⓧ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἑ\x00" "\x05" /* 'ἑ' 5 */ + "q\x00" "\x14" /* 'q' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓠ\x00" "\x05" /* 'ⓠ' 5 */ + "KP_7\x00" "\x17" /* 'KP_7' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑦\x00" "\x05" /* '⑦' 5 */ + "kana_I\x00" "\x19" /* 'kana_I' 25 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋑\x00" "\x05" /* '㋑' 5 */ + "kana_WA\x00" "\x1a" /* 'kana_WA' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋻\x00" "\x05" /* '㋻' 5 */ + "kana_RU\x00" "\x1a" /* 'kana_RU' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋸\x00" "\x05" /* '㋸' 5 */ + "V\x00" "\x14" /* 'V' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓥ\x00" "\x05" /* 'Ⓥ' 5 */ + "u\x00" "\x14" /* 'u' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓤ\x00" "\x05" /* 'ⓤ' 5 */ + "kana_NI\x00" "\x1a" /* 'kana_NI' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋥\x00" "\x05" /* '㋥' 5 */ + "kana_MU\x00" "\x1a" /* 'kana_MU' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋰\x00" "\x05" /* '㋰' 5 */ + "kana_CHI\x00" "\x1b" /* 'kana_CHI' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋠\x00" "\x05" /* '㋠' 5 */ + "kana_HA\x00" "\x1a" /* 'kana_HA' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋩\x00" "\x05" /* '㋩' 5 */ + "z\x00" "\x14" /* 'z' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓩ\x00" "\x05" /* 'ⓩ' 5 */ + "G\x00" "\x14" /* 'G' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓖ\x00" "\x05" /* 'Ⓖ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἁ\x00" "\x05" /* 'Ἁ' 5 */ + "H\x00" "\x14" /* 'H' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓗ\x00" "\x05" /* 'Ⓗ' 5 */ + "8\x00" "\x14" /* '8' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑧\x00" "\x05" /* '⑧' 5 */ + "KP_1\x00" "\x81\xe1" /* 'KP_1' 481 */ + "1\x00" "\x14" /* '1' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑪\x00" "\x05" /* '⑪' 5 */ + "KP_4\x00" "\x17" /* 'KP_4' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑭\x00" "\x05" /* '⑭' 5 */ + "KP_6\x00" "\x17" /* 'KP_6' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑯\x00" "\x05" /* '⑯' 5 */ + "KP_8\x00" "\x17" /* 'KP_8' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑱\x00" "\x05" /* '⑱' 5 */ + "KP_9\x00" "\x17" /* 'KP_9' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑲\x00" "\x05" /* '⑲' 5 */ + "KP_Space\x00" "\x1b" /* 'KP_Space' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑫\x00" "\x05" /* '⑫' 5 */ + "7\x00" "\x14" /* '7' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑰\x00" "\x05" /* '⑰' 5 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "①\x00" "\x05" /* '①' 5 */ + "KP_7\x00" "\x17" /* 'KP_7' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑰\x00" "\x05" /* '⑰' 5 */ + "8\x00" "\x14" /* '8' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑱\x00" "\x05" /* '⑱' 5 */ + "KP_1\x00" "\x17" /* 'KP_1' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑪\x00" "\x05" /* '⑪' 5 */ + "3\x00" "\x14" /* '3' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑬\x00" "\x05" /* '⑬' 5 */ + "2\x00" "\x14" /* '2' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑫\x00" "\x05" /* '⑫' 5 */ + "6\x00" "\x14" /* '6' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑯\x00" "\x05" /* '⑯' 5 */ + "4\x00" "\x14" /* '4' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑭\x00" "\x05" /* '⑭' 5 */ + "KP_3\x00" "\x17" /* 'KP_3' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑬\x00" "\x05" /* '⑬' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑩\x00" "\x05" /* '⑩' 5 */ + "KP_2\x00" "\x17" /* 'KP_2' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑫\x00" "\x05" /* '⑫' 5 */ + "5\x00" "\x14" /* '5' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑮\x00" "\x05" /* '⑮' 5 */ + "KP_5\x00" "\x17" /* 'KP_5' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑮\x00" "\x05" /* '⑮' 5 */ + "9\x00" "\x14" /* '9' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑲\x00" "\x05" /* '⑲' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑩\x00" "\x05" /* '⑩' 5 */ + "3\x00" "\x81\xde" /* '3' 478 */ + "1\x00" "\x14" /* '1' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉛\x00" "\x05" /* '㉛' 5 */ + "KP_4\x00" "\x17" /* 'KP_4' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉞\x00" "\x05" /* '㉞' 5 */ + "KP_6\x00" "\x17" /* 'KP_6' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊱\x00" "\x05" /* '㊱' 5 */ + "KP_8\x00" "\x17" /* 'KP_8' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊳\x00" "\x05" /* '㊳' 5 */ + "KP_9\x00" "\x17" /* 'KP_9' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊴\x00" "\x05" /* '㊴' 5 */ + "KP_Space\x00" "\x1b" /* 'KP_Space' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉜\x00" "\x05" /* '㉜' 5 */ + "7\x00" "\x14" /* '7' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊲\x00" "\x05" /* '㊲' 5 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "③\x00" "\x05" /* '③' 5 */ + "KP_7\x00" "\x17" /* 'KP_7' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊲\x00" "\x05" /* '㊲' 5 */ + "8\x00" "\x14" /* '8' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊳\x00" "\x05" /* '㊳' 5 */ + "KP_1\x00" "\x17" /* 'KP_1' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉛\x00" "\x05" /* '㉛' 5 */ + "3\x00" "\x14" /* '3' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉝\x00" "\x05" /* '㉝' 5 */ + "2\x00" "\x14" /* '2' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉜\x00" "\x05" /* '㉜' 5 */ + "6\x00" "\x14" /* '6' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊱\x00" "\x05" /* '㊱' 5 */ + "4\x00" "\x14" /* '4' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉞\x00" "\x05" /* '㉞' 5 */ + "KP_3\x00" "\x17" /* 'KP_3' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉝\x00" "\x05" /* '㉝' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉚\x00" "\x05" /* '㉚' 5 */ + "KP_2\x00" "\x17" /* 'KP_2' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉜\x00" "\x05" /* '㉜' 5 */ + "5\x00" "\x14" /* '5' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉟\x00" "\x05" /* '㉟' 5 */ + "KP_5\x00" "\x17" /* 'KP_5' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉟\x00" "\x05" /* '㉟' 5 */ + "9\x00" "\x14" /* '9' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊴\x00" "\x05" /* '㊴' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉚\x00" "\x05" /* '㉚' 5 */ + "E\x00" "\x14" /* 'E' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓔ\x00" "\x05" /* 'Ⓔ' 5 */ + "S\x00" "\x14" /* 'S' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓢ\x00" "\x05" /* 'Ⓢ' 5 */ + "2\x00" "\x81\xde" /* '2' 478 */ + "1\x00" "\x14" /* '1' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉑\x00" "\x05" /* '㉑' 5 */ + "KP_4\x00" "\x17" /* 'KP_4' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉔\x00" "\x05" /* '㉔' 5 */ + "KP_6\x00" "\x17" /* 'KP_6' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉖\x00" "\x05" /* '㉖' 5 */ + "KP_8\x00" "\x17" /* 'KP_8' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉘\x00" "\x05" /* '㉘' 5 */ + "KP_9\x00" "\x17" /* 'KP_9' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉙\x00" "\x05" /* '㉙' 5 */ + "KP_Space\x00" "\x1b" /* 'KP_Space' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉒\x00" "\x05" /* '㉒' 5 */ + "7\x00" "\x14" /* '7' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉗\x00" "\x05" /* '㉗' 5 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "②\x00" "\x05" /* '②' 5 */ + "KP_7\x00" "\x17" /* 'KP_7' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉗\x00" "\x05" /* '㉗' 5 */ + "8\x00" "\x14" /* '8' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉘\x00" "\x05" /* '㉘' 5 */ + "KP_1\x00" "\x17" /* 'KP_1' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉑\x00" "\x05" /* '㉑' 5 */ + "3\x00" "\x14" /* '3' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉓\x00" "\x05" /* '㉓' 5 */ + "2\x00" "\x14" /* '2' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉒\x00" "\x05" /* '㉒' 5 */ + "6\x00" "\x14" /* '6' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉖\x00" "\x05" /* '㉖' 5 */ + "4\x00" "\x14" /* '4' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉔\x00" "\x05" /* '㉔' 5 */ + "KP_3\x00" "\x17" /* 'KP_3' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉓\x00" "\x05" /* '㉓' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑳\x00" "\x05" /* '⑳' 5 */ + "KP_2\x00" "\x17" /* 'KP_2' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉒\x00" "\x05" /* '㉒' 5 */ + "5\x00" "\x14" /* '5' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉕\x00" "\x05" /* '㉕' 5 */ + "KP_5\x00" "\x17" /* 'KP_5' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉕\x00" "\x05" /* '㉕' 5 */ + "9\x00" "\x14" /* '9' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉙\x00" "\x05" /* '㉙' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑳\x00" "\x05" /* '⑳' 5 */ + "Y\x00" "\x14" /* 'Y' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓨ\x00" "\x05" /* 'Ⓨ' 5 */ + "kana_RA\x00" "\x1a" /* 'kana_RA' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋶\x00" "\x05" /* '㋶' 5 */ + "f\x00" "\x14" /* 'f' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓕ\x00" "\x05" /* 'ⓕ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὁ\x00" "\x05" /* 'ὁ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἡ\x00" "\x05" /* 'ἡ' 5 */ + "kana_HE\x00" "\x1a" /* 'kana_HE' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋬\x00" "\x05" /* '㋬' 5 */ + "Greek_rho\x00" "\x10" /* 'Greek_rho' 16 */ + "ῥ\x00" "\x05" /* 'ῥ' 5 */ + "kana_KO\x00" "\x1a" /* 'kana_KO' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋙\x00" "\x05" /* '㋙' 5 */ + "d\x00" "\x14" /* 'd' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓓ\x00" "\x05" /* 'ⓓ' 5 */ + "kana_NE\x00" "\x1a" /* 'kana_NE' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋧\x00" "\x05" /* '㋧' 5 */ + "D\x00" "\x14" /* 'D' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓓ\x00" "\x05" /* 'Ⓓ' 5 */ + "kana_FU\x00" "\x1a" /* 'kana_FU' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋫\x00" "\x05" /* '㋫' 5 */ + "6\x00" "\x14" /* '6' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑥\x00" "\x05" /* '⑥' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἁ\x00" "\x05" /* 'ἁ' 5 */ + "kana_A\x00" "\x19" /* 'kana_A' 25 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋐\x00" "\x05" /* '㋐' 5 */ + "w\x00" "\x14" /* 'w' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓦ\x00" "\x05" /* 'ⓦ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἡ\x00" "\x05" /* 'Ἡ' 5 */ + "4\x00" "\x81\xde" /* '4' 478 */ + "1\x00" "\x14" /* '1' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊶\x00" "\x05" /* '㊶' 5 */ + "KP_4\x00" "\x17" /* 'KP_4' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊹\x00" "\x05" /* '㊹' 5 */ + "KP_6\x00" "\x17" /* 'KP_6' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊻\x00" "\x05" /* '㊻' 5 */ + "KP_8\x00" "\x17" /* 'KP_8' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊽\x00" "\x05" /* '㊽' 5 */ + "KP_9\x00" "\x17" /* 'KP_9' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊾\x00" "\x05" /* '㊾' 5 */ + "KP_Space\x00" "\x1b" /* 'KP_Space' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊷\x00" "\x05" /* '㊷' 5 */ + "7\x00" "\x14" /* '7' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊼\x00" "\x05" /* '㊼' 5 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "④\x00" "\x05" /* '④' 5 */ + "KP_7\x00" "\x17" /* 'KP_7' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊼\x00" "\x05" /* '㊼' 5 */ + "8\x00" "\x14" /* '8' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊽\x00" "\x05" /* '㊽' 5 */ + "KP_1\x00" "\x17" /* 'KP_1' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊶\x00" "\x05" /* '㊶' 5 */ + "3\x00" "\x14" /* '3' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊸\x00" "\x05" /* '㊸' 5 */ + "2\x00" "\x14" /* '2' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊷\x00" "\x05" /* '㊷' 5 */ + "6\x00" "\x14" /* '6' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊻\x00" "\x05" /* '㊻' 5 */ + "4\x00" "\x14" /* '4' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊹\x00" "\x05" /* '㊹' 5 */ + "KP_3\x00" "\x17" /* 'KP_3' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊸\x00" "\x05" /* '㊸' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊵\x00" "\x05" /* '㊵' 5 */ + "KP_2\x00" "\x17" /* 'KP_2' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊷\x00" "\x05" /* '㊷' 5 */ + "5\x00" "\x14" /* '5' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊺\x00" "\x05" /* '㊺' 5 */ + "KP_5\x00" "\x17" /* 'KP_5' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊺\x00" "\x05" /* '㊺' 5 */ + "9\x00" "\x14" /* '9' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊾\x00" "\x05" /* '㊾' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊵\x00" "\x05" /* '㊵' 5 */ + "kana_KU\x00" "\x1a" /* 'kana_KU' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋗\x00" "\x05" /* '㋗' 5 */ + "KP_3\x00" "\x81\xe1" /* 'KP_3' 481 */ + "1\x00" "\x14" /* '1' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉛\x00" "\x05" /* '㉛' 5 */ + "KP_4\x00" "\x17" /* 'KP_4' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉞\x00" "\x05" /* '㉞' 5 */ + "KP_6\x00" "\x17" /* 'KP_6' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊱\x00" "\x05" /* '㊱' 5 */ + "KP_8\x00" "\x17" /* 'KP_8' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊳\x00" "\x05" /* '㊳' 5 */ + "KP_9\x00" "\x17" /* 'KP_9' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊴\x00" "\x05" /* '㊴' 5 */ + "KP_Space\x00" "\x1b" /* 'KP_Space' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉜\x00" "\x05" /* '㉜' 5 */ + "7\x00" "\x14" /* '7' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊲\x00" "\x05" /* '㊲' 5 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "③\x00" "\x05" /* '③' 5 */ + "KP_7\x00" "\x17" /* 'KP_7' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊲\x00" "\x05" /* '㊲' 5 */ + "8\x00" "\x14" /* '8' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊳\x00" "\x05" /* '㊳' 5 */ + "KP_1\x00" "\x17" /* 'KP_1' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉛\x00" "\x05" /* '㉛' 5 */ + "3\x00" "\x14" /* '3' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉝\x00" "\x05" /* '㉝' 5 */ + "2\x00" "\x14" /* '2' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉜\x00" "\x05" /* '㉜' 5 */ + "6\x00" "\x14" /* '6' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊱\x00" "\x05" /* '㊱' 5 */ + "4\x00" "\x14" /* '4' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉞\x00" "\x05" /* '㉞' 5 */ + "KP_3\x00" "\x17" /* 'KP_3' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉝\x00" "\x05" /* '㉝' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉚\x00" "\x05" /* '㉚' 5 */ + "KP_2\x00" "\x17" /* 'KP_2' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉜\x00" "\x05" /* '㉜' 5 */ + "5\x00" "\x14" /* '5' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉟\x00" "\x05" /* '㉟' 5 */ + "KP_5\x00" "\x17" /* 'KP_5' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉟\x00" "\x05" /* '㉟' 5 */ + "9\x00" "\x14" /* '9' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊴\x00" "\x05" /* '㊴' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉚\x00" "\x05" /* '㉚' 5 */ + "p\x00" "\x14" /* 'p' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓟ\x00" "\x05" /* 'ⓟ' 5 */ + "J\x00" "\x14" /* 'J' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓙ\x00" "\x05" /* 'Ⓙ' 5 */ + "kana_YA\x00" "\x1a" /* 'kana_YA' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋳\x00" "\x05" /* '㋳' 5 */ + "v\x00" "\x14" /* 'v' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓥ\x00" "\x05" /* 'ⓥ' 5 */ + "P\x00" "\x14" /* 'P' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓟ\x00" "\x05" /* 'Ⓟ' 5 */ + "M\x00" "\x14" /* 'M' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓜ\x00" "\x05" /* 'Ⓜ' 5 */ + "O\x00" "\x14" /* 'O' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓞ\x00" "\x05" /* 'Ⓞ' 5 */ + "m\x00" "\x14" /* 'm' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓜ\x00" "\x05" /* 'ⓜ' 5 */ + "r\x00" "\x14" /* 'r' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓡ\x00" "\x05" /* 'ⓡ' 5 */ + "s\x00" "\x14" /* 's' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓢ\x00" "\x05" /* 'ⓢ' 5 */ + "Z\x00" "\x14" /* 'Z' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓩ\x00" "\x05" /* 'Ⓩ' 5 */ + "kana_U\x00" "\x19" /* 'kana_U' 25 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋒\x00" "\x05" /* '㋒' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⓪\x00" "\x05" /* '⓪' 5 */ + "A\x00" "\x14" /* 'A' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓐ\x00" "\x05" /* 'Ⓐ' 5 */ + "R\x00" "\x14" /* 'R' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓡ\x00" "\x05" /* 'Ⓡ' 5 */ + "kana_TO\x00" "\x1a" /* 'kana_TO' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋣\x00" "\x05" /* '㋣' 5 */ + "kana_TA\x00" "\x1a" /* 'kana_TA' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋟\x00" "\x05" /* '㋟' 5 */ + "c\x00" "\x14" /* 'c' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓒ\x00" "\x05" /* 'ⓒ' 5 */ + "kana_RO\x00" "\x1a" /* 'kana_RO' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋺\x00" "\x05" /* '㋺' 5 */ + "L\x00" "\x14" /* 'L' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓛ\x00" "\x05" /* 'Ⓛ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἑ\x00" "\x05" /* 'Ἑ' 5 */ + "KP_2\x00" "\x81\xe1" /* 'KP_2' 481 */ + "1\x00" "\x14" /* '1' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉑\x00" "\x05" /* '㉑' 5 */ + "KP_4\x00" "\x17" /* 'KP_4' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉔\x00" "\x05" /* '㉔' 5 */ + "KP_6\x00" "\x17" /* 'KP_6' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉖\x00" "\x05" /* '㉖' 5 */ + "KP_8\x00" "\x17" /* 'KP_8' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉘\x00" "\x05" /* '㉘' 5 */ + "KP_9\x00" "\x17" /* 'KP_9' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉙\x00" "\x05" /* '㉙' 5 */ + "KP_Space\x00" "\x1b" /* 'KP_Space' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉒\x00" "\x05" /* '㉒' 5 */ + "7\x00" "\x14" /* '7' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉗\x00" "\x05" /* '㉗' 5 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "②\x00" "\x05" /* '②' 5 */ + "KP_7\x00" "\x17" /* 'KP_7' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉗\x00" "\x05" /* '㉗' 5 */ + "8\x00" "\x14" /* '8' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉘\x00" "\x05" /* '㉘' 5 */ + "KP_1\x00" "\x17" /* 'KP_1' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉑\x00" "\x05" /* '㉑' 5 */ + "3\x00" "\x14" /* '3' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉓\x00" "\x05" /* '㉓' 5 */ + "2\x00" "\x14" /* '2' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉒\x00" "\x05" /* '㉒' 5 */ + "6\x00" "\x14" /* '6' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉖\x00" "\x05" /* '㉖' 5 */ + "4\x00" "\x14" /* '4' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉔\x00" "\x05" /* '㉔' 5 */ + "KP_3\x00" "\x17" /* 'KP_3' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉓\x00" "\x05" /* '㉓' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑳\x00" "\x05" /* '⑳' 5 */ + "KP_2\x00" "\x17" /* 'KP_2' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉒\x00" "\x05" /* '㉒' 5 */ + "5\x00" "\x14" /* '5' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉕\x00" "\x05" /* '㉕' 5 */ + "KP_5\x00" "\x17" /* 'KP_5' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉕\x00" "\x05" /* '㉕' 5 */ + "9\x00" "\x14" /* '9' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㉙\x00" "\x05" /* '㉙' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑳\x00" "\x05" /* '⑳' 5 */ + "kana_O\x00" "\x19" /* 'kana_O' 25 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋔\x00" "\x05" /* '㋔' 5 */ + "kana_RI\x00" "\x1a" /* 'kana_RI' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋷\x00" "\x05" /* '㋷' 5 */ + "T\x00" "\x14" /* 'T' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓣ\x00" "\x05" /* 'Ⓣ' 5 */ + "kana_KA\x00" "\x1a" /* 'kana_KA' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋕\x00" "\x05" /* '㋕' 5 */ + "kana_MI\x00" "\x1a" /* 'kana_MI' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋯\x00" "\x05" /* '㋯' 5 */ + "5\x00" "\x3f" /* '5' 63 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑤\x00" "\x05" /* '⑤' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊿\x00" "\x05" /* '㊿' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊿\x00" "\x05" /* '㊿' 5 */ + "kana_KI\x00" "\x1a" /* 'kana_KI' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋖\x00" "\x05" /* '㋖' 5 */ + "KP_5\x00" "\x42" /* 'KP_5' 66 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑤\x00" "\x05" /* '⑤' 5 */ + "KP_0\x00" "\x17" /* 'KP_0' 23 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊿\x00" "\x05" /* '㊿' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㊿\x00" "\x05" /* '㊿' 5 */ + "K\x00" "\x14" /* 'K' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓚ\x00" "\x05" /* 'Ⓚ' 5 */ + "9\x00" "\x14" /* '9' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⑨\x00" "\x05" /* '⑨' 5 */ + "kana_SO\x00" "\x1a" /* 'kana_SO' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋞\x00" "\x05" /* '㋞' 5 */ + "B\x00" "\x14" /* 'B' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓑ\x00" "\x05" /* 'Ⓑ' 5 */ + "kana_TSU\x00" "\x1b" /* 'kana_TSU' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋡\x00" "\x05" /* '㋡' 5 */ + "0\x00" "\x14" /* '0' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⓪\x00" "\x05" /* '⓪' 5 */ + "kana_MO\x00" "\x1a" /* 'kana_MO' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋲\x00" "\x05" /* '㋲' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὡ\x00" "\x05" /* 'ὡ' 5 */ + "kana_NO\x00" "\x1a" /* 'kana_NO' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋨\x00" "\x05" /* '㋨' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὡ\x00" "\x05" /* 'Ὡ' 5 */ + "kana_NA\x00" "\x1a" /* 'kana_NA' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋤\x00" "\x05" /* '㋤' 5 */ + "X\x00" "\x14" /* 'X' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓧ\x00" "\x05" /* 'Ⓧ' 5 */ + "parenleft\x00" "\x0e" /* 'parenleft' 14 */ + "[\x00" "\x03" /* '[' 3 */ + "h\x00" "\x14" /* 'h' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "ⓗ\x00" "\x05" /* 'ⓗ' 5 */ + "I\x00" "\x14" /* 'I' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓘ\x00" "\x05" /* 'Ⓘ' 5 */ + "N\x00" "\x14" /* 'N' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓝ\x00" "\x05" /* 'Ⓝ' 5 */ + "kana_SHI\x00" "\x1b" /* 'kana_SHI' 27 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋛\x00" "\x05" /* '㋛' 5 */ + "U\x00" "\x14" /* 'U' 20 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "Ⓤ\x00" "\x05" /* 'Ⓤ' 5 */ + "kana_RE\x00" "\x1a" /* 'kana_RE' 26 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "㋹\x00" "\x05" /* '㋹' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὑ\x00" "\x05" /* 'Ὑ' 5 */ + "h\x00" "\x0f" /* 'h' 15 */ + "comma\x00" "\x0c" /* 'comma' 12 */ + "ḩ\x00" "\x05" /* 'ḩ' 5 */ + "I\x00" "\x80\xb5" /* 'I' 181 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "Ī\x00" "\x04" /* 'Ī' 4 */ + "period\x00" "\x0c" /* 'period' 12 */ + "İ\x00" "\x04" /* 'İ' 4 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "Ï\x00" "\x04" /* 'Ï' 4 */ + "j\x00" "\x07" /* 'j' 7 */ + "IJ\x00" "\x04" /* 'IJ' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "Ï\x00" "\x04" /* 'Ï' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "Í\x00" "\x04" /* 'Í' 4 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "Ī\x00" "\x04" /* 'Ī' 4 */ + "J\x00" "\x07" /* 'J' 7 */ + "IJ\x00" "\x04" /* 'IJ' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Í\x00" "\x04" /* 'Í' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Į\x00" "\x04" /* 'Į' 4 */ + "asciitilde\x00" "\x10" /* 'asciitilde' 16 */ + "Ĩ\x00" "\x04" /* 'Ĩ' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "Î\x00" "\x04" /* 'Î' 4 */ + "grave\x00" "\x0b" /* 'grave' 11 */ + "Ì\x00" "\x04" /* 'Ì' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "Î\x00" "\x04" /* 'Î' 4 */ + "N\x00" "\x5b" /* 'N' 91 */ + "less\x00" "\x0a" /* 'less' 10 */ + "Ň\x00" "\x04" /* 'Ň' 4 */ + "o\x00" "\x08" /* 'o' 8 */ + "№\x00" "\x05" /* '№' 5 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "₦\x00" "\x05" /* '₦' 5 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ŋ\x00" "\x04" /* 'Ŋ' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ń\x00" "\x04" /* 'Ń' 4 */ + "O\x00" "\x08" /* 'O' 8 */ + "№\x00" "\x05" /* '№' 5 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ņ\x00" "\x04" /* 'Ņ' 4 */ + "asciitilde\x00" "\x10" /* 'asciitilde' 16 */ + "Ñ\x00" "\x04" /* 'Ñ' 4 */ + "grave\x00" "\x8a\x95" /* 'grave' 2709 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẁ\x00" "\x05" /* 'Ẁ' 5 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ằ\x00" "\x05" /* 'ằ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ằ\x00" "\x05" /* 'Ằ' 5 */ + "a\x00" "\x07" /* 'a' 7 */ + "à\x00" "\x04" /* 'à' 4 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ὶ\x00" "\x05" /* 'Ὶ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ὶ\x00" "\x05" /* 'ὶ' 5 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ờ\x00" "\x05" /* 'ờ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ừ\x00" "\x05" /* 'ừ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ờ\x00" "\x05" /* 'Ờ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ừ\x00" "\x05" /* 'Ừ' 5 */ + "dead_circumflex\x00" "\x41" /* 'dead_circumflex' 65 */ + "a\x00" "\x08" /* 'a' 8 */ + "ầ\x00" "\x05" /* 'ầ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ề\x00" "\x05" /* 'ề' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ồ\x00" "\x05" /* 'ồ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ề\x00" "\x05" /* 'Ề' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ồ\x00" "\x05" /* 'Ồ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ầ\x00" "\x05" /* 'Ầ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὸ\x00" "\x05" /* 'Ὸ' 5 */ + "Acircumflex\x00" "\x12" /* 'Acircumflex' 18 */ + "Ầ\x00" "\x05" /* 'Ầ' 5 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р̀\x00" "\x06" /* 'р̀' 6 */ + "e\x00" "\x07" /* 'e' 7 */ + "è\x00" "\x04" /* 'è' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ò\x00" "\x04" /* 'ò' 4 */ + "Udiaeresis\x00" "\x10" /* 'Udiaeresis' 16 */ + "Ǜ\x00" "\x04" /* 'Ǜ' 4 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὺ\x00" "\x05" /* 'ὺ' 5 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ừ\x00" "\x05" /* 'ừ' 5 */ + "space\x00" "\x0a" /* 'space' 10 */ + "`\x00" "\x03" /* '`' 3 */ + "dead_macron\x00" "\x2d" /* 'dead_macron' 45 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḕ\x00" "\x05" /* 'ḕ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṑ\x00" "\x05" /* 'ṑ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḕ\x00" "\x05" /* 'Ḕ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṑ\x00" "\x05" /* 'Ṑ' 5 */ + "acircumflex\x00" "\x12" /* 'acircumflex' 18 */ + "ầ\x00" "\x05" /* 'ầ' 5 */ + "Ecircumflex\x00" "\x12" /* 'Ecircumflex' 18 */ + "Ề\x00" "\x05" /* 'Ề' 5 */ + "Cyrillic_I\x00" "\x10" /* 'Cyrillic_I' 16 */ + "Ѝ\x00" "\x04" /* 'Ѝ' 4 */ + "y\x00" "\x08" /* 'y' 8 */ + "ỳ\x00" "\x05" /* 'ỳ' 5 */ + "b\x00" "\x13" /* 'b' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ằ\x00" "\x05" /* 'ằ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ằ\x00" "\x05" /* 'Ằ' 5 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О̀\x00" "\x06" /* 'О̀' 6 */ + "i\x00" "\x07" /* 'i' 7 */ + "ì\x00" "\x04" /* 'ì' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ǹ\x00" "\x04" /* 'ǹ' 4 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а̀\x00" "\x06" /* 'а̀' 6 */ + "parenright\x00" "\x80\xfb" /* 'parenright' 251 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἲ\x00" "\x05" /* 'Ἲ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἲ\x00" "\x05" /* 'ἲ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὂ\x00" "\x05" /* 'Ὂ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὒ\x00" "\x05" /* 'ὒ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἒ\x00" "\x05" /* 'ἒ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἂ\x00" "\x05" /* 'Ἂ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὂ\x00" "\x05" /* 'ὂ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἢ\x00" "\x05" /* 'ἢ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἂ\x00" "\x05" /* 'ἂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἢ\x00" "\x05" /* 'Ἢ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἒ\x00" "\x05" /* 'Ἒ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὢ\x00" "\x05" /* 'ὢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὢ\x00" "\x05" /* 'Ὢ' 5 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ờ\x00" "\x05" /* 'Ờ' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ờ\x00" "\x05" /* 'ờ' 5 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р̀\x00" "\x06" /* 'Р̀' 6 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ὲ\x00" "\x05" /* 'ὲ' 5 */ + "Cyrillic_U\x00" "\x12" /* 'Cyrillic_U' 18 */ + "У̀\x00" "\x06" /* 'У̀' 6 */ + "Ocircumflex\x00" "\x12" /* 'Ocircumflex' 18 */ + "Ồ\x00" "\x05" /* 'Ồ' 5 */ + "omacron\x00" "\x0e" /* 'omacron' 14 */ + "ṑ\x00" "\x05" /* 'ṑ' 5 */ + "ocircumflex\x00" "\x12" /* 'ocircumflex' 18 */ + "ồ\x00" "\x05" /* 'ồ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ù\x00" "\x04" /* 'ù' 4 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ὰ\x00" "\x05" /* 'Ὰ' 5 */ + "Cyrillic_ie\x00" "\x11" /* 'Cyrillic_ie' 17 */ + "ѐ\x00" "\x04" /* 'ѐ' 4 */ + "emacron\x00" "\x0e" /* 'emacron' 14 */ + "ḕ\x00" "\x05" /* 'ḕ' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "È\x00" "\x04" /* 'È' 4 */ + "Greek_iotadieresis\x00" "\x19" /* 'Greek_iotadieresis' 25 */ + "ῒ\x00" "\x05" /* 'ῒ' 5 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "Ỳ\x00" "\x05" /* 'Ỳ' 5 */ + "Cyrillic_i\x00" "\x10" /* 'Cyrillic_i' 16 */ + "ѝ\x00" "\x04" /* 'ѝ' 4 */ + "dead_dasia\x00" "\x81\x0f" /* 'dead_dasia' 271 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἳ\x00" "\x05" /* 'Ἳ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἳ\x00" "\x05" /* 'ἳ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὃ\x00" "\x05" /* 'Ὃ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὓ\x00" "\x05" /* 'ὓ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἓ\x00" "\x05" /* 'ἓ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἃ\x00" "\x05" /* 'Ἃ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὃ\x00" "\x05" /* 'ὃ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἣ\x00" "\x05" /* 'ἣ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἃ\x00" "\x05" /* 'ἃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἣ\x00" "\x05" /* 'Ἣ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἓ\x00" "\x05" /* 'Ἓ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὣ\x00" "\x05" /* 'ὣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὣ\x00" "\x05" /* 'Ὣ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὓ\x00" "\x05" /* 'Ὓ' 5 */ + "Greek_upsilondieresis\x00" "\x1c" /* 'Greek_upsilondieresis' 28 */ + "ῢ\x00" "\x05" /* 'ῢ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὸ\x00" "\x05" /* 'ὸ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ὴ\x00" "\x05" /* 'ὴ' 5 */ + "Abreve\x00" "\x0d" /* 'Abreve' 13 */ + "Ằ\x00" "\x05" /* 'Ằ' 5 */ + "dead_psili\x00" "\x80\xfb" /* 'dead_psili' 251 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἲ\x00" "\x05" /* 'Ἲ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἲ\x00" "\x05" /* 'ἲ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὂ\x00" "\x05" /* 'Ὂ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὒ\x00" "\x05" /* 'ὒ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἒ\x00" "\x05" /* 'ἒ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἂ\x00" "\x05" /* 'Ἂ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὂ\x00" "\x05" /* 'ὂ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἢ\x00" "\x05" /* 'ἢ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἂ\x00" "\x05" /* 'ἂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἢ\x00" "\x05" /* 'Ἢ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἒ\x00" "\x05" /* 'Ἒ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὢ\x00" "\x05" /* 'ὢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὢ\x00" "\x05" /* 'Ὢ' 5 */ + "quotedbl\x00" "\x3d" /* 'quotedbl' 61 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῒ\x00" "\x05" /* 'ῒ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῢ\x00" "\x05" /* 'ῢ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǜ\x00" "\x04" /* 'ǜ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǜ\x00" "\x04" /* 'Ǜ' 4 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ờ\x00" "\x05" /* 'ờ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ừ\x00" "\x05" /* 'ừ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ờ\x00" "\x05" /* 'Ờ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ừ\x00" "\x05" /* 'Ừ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ὰ\x00" "\x05" /* 'ὰ' 5 */ + "ecircumflex\x00" "\x12" /* 'ecircumflex' 18 */ + "ề\x00" "\x05" /* 'ề' 5 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẁ\x00" "\x05" /* 'ẁ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ὴ\x00" "\x05" /* 'Ὴ' 5 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о̀\x00" "\x06" /* 'о̀' 6 */ + "Emacron\x00" "\x0e" /* 'Emacron' 14 */ + "Ḕ\x00" "\x05" /* 'Ḕ' 5 */ + "underscore\x00" "\x2c" /* 'underscore' 44 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḕ\x00" "\x05" /* 'ḕ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṑ\x00" "\x05" /* 'ṑ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḕ\x00" "\x05" /* 'Ḕ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṑ\x00" "\x05" /* 'Ṑ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ò\x00" "\x04" /* 'Ò' 4 */ + "abreve\x00" "\x0d" /* 'abreve' 13 */ + "ằ\x00" "\x05" /* 'ằ' 5 */ + "macron\x00" "\x28" /* 'macron' 40 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḕ\x00" "\x05" /* 'ḕ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṑ\x00" "\x05" /* 'ṑ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḕ\x00" "\x05" /* 'Ḕ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṑ\x00" "\x05" /* 'Ṑ' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "À\x00" "\x04" /* 'À' 4 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ὲ\x00" "\x05" /* 'Ὲ' 5 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А̀\x00" "\x06" /* 'А̀' 6 */ + "Omacron\x00" "\x0e" /* 'Omacron' 14 */ + "Ṑ\x00" "\x05" /* 'Ṑ' 5 */ + "Cyrillic_IE\x00" "\x11" /* 'Cyrillic_IE' 17 */ + "Ѐ\x00" "\x04" /* 'Ѐ' 4 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὼ\x00" "\x05" /* 'ὼ' 5 */ + "dead_diaeresis\x00" "\x43" /* 'dead_diaeresis' 67 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῒ\x00" "\x05" /* 'ῒ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῢ\x00" "\x05" /* 'ῢ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǜ\x00" "\x04" /* 'ǜ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǜ\x00" "\x04" /* 'Ǜ' 4 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ừ\x00" "\x05" /* 'Ừ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὼ\x00" "\x05" /* 'Ὼ' 5 */ + "parenleft\x00" "\x81\x0e" /* 'parenleft' 270 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἳ\x00" "\x05" /* 'Ἳ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἳ\x00" "\x05" /* 'ἳ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὃ\x00" "\x05" /* 'Ὃ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὓ\x00" "\x05" /* 'ὓ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἓ\x00" "\x05" /* 'ἓ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἃ\x00" "\x05" /* 'Ἃ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὃ\x00" "\x05" /* 'ὃ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἣ\x00" "\x05" /* 'ἣ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἃ\x00" "\x05" /* 'ἃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἣ\x00" "\x05" /* 'Ἣ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἓ\x00" "\x05" /* 'Ἓ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὣ\x00" "\x05" /* 'ὣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὣ\x00" "\x05" /* 'Ὣ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὓ\x00" "\x05" /* 'Ὓ' 5 */ + "udiaeresis\x00" "\x10" /* 'udiaeresis' 16 */ + "ǜ\x00" "\x04" /* 'ǜ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ì\x00" "\x04" /* 'Ì' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ǹ\x00" "\x04" /* 'Ǹ' 4 */ + "grave\x00" "\x80\xe4" /* 'grave' 228 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р̏\x00" "\x06" /* 'р̏' 6 */ + "Cyrillic_I\x00" "\x12" /* 'Cyrillic_I' 18 */ + "И̏\x00" "\x06" /* 'И̏' 6 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О̏\x00" "\x06" /* 'О̏' 6 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а̏\x00" "\x06" /* 'а̏' 6 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р̏\x00" "\x06" /* 'Р̏' 6 */ + "Cyrillic_U\x00" "\x12" /* 'Cyrillic_U' 18 */ + "У̏\x00" "\x06" /* 'У̏' 6 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е̏\x00" "\x06" /* 'е̏' 6 */ + "Cyrillic_i\x00" "\x12" /* 'Cyrillic_i' 18 */ + "и̏\x00" "\x06" /* 'и̏' 6 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о̏\x00" "\x06" /* 'о̏' 6 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А̏\x00" "\x06" /* 'А̏' 6 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е̏\x00" "\x06" /* 'Е̏' 6 */ + "Cyrillic_u\x00" "\x12" /* 'Cyrillic_u' 18 */ + "у̏\x00" "\x06" /* 'у̏' 6 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ù\x00" "\x04" /* 'Ù' 4 */ + "Cyrillic_u\x00" "\x12" /* 'Cyrillic_u' 18 */ + "у̀\x00" "\x06" /* 'у̀' 6 */ + "asciicircum\x00" "\x3d" /* 'asciicircum' 61 */ + "a\x00" "\x08" /* 'a' 8 */ + "ầ\x00" "\x05" /* 'ầ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ề\x00" "\x05" /* 'ề' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ồ\x00" "\x05" /* 'ồ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ề\x00" "\x05" /* 'Ề' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ồ\x00" "\x05" /* 'Ồ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ầ\x00" "\x05" /* 'Ầ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὺ\x00" "\x05" /* 'Ὺ' 5 */ + "U\x00" "\x82\x9d" /* 'U' 669 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "Ū\x00" "\x04" /* 'Ū' 4 */ + "g\x00" "\x07" /* 'g' 7 */ + "ğ\x00" "\x04" /* 'ğ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "ă\x00" "\x04" /* 'ă' 4 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ῐ\x00" "\x05" /* 'Ῐ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῐ\x00" "\x05" /* 'ῐ' 5 */ + "exclam\x00" "\x18" /* 'exclam' 24 */ + "a\x00" "\x08" /* 'a' 8 */ + "ặ\x00" "\x05" /* 'ặ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ặ\x00" "\x05" /* 'Ặ' 5 */ + "e\x00" "\x07" /* 'e' 7 */ + "ĕ\x00" "\x04" /* 'ĕ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ŏ\x00" "\x04" /* 'ŏ' 4 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῠ\x00" "\x05" /* 'ῠ' 5 */ + "diaeresis\x00" "\x0f" /* 'diaeresis' 15 */ + "Ü\x00" "\x04" /* 'Ü' 4 */ + "dead_belowdot\x00" "\x1f" /* 'dead_belowdot' 31 */ + "a\x00" "\x08" /* 'a' 8 */ + "ặ\x00" "\x05" /* 'ặ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ặ\x00" "\x05" /* 'Ặ' 5 */ + "space\x00" "\x1e" /* 'space' 30 */ + "comma\x00" "\x17" /* 'comma' 23 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḝ\x00" "\x05" /* 'ḝ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḝ\x00" "\x05" /* 'Ḝ' 5 */ + "Cyrillic_I\x00" "\x10" /* 'Cyrillic_I' 16 */ + "Й\x00" "\x04" /* 'Й' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ĭ\x00" "\x04" /* 'ĭ' 4 */ + "Cyrillic_a\x00" "\x10" /* 'Cyrillic_a' 16 */ + "ӑ\x00" "\x04" /* 'ӑ' 4 */ + "Cyrillic_U\x00" "\x10" /* 'Cyrillic_U' 16 */ + "Ў\x00" "\x04" /* 'Ў' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ŭ\x00" "\x04" /* 'ŭ' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ğ\x00" "\x04" /* 'Ğ' 4 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ᾰ\x00" "\x05" /* 'Ᾰ' 5 */ + "Cyrillic_ie\x00" "\x11" /* 'Cyrillic_ie' 17 */ + "ӗ\x00" "\x04" /* 'ӗ' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ĕ\x00" "\x04" /* 'Ĕ' 4 */ + "Cyrillic_i\x00" "\x10" /* 'Cyrillic_i' 16 */ + "й\x00" "\x04" /* 'й' 4 */ + "Cyrillic_zhe\x00" "\x12" /* 'Cyrillic_zhe' 18 */ + "ӂ\x00" "\x04" /* 'ӂ' 4 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "Ü\x00" "\x04" /* 'Ü' 4 */ + "cedilla\x00" "\x19" /* 'cedilla' 25 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḝ\x00" "\x05" /* 'ḝ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḝ\x00" "\x05" /* 'Ḝ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾰ\x00" "\x05" /* 'ᾰ' 5 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "Ú\x00" "\x04" /* 'Ú' 4 */ + "underscore\x00" "\x10" /* 'underscore' 16 */ + "Ū\x00" "\x04" /* 'Ū' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ú\x00" "\x04" /* 'Ú' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ŏ\x00" "\x04" /* 'Ŏ' 4 */ + "asterisk\x00" "\x0e" /* 'asterisk' 14 */ + "Ů\x00" "\x04" /* 'Ů' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ă\x00" "\x04" /* 'Ă' 4 */ + "Cyrillic_A\x00" "\x10" /* 'Cyrillic_A' 16 */ + "Ӑ\x00" "\x04" /* 'Ӑ' 4 */ + "comma\x00" "\x0b" /* 'comma' 11 */ + "Ų\x00" "\x04" /* 'Ų' 4 */ + "asciitilde\x00" "\x10" /* 'asciitilde' 16 */ + "Ũ\x00" "\x04" /* 'Ũ' 4 */ + "greater\x00" "\x0d" /* 'greater' 13 */ + "Û\x00" "\x04" /* 'Û' 4 */ + "Cyrillic_ZHE\x00" "\x12" /* 'Cyrillic_ZHE' 18 */ + "Ӂ\x00" "\x04" /* 'Ӂ' 4 */ + "Cyrillic_IE\x00" "\x11" /* 'Cyrillic_IE' 17 */ + "Ӗ\x00" "\x04" /* 'Ӗ' 4 */ + "dead_cedilla\x00" "\x1e" /* 'dead_cedilla' 30 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḝ\x00" "\x05" /* 'ḝ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḝ\x00" "\x05" /* 'Ḝ' 5 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ĭ\x00" "\x04" /* 'Ĭ' 4 */ + "grave\x00" "\x0b" /* 'grave' 11 */ + "Ù\x00" "\x04" /* 'Ù' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ŭ\x00" "\x04" /* 'Ŭ' 4 */ + "Cyrillic_u\x00" "\x10" /* 'Cyrillic_u' 16 */ + "ў\x00" "\x04" /* 'ў' 4 */ + "asciicircum\x00" "\x11" /* 'asciicircum' 17 */ + "Û\x00" "\x04" /* 'Û' 4 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ῠ\x00" "\x05" /* 'Ῠ' 5 */ + "asciicircum\x00" "\x84\x20" /* 'asciicircum' 1056 */ + "minus\x00" "\x0b" /* 'minus' 11 */ + "¯\x00" "\x04" /* '¯' 4 */ + "period\x00" "\x0c" /* 'period' 12 */ + "·\x00" "\x04" /* '·' 4 */ + "W\x00" "\x07" /* 'W' 7 */ + "Ŵ\x00" "\x04" /* 'Ŵ' 4 */ + "g\x00" "\x07" /* 'g' 7 */ + "ĝ\x00" "\x04" /* 'ĝ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "â\x00" "\x04" /* 'â' 4 */ + "1\x00" "\x07" /* '1' 7 */ + "¹\x00" "\x04" /* '¹' 4 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ĉ\x00" "\x04" /* 'Ĉ' 4 */ + "KP_4\x00" "\x0b" /* 'KP_4' 11 */ + "⁴\x00" "\x05" /* '⁴' 5 */ + "exclam\x00" "\x38" /* 'exclam' 56 */ + "a\x00" "\x08" /* 'a' 8 */ + "ậ\x00" "\x05" /* 'ậ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ệ\x00" "\x05" /* 'ệ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ộ\x00" "\x05" /* 'ộ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ệ\x00" "\x05" /* 'Ệ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ộ\x00" "\x05" /* 'Ộ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ậ\x00" "\x05" /* 'Ậ' 5 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р̂\x00" "\x06" /* 'р̂' 6 */ + "o\x00" "\x07" /* 'o' 7 */ + "ô\x00" "\x04" /* 'ô' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ê\x00" "\x04" /* 'ê' 4 */ + "KP_6\x00" "\x0b" /* 'KP_6' 11 */ + "⁶\x00" "\x05" /* '⁶' 5 */ + "dead_belowdot\x00" "\x3f" /* 'dead_belowdot' 63 */ + "a\x00" "\x08" /* 'a' 8 */ + "ậ\x00" "\x05" /* 'ậ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ệ\x00" "\x05" /* 'ệ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ộ\x00" "\x05" /* 'ộ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ệ\x00" "\x05" /* 'Ệ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ộ\x00" "\x05" /* 'Ộ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ậ\x00" "\x05" /* 'Ậ' 5 */ + "space\x00" "\x0a" /* 'space' 10 */ + "^\x00" "\x03" /* '^' 3 */ + "KP_8\x00" "\x0b" /* 'KP_8' 11 */ + "⁸\x00" "\x05" /* '⁸' 5 */ + "Cyrillic_I\x00" "\x12" /* 'Cyrillic_I' 18 */ + "И̂\x00" "\x06" /* 'И̂' 6 */ + "y\x00" "\x07" /* 'y' 7 */ + "ŷ\x00" "\x04" /* 'ŷ' 4 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О̂\x00" "\x06" /* 'О̂' 6 */ + "i\x00" "\x07" /* 'i' 7 */ + "î\x00" "\x04" /* 'î' 4 */ + "KP_9\x00" "\x0b" /* 'KP_9' 11 */ + "⁹\x00" "\x05" /* '⁹' 5 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "⁼\x00" "\x05" /* '⁼' 5 */ + "KP_Space\x00" "\x0e" /* 'KP_Space' 14 */ + "²\x00" "\x04" /* '²' 4 */ + "7\x00" "\x08" /* '7' 8 */ + "⁷\x00" "\x05" /* '⁷' 5 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а̂\x00" "\x06" /* 'а̂' 6 */ + "j\x00" "\x07" /* 'j' 7 */ + "ĵ\x00" "\x04" /* 'ĵ' 4 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "⁾\x00" "\x05" /* '⁾' 5 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р̂\x00" "\x06" /* 'Р̂' 6 */ + "KP_7\x00" "\x0b" /* 'KP_7' 11 */ + "⁷\x00" "\x05" /* '⁷' 5 */ + "underbar\x00" "\x60" /* 'underbar' 96 */ + "a\x00" "\x07" /* 'a' 7 */ + "ª\x00" "\x04" /* 'ª' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "º\x00" "\x04" /* 'º' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ˡ\x00" "\x04" /* 'ˡ' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ʸ\x00" "\x04" /* 'ʸ' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ⁱ\x00" "\x05" /* 'ⁱ' 5 */ + "n\x00" "\x08" /* 'n' 8 */ + "ⁿ\x00" "\x05" /* 'ⁿ' 5 */ + "j\x00" "\x07" /* 'j' 7 */ + "ʲ\x00" "\x04" /* 'ʲ' 4 */ + "x\x00" "\x07" /* 'x' 7 */ + "ˣ\x00" "\x04" /* 'ˣ' 4 */ + "w\x00" "\x07" /* 'w' 7 */ + "ʷ\x00" "\x04" /* 'ʷ' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ʳ\x00" "\x04" /* 'ʳ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ˢ\x00" "\x04" /* 'ˢ' 4 */ + "h\x00" "\x07" /* 'h' 7 */ + "ʰ\x00" "\x04" /* 'ʰ' 4 */ + "Cyrillic_U\x00" "\x12" /* 'Cyrillic_U' 18 */ + "У̂\x00" "\x06" /* 'У̂' 6 */ + "u\x00" "\x07" /* 'u' 7 */ + "û\x00" "\x04" /* 'û' 4 */ + "z\x00" "\x08" /* 'z' 8 */ + "ẑ\x00" "\x05" /* 'ẑ' 5 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ĝ\x00" "\x04" /* 'Ĝ' 4 */ + "H\x00" "\x07" /* 'H' 7 */ + "Ĥ\x00" "\x04" /* 'Ĥ' 4 */ + "8\x00" "\x08" /* '8' 8 */ + "⁸\x00" "\x05" /* '⁸' 5 */ + "KP_1\x00" "\x0a" /* 'KP_1' 10 */ + "¹\x00" "\x04" /* '¹' 4 */ + "3\x00" "\x07" /* '3' 7 */ + "³\x00" "\x04" /* '³' 4 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е̂\x00" "\x06" /* 'е̂' 6 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ê\x00" "\x04" /* 'Ê' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Ŝ\x00" "\x04" /* 'Ŝ' 4 */ + "2\x00" "\x07" /* '2' 7 */ + "²\x00" "\x04" /* '²' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ŷ\x00" "\x04" /* 'Ŷ' 4 */ + "Cyrillic_i\x00" "\x12" /* 'Cyrillic_i' 18 */ + "и̂\x00" "\x06" /* 'и̂' 6 */ + "plus\x00" "\x0b" /* 'plus' 11 */ + "⁺\x00" "\x05" /* '⁺' 5 */ + "6\x00" "\x08" /* '6' 8 */ + "⁶\x00" "\x05" /* '⁶' 5 */ + "w\x00" "\x07" /* 'w' 7 */ + "ŵ\x00" "\x04" /* 'ŵ' 4 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о̂\x00" "\x06" /* 'о̂' 6 */ + "4\x00" "\x08" /* '4' 8 */ + "⁴\x00" "\x05" /* '⁴' 5 */ + "KP_3\x00" "\x0a" /* 'KP_3' 10 */ + "³\x00" "\x04" /* '³' 4 */ + "underscore\x00" "\x62" /* 'underscore' 98 */ + "a\x00" "\x07" /* 'a' 7 */ + "ª\x00" "\x04" /* 'ª' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "º\x00" "\x04" /* 'º' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ˡ\x00" "\x04" /* 'ˡ' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ʸ\x00" "\x04" /* 'ʸ' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ⁱ\x00" "\x05" /* 'ⁱ' 5 */ + "n\x00" "\x08" /* 'n' 8 */ + "ⁿ\x00" "\x05" /* 'ⁿ' 5 */ + "j\x00" "\x07" /* 'j' 7 */ + "ʲ\x00" "\x04" /* 'ʲ' 4 */ + "x\x00" "\x07" /* 'x' 7 */ + "ˣ\x00" "\x04" /* 'ˣ' 4 */ + "w\x00" "\x07" /* 'w' 7 */ + "ʷ\x00" "\x04" /* 'ʷ' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ʳ\x00" "\x04" /* 'ʳ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ˢ\x00" "\x04" /* 'ˢ' 4 */ + "h\x00" "\x07" /* 'h' 7 */ + "ʰ\x00" "\x04" /* 'ʰ' 4 */ + "J\x00" "\x07" /* 'J' 7 */ + "Ĵ\x00" "\x04" /* 'Ĵ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ô\x00" "\x04" /* 'Ô' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ŝ\x00" "\x04" /* 'ŝ' 4 */ + "Z\x00" "\x08" /* 'Z' 8 */ + "Ẑ\x00" "\x05" /* 'Ẑ' 5 */ + "KP_0\x00" "\x0b" /* 'KP_0' 11 */ + "⁰\x00" "\x05" /* '⁰' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Â\x00" "\x04" /* 'Â' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "ĉ\x00" "\x04" /* 'ĉ' 4 */ + "KP_Add\x00" "\x0d" /* 'KP_Add' 13 */ + "⁺\x00" "\x05" /* '⁺' 5 */ + "KP_2\x00" "\x0a" /* 'KP_2' 10 */ + "²\x00" "\x04" /* '²' 4 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А̂\x00" "\x06" /* 'А̂' 6 */ + "slash\x00" "\x0a" /* 'slash' 10 */ + "|\x00" "\x03" /* '|' 3 */ + "5\x00" "\x08" /* '5' 8 */ + "⁵\x00" "\x05" /* '⁵' 5 */ + "KP_5\x00" "\x0b" /* 'KP_5' 11 */ + "⁵\x00" "\x05" /* '⁵' 5 */ + "9\x00" "\x08" /* '9' 8 */ + "⁹\x00" "\x05" /* '⁹' 5 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е̂\x00" "\x06" /* 'Е̂' 6 */ + "0\x00" "\x08" /* '0' 8 */ + "⁰\x00" "\x05" /* '⁰' 5 */ + "parenleft\x00" "\x10" /* 'parenleft' 16 */ + "⁽\x00" "\x05" /* '⁽' 5 */ + "h\x00" "\x07" /* 'h' 7 */ + "ĥ\x00" "\x04" /* 'ĥ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Î\x00" "\x04" /* 'Î' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Û\x00" "\x04" /* 'Û' 4 */ + "Cyrillic_u\x00" "\x12" /* 'Cyrillic_u' 18 */ + "у̂\x00" "\x06" /* 'у̂' 6 */ + "KP_Equal\x00" "\x0f" /* 'KP_Equal' 15 */ + "⁼\x00" "\x05" /* '⁼' 5 */ + "Greek_UPSILON\x00" "\x2d" /* 'Greek_UPSILON' 45 */ + "quotedbl\x00" "\x0e" /* 'quotedbl' 14 */ + "Ϋ\x00" "\x04" /* 'Ϋ' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "Ύ\x00" "\x04" /* 'Ύ' 4 */ + "dead_belowcircumflex\x00" "\x76" /* 'dead_belowcircumflex' 118 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḙ\x00" "\x05" /* 'ḙ' 5 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḽ\x00" "\x05" /* 'ḽ' 5 */ + "t\x00" "\x08" /* 't' 8 */ + "ṱ\x00" "\x05" /* 'ṱ' 5 */ + "n\x00" "\x08" /* 'n' 8 */ + "ṋ\x00" "\x05" /* 'ṋ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṷ\x00" "\x05" /* 'ṷ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḙ\x00" "\x05" /* 'Ḙ' 5 */ + "d\x00" "\x08" /* 'd' 8 */ + "ḓ\x00" "\x05" /* 'ḓ' 5 */ + "D\x00" "\x08" /* 'D' 8 */ + "Ḓ\x00" "\x05" /* 'Ḓ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḽ\x00" "\x05" /* 'Ḽ' 5 */ + "T\x00" "\x08" /* 'T' 8 */ + "Ṱ\x00" "\x05" /* 'Ṱ' 5 */ + "N\x00" "\x08" /* 'N' 8 */ + "Ṋ\x00" "\x05" /* 'Ṋ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṷ\x00" "\x05" /* 'Ṷ' 5 */ + "dead_caron\x00" "\x82\x75" /* 'dead_caron' 629 */ + "minus\x00" "\x0c" /* 'minus' 12 */ + "₋\x00" "\x05" /* '₋' 5 */ + "g\x00" "\x07" /* 'g' 7 */ + "ǧ\x00" "\x04" /* 'ǧ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǎ\x00" "\x04" /* 'ǎ' 4 */ + "1\x00" "\x08" /* '1' 8 */ + "₁\x00" "\x05" /* '₁' 5 */ + "ezh\x00" "\x09" /* 'ezh' 9 */ + "ǯ\x00" "\x04" /* 'ǯ' 4 */ + "C\x00" "\x07" /* 'C' 7 */ + "Č\x00" "\x04" /* 'Č' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ě\x00" "\x04" /* 'ě' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǒ\x00" "\x04" /* 'ǒ' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ľ\x00" "\x04" /* 'ľ' 4 */ + "Udiaeresis\x00" "\x10" /* 'Udiaeresis' 16 */ + "Ǚ\x00" "\x04" /* 'Ǚ' 4 */ + "t\x00" "\x07" /* 't' 7 */ + "ť\x00" "\x04" /* 'ť' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + "ˇ\x00" "\x04" /* 'ˇ' 4 */ + "Multi_key\x00" "\x23" /* 'Multi_key' 35 */ + "quotedbl\x00" "\x18" /* 'quotedbl' 24 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǚ\x00" "\x04" /* 'ǚ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǚ\x00" "\x04" /* 'Ǚ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ǐ\x00" "\x04" /* 'ǐ' 4 */ + "k\x00" "\x07" /* 'k' 7 */ + "ǩ\x00" "\x04" /* 'ǩ' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ň\x00" "\x04" /* 'ň' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "₌\x00" "\x05" /* '₌' 5 */ + "dead_caron\x00" "\x10" /* 'dead_caron' 16 */ + "ˇ\x00" "\x04" /* 'ˇ' 4 */ + "7\x00" "\x08" /* '7' 8 */ + "₇\x00" "\x05" /* '₇' 5 */ + "j\x00" "\x07" /* 'j' 7 */ + "ǰ\x00" "\x04" /* 'ǰ' 4 */ + "parenright\x00" "\x11" /* 'parenright' 17 */ + "₎\x00" "\x05" /* '₎' 5 */ + "sabovedot\x00" "\x10" /* 'sabovedot' 16 */ + "ṧ\x00" "\x05" /* 'ṧ' 5 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̌\x00" "\x04" /* '̌' 4 */ + "V\x00" "\x07" /* 'V' 7 */ + "Ǚ\x00" "\x04" /* 'Ǚ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǔ\x00" "\x04" /* 'ǔ' 4 */ + "z\x00" "\x07" /* 'z' 7 */ + "ž\x00" "\x04" /* 'ž' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ǧ\x00" "\x04" /* 'Ǧ' 4 */ + "H\x00" "\x07" /* 'H' 7 */ + "Ȟ\x00" "\x04" /* 'Ȟ' 4 */ + "8\x00" "\x08" /* '8' 8 */ + "₈\x00" "\x05" /* '₈' 5 */ + "3\x00" "\x08" /* '3' 8 */ + "₃\x00" "\x05" /* '₃' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ě\x00" "\x04" /* 'Ě' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Š\x00" "\x04" /* 'Š' 4 */ + "2\x00" "\x08" /* '2' 8 */ + "₂\x00" "\x05" /* '₂' 5 */ + "d\x00" "\x07" /* 'd' 7 */ + "ď\x00" "\x04" /* 'ď' 4 */ + "D\x00" "\x07" /* 'D' 7 */ + "Ď\x00" "\x04" /* 'Ď' 4 */ + "plus\x00" "\x0b" /* 'plus' 11 */ + "₊\x00" "\x05" /* '₊' 5 */ + "6\x00" "\x08" /* '6' 8 */ + "₆\x00" "\x05" /* '₆' 5 */ + "dead_abovedot\x00" "\x1f" /* 'dead_abovedot' 31 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṧ\x00" "\x05" /* 'Ṧ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṧ\x00" "\x05" /* 'ṧ' 5 */ + "4\x00" "\x08" /* '4' 8 */ + "₄\x00" "\x05" /* '₄' 5 */ + "v\x00" "\x07" /* 'v' 7 */ + "ǚ\x00" "\x04" /* 'ǚ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǒ\x00" "\x04" /* 'Ǒ' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ř\x00" "\x04" /* 'ř' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "š\x00" "\x04" /* 'š' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ž\x00" "\x04" /* 'Ž' 4 */ + "EZH\x00" "\x09" /* 'EZH' 9 */ + "Ǯ\x00" "\x04" /* 'Ǯ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǎ\x00" "\x04" /* 'Ǎ' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ř\x00" "\x04" /* 'Ř' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "č\x00" "\x04" /* 'č' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ľ\x00" "\x04" /* 'Ľ' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ť\x00" "\x04" /* 'Ť' 4 */ + "5\x00" "\x08" /* '5' 8 */ + "₅\x00" "\x05" /* '₅' 5 */ + "K\x00" "\x07" /* 'K' 7 */ + "Ǩ\x00" "\x04" /* 'Ǩ' 4 */ + "9\x00" "\x08" /* '9' 8 */ + "₉\x00" "\x05" /* '₉' 5 */ + "0\x00" "\x08" /* '0' 8 */ + "₀\x00" "\x05" /* '₀' 5 */ + "Sabovedot\x00" "\x10" /* 'Sabovedot' 16 */ + "Ṧ\x00" "\x05" /* 'Ṧ' 5 */ + "dead_diaeresis\x00" "\x1e" /* 'dead_diaeresis' 30 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǚ\x00" "\x04" /* 'ǚ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǚ\x00" "\x04" /* 'Ǚ' 4 */ + "parenleft\x00" "\x10" /* 'parenleft' 16 */ + "₍\x00" "\x05" /* '₍' 5 */ + "h\x00" "\x07" /* 'h' 7 */ + "ȟ\x00" "\x04" /* 'ȟ' 4 */ + "udiaeresis\x00" "\x10" /* 'udiaeresis' 16 */ + "ǚ\x00" "\x04" /* 'ǚ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ǐ\x00" "\x04" /* 'Ǐ' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ň\x00" "\x04" /* 'Ň' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǔ\x00" "\x04" /* 'Ǔ' 4 */ + "dead_tilde\x00" "\x87\x32" /* 'dead_tilde' 1842 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẵ\x00" "\x05" /* 'ẵ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẵ\x00" "\x05" /* 'Ẵ' 5 */ + "a\x00" "\x07" /* 'a' 7 */ + "ã\x00" "\x04" /* 'ã' 4 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῖ\x00" "\x05" /* 'ῖ' 5 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỡ\x00" "\x05" /* 'ỡ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ữ\x00" "\x05" /* 'ữ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỡ\x00" "\x05" /* 'Ỡ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ữ\x00" "\x05" /* 'Ữ' 5 */ + "dead_circumflex\x00" "\x41" /* 'dead_circumflex' 65 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẫ\x00" "\x05" /* 'ẫ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ễ\x00" "\x05" /* 'ễ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỗ\x00" "\x05" /* 'ỗ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ễ\x00" "\x05" /* 'Ễ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỗ\x00" "\x05" /* 'Ỗ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẫ\x00" "\x05" /* 'Ẫ' 5 */ + "Acircumflex\x00" "\x12" /* 'Acircumflex' 18 */ + "Ẫ\x00" "\x05" /* 'Ẫ' 5 */ + "less\x00" "\x0b" /* 'less' 11 */ + "≲\x00" "\x05" /* '≲' 5 */ + "Oacute\x00" "\x0d" /* 'Oacute' 13 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ẽ\x00" "\x05" /* 'ẽ' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "õ\x00" "\x04" /* 'õ' 4 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῦ\x00" "\x05" /* 'ῦ' 5 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ữ\x00" "\x05" /* 'ữ' 5 */ + "space\x00" "\x0a" /* 'space' 10 */ + "~\x00" "\x03" /* '~' 3 */ + "dead_macron\x00" "\x1b" /* 'dead_macron' 27 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "acircumflex\x00" "\x12" /* 'acircumflex' 18 */ + "ẫ\x00" "\x05" /* 'ẫ' 5 */ + "Ecircumflex\x00" "\x12" /* 'Ecircumflex' 18 */ + "Ễ\x00" "\x05" /* 'Ễ' 5 */ + "y\x00" "\x08" /* 'y' 8 */ + "ỹ\x00" "\x05" /* 'ỹ' 5 */ + "Multi_key\x00" "\x82\x2d" /* 'Multi_key' 557 */ + "b\x00" "\x13" /* 'b' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẵ\x00" "\x05" /* 'ẵ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẵ\x00" "\x05" /* 'Ẵ' 5 */ + "parenright\x00" "\x80\xab" /* 'parenright' 171 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἶ\x00" "\x05" /* 'Ἶ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἶ\x00" "\x05" /* 'ἶ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὖ\x00" "\x05" /* 'ὖ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἆ\x00" "\x05" /* 'Ἆ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἦ\x00" "\x05" /* 'ἦ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἆ\x00" "\x05" /* 'ἆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἦ\x00" "\x05" /* 'Ἦ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὦ\x00" "\x05" /* 'ὦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὦ\x00" "\x05" /* 'Ὦ' 5 */ + "quotedbl\x00" "\x2f" /* 'quotedbl' 47 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῗ\x00" "\x05" /* 'ῗ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῧ\x00" "\x05" /* 'ῧ' 5 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỡ\x00" "\x05" /* 'ỡ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ữ\x00" "\x05" /* 'ữ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỡ\x00" "\x05" /* 'Ỡ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ữ\x00" "\x05" /* 'Ữ' 5 */ + "parenleft\x00" "\x80\xbe" /* 'parenleft' 190 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἷ\x00" "\x05" /* 'Ἷ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἷ\x00" "\x05" /* 'ἷ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὗ\x00" "\x05" /* 'ὗ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἇ\x00" "\x05" /* 'Ἇ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἧ\x00" "\x05" /* 'ἧ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἇ\x00" "\x05" /* 'ἇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἧ\x00" "\x05" /* 'Ἧ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὧ\x00" "\x05" /* 'ὧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὧ\x00" "\x05" /* 'Ὧ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὗ\x00" "\x05" /* 'Ὗ' 5 */ + "U\x00" "\x13" /* 'U' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẵ\x00" "\x05" /* 'ẵ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẵ\x00" "\x05" /* 'Ẵ' 5 */ + "asciicircum\x00" "\x3d" /* 'asciicircum' 61 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẫ\x00" "\x05" /* 'ẫ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ễ\x00" "\x05" /* 'ễ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỗ\x00" "\x05" /* 'ỗ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ễ\x00" "\x05" /* 'Ễ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỗ\x00" "\x05" /* 'Ỗ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẫ\x00" "\x05" /* 'Ẫ' 5 */ + "oacute\x00" "\x0d" /* 'oacute' 13 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "i\x00" "\x07" /* 'i' 7 */ + "ĩ\x00" "\x04" /* 'ĩ' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ñ\x00" "\x04" /* 'ñ' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "≃\x00" "\x05" /* '≃' 5 */ + "dead_tilde\x00" "\x0f" /* 'dead_tilde' 15 */ + "~\x00" "\x03" /* '~' 3 */ + "Uacute\x00" "\x0d" /* 'Uacute' 13 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ỡ\x00" "\x05" /* 'Ỡ' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ỡ\x00" "\x05" /* 'ỡ' 5 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̃\x00" "\x04" /* '̃' 4 */ + "V\x00" "\x08" /* 'V' 8 */ + "Ṽ\x00" "\x05" /* 'Ṽ' 5 */ + "Ocircumflex\x00" "\x12" /* 'Ocircumflex' 18 */ + "Ỗ\x00" "\x05" /* 'Ỗ' 5 */ + "omacron\x00" "\x0d" /* 'omacron' 13 */ + "ȭ\x00" "\x04" /* 'ȭ' 4 */ + "uacute\x00" "\x0d" /* 'uacute' 13 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "ocircumflex\x00" "\x12" /* 'ocircumflex' 18 */ + "ỗ\x00" "\x05" /* 'ỗ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ũ\x00" "\x04" /* 'ũ' 4 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ẽ\x00" "\x05" /* 'Ẽ' 5 */ + "Greek_iotadieresis\x00" "\x19" /* 'Greek_iotadieresis' 25 */ + "ῗ\x00" "\x05" /* 'ῗ' 5 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "Ỹ\x00" "\x05" /* 'Ỹ' 5 */ + "dead_dasia\x00" "\x80\xbf" /* 'dead_dasia' 191 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἷ\x00" "\x05" /* 'Ἷ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἷ\x00" "\x05" /* 'ἷ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὗ\x00" "\x05" /* 'ὗ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἇ\x00" "\x05" /* 'Ἇ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἧ\x00" "\x05" /* 'ἧ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἇ\x00" "\x05" /* 'ἇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἧ\x00" "\x05" /* 'Ἧ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὧ\x00" "\x05" /* 'ὧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὧ\x00" "\x05" /* 'Ὧ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὗ\x00" "\x05" /* 'Ὗ' 5 */ + "Greek_upsilondieresis\x00" "\x1c" /* 'Greek_upsilondieresis' 28 */ + "ῧ\x00" "\x05" /* 'ῧ' 5 */ + "odiaeresis\x00" "\x11" /* 'odiaeresis' 17 */ + "ṏ\x00" "\x05" /* 'ṏ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῆ\x00" "\x05" /* 'ῆ' 5 */ + "Abreve\x00" "\x0d" /* 'Abreve' 13 */ + "Ẵ\x00" "\x05" /* 'Ẵ' 5 */ + "dead_psili\x00" "\x80\xab" /* 'dead_psili' 171 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἶ\x00" "\x05" /* 'Ἶ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἶ\x00" "\x05" /* 'ἶ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὖ\x00" "\x05" /* 'ὖ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἆ\x00" "\x05" /* 'Ἆ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἦ\x00" "\x05" /* 'ἦ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἆ\x00" "\x05" /* 'ἆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἦ\x00" "\x05" /* 'Ἦ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὦ\x00" "\x05" /* 'ὦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὦ\x00" "\x05" /* 'Ὦ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾶ\x00" "\x05" /* 'ᾶ' 5 */ + "ecircumflex\x00" "\x12" /* 'ecircumflex' 18 */ + "ễ\x00" "\x05" /* 'ễ' 5 */ + "v\x00" "\x08" /* 'v' 8 */ + "ṽ\x00" "\x05" /* 'ṽ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Õ\x00" "\x04" /* 'Õ' 4 */ + "abreve\x00" "\x0d" /* 'abreve' 13 */ + "ẵ\x00" "\x05" /* 'ẵ' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ã\x00" "\x04" /* 'Ã' 4 */ + "Odiaeresis\x00" "\x11" /* 'Odiaeresis' 17 */ + "Ṏ\x00" "\x05" /* 'Ṏ' 5 */ + "greater\x00" "\x0e" /* 'greater' 14 */ + "≳\x00" "\x05" /* '≳' 5 */ + "Omacron\x00" "\x0d" /* 'Omacron' 13 */ + "Ȭ\x00" "\x04" /* 'Ȭ' 4 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῶ\x00" "\x05" /* 'ῶ' 5 */ + "dead_diaeresis\x00" "\x45" /* 'dead_diaeresis' 69 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ῗ\x00" "\x05" /* 'ῗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṏ\x00" "\x05" /* 'ṏ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ῧ\x00" "\x05" /* 'ῧ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṏ\x00" "\x05" /* 'Ṏ' 5 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ữ\x00" "\x05" /* 'Ữ' 5 */ + "dead_acute\x00" "\x2c" /* 'dead_acute' 44 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ĩ\x00" "\x04" /* 'Ĩ' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ñ\x00" "\x04" /* 'Ñ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ũ\x00" "\x04" /* 'Ũ' 4 */ + "dead_belowcomma\x00" "\x5d" /* 'dead_belowcomma' 93 */ + "t\x00" "\x07" /* 't' 7 */ + "ț\x00" "\x04" /* 'ț' 4 */ + "space\x00" "\x0a" /* 'space' 10 */ + ",\x00" "\x03" /* ',' 3 */ + "dead_belowcomma\x00" "\x14" /* 'dead_belowcomma' 20 */ + ",\x00" "\x03" /* ',' 3 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̦\x00" "\x04" /* '̦' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Ș\x00" "\x04" /* 'Ș' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ș\x00" "\x04" /* 'ș' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ț\x00" "\x04" /* 'Ț' 4 */ + "dead_doubleacute\x00" "\x80\x82" /* 'dead_doubleacute' 130 */ + "o\x00" "\x07" /* 'o' 7 */ + "ő\x00" "\x04" /* 'ő' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + "˝\x00" "\x04" /* '˝' 4 */ + "Cyrillic_U\x00" "\x10" /* 'Cyrillic_U' 16 */ + "Ӳ\x00" "\x04" /* 'Ӳ' 4 */ + "dead_doubleacute\x00" "\x16" /* 'dead_doubleacute' 22 */ + "˝\x00" "\x04" /* '˝' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̋\x00" "\x04" /* '̋' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ű\x00" "\x04" /* 'ű' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ő\x00" "\x04" /* 'Ő' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ű\x00" "\x04" /* 'Ű' 4 */ + "Cyrillic_u\x00" "\x10" /* 'Cyrillic_u' 16 */ + "ӳ\x00" "\x04" /* 'ӳ' 4 */ + "dead_abovering\x00" "\x80\xa0" /* 'dead_abovering' 160 */ + "a\x00" "\x07" /* 'a' 7 */ + "å\x00" "\x04" /* 'å' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + "°\x00" "\x04" /* '°' 4 */ + "y\x00" "\x08" /* 'y' 8 */ + "ẙ\x00" "\x05" /* 'ẙ' 5 */ + "dead_abovering\x00" "\x14" /* 'dead_abovering' 20 */ + "°\x00" "\x04" /* '°' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̊\x00" "\x04" /* '̊' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ů\x00" "\x04" /* 'ů' 4 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẘ\x00" "\x05" /* 'ẘ' 5 */ + "A\x00" "\x07" /* 'A' 7 */ + "Å\x00" "\x04" /* 'Å' 4 */ + "Aacute\x00" "\x0c" /* 'Aacute' 12 */ + "Ǻ\x00" "\x04" /* 'Ǻ' 4 */ + "aacute\x00" "\x0c" /* 'aacute' 12 */ + "ǻ\x00" "\x04" /* 'ǻ' 4 */ + "dead_acute\x00" "\x1a" /* 'dead_acute' 26 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǻ\x00" "\x04" /* 'ǻ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǻ\x00" "\x04" /* 'Ǻ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ů\x00" "\x04" /* 'Ů' 4 */ + "Greek_accentdieresis\x00" "\x39" /* 'Greek_accentdieresis' 57 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "dead_voiced_sound\x00" "\x81\x58" /* 'dead_voiced_sound' 344 */ + "kana_KE\x00" "\x0e" /* 'kana_KE' 14 */ + "ゲ\x00" "\x05" /* 'ゲ' 5 */ + "kana_SA\x00" "\x0e" /* 'kana_SA' 14 */ + "ザ\x00" "\x05" /* 'ザ' 5 */ + "kana_SE\x00" "\x0e" /* 'kana_SE' 14 */ + "ゼ\x00" "\x05" /* 'ゼ' 5 */ + "kana_SU\x00" "\x0e" /* 'kana_SU' 14 */ + "ズ\x00" "\x05" /* 'ズ' 5 */ + "kana_WO\x00" "\x0e" /* 'kana_WO' 14 */ + "ヺ\x00" "\x05" /* 'ヺ' 5 */ + "kana_TE\x00" "\x0e" /* 'kana_TE' 14 */ + "デ\x00" "\x05" /* 'デ' 5 */ + "kana_HO\x00" "\x0e" /* 'kana_HO' 14 */ + "ボ\x00" "\x05" /* 'ボ' 5 */ + "kana_HI\x00" "\x0e" /* 'kana_HI' 14 */ + "ビ\x00" "\x05" /* 'ビ' 5 */ + "kana_WA\x00" "\x0e" /* 'kana_WA' 14 */ + "ヷ\x00" "\x05" /* 'ヷ' 5 */ + "kana_CHI\x00" "\x0f" /* 'kana_CHI' 15 */ + "ヂ\x00" "\x05" /* 'ヂ' 5 */ + "kana_HA\x00" "\x0e" /* 'kana_HA' 14 */ + "バ\x00" "\x05" /* 'バ' 5 */ + "kana_HE\x00" "\x0e" /* 'kana_HE' 14 */ + "ベ\x00" "\x05" /* 'ベ' 5 */ + "kana_KO\x00" "\x0e" /* 'kana_KO' 14 */ + "ゴ\x00" "\x05" /* 'ゴ' 5 */ + "kana_FU\x00" "\x0e" /* 'kana_FU' 14 */ + "ブ\x00" "\x05" /* 'ブ' 5 */ + "kana_KU\x00" "\x0e" /* 'kana_KU' 14 */ + "グ\x00" "\x05" /* 'グ' 5 */ + "kana_U\x00" "\x0d" /* 'kana_U' 13 */ + "ヴ\x00" "\x05" /* 'ヴ' 5 */ + "kana_TO\x00" "\x0e" /* 'kana_TO' 14 */ + "ド\x00" "\x05" /* 'ド' 5 */ + "kana_TA\x00" "\x0e" /* 'kana_TA' 14 */ + "ダ\x00" "\x05" /* 'ダ' 5 */ + "kana_KA\x00" "\x0e" /* 'kana_KA' 14 */ + "ガ\x00" "\x05" /* 'ガ' 5 */ + "kana_KI\x00" "\x0e" /* 'kana_KI' 14 */ + "ギ\x00" "\x05" /* 'ギ' 5 */ + "kana_SO\x00" "\x0e" /* 'kana_SO' 14 */ + "ゾ\x00" "\x05" /* 'ゾ' 5 */ + "kana_TSU\x00" "\x0f" /* 'kana_TSU' 15 */ + "ヅ\x00" "\x05" /* 'ヅ' 5 */ + "kana_SHI\x00" "\x0f" /* 'kana_SHI' 15 */ + "ジ\x00" "\x05" /* 'ジ' 5 */ + "dead_belowtilde\x00" "\x4c" /* 'dead_belowtilde' 76 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḛ\x00" "\x05" /* 'ḛ' 5 */ + "i\x00" "\x08" /* 'i' 8 */ + "ḭ\x00" "\x05" /* 'ḭ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṵ\x00" "\x05" /* 'ṵ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḛ\x00" "\x05" /* 'Ḛ' 5 */ + "plus\x00" "\x0b" /* 'plus' 11 */ + "⨦\x00" "\x05" /* '⨦' 5 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ḭ\x00" "\x05" /* 'Ḭ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṵ\x00" "\x05" /* 'Ṵ' 5 */ + "dead_ogonek\x00" "\x80\xb7" /* 'dead_ogonek' 183 */ + "a\x00" "\x07" /* 'a' 7 */ + "ą\x00" "\x04" /* 'ą' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ę\x00" "\x04" /* 'ę' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǫ\x00" "\x04" /* 'ǫ' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + "˛\x00" "\x04" /* '˛' 4 */ + "dead_macron\x00" "\x1b" /* 'dead_macron' 27 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǭ\x00" "\x04" /* 'ǭ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǭ\x00" "\x04" /* 'Ǭ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "į\x00" "\x04" /* 'į' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̨\x00" "\x04" /* '̨' 4 */ + "omacron\x00" "\x0d" /* 'omacron' 13 */ + "ǭ\x00" "\x04" /* 'ǭ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ų\x00" "\x04" /* 'ų' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ę\x00" "\x04" /* 'Ę' 4 */ + "dead_ogonek\x00" "\x11" /* 'dead_ogonek' 17 */ + "˛\x00" "\x04" /* '˛' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǫ\x00" "\x04" /* 'Ǫ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ą\x00" "\x04" /* 'Ą' 4 */ + "Omacron\x00" "\x0d" /* 'Omacron' 13 */ + "Ǭ\x00" "\x04" /* 'Ǭ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Į\x00" "\x04" /* 'Į' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ų\x00" "\x04" /* 'Ų' 4 */ + "dead_dasia\x00" "\x81\x2f" /* 'dead_dasia' 303 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἱ\x00" "\x05" /* 'Ἱ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἱ\x00" "\x05" /* 'ἱ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὁ\x00" "\x05" /* 'Ὁ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὑ\x00" "\x05" /* 'ὑ' 5 */ + "Greek_RHO\x00" "\x10" /* 'Greek_RHO' 16 */ + "Ῥ\x00" "\x05" /* 'Ῥ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἑ\x00" "\x05" /* 'ἑ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἁ\x00" "\x05" /* 'Ἁ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὁ\x00" "\x05" /* 'ὁ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἡ\x00" "\x05" /* 'ἡ' 5 */ + "Greek_rho\x00" "\x10" /* 'Greek_rho' 16 */ + "ῥ\x00" "\x05" /* 'ῥ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἁ\x00" "\x05" /* 'ἁ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἡ\x00" "\x05" /* 'Ἡ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἑ\x00" "\x05" /* 'Ἑ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὡ\x00" "\x05" /* 'ὡ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὡ\x00" "\x05" /* 'Ὡ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὑ\x00" "\x05" /* 'Ὑ' 5 */ + "dead_iota\x00" "\x91\x39" /* 'dead_iota' 4409 */ + "dead_grave\x00" "\x82\x1c" /* 'dead_grave' 540 */ + "Multi_key\x00" "\x80\xf3" /* 'Multi_key' 243 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾊ\x00" "\x05" /* 'ᾊ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾒ\x00" "\x05" /* 'ᾒ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾂ\x00" "\x05" /* 'ᾂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾚ\x00" "\x05" /* 'ᾚ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾢ\x00" "\x05" /* 'ᾢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾪ\x00" "\x05" /* 'ᾪ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾋ\x00" "\x05" /* 'ᾋ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾓ\x00" "\x05" /* 'ᾓ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾃ\x00" "\x05" /* 'ᾃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾛ\x00" "\x05" /* 'ᾛ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾣ\x00" "\x05" /* 'ᾣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾫ\x00" "\x05" /* 'ᾫ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾋ\x00" "\x05" /* 'ᾋ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾓ\x00" "\x05" /* 'ᾓ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾃ\x00" "\x05" /* 'ᾃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾛ\x00" "\x05" /* 'ᾛ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾣ\x00" "\x05" /* 'ᾣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾫ\x00" "\x05" /* 'ᾫ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῂ\x00" "\x05" /* 'ῂ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾊ\x00" "\x05" /* 'ᾊ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾒ\x00" "\x05" /* 'ᾒ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾂ\x00" "\x05" /* 'ᾂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾚ\x00" "\x05" /* 'ᾚ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾢ\x00" "\x05" /* 'ᾢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾪ\x00" "\x05" /* 'ᾪ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾲ\x00" "\x05" /* 'ᾲ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῲ\x00" "\x05" /* 'ῲ' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "ͺ\x00" "\x04" /* 'ͺ' 4 */ + "Multi_key\x00" "\x89\x29" /* 'Multi_key' 2345 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾈ\x00" "\x05" /* 'ᾈ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾐ\x00" "\x05" /* 'ᾐ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾀ\x00" "\x05" /* 'ᾀ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾘ\x00" "\x05" /* 'ᾘ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾠ\x00" "\x05" /* 'ᾠ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾨ\x00" "\x05" /* 'ᾨ' 5 */ + "acute\x00" "\x82\x0b" /* 'acute' 523 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῄ\x00" "\x05" /* 'ῄ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾴ\x00" "\x05" /* 'ᾴ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῴ\x00" "\x05" /* 'ῴ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "apostrophe\x00" "\x82\x10" /* 'apostrophe' 528 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῄ\x00" "\x05" /* 'ῄ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾴ\x00" "\x05" /* 'ᾴ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῴ\x00" "\x05" /* 'ῴ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "asciitilde\x00" "\x82\x10" /* 'asciitilde' 528 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾎ\x00" "\x05" /* 'ᾎ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾖ\x00" "\x05" /* 'ᾖ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾆ\x00" "\x05" /* 'ᾆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾞ\x00" "\x05" /* 'ᾞ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾦ\x00" "\x05" /* 'ᾦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾮ\x00" "\x05" /* 'ᾮ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾏ\x00" "\x05" /* 'ᾏ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾗ\x00" "\x05" /* 'ᾗ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾇ\x00" "\x05" /* 'ᾇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾟ\x00" "\x05" /* 'ᾟ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾧ\x00" "\x05" /* 'ᾧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾯ\x00" "\x05" /* 'ᾯ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῇ\x00" "\x05" /* 'ῇ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾎ\x00" "\x05" /* 'ᾎ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾖ\x00" "\x05" /* 'ᾖ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾆ\x00" "\x05" /* 'ᾆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾞ\x00" "\x05" /* 'ᾞ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾦ\x00" "\x05" /* 'ᾦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾮ\x00" "\x05" /* 'ᾮ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾷ\x00" "\x05" /* 'ᾷ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῷ\x00" "\x05" /* 'ῷ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾏ\x00" "\x05" /* 'ᾏ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾗ\x00" "\x05" /* 'ᾗ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾇ\x00" "\x05" /* 'ᾇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾟ\x00" "\x05" /* 'ᾟ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾧ\x00" "\x05" /* 'ᾧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾯ\x00" "\x05" /* 'ᾯ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾉ\x00" "\x05" /* 'ᾉ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾑ\x00" "\x05" /* 'ᾑ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾁ\x00" "\x05" /* 'ᾁ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾙ\x00" "\x05" /* 'ᾙ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾡ\x00" "\x05" /* 'ᾡ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾩ\x00" "\x05" /* 'ᾩ' 5 */ + "grave\x00" "\x82\x0b" /* 'grave' 523 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾊ\x00" "\x05" /* 'ᾊ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾒ\x00" "\x05" /* 'ᾒ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾂ\x00" "\x05" /* 'ᾂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾚ\x00" "\x05" /* 'ᾚ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾢ\x00" "\x05" /* 'ᾢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾪ\x00" "\x05" /* 'ᾪ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾋ\x00" "\x05" /* 'ᾋ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾓ\x00" "\x05" /* 'ᾓ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾃ\x00" "\x05" /* 'ᾃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾛ\x00" "\x05" /* 'ᾛ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾣ\x00" "\x05" /* 'ᾣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾫ\x00" "\x05" /* 'ᾫ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῂ\x00" "\x05" /* 'ῂ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾊ\x00" "\x05" /* 'ᾊ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾒ\x00" "\x05" /* 'ᾒ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾂ\x00" "\x05" /* 'ᾂ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾚ\x00" "\x05" /* 'ᾚ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾢ\x00" "\x05" /* 'ᾢ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾪ\x00" "\x05" /* 'ᾪ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾲ\x00" "\x05" /* 'ᾲ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῲ\x00" "\x05" /* 'ῲ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾋ\x00" "\x05" /* 'ᾋ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾓ\x00" "\x05" /* 'ᾓ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾃ\x00" "\x05" /* 'ᾃ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾛ\x00" "\x05" /* 'ᾛ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾣ\x00" "\x05" /* 'ᾣ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾫ\x00" "\x05" /* 'ᾫ' 5 */ + "dead_tilde\x00" "\x82\x1c" /* 'dead_tilde' 540 */ + "Multi_key\x00" "\x80\xf3" /* 'Multi_key' 243 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾎ\x00" "\x05" /* 'ᾎ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾖ\x00" "\x05" /* 'ᾖ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾆ\x00" "\x05" /* 'ᾆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾞ\x00" "\x05" /* 'ᾞ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾦ\x00" "\x05" /* 'ᾦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾮ\x00" "\x05" /* 'ᾮ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾏ\x00" "\x05" /* 'ᾏ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾗ\x00" "\x05" /* 'ᾗ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾇ\x00" "\x05" /* 'ᾇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾟ\x00" "\x05" /* 'ᾟ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾧ\x00" "\x05" /* 'ᾧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾯ\x00" "\x05" /* 'ᾯ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾏ\x00" "\x05" /* 'ᾏ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾗ\x00" "\x05" /* 'ᾗ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾇ\x00" "\x05" /* 'ᾇ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾟ\x00" "\x05" /* 'ᾟ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾧ\x00" "\x05" /* 'ᾧ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾯ\x00" "\x05" /* 'ᾯ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῇ\x00" "\x05" /* 'ῇ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾎ\x00" "\x05" /* 'ᾎ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾖ\x00" "\x05" /* 'ᾖ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾆ\x00" "\x05" /* 'ᾆ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾞ\x00" "\x05" /* 'ᾞ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾦ\x00" "\x05" /* 'ᾦ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾮ\x00" "\x05" /* 'ᾮ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾷ\x00" "\x05" /* 'ᾷ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῷ\x00" "\x05" /* 'ῷ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾼ\x00" "\x05" /* 'ᾼ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾉ\x00" "\x05" /* 'ᾉ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾑ\x00" "\x05" /* 'ᾑ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾁ\x00" "\x05" /* 'ᾁ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾙ\x00" "\x05" /* 'ᾙ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾡ\x00" "\x05" /* 'ᾡ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾩ\x00" "\x05" /* 'ᾩ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῃ\x00" "\x05" /* 'ῃ' 5 */ + "dead_iota\x00" "\x0f" /* 'dead_iota' 15 */ + "ͺ\x00" "\x04" /* 'ͺ' 4 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾈ\x00" "\x05" /* 'ᾈ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾐ\x00" "\x05" /* 'ᾐ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾀ\x00" "\x05" /* 'ᾀ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾘ\x00" "\x05" /* 'ᾘ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾠ\x00" "\x05" /* 'ᾠ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾨ\x00" "\x05" /* 'ᾨ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾳ\x00" "\x05" /* 'ᾳ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ῌ\x00" "\x05" /* 'ῌ' 5 */ + "Greek_omegaaccent\x00" "\x18" /* 'Greek_omegaaccent' 24 */ + "ῴ\x00" "\x05" /* 'ῴ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῳ\x00" "\x05" /* 'ῳ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ῼ\x00" "\x05" /* 'ῼ' 5 */ + "dead_acute\x00" "\x82\x1c" /* 'dead_acute' 540 */ + "Multi_key\x00" "\x80\xf3" /* 'Multi_key' 243 */ + "parenright\x00" "\x74" /* 'parenright' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "parenleft\x00" "\x73" /* 'parenleft' 115 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "dead_dasia\x00" "\x74" /* 'dead_dasia' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾍ\x00" "\x05" /* 'ᾍ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾕ\x00" "\x05" /* 'ᾕ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾅ\x00" "\x05" /* 'ᾅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾝ\x00" "\x05" /* 'ᾝ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾥ\x00" "\x05" /* 'ᾥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾭ\x00" "\x05" /* 'ᾭ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ῄ\x00" "\x05" /* 'ῄ' 5 */ + "dead_psili\x00" "\x74" /* 'dead_psili' 116 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "ᾌ\x00" "\x05" /* 'ᾌ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ᾔ\x00" "\x05" /* 'ᾔ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾄ\x00" "\x05" /* 'ᾄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "ᾜ\x00" "\x05" /* 'ᾜ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ᾤ\x00" "\x05" /* 'ᾤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "ᾬ\x00" "\x05" /* 'ᾬ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ᾴ\x00" "\x05" /* 'ᾴ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ῴ\x00" "\x05" /* 'ῴ' 5 */ + "Greek_alphaaccent\x00" "\x18" /* 'Greek_alphaaccent' 24 */ + "ᾴ\x00" "\x05" /* 'ᾴ' 5 */ + "Greek_etaaccent\x00" "\x16" /* 'Greek_etaaccent' 22 */ + "ῄ\x00" "\x05" /* 'ῄ' 5 */ + "dead_greek\x00" "\x81\xed" /* 'dead_greek' 493 */ + "W\x00" "\x07" /* 'W' 7 */ + "Ω\x00" "\x04" /* 'Ω' 4 */ + "g\x00" "\x07" /* 'g' 7 */ + "γ\x00" "\x04" /* 'γ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "α\x00" "\x04" /* 'α' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ε\x00" "\x04" /* 'ε' 4 */ + "F\x00" "\x07" /* 'F' 7 */ + "Φ\x00" "\x04" /* 'Φ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ο\x00" "\x04" /* 'ο' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "λ\x00" "\x04" /* 'λ' 4 */ + "t\x00" "\x07" /* 't' 7 */ + "τ\x00" "\x04" /* 'τ' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + "µ\x00" "\x04" /* 'µ' 4 */ + "dead_macron\x00" "\x3d" /* 'dead_macron' 61 */ + "a\x00" "\x08" /* 'a' 8 */ + "ᾱ\x00" "\x05" /* 'ᾱ' 5 */ + "i\x00" "\x08" /* 'i' 8 */ + "ῑ\x00" "\x05" /* 'ῑ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ῡ\x00" "\x05" /* 'ῡ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ᾱ\x00" "\x05" /* 'Ᾱ' 5 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ῑ\x00" "\x05" /* 'Ῑ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ῡ\x00" "\x05" /* 'Ῡ' 5 */ + "Q\x00" "\x07" /* 'Q' 7 */ + "Χ\x00" "\x04" /* 'Χ' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ψ\x00" "\x04" /* 'ψ' 4 */ + "b\x00" "\x07" /* 'b' 7 */ + "β\x00" "\x04" /* 'β' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ι\x00" "\x04" /* 'ι' 4 */ + "k\x00" "\x07" /* 'k' 7 */ + "κ\x00" "\x04" /* 'κ' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ν\x00" "\x04" /* 'ν' 4 */ + "j\x00" "\x07" /* 'j' 7 */ + "θ\x00" "\x04" /* 'θ' 4 */ + "x\x00" "\x07" /* 'x' 7 */ + "ξ\x00" "\x04" /* 'ξ' 4 */ + "q\x00" "\x07" /* 'q' 7 */ + "χ\x00" "\x04" /* 'χ' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "µ\x00" "\x04" /* 'µ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "υ\x00" "\x04" /* 'υ' 4 */ + "z\x00" "\x07" /* 'z' 7 */ + "ζ\x00" "\x04" /* 'ζ' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Γ\x00" "\x04" /* 'Γ' 4 */ + "H\x00" "\x07" /* 'H' 7 */ + "Η\x00" "\x04" /* 'Η' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ε\x00" "\x04" /* 'Ε' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Σ\x00" "\x04" /* 'Σ' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ψ\x00" "\x04" /* 'Ψ' 4 */ + "f\x00" "\x07" /* 'f' 7 */ + "φ\x00" "\x04" /* 'φ' 4 */ + "d\x00" "\x07" /* 'd' 7 */ + "δ\x00" "\x04" /* 'δ' 4 */ + "dead_greek\x00" "\x10" /* 'dead_greek' 16 */ + "µ\x00" "\x04" /* 'µ' 4 */ + "D\x00" "\x07" /* 'D' 7 */ + "Δ\x00" "\x04" /* 'Δ' 4 */ + "w\x00" "\x07" /* 'w' 7 */ + "ω\x00" "\x04" /* 'ω' 4 */ + "p\x00" "\x07" /* 'p' 7 */ + "π\x00" "\x04" /* 'π' 4 */ + "J\x00" "\x07" /* 'J' 7 */ + "Θ\x00" "\x04" /* 'Θ' 4 */ + "P\x00" "\x07" /* 'P' 7 */ + "Π\x00" "\x04" /* 'Π' 4 */ + "M\x00" "\x07" /* 'M' 7 */ + "Μ\x00" "\x04" /* 'Μ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ο\x00" "\x04" /* 'Ο' 4 */ + "m\x00" "\x07" /* 'm' 7 */ + "μ\x00" "\x04" /* 'μ' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ρ\x00" "\x04" /* 'ρ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "σ\x00" "\x04" /* 'σ' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ζ\x00" "\x04" /* 'Ζ' 4 */ + "dead_stroke\x00" "\x14" /* 'dead_stroke' 20 */ + "r\x00" "\x07" /* 'r' 7 */ + "ϼ\x00" "\x04" /* 'ϼ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Α\x00" "\x04" /* 'Α' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ρ\x00" "\x04" /* 'Ρ' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Λ\x00" "\x04" /* 'Λ' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Τ\x00" "\x04" /* 'Τ' 4 */ + "dead_hook\x00" "\x12" /* 'dead_hook' 18 */ + "U\x00" "\x07" /* 'U' 7 */ + "ϒ\x00" "\x04" /* 'ϒ' 4 */ + "K\x00" "\x07" /* 'K' 7 */ + "Κ\x00" "\x04" /* 'Κ' 4 */ + "B\x00" "\x07" /* 'B' 7 */ + "Β\x00" "\x04" /* 'Β' 4 */ + "X\x00" "\x07" /* 'X' 7 */ + "Ξ\x00" "\x04" /* 'Ξ' 4 */ + "h\x00" "\x07" /* 'h' 7 */ + "η\x00" "\x04" /* 'η' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ι\x00" "\x04" /* 'Ι' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ν\x00" "\x04" /* 'Ν' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Υ\x00" "\x04" /* 'Υ' 4 */ + "dead_invertedbreve\x00" "\x80\xf1" /* 'dead_invertedbreve' 241 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р̑\x00" "\x06" /* 'р̑' 6 */ + "Cyrillic_I\x00" "\x12" /* 'Cyrillic_I' 18 */ + "И̑\x00" "\x06" /* 'И̑' 6 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О̑\x00" "\x06" /* 'О̑' 6 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а̑\x00" "\x06" /* 'а̑' 6 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р̑\x00" "\x06" /* 'Р̑' 6 */ + "Cyrillic_U\x00" "\x12" /* 'Cyrillic_U' 18 */ + "У̑\x00" "\x06" /* 'У̑' 6 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е̑\x00" "\x06" /* 'е̑' 6 */ + "Cyrillic_i\x00" "\x12" /* 'Cyrillic_i' 18 */ + "и̑\x00" "\x06" /* 'и̑' 6 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о̑\x00" "\x06" /* 'о̑' 6 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А̑\x00" "\x06" /* 'А̑' 6 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е̑\x00" "\x06" /* 'Е̑' 6 */ + "Cyrillic_u\x00" "\x12" /* 'Cyrillic_u' 18 */ + "у̑\x00" "\x06" /* 'у̑' 6 */ + "dead_psili\x00" "\x81\x0b" /* 'dead_psili' 267 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἰ\x00" "\x05" /* 'Ἰ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἰ\x00" "\x05" /* 'ἰ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὀ\x00" "\x05" /* 'Ὀ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὐ\x00" "\x05" /* 'ὐ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἐ\x00" "\x05" /* 'ἐ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἀ\x00" "\x05" /* 'Ἀ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὀ\x00" "\x05" /* 'ὀ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἠ\x00" "\x05" /* 'ἠ' 5 */ + "Greek_rho\x00" "\x10" /* 'Greek_rho' 16 */ + "ῤ\x00" "\x05" /* 'ῤ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἀ\x00" "\x05" /* 'ἀ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἠ\x00" "\x05" /* 'Ἠ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἐ\x00" "\x05" /* 'Ἐ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὠ\x00" "\x05" /* 'ὠ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὠ\x00" "\x05" /* 'Ὠ' 5 */ + "dead_abovedot\x00" "\x82\xf7" /* 'dead_abovedot' 759 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẇ\x00" "\x05" /* 'Ẇ' 5 */ + "g\x00" "\x07" /* 'g' 7 */ + "ġ\x00" "\x04" /* 'ġ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "ȧ\x00" "\x04" /* 'ȧ' 4 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ċ\x00" "\x04" /* 'Ċ' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ė\x00" "\x04" /* 'ė' 4 */ + "F\x00" "\x08" /* 'F' 8 */ + "Ḟ\x00" "\x05" /* 'Ḟ' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȯ\x00" "\x04" /* 'ȯ' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ŀ\x00" "\x04" /* 'ŀ' 4 */ + "t\x00" "\x08" /* 't' 8 */ + "ṫ\x00" "\x05" /* 'ṫ' 5 */ + "dead_belowdot\x00" "\x1f" /* 'dead_belowdot' 31 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṩ\x00" "\x05" /* 'Ṩ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṩ\x00" "\x05" /* 'ṩ' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "˙\x00" "\x04" /* '˙' 4 */ + "dead_macron\x00" "\x29" /* 'dead_macron' 41 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǡ\x00" "\x04" /* 'ǡ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȱ\x00" "\x04" /* 'ȱ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȱ\x00" "\x04" /* 'Ȱ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǡ\x00" "\x04" /* 'Ǡ' 4 */ + "y\x00" "\x08" /* 'y' 8 */ + "ẏ\x00" "\x05" /* 'ẏ' 5 */ + "b\x00" "\x08" /* 'b' 8 */ + "ḃ\x00" "\x05" /* 'ḃ' 5 */ + "Multi_key\x00" "\x74" /* 'Multi_key' 116 */ + "exclam\x00" "\x18" /* 'exclam' 24 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṩ\x00" "\x05" /* 'Ṩ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṩ\x00" "\x05" /* 'ṩ' 5 */ + "f\x00" "\x0b" /* 'f' 11 */ + "s\x00" "\x08" /* 's' 8 */ + "ẛ\x00" "\x05" /* 'ẛ' 5 */ + "acute\x00" "\x17" /* 'acute' 23 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṥ\x00" "\x05" /* 'Ṥ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṥ\x00" "\x05" /* 'ṥ' 5 */ + "apostrophe\x00" "\x1c" /* 'apostrophe' 28 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṥ\x00" "\x05" /* 'Ṥ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṥ\x00" "\x05" /* 'ṥ' 5 */ + "c\x00" "\x13" /* 'c' 19 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṧ\x00" "\x05" /* 'Ṧ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṧ\x00" "\x05" /* 'ṧ' 5 */ + "i\x00" "\x07" /* 'i' 7 */ + "ı\x00" "\x04" /* 'ı' 4 */ + "n\x00" "\x08" /* 'n' 8 */ + "ṅ\x00" "\x05" /* 'ṅ' 5 */ + "dead_caron\x00" "\x1c" /* 'dead_caron' 28 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṧ\x00" "\x05" /* 'Ṧ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṧ\x00" "\x05" /* 'ṧ' 5 */ + "j\x00" "\x07" /* 'j' 7 */ + "ȷ\x00" "\x04" /* 'ȷ' 4 */ + "x\x00" "\x08" /* 'x' 8 */ + "ẋ\x00" "\x05" /* 'ẋ' 5 */ + "amacron\x00" "\x0d" /* 'amacron' 13 */ + "ǡ\x00" "\x04" /* 'ǡ' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̇\x00" "\x04" /* '̇' 4 */ + "omacron\x00" "\x0d" /* 'omacron' 13 */ + "ȱ\x00" "\x04" /* 'ȱ' 4 */ + "z\x00" "\x07" /* 'z' 7 */ + "ż\x00" "\x04" /* 'ż' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ġ\x00" "\x04" /* 'Ġ' 4 */ + "Sacute\x00" "\x0d" /* 'Sacute' 13 */ + "Ṥ\x00" "\x05" /* 'Ṥ' 5 */ + "H\x00" "\x08" /* 'H' 8 */ + "Ḣ\x00" "\x05" /* 'Ḣ' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ė\x00" "\x04" /* 'Ė' 4 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṡ\x00" "\x05" /* 'Ṡ' 5 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "Ẏ\x00" "\x05" /* 'Ẏ' 5 */ + "scaron\x00" "\x0d" /* 'scaron' 13 */ + "ṧ\x00" "\x05" /* 'ṧ' 5 */ + "f\x00" "\x08" /* 'f' 8 */ + "ḟ\x00" "\x05" /* 'ḟ' 5 */ + "d\x00" "\x08" /* 'd' 8 */ + "ḋ\x00" "\x05" /* 'ḋ' 5 */ + "Scaron\x00" "\x0d" /* 'Scaron' 13 */ + "Ṧ\x00" "\x05" /* 'Ṧ' 5 */ + "D\x00" "\x08" /* 'D' 8 */ + "Ḋ\x00" "\x05" /* 'Ḋ' 5 */ + "dead_abovedot\x00" "\x13" /* 'dead_abovedot' 19 */ + "˙\x00" "\x04" /* '˙' 4 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẇ\x00" "\x05" /* 'ẇ' 5 */ + "p\x00" "\x08" /* 'p' 8 */ + "ṗ\x00" "\x05" /* 'ṗ' 5 */ + "P\x00" "\x08" /* 'P' 8 */ + "Ṗ\x00" "\x05" /* 'Ṗ' 5 */ + "M\x00" "\x08" /* 'M' 8 */ + "Ṁ\x00" "\x05" /* 'Ṁ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȯ\x00" "\x04" /* 'Ȯ' 4 */ + "m\x00" "\x08" /* 'm' 8 */ + "ṁ\x00" "\x05" /* 'ṁ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṙ\x00" "\x05" /* 'ṙ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṡ\x00" "\x05" /* 'ṡ' 5 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ż\x00" "\x04" /* 'Ż' 4 */ + "sacute\x00" "\x0d" /* 'sacute' 13 */ + "ṥ\x00" "\x05" /* 'ṥ' 5 */ + "dead_stroke\x00" "\x14" /* 'dead_stroke' 20 */ + "j\x00" "\x07" /* 'j' 7 */ + "ɟ\x00" "\x04" /* 'ɟ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ȧ\x00" "\x04" /* 'Ȧ' 4 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṙ\x00" "\x05" /* 'Ṙ' 5 */ + "c\x00" "\x07" /* 'c' 7 */ + "ċ\x00" "\x04" /* 'ċ' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ŀ\x00" "\x04" /* 'Ŀ' 4 */ + "T\x00" "\x08" /* 'T' 8 */ + "Ṫ\x00" "\x05" /* 'Ṫ' 5 */ + "Omacron\x00" "\x0d" /* 'Omacron' 13 */ + "Ȱ\x00" "\x04" /* 'Ȱ' 4 */ + "B\x00" "\x08" /* 'B' 8 */ + "Ḃ\x00" "\x05" /* 'Ḃ' 5 */ + "Amacron\x00" "\x0d" /* 'Amacron' 13 */ + "Ǡ\x00" "\x04" /* 'Ǡ' 4 */ + "dead_acute\x00" "\x1c" /* 'dead_acute' 28 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṥ\x00" "\x05" /* 'Ṥ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṥ\x00" "\x05" /* 'ṥ' 5 */ + "X\x00" "\x08" /* 'X' 8 */ + "Ẋ\x00" "\x05" /* 'Ẋ' 5 */ + "h\x00" "\x08" /* 'h' 8 */ + "ḣ\x00" "\x05" /* 'ḣ' 5 */ + "I\x00" "\x07" /* 'I' 7 */ + "İ\x00" "\x04" /* 'İ' 4 */ + "N\x00" "\x08" /* 'N' 8 */ + "Ṅ\x00" "\x05" /* 'Ṅ' 5 */ + "dead_double_grave\x00" "\x67" /* 'dead_double_grave' 103 */ + "a\x00" "\x07" /* 'a' 7 */ + "ȁ\x00" "\x04" /* 'ȁ' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ȅ\x00" "\x04" /* 'ȅ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȍ\x00" "\x04" /* 'ȍ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ȉ\x00" "\x04" /* 'ȉ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ȕ\x00" "\x04" /* 'ȕ' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ȅ\x00" "\x04" /* 'Ȅ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȍ\x00" "\x04" /* 'Ȍ' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ȑ\x00" "\x04" /* 'ȑ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ȁ\x00" "\x04" /* 'Ȁ' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ȑ\x00" "\x04" /* 'Ȑ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ȉ\x00" "\x04" /* 'Ȉ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ȕ\x00" "\x04" /* 'Ȕ' 4 */ + "dead_semivoiced_sound\x00" "\x5d" /* 'dead_semivoiced_sound' 93 */ + "kana_HO\x00" "\x0e" /* 'kana_HO' 14 */ + "ポ\x00" "\x05" /* 'ポ' 5 */ + "kana_HI\x00" "\x0e" /* 'kana_HI' 14 */ + "ピ\x00" "\x05" /* 'ピ' 5 */ + "kana_HA\x00" "\x0e" /* 'kana_HA' 14 */ + "パ\x00" "\x05" /* 'パ' 5 */ + "kana_HE\x00" "\x0e" /* 'kana_HE' 14 */ + "ペ\x00" "\x05" /* 'ペ' 5 */ + "kana_FU\x00" "\x0e" /* 'kana_FU' 14 */ + "プ\x00" "\x05" /* 'プ' 5 */ + "dead_stroke\x00" "\x81\xdd" /* 'dead_stroke' 477 */ + "g\x00" "\x07" /* 'g' 7 */ + "ǥ\x00" "\x04" /* 'ǥ' 4 */ + "a\x00" "\x08" /* 'a' 8 */ + "ⱥ\x00" "\x05" /* 'ⱥ' 5 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ȼ\x00" "\x04" /* 'Ȼ' 4 */ + "less\x00" "\x0b" /* 'less' 11 */ + "≮\x00" "\x05" /* '≮' 5 */ + "Oacute\x00" "\x0c" /* 'Oacute' 12 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ɇ\x00" "\x04" /* 'ɇ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ø\x00" "\x04" /* 'ø' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ł\x00" "\x04" /* 'ł' 4 */ + "t\x00" "\x07" /* 't' 7 */ + "ŧ\x00" "\x04" /* 'ŧ' 4 */ + "space\x00" "\x0a" /* 'space' 10 */ + "/\x00" "\x03" /* '/' 3 */ + "y\x00" "\x07" /* 'y' 7 */ + "ɏ\x00" "\x04" /* 'ɏ' 4 */ + "b\x00" "\x07" /* 'b' 7 */ + "ƀ\x00" "\x04" /* 'ƀ' 4 */ + "oacute\x00" "\x0c" /* 'oacute' 12 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ɨ\x00" "\x04" /* 'ɨ' 4 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "≠\x00" "\x05" /* '≠' 5 */ + "j\x00" "\x07" /* 'j' 7 */ + "ɉ\x00" "\x04" /* 'ɉ' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̸\x00" "\x04" /* '̸' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ʉ\x00" "\x04" /* 'ʉ' 4 */ + "greaterthanequal\x00" "\x17" /* 'greaterthanequal' 23 */ + "≱\x00" "\x05" /* '≱' 5 */ + "z\x00" "\x07" /* 'z' 7 */ + "ƶ\x00" "\x04" /* 'ƶ' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ǥ\x00" "\x04" /* 'Ǥ' 4 */ + "H\x00" "\x07" /* 'H' 7 */ + "Ħ\x00" "\x04" /* 'Ħ' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ɇ\x00" "\x04" /* 'Ɇ' 4 */ + "2\x00" "\x07" /* '2' 7 */ + "ƻ\x00" "\x04" /* 'ƻ' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ɏ\x00" "\x04" /* 'Ɏ' 4 */ + "d\x00" "\x07" /* 'd' 7 */ + "đ\x00" "\x04" /* 'đ' 4 */ + "dead_greek\x00" "\x13" /* 'dead_greek' 19 */ + "r\x00" "\x07" /* 'r' 7 */ + "ϼ\x00" "\x04" /* 'ϼ' 4 */ + "D\x00" "\x07" /* 'D' 7 */ + "Đ\x00" "\x04" /* 'Đ' 4 */ + "dead_abovedot\x00" "\x16" /* 'dead_abovedot' 22 */ + "j\x00" "\x07" /* 'j' 7 */ + "ɟ\x00" "\x04" /* 'ɟ' 4 */ + "lessthanequal\x00" "\x14" /* 'lessthanequal' 20 */ + "≰\x00" "\x05" /* '≰' 5 */ + "p\x00" "\x08" /* 'p' 8 */ + "ᵽ\x00" "\x05" /* 'ᵽ' 5 */ + "J\x00" "\x07" /* 'J' 7 */ + "Ɉ\x00" "\x04" /* 'Ɉ' 4 */ + "P\x00" "\x08" /* 'P' 8 */ + "Ᵽ\x00" "\x05" /* 'Ᵽ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ø\x00" "\x04" /* 'Ø' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ɍ\x00" "\x04" /* 'ɍ' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ƶ\x00" "\x04" /* 'Ƶ' 4 */ + "dead_stroke\x00" "\x10" /* 'dead_stroke' 16 */ + "/\x00" "\x03" /* '/' 3 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ⱥ\x00" "\x04" /* 'Ⱥ' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ɍ\x00" "\x04" /* 'Ɍ' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "ȼ\x00" "\x04" /* 'ȼ' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ł\x00" "\x04" /* 'Ł' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ŧ\x00" "\x04" /* 'Ŧ' 4 */ + "greater\x00" "\x0e" /* 'greater' 14 */ + "≯\x00" "\x05" /* '≯' 5 */ + "B\x00" "\x07" /* 'B' 7 */ + "Ƀ\x00" "\x04" /* 'Ƀ' 4 */ + "dead_acute\x00" "\x1a" /* 'dead_acute' 26 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "h\x00" "\x07" /* 'h' 7 */ + "ħ\x00" "\x04" /* 'ħ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ɨ\x00" "\x04" /* 'Ɨ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ʉ\x00" "\x04" /* 'Ʉ' 4 */ + "dead_hook\x00" "\x83\x5e" /* 'dead_hook' 862 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ⱳ\x00" "\x05" /* 'Ⱳ' 5 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẳ\x00" "\x05" /* 'ẳ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẳ\x00" "\x05" /* 'Ẳ' 5 */ + "g\x00" "\x07" /* 'g' 7 */ + "ɠ\x00" "\x04" /* 'ɠ' 4 */ + "a\x00" "\x08" /* 'a' 8 */ + "ả\x00" "\x05" /* 'ả' 5 */ + "dead_circumflex\x00" "\x41" /* 'dead_circumflex' 65 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẩ\x00" "\x05" /* 'ẩ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ể\x00" "\x05" /* 'ể' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ổ\x00" "\x05" /* 'ổ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ể\x00" "\x05" /* 'Ể' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ổ\x00" "\x05" /* 'Ổ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẩ\x00" "\x05" /* 'Ẩ' 5 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ở\x00" "\x05" /* 'ở' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ử\x00" "\x05" /* 'ử' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ở\x00" "\x05" /* 'Ở' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ử\x00" "\x05" /* 'Ử' 5 */ + "Acircumflex\x00" "\x12" /* 'Acircumflex' 18 */ + "Ẩ\x00" "\x05" /* 'Ẩ' 5 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ƈ\x00" "\x04" /* 'Ƈ' 4 */ + "e\x00" "\x08" /* 'e' 8 */ + "ẻ\x00" "\x05" /* 'ẻ' 5 */ + "F\x00" "\x07" /* 'F' 7 */ + "Ƒ\x00" "\x04" /* 'Ƒ' 4 */ + "o\x00" "\x08" /* 'o' 8 */ + "ỏ\x00" "\x05" /* 'ỏ' 5 */ + "t\x00" "\x07" /* 't' 7 */ + "ƭ\x00" "\x04" /* 'ƭ' 4 */ + "schwa\x00" "\x0b" /* 'schwa' 11 */ + "ɚ\x00" "\x04" /* 'ɚ' 4 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ử\x00" "\x05" /* 'ử' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "̉\x00" "\x04" /* '̉' 4 */ + "acircumflex\x00" "\x12" /* 'acircumflex' 18 */ + "ẩ\x00" "\x05" /* 'ẩ' 5 */ + "Ecircumflex\x00" "\x12" /* 'Ecircumflex' 18 */ + "Ể\x00" "\x05" /* 'Ể' 5 */ + "y\x00" "\x08" /* 'y' 8 */ + "ỷ\x00" "\x05" /* 'ỷ' 5 */ + "b\x00" "\x07" /* 'b' 7 */ + "ɓ\x00" "\x04" /* 'ɓ' 4 */ + "Multi_key\x00" "\x80\x95" /* 'Multi_key' 149 */ + "b\x00" "\x13" /* 'b' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẳ\x00" "\x05" /* 'ẳ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẳ\x00" "\x05" /* 'Ẳ' 5 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ở\x00" "\x05" /* 'ở' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ử\x00" "\x05" /* 'ử' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ở\x00" "\x05" /* 'Ở' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ử\x00" "\x05" /* 'Ử' 5 */ + "U\x00" "\x13" /* 'U' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẳ\x00" "\x05" /* 'ẳ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẳ\x00" "\x05" /* 'Ẳ' 5 */ + "asciicircum\x00" "\x3d" /* 'asciicircum' 61 */ + "a\x00" "\x08" /* 'a' 8 */ + "ẩ\x00" "\x05" /* 'ẩ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ể\x00" "\x05" /* 'ể' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ổ\x00" "\x05" /* 'ổ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ể\x00" "\x05" /* 'Ể' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ổ\x00" "\x05" /* 'Ổ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ẩ\x00" "\x05" /* 'Ẩ' 5 */ + "i\x00" "\x08" /* 'i' 8 */ + "ỉ\x00" "\x05" /* 'ỉ' 5 */ + "k\x00" "\x07" /* 'k' 7 */ + "ƙ\x00" "\x04" /* 'ƙ' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ɲ\x00" "\x04" /* 'ɲ' 4 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ở\x00" "\x05" /* 'Ở' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ở\x00" "\x05" /* 'ở' 5 */ + "q\x00" "\x07" /* 'q' 7 */ + "ʠ\x00" "\x04" /* 'ʠ' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̉\x00" "\x04" /* '̉' 4 */ + "V\x00" "\x07" /* 'V' 7 */ + "Ʋ\x00" "\x04" /* 'Ʋ' 4 */ + "Ocircumflex\x00" "\x12" /* 'Ocircumflex' 18 */ + "Ổ\x00" "\x05" /* 'Ổ' 5 */ + "ocircumflex\x00" "\x12" /* 'ocircumflex' 18 */ + "ổ\x00" "\x05" /* 'ổ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ủ\x00" "\x05" /* 'ủ' 5 */ + "z\x00" "\x07" /* 'z' 7 */ + "ȥ\x00" "\x04" /* 'ȥ' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ɠ\x00" "\x04" /* 'Ɠ' 4 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ẻ\x00" "\x05" /* 'Ẻ' 5 */ + "Y\x00" "\x08" /* 'Y' 8 */ + "Ỷ\x00" "\x05" /* 'Ỷ' 5 */ + "f\x00" "\x07" /* 'f' 7 */ + "ƒ\x00" "\x04" /* 'ƒ' 4 */ + "d\x00" "\x07" /* 'd' 7 */ + "ɗ\x00" "\x04" /* 'ɗ' 4 */ + "dead_greek\x00" "\x13" /* 'dead_greek' 19 */ + "U\x00" "\x07" /* 'U' 7 */ + "ϒ\x00" "\x04" /* 'ϒ' 4 */ + "D\x00" "\x07" /* 'D' 7 */ + "Ɗ\x00" "\x04" /* 'Ɗ' 4 */ + "Abreve\x00" "\x0d" /* 'Abreve' 13 */ + "Ẳ\x00" "\x05" /* 'Ẳ' 5 */ + "ecircumflex\x00" "\x12" /* 'ecircumflex' 18 */ + "ể\x00" "\x05" /* 'ể' 5 */ + "w\x00" "\x08" /* 'w' 8 */ + "ⱳ\x00" "\x05" /* 'ⱳ' 5 */ + "p\x00" "\x07" /* 'p' 7 */ + "ƥ\x00" "\x04" /* 'ƥ' 4 */ + "v\x00" "\x07" /* 'v' 7 */ + "ʋ\x00" "\x04" /* 'ʋ' 4 */ + "P\x00" "\x07" /* 'P' 7 */ + "Ƥ\x00" "\x04" /* 'Ƥ' 4 */ + "M\x00" "\x08" /* 'M' 8 */ + "Ɱ\x00" "\x05" /* 'Ɱ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ỏ\x00" "\x05" /* 'Ỏ' 5 */ + "abreve\x00" "\x0d" /* 'abreve' 13 */ + "ẳ\x00" "\x05" /* 'ẳ' 5 */ + "m\x00" "\x07" /* 'm' 7 */ + "ɱ\x00" "\x04" /* 'ɱ' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ɼ\x00" "\x04" /* 'ɼ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ʂ\x00" "\x04" /* 'ʂ' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ȥ\x00" "\x04" /* 'Ȥ' 4 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ả\x00" "\x05" /* 'Ả' 5 */ + "c\x00" "\x07" /* 'c' 7 */ + "ƈ\x00" "\x04" /* 'ƈ' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ƭ\x00" "\x04" /* 'Ƭ' 4 */ + "dead_hook\x00" "\x0f" /* 'dead_hook' 15 */ + "̉\x00" "\x04" /* '̉' 4 */ + "K\x00" "\x07" /* 'K' 7 */ + "Ƙ\x00" "\x04" /* 'Ƙ' 4 */ + "B\x00" "\x07" /* 'B' 7 */ + "Ɓ\x00" "\x04" /* 'Ɓ' 4 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ử\x00" "\x05" /* 'Ử' 5 */ + "h\x00" "\x07" /* 'h' 7 */ + "ɦ\x00" "\x04" /* 'ɦ' 4 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ỉ\x00" "\x05" /* 'Ỉ' 5 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ɲ\x00" "\x04" /* 'Ɲ' 4 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ủ\x00" "\x05" /* 'Ủ' 5 */ + "dead_belowbreve\x00" "\x21" /* 'dead_belowbreve' 33 */ + "H\x00" "\x08" /* 'H' 8 */ + "Ḫ\x00" "\x05" /* 'Ḫ' 5 */ + "h\x00" "\x08" /* 'h' 8 */ + "ḫ\x00" "\x05" /* 'ḫ' 5 */ + "dead_cedilla\x00" "\x81\x68" /* 'dead_cedilla' 360 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḝ\x00" "\x05" /* 'ḝ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḝ\x00" "\x05" /* 'Ḝ' 5 */ + "g\x00" "\x07" /* 'g' 7 */ + "ģ\x00" "\x04" /* 'ģ' 4 */ + "dead_currency\x00" "\x1f" /* 'dead_currency' 31 */ + "C\x00" "\x08" /* 'C' 8 */ + "₵\x00" "\x05" /* '₵' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "₵\x00" "\x05" /* '₵' 5 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ç\x00" "\x04" /* 'Ç' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ȩ\x00" "\x04" /* 'ȩ' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ļ\x00" "\x04" /* 'ļ' 4 */ + "t\x00" "\x07" /* 't' 7 */ + "ţ\x00" "\x04" /* 'ţ' 4 */ + "ColonSign\x00" "\x10" /* 'ColonSign' 16 */ + "₵\x00" "\x05" /* '₵' 5 */ + "space\x00" "\x0b" /* 'space' 11 */ + "¸\x00" "\x04" /* '¸' 4 */ + "k\x00" "\x07" /* 'k' 7 */ + "ķ\x00" "\x04" /* 'ķ' 4 */ + "n\x00" "\x07" /* 'n' 7 */ + "ņ\x00" "\x04" /* 'ņ' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̧\x00" "\x04" /* '̧' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ģ\x00" "\x04" /* 'Ģ' 4 */ + "H\x00" "\x08" /* 'H' 8 */ + "Ḩ\x00" "\x05" /* 'Ḩ' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ȩ\x00" "\x04" /* 'Ȩ' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Ş\x00" "\x04" /* 'Ş' 4 */ + "Cacute\x00" "\x0d" /* 'Cacute' 13 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "d\x00" "\x08" /* 'd' 8 */ + "ḑ\x00" "\x05" /* 'ḑ' 5 */ + "D\x00" "\x08" /* 'D' 8 */ + "Ḑ\x00" "\x05" /* 'Ḑ' 5 */ + "cent\x00" "\x0b" /* 'cent' 11 */ + "₵\x00" "\x05" /* '₵' 5 */ + "cacute\x00" "\x0d" /* 'cacute' 13 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "r\x00" "\x07" /* 'r' 7 */ + "ŗ\x00" "\x04" /* 'ŗ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ş\x00" "\x04" /* 'ş' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ŗ\x00" "\x04" /* 'Ŗ' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "ç\x00" "\x04" /* 'ç' 4 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ļ\x00" "\x04" /* 'Ļ' 4 */ + "T\x00" "\x07" /* 'T' 7 */ + "Ţ\x00" "\x04" /* 'Ţ' 4 */ + "K\x00" "\x07" /* 'K' 7 */ + "Ķ\x00" "\x04" /* 'Ķ' 4 */ + "dead_cedilla\x00" "\x12" /* 'dead_cedilla' 18 */ + "¸\x00" "\x04" /* '¸' 4 */ + "dead_acute\x00" "\x1c" /* 'dead_acute' 28 */ + "C\x00" "\x08" /* 'C' 8 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "h\x00" "\x08" /* 'h' 8 */ + "ḩ\x00" "\x05" /* 'ḩ' 5 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ņ\x00" "\x04" /* 'Ņ' 4 */ + "dead_inverted_breve\x00" "\x69" /* 'dead_inverted_breve' 105 */ + "a\x00" "\x07" /* 'a' 7 */ + "ȃ\x00" "\x04" /* 'ȃ' 4 */ + "e\x00" "\x07" /* 'e' 7 */ + "ȇ\x00" "\x04" /* 'ȇ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȏ\x00" "\x04" /* 'ȏ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ȋ\x00" "\x04" /* 'ȋ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ȗ\x00" "\x04" /* 'ȗ' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ȇ\x00" "\x04" /* 'Ȇ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȏ\x00" "\x04" /* 'Ȏ' 4 */ + "r\x00" "\x07" /* 'r' 7 */ + "ȓ\x00" "\x04" /* 'ȓ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ȃ\x00" "\x04" /* 'Ȃ' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ȓ\x00" "\x04" /* 'Ȓ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ȋ\x00" "\x04" /* 'Ȋ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ȗ\x00" "\x04" /* 'Ȗ' 4 */ + "dead_diaeresis\x00" "\x84\xb3" /* 'dead_diaeresis' 1203 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẅ\x00" "\x05" /* 'Ẅ' 5 */ + "a\x00" "\x07" /* 'a' 7 */ + "ä\x00" "\x04" /* 'ä' 4 */ + "Greek_IOTA\x00" "\x10" /* 'Greek_IOTA' 16 */ + "Ϊ\x00" "\x04" /* 'Ϊ' 4 */ + "dead_grave\x00" "\x1a" /* 'dead_grave' 26 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǜ\x00" "\x04" /* 'ǜ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǜ\x00" "\x04" /* 'Ǜ' 4 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ϊ\x00" "\x04" /* 'ϊ' 4 */ + "Umacron\x00" "\x0e" /* 'Umacron' 14 */ + "Ṻ\x00" "\x05" /* 'Ṻ' 5 */ + "Cyrillic_ZE\x00" "\x11" /* 'Cyrillic_ZE' 17 */ + "Ӟ\x00" "\x04" /* 'Ӟ' 4 */ + "dead_belowdiaeresis\x00" "\x21" /* 'dead_belowdiaeresis' 33 */ + "equal\x00" "\x0c" /* 'equal' 12 */ + "⩷\x00" "\x05" /* '⩷' 5 */ + "e\x00" "\x07" /* 'e' 7 */ + "ë\x00" "\x04" /* 'ë' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ö\x00" "\x04" /* 'ö' 4 */ + "iacute\x00" "\x0d" /* 'iacute' 13 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "Cyrillic_ze\x00" "\x11" /* 'Cyrillic_ze' 17 */ + "ӟ\x00" "\x04" /* 'ӟ' 4 */ + "t\x00" "\x08" /* 't' 8 */ + "ẗ\x00" "\x05" /* 'ẗ' 5 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ϋ\x00" "\x04" /* 'ϋ' 4 */ + "space\x00" "\x0a" /* 'space' 10 */ + "\"\x00" "\x03" /* '"' 3 */ + "dead_macron\x00" "\x39" /* 'dead_macron' 57 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "o\x00" "\x07" /* 'o' 7 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṻ\x00" "\x05" /* 'ṻ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṻ\x00" "\x05" /* 'Ṻ' 5 */ + "Cyrillic_I\x00" "\x10" /* 'Cyrillic_I' 16 */ + "Ӥ\x00" "\x04" /* 'Ӥ' 4 */ + "y\x00" "\x07" /* 'y' 7 */ + "ÿ\x00" "\x04" /* 'ÿ' 4 */ + "Multi_key\x00" "\x5b" /* 'Multi_key' 91 */ + "underscore\x00" "\x1c" /* 'underscore' 28 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṻ\x00" "\x05" /* 'ṻ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṻ\x00" "\x05" /* 'Ṻ' 5 */ + "macron\x00" "\x18" /* 'macron' 24 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṻ\x00" "\x05" /* 'ṻ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṻ\x00" "\x05" /* 'Ṻ' 5 */ + "asciitilde\x00" "\x1c" /* 'asciitilde' 28 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṏ\x00" "\x05" /* 'ṏ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṏ\x00" "\x05" /* 'Ṏ' 5 */ + "Cyrillic_O\x00" "\x10" /* 'Cyrillic_O' 16 */ + "Ӧ\x00" "\x04" /* 'Ӧ' 4 */ + "i\x00" "\x07" /* 'i' 7 */ + "ï\x00" "\x04" /* 'ï' 4 */ + "Ukrainian_I\x00" "\x11" /* 'Ukrainian_I' 17 */ + "Ї\x00" "\x04" /* 'Ї' 4 */ + "dead_caron\x00" "\x1a" /* 'dead_caron' 26 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǚ\x00" "\x04" /* 'ǚ' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǚ\x00" "\x04" /* 'Ǚ' 4 */ + "dead_tilde\x00" "\x1c" /* 'dead_tilde' 28 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṏ\x00" "\x05" /* 'ṏ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṏ\x00" "\x05" /* 'Ṏ' 5 */ + "Cyrillic_che\x00" "\x12" /* 'Cyrillic_che' 18 */ + "ӵ\x00" "\x04" /* 'ӵ' 4 */ + "Uacute\x00" "\x0c" /* 'Uacute' 12 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "Cyrillic_a\x00" "\x10" /* 'Cyrillic_a' 16 */ + "ӓ\x00" "\x04" /* 'ӓ' 4 */ + "Ugrave\x00" "\x0c" /* 'Ugrave' 12 */ + "Ǜ\x00" "\x04" /* 'Ǜ' 4 */ + "x\x00" "\x08" /* 'x' 8 */ + "ẍ\x00" "\x05" /* 'ẍ' 5 */ + "amacron\x00" "\x0d" /* 'amacron' 13 */ + "ǟ\x00" "\x04" /* 'ǟ' 4 */ + "Cyrillic_U\x00" "\x10" /* 'Cyrillic_U' 16 */ + "Ӱ\x00" "\x04" /* 'Ӱ' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "̈\x00" "\x04" /* '̈' 4 */ + "omacron\x00" "\x0d" /* 'omacron' 13 */ + "ȫ\x00" "\x04" /* 'ȫ' 4 */ + "uacute\x00" "\x0c" /* 'uacute' 12 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "u\x00" "\x07" /* 'u' 7 */ + "ü\x00" "\x04" /* 'ü' 4 */ + "otilde\x00" "\x0d" /* 'otilde' 13 */ + "ṏ\x00" "\x05" /* 'ṏ' 5 */ + "Iacute\x00" "\x0d" /* 'Iacute' 13 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "H\x00" "\x08" /* 'H' 8 */ + "Ḧ\x00" "\x05" /* 'Ḧ' 5 */ + "Cyrillic_YERU\x00" "\x13" /* 'Cyrillic_YERU' 19 */ + "Ӹ\x00" "\x04" /* 'Ӹ' 4 */ + "Cyrillic_ie\x00" "\x11" /* 'Cyrillic_ie' 17 */ + "ё\x00" "\x04" /* 'ё' 4 */ + "E\x00" "\x07" /* 'E' 7 */ + "Ë\x00" "\x04" /* 'Ë' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ÿ\x00" "\x04" /* 'Ÿ' 4 */ + "Cyrillic_i\x00" "\x10" /* 'Cyrillic_i' 16 */ + "ӥ\x00" "\x04" /* 'ӥ' 4 */ + "Otilde\x00" "\x0d" /* 'Otilde' 13 */ + "Ṏ\x00" "\x05" /* 'Ṏ' 5 */ + "Cyrillic_zhe\x00" "\x12" /* 'Cyrillic_zhe' 18 */ + "ӝ\x00" "\x04" /* 'ӝ' 4 */ + "umacron\x00" "\x0e" /* 'umacron' 14 */ + "ṻ\x00" "\x05" /* 'ṻ' 5 */ + "Cyrillic_yeru\x00" "\x13" /* 'Cyrillic_yeru' 19 */ + "ӹ\x00" "\x04" /* 'ӹ' 4 */ + "acute\x00" "\x0b" /* 'acute' 11 */ + "̈́\x00" "\x04" /* '̈́' 4 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẅ\x00" "\x05" /* 'ẅ' 5 */ + "Cyrillic_CHE\x00" "\x12" /* 'Cyrillic_CHE' 18 */ + "Ӵ\x00" "\x04" /* 'Ӵ' 4 */ + "Cyrillic_o\x00" "\x10" /* 'Cyrillic_o' 16 */ + "ӧ\x00" "\x04" /* 'ӧ' 4 */ + "Ukrainian_i\x00" "\x11" /* 'Ukrainian_i' 17 */ + "ї\x00" "\x04" /* 'ї' 4 */ + "Cyrillic_E\x00" "\x10" /* 'Cyrillic_E' 16 */ + "Ӭ\x00" "\x04" /* 'Ӭ' 4 */ + "apostrophe\x00" "\x10" /* 'apostrophe' 16 */ + "̈́\x00" "\x04" /* '̈́' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ö\x00" "\x04" /* 'Ö' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ä\x00" "\x04" /* 'Ä' 4 */ + "Cyrillic_A\x00" "\x10" /* 'Cyrillic_A' 16 */ + "Ӓ\x00" "\x04" /* 'Ӓ' 4 */ + "ugrave\x00" "\x0c" /* 'ugrave' 12 */ + "ǜ\x00" "\x04" /* 'ǜ' 4 */ + "Omacron\x00" "\x0d" /* 'Omacron' 13 */ + "Ȫ\x00" "\x04" /* 'Ȫ' 4 */ + "Cyrillic_ZHE\x00" "\x12" /* 'Cyrillic_ZHE' 18 */ + "Ӝ\x00" "\x04" /* 'Ӝ' 4 */ + "Cyrillic_IE\x00" "\x11" /* 'Cyrillic_IE' 17 */ + "Ё\x00" "\x04" /* 'Ё' 4 */ + "dead_diaeresis\x00" "\x14" /* 'dead_diaeresis' 20 */ + "¨\x00" "\x04" /* '¨' 4 */ + "Amacron\x00" "\x0d" /* 'Amacron' 13 */ + "Ǟ\x00" "\x04" /* 'Ǟ' 4 */ + "Cyrillic_e\x00" "\x10" /* 'Cyrillic_e' 16 */ + "ӭ\x00" "\x04" /* 'ӭ' 4 */ + "dead_acute\x00" "\x58" /* 'dead_acute' 88 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + "΅\x00" "\x04" /* '΅' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "X\x00" "\x08" /* 'X' 8 */ + "Ẍ\x00" "\x05" /* 'Ẍ' 5 */ + "h\x00" "\x08" /* 'h' 8 */ + "ḧ\x00" "\x05" /* 'ḧ' 5 */ + "I\x00" "\x07" /* 'I' 7 */ + "Ï\x00" "\x04" /* 'Ï' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ü\x00" "\x04" /* 'Ü' 4 */ + "Cyrillic_u\x00" "\x10" /* 'Cyrillic_u' 16 */ + "ӱ\x00" "\x04" /* 'ӱ' 4 */ + "Greek_UPSILON\x00" "\x13" /* 'Greek_UPSILON' 19 */ + "Ϋ\x00" "\x04" /* 'Ϋ' 4 */ + "dead_acute\x00" "\x8c\xfd" /* 'dead_acute' 3325 */ + "W\x00" "\x08" /* 'W' 8 */ + "Ẃ\x00" "\x05" /* 'Ẃ' 5 */ + "dead_breve\x00" "\x1c" /* 'dead_breve' 28 */ + "a\x00" "\x08" /* 'a' 8 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "g\x00" "\x07" /* 'g' 7 */ + "ǵ\x00" "\x04" /* 'ǵ' 4 */ + "a\x00" "\x07" /* 'a' 7 */ + "á\x00" "\x04" /* 'á' 4 */ + "Greek_IOTA\x00" "\x10" /* 'Greek_IOTA' 16 */ + "Ί\x00" "\x04" /* 'Ί' 4 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ί\x00" "\x04" /* 'ί' 4 */ + "dead_horn\x00" "\x2b" /* 'dead_horn' 43 */ + "o\x00" "\x08" /* 'o' 8 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "dead_circumflex\x00" "\x41" /* 'dead_circumflex' 65 */ + "a\x00" "\x08" /* 'a' 8 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "Greek_OMICRON\x00" "\x13" /* 'Greek_OMICRON' 19 */ + "Ό\x00" "\x04" /* 'Ό' 4 */ + "Acircumflex\x00" "\x12" /* 'Acircumflex' 18 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "C\x00" "\x07" /* 'C' 7 */ + "Ć\x00" "\x04" /* 'Ć' 4 */ + "Cyrillic_er\x00" "\x13" /* 'Cyrillic_er' 19 */ + "р́\x00" "\x06" /* 'р́' 6 */ + "e\x00" "\x07" /* 'e' 7 */ + "é\x00" "\x04" /* 'é' 4 */ + "Utilde\x00" "\x0d" /* 'Utilde' 13 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "o\x00" "\x07" /* 'o' 7 */ + "ó\x00" "\x04" /* 'ó' 4 */ + "l\x00" "\x07" /* 'l' 7 */ + "ĺ\x00" "\x04" /* 'ĺ' 4 */ + "Udiaeresis\x00" "\x10" /* 'Udiaeresis' 16 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ύ\x00" "\x04" /* 'ύ' 4 */ + "uhorn\x00" "\x0c" /* 'uhorn' 12 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "space\x00" "\x0a" /* 'space' 10 */ + "'\x00" "\x03" /* ''' 3 */ + "dead_macron\x00" "\x2d" /* 'dead_macron' 45 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "acircumflex\x00" "\x12" /* 'acircumflex' 18 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "Ecircumflex\x00" "\x12" /* 'Ecircumflex' 18 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "Cyrillic_I\x00" "\x12" /* 'Cyrillic_I' 18 */ + "И́\x00" "\x06" /* 'И́' 6 */ + "y\x00" "\x07" /* 'y' 7 */ + "ý\x00" "\x04" /* 'ý' 4 */ + "Multi_key\x00" "\x83\xd8" /* 'Multi_key' 984 */ + "KP_Divide\x00" "\x19" /* 'KP_Divide' 25 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "o\x00" "\x11" /* 'o' 17 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǻ\x00" "\x04" /* 'ǻ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǻ\x00" "\x04" /* 'Ǻ' 4 */ + "b\x00" "\x13" /* 'b' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "parenright\x00" "\x80\xfb" /* 'parenright' 251 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἴ\x00" "\x05" /* 'Ἴ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἴ\x00" "\x05" /* 'ἴ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὄ\x00" "\x05" /* 'Ὄ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὔ\x00" "\x05" /* 'ὔ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἔ\x00" "\x05" /* 'ἔ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἄ\x00" "\x05" /* 'Ἄ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὄ\x00" "\x05" /* 'ὄ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἤ\x00" "\x05" /* 'ἤ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἄ\x00" "\x05" /* 'ἄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἤ\x00" "\x05" /* 'Ἤ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἔ\x00" "\x05" /* 'Ἔ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὤ\x00" "\x05" /* 'ὤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὤ\x00" "\x05" /* 'Ὤ' 5 */ + "quotedbl\x00" "\x4b" /* 'quotedbl' 75 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "plus\x00" "\x26" /* 'plus' 38 */ + "o\x00" "\x08" /* 'o' 8 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ứ\x00" "\x05" /* 'ứ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "cedilla\x00" "\x19" /* 'cedilla' 25 */ + "C\x00" "\x08" /* 'C' 8 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "underscore\x00" "\x2c" /* 'underscore' 44 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "macron\x00" "\x28" /* 'macron' 40 */ + "e\x00" "\x08" /* 'e' 8 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "comma\x00" "\x17" /* 'comma' 23 */ + "C\x00" "\x08" /* 'C' 8 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "asciitilde\x00" "\x2c" /* 'asciitilde' 44 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "slash\x00" "\x15" /* 'slash' 21 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "parenleft\x00" "\x81\x0e" /* 'parenleft' 270 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἵ\x00" "\x05" /* 'Ἵ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἵ\x00" "\x05" /* 'ἵ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὅ\x00" "\x05" /* 'Ὅ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὕ\x00" "\x05" /* 'ὕ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἕ\x00" "\x05" /* 'ἕ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἅ\x00" "\x05" /* 'Ἅ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὅ\x00" "\x05" /* 'ὅ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἥ\x00" "\x05" /* 'ἥ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἅ\x00" "\x05" /* 'ἅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἥ\x00" "\x05" /* 'Ἥ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἕ\x00" "\x05" /* 'Ἕ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὥ\x00" "\x05" /* 'ὥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὥ\x00" "\x05" /* 'Ὥ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὕ\x00" "\x05" /* 'Ὕ' 5 */ + "U\x00" "\x13" /* 'U' 19 */ + "a\x00" "\x08" /* 'a' 8 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "asciicircum\x00" "\x3d" /* 'asciicircum' 61 */ + "a\x00" "\x08" /* 'a' 8 */ + "ấ\x00" "\x05" /* 'ấ' 5 */ + "e\x00" "\x08" /* 'e' 8 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "o\x00" "\x08" /* 'o' 8 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "E\x00" "\x08" /* 'E' 8 */ + "Ế\x00" "\x05" /* 'Ế' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ấ\x00" "\x05" /* 'Ấ' 5 */ + "idiaeresis\x00" "\x11" /* 'idiaeresis' 17 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "Cyrillic_O\x00" "\x12" /* 'Cyrillic_O' 18 */ + "О́\x00" "\x06" /* 'О́' 6 */ + "i\x00" "\x07" /* 'i' 7 */ + "í\x00" "\x04" /* 'í' 4 */ + "k\x00" "\x08" /* 'k' 8 */ + "ḱ\x00" "\x05" /* 'ḱ' 5 */ + "n\x00" "\x07" /* 'n' 7 */ + "ń\x00" "\x04" /* 'ń' 4 */ + "ccedilla\x00" "\x0f" /* 'ccedilla' 15 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "Cyrillic_GHE\x00" "\x12" /* 'Cyrillic_GHE' 18 */ + "Ѓ\x00" "\x04" /* 'Ѓ' 4 */ + "dead_tilde\x00" "\x2c" /* 'dead_tilde' 44 */ + "o\x00" "\x08" /* 'o' 8 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "u\x00" "\x08" /* 'u' 8 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "O\x00" "\x08" /* 'O' 8 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "U\x00" "\x08" /* 'U' 8 */ + "Ṹ\x00" "\x05" /* 'Ṹ' 5 */ + "Cyrillic_a\x00" "\x12" /* 'Cyrillic_a' 18 */ + "а́\x00" "\x06" /* 'а́' 6 */ + "Ohorn\x00" "\x0c" /* 'Ohorn' 12 */ + "Ớ\x00" "\x05" /* 'Ớ' 5 */ + "ohorn\x00" "\x0c" /* 'ohorn' 12 */ + "ớ\x00" "\x05" /* 'ớ' 5 */ + "sabovedot\x00" "\x10" /* 'sabovedot' 16 */ + "ṥ\x00" "\x05" /* 'ṥ' 5 */ + "Cyrillic_ER\x00" "\x13" /* 'Cyrillic_ER' 19 */ + "Р́\x00" "\x06" /* 'Р́' 6 */ + "Greek_epsilon\x00" "\x13" /* 'Greek_epsilon' 19 */ + "έ\x00" "\x04" /* 'έ' 4 */ + "Cyrillic_KA\x00" "\x11" /* 'Cyrillic_KA' 17 */ + "Ќ\x00" "\x04" /* 'Ќ' 4 */ + "Cyrillic_U\x00" "\x12" /* 'Cyrillic_U' 18 */ + "У́\x00" "\x06" /* 'У́' 6 */ + "dead_abovering\x00" "\x1e" /* 'dead_abovering' 30 */ + "a\x00" "\x07" /* 'a' 7 */ + "ǻ\x00" "\x04" /* 'ǻ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Ǻ\x00" "\x04" /* 'Ǻ' 4 */ + "nobreakspace\x00" "\x12" /* 'nobreakspace' 18 */ + "́\x00" "\x04" /* '́' 4 */ + "V\x00" "\x07" /* 'V' 7 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "Ocircumflex\x00" "\x12" /* 'Ocircumflex' 18 */ + "Ố\x00" "\x05" /* 'Ố' 5 */ + "AE\x00" "\x08" /* 'AE' 8 */ + "Ǽ\x00" "\x04" /* 'Ǽ' 4 */ + "omacron\x00" "\x0e" /* 'omacron' 14 */ + "ṓ\x00" "\x05" /* 'ṓ' 5 */ + "ocircumflex\x00" "\x12" /* 'ocircumflex' 18 */ + "ố\x00" "\x05" /* 'ố' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ú\x00" "\x04" /* 'ú' 4 */ + "z\x00" "\x07" /* 'z' 7 */ + "ź\x00" "\x04" /* 'ź' 4 */ + "G\x00" "\x07" /* 'G' 7 */ + "Ǵ\x00" "\x04" /* 'Ǵ' 4 */ + "Greek_ALPHA\x00" "\x11" /* 'Greek_ALPHA' 17 */ + "Ά\x00" "\x04" /* 'Ά' 4 */ + "otilde\x00" "\x0d" /* 'otilde' 13 */ + "ṍ\x00" "\x05" /* 'ṍ' 5 */ + "utilde\x00" "\x0d" /* 'utilde' 13 */ + "ṹ\x00" "\x05" /* 'ṹ' 5 */ + "Cyrillic_ie\x00" "\x13" /* 'Cyrillic_ie' 19 */ + "е́\x00" "\x06" /* 'е́' 6 */ + "emacron\x00" "\x0e" /* 'emacron' 14 */ + "ḗ\x00" "\x05" /* 'ḗ' 5 */ + "E\x00" "\x07" /* 'E' 7 */ + "É\x00" "\x04" /* 'É' 4 */ + "S\x00" "\x07" /* 'S' 7 */ + "Ś\x00" "\x04" /* 'Ś' 4 */ + "Greek_iotadieresis\x00" "\x18" /* 'Greek_iotadieresis' 24 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Y\x00" "\x07" /* 'Y' 7 */ + "Ý\x00" "\x04" /* 'Ý' 4 */ + "Cyrillic_i\x00" "\x12" /* 'Cyrillic_i' 18 */ + "и́\x00" "\x06" /* 'и́' 6 */ + "dead_dasia\x00" "\x81\x0f" /* 'dead_dasia' 271 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἵ\x00" "\x05" /* 'Ἵ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἵ\x00" "\x05" /* 'ἵ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὅ\x00" "\x05" /* 'Ὅ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὕ\x00" "\x05" /* 'ὕ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἕ\x00" "\x05" /* 'ἕ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἅ\x00" "\x05" /* 'Ἅ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὅ\x00" "\x05" /* 'ὅ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἥ\x00" "\x05" /* 'ἥ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἅ\x00" "\x05" /* 'ἅ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἥ\x00" "\x05" /* 'Ἥ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἕ\x00" "\x05" /* 'Ἕ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὥ\x00" "\x05" /* 'ὥ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὥ\x00" "\x05" /* 'Ὥ' 5 */ + "Greek_UPSILON\x00" "\x14" /* 'Greek_UPSILON' 20 */ + "Ὕ\x00" "\x05" /* 'Ὕ' 5 */ + "Greek_upsilondieresis\x00" "\x1b" /* 'Greek_upsilondieresis' 27 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "Greek_omicron\x00" "\x13" /* 'Greek_omicron' 19 */ + "ό\x00" "\x04" /* 'ό' 4 */ + "Greek_eta\x00" "\x0f" /* 'Greek_eta' 15 */ + "ή\x00" "\x04" /* 'ή' 4 */ + "Otilde\x00" "\x0d" /* 'Otilde' 13 */ + "Ṍ\x00" "\x05" /* 'Ṍ' 5 */ + "Cyrillic_ka\x00" "\x11" /* 'Cyrillic_ka' 17 */ + "ќ\x00" "\x04" /* 'ќ' 4 */ + "Aring\x00" "\x0b" /* 'Aring' 11 */ + "Ǻ\x00" "\x04" /* 'Ǻ' 4 */ + "Abreve\x00" "\x0d" /* 'Abreve' 13 */ + "Ắ\x00" "\x05" /* 'Ắ' 5 */ + "dead_psili\x00" "\x80\xfb" /* 'dead_psili' 251 */ + "Greek_IOTA\x00" "\x11" /* 'Greek_IOTA' 17 */ + "Ἴ\x00" "\x05" /* 'Ἴ' 5 */ + "Greek_iota\x00" "\x11" /* 'Greek_iota' 17 */ + "ἴ\x00" "\x05" /* 'ἴ' 5 */ + "Greek_OMICRON\x00" "\x14" /* 'Greek_OMICRON' 20 */ + "Ὄ\x00" "\x05" /* 'Ὄ' 5 */ + "Greek_upsilon\x00" "\x14" /* 'Greek_upsilon' 20 */ + "ὔ\x00" "\x05" /* 'ὔ' 5 */ + "Greek_epsilon\x00" "\x14" /* 'Greek_epsilon' 20 */ + "ἔ\x00" "\x05" /* 'ἔ' 5 */ + "Greek_ALPHA\x00" "\x12" /* 'Greek_ALPHA' 18 */ + "Ἄ\x00" "\x05" /* 'Ἄ' 5 */ + "Greek_omicron\x00" "\x14" /* 'Greek_omicron' 20 */ + "ὄ\x00" "\x05" /* 'ὄ' 5 */ + "Greek_eta\x00" "\x10" /* 'Greek_eta' 16 */ + "ἤ\x00" "\x05" /* 'ἤ' 5 */ + "Greek_alpha\x00" "\x12" /* 'Greek_alpha' 18 */ + "ἄ\x00" "\x05" /* 'ἄ' 5 */ + "Greek_ETA\x00" "\x10" /* 'Greek_ETA' 16 */ + "Ἤ\x00" "\x05" /* 'Ἤ' 5 */ + "Greek_EPSILON\x00" "\x14" /* 'Greek_EPSILON' 20 */ + "Ἔ\x00" "\x05" /* 'Ἔ' 5 */ + "Greek_omega\x00" "\x12" /* 'Greek_omega' 18 */ + "ὤ\x00" "\x05" /* 'ὤ' 5 */ + "Greek_OMEGA\x00" "\x12" /* 'Greek_OMEGA' 18 */ + "Ὤ\x00" "\x05" /* 'Ὤ' 5 */ + "Greek_alpha\x00" "\x11" /* 'Greek_alpha' 17 */ + "ά\x00" "\x04" /* 'ά' 4 */ + "ecircumflex\x00" "\x12" /* 'ecircumflex' 18 */ + "ế\x00" "\x05" /* 'ế' 5 */ + "dead_abovedot\x00" "\x1f" /* 'dead_abovedot' 31 */ + "S\x00" "\x08" /* 'S' 8 */ + "Ṥ\x00" "\x05" /* 'Ṥ' 5 */ + "s\x00" "\x08" /* 's' 8 */ + "ṥ\x00" "\x05" /* 'ṥ' 5 */ + "w\x00" "\x08" /* 'w' 8 */ + "ẃ\x00" "\x05" /* 'ẃ' 5 */ + "Greek_ETA\x00" "\x0f" /* 'Greek_ETA' 15 */ + "Ή\x00" "\x04" /* 'Ή' 4 */ + "Cyrillic_o\x00" "\x12" /* 'Cyrillic_o' 18 */ + "о́\x00" "\x06" /* 'о́' 6 */ + "Emacron\x00" "\x0e" /* 'Emacron' 14 */ + "Ḗ\x00" "\x05" /* 'Ḗ' 5 */ + "Ooblique\x00" "\x0e" /* 'Ooblique' 14 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "p\x00" "\x08" /* 'p' 8 */ + "ṕ\x00" "\x05" /* 'ṕ' 5 */ + "v\x00" "\x07" /* 'v' 7 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "P\x00" "\x08" /* 'P' 8 */ + "Ṕ\x00" "\x05" /* 'Ṕ' 5 */ + "M\x00" "\x08" /* 'M' 8 */ + "Ḿ\x00" "\x05" /* 'Ḿ' 5 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ó\x00" "\x04" /* 'Ó' 4 */ + "abreve\x00" "\x0d" /* 'abreve' 13 */ + "ắ\x00" "\x05" /* 'ắ' 5 */ + "m\x00" "\x08" /* 'm' 8 */ + "ḿ\x00" "\x05" /* 'ḿ' 5 */ + "r\x00" "\x07" /* 'r' 7 */ + "ŕ\x00" "\x04" /* 'ŕ' 4 */ + "s\x00" "\x07" /* 's' 7 */ + "ś\x00" "\x04" /* 'ś' 4 */ + "Z\x00" "\x07" /* 'Z' 7 */ + "Ź\x00" "\x04" /* 'Ź' 4 */ + "dead_stroke\x00" "\x1b" /* 'dead_stroke' 27 */ + "o\x00" "\x07" /* 'o' 7 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "O\x00" "\x07" /* 'O' 7 */ + "Ǿ\x00" "\x04" /* 'Ǿ' 4 */ + "A\x00" "\x07" /* 'A' 7 */ + "Á\x00" "\x04" /* 'Á' 4 */ + "R\x00" "\x07" /* 'R' 7 */ + "Ŕ\x00" "\x04" /* 'Ŕ' 4 */ + "c\x00" "\x07" /* 'c' 7 */ + "ć\x00" "\x04" /* 'ć' 4 */ + "Idiaeresis\x00" "\x11" /* 'Idiaeresis' 17 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "L\x00" "\x07" /* 'L' 7 */ + "Ĺ\x00" "\x04" /* 'Ĺ' 4 */ + "Greek_EPSILON\x00" "\x13" /* 'Greek_EPSILON' 19 */ + "Έ\x00" "\x04" /* 'Έ' 4 */ + "Cyrillic_A\x00" "\x12" /* 'Cyrillic_A' 18 */ + "А́\x00" "\x06" /* 'А́' 6 */ + "Ccedilla\x00" "\x0f" /* 'Ccedilla' 15 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "aring\x00" "\x0b" /* 'aring' 11 */ + "ǻ\x00" "\x04" /* 'ǻ' 4 */ + "K\x00" "\x08" /* 'K' 8 */ + "Ḱ\x00" "\x05" /* 'Ḱ' 5 */ + "Omacron\x00" "\x0e" /* 'Omacron' 14 */ + "Ṓ\x00" "\x05" /* 'Ṓ' 5 */ + "Cyrillic_IE\x00" "\x13" /* 'Cyrillic_IE' 19 */ + "Е́\x00" "\x06" /* 'Е́' 6 */ + "Sabovedot\x00" "\x10" /* 'Sabovedot' 16 */ + "Ṥ\x00" "\x05" /* 'Ṥ' 5 */ + "dead_cedilla\x00" "\x1e" /* 'dead_cedilla' 30 */ + "C\x00" "\x08" /* 'C' 8 */ + "Ḉ\x00" "\x05" /* 'Ḉ' 5 */ + "c\x00" "\x08" /* 'c' 8 */ + "ḉ\x00" "\x05" /* 'ḉ' 5 */ + "Greek_omega\x00" "\x11" /* 'Greek_omega' 17 */ + "ώ\x00" "\x04" /* 'ώ' 4 */ + "dead_diaeresis\x00" "\x5c" /* 'dead_diaeresis' 92 */ + "Greek_iota\x00" "\x10" /* 'Greek_iota' 16 */ + "ΐ\x00" "\x04" /* 'ΐ' 4 */ + "Greek_upsilon\x00" "\x13" /* 'Greek_upsilon' 19 */ + "ΰ\x00" "\x04" /* 'ΰ' 4 */ + "space\x00" "\x0b" /* 'space' 11 */ + "΅\x00" "\x04" /* '΅' 4 */ + "i\x00" "\x08" /* 'i' 8 */ + "ḯ\x00" "\x05" /* 'ḯ' 5 */ + "u\x00" "\x07" /* 'u' 7 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "I\x00" "\x08" /* 'I' 8 */ + "Ḯ\x00" "\x05" /* 'Ḯ' 5 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ǘ\x00" "\x04" /* 'Ǘ' 4 */ + "Uhorn\x00" "\x0c" /* 'Uhorn' 12 */ + "Ứ\x00" "\x05" /* 'Ứ' 5 */ + "Greek_OMEGA\x00" "\x11" /* 'Greek_OMEGA' 17 */ + "Ώ\x00" "\x04" /* 'Ώ' 4 */ + "dead_acute\x00" "\x10" /* 'dead_acute' 16 */ + "´\x00" "\x04" /* '´' 4 */ + "oslash\x00" "\x0c" /* 'oslash' 12 */ + "ǿ\x00" "\x04" /* 'ǿ' 4 */ + "Cyrillic_ghe\x00" "\x12" /* 'Cyrillic_ghe' 18 */ + "ѓ\x00" "\x04" /* 'ѓ' 4 */ + "udiaeresis\x00" "\x10" /* 'udiaeresis' 16 */ + "ǘ\x00" "\x04" /* 'ǘ' 4 */ + "I\x00" "\x07" /* 'I' 7 */ + "Í\x00" "\x04" /* 'Í' 4 */ + "N\x00" "\x07" /* 'N' 7 */ + "Ń\x00" "\x04" /* 'Ń' 4 */ + "U\x00" "\x07" /* 'U' 7 */ + "Ú\x00" "\x04" /* 'Ú' 4 */ + "Cyrillic_u\x00" "\x12" /* 'Cyrillic_u' 18 */ + "у́\x00" "\x06" /* 'у́' 6 */ + "ae\x00" "\x08" /* 'ae' 8 */ + "ǽ\x00" "\x04" /* 'ǽ' 4 */ + "Greek_UPSILON\x00" "\x13" /* 'Greek_UPSILON' 19 */ + "Ύ\x00" "\x04" /* 'Ύ' 4 */ + "dead_belowmacron\x00" "\x80\x9b" /* 'dead_belowmacron' 155 */ + "l\x00" "\x08" /* 'l' 8 */ + "ḻ\x00" "\x05" /* 'ḻ' 5 */ + "t\x00" "\x08" /* 't' 8 */ + "ṯ\x00" "\x05" /* 'ṯ' 5 */ + "b\x00" "\x08" /* 'b' 8 */ + "ḇ\x00" "\x05" /* 'ḇ' 5 */ + "k\x00" "\x08" /* 'k' 8 */ + "ḵ\x00" "\x05" /* 'ḵ' 5 */ + "n\x00" "\x08" /* 'n' 8 */ + "ṉ\x00" "\x05" /* 'ṉ' 5 */ + "z\x00" "\x08" /* 'z' 8 */ + "ẕ\x00" "\x05" /* 'ẕ' 5 */ + "d\x00" "\x08" /* 'd' 8 */ + "ḏ\x00" "\x05" /* 'ḏ' 5 */ + "D\x00" "\x08" /* 'D' 8 */ + "Ḏ\x00" "\x05" /* 'Ḏ' 5 */ + "r\x00" "\x08" /* 'r' 8 */ + "ṟ\x00" "\x05" /* 'ṟ' 5 */ + "Z\x00" "\x08" /* 'Z' 8 */ + "Ẕ\x00" "\x05" /* 'Ẕ' 5 */ + "R\x00" "\x08" /* 'R' 8 */ + "Ṟ\x00" "\x05" /* 'Ṟ' 5 */ + "L\x00" "\x08" /* 'L' 8 */ + "Ḻ\x00" "\x05" /* 'Ḻ' 5 */ + "T\x00" "\x08" /* 'T' 8 */ + "Ṯ\x00" "\x05" /* 'Ṯ' 5 */ + "K\x00" "\x08" /* 'K' 8 */ + "Ḵ\x00" "\x05" /* 'Ḵ' 5 */ + "B\x00" "\x08" /* 'B' 8 */ + "Ḇ\x00" "\x05" /* 'Ḇ' 5 */ + "h\x00" "\x08" /* 'h' 8 */ + "ẖ\x00" "\x05" /* 'ẖ' 5 */ + "N\x00" "\x08" /* 'N' 8 */ + "Ṉ\x00" "\x05" /* 'Ṉ' 5 */ + "dead_belowring\x00" "\x2a" /* 'dead_belowring' 42 */ + "a\x00" "\x08" /* 'a' 8 */ + "ḁ\x00" "\x05" /* 'ḁ' 5 */ + "bar\x00" "\x0a" /* 'bar' 10 */ + "⫰\x00" "\x05" /* '⫰' 5 */ + "A\x00" "\x08" /* 'A' 8 */ + "Ḁ\x00" "\x05" /* 'Ḁ' 5 */ +/* end marker - 4 0 bytes */ +"\x00\x00\x00\x00"; diff --git a/src/lib/ecore_input_evas/ecore_input_evas.c b/src/lib/ecore_input_evas/ecore_input_evas.c index 8ac41aa..6b499a3 100644 --- a/src/lib/ecore_input_evas/ecore_input_evas.c +++ b/src/lib/ecore_input_evas/ecore_input_evas.c @@ -25,10 +25,186 @@ struct _Ecore_Input_Window int ignore_event; }; +typedef enum _Ecore_Input_State { + ECORE_INPUT_NONE = 0, + ECORE_INPUT_DOWN, + ECORE_INPUT_MOVE, + ECORE_INPUT_UP +} Ecore_Input_State; + +typedef struct _Ecore_Input_Last Ecore_Event_Last; +struct _Ecore_Input_Last +{ + Ecore_Event_Mouse_Button *ev; + Ecore_Timer *timer; + + unsigned int device; + unsigned int buttons; + Ecore_Input_State state; + + Eina_Bool faked : 1; +}; + static int _ecore_event_evas_init_count = 0; static Ecore_Event_Handler *ecore_event_evas_handlers[8]; static Eina_Hash *_window_hash = NULL; +static Eina_List *_last_events = NULL; +static double _last_events_timeout = 0.5; +static Eina_Bool _last_events_enable = EINA_FALSE; + +static Eina_Bool _ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, + Ecore_Event_Press press, + Eina_Bool faked); + +static Ecore_Event_Last * +_ecore_event_evas_lookup(unsigned int device, unsigned int buttons, Eina_Bool create_new) +{ + Ecore_Event_Last *eel; + Eina_List *l; + + //the number of last event is small, simple check is ok. + EINA_LIST_FOREACH(_last_events, l, eel) + if ((eel->device == device) && (eel->buttons == buttons)) + return eel; + if (!create_new) return NULL; + eel = malloc(sizeof (Ecore_Event_Last)); + if (!eel) return NULL; + + eel->timer = NULL; + eel->ev = NULL; + eel->device = device; + eel->buttons = buttons; + eel->state = ECORE_INPUT_NONE; + eel->faked = EINA_FALSE; + + _last_events = eina_list_append(_last_events, eel); + return eel; +} + +static Eina_Bool +_ecore_event_evas_push_fake(void *data) +{ + Ecore_Event_Last *eel = data; + + switch (eel->state) + { + case ECORE_INPUT_NONE: + case ECORE_INPUT_UP: + /* should not happen */ + break; + case ECORE_INPUT_DOWN: + /* use the saved Ecore_Event */ + /* No up event since timeout started ... */ + case ECORE_INPUT_MOVE: + /* No up event since timeout started ... */ + _ecore_event_evas_mouse_button(eel->ev, ECORE_UP, EINA_TRUE); + eel->faked = EINA_TRUE; + break; + } + + free(eel->ev); + eel->ev = NULL; + eel->timer = NULL; + return EINA_FALSE; +} + +static void +_ecore_event_evas_push_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press press) +{ + Ecore_Event_Last *eel; + + if (!_last_events_enable) return ; + + eel = _ecore_event_evas_lookup(e->multi.device, e->buttons, EINA_TRUE); + if (!eel) return ; + + switch (eel->state) + { + case ECORE_INPUT_NONE: + goto fine; + case ECORE_INPUT_DOWN: + if (press == ECORE_UP) + goto fine; + + /* press == ECORE_DOWN => emit a faked UP then */ + _ecore_event_evas_mouse_button(e, ECORE_UP, EINA_TRUE); + break; + case ECORE_INPUT_MOVE: + if (press == ECORE_UP) + goto fine; + + /* FIXME: handle fake button up and push for more delay here */ + + /* press == ECORE_DOWN */ + _ecore_event_evas_mouse_button(e, ECORE_DOWN, EINA_TRUE); + break; + case ECORE_INPUT_UP: + if (press == ECORE_DOWN) + goto fine; + + /* press == ECORE_UP */ + _ecore_event_evas_mouse_button(e, ECORE_UP, EINA_TRUE); + break; + } + + fine: + eel->state = (press == ECORE_DOWN) ? ECORE_INPUT_DOWN : ECORE_INPUT_UP; + if (_last_events_timeout) + { + if (eel->timer) ecore_timer_del(eel->timer); + eel->timer = NULL; + if (press == ECORE_DOWN) + { + /* Save the Ecore_Event somehow */ + if (!eel->ev) eel->ev = malloc(sizeof (Ecore_Event_Mouse_Button)); + if (!eel->ev) return ; + memcpy(eel->ev, e, sizeof (Ecore_Event_Mouse_Button)); + eel->timer = ecore_timer_add(_last_events_timeout, _ecore_event_evas_push_fake, eel); + } + else + { + free(eel->ev); + eel->ev = NULL; + } + } +} + +static void +_ecore_event_evas_push_mouse_move(Ecore_Event_Mouse_Move *e) +{ + Ecore_Event_Last *eel; + Eina_List *l; + + if (!_last_events_enable) return ; + + EINA_LIST_FOREACH(_last_events, l, eel) + switch (eel->state) + { + case ECORE_INPUT_NONE: + case ECORE_INPUT_UP: + /* none or up and moving, sounds fine to me */ + break; + case ECORE_INPUT_DOWN: + case ECORE_INPUT_MOVE: + /* Down and moving, let's see */ + if (eel->ev) + { + /* Add some delay to the timer */ + ecore_timer_reset(eel->timer); + /* Update position */ + eel->ev->x = e->x; + eel->ev->y = e->y; + eel->ev->root.x = e->root.x; + eel->ev->root.y = e->root.y; + eel->state = ECORE_INPUT_MOVE; + break; + } + /* FIXME: Timer did expire, do something maybe */ + break; + } +} + EAPI void ecore_event_evas_modifier_lock_update(Evas *e, unsigned int modifiers) { @@ -163,8 +339,9 @@ _ecore_event_evas_key(Ecore_Event_Key *e, Ecore_Event_Press press) } static Eina_Bool -_ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press press) +_ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press press, Eina_Bool faked) { + Ecore_Event_Last *eel; Ecore_Input_Window *lookup; Evas_Button_Flags flags = EVAS_BUTTON_NONE; @@ -172,6 +349,22 @@ _ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press pr if (!lookup) return ECORE_CALLBACK_PASS_ON; if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK; if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK; + DBG("\tButtonEvent:ecore_event_evas press(%d), device(%d), button(%d), fake(%d)", press, e->multi.device, e->buttons, faked); + if (_last_events_enable) + { + //error handle: if ecore up without ecore down + if (press == ECORE_UP) + { + eel = _ecore_event_evas_lookup(e->multi.device, e->buttons, EINA_FALSE); + if ((!eel) || (eel->state == ECORE_INPUT_UP)) + { + INF("ButtonEvent: up event without down event."); + return ECORE_CALLBACK_PASS_ON; + } + } + } + + if (!faked) _ecore_event_evas_push_mouse_button(e, press); if (e->multi.device == 0) { ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers); @@ -233,6 +426,7 @@ ecore_event_evas_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *ev if (!lookup) return ECORE_CALLBACK_PASS_ON; if (e->multi.device == 0) { + _ecore_event_evas_push_mouse_move(e); ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers); if (lookup->move_mouse) lookup->move_mouse(lookup->window, e->x, e->y, e->timestamp); @@ -262,13 +456,13 @@ ecore_event_evas_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *ev EAPI Eina_Bool ecore_event_evas_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event) { - return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_DOWN); + return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_DOWN, EINA_FALSE); } EAPI Eina_Bool ecore_event_evas_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event) { - return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_UP); + return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_UP, EINA_FALSE); } static Eina_Bool @@ -384,6 +578,16 @@ ecore_event_evas_init(void) _window_hash = eina_hash_pointer_new(free); + if (getenv("ECORE_INPUT_FIX")) + { + const char *tmp; + _last_events_enable = EINA_TRUE; + + tmp = getenv("ECORE_INPUT_TIMEOUT_FIX"); + if (tmp) + _last_events_timeout = ((double) atoi(tmp)) / 60; + } + return _ecore_event_evas_init_count; shutdown_ecore: diff --git a/src/lib/ecore_ipc/Ecore_Ipc.h b/src/lib/ecore_ipc/Ecore_Ipc.h index f77870f..da5380e 100644 --- a/src/lib/ecore_ipc/Ecore_Ipc.h +++ b/src/lib/ecore_ipc/Ecore_Ipc.h @@ -30,6 +30,7 @@ #endif /** + * @internal * @file Ecore_Ipc.h * @brief Ecore inter-process communication functions. */ @@ -256,7 +257,7 @@ struct _Ecore_Ipc_Event_Server_Del struct _Ecore_Ipc_Event_Client_Data { Ecore_Ipc_Client *client; - /* FIXME: this needs to become an ipc message */ + /* FIXME: This needs to become an IPC message */ int major; int minor; int ref; @@ -269,7 +270,7 @@ struct _Ecore_Ipc_Event_Client_Data struct _Ecore_Ipc_Event_Server_Data { Ecore_Ipc_Server *server; - /* FIXME: this needs to become an ipc message */ + /* FIXME: This needs to become an IPC message */ int major; int minor; int ref; @@ -289,16 +290,16 @@ EAPI extern int ECORE_IPC_EVENT_SERVER_DATA; EAPI int ecore_ipc_init(void); EAPI int ecore_ipc_shutdown(void); -/* FIXME: need to add protocol type parameter */ +/* FIXME: Need to add protocol type parameter */ EAPI Ecore_Ipc_Server *ecore_ipc_server_add(Ecore_Ipc_Type type, const char *name, int port, const void *data); -/* FIXME: need to add protocol type parameter */ +/* FIXME: Need to add protocol type parameter */ EAPI Ecore_Ipc_Server *ecore_ipc_server_connect(Ecore_Ipc_Type type, char *name, int port, const void *data); EAPI void *ecore_ipc_server_del(Ecore_Ipc_Server *svr); EAPI void *ecore_ipc_server_data_get(Ecore_Ipc_Server *svr); EAPI Eina_Bool ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr); EAPI Eina_List *ecore_ipc_server_clients_get(Ecore_Ipc_Server *svr); -/* FIXME: this needs to become an ipc message */ +/* FIXME: This needs to become an IPC message */ EAPI int ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int ref_to, int response, const void *data, int size); EAPI void ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char reject_excess_clients); EAPI void ecore_ipc_server_data_size_max_set(Ecore_Ipc_Server *srv, int size); @@ -306,7 +307,7 @@ EAPI int ecore_ipc_server_data_size_max_get(Ecore_Ipc_Server *srv) EAPI const char *ecore_ipc_server_ip_get(Ecore_Ipc_Server *svr); EAPI void ecore_ipc_server_flush(Ecore_Ipc_Server *svr); -/* FIXME: this needs to become an ipc message */ +/* FIXME: This needs to become an IPC message */ EAPI int ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int ref_to, int response, const void *data, int size); EAPI Ecore_Ipc_Server *ecore_ipc_client_server_get(Ecore_Ipc_Client *cl); EAPI void *ecore_ipc_client_del(Ecore_Ipc_Client *cl); @@ -318,8 +319,8 @@ EAPI const char *ecore_ipc_client_ip_get(Ecore_Ipc_Client *cl); EAPI void ecore_ipc_client_flush(Ecore_Ipc_Client *cl); EAPI int ecore_ipc_ssl_available_get(void); -/* FIXME: need to add a callback to "ok" large ipc messages greater than */ -/* a certain size (seurity/DOS attack safety) */ +/* FIXME: Need to add a callback to "ok" large IPC messages greater than */ +/* a certain size (security/DOS attack safety) */ #ifdef __cplusplus } diff --git a/src/lib/ecore_ipc/ecore_ipc.c b/src/lib/ecore_ipc/ecore_ipc.c index 0cddad2..2033b6a 100644 --- a/src/lib/ecore_ipc/ecore_ipc.c +++ b/src/lib/ecore_ipc/ecore_ipc.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #ifdef HAVE_NETINET_IN_H @@ -357,6 +383,8 @@ ecore_ipc_server_add(Ecore_Ipc_Type compl_type, const char *name, int port, cons Ecore_Ipc_Type type; Ecore_Con_Type extra = 0; + if (!name) return NULL; + svr = calloc(1, sizeof(Ecore_Ipc_Server)); if (!svr) return NULL; type = compl_type; @@ -538,7 +566,7 @@ ecore_ipc_server_clients_get(Ecore_Ipc_Server *svr) "ecore_ipc_server_clients_get"); return NULL; } - return svr->client_list; + return svr->clients; } #define SVENC(_member) \ @@ -1044,7 +1072,6 @@ _ecore_ipc_event_client_add(void *data __UNUSED__, int ev_type __UNUSED__, void cl->max_buf_size = 32 * 1024; ecore_con_client_data_set(cl->client, (void *)cl); svr->clients = eina_list_append(svr->clients, cl); - svr->client_list = eina_list_append(svr->client_list, cl); if (!cl->delete_me) { Ecore_Ipc_Event_Client_Add *e2; @@ -1081,7 +1108,6 @@ _ecore_ipc_event_client_del(void *data __UNUSED__, int ev_type __UNUSED__, void { Ecore_Ipc_Event_Client_Del *e2; - svr->client_list = eina_list_remove(svr->client_list, cl); if (!cl->delete_me) { e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Del)); @@ -1491,19 +1517,36 @@ _ecore_ipc_event_server_data(void *data __UNUSED__, int ev_type __UNUSED__, void e2->response = msg.response; e2->size = msg.size; e2->data = buf; + if (buf == svr->buf) + { + svr->buf = NULL; + svr->buf_size = 0; + } + buf = NULL; ecore_event_add(ECORE_IPC_EVENT_SERVER_DATA, e2, _ecore_ipc_event_server_data_free, NULL); } + else + { + free(buf); + buf = NULL; + } + } + else + { + free(buf); + buf = NULL; } } svr->prev.i = msg; offset += (s + msg.size); - if (svr->buf_size == offset) + if ((svr->buf_size == offset) && ((svr->buf) || (buf))) { - free(svr->buf); + if (svr->buf) free(svr->buf); svr->buf = NULL; svr->buf_size = 0; + if (buf) free(buf); return ECORE_CALLBACK_CANCEL; } goto redo; diff --git a/src/lib/ecore_ipc/ecore_ipc_private.h b/src/lib/ecore_ipc/ecore_ipc_private.h index bbf3d7b..bedaab1 100644 --- a/src/lib/ecore_ipc/ecore_ipc_private.h +++ b/src/lib/ecore_ipc/ecore_ipc_private.h @@ -89,7 +89,6 @@ struct _Ecore_Ipc_Server ECORE_MAGIC; Ecore_Con_Server *server; Eina_List *clients; - Eina_List *client_list; void *data; unsigned char *buf; int buf_size; diff --git a/src/lib/ecore_psl1ght/Ecore_Psl1ght.h b/src/lib/ecore_psl1ght/Ecore_Psl1ght.h index c6300fd..312595a 100644 --- a/src/lib/ecore_psl1ght/Ecore_Psl1ght.h +++ b/src/lib/ecore_psl1ght/Ecore_Psl1ght.h @@ -16,6 +16,7 @@ #endif /** + * @internal * @file * @brief Ecore PSL1GHT system functions. */ @@ -54,46 +55,46 @@ struct _Ecore_Psl1ght_Event_Key_Modifiers /** PSL1GHT Key Modifier event */ typedef struct _Ecore_Psl1ght_Event_Key_Down Ecore_Psl1ght_Event_Key_Down; struct _Ecore_Psl1ght_Event_Key_Down /** PSL1GHT Key Down event */ { - const char *keyname; /**< The name of the key that was pressed */ - const char *keycompose; /**< The UTF-8 string conversion if any */ + const char *keyname; /**< The name of the key that is pressed */ + const char *keycompose; /**< The UTF-8 string conversion, if any */ unsigned int time; }; typedef struct _Ecore_Psl1ght_Event_Key_Up Ecore_Psl1ght_Event_Key_Up; struct _Ecore_Psl1ght_Event_Key_Up /** PSL1GHT Key Up event */ { - const char *keyname; /**< The name of the key that was released */ - const char *keycompose; /**< The UTF-8 string conversion if any */ + const char *keyname; /**< The name of the key that is released */ + const char *keycompose; /**< The UTF-8 string conversion, if any */ unsigned int time; }; typedef struct _Ecore_Psl1ght_Event_Mouse_Button_Down Ecore_Psl1ght_Event_Mouse_Button_Down; struct _Ecore_Psl1ght_Event_Mouse_Button_Down /** PSL1GHT Mouse Down event */ { - int button; /**< Mouse button that was pressed (1 - 32) */ - int x; /**< Mouse co-ordinates when mouse button was pressed */ - int y; /**< Mouse co-ordinates when mouse button was pressed */ - int double_click : 1; /**< Set if click was a double click */ - int triple_click : 1; /**< Set if click was a triple click */ + int button; /**< Mouse button that is pressed (1 - 32) */ + int x; /**< Mouse co-ordinates when the mouse button is pressed */ + int y; /**< Mouse co-ordinates when the mouse button is pressed */ + int double_click : 1; /**< Set if click is a double click */ + int triple_click : 1; /**< Set if click is a triple click */ unsigned int time; }; typedef struct _Ecore_Psl1ght_Event_Mouse_Button_Up Ecore_Psl1ght_Event_Mouse_Button_Up; struct _Ecore_Psl1ght_Event_Mouse_Button_Up /** PSL1GHT Mouse Up event */ { - int button; /**< Mouse button that was released (1 - 32) */ - int x; /**< Mouse co-ordinates when mouse button was raised */ - int y; /**< Mouse co-ordinates when mouse button was raised */ - int double_click : 1; /**< Set if click was a double click */ - int triple_click : 1; /**< Set if click was a triple click */ + int button; /**< Mouse button that is released (1 - 32) */ + int x; /**< Mouse co-ordinates when the mouse button is raised */ + int y; /**< Mouse co-ordinates when the mouse button is raised */ + int double_click : 1; /**< Set if click is a double click */ + int triple_click : 1; /**< Set if click is a triple click */ unsigned int time; }; typedef struct _Ecore_Psl1ght_Event_Mouse_Move Ecore_Psl1ght_Event_Mouse_Move; struct _Ecore_Psl1ght_Event_Mouse_Move /** PSL1GHT Mouse Move event */ { - int x; /**< Mouse co-ordinates where the mouse cursor moved to */ - int y; /**< Mouse co-ordinates where the mouse cursor moved to */ + int x; /**< Mouse co-ordinates of the location where the mouse cursor moved to */ + int y; /**< Mouse co-ordinates of the location where the mouse cursor moved to */ unsigned int time; }; @@ -101,8 +102,8 @@ typedef struct _Ecore_Psl1ght_Event_Mouse_Wheel Ecore_Psl1ght_Event_Mouse_Wheel; struct _Ecore_Psl1ght_Event_Mouse_Wheel /** PSL1GHT Mouse Wheel event */ { int x, y; - int direction; /* 0 = vertical, 1 = horizontal */ - int wheel; /* value 1 (left/up), -1 (right/down) */ + int direction; /* @c 0 = vertical, @c 1 = horizontal */ + int wheel; /* values are @c 1 (left/up), @c -1 (right/down) */ unsigned int time; }; diff --git a/src/lib/ecore_sdl/Ecore_Sdl.h b/src/lib/ecore_sdl/Ecore_Sdl.h index 359e974..17f03d5 100644 --- a/src/lib/ecore_sdl/Ecore_Sdl.h +++ b/src/lib/ecore_sdl/Ecore_Sdl.h @@ -28,6 +28,7 @@ #endif /* ! _WIN32 */ /** + * @internal * @file * @brief Ecore SDL system functions. */ @@ -44,46 +45,46 @@ EAPI extern int ECORE_SDL_EVENT_EXPOSE; typedef struct _Ecore_Sdl_Event_Key_Down Ecore_Sdl_Event_Key_Down; struct _Ecore_Sdl_Event_Key_Down /** SDL Key Down event */ { - const char *keyname; /**< The name of the key that was pressed */ - const char *keycompose; /**< The UTF-8 string conversion if any */ + const char *keyname; /**< The name of the key that is pressed */ + const char *keycompose; /**< The UTF-8 string conversion, if any */ unsigned int time; }; typedef struct _Ecore_Sdl_Event_Key_Up Ecore_Sdl_Event_Key_Up; struct _Ecore_Sdl_Event_Key_Up /** SDL Key Up event */ { - const char *keyname; /**< The name of the key that was released */ - const char *keycompose; /**< The UTF-8 string conversion if any */ + const char *keyname; /**< The name of the key that is released */ + const char *keycompose; /**< The UTF-8 string conversion, if any */ unsigned int time; }; typedef struct _Ecore_Sdl_Event_Mouse_Button_Down Ecore_Sdl_Event_Mouse_Button_Down; struct _Ecore_Sdl_Event_Mouse_Button_Down /** SDL Mouse Down event */ { - int button; /**< Mouse button that was pressed (1 - 32) */ - int x; /**< Mouse co-ordinates when mouse button was pressed */ - int y; /**< Mouse co-ordinates when mouse button was pressed */ - int double_click : 1; /**< Set if click was a double click */ - int triple_click : 1; /**< Set if click was a triple click */ + int button; /**< Mouse button that is pressed (1 - 32) */ + int x; /**< Mouse co-ordinates when the mouse button is pressed */ + int y; /**< Mouse co-ordinates when the mouse button is pressed */ + int double_click : 1; /**< Set if click is a double click */ + int triple_click : 1; /**< Set if click is a triple click */ unsigned int time; }; typedef struct _Ecore_Sdl_Event_Mouse_Button_Up Ecore_Sdl_Event_Mouse_Button_Up; struct _Ecore_Sdl_Event_Mouse_Button_Up /** SDL Mouse Up event */ { - int button; /**< Mouse button that was released (1 - 32) */ - int x; /**< Mouse co-ordinates when mouse button was raised */ - int y; /**< Mouse co-ordinates when mouse button was raised */ - int double_click : 1; /**< Set if click was a double click */ - int triple_click : 1; /**< Set if click was a triple click */ + int button; /**< Mouse button that is released (1 - 32) */ + int x; /**< Mouse co-ordinates when the mouse button is raised */ + int y; /**< Mouse co-ordinates when the mouse button is raised */ + int double_click : 1; /**< Set if click is a double click */ + int triple_click : 1; /**< Set if click is a triple click */ unsigned int time; }; typedef struct _Ecore_Sdl_Event_Mouse_Move Ecore_Sdl_Event_Mouse_Move; struct _Ecore_Sdl_Event_Mouse_Move /** SDL Mouse Move event */ { - int x; /**< Mouse co-ordinates where the mouse cursor moved to */ - int y; /**< Mouse co-ordinates where the mouse cursor moved to */ + int x; /**< Mouse co-ordinates of the location where the mouse cursor moved to */ + int y; /**< Mouse co-ordinates of the location where the mouse cursor moved to */ unsigned int time; }; @@ -91,8 +92,8 @@ typedef struct _Ecore_Sdl_Event_Mouse_Wheel Ecore_Sdl_Event_Mouse_Wheel; struct _Ecore_Sdl_Event_Mouse_Wheel /** SDL Mouse Wheel event */ { int x,y; - int direction; /* 0 = vertical, 1 = horizontal */ - int wheel; /* value 1 (left/up), -1 (right/down) */ + int direction; /**< @c 0 = vertical, @c 1 = horizontal */ + int wheel; /**< values are @c 1 (left/up), @c -1 (right/down) */ unsigned int time; }; diff --git a/src/lib/ecore_sdl/ecore_sdl.c b/src/lib/ecore_sdl/ecore_sdl.c index 3f28216..452300d 100644 --- a/src/lib/ecore_sdl/ecore_sdl.c +++ b/src/lib/ecore_sdl/ecore_sdl.c @@ -4,15 +4,13 @@ #include -#include "Eina.h" +#include +#include +#include +#include #include "Ecore_Sdl.h" -#include "Ecore_Input.h" -#include "Ecore.h" -#include "ecore_sdl_private.h" -#include "ecore_private.h" #include "Ecore_Sdl_Keys.h" - -#include +#include "ecore_sdl_private.h" int _ecore_sdl_log_dom = -1; diff --git a/src/lib/ecore_wayland/Ecore_Wayland.h b/src/lib/ecore_wayland/Ecore_Wayland.h index 5ff3293..193dde6 100644 --- a/src/lib/ecore_wayland/Ecore_Wayland.h +++ b/src/lib/ecore_wayland/Ecore_Wayland.h @@ -1,10 +1,10 @@ #ifndef _ECORE_WAYLAND_H_ # define _ECORE_WAYLAND_H_ -/* - * Wayland supoprt is considered experimental as wayland itself is still - * unstable and liable to change core protocol. If you use this api, it is - * possible it will break in future, until this notice is removed. +/** + * Wayland support is considered experimental as Wayland itself is still + * unstable and liable to change in the core protocol. If you use this API, it is + * possible that it may break in the future, until this notice is removed. */ # include @@ -35,6 +35,7 @@ typedef struct _Ecore_Wl_Input Ecore_Wl_Input; # ifndef _ECORE_WAYLAND_WINDOW_PREDEF typedef struct _Ecore_Wl_Window Ecore_Wl_Window; # endif +typedef struct _Ecore_Wl_Dnd Ecore_Wl_Dnd; /** @since 1.7 */ typedef struct _Ecore_Wl_Dnd_Source Ecore_Wl_Dnd_Source; typedef struct _Ecore_Wl_Dnd_Target Ecore_Wl_Dnd_Target; @@ -47,6 +48,8 @@ typedef struct _Ecore_Wl_Event_Dnd_Enter Ecore_Wl_Event_Dnd_Enter; typedef struct _Ecore_Wl_Event_Dnd_Position Ecore_Wl_Event_Dnd_Position; typedef struct _Ecore_Wl_Event_Dnd_Leave Ecore_Wl_Event_Dnd_Leave; typedef struct _Ecore_Wl_Event_Dnd_Drop Ecore_Wl_Event_Dnd_Drop; +typedef struct _Ecore_Wl_Event_Data_Source_Send Ecore_Wl_Event_Data_Source_Send; /** @since 1.7 */ +typedef struct _Ecore_Wl_Event_Selection_Data_Ready Ecore_Wl_Event_Selection_Data_Ready; /** @since 1.7 */ typedef struct _Ecore_Wl_Event_Interfaces_Bound Ecore_Wl_Event_Interfaces_Bound; enum _Ecore_Wl_Window_Type @@ -121,6 +124,7 @@ struct _Ecore_Wl_Input struct wl_keyboard *keyboard; struct wl_touch *touch; + const char *cursor_name; struct wl_surface *cursor_surface; struct wl_callback *cursor_frame_cb; @@ -142,6 +146,7 @@ struct _Ecore_Wl_Input Ecore_Wl_Dnd_Source *drag_source; Ecore_Wl_Dnd_Source *selection_source; + Ecore_Wl_Dnd *dnd; /** @since 1.7 */ struct { @@ -151,6 +156,13 @@ struct _Ecore_Wl_Input xkb_mod_mask_t alt_mask; xkb_mod_mask_t shift_mask; } xkb; + + struct + { + Ecore_Fd_Handler *hdlr; + int timerfd; + unsigned int sym, key, time; + } repeat; }; struct _Ecore_Wl_Window @@ -175,6 +187,7 @@ struct _Ecore_Wl_Window /* Eina_Bool redraw_scheduled : 1; */ /* Eina_Bool resize_scheduled : 1; */ + Eina_Bool alpha : 1; Eina_Bool transparent : 1; Eina_Bool moving : 1; Eina_Bool resizing : 1; @@ -185,6 +198,11 @@ struct _Ecore_Wl_Window Ecore_Wl_Input *pointer_device; Ecore_Wl_Input *keyboard_device; + Eina_Bool frame_pending; + struct wl_callback *frame_callback; + /* FIXME: Ideally we should record the cursor name for this window + * so that we can compare and avoid unnecessary cursor set calls to Wayland */ + void *data; }; @@ -269,6 +287,21 @@ struct _Ecore_Wl_Event_Dnd_Drop } position; }; +/** @since 1.7 */ +struct _Ecore_Wl_Event_Data_Source_Send +{ + char *type; + int fd; +}; + +/** @since 1.7 */ +struct _Ecore_Wl_Event_Selection_Data_Ready +{ + char *data; + int len; + Eina_Bool done; +}; + struct _Ecore_Wl_Event_Interfaces_Bound { Eina_Bool compositor : 1; @@ -277,12 +310,13 @@ struct _Ecore_Wl_Event_Interfaces_Bound }; /** + * @internal * @file - * @brief Ecore functions for dealing with the Wayland window system + * @brief Ecore functions for dealing with the Wayland window system. * - * Ecore_Wl provides a wrapper and convenience functions for using the - * Wayland window system. Function groups for this part of the library - * include the following: + * @remarks Ecore_Wl provides wrapper and convenience functions for using the + * Wayland window system. Function groups for this part of the library + * include the following: * * @li @ref Ecore_Wl_Init_Group * @li @ref Ecore_Wl_Display_Group @@ -299,6 +333,10 @@ EAPI extern int ECORE_WL_EVENT_DND_ENTER; EAPI extern int ECORE_WL_EVENT_DND_POSITION; EAPI extern int ECORE_WL_EVENT_DND_LEAVE; EAPI extern int ECORE_WL_EVENT_DND_DROP; +EAPI extern int ECORE_WL_EVENT_DATA_SOURCE_TARGET; /** @since 1.7 */ +EAPI extern int ECORE_WL_EVENT_DATA_SOURCE_SEND; /** @since 1.7 */ +EAPI extern int ECORE_WL_EVENT_DATA_SOURCE_CANCELLED; /** @since 1.7 */ +EAPI extern int ECORE_WL_EVENT_SELECTION_DATA_READY; /** @since 1.7 */ EAPI extern int ECORE_WL_EVENT_INTERFACES_BOUND; EAPI int ecore_wl_init(const char *name); @@ -344,4 +382,15 @@ EAPI void ecore_wl_window_cursor_from_name_set(Ecore_Wl_Window *win, const char EAPI void ecore_wl_window_cursor_default_restore(Ecore_Wl_Window *win); EAPI void ecore_wl_window_parent_set(Ecore_Wl_Window *win, Ecore_Wl_Window *parent); +/** + * @internal + * @since 1.7 + */ +EAPI Eina_Bool ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered); + +EAPI Eina_Bool ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type); +EAPI Ecore_Wl_Dnd *ecore_wl_dnd_get(); +EAPI Eina_Bool ecore_wl_dnd_start_drag(); +EAPI Eina_Bool ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd); + #endif diff --git a/src/lib/ecore_wayland/ecore_wl.c b/src/lib/ecore_wayland/ecore_wl.c index c21c102..1902808 100644 --- a/src/lib/ecore_wayland/ecore_wl.c +++ b/src/lib/ecore_wayland/ecore_wl.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include "ecore_wl_private.h" @@ -29,6 +55,10 @@ EAPI int ECORE_WL_EVENT_DND_ENTER = 0; EAPI int ECORE_WL_EVENT_DND_POSITION = 0; EAPI int ECORE_WL_EVENT_DND_LEAVE = 0; EAPI int ECORE_WL_EVENT_DND_DROP = 0; +EAPI int ECORE_WL_EVENT_DATA_SOURCE_TARGET = 0; +EAPI int ECORE_WL_EVENT_DATA_SOURCE_SEND = 0; +EAPI int ECORE_WL_EVENT_SELECTION_DATA_READY = 0; +EAPI int ECORE_WL_EVENT_DATA_SOURCE_CANCELLED = 0; EAPI int ECORE_WL_EVENT_INTERFACES_BOUND = 0; /** @@ -95,6 +125,10 @@ ecore_wl_init(const char *name) ECORE_WL_EVENT_DND_POSITION = ecore_event_type_new(); ECORE_WL_EVENT_DND_LEAVE = ecore_event_type_new(); ECORE_WL_EVENT_DND_DROP = ecore_event_type_new(); + ECORE_WL_EVENT_DATA_SOURCE_TARGET = ecore_event_type_new(); + ECORE_WL_EVENT_DATA_SOURCE_SEND = ecore_event_type_new(); + ECORE_WL_EVENT_SELECTION_DATA_READY = ecore_event_type_new(); + ECORE_WL_EVENT_DATA_SOURCE_CANCELLED = ecore_event_type_new(); ECORE_WL_EVENT_INTERFACES_BOUND = ecore_event_type_new(); } @@ -436,6 +470,9 @@ _ecore_wl_cb_handle_global(struct wl_display *disp, unsigned int id, const char else if (!strcmp(interface, "wl_shm")) { ewd->wl.shm = wl_display_bind(disp, id, &wl_shm_interface); + + /* FIXME: We should not hard-code a cursor size here, and we should + * also import the theme name from a config or env variable */ ewd->cursor_theme = wl_cursor_theme_load(NULL, 32, ewd->wl.shm); } else if (!strcmp(interface, "wl_data_device_manager")) @@ -479,3 +516,9 @@ _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd) return EINA_TRUE; } + +struct wl_data_source * +_ecore_wl_create_data_source(Ecore_Wl_Display *ewd) +{ + return wl_data_device_manager_create_data_source(ewd->wl.data_device_manager); +} diff --git a/src/lib/ecore_wayland/ecore_wl_dnd.c b/src/lib/ecore_wayland/ecore_wl_dnd.c index 164693f..e7c8f86 100644 --- a/src/lib/ecore_wayland/ecore_wl_dnd.c +++ b/src/lib/ecore_wayland/ecore_wl_dnd.c @@ -2,18 +2,162 @@ # include #endif +#include +#include #include "ecore_wl_private.h" +struct _dnd_task +{ + void *data; + Ecore_Fd_Cb cb; +}; + +struct _dnd_read_ctx +{ + int epoll_fd; + struct epoll_event *ep; +}; + /* local function prototypes */ static void _ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer __UNUSED__, const char *type); static void _ecore_wl_dnd_cb_enter_free(void *data __UNUSED__, void *event); +static void _ecore_wl_dnd_data_source_target(void *data, struct wl_data_source *source, const char *mime_type); +static void _ecore_wl_dnd_data_source_send(void *data, struct wl_data_source *source, const char *mime_type, int32_t fd); +static void _ecore_wl_dnd_data_source_cancelled(void *data, struct wl_data_source *source); +static void _ecore_wl_dnd_source_receive_data(Ecore_Wl_Dnd_Source *source, const char *type); + /* wayland listeners */ static const struct wl_data_offer_listener _ecore_wl_data_offer_listener = { _ecore_wl_dnd_offer, }; +static const struct wl_data_source_listener _ecore_wl_data_source_listener = +{ + _ecore_wl_dnd_data_source_target, + _ecore_wl_dnd_data_source_send, + _ecore_wl_dnd_data_source_cancelled +}; + +extern Ecore_Wl_Dnd *glb_dnd; + +EAPI Ecore_Wl_Dnd * +ecore_wl_dnd_get() +{ + return glb_dnd; +} + +EAPI Eina_Bool +ecore_wl_dnd_start_drag(Ecore_Wl_Dnd *dnd __UNUSED__) +{ + //TODO: + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered) +{ + char **p; + const char **type; + + dnd->data_source = _ecore_wl_create_data_source(dnd->ewd); + + /* free old types */ + if (dnd->types_offered.data) + { + wl_array_for_each(p, &dnd->types_offered) + free(*p); + wl_array_release(&dnd->types_offered); + wl_array_init(&dnd->types_offered); + } + + for (type = types_offered; *type; type++) + { + p = wl_array_add(&dnd->types_offered, sizeof(*p)); + *p = strdup(*type); + wl_data_source_offer(dnd->data_source, *p); + } + + wl_data_source_add_listener(dnd->data_source, &_ecore_wl_data_source_listener, dnd); + + _ecore_wl_input_set_selection(dnd->input, dnd->data_source); + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type) +{ + char **p; + Ecore_Wl_Input *input; + + input = dnd->input; + + if (!input->selection_source) return EINA_FALSE; + + wl_array_for_each(p, &input->selection_source->types) + if (strcmp(type, *p) == 0) break; + + if (!*p) return EINA_FALSE; + + _ecore_wl_dnd_source_receive_data(input->selection_source, type); + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd) +{ + Ecore_Wl_Input *input; + + input = dnd->input; + return (input->selection_source != NULL); +} + +/* local functions */ +static void +_ecore_wl_dnd_data_source_target(void *data __UNUSED__, struct wl_data_source *source __UNUSED__, const char *mime_type __UNUSED__) +{ + //TODO: +} + +static void +_ecore_wl_dnd_cb_data_source_send_free(void *data __UNUSED__, void *event) +{ + Ecore_Wl_Event_Data_Source_Send *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = event)) return; + + free(ev->type); + free(ev); +} + +static void +_ecore_wl_dnd_data_source_send(void *data, struct wl_data_source *source __UNUSED__, const char *mime_type, int32_t fd) +{ + Ecore_Wl_Event_Data_Source_Send *event; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!data) return; + + if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Data_Source_Send)))) return; + + event->type = strdup(mime_type); + event->fd = fd; + + ecore_event_add(ECORE_WL_EVENT_DATA_SOURCE_SEND, event, _ecore_wl_dnd_cb_data_source_send_free, NULL); +} + +static void +_ecore_wl_dnd_data_source_cancelled(void *data __UNUSED__, struct wl_data_source *source) +{ + wl_data_source_destroy(source); +} + void _ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device __UNUSED__, struct wl_data_offer *offer) { @@ -40,9 +184,10 @@ _ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device __UNUSED__, u LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!(input = data)) return; + if ((!(input = data)) || (!offer)) return; - input->drag_source = wl_data_offer_get_user_data(offer); + if (!(input->drag_source = wl_data_offer_get_user_data(offer))) + return; win = wl_surface_get_user_data(surface); // input->pointer_focus = win; @@ -53,7 +198,12 @@ _ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device __UNUSED__, u if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return; event->win = win->id; - event->source = input->drag_source->input->keyboard_focus->id; + if (input->drag_source->input) + { + if (input->drag_source->input->keyboard_focus) + event->source = input->drag_source->input->keyboard_focus->id; + } + event->position.x = wl_fixed_to_int(x); event->position.y = wl_fixed_to_int(y); event->num_types = input->drag_source->types.size; @@ -92,8 +242,17 @@ _ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device __UNUSED__, if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return; - event->win = input->drag_source->input->pointer_focus->id; - event->source = input->drag_source->input->keyboard_focus->id; + if (input->drag_source) + { + if (input->drag_source->input) + { + if (input->drag_source->input->pointer_focus) + event->win = input->drag_source->input->pointer_focus->id; + if (input->drag_source->input->keyboard_focus) + event->source = input->drag_source->input->keyboard_focus->id; + } + } + event->position.x = input->sx; event->position.y = input->sy; @@ -112,8 +271,17 @@ _ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device __UNUSED__) if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return; - event->win = input->drag_source->input->pointer_focus->id; - event->source = input->drag_source->input->keyboard_focus->id; + if (input->drag_source) + { + if (input->drag_source->input) + { + if (input->drag_source->input->pointer_focus) + event->win = input->drag_source->input->pointer_focus->id; + if (input->drag_source->input->keyboard_focus) + event->source = input->drag_source->input->keyboard_focus->id; + } + } + event->position.x = input->sx; event->position.y = input->sy; @@ -183,3 +351,135 @@ _ecore_wl_dnd_cb_enter_free(void *data __UNUSED__, void *event) if (!(ev = event)) return; free(ev); } + +static void +_ecore_wl_dnd_cb_selection_data_ready_free(void *data __UNUSED__, void *event) +{ + Ecore_Wl_Event_Selection_Data_Ready *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = event)) return; + + free(ev->data); + free(ev); +} + +static Eina_Bool +_ecore_wl_dnd_read_data(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) +{ + int len; + char buffer[4096]; + Ecore_Wl_Dnd_Source *source; + Ecore_Wl_Event_Selection_Data_Ready *event; + Eina_Bool ret; + + source = data; + + len = read(source->fd, buffer, sizeof buffer); + + if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Selection_Data_Ready)))) + return ECORE_CALLBACK_CANCEL; + + if (len <= 0) + { + close(source->fd); + _ecore_wl_dnd_del(source); + event->done = EINA_TRUE; + event->data = NULL; + event->len = 0; + ret = ECORE_CALLBACK_CANCEL; + } + else + { + event->data = malloc(len + 1); + if (!event->data) return ECORE_CALLBACK_CANCEL; + strncpy(event->data, buffer, len); + event->data[len] = '\0'; + event->len = len; + event->done = EINA_FALSE; + ret = ECORE_CALLBACK_RENEW; + } + + ecore_event_add(ECORE_WL_EVENT_SELECTION_DATA_READY, event, + _ecore_wl_dnd_cb_selection_data_ready_free, NULL); + return ret; +} + + +static Eina_Bool +_ecore_wl_dnd_idler_cb(void *data) +{ + struct _dnd_read_ctx *ctx; + struct _dnd_task *task; + int count, i; + + ctx = data; + count = epoll_wait(ctx->epoll_fd, ctx->ep, 1, 0); + for (i = 0; i < count; i++) + { + task = ctx->ep->data.ptr; + if (task->cb(task->data, NULL) == ECORE_CALLBACK_CANCEL) + { + free(ctx->ep); + free(task); + free(ctx); + return ECORE_CALLBACK_CANCEL; + } + } + return ECORE_CALLBACK_RENEW; +} + +static void +_ecore_wl_dnd_source_receive_data(Ecore_Wl_Dnd_Source *source, const char *type) +{ + int epoll_fd; + struct epoll_event *ep = NULL; + struct _dnd_task *task = NULL; + struct _dnd_read_ctx *read_ctx = NULL; + int p[2]; + + if (pipe2(p, O_CLOEXEC) == -1) + return; + + wl_data_offer_receive(source->offer, type, p[1]); + close(p[1]); + + /* Due to http://trac.enlightenment.org/e/ticket/1208, + * use epoll and idle handler instead of ecore_main_fd_handler_add() */ + + ep = calloc(1, sizeof(struct epoll_event)); + if (!ep) goto err; + + task = calloc(1, sizeof(struct _dnd_task)); + if (!task) goto err; + + read_ctx = calloc(1, sizeof(struct _dnd_read_ctx)); + if (!read_ctx) goto err; + + epoll_fd = epoll_create1(0); + if (epoll_fd < 0) goto err; + + task->data = source; + task->cb = _ecore_wl_dnd_read_data; + ep->events = EPOLLIN; + ep->data.ptr = task; + + if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, p[0], ep) < 0) goto err; + + read_ctx->epoll_fd = epoll_fd; + read_ctx->ep = ep; + + if (!ecore_idler_add(_ecore_wl_dnd_idler_cb, read_ctx)) goto err; + + source->refcount++; + source->fd = p[0]; + return; + +err: + if (ep) free(ep); + if (task) free(task); + if (read_ctx) free(read_ctx); + close(p[0]); + return; +} diff --git a/src/lib/ecore_wayland/ecore_wl_input.c b/src/lib/ecore_wayland/ecore_wl_input.c index 9d82f60..54c77d0 100644 --- a/src/lib/ecore_wayland/ecore_wl_input.c +++ b/src/lib/ecore_wayland/ecore_wl_input.c @@ -19,6 +19,7 @@ #include "ecore_wl_private.h" #include +#include /* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ... * What about other OSs ?? */ @@ -34,9 +35,7 @@ # define BTN_BACK 0x116 #endif -#define MOD_SHIFT_MASK 0x01 -#define MOD_ALT_MASK 0x02 -#define MOD_CONTROL_MASK 0x04 +Ecore_Wl_Dnd *glb_dnd = NULL; /* local function prototypes */ static void _ecore_wl_input_seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps); @@ -52,6 +51,7 @@ static void _ecore_wl_input_cb_keyboard_enter(void *data, struct wl_keyboard *ke static void _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, struct wl_surface *surface); static void _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, unsigned int timestamp, unsigned int key, unsigned int state); static void _ecore_wl_input_cb_keyboard_modifiers(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial __UNUSED__, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group); +static Eina_Bool _ecore_wl_input_cb_keyboard_repeat(void *data, Ecore_Fd_Handler *handler __UNUSED__); static void _ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch __UNUSED__, unsigned int serial, unsigned int timestamp, struct wl_surface *surface __UNUSED__, int id __UNUSED__, wl_fixed_t x, wl_fixed_t y); static void _ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch __UNUSED__, unsigned int serial, unsigned int timestamp, int id __UNUSED__); static void _ecore_wl_input_cb_touch_motion(void *data, struct wl_touch *touch __UNUSED__, unsigned int timestamp, int id __UNUSED__, wl_fixed_t x, wl_fixed_t y); @@ -108,7 +108,6 @@ static const struct wl_seat_listener _ecore_wl_seat_listener = _ecore_wl_input_seat_handle_capabilities, }; - static const struct wl_data_device_listener _ecore_wl_data_listener = { _ecore_wl_input_cb_data_offer, @@ -168,18 +167,25 @@ ecore_wl_input_cursor_from_name_set(Ecore_Wl_Input *input, const char *cursor_na if (!input) return; - /* No cursor */ - if (!cursor_name) + eina_stringshare_replace(&input->cursor_name, cursor_name); + + /* No cursor. Set to default Left Pointer */ + if (!cursor_name) + eina_stringshare_replace(&input->cursor_name, "left_ptr"); + + /* try to get this cursor from the theme */ + if (!(cursor = ecore_wl_cursor_get(input->cursor_name))) { - ecore_wl_input_pointer_set(input, NULL, 0, 0); - return; + /* if the theme does not have this cursor, default to left pointer */ + if (!(cursor = ecore_wl_cursor_get("left_ptr"))) + return; } - if (!(cursor = ecore_wl_cursor_get(cursor_name))) - return; - if ((!cursor->images) || (!cursor->images[0])) - return; + { + ecore_wl_input_pointer_set(input, NULL, 0, 0); + return; + } cursor_image = cursor->images[0]; if ((buffer = wl_cursor_image_get_buffer(cursor_image))) @@ -207,6 +213,7 @@ ecore_wl_input_cursor_default_restore(Ecore_Wl_Input *input) ecore_wl_input_cursor_from_name_set(input, "left_ptr"); } +/* local functions */ void _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id) { @@ -237,7 +244,23 @@ _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id) input->cursor_surface = wl_compositor_create_surface(_ecore_wl_disp->wl.compositor); + input->repeat.timerfd = + timerfd_create(CLOCK_MONOTONIC, (TFD_CLOEXEC | TFD_NONBLOCK)); + + input->repeat.hdlr = + ecore_main_fd_handler_add(input->repeat.timerfd, ECORE_FD_READ, + _ecore_wl_input_cb_keyboard_repeat, input, + NULL, NULL); + ewd->input = input; + + /* create Ecore_Wl_Dnd */ + if (!glb_dnd) + if (!(glb_dnd = calloc(1, sizeof(Ecore_Wl_Dnd)))) return; + glb_dnd->ewd = ewd; + glb_dnd->input = input; + input->dnd = glb_dnd; + wl_array_init(&glb_dnd->types_offered); } void @@ -245,6 +268,19 @@ _ecore_wl_input_del(Ecore_Wl_Input *input) { if (!input) return; + if (input->cursor_name) eina_stringshare_del(input->cursor_name); + input->cursor_name = NULL; + + if (input->keyboard_focus) + { + Ecore_Wl_Window *win = NULL; + + if ((win = input->keyboard_focus)) + win->keyboard_device = NULL; + + input->keyboard_focus = NULL; + } + if (input->drag_source) _ecore_wl_dnd_del(input->drag_source); input->drag_source = NULL; @@ -264,6 +300,12 @@ _ecore_wl_input_del(Ecore_Wl_Input *input) wl_list_remove(&input->link); if (input->seat) wl_seat_destroy(input->seat); + if (input->repeat.hdlr) ecore_main_fd_handler_del(input->repeat.hdlr); + input->repeat.hdlr = NULL; + + if (input->repeat.timerfd) close(input->repeat.timerfd); + input->repeat.timerfd = 0; + free(input); } @@ -274,7 +316,6 @@ _ecore_wl_input_pointer_xy_get(int *x, int *y) if (y) *y = _pointer_y; } -/* local functions */ static void _ecore_wl_input_seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) { @@ -336,7 +377,7 @@ _ecore_wl_input_cb_pointer_motion(void *data, struct wl_pointer *pointer __UNUSE if (input->pointer_focus) _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp); - ecore_wl_input_cursor_default_restore(input); + ecore_wl_input_cursor_from_name_set(input, input->cursor_name); } static void @@ -403,7 +444,12 @@ _ecore_wl_input_cb_pointer_frame(void *data, struct wl_callback *callback, unsig input->cursor_frame_cb = NULL; } - /* TODO: Finish me */ + if (!input->cursor_name) + { + ecore_wl_input_pointer_set(input, NULL, 0, 0); + return; + } + if (!input->cursor_frame_cb) { input->cursor_frame_cb = wl_surface_frame(input->cursor_surface); @@ -462,56 +508,6 @@ _ecore_wl_input_cb_keyboard_keymap(void *data, struct wl_keyboard *keyboard __UN 1 << xkb_map_mod_get_index(input->xkb.keymap, "Shift"); } -/* - * _ecore_wl_input_keysym_to_string: Translate a symbol to its printable form - * - * @symbol: the symbol to translate - * @buffer: the buffer where to put the translated string - * @len: size of the buffer - * - * Translates @symbol into a printable representation in @buffer, if possible. - * - * Return value: The number of bytes of the translated string, 0 if the - * symbol can't be printed - * - * Note: The code is derived from libX11's src/KeyBind.c - * Copyright 1985, 1987, 1998 The Open Group - * - */ -static int -_ecore_wl_input_keysym_to_string(unsigned int symbol, char *buffer, int len) -{ - unsigned long high_bytes; - unsigned char c; - - high_bytes = symbol >> 8; - if (!(len && - ((high_bytes == 0) || - ((high_bytes == 0xFF) && - (((symbol >= XKB_KEY_BackSpace) && - (symbol <= XKB_KEY_Clear)) || - (symbol == XKB_KEY_Return) || - (symbol == XKB_KEY_Escape) || - (symbol == XKB_KEY_KP_Space) || - (symbol == XKB_KEY_KP_Tab) || - (symbol == XKB_KEY_KP_Enter) || - ((symbol >= XKB_KEY_KP_Multiply) && - (symbol <= XKB_KEY_KP_9)) || - (symbol == XKB_KEY_KP_Equal) || - (symbol == XKB_KEY_Delete)))))) - return 0; - - if (symbol == XKB_KEY_KP_Space) - c = ' '; - else if (high_bytes == 0xFF) - c = symbol & 0x7F; - else - c = symbol & 0xFF; - - buffer[0] = c; - return 1; -} - static void _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state) { @@ -519,50 +515,69 @@ _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard __UNUSE Ecore_Wl_Window *win; unsigned int code, num; const xkb_keysym_t *syms; - xkb_keysym_t sym; - char string[32], key[32], keyname[32]; + xkb_keysym_t sym = XKB_KEY_NoSymbol; + xkb_mod_mask_t mask; + char string[32], key[32], keyname[32];// compose[32]; Ecore_Event_Key *e; + struct itimerspec ts; + int len = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!(input = data)) return; input->display->serial = serial; + + /* xkb rules reflect X broken keycodes, so offset by 8 */ code = keycode + 8; win = input->keyboard_focus; - if ((!win) || (win->keyboard_device != input)) return; + if ((!win) || (win->keyboard_device != input) || (!input->xkb.state)) + return; - num = xkb_key_get_syms(input->xkb.state, code, &syms); + mask = xkb_state_serialize_mods(input->xkb.state, + XKB_STATE_DEPRESSED | XKB_STATE_LATCHED); - xkb_state_update_key(input->xkb.state, code, - (state ? XKB_KEY_DOWN : XKB_KEY_UP)); + input->modifiers = 0; - /* mask = xkb_state_serialize_mods(input->display->xkb.state, */ - /* (XKB_STATE_DEPRESSED | XKB_STATE_LATCHED)); */ - /* input->modifiers = 0; */ - /* if (mask & input->display->xkb.control_mask) */ - /* input->modifiers |= MOD_CONTROL_MASK; */ - /* if (mask & input->display->xkb.alt_mask) */ - /* input->modifiers |= MOD_ALT_MASK; */ - /* if (mask & input->display->xkb.shift_mask) */ - /* input->modifiers |= MOD_SHIFT_MASK; */ + /* The Ecore_Event_Modifiers don't quite match the X mask bits */ + if (mask & input->xkb.control_mask) + input->modifiers |= ECORE_EVENT_MODIFIER_CTRL; + if (mask & input->xkb.alt_mask) + input->modifiers |= ECORE_EVENT_MODIFIER_ALT; + if (mask & input->xkb.shift_mask) + input->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + num = xkb_key_get_syms(input->xkb.state, code, &syms); if (num == 1) sym = syms[0]; - else sym = XKB_KEY_NoSymbol; memset(key, 0, sizeof(key)); + xkb_keysym_get_name(sym, key, sizeof(key)); + memset(keyname, 0, sizeof(keyname)); - memset(string, 0, sizeof(string)); + xkb_keysym_get_name(sym, keyname, sizeof(keyname)); + if (keyname[0] == '\0') + snprintf(keyname, sizeof(keyname), "Keycode-%i", code); - /* TODO: Switch over to the libxkbcommon API when it is available */ - if (!_ecore_wl_input_keysym_to_string(sym, string, sizeof(string))) - string[0] = '\0'; + memset(string, 0, sizeof(string)); + if (xkb_keysym_to_utf8(sym, string, 32) <= 0) + { + /* FIXME: NB: We may need to add more checks here for other + * non-printable characters */ + if ((sym == XKB_KEY_Tab) || (sym == XKB_KEY_ISO_Left_Tab)) + string[len++] = '\t'; + } - xkb_keysym_get_name(sym, key, sizeof(key)); - xkb_keysym_get_name(sym, keyname, sizeof(keyname)); + /* FIXME: NB: Start hacking on compose key support */ + /* memset(compose, 0, sizeof(compose)); */ + /* if (sym == XKB_KEY_Multi_key) */ + /* { */ + /* if (xkb_keysym_to_utf8(sym, compose, 32) <= 0) */ + /* compose[0] = '\0'; */ + /* } */ - e = malloc(sizeof(Ecore_Event_Key) + strlen(keyname) + strlen(key) + - strlen(string) + 3); + e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + + ((string[0] != '\0') ? strlen(string) : 0) + 3); + if (!e) return; e->keyname = (char *)(e + 1); e->key = e->keyname + strlen(keyname) + 1; @@ -571,8 +586,7 @@ _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard __UNUSE strcpy((char *)e->keyname, keyname); strcpy((char *)e->key, key); - if (strlen (string)) - strcpy((char *)e->string, string); + if (strlen(string)) strcpy((char *)e->string, string); e->window = win->id; e->event_window = win->id; @@ -583,36 +597,73 @@ _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard __UNUSE ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL); else ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL); + + if ((!state) && (keycode == input->repeat.key)) + { + input->repeat.sym = 0; + input->repeat.key = 0; + input->repeat.time = 0; + + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 0; + ts.it_value.tv_sec = 0; + ts.it_value.tv_nsec = 0; + + timerfd_settime(input->repeat.timerfd, 0, &ts, NULL); + } + else if ((state) && + ((!input->repeat.key) || + ((keycode) && (keycode != input->repeat.key)))) + { + input->repeat.sym = sym; + input->repeat.key = keycode; + input->repeat.time = timestamp; + + /* interval after expires */ + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 35 * 1000 * 1000; + + /* initial expiration */ + ts.it_value.tv_sec = 0; + ts.it_value.tv_nsec = 500 * 1000 * 1000; + + timerfd_settime(input->repeat.timerfd, 0, &ts, NULL); + } } static void _ecore_wl_input_cb_keyboard_modifiers(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial __UNUSED__, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group) { Ecore_Wl_Input *input; - xkb_mod_mask_t mask = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!(input = data)) return; - if (input->xkb.state) - { - xkb_state_update_mask(input->xkb.state, depressed, latched, - locked, 0, 0, group); + xkb_state_update_mask(input->xkb.state, depressed, latched, + locked, 0, 0, group); +} - mask = - xkb_state_serialize_mods(input->xkb.state, - (XKB_STATE_DEPRESSED | XKB_STATE_LATCHED)); - } +static Eina_Bool +_ecore_wl_input_cb_keyboard_repeat(void *data, Ecore_Fd_Handler *handler __UNUSED__) +{ + Ecore_Wl_Input *input; + Ecore_Wl_Window *win = NULL; + unsigned long long int xp; - input->modifiers = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* The Ecore_Event_Modifiers don't quite match the X mask bits */ - if (mask & input->xkb.control_mask) - input->modifiers |= MOD_CONTROL_MASK; - if (mask & input->xkb.alt_mask) - input->modifiers |= MOD_ALT_MASK; - if (mask & input->xkb.shift_mask) - input->modifiers |= MOD_SHIFT_MASK; + if (!(input = data)) return ECORE_CALLBACK_RENEW; + + /* Trap for EAGAIN */ + if (read(input->repeat.timerfd, &xp, sizeof(xp)) != sizeof(xp)) + return ECORE_CALLBACK_RENEW; + + if ((win = input->keyboard_focus)) + _ecore_wl_input_cb_keyboard_key(input, NULL, input->display->serial, + input->repeat.time, + input->repeat.key, EINA_TRUE); + + return ECORE_CALLBACK_RENEW; } static void @@ -648,7 +699,7 @@ _ecore_wl_input_cb_pointer_enter(void *data, struct wl_pointer *pointer __UNUSED _ecore_wl_input_mouse_in_send(input, win, input->timestamp); /* The cursor on the surface is undefined until we set it */ - ecore_wl_window_cursor_default_restore(win); + ecore_wl_input_cursor_from_name_set(input, "left_ptr"); /* NB: This whole 'if' below is a major HACK due to wayland's stupidness * of not sending a mouse_up (or any notification at all for that matter) @@ -692,6 +743,7 @@ _ecore_wl_input_cb_pointer_leave(void *data, struct wl_pointer *pointer __UNUSED LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!surface) return; if (!(input = data)) return; input->display->serial = serial; @@ -721,6 +773,7 @@ _ecore_wl_input_cb_keyboard_enter(void *data, struct wl_keyboard *keyboard __UNU LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!surface) return; if (!(input = data)) return; if (!input->timestamp) @@ -749,8 +802,21 @@ _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard __UNU LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!surface) return; if (!(input = data)) return; + if (input->repeat.timerfd) + { + struct itimerspec ts; + + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 0; + ts.it_value.tv_sec = 0; + ts.it_value.tv_nsec = 0; + + timerfd_settime(input->repeat.timerfd, 0, &ts, NULL); + } + if (!input->timestamp) { struct timeval tv; @@ -765,9 +831,9 @@ _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard __UNU if (!(win = wl_surface_get_user_data(surface))) return; win->keyboard_device = NULL; - input->keyboard_focus = NULL; - _ecore_wl_input_focus_out_send(input, win, input->timestamp); + + input->keyboard_focus = NULL; } static void @@ -777,15 +843,17 @@ _ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch __UNUSED__, uns LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!surface) return; if (!(input = data)) return; /* FIXME: NB: Not sure yet if input->timestamp should be set here. * This needs to be tested with an actual touch device */ /* input->timestamp = timestamp; */ input->display->serial = serial; - input->button = 0; + input->button = BTN_LEFT; input->sx = wl_fixed_to_int(x); input->sy = wl_fixed_to_int(y); + _ecore_wl_input_cb_pointer_enter(data, NULL, serial, surface, x, y); _ecore_wl_input_mouse_down_send(input, input->pointer_focus, timestamp); } @@ -801,9 +869,10 @@ _ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch __UNUSED__, unsig /* FIXME: NB: Not sure yet if input->timestamp should be set here. * This needs to be tested with an actual touch device */ /* input->timestamp = timestamp; */ - input->button = 0; + input->button = BTN_LEFT; input->display->serial = serial; _ecore_wl_input_mouse_up_send(input, input->pointer_focus, timestamp); + input->button = 0; } static void @@ -849,6 +918,8 @@ _ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, un { LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!surface) return; + _ecore_wl_dnd_enter(data, data_device, timestamp, surface, x, y, offer); } @@ -908,8 +979,11 @@ _ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, uns ev->multi.x = input->sx; ev->multi.y = input->sy; - ev->window = win->id; - ev->event_window = win->id; + if (win) + { + ev->window = win->id; + ev->event_window = win->id; + } ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); } @@ -930,8 +1004,11 @@ _ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsig ev->modifiers = input->modifiers; ev->timestamp = timestamp; - ev->window = win->id; - ev->event_window = win->id; + if (win) + { + ev->window = win->id; + ev->event_window = win->id; + } ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL); } @@ -952,8 +1029,11 @@ _ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsi ev->modifiers = input->modifiers; ev->timestamp = timestamp; - ev->window = win->id; - ev->event_window = win->id; + if (win) + { + ev->window = win->id; + ev->event_window = win->id; + } ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL); } @@ -967,7 +1047,7 @@ _ecore_wl_input_focus_in_send(Ecore_Wl_Input *input __UNUSED__, Ecore_Wl_Window if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_In)))) return; ev->timestamp = timestamp; - ev->win = win->id; + if (win) ev->win = win->id; ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL); } @@ -980,7 +1060,7 @@ _ecore_wl_input_focus_out_send(Ecore_Wl_Input *input __UNUSED__, Ecore_Wl_Window if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_Out)))) return; ev->timestamp = timestamp; - ev->win = win->id; + if (win) ev->win = win->id; ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL); } @@ -1007,7 +1087,6 @@ _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, uns ev->y = input->sy; /* ev->root.x = input->sx; */ /* ev->root.y = input->sy; */ - /* printf("Input Modifiers: %d\n", input->modifiers); */ ev->modifiers = input->modifiers; /* FIXME: Need to get these from wayland somehow */ @@ -1023,8 +1102,11 @@ _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, uns ev->multi.x = input->sx; ev->multi.y = input->sy; - ev->window = win->id; - ev->event_window = win->id; + if (win) + { + ev->window = win->id; + ev->event_window = win->id; + } ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); } @@ -1067,8 +1149,11 @@ _ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsig ev->multi.x = input->sx; ev->multi.y = input->sy; - ev->window = win->id; - ev->event_window = win->id; + if (win) + { + ev->window = win->id; + ev->event_window = win->id; + } ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); } @@ -1113,3 +1198,10 @@ _ecore_wl_input_mouse_wheel_send(Ecore_Wl_Input *input, unsigned int axis, int v ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL); } + +void +_ecore_wl_input_set_selection(Ecore_Wl_Input *input, struct wl_data_source *source) +{ + wl_data_device_set_selection(input->data_device, source, input->display->serial); +} + diff --git a/src/lib/ecore_wayland/ecore_wl_output.c b/src/lib/ecore_wayland/ecore_wl_output.c index 5e6c38d..50057df 100644 --- a/src/lib/ecore_wayland/ecore_wl_output.c +++ b/src/lib/ecore_wayland/ecore_wl_output.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "ecore_wl_private.h" /* local function prototypes */ diff --git a/src/lib/ecore_wayland/ecore_wl_private.h b/src/lib/ecore_wayland/ecore_wl_private.h index 63a5f12..7f59ae9 100644 --- a/src/lib/ecore_wayland/ecore_wl_private.h +++ b/src/lib/ecore_wayland/ecore_wl_private.h @@ -50,6 +50,18 @@ extern Ecore_Wl_Display *_ecore_wl_disp; # endif # define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_wl_log_dom, __VA_ARGS__) +struct _Ecore_Wl_Dnd +{ + Ecore_Wl_Display *ewd; + Ecore_Wl_Input *input; + + /* As provider */ + struct wl_data_source *data_source; + struct wl_array types_offered; + + /* TODO: dnd specific fields */ +}; + struct _Ecore_Wl_Dnd_Source { struct wl_data_offer *offer; @@ -77,6 +89,7 @@ void _ecore_wl_output_del(Ecore_Wl_Output *output); void _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id); void _ecore_wl_input_del(Ecore_Wl_Input *input); void _ecore_wl_input_pointer_xy_get(int *x, int *y); +void _ecore_wl_input_set_selection(Ecore_Wl_Input *input, struct wl_data_source *source); void _ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device, struct wl_data_offer *offer); void _ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device __UNUSED__, unsigned int timestamp __UNUSED__, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer); @@ -86,4 +99,5 @@ void _ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device __UNUSED_ void _ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device __UNUSED__, struct wl_data_offer *offer); void _ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source); +struct wl_data_source *_ecore_wl_create_data_source(Ecore_Wl_Display *ewd); #endif diff --git a/src/lib/ecore_wayland/ecore_wl_window.c b/src/lib/ecore_wayland/ecore_wl_window.c index ab72a01..94b5628 100644 --- a/src/lib/ecore_wayland/ecore_wl_window.c +++ b/src/lib/ecore_wayland/ecore_wl_window.c @@ -2,14 +2,40 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "ecore_wl_private.h" /* local function prototypes */ static void _ecore_wl_window_cb_ping(void *data __UNUSED__, struct wl_shell_surface *shell_surface, unsigned int serial); static void _ecore_wl_window_cb_configure(void *data, struct wl_shell_surface *shell_surface __UNUSED__, unsigned int edges, int w, int h); static void _ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface *shell_surface __UNUSED__); -static void _ecore_wl_window_cb_surface_enter(void *data, struct wl_surface *surface, struct wl_output *output); -static void _ecore_wl_window_cb_surface_leave(void *data, struct wl_surface *surface, struct wl_output *output); +static void _ecore_wl_window_cb_surface_enter(void *data, struct wl_surface *surface, struct wl_output *output __UNUSED__); +static void _ecore_wl_window_cb_surface_leave(void *data, struct wl_surface *surface, struct wl_output *output __UNUSED__); static void _ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h); static char *_ecore_wl_window_id_str_get(unsigned int win_id); @@ -205,11 +231,11 @@ ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h, int location) if (!win) return; - win->allocation.w = w; - win->allocation.h = h; - if (win->type != ECORE_WL_WINDOW_TYPE_FULLSCREEN) { + win->allocation.w = w; + win->allocation.h = h; + win->region.input = wl_compositor_create_region(_ecore_wl_disp->wl.compositor); wl_region_add(win->region.input, win->allocation.x, win->allocation.y, @@ -264,20 +290,29 @@ ecore_wl_window_buffer_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer, in switch (win->buffer_type) { case ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW: - /* FIXME: weston has wl_egl_window_get_attached_size */ + win->server_allocation = win->allocation; break; case ECORE_WL_WINDOW_BUFFER_TYPE_EGL_IMAGE: case ECORE_WL_WINDOW_BUFFER_TYPE_SHM: if (win->surface) { + if (win->edges & 4) // resizing from the left + x = win->server_allocation.w - win->allocation.w; + else + x = 0; + + if (win->edges & 1) // resizing from the top + y = win->server_allocation.h - win->allocation.h; + else + y = 0; + + win->edges = 0; + /* if (buffer) */ wl_surface_attach(win->surface, buffer, x, y); wl_surface_damage(win->surface, 0, 0, win->allocation.w, win->allocation.h); - wl_surface_damage(win->surface, 0, 0, - win->allocation.w, win->allocation.h); - win->server_allocation = win->allocation; } break; @@ -422,6 +457,7 @@ ecore_wl_window_maximized_set(Ecore_Wl_Window *win, Eina_Bool maximized) LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!win) return; + if ((win->type == ECORE_WL_WINDOW_TYPE_MAXIMIZED) == maximized) return; if (win->type == ECORE_WL_WINDOW_TYPE_TOPLEVEL) { @@ -430,14 +466,13 @@ ecore_wl_window_maximized_set(Ecore_Wl_Window *win, Eina_Bool maximized) wl_shell_surface_set_maximized(win->shell_surface, NULL); win->type = ECORE_WL_WINDOW_TYPE_MAXIMIZED; } - else + else if (win->type == ECORE_WL_WINDOW_TYPE_MAXIMIZED) { if (win->shell_surface) wl_shell_surface_set_toplevel(win->shell_surface); win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; - win->allocation = win->saved_allocation; - _ecore_wl_window_configure_send(win, win->allocation.w, - win->allocation.h); + _ecore_wl_window_configure_send(win, win->saved_allocation.w, + win->saved_allocation.h); } } @@ -462,9 +497,8 @@ ecore_wl_window_fullscreen_set(Ecore_Wl_Window *win, Eina_Bool fullscreen) if (win->shell_surface) wl_shell_surface_set_toplevel(win->shell_surface); win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; - win->allocation = win->saved_allocation; - _ecore_wl_window_configure_send(win, win->allocation.w, - win->allocation.h); + _ecore_wl_window_configure_send(win, win->saved_allocation.w, + win->saved_allocation.h); } } @@ -475,6 +509,15 @@ ecore_wl_window_transparent_set(Ecore_Wl_Window *win, Eina_Bool transparent) if (!win) return; win->transparent = transparent; + if (win->region.opaque) wl_region_destroy(win->region.opaque); + win->region.opaque = NULL; + if (!win->transparent) + { + win->region.opaque = + wl_compositor_create_region(_ecore_wl_disp->wl.compositor); + wl_region_add(win->region.opaque, win->allocation.x, win->allocation.y, + win->allocation.w, win->allocation.h); + } } EAPI void @@ -586,6 +629,7 @@ ecore_wl_window_parent_set(Ecore_Wl_Window *win, Ecore_Wl_Window *parent) static void _ecore_wl_window_cb_ping(void *data __UNUSED__, struct wl_shell_surface *shell_surface, unsigned int serial) { + if (!shell_surface) return; wl_shell_surface_pong(shell_surface, serial); } @@ -619,27 +663,30 @@ _ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface *shell_surfac LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!shell_surface) return; if (!(win = data)) return; ecore_wl_input_ungrab(win->pointer_device); } static void -_ecore_wl_window_cb_surface_enter(void *data, struct wl_surface *surface, struct wl_output *output) +_ecore_wl_window_cb_surface_enter(void *data, struct wl_surface *surface, struct wl_output *output __UNUSED__) { Ecore_Wl_Window *win; LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!surface) return; if (!(win = data)) return; } static void -_ecore_wl_window_cb_surface_leave(void *data, struct wl_surface *surface, struct wl_output *output) +_ecore_wl_window_cb_surface_leave(void *data, struct wl_surface *surface, struct wl_output *output __UNUSED__) { Ecore_Wl_Window *win; LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!surface) return; if (!(win = data)) return; } diff --git a/src/lib/ecore_win32/Ecore_Win32.h b/src/lib/ecore_win32/Ecore_Win32.h index ae1bd4e..e74721d 100644 --- a/src/lib/ecore_win32/Ecore_Win32.h +++ b/src/lib/ecore_win32/Ecore_Win32.h @@ -2,17 +2,17 @@ #define __ECORE_WIN32_H__ /* - * DO NOT USE THIS HEADER. IT IS WORK IN PROGRESS. IT IS NOT FINAL AND + * DO NOT USE THIS HEADER. IT IS A WORK IN PROGRESS API. IT IS NOT FINAL AND * THE API MAY CHANGE. */ #ifndef ECORE_WIN32_WIP_POZEFLKSD # ifdef _MSC_VER # pragma message ("You are using a work in progress API. This API is not stable") -# pragma message ("and is subject to change. You use this at your own risk.") +# pragma message ("and is subject to change. You can use this at your own risk.") # else # warning "You are using a work in progress API. This API is not stable" -# warning "and is subject to change. You use this at your own risk." +# warning "and is subject to change. You can use this at your own risk." # endif #endif @@ -50,35 +50,37 @@ extern "C" { #endif /** + * @internal * @defgroup Ecore_Win32_Group Ecore_Win32 library + * @ingroup Ecore_Group * * @{ */ /** * @typedef Ecore_Win32_Window_State - * State of a window. + * @brief Enumeration for state of a window. */ typedef enum { - ECORE_WIN32_WINDOW_STATE_ICONIFIED, /**< iconified window */ - ECORE_WIN32_WINDOW_STATE_MODAL, /**< modal dialog box */ - ECORE_WIN32_WINDOW_STATE_STICKY, /**< sticky window */ - ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT, /**< maximum vertical sized window */ - ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ, /**< maximum horizontal sized window */ - ECORE_WIN32_WINDOW_STATE_MAXIMIZED, /**< maximum sized window */ - ECORE_WIN32_WINDOW_STATE_SHADED, /**< shaded window */ - ECORE_WIN32_WINDOW_STATE_HIDDEN, /**< hidden (minimized or iconified) window */ - ECORE_WIN32_WINDOW_STATE_FULLSCREEN, /**< fullscreen window */ - ECORE_WIN32_WINDOW_STATE_ABOVE, /**< above window */ - ECORE_WIN32_WINDOW_STATE_BELOW, /**< below window */ + ECORE_WIN32_WINDOW_STATE_ICONIFIED, /**< Iconified window */ + ECORE_WIN32_WINDOW_STATE_MODAL, /**< Modal dialog box */ + ECORE_WIN32_WINDOW_STATE_STICKY, /**< Sticky window */ + ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT, /**< Maximum vertical sized window */ + ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ, /**< Maximum horizontal sized window */ + ECORE_WIN32_WINDOW_STATE_MAXIMIZED, /**< Maximum sized window */ + ECORE_WIN32_WINDOW_STATE_SHADED, /**< Shaded window */ + ECORE_WIN32_WINDOW_STATE_HIDDEN, /**< Hidden (minimized or iconified) window */ + ECORE_WIN32_WINDOW_STATE_FULLSCREEN, /**< Fullscreen window */ + ECORE_WIN32_WINDOW_STATE_ABOVE, /**< Above window */ + ECORE_WIN32_WINDOW_STATE_BELOW, /**< Below window */ ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION, /**< To document */ ECORE_WIN32_WINDOW_STATE_UNKNOWN /**< Unknown state */ } Ecore_Win32_Window_State; /** * @typedef Ecore_Win32_Window_Type - * Type of a window. + * @brief Enumeration for type of a window. */ typedef enum { @@ -95,7 +97,7 @@ typedef enum /** * @typedef Ecore_Win32_Cursor_Shape - * Shape of a cursor. + * @brief Enumeration for shape of a cursor. */ typedef enum { @@ -117,7 +119,7 @@ typedef enum /** * @typedef Ecore_Win32_DnD_State - * State of a DnD operation. + * @brief Enumeration for state of a DnD operation. */ typedef enum { @@ -129,136 +131,136 @@ typedef enum /** * @typedef Ecore_Win32_Window - * Abstract type for a window. + * @brief The structure type containing the abstract type for a window. */ typedef struct _Ecore_Win32_Window Ecore_Win32_Window; /** * @typedef Ecore_Win32_Cursor - * Abstract type for a cursor. + * @brief The structure type containing the abstract type for a cursor. */ typedef void Ecore_Win32_Cursor; /** * @typedef Ecore_Win32_Event_Mouse_In - * Event sent when the mouse enters the window. + * @brief The structure type containing the event sent when the mouse enters the window. */ typedef struct _Ecore_Win32_Event_Mouse_In Ecore_Win32_Event_Mouse_In; /** * @typedef Ecore_Win32_Event_Mouse_Out - * Event sent when the mouse leaves the window. + * @brief The structure type containing the event sent when the mouse leaves the window. */ typedef struct _Ecore_Win32_Event_Mouse_Out Ecore_Win32_Event_Mouse_Out; /** * @typedef Ecore_Win32_Event_Window_Focus_In - * Event sent when the window gets the focus. + * @brief The structure type containing the event sent when the window gets focus. */ typedef struct _Ecore_Win32_Event_Window_Focus_In Ecore_Win32_Event_Window_Focus_In; /** * @typedef Ecore_Win32_Event_Window_Focus_Out - * Event sent when the window looses the focus. + * @brief The structure type containing the event sent when the window loses focus. */ typedef struct _Ecore_Win32_Event_Window_Focus_Out Ecore_Win32_Event_Window_Focus_Out; /** * @typedef Ecore_Win32_Event_Window_Damage - * Event sent when the window is damaged. + * @brief The structure type containing the event sent when the window is damaged. */ typedef struct _Ecore_Win32_Event_Window_Damage Ecore_Win32_Event_Window_Damage; /** * @typedef Ecore_Win32_Event_Window_Create - * Event sent when the window is created. + * @brief The structure type containing the event sent when the window is created. */ typedef struct _Ecore_Win32_Event_Window_Create Ecore_Win32_Event_Window_Create; /** * @typedef Ecore_Win32_Event_Window_Destroy - * Event sent when the window is destroyed. + * @brief The structure type containing the event sent when the window is destroyed. */ typedef struct _Ecore_Win32_Event_Window_Destroy Ecore_Win32_Event_Window_Destroy; /** * @typedef Ecore_Win32_Event_Window_Hide - * Event sent when the window is hidden. + * @brief The structure type containing the event sent when the window is hidden. */ typedef struct _Ecore_Win32_Event_Window_Hide Ecore_Win32_Event_Window_Hide; /** * @typedef Ecore_Win32_Event_Window_Show - * Event sent when the window is shown. + * @brief The structure type containing the event sent when the window is shown. */ typedef struct _Ecore_Win32_Event_Window_Show Ecore_Win32_Event_Window_Show; /** * @typedef Ecore_Win32_Event_Window_Configure - * Event sent when the window is configured. + * @brief The structure type containing the event sent when the window is configured. */ typedef struct _Ecore_Win32_Event_Window_Configure Ecore_Win32_Event_Window_Configure; /** * @typedef Ecore_Win32_Event_Window_Resize - * Event sent when the window is resized. + * @brief The structure type containing the event sent when the window is resized. */ typedef struct _Ecore_Win32_Event_Window_Resize Ecore_Win32_Event_Window_Resize; /** * @typedef Ecore_Win32_Event_Window_Delete_Request - * Event sent when the window is deleted. + * @brief The structure type containing the event sent when the window is deleted. */ typedef struct _Ecore_Win32_Event_Window_Delete_Request Ecore_Win32_Event_Window_Delete_Request; /** * @struct _Ecore_Win32_Event_Mouse_In - * Event sent when the mouse enters the window. + * @brief The structure type containing the event sent when the mouse enters the window. */ struct _Ecore_Win32_Event_Mouse_In { Ecore_Win32_Window *window; /**< The window that received the event */ - int x; /**< The x coordinate where the mouse leaved */ + int x; /**< The x coordinate where the mouse left */ int y; /**< The y coordinate where the mouse entered */ - unsigned long timestamp; /**< The time the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Mouse_Out - * Event sent when the mouse leaves the window. + * @brief The structure type containing the event sent when the mouse leaves the window. */ struct _Ecore_Win32_Event_Mouse_Out { Ecore_Win32_Window *window; /**< The window that received the event */ - int x; /**< The x coordinate where the mouse leaved */ - int y; /**< The y coordinate where the mouse leaved */ - unsigned long timestamp; /**< The time the event occurred */ + int x; /**< The x coordinate where the mouse left */ + int y; /**< The y coordinate where the mouse left */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Window_Focus_In - * Event sent when the window gets the focus. + * @brief The structure type containing the event sent when the window gets focus. */ struct _Ecore_Win32_Event_Window_Focus_In { Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Window_Focus_Out - * Event sent when the window looses the focus. + * @brief The structure type containing the event sent when the window loses focus. */ struct _Ecore_Win32_Event_Window_Focus_Out { Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Window_Damage - * Event sent when the window is damaged. + * @brief The structure type containing the event sent when the window is damaged. */ struct _Ecore_Win32_Event_Window_Damage { @@ -266,53 +268,53 @@ struct _Ecore_Win32_Event_Window_Damage int x; /**< The x coordinate of the top left corner of the damaged region */ int y; /**< The y coordinate of the top left corner of the damaged region */ int width; /**< The width of the damaged region */ - int height; /**< The time the event occurred */ - unsigned long timestamp; /**< The time the event occurred */ + int height; /**< The time when the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Window_Create - * Event sent when the window is created. + * @brief The structure type containing the event sent when the window is created. */ struct _Ecore_Win32_Event_Window_Create { Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Window_Destroy - * Event sent when the window is destroyed. + * @brief The structure type containing the event sent when the window is destroyed. */ struct _Ecore_Win32_Event_Window_Destroy { Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Window_Hide - * Event sent when the window is hidden. + * @brief The structure type containing the event sent when the window is hidden. */ struct _Ecore_Win32_Event_Window_Hide { Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Window_Show - * Event sent when the window is shown. + * @brief The structure type containing the event sent when the window is shown. */ struct _Ecore_Win32_Event_Window_Show { Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Window_Configure - * Event sent when the window is configured. + * @brief The structure type containing the event sent when the window is configured. */ struct _Ecore_Win32_Event_Window_Configure { @@ -322,34 +324,34 @@ struct _Ecore_Win32_Event_Window_Configure int y; /**< The new y coordinate of the top left corner */ int width; /**< The new width */ int height; /**< The new height */ - unsigned long timestamp; /**< The time the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Window_Resize - * Event sent when the window is resized. + * @brief The structure type containing the event sent when the window is resized. */ struct _Ecore_Win32_Event_Window_Resize { Ecore_Win32_Window *window; /**< The window that received the event */ int width; /**< The new width */ int height; /**< The new height */ - unsigned long timestamp; /**< The time the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @struct _Ecore_Win32_Event_Window_Delete_Request - * Event sent when the window is deleted. + * @brief The structure type containing the event sent when the window is deleted. */ struct _Ecore_Win32_Event_Window_Delete_Request { Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ + unsigned long timestamp; /**< The time when the event occurred */ }; /** * @typedef Ecore_Win32_Dnd_DropTarget_Callback - * Callback type for Drop operations. See ecore_win32_dnd_register_drop_target(). + * @brief The integer callback type for Drop operations. See ecore_win32_dnd_register_drop_target(). */ typedef int (*Ecore_Win32_Dnd_DropTarget_Callback)(void *window, int event, int pt_x, int pt_y, void *data, int size); @@ -357,13 +359,13 @@ EAPI extern int ECORE_WIN32_EVENT_MOUSE_IN; /**< Ecore_Event for the #Ecore_Win3 EAPI extern int ECORE_WIN32_EVENT_MOUSE_OUT; /**< Ecore_Event for the #Ecore_Win32_Event_Mouse_Out event */ EAPI extern int ECORE_WIN32_EVENT_WINDOW_FOCUS_IN; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Focus_In event */ EAPI extern int ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Focus_Out event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_DAMAGE; /**< Ecore_Event for the Ecore_Win32_Event_Damage event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_CREATE; /**< Ecore_Event for the Ecore_Win32_Event_Create event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_DESTROY; /**< Ecore_Event for the Ecore_Win32_Event_Destroy event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_HIDE; /**< Ecore_Event for the Ecore_Win32_Event_Hide event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_SHOW; /**< Ecore_Event for the Ecore_Win32_Event_Show event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_CONFIGURE; /**< Ecore_Event for the Ecore_Win32_Event_Configure event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_RESIZE; /**< Ecore_Event for the Ecore_Win32_Event_Resize event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_DAMAGE; /**< Ecore_Event for the #Ecore_Win32_Event_Damage event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_CREATE; /**< Ecore_Event for the #Ecore_Win32_Event_Create event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_DESTROY; /**< Ecore_Event for the #Ecore_Win32_Event_Destroy event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_HIDE; /**< Ecore_Event for the #Ecore_Win32_Event_Hide event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_SHOW; /**< Ecore_Event for the #Ecore_Win32_Event_Show event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_CONFIGURE; /**< Ecore_Event for the #Ecore_Win32_Event_Configure event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_RESIZE; /**< Ecore_Event for the #Ecore_Win32_Event_Resize event */ EAPI extern int ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Delete_Request event */ diff --git a/src/lib/ecore_win32/ecore_win32_window.c b/src/lib/ecore_win32/ecore_win32_window.c index 36f8a86..4938b5b 100644 --- a/src/lib/ecore_win32/ecore_win32_window.c +++ b/src/lib/ecore_win32/ecore_win32_window.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include /* for printf */ diff --git a/src/lib/ecore_wince/Ecore_WinCE.h b/src/lib/ecore_wince/Ecore_WinCE.h index 20c1975..000e57a 100644 --- a/src/lib/ecore_wince/Ecore_WinCE.h +++ b/src/lib/ecore_wince/Ecore_WinCE.h @@ -2,13 +2,13 @@ #define __ECORE_WINCE_H__ /* - * DO NOT USE THIS HEADER. IT IS WORK IN PROGRESS. IT IS NOT FINAL AND + * DO NOT USE THIS HEADER. IT IS A WORK IN PROGRESS API. IT IS NOT FINAL AND * THE API MAY CHANGE. */ #ifndef ECORE_WINCE_WIP_OSXCKQSD # warning "You are using a work in progress API. This API is not stable" -# warning "and is subject to change. You use this at your own risk." +# warning "and is subject to change. You can use this at your own risk." #endif #include @@ -44,7 +44,9 @@ extern "C" { #endif /** + * @internal * @defgroup Ecore_WinCE_Group Ecore_WinCE library + * @ingroup Ecore_Group * * @{ */ @@ -52,119 +54,119 @@ extern "C" { /** * @typedef Ecore_WinCE_Window - * Abstract type for a window. + * @brief The structure type containing the abstract type for a window. */ typedef struct _Ecore_WinCE_Window Ecore_WinCE_Window; /** * @typedef Ecore_WinCE_Event_Mouse_In - * Event sent when the mouse enters the window. + * @brief The structure type containing the event sent when the mouse enters the window. */ typedef struct _Ecore_WinCE_Event_Mouse_In Ecore_WinCE_Event_Mouse_In; /** * @typedef Ecore_WinCE_Event_Mouse_Out - * Event sent when the mouse leaves the window. + * @brief The structure type containing the event sent when the mouse leaves the window. */ typedef struct _Ecore_WinCE_Event_Mouse_Out Ecore_WinCE_Event_Mouse_Out; /** * @typedef Ecore_WinCE_Event_Window_Focus_In - * Event sent when the window gets the focus. + * @brief The structure type containing the event sent when the window gets focus. */ typedef struct _Ecore_WinCE_Event_Window_Focus_In Ecore_WinCE_Event_Window_Focus_In; /** * @typedef Ecore_WinCE_Event_Window_Focus_Out - * Event sent when the window looses the focus. + * @brief The structure type containing the event sent when the window loses focus. */ typedef struct _Ecore_WinCE_Event_Window_Focus_Out Ecore_WinCE_Event_Window_Focus_Out; /** * @typedef Ecore_WinCE_Event_Window_Damage - * Event sent when the window is damaged. + * @brief The structure type containing the event sent when the window is damaged. */ typedef struct _Ecore_WinCE_Event_Window_Damage Ecore_WinCE_Event_Window_Damage; /** * @typedef Ecore_WinCE_Event_Window_Create - * Event sent when the window is created. + * @brief The structure type containing the event sent when the window is created. */ typedef struct _Ecore_WinCE_Event_Window_Create Ecore_WinCE_Event_Window_Create; /** * @typedef Ecore_WinCE_Event_Window_Destroy - * Event sent when the window is destroyed. + * @brief The structure type containing the event sent when the window is destroyed. */ typedef struct _Ecore_WinCE_Event_Window_Destroy Ecore_WinCE_Event_Window_Destroy; /** * @typedef Ecore_WinCE_Event_Window_Hide - * Event sent when the window is hidden. + * @brief The structure type containing the event sent when the window is hidden. */ typedef struct _Ecore_WinCE_Event_Window_Hide Ecore_WinCE_Event_Window_Hide; /** * @typedef Ecore_WinCE_Event_Window_Show - * Event sent when the window is shown. + * @brief The structure type containing the event sent when the window is shown. */ typedef struct _Ecore_WinCE_Event_Window_Show Ecore_WinCE_Event_Window_Show; /** * @typedef Ecore_WinCE_Event_Window_Delete_Request - * Event sent when the window is deleted. + * @brief The structure type containing the Event sent when the window is deleted. */ typedef struct _Ecore_WinCE_Event_Window_Delete_Request Ecore_WinCE_Event_Window_Delete_Request; /** * @struct _Ecore_WinCE_Event_Mouse_In - * Event sent when the mouse enters the window. + * @brief The structure type containing the event sent when the mouse enters the window. */ struct _Ecore_WinCE_Event_Mouse_In { Ecore_WinCE_Window *window; /**< The window that received the event */ int x; /**< The x coordinate where the mouse entered */ int y; /**< The y coordinate where the mouse entered */ - long time; /**< The time the event occurred */ + long time; /**< The time when the event occurred */ }; /** * @struct _Ecore_WinCE_Event_Mouse_Out - * Event sent when the mouse leaves the window. + * @brief The structure type containing the event sent when the mouse leaves the window. */ struct _Ecore_WinCE_Event_Mouse_Out { Ecore_WinCE_Window *window; /**< The window that received the event */ - int x; /**< The x coordinate where the mouse leaved */ - int y; /**< The y coordinate where the mouse leaved */ - long time; /**< The time the event occurred */ + int x; /**< The x coordinate where the mouse left */ + int y; /**< The y coordinate where the mouse left */ + long time; /**< The time when the event occurred */ }; /** * @struct _Ecore_WinCE_Event_Window_Focus_In - * Event sent when the window gets the focus. + * @brief The structure type containing the event sent when the window gets focus. */ struct _Ecore_WinCE_Event_Window_Focus_In { Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ + long time; /**< The time when the event occurred */ }; /** * @struct _Ecore_WinCE_Event_Window_Focus_Out - * Event sent when the window looses the focus. + * @brief The structure type containing the event sent when the window loses focus. */ struct _Ecore_WinCE_Event_Window_Focus_Out { Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ + long time; /**< The time when the event occurred */ }; /** * @struct _Ecore_WinCE_Event_Window_Damage - * Event sent when the window is damaged. + * @brief The structure type containing the event sent when the window is damaged. */ struct _Ecore_WinCE_Event_Window_Damage { @@ -173,57 +175,57 @@ struct _Ecore_WinCE_Event_Window_Damage int y; /**< The y coordinate of the top left corner of the damaged region */ int width; /**< The width of the damaged region */ int height; /**< The height of the damaged region */ - long time; /**< The time the event occurred */ + long time; /**< The time when the event occurred */ }; /** * @struct _Ecore_WinCE_Event_Window_Create - * Event sent when the window is created. + * @brief The structure type containing the event sent when the window is created. */ struct _Ecore_WinCE_Event_Window_Create { Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ + long time; /**< The time when the event occurred */ }; /** * @struct _Ecore_WinCE_Event_Window_Destroy - * Event sent when the window is destroyed. + * @brief The structure type containing the event sent when the window is destroyed. */ struct _Ecore_WinCE_Event_Window_Destroy { Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ + long time; /**< The time when the event occurred */ }; /** * @struct _Ecore_WinCE_Event_Window_Hide - * Event sent when the window is hidden. + * @brief The structure type containing the event sent when the window is hidden. */ struct _Ecore_WinCE_Event_Window_Hide { Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ + long time; /**< The time when the event occurred */ }; /** * @struct _Ecore_WinCE_Event_Window_Show - * Event sent when the window is shown. + * @brief The structure type containing the event sent when the window is shown. */ struct _Ecore_WinCE_Event_Window_Show { Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ + long time; /**< The time when the event occurred */ }; /** * @struct _Ecore_WinCE_Event_Window_Delete_Request - * Event sent when the window is deleted. + * @brief The structure type containing the event sent when the window is deleted. */ struct _Ecore_WinCE_Event_Window_Delete_Request { Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ + long time; /**< The time when the event occurred */ }; @@ -231,11 +233,11 @@ EAPI extern int ECORE_WINCE_EVENT_MOUSE_IN; /**< Ecore_Event for the #Ecore_WinC EAPI extern int ECORE_WINCE_EVENT_MOUSE_OUT; /**< Ecore_Event for the #Ecore_WinCE_Event_Mouse_Out event */ EAPI extern int ECORE_WINCE_EVENT_WINDOW_FOCUS_IN; /**< Ecore_Event for the #Ecore_WinCE_Event_Window_Focus_In event */ EAPI extern int ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT; /**< Ecore_Event for the #Ecore_WinCE_Event_Window_Focus_Out event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_DAMAGE; /**< Ecore_Event for the Ecore_WinCE_Event_Damage event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_CREATE; /**< Ecore_Event for the Ecore_WinCE_Event_Create event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_DESTROY; /**< Ecore_Event for the Ecore_WinCE_Event_Destroy event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_HIDE; /**< Ecore_Event for the Ecore_WinCE_Event_Hide event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_SHOW; /**< Ecore_Event for the Ecore_WinCE_Event_Show event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_DAMAGE; /**< Ecore_Event for the #Ecore_WinCE_Event_Damage event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_CREATE; /**< Ecore_Event for the #Ecore_WinCE_Event_Create event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_DESTROY; /**< Ecore_Event for the #Ecore_WinCE_Event_Destroy event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_HIDE; /**< Ecore_Event for the #Ecore_WinCE_Event_Hide event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_SHOW; /**< Ecore_Event for the #Ecore_WinCE_Event_Show event */ EAPI extern int ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST; /**< Ecore_Event for the #Ecore_WinCE_Event_Window_Delete_Request event */ diff --git a/src/lib/ecore_wince/ecore_wince_window.c b/src/lib/ecore_wince/ecore_wince_window.c index 49a6312..5a550da 100644 --- a/src/lib/ecore_wince/ecore_wince_window.c +++ b/src/lib/ecore_wince/ecore_wince_window.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h old mode 100644 new mode 100755 index b16fab5..90e4270 --- a/src/lib/ecore_x/Ecore_X.h +++ b/src/lib/ecore_x/Ecore_X.h @@ -28,17 +28,25 @@ #include /** + * @internal * @file - * @brief Ecore functions for dealing with the X Windows System + * @brief Ecore functions for dealing with the X Windows System. * - * Ecore_X provides a wrapper and convenience functions for using the - * X Windows System. Function groups for this part of the library - * include the following: + * @remarks Ecore_X provides wrapper and convenience functions for using the + * X Windows System. Function groups for this part of the library + * include the following: * @li @ref Ecore_X_Init_Group * @li @ref Ecore_X_Display_Attr_Group * @li @ref Ecore_X_Flush_Group */ +/** + * @internal + * @defgroup Ecore_X_Group Ecore X + * @ingroup Ecore_Group + * @{ + */ + typedef unsigned int Ecore_X_ID; #ifndef _ECORE_X_WINDOW_PREDEF typedef Ecore_X_ID Ecore_X_Window; @@ -121,26 +129,25 @@ typedef enum _Ecore_X_Composite_Update_Type /** * @typedef _Ecore_X_Window_State - * Defines the different states of the window of Ecore_X. + * @brief Enumeration of the different states of the window of Ecore_X. */ typedef enum _Ecore_X_Window_State { - /* Unknown state */ - ECORE_X_WINDOW_STATE_UNKNOWN = 0, /** The window is iconified. */ - ECORE_X_WINDOW_STATE_ICONIFIED, /** The window is a modal dialog box. */ - ECORE_X_WINDOW_STATE_MODAL, /** The window manager should keep the window's position fixed - * even if the virtual desktop scrolls. */ - ECORE_X_WINDOW_STATE_STICKY, /** The window has the maximum vertical size. */ - ECORE_X_WINDOW_STATE_MAXIMIZED_VERT, /** The window has the maximum horizontal size. */ - ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ, /** The window is shaded. */ - ECORE_X_WINDOW_STATE_SHADED, /** The window should not be included in the taskbar. */ - ECORE_X_WINDOW_STATE_SKIP_TASKBAR, /** The window should not be included in the pager. */ - ECORE_X_WINDOW_STATE_SKIP_PAGER, /** The window is invisible (i.e. minimized/iconified) */ - ECORE_X_WINDOW_STATE_HIDDEN, /** The window should fill the entire screen and have no - * window border/decorations */ - ECORE_X_WINDOW_STATE_FULLSCREEN, /* The following are not documented because they are not - * intended for use in applications. */ - ECORE_X_WINDOW_STATE_ABOVE, ECORE_X_WINDOW_STATE_BELOW, /* FIXME: Documentation */ + ECORE_X_WINDOW_STATE_UNKNOWN = 0, + ECORE_X_WINDOW_STATE_ICONIFIED, /**< The window is iconified */ + ECORE_X_WINDOW_STATE_MODAL, /**< The window is a modal dialog box */ + ECORE_X_WINDOW_STATE_STICKY, /**< The window manager should keep the window's position fixed + * even if the virtual desktop scrolls */ + ECORE_X_WINDOW_STATE_MAXIMIZED_VERT, /**< The window has the maximum vertical size */ + ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ, /**< The window has the maximum horizontal size */ + ECORE_X_WINDOW_STATE_SHADED, /**< The window is shaded */ + ECORE_X_WINDOW_STATE_SKIP_TASKBAR, /**< The window should not be included in the taskbar */ + ECORE_X_WINDOW_STATE_SKIP_PAGER, /**< The window should not be included in the pager */ + ECORE_X_WINDOW_STATE_HIDDEN, /**< The window is invisible (i.e. minimized/iconified) */ + ECORE_X_WINDOW_STATE_FULLSCREEN, /**< The window should fill the entire screen and have no + * window border/decorations */ + ECORE_X_WINDOW_STATE_ABOVE, + ECORE_X_WINDOW_STATE_BELOW, ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION } Ecore_X_Window_State; @@ -160,6 +167,26 @@ typedef enum _Ecore_X_Window_Stack_Mode ECORE_X_WINDOW_STACK_OPPOSITE = 4 } Ecore_X_Window_Stack_Mode; +/** + * @typedef _Ecore_X_Window_Rotation_Transform_Hint + * @brief Enumeration of the different transform hints of the window of Ecore_X. + * + * @remarks A value of @c 3 means, HINT_0 goes to HINT_180(0x3). + * It is same as HINT_0 goes to HINT_FLIP_H(0x1) and it goes to HINT_FLIP_V(0x2).( 0x1 + 0x2 = 0x3 ) + * + * @remarks A value of @c 7 means, HINT_0 goes to HINT_270(0x7). + * It is same as HINT_0 goes to HINT_90(0x4) and it goes to HINT_FLIP_H(0x1) and HINT_FLIP_V(0x2).( 0x4 + 0x1 + 0x2 = 0x7 ) + */ +typedef enum _Ecore_X_Window_Rotation_Transform_Hint +{ + ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_0 = 0, + ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_FLIP_H = 0x1, /**< Rotate source image along the horizontal axis */ + ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_FLIP_V = 0x2, /**< Rotate source image along the vertical axis */ + ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_180 = 0x3, /**< Rotate source image 180 degrees clockwise */ + ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_90 = 0x4, /**< Rotate source image 90 degrees clockwise */ + ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_270 = 0x7 /**< Rotate source image 270 degrees clockwise */ +} Ecore_X_Window_Rotation_Transform_Hint; + typedef enum _Ecore_X_Randr_Orientation { ECORE_X_RANDR_ORIENTATION_ROT_0 = (1 << 0), @@ -353,31 +380,31 @@ typedef enum _Ecore_X_Netwm_Direction /** * @typedef _Ecore_X_Error_Code - * Defines the error codes of Ecore_X which wraps the X Window Systems - * protocol's errors. + * @brief Enumeration of the error codes of Ecore_X that wraps the X Window Systems + * protocol errors. * * @since 1.7.0 */ typedef enum _Ecore_X_Error_Code { - /** Everything is okay. */ - ECORE_X_ERROR_CODE_SUCCESS = 0, /** Bad request code */ - ECORE_X_ERROR_CODE_BAD_REQUEST = 1, /** Int parameter out of range */ - ECORE_X_ERROR_CODE_BAD_VALUE = 2, /** Parameter not a Window */ - ECORE_X_ERROR_CODE_BAD_WINDOW = 3, /** Parameter not a Pixmap */ - ECORE_X_ERROR_CODE_BAD_PIXMAP = 4, /** Parameter not an Atom */ - ECORE_X_ERROR_CODE_BAD_ATOM = 5, /** Parameter not a Cursor */ - ECORE_X_ERROR_CODE_BAD_CURSOR = 6, /** Parameter not a Font */ - ECORE_X_ERROR_CODE_BAD_FONT = 7, /** Parameter mismatch */ - ECORE_X_ERROR_CODE_BAD_MATCH = 8, /** Parameter not a Pixmap or Window */ - ECORE_X_ERROR_CODE_BAD_DRAWABLE = 9, /** Bad access */ - ECORE_X_ERROR_CODE_BAD_ACCESS = 10, /** Insufficient resources */ - ECORE_X_ERROR_CODE_BAD_ALLOC = 11, /** No such colormap */ - ECORE_X_ERROR_CODE_BAD_COLOR = 12, /** Parameter not a GC */ - ECORE_X_ERROR_CODE_BAD_GC = 13, /** Choice not in range or already used */ - ECORE_X_ERROR_CODE_BAD_ID_CHOICE = 14, /** Font or color name doesn't exist */ - ECORE_X_ERROR_CODE_BAD_NAME = 15, /** Request length incorrect */ - ECORE_X_ERROR_CODE_BAD_LENGTH = 16, /** Server is defective */ + /** Everything is okay */ + ECORE_X_ERROR_CODE_SUCCESS = 0, /**< Bad request code */ + ECORE_X_ERROR_CODE_BAD_REQUEST = 1, /**< Integer parameter is out of range */ + ECORE_X_ERROR_CODE_BAD_VALUE = 2, /**< Parameter is not a Window */ + ECORE_X_ERROR_CODE_BAD_WINDOW = 3, /**< Parameter is not a Pixmap */ + ECORE_X_ERROR_CODE_BAD_PIXMAP = 4, /**< Parameter is not an Atom */ + ECORE_X_ERROR_CODE_BAD_ATOM = 5, /**< Parameter is not a Cursor */ + ECORE_X_ERROR_CODE_BAD_CURSOR = 6, /**< Parameter is not a Font */ + ECORE_X_ERROR_CODE_BAD_FONT = 7, /**< Parameter mismatch */ + ECORE_X_ERROR_CODE_BAD_MATCH = 8, /**< Parameter is not a Pixmap or Window */ + ECORE_X_ERROR_CODE_BAD_DRAWABLE = 9, /**< Bad access */ + ECORE_X_ERROR_CODE_BAD_ACCESS = 10, /**< Insufficient resources */ + ECORE_X_ERROR_CODE_BAD_ALLOC = 11, /**< No such colormap */ + ECORE_X_ERROR_CODE_BAD_COLOR = 12, /**< Parameter is not a GC */ + ECORE_X_ERROR_CODE_BAD_GC = 13, /**< Choice is not in the range or already used */ + ECORE_X_ERROR_CODE_BAD_ID_CHOICE = 14, /**< Font or color name doesn't exist */ + ECORE_X_ERROR_CODE_BAD_NAME = 15, /**< Request length is incorrect */ + ECORE_X_ERROR_CODE_BAD_LENGTH = 16, /**< Server is defective */ ECORE_X_ERROR_CODE_BAD_IMPLEMENTATION = 17, } Ecore_X_Error_Code; @@ -543,6 +570,7 @@ struct _Ecore_X_Event_Window_Hide Ecore_X_Window win; Ecore_X_Window event_win; Ecore_X_Time time; + Eina_Bool send_event : 1; }; struct _Ecore_X_Event_Window_Show @@ -837,7 +865,7 @@ struct _Ecore_X_Event_Screen_Change { Ecore_X_Window win; Ecore_X_Window root; - Ecore_X_Randr_Screen_Size_MM size; /* in pixel and millimeters */ + Ecore_X_Randr_Screen_Size_MM size; /* In pixel and millimeters */ Ecore_X_Time time; Ecore_X_Time config_time; Ecore_X_Randr_Orientation orientation; @@ -986,9 +1014,9 @@ struct _Ecore_X_Event_Generic void *data; }; -EAPI extern int ECORE_X_EVENT_ANY; /**< low level event dependent on - backend in use, if Xlib will be XEvent, if XCB will be xcb_generic_event_t. - @warning avoid using it. +EAPI extern int ECORE_X_EVENT_ANY; /**< Low level event is dependent on the + backend being used, if Xlib is XEvent, if XCB is xcb_generic_event_t. + @remarks Avoid using it */ EAPI extern int ECORE_X_EVENT_MOUSE_IN; EAPI extern int ECORE_X_EVENT_MOUSE_OUT; @@ -1046,6 +1074,8 @@ EAPI extern int ECORE_X_EVENT_DESKTOP_CHANGE; EAPI extern int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW; EAPI extern int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE; EAPI extern int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE; +EAPI extern int ECORE_X_EVENT_XKB_STATE_NOTIFY; /** @since 1.7 */ +EAPI extern int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY; /** @since 1.7 */ EAPI extern int ECORE_X_EVENT_GENERIC; @@ -1067,61 +1097,71 @@ EAPI extern int ECORE_X_LOCK_NUM; EAPI extern int ECORE_X_LOCK_CAPS; EAPI extern int ECORE_X_LOCK_SHIFT; +EAPI extern int ECORE_X_RAW_BUTTON_PRESS; /**< @since 1.8 */ +EAPI extern int ECORE_X_RAW_BUTTON_RELEASE; /**< @since 1.8 */ +EAPI extern int ECORE_X_RAW_MOTION; /**< @since 1.8 */ + +/** + * @brief Ecore X WM Protocol + */ typedef enum _Ecore_X_WM_Protocol { - /** If enabled the window manager will be asked to send a - * delete message instead of just closing (destroying) the window. */ + /**< If enabled, the window manager is asked to send a + * delete message instead of just closing (destroying) the window */ ECORE_X_WM_PROTOCOL_DELETE_REQUEST, - /** If enabled the window manager will be told that the window - * explicitly sets input focus. */ + /**< If enabled, the window manager is told that the window + * explicitly sets the input focus */ ECORE_X_WM_PROTOCOL_TAKE_FOCUS, - /** If enabled the window manager can ping the window to check - * if it is alive. */ + /**< If enabled, the window manager can ping the window to check + * if it is alive */ ECORE_X_NET_WM_PROTOCOL_PING, - /** If enabled the window manager can sync updating with the + /**< If enabled, the window manager can sync updating with the * window (?) */ ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST, - /** Number of defined items */ + /**< Number of defined items */ ECORE_X_WM_PROTOCOL_NUM } Ecore_X_WM_Protocol; +/** + * @brief Enumeration Ecore X Window Input Mode type + */ typedef enum _Ecore_X_Window_Input_Mode { - /** The window can never be focused */ + /**< The window can never be focused */ ECORE_X_WINDOW_INPUT_MODE_NONE, - /** The window can be focused by the WM but doesn't focus itself */ + /**< The window can be focused by the WM but doesn't focus itself */ ECORE_X_WINDOW_INPUT_MODE_PASSIVE, - /** The window sets the focus itself if one of its sub-windows - * already is focused */ + /**< The window sets the focus on its own if one of its sub-windows + * is already focused */ ECORE_X_WINDOW_INPUT_MODE_ACTIVE_LOCAL, - /** The window sets the focus itself even if another window + /**< The window sets the focus itself even if another window * is currently focused */ ECORE_X_WINDOW_INPUT_MODE_ACTIVE_GLOBAL } Ecore_X_Window_Input_Mode; /** * @typedef _Ecore_X_Window_State_Hint - * Defines the different state hint of the window of Ecore_X. + * @brief Enumeration of the different state hints of the window of Ecore_X. */ typedef enum _Ecore_X_Window_State_Hint { - /** Do not provide any state hint to the window manager */ + /**< Do not provide any state hint to the window manager */ ECORE_X_WINDOW_STATE_HINT_NONE = -1, - /** The window wants to remain hidden and NOT iconified */ + /**< The window wants to remain hidden and NOT iconified */ ECORE_X_WINDOW_STATE_HINT_WITHDRAWN, - /** The window wants to be mapped normally */ + /**< The window wants to be mapped normally */ ECORE_X_WINDOW_STATE_HINT_NORMAL, - /** The window wants to start in an iconified state */ + /**< The window wants to start in an iconified state */ ECORE_X_WINDOW_STATE_HINT_ICONIC } Ecore_X_Window_State_Hint; @@ -1225,13 +1265,23 @@ typedef enum _Ecore_X_Illume_Indicator_Opacity_Mode ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN = 0, ECORE_X_ILLUME_INDICATOR_OPAQUE, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT, - ECORE_X_ILLUME_INDICATOR_TRANSPARENT + ECORE_X_ILLUME_INDICATOR_TRANSPARENT, + ECORE_X_ILLUME_INDICATOR_BG_TRANSPARENT } Ecore_X_Illume_Indicator_Opacity_Mode; +typedef enum _Ecore_X_Illume_Indicator_Type_Mode +{ + ECORE_X_ILLUME_INDICATOR_TYPE_UNKNOWN = 0, + ECORE_X_ILLUME_INDICATOR_TYPE_1, + ECORE_X_ILLUME_INDICATOR_TYPE_2, + ECORE_X_ILLUME_INDICATOR_TYPE_3 +} Ecore_X_Illume_Indicator_Type_Mode; + typedef enum _Ecore_X_Illume_Window_State { ECORE_X_ILLUME_WINDOW_STATE_NORMAL = 0, - ECORE_X_ILLUME_WINDOW_STATE_FLOATING + ECORE_X_ILLUME_WINDOW_STATE_FLOATING, + ECORE_X_ILLUME_WINDOW_STATE_ASSISTANT_MENU } Ecore_X_Illume_Window_State; /* Window layer constants */ @@ -1247,21 +1297,55 @@ typedef enum _Ecore_X_Illume_Window_State EAPI int ecore_x_init(const char *name); EAPI int ecore_x_shutdown(void); EAPI int ecore_x_disconnect(void); + +/** + * Retrieves the Ecore_X_Display handle used for the current X connection. + * @return The current X display. + * @ingroup Ecore_X_Display_Attr_Group + */ EAPI Ecore_X_Display *ecore_x_display_get(void); EAPI Ecore_X_Connection *ecore_x_connection_get(void); EAPI int ecore_x_fd_get(void); EAPI Ecore_X_Screen *ecore_x_default_screen_get(void); EAPI void ecore_x_screen_size_get(const Ecore_X_Screen *screen, int *w, int *h); + +/** + * Retrieves the number of screens. + * + * @return The count of the number of screens. + * @ingroup Ecore_X_Display_Attr_Group + * + * @since 1.1 + */ EAPI int ecore_x_screen_count_get(void); EAPI int ecore_x_screen_index_get(const Ecore_X_Screen *screen); EAPI Ecore_X_Screen *ecore_x_screen_get(int index); EAPI void ecore_x_double_click_time_set(double t); + +/** + * @brief Retrieves the double and triple click flag timeout. + * + * @see ecore_x_double_click_time_set for more information. + * + * @return The timeout for double clicks in seconds. + * @ingroup Ecore_X_Display_Attr_Group + */ EAPI double ecore_x_double_click_time_get(void); EAPI void ecore_x_flush(void); EAPI void ecore_x_sync(void); EAPI void ecore_x_killall(Ecore_X_Window root); EAPI void ecore_x_kill(Ecore_X_Window win); + +/** + * Return the screen DPI + * + * This is a simplistic call to get DPI. It does not account for differing + * DPI in the x amd y axes nor does it account for multihead or xinerama and + * xrander where different parts of the screen may have different DPI etc. + * + * @return the general screen DPI (dots/pixels per inch). + */ EAPI int ecore_x_dpi_get(void); EAPI Eina_Bool ecore_x_bell(int percent); EAPI unsigned int ecore_x_visual_id_get(Ecore_X_Visual visual); @@ -1303,6 +1387,7 @@ EAPI void ecore_x_selection_parser_add(const char *target, EAPI void ecore_x_selection_parser_del(const char *target); EAPI void ecore_x_selection_owner_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Time tm); EAPI Ecore_X_Window ecore_x_selection_owner_get(Ecore_X_Atom atom); +EAPI Eina_Bool ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *targprop, int *s); /** @since 1.8 */ EAPI void ecore_x_dnd_aware_set(Ecore_X_Window win, Eina_Bool on); EAPI int ecore_x_dnd_version_get(Ecore_X_Window win); @@ -1312,11 +1397,14 @@ EAPI void ecore_x_dnd_types_set(Ecore_X_Window win, const c EAPI void ecore_x_dnd_actions_set(Ecore_X_Window win, Ecore_X_Atom *actions, unsigned int num_actions); EAPI Eina_Bool ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size); EAPI Eina_Bool ecore_x_dnd_drop(void); +EAPI Eina_Bool ecore_x_dnd_self_begin(Ecore_X_Window source, unsigned char *data, int size); /**< @since 1.8 */ +EAPI Eina_Bool ecore_x_dnd_self_drop(void); /**< @since 1.8 */ EAPI void ecore_x_dnd_send_status(Eina_Bool will_accept, Eina_Bool suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action); EAPI void ecore_x_dnd_send_finished(void); EAPI void ecore_x_dnd_source_action_set(Ecore_X_Atom action); EAPI Ecore_X_Atom ecore_x_dnd_source_action_get(void); EAPI void ecore_x_dnd_callback_pos_update_set(void (*cb)(void *, Ecore_X_Xdnd_Position *data), const void *data); +EAPI Eina_Bool ecore_x_dnd_abort(Ecore_X_Window xwin_source); /**< @since 1.9 */ EAPI Ecore_X_Window ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h); EAPI Ecore_X_Window ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h); @@ -1324,6 +1412,7 @@ EAPI int ecore_x_window_argb_get(Ecore_X_Window win); EAPI Ecore_X_Window ecore_x_window_manager_argb_new(Ecore_X_Window parent, int x, int y, int w, int h); EAPI Ecore_X_Window ecore_x_window_argb_new(Ecore_X_Window parent, int x, int y, int w, int h); EAPI Ecore_X_Window ecore_x_window_override_argb_new(Ecore_X_Window parent, int x, int y, int w, int h); +EAPI Ecore_X_Window ecore_x_window_permanent_create(Ecore_X_Window parent, Ecore_X_Atom unique_atom); /* @since 1.9 */ EAPI Ecore_X_Window ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h); EAPI void ecore_x_window_configure(Ecore_X_Window win, Ecore_X_Window_Configure_Mask mask, int x, int y, int w, int h, int border_width, Ecore_X_Window sibling, int stack_mode); EAPI void ecore_x_window_cursor_set(Ecore_X_Window win, Ecore_X_Cursor c); @@ -1343,10 +1432,48 @@ EAPI Ecore_X_Window ecore_x_window_focus_get(void); EAPI void ecore_x_window_raise(Ecore_X_Window win); EAPI void ecore_x_window_lower(Ecore_X_Window win); EAPI void ecore_x_window_reparent(Ecore_X_Window win, Ecore_X_Window new_parent, int x, int y); + +/** + * Retrieves the size of the given window. + * @param win The given window. + * @param w Pointer to an integer into which the width is to be stored. + * @param h Pointer to an integer into which the height is to be stored. + * @ingroup Ecore_X_Window_Geometry_Group + */ EAPI void ecore_x_window_size_get(Ecore_X_Window win, int *w, int *h); + +/** + * Retrieves the geometry of the given window. + * + * Note that the x & y coordinates are relative to your parent. In + * particular for reparenting window managers - relative to you window border. + * If you want screen coordinates either walk the window tree to the root, + * else for ecore_evas applications see ecore_evas_geometry_get(). Elementary + * applications can use elm_win_screen_position_get(). + * + * @param win The given window. + * @param x Pointer to an integer in which the X position is to be stored. + * @param y Pointer to an integer in which the Y position is to be stored. + * @param w Pointer to an integer in which the width is to be stored. + * @param h Pointer to an integer in which the height is to be stored. + * @ingroup Ecore_X_Window_Geometry_Group + */ EAPI void ecore_x_window_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h); + +/** + * Retrieves the width of the border of the given window. + * @param win The given window. + * @return Width of the border of @p win. + * @ingroup Ecore_X_Window_Geometry_Group + */ EAPI int ecore_x_window_border_width_get(Ecore_X_Window win); EAPI void ecore_x_window_border_width_set(Ecore_X_Window win, int width); + +/** + * Retrieves the depth of the given window. + * @param win The given window. + * @return Depth of the window. + */ EAPI int ecore_x_window_depth_get(Ecore_X_Window win); EAPI void ecore_x_window_cursor_show(Ecore_X_Window win, Eina_Bool show); EAPI void ecore_x_window_defaults_set(Ecore_X_Window win); @@ -1450,13 +1577,14 @@ EAPI Ecore_X_Cursor ecore_x_cursor_shape_get(int shape); EAPI void ecore_x_cursor_size_set(int size); EAPI int ecore_x_cursor_size_get(void); -/* FIXME: these funcs need categorising */ +/* FIXME: These functions need categorising */ EAPI Ecore_X_Window *ecore_x_window_root_list(int *num_ret); EAPI Ecore_X_Window ecore_x_window_root_first_get(void); EAPI Eina_Bool ecore_x_window_manage(Ecore_X_Window win); EAPI void ecore_x_window_container_manage(Ecore_X_Window win); EAPI void ecore_x_window_client_manage(Ecore_X_Window win); EAPI void ecore_x_window_sniff(Ecore_X_Window win); +EAPI void ecore_x_window_unsniff(Ecore_X_Window win); EAPI void ecore_x_window_client_sniff(Ecore_X_Window win); EAPI Ecore_X_Atom ecore_x_atom_get(const char *name); @@ -1594,6 +1722,7 @@ EAPI void ecore_x_netwm_ping_send(Ecore_X_Window win) EAPI void ecore_x_netwm_sync_request_send(Ecore_X_Window win, unsigned int serial); EAPI void ecore_x_netwm_state_request_send(Ecore_X_Window win, Ecore_X_Window root, Ecore_X_Window_State s1, Ecore_X_Window_State s2, Eina_Bool set); EAPI void ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop); +EAPI void ecore_x_netwm_moveresize_request_send(Ecore_X_Window win, int x, int y, Ecore_X_Netwm_Direction direction, unsigned int button); EAPI void ecore_x_e_init(void); EAPI void ecore_x_e_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb); @@ -1621,9 +1750,12 @@ EAPI void ecore_x_e_illume_home_del_send(Ecore_X_Wind EAPI void ecore_x_e_illume_access_action_next_send(Ecore_X_Window win); EAPI void ecore_x_e_illume_access_action_prev_send(Ecore_X_Window win); EAPI void ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win); +EAPI void ecore_x_e_illume_access_action_over_send(Ecore_X_Window win); EAPI void ecore_x_e_illume_access_action_read_send(Ecore_X_Window win); EAPI void ecore_x_e_illume_access_action_read_next_send(Ecore_X_Window win); EAPI void ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win); +EAPI void ecore_x_e_illume_access_action_up_send(Ecore_X_Window win); +EAPI void ecore_x_e_illume_access_action_down_send(Ecore_X_Window win); EAPI void ecore_x_e_illume_drag_set(Ecore_X_Window win, unsigned int drag); EAPI Eina_Bool ecore_x_e_illume_drag_get(Ecore_X_Window win); @@ -1678,6 +1810,26 @@ EAPI void ecore_x_e_window_profile_set(Ecore_X_Windo EAPI void ecore_x_e_window_profile_list_set(Ecore_X_Window win, const char **profiles, unsigned int num_profiles); EAPI Eina_Bool ecore_x_e_window_profile_list_get(Ecore_X_Window win, const char ***profiles, int *ret_num); +EAPI void ecore_x_e_window_rotation_supported_set(Ecore_X_Window root, Eina_Bool enabled); +EAPI Eina_Bool ecore_x_e_window_rotation_supported_get(Ecore_X_Window root); +EAPI void ecore_x_e_window_rotation_app_set(Ecore_X_Window win, Eina_Bool set); +EAPI Eina_Bool ecore_x_e_window_rotation_app_get(Ecore_X_Window win); +EAPI void ecore_x_e_window_rotation_preferred_rotation_set(Ecore_X_Window win, int rot); +EAPI Eina_Bool ecore_x_e_window_rotation_preferred_rotation_get(Ecore_X_Window win, int *rot); +EAPI void ecore_x_e_window_rotation_available_rotations_set(Ecore_X_Window win, const int *rots, unsigned int count); +EAPI Eina_Bool ecore_x_e_window_rotation_available_rotations_get(Ecore_X_Window win, int **rots, unsigned int *count); +EAPI void ecore_x_e_window_rotation_change_prepare_send(Ecore_X_Window win, int rot, Eina_Bool resize, int w, int h); +EAPI void ecore_x_e_window_rotation_change_prepare_done_send(Ecore_X_Window root, Ecore_X_Window win, int rot); +EAPI void ecore_x_e_window_rotation_change_request_send(Ecore_X_Window win, int rot); +EAPI void ecore_x_e_window_rotation_change_done_send(Ecore_X_Window root, Ecore_X_Window win, int rot, int w, int h); +EAPI void ecore_x_e_window_rotation_geometry_set(Ecore_X_Window win, int rot, int x, int y, int w, int h); +EAPI Eina_Bool ecore_x_e_window_rotation_geometry_get(Ecore_X_Window win, int rot, int *x, int *y, int *w, int *h); +EAPI void ecore_x_e_virtual_keyboard_control_window_set(Ecore_X_Window root, Ecore_X_Window win, unsigned int zone, Eina_Bool set); +EAPI void ecore_x_e_virtual_keyboard_on_prepare_request_send(Ecore_X_Window win); +EAPI void ecore_x_e_virtual_keyboard_on_prepare_done_send(Ecore_X_Window root, Ecore_X_Window win); +EAPI void ecore_x_e_virtual_keyboard_off_prepare_request_send(Ecore_X_Window win); +EAPI void ecore_x_e_virtual_keyboard_off_prepare_done_send(Ecore_X_Window root, Ecore_X_Window win); + EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter); EAPI Eina_Bool ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm); EAPI Eina_Bool ecore_x_sync_counter_query(Ecore_X_Sync_Counter counter, unsigned int *val); @@ -1705,8 +1857,10 @@ EAPI int ecore_x_screensaver_expose_get(void); EAPI void ecore_x_screensaver_interval_set(int timeout); EAPI int ecore_x_screensaver_interval_get(void); EAPI void ecore_x_screensaver_event_listen_set(Eina_Bool on); - -/* FIXME: these funcs need categorising */ +EAPI Eina_Bool ecore_x_screensaver_custom_blanking_enable(void); /** @since 1.7 */ +EAPI Eina_Bool ecore_x_screensaver_custom_blanking_disable(void); /** @since 1.7 */ + +/* FIXME: These functions need categorising */ typedef struct _Ecore_X_Window_Attributes { @@ -1780,8 +1934,8 @@ EAPI Eina_Bool ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecor /* ecore_x_randr.c */ /* The usage of 'Ecore_X_Randr_None' or 'Ecore_X_Randr_Unset' - * depends on the context. In most cases 'Ecore_X_Randr_Unset' - * can be used, but in some cases -1 is a special value to + * depends on the context. In most cases, 'Ecore_X_Randr_Unset' + * can be used, but in some cases @c -1 is a special value to * functions, thus 'Ecore_X_Randr_None' (=0) must be used. */ @@ -1819,13 +1973,14 @@ EAPI Eina_Bool ecore_x_randr_screen_primary_outp EAPI Ecore_X_Randr_Screen_Size_MM *ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, int *num); /** - * @brief get the current set size of a given screen's primary output - * @param root window which's primary output will be queried - * @param w the current size's width - * @param h the current size's height - * @param w_mm the current size's width in mm - * @param h_mm the current size's height in mm - * @param size_index of current set size to be used with ecore_x_randr_primary_output_size_set() + * @brief Gets the current set size of a given screen's primary output. + * + * @param[in] root The window whose primary output is queried + * @param[out] w The current size's width + * @param[out] h The current size's height + * @param[out] w_mm The current size's width in mm + * @param[out] h_mm The current size's height in mm + * @param[out] size_index The size index of the current set size to be used with ecore_x_randr_primary_output_size_set() */ EAPI void ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm, int *size_index); EAPI Eina_Bool ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, int size_index); @@ -1886,183 +2041,188 @@ EAPI Eina_Bool ecore_x_randr_output_crtc_set(Eco /* ecore_x_randr_12_edid.c */ /** - * @brief Validates the header from raw EDID data. + * @brief Validates the header from the raw EDID data. * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if the header is valid, @c EINA_FALSE otherwise. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return @c EINA_TRUE if the header is valid, + * otherwise @c EINA_FALSE */ EAPI Eina_Bool ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length); /** * @brief Checks whether a display's EDID has a valid checksum. * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if the checksum is valid, @c EINA_FALSE otherwise. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return @c EINA_TRUE if the checksum is valid, + * otherwise @c EINA_FALSE */ EAPI Eina_Bool ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the encoded version from raw EDID data. + * @brief Gets the encoded version from the raw EDID data. * - * The return value has the minor version in the lowest 8 bits, and the major - * version in all the rest of the bits. i.e. + * @remarks The return value has the minor version in the lowest 8 bits, and the major + * version in all the rest of the bits. i.e. * - * minor = (version & 0x000000ff); - * major = (version & 0xffffff00) >> 8; + * minor = (version & 0x000000ff); + * major = (version & 0xffffff00) >> 8; * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded major and minor version encasuplated an int. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The encoded major and minor version encasuplated an int */ EAPI int ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the encoded manufacturer from raw EDID data. + * @brief Gets the encoded manufacturer from the raw EDID data. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded manufacturer identifier. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The encoded manufacturer identifier */ EAPI char *ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the encoded name from raw EDID data. + * @brief Gets the encoded name from the raw EDID data. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded manufacturer identifier. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The encoded manufacturer identifier */ EAPI char *ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the encoded ASCII from raw EDID data. + * @brief Gets the encoded ASCII from the raw EDID data. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded ASCII display identifier. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The encoded ASCII display identifier */ EAPI char *ecore_x_randr_edid_display_ascii_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the encoded serial identifier from raw EDID data. + * @brief Gets the encoded serial identifier from the raw EDID data. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded serial identifier. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The encoded serial identifier */ EAPI char *ecore_x_randr_edid_display_serial_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the encoded model number from raw EDID data. + * @brief Gets the encoded model number from the raw EDID data. * - * The manufacturer ID table is necessary for a useful description. + * @remarks The manufacturer ID table is necessary for a useful description. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded model number. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The encoded model number */ EAPI int ecore_x_randr_edid_model_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the manufacturer serial number from raw EDID data. + * @brief Gets the manufacturer serial number from the raw EDID data. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded serial manufacturer serial number. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The encoded serial manufacturer serial number */ EAPI int ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the manufacturer model number from raw EDID data. + * @brief Gets the manufacturer model number from the raw EDID data. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The manufacturer's model number. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The manufacturer model number */ EAPI int ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Looks up the DPMS support from raw EDID data. + * @brief Looks for DPMS support from the raw EDID data. * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if DPMS is supported in some way, @c EINA_FALSE - * otherwise. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return @c EINA_TRUE if DPMS is supported in some way, + * otherwise @c EINA_FALSE */ EAPI Eina_Bool ecore_x_randr_edid_dpms_available_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Looks up the DPMS Standby support from raw EDID data. + * @brief Looks for DPMS Standby support from the raw EDID data. * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if DPMS Standby is supported, @c EINA_FALSE otherwise. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return @c EINA_TRUE if DPMS Standby is supported, + * otherwise @c EINA_FALSE */ EAPI Eina_Bool ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Looks up the DPMS Suspend support from raw EDID data. + * @brief Looks for DPMS Suspend support from the raw EDID data. * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if DPMS Suspend is supported, @c EINA_FALSE otherwise. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return @c EINA_TRUE if DPMS Suspend is supported, + * otherwise @c EINA_FALSE */ EAPI Eina_Bool ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Looks up the DPMS Off support from raw EDID data. + * @brief Looks for DPMS Off support from the raw EDID data. * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if DPMS Off is supported, @c EINA_FALSE otherwise. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return @c EINA_TRUE if DPMS Off is supported, + * otherwise @c EINA_FALSE */ EAPI Eina_Bool ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the preferred aspect ratio from raw EDID data. + * @brief Gets the preferred aspect ratio from the raw EDID data. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The preferred aspect ratio. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The preferred aspect ratio */ EAPI Ecore_X_Randr_Edid_Aspect_Ratio ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the supported aspect ratios from raw EDID data. + * @brief Gets the supported aspect ratios from the raw EDID data. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The supported aspect ratios. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The supported aspect ratios */ EAPI Ecore_X_Randr_Edid_Aspect_Ratio ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the supported colorschemes from raw EDID data. + * @brief Gets the supported colorschemes from the raw EDID data. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The supported colorschemes. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The supported colorschemes */ EAPI Ecore_X_Randr_Edid_Display_Colorscheme ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the display type from raw EDID data. + * @brief Gets the display type from the raw EDID data. * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if the display is a digital one, @c EINA_FALSE - * otherwise. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return @c EINA_TRUE if the display is a digital one, + * otherwise @c EINA_FALSE */ EAPI Eina_Bool ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, unsigned long edid_length); /** - * @brief Get the display interface type from raw EDID data. + * @brief Gets the display interface type from the raw EDID data. * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The interface type. + * @param[in] edid The edid structure + * @param[in] edid_length The length of the edid structure + * @return The interface type */ EAPI Ecore_X_Randr_Edid_Display_Interface_Type ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, unsigned long edid_length); @@ -2083,15 +2243,14 @@ EAPI Eina_Bool ecore_x_randr_output_signal_forma EAPI Ecore_X_Randr_Signal_Property *ecore_x_randr_output_signal_properties_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); EAPI int ecore_x_randr_output_connector_number_get(Ecore_X_Window root, Ecore_X_Randr_Output output); EAPI Ecore_X_Randr_Connector_Type ecore_x_randr_output_connector_type_get(Ecore_X_Window root, Ecore_X_Randr_Output output); -/* WTF - these dont exist in ecore-x!!!! +/* These dont exist in ecore-x */ EAPI Eina_Rectangle *ecore_x_randr_crtc_panning_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h); EAPI Eina_Bool ecore_x_randr_crtc_panning_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, const int y, const int w, const int h); EAPI Eina_Rectangle *ecore_x_randr_crtc_tracking_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h); EAPI Eina_Bool ecore_x_randr_crtc_tracking_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, const int y, const int w, const int h); EAPI Eina_Rectangle *ecore_x_randr_crtc_border_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc); EAPI Eina_Bool ecore_x_randr_crtc_border_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int left, const int top, const int right, const int bottom); -*/ - + /* XRender Support (horrendously incomplete) */ typedef Ecore_X_ID Ecore_X_Picture; @@ -2125,12 +2284,15 @@ EAPI void ecore_x_region_window_shape_set(Ecore_X_Region region, E EAPI void ecore_x_region_picture_clip_set(Ecore_X_Region region, Ecore_X_Picture picture, int x_origin, int y_origin); /** - * xfixes selection notification request. + * @brief Decides the xfixes selection for which to get a notification request. + * + * @details This lets you choose which selections you want to get notifications for. * - * This lets you choose which selections you want to get notifications for. - * @param selection The selection atom. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. * @since 1.1.0 + * + * @param[in] selection The selection atom + * @return @c EINA_TRUE on success, + * otherwise @c EINA_FALSE on failure */ EAPI Eina_Bool ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection); @@ -2170,6 +2332,12 @@ struct _Ecore_X_Event_Damage typedef struct _Ecore_X_Event_Damage Ecore_X_Event_Damage; +struct _Ecore_X_Event_Xkb +{ + int group; +}; +typedef struct _Ecore_X_Event_Xkb Ecore_X_Event_Xkb; /** @since 1.7 */ + EAPI Eina_Bool ecore_x_damage_query(void); EAPI Ecore_X_Damage ecore_x_damage_new(Ecore_X_Drawable d, Ecore_X_Damage_Report_Level level); EAPI void ecore_x_damage_free(Ecore_X_Damage damage); @@ -2197,11 +2365,12 @@ EAPI Eina_Bool ecore_x_test_fake_key_press(const char *key); EAPI const char *ecore_x_keysym_string_get(int keysym); /** - * Given a keyname, return the keycode representing that key - * @param keyname The key from which to get the keycode. - * @return The keycode of the key. + * @brief Returns the keycode representing a key, given that the keyname is provided. * * @since 1.2.0 + * + * @param[in] keyname The key from which to get the keycode + * @return The keycode of the key */ EAPI int ecore_x_keysym_keycode_get(const char *keyname); @@ -2217,6 +2386,10 @@ EAPI Eina_Bool ecore_x_image_is_argb32_get(Ecore_X_Image *im); EAPI Eina_Bool ecore_x_image_to_argb_convert(void *src, int sbpp, int sbpl, Ecore_X_Colormap c, Ecore_X_Visual v, int x, int y, int w, int h, unsigned int *dst, int dbpl, int dx, int dy); EAPI Eina_Bool ecore_x_input_multi_select(Ecore_X_Window win); +/** + * @since 1.8 + */ +EAPI Eina_Bool ecore_x_input_raw_select(Ecore_X_Window win); EAPI Eina_Bool ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win); @@ -2367,29 +2540,27 @@ EAPI Ecore_X_Illume_Indicator_State ecore_x_e_illume_indicator_state_get( EAPI void ecore_x_e_illume_indicator_state_send(Ecore_X_Window win, Ecore_X_Illume_Indicator_State state); EAPI void ecore_x_e_illume_indicator_opacity_set(Ecore_X_Window win, Ecore_X_Illume_Indicator_Opacity_Mode mode); - EAPI Ecore_X_Illume_Indicator_Opacity_Mode ecore_x_e_illume_indicator_opacity_get(Ecore_X_Window win); - EAPI void ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win, Ecore_X_Illume_Indicator_Opacity_Mode mode); -EAPI void -ecore_x_e_illume_window_state_set(Ecore_X_Window win, - Ecore_X_Illume_Window_State state); +EAPI void ecore_x_e_illume_indicator_type_set(Ecore_X_Window win, Ecore_X_Illume_Indicator_Type_Mode mode); +EAPI Ecore_X_Illume_Indicator_Type_Mode ecore_x_e_illume_indicator_type_get(Ecore_X_Window win); +EAPI void ecore_x_e_illume_indicator_type_send(Ecore_X_Window win, Ecore_X_Illume_Indicator_Type_Mode mode); -EAPI Ecore_X_Illume_Window_State -ecore_x_e_illume_window_state_get(Ecore_X_Window win); +EAPI void ecore_x_e_illume_window_state_set(Ecore_X_Window win, Ecore_X_Illume_Window_State state); +EAPI Ecore_X_Illume_Window_State ecore_x_e_illume_window_state_get(Ecore_X_Window win); +EAPI void ecore_x_e_illume_window_state_send(Ecore_X_Window win, Ecore_X_Illume_Window_State state); -EAPI void -ecore_x_e_illume_window_state_set(Ecore_X_Window win, - Ecore_X_Illume_Window_State state); - -EAPI Ecore_X_Illume_Window_State -ecore_x_e_illume_window_state_get(Ecore_X_Window win); +EAPI void ecore_x_xkb_select_group(int group); /* @since 1.7 */ #ifdef __cplusplus } #endif // ifdef __cplusplus +/** + * @} + */ + #include #include diff --git a/src/lib/ecore_x/Ecore_X_Atoms.h b/src/lib/ecore_x/Ecore_X_Atoms.h old mode 100644 new mode 100755 index c9af5bf..0038d7d --- a/src/lib/ecore_x/Ecore_X_Atoms.h +++ b/src/lib/ecore_x/Ecore_X_Atoms.h @@ -2,11 +2,12 @@ #define _ECORE_X_ATOMS_H /** + * @internal * @file - * @brief Ecore X atoms + * @brief Ecore X atoms. */ -/* generic atoms */ +/* Generic atoms */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_ATOM; EAPI extern Ecore_X_Atom ECORE_X_ATOM_CARDINAL; EAPI extern Ecore_X_Atom ECORE_X_ATOM_COMPOUND_TEXT; @@ -45,10 +46,10 @@ EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_LINK; EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_ASK; EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE; -/* old E atom */ +/* Old E atom */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_FRAME_SIZE; -/* old Gnome atom */ +/* Old Gnome atom */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_WIN_LAYER; /* ICCCM: client properties */ @@ -102,7 +103,7 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_VIRTUAL_ROOTS; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_LAYOUT; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_SHOWING_DESKTOP; -/* pager */ +/* Pager */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_CLOSE_WINDOW; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_MOVERESIZE_WINDOW; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_MOVERESIZE; @@ -115,7 +116,7 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_NAME; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_DESKTOP; -/* window type */ +/* Window type */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK; @@ -132,7 +133,7 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND; -/* state */ +/* State */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MODAL; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_STICKY; @@ -147,7 +148,7 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_ABOVE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_BELOW; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION; -/* allowed actions */ +/* Allowed actions */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MOVE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_RESIZE; @@ -187,7 +188,7 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_PRIMARY; EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_SECONDARY; EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD; -/* currently E specific virtual keyboard extension, aim to submit to netwm spec +/* Currently E specific virtual keyboard extension, aim to submit to netwm spec * later */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD; @@ -245,6 +246,11 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_BG_TRANSPARENT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_MODE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_1; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_2; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_3; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE; @@ -255,13 +261,23 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_GEOMETRY; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_ASSISTANT_MENU; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_OVER; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_BACK; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_SCROLL; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ZOOM; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_MOUSE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ENABLE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DISABLE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_COUNTER; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE; @@ -276,15 +292,49 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_PIXMAP; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_PARENT; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_POSITION; -/* currently elementary and E specific extension */ +/* For operating indicator and quickpanel */ +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_INDICATOR_FLICK_DONE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_MOVE_QUICKPANEL_STATE; + +/* Currently elementary and E specific extension */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_PROFILE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST; -/* for sliding window */ +/* For sliding window */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY; -/* for SDB(Samsung Debug Bridge) */ +/* For SDB */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT; EAPI extern Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT; + +/* E window rotation extension */ +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_TRANSFORM_HINT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_DESKTOP_LAYOUT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_REQUEST; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_REQUEST; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE; + +/* For deiconify approve protcol */ +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_DEICONIFY_APPROVE; + +/* For window auxiliary hint */ +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_AUX_HINT_SUPPORTED_LIST; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_AUX_HINT_SUPPORT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_AUX_HINT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_AUX_HINT_ALLOWED; #endif /* _ECORE_X_ATOMS_H */ diff --git a/src/lib/ecore_x/Ecore_X_Cursor.h b/src/lib/ecore_x/Ecore_X_Cursor.h index 807541e..05d3b8a 100644 --- a/src/lib/ecore_x/Ecore_X_Cursor.h +++ b/src/lib/ecore_x/Ecore_X_Cursor.h @@ -2,8 +2,9 @@ #define _ECORE_X_CURSOR_H /** + * @internal * @file - * @brief Defines the various cursor types for the X Windows system. + * @brief Definition for the various cursor types of the X Windows system. */ #define ECORE_X_CURSOR_X 0 diff --git a/src/lib/ecore_x/ecore_x_atoms_decl.h b/src/lib/ecore_x/ecore_x_atoms_decl.h old mode 100644 new mode 100755 index 85e1606..c1e7659 --- a/src/lib/ecore_x/ecore_x_atoms_decl.h +++ b/src/lib/ecore_x/ecore_x_atoms_decl.h @@ -271,6 +271,11 @@ EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE= 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_BG_TRANSPARENT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_MODE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_1 = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_2 = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_3 = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE = 0; @@ -281,13 +286,23 @@ EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_ASSISTANT_MENU = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_OVER = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_BACK = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_SCROLL = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ZOOM = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_MOUSE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ENABLE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DISABLE = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_COUNTER = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE = 0; @@ -304,11 +319,15 @@ EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_PIXMAP = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_PARENT = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_POSITION = 0; +/* for operating indicator and quickpanel */ +EAPI Ecore_X_Atom ECORE_X_ATOM_E_INDICATOR_FLICK_DONE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_MOVE_QUICKPANEL_STATE = 0; + /* for sliding window */ EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY = 0; -/* for SDB(Samsung Debug Bridge) */ +/* for SDB */ EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT = 0; @@ -316,6 +335,36 @@ EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST = 0; +/* E window rotation extension */ +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_TRANSFORM_HINT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_DESKTOP_LAYOUT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_REQUEST = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_REQUEST = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE = 0; + +/* for deiconify approve protcol */ +EAPI Ecore_X_Atom ECORE_X_ATOM_E_DEICONIFY_APPROVE = 0; + +/* for window auxiliary hint */ +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_AUX_HINT_SUPPORTED_LIST = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_AUX_HINT_SUPPORT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_AUX_HINT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_AUX_HINT_ALLOWED = 0; + typedef struct _Atom_Item Atom_Item; struct _Atom_Item @@ -565,6 +614,11 @@ const Atom_Item atom_items[] = { "_E_ILLUME_INDICATOR_OPAQUE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE }, { "_E_ILLUME_INDICATOR_TRANSLUCENT", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT }, { "_E_ILLUME_INDICATOR_TRANSPARENT", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT }, + { "_E_ILLUME_INDICATOR_BG_TRANSPARENT", &ECORE_X_ATOM_E_ILLUME_INDICATOR_BG_TRANSPARENT }, + { "_E_ILLUME_INDICATOR_TYPE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_MODE }, + { "_E_ILLUME_INDICATOR_TYPE_0", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_1 }, + { "_E_ILLUME_INDICATOR_TYPE_1", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_2 }, + { "_E_ILLUME_INDICATOR_TYPE_2", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_3 }, { "_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLES", &ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE }, { "_E_ILLUME_ROTATE_WINDOW_ANGLE", &ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE }, { "_E_ILLUME_ROTATE_ROOT_ANGLE", &ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE }, @@ -575,13 +629,23 @@ const Atom_Item atom_items[] = { "_E_ILLUME_WINDOW_STATE", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE }, { "_E_ILLUME_WINDOW_STATE_NORMAL", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL }, { "_E_ILLUME_WINDOW_STATE_FLOATING", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING }, + { "_E_ILLUME_WINDOW_STATE_ASSISTANT_MENU", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_ASSISTANT_MENU }, { "_E_ILLUME_ACCESS_CONTROL", &ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL }, { "_E_ILLUME_ACCESS_ACTION_NEXT", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT }, { "_E_ILLUME_ACCESS_ACTION_PREV", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV }, { "_E_ILLUME_ACCESS_ACTION_ACTIVATE", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE }, + { "_E_ILLUME_ACCESS_ACTION_OVER", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_OVER }, { "_E_ILLUME_ACCESS_ACTION_READ", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ }, { "_E_ILLUME_ACCESS_ACTION_READ_NEXT", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT }, { "_E_ILLUME_ACCESS_ACTION_READ_PREV", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV }, + { "_E_ILLUME_ACCESS_ACTION_UP", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP }, + { "_E_ILLUME_ACCESS_ACTION_DOWN", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN }, + { "_E_ILLUME_ACCESS_ACTION_BACK", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_BACK }, + { "_E_ILLUME_ACCESS_ACTION_SCROLL", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_SCROLL }, + { "_E_ILLUME_ACCESS_ACTION_ZOOM", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ZOOM }, + { "_E_ILLUME_ACCESS_ACTION_MOUSE", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_MOUSE }, + { "_E_ILLUME_ACCESS_ACTION_ENABLE", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ENABLE }, + { "_E_ILLUME_ACCESS_ACTION_DISABLE", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DISABLE }, { "_E_COMP_SYNC_COUNTER", &ECORE_X_ATOM_E_COMP_SYNC_COUNTER }, { "_E_COMP_SYNC_DRAW_DONE", &ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE }, { "_E_COMP_SYNC_SUPPORTED", &ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED }, @@ -595,8 +659,31 @@ const Atom_Item atom_items[] = { "_E_VIDEO_PARENT", &ECORE_X_ATOM_E_VIDEO_PARENT }, { "_E_VIDEO_POSITION", &ECORE_X_ATOM_E_VIDEO_POSITION }, + { "_E_INDICATOR_FLICK_DONE", &ECORE_X_ATOM_E_INDICATOR_FLICK_DONE }, + { "_E_MOVE_QUICKPANEL_STATE", &ECORE_X_ATOM_E_MOVE_QUICKPANEL_STATE }, + { "_E_PROFILE", &ECORE_X_ATOM_E_PROFILE }, - { "_E_PROFILE_LIST", &ECORE_X_ATOM_E_PROFILE_LIST } + { "_E_PROFILE_LIST", &ECORE_X_ATOM_E_PROFILE_LIST }, + + { "_E_WINDOW_ROTATION_SUPPORTED", &ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED }, + { "_E_WINDOW_ROTATION_APP_SUPPORTED", &ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED }, + { "_E_WINDOW_ROTATION_AVAILABLE_LIST", &ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST }, + { "_E_WINDOW_ROTATION_PREFERRED_ROTATION", &ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION }, + { "_E_WINDOW_ROTATION_CHANGE_PREPARE", &ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE }, + { "_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE", &ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE }, + { "_E_WINDOW_ROTATION_CHANGE_REQUEST", &ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST }, + { "_E_WINDOW_ROTATION_CHANGE_DONE", &ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE }, + { "_E_WINDOW_ROTATION_0_GEOMETRY", &ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY }, + { "_E_WINDOW_ROTATION_90_GEOMETRY", &ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY }, + { "_E_WINDOW_ROTATION_180_GEOMETRY", &ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY }, + { "_E_WINDOW_ROTATION_270_GEOMETRY", &ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY }, + { "_E_WINDOW_ROTATION_TRANSFORM_HINT", &ECORE_X_ATOM_E_WINDOW_ROTATION_TRANSFORM_HINT }, + { "_E_ATOM_WINDOW_DESKTOP_LAYOUT", &ECORE_X_ATOM_E_WINDOW_DESKTOP_LAYOUT }, + { "_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW }, + { "_E_VIRTUAL_KEYBOARD_ON_PREPARE_REQUEST", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_REQUEST }, + { "_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE }, + { "_E_VIRTUAL_KEYBOARD_OFF_PREPARE_REQUEST", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_REQUEST }, + { "_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE } /* SLP additions after the comma */ , @@ -604,8 +691,15 @@ const Atom_Item atom_items[] = { "_E_ILLUME_SLIDING_WIN_STATE", &ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE }, { "_E_ILLUME_SLIDING_WIN_GEOMETRY", &ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY }, - /* for SDB(Samsung Debug Bridge) */ + /* for SDB */ { "_SDB_SERVER_CONNECT", &ECORE_X_ATOM_SDB_SERVER_CONNECT }, - { "_SDB_SERVER_DISCONNECT", &ECORE_X_ATOM_SDB_SERVER_DISCONNECT } + { "_SDB_SERVER_DISCONNECT", &ECORE_X_ATOM_SDB_SERVER_DISCONNECT }, + + { "_E_DEICONIFY_APPROVE", &ECORE_X_ATOM_E_DEICONIFY_APPROVE }, + + { "_E_WINDOW_AUX_HINT_SUPPORTED_LIST", &ECORE_X_ATOM_E_WINDOW_AUX_HINT_SUPPORTED_LIST }, + { "_E_WINDOW_AUX_HINT_SUPPORT", &ECORE_X_ATOM_E_WINDOW_AUX_HINT_SUPPORT }, + { "_E_WINDOW_AUX_HINT", &ECORE_X_ATOM_E_WINDOW_AUX_HINT }, + { "_E_WINDOW_AUX_HINT_ALLOWED", &ECORE_X_ATOM_E_WINDOW_AUX_HINT_ALLOWED } }; diff --git a/src/lib/ecore_x/xcb/ecore_xcb.c b/src/lib/ecore_x/xcb/ecore_xcb.c index 9d8910d..0ca779e 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb.c +++ b/src/lib/ecore_x/xcb/ecore_xcb.c @@ -1404,6 +1404,12 @@ ecore_x_default_depth_get(Ecore_X_Display *disp __UNUSED__, Ecore_X_Screen *scre return s->root_depth; } +EAPI void +ecore_x_xkb_select_group(int group) +{ + // XXX: implement me */ +} + /** * Sets the timeout for a double and triple clicks to be flagged. * diff --git a/src/lib/ecore_x/xcb/ecore_xcb_atoms.c b/src/lib/ecore_x/xcb/ecore_xcb_atoms.c index b01898f..c8c217e 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_atoms.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_atoms.c @@ -63,10 +63,6 @@ _ecore_xcb_atoms_finalize(void) * @p reply is @c NULL, the NULL atom is returned. Otherwise, the atom * associated to the name is returned. * - * To use this function, you must call before, and in order, - * ecore_x_atom_get_prefetch(), which sends the InternAtom request, - * then ecore_x_atom_get_fetch(), which gets the reply. - * * @ingroup Ecore_X_Atom_Group */ EAPI Ecore_X_Atom diff --git a/src/lib/ecore_x/xcb/ecore_xcb_dnd.c b/src/lib/ecore_x/xcb/ecore_xcb_dnd.c index 177e61d..cbce44f 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_dnd.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_dnd.c @@ -12,13 +12,13 @@ typedef struct _Version_Cache_Item } Version_Cache_Item; /* local function prototypes */ -static Eina_Bool _ecore_xcb_dnd_converter_copy(char *target __UNUSED__, +static Eina_Bool _ecore_xcb_dnd_converter_copy(char *target EINA_UNUSED, void *data, int size, void **data_ret, int *size_ret, - Ecore_X_Atom *tprop __UNUSED__, - int *count __UNUSED__); + Ecore_X_Atom *tprop EINA_UNUSED, + int *count EINA_UNUSED); /* local variables */ static int _ecore_xcb_dnd_init_count = 0; @@ -132,60 +132,6 @@ ecore_x_dnd_send_status(Eina_Bool will_accept, // ecore_x_flush(); } -EAPI Eina_Bool -ecore_x_dnd_drop(void) -{ - xcb_client_message_event_t ev; - Eina_Bool status = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - if (_source->dest) - { - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = _source->dest; - - if (_source->will_accept) - { - ev.type = ECORE_X_ATOM_XDND_DROP; - ev.data.data32[0] = _source->win; - ev.data.data32[1] = 0; - ev.data.data32[2] = _source->time; - - xcb_send_event(_ecore_xcb_conn, 0, _source->dest, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); - _source->state = ECORE_X_DND_SOURCE_DROPPED; - status = EINA_TRUE; - } - else - { - ev.type = ECORE_X_ATOM_XDND_LEAVE; - ev.data.data32[0] = _source->win; - ev.data.data32[1] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, _source->dest, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); - _source->state = ECORE_X_DND_SOURCE_IDLE; - } - } - else - { - ecore_x_selection_xdnd_clear(); - _source->state = ECORE_X_DND_SOURCE_IDLE; - } - - ecore_x_window_ignore_set(_source->win, 0); - _source->prev.window = 0; - - return status; -} - EAPI void ecore_x_dnd_aware_set(Ecore_X_Window win, Eina_Bool on) @@ -429,10 +375,11 @@ ecore_x_dnd_callback_pos_update_set(void (*cb)(void *, Ecore_X_Xdnd_Position *da _posupdatedata = (void *)data; } -EAPI Eina_Bool -ecore_x_dnd_begin(Ecore_X_Window source, - unsigned char *data, - int size) +static Eina_Bool +_ecore_x_dnd_begin(Ecore_X_Window source, + Eina_Bool self; + unsigned char *data, + int size) { LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -452,7 +399,7 @@ ecore_x_dnd_begin(Ecore_X_Window source, ecore_x_window_shadow_tree_flush(); _source->win = source; - ecore_x_window_ignore_set(_source->win, 1); + if (!self) ecore_x_window_ignore_set(_source->win, 1); _source->state = ECORE_X_DND_SOURCE_DRAGGING; _source->time = _ecore_xcb_events_last_time_get(); _source->prev.window = 0; @@ -465,6 +412,88 @@ ecore_x_dnd_begin(Ecore_X_Window source, return EINA_TRUE; } +static Eina_Bool +_ecore_x_dnd_drop(Eina_Bool self) +{ + xcb_client_message_event_t ev; + Eina_Bool status = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + if (_source->dest) + { + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = _source->dest; + + if (_source->will_accept) + { + ev.type = ECORE_X_ATOM_XDND_DROP; + ev.data.data32[0] = _source->win; + ev.data.data32[1] = 0; + ev.data.data32[2] = _source->time; + + xcb_send_event(_ecore_xcb_conn, 0, _source->dest, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); + _source->state = ECORE_X_DND_SOURCE_DROPPED; + status = EINA_TRUE; + } + else + { + ev.type = ECORE_X_ATOM_XDND_LEAVE; + ev.data.data32[0] = _source->win; + ev.data.data32[1] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, _source->dest, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); + _source->state = ECORE_X_DND_SOURCE_IDLE; + } + } + else + { + ecore_x_selection_xdnd_clear(); + _source->state = ECORE_X_DND_SOURCE_IDLE; + } + + if (!self) ecore_x_window_ignore_set(_source->win, 0); + _source->prev.window = 0; + + return status; +} + +EAPI Eina_Bool +ecore_x_dnd_begin(Ecore_X_Window source, + unsigned char *data, + int size) +{ + return _ecore_x_dnd_begin(source, EINA_FALSE, data, size); +} + +EAPI Eina_Bool +ecore_x_dnd_drop(void) +{ + return _ecore_x_dnd_drop(EINA_FALSE); +} + +EAPI Eina_Bool +ecore_x_dnd_self_begin(Ecore_X_Window source, + unsigned char *data, + int size) +{ + return _ecore_x_dnd_begin(source, EINA_TRUE, data, size); +} + +EAPI Eina_Bool +ecore_x_dnd_self_drop(void) +{ + return _ecore_x_dnd_drop(EINA_TRUE); +} + EAPI void ecore_x_dnd_send_finished(void) { @@ -529,11 +558,11 @@ _ecore_xcb_dnd_drag(Ecore_X_Window root, Ecore_X_Xdnd_Position pos; int num = 0; - if (_source->state != ECORE_X_DND_SOURCE_DRAGGING) return; - LOGFN(__FILE__, __LINE__, __FUNCTION__); CHECK_XCB_CONN; + if (_source->state != ECORE_X_DND_SOURCE_DRAGGING) return; + memset(&ev, 0, sizeof(xcb_client_message_event_t)); ev.response_type = XCB_CLIENT_MESSAGE; @@ -643,13 +672,13 @@ ecore_x_dnd_source_action_get(void) /* local functions */ static Eina_Bool -_ecore_xcb_dnd_converter_copy(char *target __UNUSED__, +_ecore_xcb_dnd_converter_copy(char *target EINA_UNUSED, void *data, int size, void **data_ret, int *size_ret, - Ecore_X_Atom *tprop __UNUSED__, - int *count __UNUSED__) + Ecore_X_Atom *tprop EINA_UNUSED, + int *count EINA_UNUSED) { Ecore_Xcb_Textproperty text_prop; Ecore_Xcb_Encoding_Style style = XcbTextStyle; @@ -686,3 +715,14 @@ _ecore_xcb_dnd_converter_copy(char *target __UNUSED__, } } +EAPI Eina_Bool +ecore_x_dnd_abort(Ecore_X_Window xwin_source) +{ + if (xwin_source == _source->win) + { + _source->will_accept = 0; + return ecore_x_dnd_self_drop(); + } + else return EINA_FALSE; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_e.c b/src/lib/ecore_x/xcb/ecore_xcb_e.c old mode 100644 new mode 100755 index d86d0c7..c53150a --- a/src/lib/ecore_x/xcb/ecore_xcb_e.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_e.c @@ -1,3 +1,33 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "ecore_xcb_private.h" /* local function prototypes */ @@ -240,6 +270,9 @@ ecore_x_e_window_profile_get(Ecore_X_Window win) if (atom) profile = ecore_x_atom_name_get(atom[0]); + if (data) + free(data); + return profile; } @@ -863,7 +896,7 @@ _ecore_xcb_e_clipboard_state_get(Ecore_X_Atom atom) if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF) return ECORE_X_ILLUME_CLIPBOARD_STATE_OFF; - return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; + return ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN; } EAPI void @@ -1066,6 +1099,18 @@ ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win) } EAPI void +ecore_x_e_illume_access_action_over_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_OVER, + 0, 0, 0); +} + +EAPI void ecore_x_e_illume_access_action_read_send(Ecore_X_Window win) { LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -1102,6 +1147,30 @@ ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win) } EAPI void +ecore_x_e_illume_access_action_up_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_down_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN, + 0, 0, 0); +} + +EAPI void ecore_x_e_illume_drag_set(Ecore_X_Window win, unsigned int drag) { @@ -1435,6 +1504,9 @@ _ecore_x_e_indicator_opacity_atom_get(Ecore_X_Illume_Indicator_Opacity_Mode mode case ECORE_X_ILLUME_INDICATOR_TRANSPARENT: return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT; + case ECORE_X_ILLUME_INDICATOR_BG_TRANSPARENT: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_BG_TRANSPARENT; + default: break; } @@ -1453,6 +1525,9 @@ _ecore_x_e_indicator_opacity_get(Ecore_X_Atom atom) if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT) return ECORE_X_ILLUME_INDICATOR_TRANSPARENT; + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_BG_TRANSPARENT) + return ECORE_X_ILLUME_INDICATOR_BG_TRANSPARENT; + return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN; } @@ -1496,6 +1571,80 @@ ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win, } static Ecore_X_Atom +_ecore_x_e_indicator_type_atom_get(Ecore_X_Illume_Indicator_Type_Mode mode) +{ + switch (mode) + { + case ECORE_X_ILLUME_INDICATOR_TYPE_1: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_1; + + case ECORE_X_ILLUME_INDICATOR_TYPE_2: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_2; + + case ECORE_X_ILLUME_INDICATOR_TYPE_3: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_3; + + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Indicator_Type_Mode +_ecore_x_e_indicator_type_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_1) + return ECORE_X_ILLUME_INDICATOR_TYPE_1; + + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_2) + return ECORE_X_ILLUME_INDICATOR_TYPE_2; + + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_3) + return ECORE_X_ILLUME_INDICATOR_TYPE_3; + + return ECORE_X_ILLUME_INDICATOR_TYPE_UNKNOWN; +} + +EAPI void +ecore_x_e_illume_indicator_type_set(Ecore_X_Window win, + Ecore_X_Illume_Indicator_Type_Mode mode) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + atom = _ecore_x_e_indicator_type_atom_get(mode); + ecore_x_window_prop_atom_set(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_MODE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Indicator_Type_Mode +ecore_x_e_illume_indicator_type_get(Ecore_X_Window win) +{ + Ecore_X_Atom atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!ecore_x_window_prop_atom_get(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_MODE, + &atom, 1)) + return ECORE_X_ILLUME_INDICATOR_TYPE_UNKNOWN; + + return _ecore_x_e_indicator_type_get(atom); +} + +EAPI void +ecore_x_e_illume_indicator_type_send(Ecore_X_Window win, + Ecore_X_Illume_Indicator_Type_Mode mode) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_MODE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_x_e_indicator_type_atom_get(mode), + 0, 0, 0, 0); +} + +static Ecore_X_Atom _ecore_x_e_illume_window_state_atom_get(Ecore_X_Illume_Window_State state) { switch (state) @@ -1506,6 +1655,9 @@ _ecore_x_e_illume_window_state_atom_get(Ecore_X_Illume_Window_State state) case ECORE_X_ILLUME_WINDOW_STATE_FLOATING: return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING; + case ECORE_X_ILLUME_WINDOW_STATE_ASSISTANT_MENU: + return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_ASSISTANT_MENU; + default: break; } @@ -1521,6 +1673,9 @@ _ecore_x_e_illume_window_state_get(Ecore_X_Atom atom) if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING) return ECORE_X_ILLUME_WINDOW_STATE_FLOATING; + if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_ASSISTANT_MENU) + return ECORE_X_ILLUME_WINDOW_STATE_ASSISTANT_MENU; + return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; } @@ -1550,3 +1705,14 @@ ecore_x_e_illume_window_state_get(Ecore_X_Window win) return _ecore_x_e_illume_window_state_get(atom); } +EAPI void +ecore_x_e_illume_window_state_send(Ecore_X_Window win, + Ecore_X_Illume_Window_State state) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, + ECORE_X_ATOM_E_ILLUME_WINDOW_STATE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_x_e_illume_window_state_atom_get(state), + 0, 0, 0, 0); +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_events.c b/src/lib/ecore_x/xcb/ecore_xcb_events.c index 272071f..39f4d82 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_events.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_events.c @@ -180,8 +180,14 @@ EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0; EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0; EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0; EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0; +EAPI int ECORE_X_EVENT_XKB_STATE_NOTIFY = 0; +EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0; EAPI int ECORE_X_EVENT_GENERIC = 0; +EAPI int ECORE_X_RAW_BUTTON_PRESS = 0; +EAPI int ECORE_X_RAW_BUTTON_RELEASE = 0; +EAPI int ECORE_X_RAW_MOTION = 0; + void _ecore_xcb_events_init(void) { @@ -243,7 +249,13 @@ _ecore_xcb_events_init(void) ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = ecore_event_type_new(); ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new(); ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new(); + ECORE_X_EVENT_XKB_STATE_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = ecore_event_type_new(); ECORE_X_EVENT_GENERIC = ecore_event_type_new(); + + ECORE_X_RAW_BUTTON_PRESS = ecore_event_type_new(); + ECORE_X_RAW_BUTTON_RELEASE = ecore_event_type_new(); + ECORE_X_RAW_MOTION = ecore_event_type_new(); } } @@ -1023,6 +1035,8 @@ _ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event) e->win = ev->window; e->event_win = ev->event; e->time = _ecore_xcb_event_last_time; + /* send_event is bit 7 (0x80) of response_type */ + e->send_event = ((ev->response_type & 0x80) ? 1 : 0); ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL); } @@ -1251,6 +1265,8 @@ _ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event) e->selection = ECORE_X_SELECTION_PRIMARY; else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY) e->selection = ECORE_X_SELECTION_SECONDARY; + else if (sel == ECORE_X_ATOM_SELECTION_XDND) + e->selection = ECORE_X_SELECTION_XDND; else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD) e->selection = ECORE_X_SELECTION_CLIPBOARD; else @@ -1344,13 +1360,9 @@ _ecore_xcb_event_handle_selection_notify(xcb_generic_event_t *event) } } else - { - format = - ecore_x_window_prop_property_get(ev->requestor, ev->property, - XCB_GET_PROPERTY_TYPE_ANY, 8, - &data, &num); - if (!format) return; - } + format = ecore_x_window_prop_property_get(ev->requestor, ev->property, + XCB_GET_PROPERTY_TYPE_ANY, 8, + &data, &num); e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify)); if (!e) return; @@ -1935,7 +1947,7 @@ _ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event) #ifdef ECORE_XCB_RANDR ev = (xcb_randr_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change)))) + if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Change)))) return; e->win = ev->u.oc.window; @@ -1991,7 +2003,8 @@ _ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event) e->win = ev->window; e->on = EINA_FALSE; - if (ev->state == XCB_SCREENSAVER_STATE_ON) e->on = EINA_TRUE; + if ((ev->state == XCB_SCREENSAVER_STATE_ON) || + (ev->state == XCB_SCREENSAVER_STATE_CYCLE)) e->on = EINA_TRUE; e->time = ev->time; ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL); @@ -2278,6 +2291,8 @@ _ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event) e->selection = ECORE_X_SELECTION_PRIMARY; else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY) e->selection = ECORE_X_SELECTION_SECONDARY; + else if (sel == ECORE_X_ATOM_SELECTION_XDND) + e->selection = ECORE_X_SELECTION_XDND; else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD) e->selection = ECORE_X_SELECTION_CLIPBOARD; else diff --git a/src/lib/ecore_x/xcb/ecore_xcb_image.c b/src/lib/ecore_x/xcb/ecore_xcb_image.c index 6789b94..b094b73 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_image.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_image.c @@ -1,3 +1,33 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "ecore_xcb_private.h" #include #include @@ -249,15 +279,15 @@ ecore_x_image_is_argb32_get(Ecore_X_Image *im) if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) && - (im->depth >= 24) && (vis->red_mask == 0xff0000) && - (vis->green_mask == 0x00ff00) && (vis->blue_mask == 0x0000ff)) + (im->bpp == 4) && + (vis->red_mask == 0xff0000) && + (vis->green_mask == 0x00ff00) && + (vis->blue_mask == 0x0000ff)) { #ifdef WORDS_BIGENDIAN - if (im->xim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST) - return EINA_TRUE; + if (im->xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST) return EINA_TRUE; #else - if (im->xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST) - return EINA_TRUE; + if (im->xim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST) return EINA_TRUE; #endif } @@ -289,6 +319,8 @@ ecore_x_image_to_argb_convert(void *src, rgb565, bgr565, rgbx555, + rgb888, + bgr888, argbx888, abgrx888, rgba888x, @@ -348,40 +380,56 @@ ecore_x_image_to_argb_convert(void *src, else if ((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) { - if ((vis->red_mask == 0x00ff0000) && - (vis->green_mask == 0x0000ff00) && - (vis->blue_mask == 0x000000ff)) - mode = argbx888; - else if ((vis->red_mask == 0x000000ff) && + if (sbpp == 24) + { + if ((vis->red_mask == 0x00ff0000) && (vis->green_mask == 0x0000ff00) && - (vis->blue_mask == 0x00ff0000)) - mode = abgrx888; - else if ((vis->red_mask == 0xff000000) && - (vis->green_mask == 0x00ff0000) && - (vis->blue_mask == 0x0000ff00)) - mode = rgba888x; - else if ((vis->red_mask == 0x0000ff00) && - (vis->green_mask == 0x00ff0000) && - (vis->blue_mask == 0xff000000)) - mode = bgra888x; - else if ((vis->red_mask == 0x0003f000) && - (vis->green_mask == 0x00000fc0) && - (vis->blue_mask == 0x0000003f)) - mode = argbx666; - else if ((vis->red_mask == 0x0000f800) && - (vis->green_mask == 0x000007e0) && - (vis->blue_mask == 0x0000001f)) - mode = rgb565; - else if ((vis->red_mask == 0x0000001f) && - (vis->green_mask == 0x000007e0) && - (vis->blue_mask == 0x0000f800)) - mode = bgr565; - else if ((vis->red_mask == 0x00007c00) && - (vis->green_mask == 0x000003e0) && - (vis->blue_mask == 0x0000001f)) - mode = rgbx555; + (vis->blue_mask == 0x000000ff)) + mode = rgb888; + else if ((vis->red_mask == 0x000000ff) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x00ff0000)) + mode = bgr888; + else + return EINA_FALSE; + } else - return EINA_FALSE; + { + if ((vis->red_mask == 0x00ff0000) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x000000ff)) + mode = argbx888; + else if ((vis->red_mask == 0x000000ff) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x00ff0000)) + mode = abgrx888; + else if ((vis->red_mask == 0xff000000) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0x0000ff00)) + mode = rgba888x; + else if ((vis->red_mask == 0x0000ff00) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0xff000000)) + mode = bgra888x; + else if ((vis->red_mask == 0x0003f000) && + (vis->green_mask == 0x00000fc0) && + (vis->blue_mask == 0x0000003f)) + mode = argbx666; + else if ((vis->red_mask == 0x0000f800) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgb565; + else if ((vis->red_mask == 0x0000001f) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000f800)) + mode = bgr565; + else if ((vis->red_mask == 0x00007c00) && + (vis->green_mask == 0x000003e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgbx555; + else + return EINA_FALSE; + } } for (row = 0; row < h; row++) { @@ -463,6 +511,29 @@ ecore_x_image_to_argb_convert(void *src, break; case 24: + s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + (x * (sbpp / 8)); + switch (mode) + { + case rgb888: + while (dp < de) + { + *dp = 0xff000000 | (s8[2] << 16) | (s8[1] << 8) | s8[0]; + s8 += 3; dp++; + } + break; + case bgr888: + while (dp < de) + { + *dp = 0xff000000 | (s8[0] << 16) | (s8[1] << 8) | s8[2]; + s8 += 3; dp++; + } + break; + default: + return EINA_FALSE; + break; + } + break; + case 32: s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; @@ -525,7 +596,6 @@ ecore_x_image_to_argb_convert(void *src, break; } break; - break; default: return EINA_FALSE; diff --git a/src/lib/ecore_x/xcb/ecore_xcb_randr.c b/src/lib/ecore_x/xcb/ecore_xcb_randr.c index a96b047..cc7d6a4 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_randr.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_randr.c @@ -2761,12 +2761,11 @@ ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_leng edid_name = (const char *)block + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; name = - malloc(sizeof(char) * - _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); + malloc(_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX + 1); if (!name) return NULL; strncpy(name, edid_name, - (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); + _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; for (p = name; *p; p++) if ((*p < ' ') || (*p > '~')) *p = 0; diff --git a/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c b/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c index cb7249f..6106450 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c @@ -324,7 +324,8 @@ ecore_x_screensaver_event_listen_set(Eina_Bool on) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; if (on) xcb_screensaver_select_input(_ecore_xcb_conn, root, - XCB_SCREENSAVER_EVENT_NOTIFY_MASK); + XCB_SCREENSAVER_EVENT_NOTIFY_MASK | + XCB_SCREENSAVER_EVENT_CYCLE_MASK); else xcb_screensaver_select_input(_ecore_xcb_conn, root, 0); #endif @@ -336,3 +337,34 @@ ecore_x_screensaver_event_available_get(void) return _screensaver_avail; } +EAPI Eina_Bool +ecore_x_screensaver_custom_blanking_enable(void) +{ +#ifdef ECORE_XCB_SCREENSAVER + uint32_t mask_list[9]; + + xcb_screensaver_set_attributes_checked + (_ecore_xcb_conn, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + -9999, -9999, 1, 1, 0, + XCB_WINDOW_CLASS_INPUT_ONLY, + XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT, + 0, mask_list); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + +EAPI Eina_Bool +ecore_x_screensaver_custom_blanking_disable(void) +{ +#ifdef ECORE_XCB_SCREENSAVER + xcb_screensaver_unset_attributes_checked + (_ecore_xcb_conn, + ((xcb_screen_t *)_ecore_xcb_screen)->root); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_selection.c b/src/lib/ecore_x/xcb/ecore_xcb_selection.c index afb1b8c..16be9fe 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_selection.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_selection.c @@ -1,16 +1,39 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "ecore_xcb_private.h" //#include "Ecore_X_Atoms.h" #define ECORE_XCB_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x)) /* local function prototypes */ -static Eina_Bool _ecore_xcb_selection_converter_text(char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *type, - int *size_type); static void *_ecore_xcb_selection_parser_text(const char *target __UNUSED__, void *data, int size, @@ -53,13 +76,13 @@ _ecore_xcb_selection_init(void) /* init converters */ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT, - _ecore_xcb_selection_converter_text); + ecore_x_selection_converter_text); ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING, - _ecore_xcb_selection_converter_text); + ecore_x_selection_converter_text); ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT, - _ecore_xcb_selection_converter_text); + ecore_x_selection_converter_text); ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING, - _ecore_xcb_selection_converter_text); + ecore_x_selection_converter_text); /* init parsers */ ecore_x_selection_parser_add("text/plain", @@ -456,7 +479,7 @@ ecore_x_selection_convert(Ecore_X_Atom selection, { Ecore_X_Selection_Intern *sel; Ecore_X_Selection_Converter *cnv; - void *data; + void *data = NULL; char *tgt_str; LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -468,7 +491,7 @@ ecore_x_selection_convert(Ecore_X_Atom selection, { if (cnv->target == target) { - int r = 0; + int r; r = cnv->convert(tgt_str, sel->data, sel->length, &data, size, targtype, typesize); @@ -482,6 +505,7 @@ ecore_x_selection_convert(Ecore_X_Atom selection, return EINA_FALSE; } } + free(tgt_str); return EINA_FALSE; } @@ -624,6 +648,12 @@ _ecore_xcb_selection_set(Ecore_X_Window win, else return EINA_FALSE; + if (_selections[in].data) + { + free(_selections[in].data); + memset(&_selections[in], 0, sizeof(Ecore_X_Selection_Intern)); + } + if (data) { unsigned char *buff = NULL; @@ -638,11 +668,6 @@ _ecore_xcb_selection_set(Ecore_X_Window win, memcpy(buff, data, size); _selections[in].data = buff; } - else if (_selections[in].data) - { - free(_selections[in].data); - memset(&_selections[in], 0, sizeof(Ecore_X_Selection_Data)); - } return EINA_TRUE; } @@ -672,14 +697,14 @@ _ecore_xcb_selection_request(Ecore_X_Window win, XCB_CURRENT_TIME); } -static Eina_Bool -_ecore_xcb_selection_converter_text(char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *type __UNUSED__, - int *size_type __UNUSED__) +EAPI Eina_Bool +ecore_x_selection_converter_text(char *target, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *type __UNUSED__, + int *size_type __UNUSED__) { Ecore_Xcb_Encoding_Style style; Ecore_Xcb_Textproperty ret; @@ -755,7 +780,7 @@ _ecore_xcb_selection_parser_text(const char *target __UNUSED__, sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text)); if (!sel) return NULL; - if (_data[size - 1]) + if (_data && _data[size - 1]) { size++; t = realloc(_data, size); @@ -797,7 +822,7 @@ _ecore_xcb_selection_parser_files(const char *target, ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_files_free; - if (_data[size - 1]) + if (_data && _data[size - 1]) { size++; t = realloc(_data, size); @@ -871,13 +896,13 @@ _ecore_xcb_selection_parser_targets(const char *target __UNUSED__, int format __UNUSED__) { Ecore_X_Selection_Data_Targets *sel; - unsigned long *targets; + int *targets; int i = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); CHECK_XCB_CONN; - if (!(targets = (unsigned long *)data)) return NULL; + if (!(targets = data)) return NULL; sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets)); if (!sel) return NULL; diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window.c b/src/lib/ecore_x/xcb/ecore_xcb_window.c index 8e38c5a..af4f629 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_window.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_window.c @@ -1,3 +1,33 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "ecore_xcb_private.h" #ifdef ECORE_XCB_RENDER # include @@ -309,6 +339,88 @@ ecore_x_window_override_argb_new(Ecore_X_Window parent, return win; } +EAPI Ecore_X_Window +ecore_x_window_permanent_create(Ecore_X_Window parent, + Ecore_X_Atom unique_atom) +{ + xcb_connection_t *conn; + Ecore_X_Window win, win2, realwin; + uint32_t mask, mask_list[9]; + xcb_get_property_reply_t *reply; + xcb_get_property_cookie_t cookie; + unsigned long ldata, *datap; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + conn = xcb_connect(name, NULL); + if (!conn) return 0; + + xcb_grab_server(conn); + cookie = xcb_get_property_unchecked(conn, 0, parent, unique_atom, + ECORE_X_ATOM_WINDOW, 0, 0x7fffffff); + reply = xcb_get_property_reply(conn, cookie, NULL); + if (reply) + { + if ((reply->type == ECORE_X_ATOM_WINDOW) && (reply->format == 32) && + (reply->value_len == 1) && + ((datap = (unsigned long *)xcb_get_property_value(reply)))) + { + win = (Ecore_X_Window)(*datap); + free(reply); + cookie = xcb_get_property_unchecked(conn, 0, win, unique_atom, + ECORE_X_ATOM_WINDOW, 0, 0x7fffffff); + reply = xcb_get_property_reply(conn, cookie, NULL); + if (reply) + { + if ((reply->type == ECORE_X_ATOM_WINDOW) && (reply->format == 32) && + (reply->value_len == 1) && + ((datap = (unsigned long *)xcb_get_property_value(reply)))) + { + win2 = (Ecore_X_Window)(*datap); + free(reply); + if (win2 == win) realwin = win; + } + else free(reply); + } + } + else free(reply); + } + if (realwin != 0) + { + xcb_ungrab_server(conn); + xcb_flush(conn); + xcb_disconnect(conn); + return realwin; + } + mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | + XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | + XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | + XCB_CW_DONT_PROPAGATE); + mask_list[0] = XCB_BACK_PIXMAP_NONE; + mask_list[1] = 0; + mask_list[2] = XCB_GRAVITY_NORTH_WEST; + mask_list[3] = XCB_GRAVITY_NORTH_WEST; + mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL; + mask_list[5] = 1; + mask_list[6] = 0; + mask_list[7] = XCB_EVENT_MASK_NO_EVENT; + mask_list[8] = XCB_EVENT_MASK_NO_EVENT; + win = xcb_generate_id(conn); + xcb_create_window(conn, XCB_COPY_FROM_PARENT, + win, parent, -77, -77, 7, 7, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + XCB_COPY_FROM_PARENT, mask, mask_list); + ldata = (unsigned long)win; + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, unique_atom, + ECORE_X_ATOM_WINDOW, 32, 1, (unsigned char *)ldata); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, parent, unique_atom, + ECORE_X_ATOM_WINDOW, 32, 1, (unsigned char *)ldata); + xcb_set_close_down_mode(conn, XCB_CLOSE_DOWN_RETAIN_PERMANENT); + xcb_ungrab_server(conn); + xcb_flush(conn); + xcb_disconnect(conn); + return win; +} + /** * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions * @@ -1050,6 +1162,16 @@ ecore_x_window_sniff(Ecore_X_Window win) } EAPI void +ecore_x_window_unsniff(Ecore_X_Window win) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); +///TODO: implement xcb +// ecore_x_flush(); +} + +EAPI void ecore_x_window_client_sniff(Ecore_X_Window win) { uint32_t list; diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c b/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c index bbca2a5..58444cd 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c @@ -507,12 +507,6 @@ ecore_x_region_extents(Ecore_X_Region dest, * @param bounds The returned bounds of the region. * @return The returned rectangles. * - * The @p region passed to ecore_xcb_region_fetch_prefetch() is - * returned as a list of rectagles in XY-banded order. - * - * To use this function, you must call before, and in order, - * ecore_xcb_region_fetch_prefetch(), which sends the XFixesFetchRegion request, - * then ecore_xcb_region_fetch_fetch(), which gets the reply. * @ingroup Ecore_X_Fixes_Group */ EAPI Ecore_X_Rectangle * diff --git a/src/lib/ecore_x/xlib/Makefile.am b/src/lib/ecore_x/xlib/Makefile.am index 3c7364c..de42778 100644 --- a/src/lib/ecore_x/xlib/Makefile.am +++ b/src/lib/ecore_x/xlib/Makefile.am @@ -65,6 +65,7 @@ ecore_x_region.c \ ecore_x_image.c \ ecore_x_xi2.c \ ecore_x_vsync.c \ +ioctl.h \ ecore_x_randr.h \ ecore_x_gesture.c diff --git a/src/lib/ecore_x/xlib/ecore_x.c b/src/lib/ecore_x/xlib/ecore_x.c index ce3cd57..592c719 100644 --- a/src/lib/ecore_x/xlib/ecore_x.c +++ b/src/lib/ecore_x/xlib/ecore_x.c @@ -2,6 +2,32 @@ # include #endif /* ifdef HAVE_CONFIG_H */ +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include #include @@ -50,6 +76,9 @@ static int _ecore_x_event_damage_id = 0; #ifdef ECORE_XGESTURE static int _ecore_x_event_gesture_id = 0; #endif /* ifdef ECORE_XGESTURE */ +#ifdef ECORE_XKB +static int _ecore_x_event_xkb_id = 0; +#endif /* ifdef ECORE_XKB */ static int _ecore_x_event_handlers_num = 0; static void (**_ecore_x_event_handlers) (XEvent * event) = NULL; @@ -124,6 +153,10 @@ EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0; EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0; EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0; +EAPI int ECORE_X_EVENT_XKB_STATE_NOTIFY = 0; +EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0; + + EAPI int ECORE_X_EVENT_GENERIC = 0; EAPI int ECORE_X_MODIFIER_SHIFT = 0; @@ -137,6 +170,10 @@ EAPI int ECORE_X_LOCK_NUM = 0; EAPI int ECORE_X_LOCK_CAPS = 0; EAPI int ECORE_X_LOCK_SHIFT = 0; +EAPI int ECORE_X_RAW_BUTTON_PRESS = 0; +EAPI int ECORE_X_RAW_BUTTON_RELEASE = 0; +EAPI int ECORE_X_RAW_MOTION = 0; + #ifdef LOGRT static double t0 = 0.0; static Status (*_logrt_real_reply)(Display *disp, @@ -299,7 +336,9 @@ ecore_x_init(const char *name) int gesture_base = 0; int gesture_err_base = 0; #endif /* ifdef ECORE_XGESTURE */ - +#ifdef ECORE_XKB + int xkb_base = 0; +#endif /* ifdef ECORE_XKB */ if (++_ecore_x_init_count != 1) return _ecore_x_init_count; @@ -390,6 +429,18 @@ ecore_x_init(const char *name) ECORE_X_EVENT_HANDLERS_GROW(gesture_base, GestureNumberEvents); #endif /* ifdef ECORE_XGESTURE */ +#ifdef ECORE_XKB + { + int dummy; + + if (XkbQueryExtension(_ecore_x_disp, &dummy, &xkb_base, + &dummy, &dummy, &dummy)) + _ecore_x_event_xkb_id = xkb_base; + XkbSelectEventDetails(_ecore_x_disp, XkbUseCoreKbd, XkbStateNotify, + XkbAllStateComponentsMask, XkbGroupStateMask); + } + ECORE_X_EVENT_HANDLERS_GROW(xkb_base, XkbNumberEvents); +#endif _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *)); if (!_ecore_x_event_handlers) @@ -502,7 +553,9 @@ ecore_x_init(const char *name) Bool works = 0; XkbSetDetectableAutoRepeat(_ecore_x_disp, 1, &works); } - while (0); + while (0); + if (_ecore_x_event_xkb_id) + _ecore_x_event_handlers[_ecore_x_event_xkb_id] = _ecore_x_event_handle_xkb; #endif /* ifdef ECORE_XKB */ #ifdef ECORE_XGESTURE @@ -585,7 +638,14 @@ ecore_x_init(const char *name) ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new(); ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new(); + ECORE_X_EVENT_XKB_STATE_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_GENERIC = ecore_event_type_new(); + + ECORE_X_RAW_BUTTON_PRESS = ecore_event_type_new(); + ECORE_X_RAW_BUTTON_RELEASE = ecore_event_type_new(); + ECORE_X_RAW_MOTION = ecore_event_type_new(); } _ecore_x_modifiers_get(); @@ -790,14 +850,6 @@ ecore_x_screen_size_get(const Ecore_X_Screen *screen, if (h) *h = s->height; } -/** - * Retrieves the number of screens. - * - * @return The count of the number of screens. - * @ingroup Ecore_X_Display_Attr_Group - * - * @since 1.1 - */ EAPI int ecore_x_screen_count_get(void) { @@ -855,14 +907,6 @@ ecore_x_double_click_time_set(double t) _ecore_x_double_click_time = t; } -/** - * Retrieves the double and triple click flag timeout. - * - * See @ref ecore_x_double_click_time_set for more information. - * - * @return The timeout for double clicks in seconds. - * @ingroup Ecore_X_Display_Attr_Group - */ EAPI double ecore_x_double_click_time_get(void) { @@ -958,15 +1002,6 @@ ecore_x_current_time_get(void) return _ecore_x_event_last_time; } -/** - * Return the screen DPI - * - * This is a simplistic call to get DPI. It does not account for differing - * DPI in the x amd y axes nor does it account for multihead or xinerama and - * xrander where different parts of the screen may have different DPI etc. - * - * @return the general screen DPI (dots/pixels per inch). - */ EAPI int ecore_x_dpi_get(void) { @@ -1016,14 +1051,12 @@ _ecore_x_fd_handler(void *data, XEvent ev; XNextEvent(d, &ev); - #ifdef ENABLE_XIM /* Filter event for XIM */ if (XFilterEvent(&ev, ev.xkey.window)) continue; #endif /* ifdef ENABLE_XIM */ - if ((ev.type >= 0) && (ev.type < _ecore_x_event_handlers_num)) { if (_ecore_x_event_handlers[AnyXEvent]) @@ -1313,6 +1346,15 @@ ecore_x_window_sniff(Ecore_X_Window win) } EAPI void +ecore_x_window_unsniff(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ///TODO:implement check previous masking + XSelectInput(_ecore_x_disp, win, + NoEventMask); +} + +EAPI void ecore_x_window_client_sniff(Ecore_X_Window win) { LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -1878,7 +1920,8 @@ ecore_x_client_message8_send(Ecore_X_Window win, len = 20; memcpy(xev.xclient.data.b, data, len); - memset(xev.xclient.data.b + len, 0, 20 - len); + if (len < 20) + memset(xev.xclient.data.b + len, 0, 20 - len); return XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev) ? EINA_TRUE : EINA_FALSE; } @@ -2135,6 +2178,14 @@ ecore_x_default_depth_get(Ecore_X_Display *disp, return DefaultDepth(disp, ecore_x_screen_index_get(screen)); } +EAPI void +ecore_x_xkb_select_group(int group) +{ +#ifdef ECORE_XKB + XkbLockGroup(_ecore_x_disp, XkbUseCoreKbd, group); +#endif +} + /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ diff --git a/src/lib/ecore_x/xlib/ecore_x_atoms.c b/src/lib/ecore_x/xlib/ecore_x_atoms.c index 6518264..2aec7ce 100644 --- a/src/lib/ecore_x/xlib/ecore_x_atoms.c +++ b/src/lib/ecore_x/xlib/ecore_x_atoms.c @@ -2,22 +2,31 @@ # include #endif /* ifdef HAVE_CONFIG_H */ +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif #ifdef HAVE_ALLOCA_H # include -#elif defined __GNUC__ -# define alloca __builtin_alloca -#elif defined _AIX -# define alloca __alloca -#elif defined _MSC_VER -# include -# define alloca _alloca -#else /* ifdef HAVE_ALLOCA_H */ -# include -# ifdef __cplusplus +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus extern "C" -# endif /* ifdef __cplusplus */ -void *alloca(size_t); -#endif /* ifdef HAVE_ALLOCA_H */ +# endif +void *alloca (size_t); +# endif +#endif #include diff --git a/src/lib/ecore_x/xlib/ecore_x_dnd.c b/src/lib/ecore_x/xlib/ecore_x_dnd.c index 372470a..1d64439 100644 --- a/src/lib/ecore_x/xlib/ecore_x_dnd.c +++ b/src/lib/ecore_x/xlib/ecore_x_dnd.c @@ -88,13 +88,13 @@ _ecore_x_dnd_shutdown(void) } static Eina_Bool -_ecore_x_dnd_converter_copy(char *target __UNUSED__, +_ecore_x_dnd_converter_copy(char *target EINA_UNUSED, void *data, int size, void **data_ret, int *size_ret, - Ecore_X_Atom *tprop __UNUSED__, - int *count __UNUSED__) + Ecore_X_Atom *tprop EINA_UNUSED, + int *count EINA_UNUSED) { XTextProperty text_prop; char *mystr; @@ -398,10 +398,13 @@ _ecore_x_dnd_target_get(void) return _target; } -EAPI Eina_Bool -ecore_x_dnd_begin(Ecore_X_Window source, - unsigned char *data, - int size) + + +static Eina_Bool +_ecore_x_dnd_begin(Ecore_X_Window source, + Eina_Bool self, + unsigned char *data, + int size) { LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!ecore_x_dnd_version_get(source)) @@ -422,7 +425,7 @@ ecore_x_dnd_begin(Ecore_X_Window source, ecore_x_window_shadow_tree_flush(); _source->win = source; - ecore_x_window_ignore_set(_source->win, 1); + if (!self) ecore_x_window_ignore_set(_source->win, 1); _source->state = ECORE_X_DND_SOURCE_DRAGGING; _source->time = _ecore_x_event_last_time; _source->prev.window = 0; @@ -435,8 +438,8 @@ ecore_x_dnd_begin(Ecore_X_Window source, return EINA_TRUE; } -EAPI Eina_Bool -ecore_x_dnd_drop(void) +static Eina_Bool +_ecore_x_dnd_drop(Eina_Bool self) { XEvent xev; int status = EINA_FALSE; @@ -475,13 +478,41 @@ ecore_x_dnd_drop(void) _source->state = ECORE_X_DND_SOURCE_IDLE; } - ecore_x_window_ignore_set(_source->win, 0); + if (!self) ecore_x_window_ignore_set(_source->win, 0); _source->prev.window = 0; return status; } +EAPI Eina_Bool +ecore_x_dnd_begin(Ecore_X_Window source, + unsigned char *data, + int size) +{ + return _ecore_x_dnd_begin(source, EINA_FALSE, data, size); +} + +EAPI Eina_Bool +ecore_x_dnd_drop(void) +{ + return _ecore_x_dnd_drop(EINA_FALSE); +} + +EAPI Eina_Bool +ecore_x_dnd_self_begin(Ecore_X_Window source, + unsigned char *data, + int size) +{ + return _ecore_x_dnd_begin(source, EINA_TRUE, data, size); +} + +EAPI Eina_Bool +ecore_x_dnd_self_drop(void) +{ + return _ecore_x_dnd_drop(EINA_TRUE); +} + EAPI void ecore_x_dnd_send_status(Eina_Bool will_accept, Eina_Bool suppress, @@ -604,7 +635,6 @@ _ecore_x_dnd_drag(Ecore_X_Window root, // that instead. // win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num); win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num); - // NOTE: This now uses the shadow version to find parent windows // while ((win) && !(ecore_x_dnd_version_get(win))) // win = ecore_x_window_parent_get(win); @@ -703,4 +733,15 @@ _ecore_x_dnd_drag(Ecore_X_Window root, _source->dest = win; } +EAPI Eina_Bool +ecore_x_dnd_abort(Ecore_X_Window xwin_source) +{ + if (xwin_source == _source->win) + { + _source->will_accept = 0; + return ecore_x_dnd_self_drop(); + } + else return EINA_FALSE; +} + /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/ diff --git a/src/lib/ecore_x/xlib/ecore_x_e.c b/src/lib/ecore_x/xlib/ecore_x_e.c old mode 100644 new mode 100755 index fb26a13..3d8c8d6 --- a/src/lib/ecore_x/xlib/ecore_x_e.c +++ b/src/lib/ecore_x/xlib/ecore_x_e.c @@ -6,6 +6,32 @@ # include #endif /* ifdef HAVE_CONFIG_H */ +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "Ecore.h" #include "ecore_x_private.h" #include "Ecore_X.h" @@ -45,7 +71,7 @@ ecore_x_e_virtual_keyboard_set(Ecore_X_Window win, EAPI Eina_Bool ecore_x_e_virtual_keyboard_get(Ecore_X_Window win) { - unsigned int val; + unsigned int val = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD, @@ -244,7 +270,7 @@ ecore_x_e_illume_zone_set(Ecore_X_Window win, EAPI Ecore_X_Window ecore_x_e_illume_zone_get(Ecore_X_Window win) { - Ecore_X_Window zone; + Ecore_X_Window zone = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!ecore_x_window_prop_window_get(win, ECORE_X_ATOM_E_ILLUME_ZONE, @@ -409,6 +435,17 @@ ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win) } EAPI void +ecore_x_e_illume_access_action_over_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_OVER, + 0, 0, 0); +} + +EAPI void ecore_x_e_illume_access_action_read_send(Ecore_X_Window win) { LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -442,6 +479,28 @@ ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win) } EAPI void +ecore_x_e_illume_access_action_up_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_down_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN, + 0, 0, 0); +} + +EAPI void ecore_x_e_illume_drag_set(Ecore_X_Window win, unsigned int drag) { @@ -858,7 +917,7 @@ _ecore_x_e_clipboard_state_get(Ecore_X_Atom atom) if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF) return ECORE_X_ILLUME_CLIPBOARD_STATE_OFF; - return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; + return ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN; } EAPI void @@ -1088,6 +1147,437 @@ ecore_x_e_comp_sync_draw_size_done_send(Ecore_X_Window root, &xev); } +EAPI void +ecore_x_e_window_rotation_supported_set(Ecore_X_Window root, + Eina_Bool enabled) +{ + Ecore_X_Window win; + + if (!root) + root = DefaultRootWindow(_ecore_x_disp); + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (enabled) + { + win = ecore_x_window_new(root, 1, 2, 3, 4); + ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + ecore_x_window_prop_xid_set(root, ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + } + else + { + int ret; + + ret = + ecore_x_window_prop_xid_get(root, + ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED, + ECORE_X_ATOM_WINDOW, + &win, 1); + if ((ret == 1) && (win)) + { + ecore_x_window_prop_property_del( + root, + ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED); + ecore_x_window_free(win); + } + } +} + +EAPI Eina_Bool +ecore_x_e_window_rotation_supported_get(Ecore_X_Window root) +{ + Ecore_X_Window win, win2; + int ret; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!root) + root = DefaultRootWindow(_ecore_x_disp); + + ret = + ecore_x_window_prop_xid_get(root, + ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED, + ECORE_X_ATOM_WINDOW, + &win, 1); + if ((ret == 1) && (win)) + { + ret = + ecore_x_window_prop_xid_get(win, + ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED, + ECORE_X_ATOM_WINDOW, + &win2, 1); + if ((ret == 1) && (win2 == win)) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +EAPI void +ecore_x_e_window_rotation_app_set(Ecore_X_Window win, + Eina_Bool set) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (set) val = 1; + + ecore_x_window_prop_card32_set(win, + ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED, + &val, 1); +} + +EAPI Eina_Bool +ecore_x_e_window_rotation_app_get(Ecore_X_Window win) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED, + &val, 1)) + return EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_x_e_window_rotation_preferred_rotation_set(Ecore_X_Window win, + int rot) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (rot != -1) + { + val = (unsigned int)rot; + ecore_x_window_prop_card32_set(win, + ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION, + &val, 1); + } + else + { + ecore_x_window_prop_property_del(win, + ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION); + } +} + +EAPI Eina_Bool +ecore_x_e_window_rotation_preferred_rotation_get(Ecore_X_Window win, + int *rot) +{ + unsigned int val = 0; + int ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ret = ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION, + &val, 1); + if (ret == 1) + { + if (rot) *rot = (int)val; + return EINA_TRUE; + } + return EINA_FALSE; +} + +EAPI void +ecore_x_e_window_rotation_available_rotations_set(Ecore_X_Window win, + const int *rots, + unsigned int count) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + if ((rots) && (count > 0)) + ecore_x_window_prop_card32_set(win, + ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST, + (unsigned int *)rots, count); + else + ecore_x_window_prop_property_del(win, + ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST); +} + +EAPI Eina_Bool +ecore_x_e_window_rotation_available_rotations_get(Ecore_X_Window win, + int **rots, + unsigned int *count) +{ + unsigned char *data = NULL; + int num, i; + int *val = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!win) || (!rots) || (!count)) + return EINA_FALSE; + + *rots = NULL; + *count = 0; + + if (!ecore_x_window_prop_property_get(win, + ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST, + XA_CARDINAL, 32, &data, &num)) + return EINA_FALSE; + + *count = num; + + if ((num >= 1) && (data)) + { + val = calloc(num, sizeof(int)); + if (!val) + { + if (data) free(data); + return EINA_FALSE; + } + for (i = 0; i < num; i++) + val[i] = ((int *)data)[i]; + if (data) free(data); + *rots = val; + return EINA_TRUE; + } + if (data) free(data); + return EINA_FALSE; +} + +EAPI void +ecore_x_e_window_rotation_change_prepare_send(Ecore_X_Window win, + int rot, + Eina_Bool resize, + int w, + int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send + (win, ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE, + ECORE_X_EVENT_MASK_NONE, + win, rot, resize, w, h); +} + +EAPI void +ecore_x_e_window_rotation_change_prepare_done_send(Ecore_X_Window root, + Ecore_X_Window win, + int rot) +{ + XEvent xev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!root) + root = DefaultRootWindow(_ecore_x_disp); + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE; + xev.xclient.format = 32; + xev.xclient.data.l[0] = win; + xev.xclient.data.l[1] = rot; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent(_ecore_x_disp, root, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); +} + +EAPI void +ecore_x_e_window_rotation_change_request_send(Ecore_X_Window win, + int rot) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send + (win, ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST, + ECORE_X_EVENT_MASK_NONE, + win, rot, 0, 0, 0); +} + +EAPI void +ecore_x_e_window_rotation_change_done_send(Ecore_X_Window root, + Ecore_X_Window win, + int rot, + int w, + int h) +{ + XEvent xev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!root) + root = DefaultRootWindow(_ecore_x_disp); + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE; + xev.xclient.format = 32; + xev.xclient.data.l[0] = win; + xev.xclient.data.l[1] = rot; + xev.xclient.data.l[2] = w; + xev.xclient.data.l[3] = h; + xev.xclient.data.l[4] = 0; + + XSendEvent(_ecore_x_disp, root, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); + XFlush(_ecore_x_disp); +} + +EAPI void +ecore_x_e_window_rotation_geometry_set(Ecore_X_Window win, + int rot, + int x, + int y, + int w, + int h) +{ + Ecore_X_Atom atom; + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + geom[0] = x; + geom[1] = y; + geom[2] = w; + geom[3] = h; + + switch (rot) + { + case 0: atom = ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY; break; + case 90: atom = ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY; break; + case 180: atom = ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY; break; + case 270: atom = ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY; break; + default: atom = ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY; break; + } + + ecore_x_window_prop_card32_set(win, atom, geom, 4); +} + +EAPI Eina_Bool +ecore_x_e_window_rotation_geometry_get(Ecore_X_Window win, + int rot, + int *x, + int *y, + int *w, + int *h) +{ + int ret = 0; + Ecore_X_Atom atom; + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + switch (rot) + { + case 0: atom = ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY; break; + case 90: atom = ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY; break; + case 180: atom = ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY; break; + case 270: atom = ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY; break; + default: atom = ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY; break; + } + + ret = ecore_x_window_prop_card32_get(win, atom, geom, 4); + + if (ret != 4) + return EINA_FALSE; + + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + + return EINA_TRUE; +} + +EAPI void +ecore_x_e_virtual_keyboard_control_window_set(Ecore_X_Window root, + Ecore_X_Window win, + unsigned int zone, + Eina_Bool set) +{ + XEvent xev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!root) + root = DefaultRootWindow(_ecore_x_disp); + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW; + xev.xclient.format = 32; + xev.xclient.data.l[0] = win; + xev.xclient.data.l[1] = zone; + xev.xclient.data.l[2] = set; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent(_ecore_x_disp, root, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); +} + +EAPI void +ecore_x_e_virtual_keyboard_on_prepare_request_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send + (win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_REQUEST, + ECORE_X_EVENT_MASK_NONE, win, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_virtual_keyboard_on_prepare_done_send(Ecore_X_Window root, + Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!root) + root = DefaultRootWindow(_ecore_x_disp); + ecore_x_client_message32_send + (root, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE, + ECORE_X_EVENT_MASK_WINDOW_CHILD_CONFIGURE | ECORE_X_EVENT_MASK_WINDOW_MANAGE, + win, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_virtual_keyboard_off_prepare_request_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send + (win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_REQUEST, + ECORE_X_EVENT_MASK_NONE, + win, 0, 0, 0, 0); +} + +EAPI void +ecore_x_e_virtual_keyboard_off_prepare_done_send(Ecore_X_Window root, + Ecore_X_Window win) +{ + XEvent xev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!root) + root = DefaultRootWindow(_ecore_x_disp); + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE; + xev.xclient.format = 32; + xev.xclient.data.l[0] = win; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent(_ecore_x_disp, root, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); +} + /* * @since 1.3 * @@ -1166,7 +1656,7 @@ ecore_x_e_window_profile_list_get(Ecore_X_Window win, } if (data) - XFree(data); + free(data); return EINA_TRUE; } @@ -1216,6 +1706,8 @@ ecore_x_e_window_profile_get(Ecore_X_Window win) if (atom) profile = ecore_x_atom_name_get(atom[0]); + if (data) free(data); + return profile; } @@ -1505,6 +1997,9 @@ _ecore_x_e_indicator_opacity_atom_get(Ecore_X_Illume_Indicator_Opacity_Mode mode case ECORE_X_ILLUME_INDICATOR_TRANSPARENT: return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT; + case ECORE_X_ILLUME_INDICATOR_BG_TRANSPARENT: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_BG_TRANSPARENT; + default: break; } @@ -1523,6 +2018,9 @@ _ecore_x_e_indicator_opacity_get(Ecore_X_Atom atom) if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT) return ECORE_X_ILLUME_INDICATOR_TRANSPARENT; + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_BG_TRANSPARENT) + return ECORE_X_ILLUME_INDICATOR_BG_TRANSPARENT; + return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN; } @@ -1566,6 +2064,80 @@ ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win, } static Ecore_X_Atom +_ecore_x_e_indicator_type_atom_get(Ecore_X_Illume_Indicator_Type_Mode mode) +{ + switch (mode) + { + case ECORE_X_ILLUME_INDICATOR_TYPE_1: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_1; + + case ECORE_X_ILLUME_INDICATOR_TYPE_2: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_2; + + case ECORE_X_ILLUME_INDICATOR_TYPE_3: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_3; + + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Indicator_Type_Mode +_ecore_x_e_indicator_type_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_1) + return ECORE_X_ILLUME_INDICATOR_TYPE_1; + + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_2) + return ECORE_X_ILLUME_INDICATOR_TYPE_2; + + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_3) + return ECORE_X_ILLUME_INDICATOR_TYPE_3; + + return ECORE_X_ILLUME_INDICATOR_TYPE_UNKNOWN; +} + +EAPI void +ecore_x_e_illume_indicator_type_set(Ecore_X_Window win, + Ecore_X_Illume_Indicator_Type_Mode mode) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + atom = _ecore_x_e_indicator_type_atom_get(mode); + ecore_x_window_prop_atom_set(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_MODE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Indicator_Type_Mode +ecore_x_e_illume_indicator_type_get(Ecore_X_Window win) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!ecore_x_window_prop_atom_get(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_MODE, + &atom, 1)) + return ECORE_X_ILLUME_INDICATOR_TYPE_UNKNOWN; + + return _ecore_x_e_indicator_type_get(atom); +} + +EAPI void +ecore_x_e_illume_indicator_type_send(Ecore_X_Window win, + Ecore_X_Illume_Indicator_Type_Mode mode) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_TYPE_MODE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_x_e_indicator_type_atom_get(mode), + 0, 0, 0, 0); +} + +static Ecore_X_Atom _ecore_x_e_illume_window_state_atom_get(Ecore_X_Illume_Window_State state) { switch (state) @@ -1576,6 +2148,9 @@ _ecore_x_e_illume_window_state_atom_get(Ecore_X_Illume_Window_State state) case ECORE_X_ILLUME_WINDOW_STATE_FLOATING: return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING; + case ECORE_X_ILLUME_WINDOW_STATE_ASSISTANT_MENU: + return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_ASSISTANT_MENU; + default: break; } @@ -1591,6 +2166,9 @@ _ecore_x_e_illume_window_state_get(Ecore_X_Atom atom) if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING) return ECORE_X_ILLUME_WINDOW_STATE_FLOATING; + if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_ASSISTANT_MENU) + return ECORE_X_ILLUME_WINDOW_STATE_ASSISTANT_MENU; + return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; } @@ -1620,3 +2198,14 @@ ecore_x_e_illume_window_state_get(Ecore_X_Window win) return _ecore_x_e_illume_window_state_get(atom); } +EAPI void +ecore_x_e_illume_window_state_send(Ecore_X_Window win, + Ecore_X_Illume_Window_State state) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, + ECORE_X_ATOM_E_ILLUME_WINDOW_STATE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_x_e_illume_window_state_atom_get(state), + 0, 0, 0, 0); +} diff --git a/src/lib/ecore_x/xlib/ecore_x_events.c b/src/lib/ecore_x/xlib/ecore_x_events.c index 034a1f1..f9ee83b 100644 --- a/src/lib/ecore_x/xlib/ecore_x_events.c +++ b/src/lib/ecore_x/xlib/ecore_x_events.c @@ -341,7 +341,13 @@ _ecore_key_press(int event, ecore_event_add(event, e, NULL, NULL); - _ecore_x_event_last_time = e->timestamp; + //FIXME: isf team send timestamp set as 1 or 0 for distinguish between SW keyborad or + //HW keyboard. it makes side effect about using X API(XSetSelectionOwner) + //so i insert code for avoid that side effect. it have to fix at TIZEN 3.0 + if (e->timestamp <= 1) + _ecore_x_event_last_time++; + else + _ecore_x_event_last_time = e->timestamp; on_error: if (tmp) @@ -522,6 +528,8 @@ _ecore_x_event_handle_button_press(XEvent *xevent) { int i; + DBG("ButtonEvent:press time=%u button=%d", (unsigned int)xevent->xbutton.time, xevent->xbutton.button); + _ecore_x_last_event_mouse_move = 0; if ((xevent->xbutton.button > 3) && (xevent->xbutton.button < 8)) { @@ -672,6 +680,7 @@ void _ecore_x_event_handle_button_release(XEvent *xevent) { _ecore_x_last_event_mouse_move = 0; + DBG("ButtonEvent:release time=%u button=%d", (unsigned int)xevent->xbutton.time, xevent->xbutton.button); /* filter out wheel buttons */ if ((xevent->xbutton.button <= 3) || (xevent->xbutton.button > 7)) { @@ -1087,6 +1096,7 @@ _ecore_x_event_handle_unmap_notify(XEvent *xevent) e->win = xevent->xunmap.window; e->event_win = xevent->xunmap.event; e->time = _ecore_x_event_last_time; + e->send_event = xevent->xunmap.send_event; ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL); } @@ -1309,6 +1319,8 @@ _ecore_x_event_handle_selection_clear(XEvent *xevent) e->selection = ECORE_X_SELECTION_PRIMARY; else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY) e->selection = ECORE_X_SELECTION_SECONDARY; + else if (sel == ECORE_X_ATOM_SELECTION_XDND) + e->selection = ECORE_X_SELECTION_XDND; else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD) e->selection = ECORE_X_SELECTION_CLIPBOARD; else @@ -2007,7 +2019,8 @@ _ecore_x_event_handle_screensaver_notify(XEvent *xevent) return; e->win = screensaver_event->window; - if (screensaver_event->state == ScreenSaverOn) + if ((screensaver_event->state == ScreenSaverOn) || + (screensaver_event->state == ScreenSaverCycle)) e->on = EINA_TRUE; else e->on = EINA_FALSE; @@ -2206,6 +2219,8 @@ _ecore_x_event_handle_fixes_selection_notify(XEvent *event) e->selection = ECORE_X_SELECTION_PRIMARY; else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY) e->selection = ECORE_X_SELECTION_SECONDARY; + else if (sel == ECORE_X_ATOM_SELECTION_XDND) + e->selection = ECORE_X_SELECTION_XDND; else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD) e->selection = ECORE_X_SELECTION_CLIPBOARD; else @@ -2221,7 +2236,7 @@ _ecore_x_event_handle_fixes_selection_notify(XEvent *event) void _ecore_x_event_handle_damage_notify(XEvent *event) { - XDamageNotifyEvent *damage_event; + XDamageNotifyEvent *damage_event; Ecore_X_Event_Damage *e; _ecore_x_last_event_mouse_move = 0; @@ -2496,4 +2511,33 @@ _ecore_x_event_handle_gesture_notify_group(XEvent *xevent) } #endif /* ifdef ECORE_XGESTURE */ +#ifdef ECORE_XKB +void +_ecore_x_event_handle_xkb(XEvent *xevent) +{ + XkbEvent *xkbev; + Ecore_X_Event_Xkb *e; + + xkbev = (XkbEvent *) xevent; + e = calloc(1, sizeof(Ecore_X_Event_Xkb)); + if (!e) + return; + e->group = xkbev->state.group; + if (xkbev->any.xkb_type == XkbStateNotify) + ecore_event_add(ECORE_X_EVENT_XKB_STATE_NOTIFY, e, NULL, NULL); + else if ((xkbev->any.xkb_type == XkbNewKeyboardNotify) || + (xkbev->any.xkb_type == XkbMapNotify)) + { + if (xkbev->any.xkb_type == XkbMapNotify) + { + XkbMapNotifyEvent *xkbmapping; + xkbmapping = (XkbMapNotifyEvent *)xkbev; + XkbRefreshKeyboardMapping(xkbmapping); + } + ecore_event_add(ECORE_X_EVENT_XKB_NEWKBD_NOTIFY, e, NULL, NULL); + } + else + free(e); +} +#endif /* ifdef ECORE_XKB */ diff --git a/src/lib/ecore_x/xlib/ecore_x_gesture.c b/src/lib/ecore_x/xlib/ecore_x_gesture.c index 3c390a9..f6af8de 100644 --- a/src/lib/ecore_x/xlib/ecore_x_gesture.c +++ b/src/lib/ecore_x/xlib/ecore_x_gesture.c @@ -72,7 +72,7 @@ ecore_x_gesture_events_selected_get(Ecore_X_Window win) return ECORE_X_GESTURE_EVENT_MASK_NONE; LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (GestureSuccess != XGestureGetSelectedEvents(_ecore_x_disp, win, &mask)) + if (GestureSuccess != XGestureGetSelectedEvents(_ecore_x_disp, win, (Mask *)&mask)) { mask = ECORE_X_GESTURE_EVENT_MASK_NONE; return mask; @@ -115,8 +115,6 @@ ecore_x_gesture_event_ungrab(Ecore_X_Window win, int num_fingers) { #ifdef ECORE_XGESTURE - Ecore_X_Gesture_Event_Mask mask; - if (!_gesture_available) return EINA_FALSE; diff --git a/src/lib/ecore_x/xlib/ecore_x_icccm.c b/src/lib/ecore_x/xlib/ecore_x_icccm.c index 8d6ea1f..9cdc198 100644 --- a/src/lib/ecore_x/xlib/ecore_x_icccm.c +++ b/src/lib/ecore_x/xlib/ecore_x_icccm.c @@ -992,8 +992,7 @@ ecore_x_icccm_colormap_window_set(Ecore_X_Window win, { if (oldset[i] == subwin) { - if (old_data) - XFree(old_data); + XFree(old_data); old_data = NULL; free(newset); @@ -1004,8 +1003,7 @@ ecore_x_icccm_colormap_window_set(Ecore_X_Window win, } newset[num++] = subwin; - if (old_data) - XFree(old_data); + XFree(old_data); data = (unsigned char *)newset; } @@ -1046,8 +1044,7 @@ ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, { XDeleteProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS); - if (old_data) - XFree(old_data); + XFree(old_data); old_data = NULL; return; @@ -1067,8 +1064,7 @@ ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, 32, data, k); - if (old_data) - XFree(old_data); + XFree(old_data); old_data = NULL; free(newset); diff --git a/src/lib/ecore_x/xlib/ecore_x_image.c b/src/lib/ecore_x/xlib/ecore_x_image.c index b8e720c..a491e89 100644 --- a/src/lib/ecore_x/xlib/ecore_x_image.c +++ b/src/lib/ecore_x/xlib/ecore_x_image.c @@ -2,6 +2,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include #include @@ -167,6 +193,7 @@ _ecore_x_image_shm_create(Ecore_X_Image *im) if (im->shminfo.shmid == -1) { XDestroyImage(im->xim); + im->xim = NULL; return; } @@ -179,6 +206,7 @@ _ecore_x_image_shm_create(Ecore_X_Image *im) shmdt(im->shminfo.shmaddr); shmctl(im->shminfo.shmid, IPC_RMID, 0); XDestroyImage(im->xim); + im->xim = NULL; return; } @@ -192,7 +220,9 @@ _ecore_x_image_shm_create(Ecore_X_Image *im) im->bpp = 1; else if (im->xim->bits_per_pixel <= 16) im->bpp = 2; - else + else if (im->xim->bits_per_pixel <= 24) + im->bpp = 3; + else im->bpp = 4; } @@ -219,6 +249,8 @@ ecore_x_image_get(Ecore_X_Image *im, return 0; _ecore_x_image_err = 0; + + ecore_x_sync(); // optimised path ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler); if ((sx == 0) && (w == im->w)) @@ -332,15 +364,15 @@ ecore_x_image_is_argb32_get(Ecore_X_Image *im) if (!im->xim) _ecore_x_image_shm_create(im); if (((vis->class == TrueColor) || (vis->class == DirectColor)) && - (im->depth >= 24) && + (im->bpp == 4) && (vis->red_mask == 0xff0000) && (vis->green_mask == 0x00ff00) && (vis->blue_mask == 0x0000ff)) { #ifdef WORDS_BIGENDIAN - if (im->xim->bitmap_bit_order == LSBFirst) return EINA_TRUE; -#else if (im->xim->bitmap_bit_order == MSBFirst) return EINA_TRUE; +#else + if (im->xim->bitmap_bit_order == LSBFirst) return EINA_TRUE; #endif } return EINA_FALSE; @@ -371,6 +403,8 @@ ecore_x_image_to_argb_convert(void *src, rgb565, bgr565, rgbx555, + rgb888, + bgr888, argbx888, abgrx888, rgba888x, @@ -413,40 +447,56 @@ ecore_x_image_to_argb_convert(void *src, else if ((vis->class == TrueColor) || (vis->class == DirectColor)) { - if ((vis->red_mask == 0x00ff0000) && - (vis->green_mask == 0x0000ff00) && - (vis->blue_mask == 0x000000ff)) - mode = argbx888; - else if ((vis->red_mask == 0x000000ff) && + if (sbpp == 24) + { + if ((vis->red_mask == 0x00ff0000) && (vis->green_mask == 0x0000ff00) && - (vis->blue_mask == 0x00ff0000)) - mode = abgrx888; - else if ((vis->red_mask == 0xff000000) && - (vis->green_mask == 0x00ff0000) && - (vis->blue_mask == 0x0000ff00)) - mode = rgba888x; - else if ((vis->red_mask == 0x0000ff00) && - (vis->green_mask == 0x00ff0000) && - (vis->blue_mask == 0xff000000)) - mode = bgra888x; - else if ((vis->red_mask == 0x0003f000) && - (vis->green_mask == 0x00000fc0) && - (vis->blue_mask == 0x0000003f)) - mode = argbx666; - else if ((vis->red_mask == 0x0000f800) && - (vis->green_mask == 0x000007e0) && - (vis->blue_mask == 0x0000001f)) - mode = rgb565; - else if ((vis->red_mask == 0x0000001f) && - (vis->green_mask == 0x000007e0) && - (vis->blue_mask == 0x0000f800)) - mode = bgr565; - else if ((vis->red_mask == 0x00007c00) && - (vis->green_mask == 0x000003e0) && - (vis->blue_mask == 0x0000001f)) - mode = rgbx555; + (vis->blue_mask == 0x000000ff)) + mode = rgb888; + else if ((vis->red_mask == 0x000000ff) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x00ff0000)) + mode = bgr888; + else + return EINA_FALSE; + } else - return EINA_FALSE; + { + if ((vis->red_mask == 0x00ff0000) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x000000ff)) + mode = argbx888; + else if ((vis->red_mask == 0x000000ff) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x00ff0000)) + mode = abgrx888; + else if ((vis->red_mask == 0xff000000) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0x0000ff00)) + mode = rgba888x; + else if ((vis->red_mask == 0x0000ff00) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0xff000000)) + mode = bgra888x; + else if ((vis->red_mask == 0x0003f000) && + (vis->green_mask == 0x00000fc0) && + (vis->blue_mask == 0x0000003f)) + mode = argbx666; + else if ((vis->red_mask == 0x0000f800) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgb565; + else if ((vis->red_mask == 0x0000001f) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000f800)) + mode = bgr565; + else if ((vis->red_mask == 0x00007c00) && + (vis->green_mask == 0x000003e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgbx555; + else + return EINA_FALSE; + } } for (row = 0; row < h; row++) { @@ -527,6 +577,29 @@ ecore_x_image_to_argb_convert(void *src, break; case 24: + s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + (x * (sbpp / 8)); + switch (mode) + { + case rgb888: + while (dp < de) + { + *dp = 0xff000000 | (s8[2] << 16) | (s8[1] << 8) | s8[0]; + s8 += 3; dp++; + } + break; + case bgr888: + while (dp < de) + { + *dp = 0xff000000 | (s8[0] << 16) | (s8[1] << 8) | s8[2]; + s8 += 3; dp++; + } + break; + default: + return EINA_FALSE; + break; + } + break; + case 32: s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; switch (mode) @@ -588,7 +661,6 @@ ecore_x_image_to_argb_convert(void *src, break; } break; - break; default: return EINA_FALSE; diff --git a/src/lib/ecore_x/xlib/ecore_x_netwm.c b/src/lib/ecore_x/xlib/ecore_x_netwm.c index 5a23a1b..5ffd240 100644 --- a/src/lib/ecore_x/xlib/ecore_x_netwm.c +++ b/src/lib/ecore_x/xlib/ecore_x_netwm.c @@ -137,11 +137,12 @@ ecore_x_netwm_supported_get(Ecore_X_Window root, { int num_ret; + if (!supported) return EINA_FALSE; + if (num) *num = 0; - if (supported) - *supported = NULL; + *supported = NULL; LOGFN(__FILE__, __LINE__, __FUNCTION__); num_ret = ecore_x_window_prop_atom_list_get(root, ECORE_X_ATOM_NET_SUPPORTED, @@ -1237,7 +1238,10 @@ ecore_x_netwm_window_types_get(Ecore_X_Window win, atoms2 = malloc(num * sizeof(Ecore_X_Window_Type)); if (!atoms2) - return 0; + { + free(atoms); + return 0; + } for (i = 0; i < num; i++) atoms2[i] = _ecore_x_netwm_window_type_type_get(atoms[i]); diff --git a/src/lib/ecore_x/xlib/ecore_x_private.h b/src/lib/ecore_x/xlib/ecore_x_private.h index 4236932..f962ffb 100644 --- a/src/lib/ecore_x/xlib/ecore_x_private.h +++ b/src/lib/ecore_x/xlib/ecore_x_private.h @@ -258,6 +258,9 @@ void _ecore_x_event_handle_fixes_selection_notify(XEvent *xevent); #ifdef ECORE_XDAMAGE void _ecore_x_event_handle_damage_notify(XEvent *xevent); #endif /* ifdef ECORE_XDAMAGE */ +#ifdef ECORE_XKB +void _ecore_x_event_handle_xkb(XEvent *xevent); +#endif /* ifdef ECORE_XKB */ void _ecore_x_event_handle_generic_event(XEvent *xevent); void _ecore_x_selection_data_init(void); diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_12.c b/src/lib/ecore_x/xlib/ecore_x_randr_12.c index a1fecf8..405b779 100644 --- a/src/lib/ecore_x/xlib/ecore_x_randr_12.c +++ b/src/lib/ecore_x/xlib/ecore_x_randr_12.c @@ -6,6 +6,32 @@ # include #endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include "ecore_x_private.h" #include "ecore_x_randr.h" #include @@ -527,13 +553,17 @@ ecore_x_randr_crtcs_get(Ecore_X_Window root, XRRScreenResources *res = NULL; Ecore_X_Randr_Crtc *ret = NULL; - if (num && root && + if (root && (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) { if ((ret = malloc(sizeof(Ecore_X_Randr_Crtc) * res->ncrtc))) { - memcpy(ret, res->crtcs, (sizeof(Ecore_X_Randr_Crtc) * res->ncrtc)); - *num = res->ncrtc; + int i = 0; + + if (num) *num = res->ncrtc; + + for (i = 0; i < res->ncrtc; i++) + ret[i] = res->crtcs[i]; } XRRFreeScreenResources(res); @@ -637,15 +667,17 @@ ecore_x_randr_outputs_get(Ecore_X_Window root, XRRScreenResources *res = NULL; Ecore_X_Randr_Output *ret = NULL; - if (num && root && - (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) + if (root && + (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) { if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * res->noutput))) { - memcpy(ret, res->outputs, - (sizeof(Ecore_X_Randr_Output) * res->noutput)); - if (num) - *num = res->noutput; + int i = 0; + + if (num) *num = res->noutput; + + for (i = 0; i < res->noutput; i++) + ret[i] = res->outputs[i]; } if (res) @@ -675,19 +707,19 @@ ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Output *ret = NULL; XRRCrtcInfo *crtc_info = NULL; - if (_ecore_x_randr_crtc_validate(root, - crtc) && + if (_ecore_x_randr_crtc_validate(root, crtc) && (res = - _ecore_x_randr_get_screen_resources (_ecore_x_disp, - root)) && + _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)) && (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) { if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->noutput))) { - memcpy(ret, crtc_info->outputs, - (sizeof(Ecore_X_Randr_Output) * crtc_info->noutput)); - if (num) - *num = crtc_info->noutput; + int i = 0; + + if (num) *num = crtc_info->noutput; + + for (i = 0; i < crtc_info->noutput; i++) + ret[i] = crtc_info->outputs[i]; } if (crtc_info) @@ -719,8 +751,7 @@ ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Output *ret = NULL; XRRCrtcInfo *crtc_info = NULL; - if (_ecore_x_randr_crtc_validate(root, - crtc) && + if (_ecore_x_randr_crtc_validate(root, crtc) && (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) { if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) @@ -728,10 +759,12 @@ ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->npossible))) { - memcpy(ret, crtc_info->possible, - (sizeof(Ecore_X_Randr_Output) * crtc_info->npossible)); - if (num) - *num = res->ncrtc; + int i = 0; + + if (num) *num = crtc_info->npossible; + + for (i = 0; i < crtc_info->npossible; i++) + ret[i] = crtc_info->possible[i]; } XRRFreeCrtcInfo(crtc_info); @@ -1583,13 +1616,13 @@ ecore_x_randr_output_modes_get(Ecore_X_Window root, { if ((modes = malloc(sizeof(Ecore_X_Randr_Mode) * output_info->nmode))) { - memcpy(modes, output_info->modes, - (sizeof(Ecore_X_Randr_Mode) * output_info->nmode)); - if (num) - *num = output_info->nmode; + int i = 0; - if (npreferred) - *npreferred = output_info->npreferred; + if (num) *num = output_info->nmode; + if (npreferred) *npreferred = output_info->npreferred; + + for (i = 0; i < output_info->nmode; i++) + modes[i] = output_info->modes[i]; } } @@ -1917,7 +1950,7 @@ ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, Ecore_X_Randr_Crtc *crtcs_to_be_moved = NULL; XRRScreenResources *res = NULL; int i, j, k, n; - Eina_Bool ret; + Eina_Bool ret = EINA_FALSE; if ((nnot_moved <= 0) || (!not_moved) || !_ecore_x_randr_root_validate(root) @@ -1939,11 +1972,11 @@ ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, //crtcs[i] is not in the 'not to move'-list crtcs_to_be_moved[k++] = res->crtcs[i]; } + ret = ecore_x_randr_move_crtcs(root, crtcs_to_be_moved, n, dx, dy); + free(crtcs_to_be_moved); } XRRFreeScreenResources(res); - ret = ecore_x_randr_move_crtcs(root, crtcs_to_be_moved, n, dx, dy); - free(crtcs_to_be_moved); return ret; #else return EINA_FALSE; diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c b/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c index 5bda332..4c37a2c 100644 --- a/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c +++ b/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c @@ -184,9 +184,9 @@ ecore_x_randr_edid_display_name_get(unsigned char *edid, const char *edid_name; edid_name = (const char *)block + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; - name = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); + name = malloc(_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX + 1); if (!name) return NULL; - strncpy(name, edid_name, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); + strncpy(name, edid_name, _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; for (p = name; *p; p++) { @@ -288,9 +288,9 @@ ecore_x_randr_edid_display_ascii_get(unsigned char *edid, * TODO: Two of these in a row, in the third and fourth slots, * seems to be specified by SPWG: http://www.spwg.org/ */ - ascii = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); + ascii = malloc(_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX + 1); if (!ascii) return NULL; - strncpy(ascii, edid_ascii, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); + strncpy(ascii, edid_ascii, _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); ascii[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; for (p = ascii; *p; p++) { @@ -321,9 +321,9 @@ ecore_x_randr_edid_display_serial_get(unsigned char *edid, * TODO: Two of these in a row, in the third and fourth slots, * seems to be specified by SPWG: http://www.spwg.org/ */ - serial = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); + serial = malloc(_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX + 1); if (!serial) return NULL; - strncpy(serial, edid_serial, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); + strncpy(serial, edid_serial, _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); serial[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; for (p = serial; *p; p++) { diff --git a/src/lib/ecore_x/xlib/ecore_x_screensaver.c b/src/lib/ecore_x/xlib/ecore_x_screensaver.c index 40dd738..3688a44 100644 --- a/src/lib/ecore_x/xlib/ecore_x_screensaver.c +++ b/src/lib/ecore_x/xlib/ecore_x_screensaver.c @@ -162,7 +162,8 @@ ecore_x_screensaver_event_listen_set(Eina_Bool on) LOGFN(__FILE__, __LINE__, __FUNCTION__); root = DefaultRootWindow(_ecore_x_disp); if (on) - XScreenSaverSelectInput(_ecore_x_disp, root, ScreenSaverNotifyMask); + XScreenSaverSelectInput(_ecore_x_disp, root, + ScreenSaverNotifyMask | ScreenSaverCycle); else XScreenSaverSelectInput(_ecore_x_disp, root, 0); #else @@ -171,3 +172,33 @@ ecore_x_screensaver_event_listen_set(Eina_Bool on) #endif /* ifdef ECORE_XSS */ } + +EAPI Eina_Bool +ecore_x_screensaver_custom_blanking_enable(void) +{ +#ifdef ECORE_XSS + XSetWindowAttributes attr; + + XScreenSaverSetAttributes(_ecore_x_disp, + DefaultRootWindow(_ecore_x_disp), + -9999, -9999, 1, 1, 0, + CopyFromParent, InputOnly, CopyFromParent, + 0, &attr); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif /* ifdef ECORE_XSS */ +} + +EAPI Eina_Bool +ecore_x_screensaver_custom_blanking_disable(void) +{ +#ifdef ECORE_XSS + XScreenSaverUnsetAttributes(_ecore_x_disp, + DefaultRootWindow(_ecore_x_disp)); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif /* ifdef ECORE_XSS */ +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_selection.c b/src/lib/ecore_x/xlib/ecore_x_selection.c index fa177c3..2c3f5a5 100644 --- a/src/lib/ecore_x/xlib/ecore_x_selection.c +++ b/src/lib/ecore_x/xlib/ecore_x_selection.c @@ -2,6 +2,32 @@ # include #endif /* ifdef HAVE_CONFIG_H */ +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include @@ -15,13 +41,6 @@ static Ecore_X_Selection_Intern selections[4]; static Ecore_X_Selection_Converter *converters = NULL; static Ecore_X_Selection_Parser *parsers = NULL; -static Eina_Bool _ecore_x_selection_converter_text(char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *tprop, - int *); static int _ecore_x_selection_data_default_free(void *data); static void *_ecore_x_selection_parser_files(const char *target, void *data, @@ -49,15 +68,15 @@ _ecore_x_selection_data_init(void) /* Initialize converters */ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT, - _ecore_x_selection_converter_text); + ecore_x_selection_converter_text); #ifdef X_HAVE_UTF8_STRING ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING, - _ecore_x_selection_converter_text); + ecore_x_selection_converter_text); #endif /* ifdef X_HAVE_UTF8_STRING */ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT, - _ecore_x_selection_converter_text); + ecore_x_selection_converter_text); ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING, - _ecore_x_selection_converter_text); + ecore_x_selection_converter_text); /* Initialize parsers */ ecore_x_selection_parser_add("text/plain", @@ -143,6 +162,12 @@ _ecore_x_selection_set(Window w, else return EINA_FALSE; + if (selections[in].data) + { + free(selections[in].data); + memset(&selections[in], 0, sizeof(Ecore_X_Selection_Intern)); + } + if (data) { selections[in].win = w; @@ -155,11 +180,6 @@ _ecore_x_selection_set(Window w, memcpy(buf, data, size); selections[in].data = buf; } - else if (selections[in].data) - { - free(selections[in].data); - memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data)); - } return EINA_TRUE; } @@ -543,7 +563,7 @@ ecore_x_selection_convert(Ecore_X_Atom selection, { Ecore_X_Selection_Intern *sel; Ecore_X_Selection_Converter *cnv; - void *data; + void *data = NULL; char *tgt_str; LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -555,6 +575,7 @@ ecore_x_selection_convert(Ecore_X_Atom selection, if (cnv->target == target) { int r; + r = cnv->convert(tgt_str, sel->data, sel->length, &data, size, targtype, typesize); free(tgt_str); @@ -567,6 +588,7 @@ ecore_x_selection_convert(Ecore_X_Atom selection, return EINA_FALSE; } } + free(tgt_str); /* ICCCM says "If the selection cannot be converted into a form based on the target (and parameters, if any), the owner should refuse the SelectionRequest as previously described." */ return EINA_FALSE; @@ -582,14 +604,14 @@ ecore_x_selection_convert(Ecore_X_Atom selection, /* TODO: We need to work out a mechanism for automatic conversion to any requested * locale using Ecore_Txt functions */ /* Converter for standard non-utf8 text targets */ -static Eina_Bool -_ecore_x_selection_converter_text(char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *targprop __UNUSED__, - int *s __UNUSED__) +EAPI Eina_Bool +ecore_x_selection_converter_text(char *target, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *targprop __UNUSED__, + int *s __UNUSED__) { XTextProperty text_prop; char *mystr; @@ -813,11 +835,13 @@ _ecore_x_selection_parser_files(const char *target, strcmp(target, "_NETSCAPE_URL")) return NULL; + if (!data) return NULL; + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files)); if (!sel) return NULL; ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free; - if (data[size - 1]) + if (data && data[size - 1]) { /* Isn't nul terminated */ size++; @@ -834,6 +858,7 @@ _ecore_x_selection_parser_files(const char *target, tmp = malloc(size); if (!tmp) { + if(data) free(data); free(sel); return NULL; } @@ -916,7 +941,7 @@ _ecore_x_selection_parser_text(const char *target __UNUSED__, sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text)); if (!sel) return NULL; - if (data[size - 1]) + if (data && data[size - 1]) { /* Isn't nul terminated */ size++; @@ -956,12 +981,12 @@ _ecore_x_selection_parser_targets(const char *target __UNUSED__, int format __UNUSED__) { Ecore_X_Selection_Data_Targets *sel; - unsigned long *targets; + int *targets; int i; sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets)); if (!sel) return NULL; - targets = (unsigned long *)data; + targets = data; sel->num_targets = size - 2; sel->targets = malloc((size - 2) * sizeof(char *)); diff --git a/src/lib/ecore_x/xlib/ecore_x_vsync.c b/src/lib/ecore_x/xlib/ecore_x_vsync.c index 4296bb2..4714628 100644 --- a/src/lib/ecore_x/xlib/ecore_x_vsync.c +++ b/src/lib/ecore_x/xlib/ecore_x_vsync.c @@ -5,6 +5,7 @@ #include "Ecore.h" #include "ecore_x_private.h" #include "Ecore_X.h" +#include "ioctl.h" #include #include @@ -13,6 +14,7 @@ #include #include #include +#include #include #define ECORE_X_VSYNC_DRI2 1 @@ -108,6 +110,7 @@ static drm_magic_t drm_magic; static int drm_fd = -1; static int drm_event_is_busy = 0; +static int drm_event_exist = 0; static int drm_animators_interval = 1; static drmEventContext drm_evctx; static Ecore_Fd_Handler *dri_drm_fdh = NULL; @@ -117,7 +120,182 @@ static void *drm_lib = NULL; static Window dri_drm_vsync_root = 0; +static Ecore_Idle_Enterer *_idle_before = NULL; + +#define MSMFB_IOCTL_MAGIC 'm' +#define MSMFB_VSYNC_CTRL _IOW(MSMFB_IOCTL_MAGIC, 161, unsigned int) + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//vsync code +static int using_xvsync_fd = 0 +; +static Window vsync_root = 0; +static int fb0_fd = -1; +static int vsync_fd = -1; +static Ecore_Fd_Handler *vsync_fdh = NULL; +static int vsync_event_is_busy = 0; + +static double prev = 0; +static double cur = 0; +static Eina_Bool _dri_drm_tick_schedule(void); + +static double +get_time(void) +{ + struct timeval timev; + + gettimeofday(&timev, NULL); + return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); +} + +static Eina_Bool +_vsync_tick_schedule(void) +{ + char buf[256]; + int ret; + + if (vsync_fd == -1) return EINA_FALSE; + + memset(buf, 0, sizeof(buf)); +// LOG(LOG_INFO, "ECORE_VSYNC","Waiting on read()...\n"); + ret = pread(vsync_fd, buf, 256, 0); + if (ret > 0) + { + if (prev == 0) prev = get_time(); + else + { + cur = get_time(); + prev = cur; + } + } + else + return EINA_FALSE; + + return EINA_TRUE; +} + +static void +_vsync_tick_begin(void *data __UNUSED__) +{ + vsync_event_is_busy = 1; + _vsync_tick_schedule(); +} + static void +_vsync_tick_end(void *data __UNUSED__) +{ + vsync_event_is_busy = 0; +} + +static Eina_Bool +_xvsync_cb(void *data __UNUSED__, + Ecore_Fd_Handler *fd_handler __UNUSED__) +{ + if (vsync_event_is_busy ==1) + { + ecore_animator_custom_tick(); + _vsync_tick_schedule(); + } + return ECORE_CALLBACK_RENEW; +} + +static int +_vsync_link(void) +{ + if (using_xvsync_fd == 1) + { + int enable = 1; + + fb0_fd = open ("/dev/fb0", O_RDWR); + if (fb0_fd < 0) + { + ERR("%s failed to open fb0", __func__); + return -1; + } + + if (ioctl(fb0_fd, MSMFB_VSYNC_CTRL, &enable) < 0) + { + ERR("%s failed to set vsync [enable:%d]", __func__, enable); + return -1; + } + return 1; + } + return 0; +} + +static int +_vsync_init(void) +{ + if (using_xvsync_fd == 1) + { + vsync_fd = open ("/sys/class/graphics/fb0/vsync_event", O_RDONLY); + if (vsync_fd < 0) + return 0; + vsync_fdh = ecore_main_fd_handler_add(vsync_fd, ECORE_FD_ERROR, + _xvsync_cb, NULL, NULL, NULL); + if (!vsync_fdh) + { + close(vsync_fd); + vsync_fd = -1; + return 0; + } + + return 1; + } + return 0; +} + +static void +_vsync_shutdown(void) +{ + if (vsync_fd >= 0) + { + close(vsync_fd); + vsync_fd = -1; + } + if (vsync_fdh) + { + ecore_main_fd_handler_del(vsync_fdh); + vsync_fdh = NULL; + } +} + + +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +static Eina_Bool +_dri_drm_ecore_idle_enterer_before(void *data __UNUSED__) +{ + if (drm_event_exist) + { + ecore_animator_custom_tick(); + drm_event_exist = 0; + } + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_dri_drm_fail_timer_cb(void *data) +{ + if (drm_event_is_busy) + { + // we don't call animator here as input events could not be + // processed yet. This is because both input events and vsync events + // are handled by the 'select' of the ecore mainloop and the order + // of the two events is undefined. Moreover, input events are NOT + // even delievered to event listeners at the select handler. + // Thus we're running animators as 'idle_enterer_before_add' callback, + // which is executed right before evas rendering. + drm_event_exist = 1; + _dri_drm_tick_schedule(); + } + + return ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool _dri_drm_tick_schedule(void) { drmVBlank vbl; @@ -125,13 +303,20 @@ _dri_drm_tick_schedule(void) vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; vbl.request.sequence = drm_animators_interval; vbl.request.signal = 0; - sym_drmWaitVBlank(drm_fd, &vbl); + if (sym_drmWaitVBlank(drm_fd, &vbl) < 0) + { + // If LCD is off, drmWaitVBlank will be failed. In this case, we just use S/W timer! + ecore_timer_add(ecore_animator_frametime_get(), _dri_drm_fail_timer_cb, NULL); + } + return EINA_TRUE; } static void _dri_drm_tick_begin(void *data __UNUSED__) { + _idle_before = ecore_idle_enterer_before_add(_dri_drm_ecore_idle_enterer_before, NULL); drm_event_is_busy = 1; + drm_event_exist = 0; _dri_drm_tick_schedule(); } @@ -139,6 +324,12 @@ static void _dri_drm_tick_end(void *data __UNUSED__) { drm_event_is_busy = 0; + drm_event_exist = 0; + if (_idle_before) + { + ecore_idle_enterer_del(_idle_before); + _idle_before = NULL; + } } static void @@ -148,8 +339,18 @@ _dri_drm_vblank_handler(int fd __UNUSED__, unsigned int usec __UNUSED__, void *data __UNUSED__) { - ecore_animator_custom_tick(); - if (drm_event_is_busy) _dri_drm_tick_schedule(); + if (drm_event_is_busy) + { + // we don't call animator here as input events could not be + // processed yet. This is because both input events and vsync events + // are handled by the 'select' of the ecore mainloop and the order + // of the two events is undefined. Moreover, input events are NOT + // even delievered to event listeners at the select handler. + // Thus we're running animators as 'idle_enterer_befor' callback, + // which is executed right before evas rendering. + drm_event_exist = 1; + _dri_drm_tick_schedule(); + } } static Eina_Bool @@ -209,6 +410,7 @@ _dri_drm_link(void) SYM(drm_lib, drmClose); SYM(drm_lib, drmWaitVBlank); SYM(drm_lib, drmHandleEvent); + SYM(drm_lib, drmGetMagic); if (fail) { dlclose(drm_lib); @@ -252,7 +454,7 @@ _dri_drm_init(void) return 0; if (!sym_DRI2QueryVersion(_ecore_x_disp, &dri2_major, &dri2_minor)) return 0; - if (dri2_major < 2) + if ((dri2_major<1) || ((dri2_major==1) && (dri2_minor< 2))) //if (dri_version < 1.2) return 0; if (!sym_DRI2Connect(_ecore_x_disp, dri_drm_vsync_root, &driver_name, &device_name)) return 0; @@ -271,6 +473,13 @@ _dri_drm_init(void) drm_evctx.vblank_handler = _dri_drm_vblank_handler; drm_evctx.page_flip_handler = NULL; + if (!_dri_drm_tick_schedule()) + { + close(drm_fd); + drm_fd = -1; + return 0; + } + dri_drm_fdh = ecore_main_fd_handler_add(drm_fd, ECORE_FD_READ, _dri_drm_cb, NULL, NULL, NULL); if (!dri_drm_fdh) @@ -305,40 +514,86 @@ ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win) #ifdef ECORE_X_VSYNC_DRI2 Ecore_X_Window root; - root = ecore_x_window_root_get(win); - if (root != dri_drm_vsync_root) + if (getenv("ECORE_X_VSYNC")) using_xvsync_fd = 1; + + if (using_xvsync_fd) { - dri_drm_vsync_root = root; - if (dri_drm_vsync_root) + root = ecore_x_window_root_get(win); + if (root != vsync_root) { - if (!_dri_drm_link()) + vsync_root = root; + if (vsync_root) { - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); - return EINA_FALSE; + if (!_vsync_link()) + { + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + return EINA_FALSE; + } + + if (!_vsync_init()) + { + vsync_root = 0; + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + return EINA_FALSE; + } + + ecore_animator_custom_source_tick_begin_callback_set + (_vsync_tick_begin, NULL); + ecore_animator_custom_source_tick_end_callback_set + (_vsync_tick_end, NULL); + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); } - _dri_drm_shutdown(); - if (!_dri_drm_init()) + else { - dri_drm_vsync_root = 0; - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); - return EINA_FALSE; + if (vsync_fd >= 0) + { + _vsync_shutdown(); + ecore_animator_custom_source_tick_begin_callback_set + (NULL, NULL); + ecore_animator_custom_source_tick_end_callback_set + (NULL, NULL); + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + } } - ecore_animator_custom_source_tick_begin_callback_set - (_dri_drm_tick_begin, NULL); - ecore_animator_custom_source_tick_end_callback_set - (_dri_drm_tick_end, NULL); - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); } - else + } + else + { + root = ecore_x_window_root_get(win); + if (root != dri_drm_vsync_root) { - if (drm_fd >= 0) + dri_drm_vsync_root = root; + if (dri_drm_vsync_root) + { + if (!_dri_drm_link()) + { + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + return EINA_FALSE; + } + _dri_drm_shutdown(); + if (!_dri_drm_init()) + { + dri_drm_vsync_root = 0; + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + return EINA_FALSE; + } + ecore_animator_custom_source_tick_begin_callback_set + (_dri_drm_tick_begin, NULL); + ecore_animator_custom_source_tick_end_callback_set + (_dri_drm_tick_end, NULL); + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); + } + else { - _dri_drm_shutdown(); - ecore_animator_custom_source_tick_begin_callback_set - (NULL, NULL); - ecore_animator_custom_source_tick_end_callback_set - (NULL, NULL); - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + if (drm_fd >= 0) + { + _dri_drm_shutdown(); + ecore_animator_custom_source_tick_begin_callback_set + (NULL, NULL); + ecore_animator_custom_source_tick_end_callback_set + (NULL, NULL); + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + } } } } diff --git a/src/lib/ecore_x/xlib/ecore_x_window.c b/src/lib/ecore_x/xlib/ecore_x_window.c old mode 100644 new mode 100755 index f16f5b1..1a6dd1a --- a/src/lib/ecore_x/xlib/ecore_x_window.c +++ b/src/lib/ecore_x/xlib/ecore_x_window.c @@ -235,6 +235,7 @@ ecore_x_window_defaults_set(Ecore_X_Window win) int argc; char **argv; XTextProperty xprop; + unsigned int transform_hint = ECORE_X_WINDOW_ROTATION_TRANSFORM_HINT_0; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* @@ -263,6 +264,8 @@ ecore_x_window_defaults_set(Ecore_X_Window win) ecore_app_args_get(&argc, &argv); ecore_x_icccm_command_set(win, argc, argv); + + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_WINDOW_ROTATION_TRANSFORM_HINT, &transform_hint, 1); } EAPI void @@ -670,13 +673,6 @@ ecore_x_window_reparent(Ecore_X_Window win, XReparentWindow(_ecore_x_disp, win, new_parent, x, y); } -/** - * Retrieves the size of the given window. - * @param win The given window. - * @param w Pointer to an integer into which the width is to be stored. - * @param h Pointer to an integer into which the height is to be stored. - * @ingroup Ecore_X_Window_Geometry_Group - */ EAPI void ecore_x_window_size_get(Ecore_X_Window win, int *w, @@ -691,22 +687,6 @@ ecore_x_window_size_get(Ecore_X_Window win, ecore_x_drawable_geometry_get(win, &dummy_x, &dummy_y, w, h); } -/** - * Retrieves the geometry of the given window. - * - * Note that the x & y coordinates are relative to your parent. In - * particular for reparenting window managers - relative to you window border. - * If you want screen coordinates either walk the window tree to the root, - * else for ecore_evas applications see ecore_evas_geometry_get(). Elementary - * applications can use elm_win_screen_position_get(). - * - * @param win The given window. - * @param x Pointer to an integer in which the X position is to be stored. - * @param y Pointer to an integer in which the Y position is to be stored. - * @param w Pointer to an integer in which the width is to be stored. - * @param h Pointer to an integer in which the height is to be stored. - * @ingroup Ecore_X_Window_Geometry_Group - */ EAPI void ecore_x_window_geometry_get(Ecore_X_Window win, int *x, @@ -721,12 +701,6 @@ ecore_x_window_geometry_get(Ecore_X_Window win, ecore_x_drawable_geometry_get(win, x, y, w, h); } -/** - * Retrieves the width of the border of the given window. - * @param win The given window. - * @return Width of the border of @p win. - * @ingroup Ecore_X_Window_Geometry_Group - */ EAPI int ecore_x_window_border_width_get(Ecore_X_Window win) { @@ -756,11 +730,6 @@ ecore_x_window_border_width_set(Ecore_X_Window win, XSetWindowBorderWidth (_ecore_x_disp, win, width); } -/** - * Retrieves the depth of the given window. - * @param win The given window. - * @return Depth of the window. - */ EAPI int ecore_x_window_depth_get(Ecore_X_Window win) { @@ -1725,3 +1694,71 @@ ecore_x_window_override_argb_new(Ecore_X_Window parent, #endif /* ifdef ECORE_XRENDER */ } +EAPI Ecore_X_Window +ecore_x_window_permanent_create(Ecore_X_Window parent, + Ecore_X_Atom unique_atom) +{ + Display *disp; + Window win, win2, realwin = 0; + Atom type_ret; + int format_ret; + unsigned long ldata, bytes_after, num_ret, *datap; + unsigned char *prop_ret; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + disp = XOpenDisplay(DisplayString(_ecore_x_disp)); + if (!disp) return 0; + + XGrabServer(disp); + if (XGetWindowProperty(disp, parent, unique_atom, 0, 0x7fffffff, + False, XA_WINDOW, &type_ret, &format_ret, + &num_ret, &bytes_after, &prop_ret)) + { + if (prop_ret) + { + if ((format_ret == 32) && (type_ret == XA_WINDOW) && + (num_ret == 1)) + { + datap = (unsigned long *)prop_ret; + win = (Window)(*datap); + XFree(prop_ret); + if (XGetWindowProperty(disp, win, unique_atom, 0, 0x7fffffff, + False, XA_WINDOW, &type_ret, &format_ret, + &num_ret, &bytes_after, &prop_ret)) + { + if (prop_ret) + { + if ((format_ret == 32) && (type_ret == XA_WINDOW) && + (num_ret == 1)) + { + datap = (unsigned long *)prop_ret; + win2 = (Window)(*datap); + XFree(prop_ret); + if (win2 == win) realwin = win; + } + else XFree(prop_ret); + } + } + } + else XFree(prop_ret); + } + } + if (realwin != 0) + { + XUngrabServer(disp); + XFlush(disp); + XCloseDisplay(disp); + return realwin; + } + win = XCreateSimpleWindow(disp, parent, -77, -77, 7, 7, 0, 0, 0); + ldata = (unsigned long)win; + XChangeProperty(disp, win, unique_atom, XA_WINDOW, 32, + PropModeReplace, (unsigned char *)(&ldata), 1); + XChangeProperty(disp, parent, unique_atom, XA_WINDOW, 32, + PropModeReplace, (unsigned char *)(&ldata), 1); + XSetCloseDownMode(disp, RetainPermanent); + XUngrabServer(disp); + XFlush(disp); + XCloseDisplay(disp); + return win; +} diff --git a/src/lib/ecore_x/xlib/ecore_x_window_prop.c b/src/lib/ecore_x/xlib/ecore_x_window_prop.c index a582453..98b41c4 100644 --- a/src/lib/ecore_x/xlib/ecore_x_window_prop.c +++ b/src/lib/ecore_x/xlib/ecore_x_window_prop.c @@ -2,6 +2,32 @@ # include #endif /* ifdef HAVE_CONFIG_H */ +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + #include #include diff --git a/src/lib/ecore_x/xlib/ecore_x_window_shape.c b/src/lib/ecore_x/xlib/ecore_x_window_shape.c index 71718cf..992be09 100644 --- a/src/lib/ecore_x/xlib/ecore_x_window_shape.c +++ b/src/lib/ecore_x/xlib/ecore_x_window_shape.c @@ -201,16 +201,17 @@ ecore_x_window_shape_rectangles_set(Ecore_X_Window win, rect[i].width = rects[i].width; rect[i].height = rects[i].height; } + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeBounding, + 0, + 0, + rect, + num, + ShapeSet, + Unsorted); } - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeBounding, - 0, - 0, - rect, - num, - ShapeSet, - Unsorted); + if (rect) free(rect); #else return; @@ -496,17 +497,17 @@ ecore_x_window_shape_rectangles_add(Ecore_X_Window win, rect[i].width = rects[i].width; rect[i].height = rects[i].height; } + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeBounding, + 0, + 0, + rect, + num, + ShapeUnion, + Unsorted); } - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeBounding, - 0, - 0, - rect, - num, - ShapeUnion, - Unsorted); if (rect) free(rect); } @@ -531,17 +532,17 @@ ecore_x_window_shape_input_rectangles_add(Ecore_X_Window win, rect[i].width = rects[i].width; rect[i].height = rects[i].height; } + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeInput, + 0, + 0, + rect, + num, + ShapeUnion, + Unsorted); } - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeInput, - 0, - 0, - rect, - num, - ShapeUnion, - Unsorted); if (rect) free(rect); #else return; diff --git a/src/lib/ecore_x/xlib/ecore_x_xi2.c b/src/lib/ecore_x/xlib/ecore_x_xi2.c old mode 100644 new mode 100755 index fbfbd43..4690f60 --- a/src/lib/ecore_x/xlib/ecore_x_xi2.c +++ b/src/lib/ecore_x/xlib/ecore_x_xi2.c @@ -19,8 +19,27 @@ int _ecore_x_xi2_opcode = -1; #endif #ifdef ECORE_XI2 +#ifdef ECORE_XI2_2 +#ifndef XITouchEmulatingPointer +#define XITouchEmulatingPointer (1 << 17) +#endif + +typedef struct _Ecore_X_Touch_Device_Info +{ + EINA_INLIST; + int devid; + int mode; + const char *name; + int max_touch; + int *slot; +} Ecore_X_Touch_Device_Info; +#endif /* ifdef ECORE_XI2_2 */ + static XIDeviceInfo *_ecore_x_xi2_devs = NULL; static int _ecore_x_xi2_num = 0; +#ifdef ECORE_XI2_2 +static Eina_Inlist *_ecore_x_xi2_touch_info_list = NULL; +#endif /* ifdef ECORE_XI2_2 */ #endif /* ifdef ECORE_XI2 */ void @@ -28,7 +47,7 @@ _ecore_x_input_init(void) { #ifdef ECORE_XI2 int event, error; - int major = 2, minor = 0; + int major = XI_2_Major, minor = XI_2_Minor; if (!XQueryExtension(_ecore_x_disp, "XInputExtension", &_ecore_x_xi2_opcode, &event, &error)) @@ -48,6 +67,27 @@ _ecore_x_input_init(void) #endif /* ifdef ECORE_XI2 */ } +#ifdef ECORE_XI2 +#ifdef ECORE_XI2_2 +static void +_ecore_x_input_touch_info_clear(void) +{ + Eina_Inlist *l = _ecore_x_xi2_touch_info_list; + Ecore_X_Touch_Device_Info *info = NULL; + + while (l) + { + info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Touch_Device_Info); + l = eina_inlist_remove(l, l); + if (info->slot) free(info->slot); + free(info); + } + + _ecore_x_xi2_touch_info_list = NULL; +} +#endif /* ifdef ECORE_XI2_2 */ +#endif /* ifdef ECORE_XI2 */ + void _ecore_x_input_shutdown(void) { @@ -56,6 +96,9 @@ _ecore_x_input_shutdown(void) { XIFreeDeviceInfo(_ecore_x_xi2_devs); _ecore_x_xi2_devs = NULL; +#ifdef ECORE_XI2_2 + _ecore_x_input_touch_info_clear(); +#endif /* ifdef ECORE_XI2_2 */ } _ecore_x_xi2_num = 0; @@ -63,14 +106,136 @@ _ecore_x_input_shutdown(void) #endif /* ifdef ECORE_XI2 */ } +#ifdef ECORE_XI2 +#ifdef ECORE_XI2_2 +static int +_ecore_x_input_touch_index_get(int devid, int detail, int event_type) +{ + int i; + Eina_Inlist *l = _ecore_x_xi2_touch_info_list; + Ecore_X_Touch_Device_Info *info = NULL; + + if ((!_ecore_x_xi2_devs) || (!_ecore_x_xi2_touch_info_list)) + return 0; + + EINA_INLIST_FOREACH(l, info) + if (info->devid == devid) break; + + if ((!info) || (!info->slot)) return 0; + + for (i = 0; i < info->max_touch ; i++) + { + int *p = &(info->slot[i]); + + if ((event_type == XI_TouchBegin) && (*p < 0)) + { + *p = detail; + return i; + } + else if (*p == detail) + { + return i; + } + } + + return 0; +} + +static void +_ecore_x_input_touch_index_clear(int devid, int idx) +{ + Eina_Inlist *l = _ecore_x_xi2_touch_info_list; + Ecore_X_Touch_Device_Info *info = NULL; + + if ((!_ecore_x_xi2_devs) || (!_ecore_x_xi2_touch_info_list)) + return; + + EINA_INLIST_FOREACH(l, info) + { + if ((info->devid == devid) && (info->slot)) + { + info->slot[idx] = -1; + return; + } + } +} + +static Ecore_X_Touch_Device_Info * +_ecore_x_input_touch_info_get(XIDeviceInfo *dev) +{ + int k; + int *slot = NULL; + XITouchClassInfo *t = NULL; + Ecore_X_Touch_Device_Info *info = NULL; + + if (!dev) + return NULL; + + for (k = 0; k < dev->num_classes; k++) + { + XIAnyClassInfo *clas = dev->classes[k]; + + if (clas && (clas->type == XITouchClass)) + { + t = (XITouchClassInfo *)clas; + break; + } + } + + if (t && (t->type == XITouchClass)) + { + info = calloc(1, sizeof(Ecore_X_Touch_Device_Info)); + if (!info) return NULL; + + slot = malloc(sizeof(int) * (t->num_touches + 1)); + if (!slot) + { + free(info); + return NULL; + } + + info->devid = dev->deviceid; + info->max_touch = t->num_touches + 1; + info->mode = t->mode; + info->name = dev->name; + memset(slot, -1, sizeof(int) * info->max_touch); + info->slot = slot; + } + + return info; +} +#endif /* ifdef ECORE_XI2_2 */ +#endif + void _ecore_x_input_handler(XEvent *xevent) { #ifdef ECORE_XI2 XIDeviceEvent *evd = (XIDeviceEvent *)(xevent->xcookie.data); + /* XIRawEvent *evr = (XIRawEvent *)(xevent->xcookie.data); */ int devid = evd->deviceid; int i; + /* No filter for this events */ + switch (xevent->xcookie.evtype) + { +#ifdef XI_RawButtonPress + case XI_RawButtonPress: + ecore_event_add(ECORE_X_RAW_BUTTON_PRESS, NULL, NULL, NULL); + break; +#endif +#ifdef XI_RawButtonRelease + case XI_RawButtonRelease: + ecore_event_add(ECORE_X_RAW_BUTTON_RELEASE, NULL, NULL, NULL); + break; +#endif +#ifdef XI_RawMotion + case XI_RawMotion: + ecore_event_add(ECORE_X_RAW_MOTION, NULL, NULL, NULL); + break; +#endif + } + if (_ecore_x_xi2_devs) { for (i = 0; i < _ecore_x_xi2_num; i++) @@ -82,6 +247,16 @@ _ecore_x_input_handler(XEvent *xevent) if (dev->use == XIMasterPointer) return; if ((dev->use == XISlavePointer) && (evd->flags & XIPointerEmulated)) return; + // TIZEN ONLY (20150713): support rotary event + if (!strcmp(dev->name, "tizen_rotary")) + { + return; + } + if (!strcmp(dev->name, "tizen_detent")) + { + return; + } + // } } } @@ -105,6 +280,7 @@ _ecore_x_input_handler(XEvent *xevent) break; case XI_ButtonPress: + DBG("ButtonEvent:multi press time=%u devid=%d", (unsigned int)evd->time, devid); _ecore_mouse_button (ECORE_EVENT_MOUSE_BUTTON_DOWN, evd->time, @@ -124,6 +300,7 @@ _ecore_x_input_handler(XEvent *xevent) break; case XI_ButtonRelease: + DBG("ButtonEvent:multi release time=%u devid=%d", (unsigned int)evd->time, devid); _ecore_mouse_button (ECORE_EVENT_MOUSE_BUTTON_UP, evd->time, @@ -144,6 +321,10 @@ _ecore_x_input_handler(XEvent *xevent) #ifdef XI_TouchUpdate case XI_TouchUpdate: +#ifdef ECORE_XI2_2 + i = _ecore_x_input_touch_index_get(devid, evd->detail, XI_TouchUpdate); + if ((i == 0) && (evd->flags & XITouchEmulatingPointer)) return; +#endif /* #ifdef ECORE_XI2_2 */ _ecore_mouse_move (evd->time, 0, // state @@ -153,16 +334,24 @@ _ecore_x_input_handler(XEvent *xevent) (evd->child ? evd->child : evd->event), evd->root, 1, // same_screen +#ifdef ECORE_XI2_2 + i, 1, 1, +#else devid, 1, 1, +#endif /* #ifdef ECORE_XI2_2 */ 1.0, // pressure 0.0, // angle evd->event_x, evd->event_y, evd->root_x, evd->root_y); break; - #endif + #ifdef XI_TouchBegin case XI_TouchBegin: +#ifdef ECORE_XI2_2 + i = _ecore_x_input_touch_index_get(devid, evd->detail, XI_TouchBegin); + if ((i == 0) && (evd->flags & XITouchEmulatingPointer)) return; +#endif /* #ifdef ECORE_XI2_2 */ _ecore_mouse_button (ECORE_EVENT_MOUSE_BUTTON_DOWN, evd->time, @@ -174,16 +363,28 @@ _ecore_x_input_handler(XEvent *xevent) (evd->child ? evd->child : evd->event), evd->root, 1, // same_screen +#ifdef ECORE_XI2_2 + i, 1, 1, +#else devid, 1, 1, +#endif /* #ifdef ECORE_XI2_2 */ 1.0, // pressure 0.0, // angle evd->event_x, evd->event_y, evd->root_x, evd->root_y); break; - #endif + #ifdef XI_TouchEnd case XI_TouchEnd: +#ifdef ECORE_XI2_2 + i = _ecore_x_input_touch_index_get(devid, evd->detail, XI_TouchEnd); + if ((i == 0) && (evd->flags & XITouchEmulatingPointer)) + { + _ecore_x_input_touch_index_clear(devid, i); + return; + } +#endif /* #ifdef ECORE_XI2_2 */ _ecore_mouse_button (ECORE_EVENT_MOUSE_BUTTON_UP, evd->time, @@ -195,14 +396,21 @@ _ecore_x_input_handler(XEvent *xevent) (evd->child ? evd->child : evd->event), evd->root, 1, // same_screen +#ifdef ECORE_XI2_2 + i, 1, 1, +#else devid, 1, 1, +#endif /* #ifdef ECORE_XI2_2 */ 1.0, // pressure 0.0, // angle evd->event_x, evd->event_y, evd->root_x, evd->root_y); +#ifdef ECORE_XI2_2 + _ecore_x_input_touch_index_clear(devid, i); +#endif /* #ifdef ECORE_XI2_2 */ break; - #endif + default: break; } @@ -260,6 +468,21 @@ ecore_x_input_multi_select(Ecore_X_Window win) XISetMask(mask, XI_ButtonPress); XISetMask(mask, XI_ButtonRelease); XISetMask(mask, XI_Motion); +#ifdef ECORE_XI2_2 + Eina_Inlist *l = _ecore_x_xi2_touch_info_list; + Ecore_X_Touch_Device_Info *info; + info = _ecore_x_input_touch_info_get(dev); + + if (info) + { + XISetMask(mask, XI_TouchUpdate); + XISetMask(mask, XI_TouchBegin); + XISetMask(mask, XI_TouchEnd); + + l = eina_inlist_append(l, (Eina_Inlist *)info); + _ecore_x_xi2_touch_info_list = l; + } +#else # ifdef XI_TouchUpdate XISetMask(mask, XI_TouchUpdate); # endif @@ -269,9 +492,39 @@ ecore_x_input_multi_select(Ecore_X_Window win) # ifdef XI_TouchEnd XISetMask(mask, XI_TouchEnd); # endif +#endif /* #ifdef ECORE_XI2_2 */ + XISelectEvents(_ecore_x_disp, win, &eventmask, 1); find = EINA_TRUE; } +#ifdef ECORE_XI2_2 + else if ((atdev) && (atdev->use == XIMasterPointer)) + { + Eina_Inlist *l = _ecore_x_xi2_touch_info_list; + Ecore_X_Touch_Device_Info *info; + info = _ecore_x_input_touch_info_get(dev); + + if (info) + { + XIEventMask eventmask; + unsigned char mask[4] = { 0 }; + + eventmask.deviceid = dev->deviceid; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + + XISetMask(mask, XI_TouchUpdate); + XISetMask(mask, XI_TouchBegin); + XISetMask(mask, XI_TouchEnd); + XISelectEvents(_ecore_x_disp, win, &eventmask, 1); + + l = eina_inlist_append(l, (Eina_Inlist *)info); + _ecore_x_xi2_touch_info_list = l; + + find = EINA_TRUE; + } + } +#endif /* #ifdef ECORE_XI2_2 */ } } @@ -281,3 +534,35 @@ ecore_x_input_multi_select(Ecore_X_Window win) #endif /* ifdef ECORE_XI2 */ } +EAPI Eina_Bool +ecore_x_input_raw_select(Ecore_X_Window win) +{ +#ifdef ECORE_XI2 + XIEventMask emask; + unsigned char mask[4] = { 0 }; + + if (!_ecore_x_xi2_devs) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + emask.deviceid = XIAllMasterDevices; + emask.mask_len = sizeof(mask); + emask.mask = mask; +#ifdef XI_RawButtonPress + XISetMask(emask.mask, XI_RawButtonPress); +#endif +#ifdef XI_RawButtonRelease + XISetMask(emask.mask, XI_RawButtonRelease); +#endif +#ifdef XI_RawMotion + XISetMask(emask.mask, XI_RawMotion); +#endif + + XISelectEvents(_ecore_x_disp, win, &emask, 1); + + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + diff --git a/src/lib/ecore_x/xlib/ioctl.h b/src/lib/ecore_x/xlib/ioctl.h new file mode 100755 index 0000000..15828b2 --- /dev/null +++ b/src/lib/ecore_x/xlib/ioctl.h @@ -0,0 +1,105 @@ +#ifndef _ASM_GENERIC_IOCTL_H +#define _ASM_GENERIC_IOCTL_H + +/* ioctl command encoding: 32 bits total, command in lower 16 bits, + * size of the parameter structure in the lower 14 bits of the + * upper 16 bits. + * Encoding the size of the parameter structure in the ioctl request + * is useful for catching programs compiled with old versions + * and to avoid overwriting user space outside the user buffer area. + * The highest 2 bits are reserved for indicating the ``access mode''. + * NOTE: This limits the max parameter size to 16kB -1 ! + */ + +/* + * The following is for compatibility across the various Linux + * platforms. The generic ioctl numbering scheme doesn't really enforce + * a type field. De facto, however, the top 8 bits of the lower 16 + * bits are indeed used as a type field, so we might just as well make + * this explicit here. Please be sure to use the decoding macros + * below from now on. + */ +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 + +/* + * Let any architecture override either of the following before + * including this file. + */ + +#ifndef _IOC_SIZEBITS +# define _IOC_SIZEBITS 14 +#endif + +#ifndef _IOC_DIRBITS +# define _IOC_DIRBITS 2 +#endif + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * Direction bits, which any architecture can choose to override + * before including this file. + */ + +#ifndef _IOC_NONE +# define _IOC_NONE 0U +#endif + +#ifndef _IOC_WRITE +# define _IOC_WRITE 1U +#endif + +#ifndef _IOC_READ +# define _IOC_READ 2U +#endif + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +#ifdef __KERNEL__ +/* provoke compile error for invalid uses of size argument */ +extern unsigned int __invalid_size_argument_for_IOC; +#define _IOC_TYPECHECK(t) \ + ((sizeof(t) == sizeof(t[1]) && \ + sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ + sizeof(t) : __invalid_size_argument_for_IOC) +#else +#define _IOC_TYPECHECK(t) (sizeof(t)) +#endif + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode ioctl numbers.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +/* ...and for the drivers/sound files... */ + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* _ASM_GENERIC_IOCTL_H */ diff --git a/src/modules/immodules/ibus/ibus_imcontext.c b/src/modules/immodules/ibus/ibus_imcontext.c index 2c2e180..e41a11b 100644 --- a/src/modules/immodules/ibus/ibus_imcontext.c +++ b/src/modules/immodules/ibus/ibus_imcontext.c @@ -257,6 +257,8 @@ ibus_im_context_del(Ecore_IMF_Context *ctx) // release preedit if (ibusimcontext->preedit_string) free(ibusimcontext->preedit_string); + if (_focus_im_context == ctx) + _focus_im_context = NULL; } EAPI Eina_Bool @@ -426,7 +428,12 @@ ibus_im_context_preedit_string_get(Ecore_IMF_Context *ctx, if (cursor_pos) *cursor_pos = 0; } - EINA_LOG_DBG("str : %s, cursor_pos : %d", *str, *cursor_pos); + + if (str) + EINA_LOG_DBG("str : %s", *str); + + if (cursor_pos) + EINA_LOG_DBG("cursor_pos : %d", *cursor_pos); } EAPI void @@ -454,7 +461,12 @@ ibus_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, if (cursor_pos) *cursor_pos = 0; } - EINA_LOG_DBG("str : %s, cursor_pos : %d", *str, *cursor_pos); + + if (str) + EINA_LOG_DBG("str : %s", *str); + + if (cursor_pos) + EINA_LOG_DBG("cursor_pos : %d", *cursor_pos); } EAPI void diff --git a/src/modules/immodules/scim/scim_imcontext.cpp b/src/modules/immodules/scim/scim_imcontext.cpp index d4d20b1..0bb29f9 100644 --- a/src/modules/immodules/scim/scim_imcontext.cpp +++ b/src/modules/immodules/scim/scim_imcontext.cpp @@ -2828,6 +2828,7 @@ slot_get_surrounding_text(IMEngineInstanceBase *si, else if (maxlen_after == 0) after = WideString(); text = before + after; cursor = before.length(); + if (surrounding) free(surrounding); return true; } } diff --git a/src/modules/immodules/xim/ecore_imf_xim.c b/src/modules/immodules/xim/ecore_imf_xim.c index 7605763..3e0c24b 100644 --- a/src/modules/immodules/xim/ecore_imf_xim.c +++ b/src/modules/immodules/xim/ecore_imf_xim.c @@ -228,8 +228,6 @@ _ecore_imf_context_xim_preedit_string_get(Ecore_IMF_Context *ctx, { if (str) *str = NULL; - if (cursor_pos) - *cursor_pos = 0; } if (cursor_pos) @@ -738,18 +736,7 @@ _ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, } else { - XComposeStatus status; - val = XLookupString(&xev, - compose_buffer, - sizeof(compose_buffer), - &sym, - &status); - if (val > 0) - { - compose_buffer[val] = '\0'; - compose = eina_str_convert(nl_langinfo(CODESET), - "UTF-8", compose_buffer); - } + compose = strdup(ev->compose); } if (compose) @@ -1031,6 +1018,8 @@ preedit_draw_callback(XIC xic __UNUSED__, EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + imf_context_data->preedit_cursor = call_data->caret; + preedit_bufs = eina_ustrbuf_new(); if (imf_context_data->preedit_chars) { @@ -1132,6 +1121,8 @@ preedit_callback_set(Ecore_IMF_Context *ctx) { Ecore_IMF_Context_Data *imf_context_data; imf_context_data = ecore_imf_context_data_get(ctx); + if (!imf_context_data) + return XVaCreateNestedList(0, NULL); imf_context_data->preedit_start_cb.client_data = (XPointer)ctx; imf_context_data->preedit_start_cb.callback = (XIMProc)preedit_start_callback; @@ -1356,12 +1347,13 @@ set_ic_client_window(Ecore_IMF_Context *ctx, EINA_LOG_DBG("old_win:%d window:%d ", old_win, window); if (old_win != 0 && old_win != window) /* XXX how do check window... */ { - XIM_Im_Info *info; - info = imf_context_data->im_info; - info->ics = eina_list_remove(info->ics, imf_context_data); - if (imf_context_data->im_info) - imf_context_data->im_info->user = NULL; - imf_context_data->im_info = NULL; + XIM_Im_Info *info = imf_context_data->im_info; + if (info) + { + info->ics = eina_list_remove(info->ics, imf_context_data); + info->user = NULL; + info = NULL; + } } imf_context_data->win = window; -- 2.7.4