1 /* 2 * This file is a part of the Cairo-Dock project 3 * 4 * Copyright : (C) see the 'copyright' file. 5 * E-mail : see the 'copyright' file. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 3 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef __CAIRO_DOCK_CONTAINER__ 21 #define __CAIRO_DOCK_CONTAINER__ 22 23 #include "gldi-config.h" 24 #include <glib.h> 25 #ifdef HAVE_GLX 26 #include <GL/glx.h> // GLXContext 27 #endif 28 #ifdef HAVE_EGL 29 #include <EGL/egl.h> // EGLContext, EGLSurface 30 #endif 31 #include "cairo-dock-struct.h" 32 #include "cairo-dock-manager.h" 33 34 G_BEGIN_DECLS 35 36 /** 37 *@file cairo-dock-container.h This class defines the Containers, that are classic or hardware accelerated animated windows, and exposes common functions, such as redrawing a part of a container or popping a menu on a container. 38 * 39 * A Container is a rectangular on-screen located surface, has the notion of orientation, can hold external datas, monitors the mouse position, and has its own animation loop. 40 * 41 * Docks, Desklets, Dialogs, and Flying-containers all derive from Containers. 42 * 43 */ 44 45 // manager 46 typedef struct _GldiContainersParam GldiContainersParam; 47 typedef struct _GldiContainerAttr GldiContainerAttr; 48 49 #ifndef _MANAGER_DEF_ 50 extern GldiContainersParam myContainersParam; 51 extern GldiManager myContainersMgr; 52 extern GldiObjectManager myContainerObjectMgr; 53 #endif 54 55 #define CD_DOUBLE_CLICK_DELAY 250 // ms 56 57 // params 58 struct _GldiContainersParam{ 59 //gboolean bUseFakeTransparency; 60 gint iGLAnimationDeltaT; 61 gint iCairoAnimationDeltaT; 62 }; 63 64 struct _GldiContainerAttr { 65 gboolean bNoOpengl; 66 }; 67 68 /// signals 69 typedef enum { 70 /// notification called when the menu is being built on a container. data : {Icon, GldiContainer, GtkMenu, gboolean*} 71 NOTIFICATION_BUILD_CONTAINER_MENU = NB_NOTIFICATIONS_OBJECT, 72 /// notification called when the menu is being built on an icon (possibly NULL). data : {Icon, GldiContainer, GtkMenu} 73 NOTIFICATION_BUILD_ICON_MENU, 74 /// notification called when use clicks on an icon data : {Icon, CairoDock, int} 75 NOTIFICATION_CLICK_ICON, 76 /// notification called when the user double-clicks on an icon. data : {Icon, CairoDock} 77 NOTIFICATION_DOUBLE_CLICK_ICON, 78 /// notification called when the user middle-clicks on an icon. data : {Icon, CairoDock} 79 NOTIFICATION_MIDDLE_CLICK_ICON, 80 /// notification called when the user scrolls on an icon. data : {Icon, CairoDock, int} 81 NOTIFICATION_SCROLL_ICON, 82 /// notification called when the mouse enters an icon. data : {Icon, CairoDock, gboolean*} 83 NOTIFICATION_ENTER_ICON, 84 /// notification called when the mouse enters a dock while dragging an object. 85 NOTIFICATION_START_DRAG_DATA, 86 /// notification called when something is dropped inside a container. data : {gchar*, Icon, double*, CairoDock} 87 NOTIFICATION_DROP_DATA, 88 /// notification called when the mouse has moved inside a container. 89 NOTIFICATION_MOUSE_MOVED, 90 /// notification called when a key is pressed in a container that has the focus. 91 NOTIFICATION_KEY_PRESSED, 92 /// notification called for the fast rendering loop on a container. 93 NOTIFICATION_UPDATE, 94 /// notification called for the slow rendering loop on a container. 95 NOTIFICATION_UPDATE_SLOW, 96 /// notification called when a container is rendered. 97 NOTIFICATION_RENDER, 98 NB_NOTIFICATIONS_CONTAINER 99 } GldiContainerNotifications; 100 101 102 // factory 103 /// Main orientation of a container. 104 typedef enum { 105 CAIRO_DOCK_VERTICAL = 0, 106 CAIRO_DOCK_HORIZONTAL 107 } CairoDockTypeHorizontality; 108 109 struct _GldiContainerInterface { 110 gboolean (*animation_loop) (GldiContainer *pContainer); 111 void (*setup_menu) (GldiContainer *pContainer, Icon *pIcon, GtkWidget *pMenu); 112 void (*detach_icon) (GldiContainer *pContainer, Icon *pIcon); 113 void (*insert_icon) (GldiContainer *pContainer, Icon *pIcon, gboolean bAnimateIcon); 114 }; 115 116 /// Definition of a Container, whom derive Dock, Desklet, Dialog and FlyingContainer. 117 struct _GldiContainer { 118 /// object. 119 GldiObject object; 120 /// External data. 121 gpointer pDataSlot[CAIRO_DOCK_NB_DATA_SLOT]; 122 /// window of the container. 123 GtkWidget *pWidget; 124 /// size of the container. 125 gint iWidth, iHeight; 126 /// position of the container. 127 gint iWindowPositionX, iWindowPositionY; 128 /// TURE is the mouse is inside the container (including the possible sub-widgets). 129 gboolean bInside; 130 /// TRUE if the container is horizontal, FALSE if vertical 131 CairoDockTypeHorizontality bIsHorizontal; 132 /// TRUE if the container is oriented upwards, FALSE if downwards. 133 gboolean bDirectionUp; 134 /// Source ID of the animation loop. 135 guint iSidGLAnimation; 136 /// interval of time between 2 animation steps. 137 gint iAnimationDeltaT; 138 /// X position of the mouse in the container's system of reference. 139 gint iMouseX; 140 /// Y position of the mouse in the container's system of reference. 141 gint iMouseY; 142 /// zoom applied to the container's elements. 143 gdouble fRatio; 144 /// TRUE if the container has a reflection power. 145 gboolean bUseReflect; 146 #ifdef HAVE_GLX 147 /// OpenGL context. 148 GLXContext glContext; 149 void *unused; // keep ABI compatibility 150 #elif defined(HAVE_EGL) 151 /// OpenGL context. 152 EGLContext glContext; 153 /// EGL surface. 154 EGLSurface eglSurface; 155 #endif 156 /// whether the GL context is an ortho or a perspective view. 157 gboolean bPerspectiveView; 158 /// TRUE if a slow animation is running. 159 gboolean bKeepSlowAnimation; 160 /// counter for the animation loop. 161 gint iAnimationStep; 162 GldiContainerInterface iface; 163 164 gboolean bIgnoreNextReleaseEvent; 165 gpointer reserved[4]; 166 }; 167 168 169 /// Definition of the Container backend. It defines some operations that should be, but are not, provided by GTK. 170 struct _GldiContainerManagerBackend { 171 void (*reserve_space) (GldiContainer *pContainer, int left, int right, int top, int bottom, int left_start_y, int left_end_y, int right_start_y, int right_end_y, int top_start_x, int top_end_x, int bottom_start_x, int bottom_end_x); 172 int (*get_current_desktop_index) (GldiContainer *pContainer); 173 void (*move) (GldiContainer *pContainer, int iNumDesktop, int iAbsolutePositionX, int iAbsolutePositionY); 174 gboolean (*is_active) (GldiContainer *pContainer); 175 void (*present) (GldiContainer *pContainer); 176 }; 177 178 179 /// Get the Container part of a pointer. 180 #define CAIRO_CONTAINER(p) ((GldiContainer *) (p)) 181 182 /** Say if an object is a Container. 183 *@param obj the object. 184 *@return TRUE if the object is a Container. 185 */ 186 #define CAIRO_DOCK_IS_CONTAINER(obj) gldi_object_is_manager_child (GLDI_OBJECT(obj), &myContainerObjectMgr) 187 188 ///////////// 189 // WINDOW // 190 /////////// 191 192 193 void cairo_dock_set_containers_non_sticky (void); 194 195 void cairo_dock_disable_containers_opacity (void); 196 197 #define gldi_container_get_gdk_window(pContainer) gtk_widget_get_window ((pContainer)->pWidget) 198 199 #define gldi_container_get_Xid(pContainer) GDK_WINDOW_XID (gldi_container_get_gdk_window(pContainer)) 200 201 #define gldi_container_is_visible(pContainer) gtk_widget_get_visible ((pContainer)->pWidget) 202 203 #define gldi_display_get_pointer(xptr, yptr) do {\ 204 GdkDeviceManager *_dm = gdk_display_get_device_manager (gdk_display_get_default());\ 205 GdkDevice *_dev = gdk_device_manager_get_client_pointer (_dm);\ 206 gdk_device_get_position (_dev, NULL, xptr, yptr); } while (0) 207 208 #define gldi_container_update_mouse_position(pContainer) do {\ 209 GdkDeviceManager *pManager = gdk_display_get_device_manager (gtk_widget_get_display (pContainer->pWidget)); \ 210 GdkDevice *pDevice = gdk_device_manager_get_client_pointer (pManager); \ 211 if ((pContainer)->bIsHorizontal) \ 212 gdk_window_get_device_position (gldi_container_get_gdk_window (pContainer), pDevice, &pContainer->iMouseX, &pContainer->iMouseY, NULL); \ 213 else \ 214 gdk_window_get_device_position (gldi_container_get_gdk_window (pContainer), pDevice, &pContainer->iMouseY, &pContainer->iMouseX, NULL); } while (0) 215 216 217 /** Reserve a space on the screen for a Container; other windows won't overlap this space when maximised. 218 *@param pContainer the container 219 *@param left 220 *@param right 221 *@param top 222 *@param bottom 223 *@param left_start_y 224 *@param left_end_y 225 *@param right_start_y 226 *@param right_end_y 227 *@param top_start_x 228 *@param top_end_x 229 *@param bottom_start_x 230 *@param bottom_end_x 231 */ 232 void gldi_container_reserve_space (GldiContainer *pContainer, int left, int right, int top, int bottom, int left_start_y, int left_end_y, int right_start_y, int right_end_y, int top_start_x, int top_end_x, int bottom_start_x, int bottom_end_x); 233 234 /** Get the desktop and viewports a Container is placed on. 235 *@param pContainer the container 236 *@return an index representing the desktop and viewports. 237 */ 238 int gldi_container_get_current_desktop_index (GldiContainer *pContainer); 239 240 /** Move a Container to a given desktop, viewport, and position (similar to gtk_window_move except that the position is defined on the whole desktop (made of all viewports); it's only useful if the Container is sticky). 241 *@param pContainer the container 242 *@param iNumDesktop desktop number 243 *@param iAbsolutePositionX horizontal position on the virtual screen 244 *@param iAbsolutePositionY vertical position on the virtual screen 245 */ 246 void gldi_container_move (GldiContainer *pContainer, int iNumDesktop, int iAbsolutePositionX, int iAbsolutePositionY); 247 248 /** Tell if a Container is the current active window (similar to gtk_window_is_active but actually works). 249 *@param pContainer the container 250 *@return TRUE if the Container is the current active window. 251 */ 252 gboolean gldi_container_is_active (GldiContainer *pContainer); 253 254 /** Show a Container and make it take the focus (similar to gtk_window_present, but bypasses the WM focus steal prevention). 255 *@param pContainer the container 256 */ 257 void gldi_container_present (GldiContainer *pContainer); 258 259 260 void gldi_container_manager_register_backend (GldiContainerManagerBackend *pBackend); 261 262 263 264 //////////// 265 // REDRAW // 266 //////////// 267 268 void cairo_dock_set_default_rgba_visual (GtkWidget *pWidget); 269 270 /** Clear and trigger the redraw of a Container. 271 *@param pContainer the Container to redraw. 272 */ 273 void cairo_dock_redraw_container (GldiContainer *pContainer); 274 275 /** Clear and trigger the redraw of a part of a container. 276 *@param pContainer the Container to redraw. 277 *@param pArea the zone to redraw. 278 */ 279 void cairo_dock_redraw_container_area (GldiContainer *pContainer, GdkRectangle *pArea); 280 281 /** Clear and trigger the redraw of an Icon. The drawing is not done immediately, but when the expose event is received. 282 *@param icon l'icone a retracer. 283 */ 284 void cairo_dock_redraw_icon (Icon *icon); 285 286 287 void cairo_dock_allow_widget_to_receive_data (GtkWidget *pWidget, GCallback pCallBack, gpointer data); 288 289 /** Enable a Container to accept drag-and-drops. 290 * @param pContainer a container. 291 * @param pCallBack the function that will be called when some data is received. 292 * @param data data passed to the callback. 293 */ 294 #define gldi_container_enable_drop(pContainer, pCallBack, data) cairo_dock_allow_widget_to_receive_data (pContainer->pWidget, pCallBack, data) 295 296 void gldi_container_disable_drop (GldiContainer *pContainer); 297 298 /** Notify everybody that a drop has just occured. 299 * @param cReceivedData the dropped data. 300 * @param pPointedIcon the icon which was pointed when the drop occured. 301 * @param fOrder the order of the icon if the drop occured on it, or LAST_ORDER if the drop occured between 2 icons. 302 * @param pContainer the container of the icon 303 */ 304 void gldi_container_notify_drop_data (GldiContainer *pContainer, gchar *cReceivedData, Icon *pPointedIcon, double fOrder); 305 306 307 gboolean cairo_dock_emit_signal_on_container (GldiContainer *pContainer, const gchar *cSignal); 308 gboolean cairo_dock_emit_leave_signal (GldiContainer *pContainer); 309 gboolean cairo_dock_emit_enter_signal (GldiContainer *pContainer); 310 311 /** Build the main menu of a Container. 312 *@param icon the icon that was left-clicked, or NULL if none. 313 *@param pContainer the container that was left-clicked. 314 *@return the menu. 315 */ 316 GtkWidget *gldi_container_build_menu (GldiContainer *pContainer, Icon *icon); 317 318 319 ///////////////// 320 // INPUT SHAPE // 321 ///////////////// 322 323 cairo_region_t *gldi_container_create_input_shape (GldiContainer *pContainer, int x, int y, int w, int h); 324 325 // Note: if gdkwindow->shape == NULL, setting a NULL shape will do nothing 326 #define gldi_container_set_input_shape(pContainer, pShape) \ 327 gtk_widget_input_shape_combine_region ((pContainer)->pWidget, pShape) 328 329 330 void gldi_register_containers_manager (void); 331 332 G_END_DECLS 333 #endif 334