cairo-dock-3.3.2/src/cairo-dock-widget-module.h 000664 001750 001750 00000003517 12223247550 022417 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_WIDGET_MODULE__
#define __CAIRO_DOCK_WIDGET_MODULE__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-widget.h"
G_BEGIN_DECLS
typedef struct _ModuleWidget ModuleWidget;
struct _ModuleWidget {
CDWidget widget;
GldiModule *pModule;
GldiModuleInstance *pModuleInstance;
gchar *cConfFilePath;
GtkWidget *pMainWindow;
};
#define MODULE_WIDGET(w) ((ModuleWidget*)(w))
#define IS_MODULE_WIDGET(w) (w && CD_WIDGET(w)->iType == WIDGET_MODULE)
ModuleWidget *cairo_dock_module_widget_new (GldiModule *pModule, GldiModuleInstance *pInstance, GtkWidget *pMainWindow);
void cairo_dock_module_widget_update_desklet_params (ModuleWidget *pModuleWidget, CairoDesklet *pDesklet);
void cairo_dock_module_widget_update_desklet_visibility_params (ModuleWidget *pModuleWidget, CairoDesklet *pDesklet);
void cairo_dock_module_widget_update_module_instance_container (ModuleWidget *pModuleWidget, GldiModuleInstance *pInstance, gboolean bDetached);
void cairo_dock_module_widget_reload_current_widget (ModuleWidget *pModuleWidget);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/cairo-dock-user-interaction.c 000664 001750 001750 00000045264 12223247550 023144 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include "cairo-dock-icon-facility.h"
#include "cairo-dock-applications-manager.h"
#include "cairo-dock-launcher-manager.h" // gldi_launcher_add_new
#include "cairo-dock-utils.h" // cairo_dock_launch_command_full
#include "cairo-dock-stack-icon-manager.h"
#include "cairo-dock-separator-manager.h"
#include "cairo-dock-applet-manager.h"
#include "cairo-dock-class-icon-manager.h"
#include "cairo-dock-dock-facility.h"
#include "cairo-dock-dialog-factory.h" // gldi_dialog_show_temporary_with_default_icon
#include "cairo-dock-themes-manager.h" // cairo_dock_update_conf_file
#include "cairo-dock-file-manager.h" // cairo_dock_copy_file
#include "cairo-dock-log.h"
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-keybinder.h" // cairo_dock_trigger_shortkey
#include "cairo-dock-animations.h" // gldi_icon_request_animation
#include "cairo-dock-class-manager.h"
#include "cairo-dock-desktop-manager.h"
#include "cairo-dock-windows-manager.h"
#include "cairo-dock-gui-backend.h"
#include "cairo-dock-user-interaction.h"
extern gboolean g_bLocked;
extern gchar *g_cConfFile;
extern gchar *g_cCurrentIconsPath;
static int _compare_zorder (Icon *icon1, Icon *icon2) // classe par z-order decroissant.
{
if (icon1->pAppli->iStackOrder < icon2->pAppli->iStackOrder)
return -1;
else if (icon1->pAppli->iStackOrder > icon2->pAppli->iStackOrder)
return 1;
else
return 0;
}
static void _cairo_dock_hide_show_in_class_subdock (Icon *icon)
{
if (icon->pSubDock == NULL || icon->pSubDock->icons == NULL)
return;
// if the appli has the focus, we hide all the windows, else we show them all
Icon *pIcon;
GList *ic;
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (pIcon->pAppli != NULL && pIcon->pAppli == gldi_windows_get_active ())
{
break;
}
}
if (ic != NULL) // one of the windows of the appli has the focus -> hide.
{
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (pIcon->pAppli != NULL && ! pIcon->pAppli->bIsHidden)
{
gldi_window_minimize (pIcon->pAppli);
}
}
}
else // on montre tout, dans l'ordre du z-order.
{
GList *pZOrderList = NULL;
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (pIcon->pAppli != NULL)
pZOrderList = g_list_insert_sorted (pZOrderList, pIcon, (GCompareFunc) _compare_zorder);
}
int iNumDesktop, iViewPortX, iViewPortY;
gldi_desktop_get_current (&iNumDesktop, &iViewPortX, &iViewPortY);
for (ic = pZOrderList; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (gldi_window_is_on_desktop (pIcon->pAppli, iNumDesktop, iViewPortX, iViewPortY))
break;
}
if (pZOrderList && ic == NULL) // no window on the current desktop -> take the first desktop
{
pIcon = pZOrderList->data;
iNumDesktop = pIcon->pAppli->iNumDesktop;
iViewPortX = pIcon->pAppli->iViewPortX;
iViewPortY = pIcon->pAppli->iViewPortY;
}
for (ic = pZOrderList; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (gldi_window_is_on_desktop (pIcon->pAppli, iNumDesktop, iViewPortX, iViewPortY))
gldi_window_show (pIcon->pAppli);
}
g_list_free (pZOrderList);
}
}
static void _cairo_dock_show_prev_next_in_subdock (Icon *icon, gboolean bNext)
{
if (icon->pSubDock == NULL || icon->pSubDock->icons == NULL)
return;
GldiWindowActor *pActiveAppli = gldi_windows_get_active ();
GList *ic;
Icon *pIcon;
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (pIcon->pAppli == pActiveAppli)
break;
}
if (ic == NULL)
ic = icon->pSubDock->icons;
GList *ic2 = ic;
do
{
ic2 = (bNext ? cairo_dock_get_next_element (ic2, icon->pSubDock->icons) : cairo_dock_get_previous_element (ic2, icon->pSubDock->icons));
pIcon = ic2->data;
if (CAIRO_DOCK_IS_APPLI (pIcon))
{
gldi_window_show (pIcon->pAppli);
break;
}
} while (ic2 != ic);
}
static void _cairo_dock_close_all_in_class_subdock (Icon *icon)
{
if (icon->pSubDock == NULL || icon->pSubDock->icons == NULL)
return;
Icon *pIcon;
GList *ic;
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (pIcon->pAppli != NULL)
{
gldi_window_close (pIcon->pAppli);
}
}
}
static void _show_all_windows (GList *pIcons)
{
Icon *pIcon;
GList *ic;
for (ic = pIcons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (pIcon->pAppli != NULL && pIcon->pAppli->bIsHidden) // a window is hidden...
{
gldi_window_show (pIcon->pAppli);
}
}
}
static gboolean _launch_icon_command (Icon *icon)
{
if (icon->cCommand == NULL)
return GLDI_NOTIFICATION_LET_PASS;
gboolean bSuccess = FALSE;
if (*icon->cCommand == '<') // shortkey
{
bSuccess = cairo_dock_trigger_shortkey (icon->cCommand);
if (!bSuccess)
bSuccess = gldi_icon_launch_command (icon);
}
else // normal command
{
bSuccess = gldi_icon_launch_command (icon);
if (! bSuccess)
bSuccess = cairo_dock_trigger_shortkey (icon->cCommand);
}
if (! bSuccess)
{
gldi_icon_request_animation (icon, "blink", 1); // 1 blink if fail.
}
return GLDI_NOTIFICATION_INTERCEPT;
}
gboolean cairo_dock_notification_click_icon (G_GNUC_UNUSED gpointer pUserData, Icon *icon, GldiContainer *pContainer, guint iButtonState)
{
if (icon == NULL || ! CAIRO_DOCK_IS_DOCK (pContainer))
return GLDI_NOTIFICATION_LET_PASS;
CairoDock *pDock = CAIRO_DOCK (pContainer);
// shit/ctrl + click on an icon that is linked to a program => re-launch this program.
if (iButtonState & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) // shit or ctrl + click
{
if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (icon)
|| CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon)
|| CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (icon))
{
_launch_icon_command (icon);
}
return GLDI_NOTIFICATION_LET_PASS;
}
// scale on an icon holding a class sub-dock.
if (CAIRO_DOCK_IS_MULTI_APPLI(icon))
{
if (myTaskbarParam.bPresentClassOnClick // if we want to use this feature
&& (!myDocksParam.bShowSubDockOnClick // if sub-docks are shown on mouse over
|| gldi_container_is_visible (CAIRO_CONTAINER (icon->pSubDock))) // or this sub-dock is already visible
&& gldi_desktop_present_class (icon->cClass)) // we use the scale plugin if it's possible
{
_show_all_windows (icon->pSubDock->icons); // show all windows
// in case the dock is visible or about to be visible, hide it, as it would confuse the user to have both.
cairo_dock_emit_leave_signal (CAIRO_CONTAINER (icon->pSubDock));
return GLDI_NOTIFICATION_INTERCEPT;
}
}
// else handle sub-docks showing on click, applis and launchers (not applets).
if (icon->pSubDock != NULL && (myDocksParam.bShowSubDockOnClick || !gldi_container_is_visible (CAIRO_CONTAINER (icon->pSubDock)))) // icon pointing to a sub-dock with either "sub-dock activation on click" option enabled, or sub-dock not visible -> open the sub-dock
{
cairo_dock_show_subdock (icon, pDock);
return GLDI_NOTIFICATION_INTERCEPT;
}
else if (CAIRO_DOCK_IS_APPLI (icon) && ! CAIRO_DOCK_IS_APPLET (icon)) // icon holding an appli, but not being an applet -> show/hide the window.
{
GldiWindowActor *pAppli = icon->pAppli;
if (gldi_windows_get_active () == pAppli && myTaskbarParam.bMinimizeOnClick && ! pAppli->bIsHidden && gldi_window_is_on_current_desktop (pAppli)) // ne marche que si le dock est une fenêtre de type 'dock', sinon il prend le focus.
gldi_window_minimize (pAppli);
else
gldi_window_show (pAppli);
return GLDI_NOTIFICATION_INTERCEPT;
}
else if (CAIRO_DOCK_IS_MULTI_APPLI (icon)) // icon holding a class sub-dock -> show/hide the windows of the class.
{
if (! myDocksParam.bShowSubDockOnClick)
{
_cairo_dock_hide_show_in_class_subdock (icon);
}
return GLDI_NOTIFICATION_INTERCEPT;
}
else if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (icon)) // finally, launcher being none of the previous cases -> launch the command
{
if (! gldi_class_is_starting (icon->cClass) && ! gldi_icon_is_launching (icon)) // do not launch it twice (avoid wrong double click) => if we want to launch it 2 times in a row, we have to use Shift + Click
_launch_icon_command (icon);
}
else // for applets and their sub-icons, let the module-instance handles the click; for separators, no action.
{
cd_debug ("no action here");
}
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_middle_click_icon (G_GNUC_UNUSED gpointer pUserData, Icon *icon, GldiContainer *pContainer)
{
if (icon == NULL || ! CAIRO_DOCK_IS_DOCK (pContainer))
return GLDI_NOTIFICATION_LET_PASS;
CairoDock *pDock = CAIRO_DOCK (pContainer);
if (CAIRO_DOCK_IS_APPLI (icon) && ! CAIRO_DOCK_IS_APPLET (icon) && myTaskbarParam.iActionOnMiddleClick != 0)
{
switch (myTaskbarParam.iActionOnMiddleClick)
{
case 1: // close
gldi_window_close (icon->pAppli);
break;
case 2: // minimise
if (! icon->pAppli->bIsHidden)
{
gldi_window_minimize (icon->pAppli);
}
break;
case 3: // launch new
if (icon->cCommand != NULL)
{
gldi_object_notify (pDock, NOTIFICATION_CLICK_ICON, icon, pDock, GDK_SHIFT_MASK); // on emule un shift+clic gauche .
}
break;
}
return GLDI_NOTIFICATION_INTERCEPT;
}
else if (CAIRO_DOCK_IS_MULTI_APPLI (icon) && myTaskbarParam.iActionOnMiddleClick != 0)
{
switch (myTaskbarParam.iActionOnMiddleClick)
{
case 1: // close
_cairo_dock_close_all_in_class_subdock (icon);
break;
case 2: // minimise
_cairo_dock_hide_show_in_class_subdock (icon);
break;
case 3: // launch new
if (icon->cCommand != NULL)
{
gldi_object_notify (CAIRO_CONTAINER (pDock), NOTIFICATION_CLICK_ICON, icon, pDock, GDK_SHIFT_MASK); // on emule un shift+clic gauche .
}
break;
}
return GLDI_NOTIFICATION_INTERCEPT;
}
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_scroll_icon (G_GNUC_UNUSED gpointer pUserData, Icon *icon, G_GNUC_UNUSED GldiContainer *pContainer, int iDirection)
{
if (CAIRO_DOCK_IS_MULTI_APPLI (icon) || CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (icon)) // on emule un alt+tab sur la liste des applis du sous-dock.
{
_cairo_dock_show_prev_next_in_subdock (icon, iDirection == GDK_SCROLL_DOWN);
}
else if (CAIRO_DOCK_IS_APPLI (icon) && icon->cClass != NULL)
{
Icon *pNextIcon = cairo_dock_get_prev_next_classmate_icon (icon, iDirection == GDK_SCROLL_DOWN);
if (pNextIcon != NULL)
gldi_window_show (pNextIcon->pAppli);
}
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_drop_data (G_GNUC_UNUSED gpointer pUserData, const gchar *cReceivedData, Icon *icon, double fOrder, GldiContainer *pContainer)
{
cd_debug ("take the drop");
if (! CAIRO_DOCK_IS_DOCK (pContainer))
return GLDI_NOTIFICATION_LET_PASS;
CairoDock *pDock = CAIRO_DOCK (pContainer);
CairoDock *pReceivingDock = pDock;
if (g_str_has_suffix (cReceivedData, ".desktop")) // .desktop -> add a new launcher if dropped on or amongst launchers.
{
cd_debug (" dropped a .desktop");
if (! myTaskbarParam.bMixLauncherAppli && CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon))
return GLDI_NOTIFICATION_LET_PASS;
cd_debug (" add it");
if (fOrder == CAIRO_DOCK_LAST_ORDER && CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (icon) && icon->pSubDock != NULL) // drop onto a container icon.
{
pReceivingDock = icon->pSubDock; // -> add into the pointed sub-dock.
}
}
else // file.
{
if (icon != NULL && fOrder == CAIRO_DOCK_LAST_ORDER) // dropped on an icon
{
if (CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (icon)) // sub-dock -> propagate to the sub-dock.
{
pReceivingDock = icon->pSubDock;
}
else if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (icon)
|| CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon)
|| CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (icon)) // launcher/appli -> fire the command with this file.
{
if (icon->cCommand == NULL)
return GLDI_NOTIFICATION_LET_PASS;
gchar *cPath = NULL;
if (strncmp (cReceivedData, "file://", 7) == 0) // tous les programmes ne gerent pas les URI; pour parer au cas ou il ne le gererait pas, dans le cas d'un fichier local, on convertit en un chemin
{
cPath = g_filename_from_uri (cReceivedData, NULL, NULL);
}
gchar *cCommand = g_strdup_printf ("%s \"%s\"", icon->cCommand, cPath ? cPath : cReceivedData);
cd_message ("will open the file with the command '%s'...", cCommand);
g_spawn_command_line_async (cCommand, NULL);
g_free (cPath);
g_free (cCommand);
gldi_icon_request_animation (icon, "blink", 2);
return GLDI_NOTIFICATION_INTERCEPT;
}
else // skip any other case.
{
return GLDI_NOTIFICATION_LET_PASS;
}
} // else: dropped between 2 icons -> try to add it (for instance a script).
}
if (g_bLocked || myDocksParam.bLockAll)
return GLDI_NOTIFICATION_LET_PASS;
Icon *pNewIcon = gldi_launcher_add_new (cReceivedData, pReceivingDock, fOrder);
return (pNewIcon ? GLDI_NOTIFICATION_INTERCEPT : GLDI_NOTIFICATION_LET_PASS);
}
void cairo_dock_set_custom_icon_on_appli (const gchar *cFilePath, Icon *icon, GldiContainer *pContainer)
{
g_return_if_fail (CAIRO_DOCK_IS_APPLI (icon) && cFilePath != NULL);
gchar *ext = strrchr (cFilePath, '.');
if (!ext)
return;
cd_debug ("%s (%s - %s)", __func__, cFilePath, icon->cFileName);
if ((strcmp (ext, ".png") == 0 || strcmp (ext, ".svg") == 0) && !myDocksParam.bLockAll) // && ! myDocksParam.bLockIcons) // or if we have to hide the option...
{
if (!myTaskbarParam.bOverWriteXIcons)
{
myTaskbarParam.bOverWriteXIcons = TRUE;
cairo_dock_update_conf_file (g_cConfFile,
G_TYPE_BOOLEAN, "TaskBar", "overwrite xicon", myTaskbarParam.bOverWriteXIcons,
G_TYPE_INVALID);
gldi_dialog_show_temporary_with_default_icon (_("The option 'overwrite X icons' has been automatically enabled in the config.\nIt is located in the 'Taskbar' module."), icon, pContainer, 6000);
}
gchar *cPath = NULL;
if (strncmp (cFilePath, "file://", 7) == 0)
{
cPath = g_filename_from_uri (cFilePath, NULL, NULL);
}
const gchar *cClassIcon = cairo_dock_get_class_icon (icon->cClass);
if (cClassIcon == NULL)
cClassIcon = icon->cClass;
gchar *cDestPath = g_strdup_printf ("%s/%s%s", g_cCurrentIconsPath, cClassIcon, ext);
cairo_dock_copy_file (cPath?cPath:cFilePath, cDestPath);
g_free (cDestPath);
g_free (cPath);
cairo_dock_reload_icon_image (icon, pContainer);
cairo_dock_redraw_icon (icon);
}
}
gboolean cairo_dock_notification_configure_desklet (G_GNUC_UNUSED gpointer pUserData, CairoDesklet *pDesklet)
{
//g_print ("desklet %s configured\n", pDesklet->pIcon?pDesklet->pIcon->cName:"unknown");
cairo_dock_gui_update_desklet_params (pDesklet);
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_icon_moved (G_GNUC_UNUSED gpointer pUserData, Icon *pIcon, G_GNUC_UNUSED CairoDock *pDock)
{
//g_print ("icon %s moved\n", pIcon?pIcon->cName:"unknown");
if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (pIcon)
|| CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (pIcon)
|| (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon) && pIcon->cDesktopFileName)
|| CAIRO_DOCK_ICON_TYPE_IS_APPLET (pIcon))
cairo_dock_gui_trigger_reload_items ();
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_icon_inserted (G_GNUC_UNUSED gpointer pUserData, Icon *pIcon, G_GNUC_UNUSED CairoDock *pDock)
{
//g_print ("icon %s inserted (%.2f)\n", pIcon?pIcon->cName:"unknown", pIcon->fInsertRemoveFactor);
//if (pIcon->fInsertRemoveFactor == 0)
// return GLDI_NOTIFICATION_LET_PASS;
if ( ( (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (pIcon)
|| CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (pIcon)
|| CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) && pIcon->cDesktopFileName)
|| CAIRO_DOCK_ICON_TYPE_IS_APPLET (pIcon))
cairo_dock_gui_trigger_reload_items ();
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_icon_removed (G_GNUC_UNUSED gpointer pUserData, Icon *pIcon, G_GNUC_UNUSED CairoDock *pDock)
{
//g_print ("icon %s removed (%.2f)\n", pIcon?pIcon->cName:"unknown", pIcon->fInsertRemoveFactor);
//if (pIcon->fInsertRemoveFactor == 0)
// return GLDI_NOTIFICATION_LET_PASS;
if ( ( (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (pIcon)
|| CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (pIcon)
|| CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) && pIcon->cDesktopFileName)
|| CAIRO_DOCK_ICON_TYPE_IS_APPLET (pIcon))
cairo_dock_gui_trigger_reload_items ();
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_desklet_added_removed (G_GNUC_UNUSED gpointer pUserData, G_GNUC_UNUSED CairoDesklet *pDesklet)
{
//Icon *pIcon = pDesklet->pIcon;
//g_print ("desklet %s removed\n", pIcon?pIcon->cName:"unknown");
cairo_dock_gui_trigger_reload_items ();
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_dock_destroyed (G_GNUC_UNUSED gpointer pUserData, G_GNUC_UNUSED CairoDock *pDock)
{
//g_print ("dock destroyed\n");
cairo_dock_gui_trigger_reload_items ();
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_module_activated (G_GNUC_UNUSED gpointer pUserData, const gchar *cModuleName, G_GNUC_UNUSED gboolean bActivated)
{
//g_print ("module %s (de)activated (%d)\n", cModuleName, bActivated);
cairo_dock_gui_trigger_update_module_state (cModuleName);
cairo_dock_gui_trigger_reload_items (); // for plug-ins that don't have an applet, like Cairo-Pinguin.
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_module_registered (G_GNUC_UNUSED gpointer pUserData, G_GNUC_UNUSED const gchar *cModuleName, G_GNUC_UNUSED gboolean bRegistered)
{
//g_print ("module %s (un)registered (%d)\n", cModuleName, bRegistered);
cairo_dock_gui_trigger_update_modules_list ();
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_module_detached (G_GNUC_UNUSED gpointer pUserData, GldiModuleInstance *pInstance, gboolean bIsDetached)
{
//g_print ("module %s (de)tached (%d)\n", pInstance->pModule->pVisitCard->cModuleName, bIsDetached);
cairo_dock_gui_trigger_update_module_container (pInstance, bIsDetached);
cairo_dock_gui_trigger_reload_items ();
return GLDI_NOTIFICATION_LET_PASS;
}
gboolean cairo_dock_notification_shortkey_added_removed_changed (G_GNUC_UNUSED gpointer pUserData, G_GNUC_UNUSED GldiShortkey *pShortkey)
{
cairo_dock_gui_trigger_reload_shortkeys ();
return GLDI_NOTIFICATION_LET_PASS;
}
cairo-dock-3.3.2/src/cairo-dock-widget-plugins.c 000664 001750 001750 00000035202 12223247550 022602 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include "config.h"
#include "cairo-dock-struct.h"
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-module-manager.h"
#include "cairo-dock-gui-factory.h"
#include "cairo-dock-log.h"
#include "cairo-dock-menu.h" // cairo_dock_add_in_menu_with_stock_and_data
#include "cairo-dock-desktop-manager.h" // gldi_desktop_get_width
#include "cairo-dock-gui-manager.h" // cairo_dock_show_module_instance_gui
#include "cairo-dock-gui-backend.h" // cairo_dock_show_module_gui
#include "cairo-dock-gui-commons.h" // cairo_dock_get_third_party_applets_link
#include "cairo-dock-widget-plugins.h"
#define CAIRO_DOCK_PREVIEW_HEIGHT 250 // matttbe: 200
#define CAIRO_DOCK_PLUGINS_ICON_SIZE 32
extern gchar *g_cConfFile;
extern GldiContainer *g_pPrimaryContainer;
static void _widget_plugins_reload (CDWidget *pCdWidget);
static void _cairo_dock_activate_one_module (G_GNUC_UNUSED GtkCellRendererToggle * cell_renderer, gchar * path, GtkTreeModel * model)
{
GtkTreeIter iter;
if (! gtk_tree_model_get_iter_from_string (model, &iter, path))
return ;
gchar *cModuleName = NULL;
gboolean bState;
gtk_tree_model_get (model, &iter,
CAIRO_DOCK_MODEL_RESULT, &cModuleName,
CAIRO_DOCK_MODEL_ACTIVE, &bState, -1);
bState = !bState;
gtk_list_store_set (GTK_LIST_STORE (model), &iter, CAIRO_DOCK_MODEL_ACTIVE, bState, -1);
GldiModule *pModule = gldi_module_get (cModuleName);
if (g_pPrimaryContainer == NULL)
{
cairo_dock_add_remove_element_to_key (g_cConfFile, "System", "modules", cModuleName, bState);
}
else if (pModule->pInstancesList == NULL)
{
gldi_module_activate (pModule);
}
else
{
gldi_module_deactivate (pModule);
} // la ligne passera en gras automatiquement.
g_free (cModuleName);
}
static void _cairo_dock_initiate_config_module (G_GNUC_UNUSED GtkMenuItem *pMenuItem, GldiModule *pModule)
{
GldiModuleInstance *pModuleInstance = (pModule->pInstancesList ? pModule->pInstancesList->data : NULL);
if (pModuleInstance)
cairo_dock_show_module_instance_gui (pModuleInstance, -1);
else
cairo_dock_show_module_gui (pModule->pVisitCard->cModuleName);
}
static gboolean _on_click_module_tree_view (GtkTreeView *pTreeView, GdkEventButton* pButton, G_GNUC_UNUSED gpointer data)
{
if ((pButton->button == 3 && pButton->type == GDK_BUTTON_RELEASE) // right click
|| (pButton->button == 1 && pButton->type == GDK_2BUTTON_PRESS)) // double click
{
GtkTreeSelection *pSelection = gtk_tree_view_get_selection (pTreeView);
GtkTreeModel *pModel;
GtkTreeIter iter;
if (! gtk_tree_selection_get_selected (pSelection, &pModel, &iter))
return FALSE;
gchar *cModuleName = NULL;
gtk_tree_model_get (pModel, &iter,
CAIRO_DOCK_MODEL_RESULT, &cModuleName, -1);
GldiModule *pModule = gldi_module_get (cModuleName);
if (pModule == NULL)
return FALSE;
if (pModule->pInstancesList == NULL) // on ne gere pas la config d'un module non actif, donc inutile de presenter le menu dans ce cas-la.
return FALSE;
if (pButton->button == 3)
{
GtkWidget *pMenu = gtk_menu_new ();
cairo_dock_add_in_menu_with_stock_and_data (_("Configure this applet"), GTK_STOCK_PROPERTIES, G_CALLBACK (_cairo_dock_initiate_config_module), pMenu, pModule);
gtk_widget_show_all (pMenu);
gtk_menu_popup (GTK_MENU (pMenu),
NULL,
NULL,
NULL,
NULL,
1,
gtk_get_current_event_time ());
}
else
{
_cairo_dock_initiate_config_module (NULL, pModule);
}
}
return FALSE;
}
static void _cairo_dock_render_module_name (G_GNUC_UNUSED GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *model,GtkTreeIter *iter, G_GNUC_UNUSED gpointer data)
{
gboolean bActive = FALSE;
gtk_tree_model_get (model, iter, CAIRO_DOCK_MODEL_ACTIVE, &bActive, -1);
if (bActive)
g_object_set (cell, "weight", 800, "weight-set", TRUE, NULL);
else
g_object_set (cell, "weight", 400, "weight-set", FALSE, NULL);
}
static void _cairo_dock_render_category (G_GNUC_UNUSED GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *model,GtkTreeIter *iter, G_GNUC_UNUSED gpointer data)
{
const gchar *cCategory=NULL;
gint iCategory = 0;
gtk_tree_model_get (model, iter, CAIRO_DOCK_MODEL_STATE, &iCategory, -1);
switch (iCategory)
{
case CAIRO_DOCK_CATEGORY_APPLET_FILES:
cCategory = _("Files");
g_object_set (cell, "foreground", "#004EA1", NULL); // blue
g_object_set (cell, "foreground-set", TRUE, NULL);
break;
case CAIRO_DOCK_CATEGORY_APPLET_INTERNET:
cCategory = _("Internet");
g_object_set (cell, "foreground", "#FF5555", NULL); // orange
g_object_set (cell, "foreground-set", TRUE, NULL);
break;
case CAIRO_DOCK_CATEGORY_APPLET_DESKTOP:
cCategory = _("Desktop");
g_object_set (cell, "foreground", "#116E08", NULL); // green
g_object_set (cell, "foreground-set", TRUE, NULL);
break;
case CAIRO_DOCK_CATEGORY_APPLET_ACCESSORY:
cCategory = _("Accessory");
g_object_set (cell, "foreground", "#900009", NULL); // red
g_object_set (cell, "foreground-set", TRUE, NULL);
break;
case CAIRO_DOCK_CATEGORY_APPLET_SYSTEM:
cCategory = _("System");
g_object_set (cell, "foreground", "#A58B0D", NULL); // yellow
g_object_set (cell, "foreground-set", TRUE, NULL);
break;
case CAIRO_DOCK_CATEGORY_APPLET_FUN:
cCategory = _("Fun");
g_object_set (cell, "foreground", "#FF55FF", NULL); // purple
g_object_set (cell, "foreground-set", TRUE, NULL);
break;
case CAIRO_DOCK_CATEGORY_BEHAVIOR: // help applet
cCategory = _("Behaviour");
g_object_set (cell, "foreground", "#000066", NULL); // dark blue
g_object_set (cell, "foreground-set", TRUE, NULL);
break;
default:
cd_warning ("incorrect category (%d)", iCategory);
break;
}
if (cCategory != NULL)
{
g_object_set (cell, "text", cCategory, NULL);
}
}
static gboolean _cairo_dock_add_module_to_modele (gchar *cModuleName, GldiModule *pModule, GtkListStore *pModel)
{
if (pModule->pVisitCard->iCategory != CAIRO_DOCK_CATEGORY_THEME // don't display the animations plug-ins
&& ! gldi_module_is_auto_loaded (pModule)) // don't display modules that can't be disabled
{
//g_print (" + %s\n", pModule->pVisitCard->cIconFilePath);
gchar *cIcon = cairo_dock_get_icon_for_gui (pModule->pVisitCard->cModuleName,
pModule->pVisitCard->cIconFilePath,
pModule->pVisitCard->cShareDataDir,
CAIRO_DOCK_PLUGINS_ICON_SIZE,
TRUE);
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (cIcon, CAIRO_DOCK_PLUGINS_ICON_SIZE, CAIRO_DOCK_PLUGINS_ICON_SIZE, NULL);
g_free (cIcon);
GtkTreeIter iter;
memset (&iter, 0, sizeof (GtkTreeIter));
gtk_list_store_append (GTK_LIST_STORE (pModel), &iter);
gtk_list_store_set (GTK_LIST_STORE (pModel), &iter,
CAIRO_DOCK_MODEL_NAME, pModule->pVisitCard->cTitle,
CAIRO_DOCK_MODEL_RESULT, cModuleName,
CAIRO_DOCK_MODEL_DESCRIPTION_FILE, dgettext (pModule->pVisitCard->cGettextDomain, pModule->pVisitCard->cDescription),
CAIRO_DOCK_MODEL_IMAGE, pModule->pVisitCard->cPreviewFilePath,
CAIRO_DOCK_MODEL_ICON, pixbuf,
CAIRO_DOCK_MODEL_STATE, pModule->pVisitCard->iCategory,
CAIRO_DOCK_MODEL_ACTIVE, (pModule->pInstancesList != NULL), -1);
g_object_unref (pixbuf);
}
return FALSE;
}
static GtkWidget *_cairo_dock_build_modules_treeview (void)
{
//\______________ On construit le treeview des modules.
GtkWidget *pOneWidget = cairo_dock_gui_make_tree_view (FALSE);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (pOneWidget), TRUE);
gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (pOneWidget), TRUE);
g_signal_connect (G_OBJECT (pOneWidget), "button-release-event", G_CALLBACK (_on_click_module_tree_view), NULL); // pour le menu du clic droit
g_signal_connect (G_OBJECT (pOneWidget), "button-press-event", G_CALLBACK (_on_click_module_tree_view), NULL); // pour le menu du clic droit
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pOneWidget));
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
//\______________ On remplit le modele avec les modules de la categorie.
GtkTreeModel *pModel = gtk_tree_view_get_model (GTK_TREE_VIEW (pOneWidget));
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (pModel), CAIRO_DOCK_MODEL_STATE, GTK_SORT_ASCENDING);
gldi_module_foreach ((GHRFunc) _cairo_dock_add_module_to_modele, pModel);
//\______________ On definit l'affichage du modele dans le tree-view.
GtkTreeViewColumn* col;
GtkCellRenderer *rend;
// case a cocher
rend = gtk_cell_renderer_toggle_new ();
col = gtk_tree_view_column_new_with_attributes (NULL, rend, "active", CAIRO_DOCK_MODEL_ACTIVE, NULL);
gtk_tree_view_column_set_sort_column_id (col, CAIRO_DOCK_MODEL_ACTIVE);
gtk_tree_view_append_column (GTK_TREE_VIEW (pOneWidget), col);
g_signal_connect (G_OBJECT (rend), "toggled", (GCallback) _cairo_dock_activate_one_module, pModel);
// icone
rend = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (pOneWidget), -1, NULL, rend, "pixbuf", CAIRO_DOCK_MODEL_ICON, NULL);
// nom
rend = gtk_cell_renderer_text_new ();
col = gtk_tree_view_column_new_with_attributes (_("Plug-in"), rend, "text", CAIRO_DOCK_MODEL_NAME, NULL);
gtk_tree_view_column_set_cell_data_func (col, rend, (GtkTreeCellDataFunc)_cairo_dock_render_module_name, NULL, NULL);
gtk_tree_view_column_set_sort_column_id (col, CAIRO_DOCK_MODEL_NAME);
gtk_tree_view_append_column (GTK_TREE_VIEW (pOneWidget), col);
// categorie
rend = gtk_cell_renderer_text_new ();
col = gtk_tree_view_column_new_with_attributes (_("Category"), rend, "text", CAIRO_DOCK_MODEL_STATE, NULL);
gtk_tree_view_column_set_cell_data_func (col, rend, (GtkTreeCellDataFunc)_cairo_dock_render_category, NULL, NULL);
gtk_tree_view_column_set_sort_column_id (col, CAIRO_DOCK_MODEL_STATE);
gtk_tree_view_append_column (GTK_TREE_VIEW (pOneWidget), col);
return pOneWidget;
}
static void _build_plugins_widget (PluginsWidget *pPluginsWidget)
{
//\_____________ On construit le tree-view.
pPluginsWidget->pTreeView = _cairo_dock_build_modules_treeview ();
//\_____________ On l'ajoute a la fenetre.
GtkWidget *pKeyBox = _gtk_hbox_new (CAIRO_DOCK_GUI_MARGIN);
GtkWidget *pScrolledWindow = gtk_scrolled_window_new (NULL, NULL);
g_object_set (pScrolledWindow, "height-request", MIN (2*CAIRO_DOCK_PREVIEW_HEIGHT, gldi_desktop_get_height() - 210), NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pScrolledWindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
#if GTK_CHECK_VERSION (3, 8, 0)
gtk_container_add (GTK_CONTAINER (pScrolledWindow), pPluginsWidget->pTreeView);
#else
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (pScrolledWindow), pPluginsWidget->pTreeView);
#endif
gtk_box_pack_start (GTK_BOX (pKeyBox), pScrolledWindow, TRUE, TRUE, 0);
//\______________ On construit le widget de prevue et on le rajoute a la suite.
GPtrArray *pDataGarbage = g_ptr_array_new ();
gchar *cDefaultMessage = g_strdup_printf ("%s", _("Click on an applet in order to have a preview and a description for it."));
GtkWidget *pPreviewBox = cairo_dock_gui_make_preview_box (pKeyBox, pPluginsWidget->pTreeView, FALSE, 1, cDefaultMessage, CAIRO_DOCK_SHARE_DATA_DIR"/images/"CAIRO_DOCK_LOGO, pDataGarbage); // vertical packaging.
GtkWidget *pScrolledWindow2 = gtk_scrolled_window_new (NULL, NULL);
g_object_set (pScrolledWindow, "height-request", MIN (2*CAIRO_DOCK_PREVIEW_HEIGHT, gldi_desktop_get_height() - 210), NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pScrolledWindow2), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
#if GTK_CHECK_VERSION (3, 8, 0)
gtk_container_add (GTK_CONTAINER (pScrolledWindow2), pPreviewBox);
#else
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (pScrolledWindow2), pPreviewBox);
#endif
gtk_box_pack_start (GTK_BOX (pKeyBox), pScrolledWindow2, FALSE, FALSE, 0);
g_free (cDefaultMessage);
GtkWidget *pVBox = _gtk_vbox_new (CAIRO_DOCK_GUI_MARGIN);
gtk_box_pack_start (GTK_BOX (pVBox), pKeyBox, TRUE, TRUE, 0);
//\______________ Add a link to the third-party applet (Note: it's somewhere around here that we could add a third-party addons selector).
gchar *cLink = cairo_dock_get_third_party_applets_link ();
GtkWidget *pLink = gtk_link_button_new_with_label (cLink, _("Get more applets!"));
g_free (cLink);
gtk_box_pack_start (GTK_BOX (pVBox), pLink, FALSE, FALSE, 0);
pPluginsWidget->widget.pWidget = pVBox;
pPluginsWidget->widget.pDataGarbage = pDataGarbage;
}
PluginsWidget *cairo_dock_plugins_widget_new (void)
{
PluginsWidget *pPluginsWidget = g_new0 (PluginsWidget, 1);
pPluginsWidget->widget.iType = WIDGET_PLUGINS;
pPluginsWidget->widget.apply = NULL; // no apply button
pPluginsWidget->widget.reset = NULL; // nothing special to clean
pPluginsWidget->widget.reload = _widget_plugins_reload;
_build_plugins_widget (pPluginsWidget);
return pPluginsWidget;
}
static gboolean _update_module_checkbox (GtkTreeModel *pModel, G_GNUC_UNUSED GtkTreePath *path, GtkTreeIter *iter, gpointer *data)
{
gchar *cWantedModuleName = data[0];
gchar *cModuleName = NULL;
gtk_tree_model_get (pModel, iter,
CAIRO_DOCK_MODEL_RESULT, &cModuleName, -1);
if (cModuleName && strcmp (cModuleName, cWantedModuleName) == 0)
{
gtk_list_store_set (GTK_LIST_STORE (pModel), iter, CAIRO_DOCK_MODEL_ACTIVE, data[1], -1);
g_free (cModuleName);
return TRUE;
}
g_free (cModuleName);
return FALSE;
}
void cairo_dock_widget_plugins_update_module_state (PluginsWidget *pPluginsWidget, const gchar *cModuleName, gboolean bActive)
{
GtkTreeModel *pModel = gtk_tree_view_get_model (GTK_TREE_VIEW (pPluginsWidget->pTreeView));
gpointer data[2] = {(gpointer)cModuleName, GINT_TO_POINTER (bActive)};
gtk_tree_model_foreach (GTK_TREE_MODEL (pModel), (GtkTreeModelForeachFunc) _update_module_checkbox, data);
}
static void _widget_plugins_reload (CDWidget *pCdWidget)
{
PluginsWidget *pPluginsWidget = PLUGINS_WIDGET (pCdWidget);
GtkTreeModel *pModel = gtk_tree_view_get_model (GTK_TREE_VIEW (pPluginsWidget->pTreeView));
g_return_if_fail (pModel != NULL);
gtk_list_store_clear (GTK_LIST_STORE (pModel));
gldi_module_foreach ((GHRFunc) _cairo_dock_add_module_to_modele, pModel);
}
cairo-dock-3.3.2/src/cairo-dock-widget-config-group.h 000664 001750 001750 00000002632 12223247550 023526 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_WIDGET_CONFIG_GROUP__
#define __CAIRO_DOCK_WIDGET_CONFIG_GROUP__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-widget.h"
G_BEGIN_DECLS
typedef struct _ConfigGroupWidget ConfigGroupWidget;
struct _ConfigGroupWidget {
CDWidget widget;
gchar *cGroupName;
GList *pManagers;
GSList *pExtraWidgets;
};
#define CONFIG_GROUP_WIDGET(w) ((ConfigGroupWidget*)(w))
#define IS_CONFIG_GROUP_WIDGET(w) (w && CD_WIDGET(w)->iType == WIDGET_CONFIG_GROUP)
ConfigGroupWidget *cairo_dock_config_group_widget_new (const gchar *cGroupName, GList *pManagers, const gchar *cTitle, const gchar *cIcon);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/cairo-dock-gui-advanced.h 000664 001750 001750 00000001654 12223247550 022200 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_GUI_ADVANCED__
#define __CAIRO_DOCK_GUI_ADVANCED__
G_BEGIN_DECLS
void cairo_dock_register_advanced_gui_backend (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/cairo-dock-widget-config-group.c 000664 001750 001750 00000017236 12223247550 023527 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include "config.h"
#include "cairo-dock-struct.h"
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-module-manager.h"
#include "cairo-dock-themes-manager.h" // cairo_dock_write_keys_to_conf_file
#include "cairo-dock-module-instance-manager.h" // gldi_module_instance_reload
#include "cairo-dock-gui-factory.h"
#include "cairo-dock-log.h"
#include "cairo-dock-widget-config-group.h"
#define CAIRO_DOCK_ICON_MARGIN 6
extern gchar *g_cConfFile;
static void _config_group_widget_apply (CDWidget *pCdWidget)
{
ConfigGroupWidget *pConfigGroupWidget = CONFIG_GROUP_WIDGET (pCdWidget);
// update the conf file.
GKeyFile *pKeyFile = cairo_dock_open_key_file (g_cConfFile);
g_return_if_fail (pKeyFile != NULL);
cairo_dock_update_keyfile_from_widget_list (pKeyFile, pCdWidget->pWidgetList);
cairo_dock_write_keys_to_conf_file (pKeyFile, g_cConfFile);
g_key_file_free (pKeyFile);
// reload the associated managers.
const gchar *cManagerName, *cModuleName;
GldiModule *pModule;
GldiModuleInstance *pExtraInstance;
GldiManager *pManager;
GSList *pExtraWidgetList;
GKeyFile* pExtraKeyFile;
GList *m, *e;
GSList *w = pConfigGroupWidget->pExtraWidgets;
for (m = pConfigGroupWidget->pManagers; m != NULL; m = m->next)
{
cManagerName = m->data;
pManager = gldi_manager_get (cManagerName);
g_return_if_fail (pManager != NULL);
gldi_object_reload (GLDI_OBJECT(pManager), TRUE);
// reload the extensions too
for (e = pManager->pExternalModules; e != NULL && w != NULL; e = e->next)
{
// get the extension
cModuleName = e->data;
pModule = gldi_module_get (cModuleName);
if (!pModule)
continue;
pExtraInstance = pModule->pInstancesList->data;
if (pExtraInstance == NULL)
continue;
// update its conf file
pExtraKeyFile = cairo_dock_open_key_file (pExtraInstance->cConfFilePath);
if (pExtraKeyFile == NULL)
continue;
pExtraWidgetList = w->data;
w = w->next;
cairo_dock_update_keyfile_from_widget_list (pExtraKeyFile, pExtraWidgetList);
if (pModule->pInterface->save_custom_widget != NULL)
pModule->pInterface->save_custom_widget (pExtraInstance, pKeyFile, pExtraWidgetList);
cairo_dock_write_keys_to_conf_file (pExtraKeyFile, pExtraInstance->cConfFilePath);
g_key_file_free (pExtraKeyFile);
// reload it
gldi_object_reload (GLDI_OBJECT(pExtraInstance), TRUE);
}
}
}
static void _config_group_widget_reset (CDWidget *pCdWidget)
{
ConfigGroupWidget *pConfigGroupWidget = CONFIG_GROUP_WIDGET (pCdWidget);
g_free (pConfigGroupWidget->cGroupName);
g_slist_foreach (pConfigGroupWidget->pExtraWidgets, (GFunc)cairo_dock_free_generated_widget_list, NULL);
g_slist_free (pConfigGroupWidget->pExtraWidgets);
memset (pCdWidget+1, 0, sizeof (ConfigGroupWidget) - sizeof (CDWidget)); // reset all our parameters.
}
ConfigGroupWidget *cairo_dock_config_group_widget_new (const gchar *cGroupName, GList *pManagers, const gchar *cTitle, const gchar *cIcon)
{
ConfigGroupWidget *pConfigGroupWidget = g_new0 (ConfigGroupWidget, 1);
pConfigGroupWidget->widget.iType = WIDGET_CONFIG_GROUP;
pConfigGroupWidget->widget.apply = _config_group_widget_apply;
pConfigGroupWidget->widget.reset = _config_group_widget_reset;
pConfigGroupWidget->cGroupName = g_strdup (cGroupName);
pConfigGroupWidget->pManagers = pManagers;
// build its widget based on its config file.
GKeyFile* pKeyFile = cairo_dock_open_key_file (g_cConfFile);
g_return_val_if_fail (pKeyFile != NULL, NULL);
GSList *pWidgetList = NULL;
GPtrArray *pDataGarbage = g_ptr_array_new ();
GtkWidget *pWidget = cairo_dock_build_group_widget (pKeyFile,
cGroupName,
NULL, // gettext domain
NULL, // main window
&pWidgetList,
pDataGarbage,
g_strdup (CAIRO_DOCK_SHARE_DATA_DIR"/"CAIRO_DOCK_CONF_FILE));
pConfigGroupWidget->widget.pWidgetList = pWidgetList;
pConfigGroupWidget->widget.pDataGarbage = pDataGarbage;
// build the widgets of the extensions
GtkWidget *pNoteBook = NULL;
GKeyFile* pExtraKeyFile;
GldiModule *pModule;
GldiModuleInstance *pExtraInstance;
GSList *pExtraWidgetList;
gchar *cOriginalConfFilePath;
GldiManager *pManager;
const gchar *cManagerName, *cModuleName;
GList *m, *e;
for (m = pManagers; m != NULL; m = m->next)
{
cManagerName = m->data;
pManager = gldi_manager_get (cManagerName);
if (!pManager)
continue;
for (e = pManager->pExternalModules; e != NULL; e = e->next)
{
cModuleName = e->data;
pModule = gldi_module_get (cModuleName);
if (!pModule)
continue;
pExtraInstance = pModule->pInstancesList->data;
if (pExtraInstance == NULL)
continue;
pExtraKeyFile = cairo_dock_open_key_file (pExtraInstance->cConfFilePath);
if (pExtraKeyFile == NULL)
continue;
pExtraWidgetList = NULL;
cOriginalConfFilePath = g_strdup_printf ("%s/%s", pModule->pVisitCard->cShareDataDir, pModule->pVisitCard->cConfFileName);
pNoteBook = cairo_dock_build_key_file_widget (pExtraKeyFile,
pModule->pVisitCard->cGettextDomain,
NULL,
&pExtraWidgetList,
pDataGarbage, // the garbage array can be mutualized with 'pConfigGroupWidget'
cOriginalConfFilePath); /// TODO : fournir pNoteBook a la fonction pour fusionner les differents modules extra...
pConfigGroupWidget->pExtraWidgets = g_slist_append (pConfigGroupWidget->pExtraWidgets, pExtraWidgetList); // append, so that we can parse the list in the same order again.
if (pModule->pInterface->load_custom_widget != NULL)
pModule->pInterface->load_custom_widget (pExtraInstance, pExtraKeyFile, pExtraWidgetList);
///g_free (cOriginalConfFilePath);
g_key_file_free (pExtraKeyFile);
}
}
// on rajoute la page du module interne en 1er dans le notebook.
if (pNoteBook != NULL)
{
GtkWidget *pLabel = gtk_label_new (cTitle);
GtkWidget *pLabelContainer = NULL;
GtkWidget *pAlign = NULL;
if (cIcon != NULL && *cIcon != '\0')
{
pLabelContainer = _gtk_hbox_new (CAIRO_DOCK_ICON_MARGIN);
pAlign = gtk_alignment_new (0., 0.5, 0., 0.);
gtk_container_add (GTK_CONTAINER (pAlign), pLabelContainer);
GtkWidget *pImage = _gtk_image_new_from_file (cIcon, GTK_ICON_SIZE_BUTTON);
gtk_container_add (GTK_CONTAINER (pLabelContainer),
pImage);
gtk_container_add (GTK_CONTAINER (pLabelContainer), pLabel);
gtk_widget_show_all (pLabelContainer);
}
GtkWidget *pScrolledWindow = gtk_scrolled_window_new (NULL, NULL); // add scrollbars on the widget before putting it into the notebook.
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pScrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
#if GTK_CHECK_VERSION (3, 8, 0)
gtk_container_add (GTK_CONTAINER (pScrolledWindow), pWidget);
#else
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (pScrolledWindow), pWidget);
#endif
gtk_notebook_prepend_page (GTK_NOTEBOOK (pNoteBook), pScrolledWindow, (pAlign != NULL ? pAlign : pLabel));
pWidget = pNoteBook;
}
pConfigGroupWidget->widget.pWidget = pWidget;
g_key_file_free (pKeyFile);
return pConfigGroupWidget;
}
cairo-dock-3.3.2/src/cairo-dock-widget-shortkeys.h 000664 001750 001750 00000002641 12223247550 023162 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_WIDGET_SHORKEYS__
#define __CAIRO_DOCK_WIDGET_SHORKEYS__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-widget.h"
G_BEGIN_DECLS
typedef struct _ShortkeysWidget ShortkeysWidget;
struct _ShortkeysWidget {
CDWidget widget;
GtkWidget *pShortKeysTreeView;
int iIconSize;
int iTaskbarType;
gchar *cHoverAnim;
gchar *cHoverEffect;
gchar *cClickAnim;
gchar *cClickEffect;
int iEffectOnDisappearance;
};
#define SHORKEYS_WIDGET(w) ((ShortkeysWidget*)(w))
#define IS_SHORKEYS_WIDGET(w) (w && CD_WIDGET(w)->iType == WIDGET_SHORKEYS)
ShortkeysWidget *cairo_dock_shortkeys_widget_new (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/cairo-dock-gui-commons.h 000664 001750 001750 00000004415 12223247550 022104 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_GUI_COMMONS__
#define __CAIRO_DOCK_GUI_COMMONS__
#include
#include
/**
*@file cairo-dock-gui-commons.h Common helpers for GUI management.
*/
G_BEGIN_DECLS
void cairo_dock_update_desklet_widgets (CairoDesklet *pDesklet, GSList *pWidgetList);
void cairo_dock_update_desklet_visibility_widgets (CairoDesklet *pDesklet, GSList *pWidgetList);
void cairo_dock_update_is_detached_widget (gboolean bIsDetached, GSList *pWidgetList);
/**
* Popup a menu under the given widget.
* Can be used as a callback for the clicked event.
* @param pWidget The widget whose position and size will be considered.
* Can be NULL, the menu will pop under the mouse.
* @param pMenu The given menu to popup.
* @code
* g_signal_connect (
* G_OBJECT (pButton),
* "clicked",
* G_CALLBACK (cairo_dock_popup_menu_under_widget),
* GTK_MENU (pMenu)
* );
* @endcode
*/
void cairo_dock_popup_menu_under_widget (GtkWidget *pWidget, GtkMenu *pMenu);
gchar *cairo_dock_get_third_party_applets_link (void);
/**
* Look for an icon for GUI
* @param cGroupName The name of the module
* @param cIcon The name of an icon, or its path, or a GTK icon
* @param cShareDataDir The directory of the module (where we can find an 'icon' file)
* @param iSize The best size for the new icon
* @param bFastLoad To not check if the file exists or not
*/
gchar *cairo_dock_get_icon_for_gui (const gchar *cGroupName, const gchar *cIcon, const gchar *cShareDataDir, gint iSize, gboolean bFastLoad);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/cairo-dock-widget-plugins.h 000664 001750 001750 00000002565 12223247550 022615 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_WIDGET_PLUGINS__
#define __CAIRO_DOCK_WIDGET_PLUGINS__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-widget.h"
G_BEGIN_DECLS
typedef struct _PluginsWidget PluginsWidget;
struct _PluginsWidget {
CDWidget widget;
GtkWidget *pTreeView;
};
#define PLUGINS_WIDGET(w) ((PluginsWidget*)(w))
#define IS_PLUGINS_WIDGET(w) (w && CD_WIDGET(w)->iType == WIDGET_PLUGINS)
PluginsWidget *cairo_dock_plugins_widget_new (void);
void cairo_dock_widget_plugins_update_module_state (PluginsWidget *pPluginsWidget, const gchar *cModuleName, gboolean bActive);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/cairo-dock-widget-config.h 000664 001750 001750 00000003055 12223247550 022374 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_WIDGET_CONFIG__
#define __CAIRO_DOCK_WIDGET_CONFIG__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-widget-shortkeys.h"
#include "cairo-dock-widget.h"
G_BEGIN_DECLS
typedef struct _ConfigWidget ConfigWidget;
struct _ConfigWidget {
CDWidget widget;
ShortkeysWidget *pShortKeysWidget;
int iIconSize;
int iTaskbarType;
gchar *cHoverAnim;
gchar *cHoverEffect;
gchar *cClickAnim;
gchar *cClickEffect;
int iEffectOnDisappearance;
GtkWindow *pMainWindow;
};
#define CONFIG_WIDGET(w) ((ConfigWidget*)(w))
#define IS_CONFIG_WIDGET(w) (w && CD_WIDGET(w)->iType == WIDGET_CONFIG)
ConfigWidget *cairo_dock_config_widget_new (GtkWindow *pMainWindow);
void cairo_dock_widget_config_update_shortkeys (ConfigWidget *pConfigWidget);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/cairo-dock-widget.h 000664 001750 001750 00000003641 12223247550 021132 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_WIDGET__
#define __CAIRO_DOCK_WIDGET__
#include
#include "cairo-dock-struct.h"
G_BEGIN_DECLS
typedef struct _CDWidget CDWidget;
typedef enum {
WIDGET_UNKNOWN,
WIDGET_CONFIG_GROUP,
WIDGET_CONFIG,
WIDGET_ITEMS,
WIDGET_MODULE,
WIDGET_PLUGINS,
WIDGET_SHORTKEYS,
WIDGET_THEMES,
WIDGET_NB_TYPES,
} CDWidgetType;
struct _CDWidget {
CDWidgetType iType;
GtkWidget *pWidget;
void (*apply) (CDWidget *pWidget);
void (*reset) (CDWidget *pWidget);
void (*reload) (CDWidget *pWidget); // reload, possibly destroying the GTK widget.
//gboolean (*represents_module_instance) (GldiModuleInstance *pInstance);
//CairoDockGroupKeyWidget* (*get_widget_from_name) (GldiModuleInstance *pInstance, const gchar *cGroupName, const gchar *cKeyName);
GSList *pWidgetList;
GPtrArray *pDataGarbage;
};
#define CD_WIDGET(w) ((CDWidget*)(w))
void cairo_dock_widget_apply (CDWidget *pCdWidget);
gboolean cairo_dock_widget_can_apply (CDWidget *pCdWidget);
void cairo_dock_widget_reload (CDWidget *pCdWidget);
void cairo_dock_widget_free (CDWidget *pCdWidget);
void cairo_dock_widget_destroy_widget (CDWidget *pCdWidget);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/cairo-dock-gui-backend.c 000664 001750 001750 00000017717 12223247550 022024 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#define __USE_XOPEN_EXTENDED
#include
#include
#include
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-gui-advanced.h"
#include "cairo-dock-gui-simple.h"
#include "cairo-dock-gui-manager.h"
#include "cairo-dock-dock-factory.h"
#include "cairo-dock-desklet-manager.h"
#include "cairo-dock-module-manager.h" // gldi_module_get
#include "cairo-dock-gui-simple.h"
#include "cairo-dock-gui-backend.h"
extern gchar *g_cCairoDockDataDir;
extern CairoDock *g_pMainDock;
static CairoDockMainGuiBackend *s_pMainGuiBackend = NULL;
static int s_iCurrentMode = 0;
void cairo_dock_load_user_gui_backend (int iMode) // 0 = simple
{
if (iMode == 1)
{
cairo_dock_register_advanced_gui_backend ();
}
else
{
cairo_dock_register_simple_gui_backend ();
}
s_iCurrentMode = iMode;
}
int cairo_dock_gui_backend_get_mode ()
{
return s_iCurrentMode;
}
static void on_click_switch_mode (G_GNUC_UNUSED GtkButton *button, G_GNUC_UNUSED gpointer data)
{
cairo_dock_close_gui ();
int iNewMode = (s_iCurrentMode == 1 ? 0 : 1);
gchar *cConfFilePath = g_strdup_printf ("%s/.cairo-dock", g_cCairoDockDataDir);
cairo_dock_update_keyfile (cConfFilePath,
G_TYPE_INT, "Gui", "mode", iNewMode,
G_TYPE_INVALID);
g_free (cConfFilePath);
cairo_dock_load_user_gui_backend (iNewMode);
cairo_dock_show_main_gui ();
}
GtkWidget *cairo_dock_make_switch_gui_button (void)
{
GtkWidget *pSwitchButton = gtk_button_new_with_label (s_pMainGuiBackend->cDisplayedName);
if (s_pMainGuiBackend->cTooltip)
gtk_widget_set_tooltip_text (pSwitchButton, s_pMainGuiBackend->cTooltip);
GtkWidget *pImage = gtk_image_new_from_stock (GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_BUTTON);
gtk_button_set_image (GTK_BUTTON (pSwitchButton), pImage);
g_signal_connect (G_OBJECT (pSwitchButton), "clicked", G_CALLBACK(on_click_switch_mode), NULL);
return pSwitchButton;
}
void cairo_dock_gui_update_desklet_params (CairoDesklet *pDesklet)
{
g_return_if_fail (pDesklet != NULL);
if (s_pMainGuiBackend && s_pMainGuiBackend->update_desklet_params)
s_pMainGuiBackend->update_desklet_params (pDesklet);
}
void cairo_dock_gui_update_desklet_visibility (CairoDesklet *pDesklet)
{
g_return_if_fail (pDesklet != NULL);
if (s_pMainGuiBackend && s_pMainGuiBackend->update_desklet_visibility_params)
s_pMainGuiBackend->update_desklet_visibility_params (pDesklet);
}
static guint s_iSidReloadItems = 0;
static gboolean _reload_items (G_GNUC_UNUSED gpointer data)
{
if (s_pMainGuiBackend && s_pMainGuiBackend->reload_items)
s_pMainGuiBackend->reload_items ();
s_iSidReloadItems = 0;
return FALSE;
}
void cairo_dock_gui_trigger_reload_items (void)
{
if (s_iSidReloadItems == 0)
{
s_iSidReloadItems = g_idle_add_full (G_PRIORITY_LOW,
(GSourceFunc) _reload_items,
NULL,
NULL);
}
}
static guint s_iSidUpdateModuleState = 0;
static gboolean _update_module_state (gchar *cModuleName)
{
if (s_pMainGuiBackend && s_pMainGuiBackend->update_module_state)
{
GldiModule *pModule = gldi_module_get (cModuleName);
if (pModule != NULL)
{
s_pMainGuiBackend->update_module_state (cModuleName, pModule->pInstancesList != NULL);
}
}
s_iSidUpdateModuleState = 0;
return FALSE;
}
void cairo_dock_gui_trigger_update_module_state (const gchar *cModuleName)
{
if (s_iSidUpdateModuleState == 0)
{
s_iSidUpdateModuleState = g_idle_add_full (G_PRIORITY_LOW,
(GSourceFunc) _update_module_state,
g_strdup (cModuleName),
g_free);
}
}
static guint s_iSidReloadModulesList = 0;
static gboolean _update_modules_list (G_GNUC_UNUSED gpointer data)
{
if (s_pMainGuiBackend && s_pMainGuiBackend->update_module_state)
s_pMainGuiBackend->update_modules_list ();
s_iSidReloadModulesList = 0;
return FALSE;
}
void cairo_dock_gui_trigger_update_modules_list (void)
{
if (s_iSidReloadModulesList == 0)
{
s_iSidReloadModulesList = g_idle_add_full (G_PRIORITY_LOW,
(GSourceFunc) _update_modules_list,
NULL,
NULL);
}
}
static guint s_iSidReloadShortkeys = 0;
static gboolean _update_shortkeys (G_GNUC_UNUSED gpointer data)
{
if (s_pMainGuiBackend && s_pMainGuiBackend->update_shortkeys)
s_pMainGuiBackend->update_shortkeys ();
s_iSidReloadShortkeys = 0;
return FALSE;
}
void cairo_dock_gui_trigger_reload_shortkeys (void)
{
if (s_iSidReloadShortkeys == 0)
{
s_iSidReloadShortkeys = g_idle_add_full (G_PRIORITY_LOW,
(GSourceFunc) _update_shortkeys,
NULL,
NULL);
}
}
void cairo_dock_gui_trigger_update_module_container (GldiModuleInstance *pInstance, gboolean bIsDetached)
{
if (s_pMainGuiBackend && s_pMainGuiBackend->update_module_instance_container)
s_pMainGuiBackend->update_module_instance_container (pInstance, bIsDetached); // on n'a encore pas de moyen simple d'etre prevenu de la destruction de l'instance, donc on effectue l'action tout de suite. -> si, regarder l'icone ...
}
void cairo_dock_register_config_gui_backend (CairoDockMainGuiBackend *pBackend)
{
g_free (s_pMainGuiBackend);
s_pMainGuiBackend = pBackend;
}
static void _display_window (GtkWidget *pWindow)
{
// place it on the current desktop, and avoid overlapping the main dock
if (pWindow && g_pMainDock != NULL) // evitons d'empieter sur le main dock.
{
if (g_pMainDock->container.bIsHorizontal)
{
if (g_pMainDock->container.bDirectionUp)
gtk_window_move (GTK_WINDOW (pWindow), 0, 0);
else
gtk_window_move (GTK_WINDOW (pWindow), 0, g_pMainDock->iMinDockHeight+10);
}
else
{
if (g_pMainDock->container.bDirectionUp)
gtk_window_move (GTK_WINDOW (pWindow), 0, 0);
else
gtk_window_move (GTK_WINDOW (pWindow), g_pMainDock->iMinDockHeight+10, 0);
}
}
// take focus
gtk_window_present (GTK_WINDOW (pWindow));
}
GtkWidget * cairo_dock_show_main_gui (void)
{
// create the window
GtkWidget *pWindow = NULL;
if (s_pMainGuiBackend && s_pMainGuiBackend->show_main_gui)
pWindow = s_pMainGuiBackend->show_main_gui ();
_display_window (pWindow);
return pWindow;
}
void cairo_dock_show_module_gui (const gchar *cModuleName)
{
GtkWidget *pWindow = NULL;
if (s_pMainGuiBackend && s_pMainGuiBackend->show_module_gui)
pWindow = s_pMainGuiBackend->show_module_gui (cModuleName);
_display_window (pWindow);
}
void cairo_dock_close_gui (void)
{
if (s_pMainGuiBackend && s_pMainGuiBackend->close_gui)
s_pMainGuiBackend->close_gui ();
}
void cairo_dock_show_items_gui (Icon *pIcon, GldiContainer *pContainer, GldiModuleInstance *pModuleInstance, int iShowPage)
{
GtkWidget *pWindow = NULL;
if (s_pMainGuiBackend && s_pMainGuiBackend->show_gui)
pWindow = s_pMainGuiBackend->show_gui (pIcon, pContainer, pModuleInstance, iShowPage);
_display_window (pWindow);
}
void cairo_dock_reload_gui (void)
{
if (s_pMainGuiBackend && s_pMainGuiBackend->reload)
s_pMainGuiBackend->reload ();
}
void cairo_dock_show_themes (void)
{
GtkWidget *pWindow = NULL;
if (s_pMainGuiBackend && s_pMainGuiBackend->show_themes)
pWindow = s_pMainGuiBackend->show_themes ();
_display_window (pWindow);
}
void cairo_dock_show_addons (void)
{
GtkWidget *pWindow = NULL;
if (s_pMainGuiBackend && s_pMainGuiBackend->show_addons)
pWindow = s_pMainGuiBackend->show_addons ();
_display_window (pWindow);
}
gboolean cairo_dock_can_manage_themes (void)
{
return (s_pMainGuiBackend && s_pMainGuiBackend->show_themes);
}
cairo-dock-3.3.2/src/cairo-dock.c 000664 001750 001750 00000107255 12223247550 017652 0 ustar 00mbaerts mbaerts 000000 000000
/*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
/*****************************************************************************************************
**
** Program:
** cairo-dock
**
** License :
** This program is released under the terms of the GNU General Public License, version 3 or above.
** If you don't know what that means take a look at:
** http://www.gnu.org/licenses/licenses.html#GPL
**
*********************** VERSION 0 (2006) *********************
**
** Original idea :
** Mirco "MacSlow" Mueller , June 2006.
** With the help of:
** Behdad Esfahbod
** David Reveman
** Karl Lattimer
** Originally conceived as a stress-test for cairo, librsvg, and glitz.
**
*********************** VERSION 0.1 and above (2007-2013) *********************
**
** author(s) :
** Fabrice Rey
** With the help of:
** A lot of people !!!
**
*******************************************************************************/
/// http://www.siteduzero.com/tutoriel-3-307309-le-systeme-de-micro-paiement-flattr.html
/// http://www.cyber-junk.de/wp-content/cache/supercache/cyber-junk.de/entwickelt/flattr-button-im-eigenbau-mittels-curl-und-mini-api/index.html
#include // sleep, execl
#include
#define __USE_POSIX
#include
#include
#include // dbus_g_thread_init
#include "config.h"
#include "cairo-dock-icon-facility.h" // cairo_dock_get_first_icon
#include "cairo-dock-module-manager.h" // gldi_modules_new_from_directory
#include "cairo-dock-module-instance-manager.h" // GldiModuleInstance
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-desklet-manager.h"
#include "cairo-dock-themes-manager.h"
#include "cairo-dock-dialog-factory.h"
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-config.h"
#include "cairo-dock-file-manager.h"
#include "cairo-dock-log.h"
#include "cairo-dock-keybinder.h"
#include "cairo-dock-opengl.h"
#include "cairo-dock-packages.h"
#include "cairo-dock-utils.h" // cairo_dock_launch_command
#include "cairo-dock-core.h"
#include "cairo-dock-gui-manager.h"
#include "cairo-dock-gui-backend.h"
#include "cairo-dock-user-interaction.h"
#include "cairo-dock-user-menu.h"
//#define CAIRO_DOCK_THEME_SERVER "http://themes.glx-dock.org"
#define CAIRO_DOCK_THEME_SERVER "http://download.tuxfamily.org/glxdock/themes"
#define CAIRO_DOCK_BACKUP_THEME_SERVER "http://fabounet03.free.fr"
// Nom du repertoire racine du theme courant.
#define CAIRO_DOCK_CURRENT_THEME_NAME "current_theme"
// Nom du repertoire des themes extras.
#define CAIRO_DOCK_EXTRAS_DIR "extras"
extern gchar *g_cCairoDockDataDir;
extern gchar *g_cCurrentThemePath;
extern gchar *g_cConfFile;
extern int g_iMajorVersion, g_iMinorVersion, g_iMicroVersion;
extern CairoDock *g_pMainDock;
extern CairoDockGLConfig g_openglConfig;
extern gboolean g_bUseOpenGL;
extern gboolean g_bEasterEggs;
extern GldiModuleInstance *g_pCurrentModule;
extern GtkWidget *cairo_dock_build_simple_gui_window (void);
gboolean g_bForceCairo = FALSE;
gboolean g_bLocked;
static gboolean s_bSucessfulLaunch = FALSE;
static GString *s_pLaunchCommand = NULL;
static gchar *s_cLastVersion = NULL;
static gchar *s_cDefaulBackend = NULL;
static gint s_iGuiMode = 0; // 0 = simple mode, 1 = advanced mode
static gint s_iLastYear = 0;
static gint s_iNbCrashes = 0;
static gboolean s_bPingServer = TRUE;
static void _on_got_server_answer (const gchar *data, G_GNUC_UNUSED gpointer user_data)
{
if (data != NULL)
{
s_bPingServer = TRUE; // after we got the answer, we can write in the global file to not try any more.
gchar *cConfFilePath = g_strdup_printf ("%s/.cairo-dock", g_cCairoDockDataDir);
cairo_dock_update_conf_file (cConfFilePath,
G_TYPE_BOOLEAN, "Launch", "ping server", s_bPingServer,
G_TYPE_INVALID);
g_free (cConfFilePath);
}
}
static gboolean _cairo_dock_successful_launch (gpointer data)
{
s_bSucessfulLaunch = TRUE;
// new year greetings.
time_t t = time (NULL);
struct tm st;
localtime_r (&t, &st);
if (!data && st.tm_mday <= 15 && st.tm_mon == 0 && s_iLastYear < st.tm_year + 1900) // first 2 weeks of january + not first launch
{
s_iLastYear = st.tm_year + 1900;
gchar *cConfFilePath = g_strdup_printf ("%s/.cairo-dock", g_cCairoDockDataDir);
cairo_dock_update_conf_file (cConfFilePath,
G_TYPE_INT, "Launch", "last year", s_iLastYear,
G_TYPE_INVALID);
g_free (cConfFilePath);
Icon *pIcon = gldi_icons_get_any_without_dialog ();
gchar *cMessage = g_strdup_printf (_("Happy new year %d !!!"), s_iLastYear);
gchar *cMessageFull = g_strdup_printf ("\n%s :-)\n", cMessage);
gldi_dialog_show_temporary_with_icon (cMessageFull, pIcon, CAIRO_CONTAINER (g_pMainDock), 15000., CAIRO_DOCK_SHARE_DATA_DIR"/icons/balloons.png");
g_free (cMessageFull);
g_free (cMessage);
}
if (! s_bPingServer && g_str_has_suffix (g_cCairoDockDataDir, CAIRO_DOCK_DATA_DIR)) // the server (which hosts themes, third-party applets and packages) has never been accessed yet, ping it once
{
s_bPingServer = TRUE;
cairo_dock_get_url_data_async (CAIRO_DOCK_THEME_SERVER"/ping.txt", (GFunc)_on_got_server_answer, NULL);
}
return FALSE;
}
static gboolean _cairo_dock_first_launch_setup (G_GNUC_UNUSED gpointer data)
{
cairo_dock_launch_command (CAIRO_DOCK_SHARE_DATA_DIR"/scripts/initial-setup.sh");
return FALSE;
}
static void _cairo_dock_quit (G_GNUC_UNUSED int signal)
{
gtk_main_quit ();
}
/* Crash at startup:
* - First 2 crashes: retry with a delay of 2 sec (maybe due to a problem at startup)
* - 3th crash: remove the applet and restart the dock
* - 4th crash: show the maintenance mode
* - 5th crash: quit
*/
static void _cairo_dock_intercept_signal (int signal)
{
cd_warning ("Cairo-Dock has crashed (sig %d).\nIt will be restarted now.\nFeel free to report this bug on glx-dock.org to help improving the dock!", signal);
g_print ("info on the system :\n");
int r = system ("uname -a");
if (r < 0)
cd_warning ("Not able to launch this command: uname");
// if a module is responsible, expose it to public shame.
if (g_pCurrentModule != NULL)
{
g_print ("The applet '%s' may be the culprit", g_pCurrentModule->pModule->pVisitCard->cModuleName);
if (! s_bSucessfulLaunch) // else, be quiet.
g_string_append_printf (s_pLaunchCommand, " -x \"%s\"", g_pCurrentModule->pModule->pVisitCard->cModuleName);
}
else
{
g_print ("Couldn't guess if it was an applet's fault or not. It may have crashed inside the core or inside a thread\n");
}
// if the crash occurs on startup, take additionnal measures; else just respawn quietly.
if (! s_bSucessfulLaunch) // a crash on startup,
{
if (s_iNbCrashes < 2) // the first 2 crashes, restart with a delay (in case we were launched too early on startup).
g_string_append (s_pLaunchCommand, " -w 2"); // 2s delay.
else if (g_pCurrentModule == NULL || s_iNbCrashes == 3) // crash and no culprit or 4th crash => start in maintenance mode.
g_string_append (s_pLaunchCommand, " -m");
g_string_append_printf (s_pLaunchCommand, " -q %d", s_iNbCrashes + 1); // increment the first-crash counter.
} // else a random crash, respawn quietly.
g_print ("restarting with '%s'...\n", s_pLaunchCommand->str);
execl ("/bin/sh", "/bin/sh", "-c", s_pLaunchCommand->str, (char *)NULL); // on ne revient pas de cette fonction.
//execlp ("cairo-dock", "cairo-dock", s_pLaunchCommand->str, (char *)0);
cd_warning ("Sorry, couldn't restart the dock");
}
static void _cairo_dock_set_signal_interception (void)
{
signal (SIGSEGV, _cairo_dock_intercept_signal); // Segmentation violation
signal (SIGFPE, _cairo_dock_intercept_signal); // Floating-point exception
signal (SIGILL, _cairo_dock_intercept_signal); // Illegal instruction
signal (SIGABRT, _cairo_dock_intercept_signal); // Abort // kill -6
}
static gboolean on_delete_maintenance_gui (G_GNUC_UNUSED GtkWidget *pWidget, GMainLoop *pBlockingLoop)
{
cd_debug ("%s ()", __func__);
if (pBlockingLoop != NULL && g_main_loop_is_running (pBlockingLoop))
{
g_main_loop_quit (pBlockingLoop);
}
return FALSE; // TRUE <=> ne pas detruire la fenetre.
}
static void PrintMuteFunc (G_GNUC_UNUSED const gchar *string) {}
static void _cairo_dock_get_global_config (const gchar *cCairoDockDataDir)
{
gchar *cConfFilePath = g_strdup_printf ("%s/.cairo-dock", cCairoDockDataDir);
GKeyFile *pKeyFile = g_key_file_new ();
if (g_file_test (cConfFilePath, G_FILE_TEST_EXISTS))
{
g_key_file_load_from_file (pKeyFile, cConfFilePath, 0, NULL);
s_cLastVersion = g_key_file_get_string (pKeyFile, "Launch", "last version", NULL);
s_cDefaulBackend = g_key_file_get_string (pKeyFile, "Launch", "default backend", NULL);
if (s_cDefaulBackend && *s_cDefaulBackend == '\0')
{
g_free (s_cDefaulBackend);
s_cDefaulBackend = NULL;
}
s_iGuiMode = g_key_file_get_integer (pKeyFile, "Gui", "mode", NULL); // 0 by default
s_iLastYear = g_key_file_get_integer (pKeyFile, "Launch", "last year", NULL); // 0 by default
s_bPingServer = g_key_file_get_boolean (pKeyFile, "Launch", "ping server", NULL); // FALSE by default
}
else // first launch or old version, the file doesn't exist yet.
{
gchar *cLastVersionFilePath = g_strdup_printf ("%s/.cairo-dock-last-version", cCairoDockDataDir);
if (g_file_test (cLastVersionFilePath, G_FILE_TEST_EXISTS))
{
gsize length = 0;
g_file_get_contents (cLastVersionFilePath,
&s_cLastVersion,
&length,
NULL);
}
g_remove (cLastVersionFilePath);
g_free (cLastVersionFilePath);
g_key_file_set_string (pKeyFile, "Launch", "last version", s_cLastVersion?s_cLastVersion:"");
g_key_file_set_string (pKeyFile, "Launch", "default backend", "");
g_key_file_set_integer (pKeyFile, "Gui", "mode", s_iGuiMode);
g_key_file_set_integer (pKeyFile, "Launch", "last year", s_iLastYear);
cairo_dock_write_keys_to_file (pKeyFile, cConfFilePath);
}
g_key_file_free (pKeyFile);
g_free (cConfFilePath);
}
int main (int argc, char** argv)
{
//\___________________ build the command line used to respawn, and check if we have been launched from another life.
s_pLaunchCommand = g_string_new (argv[0]);
int i;
for (i = 1; i < argc; i ++)
{
//g_print ("'%s'\n", argv[i]);
if (strcmp (argv[i], "-q") == 0) // this option is only set by the dock itself, at the end of the command line.
{
s_iNbCrashes = atoi (argv[i+1]);
argc = i; // remove this option, as it doesn't belong to the options table.
argv[i] = NULL;
break;
}
else if (strcmp (argv[i], "-w") == 0 || strcmp (argv[i], "-x") == 0) // skip this option and its argument.
{
i ++;
}
else if (strcmp (argv[i], "-m") == 0) // skip this option
{
// nothing else to do.
}
else // keep this option in the command line.
{
g_string_append_printf (s_pLaunchCommand, " %s", argv[i]);
}
}
/* Crash: 5th crash: an applet has already been removed and the maintenance
* mode has already been displayed => stop
*/
if (s_iNbCrashes > 4)
{
g_print ("Sorry, Cairo-Dock has encoutered some problems, and will quit.\n");
return 1;
}
// mute all output messages if CD is not launched from a terminal
if (getenv("TERM") == NULL) /// why not isatty(stdout) ?...
g_set_print_handler(PrintMuteFunc);
// init lib
#if !defined (GLIB_VERSION_2_36) // no longer needed now... (>= 2.35)
g_type_init (); // should initialise threads too on new versions of GLIB (>= 2.24)
#endif
#if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 24)
if (!g_thread_supported ())
g_thread_init (NULL);
#endif
dbus_g_thread_init (); // it's a wrapper: it will use dbus_threads_init_default ();
gtk_init (&argc, &argv);
GError *erreur = NULL;
//\___________________ internationalize the app.
bindtextdomain (CAIRO_DOCK_GETTEXT_PACKAGE, CAIRO_DOCK_LOCALE_DIR);
bind_textdomain_codeset (CAIRO_DOCK_GETTEXT_PACKAGE, "UTF-8");
textdomain (CAIRO_DOCK_GETTEXT_PACKAGE);
//\___________________ get app's options.
gboolean bSafeMode = FALSE, bMaintenance = FALSE, bNoSticky = FALSE, bCappuccino = FALSE, bPrintVersion = FALSE, bTesting = FALSE, bForceOpenGL = FALSE, bToggleIndirectRendering = FALSE, bKeepAbove = FALSE, bForceColors = FALSE, bAskBackend = FALSE, bMetacityWorkaround = FALSE;
gchar *cEnvironment = NULL, *cUserDefinedDataDir = NULL, *cVerbosity = 0, *cUserDefinedModuleDir = NULL, *cExcludeModule = NULL, *cThemeServerAdress = NULL;
int iDelay = 0;
GOptionEntry pOptionsTable[] =
{
// GLDI options: cairo, opengl, indirect-opengl, env, keep-above, no-sticky
{"cairo", 'c', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&g_bForceCairo,
_("Use Cairo backend."), NULL},
{"opengl", 'o', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bForceOpenGL,
_("Use OpenGL backend."), NULL},
{"indirect-opengl", 'O', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bToggleIndirectRendering,
_("Use OpenGL backend with indirect rendering. There are very few case where this option should be used."), NULL},
{"ask-backend", 'A', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bAskBackend,
_("Ask again on startup which backend to use."), NULL},
{"env", 'e', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING,
&cEnvironment,
_("Force the dock to consider this environnement - use it with care."), NULL},
{"dir", 'd', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING,
&cUserDefinedDataDir,
_("Force the dock to load from this directory, instead of ~/.config/cairo-dock."), NULL},
{"server", 'S', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING,
&cThemeServerAdress,
_("Address of a server containing additional themes. This will overwrite the default server address."), NULL},
{"wait", 'w', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_INT,
&iDelay,
_("Wait for N seconds before starting; this is useful if you notice some problems when the dock starts with the session."), NULL},
{"maintenance", 'm', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bMaintenance,
_("Allow to edit the config before the dock is started and show the config panel on start."), NULL},
{"exclude", 'x', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING,
&cExcludeModule,
_("Exclude a given plug-in from activating (it is still loaded though)."), NULL},
{"safe-mode", 'f', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bSafeMode,
_("Don't load any plug-ins."), NULL},
{"metacity-workaround", 'W', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bMetacityWorkaround,
_("Work around some bugs in Metacity Window-Manager (invisible dialogs or sub-docks)"), NULL},
{"log", 'l', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING,
&cVerbosity,
_("Log verbosity (debug,message,warning,critical,error); default is warning."), NULL},
{"colors", 'F', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bForceColors,
_("Force to display some output messages with colors."), NULL},
{"version", 'v', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bPrintVersion,
_("Print version and quit."), NULL},
{"locked", 'k', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&g_bLocked,
_("Lock the dock so that any modification is impossible for users."), NULL},
// below options are probably useless for most of people.
{"keep-above", 'a', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bKeepAbove,
_("Keep the dock above other windows whatever."), NULL},
{"no-sticky", 's', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bNoSticky,
_("Don't make the dock appear on all desktops."), NULL},
{"capuccino", 'C', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bCappuccino,
_("Cairo-Dock makes anything, including coffee !"), NULL},
{"modules-dir", 'M', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING,
&cUserDefinedModuleDir,
_("Ask the dock to load additionnal modules contained in this directory (though it is unsafe for your dock to load unnofficial modules)."), NULL},
{"testing", 'T', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&bTesting,
_("For debugging purpose only. The crash manager will not be started to hunt down the bugs."), NULL},
{"easter-eggs", 'E', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&g_bEasterEggs,
_("For debugging purpose only. Some hidden and still unstable options will be activated."), NULL},
{NULL, 0, 0, 0,
NULL,
NULL, NULL}
};
GOptionContext *context = g_option_context_new ("Cairo-Dock");
g_option_context_add_main_entries (context, pOptionsTable, NULL);
g_option_context_parse (context, &argc, &argv, &erreur);
if (erreur != NULL)
{
cd_error ("ERROR in options: %s", erreur->message);
return 1;
}
if (bPrintVersion)
{
g_print ("%s\n", CAIRO_DOCK_VERSION);
return 0;
}
if (g_bLocked)
cd_warning ("Cairo-Dock will be locked.");
if (cVerbosity != NULL)
{
cd_log_set_level_from_name (cVerbosity);
g_free (cVerbosity);
}
if (bForceColors)
cd_log_force_use_color ();
CairoDockDesktopEnv iDesktopEnv = CAIRO_DOCK_UNKNOWN_ENV;
if (cEnvironment != NULL)
{
if (strcmp (cEnvironment, "gnome") == 0)
iDesktopEnv = CAIRO_DOCK_GNOME;
else if (strcmp (cEnvironment, "kde") == 0)
iDesktopEnv = CAIRO_DOCK_KDE;
else if (strcmp (cEnvironment, "xfce") == 0)
iDesktopEnv = CAIRO_DOCK_XFCE;
else if (strcmp (cEnvironment, "none") == 0)
iDesktopEnv = CAIRO_DOCK_UNKNOWN_ENV;
else
cd_warning ("Unknown environment '%s'", cEnvironment);
g_free (cEnvironment);
}
if (bCappuccino)
{
const gchar *cCappuccino = _("Cairo-Dock makes anything, including coffee !");
g_print ("%s\n", cCappuccino);
return 0;
}
//\___________________ get global config.
gboolean bFirstLaunch = FALSE;
gchar *cRootDataDirPath;
// if the user has specified the '-d' parameter.
if (cUserDefinedDataDir != NULL)
{
// if 'cRootDataDirPath' is not a full path, we will have a few problems with image in the config panel without a full path (e.g. 'bg.svg' in the default theme)
if (*cUserDefinedDataDir == '/')
cRootDataDirPath = cUserDefinedDataDir;
else if (*cUserDefinedDataDir == '~')
cRootDataDirPath = g_strdup_printf ("%s%s", getenv("HOME"), cUserDefinedDataDir + 1);
else
cRootDataDirPath = g_strdup_printf ("%s/%s", g_get_current_dir(), cUserDefinedDataDir);
cUserDefinedDataDir = NULL;
}
else
{
cRootDataDirPath = g_strdup_printf ("%s/.config/%s", getenv("HOME"), CAIRO_DOCK_DATA_DIR);
}
bFirstLaunch = ! g_file_test (cRootDataDirPath, G_FILE_TEST_IS_DIR);
_cairo_dock_get_global_config (cRootDataDirPath);
if (bAskBackend)
{
g_free (s_cDefaulBackend);
s_cDefaulBackend = NULL;
}
//\___________________ delay the startup if specified.
if (iDelay > 0)
{
sleep (iDelay);
}
//\___________________ initialize libgldi.
GldiRenderingMethod iRendering = (bForceOpenGL ? GLDI_OPENGL : g_bForceCairo ? GLDI_CAIRO : GLDI_DEFAULT);
gldi_init (iRendering);
//\___________________ set custom user options.
if (bKeepAbove)
cairo_dock_force_docks_above ();
if (bNoSticky)
cairo_dock_set_containers_non_sticky ();
if (bMetacityWorkaround)
cairo_dock_disable_containers_opacity ();
if (iDesktopEnv != CAIRO_DOCK_UNKNOWN_ENV)
cairo_dock_fm_force_desktop_env (iDesktopEnv);
if (bToggleIndirectRendering)
gldi_gl_backend_force_indirect_rendering ();
gchar *cExtraDirPath = g_strconcat (cRootDataDirPath, "/"CAIRO_DOCK_EXTRAS_DIR, NULL);
gchar *cThemesDirPath = g_strconcat (cRootDataDirPath, "/"CAIRO_DOCK_THEMES_DIR, NULL);
gchar *cCurrentThemeDirPath = g_strconcat (cRootDataDirPath, "/"CAIRO_DOCK_CURRENT_THEME_NAME, NULL);
cairo_dock_set_paths (cRootDataDirPath, cExtraDirPath, cThemesDirPath, cCurrentThemeDirPath, (gchar*)CAIRO_DOCK_SHARE_THEMES_DIR, (gchar*)CAIRO_DOCK_DISTANT_THEMES_DIR, cThemeServerAdress ? cThemeServerAdress : g_strdup (CAIRO_DOCK_THEME_SERVER));
//\___________________ Check that OpenGL is safely usable, if not ask the user what to do.
if (bAskBackend || (g_bUseOpenGL && ! bForceOpenGL && ! bToggleIndirectRendering && ! gldi_gl_backend_is_safe ())) // opengl disponible sans l'avoir force mais pas safe => on demande confirmation.
{
if (s_cDefaulBackend == NULL) // pas de backend par defaut defini.
{
GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Use OpenGL in Cairo-Dock"),
NULL,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_YES,
GTK_RESPONSE_YES,
GTK_STOCK_NO,
GTK_RESPONSE_NO,
NULL);
GtkWidget *label = gtk_label_new (_("OpenGL allows you to use the hardware acceleration, reducing the CPU load to the minimum.\nIt also allows some pretty visual effects similar to Compiz.\nHowever, some cards and/or their drivers don't fully support it, which may prevent the dock from running correctly.\nDo you want to activate OpenGL ?\n (To not show this dialog, launch the dock from the Application menu,\n or with the -o option to force OpenGL and -c to force cairo.)"));
#if (GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION >= 14)
GtkWidget *pContentBox = gtk_dialog_get_content_area (GTK_DIALOG(dialog));
#else
GtkWidget *pContentBox = GTK_DIALOG(dialog)->vbox;
#endif
gtk_box_pack_start (GTK_BOX (pContentBox), label, FALSE, FALSE, 0);
GtkWidget *pAskBox = _gtk_hbox_new (3);
gtk_box_pack_start (GTK_BOX (pContentBox), pAskBox, FALSE, FALSE, 0);
label = gtk_label_new (_("Remember this choice"));
GtkWidget *pCheckBox = gtk_check_button_new ();
gtk_box_pack_end (GTK_BOX (pAskBox), pCheckBox, FALSE, FALSE, 0);
gtk_box_pack_end (GTK_BOX (pAskBox), label, FALSE, FALSE, 0);
gtk_widget_show_all (dialog);
gint iAnswer = gtk_dialog_run (GTK_DIALOG (dialog)); // lance sa propre main loop, c'est pourquoi on peut le faire avant le gtk_main().
gboolean bRememberChoice = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pCheckBox));
gtk_widget_destroy (dialog);
if (iAnswer == GTK_RESPONSE_NO)
{
gldi_gl_backend_deactivate ();
}
if (bRememberChoice) // l'utilisateur a defini le choix par defaut.
{
s_cDefaulBackend = g_strdup (iAnswer == GTK_RESPONSE_NO ? "cairo" : "opengl");
gchar *cConfFilePath = g_strdup_printf ("%s/.cairo-dock", g_cCairoDockDataDir);
cairo_dock_update_conf_file (cConfFilePath,
G_TYPE_STRING, "Launch", "default backend", s_cDefaulBackend,
G_TYPE_INVALID);
g_free (cConfFilePath);
}
}
else if (strcmp (s_cDefaulBackend, "opengl") != 0) // un backend par defaut qui n'est pas OpenGL.
{
gldi_gl_backend_deactivate ();
}
}
g_print ("\n"
" ============================================================================\n"
"\tCairo-Dock version : %s\n"
"\tCompiled date : %s %s\n"
"\tBuilt with GTK : %d.%d\n"
"\tRunning with OpenGL: %d\n"
" ============================================================================\n\n",
CAIRO_DOCK_VERSION,
__DATE__, __TIME__,
GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
g_bUseOpenGL);
//\___________________ load plug-ins (must be done after everything is initialized).
if (! bSafeMode)
{
gldi_modules_new_from_directory (NULL, &erreur); // load gldi-based plug-ins
if (erreur != NULL)
{
cd_warning ("%s\n no module will be available", erreur->message);
g_error_free (erreur);
erreur = NULL;
}
if (cUserDefinedModuleDir != NULL)
{
gldi_modules_new_from_directory (cUserDefinedModuleDir, &erreur); // load user plug-ins
if (erreur != NULL)
{
cd_warning ("%s\n no additionnal module will be available", erreur->message);
g_error_free (erreur);
erreur = NULL;
}
g_free (cUserDefinedModuleDir);
cUserDefinedModuleDir = NULL;
}
}
//\___________________ define GUI backend.
cairo_dock_load_user_gui_backend (s_iGuiMode);
//\___________________ register to the useful notifications.
gldi_object_register_notification (&myContainerObjectMgr,
NOTIFICATION_DROP_DATA,
(GldiNotificationFunc) cairo_dock_notification_drop_data,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myContainerObjectMgr,
NOTIFICATION_CLICK_ICON,
(GldiNotificationFunc) cairo_dock_notification_click_icon,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myContainerObjectMgr,
NOTIFICATION_MIDDLE_CLICK_ICON,
(GldiNotificationFunc) cairo_dock_notification_middle_click_icon,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myContainerObjectMgr,
NOTIFICATION_SCROLL_ICON,
(GldiNotificationFunc) cairo_dock_notification_scroll_icon,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myContainerObjectMgr,
NOTIFICATION_BUILD_CONTAINER_MENU,
(GldiNotificationFunc) cairo_dock_notification_build_container_menu,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myContainerObjectMgr,
NOTIFICATION_BUILD_ICON_MENU,
(GldiNotificationFunc) cairo_dock_notification_build_icon_menu,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myDeskletObjectMgr,
NOTIFICATION_CONFIGURE_DESKLET,
(GldiNotificationFunc) cairo_dock_notification_configure_desklet,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myDockObjectMgr,
NOTIFICATION_ICON_MOVED,
(GldiNotificationFunc) cairo_dock_notification_icon_moved,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myDockObjectMgr,
NOTIFICATION_DESTROY,
(GldiNotificationFunc) cairo_dock_notification_dock_destroyed,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myModuleObjectMgr,
NOTIFICATION_MODULE_ACTIVATED,
(GldiNotificationFunc) cairo_dock_notification_module_activated,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myModuleObjectMgr,
NOTIFICATION_MODULE_REGISTERED,
(GldiNotificationFunc) cairo_dock_notification_module_registered,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myModuleInstanceObjectMgr,
NOTIFICATION_MODULE_INSTANCE_DETACHED,
(GldiNotificationFunc) cairo_dock_notification_module_detached,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myDockObjectMgr,
NOTIFICATION_INSERT_ICON,
(GldiNotificationFunc) cairo_dock_notification_icon_inserted,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myDockObjectMgr,
NOTIFICATION_REMOVE_ICON,
(GldiNotificationFunc) cairo_dock_notification_icon_removed,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myDeskletObjectMgr,
NOTIFICATION_DESTROY,
(GldiNotificationFunc) cairo_dock_notification_desklet_added_removed,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myDeskletObjectMgr,
NOTIFICATION_NEW,
(GldiNotificationFunc) cairo_dock_notification_desklet_added_removed,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myShortkeyObjectMgr,
NOTIFICATION_NEW,
(GldiNotificationFunc) cairo_dock_notification_shortkey_added_removed_changed,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myShortkeyObjectMgr,
NOTIFICATION_DESTROY,
(GldiNotificationFunc) cairo_dock_notification_shortkey_added_removed_changed,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myShortkeyObjectMgr,
NOTIFICATION_SHORTKEY_CHANGED,
(GldiNotificationFunc) cairo_dock_notification_shortkey_added_removed_changed,
GLDI_RUN_AFTER, NULL);
//\___________________ handle crashes.
if (! bTesting)
_cairo_dock_set_signal_interception ();
//\___________________ handle terminate signals to quit properly (especially when the system shuts down).
signal (SIGTERM, _cairo_dock_quit); // Term // kill -15 (system)
signal (SIGHUP, _cairo_dock_quit); // sent to a process when its controlling terminal is closed
//\___________________ Disable modules that have crashed
if (cExcludeModule != NULL && (s_iNbCrashes > 2 || bMaintenance)) // 3th crash or 4th (with -m)
{
gchar *cCommand = g_strdup_printf ("sed -i \"/modules/ s/%s//g\" \"%s\"",
cExcludeModule, g_cConfFile);
int r = system (cCommand);
if (r < 0)
cd_warning ("Not able to launch this command: %s", cCommand);
else
cd_warning (_("The module '%s' has been deactivated because it may "
"have caused some problems.\nYou can reactivate it, if it happens "
"again thanks to report it at http://glx-dock.org"), cExcludeModule);
g_free (cCommand);
}
//\___________________ maintenance mode -> show the main config panel.
if (bMaintenance)
{
cairo_dock_load_user_gui_backend (1); // force the advanced GUI, it can display the config before the theme is loaded.
GtkWidget *pWindow = cairo_dock_show_main_gui ();
gtk_window_set_title (GTK_WINDOW (pWindow), _("< Maintenance mode >"));
if (cExcludeModule != NULL)
cairo_dock_set_status_message_printf (pWindow, "%s '%s'...", _("Something went wrong with this applet:"), cExcludeModule);
gtk_window_set_modal (GTK_WINDOW (pWindow), TRUE);
GMainLoop *pBlockingLoop = g_main_loop_new (NULL, FALSE);
g_signal_connect (G_OBJECT (pWindow),
"destroy",
G_CALLBACK (on_delete_maintenance_gui),
pBlockingLoop);
cd_warning ("showing the maintenance mode ...");
g_main_loop_run (pBlockingLoop); // pas besoin de GDK_THREADS_LEAVE/ENTER vu qu'on est pas encore dans la main loop de GTK. En fait cette boucle va jouer le role de la main loop GTK.
cd_warning ("end of the maintenance mode.");
g_main_loop_unref (pBlockingLoop);
cairo_dock_load_user_gui_backend (s_iGuiMode); // go back to the user GUI.
}
//\___________________ load the current theme.
cd_message ("loading theme ...");
if (! g_file_test (g_cConfFile, G_FILE_TEST_EXISTS)) // no theme yet, copy the default theme first.
{
const gchar *cDesktopSessionEnv = g_getenv ("DESKTOP_SESSION");
const gchar *cThemeName;
if (g_strcmp0 (cDesktopSessionEnv, "cairo-dock") == 0
|| g_strcmp0 (cDesktopSessionEnv, "cairo-dock-fallback") == 0)
cThemeName = "Default-Panel";
else
cThemeName = "Default-Single";
gchar *cCommand = g_strdup_printf ("/bin/cp -r \"%s/%s\"/* \"%s\"", CAIRO_DOCK_SHARE_DATA_DIR"/themes", cThemeName, g_cCurrentThemePath);
cd_message (cCommand);
int r = system (cCommand);
if (r < 0)
cd_warning ("Not able to launch this command: %s", cCommand);
g_free (cCommand);
}
cairo_dock_load_current_theme ();
//\___________________ lock mode.
if (g_bLocked) // comme on ne pourra pas ouvrir le panneau de conf, ces 2 variables resteront tel quel.
{
myDocksParam.bLockIcons = TRUE;
myDocksParam.bLockAll = TRUE;
}
if (!bSafeMode && gldi_module_get_nb () <= 1) // 1 en comptant l'aide
{
Icon *pIcon = gldi_icons_get_any_without_dialog ();
///cairo_dock_ask_question_and_wait (_("No plug-in were found.\nPlug-ins provide most of the functionalities of Cairo-Dock (animations, applets, views, etc).\nSee http://glx-dock.org for more information.\nSince there is almost no meaning in running the dock without them, the application will quit now."), pIcon, CAIRO_CONTAINER (g_pMainDock));
gldi_dialog_show_temporary_with_icon (_("No plug-in were found.\nPlug-ins provide most of the functionalities (animations, applets, views, etc).\nSee http://glx-dock.org for more information.\nThere is almost no meaning in running the dock without them and it's probably due to a problem with the installation of these plug-ins.\nBut if you really want to use the dock without these plug-ins, you can launch the dock with the '-f' option to no longer have this message.\n"), pIcon, CAIRO_CONTAINER (g_pMainDock), 0., CAIRO_DOCK_SHARE_DATA_DIR"/"CAIRO_DOCK_ICON);
}
//\___________________ display the changelog in case of a new version.
gboolean bNewVersion = (s_cLastVersion == NULL || strcmp (s_cLastVersion, CAIRO_DOCK_VERSION) != 0);
if (bNewVersion)
{
gchar *cConfFilePath = g_strdup_printf ("%s/.cairo-dock", g_cCairoDockDataDir);
cairo_dock_update_conf_file (cConfFilePath,
G_TYPE_STRING, "Launch", "last version", CAIRO_DOCK_VERSION,
G_TYPE_INVALID);
g_free (cConfFilePath);
/// If any operation must be done on the user theme (like activating a module by default, or disabling an option), it should be done here once (when CAIRO_DOCK_VERSION matches the new version).
}
//g_print ("bFirstLaunch: %d; bNewVersion: %d\n", bFirstLaunch, bNewVersion);
if (bFirstLaunch) // first launch => set up config
{
g_timeout_add_seconds (4, _cairo_dock_first_launch_setup, NULL);
}
else if (bNewVersion) // new version -> changelog (if it's the first launch, useless to display what's new, we already have the Welcome message).
{
gchar *cChangeLogFilePath = g_strdup_printf ("%s/ChangeLog.txt", CAIRO_DOCK_SHARE_DATA_DIR);
GKeyFile *pKeyFile = cairo_dock_open_key_file (cChangeLogFilePath);
if (pKeyFile != NULL)
{
gchar *cKeyName = g_strdup_printf ("%d.%d.%d", g_iMajorVersion, g_iMinorVersion, g_iMicroVersion); // version without "alpha", "beta", "rc", etc.
gchar *cChangeLogMessage = g_key_file_get_string (pKeyFile, "ChangeLog", cKeyName, NULL);
g_free (cKeyName);
if (cChangeLogMessage != NULL)
{
GString *sChangeLogMessage = g_string_new (gettext (cChangeLogMessage));
g_free (cChangeLogMessage);
// changelog message is now split (by line): to not re-translate all the message when there is a modification
int i = 0;
while (TRUE)
{
cKeyName = g_strdup_printf ("%d.%d.%d.%d", g_iMajorVersion, g_iMinorVersion, g_iMicroVersion, i);
cChangeLogMessage = g_key_file_get_string (pKeyFile, "ChangeLog", cKeyName, NULL);
g_free (cKeyName);
if (cChangeLogMessage == NULL) // no more message
break;
g_string_append_printf (sChangeLogMessage, "\n %s", gettext (cChangeLogMessage));
g_free (cChangeLogMessage);
i++;
}
Icon *pFirstIcon = cairo_dock_get_first_icon (g_pMainDock->icons);
CairoDialogAttr attr;
memset (&attr, 0, sizeof (CairoDialogAttr));
attr.cText = sChangeLogMessage->str;
attr.cImageFilePath = CAIRO_DOCK_SHARE_DATA_DIR"/"CAIRO_DOCK_ICON;
attr.bUseMarkup = TRUE;
attr.pIcon = pFirstIcon;
attr.pContainer = CAIRO_CONTAINER (g_pMainDock);
gldi_dialog_new (&attr);
g_string_free (sChangeLogMessage, TRUE);
}
g_key_file_free (pKeyFile);
}
// In case something has changed in Compiz/Gtk/others, we also run the script on a new version of the dock.
g_timeout_add_seconds (4, _cairo_dock_first_launch_setup, NULL);
}
else if (cExcludeModule != NULL && ! bMaintenance && s_iNbCrashes > 1)
{
gchar *cMessage;
if (s_iNbCrashes == 2) // <=> second crash: display a dialogue
cMessage = g_strdup_printf (_("The module '%s' may have encountered a problem.\nIt has been restored successfully, but if it happens again, please report it at http://glx-dock.org"), cExcludeModule);
else // since the 3th crash: the applet has been disabled
cMessage = g_strdup_printf (_("The module '%s' has been deactivated because it may have caused some problems.\nYou can reactivate it, if it happens again thanks to report it at http://glx-dock.org"), cExcludeModule);
GldiModule *pModule = gldi_module_get (cExcludeModule);
Icon *icon = gldi_icons_get_any_without_dialog ();
gldi_dialog_show_temporary_with_icon (cMessage, icon, CAIRO_CONTAINER (g_pMainDock), 15000., (pModule ? pModule->pVisitCard->cIconFilePath : NULL));
g_free (cMessage);
}
if (! bTesting)
g_timeout_add_seconds (5, _cairo_dock_successful_launch, GINT_TO_POINTER (bFirstLaunch));
// Start Mainloop
gtk_main ();
signal (SIGSEGV, NULL); // Segmentation violation
signal (SIGFPE, NULL); // Floating-point exception
signal (SIGILL, NULL); // Illegal instruction
signal (SIGABRT, NULL);
signal (SIGTERM, NULL);
signal (SIGHUP, NULL);
gldi_free_all ();
#if (LIBRSVG_MAJOR_VERSION == 2 && LIBRSVG_MINOR_VERSION < 36)
rsvg_term ();
#endif
xmlCleanupParser ();
g_string_free (s_pLaunchCommand, TRUE);
cd_message ("Bye bye !");
g_print ("\033[0m\n");
return 0;
}
cairo-dock-3.3.2/src/cairo-dock-gui-backend.h 000664 001750 001750 00000007047 12223247550 022024 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_GUI_SWITCH__
#define __CAIRO_DOCK_GUI_SWITCH__
#include
G_BEGIN_DECLS
// Definition of the main GUI interface.
struct _CairoDockMainGuiBackend {
// Show the main config panel, build it if necessary.
GtkWidget * (*show_main_gui) (void);
// Show the config panel of a given module (internal or external), reload it if it was already opened.
GtkWidget * (*show_module_gui) (const gchar *cModuleName);
// close the config panels.
void (*close_gui) (void);
// update the GUI to mark a module as '(in)active'.
void (*update_module_state) (const gchar *cModuleName, gboolean bActive);
void (*update_module_instance_container) (GldiModuleInstance *pInstance, gboolean bDetached);
void (*update_desklet_params) (CairoDesklet *pDesklet);
void (*update_desklet_visibility_params) (CairoDesklet *pDesklet);
void (*update_modules_list) (void);
void (*update_shortkeys) (void);
// Show the config panel on a given icon/container, build or reload it if necessary.
GtkWidget * (*show_gui) (Icon *pIcon, GldiContainer *pContainer, GldiModuleInstance *pModuleInstance, int iShowPage);
// reload the gui and its content, for the case a launcher has changed (image, order, new container, etc).
void (*reload_items) (void);
// reload everything, in case the current theme has changed
void (*reload) (void);
// show the themes, in case it should be presented in the menu.
GtkWidget * (*show_themes) (void);
// show the applets.
GtkWidget * (*show_addons) (void);
const gchar *cDisplayedName;
const gchar *cTooltip;
} ;
typedef struct _CairoDockMainGuiBackend CairoDockMainGuiBackend;
void cairo_dock_load_user_gui_backend (int iMode);
int cairo_dock_gui_backend_get_mode ();
GtkWidget *cairo_dock_make_switch_gui_button (void);
gboolean cairo_dock_theme_manager_is_integrated (void);
void cairo_dock_gui_update_desklet_params (CairoDesklet *pDesklet);
void cairo_dock_gui_update_desklet_visibility (CairoDesklet *pDesklet);
void cairo_dock_gui_trigger_reload_items (void);
void cairo_dock_gui_trigger_update_module_state (const gchar *cModuleName);
void cairo_dock_gui_trigger_update_modules_list (void);
void cairo_dock_gui_trigger_update_module_container (GldiModuleInstance *pInstance, gboolean bIsDetached);
void cairo_dock_gui_trigger_reload_shortkeys (void);
void cairo_dock_register_config_gui_backend (CairoDockMainGuiBackend *pBackend);
GtkWidget * cairo_dock_show_main_gui (void);
void cairo_dock_show_module_gui (const gchar *cModuleName);
void cairo_dock_close_gui (void);
void cairo_dock_show_items_gui (Icon *pIcon, GldiContainer *pContainer, GldiModuleInstance *pModuleInstance, int iShowPage);
void cairo_dock_reload_gui (void);
void cairo_dock_show_themes (void);
void cairo_dock_show_addons (void);
gboolean cairo_dock_can_manage_themes (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/cairo-dock-gui-simple.h 000664 001750 001750 00000001647 12223247550 021726 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_GUI_SIMPLE__
#define __CAIRO_DOCK_GUI_SIMPLE__
G_BEGIN_DECLS
void cairo_dock_register_simple_gui_backend (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/CMakeLists.txt 000664 001750 001750 00000003071 12223247550 020222 0 ustar 00mbaerts mbaerts 000000 000000
add_subdirectory (gldit)
add_subdirectory (implementations)
SET(cairo_dock_SRCS
cairo-dock.c
cairo-dock-user-menu.c cairo-dock-user-menu.h
cairo-dock-user-interaction.c cairo-dock-user-interaction.h
cairo-dock-gui-advanced.c cairo-dock-gui-advanced.h
cairo-dock-gui-simple.c cairo-dock-gui-simple.h
cairo-dock-gui-backend.c cairo-dock-gui-backend.h
cairo-dock-gui-commons.c cairo-dock-gui-commons.h
cairo-dock-widget.c cairo-dock-widget.h
cairo-dock-widget-themes.c cairo-dock-widget-themes.h
cairo-dock-widget-items.c cairo-dock-widget-items.h
cairo-dock-widget-config.c cairo-dock-widget-config.h
cairo-dock-widget-plugins.c cairo-dock-widget-plugins.h
cairo-dock-widget-module.c cairo-dock-widget-module.h
cairo-dock-widget-config-group.c cairo-dock-widget-config-group.h
cairo-dock-widget-shortkeys.c cairo-dock-widget-shortkeys.h
)
########### compilation ###############
# Make sure the compiler can find include files from the libraries.
include_directories(
${PACKAGE_INCLUDE_DIRS}
${GTK_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/src/gldit)
# Make sure the linker can find the libraries.
link_directories(
${PACKAGE_LIBRARY_DIRS}
${GTK_LIBRARY_DIRS}
${CMAKE_SOURCE_DIR}/src/gldit)
# Add executable that is built from the source files.
add_executable (${PROJECT_NAME}
${cairo_dock_SRCS} )
# Link the executable to the librairies.
target_link_libraries (${PROJECT_NAME}
${PACKAGE_LIBRARIES}
${GTK_LIBRARIES}
gldi
${LIBINTL_LIBRARIES})
# install the program once it is built.
install(
TARGETS ${PACKAGE}
DESTINATION bin)
cairo-dock-3.3.2/src/cairo-dock-widget-shortkeys.c 000664 001750 001750 00000025301 12223247550 023153 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include "config.h"
#include "cairo-dock-struct.h"
#include "cairo-dock-gui-factory.h"
#include "cairo-dock-gui-manager.h"
#include "cairo-dock-container.h"
#include "cairo-dock-log.h"
#include "cairo-dock-menu.h" // cairo_dock_add_in_menu_with_stock_and_data
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-keybinder.h"
#include "cairo-dock-themes-manager.h" // cairo_dock_update_conf_file
#include "cairo-dock-desktop-manager.h" // gldi_desktop_get_width
#include "cairo-dock-widget-shortkeys.h"
#define CAIRO_DOCK_PREVIEW_HEIGHT 250
static void _shortkeys_widget_reload (CDWidget *pCdWidget);
typedef enum {
CD_SHORTKEY_MODEL_NAME = 0, // demander
CD_SHORTKEY_MODEL_DESCRIPTION, // description
CD_SHORTKEY_MODEL_PIXBUF, // icon image
CD_SHORTKEY_MODEL_SHORTKEY, // shortkey
CD_SHORTKEY_MODEL_STATE, // grabbed or not
CD_SHORTKEY_MODEL_BINDING, // the binding
CD_SHORTKEY_MODEL_NB_COLUMNS
} CDModelColumns;
static void _on_key_grab_cb (GtkWidget *pInputDialog, GdkEventKey *event, GtkTreeView *pTreeView)
{
gchar *key;
cd_debug ("key pressed");
if (gtk_accelerator_valid (event->keyval, event->state))
{
/* This lets us ignore all ignorable modifier keys, including
* NumLock and many others. :)
*
* The logic is: keep only the important modifiers that were pressed
* for this event. */
event->state &= gtk_accelerator_get_default_mod_mask();
/* Generate the correct name for this key */
key = gtk_accelerator_name (event->keyval, event->state);
cd_debug ("KEY GRABBED: '%s'", key);
// get the key binding
GtkTreeSelection *pSelection = gtk_tree_view_get_selection (pTreeView);
GtkTreeModel *pModel;
GtkTreeIter iter;
if (gtk_tree_selection_get_selected (pSelection, &pModel, &iter)) // we retrieve it from the current selection, this way if the binding has been destroyed meanwhile (very unlikely), we're safe.
{
// Bind the new shortkey
GldiShortkey *binding = NULL;
gtk_tree_model_get (pModel, &iter,
CD_SHORTKEY_MODEL_BINDING, &binding, -1);
gldi_shortkey_rebind (binding, key, NULL);
// update the model
gtk_list_store_set (GTK_LIST_STORE (pModel), &iter,
CD_SHORTKEY_MODEL_SHORTKEY, binding->keystring,
CD_SHORTKEY_MODEL_STATE, binding->bSuccess, -1);
// store the new shortkey
if (binding->cConfFilePath != NULL)
{
cairo_dock_update_conf_file (binding->cConfFilePath,
G_TYPE_STRING, binding->cGroupName, binding->cKeyName, key,
G_TYPE_INVALID);
}
}
// Close the window
g_free (key);
gtk_widget_destroy (pInputDialog);
}
}
static void on_cancel_shortkey (G_GNUC_UNUSED GtkButton *button, GtkWidget *pInputDialog)
{
gtk_widget_destroy (pInputDialog);
}
static void _cairo_dock_initiate_change_shortkey (G_GNUC_UNUSED GtkMenuItem *pMenuItem, GtkTreeView *pTreeView)
{
// ensure a line is selected
GtkTreeSelection *pSelection = gtk_tree_view_get_selection (pTreeView);
GtkTreeModel *pModel;
GtkTreeIter iter;
if (! gtk_tree_selection_get_selected (pSelection, &pModel, &iter))
return ;
// build a small modal input dialog, mainly to prevent any other interaction.
GtkWidget *pInputDialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_decorated (GTK_WINDOW (pInputDialog), FALSE);
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (pInputDialog), TRUE);
gtk_window_set_skip_pager_hint (GTK_WINDOW (pInputDialog), TRUE);
//gtk_window_set_transient_for (GTK_WINDOW (pInputDialog), GTK_WINDOW (pMainWindow));
gtk_window_set_modal (GTK_WINDOW (pInputDialog), TRUE);
gtk_widget_add_events (pInputDialog, GDK_KEY_PRESS_MASK);
g_signal_connect (GTK_WIDGET(pInputDialog), "key-press-event", G_CALLBACK(_on_key_grab_cb), pTreeView);
GtkWidget *pMainVBox = _gtk_vbox_new (CAIRO_DOCK_FRAME_MARGIN);
gtk_container_add (GTK_CONTAINER (pInputDialog), pMainVBox);
GtkWidget *pLabel = gtk_label_new (_("Press the shortkey"));
gtk_box_pack_start(GTK_BOX (pMainVBox), pLabel, FALSE, FALSE, 0);
GtkWidget *pCancelButton = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
g_signal_connect (G_OBJECT (pCancelButton), "clicked", G_CALLBACK(on_cancel_shortkey), pInputDialog);
gtk_box_pack_start (GTK_BOX (pMainVBox), pCancelButton, FALSE, FALSE, 0);
gtk_widget_show_all (pInputDialog);
}
static gboolean _on_click_shortkey_tree_view (GtkTreeView *pTreeView, GdkEventButton* pButton, G_GNUC_UNUSED gpointer data)
{
if ((pButton->button == 3 && pButton->type == GDK_BUTTON_RELEASE) // right click
|| (pButton->button == 1 && pButton->type == GDK_2BUTTON_PRESS)) // double click
{
if (pButton->button == 3)
{
GtkWidget *pMenu = gtk_menu_new ();
cairo_dock_add_in_menu_with_stock_and_data (_("Change the shortkey"), GTK_STOCK_PROPERTIES, G_CALLBACK (_cairo_dock_initiate_change_shortkey), pMenu, pTreeView);
gtk_widget_show_all (pMenu);
gtk_menu_popup (GTK_MENU (pMenu),
NULL,
NULL,
NULL,
NULL,
1,
gtk_get_current_event_time ());
}
else
{
_cairo_dock_initiate_change_shortkey (NULL, pTreeView);
}
}
return FALSE;
}
static void _cairo_dock_render_shortkey (G_GNUC_UNUSED GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *model,GtkTreeIter *iter, G_GNUC_UNUSED gpointer data)
{
gboolean bActive = FALSE;
gchar *cShortkey = NULL;
gtk_tree_model_get (model, iter,
CD_SHORTKEY_MODEL_STATE, &bActive,
CD_SHORTKEY_MODEL_SHORTKEY, &cShortkey, -1);
if (bActive)
{
g_object_set (cell, "foreground", "#108000", NULL); // vert
g_object_set (cell, "foreground-set", TRUE, NULL);
}
else if (cShortkey != NULL)
{
g_object_set (cell, "foreground", "#B00000", NULL); // rouge
g_object_set (cell, "foreground-set", TRUE, NULL);
}
else
{
g_object_set (cell, "foreground-set", FALSE, NULL);
}
g_free (cShortkey);
}
void cairo_dock_add_shortkey_to_model (GldiShortkey *binding, GtkListStore *pModel)
{
//g_print (" + %s\n", pModule->pVisitCard->cIconFilePath);
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (binding->cIconFilePath, 32, 32, NULL);
GtkTreeIter iter;
memset (&iter, 0, sizeof (GtkTreeIter));
gtk_list_store_append (GTK_LIST_STORE (pModel), &iter);
// cd_debug (" + %s (%s, %d)", binding->keystring, binding->cDemander, binding->bSuccess);
gtk_list_store_set (GTK_LIST_STORE (pModel), &iter,
CD_SHORTKEY_MODEL_NAME, binding->cDemander,
CD_SHORTKEY_MODEL_SHORTKEY, binding->keystring,
CD_SHORTKEY_MODEL_DESCRIPTION, binding->cDescription,
CD_SHORTKEY_MODEL_PIXBUF, pixbuf,
CD_SHORTKEY_MODEL_STATE, binding->bSuccess,
CD_SHORTKEY_MODEL_BINDING, binding, -1);
g_object_unref (pixbuf);
}
static GtkWidget *cairo_dock_build_shortkeys_widget (void)
{
// fill the model
GtkListStore *pModel = gtk_list_store_new (CD_SHORTKEY_MODEL_NB_COLUMNS,
G_TYPE_STRING, // demander
G_TYPE_STRING, // description
GDK_TYPE_PIXBUF, // icon
G_TYPE_STRING, // shortkey
G_TYPE_BOOLEAN, // grabbed or not
G_TYPE_POINTER); // binding
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (pModel), CD_SHORTKEY_MODEL_NAME, GTK_SORT_ASCENDING);
gldi_shortkeys_foreach ((GFunc) cairo_dock_add_shortkey_to_model, pModel);
// make the treeview
GtkWidget *pOneWidget = gtk_tree_view_new_with_model (GTK_TREE_MODEL (pModel));
g_object_unref (pModel);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (pOneWidget), TRUE);
g_signal_connect (G_OBJECT (pOneWidget), "button-press-event", G_CALLBACK (_on_click_shortkey_tree_view), NULL);
g_signal_connect (G_OBJECT (pOneWidget), "button-release-event", G_CALLBACK (_on_click_shortkey_tree_view), NULL);
// define the rendering of the treeview
GtkTreeViewColumn* col;
GtkCellRenderer *rend;
// icon
rend = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (pOneWidget), -1, NULL, rend, "pixbuf", CD_SHORTKEY_MODEL_PIXBUF, NULL);
// demander
rend = gtk_cell_renderer_text_new ();
col = gtk_tree_view_column_new_with_attributes (_("Origin"), rend, "text", CD_SHORTKEY_MODEL_NAME, NULL);
gtk_tree_view_column_set_sort_column_id (col, CD_SHORTKEY_MODEL_NAME);
gtk_tree_view_append_column (GTK_TREE_VIEW (pOneWidget), col);
// action description
rend = gtk_cell_renderer_text_new ();
col = gtk_tree_view_column_new_with_attributes (_("Action"), rend, "text", CD_SHORTKEY_MODEL_DESCRIPTION, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (pOneWidget), col);
// shortkey
rend = gtk_cell_renderer_text_new ();
col = gtk_tree_view_column_new_with_attributes (_("Shortkey"), rend, "text", CD_SHORTKEY_MODEL_SHORTKEY, NULL);
gtk_tree_view_column_set_cell_data_func (col, rend, (GtkTreeCellDataFunc)_cairo_dock_render_shortkey, NULL, NULL);
gtk_tree_view_column_set_sort_column_id (col, CD_SHORTKEY_MODEL_SHORTKEY);
gtk_tree_view_append_column (GTK_TREE_VIEW (pOneWidget), col);
return pOneWidget;
}
ShortkeysWidget *cairo_dock_shortkeys_widget_new (void)
{
ShortkeysWidget *pShortkeysWidget = g_new0 (ShortkeysWidget, 1);
pShortkeysWidget->widget.iType = WIDGET_SHORTKEYS;
pShortkeysWidget->widget.reload = _shortkeys_widget_reload;
pShortkeysWidget->pShortKeysTreeView = cairo_dock_build_shortkeys_widget ();
GtkWidget *pScrolledWindow = gtk_scrolled_window_new (NULL, NULL);
g_object_set (pScrolledWindow, "height-request", MIN (2*CAIRO_DOCK_PREVIEW_HEIGHT, gldi_desktop_get_height() - 175), NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pScrolledWindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
#if GTK_CHECK_VERSION (3, 8, 0)
gtk_container_add (GTK_CONTAINER (pScrolledWindow), pShortkeysWidget->pShortKeysTreeView);
#else
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (pScrolledWindow), pShortkeysWidget->pShortKeysTreeView);
#endif
pShortkeysWidget->widget.pWidget = pScrolledWindow;
return pShortkeysWidget;
}
static void _shortkeys_widget_reload (CDWidget *pCdWidget)
{
ShortkeysWidget *pShortkeysWidget = SHORKEYS_WIDGET (pCdWidget);
GtkTreeModel *pModel = gtk_tree_view_get_model (GTK_TREE_VIEW (pShortkeysWidget->pShortKeysTreeView));
g_return_if_fail (pModel != NULL);
gtk_list_store_clear (GTK_LIST_STORE (pModel));
gldi_shortkeys_foreach ((GFunc) cairo_dock_add_shortkey_to_model, pModel);
}
cairo-dock-3.3.2/src/cairo-dock-widget-themes.h 000664 001750 001750 00000003422 12223247550 022412 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_WIDGET_THEMES__
#define __CAIRO_DOCK_WIDGET_THEMES__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-widget.h"
G_BEGIN_DECLS
typedef struct _ThemesWidget ThemesWidget;
struct _ThemesWidget {
CDWidget widget; // base class
gchar *cInitConfFile; // conf file used to build the widget
GtkWindow *pMainWindow; // main window, needed to make the waiting dialog modal
CairoDockTask *pImportTask; // task to import a theme from the server
CairoDockTask *pListTask; // task to list the themes on the server
GtkWidget *pTreeView; // tree view for the complete themes list
GtkWidget *pCombo; // combo for the user themes
GtkWidget *pWaitingDialog; // modal dialog to show a progress bar during importation
guint iSidPulse; // timer to make the progress bar move
};
#define THEMES_WIDGET(w) ((ThemesWidget*)(w))
#define IS_THEMES_WIDGET(w) (w && CD_WIDGET(w)->iType == WIDGET_THEMES)
ThemesWidget *cairo_dock_themes_widget_new (GtkWindow *pMainWindow);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/cairo-dock-gui-commons.c 000664 001750 001750 00000024045 12223247550 022100 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#define __USE_XOPEN_EXTENDED
#include
#include
#define __USE_POSIX
#include
#include
#include "config.h"
#include "cairo-dock-config.h"
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-desklet-factory.h" // cairo_dock_desklet_is_sticky
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-gui-manager.h"
#include "cairo-dock-gui-factory.h"
#include "cairo-dock-task.h"
#include "cairo-dock-log.h"
#include "cairo-dock-packages.h"
#include "cairo-dock-keybinder.h"
#include "cairo-dock-desktop-manager.h" // gldi_desktop_get_width
#include "cairo-dock-themes-manager.h"
#include "cairo-dock-dialog-manager.h"
#include "cairo-dock-gui-backend.h"
#include "cairo-dock-gui-commons.h"
#include "cairo-dock-icon-manager.h" // cairo_dock_search_icon_s_path
#define CAIRO_DOCK_PLUGINS_EXTRAS_URL "http://extras.glx-dock.org"
extern gchar *g_cCairoDockDataDir;
void cairo_dock_update_desklet_widgets (CairoDesklet *pDesklet, GSList *pWidgetList)
{
CairoDockGroupKeyWidget *pGroupKeyWidget;
GtkWidget *pOneWidget;
pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Desklet", "locked");
g_return_if_fail (pGroupKeyWidget != NULL && pGroupKeyWidget->pSubWidgetList != NULL);
pOneWidget = pGroupKeyWidget->pSubWidgetList->data;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pOneWidget), pDesklet->bPositionLocked);
pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Desklet", "size");
g_return_if_fail (pGroupKeyWidget != NULL && pGroupKeyWidget->pSubWidgetList != NULL);
pOneWidget = pGroupKeyWidget->pSubWidgetList->data;
g_signal_handlers_block_matched (pOneWidget,
(GSignalMatchType) G_SIGNAL_MATCH_FUNC,
0, 0, NULL, _cairo_dock_set_value_in_pair, NULL);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (pOneWidget), pDesklet->container.iWidth);
g_signal_handlers_unblock_matched (pOneWidget,
(GSignalMatchType) G_SIGNAL_MATCH_FUNC,
0, 0, NULL, _cairo_dock_set_value_in_pair, NULL);
if (pGroupKeyWidget->pSubWidgetList->next != NULL)
{
pOneWidget = pGroupKeyWidget->pSubWidgetList->next->data;
g_signal_handlers_block_matched (pOneWidget,
(GSignalMatchType) G_SIGNAL_MATCH_FUNC,
0, 0, NULL, _cairo_dock_set_value_in_pair, NULL);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (pOneWidget), pDesklet->container.iHeight);
g_signal_handlers_unblock_matched (pOneWidget,
(GSignalMatchType) G_SIGNAL_MATCH_FUNC,
0, 0, NULL, _cairo_dock_set_value_in_pair, NULL);
}
int iRelativePositionX = (pDesklet->container.iWindowPositionX + pDesklet->container.iWidth/2 <= gldi_desktop_get_width()/2 ? pDesklet->container.iWindowPositionX : pDesklet->container.iWindowPositionX - gldi_desktop_get_width());
int iRelativePositionY = (pDesklet->container.iWindowPositionY + pDesklet->container.iHeight/2 <= gldi_desktop_get_height()/2 ? pDesklet->container.iWindowPositionY : pDesklet->container.iWindowPositionY - gldi_desktop_get_height());
pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Desklet", "x position");
g_return_if_fail (pGroupKeyWidget != NULL && pGroupKeyWidget->pSubWidgetList != NULL);
pOneWidget = pGroupKeyWidget->pSubWidgetList->data;
gtk_spin_button_set_value (GTK_SPIN_BUTTON (pOneWidget), iRelativePositionX);
pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Desklet", "y position");
g_return_if_fail (pGroupKeyWidget != NULL && pGroupKeyWidget->pSubWidgetList != NULL);
pOneWidget = pGroupKeyWidget->pSubWidgetList->data;
gtk_spin_button_set_value (GTK_SPIN_BUTTON (pOneWidget), iRelativePositionY);
pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Desklet", "rotation");
g_return_if_fail (pGroupKeyWidget != NULL && pGroupKeyWidget->pSubWidgetList != NULL);
pOneWidget = pGroupKeyWidget->pSubWidgetList->data;
gtk_range_set_value (GTK_RANGE (pOneWidget), pDesklet->fRotation/G_PI*180.);
}
void cairo_dock_update_desklet_visibility_widgets (CairoDesklet *pDesklet, GSList *pWidgetList)
{
CairoDockGroupKeyWidget *pGroupKeyWidget;
GtkWidget *pOneWidget;
gboolean bIsSticky = gldi_desklet_is_sticky (pDesklet);
CairoDeskletVisibility iVisibility = pDesklet->iVisibility;
pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Desklet", "accessibility");
g_return_if_fail (pGroupKeyWidget != NULL && pGroupKeyWidget->pSubWidgetList != NULL);
pOneWidget = pGroupKeyWidget->pSubWidgetList->data;
gtk_combo_box_set_active (GTK_COMBO_BOX (pOneWidget), iVisibility);
pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Desklet", "sticky");
g_return_if_fail (pGroupKeyWidget != NULL && pGroupKeyWidget->pSubWidgetList != NULL);
pOneWidget = pGroupKeyWidget->pSubWidgetList->data;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pOneWidget), bIsSticky);
pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Desklet", "locked");
g_return_if_fail (pGroupKeyWidget != NULL && pGroupKeyWidget->pSubWidgetList != NULL);
pOneWidget = pGroupKeyWidget->pSubWidgetList->data;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pOneWidget), pDesklet->bPositionLocked);
}
void cairo_dock_update_is_detached_widget (gboolean bIsDetached, GSList *pWidgetList)
{
CairoDockGroupKeyWidget *pGroupKeyWidget;
GtkWidget *pOneWidget;
pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Desklet", "initially detached");
g_return_if_fail (pGroupKeyWidget != NULL && pGroupKeyWidget->pSubWidgetList != NULL);
pOneWidget = pGroupKeyWidget->pSubWidgetList->data;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pOneWidget), bIsDetached);
}
#define DISTANT_DIR "3.3.0"
gchar *cairo_dock_get_third_party_applets_link (void)
{
return g_strdup_printf (CAIRO_DOCK_PLUGINS_EXTRAS_URL"/"DISTANT_DIR);
}
/**
* Return absolute position of the bottom left corner of a widget to place a menu.
* use with @see cairo_dock_place_menu_at_position
* see @see cairo_dock_popup_menu_under_widget for an example
*/
GtkRequisition *cairo_dock_get_widget_bottom_position (GtkWidget *pWidget)
{
GtkRequisition *pPosition = g_new (GtkRequisition, 1);
gint dx = 0, dy = 0;
GtkRequisition req;
// Top left drawable window coordinates on screen. (inside decorations)
// We need to get the toplevel widget origin.
// Otherwise, it would give wrong results if called on the widget in a scrolled area.
// (drawable surface origin can even be out of the screen).
GtkWidget *pTopLevel = gtk_widget_get_toplevel (pWidget);
gdk_window_get_origin (gtk_widget_get_window (pTopLevel), &pPosition->width, &pPosition->height);
// Widget position inside the window.
gtk_widget_translate_coordinates (pWidget, pTopLevel, 0, 0, &dx, &dy);
// Widget height.
#if (GTK_MAJOR_VERSION < 3)
gtk_widget_size_request (pWidget, &req);
#else
gtk_widget_get_preferred_size (pWidget, &req, NULL);
#endif
pPosition->width += dx;
pPosition->height += dy + req.height;
return pPosition;
}
/**
* Convenient GtkMenuPositionFunc callback function to position menu.
* use with @see cairo_dock_get_widget_bottom_position
*/
void cairo_dock_place_menu_at_position (G_GNUC_UNUSED GtkMenu *menu, gint *x, gint *y, gboolean *push_in, GtkRequisition *pPosition)
{
*push_in = TRUE;
if (pPosition != NULL)
{
*x = pPosition->width;
*y = pPosition->height;
}
}
/**
* Callback for the button-press-event that popup the given menu.
*/
void cairo_dock_popup_menu_under_widget (GtkWidget *pWidget, GtkMenu *pMenu)
{
GtkRequisition *pPosition = pWidget == NULL ? NULL : cairo_dock_get_widget_bottom_position (pWidget);
gtk_menu_popup (pMenu,
NULL,
NULL,
(GtkMenuPositionFunc) cairo_dock_place_menu_at_position,
pPosition,
0, // pEventButton->button
gtk_get_current_event_time ()); // pEventButton->time
if (pPosition != NULL)
g_free (pPosition);
}
/**
* Look for an icon for GUI
*/
gchar * cairo_dock_get_icon_for_gui (const gchar *cGroupName, const gchar *cIcon, const gchar *cShareDataDir, gint iSize, gboolean bFastLoad)
{
gchar *cIconPath = NULL;
if (cIcon)
{
if (*cIcon == '/') // on ecrase les chemins des icons d'applets.
{
if (bFastLoad)
return g_strdup (cIcon);
cIconPath = g_strdup_printf ("%s/config-panel/%s.png", g_cCairoDockDataDir, cGroupName);
if (!g_file_test (cIconPath, G_FILE_TEST_EXISTS))
{
g_free (cIconPath);
cIconPath = g_strdup (cIcon);
}
}
else if (strncmp (cIcon, "gtk-", 4) == 0)
{
cIconPath = g_strdup (cIcon);
}
else // categorie ou module interne.
{
if (! bFastLoad)
{
cIconPath = g_strconcat (g_cCairoDockDataDir, "/config-panel/", cIcon, NULL);
if (!g_file_test (cIconPath, G_FILE_TEST_EXISTS))
{
g_free (cIconPath);
cIconPath = g_strconcat (CAIRO_DOCK_SHARE_DATA_DIR"/icons/", cIcon, NULL);
if (!g_file_test (cIconPath, G_FILE_TEST_EXISTS)) // if we just have the name of an application
{
g_free (cIconPath);
cIconPath = NULL;
}
}
}
if (cIconPath == NULL)
{
cIconPath = cairo_dock_search_icon_s_path (cIcon, iSize);
if (cIconPath == NULL && cShareDataDir) // maybe we don't have any icon with this name
cIconPath = cShareDataDir ? g_strdup_printf ("%s/icon", cShareDataDir) : g_strdup (cIcon);
}
}
}
else if (cShareDataDir)
cIconPath = g_strdup_printf ("%s/icon", cShareDataDir);
return cIconPath;
}
cairo-dock-3.3.2/src/cairo-dock-user-menu.h 000664 001750 001750 00000002304 12223247550 021562 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_USER_MENU__
#define __CAIRO_DOCK_USER_MENU__
#include
#include "cairo-dock-struct.h"
G_BEGIN_DECLS
gboolean cairo_dock_notification_build_container_menu (gpointer *pUserData, Icon *icon, GldiContainer *pContainer, GtkWidget *menu, gboolean *bDiscardMenu);
gboolean cairo_dock_notification_build_icon_menu (gpointer *pUserData, Icon *icon, GldiContainer *pContainer, GtkWidget *menu);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-utils.h 000664 001750 001750 00000006636 12223247550 022121 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_UTILS__
#define __CAIRO_DOCK_UTILS__
G_BEGIN_DECLS
/**
*@file cairo-dock-utils.h Some helper functions.
*/
gchar *cairo_dock_generate_unique_filename (const gchar *cBaseName, const gchar *cCairoDockDataDir);
gchar *cairo_dock_cut_string (const gchar *cString, int iNbCaracters);;
/** Remove the version number from a string. Directly modifies the string.
* @param cString a string.
* @return TRUE if a version has been removed.
*/
gboolean cairo_dock_remove_version_from_string (gchar *cString);
/** Replace the %20 by normal spaces into the string. The string is directly modified.
*@param cString the string (it can't be a constant string)
*/
void cairo_dock_remove_html_spaces (gchar *cString);
/** Get the 3 version numbers of a string.
*@param cVersionString the string of the form "x.y.z".
*@param iMajorVersion pointer to the major version.
*@param iMinorVersion pointer to the minor version.
*@param iMicroVersion pointer to the micro version.
*/
void cairo_dock_get_version_from_string (const gchar *cVersionString, int *iMajorVersion, int *iMinorVersion, int *iMicroVersion);
/** Say if a string is an adress (file://xxx, http://xxx, ftp://xxx, etc).
* @param cString a string.
* @return TRUE if it's an address.
*/
gboolean cairo_dock_string_is_address (const gchar *cString);
#define cairo_dock_string_is_adress cairo_dock_string_is_address
gchar *cairo_dock_launch_command_sync_with_stderr (const gchar *cCommand, gboolean bPrintStdErr);
#define cairo_dock_launch_command_sync(cCommand) cairo_dock_launch_command_sync_with_stderr (cCommand, TRUE)
gboolean cairo_dock_launch_command_printf (const gchar *cCommandFormat, const gchar *cWorkingDirectory, ...) G_GNUC_PRINTF (1, 3);
gboolean cairo_dock_launch_command_full (const gchar *cCommand, const gchar *cWorkingDirectory);
#define cairo_dock_launch_command(cCommand) cairo_dock_launch_command_full (cCommand, NULL)
gchar * cairo_dock_get_command_with_right_terminal (const gchar *cCommand);
/* Like g_strcmp0, but saves a function call.
*/
#define gldi_strings_differ(s1, s2) (!s1 ? s2 != NULL : !s2 ? s1 != NULL : strcmp(s1, s2) != 0)
#define cairo_dock_strings_differ gldi_strings_differ
/** Say if 2 RGBA colors differ.
*/
#define cairo_dock_colors_rvb_differ(c1, c2) ((c1[0] != c2[0]) || (c1[1] != c2[1]) || (c1[2] != c2[2]))
/** Say if 2 RGB colors differ.
*/
#define cairo_dock_colors_differ(c1, c2) (cairo_dock_colors_rvb_differ (c1, c2) || (c1[3] != c2[3]))
#include "gldi-config.h"
#ifdef HAVE_X11
gboolean cairo_dock_property_is_present_on_root (const gchar *cPropertyName); // env-manager
gboolean cairo_dock_check_xrandr (int major, int minor); // showDesktop
#endif
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-dbus.c 000664 001750 001750 00000044762 12223247550 021713 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include "cairo-dock-log.h"
#include "cairo-dock-dbus.h"
static DBusGConnection *s_pSessionConnexion = NULL;
static DBusGConnection *s_pSystemConnexion = NULL;
static DBusGProxy *s_pDBusSessionProxy = NULL;
static DBusGProxy *s_pDBusSystemProxy = NULL;
static GHashTable *s_pFilterTable = NULL;
static GList *s_pFilterList = NULL;
DBusGConnection *cairo_dock_get_session_connection (void)
{
if (s_pSessionConnexion == NULL)
{
GError *erreur = NULL;
s_pSessionConnexion = dbus_g_bus_get (DBUS_BUS_SESSION, &erreur);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
s_pSessionConnexion = NULL;
}
}
return s_pSessionConnexion;
}
DBusGConnection *cairo_dock_get_system_connection (void)
{
if (s_pSystemConnexion == NULL)
{
GError *erreur = NULL;
s_pSystemConnexion = dbus_g_bus_get (DBUS_BUS_SYSTEM, &erreur);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
s_pSystemConnexion = NULL;
}
}
return s_pSystemConnexion;
}
DBusGProxy *cairo_dock_get_main_proxy (void)
{
if (s_pDBusSessionProxy == NULL)
{
s_pDBusSessionProxy = cairo_dock_create_new_session_proxy (DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS);
}
return s_pDBusSessionProxy;
}
DBusGProxy *cairo_dock_get_main_system_proxy (void)
{
if (s_pDBusSystemProxy == NULL)
{
s_pDBusSystemProxy = cairo_dock_create_new_system_proxy (DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS);
}
return s_pDBusSystemProxy;
}
gboolean cairo_dock_register_service_name (const gchar *cServiceName)
{
DBusGProxy *pProxy = cairo_dock_get_main_proxy ();
if (pProxy == NULL)
return FALSE;
GError *erreur = NULL;
guint request_ret;
org_freedesktop_DBus_request_name (pProxy, cServiceName, 0, &request_ret, &erreur);
if (erreur != NULL)
{
cd_warning ("Unable to register service: %s", erreur->message);
g_error_free (erreur);
return FALSE;
}
return TRUE;
}
gboolean cairo_dock_dbus_is_enabled (void)
{
return (cairo_dock_get_session_connection () != NULL && cairo_dock_get_system_connection () != NULL);
}
static void on_name_owner_changed (G_GNUC_UNUSED DBusGProxy *pProxy, const gchar *cName, G_GNUC_UNUSED const gchar *cPrevOwner, const gchar *cNewOwner, G_GNUC_UNUSED gpointer data)
{
//g_print ("%s (%s)\n", __func__, cName);
gboolean bOwned = (cNewOwner != NULL && *cNewOwner != '\0');
GList *pFilter = g_hash_table_lookup (s_pFilterTable, cName);
GList *f;
for (f = pFilter; f != NULL; f = f->next)
{
gpointer *p = f->data;
CairoDockDbusNameOwnerChangedFunc pCallback = p[0];
pCallback (cName, bOwned, p[1]);
}
for (f = s_pFilterList; f != NULL; f = f->next)
{
gpointer *p = f->data;
if (strncmp (cName, p[2], GPOINTER_TO_INT (p[3])) == 0)
{
CairoDockDbusNameOwnerChangedFunc pCallback = p[0];
pCallback (cName, bOwned, p[1]);
}
}
}
void cairo_dock_watch_dbus_name_owner (const char *cName, CairoDockDbusNameOwnerChangedFunc pCallback, gpointer data)
{
if (cName == NULL)
return;
if (s_pFilterTable == NULL) // first call to this function.
{
// create the table
s_pFilterTable = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
// and register to the 'NameOwnerChanged' signal
DBusGProxy *pProxy = cairo_dock_get_main_proxy ();
g_return_if_fail (pProxy != NULL);
dbus_g_proxy_add_signal (pProxy, "NameOwnerChanged",
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_INVALID);
dbus_g_proxy_connect_signal (pProxy, "NameOwnerChanged",
G_CALLBACK (on_name_owner_changed),
NULL, NULL);
}
// record the callback.
gpointer *p = g_new0 (gpointer, 4);
p[0] = pCallback;
p[1] = data;
int n = strlen(cName);
if (cName[n-1] == '*')
{
p[2] = g_strdup (cName);
p[3] = GINT_TO_POINTER (n-1);
s_pFilterList = g_list_prepend (s_pFilterList, p);
}
else
{
GList *pFilter = g_hash_table_lookup (s_pFilterTable, cName);
pFilter = g_list_prepend (pFilter, p);
g_hash_table_insert (s_pFilterTable, g_strdup (cName), pFilter);
}
}
void cairo_dock_stop_watching_dbus_name_owner (const char *cName, CairoDockDbusNameOwnerChangedFunc pCallback)
{
if (cName == NULL || *cName == '\0')
return;
int n = strlen(cName);
if (cName[n-1] == '*')
{
GList *f;
for (f = s_pFilterList; f != NULL; f = f->next)
{
gpointer *p = f->data;
if (strncmp (cName, p[2], strlen (cName)-1) == 0 && pCallback == p[0])
{
g_free (p[2]);
g_free (p);
s_pFilterList = g_list_delete_link (s_pFilterList, f);
}
}
}
else
{
GList *pFilter = g_hash_table_lookup (s_pFilterTable, cName);
if (pFilter != NULL)
{
GList *f;
for (f = pFilter; f != NULL; f = f->next)
{
gpointer *p = f->data;
if (pCallback == p[0])
{
g_free (p);
pFilter = g_list_delete_link (pFilter, f);
g_hash_table_insert (s_pFilterTable, g_strdup (cName), pFilter);
break;
}
}
}
}
}
DBusGProxy *cairo_dock_create_new_session_proxy (const char *name, const char *path, const char *interface)
{
DBusGConnection *pConnection = cairo_dock_get_session_connection ();
if (pConnection != NULL)
return dbus_g_proxy_new_for_name (
pConnection,
name,
path,
interface);
else
return NULL;
}
DBusGProxy *cairo_dock_create_new_system_proxy (const char *name, const char *path, const char *interface)
{
DBusGConnection *pConnection = cairo_dock_get_system_connection ();
if (pConnection != NULL)
return dbus_g_proxy_new_for_name (
pConnection,
name,
path,
interface);
else
return NULL;
}
static void _on_detect_application (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer *data)
{
CairoDockOnAppliPresentOnDbus pCallback = data[0];
gpointer user_data = data[1];
gchar *cName = data[2];
gchar **name_list = NULL;
gboolean bSuccess = dbus_g_proxy_end_call (proxy,
call_id,
NULL,
G_TYPE_STRV,
&name_list,
G_TYPE_INVALID);
gboolean bPresent = FALSE;
cd_message ("detection du service %s (%d)...", cName, bSuccess);
if (bSuccess && name_list)
{
int i;
int n = strlen(cName);
if (cName[n-1] == '*')
{
for (i = 0; name_list[i] != NULL; i ++)
{
if (strncmp (name_list[i], cName, n) == 0)
{
bPresent = TRUE;
break;
}
}
}
else
{
for (i = 0; name_list[i] != NULL; i ++)
{
if (strcmp (name_list[i], cName) == 0)
{
bPresent = TRUE;
break;
}
}
}
}
pCallback (bPresent, user_data);
g_strfreev (name_list);
g_free (cName);
data[2] = NULL;
}
static void _free_detect_application (gpointer *data)
{
cd_debug ("free detection data\n");
g_free (data[2]);
g_free (data);
}
static inline DBusGProxyCall *_dbus_detect_application_async (const gchar *cName, DBusGProxy *pProxy, CairoDockOnAppliPresentOnDbus pCallback, gpointer user_data)
{
g_return_val_if_fail (cName != NULL && pProxy != NULL, FALSE);
gpointer *data = g_new0 (gpointer, 3);
data[0] = pCallback;
data[1] = user_data;
data[2] = g_strdup (cName);
DBusGProxyCall* pCall= dbus_g_proxy_begin_call (pProxy, "ListNames",
(DBusGProxyCallNotify)_on_detect_application,
data,
(GDestroyNotify) _free_detect_application,
G_TYPE_INVALID);
return pCall;
}
DBusGProxyCall *cairo_dock_dbus_detect_application_async (const gchar *cName, CairoDockOnAppliPresentOnDbus pCallback, gpointer user_data)
{
cd_message ("%s (%s)", __func__, cName);
DBusGProxy *pProxy = cairo_dock_get_main_proxy ();
return _dbus_detect_application_async (cName, pProxy, pCallback, user_data);
}
DBusGProxyCall *cairo_dock_dbus_detect_system_application_async (const gchar *cName, CairoDockOnAppliPresentOnDbus pCallback, gpointer user_data)
{
cd_message ("%s (%s)", __func__, cName);
DBusGProxy *pProxy = cairo_dock_get_main_system_proxy ();
return _dbus_detect_application_async (cName, pProxy, pCallback, user_data);
}
static inline gboolean _dbus_detect_application (const gchar *cName, DBusGProxy *pProxy)
{
g_return_val_if_fail (cName != NULL && pProxy != NULL, FALSE);
gchar **name_list = NULL;
gboolean bPresent = FALSE;
if(dbus_g_proxy_call (pProxy, "ListNames", NULL,
G_TYPE_INVALID,
G_TYPE_STRV,
&name_list,
G_TYPE_INVALID))
{
cd_message ("detection du service %s ...", cName);
int i;
for (i = 0; name_list[i] != NULL; i ++)
{
if (strcmp (name_list[i], cName) == 0)
{
bPresent = TRUE;
break;
}
}
}
g_strfreev (name_list);
return bPresent;
}
gboolean cairo_dock_dbus_detect_application (const gchar *cName)
{
cd_message ("%s (%s)", __func__, cName);
DBusGProxy *pProxy = cairo_dock_get_main_proxy ();
return _dbus_detect_application (cName, pProxy);
}
gboolean cairo_dock_dbus_detect_system_application (const gchar *cName)
{
cd_message ("%s (%s)", __func__, cName);
DBusGProxy *pProxy = cairo_dock_get_main_system_proxy ();
return _dbus_detect_application (cName, pProxy);
}
gchar **cairo_dock_dbus_get_services (void)
{
DBusGProxy *pProxy = cairo_dock_get_main_proxy ();
gchar **name_list = NULL;
if(dbus_g_proxy_call (pProxy, "ListNames", NULL,
G_TYPE_INVALID,
G_TYPE_STRV,
&name_list,
G_TYPE_INVALID))
return name_list;
else
return NULL;
}
gboolean cairo_dock_dbus_get_boolean (DBusGProxy *pDbusProxy, const gchar *cAccessor)
{
GError *erreur = NULL;
gboolean bValue = FALSE;
dbus_g_proxy_call (pDbusProxy, cAccessor, &erreur,
G_TYPE_INVALID,
G_TYPE_BOOLEAN, &bValue,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
}
return bValue;
}
int cairo_dock_dbus_get_integer (DBusGProxy *pDbusProxy, const gchar *cAccessor)
{
GError *erreur = NULL;
int iValue = -1;
dbus_g_proxy_call (pDbusProxy, cAccessor, &erreur,
G_TYPE_INVALID,
G_TYPE_INT, &iValue,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
iValue = -1;
}
return iValue;
}
guint cairo_dock_dbus_get_uinteger (DBusGProxy *pDbusProxy, const gchar *cAccessor)
{
GError *erreur = NULL;
guint iValue = -1;
dbus_g_proxy_call (pDbusProxy, cAccessor, &erreur,
G_TYPE_INVALID,
G_TYPE_UINT, &iValue,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
iValue = -1;
}
return iValue;
}
gchar *cairo_dock_dbus_get_string (DBusGProxy *pDbusProxy, const gchar *cAccessor)
{
GError *erreur = NULL;
gchar *cValue = NULL;
dbus_g_proxy_call (pDbusProxy, cAccessor, &erreur,
G_TYPE_INVALID,
G_TYPE_STRING, &cValue,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
}
return cValue;
}
guchar *cairo_dock_dbus_get_uchar (DBusGProxy *pDbusProxy, const gchar *cAccessor)
{
GError *erreur = NULL;
guchar* uValue = NULL;
dbus_g_proxy_call (pDbusProxy, cAccessor, &erreur,
G_TYPE_INVALID,
G_TYPE_UCHAR, &uValue,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
}
return uValue;
}
gdouble cairo_dock_dbus_get_double (DBusGProxy *pDbusProxy, const gchar *cAccessor)
{
GError *erreur = NULL;
gdouble fValue = 0.;
dbus_g_proxy_call (pDbusProxy, cAccessor, &erreur,
G_TYPE_INVALID,
G_TYPE_DOUBLE, &fValue,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
}
return fValue;
}
gchar **cairo_dock_dbus_get_string_list (DBusGProxy *pDbusProxy, const gchar *cAccessor)
{
GError *erreur = NULL;
gchar **cValues = NULL;
dbus_g_proxy_call (pDbusProxy, cAccessor, &erreur,
G_TYPE_INVALID,
G_TYPE_STRV, &cValues,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
}
return cValues;
}
GPtrArray *cairo_dock_dbus_get_array (DBusGProxy *pDbusProxy, const gchar *cAccessor)
{
GError *erreur = NULL;
GPtrArray *pArray = NULL;
dbus_g_proxy_call (pDbusProxy, cAccessor, &erreur,
G_TYPE_INVALID,
dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &pArray,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
}
return pArray;
}
void cairo_dock_dbus_call (DBusGProxy *pDbusProxy, const gchar *cCommand)
{
dbus_g_proxy_call_no_reply (pDbusProxy, cCommand,
G_TYPE_INVALID,
G_TYPE_INVALID);
}
void cairo_dock_dbus_get_properties (DBusGProxy *pDbusProxy, const gchar *cCommand, const gchar *cInterface, const gchar *cProperty, GValue *vProperties)
{
GError *erreur=NULL;
dbus_g_proxy_call(pDbusProxy, cCommand, &erreur,
G_TYPE_STRING, cInterface,
G_TYPE_STRING, cProperty,
G_TYPE_INVALID,
G_TYPE_VALUE, vProperties,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
}
}
void cairo_dock_dbus_get_property_in_value_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, GValue *pProperty, gint iTimeOut)
{
GError *erreur=NULL;
dbus_g_proxy_call_with_timeout (pDbusProxy, "Get", iTimeOut, &erreur,
G_TYPE_STRING, cInterface,
G_TYPE_STRING, cProperty,
G_TYPE_INVALID,
G_TYPE_VALUE, pProperty,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
}
}
gboolean cairo_dock_dbus_get_property_as_boolean_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, gint iTimeOut)
{
GValue v = G_VALUE_INIT;
cairo_dock_dbus_get_property_in_value_with_timeout (pDbusProxy, cInterface, cProperty, &v, iTimeOut);
if (G_VALUE_HOLDS_BOOLEAN (&v))
return g_value_get_boolean (&v);
else
return FALSE;
}
gint cairo_dock_dbus_get_property_as_int_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, gint iTimeOut)
{
GValue v = G_VALUE_INIT;
cairo_dock_dbus_get_property_in_value_with_timeout (pDbusProxy, cInterface, cProperty, &v, iTimeOut);
if (G_VALUE_HOLDS_INT (&v))
return g_value_get_int (&v);
else
return 0;
}
guint cairo_dock_dbus_get_property_as_uint_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, gint iTimeOut)
{
GValue v = G_VALUE_INIT;
cairo_dock_dbus_get_property_in_value_with_timeout (pDbusProxy, cInterface, cProperty, &v, iTimeOut);
if (G_VALUE_HOLDS_UINT (&v))
return g_value_get_uint (&v);
else
return 0;
}
guchar cairo_dock_dbus_get_property_as_uchar_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, gint iTimeOut)
{
GValue v = G_VALUE_INIT;
cairo_dock_dbus_get_property_in_value_with_timeout (pDbusProxy, cInterface, cProperty, &v, iTimeOut);
if (G_VALUE_HOLDS_UCHAR (&v))
return g_value_get_uchar (&v);
else
return 0;
}
gdouble cairo_dock_dbus_get_property_as_double_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, gint iTimeOut)
{
GValue v = G_VALUE_INIT;
cairo_dock_dbus_get_property_in_value_with_timeout (pDbusProxy, cInterface, cProperty, &v, iTimeOut);
if (G_VALUE_HOLDS_DOUBLE (&v))
return g_value_get_double (&v);
else
return 0.;
}
gchar *cairo_dock_dbus_get_property_as_string_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, gint iTimeOut)
{
GValue v = G_VALUE_INIT;
cairo_dock_dbus_get_property_in_value_with_timeout (pDbusProxy, cInterface, cProperty, &v, iTimeOut);
if (G_VALUE_HOLDS_STRING (&v))
{
gchar *s = (gchar*)g_value_get_string (&v); // on recupere directement le contenu de la GValue. Comme on ne libere pas la GValue, la chaine est a liberer soi-meme quand on en n'a plus besoin.
return s;
}
else
return NULL;
}
gchar *cairo_dock_dbus_get_property_as_object_path_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, gint iTimeOut)
{
GValue v = G_VALUE_INIT;
cairo_dock_dbus_get_property_in_value_with_timeout (pDbusProxy, cInterface, cProperty, &v, iTimeOut);
if (G_VALUE_HOLDS (&v, DBUS_TYPE_G_OBJECT_PATH))
{
gchar *s = (gchar*)g_value_get_string (&v); // meme remarque.
return s;
}
else
return NULL;
}
gpointer cairo_dock_dbus_get_property_as_boxed_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, gint iTimeOut)
{
GValue v = G_VALUE_INIT;
cairo_dock_dbus_get_property_in_value_with_timeout (pDbusProxy, cInterface, cProperty, &v, iTimeOut);
if (G_VALUE_HOLDS_BOXED (&v))
{
gpointer p = g_value_get_boxed (&v); // meme remarque.
return p;
}
else
return NULL;
}
gchar **cairo_dock_dbus_get_property_as_string_list_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, gint iTimeOut)
{
GValue v = G_VALUE_INIT;
cairo_dock_dbus_get_property_in_value_with_timeout (pDbusProxy, cInterface, cProperty, &v, iTimeOut);
if (G_VALUE_HOLDS_BOXED(&v))
{
gchar **s = (gchar**)g_value_get_boxed (&v); // meme remarque.
return s;
}
else
return NULL;
}
GHashTable *cairo_dock_dbus_get_all_properties_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, gint iTimeOut)
{
GError *erreur=NULL;
GHashTable *hProperties = NULL;
dbus_g_proxy_call_with_timeout (pDbusProxy, "GetAll", iTimeOut, &erreur,
G_TYPE_STRING, cInterface,
G_TYPE_INVALID,
(dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)), &hProperties,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
return NULL;
}
else
{
return hProperties;
}
}
void cairo_dock_dbus_set_property_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, GValue *pProperty, gint iTimeOut)
{
GError *erreur=NULL;
dbus_g_proxy_call_with_timeout (pDbusProxy, "Set", iTimeOut, &erreur,
G_TYPE_STRING, cInterface,
G_TYPE_STRING, cProperty,
G_TYPE_VALUE, pProperty,
G_TYPE_INVALID,
G_TYPE_INVALID);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
}
}
void cairo_dock_dbus_set_boolean_property_with_timeout (DBusGProxy *pDbusProxy, const gchar *cInterface, const gchar *cProperty, gboolean bValue, gint iTimeOut)
{
GValue v = G_VALUE_INIT;
g_value_init (&v, G_TYPE_BOOLEAN);
g_value_set_boolean (&v, bValue);
cairo_dock_dbus_set_property_with_timeout (pDbusProxy, cInterface, cProperty, &v, iTimeOut);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-config.c 000664 001750 001750 00000050755 12223247550 022222 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include
#include "gldi-config.h"
#ifdef HAVE_LIBCRYPT
#ifdef __FreeBSD__
#include // on BSD, there is no crypt.h
#else
#include
#endif
static char DES_crypt_key[64] =
{
1,0,0,1,1,1,0,0, 1,0,1,1,1,0,1,1, 1,1,0,1,0,1,0,1, 1,1,0,0,0,0,0,1,
0,0,0,1,0,1,1,0, 1,1,1,0,1,1,1,0, 1,1,1,0,0,1,0,0, 1,0,1,0,1,0,1,1
};
#endif
#include "cairo-dock-log.h"
#include "cairo-dock-icon-manager.h" // cairo_dock_hide_show_launchers_on_other_desktops
#include "cairo-dock-applications-manager.h" // cairo_dock_start_applications_manager
#include "cairo-dock-module-manager.h" // gldi_modules_activate_from_list
#include "cairo-dock-themes-manager.h" // cairo_dock_update_conf_file
#include "cairo-dock-dock-factory.h" // gldi_dock_new
#include "cairo-dock-file-manager.h" // cairo_dock_get_file_size
#include "cairo-dock-user-icon-manager.h" // gldi_user_icons_new_from_directory
#include "cairo-dock-utils.h" // cairo_dock_launch_command_sync
#include "cairo-dock-core.h" // gldi_free_all
#include "cairo-dock-config.h"
gboolean g_bEasterEggs = FALSE;
extern gchar *g_cCurrentLaunchersPath;
extern gchar *g_cConfFile;
extern gboolean g_bUseOpenGL;
extern CairoDockDesktopEnv g_iDesktopEnv;
static gboolean s_bLoading = FALSE;
gboolean cairo_dock_get_boolean_key_value (GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, gboolean bDefaultValue, const gchar *cDefaultGroupName, const gchar *cDefaultKeyName)
{
GError *erreur = NULL;
gboolean bValue = g_key_file_get_boolean (pKeyFile, cGroupName, cKeyName, &erreur);
if (erreur != NULL)
{
if (bFlushConfFileNeeded != NULL)
cd_warning (erreur->message);
g_error_free (erreur);
erreur = NULL;
gchar* cGroupNameUpperCase = g_ascii_strup (cGroupName, -1);
bValue = g_key_file_get_boolean (pKeyFile, cGroupNameUpperCase, cKeyName, &erreur);
g_free (cGroupNameUpperCase);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
bValue = g_key_file_get_boolean (pKeyFile, "Cairo Dock", cKeyName, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
bValue = g_key_file_get_boolean (pKeyFile, (cDefaultGroupName != NULL ? cDefaultGroupName : cGroupName), (cDefaultKeyName != NULL ? cDefaultKeyName : cKeyName), &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
bValue = bDefaultValue;
}
else
cd_message (" (recuperee)");
}
else
cd_message (" (recuperee)");
}
g_key_file_set_boolean (pKeyFile, cGroupName, cKeyName, bValue);
if (bFlushConfFileNeeded != NULL)
*bFlushConfFileNeeded = TRUE;
}
return bValue;
}
int cairo_dock_get_integer_key_value (GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, int iDefaultValue, const gchar *cDefaultGroupName, const gchar *cDefaultKeyName)
{
GError *erreur = NULL;
int iValue = g_key_file_get_integer (pKeyFile, cGroupName, cKeyName, &erreur);
if (erreur != NULL)
{
if (bFlushConfFileNeeded != NULL)
cd_warning (erreur->message);
g_error_free (erreur);
erreur = NULL;
gchar* cGroupNameUpperCase = g_ascii_strup (cGroupName, -1);
iValue = g_key_file_get_integer (pKeyFile, cGroupNameUpperCase, cKeyName, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
iValue = g_key_file_get_integer (pKeyFile, "Cairo Dock", cKeyName, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
iValue = g_key_file_get_integer (pKeyFile, (cDefaultGroupName != NULL ? cDefaultGroupName : cGroupName), (cDefaultKeyName != NULL ? cDefaultKeyName : cKeyName), &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
iValue = iDefaultValue;
}
else
cd_message (" (recuperee)");
}
else
cd_message (" (recuperee)");
}
g_free (cGroupNameUpperCase);
g_key_file_set_integer (pKeyFile, cGroupName, cKeyName, iValue);
if (bFlushConfFileNeeded != NULL)
*bFlushConfFileNeeded = TRUE;
}
return iValue;
}
double cairo_dock_get_double_key_value (GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, double fDefaultValue, const gchar *cDefaultGroupName, const gchar *cDefaultKeyName)
{
GError *erreur = NULL;
double fValue = g_key_file_get_double (pKeyFile, cGroupName, cKeyName, &erreur);
if (erreur != NULL)
{
if (bFlushConfFileNeeded != NULL)
cd_warning (erreur->message);
g_error_free (erreur);
erreur = NULL;
gchar* cGroupNameUpperCase = g_ascii_strup (cGroupName, -1);
fValue = g_key_file_get_double (pKeyFile, cGroupNameUpperCase, cKeyName, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
fValue = g_key_file_get_double (pKeyFile, "Cairo Dock", cKeyName, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
fValue = g_key_file_get_double (pKeyFile, (cDefaultGroupName != NULL ? cDefaultGroupName : cGroupName), (cDefaultKeyName != NULL ? cDefaultKeyName : cKeyName), &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
fValue = fDefaultValue;
}
else
cd_message (" (recuperee)");
}
else
cd_message (" (recuperee)");
}
g_free (cGroupNameUpperCase);
g_key_file_set_double (pKeyFile, cGroupName, cKeyName, fValue);
if (bFlushConfFileNeeded != NULL)
*bFlushConfFileNeeded = TRUE;
}
return fValue;
}
gchar *cairo_dock_get_string_key_value (GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, const gchar *cDefaultValue, const gchar *cDefaultGroupName, const gchar *cDefaultKeyName)
{
GError *erreur = NULL;
gchar *cValue = g_key_file_get_string (pKeyFile, cGroupName, cKeyName, &erreur);
if (erreur != NULL)
{
if (bFlushConfFileNeeded != NULL)
cd_warning (erreur->message);
g_error_free (erreur);
erreur = NULL;
gchar* cGroupNameUpperCase = g_ascii_strup (cGroupName, -1);
cValue = g_key_file_get_string (pKeyFile, cGroupNameUpperCase, cKeyName, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
cValue = g_key_file_get_string (pKeyFile, "Cairo Dock", cKeyName, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
cValue = g_key_file_get_string (pKeyFile, (cDefaultGroupName != NULL ? cDefaultGroupName : cGroupName), (cDefaultKeyName != NULL ? cDefaultKeyName : cKeyName), &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
cValue = g_strdup (cDefaultValue);
}
else
cd_message (" (recuperee)");
}
else
cd_message (" (recuperee)");
}
g_free (cGroupNameUpperCase);
g_key_file_set_string (pKeyFile, cGroupName, cKeyName, (cValue != NULL ? cValue : ""));
if (bFlushConfFileNeeded != NULL)
*bFlushConfFileNeeded = TRUE;
}
if (cValue != NULL && *cValue == '\0')
{
g_free (cValue);
cValue = NULL;
}
return cValue;
}
void cairo_dock_get_integer_list_key_value (GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, int *iValueBuffer, guint iNbElements, int *iDefaultValues, const gchar *cDefaultGroupName, const gchar *cDefaultKeyName)
{
GError *erreur = NULL;
gsize length = 0;
if (iDefaultValues != NULL)
memcpy (iValueBuffer, iDefaultValues, iNbElements * sizeof (int));
int *iValuesList = g_key_file_get_integer_list (pKeyFile, cGroupName, cKeyName, &length, &erreur);
if (erreur != NULL)
{
if (bFlushConfFileNeeded != NULL)
cd_warning (erreur->message);
g_error_free (erreur);
erreur = NULL;
gchar* cGroupNameUpperCase = g_ascii_strup (cGroupName, -1);
iValuesList = g_key_file_get_integer_list (pKeyFile, cGroupNameUpperCase, cKeyName, &length, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
iValuesList = g_key_file_get_integer_list (pKeyFile, "Cairo Dock", cKeyName, &length, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
iValuesList = g_key_file_get_integer_list (pKeyFile, (cDefaultGroupName != NULL ? cDefaultGroupName : cGroupName), (cDefaultKeyName != NULL ? cDefaultKeyName : cKeyName), &length, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
}
else
{
cd_message (" (recuperee)");
if (length > 0)
memcpy (iValueBuffer, iValuesList, MIN (iNbElements, length) * sizeof (int));
}
}
else
{
cd_message (" (recuperee)");
if (length > 0)
memcpy (iValueBuffer, iValuesList, MIN (iNbElements, length) * sizeof (int));
}
}
else
{
if (length > 0)
memcpy (iValueBuffer, iValuesList, MIN (iNbElements, length) * sizeof (int));
}
g_free (cGroupNameUpperCase);
if (iDefaultValues != NULL) // on ne modifie les valeurs actuelles que si on a explicitement passe des valeurs par defaut en entree; sinon on considere que l'on va traiter le cas en aval.
g_key_file_set_integer_list (pKeyFile, cGroupName, cKeyName, iValueBuffer, iNbElements);
if (bFlushConfFileNeeded != NULL)
*bFlushConfFileNeeded = TRUE;
}
else
{
if (length > 0)
memcpy (iValueBuffer, iValuesList, MIN (iNbElements, length) * sizeof (int));
}
g_free (iValuesList);
}
void cairo_dock_get_double_list_key_value (GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, double *fValueBuffer, guint iNbElements, double *fDefaultValues, const gchar *cDefaultGroupName, const gchar *cDefaultKeyName)
{
GError *erreur = NULL;
gsize length = 0;
if (fDefaultValues != NULL)
memcpy (fValueBuffer, fDefaultValues, iNbElements * sizeof (double));
double *fValuesList = g_key_file_get_double_list (pKeyFile, cGroupName, cKeyName, &length, &erreur);
if (erreur != NULL)
{
if (bFlushConfFileNeeded != NULL)
cd_warning (erreur->message);
g_error_free (erreur);
erreur = NULL;
gchar* cGroupNameUpperCase = g_ascii_strup (cGroupName, -1);
fValuesList = g_key_file_get_double_list (pKeyFile, cGroupNameUpperCase, cKeyName, &length, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
fValuesList = g_key_file_get_double_list (pKeyFile, "Cairo Dock", cKeyName, &length, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
fValuesList = g_key_file_get_double_list (pKeyFile, (cDefaultGroupName != NULL ? cDefaultGroupName : cGroupName), (cDefaultKeyName != NULL ? cDefaultKeyName : cKeyName), &length, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
}
else
{
cd_message (" (recuperee)");
if (length > 0)
memcpy (fValueBuffer, fValuesList, MIN (iNbElements, length) * sizeof (double));
}
}
else
{
cd_message (" (recuperee)");
if (length > 0)
memcpy (fValueBuffer, fValuesList, MIN (iNbElements, length) * sizeof (double));
}
}
else
{
if (length > 0)
memcpy (fValueBuffer, fValuesList, MIN (iNbElements, length) * sizeof (double));
}
g_free (cGroupNameUpperCase);
g_key_file_set_double_list (pKeyFile, cGroupName, cKeyName, fValueBuffer, iNbElements);
if (bFlushConfFileNeeded != NULL)
*bFlushConfFileNeeded = TRUE;
}
else
{
if (length > 0)
memcpy (fValueBuffer, fValuesList, MIN (iNbElements, length) * sizeof (double));
}
g_free (fValuesList);
}
gchar **cairo_dock_get_string_list_key_value (GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, gsize *length, const gchar *cDefaultValues, const gchar *cDefaultGroupName, const gchar *cDefaultKeyName)
{
GError *erreur = NULL;
*length = 0;
gchar **cValuesList = g_key_file_get_string_list (pKeyFile, cGroupName, cKeyName, length, &erreur);
if (erreur != NULL)
{
if (bFlushConfFileNeeded != NULL)
cd_warning (erreur->message);
g_error_free (erreur);
erreur = NULL;
gchar* cGroupNameUpperCase = g_ascii_strup (cGroupName, -1);
cValuesList = g_key_file_get_string_list (pKeyFile, cGroupNameUpperCase, cKeyName, length, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
erreur = NULL;
cValuesList = g_key_file_get_string_list (pKeyFile, (cDefaultGroupName != NULL ? cDefaultGroupName : cGroupName), (cDefaultKeyName != NULL ? cDefaultKeyName : cKeyName), length, &erreur);
if (erreur != NULL)
{
g_error_free (erreur);
cValuesList = g_strsplit (cDefaultValues, ";", -1); // "" -> NULL.
int i = 0;
if (cValuesList != NULL)
{
while (cValuesList[i] != NULL)
i ++;
}
*length = i;
}
}
g_free (cGroupNameUpperCase);
if (*length > 0)
g_key_file_set_string_list (pKeyFile, cGroupName, cKeyName, (const gchar **)cValuesList, *length);
else
g_key_file_set_string (pKeyFile, cGroupName, cKeyName, "");
if (bFlushConfFileNeeded != NULL)
*bFlushConfFileNeeded = TRUE;
}
if (cValuesList != NULL && (cValuesList[0] == NULL || (*(cValuesList[0]) == '\0' && *length == 1)))
{
g_strfreev (cValuesList);
cValuesList = NULL;
*length = 0;
}
return cValuesList;
}
gchar *cairo_dock_get_file_path_key_value (GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, const gchar *cDefaultGroupName, const gchar *cDefaultKeyName, const gchar *cDefaultDir, const gchar *cDefaultFileName)
{
gchar *cFileName = cairo_dock_get_string_key_value (pKeyFile, cGroupName, cKeyName, bFlushConfFileNeeded, NULL, cDefaultGroupName, cDefaultKeyName);
gchar *cFilePath = NULL;
if (cFileName != NULL)
cFilePath = cairo_dock_search_image_s_path (cFileName);
if (cFilePath == NULL && cDefaultFileName != NULL && cDefaultDir != NULL) // pas d'image specifiee, ou image introuvable => on prend l'image par defaut fournie.
cFilePath = g_strdup_printf ("%s/%s", cDefaultDir, cDefaultFileName);
g_free (cFileName);
return cFilePath;
}
void cairo_dock_get_size_key_value (GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, gint iDefaultSize, const gchar *cDefaultGroupName, const gchar *cDefaultKeyName, int *iWidth, int *iHeight)
{
int iSize[2];
int iDefaultValues[2] = {iDefaultSize, iDefaultSize};
cairo_dock_get_integer_list_key_value (pKeyFile, cGroupName, cKeyName, bFlushConfFileNeeded, iSize, 2, iDefaultValues, cDefaultGroupName, cDefaultKeyName);
*iWidth = iSize[0];
*iHeight = iSize[1];
}
void cairo_dock_load_current_theme (void)
{
cd_message ("%s ()", __func__);
s_bLoading = TRUE;
//\___________________ Free everything.
gldi_free_all (); // do nothing if there is nothing to unload.
//\___________________ Get all managers config.
gldi_managers_get_config (g_cConfFile, GLDI_VERSION); /// en fait, CAIRO_DOCK_VERSION ...
//\___________________ Create the primary container (needed to have a cairo/opengl context).
CairoDock *pMainDock = gldi_dock_new (CAIRO_DOCK_MAIN_DOCK_NAME);
//\___________________ Load all managers data.
gldi_managers_load ();
gldi_modules_activate_from_list (NULL); // load auto-loaded modules before loading anything (views, etc)
//\___________________ Now load the user icons (launchers, etc).
gldi_user_icons_new_from_directory (g_cCurrentLaunchersPath);
cairo_dock_hide_show_launchers_on_other_desktops ();
//\___________________ Load the applets.
gldi_modules_activate_from_list (myModulesParam.cActiveModuleList);
//\___________________ Start the applications manager (will load the icons if the option is enabled).
cairo_dock_start_applications_manager (pMainDock);
s_bLoading = FALSE;
}
gboolean cairo_dock_is_loading (void)
{
return s_bLoading;
}
void cairo_dock_decrypt_string( const gchar *cEncryptedString, gchar **cDecryptedString )
{
g_return_if_fail (cDecryptedString != NULL);
if( !cEncryptedString || *cEncryptedString == '\0' )
{
*cDecryptedString = g_strdup( "" );
return;
}
#ifdef HAVE_LIBCRYPT
guchar *input = (guchar *)g_strdup (cEncryptedString);
guchar *shifted_input = input;
guchar **output = (guchar **)cDecryptedString;
guchar *current_output = NULL;
*output = g_malloc( (strlen((char *)input)+1)/3+1 );
current_output = *output;
guchar *last_char_in_input = input + strlen((char *)input);
// g_print( "Password (before decrypt): %s\n", input );
for( ; shifted_input < last_char_in_input; shifted_input += 16+8, current_output += 8 )
{
guint block[8];
guchar txt[64];
gint i = 0, j = 0;
memset( txt, 0, 64 );
shifted_input[16+8-1] = 0; // cut the string
sscanf( (char *)shifted_input, "%X-%X-%X-%X-%X-%X-%X-%X",
&block[0], &block[1], &block[2], &block[3], &block[4], &block[5], &block[6], &block[7] );
// process the eight first characters of "input"
for( i = 0; i < 8 ; i++ )
for ( j = 0; j < 8; j++ )
txt[i*8+j] = block[i] >> j & 1;
setkey( DES_crypt_key );
encrypt( (gchar *)txt, 1 ); // decrypt
for ( i = 0; i < 8; i++ )
{
current_output[i] = 0;
for ( j = 0; j < 8; j++ )
{
current_output[i] |= txt[i*8+j] << j;
}
}
}
*current_output = 0;
// g_print( "Password (after decrypt): %s\n", *output );
g_free( input );
#else
*cDecryptedString = g_strdup( cEncryptedString );
#endif
}
void cairo_dock_encrypt_string( const gchar *cDecryptedString, gchar **cEncryptedString )
{
g_return_if_fail (cEncryptedString != NULL);
if( !cDecryptedString || *cDecryptedString == '\0' )
{
*cEncryptedString = g_strdup( "" );
return;
}
#ifdef HAVE_LIBCRYPT
const guchar *input = (guchar *)cDecryptedString;
guchar **output = (guchar **)cEncryptedString;
guchar *current_output = NULL;
// for each block of 8 characters, we need 24 bytes.
guint nbBlocks = strlen((char *)input)/8+1;
*output = g_malloc( nbBlocks*24+1 );
current_output = *output;
const guchar *last_char_in_input = input + strlen((char *)input);
// g_print( "Password (before encrypt): %s\n", input );
for( ; input < last_char_in_input; input += 8, current_output += 16+8 )
{
guchar txt[64];
guint i = 0, j = 0;
guchar current_letter = 0;
memset( txt, 0, 64 );
// process the eight first characters of "input"
for( i = 0; i < strlen((char *)input) && i < 8 ; i++ )
for ( j = 0; j < 8; j++ )
txt[i*8+j] = input[i] >> j & 1;
setkey( DES_crypt_key );
encrypt( (char *)txt, 0 ); // encrypt
for ( i = 0; i < 8; i++ )
{
current_letter = 0;
for ( j = 0; j < 8; j++ )
{
current_letter |= txt[i*8+j] << j;
}
snprintf( (char *)current_output + i*3, 4, "%02X-", current_letter );
}
}
*(current_output-1) = 0;
// g_print( "Password (after encrypt): %s\n", *output );
#else
*cEncryptedString = g_strdup( cDecryptedString );
#endif
}
xmlDocPtr cairo_dock_open_xml_file (const gchar *cDataFilePath, const gchar *cRootNodeName, xmlNodePtr *root_node, GError **erreur)
{
if (cairo_dock_get_file_size (cDataFilePath) == 0)
{
g_set_error (erreur, 1, 1, "file '%s' doesn't exist or is empty", cDataFilePath);
*root_node = NULL;
return NULL;
}
xmlInitParser ();
xmlDocPtr doc = xmlParseFile (cDataFilePath);
if (doc == NULL)
{
g_set_error (erreur, 1, 1, "file '%s' is incorrect", cDataFilePath);
*root_node = NULL;
return NULL;
}
xmlNodePtr noeud = xmlDocGetRootElement (doc);
if (noeud == NULL || xmlStrcmp (noeud->name, (const xmlChar *) cRootNodeName) != 0)
{
g_set_error (erreur, 1, 2, "xml file '%s' is not well formed", cDataFilePath);
*root_node = NULL;
return doc;
}
*root_node = noeud;
return doc;
}
void cairo_dock_close_xml_file (xmlDocPtr doc)
{
if (doc)
xmlFreeDoc (doc); // ne pas utiliser xmlCleanupParser(), cela peut affecter les autres threads utilisant libxml !
}
gchar *cairo_dock_get_default_system_font (void)
{
static gchar *s_cFontName = NULL;
if (s_cFontName == NULL)
{
if (g_iDesktopEnv == CAIRO_DOCK_GNOME)
s_cFontName = cairo_dock_launch_command_sync ("gconftool-2 -g /desktop/gnome/interface/font_name"); /// ou document_font_name ?...
else
s_cFontName = g_strdup ("Sans 10");
}
return g_strdup (s_cFontName);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-manager.c 000664 001750 001750 00000016316 12223247550 022362 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include "gldi-config.h"
#include "cairo-dock-log.h"
#include "cairo-dock-module-manager.h" // GldiVisitCard (for gldi_extend_manager)
#include "cairo-dock-keyfile-utilities.h"
#define __MANAGER_DEF__
#include "cairo-dock-manager.h"
// public (manager, config, data)
GldiObjectManager myManagerObjectMgr;
// dependancies
extern GldiContainer *g_pPrimaryContainer;
extern gchar *g_cConfFile;
// private
static GList *s_pManagers = NULL;
static void _gldi_init_manager (GldiManager *pManager)
{
// be sure to init once only
if (pManager->bInitIsDone)
return;
pManager->bInitIsDone = TRUE;
// if the manager depends on another, init this one first.
if (pManager->pDependence != NULL)
_gldi_init_manager (pManager->pDependence);
// init the manager
if (pManager->init)
pManager->init ();
}
static inline void _gldi_load_manager (GldiManager *pManager)
{
if (pManager->load)
pManager->load ();
}
static inline void _gldi_unload_manager (GldiManager *pManager)
{
if (pManager->unload)
pManager->unload ();
if (pManager->iSizeOfConfig != 0 && pManager->pConfig != NULL && pManager->reset_config)
{
pManager->reset_config (pManager->pConfig);
memset (pManager->pConfig, 0, pManager->iSizeOfConfig);
}
}
static void _gldi_manager_reload_from_keyfile (GldiManager *pManager, GKeyFile *pKeyFile)
{
gpointer *pPrevConfig = NULL;
// get new config
if (pManager->iSizeOfConfig != 0 && pManager->pConfig != NULL && pManager->get_config != NULL)
{
pPrevConfig = g_memdup (pManager->pConfig, pManager->iSizeOfConfig);
memset (pManager->pConfig, 0, pManager->iSizeOfConfig);
pManager->get_config (pKeyFile, pManager->pConfig);
}
// reload
if (pManager->reload && g_pPrimaryContainer != NULL) // in maintenance mode, no need to reload.
pManager->reload (pPrevConfig, pManager->pConfig);
// free old config
if (pManager->reset_config)
pManager->reset_config (pPrevConfig);
g_free (pPrevConfig);
}
/*void gldi_manager_reload (GldiManager *pManager, const gchar *cConfFilePath) // expose pour Dbus.
{
g_return_if_fail (pManager != NULL);
GKeyFile *pKeyFile = cairo_dock_open_key_file (cConfFilePath);
if (pKeyFile == NULL)
return;
gldi_manager_reload_from_keyfile (pManager, pKeyFile);
g_key_file_free (pKeyFile);
}*/
static gboolean gldi_manager_get_config (GldiManager *pManager, GKeyFile *pKeyFile)
{
if (! pManager->get_config || ! pManager->pConfig || pManager->iSizeOfConfig == 0)
return FALSE;
if (pManager->reset_config)
{
pManager->reset_config (pManager->pConfig);
}
memset (pManager->pConfig, 0, pManager->iSizeOfConfig);
return pManager->get_config (pKeyFile, pManager->pConfig);
}
void gldi_manager_extend (GldiVisitCard *pVisitCard, const gchar *cManagerName)
{
GldiManager *pManager = gldi_manager_get (cManagerName);
g_return_if_fail (pManager != NULL && pVisitCard->cInternalModule == NULL);
pManager->pExternalModules = g_list_prepend (pManager->pExternalModules, (gpointer)pVisitCard->cModuleName);
pVisitCard->cInternalModule = cManagerName;
}
///////////////
/// MANAGER ///
///////////////
GldiManager *gldi_manager_get (const gchar *cName)
{
GldiManager *pManager = NULL;
GList *m;
for (m = s_pManagers; m != NULL; m = m->next)
{
pManager = m->data;
if (strcmp (cName, pManager->cModuleName) == 0)
return pManager;
}
return NULL;
}
void gldi_managers_init (void)
{
cd_message ("%s()", __func__);
GldiManager *pManager;
GList *m;
for (m = s_pManagers; m != NULL; m = m->next)
{
pManager = m->data;
_gldi_init_manager (pManager);
}
}
gboolean gldi_managers_get_config_from_key_file (GKeyFile *pKeyFile)
{
gboolean bFlushConfFileNeeded = FALSE;
GldiManager *pManager;
GList *m;
for (m = s_pManagers; m != NULL; m = m->next)
{
pManager = m->data;
bFlushConfFileNeeded |= gldi_manager_get_config (pManager, pKeyFile);
}
return bFlushConfFileNeeded;
}
void gldi_managers_get_config (const gchar *cConfFilePath, const gchar *cVersion)
{
//\___________________ On ouvre le fichier de conf.
GKeyFile *pKeyFile = cairo_dock_open_key_file (cConfFilePath);
g_return_if_fail (pKeyFile != NULL);
//\___________________ On recupere la conf de tous les managers.
gboolean bFlushConfFileNeeded = gldi_managers_get_config_from_key_file (pKeyFile);
//\___________________ On met a jour le fichier sur le disque si necessaire.
if (! bFlushConfFileNeeded && cVersion != NULL)
bFlushConfFileNeeded = cairo_dock_conf_file_needs_update (pKeyFile, cVersion);
if (bFlushConfFileNeeded)
{
cairo_dock_upgrade_conf_file (cConfFilePath, pKeyFile, GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_CONF_FILE);
}
g_key_file_free (pKeyFile);
}
void gldi_managers_load (void)
{
cd_message ("%s()", __func__);
GldiManager *pManager;
GList *m;
for (m = s_pManagers; m != NULL; m = m->next)
{
pManager = m->data;
_gldi_load_manager (pManager);
}
}
void gldi_managers_unload (void)
{
cd_message ("%s()", __func__);
GldiManager *pManager;
GList *m;
for (m = s_pManagers; m != NULL; m = m->next)
{
pManager = m->data;
_gldi_unload_manager (pManager);
}
}
void gldi_managers_foreach (GFunc callback, gpointer data)
{
g_list_foreach (s_pManagers, callback, data);
}
//////////////
/// OBJECT ///
//////////////
static void init_object (GldiObject *obj, G_GNUC_UNUSED gpointer attr)
{
GldiManager *pManager = (GldiManager*)obj;
s_pManagers = g_list_prepend (s_pManagers, pManager); // we don't init the manager, since we want to do that after all maangers have been created
}
static GKeyFile* reload_object (GldiObject *obj, gboolean bReloadConf, GKeyFile *pKeyFile)
{
GldiManager *pManager = (GldiManager*)obj;
cd_message ("reload %s (%d)", pManager->cModuleName, bReloadConf);
if (bReloadConf && !pKeyFile)
{
pKeyFile = cairo_dock_open_key_file (g_cConfFile);
g_return_val_if_fail (pKeyFile != NULL, NULL);
}
_gldi_manager_reload_from_keyfile (pManager, pKeyFile);
return pKeyFile;
}
static gboolean delete_object (G_GNUC_UNUSED GldiObject *obj)
{
return FALSE; // don't allow to delete a manager
}
void gldi_register_managers_manager (void)
{
// Object Manager
memset (&myManagerObjectMgr, 0, sizeof (GldiObjectManager));
myManagerObjectMgr.cName = "Manager";
myManagerObjectMgr.iObjectSize = sizeof (GldiManager);
// interface
myManagerObjectMgr.init_object = init_object;
myManagerObjectMgr.reload_object = reload_object;
myManagerObjectMgr.delete_object = delete_object;
// signals
gldi_object_install_notifications (GLDI_OBJECT (&myManagerObjectMgr), NB_NOTIFICATIONS_MANAGER);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-icon-factory.c 000664 001750 001750 00000032330 12223247550 023337 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include "gldi-config.h"
#include "cairo-dock-draw.h" // cairo_dock_erase_cairo_context
#include "cairo-dock-draw-opengl.h"
#include "cairo-dock-surface-factory.h"
#include "cairo-dock-module-instance-manager.h" // GldiModuleInstance
#include "cairo-dock-log.h"
#include "cairo-dock-utils.h" // cairo_dock_cut_string
#include "cairo-dock-applications-manager.h" // myTaskbarParam.iAppliMaxNameLength
#include "cairo-dock-separator-manager.h" // GLDI_OBJECT_IS_SEPARATOR_ICON
#include "cairo-dock-dock-facility.h" // cairo_dock_update_dock_size
#include "cairo-dock-backends-manager.h" // cairo_dock_get_icon_container_renderer
#include "cairo-dock-icon-facility.h"
#include "cairo-dock-data-renderer.h"
#include "cairo-dock-overlay.h"
#include "cairo-dock-icon-factory.h"
extern CairoDockImageBuffer g_pIconBackgroundBuffer;
//extern gboolean g_bUseOpenGL;
const gchar *s_cRendererNames[4] = {NULL, "Emblem", "Stack", "Box"}; // c'est juste pour realiser la transition entre le chiffre en conf, et un nom (limitation du panneau de conf). On garde le numero pour savoir rapidement sur laquelle on set.
Icon *gldi_icon_new (void)
{
Icon *_icon = (Icon*)gldi_object_new (&myIconObjectMgr, NULL);
return _icon;
}
Icon * cairo_dock_create_dummy_launcher (gchar *cName, gchar *cFileName, gchar *cCommand, gchar *cQuickInfo, double fOrder)
{
//\____________ On cree l'icone.
Icon *pIcon = gldi_icon_new ();
pIcon->iGroup = CAIRO_DOCK_LAUNCHER;
pIcon->cName = cName;
pIcon->cFileName = cFileName;
pIcon->cQuickInfo = cQuickInfo;
pIcon->fOrder = fOrder;
pIcon->fScale = 1.;
pIcon->fAlpha = 1.;
pIcon->fWidthFactor = 1.;
pIcon->fHeightFactor = 1.;
pIcon->cCommand = cCommand;
return pIcon;
}
//////////////
/// LOADER ///
//////////////
gboolean cairo_dock_apply_icon_background_opengl (Icon *icon)
{
if (cairo_dock_begin_draw_icon (icon, 1)) // 1 => don't clear current image
{
_cairo_dock_enable_texture ();
glBlendFunc (GL_ONE_MINUS_DST_ALPHA, GL_ONE); // dest_over = src * (1 - dst.a) + dst
_cairo_dock_set_alpha (1.);
_cairo_dock_apply_texture_at_size (g_pIconBackgroundBuffer.iTexture,
icon->image.iWidth,
icon->image.iHeight);
cairo_dock_end_draw_icon (icon);
return TRUE;
}
return FALSE;
}
void cairo_dock_load_icon_image (Icon *icon, G_GNUC_UNUSED GldiContainer *pContainer)
{
if (icon->pContainer == NULL)
{
cd_warning ("/!\\ Icon %s is not inside a container !!!", icon->cName); // it's ok if this happens, but it should be rare, and I'd like to know when, so be noisy.
return;
}
GldiModuleInstance *pInstance = icon->pModuleInstance; // this is the only function where we destroy/create the icon's surface, so we must handle the cairo-context here.
if (pInstance && pInstance->pDrawContext != NULL)
{
cairo_destroy (pInstance->pDrawContext);
pInstance->pDrawContext = NULL;
}
//g_print ("%s (%s, %dx%d)\n", __func__, icon->cName, (int)icon->fWidth, (int)icon->fHeight);
// the renderer of the container must have set the size beforehand, when the icon has been inserted into the container.
if (cairo_dock_icon_get_allocated_width (icon) <= 0 || cairo_dock_icon_get_allocated_height (icon) <= 0) // we don't want a surface/texture.
{
cairo_dock_unload_image_buffer (&icon->image);
return;
}
g_return_if_fail (icon->fWidth > 0); // should never happen; if it does, it's an error, so be noisy.
//\______________ keep the current buffer on the icon so that the 'load' can use it (for instance, applis may draw emblems).
cairo_surface_t *pPrevSurface = icon->image.pSurface;
GLuint iPrevTexture = icon->image.iTexture;
//\______________ load the image buffer (surface + texture).
if (icon->iface.load_image)
icon->iface.load_image (icon);
//\______________ if nothing has changed or no image was loaded, set a default image.
if ((icon->image.pSurface == pPrevSurface || icon->image.pSurface == NULL)
&& (icon->image.iTexture == iPrevTexture || icon->image.iTexture == 0))
{
gchar *cIconPath = cairo_dock_search_image_s_path (CAIRO_DOCK_DEFAULT_ICON_NAME);
if (cIconPath == NULL) // fichier non trouve.
{
cIconPath = g_strdup (GLDI_SHARE_DATA_DIR"/icons/"CAIRO_DOCK_DEFAULT_ICON_NAME);
}
int w = cairo_dock_icon_get_allocated_width (icon);
int h = cairo_dock_icon_get_allocated_height (icon);
cairo_surface_t *pSurface = cairo_dock_create_surface_from_image_simple (cIconPath,
w,
h);
cairo_dock_load_image_buffer_from_surface (&icon->image, pSurface, w, h);
g_free (cIconPath);
}
//\_____________ set the background if needed.
icon->bNeedApplyBackground = FALSE;
if (g_pIconBackgroundBuffer.pSurface != NULL && ! GLDI_OBJECT_IS_SEPARATOR_ICON (icon))
{
if (icon->image.iTexture != 0 && g_pIconBackgroundBuffer.iTexture != 0)
{
if (! cairo_dock_apply_icon_background_opengl (icon)) // couldn't draw on the texture
{
icon->bDamaged = FALSE; // it's not a big deal, since we can draw under the existing image easily; so we don't need to damage the icon (it's expensive especially if it's an applet).
icon->bNeedApplyBackground = TRUE; // just postpone it until drawing is possible.
}
}
else if (icon->image.pSurface != NULL)
{
cairo_t *pCairoIconBGContext = cairo_create (icon->image.pSurface);
cairo_set_operator (pCairoIconBGContext, CAIRO_OPERATOR_DEST_OVER);
cairo_dock_apply_image_buffer_surface_at_size (&g_pIconBackgroundBuffer, pCairoIconBGContext,
icon->image.iWidth, icon->image.iHeight,
0, 0, 1);
cairo_destroy (pCairoIconBGContext);
}
}
//\______________ free the previous buffers.
if (pPrevSurface != NULL)
cairo_surface_destroy (pPrevSurface);
if (iPrevTexture != 0)
_cairo_dock_delete_texture (iPrevTexture);
if (pInstance && icon->image.pSurface != NULL)
{
pInstance->pDrawContext = cairo_create (icon->image.pSurface);
if (!pInstance->pDrawContext || cairo_status (pInstance->pDrawContext) != CAIRO_STATUS_SUCCESS)
{
cd_warning ("couldn't initialize drawing context, applet won't be able to draw itself !");
pInstance->pDrawContext = NULL;
}
}
}
void cairo_dock_load_icon_text (Icon *icon)
{
cairo_dock_unload_image_buffer (&icon->label);
if (icon->cName == NULL || (myIconsParam.iconTextDescription.iSize == 0))
return ;
gchar *cTruncatedName = NULL;
if (CAIRO_DOCK_IS_APPLI (icon) && myTaskbarParam.iAppliMaxNameLength > 0)
{
cTruncatedName = cairo_dock_cut_string (icon->cName, myTaskbarParam.iAppliMaxNameLength);
}
int iWidth, iHeight;
cairo_surface_t *pSurface = cairo_dock_create_surface_from_text ((cTruncatedName != NULL ? cTruncatedName : icon->cName),
&myIconsParam.iconTextDescription,
&iWidth,
&iHeight);
cairo_dock_load_image_buffer_from_surface (&icon->label, pSurface, iWidth, iHeight);
g_free (cTruncatedName);
}
void cairo_dock_load_icon_quickinfo (Icon *icon)
{
if (icon->cQuickInfo == NULL) // no more quick-info -> remove any previous one
{
cairo_dock_remove_overlay_at_position (icon, CAIRO_OVERLAY_BOTTOM, (gpointer)"quick-info");
}
else // add an overlay at the bottom with the text surface; any previous "quick-info" overlay will be removed.
{
int iWidth, iHeight;
cairo_dock_get_icon_extent (icon, &iWidth, &iHeight);
double fMaxScale = cairo_dock_get_icon_max_scale (icon);
if (iHeight / (myIconsParam.quickInfoTextDescription.iSize * fMaxScale) > 5) // if the icon is very height (the text occupies less than 20% of the icon)
fMaxScale = MIN ((double)iHeight / (myIconsParam.quickInfoTextDescription.iSize * 5), MAX (1., 16./myIconsParam.quickInfoTextDescription.iSize) * fMaxScale); // let's make it use 20% of the icon's height, limited to 16px
int w, h;
cairo_surface_t *pSurface = cairo_dock_create_surface_from_text_full (icon->cQuickInfo,
&myIconsParam.quickInfoTextDescription,
fMaxScale,
iWidth, // limit the text to the width of the icon
&w, &h);
CairoOverlay *pOverlay = cairo_dock_add_overlay_from_surface (icon, pSurface, w, h, CAIRO_OVERLAY_BOTTOM, (gpointer)"quick-info"); // the constant string "quick-info" is used as a unique identifier for all quick-infos; the surface is taken by the overlay.
if (pOverlay)
cairo_dock_set_overlay_scale (pOverlay, 0);
}
}
void cairo_dock_load_icon_buffers (Icon *pIcon, GldiContainer *pContainer)
{
gboolean bLoadText = TRUE;
if (pIcon->iSidLoadImage != 0) // if a load was sheduled, cancel it and do it now (we need to load the applets' buffer before initializing the module).
{
//g_print (" load %s immediately\n", pIcon->cName);
g_source_remove (pIcon->iSidLoadImage);
pIcon->iSidLoadImage = 0;
bLoadText = FALSE; // has been done in cairo_dock_trigger_load_icon_buffers(), the only function to schedule the image loading.
}
if (cairo_dock_icon_get_allocated_width (pIcon) > 0)
{
cairo_dock_load_icon_image (pIcon, pContainer);
if (bLoadText)
cairo_dock_load_icon_text (pIcon);
cairo_dock_load_icon_quickinfo (pIcon);
}
}
static gboolean _load_icon_buffer_idle (Icon *pIcon)
{
//g_print ("%s (%s; %dx%d; %.2fx%.2f; %x)\n", __func__, pIcon->cName, pIcon->iAllocatedWidth, pIcon->iAllocatedHeight, pIcon->fWidth, pIcon->fHeight, pIcon->pContainer);
pIcon->iSidLoadImage = 0;
GldiContainer *pContainer = pIcon->pContainer;
if (pContainer)
{
cairo_dock_load_icon_image (pIcon, pContainer);
if (cairo_dock_get_icon_data_renderer (pIcon) != NULL)
cairo_dock_refresh_data_renderer (pIcon, pContainer);
cairo_dock_load_icon_quickinfo (pIcon);
cairo_dock_redraw_icon (pIcon);
//g_print ("icon-factory: do 1 main loop iteration\n");
//gtk_main_iteration_do (FALSE); /// "unforseen consequences" : if _redraw_subdock_content_idle is planned just after, the container-icon stays blank in opengl only. couldn't figure why exactly :-/
}
return FALSE;
}
void cairo_dock_trigger_load_icon_buffers (Icon *pIcon)
{
if (pIcon->iSidLoadImage == 0)
{
cairo_dock_load_icon_text (pIcon); // la vue peut avoir besoin de connaitre la taille du texte.
pIcon->iSidLoadImage = g_idle_add ((GSourceFunc)_load_icon_buffer_idle, pIcon);
}
}
///////////////////////
/// CONTAINER ICONS ///
///////////////////////
void cairo_dock_draw_subdock_content_on_icon (Icon *pIcon, CairoDock *pDock)
{
g_return_if_fail (pIcon != NULL && pIcon->pSubDock != NULL && (pIcon->image.pSurface != NULL || pIcon->image.iTexture != 0));
CairoIconContainerRenderer *pRenderer = cairo_dock_get_icon_container_renderer (pIcon->cClass != NULL ? "Stack" : s_cRendererNames[pIcon->iSubdockViewType]);
if (pRenderer == NULL)
return;
cd_debug ("%s (%s)", __func__, pIcon->cName);
int w, h;
cairo_dock_get_icon_extent (pIcon, &w, &h);
if (pIcon->image.iTexture != 0 && pRenderer->render_opengl) // dessin opengl
{
//\______________ On efface le dessin existant.
if (! cairo_dock_begin_draw_icon (pIcon, 0)) // 0 <=> erase the current texture.
return ;
_cairo_dock_set_blend_alpha ();
_cairo_dock_set_alpha (1.);
_cairo_dock_enable_texture ();
//\______________ On dessine les 3 ou 4 premieres icones du sous-dock.
pRenderer->render_opengl (pIcon, CAIRO_CONTAINER (pDock), w, h);
//\______________ On finit le dessin.
_cairo_dock_disable_texture ();
cairo_dock_end_draw_icon (pIcon);
}
else if (pIcon->image.pSurface != NULL && pRenderer->render != NULL) // dessin cairo
{
//\______________ On efface le dessin existant.
cairo_t *pCairoContext = cairo_dock_begin_draw_icon_cairo (pIcon, 0, NULL); // 0 <=> erase
g_return_if_fail (pCairoContext != NULL);
//\______________ On dessine les 3 ou 4 premieres icones du sous-dock.
pRenderer->render (pIcon, CAIRO_CONTAINER (pDock), w, h, pCairoContext);
//\______________ On finit le dessin.
cairo_dock_end_draw_icon_cairo (pIcon);
cairo_destroy (pCairoContext);
}
}
void gldi_icon_detach (Icon *pIcon)
{
GldiContainer *pContainer = cairo_dock_get_icon_container (pIcon);
if (! pContainer) // the icon is not in a container -> nothing to do
return;
pContainer->iface.detach_icon (pContainer, pIcon);
cairo_dock_set_icon_container (pIcon, NULL);
}
void gldi_icon_insert_in_container (Icon *pIcon, GldiContainer *pContainer, gboolean bAnimateIcon)
{
g_return_if_fail (pContainer->iface.insert_icon != NULL); // the container must handle icons
if (cairo_dock_get_icon_container (pIcon) != NULL) // the icon must not be in a container yet
{
cd_warning ("This icon (%s) is already inside a container !", pIcon->cName);
return;
}
cairo_dock_set_icon_container (pIcon, pContainer); // set the container already, the icon might need it to set its size.
pContainer->iface.insert_icon (pContainer, pIcon, bAnimateIcon);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-opengl-font.c 000664 001750 001750 00000027554 12223247550 023206 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include "cairo-dock-surface-factory.h" // cairo_dock_create_blank_surface
#include "cairo-dock-draw.h" // cairo_dock_create_drawing_context_generic
#include "cairo-dock-log.h"
#include "cairo-dock-draw-opengl.h"
#include "cairo-dock-opengl-font.h"
#include "texture-gradation.h"
#define RADIAN (G_PI / 180.0) // Conversion Radian/Degres
#define DELTA_ROUND_DEGREE 3
extern GldiContainer *g_pPrimaryContainer;
extern CairoDockGLConfig g_openglConfig;
GLuint cairo_dock_create_texture_from_text_simple (const gchar *cText, const gchar *cFontDescription, cairo_t* pSourceContext, int *iWidth, int *iHeight)
{
g_return_val_if_fail (cText != NULL && cFontDescription != NULL, 0);
//\_________________ On ecrit le texte dans un calque Pango.
PangoLayout *pLayout = pango_cairo_create_layout (pSourceContext);
PangoFontDescription *fd = pango_font_description_from_string (cFontDescription);
pango_layout_set_font_description (pLayout, fd);
pango_font_description_free (fd);
pango_layout_set_text (pLayout, cText, -1);
//\_________________ On cree une surface aux dimensions du texte.
PangoRectangle log;
pango_layout_get_pixel_extents (pLayout, NULL, &log);
cairo_surface_t* pNewSurface = cairo_dock_create_blank_surface (
log.width,
log.height);
*iWidth = log.width;
*iHeight = log.height;
//\_________________ On dessine le texte.
cairo_t* pCairoContext = cairo_create (pNewSurface);
cairo_translate (pCairoContext, -log.x, -log.y);
cairo_set_source_rgb (pCairoContext, 1., 1., 1.);
cairo_move_to (pCairoContext, 0, 0);
pango_cairo_show_layout (pCairoContext, pLayout);
cairo_destroy (pCairoContext);
g_object_unref (pLayout);
//\_________________ On cree la texture.
GLuint iTexture = cairo_dock_create_texture_from_surface (pNewSurface);
cairo_surface_destroy (pNewSurface);
return iTexture;
}
// taken from gdkgl
// pango_x_ functions are deprecated, but as long as they work, we shouldn't care too much.
// use XLoadQueryFont() if needed...
/*static PangoFont *
gldi_font_use_pango_font_common (PangoFontMap *font_map,
const PangoFontDescription *font_desc,
int first,
int count,
int list_base)
{
PangoFont *font = NULL;
const gchar *charset = NULL;
PangoXSubfont subfont_id;
gchar *xlfd = NULL; // X Logical Font Description
PangoXFontCache *font_cache;
XFontStruct *fs;
font = pango_font_map_load_font (font_map, NULL, font_desc);
if (font == NULL)
{
g_warning ("cannot load PangoFont");
goto FAIL;
}
charset = "iso8859-1";
if (!pango_x_find_first_subfont (font, (gchar **)&charset, 1, &subfont_id))
{
g_warning ("cannot find PangoXSubfont");
font = NULL;
goto FAIL;
}
xlfd = pango_x_font_subfont_xlfd (font, subfont_id);
if (xlfd == NULL)
{
g_warning ("cannot get XLFD");
font = NULL;
goto FAIL;
}
font_cache = pango_x_font_map_get_font_cache (font_map);
fs = pango_x_font_cache_load (font_cache, xlfd);
glXUseXFont (fs->fid, first, count, list_base);
pango_x_font_cache_unload (font_cache, fs);
FAIL:
if (xlfd != NULL)
g_free (xlfd);
return font;
}
static PangoFont *
gldi_font_use_pango_font (const PangoFontDescription *font_desc,
int first,
int count,
int list_base)
{
PangoFontMap *font_map;
g_return_val_if_fail (font_desc != NULL, NULL);
font_map = pango_x_font_map_for_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
return gldi_font_use_pango_font_common (font_map, font_desc,
first, count, list_base);
}
CairoDockGLFont *cairo_dock_load_bitmap_font (const gchar *cFontDescription, int first, int count)
{
g_return_val_if_fail (cFontDescription != NULL && count > 0, NULL);
GLuint iListBase = glGenLists (count);
g_return_val_if_fail (iListBase != 0, NULL);
CairoDockGLFont *pFont = g_new0 (CairoDockGLFont, 1);
pFont->iListBase = iListBase;
pFont->iNbChars = count;
pFont->iCharBase = first;
PangoFontDescription *fd = pango_font_description_from_string (cFontDescription);
PangoFont *font = gldi_font_use_pango_font (fd,
first,
count,
iListBase);
g_return_val_if_fail (font != NULL, NULL);
PangoFontMetrics* metrics = pango_font_get_metrics (font, NULL);
pFont->iCharWidth = pango_font_metrics_get_approximate_char_width (metrics) / PANGO_SCALE;
pFont->iCharHeight = (pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics)) / PANGO_SCALE;
pango_font_metrics_unref(metrics);
pango_font_description_free (fd);
return pFont;
}*/
CairoDockGLFont *cairo_dock_load_textured_font (const gchar *cFontDescription, int first, int count)
{
g_return_val_if_fail (g_pPrimaryContainer != NULL && count > 0, NULL);
if (first < 32) // 32 = ' '
{
count -= (32 - first);
first = 32;
}
gchar *cPool = g_new0 (gchar, 4*count + 1);
int i, j=0;
guchar c;
for (i = 0; i < count; i ++)
{
c = first + i;
if (c > 254)
{
count=i;
break;
}
if ((c > 126 && c < 126 + 37) || (c == 173)) // le 173 est un caractere bizarre (sa taille est nulle).
{
cPool[j++] = ' ';
}
else
{
j += MAX (0, sprintf (cPool+j, "%lc", c)); // les caracteres ASCII >128 doivent etre convertis en multi-octets.
}
}
cd_debug ("%s (%d + %d -> '%s')", __func__, first, count, cPool);
/*iconv_t cd = iconv_open("UTF-8", "ISO-8859-1");
gchar *outbuf = g_new0 (gchar, count*4+1);
gchar *outbuf0 = outbuf, *inbuf0 = cPool;
size_t inbytesleft = count;
size_t outbytesleft = count*4;
size_t size = iconv (cd,
&cPool, &inbytesleft,
&outbuf, &outbytesleft);
cd_debug ("%d bytes left, %d bytes written => '%s'", inbytesleft, outbytesleft, outbuf0);
g_free (inbuf0);
cPool = outbuf0;
iconv_close (cd);*/
int iWidth, iHeight;
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (g_pPrimaryContainer);
GLuint iTexture = cairo_dock_create_texture_from_text_simple (cPool, cFontDescription, pCairoContext, &iWidth, &iHeight);
cairo_destroy (pCairoContext);
g_free (cPool);
CairoDockGLFont *pFont = g_new0 (CairoDockGLFont, 1);
pFont->iTexture = iTexture;
pFont->iNbChars = count;
pFont->iCharBase = first;
pFont->iNbRows = 1;
pFont->iNbColumns = count;
pFont->iCharWidth = (double)iWidth / count;
pFont->iCharHeight = iHeight;
cd_debug ("%d char / %d pixels => %.3f", count, iWidth, (double)iWidth / count);
return pFont;
}
CairoDockGLFont *cairo_dock_load_textured_font_from_image (const gchar *cImagePath)
{
double fImageWidth, fImageHeight;
GLuint iTexture = cairo_dock_create_texture_from_image_full (cImagePath, &fImageWidth, &fImageHeight);
g_return_val_if_fail (iTexture != 0, NULL);
CairoDockGLFont *pFont = g_new0 (CairoDockGLFont, 1);
pFont->iTexture = iTexture;
pFont->iNbChars = 256;
pFont->iCharBase = 0;
pFont->iNbRows = 16;
pFont->iNbColumns = 16;
pFont->iCharWidth = fImageWidth / pFont->iNbColumns;
pFont->iCharHeight = fImageHeight / pFont->iNbRows;
return pFont;
}
void cairo_dock_free_gl_font (CairoDockGLFont *pFont)
{
if (pFont == NULL)
return ;
if (pFont->iListBase != 0)
glDeleteLists (pFont->iListBase, pFont->iNbChars);
if (pFont->iTexture != 0)
_cairo_dock_delete_texture (pFont->iTexture);
g_free (pFont);
}
void cairo_dock_get_gl_text_extent (const gchar *cText, CairoDockGLFont *pFont, int *iWidth, int *iHeight)
{
if (pFont == NULL || cText == NULL)
{
*iWidth = 0;
*iHeight = 0;
return ;
}
int i, w=0, wmax=0, h=pFont->iCharHeight;
for (i = 0; cText[i] != '\0'; i ++)
{
if (cText[i] == '\n')
{
h += pFont->iCharHeight + 1;
wmax = MAX (wmax, w);
w = 0;
}
else
w += pFont->iCharWidth;
}
*iWidth = MAX (wmax, w);
*iHeight = h;
}
void cairo_dock_draw_gl_text (const guchar *cText, CairoDockGLFont *pFont)
{
int n = strlen ((char *) cText);
if (pFont->iListBase != 0)
{
if (pFont->iCharBase == 0 && strchr ((char *) cText, '\n') == NULL) // version optimisee ou on a charge tous les caracteres.
{
glDisable (GL_TEXTURE_2D);
glListBase (pFont->iListBase);
glCallLists (n, GL_UNSIGNED_BYTE, (unsigned char *)cText);
glListBase (0);
}
else
{
int i, j;
for (i = 0; i < n; i ++)
{
if (cText[i] == '\n')
{
GLfloat rpos[4];
glGetFloatv (GL_CURRENT_RASTER_POSITION, rpos);
glRasterPos2f (rpos[0], rpos[1] + pFont->iCharHeight + 1);
continue;
}
if (cText[i] < pFont->iCharBase || cText[i] >= pFont->iCharBase + pFont->iNbChars)
continue;
j = cText[i] - pFont->iCharBase;
glCallList (pFont->iListBase + j);
}
}
}
else if (pFont->iTexture != 0)
{
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_pbuffer (); // rend mieux pour les textes
glBindTexture (GL_TEXTURE_2D, pFont->iTexture);
double u, v, du=1./pFont->iNbColumns, dv=1./pFont->iNbRows, w=pFont->iCharWidth, h=pFont->iCharHeight, x=.5*w, y=.5*h;
int i, j;
for (i = 0; i < n; i ++)
{
if (cText[i] == '\n')
{
x = .5*pFont->iCharWidth;
y += pFont->iCharHeight + 1;
continue;
}
if (cText[i] < pFont->iCharBase || cText[i] >= pFont->iCharBase + pFont->iNbChars)
continue;
j = cText[i] - pFont->iCharBase;
u = (double) (j%pFont->iNbColumns) / pFont->iNbColumns;
v = (double) (j/pFont->iNbColumns) / pFont->iNbRows;
_cairo_dock_apply_current_texture_portion_at_size_with_offset (u, v, du, dv, w, h, x, y);
x += pFont->iCharWidth;
}
_cairo_dock_disable_texture ();
}
}
void cairo_dock_draw_gl_text_in_area (const guchar *cText, CairoDockGLFont *pFont, int iWidth, int iHeight, gboolean bCentered)
{
g_return_if_fail (pFont != NULL && cText != NULL);
if (pFont->iListBase != 0) // marche po sur du raster.
{
cd_warning ("can't resize raster ! use a textured font inside.");
}
else
{
int w, h;
cairo_dock_get_gl_text_extent ((char *) cText, pFont, &w, &h);
double zx, zy;
if (fabs ((double)iWidth/w) < fabs ((double)iHeight/h)) // on autorise les dimensions negatives pour pouvoir retourner le texte.
{
zx = (double)iWidth/w;
zy = (iWidth*iHeight > 0 ? zx : -zx);
}
else
{
zy = (double)iHeight/h;
zx = (iWidth*iHeight > 0 ? zy : -zy);
}
glScalef (zx, zy, 1.);
if (bCentered)
glTranslatef (-w/2, -h/2, 0.);
cairo_dock_draw_gl_text (cText, pFont);
}
}
void cairo_dock_draw_gl_text_at_position (const guchar *cText, CairoDockGLFont *pFont, int x, int y)
{
g_return_if_fail (pFont != NULL && cText != NULL);
if (pFont->iListBase != 0)
{
glRasterPos2f (x, y);
}
else
{
glTranslatef (x, y, 0);
}
cairo_dock_draw_gl_text (cText, pFont);
}
void cairo_dock_draw_gl_text_at_position_in_area (const guchar *cText, CairoDockGLFont *pFont, int x, int y, int iWidth, int iHeight, gboolean bCentered)
{
g_return_if_fail (pFont != NULL && cText != NULL);
if (pFont->iListBase != 0) // marche po sur du raster.
{
cd_warning ("can't resize raster ! use a textured font inside.");
}
else
{
glTranslatef (x, y, 0);
cairo_dock_draw_gl_text_in_area (cText, pFont, iWidth, iHeight, bCentered);
}
}
cairo-dock-3.3.2/src/gldit/cairo-dock-desklet-factory.c 000664 001750 001750 00000131212 12223247550 024041 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
* Login :
* Started on Sun Jan 27 18:35:38 2008 Cedric GESTES
* $Id$
*
* Author(s)
* - Cedric GESTES
* - Fabrice REY
*
* Copyright : (C) 2008 Cedric GESTES
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include
#include "cairo-dock-draw.h"
#include "cairo-dock-icon-facility.h" // cairo_dock_set_icon_container
#include "cairo-dock-module-instance-manager.h" // gldi_module_instance_detach
#include "cairo-dock-dialog-manager.h" // gldi_dialogs_replace_all
#include "cairo-dock-icon-factory.h"
#include "cairo-dock-icon-facility.h"
#include "cairo-dock-themes-manager.h" // cairo_dock_update_conf_file
#include "cairo-dock-desktop-manager.h"
#include "cairo-dock-log.h"
#include "cairo-dock-container.h"
#include "cairo-dock-surface-factory.h"
#include "cairo-dock-backends-manager.h"
#include "cairo-dock-draw-opengl.h"
#include "cairo-dock-image-buffer.h"
#include "cairo-dock-animations.h"
#include "cairo-dock-launcher-manager.h"
#include "cairo-dock-menu.h"
#include "cairo-dock-desklet-manager.h"
#include "cairo-dock-desklet-factory.h"
extern gboolean g_bUseOpenGL;
static void _reserve_space_for_desklet (CairoDesklet *pDesklet, gboolean bReserve);
#define CD_WRITE_DELAY 600 // ms
///////////////
/// SIGNALS ///
///////////////
static gboolean on_expose_desklet(G_GNUC_UNUSED GtkWidget *pWidget,
#if (GTK_MAJOR_VERSION < 3)
G_GNUC_UNUSED GdkEventExpose *pExpose,
#else
G_GNUC_UNUSED cairo_t *ctx,
#endif
CairoDesklet *pDesklet)
{
if (pDesklet->iDesiredWidth != 0 && pDesklet->iDesiredHeight != 0 && (pDesklet->iKnownWidth != pDesklet->iDesiredWidth || pDesklet->iKnownHeight != pDesklet->iDesiredHeight)) // skip the drawing until the desklet has reached its size, only make it transparent.
{
//g_print ("on saute le dessin\n");
if (g_bUseOpenGL)
{
if (! gldi_gl_container_begin_draw (CAIRO_CONTAINER (pDesklet)))
return FALSE;
gldi_gl_container_end_draw (CAIRO_CONTAINER (pDesklet));
}
else
{
cairo_t *pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDesklet));
cairo_destroy (pCairoContext);
}
return FALSE;
}
if (g_bUseOpenGL && pDesklet->pRenderer && pDesklet->pRenderer->render_opengl)
{
if (! gldi_gl_container_begin_draw (CAIRO_CONTAINER (pDesklet)))
return FALSE;
gldi_object_notify (pDesklet, NOTIFICATION_RENDER, pDesklet, NULL);
gldi_gl_container_end_draw (CAIRO_CONTAINER (pDesklet));
}
else
{
cairo_t *pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDesklet));
gldi_object_notify (pDesklet, NOTIFICATION_RENDER, pDesklet, pCairoContext);
cairo_destroy (pCairoContext);
}
return FALSE;
}
static void _cairo_dock_set_desklet_input_shape (CairoDesklet *pDesklet)
{
gldi_container_set_input_shape (CAIRO_CONTAINER (pDesklet), NULL);
if (pDesklet->bNoInput)
{
GldiShape *pShapeBitmap = gldi_container_create_input_shape (CAIRO_CONTAINER (pDesklet),
pDesklet->container.iWidth - myDeskletsParam.iDeskletButtonSize,
pDesklet->container.iHeight - myDeskletsParam.iDeskletButtonSize,
myDeskletsParam.iDeskletButtonSize,
myDeskletsParam.iDeskletButtonSize);
gldi_container_set_input_shape (CAIRO_CONTAINER (pDesklet), pShapeBitmap);
gldi_shape_destroy (pShapeBitmap);
}
}
static gboolean _cairo_dock_write_desklet_size (CairoDesklet *pDesklet)
{
if ((pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0) && pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL && gldi_desklet_manager_is_ready ())
{
gchar *cSize = g_strdup_printf ("%d;%d", pDesklet->container.iWidth, pDesklet->container.iHeight);
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
G_TYPE_STRING, "Desklet", "size", cSize,
G_TYPE_INVALID);
g_free (cSize);
gldi_object_notify (pDesklet, NOTIFICATION_CONFIGURE_DESKLET, pDesklet);
}
pDesklet->iSidWriteSize = 0;
pDesklet->iKnownWidth = pDesklet->container.iWidth;
pDesklet->iKnownHeight = pDesklet->container.iHeight;
if (((pDesklet->iDesiredWidth != 0 || pDesklet->iDesiredHeight != 0) && pDesklet->iDesiredWidth == pDesklet->container.iWidth && pDesklet->iDesiredHeight == pDesklet->container.iHeight) || (pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0))
{
pDesklet->iDesiredWidth = 0;
pDesklet->iDesiredHeight = 0;
gldi_desklet_load_desklet_decorations (pDesklet); // reload the decorations at the new desklet size.
if (pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
{
// on recalcule la vue du desklet a la nouvelle dimension.
CairoDeskletRenderer *pRenderer = pDesklet->pRenderer;
if (pRenderer)
{
// on calcule les icones et les parametres internes de la vue.
if (pRenderer->calculate_icons != NULL)
pRenderer->calculate_icons (pDesklet);
// on recharge l'icone principale.
Icon* pIcon = pDesklet->pIcon;
if (pIcon) // if the view doesn't display the main icon, it will set the allocated size to 0 so that the icon won't be loaded.
{
cairo_dock_load_icon_buffers (pIcon, CAIRO_CONTAINER (pDesklet)); // pas de trigger, car on veut pouvoir associer un contexte a l'icone principale tout de suite.
}
// on recharge chaque icone.
GList* ic;
for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (cairo_dock_icon_get_allocated_width (pIcon) != pIcon->image.iWidth || cairo_dock_icon_get_allocated_height (pIcon) != pIcon->image.iHeight)
{
cairo_dock_trigger_load_icon_buffers (pIcon);
}
}
// on recharge les buffers de la vue.
if (pRenderer->load_data != NULL)
pRenderer->load_data (pDesklet);
}
// on recharge le module associe.
gldi_object_reload (GLDI_OBJECT(pDesklet->pIcon->pModuleInstance), FALSE);
gtk_widget_queue_draw (pDesklet->container.pWidget); // sinon on ne redessine que l'interieur.
}
if (pDesklet->bSpaceReserved) // l'espace est reserve, on reserve la nouvelle taille.
{
_reserve_space_for_desklet (pDesklet, TRUE);
}
}
//g_print ("iWidth <- %d;iHeight <- %d ; (%dx%d) (%x)\n", pDesklet->container.iWidth, pDesklet->container.iHeight, pDesklet->iKnownWidth, pDesklet->iKnownHeight, pDesklet->pIcon);
return FALSE;
}
static gboolean _cairo_dock_write_desklet_position (CairoDesklet *pDesklet)
{
if (pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
{
int iRelativePositionX = (pDesklet->container.iWindowPositionX + pDesklet->container.iWidth/2 <= gldi_desktop_get_width()/2 ? pDesklet->container.iWindowPositionX : pDesklet->container.iWindowPositionX - gldi_desktop_get_width());
int iRelativePositionY = (pDesklet->container.iWindowPositionY + pDesklet->container.iHeight/2 <= gldi_desktop_get_height()/2 ? pDesklet->container.iWindowPositionY : pDesklet->container.iWindowPositionY - gldi_desktop_get_height());
int iNumDesktop = -1;
if (! gldi_desklet_is_sticky (pDesklet))
{
iNumDesktop = gldi_container_get_current_desktop_index (CAIRO_CONTAINER (pDesklet));
//g_print ("desormais on place le desklet sur le bureau (%d,%d,%d)\n", iDesktop, iViewportX, iViewportY);
}
cd_debug ("%d; %d; %d", iNumDesktop, iRelativePositionX, iRelativePositionY);
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
G_TYPE_INT, "Desklet", "x position", iRelativePositionX,
G_TYPE_INT, "Desklet", "y position", iRelativePositionY,
G_TYPE_INT, "Desklet", "num desktop", iNumDesktop,
G_TYPE_INVALID);
gldi_object_notify (pDesklet, NOTIFICATION_CONFIGURE_DESKLET, pDesklet);
}
if (pDesklet->bSpaceReserved) // l'espace est reserve, on reserve a la nouvelle position.
{
_reserve_space_for_desklet (pDesklet, TRUE);
}
if (pDesklet->pIcon && gldi_icon_has_dialog (pDesklet->pIcon))
{
gldi_dialogs_replace_all ();
}
pDesklet->iSidWritePosition = 0;
return FALSE;
}
static gboolean on_configure_desklet (G_GNUC_UNUSED GtkWidget* pWidget,
GdkEventConfigure* pEvent,
CairoDesklet *pDesklet)
{
//g_print (" >>>>>>>>> %s (%dx%d, %d;%d)", __func__, pEvent->width, pEvent->height, pEvent->x, pEvent->y);
if (pDesklet->container.iWidth != pEvent->width || pDesklet->container.iHeight != pEvent->height)
{
if ((pEvent->width < pDesklet->container.iWidth || pEvent->height < pDesklet->container.iHeight) && (pDesklet->iDesiredWidth != 0 && pDesklet->iDesiredHeight != 0))
{
gdk_window_resize (gldi_container_get_gdk_window (CAIRO_CONTAINER (pDesklet)),
pDesklet->iDesiredWidth,
pDesklet->iDesiredHeight);
}
pDesklet->container.iWidth = pEvent->width;
pDesklet->container.iHeight = pEvent->height;
if (g_bUseOpenGL)
{
GLsizei w = pEvent->width;
GLsizei h = pEvent->height;
if (! gldi_gl_container_make_current (CAIRO_CONTAINER (pDesklet)))
return FALSE;
glViewport(0, 0, w, h);
cairo_dock_set_perspective_view (CAIRO_CONTAINER (pDesklet));
}
if (pDesklet->bNoInput)
_cairo_dock_set_desklet_input_shape (pDesklet);
if (pDesklet->iSidWriteSize != 0)
{
g_source_remove (pDesklet->iSidWriteSize);
}
pDesklet->iSidWriteSize = g_timeout_add (CD_WRITE_DELAY, (GSourceFunc) _cairo_dock_write_desklet_size, (gpointer) pDesklet);
}
int x = pEvent->x, y = pEvent->y;
//g_print ("new desklet position : (%d;%d)", x, y);
while (x < 0) // on passe au referentiel du viewport de la fenetre; inutile de connaitre sa position, puisqu'ils ont tous la meme taille.
x += gldi_desktop_get_width();
while (x >= gldi_desktop_get_width())
x -= gldi_desktop_get_width();
while (y < 0)
y += gldi_desktop_get_height();
while (y >= gldi_desktop_get_height())
y -= gldi_desktop_get_height();
//g_print (" => (%d;%d)\n", x, y);
if (pDesklet->container.iWindowPositionX != x || pDesklet->container.iWindowPositionY != y)
{
pDesklet->container.iWindowPositionX = x;
pDesklet->container.iWindowPositionY = y;
if (gldi_desklet_manager_is_ready ())
{
if (pDesklet->iSidWritePosition != 0)
{
g_source_remove (pDesklet->iSidWritePosition);
}
pDesklet->iSidWritePosition = g_timeout_add (CD_WRITE_DELAY, (GSourceFunc) _cairo_dock_write_desklet_position, (gpointer) pDesklet);
}
}
pDesklet->moving = FALSE;
return FALSE;
}
static gboolean on_scroll_desklet (G_GNUC_UNUSED GtkWidget* pWidget,
GdkEventScroll* pScroll,
CairoDesklet *pDesklet)
{
//g_print ("scroll %d\n", pScroll->direction);
if (pScroll->direction != GDK_SCROLL_UP && pScroll->direction != GDK_SCROLL_DOWN) // on degage les scrolls horizontaux.
{
return FALSE;
}
Icon *icon = gldi_desklet_find_clicked_icon (pDesklet); // can be NULL
gldi_object_notify (pDesklet, NOTIFICATION_SCROLL_ICON, icon, pDesklet, pScroll->direction);
return FALSE;
}
static gboolean on_unmap_desklet (GtkWidget* pWidget,
G_GNUC_UNUSED GdkEvent *pEvent,
CairoDesklet *pDesklet)
{
cd_debug ("unmap desklet (bAllowMinimize:%d)", pDesklet->bAllowMinimize);
if (pDesklet->iVisibility == CAIRO_DESKLET_ON_WIDGET_LAYER) // on the widget layer, let pass the unmap event..
return FALSE;
if (! pDesklet->bAllowMinimize)
{
if (pDesklet->pUnmapTimer)
{
double fElapsedTime = g_timer_elapsed (pDesklet->pUnmapTimer, NULL);
cd_debug ("fElapsedTime : %fms", fElapsedTime);
g_timer_destroy (pDesklet->pUnmapTimer);
pDesklet->pUnmapTimer = NULL;
if (fElapsedTime < .2)
return TRUE;
}
gtk_window_present (GTK_WINDOW (pWidget));
}
else
{
pDesklet->bAllowMinimize = FALSE;
if (pDesklet->pUnmapTimer == NULL)
pDesklet->pUnmapTimer = g_timer_new (); // starts the timer.
}
return TRUE; // stops other handlers from being invoked for the event.
}
static gboolean on_button_press_desklet(G_GNUC_UNUSED GtkWidget *pWidget,
GdkEventButton *pButton,
CairoDesklet *pDesklet)
{
if (pButton->button == 1) // clic gauche.
{
pDesklet->container.iMouseX = pButton->x;
pDesklet->container.iMouseY = pButton->y;
if (pButton->type == GDK_BUTTON_PRESS)
{
pDesklet->bClicked = TRUE;
if (cairo_dock_desklet_is_free (pDesklet))
{
///pDesklet->container.iMouseX = pButton->x; // pour le deplacement manuel.
///pDesklet->container.iMouseY = pButton->y;
if (pButton->x < myDeskletsParam.iDeskletButtonSize && pButton->y < myDeskletsParam.iDeskletButtonSize)
pDesklet->rotating = TRUE;
else if (pButton->x > pDesklet->container.iWidth - myDeskletsParam.iDeskletButtonSize && pButton->y < myDeskletsParam.iDeskletButtonSize)
pDesklet->retaching = TRUE;
else if (pButton->x > (pDesklet->container.iWidth - myDeskletsParam.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDeskletsParam.iDeskletButtonSize)/2 && pButton->y < myDeskletsParam.iDeskletButtonSize)
pDesklet->rotatingY = TRUE;
else if (pButton->y > (pDesklet->container.iHeight - myDeskletsParam.iDeskletButtonSize)/2 && pButton->y < (pDesklet->container.iHeight + myDeskletsParam.iDeskletButtonSize)/2 && pButton->x < myDeskletsParam.iDeskletButtonSize)
pDesklet->rotatingX = TRUE;
else
pDesklet->time = pButton->time;
}
if (pDesklet->bAllowNoClickable && pButton->x > pDesklet->container.iWidth - myDeskletsParam.iDeskletButtonSize && pButton->y > pDesklet->container.iHeight - myDeskletsParam.iDeskletButtonSize)
pDesklet->making_transparent = TRUE;
}
else if (pButton->type == GDK_BUTTON_RELEASE)
{
if (!pDesklet->bClicked) // on n'accepte le release que si on avait clique sur le desklet avant (on peut recevoir le release si on avait clique sur un dialogue qui chevauchait notre desklet et qui a disparu au clic).
{
return FALSE;
}
pDesklet->bClicked = FALSE;
//g_print ("GDK_BUTTON_RELEASE\n");
int x = pDesklet->container.iMouseX;
int y = pDesklet->container.iMouseY;
if (pDesklet->moving)
{
pDesklet->moving = FALSE;
}
else if (pDesklet->rotating)
{
pDesklet->rotating = FALSE;
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
G_TYPE_INT, "Desklet", "rotation", (int) (pDesklet->fRotation / G_PI * 180.),
G_TYPE_INVALID);
gtk_widget_queue_draw (pDesklet->container.pWidget);
gldi_object_notify (pDesklet, NOTIFICATION_CONFIGURE_DESKLET, pDesklet);
}
else if (pDesklet->retaching)
{
pDesklet->retaching = FALSE;
if (x > pDesklet->container.iWidth - myDeskletsParam.iDeskletButtonSize && y < myDeskletsParam.iDeskletButtonSize) // on verifie qu'on est encore dedans.
{
Icon *icon = pDesklet->pIcon;
g_return_val_if_fail (CAIRO_DOCK_IS_APPLET (icon), FALSE);
gldi_module_instance_detach (icon->pModuleInstance);
return GLDI_NOTIFICATION_INTERCEPT; // interception du signal.
}
}
else if (pDesklet->making_transparent)
{
cd_debug ("pDesklet->making_transparent\n");
pDesklet->making_transparent = FALSE;
if (x > pDesklet->container.iWidth - myDeskletsParam.iDeskletButtonSize && y > pDesklet->container.iHeight - myDeskletsParam.iDeskletButtonSize) // on verifie qu'on est encore dedans.
{
Icon *icon = pDesklet->pIcon;
g_return_val_if_fail (CAIRO_DOCK_IS_APPLET (icon), FALSE);
pDesklet->bNoInput = ! pDesklet->bNoInput;
cd_debug ("no input : %d (%s)", pDesklet->bNoInput, icon->pModuleInstance->cConfFilePath);
cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
G_TYPE_BOOLEAN, "Desklet", "no input", pDesklet->bNoInput,
G_TYPE_INVALID);
_cairo_dock_set_desklet_input_shape (pDesklet);
gtk_widget_queue_draw (pDesklet->container.pWidget);
}
}
else if (pDesklet->rotatingY)
{
pDesklet->rotatingY = FALSE;
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
G_TYPE_INT, "Desklet", "depth rotation y", (int) (pDesklet->fDepthRotationY / G_PI * 180.),
G_TYPE_INVALID);
gtk_widget_queue_draw (pDesklet->container.pWidget);
}
else if (pDesklet->rotatingX)
{
pDesklet->rotatingX = FALSE;
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
G_TYPE_INT, "Desklet", "depth rotation x", (int) (pDesklet->fDepthRotationX / G_PI * 180.),
G_TYPE_INVALID);
gtk_widget_queue_draw (pDesklet->container.pWidget);
}
else
{
Icon *pClickedIcon = gldi_desklet_find_clicked_icon (pDesklet);
gldi_object_notify (pDesklet, NOTIFICATION_CLICK_ICON, pClickedIcon, pDesklet, pButton->state);
}
// prudence.
pDesklet->rotating = FALSE;
pDesklet->retaching = FALSE;
pDesklet->making_transparent = FALSE;
pDesklet->rotatingX = FALSE;
pDesklet->rotatingY = FALSE;
}
else if (pButton->type == GDK_2BUTTON_PRESS)
{
if (! (pButton->x < myDeskletsParam.iDeskletButtonSize && pButton->y < myDeskletsParam.iDeskletButtonSize) && ! (pButton->x > (pDesklet->container.iWidth - myDeskletsParam.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDeskletsParam.iDeskletButtonSize)/2 && pButton->y < myDeskletsParam.iDeskletButtonSize))
{
Icon *pClickedIcon = gldi_desklet_find_clicked_icon (pDesklet); // can be NULL
gldi_object_notify (pDesklet, NOTIFICATION_DOUBLE_CLICK_ICON, pClickedIcon, pDesklet);
}
}
}
else if (pButton->button == 3 && pButton->type == GDK_BUTTON_PRESS) // clique droit.
{
Icon *pClickedIcon = gldi_desklet_find_clicked_icon (pDesklet);
GtkWidget *menu = gldi_container_build_menu (CAIRO_CONTAINER (pDesklet), pClickedIcon); // genere un CAIRO_DOCK_BUILD_ICON_MENU.
gldi_menu_popup (menu);
}
else if (pButton->button == 2 && pButton->type == GDK_BUTTON_PRESS) // clique milieu.
{
if (pButton->x < myDeskletsParam.iDeskletButtonSize && pButton->y < myDeskletsParam.iDeskletButtonSize)
{
pDesklet->fRotation = 0.;
gtk_widget_queue_draw (pDesklet->container.pWidget);
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
G_TYPE_INT, "Desklet", "rotation", 0,
G_TYPE_INVALID);
gldi_object_notify (pDesklet, NOTIFICATION_CONFIGURE_DESKLET, pDesklet);
}
else if (pButton->x > (pDesklet->container.iWidth - myDeskletsParam.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDeskletsParam.iDeskletButtonSize)/2 && pButton->y < myDeskletsParam.iDeskletButtonSize)
{
pDesklet->fDepthRotationY = 0.;
gtk_widget_queue_draw (pDesklet->container.pWidget);
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
G_TYPE_INT, "Desklet", "depth rotation y", 0,
G_TYPE_INVALID);
}
else if (pButton->y > (pDesklet->container.iHeight - myDeskletsParam.iDeskletButtonSize)/2 && pButton->y < (pDesklet->container.iHeight + myDeskletsParam.iDeskletButtonSize)/2 && pButton->x < myDeskletsParam.iDeskletButtonSize)
{
pDesklet->fDepthRotationX = 0.;
gtk_widget_queue_draw (pDesklet->container.pWidget);
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
G_TYPE_INT, "Desklet", "depth rotation x", 0,
G_TYPE_INVALID);
}
else
{
gldi_object_notify (pDesklet, NOTIFICATION_MIDDLE_CLICK_ICON, pDesklet->pIcon, pDesklet);
}
}
return FALSE;
}
static void _on_drag_data_received (G_GNUC_UNUSED GtkWidget *pWidget, G_GNUC_UNUSED GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data, G_GNUC_UNUSED guint info, guint time, CairoDesklet *pDesklet)
{
//\_________________ On recupere l'URI.
gchar *cReceivedData = (gchar *) gtk_selection_data_get_data (selection_data); // the data are actually 'const guchar*', but since we only allowed text and urls, it will be a string
g_return_if_fail (cReceivedData != NULL);
int length = strlen (cReceivedData);
if (cReceivedData[length-1] == '\n')
cReceivedData[--length] = '\0'; // on vire le retour chariot final.
if (cReceivedData[length-1] == '\r')
cReceivedData[--length] = '\0';
// g_print ("%s (%dx%d, %s)\n", __func__, x, y, cReceivedData);
pDesklet->container.iMouseX = x;
pDesklet->container.iMouseY = y;
Icon *pClickedIcon = gldi_desklet_find_clicked_icon (pDesklet);
gldi_container_notify_drop_data (CAIRO_CONTAINER (pDesklet), cReceivedData, pClickedIcon, 0);
gtk_drag_finish (dc, TRUE, FALSE, time);
}
static gboolean on_motion_notify_desklet (GtkWidget *pWidget,
GdkEventMotion* pMotion,
CairoDesklet *pDesklet)
{
/*if (pMotion->state & GDK_BUTTON1_MASK && cairo_dock_desklet_is_free (pDesklet))
{
cd_debug ("root : %d;%d", (int) pMotion->x_root, (int) pMotion->y_root);
}
else*/ // le 'press-button' est local au sous-widget clique, alors que le 'motion-notify' est global a la fenetre; c'est donc par lui qu'on peut avoir a coup sur les coordonnees du curseur (juste avant le clic).
{
pDesklet->container.iMouseX = pMotion->x;
pDesklet->container.iMouseY = pMotion->y;
gboolean bStartAnimation = FALSE;
gldi_object_notify (pDesklet, NOTIFICATION_MOUSE_MOVED, pDesklet, &bStartAnimation);
if (bStartAnimation)
cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
}
if (pDesklet->rotating && cairo_dock_desklet_is_free (pDesklet))
{
double alpha = atan2 (pDesklet->container.iHeight, - pDesklet->container.iWidth);
pDesklet->fRotation = alpha - atan2 (.5*pDesklet->container.iHeight - pMotion->y, pMotion->x - .5*pDesklet->container.iWidth);
while (pDesklet->fRotation > G_PI)
pDesklet->fRotation -= 2 * G_PI;
while (pDesklet->fRotation <= - G_PI)
pDesklet->fRotation += 2 * G_PI;
gtk_widget_queue_draw(pDesklet->container.pWidget);
}
else if (pDesklet->rotatingY && cairo_dock_desklet_is_free (pDesklet))
{
pDesklet->fDepthRotationY = G_PI * (pMotion->x - .5*pDesklet->container.iWidth) / pDesklet->container.iWidth;
gtk_widget_queue_draw(pDesklet->container.pWidget);
}
else if (pDesklet->rotatingX && cairo_dock_desklet_is_free (pDesklet))
{
pDesklet->fDepthRotationX = G_PI * (pMotion->y - .5*pDesklet->container.iHeight) / pDesklet->container.iHeight;
gtk_widget_queue_draw(pDesklet->container.pWidget);
}
else if (pMotion->state & GDK_BUTTON1_MASK && cairo_dock_desklet_is_free (pDesklet) && ! pDesklet->moving)
{
gtk_window_begin_move_drag (GTK_WINDOW (gtk_widget_get_toplevel (pWidget)),
1/*pButton->button*/,
pMotion->x_root/*pButton->x_root*/,
pMotion->y_root/*pButton->y_root*/,
pDesklet->time/*pButton->time*/);
pDesklet->moving = TRUE;
}
else
{
gboolean bStartAnimation = FALSE;
Icon *pIcon = gldi_desklet_find_clicked_icon (pDesklet);
if (pIcon != NULL)
{
if (! pIcon->bPointed)
{
Icon *pPointedIcon = cairo_dock_get_pointed_icon (pDesklet->icons);
if (pPointedIcon != NULL)
pPointedIcon->bPointed = FALSE;
pIcon->bPointed = TRUE;
//g_print ("on survole %s\n", pIcon->cName);
gldi_object_notify (pDesklet, NOTIFICATION_ENTER_ICON, pIcon, pDesklet, &bStartAnimation);
}
}
else
{
Icon *pPointedIcon = cairo_dock_get_pointed_icon (pDesklet->icons);
if (pPointedIcon != NULL)
{
pPointedIcon->bPointed = FALSE;
//g_print ("kedal\n");
//gldi_object_notify (pDesklet, NOTIFICATION_ENTER_ICON, pPointedIcon, pDesklet, &bStartAnimation);
}
}
if (bStartAnimation)
{
cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
}
}
gdk_device_get_state (pMotion->device, pMotion->window, NULL, NULL); // pour recevoir d'autres MotionNotify.
return FALSE;
}
static gboolean on_focus_in_out_desklet(G_GNUC_UNUSED GtkWidget *widget,
G_GNUC_UNUSED GdkEventFocus *event,
CairoDesklet *pDesklet)
{
gtk_widget_queue_draw(pDesklet->container.pWidget);
return FALSE;
}
static gboolean on_enter_desklet (GtkWidget* pWidget,
G_GNUC_UNUSED GdkEventCrossing* pEvent,
CairoDesklet *pDesklet)
{
//g_print ("%s (%d)\n", __func__, pDesklet->container.bInside);
if (! pDesklet->container.bInside) // avant on etait dehors, on redessine donc.
{
pDesklet->container.bInside = TRUE;
gtk_widget_queue_draw (pWidget); // redessin des boutons.
gboolean bStartAnimation = FALSE;
gldi_object_notify (pDesklet, NOTIFICATION_ENTER_DESKLET, pDesklet, &bStartAnimation);
if (bStartAnimation)
cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
}
return FALSE;
}
static gboolean on_leave_desklet (GtkWidget* pWidget,
GdkEventCrossing* pEvent,
CairoDesklet *pDesklet)
{
//g_print ("%s (%d, %p, %d;%d)\n", __func__, pDesklet->container.bInside, pEvent, iMouseX, iMouseY);
int iMouseX, iMouseY;
if (pEvent != NULL)
{
iMouseX = pEvent->x;
iMouseY = pEvent->y;
}
else
{
gldi_container_update_mouse_position (CAIRO_CONTAINER (pDesklet));
iMouseX = pDesklet->container.iMouseX;
iMouseY = pDesklet->container.iMouseY;
}
if (gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget)) != NULL && iMouseX > 0 && iMouseX < pDesklet->container.iWidth && iMouseY > 0 && iMouseY < pDesklet->container.iHeight) // en fait on est dans un widget fils, donc on ne fait rien.
{
return FALSE;
}
pDesklet->container.bInside = FALSE;
Icon *pPointedIcon = cairo_dock_get_pointed_icon (pDesklet->icons);
if (pPointedIcon != NULL)
pPointedIcon->bPointed = FALSE;
gtk_widget_queue_draw (pWidget); // redessin des boutons.
gboolean bStartAnimation = FALSE;
gldi_object_notify (pDesklet, NOTIFICATION_LEAVE_DESKLET, pDesklet, &bStartAnimation);
if (bStartAnimation)
cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
return FALSE;
}
///////////////
/// FACTORY ///
///////////////
static gboolean _cairo_desklet_animation_loop (GldiContainer *pContainer)
{
CairoDesklet *pDesklet = CAIRO_DESKLET (pContainer);
gboolean bContinue = FALSE;
gboolean bUpdateSlowAnimation = FALSE;
pContainer->iAnimationStep ++;
if (pContainer->iAnimationStep * pContainer->iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
{
bUpdateSlowAnimation = TRUE;
pContainer->iAnimationStep = 0;
pContainer->bKeepSlowAnimation = FALSE;
}
if (pDesklet->pIcon != NULL)
{
gboolean bIconIsAnimating = FALSE;
if (bUpdateSlowAnimation)
{
gldi_object_notify (pDesklet->pIcon, NOTIFICATION_UPDATE_ICON_SLOW, pDesklet->pIcon, pDesklet, &bIconIsAnimating);
pDesklet->container.bKeepSlowAnimation |= bIconIsAnimating;
}
gldi_object_notify (pDesklet->pIcon, NOTIFICATION_UPDATE_ICON, pDesklet->pIcon, pDesklet, &bIconIsAnimating);
if (! bIconIsAnimating)
pDesklet->pIcon->iAnimationState = CAIRO_DOCK_STATE_REST;
else
bContinue = TRUE;
}
if (bUpdateSlowAnimation)
{
gldi_object_notify (pDesklet, NOTIFICATION_UPDATE_SLOW, pDesklet, &pContainer->bKeepSlowAnimation);
}
gldi_object_notify (pDesklet, NOTIFICATION_UPDATE, pDesklet, &bContinue);
if (! bContinue && ! pContainer->bKeepSlowAnimation)
{
pContainer->iSidGLAnimation = 0;
return FALSE;
}
else
return TRUE;
}
static void _update_desklet_icons (CairoDesklet *pDesklet)
{
// compute icons size
if (pDesklet->pRenderer && pDesklet->pRenderer->calculate_icons != NULL)
pDesklet->pRenderer->calculate_icons (pDesklet);
// trigger load if changed
Icon* pIcon = pDesklet->pIcon;
if (pIcon)
{
if (cairo_dock_icon_get_allocated_width (pIcon) != pIcon->image.iWidth || cairo_dock_icon_get_allocated_height (pIcon) != pIcon->image.iHeight)
{
cairo_dock_trigger_load_icon_buffers (pIcon);
}
}
GList* ic;
for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (cairo_dock_icon_get_allocated_width (pIcon) != pIcon->image.iWidth || cairo_dock_icon_get_allocated_height (pIcon) != pIcon->image.iHeight)
{
cairo_dock_trigger_load_icon_buffers (pIcon);
}
}
// redraw
cairo_dock_redraw_container (CAIRO_CONTAINER (pDesklet));
}
static void _detach_icon (GldiContainer *pContainer, Icon *pIcon)
{
CairoDesklet *pDesklet = CAIRO_DESKLET (pContainer);
// remove icon
pDesklet->icons = g_list_remove (pDesklet->icons, pIcon);
// calculate icons
_update_desklet_icons (pDesklet);
}
static void _insert_icon (GldiContainer *pContainer, Icon *pIcon, G_GNUC_UNUSED gboolean bAnimateIcon)
{
CairoDesklet *pDesklet = CAIRO_DESKLET (pContainer);
// insert icon
pDesklet->icons = g_list_insert_sorted (pDesklet->icons,
pIcon,
(GCompareFunc)cairo_dock_compare_icons_order);
cairo_dock_set_icon_container (pIcon, pDesklet);
// calculate icons
_update_desklet_icons (pDesklet);
}
CairoDesklet *gldi_desklet_new (CairoDeskletAttr *attr)
{
return (CairoDesklet*)gldi_object_new (&myDeskletObjectMgr, attr);
}
void gldi_desklet_init_internals (CairoDesklet *pDesklet)
{
pDesklet->container.iface.animation_loop = _cairo_desklet_animation_loop;
pDesklet->container.iface.detach_icon = _detach_icon;
pDesklet->container.iface.insert_icon = _insert_icon;
// set up its window
GtkWidget *pWindow = pDesklet->container.pWidget;
gtk_window_set_title (GTK_WINDOW(pWindow), "cairo-dock-desklet");
gtk_widget_add_events( pWindow,
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_SCROLL_MASK |
GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK |
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
gtk_container_set_border_width(GTK_CONTAINER(pWindow), 1);
// connect the signals to the window
g_signal_connect (G_OBJECT (pWindow),
#if (GTK_MAJOR_VERSION < 3)
"expose-event",
#else
"draw",
#endif
G_CALLBACK (on_expose_desklet),
pDesklet);
g_signal_connect (G_OBJECT (pWindow),
"configure-event",
G_CALLBACK (on_configure_desklet),
pDesklet);
g_signal_connect (G_OBJECT (pWindow),
"motion-notify-event",
G_CALLBACK (on_motion_notify_desklet),
pDesklet);
g_signal_connect (G_OBJECT (pWindow),
"button-press-event",
G_CALLBACK (on_button_press_desklet),
pDesklet);
g_signal_connect (G_OBJECT (pWindow),
"button-release-event",
G_CALLBACK (on_button_press_desklet),
pDesklet);
g_signal_connect (G_OBJECT (pWindow),
"focus-in-event",
G_CALLBACK (on_focus_in_out_desklet),
pDesklet);
g_signal_connect (G_OBJECT (pWindow),
"focus-out-event",
G_CALLBACK (on_focus_in_out_desklet),
pDesklet);
g_signal_connect (G_OBJECT (pWindow),
"enter-notify-event",
G_CALLBACK (on_enter_desklet),
pDesklet);
g_signal_connect (G_OBJECT (pWindow),
"leave-notify-event",
G_CALLBACK (on_leave_desklet),
pDesklet);
g_signal_connect (G_OBJECT (pWindow),
"unmap-event",
G_CALLBACK (on_unmap_desklet),
pDesklet);
g_signal_connect (G_OBJECT (pWindow),
"scroll-event",
G_CALLBACK (on_scroll_desklet),
pDesklet);
gldi_container_enable_drop (CAIRO_CONTAINER (pDesklet), G_CALLBACK (_on_drag_data_received), pDesklet);
gtk_widget_show_all (pWindow);
}
void gldi_desklet_configure (CairoDesklet *pDesklet, CairoDeskletAttr *pAttribute)
{
//g_print ("%s (%dx%d ; (%d,%d) ; %d)\n", __func__, pAttribute->iDeskletWidth, pAttribute->iDeskletHeight, pAttribute->iDeskletPositionX, pAttribute->iDeskletPositionY, pAttribute->iVisibility);
if (pAttribute->bDeskletUseSize && (pAttribute->iDeskletWidth != pDesklet->container.iWidth || pAttribute->iDeskletHeight != pDesklet->container.iHeight))
{
pDesklet->iDesiredWidth = pAttribute->iDeskletWidth;
pDesklet->iDesiredHeight = pAttribute->iDeskletHeight;
gdk_window_resize (gldi_container_get_gdk_window (CAIRO_CONTAINER (pDesklet)),
pAttribute->iDeskletWidth,
pAttribute->iDeskletHeight);
}
if (! pAttribute->bDeskletUseSize)
{
gtk_container_set_border_width (GTK_CONTAINER (pDesklet->container.pWidget), 0);
gtk_window_set_resizable (GTK_WINDOW(pDesklet->container.pWidget), FALSE);
}
int iAbsolutePositionX = (pAttribute->iDeskletPositionX < 0 ? gldi_desktop_get_width() + pAttribute->iDeskletPositionX : pAttribute->iDeskletPositionX);
iAbsolutePositionX = MAX (0, MIN (gldi_desktop_get_width() - pAttribute->iDeskletWidth, iAbsolutePositionX));
int iAbsolutePositionY = (pAttribute->iDeskletPositionY < 0 ? gldi_desktop_get_height() + pAttribute->iDeskletPositionY : pAttribute->iDeskletPositionY);
iAbsolutePositionY = MAX (0, MIN (gldi_desktop_get_height() - pAttribute->iDeskletHeight, iAbsolutePositionY));
//g_print (" let's place the deklet at (%d;%d)", iAbsolutePositionX, iAbsolutePositionY);
if (pAttribute->bOnAllDesktops)
{
gtk_window_stick (GTK_WINDOW (pDesklet->container.pWidget));
gdk_window_move (gldi_container_get_gdk_window (CAIRO_CONTAINER (pDesklet)),
iAbsolutePositionX,
iAbsolutePositionY);
}
else
{
gtk_window_unstick (GTK_WINDOW (pDesklet->container.pWidget));
if (g_desktopGeometry.iNbViewportX > 0 && g_desktopGeometry.iNbViewportY > 0)
{
int iNumDesktop, iNumViewportX, iNumViewportY;
iNumDesktop = pAttribute->iNumDesktop / (g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY);
int index2 = pAttribute->iNumDesktop % (g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY);
iNumViewportX = index2 / g_desktopGeometry.iNbViewportY;
iNumViewportY = index2 % g_desktopGeometry.iNbViewportY;
int iCurrentDesktop, iCurrentViewportX, iCurrentViewportY;
gldi_desktop_get_current (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
cd_debug (">>> on fixe le desklet sur le bureau (%d,%d,%d) (cur : %d,%d,%d)", iNumDesktop, iNumViewportX, iNumViewportY, iCurrentDesktop, iCurrentViewportX, iCurrentViewportY);
iNumViewportX -= iCurrentViewportX;
iNumViewportY -= iCurrentViewportY;
cd_debug ("on le place en %d + %d", iNumViewportX * gldi_desktop_get_width(), iAbsolutePositionX);
gldi_container_move (CAIRO_CONTAINER (pDesklet), iNumDesktop, iNumViewportX * gldi_desktop_get_width() + iAbsolutePositionX, iNumViewportY * gldi_desktop_get_height() + iAbsolutePositionY);
}
}
pDesklet->bPositionLocked = pAttribute->bPositionLocked;
pDesklet->bNoInput = pAttribute->bNoInput;
pDesklet->fRotation = pAttribute->iRotation / 180. * G_PI ;
pDesklet->fDepthRotationY = pAttribute->iDepthRotationY / 180. * G_PI ;
pDesklet->fDepthRotationX = pAttribute->iDepthRotationX / 180. * G_PI ;
g_free (pDesklet->cDecorationTheme);
pDesklet->cDecorationTheme = pAttribute->cDecorationTheme;
pAttribute->cDecorationTheme = NULL;
gldi_desklet_decoration_free (pDesklet->pUserDecoration);
pDesklet->pUserDecoration = pAttribute->pUserDecoration;
pAttribute->pUserDecoration = NULL;
gldi_desklet_set_accessibility (pDesklet, pAttribute->iVisibility, FALSE);
//cd_debug ("%s (%dx%d ; %d)", __func__, pDesklet->iDesiredWidth, pDesklet->iDesiredHeight, pDesklet->iSidWriteSize);
if (pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0 && pDesklet->iSidWriteSize == 0)
{
gldi_desklet_load_desklet_decorations (pDesklet);
}
}
void gldi_desklet_load_desklet_decorations (CairoDesklet *pDesklet)
{
cairo_dock_unload_image_buffer (&pDesklet->backGroundImageBuffer);
cairo_dock_unload_image_buffer (&pDesklet->foreGroundImageBuffer);
CairoDeskletDecoration *pDeskletDecorations;
//cd_debug ("%s (%s)", __func__, pDesklet->cDecorationTheme);
if (pDesklet->cDecorationTheme == NULL || strcmp (pDesklet->cDecorationTheme, "personnal") == 0)
pDeskletDecorations = pDesklet->pUserDecoration;
else if (strcmp (pDesklet->cDecorationTheme, "default") == 0)
pDeskletDecorations = cairo_dock_get_desklet_decoration (myDeskletsParam.cDeskletDecorationsName);
else
pDeskletDecorations = cairo_dock_get_desklet_decoration (pDesklet->cDecorationTheme);
if (pDeskletDecorations == NULL) // peut arriver si rendering n'a pas encore charge ses decorations.
return ;
//cd_debug ("pDeskletDecorations : %s (%x)", pDesklet->cDecorationTheme, pDeskletDecorations);
double fZoomX = 0., fZoomY = 0.;
if (pDeskletDecorations->cBackGroundImagePath != NULL && pDeskletDecorations->fBackGroundAlpha > 0)
{
//cd_debug ("bg : %s", pDeskletDecorations->cBackGroundImagePath);
cairo_dock_load_image_buffer_full (&pDesklet->backGroundImageBuffer,
pDeskletDecorations->cBackGroundImagePath,
pDesklet->container.iWidth,
pDesklet->container.iHeight,
pDeskletDecorations->iLoadingModifier,
pDeskletDecorations->fBackGroundAlpha);
fZoomX = pDesklet->backGroundImageBuffer.fZoomX;
fZoomY = pDesklet->backGroundImageBuffer.fZoomY;
}
if (pDeskletDecorations->cForeGroundImagePath != NULL && pDeskletDecorations->fForeGroundAlpha > 0)
{
//cd_debug ("fg : %s", pDeskletDecorations->cForeGroundImagePath);
cairo_dock_load_image_buffer_full (&pDesklet->foreGroundImageBuffer,
pDeskletDecorations->cForeGroundImagePath,
pDesklet->container.iWidth,
pDesklet->container.iHeight,
pDeskletDecorations->iLoadingModifier,
pDeskletDecorations->fForeGroundAlpha);
fZoomX = pDesklet->foreGroundImageBuffer.fZoomX;
fZoomY = pDesklet->foreGroundImageBuffer.fZoomY;
}
pDesklet->iLeftSurfaceOffset = pDeskletDecorations->iLeftMargin * fZoomX;
pDesklet->iTopSurfaceOffset = pDeskletDecorations->iTopMargin * fZoomY;
pDesklet->iRightSurfaceOffset = pDeskletDecorations->iRightMargin * fZoomX;
pDesklet->iBottomSurfaceOffset = pDeskletDecorations->iBottomMargin * fZoomY;
//g_print ("%d;%d;%d;%d ; %.2f;%.2f\n", pDesklet->iLeftSurfaceOffset, pDesklet->iTopSurfaceOffset, pDesklet->iRightSurfaceOffset, pDesklet->iBottomSurfaceOffset, fZoomX, fZoomY);
}
void gldi_desklet_decoration_free (CairoDeskletDecoration *pDecoration)
{
if (pDecoration == NULL)
return ;
g_free (pDecoration->cBackGroundImagePath);
g_free (pDecoration->cForeGroundImagePath);
g_free (pDecoration);
}
////////////////
/// FACILITY ///
////////////////
void gldi_desklet_add_interactive_widget_with_margin (CairoDesklet *pDesklet, GtkWidget *pInteractiveWidget, int iRightMargin)
{
g_return_if_fail (pDesklet != NULL && pInteractiveWidget != NULL);
if (pDesklet->pInteractiveWidget != NULL || gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget)) != NULL)
{
cd_warning ("This desklet already has an interactive widget !");
return;
}
//gtk_container_add (GTK_CONTAINER (pDesklet->container.pWidget), pInteractiveWidget);
GtkWidget *pHBox = _gtk_hbox_new (0);
gtk_container_add (GTK_CONTAINER (pDesklet->container.pWidget), pHBox);
gtk_box_pack_start (GTK_BOX (pHBox), pInteractiveWidget, TRUE, TRUE, 0);
pDesklet->pInteractiveWidget = pInteractiveWidget;
if (iRightMargin != 0)
{
GtkWidget *pMarginBox = _gtk_vbox_new (0);
g_object_set (pMarginBox, "width-request", iRightMargin, NULL);
gtk_box_pack_start (GTK_BOX (pHBox), pMarginBox, FALSE, FALSE, 0); // a tester ...
}
gtk_widget_show_all (pHBox);
}
void gldi_desklet_set_margin (CairoDesklet *pDesklet, int iRightMargin)
{
g_return_if_fail (pDesklet != NULL && pDesklet->pInteractiveWidget != NULL);
GtkWidget *pHBox = gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget));
if (pHBox && pHBox != pDesklet->pInteractiveWidget) // precaution.
{
GList *pChildList = gtk_container_get_children (GTK_CONTAINER (pHBox));
if (pChildList != NULL)
{
if (pChildList->next != NULL)
{
GtkWidget *pMarginBox = GTK_WIDGET (pChildList->next->data);
g_object_set (pMarginBox, "width-request", iRightMargin, NULL);
}
else // on rajoute le widget de la marge.
{
GtkWidget *pMarginBox = _gtk_vbox_new (0);
g_object_set (pMarginBox, "width-request", iRightMargin, NULL);
gtk_box_pack_start (GTK_BOX (pHBox), pMarginBox, FALSE, FALSE, 0);
}
g_list_free (pChildList);
}
}
}
GtkWidget *gldi_desklet_steal_interactive_widget (CairoDesklet *pDesklet)
{
if (pDesklet == NULL)
return NULL;
GtkWidget *pInteractiveWidget = pDesklet->pInteractiveWidget;
if (pInteractiveWidget != NULL)
{
pInteractiveWidget = cairo_dock_steal_widget_from_its_container (pInteractiveWidget);
pDesklet->pInteractiveWidget = NULL;
GtkWidget *pBox = gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget));
if (pBox != NULL)
gtk_widget_destroy (pBox);
}
return pInteractiveWidget;
}
void gldi_desklet_hide (CairoDesklet *pDesklet)
{
if (pDesklet)
{
pDesklet->bAllowMinimize = TRUE;
gtk_widget_hide (pDesklet->container.pWidget);
}
}
void gldi_desklet_show (CairoDesklet *pDesklet)
{
if (pDesklet)
{
gtk_window_present(GTK_WINDOW(pDesklet->container.pWidget));
gtk_window_move (GTK_WINDOW(pDesklet->container.pWidget), pDesklet->container.iWindowPositionX, pDesklet->container.iWindowPositionY); // sinon le WM le place n'importe ou.
}
}
static void _reserve_space_for_desklet (CairoDesklet *pDesklet, gboolean bReserve)
{
cd_debug ("%s (%d)", __func__, bReserve);
int left=0, right=0, top=0, bottom=0;
int left_start_y=0, left_end_y=0, right_start_y=0, right_end_y=0, top_start_x=0, top_end_x=0, bottom_start_x=0, bottom_end_x=0;
int iHeight = pDesklet->container.iHeight, iWidth = pDesklet->container.iWidth;
int iX = pDesklet->container.iWindowPositionX, iY = pDesklet->container.iWindowPositionY;
if (bReserve)
{
int iTopOffset, iBottomOffset, iRightOffset, iLeftOffset;
iTopOffset = iY;
iBottomOffset = gldi_desktop_get_height() - 1 - (iY + iHeight);
iLeftOffset = iX;
iRightOffset = gldi_desktop_get_width() - 1 - (iX + iWidth);
if (iBottomOffset < MIN (iLeftOffset, iRightOffset)) // en bas.
{
bottom = iHeight + iBottomOffset;
bottom_start_x = iX;
bottom_end_x = iX + iWidth;
}
else if (iTopOffset < MIN (iLeftOffset, iRightOffset)) // en haut.
{
top = iHeight + iTopOffset;
top_start_x = iX;
top_end_x = iX + iWidth;
}
else if (iLeftOffset < iRightOffset) // a gauche.
{
left = iWidth + iLeftOffset;
left_start_y = iY;
left_end_y = iY + iHeight;
}
else // a droite.
{
right = iWidth + iRightOffset;
right_start_y = iY;
right_end_y = iY + iHeight;
}
}
gldi_container_reserve_space (CAIRO_CONTAINER(pDesklet), left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x);
pDesklet->bSpaceReserved = bReserve;
}
void gldi_desklet_set_accessibility (CairoDesklet *pDesklet, CairoDeskletVisibility iVisibility, gboolean bSaveState)
{
cd_debug ("%s (%d)", __func__, iVisibility);
//\_________________ On applique la nouvelle accessibilite.
gtk_window_set_keep_below (GTK_WINDOW (pDesklet->container.pWidget), iVisibility == CAIRO_DESKLET_KEEP_BELOW);
gtk_window_set_keep_above (GTK_WINDOW (pDesklet->container.pWidget), iVisibility == CAIRO_DESKLET_KEEP_ABOVE);
if (iVisibility == CAIRO_DESKLET_ON_WIDGET_LAYER)
{
if (pDesklet->iVisibility != CAIRO_DESKLET_ON_WIDGET_LAYER)
gldi_desktop_set_on_widget_layer (CAIRO_CONTAINER (pDesklet), TRUE);
}
else if (pDesklet->iVisibility == CAIRO_DESKLET_ON_WIDGET_LAYER)
{
gldi_desktop_set_on_widget_layer (CAIRO_CONTAINER (pDesklet), FALSE);
}
if (iVisibility == CAIRO_DESKLET_RESERVE_SPACE)
{
if (! pDesklet->bSpaceReserved)
_reserve_space_for_desklet (pDesklet, TRUE); // sinon inutile de le refaire, s'il y'a un changement de taille ce sera fait lors du configure-event.
}
else if (pDesklet->bSpaceReserved)
{
_reserve_space_for_desklet (pDesklet, FALSE);
}
//\_________________ On enregistre le nouvel etat.
pDesklet->iVisibility = iVisibility;
Icon *icon = pDesklet->pIcon;
if (bSaveState && CAIRO_DOCK_IS_APPLET (icon))
cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
G_TYPE_INT, "Desklet", "accessibility", iVisibility,
G_TYPE_INVALID);
}
void gldi_desklet_set_sticky (CairoDesklet *pDesklet, gboolean bSticky)
{
//g_print ("%s (%d)\n", __func__, bSticky);
int iNumDesktop;
if (bSticky)
{
gtk_window_stick (GTK_WINDOW (pDesklet->container.pWidget));
iNumDesktop = -1;
}
else
{
gtk_window_unstick (GTK_WINDOW (pDesklet->container.pWidget));
int iCurrentDesktop, iCurrentViewportX, iCurrentViewportY;
gldi_desktop_get_current (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
iNumDesktop = iCurrentDesktop * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportY;
cd_debug (">>> on colle ce desklet sur le bureau %d", iNumDesktop);
}
//\_________________ On enregistre le nouvel etat.
Icon *icon = pDesklet->pIcon;
if (CAIRO_DOCK_IS_APPLET (icon))
cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
G_TYPE_BOOLEAN, "Desklet", "sticky", bSticky,
G_TYPE_INT, "Desklet", "num desktop", iNumDesktop,
G_TYPE_INVALID);
}
gboolean gldi_desklet_is_sticky (CairoDesklet *pDesklet)
{
GdkWindow *window = gldi_container_get_gdk_window (CAIRO_CONTAINER (pDesklet));
#if (GTK_MAJOR_VERSION >= 3)
return ((gdk_window_get_state (window)) & GDK_WINDOW_STATE_STICKY);
#else
return (((GdkWindowObject*) window)->state & GDK_WINDOW_STATE_STICKY);
#endif
}
void gldi_desklet_lock_position (CairoDesklet *pDesklet, gboolean bPositionLocked)
{
//g_print ("%s (%d)\n", __func__, bPositionLocked);
pDesklet->bPositionLocked = bPositionLocked;
//\_________________ On enregistre le nouvel etat.
Icon *icon = pDesklet->pIcon;
if (CAIRO_DOCK_IS_APPLET (icon))
cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
G_TYPE_BOOLEAN, "Desklet", "locked", pDesklet->bPositionLocked,
G_TYPE_INVALID);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-desktop-manager.c 000664 001750 001750 00000024461 12223247550 024031 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include "cairo-dock-log.h"
#include "cairo-dock-desklet-manager.h" // cairo_dock_foreach_desklet
#include "cairo-dock-desklet-factory.h"
#include "cairo-dock-draw-opengl.h" // cairo_dock_create_texture_from_surface
#include "cairo-dock-compiz-integration.h"
#include "cairo-dock-kwin-integration.h"
#include "cairo-dock-gnome-shell-integration.h"
#include "cairo-dock-cinnamon-integration.h"
#define _MANAGER_DEF_
#include "cairo-dock-desktop-manager.h"
// public (manager, config, data)
GldiManager myDesktopMgr;
GldiDesktopGeometry g_desktopGeometry;
// dependancies
extern GldiContainer *g_pPrimaryContainer;
// private
static GldiDesktopBackground *s_pDesktopBg = NULL; // une fois alloue, le pointeur restera le meme tout le temps.
static GldiDesktopManagerBackend s_backend;
static void _reload_desktop_background (void);
//////////////////////
/// desktop access ///
//////////////////////
void gldi_desktop_get_current (int *iCurrentDesktop, int *iCurrentViewportX, int *iCurrentViewportY)
{
*iCurrentDesktop = g_desktopGeometry.iCurrentDesktop;
*iCurrentViewportX = g_desktopGeometry.iCurrentViewportX;
*iCurrentViewportY = g_desktopGeometry.iCurrentViewportY;
}
//////////////////////////////
/// DESKTOP MANAGER BACKEND ///
//////////////////////////////
static gboolean _set_desklets_on_widget_layer (CairoDesklet *pDesklet, G_GNUC_UNUSED gpointer data)
{
if (pDesklet->iVisibility == CAIRO_DESKLET_ON_WIDGET_LAYER)
gldi_desktop_set_on_widget_layer (CAIRO_CONTAINER (pDesklet), TRUE);
return FALSE; // continue
}
void gldi_desktop_manager_register_backend (GldiDesktopManagerBackend *pBackend)
{
gpointer *ptr = (gpointer*)&s_backend;
gpointer *src = (gpointer*)pBackend;
gpointer *src_end = (gpointer*)(pBackend + 1);
while (src != src_end)
{
if (*src != NULL)
*ptr = *src;
src ++;
ptr ++;
}
// since we have a backend, set up the desklets that are supposed to be on the widget layer.
if (s_backend.set_on_widget_layer != NULL)
{
gldi_desklets_foreach ((GldiDeskletForeachFunc) _set_desklets_on_widget_layer, NULL);
}
}
gboolean gldi_desktop_present_class (const gchar *cClass) // scale matching class
{
g_return_val_if_fail (cClass != NULL, FALSE);
if (s_backend.present_class != NULL)
{
return s_backend.present_class (cClass);
}
return FALSE;
}
gboolean gldi_desktop_present_windows (void) // scale
{
if (s_backend.present_windows != NULL)
{
return s_backend.present_windows ();
}
return FALSE;
}
gboolean gldi_desktop_present_desktops (void) // expose
{
if (s_backend.present_desktops != NULL)
{
return s_backend.present_desktops ();
}
return FALSE;
}
gboolean gldi_desktop_show_widget_layer (void) // widget
{
if (s_backend.show_widget_layer != NULL)
{
return s_backend.show_widget_layer ();
}
return FALSE;
}
gboolean gldi_desktop_set_on_widget_layer (GldiContainer *pContainer, gboolean bOnWidgetLayer)
{
if (s_backend.set_on_widget_layer != NULL)
{
return s_backend.set_on_widget_layer (pContainer, bOnWidgetLayer);
}
return FALSE;
}
gboolean gldi_desktop_can_present_class (void)
{
return (s_backend.present_class != NULL);
}
gboolean gldi_desktop_can_present_windows (void)
{
return (s_backend.present_windows != NULL);
}
gboolean gldi_desktop_can_present_desktops (void)
{
return (s_backend.present_desktops != NULL);
}
gboolean gldi_desktop_can_show_widget_layer (void)
{
return (s_backend.show_widget_layer != NULL);
}
gboolean gldi_desktop_can_set_on_widget_layer (void)
{
return (s_backend.set_on_widget_layer != NULL);
}
gboolean gldi_desktop_show_hide (gboolean bShow)
{
if (s_backend.show_hide_desktop)
{
s_backend.show_hide_desktop (bShow);
return TRUE;
}
return FALSE;
}
gboolean gldi_desktop_is_visible (void)
{
if (s_backend.desktop_is_visible)
return s_backend.desktop_is_visible ();
return FALSE; // default state = not visible
}
gchar** gldi_desktop_get_names (void)
{
if (s_backend.get_desktops_names)
return s_backend.get_desktops_names ();
return NULL;
}
gboolean gldi_desktop_set_names (gchar **cNames)
{
if (s_backend.set_desktops_names)
return s_backend.set_desktops_names (cNames);
return FALSE;
}
static cairo_surface_t *_get_desktop_bg_surface (void)
{
if (s_backend.get_desktop_bg_surface)
return s_backend.get_desktop_bg_surface ();
return NULL;
}
gboolean gldi_desktop_set_current (int iDesktopNumber, int iViewportNumberX, int iViewportNumberY)
{
if (s_backend.set_current_desktop)
return s_backend.set_current_desktop (iDesktopNumber, iViewportNumberX, iViewportNumberY);
return FALSE;
}
gboolean gldi_desktop_set_nb_desktops (int iNbDesktops, int iNbViewportX, int iNbViewportY)
{
if (s_backend.set_nb_desktops)
return s_backend.set_nb_desktops (iNbDesktops, iNbViewportX, iNbViewportY);
return FALSE;
}
void gldi_desktop_refresh (void)
{
if (s_backend.refresh)
s_backend.refresh ();
}
void gldi_desktop_notify_startup (const gchar *cClass)
{
if (s_backend.notify_startup)
s_backend.notify_startup (cClass);
}
//////////////////
/// DESKTOP BG ///
//////////////////
GldiDesktopBackground *gldi_desktop_background_get (gboolean bWithTextureToo)
{
//g_print ("%s (%d, %d)\n", __func__, bWithTextureToo, s_pDesktopBg?s_pDesktopBg->iRefCount:-1);
if (s_pDesktopBg == NULL)
{
s_pDesktopBg = g_new0 (GldiDesktopBackground, 1);
}
if (s_pDesktopBg->pSurface == NULL)
{
s_pDesktopBg->pSurface = _get_desktop_bg_surface ();
}
if (s_pDesktopBg->iTexture == 0 && bWithTextureToo)
{
s_pDesktopBg->iTexture = cairo_dock_create_texture_from_surface (s_pDesktopBg->pSurface);
}
s_pDesktopBg->iRefCount ++;
if (s_pDesktopBg->iSidDestroyBg != 0)
{
//g_print ("cancel pending destroy\n");
g_source_remove (s_pDesktopBg->iSidDestroyBg);
s_pDesktopBg->iSidDestroyBg = 0;
}
return s_pDesktopBg;
}
static gboolean _destroy_bg (GldiDesktopBackground *pDesktopBg)
{
//g_print ("%s ()\n", __func__);
g_return_val_if_fail (pDesktopBg != NULL, 0);
if (pDesktopBg->pSurface != NULL)
{
cairo_surface_destroy (pDesktopBg->pSurface);
pDesktopBg->pSurface = NULL;
//g_print ("--- surface destroyed\n");
}
if (pDesktopBg->iTexture != 0)
{
_cairo_dock_delete_texture (pDesktopBg->iTexture);
pDesktopBg->iTexture = 0;
}
pDesktopBg->iSidDestroyBg = 0;
return FALSE;
}
void gldi_desktop_background_destroy (GldiDesktopBackground *pDesktopBg)
{
//g_print ("%s ()\n", __func__);
g_return_if_fail (pDesktopBg != NULL);
if (pDesktopBg->iRefCount > 0)
pDesktopBg->iRefCount --;
if (pDesktopBg->iRefCount == 0 && pDesktopBg->iSidDestroyBg == 0)
{
//g_print ("add pending destroy\n");
pDesktopBg->iSidDestroyBg = g_timeout_add_seconds (3, (GSourceFunc)_destroy_bg, pDesktopBg);
}
}
cairo_surface_t *gldi_desktop_background_get_surface (GldiDesktopBackground *pDesktopBg)
{
g_return_val_if_fail (pDesktopBg != NULL, NULL);
return pDesktopBg->pSurface;
}
GLuint gldi_desktop_background_get_texture (GldiDesktopBackground *pDesktopBg)
{
g_return_val_if_fail (pDesktopBg != NULL, 0);
return pDesktopBg->iTexture;
}
static void _reload_desktop_background (void)
{
//g_print ("%s ()\n", __func__);
if (s_pDesktopBg == NULL) // rien a recharger.
return ;
if (s_pDesktopBg->pSurface == NULL && s_pDesktopBg->iTexture == 0) // rien a recharger.
return ;
if (s_pDesktopBg->pSurface != NULL)
{
cairo_surface_destroy (s_pDesktopBg->pSurface);
//g_print ("--- surface destroyed\n");
}
s_pDesktopBg->pSurface = _get_desktop_bg_surface ();
if (s_pDesktopBg->iTexture != 0)
{
_cairo_dock_delete_texture (s_pDesktopBg->iTexture);
s_pDesktopBg->iTexture = cairo_dock_create_texture_from_surface (s_pDesktopBg->pSurface);
}
}
//////////////
/// UNLOAD ///
//////////////
static void unload (void)
{
/*if (s_pDesktopBg != NULL && s_pDesktopBg->iTexture != 0)
{
_cairo_dock_delete_texture (s_pDesktopBg->iTexture);
s_pDesktopBg->iTexture = 0;
}*/
if (s_pDesktopBg) // on decharge le desktop-bg de force.
{
if (s_pDesktopBg->iSidDestroyBg != 0)
{
g_source_remove (s_pDesktopBg->iSidDestroyBg);
s_pDesktopBg->iSidDestroyBg = 0;
}
s_pDesktopBg->iRefCount = 0;
_destroy_bg (s_pDesktopBg); // detruit ses ressources immediatement, mais pas le pointeur.
}
}
static gboolean on_wallpaper_changed (G_GNUC_UNUSED gpointer data)
{
_reload_desktop_background ();
return GLDI_NOTIFICATION_LET_PASS;
}
////////////
/// INIT ///
////////////
static void init (void)
{
//\__________________ Init the Window Manager backends.
cd_init_compiz_backend ();
cd_init_kwin_backend ();
cd_init_gnome_shell_backend ();
cd_init_cinnamon_backend ();
}
///////////////
/// MANAGER ///
///////////////
void gldi_register_desktop_manager (void)
{
// Manager
memset (&myDesktopMgr, 0, sizeof (GldiManager));
gldi_object_init (GLDI_OBJECT(&myDesktopMgr), &myManagerObjectMgr, NULL);
myDesktopMgr.cModuleName = "Desktop";
// interface
myDesktopMgr.init = init;
myDesktopMgr.load = NULL;
myDesktopMgr.unload = unload;
myDesktopMgr.reload = (GldiManagerReloadFunc)NULL;
myDesktopMgr.get_config = (GldiManagerGetConfigFunc)NULL;
myDesktopMgr.reset_config = (GldiManagerResetConfigFunc)NULL;
// Config
myDesktopMgr.pConfig = (GldiManagerConfigPtr)NULL;
myDesktopMgr.iSizeOfConfig = 0;
// data
myDesktopMgr.iSizeOfData = 0;
myDesktopMgr.pData = (GldiManagerDataPtr)NULL;
memset (&s_backend, 0, sizeof (GldiDesktopManagerBackend));
// signals
gldi_object_install_notifications (&myDesktopMgr, NB_NOTIFICATIONS_DESKTOP); // we don't have a Desktop Object, so let's put the signals here
// init
gldi_object_register_notification (&myDesktopMgr,
NOTIFICATION_DESKTOP_WALLPAPER_CHANGED,
(GldiNotificationFunc) on_wallpaper_changed,
GLDI_RUN_FIRST, NULL);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-applet-multi-instance.h 000664 001750 001750 00000003564 12223247550 025175 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_APPLET_MULTI_INSTANCE__
#define __CAIRO_DOCK_APPLET_MULTI_INSTANCE__
#define CD_APPLET_DEFINE_BEGIN(cName, iMajorVersion, iMinorVersion, iMicroVersion, iAppletCategory, cDescription, cAuthor) \
CD_APPLET_DEFINE_ALL_BEGIN (cName, iMajorVersion, iMinorVersion, iMicroVersion, iAppletCategory, cDescription, cAuthor) \
pVisitCard->bMultiInstance = TRUE;
#define CD_APPLET_INIT_BEGIN CD_APPLET_INIT_ALL_BEGIN (myApplet)
#define myIcon myApplet->pIcon
#define myContainer myApplet->pContainer
#define myDock myApplet->pDock
#define myDesklet myApplet->pDesklet
#define myDrawContext myApplet->pDrawContext
#define myConfigPtr ((AppletConfig *)myApplet->pConfig)
#define myConfig (*myConfigPtr)
#define myDataPtr ((AppletData *)myApplet->pData)
#define myData (*myDataPtr)
#define CD_APPLET_RELOAD_BEGIN CD_APPLET_RELOAD_ALL_BEGIN
#define CD_APPLET_RESET_DATA_END CD_APPLET_RESET_DATA_ALL_END
#define CD_APPLET_RESET_CONFIG_BEGIN CD_APPLET_RESET_CONFIG_ALL_BEGIN
#define CD_APPLET_RESET_CONFIG_END CD_APPLET_RESET_CONFIG_ALL_END
#define CD_APPLET_GET_CONFIG_BEGIN CD_APPLET_GET_CONFIG_ALL_BEGIN
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-icon-factory.h 000664 001750 001750 00000026623 12223247550 023354 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_ICON_FACTORY__
#define __CAIRO_DOCK_ICON_FACTORY__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-image-buffer.h"
#include "cairo-dock-object.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-icon-factory.h This class defines the items contained in containers : Icons.
* An icon can either be:
* - a launcher (it has a command, a class, and possible an X window ID)
* - an appli (it has a X window ID and a class, no command)
* - an applet (it has a module instance and no command, possibly a class)
* - a container (it has a sub-dock and no class nor command)
* - a class icon (it has a bsub-dock and a class, but no command nor X ID)
* - a separator (it has nothing)
*
* The class defines the methods used to create a generic Icon and to load its various buffers.
* Specialized Icons are created by the corresponding factory.
*/
/// Available groups of icons.
typedef enum {
CAIRO_DOCK_LAUNCHER = 0, // launchers and applets, and applis if mixed
CAIRO_DOCK_SEPARATOR12,
CAIRO_DOCK_APPLI,
CAIRO_DOCK_NB_GROUPS
} CairoDockIconGroup;
/// Animation state of an icon, sorted by priority.
typedef enum {
CAIRO_DOCK_STATE_REST = 0,
CAIRO_DOCK_STATE_MOUSE_HOVERED,
CAIRO_DOCK_STATE_CLICKED,
CAIRO_DOCK_STATE_AVOID_MOUSE,
CAIRO_DOCK_STATE_FOLLOW_MOUSE,
CAIRO_DOCK_STATE_REMOVE_INSERT,
CAIRO_DOCK_NB_STATES
} CairoDockAnimationState;
/// Icon's interface
struct _IconInterface {
/// function that loads the icon surface (and optionnally texture).
void (*load_image) (Icon *icon);
/// function called when the user drag something over the icon for more than 500ms.
void (*action_on_drag_hover) (Icon *icon);
};
/// Definition of an Icon.
struct _Icon {
//\____________ Definition.
/// object
GldiObject object;
gpointer pDataSlot[CAIRO_DOCK_NB_DATA_SLOT];
/// group of the icon.
CairoDockIconGroup iGroup;
/// interface
IconInterface iface;
GldiContainer *pContainer; // container where the icon is currently.
//\____________ properties.
// generic.
/// Name of the icon.
gchar *cName;
/// Short info displayed on the icon (few characters).
gchar *cQuickInfo;
/// name or path of an image displayed on the icon.
gchar *cFileName;
/// Class of application the icon will be bound to.
gchar *cClass;
/// name of the dock the icon belongs to (NULL means it's not currently inside a dock).
gchar *cParentDockName;
/// Sub-dock the icon is pointing to.
CairoDock *pSubDock;
/// Order of the icon amongst the other icons of its group.
gdouble fOrder;
gint iSpecificDesktop;
gint iSubdockViewType;
/// a hint to indicate the icon should be kept static (no animation like bouncing).
gboolean bStatic;
/// a flag that allows the icon to be always visible, even when the dock is hidden.
gboolean bAlwaysVisible;
gboolean bIsDemandingAttention;
gboolean bHasHiddenBg;
gdouble *pHiddenBgColor; // NULL to use the default color
gboolean bIgnoreQuicklist; // TRUE to not display the Ubuntu's quicklist of the class
gboolean bHasIndicator;
// Launcher.
gchar *cDesktopFileName; // nom (et non pas chemin) du fichier .desktop
gchar *cCommand;
gchar *cWorkingDirectory;
gchar *cBaseURI;
gint iVolumeID;
gchar **pMimeTypes;
gchar *cWmClass;
gchar *cInitialName;
// Appli.
GldiWindowActor *pAppli;
// Applet.
GldiModuleInstance *pModuleInstance;
GldiModuleInstance *pAppletOwner;
//\____________ Buffers.
gdouble fWidth, fHeight; // size at rest in the container (including ratio and orientation).
gint iRequestedWidth, iRequestedHeight; // buffer image size that can be requested (surface/texture size)
gint iRequestedDisplayWidth, iRequestedDisplayHeight; // icon size that can be requested (as displayed in the dock)
gint iAllocatedWidth, iAllocatedHeight; // buffer image size actually allocated (surface/texture size)
CairoDockImageBuffer image; // the image of the icon
CairoDockImageBuffer label; // the label above the icon
GList *pOverlays; // a list of CairoOverlay
CairoDataRenderer *pDataRenderer;
CairoDockTransition *pTransition;
//\____________ Drawing parameters.
gdouble fXMin, fXMax; // Abscisse extremale gauche/droite que the icon atteindra (variable avec la vague).
gdouble fXAtRest; // Abscisse de the icon au repos.
gdouble fPhase; // Phase de the icon (entre -pi et piconi).
gdouble fX, fY; // Abscisse/Ordonnee temporaire du bord haut-gauche de l'image de the icon.
gdouble fScale;
gdouble fDrawX, fDrawY;
gdouble fWidthFactor, fHeightFactor;
gdouble fAlpha;
gdouble fDeltaYReflection; // Decalage en ordonnees du reflet (rebond).
gdouble fOrientation; // par rapport a la verticale Oz
gint iRotationX; // Rotation autour de l'axe Ox
gint iRotationY; // Rotation autour de l'axe Oy
gdouble fReflectShading;
gdouble fGlideOffset; // decalage pour le glissement des icons.
gint iGlideDirection; // direction dans laquelle glisse the icon.
gdouble fGlideScale; // echelle d'adaptation au glissement.
CairoDockAnimationState iAnimationState;
/// Whether the icon is currently pointed or not.
gboolean bPointed;
gdouble fInsertRemoveFactor;
gboolean bDamaged; // TRUE when the icon couldn't draw its surface, because the Gl context was not yet ready.
gboolean bNeedApplyBackground;
//\____________ Other dynamic parameters.
guint iSidRedrawSubdockContent;
guint iSidLoadImage;
guint iSidDoubleClickDelay;
gint iNbDoubleClickListeners;
gint iHideLabel;
gint iThumbnailX, iThumbnailY; // X icon geometry for apps
gint iThumbnailWidth, iThumbnailHeight;
gboolean bIsLaunching; // a mere recopy of gldi_class_is_starting()
gpointer reserved[4];
};
typedef void (*CairoIconContainerLoadFunc) (void);
typedef void (*CairoIconContainerUnloadFunc) (void);
typedef void (*CairoIconContainerRenderFunc) (Icon *pIcon, GldiContainer *pContainer, int w, int h, cairo_t *pCairoContext);
typedef void (*CairoIconContainerRenderOpenGLFunc) (Icon *pIcon, GldiContainer *pContainer, int w, int h);
/// Definition of an Icon container (= an icon holding a sub-dock) renderer.
struct _CairoIconContainerRenderer {
CairoIconContainerLoadFunc load;
CairoIconContainerUnloadFunc unload;
CairoIconContainerRenderFunc render;
CairoIconContainerRenderOpenGLFunc render_opengl;
};
/** Say if an object is an Icon.
*@param obj the object.
*@return TRUE if the object is an icon.
*/
#define CAIRO_DOCK_IS_ICON(obj) gldi_object_is_manager_child (obj, &myIconObjectMgr)
#define CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER GLDI_OBJECT_IS_LAUNCHER_ICON
#define CAIRO_DOCK_ICON_TYPE_IS_CONTAINER GLDI_OBJECT_IS_STACK_ICON
#define CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR GLDI_OBJECT_IS_SEPARATOR_ICON
#define CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER GLDI_OBJECT_IS_CLASS_ICON
#define CAIRO_DOCK_ICON_TYPE_IS_APPLI GLDI_OBJECT_IS_APPLI_ICON
#define CAIRO_DOCK_ICON_TYPE_IS_APPLET GLDI_OBJECT_IS_APPLET_ICON
/** TRUE if the icon holds a window.
*@param icon an icon.
*/
#define CAIRO_DOCK_IS_APPLI(icon) (icon != NULL && (icon)->pAppli != NULL)
/** TRUE if the icon holds an instance of a module.
*@param icon an icon.
*/
#define CAIRO_DOCK_IS_APPLET(icon) (icon != NULL && (icon)->pModuleInstance != NULL)
/** TRUE if the icon is an icon pointing on the sub-dock of a class.
*@param icon an icon.
*/
#define CAIRO_DOCK_IS_MULTI_APPLI(icon) (\
( CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (icon)\
|| CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (icon)\
|| (CAIRO_DOCK_ICON_TYPE_IS_APPLET (icon) && icon->cClass != NULL) )\
&& icon->pSubDock != NULL)
/** TRUE if the icon is an automatic separator.
*@param icon an icon.
*/
#define CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR(icon) (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) && (icon)->cDesktopFileName == NULL)
/** TRUE if the icon is a separator added by the user.
*@param icon an icon.
*/
#define CAIRO_DOCK_IS_USER_SEPARATOR(icon) (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) && (icon)->cDesktopFileName != NULL)
/**
*TRUE if the icon is an icon d'appli only.
*@param icon an icon.
*/
#define CAIRO_DOCK_IS_NORMAL_APPLI(icon) (CAIRO_DOCK_IS_APPLI (icon) && CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon))
/**
*TRUE if the icon is an icon d'applet detachable en desklet.
*@param icon an icon.
*/
#define CAIRO_DOCK_IS_DETACHABLE_APPLET(icon) (CAIRO_DOCK_IS_APPLET (icon) && ((icon)->pModuleInstance->pModule->pVisitCard->iContainerType & CAIRO_DOCK_MODULE_CAN_DESKLET))
/** Create an empty icon.
*@return the newly allocated icon object.
*/
Icon *gldi_icon_new (void);
/** Create an Icon that will behave like a launcher. It's especially useful for applets that want to fill a sub-dock or a desklet (the icon is not loaded by the function). Be careful that the strings are not duplicated. Therefore, you must use g_strdup() if you want to set a constant string; and must not free the strings after calling this function.
* @param cName label of the icon
* @param cFileName name of an image
* @param cCommand a command, or NULL
* @param cQuickInfo a quick-info, or NULL
* @param fOrder order of the icon in its container.
* @return the newly created icon.
*/
Icon * cairo_dock_create_dummy_launcher (gchar *cName, gchar *cFileName, gchar *cCommand, gchar *cQuickInfo, double fOrder);
/* Cree la surface de reflection d'une icone (pour cairo).
*@param pIcon l'icone.
*@param pContainer le container de l'icone.
*/
void cairo_dock_add_reflection_to_icon (Icon *pIcon, GldiContainer *pContainer);
gboolean cairo_dock_apply_icon_background_opengl (Icon *icon);
/**Fill the image buffer (surface & texture) of a given icon, according to its type. Set its size if necessary, and fills the reflection buffer for cairo.
*@param icon the icon.
*@param pContainer its container.
*/
void cairo_dock_load_icon_image (Icon *icon, GldiContainer *pContainer);
#define cairo_dock_reload_icon_image cairo_dock_load_icon_image
/**Fill the label buffer (surface & texture) of a given icon, according to a text description.
*@param icon the icon.
*/
void cairo_dock_load_icon_text (Icon *icon);
/**Fill the quick-info buffer (surface & texture) of a given icon, according to a text description.
*@param icon the icon.
*/
void cairo_dock_load_icon_quickinfo (Icon *icon);
/** Fill all the buffers (surfaces & textures) of a given icon, according to its type. Set its size accordingly, and fills the reflection buffer for cairo. Label and quick-info are loaded with the current global text description.
*@param pIcon the icon.
*@param pContainer its container.
*/
void cairo_dock_load_icon_buffers (Icon *pIcon, GldiContainer *pContainer);
void cairo_dock_trigger_load_icon_buffers (Icon *pIcon);
void cairo_dock_draw_subdock_content_on_icon (Icon *pIcon, CairoDock *pDock);
#define cairo_dock_set_subdock_content_renderer(pIcon, view) (pIcon)->iSubdockViewType = view
void gldi_icon_detach (Icon *pIcon);
void gldi_icon_insert_in_container (Icon *pIcon, GldiContainer *pContainer, gboolean bAnimateIcon);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-application-facility.c 000664 001750 001750 00000056063 12223247550 025060 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include "cairo-dock-icon-facility.h" // gldi_icon_set_name
#include "cairo-dock-dialog-factory.h"
#include "cairo-dock-animations.h"
#include "cairo-dock-surface-factory.h"
#include "cairo-dock-applications-manager.h"
#include "cairo-dock-launcher-manager.h"
#include "cairo-dock-separator-manager.h"
#include "cairo-dock-applet-manager.h"
#include "cairo-dock-stack-icon-manager.h"
#include "cairo-dock-windows-manager.h"
#include "cairo-dock-log.h"
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-class-manager.h"
#include "cairo-dock-dock-facility.h" // cairo_dock_update_dock_size
#include "cairo-dock-desktop-manager.h"
#include "cairo-dock-indicator-manager.h" // myIndicatorsParam.bUseClassIndic
#include "cairo-dock-class-icon-manager.h" // gldi_class_icon_new
#include "cairo-dock-utils.h" // cairo_dock_launch_command_full
#include "cairo-dock-application-facility.h"
extern CairoDock *g_pMainDock;
extern CairoDockHidingEffect *g_pHidingBackend; // cairo_dock_is_hidden
extern GldiContainer *g_pPrimaryContainer;
static void _gldi_appli_icon_demands_attention (Icon *icon, CairoDock *pDock, gboolean bForceDemand, Icon *pHiddenIcon)
{
cd_debug ("%s (%s, force:%d)", __func__, icon->cName, bForceDemand);
if (CAIRO_DOCK_IS_APPLET (icon)) // on considere qu'une applet prenant le controle d'une icone d'appli dispose de bien meilleurs moyens pour interagir avec l'appli que la barre des taches.
return ;
//\____________________ On montre le dialogue.
if (myTaskbarParam.bDemandsAttentionWithDialog)
{
CairoDialog *pDialog;
if (pHiddenIcon == NULL)
{
pDialog = gldi_dialog_show_temporary_with_icon (icon->cName, icon, CAIRO_CONTAINER (pDock), 1000*myTaskbarParam.iDialogDuration, "same icon");
}
else
{
pDialog = gldi_dialog_show_temporary (pHiddenIcon->cName, icon, CAIRO_CONTAINER (pDock), 1000*myTaskbarParam.iDialogDuration); // mieux vaut montrer pas d'icone dans le dialogue que de montrer une icone qui n'a pas de rapport avec l'appli demandant l'attention.
g_return_if_fail (pDialog != NULL);
gldi_dialog_set_icon_surface (pDialog, pHiddenIcon->image.pSurface, pDialog->iIconSize);
}
if (pDialog && bForceDemand)
{
cd_debug ("force dock and dialog on top");
if (pDock->iRefCount == 0 && pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && pDock->bIsBelow)
cairo_dock_pop_up (pDock);
gtk_window_set_keep_above (GTK_WINDOW (pDialog->container.pWidget), TRUE);
gtk_window_set_type_hint (GTK_WINDOW (pDialog->container.pWidget), GDK_WINDOW_TYPE_HINT_DOCK); // pour passer devant les fenetres plein ecran; depend du WM.
}
}
//\____________________ On montre l'icone avec une animation.
if (myTaskbarParam.cAnimationOnDemandsAttention && ! pHiddenIcon) // on ne l'anime pas si elle n'est pas dans un dock.
{
if (pDock->iRefCount == 0)
{
if (bForceDemand)
{
if (pDock->iRefCount == 0 && pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && pDock->bIsBelow)
cairo_dock_pop_up (pDock);
}
}
/**else if (bForceDemand)
{
cd_debug ("force sub-dock to raise\n");
CairoDock *pParentDock = NULL;
Icon *pPointedIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
if (pParentDock)
cairo_dock_show_subdock (pPointedIcon, pParentDock);
}*/
gldi_icon_request_attention (icon, myTaskbarParam.cAnimationOnDemandsAttention, 10000); // animation de 2-3 heures.
}
}
void gldi_appli_icon_demands_attention (Icon *icon)
{
cd_debug ("%s (%s, %p)", __func__, icon->cName, cairo_dock_get_icon_container(icon));
if (icon->pAppli == gldi_windows_get_active()) // apparemment ce cas existe, et conduit a ne pas pouvoir stopper l'animation de demande d'attention facilement.
{
cd_message ("cette fenetre a deja le focus, elle ne peut demander l'attention en plus.");
return ;
}
gboolean bForceDemand = (myTaskbarParam.cForceDemandsAttention && icon->cClass && g_strstr_len (myTaskbarParam.cForceDemandsAttention, -1, icon->cClass));
CairoDock *pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (icon));
if (pParentDock == NULL) // appli inhibee ou non affichee.
{
Icon *pInhibitorIcon = cairo_dock_get_inhibitor (icon, TRUE); // on cherche son inhibiteur dans un dock.
if (pInhibitorIcon != NULL) // appli inhibee.
{
pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (pInhibitorIcon));
if (pParentDock != NULL) // if the inhibitor is hidden (detached), there is no way to remember what should be its animation, so just forget it (we could fix it when inserting the icon back into a container, by checking if its appli is demanding the attention)
_gldi_appli_icon_demands_attention (pInhibitorIcon, pParentDock, bForceDemand, NULL);
}
else if (bForceDemand) // appli pas affichee, mais on veut tout de meme etre notifie.
{
Icon *pOneIcon = gldi_icons_get_any_without_dialog (); // on prend une icone dans le main dock.
if (pOneIcon != NULL)
_gldi_appli_icon_demands_attention (pOneIcon, g_pMainDock, bForceDemand, icon);
}
}
else // appli dans un dock.
_gldi_appli_icon_demands_attention (icon, pParentDock, bForceDemand, NULL);
}
static void _gldi_appli_icon_stop_demanding_attention (Icon *icon, CairoDock *pDock)
{
if (CAIRO_DOCK_IS_APPLET (icon)) // cf remarque plus haut.
return ;
if (myTaskbarParam.bDemandsAttentionWithDialog)
gldi_dialogs_remove_on_icon (icon);
if (myTaskbarParam.cAnimationOnDemandsAttention)
{
gldi_icon_stop_attention (icon); // arrete l'animation precedemment lancee par la demande.
gtk_widget_queue_draw (pDock->container.pWidget); // optimisation possible : ne redessiner que l'icone en tenant compte de la zone de sa derniere animation (pulse ou rebond).
}
if (pDock->iRefCount == 0 && pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->bIsBelow && ! pDock->container.bInside)
cairo_dock_pop_down (pDock);
}
void gldi_appli_icon_stop_demanding_attention (Icon *icon)
{
CairoDock *pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (icon));
if (pParentDock == NULL) // inhibited
{
Icon *pInhibitorIcon = cairo_dock_get_inhibitor (icon, TRUE);
if (pInhibitorIcon != NULL)
{
pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (pInhibitorIcon));
if (pParentDock != NULL)
_gldi_appli_icon_stop_demanding_attention (pInhibitorIcon, pParentDock);
}
}
else
_gldi_appli_icon_stop_demanding_attention (icon, pParentDock);
}
void gldi_appli_icon_animate_on_active (Icon *icon, CairoDock *pParentDock)
{
g_return_if_fail (pParentDock != NULL);
if (! cairo_dock_icon_is_being_inserted_or_removed (icon)) // sinon on laisse l'animation actuelle.
{
if (myTaskbarParam.cAnimationOnActiveWindow)
{
if (cairo_dock_animation_will_be_visible (pParentDock) && icon->iAnimationState == CAIRO_DOCK_STATE_REST)
gldi_icon_request_animation (icon, myTaskbarParam.cAnimationOnActiveWindow, 1);
}
else
{
cairo_dock_redraw_icon (icon); // Si pas d'animation, on le fait pour redessiner l'indicateur.
}
if (pParentDock->iRefCount != 0) // l'icone est dans un sous-dock, on veut que l'indicateur soit aussi dessine sur l'icone pointant sur ce sous-dock.
{
CairoDock *pMainDock = NULL;
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pParentDock, &pMainDock);
if (pPointingIcon && pMainDock)
{
cairo_dock_redraw_icon (pPointingIcon); // on se contente de redessiner cette icone sans l'animer. Une facon comme une autre de differencier ces 2 cas.
}
}
}
}
// this function is used when we have an appli that is not inhibited. we can place it either in its subdock or in a dock next to an inhibitor or in the main dock amongst the other applis
static CairoDock *_get_parent_dock_for_appli (Icon *icon, CairoDock *pMainDock)
{
cd_message ("%s (%s)", __func__, icon->cName);
CairoDock *pParentDock = pMainDock;
if (CAIRO_DOCK_IS_APPLI (icon) && myTaskbarParam.bGroupAppliByClass && icon->cClass != NULL && ! cairo_dock_class_is_expanded (icon->cClass)) // if this is a valid appli and we want to group the classes.
{
Icon *pSameClassIcon = cairo_dock_get_classmate (icon); // un inhibiteur dans un dock avec appli ou subdock OU une appli de meme classe dans un dock != class-sub-dock.
if (pSameClassIcon == NULL) // aucun classmate => elle va dans son class sub-dock ou dans le main dock.
{
cd_message (" no classmate for %s", icon->cClass);
pParentDock = cairo_dock_get_class_subdock (icon->cClass);
if (pParentDock == NULL) // no class sub-dock => go to main dock
pParentDock = pMainDock;
}
else // on la met dans le sous-dock de sa classe.
{
//\____________ create the class sub-dock if necessary
pParentDock = cairo_dock_get_class_subdock (icon->cClass);
if (pParentDock == NULL) // no class sub-dock yet -> create it, and we'll link it to either pSameClassIcon or a class-icon.
{
cd_message (" creation du dock pour la classe %s", icon->cClass);
pMainDock = CAIRO_DOCK(cairo_dock_get_icon_container (pSameClassIcon));
pParentDock = cairo_dock_create_class_subdock (icon->cClass, pMainDock);
}
else
cd_message (" sous-dock de la classe %s existant", icon->cClass);
//\____________ link this sub-dock to the inhibitor, or to a fake appli icon.
if (GLDI_OBJECT_IS_LAUNCHER_ICON (pSameClassIcon) || GLDI_OBJECT_IS_APPLET_ICON (pSameClassIcon)) // it's an inhibitor
{
if (pSameClassIcon->pAppli != NULL) // actuellement l'inhibiteur inhibe 1 seule appli.
{
cd_debug ("actuellement l'inhibiteur inhibe 1 seule appli");
Icon *pInhibitedIcon = cairo_dock_get_appli_icon (pSameClassIcon->pAppli); // get the currently inhibited appli-icon; it will go into the class sub-dock with 'icon'
gldi_icon_unset_appli (pSameClassIcon); // on lui laisse par contre l'indicateur.
if (pSameClassIcon->pSubDock == NULL) // paranoia
{
if (pSameClassIcon->cInitialName != NULL)
gldi_icon_set_name (pSameClassIcon, pSameClassIcon->cInitialName); // on lui remet son nom de lanceur.
pSameClassIcon->pSubDock = pParentDock;
cairo_dock_redraw_icon (pSameClassIcon); // on la redessine car elle prend l'indicateur de classe.
}
else
cd_warning ("this launcher (%s) already has a subdock !", pSameClassIcon->cName);
if (pInhibitedIcon != NULL) // paranoia
{
cd_debug (" on insere %s dans le dock de la classe", pInhibitedIcon->cName);
gldi_icon_insert_in_container (pInhibitedIcon, CAIRO_CONTAINER(pParentDock), ! CAIRO_DOCK_ANIMATE_ICON);
}
else
cd_warning ("couldn't get the appli-icon for '%s' !", pSameClassIcon->cName);
}
else if (pSameClassIcon->pSubDock != pParentDock)
cd_warning ("this inhibitor doesn't hold the class sub-dock !");
}
else // it's an appli in a dock (not the class sub-dock)
{
//\______________ make a class-icon that will hold the class sub-dock
cd_debug (" on cree un fake...");
CairoDock *pClassMateParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (pSameClassIcon)); // c'est en fait le main dock.
if (!pClassMateParentDock) // if not yet in its dock (or hidden)
pClassMateParentDock = gldi_dock_get (pSameClassIcon->cParentDockName);
Icon *pFakeClassIcon = gldi_class_icon_new (pSameClassIcon, pParentDock);
//\______________ detach the classmate, and put it into the class sub-dock with 'icon'
cd_debug (" on detache %s pour la passer dans le sous-dock de sa classe", pSameClassIcon->cName);
gldi_icon_detach (pSameClassIcon);
gldi_icon_insert_in_container (pSameClassIcon, CAIRO_CONTAINER(pParentDock), ! CAIRO_DOCK_ANIMATE_ICON);
//\______________ put the class-icon in place of the clasmate
cd_debug (" on lui substitue le fake");
gldi_icon_insert_in_container (pFakeClassIcon, CAIRO_CONTAINER(pClassMateParentDock), ! CAIRO_DOCK_ANIMATE_ICON);
if (!myIndicatorsParam.bUseClassIndic)
cairo_dock_trigger_redraw_subdock_content_on_icon (pFakeClassIcon);
}
}
}
else /// TODO: look for an inhibitor or a classmate to go in its dock (it's not necessarily the main dock) ...
{
pParentDock = pMainDock;
}
return pParentDock;
}
CairoDock *gldi_appli_icon_insert_in_dock (Icon *icon, CairoDock *pMainDock, gboolean bAnimate)
{
if (! myTaskbarParam.bShowAppli)
return NULL;
cd_message ("%s (%s, %p)", __func__, icon->cName, icon->pAppli);
if (myTaskbarParam.bAppliOnCurrentDesktopOnly && ! gldi_window_is_on_current_desktop (icon->pAppli))
return NULL;
//\_________________ On gere ses eventuels inhibiteurs.
if (myTaskbarParam.bMixLauncherAppli && cairo_dock_prevent_inhibited_class (icon))
{
cd_message (" -> se fait inhiber");
return NULL;
}
//\_________________ On gere le filtre 'applis minimisees seulement'.
if (!icon->pAppli->bIsHidden && myTaskbarParam.bHideVisibleApplis)
{
gldi_appli_reserve_geometry_for_window_manager (icon->pAppli, icon, pMainDock); // on reserve la position de l'icone dans le dock pour que l'effet de minimisation puisse viser la bonne position avant que l'icone ne soit effectivement dans le dock.
return NULL;
}
//\_________________ On determine dans quel dock l'inserer (cree au besoin).
CairoDock *pParentDock = _get_parent_dock_for_appli (icon, pMainDock);
g_return_val_if_fail (pParentDock != NULL, NULL);
//\_________________ On l'insere dans son dock parent en animant ce dernier eventuellement.
if (myTaskbarParam.bMixLauncherAppli && pParentDock != cairo_dock_get_class_subdock (icon->cClass)) // this appli is amongst the launchers in the main dock
{
cairo_dock_set_class_order_in_dock (icon, pParentDock);
}
else // this appli is either in a different group or in the class sub-dock
{
cairo_dock_set_class_order_amongst_applis (icon, pParentDock);
}
gldi_icon_insert_in_container (icon, CAIRO_CONTAINER(pParentDock), bAnimate);
cd_message (" insertion de %s complete (%.2f %.2fx%.2f) dans %s", icon->cName, icon->fInsertRemoveFactor, icon->fWidth, icon->fHeight, gldi_dock_get_name(pParentDock));
if (bAnimate && cairo_dock_animation_will_be_visible (pParentDock))
{
cairo_dock_launch_animation (CAIRO_CONTAINER (pParentDock));
}
else
{
icon->fInsertRemoveFactor = 0;
icon->fScale = 1.;
}
return pParentDock;
}
CairoDock * gldi_appli_icon_detach (Icon *pIcon)
{
cd_debug ("%s (%s)", __func__, pIcon->cName);
CairoDock *pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (pIcon));
if (! GLDI_OBJECT_IS_DOCK (pParentDock))
return NULL;
gldi_icon_detach (pIcon);
if (pIcon->cClass != NULL && pParentDock == cairo_dock_get_class_subdock (pIcon->cClass)) // is in the sub-dock class -> check if we must destroy it.
{
gboolean bEmptyClassSubDock = cairo_dock_check_class_subdock_is_empty (pParentDock, pIcon->cClass);
if (bEmptyClassSubDock) // has been destroyed.
return NULL;
}
return pParentDock;
}
#define x_icon_geometry(icon, pDock) (pDock->container.iWindowPositionX + icon->fXAtRest + (pDock->container.iWidth - pDock->iActiveWidth) * pDock->fAlign + (pDock->iActiveWidth - pDock->fFlatDockWidth) / 2)
///#define y_icon_geometry(icon, pDock) (pDock->container.iWindowPositionY + icon->fDrawY - icon->fHeight * myIconsParam.fAmplitude * pDock->fMagnitudeMax)
#define y_icon_geometry(icon, pDock) (pDock->container.iWindowPositionY + icon->fDrawY)
void gldi_appli_icon_set_geometry_for_window_manager (Icon *icon, CairoDock *pDock)
{
//g_print ("%s (%s)\n", __func__, icon->cName);
int iX, iY, iWidth, iHeight;
iX = x_icon_geometry (icon, pDock);
iY = y_icon_geometry (icon, pDock); // il faudrait un fYAtRest ...
//g_print (" -> %d;%d (%.2f)\n", iX - pDock->container.iWindowPositionX, iY - pDock->container.iWindowPositionY, icon->fXAtRest);
iWidth = icon->fWidth;
int dh = (icon->image.iWidth - icon->fHeight);
iHeight = icon->fHeight + 2 * dh; // on elargit en haut et en bas, pour gerer les cas ou l'icone grossirait vers le haut ou vers le bas.
if (pDock->container.bIsHorizontal)
gldi_window_set_thumbnail_area (icon->pAppli, iX, iY - dh, iWidth, iHeight);
else
gldi_window_set_thumbnail_area (icon->pAppli, iY - dh, iX, iHeight, iWidth);
}
void gldi_appli_reserve_geometry_for_window_manager (GldiWindowActor *pAppli, Icon *icon, CairoDock *pMainDock)
{
if (CAIRO_DOCK_IS_APPLI (icon) && cairo_dock_get_icon_container(icon) == NULL) // a detached appli
{
/// TODO: use the same algorithm as the class-manager to find the future position of the icon ...
Icon *pInhibitor = cairo_dock_get_inhibitor (icon, FALSE); // FALSE <=> meme en-dehors d'un dock
if (pInhibitor == NULL) // cette icone n'est pas inhibee, donc se minimisera dans le dock en une nouvelle icone.
{
int x, y;
Icon *pClassmate = cairo_dock_get_classmate (icon);
CairoDock *pClassmateDock = (pClassmate ? CAIRO_DOCK(cairo_dock_get_icon_container (pClassmate)) : NULL);
if (myTaskbarParam.bGroupAppliByClass && pClassmate != NULL && pClassmateDock != NULL) // on va se grouper avec cette icone.
{
x = x_icon_geometry (pClassmate, pClassmateDock);
if (cairo_dock_is_hidden (pMainDock))
{
y = (pClassmateDock->container.bDirectionUp ? 0 : gldi_desktop_get_height());
}
else
{
y = y_icon_geometry (pClassmate, pClassmateDock);
}
}
else if (myTaskbarParam.bMixLauncherAppli && pClassmate != NULL && pClassmateDock != NULL) // on va se placer a cote.
{
x = x_icon_geometry (pClassmate, pClassmateDock) + pClassmate->fWidth/2;
if (cairo_dock_is_hidden (pClassmateDock))
{
y = (pClassmateDock->container.bDirectionUp ? 0 : gldi_desktop_get_height());
}
else
{
y = y_icon_geometry (pClassmate, pClassmateDock);
}
}
else // on va se placer a la fin de la barre des taches.
{
Icon *pIcon, *pLastLauncher = NULL;
GList *ic;
for (ic = pMainDock->icons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (GLDI_OBJECT_IS_LAUNCHER_ICON (pIcon) // launcher, even without class
|| GLDI_OBJECT_IS_STACK_ICON (pIcon) // container icon (likely to contain some launchers)
|| (GLDI_OBJECT_IS_APPLET_ICON (pIcon) && pIcon->cClass != NULL) // applet acting like a launcher
|| (GLDI_OBJECT_IS_SEPARATOR_ICON (pIcon))) // separator (user or auto).
{
pLastLauncher = pIcon;
}
}
if (pLastLauncher != NULL) // on se placera juste apres.
{
x = x_icon_geometry (pLastLauncher, pMainDock) + pLastLauncher->fWidth/2;
if (cairo_dock_is_hidden (pMainDock))
{
y = (pMainDock->container.bDirectionUp ? 0 : gldi_desktop_get_height());
}
else
{
y = y_icon_geometry (pLastLauncher, pMainDock);
}
}
else // aucune icone avant notre groupe, on sera insere en 1er.
{
x = pMainDock->container.iWindowPositionX + 0 + (pMainDock->container.iWidth - pMainDock->fFlatDockWidth) / 2;
if (cairo_dock_is_hidden (pMainDock))
{
y = (pMainDock->container.bDirectionUp ? 0 : gldi_desktop_get_height());
}
else
{
y = pMainDock->container.iWindowPositionY;
}
}
}
//g_print (" - %s en (%d;%d)\n", icon->cName, x, y);
if (pMainDock->container.bIsHorizontal)
gldi_window_set_minimize_position (pAppli, x, y);
else
gldi_window_set_minimize_position (pAppli, y, x);
}
else
{
/// gerer les desklets...
}
}
}
const CairoDockImageBuffer *gldi_appli_icon_get_image_buffer (Icon *pIcon)
{
static CairoDockImageBuffer image;
// if the given icon is not loaded
if (pIcon->image.pSurface == NULL)
{
// try to get the image from the class
const CairoDockImageBuffer *pImageBuffer = cairo_dock_get_class_image_buffer (pIcon->cClass);
if (pImageBuffer && pImageBuffer->pSurface)
{
return pImageBuffer;
}
// try to load the icon.
if (g_pMainDock)
{
// set a size (we could set any size, but let's set something useful: if the icon is inserted in a dock and is already loaded at the correct size, it won't be loaded again).
gboolean bNoContainer = FALSE;
if (pIcon->pContainer == NULL) // not in a container (=> no size) -> set a size before loading it.
{
bNoContainer = TRUE;
cairo_dock_set_icon_container (pIcon, g_pPrimaryContainer);
pIcon->fWidth = pIcon->fHeight = 0; /// useful ?...
pIcon->iRequestedWidth = pIcon->iRequestedHeight = 0; // no request
cairo_dock_set_icon_size_in_dock (g_pMainDock, pIcon);
}
// load the icon
cairo_dock_load_icon_image (pIcon, g_pPrimaryContainer);
if (bNoContainer)
{
cairo_dock_set_icon_container (pIcon, NULL);
}
}
}
// if the given icon is loaded, use its image.
if (pIcon->image.pSurface != NULL || pIcon->image.iTexture != 0)
{
memcpy (&image, &pIcon->image, sizeof (CairoDockImageBuffer));
return ℑ
}
else
{
return NULL;
}
}
static gboolean _set_inhibitor_name (Icon *pInhibitorIcon, const gchar *cNewName)
{
if (! CAIRO_DOCK_ICON_TYPE_IS_APPLET (pInhibitorIcon))
{
cd_debug (" %s change son nom en %s", pInhibitorIcon->cName, cNewName);
if (pInhibitorIcon->cInitialName == NULL)
{
pInhibitorIcon->cInitialName = pInhibitorIcon->cName;
cd_debug ("pInhibitorIcon->cInitialName <- %s", pInhibitorIcon->cInitialName);
}
else
g_free (pInhibitorIcon->cName);
pInhibitorIcon->cName = NULL;
gldi_icon_set_name (pInhibitorIcon, (cNewName != NULL ? cNewName : pInhibitorIcon->cInitialName));
}
cairo_dock_redraw_icon (pInhibitorIcon);
return TRUE; // continue
}
void gldi_window_inhibitors_set_name (GldiWindowActor *actor, const gchar *cNewName)
{
gldi_window_foreach_inhibitor (actor, (GldiIconRFunc)_set_inhibitor_name, (gpointer)cNewName);
}
static gboolean _set_active_state (Icon *pInhibitorIcon, gpointer data)
{
gboolean bActive = GPOINTER_TO_INT(data);
if (bActive)
{
CairoDock *pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (pInhibitorIcon));
if (pParentDock != NULL)
gldi_appli_icon_animate_on_active (pInhibitorIcon, pParentDock);
}
else
{
cairo_dock_redraw_icon (pInhibitorIcon);
}
return TRUE; // continue
}
void gldi_window_inhibitors_set_active_state (GldiWindowActor *actor, gboolean bActive)
{
gldi_window_foreach_inhibitor (actor, (GldiIconRFunc)_set_active_state, GINT_TO_POINTER(bActive));
}
static gboolean _set_hidden_state (Icon *pInhibitorIcon, G_GNUC_UNUSED gpointer data)
{
if (! CAIRO_DOCK_ICON_TYPE_IS_APPLET (pInhibitorIcon) && myTaskbarParam.fVisibleAppliAlpha != 0)
{
pInhibitorIcon->fAlpha = 1; // on triche un peu.
cairo_dock_redraw_icon (pInhibitorIcon);
}
return TRUE; // continue
}
void gldi_window_inhibitors_set_hidden_state (GldiWindowActor *actor, gboolean bIsHidden)
{
gldi_window_foreach_inhibitor (actor, (GldiIconRFunc)_set_hidden_state, GINT_TO_POINTER(bIsHidden));
}
cairo-dock-3.3.2/src/gldit/cairo-dock-dock-visibility.c 000664 001750 001750 00000030043 12223247550 024046 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include "gldi-config.h"
#include "cairo-dock-dock-facility.h"
#include "cairo-dock-container.h"
#include "cairo-dock-object.h"
#include "cairo-dock-log.h"
#include "cairo-dock-windows-manager.h"
#include "cairo-dock-desktop-manager.h"
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-dock-visibility.h"
/////////////////////
// Dock visibility //
/////////////////////
static void _show_if_no_overlapping_window (CairoDock *pDock, G_GNUC_UNUSED gpointer data)
{
if (pDock->iVisibility != CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY)
return ;
if (cairo_dock_is_temporary_hidden (pDock))
{
if (gldi_dock_search_overlapping_window (pDock) == NULL)
{
cairo_dock_deactivate_temporary_auto_hide (pDock);
}
}
}
static void _hide_if_any_overlap (CairoDock *pDock, G_GNUC_UNUSED gpointer data)
{
if (pDock->iVisibility != CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY)
return ;
if (!cairo_dock_is_temporary_hidden (pDock))
{
if (gldi_dock_search_overlapping_window (pDock) != NULL)
{
cairo_dock_activate_temporary_auto_hide (pDock);
}
}
}
static void _hide_if_overlap (CairoDock *pDock, GldiWindowActor *pAppli)
{
if (pDock->iVisibility != CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY)
return ;
if (! cairo_dock_is_temporary_hidden (pDock))
{
if (gldi_window_is_on_current_desktop (pAppli) && gldi_dock_overlaps_window (pDock, pAppli))
{
cairo_dock_activate_temporary_auto_hide (pDock);
}
}
}
static void _hide_if_overlap_or_show_if_no_overlapping_window (CairoDock *pDock, GldiWindowActor *pAppli)
{
if (pDock->iVisibility != CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY)
return ;
if (gldi_dock_overlaps_window (pDock, pAppli)) // cette fenetre peut provoquer l'auto-hide.
{
if (! cairo_dock_is_temporary_hidden (pDock))
{
cairo_dock_activate_temporary_auto_hide (pDock);
}
}
else // ne gene pas/plus.
{
if (cairo_dock_is_temporary_hidden (pDock))
{
if (gldi_dock_search_overlapping_window (pDock) == NULL)
{
cairo_dock_deactivate_temporary_auto_hide (pDock);
}
}
}
}
static void _hide_show_if_on_our_way (CairoDock *pDock, GldiWindowActor *pCurrentAppli)
{
if (pDock->iVisibility != CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP)
return ;
/* hide the dock if the active window or its parent if this window doesn't
* have any dedicated icon in the dock -> If my window's text editor is
* maximised and then I open a 'Search' box, the dock should not appear
* above the maximised window
*/
GldiWindowActor *pParentAppli = NULL;
if (pCurrentAppli && pCurrentAppli->bIsTransientFor)
{
pParentAppli = gldi_window_get_transient_for (pCurrentAppli);
}
if (_gldi_window_is_on_our_way (pCurrentAppli, pDock) // the new active window is above the dock
|| (pParentAppli && _gldi_window_is_on_our_way (pParentAppli, pDock))) // it's a transient window; consider its parent too.
{
if (!cairo_dock_is_temporary_hidden (pDock))
cairo_dock_activate_temporary_auto_hide (pDock);
}
else if (cairo_dock_is_temporary_hidden (pDock))
cairo_dock_deactivate_temporary_auto_hide (pDock);
}
static void _hide_if_any_overlap_or_show (CairoDock *pDock, G_GNUC_UNUSED gpointer data)
{
if (pDock->iVisibility != CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY)
return ;
if (cairo_dock_is_temporary_hidden (pDock))
{
if (gldi_dock_search_overlapping_window (pDock) == NULL)
{
cairo_dock_deactivate_temporary_auto_hide (pDock);
}
}
else
{
if (gldi_dock_search_overlapping_window (pDock) != NULL)
{
cairo_dock_activate_temporary_auto_hide (pDock);
}
}
}
///////////////
// Callbacks //
///////////////
static gboolean _on_window_created (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
// docks visibility on overlap any
/// see how to handle modal dialogs ...
gldi_docks_foreach_root ((GFunc)_hide_if_overlap, actor);
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_destroyed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
// docks visibility on overlap any
gboolean bIsHidden = actor->bIsHidden; // the window is already destroyed, but the actor is still valid (it represents the last state of the window); temporarily make it hidden so that it doesn't overlap the dock (that's a bit tricky, we could also add an "except-this-window" parameter to 'gldi_dock_search_overlapping_window()')
actor->bIsHidden = TRUE;
gldi_docks_foreach_root ((GFunc)_show_if_no_overlapping_window, NULL);
actor->bIsHidden = bIsHidden;
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_size_position_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
// docks visibility on overlap any
if (! gldi_window_is_on_current_desktop (actor)) // not on this desktop/viewport any more
{
gldi_docks_foreach_root ((GFunc)_show_if_no_overlapping_window, actor);
}
else // elle est sur le viewport courant.
{
gldi_docks_foreach_root ((GFunc)_hide_if_overlap_or_show_if_no_overlapping_window, actor);
}
// docks visibility on overlap active
if (actor == gldi_windows_get_active()) // c'est la fenetre courante qui a change de bureau.
{
gldi_docks_foreach_root ((GFunc)_hide_show_if_on_our_way, actor);
}
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_state_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor, gboolean bHiddenChanged, G_GNUC_UNUSED gboolean bMaximizedChanged, gboolean bFullScreenChanged)
{
// docks visibility on overlap active
if (actor == gldi_windows_get_active()) // c'est la fenetre courante qui a change d'etat.
{
if (bHiddenChanged || bFullScreenChanged) // si c'est l'etat maximise qui a change, on le verra au changement de dimensions.
{
gldi_docks_foreach_root ((GFunc)_hide_show_if_on_our_way, actor);
}
}
// docks visibility on overlap any
if (bHiddenChanged)
{
if (!actor->bIsHidden) // la fenetre reapparait.
gldi_docks_foreach_root ((GFunc)_hide_if_overlap, actor);
else // la fenetre se cache.
gldi_docks_foreach_root ((GFunc)_show_if_no_overlapping_window, NULL);
}
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_desktop_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
// docks visibility on overlap active
if (actor == gldi_windows_get_active()) // c'est la fenetre courante qui a change de bureau.
{
gldi_docks_foreach_root ((GFunc)_hide_show_if_on_our_way, actor);
}
// docks visibility on overlap any
if (gldi_window_is_on_current_desktop (actor)) // petite optimisation : si l'appli arrive sur le bureau courant, on peut se contenter de ne verifier qu'elle.
{
gldi_docks_foreach_root ((GFunc)_hide_if_overlap, actor);
}
else // la fenetre n'est plus sur le bureau courant.
{
gldi_docks_foreach_root ((GFunc)_show_if_no_overlapping_window, NULL);
}
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_desktop_changed (G_GNUC_UNUSED gpointer data)
{
// docks visibility on overlap active
GldiWindowActor *pCurrentAppli = gldi_windows_get_active ();
gldi_docks_foreach_root ((GFunc)_hide_show_if_on_our_way, pCurrentAppli);
// docks visibility on overlap any
gldi_docks_foreach_root ((GFunc)_hide_if_any_overlap_or_show, NULL);
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_active_window_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
// docks visibility on overlap active
gldi_docks_foreach_root ((GFunc)_hide_show_if_on_our_way, actor);
return GLDI_NOTIFICATION_LET_PASS;
}
///////////////
// Utilities //
///////////////
void gldi_dock_hide_show_if_current_window_is_on_our_way (CairoDock *pDock)
{
GldiWindowActor *pCurrentAppli = gldi_windows_get_active ();
_hide_show_if_on_our_way (pDock, pCurrentAppli);
}
void gldi_dock_hide_if_any_window_overlap_or_show (CairoDock *pDock)
{
_hide_if_any_overlap_or_show (pDock, NULL);
}
static inline gboolean _window_overlaps_dock (GtkAllocation *pWindowGeometry, gboolean bIsHidden, CairoDock *pDock)
{
if (pWindowGeometry->width != 0 && pWindowGeometry->height != 0)
{
int iDockX, iDockY, iDockWidth, iDockHeight;
if (pDock->container.bIsHorizontal)
{
iDockWidth = pDock->iMinDockWidth;
iDockHeight = pDock->iMinDockHeight;
iDockX = pDock->container.iWindowPositionX + (pDock->container.iWidth - iDockWidth)/2;
iDockY = pDock->container.iWindowPositionY + (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->iMinDockHeight : 0);
}
else
{
iDockWidth = pDock->iMinDockHeight;
iDockHeight = pDock->iMinDockWidth;
iDockX = pDock->container.iWindowPositionY + (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->iMinDockHeight : 0);
iDockY = pDock->container.iWindowPositionX + (pDock->container.iWidth - iDockHeight)/2;
}
if (! bIsHidden && pWindowGeometry->x < iDockX + iDockWidth && pWindowGeometry->x + pWindowGeometry->width > iDockX && pWindowGeometry->y < iDockY + iDockHeight && pWindowGeometry->y + pWindowGeometry->height > iDockY)
{
return TRUE;
}
}
else
{
cd_warning (" unknown window geometry");
}
return FALSE;
}
gboolean gldi_dock_overlaps_window (CairoDock *pDock, GldiWindowActor *actor)
{
return _window_overlaps_dock (&actor->windowGeometry, actor->bIsHidden, pDock);
}
static gboolean _window_is_overlapping_dock (GldiWindowActor *actor, gpointer data)
{
CairoDock *pDock = CAIRO_DOCK (data);
if (gldi_window_is_on_current_desktop (actor) && ! actor->bIsHidden)
{
if (gldi_dock_overlaps_window (pDock, actor))
{
return TRUE;
}
}
return FALSE;
}
GldiWindowActor *gldi_dock_search_overlapping_window (CairoDock *pDock)
{
return gldi_windows_find (_window_is_overlapping_dock, pDock);
}
////////////
/// INIT ///
////////////
void gldi_docks_visibility_start (void)
{
static gboolean first = TRUE;
// register to events
if (first)
{
first = FALSE;
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_CREATED,
(GldiNotificationFunc) _on_window_created,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_DESTROYED,
(GldiNotificationFunc) _on_window_destroyed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_SIZE_POSITION_CHANGED,
(GldiNotificationFunc) _on_window_size_position_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_STATE_CHANGED,
(GldiNotificationFunc) _on_window_state_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_DESKTOP_CHANGED,
(GldiNotificationFunc) _on_window_desktop_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myDesktopMgr,
NOTIFICATION_DESKTOP_CHANGED,
(GldiNotificationFunc) _on_desktop_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_ACTIVATED,
(GldiNotificationFunc) _on_active_window_changed,
GLDI_RUN_FIRST, NULL);
}
// handle current docks visibility
GldiWindowActor *pCurrentAppli = gldi_windows_get_active ();
gldi_docks_foreach_root ((GFunc)_hide_show_if_on_our_way, pCurrentAppli);
gldi_docks_foreach_root ((GFunc)_hide_if_any_overlap, NULL);
}
static void _unhide_all_docks (CairoDock *pDock, G_GNUC_UNUSED Icon *icon)
{
if (cairo_dock_is_temporary_hidden (pDock))
cairo_dock_deactivate_temporary_auto_hide (pDock);
}
void gldi_docks_visibility_stop (void) // not used yet
{
gldi_docks_foreach_root ((GFunc)_unhide_all_docks, NULL);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-indicator-manager.h 000664 001750 001750 00000004135 12223247550 024335 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_INDICATOR_MANAGER__
#define __CAIRO_DOCK_INDICATOR_MANAGER__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-manager.h"
#include "cairo-dock-surface-factory.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-indicator-manager.h This class manages the indicators.
*/
// manager
typedef struct _CairoIndicatorsParam CairoIndicatorsParam;
#ifndef _MANAGER_DEF_
extern CairoIndicatorsParam myIndicatorsParam;
extern GldiManager myIndicatorsMgr;
#endif
// params
struct _CairoIndicatorsParam {
// active indicator.
gchar *cActiveIndicatorImagePath;
gdouble fActiveColor[4];
gint iActiveLineWidth;
gint iActiveCornerRadius;
gboolean bActiveIndicatorAbove;
// launched indicator.
gchar *cIndicatorImagePath;
gboolean bIndicatorAbove;
gdouble fIndicatorRatio;
gboolean bIndicatorOnIcon;
gdouble fIndicatorDeltaY;
gboolean bRotateWithDock;
gboolean bDrawIndicatorOnAppli;
// grouped indicator.
gchar *cClassIndicatorImagePath;
gboolean bZoomClassIndicator;
gboolean bUseClassIndic;
// progress bars
gdouble fBarColorStart[4];
gdouble fBarColorStop[4];
gboolean bBarHasOutline;
gdouble fBarColorOutline[4];
gint iBarThickness;
};
// signals
typedef enum {
NB_NOTIFICATIONS_INDICATORS = NB_NOTIFICATIONS_OBJECT
} CairoIndicatorsNotifications;
void gldi_register_indicators_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-applet-single-instance.h 000664 001750 001750 00000005252 12223247550 025320 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_APPLET_SINGLE_INSTANCE__
#define __CAIRO_DOCK_APPLET_SINGLE_INSTANCE__
#define myDrawContext myApplet->pDrawContext
#define CD_APPLET_DEFINE_BEGIN(cName, iMajorVersion, iMinorVersion, iMicroVersion, iAppletCategory, cDescription, cAuthor) \
GldiModuleInstance *myApplet = NULL; \
Icon *myIcon; \
GldiContainer *myContainer; \
CairoDock *myDock; \
CairoDesklet *myDesklet; \
AppletConfig *myConfigPtr = NULL; \
AppletData *myDataPtr = NULL; \
CD_APPLET_DEFINE_ALL_BEGIN (cName, iMajorVersion, iMinorVersion, iMicroVersion, iAppletCategory, cDescription, cAuthor) \
pVisitCard->bMultiInstance = FALSE;
#define CD_APPLET_INIT_BEGIN \
CD_APPLET_INIT_ALL_BEGIN(pApplet) \
myApplet = pApplet; \
myIcon = myApplet->pIcon; \
myContainer = myApplet->pContainer; \
myDock = myApplet->pDock; \
myDesklet = myApplet->pDesklet;\
myDataPtr = (AppletData*)myApplet->pData;
#define myConfig (* myConfigPtr)
#define myData (* myDataPtr)
#define CD_APPLET_RELOAD_BEGIN \
CD_APPLET_RELOAD_ALL_BEGIN \
myContainer = myApplet->pContainer; \
myDock = myApplet->pDock; \
myDesklet = myApplet->pDesklet; \
#define CD_APPLET_RESET_DATA_END \
myDock = NULL; \
myContainer = NULL; \
myIcon = NULL; \
myDataPtr = NULL; \
myDesklet = NULL; \
myApplet = NULL; \
CD_APPLET_RESET_DATA_ALL_END
#define CD_APPLET_RESET_CONFIG_BEGIN \
CD_APPLET_RESET_CONFIG_ALL_BEGIN \
if (myConfigPtr == NULL) \
return ;
#define CD_APPLET_RESET_CONFIG_END \
myConfigPtr = NULL; \
CD_APPLET_RESET_CONFIG_ALL_END
#define CD_APPLET_GET_CONFIG_BEGIN \
CD_APPLET_GET_CONFIG_ALL_BEGIN\
if (myConfigPtr == NULL)\
myConfigPtr = (AppletConfig*)myApplet->pConfig;\
if (myDataPtr == NULL)\
myDataPtr = (AppletData*)myApplet->pData;
extern Icon *myIcon;
extern GldiContainer *myContainer;
extern CairoDock *myDock;
extern CairoDesklet *myDesklet;
extern AppletConfig *myConfigPtr;
extern AppletData *myDataPtr;
extern GldiModuleInstance *myApplet;
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-class-manager.c 000664 001750 001750 00000221522 12233704045 023460 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include
#include "cairo-dock-icon-factory.h"
#include "cairo-dock-icon-facility.h"
#include "cairo-dock-surface-factory.h"
#include "cairo-dock-log.h"
#include "cairo-dock-utils.h" // cairo_dock_remove_version_from_string
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-applet-manager.h"
#include "cairo-dock-launcher-manager.h"
#include "cairo-dock-stack-icon-manager.h"
#include "cairo-dock-separator-manager.h"
#include "cairo-dock-class-icon-manager.h"
#include "cairo-dock-dock-factory.h"
#include "cairo-dock-desktop-manager.h" // gldi_desktop_notify_startup
#include "cairo-dock-module-manager.h" // GldiModule
#include "cairo-dock-module-instance-manager.h" // GldiModuleInstance
#include "cairo-dock-dock-facility.h"
#include "cairo-dock-config.h"
#include "cairo-dock-applications-manager.h"
#include "cairo-dock-draw.h"
#include "cairo-dock-image-buffer.h"
#include "cairo-dock-icon-manager.h"
#include "cairo-dock-indicator-manager.h"
#include "cairo-dock-container.h"
#include "cairo-dock-animations.h"
#include "cairo-dock-application-facility.h"
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-file-manager.h"
#include "cairo-dock-windows-manager.h"
#include "cairo-dock-class-manager.h"
extern CairoDock *g_pMainDock;
extern CairoDockDesktopEnv g_iDesktopEnv;
static GHashTable *s_hClassTable = NULL;
static void cairo_dock_free_class_appli (CairoDockClassAppli *pClassAppli)
{
g_list_free (pClassAppli->pIconsOfClass);
g_list_free (pClassAppli->pAppliOfClass);
g_free (pClassAppli->cDesktopFile);
g_free (pClassAppli->cCommand);
g_free (pClassAppli->cName);
g_free (pClassAppli->cIcon);
g_free (pClassAppli->cStartupWMClass);
g_free (pClassAppli->cWorkingDirectory);
if (pClassAppli->pMimeTypes)
g_strfreev (pClassAppli->pMimeTypes);
g_list_foreach (pClassAppli->pMenuItems, (GFunc)g_strfreev, NULL);
g_list_free (pClassAppli->pMenuItems);
if (pClassAppli->iSidOpeningTimeout != 0)
g_source_remove (pClassAppli->iSidOpeningTimeout);
g_free (pClassAppli);
}
static inline CairoDockClassAppli *_cairo_dock_lookup_class_appli (const gchar *cClass)
{
return (cClass != NULL ? g_hash_table_lookup (s_hClassTable, cClass) : NULL);
}
static gboolean _on_window_created (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
gldi_class_startup_notify_end (actor->cClass);
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_activated (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
if (! actor)
return GLDI_NOTIFICATION_LET_PASS;
gldi_class_startup_notify_end (actor->cClass);
return GLDI_NOTIFICATION_LET_PASS;
}
void cairo_dock_initialize_class_manager (void)
{
if (s_hClassTable == NULL)
s_hClassTable = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) cairo_dock_free_class_appli);
// register to events to detect the ending of a launching
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_CREATED,
(GldiNotificationFunc) _on_window_created,
GLDI_RUN_AFTER, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_ACTIVATED,
(GldiNotificationFunc) _on_window_activated,
GLDI_RUN_AFTER, NULL); // some applications don't open a new window, but rather take the focus;
}
const GList *cairo_dock_list_existing_appli_with_class (const gchar *cClass)
{
g_return_val_if_fail (cClass != NULL, NULL);
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (cClass);
return (pClassAppli != NULL ? pClassAppli->pAppliOfClass : NULL);
}
static CairoDockClassAppli *cairo_dock_get_class (const gchar *cClass)
{
g_return_val_if_fail (cClass != NULL, NULL);
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (cClass);
if (pClassAppli == NULL)
{
pClassAppli = g_new0 (CairoDockClassAppli, 1);
g_hash_table_insert (s_hClassTable, g_strdup (cClass), pClassAppli);
}
return pClassAppli;
}
static gboolean _cairo_dock_add_inhibitor_to_class (const gchar *cClass, Icon *pIcon)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
g_return_val_if_fail (pClassAppli!= NULL, FALSE);
g_return_val_if_fail (g_list_find (pClassAppli->pIconsOfClass, pIcon) == NULL, TRUE);
pClassAppli->pIconsOfClass = g_list_prepend (pClassAppli->pIconsOfClass, pIcon);
return TRUE;
}
CairoDock *cairo_dock_get_class_subdock (const gchar *cClass)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
g_return_val_if_fail (pClassAppli!= NULL, NULL);
return gldi_dock_get (pClassAppli->cDockName);
}
CairoDock* cairo_dock_create_class_subdock (const gchar *cClass, CairoDock *pParentDock)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
g_return_val_if_fail (pClassAppli!= NULL, NULL);
CairoDock *pDock = gldi_dock_get (pClassAppli->cDockName);
if (pDock == NULL) // cDockName not yet defined, or previous class subdock no longer exists
{
g_free (pClassAppli->cDockName);
pClassAppli->cDockName = cairo_dock_get_unique_dock_name (cClass);
pDock = gldi_subdock_new (pClassAppli->cDockName, NULL, pParentDock, NULL);
}
return pDock;
}
static void cairo_dock_destroy_class_subdock (const gchar *cClass)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
g_return_if_fail (pClassAppli!= NULL);
CairoDock *pDock = gldi_dock_get (pClassAppli->cDockName);
if (pDock)
{
gldi_object_unref (GLDI_OBJECT(pDock));
}
g_free (pClassAppli->cDockName);
pClassAppli->cDockName = NULL;
}
gboolean cairo_dock_add_appli_icon_to_class (Icon *pIcon)
{
g_return_val_if_fail (CAIRO_DOCK_ICON_TYPE_IS_APPLI (pIcon) && pIcon->pAppli, FALSE);
cd_debug ("%s (%s)", __func__, pIcon->cClass);
if (pIcon->cClass == NULL)
{
cd_message (" %s n'a pas de classe, c'est po bien", pIcon->cName);
return FALSE;
}
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
g_return_val_if_fail (pClassAppli!= NULL, FALSE);
///if (pClassAppli->iAge == 0) // age is > 0, so it means we have never set it yet.
if (pClassAppli->pAppliOfClass == NULL) // the first appli of a class defines the age of the class.
pClassAppli->iAge = pIcon->pAppli->iAge;
g_return_val_if_fail (g_list_find (pClassAppli->pAppliOfClass, pIcon) == NULL, TRUE);
pClassAppli->pAppliOfClass = g_list_prepend (pClassAppli->pAppliOfClass, pIcon);
return TRUE;
}
gboolean cairo_dock_remove_appli_from_class (Icon *pIcon)
{
g_return_val_if_fail (pIcon!= NULL, FALSE);
cd_debug ("%s (%s, %s)", __func__, pIcon->cClass, pIcon->cName);
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
g_return_val_if_fail (pClassAppli!= NULL, FALSE);
pClassAppli->pAppliOfClass = g_list_remove (pClassAppli->pAppliOfClass, pIcon);
return TRUE;
}
gboolean cairo_dock_set_class_use_xicon (const gchar *cClass, gboolean bUseXIcon)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
g_return_val_if_fail (pClassAppli!= NULL, FALSE);
if (pClassAppli->bUseXIcon == bUseXIcon) // rien a faire.
return FALSE;
GList *pElement;
Icon *pAppliIcon;
for (pElement = pClassAppli->pAppliOfClass; pElement != NULL; pElement = pElement->next)
{
pAppliIcon = pElement->data;
if (bUseXIcon)
{
cd_message ("%s prend l'icone de X", pAppliIcon->cName);
}
else
{
cd_message ("%s n'utilise plus l'icone de X", pAppliIcon->cName);
}
cairo_dock_reload_icon_image (pAppliIcon, cairo_dock_get_icon_container (pAppliIcon));
}
return TRUE;
}
static void _cairo_dock_set_same_indicator_on_sub_dock (Icon *pInhibhatorIcon)
{
CairoDock *pInhibatorDock = CAIRO_DOCK(cairo_dock_get_icon_container (pInhibhatorIcon));
if (GLDI_OBJECT_IS_DOCK(pInhibatorDock) && pInhibatorDock->iRefCount > 0) // l'inhibiteur est dans un sous-dock.
{
gboolean bSubDockHasIndicator = FALSE;
if (pInhibhatorIcon->bHasIndicator)
{
bSubDockHasIndicator = TRUE;
}
else
{
GList* ic;
Icon *icon;
for (ic = pInhibatorDock->icons ; ic != NULL; ic = ic->next)
{
icon = ic->data;
if (icon->bHasIndicator)
{
bSubDockHasIndicator = TRUE;
break;
}
}
}
CairoDock *pParentDock = NULL;
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pInhibatorDock, &pParentDock);
if (pPointingIcon != NULL && pPointingIcon->bHasIndicator != bSubDockHasIndicator)
{
cd_message (" pour le sous-dock %s : indicateur <- %d", pPointingIcon->cName, bSubDockHasIndicator);
pPointingIcon->bHasIndicator = bSubDockHasIndicator;
if (pParentDock != NULL)
cairo_dock_redraw_icon (pPointingIcon);
}
}
}
static GldiWindowActor *_gldi_appli_icon_detach_of_class (const gchar *cClass)
{
g_return_val_if_fail (cClass != NULL, 0);
const GList *pList = cairo_dock_list_existing_appli_with_class (cClass);
Icon *pIcon;
const GList *pElement;
///gboolean bNeedsRedraw = FALSE;
CairoDock *pParentDock;
GldiWindowActor *pFirstFoundActor = NULL;
for (pElement = pList; pElement != NULL; pElement = pElement->next)
{
pIcon = pElement->data;
pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (pIcon));
if (pParentDock == NULL) // pas dans un dock => rien a faire.
continue;
cd_debug ("detachement de l'icone %s (%p)", pIcon->cName, pFirstFoundActor);
gldi_icon_detach (pIcon);
// if the icon was in the class sub-dock, check if it became empty
if (pParentDock == cairo_dock_get_class_subdock (cClass)) // the icon was in the class sub-dock
{
if (pParentDock->icons == NULL) // and it's now empty -> destroy it (and the class-icon pointing on it as well)
{
CairoDock *pMainDock = NULL;
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pParentDock, &pMainDock);
/// TODO: register to the destroy event of the class sub-dock...
cairo_dock_destroy_class_subdock (cClass); // destroy it before the class-icon, since it will destroy the sub-dock
if (pMainDock && CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (pPointingIcon))
{
gldi_icon_detach (pPointingIcon);
gldi_object_unref (GLDI_OBJECT(pPointingIcon));
}
}
}
if (pFirstFoundActor == NULL) // on recupere la 1ere appli de la classe.
{
pFirstFoundActor = pIcon->pAppli;
}
}
return pFirstFoundActor;
}
gboolean cairo_dock_inhibite_class (const gchar *cClass, Icon *pInhibitorIcon)
{
g_return_val_if_fail (cClass != NULL, FALSE);
cd_message ("%s (%s)", __func__, cClass);
// add inhibitor to class (first, so that applis can find it and take its surface if neccessary)
if (! _cairo_dock_add_inhibitor_to_class (cClass, pInhibitorIcon))
return FALSE;
// set class name on the inhibitor if not already done.
if (pInhibitorIcon && pInhibitorIcon->cClass != cClass)
{
g_free (pInhibitorIcon->cClass);
pInhibitorIcon->cClass = g_strdup (cClass);
}
// if launchers are mixed with applis, steal applis icons.
if (!myTaskbarParam.bMixLauncherAppli)
return TRUE;
GldiWindowActor *pFirstFoundActor = _gldi_appli_icon_detach_of_class (cClass); // detach existing applis, and then retach them to the inhibitor.
if (pInhibitorIcon != NULL)
{
// inhibitor takes control of the first existing appli of the class.
gldi_icon_set_appli (pInhibitorIcon, pFirstFoundActor);
pInhibitorIcon->bHasIndicator = (pFirstFoundActor != NULL);
_cairo_dock_set_same_indicator_on_sub_dock (pInhibitorIcon);
// other applis icons are retached to the inhibitor.
const GList *pList = cairo_dock_list_existing_appli_with_class (cClass);
Icon *pIcon;
const GList *pElement;
for (pElement = pList; pElement != NULL; pElement = pElement->next)
{
pIcon = pElement->data;
cd_debug (" une appli detachee (%s)", pIcon->cName);
if (pIcon->pAppli != pFirstFoundActor && cairo_dock_get_icon_container (pIcon) == NULL) // s'est faite detacher et doit etre rattachee.
gldi_appli_icon_insert_in_dock (pIcon, g_pMainDock, ! CAIRO_DOCK_ANIMATE_ICON);
}
}
return TRUE;
}
gboolean cairo_dock_class_is_inhibited (const gchar *cClass)
{
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (cClass);
return (pClassAppli != NULL && pClassAppli->pIconsOfClass != NULL);
}
gboolean cairo_dock_class_is_using_xicon (const gchar *cClass)
{
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (cClass);
return (pClassAppli != NULL && pClassAppli->bUseXIcon); // si pClassAppli == NULL, il n'y a pas de lanceur pouvant lui filer son icone, mais on peut en trouver une dans le theme d'icones systeme.
}
gboolean cairo_dock_class_is_expanded (const gchar *cClass)
{
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (cClass);
return (pClassAppli != NULL && pClassAppli->bExpand);
}
gboolean cairo_dock_prevent_inhibited_class (Icon *pIcon)
{
g_return_val_if_fail (pIcon != NULL, FALSE);
//g_print ("%s (%s)\n", __func__, pIcon->cClass);
gboolean bToBeInhibited = FALSE;
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (pIcon->cClass);
if (pClassAppli != NULL)
{
Icon *pInhibitorIcon;
GList *pElement;
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
{
pInhibitorIcon = pElement->data;
if (pInhibitorIcon != NULL) // un inhibiteur est present.
{
if (pInhibitorIcon->pAppli == NULL && pInhibitorIcon->pSubDock == NULL) // cette icone inhibe cette classe mais ne controle encore aucune appli, on s'y asservit.
{
gldi_icon_set_appli (pInhibitorIcon, pIcon->pAppli);
cd_message (">>> %s prendra un indicateur au prochain redraw ! (pAppli : %p)", pInhibitorIcon->cName, pInhibitorIcon->pAppli);
pInhibitorIcon->bHasIndicator = TRUE;
_cairo_dock_set_same_indicator_on_sub_dock (pInhibitorIcon);
/**}
if (pInhibitorIcon->pAppli == pIcon->pAppli) // cette icone nous controle.
{*/
CairoDock *pInhibatorDock = CAIRO_DOCK(cairo_dock_get_icon_container (pInhibitorIcon));
//\______________ On place l'icone pour X.
if (! bToBeInhibited) // on ne met le thumbnail que sur la 1ere.
{
if (pInhibatorDock != NULL)
{
//g_print ("on positionne la miniature sur l'inhibiteur %s\n", pInhibitorIcon->cName);
gldi_appli_icon_set_geometry_for_window_manager (pInhibitorIcon, pInhibatorDock);
}
}
//\______________ On met a jour l'etiquette de l'inhibiteur.
if (pInhibatorDock != NULL && pIcon->cName != NULL)
{
if (pInhibitorIcon->cInitialName == NULL)
pInhibitorIcon->cInitialName = pInhibitorIcon->cName;
else
g_free (pInhibitorIcon->cName);
pInhibitorIcon->cName = NULL;
gldi_icon_set_name (pInhibitorIcon, pIcon->cName);
}
}
bToBeInhibited = (pInhibitorIcon->pAppli == pIcon->pAppli);
}
}
}
return bToBeInhibited;
}
static void _cairo_dock_remove_icon_from_class (Icon *pInhibitorIcon)
{
g_return_if_fail (pInhibitorIcon != NULL);
cd_message ("%s (%s)", __func__, pInhibitorIcon->cClass);
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (pInhibitorIcon->cClass);
if (pClassAppli != NULL)
{
pClassAppli->pIconsOfClass = g_list_remove (pClassAppli->pIconsOfClass, pInhibitorIcon);
}
}
void cairo_dock_deinhibite_class (const gchar *cClass, Icon *pInhibitorIcon)
{
cd_message ("%s (%s)", __func__, cClass);
_cairo_dock_remove_icon_from_class (pInhibitorIcon);
if (pInhibitorIcon != NULL && pInhibitorIcon->pSubDock != NULL && pInhibitorIcon->pSubDock == cairo_dock_get_class_subdock (cClass)) // the launcher is controlling several appli icons, place them back in the taskbar.
{
// first destroy the class sub-dock, so that the appli icons won't go inside again.
// we empty the sub-dock then destroy it, then re-insert the appli icons
GList *icons = pInhibitorIcon->pSubDock->icons;
pInhibitorIcon->pSubDock->icons = NULL; // empty the sub-dock
cairo_dock_destroy_class_subdock (cClass); // destroy the sub-dock without destroying its icons
pInhibitorIcon->pSubDock = NULL; // since the inhibitor can already be detached, the sub-dock can't find it
Icon *pAppliIcon;
GList *ic;
for (ic = icons; ic != NULL; ic = ic->next)
{
pAppliIcon = ic->data;
cairo_dock_set_icon_container (pAppliIcon, NULL); // manually "detach" it
}
// then re-insert the appli icons.
for (ic = icons; ic != NULL; ic = ic->next)
{
pAppliIcon = ic->data;
gldi_appli_icon_insert_in_dock (pAppliIcon, g_pMainDock, ! CAIRO_DOCK_ANIMATE_ICON);
}
g_list_free (icons);
cairo_dock_trigger_load_icon_buffers (pInhibitorIcon); // in case the inhibitor was drawn with an emblem or a stack of the applis
}
if (pInhibitorIcon == NULL || pInhibitorIcon->pAppli != NULL) // the launcher is controlling 1 appli icon, or we deinhibate all the inhibitors.
{
const GList *pList = cairo_dock_list_existing_appli_with_class (cClass);
Icon *pIcon;
///gboolean bNeedsRedraw = FALSE;
///CairoDock *pParentDock;
const GList *pElement;
for (pElement = pList; pElement != NULL; pElement = pElement->next)
{
pIcon = pElement->data;
if (pInhibitorIcon == NULL || pIcon->pAppli == pInhibitorIcon->pAppli)
{
cd_message ("rajout de l'icone precedemment inhibee (pAppli:%p)", pIcon->pAppli);
pIcon->fInsertRemoveFactor = 0;
pIcon->fScale = 1.;
/**pParentDock = */
gldi_appli_icon_insert_in_dock (pIcon, g_pMainDock, ! CAIRO_DOCK_ANIMATE_ICON);
///bNeedsRedraw = (pParentDock != NULL && pParentDock->bIsMainDock);
}
///cairo_dock_reload_icon_image (pIcon, cairo_dock_get_icon_container (pIcon)); /// question : pourquoi le faire pour toutes les icones ?...
}
///if (bNeedsRedraw)
/// gtk_widget_queue_draw (g_pMainDock->container.pWidget); /// pDock->pRenderer->calculate_icons (pDock); ?...
}
if (pInhibitorIcon != NULL)
{
cd_message (" l'inhibiteur a perdu toute sa mana");
gldi_icon_unset_appli (pInhibitorIcon);
pInhibitorIcon->bHasIndicator = FALSE;
g_free (pInhibitorIcon->cClass);
pInhibitorIcon->cClass = NULL;
cd_debug (" plus de classe");
}
}
void gldi_window_detach_from_inhibitors (GldiWindowActor *pAppli)
{
const gchar *cClass = pAppli->cClass;
cd_message ("%s (%s)", __func__, cClass);
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (cClass);
if (pClassAppli != NULL)
{
GldiWindowActor *pNextAppli = NULL; // next window that will be inhibited.
gboolean bFirstSearch = TRUE;
Icon *pSameClassIcon = NULL;
Icon *pIcon;
GList *pElement;
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
{
pIcon = pElement->data;
if (pIcon->pAppli == pAppli) // this inhibitor controls the given window -> make it control another (possibly none).
{
// find the next inhibited appli
if (bFirstSearch) // we didn't search the next window yet, do it now.
{
bFirstSearch = FALSE;
Icon *pOneIcon;
GList *ic;
for (ic = g_list_last (pClassAppli->pAppliOfClass); ic != NULL; ic = ic->prev) // reverse order, to take the oldest window of this class.
{
pOneIcon = ic->data;
if (pOneIcon != NULL
&& pOneIcon->pAppli != NULL
&& pOneIcon->pAppli != pAppli // not the window we precisely want to avoid
&& (! myTaskbarParam.bAppliOnCurrentDesktopOnly || gldi_window_is_on_current_desktop (pOneIcon->pAppli))) // can actually be displayed
{
pSameClassIcon = pOneIcon;
break ;
}
}
pNextAppli = (pSameClassIcon != NULL ? pSameClassIcon->pAppli : NULL);
if (pSameClassIcon != NULL) // this icon will be inhibited, we need to detach it if needed
{
cd_message (" c'est %s qui va la remplacer", pSameClassIcon->cName);
gldi_icon_detach (pSameClassIcon); // it can't be the class sub-dock, because pIcon had the window actor, so it doesn't hold the class sub-dock and the class is not grouped (otherwise they would all be in the class sub-dock).
}
}
// make the icon inhibite the next appli (possibly none)
gldi_icon_set_appli (pIcon, pNextAppli);
pIcon->bHasIndicator = (pNextAppli != NULL);
_cairo_dock_set_same_indicator_on_sub_dock (pIcon);
if (pNextAppli == NULL)
gldi_icon_set_name (pIcon, pIcon->cInitialName);
cd_message (" %s : bHasIndicator <- %d, pAppli <- %p", pIcon->cName, pIcon->bHasIndicator, pIcon->pAppli);
// redraw
GldiContainer *pContainer = cairo_dock_get_icon_container (pIcon);
if (pContainer)
gtk_widget_queue_draw (pContainer->pWidget);
}
}
}
}
static void _cairo_dock_remove_all_applis_from_class (G_GNUC_UNUSED gchar *cClass, CairoDockClassAppli *pClassAppli, G_GNUC_UNUSED gpointer data)
{
g_list_free (pClassAppli->pAppliOfClass);
pClassAppli->pAppliOfClass = NULL;
Icon *pInhibitorIcon;
GList *pElement;
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
{
pInhibitorIcon = pElement->data;
pInhibitorIcon->bHasIndicator = FALSE;
gldi_icon_unset_appli (pInhibitorIcon);
_cairo_dock_set_same_indicator_on_sub_dock (pInhibitorIcon);
}
}
void cairo_dock_remove_all_applis_from_class_table (void) // pour le stop_application_manager
{
g_hash_table_foreach (s_hClassTable, (GHFunc) _cairo_dock_remove_all_applis_from_class, NULL);
}
void cairo_dock_reset_class_table (void)
{
g_hash_table_remove_all (s_hClassTable);
}
cairo_surface_t *cairo_dock_create_surface_from_class (const gchar *cClass, int iWidth, int iHeight)
{
cd_debug ("%s (%s)", __func__, cClass);
// first we try to get an icon from one of the inhibator.
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
if (pClassAppli != NULL)
{
cd_debug ("bUseXIcon:%d", pClassAppli->bUseXIcon);
if (pClassAppli->bUseXIcon)
return NULL;
GList *pElement;
Icon *pInhibitorIcon;
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
{
pInhibitorIcon = pElement->data;
cd_debug (" %s", pInhibitorIcon->cName);
if (! CAIRO_DOCK_ICON_TYPE_IS_APPLET (pInhibitorIcon))
{
if (pInhibitorIcon->pSubDock == NULL || myIndicatorsParam.bUseClassIndic) // dans le cas d'un lanceur qui aurait deja plusieurs instances de sa classe, et qui les representerait en pile, on ne prend pas son icone.
{
cd_debug ("%s will give its surface", pInhibitorIcon->cName);
return cairo_dock_duplicate_surface (pInhibitorIcon->image.pSurface,
pInhibitorIcon->image.iWidth,
pInhibitorIcon->image.iHeight,
iWidth,
iHeight);
}
else if (pInhibitorIcon->cFileName != NULL)
{
gchar *cIconFilePath = cairo_dock_search_icon_s_path (pInhibitorIcon->cFileName, MAX (iWidth, iHeight));
if (cIconFilePath != NULL)
{
cd_debug ("we replace X icon by %s", cIconFilePath);
cairo_surface_t *pSurface = cairo_dock_create_surface_from_image_simple (cIconFilePath,
iWidth,
iHeight);
g_free (cIconFilePath);
if (pSurface)
return pSurface;
}
}
}
}
}
// if we didn't find one, we use the icon defined in the class.
if (pClassAppli != NULL && pClassAppli->cIcon != NULL)
{
cd_debug ("get the class icon (%s)", pClassAppli->cIcon);
gchar *cIconFilePath = cairo_dock_search_icon_s_path (pClassAppli->cIcon, MAX (iWidth, iHeight));
cairo_surface_t *pSurface = cairo_dock_create_surface_from_image_simple (cIconFilePath,
iWidth,
iHeight);
g_free (cIconFilePath);
if (pSurface)
return pSurface;
}
else
{
cd_debug ("no icon for the class %s", cClass);
}
// if not found or not defined, try to find an icon based on the name class.
gchar *cIconFilePath = cairo_dock_search_icon_s_path (cClass, MAX (iWidth, iHeight));
if (cIconFilePath != NULL)
{
cd_debug ("on remplace l'icone X par %s", cIconFilePath);
cairo_surface_t *pSurface = cairo_dock_create_surface_from_image_simple (cIconFilePath,
iWidth,
iHeight);
g_free (cIconFilePath);
if (pSurface)
return pSurface;
}
cd_debug ("classe %s prendra l'icone X", cClass);
return NULL;
}
/**
void cairo_dock_update_visibility_on_inhibitors (const gchar *cClass, GldiWindowActor *pAppli, gboolean bIsHidden)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
if (pClassAppli != NULL)
{
GList *pElement;
Icon *pInhibitorIcon;
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
{
pInhibitorIcon = pElement->data;
if (pInhibitorIcon->pAppli == pAppli)
{
cd_debug (" %s aussi se %s", pInhibitorIcon->cName, (bIsHidden ? "cache" : "montre"));
if (! CAIRO_DOCK_ICON_TYPE_IS_APPLET (pInhibitorIcon) && myTaskbarParam.fVisibleAppliAlpha != 0)
{
pInhibitorIcon->fAlpha = 1; // on triche un peu.
cairo_dock_redraw_icon (pInhibitorIcon);
}
}
}
}
}
void cairo_dock_update_activity_on_inhibitors (const gchar *cClass, GldiWindowActor *pAppli)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
if (pClassAppli != NULL)
{
GList *pElement;
Icon *pInhibitorIcon;
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
{
pInhibitorIcon = pElement->data;
if (pInhibitorIcon->pAppli == pAppli)
{
cd_debug (" %s aussi devient active", pInhibitorIcon->cName);
CairoDock *pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (pInhibitorIcon));
if (pParentDock != NULL)
gldi_appli_icon_animate_on_active (pInhibitorIcon, pParentDock);
}
}
}
}
void cairo_dock_update_inactivity_on_inhibitors (const gchar *cClass, GldiWindowActor *pAppli)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
if (pClassAppli != NULL)
{
GList *pElement;
Icon *pInhibitorIcon;
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
{
pInhibitorIcon = pElement->data;
if (pInhibitorIcon->pAppli == pAppli)
{
cairo_dock_redraw_icon (pInhibitorIcon);
}
}
}
}
void cairo_dock_update_name_on_inhibitors (const gchar *cClass, GldiWindowActor *actor, gchar *cNewName)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
if (pClassAppli != NULL)
{
GList *pElement;
Icon *pInhibitorIcon;
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
{
pInhibitorIcon = pElement->data;
if (pInhibitorIcon->pAppli == actor)
{
if (! CAIRO_DOCK_ICON_TYPE_IS_APPLET (pInhibitorIcon))
{
cd_debug (" %s change son nom en %s", pInhibitorIcon->cName, cNewName);
if (pInhibitorIcon->cInitialName == NULL)
{
pInhibitorIcon->cInitialName = pInhibitorIcon->cName;
cd_debug ("pInhibitorIcon->cInitialName <- %s", pInhibitorIcon->cInitialName);
}
else
g_free (pInhibitorIcon->cName);
pInhibitorIcon->cName = NULL;
gldi_icon_set_name (pInhibitorIcon, (cNewName != NULL ? cNewName : pInhibitorIcon->cInitialName));
}
cairo_dock_redraw_icon (pInhibitorIcon);
}
}
}
}
*/
void gldi_window_foreach_inhibitor (GldiWindowActor *actor, GldiIconRFunc callback, gpointer data)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (actor->cClass);
if (pClassAppli != NULL)
{
Icon *pInhibitorIcon;
GList *ic;
for (ic = pClassAppli->pIconsOfClass; ic != NULL; ic = ic->next)
{
pInhibitorIcon = ic->data;
if (pInhibitorIcon->pAppli == actor)
{
if (! callback (pInhibitorIcon, data))
break;
}
}
}
}
Icon *cairo_dock_get_classmate (Icon *pIcon) // gets an icon of the same class, that is inside a dock (or will be for an inhibitor), but not inside the class sub-dock
{
cd_debug ("%s (%s)", __func__, pIcon->cClass);
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
if (pClassAppli == NULL)
return NULL;
Icon *pFriendIcon = NULL;
GList *pElement;
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
{
pFriendIcon = pElement->data;
/// TODO: this is ugly... maybe an inhibitor shouldn't inhibite when not yet in a dock...
if (pFriendIcon == NULL || (cairo_dock_get_icon_container(pFriendIcon) == NULL && pFriendIcon->cParentDockName == NULL)) // if not inside a dock (for instance a detached applet, but not a hidden launcher), ignore.
continue ;
cd_debug (" friend : %s", pFriendIcon->cName);
if (pFriendIcon->pAppli != NULL || pFriendIcon->pSubDock != NULL) // is linked to a window, 1 or several times (window actor or class sub-dock).
return pFriendIcon;
}
GldiContainer *pClassSubDock = CAIRO_CONTAINER(cairo_dock_get_class_subdock (pIcon->cClass));
for (pElement = pClassAppli->pAppliOfClass; pElement != NULL; pElement = pElement->next)
{
pFriendIcon = pElement->data;
if (pFriendIcon == pIcon) // skip ourselves
continue ;
if (cairo_dock_get_icon_container (pFriendIcon) != NULL && cairo_dock_get_icon_container (pFriendIcon) != pClassSubDock) // inside a dock, but not the class sub-dock
return pFriendIcon;
}
return NULL;
}
gboolean cairo_dock_check_class_subdock_is_empty (CairoDock *pDock, const gchar *cClass)
{
cd_debug ("%s (%s, %d)", __func__, cClass, g_list_length (pDock->icons));
if (pDock->iRefCount == 0)
return FALSE;
if (pDock->icons == NULL) // shouldn't happen, handle this case and make some noise.
{
cd_warning ("the %s class sub-dock has no element, which is probably an error !\nit will be destroyed.", cClass);
Icon *pFakeClassIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
cairo_dock_destroy_class_subdock (cClass);
pFakeClassIcon->pSubDock = NULL;
if (CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (pFakeClassIcon))
{
gldi_icon_detach (pFakeClassIcon);
gldi_object_unref (GLDI_OBJECT(pFakeClassIcon));
}
return TRUE;
}
else if (pDock->icons->next == NULL) // only 1 icon left in the sub-dock -> destroy it.
{
cd_debug (" le sous-dock de la classe %s n'a plus que 1 element et va etre vide puis detruit", cClass);
Icon *pLastClassIcon = pDock->icons->data;
CairoDock *pFakeParentDock = NULL;
Icon *pFakeClassIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pFakeParentDock);
g_return_val_if_fail (pFakeClassIcon != NULL, TRUE);
// detach the last icon from the class sub-dock
gboolean bLastIconIsRemoving = cairo_dock_icon_is_being_removed (pLastClassIcon); // keep the removing state because when we detach the icon, it returns to normal state.
gldi_icon_detach (pLastClassIcon);
pLastClassIcon->fOrder = pFakeClassIcon->fOrder; // if re-inserted in a dock, insert at the same place
// destroy the class sub-dock
cairo_dock_destroy_class_subdock (cClass);
pFakeClassIcon->pSubDock = NULL;
if (CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (pFakeClassIcon)) // the class sub-dock is pointed by a class-icon
{
// destroy the class-icon
gldi_icon_detach (pFakeClassIcon);
gldi_object_unref (GLDI_OBJECT(pFakeClassIcon));
// re-insert the last icon in place of it, or destroy it if it was being removed
if (! bLastIconIsRemoving)
{
gldi_icon_insert_in_container (pLastClassIcon, CAIRO_CONTAINER(pFakeParentDock), ! CAIRO_DOCK_ANIMATE_ICON);
}
else // la derniere icone est en cours de suppression, inutile de la re-inserer. (c'est souvent lorsqu'on ferme toutes une classe d'un coup. donc les animations sont pratiquement dans le meme etat, donc la derniere icone en est aussi a la fin, donc on ne verrait de toute facon aucune animation.
{
cd_debug ("inutile de re-inserer l'icone restante");
gldi_object_unref (GLDI_OBJECT(pLastClassIcon));
}
}
else // the class sub-dock is pointed by a launcher/applet
{
// re-inhibite the last icon or destroy it if it was being removed
if (! bLastIconIsRemoving)
{
gldi_appli_icon_insert_in_dock (pLastClassIcon, g_pMainDock, ! CAIRO_DOCK_ANIMATE_ICON); // Note that we could optimize and manually set the appli and the name...
///cairo_dock_update_name_on_inhibitors (cClass, pLastClassIcon->pAppli, pLastClassIcon->cName);
}
else // la derniere icone est en cours de suppression, inutile de la re-inserer
{
pFakeClassIcon->bHasIndicator = FALSE;
gldi_object_unref (GLDI_OBJECT(pLastClassIcon));
}
cairo_dock_redraw_icon (pFakeClassIcon);
}
cd_debug ("no more dock");
return TRUE;
}
return FALSE;
}
static void _cairo_dock_reset_overwrite_exceptions (G_GNUC_UNUSED gchar *cClass, CairoDockClassAppli *pClassAppli, G_GNUC_UNUSED gpointer data)
{
pClassAppli->bUseXIcon = FALSE;
}
void cairo_dock_set_overwrite_exceptions (const gchar *cExceptions)
{
g_hash_table_foreach (s_hClassTable, (GHFunc) _cairo_dock_reset_overwrite_exceptions, NULL);
if (cExceptions == NULL)
return ;
gchar **cClassList = g_strsplit (cExceptions, ";", -1);
if (cClassList == NULL || cClassList[0] == NULL || *cClassList[0] == '\0')
{
g_strfreev (cClassList);
return ;
}
CairoDockClassAppli *pClassAppli;
int i;
for (i = 0; cClassList[i] != NULL; i ++)
{
pClassAppli = cairo_dock_get_class (cClassList[i]);
pClassAppli->bUseXIcon = TRUE;
}
g_strfreev (cClassList);
}
static void _cairo_dock_reset_group_exceptions (G_GNUC_UNUSED gchar *cClass, CairoDockClassAppli *pClassAppli, G_GNUC_UNUSED gpointer data)
{
pClassAppli->bExpand = FALSE;
}
void cairo_dock_set_group_exceptions (const gchar *cExceptions)
{
g_hash_table_foreach (s_hClassTable, (GHFunc) _cairo_dock_reset_group_exceptions, NULL);
if (cExceptions == NULL)
return ;
gchar **cClassList = g_strsplit (cExceptions, ";", -1);
if (cClassList == NULL || cClassList[0] == NULL || *cClassList[0] == '\0')
{
g_strfreev (cClassList);
return ;
}
CairoDockClassAppli *pClassAppli;
int i;
for (i = 0; cClassList[i] != NULL; i ++)
{
pClassAppli = cairo_dock_get_class (cClassList[i]);
pClassAppli->bExpand = TRUE;
}
g_strfreev (cClassList);
}
Icon *cairo_dock_get_prev_next_classmate_icon (Icon *pIcon, gboolean bNext)
{
cd_debug ("%s (%s, %s)", __func__, pIcon->cClass, pIcon->cName);
g_return_val_if_fail (pIcon->cClass != NULL, NULL);
Icon *pActiveIcon = cairo_dock_get_current_active_icon ();
if (pActiveIcon == NULL || pActiveIcon->cClass == NULL || strcmp (pActiveIcon->cClass, pIcon->cClass) != 0) // la fenetre active n'est pas de notre classe, on active l'icone fournies en entree.
{
cd_debug ("on active la classe %s", pIcon->cClass);
return pIcon;
}
//\________________ on va chercher dans la classe la fenetre active, et prendre la suivante ou la precedente.
Icon *pNextIcon = NULL;
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
if (pClassAppli == NULL)
return NULL;
//\________________ On cherche dans les icones d'applis.
Icon *pClassmateIcon;
GList *pElement, *ic;
for (pElement = pClassAppli->pAppliOfClass; pElement != NULL && pNextIcon == NULL; pElement = pElement->next)
{
pClassmateIcon = pElement->data;
cd_debug (" %s est-elle active ?", pClassmateIcon->cName);
if (pClassmateIcon->pAppli == pActiveIcon->pAppli) // on a trouve la fenetre active.
{
cd_debug (" fenetre active trouvee (%s; %p)", pClassmateIcon->cName, pClassmateIcon->pAppli);
if (bNext) // on prend la 1ere non nulle qui suit.
{
ic = pElement;
do
{
ic = cairo_dock_get_next_element (ic, pClassAppli->pAppliOfClass);
if (ic == pElement)
{
cd_debug (" on a fait le tour sans rien trouve");
break ;
}
pClassmateIcon = ic->data;
if (pClassmateIcon != NULL && pClassmateIcon->pAppli != NULL)
{
cd_debug (" ok on prend celle-la (%s; %p)", pClassmateIcon->cName, pClassmateIcon->pAppli);
pNextIcon = pClassmateIcon;
break ;
}
cd_debug ("un coup pour rien");
}
while (1);
}
else // on prend la 1ere non nulle qui precede.
{
ic = pElement;
do
{
ic = cairo_dock_get_previous_element (ic, pClassAppli->pAppliOfClass);
if (ic == pElement)
break ;
pClassmateIcon = ic->data;
if (pClassmateIcon != NULL && pClassmateIcon->pAppli != NULL)
{
pNextIcon = pClassmateIcon;
break ;
}
}
while (1);
}
break ;
}
}
return pNextIcon;
}
Icon *cairo_dock_get_inhibitor (Icon *pIcon, gboolean bOnlyInDock)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
if (pClassAppli != NULL)
{
GList *pElement;
Icon *pInhibitorIcon;
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
{
pInhibitorIcon = pElement->data;
if (pInhibitorIcon->pAppli == pIcon->pAppli)
{
if (! bOnlyInDock || cairo_dock_get_icon_container (pInhibitorIcon) != NULL)
return pInhibitorIcon;
}
}
}
return NULL;
}
/* Not used
static gboolean _appli_is_older (Icon *pIcon1, Icon *pIcon2, CairoDockClassAppli *pClassAppli) // TRUE if icon1 older than icon2
{
Icon *pAppliIcon;
GList *ic;
for (ic = pClassAppli->pAppliOfClass; ic != NULL; ic = ic->next)
{
pAppliIcon = ic->data;
if (pAppliIcon == pIcon1) // we found the icon1 first, so icon1 is more recent (prepend).
return FALSE;
if (pAppliIcon == pIcon2) // we found the icon2 first, so icon2 is more recent (prepend).
return TRUE;
}
return FALSE;
}
*/
static inline double _get_previous_order (GList *ic)
{
if (ic == NULL)
return 0;
double fOrder;
Icon *icon = ic->data;
Icon *prev_icon = (ic->prev ? ic->prev->data : NULL);
if (prev_icon != NULL && cairo_dock_get_icon_order (prev_icon) == cairo_dock_get_icon_order (icon))
fOrder = (icon->fOrder + prev_icon->fOrder) / 2;
else
fOrder = icon->fOrder - 1;
return fOrder;
}
static inline double _get_next_order (GList *ic)
{
if (ic == NULL)
return 0;
double fOrder;
Icon *icon = ic->data;
Icon *next_icon = (ic->next ? ic->next->data : NULL);
if (next_icon != NULL && cairo_dock_get_icon_order (next_icon) == cairo_dock_get_icon_order (icon))
fOrder = (icon->fOrder + next_icon->fOrder) / 2;
else
fOrder = icon->fOrder + 1;
return fOrder;
}
static inline double _get_first_appli_order (CairoDock *pDock, GList *first_launcher_ic, GList *last_launcher_ic)
{
double fOrder;
switch (myTaskbarParam.iIconPlacement)
{
case CAIRO_APPLI_BEFORE_FIRST_ICON:
fOrder = _get_previous_order (pDock->icons);
break;
case CAIRO_APPLI_BEFORE_FIRST_LAUNCHER:
if (first_launcher_ic != NULL)
{
//g_print (" go just before the first launcher (%s)\n", ((Icon*)first_launcher_ic->data)->cName);
fOrder = _get_previous_order (first_launcher_ic); // 'first_launcher_ic' includes the separators, so we can just take the previous order.
}
else // no launcher, go to the beginning of the dock.
{
fOrder = _get_previous_order (pDock->icons);
}
break;
case CAIRO_APPLI_AFTER_ICON:
{
Icon *icon;
GList *ic = NULL;
for (ic = pDock->icons; ic != NULL; ic = ic->next)
{
icon = ic->data;
if ((icon->cDesktopFileName != NULL && g_strcmp0 (icon->cDesktopFileName, myTaskbarParam.cRelativeIconName) == 0)
|| (icon->pModuleInstance && g_strcmp0 (icon->pModuleInstance->cConfFilePath, myTaskbarParam.cRelativeIconName) == 0))
break;
}
if (ic != NULL) // icon found
{
fOrder = _get_next_order (ic);
break;
} // else don't break, and go to the 'CAIRO_APPLI_AFTER_LAST_LAUNCHER' case, which will be the fallback.
}
case CAIRO_APPLI_AFTER_LAST_LAUNCHER:
default:
if (last_launcher_ic != NULL)
{
//g_print (" go just after the last launcher (%s)\n", ((Icon*)last_launcher_ic->data)->cName);
fOrder = _get_next_order (last_launcher_ic);
}
else // no launcher, go to the beginning of the dock.
{
fOrder = _get_previous_order (pDock->icons);
}
break;
case CAIRO_APPLI_AFTER_LAST_ICON:
fOrder = _get_next_order (g_list_last (pDock->icons));
break;
}
return fOrder;
}
static inline int _get_class_age (CairoDockClassAppli *pClassAppli)
{
if (pClassAppli->pAppliOfClass == NULL)
return 0;
return pClassAppli->iAge;
}
// Set the order of an appli when they are mixed amongst launchers and no class sub-dock exists (because either they are not grouped by class, or just it's the first appli of this class in the dock)
// First try to see if an inhibitor is present in the dock; if not, see if an appli of the same class is present in the dock.
// -> if yes, place it next to it, ordered by age (go to the right until our age is greater)
// -> if no, place it amongst the other appli icons, ordered by age (search the last launcher, skip any automatic separator, and then go to the right until our age is greater or there is no more appli).
void cairo_dock_set_class_order_in_dock (Icon *pIcon, CairoDock *pDock)
{
//g_print ("%s (%s, %d)\n", __func__, pIcon->cClass, pIcon->iAge);
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
g_return_if_fail (pClassAppli != NULL);
// Look for an icon of the same class in the dock, to place ourself relatively to it.
Icon *pSameClassIcon = NULL;
GList *same_class_ic = NULL;
// First look for an inhibitor of this class, preferably a launcher.
CairoDock *pParentDock;
Icon *pInhibitorIcon;
GList *ic;
for (ic = pClassAppli->pIconsOfClass; ic != NULL; ic = ic->next)
{
pInhibitorIcon = ic->data;
pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (pInhibitorIcon));
if (! GLDI_OBJECT_IS_DOCK(pParentDock)) // not inside a dock, for instance a desklet (or a hidden launcher) -> skip
continue;
pSameClassIcon = pInhibitorIcon;
same_class_ic = ic;
//g_print (" found an inhibitor of this class: %s (%d)\n", pSameClassIcon->cName, pSameClassIcon->iAge);
if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (pSameClassIcon)) // it's a launcher, we wont't find better -> quit
break ;
}
// if no inhibitor found, look for an appli of this class in the dock.
if (pSameClassIcon == NULL)
{
Icon *pAppliIcon;
for (ic = g_list_last (pClassAppli->pAppliOfClass); ic != NULL; ic = ic->prev) // check the older icons first (prepend), because then we'll place ourself to their right.
{
pAppliIcon = ic->data;
if (pAppliIcon == pIcon) // skip ourself
continue;
pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (pAppliIcon));
if (pParentDock != NULL)
{
pSameClassIcon = pAppliIcon;
same_class_ic = ic;
//g_print (" found an appli of this class: %s (%d)\n", pSameClassIcon->cName, pSameClassIcon->iAge);
break ;
}
}
pIcon->iGroup = (myTaskbarParam.bSeparateApplis ? CAIRO_DOCK_APPLI : CAIRO_DOCK_LAUNCHER); // no inhibitor, so we'll go in the taskbar group.
}
else // an inhibitor is present, we'll go next to it, so we'll be in its group.
{
pIcon->iGroup = pSameClassIcon->iGroup;
}
// if we found one, place next to it, ordered by age amongst the other appli of this class already in the dock.
if (pSameClassIcon != NULL)
{
same_class_ic = g_list_find (pDock->icons, pSameClassIcon);
g_return_if_fail (same_class_ic != NULL);
Icon *pNextIcon = NULL; // the next icon after all the icons of our class, or NULL if we reach the end of the dock.
for (ic = same_class_ic->next; ic != NULL; ic = ic->next)
{
pNextIcon = ic->data;
//g_print (" next icon: %s (%d)\n", pNextIcon->cName, pNextIcon->iAge);
if (!pNextIcon->cClass || strcmp (pNextIcon->cClass, pIcon->cClass) != 0) // not our class any more, quit.
break;
if (pIcon->pAppli->iAge > pNextIcon->pAppli->iAge) // we are more recent than this icon -> place on its right -> continue
{
pSameClassIcon = pNextIcon; // 'pSameClassIcon' will be the last icon of our class older than us.
pNextIcon = NULL;
}
else // we are older than it -> go just before it -> quit
{
break;
}
}
//g_print (" pNextIcon: %s (%d)\n", pNextIcon?pNextIcon->cName:"none", pNextIcon?pNextIcon->iAge:-1);
if (pNextIcon != NULL && cairo_dock_get_icon_order (pNextIcon) == cairo_dock_get_icon_order (pSameClassIcon)) // l'icone suivante est dans le meme groupe que nous, on s'intercalle entre elle et pSameClassIcon.
pIcon->fOrder = (pNextIcon->fOrder + pSameClassIcon->fOrder) / 2;
else // aucune icone apres notre classe, ou alors dans un groupe different, on se place juste apres pSameClassIcon.
pIcon->fOrder = pSameClassIcon->fOrder + 1;
return;
}
// if no icon of our class is present in the dock, place it amongst the other appli icons, after the first appli or after the launchers, and ordered by age.
// search the last launcher and the first appli.
Icon *icon;
Icon *pFirstLauncher = NULL;
GList *first_appli_ic = NULL, *last_launcher_ic = NULL, *first_launcher_ic = NULL;
for (ic = pDock->icons; ic != NULL; ic = ic->next)
{
icon = ic->data;
if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (icon) // launcher, even without class
|| CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (icon) // container icon (likely to contain some launchers)
|| (CAIRO_DOCK_ICON_TYPE_IS_APPLET (icon) && icon->pModuleInstance->pModule->pVisitCard->bActAsLauncher) // applet acting like a launcher
/**|| CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon)*/) // separator (user or auto).
{
// pLastLauncher = icon;
last_launcher_ic = ic;
if (pFirstLauncher == NULL)
{
pFirstLauncher = icon;
first_launcher_ic = ic;
}
}
else if ((CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon) || CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (icon))
&& ! cairo_dock_class_is_inhibited (icon->cClass)) // an appli not placed next to its inhibitor.
{
// pFirstAppli = icon;
first_appli_ic = ic;
break ;
}
}
//g_print (" last launcher: %s\n", pLastLauncher?pLastLauncher->cName:"none");
//g_print (" first appli: %s\n", pFirstAppli?pFirstAppli->cName:"none");
// place amongst the other applis, or after the last launcher.
if (first_appli_ic != NULL) // if an appli exists in the dock, use it as an anchor.
{
int iAge = _get_class_age (pClassAppli); // the age of our class.
GList *last_appli_ic = NULL; // last appli whose class is older than ours => we'll go just after.
for (ic = first_appli_ic; ic != NULL; ic = ic->next)
{
icon = ic->data;
if (! CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon) && ! CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (icon))
break;
// get the age of this class (= age of the oldest icon of this class)
CairoDockClassAppli *pOtherClassAppli = _cairo_dock_lookup_class_appli (icon->cClass);
if (! pOtherClassAppli || ! pOtherClassAppli->pAppliOfClass) // should never happen
continue;
int iOtherClassAge = _get_class_age (pOtherClassAppli);
//g_print (" age of class %s: %d\n", icon->cClass, iOtherClassAge);
// compare to our class.
if (iOtherClassAge < iAge) // it's older than our class -> skip this whole class, we'll go after.
{
Icon *next_icon;
while (ic->next != NULL)
{
next_icon = ic->next->data;
if (next_icon->cClass && strcmp (next_icon->cClass, icon->cClass) == 0) // next icon is of the same class -> skip
ic = ic->next;
else
break;
}
last_appli_ic = ic;
}
else // we are older -> discard and quit.
{
break;
}
}
if (last_appli_ic == NULL) // we are the oldest class -> go just before the first appli
{
//g_print (" we are the oldest class\n");
pIcon->fOrder = _get_previous_order (first_appli_ic);
}
else // go just after the last one
{
//g_print (" go just after %s\n", ((Icon*)last_appli_ic->data)->cName);
pIcon->fOrder = _get_next_order (last_appli_ic);
}
}
else // no appli yet in the dock -> place it at the taskbar position defined in conf.
{
pIcon->fOrder = _get_first_appli_order (pDock, first_launcher_ic, last_launcher_ic);
}
}
void cairo_dock_set_class_order_amongst_applis (Icon *pIcon, CairoDock *pDock) // set the order of an appli amongst the other applis of a given dock (class sub-dock or main dock).
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
g_return_if_fail (pClassAppli != NULL);
// place the icon amongst the other appli icons of this class, or after the last appli if none.
if (myTaskbarParam.bSeparateApplis)
pIcon->iGroup = CAIRO_DOCK_APPLI;
else
pIcon->iGroup = CAIRO_DOCK_LAUNCHER;
Icon *icon;
GList *ic, *last_ic = NULL, *first_appli_ic = NULL;
GList *last_launcher_ic = NULL, *first_launcher_ic = NULL;
for (ic = pDock->icons; ic != NULL; ic = ic->next)
{
icon = ic->data;
if (CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon))
{
if (! first_appli_ic)
first_appli_ic = ic;
if (icon->cClass && strcmp (icon->cClass, pIcon->cClass) == 0) // this icon is in our class.
{
if (!icon->pAppli || icon->pAppli->iAge < pIcon->pAppli->iAge) // it's older than us => we are more recent => go after => continue. (Note: icon->pAppli can be NULL if the icon in the dock is being removed)
{
last_ic = ic; // remember the last item of our class.
}
else // we are older than it => go just before it.
{
pIcon->fOrder = _get_previous_order (ic);
return ;
}
}
}
else if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (icon) // launcher, even without class
|| CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (icon) // container icon (likely to contain some launchers)
|| (CAIRO_DOCK_ICON_TYPE_IS_APPLET (icon) && icon->cClass != NULL && icon->pModuleInstance->pModule->pVisitCard->bActAsLauncher) // applet acting like a launcher
|| (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))) // separator (user or auto).
{
last_launcher_ic = ic;
if (first_launcher_ic == NULL)
{
first_launcher_ic = ic;
}
}
}
if (last_ic != NULL) // there are some applis of our class, but none are more recent than us, so we are the most recent => go just after the last one we found previously.
{
pIcon->fOrder = _get_next_order (last_ic);
}
else // we didn't find a single icon of our class => place amongst the other applis from age.
{
if (first_appli_ic != NULL) // if an appli exists in the dock, use it as an anchor.
{
Icon *pOldestAppli = g_list_last (pClassAppli->pAppliOfClass)->data; // prepend
int iAge = pOldestAppli->pAppli->iAge; // the age of our class.
GList *last_appli_ic = NULL; // last appli whose class is older than ours => we'll go just after.
for (ic = first_appli_ic; ic != NULL; ic = ic->next)
{
icon = ic->data;
if (! CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon) && ! CAIRO_DOCK_IS_MULTI_APPLI (icon))
break;
// get the age of this class (= age of the oldest icon of this class)
CairoDockClassAppli *pOtherClassAppli = _cairo_dock_lookup_class_appli (icon->cClass);
if (! pOtherClassAppli || ! pOtherClassAppli->pAppliOfClass) // should never happen
continue;
Icon *pOldestAppli = g_list_last (pOtherClassAppli->pAppliOfClass)->data; // prepend
// compare to our class.
if (pOldestAppli->pAppli->iAge < iAge) // it's older than our class -> skip this whole class, we'll go after.
{
while (ic->next != NULL)
{
icon = ic->next->data;
if (CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon) && icon->cClass && strcmp (icon->cClass, pOldestAppli->cClass) == 0) // next icon is an appli of the same class -> skip
ic = ic->next;
else
break;
}
last_appli_ic = ic;
}
else // we are older -> discard and quit.
{
break;
}
}
if (last_appli_ic == NULL) // we are the oldest class -> go just before the first appli
{
pIcon->fOrder = _get_previous_order (first_appli_ic);
}
else // go just after the last one
{
pIcon->fOrder = _get_next_order (last_appli_ic);
}
}
else // no appli, use the defined placement.
{
pIcon->fOrder = _get_first_appli_order (pDock, first_launcher_ic, last_launcher_ic);
}
}
}
static inline CairoDockClassAppli *_get_class_appli_with_attributes (const gchar *cClass)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
if (! pClassAppli->bSearchedAttributes)
{
gchar *cClass2 = cairo_dock_register_class (cClass);
g_free (cClass2);
}
return pClassAppli;
}
const gchar *cairo_dock_get_class_command (const gchar *cClass)
{
g_return_val_if_fail (cClass != NULL, NULL);
CairoDockClassAppli *pClassAppli = _get_class_appli_with_attributes (cClass);
return pClassAppli->cCommand;
}
const gchar *cairo_dock_get_class_name (const gchar *cClass)
{
g_return_val_if_fail (cClass != NULL, NULL);
CairoDockClassAppli *pClassAppli = _get_class_appli_with_attributes (cClass);
return pClassAppli->cName;
}
const gchar **cairo_dock_get_class_mimetypes (const gchar *cClass)
{
g_return_val_if_fail (cClass != NULL, NULL);
CairoDockClassAppli *pClassAppli = _get_class_appli_with_attributes (cClass);
return (const gchar **)pClassAppli->pMimeTypes;
}
const gchar *cairo_dock_get_class_desktop_file (const gchar *cClass)
{
g_return_val_if_fail (cClass != NULL, NULL);
CairoDockClassAppli *pClassAppli = _get_class_appli_with_attributes (cClass);
return pClassAppli->cDesktopFile;
}
const gchar *cairo_dock_get_class_icon (const gchar *cClass)
{
g_return_val_if_fail (cClass != NULL, NULL);
CairoDockClassAppli *pClassAppli = _get_class_appli_with_attributes (cClass);
return pClassAppli->cIcon;
}
const GList *cairo_dock_get_class_menu_items (const gchar *cClass)
{
g_return_val_if_fail (cClass != NULL, NULL);
CairoDockClassAppli *pClassAppli = _get_class_appli_with_attributes (cClass);
return pClassAppli->pMenuItems;
}
const gchar *cairo_dock_get_class_wm_class (const gchar *cClass)
{
g_return_val_if_fail (cClass != NULL, NULL);
CairoDockClassAppli *pClassAppli = _get_class_appli_with_attributes (cClass);
if (pClassAppli->cStartupWMClass == NULL) // if the WMClass has not been retrieved beforehand, do it now
{
cd_debug ("retrieve WMClass for %s...", cClass);
Icon *pIcon;
GList *ic;
for (ic = pClassAppli->pAppliOfClass; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (pIcon->pAppli && pIcon->pAppli->cWmClass)
{
pClassAppli->cStartupWMClass = g_strdup (pIcon->pAppli->cWmClass);
break;
}
}
}
return pClassAppli->cStartupWMClass;
}
const CairoDockImageBuffer *cairo_dock_get_class_image_buffer (const gchar *cClass)
{
static CairoDockImageBuffer image;
g_return_val_if_fail (cClass != NULL, NULL);
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
Icon *pIcon;
GList *ic;
for (ic = pClassAppli->pIconsOfClass; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (pIcon) && pIcon->image.pSurface) // avoid applets
{
memcpy (&image, &pIcon->image, sizeof (CairoDockImageBuffer));
return ℑ
}
}
for (ic = pClassAppli->pAppliOfClass; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (pIcon->image.pSurface)
{
memcpy (&image, &pIcon->image, sizeof (CairoDockImageBuffer));
return ℑ
}
}
return NULL;
}
static gchar *_search_desktop_file (const gchar *cDesktopFile) // file, path or even class
{
if (cDesktopFile == NULL)
return NULL;
if (*cDesktopFile == '/' && g_file_test (cDesktopFile, G_FILE_TEST_EXISTS)) // it's a path and it exists.
{
return g_strdup (cDesktopFile);
}
gchar *cDesktopFileName = NULL;
if (*cDesktopFile == '/')
cDesktopFileName = g_path_get_basename (cDesktopFile);
else if (! g_str_has_suffix (cDesktopFile, ".desktop"))
cDesktopFileName = g_strdup_printf ("%s.desktop", cDesktopFile);
const gchar *cFileName = (cDesktopFileName ? cDesktopFileName : cDesktopFile);
gboolean bFound = TRUE;
GString *sDesktopFilePath = g_string_new ("");
g_string_printf (sDesktopFilePath, "/usr/share/applications/%s", cFileName);
if (! g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS))
{
g_string_printf (sDesktopFilePath, "/usr/share/applications/%c%s", g_ascii_toupper (*cFileName), cFileName+1); // handle stupid cases like Thunar.desktop
if (! g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS))
{
g_string_printf (sDesktopFilePath, "/usr/share/applications/xfce4/%s", cFileName);
if (! g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS))
{
g_string_printf (sDesktopFilePath, "/usr/share/applications/kde4/%s", cFileName);
if (! g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS))
{
g_string_printf (sDesktopFilePath, "%s/.local/share/applications/%s", g_getenv ("HOME"), cFileName);
if (! g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS))
{
bFound = FALSE;
}
}
}
}
}
g_free (cDesktopFileName);
gchar *cResult;
if (bFound)
{
cResult = sDesktopFilePath->str;
g_string_free (sDesktopFilePath, FALSE);
}
else
{
cResult = NULL;
g_string_free (sDesktopFilePath, TRUE);
}
return cResult;
}
gchar *cairo_dock_guess_class (const gchar *cCommand, const gchar *cStartupWMClass)
{
// plusieurs cas sont possibles :
// Exec=toto
// Exec=toto-1.2
// Exec=toto -x -y
// Exec=/path/to/toto -x -y
// Exec=gksu nautilus / (or kdesu)
// Exec=su-to-root -X -c /usr/sbin/synaptic
// Exec=gksu --description /usr/share/applications/synaptic.desktop /usr/sbin/synaptic
// Exec=wine "C:\Program Files\Starcraft\Starcraft.exe"
// Exec=wine "/path/to/prog.exe"
// Exec=env WINEPREFIX="/home/fab/.wine" wine "C:\Program Files\Starcraft\Starcraft.exe"
cd_debug ("%s (%s, '%s')", __func__, cCommand, cStartupWMClass);
gchar *cResult = NULL;
if (cStartupWMClass == NULL || *cStartupWMClass == '\0' || strcmp (cStartupWMClass, "Wine") == 0) // on force pour wine, car meme si la classe est explicitement definie en tant que "Wine", cette information est inexploitable.
{
if (cCommand == NULL || *cCommand == '\0')
return NULL;
gchar *cDefaultClass = g_ascii_strdown (cCommand, -1);
gchar *str;
const gchar *cClass = cDefaultClass; // pointer to the current class.
if (strncmp (cClass, "gksu", 4) == 0 || strncmp (cClass, "kdesu", 5) == 0 || strncmp (cClass, "su-to-root", 10) == 0) // on prend la fin.
{
str = (gchar*)cClass + strlen(cClass) - 1; // last char.
while (*str == ' ') // par securite on enleve les espaces en fin de ligne.
*(str--) = '\0';
str = strchr (cClass, ' '); // on cherche le premier espace.
if (str != NULL) // on prend apres.
{
while (*str == ' ')
str ++;
cClass = str;
} // la on a vire le gksu.
if (*cClass == '-') // option, on prend le dernier argument de la commande.
{
str = strrchr (cClass, ' '); // on cherche le dernier espace.
if (str != NULL) // on prend apres.
cClass = str + 1;
}
else // on prend le premier argument.
{
str = strchr (cClass, ' '); // on cherche le premier espace.
if (str != NULL) // on vire apres.
*str = '\0';
}
str = strrchr (cClass, '/'); // on cherche le dernier '/'.
if (str != NULL) // on prend apres.
cClass = str + 1;
}
else if ((str = g_strstr_len (cClass, -1, "wine ")) != NULL)
{
cClass = str; // on met deja la classe a "wine", c'est mieux que rien.
*(str+4) = '\0';
str += 5;
while (*str == ' ') // on enleve les espaces supplementaires.
str ++;
gchar *exe = g_strstr_len (str, -1, ".exe"); // on cherche a isoler le nom de l'executable, puisque wine l'utilise dans le res_name.
if (!exe)
exe = g_strstr_len (str, -1, ".EXE");
if (exe)
{
*exe = '\0'; // vire l'extension par la meme occasion.
gchar *slash = strrchr (str, '\\');
if (slash)
cClass = slash+1;
else
{
slash = strrchr (str, '/');
if (slash)
cClass = slash+1;
else
cClass = str;
}
}
cd_debug (" special case : wine application => class = '%s'", cClass);
}
else
{
while (*cClass == ' ') // par securite on enleve les espaces en debut de ligne.
cClass ++;
str = strchr (cClass, ' '); // on cherche le premier espace.
if (str != NULL) // on vire apres.
*str = '\0';
str = strrchr (cClass, '/'); // on cherche le dernier '/'.
if (str != NULL) // on prend apres.
cClass = str + 1;
str = strchr (cClass, '.'); // on vire les .xxx, sinon on ne sait pas detecter l'absence d'extension quand on cherche l'icone (openoffice.org), ou tout simplement ca empeche de trouver l'icone (jbrout.py).
if (str != NULL && str != cClass)
*str = '\0';
}
// handle the cases of programs where command != class.
if (*cClass != '\0')
{
if (strncmp (cClass, "oo", 2) == 0)
{
if (strcmp (cClass, "ooffice") == 0 || strcmp (cClass, "oowriter") == 0 || strcmp (cClass, "oocalc") == 0 || strcmp (cClass, "oodraw") == 0 || strcmp (cClass, "ooimpress") == 0) // openoffice poor design: there is no way to bind its windows to the launcher without this trick.
cClass = "openoffice";
}
else if (strncmp (cClass, "libreoffice", 11) == 0) // libreoffice has different classes according to the launching option (--writer => libreoffice-writer, --calc => libreoffice-calc, etc)
{
gchar *str = strchr (cCommand, ' ');
if (str && *(str+1) == '-')
{
g_free (cDefaultClass);
cDefaultClass = g_strdup_printf ("%s%s", "libreoffice", str+2);
str = strchr (cDefaultClass, ' '); // remove the additionnal params of the command.
if (str)
*str = '\0';
cClass = cDefaultClass; // "libreoffice-writer"
}
}
cResult = g_strdup (cClass);
}
g_free (cDefaultClass);
}
else
{
cResult = g_ascii_strdown (cStartupWMClass, -1);
gchar *str = strchr (cResult, '.'); // on vire les .xxx, sinon on ne sait pas detecter l'absence d'extension quand on cherche l'icone (openoffice.org), ou tout simplement ca empeche de trouver l'icone (jbrout.py).
if (str != NULL)
*str = '\0';
}
cairo_dock_remove_version_from_string (cResult);
cd_debug (" -> '%s'", cResult);
return cResult;
}
static void _add_action_menus (GKeyFile *pKeyFile, CairoDockClassAppli *pClassAppli, const gchar *cGettextDomain, const gchar *cMenuListKey, const gchar *cMenuGroup, gboolean bActionFirstInGroupKey)
{
gsize length = 0;
gchar **pMenuList = g_key_file_get_string_list (pKeyFile, "Desktop Entry", cMenuListKey, &length, NULL);
if (pMenuList != NULL)
{
gchar *cGroup;
int i;
for (i = 0; pMenuList[i] != NULL; i++)
{
cGroup = g_strdup_printf ("%s %s",
bActionFirstInGroupKey ? pMenuList[i] : cMenuGroup, // [NewWindow Shortcut Group]
bActionFirstInGroupKey ? cMenuGroup : pMenuList [i]); // [Desktop Action NewWindow]
if (g_key_file_has_group (pKeyFile, cGroup))
{
gchar **pMenuItem = g_new0 (gchar*, 4);
// for a few apps, the translations are directly available in the .desktop file (e.g. firefox)
gchar *cName = g_key_file_get_locale_string (pKeyFile, cGroup, "Name", NULL, NULL);
pMenuItem[0] = g_strdup (dgettext (cGettextDomain, cName)); // but most of the time, it's available in the .mo file
g_free (cName);
gchar *cCommand = g_key_file_get_string (pKeyFile, cGroup, "Exec", NULL);
if (cCommand != NULL) // remove the launching options %x.
{
gchar *str = strchr (cCommand, '%'); // search the first one.
if (str != NULL)
{
if (str != cCommand && (*(str-1) == '"' || *(str-1) == '\'')) // take care of "" around the option.
str --;
*str = '\0'; // il peut rester un espace en fin de chaine, ce n'est pas grave.
}
}
pMenuItem[1] = cCommand;
pMenuItem[2] = g_key_file_get_string (pKeyFile, cGroup, "Icon", NULL);
pClassAppli->pMenuItems = g_list_append (pClassAppli->pMenuItems, pMenuItem);
}
g_free (cGroup);
}
g_strfreev (pMenuList);
}
}
/*
register from desktop-file name/path (+class-name):
if class-name: guess class -> lookup class -> if already registered => quit
search complete path -> not found => abort
get main info from file (Exec, StartupWMClass)
if class-name NULL: guess class from Exec+StartupWMClass
if already registered => quit
make new class
get additional params from file (MimeType, Icon, etc) and store them in the class
register from class name (window or old launchers):
guess class -> lookup class -> if already registered => quit
search complete path -> not found => abort
make new class
get additional params from file (MimeType, Icon, etc) and store them in the class
*/
gchar *cairo_dock_register_class_full (const gchar *cDesktopFile, const gchar *cClassName, const gchar *cWmClass)
{
g_return_val_if_fail (cDesktopFile != NULL || cClassName != NULL, NULL);
//g_print ("%s (%s, %s, %s)\n", __func__, cDesktopFile, cClassName, cWmClass);
//\__________________ if the class is already registered and filled, quit.
gchar *cClass = NULL;
if (cClassName != NULL)
cClass = cairo_dock_guess_class (NULL, cClassName);
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (cClass?cClass:cDesktopFile);
if (pClassAppli != NULL && pClassAppli->bSearchedAttributes && pClassAppli->cDesktopFile) // we already searched this class, and we did find its .desktop file, so let's end here.
{
//g_print ("class %s already known (%s)\n", cClass?cClass:cDesktopFile, pClassAppli->cDesktopFile);
if (pClassAppli->cStartupWMClass == NULL && cWmClass != NULL) // if the cStartupWMClass was not defined in the .desktop file, store it now.
pClassAppli->cStartupWMClass = g_strdup (cWmClass);
//g_print ("%s --> %s\n", cClass, pClassAppli->cStartupWMClass);
return (cClass?cClass:g_strdup (cDesktopFile));
}
//\__________________ search the desktop file's path.
gchar *cDesktopFilePath = _search_desktop_file (cDesktopFile?cDesktopFile:cClass);
if (cDesktopFilePath == NULL) // couldn't find the .desktop
{
if (cClass != NULL) // make a class anyway to store the few info we have.
{
if (pClassAppli == NULL)
pClassAppli = cairo_dock_get_class (cClass);
if (pClassAppli != NULL)
{
if (pClassAppli->cStartupWMClass == NULL && cWmClass != NULL)
pClassAppli->cStartupWMClass = g_strdup (cWmClass);
//g_print ("%s ---> %s\n", cClass, pClassAppli->cStartupWMClass);
pClassAppli->bSearchedAttributes = TRUE;
}
}
cd_debug ("couldn't find the desktop file %s", cDesktopFile?cDesktopFile:cClass);
return cClass; /// NULL
}
//\__________________ open it.
cd_debug ("+ parsing class desktop file %s...", cDesktopFilePath);
GKeyFile* pKeyFile = cairo_dock_open_key_file (cDesktopFilePath);
g_return_val_if_fail (pKeyFile != NULL, NULL);
//\__________________ guess the class name.
gchar *cCommand = g_key_file_get_string (pKeyFile, "Desktop Entry", "Exec", NULL);
gchar *cStartupWMClass = g_key_file_get_string (pKeyFile, "Desktop Entry", "StartupWMClass", NULL);
if (cStartupWMClass && *cStartupWMClass == '\0')
{
g_free (cStartupWMClass);
cStartupWMClass = NULL;
}
if (cClass == NULL)
cClass = cairo_dock_guess_class (cCommand, cStartupWMClass);
if (cClass == NULL)
{
cd_debug ("couldn't guess the class for %s", cDesktopFile);
g_free (cDesktopFilePath);
g_free (cCommand);
g_free (cStartupWMClass);
return NULL;
}
//\__________________ make a new class or get the existing one.
pClassAppli = cairo_dock_get_class (cClass);
g_return_val_if_fail (pClassAppli!= NULL, NULL);
//\__________________ if we already searched and found the attributes beforehand, quit.
if (pClassAppli->bSearchedAttributes && pClassAppli->cDesktopFile)
{
if (pClassAppli->cStartupWMClass == NULL && cWmClass != NULL) // we already searched this class before, but we couldn't have its WM class.
pClassAppli->cStartupWMClass = g_strdup (cWmClass);
//g_print ("%s ----> %s\n", cClass, pClassAppli->cStartupWMClass);
g_free (cDesktopFilePath);
g_free (cCommand);
g_free (cStartupWMClass);
return cClass;
}
pClassAppli->bSearchedAttributes = TRUE;
//\__________________ get the attributes.
pClassAppli->cDesktopFile = cDesktopFilePath;
pClassAppli->cName = g_key_file_get_locale_string (pKeyFile, "Desktop Entry", "Name", NULL, NULL);
if (cCommand != NULL) // remove the launching options %x.
{
gchar *str = strchr (cCommand, '%'); // search the first one.
if (str && *(str+1) == 'c') // this one (caption) is the only one that is expected (ex.: kreversi -caption "%c"; if we let '-caption' with nothing after, the appli will melt down); others are either URL or icon that can be empty as per the freedesktop specs, so we can sefely remove them completely from the command line.
{
*str = '\0';
gchar *cmd2 = g_strdup_printf ("%s%s%s", cCommand, pClassAppli->cName, str+2); // replace %c with the localized name.
g_free (cCommand);
cCommand = cmd2;
str = strchr (cCommand, '%'); // jump to the next one.
}
if (str != NULL) // remove everything from the first option to the end.
{
if (str != cCommand && (*(str-1) == '"' || *(str-1) == '\'')) // take care of "" around the option.
str --;
*str = '\0'; // il peut rester un espace en fin de chaine, ce n'est pas grave.
}
}
pClassAppli->cCommand = cCommand;
if (pClassAppli->cStartupWMClass == NULL)
pClassAppli->cStartupWMClass = (cStartupWMClass ? cStartupWMClass : g_strdup (cWmClass));
//g_print ("%s -> pClassAppli->cStartupWMClass: %s\n", cClass, pClassAppli->cStartupWMClass);
pClassAppli->cIcon = g_key_file_get_string (pKeyFile, "Desktop Entry", "Icon", NULL);
if (pClassAppli->cIcon != NULL && *pClassAppli->cIcon != '/') // remove any extension.
{
gchar *str = strrchr (pClassAppli->cIcon, '.');
if (str && (strcmp (str+1, "png") == 0 || strcmp (str+1, "svg") == 0 || strcmp (str+1, "xpm") == 0))
*str = '\0';
}
gsize length = 0;
pClassAppli->pMimeTypes = g_key_file_get_string_list (pKeyFile, "Desktop Entry", "MimeType", &length, NULL);
pClassAppli->cWorkingDirectory = g_key_file_get_string (pKeyFile, "Desktop Entry", "Path", NULL);
pClassAppli->bHasStartupNotify = g_key_file_get_boolean (pKeyFile, "Desktop Entry", "StartupNotify", NULL); // let's handle the case StartupNotify=false as if the key was absent (ie: rely on the window events to stop the launching)
//\__________________ Gettext domain
// The translations of the quicklist menus are generally available in a .mo file
gchar *cGettextDomain = g_key_file_get_string (pKeyFile, "Desktop Entry", "X-Ubuntu-Gettext-Domain", NULL);
if (cGettextDomain == NULL)
cGettextDomain = g_key_file_get_string (pKeyFile, "Desktop Entry", "X-GNOME-Gettext-Domain", NULL); // Yes, they like doing that :P
// a few time ago, it seems that it was 'X-Gettext-Domain'
//______________ Quicklist menus.
_add_action_menus (pKeyFile, pClassAppli, cGettextDomain, "X-Ayatana-Desktop-Shortcuts", "Shortcut Group", TRUE); // oh crap, with a name like that you can be sure it will change 25 times before they decide a definite name :-/
_add_action_menus (pKeyFile, pClassAppli, cGettextDomain, "Actions", "Desktop Action", FALSE); // yes, it's true ^^ => Ubuntu Quantal
g_free (cGettextDomain);
g_key_file_free (pKeyFile);
cd_debug (" -> class '%s'", cClass);
return cClass;
}
void cairo_dock_set_data_from_class (const gchar *cClass, Icon *pIcon)
{
g_return_if_fail (cClass != NULL && pIcon != NULL);
cd_debug ("%s (%s)", __func__, cClass);
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (cClass);
if (pClassAppli == NULL || ! pClassAppli->bSearchedAttributes)
{
cd_debug ("no class %s or no attributes", cClass);
return;
}
if (pIcon->cCommand == NULL)
pIcon->cCommand = g_strdup (pClassAppli->cCommand);
if (pIcon->cWorkingDirectory == NULL)
pIcon->cWorkingDirectory = g_strdup (pClassAppli->cWorkingDirectory);
if (pIcon->cName == NULL)
pIcon->cName = g_strdup (pClassAppli->cName);
if (pIcon->cFileName == NULL)
pIcon->cFileName = g_strdup (pClassAppli->cIcon);
if (pIcon->pMimeTypes == NULL)
pIcon->pMimeTypes = g_strdupv ((gchar**)pClassAppli->pMimeTypes);
}
static gboolean _stop_opening_timeout (const gchar *cClass)
{
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
g_return_val_if_fail (pClassAppli != NULL, FALSE);
pClassAppli->iSidOpeningTimeout = 0;
gldi_class_startup_notify_end (cClass);
return FALSE;
}
void gldi_class_startup_notify (Icon *pIcon)
{
const gchar *cClass = pIcon->cClass;
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
if (! pClassAppli || pClassAppli->bIsLaunching)
return;
// mark the class as launching and set a timeout
pClassAppli->bIsLaunching = TRUE;
if (pClassAppli->iSidOpeningTimeout == 0)
pClassAppli->iSidOpeningTimeout = g_timeout_add_seconds (15, // 15 seconds, for applications that take a really long time to start
(GSourceFunc) _stop_opening_timeout, g_strdup (cClass)); /// TODO: there is a memory leak here...
// notify about the startup
gldi_desktop_notify_startup (cClass);
// mark the icon as launching (this is just for convenience for the animations)
gldi_icon_mark_as_launching (pIcon);
}
void gldi_class_startup_notify_end (const gchar *cClass)
{
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (cClass);
if (! pClassAppli || ! pClassAppli->bIsLaunching)
return;
// unset the icons as launching
GList* ic;
Icon *icon;
for (ic = pClassAppli->pIconsOfClass; ic != NULL; ic = ic->next)
{
icon = ic->data;
gldi_icon_stop_marking_as_launching (icon);
}
for (ic = pClassAppli->pAppliOfClass; ic != NULL; ic = ic->next)
{
icon = ic->data;
gldi_icon_stop_marking_as_launching (icon);
}
// unset the class as launching and stop a timeout
pClassAppli->bIsLaunching = FALSE;
if (pClassAppli->iSidOpeningTimeout != 0)
{
g_source_remove (pClassAppli->iSidOpeningTimeout);
pClassAppli->iSidOpeningTimeout = 0;
}
}
gboolean gldi_class_is_starting (const gchar *cClass)
{
CairoDockClassAppli *pClassAppli = _cairo_dock_lookup_class_appli (cClass);
return (pClassAppli != NULL && pClassAppli->iSidOpeningTimeout != 0);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-draw.h 000664 001750 001750 00000021732 12223247550 021710 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_DRAW__
#define __CAIRO_DOCK_DRAW__
#include
#include "cairo-dock-struct.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-draw.h This class provides some useful functions to draw with libcairo.
*/
///////////////
/// CONTEXT ///
///////////////
/** Create a generic drawing context, to be used as a source context (for instance, for creating a surface).
*@param pContainer a container.
*@return the context on which to draw. Is never NULL, test it with cairo_status() before use it, and destroy it with cairo_destroy() when you're done with it.
*/
cairo_t * cairo_dock_create_drawing_context_generic (GldiContainer *pContainer);
#define cairo_dock_create_context_from_window cairo_dock_create_drawing_context_generic
#define cairo_dock_create_context_from_container cairo_dock_create_drawing_context_generic
/** Create a drawing context to draw on a container. It handles fake transparency.
*@param pContainer the container on which you want to draw.
*@return the newly allocated context, to be destroyed with 'cairo_destroy'.
*/
cairo_t *cairo_dock_create_drawing_context_on_container (GldiContainer *pContainer);
#define cairo_dock_create_drawing_context cairo_dock_create_drawing_context_on_container
/** Create a drawing context to draw on a part of a container. It handles fake transparency.
*@param pContainer the container on which you want to draw
*@param pArea part of the container to draw.
*@param fBgColor background color (rgba) to fill the area with, or NULL to let it transparent.
*@return the newly allocated context, with a clip corresponding to the area, to be destroyed with 'cairo_destroy'.
*/
cairo_t *cairo_dock_create_drawing_context_on_area (GldiContainer *pContainer, GdkRectangle *pArea, double *fBgColor);
double cairo_dock_calculate_extra_width_for_trapeze (double fFrameHeight, double fInclination, double fRadius, double fLineWidth);
/** Compute the path of a rectangle with rounded corners. It doesn't stroke it, use cairo_stroke or cairo_fill to draw the line or the inside.
*@param pCairoContext a drawing context; the current matrix is not altered, but the current path is.
*@param fRadius radius if the corners.
*@param fLineWidth width of the line.
*@param fFrameWidth width of the rectangle, without the corners.
*@param fFrameHeight height of the rectangle, including the corners.
*/
void cairo_dock_draw_rounded_rectangle (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight);
/* Trace sur the context un contour trapezoidale aux coins arrondis. Le contour n'est pas dessine, mais peut l'etre a posteriori, et peut servir de cadre pour y dessiner des choses dedans.
*@param pCairoContext the context du dessin, contenant le cadre a la fin de la fonction.
*@param fRadius le rayon en pixels des coins.
*@param fLineWidth l'epaisseur en pixels du contour.
*@param fFrameWidth la largeur de la plus petite base du trapeze.
*@param fFrameHeight la hauteur du trapeze.
*@param fDockOffsetX un decalage, dans le sens de la largeur du dock, a partir duquel commencer a tracer la plus petite base du trapeze.
*@param fDockOffsetY un decalage, dans le sens de la hauteur du dock, a partir duquel commencer a tracer la plus petite base du trapeze.
*@param sens 1 pour un tracer dans le sens des aiguilles d'une montre (indirect), -1 sinon.
*@param fInclination tangente de l'angle d'inclinaison des cotes du trapeze par rapport a la vertical. 0 pour tracer un rectangle.
*@param bHorizontal CAIRO_DOCK_HORIZONTAL ou CAIRO_DOCK_VERTICAL suivant l'horizontalité du dock.
*/
double cairo_dock_draw_frame (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, int sens, double fInclination, gboolean bHorizontal, gboolean bRoundedBottomCorner);
/* Dessine les decorations d'un dock a l'interieur d'un cadre prealablement trace sur the context.
*@param pCairoContext the context du dessin, est laisse intact par la fonction.
*@param pDock le dock sur lequel appliquer les decorations.
*@param fOffsetY position du coin haut gauche du cadre, dans le sens de la hauteur du dock.
*@param fOffsetX position du coin haut gauche du cadre, dans le sens de la largeur du dock.
*@param fWidth largeur du cadre (et donc des decorations)
*/
void cairo_dock_render_decorations_in_frame (cairo_t *pCairoContext, CairoDock *pDock, double fOffsetY, double fOffsetX, double fWidth);
void cairo_dock_set_icon_scale_on_context (cairo_t *pCairoContext, Icon *icon, gboolean bIsHorizontal, double fRatio, gboolean bDirectionUp);
void cairo_dock_draw_icon_reflect_cairo (Icon *icon, GldiContainer *pContainer, cairo_t *pCairoContext);
/** Draw an icon and its reflect on a dock. Only draw the icon's image and reflect, and nothing else.
*@param icon the icon to draw.
*@param pDock the dock containing the icon.
*@param pCairoContext a context on the dock, not altered by the function.
*/
void cairo_dock_draw_icon_cairo (Icon *icon, CairoDock *pDock, cairo_t *pCairoContext);
gboolean cairo_dock_render_icon_notification (gpointer pUserData, Icon *pIcon, CairoDock *pDock, gboolean *bHasBeenRendered, cairo_t *pCairoContext);
/** Draw an icon, according to its current parameters : position, transparency, reflect, rotation, stretching. Also draws its indicators, label, and quick-info. It generates a CAIRO_DOCK_RENDER_ICON notification.
*@param icon the icon to draw.
*@param pDock the dock containing the icon.
*@param pCairoContext a context on the dock, it is altered by the function.
*@param fDockMagnitude current magnitude of the dock.
*@param bUseText TRUE to draw the labels.
*/
void cairo_dock_render_one_icon (Icon *icon, CairoDock *pDock, cairo_t *pCairoContext, double fDockMagnitude, gboolean bUseText);
void cairo_dock_render_icons_linear (cairo_t *pCairoContext, CairoDock *pDock);
void cairo_dock_render_one_icon_in_desklet (Icon *icon, GldiContainer *pContainer, cairo_t *pCairoContext, gboolean bUseText);
/** Draw a string linking the center of all the icons of a dock.
*@param pCairoContext a context on the dock, not altered by the function.
*@param pDock the dock.
*@param fStringLineWidth width of the line.
*@param bIsLoop TRUE to loop (link the last icon to the first one).
*@param bForceConstantSeparator TRUE to consider separators having a constant size.
*/
void cairo_dock_draw_string (cairo_t *pCairoContext, CairoDock *pDock, double fStringLineWidth, gboolean bIsLoop, gboolean bForceConstantSeparator);
void cairo_dock_draw_surface (cairo_t *pCairoContext, cairo_surface_t *pSurface, int iWidth, int iHeight, gboolean bDirectionUp, gboolean bHorizontal, gdouble fAlpha);
/** Erase a drawing context, making it fully transparent. You don't need to erase a newly created context.
*@param pCairoContext a drawing context.
*/
#define cairo_dock_erase_cairo_context(pCairoContext) do {\
cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 0.0);\
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);\
cairo_paint (pCairoContext);\
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER); } while (0)
void cairo_dock_render_hidden_dock (cairo_t *pCairoContext, CairoDock *pDock);
/*#define _cairo_dock_extend_area(area, x, y, w, h) do {\
int xmin = MIN (area.x, x);
int ymin = MIN (area.y, y);
area.width = MAX (area.x + area.width, x + w) - xmin;\
area.height = MAX (area.y + area.height, y + h) - ymin;\
area.x = MIN (area.x, x);\
area.y = MIN (area.y, y); } while (0)
#define _cairo_dock_compute_areas_bounded_box(area, area_) _cairo_dock_extend_area (area, area_.x, area_.y, area_.width, area_.height)
#define cairo_dock_damage_container_area(pContainer, area) _cairo_dock_compute_areas_bounded_box (pContainer->damageArea, area)
#define cairo_dock_damage_icon(pIcon, pContainer) do {\
cairo_rectangle_int_t area;\
cairo_dock_compute_icon_area (icon, pContainer, &area);\
cairo_dock_damage_container_area(pContainer, area); } while (0)
#define cairo_dock_damage_container(pContainer) do {\
pContainer->damageArea.x = 0;\
pContainer->damageArea.y = 0;\
if (pContainer->bHorizontal) {\
pContainer->damageArea.width = pContainer->iWidth;\
pContainer->damageArea.height = pContainer->iHeight; }\
else {\
pContainer->damageArea.width = pContainer->iHeight;\
pContainer->damageArea.height = pContainer->iWidth; }\
} while (0)*/
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/texture-blur.h 000664 001750 001750 00000040655 12223247550 021411 0 ustar 00mbaerts mbaerts 000000 000000 /**
*
* Particle texture for Beryl benchmark plugin
*
* Copyright : (C) 2006 by Dennis Kasprzyk
* E-mail : onestone@beryl-project.org
*
*
* 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 3
* 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.
*
**/
static const unsigned char blurTex[4096] = {
"\0\0\0\0\377\377\377\3\377\377\377\2\377\377\377\5\377\377\377\7\377\377"
"\377\6\377\377\377\6\377\377\377\12\377\377\377\13\377\377\377\11\377\377"
"\377\12\377\377\377\12\377\377\377\14\377\377\377\14\377\377\377\14\377\377"
"\377\16\377\377\377\15\377\377\377\14\377\377\377\12\377\377\377\13\377\377"
"\377\13\377\377\377\11\377\377\377\12\377\377\377\12\377\377\377\10\377\377"
"\377\7\377\377\377\6\377\377\377\6\377\377\377\5\377\377\377\2\0\0\0\0\0"
"\0\0\0\377\377\377\4\377\377\377\3\377\377\377\4\377\377\377\7\377\377\377"
"\6\377\377\377\10\377\377\377\11\377\377\377\11\377\377\377\14\377\377\377"
"\14\377\377\377\15\377\377\377\16\377\377\377\20\377\377\377\21\377\377\377"
"\20\377\377\377\22\377\377\377\20\377\377\377\21\377\377\377\17\377\377\377"
"\20\377\377\377\17\377\377\377\13\377\377\377\13\377\377\377\13\377\377\377"
"\14\377\377\377\11\377\377\377\6\377\377\377\6\377\377\377\6\377\377\377"
"\4\377\377\377\1\0\0\0\0\377\377\377\5\377\377\377\4\377\377\377\6\377\377"
"\377\6\377\377\377\12\377\377\377\12\377\377\377\11\377\377\377\14\377\377"
"\377\15\377\377\377\20\377\377\377\20\377\377\377\24\377\377\377\24\377\377"
"\377\23\377\377\377\23\377\377\377\26\377\377\377\25\377\377\377\23\377\377"
"\377\21\377\377\377\24\377\377\377\22\377\377\377\17\377\377\377\17\377\377"
"\377\15\377\377\377\15\377\377\377\11\377\377\377\11\377\377\377\7\377\377"
"\377\7\377\377\377\6\377\377\377\3\377\377\377\3\377\377\377\6\377\377\377"
"\6\377\377\377\6\377\377\377\12\377\377\377\13\377\377\377\13\377\377\377"
"\13\377\377\377\17\377\377\377\22\377\377\377\24\377\377\377\22\377\377\377"
"\30\377\377\377\30\377\377\377\31\377\377\377\31\377\377\377\33\377\377\377"
"\31\377\377\377\30\377\377\377\30\377\377\377\30\377\377\377\25\377\377\377"
"\25\377\377\377\23\377\377\377\22\377\377\377\17\377\377\377\13\377\377\377"
"\12\377\377\377\11\377\377\377\7\377\377\377\6\377\377\377\5\377\377\377"
"\4\377\377\377\7\377\377\377\6\377\377\377\12\377\377\377\11\377\377\377"
"\14\377\377\377\15\377\377\377\20\377\377\377\22\377\377\377\25\377\377\377"
"\30\377\377\377\32\377\377\377\35\377\377\377\34\377\377\377\34\377\377\377"
"\36\377\377\377\40\377\377\377\36\377\377\377\34\377\377\377\34\377\377\377"
"\34\377\377\377\32\377\377\377\31\377\377\377\26\377\377\377\25\377\377\377"
"\22\377\377\377\16\377\377\377\12\377\377\377\12\377\377\377\12\377\377\377"
"\10\377\377\377\6\377\377\377\4\377\377\377\10\377\377\377\11\377\377\377"
"\12\377\377\377\13\377\377\377\16\377\377\377\21\377\377\377\22\377\377\377"
"\25\377\377\377\30\377\377\377\34\377\377\377\37\377\377\377!\377\377\377"
"\"\377\377\377#\377\377\377#\377\377\377&\377\377\377&\377\377\377$\377\377"
"\377#\377\377\377\40\377\377\377!\377\377\377\35\377\377\377\34\377\377\377"
"\25\377\377\377\24\377\377\377\21\377\377\377\15\377\377\377\14\377\377\377"
"\14\377\377\377\12\377\377\377\6\377\377\377\6\377\377\377\10\377\377\377"
"\12\377\377\377\12\377\377\377\16\377\377\377\22\377\377\377\24\377\377\377"
"\26\377\377\377\30\377\377\377\34\377\377\377\37\377\377\377#\377\377\377"
"&\377\377\377,\377\377\377+\377\377\377,\377\377\377-\377\377\377-\377\377"
"\377,\377\377\377+\377\377\377&\377\377\377)\377\377\377$\377\377\377\34"
"\377\377\377\34\377\377\377\27\377\377\377\24\377\377\377\23\377\377\377"
"\17\377\377\377\15\377\377\377\12\377\377\377\7\377\377\377\6\377\377\377"
"\12\377\377\377\12\377\377\377\16\377\377\377\21\377\377\377\22\377\377\377"
"\27\377\377\377\31\377\377\377\36\377\377\377!\377\377\377%\377\377\377("
"\377\377\3771\377\377\3772\377\377\3775\377\377\377;\377\377\377<\377\377"
"\3779\377\377\3778\377\377\3773\377\377\3771\377\377\377-\377\377\377'\377"
"\377\377\"\377\377\377\34\377\377\377\36\377\377\377\32\377\377\377\25\377"
"\377\377\21\377\377\377\15\377\377\377\11\377\377\377\12\377\377\377\7\377"
"\377\377\13\377\377\377\14\377\377\377\17\377\377\377\21\377\377\377\31\377"
"\377\377\31\377\377\377\35\377\377\377!\377\377\377'\377\377\377+\377\377"
"\3771\377\377\377=\377\377\377E\377\377\377H\377\377\377M\377\377\377M\377"
"\377\377J\377\377\377I\377\377\377A\377\377\377A\377\377\3778\377\377\377"
",\377\377\377%\377\377\377$\377\377\377\"\377\377\377\34\377\377\377\24\377"
"\377\377\22\377\377\377\17\377\377\377\13\377\377\377\12\377\377\377\11\377"
"\377\377\13\377\377\377\14\377\377\377\20\377\377\377\23\377\377\377\27\377"
"\377\377\35\377\377\377$\377\377\377(\377\377\377.\377\377\3776\377\377\377"
"=\377\377\377H\377\377\377W\377\377\377Y\377\377\377]\377\377\377a\377\377"
"\377\\\377\377\377\\\377\377\377U\377\377\377O\377\377\377?\377\377\3774"
"\377\377\377-\377\377\377+\377\377\377\40\377\377\377\32\377\377\377\27\377"
"\377\377\23\377\377\377\22\377\377\377\15\377\377\377\11\377\377\377\13\377"
"\377\377\12\377\377\377\15\377\377\377\21\377\377\377\25\377\377\377\30\377"
"\377\377\37\377\377\377$\377\377\377.\377\377\3779\377\377\377?\377\377\377"
"N\377\377\377X\377\377\377h\377\377\377r\377\377\377w\377\377\377|\377\377"
"\377x\377\377\377p\377\377\377k\377\377\377\\\377\377\377J\377\377\377F\377"
"\377\3779\377\377\377*\377\377\377$\377\377\377\36\377\377\377\30\377\377"
"\377\25\377\377\377\24\377\377\377\20\377\377\377\14\377\377\377\12\377\377"
"\377\15\377\377\377\17\377\377\377\22\377\377\377\27\377\377\377\34\377\377"
"\377\40\377\377\377%\377\377\377.\377\377\377<\377\377\377M\377\377\377["
"\377\377\377l\377\377\377~\377\377\377\227\377\377\377\230\377\377\377\234"
"\377\377\377\233\377\377\377\226\377\377\377\205\377\377\377i\377\377\377"
"b\377\377\377P\377\377\3779\377\377\377-\377\377\377(\377\377\377!\377\377"
"\377\35\377\377\377\32\377\377\377\25\377\377\377\21\377\377\377\13\377\377"
"\377\12\377\377\377\15\377\377\377\21\377\377\377\23\377\377\377\31\377\377"
"\377\37\377\377\377!\377\377\377(\377\377\3774\377\377\377@\377\377\377Q"
"\377\377\377g\377\377\377\200\377\377\377\231\377\377\377\254\377\377\377"
"\275\377\377\377\310\377\377\377\304\377\377\377\264\377\377\377\227\377"
"\377\377\212\377\377\377f\377\377\377Q\377\377\377B\377\377\377:\377\377"
"\377/\377\377\377&\377\377\377\36\377\377\377\32\377\377\377\26\377\377\377"
"\21\377\377\377\14\377\377\377\12\377\377\377\17\377\377\377\22\377\377\377"
"\24\377\377\377\31\377\377\377\40\377\377\377&\377\377\377-\377\377\377:"
"\377\377\377H\377\377\377X\377\377\377k\377\377\377\220\377\377\377\252\377"
"\377\377\324\377\377\377\363\377\377\377\370\377\377\377\366\377\377\377"
"\335\377\377\377\263\377\377\377\221\377\377\377w\377\377\377b\377\377\377"
"P\377\377\377>\377\377\3770\377\377\377&\377\377\377\37\377\377\377\32\377"
"\377\377\26\377\377\377\23\377\377\377\15\377\377\377\11\377\377\377\16\377"
"\377\377\21\377\377\377\27\377\377\377\33\377\377\377\"\377\377\377(\377"
"\377\377/\377\377\377<\377\377\377N\377\377\377b\377\377\377z\377\377\377"
"\231\377\377\377\275\377\377\377\361\377\377\377\375\377\377\377\376\377"
"\377\377\376\377\377\377\370\377\377\377\316\377\377\377\240\377\377\377"
"\205\377\377\377b\377\377\377L\377\377\377<\377\377\377.\377\377\377&\377"
"\377\377\40\377\377\377\33\377\377\377\26\377\377\377\22\377\377\377\15\377"
"\377\377\12\377\377\377\16\377\377\377\22\377\377\377\24\377\377\377\32\377"
"\377\377\40\377\377\377$\377\377\377,\377\377\377:\377\377\377L\377\377\377"
"`\377\377\377|\377\377\377\231\377\377\377\310\377\377\377\372\377\377\377"
"\375\377\377\377\376\377\377\377\376\377\377\377\375\377\377\377\332\377"
"\377\377\241\377\377\377\207\377\377\377f\377\377\377R\377\377\377@\377\377"
"\3773\377\377\377+\377\377\377\"\377\377\377\35\377\377\377\30\377\377\377"
"\24\377\377\377\17\377\377\377\14\377\377\377\16\377\377\377\22\377\377\377"
"\25\377\377\377\30\377\377\377\40\377\377\377$\377\377\377,\377\377\377;"
"\377\377\377N\377\377\377e\377\377\377\206\377\377\377\246\377\377\377\327"
"\377\377\377\374\377\377\377\375\377\377\377\376\377\377\377\376\377\377"
"\377\374\377\377\377\331\377\377\377\243\377\377\377\210\377\377\377b\377"
"\377\377O\377\377\377>\377\377\377.\377\377\377&\377\377\377\40\377\377\377"
"\33\377\377\377\27\377\377\377\22\377\377\377\15\377\377\377\12\377\377\377"
"\16\377\377\377\22\377\377\377\23\377\377\377\32\377\377\377\40\377\377\377"
"'\377\377\3770\377\377\377?\377\377\377U\377\377\377h\377\377\377\200\377"
"\377\377\237\377\377\377\270\377\377\377\344\377\377\377\372\377\377\377"
"\375\377\377\377\376\377\377\377\354\377\377\377\275\377\377\377\227\377"
"\377\377\200\377\377\377e\377\377\377Q\377\377\377>\377\377\377.\377\377"
"\377%\377\377\377\40\377\377\377\33\377\377\377\26\377\377\377\22\377\377"
"\377\15\377\377\377\11\377\377\377\17\377\377\377\22\377\377\377\25\377\377"
"\377\31\377\377\377\"\377\377\377*\377\377\3773\377\377\377=\377\377\377"
"J\377\377\377^\377\377\377o\377\377\377\211\377\377\377\235\377\377\377\271"
"\377\377\377\327\377\377\377\342\377\377\377\335\377\377\377\302\377\377"
"\377\240\377\377\377\216\377\377\377k\377\377\377X\377\377\377C\377\377\377"
"9\377\377\377/\377\377\377&\377\377\377\"\377\377\377\33\377\377\377\26\377"
"\377\377\22\377\377\377\14\377\377\377\12\377\377\377\15\377\377\377\22\377"
"\377\377\31\377\377\377\35\377\377\377\37\377\377\377$\377\377\377,\377\377"
"\3777\377\377\377A\377\377\377Q\377\377\377[\377\377\377p\377\377\377\212"
"\377\377\377\231\377\377\377\242\377\377\377\253\377\377\377\251\377\377"
"\377\236\377\377\377\215\377\377\377u\377\377\377b\377\377\377O\377\377\377"
"<\377\377\3771\377\377\377)\377\377\377\"\377\377\377\34\377\377\377\32\377"
"\377\377\27\377\377\377\21\377\377\377\16\377\377\377\12\377\377\377\17\377"
"\377\377\21\377\377\377\20\377\377\377\27\377\377\377\37\377\377\377$\377"
"\377\377&\377\377\377,\377\377\3778\377\377\377B\377\377\377R\377\377\377"
"_\377\377\377k\377\377\377~\377\377\377\207\377\377\377\220\377\377\377\220"
"\377\377\377\203\377\377\377q\377\377\377_\377\377\377V\377\377\377F\377"
"\377\3777\377\377\377,\377\377\377%\377\377\377!\377\377\377\31\377\377\377"
"\25\377\377\377\22\377\377\377\17\377\377\377\14\377\377\377\11\377\377\377"
"\12\377\377\377\16\377\377\377\22\377\377\377\27\377\377\377\33\377\377\377"
"\35\377\377\377\"\377\377\377(\377\377\377/\377\377\3779\377\377\377E\377"
"\377\377L\377\377\377^\377\377\377d\377\377\377e\377\377\377k\377\377\377"
"l\377\377\377d\377\377\377a\377\377\377O\377\377\377C\377\377\377=\377\377"
"\3770\377\377\377)\377\377\377$\377\377\377\35\377\377\377\30\377\377\377"
"\25\377\377\377\22\377\377\377\16\377\377\377\12\377\377\377\13\377\377\377"
"\13\377\377\377\15\377\377\377\20\377\377\377\21\377\377\377\31\377\377\377"
"\33\377\377\377\35\377\377\377$\377\377\377)\377\377\3771\377\377\3776\377"
"\377\377@\377\377\377J\377\377\377N\377\377\377P\377\377\377S\377\377\377"
"X\377\377\377P\377\377\377J\377\377\377E\377\377\3777\377\377\377,\377\377"
"\377+\377\377\377%\377\377\377\40\377\377\377\32\377\377\377\26\377\377\377"
"\21\377\377\377\21\377\377\377\14\377\377\377\11\377\377\377\12\377\377\377"
"\13\377\377\377\11\377\377\377\14\377\377\377\21\377\377\377\23\377\377\377"
"\27\377\377\377\33\377\377\377\37\377\377\377&\377\377\377(\377\377\377*"
"\377\377\3774\377\377\3779\377\377\377<\377\377\377=\377\377\377C\377\377"
"\377E\377\377\377?\377\377\3779\377\377\377:\377\377\377.\377\377\377(\377"
"\377\377!\377\377\377!\377\377\377\35\377\377\377\31\377\377\377\24\377\377"
"\377\21\377\377\377\16\377\377\377\12\377\377\377\11\377\377\377\10\377\377"
"\377\10\377\377\377\11\377\377\377\13\377\377\377\16\377\377\377\22\377\377"
"\377\25\377\377\377\30\377\377\377\33\377\377\377\"\377\377\377!\377\377"
"\377%\377\377\377*\377\377\377-\377\377\3770\377\377\377/\377\377\3773\377"
"\377\3772\377\377\3774\377\377\377-\377\377\377,\377\377\377*\377\377\377"
"\"\377\377\377\37\377\377\377\32\377\377\377\33\377\377\377\27\377\377\377"
"\21\377\377\377\17\377\377\377\16\377\377\377\12\377\377\377\11\377\377\377"
"\6\377\377\377\10\377\377\377\12\377\377\377\11\377\377\377\15\377\377\377"
"\20\377\377\377\22\377\377\377\23\377\377\377\30\377\377\377\32\377\377\377"
"\35\377\377\377\40\377\377\377!\377\377\377%\377\377\377(\377\377\377&\377"
"\377\377)\377\377\377(\377\377\377+\377\377\377$\377\377\377!\377\377\377"
"#\377\377\377\36\377\377\377\30\377\377\377\30\377\377\377\24\377\377\377"
"\22\377\377\377\20\377\377\377\15\377\377\377\11\377\377\377\12\377\377\377"
"\6\377\377\377\6\377\377\377\7\377\377\377\7\377\377\377\11\377\377\377\12"
"\377\377\377\16\377\377\377\17\377\377\377\22\377\377\377\23\377\377\377"
"\26\377\377\377\31\377\377\377\33\377\377\377\34\377\377\377!\377\377\377"
"\40\377\377\377\"\377\377\377\"\377\377\377\"\377\377\377&\377\377\377\36"
"\377\377\377\35\377\377\377\35\377\377\377\34\377\377\377\26\377\377\377"
"\24\377\377\377\23\377\377\377\20\377\377\377\15\377\377\377\14\377\377\377"
"\13\377\377\377\7\377\377\377\5\377\377\377\6\377\377\377\7\377\377\377\6"
"\377\377\377\11\377\377\377\12\377\377\377\11\377\377\377\15\377\377\377"
"\16\377\377\377\21\377\377\377\22\377\377\377\26\377\377\377\26\377\377\377"
"\30\377\377\377\33\377\377\377\32\377\377\377\34\377\377\377\33\377\377\377"
"\32\377\377\377\37\377\377\377\31\377\377\377\31\377\377\377\27\377\377\377"
"\30\377\377\377\21\377\377\377\22\377\377\377\17\377\377\377\14\377\377\377"
"\11\377\377\377\11\377\377\377\12\377\377\377\6\377\377\377\6\377\377\377"
"\4\377\377\377\6\377\377\377\6\377\377\377\5\377\377\377\7\377\377\377\13"
"\377\377\377\11\377\377\377\12\377\377\377\16\377\377\377\21\377\377\377"
"\21\377\377\377\20\377\377\377\22\377\377\377\30\377\377\377\26\377\377\377"
"\27\377\377\377\30\377\377\377\27\377\377\377\30\377\377\377\26\377\377\377"
"\23\377\377\377\22\377\377\377\20\377\377\377\20\377\377\377\16\377\377\377"
"\14\377\377\377\11\377\377\377\11\377\377\377\10\377\377\377\6\377\377\377"
"\6\377\377\377\4\377\377\377\3\377\377\377\4\377\377\377\4\377\377\377\4"
"\377\377\377\7\377\377\377\10\377\377\377\12\377\377\377\10\377\377\377\11"
"\377\377\377\15\377\377\377\16\377\377\377\16\377\377\377\20\377\377\377"
"\23\377\377\377\21\377\377\377\23\377\377\377\22\377\377\377\22\377\377\377"
"\21\377\377\377\22\377\377\377\22\377\377\377\20\377\377\377\16\377\377\377"
"\15\377\377\377\12\377\377\377\11\377\377\377\12\377\377\377\7\377\377\377"
"\6\377\377\377\7\377\377\377\5\377\377\377\4\377\377\377\1\377\377\377\1"
"\377\377\377\3\377\377\377\3\377\377\377\6\377\377\377\7\377\377\377\6\377"
"\377\377\10\377\377\377\12\377\377\377\12\377\377\377\11\377\377\377\13\377"
"\377\377\16\377\377\377\16\377\377\377\16\377\377\377\17\377\377\377\16\377"
"\377\377\16\377\377\377\17\377\377\377\17\377\377\377\15\377\377\377\14\377"
"\377\377\12\377\377\377\11\377\377\377\12\377\377\377\12\377\377\377\7\377"
"\377\377\6\377\377\377\6\377\377\377\6\377\377\377\3\377\377\377\1\377\377"
"\377\1\0\0\0\0\0\0\0\0\377\377\377\2\377\377\377\4\377\377\377\7\377\377"
"\377\6\377\377\377\6\377\377\377\7\377\377\377\13\377\377\377\13\377\377"
"\377\10\377\377\377\11\377\377\377\11\377\377\377\11\377\377\377\15\377\377"
"\377\13\377\377\377\14\377\377\377\11\377\377\377\13\377\377\377\11\377\377"
"\377\12\377\377\377\13\377\377\377\11\377\377\377\11\377\377\377\6\377\377"
"\377\7\377\377\377\4\377\377\377\5\377\377\377\3\377\377\377\1\0\0\0\0\0"
"\0\0\0"
};
cairo-dock-3.3.2/src/gldit/cairo-dock-backends-manager.h 000664 001750 001750 00000014753 12223247550 024142 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_BACKENDS_MANAGER__
#define __CAIRO_DOCK_BACKENDS_MANAGER__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-manager.h"
#include "cairo-dock-desklet-factory.h"
#include "cairo-dock-dock-factory.h"
#include "cairo-dock-dialog-factory.h"
G_BEGIN_DECLS
// manager
typedef struct _CairoBackendsParam CairoBackendsParam;
#ifndef _MANAGER_DEF_
extern GldiManager myBackendsMgr;
extern CairoBackendsParam myBackendsParam;
#endif
// params
struct _CairoBackendsParam {
// views
gchar *cMainDockDefaultRendererName;
gchar *cSubDockDefaultRendererName;
gdouble fSubDockSizeRatio;
// system
gint iUnfoldingDuration;
gint iGrowUpInterval, iShrinkDownInterval;
gint iHideNbSteps, iUnhideNbSteps;
gdouble fRefreshInterval;
gboolean bDynamicReflection;
};
struct _CairoDockAnimationRecord {
gint id;
const gchar *cDisplayedName;
gboolean bIsEffect;
};
// Dock renderer
CairoDockRenderer *cairo_dock_get_renderer (const gchar *cRendererName, gboolean bForMainDock);
void cairo_dock_register_renderer (const gchar *cRendererName, CairoDockRenderer *pRenderer);
void cairo_dock_remove_renderer (const gchar *cRendererName);
// Desklet renderer
CairoDeskletRenderer *cairo_dock_get_desklet_renderer (const gchar *cRendererName);
void cairo_dock_register_desklet_renderer (const gchar *cRendererName, CairoDeskletRenderer *pRenderer);
void cairo_dock_remove_desklet_renderer (const gchar *cRendererName);
void cairo_dock_predefine_desklet_renderer_config (CairoDeskletRenderer *pRenderer, const gchar *cConfigName, CairoDeskletRendererConfigPtr pConfig);
CairoDeskletRendererConfigPtr cairo_dock_get_desklet_renderer_predefined_config (const gchar *cRendererName, const gchar *cConfigName);
// Dialog renderer
CairoDialogRenderer *cairo_dock_get_dialog_renderer (const gchar *cRendererName);
void cairo_dock_register_dialog_renderer (const gchar *cRendererName, CairoDialogRenderer *pRenderer);
void cairo_dock_remove_dialog_renderer (const gchar *cRendererName);
// Desklet decorations
CairoDeskletDecoration *cairo_dock_get_desklet_decoration (const gchar *cDecorationName);
void cairo_dock_register_desklet_decoration (const gchar *cDecorationName, CairoDeskletDecoration *pDecoration);
void cairo_dock_remove_desklet_decoration (const gchar *cDecorationName);
// Hiding animations
CairoDockHidingEffect *cairo_dock_get_hiding_effect (const gchar *cHidingEffect);
void cairo_dock_register_hiding_effect (const gchar *cHidingEffect, CairoDockHidingEffect *pEffect);
void cairo_dock_remove_hiding_effect (const gchar *cHidingEffect);
// Container Icon renderer
CairoIconContainerRenderer *cairo_dock_get_icon_container_renderer (const gchar *cRendererName);
void cairo_dock_register_icon_container_renderer (const gchar *cRendererName, CairoIconContainerRenderer *pRenderer);
void cairo_dock_remove_icon_container_renderer (const gchar *cRendererName);
void cairo_dock_foreach_icon_container_renderer (GHFunc pCallback, gpointer data);
void cairo_dock_set_renderer (CairoDock *pDock, const gchar *cRendererName);
void cairo_dock_set_default_renderer (CairoDock *pDock);
void cairo_dock_set_desklet_renderer (CairoDesklet *pDesklet, CairoDeskletRenderer *pRenderer, CairoDeskletRendererConfigPtr pConfig);
void cairo_dock_set_desklet_renderer_by_name (CairoDesklet *pDesklet, const gchar *cRendererName, CairoDeskletRendererConfigPtr pConfig);
void cairo_dock_set_dialog_renderer (CairoDialog *pDialog, CairoDialogRenderer *pRenderer, CairoDialogRendererConfigPtr pConfig);
void cairo_dock_set_dialog_renderer_by_name (CairoDialog *pDialog, const gchar *cRendererName, CairoDialogRendererConfigPtr pConfig);
// Dialog decorator
CairoDialogDecorator *cairo_dock_get_dialog_decorator (const gchar *cDecoratorName);
void cairo_dock_register_dialog_decorator (const gchar *cDecoratorName, CairoDialogDecorator *pDecorator);
void cairo_dock_remove_dialog_decorator (const gchar *cDecoratorName);
void cairo_dock_set_dialog_decorator (CairoDialog *pDialog, CairoDialogDecorator *pDecorator);
void cairo_dock_set_dialog_decorator_by_name (CairoDialog *pDialog, const gchar *cDecoratorName);
void cairo_dock_render_desklet_with_new_data (CairoDesklet *pDesklet, CairoDeskletRendererDataPtr pNewData);
void cairo_dock_render_dialog_with_new_data (CairoDialog *pDialog, CairoDialogRendererDataPtr pNewData);
void cairo_dock_foreach_dock_renderer (GHFunc pFunction, gpointer data);
void cairo_dock_foreach_desklet_decoration (GHFunc pFunction, gpointer data);
void cairo_dock_foreach_dialog_decorator (GHFunc pFunction, gpointer data);
void cairo_dock_foreach_animation (GHFunc pFunction, gpointer data);
void cairo_dock_update_renderer_list_for_gui (void);
void cairo_dock_update_desklet_decorations_list_for_gui (void);
void cairo_dock_update_desklet_decorations_list_for_applet_gui (void);
void cairo_dock_update_animations_list_for_gui (void);
void cairo_dock_update_dialog_decorator_list_for_gui (void);
// Icon animations
int cairo_dock_register_animation (const gchar *cAnimation, const gchar *cDisplayedName, gboolean bIsEffect);
void cairo_dock_free_animation_record (CairoDockAnimationRecord *pRecord);
int cairo_dock_get_animation_id (const gchar *cAnimation);
const gchar *cairo_dock_get_animation_displayed_name (const gchar *cAnimation);
void cairo_dock_unregister_animation (const gchar *cAnimation);
void cairo_dock_foreach_animation (GHFunc pHFunction, gpointer data);
#define CAIRO_CONTAINER_IS_OPENGL(pContainer) (g_bUseOpenGL && ((CAIRO_DOCK_IS_DOCK (pContainer) && CAIRO_DOCK (pContainer)->pRenderer->render_opengl) || (CAIRO_DOCK_IS_DESKLET (pContainer) && CAIRO_DESKLET (pContainer)->pRenderer && CAIRO_DESKLET (pContainer)->pRenderer->render_opengl)))
#define CAIRO_DOCK_CONTAINER_IS_OPENGL CAIRO_CONTAINER_IS_OPENGL
void gldi_register_backends_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-dialog-factory.c 000664 001750 001750 00000110202 12223247550 023641 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include
#include "gldi-config.h"
#include "cairo-dock-icon-factory.h"
#include "cairo-dock-icon-facility.h"
#include "cairo-dock-container.h"
#include "cairo-dock-image-buffer.h"
#include "cairo-dock-draw.h"
#include "cairo-dock-draw-opengl.h"
#include "cairo-dock-log.h"
#include "cairo-dock-desklet-factory.h"
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-dock-facility.h"
#include "cairo-dock-backends-manager.h"
#include "cairo-dock-surface-factory.h"
#include "cairo-dock-animations.h" // cairo_dock_launch_animation
#include "cairo-dock-launcher-manager.h" // cairo_dock_search_icon_s_path
#include "cairo-dock-windows-manager.h" // gldi_windows_get_active
#include "cairo-dock-desktop-manager.h"
#include "cairo-dock-dialog-manager.h"
#include "cairo-dock-dialog-factory.h"
extern gboolean g_bUseOpenGL;
extern CairoDock *g_pMainDock;
static void _compute_dialog_sizes (CairoDialog *pDialog)
{
pDialog->iMessageWidth = pDialog->iIconSize + pDialog->iTextWidth + (pDialog->iTextWidth != 0 ? 2 : 0) * CAIRO_DIALOG_TEXT_MARGIN - pDialog->iIconOffsetX; // icone + marge + texte + marge.
pDialog->iMessageHeight = MAX (pDialog->iIconSize - pDialog->iIconOffsetY, pDialog->iTextHeight) + (pDialog->pInteractiveWidget != NULL ? CAIRO_DIALOG_VGAP : 0); // (icone/texte + marge) + widget + (marge + boutons) + pointe.
if (pDialog->pButtons != NULL)
{
pDialog->iButtonsWidth = pDialog->iNbButtons * myDialogsParam.iDialogButtonWidth + (pDialog->iNbButtons - 1) * CAIRO_DIALOG_BUTTON_GAP + 2 * CAIRO_DIALOG_TEXT_MARGIN; // marge + bouton1 + ecart + bouton2 + marge.
pDialog->iButtonsHeight = CAIRO_DIALOG_VGAP + myDialogsParam.iDialogButtonHeight; // il y'a toujours quelque chose au-dessus (texte et/ou widget)
}
pDialog->iBubbleWidth = MAX (pDialog->iInteractiveWidth, MAX (pDialog->iButtonsWidth, MAX (pDialog->iMessageWidth, pDialog->iMinFrameWidth)));
pDialog->iBubbleHeight = pDialog->iMessageHeight + pDialog->iInteractiveHeight + pDialog->iButtonsHeight;
if (pDialog->iBubbleWidth == 0) // precaution.
pDialog->iBubbleWidth = 20;
if (pDialog->iBubbleHeight == 0)
pDialog->iBubbleHeight = 10;
pDialog->iComputedWidth = pDialog->iLeftMargin + pDialog->iBubbleWidth + pDialog->iRightMargin;
pDialog->iComputedHeight = pDialog->iTopMargin + pDialog->iBubbleHeight + pDialog->iBottomMargin + pDialog->iMinBottomGap; // all included.
pDialog->container.iWidth = pDialog->iComputedWidth;
pDialog->container.iHeight = pDialog->iComputedHeight;
}
static gboolean on_expose_dialog (G_GNUC_UNUSED GtkWidget *pWidget,
#if (GTK_MAJOR_VERSION < 3)
GdkEventExpose *pExpose,
#else
cairo_t *ctx,
#endif
CairoDialog *pDialog)
{
//g_print ("%s (%dx%d ; %d;%d)\n", __func__, pDialog->container.iWidth, pDialog->container.iHeight, pExpose->area.x, pExpose->area.y);
/* int x, y;
// OpenGL renderers are not ready for dialogs.
if (g_bUseOpenGL && (pDialog->pDecorator == NULL || pDialog->pDecorator->render_opengl != NULL) && (pDialog->pRenderer == NULL || pDialog->pRenderer->render_opengl != NULL))
{
if (! gldi_glx_begin_draw_container (CAIRO_CONTAINER (pDialog)))
return FALSE;
if (pDialog->pDecorator != NULL && pDialog->pDecorator->render_opengl != NULL)
{
glPushMatrix ();
pDialog->pDecorator->render_opengl (pDialog);
glPopMatrix ();
}
gldi_object_notify (pDialog, NOTIFICATION_RENDER, pDialog, NULL);
gldi_glx_end_draw_container (CAIRO_CONTAINER (pDialog));
}
else
{*/
cairo_t *pCairoContext;
GdkRectangle area;
#if (GTK_MAJOR_VERSION < 3)
memcpy (&area, &pExpose->area, sizeof (GdkRectangle));
#else
double x1, x2, y1, y2;
cairo_clip_extents (ctx, &x1, &y1, &x2, &y2);
area.x = x1;
area.y = y1;
area.width = x2 - x1;
area.height = y2 - y1; /// or the opposite ?...
#endif
if (area.x != 0 || area.y != 0)
{
pCairoContext = cairo_dock_create_drawing_context_on_area (CAIRO_CONTAINER (pDialog), &area, NULL); // pass a NULL color, so that the context is filled with transparency (otherwise, internal widgets can appear).
}
else
{
pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDialog));
}
if (pDialog->pDecorator != NULL)
{
cairo_save (pCairoContext);
pDialog->pDecorator->render (pCairoContext, pDialog);
cairo_restore (pCairoContext);
}
gldi_object_notify (pDialog, NOTIFICATION_RENDER, pDialog, pCairoContext);
if (pDialog->fAppearanceCounter < 1.)
{
double fAlpha = pDialog->fAppearanceCounter * pDialog->fAppearanceCounter;
cairo_rectangle (pCairoContext,
0,
0,
pDialog->container.iWidth,
pDialog->container.iHeight);
cairo_set_line_width (pCairoContext, 0);
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_DEST_OUT);
cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 1. - fAlpha);
cairo_fill (pCairoContext);
}
cairo_destroy (pCairoContext);
//}
return FALSE;
}
static void _cairo_dock_set_dialog_input_shape (CairoDialog *pDialog)
{
if (pDialog->pShapeBitmap != NULL)
gldi_shape_destroy (pDialog->pShapeBitmap);
pDialog->pShapeBitmap = gldi_container_create_input_shape (CAIRO_CONTAINER (pDialog),
0,
0,
1,
1); // workaround a bug in X with fully transparent window => let 1 pixel ON.
gldi_container_set_input_shape (CAIRO_CONTAINER (pDialog), pDialog->pShapeBitmap);
}
static gboolean on_configure_dialog (G_GNUC_UNUSED GtkWidget* pWidget,
GdkEventConfigure* pEvent,
CairoDialog *pDialog)
{
//g_print ("%s (%dx%d, %d;%d) [%d]\n", __func__, pEvent->width, pEvent->height, pEvent->x, pEvent->y, pDialog->bPositionForced);
if (pEvent->width <= CAIRO_DIALOG_MIN_SIZE && pEvent->height <= CAIRO_DIALOG_MIN_SIZE && ! pDialog->bNoInput)
{
pDialog->container.bInside = FALSE;
return FALSE;
}
//\____________ get dialog size and position.
int iPrevWidth = pDialog->container.iWidth, iPrevHeight = pDialog->container.iHeight;
pDialog->container.iWidth = pEvent->width;
pDialog->container.iHeight = pEvent->height;
pDialog->container.iWindowPositionX = pEvent->x;
pDialog->container.iWindowPositionY = pEvent->y;
//\____________ if an interactive widget is present, internal sizes may have changed.
if (pDialog->pInteractiveWidget != NULL)
{
int w = pDialog->iInteractiveWidth, h = pDialog->iInteractiveHeight;
GtkRequisition requisition;
#if (GTK_MAJOR_VERSION < 3)
gtk_widget_size_request (pDialog->pInteractiveWidget, &requisition);
#else
gtk_widget_get_preferred_size (pDialog->pInteractiveWidget, &requisition, NULL);
#endif
pDialog->iInteractiveWidth = requisition.width;
pDialog->iInteractiveHeight = requisition.height;
//g_print (" pInteractiveWidget : %dx%d\n", pDialog->iInteractiveWidth, pDialog->iInteractiveHeight);
_compute_dialog_sizes (pDialog);
if (w != pDialog->iInteractiveWidth || h != pDialog->iInteractiveHeight)
{
gldi_dialogs_replace_all ();
/*Icon *pIcon = pDialog->pIcon;
if (pIcon != NULL)
{
GldiContainer *pContainer = cairo_dock_search_container_from_icon (pIcon);
cairo_dock_place_dialog (pDialog, pContainer);
}*/
}
}
//g_print ("dialog size: %dx%d / %dx%d\n", pEvent->width, pEvent->height, pDialog->iComputedWidth, pDialog->iComputedHeight);
//\____________ set input shape if size has changed or if no shape yet.
if (pDialog->bNoInput && (iPrevWidth != pEvent->width || iPrevHeight != pEvent->height || ! pDialog->pShapeBitmap))
{
_cairo_dock_set_dialog_input_shape (pDialog);
pDialog->container.bInside = FALSE;
}
//\____________ force position for buggy WM (Compiz).
if (pDialog->iComputedWidth == pEvent->width && pDialog->iComputedHeight == pEvent->height && (pEvent->y != pDialog->iComputedPositionY || pEvent->x != pDialog->iComputedPositionX) && pDialog->bPositionForced == 3)
{
pDialog->container.bInside = FALSE;
cd_debug ("force to %d;%d", pDialog->iComputedPositionX, pDialog->iComputedPositionY);
/*gtk_window_move (GTK_WINDOW (pDialog->container.pWidget),
pDialog->iComputedPositionX,
pDialog->iComputedPositionY);
*/pDialog->bPositionForced ++;
}
gtk_widget_queue_draw (pDialog->container.pWidget); // les widgets internes peuvent avoir changer de taille sans que le dialogue n'en ait change, il faut donc redessiner tout le temps.
return FALSE;
}
static gboolean on_unmap_dialog (GtkWidget* pWidget,
G_GNUC_UNUSED GdkEvent *pEvent,
CairoDialog *pDialog)
{
//g_print ("unmap dialog (bAllowMinimize:%d, visible:%d)\n", pDialog->bAllowMinimize, GTK_WIDGET_VISIBLE (pWidget));
if (! pDialog->bAllowMinimize) // it's an unexpected unmap event
{
if (pDialog->pUnmapTimer) // see if it happened just after an event that we expected
{
double fElapsedTime = g_timer_elapsed (pDialog->pUnmapTimer, NULL);
//g_print ("fElapsedTime : %fms\n", fElapsedTime);
if (fElapsedTime < .2) // it's a 2nd unmap event just after the first one, ignore it, it's just some noise from the WM
return TRUE;
}
gtk_window_present (GTK_WINDOW (pWidget)); // counter it, we don't want dialogs to be hidden
}
else // expected event, it's an unmap that we triggered with 'gldi_dialog_hide', so let pass it
{
pDialog->bAllowMinimize = FALSE;
if (pDialog->pUnmapTimer != NULL)
g_timer_destroy (pDialog->pUnmapTimer);
pDialog->pUnmapTimer = g_timer_new (); // remember the time it arrived
}
return TRUE; // stops other handlers from being invoked for the event.
}
static gboolean on_map_dialog (G_GNUC_UNUSED GtkWidget* pWidget,
G_GNUC_UNUSED GdkEvent *pEvent,
CairoDialog *pDialog)
{
if (pDialog->pInteractiveWidget)
{
gldi_container_present (CAIRO_CONTAINER (pDialog));
}
return FALSE;
}
static gboolean on_button_press_widget (G_GNUC_UNUSED GtkWidget *widget,
GdkEventButton *pButton,
CairoDialog *pDialog)
{
cd_debug ("press button on widget");
// memorize the time when the user clicked on the widget.
pDialog->iButtonPressTime = pButton->time;
return FALSE;
}
static GtkWidget *_cairo_dock_add_dialog_internal_box (CairoDialog *pDialog, int iWidth, int iHeight, gboolean bCanResize)
{
GtkWidget *pBox = _gtk_hbox_new (0);
if (iWidth != 0 && iHeight != 0)
g_object_set (pBox, "height-request", iHeight, "width-request", iWidth, NULL);
else if (iWidth != 0)
g_object_set (pBox, "width-request", iWidth, NULL);
else if (iHeight != 0)
g_object_set (pBox, "height-request", iHeight, NULL);
gtk_box_pack_start (GTK_BOX (pDialog->pWidgetLayout),
pBox,
bCanResize,
bCanResize,
0);
return pBox;
}
static cairo_surface_t *_cairo_dock_create_dialog_text_surface (const gchar *cText, gboolean bUseMarkup, int *iTextWidth, int *iTextHeight)
{
if (cText == NULL)
return NULL;
myDialogsParam.dialogTextDescription.bUseMarkup = bUseMarkup; // slight optimization, rather than duplicating the TextDescription each time.
cairo_surface_t *pSurface = cairo_dock_create_surface_from_text (cText,
&myDialogsParam.dialogTextDescription,
iTextWidth,
iTextHeight);
myDialogsParam.dialogTextDescription.bUseMarkup = FALSE; // by default
return pSurface;
}
static cairo_surface_t *_cairo_dock_create_dialog_icon_surface (const gchar *cImageFilePath, Icon *pIcon, int iDesiredSize, int *iIconSize)
{
if (cImageFilePath == NULL)
return NULL;
if (iDesiredSize == 0)
iDesiredSize = myDialogsParam.iDialogIconSize;
cairo_surface_t *pIconBuffer = NULL;
if (strcmp (cImageFilePath, "same icon") == 0)
{
if (pIcon && pIcon->image.pSurface)
{
int iWidth, iHeight;
cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
pIconBuffer = cairo_dock_duplicate_surface (pIcon->image.pSurface,
iWidth, iHeight,
iDesiredSize, iDesiredSize);
}
else if (pIcon && pIcon->cFileName)
{
pIconBuffer = cairo_dock_create_surface_from_image_simple (pIcon->cFileName,
iDesiredSize,
iDesiredSize);
}
}
else
{
pIconBuffer = cairo_dock_create_surface_from_image_simple (cImageFilePath,
iDesiredSize,
iDesiredSize);
}
if (pIconBuffer != NULL)
*iIconSize = iDesiredSize;
return pIconBuffer;
}
static gboolean _animation_loop (GldiContainer *pContainer)
{
CairoDialog *pDialog = CAIRO_DIALOG (pContainer);
gboolean bContinue = FALSE;
gboolean bUpdateSlowAnimation = FALSE;
pContainer->iAnimationStep ++;
if (pContainer->iAnimationStep * pContainer->iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
{
bUpdateSlowAnimation = TRUE;
pContainer->iAnimationStep = 0;
pContainer->bKeepSlowAnimation = FALSE;
}
if (pDialog->fAppearanceCounter < 1)
{
pDialog->fAppearanceCounter += .08;
if (pDialog->fAppearanceCounter > .99)
{
pDialog->fAppearanceCounter = 1.;
}
else
{
bContinue = TRUE;
}
}
if (bUpdateSlowAnimation)
{
gldi_object_notify (pDialog, NOTIFICATION_UPDATE_SLOW, pDialog, &pContainer->bKeepSlowAnimation);
}
gldi_object_notify (pDialog, NOTIFICATION_UPDATE, pDialog, &bContinue);
cairo_dock_redraw_container (CAIRO_CONTAINER (pDialog));
if (! bContinue && ! pContainer->bKeepSlowAnimation)
{
pContainer->iSidGLAnimation = 0;
return FALSE;
}
else
return TRUE;
}
void gldi_dialog_init_internals (CairoDialog *pDialog, CairoDialogAttr *pAttribute)
{
pDialog->container.iface.animation_loop = _animation_loop;
//\________________ set up the window
GtkWidget *pWindow = pDialog->container.pWidget;
gtk_window_set_title (GTK_WINDOW (pWindow), "cairo-dock-dialog");
if (! pAttribute->pInteractiveWidget && ! pAttribute->pActionFunc) // not an interactive dialog
gtk_window_set_type_hint (GTK_WINDOW (pDialog->container.pWidget), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN); // pour ne pas prendre le focus.
gtk_widget_add_events (pWindow, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
gtk_window_resize (GTK_WINDOW (pWindow), CAIRO_DIALOG_MIN_SIZE, CAIRO_DIALOG_MIN_SIZE);
gtk_window_set_keep_above (GTK_WINDOW (pWindow), TRUE);
pDialog->pIcon = pAttribute->pIcon;
if (pAttribute->bForceAbove) // try to force it above other windows (with most WM, it will still stay below fullscreen windows).
{
gtk_window_set_keep_above (GTK_WINDOW (pDialog->container.pWidget), TRUE);
gtk_window_set_type_hint (GTK_WINDOW (pDialog->container.pWidget), GDK_WINDOW_TYPE_HINT_DOCK); // should be called before the window becomes visible
}
//\________________ load the message
if (pAttribute->cText != NULL)
{
pDialog->pTextBuffer = _cairo_dock_create_dialog_text_surface (pAttribute->cText,
pAttribute->bUseMarkup,
&pDialog->iTextWidth, &pDialog->iTextHeight);
///pDialog->iTextTexture = cairo_dock_create_texture_from_surface (pDialog->pTextBuffer);
}
pDialog->bUseMarkup = pAttribute->bUseMarkup; // remember this attribute, in case another text is set (with cairo_dock_set_dialog_message).
//\________________ load the icon
if (pAttribute->cImageFilePath != NULL)
{
pDialog->pIconBuffer = _cairo_dock_create_dialog_icon_surface (pAttribute->cImageFilePath, pAttribute->pIcon, pAttribute->iIconSize, &pDialog->iIconSize);
///pDialog->iIconTexture = cairo_dock_create_texture_from_surface (pDialog->pIconBuffer);
}
//\________________ load the interactive widget
if (pAttribute->pInteractiveWidget != NULL)
{
pDialog->pInteractiveWidget = pAttribute->pInteractiveWidget;
GtkRequisition requisition;
#if (GTK_MAJOR_VERSION < 3)
gtk_widget_size_request (pAttribute->pInteractiveWidget, &requisition);
#else
gtk_widget_get_preferred_size (pAttribute->pInteractiveWidget, &requisition, NULL);
#endif
pDialog->iInteractiveWidth = requisition.width;
pDialog->iInteractiveHeight = requisition.height;
}
//\________________ load the buttons
pDialog->pUserData = pAttribute->pUserData;
pDialog->pFreeUserDataFunc = pAttribute->pFreeDataFunc;
if (pAttribute->cButtonsImage != NULL && pAttribute->pActionFunc != NULL)
{
int i;
for (i = 0; pAttribute->cButtonsImage[i] != NULL; i++);
pDialog->iNbButtons = i;
pDialog->action_on_answer = pAttribute->pActionFunc;
pDialog->pButtons = g_new0 (CairoDialogButton, pDialog->iNbButtons);
const gchar *cButtonImage;
for (i = 0; i < pDialog->iNbButtons; i++)
{
cButtonImage = pAttribute->cButtonsImage[i];
if (strcmp (cButtonImage, "ok") == 0)
{
pDialog->pButtons[i].iDefaultType = 1;
}
else if (strcmp (cButtonImage, "cancel") == 0)
{
pDialog->pButtons[i].iDefaultType = 0;
}
else
{
gchar *cButtonPath;
if (*cButtonImage != '/')
cButtonPath = cairo_dock_search_icon_s_path (cButtonImage,
MAX (myDialogsParam.iDialogButtonWidth, myDialogsParam.iDialogButtonHeight));
else
cButtonPath = (gchar*)cButtonImage;
pDialog->pButtons[i].pSurface = cairo_dock_create_surface_from_image_simple (cButtonPath,
myDialogsParam.iDialogButtonWidth,
myDialogsParam.iDialogButtonHeight);
if (cButtonPath != cButtonImage)
g_free (cButtonPath);
///pDialog->pButtons[i].iTexture = cairo_dock_create_texture_from_surface (pDialog->pButtons[i].pSurface);
}
}
}
else
{
pDialog->bNoInput = pAttribute->bNoInput;
}
//\________________ set a decorator.
cairo_dock_set_dialog_decorator_by_name (pDialog, (pAttribute->cDecoratorName ? pAttribute->cDecoratorName : myDialogsParam.cDecoratorName));
if (pDialog->pDecorator != NULL)
pDialog->pDecorator->set_size (pDialog);
//\________________ Maintenant qu'on connait tout, on calcule les tailles des divers elements.
_compute_dialog_sizes (pDialog);
pDialog->container.iWidth = pDialog->iBubbleWidth + pDialog->iLeftMargin + pDialog->iRightMargin;
pDialog->container.iHeight = pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin + pDialog->iMinBottomGap;
//\________________ On reserve l'espace pour les decorations.
GtkWidget *pMainHBox = _gtk_hbox_new (0);
gtk_container_add (GTK_CONTAINER (pDialog->container.pWidget), pMainHBox);
pDialog->pLeftPaddingBox = _gtk_vbox_new (0);
g_object_set (pDialog->pLeftPaddingBox, "width-request", pDialog->iLeftMargin, NULL);
gtk_box_pack_start (GTK_BOX (pMainHBox),
pDialog->pLeftPaddingBox,
FALSE,
FALSE,
0);
pDialog->pWidgetLayout = _gtk_vbox_new (0);
gtk_box_pack_start (GTK_BOX (pMainHBox),
pDialog->pWidgetLayout,
FALSE,
FALSE,
0);
pDialog->pRightPaddingBox = _gtk_vbox_new (0);
g_object_set (pDialog->pRightPaddingBox, "width-request", pDialog->iRightMargin, NULL);
gtk_box_pack_start (GTK_BOX (pMainHBox),
pDialog->pRightPaddingBox,
FALSE,
FALSE,
0);
//\________________ On reserve l'espace pour les elements.
if (pDialog->container.bDirectionUp)
pDialog->pTopWidget = _cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iTopMargin, FALSE);
else
pDialog->pTipWidget = _cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iMinBottomGap + pDialog->iBottomMargin, TRUE);
if (pDialog->iMessageWidth != 0 && pDialog->iMessageHeight != 0)
{
pDialog->pMessageWidget = _cairo_dock_add_dialog_internal_box (pDialog, pDialog->iMessageWidth, pDialog->iMessageHeight, FALSE);
}
if (pDialog->pInteractiveWidget != NULL)
{
gtk_box_pack_start (GTK_BOX (pDialog->pWidgetLayout),
pDialog->pInteractiveWidget,
FALSE,
FALSE,
0);
gtk_window_present (GTK_WINDOW (pDialog->container.pWidget));
gtk_widget_grab_focus (pDialog->pInteractiveWidget);
}
if (pDialog->pButtons != NULL)
{
pDialog->pButtonsWidget = _cairo_dock_add_dialog_internal_box (pDialog, pDialog->iButtonsWidth, pDialog->iButtonsHeight, FALSE);
}
if (pDialog->container.bDirectionUp)
pDialog->pTipWidget = _cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iMinBottomGap + pDialog->iBottomMargin, TRUE);
else
pDialog->pTopWidget = _cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iTopMargin, TRUE);
gtk_widget_show_all (pDialog->container.pWidget);
//\________________ load the input shape.
if (pDialog->bNoInput)
{
_cairo_dock_set_dialog_input_shape (pDialog);
}
//\________________ connect the signals to the window
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
#if (GTK_MAJOR_VERSION < 3)
"expose-event",
#else
"draw",
#endif
G_CALLBACK (on_expose_dialog),
pDialog);
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
"configure-event",
G_CALLBACK (on_configure_dialog),
pDialog);
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
"unmap-event",
G_CALLBACK (on_unmap_dialog),
pDialog); // prevent dialogs from being hidden (for instance by a 'show-desktop' event), because they might be modal
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
"map-event",
G_CALLBACK (on_map_dialog),
pDialog); // some WM (like GS) prevent the focus to be taken, so we have to force it whenever the dialog is shown (creation or unhide).
if (pDialog->pInteractiveWidget != NULL && pDialog->pButtons == NULL) // the dialog has no button to be closed, so it can be closed by clicking on it. But some widget (like the GTK calendar) let pass the click to their parent (= the dialog), which then close it. To prevent this, we memorize the last click on the widget.
g_signal_connect (G_OBJECT (pDialog->pInteractiveWidget),
"button-press-event",
G_CALLBACK (on_button_press_widget),
pDialog);
cairo_dock_launch_animation (CAIRO_CONTAINER (pDialog));
}
CairoDialog *gldi_dialog_new (CairoDialogAttr *pAttribute)
{
if (!pAttribute->bForceAbove)
{
GldiWindowActor *pActiveAppli = gldi_windows_get_active ();
if (pActiveAppli && pActiveAppli->bIsFullScreen && gldi_window_is_on_current_desktop (pActiveAppli))
{
cd_debug ("skip dialog since current fullscreen window would mask it");
return NULL;
}
}
pAttribute->cattr.bNoOpengl = TRUE;
cd_debug ("%s (%s, %s, %x, %x, (%p;%p))", __func__, pAttribute->cText, pAttribute->cImageFilePath, pAttribute->pInteractiveWidget, pAttribute->pActionFunc, pAttribute->pIcon, pAttribute->pContainer);
return (CairoDialog*)gldi_object_new (&myDialogObjectMgr, pAttribute);
}
CairoDialog *gldi_dialog_show (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, double fTimeLength, const gchar *cIconPath, GtkWidget *pInteractiveWidget, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc)
{
if (pIcon != NULL && cairo_dock_icon_is_being_removed (pIcon)) // icone en cours de suppression.
{
cd_debug ("dialog skipped for %s (%.2f)", pIcon->cName, pIcon->fInsertRemoveFactor);
return NULL;
}
CairoDialogAttr attr;
memset (&attr, 0, sizeof (CairoDialogAttr));
attr.cText = (gchar *)cText;
attr.cImageFilePath = (gchar *)cIconPath;
attr.pInteractiveWidget = pInteractiveWidget;
attr.pActionFunc = pActionFunc;
attr.pUserData = data;
attr.pFreeDataFunc = pFreeDataFunc;
attr.iTimeLength = (int) fTimeLength;
const gchar *cDefaultActionButtons[3] = {"ok", "cancel", NULL};
if (pActionFunc != NULL)
attr.cButtonsImage = cDefaultActionButtons;
attr.pIcon = pIcon;
attr.pContainer = pContainer;
return gldi_dialog_new (&attr);
}
CairoDialog *gldi_dialog_show_temporary_with_icon_printf (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, double fTimeLength, const gchar *cIconPath, ...)
{
g_return_val_if_fail (cText != NULL, NULL);
va_list args;
va_start (args, cIconPath);
gchar *cFullText = g_strdup_vprintf (cText, args);
CairoDialog *pDialog = gldi_dialog_show (cFullText, pIcon, pContainer, fTimeLength, cIconPath, NULL, NULL, NULL, NULL);
g_free (cFullText);
va_end (args);
return pDialog;
}
CairoDialog *gldi_dialog_show_temporary_with_icon (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, double fTimeLength, const gchar *cIconPath)
{
g_return_val_if_fail (cText != NULL, NULL);
return gldi_dialog_show (cText, pIcon, pContainer, fTimeLength, cIconPath, NULL, NULL, NULL, NULL);
}
CairoDialog *gldi_dialog_show_temporary (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, double fTimeLength)
{
g_return_val_if_fail (cText != NULL, NULL);
return gldi_dialog_show (cText, pIcon, pContainer, fTimeLength, NULL, NULL, NULL, NULL, NULL);
}
CairoDialog *gldi_dialog_show_temporary_with_default_icon (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, double fTimeLength)
{
g_return_val_if_fail (cText != NULL, NULL);
const gchar *cIconPath = GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_ICON;
CairoDialogAttr attr;
memset (&attr, 0, sizeof (CairoDialogAttr));
attr.cText = cText;
attr.cImageFilePath = cIconPath;
attr.iTimeLength = (int) fTimeLength;
attr.pIcon = pIcon;
attr.pContainer = pContainer;
return gldi_dialog_new (&attr);
}
static inline GtkWidget *_cairo_dock_make_entry_for_dialog (const gchar *cTextForEntry)
{
GtkWidget *pWidget = gtk_entry_new ();
gtk_entry_set_has_frame (GTK_ENTRY (pWidget), FALSE);
g_object_set (pWidget, "width-request", CAIRO_DIALOG_MIN_ENTRY_WIDTH, NULL);
if (cTextForEntry != NULL)
gtk_entry_set_text (GTK_ENTRY (pWidget), cTextForEntry);
return pWidget;
}
static inline GtkWidget *_cairo_dock_make_hscale_for_dialog (double fValueForHScale, double fMaxValueForHScale)
{
#if (GTK_MAJOR_VERSION < 3)
GtkWidget *pWidget = gtk_hscale_new_with_range (0, fMaxValueForHScale, fMaxValueForHScale / 100.);
#else
GtkWidget *pWidget = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, fMaxValueForHScale, fMaxValueForHScale / 100.);
#endif
gtk_scale_set_digits (GTK_SCALE (pWidget), 2);
gtk_range_set_value (GTK_RANGE (pWidget), fValueForHScale);
g_object_set (pWidget, "width-request", CAIRO_DIALOG_MIN_SCALE_WIDTH, NULL);
gldi_dialog_set_widget_text_color (pWidget);
return pWidget;
}
CairoDialog *gldi_dialog_show_with_question (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, const gchar *cIconPath, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc)
{
return gldi_dialog_show (cText, pIcon, pContainer, 0, cIconPath, NULL, pActionFunc, data, pFreeDataFunc);
}
CairoDialog *gldi_dialog_show_with_entry (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, const gchar *cIconPath, const gchar *cTextForEntry, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc)
{
//GtkWidget *pWidget = cairo_dock_build_common_interactive_widget_for_dialog (cTextForEntry, -1, -1);
GtkWidget *pWidget = _cairo_dock_make_entry_for_dialog (cTextForEntry);
return gldi_dialog_show (cText, pIcon, pContainer, 0, cIconPath, pWidget, pActionFunc, data, pFreeDataFunc);
}
CairoDialog *gldi_dialog_show_with_value (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, const gchar *cIconPath, double fValue, double fMaxValue, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc)
{
fValue = MAX (0., fValue);
fValue = MIN (fMaxValue, fValue);
//GtkWidget *pWidget = cairo_dock_build_common_interactive_widget_for_dialog (NULL, fValue, 1.);
GtkWidget *pWidget = _cairo_dock_make_hscale_for_dialog (fValue, fMaxValue);
return gldi_dialog_show (cText, pIcon, pContainer, 0, cIconPath, pWidget, pActionFunc, data, pFreeDataFunc);
}
CairoDialog *gldi_dialog_show_general_message (const gchar *cMessage, double fTimeLength)
{
Icon *pIcon = gldi_icons_get_any_without_dialog ();
return gldi_dialog_show_temporary (cMessage, pIcon, CAIRO_CONTAINER (g_pMainDock), fTimeLength);
}
static void _cairo_dock_get_answer_from_dialog (int iClickedButton, G_GNUC_UNUSED GtkWidget *pInteractiveWidget, gpointer *data, CairoDialog *pDialog)
{
cd_message ("%s (%d)", __func__, iClickedButton);
int *iAnswerBuffer = data[0];
// GMainLoop *pBlockingLoop = data[1];
gldi_dialog_steal_interactive_widget (pDialog); // le dialogue disparaitra apres cette fonction, mais le widget interactif doit rester.
*iAnswerBuffer = iClickedButton;
}
static void _on_free_blocking_dialog (gpointer *data)
{
GMainLoop *pBlockingLoop = data[1];
if (g_main_loop_is_running (pBlockingLoop))
g_main_loop_quit (pBlockingLoop);
}
int gldi_dialog_show_and_wait (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, const gchar *cIconPath, GtkWidget *pInteractiveWidget)
{
int iClickedButton = -3;
GMainLoop *pBlockingLoop = g_main_loop_new (NULL, FALSE);
gpointer data[2] = {&iClickedButton, pBlockingLoop}; // it's useless to allocate 'data' because this function will wait for an answer
CairoDialog *pDialog = gldi_dialog_show (cText,
pIcon,
pContainer,
0.,
cIconPath,
pInteractiveWidget,
(CairoDockActionOnAnswerFunc)_cairo_dock_get_answer_from_dialog,
(gpointer) data,
(GFreeFunc)_on_free_blocking_dialog);
if (pDialog != NULL)
{
pDialog->fAppearanceCounter = 1.;
cd_debug ("Start the blocking loop...");
g_main_loop_run (pBlockingLoop);
cd_debug ("End of the blocking loop -> %d", iClickedButton);
}
g_main_loop_unref (pBlockingLoop);
return iClickedButton;
}
GtkWidget *cairo_dock_steal_widget_from_its_container (GtkWidget *pWidget)
{
g_return_val_if_fail (pWidget != NULL, NULL);
GtkWidget *pContainer = gtk_widget_get_parent (pWidget);
if (pContainer != NULL)
{
g_object_ref (G_OBJECT (pWidget));
gtk_container_remove (GTK_CONTAINER (pContainer), pWidget);
}
return pWidget;
}
GtkWidget *gldi_dialog_steal_interactive_widget (CairoDialog *pDialog)
{
if (pDialog == NULL)
return NULL;
GtkWidget *pInteractiveWidget = pDialog->pInteractiveWidget;
if (pInteractiveWidget != NULL)
{
pInteractiveWidget = cairo_dock_steal_widget_from_its_container (pInteractiveWidget);
pDialog->pInteractiveWidget = NULL;
// if we were monitoring the click events on the widget, stop it.
g_signal_handlers_disconnect_matched (pInteractiveWidget,
G_SIGNAL_MATCH_FUNC,
0,
0,
NULL,
on_button_press_widget,
NULL);
}
return pInteractiveWidget;
}
void gldi_dialog_set_widget_text_color (GtkWidget *pWidget)
{
#if (GTK_MAJOR_VERSION < 3)
static GdkColor color;
color.red = myDialogsParam.dialogTextDescription.fColorStart[0] * 65535;
color.green = myDialogsParam.dialogTextDescription.fColorStart[1] * 65535;
color.blue = myDialogsParam.dialogTextDescription.fColorStart[2] * 65535;
gtk_widget_modify_fg (pWidget, GTK_STATE_NORMAL, &color);
#else
static GdkRGBA color;
color.red = myDialogsParam.dialogTextDescription.fColorStart[0];
color.green = myDialogsParam.dialogTextDescription.fColorStart[1];
color.blue = myDialogsParam.dialogTextDescription.fColorStart[2];
color.alpha = 1.;
gtk_widget_override_color (pWidget, GTK_STATE_NORMAL, &color);
#endif
}
void gldi_dialog_set_widget_bg_color (GtkWidget *pWidget)
{
#if (GTK_MAJOR_VERSION < 3)
static GdkColor color;
color.red = myDialogsParam.fDialogColor[0] * 65535;
color.green = myDialogsParam.fDialogColor[1] * 65535;
color.blue = myDialogsParam.fDialogColor[2] * 65535;
gtk_widget_modify_bg (pWidget, GTK_STATE_NORMAL, &color);
#else
static GdkRGBA color;
color.red = myDialogsParam.fDialogColor[0];
color.green = myDialogsParam.fDialogColor[1];
color.blue = myDialogsParam.fDialogColor[2];
color.alpha = myDialogsParam.fDialogColor[3];
gtk_widget_override_color (pWidget, GTK_STATE_NORMAL, &color);
#endif
}
static void _redraw_icon_surface (CairoDialog *pDialog)
{
if (!pDialog->container.bUseReflect)
gtk_widget_queue_draw_area (pDialog->container.pWidget,
pDialog->iLeftMargin,
(pDialog->container.bDirectionUp ?
pDialog->iTopMargin :
pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight)),
pDialog->iIconSize,
pDialog->iIconSize);
else
gtk_widget_queue_draw (pDialog->container.pWidget);
}
static void _redraw_text_surface (CairoDialog *pDialog)
{
if (!pDialog->container.bUseReflect)
gtk_widget_queue_draw_area (pDialog->container.pWidget,
pDialog->iLeftMargin + pDialog->iIconSize + CAIRO_DIALOG_TEXT_MARGIN,
(pDialog->container.bDirectionUp ?
pDialog->iTopMargin :
pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight)),
pDialog->iTextWidth,
pDialog->iTextHeight);
else
gtk_widget_queue_draw (pDialog->container.pWidget);
}
void gldi_dialog_redraw_interactive_widget (CairoDialog *pDialog)
{
if (!pDialog->container.bUseReflect)
gtk_widget_queue_draw_area (pDialog->container.pWidget,
pDialog->iLeftMargin,
(pDialog->container.bDirectionUp ?
pDialog->iTopMargin + pDialog->iMessageHeight :
pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight) + pDialog->iMessageHeight),
pDialog->iInteractiveWidth,
pDialog->iInteractiveHeight);
else
gtk_widget_queue_draw (pDialog->container.pWidget);
}
static void _set_icon_surface (CairoDialog *pDialog, cairo_surface_t *pNewIconSurface, int iNewIconSize)
{
int iPrevMessageWidth = pDialog->iMessageWidth;
int iPrevMessageHeight = pDialog->iMessageHeight;
cairo_surface_destroy (pDialog->pIconBuffer);
if (pDialog->iIconTexture != 0)
_cairo_dock_delete_texture (pDialog->iIconTexture);
pDialog->pIconBuffer = pNewIconSurface;
if (! pNewIconSurface)
iNewIconSize = 0;
if (pDialog->iIconSize != iNewIconSize) // can happen if the dialog didn't have an icon before, or if the new one is NULL
{
pDialog->iIconSize = iNewIconSize;
_compute_dialog_sizes (pDialog);
}
// redraw
if (pDialog->iMessageWidth != iPrevMessageWidth || pDialog->iMessageHeight != iPrevMessageHeight)
{
g_object_set (pDialog->pMessageWidget, "width-request", pDialog->iMessageWidth, "height-request", pDialog->iMessageHeight, NULL); // inutile de replacer le dialogue puisque sa gravite fera le boulot.
gtk_widget_queue_draw (pDialog->container.pWidget);
}
else
{
_redraw_icon_surface (pDialog);
}
}
void gldi_dialog_set_icon_surface (CairoDialog *pDialog, cairo_surface_t *pNewIconSurface, int iNewIconSize)
{
int iIconSize = (pDialog->iIconSize != 0 ? pDialog->iIconSize : myDialogsParam.iDialogIconSize);
cairo_surface_t *pIconBuffer = cairo_dock_duplicate_surface (pNewIconSurface, iNewIconSize, iNewIconSize, iIconSize, iIconSize);
_set_icon_surface (pDialog, pIconBuffer, iIconSize);
}
void gldi_dialog_set_icon (CairoDialog *pDialog, const gchar *cImageFilePath)
{
int iIconSize = (pDialog->iIconSize != 0 ? pDialog->iIconSize : myDialogsParam.iDialogIconSize);
cairo_surface_t *pIconBuffer = cairo_dock_create_surface_for_square_icon (cImageFilePath, iIconSize);
_set_icon_surface (pDialog, pIconBuffer, iIconSize);
}
static void _set_text_surface (CairoDialog *pDialog, cairo_surface_t *pNewTextSurface, int iNewTextWidth, int iNewTextHeight)
{
int iPrevMessageWidth = pDialog->iMessageWidth;
int iPrevMessageHeight = pDialog->iMessageHeight;
cairo_surface_destroy (pDialog->pTextBuffer);
pDialog->pTextBuffer = pNewTextSurface;
if (pDialog->iTextTexture != 0)
_cairo_dock_delete_texture (pDialog->iTextTexture);
///pDialog->iTextTexture = cairo_dock_create_texture_from_surface (pNewTextSurface);
pDialog->iTextWidth = iNewTextWidth;
pDialog->iTextHeight = iNewTextHeight;
_compute_dialog_sizes (pDialog);
if (pDialog->iMessageWidth != iPrevMessageWidth || pDialog->iMessageHeight != iPrevMessageHeight)
{
g_object_set (pDialog->pMessageWidget, "width-request", pDialog->iMessageWidth, "height-request", pDialog->iMessageHeight, NULL); // inutile de replacer le dialogue puisque sa gravite fera le boulot.
gtk_widget_queue_draw (pDialog->container.pWidget);
gboolean bInside = pDialog->container.bInside;
pDialog->container.bInside = FALSE; // unfortunately the gravity is really badly handled by many WMs, so we have to replace he dialog ourselves :-/
gldi_dialogs_replace_all ();
pDialog->container.bInside = bInside;
}
else
{
_redraw_text_surface (pDialog);
}
}
void gldi_dialog_set_message (CairoDialog *pDialog, const gchar *cMessage)
{
cd_debug ("%s", cMessage);
int iNewTextWidth=0, iNewTextHeight=0;
cairo_surface_t *pNewTextSurface = _cairo_dock_create_dialog_text_surface (cMessage, pDialog->bUseMarkup, &iNewTextWidth, &iNewTextHeight);
_set_text_surface (pDialog, pNewTextSurface, iNewTextWidth, iNewTextHeight);
}
void gldi_dialog_set_message_printf (CairoDialog *pDialog, const gchar *cMessageFormat, ...)
{
g_return_if_fail (cMessageFormat != NULL);
va_list args;
va_start (args, cMessageFormat);
gchar *cMessage = g_strdup_vprintf (cMessageFormat, args);
gldi_dialog_set_message (pDialog, cMessage);
g_free (cMessage);
va_end (args);
}
cairo-dock-3.3.2/src/gldit/gtk3imagemenuitem.h 000664 001750 001750 00000007162 12223247550 022362 0 ustar 00mbaerts mbaerts 000000 000000 /* GTK - The GIMP Toolkit
* Copyright (C) Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK3_IMAGE_MENU_ITEM_H__
#define __GTK3_IMAGE_MENU_ITEM_H__
#include
G_BEGIN_DECLS
#define GTK3_TYPE_IMAGE_MENU_ITEM (gtk3_image_menu_item_get_type ())
#define GTK3_IMAGE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK3_TYPE_IMAGE_MENU_ITEM, Gtk3ImageMenuItem))
#define GTK3_IMAGE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK3_TYPE_IMAGE_MENU_ITEM, Gtk3ImageMenuItemClass))
#define GTK3_IS_IMAGE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK3_TYPE_IMAGE_MENU_ITEM))
#define GTK3_IS_IMAGE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK3_TYPE_IMAGE_MENU_ITEM))
#define GTK3_IMAGE_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK3_TYPE_IMAGE_MENU_ITEM, Gtk3ImageMenuItemClass))
typedef struct _Gtk3ImageMenuItem Gtk3ImageMenuItem;
typedef struct _Gtk3ImageMenuItemPrivate Gtk3ImageMenuItemPrivate;
typedef struct _Gtk3ImageMenuItemClass Gtk3ImageMenuItemClass;
struct _Gtk3ImageMenuItem
{
GtkMenuItem menu_item;
/*< private >*/
Gtk3ImageMenuItemPrivate *priv;
};
struct _Gtk3ImageMenuItemClass
{
GtkMenuItemClass parent_class;
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
};
GType gtk3_image_menu_item_get_type (void) G_GNUC_CONST;
GtkWidget* gtk3_image_menu_item_new (void);
GtkWidget* gtk3_image_menu_item_new_with_label (const gchar *label);
GtkWidget* gtk3_image_menu_item_new_with_mnemonic (const gchar *label);
GtkWidget* gtk3_image_menu_item_new_from_stock (const gchar *stock_id,
GtkAccelGroup *accel_group);
void gtk3_image_menu_item_set_always_show_image (Gtk3ImageMenuItem *image_menu_item,
gboolean always_show);
gboolean gtk3_image_menu_item_get_always_show_image (Gtk3ImageMenuItem *image_menu_item);
void gtk3_image_menu_item_set_image (Gtk3ImageMenuItem *image_menu_item,
GtkWidget *image);
GtkWidget* gtk3_image_menu_item_get_image (Gtk3ImageMenuItem *image_menu_item);
void gtk3_image_menu_item_set_use_stock (Gtk3ImageMenuItem *image_menu_item,
gboolean use_stock);
gboolean gtk3_image_menu_item_get_use_stock (Gtk3ImageMenuItem *image_menu_item);
void gtk3_image_menu_item_set_accel_group (Gtk3ImageMenuItem *image_menu_item,
GtkAccelGroup *accel_group);
G_END_DECLS
#endif /* __GTK3_IMAGE_MENU_ITEM_H__ */
cairo-dock-3.3.2/src/gldit/cairo-dock-opengl.h 000664 001750 001750 00000011260 12223247550 022232 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_OPENGL__
#define __CAIRO_DOCK_OPENGL__
#include
#include "gldi-config.h"
#include "cairo-dock-struct.h"
#include "cairo-dock-container.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-opengl.h This class manages the OpenGL backend and context.
*/
/// This strucure summarizes the available OpenGL configuration on the system.
struct _CairoDockGLConfig {
gboolean bIndirectRendering;
gboolean bAlphaAvailable;
gboolean bStencilBufferAvailable;
gboolean bAccumBufferAvailable;
gboolean bFboAvailable;
gboolean bNonPowerOfTwoAvailable;
gboolean bTextureFromPixmapAvailable;
// GLX-backend's data
#ifdef HAVE_GLX
GLXContext context;
XVisualInfo *pVisInfo;
#if (GTK_MAJOR_VERSION < 3) // GTK2
Colormap xcolormap;
GdkColormap *pColormap;
#else // GTK3
GdkVisual *pGdkVisual;
#endif
void (*bindTexImage) (Display *display, GLXDrawable drawable, int buffer, int *attribList); // texture from pixmap
void (*releaseTexImage) (Display *display, GLXDrawable drawable, int buffer); // texture from pixmap
#endif
};
struct _GldiGLManagerBackend {
gboolean (*init) (gboolean bForceOpenGL);
void (*stop) (void);
gboolean (*container_make_current) (GldiContainer *pContainer);
void (*container_end_draw) (GldiContainer *pContainer);
void (*container_init) (GldiContainer *pContainer);
void (*container_finish) (GldiContainer *pContainer);
};
/////////////
// BACKEND //
/////////////
/** Initialize the OpenGL backend, by trying to get a suitable GLX configuration.
*@param bForceOpenGL whether to force the use of OpenGL, or let the function decide.
*@return TRUE if OpenGL is usable.
*/
gboolean gldi_gl_backend_init (gboolean bForceOpenGL);
void gldi_gl_backend_deactivate (void);
#define gldi_gl_backend_is_safe(...) (g_bUseOpenGL && ! g_openglConfig.bIndirectRendering && g_openglConfig.bAlphaAvailable && g_openglConfig.bStencilBufferAvailable) // bNonPowerOfTwoAvailable et FBO sont detectes une fois qu'on a un contexte OpenGL, on ne peut donc pas les inclure ici.
/* Toggle on/off the indirect rendering mode (for cards like Radeon 35xx).
*/
void gldi_gl_backend_force_indirect_rendering (void);
///////////////
// CONTAINER //
///////////////
/** Make a Container's OpenGL context the current one.
*@param pContainer the container
*@return TRUE if the Container's context is now the current one.
*/
gboolean gldi_gl_container_make_current (GldiContainer *pContainer);
gboolean gldi_gl_container_begin_draw_full (GldiContainer *pContainer, GdkRectangle *pArea, gboolean bClear);
#define gldi_gl_container_begin_draw(pContainer) gldi_gl_container_begin_draw_full (pContainer, NULL, TRUE)
/** Ends the drawing on a Container's OpenGL context (swap buffers).
*@param pContainer the container
*/
void gldi_gl_container_end_draw (GldiContainer *pContainer);
/** Set a perspective view to the current GL context to fit a given ontainer. Perspective view accentuates the depth effect of the scene, but can distort it on the edges, and is difficult to manipulate because the size of objects depends on their position.
*@param pContainer the container
*/
void cairo_dock_set_perspective_view (GldiContainer *pContainer);
void cairo_dock_set_perspective_view_for_icon (Icon *pIcon, GldiContainer *pContainer);
/** Set an orthogonal view to the current GL context to fit a given ontainer. Orthogonal view is convenient to draw classic 2D, because the objects are not zoomed according to their position. The drawback is a poor depth effect.
*@param pContainer the container
*/
void cairo_dock_set_ortho_view (GldiContainer *pContainer);
void cairo_dock_set_ortho_view_for_icon (Icon *pIcon, GldiContainer *pContainer);
/** Set a shared default-initialized GL context on a window.
*@param pContainer the container, not yet realized.
*/
void gldi_gl_container_init (GldiContainer *pContainer);
void gldi_gl_container_finish (GldiContainer *pContainer);
void gldi_gl_manager_register_backend (GldiGLManagerBackend *pBackend);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-dock-visibility.h 000664 001750 001750 00000003377 12223247550 024065 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_VISIBILITY__
#define __CAIRO_DOCK_VISIBILITY__
#include "cairo-dock-struct.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-dock-visibility.h This class manages the visibility of Docks.
*/
#define _gldi_window_is_on_our_way(pAppli, pDock) (pAppli != NULL && gldi_window_is_on_current_desktop (pAppli) && pDock->iVisibility == CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP && gldi_dock_overlaps_window (pDock, pAppli))
void gldi_dock_hide_show_if_current_window_is_on_our_way (CairoDock *pDock);
void gldi_dock_hide_if_any_window_overlap_or_show (CairoDock *pDock);
gboolean gldi_dock_overlaps_window (CairoDock *pDock, GldiWindowActor *actor);
/** Get the application whose window overlaps a dock, or NULL if none.
*@param pDock the dock to test.
*@return the window actor, or NULL if none has been found.
*/
GldiWindowActor *gldi_dock_search_overlapping_window (CairoDock *pDock);
void gldi_docks_visibility_start (void);
void gldi_docks_visibility_stop (void); // not used yet
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-file-manager.h 000664 001750 001750 00000023266 12223247550 023306 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_FILE_MANAGER__
#define __CAIRO_DOCK_FILE_MANAGER__
#include "cairo-dock-icon-factory.h"
#include "cairo-dock-struct.h"
#include "cairo-dock-manager.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-file-manager.h This class manages the integration into the desktop environment, which includes :
* - the VFS (Virtual File System)
* - the various desktop-related tools.
*/
// manager
#ifndef _MANAGER_DEF_
extern GldiManager myDesktopEnvMgr;
#endif
/// Type of available Desktop Environments.
typedef enum {
CAIRO_DOCK_UNKNOWN_ENV=0,
CAIRO_DOCK_GNOME,
CAIRO_DOCK_KDE,
CAIRO_DOCK_XFCE,
CAIRO_DOCK_NB_DESKTOPS
} CairoDockDesktopEnv;
/// Type of events that can occur to a file.
typedef enum {
CAIRO_DOCK_FILE_MODIFIED=0,
CAIRO_DOCK_FILE_DELETED,
CAIRO_DOCK_FILE_CREATED,
CAIRO_DOCK_NB_EVENT_ON_FILES
} CairoDockFMEventType;
/// Type of sorting available on files.
typedef enum {
CAIRO_DOCK_FM_SORT_BY_NAME=0,
CAIRO_DOCK_FM_SORT_BY_DATE,
CAIRO_DOCK_FM_SORT_BY_SIZE,
CAIRO_DOCK_FM_SORT_BY_TYPE,
CAIRO_DOCK_FM_SORT_BY_ACCESS,
CAIRO_DOCK_NB_SORT_ON_FILE
} CairoDockFMSortType;
#define CAIRO_DOCK_FM_VFS_ROOT "_vfsroot_"
#define CAIRO_DOCK_FM_NETWORK "_network_"
#define CAIRO_DOCK_FM_TRASH "_trash_"
#define CAIRO_DOCK_FM_DESKTOP "_desktop_"
typedef void (*CairoDockFMGetFileInfoFunc) (const gchar *cBaseURI, gchar **cName, gchar **cURI, gchar **cIconName, gboolean *bIsDirectory, int *iVolumeID, double *fOrder, CairoDockFMSortType iSortType);
typedef void (*CairoDockFMFilePropertiesFunc) (const gchar *cURI, guint64 *iSize, time_t *iLastModificationTime, gchar **cMimeType, int *iUID, int *iGID, int *iPermissionsMask);
typedef GList * (*CairoDockFMListDirectoryFunc) (const gchar *cURI, CairoDockFMSortType g_fm_iSortType, int iNewIconsType, gboolean bListHiddenFiles, int iNbMaxFiles, gchar **cFullURI);
typedef gsize (*CairoDockFMMeasureDirectoryFunc) (const gchar *cURI, gint iCountType, gboolean bRecursive, gint *pCancel);
typedef void (*CairoDockFMLaunchUriFunc) (const gchar *cURI);
typedef gchar * (*CairoDockFMIsMountedFunc) (const gchar *cURI, gboolean *bIsMounted);
typedef gboolean (*CairoDockFMCanEjectFunc) (const gchar *cURI);
typedef gboolean (*CairoDockFMEjectDriveFunc) (const gchar *cURI);
typedef void (*CairoDockFMMountCallback) (gboolean bMounting, gboolean bSuccess, const gchar *cName, const gchar *cUri, gpointer data);
typedef void (*CairoDockFMMountFunc) (const gchar *cURI, int iVolumeID, CairoDockFMMountCallback pCallback, gpointer user_data);
typedef void (*CairoDockFMUnmountFunc) (const gchar *cURI, int iVolumeID, CairoDockFMMountCallback pCallback, gpointer user_data);
typedef void (*CairoDockFMMonitorCallback) (CairoDockFMEventType iEventType, const gchar *cURI, gpointer data);
typedef void (*CairoDockFMAddMonitorFunc) (const gchar *cURI, gboolean bDirectory, CairoDockFMMonitorCallback pCallback, gpointer data);
typedef void (*CairoDockFMRemoveMonitorFunc) (const gchar *cURI);
typedef gboolean (*CairoDockFMDeleteFileFunc) (const gchar *cURI, gboolean bNoTrash);
typedef gboolean (*CairoDockFMRenameFileFunc) (const gchar *cOldURI, const gchar *cNewName);
typedef gboolean (*CairoDockFMMoveFileFunc) (const gchar *cURI, const gchar *cDirectoryURI);
typedef gboolean (*CairoDockFMCreateFileFunc) (const gchar *cURI, gboolean bDirectory);
typedef GList * (*CairoDockFMListAppsForFileFunc) (const gchar *cURI);
typedef gchar * (*CairoDockFMGetTrashFunc) (const gchar *cNearURI, gchar **cFileInfoPath);
typedef void (*CairoDockFMEmptyTrashFunc) (void);
typedef gchar * (*CairoDockFMGetDesktopFunc) (void);
typedef void (*CairoDockFMUserActionFunc) (void);
/// Definition of the Desktop Environment backend.
struct _CairoDockDesktopEnvBackend {
CairoDockFMGetFileInfoFunc get_file_info;
CairoDockFMFilePropertiesFunc get_file_properties;
CairoDockFMListDirectoryFunc list_directory;
CairoDockFMMeasureDirectoryFunc measure_directory;
CairoDockFMLaunchUriFunc launch_uri;
CairoDockFMIsMountedFunc is_mounted;
CairoDockFMCanEjectFunc can_eject;
CairoDockFMEjectDriveFunc eject;
CairoDockFMMountFunc mount;
CairoDockFMUnmountFunc unmount;
CairoDockFMAddMonitorFunc add_monitor;
CairoDockFMRemoveMonitorFunc remove_monitor;
CairoDockFMDeleteFileFunc delete_file;
CairoDockFMRenameFileFunc rename;
CairoDockFMMoveFileFunc move;
CairoDockFMCreateFileFunc create;
CairoDockFMListAppsForFileFunc list_apps_for_file;
CairoDockFMEmptyTrashFunc empty_trash;
CairoDockFMGetTrashFunc get_trash_path;
CairoDockFMGetDesktopFunc get_desktop_path;
CairoDockFMUserActionFunc logout;
CairoDockFMUserActionFunc lock_screen;
CairoDockFMUserActionFunc shutdown;
CairoDockFMUserActionFunc reboot;
CairoDockFMUserActionFunc setup_time;
CairoDockFMUserActionFunc show_system_monitor;
};
/** Register a environment backend, overwriting any previous backend.
*/
void cairo_dock_fm_register_vfs_backend (CairoDockDesktopEnvBackend *pVFSBackend);
gboolean cairo_dock_fm_vfs_backend_is_defined (void);
void cairo_dock_fm_force_desktop_env (CairoDockDesktopEnv iForceDesktopEnv);
/** List the content of a directory and turn it into a list of icons.
*/
GList * cairo_dock_fm_list_directory (const gchar *cURI, CairoDockFMSortType g_fm_iSortType, int iNewIconsType, gboolean bListHiddenFiles, int iNbMaxFiles, gchar **cFullURI);
/** Measure a directory (number of files or total size).
*/
gsize cairo_dock_fm_measure_diretory (const gchar *cBaseURI, gint iCountType, gboolean bRecursive, gint *pCancel);
/** Get the main info to represent a file.
*/
gboolean cairo_dock_fm_get_file_info (const gchar *cBaseURI, gchar **cName, gchar **cURI, gchar **cIconName, gboolean *bIsDirectory, int *iVolumeID, double *fOrder, CairoDockFMSortType iSortType);
/** Get some properties about a file.
*/
gboolean cairo_dock_fm_get_file_properties (const gchar *cURI, guint64 *iSize, time_t *iLastModificationTime, gchar **cMimeType, int *iUID, int *iGID, int *iPermissionsMask);
/** Open a file with the default application.
*/
gboolean cairo_dock_fm_launch_uri (const gchar *cURI);
/** Add a monitor on an URI. It will be called each time a modification occurs on the file.
*/
gboolean cairo_dock_fm_add_monitor_full (const gchar *cURI, gboolean bDirectory, const gchar *cMountedURI, CairoDockFMMonitorCallback pCallback, gpointer data);
/** Remove a monitor on an URI.
*/
gboolean cairo_dock_fm_remove_monitor_full (const gchar *cURI, gboolean bDirectory, const gchar *cMountedURI);
/** Mount a point.
*/
gboolean cairo_dock_fm_mount_full (const gchar *cURI, int iVolumeID, CairoDockFMMountCallback pCallback, gpointer user_data);
/** Unmount a point.
*/
gboolean cairo_dock_fm_unmount_full (const gchar *cURI, int iVolumeID, CairoDockFMMountCallback pCallback, gpointer user_data);
/** Say if a point is currently mounted.
*/
gchar *cairo_dock_fm_is_mounted (const gchar *cURI, gboolean *bIsMounted);
/** Say if a point can be ejected (like a CD player).
*/
gboolean cairo_dock_fm_can_eject (const gchar *cURI);
/** Eject a drive, like a CD player.
*/
gboolean cairo_dock_fm_eject_drive (const gchar *cURI);
/** Delete a file.
*/
gboolean cairo_dock_fm_delete_file (const gchar *cURI, gboolean bNoTrash);
/** Rename a file.
*/
gboolean cairo_dock_fm_rename_file (const gchar *cOldURI, const gchar *cNewName);
/** Move a file.
*/
gboolean cairo_dock_fm_move_file (const gchar *cURI, const gchar *cDirectoryURI);
/** Create a new file.
*/
gboolean cairo_dock_fm_create_file (const gchar *cURI, gboolean bDirectory);
/** Get the list of applications that can open a given file. Returns a list of strings arrays : {name, command, icon}.
*/
GList *cairo_dock_fm_list_apps_for_file (const gchar *cURI);
/** Empty the Trash.
*/
gboolean cairo_dock_fm_empty_trash (void);
/** Get the path to the Trash.
*/
gchar *cairo_dock_fm_get_trash_path (const gchar *cNearURI, gchar **cFileInfoPath);
/** Get the path to the Desktop.
*/
gchar *cairo_dock_fm_get_desktop_path (void);
/** Raise the logout panel.
*/
gboolean cairo_dock_fm_logout (void);
/** Raise the shutdown panel.
*/
gboolean cairo_dock_fm_shutdown (void);
/** Raise the reboot panel.
*/
gboolean cairo_dock_fm_reboot (void);
/** Lock the screen.
*/
gboolean cairo_dock_fm_lock_screen (void);
gboolean cairo_dock_fm_can_setup_time (void);
/** Raise the panel to configure the time.
*/
gboolean cairo_dock_fm_setup_time (void);
/** Raise the default system monitor.
*/
gboolean cairo_dock_fm_show_system_monitor (void);
/** Create an Icon representing a given URI.
*/
Icon *cairo_dock_fm_create_icon_from_URI (const gchar *cURI, GldiContainer *pContainer, CairoDockFMSortType iFileSortType);
gboolean cairo_dock_fm_move_into_directory (const gchar *cURI, Icon *icon, GldiContainer *pContainer);
/** Get the size of a local file.
*@param cFilePath path of a file on the hard disk.
*@return the size of the file, or 0 if it doesn't exist.
*/
int cairo_dock_get_file_size (const gchar *cFilePath);
gboolean cairo_dock_copy_file (const gchar *cFilePath, const gchar *cDestPath);
void gldi_register_desktop_environment_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-applications-manager.h 000664 001750 001750 00000007415 12233704045 025051 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_APPLICATION_MANAGER__
#define __CAIRO_DOCK_APPLICATION_MANAGER__
#include "cairo-dock-struct.h"
#include "cairo-dock-icon-manager.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-applications-manager.h This class manages the list of icons representing a window, ie the Taskbar.
*/
// manager
typedef struct _CairoTaskbarParam CairoTaskbarParam;
typedef struct _Icon AppliIcon;
#ifndef _MANAGER_DEF_
extern CairoTaskbarParam myTaskbarParam;
extern GldiManager myTaskbarMgr;
extern GldiObjectManager myAppliIconObjectMgr;
#endif
typedef enum {
CAIRO_APPLI_BEFORE_FIRST_ICON,
CAIRO_APPLI_BEFORE_FIRST_LAUNCHER,
CAIRO_APPLI_AFTER_LAST_LAUNCHER,
CAIRO_APPLI_AFTER_LAST_ICON,
CAIRO_APPLI_AFTER_ICON,
CAIRO_APPLI_NB_PLACEMENTS
} CairoTaskbarPlacement;
// params
struct _CairoTaskbarParam {
gboolean bShowAppli;
gboolean bGroupAppliByClass;
gint iAppliMaxNameLength;
gboolean bMinimizeOnClick;
gboolean bPresentClassOnClick;
gint iActionOnMiddleClick;
gboolean bHideVisibleApplis;
gdouble fVisibleAppliAlpha;
gboolean bAppliOnCurrentDesktopOnly;
gboolean bDemandsAttentionWithDialog;
gint iDialogDuration;
gchar *cAnimationOnDemandsAttention;
gchar *cAnimationOnActiveWindow;
gboolean bOverWriteXIcons;
gint iMinimizedWindowRenderType;
gboolean bMixLauncherAppli;
gchar *cOverwriteException;
gchar *cGroupException;
gchar *cForceDemandsAttention;
CairoTaskbarPlacement iIconPlacement;
gchar *cRelativeIconName;
gboolean bSeparateApplis;
} ;
// signals
typedef enum {
NB_NOTIFICATIONS_TASKBAR = NB_NOTIFICATIONS_ICON,
} CairoTaskbarNotifications;
/** Say if an object is an AppliIcon.
*@param obj the object.
*@return TRUE if the object is a AppliIcon.
*/
#define GLDI_OBJECT_IS_APPLI_ICON(obj) gldi_object_is_manager_child (GLDI_OBJECT(obj), &myAppliIconObjectMgr)
/** Start the applications manager. It will load all the appli-icons, and keep monitoring them. If enabled, it will insert them into the dock.
*@param pDock the main dock
*/
void cairo_dock_start_applications_manager (CairoDock *pDock);
/** Get the list of appli-icons, including the icons not currently displayed in the dock. You can then order the list by z-order, name, etc.
*@return a newly allocated list of appli-icons. You must free the list when you're done with it, but not the icons.
*/
GList *cairo_dock_get_current_applis_list (void);
/** Get the icon of the currently active window, if any.
*@return the icon (maybe not inside a dock, maybe NULL).
*/
Icon *cairo_dock_get_current_active_icon (void);
/** Get the icon of a given window, if any.
*@param actor the window actor
*@return the icon (maybe not inside a dock, maybe NULL).
*/
Icon *cairo_dock_get_appli_icon (GldiWindowActor *actor);
/** Run a function on all Appli icons.
*@param pFunction function to be called
*@param pUserData data passed to the function.
*/
void cairo_dock_foreach_appli_icon (GldiIconFunc pFunction, gpointer pUserData);
void cairo_dock_set_icons_geometry_for_window_manager (CairoDock *pDock);
void gldi_register_applications_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-opengl-path.c 000664 001750 001750 00000043630 12223247550 023165 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-icon-facility.h" // cairo_dock_generate_string_path_opengl
#include "cairo-dock-dock-factory.h"
#include "cairo-dock-separator-manager.h"
#include "cairo-dock-opengl-path.h"
#define _CD_PATH_DIM 2
#define _cd_gl_path_set_nth_vertex_x(pPath, _x, i) pPath->pVertices[_CD_PATH_DIM*(i)] = _x
#define _cd_gl_path_set_nth_vertex_y(pPath, _y, i) pPath->pVertices[_CD_PATH_DIM*(i)+1] = _y
#define _cd_gl_path_set_vertex_x(pPath, _x) _cd_gl_path_set_nth_vertex_x (pPath, _x, pPath->iCurrentPt)
#define _cd_gl_path_set_vertex_y(pPath, _y) _cd_gl_path_set_nth_vertex_y (pPath, _y, pPath->iCurrentPt)
#define _cd_gl_path_set_current_vertex(pPath, _x, _y) do {\
_cd_gl_path_set_vertex_x(pPath, _x);\
_cd_gl_path_set_vertex_y(pPath, _y); } while (0)
#define _cd_gl_path_get_nth_vertex_x(pPath, i) pPath->pVertices[_CD_PATH_DIM*(i)]
#define _cd_gl_path_get_nth_vertex_y(pPath, i) pPath->pVertices[_CD_PATH_DIM*(i)+1]
#define _cd_gl_path_get_current_vertex_x(pPath) _cd_gl_path_get_nth_vertex_x (pPath, pPath->iCurrentPt-1)
#define _cd_gl_path_get_current_vertex_y(pPath) _cd_gl_path_get_nth_vertex_y (pPath, pPath->iCurrentPt-1)
CairoDockGLPath *cairo_dock_new_gl_path (int iNbVertices, double x0, double y0, int iWidth, int iHeight)
{
CairoDockGLPath *pPath = g_new0 (CairoDockGLPath, 1);
pPath->pVertices = g_new0 (GLfloat, (iNbVertices+1) * _CD_PATH_DIM); // +1 = securite
pPath->iNbPoints = iNbVertices;
_cd_gl_path_set_current_vertex (pPath, x0, y0);
pPath->iCurrentPt ++;
pPath->iWidth = iWidth;
pPath->iHeight = iHeight;
return pPath;
}
void cairo_dock_free_gl_path (CairoDockGLPath *pPath)
{
if (!pPath)
return;
g_free (pPath->pVertices);
g_free (pPath);
}
void cairo_dock_gl_path_move_to (CairoDockGLPath *pPath, double x0, double y0)
{
pPath->iCurrentPt = 0;
_cd_gl_path_set_current_vertex (pPath, x0, y0);
pPath->iCurrentPt ++;
}
void cairo_dock_gl_path_set_extent (CairoDockGLPath *pPath, int iWidth, int iHeight)
{
pPath->iWidth = iWidth;
pPath->iHeight = iHeight;
}
void cairo_dock_gl_path_line_to (CairoDockGLPath *pPath, GLfloat x, GLfloat y)
{
g_return_if_fail (pPath->iCurrentPt < pPath->iNbPoints);
_cd_gl_path_set_current_vertex (pPath, x, y);
pPath->iCurrentPt ++;
}
void cairo_dock_gl_path_rel_line_to (CairoDockGLPath *pPath, GLfloat dx, GLfloat dy)
{
cairo_dock_gl_path_line_to (pPath,
_cd_gl_path_get_current_vertex_x (pPath) + dx,
_cd_gl_path_get_current_vertex_y (pPath) + dy);
}
// OM(t) = sum ([k=0..n] Bn,k(t)*OAk)
// Bn,k(x) = Cn,k*x^k*(1-x)^(n-k)
#define B0(t) (1-t)*(1-t)*(1-t)
#define B1(t) 3*t*(1-t)*(1-t)
#define B2(t) 3*t*t*(1-t)
#define B3(t) t*t*t
#define Bezier(x0,x1,x2,x3,t) (B0(t)*x0 + B1(t)*x1 + B2(t)*x2 + B3(t)*x3)
void cairo_dock_gl_path_curve_to (CairoDockGLPath *pPath, int iNbPoints, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3)
{
g_return_if_fail (pPath->iCurrentPt + iNbPoints <= pPath->iNbPoints);
GLfloat x0, y0;
x0 = _cd_gl_path_get_current_vertex_x (pPath);
y0 = _cd_gl_path_get_current_vertex_y (pPath);
double t;
int i;
for (i = 0; i < iNbPoints; i ++)
{
t = (double)(i+1)/iNbPoints; // [0;1]
_cd_gl_path_set_nth_vertex_x (pPath, Bezier (x0, x1, x2, x3, t), pPath->iCurrentPt + i);
_cd_gl_path_set_nth_vertex_y (pPath, Bezier (y0, y1, y2, y3, t), pPath->iCurrentPt + i);
}
pPath->iCurrentPt += iNbPoints;
}
void cairo_dock_gl_path_rel_curve_to (CairoDockGLPath *pPath, int iNbPoints, GLfloat dx1, GLfloat dy1, GLfloat dx2, GLfloat dy2, GLfloat dx3, GLfloat dy3)
{
GLfloat x0, y0;
x0 = _cd_gl_path_get_current_vertex_x (pPath);
y0 = _cd_gl_path_get_current_vertex_y (pPath);
cairo_dock_gl_path_curve_to (pPath, iNbPoints, x0 + dx1, y0 + dy1, x0 + dx2, y0 + dy2, x0 + dx3, y0 + dy3);
}
#define Bezier2(p,q,s,t) ((1-t) * (1-t) * p + 2 * t * (1-t) * q + t * t * s)
void cairo_dock_gl_path_simple_curve_to (CairoDockGLPath *pPath, int iNbPoints, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
g_return_if_fail (pPath->iCurrentPt + iNbPoints <= pPath->iNbPoints);
GLfloat x0, y0;
x0 = _cd_gl_path_get_current_vertex_x (pPath);
y0 = _cd_gl_path_get_current_vertex_y (pPath);
double t;
int i;
for (i = 0; i < iNbPoints; i ++)
{
t = (double)(i+1)/iNbPoints; // [0;1]
_cd_gl_path_set_nth_vertex_x (pPath, Bezier2 (x0, x1, x2, t), pPath->iCurrentPt + i);
_cd_gl_path_set_nth_vertex_y (pPath, Bezier2 (y0, y1, y2, t), pPath->iCurrentPt + i);
}
pPath->iCurrentPt += iNbPoints;
}
void cairo_dock_gl_path_rel_simple_curve_to (CairoDockGLPath *pPath, int iNbPoints, GLfloat dx1, GLfloat dy1, GLfloat dx2, GLfloat dy2)
{
GLfloat x0, y0;
x0 = _cd_gl_path_get_current_vertex_x (pPath);
y0 = _cd_gl_path_get_current_vertex_y (pPath);
cairo_dock_gl_path_simple_curve_to (pPath, iNbPoints, x0 + dx1, y0 + dy1, x0 + dx2, y0 + dy2);
}
void cairo_dock_gl_path_arc (CairoDockGLPath *pPath, int iNbPoints, GLfloat xc, GLfloat yc, double r, double teta0, double cone)
{
g_return_if_fail (pPath->iCurrentPt + iNbPoints <= pPath->iNbPoints);
double t;
int i;
for (i = 0; i < iNbPoints; i ++)
{
t = teta0 + (double)i/(iNbPoints-1) * cone; // [teta0, teta0+cone]
_cd_gl_path_set_nth_vertex_x (pPath, xc + r * cos (t), pPath->iCurrentPt + i);
_cd_gl_path_set_nth_vertex_y (pPath, yc + r * sin (t), pPath->iCurrentPt + i);
}
pPath->iCurrentPt += iNbPoints;
}
static inline void _draw_current_path (int iNbPoints, gboolean bClosePath)
{
//\__________________ On active l'antialiasing.
glPolygonMode (GL_FRONT, GL_LINE);
glEnable (GL_LINE_SMOOTH);
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
glEnable (GL_BLEND); // On active le blend pour l'antialiasing.
//glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glLineWidth(fLineWidth);
//glColor4f (fLineColor[0], fLineColor[1], fLineColor[2], fLineColor[3]); // Et sa couleur.
//\__________________ On dessine le cadre.
glEnableClientState (GL_VERTEX_ARRAY);
glDrawArrays (bClosePath ? GL_LINE_LOOP : GL_LINE_STRIP, 0, iNbPoints);
glDisableClientState (GL_VERTEX_ARRAY);
//\__________________ On desactive l'antialiasing.
glDisable (GL_LINE_SMOOTH);
glDisable (GL_BLEND);
}
void cairo_dock_stroke_gl_path (const CairoDockGLPath *pPath, gboolean bClosePath)
{
glVertexPointer (_CD_PATH_DIM, GL_FLOAT, 0, pPath->pVertices);
_draw_current_path (pPath->iCurrentPt, bClosePath);
}
void cairo_dock_fill_gl_path (const CairoDockGLPath *pPath, GLuint iTexture)
{
//\__________________ On active l'antialiasing.
glPolygonMode (GL_FRONT, GL_FILL);
//glEnable (GL_POLYGON_SMOOTH); // makes horrible white lines where the triangles overlaps :-/
//glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glEnable (GL_BLEND); // On active le blend pour l'antialiasing.
//\__________________ On mappe la texture dans le cadre.
if (iTexture != 0)
{
// on active le texturing.
glColor4f(1., 1., 1., 1.); // Couleur a fond
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D); // Je veux de la texture
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, iTexture); // allez on bind la texture
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); // ok la on selectionne le type de generation des coordonnees de la texture
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
glEnable(GL_TEXTURE_GEN_S); // oui je veux une generation en S
glEnable(GL_TEXTURE_GEN_T); // Et en T aussi
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// on met la texture a sa place.
glMatrixMode(GL_TEXTURE);
glPushMatrix ();
glTranslatef (.5, .5, 0.);
if (pPath->iWidth != 0 && pPath->iHeight != 0)
glScalef (1./pPath->iWidth, -1./pPath->iHeight, 1.);
glMatrixMode (GL_MODELVIEW);
}
//\__________________ On dessine le cadre.
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (_CD_PATH_DIM, GL_FLOAT, 0, pPath->pVertices);
glDrawArrays (GL_TRIANGLE_FAN, 0, pPath->iCurrentPt); // GL_POLYGON / GL_TRIANGLE_FAN
glDisableClientState (GL_VERTEX_ARRAY);
//\__________________ On desactive l'antialiasing et la texture.
if (iTexture != 0)
{
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_2D); // Plus de texture merci
glMatrixMode(GL_TEXTURE);
glPopMatrix ();
glMatrixMode (GL_MODELVIEW);
}
//glDisable (GL_POLYGON_SMOOTH);
glDisable (GL_BLEND);
}
// HELPER FUNCTIONS //
#define DELTA_ROUND_DEGREE 3
const CairoDockGLPath *cairo_dock_generate_rectangle_path (double fFrameWidth, double fTotalHeight, double fRadius, gboolean bRoundedBottomCorner)
{
static CairoDockGLPath *pPath = NULL;
double fTotalWidth = fFrameWidth + 2 * fRadius;
double fFrameHeight = MAX (0, fTotalHeight - 2 * fRadius);
double w = fFrameWidth / 2;
double h = fFrameHeight / 2;
double r = fRadius;
int iNbPoins1Round = 90/10;
if (pPath == NULL)
{
pPath = cairo_dock_new_gl_path ((iNbPoins1Round+1)*4+1, w+r, h, fTotalWidth, fTotalHeight); // on commence au centre droit pour avoir une bonne triangulation du polygone, et en raisonnant par rapport au centre du rectangle.
///pPath = cairo_dock_new_gl_path ((iNbPoins1Round+1)*4+1, 0, 0, fTotalWidth, fTotalHeight); // on commence au centre pour avoir une bonne triangulation
}
else
{
cairo_dock_gl_path_move_to (pPath, w+r, h);
///cairo_dock_gl_path_move_to (pPath, 0, 0);
cairo_dock_gl_path_set_extent (pPath, fTotalWidth, fTotalHeight);
}
//cairo_dock_gl_path_move_to (pPath, 0., h+r);
//cairo_dock_gl_path_rel_line_to (pPath, -w, 0.);
cairo_dock_gl_path_arc (pPath, iNbPoins1Round, w, h, r, 0., +G_PI/2); // coin haut droit.
cairo_dock_gl_path_arc (pPath, iNbPoins1Round, -w, h, r, G_PI/2, +G_PI/2); // coin haut gauche.
if (bRoundedBottomCorner)
{
cairo_dock_gl_path_arc (pPath, iNbPoins1Round, -w, -h, r, G_PI, +G_PI/2); // coin bas gauche.
cairo_dock_gl_path_arc (pPath, iNbPoins1Round, w, -h, r, -G_PI/2, +G_PI/2); // coin bas droit.
}
else
{
cairo_dock_gl_path_rel_line_to (pPath, 0., - (fFrameHeight + r));
cairo_dock_gl_path_rel_line_to (pPath, fTotalWidth, 0.);
}
//cairo_dock_gl_path_arc (pPath, iNbPoins1Round, w, h, r, 0., +G_PI/2); // coin haut droit.
return pPath;
}
const CairoDockGLPath *cairo_dock_generate_trapeze_path (double fUpperFrameWidth, double fTotalHeight, double fRadius, gboolean bRoundedBottomCorner, double fInclination, double *fExtraWidth)
{
static CairoDockGLPath *pPath = NULL;
double a = atan (fInclination);
double cosa = 1. / sqrt (1 + fInclination * fInclination);
double sina = cosa * fInclination;
double fFrameHeight = MAX (0, fTotalHeight - 2 * fRadius);
*fExtraWidth = fInclination * (fFrameHeight - (bRoundedBottomCorner ? 2 : 1-cosa) * fRadius) + fRadius * (bRoundedBottomCorner ? 1 : sina);
double fTotalWidth = fUpperFrameWidth + 2*(*fExtraWidth);
double dw = (bRoundedBottomCorner ? fInclination * (fFrameHeight) : *fExtraWidth);
double r = fRadius;
double w = fUpperFrameWidth / 2;
double h = fFrameHeight / 2;
double w_ = w + dw + (bRoundedBottomCorner ? 0 : 0*r * cosa);
int iNbPoins1Round = 70/DELTA_ROUND_DEGREE; // pour une inclinaison classique (~30deg), les coins du haut feront moins d'1/4 de tour.
int iNbPoins1Curve = 10;
if (pPath == NULL)
pPath = cairo_dock_new_gl_path ((iNbPoins1Round+1)*2 + (iNbPoins1Curve+1)*2 + 1, 0., fTotalHeight/2, fTotalWidth, fTotalHeight);
else
{
cairo_dock_gl_path_move_to (pPath, 0., fTotalHeight/2);
cairo_dock_gl_path_set_extent (pPath, fTotalWidth, fTotalHeight);
}
cairo_dock_gl_path_arc (pPath, iNbPoins1Round, -w, h, r, G_PI/2, G_PI/2 - a); // coin haut gauche. 90 -> 180-a
if (bRoundedBottomCorner)
{
double t = G_PI-a;
double x0 = -w_ + r * cos (t);
double y0 = -h + r * sin (t);
double x1 = x0 - fInclination * r * (1+sina);
double y1 = -h - r;
double x2 = -w_;
double y2 = y1;
cairo_dock_gl_path_line_to (pPath, x0, y0);
cairo_dock_gl_path_simple_curve_to (pPath, iNbPoins1Curve, x1, y1, x2, y2); // coin bas gauche.
double x3 = x0, y3 = y0; // temp.
x0 = - x2;
y0 = y2;
x1 = - x1;
x2 = - x3;
y2 = y3;
cairo_dock_gl_path_line_to (pPath, x0, y0);
cairo_dock_gl_path_simple_curve_to (pPath, iNbPoins1Curve, x1, y1, x2, y2); // coin bas droit.
}
else
{
cairo_dock_gl_path_line_to (pPath,
-w_,
-h - r); // bas gauche.
cairo_dock_gl_path_line_to (pPath,
w_,
-h - r); // bas droit.
}
cairo_dock_gl_path_arc (pPath, iNbPoins1Round, w, h, r, a, G_PI/2 - a); // coin haut droit. a -> 90
return pPath;
}
#define _get_icon_center_x(icon) (icon->fDrawX + icon->fWidth * icon->fScale/2)
#define _get_icon_center_y(icon) (icon->fDrawY + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) ? icon->fHeight * (icon->fScale - .5) : icon->fHeight * icon->fScale/2))
#define _get_icon_center(icon,x,y) do {\
if (pDock->container.bIsHorizontal) {\
x = _get_icon_center_x (icon);\
y = pDock->container.iHeight - _get_icon_center_y (icon); }\
else {\
y = _get_icon_center_x (icon);\
x = pDock->container.iWidth - _get_icon_center_y (icon); } } while (0)
#define _calculate_slope(x0,y0,x1,y1,dx,dy) do {\
dx = x1 - x0;\
dy = y1 - y0;\
norme = sqrt (dx*dx + dy*dy);\
dx /= norme;\
dy /= norme; } while (0)
#define NB_VERTEX_PER_ICON_PAIR 10
const CairoDockGLPath *cairo_dock_generate_string_path_opengl (CairoDock *pDock, gboolean bIsLoop, gboolean bForceConstantSeparator)
{
static CairoDockGLPath *pPath = NULL;
if (pPath == NULL)
pPath = cairo_dock_new_gl_path (100*NB_VERTEX_PER_ICON_PAIR + 1, 0., 0., 0., 0.);
GList *ic, *next_ic, *next2_ic, *pFirstDrawnElement = pDock->icons;
Icon *pIcon, *pNextIcon, *pNext2Icon;
double x0,y0, x1,y1, x2,y2; // centres des icones P0, P1, P2, en coordonnees opengl.
double norme; // pour normaliser les pentes.
double dx, dy; // direction au niveau de l'icone courante P0.
double dx_, dy_; // direction au niveau de l'icone suivante P1.
double x0_,y0_, x1_,y1_; // points de controle entre P0 et P1.
if (pFirstDrawnElement == NULL)
{
return pPath;
}
// direction initiale.
ic = pFirstDrawnElement;
pIcon = ic->data;
_get_icon_center (pIcon,x0,y0);
next_ic = cairo_dock_get_next_element (ic, pDock->icons);
pNextIcon = next_ic->data;
_get_icon_center (pNextIcon,x1,y1);
if (! bIsLoop)
{
_calculate_slope (x0,y0, x1,y1, dx,dy);
}
else
{
next2_ic = cairo_dock_get_previous_element (ic, pDock->icons); // icone precedente dans la boucle.
pNext2Icon = next2_ic->data;
_get_icon_center (pNext2Icon,x2,y2);
_calculate_slope (x2,y2, x0,y0, dx,dy);
}
// point suivant.
next2_ic = cairo_dock_get_next_element (next_ic, pDock->icons);
pNext2Icon = next2_ic->data;
_get_icon_center (pNext2Icon,x2,y2);
cairo_dock_gl_path_move_to (pPath, x0, y0);
if (pDock->container.bIsHorizontal)
cairo_dock_gl_path_set_extent (pPath, pDock->container.iWidth, pDock->container.iHeight);
else
cairo_dock_gl_path_set_extent (pPath, pDock->container.iHeight, pDock->container.iWidth);
// on parcourt les icones.
do
{
// l'icone courante, la suivante, et celle d'apres.
pIcon = ic->data;
pNextIcon = next_ic->data;
pNext2Icon = next2_ic->data;
// on va tracer de (x0,y0) a (x1,y1)
_get_icon_center (pIcon,x0,y0);
_get_icon_center (pNextIcon,x1,y1);
_get_icon_center (pNext2Icon,x2,y2);
// la pente au point (x1,y1)
_calculate_slope (x0,y0, x2,y2, dx_,dy_);
// points de controle.
norme = sqrt ((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0))/2; // distance de prolongation suivant la pente.
x0_ = x0 + dx * norme;
y0_ = y0 + dy * norme;
x1_ = x1 - dx_ * norme;
y1_ = y1 - dy_ * norme;
cairo_dock_gl_path_curve_to (pPath, NB_VERTEX_PER_ICON_PAIR,
x0_, y0_,
x1_, y1_,
x1, y1);
// on decale tout d'un cran.
ic = next_ic;
next_ic = next2_ic;
next2_ic = cairo_dock_get_next_element (next_ic, pDock->icons);
dx = dx_;
dy = dy_;
if (next_ic == pFirstDrawnElement && ! bIsLoop)
break ;
}
while (ic != pFirstDrawnElement);
return pPath;
}
void cairo_dock_draw_current_path_opengl (double fLineWidth, double *fLineColor, int iNbVertex)
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glLineWidth(fLineWidth); // Ici on choisit l'epaisseur du contour du polygone.
if (fLineColor != NULL)
glColor4f (fLineColor[0], fLineColor[1], fLineColor[2], fLineColor[3]); // Et sa couleur.
_draw_current_path (iNbVertex, FALSE);
}
void cairo_dock_draw_rounded_rectangle_opengl (double fFrameWidth, double fFrameHeight, double fRadius, double fLineWidth, double *fLineColor)
{
const CairoDockGLPath *pPath = cairo_dock_generate_rectangle_path (fFrameWidth, fFrameHeight, fRadius, TRUE);
if (fLineColor != NULL)
glColor4f (fLineColor[0], fLineColor[1], fLineColor[2], fLineColor[3]);
if (fLineWidth == 0)
{
cairo_dock_fill_gl_path (pPath, 0);
}
else
{
glLineWidth (fLineWidth);
cairo_dock_stroke_gl_path (pPath, TRUE);
}
}
void cairo_dock_draw_string_opengl (CairoDock *pDock, double fStringLineWidth, gboolean bIsLoop, gboolean bForceConstantSeparator)
{
const CairoDockGLPath *pPath = cairo_dock_generate_string_path_opengl (pDock, bIsLoop, bForceConstantSeparator);
if (pPath == NULL || pPath->iCurrentPt < 2)
return;
glLineWidth (fStringLineWidth);
///glColor4f (myIconsParam.fStringColor[0], myIconsParam.fStringColor[1], myIconsParam.fStringColor[2], myIconsParam.fStringColor[3]);
cairo_dock_stroke_gl_path (pPath, FALSE);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-opengl-font.h 000664 001750 001750 00000013236 12223247550 023203 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_OPENGL_FONT__
#define __CAIRO_DOCK_OPENGL_FONT__
#include
#include
#include "cairo-dock-struct.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-opengl-font.h This class provides different ways to draw text directly in OpenGL.
* \ref cairo_dock_create_texture_from_text_simple lets you draw any text in any font, by creating a texture from a Pango font description. This is a convenient function but not very fast.
* For a more efficient way, you load a font into a CairoDockGLFont with either :
* \ref cairo_dock_load_textured_font to load a subset of a Mono font into textures.
* You then use \ref cairo_dock_draw_gl_text_at_position to draw the text.
*/
/** Create a texture from a text. The text is drawn in white, so that you can later colorize it with a mere glColor.
*@param cText the text
*@param cFontDescription a description of the font, for instance "Monospace Bold 12"
*@param pSourceContext a cairo context, not altered by the function.
*@param iWidth a pointer that will be filled with the width of the texture.
*@param iHeight a pointer that will be filled with the height of the texture.
*@return a newly allocated texture.
*/
GLuint cairo_dock_create_texture_from_text_simple (const gchar *cText, const gchar *cFontDescription, cairo_t* pSourceContext, int *iWidth, int *iHeight);
/// Structure used to load a font for OpenGL text rendering.
struct _CairoDockGLFont {
GLuint iListBase;
GLuint iTexture;
gint iNbRows;
gint iNbColumns;
gint iCharBase;
gint iNbChars;
gdouble iCharWidth;
gdouble iCharHeight;
};
/* Load a font into bitmaps. You can load any characters of font with this function. The drawback is that each character is a bitmap, that is to say you can't zoom them.
*@param cFontDescription a description of the font, for instance "Monospace Bold 12"
*@param first first character to load.
*@param count number of characters to load.
*@return a newly allocated opengl font.
*/
//CairoDockGLFont *cairo_dock_load_bitmap_font (const gchar *cFontDescription, int first, int count);
/** Load a font into textures. You can then render your text like a normal texture (zoom, etc). The drawback is that only a mono font can be used with this function.
*@param cFontDescription a description of the font, for instance "Monospace Bold 12"
*@param first first character to load.
*@param count number of characters to load.
*@return a newly allocated opengl font.
*/
CairoDockGLFont *cairo_dock_load_textured_font (const gchar *cFontDescription, int first, int count);
/** Like the previous function, but loads the characters from an image. The image must be squared and contain the 256 extended ASCII characters in the alphabetic order.
*@param cImagePath path to the image.
*@return a newly allocated opengl font.
*/
CairoDockGLFont *cairo_dock_load_textured_font_from_image (const gchar *cImagePath);
/** Free an opengl font.
*@param pFont the font.
*/
void cairo_dock_free_gl_font (CairoDockGLFont *pFont);
/** Compute the size a text will take for a given font.
*@param cText the text
*@param pFont the font.
*@param iWidth a pointer that will be filled with the width of the text.
*@param iHeight a pointer that will be filled with the height of the text.
*/
void cairo_dock_get_gl_text_extent (const gchar *cText, CairoDockGLFont *pFont, int *iWidth, int *iHeight);
/** Render a text for a given font. In the case of a bitmap font, the current raster position is used. In the case of a texture font, the current model view is used.
*@param cText the text
*@param pFont the font.
*/
void cairo_dock_draw_gl_text (const guchar *cText, CairoDockGLFont *pFont);
/** Like /ref cairo_dock_draw_gl_text but at a given position.
*@param cText the text
*@param pFont the font.
*@param x x position of the left bottom corner of the text.
*@param y y position of the left bottom corner of the text.
*/
void cairo_dock_draw_gl_text_at_position (const guchar *cText, CairoDockGLFont *pFont, int x, int y);
/** Like /ref cairo_dock_draw_gl_text but resize the text so that it fits into a given area. Only works for a texture font.
*@param cText the text
*@param pFont the font.
*@param iWidth iWidth of the area.
*@param iHeight iHeight of the area
*@param bCentered whether the text is centered on the current position or not.
*/
void cairo_dock_draw_gl_text_in_area (const guchar *cText, CairoDockGLFont *pFont, int iWidth, int iHeight, gboolean bCentered);
/** Like /ref cairo_dock_draw_gl_text_in_area and /ref cairo_dock_draw_gl_text_at_position.
*@param cText the text
*@param pFont the font.
*@param x x position of the left bottom corner of the text.
*@param y y position of the left bottom corner of the text.
*@param iWidth iWidth of the area.
*@param iHeight iHeight of the area
*@param bCentered whether the text is centered on the given position or not.
*/
void cairo_dock_draw_gl_text_at_position_in_area (const guchar *cText, CairoDockGLFont *pFont, int x, int y, int iWidth, int iHeight, gboolean bCentered);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-applet-manager.h 000664 001750 001750 00000004025 12223247550 023644 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_APPLET_ICON_MANAGER__
#define __CAIRO_DOCK_APPLET_ICON_MANAGER__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-icon-manager.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-applet-manager.h This class handles the Applet Icons, which are icons used by module instances.
* Note: they are not UserIcon, because they are created by and belongs to a ModuleInstance, which is the actual object belonging to the user.
*/
// manager
typedef struct _GldiAppletIconAttr GldiAppletIconAttr;
typedef Icon GldiAppletIcon; // icon + module-instance
#ifndef _MANAGER_DEF_
extern GldiObjectManager myAppletIconObjectMgr;
#endif
struct _GldiAppletIconAttr {
CairoDockMinimalAppletConfig *pMinimalConfig;
GldiModuleInstance *pModuleInstance;
};
// signals
typedef enum {
NB_NOTIFICATIONS_APPLET_ICON = NB_NOTIFICATIONS_ICON,
} GldiAppletIconNotifications;
/** Say if an object is a AppletIcon.
*@param obj the object.
*@return TRUE if the object is a AppletIcon.
*/
#define GLDI_OBJECT_IS_APPLET_ICON(obj) gldi_object_is_manager_child (GLDI_OBJECT(obj), &myAppletIconObjectMgr)
Icon *gldi_applet_icon_new (CairoDockMinimalAppletConfig *pMinimalConfig, GldiModuleInstance *pModuleInstance);
void gldi_register_applet_icons_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-launcher-manager.c 000664 001750 001750 00000031774 12223247550 024166 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include "gldi-config.h" // GLDI_VERSION
#include "cairo-dock-icon-facility.h" // cairo_dock_compare_icons_order
#include "cairo-dock-config.h" // cairo_dock_update_conf_file
#include "cairo-dock-surface-factory.h"
#include "cairo-dock-backends-manager.h" // cairo_dock_set_renderer
#include "cairo-dock-log.h"
#include "cairo-dock-utils.h"
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-applications-manager.h" // myTaskbarParam.bMixLauncherAppli
#include "cairo-dock-class-icon-manager.h"
#include "cairo-dock-class-manager.h" // cairo_dock_inhibite_class
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-dock-facility.h" // cairo_dock_update_dock_size
#include "cairo-dock-separator-manager.h" // cairo_dock_create_separator_surface
#include "cairo-dock-themes-manager.h" // cairo_dock_update_conf_file
#include "cairo-dock-windows-manager.h" // gldi_window_show
#include "cairo-dock-file-manager.h" // g_iDesktopEnv
#include "cairo-dock-launcher-manager.h"
// public (manager, config, data)
GldiObjectManager myLauncherObjectMgr;
// dependancies
extern gchar *g_cCurrentLaunchersPath;
extern CairoDockDesktopEnv g_iDesktopEnv;
// private
#define CAIRO_DOCK_LAUNCHER_CONF_FILE "launcher.desktop"
static gboolean _get_launcher_params (Icon *icon, GKeyFile *pKeyFile)
{
gboolean bNeedUpdate = FALSE;
// get launcher params
icon->cFileName = g_key_file_get_string (pKeyFile, "Desktop Entry", "Icon", NULL);
if (icon->cFileName != NULL && *icon->cFileName == '\0')
{
g_free (icon->cFileName);
icon->cFileName = NULL;
}
icon->cName = g_key_file_get_locale_string (pKeyFile, "Desktop Entry", "Name", NULL, NULL);
if (icon->cName != NULL && *icon->cName == '\0')
{
g_free (icon->cName);
icon->cName = NULL;
}
icon->cCommand = g_key_file_get_string (pKeyFile, "Desktop Entry", "Exec", NULL);
if (icon->cCommand != NULL && *icon->cCommand == '\0')
{
g_free (icon->cCommand);
icon->cCommand = NULL;
}
gchar *cStartupWMClass = g_key_file_get_string (pKeyFile, "Desktop Entry", "StartupWMClass", NULL);
if (cStartupWMClass && *cStartupWMClass == '\0')
{
g_free (cStartupWMClass);
cStartupWMClass = NULL;
}
// get the origin of the desktop file.
gchar *cClass = NULL;
gsize length = 0;
gchar **pOrigins = g_key_file_get_string_list (pKeyFile, "Desktop Entry", "Origin", &length, NULL);
int iNumOrigin = -1;
if (pOrigins != NULL) // some origins are provided, try them one by one.
{
int i;
for (i = 0; pOrigins[i] != NULL; i++)
{
cClass = cairo_dock_register_class_full (pOrigins[i], cStartupWMClass, NULL);
if (cClass != NULL) // neat, this origin is a valid one, let's use it from now.
{
iNumOrigin = i;
break;
}
}
g_strfreev (pOrigins);
}
// if no origin class could be found, try to guess the class
gchar *cFallbackClass = NULL;
if (cClass == NULL) // no class found, maybe an old launcher or a custom one, try to guess from the info in the user desktop file.
{
cFallbackClass = cairo_dock_guess_class (icon->cCommand, cStartupWMClass);
cClass = cairo_dock_register_class_full (cFallbackClass, cStartupWMClass, NULL);
}
// get common data from the class
g_free (icon->cClass);
if (cClass != NULL)
{
icon->cClass = cClass;
g_free (cFallbackClass);
cairo_dock_set_data_from_class (cClass, icon);
if (iNumOrigin != 0) // it's not the first origin that gave us the correct class, so let's write it down to avoid searching the next time.
{
g_key_file_set_string (pKeyFile, "Desktop Entry", "Origin", cairo_dock_get_class_desktop_file (cClass));
bNeedUpdate = TRUE;
}
}
else // no class found, it's maybe an old launcher, take the remaining common params from the user desktop file.
{
icon->cClass = cFallbackClass;
gsize length = 0;
icon->pMimeTypes = g_key_file_get_string_list (pKeyFile, "Desktop Entry", "MimeType", &length, NULL);
if (icon->cCommand != NULL)
{
icon->cWorkingDirectory = g_key_file_get_string (pKeyFile, "Desktop Entry", "Path", NULL);
if (icon->cWorkingDirectory != NULL && *icon->cWorkingDirectory == '\0')
{
g_free (icon->cWorkingDirectory);
icon->cWorkingDirectory = NULL;
}
}
}
// take into account the execution in a terminal.
gboolean bExecInTerminal = g_key_file_get_boolean (pKeyFile, "Desktop Entry", "Terminal", NULL);
if (bExecInTerminal) // on le fait apres la classe puisqu'on change la commande.
{
gchar *cOldCommand = icon->cCommand;
icon->cCommand = cairo_dock_get_command_with_right_terminal (cOldCommand);
g_free (cOldCommand);
}
gboolean bPreventFromInhibiting = g_key_file_get_boolean (pKeyFile, "Desktop Entry", "prevent inhibate", NULL); // FALSE by default
if (bPreventFromInhibiting)
{
g_free (icon->cClass);
icon->cClass = NULL;
}
g_free (cStartupWMClass);
return bNeedUpdate;
}
static void _show_appli_for_drop (Icon *pIcon)
{
if (pIcon->pAppli != NULL)
gldi_window_show (pIcon->pAppli);
}
static void init_object (GldiObject *obj, gpointer attr)
{
Icon *icon = (Icon*)obj;
GldiUserIconAttr *pAttributes = (GldiUserIconAttr*)attr;
icon->iface.action_on_drag_hover = _show_appli_for_drop; // we use the generic 'load_image' method
if (!pAttributes->pKeyFile)
return;
//\____________ get additional parameters
GKeyFile *pKeyFile = pAttributes->pKeyFile;
gboolean bNeedUpdate = _get_launcher_params (icon, pKeyFile);
if (icon->cCommand == NULL) // no command could be found for this launcher -> mark it as invalid
{
g_free (icon->cDesktopFileName);
icon->cDesktopFileName = NULL; // we use this as a way to tell the UserIcon manager that the icon is invalid; we could add a boolean in the GldiUserIcon structure, but it's not that necessary
}
//\____________ Make it an inhibator for its class.
cd_message ("+ %s/%s", icon->cName, icon->cClass);
if (icon->cClass != NULL)
{
cairo_dock_inhibite_class (icon->cClass, icon); // gere le bMixLauncherAppli
}
//\____________ Update the conf file if needed.
if (! bNeedUpdate)
bNeedUpdate = cairo_dock_conf_file_needs_update (pKeyFile, GLDI_VERSION);
if (bNeedUpdate)
{
gchar *cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, pAttributes->cConfFileName);
const gchar *cTemplateFile = GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_LAUNCHER_CONF_FILE;
cairo_dock_upgrade_conf_file (cDesktopFilePath, pKeyFile, cTemplateFile); // update keys
g_free (cDesktopFilePath);
}
}
static GKeyFile* reload_object (GldiObject *obj, gboolean bReloadConf, GKeyFile *pKeyFile)
{
Icon *icon = (Icon*)obj;
if (bReloadConf)
g_return_val_if_fail (pKeyFile != NULL, NULL);
gchar *cClass = icon->cClass;
icon->cClass = NULL;
gchar *cName = icon->cName;
icon->cName = NULL;
g_free (icon->cFileName);
icon->cFileName = NULL;
g_free (icon->cCommand);
icon->cCommand = NULL;
if (icon->pMimeTypes != NULL)
{
g_strfreev (icon->pMimeTypes);
icon->pMimeTypes = NULL;
}
g_free (icon->cWorkingDirectory);
icon->cWorkingDirectory = NULL;
//\__________________ get parameters
_get_launcher_params (icon, pKeyFile);
//\_____________ reload icon's buffers
GldiContainer *pNewContainer = cairo_dock_get_icon_container (icon);
cairo_dock_load_icon_image (icon, pNewContainer);
if (g_strcmp0 (cName, icon->cName) != 0)
cairo_dock_load_icon_text (icon);
//\_____________ handle class inhibition.
gchar *cNowClass = icon->cClass;
if (cClass != NULL && (cNowClass == NULL || strcmp (cNowClass, cClass) != 0)) // la classe a change, on desinhibe l'ancienne.
{
icon->cClass = cClass;
cairo_dock_deinhibite_class (cClass, icon);
cClass = NULL; // libere par la fonction precedente.
icon->cClass = cNowClass;
}
if (myTaskbarParam.bMixLauncherAppli && cNowClass != NULL && (cClass == NULL || strcmp (cNowClass, cClass) != 0)) // la classe a change, on inhibe la nouvelle.
cairo_dock_inhibite_class (cNowClass, icon);
//\_____________ redraw dock.
cairo_dock_redraw_icon (icon);
g_free (cClass);
g_free (cName);
return pKeyFile;
}
void gldi_register_launchers_manager (void)
{
// Object Manager
memset (&myLauncherObjectMgr, 0, sizeof (GldiObjectManager));
myLauncherObjectMgr.cName = "Launcher";
myLauncherObjectMgr.iObjectSize = sizeof (GldiLauncherIcon);
// interface
myLauncherObjectMgr.init_object = init_object;
myLauncherObjectMgr.reload_object = reload_object;
// signals
gldi_object_install_notifications (&myLauncherObjectMgr, NB_NOTIFICATIONS_LAUNCHER);
// parent object
gldi_object_set_manager (GLDI_OBJECT (&myLauncherObjectMgr), &myUserIconObjectMgr);
}
Icon *gldi_launcher_new (const gchar *cConfFile, GKeyFile *pKeyFile)
{
GldiLauncherIconAttr attr = {(gchar*)cConfFile, pKeyFile};
return (Icon*)gldi_object_new (&myLauncherObjectMgr, &attr);
}
gchar *gldi_launcher_add_conf_file (const gchar *cOrigin, const gchar *cDockName, double fOrder)
{
//\__________________ open the template.
const gchar *cTemplateFile = GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_LAUNCHER_CONF_FILE;
GKeyFile *pKeyFile = cairo_dock_open_key_file (cTemplateFile);
g_return_val_if_fail (pKeyFile != NULL, NULL);
//\__________________ fill the parameters
gchar *cFilePath = NULL;
if (cOrigin != NULL && *cOrigin != '/') // transform the origin URI into a path or a file name.
{
if (strncmp (cOrigin, "application://", 14) == 0) // Ubuntu >= 11.04: it's now an "app" URI
cFilePath = g_strdup (cOrigin + 14); // in this case we don't have the actual path of the .desktop, but that doesn't matter.
else
cFilePath = g_filename_from_uri (cOrigin, NULL, NULL);
}
else // no origin or already a path.
cFilePath = g_strdup (cOrigin);
g_key_file_set_string (pKeyFile, "Desktop Entry", "Origin", cFilePath?cFilePath:"");
g_key_file_set_double (pKeyFile, "Desktop Entry", "Order", fOrder);
g_key_file_set_string (pKeyFile, "Desktop Entry", "Container", cDockName);
//\__________________ in the case of a script, set ourselves a valid name and command.
if (cFilePath != NULL && g_str_has_suffix (cFilePath, ".sh"))
{
gchar *cName = g_path_get_basename (cFilePath);
g_key_file_set_string (pKeyFile, "Desktop Entry", "Name", cName);
g_free (cName);
g_key_file_set_string (pKeyFile, "Desktop Entry", "Exec", cFilePath);
g_key_file_set_boolean (pKeyFile, "Desktop Entry", "Terminal", TRUE);
}
//\__________________ in the case of a custom launcher, set a command (the launcher would be invalid without).
if (cFilePath == NULL)
{
g_key_file_set_string (pKeyFile, "Desktop Entry", "Exec", _("Enter a command"));
g_key_file_set_string (pKeyFile, "Desktop Entry", "Name", _("New launcher"));
}
//\__________________ generate a unique and readable filename.
gchar *cBaseName = (cFilePath ?
*cFilePath == '/' ?
g_path_get_basename (cFilePath) :
g_strdup (cFilePath) :
g_path_get_basename (cTemplateFile));
if (! g_str_has_suffix (cBaseName, ".desktop")) // if we have a script (.sh file) => add '.desktop'
{
gchar *cTmpBaseName = g_strdup_printf ("%s.desktop", cBaseName);
g_free (cBaseName);
cBaseName = cTmpBaseName;
}
gchar *cNewDesktopFileName = cairo_dock_generate_unique_filename (cBaseName, g_cCurrentLaunchersPath);
g_free (cBaseName);
//\__________________ write the keys.
gchar *cNewDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, cNewDesktopFileName);
cairo_dock_write_keys_to_conf_file (pKeyFile, cNewDesktopFilePath);
g_free (cNewDesktopFilePath);
g_free (cFilePath);
g_key_file_free (pKeyFile);
return cNewDesktopFileName;
}
Icon *gldi_launcher_add_new (const gchar *cURI, CairoDock *pDock, double fOrder)
{
//\_________________ add a launcher in the current theme
const gchar *cDockName = gldi_dock_get_name (pDock);
if (fOrder == CAIRO_DOCK_LAST_ORDER) // the order is not defined -> place at the end
{
Icon *pLastIcon = cairo_dock_get_last_launcher (pDock->icons);
fOrder = (pLastIcon ? pLastIcon->fOrder + 1 : 1);
}
gchar *cNewDesktopFileName = gldi_launcher_add_conf_file (cURI, cDockName, fOrder);
g_return_val_if_fail (cNewDesktopFileName != NULL, NULL);
//\_________________ load the new icon
Icon *pNewIcon = gldi_user_icon_new (cNewDesktopFileName);
g_free (cNewDesktopFileName);
g_return_val_if_fail (pNewIcon, NULL);
gldi_icon_insert_in_container (pNewIcon, CAIRO_CONTAINER(pDock), CAIRO_DOCK_ANIMATE_ICON);
return pNewIcon;
}
cairo-dock-3.3.2/src/gldit/cairo-dock-packages.h 000664 001750 001750 00000026334 12223247550 022534 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_PACKAGES__
#define __CAIRO_DOCK_PACKAGES__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-manager.h"
G_BEGIN_DECLS
/**@file cairo-dock-packages.h This class provides a convenient way to deal with packages. A Package is a tarball (tar.gz) of a folder, located on a distant server, that can be installed locally.
* Packages are listed on the server in a file named "list.conf". It's a group-key file starting with "#!CD" on the first line; each package is described in its own group. Packages are stored on the server in a folder that has the same name, and contains the tarball, a "readme" file, and a "preview" file.
*
* The class offers a high level of abstraction that allows to manipulate packages without having to care their location, version, etc.
* It also provides convenient utility functions to download a file or make a request to a server.
*
* To get the list of available packages, use \ref cairo_dock_list_packages, or its asynchronous version \ref cairo_dock_list_packages_async.
* To access a package, use \ref cairo_dock_get_package_path.
*/
// manager
typedef struct _CairoConnectionParam CairoConnectionParam;
#ifndef _MANAGER_DEF_
extern CairoConnectionParam myConnectionParam;
extern GldiManager myConnectionMgr;
#endif
// params
struct _CairoConnectionParam {
gint iConnectionTimeout;
gint iConnectionMaxTime;
gchar *cConnectionProxy;
gint iConnectionPort;
gchar *cConnectionUser;
gchar *cConnectionPasswd;
gboolean bForceIPv4;
};
// signals
typedef enum {
NOTIFICATION_CONNECTION_UP = NB_NOTIFICATIONS_OBJECT, // not yet implemented
NB_NOTIFICATIONS_CONNECTION
} CairoConnectionNotifications;
/// Types of packagess.
typedef enum {
/// package installed as root on the machine (in a sub-folder /usr).
CAIRO_DOCK_LOCAL_PACKAGE=0,
/// package located in the user's home
CAIRO_DOCK_USER_PACKAGE,
/// package present on the server
CAIRO_DOCK_DISTANT_PACKAGE,
/// package newly present on the server (for less than 1 month)
CAIRO_DOCK_NEW_PACKAGE,
/// package present locally but with a more recent version on the server, or distant package that has been updated in the past month.
CAIRO_DOCK_UPDATED_PACKAGE,
/// joker (the search path function will search locally first, and on the server then).
CAIRO_DOCK_ANY_PACKAGE,
CAIRO_DOCK_NB_TYPE_PACKAGE
} CairoDockPackageType;
/// Definition of a generic package.
struct _CairoDockPackage {
/// complete path of the package.
gchar *cPackagePath;
/// size in Mo
gdouble fSize;
/// author(s)
gchar *cAuthor;
/// name of the package
gchar *cDisplayedName;
/// type of package : installed, user, distant.
CairoDockPackageType iType;
/// rating of the package.
gint iRating;
/// sobriety/simplicity of the package.
gint iSobriety;
/// hint of the package, for instance "sound" or "battery" for a gauge, "internet" or "desktop" for a third-party applet.
gchar *cHint;
/// date of creation of the package.
gint iCreationDate;
/// date of latest changes in the package.
gint iLastModifDate;
};
/// Prototype of the function called when the list of packages is available. Use g_hash_table_ref if you want to keep the table outside of this function.
typedef void (* CairoDockGetPackagesFunc ) (GHashTable *pPackagesTable, gpointer data);
gchar *cairo_dock_uncompress_file (const gchar *cArchivePath, const gchar *cExtractTo, const gchar *cRealArchiveName);
/** Download a distant file into a given location.
*@param cURL adress of the file.
*@param cLocalPath a local path where to store the file.
*@return TRUE on success, else FALSE..
*/
gboolean cairo_dock_download_file (const gchar *cURL, const gchar *cLocalPath);
/** Download a distant file as a temporary file.
*@param cURL adress of the file.
*@return the local path of the file on success, else NULL. Free the string after using it.
*/
gchar *cairo_dock_download_file_in_tmp (const gchar *cURL);
/** Download an archive and extract it into a given folder.
*@param cURL adress of the file.
*@param cExtractTo folder where to extract the archive (the archive is deleted then).
*@return the local path of the file on success, else NULL. Free the string after using it.
*/
gchar *cairo_dock_download_archive (const gchar *cURL, const gchar *cExtractTo);
/** Asynchronously download a distant file into a given location. This function is non-blocking, you'll get a CairoTask that you can discard at any time, and you'll get the path of the downloaded file as the first argument of the callback (the second being the data you passed to this function).
*@param cURL adress of the file.
*@param cLocalPath a local path where to store the file, or NULL for a temporary file.
*@param pCallback function called when the download is finished. It takes the path of the downloaded file (it belongs to the task so don't free it) and the data you've set here.
*@param data data to be passed to the callback.
*@return the Task that is doing the job. Keep it and use \ref cairo_dock_discard_task whenever you want to discard the download (for instance if the user cancels it), or \ref cairo_dock_free_task inside your callback.
*/
CairoDockTask *cairo_dock_download_file_async (const gchar *cURL, const gchar *cLocalPath, GFunc pCallback, gpointer data);
/** Retrieve the response of a POST request to a server.
*@param cURL the URL request
*@param bGetOutputHeaders whether to retrieve the page's header.
*@param erreur an error.
*@param cFirstProperty first property of the POST data.
*@param ... tuples of property and data to insert in POST data; the POST data will be formed with a=urlencode(b)&c=urlencode(d)&... End it with NULL.
*@return the data (NULL if failed). It's an array of chars, possibly containing nul chars. Free it after using.
*/
gchar *cairo_dock_get_url_data_with_post (const gchar *cURL, gboolean bGetOutputHeaders, GError **erreur, const gchar *cFirstProperty, ...);
/** Retrieve the data of a distant URL.
*@param cURL distant adress to get data from.
*@param erreur an error.
*@return the data (NULL if failed). It's an array of chars, possibly containing nul chars. Free it after using.
*/
#define cairo_dock_get_url_data(cURL, erreur) cairo_dock_get_url_data_with_post (cURL, FALSE, erreur, NULL)
/** Asynchronously retrieve the content of a distant URL. This function is non-blocking, you'll get a CairoTask that you can discard at any time, and you'll get the content of the downloaded file as the first argument of the callback (the second being the data you passed to this function).
*@param cURL distant adress to get data from.
*@param pCallback function called when the download is finished. It takes the content of the downloaded file (it belongs to the task so don't free it) and the data you've set here.
*@param data data to be passed to the callback.
*@return the Task that is doing the job. Keep it and use \ref cairo_dock_discard_task whenever you want to discard the download (for instance if the user cancels it), or \ref cairo_dock_free_task inside your callback.
*/
CairoDockTask *cairo_dock_get_url_data_async (const gchar *cURL, GFunc pCallback, gpointer data);
////////////////
// THEMES API //
////////////////
/** Destroy a package and free all its allocated memory.
*@param pPackage the package.
*/
void cairo_dock_free_package (CairoDockPackage *pPackage);
GHashTable *cairo_dock_list_local_packages (const gchar *cPackagesDir, GHashTable *hProvidedTable, gboolean bUpdatePackageValidity, GError **erreur);
GHashTable *cairo_dock_list_net_packages (const gchar *cServerAdress, const gchar *cDirectory, const gchar *cListFileName, GHashTable *hProvidedTable, GError **erreur);
/** Get a list of packages from differente sources.
*@param cSharePackagesDir path of a local folder containg packages or NULL.
*@param cUserPackagesDir path of a user folder containg packages or NULL.
*@param cDistantPackagesDir path of a distant folder containg packages or NULL.
*@param pTable a table of packages previously retrieved, or NULL.
*@return a hash table of (name, #_CairoDockPackage). Free it with g_hash_table_destroy when you're done with it.
*/
GHashTable *cairo_dock_list_packages (const gchar *cSharePackagesDir, const gchar *cUserPackagesDir, const gchar *cDistantPackagesDir, GHashTable *pTable);
/** Asynchronously get a list of packages from differente sources. This function is non-blocking, you'll get a CairoTask that you can discard at any time, and you'll get a hash-table of the packages as the first argument of the callback (the second being the data you passed to this function).
*@param cSharePackagesDir path of a local folder containg packages or NULL.
*@param cUserPackagesDir path of a user folder containg packages or NULL.
*@param cDistantPackagesDir path of a distant folder containg packages or NULL.
*@param pCallback function called when the listing is finished. It takes the hash-table of the found packages (it belongs to the task so don't free it) and the data you've set here.
*@param data data to be passed to the callback.
*@param pTable a table of packages previously retrieved, or NULL.
*@return the Task that is doing the job. Keep it and use \ref cairo_dock_discard_task whenever you want to discard the download (for instance if the user cancels it), or \ref cairo_dock_free_task inside your callback.
*/
CairoDockTask *cairo_dock_list_packages_async (const gchar *cSharePackagesDir, const gchar *cUserPackagesDir, const gchar *cDistantPackagesDir, CairoDockGetPackagesFunc pCallback, gpointer data, GHashTable *pTable);
/** Look for a package with a given name into differente sources. If the package is found on the server and is not present on the disk, or is not up to date, then it is downloaded and the local path is returned.
*@param cPackageName name of the package.
*@param cSharePackagesDir path of a local folder containing packages or NULL.
*@param cUserPackagesDir path of a user folder containing packages or NULL.
*@param cDistantPackagesDir path of a distant folder containg packages or NULL.
*@param iGivenType type of package, or CAIRO_DOCK_ANY_PACKAGE if any type of package should be considered.
*@return a newly allocated string containing the complete local path of the package. If the package is distant, it is downloaded and extracted into this folder.
*/
gchar *cairo_dock_get_package_path (const gchar *cPackageName, const gchar *cSharePackagesDir, const gchar *cUserPackagesDir, const gchar *cDistantPackagesDir, CairoDockPackageType iGivenType);
CairoDockPackageType cairo_dock_extract_package_type_from_name (const gchar *cPackageName);
void cairo_dock_set_packages_server (gchar *cPackageServerAdress);
void gldi_register_connection_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-manager.h 000664 001750 001750 00000010053 12223247550 022357 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __GLDI_MANAGER__
#define __GLDI_MANAGER__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-object.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-manager.h This class defines the Managers. A Manager is like an internal module: it has a classic module interface, manages a set of resources, and has its own configuration.
*
* Each manager is initialized at the beginning.
* When loading the current theme, get_config and load are called.
* When unloading the current theme, unload and reset_config are called.
* When reloading a part of the current theme, reset_config, get_config and load are called.
*/
#ifndef __MANAGER_DEF__
extern GldiObjectManager myManagerObjectMgr;
#endif
// signals
typedef enum {
NB_NOTIFICATIONS_MANAGER = NB_NOTIFICATIONS_OBJECT,
} GldiManagerNotifications;
typedef gpointer GldiManagerConfigPtr;
typedef gpointer GldiManagerDataPtr;
typedef void (*GldiManagerInitFunc) (void);
typedef void (*GldiManagerLoadFunc) (void);
typedef void (*GldiManagerUnloadFunc) (void);
typedef void (* GldiManagerReloadFunc) (GldiManagerConfigPtr pPrevConfig, GldiManagerConfigPtr pNewConfig);
typedef gboolean (* GldiManagerGetConfigFunc) (GKeyFile *pKeyFile, GldiManagerConfigPtr pConfig);
typedef void (* GldiManagerResetConfigFunc) (GldiManagerConfigPtr pConfig);
/// Definition of a Manager.
struct _GldiManager {
/// object
GldiObject object;
//\_____________ Visit card.
const gchar *cModuleName;
gint iSizeOfConfig;
gint iSizeOfData;
//\_____________ Interface.
/// function called once and for all at the init of the core.
GldiManagerInitFunc init;
/// function called when loading the current theme, after getting the config
GldiManagerLoadFunc load;
/// function called when unloading the current theme, before resetting the config.
GldiManagerUnloadFunc unload;
/// function called when reloading a part of the current theme.
GldiManagerReloadFunc reload;
/// function called when getting the config of the current theme, or a part of it.
GldiManagerGetConfigFunc get_config;
/// function called when resetting the current theme, or a part of it.
GldiManagerResetConfigFunc reset_config;
//\_____________ Instance.
GldiManagerConfigPtr pConfig;
GldiManagerDataPtr pData;
GList *pExternalModules;
gboolean bInitIsDone;
GldiManager *pDependence; // only 1 at the moment, can be a GSList if needed
};
#define GLDI_MANAGER(m) ((GldiManager*)(m))
/** Say if an object is a Manager.
*@param obj the object.
*@return TRUE if the object is a Manager.
*/
#define GLDI_OBJECT_IS_MANAGER(obj) gldi_object_is_manager_child (GLDI_OBJECT(obj), &myManagerObjectMgr)
// facility
/*void gldi_manager_reload_from_keyfile (GldiManager *pManager, GKeyFile *pKeyFile);
void gldi_manager_reload (GldiManager *pManager, const gchar *cConfFilePath); // expose pour Dbus.
*/
void gldi_manager_extend (GldiVisitCard *pVisitCard, const gchar *cManagerName);
// manager
GldiManager *gldi_manager_get (const gchar *cName);
void gldi_managers_init (void);
gboolean gldi_managers_get_config_from_key_file (GKeyFile *pKeyFile);
void gldi_managers_get_config (const gchar *cConfFilePath, const gchar *cVersion);
void gldi_managers_load (void);
void gldi_managers_unload (void);
void gldi_managers_foreach (GFunc callback, gpointer data);
void gldi_register_managers_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-core.h 000664 001750 001750 00000002201 12223247550 021671 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __GLDI_CORE__
#define __GLDI_CORE__
#include
#include "cairo-dock-struct.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-core.h This class instanciates the different core managers.
*/
typedef enum {
GLDI_DEFAULT,
GLDI_OPENGL,
GLDI_CAIRO,
} GldiRenderingMethod;
void gldi_init (GldiRenderingMethod iRendering);
void gldi_free_all (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-global-variables.h 000664 001750 001750 00000003467 12223247550 024166 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_GLOBAL_VARIABLES_H__
#define __CAIRO_DOCK_GLOBAL_VARIABLES_H__
#include "cairo-dock-struct.h"
#include "cairo-dock-file-manager.h" // pour g_iDesktopEnv
G_BEGIN_DECLS
/// Pointeur sur le dock principal.
extern CairoDock *g_pMainDock;
extern GldiContainer *g_pPrimaryContainer;
/// Chemin du fichier de conf de l'appli.
extern gchar *g_cConfFile;
/// Le chemin vers le repertoire racine.
extern gchar *g_cCairoDockDataDir;
extern gchar *g_cCurrentThemePath;
extern gchar *g_cCurrentLaunchersPath;
/// version
extern int g_iMajorVersion, g_iMinorVersion, g_iMicroVersion;
/// boite
extern CairoDockImageBuffer g_pBoxAboveBuffer;
extern CairoDockImageBuffer g_pBoxBelowBuffer;
/// icon bg
extern CairoDockImageBuffer g_pIconBackgroundBuffer;
/// config opengl
extern CairoDockGLConfig g_openglConfig;
/// Environnement de bureau detecte.
extern CairoDockDesktopEnv g_iDesktopEnv;
extern gboolean g_bEasterEggs;
extern gboolean g_bUseOpenGL;
extern GLuint g_pGradationTexture[2];
extern GldiModuleInstance *g_pCurrentModule;
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-windows-manager.h 000664 001750 001750 00000015213 12223247550 024052 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __GLDI_WINDOWS_MANAGER__
#define __GLDI_WINDOWS_MANAGER__
#include "cairo-dock-struct.h"
#include "cairo-dock-manager.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-windows-manager.h This class manages the windows actors and notifies for any change on them.
*/
// manager
typedef struct _GldiWindowsManager GldiWindowsManager;
#ifndef _MANAGER_DEF_
extern GldiObjectManager myWindowObjectMgr;
#endif
/// signals
typedef enum {
NOTIFICATION_WINDOW_CREATED = NB_NOTIFICATIONS_OBJECT,
NOTIFICATION_WINDOW_DESTROYED,
NOTIFICATION_WINDOW_NAME_CHANGED,
NOTIFICATION_WINDOW_ICON_CHANGED,
NOTIFICATION_WINDOW_ATTENTION_CHANGED,
NOTIFICATION_WINDOW_SIZE_POSITION_CHANGED,
NOTIFICATION_WINDOW_STATE_CHANGED,
NOTIFICATION_WINDOW_CLASS_CHANGED,
NOTIFICATION_WINDOW_Z_ORDER_CHANGED,
NOTIFICATION_WINDOW_ACTIVATED,
NOTIFICATION_WINDOW_DESKTOP_CHANGED,
NB_NOTIFICATIONS_WINDOWS
} GldiWindowNotifications;
// data
/// Definition of the Windows Manager backend.
struct _GldiWindowManagerBackend {
GldiWindowActor* (*get_active_window) (void);
void (*move_to_nth_desktop) (GldiWindowActor *actor, int iNumDesktop, int iDeltaViewportX, int iDeltaViewportY);
void (*show) (GldiWindowActor *actor);
void (*close) (GldiWindowActor *actor);
void (*kill) (GldiWindowActor *actor);
void (*minimize) (GldiWindowActor *actor);
void (*lower) (GldiWindowActor *actor);
void (*maximize) (GldiWindowActor *actor, gboolean bMaximize);
void (*set_fullscreen) (GldiWindowActor *actor, gboolean bFullScreen);
void (*set_above) (GldiWindowActor *actor, gboolean bAbove);
void (*set_minimize_position) (GldiWindowActor *actor, int x, int y);
void (*set_thumbnail_area) (GldiWindowActor *actor, int x, int y, int w, int h);
void (*set_window_border) (GldiWindowActor *actor, gboolean bWithBorder);
cairo_surface_t* (*get_icon_surface) (GldiWindowActor *actor, int iWidth, int iHeight);
cairo_surface_t* (*get_thumbnail_surface) (GldiWindowActor *actor, int iWidth, int iHeight);
GLuint (*get_texture) (GldiWindowActor *actor);
GldiWindowActor* (*get_transient_for) (GldiWindowActor *actor);
void (*is_above_or_below) (GldiWindowActor *actor, gboolean *bIsAbove, gboolean *bIsBelow);
gboolean (*is_sticky) (GldiWindowActor *actor);
void (*set_sticky) (GldiWindowActor *actor, gboolean bSticky);
void (*can_minimize_maximize_close) (GldiWindowActor *actor, gboolean *bCanMinimize, gboolean *bCanMaximize, gboolean *bCanClose);
guint (*get_id) (GldiWindowActor *actor);
GldiWindowActor* (*pick_window) (void); // grab the mouse, wait for a click, then get the clicked window and returns its actor
} ;
/// Definition of a window actor.
struct _GldiWindowActor {
GldiObject object;
gboolean bDisplayed; /// not used yet...
gboolean bIsHidden;
gboolean bIsFullScreen;
gboolean bIsMaximized;
gboolean bDemandsAttention;
GtkAllocation windowGeometry;
gint iNumDesktop; // can be -1
gint iViewPortX, iViewPortY;
gint iStackOrder;
gchar *cClass;
gchar *cWmClass;
gchar *cName;
gchar *cLastAttentionDemand;
gint iAge; // age of the window (a mere growing integer).
gboolean bIsTransientFor; // TRUE if the window is transient (for a parent window).
};
/** Register a Window Manager backend. NULL functions are simply ignored.
*@param pBackend a Window Manager backend
*/
void gldi_windows_manager_register_backend (GldiWindowManagerBackend *pBackend);
/** Run a function on each window actor.
*@param bOrderedByZ TRUE to sort by z-order, FALSE to sort by age
*@param callback the callback
*@param data user data
*/
void gldi_windows_foreach (gboolean bOrderedByZ, GFunc callback, gpointer data);
/** Run a function on each window actor.
*@param callback the callback (takes the actor and the data, returns TRUE to stop)
*@param data user data
*@return the found actor, or NULL
*/
GldiWindowActor *gldi_windows_find (gboolean (*callback) (GldiWindowActor*, gpointer), gpointer data);
/** Get the current active window actor.
*@return the actor, or NULL if no window is currently active
*/
GldiWindowActor* gldi_windows_get_active (void);
void gldi_window_move_to_desktop (GldiWindowActor *actor, int iNumDesktop, int iNumViewportX, int iNumViewportY);
void gldi_window_show (GldiWindowActor *actor);
void gldi_window_close (GldiWindowActor *actor);
void gldi_window_kill (GldiWindowActor *actor);
void gldi_window_minimize (GldiWindowActor *actor);
void gldi_window_lower (GldiWindowActor *actor);
void gldi_window_maximize (GldiWindowActor *actor, gboolean bMaximize);
void gldi_window_set_fullscreen (GldiWindowActor *actor, gboolean bFullScreen);
void gldi_window_set_above (GldiWindowActor *actor, gboolean bAbove);
void gldi_window_set_minimize_position (GldiWindowActor *actor, int x, int y);
void gldi_window_set_thumbnail_area (GldiWindowActor *actor, int x, int y, int w, int h);
void gldi_window_set_border (GldiWindowActor *actor, gboolean bWithBorder);
cairo_surface_t* gldi_window_get_icon_surface (GldiWindowActor *actor, int iWidth, int iHeight);
cairo_surface_t* gldi_window_get_thumbnail_surface (GldiWindowActor *actor, int iWidth, int iHeight);
GLuint gldi_window_get_texture (GldiWindowActor *actor);
GldiWindowActor* gldi_window_get_transient_for (GldiWindowActor *actor);
void gldi_window_is_above_or_below (GldiWindowActor *actor, gboolean *bIsAbove, gboolean *bIsBelow);
gboolean gldi_window_is_sticky (GldiWindowActor *actor);
void gldi_window_set_sticky (GldiWindowActor *actor, gboolean bSticky);
void gldi_window_can_minimize_maximize_close (GldiWindowActor *actor, gboolean *bCanMinimize, gboolean *bCanMaximize, gboolean *bCanClose);
gboolean gldi_window_is_on_current_desktop (GldiWindowActor *actor);
gboolean gldi_window_is_on_desktop (GldiWindowActor *pAppli, int iNumDesktop, int iNumViewportX, int iNumViewportY);
void gldi_window_move_to_current_desktop (GldiWindowActor *pAppli);
guint gldi_window_get_id (GldiWindowActor *pAppli);
GldiWindowActor *gldi_window_pick (void);
void gldi_register_windows_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-data-renderer-manager.h 000664 001750 001750 00000006122 12223247550 025074 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_DATA_RENDERER_MANAGER__
#define __CAIRO_DOCK_DATA_RENDERER_MANAGER__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-manager.h"
#include "cairo-dock-data-renderer.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-data-renderer-manager.h This class manages the list of available Data Renderers and their global ressources.
*/
// manager
#ifndef _MANAGER_DEF_
extern GldiManager myDataRenderersMgr;
extern GldiObjectManager myDataRendererObjectMgr;
#endif
// no params
// signals
typedef enum {
NB_NOTIFICATIONS_DATA_RENDERERS = NB_NOTIFICATIONS_OBJECT
} CairoDataRendererNotifications;
struct _CairoDockDataRendererRecord {
CairoDataRendererInterface interface;
gulong iStructSize;
const gchar *cThemeDirName;
const gchar *cDistantThemeDirName;
const gchar *cDefaultTheme;
/// whether the data-renderer draws on an overlay rather than directly on the icon.
gboolean bUseOverlay;
};
/** Say if an object is a DataRenderer.
*@param obj the object.
*@return TRUE if the object is a DataRenderer.
*/
#define GLDI_OBJECT_IS_DATA_RENDERER(obj) gldi_object_is_manager_child (GLDI_OBJECT(obj), &myDataRendererObjectMgr)
/** Get the default GLX font for Data Renderer. It can render strings of ASCII characters fastly. Don't destroy it.
*@return the default GLX font*/
CairoDockGLFont *cairo_dock_get_default_data_renderer_font (void);
void cairo_dock_unload_default_data_renderer_font (void); // merge with unload
CairoDockDataRendererRecord *cairo_dock_get_data_renderer_record (const gchar *cRendererName); // peu utile.
void cairo_dock_register_data_renderer (const gchar *cRendererName, CairoDockDataRendererRecord *pRecord);
void cairo_dock_remove_data_renderer (const gchar *cRendererName);
CairoDataRenderer *cairo_dock_new_data_renderer (const gchar *cRendererName);
GHashTable *cairo_dock_list_available_themes_for_data_renderer (const gchar *cRendererName);
gchar *cairo_dock_get_data_renderer_theme_path (const gchar *cRendererName, const gchar *cThemeName, CairoDockPackageType iType);
gchar *cairo_dock_get_package_path_for_data_renderer (const gchar *cRendererName, const gchar *cAppletConfFilePath, GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, const gchar *cDefaultThemeName);
void gldi_register_data_renderers_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/gldi-config.h.in 000664 001750 001750 00000001515 12223247550 021526 0 ustar 00mbaerts mbaerts 000000 000000
#ifndef __GLDI_INTERNAL_CONFIG_H__
#define __GLDI_INTERNAL_CONFIG_H__
/* Defined if we can use X. */
#cmakedefine HAVE_X11 @HAVE_X11@
/* Defined if we can use GLX. */
#cmakedefine HAVE_GLX @HAVE_GLX@
/* Defined if we can use X Extensions. */
#cmakedefine HAVE_XEXTEND @HAVE_XEXTEND@
/* Defined if we can use Xinerama. */
#cmakedefine HAVE_XINERAMA @HAVE_XINERAMA@
/* Defined if we can crypt passwords. */
#cmakedefine HAVE_LIBCRYPT @HAVE_LIBCRYPT@
/* Define to 1 if you have the `dl' library (-ldl). */
#cmakedefine HAVE_LIBDL @HAVE_LIBDL@
/* Define to 1 if you have the header file. */
#cmakedefine HAVE_DLFCN_H @HAVE_DLFCN_H@
#define GLDI_GETTEXT_PACKAGE "@GLDI_GETTEXT_PACKAGE@"
#define GLDI_VERSION "@VERSION@"
#define GLDI_SHARE_DATA_DIR "@GLDI_SHARE_DATA_DIR@"
#cmakedefine AVOID_PATENT_CRAP @AVOID_PATENT_CRAP@
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-module-manager.c 000664 001750 001750 00000052162 12223247550 023644 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include "gldi-config.h"
#include "gldi-module-config.h"
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-themes-manager.h" // cairo_dock_add_conf_file
#include "cairo-dock-file-manager.h" // cairo_dock_copy_file
#include "cairo-dock-log.h"
#include "cairo-dock-applet-manager.h"
#include "cairo-dock-desktop-manager.h" // gldi_desktop_get_width
#include "cairo-dock-desklet-manager.h"
#include "cairo-dock-animations.h"
#include "cairo-dock-config.h"
#include "cairo-dock-module-instance-manager.h"
#define _MANAGER_DEF_
#include "cairo-dock-module-manager.h"
// public (manager, config, data)
GldiModulesParam myModulesParam;
GldiManager myModulesMgr;
GldiObjectManager myModuleObjectMgr;
GldiModuleInstance *g_pCurrentModule = NULL; // only used to trace a possible crash in one of the modules.
// dependancies
extern gchar *g_cConfFile;
extern gchar *g_cCurrentThemePath;
extern int g_iMajorVersion, g_iMinorVersion, g_iMicroVersion;
extern gboolean g_bEasterEggs;
// private
static GHashTable *s_hModuleTable = NULL;
static GList *s_AutoLoadedModules = NULL;
static guint s_iSidWriteModules = 0;
///////////////
/// MANAGER ///
///////////////
GldiModule *gldi_module_get (const gchar *cModuleName)
{
g_return_val_if_fail (cModuleName != NULL, NULL);
return g_hash_table_lookup (s_hModuleTable, cModuleName);
}
GldiModule *gldi_module_foreach (GHRFunc pCallback, gpointer user_data)
{
return g_hash_table_find (s_hModuleTable, (GHRFunc) pCallback, user_data);
}
static int _sort_module_by_alphabetical_order (GldiModule *m1, GldiModule *m2)
{
if (!m1 || !m1->pVisitCard || !m1->pVisitCard->cTitle)
return 1;
if (!m2 || !m2->pVisitCard || !m2->pVisitCard->cTitle)
return -1;
return g_ascii_strncasecmp (m1->pVisitCard->cTitle, m2->pVisitCard->cTitle, -1);
}
GldiModule *gldi_module_foreach_in_alphabetical_order (GCompareFunc pCallback, gpointer user_data)
{
GList *pModuleList = g_hash_table_get_values (s_hModuleTable);
pModuleList = g_list_sort (pModuleList, (GCompareFunc) _sort_module_by_alphabetical_order);
GldiModule *pModule = (GldiModule *)g_list_find_custom (pModuleList, user_data, pCallback);
g_list_free (pModuleList);
return pModule;
}
int gldi_module_get_nb (void)
{
return g_hash_table_size (s_hModuleTable);
}
static void _write_one_module_name (const gchar *cModuleName, GldiModule *pModule, GString *pString)
{
if (pModule->pInstancesList != NULL && ! gldi_module_is_auto_loaded (pModule))
{
g_string_append_printf (pString, "%s;", cModuleName);
}
}
static gchar *_gldi_module_list_active (void)
{
GString *pString = g_string_new ("");
g_hash_table_foreach (s_hModuleTable, (GHFunc) _write_one_module_name, pString);
if (pString->len > 0)
pString->str[pString->len-1] = '\0';
gchar *cModuleNames = pString->str;
g_string_free (pString, FALSE);
return cModuleNames;
}
static gboolean _write_modules_idle (G_GNUC_UNUSED gpointer data)
{
gchar *cModuleNames = _gldi_module_list_active ();
cd_debug ("%s", cModuleNames);
cairo_dock_update_conf_file (g_cConfFile,
G_TYPE_STRING, "System", "modules", cModuleNames,
G_TYPE_INVALID);
g_free (cModuleNames);
s_iSidWriteModules = 0;
return FALSE;
}
void gldi_modules_write_active (void)
{
if (s_iSidWriteModules == 0)
s_iSidWriteModules = g_idle_add (_write_modules_idle, NULL);
}
/////////////////////
/// MODULE LOADER ///
/////////////////////
GldiModule *gldi_module_new (GldiVisitCard *pVisitCard, GldiModuleInterface *pInterface)
{
g_return_val_if_fail (pVisitCard != NULL && pVisitCard->cModuleName != NULL, NULL);
GldiModuleAttr attr = {pVisitCard, pInterface};
return (GldiModule*)gldi_object_new (&myModuleObjectMgr, &attr);
}
GldiModule *gldi_module_new_from_so_file (const gchar *cSoFilePath)
{
g_return_val_if_fail (cSoFilePath != NULL, NULL);
GldiVisitCard *pVisitCard = NULL;
GldiModuleInterface *pInterface = NULL;
// open the .so file
///GModule *module = g_module_open (pGldiModule->cSoFilePath, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
gpointer handle = dlopen (cSoFilePath, RTLD_LAZY | RTLD_LOCAL);
if (! handle)
{
cd_warning ("while opening module '%s' : (%s)", cSoFilePath, dlerror());
return NULL;
}
// find the pre-init entry point
GldiModulePreInit function_pre_init = NULL;
/**bSymbolFound = g_module_symbol (module, "pre_init", (gpointer) &function_pre_init);
if (bSymbolFound && function_pre_init != NULL)*/
function_pre_init = dlsym (handle, "pre_init");
if (function_pre_init == NULL)
{
cd_warning ("this module ('%s') does not have the common entry point 'pre_init', it may be broken or icompatible with cairo-dock", cSoFilePath);
goto discard;
}
// run the pre-init entry point to get the necessary info about the module
pVisitCard = g_new0 (GldiVisitCard, 1);
pInterface = g_new0 (GldiModuleInterface, 1);
gboolean bModuleLoaded = function_pre_init (pVisitCard, pInterface);
if (! bModuleLoaded)
{
cd_debug ("module '%s' has not been loaded", cSoFilePath); // can happen to xxx-integration or icon-effect for instance.
goto discard;
}
// check module compatibility
if (! g_bEasterEggs &&
(pVisitCard->iMajorVersionNeeded > g_iMajorVersion
|| (pVisitCard->iMajorVersionNeeded == g_iMajorVersion && pVisitCard->iMinorVersionNeeded > g_iMinorVersion)
|| (pVisitCard->iMajorVersionNeeded == g_iMajorVersion && pVisitCard->iMinorVersionNeeded == g_iMinorVersion && pVisitCard->iMicroVersionNeeded > g_iMicroVersion)))
{
cd_warning ("this module ('%s') needs at least Cairo-Dock v%d.%d.%d, but Cairo-Dock is in v%d.%d.%d (%s)\n It will be ignored", cSoFilePath, pVisitCard->iMajorVersionNeeded, pVisitCard->iMinorVersionNeeded, pVisitCard->iMicroVersionNeeded, g_iMajorVersion, g_iMinorVersion, g_iMicroVersion, GLDI_VERSION);
goto discard;
}
if (! g_bEasterEggs
&& pVisitCard->cDockVersionOnCompilation != NULL && strcmp (pVisitCard->cDockVersionOnCompilation, GLDI_VERSION) != 0) // separation des versions en easter egg.
{
cd_warning ("this module ('%s') was compiled with Cairo-Dock v%s, but Cairo-Dock is in v%s\n It will be ignored", cSoFilePath, pVisitCard->cDockVersionOnCompilation, GLDI_VERSION);
goto discard;
}
// create a new module with these info
GldiModule *pModule = gldi_module_new (pVisitCard, pInterface); // takes ownership of pVisitCard and pInterface
if (pModule)
pModule->handle = handle;
return pModule;
discard:
///g_module_close (pModule);
dlclose (handle);
cairo_dock_free_visit_card (pVisitCard);
g_free (pInterface);
return NULL;
}
void gldi_modules_new_from_directory (const gchar *cModuleDirPath, GError **erreur)
{
if (cModuleDirPath == NULL)
cModuleDirPath = GLDI_MODULES_DIR;
cd_message ("%s (%s)", __func__, cModuleDirPath);
GError *tmp_erreur = NULL;
GDir *dir = g_dir_open (cModuleDirPath, 0, &tmp_erreur);
if (tmp_erreur != NULL)
{
g_propagate_error (erreur, tmp_erreur);
return ;
}
const gchar *cFileName;
GString *sFilePath = g_string_new ("");
do
{
cFileName = g_dir_read_name (dir);
if (cFileName == NULL)
break ;
if (g_str_has_suffix (cFileName, ".so"))
{
g_string_printf (sFilePath, "%s/%s", cModuleDirPath, cFileName);
(void)gldi_module_new_from_so_file (sFilePath->str);
}
}
while (1);
g_string_free (sFilePath, TRUE);
g_dir_close (dir);
}
gchar *gldi_module_get_config_dir (GldiModule *pModule)
{
GldiVisitCard *pVisitCard = pModule->pVisitCard;
if (pVisitCard->cConfFileName == NULL)
return NULL;
gchar *cUserDataDirPath = g_strdup_printf ("%s/plug-ins/%s", g_cCurrentThemePath, pVisitCard->cUserDataDir);
if (! g_file_test (cUserDataDirPath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
{
cd_message ("directory %s doesn't exist, it will be added.", cUserDataDirPath);
gchar *command = g_strdup_printf ("mkdir -p \"%s\"", cUserDataDirPath);
int r = system (command);
g_free (command);
if (r != 0)
{
cd_warning ("couldn't create a directory for applet '%s' in '%s/plug-ins'\n check writing permissions", pVisitCard->cModuleName, g_cCurrentThemePath);
g_free (cUserDataDirPath);
g_free (pModule->cConfFilePath);
pModule->cConfFilePath = NULL;
return NULL;
}
}
return cUserDataDirPath;
}
void cairo_dock_free_visit_card (GldiVisitCard *pVisitCard)
{
g_free (pVisitCard); // toutes les chaines sont statiques.
}
/////////////////////////
/// MODULES HIGH LEVEL///
/////////////////////////
void gldi_module_activate (GldiModule *module)
{
g_return_if_fail (module != NULL && module->pVisitCard != NULL);
cd_debug ("%s (%s)", __func__, module->pVisitCard->cModuleName);
if (module->pInstancesList != NULL)
{
cd_warning ("Module %s already active", module->pVisitCard->cModuleName);
return ;
}
if (module->pVisitCard->cConfFileName != NULL) // the module has a conf file -> create an instance for each of them.
{
// check that the module's config dir exists or create it.
gchar *cUserDataDirPath = gldi_module_get_config_dir (module);
if (cUserDataDirPath == NULL)
{
cd_warning ("Unable to open the config folder of module %s\nCheck permissions", module->pVisitCard->cModuleName);
return;
}
// look for conf files inside this folder, and create an instance for each of them.
int n = 0;
if (module->pVisitCard->bMultiInstance) // possibly several conf files.
{
// open it
GError *tmp_erreur = NULL;
GDir *dir = g_dir_open (cUserDataDirPath, 0, &tmp_erreur);
if (tmp_erreur != NULL)
{
cd_warning ("couldn't open folder %s (%s)", cUserDataDirPath, tmp_erreur->message);
g_error_free (tmp_erreur);
g_free (cUserDataDirPath);
return ;
}
// for each conf file inside, instanciate the module with it.
const gchar *cFileName;
gchar *cInstanceFilePath;
while ((cFileName = g_dir_read_name (dir)) != NULL)
{
gchar *str = strstr (cFileName, ".conf");
if (!str)
continue;
if (*(str+5) != '-' && *(str+5) != '\0') // xxx.conf or xxx.conf-i
continue;
cInstanceFilePath = g_strdup_printf ("%s/%s", cUserDataDirPath, cFileName);
gldi_module_instance_new (module, cInstanceFilePath); // takes ownership of 'cInstanceFilePath'.
n ++;
}
g_dir_close (dir);
}
else // only 1 conf file possible.
{
gchar *cConfFilePath = g_strdup_printf ("%s/%s", cUserDataDirPath, module->pVisitCard->cConfFileName);
if (g_file_test (cConfFilePath, G_FILE_TEST_EXISTS))
{
gldi_module_instance_new (module, cConfFilePath);
n = 1;
}
else
{
g_free (cConfFilePath);
}
}
// if no conf file was present, copy the default one and instanciate the module with it.
if (n == 0) // no conf file was present.
{
gchar *cConfFilePath = g_strdup_printf ("%s/%s", cUserDataDirPath, module->pVisitCard->cConfFileName);
gboolean r = cairo_dock_copy_file (module->cConfFilePath, cConfFilePath);
if (! r) // the copy failed.
{
cd_warning ("couldn't copy %s into %s; check permissions and file's existence", module->cConfFilePath, cUserDataDirPath);
g_free (cConfFilePath);
g_free (cUserDataDirPath);
return;
}
else
{
gldi_module_instance_new (module, cConfFilePath);
}
}
g_free (cUserDataDirPath);
}
else // the module has no conf file, just instanciate it once.
{
gldi_module_instance_new (module, NULL);
}
}
void gldi_module_deactivate (GldiModule *module) // stop all instances of a module
{
g_return_if_fail (module != NULL);
cd_debug ("%s (%s, %s)", __func__, module->pVisitCard->cModuleName, module->cConfFilePath);
GList *pInstances = module->pInstancesList;
module->pInstancesList = NULL; // set to NULL already so that notifications don't get fooled. This can probably be avoided...
g_list_foreach (pInstances, (GFunc)gldi_object_unref, NULL);
g_list_free (pInstances);
gldi_object_notify (module, NOTIFICATION_MODULE_ACTIVATED, module->pVisitCard->cModuleName, FALSE); // throw it since the list was NULL when the instances were destroyed
gldi_modules_write_active (); // same
}
void gldi_modules_activate_from_list (gchar **cActiveModuleList)
{
//\_______________ On active les modules auto-charges en premier.
gchar *cModuleName;
GldiModule *pModule;
GList *m;
for (m = s_AutoLoadedModules; m != NULL; m = m->next)
{
pModule = m->data;
if (pModule->pInstancesList == NULL) // not yet active
{
gldi_module_activate (pModule);
}
}
if (cActiveModuleList == NULL)
return ;
//\_______________ On active tous les autres.
int i;
for (i = 0; cActiveModuleList[i] != NULL; i ++)
{
cModuleName = cActiveModuleList[i];
pModule = g_hash_table_lookup (s_hModuleTable, cModuleName);
if (pModule == NULL)
{
cd_debug ("No such module (%s)", cModuleName);
continue ;
}
if (pModule->pInstancesList == NULL) // not yet active
{
gldi_module_activate (pModule);
}
}
// don't write down
if (s_iSidWriteModules != 0)
{
g_source_remove (s_iSidWriteModules);
s_iSidWriteModules = 0;
}
}
static void _deactivate_one_module (G_GNUC_UNUSED gchar *cModuleName, GldiModule *pModule, G_GNUC_UNUSED gpointer data)
{
if (! gldi_module_is_auto_loaded (pModule))
gldi_module_deactivate (pModule);
}
void gldi_modules_deactivate_all (void)
{
// first deactivate applets
g_hash_table_foreach (s_hModuleTable, (GHFunc)_deactivate_one_module, NULL);
// then deactivate auto-loaded modules (that have been loaded first)
GldiModule *pModule;
GList *m;
for (m = s_AutoLoadedModules; m != NULL; m = m->next)
{
pModule = m->data;
gldi_module_deactivate (pModule);
}
// don't write down
if (s_iSidWriteModules != 0)
{
g_source_remove (s_iSidWriteModules);
s_iSidWriteModules = 0;
}
}
gchar *gldi_module_add_conf_file (GldiModule *pModule)
{
gchar *cUserDataDirPath = gldi_module_get_config_dir (pModule);
if (cUserDataDirPath == NULL)
return NULL;
// find a name that doesn't exist yet in the config dir.
gchar *cConfFilePath;
int i = 0;
do
{
if (i == 0)
cConfFilePath = g_strdup_printf ("%s/%s", cUserDataDirPath, pModule->pVisitCard->cConfFileName);
else
cConfFilePath = g_strdup_printf ("%s/%s-%d", cUserDataDirPath, pModule->pVisitCard->cConfFileName, i);
if (! g_file_test (cConfFilePath, G_FILE_TEST_EXISTS))
break;
g_free (cConfFilePath);
i ++;
} while (1);
// copy one of the instances conf file, or the default one.
GldiModuleInstance *pFirstInstance = NULL;
if (pModule->pInstancesList != NULL)
{
GList *last = g_list_last (pModule->pInstancesList);
pFirstInstance = last->data; // instances are prepended.
cairo_dock_add_conf_file (pFirstInstance->cConfFilePath, cConfFilePath);
if (pFirstInstance->pDesklet) // prevent desklets from overlapping.
{
int iX2, iX = pFirstInstance->pContainer->iWindowPositionX;
int iWidth = pFirstInstance->pContainer->iWidth;
if (iX + iWidth/2 <= gldi_desktop_get_width()/2) // desklet on the left, we place the new one on its right.
iX2 = iX + iWidth;
else // desklet on the right, we place the new one on its left.
iX2 = iX - iWidth;
int iRelativePositionX = (iX2 + iWidth/2 <= gldi_desktop_get_width()/2 ? iX2 : iX2 - gldi_desktop_get_width());
cairo_dock_update_conf_file (cConfFilePath,
G_TYPE_INT, "Desklet", "x position", iRelativePositionX,
G_TYPE_BOOLEAN, "Desklet", "locked", FALSE, // we'll probably want to move it
G_TYPE_BOOLEAN, "Desklet", "no input", FALSE,
G_TYPE_INVALID);
}
}
else // no instance yet, just copy the default conf file.
{
cairo_dock_add_conf_file (pModule->cConfFilePath, cConfFilePath);
}
g_free (cUserDataDirPath);
return cConfFilePath;
}
void gldi_module_add_instance (GldiModule *pModule)
{
// check that the module is already active
if (pModule->pInstancesList == NULL)
{
cd_warning ("This module has not been instanciated yet");
return ;
}
// check that the module can be multi-instanciated
if (! pModule->pVisitCard->bMultiInstance)
{
cd_warning ("This module can't be instanciated more than once");
return ;
}
// add a conf file
gchar *cInstanceFilePath = gldi_module_add_conf_file (pModule);
// create an instance for it
gldi_module_instance_new (pModule, cInstanceFilePath); // takes ownership of 'cInstanceFilePath'.
}
//////////////////
/// GET CONFIG ///
//////////////////
static gboolean get_config (GKeyFile *pKeyFile, GldiModulesParam *pModules)
{
gboolean bFlushConfFileNeeded = FALSE;
gsize length=0;
pModules->cActiveModuleList = cairo_dock_get_string_list_key_value (pKeyFile, "System", "modules", &bFlushConfFileNeeded, &length, NULL, "Applets", "modules_0");
return bFlushConfFileNeeded;
}
////////////////////
/// RESET CONFIG ///
////////////////////
static void reset_config (GldiModulesParam *pModules)
{
g_free (pModules->cActiveModuleList);
}
////////////
/// INIT ///
////////////
static void init (void)
{
s_hModuleTable = g_hash_table_new_full (g_str_hash,
g_str_equal,
NULL, // module name (points directly on the 'cModuleName' field of the module).
NULL); // module
}
///////////////
/// MANAGER ///
///////////////
static void init_object (GldiObject *obj, gpointer attr)
{
GldiModule *pModule = (GldiModule*)obj;
GldiModuleAttr *mattr = (GldiModuleAttr*)attr;
// check everything is ok
g_return_if_fail (mattr != NULL && mattr->pVisitCard != NULL && mattr->pVisitCard->cModuleName);
if (g_hash_table_lookup (s_hModuleTable, mattr->pVisitCard->cModuleName) != NULL)
{
cd_warning ("a module with the name '%s' is already registered", mattr->pVisitCard->cModuleName);
return;
}
// set params
pModule->pVisitCard = mattr->pVisitCard;
mattr->pVisitCard = NULL;
pModule->pInterface = mattr->pInterface;
mattr->pInterface = NULL;
if (pModule->cConfFilePath == NULL && pModule->pVisitCard->cConfFileName)
pModule->cConfFilePath = g_strdup_printf ("%s/%s", pModule->pVisitCard->cShareDataDir, pModule->pVisitCard->cConfFileName);
// register the module
g_hash_table_insert (s_hModuleTable, (gpointer)pModule->pVisitCard->cModuleName, pModule);
if (gldi_module_is_auto_loaded (pModule)) // a module that doesn't have an init/stop entry point, or that extends a manager; we'll activate it automatically (and before the others).
s_AutoLoadedModules = g_list_prepend (s_AutoLoadedModules, pModule);
// notify everybody
gldi_object_notify (&myModuleObjectMgr, NOTIFICATION_MODULE_REGISTERED, pModule->pVisitCard->cModuleName, TRUE);
}
static void reset_object (GldiObject *obj)
{
GldiModule *pModule = (GldiModule*)obj;
if (pModule->pVisitCard == NULL) // we didn't register it, pass
return;
// deactivate the module, if it was active
gldi_module_deactivate (pModule);
// unregister the module
g_hash_table_remove (s_hModuleTable, pModule->pVisitCard->cModuleName);
// notify everybody
gldi_object_notify (&myModuleObjectMgr, NOTIFICATION_MODULE_REGISTERED, pModule->pVisitCard->cModuleName, FALSE);
// free data
if (pModule->handle)
dlclose (pModule->handle);
g_free (pModule->pInterface);
cairo_dock_free_visit_card (pModule->pVisitCard);
}
static GKeyFile* reload_object (GldiObject *obj, gboolean bReloadConf, G_GNUC_UNUSED GKeyFile *pKeyFile)
{
GldiModule *pModule = (GldiModule*)obj;
GList *pElement;
GldiModuleInstance *pInstance;
for (pElement = pModule->pInstancesList; pElement != NULL; pElement = pElement->next)
{
pInstance = pElement->data;
gldi_object_reload (GLDI_OBJECT(pInstance), bReloadConf);
}
return NULL;
}
void gldi_register_modules_manager (void)
{
// Manager
memset (&myModulesMgr, 0, sizeof (GldiManager));
gldi_object_init (GLDI_OBJECT(&myModulesMgr), &myManagerObjectMgr, NULL);
myModulesMgr.cModuleName = "Modules";
// interface
myModulesMgr.init = init;
myModulesMgr.load = NULL;
myModulesMgr.unload = NULL;
myModulesMgr.reload = (GldiManagerReloadFunc)NULL;
myModulesMgr.get_config = (GldiManagerGetConfigFunc)get_config;
myModulesMgr.reset_config = (GldiManagerResetConfigFunc)reset_config;
// Config
memset (&myModulesParam, 0, sizeof (GldiModulesParam));
myModulesMgr.pConfig = (GldiManagerConfigPtr)&myModulesParam;
myModulesMgr.iSizeOfConfig = sizeof (GldiModulesParam);
// data
myModulesMgr.pData = (GldiManagerDataPtr)NULL;
myModulesMgr.iSizeOfData = 0;
// Object Manager
memset (&myModuleObjectMgr, 0, sizeof (GldiObjectManager));
myModuleObjectMgr.cName = "Module";
myModuleObjectMgr.iObjectSize = sizeof (GldiModule);
// interface
myModuleObjectMgr.init_object = init_object;
myModuleObjectMgr.reset_object = reset_object;
myModuleObjectMgr.reload_object = reload_object;
// signals
gldi_object_install_notifications (GLDI_OBJECT(&myModuleObjectMgr), NB_NOTIFICATIONS_MODULES);
}
cairo-dock-3.3.2/src/gldit/gtk3imagemenuitem.c 000664 001750 001750 00000111114 12223247550 022346 0 ustar 00mbaerts mbaerts 000000 000000 /* GTK - The GIMP Toolkit
* Copyright (C) 2001 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
// Imported from gtk+-3.8.4
// GtkImageMenuItem has been renamed to Gtk3ImageMenuItem (and all corresponding functions and macros) so that we can test it even when using GTK < 3.10.
//#include "config.h"
#include "gtk3imagemenuitem.h"
/*#include "gtkmenuitemprivate.h"
#include "gtkaccellabel.h"
#include "gtkstock.h"
#include "gtkiconfactory.h"
#include "gtkimage.h"
#include "gtkmenubar.h"
#include "gtkcontainer.h"
#include "gtkwindow.h"
#include "gtkactivatable.h"
#include "gtkintl.h"
#include "gtkprivate.h"*/
#include // strcmp
#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB // from gtkprivate.h
#define GTK_PARAM_WRITABLE G_PARAM_WRITABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB // from gtkprivate.h
#define P_(String) (String) // from gtkintl.h
/**
* SECTION:gtkimagemenuitem
* @Short_description: A menu item with an icon
* @Title: Gtk3ImageMenuItem
*
* A Gtk3ImageMenuItem is a menu item which has an icon next to the text label.
*
* Note that the user can disable display of menu icons, so make sure to still
* fill in the text label.
*/
struct _Gtk3ImageMenuItemPrivate
{
GtkWidget *image;
gchar *label;
guint use_stock : 1;
guint always_show_image : 1;
};
enum {
PROP_0,
PROP_IMAGE,
PROP_USE_STOCK,
PROP_ACCEL_GROUP,
PROP_ALWAYS_SHOW_IMAGE
};
static GtkActivatableIface *parent_activatable_iface;
static void gtk3_image_menu_item_destroy (GtkWidget *widget);
static void gtk3_image_menu_item_get_preferred_width (GtkWidget *widget,
gint *minimum,
gint *natural);
static void gtk3_image_menu_item_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural);
static void gtk3_image_menu_item_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural);
static void gtk3_image_menu_item_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk3_image_menu_item_map (GtkWidget *widget);
static void gtk3_image_menu_item_remove (GtkContainer *container,
GtkWidget *child);
static void gtk3_image_menu_item_toggle_size_request (GtkMenuItem *menu_item,
gint *requisition);
static void gtk3_image_menu_item_set_label (GtkMenuItem *menu_item,
const gchar *label);
static const gchar * gtk3_image_menu_item_get_label (GtkMenuItem *menu_item);
static void gtk3_image_menu_item_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data);
static void gtk3_image_menu_item_finalize (GObject *object);
static void gtk3_image_menu_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gtk3_image_menu_item_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gtk3_image_menu_item_recalculate (Gtk3ImageMenuItem *image_menu_item);
static void gtk3_image_menu_item_activatable_interface_init (GtkActivatableIface *iface);
static void gtk3_image_menu_item_update (GtkActivatable *activatable,
GtkAction *action,
const gchar *property_name);
static void gtk3_image_menu_item_sync_action_properties (GtkActivatable *activatable,
GtkAction *action);
G_DEFINE_TYPE_WITH_CODE (Gtk3ImageMenuItem, gtk3_image_menu_item, GTK_TYPE_MENU_ITEM,
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
gtk3_image_menu_item_activatable_interface_init))
static void
gtk3_image_menu_item_class_init (Gtk3ImageMenuItemClass *klass)
{
GObjectClass *gobject_class = (GObjectClass*) klass;
GtkWidgetClass *widget_class = (GtkWidgetClass*) klass;
GtkMenuItemClass *menu_item_class = (GtkMenuItemClass*) klass;
GtkContainerClass *container_class = (GtkContainerClass*) klass;
widget_class->destroy = gtk3_image_menu_item_destroy;
widget_class->screen_changed = NULL;
widget_class->get_preferred_width = gtk3_image_menu_item_get_preferred_width;
widget_class->get_preferred_height = gtk3_image_menu_item_get_preferred_height;
widget_class->get_preferred_height_for_width = gtk3_image_menu_item_get_preferred_height_for_width;
widget_class->size_allocate = gtk3_image_menu_item_size_allocate;
widget_class->map = gtk3_image_menu_item_map;
container_class->forall = gtk3_image_menu_item_forall;
container_class->remove = gtk3_image_menu_item_remove;
menu_item_class->toggle_size_request = gtk3_image_menu_item_toggle_size_request;
menu_item_class->set_label = gtk3_image_menu_item_set_label;
menu_item_class->get_label = gtk3_image_menu_item_get_label;
gobject_class->finalize = gtk3_image_menu_item_finalize;
gobject_class->set_property = gtk3_image_menu_item_set_property;
gobject_class->get_property = gtk3_image_menu_item_get_property;
g_object_class_install_property (gobject_class,
PROP_IMAGE,
g_param_spec_object ("image",
P_("Image widget"),
P_("Child widget to appear next to the menu text"),
GTK_TYPE_WIDGET,
GTK_PARAM_READWRITE));
/**
* Gtk3ImageMenuItem:use-stock:
*
* If %TRUE, the label set in the menuitem is used as a
* stock id to select the stock item for the item.
*
* Since: 2.16
*/
g_object_class_install_property (gobject_class,
PROP_USE_STOCK,
g_param_spec_boolean ("use-stock",
P_("Use stock"),
P_("Whether to use the label text to create a stock menu item"),
FALSE,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/**
* Gtk3ImageMenuItem:always-show-image:
*
* If %TRUE, the menu item will ignore the #GtkSettings:gtk-menu-images
* setting and always show the image, if available.
*
* Use this property if the menuitem would be useless or hard to use
* without the image.
*
* Since: 2.16
*/
g_object_class_install_property (gobject_class,
PROP_ALWAYS_SHOW_IMAGE,
g_param_spec_boolean ("always-show-image",
P_("Always show image"),
P_("Whether the image will always be shown"),
FALSE,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/**
* Gtk3ImageMenuItem:accel-group:
*
* The Accel Group to use for stock accelerator keys
*
* Since: 2.16
*/
g_object_class_install_property (gobject_class,
PROP_ACCEL_GROUP,
g_param_spec_object ("accel-group",
P_("Accel Group"),
P_("The Accel Group to use for stock accelerator keys"),
GTK_TYPE_ACCEL_GROUP,
GTK_PARAM_WRITABLE));
g_type_class_add_private (klass, sizeof (Gtk3ImageMenuItemPrivate));
}
static void
gtk3_image_menu_item_init (Gtk3ImageMenuItem *image_menu_item)
{
Gtk3ImageMenuItemPrivate *priv;
image_menu_item->priv = G_TYPE_INSTANCE_GET_PRIVATE (image_menu_item,
GTK3_TYPE_IMAGE_MENU_ITEM,
Gtk3ImageMenuItemPrivate);
priv = image_menu_item->priv;
priv->image = NULL;
priv->use_stock = FALSE;
priv->label = NULL;
}
static void
gtk3_image_menu_item_finalize (GObject *object)
{
Gtk3ImageMenuItemPrivate *priv = GTK3_IMAGE_MENU_ITEM (object)->priv;
g_free (priv->label);
priv->label = NULL;
G_OBJECT_CLASS (gtk3_image_menu_item_parent_class)->finalize (object);
}
static void
gtk3_image_menu_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (object);
switch (prop_id)
{
case PROP_IMAGE:
gtk3_image_menu_item_set_image (image_menu_item, (GtkWidget *) g_value_get_object (value));
break;
case PROP_USE_STOCK:
gtk3_image_menu_item_set_use_stock (image_menu_item, g_value_get_boolean (value));
break;
case PROP_ALWAYS_SHOW_IMAGE:
gtk3_image_menu_item_set_always_show_image (image_menu_item, g_value_get_boolean (value));
break;
case PROP_ACCEL_GROUP:
gtk3_image_menu_item_set_accel_group (image_menu_item, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk3_image_menu_item_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (object);
switch (prop_id)
{
case PROP_IMAGE:
g_value_set_object (value, gtk3_image_menu_item_get_image (image_menu_item));
break;
case PROP_USE_STOCK:
g_value_set_boolean (value, gtk3_image_menu_item_get_use_stock (image_menu_item));
break;
case PROP_ALWAYS_SHOW_IMAGE:
g_value_set_boolean (value, gtk3_image_menu_item_get_always_show_image (image_menu_item));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
#if (CAIRO_DOCK_FORCE_ICON_IN_MENUS == 1)
#define show_image(image_menu_item) TRUE
#else
static gboolean
show_image (Gtk3ImageMenuItem *image_menu_item)
{
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
return priv->always_show_image;
}
#endif
static void
gtk3_image_menu_item_map (GtkWidget *widget)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (widget);
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
GTK_WIDGET_CLASS (gtk3_image_menu_item_parent_class)->map (widget);
if (priv->image)
g_object_set (priv->image,
"visible", show_image (image_menu_item),
NULL);
}
static void
gtk3_image_menu_item_destroy (GtkWidget *widget)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (widget);
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
if (priv->image)
gtk_container_remove (GTK_CONTAINER (image_menu_item),
priv->image);
GTK_WIDGET_CLASS (gtk3_image_menu_item_parent_class)->destroy (widget);
}
static void
gtk3_image_menu_item_toggle_size_request (GtkMenuItem *menu_item,
gint *requisition)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (menu_item);
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
GtkPackDirection pack_dir;
GtkWidget *parent;
GtkWidget *widget = GTK_WIDGET (menu_item);
parent = gtk_widget_get_parent (widget);
if (GTK_IS_MENU_BAR (parent))
pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
else
pack_dir = GTK_PACK_DIRECTION_LTR;
*requisition = 0;
if (priv->image && gtk_widget_get_visible (priv->image))
{
GtkRequisition image_requisition;
guint toggle_spacing;
gtk_widget_get_preferred_size (priv->image, &image_requisition, NULL);
gtk_widget_style_get (GTK_WIDGET (menu_item),
"toggle-spacing", &toggle_spacing,
NULL);
if (pack_dir == GTK_PACK_DIRECTION_LTR || pack_dir == GTK_PACK_DIRECTION_RTL)
{
if (image_requisition.width > 0)
*requisition = image_requisition.width + toggle_spacing;
}
else
{
if (image_requisition.height > 0)
*requisition = image_requisition.height + toggle_spacing;
}
}
}
static void
gtk3_image_menu_item_recalculate (Gtk3ImageMenuItem *image_menu_item)
{
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
GtkStockItem stock_item;
GtkWidget *image;
const gchar *resolved_label = priv->label;
if (priv->use_stock && priv->label)
{
if (!priv->image)
{
image = gtk_image_new_from_stock (priv->label, GTK_ICON_SIZE_MENU);
gtk3_image_menu_item_set_image (image_menu_item, image);
}
if (gtk_stock_lookup (priv->label, &stock_item))
resolved_label = stock_item.label;
gtk_menu_item_set_use_underline (GTK_MENU_ITEM (image_menu_item), TRUE);
}
GTK_MENU_ITEM_CLASS
(gtk3_image_menu_item_parent_class)->set_label (GTK_MENU_ITEM (image_menu_item), resolved_label);
}
static void
gtk3_image_menu_item_set_label (GtkMenuItem *menu_item,
const gchar *label)
{
Gtk3ImageMenuItemPrivate *priv = GTK3_IMAGE_MENU_ITEM (menu_item)->priv;
if (priv->label != label)
{
g_free (priv->label);
priv->label = g_strdup (label);
gtk3_image_menu_item_recalculate (GTK3_IMAGE_MENU_ITEM (menu_item));
g_object_notify (G_OBJECT (menu_item), "label");
}
}
static const gchar *
gtk3_image_menu_item_get_label (GtkMenuItem *menu_item)
{
Gtk3ImageMenuItemPrivate *priv = GTK3_IMAGE_MENU_ITEM (menu_item)->priv;
return priv->label;
}
static void
gtk3_image_menu_item_get_preferred_width (GtkWidget *widget,
gint *minimum,
gint *natural)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (widget);
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
GtkPackDirection pack_dir;
GtkWidget *parent;
parent = gtk_widget_get_parent (widget);
if (GTK_IS_MENU_BAR (parent))
pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
else
pack_dir = GTK_PACK_DIRECTION_LTR;
GTK_WIDGET_CLASS (gtk3_image_menu_item_parent_class)->get_preferred_width (widget, minimum, natural);
if ((pack_dir == GTK_PACK_DIRECTION_TTB || pack_dir == GTK_PACK_DIRECTION_BTT) &&
priv->image &&
gtk_widget_get_visible (priv->image))
{
gint child_minimum, child_natural;
gtk_widget_get_preferred_width (priv->image, &child_minimum, &child_natural);
*minimum = MAX (*minimum, child_minimum);
*natural = MAX (*natural, child_natural);
}
}
static void
gtk3_image_menu_item_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (widget);
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
gint child_height = 0;
GtkPackDirection pack_dir;
GtkWidget *parent;
parent = gtk_widget_get_parent (widget);
if (GTK_IS_MENU_BAR (parent))
pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
else
pack_dir = GTK_PACK_DIRECTION_LTR;
if (priv->image && gtk_widget_get_visible (priv->image))
{
GtkRequisition child_requisition;
gtk_widget_get_preferred_size (priv->image, &child_requisition, NULL);
child_height = child_requisition.height;
}
GTK_WIDGET_CLASS (gtk3_image_menu_item_parent_class)->get_preferred_height (widget, minimum, natural);
if (pack_dir == GTK_PACK_DIRECTION_RTL || pack_dir == GTK_PACK_DIRECTION_LTR)
{
*minimum = MAX (*minimum, child_height);
*natural = MAX (*natural, child_height);
}
}
static void
gtk3_image_menu_item_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (widget);
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
gint child_height = 0;
GtkPackDirection pack_dir;
GtkWidget *parent;
parent = gtk_widget_get_parent (widget);
if (GTK_IS_MENU_BAR (parent))
pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
else
pack_dir = GTK_PACK_DIRECTION_LTR;
if (priv->image && gtk_widget_get_visible (priv->image))
{
GtkRequisition child_requisition;
gtk_widget_get_preferred_size (priv->image, &child_requisition, NULL);
child_height = child_requisition.height;
}
GTK_WIDGET_CLASS
(gtk3_image_menu_item_parent_class)->get_preferred_height_for_width (widget, width, minimum, natural);
if (pack_dir == GTK_PACK_DIRECTION_RTL || pack_dir == GTK_PACK_DIRECTION_LTR)
{
*minimum = MAX (*minimum, child_height);
*natural = MAX (*natural, child_height);
}
}
static void
gtk3_image_menu_item_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (widget);
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
GtkAllocation widget_allocation;
GtkPackDirection pack_dir;
GtkWidget *parent;
parent = gtk_widget_get_parent (widget);
if (GTK_IS_MENU_BAR (parent))
pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
else
pack_dir = GTK_PACK_DIRECTION_LTR;
GTK_WIDGET_CLASS (gtk3_image_menu_item_parent_class)->size_allocate (widget, allocation);
if (priv->image && gtk_widget_get_visible (priv->image))
{
gint x, y, offset;
GtkStyleContext *context;
GtkStateFlags state;
GtkBorder padding;
GtkRequisition child_requisition;
GtkAllocation child_allocation;
guint horizontal_padding, toggle_spacing;
gint toggle_size;
///toggle_size = GTK_MENU_ITEM (image_menu_item)->priv->toggle_size;
gtk_menu_item_toggle_size_request (GTK_MENU_ITEM (image_menu_item), &toggle_size);
gtk_widget_style_get (widget,
"horizontal-padding", &horizontal_padding,
"toggle-spacing", &toggle_spacing,
NULL);
/* Man this is lame hardcoding action, but I can't
* come up with a solution that's really better.
*/
gtk_widget_get_preferred_size (priv->image, &child_requisition, NULL);
gtk_widget_get_allocation (widget, &widget_allocation);
context = gtk_widget_get_style_context (widget);
state = gtk_widget_get_state_flags (widget);
gtk_style_context_get_padding (context, state, &padding);
offset = gtk_container_get_border_width (GTK_CONTAINER (image_menu_item));
if (pack_dir == GTK_PACK_DIRECTION_LTR ||
pack_dir == GTK_PACK_DIRECTION_RTL)
{
if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) ==
(pack_dir == GTK_PACK_DIRECTION_LTR))
x = offset + horizontal_padding + padding.left +
(toggle_size - toggle_spacing - child_requisition.width) / 2;
else
x = widget_allocation.width - offset - horizontal_padding - padding.right -
toggle_size + toggle_spacing +
(toggle_size - toggle_spacing - child_requisition.width) / 2;
y = (widget_allocation.height - child_requisition.height) / 2;
}
else
{
if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) ==
(pack_dir == GTK_PACK_DIRECTION_TTB))
y = offset + horizontal_padding + padding.top +
(toggle_size - toggle_spacing - child_requisition.height) / 2;
else
y = widget_allocation.height - offset - horizontal_padding - padding.bottom -
toggle_size + toggle_spacing +
(toggle_size - toggle_spacing - child_requisition.height) / 2;
x = (widget_allocation.width - child_requisition.width) / 2;
}
child_allocation.width = child_requisition.width;
child_allocation.height = child_requisition.height;
child_allocation.x = widget_allocation.x + MAX (x, 0);
child_allocation.y = widget_allocation.y + MAX (y, 0);
gtk_widget_size_allocate (priv->image, &child_allocation);
}
}
static void
gtk3_image_menu_item_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (container);
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
GTK_CONTAINER_CLASS (gtk3_image_menu_item_parent_class)->forall (container,
include_internals,
callback,
callback_data);
if (include_internals && priv->image)
(* callback) (priv->image, callback_data);
}
static void
gtk3_image_menu_item_activatable_interface_init (GtkActivatableIface *iface)
{
parent_activatable_iface = g_type_interface_peek_parent (iface);
iface->update = gtk3_image_menu_item_update;
iface->sync_action_properties = gtk3_image_menu_item_sync_action_properties;
}
static gboolean
activatable_update_stock_id (Gtk3ImageMenuItem *image_menu_item, GtkAction *action)
{
GtkWidget *image;
const gchar *stock_id = gtk_action_get_stock_id (action);
image = gtk3_image_menu_item_get_image (image_menu_item);
if (GTK_IS_IMAGE (image) &&
stock_id && gtk_icon_factory_lookup_default (stock_id))
{
gtk_image_set_from_stock (GTK_IMAGE (image), stock_id, GTK_ICON_SIZE_MENU);
return TRUE;
}
return FALSE;
}
static gboolean
activatable_update_gicon (Gtk3ImageMenuItem *image_menu_item, GtkAction *action)
{
GtkWidget *image;
GIcon *icon = gtk_action_get_gicon (action);
const gchar *stock_id = gtk_action_get_stock_id (action);
image = gtk3_image_menu_item_get_image (image_menu_item);
if (icon && GTK_IS_IMAGE (image) &&
!(stock_id && gtk_icon_factory_lookup_default (stock_id)))
{
gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_MENU);
return TRUE;
}
return FALSE;
}
static void
activatable_update_icon_name (Gtk3ImageMenuItem *image_menu_item, GtkAction *action)
{
GtkWidget *image;
const gchar *icon_name = gtk_action_get_icon_name (action);
image = gtk3_image_menu_item_get_image (image_menu_item);
if (GTK_IS_IMAGE (image) &&
(gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY ||
gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME))
{
gtk_image_set_from_icon_name (GTK_IMAGE (image), icon_name, GTK_ICON_SIZE_MENU);
}
}
static void
gtk3_image_menu_item_update (GtkActivatable *activatable,
GtkAction *action,
const gchar *property_name)
{
Gtk3ImageMenuItem *image_menu_item;
gboolean use_appearance;
image_menu_item = GTK3_IMAGE_MENU_ITEM (activatable);
parent_activatable_iface->update (activatable, action, property_name);
use_appearance = gtk_activatable_get_use_action_appearance (activatable);
if (!use_appearance)
return;
if (strcmp (property_name, "stock-id") == 0)
activatable_update_stock_id (image_menu_item, action);
else if (strcmp (property_name, "gicon") == 0)
activatable_update_gicon (image_menu_item, action);
else if (strcmp (property_name, "icon-name") == 0)
activatable_update_icon_name (image_menu_item, action);
}
static void
gtk3_image_menu_item_sync_action_properties (GtkActivatable *activatable,
GtkAction *action)
{
Gtk3ImageMenuItem *image_menu_item;
GtkWidget *image;
gboolean use_appearance;
image_menu_item = GTK3_IMAGE_MENU_ITEM (activatable);
parent_activatable_iface->sync_action_properties (activatable, action);
if (!action)
return;
use_appearance = gtk_activatable_get_use_action_appearance (activatable);
if (!use_appearance)
return;
image = gtk3_image_menu_item_get_image (image_menu_item);
if (image && !GTK_IS_IMAGE (image))
{
gtk3_image_menu_item_set_image (image_menu_item, NULL);
image = NULL;
}
if (!image)
{
image = gtk_image_new ();
gtk_widget_show (image);
gtk3_image_menu_item_set_image (GTK3_IMAGE_MENU_ITEM (activatable),
image);
}
if (!activatable_update_stock_id (image_menu_item, action) &&
!activatable_update_gicon (image_menu_item, action))
activatable_update_icon_name (image_menu_item, action);
gtk3_image_menu_item_set_always_show_image (image_menu_item,
gtk_action_get_always_show_image (action));
}
/**
* gtk3_image_menu_item_new:
*
* Creates a new #Gtk3ImageMenuItem with an empty label.
*
* Returns: a new #Gtk3ImageMenuItem
*/
GtkWidget*
gtk3_image_menu_item_new (void)
{
return g_object_new (GTK3_TYPE_IMAGE_MENU_ITEM, NULL);
}
/**
* gtk3_image_menu_item_new_with_label:
* @label: the text of the menu item.
*
* Creates a new #Gtk3ImageMenuItem containing a label.
*
* Returns: a new #Gtk3ImageMenuItem.
*/
GtkWidget*
gtk3_image_menu_item_new_with_label (const gchar *label)
{
return g_object_new (GTK3_TYPE_IMAGE_MENU_ITEM,
"label", label,
NULL);
}
/**
* gtk3_image_menu_item_new_with_mnemonic:
* @label: the text of the menu item, with an underscore in front of the
* mnemonic character
*
* Creates a new #Gtk3ImageMenuItem containing a label. The label
* will be created using gtk_label_new_with_mnemonic(), so underscores
* in @label indicate the mnemonic for the menu item.
*
* Returns: a new #Gtk3ImageMenuItem
*/
GtkWidget*
gtk3_image_menu_item_new_with_mnemonic (const gchar *label)
{
return g_object_new (GTK3_TYPE_IMAGE_MENU_ITEM,
"use-underline", TRUE,
"label", label,
NULL);
}
/**
* gtk3_image_menu_item_new_from_stock:
* @stock_id: the name of the stock item.
* @accel_group: (allow-none): the #GtkAccelGroup to add the menu items
* accelerator to, or %NULL.
*
* Creates a new #Gtk3ImageMenuItem containing the image and text from a
* stock item. Some stock ids have preprocessor macros like #GTK_STOCK_OK
* and #GTK_STOCK_APPLY.
*
* If you want this menu item to have changeable accelerators, then pass in
* %NULL for accel_group. Next call gtk_menu_item_set_accel_path() with an
* appropriate path for the menu item, use gtk_stock_lookup() to look up the
* standard accelerator for the stock item, and if one is found, call
* gtk_accel_map_add_entry() to register it.
*
* Returns: a new #Gtk3ImageMenuItem.
*/
GtkWidget*
gtk3_image_menu_item_new_from_stock (const gchar *stock_id,
GtkAccelGroup *accel_group)
{
return g_object_new (GTK3_TYPE_IMAGE_MENU_ITEM,
"label", stock_id,
"use-stock", TRUE,
"accel-group", accel_group,
NULL);
}
/**
* gtk3_image_menu_item_set_use_stock:
* @image_menu_item: a #Gtk3ImageMenuItem
* @use_stock: %TRUE if the menuitem should use a stock item
*
* If %TRUE, the label set in the menuitem is used as a
* stock id to select the stock item for the item.
*
* Since: 2.16
*/
void
gtk3_image_menu_item_set_use_stock (Gtk3ImageMenuItem *image_menu_item,
gboolean use_stock)
{
Gtk3ImageMenuItemPrivate *priv;
g_return_if_fail (GTK3_IS_IMAGE_MENU_ITEM (image_menu_item));
priv = image_menu_item->priv;
if (priv->use_stock != use_stock)
{
priv->use_stock = use_stock;
gtk3_image_menu_item_recalculate (image_menu_item);
g_object_notify (G_OBJECT (image_menu_item), "use-stock");
}
}
/**
* gtk3_image_menu_item_get_use_stock:
* @image_menu_item: a #Gtk3ImageMenuItem
*
* Checks whether the label set in the menuitem is used as a
* stock id to select the stock item for the item.
*
* Returns: %TRUE if the label set in the menuitem is used as a
* stock id to select the stock item for the item
*
* Since: 2.16
*/
gboolean
gtk3_image_menu_item_get_use_stock (Gtk3ImageMenuItem *image_menu_item)
{
g_return_val_if_fail (GTK3_IS_IMAGE_MENU_ITEM (image_menu_item), FALSE);
return image_menu_item->priv->use_stock;
}
/**
* gtk3_image_menu_item_set_always_show_image:
* @image_menu_item: a #Gtk3ImageMenuItem
* @always_show: %TRUE if the menuitem should always show the image
*
* If %TRUE, the menu item will ignore the #GtkSettings:gtk-menu-images
* setting and always show the image, if available.
*
* Use this property if the menuitem would be useless or hard to use
* without the image.
*
* Since: 2.16
*/
void
gtk3_image_menu_item_set_always_show_image (Gtk3ImageMenuItem *image_menu_item,
gboolean always_show)
{
Gtk3ImageMenuItemPrivate *priv;
g_return_if_fail (GTK3_IS_IMAGE_MENU_ITEM (image_menu_item));
priv = image_menu_item->priv;
if (priv->always_show_image != always_show)
{
priv->always_show_image = always_show;
if (priv->image)
{
if (show_image (image_menu_item))
gtk_widget_show (priv->image);
else
gtk_widget_hide (priv->image);
}
g_object_notify (G_OBJECT (image_menu_item), "always-show-image");
}
}
/**
* gtk3_image_menu_item_get_always_show_image:
* @image_menu_item: a #Gtk3ImageMenuItem
*
* Returns whether the menu item will ignore the #GtkSettings:gtk-menu-images
* setting and always show the image, if available.
*
* Returns: %TRUE if the menu item will always show the image
*
* Since: 2.16
*/
gboolean
gtk3_image_menu_item_get_always_show_image (Gtk3ImageMenuItem *image_menu_item)
{
g_return_val_if_fail (GTK3_IS_IMAGE_MENU_ITEM (image_menu_item), FALSE);
return image_menu_item->priv->always_show_image;
}
/**
* gtk3_image_menu_item_set_accel_group:
* @image_menu_item: a #Gtk3ImageMenuItem
* @accel_group: the #GtkAccelGroup
*
* Specifies an @accel_group to add the menu items accelerator to
* (this only applies to stock items so a stock item must already
* be set, make sure to call gtk3_image_menu_item_set_use_stock()
* and gtk_menu_item_set_label() with a valid stock item first).
*
* If you want this menu item to have changeable accelerators then
* you shouldnt need this (see gtk3_image_menu_item_new_from_stock()).
*
* Since: 2.16
*/
void
gtk3_image_menu_item_set_accel_group (Gtk3ImageMenuItem *image_menu_item,
GtkAccelGroup *accel_group)
{
Gtk3ImageMenuItemPrivate *priv;
GtkStockItem stock_item;
/* Silent return for the constructor */
if (!accel_group)
return;
g_return_if_fail (GTK3_IS_IMAGE_MENU_ITEM (image_menu_item));
g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
priv = image_menu_item->priv;
if (priv->use_stock && priv->label && gtk_stock_lookup (priv->label, &stock_item))
if (stock_item.keyval)
{
gtk_widget_add_accelerator (GTK_WIDGET (image_menu_item),
"activate",
accel_group,
stock_item.keyval,
stock_item.modifier,
GTK_ACCEL_VISIBLE);
g_object_notify (G_OBJECT (image_menu_item), "accel-group");
}
}
/**
* gtk3_image_menu_item_set_image:
* @image_menu_item: a #Gtk3ImageMenuItem.
* @image: (allow-none): a widget to set as the image for the menu item.
*
* Sets the image of @image_menu_item to the given widget.
* Note that it depends on the show-menu-images setting whether
* the image will be displayed or not.
*/
void
gtk3_image_menu_item_set_image (Gtk3ImageMenuItem *image_menu_item,
GtkWidget *image)
{
Gtk3ImageMenuItemPrivate *priv;
g_return_if_fail (GTK3_IS_IMAGE_MENU_ITEM (image_menu_item));
priv = image_menu_item->priv;
if (image == priv->image)
return;
if (priv->image)
gtk_container_remove (GTK_CONTAINER (image_menu_item),
priv->image);
priv->image = image;
if (image == NULL)
return;
gtk_widget_set_parent (image, GTK_WIDGET (image_menu_item));
g_object_set (image,
"visible", show_image (image_menu_item),
"no-show-all", TRUE,
NULL);
g_object_notify (G_OBJECT (image_menu_item), "image");
}
/**
* gtk3_image_menu_item_get_image:
* @image_menu_item: a #Gtk3ImageMenuItem
*
* Gets the widget that is currently set as the image of @image_menu_item.
* See gtk3_image_menu_item_set_image().
*
* Return value: (transfer none): the widget set as image of @image_menu_item
**/
GtkWidget*
gtk3_image_menu_item_get_image (Gtk3ImageMenuItem *image_menu_item)
{
g_return_val_if_fail (GTK3_IS_IMAGE_MENU_ITEM (image_menu_item), NULL);
return image_menu_item->priv->image;
}
static void
gtk3_image_menu_item_remove (GtkContainer *container,
GtkWidget *child)
{
Gtk3ImageMenuItem *image_menu_item = GTK3_IMAGE_MENU_ITEM (container);
Gtk3ImageMenuItemPrivate *priv = image_menu_item->priv;
if (child == priv->image)
{
gboolean widget_was_visible;
widget_was_visible = gtk_widget_get_visible (child);
gtk_widget_unparent (child);
priv->image = NULL;
if (widget_was_visible &&
gtk_widget_get_visible (GTK_WIDGET (container)))
gtk_widget_queue_resize (GTK_WIDGET (container));
g_object_notify (G_OBJECT (image_menu_item), "image");
}
else
{
GTK_CONTAINER_CLASS (gtk3_image_menu_item_parent_class)->remove (container, child);
}
}
cairo-dock-3.3.2/src/gldit/cairo-dock-object.h 000664 001750 001750 00000021275 12223247550 022223 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_OBJECT__
#define __CAIRO_DOCK_OBJECT__
#include
#include "cairo-dock-struct.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-object.h This class defines the Objects, the base class of libgldi.
* Every element in this library is an Object.
* An object is defined by an ObjectManager, which defines its capabilities and signals.
*
* Any object is created with \ref gldi_object_new and destroyed with \ref gldi_object_unref.
* An object can be deleted from the current theme with \ref gldi_object_delete.
* An object can be reloaded with \ref gldi_object_reload.
*
* You can listen for notifications on an object with \ref gldi_object_register_notification and stop listening with \ref gldi_object_remove_notification.
* To listen for notifications on any object of a given type, simply register yourself on its ObjectManager.
*/
/// Definition of an Object.
struct _GldiObject {
gint ref;
GPtrArray *pNotificationsTab;
GldiObjectManager *mgr;
GList *mgrs; // sorted in reverse order
};
/// Definition of an ObjectManager.
struct _GldiObjectManager {
GldiObject object;
const gchar *cName;
gint iObjectSize;
void (*init_object) (GldiObject *pObject, gpointer attr);
void (*reset_object) (GldiObject *pObject);
gboolean (*delete_object) (GldiObject *pObject);
GKeyFile* (*reload_object) (GldiObject *pObject, gboolean bReloadConf, GKeyFile *pKeyFile);
};
/// signals (any object has at least these ones)
typedef enum {
/// notification called when an object has been created. data : the object
NOTIFICATION_NEW,
/// notification called when the object is going to be destroyed. data : the object
NOTIFICATION_DESTROY,
NB_NOTIFICATIONS_OBJECT
} GldiObjectNotifications;
#define GLDI_OBJECT(p) ((GldiObject*)(p))
void gldi_object_init (GldiObject *obj, GldiObjectManager *pMgr, gpointer attr);
/** Create a new object.
* @param pMgr the ObjectManager
* @param attr the attributes of the object
* @return the new object, with a reference of 1; use \ref gldi_object_unref to destroy it
*/
GldiObject *gldi_object_new (GldiObjectManager *pMgr, gpointer attr);
/** Take a reference on an object.
* @param pObject the Object
*/
void gldi_object_ref (GldiObject *pObject);
/** Drop your reference on an object. If it's the last reference, the object is destroyed, otherwise nothing happen.
* @param pObject the Object
*/
void gldi_object_unref (GldiObject *pObject);
/** Delete an object from the current theme. The object is unref'd, and won't be created again on next startup.
* @param pObject the Object
*/
void gldi_object_delete (GldiObject *pObject);
/** Reload an object.
* @param pObject the Object
* @param bReloadConfig TRUE to read its config file again (if the object has one)
*/
void gldi_object_reload (GldiObject *pObject, gboolean bReloadConfig);
/* Sets the ObjectManager of an object. It is only useful to make an ObjectManager derive from another one. For any other object, it is done automatically.
*/
void gldi_object_set_manager (GldiObject *pObject, GldiObjectManager *pMgr);
gboolean gldi_object_is_manager_child (GldiObject *pObject, GldiObjectManager *pMgr);
#define gldi_object_get_type(obj) (GLDI_OBJECT(obj)->mgr ? GLDI_OBJECT(obj)->mgr->cName : "ObjectManager")
/// Generic prototype of a notification callback.
typedef gboolean (* GldiNotificationFunc) (gpointer pUserData, ...);
typedef struct {
GldiNotificationFunc pFunction;
gpointer pUserData;
} GldiNotificationRecord;
typedef guint GldiNotificationType;
/// Use this in \ref gldi_object_register_notification to be called before the core.
#define GLDI_RUN_FIRST TRUE
/// Use this in \ref gldi_object_register_notification to be called after the core.
#define GLDI_RUN_AFTER FALSE
/// Return this in your callback to prevent the other callbacks from being called after you.
#define GLDI_NOTIFICATION_INTERCEPT TRUE
/// Return this in your callback to let pass the notification to the other callbacks after you.
#define GLDI_NOTIFICATION_LET_PASS FALSE
#define gldi_object_install_notifications(pObject, iNbNotifs) do {\
GPtrArray *pNotificationsTab = (GLDI_OBJECT(pObject))->pNotificationsTab;\
if (pNotificationsTab == NULL) {\
pNotificationsTab = g_ptr_array_new ();\
(GLDI_OBJECT(pObject))->pNotificationsTab = pNotificationsTab; }\
if (pNotificationsTab->len < iNbNotifs)\
g_ptr_array_set_size (pNotificationsTab, iNbNotifs); } while (0)
/** Register an action to be called when a given notification is broadcasted from a given object.
*@param pObject the object (Icon, Container, Manager).
*@param iNotifType type of the notification.
*@param pFunction callback.
*@param bRunFirst GLDI_RUN_FIRST to be called before Cairo-Dock, GLDI_RUN_AFTER to be called after.
*@param pUserData data to be passed as the first parameter of the callback.
*/
void gldi_object_register_notification (gpointer pObject, GldiNotificationType iNotifType, GldiNotificationFunc pFunction, gboolean bRunFirst, gpointer pUserData);
/** Remove a callback from the list of callbacks of a given object for a given notification and a given data.
Note: it is safe to remove the callback when it is called, but not another one.
*@param pObject the object (Icon, Container, Manager) for which the action has been registered.
*@param iNotifType type of the notification.
*@param pFunction callback.
*@param pUserData data that was registerd with the callback.
*/
void gldi_object_remove_notification (gpointer pObject, GldiNotificationType iNotifType, GldiNotificationFunc pFunction, gpointer pUserData);
#define __notify(pNotificationRecordList, bStop, ...) do {\
GldiNotificationRecord *pNotificationRecord;\
GSList *pElement = pNotificationRecordList, *pNextElement;\
while (pElement != NULL && ! bStop) {\
pNotificationRecord = pElement->data;\
pNextElement = pElement->next;\
bStop = pNotificationRecord->pFunction (pNotificationRecord->pUserData, ##__VA_ARGS__);\
pElement = pNextElement; }\
} while (0)
#define __notify_on_object(pObject, iNotifType, ...) \
__extension__ ({\
gboolean _stop = FALSE;\
GPtrArray *pNotificationsTab = (pObject)->pNotificationsTab;\
if (pNotificationsTab && iNotifType < pNotificationsTab->len) {\
GSList *pNotificationRecordList = g_ptr_array_index (pNotificationsTab, iNotifType);\
__notify (pNotificationRecordList, _stop, ##__VA_ARGS__);} \
else {_stop = TRUE;}\
_stop; })
/** Broadcast a notification on a given object, and on all its managers.
*@param pObject the object (Icon, Container, Manager, ...).
*@param iNotifType type of the notification.
*@param ... parameters to be passed to the callbacks that have registered to this notification.
*/
#define gldi_object_notify(pObject, iNotifType, ...) \
__extension__ ({\
gboolean _bStop = FALSE;\
GldiObject *_obj = GLDI_OBJECT (pObject);\
while (_obj && !_bStop) {\
_bStop = __notify_on_object (_obj, iNotifType, ##__VA_ARGS__);\
_obj = GLDI_OBJECT (_obj->mgr); }\
})
#define GLDI_STR_HELPER(x) #x
#define GLDI_STR(x) GLDI_STR_HELPER(x)
#define GLDI_MGR_NAME(name) my##name##ObjectMgr
#define GLDI_OBJECT_NAME(name) Gldi##name
#define GLDI_OBJECT_MANAGER_REGISTER(name) gldi_##name##_object_manager_register()
#define GLDI_OBJECT_MANAGER_DEFINE_H(name) void GLDI_OBJECT_MANAGER_REGISTER(name)
//name=Dock, NAME=DOCK
#define GLDI_OBJECT_MANAGER_DEFINE_BEGIN(name, NAME) \
GLDI_OBJECT_MANAGER_DEFINE_H(name) \
{ \
GldiObjectManager *mgr = &GLDI_MGR_NAME(name); \
memset (mgr, 0, sizeof (GldiObjectManager)); \
mgr->cName = GLDI_STR(name); \
mgr->iObjectSize = sizeof (GLDI_OBJECT_NAME(name)); \
gldi_object_install_notifications (mgr, NB_NOTIFICATIONS_##NAME);
#define GLDI_OBJECT_MANAGER_HAS_INIT mgr->init_object = init_object;
#define GLDI_OBJECT_MANAGER_HAS_RESET mgr->reset_object = reset_object;
#define GLDI_OBJECT_MANAGER_HAS_DELETE mgr->delete_object = delete_object;
#define GLDI_OBJECT_MANAGER_HAS_RELOAD mgr->reload_object = reload_object;
#define GLDI_OBJECT_MANAGER_DERIVES_FROM(mgr2) gldi_object_set_manager (GLDI_OBJECT (mgr), mgr2)
#define GLDI_OBJECT_MANAGER_DEFINE_END }
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-draw-opengl.h 000664 001750 001750 00000020664 12223247550 023175 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_DRAW_OPENGL__
#define __CAIRO_DOCK_DRAW_OPENGL__
#include
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-opengl.h"
#include "cairo-dock-container.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-draw-opengl.h This class provides some useful functions to draw with OpenGL.
*/
void cairo_dock_set_icon_scale (Icon *pIcon, GldiContainer *pContainer, double fZoomFactor);
void cairo_dock_set_container_orientation_opengl (GldiContainer *pContainer);
void cairo_dock_draw_icon_reflect_opengl (Icon *pIcon, CairoDock *pDock);
void cairo_dock_draw_icon_opengl (Icon *pIcon, CairoDock *pDock);
void cairo_dock_translate_on_icon_opengl (Icon *icon, GldiContainer *pContainer, double fDockMagnitude);
/** Draw an icon, according to its current parameters : position, transparency, reflect, rotation, stretching. Also draws its indicators, label, and quick-info. It generates a CAIRO_DOCK_RENDER_ICON notification.
*@param icon the icon to draw.
*@param pDock the dock containing the icon.
*@param fDockMagnitude current magnitude of the dock.
*@param bUseText TRUE to draw the labels.
*/
void cairo_dock_render_one_icon_opengl (Icon *icon, CairoDock *pDock, double fDockMagnitude, gboolean bUseText);
void cairo_dock_render_hidden_dock_opengl (CairoDock *pDock);
//////////////////
// LOAD TEXTURE //
//////////////////
/** Load a cairo surface into an OpenGL texture. The surface can be destroyed after that if you don't need it. The texture will have the same size as the surface.
*@param pImageSurface the surface, created with one of the 'cairo_dock_create_surface_xxx' functions.
*@return the newly allocated texture, to be destroyed with _cairo_dock_delete_texture.
*/
GLuint cairo_dock_create_texture_from_surface (cairo_surface_t *pImageSurface);
/** Load a pixels buffer representing an image into an OpenGL texture.
*@param pTextureRaw a buffer of pixels.
*@param iWidth width of the image.
*@param iHeight height of the image.
*@return the newly allocated texture, to be destroyed with _cairo_dock_delete_texture.
*/
GLuint cairo_dock_create_texture_from_raw_data (const guchar *pTextureRaw, int iWidth, int iHeight);
/** Load an image on the dock into an OpenGL texture. The texture will have the same size as the image. The size is given as an output, if you need it for some reason.
*@param cImagePath path to an image.
*@param fImageWidth pointer that will be filled with the width of the image.
*@param fImageHeight pointer that will be filled with the height of the image.
*@return the newly allocated texture, to be destroyed with _cairo_dock_delete_texture.
*/
GLuint cairo_dock_create_texture_from_image_full (const gchar *cImagePath, double *fImageWidth, double *fImageHeight);
/** Load an image on the dock into an OpenGL texture. The texture will have the same size as the image.
*@param cImagePath path to an image.
*@return the newly allocated texture, to be destroyed with _cairo_dock_delete_texture.
*/
#define cairo_dock_create_texture_from_image(cImagePath) cairo_dock_create_texture_from_image_full (cImagePath, NULL, NULL)
/** Delete an OpenGL texture from the Graphic Card.
*@param iTexture variable containing the ID of a texture.
*/
#define _cairo_dock_delete_texture(iTexture) glDeleteTextures (1, &iTexture)
/** Update the icon's texture with its current cairo surface. This allows you to draw an icon with libcairo, and just copy the result to the OpenGL texture to be able to draw the icon in OpenGL too.
*@param pIcon the icon.
*/
void cairo_dock_update_icon_texture (Icon *pIcon);
void cairo_dock_draw_hidden_appli_icon (Icon *pIcon, GldiContainer *pContainer, gboolean bStateChanged);
//////////////////
// DRAW TEXTURE //
//////////////////
/** Enable texture drawing.
*/
#define _cairo_dock_enable_texture(...) do { \
glEnable (GL_BLEND);\
glEnable (GL_TEXTURE_2D);\
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);\
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);\
glEnable (GL_LINE_SMOOTH);\
glPolygonMode (GL_FRONT, GL_FILL); } while (0)
/** Disable texture drawing.
*/
#define _cairo_dock_disable_texture(...) do { \
glDisable (GL_TEXTURE_2D);\
glDisable (GL_LINE_SMOOTH);\
glDisable (GL_BLEND); } while (0)
/** Set the alpha channel to a current value, other channels are set to 1.
*@param fAlpha alpha
*/
#define _cairo_dock_set_alpha(fAlpha) glColor4f (1., 1., 1., fAlpha)
/** Set the color blending to overwrite.
*/
#define _cairo_dock_set_blend_source(...) glBlendFunc (GL_ONE, GL_ZERO)
/** Set the color blending to mix, for premultiplied texture.
*/
#define _cairo_dock_set_blend_alpha(...) glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
/** Set the color blending to mix.
*/
#define _cairo_dock_set_blend_over(...) glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
/** Set the color blending to mix on a pbuffer.
*/
#define _cairo_dock_set_blend_pbuffer(...) glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
#define _cairo_dock_apply_current_texture_at_size(w, h) do { \
glBegin(GL_QUADS);\
glTexCoord2f(0., 0.); glVertex3f(-.5*w, .5*h, 0.);\
glTexCoord2f(1., 0.); glVertex3f( .5*w, .5*h, 0.);\
glTexCoord2f(1., 1.); glVertex3f( .5*w, -.5*h, 0.);\
glTexCoord2f(0., 1.); glVertex3f(-.5*w, -.5*h, 0.);\
glEnd(); } while (0)
#define _cairo_dock_apply_current_texture_at_size_crop(iTexture, w, h, ratio) do { \
glBegin(GL_QUADS);\
glTexCoord2f(0., 1-ratio); glVertex3f(-.5*w, (ratio -.5)*h, 0.);\
glTexCoord2f(1., 1-ratio); glVertex3f( .5*w, (ratio -.5)*h, 0.);\
glTexCoord2f(1., 1); glVertex3f( .5*w, -.5*h, 0.);\
glTexCoord2f(0., 1); glVertex3f(-.5*w, -.5*h, 0.);\
glEnd(); } while (0)
#define _cairo_dock_apply_current_texture_at_size_with_offset(w, h, x, y) do { \
glBegin(GL_QUADS);\
glTexCoord2f(0., 0.); glVertex3f(x-.5*w, y+.5*h, 0.);\
glTexCoord2f(1., 0.); glVertex3f(x+.5*w, y+.5*h, 0.);\
glTexCoord2f(1., 1.); glVertex3f(x+.5*w, y-.5*h, 0.);\
glTexCoord2f(0., 1.); glVertex3f(x-.5*w, y-.5*h, 0.);\
glEnd(); } while (0)
#define _cairo_dock_apply_current_texture_portion_at_size_with_offset(u, v, du, dv, w, h, x, y) do { \
glBegin(GL_QUADS);\
glTexCoord2f(u, v); glVertex3f(x-.5*w, y+.5*h, 0.);\
glTexCoord2f(u+du, v); glVertex3f(x+.5*w, y+.5*h, 0.);\
glTexCoord2f(u+du, v+dv); glVertex3f(x+.5*w, y-.5*h, 0.);\
glTexCoord2f(u, v+dv); glVertex3f(x-.5*w, y-.5*h, 0.);\
glEnd(); } while (0)
/** Draw a texture centered on the current point, at a given size.
*@param iTexture the texture
*@param w width
*@param h height
*/
#define _cairo_dock_apply_texture_at_size(iTexture, w, h) do { \
glBindTexture (GL_TEXTURE_2D, iTexture);\
_cairo_dock_apply_current_texture_at_size (w, h); } while (0)
/** Apply a texture centered on the current point and at the given scale.
*@param iTexture the texture
*/
#define _cairo_dock_apply_texture(iTexture) _cairo_dock_apply_texture_at_size (iTexture, 1, 1)
/** Draw a texture centered on the current point, at a given size, and with a given transparency.
*@param iTexture the texture
*@param w width
*@param h height
*@param fAlpha the transparency, between 0 and 1.
*/
#define _cairo_dock_apply_texture_at_size_with_alpha(iTexture, w, h, fAlpha) do { \
_cairo_dock_set_alpha (fAlpha);\
_cairo_dock_apply_texture_at_size (iTexture, w, h); } while (0)
#define cairo_dock_apply_texture _cairo_dock_apply_texture
#define cairo_dock_apply_texture_at_size _cairo_dock_apply_texture_at_size
void cairo_dock_draw_texture_with_alpha (GLuint iTexture, int iWidth, int iHeight, double fAlpha);
void cairo_dock_draw_texture (GLuint iTexture, int iWidth, int iHeight);
void cairo_dock_apply_icon_texture (Icon *pIcon);
void cairo_dock_apply_icon_texture_at_current_size (Icon *pIcon, GldiContainer *pContainer);
void cairo_dock_draw_icon_texture (Icon *pIcon, GldiContainer *pContainer);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-applet-facility.c 000664 001750 001750 00000037300 12223247550 024033 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include "cairo-dock-image-buffer.h"
#include "cairo-dock-draw.h"
#include "cairo-dock-config.h"
#include "cairo-dock-utils.h" // cairo_dock_launch_command
#include "cairo-dock-launcher-manager.h"
#include "cairo-dock-surface-factory.h"
#include "cairo-dock-animations.h"
#include "cairo-dock-packages.h"
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-module-instance-manager.h" // GldiModuleInstance
#include "cairo-dock-module-manager.h" // GldiModuleInstance
#include "cairo-dock-log.h"
#include "cairo-dock-dock-factory.h"
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-draw-opengl.h"
#include "cairo-dock-icon-factory.h"
#include "cairo-dock-container.h"
#include "cairo-dock-gui-manager.h"
#include "cairo-dock-backends-manager.h"
#include "cairo-dock-dock-facility.h"
#include "cairo-dock-icon-facility.h"
#include "cairo-dock-applet-facility.h"
extern gchar *g_cExtrasDirPath;
///extern CairoDockImageBuffer g_pIconBackgroundBuffer;
extern gboolean g_bUseOpenGL;
void cairo_dock_set_icon_surface_full (cairo_t *pIconContext, cairo_surface_t *pSurface, double fScale, double fAlpha, Icon *pIcon)
{
///g_return_if_fail (cairo_status (pIconContext) == CAIRO_STATUS_SUCCESS);
if (! cairo_dock_begin_draw_icon_cairo (pIcon, 0, pIconContext)) // 0 <=> erase
return;
//\________________ On efface l'ancienne image.
/**cairo_dock_erase_cairo_context (pIconContext);
//\________________ On met le background de l'icone si necessaire
if (pIcon != NULL &&
pIcon->image.pSurface != NULL &&
g_pIconBackgroundBuffer.pSurface != NULL &&
(! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)))
{
//cd_message (">>> %s prendra un fond d'icone", pIcon->cName);
int iWidth, iHeight;
cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
cairo_dock_apply_image_buffer_surface_at_size (&g_pIconBackgroundBuffer, pIconContext, iWidth, iHeight, 0, 0, 1);
pIcon->bNeedApplyBackground = FALSE;
}*/
//\________________ On applique la nouvelle image.
if (pSurface != NULL && fScale > 0)
{
cairo_save (pIconContext);
if (fScale != 1 && pIcon != NULL)
{
int iWidth, iHeight;
cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
cairo_translate (pIconContext, .5 * iWidth * (1 - fScale) , .5 * iHeight * (1 - fScale));
cairo_scale (pIconContext, fScale, fScale);
}
cairo_set_source_surface (
pIconContext,
pSurface,
0.,
0.);
if (fAlpha != 1)
cairo_paint_with_alpha (pIconContext, fAlpha);
else
cairo_paint (pIconContext);
cairo_restore (pIconContext);
}
cairo_dock_end_draw_icon_cairo (pIcon);
/**if (g_bUseOpenGL)
cairo_dock_update_icon_texture (pIcon);*/
}
/// TODO: don't use 'cairo_dock_set_icon_surface' here...
gboolean cairo_dock_set_image_on_icon (cairo_t *pIconContext, const gchar *cIconName, Icon *pIcon, G_GNUC_UNUSED GldiContainer *pContainer)
{
//g_print ("%s (%s)\n", __func__, cIconName);
// load the image in a surface.
int iWidth, iHeight;
cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
cairo_surface_t *pImageSurface = cairo_dock_create_surface_from_icon (cIconName,
iWidth,
iHeight);
// check that it's ok.
if (pImageSurface == NULL) // let the icon in its current state.
return FALSE;
// set the new image on the icon
cairo_dock_set_icon_surface (pIconContext, pImageSurface, pIcon);
cairo_surface_destroy (pImageSurface);
if (cIconName != pIcon->cFileName)
{
g_free (pIcon->cFileName);
pIcon->cFileName = g_strdup (cIconName);
}
return TRUE;
}
void cairo_dock_set_image_on_icon_with_default (cairo_t *pIconContext, const gchar *cIconName, Icon *pIcon, GldiContainer *pContainer, const gchar *cDefaultImagePath)
{
if (! cIconName || ! cairo_dock_set_image_on_icon (pIconContext, cIconName, pIcon, pContainer))
cairo_dock_set_image_on_icon (pIconContext, cDefaultImagePath, pIcon, pContainer);
}
void cairo_dock_set_hours_minutes_as_quick_info (Icon *pIcon, int iTimeInSeconds)
{
int hours = iTimeInSeconds / 3600;
int minutes = (iTimeInSeconds % 3600) / 60;
if (hours != 0)
gldi_icon_set_quick_info_printf (pIcon, "%dh%02d", hours, abs (minutes));
else
gldi_icon_set_quick_info_printf (pIcon, "%dmn", minutes);
}
void cairo_dock_set_minutes_secondes_as_quick_info (Icon *pIcon, int iTimeInSeconds)
{
int minutes = iTimeInSeconds / 60;
int secondes = iTimeInSeconds % 60;
//cd_debug ("%s (%d:%d)", __func__, minutes, secondes);
if (minutes != 0)
gldi_icon_set_quick_info_printf (pIcon, "%d:%02d", minutes, abs (secondes));
else
gldi_icon_set_quick_info_printf (pIcon, "%s0:%02d", (secondes < 0 ? "-" : ""), abs (secondes));
}
gchar *cairo_dock_get_human_readable_size (long long int iSizeInBytes)
{
double fValue;
if (iSizeInBytes >> 10 == 0)
{
return g_strdup_printf ("%dB", (int) iSizeInBytes);
}
else if (iSizeInBytes >> 20 == 0)
{
fValue = (double) (iSizeInBytes) / 1024.;
return g_strdup_printf (fValue < 10 ? "%.1fK" : "%.0fK", fValue);
}
else if (iSizeInBytes >> 30 == 0)
{
fValue = (double) (iSizeInBytes >> 10) / 1024.;
return g_strdup_printf (fValue < 10 ? "%.1fM" : "%.0fM", fValue);
}
else if (iSizeInBytes >> 40 == 0)
{
fValue = (double) (iSizeInBytes >> 20) / 1024.;
return g_strdup_printf (fValue < 10 ? "%.1fG" : "%.0fG", fValue);
}
else
{
fValue = (double) (iSizeInBytes >> 30) / 1024.;
return g_strdup_printf (fValue < 10 ? "%.1fT" : "%.0fT", fValue);
}
}
void cairo_dock_set_size_as_quick_info (Icon *pIcon, long long int iSizeInBytes)
{
gchar *cSize = cairo_dock_get_human_readable_size (iSizeInBytes);
gldi_icon_set_quick_info (pIcon, cSize);
g_free (cSize);
}
gchar *cairo_dock_get_theme_path_for_module (const gchar *cAppletConfFilePath, GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, const gchar *cDefaultThemeName, const gchar *cShareThemesDir, const gchar *cExtraDirName)
{
gchar *cThemeName = cairo_dock_get_string_key_value (pKeyFile, cGroupName, cKeyName, bFlushConfFileNeeded, cDefaultThemeName, NULL, NULL);
gchar *cUserThemesDir = (cExtraDirName != NULL ? g_strdup_printf ("%s/%s", g_cExtrasDirPath, cExtraDirName) : NULL);
CairoDockPackageType iType = cairo_dock_extract_package_type_from_name (cThemeName);
gchar *cThemePath = cairo_dock_get_package_path (cThemeName, cShareThemesDir, cUserThemesDir, cExtraDirName, iType);
if (iType != CAIRO_DOCK_ANY_PACKAGE)
{
g_key_file_set_string (pKeyFile, cGroupName, cKeyName, cThemeName);
cairo_dock_write_keys_to_file (pKeyFile, cAppletConfFilePath);
}
g_free (cThemeName);
g_free (cUserThemesDir);
return cThemePath;
}
//Utile pour jouer des fichiers son depuis le dock.
//A utiliser avec l'Objet UI 'u' dans les .conf
void cairo_dock_play_sound (const gchar *cSoundPath)
{
cd_debug ("%s (%s)", __func__, cSoundPath);
if (cSoundPath == NULL)
{
cd_warning ("No sound to play, skip.");
return;
}
gchar *cSoundCommand = NULL;
if (g_file_test ("/usr/bin/paplay", G_FILE_TEST_EXISTS))
cSoundCommand = g_strdup_printf("paplay --client-name=cairo-dock \"%s\"", cSoundPath);
else if (g_file_test ("/usr/bin/aplay", G_FILE_TEST_EXISTS))
cSoundCommand = g_strdup_printf("aplay \"%s\"", cSoundPath);
else if (g_file_test ("/usr/bin/play", G_FILE_TEST_EXISTS))
cSoundCommand = g_strdup_printf("play \"%s\"", cSoundPath);
cairo_dock_launch_command (cSoundCommand);
g_free (cSoundCommand);
}
// should be in gnome-integration if needed...
/*void cairo_dock_get_gnome_version (int *iMajor, int *iMinor, int *iMicro) {
gchar *cContent = NULL;
gsize length = 0;
GError *erreur = NULL;
g_file_get_contents ("/usr/share/gnome-about/gnome-version.xml", &cContent, &length, &erreur);
if (erreur != NULL) {
cd_warning (erreur->message);
g_error_free (erreur);
erreur = NULL;
*iMajor = 0;
*iMinor = 0;
*iMicro = 0;
return;
}
gchar **cLineList = g_strsplit (cContent, "\n", -1);
gchar *cOneLine = NULL, *cMajor = NULL, *cMinor = NULL, *cMicro = NULL;
int i, iMaj = 0, iMin = 0, iMic = 0;
for (i = 0; cLineList[i] != NULL; i ++) {
cOneLine = cLineList[i];
if (*cOneLine == '\0')
continue;
//Seeking for Major
cMajor = g_strstr_len (cOneLine, -1, ""); //2
if (cMajor != NULL) {
cMajor += 10; //On saute
gchar *str = strchr (cMajor, '<');
if (str != NULL)
*str = '\0'; //On bloque a
iMaj = atoi (cMajor);
}
else { //Gutsy xml's doesn't have but
cMajor = g_strstr_len (cOneLine, -1, ""); //2
if (cMajor != NULL) {
cMajor += 7; //On saute
gchar *str = strchr (cMajor, '<');
if (str != NULL)
*str = '\0'; //On bloque a
iMaj = atoi (cMajor);
}
}
//Seeking for Minor
cMinor = g_strstr_len (cOneLine, -1, ""); //22
if (cMinor != NULL) {
cMinor += 7; //On saute
gchar *str = strchr (cMinor, '<');
if (str != NULL)
*str = '\0'; //On bloque a
iMin = atoi (cMinor);
}
//Seeking for Micro
cMicro = g_strstr_len (cOneLine, -1, ""); //3
if (cMicro != NULL) {
cMicro += 7; //On saute
gchar *str = strchr (cMicro, '<');
if (str != NULL)
*str = '\0'; //On bloque a
iMic = atoi (cMicro);
}
if (iMaj != 0 && iMin != 0 && iMic != 0)
break; //On s'enfou du reste
}
cd_debug ("Gnome Version %d.%d.%d", iMaj, iMin, iMic);
*iMajor = iMaj;
*iMinor = iMin;
*iMicro = iMic;
g_free (cContent);
g_strfreev (cLineList);
}*/
void cairo_dock_pop_up_about_applet (G_GNUC_UNUSED GtkMenuItem *menu_item, GldiModuleInstance *pModuleInstance)
{
gldi_module_instance_popup_description (pModuleInstance);
}
void cairo_dock_open_module_config_on_demand (int iClickedButton, G_GNUC_UNUSED GtkWidget *pInteractiveWidget, GldiModuleInstance *pModuleInstance, G_GNUC_UNUSED CairoDialog *pDialog)
{
if (iClickedButton == 0 || iClickedButton == -1) // bouton OK ou touche Entree.
{
cairo_dock_show_module_instance_gui (pModuleInstance, -1);
}
}
void cairo_dock_insert_icons_in_applet (GldiModuleInstance *pInstance, GList *pIconsList, const gchar *cDockRenderer, const gchar *cDeskletRenderer, gpointer pDeskletRendererData)
{
Icon *pIcon = pInstance->pIcon;
g_return_if_fail (pIcon != NULL);
GldiContainer *pContainer = pInstance->pContainer;
g_return_if_fail (pContainer != NULL);
if (pInstance->pDock)
{
if (pIcon->pSubDock == NULL)
{
if (pIcon->cName == NULL)
gldi_icon_set_name (pIcon, pInstance->pModule->pVisitCard->cModuleName);
if (cairo_dock_check_unique_subdock_name (pIcon))
gldi_icon_set_name (pIcon, pIcon->cName);
pIcon->pSubDock = gldi_subdock_new (pIcon->cName, cDockRenderer, pInstance->pDock, pIconsList);
if (pIcon->pSubDock)
pIcon->pSubDock->bPreventDraggingIcons = TRUE; // par defaut pour toutes les applets on empeche de pouvoir deplacer/supprimer les icones a la souris.
}
else
{
Icon *pOneIcon;
GList *ic;
for (ic = pIconsList; ic != NULL; ic = ic->next)
{
pOneIcon = ic->data;
gldi_icon_insert_in_container (pOneIcon, CAIRO_CONTAINER(pIcon->pSubDock), ! CAIRO_DOCK_ANIMATE_ICON);
}
g_list_free (pIconsList);
cairo_dock_set_renderer (pIcon->pSubDock, cDockRenderer);
cairo_dock_update_dock_size (pIcon->pSubDock);
}
if (pIcon->iSubdockViewType != 0) // trigger the redraw after the icons are loaded.
cairo_dock_trigger_redraw_subdock_content_on_icon (pIcon);
}
else if (pInstance->pDesklet)
{
Icon *pOneIcon;
GList *ic;
for (ic = pIconsList; ic != NULL; ic = ic->next)
{
pOneIcon = ic->data;
cairo_dock_set_icon_container (pOneIcon, pInstance->pDesklet);
}
pInstance->pDesklet->icons = g_list_concat (pInstance->pDesklet->icons, pIconsList); /// + sort icons and insert automatic separators...
cairo_dock_set_desklet_renderer_by_name (pInstance->pDesklet, cDeskletRenderer, (CairoDeskletRendererConfigPtr) pDeskletRendererData);
cairo_dock_redraw_container (pInstance->pContainer);
}
}
void cairo_dock_insert_icon_in_applet (GldiModuleInstance *pInstance, Icon *pOneIcon)
{
// get the container (create it if necessary)
GldiContainer *pContainer = NULL;
if (pInstance->pDock)
{
Icon *pIcon = pInstance->pIcon;
if (pIcon->pSubDock == NULL)
{
if (pIcon->cName == NULL)
gldi_icon_set_name (pIcon, pInstance->pModule->pVisitCard->cModuleName);
if (cairo_dock_check_unique_subdock_name (pIcon))
gldi_icon_set_name (pIcon, pIcon->cName);
pIcon->pSubDock = gldi_subdock_new (pIcon->cName, NULL, pInstance->pDock, NULL);
if (pIcon->pSubDock)
pIcon->pSubDock->bPreventDraggingIcons = TRUE; // par defaut pour toutes les applets on empeche de pouvoir deplacer/supprimer les icones a la souris.
}
pContainer = CAIRO_CONTAINER (pIcon->pSubDock);
}
else if (pInstance->pDesklet)
{
pContainer = CAIRO_CONTAINER (pInstance->pDesklet);
}
g_return_if_fail (pContainer != NULL);
// insert the icon inside
gldi_icon_insert_in_container (pOneIcon, pContainer, ! CAIRO_DOCK_ANIMATE_ICON);
}
void cairo_dock_remove_all_icons_from_applet (GldiModuleInstance *pInstance)
{
Icon *pIcon = pInstance->pIcon;
g_return_if_fail (pIcon != NULL);
GldiContainer *pContainer = pInstance->pContainer;
g_return_if_fail (pContainer != NULL);
cd_debug ("%s (%s)", __func__, pInstance->pModule->pVisitCard->cModuleName);
if (pInstance->pDesklet && pInstance->pDesklet->icons != NULL)
{
cd_debug (" destroy desklet icons");
GList *icons = pInstance->pDesklet->icons;
pInstance->pDesklet->icons = NULL;
GList *ic;
Icon *icon;
for (ic = icons; ic != NULL; ic = ic->next)
{
icon = ic->data;
cairo_dock_set_icon_container (icon, NULL);
gldi_object_unref (GLDI_OBJECT(icon));
}
g_list_free (icons);
cairo_dock_redraw_container (pInstance->pContainer);
}
if (pIcon->pSubDock != NULL)
{
if (pInstance->pDock) // optimisation : on ne detruit pas le sous-dock.
{
cd_debug (" destroy sub-dock icons");
GList *icons = pIcon->pSubDock->icons;
pIcon->pSubDock->icons = NULL;
GList *ic;
Icon *icon;
for (ic = icons; ic != NULL; ic = ic->next)
{
icon = ic->data;
cairo_dock_set_icon_container (icon, NULL);
gldi_object_unref (GLDI_OBJECT(icon));
}
g_list_free (icons);
}
else // precaution pas chere
{
cd_debug (" destroy sub-dock");
gldi_object_unref (GLDI_OBJECT(pIcon->pSubDock));
pIcon->pSubDock = NULL;
}
}
}
void cairo_dock_resize_applet (GldiModuleInstance *pInstance, int w, int h)
{
Icon *pIcon = pInstance->pIcon;
g_return_if_fail (pIcon != NULL);
GldiContainer *pContainer = pInstance->pContainer;
g_return_if_fail (pContainer != NULL);
if (pInstance->pDock)
{
cairo_dock_icon_set_requested_size (pIcon, w, h);
cairo_dock_resize_icon_in_dock (pIcon, pInstance->pDock);
}
else // in desklet mode, just resize the desklet, it will trigger the reload of the applet when the 'configure' event is received.
{
gtk_window_resize (GTK_WINDOW (pContainer->pWidget),
w,
h); /// TODO: actually, the renderer should handle this, because except with the 'Simple' view, we can't know the actual size of the icon.
}
}
cairo-dock-3.3.2/src/gldit/cairo-dock-task.h 000664 001750 001750 00000022513 12223247550 021713 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_TASK__
#define __CAIRO_DOCK_TASK__
#include "cairo-dock-struct.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-task.h An easy way to define periodic and asynchronous tasks, that can perform heavy jobs without blocking the dock.
*
* A Task is divided in 2 phases :
* - the asynchronous phase will be executed in another thread, while the dock continues to run on its own thread, in parallel. During this phase you will do all the heavy job (like downloading a file or computing something) but you can't interact on the dock.
* - the synchronous phase will be executed after the first one has finished. There you will update your applet with the result of the first phase.
*
* \attention A data buffer is used to communicate between the 2 phases. It is important that these datas are never accessed outside the task, and vice versa that the asynchronous thread never accesses other data than this buffer.\n
* If you want to access these datas outside the task, you have to copy them in a safe place during the 2nd phase, or to stop the task before (beware that stopping the task means waiting for the 1st phase to finish, which can take some time).
*
* You create a Task with \ref cairo_dock_new_task, launch it with \ref cairo_dock_launch_task, and destroy it with \ref cairo_dock_free_task.
*
* A Task can be periodic if you specify a period, otherwise it will be executed once. It also can also be fully synchronous if you don't specify an asynchronous function.
*
*/
/// Type of frequency for a periodic task. The frequency of the Task is divided by 2, 4, and 10 for each state.
typedef enum {
CAIRO_DOCK_FREQUENCY_NORMAL = 0,
CAIRO_DOCK_FREQUENCY_LOW,
CAIRO_DOCK_FREQUENCY_VERY_LOW,
CAIRO_DOCK_FREQUENCY_SLEEP,
CAIRO_DOCK_NB_FREQUENCIES
} CairoDockFrequencyState;
/// Definition of the asynchronous job, that does the heavy part.
typedef void (* CairoDockGetDataAsyncFunc ) (gpointer pSharedMemory);
/// Definition of the synchronous job, that update the dock with the results of the previous job. Returns TRUE to continue, FALSE to stop
typedef gboolean (* CairoDockUpdateSyncFunc ) (gpointer pSharedMemory);
/// Definition of a periodic and asynchronous Task.
struct _CairoDockTask {
/// ID of the timer of the Task (if periodic)
gint iSidTimer;
/// ID of the timer to perform the update.
gint iSidTimerUpdate;
gboolean bIsRunning; // TRUE is the thread is running or about to run or if the update is pending
/// function carrying out the heavy job.
CairoDockGetDataAsyncFunc get_data;
/// function carrying out the update of the dock. Returns TRUE to continue, FALSE to stop.
CairoDockUpdateSyncFunc update;
/// interval of time in seconds, 0 to run the Task once.
guint iPeriod;
/// state of the frequency of the Task.
CairoDockFrequencyState iFrequencyState;
/// structure passed as parameter of the 'get_data' and 'update' functions. Must not be accessed outside of these 2 functions !
gpointer pSharedMemory;
/// timer to get the accurate amount of time since last update.
GTimer *pClock;
/// time elapsed since last update.
double fElapsedTime;
/// function called when the task is destroyed to free the shared memory (optionnal).
GFreeFunc free_data;
/// TRUE when the task has been discarded.
gboolean bDiscard;
gboolean bNeedsUpdate; // TRUE when new data are waiting to be processed.
gboolean bContinue; // result of the 'update' function (TRUE -> continue, FALSE -> stop, if the task is periodic).
GThread *pThread; // the thread that execute the asynchronous 'get_data' callback
GCond *pCond; // condition to awake the thread (if periodic).
gboolean bRunThread; // condition value: whether to run the thread or exit.
GMutex *pMutex; // mutex associated with the condition.
} ;
/** Launch a periodic Task, beforehand prepared with #cairo_dock_new_task. The first iteration is executed immediately. The frequency returns to its normal state.
*@param pTask the periodic Task.
*/
void cairo_dock_launch_task (CairoDockTask *pTask);
/** Same as above but after a delay.
*@param pTask the periodic Task.
*@param fDelay delay in ms.
*/
void cairo_dock_launch_task_delayed (CairoDockTask *pTask, double fDelay);
/** Create a periodic Task.
*@param iPeriod time between 2 iterations, possibly nul for a Task to be executed once only.
*@param get_data asynchonous function, which carries out the heavy job parallel to the dock; stores the results in the shared memory.
*@param update synchonous function, which carries out the update of the dock from the result of the previous function. Returns TRUE to continue, FALSE to stop.
*@param free_data function called when the Task is destroyed, to free the shared memory (optionnal).
*@param pSharedMemory structure passed as a parameter of the get_data and update functions. Must not be accessed outside of these functions !
*@return the newly allocated Task, ready to be launched with #cairo_dock_launch_task. Free it with #cairo_dock_free_task.
*/
CairoDockTask *cairo_dock_new_task_full (int iPeriod, CairoDockGetDataAsyncFunc get_data, CairoDockUpdateSyncFunc update, GFreeFunc free_data, gpointer pSharedMemory);
/** Create a periodic Task.
*@param iPeriod time between 2 iterations, possibly nul for a Task to be executed once only.
*@param get_data asynchonous function, which carries out the heavy job parallel to the dock; stores the results in the shared memory.
*@param update synchonous function, which carries out the update of the dock from the result of the previous function. Returns TRUE to continue, FALSE to stop.
*@param pSharedMemory structure passed as a parameter of the get_data and update functions. Must not be accessed outside of these functions !
*@return the newly allocated Task, ready to be launched with #cairo_dock_launch_task. Free it with #cairo_dock_free_task.
*/
#define cairo_dock_new_task(iPeriod, get_data, update, pSharedMemory) cairo_dock_new_task_full (iPeriod, get_data, update, NULL, pSharedMemory)
/** Stop a periodic Task. If the Task is running, it will wait until the asynchronous thread has finished, and skip the update. The Task can be launched again with a call to #cairo_dock_launch_task.
*@param pTask the periodic Task.
*/
void cairo_dock_stop_task (CairoDockTask *pTask);
/** Discard a periodic Task. The asynchronous thread will continue, and the Task will be freed when it ends. Use this function carefully, since you don't know when the free will occur (especially if you've set a free_data callback). The Task should be considered as destroyed after a call to this function.
*@param pTask the periodic Task.
*/
void cairo_dock_discard_task (CairoDockTask *pTask);
/** Stop and destroy a periodic Task, freeing all the allocated ressources. Unlike \ref cairo_dock_discard_task, the task is stopped before being freeed, so this is a blocking call. If you want to destroy the task inside the update callback, don't use this function; use \ref cairo_dock_discard_task instead.
*@param pTask the periodic Task.
*/
void cairo_dock_free_task (CairoDockTask *pTask);
/** Tell if a Task is active, that is to say is periodically called.
*@param pTask the periodic Task.
*@return TRUE if the Task is active.
*/
gboolean cairo_dock_task_is_active (CairoDockTask *pTask);
/** Tell if a Task is running, that is to say it is either in the thread or waiting for the update.
*@param pTask the periodic Task.
*@return TRUE if the Task is running.
*/
gboolean cairo_dock_task_is_running (CairoDockTask *pTask);
/** Change the frequency of a Task. The next iteration is re-scheduled according to the new period.
*@param pTask the periodic Task.
*@param iNewPeriod the new period between 2 iterations of the Task, in s.
*/
void cairo_dock_change_task_frequency (CairoDockTask *pTask, int iNewPeriod);
/** Change the frequency of a Task and relaunch it immediately. The next iteration is therefore immediately executed.
*@param pTask the periodic Task.
*@param iNewPeriod the new period between 2 iterations of the Task, in s, or -1 to let it unchanged.
*/
void cairo_dock_relaunch_task_immediately (CairoDockTask *pTask, int iNewPeriod);
/** Downgrade the frequency of a Task. The Task will be executed less often (this is typically useful to put on stand-by a periodic measure).
*@param pTask the periodic Task.
*/
void cairo_dock_downgrade_task_frequency (CairoDockTask *pTask);
/** Set the frequency of the Task to its normal state. This is also done automatically when launching the Task.
*@param pTask the periodic Task.
*/
void cairo_dock_set_normal_task_frequency (CairoDockTask *pTask);
/** Get the time elapsed since the last time the Task has run.
*@param pTask the periodic Task.
*/
#define cairo_dock_get_task_elapsed_time(pTask) (pTask->fElapsedTime)
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-opengl.c 000664 001750 001750 00000015142 12223247550 022230 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include // gluLookAt
#include "cairo-dock-log.h"
#include "cairo-dock-icon-facility.h" // cairo_dock_get_icon_extent
#include "cairo-dock-draw-opengl.h"
#include "cairo-dock-desktop-manager.h" // desktop dimensions
#include "cairo-dock-opengl.h"
// public (manager, config, data)
CairoDockGLConfig g_openglConfig;
gboolean g_bUseOpenGL = FALSE;
// dependencies
extern GldiDesktopBackground *g_pFakeTransparencyDesktopBg;
// private
static GldiGLManagerBackend s_backend;
gboolean gldi_gl_backend_init (gboolean bForceOpenGL)
{
memset (&g_openglConfig, 0, sizeof (CairoDockGLConfig));
g_bUseOpenGL = FALSE;
if (s_backend.init)
g_bUseOpenGL = s_backend.init (bForceOpenGL);
return g_bUseOpenGL;
}
void gldi_gl_backend_deactivate (void)
{
if (g_bUseOpenGL && s_backend.stop)
s_backend.stop ();
g_bUseOpenGL = FALSE;
}
void gldi_gl_backend_force_indirect_rendering (void)
{
if (g_bUseOpenGL)
g_openglConfig.bIndirectRendering = TRUE;
}
static inline void _cairo_dock_set_perspective_view (int iWidth, int iHeight)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0*(GLfloat)iWidth/(GLfloat)iHeight, 1., 4*iHeight);
glViewport(0, 0, iWidth, iHeight);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt (0, 0, 3., 0, 0, 0., 0.0f, 1.0f, 0.0f);
//gluLookAt (0/2, 0/2, 3., 0/2, 0/2, 0., 0.0f, 1.0f, 0.0f);
glTranslatef (0., 0., -iHeight*(sqrt(3)/2) - 1);
//glTranslatef (iWidth/2, iHeight/2, -iHeight*(sqrt(3)/2) - 1);
}
void cairo_dock_set_perspective_view (GldiContainer *pContainer)
{
int w, h;
if (pContainer->bIsHorizontal)
{
w = pContainer->iWidth;
h = pContainer->iHeight;
}
else
{
w = pContainer->iHeight;
h = pContainer->iWidth;
}
_cairo_dock_set_perspective_view (w, h);
pContainer->bPerspectiveView = TRUE;
}
void cairo_dock_set_perspective_view_for_icon (Icon *pIcon, G_GNUC_UNUSED GldiContainer *pContainer)
{
int w, h;
cairo_dock_get_icon_extent (pIcon, &w, &h);
_cairo_dock_set_perspective_view (w, h);
}
static inline void _cairo_dock_set_ortho_view (int iWidth, int iHeight)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, iWidth, 0, iHeight, 0.0, 500.0);
glViewport(0, 0, iWidth, iHeight);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt (0/2, 0/2, 3.,
0/2, 0/2, 0.,
0.0f, 1.0f, 0.0f);
glTranslatef (iWidth/2, iHeight/2, - iHeight/2);
}
void cairo_dock_set_ortho_view (GldiContainer *pContainer)
{
int w, h;
if (pContainer->bIsHorizontal)
{
w = pContainer->iWidth;
h = pContainer->iHeight;
}
else
{
w = pContainer->iHeight;
h = pContainer->iWidth;
}
_cairo_dock_set_ortho_view (w, h);
pContainer->bPerspectiveView = FALSE;
}
void cairo_dock_set_ortho_view_for_icon (Icon *pIcon, G_GNUC_UNUSED GldiContainer *pContainer)
{
int w, h;
cairo_dock_get_icon_extent (pIcon, &w, &h);
_cairo_dock_set_ortho_view (w, h);
}
gboolean gldi_gl_container_make_current (GldiContainer *pContainer)
{
if (s_backend.container_make_current)
return s_backend.container_make_current (pContainer);
return FALSE;
}
static void _apply_desktop_background (GldiContainer *pContainer)
{
if (/**! myContainersParam.bUseFakeTransparency || */! g_pFakeTransparencyDesktopBg || g_pFakeTransparencyDesktopBg->iTexture == 0)
return ;
glPushMatrix ();
gboolean bSetPerspective = pContainer->bPerspectiveView;
if (bSetPerspective)
cairo_dock_set_ortho_view (pContainer);
glLoadIdentity ();
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_source ();
_cairo_dock_set_alpha (1.);
glBindTexture (GL_TEXTURE_2D, g_pFakeTransparencyDesktopBg->iTexture);
double x, y, w, h, W, H;
W = gldi_desktop_get_width();
H = gldi_desktop_get_height();
if (pContainer->bIsHorizontal)
{
w = pContainer->iWidth;
h = pContainer->iHeight;
x = pContainer->iWindowPositionX;
y = pContainer->iWindowPositionY;
}
else
{
h = pContainer->iWidth;
w = pContainer->iHeight;
y = pContainer->iWindowPositionX;
x = pContainer->iWindowPositionY;
}
glBegin(GL_QUADS);
glTexCoord2f ((x + 0) / W, (y + 0) / H);
glVertex3f (0., h, 0.); // Top Left.
glTexCoord2f ((x + w) / W, (y + 0) / H);
glVertex3f (w, h, 0.); // Top Right
glTexCoord2f ((x + w) / W, (y + h) / H);
glVertex3f (w, 0., 0.); // Bottom Right
glTexCoord2f ((x + 0.) / W, (y + h) / H);
glVertex3f (0., 0., 0.); // Bottom Left
glEnd();
_cairo_dock_disable_texture ();
if (bSetPerspective)
cairo_dock_set_perspective_view (pContainer);
glPopMatrix ();
}
gboolean gldi_gl_container_begin_draw_full (GldiContainer *pContainer, GdkRectangle *pArea, gboolean bClear)
{
if (! gldi_gl_container_make_current (pContainer))
return FALSE;
glLoadIdentity ();
if (pArea != NULL)
{
glEnable (GL_SCISSOR_TEST); // ou comment diviser par 4 l'occupation CPU !
glScissor ((int) pArea->x,
(int) (pContainer->bIsHorizontal ? pContainer->iHeight : pContainer->iWidth) -
pArea->y - pArea->height, // lower left corner of the scissor box.
(int) pArea->width,
(int) pArea->height);
}
if (bClear)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_apply_desktop_background (pContainer);
}
return TRUE;
}
void gldi_gl_container_end_draw (GldiContainer *pContainer)
{
glDisable (GL_SCISSOR_TEST);
if (s_backend.container_end_draw)
s_backend.container_end_draw (pContainer);
}
void gldi_gl_container_init (GldiContainer *pContainer)
{
if (g_bUseOpenGL && s_backend.container_init)
s_backend.container_init (pContainer);
}
void gldi_gl_container_finish (GldiContainer *pContainer)
{
if (g_bUseOpenGL && s_backend.container_finish)
s_backend.container_finish (pContainer);
}
void gldi_gl_manager_register_backend (GldiGLManagerBackend *pBackend)
{
gpointer *ptr = (gpointer*)&s_backend;
gpointer *src = (gpointer*)pBackend;
gpointer *src_end = (gpointer*)(pBackend + 1);
while (src != src_end)
{
if (*src != NULL)
*ptr = *src;
src ++;
ptr ++;
}
}
cairo-dock-3.3.2/src/gldit/cairo-dock-user-icon-manager.c 000664 001750 001750 00000023165 12223247550 024264 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include "cairo-dock-icon-facility.h" // cairo_dock_compare_icons_order
#include "cairo-dock-log.h"
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-dock-facility.h" // cairo_dock_update_dock_size
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-themes-manager.h" // cairo_dock_delete_conf_file
#include "cairo-dock-launcher-manager.h"
#include "cairo-dock-stack-icon-manager.h"
#include "cairo-dock-separator-manager.h"
#define _MANAGER_DEF_
#include "cairo-dock-user-icon-manager.h"
// public (manager, config, data)
GldiObjectManager myUserIconObjectMgr;
// dependancies
extern gchar *g_cCurrentLaunchersPath;
// private
Icon *gldi_user_icon_new (const gchar *cConfFile)
{
gchar *cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, cConfFile);
GKeyFile* pKeyFile = cairo_dock_open_key_file (cDesktopFilePath);
g_return_val_if_fail (pKeyFile != NULL, NULL);
Icon *pIcon = NULL;
//\__________________ get the type of the icon
int iType;
if (g_key_file_has_key (pKeyFile, "Desktop Entry", "Icon Type", NULL))
{
iType = g_key_file_get_integer (pKeyFile, "Desktop Entry", "Icon Type", NULL);
}
else // old desktop file
{
gchar *cCommand = g_key_file_get_string (pKeyFile, "Desktop Entry", "Exec", NULL);
gboolean bIsContainer;
if (g_key_file_has_key (pKeyFile, "Desktop Entry", "Is container", NULL))
bIsContainer = g_key_file_get_boolean (pKeyFile, "Desktop Entry", "Is container", NULL);
else if (g_key_file_has_key (pKeyFile, "Desktop Entry", "Nb subicons", NULL))
bIsContainer = (g_key_file_get_integer (pKeyFile, "Desktop Entry", "Nb subicons", NULL) != 0);
else
bIsContainer = (g_key_file_get_integer (pKeyFile, "Desktop Entry", "Type", NULL) == 1);
if (bIsContainer)
{
iType = GLDI_USER_ICON_TYPE_STACK;
}
else if (cCommand == NULL || *cCommand == '\0')
{
iType = GLDI_USER_ICON_TYPE_SEPARATOR;
}
else
{
iType = GLDI_USER_ICON_TYPE_LAUNCHER;
}
g_key_file_set_integer (pKeyFile, "Desktop Entry", "Icon Type", iType); // the specialized manager will update the conf-file because the version has changed.
g_free (cCommand);
}
//\__________________ make an icon for the given type
GldiObjectManager *pMgr = NULL;
switch (iType)
{
case GLDI_USER_ICON_TYPE_LAUNCHER:
pMgr = &myLauncherObjectMgr;
break;
case GLDI_USER_ICON_TYPE_STACK:
pMgr = &myStackIconObjectMgr;
break;
case GLDI_USER_ICON_TYPE_SEPARATOR:
pMgr = &mySeparatorIconObjectMgr;
break;
default:
cd_warning ("unknown user icon type for file %s", cDesktopFilePath);
return NULL;
}
GldiUserIconAttr attr;
memset (&attr, 0, sizeof (attr));
attr.cConfFileName = (gchar*)cConfFile;
attr.pKeyFile = pKeyFile;
pIcon = (Icon*)gldi_object_new (pMgr, &attr);
g_free (cDesktopFilePath);
g_key_file_free (pKeyFile);
return pIcon;
}
void gldi_user_icons_new_from_directory (const gchar *cDirectory)
{
cd_message ("%s (%s)", __func__, cDirectory);
GDir *dir = g_dir_open (cDirectory, 0, NULL);
g_return_if_fail (dir != NULL);
Icon* icon;
const gchar *cFileName;
CairoDock *pParentDock;
while ((cFileName = g_dir_read_name (dir)) != NULL)
{
if (g_str_has_suffix (cFileName, ".desktop"))
{
icon = gldi_user_icon_new (cFileName);
if (icon == NULL || icon->cDesktopFileName == NULL) // if the icon couldn't be loaded, remove it from the theme (it's useless to try and fail to load it each time).
{
if (icon)
gldi_object_unref (GLDI_OBJECT(icon));
cd_warning ("Unable to load a valid icon from '%s/%s'; the file is either unreadable, unvalid or does not correspond to any installed program, and will be deleted", g_cCurrentLaunchersPath, cFileName);
gchar *cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, cFileName);
cairo_dock_delete_conf_file (cDesktopFilePath);
g_free (cDesktopFilePath);
continue;
}
pParentDock = gldi_dock_get (icon->cParentDockName);
if (pParentDock != NULL) // a priori toujours vrai.
{
gldi_icon_insert_in_container (icon, CAIRO_CONTAINER(pParentDock), ! CAIRO_DOCK_ANIMATE_ICON);
}
}
}
g_dir_close (dir);
}
static void init_object (GldiObject *obj, gpointer attr)
{
Icon *icon = (Icon*)obj;
GldiUserIconAttr *pAttributes = (GldiUserIconAttr*)attr;
if (! pAttributes->pKeyFile && pAttributes->cConfFileName)
{
gchar *cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, pAttributes->cConfFileName);
pAttributes->pKeyFile = cairo_dock_open_key_file (cDesktopFilePath);
g_free (cDesktopFilePath);
}
if (!pAttributes->pKeyFile)
return;
// get generic parameters
GKeyFile *pKeyFile = pAttributes->pKeyFile;
icon->fOrder = g_key_file_get_double (pKeyFile, "Desktop Entry", "Order", NULL);
icon->cParentDockName = g_key_file_get_string (pKeyFile, "Desktop Entry", "Container", NULL);
if (icon->cParentDockName == NULL || *icon->cParentDockName == '\0')
{
g_free (icon->cParentDockName);
icon->cParentDockName = g_strdup (CAIRO_DOCK_MAIN_DOCK_NAME);
}
int iSpecificDesktop = g_key_file_get_integer (pKeyFile, "Desktop Entry", "ShowOnViewport", NULL);
cairo_dock_set_specified_desktop_for_icon (icon, iSpecificDesktop);
icon->cDesktopFileName = g_strdup (pAttributes->cConfFileName);
// create its parent dock
CairoDock *pParentDock = gldi_dock_get (icon->cParentDockName);
if (pParentDock == NULL)
{
cd_message ("The parent dock (%s) doesn't exist: we create it", icon->cParentDockName);
pParentDock = gldi_dock_new (icon->cParentDockName);
}
}
static void reset_object (GldiObject *obj)
{
Icon *icon = (Icon*)obj;
g_free (icon->cDesktopFileName);
icon->cDesktopFileName = NULL;
}
static gboolean delete_object (GldiObject *obj)
{
Icon *icon = (Icon*)obj;
if (icon->cDesktopFileName != NULL && icon->cDesktopFileName[0] != '/') /// TODO: check that the 2nd condition is not needed any more...
{
gchar *cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, icon->cDesktopFileName);
cairo_dock_delete_conf_file (cDesktopFilePath);
g_free (cDesktopFilePath);
}
return TRUE;
}
static GKeyFile* reload_object (GldiObject *obj, gboolean bReloadConf, GKeyFile *pKeyFile)
{
Icon *icon = (Icon*)obj;
if (!bReloadConf) // just reload the icon buffers.
{
if (GLDI_OBJECT_IS_DOCK (icon->pContainer))
cairo_dock_set_icon_size_in_dock (CAIRO_DOCK(icon->pContainer), icon);
cairo_dock_load_icon_buffers (icon, icon->pContainer);
return NULL;
}
gchar *cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, icon->cDesktopFileName);
pKeyFile = cairo_dock_open_key_file (cDesktopFilePath);
g_return_val_if_fail (pKeyFile != NULL, NULL);
//\_____________ remember current state.
CairoDock *pDock = CAIRO_DOCK (cairo_dock_get_icon_container (icon));
double fOrder = icon->fOrder;
//\_____________ get its new params.
icon->fOrder = g_key_file_get_double (pKeyFile, "Desktop Entry", "Order", NULL);
g_free (icon->cParentDockName);
icon->cParentDockName = g_key_file_get_string (pKeyFile, "Desktop Entry", "Container", NULL);
if (icon->cParentDockName == NULL || *icon->cParentDockName == '\0')
{
g_free (icon->cParentDockName);
icon->cParentDockName = g_strdup (CAIRO_DOCK_MAIN_DOCK_NAME);
}
int iSpecificDesktop = g_key_file_get_integer (pKeyFile, "Desktop Entry", "ShowOnViewport", NULL);
cairo_dock_set_specified_desktop_for_icon (icon, iSpecificDesktop);
// get its (possibly new) container.
CairoDock *pNewDock = gldi_dock_get (icon->cParentDockName);
if (pNewDock == NULL)
{
cd_message ("The parent dock (%s) doesn't exist, we create it", icon->cParentDockName);
pNewDock = gldi_dock_new (icon->cParentDockName);
}
g_return_val_if_fail (pNewDock != NULL, pKeyFile);
//\_____________ manage the change of container or order.
if (pDock != pNewDock || icon->fOrder != fOrder)
{
gldi_icon_detach (icon);
gldi_icon_insert_in_container (icon, CAIRO_CONTAINER(pNewDock), CAIRO_DOCK_ANIMATE_ICON); // le remove et le insert vont declencher le redessin de l'icone pointant sur l'ancien et le nouveau sous-dock le cas echeant.
}
else if (pNewDock->iRefCount != 0) // on redessine l'icone pointant sur le sous-dock, pour le cas ou l'image ou l'ordre de l'icone aurait change.
{
cairo_dock_trigger_redraw_subdock_content (pNewDock);
}
g_free (cDesktopFilePath);
return pKeyFile;
}
void gldi_register_user_icons_manager (void)
{
// Manager
memset (&myUserIconObjectMgr, 0, sizeof (GldiObjectManager));
myUserIconObjectMgr.cName = "User-Icons";
myUserIconObjectMgr.iObjectSize = sizeof (GldiUserIcon);
// interface
myUserIconObjectMgr.init_object = init_object;
myUserIconObjectMgr.reset_object = reset_object;
myUserIconObjectMgr.delete_object = delete_object;
myUserIconObjectMgr.reload_object = reload_object;
// signals
gldi_object_install_notifications (&myUserIconObjectMgr, NB_NOTIFICATIONS_USER_ICON);
// parent object
gldi_object_set_manager (GLDI_OBJECT (&myUserIconObjectMgr), &myIconObjectMgr);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-separator-manager.h 000664 001750 001750 00000004433 12223247550 024362 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_SEPARATOR_MANAGER__
#define __CAIRO_DOCK_SEPARATOR_MANAGER__
#include "cairo-dock-struct.h"
#include "cairo-dock-user-icon-manager.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-separator-manager.h This class handles the Separator Icons, which are user icons doing nothing.
*/
// manager
typedef GldiUserIconAttr GldiSeparatorIconAttr;
typedef GldiUserIcon GldiSeparatorIcon;
#ifndef _MANAGER_DEF_
extern GldiObjectManager mySeparatorIconObjectMgr;
#endif
// signals
typedef enum {
NB_NOTIFICATIONS_SEPARATOR_ICON = NB_NOTIFICATIONS_USER_ICON,
} GldiSeparatorIconNotifications;
/** Say if an object is a SeparatorIcon.
*@param obj the object.
*@return TRUE if the object is a SeparatorIcon.
*/
#define GLDI_OBJECT_IS_SEPARATOR_ICON(obj) gldi_object_is_manager_child (GLDI_OBJECT(obj), &mySeparatorIconObjectMgr)
#define GLDI_OBJECT_IS_USER_SEPARATOR_ICON(obj) (GLDI_OBJECT_IS_SEPARATOR_ICON(obj) && ((GldiSeparatorIcon*)obj)->cDesktopFileName != NULL)
#define GLDI_OBJECT_IS_AUTO_SEPARATOR_ICON(obj) (GLDI_OBJECT_IS_SEPARATOR_ICON(obj) && ((GldiSeparatorIcon*)obj)->cDesktopFileName == NULL)
Icon *gldi_separator_icon_new (const gchar *cConfFile, GKeyFile *pKeyFile);
Icon *gldi_auto_separator_icon_new (Icon *icon, Icon *pNextIcon);
void gldi_automatic_separators_add_in_list (GList *pIconsList);
gchar *gldi_separator_icon_add_conf_file (const gchar *cDockName, double fOrder);
Icon *gldi_separator_icon_add_new (CairoDock *pDock, double fOrder);
void gldi_register_separator_icons_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-themes-manager.c 000664 001750 001750 00000071664 12223247550 023654 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#define __USE_XOPEN_EXTENDED
#include
#include
#define __USE_POSIX
#include
#include
#include
#include "gldi-config.h"
#include "cairo-dock-config.h"
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-file-manager.h" // cairo_dock_copy_file
#include "cairo-dock-launcher-manager.h" // cairo_dock_get_command_with_right_terminal
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-module-manager.h" // gldi_module_foreach
#include "cairo-dock-backends-manager.h"
#include "cairo-dock-dialog-manager.h"
#include "cairo-dock-icon-facility.h" // gldi_icons_get_any_without_dialog
#include "cairo-dock-task.h"
#include "cairo-dock-log.h"
#include "cairo-dock-utils.h" // cairo_dock_get_command_with_right_terminal
#include "cairo-dock-packages.h"
#include "cairo-dock-core.h"
#include "cairo-dock-applications-manager.h" // cairo_dock_get_current_active_icon
#include "cairo-dock-dock-facility.h"
#include "cairo-dock-themes-manager.h"
// public data
gchar *g_cCairoDockDataDir = NULL; // le repertoire racine contenant tout.
gchar *g_cCurrentThemePath = NULL; // le chemin vers le repertoire du theme courant.
gchar *g_cExtrasDirPath = NULL; // le chemin vers le repertoire des extra.
gchar *g_cThemesDirPath = NULL; // le chemin vers le repertoire des themes.
gchar *g_cCurrentLaunchersPath = NULL; // le chemin vers le repertoire des lanceurs du theme courant.
gchar *g_cCurrentIconsPath = NULL; // le chemin vers le repertoire des icones du theme courant.
gchar *g_cCurrentImagesPath = NULL; // le chemin vers le repertoire des images ou autre du theme courant.
gchar *g_cCurrentPlugInsPath = NULL; // le chemin vers le repertoire des plug-ins du theme courant.
gchar *g_cConfFile = NULL; // le chemin du fichier de conf.
// private
static gchar *s_cLocalThemeDirPath = NULL;
static gchar *s_cDistantThemeDirName = NULL;
#define CAIRO_DOCK_MODIFIED_THEME_FILE ".cairo-dock-need-save"
#define CAIRO_DOCK_LOCAL_EXTRAS_DIR "extras"
#define CAIRO_DOCK_LAUNCHERS_DIR "launchers"
#define CAIRO_DOCK_PLUG_INS_DIR "plug-ins"
#define CAIRO_DOCK_LOCAL_ICONS_DIR "icons"
#define CAIRO_DOCK_LOCAL_IMAGES_DIR "images"
// dependancies
//extern gboolean g_bUseOpenGL;
extern CairoDock *g_pMainDock;
static gchar * _replace_slash_by_underscore (gchar *cName)
{
g_return_val_if_fail (cName != NULL, NULL);
for (int i = 0; cName[i] != '\0'; i++)
{
if (cName[i] == '/' || cName[i] == '$')
cName[i] = '_';
}
return cName;
}
/** Escapes the special characters '\b', '\f', '\n', '\r', '\t', '\v', '\' and '"' in the string source by inserting a '\' before them and replaces '/' and '$' by '_'
* @param cOldName name of a filename
* @return a newly-allocated copy of source with certain characters escaped. See above.
*/
static gchar * _escape_string_for_filename (const gchar *cOldName)
{
gchar *cNewName = g_strescape (cOldName, NULL);
return _replace_slash_by_underscore (cNewName);
}
static void cairo_dock_mark_current_theme_as_modified (gboolean bModified)
{
static int state = -1;
if (state == -1)
state = cairo_dock_current_theme_need_save ();
if (state != bModified)
{
state = bModified;
gchar *cModifiedFile = g_strdup_printf ("%s/%s", g_cCairoDockDataDir, CAIRO_DOCK_MODIFIED_THEME_FILE);
g_file_set_contents (cModifiedFile,
(bModified ? "1" : "0"),
-1,
NULL);
g_free (cModifiedFile);
}
}
gboolean cairo_dock_current_theme_need_save (void)
{
gchar *cModifiedFile = g_strdup_printf ("%s/%s", g_cCairoDockDataDir, CAIRO_DOCK_MODIFIED_THEME_FILE);
gsize length = 0;
gchar *cContent = NULL;
g_file_get_contents (cModifiedFile,
&cContent,
&length,
NULL);
g_free (cModifiedFile);
gboolean bNeedSave;
if (length > 0)
bNeedSave = (*cContent == '1');
else
bNeedSave = FALSE;
g_free (cContent);
return bNeedSave;
}
void cairo_dock_delete_conf_file (const gchar *cConfFilePath)
{
g_remove (cConfFilePath);
cairo_dock_mark_current_theme_as_modified (TRUE);
}
gboolean cairo_dock_add_conf_file (const gchar *cOriginalConfFilePath, const gchar *cConfFilePath)
{
gboolean r = cairo_dock_copy_file (cOriginalConfFilePath, cConfFilePath);
if (r)
cairo_dock_mark_current_theme_as_modified (TRUE);
return r;
}
void cairo_dock_update_conf_file (const gchar *cConfFilePath, GType iFirstDataType, ...)
{
va_list args;
va_start (args, iFirstDataType);
cairo_dock_update_keyfile_va_args (cConfFilePath, iFirstDataType, args);
va_end (args);
cairo_dock_mark_current_theme_as_modified (TRUE);
}
void cairo_dock_write_keys_to_conf_file (GKeyFile *pKeyFile, const gchar *cConfFilePath)
{
cairo_dock_write_keys_to_file (pKeyFile, cConfFilePath);
cairo_dock_mark_current_theme_as_modified (TRUE);
}
gboolean cairo_dock_export_current_theme (const gchar *cNewThemeName, gboolean bSaveBehavior, gboolean bSaveLaunchers)
{
g_return_val_if_fail (cNewThemeName != NULL, FALSE);
gchar *cNewThemeNameWithoutSlashes = _replace_slash_by_underscore (g_strdup (cNewThemeName));
cairo_dock_extract_package_type_from_name (cNewThemeNameWithoutSlashes);
gchar *cNewThemeNameEscaped = g_strescape (cNewThemeNameWithoutSlashes, NULL);
cd_message ("we save in %s", cNewThemeNameWithoutSlashes);
GString *sCommand = g_string_new ("");
gboolean bThemeSaved = FALSE;
int r;
gchar *cNewThemePath = g_strdup_printf ("%s/%s", g_cThemesDirPath, cNewThemeNameWithoutSlashes);
gchar *cNewThemePathEscaped = g_strdup_printf ("%s/%s", g_cThemesDirPath, cNewThemeNameEscaped);
if (g_file_test (cNewThemePath, G_FILE_TEST_EXISTS)) // on ecrase un theme existant.
{
cd_debug (" This theme will be updated");
gchar *cQuestion = g_strdup_printf (_("Are you sure you want to overwrite theme %s?"), cNewThemeName);
Icon *pIcon = cairo_dock_get_current_active_icon (); // it's most probably the icon corresponding to the configuration window
if (pIcon == NULL || cairo_dock_get_icon_container (pIcon) == NULL) // if not available, get any icon
pIcon = gldi_icons_get_any_without_dialog ();
cd_debug ("%s", pIcon->cName);
int iClickedButton = gldi_dialog_show_and_wait (cQuestion,
pIcon, CAIRO_CONTAINER (g_pMainDock),
GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_ICON, NULL);
g_free (cQuestion);
if (iClickedButton == 0 || iClickedButton == -1) // ok button or Enter.
{
//\___________________ On traite le fichier de conf global et ceux des docks principaux.
gchar *cNewConfFilePath = g_strdup_printf ("%s/%s", cNewThemePath, CAIRO_DOCK_CONF_FILE);
if (bSaveBehavior)
{
cairo_dock_copy_file (g_cConfFile, cNewConfFilePath);
}
else
{
cairo_dock_merge_conf_files (cNewConfFilePath, g_cConfFile, '+');
}
g_free (cNewConfFilePath);
//\___________________ On traite les lanceurs.
if (bSaveLaunchers)
{
g_string_printf (sCommand, "rm -f \"%s/%s\"/*", cNewThemePathEscaped, CAIRO_DOCK_LAUNCHERS_DIR);
cd_message ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
g_string_printf (sCommand, "cp \"%s\"/* \"%s/%s\"", g_cCurrentLaunchersPath, cNewThemePathEscaped, CAIRO_DOCK_LAUNCHERS_DIR);
cd_message ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
}
//\___________________ On traite tous le reste.
/// TODO : traiter les .conf des applets comme celui du dock...
g_string_printf (sCommand, "find \"%s\" -mindepth 1 -maxdepth 1 ! -name '%s' ! -name \"%s\" -exec /bin/cp -r '{}' \"%s\" \\;", g_cCurrentThemePath, CAIRO_DOCK_CONF_FILE, CAIRO_DOCK_LAUNCHERS_DIR, cNewThemePathEscaped);
cd_message ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
bThemeSaved = TRUE;
}
}
else // sinon on sauvegarde le repertoire courant tout simplement.
{
cd_debug (" creation of the new theme (%s)", cNewThemePath);
if (g_mkdir (cNewThemePath, 7*8*8+7*8+5) == 0)
{
g_string_printf (sCommand, "cp -r \"%s\"/* \"%s\"", g_cCurrentThemePath, cNewThemePathEscaped);
cd_message ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
bThemeSaved = TRUE;
}
else
cd_warning ("couldn't create %s", cNewThemePath);
}
g_free (cNewThemeNameEscaped);
g_free (cNewThemeNameWithoutSlashes);
//\___________________ On conserve la date de derniere modif.
time_t epoch = (time_t) time (NULL);
struct tm currentTime;
localtime_r (&epoch, ¤tTime);
char cDateBuffer[50+1];
strftime (cDateBuffer, 50, "%a %d %b %Y, %R", ¤tTime);
gchar *cMessage = g_strdup_printf ("%s\n %s", _("Last modification on:"), cDateBuffer);
gchar *cReadmeFile = g_strdup_printf ("%s/%s", cNewThemePath, "readme");
g_file_set_contents (cReadmeFile,
cMessage,
-1,
NULL);
g_free (cReadmeFile);
g_free (cMessage);
g_string_printf (sCommand, "rm -f \"%s/last-modif\"", cNewThemePathEscaped);
r = system (sCommand->str);
//\___________________ make a preview of the current main dock.
gchar *cPreviewPath = g_strdup_printf ("%s/preview", cNewThemePath);
cairo_dock_make_preview (g_pMainDock, cPreviewPath);
g_free (cPreviewPath);
//\___________________ Le theme n'est plus en etat 'modifie'.
g_free (cNewThemePath);
g_free (cNewThemePathEscaped);
if (bThemeSaved)
{
cairo_dock_mark_current_theme_as_modified (FALSE);
}
g_string_free (sCommand, TRUE);
return bThemeSaved;
}
gboolean cairo_dock_package_current_theme (const gchar *cThemeName, const gchar *cDirPath)
{
g_return_val_if_fail (cThemeName != NULL, FALSE);
gboolean bSuccess = FALSE;
gchar *cNewThemeName = _escape_string_for_filename (cThemeName);
if (cDirPath == NULL || *cDirPath == '\0'
|| (g_file_test (cDirPath, G_FILE_TEST_EXISTS) && g_file_test (cDirPath, G_FILE_TEST_IS_REGULAR))) // exist but not a directory
cDirPath = g_getenv ("HOME");
cairo_dock_extract_package_type_from_name (cNewThemeName);
cd_message ("building theme package ...");
const gchar *cPackageBuilderPath = GLDI_SHARE_DATA_DIR"/scripts/cairo-dock-package-theme.sh";
gboolean bScriptFound = g_file_test (cPackageBuilderPath, G_FILE_TEST_EXISTS);
if (bScriptFound)
{
int r;
gchar *cCommand = g_strdup_printf ("%s '%s' \"%s\"",
cPackageBuilderPath, cNewThemeName, cDirPath);
gchar *cFullCommand = cairo_dock_get_command_with_right_terminal (cCommand);
r = system (cFullCommand); // we need to wait...
if (r != 0)
{
cd_warning ("Not able to launch this command: %s, retry without external terminal", cFullCommand);
r = system (cCommand); // relaunch it without the terminal and wait
if (r != 0)
cd_warning ("Not able to launch this command: %s", cCommand);
else
bSuccess = TRUE;
}
else
bSuccess = TRUE;
g_free (cCommand);
g_free (cFullCommand);
}
else
cd_warning ("the package builder script was not found !");
if (bSuccess)
{
gchar *cGeneralMessage = g_strdup_printf ("%s %s", _("Your theme should now be available in this directory:"), cDirPath);
gldi_dialog_show_general_message (cGeneralMessage, 8000);
g_free (cGeneralMessage);
}
else
gldi_dialog_show_general_message (_("Error when launching 'cairo-dock-package-theme' script"), 8000);
g_free (cNewThemeName);
return bSuccess;
}
gchar *cairo_dock_depackage_theme (const gchar *cPackagePath)
{
gchar *cNewThemePath = NULL;
if (*cPackagePath == '/' || strncmp (cPackagePath, "file://", 7) == 0) // paquet en local.
{
cd_debug (" paquet local");
gchar *cFilePath = (*cPackagePath == '/' ? g_strdup (cPackagePath) : g_filename_from_uri (cPackagePath, NULL, NULL));
cNewThemePath = cairo_dock_uncompress_file (cFilePath, g_cThemesDirPath, NULL);
g_free (cFilePath);
}
else // paquet distant.
{
cd_debug (" paquet distant");
cNewThemePath = cairo_dock_download_archive (cPackagePath, g_cThemesDirPath);
if (cNewThemePath == NULL)
{
gldi_dialog_show_temporary_with_icon_printf (_("Could not access remote file %s. Maybe the server is down.\nPlease retry later or contact us at glx-dock.org."), NULL, NULL, 0, NULL, cPackagePath);
}
}
return cNewThemePath;
}
gboolean cairo_dock_delete_themes (gchar **cThemesList)
{
g_return_val_if_fail (cThemesList != NULL && cThemesList[0] != NULL, FALSE);
GString *sCommand = g_string_new ("");
gboolean bThemeDeleted = FALSE;
if (cThemesList[1] == NULL)
g_string_printf (sCommand, _("Are you sure you want to delete theme %s?"), cThemesList[0]);
else
g_string_printf (sCommand, _("Are you sure you want to delete these themes?"));
Icon *pIcon = cairo_dock_get_current_active_icon (); // it's most probably the icon corresponding to the configuration window
if (pIcon == NULL || cairo_dock_get_icon_container (pIcon) == NULL) // if not available, get any icon
pIcon = gldi_icons_get_any_without_dialog ();
int iClickedButton = gldi_dialog_show_and_wait (sCommand->str,
pIcon, cairo_dock_get_icon_container (pIcon),
GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_ICON, NULL);
if (iClickedButton == 0 || iClickedButton == -1) // ok button or Enter.
{
gchar *cThemeName;
int i, r;
for (i = 0; cThemesList[i] != NULL; i ++)
{
cThemeName = _escape_string_for_filename (cThemesList[i]);
if (*cThemeName == '\0')
{
g_free (cThemeName);
continue;
}
cairo_dock_extract_package_type_from_name (cThemeName);
bThemeDeleted = TRUE;
g_string_printf (sCommand, "rm -rf \"%s/%s\"", g_cThemesDirPath, cThemeName);
r = system (sCommand->str); // g_rmdir only delete an empty dir...
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
g_free (cThemeName);
}
}
g_string_free (sCommand, TRUE);
return bThemeDeleted;
}
static gboolean _find_module_from_user_data_dir (G_GNUC_UNUSED gchar *cModuleName, GldiModule *pModule, const gchar *cUserDataDirName)
{
if (pModule->pVisitCard->cUserDataDir && strcmp (cUserDataDirName, pModule->pVisitCard->cUserDataDir) == 0)
return TRUE;
return FALSE;
}
static gchar *_cairo_dock_get_theme_path (const gchar *cThemeName) // a theme name or a package URL, both distant or local
{
gchar *cNewThemeName = g_strdup (cThemeName);
gchar *cNewThemePath = NULL;
int length = strlen (cNewThemeName);
if (cNewThemeName[length-1] == '\n')
cNewThemeName[--length] = '\0'; // on vire le retour chariot final.
if (cNewThemeName[length-1] == '\r')
cNewThemeName[--length] = '\0';
cd_debug ("cNewThemeName : '%s'", cNewThemeName);
if (g_str_has_suffix (cNewThemeName, ".tar.gz") || g_str_has_suffix (cNewThemeName, ".tar.bz2") || g_str_has_suffix (cNewThemeName, ".tgz")) // c'est un paquet.
{
cd_debug ("it's a tarball");
cNewThemePath = cairo_dock_depackage_theme (cNewThemeName);
}
else // c'est un theme officiel.
{
cd_debug ("it's an official theme");
cNewThemePath = cairo_dock_get_package_path (cNewThemeName, s_cLocalThemeDirPath, g_cThemesDirPath, s_cDistantThemeDirName, CAIRO_DOCK_ANY_PACKAGE);
}
g_free (cNewThemeName);
return cNewThemePath;
}
static gboolean _cairo_dock_import_local_theme (const gchar *cNewThemePath, gboolean bLoadBehavior, gboolean bLoadLaunchers)
{
g_return_val_if_fail (cNewThemePath != NULL && g_file_test (cNewThemePath, G_FILE_TEST_EXISTS), FALSE);
//\___________________ On charge les parametres de comportement globaux et de chaque dock.
GString *sCommand = g_string_new ("");
int r;
cd_message ("Applying changes ...");
if (g_pMainDock == NULL || bLoadBehavior)
{
g_string_printf (sCommand, "cp \"%s\"/*.conf \"%s\"", cNewThemePath, g_cCurrentThemePath);
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
}
else
{
GDir *dir = g_dir_open (cNewThemePath, 0, NULL);
const gchar* cDockConfFile;
gchar *cThemeDockConfFile, *cUserDockConfFile;
while ((cDockConfFile = g_dir_read_name (dir)) != NULL)
{
if (g_str_has_suffix (cDockConfFile, ".conf"))
{
cThemeDockConfFile = g_strdup_printf ("%s/%s", cNewThemePath, cDockConfFile);
cUserDockConfFile = g_strdup_printf ("%s/%s", g_cCurrentThemePath, cDockConfFile);
if (g_file_test (cUserDockConfFile, G_FILE_TEST_EXISTS))
{
cairo_dock_merge_conf_files (cUserDockConfFile, cThemeDockConfFile, '+');
}
else
{
cairo_dock_copy_file (cThemeDockConfFile, cUserDockConfFile);
}
g_free (cUserDockConfFile);
g_free (cThemeDockConfFile);
}
}
g_dir_close (dir);
}
//\___________________ On charge les icones.
if (bLoadLaunchers)
{
g_string_printf (sCommand, "rm -f \"%s\"/*", g_cCurrentIconsPath);
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
g_string_printf (sCommand, "rm -f \"%s\"/.*", g_cCurrentIconsPath);
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
g_string_printf (sCommand, "rm -f \"%s\"/*", g_cCurrentImagesPath);
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
g_string_printf (sCommand, "rm -f \"%s\"/.*", g_cCurrentImagesPath);
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
}
gchar *cNewLocalIconsPath = g_strdup_printf ("%s/%s", cNewThemePath, CAIRO_DOCK_LOCAL_ICONS_DIR);
if (! g_file_test (cNewLocalIconsPath, G_FILE_TEST_IS_DIR)) // c'est un ancien theme, on deplace les icones vers le repertoire 'icons'.
{
g_string_printf (sCommand, "find \"%s/%s\" -mindepth 1 ! -name '*.desktop' -exec /bin/cp '{}' '%s' \\;", cNewThemePath, CAIRO_DOCK_LAUNCHERS_DIR, g_cCurrentIconsPath);
}
else
{
g_string_printf (sCommand, "for f in \"%s\"/* ; do rm -f \"%s/`basename \"${f%%.*}\"`\"*; done;", cNewLocalIconsPath, g_cCurrentIconsPath); // on efface les doublons car sinon on pourrait avoir x.png et x.svg ensemble et le dock ne saurait pas lequel choisir.
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
g_string_printf (sCommand, "cp \"%s\"/* \"%s\"", cNewLocalIconsPath, g_cCurrentIconsPath);
}
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
g_free (cNewLocalIconsPath);
//\___________________ On charge les extras.
g_string_printf (sCommand, "%s/%s", cNewThemePath, CAIRO_DOCK_LOCAL_EXTRAS_DIR);
if (g_file_test (sCommand->str, G_FILE_TEST_IS_DIR))
{
g_string_printf (sCommand, "cp -r \"%s/%s\"/* \"%s\"", cNewThemePath, CAIRO_DOCK_LOCAL_EXTRAS_DIR, g_cExtrasDirPath);
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
}
//\___________________ On charge les lanceurs si necessaire, en effacant ceux existants.
if (! g_file_test (g_cCurrentLaunchersPath, G_FILE_TEST_EXISTS))
{
gchar *command = g_strdup_printf ("mkdir -p \"%s\"", g_cCurrentLaunchersPath);
r = system (command);
if (r < 0)
cd_warning ("Not able to launch this command: %s", command);
g_free (command);
}
if (g_pMainDock == NULL || bLoadLaunchers)
{
g_string_printf (sCommand, "rm -f \"%s\"/*.desktop", g_cCurrentLaunchersPath);
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
g_string_printf (sCommand, "cp \"%s/%s\"/*.desktop \"%s\"", cNewThemePath, CAIRO_DOCK_LAUNCHERS_DIR, g_cCurrentLaunchersPath);
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
}
//\___________________ On remplace tous les autres fichiers par les nouveaux.
g_string_printf (sCommand, "find \"%s\" -mindepth 1 -maxdepth 1 ! -name '*.conf' -type f -exec rm -f '{}' \\;", g_cCurrentThemePath); // efface tous les fichiers du theme mais sans toucher aux lanceurs et aux plug-ins.
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
if (g_pMainDock == NULL || bLoadBehavior)
{
g_string_printf (sCommand, "find \"%s\"/* -prune ! -name '*.conf' ! -name %s -exec /bin/cp -r '{}' \"%s\" \\;", cNewThemePath, CAIRO_DOCK_LAUNCHERS_DIR, g_cCurrentThemePath); // copie tous les fichiers du nouveau theme sauf les lanceurs et le .conf, dans le repertoire du theme courant. Ecrase les fichiers de memes noms.
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
}
else
{
// on copie tous les fichiers du nouveau theme sauf les lanceurs et les .conf (dock et plug-ins).
g_string_printf (sCommand, "find \"%s\" -mindepth 1 ! -name '*.conf' ! -path '%s/%s*' ! -type d -exec cp -p {} \"%s\" \\;", cNewThemePath, cNewThemePath, CAIRO_DOCK_LAUNCHERS_DIR, g_cCurrentThemePath);
cd_debug ("%s", sCommand->str);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
// on parcours les .conf des plug-ins, on les met a jour, et on fusionne avec le theme courant.
gchar *cNewPlugInsDir = g_strdup_printf ("%s/%s", cNewThemePath, CAIRO_DOCK_PLUG_INS_DIR); // repertoire des plug-ins du nouveau theme.
GDir *dir = g_dir_open (cNewPlugInsDir, 0, NULL); // NULL si ce theme n'a pas de repertoire 'plug-ins'.
const gchar* cModuleDirName;
gchar *cConfFilePath, *cNewConfFilePath, *cUserDataDirPath, *cConfFileName;
do
{
cModuleDirName = g_dir_read_name (dir); // nom du repertoire du theme (pas forcement egal au nom du theme)
if (cModuleDirName == NULL)
break ;
// on cree le repertoire du plug-in dans le theme courant.
cd_debug (" installing %s's config", cModuleDirName);
cUserDataDirPath = g_strdup_printf ("%s/%s", g_cCurrentPlugInsPath, cModuleDirName); // repertoire du plug-in dans le theme courant.
if (! g_file_test (cUserDataDirPath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
{
cd_debug (" directory %s doesn't exist, it will be created.", cUserDataDirPath);
g_string_printf (sCommand, "mkdir -p \"%s\"", cUserDataDirPath);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
}
// on recupere le nom et le chemin du .conf du plug-in dans le nouveau theme.
cConfFileName = g_strdup_printf ("%s.conf", cModuleDirName);
cNewConfFilePath = g_strdup_printf ("%s/%s/%s", cNewPlugInsDir, cModuleDirName, cConfFileName);
if (! g_file_test (cNewConfFilePath, G_FILE_TEST_EXISTS))
{
g_free (cConfFileName);
g_free (cNewConfFilePath);
GldiModule *pModule = gldi_module_foreach ((GHRFunc) _find_module_from_user_data_dir, (gpointer) cModuleDirName);
if (pModule == NULL) // du coup, dans ce cas-la, on ne charge pas des plug-ins non utilises par l'utilisateur.
{
cd_warning ("couldn't find the module owning '%s', this file will be ignored.");
continue;
}
cConfFileName = g_strdup (pModule->pVisitCard->cConfFileName);
cNewConfFilePath = g_strdup_printf ("%s/%s/%s", cNewPlugInsDir, cModuleDirName, cConfFileName);
}
cConfFilePath = g_strdup_printf ("%s/%s", cUserDataDirPath, cConfFileName); // chemin du .conf dans le theme courant.
// on fusionne les 2 .conf.
if (! g_file_test (cConfFilePath, G_FILE_TEST_EXISTS))
{
cd_debug (" no conf file %s, we will take the theme's one", cConfFilePath);
cairo_dock_copy_file (cNewConfFilePath, cConfFilePath);
}
else
{
cairo_dock_merge_conf_files (cConfFilePath, cNewConfFilePath, '+');
}
g_free (cNewConfFilePath);
g_free (cConfFilePath);
g_free (cUserDataDirPath);
g_free (cConfFileName);
}
while (1);
g_dir_close (dir);
g_free (cNewPlugInsDir);
}
g_string_printf (sCommand, "rm -f \"%s/last-modif\"", g_cCurrentThemePath);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
// precaution probablement inutile.
g_string_printf (sCommand, "chmod -R 775 \"%s\"", g_cCurrentThemePath);
r = system (sCommand->str);
if (r < 0)
cd_warning ("Not able to launch this command: %s", sCommand->str);
cairo_dock_mark_current_theme_as_modified (FALSE);
g_string_free (sCommand, TRUE);
return TRUE;
}
gboolean cairo_dock_import_theme (const gchar *cThemeName, gboolean bLoadBehavior, gboolean bLoadLaunchers)
{
//\___________________ Get the local path of the theme (if necessary, it is downloaded and/or unzipped).
gchar *cNewThemePath = _cairo_dock_get_theme_path (cThemeName);
g_return_val_if_fail (cNewThemePath != NULL && g_file_test (cNewThemePath, G_FILE_TEST_EXISTS), FALSE);
//\___________________ import the theme in the current theme.
gboolean bSuccess = _cairo_dock_import_local_theme (cNewThemePath, bLoadBehavior, bLoadLaunchers);
g_free (cNewThemePath);
return bSuccess;
}
static void _import_theme (gpointer *pSharedMemory) // import the theme on the disk; the actual copy of the files is not done here, because we want to be able to cancel the task.
{
cd_debug ("dl start");
gchar *cNewThemePath = _cairo_dock_get_theme_path (pSharedMemory[0]);
g_free (pSharedMemory[0]);
pSharedMemory[0] = cNewThemePath;
cd_debug ("dl over");
}
static gboolean _finish_import (gpointer *pSharedMemory) // once the theme is local, we can import it in the current theme.
{
gboolean bSuccess;
if (! pSharedMemory[0])
{
cd_warning ("Couldn't download the theme.");
bSuccess = FALSE;
}
else
{
bSuccess = _cairo_dock_import_local_theme (pSharedMemory[0], GPOINTER_TO_INT (pSharedMemory[1]), GPOINTER_TO_INT (pSharedMemory[2]));
}
GFunc pCallback = pSharedMemory[3];
pCallback (GINT_TO_POINTER (bSuccess), pSharedMemory[4]);
return FALSE;
}
static void _discard_import (gpointer *pSharedMemory)
{
g_free (pSharedMemory[0]);
g_free (pSharedMemory);
}
CairoDockTask *cairo_dock_import_theme_async (const gchar *cThemeName, gboolean bLoadBehavior, gboolean bLoadLaunchers, GFunc pCallback, gpointer data)
{
gpointer *pSharedMemory = g_new0 (gpointer, 5);
pSharedMemory[0] = g_strdup (cThemeName);
pSharedMemory[1] = GINT_TO_POINTER (bLoadBehavior);
pSharedMemory[2] = GINT_TO_POINTER (bLoadLaunchers);
pSharedMemory[3] = pCallback;
pSharedMemory[4] = data;
CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _import_theme, (CairoDockUpdateSyncFunc) _finish_import, (GFreeFunc) _discard_import, pSharedMemory);
cairo_dock_launch_task (pTask);
return pTask;
}
#define _check_dir(cDirPath) \
if (! g_file_test (cDirPath, G_FILE_TEST_IS_DIR)) {\
if (g_mkdir (cDirPath, 7*8*8+7*8+7) != 0) {\
cd_warning ("couldn't create directory %s", cDirPath);\
g_free (cDirPath);\
cDirPath = NULL; } }
void cairo_dock_set_paths (gchar *cRootDataDirPath, gchar *cExtraDirPath, gchar *cThemesDirPath, gchar *cCurrentThemeDirPath, gchar *cLocalThemeDirPath, gchar *cDistantThemeDirName, gchar *cThemeServerAdress)
{
//\___________________ On initialise les chemins de l'appli.
g_cCairoDockDataDir = cRootDataDirPath; // le repertoire racine contenant tout.
_check_dir (g_cCairoDockDataDir);
g_cCurrentThemePath = cCurrentThemeDirPath; // le chemin vers le repertoire du theme courant.
_check_dir (g_cCurrentThemePath);
g_cExtrasDirPath = cExtraDirPath; // le chemin vers le repertoire des extra.
_check_dir (g_cExtrasDirPath);
g_cThemesDirPath = cThemesDirPath; // le chemin vers le repertoire des themes.
_check_dir (g_cThemesDirPath);
s_cLocalThemeDirPath = cLocalThemeDirPath;
s_cDistantThemeDirName = cDistantThemeDirName;
g_cCurrentLaunchersPath = g_strdup_printf ("%s/%s", g_cCurrentThemePath, CAIRO_DOCK_LAUNCHERS_DIR);
_check_dir (g_cCurrentLaunchersPath);
g_cCurrentIconsPath = g_strdup_printf ("%s/%s", g_cCurrentThemePath, CAIRO_DOCK_LOCAL_ICONS_DIR);
g_cCurrentImagesPath = g_strdup_printf ("%s/%s", g_cCurrentThemePath, CAIRO_DOCK_LOCAL_IMAGES_DIR);
_check_dir (g_cCurrentIconsPath);
g_cCurrentPlugInsPath = g_strdup_printf ("%s/%s", g_cCurrentThemePath, CAIRO_DOCK_PLUG_INS_DIR);
_check_dir (g_cCurrentPlugInsPath);
g_cConfFile = g_strdup_printf ("%s/%s", g_cCurrentThemePath, CAIRO_DOCK_CONF_FILE);
//\___________________ On initialise l'adresse du serveur de themes.
cairo_dock_set_packages_server (cThemeServerAdress);
}
cairo-dock-3.3.2/src/gldit/CMakeLists.txt 000664 001750 001750 00000015732 12223247550 021334 0 ustar 00mbaerts mbaerts 000000 000000
SET(core_lib_SRCS
cairo-dock-struct.h
cairo-dock-global-variables.h
cairo-dock-core.c cairo-dock-core.h
cairo-dock-manager.c cairo-dock-manager.h
cairo-dock-object.c cairo-dock-object.h
# icons
cairo-dock-icon-manager.c cairo-dock-icon-manager.h
cairo-dock-icon-factory.c cairo-dock-icon-factory.h
cairo-dock-icon-facility.c cairo-dock-icon-facility.h
cairo-dock-indicator-manager.c cairo-dock-indicator-manager.h
cairo-dock-applications-manager.c cairo-dock-applications-manager.h
cairo-dock-application-facility.c cairo-dock-application-facility.h
cairo-dock-launcher-manager.c cairo-dock-launcher-manager.h
cairo-dock-stack-icon-manager.c cairo-dock-stack-icon-manager.h
cairo-dock-class-icon-manager.c cairo-dock-class-icon-manager.h
cairo-dock-user-icon-manager.c cairo-dock-user-icon-manager.h
cairo-dock-applet-manager.c cairo-dock-applet-manager.h
cairo-dock-applet-facility.c cairo-dock-applet-facility.h
cairo-dock-separator-manager.c cairo-dock-separator-manager.h
cairo-dock-module-manager.c cairo-dock-module-manager.h
cairo-dock-module-instance-manager.c cairo-dock-module-instance-manager.h
# containers
cairo-dock-container.c cairo-dock-container.h
cairo-dock-desklet-manager.c cairo-dock-desklet-manager.h
cairo-dock-desklet-factory.c cairo-dock-desklet-factory.h
cairo-dock-dialog-factory.c cairo-dock-dialog-factory.h
cairo-dock-dialog-manager.c cairo-dock-dialog-manager.h
cairo-dock-flying-container.c cairo-dock-flying-container.h
cairo-dock-dock-manager.c cairo-dock-dock-manager.h
cairo-dock-dock-factory.c cairo-dock-dock-factory.h
cairo-dock-dock-facility.c cairo-dock-dock-facility.h
cairo-dock-dock-visibility.c cairo-dock-dock-visibility.h
cairo-dock-animations.c cairo-dock-animations.h
cairo-dock-backends-manager.c cairo-dock-backends-manager.h
cairo-dock-data-renderer.c cairo-dock-data-renderer.h
cairo-dock-data-renderer-manager.c cairo-dock-data-renderer-manager.h
cairo-dock-file-manager.c cairo-dock-file-manager.h
cairo-dock-themes-manager.c cairo-dock-themes-manager.h
cairo-dock-class-manager.c cairo-dock-class-manager.h
cairo-dock-desktop-manager.c cairo-dock-desktop-manager.h
cairo-dock-windows-manager.c cairo-dock-windows-manager.h
cairo-dock-image-buffer.c cairo-dock-image-buffer.h
cairo-dock-opengl.c cairo-dock-opengl.h
cairo-dock-opengl-path.c cairo-dock-opengl-path.h
cairo-dock-opengl-font.c cairo-dock-opengl-font.h
cairo-dock-surface-factory.c cairo-dock-surface-factory.h
cairo-dock-draw.c cairo-dock-draw.h
cairo-dock-draw-opengl.c cairo-dock-draw-opengl.h
# utilities
cairo-dock-log.c cairo-dock-log.h
cairo-dock-gui-manager.c cairo-dock-gui-manager.h
cairo-dock-gui-factory.c cairo-dock-gui-factory.h
eggaccelerators.c eggaccelerators.h
cairo-dock-keybinder.c cairo-dock-keybinder.h
cairo-dock-dbus.c cairo-dock-dbus.h
cairo-dock-keyfile-utilities.c cairo-dock-keyfile-utilities.h
cairo-dock-packages.c cairo-dock-packages.h
cairo-dock-particle-system.c cairo-dock-particle-system.h
cairo-dock-overlay.c cairo-dock-overlay.h
cairo-dock-task.c cairo-dock-task.h
cairo-dock-config.c cairo-dock-config.h
cairo-dock-utils.c cairo-dock-utils.h
cairo-dock-menu.c cairo-dock-menu.h
texture-gradation.h
texture-blur.h
)
# Gtk > 3.8
if (${GTK_MAJOR} GREATER 3 OR (${GTK_MAJOR} EQUAL 3 AND ${GTK_MINOR} GREATER 8))
LIST(APPEND core_lib_SRCS gtk3imagemenuitem.c gtk3imagemenuitem.h)
endif()
########### compilation ###############
# Make sure the compiler can find include files from the libraries.
include_directories(
${PACKAGE_INCLUDE_DIRS}
${GTK_INCLUDE_DIRS}
${XEXTEND_INCLUDE_DIRS}
${XINERAMA_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/src/gldit
${CMAKE_SOURCE_DIR}/src/implementations)
# Make sure the linker can find the libraries.
link_directories(
${PACKAGE_LIBRARY_DIRS}
${GTK_LIBRARY_DIRS}
${XEXTEND_LIBRARY_DIRS}
${XINERAMA_LIBRARY_DIRS})
# Define the library
add_library ("gldi" SHARED ${core_lib_SRCS})
STRING (REGEX REPLACE "\\..*" "" SOVERSION "${VERSION}")
set_target_properties ("gldi" PROPERTIES
# create *nix style library versions + symbolic links
VERSION ${VERSION}
SOVERSION ${SOVERSION}
# allow creating static and shared libs without conflicts
#CLEAN_DIRECT_OUTPUT 1
# avoid conflicts between library and binary target names
#OUTPUT_NAME ${PROJECT_NAME}
)
# Link the result to the librairies.
target_link_libraries("gldi"
${PACKAGE_LIBRARIES}
${GTK_LIBRARIES}
${XEXTEND_LIBRARIES}
${XINERAMA_LIBRARIES}
${LIBCRYPT_LIBS}
implementations
${LIBDL_LIBRARIES})
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/gldi.pc.in ${CMAKE_CURRENT_BINARY_DIR}/gldi.pc)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/gldi.pc DESTINATION ${install-pc-path})
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/libgldi.so DESTINATION ${libdir})
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/libgldi.so.${VERSION} DESTINATION ${libdir})
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/libgldi.so.${SOVERSION} DESTINATION ${libdir})
########### install files ###############
install(FILES cairo-dock.h DESTINATION ${includedir}/cairo-dock)
install(FILES
cairo-dock-struct.h cairo-dock-global-variables.h
gldi-config.h # gldi-module-config.h doesn't need to be installed
cairo-dock-core.h cairo-dock-manager.h
cairo-dock-object.h
cairo-dock-icon-factory.h cairo-dock-icon-manager.h
cairo-dock-icon-facility.h
cairo-dock-applications-manager.h cairo-dock-launcher-manager.h
cairo-dock-separator-manager.h cairo-dock-applet-manager.h
cairo-dock-stack-icon-manager.h cairo-dock-user-icon-manager.h
cairo-dock-class-icon-manager.h
cairo-dock-backends-manager.h
cairo-dock-packages.h
cairo-dock-data-renderer.h
cairo-dock-data-renderer-manager.h
cairo-dock-dock-manager.h
cairo-dock-desklet-manager.h
cairo-dock-dialog-manager.h
cairo-dock-indicator-manager.h
cairo-dock-themes-manager.h
cairo-dock-gui-manager.h
cairo-dock-file-manager.h
cairo-dock-desktop-manager.h
cairo-dock-windows-manager.h
cairo-dock-class-manager.h
cairo-dock-opengl.h
cairo-dock-image-buffer.h
cairo-dock-config.h
cairo-dock-module-manager.h
cairo-dock-module-instance-manager.h
cairo-dock-container.h
cairo-dock-dock-factory.h
cairo-dock-desklet-factory.h
cairo-dock-dialog-factory.h
cairo-dock-flying-container.h
cairo-dock-applet-multi-instance.h cairo-dock-applet-single-instance.h
cairo-dock-applet-canvas.h cairo-dock-applet-facility.h
cairo-dock-draw.h cairo-dock-draw-opengl.h
cairo-dock-opengl-path.h cairo-dock-opengl-font.h
cairo-dock-particle-system.h cairo-dock-overlay.h
cairo-dock-dbus.h
cairo-dock-keyfile-utilities.h cairo-dock-surface-factory.h
cairo-dock-log.h cairo-dock-keybinder.h
cairo-dock-application-facility.h cairo-dock-dock-facility.h
cairo-dock-task.h
cairo-dock-animations.h
cairo-dock-gui-factory.h
cairo-dock-menu.h
cairo-dock-utils.h
DESTINATION ${includedir}/cairo-dock/gldit)
if (disable-gtk-grip)
add_definitions (-DENABLE_GTK_GRIP=1)
endif()
cairo-dock-3.3.2/src/gldit/cairo-dock-applet-canvas.h 000664 001750 001750 00000053237 12223247550 023516 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_APPLET_CANVAS__
#define __CAIRO_DOCK_APPLET_CANVAS__
#include
#include "cairo-dock-struct.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-applet-canvas.h This file defines numerous macros, that form a canvas for all the applets.
*
* You probably won't need to dig into this file, since you can generate an applet with the 'generate-new-applet.sh' script, that will build the whole canvas for you.
* Moreover, you can have a look at an applet that has a similar functioning to yours.
*/
//\_________________________________ STRUCT
typedef struct _AppletConfig AppletConfig;
typedef struct _AppletData AppletData;
//\_________________________________ FUNCTIONS NAMES
#define CD_APPLET_DEFINE_FUNC pre_init
#define CD_APPLET_INIT_FUNC init
#define CD_APPLET_STOP_FUNC stop
#define CD_APPLET_RELOAD_FUNC reload
#define CD_APPLET_READ_CONFIG_FUNC read_conf_file
#define CD_APPLET_RESET_CONFIG_FUNC reset_config
#define CD_APPLET_RESET_DATA_FUNC reset_data
#define CD_APPLET_ON_CLICK_FUNC action_on_click
#define CD_APPLET_ON_BUILD_MENU_FUNC action_on_build_menu
#define CD_APPLET_ON_MIDDLE_CLICK_FUNC action_on_middle_click
#define CD_APPLET_ON_DOUBLE_CLICK_FUNC action_on_double_click
#define CD_APPLET_ON_DROP_DATA_FUNC action_on_drop_data
#define CD_APPLET_ON_SCROLL_FUNC action_on_scroll
#define CD_APPLET_ON_UPDATE_ICON_FUNC action_on_update_icon
//\_________________________________ PROTO
#define CD_APPLET_DEFINE_PROTO \
gboolean CD_APPLET_DEFINE_FUNC (GldiVisitCard *pVisitCard, GldiModuleInterface *pInterface)
#define CD_APPLET_INIT_PROTO(pApplet) \
void CD_APPLET_INIT_FUNC (GldiModuleInstance *pApplet, G_GNUC_UNUSED GKeyFile *pKeyFile)
#define CD_APPLET_STOP_PROTO \
void CD_APPLET_STOP_FUNC (GldiModuleInstance *myApplet)
#define CD_APPLET_RELOAD_PROTO \
gboolean CD_APPLET_RELOAD_FUNC (GldiModuleInstance *myApplet, GldiContainer *pOldContainer, G_GNUC_UNUSED GKeyFile *pKeyFile)
#define CD_APPLET_READ_CONFIG_PROTO \
gboolean CD_APPLET_READ_CONFIG_FUNC (GldiModuleInstance *myApplet, G_GNUC_UNUSED GKeyFile *pKeyFile)
#define CD_APPLET_RESET_CONFIG_PROTO \
void CD_APPLET_RESET_CONFIG_FUNC (GldiModuleInstance *myApplet)
#define CD_APPLET_RESET_DATA_PROTO \
void CD_APPLET_RESET_DATA_FUNC (GldiModuleInstance *myApplet)
#define CD_APPLET_ON_CLICK_PROTO \
gboolean CD_APPLET_ON_CLICK_FUNC (GldiModuleInstance *myApplet, Icon *pClickedIcon, GldiContainer *pClickedContainer, G_GNUC_UNUSED guint iButtonState)
#define CD_APPLET_ON_BUILD_MENU_PROTO \
gboolean CD_APPLET_ON_BUILD_MENU_FUNC (GldiModuleInstance *myApplet, Icon *pClickedIcon, GldiContainer *pClickedContainer, GtkWidget *pAppletMenu)
#define CD_APPLET_ON_MIDDLE_CLICK_PROTO \
gboolean CD_APPLET_ON_MIDDLE_CLICK_FUNC (GldiModuleInstance *myApplet, Icon *pClickedIcon, GldiContainer *pClickedContainer)
#define CD_APPLET_ON_DOUBLE_CLICK_PROTO \
gboolean CD_APPLET_ON_DOUBLE_CLICK_FUNC (GldiModuleInstance *myApplet, Icon *pClickedIcon, GldiContainer *pClickedContainer)
#define CD_APPLET_ON_DROP_DATA_PROTO \
gboolean CD_APPLET_ON_DROP_DATA_FUNC (GldiModuleInstance *myApplet, const gchar *cReceivedData, Icon *pClickedIcon, double fPosition, GldiContainer *pClickedContainer)
#define CD_APPLET_ON_SCROLL_PROTO \
gboolean CD_APPLET_ON_SCROLL_FUNC (GldiModuleInstance *myApplet, Icon *pClickedIcon, GldiContainer *pClickedContainer, int iDirection)
#define CD_APPLET_ON_UPDATE_ICON_PROTO \
gboolean CD_APPLET_ON_UPDATE_ICON_FUNC (GldiModuleInstance *myApplet, Icon *pIcon, GldiContainer *pContainer, gboolean *bContinueAnimation)
//\_________________________________ HEADERS
#define CD_APPLET_H \
CD_APPLET_DEFINE_PROTO; \
CD_APPLET_INIT_PROTO (pApplet); \
CD_APPLET_STOP_PROTO; \
CD_APPLET_RELOAD_PROTO;
#define CD_APPLET_CONFIG_H \
CD_APPLET_READ_CONFIG_PROTO; \
CD_APPLET_RESET_CONFIG_PROTO; \
CD_APPLET_RESET_DATA_PROTO;
#define CD_APPLET_ON_CLICK_H \
CD_APPLET_ON_CLICK_PROTO;
#define CD_APPLET_ON_BUILD_MENU_H \
CD_APPLET_ON_BUILD_MENU_PROTO;
#define CD_APPLET_ON_MIDDLE_CLICK_H \
CD_APPLET_ON_MIDDLE_CLICK_PROTO;
#define CD_APPLET_ON_DOUBLE_CLICK_H \
CD_APPLET_ON_DOUBLE_CLICK_PROTO;
#define CD_APPLET_ON_DROP_DATA_H \
CD_APPLET_ON_DROP_DATA_PROTO;
#define CD_APPLET_ON_SCROLL_H \
CD_APPLET_ON_SCROLL_PROTO;
#define CD_APPLET_ON_UPDATE_ICON_H \
CD_APPLET_ON_UPDATE_ICON_PROTO;
//\_________________________________ BODY
//\______________________ pre_init.
/** Debut de la fonction de pre-initialisation de l'applet (celle qui est appele a l'enregistrement de tous les plug-ins).
*Definit egalement les variables globales suivantes : myIcon, myDock, myDesklet, myContainer, et myDrawContext.
*@param _cName nom de sous lequel l'applet sera enregistree par Cairo-Dock.
*@param _iMajorVersion version majeure du dock necessaire au bon fonctionnement de l'applet.
*@param _iMinorVersion version mineure du dock necessaire au bon fonctionnement de l'applet.
*@param _iMicroVersion version micro du dock necessaire au bon fonctionnement de l'applet.
*@param _iAppletCategory Categorie de l'applet (CAIRO_DOCK_CATEGORY_ACCESSORY, CAIRO_DOCK_CATEGORY_DESKTOP, CAIRO_DOCK_CATEGORY_CONTROLER)
*@param _cDescription description et mode d'emploi succint de l'applet.
*@param _cAuthor nom de l'auteur et eventuellement adresse mail.
*/
#define CD_APPLET_DEFINE_ALL_BEGIN(_cName, _iMajorVersion, _iMinorVersion, _iMicroVersion, _iAppletCategory, _cDescription, _cAuthor) \
CD_APPLET_DEFINE_PROTO \
{ \
pVisitCard->cModuleName = _cName; \
pVisitCard->iMajorVersionNeeded = _iMajorVersion; \
pVisitCard->iMinorVersionNeeded = _iMinorVersion; \
pVisitCard->iMicroVersionNeeded = _iMicroVersion; \
pVisitCard->cPreviewFilePath = MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_PREVIEW_FILE; \
pVisitCard->cGettextDomain = MY_APPLET_GETTEXT_DOMAIN; \
pVisitCard->cDockVersionOnCompilation = MY_APPLET_DOCK_VERSION; \
pVisitCard->cUserDataDir = MY_APPLET_USER_DATA_DIR; \
pVisitCard->cShareDataDir = MY_APPLET_SHARE_DATA_DIR; \
pVisitCard->cConfFileName = (MY_APPLET_CONF_FILE != NULL && strcmp (MY_APPLET_CONF_FILE, "none") != 0 ? MY_APPLET_CONF_FILE : NULL); \
pVisitCard->cModuleVersion = MY_APPLET_VERSION;\
pVisitCard->iCategory = _iAppletCategory; \
pVisitCard->cIconFilePath = MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE; \
pVisitCard->iSizeOfConfig = sizeof (AppletConfig);\
pVisitCard->iSizeOfData = sizeof (AppletData);\
pVisitCard->cAuthor = _cAuthor;\
pVisitCard->cDescription = _cDescription;\
pVisitCard->cTitle = _cName;\
pVisitCard->iContainerType = CAIRO_DOCK_MODULE_CAN_DOCK | CAIRO_DOCK_MODULE_CAN_DESKLET;
#define CD_APPLET_DEFINE_COMMON_APPLET_INTERFACE \
pInterface->initModule = CD_APPLET_INIT_FUNC;\
pInterface->stopModule = CD_APPLET_STOP_FUNC;\
pInterface->reloadModule = CD_APPLET_RELOAD_FUNC;\
pInterface->reset_config = CD_APPLET_RESET_CONFIG_FUNC;\
pInterface->reset_data = CD_APPLET_RESET_DATA_FUNC;\
pInterface->read_conf_file = CD_APPLET_READ_CONFIG_FUNC;
#define CD_APPLET_REDEFINE_TITLE(_cTitle) pVisitCard->cTitle = _cTitle;
#define CD_APPLET_SET_CONTAINER_TYPE(x) pVisitCard->iContainerType = x;
#define CD_APPLET_SET_UNRESIZABLE_DESKLET pVisitCard->bStaticDeskletSize = TRUE;
#define CD_APPLET_ALLOW_EMPTY_TITLE pVisitCard->bAllowEmptyTitle = TRUE;
#define CD_APPLET_ACT_AS_LAUNCHER pVisitCard->bActAsLauncher = TRUE;
/** Fin de la fonction de pre-initialisation de l'applet.
*/
#define CD_APPLET_DEFINE_END \
pVisitCard->cTitle = dgettext (MY_APPLET_GETTEXT_DOMAIN, pVisitCard->cTitle);\
return TRUE ;\
}
/** Fonction de pre-initialisation generique. Ne fais que definir l'applet (en appelant les 2 macros precedentes), la plupart du temps cela est suffisant.
*/
#define CD_APPLET_DEFINITION(cName, iMajorVersion, iMinorVersion, iMicroVersion, iAppletCategory, cDescription, cAuthor) \
CD_APPLET_DEFINE_BEGIN (cName, iMajorVersion, iMinorVersion, iMicroVersion, iAppletCategory, cDescription, cAuthor) \
CD_APPLET_DEFINE_COMMON_APPLET_INTERFACE \
CD_APPLET_DEFINE_END
#define CD_APPLET_EXTEND_MANAGER(cManagerName) gldi_manager_extend (pVisitCard, cManagerName)
//\______________________ init.
/** Debut de la fonction d'initialisation de l'applet (celle qui est appelee a chaque chargement de l'applet).
*Lis le fichier de conf de l'applet, et cree son icone ainsi que son contexte de dessin.
*@param pApplet une instance du module.
*/
#define CD_APPLET_INIT_ALL_BEGIN(pApplet) \
CD_APPLET_INIT_PROTO (pApplet)\
{ \
g_pCurrentModule = pApplet;\
cd_message ("%s (%s)", __func__, pApplet->cConfFilePath);
/** Fin de la fonction d'initialisation de l'applet.
*/
#define CD_APPLET_INIT_END \
g_pCurrentModule = NULL;\
}
//\______________________ stop.
/** Debut de la fonction d'arret de l'applet.
*/
#define CD_APPLET_STOP_BEGIN \
CD_APPLET_STOP_PROTO \
{\
g_pCurrentModule = myApplet;
/** Fin de la fonction d'arret de l'applet.
*/
#define CD_APPLET_STOP_END \
g_pCurrentModule = NULL;\
}
//\______________________ reload.
/** Debut de la fonction de rechargement de l'applet.
*/
#define CD_APPLET_RELOAD_ALL_BEGIN \
CD_APPLET_RELOAD_PROTO \
{ \
g_pCurrentModule = myApplet;\
cd_message ("%s (%s)", __func__, myApplet->cConfFilePath);
/** Fin de la fonction de rechargement de l'applet.
*/
#define CD_APPLET_RELOAD_END \
g_pCurrentModule = NULL;\
return TRUE; \
}
//\______________________ read_conf_file.
/** Debut de la fonction de configuration de l'applet (celle qui est appelee au debut de l'init).
*/
#define CD_APPLET_GET_CONFIG_ALL_BEGIN \
CD_APPLET_READ_CONFIG_PROTO \
{ \
g_pCurrentModule = myApplet;\
gboolean bFlushConfFileNeeded = FALSE;
/** Fin de la fonction de configuration de l'applet.
*/
#define CD_APPLET_GET_CONFIG_END \
g_pCurrentModule = NULL;\
return bFlushConfFileNeeded; \
}
//\______________________ reset_config.
/** Debut de la fonction de liberation des donnees de la config.
*/
#define CD_APPLET_RESET_CONFIG_ALL_BEGIN \
CD_APPLET_RESET_CONFIG_PROTO \
{\
g_pCurrentModule = myApplet;
/** Fin de la fonction de liberation des donnees de la config.
*/
#define CD_APPLET_RESET_CONFIG_ALL_END \
g_pCurrentModule = NULL;\
}
//\______________________ reset_data.
/** Debut de la fonction de liberation des donnees internes.
*/
#define CD_APPLET_RESET_DATA_BEGIN \
CD_APPLET_RESET_DATA_PROTO \
{\
g_pCurrentModule = myApplet;
/** Fin de la fonction de liberation des donnees internes.
*/
#define CD_APPLET_RESET_DATA_ALL_END \
g_pCurrentModule = NULL;\
}
//\______________________ on click.
/** Debut de la fonction de notification au clic gauche.
*/
#define CD_APPLET_ON_CLICK_BEGIN \
CD_APPLET_ON_CLICK_PROTO \
{ \
g_pCurrentModule = myApplet;\
if (pClickedIcon == myIcon || (myIcon != NULL && pClickedContainer == CAIRO_CONTAINER (myIcon->pSubDock)) || pClickedContainer == CAIRO_CONTAINER (myDesklet)) \
{
/** Fin de la fonction de notification au clic gauche. Par defaut elle intercepte la notification si elle l'a recue.
*/
#define CD_APPLET_ON_CLICK_END \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_INTERCEPT; \
} \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_LET_PASS; \
}
//\______________________ on build menu.
/** Debut de la fonction de notification de construction du menu.
*/
#define CD_APPLET_ON_BUILD_MENU_BEGIN \
CD_APPLET_ON_BUILD_MENU_PROTO \
{ \
g_pCurrentModule = myApplet;\
if (pClickedIcon == myIcon || (myIcon != NULL && pClickedContainer == CAIRO_CONTAINER (myIcon->pSubDock)) || pClickedContainer == CAIRO_CONTAINER (myDesklet)) \
{ \
GtkWidget *pMenuItem; \
if (pClickedIcon == myIcon || (pClickedContainer == CAIRO_CONTAINER (myDesklet) && pClickedIcon == NULL)) {\
pMenuItem = gtk_separator_menu_item_new (); \
gtk_menu_shell_append(GTK_MENU_SHELL (pAppletMenu), pMenuItem); }
/** Fin de la fonction de notification de construction du menu. Par defaut elle intercepte la notification si elle l'a recue.
*/
#define CD_APPLET_ON_BUILD_MENU_END \
} \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_LET_PASS; \
}
//\______________________ on middle-click.
/** Debut de la fonction de notification du clic du milieu.
*/
#define CD_APPLET_ON_MIDDLE_CLICK_BEGIN \
CD_APPLET_ON_MIDDLE_CLICK_PROTO \
{ \
g_pCurrentModule = myApplet;\
if (pClickedIcon == myIcon || (myIcon != NULL && pClickedContainer == CAIRO_CONTAINER (myIcon->pSubDock)) || pClickedContainer == CAIRO_CONTAINER (myDesklet)) \
{
/** Fin de la fonction de notification du clic du milieu. Par defaut elle intercepte la notification si elle l'a recue.
*/
#define CD_APPLET_ON_MIDDLE_CLICK_END \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_INTERCEPT; \
} \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_LET_PASS; \
}
//\______________________ on double-click.
/** Debut de la fonction de notification du clic du milieu.
*/
#define CD_APPLET_ON_DOUBLE_CLICK_BEGIN \
CD_APPLET_ON_DOUBLE_CLICK_PROTO \
{ \
g_pCurrentModule = myApplet;\
if (pClickedIcon == myIcon || (myIcon != NULL && pClickedContainer == CAIRO_CONTAINER (myIcon->pSubDock)) || pClickedContainer == CAIRO_CONTAINER (myDesklet)) \
{
/** Fin de la fonction de notification du clic du milieu. Par defaut elle intercepte la notification si elle l'a recue.
*/
#define CD_APPLET_ON_DOUBLE_CLICK_END \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_INTERCEPT; \
} \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_LET_PASS; \
}
//\______________________ on drop-data.
/** Debut de la fonction de notification du glisse-depose.
*/
#define CD_APPLET_ON_DROP_DATA_BEGIN \
CD_APPLET_ON_DROP_DATA_PROTO \
{ \
g_pCurrentModule = myApplet;\
if (pClickedIcon == myIcon || (myIcon != NULL && pClickedContainer == CAIRO_CONTAINER (myIcon->pSubDock)) || pClickedContainer == CAIRO_CONTAINER (myDesklet)) \
{ \
g_return_val_if_fail (cReceivedData != NULL, GLDI_NOTIFICATION_LET_PASS);
/** Fin de la fonction de notification du glisse-depose. Par defaut elle intercepte la notification si elle l'a recue.
*/
#define CD_APPLET_ON_DROP_DATA_END \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_INTERCEPT; \
} \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_LET_PASS; \
}
//\______________________ on scroll.
/** Debut de la fonction de notification au scroll.
*/
#define CD_APPLET_ON_SCROLL_BEGIN \
CD_APPLET_ON_SCROLL_PROTO \
{ \
g_pCurrentModule = myApplet;\
if (pClickedIcon != NULL && (pClickedIcon == myIcon || (myIcon != NULL && pClickedContainer == CAIRO_CONTAINER (myIcon->pSubDock)) || pClickedContainer == CAIRO_CONTAINER (myDesklet))) \
{
/** Fin de la fonction de notification au scroll. Par defaut elle intercepte la notification si elle l'a recue.
*/
#define CD_APPLET_ON_SCROLL_END \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_INTERCEPT; \
} \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_LET_PASS; \
}
//\______________________ on update icon.
/** Debut de la fonction de notification d'update icon.
*/
#define CD_APPLET_ON_UPDATE_ICON_BEGIN \
CD_APPLET_ON_UPDATE_ICON_PROTO \
{ \
if (pIcon != myIcon)\
return GLDI_NOTIFICATION_LET_PASS;\
g_pCurrentModule = myApplet;
/** Fin de la fonction de notification d'update icon.
*/
#define CD_APPLET_ON_UPDATE_ICON_END \
*bContinueAnimation = TRUE;\
CD_APPLET_REDRAW_MY_ICON;\
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_LET_PASS; \
}
/** Quit the update function immediately and wait for the next update.
*/
#define CD_APPLET_SKIP_UPDATE_ICON do { \
*bContinueAnimation = TRUE; \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_LET_PASS; } while (0)
/** Quit the update function immediately with no more updates.
*/
#define CD_APPLET_STOP_UPDATE_ICON do { \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_LET_PASS; } while (0)
/** Quit the update function immediately with no more updates after redrawing the icon.
*/
#define CD_APPLET_PAUSE_UPDATE_ICON do { \
CD_APPLET_REDRAW_MY_ICON; \
g_pCurrentModule = NULL;\
return GLDI_NOTIFICATION_LET_PASS; } while (0)
//\_________________________________ NOTIFICATIONS
//\______________________ notification clique gauche.
/** Abonne l'applet aux notifications du clic gauche. A effectuer lors de l'init de l'applet.
*/
#define CD_APPLET_REGISTER_FOR_CLICK_EVENT gldi_object_register_notification (&myContainerObjectMgr, NOTIFICATION_CLICK_ICON, (GldiNotificationFunc) CD_APPLET_ON_CLICK_FUNC, GLDI_RUN_AFTER, myApplet);
/** Desabonne l'applet aux notifications du clic gauche. A effectuer lors de l'arret de l'applet.
*/
#define CD_APPLET_UNREGISTER_FOR_CLICK_EVENT gldi_object_remove_notification (&myContainerObjectMgr, NOTIFICATION_CLICK_ICON, (GldiNotificationFunc) CD_APPLET_ON_CLICK_FUNC, myApplet);
/** Abonne l'applet aux notifications de construction du menu. A effectuer lors de l'init de l'applet.
*/
//\______________________ notification construction menu.
#define CD_APPLET_REGISTER_FOR_BUILD_MENU_EVENT gldi_object_register_notification (&myContainerObjectMgr, NOTIFICATION_BUILD_ICON_MENU, (GldiNotificationFunc) CD_APPLET_ON_BUILD_MENU_FUNC, GLDI_RUN_FIRST, myApplet);
/** Desabonne l'applet aux notifications de construction du menu. A effectuer lors de l'arret de l'applet.
*/
#define CD_APPLET_UNREGISTER_FOR_BUILD_MENU_EVENT gldi_object_remove_notification (&myContainerObjectMgr, NOTIFICATION_BUILD_ICON_MENU, (GldiNotificationFunc) CD_APPLET_ON_BUILD_MENU_FUNC, myApplet);
//\______________________ notification clic milieu.
/** Abonne l'applet aux notifications du clic du milieu. A effectuer lors de l'init de l'applet.
*/
#define CD_APPLET_REGISTER_FOR_MIDDLE_CLICK_EVENT gldi_object_register_notification (&myContainerObjectMgr, NOTIFICATION_MIDDLE_CLICK_ICON, (GldiNotificationFunc) CD_APPLET_ON_MIDDLE_CLICK_FUNC, GLDI_RUN_AFTER, myApplet)
/** Desabonne l'applet aux notifications du clic du milieu. A effectuer lors de l'arret de l'applet.
*/
#define CD_APPLET_UNREGISTER_FOR_MIDDLE_CLICK_EVENT gldi_object_remove_notification (&myContainerObjectMgr, NOTIFICATION_MIDDLE_CLICK_ICON, (GldiNotificationFunc) CD_APPLET_ON_MIDDLE_CLICK_FUNC, myApplet)
//\______________________ notification double clic.
/** Abonne l'applet aux notifications du double clic. A effectuer lors de l'init de l'applet.
*/
#define CD_APPLET_REGISTER_FOR_DOUBLE_CLICK_EVENT do {\
cairo_dock_listen_for_double_click (myIcon);\
gldi_object_register_notification (&myContainerObjectMgr, NOTIFICATION_DOUBLE_CLICK_ICON, (GldiNotificationFunc) CD_APPLET_ON_DOUBLE_CLICK_FUNC, GLDI_RUN_AFTER, myApplet); } while (0)
/** Desabonne l'applet aux notifications du double clic. A effectuer lors de l'arret de l'applet.
*/
#define CD_APPLET_UNREGISTER_FOR_DOUBLE_CLICK_EVENT do {\
gldi_object_remove_notification (&myContainerObjectMgr, NOTIFICATION_DOUBLE_CLICK_ICON, (GldiNotificationFunc) CD_APPLET_ON_DOUBLE_CLICK_FUNC, myApplet);\
cairo_dock_stop_listening_for_double_click (myIcon); } while (0)
//\______________________ notification drag'n'drop.
/** Abonne l'applet aux notifications du glisse-depose. A effectuer lors de l'init de l'applet.
*/
#define CD_APPLET_REGISTER_FOR_DROP_DATA_EVENT gldi_object_register_notification (&myContainerObjectMgr, NOTIFICATION_DROP_DATA, (GldiNotificationFunc) CD_APPLET_ON_DROP_DATA_FUNC, GLDI_RUN_FIRST, myApplet);
/** Desabonne l'applet aux notifications du glisse-depose. A effectuer lors de l'arret de l'applet.
*/
#define CD_APPLET_UNREGISTER_FOR_DROP_DATA_EVENT gldi_object_remove_notification (&myContainerObjectMgr, NOTIFICATION_DROP_DATA, (GldiNotificationFunc) CD_APPLET_ON_DROP_DATA_FUNC, myApplet);
//\______________________ notification de scroll molette.
/**
*Abonne l'applet aux notifications du clic gauche. A effectuer lors de l'init de l'applet.
*/
#define CD_APPLET_REGISTER_FOR_SCROLL_EVENT gldi_object_register_notification (&myContainerObjectMgr, NOTIFICATION_SCROLL_ICON, (GldiNotificationFunc) CD_APPLET_ON_SCROLL_FUNC, GLDI_RUN_FIRST, myApplet)
/**
*Desabonne l'applet aux notifications du clic gauche. A effectuer lors de l'arret de l'applet.
*/
#define CD_APPLET_UNREGISTER_FOR_SCROLL_EVENT gldi_object_remove_notification (&myContainerObjectMgr, NOTIFICATION_SCROLL_ICON, (GldiNotificationFunc) CD_APPLET_ON_SCROLL_FUNC, myApplet)
//\______________________ notification de update icon.
/** Register the applet to the 'update icon' notifications of the slow rendering loop.
*/
#define CD_APPLET_REGISTER_FOR_UPDATE_ICON_SLOW_EVENT gldi_object_register_notification (&myIconObjectMgr, NOTIFICATION_UPDATE_ICON_SLOW, (GldiNotificationFunc) CD_APPLET_ON_UPDATE_ICON_FUNC, GLDI_RUN_FIRST, myApplet)
/** Unregister the applet from the slow rendering loop.
*/
#define CD_APPLET_UNREGISTER_FOR_UPDATE_ICON_SLOW_EVENT gldi_object_remove_notification (&myIconObjectMgr, NOTIFICATION_UPDATE_ICON_SLOW, (GldiNotificationFunc) CD_APPLET_ON_UPDATE_ICON_FUNC, myApplet)
/** Register the applet to the 'update icon' notifications of the fast rendering loop.
*/
#define CD_APPLET_REGISTER_FOR_UPDATE_ICON_EVENT gldi_object_register_notification (&myIconObjectMgr, NOTIFICATION_UPDATE_ICON, (GldiNotificationFunc) CD_APPLET_ON_UPDATE_ICON_FUNC, GLDI_RUN_FIRST, myApplet)
/** Unregister the applet from the fast rendering loop.
*/
#define CD_APPLET_UNREGISTER_FOR_UPDATE_ICON_EVENT gldi_object_remove_notification (&myIconObjectMgr, NOTIFICATION_UPDATE_ICON, (GldiNotificationFunc) CD_APPLET_ON_UPDATE_ICON_FUNC, myApplet)
//\_________________________________ INSTANCE
#ifdef CD_APPLET_MULTI_INSTANCE
#include
#else
#include
#endif
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-particle-system.c 000664 001750 001750 00000015111 12223247550 024065 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include "cairo-dock-draw-opengl.h"
#include "cairo-dock-particle-system.h"
static GLfloat s_pCornerCoords[8] = {0.0, 0.0,
0.0, 1.0,
1.0, 1.0,
1.0, 0.0};
void cairo_dock_render_particles_full (CairoParticleSystem *pParticleSystem, int iDepth)
{
_cairo_dock_enable_texture ();
if (pParticleSystem->bAddLuminance)
_cairo_dock_set_blend_over ();
//glBlendFunc (GL_SRC_ALPHA, GL_ONE);
else
_cairo_dock_set_blend_alpha ();
glBindTexture(GL_TEXTURE_2D, pParticleSystem->iTexture);
GLfloat *vertices = pParticleSystem->pVertices;
///GLfloat *coords = pParticleSystem->pCoords;
GLfloat *colors = pParticleSystem->pColors;
GLfloat *vertices2 = &pParticleSystem->pVertices[pParticleSystem->iNbParticles * 4 * 3];
///GLfloat *coords2 = &pParticleSystem->pCoords[pParticleSystem->iNbParticles * 4 * 2];
GLfloat *colors2 = &pParticleSystem->pColors[pParticleSystem->iNbParticles * 4 * 4];
GLfloat x,y,z;
GLfloat w, h;
GLfloat fHeight = pParticleSystem->fHeight;
int numActive = 0;
CairoParticle *p;
int i;
for (i = 0; i < pParticleSystem->iNbParticles; i ++)
{
p = &pParticleSystem->pParticles[i];
if (p->iLife == 0 || iDepth * p->z < 0)
continue;
numActive += 4;
w = p->fWidth * p->fSizeFactor;
h = p->fHeight * p->fSizeFactor;
x = p->x * pParticleSystem->fWidth / 2;
y = p->y * pParticleSystem->fHeight;
z = p->z;
vertices[0] = x - w;
vertices[2] = z;
vertices[3] = x - w;
vertices[5] = z;
vertices[6] = x + w;
vertices[8] = z;
vertices[9] = x + w;
vertices[11] = z;
if (pParticleSystem->bDirectionUp)
{
vertices[1] = y + h;
vertices[4] = y - h;
vertices[7] = y - h;
vertices[10] = y + h;
}
else
{
vertices[1] = fHeight - y + h;
vertices[4] = fHeight - y - h;
vertices[7] = fHeight - y - h;
vertices[10] = fHeight - y + h;
}
vertices += 12;
///memcpy (coords, s_pCornerCoords, sizeof (s_pCornerCoords));
///coords += 8;
colors[0] = p->color[0];
colors[1] = p->color[1];
colors[2] = p->color[2];
colors[3] = p->color[3];
memcpy (colors + 4, colors, 4*sizeof (GLfloat));
memcpy (colors + 8, colors, 8*sizeof (GLfloat));
colors += 16;
if (pParticleSystem->bAddLight)
{
w/=1.6;
h/=1.6;
vertices2[0] = x - w;
vertices2[2] = z;
vertices2[3] = x - w;
vertices2[5] = z;
vertices2[6] = x + w;
vertices2[8] = z;
vertices2[9] = x + w;
vertices2[11] = z;
if (pParticleSystem->bDirectionUp)
{
vertices2[1] = y + h;
vertices2[4] = y - h;
vertices2[7] = y - h;
vertices2[10] = y + h;
}
else
{
vertices2[1] = fHeight - y + h;
vertices2[4] = fHeight - y - h;
vertices2[7] = fHeight - y - h;
vertices2[10] = fHeight - y + h;
}
vertices2 += 12;
///memcpy (coords2, s_pCornerCoords, sizeof (s_pCornerCoords));
///coords2 += 8;
colors2[0] = 1;
colors2[1] = 1;
colors2[2] = 1;
colors2[3] = colors[3];
memcpy (colors2 + 4, colors2, 4*sizeof (GLfloat));
memcpy (colors2 + 8, colors2, 8*sizeof (GLfloat));
colors2 += 16;
}
}
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glEnableClientState (GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), pParticleSystem->pCoords);
glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), pParticleSystem->pVertices);
glColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), pParticleSystem->pColors);
glDrawArrays(GL_QUADS, 0, pParticleSystem->bAddLight ? numActive*2 : numActive);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
glDisableClientState (GL_VERTEX_ARRAY);
_cairo_dock_disable_texture ();
}
CairoParticleSystem *cairo_dock_create_particle_system (int iNbParticles, GLuint iTexture, double fWidth, double fHeight)
{
g_return_val_if_fail (iNbParticles > 0, NULL);
CairoParticleSystem *pParticleSystem = g_new0 (CairoParticleSystem, 1);
pParticleSystem->iNbParticles = iNbParticles;
pParticleSystem->pParticles = g_new0 (CairoParticle, iNbParticles);
pParticleSystem->iTexture = iTexture;
pParticleSystem->fWidth = fWidth;
pParticleSystem->fHeight = fHeight;
pParticleSystem->bDirectionUp = TRUE;
pParticleSystem->pVertices = malloc(iNbParticles * 4 * 3 * sizeof(GLfloat)*2);
pParticleSystem->pCoords = malloc(iNbParticles * 4 * 2 * sizeof(GLfloat)*2);
pParticleSystem->pColors = malloc(iNbParticles * 4 * 4 * sizeof(GLfloat)*2);
GLfloat *coords = pParticleSystem->pCoords; // on prerempli les coordonnees de la texture.
// CairoParticle *p;
int i;
for (i = 0; i < 2*iNbParticles; i ++)
{
// p = &pParticleSystem->pParticles[i];
memcpy (coords, s_pCornerCoords, sizeof (s_pCornerCoords));
coords += 8;
}
return pParticleSystem;
}
void cairo_dock_free_particle_system (CairoParticleSystem *pParticleSystem)
{
if (pParticleSystem == NULL)
return ;
g_free (pParticleSystem->pParticles);
free (pParticleSystem->pVertices);
free (pParticleSystem->pCoords);
free (pParticleSystem->pColors);
g_free (pParticleSystem);
}
gboolean cairo_dock_update_default_particle_system (CairoParticleSystem *pParticleSystem, CairoDockRewindParticleFunc pRewindParticle)
{
gboolean bAllParticlesEnded = TRUE;
CairoParticle *p;
int i;
for (i = 0; i < pParticleSystem->iNbParticles; i ++)
{
p = &(pParticleSystem->pParticles[i]);
p->fOscillation += p->fOmega;
p->x += p->vx + (p->z + 2)/3. * .02 * sin (p->fOscillation); // 3%
p->y += p->vy;
p->color[3] = 1.*p->iLife / p->iInitialLife;
p->fSizeFactor += p->fResizeSpeed;
if (p->iLife > 0)
{
p->iLife --;
if (pRewindParticle && p->iLife == 0)
{
pRewindParticle (p, pParticleSystem->dt);
}
if (bAllParticlesEnded && p->iLife != 0)
bAllParticlesEnded = FALSE;
}
else if (pRewindParticle)
pRewindParticle (p, pParticleSystem->dt);
}
return ! bAllParticlesEnded;
}
cairo-dock-3.3.2/src/gldit/cairo-dock-data-renderer.h 000664 001750 001750 00000042530 12223247550 023467 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_DATA_RENDERER__
#define __CAIRO_DOCK_DATA_RENDERER__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-packages.h"
#include "cairo-dock-overlay.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-data-renderer.h This class defines the Data Renderer structure and API.
* A Data Renderer is a generic way to display a set of values on an icon.
* For instance you could represent the (cpu, memory, temperature) evolution over the time.
*
* You bind a Data Renderer with /ref cairo_dock_add_new_data_renderer_on_icon.
* You can specify some attributes of the Data Renderer, especially the model that will be used; currently, 3 models are available: "gauge", "graph" and "progressbar".
*
* You then feed the Data Renderer with /ref cairo_dock_render_new_data_on_icon, providing it the correct number of values.
*
* To remove the Data Renderer from an icon, use /ref cairo_dock_remove_data_renderer_on_icon.
*/
typedef enum _RendererRotateTheme {
CD_RENDERER_ROTATE_NO=0,
CD_RENDERER_ROTATE_WITH_CONTAINER,
CD_RENDERER_ROTATE_YES,
CD_RENDERER_NB_ROTATE
} RendererRotateTheme;
#define CAIRO_DATA_RENDERER_UNDEF_VALUE ((double)-1.e9)
//
// Structures
//
struct _CairoDataToRenderer {
gint iNbValues;
gint iMemorySize;
gdouble *pValuesBuffer;
gdouble **pTabValues;
gdouble *pMinMaxValues;
gint iCurrentIndex;
gboolean bHasValue; // TRUE as soon as a value has been set in the history
};
#define CAIRO_DOCK_DATA_FORMAT_MAX_LEN 20
/// Prototype of a function used to format the values in a short readable format (to be displayed as quick-info).
typedef void (*CairoDataRendererFormatValueFunc) (CairoDataRenderer *pRenderer, int iNumValue, gchar *cFormatBuffer, int iBufferLength, gpointer data);
/// Generic DataRenderer attributes structure. The attributes of any implementation of a DataRenderer will derive from this class.
struct _CairoDataRendererAttribute {
/// name of the model ("gauge", "graph", etc) [mandatory].
const gchar *cModelName;
/// number of values to represent (for instance 3 for (cpu, mem, swap)) [1 by default and minimum].
gint iNbValues;
/// number of values to remember over time. For instance graphs can display as much values as the icon's width [2 by default and minimum].
gint iMemorySize;
/// an array of pairs of (min,max) values. [optionnal, input values will be considered between 0 and 1 if NULL].
gdouble *pMinMaxValues;
/// whether to automatically update the values' range [false by default].
gboolean bUpdateMinMax;
/// whether to write the values on the icon. [false by default].
gboolean bWriteValues;
/// an option to rotate applet, no, automatic or always.
RendererRotateTheme iRotateTheme;
/// time needed to update to the new values. The update is smooth in OpenGL mode. [0 by default]
gint iLatencyTime;
/// a function used to format the values into a string. Only useful if you make te DataRenderer write the values [optionnal, by default the values are formatted with 2 decimals].
CairoDataRendererFormatValueFunc format_value;
/// data to be passed to the format function [optionnal].
gpointer pFormatData;
/// an optionnal list of emblems to draw on the overlay.
gchar **cEmblems;
/// an optionnal list of labels to write on the overlay.
gchar **cLabels;
};
typedef CairoDataRenderer * (*CairoDataRendererNewFunc) (void);
typedef void (*CairoDataRendererLoadFunc) (CairoDataRenderer *pDataRenderer, Icon *pIcon, CairoDataRendererAttribute *pAttribute);
typedef void (*CairoDataRendererRenderFunc) (CairoDataRenderer *pDataRenderer, cairo_t *pCairoContext);
typedef void (*CairoDataRendererRenderOpenGLFunc) (CairoDataRenderer *pDataRenderer);
typedef void (*CairoDataRendererReloadFunc) (CairoDataRenderer *pDataRenderer);
typedef void (*CairoDataRendererUnloadFunc) (CairoDataRenderer *pDataRenderer);
/// Interface of a DataRenderer.
struct _CairoDataRendererInterface {
/// function that loads anything the DataRenderer will need. It also completes the DataRenderer structure (for instance the text zones).
CairoDataRendererLoadFunc load;
/// function that draws the values with cairo.
CairoDataRendererRenderFunc render;
/// function that draws the values with opengl.
CairoDataRendererRenderOpenGLFunc render_opengl;
/// function that reloads the DataRenderer's buffers when the icon is resized.
CairoDataRendererReloadFunc reload;
/// function that unload all the previously allocated buffers.
CairoDataRendererUnloadFunc unload;
};
struct _CairoDataRendererEmblemParam {
gdouble fX, fY; // [-1;1]
gdouble fWidth, fHeight; // [-1;1]
gdouble fAlpha;
};
struct _CairoDataRendererEmblem {
CairoDataRendererEmblemParam param;
gchar *cImagePath;
cairo_surface_t *pSurface;
GLuint iTexture;
};
struct _CairoDataRendererTextParam {
gdouble fX, fY; // [-1;1], center of the text.
gdouble fWidth, fHeight; // [-1;1]
gdouble pColor[4];
};
struct _CairoDataRendererText {
CairoDataRendererTextParam param;
gchar *cText;
gint iTextWidth, iTextHeight;
cairo_surface_t *pSurface;
GLuint iTexture;
};
/// Generic DataRenderer. Any implementation of a DataRenderer will derive from this class.
struct _CairoDataRenderer {
//\_________________ filled at init by the implementation.
/// interface of the Data Renderer.
CairoDataRendererInterface interface;
//\_________________ filled at loading time independantly of the renderer type.
/// internal data to be drawn by the renderer.
CairoDataToRenderer data;
/// size of the drawing area.
gint iWidth, iHeight; // taille du contexte de dessin.
/// specific function to format the values as text.
CairoDataRendererFormatValueFunc format_value;
/// buffer for the text.
gchar cFormatBuffer[CAIRO_DOCK_DATA_FORMAT_MAX_LEN+1];
/// data passed to the format fonction.
gpointer pFormatData;
/// TRUE <=> the Data Renderer should dynamically update the range of the values.
gboolean bUpdateMinMax;
/// TRUE <=> the Data Renderer should write the values as text itself.
gboolean bWriteValues;
/// the time it will take to update to the new value, with a smooth animation (require openGL capacity)
gint iLatencyTime;
//\_________________ filled at load time by the implementation.
/// the rank of the renderer, eg the number of values it can display at once (for exemple, 1 for a bar, 2 for a dual-gauge)
gint iRank; // nbre de valeurs que peut afficher 1 unite (en general : gauge:1/2, graph:1/2, bar:1)
/// set to TRUE <=> the renderer can draw the values as text itself.
gboolean bCanRenderValueAsText;
/// set to TRUE <=> the drawing will be rotated if the container is vertical.
gboolean bRotateWithContainer;
/// an option to rotate applet, no, automatic or always.
RendererRotateTheme iRotateTheme;
/// set to TRUE <=> the theme images are rotated 90° clockwise.
gboolean bisRotate;
/// whether the data-renderer draws on an overlay rather than directly on the icon.
gboolean bUseOverlay;
/// position of the overlay, in the case the renderer uses one.
CairoOverlayPosition iOverlayPosition;
/// an optionnal list of labels to be displayed on the Data Renderer to indicate the nature of each value. Same size as the set of values.
CairoDataRendererText *pLabels;
/// an optionnal list of emblems to be displayed on the Data Renderer to indicate the nature of each value. Same size as the set of values.
CairoDataRendererEmblem *pEmblems;
/// an optionnal list of text zones to write the values. Same size as the set of values.
CairoDataRendererTextParam *pValuesText;
//\_________________ dynamic.
/// the animation counter for the smooth movement.
gint iSmoothAnimationStep;
/// latency due to the smooth movement (0 means the displayed value is the current one, 1 the previous)
gdouble fLatency;
guint iSidRenderIdle; // source ID to delay the rendering in OpenGL until the container is fully resized
CairoOverlay *pOverlay;
};
///
/// Renderer manipulation
///
/** Get the default GLX font for Data Renderer. It can render strings of digits from 0 to 9. Don't destroy it.
*@return the default GLX font*/
CairoDockGLFont *cairo_dock_get_default_data_renderer_font (void);
void cairo_dock_unload_default_data_renderer_font (void);
/**Add a Data Renderer on an icon. If the icon already has a Data Renderer, it is replaced by the new one, keeping the history alive.
*@param pIcon the icon
*@param pContainer the icon's container
*@param pAttribute attributes defining the Renderer*/
void cairo_dock_add_new_data_renderer_on_icon (Icon *pIcon, GldiContainer *pContainer, CairoDataRendererAttribute *pAttribute);
/**Draw the current values associated with the Renderer on the icon.
*@param pIcon the icon
*@param pContainer the icon's container
*@param pCairoContext a drawing context on the icon
*@param pNewValues a set a new values (must be of the size defined on the creation of the Renderer)*/
void cairo_dock_render_new_data_on_icon (Icon *pIcon, GldiContainer *pContainer, cairo_t *pCairoContext, double *pNewValues);
/**Remove the Data Renderer of an icon. All the allocated ressources will be freed.
*@param pIcon the icon*/
void cairo_dock_remove_data_renderer_on_icon (Icon *pIcon);
/**Reload the Data Renderer of an icon, keeping the history and the attributes. This is intended to be used when the icon size changes.
*@param pIcon the icon
*@param pContainer the icon's container*/
void cairo_dock_reload_data_renderer_on_icon (Icon *pIcon, GldiContainer *pContainer);
/** Resize the history of a DataRenderer of an icon, that is to say change the number of previous values that are remembered by the DataRenderer.
*@param pIcon the icon
*@param iNewMemorySize the new size of history*/
void cairo_dock_resize_data_renderer_history (Icon *pIcon, int iNewMemorySize);
/** Redraw the DataRenderer of an icon, with the current values.
*@param pIcon the icon
*@param pContainer the icon's container*/
void cairo_dock_refresh_data_renderer (Icon *pIcon, GldiContainer *pContainer);
void cairo_dock_render_overlays_to_context (CairoDataRenderer *pRenderer, int iNumValue, cairo_t *pCairoContext);
void cairo_dock_render_overlays_to_texture (CairoDataRenderer *pRenderer, int iNumValue);
void cairo_data_renderer_get_size (CairoDataRenderer *pRenderer, gint *iWidth, gint *iHeight);
///
/// Structure Access
///
#define cairo_dock_get_icon_data_renderer(pIcon) (pIcon)->pDataRenderer
/**Get the elementary part of a Data Renderer
*@param r a high level data renderer
*@return a CairoDataRenderer* */
#define CAIRO_DATA_RENDERER(r) (&(r)->dataRenderer)
/**Get the data of a Data Renderer
*@param pRenderer a data renderer
*@return a CairoDataToRenderer* */
#define cairo_data_renderer_get_data(pRenderer) (&(pRenderer)->data);
/**Get the elementary part of a Data Renderer Attribute
*@param pAttr a high level data renderer attribute
*@return a CairoDataRendererAttribute* */
#define CAIRO_DATA_RENDERER_ATTRIBUTE(pAttr) ((CairoDataRendererAttribute *) pAttr)
/**Get the number of values a DataRenderer displays. It's also the size of any of its arrays.
*@param pRenderer a data renderer
*@return number of values a DataRenderer displays */
#define cairo_data_renderer_get_nb_values(pRenderer) ((pRenderer)->data.iNbValues)
#define cairo_data_renderer_get_history_size(pRenderer) ((pRenderer)->data.iMemorySize)
#define cairo_data_renderer_get_nth_label(pRenderer, i) (&(pRenderer)->pLabels[i])
#define cairo_data_renderer_get_nth_value_text(pRenderer, i) (&(pRenderer)->pValuesText[i])
#define cairo_data_renderer_get_nth_emblem(pRenderer, i) (&(pRenderer)->pEmblems[i])
/*#define cairo_data_renderer_set_attribute(pRendererAttribute, cAttributeName, ) g_datalist_get_data (pRendererAttribute->pExtraProperties)
#define cairo_data_renderer_get_attribute(pRendererAttribute, cAttributeName) g_datalist_get_data (pRendererAttribute->pExtraProperties)*/
///
/// Data Access
///
/**Get the lower range of the i-th value.
*@param pRenderer a data renderer
*@param i the number of the value
*@return a double*/
#define cairo_data_renderer_get_min_value(pRenderer, i) (pRenderer)->data.pMinMaxValues[2*i]
/**Get the upper range of the i-th value.
*@param pRenderer a data renderer
*@param i the number of the value
*@return a double*/
#define cairo_data_renderer_get_max_value(pRenderer, i) (pRenderer)->data.pMinMaxValues[2*i+1]
/**Get the i-th value at the time t.
*@param pRenderer a data renderer
*@param i the number of the value
*@param t the time (in number of steps)
*@return a double*/
#define cairo_data_renderer_get_value(pRenderer, i, t) pRenderer->data.pTabValues[pRenderer->data.iCurrentIndex+t > pRenderer->data.iMemorySize ? pRenderer->data.iCurrentIndex+t-pRenderer->data.iMemorySize : pRenderer->data.iCurrentIndex+t < 0 ? pRenderer->data.iCurrentIndex+t+pRenderer->data.iMemorySize : pRenderer->data.iCurrentIndex+t][i]
/**Get the current i-th value.
*@param pRenderer a data renderer
*@param i the number of the value
*@return a double*/
#define cairo_data_renderer_get_current_value(pRenderer, i) pRenderer->data.pTabValues[pRenderer->data.iCurrentIndex][i]
/**Get the previous i-th value.
*@param pRenderer a data renderer
*@param i the number of the value
*@return a double*/
#define cairo_data_renderer_get_previous_value(pRenderer, i) cairo_data_renderer_get_value (pRenderer, i, -1)
/**Get the normalized i-th value (between 0 and 1) at the time t.
*@param pRenderer a data renderer
*@param i the number of the value
*@param t the time (in number of steps)
*@return a double in [0,1]*/
#define cairo_data_renderer_get_normalized_value(pRenderer, i, t) \
__extension__ ({\
double _x = cairo_data_renderer_get_value (pRenderer, i, t);\
if ( _x > CAIRO_DATA_RENDERER_UNDEF_VALUE+1) {\
_x = MAX (0, MIN (1, (_x - cairo_data_renderer_get_min_value (pRenderer, i)) / (cairo_data_renderer_get_max_value (pRenderer, i) - cairo_data_renderer_get_min_value (pRenderer, i)))); }\
_x; })
/**Get the normalized current i-th value (between 0 and 1).
*@param pRenderer a data renderer
*@param i the number of the value
*@return a double in [0,1]*/
#define cairo_data_renderer_get_normalized_current_value(pRenderer, i) cairo_data_renderer_get_normalized_value(pRenderer, i, 0)
/**Get the normalized previous i-th value (between 0 and 1).
*@param pRenderer a data renderer
*@param i the number of the value
*@return a double in [0,1]*/
#define cairo_data_renderer_get_normalized_previous_value(pRenderer, i) cairo_data_renderer_get_normalized_value(pRenderer, i, -1)
/**Get the normalized current i-th value (between 0 and 1), taking into account the latency of the smooth movement.
*@param pRenderer a data renderer
*@param i the number of the value
*@return a double in [0,1]*/
#define cairo_data_renderer_get_normalized_current_value_with_latency(pRenderer, i) (pRenderer->fLatency == 0 || cairo_data_renderer_get_current_value (pRenderer, i) < CAIRO_DATA_RENDERER_UNDEF_VALUE+1 ? cairo_data_renderer_get_normalized_current_value (pRenderer, i) : cairo_data_renderer_get_normalized_current_value (pRenderer, i) * (1 - pRenderer->fLatency) + (cairo_data_renderer_get_previous_value (pRenderer, i) < CAIRO_DATA_RENDERER_UNDEF_VALUE+1 ? 0 : cairo_data_renderer_get_normalized_previous_value (pRenderer, i)) * pRenderer->fLatency) // if current value is UNDEF, the result is UNDEF, and if previous value is UNDEF, set it to 0.
///
/// Data Format
///
/**Write a value in a readable text format.
*@param pRenderer a data renderer
*@param i the number of the value
*@param cBuffer a buffer where to write*/
#define cairo_data_renderer_format_value_full(pRenderer, i, cBuffer) do {\
if (pRenderer->format_value != NULL)\
(pRenderer)->format_value (pRenderer, i, cBuffer, CAIRO_DOCK_DATA_FORMAT_MAX_LEN, (pRenderer)->pFormatData);\
else {\
double x_ = cairo_data_renderer_get_normalized_current_value (pRenderer, i);\
snprintf (cBuffer, CAIRO_DOCK_DATA_FORMAT_MAX_LEN, x_ < .0995 ? "%.1f" : (x_ < 1 ? " %.0f" : "%.0f"), x_ * 100.); }\
} while (0)
/**Write a value in a readable text format in the renderer text buffer.
*@param pRenderer a data renderer
*@param i the number of the value*/
#define cairo_data_renderer_format_value(pRenderer, i) cairo_data_renderer_format_value_full (pRenderer, i, (pRenderer)->cFormatBuffer)
#define cairo_data_renderer_can_write_values(pRenderer) (pRenderer)->bCanRenderValueAsText
#define cairo_data_renderer_actually_writes_values(pRenderer) (pRenderer)->bCanRenderValueAsText
GHashTable *cairo_dock_list_available_themes_for_data_renderer (const gchar *cRendererName);
gchar *cairo_dock_get_data_renderer_theme_path (const gchar *cRendererName, const gchar *cThemeName, CairoDockPackageType iType);
gchar *cairo_dock_get_package_path_for_data_renderer (const gchar *cRendererName, const gchar *cAppletConfFilePath, GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, const gchar *cDefaultThemeName);
void cairo_dock_register_built_in_data_renderers (void); // merge with init.
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-keybinder.h 000664 001750 001750 00000011622 12223247550 022724 0 ustar 00mbaerts mbaerts 000000 000000 /*
* cairo-dock-keybinder.h
* This file is a part of the Cairo-Dock project
* Login :
* Started on Thu Jan 31 03:57:17 2008 Cedric GESTES
* $Id$
*
* Author(s)
* - Cedric GESTES
* - Havoc Pennington
* - Tim Janik
*
* Copyright : (C) 2008 Cedric GESTES
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*
* imported from tomboy_key_binder.h
*/
#ifndef __CD_KEY_BINDER_H__
#define __CD_KEY_BINDER_H__
#include "cairo-dock-struct.h"
#include "cairo-dock-manager.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-keybinder.h This class defines the Shortkeys, which are objects that bind a keyboard shortcut to an action. The keyboard shortcut is defined globally on the desktop, that is to say they will be effective whatever window has the focus.
* Keyboard shortcuts are of the form <alt>F1 or <ctrl><shift>s.
*
* Use \ref gldi_shortkey_new to create a new shortkey, and simply unref it with \ref gldi_object_unref to unbind the keyboard shortcut.
* To update a binding (whenever the shortcut or the description change, or just to re-grab it), use \ref gldi_shortkey_rebind.
*/
/// Definition of a callback, called when a shortcut is pressed by the user.
typedef void (* CDBindkeyHandler) (const gchar *keystring, gpointer user_data);
struct _GldiShortkey {
/// object.
GldiObject object;
gchar *keystring;
CDBindkeyHandler handler;
gpointer user_data;
guint keycode;
guint modifiers;
gboolean bSuccess;
gchar *cDemander;
gchar *cDescription;
gchar *cIconFilePath;
gchar *cConfFilePath;
gchar *cGroupName;
gchar *cKeyName;
} ;
// manager
typedef struct _GldiShortkeyAttr GldiShortkeyAttr;
#ifndef _MANAGER_DEF_
extern GldiObjectManager myShortkeyObjectMgr;
#endif
struct _GldiShortkeyAttr {
const gchar *keystring;
CDBindkeyHandler handler;
gpointer user_data;
const gchar *cDemander;
const gchar *cDescription;
const gchar *cIconFilePath;
const gchar *cConfFilePath;
const gchar *cGroupName;
const gchar *cKeyName;
};
// signals
typedef enum {
NOTIFICATION_SHORTKEY_CHANGED = NB_NOTIFICATIONS_OBJECT,
NB_NOTIFICATIONS_SHORTKEYS
} GldiShortkeysNotifications;
/** Create a new shortkey, that binds an action to a shortkey. Unref it when you don't want it anymore, or when 'user_data' is freed.
* @param keystring a shortcut.
* @param cDemander the actor making the demand
* @param cDescription a short description of the action
* @param cIconFilePath an icon that represents the demander
* @param cConfFilePath conf file where the shortkey stored
* @param cGroupName group name where it's stored in the conf file
* @param cKeyName key name where it's stored in the conf file
* @param handler function called when the shortkey is pressed by the user
* @param user_data data passed to the callback
* @return the shortkey, already bound.
*/
GldiShortkey *gldi_shortkey_new (const gchar *keystring,
const gchar *cDemander,
const gchar *cDescription,
const gchar *cIconFilePath,
const gchar *cConfFilePath,
const gchar *cGroupName,
const gchar *cKeyName,
CDBindkeyHandler handler,
gpointer user_data);
/** Says if the shortkey of a key binding could be grabbed.
* @param binding a key binding.
* @return TRUE iif the shortkey has been successfuly grabbed by the key binding.
*/
#define gldi_shortkey_could_grab(binding) ((binding)->bSuccess)
/** Rebind a shortkey to a new one. If the shortkey is the same, don't re-bind it.
* @param binding a key binding.
* @param cNewKeyString the new shortkey
* @param cNewDescription the new description, or NULL to keep the current one.
* @return TRUE on success
*/
gboolean gldi_shortkey_rebind (GldiShortkey *binding,
const gchar *cNewKeyString,
const gchar *cNewDescription);
void gldi_shortkeys_foreach (GFunc pCallback, gpointer data);
/** Trigger a given shortkey. It will be as if the user effectively pressed the shortkey on its keyboard. It uses the 'XTest' X extension.
* @param cKeyString a shortkey.
* @return TRUE if success.
*/
gboolean cairo_dock_trigger_shortkey (const gchar *cKeyString);
void gldi_register_shortkeys_manager (void);
G_END_DECLS
#endif /* __CD_KEY_BINDER_H__ */
cairo-dock-3.3.2/src/gldit/cairo-dock-draw-opengl.c 000664 001750 001750 00000077777 12223247550 023211 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include "cairo-dock-icon-facility.h"
#include "cairo-dock-log.h"
#include "cairo-dock-dock-facility.h" // cairo_dock_get_first_drawn_element_linear
#include "cairo-dock-applications-manager.h" // myTaskbarParam.fVisibleAppliAlpha
#include "cairo-dock-windows-manager.h"
#include "cairo-dock-separator-manager.h"
#include "cairo-dock-applet-manager.h"
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-animations.h"
#include "cairo-dock-overlay.h"
#include "cairo-dock-opengl-path.h"
#include "cairo-dock-draw-opengl.h"
#include "texture-gradation.h"
#define RADIAN (G_PI / 180.0) // Conversion Radian/Degres
#define DELTA_ROUND_DEGREE 3
extern GLuint g_pGradationTexture[2];
extern GldiContainer *g_pPrimaryContainer;
extern CairoDockImageBuffer g_pVisibleZoneBuffer;
extern gboolean g_bUseOpenGL;
extern CairoDockGLConfig g_openglConfig;
extern gboolean g_bEasterEggs;
void cairo_dock_set_icon_scale (Icon *pIcon, GldiContainer *pContainer, double fZoomFactor)
{
double fSizeX, fSizeY;
cairo_dock_get_current_icon_size (pIcon, pContainer, &fSizeX, &fSizeY);
glScalef (fSizeX * fZoomFactor, fSizeY * fZoomFactor, fSizeY * fZoomFactor);
}
void cairo_dock_set_container_orientation_opengl (GldiContainer *pContainer)
{
if (pContainer->bIsHorizontal)
{
if (! pContainer->bDirectionUp)
{
glTranslatef (0., pContainer->iHeight, 0.);
glScalef (1., -1., 1.);
}
}
else
{
glTranslatef (pContainer->iHeight/2, pContainer->iWidth/2, 0.);
glRotatef (-90., 0., 0., 1.);
if (pContainer->bDirectionUp)
glScalef (1., -1., 1.);
glTranslatef (-pContainer->iWidth/2, -pContainer->iHeight/2, 0.);
}
}
void cairo_dock_combine_argb_argb (void) // taken from glitz 0.5.6
{
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture (GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glColor4f(0., 0., 0., 1.);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glActiveTexture (GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
}
void cairo_dock_draw_icon_reflect_opengl (Icon *pIcon, CairoDock *pDock)
{
if (pDock->container.bUseReflect)
{
if (pDock->pRenderer->bUseStencil && g_openglConfig.bStencilBufferAvailable)
{
glEnable (GL_STENCIL_TEST);
glStencilFunc (GL_EQUAL, 1, 1);
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
}
glPushMatrix ();
double x0, y0, x1, y1;
double fScale = ((myIconsParam.bConstantSeparatorSize && GLDI_OBJECT_IS_SEPARATOR_ICON (pIcon)) ? 1. : pIcon->fScale);
///double fReflectSize = MIN (myIconsParam.fReflectSize, pIcon->fHeight/pDock->container.fRatio*fScale);
double fReflectSize = pIcon->fHeight * myIconsParam.fReflectHeightRatio * fScale;
///double fReflectRatio = fReflectSize * pDock->container.fRatio / pIcon->fHeight / fScale / pIcon->fHeightFactor;
double fReflectRatio = myIconsParam.fReflectHeightRatio;
double fOffsetY = pIcon->fHeight * fScale/2 + fReflectSize/** * pDock->container.fRatio*/ / 2 + pIcon->fDeltaYReflection;
if (pDock->container.bIsHorizontal)
{
if (pDock->container.bDirectionUp)
{
glTranslatef (0., - fOffsetY, 0.);
glScalef (pIcon->fWidth * pIcon->fWidthFactor * fScale, - fReflectSize/** * pDock->container.fRatio*/, 1.); // taille du reflet et on se retourne.
x0 = 0.;
y0 = 1. - fReflectRatio;
x1 = 1.;
y1 = 1.;
}
else
{
glTranslatef (0., fOffsetY, 0.);
glScalef (pIcon->fWidth * pIcon->fWidthFactor * fScale, fReflectSize/** * pDock->container.fRatio*/, 1.);
x0 = 0.;
y0 = fReflectRatio;
x1 = 1.;
y1 = 0.;
}
}
else
{
if (pDock->container.bDirectionUp)
{
glTranslatef (fOffsetY, 0., 0.);
glScalef (- fReflectSize/** * pDock->container.fRatio*/, pIcon->fWidth * pIcon->fWidthFactor * fScale, 1.);
x0 = 1. - fReflectRatio;
y0 = 0.;
x1 = 1.;
y1 = 1.;
}
else
{
glTranslatef (- fOffsetY, 0., 0.);
glScalef (fReflectSize/** * pDock->container.fRatio*/, pIcon->fWidth * pIcon->fWidthFactor * fScale, 1.);
x0 = fReflectRatio;
y0 = 0.;
x1 = 0.;
y1 = 1.;
}
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, pIcon->image.iTexture);
glEnable(GL_BLEND);
_cairo_dock_set_blend_alpha ();
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//glBlendColor(1., 1., 1., 1.); // utile ?
glPolygonMode (GL_FRONT, GL_FILL);
glColor4f(1., 1., 1., 1.);
glBegin(GL_QUADS);
double fReflectAlpha = myIconsParam.fAlbedo * pIcon->fAlpha;
if (pDock->container.bIsHorizontal)
{
glTexCoord2f (x0, y0);
glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
glVertex3f (-.5, .5, 0.); // Bottom Left Of The Texture and Quad
glTexCoord2f (x1, y0);
glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
glVertex3f (.5, .5, 0.); // Bottom Right Of The Texture and Quad
glTexCoord2f (x1, y1);
glColor4f (1., 1., 1., fReflectAlpha);
glVertex3f (.5, -.5, 0.); // Top Right Of The Texture and Quad
glTexCoord2f (x0, y1);
glColor4f (1., 1., 1., fReflectAlpha);
glVertex3f (-.5, -.5, 0.); // Top Left Of The Texture and Quad
}
else
{
glTexCoord2f (x0, y0);
glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
glVertex3f (-.5, .5, 0.); // Bottom Left Of The Texture and Quad
glTexCoord2f (x1, y0);
glColor4f (1., 1., 1., fReflectAlpha);
glVertex3f (.5, .5, 0.); // Bottom Right Of The Texture and Quad
glTexCoord2f (x1, y1);
glColor4f (1., 1., 1., fReflectAlpha);
glVertex3f (.5, -.5, 0.); // Top Right Of The Texture and Quad
glTexCoord2f (x0, y1);
glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
glVertex3f (-.5, -.5, 0.); // Top Left Of The Texture and Quad
}
glEnd();
glPopMatrix ();
if (pDock->pRenderer->bUseStencil && g_openglConfig.bStencilBufferAvailable)
{
glDisable (GL_STENCIL_TEST);
}
}
}
void cairo_dock_draw_icon_opengl (Icon *pIcon, CairoDock *pDock)
{
//\_____________________ On dessine l'icone.
double fSizeX, fSizeY;
cairo_dock_get_current_icon_size (pIcon, CAIRO_CONTAINER (pDock), &fSizeX, &fSizeY);
_cairo_dock_enable_texture ();
if (pIcon->fAlpha == 1)
_cairo_dock_set_blend_pbuffer ();
else
_cairo_dock_set_blend_alpha ();
_cairo_dock_apply_texture_at_size_with_alpha (pIcon->image.iTexture, fSizeX, fSizeY, pIcon->fAlpha);
//if (g_strcmp0 (pIcon->cName, "Calculatrice") == 0)
//g_print ("%s: %.2f\n", pIcon->cName, pIcon->fAlpha);
//\_____________________ On dessine son reflet.
cairo_dock_draw_icon_reflect_opengl (pIcon, pDock);
_cairo_dock_disable_texture ();
}
static inline void _compute_icon_coordinate (Icon *icon, GldiContainer *pContainer, double fDockMagnitude, double *pX, double *pY)
{
double fX=0, fY=0;
double fRatio = pContainer->fRatio;
double fGlideScale;
if (icon->fGlideOffset != 0)
{
double fPhase = icon->fPhase + icon->fGlideOffset * icon->fWidth / fRatio / myIconsParam.iSinusoidWidth * G_PI;
if (fPhase < 0)
{
fPhase = 0;
}
else if (fPhase > G_PI)
{
fPhase = G_PI;
}
fGlideScale = (1 + fDockMagnitude * myIconsParam.fAmplitude * sin (fPhase)) / icon->fScale; // c'est un peu hacky ... il faudrait passer l'icone precedente en parametre ...
if (! pContainer->bDirectionUp)
{
if (pContainer->bIsHorizontal)
fY = (1-fGlideScale)*icon->fHeight*icon->fScale;
else
fX = (1-fGlideScale)*icon->fHeight*icon->fScale;
}
}
else
fGlideScale = 1;
icon->fGlideScale = fGlideScale;
if (pContainer->bIsHorizontal)
{
fY += pContainer->iHeight - icon->fDrawY; // ordonnee du haut de l'icone.
fX += icon->fDrawX + icon->fWidth * icon->fScale/2 + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1); // abscisse du milieu de l'icone.
}
else
{
fY += icon->fDrawY; // ordonnee du haut de l'icone.
fX += pContainer->iWidth - (icon->fDrawX + icon->fWidth * icon->fScale/2 + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1));
}
*pX = fX;
*pY = fY;
}
void cairo_dock_translate_on_icon_opengl (Icon *icon, GldiContainer *pContainer, double fDockMagnitude)
{
double fX=0, fY=0;
_compute_icon_coordinate (icon, pContainer, fDockMagnitude, &fX, &fY);
double fMaxScale = cairo_dock_get_icon_max_scale (icon);
if (pContainer->bIsHorizontal)
glTranslatef ( (fX), (fY - icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2)), - icon->fHeight * fMaxScale);
else
glTranslatef ( (fY + icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2)), (fX), - icon->fHeight * fMaxScale);
}
void cairo_dock_render_one_icon_opengl (Icon *icon, CairoDock *pDock, double fDockMagnitude, gboolean bUseText)
{
if (icon->image.iTexture == 0)
return ;
double fRatio = pDock->container.fRatio;
if (g_pGradationTexture[pDock->container.bIsHorizontal] == 0)
{
//g_pGradationTexture[pDock->container.bIsHorizontal] = cairo_dock_load_local_texture (pDock->container.bIsHorizontal ? "texture-gradation-vert.png" : "texture-gradation-horiz.png", GLDI_SHARE_DATA_DIR);
g_pGradationTexture[pDock->container.bIsHorizontal] = cairo_dock_create_texture_from_raw_data (gradationTex,
pDock->container.bIsHorizontal ? 1:48,
pDock->container.bIsHorizontal ? 48:1);
cd_debug ("g_pGradationTexture(%d) <- %d", pDock->container.bIsHorizontal, g_pGradationTexture[pDock->container.bIsHorizontal]);
}
if (CAIRO_DOCK_IS_APPLI (icon) && myTaskbarParam.fVisibleAppliAlpha != 0 && ! GLDI_OBJECT_IS_APPLET_ICON (icon) && !(myTaskbarParam.iMinimizedWindowRenderType == 1 && icon->pAppli->bIsHidden))
{
double fAlpha = (icon->pAppli->bIsHidden ? MIN (1 - myTaskbarParam.fVisibleAppliAlpha, 1) : MIN (myTaskbarParam.fVisibleAppliAlpha + 1, 1));
if (fAlpha != 1)
icon->fAlpha = fAlpha; // astuce bidon pour pas multiplier 2 fois.
}
//\_____________________ On se place au centre de l'icone.
double fX=0, fY=0;
_compute_icon_coordinate (icon, CAIRO_CONTAINER (pDock), fDockMagnitude * pDock->fMagnitudeMax, &fX, &fY);
glPushMatrix ();
if (pDock->container.bIsHorizontal)
glTranslatef (fX, fY - icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2), - icon->fHeight * icon->fScale);
else
glTranslatef (fY + icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2), fX, - icon->fHeight * icon->fScale);
//\_____________________ On positionne l'icone.
glPushMatrix ();
if (myIconsParam.bConstantSeparatorSize && GLDI_OBJECT_IS_SEPARATOR_ICON (icon))
{
if (pDock->container.bIsHorizontal)
{
glTranslatef (0., (pDock->container.bDirectionUp ? icon->fHeight * (- icon->fScale + 1)/2 : icon->fHeight * (icon->fScale - 1)/2), 0.);
}
else
{
glTranslatef ((!pDock->container.bDirectionUp ? icon->fHeight * (- icon->fScale + 1)/2 : icon->fHeight * (icon->fScale - 1)/2), 0., 0.);
}
}
if (icon->fOrientation != 0)
{
glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
}
if (GLDI_OBJECT_IS_SEPARATOR_ICON (icon) && myIconsParam.bRevolveSeparator)
{
if (pDock->container.bIsHorizontal)
{
if (! pDock->container.bDirectionUp)
{
glScalef (1., -1., 1.);
}
}
else
{
glMatrixMode(GL_TEXTURE);
glRotatef (-90., 0., 0., 1.);
glMatrixMode (GL_MODELVIEW);
if (pDock->container.bDirectionUp)
glScalef (1., -1., 1.);
}
}
if (icon->iRotationX != 0)
glRotatef (icon->iRotationX, 1., 0., 0.);
if (icon->iRotationY != 0)
glRotatef (icon->iRotationY, 0., 1., 0.);
//\_____________________ On dessine l'icone.
gboolean bIconHasBeenDrawn = FALSE;
gldi_object_notify (&myIconObjectMgr, NOTIFICATION_PRE_RENDER_ICON, icon, pDock, NULL);
gldi_object_notify (&myIconObjectMgr, NOTIFICATION_RENDER_ICON, icon, pDock, &bIconHasBeenDrawn, NULL);
glPopMatrix (); // retour juste apres la translation au milieu de l'icone.
if (GLDI_OBJECT_IS_SEPARATOR_ICON (icon) && myIconsParam.bRevolveSeparator && !pDock->container.bIsHorizontal)
{
glMatrixMode(GL_TEXTURE);
glLoadIdentity ();
glMatrixMode (GL_MODELVIEW);
}
//\_____________________ Draw the overlays on top of that.
cairo_dock_draw_icon_overlays_opengl (icon, fRatio);
//\_____________________ On dessine les etiquettes, avec un alpha proportionnel au facteur d'echelle de leur icone.
glPopMatrix (); // retour au debut de la fonction.
if (bUseText && icon->label.iTexture != 0 && icon->iHideLabel == 0
&& (icon->bPointed || (icon->fScale > 1.01 && ! myIconsParam.bLabelForPointedIconOnly))) // 1.01 car sin(pi) = 1+epsilon :-/ // && icon->iAnimationState < CAIRO_DOCK_STATE_CLICKED
{
glPushMatrix ();
glLoadIdentity ();
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_alpha (); // not good with a transparent background :-/
double fMagnitude;
if (myIconsParam.bLabelForPointedIconOnly || pDock->fMagnitudeMax == 0. || myIconsParam.fAmplitude == 0.)
{
fMagnitude = fDockMagnitude; // (icon->fScale - 1) / myIconsParam.fAmplitude / sin (icon->fPhase); // sin (phi ) != 0 puisque fScale > 1.
}
else
{
fMagnitude = (icon->fScale - 1) / myIconsParam.fAmplitude; /// il faudrait diviser par pDock->fMagnitudeMax ...
fMagnitude = pow (fMagnitude, myIconsParam.fLabelAlphaThreshold);
///fMagnitude *= (fMagnitude * myIconsParam.fLabelAlphaThreshold + 1) / (myIconsParam.fLabelAlphaThreshold + 1);
}
double dx = .5 * (icon->label.iWidth & 1); // on decale la texture pour la coller sur la grille des coordonnees entieres.
double dy = .5 * (icon->label.iHeight & 1);
if (pDock->container.bIsHorizontal || !myIconsParam.bTextAlwaysHorizontal)
{
if (fX + icon->label.iWidth/2 > pDock->container.iWidth) // l'etiquette deborde a droite.
fX = pDock->container.iWidth - icon->label.iWidth/2;
if (fX - icon->label.iWidth/2 < 0) // l'etiquette deborde a gauche.
fX = icon->label.iWidth/2;
if (pDock->container.bIsHorizontal)
glTranslatef (floor (fX) + dx,
pDock->container.bDirectionUp ?
floor (fY + myIconsParam.iLabelSize - icon->label.iHeight / 2) - dy:
floor (fY - icon->fHeight * icon->fScale - myIconsParam.iLabelSize + icon->label.iHeight / 2) + dy,
0.);
else
{
glTranslatef (pDock->container.bDirectionUp ?
floor (fY - myIconsParam.iLabelSize + icon->label.iHeight / 2) - dy:
floor (fY + icon->fHeight * icon->fScale + myIconsParam.iLabelSize - icon->label.iHeight / 2) + dy,
floor (fX) + dx,
0.);
glRotatef (pDock->container.bDirectionUp ? 90 : -90, 0., 0., 1.);
}
if (icon->fOrientation != 0 && ! myIconsParam.bTextAlwaysHorizontal)
{
glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
}
_cairo_dock_set_alpha (fMagnitude);
cairo_dock_apply_image_buffer_texture (&icon->label);
}
else // horizontal label on a vertical dock -> draw them next to the icon, vertically centered (like the Parabolic view)
{
if (icon->pSubDock && gldi_container_is_visible (CAIRO_CONTAINER (icon->pSubDock)))
{
fMagnitude /= 3;
}
const int pad = 3;
int iXStick = (pDock->container.bDirectionUp ?
floor (fY - (myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin) * (1 - pDock->fMagnitudeMax) - pad) : // right border
floor (fY + icon->fHeight * icon->fScale + (myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin) * (1 - pDock->fMagnitudeMax) + pad)); // left border
int iMaxWidth = (pDock->container.bDirectionUp ?
iXStick :
pDock->container.iHeight - iXStick);
int w;
if (icon->label.iWidth > iMaxWidth)
{
w = iMaxWidth;
dx = .5 * (w & 1);
}
else
{
w = icon->label.iWidth;
}
glTranslatef ((pDock->container.bDirectionUp ?
floor (iXStick - w/2) + dx :
floor (iXStick + w/2) + dx),
floor (fX) + dy,
0.);
if (icon->label.iWidth > iMaxWidth) // draw with an alpha gradation on the last part.
{
cairo_dock_apply_image_buffer_texture_with_limit (&icon->label, fMagnitude, iMaxWidth);
/*glBindTexture (GL_TEXTURE_2D, icon->label.iTexture);
double h = icon->label.iHeight;
double u0 = 0., u1 = (double) iMaxWidth / icon->label.iWidth;
glBegin(GL_QUAD_STRIP);
double a = .75; // 3/4 plain, 1/4 gradation
a = (double) (floor ((-.5+a)*w)) / w + .5;
glColor4f (1., 1., 1., fMagnitude);
glTexCoord2f(u0, 0); glVertex3f (-.5*w, .5*h, 0.); // top left
glTexCoord2f(u0, 1); glVertex3f (-.5*w, -.5*h, 0.); // bottom left
glTexCoord2f(u1*a, 0); glVertex3f ((-.5+a)*w, .5*h, 0.); // top middle
glTexCoord2f(u1*a, 1); glVertex3f ((-.5+a)*w, -.5*h, 0.); // bottom middle
glColor4f (1., 1., 1., 0.);
glTexCoord2f(u1, 0); glVertex3f (.5*w, .5*h, 0.); // top right
glTexCoord2f(u1, 1); glVertex3f (.5*w, -.5*h, 0.); // bottom right
glEnd();*/
}
else
{
_cairo_dock_set_alpha (fMagnitude);
cairo_dock_apply_image_buffer_texture_with_offset (&icon->label, 0, 0);
}
}
/*_cairo_dock_set_alpha (fMagnitude);
cairo_dock_apply_image_buffer_texture (&icon->label);*/
_cairo_dock_disable_texture ();
glPopMatrix ();
}
}
void cairo_dock_render_hidden_dock_opengl (CairoDock *pDock)
{
//g_print ("%s (%d, %x)\n", __func__, pDock->bIsMainDock, g_pVisibleZoneSurface);
//\_____________________ on dessine la zone de rappel.
if (g_pVisibleZoneBuffer.iTexture != 0)
{
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_over ();
int w = MIN (myDocksParam.iZoneWidth, pDock->container.iWidth);
int h = MIN (myDocksParam.iZoneHeight, pDock->container.iHeight);
cd_debug ("%s (%dx%d)", __func__, w, h);
if (pDock->container.bIsHorizontal)
{
if (pDock->container.bDirectionUp)
glTranslatef ((pDock->container.iWidth)/2, h/2, 0.);
else
glTranslatef ((pDock->container.iWidth)/2, pDock->container.iHeight - h/2, 0.);
}
else
{
if (!pDock->container.bDirectionUp)
glTranslatef (h/2, (pDock->container.iWidth)/2, 0.);
else
glTranslatef (pDock->container.iHeight - h/2, (pDock->container.iWidth)/2, 0.);
}
if (! pDock->container.bIsHorizontal)
glRotatef (90., 0, 0, 1);
if (! pDock->container.bDirectionUp) // reverse image with dock.
glScalef (1., -1., 1.);
_cairo_dock_apply_texture_at_size (g_pVisibleZoneBuffer.iTexture, w, h);
_cairo_dock_disable_texture ();
}
//\_____________________ on dessine les icones demandant l'attention.
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
if (pFirstDrawnElement == NULL)
return;
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
double y;
Icon *icon;
GList *ic = pFirstDrawnElement;
double pHiddenBgColor[4];
const double r = 4; // corner radius of the background
const double gap = 2; // gap to the screen
double dw = (myIconsParam.iIconGap > 2 ? 2 : 0); // 1px margin around the icons for a better readability (only if icons won't be stuck togather then).
double w, h;
_cairo_dock_set_blend_alpha ();
do
{
icon = ic->data;
if (icon->bIsDemandingAttention || icon->bAlwaysVisible)
{
//g_print ("%s : %d (%d)\n", icon->cName, icon->bIsDemandingAttention, icon->Xid);
y = icon->fDrawY;
icon->fDrawY = (pDock->container.bDirectionUp ? pDock->container.iHeight - icon->fHeight * icon->fScale - gap : gap);
if (icon->bHasHiddenBg)
{
if (icon->pHiddenBgColor) // custom bg color
memcpy (pHiddenBgColor, icon->pHiddenBgColor, 4*sizeof (gdouble));
else // default bg color
memcpy (pHiddenBgColor, myDocksParam.fHiddenBg, 4*sizeof (gdouble));
pHiddenBgColor[3] *= pDock->fPostHideOffset;
if (pHiddenBgColor[3] != 0)
{
_cairo_dock_set_blend_alpha ();
glPushMatrix ();
w = icon->fWidth * icon->fScale;
h = icon->fHeight * icon->fScale;
if (pDock->container.bIsHorizontal)
{
glTranslatef (icon->fDrawX + w/2,
pDock->container.iHeight - icon->fDrawY - h/2,
0.);
cairo_dock_draw_rounded_rectangle_opengl (w - 2*r + dw, h, r, 0, pHiddenBgColor);
}
else
{
glTranslatef (icon->fDrawY + h/2,
pDock->container.iWidth - icon->fDrawX - w/2,
0.);
cairo_dock_draw_rounded_rectangle_opengl (h - 2*r + dw, w, r, 0, pHiddenBgColor);
}
glPopMatrix ();
}
}
glPushMatrix ();
icon->fAlpha = pDock->fPostHideOffset * pDock->fPostHideOffset;
cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE);
glPopMatrix ();
icon->fDrawY = y;
}
ic = cairo_dock_get_next_element (ic, pDock->icons);
} while (ic != pFirstDrawnElement);
}
GLuint cairo_dock_create_texture_from_surface (cairo_surface_t *pImageSurface)
{
if (! g_bUseOpenGL || pImageSurface == NULL)
return 0;
GLuint iTexture = 0;
int w = cairo_image_surface_get_width (pImageSurface);
int h = cairo_image_surface_get_height (pImageSurface);
//g_print ("%s (%dx%d)\n", __func__, w, h);
cairo_surface_t *pPowerOfwoSurface = pImageSurface;
int iMaxTextureWidth = 4096, iMaxTextureHeight = 4096; // il faudrait le recuperer de glInfo ...
if (! g_openglConfig.bNonPowerOfTwoAvailable) // cas des vieilles cartes comme la GeForce5.
{
double log2_w = log (w) / log (2);
double log2_h = log (h) / log (2);
int w_ = MIN (iMaxTextureWidth, pow (2, ceil (log2_w)));
int h_ = MIN (iMaxTextureHeight, pow (2, ceil (log2_h)));
cd_debug ("%dx%d --> %dx%d", w, h, w_, h_);
if (w != w_ || h != h_)
{
pPowerOfwoSurface = cairo_dock_create_blank_surface (w_, h_);
cairo_t *pCairoContext = cairo_create (pPowerOfwoSurface);
cairo_scale (pCairoContext, (double) w_ / w, (double) h_ / h);
cairo_set_source_surface (pCairoContext, pImageSurface, 0., 0.);
cairo_paint (pCairoContext);
cairo_destroy (pCairoContext);
w = w_;
h = h_;
}
}
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_source ();
_cairo_dock_set_alpha (1.); // full white
glGenTextures (1, &iTexture);
//g_print ("+ texture %d generee (%p, %dx%d)\n", iTexture, cairo_image_surface_get_data (pImageSurface), w, h);
glBindTexture (GL_TEXTURE_2D, iTexture);
glTexParameteri (GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
g_bEasterEggs ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
if (g_bEasterEggs)
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (g_bEasterEggs)
gluBuild2DMipmaps (GL_TEXTURE_2D, /// see for automatic mipmaps generation, or at least how to update the mipmaps...
4,
w,
h,
GL_BGRA,
GL_UNSIGNED_BYTE,
cairo_image_surface_get_data (pPowerOfwoSurface));
else
glTexImage2D (GL_TEXTURE_2D,
0,
4, // GL_ALPHA / GL_BGRA
w,
h,
0,
GL_BGRA, // GL_ALPHA / GL_BGRA
GL_UNSIGNED_BYTE,
cairo_image_surface_get_data (pPowerOfwoSurface));
if (pPowerOfwoSurface != pImageSurface)
cairo_surface_destroy (pPowerOfwoSurface);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
return iTexture;
}
GLuint cairo_dock_create_texture_from_raw_data (const guchar *pTextureRaw, int iWidth, int iHeight)
{
/*cd_debug ("%dx%d", iWidth, iHeight);
int i;
guint pixel, alpha, red, green, blue;
float fAlphaFactor;
guint *pPixelBuffer = (guint *) pTextureRaw;
guint *pPixelBuffer2 = g_new (guint, iHeight * iWidth);
for (i = 0; i < iHeight * iWidth; i ++)
{
pixel = (gint) pPixelBuffer[i];
alpha = (pixel & 0xFF000000) >> 24;
red = (pixel & 0x00FF0000) >> 16;
green = (pixel & 0x0000FF00) >> 8;
blue = (pixel & 0x000000FF);
fAlphaFactor = (float) alpha / 255.;
red *= fAlphaFactor;
green *= fAlphaFactor;
blue *= fAlphaFactor;
pPixelBuffer2[i] = (pixel & 0xFF000000) + (red << 16) + (green << 8) + (blue << 0);
cd_debug ("\\%o\\%o\\%o\\%o", red, green, blue, alpha);
}
pTextureRaw = pPixelBuffer2;*/
GLuint iTexture = 0;
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_source ();
glColor4f (1., 1., 1., 1.);
glGenTextures(1, &iTexture);
glBindTexture(GL_TEXTURE_2D, iTexture);
glTexParameteri (GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
g_bEasterEggs ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
if (g_bEasterEggs)
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (g_bEasterEggs && pTextureRaw)
gluBuild2DMipmaps (GL_TEXTURE_2D,
4,
iWidth,
iHeight,
GL_RGBA,
GL_UNSIGNED_BYTE,
pTextureRaw);
else
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, iWidth, iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTextureRaw);
glBindTexture (GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
return iTexture;
}
GLuint cairo_dock_create_texture_from_image_full (const gchar *cImageFile, double *fImageWidth, double *fImageHeight)
{
#if (GTK_MAJOR_VERSION < 3 && GTK_MINOR_VERSION < 20)
g_return_val_if_fail (GTK_WIDGET_REALIZED (g_pPrimaryContainer->pWidget), 0);
#else
g_return_val_if_fail (gtk_widget_get_realized (g_pPrimaryContainer->pWidget), 0);
#endif
double fWidth=0, fHeight=0;
if (cImageFile == NULL)
return 0;
gchar *cImagePath;
if (*cImageFile == '/')
cImagePath = (gchar *)cImageFile;
else
cImagePath = cairo_dock_search_image_s_path (cImageFile);
cairo_surface_t *pSurface = cairo_dock_create_surface_from_image (cImagePath,
1.,
0., 0.,
CAIRO_DOCK_KEEP_RATIO,
&fWidth,
&fHeight,
NULL, NULL);
//cd_debug ("texture genere (%x, %.2fx%.2f)", pSurface, fWidth, fHeight);
if (fImageWidth != NULL)
*fImageWidth = fWidth;
if (fImageHeight != NULL)
*fImageHeight = fHeight;
GLuint iTexture = cairo_dock_create_texture_from_surface (pSurface);
cairo_surface_destroy (pSurface);
if (cImagePath != cImageFile)
g_free (cImagePath);
return iTexture;
}
void cairo_dock_update_icon_texture (Icon *pIcon)
{
if (pIcon != NULL && pIcon->image.pSurface != NULL)
{
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_source ();
_cairo_dock_set_alpha (1.); // full white
if (pIcon->image.iTexture == 0)
glGenTextures (1, &pIcon->image.iTexture);
int w = cairo_image_surface_get_width (pIcon->image.pSurface);
int h = cairo_image_surface_get_height (pIcon->image.pSurface);
glBindTexture (GL_TEXTURE_2D, pIcon->image.iTexture);
glTexParameteri (GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
g_bEasterEggs ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
if (g_bEasterEggs)
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (g_bEasterEggs)
gluBuild2DMipmaps (GL_TEXTURE_2D,
4,
w,
h,
GL_BGRA,
GL_UNSIGNED_BYTE,
cairo_image_surface_get_data (pIcon->image.pSurface));
else
glTexImage2D (GL_TEXTURE_2D,
0,
4, // GL_ALPHA / GL_BGRA
w,
h,
0,
GL_BGRA, // GL_ALPHA / GL_BGRA
GL_UNSIGNED_BYTE,
cairo_image_surface_get_data (pIcon->image.pSurface));
glDisable (GL_TEXTURE_2D);
}
}
void cairo_dock_draw_texture_with_alpha (GLuint iTexture, int iWidth, int iHeight, double fAlpha)
{
_cairo_dock_enable_texture ();
//~ if (fAlpha == 1)
//~ _cairo_dock_set_blend_over ();
//~ else
///_cairo_dock_set_blend_alpha ();
_cairo_dock_set_blend_over (); // gives the best result, at least with fAlpha=1
_cairo_dock_apply_texture_at_size_with_alpha (iTexture, iWidth, iHeight, fAlpha);
_cairo_dock_disable_texture ();
}
void cairo_dock_draw_texture (GLuint iTexture, int iWidth, int iHeight)
{
cairo_dock_draw_texture_with_alpha (iTexture, iWidth, iHeight, 1.);
}
void cairo_dock_apply_icon_texture_at_current_size (Icon *pIcon, GldiContainer *pContainer)
{
double fSizeX, fSizeY;
cairo_dock_get_current_icon_size (pIcon, pContainer, &fSizeX, &fSizeY);
_cairo_dock_apply_texture_at_size (pIcon->image.iTexture, fSizeX, fSizeY);
}
void cairo_dock_draw_icon_texture (Icon *pIcon, GldiContainer *pContainer)
{
double fSizeX, fSizeY;
cairo_dock_get_current_icon_size (pIcon, pContainer, &fSizeX, &fSizeY);
cairo_dock_draw_texture_with_alpha (pIcon->image.iTexture,
fSizeX,
fSizeY,
pIcon->fAlpha);
}
static inline void _draw_icon_bent_backwards (Icon *pIcon, GldiContainer *pContainer, GLuint iOriginalTexture, double f)
{
cairo_dock_set_perspective_view_for_icon (pIcon, pContainer);
int iWidth, iHeight;
cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
glScalef (1., -1., 1.);
glTranslatef (0., -iHeight/2, 0.); // rotation de 50° sur l'axe des X a la base de l'icone.
glRotatef (-50.*f, 1., 0., 0.);
glTranslatef (0., iHeight/2, 0.);
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_source ();
glBindTexture (GL_TEXTURE_2D, iOriginalTexture);
double a=.25, b=.1;
//double a=.0, b=.0;
_cairo_dock_apply_current_texture_at_size_with_offset (iWidth*(1+b*f),
iHeight*(1+a*f),
0.,
iHeight*(a/2*f)); // on elargit un peu la texture, car avec l'effet de profondeur elle parait trop petite.
_cairo_dock_disable_texture ();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, pContainer->iWidth, pContainer->iHeight);
glMatrixMode(GL_MODELVIEW);
cairo_dock_set_ortho_view (pContainer);
}
static gboolean _transition_step (Icon *pIcon, gpointer data)
{
CairoDock *pDock = gldi_dock_get (pIcon->cParentDockName);
if (pDock == NULL)
return FALSE;
GLuint iOriginalTexture = GPOINTER_TO_INT (data);
double f = cairo_dock_get_transition_fraction (pIcon);
if (!pIcon->pAppli->bIsHidden)
f = 1 - f;
_draw_icon_bent_backwards (pIcon, CAIRO_CONTAINER (pDock), iOriginalTexture, f);
return TRUE;
}
static void _free_transition_data (gpointer data)
{
GLuint iOriginalTexture = GPOINTER_TO_INT (data);
_cairo_dock_delete_texture (iOriginalTexture);
}
void cairo_dock_draw_hidden_appli_icon (Icon *pIcon, GldiContainer *pContainer, gboolean bStateChanged)
{
if (bStateChanged)
{
cairo_dock_remove_transition_on_icon (pIcon);
GLuint iOriginalTexture;
if (pIcon->pAppli->bIsHidden)
{
iOriginalTexture = pIcon->image.iTexture;
pIcon->image.iTexture = cairo_dock_create_texture_from_surface (pIcon->image.pSurface);
/// Using FBOs copies the texture data (pixels) within VRAM only:
/// - setup & bind FBO
/// - setup destination texture (using glTexImage() w/ pixels = 0)
/// - add (blank but sized) destination texture as color attachment
/// - bind source texture to texture target
/// - draw quad w/ glTexCoors describing src area, projection/modelview matrices & glVertexes describing dst area
}
else
{
iOriginalTexture = cairo_dock_create_texture_from_surface (pIcon->image.pSurface);
}
cairo_dock_set_transition_on_icon (pIcon, pContainer,
(CairoDockTransitionRenderFunc) NULL,
(CairoDockTransitionGLRenderFunc) _transition_step,
TRUE, // slow
500, // ms
TRUE, // remove when finished
GINT_TO_POINTER (iOriginalTexture),
_free_transition_data);
}
else if (pIcon->pAppli->bIsHidden)
{
if (!cairo_dock_begin_draw_icon (pIcon, 2))
return ;
_draw_icon_bent_backwards (pIcon, pContainer, pIcon->image.iTexture, 1.);
cairo_dock_end_draw_icon (pIcon);
}
}
cairo-dock-3.3.2/src/gldit/cairo-dock-desklet-factory.h 000664 001750 001750 00000030157 12223247550 024054 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
* Login :
* Started on Sun Jan 27 18:35:38 2008 Cedric GESTES
* $Id$
*
* Author(s)
* - Cedric GESTES
* - Fabrice REY
*
* Copyright : (C) 2008 Cedric GESTES
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DESKLET_FACTORY_H__
#define __CAIRO_DESKLET_FACTORY_H__
#include "cairo-dock-struct.h"
#include "cairo-dock-surface-factory.h"
#include "cairo-dock-image-buffer.h"
#include "cairo-dock-container.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-desklet-factory.h This class defines the Desklets, that are Widgets placed directly on your desktop.
* A Desklet is a container that holds 1 applet's icon plus an optionnal list of other icons and an optionnal GTK widget, has a decoration, suports several accessibility types (like Compiz Widget Layer), and has a renderer.
* Desklets can be resized or moved directly with the mouse, and can be rotated in the 3 directions of space.
* To actually create or destroy a Desklet, use the Desklet Manager's functoins in \ref cairo-dock-desklet-manager.h.
*/
/// Type of accessibility of a Desklet.
typedef enum {
/// Normal, like normal window
CAIRO_DESKLET_NORMAL = 0,
/// always above
CAIRO_DESKLET_KEEP_ABOVE,
/// always below
CAIRO_DESKLET_KEEP_BELOW,
/// on the Compiz widget layer
CAIRO_DESKLET_ON_WIDGET_LAYER,
/// prevent other windows form overlapping it
CAIRO_DESKLET_RESERVE_SPACE
} CairoDeskletVisibility;
/// Decoration of a Desklet.
struct _CairoDeskletDecoration {
const gchar *cDisplayedName;
gchar *cBackGroundImagePath;
gchar *cForeGroundImagePath;
CairoDockLoadImageModifier iLoadingModifier;
gdouble fBackGroundAlpha;
gdouble fForeGroundAlpha;
gint iLeftMargin;
gint iTopMargin;
gint iRightMargin;
gint iBottomMargin;
};
typedef struct _CairoDeskletAttr CairoDeskletAttr;
/// Configuration attributes of a Desklet.
struct _CairoDeskletAttr {
// parent attributes
GldiContainerAttr cattr;
gboolean bDeskletUseSize;
gint iDeskletWidth;
gint iDeskletHeight;
gint iDeskletPositionX;
gint iDeskletPositionY;
gboolean bPositionLocked;
gint iRotation;
gint iDepthRotationY;
gint iDepthRotationX;
gchar *cDecorationTheme;
CairoDeskletDecoration *pUserDecoration;
CairoDeskletVisibility iVisibility;
gboolean bOnAllDesktops;
gint iNumDesktop;
gboolean bNoInput;
Icon *pIcon;
} ;
typedef gpointer CairoDeskletRendererDataParameter;
typedef CairoDeskletRendererDataParameter* CairoDeskletRendererDataPtr;
typedef gpointer CairoDeskletRendererConfigParameter;
typedef CairoDeskletRendererConfigParameter* CairoDeskletRendererConfigPtr;
typedef struct {
gchar *cName;
CairoDeskletRendererConfigPtr pConfig;
} CairoDeskletRendererPreDefinedConfig;
typedef void (* CairoDeskletRenderFunc) (cairo_t *pCairoContext, CairoDesklet *pDesklet);
typedef void (*CairoDeskletGLRenderFunc) (CairoDesklet *pDesklet);
typedef gpointer (* CairoDeskletConfigureRendererFunc) (CairoDesklet *pDesklet, CairoDeskletRendererConfigPtr pConfig);
typedef void (* CairoDeskletLoadRendererDataFunc) (CairoDesklet *pDesklet);
typedef void (* CairoDeskletUpdateRendererDataFunc) (CairoDesklet *pDesklet, CairoDeskletRendererDataPtr pNewData);
typedef void (* CairoDeskletFreeRendererDataFunc) (CairoDesklet *pDesklet);
typedef void (* CairoDeskletCalculateIconsFunc) (CairoDesklet *pDesklet);
/// Definition of a Desklet's renderer.
struct _CairoDeskletRenderer {
/// rendering function with libcairo.
CairoDeskletRenderFunc render;
/// rendering function with OpenGL.
CairoDeskletGLRenderFunc render_opengl;
/// get the configuration of the renderer from a set of config attributes.
CairoDeskletConfigureRendererFunc configure;
/// load the internal data of the renderer.
CairoDeskletLoadRendererDataFunc load_data;
/// free all internal data of the renderer.
CairoDeskletFreeRendererDataFunc free_data;
/// define the icons' size and load them.
CairoDeskletCalculateIconsFunc calculate_icons;
/// function called on each iteration of the rendering loop.
CairoDeskletUpdateRendererDataFunc update;
/// optionnal rendering function with OpenGL that only draws the bounding boxes of the icons (for picking).
CairoDeskletGLRenderFunc render_bounding_box;
/// An optionnal list of preset configs.
GList *pPreDefinedConfigList;
};
/// Definition of a Desklet, which derives from a Container.
struct _CairoDesklet {
//\________________ Core
// container
GldiContainer container;
// Main icon (usually an applet)
Icon *pIcon;
// List of sub-icons (possibly NULL)
GList *icons;
// Renderer used to draw the desklet
CairoDeskletRenderer *pRenderer;
// data used by the renderer
gpointer pRendererData;
// The following function outclasses the corresponding function of the renderer. This is useful if you don't want to pick icons but some elements that you draw yourself on the desklet.
CairoDeskletGLRenderFunc render_bounding_box;
// ID of the object that was picked in case the previous function is not null.
GLuint iPickedObject;
//\________________ decorations
gchar *cDecorationTheme;
CairoDeskletDecoration *pUserDecoration;
gint iLeftSurfaceOffset;
gint iTopSurfaceOffset;
gint iRightSurfaceOffset;
gint iBottomSurfaceOffset;
CairoDockImageBuffer backGroundImageBuffer;
CairoDockImageBuffer foreGroundImageBuffer;
//\________________ properties.
gdouble fRotation; // rotation.
gdouble fDepthRotationY;
gdouble fDepthRotationX;
gboolean bFixedAttitude;
gboolean bAllowNoClickable;
gboolean bNoInput;
GtkWidget *pInteractiveWidget;
gboolean bPositionLocked; // TRUE ssi on ne peut pas deplacer le widget a l'aide du simple clic gauche.
//\________________ internal
gint iSidWritePosition; // un timer pour retarder l'ecriture dans le fichier lors des deplacements.
gint iSidWriteSize; // un timer pour retarder l'ecriture dans le fichier lors des redimensionnements.
gint iDesiredWidth, iDesiredHeight; // taille a atteindre (fixee par l'utilisateur dans le.conf)
gint iKnownWidth, iKnownHeight; // taille connue par l'applet associee.
gboolean bSpaceReserved; // l'espace est actuellement reserve.
gboolean bAllowMinimize; // TRUE to allow the desklet to be minimized once. The flag is reseted to FALSE after the desklet has minimized.
gint iMouseX2d; // X position of the pointer taking into account the 2D transformations on the desklet (for an opengl renderer, you'll have to use the picking).
gint iMouseY2d; // Y position of the pointer taking into account the 2D transformations on the desklet (for an opengl renderer, you'll have to use the picking).
GTimer *pUnmapTimer;
gdouble fButtonsAlpha; // pour le fondu des boutons lors de l'entree dans le desklet.
gboolean bButtonsApparition; // si les boutons sont en train d'apparaitre ou de disparaitre.
gboolean bGrowingUp; // pour le zoom initial.
//\________________ current state
gboolean rotatingY;
gboolean rotatingX;
gboolean rotating;
gboolean retaching; // rattachement au dock.
gboolean making_transparent; // no input.
gboolean moving; // pour le deplacement manuel de la fenetre.
gboolean bClicked;
guint time; // date du clic.
CairoDeskletVisibility iVisibility;
gpointer reserved[4];
};
/** Say if an object is a Desklet.
*@param obj the object.
*@return TRUE if the object is a Desklet.
*/
#define GLDI_OBJECT_IS_DESKLET(obj) gldi_object_is_manager_child (GLDI_OBJECT(obj), &myDeskletObjectMgr)
#define CAIRO_DOCK_IS_DESKLET GLDI_OBJECT_IS_DESKLET
/** Cast a Container into a Desklet.
*@param pContainer the container.
*@return the desklet.
*/
#define CAIRO_DESKLET(pContainer) ((CairoDesklet *)pContainer)
#define cairo_dock_desklet_is_free(pDesklet) (! (pDesklet->bPositionLocked || pDesklet->bFixedAttitude))
/** Create a new desklet.
*@param attr the attributes of the desklet
*@return the desklet.
*/
CairoDesklet *gldi_desklet_new (CairoDeskletAttr *attr);
void gldi_desklet_init_internals (CairoDesklet *pDesklet);
/* Apply its settings on a desklet:
* it places it, resizes it, sets up its accessibility, locks its position, and sets up its decorations.
*@param pDesklet the desklet.
*@param pAttribute the attributes to configure the desklet.
*/
void gldi_desklet_configure (CairoDesklet *pDesklet, CairoDeskletAttr *pAttribute);
#define gldi_desklet_set_static(pDesklet) (pDesklet)->bFixedAttitude = TRUE
#define gldi_desklet_allow_no_clickable(pDesklet) (pDesklet)->bAllowNoClickable = TRUE
void gldi_desklet_load_desklet_decorations (CairoDesklet *pDesklet);
void gldi_desklet_decoration_free (CairoDeskletDecoration *pDecoration);
/** Add a GtkWidget to a desklet. Only 1 widget is allowed per desklet, if you need more, you can just use a GtkContainer, and place as many widget as you want inside.
*@param pInteractiveWidget the widget to add.
*@param pDesklet the desklet.
*@param iRightMargin right margin, in pixels, useful to keep a clickable zone on the desklet, or 0 if you don't want a margin.
*/
void gldi_desklet_add_interactive_widget_with_margin (CairoDesklet *pDesklet, GtkWidget *pInteractiveWidget, int iRightMargin);
/** Add a GtkWidget to a desklet. Only 1 widget is allowed per desklet, if you need more, you can just use a GtkContainer, and place as many widget as you want inside.
*@param pInteractiveWidget the widget to add.
*@param pDesklet the desklet.
*/
#define gldi_desklet_add_interactive_widget(pDesklet, pInteractiveWidget) gldi_desklet_add_interactive_widget_with_margin (pDesklet, pInteractiveWidget, 0)
/** Set the right margin of a desklet. This is useful to keep a clickable zone on the desklet when you put a GTK widget inside.
*@param pDesklet the desklet.
*@param iRightMargin right margin, in pixels.
*/
void gldi_desklet_set_margin (CairoDesklet *pDesklet, int iRightMargin);
/** Detach the interactive widget from a desklet. The widget can then be placed anywhere after that. You have to unref it after you placed it into a container, or to destroy it.
*@param pDesklet the desklet with an interactive widget.
*@return the widget.
*/
GtkWidget *gldi_desklet_steal_interactive_widget (CairoDesklet *pDesklet);
/** Hide a desklet.
*@param pDesklet the desklet.
*/
void gldi_desklet_hide (CairoDesklet *pDesklet);
/** Show a desklet, and give it the focus.
*@param pDesklet the desklet.
*/
void gldi_desklet_show (CairoDesklet *pDesklet);
/** Set a desklet's accessibility. For Widget Layer, the WM must support it and the correct rule must be set up in the WM (for instance for Compiz : class=Cairo-dock & type=utility). The function automatically sets up the rule for Compiz (if Dbus is activated).
*@param pDesklet the desklet.
*@param iVisibility the new accessibility.
*@param bSaveState whether to save the new state in the conf file.
*/
void gldi_desklet_set_accessibility (CairoDesklet *pDesklet, CairoDeskletVisibility iVisibility, gboolean bSaveState);
/** Set a desklet sticky (i.e. visible on all desktops), or not. In case the desklet is set unsticky, its current desktop/viewport is saved.
*@param pDesklet the desklet.
*@param bSticky whether the desklet should be sticky or not.
*/
void gldi_desklet_set_sticky (CairoDesklet *pDesklet, gboolean bSticky);
gboolean gldi_desklet_is_sticky (CairoDesklet *pDesklet);
/** Lock the position of a desklet. This makes the desklet impossible to rotate, drag with the mouse, or retach to the dock. The new state is saved in conf.
*@param pDesklet the desklet.
*@param bPositionLocked whether the position should be locked or not.
*/
void gldi_desklet_lock_position (CairoDesklet *pDesklet, gboolean bPositionLocked);
void gldi_desklet_insert_icon (Icon *icon, CairoDesklet *pDesklet);
gboolean gldi_desklet_detach_icon (Icon *icon, CairoDesklet *pDesklet);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-applet-manager.c 000664 001750 001750 00000014324 12223247550 023642 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include "cairo-dock-image-buffer.h"
#include "cairo-dock-draw.h"
#include "cairo-dock-icon-factory.h"
#include "cairo-dock-icon-facility.h" // cairo_dock_icon_get_allocated_width
#include "cairo-dock-module-manager.h" // gldi_modules_write_active
#include "cairo-dock-module-instance-manager.h" // GldiModuleInstance
#include "cairo-dock-surface-factory.h"
#include "cairo-dock-animations.h"
#include "cairo-dock-container.h"
#include "cairo-dock-dock-factory.h"
#include "cairo-dock-log.h"
#include "cairo-dock-icon-manager.h" // cairo_dock_search_icon_s_path
#include "cairo-dock-applet-manager.h"
// public (manager, config, data)
GldiObjectManager myAppletIconObjectMgr;
// dependancies
// private
static cairo_surface_t *_create_applet_surface (const gchar *cIconFileName, int iWidth, int iHeight)
{
cairo_surface_t *pNewSurface;
if (cIconFileName == NULL)
{
pNewSurface = cairo_dock_create_blank_surface (
iWidth,
iHeight);
}
else
{
gchar *cIconPath = cairo_dock_search_icon_s_path (cIconFileName, MAX (iWidth, iHeight));
pNewSurface = cairo_dock_create_surface_from_image_simple (cIconPath,
iWidth,
iHeight);
g_free (cIconPath);
}
return pNewSurface;
}
static void _load_image (Icon *icon)
{
int iWidth = cairo_dock_icon_get_allocated_width (icon);
int iHeight = cairo_dock_icon_get_allocated_height (icon);
cairo_surface_t *pSurface = _create_applet_surface (icon->cFileName,
iWidth,
iHeight);
if (pSurface == NULL && icon->pModuleInstance != NULL) // une image inexistante a ete definie en conf => on met l'icone par defaut. Si aucune image n'est definie, alors c'est a l'applet de faire qqch (dessiner qqch, mettre une image par defaut, etc).
{
cd_debug ("SET default image: %s", icon->pModuleInstance->pModule->pVisitCard->cIconFilePath);
pSurface = cairo_dock_create_surface_from_image_simple (icon->pModuleInstance->pModule->pVisitCard->cIconFilePath,
iWidth,
iHeight);
} // on ne recharge pas myDrawContext ici, mais plutot dans cairo_dock_load_icon_image(), puisqu'elle gere aussi la destruction de la surface.
cairo_dock_load_image_buffer_from_surface (&icon->image, pSurface, iWidth, iHeight);
}
Icon *gldi_applet_icon_new (CairoDockMinimalAppletConfig *pMinimalConfig, GldiModuleInstance *pModuleInstance)
{
GldiAppletIconAttr attr = {pMinimalConfig, pModuleInstance};
return (Icon*)gldi_object_new (&myAppletIconObjectMgr, &attr);
}
///////////////
/// MANAGER ///
///////////////
static void init_object (GldiObject *obj, gpointer attr)
{
GldiAppletIcon *icon = (GldiAppletIcon*)obj;
GldiAppletIconAttr *pAttributes = (GldiAppletIconAttr*)attr;
g_return_if_fail (pAttributes->pModuleInstance != NULL);
CairoDockMinimalAppletConfig *pMinimalConfig = pAttributes->pMinimalConfig;
icon->iface.load_image = _load_image;
icon->iGroup = CAIRO_DOCK_LAUNCHER;
icon->pModuleInstance = pAttributes->pModuleInstance;
//\____________ On recupere les infos de sa config.
icon->cName = pMinimalConfig->cLabel;
pMinimalConfig->cLabel = NULL;
icon->cFileName = pMinimalConfig->cIconFileName;
pMinimalConfig->cIconFileName = NULL;
icon->fOrder = pMinimalConfig->fOrder;
icon->bAlwaysVisible = pMinimalConfig->bAlwaysVisible;
icon->bHasHiddenBg = pMinimalConfig->bAlwaysVisible; // if we're going to see the applet all the time, let's add a background. if the user doesn't want it, he can always set a transparent bg color.
icon->pHiddenBgColor = pMinimalConfig->pHiddenBgColor;
pMinimalConfig->pHiddenBgColor = NULL;
if (! pMinimalConfig->bIsDetached)
{
cairo_dock_icon_set_requested_display_size (icon, pMinimalConfig->iDesiredIconWidth, pMinimalConfig->iDesiredIconHeight);
}
else // l'applet creera la surface elle-meme, car on ne sait ni la taille qu'elle voudra lui donner, ni meme si elle l'utilisera !
{
icon->fWidth = -1;
icon->fHeight = -1;
}
// probably not useful...
icon->fScale = 1;
icon->fGlideScale = 1;
icon->fWidthFactor = 1.;
icon->fHeightFactor = 1.;
}
static void reset_object (GldiObject *obj)
{
GldiAppletIcon *icon = (GldiAppletIcon*)obj;
if (icon->pModuleInstance != NULL) // delete the module-instance the icon belongs to
{
cd_debug ("Reset: %s", icon->cName);
gldi_object_unref (GLDI_OBJECT(icon->pModuleInstance)); // if called from the 'reset' of the instance, this will do nothing since the ref is already 0; else, when the instance unref the icon, it will do nothing since its ref is already 0
}
}
static gboolean delete_object (GldiObject *obj)
{
GldiAppletIcon *icon = (GldiAppletIcon*)obj;
if (icon->pModuleInstance != NULL) // remove the instance from the current theme
{
cd_debug ("Delete: %s", icon->cName);
gldi_object_delete (GLDI_OBJECT(icon->pModuleInstance));
return FALSE; // don't go further, since the ModuleInstance has already unref'd ourself
}
return TRUE;
}
void gldi_register_applet_icons_manager (void)
{
// Object Manager
memset (&myAppletIconObjectMgr, 0, sizeof (GldiObjectManager));
myAppletIconObjectMgr.cName = "AppletIcon";
myAppletIconObjectMgr.iObjectSize = sizeof (GldiAppletIcon);
// interface
myAppletIconObjectMgr.init_object = init_object;
myAppletIconObjectMgr.reset_object = reset_object;
myAppletIconObjectMgr.delete_object = delete_object;
// signals
gldi_object_install_notifications (GLDI_OBJECT (&myAppletIconObjectMgr), NB_NOTIFICATIONS_APPLET_ICON);
// parent object
gldi_object_set_manager (GLDI_OBJECT (&myAppletIconObjectMgr), &myIconObjectMgr);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-log.c 000664 001750 001750 00000011274 12223247550 021527 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
* cairo-dock-log.c
* Login :
* Started on Sat Feb 9 15:54:57 2008 Cedric GESTES
* $Id$
*
* Author(s)
* - Cedric GESTES
*
* Copyright (C) 2008 Cedric GESTES
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include "cairo-dock-log.h"
static char s_iLogColor = '0';
static GLogLevelFlags s_gLogLevel = G_LOG_LEVEL_WARNING;
static gboolean s_bUseColors = TRUE;
gboolean bForceColors = FALSE;
/* # 'default' => "\033[1m", */
/* # 'black' => "\033[30m", */
/* # 'red' => "\033[31m", */
/* # 'green' => "\033[32m", */
/* # 'yellow' => "\033[33m", */
/* # 'blue' => "\033[34m", */
/* # 'magenta' => "\033[35m", */
/* # 'cyan' => "\033[36m", */
/* # 'white' => "\033[37m", */
const char *_cd_log_level_to_string (const GLogLevelFlags loglevel)
{
if (s_bUseColors || bForceColors)
{
switch(loglevel)
{
case G_LOG_LEVEL_CRITICAL:
return "\033[1;31mCRITICAL: \033[0m ";
case G_LOG_LEVEL_ERROR:
return "\033[1;31mERROR : \033[0m ";
case G_LOG_LEVEL_WARNING:
return "\033[1;31mwarning : \033[0m ";
case G_LOG_LEVEL_MESSAGE:
return "\033[1;32mmessage : \033[0m ";
case G_LOG_LEVEL_INFO:
return "\033[1;33minfo : \033[0m ";
case G_LOG_LEVEL_DEBUG:
return "\033[1;34mdebug : \033[0m ";
case G_LOG_FLAG_RECURSION:
case G_LOG_FLAG_FATAL:
case G_LOG_LEVEL_MASK:
return "\033[1;31mFATAL : \033[0m ";
}
}
else
{
switch(loglevel)
{
case G_LOG_LEVEL_CRITICAL:
return "CRITICAL: ";
case G_LOG_LEVEL_ERROR:
return "ERROR : ";
case G_LOG_LEVEL_WARNING:
return "warning : ";
case G_LOG_LEVEL_MESSAGE:
return "message : ";
case G_LOG_LEVEL_INFO:
return "info : ";
case G_LOG_LEVEL_DEBUG:
return "debug : ";
case G_LOG_FLAG_RECURSION:
case G_LOG_FLAG_FATAL:
case G_LOG_LEVEL_MASK:
return "FATAL : ";
}
}
return "";
}
void cd_log_location(const GLogLevelFlags loglevel,
const char *file,
const char *func,
const int line,
const char *format,
...)
{
va_list args;
if (loglevel > s_gLogLevel)
return;
g_print("%s", _cd_log_level_to_string (loglevel));
if (s_bUseColors)
g_print("\033[0;37m(%s:%s:%d) \033[%cm \n ", file, func, line, s_iLogColor);
else
g_print("(%s:%s:%d)\n ", file, func, line);
va_start(args, format);
g_logv(G_LOG_DOMAIN, loglevel, format, args);
va_end(args);
}
static void cairo_dock_log_handler(G_GNUC_UNUSED const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
G_GNUC_UNUSED gpointer user_data)
{
if (log_level > s_gLogLevel)
return;
g_print("%s\n", message);
}
void cd_log_init (gboolean bBlackTerminal)
{
g_log_set_default_handler(cairo_dock_log_handler, NULL);
s_iLogColor = (bBlackTerminal ? '1' : '0');
s_bUseColors = isatty (1); // use colors iif our output is associated with a terminal (otherwise it's probably redirected into log file, color characters will be annoying).
}
void cd_log_set_level (GLogLevelFlags loglevel)
{
s_gLogLevel = loglevel;
}
void cd_log_set_level_from_name (const gchar *cVerbosity)
{
if (!cVerbosity)
cd_log_set_level(G_LOG_LEVEL_WARNING);
else if (!strcmp(cVerbosity, "debug"))
cd_log_set_level(G_LOG_LEVEL_DEBUG);
else if (!strcmp(cVerbosity, "message"))
cd_log_set_level(G_LOG_LEVEL_MESSAGE);
else if (!strcmp(cVerbosity, "warning"))
cd_log_set_level(G_LOG_LEVEL_WARNING);
else if (!strcmp(cVerbosity, "critical"))
cd_log_set_level(G_LOG_LEVEL_CRITICAL);
else if (!strcmp(cVerbosity, "error"))
cd_log_set_level(G_LOG_LEVEL_ERROR);
else {
cd_log_set_level(G_LOG_LEVEL_WARNING);
cd_warning("bad verbosity option: default to warning");
}
}
void cd_log_force_use_color (void)
{
bForceColors = TRUE;
}
cairo-dock-3.3.2/src/gldit/cairo-dock-overlay.h 000664 001750 001750 00000016671 12223247550 022442 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_OVERLAY__
#define __CAIRO_DOCK_OVERLAY__
#include "cairo-dock-struct.h"
#include "cairo-dock-object.h"
#include "cairo-dock-image-buffer.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-overlay.h This class defines Overlays, that are small images superimposed on the icon at a given position.
*
* To add an overlay to an icon, use \ref cairo_dock_add_overlay_from_image or \ref cairo_dock_add_overlay_from_surface.
* The overlay can then be removed from the icon by simply destroying it with \ref gldi_object_unref
*
* A common feature is to have only 1 overlay at a given position. This can be achieved by passing a non-NULL data to the creation functions. This data will identify all of your overlays.
* You can then remove an overlay simply from its position with \ref cairo_dock_remove_overlay_at_position, and adding an overlay at a position will automatically remove any previous overlay at this position with the same data.
*
* If you're never going to update nor remove an overlay, you can choose to print it directly onto the icon with \ref cairo_dock_print_overlay_on_icon_from_image or \ref cairo_dock_print_overlay_on_icon_from_surface, which is slightly faster.
*
* Overlays are drawn at 1/2 of the icon size by default, but this can be set up with \ref cairo_dock_set_overlay_scale.
* If you need to modify an overlay directly, you can get its image buffer with \ref cairo_dock_get_overlay_image_buffer.
*/
// manager
typedef struct _CairoOverlayAttr CairoOverlayAttr;
#ifndef _MANAGER_DEF_
extern GldiObjectManager myOverlayObjectMgr;
#endif
/// Available position of an overlay on an icon.
typedef enum {
CAIRO_OVERLAY_UPPER_LEFT,
CAIRO_OVERLAY_LOWER_RIGHT,
CAIRO_OVERLAY_LOWER_LEFT,
CAIRO_OVERLAY_UPPER_RIGHT,
CAIRO_OVERLAY_MIDDLE,
CAIRO_OVERLAY_BOTTOM,
CAIRO_OVERLAY_TOP,
CAIRO_OVERLAY_RIGHT,
CAIRO_OVERLAY_LEFT,
CAIRO_OVERLAY_NB_POSITIONS,
} CairoOverlayPosition;
struct _CairoOverlayAttr {
CairoOverlayPosition iPosition;
Icon *pIcon;
gpointer data;
const gchar *cImageFile;
cairo_surface_t *pSurface;
int iWidth, iHeight;
GLuint iTexture;
};
// signals
typedef enum {
NB_NOTIFICATIONS_OVERLAYS = NB_NOTIFICATIONS_OBJECT
} CairoOverlayNotifications;
/// Definition of an Icon Overlay.
struct _CairoOverlay {
/// object
GldiObject object;
/// image buffer
CairoDockImageBuffer image;
/// position on the icon
CairoOverlayPosition iPosition;
/// scale at which to draw the overlay, relatively to the icon (0.5 by default, 1 will cover the whole icon, 0 means to draw at the actual buffer size).
gdouble fScale;
/// icon it belongs to.
Icon *pIcon;
/// data used to identify an overlay
gpointer data;
} ;
///////////////////
// OVERLAY CLASS //
///////////////////
/** Add an overlay on an icon from an image.
*@param pIcon the icon
*@param cImageFile an image (if it's not a path, it is searched amongst the current theme's images)
*@param iPosition position where to display the overlay
*@return the overlay, or NULL if the image couldn't be loaded.
*@param data data that will be used to look for the overlay in \ref cairo_dock_remove_overlay_at_position; if NULL, then this function can't be used
*/
CairoOverlay *cairo_dock_add_overlay_from_image (Icon *pIcon, const gchar *cImageFile, CairoOverlayPosition iPosition, gpointer data);
/** Add an overlay on an icon from a surface.
*@param pIcon the icon
*@param pSurface a cairo surface
*@param iWidth width of the surface
*@param iHeight height of the surface
*@param iPosition position where to display the overlay
*@param data data that will be used to look for the overlay in \ref cairo_dock_remove_overlay_at_position; if NULL, then this function can't be used
*@return the overlay.
*/
CairoOverlay *cairo_dock_add_overlay_from_surface (Icon *pIcon, cairo_surface_t *pSurface, int iWidth, int iHeight, CairoOverlayPosition iPosition, gpointer data);
/** Add an overlay on an icon from a texture.
*@param pIcon the icon
*@param iTexture a texture
*@param iPosition position where to display the overlay
*@param data data that will be used to look for the overlay in \ref cairo_dock_remove_overlay_at_position; if NULL, then this function can't be used
*@return the overlay.
*/
CairoOverlay *cairo_dock_add_overlay_from_texture (Icon *pIcon, GLuint iTexture, CairoOverlayPosition iPosition, gpointer data);
/** Set the scale of an overlay; by default it's 0.5
*@param pOverlay the overlay
*@param _fScale the scale
*/
#define cairo_dock_set_overlay_scale(pOverlay, _fScale) (pOverlay)->fScale = _fScale
/** Get the image buffer of an overlay (only useful if you need to redraw the overlay).
*@param pOverlay the overlay
*/
#define cairo_dock_get_overlay_image_buffer(pOverlay) (&(pOverlay)->image)
/** Remove an overlay from an icon, given its position and data.
*@param pIcon the icon
*@param iPosition the position of the overlay
*@param data data that was set on the overlay when created; a NULL pointer is not valid.
*/
void cairo_dock_remove_overlay_at_position (Icon *pIcon, CairoOverlayPosition iPosition, gpointer data);
///////////////////
// ICON OVERLAYS //
///////////////////
void cairo_dock_destroy_icon_overlays (Icon *pIcon);
void cairo_dock_draw_icon_overlays_cairo (Icon *pIcon, double fRatio, cairo_t *pCairoContext);
void cairo_dock_draw_icon_overlays_opengl (Icon *pIcon, double fRatio);
///////////
// PRINT //
///////////
/** Print an overlay onto an icon from an image at a given position. You can't remove/modify the overlay then. The overlay will be displayed until you modify the icon directly (for instance by setting a new image).
*@param pIcon the icon
*@param cImageFile an image (if it's not a path, it is searched amongst the current theme's images)
*@param iPosition position where to display the overlay
*@return TRUE if the overlay has been successfuly printed.
*/
gboolean cairo_dock_print_overlay_on_icon_from_image (Icon *pIcon, const gchar *cImageFile, CairoOverlayPosition iPosition);
/** Print an overlay onto an icon from a surface at a given position. You can't remove/modify the overlay then. The overlay will be displayed until you modify the icon directly (for instance by setting a new image).
*@param pIcon the icon
*@param pSurface a cairo surface
*@param iWidth width of the surface
*@param iHeight height of the surface
*@param iPosition position where to display the overlay
*@return TRUE if the overlay has been successfuly printed.
*/
void cairo_dock_print_overlay_on_icon_from_surface (Icon *pIcon, cairo_surface_t *pSurface, int iWidth, int iHeight, CairoOverlayPosition iPosition);
void cairo_dock_print_overlay_on_icon_from_texture (Icon *pIcon, GLuint iTexture, CairoOverlayPosition iPosition);
void gldi_register_overlays_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-applications-manager.c 000664 001750 001750 00000112646 12233704045 025047 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#define __USE_POSIX
#include
#include
#include "gldi-config.h"
#include "cairo-dock-icon-manager.h"
#include "cairo-dock-indicator-manager.h" // myIndicatorsParam.bDrawIndicatorOnAppli
#include "cairo-dock-class-icon-manager.h"
#include "cairo-dock-animations.h" // cairo_dock_trigger_icon_removal_from_dock
#include "cairo-dock-dock-facility.h" // cairo_dock_update_dock_size
#include "cairo-dock-icon-facility.h" // gldi_icon_set_name
#include "cairo-dock-container.h"
#include "cairo-dock-object.h"
#include "cairo-dock-log.h"
#include "cairo-dock-config.h"
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-desktop-manager.h" // NOTIFICATION_DESKTOP_CHANGED
#include "cairo-dock-class-manager.h"
#include "cairo-dock-draw-opengl.h" // cairo_dock_create_texture_from_surface
#include "cairo-dock-keyfile-utilities.h" // cairo_dock_open_key_file
#include "cairo-dock-application-facility.h"
#include "cairo-dock-windows-manager.h"
#include "cairo-dock-overlay.h" // cairo_dock_print_overlay_on_icon
#define _MANAGER_DEF_
#include "cairo-dock-applications-manager.h"
#define CAIRO_DOCK_DEFAULT_APPLI_ICON_NAME "default-icon-appli.svg"
// public (manager, config, data)
CairoTaskbarParam myTaskbarParam;
GldiManager myTaskbarMgr;
GldiObjectManager myAppliIconObjectMgr;
// dependancies
extern CairoDock *g_pMainDock;
extern gboolean g_bUseOpenGL;
//extern int g_iDamageEvent;
// private
static GHashTable *s_hAppliIconsTable = NULL; // table des fenetres affichees dans le dock.
static int s_bAppliManagerIsRunning = FALSE;
static GldiWindowActor *s_pCurrentActiveWindow = NULL;
static void cairo_dock_unregister_appli (Icon *icon);
static Icon * cairo_dock_create_icon_from_window (GldiWindowActor *actor)
{
if (actor->bDisplayed)
return (Icon*)gldi_object_new (&myAppliIconObjectMgr, actor);
else
return NULL;
}
static Icon *_get_appli_icon (GldiWindowActor *actor)
{
return g_hash_table_lookup (s_hAppliIconsTable, actor);
}
///////////////
// Callbacks //
///////////////
static gboolean _on_window_created (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
Icon *pIcon = _get_appli_icon (actor);
g_return_val_if_fail (pIcon == NULL, GLDI_NOTIFICATION_LET_PASS);
// create an appli-icon
pIcon = cairo_dock_create_icon_from_window (actor);
if (pIcon != NULL)
{
// insert into the dock
if (myTaskbarParam.bShowAppli)
{
cd_message (" insertion de %s ...", pIcon->cName);
gldi_appli_icon_insert_in_dock (pIcon, g_pMainDock, CAIRO_DOCK_ANIMATE_ICON);
}
}
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_destroyed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
cd_debug ("window %s (%p) is destroyed", actor->cName, actor);
Icon *icon = _get_appli_icon (actor);
if (icon != NULL)
{
if (actor->bDemandsAttention) // force the stop demanding attention, in case the icon was in a sub-dock (the main icon is also animating).
gldi_appli_icon_stop_demanding_attention (icon);
CairoDock *pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (icon));
if (pParentDock != NULL)
{
cd_message (" va etre supprimee");
cairo_dock_unregister_appli (icon); // unregister the icon immediately, since it doesn't represent anything any more; it unsets pAppli, so that when the animation is over, the icon will be destroyed.
cairo_dock_trigger_icon_removal_from_dock (icon);
}
else // inhibited or not shown -> destroy it immediately
{
cd_message (" pas dans un container, on la detruit donc immediatement");
///cairo_dock_update_name_on_inhibitors (icon->cClass, actor, NULL);
gldi_window_inhibitors_set_name (actor, NULL);
gldi_object_unref (GLDI_OBJECT (icon)); // will call cairo_dock_unregister_appli and update the inhibitors.
}
}
if (s_pCurrentActiveWindow == actor)
s_pCurrentActiveWindow = NULL;
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_name_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
Icon *pIcon = _get_appli_icon (actor);
if (pIcon == NULL)
return GLDI_NOTIFICATION_LET_PASS;
gldi_icon_set_name (pIcon, actor->cName);
///cairo_dock_update_name_on_inhibitors (actor->cClass, actor, pIcon->cName);
gldi_window_inhibitors_set_name (actor, pIcon->cName);
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_icon_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
Icon *icon = _get_appli_icon (actor);
if (icon == NULL)
return GLDI_NOTIFICATION_LET_PASS;
if (cairo_dock_class_is_using_xicon (icon->cClass) || ! myTaskbarParam.bOverWriteXIcons)
{
GldiContainer *pContainer = cairo_dock_get_icon_container (icon);
if (pContainer != NULL) // if the icon is not in a container (for instance inhibited), it's no use trying to load its image. It's not even useful to mark it as 'damaged', since anyway it will be loaded when inserted inside a container.
{
cairo_dock_load_icon_image (icon, pContainer);
if (CAIRO_DOCK_IS_DOCK (pContainer))
{
CairoDock *pDock = CAIRO_DOCK (pContainer);
if (pDock->iRefCount != 0)
cairo_dock_trigger_redraw_subdock_content (pDock);
}
cairo_dock_redraw_icon (icon);
}
}
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_attention_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
Icon *pIcon = _get_appli_icon (actor);
if (pIcon == NULL)
return GLDI_NOTIFICATION_LET_PASS;
if (actor->bDemandsAttention)
{
cd_debug ("%s demande votre attention", pIcon->cName);
if (myTaskbarParam.bDemandsAttentionWithDialog || myTaskbarParam.cAnimationOnDemandsAttention)
{
gldi_appli_icon_demands_attention (pIcon);
}
}
else
{
cd_debug ("%s se tait", pIcon->cName);
gldi_appli_icon_stop_demanding_attention (pIcon);
}
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_size_position_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
Icon *icon = _get_appli_icon (actor);
if (icon == NULL)
return GLDI_NOTIFICATION_LET_PASS;
// on regarde si l'appli est sur le viewport courant.
if (! gldi_window_is_on_current_desktop (actor)) // not on this desktop/viewport any more
{
// applis du bureau courant seulement.
if (myTaskbarParam.bAppliOnCurrentDesktopOnly)
{
if (cairo_dock_get_icon_container (icon) != NULL)
{
CairoDock *pParentDock = gldi_appli_icon_detach (icon);
if (pParentDock)
gtk_widget_queue_draw (pParentDock->container.pWidget);
}
else
gldi_window_detach_from_inhibitors (actor);
}
}
else // elle est sur le viewport courant.
{
// applis du bureau courant seulement.
if (myTaskbarParam.bAppliOnCurrentDesktopOnly && cairo_dock_get_icon_container (icon) == NULL && myTaskbarParam.bShowAppli)
{
//cd_message ("cette fenetre est sur le bureau courant (%d;%d)", x, y);
gldi_appli_icon_insert_in_dock (icon, g_pMainDock, ! CAIRO_DOCK_ANIMATE_ICON); // the icon might be on this desktop and yet not in a dock (inhibited), in which case this function does nothing.
}
}
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_state_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor, gboolean bHiddenChanged, G_GNUC_UNUSED gboolean bMaximizedChanged, G_GNUC_UNUSED gboolean bFullScreenChanged)
{
Icon *icon = _get_appli_icon (actor);
if (icon == NULL)
return GLDI_NOTIFICATION_LET_PASS;
// on gere le cachage/apparition de l'icone (transparence ou miniature, applis minimisees seulement).
CairoDock *pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (icon));
if (bHiddenChanged)
{
cd_message (" changement de visibilite -> %d", actor->bIsHidden);
// drawing of hidden appli-icons.
if (g_bUseOpenGL && myTaskbarParam.iMinimizedWindowRenderType == 2)
{
if (pParentDock != NULL)
{
cairo_dock_draw_hidden_appli_icon (icon, CAIRO_CONTAINER (pParentDock), TRUE);
}
}
else if (myTaskbarParam.iMinimizedWindowRenderType == 0)
{
// transparence sur les inhibiteurs.
///cairo_dock_update_visibility_on_inhibitors (icon->cClass, actor, actor->bIsHidden);
gldi_window_inhibitors_set_hidden_state (actor, actor->bIsHidden);
}
// showing hidden appli-icons only
if (myTaskbarParam.bHideVisibleApplis && myTaskbarParam.bShowAppli) // on insere/detache l'icone selon la visibilite de la fenetre, avec une animation.
{
if (actor->bIsHidden) // se cache => on insere son icone.
{
cd_message (" => se cache");
pParentDock = gldi_appli_icon_insert_in_dock (icon, g_pMainDock, CAIRO_DOCK_ANIMATE_ICON);
if (pParentDock != NULL)
{
if (g_bUseOpenGL && myTaskbarParam.iMinimizedWindowRenderType == 2) // quand on est passe dans ce cas tout a l'heure l'icone n'etait pas encore dans son dock.
cairo_dock_draw_hidden_appli_icon (icon, CAIRO_CONTAINER (pParentDock), TRUE);
gtk_widget_queue_draw (pParentDock->container.pWidget);
}
}
else // se montre => on detache l'icone.
{
cd_message (" => re-apparait");
cairo_dock_trigger_icon_removal_from_dock (icon);
}
}
else if (myTaskbarParam.fVisibleAppliAlpha != 0) // transparence
{
icon->fAlpha = 1; // on triche un peu.
if (pParentDock != NULL)
cairo_dock_redraw_icon (icon);
}
// miniature (on le fait apres l'avoir inseree/detachee, car comme ca dans le cas ou on l'enleve du dock apres l'avoir deminimisee, l'icone est marquee comme en cours de suppression, et donc on ne recharge pas son icone. Sinon l'image change pendant la transition, ce qui est pas top. Comme ca ne change pas la taille de l'icone dans le dock, on peut faire ca apres l'avoir inseree.
if (myTaskbarParam.iMinimizedWindowRenderType == 1 && (pParentDock != NULL || myTaskbarParam.bHideVisibleApplis))
{
// on redessine avec ou sans la miniature, suivant le nouvel etat.
cairo_dock_load_icon_image (icon, CAIRO_CONTAINER (pParentDock));
if (pParentDock)
{
cairo_dock_redraw_icon (icon);
if (pParentDock->iRefCount != 0) // on prevoit le redessin de l'icone pointant sur le sous-dock.
{
cairo_dock_trigger_redraw_subdock_content (pParentDock);
}
}
}
}
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_window_class_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor, const gchar *cOldClass, G_GNUC_UNUSED const gchar *cOldWmClass)
{
Icon *icon = _get_appli_icon (actor);
if (icon == NULL)
return GLDI_NOTIFICATION_LET_PASS;
// remove the icon from the dock, and then from its class
gchar *tmp = actor->cClass;
actor->cClass = (gchar*)cOldClass; // temporarily set the old class to the actor, so that we can detach it from inhibitors
CairoDock *pParentDock = NULL;
if (cairo_dock_get_icon_container (icon) != NULL) // if in a dock, detach it
pParentDock = gldi_appli_icon_detach (icon);
else // else if inhibited, detach from the inhibitor
gldi_window_detach_from_inhibitors (actor);
cairo_dock_remove_appli_from_class (icon);
actor->cClass = tmp;
// set the new class
g_free (icon->cClass);
icon->cClass = g_strdup (actor->cClass);
g_free (icon->cWmClass);
icon->cWmClass = g_strdup (actor->cWmClass);
cairo_dock_add_appli_icon_to_class (icon);
// re-insert the icon
pParentDock = gldi_appli_icon_insert_in_dock (icon, g_pMainDock, ! CAIRO_DOCK_ANIMATE_ICON);
if (pParentDock != NULL)
gtk_widget_queue_draw (pParentDock->container.pWidget);
// reload the icon
g_strfreev (icon->pMimeTypes);
icon->pMimeTypes = g_strdupv ((gchar**)cairo_dock_get_class_mimetypes (icon->cClass));
g_free (icon->cCommand);
icon->cCommand = g_strdup (cairo_dock_get_class_command (icon->cClass));
cairo_dock_load_icon_image (icon, CAIRO_CONTAINER (pParentDock));
return GLDI_NOTIFICATION_LET_PASS;
}
static void _hide_show_appli_icons_on_other_desktops (GldiWindowActor *pAppli, Icon *icon, CairoDock *pMainDock)
{
if (! myTaskbarParam.bHideVisibleApplis || pAppli->bIsHidden)
{
cd_debug ("%s (%p)", __func__, pAppli);
CairoDock *pParentDock = NULL;
if (gldi_window_is_on_current_desktop (pAppli))
{
cd_debug (" => est sur le bureau actuel.");
if (cairo_dock_get_icon_container(icon) == NULL)
{
pParentDock = gldi_appli_icon_insert_in_dock (icon, pMainDock, ! CAIRO_DOCK_ANIMATE_ICON);
}
}
else
{
cd_debug (" => n'est pas sur le bureau actuel.");
if (cairo_dock_get_icon_container (icon) != NULL) // if in a dock, detach it
pParentDock = gldi_appli_icon_detach (icon);
else // else if inhibited, detach from the inhibitor
gldi_window_detach_from_inhibitors (icon->pAppli);
}
if (pParentDock != NULL)
gtk_widget_queue_draw (pParentDock->container.pWidget);
}
}
static gboolean _on_window_desktop_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
Icon *icon = _get_appli_icon (actor);
if (icon == NULL)
return GLDI_NOTIFICATION_LET_PASS;
// applis du bureau courant seulement.
if (myTaskbarParam.bAppliOnCurrentDesktopOnly && myTaskbarParam.bShowAppli)
{
_hide_show_appli_icons_on_other_desktops (actor, icon, g_pMainDock); // si elle vient sur notre bureau, elle n'est pas forcement sur le meme viewport, donc il faut le verifier.
}
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_desktop_changed (G_GNUC_UNUSED gpointer data)
{
// applis du bureau courant seulement.
if (myTaskbarParam.bAppliOnCurrentDesktopOnly && myTaskbarParam.bShowAppli)
{
g_hash_table_foreach (s_hAppliIconsTable, (GHFunc) _hide_show_appli_icons_on_other_desktops, g_pMainDock);
}
return GLDI_NOTIFICATION_LET_PASS;
}
static gboolean _on_active_window_changed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
{
// on gere son animation et son indicateur.
Icon *icon = _get_appli_icon (actor);
CairoDock *pParentDock = NULL;
if (CAIRO_DOCK_IS_APPLI (icon))
{
if (icon->bIsDemandingAttention) // force the stop demanding attention, as it can happen (for some reason) that the attention state doesn't change when the appli takes the focus.
gldi_appli_icon_stop_demanding_attention (icon);
pParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (icon));
if (pParentDock == NULL) // inhibited or not shown
{
///cairo_dock_update_activity_on_inhibitors (icon->cClass, actor);
gldi_window_inhibitors_set_active_state (actor, TRUE);
}
else
{
gldi_appli_icon_animate_on_active (icon, pParentDock);
}
}
// on enleve l'indicateur sur la precedente appli active.
Icon *pLastActiveIcon = _get_appli_icon (s_pCurrentActiveWindow);
if (CAIRO_DOCK_IS_APPLI (pLastActiveIcon))
{
CairoDock *pLastActiveParentDock = CAIRO_DOCK(cairo_dock_get_icon_container (pLastActiveIcon));
if (pLastActiveParentDock == NULL) // inhibited or not shown
{
///cairo_dock_update_inactivity_on_inhibitors (pLastActiveIcon->cClass, s_pCurrentActiveWindow);
gldi_window_inhibitors_set_active_state (s_pCurrentActiveWindow, FALSE);
}
else
{
cairo_dock_redraw_icon (pLastActiveIcon);
if (pLastActiveParentDock->iRefCount != 0) // l'icone est dans un sous-dock, comme l'indicateur est aussi dessine sur l'icone pointant sur ce sous-dock, il faut la redessiner sans l'indicateur.
{
CairoDock *pMainDock = NULL;
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pLastActiveParentDock, &pMainDock);
if (pPointingIcon && pMainDock)
{
cairo_dock_redraw_icon (pPointingIcon);
}
}
}
}
s_pCurrentActiveWindow = actor;
return GLDI_NOTIFICATION_LET_PASS;
}
///////////////////////////
// Applis manager : core //
///////////////////////////
static void cairo_dock_register_appli (Icon *icon)
{
if (CAIRO_DOCK_IS_APPLI (icon))
{
cd_debug ("%s (%p ; %s)", __func__, icon->pAppli, icon->cName);
// add to table
g_hash_table_insert (s_hAppliIconsTable, icon->pAppli, icon);
// add to class
cairo_dock_add_appli_icon_to_class (icon);
}
}
static void cairo_dock_unregister_appli (Icon *icon)
{
if (CAIRO_DOCK_IS_APPLI (icon))
{
cd_debug ("%s (%p ; %s)", __func__, icon->pAppli, icon->cName);
// remove from table
g_hash_table_remove (s_hAppliIconsTable, icon->pAppli);
// remove from class
cairo_dock_remove_appli_from_class (icon); // n'efface pas sa classe (on peut en avoir besoin encore).
gldi_window_detach_from_inhibitors (icon->pAppli);
// unset the appli
gldi_icon_unset_appli (icon);
}
}
static void _create_appli_icon (GldiWindowActor *actor, CairoDock *pDock)
{
Icon *pIcon = cairo_dock_create_icon_from_window (actor);
if (pIcon != NULL)
{
if (myTaskbarParam.bShowAppli && pDock)
{
gldi_appli_icon_insert_in_dock (pIcon, g_pMainDock, ! CAIRO_DOCK_ANIMATE_ICON);
}
}
}
void cairo_dock_start_applications_manager (CairoDock *pDock)
{
g_return_if_fail (!s_bAppliManagerIsRunning);
cairo_dock_set_overwrite_exceptions (myTaskbarParam.cOverwriteException);
cairo_dock_set_group_exceptions (myTaskbarParam.cGroupException);
// create an appli-icon for each window.
gldi_windows_foreach (FALSE, (GFunc)_create_appli_icon, pDock); // ordered by creation date; this allows us to set the correct age to the icon, which is constant. On the next updates, the z-order (which is dynamic) will be set.
s_bAppliManagerIsRunning = TRUE;
}
static gboolean _remove_one_appli (G_GNUC_UNUSED GldiWindowActor *pAppli, Icon *pIcon, G_GNUC_UNUSED gpointer data)
{
if (pIcon == NULL)
return TRUE;
if (pIcon->pAppli == NULL)
{
g_free (pIcon);
return TRUE;
}
cd_debug (" remove %s...", pIcon->cName);
CairoDock *pDock = CAIRO_DOCK(cairo_dock_get_icon_container (pIcon));
if (GLDI_OBJECT_IS_DOCK(pDock))
{
gldi_icon_detach (pIcon);
if (pDock->iRefCount != 0) // this appli-icon is in a sub-dock (above a launcher or a class-icon)
{
if (pDock->icons == NULL) // the sub-dock gets empty -> free it
{
CairoDock *pFakeClassParentDock = NULL;
Icon *pFakeClassIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pFakeClassParentDock);
if (CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (pFakeClassIcon)) // also remove the fake launcher that was pointing on it
{
cd_debug ("on degage le fake qui pointe sur %s", pDock->cDockName);
pFakeClassIcon->pSubDock = NULL; // don't free the sub-dock, since we do it below
gldi_icon_detach (pFakeClassIcon);
gldi_object_unref (GLDI_OBJECT (pFakeClassIcon));
}
gldi_object_unref (GLDI_OBJECT(pDock));
}
}
}
gldi_icon_unset_appli (pIcon); // on ne veut pas passer dans le 'unregister'
g_free (pIcon->cClass); // ni la gestion de la classe.
pIcon->cClass = NULL;
gldi_object_unref (GLDI_OBJECT (pIcon));
return TRUE;
}
static void _cairo_dock_stop_application_manager (void)
{
s_bAppliManagerIsRunning = FALSE;
cairo_dock_remove_all_applis_from_class_table (); // enleve aussi les indicateurs.
g_hash_table_foreach_remove (s_hAppliIconsTable, (GHRFunc) _remove_one_appli, NULL); // libere toutes les icones d'appli.
}
/////////////////////////////
// Applis manager : access //
/////////////////////////////
GList *cairo_dock_get_current_applis_list (void)
{
return g_hash_table_get_values (s_hAppliIconsTable);
}
Icon *cairo_dock_get_current_active_icon (void)
{
GldiWindowActor *actor = gldi_windows_get_active ();
return cairo_dock_get_appli_icon (actor);
}
Icon *cairo_dock_get_appli_icon (GldiWindowActor *actor)
{
if (! actor)
return NULL;
return g_hash_table_lookup (s_hAppliIconsTable, actor);
}
static void _for_one_appli_icon (G_GNUC_UNUSED GldiWindowActor *actor, Icon *icon, gpointer *data)
{
if (! CAIRO_DOCK_IS_APPLI (icon) || cairo_dock_icon_is_being_removed (icon))
return ;
GldiIconFunc pFunction = data[0];
gpointer pUserData = data[1];
pFunction (icon, pUserData);
}
void cairo_dock_foreach_appli_icon (GldiIconFunc pFunction, gpointer pUserData)
{
gpointer data[2] = {pFunction, pUserData};
g_hash_table_foreach (s_hAppliIconsTable, (GHFunc) _for_one_appli_icon, data);
}
void cairo_dock_set_icons_geometry_for_window_manager (CairoDock *pDock)
{
if (! s_bAppliManagerIsRunning)
return ;
//g_print ("%s (main:%d, ref:%d)\n", __func__, pDock->bIsMainDock, pDock->iRefCount);
/*long *data = g_new0 (long, 1+6*g_list_length (pDock->icons));
int i = 0;*/
Icon *icon;
GList *ic;
for (ic = pDock->icons; ic != NULL; ic = ic->next)
{
icon = ic->data;
if (CAIRO_DOCK_IS_APPLI (icon))
{
gldi_appli_icon_set_geometry_for_window_manager (icon, pDock);
/*data[1+6*i+0] = 5;
data[1+6*i+1] = icon->Xid;
data[1+6*i+2] = pDock->container.iWindowPositionX + icon->fXAtRest;
data[1+6*i+3] = 0;
data[1+6*i+4] = icon->fWidth;
data[1+6*i+5] = icon->fHeight;
i ++;*/
}
}
/*data[0] = i;
Atom atom = XInternAtom (gdk_x11_get_default_xdisplay(), "_KDE_WINDOW_PREVIEW", False);
Window Xid = GDK_WINDOW_XID (pDock->container.pWidget->window);
XChangeProperty(gdk_x11_get_default_xdisplay(), Xid, atom, atom, 32, PropModeReplace, data, 1+6*i);*/
if (pDock->bIsMainDock && myTaskbarParam.bHideVisibleApplis) // on complete avec les applis pas dans le dock, pour que l'effet de minimisation pointe (a peu pres) au bon endroit quand on la minimisera.
{
g_hash_table_foreach (s_hAppliIconsTable, (GHFunc) gldi_appli_reserve_geometry_for_window_manager, pDock);
}
}
////////////////////////////
// Applis manager : icons //
////////////////////////////
static void _load_appli (Icon *icon)
{
if (cairo_dock_icon_is_being_removed (icon))
return ;
//\__________________ register the class to get its attributes, if it was not done yet.
if (icon->cClass && !icon->pMimeTypes && !icon->cCommand)
{
gchar *cClass = cairo_dock_register_class_full (NULL, icon->cClass, icon->cWmClass);
if (cClass != NULL)
{
g_free (cClass);
icon->cCommand = g_strdup (cairo_dock_get_class_command (icon->cClass));
icon->pMimeTypes = g_strdupv ((gchar**)cairo_dock_get_class_mimetypes (icon->cClass));
}
}
//\__________________ then draw the icon
int iWidth = cairo_dock_icon_get_allocated_width (icon);
int iHeight = cairo_dock_icon_get_allocated_height (icon);
cairo_surface_t *pPrevSurface = icon->image.pSurface;
GLuint iPrevTexture = icon->image.iTexture;
icon->image.pSurface = NULL;
icon->image.iTexture = 0;
// use the thumbnail in the case of a minimized window.
if (myTaskbarParam.iMinimizedWindowRenderType == 1 && icon->pAppli->bIsHidden)
{
// create the thumbnail (window preview).
if (g_bUseOpenGL) // in OpenGL, we should be able to use the texture-from-pixmap mechanism
{
GLuint iTexture = gldi_window_get_texture (icon->pAppli);
if (iTexture)
cairo_dock_load_image_buffer_from_texture (&icon->image, iTexture, iWidth, iHeight);
}
if (icon->image.iTexture == 0) // if not opengl or didn't work, get the content of the pixmap from the X server.
{
cairo_surface_t *pThumbnailSurface = gldi_window_get_thumbnail_surface (icon->pAppli, iWidth, iHeight);
cairo_dock_load_image_buffer_from_surface (&icon->image, pThumbnailSurface, iWidth, iHeight);
}
// draw the previous image as an emblem.
if (icon->image.iTexture != 0 && iPrevTexture != 0)
{
cairo_dock_print_overlay_on_icon_from_texture (icon, iPrevTexture, CAIRO_OVERLAY_LOWER_LEFT);
}
else if (icon->image.pSurface != NULL && pPrevSurface != NULL)
{
cairo_dock_print_overlay_on_icon_from_surface (icon, pPrevSurface, 0, 0, CAIRO_OVERLAY_LOWER_LEFT);
}
}
// in other cases (or if the preview couldn't be used)
if (icon->image.iTexture == 0 && icon->image.pSurface == NULL)
{
cairo_surface_t *pSurface = NULL;
// or use the class icon
if (myTaskbarParam.bOverWriteXIcons && ! cairo_dock_class_is_using_xicon (icon->cClass))
pSurface = cairo_dock_create_surface_from_class (icon->cClass, iWidth, iHeight);
// or use the X icon
if (pSurface == NULL)
pSurface = gldi_window_get_icon_surface (icon->pAppli, iWidth, iHeight);
// or use a default image
if (pSurface == NULL) // some applis like xterm don't define any icon, set the default one.
{
cd_debug ("%s (%p) doesn't define any icon, we set the default one.", icon->cName, icon->pAppli);
gchar *cIconPath = cairo_dock_search_image_s_path (CAIRO_DOCK_DEFAULT_APPLI_ICON_NAME);
if (cIconPath == NULL) // image non trouvee.
{
cIconPath = g_strdup (GLDI_SHARE_DATA_DIR"/icons/"CAIRO_DOCK_DEFAULT_APPLI_ICON_NAME);
}
pSurface = cairo_dock_create_surface_from_image_simple (cIconPath,
iWidth,
iHeight);
g_free (cIconPath);
}
if (pSurface != NULL)
cairo_dock_load_image_buffer_from_surface (&icon->image, pSurface, iWidth, iHeight);
}
// bent the icon in the case of a minimized window and if defined in the config.
if (icon->pAppli->bIsHidden && myTaskbarParam.iMinimizedWindowRenderType == 2)
{
GldiContainer *pContainer = cairo_dock_get_icon_container (icon);
if (pContainer)
cairo_dock_draw_hidden_appli_icon (icon, pContainer, FALSE);
}
}
static void _show_appli_for_drop (Icon *pIcon)
{
gldi_window_show (pIcon->pAppli);
}
//////////////////
/// GET CONFIG ///
//////////////////
static gboolean get_config (GKeyFile *pKeyFile, CairoTaskbarParam *pTaskBar)
{
gboolean bFlushConfFileNeeded = FALSE;
// comportement
pTaskBar->bShowAppli = cairo_dock_get_boolean_key_value (pKeyFile, "TaskBar", "show applications", &bFlushConfFileNeeded, TRUE, "Applications", NULL);
if (pTaskBar->bShowAppli)
{
pTaskBar->bAppliOnCurrentDesktopOnly = cairo_dock_get_boolean_key_value (pKeyFile, "TaskBar", "current desktop only", &bFlushConfFileNeeded, FALSE, "Applications", NULL);
pTaskBar->bMixLauncherAppli = cairo_dock_get_boolean_key_value (pKeyFile, "TaskBar", "mix launcher appli", &bFlushConfFileNeeded, TRUE, NULL, NULL);
pTaskBar->bGroupAppliByClass = cairo_dock_get_boolean_key_value (pKeyFile, "TaskBar", "group by class", &bFlushConfFileNeeded, TRUE, "Applications", NULL);
pTaskBar->cGroupException = cairo_dock_get_string_key_value (pKeyFile, "TaskBar", "group exception", &bFlushConfFileNeeded, "pidgin;xchat", NULL, NULL);
if (pTaskBar->cGroupException)
{
int i;
for (i = 0; pTaskBar->cGroupException[i] != '\0'; i ++) // on passe tout en minuscule.
pTaskBar->cGroupException[i] = g_ascii_tolower (pTaskBar->cGroupException[i]);
}
pTaskBar->bHideVisibleApplis = cairo_dock_get_boolean_key_value (pKeyFile, "TaskBar", "hide visible", &bFlushConfFileNeeded, FALSE, "Applications", NULL);
pTaskBar->iIconPlacement = cairo_dock_get_integer_key_value (pKeyFile, "TaskBar", "place icons", &bFlushConfFileNeeded, CAIRO_APPLI_AFTER_LAST_LAUNCHER, NULL, NULL); // after the last launcher by default.
pTaskBar->cRelativeIconName = cairo_dock_get_string_key_value (pKeyFile, "TaskBar", "relative icon", &bFlushConfFileNeeded, NULL, NULL, NULL);
pTaskBar->bSeparateApplis = cairo_dock_get_boolean_key_value (pKeyFile, "TaskBar", "separate applis", &bFlushConfFileNeeded, TRUE, NULL, NULL);
// representation
pTaskBar->bOverWriteXIcons = cairo_dock_get_boolean_key_value (pKeyFile, "TaskBar", "overwrite xicon", &bFlushConfFileNeeded, TRUE, NULL, NULL);
pTaskBar->cOverwriteException = cairo_dock_get_string_key_value (pKeyFile, "TaskBar", "overwrite exception", &bFlushConfFileNeeded, "pidgin;xchat", NULL, NULL);
if (pTaskBar->cOverwriteException)
{
int i;
for (i = 0; pTaskBar->cOverwriteException[i] != '\0'; i ++)
pTaskBar->cOverwriteException[i] = g_ascii_tolower (pTaskBar->cOverwriteException[i]);
}
pTaskBar->iMinimizedWindowRenderType = cairo_dock_get_integer_key_value (pKeyFile, "TaskBar", "minimized", &bFlushConfFileNeeded, -1, NULL, NULL);
if (pTaskBar->iMinimizedWindowRenderType == -1) // anciens parametres.
{
gboolean bShowThumbnail = g_key_file_get_boolean (pKeyFile, "TaskBar", "window thumbnail", NULL);
if (bShowThumbnail)
pTaskBar->iMinimizedWindowRenderType = 1;
else
pTaskBar->iMinimizedWindowRenderType = 0;
g_key_file_set_integer (pKeyFile, "TaskBar", "minimized", pTaskBar->iMinimizedWindowRenderType);
}
pTaskBar->fVisibleAppliAlpha = MIN (.6, cairo_dock_get_double_key_value (pKeyFile, "TaskBar", "visibility alpha", &bFlushConfFileNeeded, .35, "Applications", NULL));
pTaskBar->iAppliMaxNameLength = cairo_dock_get_integer_key_value (pKeyFile, "TaskBar", "max name length", &bFlushConfFileNeeded, 25, "Applications", NULL);
// interaction
pTaskBar->iActionOnMiddleClick = cairo_dock_get_integer_key_value (pKeyFile, "TaskBar", "action on middle click", &bFlushConfFileNeeded, 1, NULL, NULL);
pTaskBar->bMinimizeOnClick = cairo_dock_get_boolean_key_value (pKeyFile, "TaskBar", "minimize on click", &bFlushConfFileNeeded, TRUE, "Applications", NULL);
pTaskBar->bPresentClassOnClick = cairo_dock_get_boolean_key_value (pKeyFile, "TaskBar", "present class on click", &bFlushConfFileNeeded, TRUE, NULL, NULL);
pTaskBar->bDemandsAttentionWithDialog = cairo_dock_get_boolean_key_value (pKeyFile, "TaskBar", "demands attention with dialog", &bFlushConfFileNeeded, TRUE, "Applications", NULL);
pTaskBar->iDialogDuration = cairo_dock_get_integer_key_value (pKeyFile, "TaskBar", "duration", &bFlushConfFileNeeded, 2, NULL, NULL);
pTaskBar->cAnimationOnDemandsAttention = cairo_dock_get_string_key_value (pKeyFile, "TaskBar", "animation on demands attention", &bFlushConfFileNeeded, "fire", NULL, NULL);
gchar *cForceDemandsAttention = cairo_dock_get_string_key_value (pKeyFile, "TaskBar", "force demands attention", &bFlushConfFileNeeded, "pidgin;xchat", NULL, NULL);
if (cForceDemandsAttention != NULL)
{
pTaskBar->cForceDemandsAttention = g_ascii_strdown (cForceDemandsAttention, -1);
g_free (cForceDemandsAttention);
}
pTaskBar->cAnimationOnActiveWindow = cairo_dock_get_string_key_value (pKeyFile, "TaskBar", "animation on active window", &bFlushConfFileNeeded, "wobbly", NULL, NULL);
}
return bFlushConfFileNeeded;
}
////////////////////
/// RESET CONFIG ///
////////////////////
static void reset_config (CairoTaskbarParam *pTaskBar)
{
g_free (pTaskBar->cAnimationOnActiveWindow);
g_free (pTaskBar->cAnimationOnDemandsAttention);
g_free (pTaskBar->cOverwriteException);
g_free (pTaskBar->cGroupException);
g_free (pTaskBar->cForceDemandsAttention);
g_free (pTaskBar->cRelativeIconName);
}
////////////
/// LOAD ///
////////////
/*
static void load (void)
{
}
*/
//////////////
/// RELOAD ///
//////////////
static void reload (CairoTaskbarParam *pPrevTaskBar, CairoTaskbarParam *pTaskBar)
{
CairoDock *pDock = g_pMainDock;
if (pPrevTaskBar->bGroupAppliByClass != pTaskBar->bGroupAppliByClass
|| pPrevTaskBar->bHideVisibleApplis != pTaskBar->bHideVisibleApplis
|| pPrevTaskBar->bAppliOnCurrentDesktopOnly != pTaskBar->bAppliOnCurrentDesktopOnly
|| pPrevTaskBar->bMixLauncherAppli != pTaskBar->bMixLauncherAppli
|| pPrevTaskBar->bOverWriteXIcons != pTaskBar->bOverWriteXIcons
|| pPrevTaskBar->iMinimizedWindowRenderType != pTaskBar->iMinimizedWindowRenderType
|| pPrevTaskBar->iAppliMaxNameLength != pTaskBar->iAppliMaxNameLength
|| g_strcmp0 (pPrevTaskBar->cGroupException, pTaskBar->cGroupException) != 0
|| g_strcmp0 (pPrevTaskBar->cOverwriteException, pTaskBar->cOverwriteException) != 0
|| pPrevTaskBar->bShowAppli != pTaskBar->bShowAppli
|| pPrevTaskBar->iIconPlacement != pTaskBar->iIconPlacement
|| pPrevTaskBar->bSeparateApplis != pTaskBar->bSeparateApplis
|| g_strcmp0 (pPrevTaskBar->cRelativeIconName, pTaskBar->cRelativeIconName) != 0)
{
_cairo_dock_stop_application_manager ();
cairo_dock_start_applications_manager (pDock);
gtk_widget_queue_draw (pDock->container.pWidget); // if no appli-icon has been inserted, but an indicator or a grouped class has been added, we need to draw them now
}
else
{
gtk_widget_queue_draw (pDock->container.pWidget); // in case 'fVisibleAlpha' has changed
}
}
//////////////
/// UNLOAD ///
//////////////
static gboolean _remove_appli (G_GNUC_UNUSED GldiWindowActor *actor, Icon *pIcon, G_GNUC_UNUSED gpointer data)
{
if (pIcon == NULL)
return TRUE;
if (pIcon->pAppli == NULL)
{
g_free (pIcon);
return TRUE;
}
/// TODO here ?...
///cairo_dock_set_xicon_geometry (pIcon->Xid, 0, 0, 0, 0); // since we'll not detach the icons one by one, we do it here.
// make it an invalid appli
gldi_icon_unset_appli (pIcon); // we don't want to go into the 'unregister'
g_free (pIcon->cClass); // nor the class manager, since we reseted it beforehand.
pIcon->cClass = NULL;
// if not inside a dock, free it, else it will be freeed with the dock.
if (cairo_dock_get_icon_container (pIcon) == NULL) // not in a dock.
{
gldi_object_unref (GLDI_OBJECT (pIcon));
}
return TRUE;
}
static void unload (void)
{
// empty the class table.
cairo_dock_reset_class_table ();
// empty the applis table.
g_hash_table_foreach_remove (s_hAppliIconsTable, (GHRFunc) _remove_appli, NULL);
s_bAppliManagerIsRunning = FALSE;
}
////////////
/// INIT ///
////////////
static void init (void)
{
s_hAppliIconsTable = g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL, // window actor
NULL); // appli-icon
cairo_dock_initialize_class_manager ();
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_CREATED,
(GldiNotificationFunc) _on_window_created,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_DESTROYED,
(GldiNotificationFunc) _on_window_destroyed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_NAME_CHANGED,
(GldiNotificationFunc) _on_window_name_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_ICON_CHANGED,
(GldiNotificationFunc) _on_window_icon_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_ATTENTION_CHANGED,
(GldiNotificationFunc) _on_window_attention_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_SIZE_POSITION_CHANGED,
(GldiNotificationFunc) _on_window_size_position_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_STATE_CHANGED,
(GldiNotificationFunc) _on_window_state_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_CLASS_CHANGED,
(GldiNotificationFunc) _on_window_class_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_DESKTOP_CHANGED,
(GldiNotificationFunc) _on_window_desktop_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myDesktopMgr,
NOTIFICATION_DESKTOP_CHANGED,
(GldiNotificationFunc) _on_desktop_changed,
GLDI_RUN_FIRST, NULL);
gldi_object_register_notification (&myWindowObjectMgr,
NOTIFICATION_WINDOW_ACTIVATED,
(GldiNotificationFunc) _on_active_window_changed,
GLDI_RUN_FIRST, NULL);
}
///////////////
/// MANAGER ///
///////////////
static void init_object (GldiObject *obj, gpointer attr)
{
Icon *icon = (Icon*)obj;
GldiWindowActor *actor = (GldiWindowActor*)attr;
icon->iGroup = CAIRO_DOCK_APPLI;
icon->fOrder = CAIRO_DOCK_LAST_ORDER;
gldi_icon_set_appli (icon, actor);
icon->cName = g_strdup (actor->cName ? actor->cName : actor->cClass);
icon->cClass = g_strdup (actor->cClass); // we'll register the class during the loading of the icon, since it can take some time, and we don't really need the class params right now.
icon->iface.load_image = _load_appli;
icon->iface.action_on_drag_hover = _show_appli_for_drop;
icon->bHasIndicator = myIndicatorsParam.bDrawIndicatorOnAppli;
if (myTaskbarParam.bSeparateApplis)
icon->iGroup = CAIRO_DOCK_APPLI;
else
icon->iGroup = CAIRO_DOCK_LAUNCHER;
//\____________ register it.
cairo_dock_register_appli (icon);
}
static void reset_object (GldiObject *obj)
{
Icon *pIcon = (Icon*)obj;
cairo_dock_unregister_appli (pIcon);
}
void gldi_register_applications_manager (void)
{
// Manager
memset (&myTaskbarMgr, 0, sizeof (GldiManager));
gldi_object_init (GLDI_OBJECT(&myTaskbarMgr), &myManagerObjectMgr, NULL);
myTaskbarMgr.cModuleName = "Taskbar";
// interface
myTaskbarMgr.init = init;
myTaskbarMgr.load = NULL; // the manager is started after the launchers&applets have been created, to avoid unecessary computations.
myTaskbarMgr.unload = unload;
myTaskbarMgr.reload = (GldiManagerReloadFunc)reload;
myTaskbarMgr.get_config = (GldiManagerGetConfigFunc)get_config;
myTaskbarMgr.reset_config = (GldiManagerResetConfigFunc)reset_config;
// Config
memset (&myTaskbarParam, 0, sizeof (CairoTaskbarParam));
myTaskbarMgr.pConfig = (GldiManagerConfigPtr)&myTaskbarParam;
myTaskbarMgr.iSizeOfConfig = sizeof (CairoTaskbarParam);
// data
myTaskbarMgr.pData = (GldiManagerDataPtr)NULL;
myTaskbarMgr.iSizeOfData = 0;
// Object Manager
memset (&myAppliIconObjectMgr, 0, sizeof (GldiObjectManager));
myAppliIconObjectMgr.cName = "AppliIcon";
myAppliIconObjectMgr.iObjectSize = sizeof (Icon);
// interface
myAppliIconObjectMgr.init_object = init_object;
myAppliIconObjectMgr.reset_object = reset_object;
// signals
gldi_object_install_notifications (GLDI_OBJECT (&myAppliIconObjectMgr), NB_NOTIFICATIONS_TASKBAR);
// parent object
gldi_object_set_manager (GLDI_OBJECT (&myAppliIconObjectMgr), &myIconObjectMgr);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-gui-manager.h 000664 001750 001750 00000010434 12223247550 023144 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_GUI_FACILITY__
#define __CAIRO_DOCK_GUI_FACILITY__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-manager.h"
G_BEGIN_DECLS
/** @file cairo-dock-gui-manager.h This class provides functions to act on configuration windows.
*
* It also defines the interface that a GUI backend should implement.
*
* Note: GUIs are built from a .conf file; .conf files are normal group/key files, but with some special indications in the comments. Each key will be represented by a pre-defined widget, that is defined by the first caracter of its comment. The comment also contains a description of the key, and an optionnal tooltip. See cairo-dock-gui-factory.h for the list of pre-defined widgets and a short explanation on how to use them inside a conf file. The file 'cairo-dock.conf' can be an useful example.
*/
/// Definition of the callback called when the user apply the config panel.
typedef gboolean (* CairoDockApplyConfigFunc) (gpointer data);
typedef void (* CairoDockLoadCustomWidgetFunc) (GtkWidget *pWindow, GKeyFile *pKeyFile, GSList *pWidgetList);
typedef void (* CairoDockSaveCustomWidgetFunc) (GtkWidget *pWindow, GKeyFile *pKeyFile, GSList *pWidgetList);
/// Definition of the GUI interface for modules.
struct _CairoDockGuiBackend {
/// display a message on the GUI.
void (*set_status_message_on_gui) (const gchar *cMessage);
/// Reload the current config window from the conf file. iShowPage is the page that should be displayed in case the module has several pages, -1 means to keep the current page.
void (*reload_current_widget) (GldiModuleInstance *pModuleInstance, int iShowPage);
void (*show_module_instance_gui) (GldiModuleInstance *pModuleInstance, int iShowPage);
/// retrieve the widgets in the current module window, corresponding to the (group,key) pair in its conf file.
CairoDockGroupKeyWidget * (*get_widget_from_name) (GldiModuleInstance *pModuleInstance, const gchar *cGroupName, const gchar *cKeyName);
} ;
typedef struct _CairoDockGuiBackend CairoDockGuiBackend;
#define CAIRO_DOCK_FRAME_MARGIN 6
void cairo_dock_register_gui_backend (CairoDockGuiBackend *pBackend);
void cairo_dock_reload_current_widget_full (GldiModuleInstance *pModuleInstance, int iShowPage);
/**Reload the widget of a given module instance if it is currently opened (the current page is displayed). This is useful if the module has modified its conf file and wishes to display the changes.
@param pModuleInstance an instance of a module.
*/
#define cairo_dock_reload_current_module_widget(pModuleInstance) cairo_dock_reload_current_widget_full (pModuleInstance, -1)
#define cairo_dock_reload_current_module_widget_full cairo_dock_reload_current_widget_full
void cairo_dock_show_module_instance_gui (GldiModuleInstance *pModuleInstance, int iShowPage);
/** Display a message on a given window that has a status-bar. If no window is provided, the current config panel will be used.
@param pWindow window where the message should be displayed, or NULL to target the config panel.
@param cMessage the message.
*/
void cairo_dock_set_status_message (GtkWidget *pWindow, const gchar *cMessage);
/** Display a message on a given window that has a status-bar. If no window is provided, the current config panel will be used.
@param pWindow window where the message should be displayed, or NULL to target the config panel.
@param cFormat the message, in a printf-like format
@param ... arguments of the format.
*/
void cairo_dock_set_status_message_printf (GtkWidget *pWindow, const gchar *cFormat, ...) G_GNUC_PRINTF (2, 3);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-module-instance-manager.h 000664 001750 001750 00000010410 12223247550 025441 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_MODULE_INSTANCE_MANAGER__
#define __CAIRO_DOCK_MODULE_INSTANCE_MANAGER__
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-manager.h"
G_BEGIN_DECLS
/**
* @file cairo-dock-module-instance-manager.h This class defines the instances of modules.
*
* A module-instance represents one instance of a module; it holds a set of data: the icon and its container, the config structure and its conf file, the data structure and a slot to plug datas into containers and icons.
* All these parameters are optionnal; a module-instance that has an icon is also called an applet.
*/
// manager
typedef struct _GldiModuleInstanceAttr GldiModuleInstanceAttr;
#ifndef _MANAGER_DEF_
extern GldiObjectManager myModuleInstanceObjectMgr;
#endif
// signals
typedef enum {
NOTIFICATION_MODULE_INSTANCE_DETACHED = NB_NOTIFICATIONS_OBJECT,
NB_NOTIFICATIONS_MODULE_INSTANCES
} GldiModuleInstancesNotifications;
/// Definition of an instance of a module. A module can be instanciated several times.
struct _GldiModuleInstance {
/// object
GldiObject object;
/// the module this instance represents.
GldiModule *pModule;
/// conf file of the instance.
gchar *cConfFilePath;
/// TRUE if the instance can be detached from docks (desklet mode).
gboolean bCanDetach;
/// the icon holding the instance.
Icon *pIcon;
/// container of the icon.
GldiContainer *pContainer;
/// this field repeats the 'pContainer' field if the container is a dock, and is NULL otherwise.
CairoDock *pDock;
/// this field repeats the 'pContainer' field if the container is a desklet, and is NULL otherwise.
CairoDesklet *pDesklet;
/// a drawing context on the icon.
cairo_t *pDrawContext;
/// a unique ID to insert external data on icons and containers.
gint iSlotID;
/// pointer to a structure containing the config parameters of the applet.
gpointer pConfig;
/// pointer to a structure containing the data of the applet.
gpointer pData;
gpointer reserved[2];
};
struct _GldiModuleInstanceAttr {
GldiModule *pModule;
gchar *cConfFilePath;
};
/** Say if an object is a Module-instance.
*@param obj the object.
*@return TRUE if the object is a Module-instance.
*/
#define GLDI_OBJECT_IS_MODULE_INSTANCE(obj) gldi_object_is_manager_child (GLDI_OBJECT(obj), &myModuleInstanceObjectMgr)
GldiModuleInstance *gldi_module_instance_new (GldiModule *pModule, gchar *cConfFilePah);
GKeyFile *gldi_module_instance_open_conf_file (GldiModuleInstance *pInstance, CairoDockMinimalAppletConfig *pMinimalConfig);
void gldi_module_instance_free_generic_config (CairoDockMinimalAppletConfig *pMinimalConfig);
void gldi_module_instance_detach (GldiModuleInstance *pInstance);
void gldi_module_instance_detach_at_position (GldiModuleInstance *pInstance, int iCenterX, int iCenterY);
void gldi_module_instance_popup_description (GldiModuleInstance *pModuleInstance);
gboolean gldi_module_instance_reserve_data_slot (GldiModuleInstance *pInstance);
void gldi_module_instance_release_data_slot (GldiModuleInstance *pInstance);
#define gldi_module_instance_get_icon_data(pIcon, pInstance) ((pIcon)->pDataSlot[pInstance->iSlotID])
#define gldi_module_instance_get_container_data(pContainer, pInstance) ((pContainer)->pDataSlot[pInstance->iSlotID])
#define gldi_module_instance_set_icon_data(pIcon, pInstance, pData) \
(pIcon)->pDataSlot[pInstance->iSlotID] = pData
#define gldi_module_instance_set_container_data(pContainer, pInstance, pData) \
(pContainer)->pDataSlot[pInstance->iSlotID] = pData
void gldi_register_module_instances_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-overlay.c 000664 001750 001750 00000032632 12223247550 022430 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include "cairo-dock-icon-factory.h"
#include "cairo-dock-icon-facility.h"
#include "cairo-dock-draw.h"
#include "cairo-dock-draw-opengl.h"
#include "cairo-dock-image-buffer.h"
#include "cairo-dock-log.h"
#define _MANAGER_DEF_
#include "cairo-dock-overlay.h"
// public (manager, config, data)
GldiObjectManager myOverlayObjectMgr;
// dependancies
extern gboolean g_bUseOpenGL;
// private
#define CD_DEFAULT_SCALE 0.5
CairoOverlay *gldi_overlay_new (CairoOverlayAttr *attr)
{
return (CairoOverlay*)gldi_object_new (&myOverlayObjectMgr, attr);
}
////////////////////
/// ADD / REMOVE ///
////////////////////
static inline void cairo_dock_add_overlay_to_icon (Icon *pIcon, CairoOverlay *pOverlay, CairoOverlayPosition iPosition, gpointer data)
{
if (! pOverlay)
return;
// complete the overlay
pOverlay->iPosition = iPosition;
pOverlay->data = data;
pOverlay->pIcon = pIcon; // overlays are stucked to their icon.
// remove any overlay that matches the couple (position, data).
if (data != NULL)
{
GList* ov = pIcon->pOverlays, *next_ov;
CairoOverlay *p;
while (ov)
{
p = ov->data;
next_ov = ov->next; // get the next element now, since this one may be deleted during this iteration.
if (p->data == data && p->iPosition == iPosition) // same position and same origin => remove
{
gldi_object_unref (GLDI_OBJECT(p));
}
ov = next_ov;
}
}
// add the new overlay to the icon
pIcon->pOverlays = g_list_prepend (pIcon->pOverlays, pOverlay);
}
CairoOverlay *cairo_dock_add_overlay_from_image (Icon *pIcon, const gchar *cImageFile, CairoOverlayPosition iPosition, gpointer data)
{
CairoOverlayAttr attr;
memset (&attr, 0, sizeof (CairoOverlayAttr));
attr.iPosition = iPosition;
attr.pIcon = pIcon;
attr.data = data;
attr.cImageFile = cImageFile;
return gldi_overlay_new (&attr);
}
CairoOverlay *cairo_dock_add_overlay_from_surface (Icon *pIcon, cairo_surface_t *pSurface, int iWidth, int iHeight, CairoOverlayPosition iPosition, gpointer data)
{
CairoOverlayAttr attr;
memset (&attr, 0, sizeof (CairoOverlayAttr));
attr.iPosition = iPosition;
attr.pIcon = pIcon;
attr.data = data;
attr.pSurface = pSurface;
attr.iWidth = iWidth;
attr.iHeight = iHeight;
return gldi_overlay_new (&attr);
}
CairoOverlay *cairo_dock_add_overlay_from_texture (Icon *pIcon, GLuint iTexture, CairoOverlayPosition iPosition, gpointer data)
{
CairoOverlayAttr attr;
memset (&attr, 0, sizeof (CairoOverlayAttr));
attr.iPosition = iPosition;
attr.pIcon = pIcon;
attr.data = data;
attr.iTexture = iTexture;
return gldi_overlay_new (&attr);
}
void cairo_dock_remove_overlay_at_position (Icon *pIcon, CairoOverlayPosition iPosition, gpointer data)
{
if (! pIcon)
return;
g_return_if_fail (data != NULL); // a NULL data can't be used to identify an overlay.
GList* ov = pIcon->pOverlays, *next_ov;
CairoOverlay *p;
while (ov)
{
p = ov->data;
next_ov = ov->next; // get the next element now, since this one may be deleted during this iteration.
if (p->data == data && p->iPosition == iPosition) // same position and same origin => remove
{
gldi_object_unref (GLDI_OBJECT(p)); // will remove it from the list
}
ov = next_ov;
}
}
/////////////////////
/// ICON OVERLAYS ///
/////////////////////
void cairo_dock_destroy_icon_overlays (Icon *pIcon)
{
GList *pOverlays = pIcon->pOverlays;
pIcon->pOverlays = NULL; // nullify the list to avoid unnecessary roundtrips.
g_list_foreach (pOverlays, (GFunc)gldi_object_unref, NULL);
g_list_free (pOverlays);
}
static void _get_overlay_position_and_size (CairoOverlay *pOverlay, int w, int h, double z, double *x, double *y, int *wo, int *ho) // from the center of the icon.
{
if (pOverlay->fScale > 0)
{
*wo = round (w * z * pOverlay->fScale); // = pIcon->fWidth * pIcon->fScale
*ho = round (h * z * pOverlay->fScale);
}
else
{
*wo = pOverlay->image.iWidth * z;
*ho = pOverlay->image.iHeight * z;
}
switch (pOverlay->iPosition)
{
case CAIRO_OVERLAY_LOWER_LEFT:
default:
*x = (-w*z + *wo) / 2;
*y = (-h*z + *ho) / 2;
break;
case CAIRO_OVERLAY_LOWER_RIGHT:
*x = (w*z - *wo) / 2;
*y = (-h*z + *ho) / 2;
break;
case CAIRO_OVERLAY_BOTTOM:
*x = 0;
*y = (-h*z + *ho) / 2;
break;
case CAIRO_OVERLAY_UPPER_LEFT:
*x = (-w*z + *wo) / 2;
*y = (h*z - *ho) / 2;
break;
case CAIRO_OVERLAY_UPPER_RIGHT:
*x = (w*z - *wo) / 2;
*y = (h*z - *ho) / 2;
break;
case CAIRO_OVERLAY_TOP:
*x = 0;
*y = (h*z - *ho) / 2;
break;
case CAIRO_OVERLAY_RIGHT:
*x = (w*z - *wo) / 2;
*y = 0;
break;
case CAIRO_OVERLAY_LEFT:
*x = (-w*z + *wo) / 2;
*y = 0;
break;
case CAIRO_OVERLAY_MIDDLE:
*x = 0.;
*y = 0.;
break;
}
}
void cairo_dock_draw_icon_overlays_cairo (Icon *pIcon, double fRatio, cairo_t *pCairoContext)
{
if (pIcon->pOverlays == NULL)
return;
int w, h;
cairo_dock_get_icon_extent (pIcon, &w, &h);
double fMaxScale = cairo_dock_get_icon_max_scale (pIcon);
double z = fRatio * pIcon->fScale / fMaxScale;
GList* ov;
CairoOverlay *p;
int wo, ho; // actual size at which the overlay will rendered.
double x, y; // position of the overlay relatively to the icon center.
for (ov = pIcon->pOverlays; ov != NULL; ov = ov->next)
{
p = ov->data;
if (! p->image.pSurface)
continue;
_get_overlay_position_and_size (p, w, h, z, &x, &y, &wo, &ho);
x += (pIcon->fWidth * pIcon->fScale - wo) / 2.;
y = - y + (pIcon->fHeight * pIcon->fScale - ho) / 2.;
if (pIcon->fScale == 1) // place the overlay on the grid to avoid scale blur (only when the icon is at rest, otherwise it makes the movement jerky).
{
if (wo & 1)
x = floor (x) + .5;
else
x = round (x);
if (ho & 1)
y = floor (y) + .5;
else
y = round (y);
}
cairo_save (pCairoContext);
// translate to the top-left corner of the overlay.
cairo_translate (pCairoContext, x, y);
// draw.
cairo_scale (pCairoContext,
(double) wo / p->image.iWidth,
(double) ho / p->image.iHeight);
cairo_dock_apply_image_buffer_surface_with_offset (&p->image, pCairoContext, 0., 0., pIcon->fAlpha);
cairo_restore (pCairoContext);
}
}
void cairo_dock_draw_icon_overlays_opengl (Icon *pIcon, double fRatio)
{
if (pIcon->pOverlays == NULL)
return;
int w, h;
cairo_dock_get_icon_extent (pIcon, &w, &h);
double fMaxScale = cairo_dock_get_icon_max_scale (pIcon);
double z = fRatio * pIcon->fScale / fMaxScale;
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_over ();
_cairo_dock_set_alpha (pIcon->fAlpha);
GList* ov;
CairoOverlay *p;
int wo, ho; // actual size at which the overlay will be rendered.
double x, y; // position of the overlay relatively to the icon center.
for (ov = pIcon->pOverlays; ov != NULL; ov = ov->next)
{
p = ov->data;
if (! p->image.iTexture)
continue;
glPushMatrix ();
_get_overlay_position_and_size (p, w, h, z, &x, &y, &wo, &ho);
if (pIcon->fScale == 1) // place the overlay on the grid to avoid scale blur (only when the icon is at rest, otherwise it makes the movement jerky).
{
if (wo & 1)
x = floor (x) + .5;
else
x = round (x);
if (ho & 1)
y = floor (y) + .5;
else
y = round (y);
}
// translate to the overlay center.
glRotatef (-pIcon->fOrientation/G_PI*180., 0., 0., 1.);
glTranslatef (x, y, 0.);
// draw.
_cairo_dock_apply_texture_at_size (p->image.iTexture, wo, ho);
glPopMatrix ();
}
_cairo_dock_disable_texture ();
}
/////////////
/// PRINT ///
/////////////
static void cairo_dock_print_overlay_on_icon (Icon *pIcon, CairoOverlay *pOverlay, CairoOverlayPosition iPosition)
{
if (! pOverlay)
return;
int w, h;
cairo_dock_get_icon_extent (pIcon, &w, &h);
//g_print ("%s (%dx%d, %d, %p)\n", __func__, w, h, iPosition, pContainer);
double x, y; // relatively to the icon center.
int wo, ho; // overlay size
pOverlay->iPosition = iPosition;
_get_overlay_position_and_size (pOverlay, w, h, 1, &x, &y, &wo, &ho);
if (pIcon->image.iTexture != 0 && pOverlay->image.iTexture != 0) // dessin opengl : on dessine sur la texture de l'icone avec le mecanisme habituel.
{
/// TODO: handle the case where the drawing is not yet possible (container not yet sized).
if (! cairo_dock_begin_draw_icon (pIcon, 1)) // 1 = keep current drawing
return ;
glPushMatrix ();
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_pbuffer ();
///glBindTexture (GL_TEXTURE_2D, pOverlay->image.iTexture);
///_cairo_dock_apply_current_texture_at_size_with_offset (wo, ho, x, y);
glTranslatef (x, y, 0);
glScalef ((double)wo / pOverlay->image.iWidth,
(double)ho / pOverlay->image.iHeight,
1.);
cairo_dock_apply_image_buffer_texture (&pOverlay->image);
_cairo_dock_disable_texture ();
glPopMatrix ();
cairo_dock_end_draw_icon (pIcon);
}
else if (pIcon->image.pSurface != NULL && pOverlay->image.pSurface != NULL)
{
cairo_t *pCairoContext = cairo_create (pIcon->image.pSurface);
g_return_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS);
cairo_translate (pCairoContext,
w/2 + x - wo/2,
h/2 - y - ho/2);
cairo_scale (pCairoContext,
(double) wo / pOverlay->image.iWidth,
(double) ho / pOverlay->image.iHeight);
cairo_dock_apply_image_buffer_surface_with_offset (&pOverlay->image, pCairoContext, 0., 0., 1);
cairo_paint (pCairoContext);
cairo_destroy (pCairoContext);
}
}
gboolean cairo_dock_print_overlay_on_icon_from_image (Icon *pIcon, const gchar *cImageFile, CairoOverlayPosition iPosition)
{
CairoOverlay *pOverlay = cairo_dock_add_overlay_from_image (pIcon, cImageFile, iPosition, NULL);
if (! pOverlay)
return FALSE;
cairo_dock_print_overlay_on_icon (pIcon, pOverlay, iPosition);
gldi_object_unref (GLDI_OBJECT(pOverlay));
return TRUE;
}
void cairo_dock_print_overlay_on_icon_from_surface (Icon *pIcon, cairo_surface_t *pSurface, int iWidth, int iHeight, CairoOverlayPosition iPosition)
{
CairoOverlay *pOverlay = cairo_dock_add_overlay_from_surface (pIcon, pSurface, iWidth, iHeight, iPosition, NULL);
cairo_dock_print_overlay_on_icon (pIcon, pOverlay, iPosition);
pOverlay->image.pSurface = NULL; // we don't want to free the surface.
gldi_object_unref (GLDI_OBJECT(pOverlay));
}
void cairo_dock_print_overlay_on_icon_from_texture (Icon *pIcon, GLuint iTexture, CairoOverlayPosition iPosition)
{
CairoOverlay *pOverlay = cairo_dock_add_overlay_from_texture (pIcon, iTexture, iPosition, NULL); // we don't need the exact size of the texture as long as the scale is not 0, since then we'll simply draw the texture at the size of the icon * scale
cairo_dock_print_overlay_on_icon (pIcon, pOverlay, iPosition);
pOverlay->image.iTexture = 0; // we don't want to free the texture.
gldi_object_unref (GLDI_OBJECT(pOverlay));
}
///////////////
/// MANAGER ///
///////////////
static void init_object (GldiObject *obj, gpointer attr)
{
CairoOverlay *pOverlay = (CairoOverlay*)obj;
CairoOverlayAttr *cattr = (CairoOverlayAttr*)attr;
g_return_if_fail (cattr->pIcon != NULL);
pOverlay->fScale = CD_DEFAULT_SCALE;
pOverlay->iPosition = cattr->iPosition;
if (cattr->cImageFile != NULL)
{
int iWidth, iHeight;
cairo_dock_get_icon_extent (cattr->pIcon, &iWidth, &iHeight);
cairo_dock_load_image_buffer (&pOverlay->image, cattr->cImageFile, iWidth * pOverlay->fScale, iHeight * pOverlay->fScale, 0);
}
else if (cattr->pSurface != NULL)
{
cairo_dock_load_image_buffer_from_surface (&pOverlay->image, cattr->pSurface,
cattr->iWidth > 0 ? cattr->iWidth : cairo_dock_icon_get_allocated_width (cattr->pIcon),
cattr->iHeight > 0 ? cattr->iHeight : cairo_dock_icon_get_allocated_height (cattr->pIcon)); // we don't need the icon to be actually loaded to add an overlay on it.
}
else if (cattr->iTexture != 0)
{
cairo_dock_load_image_buffer_from_texture (&pOverlay->image, cattr->iTexture, 1, 1); // size will be used to draw it if the scale is set to 0.
}
if (cattr->data != NULL)
{
cairo_dock_add_overlay_to_icon (cattr->pIcon, pOverlay, cattr->iPosition, cattr->data);
}
}
static void reset_object (GldiObject *obj)
{
CairoOverlay *pOverlay = (CairoOverlay*)obj;
// detach the overlay from the icon
Icon *pIcon = pOverlay->pIcon;
if (pIcon)
{
pIcon->pOverlays = g_list_remove (pIcon->pOverlays, pOverlay);
}
// free data
cairo_dock_unload_image_buffer (&pOverlay->image);
}
void gldi_register_overlays_manager (void)
{
// Object Manager
memset (&myOverlayObjectMgr, 0, sizeof (GldiObjectManager));
myOverlayObjectMgr.cName = "Overlay";
myOverlayObjectMgr.iObjectSize = sizeof (CairoOverlay);
// interface
myOverlayObjectMgr.init_object = init_object;
myOverlayObjectMgr.reset_object = reset_object;
// signals
gldi_object_install_notifications (&myOverlayObjectMgr, NB_NOTIFICATIONS_OVERLAYS);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-surface-factory.h 000664 001750 001750 00000034362 12223247550 024053 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_SURFACE_FACTORY__
#define __CAIRO_DOCK_SURFACE_FACTORY__
#include
#include
#include
#include "cairo-dock-struct.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-surface-factory.h This class contains functions to load any image/X buffer/GdkPixbuf/text into a cairo-surface.
* The loading of an image can be modified by a mask, to take into account the ratio, zoom, orientation, etc.
*
* The general way to load an image is by using \ref cairo_dock_create_surface_from_image.
*
* If you just want to load an image at a given size, use \ref cairo_dock_create_surface_from_image_simple, or \ref cairo_dock_create_surface_from_icon.
*
* To load a text into a surface, describe your text look with a _CairoDockLabelDescription, and pass it to \ref cairo_dock_create_surface_from_text.
*
* Note: if you also need to load the image into a texture, it's easier to use the higher level ImageBuffer API (see \ref cairo_dock_create_image_buffer).
*/
/// Types of image loading modifiers.
typedef enum {
/// fill the space, with transparency if necessary.
CAIRO_DOCK_FILL_SPACE = 1<<0,
/// keep the ratio of the original image.
CAIRO_DOCK_KEEP_RATIO = 1<<1,
/// don't zoom in the image if the final surface is larger than the original image.
CAIRO_DOCK_DONT_ZOOM_IN = 1<<2,
/// orientation horizontal flip
CAIRO_DOCK_ORIENTATION_HFLIP = 1<<3,
/// orientation 180° rotation
CAIRO_DOCK_ORIENTATION_ROT_180 = 2<<3,
/// orientation vertical flip
CAIRO_DOCK_ORIENTATION_VFLIP = 3<<3,
/// orientation 90° rotation + horizontal flip
CAIRO_DOCK_ORIENTATION_ROT_90_HFLIP = 4<<3,
/// orientation 90° rotation
CAIRO_DOCK_ORIENTATION_ROT_90 = 5<<3,
/// orientation 90° rotation + vertical flip
CAIRO_DOCK_ORIENTATION_ROT_90_VFLIP = 6<<3,
/// orientation 270° rotation
CAIRO_DOCK_ORIENTATION_ROT_270 = 7<<3,
/// load the image as a strip if possible.
CAIRO_DOCK_ANIMATED_IMAGE = 1<<6
} CairoDockLoadImageModifier;
/// mask to get the orientation from a CairoDockLoadImageModifier.
#define CAIRO_DOCK_ORIENTATION_MASK (7<<3)
/// Description of the rendering of a text.
struct _CairoDockLabelDescription {
/// font size (also approximately the resulting size in pixels)
gint iSize;
/// font.
gchar *cFont;
/// text weight. The higher, the thicker the strokes are.
PangoWeight iWeight;
/// text style (italic or normal).
PangoStyle iStyle;
/// first color of the characters.
gdouble fColorStart[3];
/// second color of the characters. If different from the first one, it will make a gradation.
gdouble fColorStop[3];
/// TRUE if the gradation is vertical (from top to bottom).
gboolean bVerticalPattern;
/// frame background color. Set the alpha channel to 0 to not draw a frame in the background.
gdouble fBackgroundColor[4];
/// TRUE to stroke the outline of the characters (in black).
gboolean bOutlined;
/// margin around the text, it is also the dimension of the frame if available.
gint iMargin;
/// whether to use Pango markups or not (markups are html-like marks, like ...; using markups force you to escape some characters like "&" -> "&")
gboolean bUseMarkup;
/// maximum width allowed, in ratio of the screen's width. Carriage returns will be inserted if necessary. 0 means no limit.
gdouble fMaxRelativeWidth;
};
/* Calcule la taille d'une image selon une contrainte en largeur et hauteur de manière à remplir l'espace donné.
*@param fImageWidth the width of the image. Contient initialement the width of the image, et sera écrasée avec la largeur obtenue.
*@param fImageHeight the height of the image. Contient initialement the height of the image, et sera écrasée avec la hauteur obtenue.
*@param iWidthConstraint contrainte en largeur (0 <=> pas de contrainte).
*@param iHeightConstraint contrainte en hauteur (0 <=> pas de contrainte).
*@param bNoZoomUp TRUE ssi on ne doit pas agrandir the image (seulement la rétrécir).
*@param fZoomWidth sera renseigné avec le facteur de zoom en largeur qui a été appliqué.
*@param fZoomHeight sera renseigné avec le facteur de zoom en hauteur qui a été appliqué.
*/
void cairo_dock_calculate_size_fill (double *fImageWidth, double *fImageHeight, int iWidthConstraint, int iHeightConstraint, gboolean bNoZoomUp, double *fZoomWidth, double *fZoomHeight);
/* Calcule la taille d'une image selon une contrainte en largeur et hauteur en gardant le ratio hauteur/largeur constant.
*@param fImageWidth the width of the image. Contient initialement the width of the image, et sera écrasée avec la largeur obtenue.
*@param fImageHeight the height of the image. Contient initialement the height of the image, et sera écrasée avec la hauteur obtenue.
*@param iWidthConstraint contrainte en largeur (0 <=> pas de contrainte).
*@param iHeightConstraint contrainte en hauteur (0 <=> pas de contrainte).
*@param bNoZoomUp TRUE ssi on ne doit pas agrandir the image (seulement la rétrécir).
*@param fZoom sera renseigné avec le facteur de zoom qui a été appliqué.
*/
void cairo_dock_calculate_size_constant_ratio (double *fImageWidth, double *fImageHeight, int iWidthConstraint, int iHeightConstraint, gboolean bNoZoomUp, double *fZoom);
void cairo_dock_free_label_description (CairoDockLabelDescription *pTextDescription);
void cairo_dock_copy_label_description (CairoDockLabelDescription *pDestTextDescription, CairoDockLabelDescription *pOrigTextDescription);
CairoDockLabelDescription *cairo_dock_duplicate_label_description (CairoDockLabelDescription *pOrigTextDescription);
/** Calculate the size of an image according to a constraint on width and height, and a loading modifier.
*@param fImageWidth pointer to the width of the image. Initially contains the width of the original image, and is updated with the resulting width.
*@param fImageHeight pointer to the height of the image. Initially contains the height of the original image, and is updated with the resulting height.
*@param iWidthConstraint constraint on width (0 <=> no constraint).
*@param iHeightConstraint constraint on height (0 <=> no constraint).
*@param iLoadingModifier a mask of different loading modifiers.
*@param fZoomWidth will be filled with the zoom that has been applied on width.
*@param fZoomHeight will be filled with the zoom that has been applied on height.
*/
void cairo_dock_calculate_constrainted_size (double *fImageWidth, double *fImageHeight, int iWidthConstraint, int iHeightConstraint, CairoDockLoadImageModifier iLoadingModifier, double *fZoomWidth, double *fZoomHeight);
/** Create a surface from raw data of an X icon. The biggest icon possible is taken. The ratio is kept, and the surface will fill the space with transparency if necessary.
*@param pXIconBuffer raw data of the icon.
*@param iBufferNbElements number of elements in the buffer.
*@param iWidth will be filled with the resulting width of the surface.
*@param iHeight will be filled with the resulting height of the surface.
*@return the newly allocated surface.
*/
cairo_surface_t *cairo_dock_create_surface_from_xicon_buffer (gulong *pXIconBuffer, int iBufferNbElements, int iWidth, int iHeight);
/** Create a surface from a GdkPixbuf.
*@param pixbuf the pixbuf.
*@param fMaxScale maximum zoom of the icon.
*@param iWidthConstraint constraint on the width, or 0 to not constraint it.
*@param iHeightConstraint constraint on the height, or 0 to not constraint it.
*@param iLoadingModifier a mask of different loading modifiers.
*@param fImageWidth will be filled with the resulting width of the surface (hors zoom).
*@param fImageHeight will be filled with the resulting height of the surface (hors zoom).
*@param fZoomX if non NULL, will be filled with the zoom that has been applied on width.
*@param fZoomY if non NULL, will be filled with the zoom that has been applied on width.
*@return the newly allocated surface.
*/
cairo_surface_t *cairo_dock_create_surface_from_pixbuf (GdkPixbuf *pixbuf, double fMaxScale, int iWidthConstraint, int iHeightConstraint, CairoDockLoadImageModifier iLoadingModifier, double *fImageWidth, double *fImageHeight, double *fZoomX, double *fZoomY);
void cairo_dock_reset_source_context (void);
/** Create an empty surface (transparent) of a given size. In OpenGL mode, this surface can act as a buffer to generate a texture.
*@param iWidth width of the surface.
*@param iHeight height of the surface.
*@return the newly allocated surface.
*/
cairo_surface_t *cairo_dock_create_blank_surface (int iWidth, int iHeight);
/** Create a surface from any image.
*@param cImagePath complete path to the image.
*@param fMaxScale maximum zoom of the icon.
*@param iWidthConstraint constraint on the width, or 0 to not constraint it.
*@param iHeightConstraint constraint on the height, or 0 to not constraint it.
*@param iLoadingModifier a mask of different loading modifiers.
*@param fImageWidth will be filled with the resulting width of the surface (hors zoom).
*@param fImageHeight will be filled with the resulting height of the surface (hors zoom).
*@param fZoomX if non NULL, will be filled with the zoom that has been applied on width.
*@param fZoomY if non NULL, will be filled with the zoom that has been applied on width.
*@return the newly allocated surface.
*/
cairo_surface_t *cairo_dock_create_surface_from_image (const gchar *cImagePath, double fMaxScale, int iWidthConstraint, int iHeightConstraint, CairoDockLoadImageModifier iLoadingModifier, double *fImageWidth, double *fImageHeight, double *fZoomX, double *fZoomY);
/** Create a surface from any image, at a given size. If the image is given by its sole name, it is searched inside the current theme root folder.
*@param cImageFile path or name of an image.
*@param fImageWidth the desired surface width.
*@param fImageHeight the desired surface height.
*@return the newly allocated surface.
*/
cairo_surface_t *cairo_dock_create_surface_from_image_simple (const gchar *cImageFile, double fImageWidth, double fImageHeight);
/** Create a surface from any image, at a given size. If the image is given by its sole name, it is searched inside the icons themes known by Cairo-Dock.
*@param cImagePath path or name of an image.
*@param fImageWidth the desired surface width.
*@param fImageHeight the desired surface height.
*@return the newly allocated surface.
*/
cairo_surface_t *cairo_dock_create_surface_from_icon (const gchar *cImagePath, double fImageWidth, double fImageHeight);
#define cairo_dock_create_surface_for_icon cairo_dock_create_surface_from_icon
/** Create a square surface from any image, at a given size. If the image is given by its sole name, it is searched inside the icons themes known by Cairo-Dock.
*@param cImagePath path or name of an image.
*@param fImageSize the desired surface size.
*@return the newly allocated surface.
*/
#define cairo_dock_create_surface_for_square_icon(cImagePath, fImageSize) cairo_dock_create_surface_for_icon (cImagePath, fImageSize, fImageSize)
/** Create a surface at a given size, and fill it with a pattern. If the pattern image is given by its sole name, it is searched inside the current theme root folder.
*@param cImageFile path or name of an image that will be repeated to fill the surface.
*@param fImageWidth the desired surface width.
*@param fImageHeight the desired surface height.
*@param fAlpha transparency of the pattern (1 means opaque).
*@return the newly allocated surface.
*/
cairo_surface_t *cairo_dock_create_surface_from_pattern (const gchar *cImageFile, double fImageWidth, double fImageHeight, double fAlpha);
/** Create a surface by rotating another. Only works for 1/4 of rounds.
*@param pSurface surface to rotate.
*@param fImageWidth the width of the surface.
*@param fImageHeight the height of the surface.
*@param fRotationAngle rotation angle to apply, in radians.
*@return the newly allocated surface.
*/
cairo_surface_t * cairo_dock_rotate_surface (cairo_surface_t *pSurface, double fImageWidth, double fImageHeight, double fRotationAngle);
/** Create a surface representing a text, according to a given text description.
*@param cText the text.
*@param pLabelDescription description of the text rendering.
*@param fMaxScale maximum zoom of the text.
*@param iMaxWidth maximum authorized width for the surface; it will be zoomed in to fits this limit. 0 for no limit.
*@param iTextWidth will be filled the width of the resulting surface.
*@param iTextHeight will be filled the height of the resulting surface.
*@return the newly allocated surface.
*/
cairo_surface_t *cairo_dock_create_surface_from_text_full (const gchar *cText, CairoDockLabelDescription *pLabelDescription, double fMaxScale, int iMaxWidth, int *iTextWidth, int *iTextHeight);
/** Create a surface representing a text, according to a given text description.
*@param cText the text.
*@param pLabelDescription description of the text rendering.
*@param iTextWidthPtr will be filled the width of the resulting surface.
*@param iTextHeightPtr will be filled the height of the resulting surface.
*@return the newly allocated surface.
*/
#define cairo_dock_create_surface_from_text(cText, pLabelDescription, iTextWidthPtr, iTextHeightPtr) cairo_dock_create_surface_from_text_full (cText, pLabelDescription, 1., 0, iTextWidthPtr, iTextHeightPtr)
/** Create a surface identical to another, possibly resizing it.
*@param pSurface surface to duplicate.
*@param fWidth the width of the surface.
*@param fHeight the height of the surface.
*@param fDesiredWidth desired width of the copy (0 to keep the same size).
*@param fDesiredHeight desired height of the copy (0 to keep the same size).
*@return the newly allocated surface.
*/
cairo_surface_t * cairo_dock_duplicate_surface (cairo_surface_t *pSurface, double fWidth, double fHeight, double fDesiredWidth, double fDesiredHeight);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-flying-container.h 000664 001750 001750 00000004376 12223247550 024230 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_FLYING_CONTAINER__
#define __CAIRO_FLYING_CONTAINER__
#include "cairo-dock-struct.h"
#include "cairo-dock-container.h"
G_BEGIN_DECLS
// manager
typedef struct _CairoFlyingAttr CairoFlyingAttr;
#ifndef _MANAGER_DEF_
extern GldiManager myFlyingsMgr;
extern GldiObjectManager myFlyingObjectMgr;
#endif
struct _CairoFlyingAttr {
GldiContainerAttr cattr;
Icon *pIcon;
CairoDock *pOriginDock;
} ;
// signals
typedef enum {
NB_NOTIFICATIONS_FLYING_CONTAINER = NB_NOTIFICATIONS_CONTAINER
} CairoFlyingNotifications;
// factory
struct _CairoFlyingContainer {
/// container
GldiContainer container;
/// the flying icon
Icon *pIcon;
/// time the container was created.
double fCreationTime; // see callbacks.c for the usage of this.
};
/** Cast a Container into a FlyingContainer .
*@param pContainer the container.
*@return the FlyingContainer.
*/
#define CAIRO_FLYING_CONTAINER(pContainer) ((CairoFlyingContainer *)pContainer)
/** Say if an object is a FlyingContainer.
*@param obj the object.
*@return TRUE if the object is a FlyingContainer.
*/
#define CAIRO_DOCK_IS_FLYING_CONTAINER(obj) gldi_object_is_manager_child (GLDI_OBJECT(obj), &myFlyingObjectMgr)
CairoFlyingContainer *gldi_flying_container_new (Icon *pFlyingIcon, CairoDock *pOriginDock);
void gldi_flying_container_drag (CairoFlyingContainer *pFlyingContainer, CairoDock *pOriginDock);
void gldi_flying_container_terminate (CairoFlyingContainer *pFlyingContainer);
void gldi_register_flying_manager (void);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-class-icon-manager.c 000664 001750 001750 00000010372 12223247550 024407 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include "cairo-dock-surface-factory.h"
#include "cairo-dock-log.h"
#include "cairo-dock-class-manager.h" // cairo_dock_create_surface_from_class
#include "cairo-dock-indicator-manager.h" // myIndicatorsParam.bUseClassIndic
#include "cairo-dock-class-icon-manager.h"
// public (manager, config, data)
GldiObjectManager myClassIconObjectMgr;
// dependancies
// private
static void _load_image (Icon *icon)
{
int iWidth = icon->iAllocatedWidth;
int iHeight = icon->iAllocatedWidth;
cairo_surface_t *pSurface = NULL;
if (icon->pSubDock != NULL && !myIndicatorsParam.bUseClassIndic) // icone de sous-dock avec un rendu specifique, on le redessinera lorsque les icones du sous-dock auront ete chargees.
{
pSurface = cairo_dock_create_blank_surface (iWidth, iHeight);
}
else
{
cd_debug ("%s (%dx%d)", __func__, iWidth, iHeight);
pSurface = cairo_dock_create_surface_from_class (icon->cClass,
iWidth,
iHeight); /// could make a gldi_image_buffer_load_from_class...
if (pSurface == NULL) // aucun inhibiteur ou aucune image correspondant a cette classe, on cherche a copier une des icones d'appli de cette classe.
{
const GList *pApplis = cairo_dock_list_existing_appli_with_class (icon->cClass);
if (pApplis != NULL)
{
Icon *pOneIcon = (Icon *) (g_list_last ((GList*)pApplis)->data); // on prend le dernier car les applis sont inserees a l'envers, et on veut avoir celle qui etait deja present dans le dock (pour 2 raisons : continuite, et la nouvelle (en 1ere position) n'est pas forcement deja dans un dock, ce qui fausse le ratio).
cd_debug (" load from %s (%dx%d)", pOneIcon->cName, iWidth, iHeight);
pSurface = cairo_dock_duplicate_surface (pOneIcon->image.pSurface,
pOneIcon->image.iWidth,
pOneIcon->image.iHeight,
iWidth,
iHeight); /// could make a gldi_image_buffer_load_from_buffer (&pOneIcon->image, iWidth, iHeight) and duplicate the texture only...
}
}
}
cairo_dock_load_image_buffer_from_surface (&icon->image, pSurface, iWidth, iHeight);
}
Icon *gldi_class_icon_new (Icon *pAppliIcon, CairoDock *pClassSubDock)
{
GldiClassIconAttr attr;
memset (&attr, 0, sizeof (attr));
attr.pAppliIcon = pAppliIcon;
attr.pClassSubDock = pClassSubDock;
return (Icon*)gldi_object_new (&myClassIconObjectMgr, &attr);
}
///////////////
/// MANAGER ///
///////////////
static void init_object (GldiObject *obj, gpointer attr)
{
Icon *pIcon = (Icon*)obj;
GldiClassIconAttr *pAttributes = (GldiClassIconAttr*)attr;
Icon *pSameClassIcon = pAttributes->pAppliIcon;
pIcon->iface.load_image = _load_image;
pIcon->iGroup = pSameClassIcon->iGroup;
pIcon->cName = g_strdup (pSameClassIcon->cClass);
pIcon->cCommand = g_strdup (pSameClassIcon->cCommand);
pIcon->pMimeTypes = g_strdupv (pSameClassIcon->pMimeTypes);
pIcon->cClass = g_strdup (pSameClassIcon->cClass);
pIcon->fOrder = pSameClassIcon->fOrder;
pIcon->bHasIndicator = pSameClassIcon->bHasIndicator;
pIcon->pSubDock = pAttributes->pClassSubDock;
}
void gldi_register_class_icons_manager (void)
{
// Manager
memset (&myClassIconObjectMgr, 0, sizeof (GldiObjectManager));
myClassIconObjectMgr.cName = "ClassIcon";
myClassIconObjectMgr.iObjectSize = sizeof (GldiClassIcon);
// interface
myClassIconObjectMgr.init_object = init_object;
myClassIconObjectMgr.reset_object = NULL;
// signals
gldi_object_install_notifications (GLDI_OBJECT (&myClassIconObjectMgr), NB_NOTIFICATIONS_CLASS_ICON);
// parent object
gldi_object_set_manager (GLDI_OBJECT (&myClassIconObjectMgr), &myIconObjectMgr);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-gui-factory.h 000664 001750 001750 00000026244 12223247550 023207 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_GUI_FACTORY__
#define __CAIRO_DOCK_GUI_FACTORY__
#include
G_BEGIN_DECLS
/**
*@file cairo-dock-gui-factory.h This class handles the construction of the common widgets used in the conf files.
*
* A conf file is a common group/key file, with the following syntax :
* \code
* [Group]
* #comment about key1
* key1 = 1
* #comment about key2
* key2 = pouic
* \endcode
*
* Each key in the conf file has a comment.
*
* The first character of the comment defines the type of widget. Known types are listed in the CairoDockGUIWidgetType enum.
*
* A key can be a behaviour key or an appearance key. Appearance keys are keys that defines the look of the appli, they belong to the theme. Behaviour keys are keys that define some configuration parameters, that depends on the user. To mark a key as an apppearance one, suffix the widget character with a '+'. Thus, keys not marked with a '+' won't be loaded when the user loads a theme, except if he forces it.
*
* After the widget character and its suffix, some widget accept a list of values. For instance, a spinbutton can have a min and a max limits, a list can have pre-defined elements, etc. Such values are set between '[' and ']' brackets, and separated by ';' inside.
*
* After that, let a blank to start the widget description. It will appear on the left of the widget; description must be short enough to fit the config panel width.
*
* You can complete this description with a tooltip. To do that, on a new comment line, add some text between '{' and '}' brackets. Tooltips appear above the widget when you let the mouse over it for ~1 second. They can be as long as you want. Use '\n' to insert new lines inside the tooltip.
*
*/
#define CAIRO_DOCK_GUI_MARGIN 4
/// Types of widgets that Cairo-Dock can automatically build.
typedef enum {
/// boolean in a button to tick.
CAIRO_DOCK_WIDGET_CHECK_BUTTON='b',
/// boolean in a button to tick, that will control the sensitivity of the next widget.
CAIRO_DOCK_WIDGET_CHECK_CONTROL_BUTTON='B',
/// integer in a spin button.
CAIRO_DOCK_WIDGET_SPIN_INTEGER='i',
/// integer in an horizontal scale.
CAIRO_DOCK_WIDGET_HSCALE_INTEGER='I',
/// pair of integers for dimansion WidthxHeight
CAIRO_DOCK_WIDGET_SIZE_INTEGER='j',
/// double in a spin button.
CAIRO_DOCK_WIDGET_SPIN_DOUBLE='f',
/// 3 doubles with a color selector (RGB).
CAIRO_DOCK_WIDGET_COLOR_SELECTOR_RGB='c',
/// 4 doubles with a color selector (RGBA).
CAIRO_DOCK_WIDGET_COLOR_SELECTOR_RGBA='C',
/// double in an horizontal scale.
CAIRO_DOCK_WIDGET_HSCALE_DOUBLE='e',
/// list of views.
CAIRO_DOCK_WIDGET_VIEW_LIST='n',
/// list of themes in a combo, with preview and readme.
CAIRO_DOCK_WIDGET_THEME_LIST='h',
/// list of available animations.
CAIRO_DOCK_WIDGET_ANIMATION_LIST='a',
/// list of available dialog decorators.
CAIRO_DOCK_WIDGET_DIALOG_DECORATOR_LIST='t',
/// list of available desklet decorations.
CAIRO_DOCK_WIDGET_DESKLET_DECORATION_LIST='O',
/// same but with the 'default' choice too.
CAIRO_DOCK_WIDGET_DESKLET_DECORATION_LIST_WITH_DEFAULT='o',
/// list of existing docks.
CAIRO_DOCK_WIDGET_DOCK_LIST='d',
/// list of icons of a dock.
CAIRO_DOCK_WIDGET_ICONS_LIST='N',
/// list of installed icon themes.
CAIRO_DOCK_WIDGET_ICON_THEME_LIST='w',
/// list of screens
CAIRO_DOCK_WIDGET_SCREENS_LIST='r',
/// a button to jump to another module inside the config panel.
CAIRO_DOCK_WIDGET_JUMP_TO_MODULE='m',
/// same but only if the module exists.
CAIRO_DOCK_WIDGET_JUMP_TO_MODULE_IF_EXISTS='M',
/// a button to launch a specific command.
CAIRO_DOCK_WIDGET_LAUNCH_COMMAND='Z',
/// a button to launch a specific command with a condition.
CAIRO_DOCK_WIDGET_LAUNCH_COMMAND_IF_CONDITION='G',
/// a text entry.
CAIRO_DOCK_WIDGET_STRING_ENTRY='s',
/// a text entry with a file selector.
CAIRO_DOCK_WIDGET_FILE_SELECTOR='S',
/// a text entry with a file selector, files are filtered to only display images.
CAIRO_DOCK_WIDGET_IMAGE_SELECTOR='g',
/// a text entry with a folder selector.
CAIRO_DOCK_WIDGET_FOLDER_SELECTOR='D',
/// a text entry with a file selector and a 'play' button, for sound files.
CAIRO_DOCK_WIDGET_SOUND_SELECTOR='u',
/// a text entry with a shortkey selector.
CAIRO_DOCK_WIDGET_SHORTKEY_SELECTOR='k',
/// a text entry with a class selector.
CAIRO_DOCK_WIDGET_CLASS_SELECTOR='K',
/// a text entry, where text is hidden and the result is encrypted in the .conf file.
CAIRO_DOCK_WIDGET_PASSWORD_ENTRY='p',
/// a font selector button.
CAIRO_DOCK_WIDGET_FONT_SELECTOR='P',
/// a text list.
CAIRO_DOCK_WIDGET_LIST='L',
/// a combo-entry, that is to say a list where one can add a custom choice.
CAIRO_DOCK_WIDGET_LIST_WITH_ENTRY='E',
/// a combo where the number of the line is used for the choice.
CAIRO_DOCK_WIDGET_NUMBERED_LIST='l',
/// a combo where the number of the line is used for the choice, and for controlling the sensitivity of the widgets below.
CAIRO_DOCK_WIDGET_NUMBERED_CONTROL_LIST='y',
/// a combo where the number of the line is used for the choice, and for controlling the sensitivity of the widgets below; controlled widgets are indicated in the list : {entry;index first widget;nb widgets}.
CAIRO_DOCK_WIDGET_NUMBERED_CONTROL_LIST_SELECTIVE='Y',
/// a tree view, where lines are numbered and can be moved up and down.
CAIRO_DOCK_WIDGET_TREE_VIEW_SORT='T',
/// a tree view, where lines can be added, removed, and moved up and down.
CAIRO_DOCK_WIDGET_TREE_VIEW_SORT_AND_MODIFY='U',
/// a tree view, where lines are numbered and can be selected or not.
CAIRO_DOCK_WIDGET_TREE_VIEW_MULTI_CHOICE='V',
/// an empty GtkContainer, in case you need to build custom widgets.
CAIRO_DOCK_WIDGET_EMPTY_WIDGET='_',
/// an empty GtkContainer, the same but using full available space.
CAIRO_DOCK_WIDGET_EMPTY_FULL='<',
/// a simple text label.
CAIRO_DOCK_WIDGET_TEXT_LABEL='>',
/// a simple text label.
CAIRO_DOCK_WIDGET_LINK='W',
/// a label containing the handbook of the applet.
CAIRO_DOCK_WIDGET_HANDBOOK='A',
/// an horizontal separator.
CAIRO_DOCK_WIDGET_SEPARATOR='v',
/// a frame. The previous frame will be closed.
CAIRO_DOCK_WIDGET_FRAME='F',
/// a frame inside an expander. The previous frame will be closed.
CAIRO_DOCK_WIDGET_EXPANDER='X',
CAIRO_DOCK_NB_GUI_WIDGETS
} CairoDockGUIWidgetType;
#define CAIRO_DOCK_WIDGET_CAIRO_ONLY '*'
#define CAIRO_DOCK_WIDGET_OPENGL_ONLY '&'
/// Model used for combo-box and tree-view. CAIRO_DOCK_MODEL_NAME is the name as displayed in the widget, and CAIRO_DOCK_MODEL_RESULT is the resulting string effectively written in the config file.
typedef enum {
CAIRO_DOCK_MODEL_NAME = 0, // displayed name
CAIRO_DOCK_MODEL_RESULT, // string that will be used for this line
CAIRO_DOCK_MODEL_DESCRIPTION_FILE, // readme file
CAIRO_DOCK_MODEL_IMAGE, // preview file
CAIRO_DOCK_MODEL_ACTIVE, // whether the line is enabled/disabled (checkbox)
CAIRO_DOCK_MODEL_ORDER, // used to sort lines
CAIRO_DOCK_MODEL_ORDER2, // used to sort lines
CAIRO_DOCK_MODEL_ICON, // icon to be displayed
CAIRO_DOCK_MODEL_STATE, // used to give a state to the line
CAIRO_DOCK_MODEL_SIZE, // size
CAIRO_DOCK_MODEL_AUTHOR, // author
CAIRO_DOCK_MODEL_NB_COLUMNS
} CairoDockGUIModelColumns;
/// Definition of a widget corresponding to a given (group;key) pair.
struct _CairoDockGroupKeyWidget {
gchar *cGroupName;
gchar *cKeyName;
GSList *pSubWidgetList;
gchar *cOriginalConfFilePath;
GtkWidget *pLabel;
GtkWidget *pKeyBox;
};
GtkWidget *cairo_dock_gui_make_preview_box (GtkWidget *pMainWindow, GtkWidget *pOneWidget, gboolean bHorizontalPackaging, int iAddInfoBar, const gchar *cInitialDescription, const gchar *cInitialImage, GPtrArray *pDataGarbage);
void _cairo_dock_set_value_in_pair (GtkSpinButton *pSpinButton, gpointer *data); // exportee pour pouvoir desactiver la callback.
const gchar *cairo_dock_parse_key_comment (gchar *cKeyComment, char *iElementType, guint *iNbElements, gchar ***pAuthorizedValuesList, gboolean *bAligned, const gchar **cTipString);
GtkWidget *cairo_dock_build_group_widget (GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cGettextDomain, GtkWidget *pMainWindow, GSList **pWidgetList, GPtrArray *pDataGarbage, const gchar *cOriginalConfFilePath);
GtkWidget *cairo_dock_build_key_file_widget (GKeyFile* pKeyFile, const gchar *cGettextDomain, GtkWidget *pMainWindow, GSList **pWidgetList, GPtrArray *pDataGarbage, const gchar *cOriginalConfFilePath);
GtkWidget *cairo_dock_build_conf_file_widget (const gchar *cConfFilePath, const gchar *cGettextDomain, GtkWidget *pMainWindow, GSList **pWidgetList, GPtrArray *pDataGarbage, const gchar *cOriginalConfFilePath);
void cairo_dock_update_keyfile_from_widget_list (GKeyFile *pKeyFile, GSList *pWidgetList);
void cairo_dock_free_generated_widget_list (GSList *pWidgetList);
///////////////
// utilities //
///////////////
void cairo_dock_fill_model_with_themes (GtkListStore *pModel, GHashTable *pThemeTable, const gchar *cHint);
void cairo_dock_fill_combo_with_list (GtkWidget *pCombo, GList *pElementList, const gchar *cActiveElement); // utile pour les applets.
GtkWidget *cairo_dock_gui_make_tree_view (gboolean bGetActiveOnly);
GtkWidget *cairo_dock_gui_make_combo (gboolean bWithEntry);
void cairo_dock_gui_select_in_combo_full (GtkWidget *pOneWidget, const gchar *cValue, gboolean bIsTheme);
#define cairo_dock_gui_select_in_combo(pOneWidget, cValue) cairo_dock_gui_select_in_combo_full (pOneWidget, cValue, FALSE)
gchar **cairo_dock_gui_get_active_rows_in_tree_view (GtkWidget *pOneWidget, gboolean bSelectedRows, gsize *iNbElements);
/** Get a widget from a list of widgets representing a configuration window.
The widgets represent a pair (group,key) as defined in the config file.
@param pWidgetList list of widgets built from the config file
@param cGroupName name of the group the widget belongs to
@param cKeyName name of the key the widget represents
@return the widget asociated with the (group,key) , or NULL if none is found
*/
CairoDockGroupKeyWidget *cairo_dock_gui_find_group_key_widget_in_list (GSList *pWidgetList, const gchar *cGroupName, const gchar *cKeyName);
#define cairo_dock_gui_get_widgets(pGroupKeyWidget) (pGroupKeyWidget)->pSubWidgetList
#define cairo_dock_gui_get_first_widget(pGroupKeyWidget) ((pGroupKeyWidget)->pSubWidgetList ? (pGroupKeyWidget)->pSubWidgetList->data : NULL)
#define cairo_dock_gui_add_widget(pGroupKeyWidget, pOneWidget) (pGroupKeyWidget)->pSubWidgetList = g_slist_append ((pGroupKeyWidget)->pSubWidgetList, pOneWidget)
GtkWidget *_gtk_image_new_from_file (const gchar *cIcon, int iSize);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-dock-facility.h 000664 001750 001750 00000021632 12223247550 023474 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_FACILITY__
#define __CAIRO_DOCK_FACILITY__
#include "cairo-dock-struct.h"
#include "cairo-dock-dock-factory.h"
G_BEGIN_DECLS
/**
*@file cairo-dock-dock-facility.h This class contains functions to manipulate docks.
* Some functions are dedicated to linear docks, that is to say when the icon's position can be defined by 1 coordinate inside a non looped interval; it doesn't mean they have to be drawn on a straight line though, see the Curve view.
*/
/* Retourne la largeur max autorisee pour un dock.
* @param pDock le dock.
* @return la taille max.
*/
#define cairo_dock_get_max_authorized_dock_width gldi_dock_get_screen_width
/* Dis si un dock est etendu ou pas.
* @param pDock le dock.
* @return TRUE ssi le dock doit remplir l'ecran.
*/
#define cairo_dock_is_extended_dock(pDock) ((pDock)->bExtendedMode && (pDock)->iRefCount == 0)
#define cairo_dock_is_hidden(pDock) ((pDock)->iRefCount == 0 && (pDock)->bAutoHide && (pDock)->fHideOffset == 1 && (!g_pHidingBackend || !g_pHidingBackend->bCanDisplayHiddenDock))
#define cairo_dock_get_icon_size(pDock) ((pDock)->iIconSize != 0 ? (pDock)->iIconSize : myIconsParam.iIconWidth)
#define gldi_dock_get_screen_offset_x(pDock) (pDock->container.bIsHorizontal ? cairo_dock_get_screen_position_x (pDock->iNumScreen) : cairo_dock_get_screen_position_y (pDock->iNumScreen))
#define gldi_dock_get_screen_offset_y(pDock) (pDock->container.bIsHorizontal ? cairo_dock_get_screen_position_y (pDock->iNumScreen) : cairo_dock_get_screen_position_x (pDock->iNumScreen))
#define gldi_dock_get_screen_width(pDock) (pDock->container.bIsHorizontal ? cairo_dock_get_screen_width (pDock->iNumScreen) : cairo_dock_get_screen_height (pDock->iNumScreen))
#define gldi_dock_get_screen_height(pDock) (pDock->container.bIsHorizontal ? cairo_dock_get_screen_height (pDock->iNumScreen) : cairo_dock_get_screen_width (pDock->iNumScreen))
#define cairo_dock_dock_get_screen(pDock) (cairo_dock_get_nth_screen (pDock->iNumScreen))
/** Compute the maximum size of a dock, and resize it if necessary.
* It takes into account the size limit, and moves the dock so that it stays centered. Also updates the dock's background if necessary, and re-place the appli thumbnails.
*@param pDock the dock.
*/
void cairo_dock_update_dock_size (CairoDock *pDock);
void cairo_dock_trigger_update_dock_size (CairoDock *pDock);
/** Calculate the position of all icons inside a dock, and triggers the enter/leave events according to the position of the mouse.
*@param pDock the dock.
*@return the pointed icon, or NULL if none is pointed.
*/
Icon *cairo_dock_calculate_dock_icons (CairoDock *pDock);
/* Demande au WM d'empecher les autres fenetres d'empieter sur l'espace du dock.
* L'espace reserve est pris sur la taille minimale du dock, c'est-a-dire la taille de la zone de rappel si l'auto-hide est active,
* ou la taille du dock au repos sinon.
* @param pDock le dock.
* @param bReserve TRUE pour reserver l'espace, FALSE pour annuler la reservation.
*/
void cairo_dock_reserve_space_for_dock (CairoDock *pDock, gboolean bReserve);
/* Borne la position d'un dock a l'interieur de l'ecran.
*@param pDock le dock.
*/
void cairo_dock_prevent_dock_from_out_of_screen (CairoDock *pDock); // -> dock-manager
/* Calcule la position d'un dock etant donne ses nouvelles dimensions.
*/
void cairo_dock_get_window_position_at_balance (CairoDock *pDock, int iNewWidth, int iNewHeight, int *iNewPositionX, int *iNewPositionY);
/* Deplace et redimensionne un dock a ses position et taille attitrees. Ne change pas la zone d'input (cela doit etre fait par ailleurs), et ne la replace pas (cela est fait lors du configure).
*/
void cairo_dock_move_resize_dock (CairoDock *pDock);
/* Met a jour les zones d'input d'un dock.
*/
void cairo_dock_update_input_shape (CairoDock *pDock);
#define cairo_dock_set_input_shape_active(pDock) do {\
gldi_container_set_input_shape (CAIRO_CONTAINER (pDock), NULL);\
if (pDock->fMagnitudeMax == 0.)\
gldi_container_set_input_shape (CAIRO_CONTAINER (pDock), pDock->pShapeBitmap);\
else if (pDock->pActiveShapeBitmap != NULL)\
gldi_container_set_input_shape (CAIRO_CONTAINER (pDock), pDock->pActiveShapeBitmap);\
} while (0)
#define cairo_dock_set_input_shape_at_rest(pDock) do {\
gldi_container_set_input_shape (CAIRO_CONTAINER (pDock), NULL);\
gldi_container_set_input_shape (CAIRO_CONTAINER (pDock), pDock->pShapeBitmap);\
} while (0)
#define cairo_dock_set_input_shape_hidden(pDock) do {\
gldi_container_set_input_shape (CAIRO_CONTAINER (pDock), NULL);\
gldi_container_set_input_shape (CAIRO_CONTAINER (pDock), pDock->pHiddenShapeBitmap);\
} while (0)
/** Pop up a sub-dock.
*@param pPointedIcon icon pointing on the sub-dock.
*@param pParentDock dock containing the icon.
*/
void cairo_dock_show_subdock (Icon *pPointedIcon, CairoDock *pParentDock);
/** Get a list of available docks.
*@param pParentDock excluding this dock if not NULL
*@param pSubDock excluding this dock and its children if not NULL
*@return a list of CairoDock*
*/
GList *cairo_dock_get_available_docks (CairoDock *pParentDock, CairoDock *pSubDock);
/** Get a list of available docks where an user icon can be placed. Its current parent dock is excluded, as well as its sub-dock (if any) and its children.
*@param pIcon the icon
*@return a list of CairoDock*
*/
#define cairo_dock_get_available_docks_for_icon(pIcon) cairo_dock_get_available_docks (CAIRO_DOCK(cairo_dock_get_icon_container(pIcon)), pIcon->pSubDock)
/** Calculate the position at rest (when the mouse is outside of the dock and its size is normal) of the icons of a linear dock.
*@param pIconList a list of icons.
*@param fFlatDockWidth width of all the icons placed next to each other.
*/
void cairo_dock_calculate_icons_positions_at_rest_linear (GList *pIconList, double fFlatDockWidth);
double cairo_dock_calculate_max_dock_width (CairoDock *pDock, double fFlatDockWidth, double fWidthConstraintFactor, double fExtraWidth);
Icon * cairo_dock_calculate_wave_with_position_linear (GList *pIconList, int x_abs, gdouble fMagnitude, double fFlatDockWidth, int iWidth, int iHeight, double fAlign, double fLateralFactor, gboolean bDirectionUp);
/** Apply a wave effect on the icons of a linear dock. It is the famous zoom when the mouse hovers an icon.
*@param pDock a linear dock.
*@return the pointed icon, or NULL if none is pointed.
*/
Icon *cairo_dock_apply_wave_effect_linear (CairoDock *pDock);
#define cairo_dock_apply_wave_effect cairo_dock_apply_wave_effect_linear
/** Get the current width of all the icons of a linear dock. It doesn't take into account any decoration or frame, only the space occupied by the icons.
*@param pDock a linear dock.
* @return the dock's width.
*/
double cairo_dock_get_current_dock_width_linear (CairoDock *pDock);
/** Check the position of the mouse inside a linear dock. It can be inside, on the edge, or outside. Update the 'iMousePositionType' field.
*@param pDock a linear dock.
*/
void cairo_dock_check_if_mouse_inside_linear (CairoDock *pDock);
/** Check if one can drop inside a linear dock.
*Drop is allowed between 2 icons of the launchers group, if the user is dragging something over the dock. Update the 'bCanDrop' field.
*@param pDock a linear dock.
*/
void cairo_dock_check_can_drop_linear (CairoDock *pDock);
void cairo_dock_stop_marking_icons (CairoDock *pDock);
void cairo_dock_set_subdock_position_linear (Icon *pPointedIcon, CairoDock *pParentDock);
/** Get the first icon to be drawn inside a linear dock, so that if you draw from left to right, the pointed icon will be drawn at last.
*@param icons a list of icons of a linear dock.
*@return the element of the list that contains the first icon to draw.
*/
GList *cairo_dock_get_first_drawn_element_linear (GList *icons);
void cairo_dock_trigger_redraw_subdock_content (CairoDock *pDock);
void cairo_dock_trigger_redraw_subdock_content_on_icon (Icon *icon);
void cairo_dock_redraw_subdock_content (CairoDock *pDock);
void cairo_dock_trigger_set_WM_icons_geometry (CairoDock *pDock);
void cairo_dock_resize_icon_in_dock (Icon *pIcon, CairoDock *pDock);
void cairo_dock_load_dock_background (CairoDock *pDock);
void cairo_dock_trigger_load_dock_background (CairoDock *pDock); // peu utile
void cairo_dock_make_preview (CairoDock *pDock, const gchar *cPreviewPath);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-keybinder.c 000664 001750 001750 00000030655 12223247550 022726 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
* cairo-dock-keybinder.c
* Login :
* Started on Thu Jan 31 03:57:17 2008 Cedric GESTES
* $Id$
*
* Author(s)
* - Cedric GESTES
* - Havoc Pennington
* - Tim Janik
*
* Copyright (C) 2008 Cedric GESTES
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*
* imported from tomboy_keybinder.c
*/
#include
#include
#include
#include "gldi-config.h"
#ifdef HAVE_X11
#include
#include
#endif
#ifdef HAVE_XEXTEND
#include
#endif
#include "eggaccelerators.h"
#include "cairo-dock-log.h"
#include "cairo-dock-keybinder.h"
// public (manager, config, data)
GldiObjectManager myShortkeyObjectMgr;
// dependancies
// private
static GSList *s_pKeyBindings = NULL;
///static guint32 last_event_time = 0;
///static gboolean processing_event = FALSE;
static guint num_lock_mask=0, caps_lock_mask=0, scroll_lock_mask=0;
static void
lookup_ignorable_modifiers (GdkKeymap *keymap)
{
egg_keymap_resolve_virtual_modifiers (keymap,
EGG_VIRTUAL_LOCK_MASK,
&caps_lock_mask);
egg_keymap_resolve_virtual_modifiers (keymap,
EGG_VIRTUAL_NUM_LOCK_MASK,
&num_lock_mask);
egg_keymap_resolve_virtual_modifiers (keymap,
EGG_VIRTUAL_SCROLL_LOCK_MASK,
&scroll_lock_mask);
}
#ifdef HAVE_X11
static void
grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin,
GldiShortkey *binding,
gboolean grab)
{
guint mod_masks [] = {
0, /* modifier only */
num_lock_mask,
caps_lock_mask,
scroll_lock_mask,
num_lock_mask | caps_lock_mask,
num_lock_mask | scroll_lock_mask,
caps_lock_mask | scroll_lock_mask,
num_lock_mask | caps_lock_mask | scroll_lock_mask,
};
guint i;
for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
if (grab) {
XGrabKey (GDK_WINDOW_XDISPLAY (rootwin),
binding->keycode,
binding->modifiers | mod_masks [i],
GDK_WINDOW_XID (rootwin),
False,
GrabModeAsync,
GrabModeAsync);
} else {
XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
binding->keycode,
binding->modifiers | mod_masks [i],
GDK_WINDOW_XID (rootwin));
}
}
}
static gboolean
do_grab_key (GldiShortkey *binding)
{
GdkKeymap *keymap = gdk_keymap_get_default ();
GdkWindow *rootwin = gdk_get_default_root_window ();
EggVirtualModifierType virtual_mods = 0;
guint keysym = 0;
if (keymap == NULL || rootwin == NULL || binding->keystring == NULL)
return FALSE;
if (!egg_accelerator_parse_virtual (binding->keystring,
&keysym,
&virtual_mods))
return FALSE;
cd_debug ("Got accel %d, %d", keysym, virtual_mods);
binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin), keysym);
if (binding->keycode == 0)
return FALSE;
cd_debug ("Got keycode %d", binding->keycode);
egg_keymap_resolve_virtual_modifiers (keymap,
virtual_mods,
&binding->modifiers);
cd_debug ("Got modmask %d", binding->modifiers);
gdk_error_trap_push ();
grab_ungrab_with_ignorable_modifiers (rootwin,
binding,
TRUE /* grab */);
gdk_flush ();
if (gdk_error_trap_pop ())
{
g_warning ("GldiShortkey '%s' failed!", binding->keystring);
return FALSE;
}
return TRUE;
}
static gboolean
do_ungrab_key (GldiShortkey *binding)
{
GdkWindow *rootwin = gdk_get_default_root_window ();
cd_debug ("Removing grab for '%s'", binding->keystring);
grab_ungrab_with_ignorable_modifiers (rootwin,
binding,
FALSE /* ungrab */);
return TRUE;
}
static GdkFilterReturn
filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, G_GNUC_UNUSED gpointer data)
{
GdkFilterReturn return_val = GDK_FILTER_CONTINUE;
XEvent *xevent = (XEvent *) gdk_xevent;
guint event_mods;
GSList *iter;
cd_debug ("Got Event! %d, %d", xevent->type, event->type);
switch (xevent->type)
{
case KeyPress:
cd_debug ("Got KeyPress! keycode: %d, modifiers: %d", xevent->xkey.keycode, xevent->xkey.state);
/*
* Set the last event time for use when showing
* windows to avoid anti-focus-stealing code.
*/
///processing_event = TRUE;
///last_event_time = xevent->xkey.time;
event_mods = xevent->xkey.state & ~(num_lock_mask | caps_lock_mask | scroll_lock_mask);
for (iter = s_pKeyBindings; iter != NULL; iter = iter->next) {
GldiShortkey *binding = (GldiShortkey *) iter->data;
if (binding->keycode == xevent->xkey.keycode
&& binding->modifiers == event_mods)
{
cd_debug ("Calling handler for '%s'...", binding->keystring);
(binding->handler) (binding->keystring, binding->user_data);
}
}
///processing_event = FALSE;
break;
case KeyRelease:
cd_debug ("Got KeyRelease! ");
break;
}
return return_val;
}
#else
static gboolean do_grab_key (GldiShortkey *binding)
{
cd_warning ("Cairo-Dock was not built with shortkey support - can't bind '%s'", binding->keystring);
return FALSE;
}
#define do_ungrab_key(binding) (void)binding // avoid unused parameter
#endif
static void
on_keymap_changed (G_GNUC_UNUSED GdkKeymap *map)
{
GdkKeymap *keymap = gdk_keymap_get_default ();
GSList *iter;
cd_debug ("Keymap changed! Regrabbing keys...");
for (iter = s_pKeyBindings; iter != NULL; iter = iter->next)
{
GldiShortkey *binding = (GldiShortkey *) iter->data;
do_ungrab_key (binding);
}
lookup_ignorable_modifiers (keymap);
for (iter = s_pKeyBindings; iter != NULL; iter = iter->next)
{
GldiShortkey *binding = (GldiShortkey *) iter->data;
binding->bSuccess = do_grab_key (binding);
}
}
GldiShortkey *gldi_shortkey_new (const gchar *keystring,
const gchar *cDemander,
const gchar *cDescription,
const gchar *cIconFilePath,
const gchar *cConfFilePath,
const gchar *cGroupName,
const gchar *cKeyName,
CDBindkeyHandler handler,
gpointer user_data)
{
GldiShortkeyAttr attr;
attr.keystring = keystring;
attr.cDemander = cDemander;
attr.cDescription = cDescription;
attr.cIconFilePath = cIconFilePath;
attr.cConfFilePath = cConfFilePath;
attr.cGroupName = cGroupName;
attr.cKeyName = cKeyName;
attr.handler = handler;
attr.user_data = user_data;
return (GldiShortkey*)gldi_object_new (&myShortkeyObjectMgr, &attr);
}
gboolean gldi_shortkey_rebind (GldiShortkey *binding,
const gchar *cNewKeyString,
const gchar *cNewDescription)
{
g_return_val_if_fail (binding != NULL, FALSE);
cd_debug ("%s (%s)", __func__, binding->keystring);
// ensure it's a registerd binding
GSList *iter = g_slist_find (s_pKeyBindings, binding);
g_return_val_if_fail (iter != NULL, FALSE);
// update the description if needed
if (cNewDescription != NULL)
{
g_free (binding->cDescription);
binding->cDescription = g_strdup (cNewDescription);
}
// if the shortkey is the same and already bound, no need to re-grab it.
if (g_strcmp0 (cNewKeyString, binding->keystring) == 0 && binding->bSuccess)
return TRUE;
// unbind its current shortkey
if (binding->bSuccess)
do_ungrab_key (binding);
// rebind it to the new shortkey
if (cNewKeyString != binding->keystring)
{
g_free (binding->keystring);
binding->keystring = g_strdup (cNewKeyString);
}
binding->bSuccess = do_grab_key (binding);
gldi_object_notify (binding, NOTIFICATION_SHORTKEY_CHANGED, binding);
return binding->bSuccess;
}
void gldi_shortkeys_foreach (GFunc pCallback, gpointer data)
{
g_slist_foreach (s_pKeyBindings, pCallback, data);
}
#ifdef HAVE_XEXTEND
static gboolean cairo_dock_xtest_is_available (void)
{
static gboolean s_bChecked = FALSE;
static gboolean s_bUseXTest = FALSE;
if (!s_bChecked)
{
s_bChecked = TRUE;
Display *display = gdk_x11_get_default_xdisplay ();
int event_base, error_base, major = 0, minor = 0;
s_bUseXTest = XTestQueryExtension (display, &event_base, &error_base, &major, &minor);
if (!s_bUseXTest)
cd_warning ("XTest extension not available.");
}
return s_bUseXTest;
}
#endif
gboolean cairo_dock_trigger_shortkey (const gchar *cKeyString) // the idea was taken from xdo.
{
#ifdef HAVE_XEXTEND
g_return_val_if_fail (cairo_dock_xtest_is_available (), FALSE);
g_return_val_if_fail (cKeyString != NULL, FALSE);
cd_message ("%s (%s)", __func__, cKeyString);
int iNbKeys = 0;
int *pKeySyms = egg_keystring_to_keysyms (cKeyString, &iNbKeys);
int i;
int keycode;
Display *dpy = gdk_x11_get_default_xdisplay ();
for (i = 0; i < iNbKeys; i ++)
{
keycode = XKeysymToKeycode (dpy, pKeySyms[i]);
XTestFakeKeyEvent (dpy, keycode, TRUE, CurrentTime); // TRUE <=> presse.
}
for (i = iNbKeys-1; i >=0; i --)
{
keycode = XKeysymToKeycode (dpy, pKeySyms[i]);
XTestFakeKeyEvent (dpy, keycode, FALSE, CurrentTime); // TRUE <=> presse.
}
XFlush (dpy);
return TRUE;
#else
(void)cKeyString; // avoid unused parameter
cd_warning ("The dock was not compiled with the support of XTest.");
return FALSE;
#endif
}
////////////
/// INIT ///
////////////
static void init (void)
{
GdkKeymap *keymap = gdk_keymap_get_default ();
lookup_ignorable_modifiers (keymap);
#ifdef HAVE_X11
GdkWindow *rootwin = gdk_get_default_root_window ();
gdk_window_add_filter (rootwin,
filter_func,
NULL);
#endif
g_signal_connect (keymap,
"keys_changed",
G_CALLBACK (on_keymap_changed),
NULL);
}
/**static void unload (void)
{
GSList *iter;
for (iter = s_pKeyBindings; iter != NULL; iter = iter->next)
{
GldiShortkey *binding = (GldiShortkey *) iter->data;
cd_debug (" --- remove key binding '%s'", binding->keystring);
if (binding->bSuccess)
{
do_ungrab_key (binding);
binding->bSuccess = FALSE;
}
gldi_object_notify (&myShortkeyObjectMgr, NOTIFICATION_SHORTKEY_REMOVED, binding);
_free_binding (binding);
}
g_slist_free (s_pKeyBindings);
s_pKeyBindings = NULL;
}*/
///////////////
/// MANAGER ///
///////////////
static void init_object (GldiObject *obj, gpointer attr)
{
GldiShortkey *pShortkey = (GldiShortkey*)obj;
GldiShortkeyAttr *sattr = (GldiShortkeyAttr*)attr;
// store the info
pShortkey->keystring = g_strdup (sattr->keystring);
pShortkey->cDemander = g_strdup (sattr->cDemander);
pShortkey->cDescription = g_strdup (sattr->cDescription);
pShortkey->cIconFilePath = g_strdup (sattr->cIconFilePath);
pShortkey->cConfFilePath = g_strdup (sattr->cConfFilePath);
pShortkey->cGroupName = g_strdup (sattr->cGroupName);
pShortkey->cKeyName = g_strdup (sattr->cKeyName);
pShortkey->handler = sattr->handler;
pShortkey->user_data = sattr->user_data;
// register the new shortkey
s_pKeyBindings = g_slist_prepend (s_pKeyBindings, pShortkey);
// try to grab the key
if (pShortkey->keystring != NULL)
{
pShortkey->bSuccess = do_grab_key (pShortkey);
if (! pShortkey->bSuccess)
{
cd_warning ("Couldn't bind '%s' (%s: %s)\n This shortkey is probably already used by another applet or another application", pShortkey->keystring, pShortkey->cDemander, pShortkey->cDescription);
}
}
}
static void reset_object (GldiObject *obj)
{
GldiShortkey *pShortkey = (GldiShortkey*)obj;
// unbind the shortkey
if (pShortkey->bSuccess)
do_ungrab_key (pShortkey);
// remove it from the list
cd_debug (" --- remove key binding '%s'", pShortkey->keystring);
s_pKeyBindings = g_slist_remove (s_pKeyBindings, pShortkey);
// free data
g_free (pShortkey->keystring);
g_free (pShortkey->cDemander);
g_free (pShortkey->cDescription);
g_free (pShortkey->cIconFilePath);
g_free (pShortkey->cConfFilePath);
g_free (pShortkey->cGroupName);
g_free (pShortkey->cKeyName);
}
void gldi_register_shortkeys_manager (void)
{
// Manager
memset (&myShortkeyObjectMgr, 0, sizeof (GldiObjectManager));
myShortkeyObjectMgr.cName = "Shortkeys";
myShortkeyObjectMgr.iObjectSize = sizeof (GldiShortkey);
// interface
myShortkeyObjectMgr.init_object = init_object;
myShortkeyObjectMgr.reset_object = reset_object;
// signals
gldi_object_install_notifications (&myShortkeyObjectMgr, NB_NOTIFICATIONS_SHORTKEYS);
// init (since we don't unload the shortkeys ourselves, and the init can be done immediately, no need for a Manager)
init ();
}
cairo-dock-3.3.2/src/gldit/cairo-dock-draw.c 000664 001750 001750 00000110534 12223247550 021702 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include "cairo-dock-icon-facility.h" // cairo_dock_get_next_element
#include "cairo-dock-dock-factory.h"
#include "cairo-dock-dock-facility.h" // cairo_dock_get_first_drawn_element_linear
#include "cairo-dock-animations.h" // cairo_dock_calculate_magnitude
#include "cairo-dock-log.h"
#include "cairo-dock-dock-manager.h" // myDocksParam
#include "cairo-dock-applications-manager.h"
#include "cairo-dock-separator-manager.h"
#include "cairo-dock-applet-manager.h"
#include "cairo-dock-backends-manager.h"
#include "cairo-dock-container.h"
#include "cairo-dock-image-buffer.h"
#include "cairo-dock-desktop-manager.h" // g_pFakeTransparencyDesktopBg
#include "cairo-dock-windows-manager.h"
#include "cairo-dock-draw-opengl.h" // pour cairo_dock_render_one_icon
#include "cairo-dock-overlay.h" // cairo_dock_draw_icon_overlays_cairo
#include "cairo-dock-draw.h"
extern CairoDockImageBuffer g_pVisibleZoneBuffer;
extern GldiDesktopBackground *g_pFakeTransparencyDesktopBg;
extern gboolean g_bUseOpenGL;
cairo_t * cairo_dock_create_drawing_context_generic (GldiContainer *pContainer)
{
return gdk_cairo_create (gldi_container_get_gdk_window (pContainer));
}
cairo_t *cairo_dock_create_drawing_context_on_container (GldiContainer *pContainer)
{
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (pContainer);
g_return_val_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS, FALSE);
///if (myContainersParam.bUseFakeTransparency)
///{
if (g_pFakeTransparencyDesktopBg && g_pFakeTransparencyDesktopBg->pSurface)
{
if (pContainer->bIsHorizontal)
cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionX, - pContainer->iWindowPositionY);
else
cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionY, - pContainer->iWindowPositionX);
}
/**else
cairo_set_source_rgba (pCairoContext, 0.8, 0.8, 0.8, 0.0);
}*/
else
cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 0.0);
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
cairo_paint (pCairoContext);
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
return pCairoContext;
}
cairo_t *cairo_dock_create_drawing_context_on_area (GldiContainer *pContainer, GdkRectangle *pArea, double *fBgColor)
{
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (pContainer);
g_return_val_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS, pCairoContext);
if (pArea != NULL && (pArea->x > 0 || pArea->y > 0))
{
cairo_rectangle (pCairoContext,
pArea->x,
pArea->y,
pArea->width,
pArea->height);
cairo_clip (pCairoContext);
}
///if (myContainersParam.bUseFakeTransparency)
///{
if (g_pFakeTransparencyDesktopBg && g_pFakeTransparencyDesktopBg->pSurface)
{
if (pContainer->bIsHorizontal)
cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionX, - pContainer->iWindowPositionY);
else
cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionY, - pContainer->iWindowPositionX);
}
/**else
cairo_set_source_rgba (pCairoContext, 0.8, 0.8, 0.8, 0.0);
}*/
else if (fBgColor != NULL)
cairo_set_source_rgba (pCairoContext, fBgColor[0], fBgColor[1], fBgColor[2], fBgColor[3]);
else
cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 0.0);
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
cairo_paint (pCairoContext);
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
return pCairoContext;
}
double cairo_dock_calculate_extra_width_for_trapeze (double fFrameHeight, double fInclination, double fRadius, double fLineWidth)
{
if (2 * fRadius > fFrameHeight + fLineWidth)
fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
double cosa = 1. / sqrt (1 + fInclination * fInclination);
double sina = fInclination * cosa;
double fExtraWidth = fInclination * (fFrameHeight - (FALSE ? 2 : 1-cosa) * fRadius) + fRadius * (FALSE ? 1 : sina);
return (2 * fExtraWidth + fLineWidth);
/**double fDeltaXForLoop = fInclination * (fFrameHeight + fLineWidth - (myDocksParam.bRoundedBottomCorner ? 2 : 1) * fRadius);
double fDeltaCornerForLoop = fRadius * cosa + (myDocksParam.bRoundedBottomCorner ? fRadius * (1 + sina) * fInclination : 0);
return (2 * (fLineWidth/2 + fDeltaXForLoop + fDeltaCornerForLoop + myDocksParam.iFrameMargin));*/
}
void cairo_dock_draw_rounded_rectangle (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight)
{
if (2*fRadius > fFrameHeight + fLineWidth)
fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
double fDockOffsetX = fRadius + fLineWidth/2;
double fDockOffsetY = 0.;
cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY);
cairo_rel_line_to (pCairoContext, fFrameWidth, 0);
//\_________________ Coin haut droit.
cairo_rel_curve_to (pCairoContext,
0, 0,
fRadius, 0,
fRadius, fRadius);
cairo_rel_line_to (pCairoContext, 0, (fFrameHeight + fLineWidth - fRadius * 2));
//\_________________ Coin bas droit.
cairo_rel_curve_to (pCairoContext,
0, 0,
0, fRadius,
-fRadius, fRadius);
cairo_rel_line_to (pCairoContext, - fFrameWidth, 0);
//\_________________ Coin bas gauche.
cairo_rel_curve_to (pCairoContext,
0, 0,
-fRadius, 0,
-fRadius, - fRadius);
cairo_rel_line_to (pCairoContext, 0, (- fFrameHeight - fLineWidth + fRadius * 2));
//\_________________ Coin haut gauche.
cairo_rel_curve_to (pCairoContext,
0, 0,
0, -fRadius,
fRadius, -fRadius);
if (fRadius < 1)
cairo_close_path (pCairoContext);
}
static double cairo_dock_draw_frame_horizontal (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, int sens, double fInclination, gboolean bRoundedBottomCorner) // la largeur est donnee par rapport "au fond".
{
if (2*fRadius > fFrameHeight + fLineWidth)
fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
double fDeltaXForLoop = fInclination * (fFrameHeight + fLineWidth - (bRoundedBottomCorner ? 2 : 1) * fRadius);
double cosa = 1. / sqrt (1 + fInclination * fInclination);
double sina = cosa * fInclination;
cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY);
cairo_rel_line_to (pCairoContext, fFrameWidth, 0);
//\_________________ Coin haut droit.
cairo_rel_curve_to (pCairoContext,
0, 0,
fRadius * (1. / cosa - fInclination), 0,
fRadius * cosa, sens * fRadius * (1 - sina));
cairo_rel_line_to (pCairoContext, fDeltaXForLoop, sens * (fFrameHeight + fLineWidth - fRadius * (bRoundedBottomCorner ? 2 : 1 - sina)));
//\_________________ Coin bas droit.
if (bRoundedBottomCorner)
cairo_rel_curve_to (pCairoContext,
0, 0,
fRadius * (1 + sina) * fInclination, sens * fRadius * (1 + sina),
-fRadius * cosa, sens * fRadius * (1 + sina));
cairo_rel_line_to (pCairoContext, - fFrameWidth - 2 * fDeltaXForLoop - (bRoundedBottomCorner ? 0 : 2 * fRadius * cosa), 0);
//\_________________ Coin bas gauche.
if (bRoundedBottomCorner)
cairo_rel_curve_to (pCairoContext,
0, 0,
-fRadius * (fInclination + 1. / cosa), 0,
-fRadius * cosa, -sens * fRadius * (1 + sina));
cairo_rel_line_to (pCairoContext, fDeltaXForLoop, sens * (- fFrameHeight - fLineWidth + fRadius * (bRoundedBottomCorner ? 2 : 1 - sina)));
//\_________________ Coin haut gauche.
cairo_rel_curve_to (pCairoContext,
0, 0,
fRadius * (1 - sina) * fInclination, -sens * fRadius * (1 - sina),
fRadius * cosa, -sens * fRadius * (1 - sina));
if (fRadius < 1)
cairo_close_path (pCairoContext);
//return fDeltaXForLoop + fRadius * cosa;
return fInclination * (fFrameHeight - (FALSE ? 2 : 1-sina) * fRadius) + fRadius * (FALSE ? 1 : cosa);
}
static double cairo_dock_draw_frame_vertical (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, int sens, double fInclination, gboolean bRoundedBottomCorner)
{
if (2*fRadius > fFrameHeight + fLineWidth)
fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
double fDeltaXForLoop = fInclination * (fFrameHeight + fLineWidth - (bRoundedBottomCorner ? 2 : 1) * fRadius);
double cosa = 1. / sqrt (1 + fInclination * fInclination);
double sina = cosa * fInclination;
cairo_move_to (pCairoContext, fDockOffsetY, fDockOffsetX);
cairo_rel_line_to (pCairoContext, 0, fFrameWidth);
//\_________________ Coin haut droit.
cairo_rel_curve_to (pCairoContext,
0, 0,
0, fRadius * (1. / cosa - fInclination),
sens * fRadius * (1 - sina), fRadius * cosa);
cairo_rel_line_to (pCairoContext, sens * (fFrameHeight + fLineWidth - fRadius * (bRoundedBottomCorner ? 2 : 1 - sina)), fDeltaXForLoop);
//\_________________ Coin bas droit.
if (bRoundedBottomCorner)
cairo_rel_curve_to (pCairoContext,
0, 0,
sens * fRadius * (1 + sina), fRadius * (1 + sina) * fInclination,
sens * fRadius * (1 + sina), -fRadius * cosa);
cairo_rel_line_to (pCairoContext, 0, - fFrameWidth - 2 * fDeltaXForLoop - (bRoundedBottomCorner ? 0 : 2 * fRadius * cosa));
//\_________________ Coin bas gauche.
if (bRoundedBottomCorner)
cairo_rel_curve_to (pCairoContext,
0, 0,
0, -fRadius * (fInclination + 1. / cosa),
-sens * fRadius * (1 + sina), -fRadius * cosa);
cairo_rel_line_to (pCairoContext, sens * (- fFrameHeight - fLineWidth + fRadius * (bRoundedBottomCorner ? 2 : 1)), fDeltaXForLoop);
//\_________________ Coin haut gauche.
cairo_rel_curve_to (pCairoContext,
0, 0,
-sens * fRadius * (1 - sina), fRadius * (1 - sina) * fInclination,
-sens * fRadius * (1 - sina), fRadius * cosa);
if (fRadius < 1)
cairo_close_path (pCairoContext);
//return fDeltaXForLoop + fRadius * cosa;
return fInclination * (fFrameHeight - (FALSE ? 2 : 1-sina) * fRadius) + fRadius * (FALSE ? 1 : cosa);
}
double cairo_dock_draw_frame (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, int sens, double fInclination, gboolean bHorizontal, gboolean bRoundedBottomCorner)
{
if (bHorizontal)
return cairo_dock_draw_frame_horizontal (pCairoContext, fRadius, fLineWidth, fFrameWidth, fFrameHeight, fDockOffsetX, fDockOffsetY, sens, fInclination, bRoundedBottomCorner);
else
return cairo_dock_draw_frame_vertical (pCairoContext, fRadius, fLineWidth, fFrameWidth, fFrameHeight, fDockOffsetX, fDockOffsetY, sens, fInclination, bRoundedBottomCorner);
}
void cairo_dock_render_decorations_in_frame (cairo_t *pCairoContext, CairoDock *pDock, double fOffsetY, double fOffsetX, double fWidth)
{
//g_print ("%.2f\n", pDock->fDecorationsOffsetX);
if (pDock->backgroundBuffer.pSurface == NULL)
return ;
cairo_save (pCairoContext);
if (pDock->container.bIsHorizontal)
{
cairo_translate (pCairoContext, fOffsetX, fOffsetY);
cairo_scale (pCairoContext, (double)fWidth / pDock->backgroundBuffer.iWidth, (double)pDock->iDecorationsHeight / pDock->backgroundBuffer.iHeight); // pDock->container.iWidth
}
else
{
cairo_translate (pCairoContext, fOffsetY, fOffsetX);
cairo_scale (pCairoContext, (double)pDock->iDecorationsHeight / pDock->backgroundBuffer.iHeight, (double)fWidth / pDock->backgroundBuffer.iWidth);
}
cairo_dock_draw_surface (pCairoContext, pDock->backgroundBuffer.pSurface, pDock->backgroundBuffer.iWidth, pDock->backgroundBuffer.iHeight, pDock->container.bDirectionUp, pDock->container.bIsHorizontal, -1.); // -1 <=> fill_preserve
cairo_restore (pCairoContext);
}
void cairo_dock_set_icon_scale_on_context (cairo_t *pCairoContext, Icon *icon, gboolean bIsHorizontal, G_GNUC_UNUSED double fRatio, gboolean bDirectionUp)
{
if (bIsHorizontal)
{
if (myIconsParam.bConstantSeparatorSize && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
{
cairo_translate (pCairoContext,
icon->fWidthFactor * icon->fWidth * (icon->fScale - 1) / 2,
(bDirectionUp ? 1 * icon->fHeightFactor * icon->fHeight * (icon->fScale - 1) : 0));
cairo_scale (pCairoContext,
icon->fWidth / icon->image.iWidth * icon->fWidthFactor/**fRatio * icon->fWidthFactor / (1 + myIconsParam.fAmplitude)*/,
icon->fHeight / icon->image.iHeight * icon->fHeightFactor/**fRatio * icon->fHeightFactor / (1 + myIconsParam.fAmplitude)*/);
}
else
cairo_scale (pCairoContext,
icon->fWidth / icon->image.iWidth * icon->fWidthFactor * icon->fScale/**fRatio * icon->fWidthFactor * icon->fScale / (1 + myIconsParam.fAmplitude)*/ * icon->fGlideScale,
icon->fHeight / icon->image.iHeight * icon->fHeightFactor * icon->fScale/**fRatio * icon->fHeightFactor * icon->fScale / (1 + myIconsParam.fAmplitude)*/ * icon->fGlideScale);
}
else
{
if (myIconsParam.bConstantSeparatorSize && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
{
cairo_translate (pCairoContext,
icon->fHeightFactor * icon->fHeight * (icon->fScale - 1) / 2,
(bDirectionUp ? 1 * icon->fWidthFactor * icon->fWidth * (icon->fScale - 1) : 0));
cairo_scale (pCairoContext,
icon->fHeight / icon->image.iWidth * icon->fHeightFactor/**fRatio * icon->fHeightFactor / (1 + myIconsParam.fAmplitude)*/,
icon->fWidth / icon->image.iHeight * icon->fWidthFactor/**fRatio * icon->fWidthFactor / (1 + myIconsParam.fAmplitude)*/);
}
else
cairo_scale (pCairoContext,
icon->fHeight / icon->image.iWidth * icon->fHeightFactor * icon->fScale/**fRatio * icon->fHeightFactor * icon->fScale / (1 + myIconsParam.fAmplitude)*/ * icon->fGlideScale,
icon->fWidth / icon->image.iHeight * icon->fWidthFactor * icon->fScale/**fRatio * icon->fWidthFactor * icon->fScale / (1 + myIconsParam.fAmplitude)*/ * icon->fGlideScale);
}
}
void cairo_dock_draw_icon_reflect_cairo (Icon *icon, GldiContainer *pContainer, cairo_t *pCairoContext)
{
if (pContainer->bUseReflect && icon->image.pSurface != NULL)
{
cairo_save (pCairoContext);
double fScale = (myIconsParam.bConstantSeparatorSize && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) ? 1. : icon->fScale);
if (pContainer->bIsHorizontal)
{
cairo_translate (pCairoContext,
0,
(pContainer->bDirectionUp ?
icon->fDeltaYReflection + icon->fHeight * fScale : // go to bottom of icon
-icon->fDeltaYReflection - icon->fHeight * myIconsParam.fReflectHeightRatio)); // go to top of reflect
cairo_rectangle (pCairoContext, 0, 0, icon->fWidth * icon->fScale, icon->fHeight * myIconsParam.fReflectHeightRatio);
if (pContainer->bDirectionUp)
cairo_translate (pCairoContext, 0, icon->fHeight * icon->fHeightFactor * fScale);
else
cairo_translate (pCairoContext, 0, icon->fHeight * icon->fHeightFactor * myIconsParam.fReflectHeightRatio); // go back to top of icon, since we will flip y axis
}
else
{
cairo_translate (pCairoContext,
(pContainer->bDirectionUp ?
icon->fDeltaYReflection + icon->fHeight * fScale : // go to bottom of icon
-icon->fDeltaYReflection - icon->fHeight * myIconsParam.fReflectHeightRatio), // go to top of reflect
0);
cairo_rectangle (pCairoContext, 0, 0, icon->fHeight * myIconsParam.fReflectHeightRatio, icon->fWidth * icon->fScale);
if (pContainer->bDirectionUp)
cairo_translate (pCairoContext, icon->fHeight * icon->fHeightFactor * fScale, 0);
else
cairo_translate (pCairoContext, icon->fHeight * icon->fHeightFactor * myIconsParam.fReflectHeightRatio, 0); // go back to top of icon, since we will flip y axis
}
cairo_clip (pCairoContext);
cairo_dock_set_icon_scale_on_context (pCairoContext, icon, pContainer->bIsHorizontal, 1., pContainer->bDirectionUp);
if (pContainer->bIsHorizontal)
cairo_scale (pCairoContext, 1, -1);
else
cairo_scale (pCairoContext, -1, 1);
cairo_set_source_surface (pCairoContext, icon->image.pSurface, 0.0, 0.0);
if (myBackendsParam.bDynamicReflection) // on applique la surface avec un degrade en transparence, ou avec une transparence simple.
{
cairo_pattern_t *pGradationPattern;
if (pContainer->bIsHorizontal)
{
if (pContainer->bDirectionUp)
pGradationPattern = cairo_pattern_create_linear (
0,
icon->image.iHeight,
0,
icon->image.iHeight * (1 - myIconsParam.fReflectHeightRatio));
else
pGradationPattern = cairo_pattern_create_linear (
0,
0.,
0,
icon->image.iHeight * myIconsParam.fReflectHeightRatio);
g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
cairo_pattern_add_color_stop_rgba (pGradationPattern,
0.,
0.,
0.,
0.,
icon->fAlpha * myIconsParam.fAlbedo);
cairo_pattern_add_color_stop_rgba (pGradationPattern,
1.,
0.,
0.,
0.,
0.);
}
else
{
if (pContainer->bDirectionUp)
pGradationPattern = cairo_pattern_create_linear (
icon->image.iWidth,
0.,
icon->image.iWidth * (1-myIconsParam.fReflectHeightRatio),
0);
else
pGradationPattern = cairo_pattern_create_linear (
0,
0.,
icon->image.iWidth * myIconsParam.fReflectHeightRatio,
0);
g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
cairo_pattern_add_color_stop_rgba (pGradationPattern,
0.,
0.,
0.,
0.,
icon->fAlpha * myIconsParam.fAlbedo);
cairo_pattern_add_color_stop_rgba (pGradationPattern,
1.,
0.,
0.,
0.,
0.);
}
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
cairo_mask (pCairoContext, pGradationPattern);
cairo_pattern_destroy (pGradationPattern);
}
else
{
cairo_paint_with_alpha (pCairoContext, icon->fAlpha * myIconsParam.fAlbedo);
}
cairo_restore (pCairoContext);
}
}
void cairo_dock_draw_icon_cairo (Icon *icon, CairoDock *pDock, cairo_t *pCairoContext)
{
//\_____________________ On dessine l'icone.
if (icon->image.pSurface != NULL)
{
cairo_save (pCairoContext);
cairo_dock_set_icon_scale_on_context (pCairoContext, icon, pDock->container.bIsHorizontal, 1., pDock->container.bDirectionUp);
cairo_set_source_surface (pCairoContext, icon->image.pSurface, 0.0, 0.0);
if (icon->fAlpha == 1)
cairo_paint (pCairoContext);
else
cairo_paint_with_alpha (pCairoContext, icon->fAlpha);
cairo_restore (pCairoContext);
}
//\_____________________ On dessine son reflet.
cairo_dock_draw_icon_reflect_cairo (icon, CAIRO_CONTAINER (pDock), pCairoContext);
}
gboolean cairo_dock_render_icon_notification (G_GNUC_UNUSED gpointer pUserData, Icon *icon, CairoDock *pDock, gboolean *bHasBeenRendered, cairo_t *pCairoContext)
{
if (*bHasBeenRendered)
return GLDI_NOTIFICATION_LET_PASS;
if (pCairoContext != NULL)
{
if (icon->image.pSurface != NULL)
{
cairo_dock_draw_icon_cairo (icon, pDock, pCairoContext);
}
}
else
{
if (icon->image.iTexture != 0)
{
cairo_dock_draw_icon_opengl (icon, pDock);
}
}
*bHasBeenRendered = TRUE;
return GLDI_NOTIFICATION_LET_PASS;
}
void cairo_dock_render_one_icon (Icon *icon, CairoDock *pDock, cairo_t *pCairoContext, double fDockMagnitude, gboolean bUseText)
{
int iWidth = pDock->container.iWidth;
double fRatio = pDock->container.fRatio;
gboolean bDirectionUp = pDock->container.bDirectionUp;
gboolean bIsHorizontal = pDock->container.bIsHorizontal;
if (CAIRO_DOCK_IS_APPLI (icon) && myTaskbarParam.fVisibleAppliAlpha != 0 && ! CAIRO_DOCK_ICON_TYPE_IS_APPLET (icon) && !(myTaskbarParam.iMinimizedWindowRenderType == 1 && icon->pAppli->bIsHidden))
{
double fAlpha = (icon->pAppli->bIsHidden ? MIN (1 - myTaskbarParam.fVisibleAppliAlpha, 1) : MIN (myTaskbarParam.fVisibleAppliAlpha + 1, 1));
if (fAlpha != 1)
icon->fAlpha = fAlpha; // astuce bidon pour pas multiplier 2 fois.
/**if (icon->bIsHidden)
icon->fAlpha *= MIN (1 - myTaskbarParam.fVisibleAppliAlpha, 1);
else
icon->fAlpha *= MIN (myTaskbarParam.fVisibleAppliAlpha + 1, 1);*/
//g_print ("fVisibleAppliAlpha : %.2f & %d => %.2f\n", myTaskbarParam.fVisibleAppliAlpha, icon->bIsHidden, icon->fAlpha);
}
//\_____________________ On se place sur l'icone.
double fGlideScale;
if (icon->fGlideOffset != 0 && (! myIconsParam.bConstantSeparatorSize || ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon)))
{
double fPhase = icon->fPhase + icon->fGlideOffset * icon->fWidth / fRatio / myIconsParam.iSinusoidWidth * G_PI;
if (fPhase < 0)
{
fPhase = 0;
}
else if (fPhase > G_PI)
{
fPhase = G_PI;
}
fGlideScale = (1 + fDockMagnitude * pDock->fMagnitudeMax * myIconsParam.fAmplitude * sin (fPhase)) / icon->fScale; // c'est un peu hacky ... il faudrait passer l'icone precedente en parametre ...
if (bDirectionUp)
{
if (bIsHorizontal)
cairo_translate (pCairoContext, 0., (1-fGlideScale)*icon->fHeight*icon->fScale);
else
cairo_translate (pCairoContext, (1-fGlideScale)*icon->fHeight*icon->fScale, 0.);
}
}
else
fGlideScale = 1;
icon->fGlideScale = fGlideScale;
if (bIsHorizontal)
cairo_translate (pCairoContext, icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1), icon->fDrawY);
else
cairo_translate (pCairoContext, icon->fDrawY, icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1));
cairo_save (pCairoContext);
//\_____________________ On positionne l'icone.
if (icon->fOrientation != 0)
cairo_rotate (pCairoContext, icon->fOrientation);
//\_____________________ On dessine l'icone.
gboolean bIconHasBeenDrawn = FALSE;
gldi_object_notify (&myIconObjectMgr, NOTIFICATION_PRE_RENDER_ICON, icon, pDock, pCairoContext);
gldi_object_notify (&myIconObjectMgr, NOTIFICATION_RENDER_ICON, icon, pDock, &bIconHasBeenDrawn, pCairoContext);
cairo_restore (pCairoContext); // retour juste apres la translation (fDrawX, fDrawY).
//\_____________________ On dessine les etiquettes, avec un alpha proportionnel au facteur d'echelle de leur icone.
if (bUseText && icon->label.pSurface != NULL && icon->iHideLabel == 0
&& (icon->bPointed || (icon->fScale > 1.01 && ! myIconsParam.bLabelForPointedIconOnly))) // 1.01 car sin(pi) = 1+epsilon :-/ // && icon->iAnimationState < CAIRO_DOCK_STATE_CLICKED
{
cairo_save (pCairoContext);
double fMagnitude;
if (myIconsParam.bLabelForPointedIconOnly || pDock->fMagnitudeMax == 0. || myIconsParam.fAmplitude == 0.)
{
fMagnitude = fDockMagnitude; // (icon->fScale - 1) / myIconsParam.fAmplitude / sin (icon->fPhase); // sin (phi ) != 0 puisque fScale > 1.
}
else
{
fMagnitude = (icon->fScale - 1) / myIconsParam.fAmplitude; /// il faudrait diviser par pDock->fMagnitudeMax ...
fMagnitude = pow (fMagnitude, myIconsParam.fLabelAlphaThreshold);
///fMagnitude *= (fMagnitude * myIconsParam.fLabelAlphaThreshold + 1) / (myIconsParam.fLabelAlphaThreshold + 1);
}
//int iLabelSize = icon->label.iHeight;
int iLabelSize = myIconsParam.iLabelSize;
//g_print ("%d / %d\n", icon->label.iHeight, myIconsParam.iLabelSize),
cairo_identity_matrix (pCairoContext); // on positionne les etiquettes sur un pixels entier, sinon ca floute.
if (bIsHorizontal)
cairo_translate (pCairoContext, floor (icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1)), floor (icon->fDrawY));
else
cairo_translate (pCairoContext, floor (icon->fDrawY), floor (icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1)));
double fOffsetX = (icon->fWidth * icon->fScale - icon->label.iWidth) / 2;
if (fOffsetX < - icon->fDrawX) // l'etiquette deborde a gauche.
fOffsetX = - icon->fDrawX;
else if (icon->fDrawX + fOffsetX + icon->label.iWidth > iWidth) // l'etiquette deborde a droite.
fOffsetX = iWidth - icon->label.iWidth - icon->fDrawX;
if (icon->fOrientation != 0 && ! myIconsParam.bTextAlwaysHorizontal)
cairo_rotate (pCairoContext, icon->fOrientation);
if (bIsHorizontal)
{
cairo_dock_apply_image_buffer_surface_with_offset (&icon->label, pCairoContext,
floor (fOffsetX), floor (bDirectionUp ? -iLabelSize : icon->fHeight * icon->fScale), fMagnitude);
}
else if (myIconsParam.bTextAlwaysHorizontal) // horizontal label on a vertical dock -> draw them next to the icon, vertically centered (like the Parabolic view)
{
if (icon->pSubDock && gldi_container_is_visible (CAIRO_CONTAINER (icon->pSubDock))) // in vertical mode
{
fMagnitude /= 3;
}
const int pad = 3;
double fY = icon->fDrawY;
int iMaxWidth = (pDock->container.bDirectionUp ?
fY - (myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin) * (1 - pDock->fMagnitudeMax) - pad :
pDock->container.iHeight - (fY + icon->fHeight * icon->fScale + (myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin) * (1 - pDock->fMagnitudeMax) + pad));
int iOffsetX = floor (bDirectionUp ?
MAX (- iMaxWidth, - (myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin) * (1 - pDock->fMagnitudeMax) - pad - icon->label.iWidth):
icon->fHeight * icon->fScale + (myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin) * (1 - pDock->fMagnitudeMax) + pad);
int iOffsetY = floor (icon->fWidth * icon->fScale/2 - icon->label.iHeight/2);
if (icon->label.iWidth < iMaxWidth)
{
cairo_dock_apply_image_buffer_surface_with_offset (&icon->label, pCairoContext,
iOffsetX,
iOffsetY,
fMagnitude);
}
else
{
cairo_dock_apply_image_buffer_surface_with_offset_and_limit (&icon->label, pCairoContext, iOffsetX, iOffsetY, fMagnitude, iMaxWidth);
}
}
else
{
cairo_rotate (pCairoContext, bDirectionUp ? - G_PI/2 : G_PI/2);
cairo_dock_apply_image_buffer_surface_with_offset (&icon->label, pCairoContext,
floor (bDirectionUp ? fOffsetX - icon->fWidth * icon->fScale : fOffsetX),
-floor (bDirectionUp ? iLabelSize : icon->fHeight * icon->fScale + iLabelSize),
fMagnitude);
}
cairo_restore (pCairoContext); // retour juste apres la translation (fDrawX, fDrawY).
}
//\_____________________ Draw the overlays on top of that.
cairo_dock_draw_icon_overlays_cairo (icon, fRatio, pCairoContext);
}
void cairo_dock_render_one_icon_in_desklet (Icon *icon, GldiContainer *pContainer, cairo_t *pCairoContext, gboolean bUseText)
{
//\_____________________ On dessine l'icone en fonction de son placement, son angle, et sa transparence.
//g_print ("%s (%.2f;%.2f x %.2f)\n", __func__, icon->fDrawX, icon->fDrawY, icon->fScale);
if (icon->image.pSurface != NULL)
{
cairo_save (pCairoContext);
cairo_translate (pCairoContext, icon->fDrawX, icon->fDrawY);
cairo_scale (pCairoContext, icon->fWidthFactor * icon->fScale, icon->fHeightFactor * icon->fScale);
if (icon->fOrientation != 0)
cairo_rotate (pCairoContext, icon->fOrientation);
cairo_dock_apply_image_buffer_surface_with_offset (&icon->image, pCairoContext, 0, 0, icon->fAlpha);
cairo_restore (pCairoContext); // retour juste apres la translation (fDrawX, fDrawY).
if (pContainer->bUseReflect)
{
cairo_dock_draw_icon_reflect_cairo (icon, pContainer, pCairoContext);
}
}
//\_____________________ On dessine les etiquettes.
if (bUseText && icon->label.pSurface != NULL)
{
cairo_save (pCairoContext);
double fOffsetX = (icon->fWidthFactor * icon->fWidth * icon->fScale - icon->label.iWidth) / 2;
if (fOffsetX < - icon->fDrawX)
fOffsetX = - icon->fDrawX;
else if (icon->fDrawX + fOffsetX + icon->label.iWidth > pContainer->iWidth)
fOffsetX = pContainer->iWidth - icon->label.iWidth - icon->fDrawX;
if (icon->fOrientation != 0)
{
cairo_rotate (pCairoContext, icon->fOrientation);
}
cairo_dock_apply_image_buffer_surface_with_offset (&icon->label, pCairoContext,
fOffsetX, -myIconsParam.iLabelSize, 1.);
cairo_restore (pCairoContext); // retour juste apres la translation (fDrawX, fDrawY).
}
//\_____________________ Draw the overlays on top of that.
cairo_dock_draw_icon_overlays_cairo (icon, pContainer->fRatio, pCairoContext);
}
void cairo_dock_draw_string (cairo_t *pCairoContext, CairoDock *pDock, double fStringLineWidth, gboolean bIsLoop, gboolean bForceConstantSeparator)
{
bForceConstantSeparator = bForceConstantSeparator || myIconsParam.bConstantSeparatorSize;
GList *ic, *pFirstDrawnElement = pDock->icons;
if (pFirstDrawnElement == NULL || fStringLineWidth <= 0)
return ;
cairo_save (pCairoContext);
cairo_set_tolerance (pCairoContext, 0.5);
Icon *prev_icon = NULL, *next_icon, *icon;
double x, y, fCurvature = 0.3;
if (bIsLoop)
{
ic = cairo_dock_get_previous_element (pFirstDrawnElement, pDock->icons);
prev_icon = ic->data;
}
ic = pFirstDrawnElement;
icon = ic->data;
GList *next_ic;
double x1, x2, x3;
double y1, y2, y3;
double dx, dy;
x = icon->fDrawX + icon->fWidth * icon->fScale * icon->fWidthFactor / 2;
y = icon->fDrawY + icon->fHeight * icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) ? icon->fHeight * (icon->fScale - 1) / 2 : 0);
if (pDock->container.bIsHorizontal)
cairo_move_to (pCairoContext, x, y);
else
cairo_move_to (pCairoContext, y, x);
do
{
if (prev_icon != NULL)
{
x1 = prev_icon->fDrawX + prev_icon->fWidth * prev_icon->fScale * prev_icon->fWidthFactor / 2;
y1 = prev_icon->fDrawY + prev_icon->fHeight * prev_icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (prev_icon) ? prev_icon->fHeight * (prev_icon->fScale - 1) / 2 : 0);
}
else
{
x1 = x;
y1 = y;
}
prev_icon = icon;
ic = cairo_dock_get_next_element (ic, pDock->icons);
if (ic == pFirstDrawnElement && ! bIsLoop)
break;
icon = ic->data;
x2 = icon->fDrawX + icon->fWidth * icon->fScale * icon->fWidthFactor / 2;
y2 = icon->fDrawY + icon->fHeight * icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) ? icon->fHeight * (icon->fScale - 1) / 2 : 0);
dx = x2 - x;
dy = y2 - y;
next_ic = cairo_dock_get_next_element (ic, pDock->icons);
next_icon = (next_ic == pFirstDrawnElement && ! bIsLoop ? NULL : next_ic->data);
if (next_icon != NULL)
{
x3 = next_icon->fDrawX + next_icon->fWidth * next_icon->fScale * next_icon->fWidthFactor / 2;
y3 = next_icon->fDrawY + next_icon->fHeight * next_icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (next_icon) ? next_icon->fHeight * (next_icon->fScale - 1) / 2 : 0);
}
else
{
x3 = x2;
y3 = y2;
}
if (pDock->container.bIsHorizontal)
cairo_rel_curve_to (pCairoContext,
(fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature : 0),
(fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature * (y - y1) / (x - x1) : 0),
(fabs ((x3 - x2) / (y3 - y2)) > .35 ? dx * (1 - fCurvature) : dx),
(fabs ((x3 - x2) / (y3 - y2)) > .35 ? MAX (0, MIN (dy, dy - dx * fCurvature * (y3 - y2) / (x3 - x2))) : dy),
dx,
dy);
else
cairo_rel_curve_to (pCairoContext,
(fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature * (y - y1) / (x - x1) : 0),
(fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature : 0),
(fabs ((x3 - x2) / (y3 - y2)) > .35 ? MAX (0, MIN (dy, dy - dx * fCurvature * (y3 - y2) / (x3 - x2))) : dy),
(fabs ((x3 - x2) / (y3 - y2)) > .35 ? dx * (1 - fCurvature) : dx),
dy,
dx);
x = x2;
y = y2;
}
while (ic != pFirstDrawnElement);
cairo_set_line_width (pCairoContext, myIconsParam.iStringLineWidth);
cairo_set_source_rgba (pCairoContext, myIconsParam.fStringColor[0], myIconsParam.fStringColor[1], myIconsParam.fStringColor[2], myIconsParam.fStringColor[3]);
cairo_stroke (pCairoContext);
cairo_restore (pCairoContext);
}
void cairo_dock_render_icons_linear (cairo_t *pCairoContext, CairoDock *pDock)
{
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
if (pFirstDrawnElement == NULL)
return;
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex); // * pDock->fMagnitudeMax
Icon *icon;
GList *ic = pFirstDrawnElement;
do
{
icon = ic->data;
cairo_save (pCairoContext);
cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
cairo_restore (pCairoContext);
ic = cairo_dock_get_next_element (ic, pDock->icons);
} while (ic != pFirstDrawnElement);
}
void cairo_dock_draw_surface (cairo_t *pCairoContext, cairo_surface_t *pSurface, int iWidth, int iHeight, gboolean bDirectionUp, gboolean bHorizontal, gdouble fAlpha)
{
if (bDirectionUp)
{
if (bHorizontal)
{
cairo_set_source_surface (pCairoContext, pSurface, 0., 0.);
}
else
{
cairo_rotate (pCairoContext, - G_PI/2);
cairo_set_source_surface (pCairoContext, pSurface, - iWidth, 0.);
}
}
else
{
if (bHorizontal)
{
cairo_scale (pCairoContext, 1., -1.);
cairo_set_source_surface (pCairoContext, pSurface, 0., - iHeight);
}
else
{
cairo_rotate (pCairoContext, G_PI/2);
cairo_set_source_surface (pCairoContext, pSurface, 0., - iHeight);
}
}
if (fAlpha == -1)
cairo_fill_preserve (pCairoContext);
else if (fAlpha != 1)
cairo_paint_with_alpha (pCairoContext, fAlpha);
else
cairo_paint (pCairoContext);
}
void cairo_dock_render_hidden_dock (cairo_t *pCairoContext, CairoDock *pDock)
{
//\_____________________ on dessine la zone de rappel.
if (g_pVisibleZoneBuffer.pSurface != NULL)
{
cairo_save (pCairoContext);
int w = MIN (myDocksParam.iZoneWidth, pDock->container.iWidth);
int h = MIN (myDocksParam.iZoneHeight, pDock->container.iHeight);
if (pDock->container.bIsHorizontal)
{
if (pDock->container.bDirectionUp)
cairo_translate (pCairoContext, (pDock->container.iWidth - w)/2, pDock->container.iHeight - h);
else
cairo_translate (pCairoContext, (pDock->container.iWidth - w)/2, 0.);
}
else
{
if (pDock->container.bDirectionUp)
cairo_translate (pCairoContext, pDock->container.iHeight - h, (pDock->container.iWidth - w)/2);
else
cairo_translate (pCairoContext, 0., (pDock->container.iWidth - w)/2);
}
cairo_dock_draw_surface (pCairoContext, g_pVisibleZoneBuffer.pSurface,
w,
h,
pDock->container.bDirectionUp, // reverse image with dock.
pDock->container.bIsHorizontal,
1.);
cairo_restore (pCairoContext);
}
//\_____________________ on dessine les icones demandant l'attention.
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
if (pFirstDrawnElement == NULL)
return;
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
double y;
Icon *icon;
GList *ic = pFirstDrawnElement;
double *pHiddenBgColor;
const double r = 4; // corner radius of the background
const double gap = 2; // gap to the screen
double dw = (myIconsParam.iIconGap > 2 ? 2 : 0); // 1px margin around the icons for a better readability (only if icons won't be stuck togather then).
double w, h;
do
{
icon = ic->data;
if (icon->bIsDemandingAttention || icon->bAlwaysVisible)
{
y = icon->fDrawY;
icon->fDrawY = (pDock->container.bDirectionUp ? pDock->container.iHeight - icon->fHeight * icon->fScale - gap: gap);
if (icon->bHasHiddenBg)
{
if (icon->pHiddenBgColor) // custom bg color
pHiddenBgColor = icon->pHiddenBgColor;
else // default bg color
pHiddenBgColor = myDocksParam.fHiddenBg;
if ( pHiddenBgColor[3] != 0)
{
cairo_save (pCairoContext);
cairo_set_source_rgba (pCairoContext, pHiddenBgColor[0], pHiddenBgColor[1], pHiddenBgColor[2], pHiddenBgColor[3] * pDock->fPostHideOffset);
w = icon->fWidth * icon->fScale;
h = icon->fHeight * icon->fScale;
if (pDock->container.bIsHorizontal)
{
cairo_translate (pCairoContext, icon->fDrawX - dw / 2, icon->fDrawY);
cairo_dock_draw_rounded_rectangle (pCairoContext, r, 0, w - 2*r + dw, h);
}
else
{
cairo_translate (pCairoContext, icon->fDrawY - dw / 2, icon->fDrawX);
cairo_dock_draw_rounded_rectangle (pCairoContext, r, 0, h - 2*r + dw, w);
}
cairo_fill (pCairoContext);
cairo_restore (pCairoContext);
}
}
cairo_save (pCairoContext);
icon->fAlpha = pDock->fPostHideOffset;
cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
cairo_restore (pCairoContext);
icon->fDrawY = y;
}
ic = cairo_dock_get_next_element (ic, pDock->icons);
} while (ic != pFirstDrawnElement);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-animations.c 000664 001750 001750 00000036762 12225026776 023130 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include
#include
#include "cairo-dock-icon-facility.h" // cairo_dock_icon_is_being_inserted_or_removed
#include "cairo-dock-dock-facility.h" // input shapes
#include "cairo-dock-draw.h" // for transitions
#include "cairo-dock-draw-opengl.h" // idem
#include "cairo-dock-desklet-manager.h" // CAIRO_CONTAINER_IS_OPENGL
#include "cairo-dock-dialog-manager.h" // gldi_dialogs_replace_all
#include "cairo-dock-dock-manager.h"
#include "cairo-dock-applications-manager.h" // myTaskbarParam.cAnimationOnDemandsAttention
#include "cairo-dock-dock-visibility.h" // gldi_dock_search_overlapping_window
#include "cairo-dock-log.h"
#include "cairo-dock-backends-manager.h"
#include "cairo-dock-container.h"
#include "cairo-dock-animations.h"
extern gboolean g_bUseOpenGL;
extern CairoDockGLConfig g_openglConfig;
extern CairoDockHidingEffect *g_pHidingBackend;
extern CairoDockHidingEffect *g_pKeepingBelowBackend;
static gboolean _update_fade_out_dock (G_GNUC_UNUSED gpointer pUserData, CairoDock *pDock, gboolean *bContinueAnimation)
{
pDock->iFadeCounter += (pDock->bFadeInOut ? 1 : -1); // fade out, puis fade in.
if (pDock->iFadeCounter >= myBackendsParam.iHideNbSteps)
{
pDock->bFadeInOut = FALSE;
//g_print ("set below\n");
gtk_window_set_keep_below (GTK_WINDOW (pDock->container.pWidget), TRUE);
// si fenetre maximisee, on met direct iFadeCounter a 0.
// malheureusement X met du temps a faire passer le dock derriere, et ca donne un "sursaut" :-/
}
//g_print ("pDock->iFadeCounter : %d\n", pDock->iFadeCounter);
if (pDock->iFadeCounter > 0)
{
*bContinueAnimation = TRUE;
}
else
{
gldi_object_remove_notification (pDock,
NOTIFICATION_UPDATE,
(GldiNotificationFunc) _update_fade_out_dock,
NULL);
}
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
return GLDI_NOTIFICATION_LET_PASS;
}
void cairo_dock_pop_up (CairoDock *pDock)
{
//g_print ("%s (%d)\n", __func__, pDock->bIsBelow);
if (pDock->bIsBelow)
{
gldi_object_remove_notification (pDock,
NOTIFICATION_UPDATE,
(GldiNotificationFunc) _update_fade_out_dock,
NULL);
pDock->iFadeCounter = 0;
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
//g_print ("set above\n");
gtk_window_set_keep_below (GTK_WINDOW (pDock->container.pWidget), FALSE); // keep above
pDock->bIsBelow = FALSE;
}
}
void cairo_dock_pop_down (CairoDock *pDock)
{
//g_print ("%s (%d, %d)\n", __func__, pDock->bIsBelow, pDock->container.bInside);
if (! pDock->bIsBelow && pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->container.bInside)
{
if (gldi_dock_search_overlapping_window (pDock) != NULL)
{
pDock->iFadeCounter = 0;
pDock->bFadeInOut = TRUE;
gldi_object_register_notification (pDock,
NOTIFICATION_UPDATE,
(GldiNotificationFunc) _update_fade_out_dock,
GLDI_RUN_FIRST, NULL);
if (g_pKeepingBelowBackend != NULL && g_pKeepingBelowBackend->init)
g_pKeepingBelowBackend->init (pDock);
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
}
else
{
//g_print ("set below\n");
gtk_window_set_keep_below (GTK_WINDOW (pDock->container.pWidget), TRUE);
}
pDock->bIsBelow = TRUE;
}
}
gfloat cairo_dock_calculate_magnitude (gint iMagnitudeIndex) // merci a Robrob pour le patch !
{
gfloat tmp= ((gfloat)iMagnitudeIndex)/CAIRO_DOCK_NB_MAX_ITERATIONS;
if (tmp>0.5f)
tmp=1.0f-(1.0f-tmp)*(1.0f-tmp)*(1.0f-tmp)*4.0f;
else
tmp=tmp*tmp*tmp*4.0f;
if (tmp<0.0f)
tmp=0.0f;
if (tmp>1.0f)
tmp=1.0f;
return tmp;
}
void cairo_dock_launch_animation (GldiContainer *pContainer)
{
if (pContainer->iSidGLAnimation == 0 && pContainer->iface.animation_loop != NULL)
{
int iAnimationDeltaT = cairo_dock_get_animation_delta_t (pContainer);
pContainer->bKeepSlowAnimation = TRUE;
pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc)pContainer->iface.animation_loop, pContainer);
}
}
void cairo_dock_start_shrinking (CairoDock *pDock)
{
if (! pDock->bIsShrinkingDown) // on lance l'animation.
{
pDock->bIsGrowingUp = FALSE;
pDock->bIsShrinkingDown = TRUE;
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
}
}
void cairo_dock_start_growing (CairoDock *pDock)
{
//g_print ("%s (%d)\n", __func__, pDock->bIsGrowingUp);
if (! pDock->bIsGrowingUp) // on lance l'animation.
{
pDock->bIsShrinkingDown = FALSE;
pDock->bIsGrowingUp = TRUE;
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
}
}
void cairo_dock_start_hiding (CairoDock *pDock)
{
//g_print ("%s (%d)\n", __func__, pDock->bIsHiding);
if (! pDock->bIsHiding && ! pDock->container.bInside) // rien de plus desagreable que le dock qui se cache quand on est dedans.
{
// set current showing/hiding state
pDock->bIsShowing = FALSE;
pDock->bIsHiding = TRUE;
// empty the input shape (so that the dock doesn't disturb us immediately)
if (pDock->iInputState != CAIRO_DOCK_INPUT_HIDDEN) // if pDock->pHiddenShapeBitmap == NULL (at the beginning), set iInputState anyway, so that when the input-shapes are created, pDock->pHiddenShapeBitmap will be applied to the dock.
{
//g_print ("+++ input shape hidden on start hiding\n");
cairo_dock_set_input_shape_hidden (pDock);
pDock->iInputState = CAIRO_DOCK_INPUT_HIDDEN;
}
// init the animation
if (g_pHidingBackend != NULL && g_pHidingBackend->init)
g_pHidingBackend->init (pDock);
// and launch it
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
}
}
void cairo_dock_start_showing (CairoDock *pDock)
{
//g_print ("%s (%d)\n", __func__, pDock->bIsShowing);
if (! pDock->bIsShowing) // on lance l'animation.
{
// set current showing/hiding state
pDock->bIsShowing = TRUE;
pDock->bIsHiding = FALSE;
// reset the alpha for icons that were always visible (if they were still appearing, their alpha may have not reached 1 yet)
pDock->fPostHideOffset = 1.;
Icon *icon;
GList *ic;
for (ic = pDock->icons; ic != NULL; ic = ic->next)
{
icon = ic->data;
if (icon->bIsDemandingAttention || icon->bAlwaysVisible)
icon->fAlpha = 1.;
}
// reset the input shape (so that we can interact with the dock immediately)
if (pDock->pShapeBitmap && pDock->iInputState == CAIRO_DOCK_INPUT_HIDDEN)
{
//g_print ("+++ input shape at rest on start showing\n");
cairo_dock_set_input_shape_at_rest (pDock);
pDock->iInputState = CAIRO_DOCK_INPUT_AT_REST;
gldi_dialogs_replace_all ();
}
// init the animation
if (g_pHidingBackend != NULL && g_pHidingBackend->init)
g_pHidingBackend->init (pDock);
// and launch it
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
}
}
void gldi_icon_start_animation (Icon *pIcon)
{
g_return_if_fail (pIcon != NULL);
CairoDock *pDock = CAIRO_DOCK (cairo_dock_get_icon_container(pIcon));
g_return_if_fail (CAIRO_DOCK_IS_DOCK (pDock)); // currently only animate icons that are inside a dock
cd_message ("%s (%s, %d)", __func__, pIcon->cName, pIcon->iAnimationState);
if (pIcon->iAnimationState != CAIRO_DOCK_STATE_REST &&
(cairo_dock_icon_is_being_inserted_or_removed (pIcon) || pIcon->bIsDemandingAttention || pIcon->bAlwaysVisible || cairo_dock_animation_will_be_visible (pDock)))
{
//g_print (" c'est parti\n");
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
}
}
void gldi_icon_request_animation (Icon *pIcon, const gchar *cAnimation, int iNbRounds)
{
CairoDock *pDock = CAIRO_DOCK (cairo_dock_get_icon_container(pIcon));
g_return_if_fail (CAIRO_DOCK_IS_DOCK (pDock)); // currently only animate icons that are inside a dock
if (pIcon->iAnimationState != CAIRO_DOCK_STATE_REST) // on le fait avant de changer d'animation, pour le cas ou l'icone ne serait plus placee au meme endroit (rebond).
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
gldi_icon_stop_animation (pIcon);
if (cAnimation == NULL || iNbRounds == 0 || pIcon->iAnimationState != CAIRO_DOCK_STATE_REST)
return ;
gldi_object_notify (pIcon, NOTIFICATION_REQUEST_ICON_ANIMATION, pIcon, pDock, cAnimation, iNbRounds);
gldi_icon_start_animation (pIcon);
}
void gldi_icon_request_attention (Icon *pIcon, const gchar *cAnimation, int iNbRounds)
{
CairoDock *pDock = CAIRO_DOCK (cairo_dock_get_icon_container(pIcon));
g_return_if_fail (CAIRO_DOCK_IS_DOCK (pDock)); // currently only animate icons that are inside a dock
// stop any current animation
gldi_icon_stop_animation (pIcon);
if (pIcon->iAnimationState != CAIRO_DOCK_STATE_REST)
return ;
// set the 'attention animation' flag
pIcon->bIsDemandingAttention = TRUE;
// start the animation
if (iNbRounds <= 0) // <= 0 means infinite
iNbRounds = 1e6;
if (cAnimation == NULL || *cAnimation == '\0' || strcmp (cAnimation, "default") == 0)
{
if (myTaskbarParam.cAnimationOnDemandsAttention != NULL)
cAnimation = myTaskbarParam.cAnimationOnDemandsAttention;
else
cAnimation = "rotate";
}
gldi_icon_request_animation (pIcon, cAnimation, iNbRounds);
cairo_dock_mark_icon_as_clicked (pIcon); // pour eviter qu'un simple survol ne stoppe l'animation.
// if the icon is in a sub-dock, also animate the main icon.
if (pDock->iRefCount > 0)
{
CairoDock *pParentDock = NULL;
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
if (pPointingIcon != NULL)
{
gldi_icon_request_attention (pPointingIcon, cAnimation, iNbRounds);
}
}
else if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && pDock->bIsBelow)
cairo_dock_pop_up (pDock);
}
void gldi_icon_stop_attention (Icon *pIcon)
{
if (! pIcon->bIsDemandingAttention)
return;
cd_debug ("%s (%s)", __func__, pIcon->cName);
gldi_icon_stop_animation (pIcon);
pIcon->bIsDemandingAttention = FALSE;
CairoDock *pDock = CAIRO_DOCK (cairo_dock_get_icon_container(pIcon));
g_return_if_fail (pDock != NULL);
gtk_widget_queue_draw (pDock->container.pWidget); // redraw all the dock, since the animation of the icon can be larger than the icon itself.
// on stoppe la demande d'attention recursivement vers le bas.
if (pDock->iRefCount > 0)
{
GList *ic;
for (ic = pDock->icons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (pIcon->bIsDemandingAttention)
break;
}
if (ic == NULL) // plus aucune animation dans ce dock.
{
CairoDock *pParentDock = NULL;
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
if (pPointingIcon != NULL)
{
gldi_icon_stop_attention (pPointingIcon);
}
}
}
else if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->bIsBelow && ! pDock->container.bInside)
{
cairo_dock_pop_down (pDock);
}
}
void cairo_dock_trigger_icon_removal_from_dock (Icon *pIcon)
{
CairoDock *pDock = CAIRO_DOCK (cairo_dock_get_icon_container(pIcon));
if (pDock != NULL)
{
gldi_icon_stop_animation (pIcon);
if (cairo_dock_animation_will_be_visible (pDock)) // sinon inutile de se taper toute l'animation.
pIcon->fInsertRemoveFactor = 1.0;
else
pIcon->fInsertRemoveFactor = 0.05;
gldi_object_notify (pDock, NOTIFICATION_REMOVE_ICON, pIcon, pDock);
gldi_icon_start_animation (pIcon);
}
}
void cairo_dock_mark_icon_animation_as (Icon *pIcon, CairoDockAnimationState iAnimationState)
{
if (pIcon->iAnimationState < iAnimationState)
{
pIcon->iAnimationState = iAnimationState;
}
}
void cairo_dock_stop_marking_icon_animation_as (Icon *pIcon, CairoDockAnimationState iAnimationState)
{
if (pIcon->iAnimationState == iAnimationState)
{
pIcon->iAnimationState = CAIRO_DOCK_STATE_REST;
}
}
#define cairo_dock_get_transition(pIcon) (pIcon)->pTransition
#define cairo_dock_set_transition(pIcon, transition) (pIcon)->pTransition = transition
static gboolean _cairo_dock_transition_step (G_GNUC_UNUSED gpointer pUserData, Icon *pIcon, GldiContainer *pContainer, gboolean *bContinueAnimation)
{
CairoDockTransition *pTransition = cairo_dock_get_transition (pIcon);
if (pTransition == NULL)
return GLDI_NOTIFICATION_LET_PASS;
pTransition->iCount ++;
int iDetlaT = (pTransition->bFastPace ? cairo_dock_get_animation_delta_t (pContainer) : cairo_dock_get_slow_animation_delta_t (pContainer));
//int iNbSteps = 1.*pTransition->iDuration / iDetlaT;
pTransition->iElapsedTime += iDetlaT;
if (pTransition->iElapsedTime > pTransition->iDuration)
pTransition->iElapsedTime = pTransition->iDuration;
if (! pTransition->bRemoveWhenFinished && pTransition->iDuration != 0 && pTransition->iElapsedTime >= pTransition->iDuration) // skip
return GLDI_NOTIFICATION_LET_PASS;
gboolean bContinue = FALSE;
if (CAIRO_CONTAINER_IS_OPENGL (pTransition->pContainer))
{
if (pTransition->render_opengl)
{
if (! cairo_dock_begin_draw_icon (pIcon, 0))
return GLDI_NOTIFICATION_LET_PASS;
bContinue = pTransition->render_opengl (pIcon, pTransition->pUserData);
cairo_dock_end_draw_icon (pIcon);
cairo_dock_redraw_icon (pIcon);
}
else if (pTransition->render != NULL)
{
bContinue = pTransition->render (pIcon, pTransition->pUserData);
}
}
else if (pTransition->render != NULL)
{
bContinue = pTransition->render (pIcon, pTransition->pUserData);
}
if (pTransition->iDuration != 0 && pTransition->iElapsedTime >= pTransition->iDuration)
bContinue = FALSE;
if (! bContinue)
{
if (pTransition->bRemoveWhenFinished)
cairo_dock_remove_transition_on_icon (pIcon);
}
else
{
*bContinueAnimation = TRUE;
}
return GLDI_NOTIFICATION_LET_PASS;
}
void cairo_dock_set_transition_on_icon (Icon *pIcon, GldiContainer *pContainer, CairoDockTransitionRenderFunc render_step_cairo, CairoDockTransitionGLRenderFunc render_step_opengl, gboolean bFastPace, gint iDuration, gboolean bRemoveWhenFinished, gpointer pUserData, GFreeFunc pFreeUserDataFunc)
{
cairo_dock_remove_transition_on_icon (pIcon);
CairoDockTransition *pTransition = g_new0 (CairoDockTransition, 1);
pTransition->render = render_step_cairo;
pTransition->render_opengl = render_step_opengl;
pTransition->bFastPace = bFastPace;
pTransition->iDuration = iDuration;
pTransition->bRemoveWhenFinished = bRemoveWhenFinished;
pTransition->pContainer = pContainer;
pTransition->pUserData = pUserData;
pTransition->pFreeUserDataFunc = pFreeUserDataFunc;
cairo_dock_set_transition (pIcon, pTransition);
gldi_object_register_notification (pIcon,
bFastPace ? NOTIFICATION_UPDATE_ICON : NOTIFICATION_UPDATE_ICON_SLOW,
(GldiNotificationFunc) _cairo_dock_transition_step,
GLDI_RUN_AFTER, pUserData);
cairo_dock_launch_animation (pContainer);
}
void cairo_dock_remove_transition_on_icon (Icon *pIcon)
{
CairoDockTransition *pTransition = cairo_dock_get_transition (pIcon);
if (pTransition == NULL)
return ;
gldi_object_remove_notification (pIcon,
pTransition->bFastPace ? NOTIFICATION_UPDATE_ICON : NOTIFICATION_UPDATE_ICON_SLOW,
(GldiNotificationFunc) _cairo_dock_transition_step,
pTransition->pUserData);
if (pTransition->pFreeUserDataFunc != NULL)
pTransition->pFreeUserDataFunc (pTransition->pUserData);
g_free (pTransition);
cairo_dock_set_transition (pIcon, NULL);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-themes-manager.h 000664 001750 001750 00000012757 12223247550 023657 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_THEMES_MANAGER__
#define __CAIRO_DOCK_THEMES_MANAGER__
#include
#include
G_BEGIN_DECLS
/**@file cairo-dock-themes-manager.h This class allows defines the structure of the global theme of the dock (launchers, icons, plug-ins, configuration files, etc).
* It also provides methods to manage the themes, like exporting the current theme, importing new themes, deleting themes, etc.
*/
//void cairo_dock_mark_current_theme_as_modified (gboolean bModified); // needed here because of cairo_dock_update_conf_file()
gboolean cairo_dock_current_theme_need_save (void);
void cairo_dock_delete_conf_file (const gchar *cConfFilePath);
gboolean cairo_dock_add_conf_file (const gchar *cOriginalConfFilePath, const gchar *cConfFilePath);
/** Update a conf file with a list of values of the form : {type, name of the groupe, name of the key, value}. Must end with G_TYPE_INVALID.
*@param cConfFilePath path to the conf file.
*@param iFirstDataType type of the first value.
*/
void cairo_dock_update_conf_file (const gchar *cConfFilePath, GType iFirstDataType, ...);
/** Write a key file on the disk.
*@param pKeyFile the key-file
*@param cConfFilePath its path on the disk
*/
void cairo_dock_write_keys_to_conf_file (GKeyFile *pKeyFile, const gchar *cConfFilePath);
/** Export the current theme to a given name. Exported themes can be imported directly from the Theme Manager.
* @param cNewThemeName name to export the theme to.
* @param bSaveBehavior whether to save the behavior paremeters too.
* @param bSaveLaunchers whether to save the launchers too.
* @return TRUE if the theme could be exported succefuly.
*/
gboolean cairo_dock_export_current_theme (const gchar *cNewThemeName, gboolean bSaveBehavior, gboolean bSaveLaunchers);
/** Create a package of the current theme. Packages can be distributed easily, and imported into the dock by a mere drag and drop into the Theme Manager. The package is placed in the cDirPath directory (or $HOME if cDirPath is wrong).
* @param cThemeName name of the package.
* @param cDirPath path to the directory
* @return TRUE if the theme could be packaged succefuly.
*/
gboolean cairo_dock_package_current_theme (const gchar *cThemeName, const gchar *cDirPath);
/** Extract a package into the themes folder. Does not load it.
* @param cPackagePath path of a package. If the package is distant, it is first downoladed.
* @return the path of the theme folder, or NULL if anerror occured.
*/
gchar * cairo_dock_depackage_theme (const gchar *cPackagePath);
/** Remove some exported themes from the hard-disk.
* @param cThemesList a list of theme names, NULL-terminated.
* @return TRUE if the themes has been succefuly deleted.
*/
gboolean cairo_dock_delete_themes (gchar **cThemesList);
/** Import a theme, which can be : a local theme, a user theme, a distant theme, or even the path to a packaged theme.
* @param cThemeName name of the theme to import.
* @param bLoadBehavior whether to import the behavior parameters too.
* @param bLoadLaunchers whether to import the launchers too.
* @return TRUE if the theme could be imported succefuly.
*/
gboolean cairo_dock_import_theme (const gchar *cThemeName, gboolean bLoadBehavior, gboolean bLoadLaunchers);
/** Asynchronously import a theme, which can be : a local theme, a user theme, a distant theme, or even the path to a packaged theme. This function is non-blocking, you'll get a CairoTask that you can discard at any time, and you'll get the result of the import as the first argument of the callback (the second being the data you passed to this function).
* Note that only downloading or unpacking the theme is done asynchronously, actually copying the files in the current theme folder is not (because it couldn't be cancelled without first making a backup).
* @param cThemeName name of the theme to import.
* @param bLoadBehavior whether to import the behavior parameters too.
* @param bLoadLaunchers whether to import the launchers too.
* @param pCallback function called when the download is finished. It takes the result of the import (TRUE for a successful import) and the data you've set here.
* @param data data to be passed to the callback.
* @return the Task that is doing the job. Keep it and use \ref cairo_dock_discard_task if you want to discard the download before it's completed (for instance if the user cancels it), or \ref cairo_dock_free_task inside your callback.
*/
CairoDockTask *cairo_dock_import_theme_async (const gchar *cThemeName, gboolean bLoadBehavior, gboolean bLoadLaunchers, GFunc pCallback, gpointer data);
void cairo_dock_set_paths (gchar *cRootDataDirPath, gchar *cExtraDirPath, gchar *cThemesDirPath, gchar *cCurrentThemeDirPath, gchar *cLocalThemeDirPath, gchar *cDistantThemeDirName, gchar *cThemeServerAdress);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-packages.c 000664 001750 001750 00000074331 12223247550 022527 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#define __USE_XOPEN_EXTENDED
#include
#include
#define __USE_POSIX
#include
#include
#include
#include
#include "gldi-config.h"
#include "cairo-dock-keyfile-utilities.h"
#include "cairo-dock-task.h"
#include "cairo-dock-config.h"
#include "cairo-dock-log.h"
#define _MANAGER_DEF_
#include "cairo-dock-packages.h"
// public (manager, config, data)
CairoConnectionParam myConnectionParam;
GldiManager myConnectionMgr;
// dependancies
// private
#define CAIRO_DOCK_DEFAULT_PACKAGES_LIST_FILE "list.conf"
static gchar *s_cPackageServerAdress = NULL;
////////////////////
/// DOWNLOAD API ///
////////////////////
gchar *cairo_dock_uncompress_file (const gchar *cArchivePath, const gchar *cExtractTo, const gchar *cRealArchiveName)
{
//\_______________ on cree le repertoire d'extraction.
if (!g_file_test (cExtractTo, G_FILE_TEST_EXISTS))
{
if (g_mkdir (cExtractTo, 7*8*8+7*8+5) != 0)
{
cd_warning ("couldn't create directory %s", cExtractTo);
return NULL;
}
}
//\_______________ on construit le chemin local du dossier apres son extraction.
gchar *cLocalFileName;
if (cRealArchiveName == NULL)
cRealArchiveName = cArchivePath;
gchar *str = strrchr (cRealArchiveName, '/');
if (str != NULL)
cLocalFileName = g_strdup (str+1);
else
cLocalFileName = g_strdup (cRealArchiveName);
if (g_str_has_suffix (cLocalFileName, ".tar.gz"))
cLocalFileName[strlen(cLocalFileName)-7] = '\0';
else if (g_str_has_suffix (cLocalFileName, ".tar.bz2"))
cLocalFileName[strlen(cLocalFileName)-8] = '\0';
else if (g_str_has_suffix (cLocalFileName, ".tgz"))
cLocalFileName[strlen(cLocalFileName)-4] = '\0';
g_return_val_if_fail (cLocalFileName != NULL && *cLocalFileName != '\0', NULL);
gchar *cResultPath = g_strdup_printf ("%s/%s", cExtractTo, cLocalFileName);
g_free (cLocalFileName);
//\_______________ on deplace un dossier identique prealable.
gchar *cTempBackup = NULL;
if (g_file_test (cResultPath, G_FILE_TEST_EXISTS))
{
cTempBackup = g_strdup_printf ("%s___cairo-dock-backup", cResultPath);
g_rename (cResultPath, cTempBackup);
}
//\_______________ on decompresse l'archive.
gchar *cCommand = g_strdup_printf ("tar xf%c \"%s\" -C \"%s\"", (g_str_has_suffix (cArchivePath, "bz2") ? 'j' : 'z'), cArchivePath, cExtractTo);
cd_debug ("tar : %s", cCommand);
int r = system (cCommand);
//\_______________ on verifie le resultat, en remettant l'original en cas d'echec.
if (r != 0 || !g_file_test (cResultPath, G_FILE_TEST_EXISTS))
{
cd_warning ("Invalid archive file (%s)", cCommand);
if (cTempBackup != NULL)
{
g_rename (cTempBackup, cResultPath);
}
g_free (cResultPath);
cResultPath = NULL;
}
else if (cTempBackup != NULL)
{
gchar *cCommand = g_strdup_printf ("rm -rf \"%s\"", cTempBackup);
int r = system (cCommand);
if (r < 0)
cd_warning ("Couldn't remove temporary folder (%s)", cCommand);
g_free (cCommand);
}
g_free (cCommand);
g_free (cTempBackup);
return cResultPath;
}
static inline CURL *_init_curl_connection (const gchar *cURL)
{
CURL *handle = curl_easy_init ();
curl_easy_setopt (handle, CURLOPT_URL, cURL);
if (myConnectionParam.cConnectionProxy != NULL)
{
curl_easy_setopt (handle, CURLOPT_PROXY, myConnectionParam.cConnectionProxy);
if (myConnectionParam.iConnectionPort != 0)
curl_easy_setopt (handle, CURLOPT_PROXYPORT, myConnectionParam.iConnectionPort);
if (myConnectionParam.cConnectionUser != NULL && myConnectionParam.
cConnectionPasswd != NULL)
{
gchar *cUserPwd = g_strdup_printf ("%s:%s", myConnectionParam.cConnectionUser, myConnectionParam.
cConnectionPasswd);
curl_easy_setopt (handle, CURLOPT_PROXYUSERPWD, cUserPwd);
g_free (cUserPwd);
/*curl_easy_setopt (handle, CURLOPT_PROXYUSERNAME, myConnectionParam.cConnectionUser);
if (myConnectionParam.cConnectionPasswd != NULL)
curl_easy_setopt (handle, CURLOPT_PROXYPASSWORD, myConnectionParam.cConnectionPasswd);*/ // a partir de libcurl 7.19.1, donc apres Jaunty
}
}
if (myConnectionParam.bForceIPv4)
curl_easy_setopt (handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); // la resolution d'adresse en ipv6 peut etre tres lente chez certains.
curl_easy_setopt (handle, CURLOPT_TIMEOUT, myConnectionParam.iConnectionMaxTime);
curl_easy_setopt (handle, CURLOPT_CONNECTTIMEOUT, myConnectionParam.iConnectionTimeout);
curl_easy_setopt (handle, CURLOPT_NOSIGNAL, 1); // With CURLOPT_NOSIGNAL set non-zero, curl will not use any signals; sinon curl se vautre apres le timeout, meme si le download s'est bien passe !
curl_easy_setopt (handle, CURLOPT_FOLLOWLOCATION , 1); // follow redirection
curl_easy_setopt (handle, CURLOPT_USERAGENT , "a/5.0 (X11; Linux x86_64; rv:2.0b11) Gecko/20100101 Firefox/4.0b11");
return handle;
}
static size_t _write_data_to_file (gpointer buffer, size_t size, size_t nmemb, FILE *fd)
{
return fwrite (buffer, size, nmemb, fd);
}
gboolean cairo_dock_download_file (const gchar *cURL, const gchar *cLocalPath)
{
g_return_val_if_fail (cLocalPath != NULL && cURL != NULL, FALSE);
// download the file
FILE *f = fopen (cLocalPath, "wb");
g_return_val_if_fail (f, FALSE);
CURL *handle = _init_curl_connection (cURL);
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, _write_data_to_file);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, f);
CURLcode r = curl_easy_perform (handle);
fclose (f);
// check the result
gboolean bOk;
if (r != CURLE_OK) // an error occured
{
cd_warning ("Couldn't download file '%s' (%s)", cURL, curl_easy_strerror (r));
g_remove (cLocalPath);
bOk = FALSE;
}
else // download ok, check the file is not empty.
{
struct stat buf;
stat (cLocalPath, &buf);
if (buf.st_size > 0)
{
bOk = TRUE;
}
else
{
cd_warning ("Empty file from '%s'", cURL);
g_remove (cLocalPath);
bOk = FALSE;
}
}
curl_easy_cleanup (handle);
return bOk;
}
gchar *cairo_dock_download_file_in_tmp (const gchar *cURL)
{
int fds = 0;
gchar *cTmpFilePath = g_strdup ("/tmp/cairo-dock-net-file.XXXXXX");
fds = mkstemp (cTmpFilePath);
if (fds == -1)
{
cd_warning ("Couldn't create temporary file '%s' - check permissions in /tmp", cTmpFilePath);
g_free (cTmpFilePath);
return NULL;
}
gboolean bOk = cairo_dock_download_file (cURL, cTmpFilePath);
if (! bOk)
{
g_remove (cTmpFilePath);
g_free (cTmpFilePath);
cTmpFilePath = NULL;
}
close(fds);
return cTmpFilePath;
}
gchar *cairo_dock_download_archive (const gchar *cURL, const gchar *cExtractTo)
{
g_return_val_if_fail (cURL != NULL, NULL);
// download the archive
gchar *cArchivePath = cairo_dock_download_file_in_tmp (cURL);
// if success, uncompress it.
gchar *cPath = NULL;
if (cArchivePath != NULL)
{
if (cExtractTo != NULL)
{
cd_debug ("uncompressing archive...");
cPath = cairo_dock_uncompress_file (cArchivePath, cExtractTo, cURL);
g_remove (cArchivePath);
}
else
{
cPath = cArchivePath;
cArchivePath = NULL;
}
}
g_free (cArchivePath);
return cPath;
}
static void _dl_file (gpointer *pSharedMemory)
{
if (pSharedMemory[1] != NULL) // download to the given location
{
if (cairo_dock_download_file (pSharedMemory[0], pSharedMemory[1]))
{
pSharedMemory[4] = pSharedMemory[1];
pSharedMemory[1] = NULL;
}
}
else // download in /tmp
{
pSharedMemory[4] = cairo_dock_download_file_in_tmp (pSharedMemory[0]);
}
}
static gboolean _finish_dl (gpointer *pSharedMemory)
{
GFunc pCallback = pSharedMemory[2];
pCallback (pSharedMemory[4], pSharedMemory[3]);
return FALSE;
}
static void _free_dl (gpointer *pSharedMemory)
{
g_free (pSharedMemory[0]);
g_free (pSharedMemory[1]);
g_free (pSharedMemory[4]);
g_free (pSharedMemory);
}
CairoDockTask *cairo_dock_download_file_async (const gchar *cURL, const gchar *cLocalPath, GFunc pCallback, gpointer data)
{
gpointer *pSharedMemory = g_new0 (gpointer, 5);
pSharedMemory[0] = g_strdup (cURL);
pSharedMemory[1] = g_strdup (cLocalPath);
pSharedMemory[2] = pCallback;
pSharedMemory[3] = data;
CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _dl_file, (CairoDockUpdateSyncFunc) _finish_dl, (GFreeFunc) _free_dl, pSharedMemory);
cairo_dock_launch_task (pTask);
return pTask;
}
static size_t _write_data_to_buffer (gpointer data, size_t size, size_t nmemb, GString *buffer)
{
g_string_append_len (buffer, data, size * nmemb);
return size * nmemb;
}
gchar *cairo_dock_get_url_data_with_post (const gchar *cURL, gboolean bGetOutputHeaders, GError **erreur, const gchar *cFirstProperty, ...)
{
//\_______________ On lance le download.
cd_debug ("getting data from '%s' ...", cURL);
CURL *handle = _init_curl_connection (cURL);
GString *sPostData = NULL;
if (cFirstProperty != NULL)
{
sPostData = g_string_new ("");
const gchar *cProperty = cFirstProperty;
gchar *cData;
gchar *cEncodedData = NULL;
va_list args;
va_start (args, cFirstProperty);
do
{
cData = va_arg (args, gchar *);
if (!cData)
break;
if (cEncodedData != NULL) // we don't access the pointer, we just want to know if we have already looped once or not.
g_string_append_c (sPostData, '&');
cEncodedData = curl_easy_escape (handle, cData, 0);
g_string_append_printf (sPostData, "%s=%s", cProperty, cEncodedData);
curl_free (cEncodedData);
cProperty = va_arg (args, gchar *);
}
while (cProperty != NULL);
va_end (args);
// g_print ("POST data: '%s'\n", sPostData->str);
curl_easy_setopt (handle, CURLOPT_POST, 1);
curl_easy_setopt (handle, CURLOPT_POSTFIELDS, sPostData->str);
if (bGetOutputHeaders)
curl_easy_setopt (handle, CURLOPT_HEADER, 1);
}
curl_easy_setopt (handle, CURLOPT_WRITEFUNCTION, (curl_write_callback)_write_data_to_buffer);
GString *buffer = g_string_sized_new (1024);
curl_easy_setopt (handle, CURLOPT_WRITEDATA, buffer);
CURLcode r = curl_easy_perform (handle);
if (r != CURLE_OK)
{
g_set_error (erreur, 1, 1, "Couldn't download file '%s' (%s)", cURL, curl_easy_strerror (r));
g_string_free (buffer, TRUE);
buffer = NULL;
}
curl_easy_cleanup (handle);
if (sPostData)
g_string_free (sPostData, TRUE);
//\_______________ On recupere les donnees.
gchar *cContent = NULL;
if (buffer != NULL)
{
cContent = buffer->str;
g_string_free (buffer, FALSE);
}
return cContent;
}
static void _dl_file_content (gpointer *pSharedMemory)
{
GError *erreur = NULL;
pSharedMemory[3] = cairo_dock_get_url_data (pSharedMemory[0], &erreur);
if (erreur != NULL)
{
cd_warning (erreur->message);
g_error_free (erreur);
}
}
static gboolean _finish_dl_content (gpointer *pSharedMemory)
{
GFunc pCallback = pSharedMemory[1];
pCallback (pSharedMemory[3], pSharedMemory[2]);
return TRUE;
}
static void _free_dl_content (gpointer *pSharedMemory)
{
g_free (pSharedMemory[0]);
g_free (pSharedMemory[3]);
g_free (pSharedMemory);
}
CairoDockTask *cairo_dock_get_url_data_async (const gchar *cURL, GFunc pCallback, gpointer data)
{
gpointer *pSharedMemory = g_new0 (gpointer, 6);
pSharedMemory[0] = g_strdup (cURL);
pSharedMemory[1] = pCallback;
pSharedMemory[2] = data;
CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _dl_file_content, (CairoDockUpdateSyncFunc) _finish_dl_content, (GFreeFunc) _free_dl_content, pSharedMemory);
cairo_dock_launch_task (pTask);
return pTask;
}
////////////////////
/// PACKAGES API ///
////////////////////
void cairo_dock_free_package (CairoDockPackage *pPackage)
{
if (pPackage == NULL)
return ;
g_free (pPackage->cPackagePath);
g_free (pPackage->cAuthor);
g_free (pPackage->cHint);
g_free (pPackage->cDisplayedName);
g_free (pPackage);
}
static inline int _get_rating (const gchar *cPackagesDir, const gchar *cPackageName)
{
gchar *cRatingFile = g_strdup_printf ("%s/.rating/%s", cPackagesDir, cPackageName);
int iRating = 0;
gsize length = 0;
gchar *cContent = NULL;
g_file_get_contents (cRatingFile,
&cContent,
&length,
NULL);
if (cContent)
{
iRating = atoi (cContent);
g_free (cContent);
}
g_free (cRatingFile);
return iRating;
}
GHashTable *cairo_dock_list_local_packages (const gchar *cPackagesDir, GHashTable *hProvidedTable, G_GNUC_UNUSED gboolean bUpdatePackageValidity, GError **erreur)
{
cd_debug ("%s (%s)", __func__, cPackagesDir);
GError *tmp_erreur = NULL;
GDir *dir = g_dir_open (cPackagesDir, 0, &tmp_erreur);
if (tmp_erreur != NULL)
{
g_propagate_error (erreur, tmp_erreur);
return hProvidedTable;
}
GHashTable *pPackageTable = (hProvidedTable != NULL ? hProvidedTable : g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cairo_dock_free_package));
CairoDockPackageType iType = (strncmp (cPackagesDir, "/usr", 4) == 0 ?
CAIRO_DOCK_LOCAL_PACKAGE :
CAIRO_DOCK_USER_PACKAGE);
gchar *cPackagePath;
CairoDockPackage *pPackage;
const gchar *cPackageName;
while ((cPackageName = g_dir_read_name (dir)) != NULL)
{
// on ecarte les fichiers caches.
if (*cPackageName == '.')
continue;
// on ecarte les non repertoires.
cPackagePath = g_strdup_printf ("%s/%s", cPackagesDir, cPackageName);
if (! g_file_test (cPackagePath, G_FILE_TEST_IS_DIR))
{
g_free (cPackagePath);
continue;
}
// on insere le package dans la table.
pPackage = g_new0 (CairoDockPackage, 1);
pPackage->cPackagePath = cPackagePath;
pPackage->cDisplayedName = g_strdup (cPackageName);
pPackage->iType = iType;
pPackage->iRating = _get_rating (cPackagesDir, cPackageName);
g_hash_table_insert (pPackageTable, g_strdup (cPackageName), pPackage); // donc ecrase un package installe ayant le meme nom.
}
g_dir_close (dir);
return pPackageTable;
}
static inline int _convert_date (int iDate)
{
int d, m, y;
y = iDate / 10000;
m = (iDate - y*10000) / 100;
d = iDate % 100;
return (d + m*30 + y*365);
}
static void _cairo_dock_parse_package_list (GKeyFile *pKeyFile, const gchar *cServerAdress, const gchar *cDirectory, GHashTable *pPackageTable)
{
// date courante.
time_t epoch = (time_t) time (NULL);
struct tm currentTime;
localtime_r (&epoch, ¤tTime);
int day = currentTime.tm_mday; // dans l'intervalle 1 a 31.
int month = currentTime.tm_mon + 1; // dans l'intervalle 0 a 11.
int year = 1900 + currentTime.tm_year; // tm_year = nombre d'annees écoulees depuis 1900.
int now = day + month * 30 + year * 365;
// liste des packages.
gsize length=0;
gchar **pGroupList = g_key_file_get_groups (pKeyFile, &length);
g_return_if_fail (pGroupList != NULL); // rien a charger dans la table, on quitte.
// on parcourt la liste.
gchar *cPackageName, *cName, *cAuthor;
CairoDockPackage *pPackage;
CairoDockPackageType iType;
double fSize;
int iCreationDate, iLastModifDate, iLocalDate, iSobriety;
int last_modif, creation_date;
gchar *cHint;
guint i;
for (i = 0; i < length; i ++)
{
cPackageName = pGroupList[i];
iCreationDate = g_key_file_get_integer (pKeyFile, cPackageName, "creation", NULL);
iLastModifDate = g_key_file_get_integer (pKeyFile, cPackageName, "last modif", NULL);
iSobriety = g_key_file_get_integer (pKeyFile, cPackageName, "sobriety", NULL);
cHint = g_key_file_get_string (pKeyFile, cPackageName, "hint", NULL);
if (cHint && *cHint == '\0')
{
g_free (cHint);
cHint = NULL;
}
fSize = g_key_file_get_double (pKeyFile, cPackageName, "size", NULL);
cAuthor = g_key_file_get_string (pKeyFile, cPackageName, "author", NULL);
if (cAuthor && *cAuthor == '\0')
{
g_free (cAuthor);
cAuthor = NULL;
}
cName = g_key_file_get_string (pKeyFile, cPackageName, "name", NULL);
if (cName && *cName == '\0')
{
g_free (cName);
cName = NULL;
}
// creation < 30j && pas sur le disque -> new
// sinon last modif < 30j && last use < last modif -> updated
// sinon -> net
// on surcharge les packages locaux en cas de nouvelle version.
CairoDockPackage *pSamePackage = g_hash_table_lookup (pPackageTable, cPackageName);
if (pSamePackage != NULL) // le package existe en local.
{
// on regarde de quand date cette version locale.
gchar *cVersionFile = g_strdup_printf ("%s/last-modif", pSamePackage->cPackagePath);
gsize length = 0;
gchar *cContent = NULL;
g_file_get_contents (cVersionFile,
&cContent,
&length,
NULL);
if (cContent == NULL) // le package n'a pas encore de fichier de date
{
// on ne peut pas savoir quand l'utilisateur a mis a jour le package pour la derniere fois;
// on va supposer que l'on ne met pas a jour ses packages tres regulierement, donc il est probable qu'il l'ait fait il y'a au moins 1 mois.
// de cette facon, les packages mis a jour recemment (il y'a moins d'1 mois) apparaitront "updated".
if (month > 1)
iLocalDate = day + (month - 1) * 1e2 + year * 1e4;
else
iLocalDate = day + 12 * 1e2 + (year - 1) * 1e4;
gchar *cDate = g_strdup_printf ("%d", iLocalDate);
g_file_set_contents (cVersionFile,
cDate,
-1,
NULL);
g_free (cDate);
}
else
iLocalDate = atoi (cContent);
g_free (cContent);
g_free (cVersionFile);
if (iLocalDate < iLastModifDate) // la copie locale est plus ancienne.
{
iType = CAIRO_DOCK_UPDATED_PACKAGE;
}
else // c'est deja la derniere version disponible, on en reste la.
{
pSamePackage->iSobriety = iSobriety; // par contre on en profite pour renseigner la sobriete.
g_free (pSamePackage->cDisplayedName);
pSamePackage->cDisplayedName = (cName ? cName : g_strdup (cPackageName));
pSamePackage->cAuthor = cAuthor; // et l'auteur original.
pSamePackage->cHint = cHint; // et le hint.
g_free (cPackageName);
continue;
}
pPackage = pSamePackage; // we'll update the characteristics of the package with the one from the server.
g_free (pPackage->cPackagePath);
g_free (pPackage->cAuthor);
g_free (pPackage->cHint);
g_free (pPackage->cDisplayedName);
}
else // package encore jamais telecharge.
{
last_modif = _convert_date (iLastModifDate);
creation_date = _convert_date (iCreationDate);
if (now - creation_date < 30) // les packages restent nouveaux pendant 1 mois.
iType = CAIRO_DOCK_NEW_PACKAGE;
else if (now - last_modif < 30) // les packages restent mis a jour pendant 1 mois.
iType = CAIRO_DOCK_UPDATED_PACKAGE;
else
iType = CAIRO_DOCK_DISTANT_PACKAGE;
pPackage = g_new0 (CairoDockPackage, 1);
g_hash_table_insert (pPackageTable, g_strdup (cPackageName), pPackage);
pPackage->iRating = g_key_file_get_integer (pKeyFile, cPackageName, "rating", NULL); // par contre on affiche la note que l'utilisateur avait precedemment etablie.
}
pPackage->cPackagePath = g_strdup_printf ("%s/%s/%s", cServerAdress, cDirectory, cPackageName);
pPackage->iType = iType;
pPackage->fSize = fSize;
pPackage->cAuthor = cAuthor;
pPackage->cDisplayedName = (cName ? cName : g_strdup (cPackageName));
pPackage->iSobriety = iSobriety;
pPackage->cHint = cHint;
pPackage->iCreationDate = iCreationDate;
pPackage->iLastModifDate = iLastModifDate;
g_free (cPackageName);
}
g_free (pGroupList); // les noms des packages sont liberes dans la boucle.
}
GHashTable *cairo_dock_list_net_packages (const gchar *cServerAdress, const gchar *cDirectory, const gchar *cListFileName, GHashTable *hProvidedTable, GError **erreur)
{
g_return_val_if_fail (cServerAdress != NULL && *cServerAdress != '\0', hProvidedTable);
cd_message ("listing net packages on %s/%s ...", cServerAdress, cDirectory);
// On recupere la liste des packages distants.
GError *tmp_erreur = NULL;
gchar *cURL = g_strdup_printf ("%s/%s/%s", cServerAdress, cDirectory, cListFileName);
gchar *cContent = cairo_dock_get_url_data (cURL, &tmp_erreur);
g_free (cURL);
if (tmp_erreur != NULL)
{
cd_warning ("couldn't retrieve packages on %s (check that your connection is alive, or retry later)", cServerAdress);
g_propagate_error (erreur, tmp_erreur);
return hProvidedTable;
}
// on verifie son integrite.
if (cContent == NULL || strncmp (cContent, "#!CD", 4) != 0) // avec une connexion wifi etablie sur un operateur auquel on ne s'est pas logue, il peut nous renvoyer des messages au lieu de juste rien. On filtre ca par un entete dedie.
{
cd_warning ("empty packages list on %s (check that your connection is alive, or retry later)", cServerAdress);
g_set_error (erreur, 1, 1, "empty packages list on %s", cServerAdress);
g_free (cContent);
return hProvidedTable;
}
// on charge la liste dans un fichier de cles.
GKeyFile *pKeyFile = g_key_file_new ();
g_key_file_load_from_data (pKeyFile,
cContent,
-1,
G_KEY_FILE_NONE,
&tmp_erreur);
g_free (cContent);
if (tmp_erreur != NULL)
{
cd_warning ("invalid list of packages (%s)\n(check that your connection is alive, or retry later)", cServerAdress);
g_propagate_error (erreur, tmp_erreur);
g_key_file_free (pKeyFile);
return hProvidedTable;
}
// on parse la liste dans une table de hashage.
GHashTable *pPackageTable = (hProvidedTable != NULL ? hProvidedTable : g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cairo_dock_free_package));
_cairo_dock_parse_package_list (pKeyFile, cServerAdress, cDirectory, pPackageTable);
g_key_file_free (pKeyFile);
return pPackageTable;
}
GHashTable *cairo_dock_list_packages (const gchar *cSharePackagesDir, const gchar *cUserPackagesDir, const gchar *cDistantPackagesDir, GHashTable *pTable)
{
cd_message ("%s (%s, %s, %s)", __func__, cSharePackagesDir, cUserPackagesDir, cDistantPackagesDir);
GError *erreur = NULL;
GHashTable *pPackageTable = (pTable ? pTable : g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cairo_dock_free_package));
//\______________ On recupere les packages pre-installes.
if (cSharePackagesDir != NULL)
pPackageTable = cairo_dock_list_local_packages (cSharePackagesDir, pPackageTable, cDistantPackagesDir != NULL, &erreur);
if (erreur != NULL)
{
cd_warning ("while listing pre-installed packages in '%s' : %s", cSharePackagesDir, erreur->message);
g_error_free (erreur);
erreur = NULL;
}
//\______________ On recupere les packages utilisateurs (qui ecrasent donc les precedents).
if (cUserPackagesDir != NULL)
pPackageTable = cairo_dock_list_local_packages (cUserPackagesDir, pPackageTable, cDistantPackagesDir != NULL, &erreur);
if (erreur != NULL)
{
cd_warning ("while listing user packages in '%s' : %s", cUserPackagesDir, erreur->message);
g_error_free (erreur);
erreur = NULL;
}
//\______________ On recupere les packages distants (qui surchargent tous les packages).
if (cDistantPackagesDir != NULL && s_cPackageServerAdress)
{
pPackageTable = cairo_dock_list_net_packages (s_cPackageServerAdress, cDistantPackagesDir, CAIRO_DOCK_DEFAULT_PACKAGES_LIST_FILE, pPackageTable, &erreur);
if (erreur != NULL)
{
cd_warning ("while listing distant packages in '%s/%s' : %s", s_cPackageServerAdress, cDistantPackagesDir, erreur->message);
g_error_free (erreur);
erreur = NULL;
}
}
return pPackageTable;
}
static void _list_packages (gpointer *pSharedMemory)
{
pSharedMemory[5] = cairo_dock_list_packages (pSharedMemory[0], pSharedMemory[1], pSharedMemory[2], pSharedMemory[5]);
}
static gboolean _finish_list_packages (gpointer *pSharedMemory)
{
if (pSharedMemory[5] == NULL)
cd_warning ("couldn't get distant packages in '%s'", pSharedMemory[2]);
GFunc pCallback = pSharedMemory[3];
pCallback (pSharedMemory[5], pSharedMemory[4]);
return TRUE;
}
static void _discard_list_packages (gpointer *pSharedMemory)
{
g_free (pSharedMemory[0]);
g_free (pSharedMemory[1]);
g_free (pSharedMemory[2]);
if (pSharedMemory[5] != NULL)
g_hash_table_unref (pSharedMemory[5]);
g_free (pSharedMemory);
}
CairoDockTask *cairo_dock_list_packages_async (const gchar *cSharePackagesDir, const gchar *cUserPackagesDir, const gchar *cDistantPackagesDir, CairoDockGetPackagesFunc pCallback, gpointer data, GHashTable *pTable)
{
gpointer *pSharedMemory = g_new0 (gpointer, 6);
pSharedMemory[0] = g_strdup (cSharePackagesDir);
pSharedMemory[1] = g_strdup (cUserPackagesDir);
pSharedMemory[2] = g_strdup (cDistantPackagesDir);
pSharedMemory[3] = pCallback;
pSharedMemory[4] = data;
pSharedMemory[5] = pTable; // can be NULL
CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _list_packages, (CairoDockUpdateSyncFunc) _finish_list_packages, (GFreeFunc) _discard_list_packages, pSharedMemory);
cairo_dock_launch_task (pTask);
return pTask;
}
gchar *cairo_dock_get_package_path (const gchar *cPackageName, const gchar *cSharePackagesDir, const gchar *cUserPackagesDir, const gchar *cDistantPackagesDir, CairoDockPackageType iGivenType)
{
cd_message ("%s (%s, %s, %s)", __func__, cSharePackagesDir, cUserPackagesDir, cDistantPackagesDir);
if (cPackageName == NULL || *cPackageName == '\0')
return NULL;
CairoDockPackageType iType = cairo_dock_extract_package_type_from_name (cPackageName); // juste au cas ou, mais normalement c'est plutot a l'appelant d'extraire le type de theme.
if (iType == CAIRO_DOCK_ANY_PACKAGE)
iType = iGivenType;
gchar *cPackagePath = NULL;
//g_print ("iType : %d\n", iType);
if (cUserPackagesDir != NULL && iType != CAIRO_DOCK_UPDATED_PACKAGE)
{
cPackagePath = g_strdup_printf ("%s/%s", cUserPackagesDir, cPackageName);
if (g_file_test (cPackagePath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
{
return cPackagePath;
}
g_free (cPackagePath);
cPackagePath = NULL;
}
if (cSharePackagesDir != NULL && iType != CAIRO_DOCK_UPDATED_PACKAGE)
{
cPackagePath = g_strdup_printf ("%s/%s", cSharePackagesDir, cPackageName);
if (g_file_test (cPackagePath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
return cPackagePath;
g_free (cPackagePath);
cPackagePath = NULL;
}
if (cDistantPackagesDir != NULL && s_cPackageServerAdress)
{
gchar *cDistantFileName = g_strdup_printf ("%s/%s/%s/%s.tar.gz", s_cPackageServerAdress, cDistantPackagesDir, cPackageName, cPackageName);
cPackagePath = cairo_dock_download_archive (cDistantFileName, cUserPackagesDir);
g_free (cDistantFileName);
if (cPackagePath != NULL) // on se souvient de la date a laquelle on a mis a jour le package pour la derniere fois.
{
gchar *cVersionFile = g_strdup_printf ("%s/last-modif", cPackagePath);
time_t epoch = (time_t) time (NULL);
struct tm currentTime;
localtime_r (&epoch, ¤tTime);
int now = (currentTime.tm_mday+1) + (currentTime.tm_mon+1) * 1e2 + (1900+currentTime.tm_year) * 1e4;
gchar *cDate = g_strdup_printf ("%d", now);
g_file_set_contents (cVersionFile,
cDate,
-1,
NULL);
g_free (cDate);
g_free (cVersionFile);
}
}
cd_debug (" ====> cPackagePath : %s", cPackagePath);
return cPackagePath;
}
CairoDockPackageType cairo_dock_extract_package_type_from_name (const gchar *cPackageName)
{
if (cPackageName == NULL)
return CAIRO_DOCK_ANY_PACKAGE;
CairoDockPackageType iType = CAIRO_DOCK_ANY_PACKAGE;
int l = strlen (cPackageName);
if (cPackageName[l-1] == ']')
{
gchar *str = strrchr (cPackageName, '[');
if (str != NULL && g_ascii_isdigit (*(str+1)))
{
iType = atoi (str+1);
*str = '\0';
}
}
return iType;
}
void cairo_dock_set_packages_server (gchar *cPackageServerAdress)
{
s_cPackageServerAdress = cPackageServerAdress;
}
//////////////////
/// GET CONFIG ///
//////////////////
static gboolean get_config (GKeyFile *pKeyFile, CairoConnectionParam *pSystem)
{
gboolean bFlushConfFileNeeded = FALSE;
pSystem->iConnectionTimeout = cairo_dock_get_integer_key_value (pKeyFile, "System", "conn timeout", &bFlushConfFileNeeded, 7, NULL, NULL);
pSystem->iConnectionMaxTime = cairo_dock_get_integer_key_value (pKeyFile, "System", "conn max time", &bFlushConfFileNeeded, 120, NULL, NULL);
if (cairo_dock_get_boolean_key_value (pKeyFile, "System", "conn use proxy", &bFlushConfFileNeeded, FALSE, NULL, NULL))
{
pSystem->cConnectionProxy = cairo_dock_get_string_key_value (pKeyFile, "System", "conn proxy", &bFlushConfFileNeeded, NULL, NULL, NULL);
pSystem->iConnectionPort = cairo_dock_get_integer_key_value (pKeyFile, "System", "conn port", &bFlushConfFileNeeded, 0, NULL, NULL);
pSystem->cConnectionUser = cairo_dock_get_string_key_value (pKeyFile, "System", "conn user", &bFlushConfFileNeeded, NULL, NULL, NULL);
gchar *cPasswd = cairo_dock_get_string_key_value (pKeyFile, "System", "conn passwd", &bFlushConfFileNeeded, NULL, NULL, NULL);
cairo_dock_decrypt_string (cPasswd, &pSystem->cConnectionPasswd);
pSystem->bForceIPv4 = cairo_dock_get_boolean_key_value (pKeyFile, "System", "force ipv4", &bFlushConfFileNeeded, TRUE, NULL, NULL);
}
return bFlushConfFileNeeded;
}
////////////////////
/// RESET CONFIG ///
////////////////////
static void reset_config (CairoConnectionParam *pSystem)
{
g_free (pSystem->cConnectionProxy);
g_free (pSystem->cConnectionUser);
g_free (pSystem->cConnectionPasswd);
}
////////////
/// INIT ///
////////////
static void init (void)
{
curl_global_init (CURL_GLOBAL_DEFAULT);
}
///////////////
/// MANAGER ///
///////////////
void gldi_register_connection_manager (void)
{
// Manager
memset (&myConnectionMgr, 0, sizeof (GldiManager));
gldi_object_init (GLDI_OBJECT(&myConnectionMgr), &myManagerObjectMgr, NULL);
myConnectionMgr.cModuleName = "Connection";
// interface
myConnectionMgr.init = init;
myConnectionMgr.load = NULL;
myConnectionMgr.unload = NULL;
myConnectionMgr.reload = (GldiManagerReloadFunc)NULL;
myConnectionMgr.get_config = (GldiManagerGetConfigFunc)get_config;
myConnectionMgr.reset_config = (GldiManagerResetConfigFunc)reset_config;
// Config
myConnectionMgr.pConfig = (GldiManagerConfigPtr)&myConnectionParam;
myConnectionMgr.iSizeOfConfig = sizeof (CairoConnectionParam);
// data
myConnectionMgr.pData = (GldiManagerDataPtr)NULL;
myConnectionMgr.iSizeOfData = 0;
// signals
gldi_object_install_notifications (&myConnectionMgr, NB_NOTIFICATIONS_CONNECTION); // we don't have a Connection Object, so let's put the signals here
}
cairo-dock-3.3.2/src/gldit/cairo-dock.h 000664 001750 001750 00000007065 12223247550 020760 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_H__
#define __CAIRO_DOCK_H__
#include
#include
#include
#include
#include
#include
#include
#include
// Containers
#include
#include
#include
#include
#include
#include
#include
#include
#include
// Icons
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// managers.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// drawing
#include
#include
#include
#include
#include
#include
#include
#include
// GUI
#include
#include
// used by applets
#include
#include
#include
#include
#include
// base classes
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-data-renderer-manager.c 000664 001750 001750 00000016303 12223247550 025071 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#include
#include
#include
#include "gldi-config.h"
#include "cairo-dock-log.h"
#include "cairo-dock-config.h" // cairo_dock_get_string_key_value
#include "cairo-dock-keyfile-utilities.h" // cairo_dock_write_keys_to_file
#include "cairo-dock-opengl-font.h"
#define _MANAGER_DEF_
#include "cairo-dock-data-renderer-manager.h"
// public (manager, config, data)
GldiManager myDataRenderersMgr;
GldiObjectManager myDataRendererObjectMgr;
// dependancies
extern gboolean g_bUseOpenGL;
extern gchar *g_cExtrasDirPath;
// private
static GHashTable *s_hDataRendererTable = NULL; // table des rendus de donnees disponibles.
static CairoDockGLFont *s_pFont = NULL;
////////////
/// FONT ///
////////////
#define _init_data_renderer_font(...) s_pFont = cairo_dock_load_textured_font ("Monospace Bold 12", 0, 184) // on va jusqu'a ø
CairoDockGLFont *cairo_dock_get_default_data_renderer_font (void)
{
if (s_pFont == NULL)
_init_data_renderer_font ();
return s_pFont;
}
void cairo_dock_unload_default_data_renderer_font (void)
{
cairo_dock_free_gl_font (s_pFont);
s_pFont = NULL;
}
/////////////////////////
/// LIST OF RENDERERS ///
/////////////////////////
CairoDockDataRendererRecord *cairo_dock_get_data_renderer_record (const gchar *cRendererName)
{
if (cRendererName != NULL)
return g_hash_table_lookup (s_hDataRendererTable, cRendererName);
else
return NULL;
}
void cairo_dock_register_data_renderer (const gchar *cRendererName, CairoDockDataRendererRecord *pRecord)
{
cd_message ("%s (%s)", __func__, cRendererName);
g_hash_table_insert (s_hDataRendererTable, g_strdup (cRendererName), pRecord);
}
void cairo_dock_remove_data_renderer (const gchar *cRendererName)
{
g_hash_table_remove (s_hDataRendererTable, cRendererName);
}
CairoDataRenderer *cairo_dock_new_data_renderer (const gchar *cRendererName)
{
CairoDockDataRendererRecord *pRecord = cairo_dock_get_data_renderer_record (cRendererName);
g_return_val_if_fail (pRecord != NULL && pRecord->iStructSize != 0, NULL);
if (g_bUseOpenGL && s_pFont == NULL)
{
_init_data_renderer_font ();
}
CairoDataRenderer *pRenderer = g_malloc0 (pRecord->iStructSize);
memcpy (&pRenderer->interface, &pRecord->interface, sizeof (CairoDataRendererInterface));
pRenderer->bUseOverlay = pRecord->bUseOverlay;
return pRenderer;
}
//////////////////////
/// LIST OF THEMES ///
//////////////////////
GHashTable *cairo_dock_list_available_themes_for_data_renderer (const gchar *cRendererName)
{
CairoDockDataRendererRecord *pRecord = cairo_dock_get_data_renderer_record (cRendererName);
g_return_val_if_fail (pRecord != NULL, NULL);
if (pRecord->cThemeDirName == NULL && pRecord->cDistantThemeDirName == NULL)
return NULL;
gchar *cGaugeShareDir = g_strdup_printf ("%s/%s", GLDI_SHARE_DATA_DIR, pRecord->cThemeDirName);
gchar *cGaugeUserDir = g_strdup_printf ("%s/%s", g_cExtrasDirPath, pRecord->cThemeDirName);
GHashTable *pGaugeTable = cairo_dock_list_packages (cGaugeShareDir, cGaugeUserDir, pRecord->cDistantThemeDirName, NULL);
g_free (cGaugeShareDir);
g_free (cGaugeUserDir);
return pGaugeTable;
}
gchar *cairo_dock_get_data_renderer_theme_path (const gchar *cRendererName, const gchar *cThemeName, CairoDockPackageType iType) // utile pour DBus aussi.
{
CairoDockDataRendererRecord *pRecord = cairo_dock_get_data_renderer_record (cRendererName);
g_return_val_if_fail (pRecord != NULL, NULL);
if (pRecord->cThemeDirName == NULL && pRecord->cDistantThemeDirName == NULL)
return NULL;
const gchar *cGaugeShareDir = g_strdup_printf (GLDI_SHARE_DATA_DIR"/%s", pRecord->cThemeDirName);
gchar *cGaugeUserDir = g_strdup_printf ("%s/%s", g_cExtrasDirPath, pRecord->cThemeDirName);
gchar *cThemePath = cairo_dock_get_package_path (cThemeName, cGaugeShareDir, cGaugeUserDir, pRecord->cDistantThemeDirName, iType);
g_free (cGaugeUserDir);
return cThemePath;
}
gchar *cairo_dock_get_package_path_for_data_renderer (const gchar *cRendererName, const gchar *cAppletConfFilePath, GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, const gchar *cDefaultThemeName)
{
CairoDockDataRendererRecord *pRecord = cairo_dock_get_data_renderer_record (cRendererName);
g_return_val_if_fail (pRecord != NULL, NULL);
gchar *cChosenThemeName = cairo_dock_get_string_key_value (pKeyFile, cGroupName, cKeyName, bFlushConfFileNeeded, cDefaultThemeName, NULL, NULL);
if (cChosenThemeName == NULL)
cChosenThemeName = g_strdup (pRecord->cDefaultTheme);
CairoDockPackageType iType = cairo_dock_extract_package_type_from_name (cChosenThemeName);
gchar *cThemePath = cairo_dock_get_data_renderer_theme_path (cRendererName, cChosenThemeName, iType);
if (cThemePath == NULL) // theme introuvable.
cThemePath = g_strdup_printf (GLDI_SHARE_DATA_DIR"/%s/%s", pRecord->cThemeDirName, pRecord->cDefaultTheme);
if (iType != CAIRO_DOCK_ANY_PACKAGE)
{
g_key_file_set_string (pKeyFile, cGroupName, cKeyName, cChosenThemeName);
cairo_dock_write_keys_to_file (pKeyFile, cAppletConfFilePath);
}
cd_debug ("DataRenderer's theme : %s", cThemePath);
g_free (cChosenThemeName);
return cThemePath;
}
//////////////
/// UNLOAD ///
//////////////
static void unload (void)
{
cairo_dock_free_gl_font (s_pFont);
s_pFont = NULL;
}
////////////
/// INIT ///
////////////
static void init (void)
{
s_hDataRendererTable = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_free);
}
///////////////
/// MANAGER ///
///////////////
void gldi_register_data_renderers_manager (void)
{
// Manager
memset (&myDataRenderersMgr, 0, sizeof (GldiManager));
gldi_object_init (GLDI_OBJECT(&myDataRenderersMgr), &myManagerObjectMgr, NULL);
myDataRenderersMgr.cModuleName = "Data-Renderers";
// interface
myDataRenderersMgr.init = init;
myDataRenderersMgr.load = NULL; // loaded on demand
myDataRenderersMgr.unload = unload;
myDataRenderersMgr.reload = (GldiManagerReloadFunc)NULL;
myDataRenderersMgr.get_config = (GldiManagerGetConfigFunc)NULL;
myDataRenderersMgr.reset_config = (GldiManagerResetConfigFunc)NULL;
// Config
myDataRenderersMgr.pConfig = (GldiManagerConfigPtr)NULL;
myDataRenderersMgr.iSizeOfConfig = 0;
// data
myDataRenderersMgr.pData = (GldiManagerDataPtr)NULL;
myDataRenderersMgr.iSizeOfData = 0;
// Object Manager
memset (&myDataRendererObjectMgr, 0, sizeof (GldiObjectManager));
myDataRendererObjectMgr.cName = "Data-Renderers";
// signals
gldi_object_install_notifications (&myDataRendererObjectMgr, NB_NOTIFICATIONS_DATA_RENDERERS);
}
cairo-dock-3.3.2/src/gldit/cairo-dock-log.h 000664 001750 001750 00000006654 12223247550 021542 0 ustar 00mbaerts mbaerts 000000 000000 /*
* cairo-dock-log.h
* This file is a part of the Cairo-Dock project
* Login :
* Started on Sat Feb 9 16:11:48 2008 Cedric GESTES
* $Id$
*
* Author(s)
* - Cedric GESTES
*
* Copyright : (C) 2008 Cedric GESTES
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef CAIRO_DOCK_LOG_H_
# define CAIRO_DOCK_LOG_H_
# include
G_BEGIN_DECLS
/*
* internal function
*/
void cd_log_location(const GLogLevelFlags loglevel,
const char *file,
const char *func,
const int line,
const char *format,
...);
/**
* Initialize the log system.
*/
void cd_log_init(gboolean bBlackTerminal);
/**
* Set the verbosity level.
*/
void cd_log_set_level(GLogLevelFlags loglevel);
/**
* Set the verbosity level from a readable verbosity.
*/
void cd_log_set_level_from_name (const gchar *cVerbosity);
/**
* Force the use of colors in the log messages even if these messages are not displayed into a tty.
*/
void cd_log_force_use_color (void);
/* Write an error message on the terminal. Error messages are used to indicate the cause of the program stop.
*@param ... the message format and parameters, in a 'printf' style.
*/
#define cd_error(...) \
cd_log_location(G_LOG_LEVEL_ERROR, __FILE__, __PRETTY_FUNCTION__, __LINE__,__VA_ARGS__)
/* Write a critical message on the terminal. Critical messages should be as clear as possible to be useful for end-users.
*@param ... the message format and parameters, in a 'printf' style.
*/
#define cd_critical(...) \
cd_log_location(G_LOG_LEVEL_CRITICAL, __FILE__, __PRETTY_FUNCTION__, __LINE__,__VA_ARGS__)
/* Write a warning message on the terminal. Warnings should be as clear as possible to be useful for end-users.
*@param ... the message format and parameters, in a 'printf' style.
*/
#define cd_warning(...) \
cd_log_location(G_LOG_LEVEL_WARNING, __FILE__, __PRETTY_FUNCTION__, __LINE__,__VA_ARGS__)
/* Write a message on the terminal. Messages are used to trace the sequence of functions, and may be used by users for a quick debug.
*@param ... the message format and parameters, in a 'printf' style.
*/
#define cd_message(...) \
cd_log_location(G_LOG_LEVEL_MESSAGE, __FILE__, __PRETTY_FUNCTION__, __LINE__,__VA_ARGS__)
/* Write a debug message on the terminal. Debug message are only useful for developpers.
*@param ... the message format and parameters, in a 'printf' style.
*/
#define cd_debug(...) \
cd_log_location(G_LOG_LEVEL_DEBUG, __FILE__, __PRETTY_FUNCTION__, __LINE__,__VA_ARGS__)
G_END_DECLS
#endif /* !CAIRO_DOCK_LOG_H_ */
cairo-dock-3.3.2/src/gldit/cairo-dock-image-buffer.h 000664 001750 001750 00000021363 12223247550 023304 0 ustar 00mbaerts mbaerts 000000 000000 /*
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see .
*/
#ifndef __CAIRO_DOCK_IMAGE_BUFFER__
#define __CAIRO_DOCK_IMAGE_BUFFER__
#include
#include
#include "cairo-dock-struct.h"
#include "cairo-dock-surface-factory.h" // CairoDockLoadImageModifier
G_BEGIN_DECLS
/**
*@file cairo-dock-image-buffer.h This class defines a generic image API that works for both Cairo and OpenGL.
* It allows to easily load and display images, without having to care the rendering mode.
* It supports animated images (an animated image is made of several frames, ordered side by side from left to right).
*
* Use \ref cairo_dock_create_image_buffer to create an image buffer from a file, or \ref cairo_dock_load_image_buffer to load an image into an existing image buffer.
* Use \ref cairo_dock_free_image_buffer to destroy it or \ref cairo_dock_unload_image_buffer to unload and reset it to 0.
*
* Use \ref cairo_dock_apply_image_buffer_surface or \ref cairo_dock_apply_image_buffer_texture to display the image.
*/
/// Definition of an Image Buffer. It provides an unified interface for a cairo/opengl image buffer.
struct _CairoDockImageBuffer {
cairo_surface_t *pSurface;
GLuint iTexture;
gint iWidth;
gint iHeight;
gdouble fZoomX;
gdouble fZoomY;
gint iNbFrames; // nb frames in the case of an animated image.
gdouble iCurrentFrame; // current frame, the decimal part indicates we are between 2 frames.
gdouble fDeltaFrame; // duration of 1 frame
struct timeval time; // time the current frame has been set
} ;
/** Find the path of an image. '~' is handled, as well as the 'images' folder of the current theme. Use \ref cairo_dock_search_icon_s_path to search theme icons.
*@param cImageFile a file name or path. If it's already a path, it will just be duplicated.
*@return the path of the file, or NULL if it has not been found.
*/
gchar *cairo_dock_search_image_s_path (const gchar *cImageFile);
#define cairo_dock_generate_file_path cairo_dock_search_image_s_path
/** Load an image into an ImageBuffer with a given transparency. If the image is given by its sole name, it is taken in the root folder of the current theme.
*@param pImage an ImageBuffer.
*@param cImageFile name of a file
*@param iWidth width it should be loaded.
*@param iHeight height it should be loaded.
*@param iLoadModifier modifier
*@param fAlpha transparency (1:fully opaque)
*/
void cairo_dock_load_image_buffer_full (CairoDockImageBuffer *pImage, const gchar *cImageFile, int iWidth, int iHeight, CairoDockLoadImageModifier iLoadModifier, double fAlpha);
/** \fn cairo_dock_load_image_buffer(pImage, cImageFile, iWidth, iHeight, iLoadModifier)
* Load an image into an ImageBuffer. If the image is given by its sole name, it is taken in the root folder of the current theme.
*@param pImage an ImageBuffer.
*@param cImageFile name of a file
*@param iWidth width it should be loaded. The resulting width can be different depending on the modifier.
*@param iHeight height it should be loaded. The resulting width can be different depending on the modifier.
*@param iLoadModifier modifier
*/
#define cairo_dock_load_image_buffer(pImage, cImageFile, iWidth, iHeight, iLoadModifier) cairo_dock_load_image_buffer_full (pImage, cImageFile, iWidth, iHeight, iLoadModifier, 1.)
/** Load a surface into an ImageBuffer.
*@param pImage an ImageBuffer.
*@param pSurface a cairo surface
*@param iWidth width of the surface
*@param iHeight height of the surface
*/
void cairo_dock_load_image_buffer_from_surface (CairoDockImageBuffer *pImage, cairo_surface_t *pSurface, int iWidth, int iHeight);
void cairo_dock_load_image_buffer_from_texture (CairoDockImageBuffer *pImage, GLuint iTexture, int iWidth, int iHeight);
/** Create and load an image into an ImageBuffer. If the image is given by its sole name, it is taken in the root folder of the current theme.
*@param cImageFile name of a file
*@param iWidth width it should be loaded.
*@param iHeight height it should be loaded.
*@param iLoadModifier modifier
*@return a newly allocated ImageBuffer.
*/
CairoDockImageBuffer *cairo_dock_create_image_buffer (const gchar *cImageFile, int iWidth, int iHeight, CairoDockLoadImageModifier iLoadModifier);
#define cairo_dock_image_buffer_is_animated(pImage) ((pImage) && (pImage)->iNbFrames > 0)
void cairo_dock_image_buffer_next_frame (CairoDockImageBuffer *pImage);
gboolean cairo_dock_image_buffer_next_frame_no_loop (CairoDockImageBuffer *pImage);
#define cairo_dock_image_buffer_set_timelength(pImage, fTimeLength) (pImage)->fDeltaFrame = ((pImage)->iNbFrames != 0 ? (double)fTimeLength / (pImage)->iNbFrames : 1)
#define cairo_dock_image_buffer_rewind(pImage) gettimeofday (&pImage->time, NULL)
/** Reset an ImageBuffer's ressources. It can be used to load another image then.
*@param pImage an ImageBuffer.
*/
void cairo_dock_unload_image_buffer (CairoDockImageBuffer *pImage);
/** Reset and free an ImageBuffer.
*@param pImage an ImageBuffer.
*/
void cairo_dock_free_image_buffer (CairoDockImageBuffer *pImage);
/** Draw an ImageBuffer with an offset on a Cairo context, at the size it was loaded.
*@param pImage an ImageBuffer.
*@param pCairoContext the current cairo context.
*@param x horizontal offset.
*@param y vertical offset.
*@param fAlpha transparency (in [0;1])
*/
void cairo_dock_apply_image_buffer_surface_with_offset (const CairoDockImageBuffer *pImage, cairo_t *pCairoContext, double x, double y, double fAlpha);
/** Draw an ImageBuffer on a cairo context.
*@param pImage an ImageBuffer.
*@param pCairoContext the current cairo context.
*/
#define cairo_dock_apply_image_buffer_surface(pImage, pCairoContext) cairo_dock_apply_image_buffer_surface_with_offset (pImage, pCairoContext, 0., 0., 1.)
/** Draw an ImageBuffer with an offset on the current OpenGL context, at the size it was loaded.
*@param pImage an ImageBuffer.
*@param x horizontal offset.
*@param y vertical offset.
*/
void cairo_dock_apply_image_buffer_texture_with_offset (const CairoDockImageBuffer *pImage, double x, double y);
/** Draw an ImageBuffer on the current OpenGL context.
*@param pImage an ImageBuffer.
*/
#define cairo_dock_apply_image_buffer_texture(pImage) cairo_dock_apply_image_buffer_texture_with_offset (pImage, 0., 0.)
/** Draw an ImageBuffer with an offset on a Cairo context, at a given size.
*@param pImage an ImageBuffer.
*@param pCairoContext the current cairo context.
*@param w requested width
*@param h requested height
*@param x horizontal offset.
*@param y vertical offset.
*@param fAlpha transparency (in [0;1])
*/
void cairo_dock_apply_image_buffer_surface_at_size (const CairoDockImageBuffer *pImage, cairo_t *pCairoContext, int w, int h, double x, double y, double fAlpha);
/** Draw an ImageBuffer on the current OpenGL context at a given size.
*@param pImage an ImageBuffer.
*@param w requested width
*@param h requested height
*@param x horizontal offset.
*@param y vertical offset.
*/
void cairo_dock_apply_image_buffer_texture_at_size (const CairoDockImageBuffer *pImage, int w, int h, double x, double y);
void cairo_dock_apply_image_buffer_surface_with_offset_and_limit (const CairoDockImageBuffer *pImage, cairo_t *pCairoContext, double x, double y, double fAlpha, int iMaxWidth);
void cairo_dock_apply_image_buffer_texture_with_limit (const CairoDockImageBuffer *pImage, double fAlpha, int iMaxWidth);
///////////////////////
// RENDER TO TEXTURE //
///////////////////////
/** Create an FBO to render the icons inside a dock.
*/
void cairo_dock_create_icon_fbo (void);
/** Destroy the icons FBO.
*/
void cairo_dock_destroy_icon_fbo (void);
cairo_t *cairo_dock_begin_draw_image_buffer_cairo (CairoDockImageBuffer *pImage, gint iRenderingMode, cairo_t *pCairoContext);
void cairo_dock_end_draw_image_buffer_cairo (CairoDockImageBuffer *pImage);
gboolean cairo_dock_begin_draw_image_buffer_opengl (CairoDockImageBuffer *pImage, GldiContainer *pContainer, gint iRenderingMode);
void cairo_dock_end_draw_image_buffer_opengl (CairoDockImageBuffer *pImage, GldiContainer *pContainer);
void cairo_dock_image_buffer_update_texture (CairoDockImageBuffer *pImage);
GdkPixbuf *cairo_dock_image_buffer_to_pixbuf (CairoDockImageBuffer *pImage, int iWidth, int iHeight);
G_END_DECLS
#endif
cairo-dock-3.3.2/src/gldit/cairo-dock-menu.c 000664 001750 001750 00000023274 12233703616 021716 0 ustar 00mbaerts mbaerts 000000 000000 /**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* 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 3
* 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, see