From cfaf0c12b575a8e4f252ca44edb8f4d1fc20622e Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 5 Jul 2012 15:01:58 +0000 Subject: [PATCH] brace yourselves: E WINDOW PHYSICS MODULE! if you have ephysics installed, a new module 'Physics' will be available under Look which provides some fun physics effects on windows such as: *velocity based on drag direction/speed *collisions *gravity note that the edges of the screen are considered boundaries, and so windows will bounce off or get stuck in them; you will have to drag a window out if it gets stuck because I've disabled physics effects in edge areas to both 1) prevent windows from sneaking past the screen limits and flying off into space 2) actually getting stuck to the point that you can't get them out help needed! SVN revision: 73365 --- configure.ac | 34 + src/modules/Makefile.am | 4 + src/modules/physics/Makefile.am | 36 + src/modules/physics/e-module-physics.edj | Bin 0 -> 11935 bytes src/modules/physics/e_mod_config.c | 142 ++++ src/modules/physics/e_mod_config.h | 8 + src/modules/physics/e_mod_main.c | 101 +++ src/modules/physics/e_mod_main.h | 31 + src/modules/physics/e_mod_physics.c | 815 +++++++++++++++++++++ src/modules/physics/e_mod_physics.h | 14 + src/modules/physics/e_mod_physics_cfdata.c | 43 ++ src/modules/physics/e_mod_physics_cfdata.h | 19 + src/modules/physics/module.desktop.in | 6 + 13 files changed, 1253 insertions(+) create mode 100644 src/modules/physics/Makefile.am create mode 100644 src/modules/physics/e-module-physics.edj create mode 100644 src/modules/physics/e_mod_config.c create mode 100644 src/modules/physics/e_mod_config.h create mode 100644 src/modules/physics/e_mod_main.c create mode 100644 src/modules/physics/e_mod_main.h create mode 100644 src/modules/physics/e_mod_physics.c create mode 100644 src/modules/physics/e_mod_physics.h create mode 100644 src/modules/physics/e_mod_physics_cfdata.c create mode 100644 src/modules/physics/e_mod_physics_cfdata.h create mode 100644 src/modules/physics/module.desktop.in diff --git a/configure.ac b/configure.ac index 0c88e559e..b2e1fc929 100644 --- a/configure.ac +++ b/configure.ac @@ -690,6 +690,37 @@ define([CHECK_MODULE_NOTIFICATION], fi ]) +have_ephysics=no +AM_CONDITIONAL([HAVE_EPHYSICS], [false]) +AC_ARG_ENABLE([ephysics], + AC_HELP_STRING([--disable-ephysics], [disable Ephysics support @<:@default=detect@:>@]), + [e_cv_want_ephysics=$enableval], + AC_CACHE_VAL([e_cv_want_ephysics], [e_cv_want_ephysics=yes]) +) +if test "x$e_cv_want_ephysics" != "xno" ; then + AC_E_CHECK_PKG(EPHYSICS, [ ephysics ], + [ + AC_DEFINE_UNQUOTED([HAVE_EPHYSICS], [1], [enable ephysics]) + ], + [ + AC_MSG_NOTICE([ephysics disabled]) + e_cv_want_ephysics=no + ]) +else + AC_MSG_NOTICE([ephysics disabled]) + e_cv_want_ephysics=no +fi +AC_SUBST([EPHYSICS_CFLAGS]) +AC_SUBST([EPHYSICS_LIBS]) + +AM_CONDITIONAL(HAVE_PHYSICS, false) +define([CHECK_MODULE_PHYSICS], +[ + if test "x$e_cv_want_ephysics" = "xno" ; then + PHYSICS=false + fi +]) + AM_CONDITIONAL(HAVE_ALSA, false) define([CHECK_MODULE_MIXER], [ @@ -806,6 +837,7 @@ AC_E_OPTIONAL_MODULE([syscon], true) AC_E_OPTIONAL_MODULE([everything], true) AC_E_OPTIONAL_MODULE([systray], true) AC_E_OPTIONAL_MODULE([comp], true) +AC_E_OPTIONAL_MODULE([physics], true, [CHECK_MODULE_PHYSICS]) AC_E_OPTIONAL_MODULE([shot], true) AC_E_OPTIONAL_MODULE([backlight], true) AC_E_OPTIONAL_MODULE([tasks], true) @@ -961,6 +993,8 @@ src/modules/systray/Makefile src/modules/systray/module.desktop src/modules/comp/Makefile src/modules/comp/module.desktop +src/modules/physics/Makefile +src/modules/physics/module.desktop src/modules/shot/Makefile src/modules/shot/module.desktop src/modules/backlight/Makefile diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am index 0701b45b8..e65791342 100644 --- a/src/modules/Makefile.am +++ b/src/modules/Makefile.am @@ -175,6 +175,10 @@ if USE_MODULE_COMP SUBDIRS += comp endif +if USE_MODULE_PHYSICS +SUBDIRS += physics +endif + if USE_MODULE_OFONO SUBDIRS += ofono endif diff --git a/src/modules/physics/Makefile.am b/src/modules/physics/Makefile.am new file mode 100644 index 000000000..d1279f53c --- /dev/null +++ b/src/modules/physics/Makefile.am @@ -0,0 +1,36 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = physics + +# 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_builddir)/src/bin \ + -I$(top_srcdir)/src/modules \ + @e_cflags@ @EPHYSICS_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_config.c \ + e_mod_config.h \ + e_mod_physics_cfdata.c \ + e_mod_physics_cfdata.h \ + e_mod_physics.c \ + e_mod_physics.h + +module_la_LIBADD = @e_libs@ @dlopen_libs@ @EPHYSICS_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/physics/e-module-physics.edj b/src/modules/physics/e-module-physics.edj new file mode 100644 index 0000000000000000000000000000000000000000..1401ab4b8fe44c6263d8bf044116e635757a1608 GIT binary patch literal 11935 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 Tmwk@?xQcreate_cfdata = _create_data; + v->free_cfdata = _free_data; + v->basic.apply_cfdata = _basic_apply_data; + v->basic.create_widgets = _basic_create_widgets; + + cfd = e_config_dialog_new(con, _("Physics Settings"), + "E", "appearance/physics", buf, 0, v, mod); + mod->config_dialog = cfd; + return cfd; +} + +static void * +_create_data(E_Config_Dialog *cfd __UNUSED__) +{ + E_Config_Dialog_Data *cfdata; + + cfdata = E_NEW(E_Config_Dialog_Data, 1); + + cfdata->delay = _physics_mod->conf->delay; + cfdata->max_mass = _physics_mod->conf->max_mass; + + return cfdata; +} + +static void +_free_data(E_Config_Dialog *cfd __UNUSED__, + E_Config_Dialog_Data *cfdata) +{ + _physics_mod->config_dialog = NULL; + free(cfdata); +} + +static Evas_Object * +_basic_create_widgets(E_Config_Dialog *cfd, + Evas *evas, + E_Config_Dialog_Data *cfdata) +{ + Evas_Object *ob, *ol, *otb, *tab; + + tab = e_widget_table_add(evas, 0); + evas_object_name_set(tab, "dia_table"); + + otb = e_widget_toolbook_add(evas, 48 * e_scale, 48 * e_scale); + + /////////////////////////////////////////// + + ol = e_widget_list_add(evas, 0, 0); + ob = e_widget_label_add(evas, _("Physics delay after drag")); + e_widget_list_object_append(ol, ob, 1, 1, 0.5); + ob = e_widget_slider_add(evas, 1, 0, _("%2.0f Frames"), 5, 20, 1, 0, &(cfdata->delay), NULL, 150); + e_widget_list_object_append(ol, ob, 1, 1, 0.5); + ob = e_widget_label_add(evas, _("Maximum window mass")); + e_widget_list_object_append(ol, ob, 1, 1, 0.5); + ob = e_widget_slider_add(evas, 1, 0, _("%2.1f Kg"), 1, 6, 1, 0, &(cfdata->max_mass), NULL, 150); + e_widget_list_object_append(ol, ob, 1, 1, 0.5); + ob = e_widget_label_add(evas, _("Desktop gravity")); + e_widget_list_object_append(ol, ob, 1, 1, 0.5); + ob = e_widget_slider_add(evas, 1, 0, _("%1.1f m/s^2"), -5, 5, 1, 0, &(cfdata->gravity), NULL, 150); + e_widget_list_object_append(ol, ob, 1, 1, 0.5); + + e_widget_toolbook_page_append(otb, NULL, _("General"), ol, 1, 1, 1, 1, 0.5, 0.5); + + /////////////////////////////////////////// + + ol = e_widget_list_add(evas, 0, 0); + ob = e_widget_check_add(evas, _("Ignore Fullscreen"), (int*)&(cfdata->ignore_fullscreen)); + e_widget_list_object_append(ol, ob, 1, 0, 0.5); + + ob = e_widget_check_add(evas, _("Ignore Maximized"), (int*)&(cfdata->ignore_maximized)); + e_widget_list_object_append(ol, ob, 1, 0, 0.5); + + e_widget_toolbook_page_append(otb, NULL, _("Ignore"), ol, 1, 1, 1, 1, 0.5, 0.5); + + e_widget_toolbook_page_show(otb, 0); + + e_dialog_resizable_set(cfd->dia, 1); + + e_widget_table_object_append(tab, otb, 0, 0, 1, 1, 1, 1, 1, 1); + return tab; +} + + +static int +_basic_apply_data(E_Config_Dialog *cfd __UNUSED__, + E_Config_Dialog_Data *cfdata) +{ + if ((cfdata->delay != _physics_mod->conf->delay) || + (cfdata->max_mass != _physics_mod->conf->max_mass) || + (cfdata->ignore_fullscreen != _physics_mod->conf->ignore_fullscreen) || + (cfdata->ignore_maximized != _physics_mod->conf->ignore_maximized) || + (cfdata->gravity != _physics_mod->conf->gravity) + ) + { +#define SET(X) _physics_mod->conf->X = cfdata->X + _physics_mod->conf->delay = (unsigned int)cfdata->delay; + SET(max_mass); + SET(ignore_fullscreen); + SET(ignore_maximized); + SET(gravity); + e_mod_physics_shutdown(); + e_mod_physics_init(); + } + e_config_save_queue(); + return 1; +} + diff --git a/src/modules/physics/e_mod_config.h b/src/modules/physics/e_mod_config.h new file mode 100644 index 000000000..248d3c67e --- /dev/null +++ b/src/modules/physics/e_mod_config.h @@ -0,0 +1,8 @@ +#ifdef E_TYPEDEFS +#else +#ifndef E_MOD_CONFIG_H +#define E_MOD_CONFIG_H +E_Config_Dialog *e_int_config_physics_module(E_Container *con, + const char *params __UNUSED__); +#endif +#endif diff --git a/src/modules/physics/e_mod_main.c b/src/modules/physics/e_mod_main.c new file mode 100644 index 000000000..ca6dd4042 --- /dev/null +++ b/src/modules/physics/e_mod_main.c @@ -0,0 +1,101 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_physics.h" +#include "e_mod_config.h" +#include + +/* module private routines */ +Mod *_physics_mod = NULL; + +/* public module routines. all modules must have these */ +EAPI E_Module_Api e_modapi = +{ + E_MODULE_API_VERSION, + "Physics" +}; + +EAPI void * +e_modapi_init(E_Module *m) +{ + Mod *mod; + char buf[4096]; + + if (!ephysics_init()) return NULL; + mod = calloc(1, sizeof(Mod)); + m->data = mod; + + mod->module = m; + + snprintf(buf, sizeof(buf), "%s/e-module-physics.edj", e_module_dir_get(m)); + e_configure_registry_category_add("appearance", 10, _("Look"), NULL, + "preferences-look"); + e_configure_registry_item_add("appearance/physics", 120, _("Physics"), NULL, + buf, e_int_config_physics_module); + mod->conf_edd = e_mod_physics_cfdata_edd_init(); + + mod->conf = e_config_domain_load("module.physics", mod->conf_edd); + if (!mod->conf) _e_mod_config_new(m); + _physics_mod = mod; + + if (!e_mod_physics_init()) + { + e_util_dialog_internal(_("Physics Error"), _("The physics module could not be started")); + e_modapi_shutdown(mod->module); + return NULL; + } + + e_module_delayed_set(m, 0); + e_module_priority_set(m, -1000); + return mod; +} + +void +_e_mod_config_new(E_Module *m) +{ + Mod *mod = m->data; + + mod->conf = e_mod_physics_cfdata_config_new(); +} + +void +_e_mod_config_free(E_Module *m) +{ + Mod *mod = m->data; + + e_mod_cfdata_config_free(mod->conf); + mod->conf = NULL; +} + +EAPI int +e_modapi_shutdown(E_Module *m) +{ + Mod *mod = m->data; + + e_mod_physics_shutdown(); + + e_configure_registry_item_del("appearance/physics"); + e_configure_registry_category_del("appearance"); + + if (mod->config_dialog) + { + e_object_del(E_OBJECT(mod->config_dialog)); + mod->config_dialog = NULL; + } + _e_mod_config_free(m); + + E_CONFIG_DD_FREE(mod->conf_edd); + free(mod); + + if (mod == _physics_mod) _physics_mod = NULL; + + return 1; +} + +EAPI int +e_modapi_save(E_Module *m) +{ + Mod *mod = m->data; + e_config_domain_save("module.physics", mod->conf_edd, mod->conf); + return 1; +} + diff --git a/src/modules/physics/e_mod_main.h b/src/modules/physics/e_mod_main.h new file mode 100644 index 000000000..7558e3028 --- /dev/null +++ b/src/modules/physics/e_mod_main.h @@ -0,0 +1,31 @@ +#ifndef E_MOD_MAIN_H +#define E_MOD_MAIN_H + +#include "e_mod_physics_cfdata.h" + +typedef struct _Mod Mod; + +struct _Mod +{ + E_Module *module; + + E_Config_DD *conf_edd; + E_Config_DD *conf_match_edd; + Config *conf; + + E_Config_Dialog *config_dialog; +}; + +extern Mod *_physics_mod; + +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); +EAPI int e_modapi_info(E_Module *m); + +void _e_mod_config_new(E_Module *m); +void _e_mod_config_free(E_Module *m); + +#endif diff --git a/src/modules/physics/e_mod_physics.c b/src/modules/physics/e_mod_physics.c new file mode 100644 index 000000000..279003542 --- /dev/null +++ b/src/modules/physics/e_mod_physics.c @@ -0,0 +1,815 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_physics.h" +#include + +struct _E_Physics +{ + EPhysics_World *world; + Ecore_X_Window win; + E_Manager *man; + Eina_Inlist *wins; +}; + +struct _E_Physics_Win +{ + EINA_INLIST; + + E_Physics *p; // parent compositor + Ecore_X_Window win; // raw window - for menus etc. + E_Border *bd; // if its a border - later + E_Popup *pop; // if its a popup - later + E_Menu *menu; // if it is a menu - later + EPhysics_Body *body; // physics body + int x, y, w, h; // geometry + int ix, iy; // impulse geometry (next move coord */ + struct + { + int x, y, w, h; // hidden geometry (used when its unmapped and re-instated on map) + } hidden; + int border; // border width + E_Object_Delfn *dfn; // delete function handle for objects being tracked + + E_Border_Hook *begin; // begin move + E_Border_Hook *end; // end move + E_Maximize maximize; + + unsigned int stopped; /* number of frames window has been stopped for */ + unsigned int started; /* number of frames window has been moving for */ + double impulse_x, impulse_y; /* x,y for impulse vector */ + + Eina_Bool visible : 1; // is visible + Eina_Bool inhash : 1; // is in the windows hash + Eina_Bool show_ready : 1; // is this window ready for its first show + Eina_Bool moving : 1; + Eina_Bool impulse : 1; +}; + +static Eina_List *handlers = NULL; +static Eina_List *physicists = NULL; +static Eina_Hash *borders = NULL; + +////////////////////////////////////////////////////////////////////////// +#undef DBG +#if 1 +#define DBG(f, x ...) printf(f, ##x) +#else +#define DBG(f, x ...) +#endif + +static Eina_Bool _e_mod_physics_bd_fullscreen(void *data __UNUSED__, int type, void *event); +static void _e_mod_physics_bd_move_intercept_cb(E_Border *bd, int x, int y); +static void _e_mod_physics_win_update_cb(E_Physics_Win *pw, EPhysics_Body *body, void *event_info __UNUSED__); +static void _e_mod_physics_win_del(E_Physics_Win *pw); +static void _e_mod_physics_win_show(E_Physics_Win *pw); +static void _e_mod_physics_win_hide(E_Physics_Win *pw); +static void _e_mod_physics_win_configure(E_Physics_Win *pw, + int x, + int y, + int w, + int h, + int border); +/* TODO +static void +_e_mod_physics_fps_update(E_Physics *p) +{ + if (_comp_mod->conf->fps_show) + { + if (!p->fps_bg) + { + p->fps_bg = evas_object_rectangle_add(p->evas); + evas_object_color_set(p->fps_bg, 0, 0, 0, 128); + evas_object_layer_set(p->fps_bg, EVAS_LAYER_MAX); + evas_object_show(p->fps_bg); + + p->fps_fg = evas_object_text_add(p->evas); + evas_object_text_font_set(p->fps_fg, "Sans", 10); + evas_object_text_text_set(p->fps_fg, "???"); + evas_object_color_set(p->fps_fg, 255, 255, 255, 255); + evas_object_layer_set(p->fps_fg, EVAS_LAYER_MAX); + evas_object_show(p->fps_fg); + } + } + else + { + if (p->fps_fg) + { + evas_object_del(p->fps_fg); + p->fps_fg = NULL; + } + if (p->fps_bg) + { + evas_object_del(p->fps_bg); + p->fps_bg = NULL; + } + } +} +*/ + + +static void +_e_mod_physics_move_end(void *p_w, void *b_d) +{ + E_Physics_Win *pw = p_w; + /* wrong border */ + if (b_d != pw->bd) return; + DBG("PHYS: DRAG END %d\n", pw->win); + pw->impulse = pw->moving = EINA_FALSE; +} + +static void +_e_mod_physics_move_begin(void *p_w, void *b_d) +{ + E_Physics_Win *pw = p_w; + /* wrong border */ + if (b_d != pw->bd) return; + DBG("PHYS: DRAG BEGIN %d\n", pw->win); + pw->moving = EINA_TRUE; + pw->started = 0; + /* hacks! */ + if ((!pw->impulse_x) && (!pw->impulse_y)) return; + _e_mod_physics_win_hide(pw); + _e_mod_physics_win_show(pw); + pw->show_ready = 0; + _e_mod_physics_win_configure(pw, pw->bd->x, pw->bd->y, pw->bd->w, pw->bd->h, pw->border); + pw->impulse_x = pw->impulse_y = 0; +} + +static E_Physics * +_e_mod_physics_find(Ecore_X_Window root) +{ + Eina_List *l; + E_Physics *p; + + // fixme: use hash if physicists list > 4 + EINA_LIST_FOREACH (physicists, l, p) + { + if (p->man->root == root) return p; + } + return NULL; +} + +static E_Physics_Win * +_e_mod_physics_win_find(Ecore_X_Window win) +{ + return eina_hash_find(borders, e_util_winid_str_get(win)); +} + +static void +_e_mod_physics_win_show(E_Physics_Win *pw) +{ + if (pw->visible) return; + DBG("PHYS: SHOW %d\n", pw->win); + pw->visible = 1; + pw->body = ephysics_body_box_add(pw->p->world); + ephysics_body_friction_set(pw->body, 1.0); + ephysics_body_rotation_on_z_axis_enable_set(pw->body, EINA_FALSE); + ephysics_body_event_callback_add(pw->body, EPHYSICS_CALLBACK_BODY_UPDATE, (EPhysics_Body_Event_Cb)_e_mod_physics_win_update_cb, pw); + pw->begin = e_border_hook_add(E_BORDER_HOOK_MOVE_BEGIN, _e_mod_physics_move_begin, pw); + pw->end = e_border_hook_add(E_BORDER_HOOK_MOVE_END, _e_mod_physics_move_end, pw); + e_border_move_intercept_cb_set(pw->bd, _e_mod_physics_bd_move_intercept_cb); +} + +static void +_e_mod_physics_bd_move_intercept_cb(E_Border *bd, int x, int y) +{ + E_Physics_Win *pw; + + pw = _e_mod_physics_win_find(bd->client.win); + if ((bd->x == x) && (bd->y == y)) + { + DBG("PHYS: STOPPED %d\n", pw->win); + if (pw->moving) pw->started = 0; + pw->show_ready = 0; + _e_mod_physics_win_configure(pw, x, y, pw->bd->w, pw->bd->h, pw->border); + return; + } + if (!pw) return; + DBG("PHYS: MOVE %d - (%d,%d) ->(WANT) (%d,%d)\n", pw->win, bd->x, bd->y, x, y); + if ((!pw->body) || (!pw->moving) || (pw->started < _physics_mod->conf->delay)) + { + DBG("PHYS: MOVE THROUGH\n"); + bd->x = x, bd->y = y; + if (pw->moving) pw->started++; + pw->show_ready = 0; + _e_mod_physics_win_configure(pw, x, y, pw->bd->w, pw->bd->h, pw->border); + return; + } + if (!pw->impulse) + { + DBG("PHYS: IMPULSE APPLY\n"); + pw->impulse_x = (x - bd->x) * 5; + pw->impulse_y = (bd->y - y) * 5; + ephysics_body_central_impulse_apply(pw->body, pw->impulse_x, pw->impulse_y); + bd->x = x, bd->y = y; + pw->impulse = EINA_TRUE; + return; + } + if ((pw->ix == x) && (pw->iy == y)) + bd->x = x, bd->y = y; + else + { + if (E_INSIDE(bd->x, bd->y, pw->p->man->x, pw->p->man->y, pw->p->man->w, pw->p->man->h) && + E_INSIDE(bd->x + bd->w, bd->y, pw->p->man->x, pw->p->man->y, pw->p->man->w, pw->p->man->h) && + E_INSIDE(bd->x, bd->y + bd->h, pw->p->man->x, pw->p->man->y, pw->p->man->w, pw->p->man->h) && + E_INSIDE(bd->x + bd->w, bd->y + bd->h, pw->p->man->x, pw->p->man->y, pw->p->man->w, pw->p->man->h)) + DBG("REJECTED!\n"); + else if (pw->moving) + { + DBG("UPDATE\n"); + bd->x = x, bd->y = y; + pw->show_ready = 0; + _e_mod_physics_win_configure(pw, x, y, pw->bd->w, pw->bd->h, pw->border); + } + } +} + +static E_Physics_Win * +_e_mod_physics_win_add(E_Physics *p, E_Border *bd) +{ + Ecore_X_Window_Attributes att; + E_Physics_Win *pw; + + memset((&att), 0, sizeof(Ecore_X_Window_Attributes)); + if (!ecore_x_window_attributes_get(bd->client.win, &att)) + return NULL; + /* don't physics on input grab windows or tooltips */ + if (att.input_only || att.override) return NULL; + + pw = calloc(1, sizeof(E_Physics_Win)); + if (!pw) return NULL; + pw->win = bd->client.win; + pw->p = p; + pw->bd = bd; + eina_hash_add(borders, e_util_winid_str_get(pw->bd->client.win), pw); + if (pw->bd->visible) + _e_mod_physics_win_show(pw); + DBG("PHYS: WIN %d ADD\n", bd->client.win); + p->wins = eina_inlist_append(p->wins, EINA_INLIST_GET(pw)); + return pw; +} + +static void +_e_mod_physics_win_del(E_Physics_Win *pw) +{ + if (pw->dfn) + { + eina_hash_del(borders, e_util_winid_str_get(pw->bd->client.win), pw); + e_object_delfn_del(E_OBJECT(pw->bd), pw->dfn); + pw->bd = NULL; + pw->dfn = NULL; + } + e_border_move_intercept_cb_set(pw->bd, NULL); + pw->p->wins = eina_inlist_remove(pw->p->wins, EINA_INLIST_GET(pw)); + if (pw->body) ephysics_body_del(pw->body); + memset(pw, 0, sizeof(E_Physics_Win)); + free(pw); +} + +static void +_e_mod_physics_win_hide(E_Physics_Win *pw) +{ + if (!pw->visible) return; + DBG("PHYS: HIDE %d\n", pw->win); + pw->show_ready = pw->visible = 0; + ephysics_body_del(pw->body); + pw->body = NULL; + e_border_hook_del(pw->begin); + e_border_hook_del(pw->end); + pw->begin = pw->end = NULL; + e_border_move_intercept_cb_set(pw->bd, NULL); +} + +#if 0 +static void +_e_mod_physics_win_raise_above(E_Physics_Win *pw, + E_Physics_Win *cw2) +{ + DBG(" [0x%x] abv [0x%x]\n", pw->win, cw2->win); + pw->p->wins_invalid = 1; + pw->p->wins = eina_inlist_remove(pw->p->wins, EINA_INLIST_GET(pw)); + pw->p->wins = eina_inlist_append_relative(pw->p->wins, + EINA_INLIST_GET(pw), + EINA_INLIST_GET(cw2)); + evas_object_stack_above(pw->shobj, cw2->shobj); + if (pw->bd) + { + Eina_List *l; + E_Border *tmp; + + EINA_LIST_FOREACH (pw->bd->client.e.state.video_child, l, tmp) + { + E_Physics_Win *tcw; + + tcw = eina_hash_find(borders, e_util_winid_str_get(tmp->client.win)); + if (!tcw) continue; + + evas_object_stack_below(tcw->shobj, pw->shobj); + } + } + + _e_mod_physics_win_render_queue(pw); + pw->pending_count++; + e_manager_comp_event_src_config_send + (pw->p->man, (E_Manager_Comp_Source *)pw, + _e_mod_physics_cb_pending_after, pw->p); +} + +static void +_e_mod_physics_win_raise(E_Physics_Win *pw) +{ + DBG(" [0x%x] rai\n", pw->win); + pw->p->wins_invalid = 1; + pw->p->wins = eina_inlist_remove(pw->p->wins, EINA_INLIST_GET(pw)); + pw->p->wins = eina_inlist_append(pw->p->wins, EINA_INLIST_GET(pw)); + evas_object_raise(pw->shobj); + if (pw->bd) + { + Eina_List *l; + E_Border *tmp; + + EINA_LIST_FOREACH (pw->bd->client.e.state.video_child, l, tmp) + { + E_Physics_Win *tcw; + + tcw = eina_hash_find(borders, e_util_winid_str_get(tmp->client.win)); + if (!tcw) continue; + + evas_object_stack_below(tcw->shobj, pw->shobj); + } + } + + _e_mod_physics_win_render_queue(pw); + pw->pending_count++; + e_manager_comp_event_src_config_send + (pw->p->man, (E_Manager_Comp_Source *)pw, + _e_mod_physics_cb_pending_after, pw->p); +} + +static void +_e_mod_physics_win_lower(E_Physics_Win *pw) +{ + DBG(" [0x%x] low\n", pw->win); + pw->p->wins_invalid = 1; + pw->p->wins = eina_inlist_remove(pw->p->wins, EINA_INLIST_GET(pw)); + pw->p->wins = eina_inlist_prepend(pw->p->wins, EINA_INLIST_GET(pw)); + evas_object_lower(pw->shobj); + if (pw->bd) + { + Eina_List *l; + E_Border *tmp; + + EINA_LIST_FOREACH (pw->bd->client.e.state.video_child, l, tmp) + { + E_Physics_Win *tcw; + + tcw = eina_hash_find(borders, e_util_winid_str_get(tmp->client.win)); + if (!tcw) continue; + + evas_object_stack_below(tcw->shobj, pw->shobj); + } + } + + _e_mod_physics_win_render_queue(pw); + pw->pending_count++; + e_manager_comp_event_src_config_send + (pw->p->man, (E_Manager_Comp_Source *)pw, + _e_mod_physics_cb_pending_after, pw->p); +} +#endif + +static void +_e_mod_physics_win_mass_set(E_Physics_Win *pw) +{ + double mass; + + mass = _physics_mod->conf->max_mass * (((double)pw->w / (double)pw->p->man->w) + ((double)pw->h / (double)pw->p->man->h) / 2.); + DBG("PHYS: WIN %d MASS %g\n", pw->win, mass); + ephysics_body_mass_set(pw->body, mass); +} + +static void +_e_mod_physics_win_configure(E_Physics_Win *pw, + int x, + int y, + int w, + int h, + int border) +{ + //DBG("PHYS: CONFIG %d\n", pw->win); + if (!pw->visible) + { + pw->hidden.x = x; + pw->hidden.y = y; + pw->border = border; + } + else + { + if (!((x == pw->x) && (y == pw->y))) + { + pw->x = x; + pw->y = y; + } + pw->hidden.x = x; + pw->hidden.y = y; + } + pw->maximize = pw->bd->maximized; + pw->hidden.w = w; + pw->hidden.h = h; + if (!((w == pw->w) && (h == pw->h))) + { + pw->w = w; + pw->h = h; + } + if (pw->border != border) + { + pw->border = border; + } + if ((!pw->show_ready) && pw->body) + { + _e_mod_physics_win_mass_set(pw); + ephysics_body_geometry_set(pw->body, x, y, w, border + h); + pw->show_ready = 1; + } +} + + +////////////////////////////////////////////////////////////////////////// + + +static Eina_Bool +_e_mod_physics_bd_property(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + E_Event_Border_Property *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->border->client.win); + if (pw->maximize == ev->border->maximized) return ECORE_CALLBACK_PASS_ON; + + if (ev->border->maximized) + _e_mod_physics_win_del(pw); + else + { + E_Physics *p = _e_mod_physics_find(ev->border->zone->container->manager->root); + pw = _e_mod_physics_win_add(p, ev->border); + if (!pw) return ECORE_CALLBACK_PASS_ON; + _e_mod_physics_win_configure(pw, pw->bd->x, pw->bd->y, + pw->bd->w, pw->bd->h, + ecore_x_window_border_width_get(pw->bd->client.win)); + } + +out: + pw->maximize = ev->border->maximized; + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_mod_physics_bd_fullscreen(void *data __UNUSED__, int type, void *event) +{ + E_Event_Border_Fullscreen *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->border->client.win); + if (type == E_EVENT_BORDER_FULLSCREEN) + { + if (pw) + _e_mod_physics_win_del(pw); + } + else + { + E_Physics *p = _e_mod_physics_find(ev->border->zone->container->manager->root); + if (!pw) + { + pw = _e_mod_physics_win_add(p, ev->border); + if (!pw) return ECORE_CALLBACK_PASS_ON; + _e_mod_physics_win_configure(pw, pw->bd->x, pw->bd->y, + pw->bd->w, pw->bd->h, + ecore_x_window_border_width_get(pw->bd->client.win)); + } + } + return ECORE_CALLBACK_PASS_ON; +} + + +static Eina_Bool +_e_mod_physics_bd_add(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + E_Event_Border_Add *ev = event; + DBG("PHYS: NEW %d\n", ev->border->client.win); + E_Physics *p = _e_mod_physics_find(ev->border->zone->container->manager->root); + E_Physics_Win *pw = _e_mod_physics_win_find(ev->border->client.win); + if (pw) return ECORE_CALLBACK_PASS_ON; + pw = _e_mod_physics_win_add(p, ev->border); + if (pw) _e_mod_physics_win_configure(pw, ev->border->x, ev->border->y, ev->border->w, ev->border->h, + ecore_x_window_border_width_get(ev->border->client.win)); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_mod_physics_bd_del(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + E_Event_Border_Add *ev = event; + DBG("PHYS: DEL %d\n", ev->border->client.win); + E_Physics_Win *pw = _e_mod_physics_win_find(ev->border->client.win); + if (!pw) return ECORE_CALLBACK_PASS_ON; + _e_mod_physics_win_del(pw); + return ECORE_CALLBACK_PASS_ON; +} + +/* +static Eina_Bool +_e_mod_physics_reparent(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + Ecore_X_Event_Window_Reparent *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->win); + if (!pw) return ECORE_CALLBACK_PASS_ON; + if (ev->parent != pw->p->man->root) + _e_mod_physics_win_del(pw); + return ECORE_CALLBACK_PASS_ON; +} +*/ +static Eina_Bool +_e_mod_physics_configure(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + Ecore_X_Event_Window_Configure *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->win); + if (!pw) return ECORE_CALLBACK_PASS_ON; +/* TODO: stacking + if (ev->abovewin == 0) + { + if (EINA_INLIST_GET(pw)->prev) _e_mod_physics_win_lower(pw); + } + else + { + E_Physics_Win *cw2 = _e_mod_physics_win_find(ev->abovewin); + + if (cw2) + { + E_Physics_Win *cw3 = (E_Physics_Win *)(EINA_INLIST_GET(pw)->prev); + + if (cw3 != cw2) _e_mod_physics_win_raise_above(pw, cw2); + } + } +*/ + if (!((pw->x == ev->x) && (pw->y == ev->y) && + (pw->w == ev->w) && (pw->h == ev->h) && + (pw->border == ev->border))) + { + _e_mod_physics_win_configure(pw, ev->x, ev->y, ev->w, ev->h, ev->border); + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_mod_physics_stack(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + Ecore_X_Event_Window_Stack *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->win); + if (!pw) return ECORE_CALLBACK_PASS_ON; + /* TODO + if (ev->detail == ECORE_X_WINDOW_STACK_ABOVE) _e_mod_physics_win_raise(pw); + else _e_mod_physics_win_lower(pw); + */ + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_mod_physics_randr(void *data __UNUSED__, + int type __UNUSED__, + __UNUSED__ void *event __UNUSED__) +{ + Eina_List *l; + E_Physics *p; + + EINA_LIST_FOREACH(physicists, l, p) + ephysics_world_render_geometry_set(p->world, 0, 0, p->man->w, p->man->h); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_mod_physics_bd_resize(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + E_Event_Border_Move *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->border->client.win); + if (!pw) return ECORE_CALLBACK_PASS_ON; + if (!pw->visible) return ECORE_CALLBACK_PASS_ON; + pw->show_ready = 0; + _e_mod_physics_win_configure(pw, pw->x, pw->y, ev->border->w, ev->border->h, pw->border); + pw->show_ready = 1; + return ECORE_CALLBACK_PASS_ON; +} +/* +static Eina_Bool +_e_mod_physics_bd_move(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + E_Event_Border_Move *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->border->client.win); + if (!pw) return ECORE_CALLBACK_PASS_ON; + if (!pw->visible) return ECORE_CALLBACK_PASS_ON; + _e_mod_physics_win_configure(pw, pw->x, pw->y, ev->border->w, ev->border->h, pw->border); + + return ECORE_CALLBACK_PASS_ON; +} +*/ +static Eina_Bool +_e_mod_physics_bd_show(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + E_Event_Border_Hide *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->border->client.win); + if (!pw) return ECORE_CALLBACK_PASS_ON; + _e_mod_physics_win_show(pw); + _e_mod_physics_win_configure(pw, pw->bd->x, pw->bd->y, pw->bd->w, pw->bd->h, pw->border); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_mod_physics_bd_hide(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + E_Event_Border_Hide *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->border->client.win); + if (!pw) return ECORE_CALLBACK_PASS_ON; + _e_mod_physics_win_hide(pw); + return ECORE_CALLBACK_PASS_ON; +} +#if 0 +static Eina_Bool +_e_mod_physics_bd_iconify(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + E_Event_Border_Iconify *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->border->client.win); + if (!pw) return ECORE_CALLBACK_PASS_ON; + // fimxe: special iconfiy anim + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_mod_physics_bd_uniconify(void *data __UNUSED__, + int type __UNUSED__, + void *event) +{ + E_Event_Border_Uniconify *ev = event; + E_Physics_Win *pw = _e_mod_physics_win_find(ev->border->client.win); + if (!pw) return ECORE_CALLBACK_PASS_ON; + // fimxe: special uniconfiy anim + return ECORE_CALLBACK_PASS_ON; +} +#endif + +static E_Physics * +_e_mod_physics_add(E_Manager *man) +{ + E_Physics *p; + EPhysics_Body *bound; + Eina_List *l; + E_Border *bd; + + p = calloc(1, sizeof(E_Physics)); + if (!p) return NULL; + p->man = man; + p->world = ephysics_world_new(); + /* TODO: world per zone */ + DBG("PHYS: world++ || %dx%d\n", man->w, man->h); + ephysics_world_render_geometry_set(p->world, 0, 0, man->w, man->h); + ephysics_world_gravity_set(p->world, 0, _physics_mod->conf->gravity); + + bound = ephysics_body_left_boundary_add(p->world); + ephysics_body_restitution_set(bound, 1); + ephysics_body_friction_set(bound, 3); + bound = ephysics_body_right_boundary_add(p->world); + ephysics_body_restitution_set(bound, 1); + ephysics_body_friction_set(bound, 3); + bound = ephysics_body_top_boundary_add(p->world); + ephysics_body_restitution_set(bound, 1); + ephysics_body_friction_set(bound, 3); + bound = ephysics_body_bottom_boundary_add(p->world); + ephysics_body_restitution_set(bound, 1); + ephysics_body_friction_set(bound, 3); + + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + E_Physics_Win *pw; + int border; + + pw = _e_mod_physics_win_add(p, bd); + if (!pw) continue; + border = ecore_x_window_border_width_get(bd->client.win); + _e_mod_physics_win_configure(pw, bd->x, bd->y, bd->w, bd->h, border); + } + + return p; +} + +static void +_e_mod_physics_del(E_Physics *p) +{ + E_Physics_Win *pw; + + while (p->wins) + { + pw = (E_Physics_Win *)(p->wins); + _e_mod_physics_win_del(pw); + } + free(p); +} + +static void +_e_mod_physics_win_update_cb(E_Physics_Win *pw, EPhysics_Body *body, void *event_info __UNUSED__) +{ + //DBG("PHYS: TICKER %d\n", pw->win); + if (pw->moving && (pw->started < _physics_mod->conf->delay)) + { + pw->show_ready = 0; + _e_mod_physics_win_configure(pw, pw->x, pw->y, pw->w, pw->h, pw->border); + return; + } + ephysics_body_geometry_get(body, &pw->ix, &pw->iy, NULL, NULL); + e_border_move(pw->bd, pw->ix, pw->iy); +} + +////////////////////////////////////////////////////////////////////////// + +void +e_mod_physics_mass_update(void) +{ + Eina_List *l; + E_Physics *p; + E_Physics_Win *pw; + EINA_LIST_FOREACH(physicists, l, p) + EINA_INLIST_FOREACH(p->wins, pw) + _e_mod_physics_win_mass_set(pw); +} + +Eina_Bool +e_mod_physics_init(void) +{ + Eina_List *l; + E_Manager *man; + + borders = eina_hash_string_superfast_new(NULL); + +// handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_mod_physics_reparent, NULL)); + handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_mod_physics_configure, NULL)); + //handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK, _e_mod_physics_stack, NULL)); + + if (_physics_mod->conf->ignore_maximized) + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_PROPERTY, _e_mod_physics_bd_property, NULL)); + if (_physics_mod->conf->ignore_fullscreen) + { + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_FULLSCREEN, _e_mod_physics_bd_fullscreen, NULL)); + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_UNFULLSCREEN, _e_mod_physics_bd_fullscreen, NULL)); + } + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONTAINER_RESIZE, _e_mod_physics_randr, NULL)); + + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_ADD, _e_mod_physics_bd_add, NULL)); + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_REMOVE, _e_mod_physics_bd_del, NULL)); + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_SHOW, _e_mod_physics_bd_show, NULL)); + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_HIDE, _e_mod_physics_bd_hide, NULL)); +// handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_MOVE, _e_mod_physics_bd_move, NULL)); + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_RESIZE, _e_mod_physics_bd_resize, NULL)); +#if 0 + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_ICONIFY, _e_mod_physics_bd_iconify, NULL)); + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_UNICONIFY, _e_mod_physics_bd_uniconify, NULL)); +#endif + EINA_LIST_FOREACH (e_manager_list(), l, man) + { + E_Physics *p; + + p = _e_mod_physics_add(man); + if (p) physicists = eina_list_append(physicists, p); + } + + ecore_x_sync(); + + return 1; +} + +void +e_mod_physics_shutdown(void) +{ + E_Physics *p; + + EINA_LIST_FREE (physicists, p) + _e_mod_physics_del(p); + + E_FREE_LIST(handlers, ecore_event_handler_del); + + if (borders) eina_hash_free(borders); + borders = NULL; +} + diff --git a/src/modules/physics/e_mod_physics.h b/src/modules/physics/e_mod_physics.h new file mode 100644 index 000000000..468ecdb73 --- /dev/null +++ b/src/modules/physics/e_mod_physics.h @@ -0,0 +1,14 @@ +#ifdef E_TYPEDEFS +#else +#ifndef E_MOD_PHYSICS_H +#define E_MOD_PHYSICS_H + +typedef struct _E_Physics E_Physics; +typedef struct _E_Physics_Win E_Physics_Win; + +void e_mod_physics_mass_update(void); +Eina_Bool e_mod_physics_init(void); +void e_mod_physics_shutdown(void); + +#endif +#endif diff --git a/src/modules/physics/e_mod_physics_cfdata.c b/src/modules/physics/e_mod_physics_cfdata.c new file mode 100644 index 000000000..95f83a236 --- /dev/null +++ b/src/modules/physics/e_mod_physics_cfdata.c @@ -0,0 +1,43 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_physics_cfdata.h" + +EAPI E_Config_DD * +e_mod_physics_cfdata_edd_init(void) +{ + E_Config_DD *conf_edd; + + conf_edd = E_CONFIG_DD_NEW("Physics_Config", Config); +#undef T +#undef D +#define T Config +#define D conf_edd + E_CONFIG_VAL(D, T, delay, UINT); + E_CONFIG_VAL(D, T, max_mass, DOUBLE); + E_CONFIG_VAL(D, T, gravity, DOUBLE); + E_CONFIG_VAL(D, T, ignore_fullscreen, UCHAR); + E_CONFIG_VAL(D, T, ignore_maximized, UCHAR); + return conf_edd; +} + +EAPI Config * +e_mod_physics_cfdata_config_new(void) +{ + Config *cfg; + + cfg = E_NEW(Config, 1); + cfg->delay = 10; + cfg->max_mass = 3.0; + cfg->gravity = 0.0; + cfg->ignore_fullscreen = EINA_TRUE; + cfg->ignore_maximized = EINA_TRUE; + + return cfg; +} + +EAPI void +e_mod_cfdata_config_free(Config *cfg) +{ + free(cfg); +} + diff --git a/src/modules/physics/e_mod_physics_cfdata.h b/src/modules/physics/e_mod_physics_cfdata.h new file mode 100644 index 000000000..19883b50b --- /dev/null +++ b/src/modules/physics/e_mod_physics_cfdata.h @@ -0,0 +1,19 @@ +#ifndef E_MOD_PHYSICS_CFDATA_H +#define E_MOD_PHYSICS_CFDATA_H + +typedef struct _Config Config; + +struct _Config +{ + unsigned int delay; /* delay before applying physics */ + double max_mass; /* maximum mass for a window */ + double gravity; /* maximum mass for a window */ + Eina_Bool ignore_fullscreen; + Eina_Bool ignore_maximized; +}; + +EAPI E_Config_DD *e_mod_physics_cfdata_edd_init(void); +EAPI Config *e_mod_physics_cfdata_config_new(void); +EAPI void e_mod_cfdata_config_free(Config *cfg); + +#endif diff --git a/src/modules/physics/module.desktop.in b/src/modules/physics/module.desktop.in new file mode 100644 index 000000000..10f8ac87e --- /dev/null +++ b/src/modules/physics/module.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Link +Name=Physics +Icon=e-module-physics +Comment=Enlightenment Physics Professor +X-Enlightenment-ModuleType=look