mirror of
https://github.com/brl/mutter.git
synced 2024-12-25 20:32:16 +00:00
Merge branch 'moblin-plugin' into clutter
Conflicts: src/compositor/clutter/compositor-clutter-plugin-manager.c src/compositor/mutter/plugins/Makefile.am src/compositor/mutter/plugins/moblin.c src/include/compositor-clutter-plugin.h src/include/compositor-clutter.h
This commit is contained in:
commit
dc33ad1adf
780
src/compositor/clutter/compositor-clutter-plugin-manager.c
Normal file
780
src/compositor/clutter/compositor-clutter-plugin-manager.c
Normal file
@ -0,0 +1,780 @@
|
||||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#include "compositor-clutter-plugin-manager.h"
|
||||
#include "compositor-clutter.h"
|
||||
#include "prefs.h"
|
||||
#include "errors.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
static gboolean meta_compositor_clutter_plugin_manager_reload (MetaCompositorClutterPluginManager *mgr);
|
||||
|
||||
struct MetaCompositorClutterPluginManager
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
GList *plugins; /* TODO -- maybe use hash table */
|
||||
GList *unload; /* Plugins that are disabled and pending unload */
|
||||
|
||||
guint idle_unload_id;
|
||||
};
|
||||
|
||||
typedef struct MetaCompositorClutterPluginPrivate MetaCompositorClutterPluginPrivate;
|
||||
|
||||
struct MetaCompositorClutterPluginPrivate
|
||||
{
|
||||
MetaCompositorClutterPluginManager *self;
|
||||
GModule *module;
|
||||
|
||||
gboolean disabled : 1;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
free_plugin_workspaces (MetaCompositorClutterPlugin *plg)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
l = plg->work_areas;
|
||||
|
||||
while (l)
|
||||
{
|
||||
g_free (l->data);
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
if (plg->work_areas)
|
||||
g_list_free (plg->work_areas);
|
||||
|
||||
plg->work_areas = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets work area geometry and stores it in list in the plugin.
|
||||
*
|
||||
* If the plg list is already populated, we simply replace it (we are dealing
|
||||
* with a small number of items in the list and unfrequent changes).
|
||||
*/
|
||||
static void
|
||||
update_plugin_workspaces (MetaScreen *screen,
|
||||
MetaCompositorClutterPlugin *plg)
|
||||
{
|
||||
GList *l, *l2 = NULL;
|
||||
|
||||
l = meta_screen_get_workspaces (screen);
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaWorkspace *w = l->data;
|
||||
PluginWorkspaceRectangle *r;
|
||||
|
||||
r = g_new0 (PluginWorkspaceRectangle, 1);
|
||||
|
||||
meta_workspace_get_work_area_all_xineramas (w, (MetaRectangle*)r);
|
||||
|
||||
l2 = g_list_append (l2, r);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
free_plugin_workspaces (plg);
|
||||
|
||||
plg->work_areas = l2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks that the plugin is compatible with the WM and sets up the plugin
|
||||
* struct.
|
||||
*/
|
||||
static MetaCompositorClutterPlugin *
|
||||
meta_compositor_clutter_plugin_load (MetaCompositorClutterPluginManager *mgr,
|
||||
GModule *module,
|
||||
const gchar *params)
|
||||
{
|
||||
MetaCompositorClutterPlugin *plg;
|
||||
|
||||
if (g_module_symbol (module,
|
||||
META_COMPOSITOR_CLUTTER_PLUGIN_STRUCT_NAME,
|
||||
(gpointer *)&plg))
|
||||
{
|
||||
if (plg->version_api == METACITY_CLUTTER_PLUGIN_API_VERSION)
|
||||
{
|
||||
MetaCompositorClutterPluginPrivate *priv;
|
||||
gboolean (*init_func) (void);
|
||||
|
||||
priv = g_new0 (MetaCompositorClutterPluginPrivate, 1);
|
||||
plg->params = g_strdup (params);
|
||||
plg->manager_private = priv;
|
||||
priv->module = module;
|
||||
priv->self = mgr;
|
||||
|
||||
meta_screen_get_size (mgr->screen,
|
||||
&plg->screen_width, &plg->screen_height);
|
||||
|
||||
update_plugin_workspaces (mgr->screen, plg);
|
||||
|
||||
/*
|
||||
* Check for and run the plugin init function.
|
||||
*/
|
||||
if (g_module_symbol (module,
|
||||
META_COMPOSITOR_CLUTTER_PLUGIN_INIT_FUNC_NAME,
|
||||
(gpointer *)&init_func) &&
|
||||
!init_func())
|
||||
{
|
||||
g_free (plg->params);
|
||||
g_free (priv);
|
||||
|
||||
free_plugin_workspaces (plg);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
meta_verbose ("Loaded plugin [%s]\n", plg->name);
|
||||
|
||||
return plg;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
meta_compositor_clutter_plugin_unload (MetaCompositorClutterPlugin *plg)
|
||||
{
|
||||
MetaCompositorClutterPluginPrivate *priv;
|
||||
GModule *module;
|
||||
|
||||
priv = plg->manager_private;
|
||||
module = priv->module;
|
||||
|
||||
if (plg->running)
|
||||
{
|
||||
priv->disabled = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (plg->params);
|
||||
plg->params = NULL;
|
||||
|
||||
g_free (priv);
|
||||
plg->manager_private = NULL;
|
||||
|
||||
g_module_close (module);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iddle callback to remove plugins that could not be removed directly and are
|
||||
* pending for removal.
|
||||
*/
|
||||
static gboolean
|
||||
meta_compositor_clutter_plugin_manager_idle_unload (MetaCompositorClutterPluginManager *mgr)
|
||||
{
|
||||
GList *l = mgr->unload;
|
||||
gboolean dont_remove = TRUE;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaCompositorClutterPlugin *plg = l->data;
|
||||
|
||||
if (meta_compositor_clutter_plugin_unload (plg))
|
||||
{
|
||||
/* Remove from list */
|
||||
GList *p = l->prev;
|
||||
GList *n = l->next;
|
||||
|
||||
if (!p)
|
||||
mgr->unload = n;
|
||||
else
|
||||
p->next = n;
|
||||
|
||||
if (n)
|
||||
n->prev = p;
|
||||
|
||||
g_list_free_1 (l);
|
||||
|
||||
l = n;
|
||||
}
|
||||
else
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
if (!mgr->unload)
|
||||
{
|
||||
/* If no more unloads are pending, remove the handler as well */
|
||||
dont_remove = FALSE;
|
||||
mgr->idle_unload_id = 0;
|
||||
}
|
||||
|
||||
return dont_remove;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unloads all plugins
|
||||
*/
|
||||
static void
|
||||
meta_compositor_clutter_plugin_manager_unload (MetaCompositorClutterPluginManager *mgr)
|
||||
{
|
||||
GList *plugins = mgr->plugins;
|
||||
|
||||
while (plugins)
|
||||
{
|
||||
MetaCompositorClutterPlugin *plg = plugins->data;
|
||||
|
||||
/* If the plugin could not be removed, move it to the unload list */
|
||||
if (!meta_compositor_clutter_plugin_unload (plg))
|
||||
{
|
||||
mgr->unload = g_list_prepend (mgr->unload, plg);
|
||||
|
||||
if (!mgr->idle_unload_id)
|
||||
{
|
||||
mgr->idle_unload_id = g_idle_add ((GSourceFunc)
|
||||
meta_compositor_clutter_plugin_manager_idle_unload,
|
||||
mgr);
|
||||
}
|
||||
}
|
||||
|
||||
plugins = plugins->next;
|
||||
}
|
||||
|
||||
g_list_free (mgr->plugins);
|
||||
mgr->plugins = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_changed_callback (MetaPreference pref,
|
||||
void *data)
|
||||
{
|
||||
MetaCompositorClutterPluginManager *mgr = data;
|
||||
|
||||
if (pref == META_PREF_CLUTTER_PLUGINS)
|
||||
{
|
||||
meta_compositor_clutter_plugin_manager_reload (mgr);
|
||||
}
|
||||
else if (pref == META_PREF_NUM_WORKSPACES)
|
||||
{
|
||||
meta_compositor_clutter_plugin_manager_update_workspaces (mgr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads all plugins listed in gconf registry.
|
||||
*/
|
||||
static gboolean
|
||||
meta_compositor_clutter_plugin_manager_load (MetaCompositorClutterPluginManager *mgr)
|
||||
{
|
||||
const gchar *dpath = METACITY_PKGLIBDIR "/plugins/clutter/";
|
||||
GSList *plugins, *fallback = NULL;
|
||||
|
||||
plugins = meta_prefs_get_clutter_plugins ();
|
||||
|
||||
if (!plugins)
|
||||
{
|
||||
/*
|
||||
* If no plugins are specified, try to load the default plugin.
|
||||
*/
|
||||
fallback = g_slist_append (fallback, "default");
|
||||
plugins = fallback;
|
||||
}
|
||||
|
||||
while (plugins)
|
||||
{
|
||||
gchar *plg_string;
|
||||
gchar *params;
|
||||
|
||||
plg_string = g_strdup (plugins->data);
|
||||
|
||||
if (plg_string)
|
||||
{
|
||||
GModule *plg;
|
||||
gchar *path;
|
||||
|
||||
params = strchr (plg_string, ':');
|
||||
|
||||
if (params)
|
||||
{
|
||||
*params = 0;
|
||||
++params;
|
||||
}
|
||||
|
||||
path = g_strconcat (dpath, plg_string, ".so", NULL);
|
||||
|
||||
if ((plg = g_module_open (path, 0)))
|
||||
{
|
||||
MetaCompositorClutterPlugin *p;
|
||||
|
||||
if ((p = meta_compositor_clutter_plugin_load (mgr,
|
||||
plg, params)))
|
||||
mgr->plugins = g_list_prepend (mgr->plugins, p);
|
||||
else
|
||||
{
|
||||
g_message ("Plugin load for [%s] failed\n", path);
|
||||
g_module_close (plg);
|
||||
}
|
||||
}
|
||||
else
|
||||
g_message ("Unable to load plugin [%s]\n", path);
|
||||
|
||||
g_free (path);
|
||||
g_free (plg_string);
|
||||
}
|
||||
|
||||
plugins = plugins->next;
|
||||
}
|
||||
|
||||
|
||||
if (fallback)
|
||||
g_slist_free (fallback);
|
||||
|
||||
if (mgr->plugins != NULL)
|
||||
{
|
||||
meta_prefs_add_listener (prefs_changed_callback, mgr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reloads all plugins
|
||||
*/
|
||||
static gboolean
|
||||
meta_compositor_clutter_plugin_manager_reload (MetaCompositorClutterPluginManager *mgr)
|
||||
{
|
||||
/* 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.
|
||||
*/
|
||||
meta_compositor_clutter_plugin_manager_unload (mgr);
|
||||
return meta_compositor_clutter_plugin_manager_load (mgr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_compositor_clutter_plugin_manager_init (MetaCompositorClutterPluginManager *mgr)
|
||||
{
|
||||
return meta_compositor_clutter_plugin_manager_load (mgr);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_clutter_plugin_manager_update_workspace (MetaCompositorClutterPluginManager *mgr, MetaWorkspace *w)
|
||||
{
|
||||
GList *l;
|
||||
gint n;
|
||||
|
||||
n = meta_workspace_index (w);
|
||||
l = mgr->plugins;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaCompositorClutterPlugin *plg = l->data;
|
||||
PluginWorkspaceRectangle *r = g_list_nth_data (plg->work_areas, n);
|
||||
|
||||
if (r)
|
||||
{
|
||||
meta_workspace_get_work_area_all_xineramas (w, (MetaRectangle*)r);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Something not entirely right; redo the whole thing */
|
||||
update_plugin_workspaces (mgr->screen, plg);
|
||||
return;
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_clutter_plugin_manager_update_workspaces (MetaCompositorClutterPluginManager *mgr)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
l = mgr->plugins;
|
||||
while (l)
|
||||
{
|
||||
MetaCompositorClutterPlugin *plg = l->data;
|
||||
|
||||
update_plugin_workspaces (mgr->screen, plg);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
MetaCompositorClutterPluginManager *
|
||||
meta_compositor_clutter_plugin_manager_new (MetaScreen *screen)
|
||||
{
|
||||
MetaCompositorClutterPluginManager *mgr;
|
||||
|
||||
mgr = g_new0 (MetaCompositorClutterPluginManager, 1);
|
||||
|
||||
mgr->screen = screen;
|
||||
|
||||
if (!meta_compositor_clutter_plugin_manager_init (mgr))
|
||||
{
|
||||
g_free (mgr);
|
||||
mgr = NULL;
|
||||
}
|
||||
|
||||
return mgr;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_compositor_clutter_plugin_manager_kill_effect (MetaCompositorClutterPluginManager *mgr,
|
||||
MetaCompWindow *actor,
|
||||
unsigned long events)
|
||||
{
|
||||
GList *l = mgr->plugins;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaCompositorClutterPlugin *plg = l->data;
|
||||
MetaCompositorClutterPluginPrivate *priv = plg->manager_private;
|
||||
|
||||
if (!priv->disabled && (plg->features & events) && plg->kill_effect)
|
||||
plg->kill_effect (actor, events);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
#define ALL_BUT_SWITCH \
|
||||
META_COMPOSITOR_CLUTTER_PLUGIN_ALL_EFFECTS & \
|
||||
~META_COMPOSITOR_CLUTTER_PLUGIN_SWITCH_WORKSPACE
|
||||
/*
|
||||
* 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
|
||||
meta_compositor_clutter_plugin_manager_event_simple (MetaCompositorClutterPluginManager *mgr,
|
||||
MetaCompWindow *actor,
|
||||
unsigned long event)
|
||||
{
|
||||
GList *l = mgr->plugins;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaCompositorClutterPlugin *plg = l->data;
|
||||
MetaCompositorClutterPluginPrivate *priv = plg->manager_private;
|
||||
|
||||
if (!priv->disabled && (plg->features & event))
|
||||
{
|
||||
retval = TRUE;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case META_COMPOSITOR_CLUTTER_PLUGIN_MINIMIZE:
|
||||
if (plg->minimize)
|
||||
{
|
||||
meta_compositor_clutter_plugin_manager_kill_effect (mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
plg->minimize (actor);
|
||||
}
|
||||
break;
|
||||
case META_COMPOSITOR_CLUTTER_PLUGIN_MAP:
|
||||
if (plg->map)
|
||||
{
|
||||
meta_compositor_clutter_plugin_manager_kill_effect (mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
plg->map (actor);
|
||||
}
|
||||
break;
|
||||
case META_COMPOSITOR_CLUTTER_PLUGIN_DESTROY:
|
||||
if (plg->destroy)
|
||||
{
|
||||
plg->destroy (actor);
|
||||
}
|
||||
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 maximize and unmaximize
|
||||
* events.
|
||||
*
|
||||
* 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
|
||||
meta_compositor_clutter_plugin_manager_event_maximize (MetaCompositorClutterPluginManager *mgr,
|
||||
MetaCompWindow *actor,
|
||||
unsigned long event,
|
||||
gint target_x,
|
||||
gint target_y,
|
||||
gint target_width,
|
||||
gint target_height)
|
||||
{
|
||||
GList *l = mgr->plugins;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaCompositorClutterPlugin *plg = l->data;
|
||||
MetaCompositorClutterPluginPrivate *priv = plg->manager_private;
|
||||
|
||||
if (!priv->disabled && (plg->features & event))
|
||||
{
|
||||
retval = TRUE;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case META_COMPOSITOR_CLUTTER_PLUGIN_MAXIMIZE:
|
||||
if (plg->maximize)
|
||||
{
|
||||
meta_compositor_clutter_plugin_manager_kill_effect (mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
plg->maximize (actor,
|
||||
target_x, target_y,
|
||||
target_width, target_height);
|
||||
}
|
||||
break;
|
||||
case META_COMPOSITOR_CLUTTER_PLUGIN_UNMAXIMIZE:
|
||||
if (plg->unmaximize)
|
||||
{
|
||||
meta_compositor_clutter_plugin_manager_kill_effect (mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
plg->unmaximize (actor,
|
||||
target_x, target_y,
|
||||
target_width, target_height);
|
||||
}
|
||||
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
|
||||
meta_compositor_clutter_plugin_manager_switch_workspace (MetaCompositorClutterPluginManager *mgr,
|
||||
const GList **actors,
|
||||
gint from,
|
||||
gint to,
|
||||
MetaMotionDirection direction)
|
||||
{
|
||||
GList *l = mgr->plugins;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaCompositorClutterPlugin *plg = l->data;
|
||||
MetaCompositorClutterPluginPrivate *priv = plg->manager_private;
|
||||
|
||||
if (!priv->disabled &&
|
||||
(plg->features & META_COMPOSITOR_CLUTTER_PLUGIN_SWITCH_WORKSPACE) &&
|
||||
(actors && *actors))
|
||||
{
|
||||
if (plg->switch_workspace)
|
||||
{
|
||||
retval = TRUE;
|
||||
meta_compositor_clutter_plugin_manager_kill_effect (mgr,
|
||||
META_COMP_WINDOW ((*actors)->data),
|
||||
META_COMPOSITOR_CLUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
plg->switch_workspace (actors, from, to, direction);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
meta_compositor_clutter_plugin_manager_xevent_filter
|
||||
(MetaCompositorClutterPluginManager *mgr, XEvent *xev)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
if (!mgr)
|
||||
return FALSE;
|
||||
|
||||
l = mgr->plugins;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaCompositorClutterPlugin *plg = l->data;
|
||||
|
||||
if (plg->xevent_filter)
|
||||
{
|
||||
if (plg->xevent_filter (xev) == TRUE)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Public accessors for plugins, exposed from compositor-clutter-plugin.h
|
||||
*/
|
||||
ClutterActor *
|
||||
meta_comp_clutter_plugin_get_overlay_group (MetaCompositorClutterPlugin *plugin)
|
||||
{
|
||||
MetaCompositorClutterPluginPrivate *priv = plugin->manager_private;
|
||||
MetaCompositorClutterPluginManager *mgr = priv->self;
|
||||
|
||||
return meta_compositor_clutter_get_overlay_group_for_screen (mgr->screen);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
meta_comp_clutter_plugin_get_stage (MetaCompositorClutterPlugin *plugin)
|
||||
{
|
||||
MetaCompositorClutterPluginPrivate *priv = plugin->manager_private;
|
||||
MetaCompositorClutterPluginManager *mgr = priv->self;
|
||||
|
||||
return meta_compositor_clutter_get_stage_for_screen (mgr->screen);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_clutter_plugin_effect_completed (MetaCompositorClutterPlugin *plugin,
|
||||
MetaCompWindow *actor,
|
||||
unsigned long event)
|
||||
{
|
||||
if (!actor)
|
||||
{
|
||||
g_warning ("Plugin [%s] passed NULL for actor!",
|
||||
(plugin && plugin->name) ? plugin->name : "unknown");
|
||||
}
|
||||
|
||||
meta_compositor_clutter_window_effect_completed (actor, event);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
meta_comp_clutter_plugin_set_stage_reactive (MetaCompositorClutterPlugin *plugin,
|
||||
gboolean reactive)
|
||||
{
|
||||
MetaCompositorClutterPluginPrivate *priv = plugin->manager_private;
|
||||
MetaCompositorClutterPluginManager *mgr = priv->self;
|
||||
MetaDisplay *display = meta_screen_get_display (mgr->screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = meta_compositor_clutter_get_stage_for_screen (mgr->screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = meta_compositor_clutter_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
|
||||
meta_comp_clutter_plugin_set_stage_input_area (MetaCompositorClutterPlugin *plugin,
|
||||
gint x, gint y, gint width, gint height)
|
||||
{
|
||||
MetaCompositorClutterPluginPrivate *priv = plugin->manager_private;
|
||||
MetaCompositorClutterPluginManager *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 = meta_compositor_clutter_get_stage_for_screen (mgr->screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = meta_compositor_clutter_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);
|
||||
}
|
@ -1645,6 +1645,7 @@ process_property_notify (Mutter *compositor,
|
||||
static void
|
||||
show_overlay_window (MetaScreen *screen, Window cow)
|
||||
{
|
||||
#if 0
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
XserverRegion region;
|
||||
@ -1655,6 +1656,7 @@ show_overlay_window (MetaScreen *screen, Window cow)
|
||||
XFixesSetWindowShapeRegion (xdisplay, cow, ShapeInput, 0, 0, region);
|
||||
|
||||
XFixesDestroyRegion (xdisplay, region);
|
||||
#endif
|
||||
}
|
||||
|
||||
static Window
|
||||
@ -1667,7 +1669,14 @@ get_output_window (MetaScreen *screen)
|
||||
xroot = meta_screen_get_xroot (screen);
|
||||
|
||||
output = XCompositeGetOverlayWindow (xdisplay, xroot);
|
||||
XSelectInput (xdisplay, output, ExposureMask);
|
||||
XSelectInput (xdisplay,
|
||||
output,
|
||||
FocusChangeMask |
|
||||
ExposureMask |
|
||||
PointerMotionMask |
|
||||
PropertyChangeMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
KeyPressMask | KeyReleaseMask);
|
||||
|
||||
return output;
|
||||
}
|
||||
@ -1748,6 +1757,15 @@ clutter_cmp_manage_screen (MetaCompositor *compositor,
|
||||
|
||||
XReparentWindow (xdisplay, xwin, info->output, 0, 0);
|
||||
|
||||
XSelectInput (xdisplay,
|
||||
xwin,
|
||||
FocusChangeMask |
|
||||
ExposureMask |
|
||||
PointerMotionMask |
|
||||
PropertyChangeMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
KeyPressMask | KeyReleaseMask);
|
||||
|
||||
info->window_group = clutter_group_new ();
|
||||
info->overlay_group = clutter_group_new ();
|
||||
|
||||
@ -1842,6 +1860,29 @@ clutter_cmp_process_event (MetaCompositor *compositor,
|
||||
event) == TRUE)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
GSList *l;
|
||||
Mutter *clc = (Mutter*)compositor;
|
||||
|
||||
l = meta_display_get_screens (clc->display);
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaScreen *screen = l->data;
|
||||
MetaCompScreen *info;
|
||||
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (mutter_plugin_manager_xevent_filter (info->plugin_mgr,
|
||||
event) == TRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This trap is so that none of the compositor functions cause
|
||||
@ -2246,6 +2287,15 @@ mutter_new (MetaDisplay *display)
|
||||
#endif
|
||||
}
|
||||
|
||||
Window
|
||||
mutter_get_overlay_window (MetaScreen *screen)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
return info->output;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------- */
|
||||
/* Shadow Generation */
|
||||
|
||||
|
@ -28,6 +28,10 @@
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
static gboolean mutter_plugin_manager_reload (
|
||||
MutterPluginManager *plugin_mgr);
|
||||
@ -117,7 +121,7 @@ static gulong
|
||||
parse_disable_params (const char *params, gulong features)
|
||||
{
|
||||
char *p;
|
||||
|
||||
|
||||
if (!params)
|
||||
return features;
|
||||
|
||||
@ -741,7 +745,7 @@ mutter_plugin_manager_xevent_filter (
|
||||
* Public accessors for plugins, exposed from mutter-plugin.h
|
||||
*/
|
||||
ClutterActor *
|
||||
meta_comp_clutter_plugin_get_overlay_group (MutterPlugin *plugin)
|
||||
mutter_plugin_get_overlay_group (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *plugin_mgr = priv->self;
|
||||
@ -750,7 +754,7 @@ meta_comp_clutter_plugin_get_overlay_group (MutterPlugin *plugin)
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
meta_comp_clutter_plugin_get_stage (MutterPlugin *plugin)
|
||||
mutter_plugin_get_stage (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *plugin_mgr = priv->self;
|
||||
@ -759,9 +763,9 @@ meta_comp_clutter_plugin_get_stage (MutterPlugin *plugin)
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_clutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
unsigned long event)
|
||||
mutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
unsigned long event)
|
||||
{
|
||||
if (!actor)
|
||||
{
|
||||
@ -773,9 +777,9 @@ meta_comp_clutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_clutter_plugin_query_screen_size (MutterPlugin *plugin,
|
||||
int *width,
|
||||
int *height)
|
||||
mutter_plugin_query_screen_size (MutterPlugin *plugin,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *plugin_mgr = priv->self;
|
||||
@ -783,3 +787,66 @@ meta_comp_clutter_plugin_query_screen_size (MutterPlugin *plugin,
|
||||
meta_screen_get_size (plugin_mgr->screen, width, height);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -12,6 +12,13 @@ default_la_SOURCES = default.c
|
||||
default_la_LDFLAGS = -module -avoid-version -no-undefined
|
||||
default_la_LIBADD = @CLUTTER_LIBS@
|
||||
|
||||
moblin_la_CFLAGS = -fPIC
|
||||
moblin_la_SOURCES = moblin.c
|
||||
moblin_la_LDFLAGS = -module -avoid-version -no-undefined
|
||||
moblin_la_LIBADD = @CLUTTER_LIBS@
|
||||
|
||||
pkglib_LTLIBRARIES = default.la moblin.la
|
||||
|
||||
# post-install hook to remove the .la and .a files we are not interested in
|
||||
# (There is no way to stop libtool generating static libs locally, and we
|
||||
# cannot do this globally because of libmetacity-private.so).
|
||||
|
@ -202,8 +202,8 @@ on_switch_workspace_effect_complete (ClutterActor *group, gpointer data)
|
||||
state->desktop1 = NULL;
|
||||
state->desktop2 = NULL;
|
||||
|
||||
meta_comp_clutter_plugin_effect_completed (&mutter_plugin, actor_for_cb,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
mutter_plugin_effect_completed (&mutter_plugin, actor_for_cb,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -219,9 +219,9 @@ switch_workspace (const GList **actors, gint from, gint to,
|
||||
ClutterActor *stage;
|
||||
int screen_width, screen_height;
|
||||
|
||||
stage = meta_comp_clutter_plugin_get_stage (plugin);
|
||||
stage = mutter_plugin_get_stage (plugin);
|
||||
|
||||
meta_comp_clutter_plugin_query_screen_size (plugin,
|
||||
mutter_plugin_query_screen_size (plugin,
|
||||
&screen_width,
|
||||
&screen_height);
|
||||
clutter_actor_set_anchor_point (workspace1,
|
||||
@ -238,7 +238,7 @@ switch_workspace (const GList **actors, gint from, gint to,
|
||||
|
||||
if (from == to)
|
||||
{
|
||||
meta_comp_clutter_plugin_effect_completed (&mutter_plugin, NULL,
|
||||
mutter_plugin_effect_completed (&mutter_plugin, NULL,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
return;
|
||||
}
|
||||
@ -331,7 +331,7 @@ on_minimize_effect_complete (ClutterActor *actor, gpointer data)
|
||||
/* Decrease the running effect counter */
|
||||
mutter_plugin.running--;
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
meta_comp_clutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
mutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
MUTTER_PLUGIN_MINIMIZE);
|
||||
}
|
||||
|
||||
@ -368,7 +368,7 @@ minimize (MutterWindow *mc_window)
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
meta_comp_clutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
mutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
MUTTER_PLUGIN_MINIMIZE);
|
||||
}
|
||||
|
||||
@ -396,7 +396,7 @@ on_maximize_effect_complete (ClutterActor *actor, gpointer data)
|
||||
mutter_plugin.running--;
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
meta_comp_clutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
mutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAXIMIZE);
|
||||
}
|
||||
|
||||
@ -459,7 +459,7 @@ maximize (MutterWindow *mc_window,
|
||||
return;
|
||||
}
|
||||
|
||||
meta_comp_clutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
mutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAXIMIZE);
|
||||
}
|
||||
|
||||
@ -482,7 +482,7 @@ unmaximize (MutterWindow *mc_window,
|
||||
}
|
||||
|
||||
/* Do this conditionally, if the effect requires completion callback. */
|
||||
meta_comp_clutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
mutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
MUTTER_PLUGIN_UNMAXIMIZE);
|
||||
}
|
||||
|
||||
@ -504,7 +504,7 @@ on_map_effect_complete (ClutterActor *actor, gpointer data)
|
||||
mutter_plugin.running--;
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
meta_comp_clutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
mutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAP);
|
||||
}
|
||||
|
||||
@ -544,7 +544,7 @@ map (MutterWindow *mc_window)
|
||||
|
||||
}
|
||||
else
|
||||
meta_comp_clutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
mutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAP);
|
||||
}
|
||||
|
||||
@ -564,7 +564,7 @@ on_destroy_effect_complete (ClutterActor *actor, gpointer data)
|
||||
|
||||
mutter_plugin.running--;
|
||||
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, mc_window,
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_DESTROY);
|
||||
}
|
||||
|
||||
@ -597,7 +597,7 @@ destroy (MutterWindow *mc_window)
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
meta_comp_clutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
mutter_plugin_effect_completed (&mutter_plugin, mc_window,
|
||||
MUTTER_PLUGIN_DESTROY);
|
||||
}
|
||||
|
||||
|
@ -29,20 +29,25 @@
|
||||
#define N_(x) x
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <gmodule.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DESTROY_TIMEOUT 250
|
||||
#define MINIMIZE_TIMEOUT 250
|
||||
#define MAXIMIZE_TIMEOUT 250
|
||||
#define MAP_TIMEOUT 250
|
||||
#define SWITCH_TIMEOUT 500
|
||||
#define DESTROY_TIMEOUT 250
|
||||
#define MINIMIZE_TIMEOUT 250
|
||||
#define MAXIMIZE_TIMEOUT 250
|
||||
#define MAP_TIMEOUT 250
|
||||
#define SWITCH_TIMEOUT 500
|
||||
#define PANEL_SLIDE_TIMEOUT 250; \
|
||||
|
||||
#define PANEL_SLIDE_THRESHOLD 2
|
||||
#define PANEL_HEIGHT 40
|
||||
#define ACTOR_DATA_KEY "MCCP-Moblin-actor-data"
|
||||
|
||||
typedef struct PluginPrivate PluginPrivate;
|
||||
typedef struct ActorPrivate ActorPrivate;
|
||||
|
||||
static gboolean do_init (const char *params);
|
||||
static void minimize (MutterWindow *actor);
|
||||
static void map (MutterWindow *actor);
|
||||
static void destroy (MutterWindow *actor);
|
||||
@ -56,14 +61,16 @@ static void switch_workspace (const GList **actors, gint from, gint to,
|
||||
|
||||
static void kill_effect (MutterWindow *actor, gulong event);
|
||||
|
||||
static gboolean reload (void);
|
||||
static gboolean xevent_filter (XEvent *xev);
|
||||
|
||||
static gboolean reload (const char *params);
|
||||
|
||||
/*
|
||||
* First we create the header struct and initialize its static members.
|
||||
* Any dynamically allocated data should be initialized in the
|
||||
* init () function below.
|
||||
*/
|
||||
MutterPlugin MUTTER_PLUGIN_STRUCT =
|
||||
G_MODULE_EXPORT MutterPlugin mutter_plugin =
|
||||
{
|
||||
/*
|
||||
* These are predefined values; do not modify.
|
||||
@ -74,15 +81,17 @@ MutterPlugin MUTTER_PLUGIN_STRUCT =
|
||||
.version_api = METACITY_CLUTTER_PLUGIN_API_VERSION,
|
||||
|
||||
/* Human readable name (for use in UI) */
|
||||
.name = "Default Effects",
|
||||
.name = "Experimental effects",
|
||||
|
||||
/* Plugin load time initialiser */
|
||||
.do_init = do_init,
|
||||
|
||||
/* Which types of events this plugin supports */
|
||||
.features = MUTTER_PLUGIN_MINIMIZE |
|
||||
MUTTER_PLUGIN_DESTROY |
|
||||
MUTTER_PLUGIN_MAP |
|
||||
MUTTER_PLUGIN_MAXIMIZE |
|
||||
MUTTER_PLUGIN_UNMAXIMIZE |
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE,
|
||||
MUTTER_PLUGIN_UNMAXIMIZE,
|
||||
|
||||
|
||||
/* And the corresponding handlers */
|
||||
@ -92,8 +101,8 @@ MutterPlugin MUTTER_PLUGIN_STRUCT =
|
||||
.maximize = maximize,
|
||||
.unmaximize = unmaximize,
|
||||
.switch_workspace = switch_workspace,
|
||||
|
||||
.kill_effect = kill_effect,
|
||||
.xevent_filter = xevent_filter,
|
||||
|
||||
/* The reload handler */
|
||||
.reload = reload
|
||||
@ -109,6 +118,7 @@ struct PluginPrivate
|
||||
ClutterEffectTemplate *maximize_effect;
|
||||
ClutterEffectTemplate *map_effect;
|
||||
ClutterEffectTemplate *switch_workspace_effect;
|
||||
ClutterEffectTemplate *panel_slide_effect;
|
||||
|
||||
/* Valid only when switch_workspace effect is in progress */
|
||||
ClutterTimeline *tml_switch_workspace1;
|
||||
@ -117,7 +127,12 @@ struct PluginPrivate
|
||||
ClutterActor *desktop1;
|
||||
ClutterActor *desktop2;
|
||||
|
||||
ClutterActor *panel;
|
||||
|
||||
gboolean debug_mode : 1;
|
||||
gboolean panel_out : 1;
|
||||
gboolean panel_out_in_progress : 1;
|
||||
gboolean panel_back_in_progress : 1;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -157,7 +172,7 @@ static inline
|
||||
MutterPlugin *
|
||||
get_plugin ()
|
||||
{
|
||||
return &MUTTER_PLUGIN_STRUCT;
|
||||
return &mutter_plugin;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -192,8 +207,8 @@ on_switch_workspace_effect_complete (ClutterActor *group, gpointer data)
|
||||
ppriv->desktop1 = NULL;
|
||||
ppriv->desktop2 = NULL;
|
||||
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, actor_for_cb,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
mutter_plugin_effect_completed (plugin, actor_for_cb,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -207,16 +222,17 @@ switch_workspace (const GList **actors, gint from, gint to,
|
||||
ClutterActor *group1 = clutter_group_new ();
|
||||
ClutterActor *group2 = clutter_group_new ();
|
||||
ClutterActor *stage;
|
||||
gint screen_width;
|
||||
gint screen_height;
|
||||
|
||||
stage = meta_comp_clutter_plugin_get_stage (plugin);
|
||||
stage = mutter_plugin_get_stage (plugin);
|
||||
|
||||
mutter_plugin_query_screen_size (plugin, &screen_width, &screen_height);
|
||||
|
||||
#if 1
|
||||
clutter_actor_set_anchor_point (group2,
|
||||
plugin->screen_width,
|
||||
plugin->screen_height);
|
||||
clutter_actor_set_position (group2,
|
||||
plugin->screen_width,
|
||||
plugin->screen_height);
|
||||
clutter_actor_set_anchor_point (group2, screen_width, screen_height);
|
||||
|
||||
clutter_actor_set_position (group2, screen_width, screen_height);
|
||||
#endif
|
||||
|
||||
clutter_actor_set_scale (group2, 0.0, 0.0);
|
||||
@ -226,7 +242,7 @@ switch_workspace (const GList **actors, gint from, gint to,
|
||||
|
||||
if (from == to)
|
||||
{
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, NULL,
|
||||
mutter_plugin_effect_completed (plugin, NULL,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
return;
|
||||
}
|
||||
@ -242,7 +258,7 @@ switch_workspace (const GList **actors, gint from, gint to,
|
||||
ClutterActor *a = CLUTTER_ACTOR (mcw);
|
||||
gint workspace;
|
||||
|
||||
workspace = meta_comp_window_get_workspace (mcw);
|
||||
workspace = mutter_window_get_workspace (mcw);
|
||||
|
||||
if (workspace == to || workspace == from)
|
||||
{
|
||||
@ -318,7 +334,7 @@ on_minimize_effect_complete (ClutterActor *actor, gpointer data)
|
||||
plugin->running--;
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, mcw,
|
||||
mutter_plugin_effect_completed (plugin, mcw,
|
||||
MUTTER_PLUGIN_MINIMIZE);
|
||||
}
|
||||
|
||||
@ -330,14 +346,14 @@ static void
|
||||
minimize (MutterWindow *mcw)
|
||||
|
||||
{
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
MutterWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mcw);
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mcw);
|
||||
|
||||
type = meta_comp_window_get_window_type (mcw);
|
||||
type = mutter_window_get_window_type (mcw);
|
||||
|
||||
if (type == MUTTER_WINDOW_NORMAL)
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ActorPrivate *apriv = get_actor_private (mcw);
|
||||
|
||||
@ -346,7 +362,7 @@ minimize (MutterWindow *mcw)
|
||||
clutter_actor_move_anchor_point_from_gravity (actor,
|
||||
CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
MUTTER_PLUGIN_STRUCT.running++;
|
||||
plugin->running++;
|
||||
|
||||
apriv->tml_minimize = clutter_effect_scale (priv->minimize_effect,
|
||||
actor,
|
||||
@ -357,7 +373,7 @@ minimize (MutterWindow *mcw)
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, mcw,
|
||||
mutter_plugin_effect_completed (plugin, mcw,
|
||||
MUTTER_PLUGIN_MINIMIZE);
|
||||
}
|
||||
|
||||
@ -385,7 +401,7 @@ on_maximize_effect_complete (ClutterActor *actor, gpointer data)
|
||||
plugin->running--;
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, mcw,
|
||||
mutter_plugin_effect_completed (plugin, mcw,
|
||||
MUTTER_PLUGIN_MAXIMIZE);
|
||||
}
|
||||
|
||||
@ -403,7 +419,7 @@ maximize (MutterWindow *mcw,
|
||||
{
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
MutterWindowType type;
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mcw);
|
||||
|
||||
gdouble scale_x = 1.0;
|
||||
@ -411,9 +427,9 @@ maximize (MutterWindow *mcw,
|
||||
gint anchor_x = 0;
|
||||
gint anchor_y = 0;
|
||||
|
||||
type = meta_comp_window_get_window_type (mcw);
|
||||
type = mutter_window_get_window_type (mcw);
|
||||
|
||||
if (type == MUTTER_WINDOW_NORMAL)
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ActorPrivate *apriv = get_actor_private (mcw);
|
||||
guint width, height;
|
||||
@ -449,7 +465,7 @@ maximize (MutterWindow *mcw,
|
||||
return;
|
||||
}
|
||||
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, mcw,
|
||||
mutter_plugin_effect_completed (plugin, mcw,
|
||||
MUTTER_PLUGIN_MAXIMIZE);
|
||||
}
|
||||
|
||||
@ -463,11 +479,11 @@ unmaximize (MutterWindow *mcw,
|
||||
gint end_x, gint end_y, gint end_width, gint end_height)
|
||||
{
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
MutterWindowType type;
|
||||
MetaCompWindowType type;
|
||||
|
||||
type = meta_comp_window_get_window_type (mcw);
|
||||
type = mutter_window_get_window_type (mcw);
|
||||
|
||||
if (type == MUTTER_WINDOW_NORMAL)
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ActorPrivate *apriv = get_actor_private (mcw);
|
||||
|
||||
@ -475,7 +491,7 @@ unmaximize (MutterWindow *mcw,
|
||||
}
|
||||
|
||||
/* Do this conditionally, if the effect requires completion callback. */
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, mcw,
|
||||
mutter_plugin_effect_completed (plugin, mcw,
|
||||
MUTTER_PLUGIN_UNMAXIMIZE);
|
||||
}
|
||||
|
||||
@ -498,7 +514,7 @@ on_map_effect_complete (ClutterActor *actor, gpointer data)
|
||||
plugin->running--;
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, mcw,
|
||||
mutter_plugin_effect_completed (plugin, mcw,
|
||||
MUTTER_PLUGIN_MAP);
|
||||
}
|
||||
|
||||
@ -511,19 +527,19 @@ map (MutterWindow *mcw)
|
||||
{
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
MutterWindowType type;
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mcw);
|
||||
|
||||
type = meta_comp_window_get_window_type (mcw);
|
||||
type = mutter_window_get_window_type (mcw);
|
||||
|
||||
if (type == MUTTER_WINDOW_NORMAL)
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ActorPrivate *apriv = get_actor_private (mcw);
|
||||
|
||||
clutter_actor_move_anchor_point_from_gravity (actor,
|
||||
CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
MUTTER_PLUGIN_STRUCT.running++;
|
||||
plugin->running++;
|
||||
|
||||
clutter_actor_set_scale (actor, 0.0, 0.0);
|
||||
clutter_actor_show (actor);
|
||||
@ -540,7 +556,7 @@ map (MutterWindow *mcw)
|
||||
|
||||
}
|
||||
else
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, mcw,
|
||||
mutter_plugin_effect_completed (plugin, mcw,
|
||||
MUTTER_PLUGIN_MAP);
|
||||
}
|
||||
|
||||
@ -560,7 +576,7 @@ on_destroy_effect_complete (ClutterActor *actor, gpointer data)
|
||||
|
||||
plugin->running--;
|
||||
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, mcw,
|
||||
mutter_plugin_effect_completed (plugin, mcw,
|
||||
MUTTER_PLUGIN_DESTROY);
|
||||
}
|
||||
|
||||
@ -572,12 +588,12 @@ destroy (MutterWindow *mcw)
|
||||
{
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
MutterWindowType type;
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mcw);
|
||||
|
||||
type = meta_comp_window_get_window_type (mcw);
|
||||
type = mutter_window_get_window_type (mcw);
|
||||
|
||||
if (type == MUTTER_WINDOW_NORMAL)
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ActorPrivate *apriv = get_actor_private (mcw);
|
||||
|
||||
@ -595,10 +611,46 @@ destroy (MutterWindow *mcw)
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
meta_comp_clutter_plugin_effect_completed (plugin, mcw,
|
||||
mutter_plugin_effect_completed (plugin, mcw,
|
||||
MUTTER_PLUGIN_DESTROY);
|
||||
}
|
||||
|
||||
static void
|
||||
on_panel_effect_complete (ClutterActor *panel, gpointer data)
|
||||
{
|
||||
gboolean reactive = GPOINTER_TO_INT (data);
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
gint screen_width, screen_height;
|
||||
|
||||
mutter_plugin_query_screen_size (plugin, &screen_width, &screen_height);
|
||||
|
||||
if (reactive)
|
||||
{
|
||||
priv->panel_out_in_progress = FALSE;
|
||||
mutter_plugin_set_stage_reactive (plugin, reactive);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->panel_back_in_progress = FALSE;
|
||||
mutter_plugin_set_stage_input_area (plugin, 0, 0,
|
||||
screen_width, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
xevent_filter (XEvent *xev)
|
||||
{
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = mutter_plugin_get_stage (plugin);
|
||||
|
||||
clutter_x11_handle_event (xev);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
kill_effect (MutterWindow *mcw, gulong event)
|
||||
{
|
||||
@ -674,30 +726,100 @@ g_module_check_init (GModule *module)
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
stage_input_cb (ClutterActor *stage, ClutterEvent *event, gpointer data)
|
||||
{
|
||||
if (event->type == CLUTTER_MOTION)
|
||||
{
|
||||
ClutterMotionEvent *mev = (ClutterMotionEvent *) event;
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
|
||||
if (priv->panel_out_in_progress || priv->panel_back_in_progress)
|
||||
return FALSE;
|
||||
|
||||
if (priv->panel_out)
|
||||
{
|
||||
guint height = clutter_actor_get_height (priv->panel);
|
||||
gint x = clutter_actor_get_x (priv->panel);
|
||||
|
||||
if (mev->y > (gint)height)
|
||||
{
|
||||
priv->panel_back_in_progress = TRUE;
|
||||
clutter_effect_move (priv->panel_slide_effect,
|
||||
priv->panel, x, -height,
|
||||
on_panel_effect_complete,
|
||||
GINT_TO_POINTER (FALSE));
|
||||
priv->panel_out = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (mev->y < PANEL_SLIDE_THRESHOLD)
|
||||
{
|
||||
gint x = clutter_actor_get_x (priv->panel);
|
||||
|
||||
priv->panel_out_in_progress = TRUE;
|
||||
clutter_effect_move (priv->panel_slide_effect,
|
||||
priv->panel, x, 0,
|
||||
on_panel_effect_complete,
|
||||
GINT_TO_POINTER (TRUE));
|
||||
|
||||
priv->panel_out = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
make_panel (gint width)
|
||||
{
|
||||
ClutterActor *panel;
|
||||
ClutterActor *background;
|
||||
ClutterColor clr = {0xff, 0, 0, 0xff};
|
||||
|
||||
panel = clutter_group_new ();
|
||||
|
||||
/* FIME -- size and color */
|
||||
background = clutter_rectangle_new_with_color (&clr);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (panel), background);
|
||||
clutter_actor_set_size (background, width, PANEL_HEIGHT);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
/*
|
||||
* Core of the plugin init function, called for initial initialization and
|
||||
* by the reload() function. Returns TRUE on success.
|
||||
*/
|
||||
static gboolean
|
||||
do_init ()
|
||||
do_init (const char *params)
|
||||
{
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
|
||||
PluginPrivate *priv = g_new0 (PluginPrivate, 1);
|
||||
const gchar *params;
|
||||
guint destroy_timeout = DESTROY_TIMEOUT;
|
||||
guint minimize_timeout = MINIMIZE_TIMEOUT;
|
||||
guint maximize_timeout = MAXIMIZE_TIMEOUT;
|
||||
guint map_timeout = MAP_TIMEOUT;
|
||||
guint switch_timeout = SWITCH_TIMEOUT;
|
||||
guint destroy_timeout = DESTROY_TIMEOUT;
|
||||
guint minimize_timeout = MINIMIZE_TIMEOUT;
|
||||
guint maximize_timeout = MAXIMIZE_TIMEOUT;
|
||||
guint map_timeout = MAP_TIMEOUT;
|
||||
guint switch_timeout = SWITCH_TIMEOUT;
|
||||
guint panel_slide_timeout = PANEL_SLIDE_TIMEOUT;
|
||||
const gchar *name;
|
||||
ClutterActor *overlay;
|
||||
ClutterActor *panel;
|
||||
gint screen_width, screen_height;
|
||||
|
||||
plugin->plugin_private = priv;
|
||||
|
||||
name = plugin->name;
|
||||
plugin->name = _(name);
|
||||
|
||||
params = plugin->params;
|
||||
mutter_plugin_query_screen_size (plugin, &screen_width, &screen_height);
|
||||
|
||||
if (params)
|
||||
{
|
||||
@ -706,7 +828,7 @@ do_init ()
|
||||
if (strstr (params, "debug"))
|
||||
{
|
||||
g_debug ("%s: Entering debug mode.",
|
||||
MUTTER_PLUGIN_STRUCT.name);
|
||||
plugin->name);
|
||||
|
||||
priv->debug_mode = TRUE;
|
||||
|
||||
@ -777,17 +899,35 @@ do_init ()
|
||||
switch_timeout),
|
||||
CLUTTER_ALPHA_SINE_INC);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
overlay = mutter_plugin_get_overlay_group (plugin);
|
||||
|
||||
MUTTER_PLUGIN_INIT_FUNC
|
||||
{
|
||||
return do_init ();
|
||||
panel = priv->panel = make_panel (screen_width);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (overlay), panel);
|
||||
|
||||
priv->panel_slide_effect
|
||||
= clutter_effect_template_new (clutter_timeline_new_for_duration (
|
||||
panel_slide_timeout),
|
||||
CLUTTER_ALPHA_SINE_INC);
|
||||
|
||||
clutter_actor_set_position (panel, 0,
|
||||
-clutter_actor_get_height (panel));
|
||||
|
||||
g_signal_connect (mutter_plugin_get_stage (plugin),
|
||||
"motion-event", G_CALLBACK (stage_input_cb), NULL);
|
||||
|
||||
mutter_plugin_set_stage_input_area (plugin, 0, 0, screen_width, 1);
|
||||
|
||||
clutter_set_motion_events_enabled (TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
free_plugin_private (PluginPrivate *priv)
|
||||
{
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
g_object_unref (priv->destroy_effect);
|
||||
g_object_unref (priv->minimize_effect);
|
||||
g_object_unref (priv->maximize_effect);
|
||||
@ -795,7 +935,7 @@ free_plugin_private (PluginPrivate *priv)
|
||||
|
||||
g_free (priv);
|
||||
|
||||
MUTTER_PLUGIN_STRUCT.plugin_private = NULL;
|
||||
get_plugin()->plugin_private = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -803,13 +943,12 @@ free_plugin_private (PluginPrivate *priv)
|
||||
* changed.
|
||||
*/
|
||||
static gboolean
|
||||
reload ()
|
||||
reload (const char *params)
|
||||
{
|
||||
PluginPrivate *priv;
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
|
||||
priv = MUTTER_PLUGIN_STRUCT.plugin_private;
|
||||
|
||||
if (do_init ())
|
||||
if (do_init (params))
|
||||
{
|
||||
/* Success; free the old private struct */
|
||||
free_plugin_private (priv);
|
||||
@ -818,7 +957,7 @@ reload ()
|
||||
else
|
||||
{
|
||||
/* Fail -- fall back to the old private. */
|
||||
MUTTER_PLUGIN_STRUCT.plugin_private = priv;
|
||||
plugin->plugin_private = priv;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@ -827,12 +966,10 @@ reload ()
|
||||
/*
|
||||
* GModule unload function -- do any cleanup required.
|
||||
*/
|
||||
void g_module_unload (GModule *module);
|
||||
void g_module_unload (GModule *module)
|
||||
G_MODULE_EXPORT void g_module_unload (GModule *module);
|
||||
G_MODULE_EXPORT void g_module_unload (GModule *module)
|
||||
{
|
||||
PluginPrivate *priv;
|
||||
|
||||
priv = MUTTER_PLUGIN_STRUCT.plugin_private;
|
||||
PluginPrivate *priv = get_plugin()->plugin_private;
|
||||
|
||||
free_plugin_private (priv);
|
||||
}
|
||||
|
255
src/include/compositor-clutter-plugin.h
Normal file
255
src/include/compositor-clutter-plugin.h
Normal file
@ -0,0 +1,255 @@
|
||||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef META_COMPOSITOR_CLUTTER_PLUGIN_H_
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
#include "compositor.h"
|
||||
#include "compositor-clutter.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
/*
|
||||
* This file defines the plugin API.
|
||||
*
|
||||
* Effects plugin is shared library loaded via dlopen(); it is recommended
|
||||
* that the GModule API is used (otherwise you are on your own to do proper
|
||||
* plugin clean up when the module is unloaded).
|
||||
*
|
||||
* The plugin interface is exported via the MetaCompositorClutterPlugin struct.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Alias MetaRectangle to PluginWorkspaceRectangle in anticipation of
|
||||
* making this file metacity-independent (we want the plugins to be portable
|
||||
* between different WMs.
|
||||
*/
|
||||
typedef MetaRectangle PluginWorkspaceRectangle;
|
||||
|
||||
/*
|
||||
* The name of the header struct; use as:
|
||||
*
|
||||
* MetaCompositorClutterPlugin META_COMPOSITOR_CLUTTER_PLUGIN_STRUCT =
|
||||
* {
|
||||
* ...
|
||||
* };
|
||||
*
|
||||
* See clutter-plugins/simple.c for example code.
|
||||
*/
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_STRUCT MCCPS__
|
||||
|
||||
/*
|
||||
* Definition for the plugin init function; use as:
|
||||
*
|
||||
* META_COMPOSITOR_CLUTTER_PLUGIN_INIT_FUNC
|
||||
* {
|
||||
* init code ...
|
||||
* }
|
||||
*
|
||||
* See clutter-plugins/simple.c for example code.
|
||||
*/
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_INIT_FUNC \
|
||||
gboolean mccp_init__(void); \
|
||||
gboolean mccp_init__()
|
||||
|
||||
|
||||
/* Private; must match the above */
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_STRUCT_NAME "MCCPS__"
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_INIT_FUNC_NAME "mccp_init__"
|
||||
|
||||
typedef struct MetaCompositorClutterPlugin MetaCompositorClutterPlugin;
|
||||
|
||||
/*
|
||||
* Feature flags: identify events that the plugin can handle; a plugin can
|
||||
* handle one or more events.
|
||||
*/
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_MINIMIZE 0x00000001UL
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_MAXIMIZE 0x00000002UL
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_UNMAXIMIZE 0x00000004UL
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_MAP 0x00000008UL
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_DESTROY 0x00000010UL
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_SWITCH_WORKSPACE 0x00000020UL
|
||||
|
||||
#define META_COMPOSITOR_CLUTTER_PLUGIN_ALL_EFFECTS 0xffffffffUL
|
||||
|
||||
struct MetaCompositorClutterPlugin
|
||||
{
|
||||
/*
|
||||
* Version information; the first three numbers match the Metacity version
|
||||
* with which the plugin was compiled (see clutter-plugins/simple.c for sample
|
||||
* code).
|
||||
*/
|
||||
guint version_major;
|
||||
guint version_minor;
|
||||
guint version_micro;
|
||||
|
||||
/*
|
||||
* Version of the plugin API; this is unrelated to the matacity version
|
||||
* per se. The API version is checked by the plugin manager and must match
|
||||
* the one used by it (see clutter-plugins/simple.c for sample code).
|
||||
*/
|
||||
guint version_api;
|
||||
|
||||
#ifndef META_COMPOSITOR_CLUTTER_BUILDING_PLUGIN
|
||||
const
|
||||
#endif
|
||||
gchar *name; /* Human-readable name for UI */
|
||||
gulong features; /* or-ed feature flags */
|
||||
|
||||
/*
|
||||
* Event handlers
|
||||
*
|
||||
* Plugins must not make any special assumptions about the nature of
|
||||
* ClutterActor, as the implementation details can change.
|
||||
*
|
||||
* Plugins must restore actor properties on completion (i.e., fade effects
|
||||
* must restore opacity back to the original value, scale effects scale,
|
||||
* etc.).
|
||||
*
|
||||
* On completion, each event handler must call the manager completed()
|
||||
* callback function.
|
||||
*/
|
||||
void (*minimize) (MetaCompWindow *actor);
|
||||
|
||||
void (*maximize) (MetaCompWindow *actor,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
void (*unmaximize) (MetaCompWindow *actor,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
void (*map) (MetaCompWindow *actor);
|
||||
|
||||
void (*destroy) (MetaCompWindow *actor);
|
||||
|
||||
/*
|
||||
* Each actor in the list has a workspace number attached to it using
|
||||
* g_object_set_data() with key META_COMPOSITOR_CLUTTER_PLUGIN_WORKSPACE_KEY;
|
||||
* workspace < 0 indicates the window is sticky (i.e., on all desktops).
|
||||
*/
|
||||
void (*switch_workspace) (const GList **actors,
|
||||
gint from,
|
||||
gint to,
|
||||
MetaMotionDirection direction);
|
||||
|
||||
/*
|
||||
* Called if an effect should be killed prematurely; the plugin must
|
||||
* call the completed() callback as if the effect terminated naturally.
|
||||
* The events parameter is a bitmask indicating which effects are to be
|
||||
* killed.
|
||||
*/
|
||||
void (*kill_effect) (MetaCompWindow *actor,
|
||||
gulong events);
|
||||
|
||||
|
||||
/*
|
||||
* The plugin manager will call this function when module should be reloaded.
|
||||
* This happens, for example, when the parameters for the plugin changed.
|
||||
*/
|
||||
gboolean (*reload) (void);
|
||||
|
||||
/* General XEvent filter. This is fired *before* metacity itself handles
|
||||
* an event. Return TRUE to block any further processing.
|
||||
*/
|
||||
gboolean (*xevent_filter) (XEvent *event);
|
||||
|
||||
|
||||
#ifdef META_COMPOSITOR_CLUTTER_BUILDING_PLUGIN
|
||||
const
|
||||
#endif
|
||||
gchar *params; /* String containing additional parameters for the plugin;
|
||||
* this is specified after the pluing name in the gconf
|
||||
* database, separated by a colon.
|
||||
*
|
||||
* The following parameter tokens need to be handled by all
|
||||
* plugins:
|
||||
*
|
||||
* 'debug'
|
||||
* Indicates running in debug mode; the plugin
|
||||
* might want to print useful debug info, or
|
||||
* extend effect duration, etc.
|
||||
*
|
||||
* 'disable: ...;'
|
||||
*
|
||||
* The disable token indicates that the effects
|
||||
* listed after the colon should be disabled.
|
||||
*
|
||||
* The list is comma-separated, terminated by a
|
||||
* semicolon and consisting of the following
|
||||
* tokens:
|
||||
*
|
||||
* minimize
|
||||
* maximize
|
||||
* unmaximize
|
||||
* map
|
||||
* destroy
|
||||
* switch-workspace
|
||||
*/
|
||||
|
||||
gint screen_width;
|
||||
gint screen_height;
|
||||
|
||||
GList *work_areas; /* List of PluginWorkspaceRectangles defining the
|
||||
* geometry of individual workspaces.
|
||||
*/
|
||||
|
||||
gint running; /* Plugin must increase this counter for each effect it starts
|
||||
* decrease it again once the effect finishes.
|
||||
*/
|
||||
|
||||
void *plugin_private; /* Plugin private data go here; use the plugin init
|
||||
* function to allocate and initialize any private
|
||||
* data.
|
||||
*/
|
||||
|
||||
/* Private; manager private data. */
|
||||
void *manager_private;
|
||||
};
|
||||
|
||||
void
|
||||
meta_comp_clutter_plugin_effect_completed (MetaCompositorClutterPlugin *plugin,
|
||||
MetaCompWindow *actor,
|
||||
unsigned long event);
|
||||
|
||||
ClutterActor *
|
||||
meta_comp_clutter_plugin_get_overlay_group (MetaCompositorClutterPlugin *plugin);
|
||||
|
||||
ClutterActor *
|
||||
meta_comp_clutter_plugin_get_stage (MetaCompositorClutterPlugin *plugin);
|
||||
|
||||
void
|
||||
meta_comp_clutter_plugin_set_stage_reactive (MetaCompositorClutterPlugin *plugin,
|
||||
gboolean reactive);
|
||||
|
||||
void
|
||||
meta_comp_clutter_plugin_set_stage_input_area (MetaCompositorClutterPlugin *plugin,
|
||||
gint x, gint y, gint width, gint height);
|
||||
|
||||
#endif
|
76
src/include/compositor-clutter.h
Normal file
76
src/include/compositor-clutter.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008 Matthew Allum
|
||||
* Copyright (C) 2007 Iain Holmes
|
||||
* Based on xcompmgr - (c) 2003 Keith Packard
|
||||
* xfwm4 - (c) 2005-2007 Olivier Fourdan
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef META_COMPOSITOR_CLUTTER_H_
|
||||
#define META_COMPOSITOR_CLUTTER_H_
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* MetaCompWindow object (ClutterGroup sub-class)
|
||||
*/
|
||||
#define META_TYPE_COMP_WINDOW (meta_comp_window_get_type ())
|
||||
#define META_COMP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_COMP_WINDOW, MetaCompWindow))
|
||||
#define META_COMP_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_COMP_WINDOW, MetaCompWindowClass))
|
||||
#define IS_META_COMP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_COMP_WINDOW_TYPE))
|
||||
#define META_IS_COMP_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_COMP_WINDOW))
|
||||
#define META_COMP_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_COMP_WINDOW, MetaCompWindowClass))
|
||||
|
||||
typedef struct _MetaCompWindow MetaCompWindow;
|
||||
typedef struct _MetaCompWindowClass MetaCompWindowClass;
|
||||
typedef struct _MetaCompWindowPrivate MetaCompWindowPrivate;
|
||||
|
||||
struct _MetaCompWindowClass
|
||||
{
|
||||
ClutterGroupClass parent_class;
|
||||
};
|
||||
|
||||
struct _MetaCompWindow
|
||||
{
|
||||
ClutterGroup parent;
|
||||
|
||||
MetaCompWindowPrivate *priv;
|
||||
};
|
||||
|
||||
GType meta_comp_window_get_type (void);
|
||||
|
||||
Window meta_comp_window_get_x_window (MetaCompWindow *mcw);
|
||||
MetaCompWindowType meta_comp_window_get_window_type (MetaCompWindow *mcw);
|
||||
gint meta_comp_window_get_workspace (MetaCompWindow *mcw);
|
||||
|
||||
|
||||
/* Compositor API */
|
||||
MetaCompositor *meta_compositor_clutter_new (MetaDisplay *display);
|
||||
|
||||
void meta_compositor_clutter_window_effect_completed (MetaCompWindow *actor, gulong event);
|
||||
|
||||
ClutterActor * meta_compositor_clutter_get_stage_for_screen (MetaScreen *screen);
|
||||
ClutterActor * meta_compositor_clutter_get_overlay_group_for_screen (MetaScreen *screen);
|
||||
|
||||
Window meta_compositor_clutter_get_overlay_window (MetaScreen *screen);
|
||||
|
||||
|
||||
#endif
|
@ -69,5 +69,6 @@ void mutter_window_effect_completed (MutterWindow *actor, gulong event);
|
||||
|
||||
ClutterActor * mutter_get_stage_for_screen (MetaScreen *screen);
|
||||
ClutterActor * mutter_get_overlay_group_for_screen (MetaScreen *screen);
|
||||
Window mutter_get_overlay_window (MetaScreen *screen);
|
||||
|
||||
#endif
|
||||
|
@ -79,8 +79,8 @@ struct MutterPlugin
|
||||
#endif
|
||||
gchar *name; /* Human-readable name for UI */
|
||||
gulong features; /* or-ed feature flags */
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
* This function is called once the plugin has been loaded.
|
||||
*
|
||||
* @params is a string containing additional parameters for the plugin and is
|
||||
@ -94,7 +94,7 @@ struct MutterPlugin
|
||||
* Indicates running in debug mode; the plugin
|
||||
* might want to print useful debug info, or
|
||||
* extend effect duration, etc.
|
||||
*
|
||||
*
|
||||
* 'disable: ...;'
|
||||
*
|
||||
* The disable token indicates that the effects
|
||||
@ -185,8 +185,8 @@ struct MutterPlugin
|
||||
|
||||
/* List of PluginWorkspaceRectangles defining the geometry of individual
|
||||
* workspaces. */
|
||||
GList *work_areas;
|
||||
|
||||
GList *work_areas;
|
||||
|
||||
/* FIXME: It should be possible to hide this from plugins */
|
||||
gint running; /* Plugin must increase this counter for each effect it starts
|
||||
* decrease it again once the effect finishes.
|
||||
@ -202,19 +202,33 @@ struct MutterPlugin
|
||||
};
|
||||
|
||||
void
|
||||
meta_comp_clutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
unsigned long event);
|
||||
mutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
unsigned long event);
|
||||
|
||||
ClutterActor *
|
||||
meta_comp_clutter_plugin_get_overlay_group (MutterPlugin *plugin);
|
||||
mutter_plugin_get_overlay_group (MutterPlugin *plugin);
|
||||
|
||||
ClutterActor *
|
||||
meta_comp_clutter_plugin_get_stage (MutterPlugin *plugin);
|
||||
mutter_plugin_get_stage (MutterPlugin *plugin);
|
||||
|
||||
void
|
||||
meta_comp_clutter_plugin_query_screen_size (MutterPlugin *plugin,
|
||||
int *width,
|
||||
int *height);
|
||||
mutter_plugin_query_screen_size (MutterPlugin *plugin,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_overlay_group (MutterPlugin *plugin);
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_stage (MutterPlugin *plugin);
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_reactive (MutterPlugin *plugin,
|
||||
gboolean reactive);
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_input_area (MutterPlugin *plugin,
|
||||
gint x, gint y, gint width, gint height);
|
||||
|
||||
#endif /* MUTTER_PLUGIN_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user