From 2005381bbdf305a7d86b2f309e6ec28a613d976b Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Thu, 2 Jun 2005 14:56:07 +0000 Subject: [PATCH] ehack is baaack! :) SVN revision: 15057 --- TODO | 1 - configure.in | 17 ++++ src/Makefile.am | 2 +- src/bin/e_container.c | 2 +- src/bin/e_zone.c | 39 +++++-- src/preload/Makefile.am | 15 +++ src/preload/e_hack.c | 218 ++++++++++++++++++++++++++++++++++++++++ src/preload/e_hack.h | 12 +++ 8 files changed, 295 insertions(+), 11 deletions(-) create mode 100644 src/preload/Makefile.am create mode 100644 src/preload/e_hack.c create mode 100644 src/preload/e_hack.h diff --git a/TODO b/TODO index aec095875..a3747339f 100644 --- a/TODO +++ b/TODO @@ -57,7 +57,6 @@ These are in no particular order: * add locale and encoding fields to eapp files (to launch eapp in that locale+encoding) * add input method selector stuff to eapp - same as locale -* libechack needs to come back - and execute all things with libehack preloads active * get all libehack properties if they exist * titlebar/border expansion/gadget panel for moduels to put window widgets in * add actions to flip desktops on a given zone and/or container only diff --git a/configure.in b/configure.in index c2f78489d..9002a80a2 100644 --- a/configure.in +++ b/configure.in @@ -94,6 +94,22 @@ else AC_DEFINE_UNQUOTED(LOCALE_DIR, "${datadir}/locale", "Locale directory") fi +x_dir="" +x_cflags="" +x_libs="" +AC_PATH_XTRA +AC_CHECK_HEADER(X11/X.h, + [ + x_dir=${x_dir:-/usr/X11R6} + x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}} + x_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} -lX11 -lXext" + ],[ + AC_MSG_ERROR([Cannot find X headers and libraries.]) + ] +) +AC_SUBST(x_cflags) +AC_SUBST(x_libs) + ALL_LINGUAS="bg de es fi fr ja pl pt ru zh_CN hu sl it cs" AM_GNU_GETTEXT([external]) @@ -218,6 +234,7 @@ src/modules/temperature/Makefile src/modules/cpufreq/Makefile src/modules/ibox/Makefile src/modules/start/Makefile +src/preload/Makefile data/Makefile data/fonts/Makefile data/images/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index b2a955314..697490128 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,2 +1,2 @@ MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = bin modules lib +SUBDIRS = bin modules lib preload diff --git a/src/bin/e_container.c b/src/bin/e_container.c index 207b92686..ab14365a7 100644 --- a/src/bin/e_container.c +++ b/src/bin/e_container.c @@ -99,7 +99,7 @@ e_container_new(E_Manager *man) e_pointer_container_set(con); - con->num = evas_list_count(con->manager->containers); + con->num = evas_list_count(con->manager->containers) - 1; snprintf(name, sizeof(name), _("Container %d"), con->num); con->name = strdup(name); diff --git a/src/bin/e_zone.c b/src/bin/e_zone.c index b279acf0f..d702c4a0a 100644 --- a/src/bin/e_zone.c +++ b/src/bin/e_zone.c @@ -459,13 +459,20 @@ e_zone_desk_linear_flip_to(E_Zone *zone, int x) int e_zone_app_exec(E_Zone *zone, E_App *a) { - int ret; - char *penv_display, *p1, *p2; + static int launch_id = 1; + char *p1, *p2; + char *penv_display; + char *penv_ld_preload; + char *penv_ld_preload_path; char buf[4096], buf2[32]; /* save previous env vars we need to save */ penv_display = getenv("DISPLAY"); if (penv_display) penv_display = strdup(penv_display); + penv_ld_preload = getenv("LD_PRELOAD"); + if (penv_ld_preload) penv_ld_preload = strdup(penv_ld_preload); + penv_ld_preload_path = getenv("LD_PRELOAD_PATH"); + if (penv_ld_preload_path) penv_ld_preload_path = strdup(penv_ld_preload_path); /* set env vars */ p1 = strrchr(penv_display, ':'); @@ -490,16 +497,22 @@ e_zone_app_exec(E_Zone *zone, E_App *a) strcpy(buf, penv_display); e_util_env_set("DISPLAY", buf); snprintf(buf, sizeof(buf), "%i %i", zone->desk_x_current, zone->desk_y_current); - e_util_env_set("_E_DESK", buf); + e_util_env_set("E_DESK", buf); snprintf(buf, sizeof(buf), "%i", zone->num); - e_util_env_set("_E_ZONE", buf); + e_util_env_set("E_ZONE", buf); snprintf(buf, sizeof(buf), "%i", zone->container->num); - e_util_env_set("_E_CONTAINER", buf); + e_util_env_set("E_CONTAINER", buf); snprintf(buf, sizeof(buf), "%i", zone->container->manager->num); - e_util_env_set("_E_MANAGER", buf); + e_util_env_set("E_MANAGER", buf); + e_util_env_set("LD_PRELOAD_PATH", PACKAGE_LIB_DIR"/enlightenment/preload"); + e_util_env_set("LD_PRELOAD", PACKAGE_LIB_DIR"/enlightenment/preload/e_hack.so"); + snprintf(buf, sizeof(buf), "%i", launch_id); + e_util_env_set("E_LAUNCH_ID", buf); + launch_id++; + if (launch_id == 0) launch_id = 1; /* execute */ - ret = e_app_exec(a); + if (!e_app_exec(a)) return 0; /* reset env vars */ if (penv_display) @@ -507,7 +520,17 @@ e_zone_app_exec(E_Zone *zone, E_App *a) e_util_env_set("DISPLAY", penv_display); free(penv_display); } - return ret; + if (penv_ld_preload) + { + e_util_env_set("LD_PRELOAD", penv_ld_preload); + free(penv_ld_preload); + } + if (penv_ld_preload_path) + { + e_util_env_set("LD_PRELOAD_PATH", penv_ld_preload_path); + free(penv_ld_preload_path); + } + return launch_id; } /* local subsystem functions */ diff --git a/src/preload/Makefile.am b/src/preload/Makefile.am new file mode 100644 index 000000000..c08c6b23b --- /dev/null +++ b/src/preload/Makefile.am @@ -0,0 +1,15 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(includedir) \ + -I$(top_srcdir)src/preload \ + @x_cflags@ +pkgdir = $(libdir)/enlightenment/preload +pkg_LTLIBRARIES = e_hack.la +e_hack_la_SOURCES = \ +e_hack.c \ +e_hack.h +e_hack_la_LIBADD = @x_libs@ @dlopen_libs@ +e_hack_la_LDFLAGS = -module -avoid-version +e_hack_la_DEPENDENCIES = $(top_builddir)/config.h diff --git a/src/preload/e_hack.c b/src/preload/e_hack.c new file mode 100644 index 000000000..a21ed19c8 --- /dev/null +++ b/src/preload/e_hack.c @@ -0,0 +1,218 @@ +#include "config.h" +#include "e_hack.h" + +/* prototypes */ +static void __e_hack_set_properties(Display *display, Window window); + +/* dlopened xlib so we can find the symbols in the real xlib to call them */ +static void *lib_xlib = NULL; + +/* the function that actually sets the properties on toplevel window */ +static void +__e_hack_set_properties(Display *display, Window window) +{ + static Atom a_launch_id = 0; + static Atom a_user_id = 0; + static Atom a_process_id = 0; + static Atom a_p_process_id = 0; + static Atom a_machine_name = 0; + static Atom a_user_name = 0; + static Atom a_desk = 0; + static Atom a_zone = 0; + static Atom a_container = 0; + static Atom a_manager = 0; + char *env = NULL; + + if (!a_launch_id) a_launch_id = XInternAtom(display, "_E_HACK_LAUNCH_ID", False); + if (!a_user_id) a_user_id = XInternAtom(display, "_E_HACK_USER_ID", False); + if (!a_process_id) a_process_id = XInternAtom(display, "_E_HACK_PROCESS_ID", False); + if (!a_p_process_id) a_p_process_id = XInternAtom(display, "_E_HACK_PARENT_PROCESS_ID", False); + if (!a_machine_name) a_machine_name = XInternAtom(display, "_E_HACK_MACHINE_NAME", False); + if (!a_user_name) a_user_name = XInternAtom(display, "_E_HACK_USER_NAME", False); + if (!a_desk) a_desk = XInternAtom(display, "_E_HACK_DESK", False); + if (!a_zone) a_zone = XInternAtom(display, "_E_HACK_ZONE", False); + if (!a_container) a_container = XInternAtom(display, "_E_HACK_CONTAINER", False); + if (!a_manager) a_manager = XInternAtom(display, "_E_HACK_MANAGER", False); + + if ((env = getenv("E_LAUNCH_ID"))) + XChangeProperty(display, window, a_launch_id, XA_STRING, 8, PropModeReplace, env, strlen(env)); + { + uid_t uid; + pid_t pid, ppid; + struct utsname ubuf; + char buf[4096]; + + uid = getuid(); + pid = getpid(); + ppid = getppid(); + + snprintf(buf, sizeof(buf), "%i", uid); + XChangeProperty(display, window, a_user_id, XA_STRING, 8, PropModeReplace, buf, strlen(buf)); + snprintf(buf, sizeof(buf), "%i", pid); + XChangeProperty(display, window, a_process_id, XA_STRING, 8, PropModeReplace, buf, strlen(buf)); + snprintf(buf, sizeof(buf), "%i", ppid); + XChangeProperty(display, window, a_p_process_id, XA_STRING, 8, PropModeReplace, buf, strlen(buf)); + if (!uname(&ubuf)) + { + snprintf(buf, sizeof(buf), "%s", ubuf.nodename); + XChangeProperty(display, window, a_machine_name, XA_STRING, 8, PropModeReplace, buf, strlen(buf)); + } + else + XChangeProperty(display, window, a_machine_name, XA_STRING, 8, PropModeReplace, " ", 1); + } + if ((env = getenv("USER"))) + XChangeProperty(display, window, a_user_name, XA_STRING, 8, PropModeReplace, env, strlen(env)); + if ((env = getenv("E_DESK"))) + XChangeProperty(display, window, a_desk, XA_STRING, 8, PropModeReplace, env, strlen(env)); + if ((env = getenv("E_ZONE"))) + XChangeProperty(display, window, a_zone, XA_STRING, 8, PropModeReplace, env, strlen(env)); + if ((env = getenv("E_CONTAINER"))) + XChangeProperty(display, window, a_container, XA_STRING, 8, PropModeReplace, env, strlen(env)); + if ((env = getenv("E_MANAGER"))) + XChangeProperty(display, window, a_manager, XA_STRING, 8, PropModeReplace, env, strlen(env)); +} + +/* XCreateWindow intercept hack */ +Window +XCreateWindow( + Display *display, + Window parent, + int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, + int depth, + unsigned int class, + Visual *visual, + unsigned long valuemask, + XSetWindowAttributes *attributes + ) +{ + static Window (*func) + ( + Display *display, + Window parent, + int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, + int depth, + unsigned int class, + Visual *visual, + unsigned long valuemask, + XSetWindowAttributes *attributes + ) = NULL; + int i; + + /* find the real Xlib and the real X function */ + if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); + if (!func) func = dlsym (lib_xlib, "XCreateWindow"); + + /* multihead screen handling loop */ + for (i = 0; i < ScreenCount(display); i++) + { + /* if the window is created as a toplevel window */ + if (parent == RootWindow(display, i)) + { + Window window; + + /* create it */ + window = (*func) (display, parent, x, y, width, height, + border_width, depth, class, visual, valuemask, + attributes); + /* set properties */ + __e_hack_set_properties(display, window); + /* return it */ + return window; + } + } + /* normal child window - create as usual */ + return (*func) (display, parent, x, y, width, height, border_width, depth, + class, visual, valuemask, attributes); +} + +/* XCreateSimpleWindow intercept hack */ +Window +XCreateSimpleWindow( + Display *display, + Window parent, + int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, + unsigned long border, + unsigned long background + ) +{ + static Window (*func) + ( + Display *display, + Window parent, + int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, + unsigned long border, + unsigned long background + ) = NULL; + int i; + + /* find the real Xlib and the real X function */ + if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); + if (!func) func = dlsym (lib_xlib, "XCreateSimpleWindow"); + + /* multihead screen handling loop */ + for (i = 0; i < ScreenCount(display); i++) + { + /* if the window is created as a toplevel window */ + if (parent == RootWindow(display, i)) + { + Window window; + + /* create it */ + window = (*func) (display, parent, x, y, width, height, + border_width, border, background); + /* set properties */ + __e_hack_set_properties(display, window); + /* return it */ + return window; + } + } + /* normal child window - create as usual */ + return (*func) (display, parent, x, y, width, height, + border_width, border, background); +} + +/* XReparentWindow intercept hack */ +int +XReparentWindow( + Display *display, + Window window, + Window parent, + int x, int y + ) +{ + static int (*func) + ( + Display *display, + Window window, + Window parent, + int x, int y + ) = NULL; + int i; + + /* find the real Xlib and the real X function */ + if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); + if (!func) func = dlsym (lib_xlib, "XReparentWindow"); + + /* multihead screen handling loop */ + for (i = 0; i < ScreenCount(display); i++) + { + /* if the window is created as a toplevel window */ + if (parent == RootWindow(display, i)) + { + /* set properties */ + __e_hack_set_properties(display, window); + /* reparent it */ + return (*func) (display, window, parent, x, y); + } + } + /* normal child window reparenting - reparent as usual */ + return (*func) (display, window, parent, x, y); +} diff --git a/src/preload/e_hack.h b/src/preload/e_hack.h new file mode 100644 index 000000000..a2948c95d --- /dev/null +++ b/src/preload/e_hack.h @@ -0,0 +1,12 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include