2008-09-18 15:09:11 +00:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2008 Intel Corp.
|
|
|
|
*
|
|
|
|
* Author: Tomas Frydrych <tf@linux.intel.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2008-10-28 10:45:45 +00:00
|
|
|
#include "config.h"
|
2008-10-16 11:50:01 +00:00
|
|
|
#include "mutter-plugin-manager.h"
|
2008-09-18 15:09:11 +00:00
|
|
|
#include "prefs.h"
|
|
|
|
#include "errors.h"
|
|
|
|
#include "workspace.h"
|
|
|
|
|
|
|
|
#include <gmodule.h>
|
|
|
|
#include <string.h>
|
2008-10-16 22:02:34 +00:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/extensions/Xfixes.h>
|
|
|
|
#include <X11/extensions/shape.h>
|
|
|
|
#include <clutter/x11/clutter-x11.h>
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
static gboolean mutter_plugin_manager_reload (
|
|
|
|
MutterPluginManager *plugin_mgr);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
struct MutterPluginManager
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
MetaScreen *screen;
|
|
|
|
|
|
|
|
GList *plugins; /* TODO -- maybe use hash table */
|
|
|
|
GList *unload; /* Plugins that are disabled and pending unload */
|
|
|
|
|
|
|
|
guint idle_unload_id;
|
|
|
|
};
|
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
typedef struct MutterPluginPrivate
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
char *name;
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPluginManager *self;
|
2008-10-09 12:22:32 +00:00
|
|
|
GModule *module;
|
2008-10-13 11:23:47 +00:00
|
|
|
gulong features;
|
2008-10-17 16:10:15 +00:00
|
|
|
/* We use this to track the number of effects currently being managed
|
|
|
|
* by a plugin. Currently this is used to block unloading while effects
|
|
|
|
* are in progress. */
|
2008-10-20 12:04:46 +00:00
|
|
|
gint running;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
gboolean disabled : 1;
|
2008-10-16 11:50:01 +00:00
|
|
|
} MutterPluginPrivate;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
2008-10-16 11:50:01 +00:00
|
|
|
free_plugin_workspaces (MutterPlugin *plugin)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
l = plugin->work_areas;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
while (l)
|
|
|
|
{
|
|
|
|
g_free (l->data);
|
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin->work_areas)
|
|
|
|
g_list_free (plugin->work_areas);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin->work_areas = NULL;
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Gets work area geometry and stores it in list in the plugin.
|
|
|
|
*
|
2008-10-13 11:23:47 +00:00
|
|
|
* If the plugin list is already populated, we simply replace it (we are
|
|
|
|
* dealing with a small number of items in the list and unfrequent changes).
|
2008-09-18 15:09:11 +00:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
update_plugin_workspaces (MetaScreen *screen,
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
GList *l, *l2 = NULL;
|
|
|
|
|
|
|
|
l = meta_screen_get_workspaces (screen);
|
|
|
|
|
|
|
|
while (l)
|
|
|
|
{
|
|
|
|
MetaWorkspace *w = l->data;
|
2008-10-13 11:23:47 +00:00
|
|
|
MetaRectangle *r;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
r = g_new0 (MetaRectangle, 1);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
meta_workspace_get_work_area_all_xineramas (w, (MetaRectangle*)r);
|
|
|
|
|
|
|
|
l2 = g_list_append (l2, r);
|
|
|
|
|
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
free_plugin_workspaces (plugin);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin->work_areas = l2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* parse_disable_params:
|
|
|
|
* @params: as read from gconf, a ':' seperated list of plugin options
|
|
|
|
* @features: The mask of features the plugin advertises
|
|
|
|
*
|
|
|
|
* This function returns a new mask of features removing anything that
|
|
|
|
* the user has disabled.
|
|
|
|
*/
|
|
|
|
static gulong
|
2008-10-20 12:04:46 +00:00
|
|
|
parse_disable_params (const char *params, MutterPlugin *plugin)
|
2008-10-13 11:23:47 +00:00
|
|
|
{
|
2008-10-20 12:04:46 +00:00
|
|
|
char *p;
|
|
|
|
gulong features = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Feature flags: identify events that the plugin can handle; a plugin can
|
|
|
|
* handle one or more events.
|
|
|
|
*/
|
|
|
|
if (plugin->minimize)
|
|
|
|
features |= MUTTER_PLUGIN_MINIMIZE;
|
|
|
|
|
|
|
|
if (plugin->maximize)
|
|
|
|
features |= MUTTER_PLUGIN_MAXIMIZE;
|
|
|
|
|
|
|
|
if (plugin->unmaximize)
|
|
|
|
features |= MUTTER_PLUGIN_UNMAXIMIZE;
|
|
|
|
|
|
|
|
if (plugin->map)
|
|
|
|
features |= MUTTER_PLUGIN_MAP;
|
|
|
|
|
|
|
|
if (plugin->destroy)
|
|
|
|
features |= MUTTER_PLUGIN_DESTROY;
|
|
|
|
|
|
|
|
if (plugin->switch_workspace)
|
|
|
|
features |= MUTTER_PLUGIN_SWITCH_WORKSPACE;
|
2008-10-16 22:02:34 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
if (!params)
|
|
|
|
return features;
|
|
|
|
|
|
|
|
if ((p = strstr (params, "disable:")))
|
|
|
|
{
|
|
|
|
gchar *d = g_strdup (p+8);
|
|
|
|
|
|
|
|
p = strchr (d, ';');
|
|
|
|
|
|
|
|
if (p)
|
|
|
|
*p = 0;
|
|
|
|
|
|
|
|
if (strstr (d, "minimize"))
|
2008-10-16 11:50:01 +00:00
|
|
|
features &= ~ MUTTER_PLUGIN_MINIMIZE;
|
2008-10-13 11:23:47 +00:00
|
|
|
|
|
|
|
if (strstr (d, "maximize"))
|
2008-10-16 11:50:01 +00:00
|
|
|
features &= ~ MUTTER_PLUGIN_MAXIMIZE;
|
2008-10-13 11:23:47 +00:00
|
|
|
|
|
|
|
if (strstr (d, "unmaximize"))
|
2008-10-16 11:50:01 +00:00
|
|
|
features &= ~ MUTTER_PLUGIN_UNMAXIMIZE;
|
2008-10-13 11:23:47 +00:00
|
|
|
|
|
|
|
if (strstr (d, "map"))
|
2008-10-16 11:50:01 +00:00
|
|
|
features &= ~ MUTTER_PLUGIN_MAP;
|
2008-10-13 11:23:47 +00:00
|
|
|
|
|
|
|
if (strstr (d, "destroy"))
|
2008-10-16 11:50:01 +00:00
|
|
|
features &= ~ MUTTER_PLUGIN_DESTROY;
|
2008-10-13 11:23:47 +00:00
|
|
|
|
|
|
|
if (strstr (d, "switch-workspace"))
|
2008-10-16 11:50:01 +00:00
|
|
|
features &= ~MUTTER_PLUGIN_SWITCH_WORKSPACE;
|
2008-10-13 11:23:47 +00:00
|
|
|
|
|
|
|
g_free (d);
|
|
|
|
}
|
|
|
|
return features;
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Checks that the plugin is compatible with the WM and sets up the plugin
|
|
|
|
* struct.
|
|
|
|
*/
|
2008-10-16 11:50:01 +00:00
|
|
|
static MutterPlugin *
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_load (MutterPluginManager *plugin_mgr,
|
|
|
|
GModule *module,
|
|
|
|
const gchar *params)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
if (g_module_symbol (module, "mutter_plugin", (gpointer *)&plugin))
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin->version_api == METACITY_CLUTTER_PLUGIN_API_VERSION)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPluginPrivate *priv;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
priv = g_new0 (MutterPluginPrivate, 1);
|
2008-10-13 11:23:47 +00:00
|
|
|
priv->name = _(plugin->name);
|
|
|
|
priv->module = module;
|
|
|
|
priv->self = plugin_mgr;
|
|
|
|
|
|
|
|
/* FIXME: instead of hanging private data of the plugin descriptor
|
|
|
|
* we could make the descriptor const if we were to hang it off
|
|
|
|
* a plugin manager structure */
|
|
|
|
plugin->manager_private = priv;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
update_plugin_workspaces (plugin_mgr->screen, plugin);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-20 12:04:46 +00:00
|
|
|
priv->features = parse_disable_params (params, plugin);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check for and run the plugin init function.
|
|
|
|
*/
|
2008-10-13 11:23:47 +00:00
|
|
|
if (!plugin->do_init || !(plugin->do_init (params)))
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
g_free (priv);
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
free_plugin_workspaces (plugin);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
meta_verbose ("Loaded plugin [%s]\n", priv->name);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
return plugin;
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Attempst to unload a plugin; returns FALSE if plugin cannot be unloaded at
|
|
|
|
* present (e.g., and effect is in progress) and should be scheduled for
|
|
|
|
* removal later.
|
|
|
|
*/
|
|
|
|
static gboolean
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_unload (MutterPlugin *plugin)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPluginPrivate *priv;
|
2008-09-18 15:09:11 +00:00
|
|
|
GModule *module;
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
priv = plugin->manager_private;
|
2008-09-18 15:09:11 +00:00
|
|
|
module = priv->module;
|
|
|
|
|
2008-10-17 16:10:15 +00:00
|
|
|
if (priv->running)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
priv->disabled = TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (priv);
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin->manager_private = NULL;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
g_module_close (module);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Iddle callback to remove plugins that could not be removed directly and are
|
|
|
|
* pending for removal.
|
|
|
|
*/
|
|
|
|
static gboolean
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_idle_unload (MutterPluginManager *plugin_mgr)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
GList *l = plugin_mgr->unload;
|
2008-09-18 15:09:11 +00:00
|
|
|
gboolean dont_remove = TRUE;
|
|
|
|
|
|
|
|
while (l)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin = l->data;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
if (mutter_plugin_unload (plugin))
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
/* Remove from list */
|
|
|
|
GList *p = l->prev;
|
|
|
|
GList *n = l->next;
|
|
|
|
|
|
|
|
if (!p)
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr->unload = n;
|
2008-09-18 15:09:11 +00:00
|
|
|
else
|
|
|
|
p->next = n;
|
|
|
|
|
|
|
|
if (n)
|
|
|
|
n->prev = p;
|
|
|
|
|
|
|
|
g_list_free_1 (l);
|
|
|
|
|
|
|
|
l = n;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
if (!plugin_mgr->unload)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
/* If no more unloads are pending, remove the handler as well */
|
|
|
|
dont_remove = FALSE;
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr->idle_unload_id = 0;
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return dont_remove;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Unloads all plugins
|
|
|
|
*/
|
|
|
|
static void
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_unload (MutterPluginManager *plugin_mgr)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
GList *plugins = plugin_mgr->plugins;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
while (plugins)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin = plugins->data;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
/* If the plugin could not be removed, move it to the unload list */
|
2008-10-16 11:50:01 +00:00
|
|
|
if (!mutter_plugin_unload (plugin))
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr->unload = g_list_prepend (plugin_mgr->unload, plugin);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
if (!plugin_mgr->idle_unload_id)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr->idle_unload_id = g_idle_add ((GSourceFunc)
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_manager_idle_unload,
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
plugins = plugins->next;
|
|
|
|
}
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
g_list_free (plugin_mgr->plugins);
|
|
|
|
plugin_mgr->plugins = NULL;
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
prefs_changed_callback (MetaPreference pref,
|
|
|
|
void *data)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPluginManager *plugin_mgr = data;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
if (pref == META_PREF_CLUTTER_PLUGINS)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_manager_reload (plugin_mgr);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
else if (pref == META_PREF_NUM_WORKSPACES)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_manager_update_workspaces (plugin_mgr);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Loads all plugins listed in gconf registry.
|
|
|
|
*/
|
|
|
|
static gboolean
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_manager_load (MutterPluginManager *plugin_mgr)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-29 10:28:48 +00:00
|
|
|
const gchar *dpath = MUTTER_PLUGIN_DIR "/";
|
2008-10-09 14:33:06 +00:00
|
|
|
GSList *plugins, *fallback = NULL;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
plugins = meta_prefs_get_clutter_plugins ();
|
|
|
|
|
2008-10-09 14:33:06 +00:00
|
|
|
if (!plugins)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* If no plugins are specified, try to load the default plugin.
|
|
|
|
*/
|
|
|
|
fallback = g_slist_append (fallback, "default");
|
|
|
|
plugins = fallback;
|
|
|
|
}
|
|
|
|
|
2008-09-18 15:09:11 +00:00
|
|
|
while (plugins)
|
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
gchar *plugin_string;
|
2008-09-18 15:09:11 +00:00
|
|
|
gchar *params;
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_string = g_strdup (plugins->data);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin_string)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
GModule *plugin;
|
2008-09-18 15:09:11 +00:00
|
|
|
gchar *path;
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
params = strchr (plugin_string, ':');
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
if (params)
|
|
|
|
{
|
|
|
|
*params = 0;
|
|
|
|
++params;
|
|
|
|
}
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
path = g_strconcat (dpath, plugin_string, ".so", NULL);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-31 08:08:08 +00:00
|
|
|
if ((plugin = g_module_open (path, G_MODULE_BIND_LOCAL)))
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *p;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
if ((p = mutter_plugin_load (plugin_mgr, plugin, params)))
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, p);
|
2008-09-18 15:09:11 +00:00
|
|
|
else
|
2008-10-07 15:29:03 +00:00
|
|
|
{
|
2008-10-29 18:40:51 +00:00
|
|
|
g_message ("Plugin load for [%s] failed", path);
|
2008-10-13 11:23:47 +00:00
|
|
|
g_module_close (plugin);
|
2008-10-07 15:29:03 +00:00
|
|
|
}
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
2008-10-07 15:29:03 +00:00
|
|
|
else
|
2008-10-29 18:40:51 +00:00
|
|
|
g_message ("Unable to load plugin [%s]: %s", path, g_module_error());
|
2008-10-28 11:30:29 +00:00
|
|
|
|
2008-09-18 15:09:11 +00:00
|
|
|
g_free (path);
|
2008-10-13 11:23:47 +00:00
|
|
|
g_free (plugin_string);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
plugins = plugins->next;
|
|
|
|
}
|
|
|
|
|
2008-10-09 14:33:06 +00:00
|
|
|
|
|
|
|
if (fallback)
|
|
|
|
g_slist_free (fallback);
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin_mgr->plugins != NULL)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
meta_prefs_add_listener (prefs_changed_callback, plugin_mgr);
|
2008-09-18 15:09:11 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reloads all plugins
|
|
|
|
*/
|
|
|
|
static gboolean
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
/* TODO -- brute force; should we build a list of plugins to load and list of
|
|
|
|
* plugins to unload? We are probably not going to have large numbers of
|
|
|
|
* plugins loaded at the same time, so it might not be worth it.
|
|
|
|
*/
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_manager_unload (plugin_mgr);
|
|
|
|
return mutter_plugin_manager_load (plugin_mgr);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_init (MutterPluginManager *plugin_mgr)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
return mutter_plugin_manager_load (plugin_mgr);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_update_workspace (MutterPluginManager *plugin_mgr,
|
|
|
|
MetaWorkspace *workspace)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
GList *l;
|
2008-10-13 11:23:47 +00:00
|
|
|
gint index;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
index = meta_workspace_index (workspace);
|
|
|
|
l = plugin_mgr->plugins;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
while (l)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin = l->data;
|
2008-10-13 11:23:47 +00:00
|
|
|
MetaRectangle *rect = g_list_nth_data (plugin->work_areas, index);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
if (rect)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
meta_workspace_get_work_area_all_xineramas (workspace, rect);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Something not entirely right; redo the whole thing */
|
2008-10-13 11:23:47 +00:00
|
|
|
update_plugin_workspaces (plugin_mgr->screen, plugin);
|
2008-09-18 15:09:11 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_update_workspaces (MutterPluginManager *plugin_mgr)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
l = plugin_mgr->plugins;
|
2008-09-18 15:09:11 +00:00
|
|
|
while (l)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin = l->data;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
update_plugin_workspaces (plugin_mgr->screen, plugin);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPluginManager *
|
|
|
|
mutter_plugin_manager_new (MetaScreen *screen)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPluginManager *plugin_mgr;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
plugin_mgr = g_new0 (MutterPluginManager, 1);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr->screen = screen;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
if (!mutter_plugin_manager_init (plugin_mgr))
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
g_free (plugin_mgr);
|
|
|
|
plugin_mgr = NULL;
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
return plugin_mgr;
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
|
2008-10-07 15:29:03 +00:00
|
|
|
static void
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr,
|
|
|
|
MutterWindow *actor,
|
|
|
|
unsigned long events)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
GList *l = plugin_mgr->plugins;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
while (l)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin = l->data;
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
if (!priv->disabled
|
2008-10-20 12:04:46 +00:00
|
|
|
&& (priv->features & events)
|
2008-10-13 11:23:47 +00:00
|
|
|
&& plugin->kill_effect)
|
|
|
|
plugin->kill_effect (actor, events);
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ALL_BUT_SWITCH \
|
2008-10-16 11:50:01 +00:00
|
|
|
MUTTER_PLUGIN_ALL_EFFECTS & \
|
|
|
|
~MUTTER_PLUGIN_SWITCH_WORKSPACE
|
2008-09-18 15:09:11 +00:00
|
|
|
/*
|
|
|
|
* Public method that the compositor hooks into for events that require
|
|
|
|
* no additional parameters.
|
|
|
|
*
|
|
|
|
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
|
|
|
|
* if the return value is FALSE, there will be no subsequent call to the
|
|
|
|
* manager completed() callback, and the compositor must ensure that any
|
|
|
|
* appropriate post-effect cleanup is carried out.
|
|
|
|
*/
|
|
|
|
gboolean
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_event_simple (MutterPluginManager *plugin_mgr,
|
|
|
|
MutterWindow *actor,
|
|
|
|
unsigned long event)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
GList *l = plugin_mgr->plugins;
|
2008-09-18 15:09:11 +00:00
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
while (l)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin = l->data;
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-20 12:04:46 +00:00
|
|
|
if (!priv->disabled && (priv->features & event))
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
retval = TRUE;
|
|
|
|
|
|
|
|
switch (event)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
case MUTTER_PLUGIN_MINIMIZE:
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin->minimize)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_manager_kill_effect (
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr,
|
|
|
|
actor,
|
|
|
|
ALL_BUT_SWITCH);
|
|
|
|
|
2008-10-17 16:10:15 +00:00
|
|
|
priv->running++;
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin->minimize (actor);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
break;
|
2008-10-16 11:50:01 +00:00
|
|
|
case MUTTER_PLUGIN_MAP:
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin->map)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_manager_kill_effect (
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr,
|
|
|
|
actor,
|
|
|
|
ALL_BUT_SWITCH);
|
|
|
|
|
2008-10-17 16:10:15 +00:00
|
|
|
priv->running++;
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin->map (actor);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
break;
|
2008-10-16 11:50:01 +00:00
|
|
|
case MUTTER_PLUGIN_DESTROY:
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin->destroy)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-17 16:10:15 +00:00
|
|
|
priv->running++;
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin->destroy (actor);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_warning ("Incorrect handler called for event %lu", event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2008-10-07 08:01:58 +00:00
|
|
|
* The public method that the compositor hooks into for maximize and unmaximize
|
|
|
|
* events.
|
2008-09-18 15:09:11 +00:00
|
|
|
*
|
|
|
|
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
|
|
|
|
* if the return value is FALSE, there will be no subsequent call to the
|
|
|
|
* manager completed() callback, and the compositor must ensure that any
|
|
|
|
* appropriate post-effect cleanup is carried out.
|
|
|
|
*/
|
|
|
|
gboolean
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_event_maximize (MutterPluginManager *plugin_mgr,
|
|
|
|
MutterWindow *actor,
|
|
|
|
unsigned long event,
|
|
|
|
gint target_x,
|
|
|
|
gint target_y,
|
|
|
|
gint target_width,
|
|
|
|
gint target_height)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
GList *l = plugin_mgr->plugins;
|
2008-09-18 15:09:11 +00:00
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
while (l)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin = l->data;
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
2008-10-20 12:04:46 +00:00
|
|
|
if (!priv->disabled && (priv->features & event))
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
retval = TRUE;
|
|
|
|
|
|
|
|
switch (event)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
case MUTTER_PLUGIN_MAXIMIZE:
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin->maximize)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_manager_kill_effect (
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr,
|
|
|
|
actor,
|
|
|
|
ALL_BUT_SWITCH);
|
|
|
|
|
|
|
|
plugin->maximize (actor,
|
2008-10-07 08:01:58 +00:00
|
|
|
target_x, target_y,
|
|
|
|
target_width, target_height);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
break;
|
2008-10-16 11:50:01 +00:00
|
|
|
case MUTTER_PLUGIN_UNMAXIMIZE:
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin->unmaximize)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_manager_kill_effect (
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr,
|
|
|
|
actor,
|
|
|
|
ALL_BUT_SWITCH);
|
|
|
|
plugin->unmaximize (actor,
|
2008-10-07 08:01:58 +00:00
|
|
|
target_x, target_y,
|
|
|
|
target_width, target_height);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_warning ("Incorrect handler called for event %lu", event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The public method that the compositor hooks into for desktop switching.
|
|
|
|
*
|
|
|
|
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
|
|
|
|
* if the return value is FALSE, there will be no subsequent call to the
|
|
|
|
* manager completed() callback, and the compositor must ensure that any
|
|
|
|
* appropriate post-effect cleanup is carried out.
|
|
|
|
*/
|
|
|
|
gboolean
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_switch_workspace (MutterPluginManager *plugin_mgr,
|
|
|
|
const GList **actors,
|
|
|
|
gint from,
|
|
|
|
gint to,
|
|
|
|
MetaMotionDirection direction)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
GList *l = plugin_mgr->plugins;
|
2008-09-18 15:09:11 +00:00
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
while (l)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin = l->data;
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
2008-09-18 15:09:11 +00:00
|
|
|
|
|
|
|
if (!priv->disabled &&
|
2008-10-20 12:04:46 +00:00
|
|
|
(priv->features & MUTTER_PLUGIN_SWITCH_WORKSPACE) &&
|
2008-09-18 15:09:11 +00:00
|
|
|
(actors && *actors))
|
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin->switch_workspace)
|
2008-09-18 15:09:11 +00:00
|
|
|
{
|
|
|
|
retval = TRUE;
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_plugin_manager_kill_effect (
|
2008-10-13 11:23:47 +00:00
|
|
|
plugin_mgr,
|
2008-10-16 11:50:01 +00:00
|
|
|
MUTTER_WINDOW ((*actors)->data),
|
|
|
|
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
2008-10-13 11:23:47 +00:00
|
|
|
|
|
|
|
plugin->switch_workspace (actors, from, to, direction);
|
2008-09-18 15:09:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
2008-10-02 11:16:15 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The public method that the compositor hooks into for desktop switching.
|
|
|
|
*
|
|
|
|
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
|
|
|
|
* if the return value is FALSE, there will be no subsequent call to the
|
|
|
|
* manager completed() callback, and the compositor must ensure that any
|
|
|
|
* appropriate post-effect cleanup is carried out.
|
|
|
|
*/
|
|
|
|
gboolean
|
2008-11-03 09:59:01 +00:00
|
|
|
mutter_plugin_manager_xevent_filter (MutterPluginManager *plugin_mgr,
|
|
|
|
XEvent *xev)
|
2008-10-02 11:16:15 +00:00
|
|
|
{
|
2008-10-07 15:29:03 +00:00
|
|
|
GList *l;
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
if (!plugin_mgr)
|
2008-10-07 15:29:03 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
l = plugin_mgr->plugins;
|
2008-10-02 11:16:15 +00:00
|
|
|
|
|
|
|
while (l)
|
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPlugin *plugin = l->data;
|
2008-10-02 11:16:15 +00:00
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin->xevent_filter)
|
2008-10-02 11:16:15 +00:00
|
|
|
{
|
2008-10-13 11:23:47 +00:00
|
|
|
if (plugin->xevent_filter (xev) == TRUE)
|
2008-10-02 11:16:15 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-10-09 12:22:32 +00:00
|
|
|
|
|
|
|
/*
|
2008-10-16 11:50:01 +00:00
|
|
|
* Public accessors for plugins, exposed from mutter-plugin.h
|
2008-10-09 12:22:32 +00:00
|
|
|
*/
|
|
|
|
ClutterActor *
|
2008-10-16 22:02:34 +00:00
|
|
|
mutter_plugin_get_overlay_group (MutterPlugin *plugin)
|
2008-10-09 12:22:32 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
MutterPluginManager *plugin_mgr = priv->self;
|
2008-10-09 12:22:32 +00:00
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
return mutter_get_overlay_group_for_screen (plugin_mgr->screen);
|
2008-10-09 12:22:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ClutterActor *
|
2008-10-16 22:02:34 +00:00
|
|
|
mutter_plugin_get_stage (MutterPlugin *plugin)
|
2008-10-09 12:22:32 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
MutterPluginManager *plugin_mgr = priv->self;
|
2008-10-09 12:22:32 +00:00
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
return mutter_get_stage_for_screen (plugin_mgr->screen);
|
2008-10-09 12:22:32 +00:00
|
|
|
}
|
2008-10-10 10:38:00 +00:00
|
|
|
|
2008-10-28 11:30:29 +00:00
|
|
|
ClutterActor *
|
|
|
|
mutter_plugin_get_window_group (MutterPlugin *plugin)
|
|
|
|
{
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
MutterPluginManager *plugin_mgr = priv->self;
|
|
|
|
|
|
|
|
return mutter_get_window_group_for_screen (plugin_mgr->screen);
|
|
|
|
}
|
|
|
|
|
2008-10-10 10:38:00 +00:00
|
|
|
void
|
2008-10-16 22:02:34 +00:00
|
|
|
mutter_plugin_effect_completed (MutterPlugin *plugin,
|
|
|
|
MutterWindow *actor,
|
|
|
|
unsigned long event)
|
2008-10-10 10:38:00 +00:00
|
|
|
{
|
2008-10-17 16:10:15 +00:00
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
|
|
|
|
priv->running--;
|
|
|
|
|
2008-10-10 10:38:00 +00:00
|
|
|
if (!actor)
|
|
|
|
{
|
|
|
|
g_warning ("Plugin [%s] passed NULL for actor!",
|
|
|
|
(plugin && plugin->name) ? plugin->name : "unknown");
|
|
|
|
}
|
|
|
|
|
2008-10-16 11:50:01 +00:00
|
|
|
mutter_window_effect_completed (actor, event);
|
2008-10-10 10:38:00 +00:00
|
|
|
}
|
|
|
|
|
2008-10-13 11:23:47 +00:00
|
|
|
void
|
2008-10-16 22:02:34 +00:00
|
|
|
mutter_plugin_query_screen_size (MutterPlugin *plugin,
|
|
|
|
int *width,
|
|
|
|
int *height)
|
2008-10-13 11:23:47 +00:00
|
|
|
{
|
2008-10-16 11:50:01 +00:00
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
MutterPluginManager *plugin_mgr = priv->self;
|
2008-10-13 11:23:47 +00:00
|
|
|
|
|
|
|
meta_screen_get_size (plugin_mgr->screen, width, height);
|
|
|
|
}
|
|
|
|
|
2008-10-16 22:02:34 +00:00
|
|
|
void
|
|
|
|
mutter_plugin_set_stage_reactive (MutterPlugin *plugin,
|
|
|
|
gboolean reactive)
|
|
|
|
{
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
MutterPluginManager *mgr = priv->self;
|
|
|
|
MetaDisplay *display = meta_screen_get_display (mgr->screen);
|
|
|
|
Display *xdpy = meta_display_get_xdisplay (display);
|
|
|
|
Window xstage, xoverlay;
|
|
|
|
ClutterActor *stage;
|
|
|
|
|
|
|
|
stage = mutter_get_stage_for_screen (mgr->screen);
|
|
|
|
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
|
|
|
xoverlay = mutter_get_overlay_window (mgr->screen);
|
|
|
|
|
|
|
|
static XserverRegion region = None;
|
|
|
|
|
|
|
|
if (region == None)
|
|
|
|
region = XFixesCreateRegion (xdpy, NULL, 0);
|
|
|
|
|
|
|
|
if (reactive)
|
|
|
|
{
|
|
|
|
XFixesSetWindowShapeRegion (xdpy, xstage,
|
|
|
|
ShapeInput, 0, 0, None);
|
|
|
|
XFixesSetWindowShapeRegion (xdpy, xoverlay,
|
|
|
|
ShapeInput, 0, 0, None);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
XFixesSetWindowShapeRegion (xdpy, xstage,
|
|
|
|
ShapeInput, 0, 0, region);
|
|
|
|
XFixesSetWindowShapeRegion (xdpy, xoverlay,
|
|
|
|
ShapeInput, 0, 0, region);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
mutter_plugin_set_stage_input_area (MutterPlugin *plugin,
|
|
|
|
gint x, gint y, gint width, gint height)
|
|
|
|
{
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
MutterPluginManager *mgr = priv->self;
|
|
|
|
MetaDisplay *display = meta_screen_get_display (mgr->screen);
|
|
|
|
Display *xdpy = meta_display_get_xdisplay (display);
|
|
|
|
Window xstage, xoverlay;
|
|
|
|
ClutterActor *stage;
|
|
|
|
XRectangle rect;
|
|
|
|
XserverRegion region;
|
|
|
|
|
|
|
|
stage = mutter_get_stage_for_screen (mgr->screen);
|
|
|
|
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
|
|
|
xoverlay = mutter_get_overlay_window (mgr->screen);
|
|
|
|
|
|
|
|
rect.x = x;
|
|
|
|
rect.y = y;
|
|
|
|
rect.width = width;
|
|
|
|
rect.height = height;
|
|
|
|
|
|
|
|
region = XFixesCreateRegion (xdpy, &rect, 1);
|
|
|
|
|
|
|
|
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
|
|
|
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
2008-10-29 13:03:03 +00:00
|
|
|
|
|
|
|
XFixesDestroyRegion (xdpy, region);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
mutter_plugin_set_stage_input_region (MutterPlugin *plugin,
|
|
|
|
XserverRegion region)
|
|
|
|
{
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
MutterPluginManager *mgr = priv->self;
|
|
|
|
MetaDisplay *display = meta_screen_get_display (mgr->screen);
|
|
|
|
Display *xdpy = meta_display_get_xdisplay (display);
|
|
|
|
Window xstage, xoverlay;
|
|
|
|
ClutterActor *stage;
|
|
|
|
|
|
|
|
stage = mutter_get_stage_for_screen (mgr->screen);
|
|
|
|
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
|
|
|
xoverlay = mutter_get_overlay_window (mgr->screen);
|
|
|
|
|
|
|
|
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
|
|
|
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
2008-10-16 22:02:34 +00:00
|
|
|
}
|
2008-10-24 09:07:24 +00:00
|
|
|
|
|
|
|
GList *
|
|
|
|
mutter_plugin_get_windows (MutterPlugin *plugin)
|
|
|
|
{
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
MutterPluginManager *plugin_mgr = priv->self;
|
|
|
|
|
|
|
|
return mutter_get_windows (plugin_mgr->screen);
|
|
|
|
}
|
|
|
|
|
2008-10-29 13:27:35 +00:00
|
|
|
Display *
|
|
|
|
mutter_plugin_get_xdisplay (MutterPlugin *plugin)
|
|
|
|
{
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
MutterPluginManager *mgr = priv->self;
|
|
|
|
MetaDisplay *display = meta_screen_get_display (mgr->screen);
|
|
|
|
Display *xdpy = meta_display_get_xdisplay (display);
|
|
|
|
|
|
|
|
return xdpy;
|
|
|
|
}
|
2008-11-03 10:07:12 +00:00
|
|
|
|
|
|
|
MetaScreen *
|
|
|
|
mutter_plugin_get_screen (MutterPlugin *plugin)
|
|
|
|
{
|
|
|
|
MutterPluginPrivate *priv = plugin->manager_private;
|
|
|
|
MutterPluginManager *mgr = priv->self;
|
|
|
|
|
|
|
|
return mgr->screen;
|
|
|
|
}
|
|
|
|
|