From 0b404ef16344dc0b8c6c8f9a5d0f4765be5adb4e Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Thu, 20 Aug 2009 08:58:29 +0000 Subject: [PATCH] illume2 thing... refactoring the code here. use at your own risk! SVN revision: 41883 --- configure.ac | 2 + src/modules/Makefile.am | 2 +- src/modules/illume2/.cvsignore | 7 + src/modules/illume2/Makefile.am | 35 + src/modules/illume2/e-module-illume2.edj | Bin 0 -> 9866 bytes src/modules/illume2/e_kbd.c | 1101 +++++++++++++++++++++ src/modules/illume2/e_kbd.h | 53 + src/modules/illume2/e_mod_layout.c | 471 +++++++++ src/modules/illume2/e_mod_layout.h | 55 + src/modules/illume2/e_mod_layout_illume.c | 139 +++ src/modules/illume2/e_mod_layout_illume.h | 7 + src/modules/illume2/e_mod_main.c | 41 + src/modules/illume2/e_mod_main.h | 10 + src/modules/illume2/module.desktop.in | 6 + x-ui.sh | 29 +- 15 files changed, 1945 insertions(+), 13 deletions(-) create mode 100644 src/modules/illume2/.cvsignore create mode 100644 src/modules/illume2/Makefile.am create mode 100644 src/modules/illume2/e-module-illume2.edj create mode 100644 src/modules/illume2/e_kbd.c create mode 100644 src/modules/illume2/e_kbd.h create mode 100644 src/modules/illume2/e_mod_layout.c create mode 100644 src/modules/illume2/e_mod_layout.h create mode 100644 src/modules/illume2/e_mod_layout_illume.c create mode 100644 src/modules/illume2/e_mod_layout_illume.h create mode 100644 src/modules/illume2/e_mod_main.c create mode 100644 src/modules/illume2/e_mod_main.h create mode 100644 src/modules/illume2/module.desktop.in diff --git a/configure.ac b/configure.ac index 4d33ba18e..f514f13a6 100644 --- a/configure.ac +++ b/configure.ac @@ -555,6 +555,8 @@ src/modules/illume/Makefile src/modules/illume/module.desktop src/modules/illume/keyboards/Makefile src/modules/illume/dicts/Makefile +src/modules/illume2/Makefile +src/modules/illume2/module.desktop src/modules/syscon/Makefile src/modules/syscon/module.desktop src/modules/everything/Makefile diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am index d3d410e37..f544f5254 100644 --- a/src/modules/Makefile.am +++ b/src/modules/Makefile.am @@ -239,7 +239,7 @@ SUBDIRS += connman endif if USE_MODULE_ILLUME -SUBDIRS += illume +SUBDIRS += illume illume2 endif if USE_MODULE_SYSCON diff --git a/src/modules/illume2/.cvsignore b/src/modules/illume2/.cvsignore new file mode 100644 index 000000000..bb0ec768d --- /dev/null +++ b/src/modules/illume2/.cvsignore @@ -0,0 +1,7 @@ +module.la +*.lo +Makefile.in +Makefile +.libs +.deps +module.desktop diff --git a/src/modules/illume2/Makefile.am b/src/modules/illume2/Makefile.am new file mode 100644 index 000000000..f1dd59fc5 --- /dev/null +++ b/src/modules/illume2/Makefile.am @@ -0,0 +1,35 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = illume2 + +# data files for the module +filesdir = $(libdir)/enlightenment/modules/$(MODULE) +files_DATA = \ +e-module-$(MODULE).edj module.desktop + +EXTRA_DIST = $(files_DATA) + +# the module .so file +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src/modules/$(MODULE) \ + -I$(top_srcdir)/src/bin \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/modules \ + @e_cflags@ +pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la +module_la_SOURCES = e_mod_main.c \ + e_mod_main.h \ + e_mod_layout.h \ + e_mod_layout.c \ + e_mod_layout_illume.c \ + e_mod_layout_illume.h \ + e_kbd.h \ + e_kbd.c + +module_la_LIBADD = @e_libs@ @dlopen_libs@ +module_la_LDFLAGS = -module -avoid-version +module_la_DEPENDENCIES = $(top_builddir)/config.h + +uninstall: + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE) diff --git a/src/modules/illume2/e-module-illume2.edj b/src/modules/illume2/e-module-illume2.edj new file mode 100644 index 0000000000000000000000000000000000000000..3c09021b6fad9411d880b89d2dd70cf2577e16f1 GIT binary patch literal 9866 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 + e_border_layer_set(kbd->border, 250); + else + e_border_layer_set(kbd->border, 100); + e_border_show(bd); + e_border_raise(bd); +} + +static int +_e_kbd_cb_animate(void *data) +{ + E_Kbd *kbd; + double t, v; + + kbd = data; + t = ecore_loop_time_get() - kbd->start; + if (t > kbd->len) t = kbd->len; + if (kbd->len > 0.0) + { + v = t / kbd->len; + v = 1.0 - v; + v = v * v * v * v; + v = 1.0 - v; + } + else + { + t = kbd->len; + v = 1.0; + } + kbd->adjust = (kbd->adjust_end * v) + (kbd->adjust_start * (1.0 - v)); + if (kbd->border) + { + e_border_fx_offset(kbd->border, 0, kbd->border->h - kbd->adjust); + } + if (t == kbd->len) + { + kbd->animator = NULL; + if (!kbd->visible) + { + _e_kbd_border_hide(kbd->border); + kbd->actually_visible = kbd->visible; + } + _e_kbd_apply_all_job_queue(); + _e_kbd_layout_send(kbd); + return 0; + } + return 1; +} + +static void +_e_kbd_free(E_Kbd *kbd) +{ + E_Border *bd; + + kbds = eina_list_remove(kbds, kbd); + if (kbd->animator) ecore_animator_del(kbd->animator); + if (kbd->delay_hide) ecore_timer_del(kbd->delay_hide); +// FIXME: thought right - on shutdoiwn, this might point to freed data +// if (kbd->border) kbd->border->stolen = 0; + EINA_LIST_FREE(kbd->waiting_borders, bd) + bd->stolen = 0; + free(kbd); +} + +static void +_e_kbd_slide(E_Kbd *kbd, int visible, double len) +{ + _e_kbd_apply_all_job_queue(); + kbd->start = ecore_loop_time_get(); + kbd->len = len; + kbd->adjust_start = kbd->adjust; + kbd->adjust_end = 0; + if ((visible) && (kbd->border)) + kbd->adjust_end = kbd->border->h; + if (!kbd->animator) + kbd->animator = ecore_animator_add(_e_kbd_cb_animate, kbd); +} + +static void +_e_kbd_hide(E_Kbd *kbd) +{ + if (kbd->visible) return; +#if 0 + if (illume_cfg->sliding.kbd.duration <= 0) + { + _e_kbd_border_hide(kbd->border); + kbd->actually_visible = kbd->visible; + _e_kbd_apply_all_job_queue(); + _e_kbd_layout_send(kbd); + } + else + _e_kbd_slide(kbd, 0, (double)illume_cfg->sliding.kbd.duration / 1000.0); +#endif +} + +static int +_e_kbd_border_is_keyboard(E_Border *bd) +{ + if ((bd->client.vkbd.vkbd) || /* explicit hint that its a virtual keyboard */ + /* legacy */ + ( /* trap the matchbox qwerty and multitap kbd's */ + (((bd->client.icccm.title) && (!strcmp(bd->client.icccm.title, "Keyboard"))) || + ((bd->client.icccm.name) && ((!strcmp(bd->client.icccm.name, "multitap-pad"))))) + && (bd->client.netwm.state.skip_taskbar) + && (bd->client.netwm.state.skip_pager) + ) + ) + return 1; + + return 0; +} + +static void +_e_kbd_border_adopt(E_Kbd *kbd, E_Border *bd) +{ + kbd->border = bd; + bd->sticky = 1; + if (kbd->fullscreen) + e_border_layer_set(kbd->border, 250); + else + e_border_layer_set(kbd->border, 100); + if (!kbd->actually_visible) + { + e_border_fx_offset(kbd->border, 0, kbd->border->h); + _e_kbd_layout_send(kbd); + } + kbd->h = kbd->border->h; +} + +static E_Kbd * +_e_kbd_by_border_get(E_Border *bd) +{ + Eina_List *l, *l2; + E_Border *over; + E_Kbd *kbd; + + if (!bd->stolen) return NULL; + EINA_LIST_FOREACH(kbds, l, kbd) + { + if (kbd->border == bd) return kbd; + EINA_LIST_FOREACH(kbd->waiting_borders, l2, over) + if (over == bd) return kbd; + } + return NULL; +} + +static int +_e_kbd_cb_delayed_hide(void *data) +{ + E_Kbd *kbd; + + kbd = data; + _e_kbd_hide(kbd); + kbd->delay_hide = NULL; + return 0; +} + +static void +_e_kbd_all_enable(void) +{ + Eina_List *l; + E_Kbd *kbd; + + EINA_LIST_FOREACH(kbds, l, kbd) + e_kbd_enable(kbd); +} + +static void +_e_kbd_all_disable(void) +{ + Eina_List *l; + E_Kbd *kbd; + + EINA_LIST_FOREACH(kbds, l, kbd) + e_kbd_disable(kbd); +} + +static void +_e_kbd_all_show(void) +{ + Eina_List *l; + E_Kbd *kbd; + + EINA_LIST_FOREACH(kbds, l, kbd) + e_kbd_show(kbd); +} + +static void +_e_kbd_all_layout_set(E_Kbd_Layout layout) +{ + Eina_List *l; + E_Kbd *kbd; + + EINA_LIST_FOREACH(kbds, l, kbd) + e_kbd_layout_set(kbd, layout); +} + +static void +_e_kbd_all_hide(void) +{ + Eina_List *l; + E_Kbd *kbd; + + EINA_LIST_FOREACH(kbds, l, kbd) + e_kbd_hide(kbd); +} + +static void +_e_kbd_all_toggle(void) +{ + Eina_List *l; + E_Kbd *kbd; + + EINA_LIST_FOREACH(kbds, l, kbd) + if (kbd->visible) e_kbd_hide(kbd); + else e_kbd_show(kbd); +} + +static int +_e_kbd_cb_client_message(void *data, int type, void *event) +{ + Ecore_X_Event_Client_Message *ev; + + ev = event; + if ((ev->win == ecore_x_window_root_first_get()) && + ((ev->message_type == atom_mb_im_invoker_command) || + (ev->message_type == atom_mtp_im_invoker_command))) + { + if (ev->data.l[0] == 1) _e_kbd_all_show(); + else if (ev->data.l[0] == 2) _e_kbd_all_hide(); + else if (ev->data.l[0] == 3) _e_kbd_all_toggle(); + } + return 1; +} + +static int +_e_kbd_cb_border_add(void *data, int type, void *event) +{ + E_Event_Border_Add *ev; + + ev = event; + // nothing - border hooks do this + return 1; +} + +static int +_e_kbd_cb_border_remove(void *data, int type, void *event) +{ + E_Event_Border_Remove *ev; + E_Kbd *kbd; + + ev = event; + if (ev->border == focused_border) + { + focused_border = NULL; + focused_vkbd_state = 0; + return 1; + } + // if border is in a created kbd - unstore + kbd = _e_kbd_by_border_get(ev->border); + if (!kbd) return 1; + if (kbd->border == ev->border) + { + kbd->border = NULL; + if (kbd->waiting_borders) + { + E_Border *bd; + + bd = kbd->waiting_borders->data; + kbd->waiting_borders = eina_list_remove_list(kbd->waiting_borders, kbd->waiting_borders); + _e_kbd_border_adopt(kbd, bd); + } + if (kbd->visible) + { + kbd->visible = 0; + _e_kbd_border_hide(kbd->border); + kbd->actually_visible = kbd->visible; + e_kbd_show(kbd); + } + _e_kbd_apply_all_job_queue(); + } + else + kbd->waiting_borders = eina_list_remove(kbd->waiting_borders, ev->border); + return 1; +} + +static int +_e_kbd_cb_border_focus_in(void *data, int type, void *event) +{ + E_Event_Border_Focus_In *ev; + + ev = event; + if (_e_kbd_by_border_get(ev->border)) return 1; + // FIXME: if ev->border->client.vkbd.state == 0 then this app doesnt know + // how to request for a virtual keyboard and so we should have a manual + // override + if ((ev->border->need_fullscreen) || (ev->border->fullscreen)) + e_kbd_fullscreen_set(ev->border->zone, 1); + else e_kbd_fullscreen_set(ev->border->zone, 0); + focused_border = ev->border; + focused_vkbd_state = ev->border->client.vkbd.state; + if (ev->border->client.vkbd.state == 0) + return 1; + if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) + { + _e_kbd_all_layout_set(E_KBD_LAYOUT_NONE); + _e_kbd_all_hide(); + return 1; + } + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_ALPHA) + _e_kbd_all_layout_set(E_KBD_LAYOUT_ALPHA); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_NUMERIC) + _e_kbd_all_layout_set(E_KBD_LAYOUT_NUMERIC); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN) + _e_kbd_all_layout_set(E_KBD_LAYOUT_PIN); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER) + _e_kbd_all_layout_set(E_KBD_LAYOUT_PHONE_NUMBER); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX) + _e_kbd_all_layout_set(E_KBD_LAYOUT_HEX); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL) + _e_kbd_all_layout_set(E_KBD_LAYOUT_TERMINAL); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD) + _e_kbd_all_layout_set(E_KBD_LAYOUT_PASSWORD); + else + _e_kbd_all_layout_set(E_KBD_LAYOUT_DEFAULT); + _e_kbd_all_show(); + return 1; +} + +static int +_e_kbd_cb_border_focus_out(void *data, int type, void *event) +{ + E_Event_Border_Focus_Out *ev; + + ev = event; + if (_e_kbd_by_border_get(ev->border)) return 1; + if ((ev->border->need_fullscreen) || (ev->border->fullscreen)) + e_kbd_fullscreen_set(ev->border->zone, 1); + else e_kbd_fullscreen_set(ev->border->zone, 0); + _e_kbd_all_layout_set(E_KBD_LAYOUT_NONE); + _e_kbd_all_hide(); + focused_border = NULL; + focused_vkbd_state = 0; + return 1; +} + +static int +_e_kbd_cb_border_property(void *data, int type, void *event) +{ + E_Event_Border_Property *ev; + + ev = event; + if (_e_kbd_by_border_get(ev->border)) return 1; + if (!ev->border->focused) return 1; + /* nothing happened to vkbd prop - leave everything alone */ + if ((ev->border == focused_border) && + (ev->border->client.vkbd.state == focused_vkbd_state)) + return 1; + focused_vkbd_state = ev->border->client.vkbd.state; + /* app doesn't know what to do - just leave everything as-is */ + if ((ev->border->need_fullscreen) || (ev->border->fullscreen)) + e_kbd_fullscreen_set(ev->border->zone, 1); + else e_kbd_fullscreen_set(ev->border->zone, 0); + if (ev->border->client.vkbd.state == 0) + return 1; + /* app wats kbd off - then kbd off it is */ + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) + _e_kbd_all_hide(); + /* app wants something else than off... */ + else + { + if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_ALPHA) + _e_kbd_all_layout_set(E_KBD_LAYOUT_ALPHA); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_NUMERIC) + _e_kbd_all_layout_set(E_KBD_LAYOUT_NUMERIC); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN) + _e_kbd_all_layout_set(E_KBD_LAYOUT_PIN); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER) + _e_kbd_all_layout_set(E_KBD_LAYOUT_PHONE_NUMBER); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX) + _e_kbd_all_layout_set(E_KBD_LAYOUT_HEX); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL) + _e_kbd_all_layout_set(E_KBD_LAYOUT_TERMINAL); + else if (ev->border->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD) + _e_kbd_all_layout_set(E_KBD_LAYOUT_PASSWORD); + else + _e_kbd_all_layout_set(E_KBD_LAYOUT_DEFAULT); + _e_kbd_all_show(); + } + return 1; +} + +static void +_e_kbd_cb_border_hook_pre_post_fetch(void *data, E_Border *bd) +{ + // check if bd has special kbd properites - if so, store in created kbd + if (!bd->new_client) return; + if (_e_kbd_by_border_get(bd)) return; + if (_e_kbd_border_is_keyboard(bd)) + { + Eina_List *l; + E_Kbd *kbd; + + EINA_LIST_FOREACH(kbds, l, kbd) + { + if (!kbd->border) + { + _e_kbd_border_adopt(kbd, bd); + bd->stolen = 1; + if (bd->remember) + { + if (bd->bordername) + { + eina_stringshare_del(bd->bordername); + bd->bordername = NULL; + bd->client.border.changed = 1; + } + e_remember_unuse(bd->remember); + bd->remember = NULL; + } + eina_stringshare_replace(&bd->bordername, "borderless"); + bd->client.border.changed = 1; + return; + } + else + { + kbd->waiting_borders = eina_list_append(kbd->waiting_borders, bd); + bd->stolen = 1; + if (bd->remember) + { + if (bd->bordername) + { + eina_stringshare_del(bd->bordername); + bd->bordername = NULL; + bd->client.border.changed = 1; + } + e_remember_unuse(bd->remember); + bd->remember = NULL; + } + eina_stringshare_replace(&bd->bordername, "borderless"); + bd->client.border.changed = 1; + return; + } + } + } +} + +static void +_e_kbd_cb_border_hook_post_fetch(void *data, E_Border *bd) +{ + // nothing - all done in _e_kbd_cb_border_hook_pre_post_fetch() + if (!_e_kbd_by_border_get(bd)) return; +} + +static void +_e_kbd_cb_border_hook_post_border_assign(void *data, E_Border *bd) +{ + E_Kbd *kbd; + int pbx, pby, pbw, pbh; + + kbd = _e_kbd_by_border_get(bd); + if (!kbd) return; + + pbx = bd->x; + pby = bd->y; + pbw = bd->w; + pbh = bd->h; + + bd->lock_border = 1; + + bd->lock_client_location = 1; + bd->lock_client_size = 1; + bd->lock_client_desk = 1; + bd->lock_client_sticky = 1; + bd->lock_client_shade = 1; + bd->lock_client_maximize = 1; + + bd->lock_user_location = 1; + bd->lock_user_size = 1; + bd->lock_user_desk = 1; + bd->lock_user_sticky = 1; + bd->lock_user_shade = 1; + bd->lock_user_maximize = 1; + + bd->client.icccm.accepts_focus = 0; + bd->client.icccm.take_focus = 0; + + bd->w = bd->zone->w; + bd->h = bd->h; + bd->x = bd->zone->x; + bd->y = bd->zone->y + bd->zone->h - bd->h; + + bd->client.w = bd->w - bd->client_inset.l - bd->client_inset.r; + bd->client.h = bd->h - bd->client_inset.t - bd->client_inset.b; + + bd->changes.size = 1; + bd->placed = 1; + + if ((pbx != bd->x) || (pby != bd->y) || + (pbw != bd->w) || (pbh != bd->h)) + { + if (bd->internal_ecore_evas) + { + ecore_evas_managed_move(bd->internal_ecore_evas, + bd->x + bd->fx.x + bd->client_inset.l, + bd->y + bd->fx.y + bd->client_inset.t); + } + ecore_x_icccm_move_resize_send(bd->client.win, + bd->x + bd->fx.x + bd->client_inset.l, + bd->y + bd->fx.y + bd->client_inset.t, + bd->client.w, + bd->client.h); + bd->changed = 1; + bd->changes.pos = 1; + bd->changes.size = 1; + } + if (bd == kbd->border) + { + if (kbd->h != bd->h) + { + if (kbd->animator) + { + if (kbd->adjust_end > kbd->adjust_start) + { + kbd->adjust_start -= (bd->h - kbd->h); + kbd->adjust_end -= (bd->h - kbd->h); + } + } + else if (!kbd->actually_visible) + e_border_fx_offset(kbd->border, 0, kbd->border->h); + kbd->h = bd->h; + } + } +} + +static void +_e_kbd_cb_border_hook_end(void *data, E_Border *bd) +{ + E_Kbd *kbd; + + kbd = _e_kbd_by_border_get(bd); + if (!kbd) return; + if (kbd->border == bd) + { + if (!kbd->actually_visible) + _e_kbd_border_hide(kbd->border); + } + else + _e_kbd_border_hide(bd); +} + +static void +_e_kbd_layout_send(E_Kbd *kbd) +{ + Ecore_X_Virtual_Keyboard_State type; + + if ((kbd->actually_visible) && (!kbd->disabled)) + { + type = ECORE_X_VIRTUAL_KEYBOARD_STATE_ON; + if (kbd->layout == E_KBD_LAYOUT_DEFAULT) type = ECORE_X_VIRTUAL_KEYBOARD_STATE_ON; + else if (kbd->layout == E_KBD_LAYOUT_ALPHA) type = ECORE_X_VIRTUAL_KEYBOARD_STATE_ALPHA; + else if (kbd->layout == E_KBD_LAYOUT_NUMERIC) type = ECORE_X_VIRTUAL_KEYBOARD_STATE_NUMERIC; + else if (kbd->layout == E_KBD_LAYOUT_PIN) type = ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN; + else if (kbd->layout == E_KBD_LAYOUT_PHONE_NUMBER) type = ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER; + else if (kbd->layout == E_KBD_LAYOUT_HEX) type = ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX; + else if (kbd->layout == E_KBD_LAYOUT_TERMINAL) type = ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL; + else if (kbd->layout == E_KBD_LAYOUT_PASSWORD) type = ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD; + else if (kbd->layout == E_KBD_LAYOUT_NONE) type = ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF; + } + else + type = ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF; + if (kbd->border) + ecore_x_e_virtual_keyboard_state_send(kbd->border->client.win, type); +} + +// NOTES: +// +// on freerunner these are always there: +// +// /org/freedesktop/Hal/devices/platform_s3c2440_i2c_logicaldev_input +// /org/freedesktop/Hal/devices/platform_neo1973_button_0_logicaldev_input +// +// on desktop (built-in/ps2): +// +// /org/freedesktop/Hal/devices/platform_i8042_i8042_KBD_port_logicaldev_input +// +// on desktop (usb): +// +// /org/freedesktop/Hal/devices/usb_device_46d_c517_noserial_if0_logicaldev_input +// +// this: +// +// /org/freedesktop/Hal/devices/usb_device_a12_1_noserial_if0_bluetooth_hci_bluetooth_hci_logicaldev_input +// +// gets added for a bt kbd - unknown for usb. +// +// chances are i either need a way for a platform config to list devices +// known to be ebuilt-in keyboards but to be ignored when determining +// if a vkbd should be disabled or not... or... i need some other way + +static E_DBus_Connection *_e_kbd_dbus_conn = NULL; +static E_DBus_Signal_Handler *_e_kbd_dbus_handler_dev_add = NULL; +static E_DBus_Signal_Handler *_e_kbd_dbus_handler_dev_del = NULL; +static E_DBus_Signal_Handler *_e_kbd_dbus_handler_dev_chg = NULL; + +static Eina_List *_e_kbd_dbus_keyboards = NULL; +static int _e_kbd_dbus_have_real_keyboard = 0; +static Eina_List *_e_kbd_dbus_real_ignore = NULL; + +static void +_e_kbd_dbus_keyboard_add(const char *udi) +{ + const char *str; + Eina_List *l; + + EINA_LIST_FOREACH(_e_kbd_dbus_keyboards, l, str) + if (!strcmp(str, udi)) return; + + _e_kbd_dbus_keyboards = eina_list_append + (_e_kbd_dbus_keyboards, eina_stringshare_add(udi)); +} + +static void +_e_kbd_dbus_keyboard_del(const char *udi) +{ + Eina_List *l; + char *str; + + EINA_LIST_FOREACH(_e_kbd_dbus_keyboards, l, str) + if (!strcmp(str, udi)) + { + eina_stringshare_del(str); + _e_kbd_dbus_keyboards = eina_list_remove_list(_e_kbd_dbus_keyboards, l); + return; + } +} + +static void +_e_kbd_dbus_keyboard_eval(void) +{ + int have_real = 0; + Eina_List *l, *ll; + const char *g, *gg; + + have_real = eina_list_count(_e_kbd_dbus_keyboards); + EINA_LIST_FOREACH(_e_kbd_dbus_keyboards, l, g) + EINA_LIST_FOREACH(_e_kbd_dbus_real_ignore, ll, gg) + if (e_util_glob_match(g, gg)) + { + have_real--; + break; + } + + if (have_real != _e_kbd_dbus_have_real_keyboard) + { + _e_kbd_dbus_have_real_keyboard = have_real; + if (_e_kbd_dbus_have_real_keyboard) + _e_kbd_all_disable(); + else + _e_kbd_all_enable(); + } +} + +static void +_e_kbd_dbus_cb_dev_input_keyboard(void *user_data, void *reply_data, DBusError *error) +{ + E_Hal_Manager_Find_Device_By_Capability_Return *ret = reply_data; + Eina_List *l; + char *device; + + if (!ret || !ret->strings) return; + + if (dbus_error_is_set(error)) + { + dbus_error_free(error); + return; + } + + EINA_LIST_FOREACH(ret->strings, l, device) + { + _e_kbd_dbus_keyboard_add(device); + _e_kbd_dbus_keyboard_eval(); + } +} + +static void +_e_kbd_dbus_cb_input_keyboard_is(void *user_data, void *reply_data, DBusError *error) +{ + char *udi = user_data; + E_Hal_Device_Query_Capability_Return *ret = reply_data; + + if (dbus_error_is_set(error)) + { + dbus_error_free(error); + goto error; + } + + if (ret && ret->boolean) + { + _e_kbd_dbus_keyboard_add(udi); + _e_kbd_dbus_keyboard_eval(); + } + + error: + free(udi); +} + +static void +_e_kbd_dbus_cb_dev_add(void *data, DBusMessage *msg) +{ + DBusError err; + char *udi; + int ret; + + dbus_error_init(&err); + dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID); + udi = strdup(udi); + ret = e_hal_device_query_capability(_e_kbd_dbus_conn, udi, "input.keyboard", + _e_kbd_dbus_cb_input_keyboard_is, + strdup(udi)); +} + +static void +_e_kbd_dbus_cb_dev_del(void *data, DBusMessage *msg) +{ + DBusError err; + char *udi; + + dbus_error_init(&err); + dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID); + _e_kbd_dbus_keyboard_del(udi); + _e_kbd_dbus_keyboard_eval(); +} + +static void +_e_kbd_dbus_cb_cap_add(void *data, DBusMessage *msg) +{ + DBusError err; + char *udi, *capability; + + dbus_error_init(&err); + dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_STRING, + &capability, DBUS_TYPE_INVALID); + if (!strcmp(capability, "input.keyboard")) + { + _e_kbd_dbus_keyboard_add(udi); + _e_kbd_dbus_keyboard_eval(); + } +} + +static void +_e_kbd_dbus_ignore_keyboards_file_load(const char *file) +{ + char buf[4096]; + FILE *f; + + f = fopen(file, "r"); + if (!f) return; + while (fgets(buf, sizeof(buf), f)) + { + char *p; + int len; + + if (buf[0] == '#') continue; + len = strlen(buf); + if (len > 0) + { + if (buf[len - 1] == '\n') buf[len - 1] = 0; + } + p = buf; + while (isspace(*p)) p++; + if (*p) + _e_kbd_dbus_real_ignore = eina_list_append + (_e_kbd_dbus_real_ignore, eina_stringshare_add(p)); + } + fclose(f); +} + +static void +_e_kbd_dbus_ignore_keyboards_load(void) +{ + char buf[PATH_MAX]; + e_user_dir_concat_static(buf, "keyboards/ignore_built_in_keyboards"); + _e_kbd_dbus_ignore_keyboards_file_load(buf); + snprintf(buf, sizeof(buf), "%s/keyboards/ignore_built_in_keyboards", e_module_dir_get(mod)); + _e_kbd_dbus_ignore_keyboards_file_load(buf); +} + +static void +_e_kbd_dbus_real_kbd_init(void) +{ + _e_kbd_dbus_have_real_keyboard = 0; + + _e_kbd_dbus_ignore_keyboards_load(); + + _e_kbd_dbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM); + if (_e_kbd_dbus_conn) + { + + e_hal_manager_find_device_by_capability(_e_kbd_dbus_conn, "input.keyboard", + _e_kbd_dbus_cb_dev_input_keyboard, NULL); + + _e_kbd_dbus_handler_dev_add = + e_dbus_signal_handler_add(_e_kbd_dbus_conn, "org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "DeviceAdded", _e_kbd_dbus_cb_dev_add, NULL); + _e_kbd_dbus_handler_dev_del = + e_dbus_signal_handler_add(_e_kbd_dbus_conn, "org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "DeviceRemoved", _e_kbd_dbus_cb_dev_del, NULL); + _e_kbd_dbus_handler_dev_chg = + e_dbus_signal_handler_add(_e_kbd_dbus_conn, "org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "NewCapability", _e_kbd_dbus_cb_cap_add, NULL); + } +} + +static void +_e_kbd_dbus_real_kbd_shutdown(void) +{ + char *str; + + if (_e_kbd_dbus_conn) + { + e_dbus_signal_handler_del(_e_kbd_dbus_conn, _e_kbd_dbus_handler_dev_add); + e_dbus_signal_handler_del(_e_kbd_dbus_conn, _e_kbd_dbus_handler_dev_del); + e_dbus_signal_handler_del(_e_kbd_dbus_conn, _e_kbd_dbus_handler_dev_chg); + } + EINA_LIST_FREE(_e_kbd_dbus_real_ignore, str) + eina_stringshare_del(str); + EINA_LIST_FREE(_e_kbd_dbus_keyboards, str) + eina_stringshare_del(str); + _e_kbd_dbus_have_real_keyboard = 0; +} + +EAPI int +e_kbd_init(E_Module *m) +{ + mod = m; + focused_border = NULL; + focused_vkbd_state = 0; + atom_mb_im_invoker_command = ecore_x_atom_get("_MB_IM_INVOKER_COMMAND"); + atom_mtp_im_invoker_command = ecore_x_atom_get("_MTP_IM_INVOKER_COMMAND"); + handlers = eina_list_append(handlers, + ecore_event_handler_add + (ECORE_X_EVENT_CLIENT_MESSAGE, + _e_kbd_cb_client_message, NULL)); + handlers = eina_list_append(handlers, + ecore_event_handler_add + (E_EVENT_BORDER_ADD, + _e_kbd_cb_border_add, NULL)); + handlers = eina_list_append(handlers, + ecore_event_handler_add + (E_EVENT_BORDER_REMOVE, + _e_kbd_cb_border_remove, NULL)); + handlers = eina_list_append(handlers, + ecore_event_handler_add + (E_EVENT_BORDER_FOCUS_IN, + _e_kbd_cb_border_focus_in, NULL)); + handlers = eina_list_append(handlers, + ecore_event_handler_add + (E_EVENT_BORDER_FOCUS_OUT, + _e_kbd_cb_border_focus_out, NULL)); + handlers = eina_list_append(handlers, + ecore_event_handler_add + (E_EVENT_BORDER_PROPERTY, + _e_kbd_cb_border_property, NULL)); + border_hooks = eina_list_append(border_hooks, + e_border_hook_add + (E_BORDER_HOOK_EVAL_PRE_POST_FETCH, + _e_kbd_cb_border_hook_pre_post_fetch, + NULL)); + border_hooks = eina_list_append(border_hooks, + e_border_hook_add + (E_BORDER_HOOK_EVAL_POST_FETCH, + _e_kbd_cb_border_hook_post_fetch, + NULL)); + border_hooks = eina_list_append(border_hooks, + e_border_hook_add + (E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, + _e_kbd_cb_border_hook_post_border_assign, + NULL)); + border_hooks = eina_list_append(border_hooks, + e_border_hook_add + (E_BORDER_HOOK_EVAL_END, + _e_kbd_cb_border_hook_end, + NULL)); + _e_kbd_dbus_real_kbd_init(); + return 1; +} + +EAPI int +e_kbd_shutdown(void) +{ + E_Border_Hook *bh; + Ecore_Event_Handler *handle; + + _e_kbd_apply_all_job_queue_end(); + _e_kbd_dbus_real_kbd_shutdown(); + EINA_LIST_FREE(border_hooks, bh) + e_border_hook_del(bh); + EINA_LIST_FREE(handlers, handle) + ecore_event_handler_del(handle); + focused_border = NULL; + focused_vkbd_state = 0; + mod = NULL; + return 1; +} + +EAPI E_Kbd * +e_kbd_new(E_Zone *zone, const char *themedir, const char *syskbds, const char *sysdicts) +{ + E_Kbd *kbd; + + kbd = E_OBJECT_ALLOC(E_Kbd, E_KBD_TYPE, _e_kbd_free); + if (!kbd) return NULL; + kbds = eina_list_append(kbds, kbd); + kbd->layout = ECORE_X_VIRTUAL_KEYBOARD_STATE_ON; + return kbd; +} + +EAPI void +e_kbd_enable(E_Kbd *kbd) +{ + if (!kbd->disabled) return; + kbd->disabled = 0; + if (kbd->visible) + { + kbd->visible = 0; + e_kbd_show(kbd); + } +} + +EAPI void +e_kbd_disable(E_Kbd *kbd) +{ + if (kbd->disabled) return; + if (kbd->visible) e_kbd_hide(kbd); + kbd->disabled = 1; +} + +EAPI void +e_kbd_show(E_Kbd *kbd) +{ + if (kbd->delay_hide) + { + ecore_timer_del(kbd->delay_hide); + kbd->delay_hide = NULL; + } + if (kbd->visible) return; + kbd->visible = 1; + if (kbd->disabled) return; + kbd->actually_visible = kbd->visible; + _e_kbd_layout_send(kbd); +#if 0 + if (illume_cfg->sliding.kbd.duration <= 0) + { + if (kbd->border) + { + e_border_fx_offset(kbd->border, 0, 0); + _e_kbd_border_show(kbd, kbd->border); + } + kbd->actually_visible = kbd->visible; + _e_kbd_apply_all_job_queue(); + } + else + { + if (kbd->border) + { + e_border_fx_offset(kbd->border, 0, kbd->border->h - kbd->adjust); + _e_kbd_border_show(kbd, kbd->border); + } + _e_kbd_slide(kbd, 1, (double)illume_cfg->sliding.kbd.duration / 1000.0); + } +#endif +} + +EAPI void +e_kbd_layout_set(E_Kbd *kbd, E_Kbd_Layout layout) +{ + kbd->layout = layout; + _e_kbd_layout_send(kbd); +} + +EAPI void +e_kbd_hide(E_Kbd *kbd) +{ + if (!kbd->visible) return; + kbd->visible = 0; + if (!kbd->delay_hide) + kbd->delay_hide = ecore_timer_add(0.2, _e_kbd_cb_delayed_hide, kbd); +} + +EAPI void +e_kbd_safe_app_region_get(E_Zone *zone, int *x, int *y, int *w, int *h) +{ + Eina_List *l; + + if (x) *x = zone->x; + if (y) *y = zone->y; + if (w) *w = zone->w; + if (h) *h = zone->h; + for (l = kbds; l; l = l->next) + { + E_Kbd *kbd; + + kbd = l->data; + if ((kbd->border) && (kbd->border->zone == zone)) + { + if ((kbd->visible) && (!kbd->animator) && (!kbd->disabled)) + /* out finished, not disabled */ + { + if (h) + { + *h -= kbd->border->h; + if (*h < 0) *h = 0; + } + } + return; + } + } +} + +EAPI void +e_kbd_fullscreen_set(E_Zone *zone, int fullscreen) +{ + Eina_List *l; + E_Kbd *kbd; + + EINA_LIST_FOREACH(kbds, l, kbd) + if ((!!fullscreen) != kbd->fullscreen) + { + kbd->fullscreen = fullscreen; + if (kbd->fullscreen) + e_border_layer_set(kbd->border, 250); + else + e_border_layer_set(kbd->border, 100); + } +} + +#endif diff --git a/src/modules/illume2/e_kbd.h b/src/modules/illume2/e_kbd.h new file mode 100644 index 000000000..cac056934 --- /dev/null +++ b/src/modules/illume2/e_kbd.h @@ -0,0 +1,53 @@ +#ifndef E_KBD_H +#define E_KBD_H + +typedef struct _E_Kbd E_Kbd; + +#define E_KBD_TYPE 0xE1b0988 + +typedef enum _E_Kbd_Layout +{ + E_KBD_LAYOUT_NONE, + E_KBD_LAYOUT_DEFAULT, + E_KBD_LAYOUT_ALPHA, + E_KBD_LAYOUT_NUMERIC, + E_KBD_LAYOUT_PIN, + E_KBD_LAYOUT_PHONE_NUMBER, + E_KBD_LAYOUT_HEX, + E_KBD_LAYOUT_TERMINAL, + E_KBD_LAYOUT_PASSWORD +} E_Kbd_Layout; + +struct _E_Kbd +{ + E_Object e_obj_inherit; + E_Win *win; + E_Border *border; + Ecore_Timer *delay_hide; + Ecore_Animator *animator; + Eina_List *waiting_borders; + E_Kbd_Layout layout; + double start, len; + + int h; + int adjust_start, adjust, adjust_end; + + unsigned char visible : 1; + unsigned char actually_visible : 1; + unsigned char disabled : 1; // if we have a real kbd plugged in + unsigned char fullscreen : 1; +}; + +EAPI int e_kbd_init(E_Module *m); +EAPI int e_kbd_shutdown(void); + +EAPI E_Kbd *e_kbd_new(E_Zone *zone, const char *themedir, const char *syskbds, const char *sysdicts); +EAPI void e_kbd_enable(E_Kbd *kbd); +EAPI void e_kbd_disable(E_Kbd *kbd); +EAPI void e_kbd_show(E_Kbd *kbd); +EAPI void e_kbd_layout_set(E_Kbd *kbd, E_Kbd_Layout layout); +EAPI void e_kbd_hide(E_Kbd *kbd); +EAPI void e_kbd_safe_app_region_get(E_Zone *zone, int *x, int *y, int *w, int *h); +EAPI void e_kbd_fullscreen_set(E_Zone *zone, int fullscreen); + +#endif diff --git a/src/modules/illume2/e_mod_layout.c b/src/modules/illume2/e_mod_layout.c new file mode 100644 index 000000000..dbd37e1db --- /dev/null +++ b/src/modules/illume2/e_mod_layout.c @@ -0,0 +1,471 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_layout.h" +#include "e_mod_layout_illume.h" + +// internal calls +static void _e_mod_layout_cb_hook_container_layout(void *data, E_Container *con); +static void _e_mod_layout_cb_hook_post_fetch(void *data, E_Border *bd); +static void _e_mod_layout_cb_hook_post_border_assign(void *data, E_Border *bd); +static void _e_mod_layout_cb_hook_end(void *data, E_Border *bd); +static int _cb_event_border_add(void *data, int type, void *event); +static int _cb_event_border_remove(void *data, int type, void *event); +static int _cb_event_border_focus_in(void *data, int type, void *event); +static int _cb_event_border_focus_out(void *data, int type, void *event); +static int _cb_event_border_show(void *data, int type, void *event); +static int _cb_event_border_hide(void *data, int type, void *event); +static int _cb_event_zone_move_resize(void *data, int type, void *event); + +// state +static E_Border_Hook *hook1 = NULL; +static E_Border_Hook *hook2 = NULL; +static E_Border_Hook *hook3 = NULL; +static E_Border_Hook *hook4 = NULL; +static Eina_List *handlers = NULL; + +void +e_mod_layout_init(E_Module *m) +{ + Eina_List *l; + E_Manager *man; + + hook1 = e_border_hook_add(E_BORDER_HOOK_EVAL_POST_FETCH, + _e_mod_layout_cb_hook_post_fetch, NULL); + hook2 = e_border_hook_add(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, + _e_mod_layout_cb_hook_post_border_assign, NULL); + hook3 = e_border_hook_add(E_BORDER_HOOK_EVAL_END, + _e_mod_layout_cb_hook_end, NULL); + hook4 = e_border_hook_add(E_BORDER_HOOK_CONTAINER_LAYOUT, + _e_mod_layout_cb_hook_container_layout, NULL); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (E_EVENT_BORDER_ADD, _cb_event_border_add, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (E_EVENT_BORDER_REMOVE, _cb_event_border_remove, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (E_EVENT_BORDER_FOCUS_IN, _cb_event_border_focus_in, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (E_EVENT_BORDER_FOCUS_OUT, _cb_event_border_focus_out, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (E_EVENT_BORDER_SHOW, _cb_event_border_show, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (E_EVENT_BORDER_HIDE, _cb_event_border_hide, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (E_EVENT_ZONE_MOVE_RESIZE, _cb_event_zone_move_resize, NULL)); + + illume_layout_illume_init(); +} + +void +e_mod_layout_shutdown(void) +{ + Ecore_Event_Handler *handle; + + illume_layout_illume_shutdown(); + + if (hook1) e_border_hook_del(hook1); + if (hook2) e_border_hook_del(hook2); + if (hook3) e_border_hook_del(hook3); + if (hook4) e_border_hook_del(hook4); + hook1 = NULL; + hook2 = NULL; + hook3 = NULL; + hook4 = NULL; + EINA_LIST_FREE(handlers, handle) ecore_event_handler_del(handle); +} + +////////////////////////////////////////////////////////////////////////////// +// :: Convenience routines to make it easy to write layout logic code :: + +static Eina_List *modes = NULL; +static const Illume_Layout_Mode *mode = NULL; + +void +illume_layout_mode_register(const Illume_Layout_Mode *laymode) +{ + if (!modes) mode = laymode; + modes = eina_list_append(modes, laymode); +} + +void +illume_layout_mode_unregister(const Illume_Layout_Mode *laymode) +{ + if (mode == laymode) mode = NULL; + modes = eina_list_remove(modes, laymode); +} + +////////////////////////////////////////////////////////////////////////////// +// :: Convenience routines to make it easy to write layout logic code :: + +// activate a window - meant for main app and home app windows +void +illume_border_activate(E_Border *bd) +{ + e_desk_show(bd->desk); + e_border_uniconify(bd); + e_border_raise(bd); + e_border_show(bd); + e_border_focus_set(bd, 1, 1); +} + +// activate a window that isnt meant to get the focus - like panels, kbd etc. +void +illume_border_show(E_Border *bd) +{ + e_desk_show(bd->desk); + e_border_uniconify(bd); + e_border_raise(bd); + e_border_show(bd); +} + +// get a window away from being visile (but maintain it) +void +illume_border_deactivate(E_Border *bd) +{ + e_border_iconify(bd); +} + +// get window info - is this one a dialog? +Eina_Bool +illume_border_is_dialog(E_Border *bd) +{ + int isdialog = 0, i; + + if (bd->client.icccm.transient_for != 0) + isdialog = 1; + if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG) + { + isdialog = 1; + if (bd->client.netwm.extra_types) + { + for (i = 0; i < bd->client.netwm.extra_types_num; i++) + { + if (bd->client.netwm.extra_types[i] == + ECORE_X_WINDOW_TYPE_UNKNOWN) continue; + if ((bd->client.netwm.extra_types[i] != + ECORE_X_WINDOW_TYPE_DIALOG) && + (bd->client.netwm.extra_types[i] != + ECORE_X_WINDOW_TYPE_SPLASH)) + { + return 0; + } + } + } + } + return isdialog; +} + +// get window info - is this a vkbd window +Eina_Bool +illume_border_is_keyboard(E_Border *bd) +{ + if ((bd->client.vkbd.vkbd) || /* explicit hint that its a virtual keyboard */ + /* legacy */ + ( /* trap the matchbox qwerty and multitap kbd's */ + (((bd->client.icccm.title) && (!strcmp(bd->client.icccm.title, "Keyboard"))) || + ((bd->client.icccm.name) && ((!strcmp(bd->client.icccm.name, "multitap-pad"))))) + && (bd->client.netwm.state.skip_taskbar) + && (bd->client.netwm.state.skip_pager) + ) + ) + return 1; + return 0; +} + +// get window info - is it a bottom app panel window (eg qtopia softmenu) +Eina_Bool +illume_border_is_bottom_panel(E_Border *bd) +{ + if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK) || + (bd->client.qtopia.soft_menu)) + return 1; + return 0; +} + +// get window info - is it a top shelf window +Eina_Bool +illume_border_is_top_shelf(E_Border *bd) +{ + if ((bd->client.icccm.name) && + (strstr(bd->client.icccm.name, "xfce4-panel"))) + return 1; + // FIXME: detect + return 0; +} + +// get window info - is it a mini app window +Eina_Bool +illume_border_is_mini_app(E_Border *bd) +{ + // FIXME: detect + return 0; +} + +// get window info - is it a notification window +Eina_Bool +illume_border_is_notification(E_Border *bd) +{ + // FIXME: detect + return 0; +} + +// get window info - is it a home window +Eina_Bool +illume_border_is_home(E_Border *bd) +{ + // FIXME: detect + return 0; +} + +// get window info - is it side pane (left) window +Eina_Bool +illume_border_is_side_pane_left(E_Border *bd) +{ + // FIXME: detect + return 0; +} + +// get window info - is it side pane (right) window +Eina_Bool +illume_border_is_side_pane_right(E_Border *bd) +{ + // FIXME: detect + return 0; +} + +// get window info - is it overlay window (eg expose display of windows etc.) +Eina_Bool +illume_border_is_overlay(E_Border *bd) +{ + // FIXME: detect + return 0; +} + +void +illume_border_slide_to(E_Border *bd, int x, int y, Illume_Anim_Class aclass) +{ + // FIXME: do + // 1. if an existing slide exists, use is current offset x,y as current border pos, new x,y as new pos and start slide again +} + +void +illume_border_min_get(E_Border *bd, int *mw, int *mh) +{ + if (mw) + { + if (bd->client.icccm.base_w > bd->client.icccm.min_w) + *mw = bd->client.icccm.base_w; + else + *mw = bd->client.icccm.min_w; + } + if (mh) + { + if (bd->client.icccm.base_w > bd->client.icccm.min_h) + *mh = bd->client.icccm.base_h; + else + *mh = bd->client.icccm.min_h; + } +} + +static void +_e_mod_layout_cb_hook_container_layout(void *data, E_Container *con) +{ + Eina_List *l; + E_Zone *zone; + + EINA_LIST_FOREACH(con->zones, l, zone) + { + if ((mode) && (mode->funcs.zone_layout)) + mode->funcs.zone_layout(zone); + } +} + +static void +_e_mod_layout_cb_hook_post_fetch(void *data, E_Border *bd) +{ + if (bd->stolen) return; + if (bd->new_client) + { + if (bd->remember) + { + if (bd->bordername) + { + eina_stringshare_del(bd->bordername); + bd->bordername = NULL; + bd->client.border.changed = 1; + } + e_remember_unuse(bd->remember); + bd->remember = NULL; + } + eina_stringshare_replace(&bd->bordername, "borderless"); + bd->client.border.changed = 1; + bd->client.e.state.centered = 0; + } +} + +static void +_e_mod_layout_cb_hook_post_border_assign(void *data, E_Border *bd) +{ + int zx, zy, zw, zh, pbx, pby, pbw, pbh; + + if (bd->stolen) return; + + pbx = bd->x; pby = bd->y; pbw = bd->w; pbh = bd->h; + zx = bd->zone->x; zy = bd->zone->y; zw = bd->zone->w; zh = bd->zone->h; + + bd->placed = 1; + bd->client.e.state.centered = 0; + if (!((bd->need_fullscreen) || (bd->fullscreen))) + { +/* + bd->x = zx; bd->y = zy; bd->w = zw; bd->h = zh; + bd->client.w = bd->w; bd->client.h = bd->h; + if ((pbx != bd->x) || (pby != bd->y) || + (pbw != bd->w) || (pbh != bd->h)) + { + bd->changed = 1; + bd->changes.pos = 1; + bd->changes.size = 1; + } + */ + } + else + { +/* + bd->x = zx; bd->y = zy; bd->w = zw; bd->h = zh; + bd->client.w = bd->w; bd->client.h = bd->h; + if ((pbx != bd->x) || (pby != bd->y) || + (pbw != bd->w) || (pbh != bd->h)) + { + if (bd->internal_ecore_evas) + ecore_evas_managed_move(bd->internal_ecore_evas, + bd->x + bd->fx.x + bd->client_inset.l, + bd->y + bd->fx.y + bd->client_inset.t); + ecore_x_icccm_move_resize_send + (bd->client.win, + bd->x + bd->fx.x + bd->client_inset.l, + bd->y + bd->fx.y + bd->client_inset.t, + bd->client.w, + bd->client.h); + bd->changed = 1; + bd->changes.pos = 1; + bd->changes.size = 1; + } + */ + } + if (bd->remember) + { + e_remember_unuse(bd->remember); + bd->remember = NULL; + } + bd->lock_border = 1; + + bd->lock_client_location = 1; + bd->lock_client_size = 1; + bd->lock_client_desk = 1; + bd->lock_client_sticky = 1; + bd->lock_client_shade = 1; + bd->lock_client_maximize = 1; + + bd->lock_user_location = 1; + bd->lock_user_size = 1; + bd->lock_user_sticky = 1; +} + +static void +_e_mod_layout_cb_hook_end(void *data, E_Border *bd) +{ +} + +static int +_cb_event_border_add(void *data, int type, void *event) +{ + E_Event_Border_Add *ev; + E_Border *bd; + + ev = event; + if (ev->border->stolen) return 1; + bd = ev->border; + if ((mode) && (mode->funcs.border_add)) + mode->funcs.border_add(bd); + return 1; +} + +static int +_cb_event_border_remove(void *data, int type, void *event) +{ + E_Event_Border_Remove *ev; + E_Border *bd; + + ev = event; + if (ev->border->stolen) return 1; + bd = ev->border; + if ((mode) && (mode->funcs.border_del)) + mode->funcs.border_del(bd); + return 1; +} + +static int +_cb_event_border_focus_in(void *data, int type, void *event) +{ + E_Event_Border_Focus_In *ev; + E_Border *bd; + + ev = event; + if (ev->border->stolen) return 1; + bd = ev->border; + if ((mode) && (mode->funcs.border_focus_in)) + mode->funcs.border_focus_in(bd); + return 1; +} + +static int +_cb_event_border_focus_out(void *data, int type, void *event) +{ + E_Event_Border_Focus_Out *ev; + E_Border *bd; + + ev = event; + if (ev->border->stolen) return 1; + bd = ev->border; + if ((mode) && (mode->funcs.border_focus_out)) + mode->funcs.border_focus_out(bd); + return 1; +} + +static int +_cb_event_border_show(void *data, int type, void *event) +{ + E_Event_Border_Show *ev; + + ev = event; + if (ev->border->stolen) return 1; + return 1; +} + +static int +_cb_event_border_hide(void *data, int type, void *event) +{ + E_Event_Border_Hide *ev; + + ev = event; + if (ev->border->stolen) return 1; + return 1; +} + +static int +_cb_event_zone_move_resize(void *data, int type, void *event) +{ + E_Event_Zone_Move_Resize *ev; + + ev = event; + if ((mode) && (mode->funcs.zone_move_resize)) + mode->funcs.zone_move_resize(ev->zone); + return 1; +} diff --git a/src/modules/illume2/e_mod_layout.h b/src/modules/illume2/e_mod_layout.h new file mode 100644 index 000000000..7131bc696 --- /dev/null +++ b/src/modules/illume2/e_mod_layout.h @@ -0,0 +1,55 @@ +#ifndef E_MOD_LAYOUT_H +#define E_MOD_LAYOUT_H + +void e_mod_layout_init(E_Module *m); +void e_mod_layout_shutdown(void); + +typedef enum _Illume_Anim_Class +{ + ILLUME_ANIM_APP, + ILLUME_ANIM_KEYBOARD, + ILLUME_ANIM_SHELF, + ILLUME_ANIM_DIALOG, + ILLUME_ANIM_OTHER +} Illume_Anim_Class; + +typedef struct _Illume_Layout_Mode Illume_Layout_Mode; + +struct _Illume_Layout_Mode +{ + const char *name; + const char *label; + // may need more things later, but name + label will do for now + struct { + // --- + void (*border_add) (E_Border *bd); + void (*border_del) (E_Border *bd); + void (*border_focus_in) (E_Border *bd); + void (*border_focus_out) (E_Border *bd); + // --- + void (*zone_layout) (E_Zone *zone); + void (*zone_move_resize) (E_Zone *zone); + // --- add more below (activate callback, and more) + } funcs; +}; + +void illume_layout_mode_register(const Illume_Layout_Mode *laymode); +void illume_layout_mode_unregister(const Illume_Layout_Mode *laymode); + +void illume_border_activate(E_Border *bd); +void illume_border_show(E_Border *bd); +void illume_border_deactivate(E_Border *bd); +Eina_Bool illume_border_is_dialog(E_Border *bd); +Eina_Bool illume_border_is_keyboard(E_Border *bd); +Eina_Bool illume_border_is_bottom_panel(E_Border *bd); +Eina_Bool illume_border_is_top_shelf(E_Border *bd); +Eina_Bool illume_border_is_mini_app(E_Border *bd); +Eina_Bool illume_border_is_notification(E_Border *bd); +Eina_Bool illume_border_is_home(E_Border *bd); +Eina_Bool illume_border_is_side_pane_left(E_Border *bd); +Eina_Bool illume_border_is_side_pane_right(E_Border *bd); +Eina_Bool illume_border_is_overlay(E_Border *bd); +void illume_border_slide_to(E_Border *bd, int x, int y, Illume_Anim_Class aclass); +void illume_border_min_get(E_Border *bd, int *mw, int *mh); + +#endif diff --git a/src/modules/illume2/e_mod_layout_illume.c b/src/modules/illume2/e_mod_layout_illume.c new file mode 100644 index 000000000..07af4c311 --- /dev/null +++ b/src/modules/illume2/e_mod_layout_illume.c @@ -0,0 +1,139 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_layout.h" +#include "e_mod_layout_illume.h" + +static void +_border_add(E_Border *bd) +{ // handle a border being added +} + +static void +_border_del(E_Border *bd) +{ // handle a border being deleted +} + +static void +_border_focus_in(E_Border *bd) +{ // do something if focus enters a window +} + +static void +_border_focus_out(E_Border *bd) +{ // do something if the rfocus exits a window +} + +static void +_zone_layout(E_Zone *z) +{ // borders are in re-layout stage. this is where you move/resize them + Eina_List *l, *borders; + E_Border *bd; + + // data for state + int shelfsize = 0; + int kbdsize = 0; + int panelsize = 0; + + // phase 1. loop through borders to figure out sizes of things + borders = e_border_client_list(); + EINA_LIST_FOREACH(borders, l, bd) + { + int mw, mh; + + if (bd->zone != z) continue; + if (bd->new_client) continue; + if (!bd->visible) continue; + + illume_border_min_get(bd, &mw, &mh); + if (illume_border_is_top_shelf(bd)) + { + if (shelfsize < mh) shelfsize = mh; + } + else if (illume_border_is_bottom_panel(bd)) + { + if (panelsize < mh) panelsize = mh; + } + else if (illume_border_is_keyboard(bd)) + { + if (kbdsize < mh) kbdsize = mh; + } + } + + // actually apply the sizing, positioning and layering too + borders = e_border_client_list(); + EINA_LIST_FOREACH(borders, l, bd) + { + int mw, mh; + + if (bd->zone != z) continue; + if (bd->new_client) continue; + if (!bd->visible) continue; + + illume_border_min_get(bd, &mw, &mh); + if (illume_border_is_top_shelf(bd)) + { + e_border_move_resize(bd, z->x, z->y, z->w, shelfsize); + if (bd->layer != 200) e_border_layer_set(bd, 200); + } + else if (illume_border_is_bottom_panel(bd)) + { + e_border_move_resize(bd, z->x, z->y + z->h - panelsize, z->w, panelsize); + if (bd->layer != 100) e_border_layer_set(bd, 100); + } + else if (illume_border_is_keyboard(bd)) + { + e_border_move_resize(bd, z->x, z->y + z->h - kbdsize, z->w, kbdsize); + if (bd->layer != 150) e_border_layer_set(bd, 150); + } + else if (illume_border_is_home(bd)) + { + e_border_move_resize(bd, z->x, z->y, z->w, z->h); + if (bd->layer != 50) e_border_layer_set(bd, 50); + } + else if (illume_border_is_dialog(bd)) + { + if (mh > z->h) mh = z->h; + e_border_move_resize(bd, z->x, z->y + ((z->h - mh) / 2), z->w, mh); + if (bd->layer != 120) e_border_layer_set(bd, 120); + } + else + { + e_border_move_resize(bd, z->x, z->y + shelfsize, z->w, z->h - shelfsize - kbdsize); + if (bd->layer != 100) e_border_layer_set(bd, 100); + } + } +} + +static void +_zone_move_resize(E_Zone *z) +{ // the zone was moved or resized - re-configure all windows in this zone + _zone_layout(z); +} + +////////////////////////////////////////////////////////////////////////////// +const Illume_Layout_Mode laymode = +{ + "illume", "Illume", // FIXME: translatable? + // --- + _border_add, + _border_del, + _border_focus_in, + _border_focus_out, + // --- + _zone_layout, + _zone_move_resize, + // --- +}; +////////////////////////////////////////////////////////////////////////////// +void +illume_layout_illume_init(void) +{ + illume_layout_mode_register(&laymode); +} +////////////////////////////////////////////////////////////////////////////// +void +illume_layout_illume_shutdown(void) +{ + illume_layout_mode_unregister(&laymode); +} +////////////////////////////////////////////////////////////////////////////// diff --git a/src/modules/illume2/e_mod_layout_illume.h b/src/modules/illume2/e_mod_layout_illume.h new file mode 100644 index 000000000..80249a56c --- /dev/null +++ b/src/modules/illume2/e_mod_layout_illume.h @@ -0,0 +1,7 @@ +#ifndef E_MOD_LAYOUT_ILLUME_H +#define E_MOD_LAYOUT_ILLUME_H + +void illume_layout_illume_init(void); +void illume_layout_illume_shutdown(void); + +#endif diff --git a/src/modules/illume2/e_mod_main.c b/src/modules/illume2/e_mod_main.c new file mode 100644 index 000000000..7975f6b89 --- /dev/null +++ b/src/modules/illume2/e_mod_main.c @@ -0,0 +1,41 @@ +#include "e.h" + +#include "e_kbd.h" +#include "e_mod_main.h" +#include "e_mod_layout.h" + +/* this is needed to advertise a label for the module IN the code (not just + * the .desktop file) but more specifically the api version it was compiled + * for so E can skip modules that are compiled for an incorrect API version + * safely) */ +EAPI E_Module_Api e_modapi = +{ + E_MODULE_API_VERSION, "Illume2" +}; + +/* called first thing when E inits the module */ +EAPI void * +e_modapi_init(E_Module *m) +{ + /* set up the virtual keyboard */ +// e_kbd_init(m); + e_mod_layout_init(m); + return m; /* return NULL on failure, anything else on success. the pointer + * returned will be set as m->data for convenience tracking */ +} + +/* called on module shutdown - should clean up EVERYTHING or we leak */ +EAPI int +e_modapi_shutdown(E_Module *m) +{ + e_mod_layout_shutdown(); +// e_kbd_shutdown(); + return 1; /* 1 for success, 0 for failure */ +} + +/* called by E when it thinks this module shoudl go save any config it has */ +EAPI int +e_modapi_save(E_Module *m) +{ + return 1; /* 1 for success, 0 for failure */ +} diff --git a/src/modules/illume2/e_mod_main.h b/src/modules/illume2/e_mod_main.h new file mode 100644 index 000000000..f884cc0aa --- /dev/null +++ b/src/modules/illume2/e_mod_main.h @@ -0,0 +1,10 @@ +#ifndef E_MOD_MAIN_H +#define E_MOD_MAIN_H + +EAPI extern E_Module_Api e_modapi; + +EAPI void *e_modapi_init(E_Module *m); +EAPI int e_modapi_shutdown(E_Module *m); +EAPI int e_modapi_save(E_Module *m); + +#endif diff --git a/src/modules/illume2/module.desktop.in b/src/modules/illume2/module.desktop.in new file mode 100644 index 000000000..bbacd7507 --- /dev/null +++ b/src/modules/illume2/module.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Link +Name=Illume2 +Icon=e-module-illume2 +X-Enlightenment-ModuleType=system +Comment=Illume2 for Embedded diff --git a/x-ui.sh b/x-ui.sh index b184a8d16..4475df359 100755 --- a/x-ui.sh +++ b/x-ui.sh @@ -1,22 +1,27 @@ #!/bin/sh -#Xephyr :1 -noreset -ac -br -dpi 284 -screen 480x640x16 & -Xephyr :1 -noreset -ac -br -dpi 284 -screen 480x640 & -#Xephyr :1 -noreset -ac -br -dpi 284 -screen 640x480x16 & -#Xephyr :1 -noreset -ac -br -dpi 284 -screen 640x480 & -#Xephyr :1 -noreset -ac -br -dpi 181 -screen 320x320x16 & -#Xephyr :1 -noreset -ac -br -dpi 181 -screen 320x320 & -#Xephyr :1 -noreset -ac -br -dpi 186 -screen 272x480x16 & -#Xephyr :1 -noreset -ac -br -dpi 186 -screen 272x480 & #Xephyr :1 -noreset -ac -br -dpi 142 -screen 240x320x16 & +#Xephyr :1 -noreset -ac -br -dpi 142 -screen 320x240x16 & +#Xephyr :1 -noreset -ac -br -dpi 186 -screen 272x480x16 & +#Xephyr :1 -noreset -ac -br -dpi 186 -screen 480x272x16 & +#Xephyr :1 -noreset -ac -br -dpi 181 -screen 320x320x16 & +Xephyr :1 -noreset -ac -br -dpi 183 -screen 320x480x16 & +#Xephyr :1 -noreset -ac -br -dpi 183 -screen 480x320x16 & +#Xephyr :1 -noreset -ac -br -dpi 183 -screen 480x800x16 & +#Xephyr :1 -noreset -ac -br -dpi 183 -screen 800x480x16 & +#Xephyr :1 -noreset -ac -br -dpi 284 -screen 480x640x16 & +#Xephyr :1 -noreset -ac -br -dpi 284 -screen 640x480x16 & + +#Xephyr :1 -noreset -ac -br -dpi 284 -screen 480x640 & +#Xephyr :1 -noreset -ac -br -dpi 284 -screen 640x480 & +#Xephyr :1 -noreset -ac -br -dpi 181 -screen 320x320 & +#Xephyr :1 -noreset -ac -br -dpi 186 -screen 272x480 & #Xephyr :1 -noreset -ac -br -dpi 142 -screen 240x320 & sleep 1 export DISPLAY=:1 -unset E_RESTART E_START E_IPC_SOCKET E_START_TIME -#E_CONF_PROFILE=default ltrace enlightenment_start -#E_CONF_PROFILE=default enlightenment_start +unset E_RESTART E_START E_IPC_SOCKET E_START_TIME E_CONF_PROFILE enlightenment_start \ -no-precache \ -i-really-know-what-i-am-doing-and-accept-full-responsibility-for-it \ --profile illume +-profile illume2