[maemo-commits] [maemo-commits] r19057 - in projects/haf/trunk/hildon-control-panel: . debian src
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Thu Aug 6 09:21:34 EEST 2009
- Previous message: [maemo-commits] r19056 - projects/haf/tags/libsdl1.2
- Next message: [maemo-commits] r19058 - in projects/haf/trunk/maemo-launcher: . debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: kihamala Date: 2009-08-06 09:21:23 +0300 (Thu, 06 Aug 2009) New Revision: 19057 Added: projects/haf/trunk/hildon-control-panel/src/hcp-app-loader.c Modified: projects/haf/trunk/hildon-control-panel/ChangeLog projects/haf/trunk/hildon-control-panel/debian/control projects/haf/trunk/hildon-control-panel/src/hcp-app.c Log: fixes from David + ChangeLog Modified: projects/haf/trunk/hildon-control-panel/ChangeLog =================================================================== --- projects/haf/trunk/hildon-control-panel/ChangeLog 2009-08-05 16:07:21 UTC (rev 19056) +++ projects/haf/trunk/hildon-control-panel/ChangeLog 2009-08-06 06:21:23 UTC (rev 19057) @@ -1,3 +1,46 @@ +2009-08-05 David Kedves <dkedves at blumsoft.eu> + + * debian/rules: + * src/hcp-app-loader.c: + * src/Makefile.am: + - Moving applet-running code to hcp-app-loader.c, it's needed + because applets should run in a separate process from HCP. + (I tried fork () too but all applets crashed somewhere... :-S ) + - Setting the WM_CLASS to some known value, + to get the applet window later. + - HCP main window-Xid passed by hpc-app.c, create a wrapper widget + for proper transiency setting in applets + * src/hcp-app.[ch]: + - Support for topping a previously opened applet + - Maintaining a list (program->running_applets) of running applets + for proper state saving + + Added some function to get applets XID by WM_CLASS: + - search_window_r, get_xid_by_wm_class, wm_class_from_so_name + + other new functions: + - hcp_app_get_plugin, cpa_child_watch, try_focues + + Dropped functions (cpa_loader doing these now): + - hcp_app_load, hcp_app_unload, hcp_app_idle_launch + + HCPApp private struct changes: + - removed handle and execute / save state function pointers + - added wm_class, pid + + Support to run multiple different applets concurrently : + by g_spawn_async, so applets aren't block the HCP anymore + * src/hcp-program.[ch]: + - run_applet RPC method always present the HCP window first + + dropped old (unused) RPC method implementations: + - save_state_applet / is_applet_running + + State saving related changes: + - removed execute from widget struct + - added running_applets list to widget struct + * src/hcp-window.[ch]: + + State saving related changes: + - Changed Focussed entry in state file to Running applets list + - On enforce-state reloading applets with the proper ordering + - Added a signal-handler to state-saving (HD sends SIGTERM on bgkill) + - On window_quit we should not save the state, but clear it + - enforce_state should be run on window show event instead of + size-allocate + 2009-07-10 Peter Aradi <peter.aradi at maemo.org> * src/hcp-app.c: Modified: projects/haf/trunk/hildon-control-panel/debian/control =================================================================== --- projects/haf/trunk/hildon-control-panel/debian/control 2009-08-05 16:07:21 UTC (rev 19056) +++ projects/haf/trunk/hildon-control-panel/debian/control 2009-08-06 06:21:23 UTC (rev 19057) @@ -8,7 +8,7 @@ Package: hildon-control-panel Section: x11 Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, ${launcher:Depends}, hildon-control-panel-l10n-mr | hildon-control-panel-l10n-mr0, osso-app-killer (>= 1.1), osso-system-lock-l10n-mr | osso-system-lock-l10n-mr0, libosso1 (>> 2.23-1) +Depends: ${shlibs:Depends}, ${misc:Depends}, ${launcher:Depends}, hildon-control-panel-l10n-mr | hildon-control-panel-l10n-mr0, osso-app-killer (>= 1.1), osso-system-lock-l10n-mr | osso-system-lock-l10n-mr0 Recommends: hildon-theme-alpha, hildon-keyboard, matchbox-window-manager Suggests: hildon-tests Conflicts: hildon-base Added: projects/haf/trunk/hildon-control-panel/src/hcp-app-loader.c =================================================================== --- projects/haf/trunk/hildon-control-panel/src/hcp-app-loader.c 2009-08-05 16:07:21 UTC (rev 19056) +++ projects/haf/trunk/hildon-control-panel/src/hcp-app-loader.c 2009-08-06 06:21:23 UTC (rev 19057) @@ -0,0 +1,172 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <libosso.h> +#include <dlfcn.h> +#include <ctype.h> +#include <string.h> +#include <signal.h> +#include <stdlib.h> + +#include <gtk/gtk.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <glib.h> +#include <glib-object.h> +#include <glib/gi18n.h> +#include <libgnomevfs/gnome-vfs.h> +#include <hildon/hildon.h> + +typedef osso_return_t (hcp_plugin_exec_f) ( + osso_context_t * osso, + gpointer data, + gboolean user_activated); + +typedef osso_return_t (hcp_plugin_save_state_f) ( + osso_context_t * osso, + gpointer data); + +typedef struct { + gchar *soname; + gchar *name; + gboolean user_activated; + void *handle; + hcp_plugin_exec_f *exec; + hcp_plugin_save_state_f *save_state; + osso_context_t *osso; + GtkWidget *parent; +} hcp_app_data; + +/* Its ugly, but i cannot pass this parameter to sighandler ... */ +hcp_app_data *plugin_data = NULL; + +static void +save_state (int signal) +{ +/* g_debug ("%s : save_state ()", plugin_data->soname); */ + if (plugin_data->save_state) + plugin_data->save_state (plugin_data->osso, NULL); + /* State saved, immediatly exiting ... */ + exit (0); +} + +static gboolean +open_plugin (hcp_app_data *plugin) +{ + gchar* full_path = NULL; + if (*plugin->soname == G_DIR_SEPARATOR) + full_path = g_strdup (plugin->soname); /* we has the full path :-) */ + else + full_path = g_build_filename (HCP_PLUGIN_DIR, plugin->soname, NULL); + + if (!(plugin->handle = dlopen (full_path, RTLD_LAZY | RTLD_LOCAL))) + { + g_warning ("Could not load the control-panel applet: %s: %s", + plugin->soname, dlerror ()); + return FALSE; + } + + if (!(plugin->exec = dlsym (plugin->handle, "execute" ))) + { + g_warning ("Could not find \"execute\" symbol in " + "control-panel applet %s: %s", plugin->soname, dlerror ()); + return FALSE; + } + + plugin->save_state = dlsym (plugin->handle, "save_state"); + + return TRUE; +} + +static void +close_plugin (hcp_app_data* plugin) +{ + if (!plugin->handle) + return; + + if (dlclose (plugin->handle)) + g_warning ("An error occured on unloading control-panel applet %s: %s", + plugin->soname, dlerror ()); + + return; +} + +static gboolean +execute_plugin (hcp_app_data *plugin) +{ + if (open_plugin (plugin)) + plugin->exec (plugin->osso, plugin->parent, plugin->user_activated); + + close_plugin (plugin); + + gtk_main_quit (); + + return FALSE; +} + +int +main (int argc, char **argv) +{ + hcp_app_data *plugin; + Window hcp; + + if (argc != 5) + { + /* + * argv[0] "cpa_laucher" + * argv[1] "/somewhere/plugin.so" + * argv[2] "Plugin name" + * argv[3] "0" / "1" -> user_activated + * argv[4] "%lu" -> CPA_parent xid + */ + g_debug ("Parameters are: %s plugin.so plugin-name" + " 0/1 [user_activated]", argv[0]); + return 1; + } + + if (!g_thread_supported ()) g_thread_init (NULL); + + hildon_gtk_init (&argc, &argv); + + gnome_vfs_init (); + + plugin = g_new0 (hcp_app_data, 1); + + plugin->soname = g_strdup (argv[1]); + plugin->name = argv[2]; + /* Set WM_CLASS ... */ +/* g_debug ("Set WM_CLASS to '%s'", argv[2]); */ + g_set_prgname (argv[2]); + gdk_set_program_class (argv[2]); + + g_set_application_name (""); + + plugin->user_activated = (argv[3][0] == '1'); + + sscanf (argv[4], "%lu", (unsigned long*) &hcp); + + /* Hack begin ... */ + plugin->parent = gtk_widget_new (GTK_TYPE_WINDOW, "type", GTK_WINDOW_TOPLEVEL, NULL); + GTK_OBJECT_FLAGS (plugin->parent) |= (GTK_REALIZED); + plugin->parent->window = gdk_window_foreign_new ((GdkNativeWindow) hcp); + /* ... hack end */ + + plugin->osso = osso_initialize (plugin->name, "1.0", FALSE, NULL); + + /* To save stating, we should handle SIGTERM */ + plugin_data = plugin; + signal (15, save_state); + + g_idle_add ((GSourceFunc) execute_plugin, plugin); + + gtk_main (); + + /* Clean up ... */ + osso_deinitialize (plugin->osso); + g_free (plugin->soname); + g_free (plugin->name); + g_free (plugin); + + return 0; +} Modified: projects/haf/trunk/hildon-control-panel/src/hcp-app.c =================================================================== --- projects/haf/trunk/hildon-control-panel/src/hcp-app.c 2009-08-05 16:07:21 UTC (rev 19056) +++ projects/haf/trunk/hildon-control-panel/src/hcp-app.c 2009-08-06 06:21:23 UTC (rev 19057) @@ -422,7 +422,9 @@ } } - if (gdk_error_trap_pop () == BadWindow) + /* On X error, should not try query the actual window tree */ + gdk_flush (); /* for trap_pop */ + if (gdk_error_trap_pop ()) return; /* Current 'w' Window is closed meanwhile ... */ /* Recursion to child windows ... */ @@ -458,30 +460,62 @@ static gboolean try_focus (HCPApp *app) { - GdkWindow *applet; - HCPProgram *program = hcp_program_get_instance (); +#ifdef HD_PROPERLY_RAISING + XClientMessageEvent xclient; +#endif + HCPProgram *program = hcp_program_get_instance (); g_return_val_if_fail (hcp_app_is_running (app), FALSE); + if (!program->running_applets || + !program->running_applets->next) + return FALSE; /* only one applet shown, no need to raising */ + if (app->priv->xid == None) app->priv->xid = get_xid_by_wm_class (app->priv->wm_class); + g_debug ("applet xid: 0x%lx", (unsigned long) app->priv->xid); + if (app->priv->xid == None) - return FALSE; /* applet closed meanwhile ... */ + return FALSE; /* plugin window isn't exists anymore ...*/ - applet = gdk_window_foreign_new ((GdkNativeWindow) app->priv->xid); - if (applet == NULL) - return FALSE; /* applet closed meanwhile ... */ +#ifndef HD_PROPERLY_RAISING + /* XXX: HACK: force restacking with quickly unmapping / mapping */ + gdk_error_trap_push (); + XUnmapWindow (GDK_DISPLAY (), app->priv->xid); + gdk_error_trap_pop (); - gdk_window_focus (applet, GDK_CURRENT_TIME); + gdk_error_trap_push (); + XMapRaised (GDK_DISPLAY (), app->priv->xid); + gdk_error_trap_pop (); +#else /* HD_PROPERLY_RAISING */ + gdk_error_trap_push (); + XRaiseWindow (GDK_DISPLAY (), app->priv->xid); + gdk_error_trap_pop (); + memset (&xclient, 0, sizeof (xclient)); + xclient.type = ClientMessage; + xclient.window = app->priv->xid; + xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"); + xclient.format = 32; + xclient.data.l[0] = 1; /* requestor type; we're an app */ + xclient.data.l[1] = 0; + xclient.data.l[2] = None; /* currently active window */ + xclient.data.l[3] = 0; + xclient.data.l[4] = 0; + + gdk_error_trap_push (); + XSendEvent (GDK_DISPLAY (), GDK_ROOT_WINDOW (), False, + SubstructureRedirectMask | SubstructureNotifyMask, + (XEvent *)&xclient); + gdk_error_trap_pop (); +#endif + /* move to the end of the list (to save proper ordering...) */ program->running_applets = g_list_remove (program->running_applets, (gconstpointer) app); program->running_applets = g_list_append (program->running_applets, (gpointer) app); - g_object_unref (applet); - return TRUE; }
- Previous message: [maemo-commits] r19056 - projects/haf/tags/libsdl1.2
- Next message: [maemo-commits] r19058 - in projects/haf/trunk/maemo-launcher: . debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]