diff options
Diffstat (limited to 'matchbox2/mb-wm-comp-mgr.c')
-rw-r--r-- | matchbox2/mb-wm-comp-mgr.c | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/matchbox2/mb-wm-comp-mgr.c b/matchbox2/mb-wm-comp-mgr.c new file mode 100644 index 0000000..68063c3 --- /dev/null +++ b/matchbox2/mb-wm-comp-mgr.c @@ -0,0 +1,482 @@ +/* + * Matchbox Window Manager - A lightweight window manager not for the + * desktop. + * + * Authored By Tomas Frydrych <tf@o-hand.com> + * + * Copyright (c) 2002, 2004, 2007 OpenedHand Ltd - http://o-hand.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, 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. + * + */ + +#include "mb-wm.h" +#include "mb-wm-client.h" +#include "mb-wm-comp-mgr.h" +#include "mb-wm-theme.h" + +#include <X11/Xresource.h> +#include <X11/extensions/Xdamage.h> +#include <X11/extensions/Xrender.h> +#include <X11/extensions/Xcomposite.h> + +static void +mb_wm_comp_mgr_client_class_init (MBWMObjectClass *klass) +{ + MBWMCompMgrClientClass *c_klass = MB_WM_COMP_MGR_CLIENT_CLASS (klass); + +#if MBWM_WANT_DEBUG + klass->klass_name = "MBWMCompMgrClient"; +#endif +} + +static int +mb_wm_comp_mgr_client_init (MBWMObject *obj, va_list vap) +{ + MBWMCompMgrClient *client = MB_WM_COMP_MGR_CLIENT (obj); + MBWindowManagerClient *wm_client = NULL; + MBWMObjectProp prop; + XRenderPictFormat *format; + + prop = va_arg(vap, MBWMObjectProp); + while (prop) + { + switch (prop) + { + case MBWMObjectPropClient: + wm_client = va_arg(vap, MBWindowManagerClient *); + break; + default: + MBWMO_PROP_EAT (vap, prop); + } + + prop = va_arg(vap, MBWMObjectProp); + } + + if (!wm_client) + return 0; + + client->wm_client = wm_client; + client->wm = wm_client->wmref; + + /* Check visual */ + format = XRenderFindVisualFormat (client->wm->xdpy, + wm_client->window->visual); + + if (format && format->type == PictTypeDirect && format->direct.alphaMask) + client->is_argb32 = True; + + return 1; +} + +static void +mb_wm_comp_mgr_client_destroy (MBWMObject* obj) +{ + MBWMCompMgrClient *client = MB_WM_COMP_MGR_CLIENT (obj); + MBWindowManagerClient *wm_client = client->wm_client; +} + +int +mb_wm_comp_mgr_client_class_type () +{ + static int type = 0; + + if (UNLIKELY(type == 0)) + { + static MBWMObjectClassInfo info = { + sizeof (MBWMCompMgrClientClass), + sizeof (MBWMCompMgrClient), + mb_wm_comp_mgr_client_init, + mb_wm_comp_mgr_client_destroy, + mb_wm_comp_mgr_client_class_init + }; + + type = mb_wm_object_register_class (&info, MB_WM_TYPE_OBJECT, 0); + } + + return type; +} + +void +mb_wm_comp_mgr_client_hide (MBWMCompMgrClient * client) +{ + MBWMCompMgrClientClass *klass; + + if (!client) + return; + + klass = MB_WM_COMP_MGR_CLIENT_CLASS (MB_WM_OBJECT_GET_CLASS (client)); + + MBWM_ASSERT (klass->hide != NULL); + klass->hide (client); +} + +void +mb_wm_comp_mgr_client_show (MBWMCompMgrClient * client) +{ + MBWMCompMgrClientClass *klass; + + if (!client) + return; + + klass = MB_WM_COMP_MGR_CLIENT_CLASS (MB_WM_OBJECT_GET_CLASS (client)); + + MBWM_ASSERT (klass->show != NULL); + klass->show (client); +} + +void +mb_wm_comp_mgr_client_configure (MBWMCompMgrClient * client) +{ + MBWMCompMgrClientClass *klass; + + if (!client) + return; + + klass = MB_WM_COMP_MGR_CLIENT_CLASS (MB_WM_OBJECT_GET_CLASS (client)); + + MBWM_ASSERT (klass->configure != NULL); + klass->configure (client); +} + +void +mb_wm_comp_mgr_client_repair (MBWMCompMgrClient * client) +{ + MBWMCompMgrClientClass *klass; + + if (!client) + return; + + klass = MB_WM_COMP_MGR_CLIENT_CLASS (MB_WM_OBJECT_GET_CLASS (client)); + + MBWM_ASSERT (klass->repair != NULL); + klass->repair (client); +} + + +/* + * MBWMCompMgr object + * + * Base class for the composite manager, providing the common interface + * through which the manager is access by the MBWindowManager object. + */ +static void +mb_wm_comp_mgr_class_init (MBWMObjectClass *klass) +{ +#if MBWM_WANT_DEBUG + klass->klass_name = "MBWMCompMgr"; +#endif +} + +static int +mb_wm_comp_mgr_init (MBWMObject *obj, va_list vap) +{ + MBWMCompMgr * mgr = MB_WM_COMP_MGR (obj); + MBWindowManager * wm = NULL; + MBWMObjectProp prop; + + prop = va_arg(vap, MBWMObjectProp); + while (prop) + { + switch (prop) + { + case MBWMObjectPropWm: + wm = va_arg(vap, MBWindowManager *); + break; + default: + MBWMO_PROP_EAT (vap, prop); + } + + prop = va_arg(vap, MBWMObjectProp); + } + + if (!wm) + return 0; + + mgr->wm = wm; + mgr->disabled = True; + + return 1; +} + +static void +mb_wm_comp_mgr_destroy (MBWMObject* obj) +{ + MBWMCompMgr * mgr = MB_WM_COMP_MGR (obj); + + mb_wm_comp_mgr_turn_off (mgr); +} + +int +mb_wm_comp_mgr_class_type () +{ + static int type = 0; + + if (UNLIKELY(type == 0)) + { + static MBWMObjectClassInfo info = { + sizeof (MBWMCompMgrClass), + sizeof (MBWMCompMgr), + mb_wm_comp_mgr_init, + mb_wm_comp_mgr_destroy, + mb_wm_comp_mgr_class_init + }; + + type = mb_wm_object_register_class (&info, MB_WM_TYPE_OBJECT, 0); + } + + return type; +} + + +Bool +mb_wm_comp_mgr_enabled (MBWMCompMgr *mgr) +{ + if (!mgr || mgr->disabled) + return False; + + return True; +} + +/* + * Registers new client with the manager (i.e., when a window is created). + */ +void +mb_wm_comp_mgr_register_client (MBWMCompMgr * mgr, + MBWindowManagerClient * client) +{ + MBWMCompMgrClass *klass; + + if (!client) + return; + + klass = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + MBWM_ASSERT (klass->register_client != NULL); + klass->register_client (mgr, client); +} + +/* + * Unregisters existing client (e.g., when window unmaps or is destroyed + */ +void +mb_wm_comp_mgr_unregister_client (MBWMCompMgr * mgr, + MBWindowManagerClient * client) +{ + MBWMCompMgrClass *klass; + + if (!client) + return; + + klass = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + if (!client->cm_client) + return; + + if (klass->unregister_client) + klass->unregister_client (mgr, client); + + mb_wm_object_unref (MB_WM_OBJECT (client->cm_client)); + client->cm_client = NULL; +} + +/* + * Called to render the entire composited scene on screen. + */ +void +mb_wm_comp_mgr_render (MBWMCompMgr *mgr) +{ + MBWMCompMgrClass *klass; + + if (!mgr) + return; + + klass = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + if (klass->render) + klass->render (mgr); +} + +void +mb_wm_comp_mgr_restack (MBWMCompMgr *mgr) +{ + MBWMCompMgrClass *klass; + + if (!mgr) + return; + + klass = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + if (klass->restack) + klass->restack (mgr); +} + +/* + * Called when a window we are interested in maps. + */ +void +mb_wm_comp_mgr_map_notify (MBWMCompMgr *mgr, MBWindowManagerClient *c) +{ + MBWMCompMgrClass *klass; + + if (!mgr || !c || !c->cm_client) + return; + + klass = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + if (klass->map_notify) + klass->map_notify (mgr, c); + + /* + * Run map event effect *before* we call show() on the actor + * (the effect will take care of showing the actor, and if not, show() gets + * called by mb_wm_comp_mgr_map_notify()). + */ + if (!mb_wm_client_is_hiding_from_desktop (c)) + mb_wm_comp_mgr_do_effect (mgr, c, MBWMCompMgrClientEventMap); + + if (c->cm_client) + mb_wm_comp_mgr_client_show (c->cm_client); +} + +void +mb_wm_comp_mgr_unmap_notify (MBWMCompMgr *mgr, MBWindowManagerClient *c) +{ + MBWMCompMgrClass *klass; + + if (!mgr || !c || !c->cm_client) + return; + + klass = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + if (!mb_wm_client_is_hiding_from_desktop (c)) + mb_wm_comp_mgr_do_effect (mgr, c, MBWMCompMgrClientEventUnmap); + + if (klass->unmap_notify) + klass->unmap_notify (mgr, c); + + /* + * NB: cannot call hide() here, as at this point an effect could be running + * -- the subclass needs to take care of this from the effect and/or + * unmap_notify() function. + */ +} + +/* + * Runs a transition-effect from client c1 to client c2; the reverse argument + * indicates notional direction of the transition + */ +void +mb_wm_comp_mgr_do_transition (MBWMCompMgr * mgr, + MBWindowManagerClient *c1, + MBWindowManagerClient *c2, + Bool reverse) +{ + MBWMCompMgrClass *klass; + + /* + * Transitions can only be done for clients of the same type, so + * check the types here. + */ + if (!mgr || !c1 || !c2 || + MB_WM_CLIENT_CLIENT_TYPE (c1) != MB_WM_CLIENT_CLIENT_TYPE (c1)) + return; + + klass = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + if (klass->client_transition) + klass->client_transition (mgr, c1, c2, reverse); +} + +void +mb_wm_comp_mgr_do_effect (MBWMCompMgr * mgr, + MBWindowManagerClient * client, + MBWMCompMgrClientEvent event) +{ + MBWMCompMgrClass *klass; + + /* + * Transitions can only be done for clients of the same type, so + * check the types here. + */ + if (!mgr || !client) + return; + + klass = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + if (klass->client_event) + klass->client_event (mgr, client, event); +} + +void +mb_wm_comp_mgr_select_desktop (MBWMCompMgr * mgr, + int desktop, + int old_desktop) +{ + MBWMCompMgrClass *klass + = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + if (klass->select_desktop) + klass->select_desktop (mgr, desktop, old_desktop); +} + +void +mb_wm_comp_mgr_turn_on (MBWMCompMgr *mgr) +{ + MBWindowManager *wm = mgr->wm; + MBWMCompMgrClass *klass + = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + MBWM_ASSERT (klass->turn_on != NULL); + klass->turn_on (mgr); + + mgr->damage_cb_id = + mb_wm_main_context_x_event_handler_add (wm->main_ctx, + None, + wm->damage_event_base + XDamageNotify, + (MBWMXEventFunc)klass->handle_damage, + mgr); +} + +void +mb_wm_comp_mgr_turn_off (MBWMCompMgr *mgr) +{ + MBWindowManager *wm = mgr->wm; + MBWMCompMgrClass *klass + = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + MBWM_ASSERT (klass->turn_off != NULL); + klass->turn_off (mgr); + + mb_wm_main_context_x_event_handler_remove (wm->main_ctx, + wm->damage_event_base + XDamageNotify, + mgr->damage_cb_id); + + mgr->damage_cb_id = 0; +} + +/* + * Returns true if the window identified by id xwin is a special window + * that belongs to the compositing manager and should, therefore, be left + * alone by MBWMWindow manager (e.g., the overalay window). + */ +Bool +mb_wm_comp_mgr_is_my_window (MBWMCompMgr * mgr, Window xwin) +{ + MBWMCompMgrClass *klass + = MB_WM_COMP_MGR_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); + + if (klass->my_window) + return klass->my_window (mgr, xwin); + + return False; +} + |