cairo-dock-plugins-3.3.2/alsaMixer/src/applet-struct.h000775 001750 001750 00000006257 12225027055 024060 0ustar00mbaertsmbaerts000000 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 __CD_APPLET_STRUCT__ #define __CD_APPLET_STRUCT__ #include #include #define _STRUCT_TIMEVAL #include #ifdef INDICATOR_SOUNDMENU_WITH_IND3 #include "indicator-applet3.h" #elif defined SOUND_SERVICE_SUPPORT // OLD #include "indicator-applet.h" #include "mute-widget.h" #endif // Info display types typedef enum { VOLUME_NO_DISPLAY = 0, VOLUME_ON_LABEL, VOLUME_ON_ICON, VOLUME_NB_DISPLAYS } VolumeTypeDisplay; // Icon display types typedef enum { VOLUME_EFFECT_NONE = 0, VOLUME_EFFECT_BAR, VOLUME_EFFECT_GAUGE, VOLUME_NB_EFFECTS } VolumeTypeEffect; struct _AppletConfig { // alsa options gchar *card_id; gchar *cMixerElementName; gchar *cMixerElementName2; gchar *cShowAdvancedMixerCommand; // display VolumeTypeDisplay iVolumeDisplay; VolumeTypeEffect iVolumeEffect; gchar *cDefaultIcon; gchar *cBrokenIcon; gchar *cMuteIcon; gchar *cGThemePath; RendererRotateTheme iRotateTheme; // accesibility gchar *cShortcut; gint iScrollVariation; gboolean bHideScaleOnLeave; #ifdef INDICATOR_SOUNDMENU_WITH_IND3 gchar *cIndicatorName; #endif } ; // Interface of a Sound Controler typedef struct { int (*get_volume) (void); void (*set_volume) (int iVolume); void (*toggle_mute) (void); void (*show_hide) (void); void (*stop) (void); void (*reload) (void); } CDSoundCtl; struct _AppletData { // generic interface CDSoundCtl ctl; // alsa data snd_mixer_t *mixer_handle; gchar *mixer_card_name; gchar *mixer_device_name; gchar *cErrorMessage; snd_mixer_elem_t *pControledElement; snd_mixer_elem_t *pControledElement2; // des fois un element ne controle qu'une sortie (droite ou gauche). snd_mixer_selem_id_t *pControledID; gboolean bHasMuteSwitch; long iVolumeMin, iVolumeMax; // volumes min et max en unites de la carte son. guint iSidCheckVolume; CairoDialog *pDialog; int iCurrentVolume; // current volume in [0-100] // sound service data #ifdef INDICATOR_SOUNDMENU_WITH_IND3 IndicatorObject *pIndicator; IndicatorObjectEntry *pEntry; #elif defined SOUND_SERVICE_SUPPORT // OLD CDAppletIndicator *pIndicator; GtkWidget* volume_widget; GList *transport_widgets_list; GtkWidget* voip_widget; MuteWidget* mute_widget; gint iCurrentState; #endif // other gboolean bIsMute; gint bMuteImage; // 1 if the "mute" image is currently displayed, 0 if the normal icon is set, -1 if no image is set GtkWidget *pScale; GldiShortkey *cKeyBinding; } ; #endif cairo-dock-plugins-3.3.2/alsaMixer/src/voip-input-widget.h000664 001750 001750 00000004162 12223247501 024630 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2011 Canonical Ltd. Authors: Conor Curran This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 __VOIP_INPUT_WIDGET_H__ #define __VOIP_INPUT_WIDGET_H__ #include #include #include #if (GTK_MAJOR_VERSION < 3) || defined (DBUSMENU_GTK3_NEW) #include #else #include #endif G_BEGIN_DECLS #define VOIP_INPUT_WIDGET_TYPE (voip_input_widget_get_type ()) #define VOIP_INPUT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VOIP_INPUT_WIDGET_TYPE, VoipInputWidget)) #define VOIP_INPUT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetClass)) #define IS_VOIP_INPUT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VOIP_INPUT_WIDGET_TYPE)) #define IS_VOIP_INPUT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VOIP_INPUT_WIDGET_TYPE)) #define VOIP_INPUT_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetClass)) typedef struct _VoipInputWidget VoipInputWidget; typedef struct _VoipInputWidgetClass VoipInputWidgetClass; struct _VoipInputWidgetClass { GObjectClass parent_class; }; struct _VoipInputWidget { GObject parent; }; GType voip_input_widget_get_type (void) G_GNUC_CONST; GtkWidget* voip_input_widget_new(DbusmenuMenuitem* twin_item); GtkWidget* voip_input_widget_get_ido_slider(VoipInputWidget* self); void voip_input_widget_update(VoipInputWidget* self, gdouble update); void voip_input_widget_tidy_up (GtkWidget *widget); G_END_DECLS #endif cairo-dock-plugins-3.3.2/alsaMixer/src/applet-generic.h000775 001750 001750 00000002241 12223247501 024133 0ustar00mbaertsmbaerts000000 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 __APPLET_GENERIC__ #define __APPLET_GENERIC__ #include int cd_get_volume (void); void cd_set_volume (int iVolume); void cd_toggle_mute (void); void cd_show_hide (void); void cd_stop (void); void cd_reload (void); void cd_start (void); GtkWidget *mixer_build_widget (gboolean bHorizontal); void cd_mixer_set_volume_with_no_callback (GtkWidget *pScale, int iVolume); #endif cairo-dock-plugins-3.3.2/alsaMixer/src/mute-widget.c000664 001750 001750 00000007263 12223247501 023470 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2011 Canonical Ltd. Authors: Marco Trevisan (Treviño) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "mute-widget.h" #include "common-defs.h" ///#include "indicator-sound.h" typedef struct _MuteWidgetPrivate MuteWidgetPrivate; struct _MuteWidgetPrivate { DbusmenuMenuitem *item; GtkMenuItem *gitem; }; #define MUTE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MUTE_WIDGET_TYPE, MuteWidgetPrivate)) /* Prototypes */ static void mute_widget_class_init (MuteWidgetClass *klass); static void mute_widget_init (MuteWidget *self); static void mute_widget_dispose (GObject *object); static void mute_widget_finalize (GObject *object); G_DEFINE_TYPE (MuteWidget, mute_widget, G_TYPE_OBJECT); static void mute_widget_class_init (MuteWidgetClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = mute_widget_dispose; gobject_class->finalize = mute_widget_finalize; g_type_class_add_private (klass, sizeof (MuteWidgetPrivate)); } static void mute_widget_init (MuteWidget *self) { MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self); priv->item = NULL; priv->gitem = GTK_MENU_ITEM(gtk_menu_item_new ()); } static void mute_widget_dispose (GObject *object) { G_OBJECT_CLASS (mute_widget_parent_class)->dispose (object); } static void mute_widget_finalize (GObject *object) { MuteWidget *self = MUTE_WIDGET (object); MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self); g_object_unref (priv->item); g_object_unref (G_OBJECT (priv->gitem)); G_OBJECT_CLASS (mute_widget_parent_class)->finalize (object); } GtkMenuItem * mute_widget_get_menu_item(MuteWidget *self) { MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self); return priv->gitem; } MuteStatus mute_widget_get_status (MuteWidget *self) { g_return_val_if_fail(self, MUTE_STATUS_UNAVAILABLE); MuteStatus status = MUTE_STATUS_UNAVAILABLE; MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self); GVariant *vstatus = dbusmenu_menuitem_property_get_variant(priv->item, DBUSMENU_MUTE_MENUITEM_VALUE); if (g_variant_is_of_type (vstatus, G_VARIANT_TYPE_BOOLEAN)) { if (g_variant_get_boolean (vstatus)) status = MUTE_STATUS_MUTED; else status = MUTE_STATUS_UNMUTED; } return status; } void mute_widget_toggle (MuteWidget *self) { g_return_if_fail (self); MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self); gtk_menu_item_activate (priv->gitem); } /** * mute_widget_new: * @returns: a new #MuteWidget. **/ MuteWidget * mute_widget_new (DbusmenuMenuitem *item) { MuteWidget* widget = g_object_new(MUTE_WIDGET_TYPE, NULL); MuteWidgetPrivate* priv = MUTE_WIDGET_GET_PRIVATE(widget); priv->item = g_object_ref(item); GVariant *label = dbusmenu_menuitem_property_get_variant(priv->item, DBUSMENU_MENUITEM_PROP_LABEL); if (g_variant_is_of_type(label, G_VARIANT_TYPE_STRING)) gtk_menu_item_set_label(priv->gitem, g_variant_get_string(label, NULL)); return widget; } cairo-dock-plugins-3.3.2/alsaMixer/src/metadata-widget.h000664 001750 001750 00000003545 12223247501 024302 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2010 Canonical Ltd. Authors: Conor Curran This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 __METADATA_WIDGET_H__ #define __METADATA_WIDGET_H__ #include #if (GTK_MAJOR_VERSION < 3) || defined (DBUSMENU_GTK3_NEW) #include #else #include #endif G_BEGIN_DECLS #define METADATA_WIDGET_TYPE (metadata_widget_get_type ()) #define METADATA_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), METADATA_WIDGET_TYPE, MetadataWidget)) #define METADATA_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), METADATA_WIDGET_TYPE, MetadataWidgetClass)) #define IS_METADATA_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), METADATA_WIDGET_TYPE)) #define IS_METADATA_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), METADATA_WIDGET_TYPE)) #define METADATA_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), METADATA_WIDGET_TYPE, MetadataWidgetClass)) typedef struct _MetadataWidget MetadataWidget; typedef struct _MetadataWidgetClass MetadataWidgetClass; struct _MetadataWidgetClass { GtkMenuItemClass parent_class; }; struct _MetadataWidget { GtkMenuItem parent; }; GType metadata_widget_get_type (void); GtkWidget* metadata_widget_new(DbusmenuMenuitem *twin_item); G_END_DECLS #endif cairo-dock-plugins-3.3.2/alsaMixer/src/applet-generic.c000775 001750 001750 00000006634 12223247501 024140 0ustar00mbaertsmbaerts000000 000000 /** * This file is a part of the Cairo-Dock project * * Copyright : (C) see the 'copyright' file. * based on indicator-messages.c written by : * Ted Gould * Cody Russell * 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 "applet-struct.h" #include "applet-backend-alsamixer.h" #ifdef INDICATOR_SOUNDMENU_WITH_IND3 #include "applet-backend-sound-menu.h" #elif defined SOUND_SERVICE_SUPPORT // OLD #include "applet-backend-sound-menu-old.h" #endif #include "applet-generic.h" int cd_get_volume (void) { if (myData.ctl.get_volume) return myData.ctl.get_volume (); return 0; } void cd_set_volume (int iVolume) { if (myData.ctl.set_volume) myData.ctl.set_volume (iVolume); } void cd_toggle_mute (void) { if (myData.ctl.toggle_mute) myData.ctl.toggle_mute (); } void cd_show_hide (void) { if (myData.ctl.show_hide) myData.ctl.show_hide (); } void cd_stop (void) { if (myData.ctl.stop) myData.ctl.stop (); } void cd_reload (void) { if (myData.ctl.reload) myData.ctl.reload (); } void cd_start (void) { #if defined INDICATOR_SOUNDMENU_WITH_IND3 || defined SOUND_SERVICE_SUPPORT cd_mixer_connect_to_sound_service (); // connect to the sound service, it will fall back to alsa if it's not available. #else cd_mixer_init_alsa (); #endif } /// SCALE /// static void on_change_volume (GtkRange *range, gpointer data) { CD_APPLET_ENTER; int iNewVolume = (int) gtk_range_get_value (GTK_RANGE (range)); cd_debug ("%s (%d)", __func__, iNewVolume); cd_set_volume (iNewVolume); CD_APPLET_LEAVE(); } GtkWidget *mixer_build_widget (gboolean bHorizontal) { g_return_val_if_fail (myData.pControledElement != NULL, NULL); #if (GTK_MAJOR_VERSION < 3) GtkWidget *pScale = (bHorizontal ? gtk_hscale_new_with_range (0., 100., .5*myConfig.iScrollVariation) : gtk_vscale_new_with_range (0., 100., .5*myConfig.iScrollVariation)); #else GtkWidget *pScale = gtk_scale_new_with_range (bHorizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, 0., 100., .5*myConfig.iScrollVariation); #endif if (! bHorizontal) gtk_range_set_inverted (GTK_RANGE (pScale), TRUE); // de bas en haut. myData.iCurrentVolume = cd_get_volume (); gtk_range_set_value (GTK_RANGE (pScale), myData.iCurrentVolume); g_signal_connect (G_OBJECT (pScale), "value-changed", G_CALLBACK (on_change_volume), NULL); gldi_dialog_set_widget_text_color (pScale); return pScale; } void cd_mixer_set_volume_with_no_callback (GtkWidget *pScale, int iVolume) { g_signal_handlers_block_matched (GTK_WIDGET(pScale), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (void*)on_change_volume, NULL); gtk_range_set_value (GTK_RANGE (pScale), (double) iVolume); g_signal_handlers_unblock_matched (GTK_WIDGET(pScale), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (void*)on_change_volume, NULL); } cairo-dock-plugins-3.3.2/alsaMixer/src/dbus-shared-names.h000664 001750 001750 00000002520 12223247501 024533 0ustar00mbaertsmbaerts000000 000000 /* A small wrapper utility to load indicators and put them as menu items into the gnome-panel using it's applet interface. Copyright 2010 Canonical Ltd. Authors: Conor Curran Ted Gould This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 __DBUS_SHARED_NAMES_H__ #define __DBUS_SHARED_NAMES_H__ #define INDICATOR_SOUND_DBUS_NAME "com.canonical.indicator.sound" #define INDICATOR_SOUND_MENU_DBUS_OBJECT_PATH "/com/canonical/indicator/sound/menu" #define INDICATOR_SOUND_SERVICE_DBUS_OBJECT_PATH "/com/canonical/indicator/sound/service" #define INDICATOR_SOUND_DBUS_INTERFACE "com.canonical.indicator.sound" #define INDICATOR_SOUND_DBUS_VERSION 0 #define INDICATOR_SOUND_SIGNAL_STATE_UPDATE "SoundStateUpdate" #endif /* __DBUS_SHARED_NAMES_H__ */ cairo-dock-plugins-3.3.2/alsaMixer/src/applet-init.h000775 001750 001750 00000001553 12223247501 023467 0ustar00mbaertsmbaerts000000 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 __APPLET_INIT__ #define __APPLET_INIT__ #include CD_APPLET_H #endif cairo-dock-plugins-3.3.2/alsaMixer/src/volume-widget.h000664 001750 001750 00000004242 12223247501 024024 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2010 Canonical Ltd. Authors: Conor Curran This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 __VOLUME_WIDGET_H__ #define __VOLUME_WIDGET_H__ #include #include #include #if (GTK_MAJOR_VERSION < 3) || defined (DBUSMENU_GTK3_NEW) #include #else #include #endif ///#include G_BEGIN_DECLS #define VOLUME_WIDGET_TYPE (volume_widget_get_type ()) #define VOLUME_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VOLUME_WIDGET_TYPE, VolumeWidget)) #define VOLUME_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VOLUME_WIDGET_TYPE, VolumeWidgetClass)) #define IS_VOLUME_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VOLUME_WIDGET_TYPE)) #define IS_VOLUME_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VOLUME_WIDGET_TYPE)) #define VOLUME_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VOLUME_WIDGET_TYPE, VolumeWidgetClass)) typedef struct _VolumeWidget VolumeWidget; typedef struct _VolumeWidgetClass VolumeWidgetClass; struct _VolumeWidgetClass { GObjectClass parent_class; }; struct _VolumeWidget { GObject parent; }; GType volume_widget_get_type (void) G_GNUC_CONST; GtkWidget* volume_widget_new(DbusmenuMenuitem *item/**, IndicatorObject* io*/); GtkWidget* volume_widget_get_ido_slider(VolumeWidget* self); void volume_widget_update(VolumeWidget* self, gdouble update, const gchar* label); void volume_widget_tidy_up (GtkWidget *widget); gdouble volume_widget_get_current_volume ( GtkWidget *widget ); G_END_DECLS #endif cairo-dock-plugins-3.3.2/alsaMixer/src/applet-notifications.h000775 001750 001750 00000002076 12223247501 025376 0ustar00mbaertsmbaerts000000 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 __APPLET_NOTIFICATIONS__ #define __APPLET_NOTIFICATIONS__ #include CD_APPLET_ON_CLICK_H CD_APPLET_ON_MIDDLE_CLICK_H CD_APPLET_ON_BUILD_MENU_H CD_APPLET_ON_SCROLL_H CD_APPLET_ON_DOUBLE_CLICK_H void mixer_on_keybinding_pull (const char *keystring, gpointer user_data); #endif cairo-dock-plugins-3.3.2/alsaMixer/src/applet-backend-alsamixer.h000775 001750 001750 00000001713 12223247501 026074 0ustar00mbaertsmbaerts000000 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 __APPLET_MIXER__ #define __APPLET_MIXER__ #include GList *mixer_get_cards_list (void); GList *mixer_get_elements_list (void); void cd_mixer_init_alsa (void); #endif cairo-dock-plugins-3.3.2/alsaMixer/src/transport-widget.c000664 001750 001750 00000163103 12223247501 024546 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2010 Canonical Ltd. Authors: Conor Curran Mirco Müller Andrea Cimitan This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 . Uses code from ctk */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "transport-widget.h" #define RECT_WIDTH 130.0f #define Y 7.0f #define X 70.0f #define INNER_RADIUS 12.5 #define MIDDLE_RADIUS 13.0f #define OUTER_RADIUS 14.5f #define CIRCLE_RADIUS 21.0f #define PREV_WIDTH 25.0f #define PREV_HEIGHT 17.0f #define NEXT_WIDTH 25.0f //PREV_WIDTH #define NEXT_HEIGHT 17.0f //PREV_HEIGHT #define TRI_WIDTH 11.0f #define TRI_HEIGHT 13.0f #define TRI_OFFSET 6.0f #define PREV_X 68.0f #define PREV_Y 13.0f #define NEXT_X 146.0f #define NEXT_Y 13.0f //prev_y #define PAUSE_WIDTH 21.0f #define PAUSE_HEIGHT 27.0f #define BAR_WIDTH 4.5f #define BAR_HEIGHT 24.0f #define BAR_OFFSET 10.0f #define PAUSE_X 111.0f #define PAUSE_Y 7.0f #define PLAY_WIDTH 28.0f #define PLAY_HEIGHT 29.0f #define PLAY_PADDING 5.0f #define INNER_START_SHADE 0.98 #define INNER_END_SHADE 0.98 #define MIDDLE_START_SHADE 1.0 #define MIDDLE_END_SHADE 1.0 #define OUTER_START_SHADE 0.75 #define OUTER_END_SHADE 1.3 #define SHADOW_BUTTON_SHADE 0.8 #define OUTER_PLAY_START_SHADE 0.7 #define OUTER_PLAY_END_SHADE 1.38 #define BUTTON_START_SHADE 1.1 #define BUTTON_END_SHADE 0.9 #define BUTTON_SHADOW_SHADE 0.8 #define INNER_COMPRESSED_START_SHADE 1.0 #define INNER_COMPRESSED_END_SHADE 1.0 typedef struct _TransportWidgetPrivate TransportWidgetPrivate; struct _TransportWidgetPrivate { TransportAction current_command; TransportAction key_event; TransportAction motion_event; TransportState current_state; GHashTable* command_coordinates; DbusmenuMenuitem* twin_item; gboolean has_focus; gint hold_timer; gint skip_frequency; }; #if GTK_CHECK_VERSION(3, 0, 0) static GList *transport_widget_list = NULL; static GtkStyleContext *spinner_style_context = NULL; static GtkWidgetPath *spinner_widget_path = NULL; #endif // TODO refactor the UI handlers, consolidate functionality between key press /release // and button press / release. #define TRANSPORT_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRANSPORT_WIDGET_TYPE, TransportWidgetPrivate)) /* Gobject boiler plate */ static void transport_widget_class_init (TransportWidgetClass *klass); static void transport_widget_init (TransportWidget *self); static void transport_widget_dispose (GObject *object); static void transport_widget_finalize (GObject *object); G_DEFINE_TYPE (TransportWidget, transport_widget, GTK_TYPE_MENU_ITEM); /* essentials */ static void transport_widget_set_twin_item ( TransportWidget* self, DbusmenuMenuitem* twin_item); #if ! GTK_CHECK_VERSION(3, 0, 0) static gboolean transport_widget_expose ( GtkWidget *button, GdkEventExpose *event); #endif static gboolean draw (GtkWidget* button, cairo_t *cr); /* UI and dbusmenu callbacks */ static gboolean transport_widget_button_press_event (GtkWidget *menuitem, GdkEventButton *event); static gboolean transport_widget_button_release_event (GtkWidget *menuitem, GdkEventButton *event); static gboolean transport_widget_motion_notify_event (GtkWidget *menuitem, GdkEventMotion *event); static gboolean transport_widget_leave_notify_event (GtkWidget *menuitem, GdkEventCrossing *event); static void transport_widget_property_update ( DbusmenuMenuitem* item, gchar * property, GVariant * value, gpointer userdata ); static void transport_widget_menu_hidden ( GtkWidget *menu, TransportWidget *transport); static void transport_widget_notify ( GObject *item, GParamSpec *pspec, gpointer user_data ); static TransportAction transport_widget_determine_button_event ( TransportWidget* button, GdkEventButton* event); static TransportAction transport_widget_determine_motion_event ( TransportWidget* button, GdkEventMotion* event); static void transport_widget_react_to_button_release ( TransportWidget* button, TransportAction command); static void transport_widget_toggle_play_pause ( TransportWidget* button, TransportState update); static void transport_widget_select (GtkWidget* menu, gpointer Userdata); static void transport_widget_deselect (GtkWidget* menu, gpointer Userdata); static TransportAction transport_widget_collision_detection (gint x, gint y); static void transport_widget_start_timing (TransportWidget* widget); static gboolean transport_widget_trigger_seek (gpointer userdata); static gboolean transport_widget_seek (gpointer userdata); /// Init functions ////////////////////////////////////////////////////////// static void transport_widget_class_init (TransportWidgetClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); g_type_class_add_private (klass, sizeof (TransportWidgetPrivate)); widget_class->button_press_event = transport_widget_button_press_event; widget_class->button_release_event = transport_widget_button_release_event; widget_class->motion_notify_event = transport_widget_motion_notify_event; widget_class->leave_notify_event = transport_widget_leave_notify_event; #if GTK_CHECK_VERSION(3, 0, 0) widget_class->draw = draw; #else widget_class->expose_event = transport_widget_expose; #endif gobject_class->dispose = transport_widget_dispose; gobject_class->finalize = transport_widget_finalize; } static void transport_widget_init (TransportWidget *self) { TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(self); #if GTK_CHECK_VERSION(3, 0, 0) if (transport_widget_list == NULL){ /* append the object to the static linked list. */ transport_widget_list = g_list_append (transport_widget_list, self); /* create widget path */ spinner_widget_path = gtk_widget_path_new(); gtk_widget_path_append_type (spinner_widget_path, GTK_TYPE_MENU); gtk_widget_path_append_type (spinner_widget_path, GTK_TYPE_MENU_ITEM); gint pos = gtk_widget_path_append_type (spinner_widget_path, GTK_TYPE_SPINNER); gtk_widget_path_iter_set_name (spinner_widget_path, pos, "IndicatorSoundSpinner"); /* create style context and append path */ spinner_style_context = gtk_style_context_new(); gtk_style_context_set_path (spinner_style_context, spinner_widget_path); gtk_style_context_add_class (spinner_style_context, GTK_STYLE_CLASS_MENU); gtk_style_context_add_class (spinner_style_context, GTK_STYLE_CLASS_MENUITEM); gtk_style_context_add_class (spinner_style_context, GTK_STYLE_CLASS_SPINNER); } #endif priv->current_command = TRANSPORT_ACTION_NO_ACTION; priv->current_state = TRANSPORT_STATE_PAUSED; priv->key_event = TRANSPORT_ACTION_NO_ACTION; priv->motion_event = TRANSPORT_ACTION_NO_ACTION; priv->has_focus = FALSE; priv->hold_timer = 0; priv->skip_frequency = 0; priv->command_coordinates = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_list_free); GList* previous_list = NULL; previous_list = g_list_insert(previous_list, GINT_TO_POINTER(15), 0); previous_list = g_list_insert(previous_list, GINT_TO_POINTER(5), 1); previous_list = g_list_insert(previous_list, GINT_TO_POINTER(60), 2); previous_list = g_list_insert(previous_list, GINT_TO_POINTER(34), 3); g_hash_table_insert(priv->command_coordinates, GINT_TO_POINTER(TRANSPORT_ACTION_PREVIOUS), previous_list); GList* play_list = NULL; play_list = g_list_insert(play_list, GINT_TO_POINTER(58), 0); play_list = g_list_insert(play_list, GINT_TO_POINTER(0), 1); play_list = g_list_insert(play_list, GINT_TO_POINTER(50), 2); play_list = g_list_insert(play_list, GINT_TO_POINTER(43), 3); g_hash_table_insert(priv->command_coordinates, GINT_TO_POINTER(TRANSPORT_ACTION_PLAY_PAUSE), play_list); GList* next_list = NULL; next_list = g_list_insert(next_list, GINT_TO_POINTER(100), 0); next_list = g_list_insert(next_list, GINT_TO_POINTER(5), 1); next_list = g_list_insert(next_list, GINT_TO_POINTER(60), 2); next_list = g_list_insert(next_list, GINT_TO_POINTER(34), 3); g_hash_table_insert(priv->command_coordinates, GINT_TO_POINTER(TRANSPORT_ACTION_NEXT), next_list); gtk_widget_set_size_request(GTK_WIDGET(self), 200, 43); g_signal_connect (G_OBJECT(self), "notify", G_CALLBACK (transport_widget_notify), NULL); g_signal_connect (G_OBJECT(self), "select", G_CALLBACK (transport_widget_select), NULL); g_signal_connect (G_OBJECT(self), "deselect", G_CALLBACK (transport_widget_deselect), NULL); gtk_widget_realize ( GTK_WIDGET (self) ); } static void transport_widget_dispose (GObject *object) { #if GTK_CHECK_VERSION(3, 0, 0) transport_widget_list = g_list_remove (transport_widget_list, object); if (transport_widget_list == NULL){ if (spinner_widget_path != NULL){ gtk_widget_path_free (spinner_widget_path); spinner_widget_path = NULL; } if (spinner_style_context != NULL){ g_object_unref (spinner_style_context); spinner_style_context = NULL; } } #endif TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(object); if (priv->command_coordinates != NULL) { g_hash_table_destroy (priv->command_coordinates); priv->command_coordinates = NULL; } G_OBJECT_CLASS (transport_widget_parent_class)->dispose (object); } static void transport_widget_finalize (GObject *object) { G_OBJECT_CLASS (transport_widget_parent_class)->finalize (object); } #if ! GTK_CHECK_VERSION(3, 0, 0) static gboolean transport_widget_expose (GtkWidget *button, GdkEventExpose *event) { cairo_t *cr; cr = gdk_cairo_create (gtk_widget_get_window (button)); cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); draw (button, cr); cairo_destroy (cr); return FALSE; } #endif gboolean transport_widget_is_selected ( TransportWidget* widget ) { TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(widget); return priv->has_focus; } static void transport_widget_toggle_play_pause(TransportWidget* button, TransportState update) { TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); priv->current_state = update; gtk_widget_queue_draw (GTK_WIDGET(button)); } static void transport_widget_notify ( GObject *item, GParamSpec *pspec, gpointer user_data ) { if (g_strcmp0 (pspec->name, "parent")){ GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (item)); if (parent){ g_signal_connect ( parent, "hide", G_CALLBACK (transport_widget_menu_hidden), item ); } } } static void transport_widget_menu_hidden ( GtkWidget *menu, TransportWidget *transport) { g_return_if_fail(IS_TRANSPORT_WIDGET(transport)); transport_widget_react_to_button_release(transport, TRANSPORT_ACTION_NO_ACTION); } static gboolean transport_widget_motion_notify_event (GtkWidget *menuitem, GdkEventMotion *event) { //g_debug("transport_widget_motion_notify_event()"); g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); TransportAction result = transport_widget_determine_motion_event ( TRANSPORT_WIDGET(menuitem), event); priv->motion_event = result; gtk_widget_queue_draw (menuitem); if (priv->hold_timer != 0){ g_source_remove (priv->hold_timer); priv->hold_timer = 0; } if(priv->skip_frequency != 0){ g_source_remove (priv->skip_frequency); priv->skip_frequency = 0; } return TRUE; } static gboolean transport_widget_leave_notify_event (GtkWidget *menuitem, GdkEventCrossing *event) { //g_debug("transport_widget_leave_notify_event()"); g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); priv->motion_event = TRANSPORT_ACTION_NO_ACTION; priv->current_command = TRANSPORT_ACTION_NO_ACTION; gtk_widget_queue_draw (GTK_WIDGET(menuitem)); return TRUE; } static gboolean transport_widget_button_press_event (GtkWidget *menuitem, GdkEventButton *event) { //g_debug("transport_widget_button_press_event()"); g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); TransportAction result = transport_widget_determine_button_event ( TRANSPORT_WIDGET(menuitem), event); if(result != TRANSPORT_ACTION_NO_ACTION){ priv->current_command = result; gtk_widget_queue_draw (GTK_WIDGET(menuitem)); if (priv->current_command == TRANSPORT_ACTION_PREVIOUS || priv->current_command == TRANSPORT_ACTION_NEXT){ transport_widget_start_timing (TRANSPORT_WIDGET(menuitem)); } } return TRUE; } /** * TODO rename or merge * @param widget */ static void transport_widget_start_timing (TransportWidget* widget) { TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE (widget); if (priv->hold_timer == 0){ priv->hold_timer = g_timeout_add (800, transport_widget_trigger_seek, widget); } } static gboolean transport_widget_trigger_seek (gpointer userdata) { g_return_val_if_fail ( IS_TRANSPORT_WIDGET(userdata), FALSE ); TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE (TRANSPORT_WIDGET(userdata)); if (priv->skip_frequency == 0){ priv->skip_frequency = g_timeout_add (100, transport_widget_seek, userdata); } priv->hold_timer = 0; return FALSE; } /** * This will be called repeatedly until a key/button release is received * @param userdata * @return */ static gboolean transport_widget_seek (gpointer userdata) { g_return_val_if_fail ( IS_TRANSPORT_WIDGET(userdata), FALSE ); TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE (TRANSPORT_WIDGET(userdata)); GVariant* new_transport_state; if(priv->current_command == TRANSPORT_ACTION_NEXT){ //g_debug ("we should be skipping forward"); new_transport_state = g_variant_new_int32 ((int)TRANSPORT_ACTION_FORWIND); dbusmenu_menuitem_handle_event ( priv->twin_item, "Transport state change", new_transport_state, 0 ); } else if(priv->current_command == TRANSPORT_ACTION_PREVIOUS){ //g_debug ("we should be skipping back"); new_transport_state = g_variant_new_int32 ((int)TRANSPORT_ACTION_REWIND); dbusmenu_menuitem_handle_event ( priv->twin_item, "Transport state change", new_transport_state, 0 ); } return TRUE; } static gboolean transport_widget_button_release_event (GtkWidget *menuitem, GdkEventButton *event) { g_return_val_if_fail(IS_TRANSPORT_WIDGET(menuitem), FALSE); TransportWidget* transport = TRANSPORT_WIDGET(menuitem); TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); TransportAction result = transport_widget_determine_button_event ( transport, event ); if (result != TRANSPORT_ACTION_NO_ACTION && priv->current_command == result && priv->skip_frequency == 0){ GVariant* new_transport_state = g_variant_new_int32 ((int)result); dbusmenu_menuitem_handle_event ( priv->twin_item, "Transport state change", new_transport_state, 0 ); } transport_widget_react_to_button_release ( transport, result ); return TRUE; } static void transport_widget_select (GtkWidget* item, gpointer Userdata) { TransportWidget* transport = TRANSPORT_WIDGET(item); TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); priv->has_focus = TRUE; } static void transport_widget_deselect (GtkWidget* item, gpointer Userdata) { TransportWidget* transport = TRANSPORT_WIDGET(item); TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); priv->has_focus = FALSE; } void transport_widget_react_to_key_press_event ( TransportWidget* transport, TransportAction transport_event ) { if(transport_event != TRANSPORT_ACTION_NO_ACTION){ TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); priv->current_command = transport_event; priv->key_event = transport_event; gtk_widget_realize ( GTK_WIDGET(transport) ); gtk_widget_queue_draw (GTK_WIDGET(transport) ); if (priv->current_command == TRANSPORT_ACTION_PREVIOUS || priv->current_command == TRANSPORT_ACTION_NEXT){ transport_widget_start_timing (transport); } } } void transport_widget_react_to_key_release_event ( TransportWidget* transport, TransportAction transport_event ) { if(transport_event != TRANSPORT_ACTION_NO_ACTION){ TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); GVariant* new_transport_event = g_variant_new_int32((int)transport_event); if (priv->skip_frequency == 0){ dbusmenu_menuitem_handle_event ( priv->twin_item, "Transport state change", new_transport_event, 0 ); } } transport_widget_react_to_button_release ( transport, transport_event ); } void transport_widget_focus_update ( TransportWidget* transport, gboolean focus ) { TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); priv->has_focus = focus; } static TransportAction transport_widget_determine_button_event( TransportWidget* button, GdkEventButton* event ) { return transport_widget_collision_detection (event->x, event->y); } static TransportAction transport_widget_determine_motion_event( TransportWidget* button, GdkEventMotion* event ) { return transport_widget_collision_detection (event->x, event->y); } static TransportAction transport_widget_collision_detection ( gint x, gint y ) { TransportAction event = TRANSPORT_ACTION_NO_ACTION; if (x > 57 && x < 102 && y > 12 && y < 40){ event = TRANSPORT_ACTION_PREVIOUS; } else if (x > 101 && x < 143 && y > 5 && y < 47){ event = TRANSPORT_ACTION_PLAY_PAUSE; } else if (x > 142 && x < 187 && y > 12 && y < 40){ event = TRANSPORT_ACTION_NEXT; } return event; } static void transport_widget_react_to_button_release ( TransportWidget* button, TransportAction command ) { g_return_if_fail(IS_TRANSPORT_WIDGET(button)); TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); priv->current_command = TRANSPORT_ACTION_NO_ACTION; priv->key_event = TRANSPORT_ACTION_NO_ACTION; gtk_widget_queue_draw (GTK_WIDGET(button)); if (priv->hold_timer != 0){ g_source_remove (priv->hold_timer); priv->hold_timer = 0; } if(priv->skip_frequency != 0){ g_source_remove (priv->skip_frequency); priv->skip_frequency = 0; } } /// internal helper functions ////////////////////////////////////////////////// static void draw_gradient (cairo_t* cr, double x, double y, double w, double r, double* rgba_start, double* rgba_end) { cairo_pattern_t* pattern = NULL; cairo_move_to (cr, x, y); cairo_line_to (cr, x + w - 2.0f * r, y); cairo_arc (cr, x + w - 2.0f * r, y + r, r, -90.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f); cairo_line_to (cr, x, y + 2.0f * r); cairo_arc (cr, x, y + r, r, 90.0f * G_PI / 180.0f, 270.0f * G_PI / 180.0f); cairo_close_path (cr); pattern = cairo_pattern_create_linear (x, y, x, y + 2.0f * r); cairo_pattern_add_color_stop_rgba (pattern, 0.0f, rgba_start[0], rgba_start[1], rgba_start[2], rgba_start[3]); cairo_pattern_add_color_stop_rgba (pattern, 1.0f, rgba_end[0], rgba_end[1], rgba_end[2], rgba_end[3]); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); } static void draw_circle (cairo_t* cr, double x, double y, double r, double* rgba_start, double* rgba_end) { cairo_pattern_t* pattern = NULL; cairo_move_to (cr, x, y); cairo_arc (cr, x + r, y + r, r, 0.0f * G_PI / 180.0f, 360.0f * G_PI / 180.0f); pattern = cairo_pattern_create_linear (x, y, x, y + 2.0f * r); cairo_pattern_add_color_stop_rgba (pattern, 0.0f, rgba_start[0], rgba_start[1], rgba_start[2], rgba_start[3]); cairo_pattern_add_color_stop_rgba (pattern, 1.0f, rgba_end[0], rgba_end[1], rgba_end[2], rgba_end[3]); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); } static void _setup (cairo_t** cr, cairo_surface_t** surf, gint width, gint height) { if (!cr || !surf) return; *surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); *cr = cairo_create (*surf); cairo_scale (*cr, 1.0f, 1.0f); cairo_set_operator (*cr, CAIRO_OPERATOR_CLEAR); cairo_paint (*cr); cairo_set_operator (*cr, CAIRO_OPERATOR_OVER); } static void _mask_prev (cairo_t* cr, double x, double y, double tri_width, double tri_height, double tri_offset) { if (!cr) return; cairo_move_to (cr, x, y + tri_height / 2.0f); cairo_line_to (cr, x + tri_width, y); cairo_line_to (cr, x + tri_width, y + tri_height); x += tri_offset; cairo_move_to (cr, x, y + tri_height / 2.0f); cairo_line_to (cr, x + tri_width, y); cairo_line_to (cr, x + tri_width, y + tri_height); x -= tri_offset; cairo_rectangle (cr, x, y, 2.5f, tri_height); cairo_close_path (cr); } static void _mask_next (cairo_t* cr, double x, double y, double tri_width, double tri_height, double tri_offset) { if (!cr) return; cairo_move_to (cr, x, y); cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); cairo_line_to (cr, x, y + tri_height); x += tri_offset; cairo_move_to (cr, x, y); cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); cairo_line_to (cr, x, y + tri_height); x -= tri_offset; x += 2.0f * tri_width - tri_offset - 1.0f; cairo_rectangle (cr, x, y, 2.5f, tri_height); cairo_close_path (cr); } static void _mask_pause (cairo_t* cr, double x, double y, double bar_width, double bar_height, double bar_offset) { if (!cr) return; cairo_set_line_width (cr, bar_width); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); x += bar_width; y += bar_width; cairo_move_to (cr, x, y); cairo_line_to (cr, x, y + bar_height); cairo_move_to (cr, x + bar_offset, y); cairo_line_to (cr, x + bar_offset, y + bar_height); } static void _mask_play (cairo_t* cr, double x, double y, double tri_width, double tri_height) { if (!cr) return; cairo_move_to (cr, x, y); cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); cairo_line_to (cr, x, y + tri_height); cairo_close_path (cr); } static void _fill (cairo_t* cr, double x_start, double y_start, double x_end, double y_end, double* rgba_start, double* rgba_end, gboolean stroke) { cairo_pattern_t* pattern = NULL; if (!cr || !rgba_start || !rgba_end) return; pattern = cairo_pattern_create_linear (x_start, y_start, x_end, y_end); cairo_pattern_add_color_stop_rgba (pattern, 0.0f, rgba_start[0], rgba_start[1], rgba_start[2], rgba_start[3]); cairo_pattern_add_color_stop_rgba (pattern, 1.0f, rgba_end[0], rgba_end[1], rgba_end[2], rgba_end[3]); cairo_set_source (cr, pattern); if (stroke) cairo_stroke (cr); else cairo_fill (cr); cairo_pattern_destroy (pattern); } static void _finalize (cairo_t* cr, cairo_t** cr_surf, cairo_surface_t** surf, double x, double y) { if (!cr || !cr_surf || !surf) return; cairo_set_source_surface (cr, *surf, x, y); cairo_paint (cr); cairo_surface_destroy (*surf); cairo_destroy (*cr_surf); } static void _finalize_repaint (cairo_t* cr, cairo_t** cr_surf, cairo_surface_t** surf, double x, double y, int repaints) { if (!cr || !cr_surf || !surf) return; while (repaints > 0) { cairo_set_source_surface (cr, *surf, x, y); cairo_paint (cr); repaints--; } cairo_surface_destroy (*surf); cairo_destroy (*cr_surf); } static void _color_rgb_to_hls (gdouble *r, gdouble *g, gdouble *b) { gdouble min; gdouble max; gdouble red; gdouble green; gdouble blue; gdouble h = 0; gdouble l; gdouble s; gdouble delta; red = *r; green = *g; blue = *b; if (red > green) { if (red > blue) max = red; else max = blue; if (green < blue) min = green; else min = blue; } else { if (green > blue) max = green; else max = blue; if (red < blue) min = red; else min = blue; } l = (max+min)/2; if (fabs (max-min) < 0.0001) { h = 0; s = 0; } else { if (l <= 0.5) s = (max-min)/(max+min); else s = (max-min)/(2-max-min); delta = (max -min) != 0 ? (max -min) : 1; if(delta == 0) delta = 1; if (red == max) h = (green-blue)/delta; else if (green == max) h = 2+(blue-red)/delta; else if (blue == max) h = 4+(red-green)/delta; h *= 60; if (h < 0.0) h += 360; } *r = h; *g = l; *b = s; } static void _color_hls_to_rgb (gdouble *h, gdouble *l, gdouble *s) { gdouble hue; gdouble lightness; gdouble saturation; gdouble m1, m2; gdouble r, g, b; lightness = *l; saturation = *s; if (lightness <= 0.5) m2 = lightness*(1+saturation); else m2 = lightness+saturation-lightness*saturation; m1 = 2*lightness-m2; if (saturation == 0) { *h = lightness; *l = lightness; *s = lightness; } else { hue = *h+120; while (hue > 360) hue -= 360; while (hue < 0) hue += 360; if (hue < 60) r = m1+(m2-m1)*hue/60; else if (hue < 180) r = m2; else if (hue < 240) r = m1+(m2-m1)*(240-hue)/60; else r = m1; hue = *h; while (hue > 360) hue -= 360; while (hue < 0) hue += 360; if (hue < 60) g = m1+(m2-m1)*hue/60; else if (hue < 180) g = m2; else if (hue < 240) g = m1+(m2-m1)*(240-hue)/60; else g = m1; hue = *h-120; while (hue > 360) hue -= 360; while (hue < 0) hue += 360; if (hue < 60) b = m1+(m2-m1)*hue/60; else if (hue < 180) b = m2; else if (hue < 240) b = m1+(m2-m1)*(240-hue)/60; else b = m1; *h = r; *l = g; *s = b; } } void _color_shade (const CairoColorRGB *a, float k, CairoColorRGB *b) { double red; double green; double blue; red = a->r; green = a->g; blue = a->b; if (k == 1.0) { b->r = red; b->g = green; b->b = blue; return; } _color_rgb_to_hls (&red, &green, &blue); green *= k; if (green > 1.0) green = 1.0; else if (green < 0.0) green = 0.0; blue *= k; if (blue > 1.0) blue = 1.0; else if (blue < 0.0) blue = 0.0; _color_hls_to_rgb (&red, &green, &blue); b->r = red; b->g = green; b->b = blue; } static inline void _blurinner (guchar* pixel, gint* zR, gint* zG, gint* zB, gint* zA, gint alpha, gint aprec, gint zprec) { gint R; gint G; gint B; guchar A; R = *pixel; G = *(pixel + 1); B = *(pixel + 2); A = *(pixel + 3); *zR += (alpha * ((R << zprec) - *zR)) >> aprec; *zG += (alpha * ((G << zprec) - *zG)) >> aprec; *zB += (alpha * ((B << zprec) - *zB)) >> aprec; *zA += (alpha * ((A << zprec) - *zA)) >> aprec; *pixel = *zR >> zprec; *(pixel + 1) = *zG >> zprec; *(pixel + 2) = *zB >> zprec; *(pixel + 3) = *zA >> zprec; } static inline void _blurrow (guchar* pixels, gint width, gint height, gint channels, gint line, gint alpha, gint aprec, gint zprec) { gint zR; gint zG; gint zB; gint zA; gint index; guchar* scanline; scanline = &(pixels[line * width * channels]); zR = *scanline << zprec; zG = *(scanline + 1) << zprec; zB = *(scanline + 2) << zprec; zA = *(scanline + 3) << zprec; for (index = 0; index < width; index ++) _blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); for (index = width - 2; index >= 0; index--) _blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); } static inline void _blurcol (guchar* pixels, gint width, gint height, gint channels, gint x, gint alpha, gint aprec, gint zprec) { gint zR; gint zG; gint zB; gint zA; gint index; guchar* ptr; ptr = pixels; ptr += x * channels; zR = *((guchar*) ptr ) << zprec; zG = *((guchar*) ptr + 1) << zprec; zB = *((guchar*) ptr + 2) << zprec; zA = *((guchar*) ptr + 3) << zprec; for (index = width; index < (height - 1) * width; index += width) _blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); for (index = (height - 2) * width; index >= 0; index -= width) _blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); } void _expblur (guchar* pixels, gint width, gint height, gint channels, gint radius, gint aprec, gint zprec) { gint alpha; gint row = 0; gint col = 0; if (radius < 1) return; // calculate the alpha such that 90% of // the kernel is within the radius. // (Kernel extends to infinity) alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f)))); for (; row < height; row++) _blurrow (pixels, width, height, channels, row, alpha, aprec, zprec); for(; col < width; col++) _blurcol (pixels, width, height, channels, col, alpha, aprec, zprec); return; } void _surface_blur (cairo_surface_t* surface, guint radius) { guchar* pixels; guint width; guint height; cairo_format_t format; // before we mess with the surface execute any pending drawing cairo_surface_flush (surface); pixels = cairo_image_surface_get_data (surface); width = cairo_image_surface_get_width (surface); height = cairo_image_surface_get_height (surface); format = cairo_image_surface_get_format (surface); switch (format) { case CAIRO_FORMAT_ARGB32: _expblur (pixels, width, height, 4, radius, 16, 7); break; case CAIRO_FORMAT_RGB24: _expblur (pixels, width, height, 3, radius, 16, 7); break; case CAIRO_FORMAT_A8: _expblur (pixels, width, height, 1, radius, 16, 7); break; default : // do nothing break; } // inform cairo we altered the surfaces contents cairo_surface_mark_dirty (surface); } static gboolean draw (GtkWidget* button, cairo_t *cr) { g_return_val_if_fail(IS_TRANSPORT_WIDGET(button), FALSE); g_return_val_if_fail(cr != NULL, FALSE); TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); //g_debug("transport-widget draw()"); cairo_surface_t* surf = NULL; cairo_t* cr_surf = NULL; #if ! GTK_CHECK_VERSION(3, 0, 0) GtkAllocation allocation; gtk_widget_get_allocation (button, &allocation); cairo_translate (cr, allocation.x, allocation.y); #endif #if GTK_CHECK_VERSION(3, 0, 0) gtk_style_context_add_class (gtk_widget_get_style_context (button), GTK_STYLE_CLASS_MENU); #endif CairoColorRGB bg_color, fg_color, bg_selected, bg_prelight; CairoColorRGB color_middle[2], color_middle_prelight[2], color_outer[2], color_outer_prelight[2], color_play_outer[2], color_play_outer_prelight[2], color_button[4], color_button_shadow, color_inner[2], color_inner_compressed[2]; #if (GTK_MAJOR_VERSION < 3) GtkStyle *style = gtk_widget_get_style (button); bg_color.r = style->bg[0].red/65535.0; bg_color.g = style->bg[0].green/65535.0; bg_color.b = style->bg[0].blue/65535.0; bg_prelight.r = style->bg[GTK_STATE_PRELIGHT].red/65535.0; bg_prelight.g = style->bg[GTK_STATE_PRELIGHT].green/65535.0; bg_prelight.b = style->bg[GTK_STATE_PRELIGHT].blue/65535.0; bg_selected.r = style->bg[GTK_STATE_SELECTED].red/65535.0; bg_selected.g = style->bg[GTK_STATE_SELECTED].green/65535.0; bg_selected.b = style->bg[GTK_STATE_SELECTED].blue/65535.0; fg_color.r = style->fg[0].red/65535.0; fg_color.g = style->fg[0].green/65535.0; fg_color.b = style->fg[0].blue/65535.0; #else GtkStyleContext *style = gtk_widget_get_style_context (button); gtk_style_context_get_background_color (style, 0, (GdkRGBA*)&bg_color); gtk_style_context_get_background_color (style, GTK_STATE_PRELIGHT, (GdkRGBA*)&bg_prelight); gtk_style_context_get_background_color (style, GTK_STATE_SELECTED, (GdkRGBA*)&bg_selected); gtk_style_context_get_color (style, 0, (GdkRGBA*)&fg_color); #endif _color_shade (&bg_color, MIDDLE_START_SHADE, &color_middle[0]); _color_shade (&bg_color, MIDDLE_END_SHADE, &color_middle[1]); _color_shade (&bg_prelight, MIDDLE_START_SHADE, &color_middle_prelight[0]); _color_shade (&bg_prelight, MIDDLE_END_SHADE, &color_middle_prelight[1]); _color_shade (&bg_color, OUTER_START_SHADE, &color_outer[0]); _color_shade (&bg_color, OUTER_END_SHADE, &color_outer[1]); _color_shade (&bg_prelight, OUTER_START_SHADE, &color_outer_prelight[0]); _color_shade (&bg_prelight, OUTER_END_SHADE, &color_outer_prelight[1]); _color_shade (&bg_color, OUTER_PLAY_START_SHADE, &color_play_outer[0]); _color_shade (&bg_color, OUTER_PLAY_END_SHADE, &color_play_outer[1]); _color_shade (&bg_prelight, OUTER_PLAY_START_SHADE, &color_play_outer_prelight[0]); _color_shade (&bg_prelight, OUTER_PLAY_END_SHADE, &color_play_outer_prelight[1]); _color_shade (&bg_color, INNER_START_SHADE, &color_inner[0]); _color_shade (&bg_color, INNER_END_SHADE, &color_inner[1]); _color_shade (&fg_color, BUTTON_START_SHADE, &color_button[0]); _color_shade (&fg_color, BUTTON_END_SHADE, &color_button[1]); _color_shade (&bg_color, BUTTON_SHADOW_SHADE, &color_button[2]); _color_shade (&bg_color, SHADOW_BUTTON_SHADE, &color_button_shadow); _color_shade (&bg_selected, 1.0, &color_button[3]); _color_shade (&bg_color, INNER_COMPRESSED_START_SHADE, &color_inner_compressed[0]); _color_shade (&bg_color, INNER_COMPRESSED_END_SHADE, &color_inner_compressed[1]); double MIDDLE_END[] = {color_middle[0].r, color_middle[0].g, color_middle[0].b, 1.0f}; double MIDDLE_START[] = {color_middle[1].r, color_middle[1].g, color_middle[1].b, 1.0f}; double MIDDLE_END_PRELIGHT[] = {color_middle_prelight[0].r, color_middle_prelight[0].g, color_middle_prelight[0].b, 1.0f}; double MIDDLE_START_PRELIGHT[] = {color_middle_prelight[1].r, color_middle_prelight[1].g, color_middle_prelight[1].b, 1.0f}; double OUTER_END[] = {color_outer[0].r, color_outer[0].g, color_outer[0].b, 1.0f}; double OUTER_START[] = {color_outer[1].r, color_outer[1].g, color_outer[1].b, 1.0f}; double OUTER_END_PRELIGHT[] = {color_outer_prelight[0].r, color_outer_prelight[0].g, color_outer_prelight[0].b, 1.0f}; double OUTER_START_PRELIGHT[] = {color_outer_prelight[1].r, color_outer_prelight[1].g, color_outer_prelight[1].b, 1.0f}; double SHADOW_BUTTON[] = {color_button_shadow.r, color_button_shadow.g, color_button_shadow.b, 0.3f}; double OUTER_PLAY_END[] = {color_play_outer[0].r, color_play_outer[0].g, color_play_outer[0].b, 1.0f}; double OUTER_PLAY_START[] = {color_play_outer[1].r, color_play_outer[1].g, color_play_outer[1].b, 1.0f}; double OUTER_PLAY_END_PRELIGHT[] = {color_play_outer_prelight[0].r, color_play_outer_prelight[0].g, color_play_outer_prelight[0].b, 1.0f}; double OUTER_PLAY_START_PRELIGHT[] = {color_play_outer_prelight[1].r, color_play_outer_prelight[1].g, color_play_outer_prelight[1].b, 1.0f}; double BUTTON_END[] = {color_button[0].r, color_button[0].g, color_button[0].b, 1.0f}; double BUTTON_START[] = {color_button[1].r, color_button[1].g, color_button[1].b, 1.0f}; double BUTTON_SHADOW[] = {color_button[2].r, color_button[2].g, color_button[2].b, 0.75f}; double BUTTON_SHADOW_FOCUS[] = {color_button[3].r, color_button[3].g, color_button[3].b, 1.0f}; double INNER_COMPRESSED_END[] = {color_inner_compressed[1].r, color_inner_compressed[1].g, color_inner_compressed[1].b, 1.0f}; double INNER_COMPRESSED_START[] = {color_inner_compressed[0].r, color_inner_compressed[0].g, color_inner_compressed[0].b, 1.0f}; draw_gradient (cr, X, Y, RECT_WIDTH, OUTER_RADIUS, OUTER_START, OUTER_END); draw_gradient (cr, X, Y + 1, RECT_WIDTH - 2, MIDDLE_RADIUS, MIDDLE_START, MIDDLE_END); draw_gradient (cr, X, Y + 2, RECT_WIDTH - 4, MIDDLE_RADIUS, MIDDLE_START, MIDDLE_END); //prev/next button if(priv->current_command == TRANSPORT_ACTION_PREVIOUS) { draw_gradient (cr, X, Y, RECT_WIDTH/2, OUTER_RADIUS, OUTER_END, OUTER_START); draw_gradient (cr, X, Y + 1, RECT_WIDTH/2, MIDDLE_RADIUS, INNER_COMPRESSED_START, INNER_COMPRESSED_END); draw_gradient (cr, X, Y + 2, RECT_WIDTH/2, MIDDLE_RADIUS, INNER_COMPRESSED_START, INNER_COMPRESSED_END); } else if(priv->current_command == TRANSPORT_ACTION_NEXT) { draw_gradient (cr, RECT_WIDTH / 2 + X, Y, RECT_WIDTH/2, OUTER_RADIUS, OUTER_END, OUTER_START); draw_gradient (cr, RECT_WIDTH / 2 + X, Y + 1, (RECT_WIDTH - 4.5)/2, MIDDLE_RADIUS, INNER_COMPRESSED_START, INNER_COMPRESSED_END); draw_gradient (cr, RECT_WIDTH / 2 + X, Y + 2, (RECT_WIDTH - 7)/2, MIDDLE_RADIUS, INNER_COMPRESSED_START, INNER_COMPRESSED_END); } else if (priv->motion_event == TRANSPORT_ACTION_PREVIOUS) { draw_gradient (cr, X, Y, RECT_WIDTH/2, OUTER_RADIUS, OUTER_START_PRELIGHT, OUTER_END_PRELIGHT); draw_gradient (cr, X, Y + 1, RECT_WIDTH/2, MIDDLE_RADIUS, MIDDLE_START_PRELIGHT, MIDDLE_END_PRELIGHT); draw_gradient (cr, X, Y + 2, RECT_WIDTH/2, MIDDLE_RADIUS, MIDDLE_START_PRELIGHT, MIDDLE_END_PRELIGHT); } else if (priv->motion_event == TRANSPORT_ACTION_NEXT) { draw_gradient (cr, RECT_WIDTH / 2 + X, Y, RECT_WIDTH/2, OUTER_RADIUS, OUTER_START_PRELIGHT, OUTER_END_PRELIGHT); draw_gradient (cr, RECT_WIDTH / 2 + X, Y + 1, (RECT_WIDTH - 4.5)/2, MIDDLE_RADIUS, MIDDLE_START_PRELIGHT, MIDDLE_END_PRELIGHT); draw_gradient (cr, RECT_WIDTH / 2 + X, Y + 2, (RECT_WIDTH - 7)/2, MIDDLE_RADIUS, MIDDLE_START_PRELIGHT, MIDDLE_END_PRELIGHT); } // play/pause shadow if(priv->current_command != TRANSPORT_ACTION_PLAY_PAUSE) { cairo_save (cr); cairo_rectangle (cr, X, Y, RECT_WIDTH, MIDDLE_RADIUS*2); cairo_clip (cr); draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f - 1.0f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) - 1.0f, CIRCLE_RADIUS + 1.0f, SHADOW_BUTTON, SHADOW_BUTTON); cairo_restore (cr); } // play/pause button if(priv->current_command == TRANSPORT_ACTION_PLAY_PAUSE) { draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) , CIRCLE_RADIUS, OUTER_PLAY_END, OUTER_PLAY_START); draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, CIRCLE_RADIUS - 1.25, INNER_COMPRESSED_START, INNER_COMPRESSED_END); } else if (priv->motion_event == TRANSPORT_ACTION_PLAY_PAUSE) { /* this subtle offset is to fix alpha borders, should be removed once this draw routine will be refactored */ draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 0.1, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 0.1, CIRCLE_RADIUS - 0.1, OUTER_PLAY_START_PRELIGHT, OUTER_PLAY_END_PRELIGHT); draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, CIRCLE_RADIUS - 1.25, MIDDLE_START_PRELIGHT, MIDDLE_END_PRELIGHT); } else { draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)), CIRCLE_RADIUS, OUTER_PLAY_START, OUTER_PLAY_END); draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, CIRCLE_RADIUS - 1.25, MIDDLE_START, MIDDLE_END); } // draw previous-button drop-shadow if (priv->has_focus && priv->key_event == TRANSPORT_ACTION_PREVIOUS) { _setup (&cr_surf, &surf, PREV_WIDTH+6, PREV_HEIGHT+6); _mask_prev (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_SHADOW_FOCUS, BUTTON_SHADOW_FOCUS, FALSE); _surface_blur (surf, 3); _finalize_repaint (cr, &cr_surf, &surf, PREV_X, PREV_Y + 0.5f, 3); } else { _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); _mask_prev (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_SHADOW, BUTTON_SHADOW, FALSE); _surface_blur (surf, 1); _finalize (cr, &cr_surf, &surf, PREV_X, PREV_Y + 1.0f); } // draw previous-button _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); _mask_prev (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_START, BUTTON_END, FALSE); _finalize (cr, &cr_surf, &surf, PREV_X, PREV_Y); // draw next-button drop-shadow if (priv->has_focus && priv->key_event == TRANSPORT_ACTION_NEXT) { _setup (&cr_surf, &surf, NEXT_WIDTH+6, NEXT_HEIGHT+6); _mask_next (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_SHADOW_FOCUS, BUTTON_SHADOW_FOCUS, FALSE); _surface_blur (surf, 3); _finalize_repaint (cr, &cr_surf, &surf, NEXT_X, NEXT_Y + 0.5f, 3); } else { _setup (&cr_surf, &surf, NEXT_WIDTH, NEXT_HEIGHT); _mask_next (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_SHADOW, BUTTON_SHADOW, FALSE); _surface_blur (surf, 1); _finalize (cr, &cr_surf, &surf, NEXT_X, NEXT_Y + 1.0f); } // draw next-button _setup (&cr_surf, &surf, NEXT_WIDTH, NEXT_HEIGHT); _mask_next (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_START, BUTTON_END, FALSE); _finalize (cr, &cr_surf, &surf, NEXT_X, NEXT_Y); // draw pause-button drop-shadow if(priv->current_state == TRANSPORT_STATE_PLAYING) { if (priv->has_focus && (priv->key_event == TRANSPORT_ACTION_NO_ACTION || priv->key_event == TRANSPORT_ACTION_PLAY_PAUSE)) { _setup (&cr_surf, &surf, PAUSE_WIDTH+6, PAUSE_HEIGHT+6); _mask_pause (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, BAR_WIDTH, BAR_HEIGHT - 2.0f * BAR_WIDTH, BAR_OFFSET); _fill (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (double) BAR_HEIGHT, BUTTON_SHADOW_FOCUS, BUTTON_SHADOW_FOCUS, TRUE); _surface_blur (surf, 3); _finalize_repaint (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y + 0.5f, 3); } else { _setup (&cr_surf, &surf, PAUSE_WIDTH, PAUSE_HEIGHT); _mask_pause (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, BAR_WIDTH, BAR_HEIGHT - 2.0f * BAR_WIDTH, BAR_OFFSET); _fill (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (double) BAR_HEIGHT, BUTTON_SHADOW, BUTTON_SHADOW, TRUE); _surface_blur (surf, 1); _finalize (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y + 1.0f); } // draw pause-button _setup (&cr_surf, &surf, PAUSE_WIDTH, PAUSE_HEIGHT); _mask_pause (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, BAR_WIDTH, BAR_HEIGHT - 2.0f * BAR_WIDTH, BAR_OFFSET); _fill (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (double) BAR_HEIGHT, BUTTON_START, BUTTON_END, TRUE); _finalize (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y); } else if(priv->current_state == TRANSPORT_STATE_PAUSED) { if (priv->has_focus && (priv->key_event == TRANSPORT_ACTION_NO_ACTION || priv->key_event == TRANSPORT_ACTION_PLAY_PAUSE)) { _setup (&cr_surf, &surf, PLAY_WIDTH+6, PLAY_HEIGHT+6); _mask_play (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING)); _fill (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING), BUTTON_SHADOW_FOCUS, BUTTON_SHADOW_FOCUS, FALSE); _surface_blur (surf, 3); _finalize_repaint (cr, &cr_surf, &surf, PAUSE_X-0.5f, PAUSE_Y + 0.5f, 3); } else { _setup (&cr_surf, &surf, PLAY_WIDTH, PLAY_HEIGHT); _mask_play (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING)); _fill (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING), BUTTON_SHADOW, BUTTON_SHADOW, FALSE); _surface_blur (surf, 1); _finalize (cr, &cr_surf, &surf, PAUSE_X-0.75f, PAUSE_Y + 1.0f); } // draw play-button _setup (&cr_surf, &surf, PLAY_WIDTH, PLAY_HEIGHT); cairo_set_line_width (cr, 10.5); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); _mask_play (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING)); _fill (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING), BUTTON_START, BUTTON_END, FALSE); _finalize (cr, &cr_surf, &surf, PAUSE_X-0.5f, PAUSE_Y); } #if GTK_CHECK_VERSION(3, 0, 0) else if(priv->current_state == TRANSPORT_STATE_LAUNCHING) { // the spinner is not aligned, why? because the play button has odd width/height numbers gtk_render_activity (spinner_style_context, cr, 106, 6, 30, 30); } #endif return FALSE; } static void transport_widget_set_twin_item(TransportWidget* self, DbusmenuMenuitem* twin_item) { TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(self); priv->twin_item = twin_item; g_signal_connect(G_OBJECT(priv->twin_item), "property-changed", G_CALLBACK(transport_widget_property_update), self); gint initial_state = dbusmenu_menuitem_property_get_int (twin_item, DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE ); //g_debug("TRANSPORT WIDGET - INITIAL UPDATE = %i", initial_state); transport_widget_toggle_play_pause (self, (TransportState)initial_state); } /** * transport_widget_update_state() * Callback for updates from the other side of dbus **/ static void transport_widget_property_update(DbusmenuMenuitem* item, gchar* property, GVariant* value, gpointer userdata) { //g_debug("transport_widget_update_state - with property %s", property); TransportWidget* bar = (TransportWidget*)userdata; g_return_if_fail(IS_TRANSPORT_WIDGET(bar)); TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(bar); if(g_ascii_strcasecmp(DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE, property) == 0) { TransportState new_state = (TransportState)g_variant_get_int32(value); //g_debug("transport_widget_update_state - with value %i", new_state); if (new_state == TRANSPORT_STATE_LAUNCHING){ #if GTK_CHECK_VERSION(3, 0, 0) gtk_style_context_set_state (spinner_style_context, GTK_STATE_FLAG_ACTIVE); // triggers the notification #endif priv->current_state = TRANSPORT_STATE_LAUNCHING; g_debug("TransportWidget::toggle play state : %i", priv->current_state); } else{ transport_widget_toggle_play_pause(bar, new_state); } } } /** * transport_widget_new: * @returns: a new #TransportWidget. **/ GtkWidget* transport_widget_new ( DbusmenuMenuitem *item ) { GtkWidget* widget = g_object_new(TRANSPORT_WIDGET_TYPE, NULL); gtk_widget_set_app_paintable (widget, TRUE); transport_widget_set_twin_item((TransportWidget*)widget, item); return widget; } cairo-dock-plugins-3.3.2/alsaMixer/src/mute-widget.h000664 001750 001750 00000004127 12223247501 023471 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2011 Canonical Ltd. Authors: Marco Trevisan (Treviño) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 __MUTE_WIDGET_H__ #define __MUTE_WIDGET_H__ #include #include #include #if (GTK_MAJOR_VERSION < 3) || defined (DBUSMENU_GTK3_NEW) #include #else #include #endif #include G_BEGIN_DECLS #define MUTE_WIDGET_TYPE (mute_widget_get_type ()) #define MUTE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTE_WIDGET_TYPE, MuteWidget)) #define MUTE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTE_WIDGET_TYPE, MuteWidgetClass)) #define IS_MUTE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTE_WIDGET_TYPE)) #define IS_MUTE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTE_WIDGET_TYPE)) #define MUTE_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTE_WIDGET_TYPE, MuteWidgetClass)) typedef struct _MuteWidget MuteWidget; typedef struct _MuteWidgetClass MuteWidgetClass; struct _MuteWidgetClass { GObjectClass parent_class; }; struct _MuteWidget { GObject parent; }; typedef enum { MUTE_STATUS_UNAVAILABLE, MUTE_STATUS_MUTED, MUTE_STATUS_UNMUTED } MuteStatus; GType mute_widget_get_type (void) G_GNUC_CONST; MuteWidget* mute_widget_new (DbusmenuMenuitem *item); MuteStatus mute_widget_get_status (MuteWidget *self); void mute_widget_toggle (MuteWidget *self); GtkMenuItem *mute_widget_get_menu_item (MuteWidget *self); G_END_DECLS #endif cairo-dock-plugins-3.3.2/alsaMixer/src/CMakeLists.txt000664 001750 001750 00000006032 12223247501 023622 0ustar00mbaertsmbaerts000000 000000 ########### sources ############### set (cd-AlsaMixer_LIB_SRCS applet-init.c applet-init.h applet-config.c applet-config.h applet-notifications.c applet-notifications.h applet-draw.c applet-draw.h applet-generic.c applet-generic.h # alsa backend applet-backend-alsamixer.c applet-backend-alsamixer.h applet-struct.h) # Sound service backend (optionnal) if (INDICATOR_SOUNDMENU_WITH_IND3) list (APPEND cd-AlsaMixer_LIB_SRCS applet-backend-sound-menu.c applet-backend-sound-menu.h) elseif (with_soundmenu) list (APPEND cd-AlsaMixer_LIB_SRCS applet-backend-sound-menu-old.c applet-backend-sound-menu-old.h applet-menu.c applet-menu.h volume-widget.c volume-widget.h voip-input-widget.c voip-input-widget.h transport-widget.c transport-widget.h mute-widget.c mute-widget.h metadata-widget.c metadata-widget.h) endif() add_library (${PACKAGE_ALSA_MIXER} SHARED ${cd-AlsaMixer_LIB_SRCS}) ########### compil ############### add_definitions (-DMY_APPLET_SHARE_DATA_DIR="${alsa_mixerdatadir}") add_definitions (-DMY_APPLET_PREVIEW_FILE="preview.jpg") add_definitions (-DMY_APPLET_CONF_FILE="AlsaMixer.conf") add_definitions (-DMY_APPLET_USER_DATA_DIR="AlsaMixer") add_definitions (-DMY_APPLET_VERSION="${VERSION_ALSA_MIXER}") add_definitions (-DMY_APPLET_GETTEXT_DOMAIN="${GETTEXT_ALSA_MIXER}") add_definitions (-DMY_APPLET_DOCK_VERSION="${dock_version}") add_definitions (-DMY_APPLET_ICON_FILE="icon.png") if (INDICATOR_SOUNDMENU_WITH_IND3) message (STATUS " With Indicator-Applet3") add_definitions (-DINDICATOR_SOUNDMENU_WITH_IND3=1) if (INDICATOR_NG) add_definitions (-DIS_INDICATOR_NG=1) endif() set (EXTRAS_INCLUDE_DIRS ${INDICATOR_APPLET_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/Indicator-applet3) set (EXTRAS_LIBRARY_DIRS ${INDICATOR_APPLET_LIBRARY_DIRS} ${CMAKE_SOURCE_DIR}/Indicator-applet3) set (EXTRAS_LIBRARIES ${INDICATOR_APPLET_LIBRARIES} indicator-applet3) elseif (with_soundmenu) add_definitions (-DSOUND_SERVICE_SUPPORT="1") add_definitions (-DSOUND_SERVICE_VERSION=${SOUND_SERVICE_VERSION}) if (${DBUSMENU_GTK3_NEW}) add_definitions (-DDBUSMENU_GTK3_NEW=1) endif() set (EXTRAS_INCLUDE_DIRS ${DBUSMENU_INCLUDE_DIRS} ${DBUSMENU_GTK_INCLUDE_DIRS} ${INDICATOR_APPLET_INCLUDE_DIRS} ${IDO_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/Indicator-applet) set (EXTRAS_LIBRARY_DIRS ${DBUSMENU_LIBRARY_DIRS} ${DBUSMENU_GTK_LIBRARY_DIRS} ${INDICATOR_APPLET_LIBRARY_DIRS} ${IDO_LIBRARY_DIRS} ${CMAKE_SOURCE_DIR}/Indicator-applet) set (EXTRAS_LIBRARIES ${DBUSMENU_LIBRARIES} ${DBUSMENU_GTK_LIBRARIES} ${INDICATOR_APPLET_LIBRARIES} ${IDO_LIBRARIES} indicator-applet) endif() include_directories ( ${PACKAGE_INCLUDE_DIRS} ${ALSA_MIXER_PACKAGE_INCLUDE_DIRS} ${EXTRAS_INCLUDE_DIRS}) link_directories ( ${PACKAGE_LIBRARY_DIRS} ${ALSA_MIXER_PACKAGE_LIBRARY_DIRS} ${EXTRAS_LIBRARY_DIRS}) target_link_libraries (${PACKAGE_ALSA_MIXER} ${PACKAGE_LIBRARIES} ${ALSA_MIXER_PACKAGE_LIBRARIES} ${EXTRAS_LIBRARIES}) ########### install files ############### install(TARGETS ${PACKAGE_ALSA_MIXER} DESTINATION ${pluginsdir}) cairo-dock-plugins-3.3.2/alsaMixer/src/applet-menu.c000775 001750 001750 00000036575 12223247501 023477 0ustar00mbaertsmbaerts000000 000000 /** * This file is a part of the Cairo-Dock project * * Copyright : (C) see the 'copyright' file. * based on indicator-messages.c written by : * Ted Gould * Cody Russell * 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 . */ /// This file is essentially indicator-sound.c, adapted to Cairo-Dock. #include #include #include #include "applet-struct.h" #include "applet-backend-sound-menu-old.h" // update_accessible_desc #include "transport-widget.h" #include "volume-widget.h" #include "voip-input-widget.h" #include "mute-widget.h" #include "metadata-widget.h" #include "applet-menu.h" #if (GTK_MAJOR_VERSION < 3) || defined (DBUSMENU_GTK3_NEW) #include #include #else #include #include #endif #include #if (GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 20) #include #endif #include static gboolean new_transport_widget (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data) { g_debug("indicator-sound: new_transport_bar() called "); GtkWidget* bar = NULL; ///IndicatorObject *io = NULL; g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); bar = transport_widget_new(newitem); /**io = g_object_get_data (G_OBJECT (client), "indicator"); IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); priv->transport_widgets_list = g_list_append ( priv->transport_widgets_list, bar );*/ myData.transport_widgets_list = g_list_append ( myData.transport_widgets_list, bar ); GtkMenuItem *menu_transport_bar = GTK_MENU_ITEM(bar); gtk_widget_show_all(bar); dbusmenu_gtkclient_newitem_base (DBUSMENU_GTKCLIENT(client), newitem, menu_transport_bar, parent); return TRUE; } static gboolean new_metadata_widget (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data) { g_debug("indicator-sound: new_metadata_widget"); GtkWidget* metadata = NULL; g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); metadata = metadata_widget_new (newitem); g_debug ("%s (\"%s\")", __func__, dbusmenu_menuitem_property_get(newitem, DBUSMENU_METADATA_MENUITEM_PLAYER_NAME)); GtkMenuItem *menu_metadata_widget = GTK_MENU_ITEM(metadata); gtk_widget_show_all(metadata); dbusmenu_gtkclient_newitem_base (DBUSMENU_GTKCLIENT(client), newitem, menu_metadata_widget, parent); return TRUE; } static gboolean new_volume_slider_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data) { g_debug("indicator-sound: new_volume_slider_widget"); GtkWidget* volume_widget = NULL; ///IndicatorObject *io = NULL; g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); /**io = g_object_get_data (G_OBJECT (client), "indicator"); IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io));*/ AppletData *priv = myDataPtr; if (priv->volume_widget != NULL){ ///volume_widget_tidy_up (priv->volume_widget); gtk_widget_destroy (priv->volume_widget); priv->volume_widget = NULL; } volume_widget = volume_widget_new (newitem/**, io*/); priv->volume_widget = volume_widget; // Don't forget to set the accessible desc. /// TODO: check that it's not needed... update_accessible_desc (-1/**io*/); GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); gtk_widget_show_all(ido_slider_widget); // register the style callback on this widget with state manager's style change // handler (needs to remake the blocking animation for each style). /**g_signal_connect (ido_slider_widget, "style-set", G_CALLBACK(sound_state_manager_style_changed_cb), priv->state_manager);*/ GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_item, parent); return TRUE; } /** * new_voip_slider_widget * Create the voip menu item widget, must of the time this widget will be hidden. * @param newitem * @param parent * @param client * @param user_data * @return */ static gboolean new_voip_slider_widget (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data) { g_debug("indicator-sound: new_voip_slider_widget"); GtkWidget* voip_widget = NULL; ///IndicatorObject *io = NULL; g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); /**io = g_object_get_data (G_OBJECT (client), "indicator"); IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io));*/ AppletData *priv = myDataPtr; if (priv->voip_widget != NULL){ ///voip_input_widget_tidy_up (priv->voip_widget); gtk_widget_destroy (priv->voip_widget); priv->voip_widget = NULL; } voip_widget = voip_input_widget_new (newitem); priv->voip_widget = voip_widget; GtkWidget* ido_slider_widget = voip_input_widget_get_ido_slider(VOIP_INPUT_WIDGET(voip_widget)); gtk_widget_show_all(ido_slider_widget); GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_item, parent); return TRUE; } static gboolean new_mute_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data) { ///IndicatorObject *io = NULL; g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); /**io = g_object_get_data (G_OBJECT (client), "indicator"); IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io));*/ AppletData *priv = myDataPtr; if (priv->mute_widget != NULL){ g_object_unref (priv->mute_widget); priv->mute_widget = NULL; } priv->mute_widget = mute_widget_new(newitem); GtkMenuItem *item = mute_widget_get_menu_item (priv->mute_widget); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, item, parent); return TRUE; } /*******************************************************************/ //UI callbacks /******************************************************************/ /**static GtkWidget * get_current_item (GtkContainer * container) { GList *children = gtk_container_get_children (container); GList *iter; GtkWidget *rv = NULL; // Suprisingly, GTK+ doesn't really let us query "what is the currently // selected item?". But it does note it internally by prelighting the // widget, so we watch for that. for (iter = children; iter; iter = iter->next) { if (gtk_widget_get_state (GTK_WIDGET (iter->data)) & GTK_STATE_PRELIGHT) { rv = GTK_WIDGET (iter->data); break; } } return rv; }*/ /** key_press_cb: **/ static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data) { gboolean digested = FALSE; ///g_return_val_if_fail(IS_INDICATOR_SOUND(data), FALSE); ///IndicatorSound *indicator = INDICATOR_SOUND (data); ///IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); AppletData *priv = myDataPtr; GtkWidget *menuitem; ///menuitem = get_current_item (GTK_CONTAINER (widget)); #if (GTK_MAJOR_VERSION < 3) menuitem = GTK_MENU_SHELL (widget)->active_menu_item; #else menuitem = gtk_menu_shell_get_selected_item (GTK_MENU_SHELL (widget)); #endif if (IDO_IS_SCALE_MENU_ITEM(menuitem) == TRUE){ gdouble current_value = 0; gdouble new_value = 0; const gdouble five_percent = 5; gboolean is_voip_slider = FALSE; if (g_ascii_strcasecmp (ido_scale_menu_item_get_primary_label (IDO_SCALE_MENU_ITEM(menuitem)), "VOLUME") == 0) { g_debug ("vOLUME SLIDER KEY PRESS"); GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)slider_widget); GtkRange* range = (GtkRange*)slider; g_return_val_if_fail(GTK_IS_RANGE(range), FALSE); current_value = gtk_range_get_value(range); new_value = current_value; } else if (g_ascii_strcasecmp (ido_scale_menu_item_get_primary_label (IDO_SCALE_MENU_ITEM(menuitem)), "VOIP") == 0) { g_debug ("VOIP SLIDER KEY PRESS"); GtkWidget* slider_widget = voip_input_widget_get_ido_slider(VOIP_INPUT_WIDGET(priv->voip_widget)); GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)slider_widget); GtkRange* range = (GtkRange*)slider; g_return_val_if_fail(GTK_IS_RANGE(range), FALSE); current_value = gtk_range_get_value(range); new_value = current_value; is_voip_slider = TRUE; } switch (event->keyval) { case GDK_KEY_Right: digested = TRUE; new_value = current_value + five_percent; break; case GDK_KEY_Left: digested = TRUE; new_value = current_value - five_percent; break; case GDK_KEY_plus: digested = TRUE; new_value = current_value + five_percent; break; case GDK_KEY_minus: digested = TRUE; new_value = current_value - five_percent; break; default: break; } new_value = CLAMP(new_value, 0, 100); if (new_value != current_value){ if (is_voip_slider == TRUE){ voip_input_widget_update (VOIP_INPUT_WIDGET(priv->voip_widget), new_value); } else{ volume_widget_update (VOLUME_WIDGET(priv->volume_widget), new_value, "keypress-update"); } } } else if (IS_TRANSPORT_WIDGET(menuitem) == TRUE) { TransportWidget* transport_widget = NULL; GList* elem; for ( elem = priv->transport_widgets_list; elem; elem = elem->next ) { transport_widget = TRANSPORT_WIDGET ( elem->data ); if ( transport_widget_is_selected( transport_widget ) ) break; } switch (event->keyval) { case GDK_KEY_Right: transport_widget_react_to_key_press_event ( transport_widget, TRANSPORT_ACTION_NEXT ); digested = TRUE; break; case GDK_KEY_Left: transport_widget_react_to_key_press_event ( transport_widget, TRANSPORT_ACTION_PREVIOUS ); digested = TRUE; break; case GDK_KEY_space: transport_widget_react_to_key_press_event ( transport_widget, TRANSPORT_ACTION_PLAY_PAUSE ); digested = TRUE; break; case GDK_KEY_Up: case GDK_KEY_Down: digested = FALSE; break; default: break; } } return digested; } /** key_release_cb: **/ static gboolean key_release_cb(GtkWidget* widget, GdkEventKey* event, gpointer data) { gboolean digested = FALSE; ///g_return_val_if_fail(IS_INDICATOR_SOUND(data), FALSE); ///IndicatorSound *indicator = INDICATOR_SOUND (data); ///IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); AppletData *priv = myDataPtr; GtkWidget *menuitem; ///menuitem = get_current_item (GTK_CONTAINER (widget)); #if (GTK_MAJOR_VERSION < 3) menuitem = GTK_MENU_SHELL (widget)->active_menu_item; #else menuitem = gtk_menu_shell_get_selected_item (GTK_MENU_SHELL (widget)); #endif if (IS_TRANSPORT_WIDGET(menuitem) == TRUE) { TransportWidget* transport_widget = NULL; GList* elem; for(elem = priv->transport_widgets_list; elem; elem = elem->next) { transport_widget = TRANSPORT_WIDGET (elem->data); if ( transport_widget_is_selected( transport_widget ) ) break; } switch (event->keyval) { case GDK_KEY_Right: transport_widget_react_to_key_release_event ( transport_widget, TRANSPORT_ACTION_NEXT ); digested = TRUE; break; case GDK_KEY_Left: transport_widget_react_to_key_release_event ( transport_widget, TRANSPORT_ACTION_PREVIOUS ); digested = TRUE; break; case GDK_KEY_space: transport_widget_react_to_key_release_event ( transport_widget, TRANSPORT_ACTION_PLAY_PAUSE ); digested = TRUE; break; case GDK_KEY_Up: case GDK_KEY_Down: digested = FALSE; break; default: break; } } return digested; } /////////////// // MAKE MENU // /////////////// void cd_sound_add_menu_handler (DbusmenuGtkClient * client) { dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), DBUSMENU_VOLUME_MENUITEM_TYPE, new_volume_slider_widget); dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), DBUSMENU_VOIP_INPUT_MENUITEM_TYPE, new_voip_slider_widget); dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), DBUSMENU_TRANSPORT_MENUITEM_TYPE, new_transport_widget); dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), DBUSMENU_METADATA_MENUITEM_TYPE, new_metadata_widget); dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), DBUSMENU_MUTE_MENUITEM_TYPE, new_mute_widget); // Note: Not ideal but all key handling needs to be managed here and then // delegated to the appropriate widget. g_signal_connect (myData.pIndicator->pMenu, "key-press-event", G_CALLBACK(key_press_cb), myApplet); g_signal_connect (myData.pIndicator->pMenu, "key-release-event", G_CALLBACK(key_release_cb), myApplet); } cairo-dock-plugins-3.3.2/alsaMixer/src/applet-init.c000775 001750 001750 00000017555 12225027055 023475 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-config.h" #include "applet-notifications.h" #include "applet-draw.h" #include "applet-generic.h" #include "applet-init.h" CD_APPLET_DEFINE_BEGIN ("AlsaMixer", 2, 0, 0, CAIRO_DOCK_CATEGORY_APPLET_SYSTEM, N_("This applet lets you control the sound volume from the dock.\n" "Scroll up/down on the icon to increase/decrease the volume.\n" "Click on icon to show/hide the volume control (you can bind a keyboard shortcut for it)\n" "Middle-click to set or unset to mute, double-click to raise the channels mixer.\n" "The applet can either use the Ubuntu Sound-menu or the Alsa driver."), "Fabounet (Fabrice Rey)") CD_APPLET_DEFINE_COMMON_APPLET_INTERFACE CD_APPLET_ALLOW_EMPTY_TITLE CD_APPLET_REDEFINE_TITLE (N_("Sound Control")) pInterface->load_custom_widget = cd_mixer_load_custom_widget; CD_APPLET_DEFINE_END static gboolean _cd_mixer_on_enter (GtkWidget* pWidget, GdkEventCrossing* pEvent, gpointer data) { if (myData.pScale && myDesklet && myDesklet->container.iHeight > 64) { gtk_widget_show (myData.pScale); } return GLDI_NOTIFICATION_LET_PASS; } gboolean _cd_mixer_on_leave (GtkWidget* pWidget, GdkEventCrossing* pEvent, gpointer data) { if (myData.pScale && myDesklet && myDesklet->container.iHeight > 64) { if (! myDesklet->container.bInside) gtk_widget_hide (myData.pScale); } return GLDI_NOTIFICATION_LET_PASS; } static void _set_data_renderer (void) { switch (myConfig.iVolumeEffect) { case VOLUME_EFFECT_GAUGE: { CairoDataRendererAttribute *pRenderAttr; // les attributs du data-renderer global. CairoGaugeAttribute attr; // les attributs de la jauge. memset (&attr, 0, sizeof (CairoGaugeAttribute)); pRenderAttr = CAIRO_DATA_RENDERER_ATTRIBUTE (&attr); pRenderAttr->cModelName = "gauge"; pRenderAttr->iRotateTheme = myConfig.iRotateTheme; attr.cThemePath = myConfig.cGThemePath; CD_APPLET_ADD_DATA_RENDERER_ON_MY_ICON (pRenderAttr); } break; case VOLUME_EFFECT_BAR: { CD_APPLET_SET_USER_IMAGE_ON_MY_ICON (myConfig.cDefaultIcon, "default.svg"); CairoDataRendererAttribute *pRenderAttr; // les attributs du data-renderer global. CairoProgressBarAttribute attr; memset (&attr, 0, sizeof (CairoProgressBarAttribute)); pRenderAttr = CAIRO_DATA_RENDERER_ATTRIBUTE (&attr); pRenderAttr->cModelName = "progressbar"; pRenderAttr->iRotateTheme = myConfig.iRotateTheme; CD_APPLET_ADD_DATA_RENDERER_ON_MY_ICON (pRenderAttr); } break; case VOLUME_EFFECT_NONE: case VOLUME_NB_EFFECTS: break; } } CD_APPLET_INIT_BEGIN // set a desklet renderer if (myDesklet) { int iScaleWidth = (myDesklet->container.iHeight > 64 ? 15 : 0); gpointer pConfig[4] = {GINT_TO_POINTER (0), GINT_TO_POINTER (0), GINT_TO_POINTER (iScaleWidth), GINT_TO_POINTER (iScaleWidth)}; CD_APPLET_SET_DESKLET_RENDERER_WITH_DATA ("Simple", pConfig); // scale widget visibility in desklet if (myConfig.bHideScaleOnLeave) { g_signal_connect (G_OBJECT (myDesklet->container.pWidget), "enter-notify-event", G_CALLBACK (_cd_mixer_on_enter), NULL); g_signal_connect (G_OBJECT (myDesklet->container.pWidget), "leave-notify-event", G_CALLBACK (_cd_mixer_on_leave), NULL); } } // data renderer _set_data_renderer (); myData.bMuteImage = -1; // no image is set on the icon // start the sound controler cd_start (); // mouse events CD_APPLET_REGISTER_FOR_CLICK_EVENT; CD_APPLET_REGISTER_FOR_MIDDLE_CLICK_EVENT; CD_APPLET_REGISTER_FOR_BUILD_MENU_EVENT; CD_APPLET_REGISTER_FOR_SCROLL_EVENT; CD_APPLET_REGISTER_FOR_DOUBLE_CLICK_EVENT; // keyboard events myData.cKeyBinding = CD_APPLET_BIND_KEY (myConfig.cShortcut, D_("Show/hide the Sound menu"), // if no sound service, it's just a dialog though ... "Configuration", "shortkey", (CDBindkeyHandler) mixer_on_keybinding_pull); CD_APPLET_INIT_END CD_APPLET_STOP_BEGIN //\_______________ mouse events. CD_APPLET_UNREGISTER_FOR_CLICK_EVENT; CD_APPLET_UNREGISTER_FOR_MIDDLE_CLICK_EVENT; CD_APPLET_UNREGISTER_FOR_BUILD_MENU_EVENT; CD_APPLET_UNREGISTER_FOR_SCROLL_EVENT; CD_APPLET_UNREGISTER_FOR_DOUBLE_CLICK_EVENT; // keyboard events gldi_object_unref (GLDI_OBJECT(myData.cKeyBinding)); // stop the current controler. cd_stop (); CD_APPLET_STOP_END CD_APPLET_RELOAD_BEGIN //\_______________ On recharge le mixer si necessaire. if (CD_APPLET_MY_CONFIG_CHANGED) { if (myDesklet) { int iScaleWidth = (myDesklet->container.iHeight > 64 ? 15 : 0); gpointer pConfig[4] = {GINT_TO_POINTER (0), GINT_TO_POINTER (0), GINT_TO_POINTER (iScaleWidth), GINT_TO_POINTER (iScaleWidth)}; CD_APPLET_SET_DESKLET_RENDERER_WITH_DATA ("Simple", pConfig); } if (myConfig.iVolumeDisplay != VOLUME_ON_ICON) CD_APPLET_SET_QUICK_INFO_ON_MY_ICON_PRINTF (NULL); // reload or remove the data renderer if (myConfig.iVolumeEffect == VOLUME_EFFECT_NONE) { CD_APPLET_REMOVE_MY_DATA_RENDERER; } else { _set_data_renderer (); } myData.bMuteImage = -1; // to re-apply the image on the icon // reload the controler cd_reload (); // shortkey gldi_shortkey_rebind (myData.cKeyBinding, myConfig.cShortcut, NULL); // scale if (myDesklet) { if (CD_APPLET_MY_CONTAINER_TYPE_CHANGED) { gldi_object_unref (GLDI_OBJECT(myData.pDialog)); myData.pDialog = NULL; GtkWidget *box = _gtk_hbox_new (0); myData.pScale = mixer_build_widget (FALSE); gtk_box_pack_end (GTK_BOX (box), myData.pScale, FALSE, FALSE, 0); gtk_widget_show_all (box); gtk_container_add (GTK_CONTAINER (myDesklet->container.pWidget), box); if (myConfig.bHideScaleOnLeave && ! myDesklet->container.bInside) gtk_widget_hide (myData.pScale); } gulong iOnEnterCallbackID = g_signal_handler_find (myDesklet->container.pWidget, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, _cd_mixer_on_enter, NULL); if (myConfig.bHideScaleOnLeave && iOnEnterCallbackID <= 0) { g_signal_connect (G_OBJECT (myDesklet->container.pWidget), "enter-notify-event", G_CALLBACK (_cd_mixer_on_enter), NULL); g_signal_connect (G_OBJECT (myDesklet->container.pWidget), "leave-notify-event", G_CALLBACK (_cd_mixer_on_leave), NULL); } else if (! myConfig.bHideScaleOnLeave && iOnEnterCallbackID > 0) { g_signal_handler_disconnect (G_OBJECT (myDesklet->container.pWidget), iOnEnterCallbackID); gulong iOnLeaveCallbackID = g_signal_handler_find (myDesklet->container.pWidget, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, _cd_mixer_on_leave, NULL); g_signal_handler_disconnect (G_OBJECT (myDesklet->container.pWidget), iOnLeaveCallbackID); } } else { if (CD_APPLET_MY_CONTAINER_TYPE_CHANGED && myData.pScale) { gtk_widget_destroy (myData.pScale); myData.pScale = NULL; } if (myIcon->cName == NULL) { CD_APPLET_SET_NAME_FOR_MY_ICON (myData.mixer_card_name); } } } else { ///\_______________ On redessine notre icone. if (myDesklet && myDesklet->container.iHeight <= 64) gtk_widget_hide (myData.pScale); /**if (myConfig.iVolumeEffect != VOLUME_EFFECT_NONE) CD_APPLET_RELOAD_MY_DATA_RENDERER (NULL); cd_update_icon ();*/ } CD_APPLET_RELOAD_END cairo-dock-plugins-3.3.2/alsaMixer/src/applet-backend-sound-menu-old.c000775 001750 001750 00000014243 12223247501 026752 0ustar00mbaertsmbaerts000000 000000 /** * This file is a part of the Cairo-Dock project * * Copyright : (C) see the 'copyright' file. * based on indicator-messages.c written by : * Ted Gould * Cody Russell * 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 #if (SOUND_SERVICE_VERSION < 1) #include "dbus-shared-names-old.h" #else #include "dbus-shared-names.h" #endif #include "applet-struct.h" #include "common-defs.h" #include "volume-widget.h" #include "mute-widget.h" #include "applet-menu.h" #include "applet-backend-alsamixer.h" // cd_mixer_init_alsa (fallback alsa backend) #include "applet-generic.h" #include "applet-draw.h" #include "applet-backend-sound-menu-old.h" /* // we can use icons designed for Unity, or more common icons that we are likely to find in icons themes. static const gchar *_get_icon_from_state_unity (gint iState) { switch (iState) { case MUTED: return "audio-volume-muted-panel"; case ZERO_LEVEL: return "audio-volume-low-zero-panel"; case LOW_LEVEL: return "audio-volume-low-panel"; case MEDIUM_LEVEL: return "audio-volume-medium-panel"; case HIGH_LEVEL: return "audio-volume-high-panel"; case BLOCKED: return "audio-volume-muted-blocking-panel"; default: return "audio-output-none-panel"; } } static const gchar *_get_icon_from_state (gint iState) { switch (iState) { case ZERO_LEVEL: return "audio-volume-off"; case LOW_LEVEL: return "audio-volume-low"; case MEDIUM_LEVEL: return "audio-volume-medium"; case HIGH_LEVEL: return "audio-volume-high"; default: return "audio-volume-muted"; } }*/ /////////// // PROXY // /////////// static void on_sound_state_updated (DBusGProxy * proxy, gint iNewState, GldiModuleInstance *myApplet) { cd_debug ("%s (iNewState : %d)", __func__, iNewState); CD_APPLET_ENTER; if (iNewState != myData.iCurrentState) { myData.iCurrentState = iNewState; gboolean bIsMute = (iNewState == MUTED || iNewState == UNAVAILABLE || iNewState == BLOCKED); if (myData.bIsMute != bIsMute) { myData.bIsMute = bIsMute; cd_update_icon (); } } CD_APPLET_LEAVE(); } static int _get_volume (void) { if (myData.volume_widget) return (int)volume_widget_get_current_volume (myData.volume_widget); else return 0; } static void _set_volume (int iVolume) { if (myData.volume_widget) volume_widget_update (VOLUME_WIDGET(myData.volume_widget), (gdouble)iVolume, "scroll updates"); } static void _toggle_mute (void) { if (myData.mute_widget) mute_widget_toggle (MUTE_WIDGET (myData.mute_widget)); } static void _show_menu (void) { cd_indicator_show_menu (myData.pIndicator); } static void _stop (void) { cd_indicator_destroy (myData.pIndicator); g_list_free (myData.transport_widgets_list); } static void cd_sound_on_connect (GldiModuleInstance *myApplet) { cd_debug ("%s ()", __func__); // the sound service is up and running, stop the alsa mixer if ever we initialized it before. cd_stop (); // and set the interface myData.ctl.get_volume = _get_volume; myData.ctl.set_volume = _set_volume; myData.ctl.toggle_mute = _toggle_mute; myData.ctl.show_hide = _show_menu; myData.ctl.stop = _stop; myData.ctl.reload = cd_update_icon; // connect to the service signals. dbus_g_proxy_add_signal(myData.pIndicator->pServiceProxy, INDICATOR_SOUND_SIGNAL_STATE_UPDATE, G_TYPE_INT, G_TYPE_INVALID); dbus_g_proxy_connect_signal(myData.pIndicator->pServiceProxy, INDICATOR_SOUND_SIGNAL_STATE_UPDATE, G_CALLBACK(on_sound_state_updated), myApplet, NULL); } static void cd_sound_on_disconnect (GldiModuleInstance *myApplet) { CD_APPLET_ENTER; cd_debug ("%s", __func__); if (myData.ctl.get_volume == _get_volume) // the backend was set, unset it { memset (&myData.ctl, 0, sizeof (CDSoundCtl)); cd_debug ("clean"); myData.volume_widget = NULL; myData.transport_widgets_list = NULL; myData.voip_widget = NULL; myData.mute_widget = NULL; } // no (more) sound service, now rely on alsa. cd_mixer_init_alsa (); CD_APPLET_LEAVE(); } static void _on_got_sound_state (DBusGProxy *proxy, DBusGProxyCall *call_id, GldiModuleInstance *myApplet) { CD_APPLET_ENTER; int iCurrentState = 0; gboolean bSuccess = dbus_g_proxy_end_call (proxy, call_id, NULL, G_TYPE_INT, &iCurrentState, G_TYPE_INVALID); cd_debug ("got sound state: %d", iCurrentState); // update the icon. if (bSuccess) { myData.iCurrentState = iCurrentState; myData.bIsMute = (iCurrentState == MUTED || iCurrentState == UNAVAILABLE || iCurrentState == BLOCKED); myData.iCurrentVolume = _get_volume (); cd_update_icon (); } CD_APPLET_LEAVE(); } static void cd_sound_get_initial_values (GldiModuleInstance *myApplet) { // query the service to display initial values. dbus_g_proxy_begin_call (myData.pIndicator->pServiceProxy, "GetSoundState", (DBusGProxyCallNotify)_on_got_sound_state, myApplet, (GDestroyNotify) NULL, G_TYPE_INVALID); } void update_accessible_desc (double new_value) { cd_debug ("%s (%p)", __func__, myData.volume_widget); if (!myData.volume_widget) return; myData.iCurrentVolume = (new_value < 0 ? _get_volume() : new_value); cd_update_icon (); } void cd_mixer_connect_to_sound_service (void) { myData.pIndicator = cd_indicator_new (myApplet, INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_SERVICE_DBUS_OBJECT_PATH, INDICATOR_SOUND_DBUS_INTERFACE, INDICATOR_SOUND_MENU_DBUS_OBJECT_PATH, 0); myData.pIndicator->on_connect = cd_sound_on_connect; myData.pIndicator->on_disconnect = cd_sound_on_disconnect; myData.pIndicator->get_initial_values = cd_sound_get_initial_values; myData.pIndicator->add_menu_handler = cd_sound_add_menu_handler; } cairo-dock-plugins-3.3.2/alsaMixer/src/applet-draw.c000775 001750 001750 00000004630 12225027055 023455 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-generic.h" #include "applet-draw.h" void cd_update_icon (void) { gboolean bNeedRedraw = FALSE; // update the volume info switch (myConfig.iVolumeDisplay) { case VOLUME_ON_LABEL : CD_APPLET_SET_NAME_FOR_MY_ICON_PRINTF ("%s: %d%%", myData.mixer_card_name?myData.mixer_card_name:D_("Volume"), myData.iCurrentVolume); break; case VOLUME_ON_ICON : CD_APPLET_SET_QUICK_INFO_ON_MY_ICON_PRINTF ("%d%%", myData.iCurrentVolume); bNeedRedraw = TRUE; break; default : break; } // update the icon representation switch (myConfig.iVolumeEffect) // set the icon if needed { case VOLUME_EFFECT_NONE : case VOLUME_EFFECT_BAR : if (myData.bMuteImage < 0 || (myData.bIsMute != myData.bMuteImage)) { if (myData.bIsMute) CD_APPLET_SET_USER_IMAGE_ON_MY_ICON (myConfig.cMuteIcon, "mute.svg"); else CD_APPLET_SET_USER_IMAGE_ON_MY_ICON (myConfig.cDefaultIcon, "default.svg"); myData.bMuteImage = myData.bIsMute; bNeedRedraw = FALSE; } break; default : break; } switch (myConfig.iVolumeEffect) // render the value { case VOLUME_EFFECT_BAR : case VOLUME_EFFECT_GAUGE : { double fPercent; if (myData.bIsMute) fPercent = CAIRO_DATA_RENDERER_UNDEF_VALUE; else fPercent = (double) myData.iCurrentVolume / 100.; CD_APPLET_RENDER_NEW_DATA_ON_MY_ICON (&fPercent); bNeedRedraw = FALSE; } break; default : break; } if (bNeedRedraw) CD_APPLET_REDRAW_MY_ICON; if (myData.pScale) { cd_mixer_set_volume_with_no_callback (myData.pScale, myData.iCurrentVolume); } } cairo-dock-plugins-3.3.2/alsaMixer/src/applet-draw.h000775 001750 001750 00000001571 12223247501 023461 0ustar00mbaertsmbaerts000000 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 __APPLET_DRAW__ #define __APPLET_DRAW__ #include void cd_update_icon (void); #endif cairo-dock-plugins-3.3.2/alsaMixer/src/applet-backend-sound-menu-old.h000775 001750 001750 00000001710 12223247501 026752 0ustar00mbaertsmbaerts000000 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 __APPLET_SOUND_OLD__ #define __APPLET_SOUND_OLD__ #include void update_accessible_desc (double new_value); void cd_mixer_connect_to_sound_service (void); #endif cairo-dock-plugins-3.3.2/alsaMixer/src/applet-notifications.c000775 001750 001750 00000007242 12223247501 025371 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-generic.h" #include "applet-notifications.h" static const gchar *s_cMixerCmd = NULL; static gboolean bMixerChecked = FALSE; CD_APPLET_ON_CLICK_BEGIN cd_show_hide (); CD_APPLET_ON_CLICK_END static void _check_mixer_cmd (void) { // check for Gnome2 before Gnome3, since during the transition, both were present, and "gnome-control-center sound" didn't work (and it was anyway just a shortcut to gnome-volume-control). gchar *cResult = cairo_dock_launch_command_sync ("which gnome-volume-control"); // Gnome2 if (cResult != NULL && *cResult == '/') s_cMixerCmd = "gnome-volume-control -p applications"; else { g_free (cResult); cResult = cairo_dock_launch_command_sync ("which gnome-control-center"); // Gnome3 if (cResult != NULL && *cResult == '/') /// TODO: other DE... s_cMixerCmd = "gnome-control-center sound"; } /// TODO: handle other DE ... g_free (cResult); } static void _mixer_show_advanced_mixer (GtkMenuItem *menu_item, gpointer data) { CD_APPLET_ENTER; GError *erreur = NULL; if (myConfig.cShowAdvancedMixerCommand != NULL) { g_spawn_command_line_async (myConfig.cShowAdvancedMixerCommand, &erreur); } else if (s_cMixerCmd != NULL) { g_spawn_command_line_async (s_cMixerCmd, &erreur); } if (erreur != NULL) { cd_warning ("Attention : when trying to execute '%s' : %s", myConfig.cShowAdvancedMixerCommand, erreur->message); g_error_free (erreur); } CD_APPLET_LEAVE(); } CD_APPLET_ON_BUILD_MENU_BEGIN gchar *cLabel; if (!myConfig.cShowAdvancedMixerCommand && !bMixerChecked) { bMixerChecked = TRUE; _check_mixer_cmd (); } if (myConfig.cShowAdvancedMixerCommand || s_cMixerCmd) { cLabel = g_strdup_printf ("%s (%s)", D_("Adjust channels"), D_("double-click")); CD_APPLET_ADD_IN_MENU_WITH_STOCK (cLabel, GTK_STOCK_PREFERENCES, _mixer_show_advanced_mixer, CD_APPLET_MY_MENU); g_free (cLabel); } cLabel = g_strdup_printf ("%s (%s)", (myData.bIsMute ? D_("Unmute") : D_("Mute")), D_("middle-click")); CD_APPLET_ADD_IN_MENU_WITH_STOCK (cLabel, MY_APPLET_SHARE_DATA_DIR"/emblem-mute.svg", cd_toggle_mute, CD_APPLET_MY_MENU); g_free (cLabel); CD_APPLET_ON_BUILD_MENU_END CD_APPLET_ON_MIDDLE_CLICK_BEGIN cd_toggle_mute (); CD_APPLET_ON_MIDDLE_CLICK_END CD_APPLET_ON_DOUBLE_CLICK_BEGIN if (!myConfig.cShowAdvancedMixerCommand && !bMixerChecked) { bMixerChecked = TRUE; _check_mixer_cmd (); // looking for s_cMixerCmd } _mixer_show_advanced_mixer (NULL, NULL); CD_APPLET_ON_DOUBLE_CLICK_END CD_APPLET_ON_SCROLL_BEGIN double delta; if (CD_APPLET_SCROLL_UP) delta = myConfig.iScrollVariation; else delta = - myConfig.iScrollVariation; int iVolume = cd_get_volume (); iVolume = MAX (0, MIN (iVolume + delta, 100)); cd_set_volume (iVolume); CD_APPLET_ON_SCROLL_END void mixer_on_keybinding_pull (const char *keystring, gpointer user_data) { CD_APPLET_ENTER; cd_show_hide (); CD_APPLET_LEAVE(); } cairo-dock-plugins-3.3.2/alsaMixer/src/applet-backend-sound-menu.c000775 001750 001750 00000006026 12223247501 026176 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-generic.h" #include "applet-backend-alsamixer.h" // cd_mixer_init_alsa #include "applet-backend-sound-menu.h" static void _show_menu (void); static void (*_stop_parent) (void) = NULL; static void (*_show_menu_parent) (void) = NULL; static void _entry_added (IndicatorObject *pIndicator, IndicatorObjectEntry *pEntry, GldiModuleInstance *myApplet) { cd_debug ("Entry Added: %p", pEntry); g_return_if_fail (myData.pEntry == NULL && pEntry != NULL); // should not happen... only one entry myData.pEntry = pEntry; } static void _entry_removed (IndicatorObject *pIndicator, IndicatorObjectEntry *pEntry, GldiModuleInstance *myApplet) { // should not happen... except at the end. cd_debug ("Entry Removed"); // no (more) sound service... now rely on alsa to display the menu/dialog. if (myData.pEntry == pEntry) // the same entry as before, we can remove the previous one { myData.pEntry = NULL; } } static void _show_menu (void) { GtkMenu *pMenu = NULL; if (myData.pEntry) pMenu = cd_indicator3_get_menu (myData.pEntry); if (pMenu) { GList *entries = gtk_container_get_children (GTK_CONTAINER (pMenu)); if (entries) // if the menu is ok { CD_APPLET_POPUP_MENU_ON_MY_ICON (GTK_WIDGET (pMenu)); g_list_free (entries); } else // else, the daemon was probaby not launched. pMenu = NULL; } if (!pMenu) // if no menu, it's maybe because the daemon has not started, or has stopped (the entry is not removed). { if (_show_menu_parent) _show_menu_parent (); } } static void _stop (void) { _entry_removed (myData.pIndicator, myData.pEntry, myApplet); if (_stop_parent) _stop_parent (); } void cd_mixer_connect_to_sound_service (void) { // load the indicator (we only want its menu, label and image are set by us). myData.pIndicator = cd_indicator3_load (myConfig.cIndicatorName, _entry_added, _entry_removed, NULL, NULL, myApplet); // init the backend. we'll use the alsa backend (to get the exact volume and volume changes), and we'll override only the functions we need. cd_mixer_init_alsa (); // alsa backend if (myData.pIndicator) { _stop_parent = myData.ctl.stop; myData.ctl.stop = _stop; _show_menu_parent = myData.ctl.show_hide; myData.ctl.show_hide = _show_menu; // but with our menu } } cairo-dock-plugins-3.3.2/alsaMixer/src/applet-backend-alsamixer.c000775 001750 001750 00000031741 12223247501 026073 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-draw.h" #include "applet-generic.h" #include "applet-backend-alsamixer.h" static int mixer_level = 0; static struct snd_mixer_selem_regopt mixer_options; static gboolean mixer_is_mute (void); static int mixer_get_mean_volume (void); static gchar *_mixer_get_card_id_from_name (const gchar *cName) { if (cName == NULL) return g_strdup ("default"); int iCardID = -1; char *cName2; while (snd_card_next (&iCardID) == 0 && iCardID != -1) { snd_card_get_name (iCardID, &cName2); cd_debug ("+ card %d: %s", iCardID, cName2); if (! cName2) continue; if (strcmp (cName2, cName) == 0) { free (cName2); return g_strdup_printf ("hw:%d", iCardID); } free (cName2); } return g_strdup ("default"); } static void mixer_init (const gchar *cCardName) // this function is taken from AlsaMixer. { snd_ctl_card_info_t *hw_info = NULL; // ne pas liberer. snd_ctl_t *ctl_handle = NULL; int err; snd_ctl_card_info_alloca (&hw_info); // get the card ID gchar *cCardID = _mixer_get_card_id_from_name (cCardName); // get the card info if ((err = snd_ctl_open (&ctl_handle, cCardID, 0)) < 0) { myData.cErrorMessage = g_strdup_printf (D_("I couldn't open card '%s'"), cCardID); g_free (cCardID); return ; } if ((err = snd_ctl_card_info (ctl_handle, hw_info)) < 0) { myData.cErrorMessage = g_strdup_printf (D_("Card '%s' opened but I couldn't get any info"), cCardID); g_free (cCardID); return ; } snd_ctl_close (ctl_handle); // open mixer device if ((err = snd_mixer_open (&myData.mixer_handle, 0)) < 0) { myData.cErrorMessage = g_strdup (D_("I couldn't open the mixer")); g_free (cCardID); return ; } if (mixer_level == 0 && (err = snd_mixer_attach (myData.mixer_handle, cCardID)) < 0) { snd_mixer_free (myData.mixer_handle); myData.mixer_handle = NULL; g_free (cCardID); myData.cErrorMessage = g_strdup (D_("I couldn't attach the mixer to the card")); return ; } if ((err = snd_mixer_selem_register (myData.mixer_handle, mixer_level > 0 ? &mixer_options : NULL, NULL)) < 0) { snd_mixer_free (myData.mixer_handle); myData.mixer_handle = NULL; g_free (cCardID); myData.cErrorMessage = g_strdup (D_("I couldn't register options")); return ; } if ((err = snd_mixer_load (myData.mixer_handle)) < 0) { snd_mixer_free (myData.mixer_handle); myData.mixer_handle = NULL; g_free (cCardID); myData.cErrorMessage = g_strdup (D_("I couldn't load the mixer")); return ; } myData.mixer_card_name = g_strdup (snd_ctl_card_info_get_name(hw_info)); myData.mixer_device_name = g_strdup (snd_ctl_card_info_get_mixername(hw_info)); cd_debug ("myData.mixer_card_name : %s ; myData.mixer_device_name : %s", myData.mixer_card_name, myData.mixer_device_name); g_free (cCardID); } void mixer_stop (void) { if (myData.mixer_handle != NULL) { gchar *cCardID = _mixer_get_card_id_from_name (myConfig.card_id); snd_mixer_detach (myData.mixer_handle, cCardID); g_free (cCardID); snd_mixer_close (myData.mixer_handle); myData.mixer_handle = NULL; myData.pControledElement = NULL; myData.pControledElement2 = NULL; g_free (myData.cErrorMessage); myData.cErrorMessage = NULL; g_free (myData.mixer_card_name); myData.mixer_card_name = NULL; g_free (myData.mixer_device_name); myData.mixer_device_name= NULL; } } GList *mixer_get_cards_list (void) { int iCardID; char *cName; GList *pList = NULL; pList = g_list_append (pList, (gpointer) g_strdup("")); for (iCardID = 0; snd_card_get_name (iCardID, &cName) >= 0; iCardID ++) { pList = g_list_append (pList, (gpointer) cName); } return pList; } GList *mixer_get_elements_list (void) { snd_mixer_elem_t *elem; if (myData.mixer_handle == NULL) return NULL; cd_message (""); GList *pList = NULL; for (elem = snd_mixer_first_elem(myData.mixer_handle); elem; elem = snd_mixer_elem_next(elem)) { if (snd_mixer_selem_is_active (elem) && snd_mixer_selem_has_playback_volume (elem)) pList = g_list_prepend (pList, (gpointer)snd_mixer_selem_get_name (elem)); // la liste ne contiendra que des const, on ne supprimera pas ses elements lors du g_list_free. } return pList; } static snd_mixer_elem_t *_mixer_get_element_by_name (const gchar *cName) { if (myData.mixer_handle == NULL) return NULL; if (cName != NULL) { snd_mixer_elem_t *elem; for (elem = snd_mixer_first_elem(myData.mixer_handle); elem; elem = snd_mixer_elem_next(elem)) { if (strcmp (cName, snd_mixer_selem_get_name (elem)) == 0) return elem; } } cd_debug ("no channel matches '%s', we take the first available channel by default", cName); return snd_mixer_first_elem(myData.mixer_handle); /**myData.cErrorMessage = g_strdup_printf (D_("I couldn't find any audio channel named '%s'\nYou should try to open the configuration panel of the applet,\n and select the proper audio channel you want to control."), cName); return NULL;*/ } static int mixer_element_update_with_event (snd_mixer_elem_t *elem, unsigned int mask) { CD_APPLET_ENTER; cd_debug ("%s (%d)", __func__, mask); if (mask != SND_CTL_EVENT_MASK_REMOVE && (mask & SND_CTL_EVENT_MASK_VALUE)) // filter calls that can occur when we really don't want, like when closing the applet. { myData.iCurrentVolume = mixer_get_mean_volume (); myData.bIsMute = mixer_is_mute (); cd_debug (" iCurrentVolume <- %d bIsMute <- %d", myData.iCurrentVolume, myData.bIsMute); cd_update_icon (); } CD_APPLET_LEAVE(0); } static void mixer_get_controlled_element (void) { myData.pControledElement = _mixer_get_element_by_name (myConfig.cMixerElementName); if (myData.pControledElement != NULL) { myData.bHasMuteSwitch = snd_mixer_selem_has_playback_switch (myData.pControledElement); snd_mixer_selem_get_playback_volume_range (myData.pControledElement, &myData.iVolumeMin, &myData.iVolumeMax); cd_debug ("volume range : %d - %d", myData.iVolumeMin, myData.iVolumeMax); snd_mixer_elem_set_callback (myData.pControledElement, mixer_element_update_with_event); } if (myConfig.cMixerElementName2 != NULL) { myData.pControledElement2 = _mixer_get_element_by_name (myConfig.cMixerElementName2); } } static int mixer_get_mean_volume (void) { g_return_val_if_fail (myData.pControledElement != NULL, 0); long iVolumeLeft=0, iVolumeRight=0; gboolean bHasLeft = snd_mixer_selem_has_playback_channel (myData.pControledElement, SND_MIXER_SCHN_FRONT_LEFT); gboolean bHasRight = snd_mixer_selem_has_playback_channel (myData.pControledElement, SND_MIXER_SCHN_FRONT_RIGHT); g_return_val_if_fail (bHasLeft || bHasRight, 0); if (bHasLeft) snd_mixer_selem_get_playback_volume (myData.pControledElement, SND_MIXER_SCHN_FRONT_LEFT, &iVolumeLeft); if (bHasRight) snd_mixer_selem_get_playback_volume (myData.pControledElement, SND_MIXER_SCHN_FRONT_RIGHT, &iVolumeRight); cd_debug ("volume : %d;%d", iVolumeLeft, iVolumeRight); int iMeanVolume = (iVolumeLeft + iVolumeRight) / (bHasLeft + bHasRight); cd_debug ("myData.iVolumeMin : %d ; myData.iVolumeMax : %d ; iMeanVolume : %d", myData.iVolumeMin, myData.iVolumeMax, iMeanVolume); return (100. * (iMeanVolume - myData.iVolumeMin) / (myData.iVolumeMax - myData.iVolumeMin)); } static void _set_mute (gboolean bMute) { snd_mixer_selem_set_playback_switch_all (myData.pControledElement, !bMute); if (myData.pControledElement2 != NULL) snd_mixer_selem_set_playback_switch_all (myData.pControledElement2, !bMute); myData.bIsMute = bMute; } static void mixer_set_volume (int iNewVolume) { g_return_if_fail (myData.pControledElement != NULL); cd_debug ("%s (%d)", __func__, iNewVolume); int iVolume = ceil (myData.iVolumeMin + (myData.iVolumeMax - myData.iVolumeMin) * iNewVolume / 100.); snd_mixer_selem_set_playback_volume_all (myData.pControledElement, iVolume); if (myData.pControledElement2 != NULL) snd_mixer_selem_set_playback_volume_all (myData.pControledElement2, iVolume); myData.iCurrentVolume = iNewVolume; if (myData.bIsMute) { _set_mute (FALSE); } cd_update_icon (); // on ne recoit pas d'evenements pour nos actions. } static gboolean mixer_is_mute (void) { cd_debug (""); g_return_val_if_fail (myData.pControledElement != NULL, FALSE); if (snd_mixer_selem_has_playback_switch (myData.pControledElement)) { int iSwitchLeft, iSwitchRight; snd_mixer_selem_get_playback_switch (myData.pControledElement, SND_MIXER_SCHN_FRONT_LEFT, &iSwitchLeft); snd_mixer_selem_get_playback_switch (myData.pControledElement, SND_MIXER_SCHN_FRONT_RIGHT, &iSwitchRight); cd_debug ("%d;%d", iSwitchLeft, iSwitchRight); return (iSwitchLeft == 0 && iSwitchRight == 0); } else return FALSE; } static void mixer_switch_mute (void) { g_return_if_fail (myData.pControledElement != NULL); gboolean bIsMute = mixer_is_mute (); _set_mute (! bIsMute); cd_update_icon (); // on ne recoit pas d'evenements pour nos actions. } static void _on_dialog_destroyed (GldiModuleInstance *myApplet) { myData.pDialog = NULL; } static void mixer_show_hide_dialog (void) { if (myDesklet) return ; if (myData.pDialog == NULL) { const gchar *cMessage; GtkWidget *pScale = NULL; if (myData.cErrorMessage != NULL) cMessage = myData.cErrorMessage; else { cMessage = D_("Set up volume:"); pScale = mixer_build_widget (TRUE); } CairoDialogAttr attr; memset (&attr, 0, sizeof (CairoDialogAttr)); attr.cText = cMessage; attr.cImageFilePath = MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE; attr.pInteractiveWidget = pScale; attr.pUserData = myApplet; attr.pFreeDataFunc = (GFreeFunc)_on_dialog_destroyed; attr.pIcon = myIcon; attr.pContainer = myContainer; myData.pDialog = gldi_dialog_new (&attr); } else { gldi_object_unref (GLDI_OBJECT(myData.pDialog)); myData.pDialog = NULL; } } static void cd_mixer_stop_alsa (void) { if (myData.mixer_handle != NULL) { mixer_stop (); g_free (myData.cErrorMessage); myData.cErrorMessage = NULL; g_free (myData.mixer_card_name); myData.mixer_card_name = NULL; g_free (myData.mixer_device_name); myData.mixer_device_name= NULL; if (myData.iSidCheckVolume != 0) { g_source_remove (myData.iSidCheckVolume); myData.iSidCheckVolume = 0; } } } static gboolean mixer_check_events (gpointer data) { CD_APPLET_ENTER; CD_APPLET_LEAVE_IF_FAIL (myData.mixer_handle, FALSE); snd_mixer_handle_events (myData.mixer_handle); // ne renvoie pas d'evenements pour nos actions ! CD_APPLET_LEAVE(TRUE); } static void cd_mixer_reload_alsa (void) { myData.ctl.stop (); mixer_init (myConfig.card_id); mixer_get_controlled_element (); if (myData.pControledElement == NULL) { CD_APPLET_SET_USER_IMAGE_ON_MY_ICON (myConfig.cBrokenIcon, "broken.svg"); } else { mixer_element_update_with_event (myData.pControledElement, 1); // 1 => get the current state (card may have changed). myData.iSidCheckVolume = g_timeout_add (1000, (GSourceFunc) mixer_check_events, (gpointer) NULL); } } void cd_mixer_init_alsa (void) { // connect to the sound card mixer_init (myConfig.card_id); // get the mixer element mixer_get_controlled_element (); // update the icon if (myData.pControledElement == NULL) // no luck { CD_APPLET_SET_USER_IMAGE_ON_MY_ICON (myConfig.cBrokenIcon, "broken.svg"); } else // mixer aquired { // set the interface myData.ctl.get_volume = mixer_get_mean_volume; myData.ctl.set_volume = mixer_set_volume; myData.ctl.toggle_mute = mixer_switch_mute; myData.ctl.show_hide = mixer_show_hide_dialog; myData.ctl.stop = cd_mixer_stop_alsa; myData.ctl.reload = cd_mixer_reload_alsa; // build the scale now if we're in a desklet if (myDesklet) { GtkWidget *box = _gtk_hbox_new (0); myData.pScale = mixer_build_widget (FALSE); gtk_box_pack_end (GTK_BOX (box), myData.pScale, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (myDesklet->container.pWidget), box); gtk_widget_show_all (box); if (myConfig.bHideScaleOnLeave && ! myDesklet->container.bInside) gtk_widget_hide (myData.pScale); } else if (myIcon->cName == NULL) // in dock, set the label { CD_APPLET_SET_NAME_FOR_MY_ICON (myData.mixer_card_name); } // trigger the callback to update the icon mixer_element_update_with_event (myData.pControledElement, 1); // 1 => get the current state. myData.iSidCheckVolume = g_timeout_add (1000, (GSourceFunc) mixer_check_events, (gpointer) NULL); } } cairo-dock-plugins-3.3.2/alsaMixer/src/applet-config.c000775 001750 001750 00000013627 12223247501 023771 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-backend-alsamixer.h" // mixer_get_elements_list #include "applet-notifications.h" #include "applet-config.h" CD_APPLET_GET_CONFIG_BEGIN //\_________________ On recupere toutes les valeurs de notre fichier de conf. myConfig.card_id = CD_CONFIG_GET_STRING ("Configuration", "card id"); gchar *cMixerElementName = CD_CONFIG_GET_STRING ("Configuration", "mixer element"); gchar *cMixerElementName2 = CD_CONFIG_GET_STRING ("Configuration", "mixer element 2"); if (cMixerElementName != NULL && cMixerElementName2 != NULL && strcmp (cMixerElementName, cMixerElementName2) == 0) { myConfig.cMixerElementName = g_strconcat (cMixerElementName, ",0", NULL); myConfig.cMixerElementName2 = g_strconcat (cMixerElementName, ",1", NULL); g_free (cMixerElementName); } else { myConfig.cMixerElementName = cMixerElementName; myConfig.cMixerElementName2 = cMixerElementName2; } myConfig.cShowAdvancedMixerCommand = CD_CONFIG_GET_STRING ("Configuration", "show mixer"); myConfig.cShortcut = CD_CONFIG_GET_STRING ("Configuration", "shortkey"); myConfig.iScrollVariation = CD_CONFIG_GET_INTEGER ("Configuration", "scroll variation"); myConfig.bHideScaleOnLeave = CD_CONFIG_GET_BOOLEAN ("Configuration", "hide on leave"); myConfig.iVolumeDisplay = CD_CONFIG_GET_INTEGER ("Configuration", "display volume"); myConfig.iVolumeEffect = CD_CONFIG_GET_INTEGER_WITH_DEFAULT ("Configuration", "display icon", -1); if (myConfig.iVolumeEffect >= VOLUME_NB_EFFECTS) // new option (iVolumeEffect is an unsigned int) { myConfig.iVolumeEffect = CD_CONFIG_GET_INTEGER ("Configuration", "effect"); if (myConfig.iVolumeEffect == 1 || myConfig.iVolumeEffect == 2) // old "zoom" and "transparency" effects myConfig.iVolumeEffect = VOLUME_EFFECT_BAR; else if (myConfig.iVolumeEffect >= 3) // other options are offseted by 2 myConfig.iVolumeEffect -= 2; g_key_file_set_integer (CD_APPLET_MY_KEY_FILE, "Configuration", "display icon", myConfig.iVolumeEffect); } if (myConfig.iVolumeEffect == VOLUME_EFFECT_GAUGE) { myConfig.cGThemePath = CD_CONFIG_GET_GAUGE_THEME ("Configuration", "theme"); myConfig.iRotateTheme = CD_CONFIG_GET_INTEGER ("Configuration", "rotate theme"); } myConfig.cDefaultIcon = CD_CONFIG_GET_STRING ("Configuration", "default icon"); myConfig.cBrokenIcon = CD_CONFIG_GET_STRING ("Configuration", "broken icon"); myConfig.cMuteIcon = CD_CONFIG_GET_STRING ("Configuration", "mute icon"); #ifdef INDICATOR_SOUNDMENU_WITH_IND3 myConfig.cIndicatorName = CD_CONFIG_GET_STRING ("Configuration", "indicator name"); // we take it from the config just in case the name changes, it's not a visible option. if (myConfig.cIndicatorName == NULL) #ifdef IS_INDICATOR_NG myConfig.cIndicatorName = g_strdup ("com.canonical.indicator.sound"); #else myConfig.cIndicatorName = g_strdup ("libsoundmenu.so"); #endif #endif CD_APPLET_GET_CONFIG_END CD_APPLET_RESET_CONFIG_BEGIN g_free (myConfig.card_id); g_free (myConfig.cMixerElementName); g_free (myConfig.cMixerElementName2); g_free (myConfig.cShowAdvancedMixerCommand); g_free (myConfig.cShortcut); g_free (myConfig.cDefaultIcon); g_free (myConfig.cBrokenIcon); g_free (myConfig.cMuteIcon); g_free (myConfig.cGThemePath); #ifdef INDICATOR_SOUNDMENU_WITH_IND3 g_free (myConfig.cIndicatorName); #endif CD_APPLET_RESET_CONFIG_END CD_APPLET_RESET_DATA_BEGIN if (myData.pScale != NULL) { gtk_widget_destroy (myData.pScale); myData.pScale = NULL; } gldi_object_unref (GLDI_OBJECT(myData.pDialog)); CD_APPLET_RESET_DATA_END void cd_mixer_load_custom_widget (GldiModuleInstance *myApplet, GKeyFile* pKeyFile, GSList *pWidgetList) // myApplet can be NULL { //\____________ build the list of available sound cards. GList *pList = mixer_get_cards_list (); //\____________ get the combo CairoDockGroupKeyWidget *pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Configuration", "card id"); GtkWidget *pCombo = cairo_dock_gui_get_first_widget (pGroupKeyWidget); g_return_if_fail (pCombo != NULL); cairo_dock_fill_combo_with_list (pCombo, pList, myApplet?myConfig.card_id:NULL); g_list_foreach (pList, (GFunc)free, NULL); g_list_free (pList); //\____________ On construit la liste des canaux a controler. if (myApplet) { pList = mixer_get_elements_list (); //\____________ On recupere la combo. pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Configuration", "mixer element"); pCombo = cairo_dock_gui_get_first_widget (pGroupKeyWidget); g_return_if_fail (pCombo != NULL); cairo_dock_fill_combo_with_list (pCombo, pList, myConfig.cMixerElementName); //\____________ Idem pour la 2eme, avec une entree vide au debut. pGroupKeyWidget = cairo_dock_gui_find_group_key_widget_in_list (pWidgetList, "Configuration", "mixer element 2"); pCombo = cairo_dock_gui_get_first_widget (pGroupKeyWidget); g_return_if_fail (pCombo != NULL); pList = g_list_prepend (pList, (gpointer)""); // on peut caster ici car tous les elements sont des const pour nous. cairo_dock_fill_combo_with_list (pCombo, pList, myConfig.cMixerElementName2); g_list_free (pList); // les elements appartiennent au mixer_handle. } } cairo-dock-plugins-3.3.2/alsaMixer/src/common-defs.h000664 001750 001750 00000007720 12223247501 023447 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2010 Canonical Ltd. Authors: Conor Curran This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 __COMMON_DEFS_H__ #define __COMMON_DEFS_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif typedef enum { MUTED, ZERO_LEVEL, LOW_LEVEL, MEDIUM_LEVEL, HIGH_LEVEL, BLOCKED, UNAVAILABLE, AVAILABLE }SoundState; typedef enum { TRANSPORT_ACTION_PREVIOUS, TRANSPORT_ACTION_PLAY_PAUSE, TRANSPORT_ACTION_NEXT, TRANSPORT_ACTION_REWIND, TRANSPORT_ACTION_FORWIND, TRANSPORT_ACTION_NO_ACTION }TransportAction; typedef enum { TRANSPORT_STATE_PLAYING, TRANSPORT_STATE_PAUSED, TRANSPORT_STATE_LAUNCHING }TransportState; #define NOT_ACTIVE -1 #define DBUSMENU_PROPERTY_EMPTY -1 /* DBUS Custom Items */ #define DBUSMENU_VOLUME_MENUITEM_TYPE "x-canonical-ido-volume-type" #define DBUSMENU_VOLUME_MENUITEM_LEVEL "x-canonical-ido-volume-level" #define DBUSMENU_VOLUME_MENUITEM_MUTE "x-canonical-ido-volume-mute" #define DBUSMENU_VOIP_INPUT_MENUITEM_TYPE "x-canonical-ido-voip-input-type" #define DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL "x-canonical-ido-voip-input-level" #define DBUSMENU_VOIP_INPUT_MENUITEM_MUTE "x-canonical-ido-voip-input-mute" #define DBUSMENU_MUTE_MENUITEM_TYPE "x-canonical-sound-menu-mute-type" #define DBUSMENU_MUTE_MENUITEM_VALUE "x-canonical-sound-menu-mute-value" #define DBUSMENU_TRANSPORT_MENUITEM_TYPE "x-canonical-sound-menu-player-transport-type" #define DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE "x-canonical-sound-menu-player-transport-state" #define DBUSMENU_TRACK_SPECIFIC_MENUITEM_TYPE "x-canonical-sound-menu-player-track-specific-type" #define DBUSMENU_METADATA_MENUITEM_TYPE "x-canonical-sound-menu-player-metadata-type" #define DBUSMENU_METADATA_MENUITEM_ARTIST "x-canonical-sound-menu-player-metadata-xesam:artist" #define DBUSMENU_METADATA_MENUITEM_TITLE "x-canonical-sound-menu-player-metadata-xesam:title" #define DBUSMENU_METADATA_MENUITEM_ALBUM "x-canonical-sound-menu-player-metadata-xesam:album" #define DBUSMENU_METADATA_MENUITEM_ARTURL "x-canonical-sound-menu-player-metadata-mpris:artUrl" #define DBUSMENU_METADATA_MENUITEM_PLAYER_NAME "x-canonical-sound-menu-player-metadata-player-name" #define DBUSMENU_METADATA_MENUITEM_PLAYER_ICON "x-canonical-sound-menu-player-metadata-player-icon" #define DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING "x-canonical-sound-menu-player-metadata-player-running" #define DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS "x-canonical-sound-menu-player-metadata-hide-track-details" #define DBUSMENU_SCRUB_MENUITEM_TYPE "x-canonical-sound-menu-player-scrub-type" #define DBUSMENU_SCRUB_MENUITEM_DURATION "x-canonical-sound-menu-player-scrub-mpris:length" #define DBUSMENU_SCRUB_MENUITEM_POSITION "x-canonical-sound-menu-player-scrub-position" #define DBUSMENU_SCRUB_MENUITEM_PLAY_STATE "x-canonical-sound-menu-player-scrub-play-state" #define DBUSMENU_PLAYLISTS_MENUITEM_TYPE "x-canonical-sound-menu-player-playlists-type" #define DBUSMENU_PLAYLISTS_MENUITEM_TITLE "x-canonical-sound-menu-player-playlists-title" #define DBUSMENU_PLAYLISTS_MENUITEM_PLAYLISTS "x-canonical-sound-menu-player-playlists-playlists" #define DBUSMENU_PLAYLIST_MENUITEM_PATH "x-canonical-sound-menu-player-playlist-path" #endif cairo-dock-plugins-3.3.2/alsaMixer/src/metadata-widget.c000664 001750 001750 00000105654 12223247501 024301 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2010 Canonical Ltd. Authors: Conor Curran Mirco Müller This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "metadata-widget.h" #include "common-defs.h" #include #include #include "transport-widget.h" typedef struct _MetadataWidgetPrivate MetadataWidgetPrivate; struct _MetadataWidgetPrivate { gboolean theme_change_occured; GtkWidget* meta_data_h_box; GtkWidget* meta_data_v_box; GtkWidget* album_art; GString* image_path; GString* old_image_path; GtkWidget* artist_label; GtkWidget* piece_label; GtkWidget* container_label; GtkWidget* player_label; GdkPixbuf* icon_buf; DbusmenuMenuitem* twin_item; gint current_height; }; #define METADATA_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), METADATA_WIDGET_TYPE, MetadataWidgetPrivate)) /* Prototypes */ static void metadata_widget_class_init (MetadataWidgetClass *klass); static void metadata_widget_init (MetadataWidget *self); static void metadata_widget_dispose (GObject *object); static void metadata_widget_finalize (GObject *object); static void metadata_widget_set_style (GtkWidget* button, GtkStyle* style); static void metadata_widget_set_twin_item (MetadataWidget* self, DbusmenuMenuitem* twin_item); // keyevent consumers static gboolean metadata_widget_button_release_event (GtkWidget *menuitem, GdkEventButton *event); // Dbusmenuitem properties update callback static void metadata_widget_property_update (DbusmenuMenuitem* item, gchar* property, GVariant* value, gpointer userdata); static void metadata_widget_style_labels ( MetadataWidget* self, GtkLabel* label); static void metadata_widget_selection_received_event_callback( GtkWidget *widget, GtkSelectionData *data, guint time, gpointer user_data); #if GTK_CHECK_VERSION(3, 0, 0) static void metadata_widget_get_preferred_width (GtkWidget* self, gint* minimum_width, gint* natural_width); static void draw_album_art_placeholder_gtk_3 (GtkWidget *metadata, cairo_t* cr); static void draw_album_border_gtk_3 (GtkWidget *metadata, gboolean selected, cairo_t* cr); static gboolean metadata_widget_icon_triangle_draw_cb_gtk_3 (GtkWidget *image, cairo_t* cr, gpointer user_data); static gboolean metadata_image_expose_gtk_3 (GtkWidget *image, cairo_t* cr, gpointer user_data); #else static void draw_album_art_placeholder (GtkWidget *metadata); static void draw_album_border (GtkWidget *metadata, gboolean selected); static gboolean metadata_widget_icon_triangle_draw_cb (GtkWidget *image, GdkEventExpose *event, gpointer user_data); static gboolean metadata_image_expose (GtkWidget *image, GdkEventExpose *event, gpointer user_data); #endif static void metadata_widget_set_icon (MetadataWidget *self); static void metadata_widget_handle_resizing (MetadataWidget* self); G_DEFINE_TYPE (MetadataWidget, metadata_widget, GTK_TYPE_MENU_ITEM); static void metadata_widget_class_init (MetadataWidgetClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); widget_class->button_release_event = metadata_widget_button_release_event; #if GTK_CHECK_VERSION(3, 0, 0) widget_class->get_preferred_width = metadata_widget_get_preferred_width; #endif g_type_class_add_private (klass, sizeof (MetadataWidgetPrivate)); gobject_class->dispose = metadata_widget_dispose; gobject_class->finalize = metadata_widget_finalize; } static void metadata_widget_init (MetadataWidget *self) { MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); GtkWidget *hbox; GtkWidget *outer_v_box; priv->icon_buf = NULL; outer_v_box = _gtk_vbox_new (0); hbox = _gtk_hbox_new(0); priv->meta_data_h_box = hbox; priv->current_height = 1; // image priv->album_art = gtk_image_new(); priv->image_path = g_string_new(""); priv->old_image_path = g_string_new(""); #if GTK_CHECK_VERSION(3, 0, 0) g_signal_connect(priv->album_art, "draw", G_CALLBACK(metadata_image_expose_gtk_3), GTK_WIDGET(self)); g_signal_connect_after (GTK_WIDGET(self), "draw", G_CALLBACK(metadata_widget_icon_triangle_draw_cb_gtk_3), GTK_WIDGET(self)); #else g_signal_connect(priv->album_art, "expose-event", G_CALLBACK(metadata_image_expose), GTK_WIDGET(self)); g_signal_connect_after (GTK_WIDGET(self), "expose-event", G_CALLBACK(metadata_widget_icon_triangle_draw_cb), GTK_WIDGET(self)); #endif gtk_box_pack_start (GTK_BOX (priv->meta_data_h_box), priv->album_art, FALSE, FALSE, 1); priv->theme_change_occured = FALSE; GtkWidget* vbox = _gtk_vbox_new(0); // artist GtkWidget* artist; artist = gtk_label_new(""); gtk_misc_set_alignment(GTK_MISC(artist), (gfloat)0, (gfloat)0); gtk_misc_set_padding (GTK_MISC(artist), (gfloat)10, (gfloat)0); gtk_widget_set_size_request (artist, 140, 15); gtk_label_set_ellipsize(GTK_LABEL(artist), PANGO_ELLIPSIZE_MIDDLE); metadata_widget_style_labels(self, GTK_LABEL(artist)); priv->artist_label = artist; // title GtkWidget* piece; piece = gtk_label_new(""); gtk_misc_set_alignment(GTK_MISC(piece), (gfloat)0, (gfloat)0); gtk_misc_set_padding (GTK_MISC(piece), (gfloat)10, (gfloat)-5); gtk_widget_set_size_request (piece, 140, 15); gtk_label_set_ellipsize(GTK_LABEL(piece), PANGO_ELLIPSIZE_MIDDLE); metadata_widget_style_labels(self, GTK_LABEL(piece)); priv->piece_label = piece; // container GtkWidget* container; container = gtk_label_new(""); gtk_misc_set_alignment(GTK_MISC(container), (gfloat)0, (gfloat)0); gtk_misc_set_padding (GTK_MISC(container), (gfloat)10, (gfloat)0); gtk_widget_set_size_request (container, 140, 15); gtk_label_set_ellipsize(GTK_LABEL(container), PANGO_ELLIPSIZE_MIDDLE); metadata_widget_style_labels(self, GTK_LABEL(container)); priv->container_label = container; gtk_box_pack_start (GTK_BOX (vbox), priv->piece_label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), priv->artist_label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), priv->container_label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (priv->meta_data_h_box), vbox, FALSE, FALSE, 0); g_signal_connect(self, "style-set", G_CALLBACK(metadata_widget_set_style), GTK_WIDGET(self)); g_signal_connect (self, "selection-received", G_CALLBACK(metadata_widget_selection_received_event_callback), GTK_WIDGET(self)); // player label GtkWidget* player_label; player_label = gtk_label_new(""); gtk_misc_set_alignment(GTK_MISC(player_label), (gfloat)0, (gfloat)0); gtk_misc_set_padding (GTK_MISC(player_label), (gfloat)1, (gfloat)4); gtk_widget_set_size_request (player_label, 150, 24); priv->player_label = player_label; gtk_box_pack_start (GTK_BOX(outer_v_box), priv->player_label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX(outer_v_box), priv->meta_data_h_box, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (self), outer_v_box); gtk_widget_show_all (priv->meta_data_h_box); gtk_widget_set_no_show_all (priv->meta_data_h_box, TRUE); gtk_widget_hide (priv->meta_data_h_box); } static void metadata_widget_dispose (GObject *object) { MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(object)); if (priv->icon_buf != NULL){ g_object_unref (priv->icon_buf); priv->icon_buf = NULL; } g_string_free (priv->image_path, TRUE); priv->image_path = NULL; g_string_free (priv->old_image_path, TRUE); priv->old_image_path = NULL; G_OBJECT_CLASS (metadata_widget_parent_class)->dispose (object); } static void metadata_widget_finalize (GObject *object) { G_OBJECT_CLASS (metadata_widget_parent_class)->finalize (object); } #if GTK_CHECK_VERSION(3, 0, 0) static void metadata_widget_get_preferred_width (GtkWidget* self, gint* minimum_width, gint* natural_width) { *minimum_width = *natural_width = 200; } static void draw_album_border_gtk_3(GtkWidget *metadata, gboolean selected, cairo_t *cr) { gtk_style_context_add_class (gtk_widget_get_style_context (metadata), "menu"); int x, y, width, height; x = 0; y = 0; width = gtk_widget_get_allocated_width (metadata); height = gtk_widget_get_allocated_height (metadata); gint offset = 1; width = width + (offset * 2); height = height + (offset * 2) - 7; x = x - offset; y = y - offset + 3; gint state = selected ? 5 : 0; CairoColorRGB bg_normal, fg_normal; GtkStyleContext *style = gtk_widget_get_style_context (metadata); gtk_style_context_get_background_color (style, 0, (GdkRGBA*)&bg_normal); gtk_style_context_get_color (style, state, (GdkRGBA*)&fg_normal); CairoColorRGB dark_top_color; CairoColorRGB light_bottom_color; CairoColorRGB background_color; _color_shade ( &bg_normal, 0.93, &background_color ); _color_shade ( &bg_normal, 0.23, &dark_top_color ); _color_shade ( &fg_normal, 0.55, &light_bottom_color ); cairo_rectangle (cr, x, y, width, height); cairo_set_line_width (cr, 1.0); cairo_clip ( cr ); /// seems redundant here ... cairo_move_to (cr, x, y ); cairo_line_to (cr, x + width, y ); cairo_line_to ( cr, x + width, y + height ); cairo_line_to ( cr, x, y + height ); cairo_line_to ( cr, x, y); cairo_close_path (cr); cairo_set_source_rgba ( cr, background_color.r, background_color.g, background_color.b, 1.0 ); cairo_fill ( cr ); cairo_move_to (cr, x, y ); cairo_line_to (cr, x + width, y ); cairo_close_path (cr); cairo_set_source_rgba ( cr, dark_top_color.r, dark_top_color.g, dark_top_color.b, 1.0 ); cairo_stroke ( cr ); cairo_move_to ( cr, x + width, y + height ); cairo_line_to ( cr, x, y + height ); cairo_close_path (cr); cairo_set_source_rgba ( cr, light_bottom_color.r, light_bottom_color.g, light_bottom_color.b, 1.0); cairo_stroke ( cr ); } static void draw_album_art_placeholder_gtk_3(GtkWidget *metadata, cairo_t *cr) { int x, y, width; x = 0; y = 0; width = gtk_widget_get_allocated_width (metadata); PangoLayout *layout; PangoFontDescription *desc; layout = pango_cairo_create_layout(cr); PangoContext* pcontext = pango_cairo_create_context(cr); pango_cairo_context_set_resolution (pcontext, 96); GString* string = g_string_new(""); gssize size = -1; gunichar code = g_utf8_get_char_validated("\342\231\253", size); g_string_append_unichar (string, code); pango_layout_set_text(layout, string->str, -1); desc = pango_font_description_from_string("Sans Bold 30"); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); CairoColorRGB fg_normal, light_bottom_color; GtkStyleContext *style = gtk_widget_get_style_context (metadata); gtk_style_context_get_color (style, 0, (GdkRGBA*)&fg_normal); _color_shade ( &fg_normal, 0.78, &light_bottom_color ); cairo_set_source_rgba (cr, light_bottom_color.r, light_bottom_color.g, light_bottom_color.b, 1.0); pango_cairo_update_layout(cr, layout); cairo_move_to (cr, x + width/6, y + 3); pango_cairo_show_layout(cr, layout); g_object_unref(layout); g_object_unref(pcontext); g_string_free (string, TRUE); } /** * We override the expose method to enable primitive drawing of the * empty album art image and rounded rectangles on the album art. */ static gboolean metadata_image_expose_gtk_3 (GtkWidget *metadata, cairo_t* cr, gpointer user_data) { g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); MetadataWidget* widget = METADATA_WIDGET(user_data); MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); if ( TRUE == dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(priv->twin_item), DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS)) { return FALSE; } if(priv->image_path->len > 0){ if(g_string_equal(priv->image_path, priv->old_image_path) == FALSE || priv->theme_change_occured == TRUE){ priv->theme_change_occured = FALSE; GdkPixbuf* pixbuf; pixbuf = gdk_pixbuf_new_from_file_at_size(priv->image_path->str, 60, 60, NULL); if(GDK_IS_PIXBUF(pixbuf) == FALSE){ gtk_image_clear ( GTK_IMAGE(priv->album_art)); gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); draw_album_border_gtk_3 (metadata, FALSE, cr); draw_album_art_placeholder_gtk_3(metadata, cr); return FALSE; } gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf); gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); draw_album_border_gtk_3 (metadata, FALSE, cr); g_string_erase (priv->old_image_path, 0, -1); g_string_overwrite (priv->old_image_path, 0, priv->image_path->str); g_object_unref(pixbuf); } return FALSE; } gtk_image_clear (GTK_IMAGE(priv->album_art)); gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); draw_album_border_gtk_3 (metadata, FALSE, cr); draw_album_art_placeholder_gtk_3(metadata, cr); return FALSE; } // Draw the triangle if the player is running ... static gboolean metadata_widget_icon_triangle_draw_cb_gtk_3 (GtkWidget *widget, cairo_t* cr, gpointer user_data) { g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); MetadataWidget* meta = METADATA_WIDGET(user_data); MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(meta); int x, y, height, arrow_width, arrow_height; arrow_width = 5; arrow_height = 9; x = 0; y = 0; height = gtk_widget_get_allocated_height (widget); gint offset = (height - gdk_pixbuf_get_height (priv->icon_buf)) / 2; // Draw player icon if (priv->icon_buf != NULL){ gdk_cairo_set_source_pixbuf (cr, priv->icon_buf, x + arrow_width + 1, y + offset); cairo_paint (cr); } // Draw triangle but only if the player is running. if (dbusmenu_menuitem_property_get_bool (priv->twin_item, DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING)){ y += height/2.0 - (double)arrow_height/2.0; cairo_set_line_width (cr, 1.0); cairo_move_to (cr, x, y); cairo_line_to (cr, x, y + arrow_height); cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0); cairo_close_path (cr); CairoColorRGB fg_normal; GtkStyleContext *style = gtk_widget_get_style_context (widget); gtk_style_context_get_color (style, gtk_widget_get_state(widget), (GdkRGBA*)&fg_normal); cairo_set_source_rgb (cr, fg_normal.r, fg_normal.g, fg_normal.b); cairo_fill (cr); } return FALSE; } // GTK 2 Expose handler #else static void draw_album_border(GtkWidget *metadata, gboolean selected) { cairo_t *cr; cr = gdk_cairo_create (gtk_widget_get_window (metadata)); #if GTK_CHECK_VERSION(3, 0, 0) gtk_style_context_add_class (gtk_widget_get_style_context (metadata), "menu"); #endif GtkStyle *style; style = gtk_widget_get_style (metadata); GtkAllocation alloc; gtk_widget_get_allocation (metadata, &alloc); gint offset = 1; alloc.width = alloc.width + (offset * 2); alloc.height = alloc.height + (offset * 2) - 7; alloc.x = alloc.x - offset; alloc.y = alloc.y - offset + 3; CairoColorRGB bg_normal, fg_normal; bg_normal.r = style->bg[0].red/65535.0; bg_normal.g = style->bg[0].green/65535.0; bg_normal.b = style->bg[0].blue/65535.0; gint state = selected ? 5 : 0; fg_normal.r = style->fg[state].red/65535.0; fg_normal.g = style->fg[state].green/65535.0; fg_normal.b = style->fg[state].blue/65535.0; CairoColorRGB dark_top_color; CairoColorRGB light_bottom_color; CairoColorRGB background_color; _color_shade ( &bg_normal, 0.93, &background_color ); _color_shade ( &bg_normal, 0.23, &dark_top_color ); _color_shade ( &fg_normal, 0.55, &light_bottom_color ); cairo_rectangle (cr, alloc.x, alloc.y, alloc.width, alloc.height); cairo_set_line_width (cr, 1.0); cairo_clip ( cr ); cairo_move_to (cr, alloc.x, alloc.y ); cairo_line_to (cr, alloc.x + alloc.width, alloc.y ); cairo_line_to ( cr, alloc.x + alloc.width, alloc.y + alloc.height ); cairo_line_to ( cr, alloc.x, alloc.y + alloc.height ); cairo_line_to ( cr, alloc.x, alloc.y); cairo_close_path (cr); cairo_set_source_rgba ( cr, background_color.r, background_color.g, background_color.b, 1.0 ); cairo_fill ( cr ); cairo_move_to (cr, alloc.x, alloc.y ); cairo_line_to (cr, alloc.x + alloc.width, alloc.y ); cairo_close_path (cr); cairo_set_source_rgba ( cr, dark_top_color.r, dark_top_color.g, dark_top_color.b, 1.0 ); cairo_stroke ( cr ); cairo_move_to ( cr, alloc.x + alloc.width, alloc.y + alloc.height ); cairo_line_to ( cr, alloc.x, alloc.y + alloc.height ); cairo_close_path (cr); cairo_set_source_rgba ( cr, light_bottom_color.r, light_bottom_color.g, light_bottom_color.b, 1.0); cairo_stroke ( cr ); cairo_destroy (cr); } static void draw_album_art_placeholder(GtkWidget *metadata) { cairo_t *cr; cr = gdk_cairo_create (gtk_widget_get_window (metadata)); GtkStyle *style; style = gtk_widget_get_style (metadata); GtkAllocation alloc; gtk_widget_get_allocation (metadata, &alloc); PangoLayout *layout; PangoFontDescription *desc; layout = pango_cairo_create_layout(cr); PangoContext* pcontext = pango_cairo_create_context(cr); pango_cairo_context_set_resolution (pcontext, 96); GString* string = g_string_new(""); gssize size = -1; gunichar code = g_utf8_get_char_validated("\342\231\253", size); g_string_append_unichar (string, code); pango_layout_set_text(layout, string->str, -1); desc = pango_font_description_from_string("Sans Bold 30"); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); CairoColorRGB fg_normal, light_bottom_color; fg_normal.r = style->fg[0].red/65535.0; fg_normal.g = style->fg[0].green/65535.0; fg_normal.b = style->fg[0].blue/65535.0; _color_shade ( &fg_normal, 0.78, &light_bottom_color ); cairo_set_source_rgba (cr, light_bottom_color.r, light_bottom_color.g, light_bottom_color.b, 1.0); pango_cairo_update_layout(cr, layout); cairo_move_to (cr, alloc.x + alloc.width/6, alloc.y + 3); pango_cairo_show_layout(cr, layout); g_object_unref(layout); g_object_unref(pcontext); g_string_free (string, TRUE); cairo_destroy (cr); } static gboolean metadata_image_expose (GtkWidget *metadata, GdkEventExpose *event, gpointer user_data) { g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); MetadataWidget* widget = METADATA_WIDGET(user_data); MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); if ( TRUE == dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(priv->twin_item), DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS)) { return FALSE; } draw_album_border(metadata, FALSE); if(priv->image_path->len > 0){ if(g_string_equal(priv->image_path, priv->old_image_path) == FALSE || priv->theme_change_occured == TRUE){ priv->theme_change_occured = FALSE; GdkPixbuf* pixbuf; pixbuf = gdk_pixbuf_new_from_file_at_size(priv->image_path->str, 60, 60, NULL); if(GDK_IS_PIXBUF(pixbuf) == FALSE){ gtk_image_clear ( GTK_IMAGE(priv->album_art)); gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); draw_album_art_placeholder(metadata); return FALSE; } gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf); gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); g_string_erase (priv->old_image_path, 0, -1); g_string_overwrite (priv->old_image_path, 0, priv->image_path->str); g_object_unref(pixbuf); } return FALSE; } gtk_image_clear (GTK_IMAGE(priv->album_art)); gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); draw_album_art_placeholder(metadata); return FALSE; } // Draw the triangle if the player is running ... static gboolean metadata_widget_icon_triangle_draw_cb (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); MetadataWidget* meta = METADATA_WIDGET(user_data); MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(meta); GtkStyle *style; cairo_t *cr; int x, y, arrow_width, arrow_height; arrow_width = 5; arrow_height = 9; style = gtk_widget_get_style (widget); cr = (cairo_t*) gdk_cairo_create (gtk_widget_get_window (widget)); GtkAllocation allocation; gtk_widget_get_allocation (widget, &allocation); x = allocation.x; y = allocation.y; gint offset = (allocation.height - gdk_pixbuf_get_height (priv->icon_buf)) / 2; // Draw player icon if (priv->icon_buf != NULL){ gdk_cairo_set_source_pixbuf (cr, priv->icon_buf, x + arrow_width + 1, y + offset); cairo_paint (cr); } // Draw triangle but only if the player is running. if (dbusmenu_menuitem_property_get_bool (priv->twin_item, DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING)){ y += allocation.height/2.0 - (double)arrow_height/2.0; cairo_set_line_width (cr, 1.0); cairo_move_to (cr, x, y); cairo_line_to (cr, x, y + arrow_height); cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0); cairo_close_path (cr); cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0, style->fg[gtk_widget_get_state(widget)].green/65535.0, style->fg[gtk_widget_get_state(widget)].blue/65535.0); cairo_fill (cr); } cairo_destroy (cr); return FALSE; } #endif static void metadata_widget_selection_received_event_callback ( GtkWidget *widget, GtkSelectionData *data, guint time, gpointer user_data ) { #if GTK_CHECK_VERSION(3, 0, 0) cairo_t *cr = (cairo_t*) gdk_cairo_create (gtk_widget_get_window (widget)); /// TODO: need to translate at the widget's position ... draw_album_border_gtk_3(widget, TRUE, cr); cairo_destroy (cr); #else draw_album_border(widget, TRUE); #endif } /* Suppress/consume keyevents */ static gboolean metadata_widget_button_release_event (GtkWidget *menuitem, GdkEventButton *event) { g_return_val_if_fail (IS_METADATA_WIDGET (menuitem), FALSE); MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(menuitem)); // For the left raise/launch the player if (event->button == 1){ GVariant* new_title_event = g_variant_new_boolean(TRUE); dbusmenu_menuitem_handle_event (priv->twin_item, "Title menu event", new_title_event, 0); } // For the right copy track details to clipboard only if the player is running // and there is something there else if (event->button == 3){ gboolean running = dbusmenu_menuitem_property_get_bool (priv->twin_item, DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING); gboolean hidden = dbusmenu_menuitem_property_get_bool (priv->twin_item, DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS); g_return_val_if_fail ( running, FALSE ); g_return_val_if_fail ( !hidden, FALSE ); GtkClipboard* board = gtk_clipboard_get (GDK_NONE); gchar* contents = g_strdup_printf("artist: %s \ntitle: %s \nalbum: %s", dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_METADATA_MENUITEM_ARTIST), dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_METADATA_MENUITEM_TITLE), dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_METADATA_MENUITEM_ALBUM)); gtk_clipboard_set_text (board, contents, -1); gtk_clipboard_store (board); g_free(contents); } return FALSE; } static void metadata_widget_property_update(DbusmenuMenuitem* item, gchar* property, GVariant* value, gpointer userdata) { g_return_if_fail (IS_METADATA_WIDGET (userdata)); if(g_variant_is_of_type(value, G_VARIANT_TYPE_INT32) == TRUE && g_variant_get_int32(value) == DBUSMENU_PROPERTY_EMPTY){ GVariant* new_value = g_variant_new_string (""); value = new_value; } MetadataWidget* mitem = METADATA_WIDGET(userdata); MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(mitem); if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTIST, property) == 0){ gtk_label_set_text(GTK_LABEL(priv->artist_label), g_variant_get_string(value, NULL)); metadata_widget_style_labels(mitem, GTK_LABEL(priv->artist_label)); } else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_TITLE, property) == 0){ gtk_label_set_text(GTK_LABEL(priv->piece_label), g_variant_get_string(value, NULL)); metadata_widget_style_labels(mitem, GTK_LABEL(priv->piece_label)); } else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ALBUM, property) == 0){ gtk_label_set_text(GTK_LABEL(priv->container_label), g_variant_get_string(value, NULL)); metadata_widget_style_labels(mitem, GTK_LABEL(priv->container_label)); } else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTURL, property) == 0){ g_string_erase(priv->image_path, 0, -1); g_string_overwrite(priv->image_path, 0, g_variant_get_string (value, NULL)); gtk_widget_queue_draw(GTK_WIDGET(mitem)); } else if (g_ascii_strcasecmp (DBUSMENU_METADATA_MENUITEM_PLAYER_NAME, property) == 0){ gtk_label_set_label (GTK_LABEL (priv->player_label), g_variant_get_string(value, NULL)); } else if (g_ascii_strcasecmp (DBUSMENU_METADATA_MENUITEM_PLAYER_ICON, property) == 0){ metadata_widget_set_icon (mitem); } else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS, property) == 0){ metadata_widget_handle_resizing (mitem); } } static void metadata_widget_handle_resizing (MetadataWidget* self) { MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); if (dbusmenu_menuitem_property_get_bool (priv->twin_item, DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS) == TRUE){ gtk_widget_hide (priv->meta_data_h_box); } else{ gtk_widget_show (priv->meta_data_h_box); } gtk_widget_queue_draw(GTK_WIDGET(self)); } static void metadata_widget_style_labels(MetadataWidget* self, GtkLabel* label) { char* markup; markup = g_markup_printf_escaped ("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup (GTK_LABEL (label), markup); g_free(markup); } static void metadata_widget_set_style(GtkWidget* metadata, GtkStyle* style) { g_return_if_fail(IS_METADATA_WIDGET(metadata)); MetadataWidget* widg = METADATA_WIDGET(metadata); MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widg); priv->theme_change_occured = TRUE; gtk_widget_queue_draw(GTK_WIDGET(metadata)); } static void metadata_widget_set_icon (MetadataWidget *self) { MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); if (priv->icon_buf != NULL){ g_object_unref (priv->icon_buf); priv->icon_buf = NULL; } gint padding = 0; gtk_widget_style_get(GTK_WIDGET(self), "horizontal-padding", &padding, NULL); gint width, height; gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height); GString* banshee_string = g_string_new ( "banshee" ); gchar * tmp = g_utf8_strdown (dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_METADATA_MENUITEM_PLAYER_NAME), -1); GString* app_panel = g_string_new (tmp); g_free (tmp); GdkPixbuf* icon_buf; // Banshee Special case! // Not ideal but apparently we want the banshee icon to be the greyscale one // and any others to be the icon from the desktop file => colour. if ( g_string_equal ( banshee_string, app_panel ) == TRUE && gtk_icon_theme_has_icon ( gtk_icon_theme_get_default(), app_panel->str ) ){ g_string_append ( app_panel, "-panel" ); } else{ // Otherwise use what is stored in the props g_string_erase (app_panel, 0, -1); g_string_overwrite (app_panel, 0, dbusmenu_menuitem_property_get ( priv->twin_item, DBUSMENU_METADATA_MENUITEM_PLAYER_ICON )); } icon_buf = gtk_icon_theme_load_icon ( gtk_icon_theme_get_default(), app_panel->str, (width > height) ? width : height, GTK_ICON_LOOKUP_GENERIC_FALLBACK, NULL ); priv->icon_buf = icon_buf; g_string_free ( app_panel, TRUE); g_string_free ( banshee_string, TRUE); } static void metadata_widget_set_twin_item (MetadataWidget* self, DbusmenuMenuitem* twin_item) { MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(self); priv->twin_item = twin_item; g_signal_connect( G_OBJECT(priv->twin_item), "property-changed", G_CALLBACK(metadata_widget_property_update), self); gtk_label_set_text( GTK_LABEL(priv->container_label), dbusmenu_menuitem_property_get( priv->twin_item, DBUSMENU_METADATA_MENUITEM_ALBUM)); metadata_widget_style_labels( self, GTK_LABEL(priv->container_label)); gtk_label_set_text( GTK_LABEL(priv->piece_label), dbusmenu_menuitem_property_get( priv->twin_item, DBUSMENU_METADATA_MENUITEM_TITLE)); metadata_widget_style_labels( self, GTK_LABEL(priv->piece_label)); gtk_label_set_text( GTK_LABEL(priv->artist_label), dbusmenu_menuitem_property_get( priv->twin_item, DBUSMENU_METADATA_MENUITEM_ARTIST)); metadata_widget_style_labels( self, GTK_LABEL(priv->artist_label)); g_string_erase(priv->image_path, 0, -1); const gchar *arturl = dbusmenu_menuitem_property_get( priv->twin_item, DBUSMENU_METADATA_MENUITEM_ARTURL ); gtk_label_set_label (GTK_LABEL(priv->player_label), dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_METADATA_MENUITEM_PLAYER_NAME)); metadata_widget_set_icon(self); if (arturl != NULL){ g_string_overwrite( priv->image_path, 0, arturl); // if its a remote image queue a redraw incase the download took too long if (g_str_has_prefix (arturl, g_get_user_cache_dir())){ gtk_widget_queue_draw(GTK_WIDGET(self)); } } metadata_widget_handle_resizing (self); } /** * transport_new: * @returns: a new #MetadataWidget. **/ GtkWidget* metadata_widget_new(DbusmenuMenuitem *item) { GtkWidget* widget = g_object_new(METADATA_WIDGET_TYPE, NULL); metadata_widget_set_twin_item ( METADATA_WIDGET(widget), item ); return widget; } cairo-dock-plugins-3.3.2/alsaMixer/src/applet-menu.h000775 001750 001750 00000002050 12223247501 023461 0ustar00mbaertsmbaerts000000 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 __APPLET_MENU__ #define __APPLET_MENU__ #include #if (GTK_MAJOR_VERSION < 3) || defined (DBUSMENU_GTK3_NEW) #include #else #include #endif void cd_sound_add_menu_handler (DbusmenuGtkClient * client); #endif cairo-dock-plugins-3.3.2/alsaMixer/src/transport-widget.h000664 001750 001750 00000004706 12223247501 024556 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2010 Canonical Ltd. Authors: Conor Curran This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 __TRANSPORT_WIDGET_H__ #define __TRANSPORT_WIDGET_H__ #include #if (GTK_MAJOR_VERSION < 3) || defined (DBUSMENU_GTK3_NEW) #include #else #include #endif #include "common-defs.h" G_BEGIN_DECLS #define TRANSPORT_WIDGET_TYPE (transport_widget_get_type ()) #define TRANSPORT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRANSPORT_WIDGET_TYPE, TransportWidget)) #define TRANSPORT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TRANSPORT_WIDGET_TYPE, TransportWidgetClass)) #define IS_TRANSPORT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRANSPORT_WIDGET_TYPE)) #define IS_TRANSPORT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TRANSPORT_WIDGET_TYPE)) #define TRANSPORT_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TRANSPORT_WIDGET_TYPE, TransportWidgetClass)) typedef struct _TransportWidget TransportWidget; typedef struct _TransportWidgetClass TransportWidgetClass; struct _TransportWidgetClass { GtkMenuItemClass parent_class; }; struct _TransportWidget { GtkMenuItem parent; }; typedef struct { double r; double g; double b; /// make it a GdkRGBA double a; } CairoColorRGB; void _color_shade (const CairoColorRGB *a, float k, CairoColorRGB *b); GType transport_widget_get_type (void); GtkWidget* transport_widget_new (DbusmenuMenuitem *item); void transport_widget_react_to_key_press_event (TransportWidget* widget, TransportAction transport_event); void transport_widget_react_to_key_release_event (TransportWidget* widget, TransportAction transport_event); gboolean transport_widget_is_selected (TransportWidget* widget); G_END_DECLS #endif cairo-dock-plugins-3.3.2/alsaMixer/src/applet-backend-sound-menu.h000775 001750 001750 00000001616 12223247501 026203 0ustar00mbaertsmbaerts000000 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 __APPLET_SOUND__ #define __APPLET_SOUND__ #include void cd_mixer_connect_to_sound_service (void); #endif cairo-dock-plugins-3.3.2/alsaMixer/src/dbus-shared-names-old.h000664 001750 001750 00000002524 12223247501 025313 0ustar00mbaertsmbaerts000000 000000 /* A small wrapper utility to load indicators and put them as menu items into the gnome-panel using it's applet interface. Copyright 2010 Canonical Ltd. Authors: Conor Curran Ted Gould This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 __DBUS_SHARED_NAMES_H__ #define __DBUS_SHARED_NAMES_H__ #define INDICATOR_SOUND_DBUS_NAME "com.canonical.indicators.sound" #define INDICATOR_SOUND_MENU_DBUS_OBJECT_PATH "/com/canonical/indicators/sound/menu" #define INDICATOR_SOUND_SERVICE_DBUS_OBJECT_PATH "/com/canonical/indicators/sound/service" #define INDICATOR_SOUND_DBUS_INTERFACE "com.canonical.indicators.sound" #define INDICATOR_SOUND_DBUS_VERSION 0 #define INDICATOR_SOUND_SIGNAL_STATE_UPDATE "SoundStateUpdate" #endif /* __DBUS_SHARED_NAMES_H__ */ cairo-dock-plugins-3.3.2/alsaMixer/src/applet-config.h000775 001750 001750 00000001741 12223247501 023770 0ustar00mbaertsmbaerts000000 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 __APPLET_CONFIG__ #define __APPLET_CONFIG__ #include CD_APPLET_CONFIG_H void cd_mixer_load_custom_widget (GldiModuleInstance *myApplet, GKeyFile* pKeyFile, GSList *pWidgetList); #endif cairo-dock-plugins-3.3.2/alsaMixer/src/voip-input-widget.c000664 001750 001750 00000026520 12223247501 024625 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2011 Canonical Ltd. Authors: Conor Curran This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "voip-input-widget.h" #include "common-defs.h" #include typedef struct _VoipInputWidgetPrivate VoipInputWidgetPrivate; struct _VoipInputWidgetPrivate { DbusmenuMenuitem* twin_item; GtkWidget* ido_voip_input_slider; gboolean grabbed; }; #define VOIP_INPUT_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetPrivate)) /* Prototypes */ static void voip_input_widget_class_init (VoipInputWidgetClass *klass); static void voip_input_widget_init (VoipInputWidget *self); static void voip_input_widget_dispose (GObject *object); static void voip_input_widget_finalize (GObject *object); static void voip_input_widget_set_twin_item( VoipInputWidget* self, DbusmenuMenuitem* twin_item); static void voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property, GVariant* value, gpointer userdata ); static gboolean voip_input_widget_change_value_cb (GtkRange *range, GtkScrollType scroll, gdouble value, gpointer user_data); static gboolean voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data); static void voip_input_widget_slider_grabbed(GtkWidget *widget, gpointer user_data); static void voip_input_widget_slider_released(GtkWidget *widget, gpointer user_data); static void voip_input_widget_parent_changed (GtkWidget *widget, gpointer user_data); G_DEFINE_TYPE (VoipInputWidget, voip_input_widget, G_TYPE_OBJECT); static void voip_input_widget_class_init (VoipInputWidgetClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (VoipInputWidgetPrivate)); gobject_class->dispose = voip_input_widget_dispose; gobject_class->finalize = voip_input_widget_finalize; } static void voip_input_widget_init (VoipInputWidget *self) { VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); priv->ido_voip_input_slider = ido_scale_menu_item_new_with_range ("VOLUME", IDO_RANGE_STYLE_DEFAULT, 0, 0, 100, 1); g_object_ref (priv->ido_voip_input_slider); ido_scale_menu_item_set_primary_label (IDO_SCALE_MENU_ITEM(priv->ido_voip_input_slider), "VOIP"); ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (priv->ido_voip_input_slider), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); g_object_set(priv->ido_voip_input_slider, "reverse-scroll-events", TRUE, NULL); g_signal_connect (priv->ido_voip_input_slider, "notify::parent", G_CALLBACK (voip_input_widget_parent_changed), NULL); GtkWidget* voip_input_widget = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); g_signal_connect(voip_input_widget, "change-value", G_CALLBACK(voip_input_widget_change_value_cb), self); g_signal_connect(voip_input_widget, "value-changed", G_CALLBACK(voip_input_widget_value_changed_cb), self); g_signal_connect(priv->ido_voip_input_slider, "slider-grabbed", G_CALLBACK(voip_input_widget_slider_grabbed), self); g_signal_connect(priv->ido_voip_input_slider, "slider-released", G_CALLBACK(voip_input_widget_slider_released), self); GtkWidget* primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider); GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks("audio-input-microphone-low-zero-panel"); gtk_image_set_from_gicon(GTK_IMAGE(primary_image), primary_gicon, GTK_ICON_SIZE_MENU); g_object_unref(primary_gicon); GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider); GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-input-microphone-high-panel"); gtk_image_set_from_gicon(GTK_IMAGE(secondary_image), secondary_gicon, GTK_ICON_SIZE_MENU); g_object_unref(secondary_gicon); GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (voip_input_widget)); gtk_adjustment_set_step_increment(adj, 4); } static void voip_input_widget_dispose (GObject *object) { G_OBJECT_CLASS (voip_input_widget_parent_class)->dispose (object); } static void voip_input_widget_finalize (GObject *object) { /// we need to unref what we ref'ed VoipInputWidget *self = VOIP_INPUT_WIDGET (object); VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); g_object_unref (priv->twin_item); g_object_unref (priv->ido_voip_input_slider); G_OBJECT_CLASS (voip_input_widget_parent_class)->finalize (object); } static void voip_input_widget_property_update (DbusmenuMenuitem* item, gchar* property, GVariant* value, gpointer userdata) { g_return_if_fail (IS_VOIP_INPUT_WIDGET (userdata)); VoipInputWidget* mitem = VOIP_INPUT_WIDGET(userdata); VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); if(g_ascii_strcasecmp(DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL, property) == 0){ g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); if (priv->grabbed == FALSE){ GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); GtkRange *range = (GtkRange*)slider; gdouble update = g_variant_get_double (value); //g_debug("volume-widget - update level with value %f", update); gtk_range_set_value(range, update); } } if(g_ascii_strcasecmp(DBUSMENU_VOIP_INPUT_MENUITEM_MUTE, property) == 0){ if(priv->grabbed == FALSE){ g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32)); GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); GtkRange *range = (GtkRange*)slider; gint update = g_variant_get_int32 (value); gdouble level; if (update == 1){ level = 0; } else{ GVariant* variant = dbusmenu_menuitem_property_get_variant (priv->twin_item, DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL); g_return_if_fail (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE)); level = g_variant_get_double (variant); } gtk_range_set_value(range, level); g_debug ("voip-item-widget - update mute with value %i", update); } } } static void voip_input_widget_set_twin_item (VoipInputWidget* self, DbusmenuMenuitem* twin_item) { VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); priv->twin_item = twin_item; g_object_ref(priv->twin_item); g_signal_connect(G_OBJECT(twin_item), "property-changed", G_CALLBACK(voip_input_widget_property_update), self); gdouble initial_level = g_variant_get_double (dbusmenu_menuitem_property_get_variant(twin_item, DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL)); //g_debug("voip_input_widget_set_twin_item initial level = %f", initial_level); GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); GtkRange *range = (GtkRange*)slider; gtk_range_set_value(range, initial_level); gint mute = g_variant_get_int32 (dbusmenu_menuitem_property_get_variant (priv->twin_item, DBUSMENU_VOIP_INPUT_MENUITEM_MUTE)); if (mute == 1){ gtk_range_set_value (range, 0.0); } } static gboolean voip_input_widget_change_value_cb (GtkRange *range, GtkScrollType scroll, gdouble new_value, gpointer user_data) { g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE); VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); voip_input_widget_update(mitem, new_value); return FALSE; } /** * We only want this callback to catch mouse icon press events which set the * slider to 0 or 100. Ignore all other events including the new Mute behaviour * (slider to go to 0 on mute without setting the level to 0 and return to * previous level on unmute) **/ static gboolean voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data) { g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE); VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); gdouble current_value = CLAMP(gtk_range_get_value(GTK_RANGE(slider)), 0, 100); gint mute = g_variant_get_int32 (dbusmenu_menuitem_property_get_variant (priv->twin_item, DBUSMENU_VOIP_INPUT_MENUITEM_MUTE)); if ((current_value == 0 && mute != 1) || current_value == 100 ){ voip_input_widget_update(mitem, current_value); } return FALSE; } void voip_input_widget_update(VoipInputWidget* self, gdouble update) { VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); gdouble clamped = CLAMP(update, 0, 100); GVariant* new_volume = g_variant_new_double(clamped); dbusmenu_menuitem_handle_event (priv->twin_item, "update", new_volume, 0); } GtkWidget* voip_input_widget_get_ido_slider(VoipInputWidget* self) { VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); return priv->ido_voip_input_slider; } static void voip_input_widget_parent_changed (GtkWidget *widget, gpointer user_data) { gtk_widget_set_size_request (widget, 200, -1); //g_debug("voip_input_widget_parent_changed"); } static void voip_input_widget_slider_grabbed(GtkWidget *widget, gpointer user_data) { VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); priv->grabbed = TRUE; } static void voip_input_widget_slider_released(GtkWidget *widget, gpointer user_data) { VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); priv->grabbed = FALSE; } void voip_input_widget_tidy_up (GtkWidget *widget) { VoipInputWidget* mitem = VOIP_INPUT_WIDGET(widget); VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); gtk_widget_destroy (priv->ido_voip_input_slider); } /** * voip_input_widget_new: * @returns: a new #VoipInputWidget. **/ GtkWidget* voip_input_widget_new(DbusmenuMenuitem *item) { GtkWidget* widget = g_object_new(VOIP_INPUT_WIDGET_TYPE, NULL); voip_input_widget_set_twin_item((VoipInputWidget*)widget, item); return widget; } cairo-dock-plugins-3.3.2/alsaMixer/src/volume-widget.c000664 001750 001750 00000027721 12223247501 024026 0ustar00mbaertsmbaerts000000 000000 /* Copyright 2010 Canonical Ltd. Authors: Conor Curran This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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 . */ /**#ifdef HAVE_CONFIG_H #include "config.h" #endif*/ #include #include #include #include "volume-widget.h" #include "common-defs.h" #include ///#include "indicator-sound.h" #include "applet-backend-sound-menu-old.h" typedef struct _VolumeWidgetPrivate VolumeWidgetPrivate; struct _VolumeWidgetPrivate { DbusmenuMenuitem* twin_item; GtkWidget* ido_volume_slider; gboolean grabbed; ///IndicatorObject* indicator; }; #define VOLUME_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOLUME_WIDGET_TYPE, VolumeWidgetPrivate)) /* Prototypes */ static void volume_widget_class_init (VolumeWidgetClass *klass); static void volume_widget_init (VolumeWidget *self); static void volume_widget_dispose (GObject *object); static void volume_widget_finalize (GObject *object); static void volume_widget_set_twin_item( VolumeWidget* self, DbusmenuMenuitem* twin_item); static void volume_widget_property_update( DbusmenuMenuitem* item, gchar* property, GVariant* value, gpointer userdata ); static gboolean volume_widget_change_value_cb (GtkRange *range, GtkScrollType scroll, gdouble value, gpointer user_data); static gboolean volume_widget_value_changed_cb(GtkRange *range, gpointer user_data); static void volume_widget_slider_grabbed(GtkWidget *widget, gpointer user_data); static void volume_widget_slider_released(GtkWidget *widget, gpointer user_data); static void volume_widget_parent_changed (GtkWidget *widget, gpointer user_data); G_DEFINE_TYPE (VolumeWidget, volume_widget, G_TYPE_OBJECT); static void volume_widget_class_init (VolumeWidgetClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (VolumeWidgetPrivate)); gobject_class->dispose = volume_widget_dispose; gobject_class->finalize = volume_widget_finalize; } static void volume_widget_init (VolumeWidget *self) { //g_debug("VolumeWidget::volume_widget_init"); VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); priv->ido_volume_slider = ido_scale_menu_item_new_with_range ("VOLUME", IDO_RANGE_STYLE_DEFAULT, 0, 0, 100, 1); g_object_ref (priv->ido_volume_slider); ido_scale_menu_item_set_primary_label (IDO_SCALE_MENU_ITEM(priv->ido_volume_slider), "VOLUME"); ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (priv->ido_volume_slider), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); g_object_set(priv->ido_volume_slider, "reverse-scroll-events", TRUE, NULL); g_signal_connect (priv->ido_volume_slider, "notify::parent", G_CALLBACK (volume_widget_parent_changed), NULL); GtkWidget* volume_widget = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); g_signal_connect(volume_widget, "change-value", G_CALLBACK(volume_widget_change_value_cb), self); g_signal_connect(volume_widget, "value-changed", G_CALLBACK(volume_widget_value_changed_cb), self); g_signal_connect(priv->ido_volume_slider, "slider-grabbed", G_CALLBACK(volume_widget_slider_grabbed), self); g_signal_connect(priv->ido_volume_slider, "slider-released", G_CALLBACK(volume_widget_slider_released), self); GtkWidget* primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)priv->ido_volume_slider); GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks("audio-volume-low-zero-panel"); gtk_image_set_from_gicon(GTK_IMAGE(primary_image), primary_gicon, GTK_ICON_SIZE_MENU); g_object_unref(primary_gicon); GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)priv->ido_volume_slider); GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-volume-high-panel"); gtk_image_set_from_gicon(GTK_IMAGE(secondary_image), secondary_gicon, GTK_ICON_SIZE_MENU); g_object_unref(secondary_gicon); GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (volume_widget)); gtk_adjustment_set_step_increment(adj, 4); } static void volume_widget_dispose (GObject *object) { G_OBJECT_CLASS (volume_widget_parent_class)->dispose (object); } static void volume_widget_finalize (GObject *object) { /// we need to unref what we ref'ed // VolumeWidget *self = VOLUME_WIDGET (object); VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(object); g_object_unref (priv->twin_item); g_object_unref (priv->ido_volume_slider); G_OBJECT_CLASS (volume_widget_parent_class)->finalize (object); } static void volume_widget_property_update( DbusmenuMenuitem* item, gchar* property, GVariant* value, gpointer userdata) { g_return_if_fail (IS_VOLUME_WIDGET(userdata)); VolumeWidget* mitem = VOLUME_WIDGET(userdata); VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); if(g_ascii_strcasecmp(DBUSMENU_VOLUME_MENUITEM_LEVEL, property) == 0){ g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE) ); if(priv->grabbed == FALSE){ GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); GtkRange *range = (GtkRange*)slider; gdouble update = g_variant_get_double (value); gtk_range_set_value(range, update); /* g_debug ("volume-widget::volume_widget_property_update - volume - value %f", update); */ update_accessible_desc(update/**priv->indicator*/); } } else if(g_ascii_strcasecmp(DBUSMENU_VOLUME_MENUITEM_MUTE, property) == 0){ g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)); if(priv->grabbed == FALSE){ GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); GtkRange *range = (GtkRange*)slider; gboolean update = g_variant_get_boolean (value); gdouble level; if (update == TRUE){ level = 0; } else{ GVariant* variant = dbusmenu_menuitem_property_get_variant (priv->twin_item, DBUSMENU_VOLUME_MENUITEM_LEVEL); /* g_debug ("variant for the volume - is it null = %i", variant == NULL); */ g_return_if_fail (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE) ); level = g_variant_get_double (variant); } /* g_debug ("volume-widget::volume_widget_property_update - mute - value %i and level = %f", update, level); */ gtk_range_set_value(range, level); } } } static void volume_widget_set_twin_item(VolumeWidget* self, DbusmenuMenuitem* twin_item) { VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); priv->twin_item = twin_item; g_object_ref(priv->twin_item); g_signal_connect(G_OBJECT(twin_item), "property-changed", G_CALLBACK(volume_widget_property_update), self); gdouble initial_level = g_variant_get_double (dbusmenu_menuitem_property_get_variant(twin_item, DBUSMENU_VOLUME_MENUITEM_LEVEL)); gboolean initial_mute = g_variant_get_boolean (dbusmenu_menuitem_property_get_variant(twin_item, DBUSMENU_VOLUME_MENUITEM_MUTE)); //g_debug("volume_widget_set_twin_item initial level = %f", initial_level); GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); GtkRange *range = (GtkRange*)slider; if(initial_mute == TRUE){ initial_level = 0; } gtk_range_set_value(range, initial_level); } static gboolean volume_widget_change_value_cb (GtkRange *range, GtkScrollType scroll, gdouble new_value, gpointer user_data) { g_return_val_if_fail (IS_VOLUME_WIDGET (user_data), FALSE); VolumeWidget* mitem = VOLUME_WIDGET(user_data); /* g_debug ("changed value %f", new_value); */ volume_widget_update(mitem, new_value, "change-value"); // we need to update the icon here. update_accessible_desc (new_value); return FALSE; } /* We only want this callback to catch mouse icon press events which set the slider to 0 or 100. Ignore all other events. */ static gboolean volume_widget_value_changed_cb (GtkRange *range, gpointer user_data) { g_return_val_if_fail (IS_VOLUME_WIDGET (user_data), FALSE); VolumeWidget* mitem = VOLUME_WIDGET (user_data); VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); gdouble current_value = CLAMP(gtk_range_get_value(GTK_RANGE(slider)), 0, 100); gboolean mute = g_variant_get_boolean (dbusmenu_menuitem_property_get_variant (priv->twin_item, DBUSMENU_VOLUME_MENUITEM_MUTE)); if((current_value == 0 && mute == FALSE) || current_value == 100){ /* g_debug ("value changed - actual set %f", current_value); */ volume_widget_update (mitem, current_value, "value-changed"); } return FALSE; } void volume_widget_update(VolumeWidget* self, gdouble update, const gchar* label) { const gchar* source = NULL; source = label; if (label == NULL){ source = "v widget update"; } VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); gdouble clamped = CLAMP(update, 0, 100); GVariant* new_volume = g_variant_new_double(clamped); dbusmenu_menuitem_handle_event (priv->twin_item, source, new_volume, 0); } GtkWidget* volume_widget_get_ido_slider(VolumeWidget* self) { VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); return priv->ido_volume_slider; } static void volume_widget_parent_changed (GtkWidget *widget, gpointer user_data) { gtk_widget_set_size_request (widget, 200, -1); //g_debug("volume_widget_parent_changed"); } static void volume_widget_slider_grabbed(GtkWidget *widget, gpointer user_data) { VolumeWidget* mitem = VOLUME_WIDGET(user_data); VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); priv->grabbed = TRUE; } static void volume_widget_slider_released(GtkWidget *widget, gpointer user_data) { VolumeWidget* mitem = VOLUME_WIDGET(user_data); VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); priv->grabbed = FALSE; } void volume_widget_tidy_up (GtkWidget *widget) { VolumeWidget* mitem = VOLUME_WIDGET(widget); VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); gtk_widget_destroy (priv->ido_volume_slider); } gdouble volume_widget_get_current_volume ( GtkWidget *widget ) { VolumeWidget* mitem = VOLUME_WIDGET(widget); VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); gdouble vol = g_variant_get_double( dbusmenu_menuitem_property_get_variant( priv->twin_item, DBUSMENU_VOLUME_MENUITEM_LEVEL)); return vol; } /** * volume_widget_new: * @returns: a new #VolumeWidget. **/ GtkWidget* volume_widget_new(DbusmenuMenuitem *item/**, IndicatorObject* io*/) { GtkWidget* widget = g_object_new(VOLUME_WIDGET_TYPE, NULL); /**VolumeWidgetPrivate* priv = VOLUME_WIDGET_GET_PRIVATE(VOLUME_WIDGET(widget)); priv->indicator = io;*/ volume_widget_set_twin_item((VolumeWidget*)widget, item); return widget; } cairo-dock-plugins-3.3.2/alsaMixer/CMakeLists.txt000664 001750 001750 00000000332 12223247501 023030 0ustar00mbaertsmbaerts000000 000000 add_subdirectory(src) add_subdirectory(data) ########### install files ############### #original Makefile.am contents follow: ##dnl Process this file with automake to produce Makefile.in # #SUBDIRS = . src data cairo-dock-plugins-3.3.2/alsaMixer/data/broken.svg000664 001750 001750 00000127273 12223247501 023220 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/alsaMixer/data/icon.png000664 001750 001750 00000010447 12223247501 022647 0ustar00mbaertsmbaerts000000 000000 PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<IDATx[{p\u>=Vo-#$)Ҵ)ut:?0eF1' ĆZf2\ۅH%-˲$KZ}s]m$f wݽ;w~w-C{~IOd]iT$z̛J8p`_qLGqMU(Vo<LW_zP׵rrsݥ嶒/ٹYMOoƫD#`/?Sza(?m (( Iq8wZC i!i}{pq"4ohrrs ;+ JJKBw` eq/>Gyyt:9݇'N@úzp\(|bbv){g(^ e%1hA._gΜlE/>6ylg˾i?;;gϝʑs\ y\d#<rÑe ^ޖFtSW~^={6E{`pq8x< EC}]cq##PT\,(x @tjA0~$<31 ]YQj$_[OeݱcE]əO5]hD@[tzރt.]C@WWW,jT-5eQJݥ(uK;9+())eC 0T @~ ZA3` ;'.}'{jUcp}~Au"=s4\_P[U099 m[:8V#$,`Πԛ% qpcc!1*'&Y5 x`TQQnB:7?33lR. wt ]UU DQ9{ xcYdK[Df1 %dRaA v, gw%yHQQ2O,CvKeA%E8K6(pƭ &oh: +g{~illBjC SOƓҡux KnwC!2 Cd %[bZKF5t!nCt6 %c@\ŬV6g_VVAM`~~KN^w8D‹PTZA7@ݺc 0K>3ʶÏN?H~p}6ϕ'A$pX},An W.f^NlqEoـ5 S)wa[,W *<жm bDp"iYORRX@'"Anx:~D)0 86$*M f9X#Gr|vԆMŊu O0$YW zOkDa:‘Pb/sDw݉V>@9,k(2 # CZUS}q~JkNJmj UlǾ[#@I/H5UÖH-u ΀?h?$ȒĬ B vӊ`VɈEStB Q^G.1I G0\bZ$dh110l.tagQ|O,l<" @v  "Q:;Ðe[u%nz0c`ad@:6 2JaD12v(=G#Q|.0ک b8zi 1Cڂ-dTi@5)t|.:@ٍ.F9x:p(PREweD:1@1d*Du=q'MS3$)1MgL><Gup[200 Z4rHOLeҊF4?gmlOe+H$+/Wav?GkkV,g7"*4eT^3p1d= "|oKF7.u srrV#a @F"?DvhDH,Lk}tivGB~7D5h߶2W9OU1 |Ňq"B;wDVp:TrPPg餫mK3O<̘Yx eARj ŌÇ~ĉ*]-I)QTx#l(r{m[h4MMi@ +.jjmw|uZ3,\x X^({ eAY_H˸o""@ Y?9*tww *3 4ȴn&ˀCorQg.fo&,C‚ *1 C1C @ +[ob. Е\R &\D eh CCWJQhljXWN n=TR Q^QɀbőRGW̏9B-]v=' dG;v{}"~ <>ی@<.2eSX`"ZZɨ$===ݥ۳_-5SGeR4K ?spA+?})w nUT_uv)fW#H ݧ wuO{\akgV@qr ۶Muojl&PuwBա/bh irtB2KD¶ؗ((w#Xa`nBo{ 8Y>5i}]> Ĉ%Ȅ&ŭJmH-zvfFNzEdc4]Xoj rsBF.~ Fo÷umы 'knaf##++mug `:'~_[|ˁO%U`:< 0{RIENDB`cairo-dock-plugins-3.3.2/alsaMixer/data/preview.jpg000664 001750 001750 00000051503 12223247501 023372 0ustar00mbaertsmbaerts000000 000000 JFIFHHC  !"$"$C" X !1AQq"23RSa6Us4Tbt$BD#EV%5drCWu•51!2QRaAqSB"3 ?D@DDD@CĊЃOӝ*Q<͍qqTN- $g챼KMl Lvgۿsx򛺓}NrֳMgyګ:}NrֳMgyڜFK>'KGkYqN#h~x}\8SYq?R~ >.Zw}8Sé{Z?_h~x-k;>w}aԽ-w~ jk;>0^;Z?_Z5jsu/KG-gyښ9:}NrֳMgyڜFK>'KGkYqN#h~x}\8SYq?R~ >.Zw}8Sé{Z?_h~x-k;>w}az/tm$U=g)\fӐFW%{]S.ٻ!N+WaGe " """ """ """ ""MURO&{0<>dzȳAAJ\QK%-5~޴2(.MNqmdWlRnQVw hvj0xjjjYQQ42?]Hzy>yISQIzST"{]3$rNO: aѱ۵U]f̰ E'8NF D-6Id}B+eNJڌ16qcl^-q_B|iHi_ ܙl} =8Dq8'pߎDm x Տp5W|nr; ARO&'wAA=E^ zTفY.m(13cq%mћ6SY ܟQOm_7]o͸>}x+;tDUD@DDD@DDD@DDD@DDI< M `y}{?(99Sfg׳㞔",eoH:Zj=IZX#7T|:I\\rI<""" """ ""/xe8 #49+np][+7-ב{o;4s ӕ_c]mu~o#d$xU E-BƾJ9`)ETPb-&EnVnsꌀNKC'~>%aqN4D@W|nrk鶯.7V>v:"*" """ """ """ ""MURO&{0<>dzȳAAJ\Q{j;NMWj#AY,^ƽYx?]mW^Fv6vwoߞnA" 7* 4b*0ȥl`a|my yTM1\j+n m]++IE=SHs]<'!C+lU+WK*a6&F6-\Ɨc)VWPo}7MF(Yxo~ Qɨdxo~ ̚Axo~ Qɨdxo~ ̚Axo~ Qɨdcq;(፨09HZwab "j=iA"Dt~A{%k9# Ol9q9 odn)dzpy即=~$ {x5̪>6Po}75̉|m/Hǜ4 [An}:c!&^1COA dgθ[FfG:Vcv ݍET2VFIc^Csnj]CxRiihV*`e5%˺tS1ݒ-_륱٬YI+bD*N2hm x Տp5W|nr; ARO&'wAA=E^ zTفY׆~hKA*ac:01PYTT|uBac:QS  EL7gT&3U01PoΨATT|uBac:QS  EL7gT&3U}l3DRulr[]yTlb<c=݇ ~wqh=l[_JP&h1u<җP+%|QHy\֒`ܞa4d9VscmFϤQۥ4N>Is&^͆ jG gwg5ƾOKY."I't;FT>ܰ>R0'qxãuK7jQMM :!}f ,g,i;H kL)\6j&HDmrefnxOm_7]o͸>}x+;tDUD@DDD@DDD@DDD@DDI< M `y}{?(99Sfg׳㞔4o:Yk&ᖦbhĴ[yT].RUVT;^Y_ VYeE5 m e4OtM7n_.^_j]nj^ar< E ]wN巒~UemL;Y4 a~*w[dWr9,shppk;ZӃV*襦*ژn;+ka>˜wrUSzU\cTݫ歌Lt8É>b.w+ҤTꫧ TL8\IQqbCX8WiY$<Hug*>,7]g8!" """ """ "" 鶯.7V>Om_7]o͸>}x+;tDUD@DDD@DDD@DDD@DDI< M `y}{?(99Sfg׳㞔",xMlc~I$#-'ckApjh~ w4~зN¾clk_&"`vvxу=,Oc!a!vuIxf0m]oU9x"WCLk@8;Rԯ/w0@qtUɶ] ,XqyJ];KWx,ocpAQ3#.bUck4kt{%IWEi߲Ƶ;G~ޥiW;Jӭ}jbr0 C5N ޮ%w4~OZ8۴NiRZIKI#x#w4~ڻ?v߂z^uusQ3&>}͚v IxRMW1eJK#XWocFzTf !(/SESzKS#8Z\H8>g;|п>*s1CTUݏ7[M\o54̬2L7R}Cz߭jq%|,H$2Zx92O vB(t"PxЪfGؠz}_Q]TY\z0 |O*Oڷ~tסp/vx%hd,{@h'r^7\xw|Pt]ddsXf xy>Ƶ 5-4:gxغ=-(_ xN=%Cz/kп>(>'|w6"=n#Uc::}"" "" 鶯.7V>Om_7]o͸>}x+;tDUD@DDD@DDD@DDD@DDI< M `y}{?(99Sfg׳㞔",lwKUh;M֘坓q͙as:8֐h;]u&QjZ]$ry݄,JvmPW;Gh{ca1\jX7 F]4L%Q,,מ7av]1ӑ`lhnNhmSj*fWZ8kjUs%C.SA,VvH h24vyw E5l6ѝUΪF9'ʼZT`u vƍn8hރ7K~ܠ:Ute 4o3 -$"7Z[SS$=-w5%!hv)k/c^]ҺzkVwxnt:V1;$6ift7Kc չ1$6<:0NH';C=Z*Mxk5C`<[ """ ~j~mc\ t6<ۃܷ³GDEPDDD@DDD@DDD@DDD@TɻIPrfg׳㞕8`y}{?(5q\S_0|K6tluYfaֆD1,'X ('= uVyV环>xh6PvrGu۝Me3re{Z:+ɺ J(i[+5bC""VqdG_0|l(>v'M;1^y\>*GQDLdvH ]CiXxi环vqH˔w8K5޴K$&BZqyv7,fiUV2'V3jh]K0,ΩlvAn \WLxh*>xi环您环>xh,nڿ|oߛp}X\֬o&9|nr; ARO&'wAA}-k {CCFAA{K:&^a 8/>oFg2:47;r*)u>w-ܚOt}2C#T0|=- clXdcs\׼(:'ћ.\&*|RT8-cI.w$TE 25Qpހ7.-m⸹39~mkͪuL?&k䖉G'-[}ESS[|ϑBHh-N9s]CWJd0>/ڌǽ۫`;q߈iLrG_^&KD䖉G,MO|l8I]2B˾A[ʞX?Иyi Z 1MW^[4y"zz"KD䖉G-Q͕¥0"f CzOc86ܨ* S#ssr7jq 'rQ?Lѣc^RվIh~r|?(ݭ,nUT† ҇;j{S` ۸]Mvkkˏ_17LըѣX~-OZ'ܶ)5p>ڍ2XKvC01s,^ֳwZQW٦'X?(%@Q_mMWnxbE-OZ'ܯ޴znx+X?(%@Q_mM=ObE-OZ'ܯ޵e>i%dk6-j\ldUK;!nYaoMrTͪI+DDf#n-OZ'ܽ*[5U f#C^oZubq5K4y Z'ܟ$O ?k_miIV<%@Q_KD֛oZ{McZ'ܟ$O ?k_m}j_Z{Mc -I-R>K2I]]o͸>}˗8}vF>~mc_aj3?~}hUM1$tD^$n*y7tMyۿq;FwZXLz:[dOpxjSF ^NqӚ>oW˜6mtzsuU9b 2)ၵh$`czhT۫^ڧ,vNG/6-ʟxo25yڋZ≵ݜ:[:/$.Uԉ4ӝQg#]n9ߛnڝl5gF=mFTƧ|[ѕ>tޙ=:x +;K!eWaָog:oȕ7i.]"9cs.hO6BN*}TΓ[3GDbng~$}(am}nxZŏלnH/. ַQ6mqnۋWgtceOjwŷS4z OsqVHiLNs^&Qwk00D"%%xCjkwhEh Ưa퓳<SݺO}?r>hE>%g; ^N9 'u^z܏w&hmFTƧ|[ѕ>Wރ#6bWH-Z9iv)ZFZѵ$%DmFTƭzz4J 4i(ؗ0ɪ"%xd㌮itQ;KOv33'۽ΏDnNZbI l%.qihd]nӊxl6 'F5d8\$i\hŷSh^5[8/鴱E}׏VhEŷSmFTƯ?ݺރ#6Z?|[ѕ>eOj{U=r7-ʟxo25=۪~}^:;ZG?<ۃܸ˄*6O ,:+_F1.7V>.vMq̾-5]b:".""" """ """ """ *IUU$n(9ȳAAJ{0<>͠dN}18UՈqQς)}$A[/gQG^A4H@34FbtkCimM-{% rC-9.yh'P^.= l.Ip!Po """ "" 鶯.7V>Om_7]o͸>}x+;tDUD@DDD@DDD@DDD@DDI< M `y}{?(99Sfg׳㞔",S8ު(tgHcugy7JG2FK c=iDPv$ h}[]-5R!/+!4o[4w~F{N˳bly21 +U:+u5ri=LG2N$R:b@lN/9 ɎL(]iƑ\5dʰy GI$s\8丞2J#$r)k;#}rHpk K:mdJnFszx`TihR,e$^o ɼ'i]KoZjNLD& @Jժ%5SI<g#IWLbMh_ѮR|A<2rca>m4<V7:? xwsyW=>P}:z"=>P}:_mMN5짚Q:W}8ySl!)툌Ynn#㘃ʂ̱9i9lǰ۟^>k)Hc~G q3Ҽym|VҚz{eS)=HՖ&߷U> 3=Ejs=eDt*DΨM>PUM4Ouq9]a;&8oAjiX}A} """ "" 鶯.7V>Om_7]o͸>}x+;tDUD@DDD@DDD@DDD@DDI< M `y}{?(99Sfg׳^|#໏)sh EL5R>kdmw\4l}AuCc}ll Fv['[R^vQciQ;-Nxn߭r|JdGtiMZ=7jݯnݞEg@o51t[]i1=9eNehvCn ('TOL jikѓ O}IY).ߪIX]JH媜1T1{7s'TOA#^/YnFy$ԕMvѱPHZ Neǩd:Z k2|J ‚ͥ1uZS  XcqoY 6Lpе PZi/T: Nt{G_.$p|Jd[[pZRM-D 5WLg9 #;ք\PY]5mw2kj\ǰ3ŝSr'TOL ŷ *nIb ,kCK ݴ;8.:I3RYUVU [1SRQcu{Y}ˁZ1c˾x Տogt'wAUTɻɾiGi⎎\i+d{8ZssҼWt|+7s_mK?xWsҗ6DE) ~MEV譳\.JkY𼴻Co [#l|0ҼLwJA,npjdFjh 5-em&!i3G%s] ρzh7.4OOp KcejLmѳk9G8 56{}"KogkSm4c\f'rpu]=eQ\Z+l:Fp<4f NwA~J> EֶznHvڒ0 fIjktqAIZִ9.* J-Mp ԱZac]@> &"Hߒv&vhncd]>3p䁞T--79k.UV|&Ac|/o #/^5,E5=&j*#|Q}ˁڿ|oߛp}XVwH航 Ъ#ԃ%4iIi*㖊o#{߬ł2IZKsһC Gl Sᴌ1йNoGbgc'0)zcӽzcz9NaVi-}]]zei'cdqp{r4"A$HunZmJF@~'ήNO*>;+ڎL4Jl{44r8륤HFHrk]rCYc+Z[ps$fi^DĶ@C7d4W{Ci[tU%5I]ڭ։?{^&cOx[pl5)kmvjk=H~R䖹k#r߽+;߽#:99WA38ktm5^V+֨i%%u%SZ'ko-$kFN#˽ ? ?reɥWTM4OgiqNr7wM򾊒J*&@I ù;߽#;߽#GG&Z+jj+!lMv<ňpx-d9*7 HBjY#րp![ކ ކ ɖsMpU*hh=UEUDd|i9bIޱsĭc XՉ7[$J{߽#;߽#OG&Q) ? ?(ކ ކ ɔrFC~C~9E#wzGwzGtre߽#;߽#:92QHoޑ@oޑ@E>k6\jݕ< Dv=9hg7+dG-<4*tqj ¾VˆL0Qg7ز(j/Dbw7ز(j/Db4oHdȨGh#mK^+x`e=K02y@ rWt5r2K~Ɖގ^+OmFGl]!vK湺pg mXf޿nfPEE WlۢY^4)SC4ǥpk[*g7RV|o[Hwkmӊ*lh]B" """ "! 3p[)-m8AY%> j;৖T)\pjiKH5M[1c>pU KSpn!L>x[-qi3.v~^c2/kӵٍk\t;W)'=,[}8V~!B Mڢ{"s^F9mZ%CT+l#񶈞G #qi}jLь9iVa9ϋ06Ɔz27M4h2PS}ѕk-_IYvT;e8lQ^绡E0l4QwBp7>ں'Bp7>ں-9e%)E]М ϶ М ϶ 'IJQZHUmTH:-߻z4. .#yY8G\'|nk$\A(… ޓG!4z=[egOJ4 9p9{'g\h>4_G67&x'c^с2A:d9;.MvZ*v ix! \Mw˥J7 Kj{`Y#XꓸΞ%t4vaJ6CA2pG&N=-=- A]ʊZn M = fꁞ\k+*kCqXJ_ -y_=c\.|2ֲy\E*1B{ o}"}Amgfg[ E &8t</o}uZVp Y uNZǍoLS_5ڢkm_2K5ӲE36eZ:8F2?TzZbyYH_8vE :1M˯hLqJq4D|Vh2j{kt$l'y1d`["YARcl7IK;߬燽90uAcd([FUneDBDm 7 \h;.imNCers1?mMU$WyOtt<6(+Ɨ8ԫu&^CG0,' iMC,m1VVH929+(| cGS8p'ع1Y4fCWW?c\[ӎ%i-֋mAR٘7;OD:0VMUeqsNw+MYA<;h0_'*ʫ|6z0ڡ $8ں*YN(ꔢ1o9Ӌk_.qykq]Zʽ%(%MXkMWks]d!vcq`J4H/-c穚w'"nssnjnޤ+~V\f3wVwCr{õ\=N\R=6s~>M.ު&gQ_Th- lW:JfɫaA !RMQ,. SO.ΉhTV ݊X$6(<;݋>ۡކk\#ULj*Qnks{tSHu2=[bsKSX׼sNT|]Bqcx>(9~okܮtNΝA}t> fsMi)pɢI+ SIS[SLhk^0χ~ { X;u)\ܲNF<\˘WE0۫:*1,4hf[ߌkQ3c=鈪R(TӖqHG9#pW6M[)-e=UG Sg#miu?#^p/d`MIa]jCύ 9] uG-uھA[>åVʺ'-u;86B EZI|nh[#pώsEr殪fc.TE(s5 }F4פlj NpN#_t-Zlԕq Aii 8!gI7xHʻl7+v>h5U%s$W#ǔ㐫[5.͢#\9J>\n=j_ oJO4&Z^}fjCTvXi Uޯl4âGsjQ\(h+i=E;Hn.os9s,r4݂OU9zcucj&ֳ`ahSۡڻR0$qo޺ELLd[w FQMK䒦Y&k#Kߜw*xBK.64N&9"~nIs.ntIT5snεv˕hulQasAswҲ5B<5[Ӽsʲj)\U͹D27ii. m#n^hh#5^fG7o /OtXYtY%Y20\NIZGIO*5Hu'='^UYDhۦ\a:gONL E(inEiqg]3irEc^DEθ<.5 fd4Idqk@'\%mÄ;Yfњw-}aדyzN8so4<[-**l#w'VO_DEUŜd*p fBw{V E舗øz<6FWTR½qj[:oqwϫqeάꟊ[]QJ~+G'6N%SwRxEy n}Hwz^?U>ptg]o۵0[XL2r 9gQw)ٝS$C'r": 89k#ABltڷw6:^*l+MDM$#;T2';UFğbw?4?ذA~_{c_uൡ9h>>.eF1Us_[/> dnwS8X"ϦɛM?%[t׊ʦSR9!Hc=6^9W[;SEUm U4(ϦVQS:S cHU#*QwUFӂsFϬVYF( O;vx ~2y־*li++L6a6> &-`l~/o}xɕ݌:A_e2h嵍'jN|qZL|=qq7-&F8 ܎OW*1TE)<(ctwZ2WjVG֭j$n-p9w!p}I<֐i{jb>2ՖW]WK5,rc!2k(s_ |WPRFs5'Y}MmĎ1OW:_g!u DH'yXWvMu&c "?VX(nV+5m,Ւ#9\+o*ZZ=, JhiD^{,cdDTl""$D_Gdj50DIq[ rxh Z"DDDDy.jR飳"*dO:"O:" &O:"d d"" dO:"O:" ""cairo-dock-plugins-3.3.2/alsaMixer/data/emblem-mute.svg000664 001750 001750 00000053060 12223247501 024141 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/alsaMixer/data/CMakeLists.txt000664 001750 001750 00000000355 12223247501 023746 0ustar00mbaertsmbaerts000000 000000 add_subdirectory(gauges) ########### install files ############### install(FILES ${CMAKE_CURRENT_BINARY_DIR}/AlsaMixer.conf default.svg mute.svg emblem-mute.svg broken.svg preview.jpg icon.png DESTINATION ${alsa_mixerdatadir}) cairo-dock-plugins-3.3.2/alsaMixer/data/AlsaMixer.conf.in000664 001750 001750 00000007327 12223247501 024355 0ustar00mbaertsmbaerts000000 000000 #@VERSION_ALSA_MIXER@ #[gtk-about] [Icon] #F[Icon] frame_maininfo= #d Name of the dock it belongs to: dock name = #s[Sound card name] Name of the icon as it will appear in its caption in the dock: name = #v sep_display= icon= #j[0;128] Desired icon size for this applet #{Set to 0 to use the default applet size} icon size = 0;0 #Y+[No;0;0;With default background;0;0;With custom background;1;1] Always display the icon, even when the dock is hidden? always_visi = 0 #C+ Background color to add in this case bg color = .8;.8;.8;.5 order= #A handbook=AlsaMixer #[gtk-convert] [Desklet] #X[Position] frame_pos = #b Lock position? #{If locked, the desklet cannot be moved by simply dragging it with the left mouse button. It can still be moved with ALT + left-click.} locked = false #j+[48;512] Desklet dimensions (width x height): #{Depending on your WindowManager, you may be able to resize this with ALT + middle-click or ALT + left-click.} size = 96;96 #i[-2048;2048] Desklet position (x, y): #{Depending on your WindowManager, you may be able to move this with ALT + left-click.. Negative values are counted from the right/bottom of the screen} x position=0 #i[-2048;2048] ... y position=0 #I[-180;180] Rotation: #{You can quickly rotate the desklet with the mouse, by dragging the little buttons on its left and top sides.} rotation = 0 #X[Visibility] frame_visi = #b Is detached from the dock initially detached=false #l[Normal;Keep above;Keep below;Keep on widget layer;Reserve space] Visibility: accessibility=0 #b Should be visible on all desktops? sticky=true #F[Decorations;gtk-orientation-portrait] frame_deco= #o+ Choose a decoration theme for this desklet: #{Choose 'Custom decorations' to define your own decorations below.} decorations = default #v sep_deco = #g+ Background image: #{Image to be displayed below drawings, e.g. a frame. Leave empty for no image.} bg desklet = #e+[0;1] Background transparency: bg alpha = 1 #i+[0;256] Left offset: #{in pixels. Use this to adjust the left position of drawings.} left offset = 0 #i+[0;256] Top offset: #{in pixels. Use this to adjust the top position of drawings.} top offset = 0 #i+[0;256] Right offset: #{in pixels. Use this to adjust the right position of drawings.} right offset = 0 #i+[0;256] Bottom offset: #{in pixels. Use this to adjust the bottom position of drawings.} bottom offset = 0 #g+ Foreground image: #{Image to be displayed above the drawings, e.g. a reflection. Leave empty for no image.} fg desklet = #e+[0;1] Foreground tansparency: fg alpha = 1 #[gtk-preferences] [Configuration] #F[Display;gtk-dialog-info] frame_disp = #l[No;On label;On icon] Display volume : display volume = 1 #v sep_disp_vol = #Y+[Icon;1;2;Icon with progress bar;1;2;Gauge;3;2] Display style display icon = 1 #g+[Default] Default icon: default icon = #g+[Default] Mute icon: mute icon = #h+[@gaugesdir@;gauges;gauges3;sound] Gauge theme/ theme = Sound-Mono #l+[No;With dock orientation;Yes] Rotate applet theme : rotate theme = 0 #v sep_disp = #g+[Default] Broken icon: broken icon = #F[Control;gtk-execute] frame_ctrl = #k Shortkey to show/hide the sound control dialog: shortkey = F3 #i[2;20] Variation for 1 mouse scroll, in %: scroll variation = 5 #b Hide the scale when mouse leaves the desklet? hide on leave = true #X[Alsa] frame_alsa = #L[] Sound card: card id = #L[] Select channel: mixer element = Master #E[] Choose a second channel to control (optional): #{On some cards, a channel only controls 1 side (right or left). You will then need to specify a second channel here, to control both sides. Most of the time, you should just leave this empty.} mixer element 2 = #s[Default] Specific command to run to show an advanced sound mixer: show mixer = indicator name = cairo-dock-plugins-3.3.2/alsaMixer/data/mute.svg000664 001750 001750 00000161105 12223247501 022702 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/alsaMixer/data/default.svg000664 001750 001750 00000053315 12223247501 023357 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/Sound-Mono/preview000664 001750 001750 00000012756 12223247501 026073 0ustar00mbaertsmbaerts000000 000000 PNG  IHDR>asBIT|d pHYsIIEtEXtSoftwarewww.inkscape.org<kIDATx}|TՙNfbk hjֺ].V.vnJ/mYDD*!b@20ɼd2y$z}9g2Թχ?fr<92"A"u C!@c1P(p 8 C!@c1P(p 8 C!@S4 (D|%@$ةLiǪ- b>NīΚ>]CkLL8Twm2*vROֵQzVV 2HL*Fj!a8׆I%A)FC:B"v*5_t/8pPԖ12=C:2k֕!%bKIA{lT e.rs3F]F|T;}u&]v8{C@ G,ʲp`GA0 /_u3x@)Ӧcd ;u%]c ^x]e.23"N^ !eQ8mH3j3.uD_jE v{ `.)m&on-$9c`P%! lV ,Li$3F2:8~ såq]D$zTUp8D")DcSS+\b7w BQDNnge@Fk>s;VYyL k l E**k@ssWz@fg3fO*bLCV${ںuk3VT\~F>cE =~h$^  ?3F.W$ͲE٠Ttt{+|%Y\&덾r%t @EŚ5Ƥr3XfY j=r;kv/B$@9zTwOTW \ca i@6@˘ }v?yztZ?1-2L@G#=JQ(fp3=AWv PfFT&0.2E'YKHcCE7|Guv'yFDx]1#r$` c&z)چFֆ H>aYbVg2b5B._M.sь N!)=Lx'Uӧ/- \g}tOF3"1 2f-OSݕT87JBi[(֛ؖ^wrOw;|1|nyw dF w^#;87Jm^xxPwhBJoo_#PbMZklܽN@CyV*q&B"&-1ԍp @?ٌD߸2D 2cvEnElfA[ٵsN'Y=(ޥ#X[f8<Qa'`nE â&Dw !Xf{mbE2cDR^uÅtB!oٳ,eۻ s |jYh ?WGb//vˮMDzXSd !\fz/D@=YpdCHaGGuɊRE,s D$ wK/=sr˦)2?'>̍jEXaWQjnN֋~Bq9`hKAǹ@EQEK!ع{w /13 (ܓbrD80"c0,ñx뵛Lp*P!,r}P11 F$;e%{H$Gͤ L\"cPb``Pd1KOwL Q8Sb&ud bp 2nŸt}M]A+V&Y~[[w "Esh@p?K@EDNIKNHpPHា10001߿Ox(b)^$1-&A;ŃG\RQCUUUU£ʊs0n),Kx6lPI!haE ?ٷ9JWc ^ q݄!0猤 䓋#U}2'3$CUϿxPd0UnximkwA̖"n",SA6ƕ[Y;܊F,sS0v3Ϩm'XD.{ q*Imܾ$Y `쮵^Wx[VڿY~<\S-n&"!X`n  su+W}X4&rNΨp8NcU.ò}Rɹ2I`rx0@KeeW/PF6$5^|P(h,6AwOf A離ŧl"n'U 9;˖jذazK Tiv?x ;\WA  -%K"ų "xz@ 1@lBh|ڤBry%mncdߘ_?jf½"#kP͚v&\_?g {1T"#6"j`?w]*sd@hpC߈HKZt@m&qqq==۷ @h4s2y86v?{ jqÔyTx~* {c%±]O[jѸɣT8hiߜKcDMKssubJU>nc31;;mBW'{߯ igx6ĤX,>]($  9Xl_ ʵkuFQvQ.iJ6~Ua:3ϮK!; /9 yHn@g6[$AĈT:GÏRr@"")#ٽ/dNUDEꗳ+BDDr񾚈j3^l<X%"ZfmE,#$!;v.%be="#HsqTGެmoo_7pIS>$=DTGD"!_Ơ)p۫V:'e_a۽~_?eLfǃcVGV8w݂j})S.e9}xEŚ߰nh;gx;v(:{ċOE]PZOG| 9 rX ˆ\ty$ڴ孕 d>gLIL-fO[UUM@N @Cɋ!`(D2e~HQW28X?#H@;*~ups Ͽ[4"?\ 9'd5kvNgzkC^f#nO^~ FTZڻyNDAkݴ%־@c}CC_﮻~sz>"vL&y?lVJxa4u,/nSDet'H&0%;MZ,qO io<(ҳWNhچH!=oH:@w`\1}D.Zcl$o>Ch=DZyeyM'BoI{|sk\ʿ ^QM\R)RY"W5>e!,Zv:d.^\]&2+V*t:SqVIEk'0a kݎPٶ]6Fck'0!"C0"qχ}CN5e"gZzuH?!(/8.{ڗ,[ Irĉ2^st=401#+V>tۆÓ(?1 d>kp8wtu}ztԒt Xߘ'N !@?m uCyAe:^2||RA!}#U{  Z2=j! C!@c1P(p 8 =#>IENDB`cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/Sound-Mono/1.svg000664 001750 001750 00000004646 12223247501 025347 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/Sound-Mono/0.svg000664 001750 001750 00000004723 12223247501 025342 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/Sound-Mono/undef.svg000664 001750 001750 00000002723 12223247501 026302 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/Sound-Mono/2.svg000664 001750 001750 00000004571 12223247501 025345 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/Sound-Mono/CMakeLists.txt000664 001750 001750 00000000256 12223247501 027217 0ustar00mbaertsmbaerts000000 000000 ########### install files ############### install(FILES 0.svg 1.svg 2.svg 3.svg preview readme theme.xml undef.svg version DESTINATION ${gaugesdir}/Sound-Mono ) cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/Sound-Mono/readme000775 001750 001750 00000000102 12223247501 025630 0ustar00mbaertsmbaerts000000 000000 Official Ubuntu-Mono's Icons assembled by Matttbe for Cairo-Dock. cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/Sound-Mono/theme.xml000664 001750 001750 00000000436 12223247501 026303 0ustar00mbaertsmbaerts000000 000000 Sound: Ubuntu Mono Dark 3 Ubuntu-Mono Designers 0.svg 1.svg 2.svg 3.svg undef.svg cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/Sound-Mono/3.svg000664 001750 001750 00000003650 12223247501 025343 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/Sound-Mono/version000664 001750 001750 00000000002 12223247501 026054 0ustar00mbaertsmbaerts000000 000000 1 cairo-dock-plugins-3.3.2/alsaMixer/data/gauges/CMakeLists.txt000664 001750 001750 00000000036 12223247501 025215 0ustar00mbaertsmbaerts000000 000000 add_subdirectory(Sound-Mono) cairo-dock-plugins-3.3.2/Applets.stable000664 001750 001750 00000002162 12223247501 021152 0ustar00mbaertsmbaerts000000 000000 ###Core plug-ins : ###you *should* integrate them, as they extend the dock's functionnalities. dock-rendering desklet-rendering dialog-rendering gnome-integration-old gnome-integration xfce-integration Dbus Animated-icons icon-effect illusion drop-indicator ###Stable applets, considered as finished : shortcuts clock logout dustbin showDesklets Xgamma alsaMixer weather terminal Cairo-Penguin showDesktop # compiz-icon # removed in v2.4.0 slider Clipper GMenu powermanager switcher motion-blur show-mouse quick-browser Toons ###Will be replaced in a near future : netspeed wifi ###Stable but few minor bugs exist : tomboy systray stack keyboard-indicator ###Last addition of v2.1.0 : System-Monitor dnd2share musicPlayer mail ###Added in v2.1.3 RSSReader kde-integration ###Added in v2.2.0 MeMenu Messaging-Menu Folders ###Added in v2.3.0 Remote-Control Recent-Events Status-Notifier ###Added in v2.4.0 Composite-Manager Impulse ###All other applets are considered to be either not enough functionnal, buggy/untested, or under heavy development. #Sound-Menu #Application-Menu #Scooby-Do #Network-Monitor #Disks #Doncky #KDE experimental cairo-dock-plugins-3.3.2/wifi/src/applet-struct.h000775 001750 001750 00000004007 12223247501 023056 0ustar00mbaertsmbaerts000000 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 __CD_APPLET_STRUCT__ #define __CD_APPLET_STRUCT__ #include typedef enum { WIFI_INFO_NONE = 0, WIFI_INFO_SIGNAL_STRENGTH_LEVEL, WIFI_INFO_SIGNAL_STRENGTH_PERCENT, WIFI_INFO_SIGNAL_STRENGTH_DB, WIFI_NB_INFO_TYPE } CDWifiInfoType; typedef enum { WIFI_QUALITY_NO_SIGNAL = 0, WIFI_QUALITY_VERY_LOW, WIFI_QUALITY_LOW, WIFI_QUALITY_MIDDLE, WIFI_QUALITY_GOOD, WIFI_QUALITY_EXCELLENT, WIFI_NB_QUALITY } CDWifiQuality; typedef enum _CDWifiDisplayType { CD_WIFI_GAUGE=0, CD_WIFI_GRAPH, CD_WIFI_BAR, CD_WIFI_NB_TYPES } CDWifiDisplayType; struct _AppletConfig { gchar *defaultTitle; gchar *cDefaultIcon; gchar *cNoSignalIcon; gchar *cGThemePath; gchar *cUserCommand; CDWifiInfoType quickInfoType; CDWifiDisplayType iDisplayType; gint iCheckInterval; CairoDockTypeGraph iGraphType; gdouble fLowColor[3]; gdouble fHigholor[3]; gdouble fBgColor[4]; gdouble fSmoothFactor; }; struct _AppletData { // shared memory CDWifiQuality iQuality, iPreviousQuality; gint iPercent, iPrevPercent; gint iSignalLevel, iPrevSignalLevel; gint iPrevNoiseLevel, iNoiseLevel; gchar *cESSID; gchar *cInterface; gchar *cAccessPoint; // end of shared memory gboolean bWirelessExt; CairoDockTask *pTask; gchar *cIWConfigPath; }; #endif cairo-dock-plugins-3.3.2/wifi/src/applet-wifi.h000775 001750 001750 00000001670 12223247501 022473 0ustar00mbaertsmbaerts000000 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 __APPLET_WIFI__ #define __APPLET_WIFI__ #include void cd_wifi_get_data (gpointer data); gboolean cd_wifi_update_from_data (gpointer data); #endif cairo-dock-plugins-3.3.2/wifi/src/applet-init.h000775 001750 001750 00000001553 12223247501 022500 0ustar00mbaertsmbaerts000000 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 __APPLET_INIT__ #define __APPLET_INIT__ #include CD_APPLET_H #endif cairo-dock-plugins-3.3.2/wifi/src/applet-notifications.h000775 001750 001750 00000001677 12223247501 024415 0ustar00mbaertsmbaerts000000 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 __APPLET_NOTIFICATIONS__ #define __APPLET_NOTIFICATIONS__ #include CD_APPLET_ON_CLICK_H CD_APPLET_ON_BUILD_MENU_H CD_APPLET_ON_MIDDLE_CLICK_H #endif cairo-dock-plugins-3.3.2/wifi/src/CMakeLists.txt000664 001750 001750 00000004011 12223247501 022626 0ustar00mbaertsmbaerts000000 000000 ########### sources ############### SET(cd-wifi_LIB_SRCS applet-init.c applet-init.h applet-config.c applet-config.h applet-wifi.c applet-wifi.h applet-notifications.c applet-notifications.h applet-draw.c applet-draw.h applet-struct.h ) add_library(${PACKAGE_WIFI} SHARED ${cd-wifi_LIB_SRCS}) ########### compil ############### add_definitions (-DMY_APPLET_SHARE_DATA_DIR="${wifidatadir}") add_definitions (-DMY_APPLET_PREVIEW_FILE="preview.jpg") add_definitions (-DMY_APPLET_CONF_FILE="wifi.conf") add_definitions (-DMY_APPLET_USER_DATA_DIR="wifi") add_definitions (-DMY_APPLET_VERSION="${VERSION_WIFI}") add_definitions (-DMY_APPLET_GETTEXT_DOMAIN="${GETTEXT_WIFI}") add_definitions (-DMY_APPLET_DOCK_VERSION="${dock_version}") add_definitions (-DMY_APPLET_ICON_FILE="icon.png") include_directories ( ${PACKAGE_INCLUDE_DIRS}) link_directories ( ${PACKAGE_LIBRARY_DIRS}) target_link_libraries (${PACKAGE_WIFI} ${PACKAGE_LIBRARIES}) ########### install files ############### install(TARGETS ${PACKAGE_WIFI} DESTINATION ${pluginsdir}) #original Makefile.am contents follow: # #dnl Process this file with automake to produce Makefile.in # #lib_LTLIBRARIES = # libcd-wifi.la # # #libcd_wifi_la_SOURCES = # applet-init.c # applet-init.h # applet-config.c # applet-config.h # applet-wifi.c # applet-wifi.h # applet-notifications.c # applet-notifications.h # applet-draw.c # applet-draw.h # applet-struct.h # # #dock_version = `pkg-config --modversion cairo-dock` # #libcd_wifi_la_CFLAGS = # -I$(top_srcdir)/src # $(PACKAGE_CFLAGS) # -DMY_APPLET_SHARE_DATA_DIR="${wifidatadir)" # -DMY_APPLET_PREVIEW_FILE="preview.jpg" # -DMY_APPLET_CONF_FILE="wifi.conf" # -DMY_APPLET_USER_DATA_DIR="wifi" # -DMY_APPLET_VERSION="${VERSION_WIFI)" # -DMY_APPLET_GETTEXT_DOMAIN="${GETTEXT_WIFI)" # -DMY_APPLET_DOCK_VERSION="${dock_version)" # -DMY_APPLET_ICON_FILE="icon.png" # -std=c99 # -Werror-implicit-function-declaration ## -g -ggdb -W -Wall # # #libcd_wifi_la_LIBADD = # $(PACKAGE_LIBS) -lm # # #libcd_wifi_la_LDFLAGS = # -avoid-version -module cairo-dock-plugins-3.3.2/wifi/src/applet-init.c000775 001750 001750 00000012547 12223247501 022500 0ustar00mbaertsmbaerts000000 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 "stdlib.h" #include "applet-config.h" #include "applet-notifications.h" #include "applet-struct.h" #include "applet-wifi.h" #include "applet-draw.h" #include "applet-init.h" CD_APPLET_DEFINE_BEGIN ("wifi", 3, 0, 2, CAIRO_DOCK_CATEGORY_APPLET_INTERNET, N_("This applet shows you the signal strength of the first active wifi connection\n" "Left-click to pop-up some info," "Middle-click to re-check immediately."), "ChAnGFu (Rémy Robertson)") CD_APPLET_DEFINE_COMMON_APPLET_INTERFACE CD_APPLET_ALLOW_EMPTY_TITLE CD_APPLET_REDEFINE_TITLE (N_("Wifi")) CD_APPLET_DEFINE_END static void _set_data_renderer (GldiModuleInstance *myApplet, gboolean bReload) { CairoDataRendererAttribute *pRenderAttr = NULL; // attributes for the global data-renderer. CairoGaugeAttribute aGaugeAttr; // gauge attributes. CairoGraphAttribute aGraphAttr; // graph attributes. CairoGraphAttribute aProgressBarAttr; // graph attributes. switch (myConfig.iDisplayType) { case CD_WIFI_GAUGE: { memset (&aGaugeAttr, 0, sizeof (CairoGaugeAttribute)); pRenderAttr = CAIRO_DATA_RENDERER_ATTRIBUTE (&aGaugeAttr); pRenderAttr->cModelName = "gauge"; aGaugeAttr.cThemePath = myConfig.cGThemePath; } break; case CD_WIFI_GRAPH: { memset (&aGraphAttr, 0, sizeof (CairoGraphAttribute)); pRenderAttr = CAIRO_DATA_RENDERER_ATTRIBUTE (&aGraphAttr); pRenderAttr->cModelName = "graph"; int w, h; CD_APPLET_GET_MY_ICON_EXTENT (&w, &h); pRenderAttr->iMemorySize = (w > 1 ? w : 32); // fWidth can be <= 1 in desklet mode when loading it aGraphAttr.iType = myConfig.iGraphType; aGraphAttr.fHighColor = myConfig.fHigholor; aGraphAttr.fLowColor = myConfig.fLowColor; memcpy (aGraphAttr.fBackGroundColor, myConfig.fBgColor, 4*sizeof (double)); } break; case CD_WIFI_BAR: { CD_APPLET_SET_USER_IMAGE_ON_MY_ICON (myConfig.cDefaultIcon, "default.svg"); memset (&aProgressBarAttr, 0, sizeof (CairoProgressBarAttribute)); pRenderAttr = CAIRO_DATA_RENDERER_ATTRIBUTE (&aProgressBarAttr); pRenderAttr->cModelName = "progressbar"; } break; default: break; } if (pRenderAttr != NULL) { pRenderAttr->iLatencyTime = myConfig.iCheckInterval * 1000 * myConfig.fSmoothFactor; CD_APPLET_ADD_DATA_RENDERER_ON_MY_ICON (pRenderAttr); } } static void _set_iwconfig_path (GldiModuleInstance *myApplet) { gchar *cResult = cairo_dock_launch_command_sync ("which iwconfig"); if (cResult != NULL && *cResult == '/') myData.cIWConfigPath = cResult; else { g_free (cResult); // if '/sbin' is not in $PATH myData.cIWConfigPath = g_strdup ("/sbin/iwconfig"); } } CD_APPLET_INIT_BEGIN if (myDesklet != NULL) { CD_APPLET_SET_DESKLET_RENDERER ("Simple"); CD_APPLET_ALLOW_NO_CLICKABLE_DESKLET; } // Renderer Init _set_data_renderer (myApplet, FALSE); // check iwconfig path _set_iwconfig_path (myApplet); // Initialisation of the periodic task myData.iPreviousQuality = -2; // force a redraw. myData.pTask = cairo_dock_new_task (myConfig.iCheckInterval, (CairoDockGetDataAsyncFunc) cd_wifi_get_data, (CairoDockUpdateSyncFunc) cd_wifi_update_from_data, myApplet); if (cairo_dock_is_loading ()) cairo_dock_launch_task_delayed (myData.pTask, 2000); else cairo_dock_launch_task (myData.pTask); CD_APPLET_REGISTER_FOR_CLICK_EVENT; CD_APPLET_REGISTER_FOR_BUILD_MENU_EVENT; CD_APPLET_REGISTER_FOR_MIDDLE_CLICK_EVENT; CD_APPLET_INIT_END CD_APPLET_STOP_BEGIN //\_______________ On se desabonne de nos notifications. CD_APPLET_UNREGISTER_FOR_CLICK_EVENT; CD_APPLET_UNREGISTER_FOR_BUILD_MENU_EVENT; CD_APPLET_UNREGISTER_FOR_MIDDLE_CLICK_EVENT; CD_APPLET_STOP_END CD_APPLET_RELOAD_BEGIN //\_______________ On relance avec la nouvelle config ou on redessine. if (CD_APPLET_MY_CONFIG_CHANGED) { if (myDesklet && CD_APPLET_MY_CONTAINER_TYPE_CHANGED) // we are now in a desklet, set a renderer. { CD_APPLET_SET_DESKLET_RENDERER ("Simple"); CD_APPLET_ALLOW_NO_CLICKABLE_DESKLET; } _set_data_renderer (myApplet, TRUE); myData.iQuality = -2; // force le redessin. myData.iPercent = -2; myData.iSignalLevel = -2; CD_APPLET_SET_QUICK_INFO_ON_MY_ICON (NULL); cairo_dock_relaunch_task_immediately (myData.pTask, myConfig.iCheckInterval); } else // on redessine juste l'icone. { ///CD_APPLET_RELOAD_MY_DATA_RENDERER (NULL); if (myConfig.iDisplayType == CD_WIFI_GRAPH) CD_APPLET_SET_MY_DATA_RENDERER_HISTORY_TO_MAX; /**myData.iQuality = -2; // force le redessin. if (! cairo_dock_task_is_running (myData.pTask)) { if (myData.bWirelessExt) { cd_wifi_draw_icon (); } else { cd_wifi_draw_no_wireless_extension (); } }*/ } CD_APPLET_RELOAD_END cairo-dock-plugins-3.3.2/wifi/src/applet-wifi.c000775 001750 001750 00000014205 12223247501 022464 0ustar00mbaertsmbaerts000000 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 . */ #define _BSD_SOURCE #include #include #include #include #include #include #include "applet-struct.h" #include "applet-notifications.h" #include "applet-draw.h" #include "applet-wifi.h" #define _pick_string(cValueName, cValue) \ str = g_strstr_len (cOneInfopipe, -1, cValueName);\ if (str) {\ str += strlen (cValueName) + 1;\ while (*str == ' ')\ str ++;\ if (*str == '"') {\ str ++;\ str2 = strchr (str, '"'); }\ else {\ str2 = strchr (str, ' '); }\ if (str2) {\ cValue = g_strndup (str, str2 - str); }\ else {\ cValue = g_strdup (str); }\ cd_debug ("%s : %s", cValueName, cValue); } #define _pick_value(cValueName, iValue, iMaxValue)\ str = g_strstr_len (cOneInfopipe, -1, cValueName);\ if (str) {\ str += strlen (cValueName) + 1;\ iValue = atoi (str);\ str2 = strchr (str, '/');\ if (str2)\ iMaxValue = atoi (str2+1);\ cd_debug ("%s : %d (/%d)", cValueName, iValue, iMaxValue); } void cd_wifi_get_data (gpointer data) { myData.iPreviousQuality = myData.iQuality; myData.iQuality = -1; myData.iPrevPercent = myData.iPercent; myData.iPercent = -1; myData.iPrevSignalLevel = myData.iSignalLevel; myData.iSignalLevel = -1; myData.iPrevNoiseLevel = myData.iNoiseLevel; myData.iNoiseLevel = -1; g_free (myData.cESSID); myData.cESSID = NULL; g_free (myData.cInterface); myData.cInterface = NULL; g_free (myData.cAccessPoint); myData.cAccessPoint = NULL; /* for tests: myData.iPercent = g_random_int_range (0, 100); myData.iQuality = 5 * myData.iPercent/100; myData.cInterface = g_strdup ("toto"); return;*/ /* iwconfig prints wireless interface on stdout * and other interfaces (e.g. eth0 -> no wireless extensions.) on stderr... */ gchar *cResult = cairo_dock_launch_command_sync_with_stderr (myData.cIWConfigPath, FALSE); // to avoid warnings... or with "sh -c \"iwconfig 2> /dev/null\"" but it uses 2 process each time... if (cResult == NULL || *cResult == '\0') // error when launching iwconfig: rights problem, iwconfig not available or no wifi interface? { g_free (cResult); return ; } //eth0 no wireless extensions. //eth2 IEEE 802.11 Nickname:"" //Access Point: Not-Associated //wlan0 IEEE 802.11abg ESSID:"NETXHO" //Mode:Managed Frequency:2.452 GHz Access Point: 00:24:2B:48:07:21 //Bit Rate=54 Mb/s Tx-Power=15 dBm //Retry long limit:7 RTS thr:off Fragment thr:off //Encryption key:C6DA-6974-1612-DA99-3049-FDC0-1399-23BA-894E-67B0-9C8B-72C7-EE5B-5876-5C58-331B [2] //Power Management:off //Link Quality=52/70 Signal level=-58 dBm Noise level=-127 dBm //Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 //Tx excessive retries:0 Invalid misc:0 Missed beacon:0 gchar **cInfopipesList = g_strsplit (cResult, "\n", -1); g_free (cResult); gchar *cOneInfopipe, *str, *str2; int i, iMaxValue=1; // gcc rale si on n'initialise pas. for (i = 0; cInfopipesList[i] != NULL; i ++) { cOneInfopipe = cInfopipesList[i]; if (*cOneInfopipe == '\0' || *cOneInfopipe == '\n' ) // EOL: a new interface. { if (myData.cInterface != NULL) // we only want one, break break; else continue; } if (myData.cInterface == NULL) // we don't still have any interface { str = strchr (cOneInfopipe, ' '); // interface's name is at the beginning of the line. if (str) { str2 = str + 1; while (*str2 == ' ') str2 ++; if (strncmp (str2, "no wireless", 11) != 0) myData.cInterface = g_strndup (cOneInfopipe, str - cOneInfopipe); } cd_debug ("interface : %s", myData.cInterface); if (myData.cInterface == NULL) // no new info, skip it continue; } if (myData.cESSID == NULL) { _pick_string ("ESSID", myData.cESSID); // eth1 IEEE 802.11g ESSID:"bla bla bla" } /*if (myData.cNickName == NULL) { _pick_string ("Nickname", myData.cNickName); }*/ if (myData.cAccessPoint == NULL) { _pick_string ("Access Point", myData.cAccessPoint); } if (myData.iQuality >= WIFI_NB_QUALITY) // Link Quality=54/100 Signal level=-76 dBm Noise level=-78 dBm OU Link Quality:5 Signal level:219 Noise level:177 { iMaxValue = 0; _pick_value ("Link Quality", myData.iQuality, iMaxValue); if (iMaxValue != 0) // old version, quality in % { myData.iPercent = 100. * myData.iQuality / iMaxValue; if (myData.iPercent <= 0) myData.iQuality = WIFI_QUALITY_NO_SIGNAL; else if (myData.iPercent < 20) myData.iQuality = WIFI_QUALITY_VERY_LOW; else if (myData.iPercent < 40) myData.iQuality = WIFI_QUALITY_LOW; else if (myData.iPercent < 60) myData.iQuality = WIFI_QUALITY_MIDDLE; else if (myData.iPercent < 80) myData.iQuality = WIFI_QUALITY_GOOD; else myData.iQuality = WIFI_QUALITY_EXCELLENT; } else { myData.iPercent = 100. * myData.iQuality / (WIFI_NB_QUALITY-1); } } if (myData.iSignalLevel == -1) { _pick_value ("Signal level", myData.iSignalLevel, iMaxValue); } if (myData.iNoiseLevel == -1) { _pick_value ("Noise level", myData.iNoiseLevel, iMaxValue); } } g_strfreev (cInfopipesList); } gboolean cd_wifi_update_from_data (gpointer data) { if (myData.cInterface != NULL) { myData.bWirelessExt = TRUE; cd_wifi_draw_icon (); cairo_dock_set_normal_task_frequency (myData.pTask); } else { myData.bWirelessExt = FALSE; cd_wifi_draw_no_wireless_extension (); cairo_dock_downgrade_task_frequency (myData.pTask); } return TRUE; } cairo-dock-plugins-3.3.2/wifi/src/applet-draw.c000775 001750 001750 00000011570 12223247501 022465 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-wifi.h" #include "applet-draw.h" static const gchar *s_cLevelQualityName[WIFI_NB_QUALITY] = {N_("None"), N_("Very Low"), N_("Low"), N_("Middle"), N_("Good"), N_("Excellent")}; void cd_wifi_draw_no_wireless_extension (void) { cd_debug ("No Wireless: %d, %d", myData.iPreviousQuality, myData.iQuality); if (myData.iPreviousQuality != myData.iQuality) { if (myDesklet != NULL) CD_APPLET_SET_DESKLET_RENDERER ("Simple"); myData.iPreviousQuality = myData.iQuality; // reset label if (myConfig.defaultTitle) // has another default name CD_APPLET_SET_NAME_FOR_MY_ICON (myConfig.defaultTitle); else CD_APPLET_SET_NAME_FOR_MY_ICON (myApplet->pModule->pVisitCard->cTitle); // reset quick-info if (myConfig.quickInfoType != WIFI_INFO_NONE) // if we want to have a quick info CD_APPLET_SET_QUICK_INFO_ON_MY_ICON ("N/A"); // reset the data-renderer if (myConfig.iDisplayType == CD_WIFI_BAR) CD_APPLET_SET_USER_IMAGE_ON_MY_ICON (myConfig.cNoSignalIcon, "no-signal.svg"); double fValue = CAIRO_DATA_RENDERER_UNDEF_VALUE; CD_APPLET_RENDER_NEW_DATA_ON_MY_ICON (&fValue); } else if (myConfig.iDisplayType == CD_WIFI_GRAPH) { double fValue = CAIRO_DATA_RENDERER_UNDEF_VALUE; CD_APPLET_RENDER_NEW_DATA_ON_MY_ICON (&fValue); } } void cd_wifi_draw_icon (void) { cd_debug ("Draw Wireless: %d, %d", myData.iPreviousQuality, myData.iQuality); if (myData.iPercent <= 0) { cd_wifi_draw_no_wireless_extension (); // not connected return; } // update quick-info gboolean bNeedRedraw = FALSE; switch (myConfig.quickInfoType) { case WIFI_INFO_SIGNAL_STRENGTH_LEVEL : if (myData.iQuality != myData.iPreviousQuality && myData.iQuality < WIFI_NB_QUALITY) { CD_APPLET_SET_QUICK_INFO_ON_MY_ICON (D_(s_cLevelQualityName[myData.iQuality])); bNeedRedraw = TRUE; } break; case WIFI_INFO_SIGNAL_STRENGTH_PERCENT : if (myData.iPrevPercent != myData.iPercent) { myData.iPrevPercent = myData.iPercent; CD_APPLET_SET_QUICK_INFO_ON_MY_ICON_PRINTF ("%d%%", myData.iPercent); bNeedRedraw = TRUE; } break; case WIFI_INFO_SIGNAL_STRENGTH_DB : if (myData.iPrevSignalLevel != myData.iSignalLevel || myData.iPrevNoiseLevel != myData.iNoiseLevel) { myData.iPrevSignalLevel = myData.iSignalLevel; myData.iPrevNoiseLevel = myData.iNoiseLevel; CD_APPLET_SET_QUICK_INFO_ON_MY_ICON_PRINTF ("%d/%d", myData.iSignalLevel, myData.iNoiseLevel); bNeedRedraw = TRUE; } break; default: // WIFI_INFO_NONE break; } if (myData.iQuality != myData.iPreviousQuality || myConfig.iDisplayType == CD_WIFI_GRAPH) { myData.iPreviousQuality = myData.iQuality; //cd_debug ("Wifi - Value have changed, redraw. (Use Gauge: %d)", myConfig.bUseGauge); double fValue = (double) myData.iPercent / 100.; CD_APPLET_RENDER_NEW_DATA_ON_MY_ICON (&fValue); bNeedRedraw = FALSE; } if (myData.cESSID != NULL && myConfig.defaultTitle == NULL && cairo_dock_strings_differ (myData.cESSID, myIcon->cName)) { CD_APPLET_SET_NAME_FOR_MY_ICON (myData.cESSID); } if (bNeedRedraw) CD_APPLET_REDRAW_MY_ICON; } void cd_wifi_bubble (void) { if (cairo_dock_task_is_running (myData.pTask)) { gldi_dialog_show_temporary (D_("Checking connection...\nPlease retry in a few seconds"), myIcon, myContainer, 3000); return ; } GString *sInfo = g_string_new (""); const gchar *cIconPath; if (! myData.bWirelessExt) { cIconPath = MY_APPLET_SHARE_DATA_DIR"/no-signal.svg"; g_string_assign (sInfo, D_("WiFi disabled.")); } else { cIconPath = MY_APPLET_SHARE_DATA_DIR"/default.svg"; g_string_assign (sInfo, D_("Wifi enabled.")); g_string_printf (sInfo, "%s : %s\n%s : %s\n%s : %s\n%s : %d/%d", D_ ("Network ID"), myData.cESSID ? myData.cESSID : D_("unknown"), D_ ("Access point"), myData.cAccessPoint, D_ ("Interface"), myData.cInterface, D_ ("Signal Quality"), myData.iQuality, WIFI_NB_QUALITY-1); } //cd_debug ("%s (%s)", sInfo->str, cIconPath); gldi_dialog_show_temporary_with_icon (sInfo->str, myIcon, myContainer, 6000, cIconPath); g_string_free (sInfo, TRUE); } cairo-dock-plugins-3.3.2/wifi/src/applet-draw.h000775 001750 001750 00000001714 12223247501 022471 0ustar00mbaertsmbaerts000000 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 __APPLET_DRAW__ #define __APPLET_DRAW__ #include "applet-struct.h" void cd_wifi_draw_no_wireless_extension (void); void cd_wifi_draw_icon (void); void cd_wifi_bubble(void); #endif cairo-dock-plugins-3.3.2/wifi/src/applet-notifications.c000775 001750 001750 00000005774 12223247501 024412 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-notifications.h" #include "applet-wifi.h" #include "applet-draw.h" CD_APPLET_ON_CLICK_BEGIN gldi_dialogs_remove_on_icon (myIcon); cd_wifi_bubble(); CD_APPLET_ON_CLICK_END static void _wifi_recheck_wireless_extension (GtkMenuItem *menu_item, gpointer data) { cairo_dock_stop_task (myData.pTask); cairo_dock_launch_task (myData.pTask); } static void _cd_wifi_show_config (GtkMenuItem *menu_item, gpointer data) { if (myConfig.cUserCommand != NULL) { cairo_dock_launch_command (myConfig.cUserCommand); return; } const gchar *cCommand = "nm-connection-editor"; // network-admin n'est plus present depuis Intrepid, et nm-connection-editor marche aussi sous KDE. cairo_dock_launch_command (cCommand); } static void toggle_wlan (void) { DBusGProxy *dbus_proxy_nm = cairo_dock_create_new_system_proxy ( "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager"); g_return_if_fail (dbus_proxy_nm != NULL); guint state = 0; dbus_g_proxy_call (dbus_proxy_nm, "state", NULL, G_TYPE_INVALID, G_TYPE_UINT, &state, G_TYPE_INVALID); cd_debug ("current network state : %d", state); if (state == 3) // actif { dbus_g_proxy_call_no_reply (dbus_proxy_nm, "sleep", G_TYPE_INVALID, G_TYPE_INVALID); } else if (state == 1) // inactif { dbus_g_proxy_call_no_reply (dbus_proxy_nm, "wake", G_TYPE_INVALID, G_TYPE_INVALID); } g_object_unref (dbus_proxy_nm); } CD_APPLET_ON_BUILD_MENU_BEGIN if (! myData.bWirelessExt) CD_APPLET_ADD_IN_MENU_WITH_STOCK (D_("Check for Wireless Extension"), GTK_STOCK_REFRESH, _wifi_recheck_wireless_extension, CD_APPLET_MY_MENU); else { gchar *cLabel = g_strdup_printf ("%s (%s)", D_("Toggle wifi ON/OFF"), D_("middle-click")); CD_APPLET_ADD_IN_MENU_WITH_STOCK (cLabel, (myData.iQuality == WIFI_QUALITY_NO_SIGNAL ? GTK_STOCK_MEDIA_PLAY : GTK_STOCK_MEDIA_PAUSE), toggle_wlan, CD_APPLET_MY_MENU); g_free (cLabel); } CD_APPLET_ADD_IN_MENU_WITH_STOCK (D_("Network Administration"), GTK_STOCK_PREFERENCES, _cd_wifi_show_config, CD_APPLET_MY_MENU); CD_APPLET_ON_BUILD_MENU_END CD_APPLET_ON_MIDDLE_CLICK_BEGIN toggle_wlan (); CD_APPLET_ON_MIDDLE_CLICK_END cairo-dock-plugins-3.3.2/wifi/src/applet-config.c000775 001750 001750 00000006023 12223247501 022772 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-config.h" CD_APPLET_GET_CONFIG_BEGIN //\_________________ On recupere toutes les valeurs de notre fichier de conf. myConfig.defaultTitle = CD_CONFIG_GET_STRING ("Icon", "name"); myConfig.iCheckInterval = CD_CONFIG_GET_INTEGER_WITH_DEFAULT ("Configuration", "delay", 10); myConfig.fSmoothFactor = CD_CONFIG_GET_DOUBLE ("Configuration", "smooth"); myConfig.cUserCommand = CD_CONFIG_GET_STRING ("Configuration", "command"); myConfig.quickInfoType = CD_CONFIG_GET_INTEGER_WITH_DEFAULT ("Configuration", "signal_type", WIFI_INFO_SIGNAL_STRENGTH_LEVEL); myConfig.iDisplayType = CD_CONFIG_GET_INTEGER_WITH_DEFAULT ("Configuration", "renderer", 0); myConfig.cGThemePath = CD_CONFIG_GET_GAUGE_THEME ("Configuration", "theme"); myConfig.iGraphType = CD_CONFIG_GET_INTEGER ("Configuration", "graphic type"); CD_CONFIG_GET_COLOR_RVB ("Configuration", "low color", myConfig.fLowColor); CD_CONFIG_GET_COLOR_RVB ("Configuration", "high color", myConfig.fHigholor); CD_CONFIG_GET_COLOR ("Configuration", "bg color", myConfig.fBgColor); if (! g_key_file_has_key (CD_APPLET_MY_KEY_FILE, "Configuration", "default_icon", NULL)) // new option -> get the previous "excellent" user icon { myConfig.cDefaultIcon = CD_CONFIG_GET_STRING ("Configuration", "icon_5"); g_key_file_set_string (CD_APPLET_MY_KEY_FILE, "Configuration", "default_icon", myConfig.cDefaultIcon?myConfig.cDefaultIcon:""); myConfig.cNoSignalIcon = CD_CONFIG_GET_STRING ("Configuration", "icon_0"); g_key_file_set_string (CD_APPLET_MY_KEY_FILE, "Configuration", "no_signal_icon", myConfig.cDefaultIcon?myConfig.cDefaultIcon:""); } else { myConfig.cDefaultIcon = CD_CONFIG_GET_STRING ("Configuration", "default_icon"); myConfig.cNoSignalIcon = CD_CONFIG_GET_STRING ("Configuration", "no_signal_icon"); } CD_APPLET_GET_CONFIG_END CD_APPLET_RESET_CONFIG_BEGIN g_free (myConfig.cGThemePath); g_free (myConfig.defaultTitle); g_free (myConfig.cUserCommand); CD_APPLET_RESET_CONFIG_END CD_APPLET_RESET_DATA_BEGIN cairo_dock_free_task (myData.pTask); CD_APPLET_REMOVE_MY_DATA_RENDERER; g_free (myData.cESSID); g_free (myData.cInterface); g_free (myData.cAccessPoint); g_free (myData.cIWConfigPath); CD_APPLET_RESET_DATA_END cairo-dock-plugins-3.3.2/wifi/src/applet-config.h000775 001750 001750 00000001565 12223247501 023005 0ustar00mbaertsmbaerts000000 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 __APPLET_CONFIG__ #define __APPLET_CONFIG__ #include CD_APPLET_CONFIG_H #endif cairo-dock-plugins-3.3.2/wifi/CMakeLists.txt000664 001750 001750 00000000332 12223247501 022041 0ustar00mbaertsmbaerts000000 000000 add_subdirectory(src) add_subdirectory(data) ########### install files ############### #original Makefile.am contents follow: ##dnl Process this file with automake to produce Makefile.in # #SUBDIRS = . src data cairo-dock-plugins-3.3.2/wifi/data/link-3.svg000664 001750 001750 00000100361 12223247501 022033 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/no-signal.svg000664 001750 001750 00000045074 12223247501 022636 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/icon.png000664 001750 001750 00000013761 12223247501 021662 0ustar00mbaertsmbaerts000000 000000 PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<nIDATx{$uVUW?g絳3(!Rơ E=2a:XpH H cE2d )#2%+!"&% rwgvv3={1Crn||j%" i~>gq͜;`[d=˟}z8O~7uLB= 9;:Zuk9g\Mq·~cXR 5{`Z8ˆ9vM-v-Wf`ŭ;~?5UWs(g=u28pj IfI˸JпV c-ıaqYXg?S|{rfٻϜ7}dfN'ݳNZc{geڽv7\Gfm}8 ,!*/ xQ d~~V>ύ,~F:r=x`azFDzI,V`ckgՍUڝ6J) a@u0Q<Ƴ瞢m1+졣$mtSڪܸ>_i/\ZB{9ma$wS]R0@itpZ2c1R#n]2x³$iNc82k1Ƒ9BSBNB]9.s|MOW Bͦ!5h#EJ U1ΰ1o{E678 \FHp :u +DlVczfNo}ujk; 8$Da@ 8DPo9'XޠP`ő)))IC7I9Jj&4Z=6v$@8!Cam \>=?%z]w۵l2&"Z1TP gdufkg,ˈY)'jl6KJS(QHᬰ찾f}1c Y8/ϾOs,nXj7g5#G_2k8*2W0\?X!Z02|]*LUIRVⳝb_EQX<~v襖fJYJZ_3q.;i.x]=^sTq).]>ljSyTS]OZB\@Jca?xĝahS)uiE+1Cϙsd*XOSMzug@Yv>(fjSL:f5 Hӧ KFf,k-;yGr?K8Xȱ3SC7u DqsNK^FC)aafL}˗H{=ziRg|ba174K1"k^{@awU_6!sl7L*nggoN>3EUn=@I2A)/t/R)J@kipwtZ8臬 K~|h2Ccv16n =I]KQ5(V)qnl'>X"@*4 xjZ=N8qhQhV Z)6qx9Ki;3NP,׸ti2k)%I33MX?ApNW=ٜ_jj, A->)S2 a/ZAned4Xi._dE8āp\瀡 Zz1DijZA\`gk,3sA"KYǒvK2lu$>qT𞉙#a/On OvrR3 ;yɱ _{ugP'X 힯:@:8|9vu|(50Dpl&ޭxx8cI~RDQ`"q%V7Vx w'2 =\ #^w(?5vR'BE^xiPy fc>uet DK+_q (? ,.E"@@BŞ͎ҵ%ʼny?<(co?f w='HkK>|CGX]ʽS R6V)g"l$KQ"}O<}E,.G;^j |sE_P{Fp4Z]N뫋YơS4wI^~ _D)Uk AEsp$Kru"QUs@f-`jch~{͞Y0VȬ+d2g X+LJ4;t:MfO` }@(.EJ8zs%a\Rs :eOpV9ّ&*0_#g ;\i sC5qCGOxˆID@!Dq:~STE1NJ g~s 4%Ͳ<5M ß)@NzW1hݔىj.vIң"PADe|\;Mk bPi8 `ێRBmRrɈBsn4~%J)Z݄b\FvV b9B<4S)!#@1Yɉ(s율<2`ffN5p92hѻO} sjR8kY|kQDmjn@Z)@J֭tײ;fʠuyCފÀ#=$?z\=?5ya5B609G!S)rs\8:ADC=-jF=EulrZa+ Vޛ.(l< DR^ G1Rtz)6M7MALD$r.M3PP+~(Ou[LM&P,ȱ6kK?0*O 0 GFSS z G%gLֳWnZΒ<>Prr$]SȷPZ#3p6P ҧ)VAsqP 4:=,1(Y9ϙYgnG\^<2{&ڼz\Ga>AXxXf%!s7bcP@ \y(Fzx>Vs~7;2ʢXp\T9CP 5;-1ߣd7?TZi{g)-CVB 5Ar׀TGq Z~%D(9 @Q$)Y֖Է[X[Xs~N0Q-l4"Iv?rߞ4P#)4'RZi˴ [ͶOg0]#婰X%k66(zDqF'Z۰nÔ |#1&8$Z%A?{~)R˴:]7v|DXCm!Eڸ/2הOl\@Pb/ j&J!!<o= ,F^Z0Yaei}>$MK/i_9ݭX1g=n6hr!{=<4>8& C2+τZ3_/1?Uabi}qn+p/䍑_~k('KR3fZnNL5A{stq;t{+WX󮍥Ԝ f'Oitv +[ի,oq^@@@G) q퇉ÐfvV>6-ko:qYͷo ڱ7lfPǦ>_[箲8q1ÉM1Q-RƄVG7ao=mB.+/_Myqb}ؐ9Tcekf'* 屙|35&&qmq֚ʺ`\ϋ?A."V=*w**A Yܥf7[s 1JIz-m@C5ֶv=WgqFGWdxKFɻrOPq%P2 xRhA={HƳUl4e3 ݕxɯ>7Eӕ{3Quҁ*C˜zLhu AbBv9Š]fL鵧q>^`;sa^A;(K%*2if&i.O>V !Ҵ{]Pؤ'i.>:b=ۗ%G@^xX?C^A\yRj"ЁRo"a ! &M:_k/_߼0bu /K ~Ca6Gʉ, Q(~gڤxOYn0nV|x ?jX;vL41;¸4ttHь [̬j{ݕtgeyX1uX*?d"FQA+{(=ԽM EK@ v¿W9 y ~=%5"~®~>ad[J}IENDB`cairo-dock-plugins-3.3.2/wifi/data/preview.jpg000664 001750 001750 00000043641 12223247501 022407 0ustar00mbaertsmbaerts000000 000000 JFIFHH ExifMM*, UJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222V" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?JZJ4_-~Qv%8bw=>FPܜ[ @&_YiݕF_j_ʀ>8ÞHm2HNI)68dj;E(ZH>osP+-Vٕn} E:ШR>@؟d)l8.G[SQ:Vזm"!OfXkn` Q7^|"o򎇵|qRl-}<fiq_Wzm.*,6>@RjQ4;ԓXڶ)i%u)i) g 5.nG+0-Kw ܌ 4ֿҭbF_zY7w .0'+="2p=J"u8X#$*ƹ}:xOX^Cg1+9%דżt*U|V5b^ћ1N9Yistg֢+ PGL)v6eM^t<"<௵շUۘaBbVxh$% z`I<~UtZQ>_44$֭Q{(`rCHѹcU%:{V&ϡ-nK~|}_^icZڿކP@뉟A_ctWD((u=6kiha/ruC\֧i-:`T<Y;/fd' ̌TRN= ͥБB0LHfIz2AJdc_Aç(rW{jpJwYIT%I!YU j.5O0[+m%oλ Y̏˹OU/}O?U4(S:s&e Jyn۳ ~{g_. |*/AқG-Z1<BDGݣ ~f * Ljھ׹rGiv֑hXVzFK;Qi~%)–e{ܱ'ھɓ[ |mYWikqQ>}7I"clr}s_Fxϕ@1[RGFbyR6aaAXSbzF2k@cW+G{5Čx,!I&l,ñyn5u⿇,[UОNi^n/.移8Z9׳ Yy zW i+%=s\կZG e*x"%ښfipt&1\ͬL :0k*m{ke%ەg{*[ YyEu,UkIH?{Tk:oB+QU5R2tJ?JM39Vo47g8cX|@wB"Hc–rWDZ#;?yh E[=O>_!Wү_e \[@((((((((Created with GIMPCC"   V   ! 1"AQi9Iaq$2#&'(36BYeg%CDERhs 5!1"AQa2qR#B$ ?o%|_^Դ?xxzOw||'_^ziT> 7T ?Thm2OM}U><4|. } UO UO $$HS#$HS#A'y~ x_?*x w ƍ #% UNUwHODTm M H:MXͶ$)16ՁU` ҥZIwݸN='?|cXii]I]:lZڪ'M3#ą(idh!#Xƪۢl:ˊ_W&Gi 3Cetl1 \6{VL<.c ,좽D=F:<06[ts gj/铖  ]F] }86yʸmqL9HB$F2Q m]|\&VPm=$zHX۠xlYh6^d#e܈܍4o ⪷vzC Cd6Ec#|$dwW=\Ws\Xj^-(MQd茍X(cTb0"R6dKS\V!i)*=E@WnHHL$2.Rt 8IH#y ` F s죝n2'kZc9G,LlX#ePVc6,%ڲڦlcU;*ݠ񳼞HЂe+iُV=m7l:JP:kte%efs;(QH;•Wb= <"VB7wp:9($-wXҿoT#ZfQ7D4sNz/u0W%SPE*Skm܈NEYrvJ;GB$)(ӫIHiYnHlĮǢ̴SO1QP|I(2U\>,ycͱ~NqnǴ[U?OLA(VUEex1b*\41vRv#첽;\(h6IdQD+B,c@Xm 8lP*AQXka{r %u p* ZҐrHA$Glw1"9O,c)ji߀QwpRڎ+kd]fWoQ:IckDcp@u#:9~^9Ng4ңT4,l, Hs? H6P{Җ4e]&eds_~~Ccc`aZ> c ǻ@dž8l`Jdv Q[ݜ$ƲRsWtEOb/?+1WyK2 ٿ0SF%I뮝ZʀtR\AZ@D*wcʲT}~7~m`M<\,z/4/YGG@u?z$SIph8sfxoVǷ*8ҏ n9Z=8ՂI" SG # 4^LAGunk\M~lq)9F\˂ȱ+snFyG|j5!YM B6f Kԕ__CEx4ֹ׉TUi0fG7F'?ujo9+&}sy3'=cUo_[+[6䏰ڴez)n+X֍kj'JmX9cWnsogof;'O.1*hhd[aS%dQ1Ilq8^6X7L KTJF!H1[0oRV UiЅ &I%{GC)R ##{d!Ω1U7=9j8!w[VYo`Մl^dIbL0y9tP.jnnmM:WJp̗)MquX !h -+A0j>JI˙p"5LILy("HE$xи2iybՠΙ#5(1(F1:#T.5A3۱'~N͂;?̖[R+`p=`U>"YQ6܏" GUKǵRW::<Idi1\}7rutdxM5GN" &-FN<Or{iG+3 dH^)Xơs{bq1^ Cw[F*";g{]Wl^J2 :'B">?GJ'Oyʉ㵝yk]dA btId~g`Ē/$nj%\2Ls+׺8'Z#M湿U7EG:nT^"TKE3F$q6t1`l[SNԱʢAW r2>uCaJC&QE])},\ m^@K( s+[Xh%@J!(AQ AkBLs k:RTDDNUm"Ded R$SY.\Fb>5r\=KTFFzY~nOXd)J8m)3m1T<ྯPPBLb ")d*APN0òDt[ylP6\"5.}Qf;eDMs\')^w tw3 yY.X{۵U8vki3uw# du~21Ͷwp\6WJNcZZX.o]Wj!ݾ Aa%^q=Tb:9Y:j)JVP> G8 >)]eMFK\-wHH8-P(8>V-5Å+Jֻ |[4_"9Yq \]ܩ6]8A$$ќ1;cs7;jmd)s OJw u3&]o5e_2J=ƓTJɱQVrG#$Ýcf`?eW0cq+]jJz=6 ];ҽJ&R8C9،1㹬  q"\2(hRu{ֹr <ck y9~ 6e+e,dagcs0skԹRaUc]c {3?Kjs6zeO5]CH_6]9Jt#s#M|XϚ c;p TR %[Z,5H=!5joM//^"٩CT:'BRǜLmO~KI5HJֺ4նJ4nr@2s:@?6_E.[n=xhj#(H(52Di. 1lx+kFpܛZTTV.EM7O nM<=,`S,s&&>Hմ *IfG(\E$@:ֽc"TQxmm/DzF>JǵV4z?tTr.Ҩպn"yK 9϶@o|s߾9+<lj*ØFT9B9d"j1QVV7,~soEYᏏXKJH粭1 C&FYC!x:؍q!开i@IPC}@bg6 A&oWw^3dۋJd4 KM:9iID]tr.ʐO]gܑ| ?q~3)İXv8F~5^w?>bj-Oӛ %5W1Ljl$VTsl+e0g կ Ø)dɌg󏄈50v=/EEiኦ HFDaea}ƽct6(88*AGò}LLPbȩ*Q:1< 0MH/#[ÏϏ%ic묐kcOc>=L0ս%H!}JBro "Xh ɷ88 [F}L팝uAW^%iĶ]v0E{z)X݈S7+Iv6|6=EE{6V^ψr :LUA;k*QG6+V +ƉR;Ԗ" p%ܜ u5W.QY)< Q^ZFyc9\- 2ME|w UmD#UD|tJ[ Jy3¨ū Ҭ0Á lK6\-@ZuݎVO4z39^HhoW+U6@eVRcyਪ+[@!nY%W*sWzȭZY%d2* p@B5talJ >e11;{Ko]0h%S[p/CB C8Fa;s'6]2`.$ )!0gw=*BA]O{1Xަt@2谐{p LuLuLKl5i$tvJZx]MMlnSkT{|LQ+E~~ƺ\p%L۲UԳVjcF[ Hta|,(˳+T$aq)ەƎCUrNtpHp Ifb5muyWP?#UHIM櫇Вf(PA"Yv^/T^a)"Xula>A, S#ܷ6YPj*|GGv9]e;&{ABu y ,vk .)K2]O-c;oN3bs [;)p‚vYXħ&y, -sg#kUi*d)֎i3&`=Ђ77.J?NX܏ath^C`X'W]h3PH>I;</,laWG*":1lCɅ>HfBGDiQ@bQ={U*. 0IHرa*ڮ=y>Y%x^2$DW(gLÕGǯr)dchnfr<}9!H,%}7XDan(h*:t[ĉ57T g@8̫)(B u,mޭI^qr:p,/ka[r<×P\(#:#\棷Dha*Xf$D`GVGq9<=iqsjƱW| %M3-?ZGz"V`9,jK^&%d||,SXysOYvgm.-bWxҲ=cpRtMi^VJ\+ BpR :.$p9Ús\<5ЕWjh5Hi%VU4+Q^8"QIEHѴАb78;g%dFԹ|p/D$(dל$z5GWrϒUUNw&+Xw{7\򉱪N֍\\mv[쌮i F2Uk@1=PfAS}Zqa[֕㣣lŧӤ%䐬w 5a<EdRKROpx?D>'i Uzh>ysD]U9m | l A<Ͻ Ϳc~)?6_Eq#(H(52Di.  t+_]+.Iӿ89z Ҷdͯ0ڏiu&'i|8WK@fzyQmb%=*QㄋGAg`ʡiHbX|+=ۂ@Hchm!ȑ JېGuw[|YA|6 iRfǨrBdMCTHp)śQ ZrRUуh!kX0 lkX61F5kQDnȍDӝ7Q$xx(_v畔 !rUv/_K\!3~AJHGouHe#zF8a3|cuZEƝB->bqf,͉p6532D h1:֣5u^^O*EG5F檣ׯ::}-u鋏+ahf)ʪJ7&V:.՗8#\}4;Oǽ}1,+P-l!*H2UbR"Ր5w&LcŲc#TMzm~K3Z++1*MqH* ,eLDϱā! p#[0*S.G?{зڊ5HXFd[-ֽ!_=?v=n+KI8YÜ%J' GbW,#;U N21Y_guM|2xΒ0I!ę1(D8cRUG85Ӫ\eC dRC:ASCrRaH-$0 3T+mَLlKw\-J?ڼE;{k&$XNS&nZC%L9`xUxN5Rȯ$z$31׌! ^o6*T$K))ӯ TPJ򐯴ƥr˾D]$ۭG3LA%! exODB4cf My\Tw##'h0##51#$jˋR ]g5$z~1$[G;_؊W2٨zzm[bPࢦAEk,{},ı$*QPЎ7GujO49>6*7~-5vGL XX75.Z>Ŭ/3t0`Wx,*ǕX @7c\q!OWS1r#Dz*ٕ785vtyXXK#02 ʏb`Na㕼-EItRMpZ5r;aF uvASjGuS_V=CIgTVyTR+KӒ6&R|.Q>e?6_E.[n=xei﬎.GK;,}=w >}ݶz~_VzP*jsOoʿ7}> 2υ~k~~_nVjZj_ҋb. 1X&/g\'*W/o-H~EbSwgTH%o.Zp.1g=n$pC_ B,FPKlbo@>X&5MkS"q\Gַiδі|.[m|.[m4\4d@tݞ2|楄OZ8?¥"?mOZ"n p@?Fp^MX6{;!mT[5WϾg֢5hD""'̈l Np hі|.[m|.[m4\gFp}Z߻oυ/g?58 N:[ U{=5,Uk~>oy'g"|fŷd Fp}Z߻g p}Z߻oѩ U}Y W^4 ӏ!?Y]c~I.cairo-dock-plugins-3.3.2/wifi/data/CMakeLists.txt000664 001750 001750 00000000311 12223247501 022747 0ustar00mbaertsmbaerts000000 000000 add_subdirectory(gauges) ########### install files ############### install(FILES ${CMAKE_CURRENT_BINARY_DIR}/wifi.conf preview.jpg default.svg no-signal.svg icon.png DESTINATION ${wifidatadir}) cairo-dock-plugins-3.3.2/wifi/data/link-0.svg000664 001750 001750 00000045074 12223247501 022041 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/link-4.svg000664 001750 001750 00000071764 12223247501 022052 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/link-1.svg000664 001750 001750 00000054277 12223247501 022047 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/default.svg000664 001750 001750 00000071745 12223247501 022377 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/link-2.svg000664 001750 001750 00000070117 12223247501 022037 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/wifi.conf.in000664 001750 001750 00000007470 12223247501 022436 0ustar00mbaertsmbaerts000000 000000 #@VERSION_WIFI@ #[gtk-about] [Icon] #F[Icon] frame_maininfo= #d Name of the dock it belongs to: dock name = #s[Connection name] Name of the icon as it will appear in its caption in the dock: name = #v sep_display= icon= #j+[0;128] Desired icon size for this applet #{Set to 0 to use the default applet size} icon size = 0;0 #Y+[No;0;0;With default background;0;0;With custom background;1;1] Always display the icon, even when the dock is hidden? always_visi = 0 #C+ Background color to add in this case bg color = .8;.8;.8;.5 order= #A handbook=wifi #[gtk-convert] [Desklet] #X[Position] frame_pos = #b Lock position? #{If locked, the desklet cannot be moved by simply dragging it with the left mouse button. It can still be moved with ALT + left-click.} locked = false #j+[24;512] Desklet dimensions (width x height): #{Depending on your WindowManager, you may be able to resize this with ALT + middle-click or ALT + left-click.} size = 96;96 #i[-2048;2048] Desklet position (x, y): #{Depending on your WindowManager, you may be able to move this with ALT + left-click.} x position=0 #i[-2048;2048] ... y position=0 #I[-180;180] Rotation: #{You can quickly rotate the desklet with the mouse, by dragging the little buttons on its left and top sides.} rotation = 0 #X[Visibility] frame_visi = #b+ Is detached from the dock initially detached=false #l[Normal;Keep above;Keep below;Keep on widget layer;Reserve space] Visibility: accessibility=0 #b Should be visible on all desktops? sticky=true #F[Decorations;gtk-orientation-portrait] frame_deco= #o+ Choose a decoration theme for this desklet: #{Choose 'Custom decorations' to define your own decorations below.} decorations = default #v sep_deco = #g+ Background image: #{Image to be displayed below drawings, e.g. a frame. Leave empty for no image.} bg desklet = #e+[0;1] Background transparency: bg alpha = 1 #i+[0;256] Left offset: #{in pixels. Use this to adjust the left position of drawings.} left offset = 0 #i+[0;256] Top offset: #{in pixels. Use this to adjust the top position of drawings.} top offset = 0 #i+[0;256] Right offset: #{in pixels. Use this to adjust the right position of drawings.} right offset = 0 #i+[0;256] Bottom offset: #{in pixels. Use this to adjust the bottom position of drawings.} bottom offset = 0 #g+ Foreground image: #{Image to be displayed above the drawings, e.g. a reflection. Leave empty for no image.} fg desklet = #e+[0;1] Foreground tansparency: fg alpha = 1 #[gtk-preferences] [Configuration] #Y+[Gauge;1;1;Graph;2;1;Icon with progress bar;3;1] Display style renderer = 0 #X[Gauge;@shared_filesdatadir@/images/icon-gauge.png] frame_gauge= #h+[@gaugesdir@;gauges;gauges3;wifi] Gauge theme/ theme = Wifi_default #X[Graph;@shared_filesdatadir@/images/icon-graph.png] frame_graph= #l+[Line;Plain;Bar;Circle;Plain Circle] Type of graphic : graphic type = 0 #c+ High value's colour : #{It's the colour of the graphic for high quality signal.} high color = 1;0;0 #c+ Low value's colour : #{It's the colour of the graphic for low quality signal.} low color = 1;1;0 #C+ Background colour of the graphic : bg color = .5;.5;1.;.4 #X[Icon;@wifidatadir@/icon.png] frame_icons = #g+[Default] Default icon: default_icon = #g+[Default] "No signal" icon no_signal_icon = #F+[Info;gtk-info] frame_disp= #l[None;Signal Strength;Signal Strength in percent;Raw Signal Informations] Information to display on the icon : signal_type=2 #F[Parameters;gtk-preferences] frame_param = #i[1;60] Delay between signal checks : #{in seconds.} delay = 10 #e[0;1] How smooth is the movement? #{You need OpenGL for this option. Set it to 0 means not used, 1 means the movement is continue.} smooth = .33 #s Alternative command line to launch Wireless Configuration : #{Allow you to overwrite applet's default command line and launch your wireless configuration interface.} command = cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/link-3.svg000664 001750 001750 00000100361 12223247501 025710 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/preview000664 001750 001750 00000043641 12223247501 025505 0ustar00mbaertsmbaerts000000 000000 JFIFHH ExifMM*, UJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222V" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?JZJ4_-~Qv%8bw=>FPܜ[ @&_YiݕF_j_ʀ>8ÞHm2HNI)68dj;E(ZH>osP+-Vٕn} E:ШR>@؟d)l8.G[SQ:Vזm"!OfXkn` Q7^|"o򎇵|qRl-}<fiq_Wzm.*,6>@RjQ4;ԓXڶ)i%u)i) g 5.nG+0-Kw ܌ 4ֿҭbF_zY7w .0'+="2p=J"u8X#$*ƹ}:xOX^Cg1+9%דżt*U|V5b^ћ1N9Yistg֢+ PGL)v6eM^t<"<௵շUۘaBbVxh$% z`I<~UtZQ>_44$֭Q{(`rCHѹcU%:{V&ϡ-nK~|}_^icZڿކP@뉟A_ctWD((u=6kiha/ruC\֧i-:`T<Y;/fd' ̌TRN= ͥБB0LHfIz2AJdc_Aç(rW{jpJwYIT%I!YU j.5O0[+m%oλ Y̏˹OU/}O?U4(S:s&e Jyn۳ ~{g_. |*/AқG-Z1<BDGݣ ~f * Ljھ׹rGiv֑hXVzFK;Qi~%)–e{ܱ'ھɓ[ |mYWikqQ>}7I"clr}s_Fxϕ@1[RGFbyR6aaAXSbzF2k@cW+G{5Čx,!I&l,ñyn5u⿇,[UОNi^n/.移8Z9׳ Yy zW i+%=s\կZG e*x"%ښfipt&1\ͬL :0k*m{ke%ەg{*[ YyEu,UkIH?{Tk:oB+QU5R2tJ?JM39Vo47g8cX|@wB"Hc–rWDZ#;?yh E[=O>_!Wү_e \[@((((((((Created with GIMPCC"   V   ! 1"AQi9Iaq$2#&'(36BYeg%CDERhs 5!1"AQa2qR#B$ ?o%|_^Դ?xxzOw||'_^ziT> 7T ?Thm2OM}U><4|. } UO UO $$HS#$HS#A'y~ x_?*x w ƍ #% UNUwHODTm M H:MXͶ$)16ՁU` ҥZIwݸN='?|cXii]I]:lZڪ'M3#ą(idh!#Xƪۢl:ˊ_W&Gi 3Cetl1 \6{VL<.c ,좽D=F:<06[ts gj/铖  ]F] }86yʸmqL9HB$F2Q m]|\&VPm=$zHX۠xlYh6^d#e܈܍4o ⪷vzC Cd6Ec#|$dwW=\Ws\Xj^-(MQd茍X(cTb0"R6dKS\V!i)*=E@WnHHL$2.Rt 8IH#y ` F s죝n2'kZc9G,LlX#ePVc6,%ڲڦlcU;*ݠ񳼞HЂe+iُV=m7l:JP:kte%efs;(QH;•Wb= <"VB7wp:9($-wXҿoT#ZfQ7D4sNz/u0W%SPE*Skm܈NEYrvJ;GB$)(ӫIHiYnHlĮǢ̴SO1QP|I(2U\>,ycͱ~NqnǴ[U?OLA(VUEex1b*\41vRv#첽;\(h6IdQD+B,c@Xm 8lP*AQXka{r %u p* ZҐrHA$Glw1"9O,c)ji߀QwpRڎ+kd]fWoQ:IckDcp@u#:9~^9Ng4ңT4,l, Hs? H6P{Җ4e]&eds_~~Ccc`aZ> c ǻ@dž8l`Jdv Q[ݜ$ƲRsWtEOb/?+1WyK2 ٿ0SF%I뮝ZʀtR\AZ@D*wcʲT}~7~m`M<\,z/4/YGG@u?z$SIph8sfxoVǷ*8ҏ n9Z=8ՂI" SG # 4^LAGunk\M~lq)9F\˂ȱ+snFyG|j5!YM B6f Kԕ__CEx4ֹ׉TUi0fG7F'?ujo9+&}sy3'=cUo_[+[6䏰ڴez)n+X֍kj'JmX9cWnsogof;'O.1*hhd[aS%dQ1Ilq8^6X7L KTJF!H1[0oRV UiЅ &I%{GC)R ##{d!Ω1U7=9j8!w[VYo`Մl^dIbL0y9tP.jnnmM:WJp̗)MquX !h -+A0j>JI˙p"5LILy("HE$xи2iybՠΙ#5(1(F1:#T.5A3۱'~N͂;?̖[R+`p=`U>"YQ6܏" GUKǵRW::<Idi1\}7rutdxM5GN" &-FN<Or{iG+3 dH^)Xơs{bq1^ Cw[F*";g{]Wl^J2 :'B">?GJ'Oyʉ㵝yk]dA btId~g`Ē/$nj%\2Ls+׺8'Z#M湿U7EG:nT^"TKE3F$q6t1`l[SNԱʢAW r2>uCaJC&QE])},\ m^@K( s+[Xh%@J!(AQ AkBLs k:RTDDNUm"Ded R$SY.\Fb>5r\=KTFFzY~nOXd)J8m)3m1T<ྯPPBLb ")d*APN0òDt[ylP6\"5.}Qf;eDMs\')^w tw3 yY.X{۵U8vki3uw# du~21Ͷwp\6WJNcZZX.o]Wj!ݾ Aa%^q=Tb:9Y:j)JVP> G8 >)]eMFK\-wHH8-P(8>V-5Å+Jֻ |[4_"9Yq \]ܩ6]8A$$ќ1;cs7;jmd)s OJw u3&]o5e_2J=ƓTJɱQVrG#$Ýcf`?eW0cq+]jJz=6 ];ҽJ&R8C9،1㹬  q"\2(hRu{ֹr <ck y9~ 6e+e,dagcs0skԹRaUc]c {3?Kjs6zeO5]CH_6]9Jt#s#M|XϚ c;p TR %[Z,5H=!5joM//^"٩CT:'BRǜLmO~KI5HJֺ4նJ4nr@2s:@?6_E.[n=xhj#(H(52Di. 1lx+kFpܛZTTV.EM7O nM<=,`S,s&&>Hմ *IfG(\E$@:ֽc"TQxmm/DzF>JǵV4z?tTr.Ҩպn"yK 9϶@o|s߾9+<lj*ØFT9B9d"j1QVV7,~soEYᏏXKJH粭1 C&FYC!x:؍q!开i@IPC}@bg6 A&oWw^3dۋJd4 KM:9iID]tr.ʐO]gܑ| ?q~3)İXv8F~5^w?>bj-Oӛ %5W1Ljl$VTsl+e0g կ Ø)dɌg󏄈50v=/EEiኦ HFDaea}ƽct6(88*AGò}LLPbȩ*Q:1< 0MH/#[ÏϏ%ic묐kcOc>=L0ս%H!}JBro "Xh ɷ88 [F}L팝uAW^%iĶ]v0E{z)X݈S7+Iv6|6=EE{6V^ψr :LUA;k*QG6+V +ƉR;Ԗ" p%ܜ u5W.QY)< Q^ZFyc9\- 2ME|w UmD#UD|tJ[ Jy3¨ū Ҭ0Á lK6\-@ZuݎVO4z39^HhoW+U6@eVRcyਪ+[@!nY%W*sWzȭZY%d2* p@B5talJ >e11;{Ko]0h%S[p/CB C8Fa;s'6]2`.$ )!0gw=*BA]O{1Xަt@2谐{p LuLuLKl5i$tvJZx]MMlnSkT{|LQ+E~~ƺ\p%L۲UԳVjcF[ Hta|,(˳+T$aq)ەƎCUrNtpHp Ifb5muyWP?#UHIM櫇Вf(PA"Yv^/T^a)"Xula>A, S#ܷ6YPj*|GGv9]e;&{ABu y ,vk .)K2]O-c;oN3bs [;)p‚vYXħ&y, -sg#kUi*d)֎i3&`=Ђ77.J?NX܏ath^C`X'W]h3PH>I;</,laWG*":1lCɅ>HfBGDiQ@bQ={U*. 0IHرa*ڮ=y>Y%x^2$DW(gLÕGǯr)dchnfr<}9!H,%}7XDan(h*:t[ĉ57T g@8̫)(B u,mޭI^qr:p,/ka[r<×P\(#:#\棷Dha*Xf$D`GVGq9<=iqsjƱW| %M3-?ZGz"V`9,jK^&%d||,SXysOYvgm.-bWxҲ=cpRtMi^VJ\+ BpR :.$p9Ús\<5ЕWjh5Hi%VU4+Q^8"QIEHѴАb78;g%dFԹ|p/D$(dל$z5GWrϒUUNw&+Xw{7\򉱪N֍\\mv[쌮i F2Uk@1=PfAS}Zqa[֕㣣lŧӤ%䐬w 5a<EdRKROpx?D>'i Uzh>ysD]U9m | l A<Ͻ Ϳc~)?6_Eq#(H(52Di.  t+_]+.Iӿ89z Ҷdͯ0ڏiu&'i|8WK@fzyQmb%=*QㄋGAg`ʡiHbX|+=ۂ@Hchm!ȑ JېGuw[|YA|6 iRfǨrBdMCTHp)śQ ZrRUуh!kX0 lkX61F5kQDnȍDӝ7Q$xx(_v畔 !rUv/_K\!3~AJHGouHe#zF8a3|cuZEƝB->bqf,͉p6532D h1:֣5u^^O*EG5F檣ׯ::}-u鋏+ahf)ʪJ7&V:.՗8#\}4;Oǽ}1,+P-l!*H2UbR"Ր5w&LcŲc#TMzm~K3Z++1*MqH* ,eLDϱā! p#[0*S.G?{зڊ5HXFd[-ֽ!_=?v=n+KI8YÜ%J' GbW,#;U N21Y_guM|2xΒ0I!ę1(D8cRUG85Ӫ\eC dRC:ASCrRaH-$0 3T+mَLlKw\-J?ڼE;{k&$XNS&nZC%L9`xUxN5Rȯ$z$31׌! ^o6*T$K))ӯ TPJ򐯴ƥr˾D]$ۭG3LA%! exODB4cf My\Tw##'h0##51#$jˋR ]g5$z~1$[G;_؊W2٨zzm[bPࢦAEk,{},ı$*QPЎ7GujO49>6*7~-5vGL XX75.Z>Ŭ/3t0`Wx,*ǕX @7c\q!OWS1r#Dz*ٕ785vtyXXK#02 ʏb`Na㕼-EItRMpZ5r;aF uvASjGuS_V=CIgTVyTR+KӒ6&R|.Q>e?6_E.[n=xei﬎.GK;,}=w >}ݶz~_VzP*jsOoʿ7}> 2υ~k~~_nVjZj_ҋb. 1X&/g\'*W/o-H~EbSwgTH%o.Zp.1g=n$pC_ B,FPKlbo@>X&5MkS"q\Gַiδі|.[m|.[m4\4d@tݞ2|楄OZ8?¥"?mOZ"n p@?Fp^MX6{;!mT[5WϾg֢5hD""'̈l Np hі|.[m|.[m4\gFp}Z߻oυ/g?58 N:[ U{=5,Uk~>oy'g"|fŷd Fp}Z߻g p}Z߻oѩ U}Y W^4 ӏ!?Y]c~I.cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/CMakeLists.txt000664 001750 001750 00000000321 12223247501 026625 0ustar00mbaertsmbaerts000000 000000 ########### install files ############### install(FILES link-0.svg link-1.svg link-2.svg link-3.svg link-4.svg link-5.svg preview readme theme.xml version DESTINATION ${gaugesdir}/Wifi_default ) cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/readme000775 001750 001750 00000000051 12223247501 025250 0ustar00mbaertsmbaerts000000 000000 Default Wifi gauge theme for Cairo-Dock. cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/link-0.svg000664 001750 001750 00000045074 12223247501 025716 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/link-4.svg000664 001750 001750 00000071764 12223247501 025727 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/link-1.svg000664 001750 001750 00000054277 12223247501 025724 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/link-2.svg000664 001750 001750 00000070117 12223247501 025714 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/theme.xml000664 001750 001750 00000000475 12223247501 025723 0ustar00mbaertsmbaerts000000 000000 Wifi: Default 3 Cairo-Dock team link-1.svg link-2.svg link-3.svg link-4.svg link-5.svg link-0.svg cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/version000664 001750 001750 00000000002 12223247501 025471 0ustar00mbaertsmbaerts000000 000000 1 cairo-dock-plugins-3.3.2/wifi/data/gauges/Wifi_default/link-5.svg000664 001750 001750 00000071745 12223247501 025727 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/wifi/data/gauges/CMakeLists.txt000664 001750 001750 00000000040 12223247501 024221 0ustar00mbaertsmbaerts000000 000000 add_subdirectory(Wifi_default) cairo-dock-plugins-3.3.2/wifi/data/link-5.svg000664 001750 001750 00000071745 12223247501 022052 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/drop-indicator/src/applet-struct.h000775 001750 001750 00000002712 12223247501 025037 0ustar00mbaertsmbaerts000000 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 __CD_APPLET_STRUCT__ #define __CD_APPLET_STRUCT__ #include //\___________ structure containing the applet's configuration parameters. struct _AppletConfig { gint iSpeed; gdouble fRotationSpeed; gchar *cDropIndicatorImageName; gchar *cHoverIndicatorImageName; } ; //\___________ structure containing the applet's data, like surfaces, dialogs, results of calculus, etc. struct _AppletData { CairoDockImageBuffer dropIndicator; CairoDockImageBuffer hoverIndicator; GLuint iBilinearGradationTexture; } ; typedef struct _CDDropIndicatorData { gint iDropIndicatorOffset; gint iDropIndicatorRotation; gdouble fAlpha; gdouble fAlphaHover; } CDDropIndicatorData; #endif cairo-dock-plugins-3.3.2/drop-indicator/src/applet-init.h000775 001750 001750 00000001553 12223247501 024460 0ustar00mbaertsmbaerts000000 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 __APPLET_INIT__ #define __APPLET_INIT__ #include CD_APPLET_H #endif cairo-dock-plugins-3.3.2/drop-indicator/src/applet-notifications.h000775 001750 001750 00000002655 12223247501 026372 0ustar00mbaertsmbaerts000000 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 __APPLET_NOTIFICATIONS__ #define __APPLET_NOTIFICATIONS__ #include gboolean cd_drop_indicator_render (gpointer pUserData, CairoDock *pDock, cairo_t *pCairoContext); gboolean cd_drop_indicator_mouse_moved (gpointer pUserData, CairoDock *pDock, gboolean *bStartAnimation); gboolean cd_drop_indicator_update_dock (gpointer pUserData, CairoDock *pDock, gboolean *bContinueAnimation); void cd_drop_indicator_load_drop_indicator (gchar *cImagePath, int iWidth, int iHeight); void cd_drop_indicator_load_hover_indicator (gchar *cImagePath, int iWidth, int iHeight); gboolean cd_drop_indicator_stop_dock (gpointer data, CairoDock *pDock); #endif cairo-dock-plugins-3.3.2/drop-indicator/src/CMakeLists.txt000664 001750 001750 00000005317 12223247501 024620 0ustar00mbaertsmbaerts000000 000000 ########### sources ############### SET(cd-drop_indicator_LIB_SRCS applet-init.c applet-init.h applet-config.c applet-config.h applet-notifications.c applet-notifications.h applet-struct.h bilinear-gradation-texture.h ) add_library(${PACKAGE_DROP_INDICATOR} SHARED ${cd-drop_indicator_LIB_SRCS}) ########### compil ############### add_definitions (-DMY_APPLET_SHARE_DATA_DIR="${drop_indicatordatadir}") add_definitions (-DMY_APPLET_PREVIEW_FILE="preview.jpg") add_definitions (-DMY_APPLET_CONF_FILE="drop_indicator.conf") add_definitions (-DMY_APPLET_USER_DATA_DIR="drop_indicator") add_definitions (-DMY_APPLET_VERSION="${VERSION_DROP_INDICATOR}") add_definitions (-DMY_APPLET_GETTEXT_DOMAIN="${GETTEXT_DROP_INDICATOR}") add_definitions (-DMY_APPLET_DOCK_VERSION="${dock_version}") add_definitions (-DMY_APPLET_ICON_FILE="icon.svg") add_definitions (-DMY_APPLET_DEFAULT_DROP_INDICATOR_NAME="default-drop-indicator.svg") add_definitions (-DMY_APPLET_DEFAULT_HOVER_INDICATOR_NAME="default-hover-indicator.svg") add_definitions (-DMY_APPLET_MASK_INDICATOR_NAME="texture-bilinear-gradation.png") add_definitions (-DGL_GLEXT_PROTOTYPES="1") include_directories ( ${PACKAGE_INCLUDE_DIRS}) link_directories ( ${PACKAGE_LIBRARY_DIRS}) target_link_libraries (${PACKAGE_DROP_INDICATOR} ${PACKAGE_LIBRARIES}) ########### install files ############### install(TARGETS ${PACKAGE_DROP_INDICATOR} DESTINATION ${pluginsdir}) #original Makefile.am contents follow: # #dnl Process this file with automake to produce Makefile.in # #lib_LTLIBRARIES = # libcd-drop_indicator.la # # #libcd_drop_indicator_la_SOURCES = # applet-init.c # applet-init.h # applet-config.c # applet-config.h # applet-notifications.c # applet-notifications.h # applet-struct.h # bilinear-gradation-texture.h # # #dock_version = `pkg-config --modversion cairo-dock` # #libcd_drop_indicator_la_CFLAGS = # -I$(top_srcdir)/src # $(PACKAGE_CFLAGS) # -DMY_APPLET_SHARE_DATA_DIR=""${drop_indicatordatadir)"" # -DMY_APPLET_PREVIEW_FILE=""preview.jpg"" # -DMY_APPLET_CONF_FILE=""drop_indicator.conf"" # -DMY_APPLET_USER_DATA_DIR=""drop_indicator"" # -DMY_APPLET_VERSION=""${VERSION_DROP_INDICATOR)"" # -DMY_APPLET_GETTEXT_DOMAIN=""${GETTEXT_DROP_INDICATOR)"" # -DMY_APPLET_DOCK_VERSION=""${dock_version)"" # -DMY_APPLET_ICON_FILE=""icon.svg"" # -DMY_APPLET_DEFAULT_DROP_INDICATOR_NAME=""default-drop-indicator.svg"" # -DMY_APPLET_DEFAULT_HOVER_INDICATOR_NAME=""default-hover-indicator.svg"" # -DMY_APPLET_MASK_INDICATOR_NAME=""texture-bilinear-gradation.png"" # -DGL_GLEXT_PROTOTYPES=""1"" # -std=c99 # -Werror-implicit-function-declaration ## -g -ggdb -W -Wall # # #libcd_drop_indicator_la_LIBADD = # $(PACKAGE_LIBS) -lm # # #libcd_drop_indicator_la_LDFLAGS = # -avoid-version -module cairo-dock-plugins-3.3.2/drop-indicator/src/applet-init.c000664 001750 001750 00000010767 12223247501 024457 0ustar00mbaertsmbaerts000000 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 "stdlib.h" #include "applet-config.h" #include "applet-notifications.h" #include "applet-struct.h" #include "applet-init.h" CD_APPLET_DEFINE_BEGIN (N_("drop indicator"), 2, 0, 0, CAIRO_DOCK_CATEGORY_THEME, "This plug-in displays an animated indicator when you drop something into the dock.", "Fabounet (Fabrice Rey)") CD_APPLET_DEFINE_COMMON_APPLET_INTERFACE; CD_APPLET_SET_CONTAINER_TYPE (CAIRO_DOCK_MODULE_IS_PLUGIN); CD_APPLET_EXTEND_MANAGER ("Indicators"); CD_APPLET_DEFINE_END static void _load_indicators (void) { double iBaseWidth = myIconsParam.iIconWidth * (1 + myIconsParam.fAmplitude); double iBaseHeight = myIconsParam.iIconHeight * (1 + myIconsParam.fAmplitude); cd_drop_indicator_load_drop_indicator (myConfig.cDropIndicatorImageName, iBaseWidth, iBaseHeight/2); cd_drop_indicator_load_hover_indicator (myConfig.cHoverIndicatorImageName, iBaseWidth/3, iBaseHeight/3); } //\___________ Here is where you initiate your applet. myConfig is already set at this point, and also myIcon, myContainer, myDock, myDesklet (and myDrawContext if you're in dock mode). The macro CD_APPLET_MY_CONF_FILE and CD_APPLET_MY_KEY_FILE can give you access to the applet's conf-file and its corresponding key-file (also available during reload). If you're in desklet mode, myDrawContext is still NULL, and myIcon's buffers has not been filled, because you may not need them then (idem when reloading). CD_APPLET_INIT_BEGIN if (! CD_APPLET_RESERVE_DATA_SLOT ()) return; _load_indicators (); gldi_object_register_notification (&myContainerObjectMgr, NOTIFICATION_MOUSE_MOVED, (GldiNotificationFunc) cd_drop_indicator_mouse_moved, GLDI_RUN_AFTER, NULL); gldi_object_register_notification (&myDockObjectMgr, NOTIFICATION_RENDER, (GldiNotificationFunc) cd_drop_indicator_render, GLDI_RUN_AFTER, NULL); gldi_object_register_notification (&myDockObjectMgr, NOTIFICATION_UPDATE, (GldiNotificationFunc) cd_drop_indicator_update_dock, GLDI_RUN_AFTER, NULL); gldi_object_register_notification (&myDockObjectMgr, NOTIFICATION_DESTROY, (GldiNotificationFunc) cd_drop_indicator_stop_dock, GLDI_RUN_AFTER, NULL); CD_APPLET_INIT_END //\___________ Here is where you stop your applet. myConfig and myData are still valid, but will be reseted to 0 at the end of the function. In the end, your applet will go back to its original state, as if it had never been activated. static void _free_data_on_dock (const gchar *cDockName, CairoDock *pDock, gpointer data) { cd_drop_indicator_stop_dock (NULL, pDock); } CD_APPLET_STOP_BEGIN gldi_object_remove_notification (&myContainerObjectMgr, NOTIFICATION_MOUSE_MOVED, (GldiNotificationFunc) cd_drop_indicator_mouse_moved, NULL); gldi_object_remove_notification (&myDockObjectMgr, NOTIFICATION_RENDER, (GldiNotificationFunc) cd_drop_indicator_render, NULL); gldi_object_remove_notification (&myDockObjectMgr, NOTIFICATION_UPDATE, (GldiNotificationFunc) cd_drop_indicator_update_dock, NULL); gldi_object_remove_notification (&myDockObjectMgr, NOTIFICATION_DESTROY, (GldiNotificationFunc) cd_drop_indicator_stop_dock, NULL); gldi_docks_foreach ((GHFunc)_free_data_on_dock, NULL); CD_APPLET_STOP_END //\___________ The reload occurs in 2 occasions : when the user changes the applet's config, and when the user reload the cairo-dock's config or modify the desklet's size. The macro CD_APPLET_MY_CONFIG_CHANGED can tell you this. myConfig has already been reloaded at this point if you're in the first case, myData is untouched. You also have the macro CD_APPLET_MY_CONTAINER_TYPE_CHANGED that can tell you if you switched from dock/desklet to desklet/dock mode. CD_APPLET_RELOAD_BEGIN if (CD_APPLET_MY_CONFIG_CHANGED) { cd_drop_indicator_free_buffers (); _load_indicators (); } CD_APPLET_RELOAD_END cairo-dock-plugins-3.3.2/drop-indicator/src/bilinear-gradation-texture.h000775 001750 001750 00000003624 12223247501 027464 0ustar00mbaertsmbaerts000000 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 . */ /* GIMP RGBA C-Source image dump (texture-bilinear-gradation.c) */ // alpha pre-multiplie par mes soins. static const unsigned char gradationTex[1 * 32 * 4 + 1] = { "\0\0\0\0\6\6\6\6\16\16\16\16\35\35\35\35\137\137\137\137\242\242\242\242\304\304\304\304\353\353\353\353\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\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\376\376\376\367\367\367\367\332\332\332\332\240\240\240\240\120\120\120\120\35\35\35\35\16\16\16\16\6\6\6\6\0\0\0\0" /*"\377\377\377\0\377\377\377\6\377\377\377\16\377\377\377\35\377\377\377_\377" "\377\377\242\377\377\377\304\377\377\377\353\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\377\377\377\377" "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" "\377\377\376\377\377\377\367\377\377\377\332\377\377\377\240\377\377\377" "P\377\377\377\35\377\377\377\16\377\377\377\6\377\377\377\0"*/ }; cairo-dock-plugins-3.3.2/drop-indicator/src/applet-notifications.c000775 001750 001750 00000035102 12223247501 026356 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-notifications.h" #include "bilinear-gradation-texture.h" gboolean cd_drop_indicator_render (gpointer pUserData, CairoDock *pDock, cairo_t *pCairoContext) { CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock); if (pData == NULL) return GLDI_NOTIFICATION_LET_PASS; if (pCairoContext != NULL) { if (pData->fAlpha > 0) { cairo_save (pCairoContext); double fX = pDock->container.iMouseX - myData.dropIndicator.iWidth / 2; if (pDock->container.bIsHorizontal) cairo_rectangle (pCairoContext, (int) pDock->container.iMouseX - myData.dropIndicator.iWidth/2, (int) (pDock->container.bDirectionUp ? 0 : pDock->iActiveHeight - 2*myData.dropIndicator.iHeight), (int) myData.dropIndicator.iWidth, (int) (pDock->container.bDirectionUp ? 2*myData.dropIndicator.iHeight : pDock->iActiveHeight)); else cairo_rectangle (pCairoContext, (int) (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->iActiveHeight : pDock->iActiveHeight - 2*myData.dropIndicator.iHeight), (int) pDock->container.iMouseX - myData.dropIndicator.iWidth/2, (int) (pDock->container.bDirectionUp ? 2*myData.dropIndicator.iHeight : pDock->iActiveHeight), (int) myData.dropIndicator.iWidth); cairo_clip (pCairoContext); if (pDock->container.bIsHorizontal) cairo_translate (pCairoContext, fX, (pDock->container.bDirectionUp ? 0 : pDock->iActiveHeight)); else cairo_translate (pCairoContext, (pDock->container.bDirectionUp ? 0 : pDock->iActiveHeight), fX); double fRotationAngle = (pDock->container.bIsHorizontal ? (pDock->container.bDirectionUp ? 0 : G_PI) : (pDock->container.bDirectionUp ? -G_PI/2 : G_PI/2)); cairo_rotate (pCairoContext, fRotationAngle); cairo_translate (pCairoContext, 0, pData->iDropIndicatorOffset); cairo_pattern_t* pPattern = cairo_pattern_create_for_surface (myData.dropIndicator.pSurface); g_return_val_if_fail (cairo_pattern_status (pPattern) == CAIRO_STATUS_SUCCESS, GLDI_NOTIFICATION_LET_PASS); cairo_pattern_set_extend (pPattern, CAIRO_EXTEND_REPEAT); cairo_set_source (pCairoContext, pPattern); cairo_translate (pCairoContext, 0, - pData->iDropIndicatorOffset); cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (0., 0., 0., 2*myData.dropIndicator.iHeight); // de haut en bas. g_return_val_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS, GLDI_NOTIFICATION_LET_PASS); cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0., 0., 0., 0., 0.); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0.4, 0., 0., 0., pData->fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0.5, 0., 0., 0., pData->fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 1., 0., 0., 0., 0.); cairo_mask (pCairoContext, pGradationPattern); cairo_pattern_destroy (pPattern); cairo_pattern_destroy (pGradationPattern); cairo_restore (pCairoContext); } if (pData->fAlphaHover > 0 && myData.hoverIndicator.pSurface != NULL) { Icon *pIcon = cairo_dock_get_pointed_icon (pDock->icons); if (pIcon != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) { cairo_save (pCairoContext); if (pDock->container.bIsHorizontal) { cairo_translate (pCairoContext, pIcon->fDrawX + 2./3*pIcon->fWidth*pIcon->fScale, pIcon->fDrawY); // top right corner cairo_scale (pCairoContext, pIcon->fWidth*pIcon->fScale/3 / myData.hoverIndicator.iWidth, pIcon->fHeight*pIcon->fScale/3 / myData.hoverIndicator.iHeight); } else { cairo_translate (pCairoContext, pIcon->fDrawY + 2./3*pIcon->fWidth*pIcon->fScale, pIcon->fDrawX); cairo_scale (pCairoContext, pIcon->fHeight*pIcon->fScale/3 / myData.hoverIndicator.iWidth, pIcon->fWidth*pIcon->fScale/3 / myData.hoverIndicator.iHeight); } cairo_set_source_surface (pCairoContext, myData.hoverIndicator.pSurface, 0., 0.); cairo_paint_with_alpha (pCairoContext, pData->fAlphaHover); cairo_restore (pCairoContext); } } } else { if (pData->fAlpha > 0) { double fX = pDock->container.iMouseX; double fY = (pDock->container.bDirectionUp ? pDock->iActiveHeight - myData.dropIndicator.iHeight : myData.dropIndicator.iHeight); glPushMatrix(); glLoadIdentity(); if (pDock->container.bIsHorizontal) { fX = pDock->container.iMouseX; fY = (pDock->container.bDirectionUp ? pDock->iActiveHeight - myData.dropIndicator.iHeight : myData.dropIndicator.iHeight); glTranslatef (fX, fY, - myData.dropIndicator.iWidth-1.); if (! pDock->container.bDirectionUp) glScalef (1., -1., 1.); } else { fX = pDock->container.iWidth - pDock->container.iMouseX; fY = (! pDock->container.bDirectionUp ? pDock->iActiveHeight - myData.dropIndicator.iHeight : pDock->container.iHeight - pDock->iActiveHeight + myData.dropIndicator.iHeight); glTranslatef (fY, fX, - myData.dropIndicator.iWidth-1.); glRotatef ((pDock->container.bDirectionUp ? 90. : -90.), 0., 0., 1.); } glRotatef (pData->iDropIndicatorRotation, 0., 1., 0.); //\_________________ On decale la texture vers le bas. glMatrixMode(GL_TEXTURE); // On selectionne la matrice des textures glPushMatrix(); glLoadIdentity(); // On la reset glTranslatef(.0, - (double)pData->iDropIndicatorOffset / myData.dropIndicator.iHeight, 0.); glScalef (1., -2., 1.); glMatrixMode(GL_MODELVIEW); // On revient sur la matrice d'affichage //\_________________ On dessine l'indicateur. glEnable (GL_BLEND); if (pData->fAlpha != 1) _cairo_dock_set_blend_alpha (); else _cairo_dock_set_blend_over(); //glEnable(GL_DEPTH_TEST); glScalef (myData.dropIndicator.iWidth, myData.dropIndicator.iHeight, myData.dropIndicator.iWidth); glColor4f(1.0f, 1.0f, 1.0f, pData->fAlpha); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_TEXTURE); glActiveTextureARB(GL_TEXTURE0_ARB); // Go pour le multitexturing 1ere passe glEnable(GL_TEXTURE_2D); // On active le texturing sur cette passe glBindTexture(GL_TEXTURE_2D, myData.dropIndicator.iTexture); glActiveTextureARB(GL_TEXTURE1_ARB); // Go pour le texturing 2eme passe glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, myData.iBilinearGradationTexture); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Le mode de combinaison des textures ///glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE); // multiplier les alpha. //glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA); glBegin(GL_QUADS); glNormal3f(0,0,1); glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 0.); glVertex3f(-0.5, -1., 0.); // Bottom Left Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 0.); glVertex3f( 0.5, -1., 0.); // Bottom Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 1.); glVertex3f( 0.5, 1., 0.); // Top Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 1.); glVertex3f(-0.5, 1., 0.); // Top Left Of The Texture and Quad glNormal3f(1,0,0); glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 0.); glVertex3f(0., -1., -0.5); // Bottom Left Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 0.); glVertex3f(0., -1., 0.5); // Bottom Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 1.); glVertex3f(0., 1., 0.5); // Top Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 1.); glVertex3f(0., 1., -0.5); // Top Left Of The Texture and Quad glEnd(); glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glActiveTextureARB(GL_TEXTURE0_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable (GL_BLEND); _cairo_dock_set_blend_alpha (); glPopMatrix(); //\_________________ On remet la matrice des textures. glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } if (pData->fAlphaHover > 0 && myData.hoverIndicator.iTexture != 0) { Icon *pIcon = cairo_dock_get_pointed_icon (pDock->icons); if (pIcon != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) { _cairo_dock_enable_texture (); _cairo_dock_set_blend_alpha (); glPushMatrix (); if (pDock->container.bIsHorizontal) glTranslatef (pIcon->fDrawX + 5./6*pIcon->fWidth*pIcon->fScale, pDock->iActiveHeight - pIcon->fDrawY - 1./6*pIcon->fHeight*pIcon->fScale, 0.); else glTranslatef (pIcon->fDrawY + 5./6*pIcon->fHeight*pIcon->fScale, pDock->container.iWidth - (pIcon->fDrawX + 1./6*pIcon->fWidth*pIcon->fScale), 0.); _cairo_dock_apply_texture_at_size_with_alpha (myData.hoverIndicator.iTexture, myData.hoverIndicator.iWidth, myData.hoverIndicator.iHeight, pData->fAlphaHover); glPopMatrix (); _cairo_dock_disable_texture (); } } } return GLDI_NOTIFICATION_LET_PASS; } gboolean cd_drop_indicator_mouse_moved (gpointer pUserData, CairoDock *pDock, gboolean *bStartAnimation) { CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock); if (pDock->bIsDragging) { if (pData == NULL) { pData = g_new0 (CDDropIndicatorData, 1); CD_APPLET_SET_MY_DOCK_DATA (pDock, pData); } if (pDock->bCanDrop) pData->fAlpha = 1.; else pData->fAlphaHover = 1.; } else if (pData != NULL && pData->fAlpha <= 0 && pData->fAlphaHover <= 0) { g_free (pData); pData = NULL; CD_APPLET_SET_MY_DOCK_DATA (pDock, NULL); } if (pData != NULL) *bStartAnimation = TRUE; return GLDI_NOTIFICATION_LET_PASS; } #define delta_alpha 0.06 gboolean cd_drop_indicator_update_dock (gpointer pUserData, CairoDock *pDock, gboolean *bContinueAnimation) { CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock); if (pData == NULL) return GLDI_NOTIFICATION_LET_PASS; pData->iDropIndicatorOffset += myConfig.iSpeed; if (pData->iDropIndicatorOffset > 2*myData.dropIndicator.iHeight) pData->iDropIndicatorOffset -= 2*myData.dropIndicator.iHeight; double dt = cairo_dock_get_animation_delta_t (CAIRO_CONTAINER (pDock)); pData->iDropIndicatorRotation += myConfig.fRotationSpeed * 360. * dt/1e3; if (pDock->bCanDrop) { pData->fAlphaHover -= delta_alpha; *bContinueAnimation = TRUE; } else { pData->fAlpha -= delta_alpha; if (!pDock->bIsDragging) pData->fAlphaHover -= delta_alpha; if (pData->fAlpha <= 0 && pData->fAlphaHover <= 0) { g_free (pData); pData = NULL; CD_APPLET_SET_MY_DOCK_DATA (pDock, NULL); } else *bContinueAnimation = TRUE; } GdkRectangle rect = {(int) pDock->container.iMouseX - myData.dropIndicator.iWidth/2, (int) (pDock->container.bDirectionUp ? 0 : pDock->iActiveHeight - 2*myData.dropIndicator.iHeight), (int) myData.dropIndicator.iWidth, (int) 2*myData.dropIndicator.iHeight}; if (! pDock->container.bIsHorizontal) { rect.x = (int) (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->iActiveHeight : pDock->iActiveHeight - 2*myData.dropIndicator.iHeight); rect.y = (int) pDock->container.iMouseX - myData.dropIndicator.iWidth/2; rect.width = (int) 2*myData.dropIndicator.iHeight; rect.height = (int) myData.dropIndicator.iWidth; } //g_print ("rect (%d;%d) (%dx%d)\n", rect.x, rect.y, rect.width, rect.height); if (rect.width > 0 && rect.height > 0) { cairo_dock_redraw_container_area (CAIRO_CONTAINER (pDock), &rect); } if (pData && pData->fAlphaHover > 0) { Icon *pIcon = cairo_dock_get_pointed_icon (pDock->icons); if (pIcon != NULL) cairo_dock_redraw_icon (pIcon); } return GLDI_NOTIFICATION_LET_PASS; } void cd_drop_indicator_load_drop_indicator (gchar *cImage, int iWidth, int iHeight) { cd_message ("%s (%s)", __func__, cImage); cairo_dock_load_image_buffer (&myData.dropIndicator, cImage, iWidth, iHeight, CAIRO_DOCK_KEEP_RATIO); if (myData.dropIndicator.pSurface == NULL) // image inexistante ou illisible. { cairo_dock_load_image_buffer (&myData.dropIndicator, MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_DEFAULT_DROP_INDICATOR_NAME, iWidth, iHeight, CAIRO_DOCK_KEEP_RATIO); } if (myData.dropIndicator.iTexture != 0 && myData.iBilinearGradationTexture == 0) { myData.iBilinearGradationTexture = cairo_dock_create_texture_from_raw_data (gradationTex, 1, 32); } } void cd_drop_indicator_load_hover_indicator (gchar *cImage, int iWidth, int iHeight) { cd_message ("%s (%s)", __func__, cImage); cairo_dock_load_image_buffer (&myData.hoverIndicator, cImage, iWidth, iHeight, CAIRO_DOCK_KEEP_RATIO); if (myData.hoverIndicator.pSurface == NULL) // image inexistante ou illisible. { cairo_dock_load_image_buffer (&myData.hoverIndicator, MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_DEFAULT_HOVER_INDICATOR_NAME, iWidth, iHeight, CAIRO_DOCK_KEEP_RATIO); } cd_debug (" %p, %d, %d", myData.hoverIndicator.pSurface, myData.hoverIndicator.iTexture, g_bUseOpenGL); } void cd_drop_indicator_free_buffers (void) { cairo_dock_unload_image_buffer (&myData.dropIndicator); cairo_dock_unload_image_buffer (&myData.hoverIndicator); } gboolean cd_drop_indicator_stop_dock (gpointer data, CairoDock *pDock) { CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock); if (pData != NULL) { g_free (pData); CD_APPLET_SET_MY_DOCK_DATA (pDock, NULL); } return GLDI_NOTIFICATION_LET_PASS; } cairo-dock-plugins-3.3.2/drop-indicator/src/applet-config.c000775 001750 001750 00000005464 12223247501 024762 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-notifications.h" #include "applet-config.h" //\_________________ Here you have to get all your parameters from the conf file. Use the macros CD_CONFIG_GET_BOOLEAN, CD_CONFIG_GET_INTEGER, CD_CONFIG_GET_STRING, etc. myConfig has been reseted to 0 at this point. This function is called at the beginning of init and reload. CD_APPLET_GET_CONFIG_BEGIN CD_CONFIG_RENAME_GROUP ("Configuration", "Drag and drop indicator"); myConfig.fRotationSpeed = CD_CONFIG_GET_DOUBLE ("Drag and drop indicator", "rotation speed"); myConfig.iSpeed = CD_CONFIG_GET_INTEGER ("Drag and drop indicator", "speed"); myConfig.cDropIndicatorImageName = CD_CONFIG_GET_STRING ("Drag and drop indicator", "drop indicator"); myConfig.cHoverIndicatorImageName = CD_CONFIG_GET_STRING ("Drag and drop indicator", "hover indicator"); CD_APPLET_GET_CONFIG_END //\_________________ Here you have to free all ressources allocated for myConfig. This one will be reseted to 0 at the end of this function. This function is called right before you get the applet's config, and when your applet is stopped, in the end. CD_APPLET_RESET_CONFIG_BEGIN g_free (myConfig.cDropIndicatorImageName); g_free (myConfig.cHoverIndicatorImageName); CD_APPLET_RESET_CONFIG_END //\_________________ Here you have to free all ressources allocated for myData. This one will be reseted to 0 at the end of this function. This function is called when your applet is stopped, in the very end. static void _reset_data_on_one_dock (const gchar *cDockName, CairoDock *pDock, gpointer data) { CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock); if (pData == NULL) return ; g_free (pData); CD_APPLET_SET_MY_DOCK_DATA (pDock, NULL); } CD_APPLET_RESET_DATA_BEGIN gldi_docks_foreach ((GHFunc) _reset_data_on_one_dock, NULL); cd_drop_indicator_free_buffers (); if (myData.iBilinearGradationTexture != 0) { _cairo_dock_delete_texture (myData.iBilinearGradationTexture); myData.iBilinearGradationTexture = 0; } CD_APPLET_RESET_DATA_END cairo-dock-plugins-3.3.2/drop-indicator/src/applet-config.h000775 001750 001750 00000001642 12223247501 024761 0ustar00mbaertsmbaerts000000 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 __APPLET_CONFIG__ #define __APPLET_CONFIG__ #include CD_APPLET_CONFIG_H void cd_drop_indicator_free_buffers (void); #endif cairo-dock-plugins-3.3.2/drop-indicator/CMakeLists.txt000664 001750 001750 00000000332 12223247501 024021 0ustar00mbaertsmbaerts000000 000000 add_subdirectory(src) add_subdirectory(data) ########### install files ############### #original Makefile.am contents follow: ##dnl Process this file with automake to produce Makefile.in # #SUBDIRS = . src data cairo-dock-plugins-3.3.2/drop-indicator/data/default-hover-indicator.svg000775 001750 001750 00000012264 12223247501 027444 0ustar00mbaertsmbaerts000000 000000 advertising caution security warning signs_and_symbols sign yves GUILLOU yves GUILLOU yves GUILLOU image/svg+xml en cairo-dock-plugins-3.3.2/drop-indicator/data/preview.jpg000664 001750 001750 00000013244 12223247501 024363 0ustar00mbaertsmbaerts000000 000000 JFIFC   %# , #&')*)-0-(0%()(C   ((((((((((((((((((((((((((((((((((((((((((((((((((("B!1AQaq"2RBCSb#$3r%DFc+!1QA"#a2Bq ?cI$Bb`!6 Lq@RBsM!4B qG5.iHpR ,!5"!$#LpGÒa0!c8 ),0#q 0LЃ $RO @)p SBBV&m1oM+l=SW:WiTP,#忂sUPSA;]]JL{nȕ|҇D9ZSRY`lyäx:yWJgw',;gqIPXpsV!kzQ0L$.GXj_SL6Z7xJTe4/nNc/`p9y-f{4-acP"l Hdn OO B$0:)&c`&8ih&Dh< a0sAzu LKp\zo-#jYeuak5/3GW"#`[[o ejj1izfx1]Op-ti ةi cMck^ь*Z4(uک N;^5=4[ŧӷvx}AD4>[|PEcc0QSVT Fm Ús3cPͥm@=3Ϟ;GBݜֹ.(E=SW RM#a,)r\hB ߕ 9U]*li.~,Bc"?F#\nkh%l49yDvye %YOȏ땢5Ub8\wZn4Ze #Wȋ~S@M2-5;,P+.Տ ?gw7GY꘬4(fJuw4|NTj=mXف}G@zy-h'KgEp߄5UpBxFHF4z B0Q&1ܚb !LLi0HA&l@UF{y>ΡN2qy!'gtqM;yU'eGG`\i1U%AG/#mG׶L[G|E]*tqiCaU(L:*}h}NuDv([3D9揉*{\Zʺʦ#-UKU_;HU9+C=.֙g<;dLdQ8ƌ5 ,?AYɰ{Pǐ aPUKnUg- oMg*e,<'zN:nknRlDhM&ݐeR4Or49ȪdJ$-kX~4ND<9Bg%t f)$`04DꌡQjZĐLǴ 3QE5Qj%·|R>Wm U tLƋ//ogZuSPӗI Lc9{wgRCsIH`x>Nocԭj9/T%V?F=~K[hPAGH1[ hIaT;}EF30Lu'1xЩs;r= wHZrw1S]9r4,V1anjS{.d*o4qWk/gP 8Z=ԯm{(ځ?jHߧ:x_,k#`˜7lڵz'fHHc;;P:w+%DQy|4w|W=_kk,щf1w,K^DZ hgY-;s{Gf溶;B\{f~B̡EX$}`=7*M*|]Gk8yt߰qkjzR-.˶C PZ[mvڃd]<>]c ɝJS'CBS+jXTwiX9z- LiJlw+ݲ=0? +Ӷo>m]j] D8Z4UH=T+[;H9T)^jg/tYm'o8 SNk;-QquK}M-{]ۮ4x>tU'[o[[em5ʑ">Ǒ]sJ[(ËW􍶮Ҭ4q't_rjiyOk˫Mre{CTPj&ibu4= ȝK[,,#d ,EΫSk-SM]zHO /q>:,a-KI nPaN8[++e5l8|檏$J[?ҳխR7&UBU`WСQWqʲLT0i̚|햴sqWu RbcZrxԭ$SnQ|vv?]ɸ;8Zz5r=xtΙÐr^kfw n[1GLFpi*z9[k-66\SQebɪjЯQWTo0@ \iЬ]ӵ|@gz紫 s hhOS}^sb-~k҄>ٹlzִzF*q>1#f-w0E$vum0Sc.x. JJ:MCK <9%W{V^a@d:!Ta-u']EULdtC x=V6ʃ?qUPMLOH'28eT2iӳ+dԽ[ifp s [4]Y6C }ڦGtfk`?}ޡSx5N2j}3Yl0n]ȯXV RAU - w^ZWiSK-x#kao8z=gMљ M_Ri{߸M-ӑ=^e>`ZZy%4ɽ<ડx{tj;/oKWW4za ,3oP'tbMdWEs5p3\f5Ϩivx=.vڊ:i[m&S5+\5RXoYu֔󹙦ܿk7n;e{q )Yj[ܤvdl>JzuSQ{,Kvvj*X,! HP '7:cr92ChsOr(ؠdpP")LPas{Cs7 H?M'ASA2"UGY{Ze[~_{ӚZuyUJvz\ʳY,G\`xjo[:)~JPJ lW(*ɶ7}yd@;$8y+:g r gV#aVY\vC%>\uD\Yktncm wOQv=&5=lopP2gUNO*r/ZXԍɃҖUBGoT5zrglƚY%k)$u5tw68qi“sFB/R\#b ut4Cbc`i!tumVUjK}%-4PAm k@aOݷ䫜)NY6r*וI93ji#w>ktuaix|Z"7a4* 4!GDxF Zպ.ѩٚK*[Ox>fBlHH!>JYqGrõ'Ud{D n) 4H^ƐedCa]qP*imIyhLEbEI8QsKe5A'%VL@ UTy* HU6չf6T60廐2|RJw[nk0o9Y&a{~i+!PB⩉;;.-OD!tގ ^lFaIMD#`|Q#BA|Q#B C)Z ssBp&zc'|q!A|q#BC8|q!!E#0dz_d:.~xA(yb image/svg+xml cairo-dock-plugins-3.3.2/drop-indicator/data/default-drop-indicator.svg000775 001750 001750 00000007336 12223247501 027271 0ustar00mbaertsmbaerts000000 000000 arki_arrow_down jean.victor.balin@gmail.com shape arrows Jean-Victor Balin Jean-Victor Balin Jean-Victor Balin image/svg+xml en cairo-dock-plugins-3.3.2/drop-indicator/data/drop_indicator.conf.in000664 001750 001750 00000001155 12223247501 026452 0ustar00mbaertsmbaerts000000 000000 #@VERSION_DROP_INDICATOR@ #[@drop_indicatordatadir@/icon.svg] [Drag and drop indicator] #F[Images] images = #g+[Default] Image for the drag & drop animation: #{Typically an arrow, this will be displayed when you try to drop a new launcher into the dock. Leave this empty to use the default.} drop indicator = #g+[Default] Image when hovering an icon : #{An emblem that will be displayed when you try to drop something on an icon. Leave empty to use the default one.} hover indicator = #F[Animation] animation = #I+[1;5] Speed: speed = 2 #e+[0;1] Rotation speed : #{Number of round per second.} rotation speed = .2 cairo-dock-plugins-3.3.2/Global-Menu/src/applet-struct.h000775 001750 001750 00000005362 12223247501 024227 0ustar00mbaertsmbaerts000000 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 __CD_APPLET_STRUCT__ #define __CD_APPLET_STRUCT__ #include #include #if (GTK_MAJOR_VERSION < 3) || defined (DBUSMENU_GTK3_NEW) #include #include #else #include #include #endif typedef enum { CD_BUTTON_MENU, CD_BUTTON_MINIMIZE, CD_BUTTON_MAXIMIZE, CD_BUTTON_CLOSE, CD_NB_BUTTONS } CDButtonEnum; typedef enum { CD_GM_BUTTON_ORDER_AUTO = 0, CD_GM_BUTTON_ORDER_RIGHT, CD_GM_BUTTON_ORDER_LEFT } CDGMReversedMenu; //\___________ structure containing the applet's configuration parameters. struct _AppletConfig { gboolean bDisplayControls; // steal the window top border gboolean bDisplayMenu; // steal the menu from the window gboolean bCompactMode; // TRUE = if bDisplayControls, display all control buttons on the icon CDGMReversedMenu iButtonsOrder; // Buttons' order (auto / right / left) gchar *cShortkey; // if bDisplayMenu, shortkey to pop up the menu gboolean bMenuOnMouse; gint iTransitionDuration; // ms gchar *cMinimizeImage; gchar *cMaximizeImage; gchar *cRestoreImage; gchar *cCloseImage; } ; //\___________ structure containing the applet's data, like surfaces, dialogs, results of calculus, etc. #define CD_ANIM_STEPS 15 struct _AppletData { DBusGProxy *pProxyRegistrar; gboolean bOwnRegistrar; GldiWindowActor *pPreviousWindow, *pCurrentWindow; // window currently controlled. gboolean bCanClose; gboolean bCanMinimize; gboolean bCanMaximize; DbusmenuGtkMenu *pMenu; GldiShortkey *pKeyBinding; CairoDockImageBuffer defaultIcon; CairoDockImageBuffer minimizeButton; CairoDockImageBuffer maximizeButton; CairoDockImageBuffer restoreButton; CairoDockImageBuffer closeButton; gint iAnimIterMin, iAnimIterMax, iAnimIterClose, iAnimIterRestore; gboolean bButtonAnimating; guint iSidInitIdle; guint iSidInitIdle2; CairoDockTask *pTask; gint iNbButtons; GHashTable *windows; gboolean bReversedButtonsOrder; } ; #endif cairo-dock-plugins-3.3.2/Global-Menu/src/applet-app.c000775 001750 001750 00000026226 12223247501 023460 0ustar00mbaertsmbaerts000000 000000 /** * This file is a part of the Cairo-Dock project * * Copyright : (C) see the 'copyright' file. * based on indicator-messages.c written by : * Ted Gould * Cody Russell * 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 "MwmUtil.h" #include "applet-struct.h" #include "applet-draw.h" #include "applet-app.h" #define CD_APP_MENU_REGISTRAR_ADDR "com.canonical.AppMenu.Registrar" #define CD_APP_MENU_REGISTRAR_OBJ "/com/canonical/AppMenu/Registrar" #define CD_APP_MENU_REGISTRAR_IFACE "com.canonical.AppMenu.Registrar" static DBusGProxyCall *s_pDetectRegistrarCall = NULL; static DBusGProxyCall *s_pGetMenuCall = NULL; /////////////////////// /// WINDOW CONTROLS /// /////////////////////// static void _get_window_allowed_actions (GldiWindowActor *actor) { if (actor == NULL) { myData.bCanMinimize = FALSE; myData.bCanMaximize = FALSE; myData.bCanClose = FALSE; return; } gldi_window_can_minimize_maximize_close (actor, &myData.bCanMinimize, &myData.bCanMaximize, &myData.bCanClose); } static void _set_border (GldiWindowActor *actor, gboolean bWithBorder) { if (actor->bIsMaximized) gldi_window_set_border (actor, bWithBorder); } void cd_app_menu_set_windows_borders (gboolean bWithBorder) { gldi_windows_foreach (FALSE, (GFunc)_set_border, GINT_TO_POINTER (bWithBorder)); } //////////////////////// /// APPLICATION MENU /// //////////////////////// static void cd_app_menu_launch_our_registrar (void) { cairo_dock_launch_command (CD_PLUGINS_DIR"/appmenu-registrar"); myData.bOwnRegistrar = TRUE; } static void _on_registrar_owner_changed (const gchar *cName, gboolean bOwned, gpointer data) { cd_debug ("Registrar is on the bus (%d)", bOwned); CD_APPLET_ENTER; if (bOwned) { // set up a proxy to the Registrar myData.pProxyRegistrar = cairo_dock_create_new_session_proxy ( CD_APP_MENU_REGISTRAR_ADDR, CD_APP_MENU_REGISTRAR_OBJ, CD_APP_MENU_REGISTRAR_IFACE); // whenever it appears on the bus, we'll get it. // get the controls and menu of the current window. GldiWindowActor *actor = gldi_windows_get_active (); cd_app_menu_set_current_window (actor); } else // no more registrar on the bus. { g_object_unref (myData.pProxyRegistrar); myData.pProxyRegistrar = NULL; cd_app_menu_launch_our_registrar (); } CD_APPLET_LEAVE (); } static void _on_detect_registrar (gboolean bPresent, gpointer data) { cd_debug ("Registrar is present: %d", bPresent); CD_APPLET_ENTER; s_pDetectRegistrarCall = NULL; // if present, set up proxy. if (bPresent) { _on_registrar_owner_changed (CD_APP_MENU_REGISTRAR_ADDR, TRUE, NULL); } else { cd_app_menu_launch_our_registrar (); // when it has been launched, we'll get notified by Dbus. } // watch whenever the Registrar goes up or down. cairo_dock_watch_dbus_name_owner (CD_APP_MENU_REGISTRAR_ADDR, (CairoDockDbusNameOwnerChangedFunc) _on_registrar_owner_changed, NULL); CD_APPLET_LEAVE (); } void cd_app_detect_registrar (void) { if (s_pDetectRegistrarCall == NULL) s_pDetectRegistrarCall = cairo_dock_dbus_detect_application_async (CD_APP_MENU_REGISTRAR_ADDR, (CairoDockOnAppliPresentOnDbus) _on_detect_registrar, NULL); } void cd_app_disconnect_from_registrar (void) { // stop detecting/watching the registrar cairo_dock_stop_watching_dbus_name_owner (CD_APP_MENU_REGISTRAR_ADDR, (CairoDockDbusNameOwnerChangedFunc) _on_registrar_owner_changed); if (s_pDetectRegistrarCall != NULL) { DBusGProxy *pProxy = cairo_dock_get_main_proxy (); dbus_g_proxy_cancel_call (pProxy, s_pDetectRegistrarCall); s_pDetectRegistrarCall = NULL; } // discard the menu if (s_pGetMenuCall != NULL) { DBusGProxy *pProxy = cairo_dock_get_main_proxy (); dbus_g_proxy_cancel_call (pProxy, s_pGetMenuCall); s_pGetMenuCall = NULL; } if (myData.pMenu != NULL) { gtk_widget_destroy (GTK_WIDGET (myData.pMenu)); myData.pMenu = NULL; } if (myData.pTask != NULL) { cairo_dock_discard_task (myData.pTask); myData.pTask = NULL; } // kill the registrar if it's our own one if (myData.bOwnRegistrar) { int r = system ("pkill appmenu-registr"); // 15 chars limit; 'pkill -f' doesn't work :-/ this is not very clean, we should get the PID when we spawn it, and use it. if (r < 0) cd_warning ("Not able to launch this command: pkill"); myData.bOwnRegistrar = FALSE; } } typedef struct { gchar *cService; gchar *cMenuObject; DbusmenuGtkMenu *pMenu; } CDSharedMemory; static void _on_menu_destroyed (GldiModuleInstance *myApplet, GObject *old_menu_pointer) { if (old_menu_pointer == (GObject*)myData.pMenu) myData.pMenu = NULL; } /*static void _free_shared_memory (CDSharedMemory *pSharedMemory) { g_free (pSharedMemory->cService); g_free (pSharedMemory->cMenuObject); if (pSharedMemory->pMenu) gtk_widget_destroy (GTK_WIDGET (pSharedMemory->pMenu)); g_free (pSharedMemory); } static void _get_menu_async (CDSharedMemory *pSharedMemory) { cd_debug ("%s()", __func__); pSharedMemory->pMenu = dbusmenu_gtkmenu_new (pSharedMemory->cService, pSharedMemory->cMenuObject); /// can this object disappear by itself ? it seems to crash with 2 instances of inkscape, when closing one of them... cd_debug ("menu built"); } static gboolean _fetch_menu (CDSharedMemory *pSharedMemory) { cd_debug ("%s()", __func__); CD_APPLET_ENTER; myData.pMenu = pSharedMemory->pMenu; pSharedMemory->pMenu = NULL; g_object_weak_ref (G_OBJECT (myData.pMenu), (GWeakNotify)_on_menu_destroyed, myApplet); CD_APPLET_LEAVE (TRUE); }*/ static void _on_got_menu (DBusGProxy *proxy, DBusGProxyCall *call_id, GldiModuleInstance *myApplet) { cd_debug ("%s ()", __func__); CD_APPLET_ENTER; s_pGetMenuCall = NULL; GError *erreur = NULL; gchar *cService = NULL, *cMenuObject = NULL; gboolean bSuccess = dbus_g_proxy_end_call (proxy, call_id, &erreur, G_TYPE_STRING, &cService, DBUS_TYPE_G_OBJECT_PATH, &cMenuObject, G_TYPE_INVALID); if (erreur) { cd_warning ("couldn't get the application menu (%s)", erreur->message); g_error_free (erreur); } if (bSuccess) { cd_debug (" -> %s", cService); cd_debug (" %s", cMenuObject); if (cService && *cService != '\0') { /*if (myData.pTask != NULL) { cairo_dock_discard_task (myData.pTask); myData.pTask = NULL; } CDSharedMemory *pSharedMemory = g_new0 (CDSharedMemory, 1); pSharedMemory->cService = cService; pSharedMemory->cMenuObject = cMenuObject; myData.pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _get_menu_async, (CairoDockUpdateSyncFunc) _fetch_menu, (GFreeFunc) _free_shared_memory, pSharedMemory); cairo_dock_launch_task_delayed (myData.pTask, 0);*/ /// TODO: it seems to hang he dock for a second, even with a task :-/ /// so maybe we need to cache the {window,menu} couples... myData.pMenu = dbusmenu_gtkmenu_new (cService, cMenuObject); /// can this object disappear by itself ? it seems to crash with 2 instances of inkscape, when closing one of them... if (g_object_is_floating (myData.pMenu)) // claim ownership on the menu. g_object_ref_sink (myData.pMenu); if (myData.pMenu) { g_object_weak_ref (G_OBJECT (myData.pMenu), (GWeakNotify)_on_menu_destroyed, myApplet); gldi_menu_init (GTK_WIDGET(myData.pMenu), myIcon); } } } ///g_free (cService); ///g_free (cMenuObject); CD_APPLET_LEAVE (); } static void _get_application_menu (GldiWindowActor *actor) { // destroy the current menu if (myData.pMenu != NULL) { gtk_widget_destroy (GTK_WIDGET (myData.pMenu)); myData.pMenu = NULL; } if (s_pGetMenuCall != NULL) { DBusGProxy *pProxy = cairo_dock_get_main_proxy (); dbus_g_proxy_cancel_call (pProxy, s_pGetMenuCall); s_pGetMenuCall = NULL; } if (myData.pTask != NULL) { cairo_dock_discard_task (myData.pTask); myData.pTask = NULL; } // get the new one. if (actor != NULL) { if (myData.pProxyRegistrar != NULL) { guint id = gldi_window_get_id (actor); s_pGetMenuCall = dbus_g_proxy_begin_call (myData.pProxyRegistrar, "GetMenuForWindow", (DBusGProxyCallNotify)_on_got_menu, myApplet, (GDestroyNotify) NULL, G_TYPE_UINT, id, G_TYPE_INVALID); } } } //////////////////// /// START / STOP /// //////////////////// static gboolean _get_current_window_idle (GldiModuleInstance *myApplet) { // get the controls and menu of the current window. GldiWindowActor *actor = gldi_windows_get_active (); cd_app_menu_set_current_window (actor); myData.iSidInitIdle = 0; return FALSE; } static gboolean _remove_windows_borders_idle (GldiModuleInstance *myApplet) { cd_app_menu_set_windows_borders (FALSE); myData.iSidInitIdle2 = 0; return FALSE; } void cd_app_menu_start (void) { // connect to the registrar or directly get the current window. if (myConfig.bDisplayMenu) { cd_app_detect_registrar (); // -> will get the current window once connected to the registrar } else { myData.iSidInitIdle = g_idle_add ((GSourceFunc)_get_current_window_idle, myApplet); // in idle, because it's heavy + the applications-manager is started after the plug-ins. } // remove borders from all maximised windows if (myConfig.bDisplayControls) { myData.iSidInitIdle2 = g_idle_add ((GSourceFunc)_remove_windows_borders_idle, myApplet); // in idle, because it's heavy + the applications-manager is started after the plug-ins. } if (myConfig.bDisplayControls) { cd_app_menu_resize (); } } void cd_app_menu_stop (void) { // disconnect from the registrar. if (myConfig.bDisplayMenu) { cd_app_disconnect_from_registrar (); } // set back the window border of maximized windows. if (myConfig.bDisplayControls) { cd_app_menu_set_windows_borders (TRUE); } if (myData.iSidInitIdle != 0) g_source_remove (myData.iSidInitIdle); if (myData.iSidInitIdle2 != 0) g_source_remove (myData.iSidInitIdle2); gldi_icon_unset_appli (myIcon); } void cd_app_menu_set_current_window (GldiWindowActor *actor) { cd_debug ("%s (%p)", __func__, actor); if (actor != myData.pCurrentWindow) { myData.pPreviousWindow = myData.pCurrentWindow; myData.pCurrentWindow = actor; gldi_icon_set_appli (myIcon, actor); // set the actor on our icon, so that the dock adds the usual actions in our right-click menu. // this takes a reference on the actor, and remove the ref on the previous one. if (myConfig.bDisplayMenu) _get_application_menu (actor); if (myConfig.bDisplayControls) _get_window_allowed_actions (actor); // update the icon CD_APPLET_SET_NAME_FOR_MY_ICON (actor ? actor->cName : NULL); cd_app_menu_redraw_icon (); } } cairo-dock-plugins-3.3.2/Global-Menu/src/applet-init.h000775 001750 001750 00000001553 12223247501 023644 0ustar00mbaertsmbaerts000000 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 __APPLET_INIT__ #define __APPLET_INIT__ #include CD_APPLET_H #endif cairo-dock-plugins-3.3.2/Global-Menu/src/applet-notifications.h000775 001750 001750 00000003430 12223247501 025546 0ustar00mbaertsmbaerts000000 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 __APPLET_NOTIFICATIONS__ #define __APPLET_NOTIFICATIONS__ #include CD_APPLET_ON_CLICK_H CD_APPLET_ON_MIDDLE_CLICK_H CD_APPLET_ON_SCROLL_H CD_APPLET_ON_DOUBLE_CLICK_H // CD_APPLET_ON_BUILD_MENU_H void cd_app_menu_on_keybinding_pull (const gchar *keystring, GldiModuleInstance *myApplet); gboolean on_mouse_moved (GldiModuleInstance *myApplet, GldiContainer *pContainer, gboolean *bStartAnimation); gboolean cd_app_menu_on_active_window_changed (GldiModuleInstance *myApplet, GldiWindowActor *actor); gboolean cd_app_menu_on_state_changed (GldiModuleInstance *myApplet, GldiWindowActor *actor, gboolean bHiddenChanged, gboolean bMaximizedChanged, gboolean bFullScreenChanged); gboolean cd_app_menu_on_name_changed (GldiModuleInstance *myApplet, GldiWindowActor *actor); gboolean cd_app_menu_on_new_appli (GldiModuleInstance *myApplet, GldiWindowActor *actor); gboolean cd_app_menu_on_update_container (GldiModuleInstance *myApplet, GldiContainer *pContainer, gboolean *bContinueAnimation); #endif cairo-dock-plugins-3.3.2/Global-Menu/src/CMakeLists.txt000664 001750 001750 00000003134 12223247501 023777 0ustar00mbaertsmbaerts000000 000000 ########### sources ############### SET(MODULE_SRCS applet-struct.h applet-init.c applet-init.h applet-config.c applet-config.h applet-notifications.c applet-notifications.h applet-app.c applet-app.h applet-draw.c applet-draw.h ) add_library(${PACKAGE_GLOBAL_MENU} SHARED ${MODULE_SRCS}) ########### compil ############### add_definitions (-DMY_APPLET_SHARE_DATA_DIR="${global_menudatadir}") add_definitions (-DMY_APPLET_PREVIEW_FILE="preview.jpg") add_definitions (-DMY_APPLET_CONF_FILE="Global-Menu.conf") add_definitions (-DMY_APPLET_USER_DATA_DIR="Global-Menu") add_definitions (-DMY_APPLET_VERSION="${VERSION_GLOBAL_MENU}") add_definitions (-DMY_APPLET_GETTEXT_DOMAIN="${GETTEXT_GLOBAL_MENU}") add_definitions (-DMY_APPLET_DOCK_VERSION="${dock_version}") add_definitions (-DMY_APPLET_ICON_FILE="icon.svg") add_definitions (-DCD_PLUGINS_DIR="${pluginsdir}") ### uncomment the following line to allow multi-instance applet. #add_definitions (-DCD_APPLET_MULTI_INSTANCE="1") ### uncomment the following line to allow extended OpenGL drawing. #add_definitions (-DGL_GLEXT_PROTOTYPES="1") if (${DBUSMENU_GTK3_NEW}) add_definitions (-DDBUSMENU_GTK3_NEW=1) endif() include_directories ( ${PACKAGE_INCLUDE_DIRS} ${DBUSMENU_INCLUDE_DIRS} ${DBUSMENU_GTK_INCLUDE_DIRS}) link_directories ( ${PACKAGE_LIBRARY_DIRS} ${DBUSMENU_LIBRARY_DIRS} ${DBUSMENU_GTK_LIBRARY_DIRS}) target_link_libraries (${PACKAGE_GLOBAL_MENU} ${PACKAGE_LIBRARIES} ${DBUSMENU_LIBRARIES} ${DBUSMENU_GTK_LIBRARIES}) ########### install files ############### install(TARGETS ${PACKAGE_GLOBAL_MENU} DESTINATION ${pluginsdir}) cairo-dock-plugins-3.3.2/Global-Menu/src/applet-init.c000775 001750 001750 00000022147 12223247501 023641 0ustar00mbaertsmbaerts000000 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 "stdlib.h" #include "applet-config.h" #include "applet-notifications.h" #include "applet-app.h" #include "applet-draw.h" #include "applet-struct.h" #include "applet-init.h" CD_APPLET_DEFINE_BEGIN (N_("Global Menu"), 3, 0, 0, CAIRO_DOCK_CATEGORY_APPLET_DESKTOP, N_("This applet allows you to control the current active window:\n" " close, minimize, maximize, and display the application menu." "To display the menu, applications have to support this feature, which is the case on Ubuntu by default.\n" "You can bind a shortkey to this action."), "Fabounet") CD_APPLET_DEFINE_COMMON_APPLET_INTERFACE CD_APPLET_ALLOW_EMPTY_TITLE CD_APPLET_DEFINE_END static gboolean _reversed_buttons_order (void) { // TRUE: on the left (close, min, max) || FALSE: on the right (min, max, close) if (myConfig.iButtonsOrder == CD_GM_BUTTON_ORDER_AUTO && ((myDock && (int) myIcon->fXAtRest < (myDock->container.iWidth / 2)) || (myDesklet && myDesklet->container.iWindowPositionX < (g_desktopGeometry.Xscreen.width / 2)))) return TRUE; return (myConfig.iButtonsOrder == CD_GM_BUTTON_ORDER_LEFT); } //\___________ Here is where you initiate your applet. myConfig is already set at this point, and also myIcon, myContainer, myDock, myDesklet (and myDrawContext if you're in dock mode). The macro CD_APPLET_MY_CONF_FILE and CD_APPLET_MY_KEY_FILE can give you access to the applet's conf-file and its corresponding key-file (also available during reload). If you're in desklet mode, myDrawContext is still NULL, and myIcon's buffers has not been filled, because you may not need them then (idem when reloading). CD_APPLET_INIT_BEGIN if (myDesklet) { CD_APPLET_SET_DESKLET_RENDERER ("Simple"); // set a desklet renderer. } gldi_object_register_notification (&myWindowObjectMgr, NOTIFICATION_WINDOW_ACTIVATED, (GldiNotificationFunc) cd_app_menu_on_active_window_changed, GLDI_RUN_AFTER, myApplet); gldi_object_register_notification (&myWindowObjectMgr, NOTIFICATION_WINDOW_STATE_CHANGED, (GldiNotificationFunc) cd_app_menu_on_state_changed, GLDI_RUN_AFTER, myApplet); gldi_object_register_notification (&myWindowObjectMgr, NOTIFICATION_WINDOW_NAME_CHANGED, (GldiNotificationFunc) cd_app_menu_on_name_changed, GLDI_RUN_AFTER, myApplet); gldi_object_register_notification (&myWindowObjectMgr, NOTIFICATION_WINDOW_CREATED, (GldiNotificationFunc) cd_app_menu_on_new_appli, GLDI_RUN_AFTER, myApplet); gldi_object_register_notification (myContainer, NOTIFICATION_MOUSE_MOVED, (GldiNotificationFunc) on_mouse_moved, GLDI_RUN_AFTER, myApplet); gldi_object_register_notification (myContainer, NOTIFICATION_UPDATE_SLOW, (GldiNotificationFunc) cd_app_menu_on_update_container, GLDI_RUN_AFTER, myApplet); // start ! myData.iNbButtons = myConfig.bDisplayControls * 3 + 1; // we display the icon even if we don't provide the menu. cd_app_menu_start (); if (myConfig.bDisplayControls) // no animation on mouse hover if the buttons are displayed, it's hard to click { CD_APPLET_SET_STATIC_ICON; myData.bReversedButtonsOrder = _reversed_buttons_order (); /** => TODO? check if the position of the icon has changed? * => if we use the 'auto' position, this position of the icon seems to * not be correct if we call this function here... we can check if * something has changed with CD_APPLET_RELOAD but the order doesn't * change if the icon has been moved in the same dock (it works if the * container has changed). Do we have to register to this notifications? * => NOTIFICATION_ICON_MOVED */ } // mouse events CD_APPLET_REGISTER_FOR_CLICK_EVENT; CD_APPLET_REGISTER_FOR_MIDDLE_CLICK_EVENT; CD_APPLET_REGISTER_FOR_DOUBLE_CLICK_EVENT; // CD_APPLET_REGISTER_FOR_BUILD_MENU_EVENT; CD_APPLET_REGISTER_FOR_SCROLL_EVENT; // keyboard events if (myConfig.bDisplayMenu) myData.pKeyBinding = CD_APPLET_BIND_KEY (myConfig.cShortkey, D_("Show/hide the current application menu"), "Configuration", "shortkey", (CDBindkeyHandler) cd_app_menu_on_keybinding_pull); CD_APPLET_INIT_END //\___________ Here is where you stop your applet. myConfig and myData are still valid, but will be reseted to 0 at the end of the function. In the end, your applet will go back to its original state, as if it had never been activated. CD_APPLET_STOP_BEGIN gldi_object_remove_notification (&myWindowObjectMgr, NOTIFICATION_WINDOW_ACTIVATED, (GldiNotificationFunc) cd_app_menu_on_active_window_changed, myApplet); gldi_object_remove_notification (&myWindowObjectMgr, NOTIFICATION_WINDOW_STATE_CHANGED, (GldiNotificationFunc) cd_app_menu_on_state_changed, myApplet); gldi_object_remove_notification (&myWindowObjectMgr, NOTIFICATION_WINDOW_NAME_CHANGED, (GldiNotificationFunc) cd_app_menu_on_name_changed, myApplet); gldi_object_remove_notification (&myWindowObjectMgr, NOTIFICATION_WINDOW_CREATED, (GldiNotificationFunc) cd_app_menu_on_new_appli, myApplet); gldi_object_remove_notification (myContainer, NOTIFICATION_MOUSE_MOVED, (GldiNotificationFunc) on_mouse_moved, myApplet); gldi_object_remove_notification (myContainer, NOTIFICATION_UPDATE_SLOW, (GldiNotificationFunc) cd_app_menu_on_update_container, myApplet); cd_app_menu_stop (); // mouse events CD_APPLET_UNREGISTER_FOR_CLICK_EVENT; CD_APPLET_UNREGISTER_FOR_DOUBLE_CLICK_EVENT; CD_APPLET_UNREGISTER_FOR_MIDDLE_CLICK_EVENT; // CD_APPLET_UNREGISTER_FOR_BUILD_MENU_EVENT; CD_APPLET_UNREGISTER_FOR_SCROLL_EVENT; // keyboard events if (myConfig.bDisplayMenu) gldi_object_unref (GLDI_OBJECT(myData.pKeyBinding)); CD_APPLET_STOP_END //\___________ The reload occurs in 2 occasions : when the user changes the applet's config, and when the user reload the cairo-dock's config or modify the desklet's size. The macro CD_APPLET_MY_CONFIG_CHANGED can tell you this. myConfig has already been reloaded at this point if you're in the first case, myData is untouched. You also have the macro CD_APPLET_MY_CONTAINER_TYPE_CHANGED that can tell you if you switched from dock/desklet to desklet/dock mode. CD_APPLET_RELOAD_BEGIN // if they are loaded, reload the controls icons. cd_app_menu_load_button_images (); cd_app_menu_default_image (); if (CD_APPLET_MY_CONFIG_CHANGED) { if (myDesklet && CD_APPLET_MY_CONTAINER_TYPE_CHANGED) // we are now in a desklet, set a renderer. { CD_APPLET_SET_DESKLET_RENDERER ("Simple"); } if (CD_APPLET_MY_OLD_CONTAINER != myContainer) { gldi_object_remove_notification (CD_APPLET_MY_OLD_CONTAINER, NOTIFICATION_MOUSE_MOVED, (GldiNotificationFunc) on_mouse_moved, myApplet); gldi_object_remove_notification (CD_APPLET_MY_OLD_CONTAINER, NOTIFICATION_UPDATE_SLOW, (GldiNotificationFunc) cd_app_menu_on_update_container, myApplet); gldi_object_register_notification (myContainer, NOTIFICATION_MOUSE_MOVED, (GldiNotificationFunc) on_mouse_moved, GLDI_RUN_AFTER, myApplet); gldi_object_register_notification (myContainer, NOTIFICATION_UPDATE_SLOW, (GldiNotificationFunc) cd_app_menu_on_update_container, GLDI_RUN_AFTER, myApplet); } // windows borders cd_app_menu_set_windows_borders (!myConfig.bDisplayControls); // registrar if (myConfig.bDisplayMenu && !myData.pProxyRegistrar) cd_app_detect_registrar (); else if (! myConfig.bDisplayMenu) // even if myData.pProxyRegistrar is NULL, we have to cancel the detection cd_app_disconnect_from_registrar (); // to update any param that could have changed, simply re-set the current window. myData.iNbButtons = myConfig.bDisplayControls * 3 + 1; myData.iAnimIterMin = myData.iAnimIterMax = myData.iAnimIterClose = 0; myData.bButtonAnimating = FALSE; GldiWindowActor *pActiveWindow = myData.pCurrentWindow; myData.pCurrentWindow = NULL; cd_app_menu_set_current_window (pActiveWindow); // shortkey if (myConfig.bDisplayMenu) { if (myData.pKeyBinding) gldi_shortkey_rebind (myData.pKeyBinding, myConfig.cShortkey, NULL); else myData.pKeyBinding = CD_APPLET_BIND_KEY (myConfig.cShortkey, D_("Show/hide the current application menu"), "Configuration", "shortkey", (CDBindkeyHandler) cd_app_menu_on_keybinding_pull); } else if (myData.pKeyBinding) { gldi_object_unref (GLDI_OBJECT(myData.pKeyBinding)); } cairo_dock_set_icon_static (myIcon, myConfig.bDisplayControls); } if (myConfig.bDisplayControls) { myData.bReversedButtonsOrder = _reversed_buttons_order (); cd_app_menu_resize (); } CD_APPLET_RELOAD_END cairo-dock-plugins-3.3.2/Global-Menu/src/applet-draw.c000775 001750 001750 00000030443 12223247501 023631 0ustar00mbaertsmbaerts000000 000000 /** * This file is a part of the Cairo-Dock project * * Copyright : (C) see the 'copyright' file. * based on indicator-messages.c written by : * Ted Gould * Cody Russell * 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 "applet-struct.h" #include "applet-draw.h" #define _compute_alpha(pImage, iAnimIter, bEnabled) (bEnabled ? \ cairo_dock_image_buffer_is_animated (pImage) ? \ 1. : \ 1. - .4 * sin (G_PI * iAnimIter / (CD_ANIM_STEPS - 1))\ : .6) static void _apply_button_opengl (CairoDockImageBuffer *pImage, int x, int y, gboolean bEnabled, gint iAnimIter) { double fAlpha = _compute_alpha (pImage, iAnimIter, bEnabled); _cairo_dock_set_alpha (fAlpha); cairo_dock_apply_image_buffer_texture_with_offset (pImage, x, y); } static void _apply_button_cairo (CairoDockImageBuffer *pImage, int x, int y, gboolean bEnabled, gint iAnimIter) { double fAlpha = _compute_alpha (pImage, iAnimIter, bEnabled); cairo_dock_apply_image_buffer_surface_with_offset (pImage, myDrawContext, x, y, fAlpha); } static gboolean cd_app_menu_render_step_opengl (Icon *pIcon, GldiModuleInstance *myApplet) { CD_APPLET_ENTER; double f = CD_APPLET_GET_TRANSITION_FRACTION (); int iWidth, iHeight; CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight); CD_APPLET_LEAVE_IF_FAIL (iHeight != 0, TRUE); _cairo_dock_enable_texture (); _cairo_dock_set_blend_alpha (); // icon position/size int x, y, w, h; if (myConfig.bDisplayControls) { w = MIN (iWidth, iHeight); h = w; } else { w = iWidth; h = iHeight; } if (iWidth > iHeight) // horizontal alignment { x = (-iWidth + w)/2; // on the left y = 0; // vertically centered } else // vertical alignment { x = 0; // horizontally centered y = (iHeight - h)/2; // on top } // draw current icon const CairoDockImageBuffer *pImage = NULL, *pPrevImage = NULL; Icon *pAppli = cairo_dock_get_appli_icon (myData.pCurrentWindow); if (pAppli) { pImage = gldi_appli_icon_get_image_buffer (pAppli); } GLuint iTexture = (pImage ? pImage->iTexture : 0); Icon *pPrevIcon = cairo_dock_get_appli_icon (myData.pPreviousWindow); if (pPrevIcon) { pPrevImage = gldi_appli_icon_get_image_buffer (pPrevIcon); } GLuint iPrevTexture = (pPrevImage ? pPrevImage->iTexture : 0); if (iPrevTexture != 0) { _cairo_dock_set_alpha (1-f); glBindTexture (GL_TEXTURE_2D, iPrevTexture); _cairo_dock_apply_current_texture_at_size_with_offset (w, h, x, y); } if (iTexture != 0) { _cairo_dock_set_alpha (f); glBindTexture (GL_TEXTURE_2D, iTexture); _cairo_dock_apply_current_texture_at_size_with_offset (w, h, x, y); } _cairo_dock_set_alpha (1); // draw window buttons if (myConfig.bDisplayControls) { // minimize button if (iWidth > iHeight) // horizontal alignment x += w; else y -= w; if (myData.bReversedButtonsOrder) _apply_button_opengl (&myData.closeButton, x, y, myData.pCurrentWindow && myData.bCanClose, myData.iAnimIterClose); else _apply_button_opengl (&myData.minimizeButton, x, y, myData.pCurrentWindow && myData.bCanMinimize, myData.iAnimIterMin); // restore/maximize button if (iWidth > iHeight) // horizontal alignment x += w; else y -= w; if (myData.bReversedButtonsOrder) _apply_button_opengl (&myData.minimizeButton, x, y, myData.pCurrentWindow && myData.bCanMinimize, myData.iAnimIterMin); else { if (myData.pCurrentWindow && myData.pCurrentWindow->bIsMaximized) _apply_button_opengl (&myData.restoreButton, x, y, myData.pCurrentWindow && myData.bCanMaximize, myData.iAnimIterRestore); else _apply_button_opengl (&myData.maximizeButton, x, y, myData.pCurrentWindow && myData.bCanMaximize, myData.iAnimIterMax); } // close button if (iWidth > iHeight) // horizontal alignment x += w; else y -= h; if (myData.bReversedButtonsOrder) { if (myData.pCurrentWindow && myData.pCurrentWindow->bIsMaximized) _apply_button_opengl (&myData.restoreButton, x, y, myData.pCurrentWindow && myData.bCanMaximize, myData.iAnimIterRestore); else _apply_button_opengl (&myData.maximizeButton, x, y, myData.pCurrentWindow && myData.bCanMaximize, myData.iAnimIterMax); } else _apply_button_opengl (&myData.closeButton, x, y, myData.pCurrentWindow && myData.bCanClose, myData.iAnimIterClose); } _cairo_dock_disable_texture (); CD_APPLET_LEAVE (TRUE); } static gboolean cd_app_menu_render_step_cairo (Icon *pIcon, GldiModuleInstance *myApplet) { CD_APPLET_ENTER; double f = CD_APPLET_GET_TRANSITION_FRACTION (); int iWidth, iHeight; CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight); CD_APPLET_LEAVE_IF_FAIL (iHeight != 0, TRUE); CD_APPLET_START_DRAWING_MY_ICON_OR_RETURN_CAIRO (FALSE); // items size int x, y, w, h; if (myConfig.bDisplayControls) // we need to draw the icon + 3 buttons { if (iWidth > iHeight) // horizontal alignment { w = MIN (iWidth / 4, iHeight); h = w; } else { w = MIN (iHeight / 4, iWidth); h = w; } } else // just draw the icon on the whole surface. { w = iWidth; h = iHeight; } // draw current icon if (iWidth > iHeight) // horizontal alignment { x = 0; // on the left y = (-iHeight + h)/2; // vertically centered } else // vertical alignment { x = (iWidth - w)/2; // horizontally centered y = 0; // on top } const CairoDockImageBuffer *pImage = NULL, *pPrevImage = NULL; Icon *pPrevIcon = cairo_dock_get_appli_icon (myData.pPreviousWindow); if (pPrevIcon) { pPrevImage = gldi_appli_icon_get_image_buffer (pPrevIcon); } if (pPrevImage && pPrevImage->pSurface) { cairo_dock_apply_image_buffer_surface_at_size (pPrevImage, myDrawContext, w, h, x, y, 1-f); } Icon *pAppli = cairo_dock_get_appli_icon (myData.pCurrentWindow); if (pAppli) { pImage = gldi_appli_icon_get_image_buffer (pAppli); } if (pImage && pImage->pSurface) { cairo_dock_apply_image_buffer_surface_at_size (pImage, myDrawContext, w, h, x, y, f); } // draw window buttons if (myConfig.bDisplayControls) { // minimize button if (iWidth > iHeight) // horizontal alignment x += w; else y += h; if (myData.bReversedButtonsOrder) _apply_button_cairo (&myData.closeButton, x, y, myData.pCurrentWindow && myData.bCanClose, myData.iAnimIterClose); else _apply_button_cairo (&myData.minimizeButton, x, y, myData.pCurrentWindow && myData.bCanMinimize, myData.iAnimIterMin); // restore/maximize button if (iWidth > iHeight) // horizontal alignment x += w; else y += h; if (myData.bReversedButtonsOrder) _apply_button_cairo (&myData.minimizeButton, x, y, myData.pCurrentWindow && myData.bCanMinimize, myData.iAnimIterMin); else { if (myData.pCurrentWindow && myData.pCurrentWindow->bIsMaximized) _apply_button_cairo (&myData.maximizeButton, x, y, myData.pCurrentWindow && myData.bCanMaximize, myData.iAnimIterMax); else _apply_button_cairo (&myData.restoreButton, x, y, myData.pCurrentWindow && myData.bCanMaximize, myData.iAnimIterRestore); } // close button if (iWidth > iHeight) // horizontal alignment x += w; else y += h; if (myData.bReversedButtonsOrder) { if (myData.pCurrentWindow && myData.pCurrentWindow->bIsMaximized) _apply_button_cairo (&myData.maximizeButton, x, y, myData.pCurrentWindow && myData.bCanMaximize, myData.iAnimIterMax); else _apply_button_cairo (&myData.restoreButton, x, y, myData.pCurrentWindow && myData.bCanMaximize, myData.iAnimIterRestore); } else _apply_button_cairo (&myData.closeButton, x, y, myData.pCurrentWindow && myData.bCanClose, myData.iAnimIterClose); } CD_APPLET_FINISH_DRAWING_MY_ICON_CAIRO; CD_APPLET_LEAVE (TRUE); } void cd_app_menu_load_button_images (void) { int iWidth, iHeight; CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight); g_return_if_fail (iHeight != 0); cairo_dock_unload_image_buffer (&myData.minimizeButton); cairo_dock_unload_image_buffer (&myData.maximizeButton); cairo_dock_unload_image_buffer (&myData.restoreButton); cairo_dock_unload_image_buffer (&myData.closeButton); if (myConfig.bDisplayControls) { int w, h; w = MIN (iWidth, iHeight); h = w; cairo_dock_load_image_buffer (&myData.minimizeButton, myConfig.cMinimizeImage, w, h, CAIRO_DOCK_ANIMATED_IMAGE); cairo_dock_image_buffer_set_timelength (&myData.minimizeButton, 3.); // 4s cairo_dock_load_image_buffer (&myData.maximizeButton, myConfig.cMaximizeImage, w, h, CAIRO_DOCK_ANIMATED_IMAGE); cairo_dock_image_buffer_set_timelength (&myData.maximizeButton, 3.); cairo_dock_load_image_buffer (&myData.restoreButton, myConfig.cRestoreImage, w, h, CAIRO_DOCK_ANIMATED_IMAGE); cairo_dock_image_buffer_set_timelength (&myData.restoreButton, 3.); cairo_dock_load_image_buffer (&myData.closeButton, myConfig.cCloseImage, w, h, CAIRO_DOCK_ANIMATED_IMAGE); cairo_dock_image_buffer_set_timelength (&myData.closeButton, 3.); } } void cd_app_menu_default_image (void) { int iWidth, iHeight; CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight); g_return_if_fail (iHeight != 0); int w, h; if (myConfig.bDisplayControls) { w = MIN (iWidth, iHeight); h = w; } else { w = iWidth; h = iHeight; } cairo_dock_load_image_buffer (&myData.defaultIcon, MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE, w, h, 0); } void cd_app_menu_redraw_icon (void) { // load the buttons and the default icon if (myData.pCurrentWindow == NULL && myData.defaultIcon.iWidth == 0) { cd_app_menu_default_image (); } if (myData.minimizeButton.iWidth == 0) { cd_app_menu_load_button_images (); } // set and launch a transition CD_APPLET_SET_TRANSITION_ON_MY_ICON (cd_app_menu_render_step_cairo, cd_app_menu_render_step_opengl, g_bUseOpenGL, // bFastPace : vite si opengl, lent si cairo. myConfig.iTransitionDuration, TRUE); // bRemoveWhenFinished } void cd_app_menu_redraw_buttons (void) { if (CD_APPLET_MY_CONTAINER_IS_OPENGL) { CD_APPLET_START_DRAWING_MY_ICON_OR_RETURN (); cd_app_menu_render_step_opengl (myIcon, myApplet); CD_APPLET_FINISH_DRAWING_MY_ICON; } else { cd_app_menu_render_step_cairo (myIcon, myApplet); } } void cd_app_menu_resize (void) { int iWidth, iHeight; CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight); if (myContainer->bIsHorizontal) cairo_dock_resize_applet (myApplet, MAX (iWidth, myData.iNbButtons*iHeight), iHeight); else cairo_dock_resize_applet (myApplet, iWidth, MAX (myData.iNbButtons*iWidth, iHeight)); } CDButtonEnum cd_app_menu_find_button (GldiModuleInstance *myApplet) { int iNumButton = -1; int iMouseX, iMouseY; if (myDesklet) /// TODO: handle the opengl picking... { iMouseX = myDesklet->iMouseX2d; iMouseY = myDesklet->iMouseY2d; } else { iMouseX = myContainer->iMouseX - myIcon->fDrawX; iMouseY = myContainer->iMouseY - myIcon->fDrawY; } int w, h; if (myContainer->bIsHorizontal) { w = myIcon->fWidth * myIcon->fScale; h = myIcon->fHeight * myIcon->fScale; } else { h = myIcon->fWidth * myIcon->fScale; w = myIcon->fHeight * myIcon->fScale; int tmp = iMouseX; iMouseX = iMouseY; iMouseY = tmp; } g_return_val_if_fail (w + h != 0, iNumButton); // it can crash with Arithmetic exception if we switch from the dock to a desklet if (w >= h) // horizontal alignment { iNumButton = iMouseX / (w/myData.iNbButtons); } else // vertical alignment { iNumButton = iMouseY / (h/myData.iNbButtons); } if (!myConfig.bDisplayControls) iNumButton++; if (myData.bReversedButtonsOrder) // 1->1 ; 2->4 ; 3->2 ; 4->3 { // Menu (1) - Close (4) - Min (2) - Max (3) instead of // Menu (1) - Min (2) - Max (3) - Close (4) if (iNumButton == CD_BUTTON_MINIMIZE) // 2 is now 4 iNumButton = CD_BUTTON_CLOSE; else if (iNumButton != CD_BUTTON_MENU) iNumButton--; // 3 is now 2 and 4 is now 3 } return iNumButton; } cairo-dock-plugins-3.3.2/Global-Menu/src/applet-draw.h000775 001750 001750 00000002206 12223247501 023632 0ustar00mbaertsmbaerts000000 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 __APPLET_DRAW__ #define __APPLET_DRAW__ #include #include "applet-struct.h" void cd_app_menu_load_button_images (void); void cd_app_menu_default_image (void); void cd_app_menu_redraw_icon (void); void cd_app_menu_redraw_buttons (void); void cd_app_menu_resize (void); CDButtonEnum cd_app_menu_find_button (GldiModuleInstance *myApplet); #endif cairo-dock-plugins-3.3.2/Global-Menu/src/applet-app.h000775 001750 001750 00000002314 12223247501 023455 0ustar00mbaertsmbaerts000000 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 __APPLET_APP_MENU__ #define __APPLET_APP_MENU__ #include void cd_app_menu_set_window_border (GldiWindowActor *actor, gboolean bWithBorder); void cd_app_menu_set_windows_borders (gboolean bWithBorder); void cd_app_detect_registrar (void); void cd_app_disconnect_from_registrar (void); void cd_app_menu_start (void); void cd_app_menu_stop (void); void cd_app_menu_set_current_window (GldiWindowActor *actor); #endif cairo-dock-plugins-3.3.2/Global-Menu/src/MwmUtil.h000664 001750 001750 00000007306 12223247501 023013 0ustar00mbaertsmbaerts000000 000000 /** * * $Id$ * * Copyright (C) 1995 Free Software Foundation, Inc. * * This file is part of the GNU LessTif Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * * * Feb 21 1999 - George Lebl (jirka@5z.com) * Owen Taylor (otaylor@redhat.com) * * Modified so that the MotifWmHints structure defined here * is suitable for client side use on 64-bit architectures. * X expects fields with a format of 32 to be longs, even * when sizeof(long) == 8. **/ #ifndef MWMUTIL_H_INCLUDED #define MWMUTIL_H_INCLUDED #include //G_BEGIN_DECLS typedef struct { unsigned long flags; unsigned long functions; unsigned long decorations; long input_mode; unsigned long status; } MotifWmHints, MwmHints; #define MWM_HINTS_FUNCTIONS (1L << 0) #define MWM_HINTS_DECORATIONS (1L << 1) #define MWM_HINTS_INPUT_MODE (1L << 2) #define MWM_HINTS_STATUS (1L << 3) #define MWM_FUNC_ALL (1L << 0) #define MWM_FUNC_RESIZE (1L << 1) #define MWM_FUNC_MOVE (1L << 2) #define MWM_FUNC_MINIMIZE (1L << 3) #define MWM_FUNC_MAXIMIZE (1L << 4) #define MWM_FUNC_CLOSE (1L << 5) #define MWM_DECOR_ALL (1L << 0) #define MWM_DECOR_BORDER (1L << 1) #define MWM_DECOR_RESIZEH (1L << 2) #define MWM_DECOR_TITLE (1L << 3) #define MWM_DECOR_MENU (1L << 4) #define MWM_DECOR_MINIMIZE (1L << 5) #define MWM_DECOR_MAXIMIZE (1L << 6) #define MWM_INPUT_MODELESS 0 #define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 #define MWM_INPUT_SYSTEM_MODAL 2 #define MWM_INPUT_FULL_APPLICATION_MODAL 3 #define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL #define MWM_TEAROFF_WINDOW (1L<<0) /* * atoms */ #define _XA_MOTIF_BINDINGS "_MOTIF_BINDINGS" #define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" #define _XA_MOTIF_WM_MESSAGES "_MOTIF_WM_MESSAGES" #define _XA_MOTIF_WM_OFFSET "_MOTIF_WM_OFFSET" #define _XA_MOTIF_WM_MENU "_MOTIF_WM_MENU" #define _XA_MOTIF_WM_INFO "_MOTIF_WM_INFO" #define _XA_MWM_HINTS _XA_MOTIF_WM_HINTS #define _XA_MWM_MESSAGES _XA_MOTIF_WM_MESSAGES #define _XA_MWM_MENU _XA_MOTIF_WM_MENU #define _XA_MWM_INFO _XA_MOTIF_WM_INFO /* * _MWM_INFO property */ typedef struct { long flags; Window wm_window; } MotifWmInfo; typedef MotifWmInfo MwmInfo; #define MWM_INFO_STARTUP_STANDARD (1L<<0) #define MWM_INFO_STARTUP_CUSTOM (1L<<1) /* * _MWM_HINTS property */ typedef struct { unsigned long flags; unsigned long functions; unsigned long decorations; long inputMode; unsigned long status; } PropMotifWmHints; typedef PropMotifWmHints PropMwmHints; #define PROP_MOTIF_WM_HINTS_ELEMENTS 5 #define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS /* * _MWM_INFO property, slight return */ typedef struct { unsigned long flags; unsigned long wmWindow; } PropMotifWmInfo; typedef PropMotifWmInfo PropMwmInfo; #define PROP_MOTIF_WM_INFO_ELEMENTS 2 #define PROP_MWM_INFO_ELEMENTS PROP_MOTIF_WM_INFO_ELEMENTS //G_END_DECLS #endif /* MWMUTIL_H_INCLUDED */ cairo-dock-plugins-3.3.2/Global-Menu/src/applet-notifications.c000775 001750 001750 00000023171 12223247501 025545 0ustar00mbaertsmbaerts000000 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 "gdk/gdkx.h" #include "applet-struct.h" #include "applet-draw.h" #include "applet-app.h" #include "applet-notifications.h" #define FORCE_REMOVE_DOUBLE_SEPARATORS #ifdef FORCE_REMOVE_DOUBLE_SEPARATORS /// REMOVE ME WHEN IT'S POSSIBLE! :) static void _remove_double_separators (GtkWidget *pWidget) { if (pWidget == NULL) return; gboolean bPrevIsSeparator = TRUE; // to remove the first entry if it's a separator GList *pChildren = gtk_container_get_children (GTK_CONTAINER (pWidget)); GList *ic; GtkWidget *pCurrentWidget; GtkWidget *pSubMenu; for (ic = pChildren; ic != NULL; ic = ic->next) { pCurrentWidget = ic->data; if (GTK_IS_SEPARATOR_MENU_ITEM (pCurrentWidget)) { if (bPrevIsSeparator) gtk_widget_destroy (pCurrentWidget); // or ? gtk_container_remove (pContainer, pCurrentWidget); bPrevIsSeparator = TRUE; } else if (GTK_IS_MENU_ITEM (pCurrentWidget)) { pSubMenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (pCurrentWidget)); if (pSubMenu != NULL) { bPrevIsSeparator = TRUE; _remove_double_separators (pSubMenu); } else bPrevIsSeparator = FALSE; } else bPrevIsSeparator = FALSE; } g_list_free (pChildren); } #endif static void _show_menu (gboolean bOnMouse) { if (! myConfig.bDisplayMenu) return; if (myData.pMenu != NULL) { #ifdef FORCE_REMOVE_DOUBLE_SEPARATORS _remove_double_separators (GTK_WIDGET (myData.pMenu)); #endif if (bOnMouse) { gtk_widget_show_all (GTK_WIDGET (myData.pMenu)); gtk_menu_popup (GTK_MENU (myData.pMenu), NULL, NULL, (GtkMenuPositionFunc) NULL, NULL, 0, gtk_get_current_event_time ()); } else { CD_APPLET_POPUP_MENU_ON_MY_ICON (GTK_WIDGET (myData.pMenu)); } } else /// either show a message, or remember the user demand, so that we pop the menu as soon as we get it... { gldi_dialog_show_temporary_with_icon (D_("The application didn't send its menu to us."), myIcon, myContainer, 4000., "same icon"); } } //\___________ Action on click: show the menu CD_APPLET_ON_CLICK_BEGIN if (myData.pCurrentWindow == NULL) return GLDI_NOTIFICATION_LET_PASS; if (myConfig.bDisplayControls) { int iNumButton = cd_app_menu_find_button (myApplet); if (iNumButton >= 0) { switch (iNumButton) { case CD_BUTTON_MENU: _show_menu (FALSE); break; case CD_BUTTON_MINIMIZE: if (myData.bCanMinimize) gldi_window_minimize (myData.pCurrentWindow); break; case CD_BUTTON_MAXIMIZE: if (myData.bCanMaximize) { gldi_window_maximize (myData.pCurrentWindow, ! myData.pCurrentWindow->bIsMaximized); } break; case CD_BUTTON_CLOSE: if (myData.bCanClose) gldi_window_close (myData.pCurrentWindow); break; } } } else if (myConfig.bDisplayMenu) _show_menu (FALSE); CD_APPLET_ON_CLICK_END //\___________ Other actions are defined to mime the usual actions available on windows top border CD_APPLET_ON_MIDDLE_CLICK_BEGIN // set the window behind all the others. GldiWindowActor *actor = gldi_windows_get_active(); if (actor) gldi_window_lower (actor); CD_APPLET_ON_MIDDLE_CLICK_END CD_APPLET_ON_SCROLL_BEGIN // minimize the window (we could also use the scroll to (un)shade the window, but I'm afraid that a maximized shaded window would be too much hidden, users could be confused). GldiWindowActor *actor = gldi_windows_get_active(); if (actor && CD_APPLET_SCROLL_DOWN) gldi_window_minimize (actor); CD_APPLET_ON_SCROLL_END CD_APPLET_ON_DOUBLE_CLICK_BEGIN // maximize/restaure the window. if (myData.pCurrentWindow != 0) { gldi_window_maximize (myData.pCurrentWindow, ! myData.pCurrentWindow->bIsMaximized); } CD_APPLET_ON_DOUBLE_CLICK_END /* CD_APPLET_ON_BUILD_MENU_BEGIN // nothing to do here, since the icon is considered as an appli, the dock will fill it for free ! CD_APPLET_ON_BUILD_MENU_END */ void cd_app_menu_on_keybinding_pull (const gchar *keystring, GldiModuleInstance *myApplet) { CD_APPLET_ENTER; _show_menu (myConfig.bMenuOnMouse); CD_APPLET_LEAVE(); } //\___________ Other notifications, that are not from the user (but from the Applications-manager) static void _check_dock_is_active (gchar *cDockName, CairoDock *pDock, gboolean *data) { if (gldi_container_is_active (CAIRO_CONTAINER (pDock))) *data = 1; } gboolean cd_app_menu_on_active_window_changed (GldiModuleInstance *myApplet, GldiWindowActor *actor) { // check if a dock has the focus (we don't want to control the dock, it wouldn't make sense anyway). if (actor) { gboolean is_dock = FALSE; gldi_docks_foreach ((GHFunc) _check_dock_is_active, &is_dock); if (is_dock) // it's a dock, ignore it. actor = NULL; } // take this new window (possibly NULL). cd_app_menu_set_current_window (actor); return GLDI_NOTIFICATION_LET_PASS; } gboolean cd_app_menu_on_state_changed (GldiModuleInstance *myApplet, GldiWindowActor *actor, gboolean bHiddenChanged, gboolean bMaximizedChanged, gboolean bFullScreenChanged) { if (actor == myData.pCurrentWindow) { if (bMaximizedChanged) { gldi_window_set_border (actor, ! actor->bIsMaximized); cd_app_menu_redraw_buttons (); } } return GLDI_NOTIFICATION_LET_PASS; } gboolean cd_app_menu_on_name_changed (GldiModuleInstance *myApplet, GldiWindowActor *actor) { if (actor == myData.pCurrentWindow) { CD_APPLET_SET_NAME_FOR_MY_ICON (actor->cName); } return GLDI_NOTIFICATION_LET_PASS; } gboolean cd_app_menu_on_new_appli (GldiModuleInstance *myApplet, GldiWindowActor *actor) { if (actor->bIsMaximized) { gldi_window_set_border (actor, ! actor->bIsMaximized); } return GLDI_NOTIFICATION_LET_PASS; } //\___________ Other notifications, for animation of the buttons. gboolean on_mouse_moved (GldiModuleInstance *myApplet, GldiContainer *pContainer, gboolean *bStartAnimation) { CD_APPLET_ENTER; if (! myIcon->bPointed || ! pContainer->bInside) CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS); // find the pointed button int iNumButton = cd_app_menu_find_button (myApplet); if (iNumButton >= 0 && iNumButton < myData.iNbButtons) { // trigger animation *bStartAnimation = TRUE; } CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS); } static gboolean _update_button_image_no_loop (CairoDockImageBuffer *pImage, int *iStep) { gboolean bButtonAnimating = FALSE; if (cairo_dock_image_buffer_is_animated (pImage)) { if (pImage->iCurrentFrame != 0) // in the loop { gboolean bLastFrame = cairo_dock_image_buffer_next_frame_no_loop (pImage); if (bLastFrame) pImage->iCurrentFrame = 0; else bButtonAnimating = TRUE; } } else // update the step { if (*iStep != 0) // in the loop { ++ *iStep; if (*iStep >= CD_ANIM_STEPS) *iStep = 0; else bButtonAnimating = TRUE; } } return bButtonAnimating; } static void _update_button_image_loop (CairoDockImageBuffer *pImage, int *iStep) { if (cairo_dock_image_buffer_is_animated (pImage)) { cairo_dock_image_buffer_next_frame (pImage); } else // update the step { ++ *iStep; if (*iStep >= CD_ANIM_STEPS) *iStep = 0; } } static gboolean _update_button_image (CairoDockImageBuffer *pImage, int *iStep, gboolean bLoop) { if (bLoop) { _update_button_image_loop (pImage, iStep); return TRUE; } else { return _update_button_image_no_loop (pImage, iStep); } } gboolean cd_app_menu_on_update_container (GldiModuleInstance *myApplet, GldiContainer *pContainer, gboolean *bContinueAnimation) { CD_APPLET_ENTER; if (! myIcon->bPointed || ! pContainer->bInside) // our icon is not pointed, only update it to finish the current button animations. { if (myData.bButtonAnimating) // one or more button is animating. { myData.bButtonAnimating = FALSE; myData.bButtonAnimating |= _update_button_image_no_loop (&myData.minimizeButton, &myData.iAnimIterMin); myData.bButtonAnimating |= _update_button_image_no_loop (&myData.maximizeButton, &myData.iAnimIterMax); myData.bButtonAnimating |= _update_button_image_no_loop (&myData.restoreButton, &myData.iAnimIterRestore); myData.bButtonAnimating |= _update_button_image_no_loop (&myData.closeButton, &myData.iAnimIterClose); cd_app_menu_redraw_buttons (); } } else // our button is currently pointed. { myData.bButtonAnimating = FALSE; int iNumButton = cd_app_menu_find_button (myApplet); myData.bButtonAnimating |= _update_button_image (&myData.minimizeButton, &myData.iAnimIterMin, iNumButton == CD_BUTTON_MINIMIZE); myData.bButtonAnimating |= _update_button_image (&myData.maximizeButton, &myData.iAnimIterMax, iNumButton == CD_BUTTON_MAXIMIZE); myData.bButtonAnimating |= _update_button_image (&myData.restoreButton, &myData.iAnimIterRestore, iNumButton == CD_BUTTON_MAXIMIZE); myData.bButtonAnimating |= _update_button_image (&myData.closeButton, &myData.iAnimIterClose, iNumButton == CD_BUTTON_CLOSE); cd_app_menu_redraw_buttons (); } if (myData.bButtonAnimating) *bContinueAnimation = TRUE; CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS); } cairo-dock-plugins-3.3.2/Global-Menu/src/applet-config.c000775 001750 001750 00000005555 12223247501 024147 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-config.h" //\_________________ Here you have to get all your parameters from the conf file. Use the macros CD_CONFIG_GET_BOOLEAN, CD_CONFIG_GET_INTEGER, CD_CONFIG_GET_STRING, etc. myConfig has been reseted to 0 at this point. This function is called at the beginning of init and reload. CD_APPLET_GET_CONFIG_BEGIN guint iSteal = CD_CONFIG_GET_INTEGER ("Configuration", "steal"); myConfig.bDisplayMenu = (iSteal == 0 || iSteal == 2); myConfig.bDisplayControls = (iSteal == 1 || iSteal == 2); myConfig.cShortkey = CD_CONFIG_GET_STRING ("Configuration", "shortkey"); myConfig.bMenuOnMouse = CD_CONFIG_GET_BOOLEAN ("Configuration", "menu on mouse"); myConfig.bCompactMode = CD_CONFIG_GET_BOOLEAN ("Configuration", "compact"); myConfig.iButtonsOrder = CD_CONFIG_GET_INTEGER ("Configuration", "buttons order"); // (auto / right / left) myConfig.iTransitionDuration = 500; myConfig.cMinimizeImage = CD_CONFIG_GET_FILE_PATH ("Configuration", "min button", "button-min.svg"); myConfig.cMaximizeImage = CD_CONFIG_GET_FILE_PATH ("Configuration", "max button", "button-max.svg"); myConfig.cRestoreImage = CD_CONFIG_GET_FILE_PATH ("Configuration", "restore button", "button-restore.svg"); myConfig.cCloseImage = CD_CONFIG_GET_FILE_PATH ("Configuration", "close button", "button-close.svg"); CD_APPLET_GET_CONFIG_END //\_________________ Here you have to free all ressources allocated for myConfig. This one will be reseted to 0 at the end of this function. This function is called right before you get the applet's config, and when your applet is stopped, in the end. CD_APPLET_RESET_CONFIG_BEGIN g_free (myConfig.cShortkey); g_free (myConfig.cMinimizeImage); g_free (myConfig.cMaximizeImage); g_free (myConfig.cRestoreImage); g_free (myConfig.cCloseImage); CD_APPLET_RESET_CONFIG_END //\_________________ Here you have to free all ressources allocated for myData. This one will be reseted to 0 at the end of this function. This function is called when your applet is stopped, in the very end. CD_APPLET_RESET_DATA_BEGIN CD_APPLET_RESET_DATA_END cairo-dock-plugins-3.3.2/Global-Menu/src/applet-config.h000775 001750 001750 00000001565 12223247501 024151 0ustar00mbaertsmbaerts000000 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 __APPLET_CONFIG__ #define __APPLET_CONFIG__ #include CD_APPLET_CONFIG_H #endif cairo-dock-plugins-3.3.2/Global-Menu/CMakeLists.txt000664 001750 001750 00000000170 12223247501 023205 0ustar00mbaertsmbaerts000000 000000 add_subdirectory(src) add_subdirectory(data) if (PYTHON2_FOUND OR PYTHON3_FOUND) add_subdirectory(registrar) endif() cairo-dock-plugins-3.3.2/Global-Menu/data/Global-Menu.conf.in000664 001750 001750 00000006117 12223247501 024743 0ustar00mbaertsmbaerts000000 000000 #@VERSION_GLOBAL_MENU@ #[gtk-about] [Icon] #F[Icon] frame_maininfo= #d Name of the dock it belongs to: dock name = name = #v sep_display= icon = #j[0;128] Desired icon size for this applet #{Set to 0 to use the default applet size} icon size = 0;0 order= #A handbook=Global Menu #[gtk-convert] [Desklet] #X[Position] frame_pos = #b Lock position? #{If locked, the desklet cannot be moved by simply dragging it with the left mouse button. It can still be moved with ALT + left-click.} locked = false #j+[24;512] Desklet dimensions (width x height): #{Depending on your WindowManager, you may be able to resize this with ALT + middle-click or ALT + left-click.} size = 96;96 #i[-2048;2048] Desklet position (x, y): #{Depending on your WindowManager, you may be able to move this with ALT + left-click.. Negative values are counted from the right/bottom of the screen} x position=0 #i[-2048;2048] ... y position=0 #I[-180;180] Rotation: #{You can quickly rotate the desklet with the mouse, by dragging the little buttons on its left and top sides.} rotation = 0 #X[Visibility] frame_visi = #b Is detached from the dock initially detached=false #l[Normal;Keep above;Keep below;Keep on widget layer;Reserve space] Visibility: accessibility=0 #b Should be visible on all desktops? sticky=true #F[Decorations;gtk-orientation-portrait] frame_deco= #o+ Choose a decoration theme for this desklet: #{Choose 'Custom decorations' to define your own decorations below.} decorations = default #v sep_deco = #g+ Background image: #{Image to be displayed below drawings, e.g. a frame. Leave empty for no image.} bg desklet = #e+[0;1] Background transparency: bg alpha = 1 #i+[0;256] Left offset: #{in pixels. Use this to adjust the left position of drawings.} left offset = 0 #i+[0;256] Top offset: #{in pixels. Use this to adjust the top position of drawings.} top offset = 0 #i+[0;256] Right offset: #{in pixels. Use this to adjust the right position of drawings.} right offset = 0 #i+[0;256] Bottom offset: #{in pixels. Use this to adjust the bottom position of drawings.} bottom offset = 0 #g+ Foreground image: #{Image to be displayed above the drawings, e.g. a reflection. Leave empty for no image.} fg desklet = #e+[0;1] Foreground tansparency: fg alpha = 1 #[gtk-preferences] [Configuration] #Y[Steal window menu;1;2;Steal window decoration;3;2;Steal window menu and border;1;4] Behaviour #{The applet can steal the top border of maximized windows, in which case it will display the window control buttons. # The applet can steal the menu from the windows, in which case it will display a button to pop up the menu of the current window.} steal = 2 #k Shortkey to pop up the menu shortkey = F1 #b Pop up the menu at mouse position menu on mouse = false #b Compact mode compact = false #l+[Auto;Close button at the end;Close button at first] Order of the buttons: buttons order = 0 #g+[Default] Image for the 'minimize' button min button = #g+[Default] Image for the 'maximize' button max button = #g+[Default] Image for the 'restore' button restore button = #g+[Default] Image for the 'close' button close button = cairo-dock-plugins-3.3.2/Global-Menu/data/button-close.svg000664 001750 001750 00000116724 12223247501 024532 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/Global-Menu/data/preview.jpg000664 001750 001750 00000020652 12223247501 023550 0ustar00mbaertsmbaerts000000 000000 JFIFExifII*  H H( 1n2| igthumb 2.13.12011:12:19 17:30:4902210100    H H( ,ZJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?//Qֱ6Ok [5ӲPʸUr÷w_ξ.Trث3ހ>juw?/j=/tA!˓uw?/jG-W+N]^!59f[uVve YrTm?\6Z64]K")\ Y%7|]]H_PY9}(_I-?7?ƐɎLRZ~zQ _?ƏHlɆ_ox`+@Vk)GGku^/#oRլ$X6a'#}+Yk ۀ9 KK{L҉6@#P]k:}@3x>M[P\GUj定2T.ЙI4O­6f+zӁnB#ckV] eУ<>fO9.g wrN 1y6VYF#wZhir3LѼ>=̓-K61}hJRHtt˻C9qI\o?sЅhu^/#?@A#ex>*&# ;Vsr6shN-Vi8!wcNR˞(OWܛqghLg ɪ_XPJn}iD~G6_Ite9=wg>f>M6|6Øy,24r^@KAdIH]sw{v$rJִogmZrJxq?~^j1@f$Vk7^-BlՕZ'YcVU?lёןנ| _FG@Z'Lu!8ϭK!?L:Ij4,g6h-ݎ=_<4Ԟ蝵r]k9Iu^/#I}?/y%@x5³#{Ws)ҹ~PՊāy#VqVLN-ݣ+AVzo5 ZΎ"VfPxfvw~Z+`HzoS;k³#{UL-HW.c5~;$Llwe+=?7kkWv &A ' XjwrB79{zC OG+=?7v٣4{zCxkEþ"yeWM9.}+cZmp1xuџqUY:?pOY6ۻ-$_jZwwpgQ,s'zU>vgh@gz?d{l Gd38뀫Zvw{c1"v#2 `IξSw.[!};?@T_Qѽ}G_+?nx}]}pxs@LxjF-ᤑy;)Ҽ|OMk޹"FTd=3rxm~*7iC#VC b>(iX.fEBuٻqҼz:\zP8#'5#P|*0VŜn+C  !"$"$C"H !1aAQU"6Tqt&2BR#$3SVbcer'!1RQ"#aq ?)j 1\1z8`&`v"c_VV,j.vnT@YqG71ٖԺU#v;N;3 ^׉e](Gq/MxH==& UEJ[IVZH]_GqGغ\+?բ\2#)d&V~R;*ϊ٘q]M .=r8#W9*CSfB 5h˿5ـ-B5Rn{SYI M^xr8֣q%O iGVA#UYӥ_CBCvlnPGD*yNY>#4e#KO"u qp(q,e ~xEP?Mem+$4큾'd3~eIQTxMtopo7cHIeA J͛t~8"E7MV1(R$N32E#Vwdn')rq%&閙I~4rnef ?×)O$S}:J>oGt,oͧ$S}H#p {S?ɛ'mL!?T8y"J')2w/ϊovQC^XL̰ۨBfKvpnOLPBѦ"QXLͱ5.B kmbЦ&³8sNT&g:ϸ6B2ٴ^y//.3KKb{hQ.)Fu-9waSX=G<,ZoW6}x`$jf0 (*mLMD͙Ixv vL`)bDx]UV(J2q/=[kSTUBdlrkl\)(=:gVAj(ZjJS~qxۥ&ʸ$lx=]NDÈNu$%BUpsVNgVeHt7rnkO=4̗Z-h7z S+Tʔ3iy HIvۜp/ԧQ8ٹIo.] 7xB{܏#=G7=Z=`vjlV1=Ü&iթOqp X@^Oq-O-C2R$Boc%|""beKSeWM?-_̾%ndI#n"br*à6V&Sia%m~mnI*fڥC@Qp)~{ԏ& wEaɄ['-}ocJ{܎`qV2rE[M:o1گYbg^]61kjrcuD$AQjsJ< #0K$BU^"2ږv1ݤ)T֙2K]”z8~/|.k^=qyWHom\UTaZe#M:o*PBh`}˒cO=7Qat¶'l@6Bl9x]z+Ҍ cR."nbㅷYJ/97Pm$e/Fliɚ,@Td4\kJRU(N㸂kXw Mi=)ȚSoQ8VeJ@شh:4:*=.["qDzA HqJ P YChSj]g 7Wu$e{3ACh7m7`?cairo-dock-plugins-3.3.2/Global-Menu/data/button-restore.svg000664 001750 001750 00000107417 12223247501 025107 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/Global-Menu/data/CMakeLists.txt000664 001750 001750 00000000352 12223247501 024120 0ustar00mbaertsmbaerts000000 000000 ########### install files ############### install (FILES ${CMAKE_CURRENT_BINARY_DIR}/Global-Menu.conf preview.jpg icon.svg button-min.svg button-max.svg button-restore.svg button-close.svg DESTINATION ${global_menudatadir}) cairo-dock-plugins-3.3.2/Global-Menu/data/icon.svg000664 001750 001750 00000037665 12223247501 023052 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/Global-Menu/data/button-min.svg000664 001750 001750 00000026535 12223247501 024210 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/Global-Menu/data/button-max.svg000664 001750 001750 00000067754 12223247501 024222 0ustar00mbaertsmbaerts000000 000000 image/svg+xml cairo-dock-plugins-3.3.2/Global-Menu/registrar/CMakeLists.txt000664 001750 001750 00000000351 12223247501 025210 0ustar00mbaertsmbaerts000000 000000 ########### install files ############### install(FILES appmenu-registrar.py DESTINATION ${pluginsdir} RENAME appmenu-registrar PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) cairo-dock-plugins-3.3.2/Global-Menu/registrar/appmenu-registrar.py000775 001750 001750 00000007031 12223247501 026474 0ustar00mbaertsmbaerts000000 000000 #!/usr/bin/env python # # This is a part of the Cairo-Dock plug-ins. # Copyright : (C) 2011 by Fabrice Rey # E-mail : fabounet@glx-dock.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. # http://www.gnu.org/licenses/licenses.html#GPL # # Developped as a part of Cairo-Dock, but usable as a stand-alone systray daemon. # The code follows the same logic as the KDE watcher, to ensure a complete compatibility. from __future__ import print_function import sys try: import glib import gobject g_bMainLoopInGObject = True except: from gi.repository import GLib as glib from gi.repository import GObject as gobject g_bMainLoopInGObject = False import dbus, dbus.service from dbus.mainloop.glib import DBusGMainLoop class Registrar(dbus.service.Object): bus_name_str = 'com.canonical.AppMenu.Registrar' bus_obj_str = '/com/canonical/AppMenu/Registrar' bus_iface_str = 'com.canonical.AppMenu.Registrar' windows = {} # table of couple (X id, menu object path) def __init__(self): DBusGMainLoop(set_as_default=True) try: self.bus = dbus.SessionBus() bus_name = dbus.service.BusName (self.bus_name_str, self.bus) print("registered a registrar:",bus_name) dbus.service.Object.__init__(self, bus_name, self.bus_obj_str) except dbus.DBusException: print('Could not open dbus. Uncaught exception.') return bus_object = self.bus.get_object(dbus.BUS_DAEMON_NAME, dbus.BUS_DAEMON_PATH) self.main = dbus.Interface(bus_object, dbus.BUS_DAEMON_IFACE) #self.main.connect_to_signal("NameOwnerChanged", self.on_name_owner_changed) if g_bMainLoopInGObject: self.loop = gobject.MainLoop() else: self.loop = glib.MainLoop() self.loop.run() ### methods ### @dbus.service.method(dbus_interface = bus_iface_str, in_signature = 'uo', out_signature = None, sender_keyword='sender') def RegisterWindow(self, Xid, menu, sender=None): self.windows[Xid] = (sender, menu) self.WindowRegistered (Xid, sender, menu) @dbus.service.method(dbus_interface = bus_iface_str, in_signature = 'u', out_signature = None) def UnregisterWindow(self, Xid): del self.windows[Xid] self.WindowUnregistered (Xid) @dbus.service.method(dbus_interface = bus_iface_str, in_signature = 'u', out_signature = 'so') def GetMenuForWindow(self, Xid): print("GetMenuForWindow(%d)..." % Xid) try: service,menu = self.windows[Xid] return service,menu # dbus.ObjectPath(menu) except: return "","/" # return an empty string to avoid ugly warnings; clients should be able to deal with it. @dbus.service.method(dbus_interface = bus_iface_str, in_signature = None, out_signature = 'a(uso)') def GetMenus(self): menus=[] for xid in self.windows: service,menu = self.windows[xid] menus.append((xid, service, menu)) ### Signals ### @dbus.service.signal(dbus_interface=bus_name_str, signature='uso') def WindowRegistered(self, Xid, service, menu): print("%d registered" % (Xid)) sys.stdout.flush() @dbus.service.signal(dbus_interface=bus_name_str, signature='u') def WindowUnregistered(self, Xid): print("%d unregistered" % (Xid)) sys.stdout.flush() if __name__ == '__main__': Registrar() cairo-dock-plugins-3.3.2/Folders/src/applet-struct.h000775 001750 001750 00000003065 12223247501 023521 0ustar00mbaertsmbaerts000000 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 __CD_APPLET_STRUCT__ #define __CD_APPLET_STRUCT__ #include //\___________ structure containing the applet's configuration parameters. struct _AppletConfig { gchar *cImageFile; gchar *cDefaultTitle; gchar *cDirPath; gboolean bShowFiles; CairoDockFMSortType iSortType; gboolean bFoldersFirst; gboolean bShowHiddenFiles; gint iSubdockViewType; gchar *cRenderer; } ; typedef struct { gchar *cDirPath; gboolean bShowFiles; CairoDockFMSortType iSortType; gboolean bFoldersFirst; gboolean bShowHiddenFiles; GList *pIconList; GldiModuleInstance *pApplet; } CDSharedMemory; //\___________ structure containing the applet's data, like surfaces, dialogs, results of calculus, etc. struct _AppletData { CairoDockTask *pTask; GCompareFunc comp; GList *pAppList; } ; #endif cairo-dock-plugins-3.3.2/Folders/src/applet-load-icons.h000775 001750 001750 00000002074 12223247501 024224 0ustar00mbaertsmbaerts000000 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 __APPLET_LOAD_ICONS__ #define __APPLET_LOAD_ICONS__ #include void cd_folders_start (GldiModuleInstance *myApplet); void cd_folders_free_all_data (GldiModuleInstance *myApplet); void cd_folders_sort_icons (GldiModuleInstance *myApplet, CairoDockFMSortType iSortType); #endif cairo-dock-plugins-3.3.2/Folders/src/applet-init.h000775 001750 001750 00000001553 12223247501 023140 0ustar00mbaertsmbaerts000000 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 __APPLET_INIT__ #define __APPLET_INIT__ #include CD_APPLET_H #endif cairo-dock-plugins-3.3.2/Folders/src/applet-notifications.h000775 001750 001750 00000002206 12223247501 025042 0ustar00mbaertsmbaerts000000 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 __APPLET_NOTIFICATIONS__ #define __APPLET_NOTIFICATIONS__ #include CD_APPLET_ON_CLICK_H CD_APPLET_ON_MIDDLE_CLICK_H CD_APPLET_ON_BUILD_MENU_H gboolean cd_folders_on_drop_data (gpointer data, const gchar *cReceivedData, Icon *icon, double fOrder, GldiContainer *pContainer); void cd_folders_free_apps_list (GldiModuleInstance *myApplet); #endif cairo-dock-plugins-3.3.2/Folders/src/CMakeLists.txt000664 001750 001750 00000002305 12223247501 023272 0ustar00mbaertsmbaerts000000 000000 ########### sources ############### SET(MODULE_SRCS applet-struct.h applet-init.c applet-init.h applet-config.c applet-config.h applet-load-icons.c applet-load-icons.h applet-notifications.c applet-notifications.h ) add_library(${PACKAGE_FOLDERS} SHARED ${MODULE_SRCS}) ########### compil ############### add_definitions (-DMY_APPLET_SHARE_DATA_DIR="${foldersdatadir}") add_definitions (-DMY_APPLET_PREVIEW_FILE="preview.jpg") add_definitions (-DMY_APPLET_CONF_FILE="Folders.conf") add_definitions (-DMY_APPLET_USER_DATA_DIR="Folders") add_definitions (-DMY_APPLET_VERSION="${VERSION_FOLDERS}") add_definitions (-DMY_APPLET_GETTEXT_DOMAIN="${GETTEXT_FOLDERS}") add_definitions (-DMY_APPLET_DOCK_VERSION="${dock_version}") add_definitions (-DMY_APPLET_ICON_FILE="icon.png") add_definitions (-DCD_APPLET_MULTI_INSTANCE="1") ### uncomment the following line to allow extended OpenGL drawing. #add_definitions (-DGL_GLEXT_PROTOTYPES="1") include_directories ( ${PACKAGE_INCLUDE_DIRS}) link_directories ( ${PACKAGE_LIBRARY_DIRS}) target_link_libraries (${PACKAGE_FOLDERS} ${PACKAGE_LIBRARIES}) ########### install files ############### install(TARGETS ${PACKAGE_FOLDERS} DESTINATION ${pluginsdir}) cairo-dock-plugins-3.3.2/Folders/src/applet-init.c000775 001750 001750 00000015151 12223247501 023132 0ustar00mbaertsmbaerts000000 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 "stdlib.h" #include "applet-config.h" #include "applet-notifications.h" #include "applet-load-icons.h" #include "applet-struct.h" #include "applet-init.h" CD_APPLET_DEFINE_BEGIN (N_("Folders"), 2, 2, 0, CAIRO_DOCK_CATEGORY_APPLET_FILES, N_("This applet imports folders inside the Dock\n" "You can have as many instances of this applet as you want, each one with a different folder.\n" "To add a folder in your dock:\n" " - activate the applet, open its configuration panel, and select a folder\n" " - or just drop a folder into the dock\n" "Middle-click on the main icon opens the folder.\n"), "Fabounet") CD_APPLET_DEFINE_COMMON_APPLET_INTERFACE CD_APPLET_ALLOW_EMPTY_TITLE gldi_object_register_notification (&myDockObjectMgr, NOTIFICATION_DROP_DATA, (GldiNotificationFunc) cd_folders_on_drop_data, GLDI_RUN_FIRST, NULL); CD_APPLET_DEFINE_END static inline void _set_comparaison_func (GldiModuleInstance *myApplet) { switch (myConfig.iSortType) { case 0: // name default: myData.comp = (GCompareFunc) cairo_dock_compare_icons_name; break; case 1: // date case 2: // size myData.comp = NULL; break; case 3: // type myData.comp = (GCompareFunc) cairo_dock_compare_icons_extension; break; } } static inline void _set_icon_label (GldiModuleInstance *myApplet) { if (myDock && myConfig.cDefaultTitle == NULL && myConfig.cDirPath != NULL) { gchar *cPath = g_filename_from_uri (myConfig.cDirPath, NULL, NULL); if (cPath) { gchar *str = strrchr (cPath, '/'); if (str) CD_APPLET_SET_NAME_FOR_MY_ICON (str+1); g_free (cPath); } } } //\___________ Here is where you initiate your applet. myConfig is already set at this point, and also myIcon, myContainer, myDock, myDesklet (and myDrawContext if you're in dock mode). The macro CD_APPLET_MY_CONF_FILE and CD_APPLET_MY_KEY_FILE can give you access to the applet's conf-file and its corresponding key-file (also available during reload). If you're in desklet mode, myDrawContext is still NULL, and myIcon's buffers has not been filled, because you may not need them then (idem when reloading). CD_APPLET_INIT_BEGIN if (myConfig.cDirPath == NULL) { CD_APPLET_SET_IMAGE_ON_MY_ICON (myConfig.cImageFile); gldi_dialog_show_temporary_with_icon (D_("Open the configuration of the applet to choose a folder to import."), myIcon, myContainer, 8000., myConfig.iSubdockViewType == 0 ? "same icon" : MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE); } else { //\_______________ On lance la tache recuperation des fichiers. _set_comparaison_func (myApplet); if (myConfig.bShowFiles) { cd_folders_start (myApplet); } //\_______________ set the icon rendering if (myDock) // dock mode: set the image or the sub-dock renderer { cairo_dock_set_subdock_content_renderer (myIcon, myConfig.iSubdockViewType); if (myConfig.iSubdockViewType == 0) CD_APPLET_SET_IMAGE_ON_MY_ICON (myConfig.cImageFile); } else // desklet mode: set the image if we don't show the files. { if (! myConfig.bShowFiles) { CD_APPLET_SET_DESKLET_RENDERER ("Simple"); CD_APPLET_SET_IMAGE_ON_MY_ICON (myConfig.cImageFile); } } //\_______________ set the label _set_icon_label (myApplet); } //\_______________ On enregistre nos notifications. CD_APPLET_REGISTER_FOR_CLICK_EVENT; CD_APPLET_REGISTER_FOR_MIDDLE_CLICK_EVENT; CD_APPLET_REGISTER_FOR_BUILD_MENU_EVENT; CD_APPLET_INIT_END //\___________ Here is where you stop your applet. myConfig and myData are still valid, but will be reseted to 0 at the end of the function. In the end, your applet will go back to its original state, as if it had never been activated. CD_APPLET_STOP_BEGIN CD_APPLET_UNREGISTER_FOR_MIDDLE_CLICK_EVENT; CD_APPLET_UNREGISTER_FOR_BUILD_MENU_EVENT; gldi_object_remove_notification (&myContainerObjectMgr, NOTIFICATION_CLICK_ICON, (GldiNotificationFunc) CD_APPLET_ON_CLICK_FUNC, myApplet); CD_APPLET_STOP_END //\___________ The reload occurs in 2 occasions : when the user changes the applet's config, and when the user reload the cairo-dock's config or modify the desklet's size. The macro CD_APPLET_MY_CONFIG_CHANGED can tell you this. myConfig has already been reloaded at this point if you're in the first case, myData is untouched. You also have the macro CD_APPLET_MY_CONTAINER_TYPE_CHANGED that can tell you if you switched from dock/desklet to desklet/dock mode. CD_APPLET_RELOAD_BEGIN if (CD_APPLET_MY_CONFIG_CHANGED) { //\_______________ On detruit les icones des fichiers. cd_folders_free_all_data (myApplet); if (myConfig.cDirPath == NULL) { CD_APPLET_SET_IMAGE_ON_MY_ICON (myConfig.cImageFile); gldi_dialog_show_temporary_with_icon (D_("Open the configuration of the applet to choose a folder to import."), myIcon, myContainer, 8000., myConfig.iSubdockViewType == 0 ? "same icon" : MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE); } else { //\_______________ On charge les icones dans un sous-dock. _set_comparaison_func (myApplet); if (myConfig.bShowFiles) { cd_folders_start (myApplet); } else if (myDock && myIcon->pSubDock) // dans ce cas on veut un comportement de type lanceur, donc on ne veut pas d'un sous-dock vide. { gldi_object_unref (GLDI_OBJECT(myIcon->pSubDock)); myIcon->pSubDock = NULL; } //\_______________ set the icon rendering if (myDock) // dock mode: set the image or the sub-dock renderer { cairo_dock_set_subdock_content_renderer (myIcon, myConfig.iSubdockViewType); if (myConfig.iSubdockViewType == 0) CD_APPLET_SET_IMAGE_ON_MY_ICON (myConfig.cImageFile); } else // desklet mode: set the image if we don't show the files. { if (! myConfig.bShowFiles) { CD_APPLET_SET_DESKLET_RENDERER ("Simple"); CD_APPLET_SET_IMAGE_ON_MY_ICON (myConfig.cImageFile); } } //\_______________ set the label _set_icon_label (myApplet); } } CD_APPLET_RELOAD_END cairo-dock-plugins-3.3.2/Folders/src/applet-notifications.c000775 001750 001750 00000052752 12223247501 025050 0ustar00mbaertsmbaerts000000 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_POSIX 1 #include #include "applet-struct.h" #include "applet-load-icons.h" #include "applet-notifications.h" //\___________ Define here the action to be taken when the user left-clicks on your icon or on its subdock or your desklet. The icon and the container that were clicked are available through the macros CD_APPLET_CLICKED_ICON and CD_APPLET_CLICKED_CONTAINER. CD_APPLET_CLICKED_ICON may be NULL if the user clicked in the container but out of icons. CD_APPLET_ON_CLICK_BEGIN if (CD_APPLET_CLICKED_ICON == myIcon) { if (! myConfig.bShowFiles) { cairo_dock_fm_launch_uri (myConfig.cDirPath); } else if (CD_APPLET_MY_ICONS_LIST == NULL) // repertoire vide, ou illisible, ou non defini { gldi_dialogs_remove_on_icon (myIcon); if (myConfig.cDirPath == NULL) gldi_dialog_show_temporary_with_icon (D_("Open the configuration of the applet to choose a folder to import."), myIcon, myContainer, 8000., myConfig.iSubdockViewType == 0 ? "same icon" : MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE); else { gchar *cPath = g_filename_from_uri (myConfig.cDirPath, NULL, NULL); gldi_dialog_show_temporary_with_icon_printf ("%s :\n%s", myIcon, myContainer, 4000., myConfig.iSubdockViewType == 0 ? "same icon" : MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE, cPath ? cPath : myConfig.cDirPath, D_("Empty or unreadable folder.")); g_free (cPath); } } else CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS); // on laisse passer la notification (pour ouvrir le sous-dock au clic). } else if (CD_APPLET_CLICKED_ICON != NULL) { //g_print ("clic on %s\n", CD_APPLET_CLICKED_ICON->cBaseURI); if (CD_APPLET_CLICKED_ICON->iVolumeID == -1) { //g_print ("folder\n"); /// lister le repertoire dans un thread. /// lancer une animation de transition. /// en attendant, on ouvre le repertoire... cairo_dock_fm_launch_uri (CD_APPLET_CLICKED_ICON->cBaseURI); } else { cairo_dock_fm_launch_uri (CD_APPLET_CLICKED_ICON->cBaseURI); } } CD_APPLET_ON_CLICK_END //\___________ Same as ON_CLICK, but with middle-click. CD_APPLET_ON_MIDDLE_CLICK_BEGIN if (CD_APPLET_CLICKED_ICON == myIcon) { cairo_dock_fm_launch_uri (myConfig.cDirPath); } else if (CD_APPLET_CLICKED_ICON != NULL && CD_APPLET_CLICKED_ICON->iVolumeID != 0) // clic sur un des repertoires. { cairo_dock_fm_launch_uri (CD_APPLET_CLICKED_ICON->cBaseURI); } CD_APPLET_ON_MIDDLE_CLICK_END //\___________ Define here the entries you want to add to the menu when the user right-clicks on your icon or on its subdock or your desklet. The icon and the container that were clicked are available through the macros CD_APPLET_CLICKED_ICON and CD_APPLET_CLICKED_CONTAINER. CD_APPLET_CLICKED_ICON may be NULL if the user clicked in the container but out of icons. The menu where you can add your entries is available throught the macro CD_APPLET_MY_MENU; you can add sub-menu to it if you want. #define MARGIN 3 static void _cd_folders_show_file_properties (GtkMenuItem *pMenuItem, gpointer *data) { Icon *icon = data[0]; CairoDock *pDock = data[1]; //g_print ("%s (%s)\n", __func__, icon->cName); guint64 iSize = 0; time_t iLastModificationTime = 0; gchar *cMimeType = NULL; int iUID=0, iGID=0, iPermissionsMask=0; if (cairo_dock_fm_get_file_properties (icon->cBaseURI, &iSize, &iLastModificationTime, &cMimeType, &iUID, &iGID, &iPermissionsMask)) { GtkWidget *pDialog = gtk_message_dialog_new (GTK_WINDOW (pDock->container.pWidget), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, D_("Properties:")); GString *sInfo = g_string_new (""); g_string_printf (sInfo, "%s", icon->cName); GtkWidget *pLabel= gtk_label_new (NULL); gtk_label_set_use_markup (GTK_LABEL (pLabel), TRUE); gtk_label_set_markup (GTK_LABEL (pLabel), sInfo->str); GtkWidget *pFrame = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (pFrame), MARGIN); gtk_frame_set_label_widget (GTK_FRAME (pFrame), pLabel); gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG(pDialog))), pFrame); gtk_frame_set_shadow_type (GTK_FRAME (pFrame), GTK_SHADOW_OUT); GtkWidget *pVBox = _gtk_vbox_new (MARGIN); gtk_container_add (GTK_CONTAINER (pFrame), pVBox); pLabel = gtk_label_new (NULL); gtk_label_set_use_markup (GTK_LABEL (pLabel), TRUE); g_string_printf (sInfo, "%s: %"G_GUINT64_FORMAT" %s", D_("Size"), iSize, D_("bytes")); if (iSize > 1024*1024) g_string_append_printf (sInfo, " (%.1f %s)", 1. * iSize / 1024 / 1024, D_("MB")); else if (iSize > 1024) g_string_append_printf (sInfo, " (%.1f %s)", 1. * iSize / 1024, D_("KB")); gtk_label_set_markup (GTK_LABEL (pLabel), sInfo->str); gtk_container_add (GTK_CONTAINER (pVBox), pLabel); pLabel = gtk_label_new (NULL); gtk_label_set_use_markup (GTK_LABEL (pLabel), TRUE); struct tm epoch_tm; localtime_r (&iLastModificationTime, &epoch_tm); // et non pas gmtime_r. gchar *cTimeChain = g_new0 (gchar, 100); strftime (cTimeChain, 100, "%F, %T", &epoch_tm); g_string_printf (sInfo, "%s: %s", D_("Last Modification"), cTimeChain); g_free (cTimeChain); gtk_label_set_markup (GTK_LABEL (pLabel), sInfo->str); gtk_container_add (GTK_CONTAINER (pVBox), pLabel); if (cMimeType != NULL) { pLabel = gtk_label_new (NULL); gtk_label_set_use_markup (GTK_LABEL (pLabel), TRUE); g_string_printf (sInfo, "%s: %s", D_("Mime Type"), cMimeType); gtk_label_set_markup (GTK_LABEL (pLabel), sInfo->str); gtk_container_add (GTK_CONTAINER (pVBox), pLabel); } #if (GTK_MAJOR_VERSION < 3) GtkWidget *pSeparator = gtk_hseparator_new (); #else GtkWidget *pSeparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); #endif gtk_container_add (GTK_CONTAINER (pVBox), pSeparator); pLabel = gtk_label_new (NULL); gtk_label_set_use_markup (GTK_LABEL (pLabel), TRUE); g_string_printf (sInfo, "%s: %d \t %s: %d", D_("User ID"), iUID, D_("Group ID"), iGID); gtk_label_set_markup (GTK_LABEL (pLabel), sInfo->str); gtk_container_add (GTK_CONTAINER (pVBox), pLabel); pLabel = gtk_label_new (NULL); gtk_label_set_use_markup (GTK_LABEL (pLabel), TRUE); int iOwnerPermissions = iPermissionsMask >> 6; // 8*8. int iGroupPermissions = (iPermissionsMask - (iOwnerPermissions << 6)) >> 3; int iOthersPermissions = (iPermissionsMask % 8); g_string_printf (sInfo, "%s: %s: %s / %s: %s / %s: %s", D_("Permissions"), D_("Read"), iOwnerPermissions ? D_("Yes") : D_("No"), D_("Write"), iGroupPermissions ? D_("Yes") : D_("No"), D_("Execute"), iOthersPermissions ? D_("Yes") : D_("No")); gtk_label_set_markup (GTK_LABEL (pLabel), sInfo->str); gtk_container_add (GTK_CONTAINER (pVBox), pLabel); gtk_window_set_type_hint (GTK_WINDOW (pDialog), GDK_WINDOW_TYPE_HINT_DOCK); // sinon le dialogue sera toujours derriere le sous-dock, meme avec un 'set_keep_above'. en contrepartie, le dialgue n'aura pas de bordure (du moins avec Compiz). gtk_window_set_keep_above (GTK_WINDOW (pDialog), TRUE); gtk_widget_show_all (gtk_dialog_get_content_area (GTK_DIALOG(pDialog))); gtk_window_set_position (GTK_WINDOW (pDialog), GTK_WIN_POS_CENTER_ALWAYS); gtk_dialog_run (GTK_DIALOG (pDialog)); gtk_widget_destroy (pDialog); g_string_free (sInfo, TRUE); g_free (cMimeType); } } static void _on_answer_delete_file (int iClickedButton, GtkWidget *pInteractiveWidget, Icon *icon, CairoDialog *pDialog) { if (iClickedButton == 0 || iClickedButton == -1) // ok button or Enter. { gboolean bSuccess = cairo_dock_fm_delete_file (icon->cBaseURI, FALSE); if (! bSuccess) { cd_warning ("couldn't delete this file.\nCheck that you have writing rights on this file.\n"); gchar *cMessage = g_strdup_printf (D_("Warning: could not delete this file.\nPlease check file permissions.")); gldi_dialog_show_temporary_with_default_icon (cMessage, icon, icon->pContainer, 4000); g_free (cMessage); } } } static void _cd_folders_delete_file (GtkMenuItem *pMenuItem, gpointer *data) { Icon *icon = data[0]; GldiContainer *pContainer = data[1]; cd_message ("%s (%s)", __func__, icon->cName); gchar *cPath = g_filename_from_uri (icon->cBaseURI, NULL, NULL); g_return_if_fail (cPath != NULL); gchar *question = g_strdup_printf (D_("You're about deleting this file\n (%s)\nfrom your hard-disk. Sure ?"), cPath); g_free (cPath); gldi_dialog_show_with_question (question, icon, pContainer, "same icon", (CairoDockActionOnAnswerFunc) _on_answer_delete_file, icon, (GFreeFunc)NULL); // if the icon is deleted during the question, the dialog will disappear with it, and we won't be called back. } static void _on_answer_rename_file (int iClickedButton, GtkWidget *pInteractiveWidget, Icon *icon, CairoDialog *pDialog) { if (iClickedButton == 0 || iClickedButton == -1) // ok button or Enter. { const gchar *cNewName = gtk_entry_get_text (GTK_ENTRY (pInteractiveWidget)); if (cNewName != NULL && *cNewName != '\0') { gboolean bSuccess = cairo_dock_fm_rename_file (icon->cBaseURI, cNewName); if (! bSuccess) { cd_warning ("couldn't rename this file.\nCheck that you have writing rights, and that the new name does not already exist."); gldi_dialog_show_temporary_with_icon_printf (D_("Warning: could not rename %s.\nCheck file permissions \nand that the new name does not already exist."), icon, icon->pContainer, 5000, NULL, icon->cBaseURI); } } } } static void _cd_folders_rename_file (GtkMenuItem *pMenuItem, gpointer *data) { Icon *icon = data[0]; cd_message ("%s (%s)", __func__, icon->cName); gldi_dialog_show_with_entry (D_("Rename to:"), icon, icon->pContainer, "same icon", icon->cName, (CairoDockActionOnAnswerFunc)_on_answer_rename_file, icon, (GFreeFunc)NULL); } static void _cd_folders_move_file (GtkMenuItem *pMenuItem, gpointer *data) { Icon *icon = data[0]; GldiContainer *pContainer = data[1]; GldiModuleInstance *myApplet = data[2]; cd_message ("%s (%s)", __func__, icon->cName); GtkWidget* pFileChooserDialog = gtk_file_chooser_dialog_new ( _("Pick up a directory"), GTK_WINDOW (pContainer->pWidget), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (pFileChooserDialog), myConfig.cDirPath); gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (pFileChooserDialog), FALSE); gtk_widget_show (pFileChooserDialog); int answer = gtk_dialog_run (GTK_DIALOG (pFileChooserDialog)); if (answer == GTK_RESPONSE_OK) { gchar *cFilePath = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (pFileChooserDialog)); cairo_dock_fm_move_file (icon->cBaseURI, cFilePath); } gtk_widget_destroy (pFileChooserDialog); } static void _on_answer_create_file (int iClickedButton, GtkWidget *pInteractiveWidget, gpointer *data, CairoDialog *pDialog) { if (iClickedButton == 0 || iClickedButton == -1) // ok button or Enter. { gboolean bFolder = GPOINTER_TO_INT (data[0]); GldiModuleInstance *myApplet = data[1]; const gchar *cNewName = gtk_entry_get_text (GTK_ENTRY (pInteractiveWidget)); if (cNewName != NULL && *cNewName != '\0') { gchar *cURI = g_strdup_printf ("%s/%s", myConfig.cDirPath, cNewName); gboolean bSuccess = cairo_dock_fm_create_file (cURI, bFolder); if (! bSuccess) { cd_warning ("couldn't create this file.\nCheck that you have writing rights, and that the new name does not already exist."); gldi_dialog_show_temporary_with_icon_printf (D_("Warning: could not create %s.\nCheck file permissions \nand that the new name does not already exist."), myIcon, myContainer, 5000, NULL, cNewName); } } } } static inline void _create_new_file (GldiModuleInstance *myApplet, gboolean bFolder) { gpointer *data = g_new (gpointer, 2); data[0] = GINT_TO_POINTER (bFolder); data[1] = myApplet; gldi_dialog_show_with_entry (D_("Enter a file name:"), myIcon, myContainer, "same icon", NULL, (CairoDockActionOnAnswerFunc)_on_answer_create_file, data, (GFreeFunc)g_free); } static void _cd_folders_new_file (GtkMenuItem *pMenuItem, GldiModuleInstance *myApplet) { _create_new_file (myApplet, FALSE); } static void _cd_folders_new_folder (GtkMenuItem *pMenuItem, GldiModuleInstance *myApplet) { _create_new_file (myApplet, TRUE); } static void _cd_folders_open_folder (GtkMenuItem *pMenuItem, GldiModuleInstance *myApplet) { cairo_dock_fm_launch_uri (myConfig.cDirPath); } static void _cd_folders_launch_with (GtkMenuItem *pMenuItem, gpointer *app) { Icon *icon = app[0]; gchar *cExec = app[3]; gchar *cUri = NULL; if (icon->cBaseURI && *icon->cBaseURI == '/') cUri = g_filename_from_uri (icon->cBaseURI, NULL, NULL); cairo_dock_launch_command_printf ("%s \"%s\"", NULL, cExec, cUri?cUri:icon->cBaseURI); // in case the program doesn't handle URI (geeqie, etc). g_free (cUri); } static void _cd_folders_sort_by_name (GtkMenuItem *pMenuItem, GldiModuleInstance *myApplet) { cd_folders_sort_icons (myApplet, CAIRO_DOCK_FM_SORT_BY_NAME); } static void _cd_folders_sort_by_date (GtkMenuItem *pMenuItem, GldiModuleInstance *myApplet) { cd_folders_sort_icons (myApplet, CAIRO_DOCK_FM_SORT_BY_DATE); } static void _cd_folders_sort_by_size (GtkMenuItem *pMenuItem, GldiModuleInstance *myApplet) { cd_folders_sort_icons (myApplet, CAIRO_DOCK_FM_SORT_BY_SIZE); } static void _cd_folders_sort_by_type (GtkMenuItem *pMenuItem, GldiModuleInstance *myApplet) { cd_folders_sort_icons (myApplet, CAIRO_DOCK_FM_SORT_BY_TYPE); } static void _free_app (gpointer *app) { g_free (app[3]); g_free (app); } void cd_folders_free_apps_list (GldiModuleInstance *myApplet) { if (myData.pAppList != NULL) { g_list_foreach (myData.pAppList, (GFunc) _free_app, NULL); g_list_free (myData.pAppList); myData.pAppList = NULL; } } CD_APPLET_ON_BUILD_MENU_BEGIN static gpointer *data = NULL; //g_print ("%x;%x;%x\n", icon, pContainer, menu); if (data == NULL) data = g_new0 (gpointer, 4); data[0] = CD_APPLET_CLICKED_ICON; data[1] = CD_APPLET_CLICKED_CONTAINER; data[2] = myApplet; if (CD_APPLET_CLICKED_ICON == myIcon || CD_APPLET_CLICKED_ICON == NULL) // click on main icon or on the container. { if (myConfig.bShowFiles) { gchar *cLabel = g_strdup_printf ("%s (%s)", D_("Open the folder"), D_("middle-click")); CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (cLabel, GTK_STOCK_OPEN, _cd_folders_open_folder, CD_APPLET_MY_MENU, myApplet); g_free (cLabel); } } else // clic on a file. { CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (D_("Rename this file"), GTK_STOCK_SAVE_AS, _cd_folders_rename_file, CD_APPLET_MY_MENU, data); CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (D_("Delete this file"), GTK_STOCK_REMOVE, _cd_folders_delete_file, CD_APPLET_MY_MENU, data); CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (D_("Move this file"), GTK_STOCK_JUMP_TO, _cd_folders_move_file, CD_APPLET_MY_MENU, data); GList *pApps = cairo_dock_fm_list_apps_for_file (CD_APPLET_CLICKED_ICON->cBaseURI); if (pApps != NULL) { CD_APPLET_ADD_SEPARATOR_IN_MENU (CD_APPLET_MY_MENU); GtkWidget *pSubMenu = CD_APPLET_ADD_SUB_MENU_WITH_IMAGE (D_("Open with"), CD_APPLET_MY_MENU, GTK_STOCK_OPEN); cd_folders_free_apps_list (myApplet); GList *a; gchar **pAppInfo; gchar *cIconPath; gpointer *app; gint iDesiredIconSize = cairo_dock_search_icon_size (GTK_ICON_SIZE_LARGE_TOOLBAR); // 24px for (a = pApps; a != NULL; a = a->next) { pAppInfo = a->data; app = g_new0 (gpointer, 4); app[0] = CD_APPLET_CLICKED_ICON; app[1] = CD_APPLET_CLICKED_CONTAINER; app[2] = myApplet; app[3] = g_strdup (pAppInfo[1]); //g_print (" + %s (%s ; %s)\n", pAppInfo[0], pAppInfo[1], pAppInfo[2]); myData.pAppList = g_list_prepend (myData.pAppList, app); if (pAppInfo[2] != NULL) cIconPath = cairo_dock_search_icon_s_path (pAppInfo[2], iDesiredIconSize); else cIconPath = NULL; CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (pAppInfo[0], cIconPath, _cd_folders_launch_with, pSubMenu, app); g_free (cIconPath); g_strfreev (pAppInfo); } g_list_free (pApps); } CD_APPLET_ADD_SEPARATOR_IN_MENU (CD_APPLET_MY_MENU); CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (D_("Properties"), GTK_STOCK_PROPERTIES, _cd_folders_show_file_properties, CD_APPLET_MY_MENU, data); CD_APPLET_ADD_SEPARATOR_IN_MENU (CD_APPLET_MY_MENU); CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (D_("Create a new file"), GTK_STOCK_NEW, _cd_folders_new_file, CD_APPLET_MY_MENU, myApplet); CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (D_("Create a new folder"), GTK_STOCK_NEW, _cd_folders_new_folder, CD_APPLET_MY_MENU, myApplet); } if (myConfig.bShowFiles) { GtkWidget *pSubMenu = CD_APPLET_ADD_SUB_MENU_WITH_IMAGE (D_("Sort by"), CD_APPLET_MY_MENU, GTK_STOCK_SORT_DESCENDING); pMenuItem = CD_APPLET_ADD_IN_MENU_WITH_DATA (D_("By name"), _cd_folders_sort_by_name, pSubMenu, myApplet); pMenuItem = CD_APPLET_ADD_IN_MENU_WITH_DATA (D_("By date"), _cd_folders_sort_by_date, pSubMenu, myApplet); pMenuItem = CD_APPLET_ADD_IN_MENU_WITH_DATA (D_("By size"), _cd_folders_sort_by_size, pSubMenu, myApplet); pMenuItem = CD_APPLET_ADD_IN_MENU_WITH_DATA (D_("By type"), _cd_folders_sort_by_type, pSubMenu, myApplet); } if (CD_APPLET_CLICKED_ICON != NULL && CD_APPLET_CLICKED_ICON != myIcon) CD_APPLET_LEAVE (GLDI_NOTIFICATION_INTERCEPT); CD_APPLET_ON_BUILD_MENU_END typedef struct { gchar *cReceivedData; double fOrder; gchar *cDockName; } CDDropData; static void _on_answer_import (int iClickedButton, GtkWidget *pInteractiveWidget, CDDropData *data, CairoDialog *pDialog) { cd_debug ("%s (%d)", __func__, iClickedButton); const gchar *cReceivedData = data->cReceivedData; double fOrder = data->fOrder; gboolean bImportFiles = (iClickedButton == 0 || iClickedButton == -1); // ok or Enter. // add a new conf file for the "Folders" module, with proper values. GldiModule *pModule = gldi_module_get ("Folders"); g_return_if_fail (pModule != NULL); gchar *cConfFilePath = gldi_module_add_conf_file (pModule); // we want to update the conf file before we instanciate the applet, so don't use high-level functions. cairo_dock_update_conf_file (cConfFilePath, G_TYPE_STRING, "Configuration", "dir path", cReceivedData, G_TYPE_BOOLEAN, "Configuration", "show files", bImportFiles, G_TYPE_DOUBLE, "Icon", "order", fOrder, G_TYPE_STRING, "Icon", "dock name", data->cDockName, G_TYPE_INVALID); // instanciate the module from this conf file. GldiModuleInstance *pNewInstance = gldi_module_instance_new (pModule, cConfFilePath); // prend le 'cConfFilePath'. // show a success message on the new icon. if (pNewInstance != NULL) gldi_dialog_show_temporary_with_icon (D_("The folder has been imported."), pNewInstance->pIcon, pNewInstance->pContainer, 5000, MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE); // not "same icon" because the icon may not be loaded yet (eg. stack or emblem icon). } static void _free_dialog_data (CDDropData *data) { g_free (data->cReceivedData); g_free (data->cDockName); g_free (data); } gboolean cd_folders_on_drop_data (gpointer data, const gchar *cReceivedData, Icon *icon, double fOrder, GldiContainer *pContainer) { //g_print ("Folders received '%s'\n", cReceivedData); if (icon != NULL || fOrder == CAIRO_DOCK_LAST_ORDER) // drop on an icon or outside of icons. return GLDI_NOTIFICATION_LET_PASS; gchar *cPath = NULL; if (strncmp (cReceivedData, "file://", 7) == 0) cPath = g_filename_from_uri (cReceivedData, NULL, NULL); else cPath = g_strdup (cReceivedData); if (g_file_test (cPath, G_FILE_TEST_IS_DIR)) // it's a folder, let's add a new instance of the applet that will handle it. { // search the closest icon to the drop point (we want to place the dialog on it). GList *pIconsList = NULL, *ic; if (CAIRO_DOCK_IS_DOCK (pContainer)) pIconsList = CAIRO_DOCK (pContainer)->icons; else if (CAIRO_DOCK_IS_DESKLET (pContainer)) pIconsList = CAIRO_DESKLET (pContainer)->icons; Icon *pIcon = NULL; for (ic = pIconsList; ic != NULL; ic = ic->next) { icon = ic->data; if (icon->fOrder > fOrder) { pIcon = icon; break; } } if (pIcon == NULL) { if (CAIRO_DOCK_IS_DOCK (pContainer)) pIcon = gldi_icons_get_without_dialog (CAIRO_DOCK (pContainer)->icons); else pIcon = gldi_icons_get_any_without_dialog (); } // ask the user whether (s)he wants to import the folder's content. CDDropData *data = g_new0 (CDDropData, 1); data->cReceivedData = g_strdup (cReceivedData); data->fOrder = fOrder; if (CAIRO_DOCK_IS_DOCK (pContainer)) data->cDockName = g_strdup (gldi_dock_get_name (CAIRO_DOCK (pContainer))); gldi_dialog_show (D_("Do you want to import the content of the folder too?"), pIcon, pContainer, 0, MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE, NULL, (CairoDockActionOnAnswerFunc) _on_answer_import, data, (GFreeFunc)_free_dialog_data); return GLDI_NOTIFICATION_INTERCEPT; } return GLDI_NOTIFICATION_LET_PASS; } cairo-dock-plugins-3.3.2/Folders/src/applet-load-icons.c000775 001750 001750 00000034057 12223247501 024225 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-notifications.h" #include "applet-load-icons.h" static void _cd_folders_remove_all_icons (GldiModuleInstance *myApplet); void cd_shortcuts_set_icon_order (Icon *pNewIcon, GList *pIconsList, GCompareFunc comp) { if (comp == NULL) return; cd_debug ("%s (%s)", __func__, pNewIcon->cName); // on cherche la 1ere icone du meme type. GList *ic; Icon *pIcon; for (ic = pIconsList; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->iGroup == pNewIcon->iGroup) break; } GList *ic0 = ic; if (! ic0) // si non trouve, on arrete la. { pNewIcon->fOrder = 0; return; } pIcon = ic0->data; if (comp (pNewIcon, pIcon) <= 0) { pNewIcon->fOrder = pIcon->fOrder - 1; cd_debug ("name : %s <= %s -> %.2f", pNewIcon->cName, pIcon->cName, pNewIcon->fOrder); return; } pNewIcon->fOrder = 0; for (ic = ic0; ic != NULL; ic = ic->next) { pIcon = ic->data; cd_debug (" compare with %s (%.2f)", pIcon->cName, pIcon->fOrder); if (pIcon->iGroup != pNewIcon->iGroup) { cd_debug (" type differ, break"); break; } if (comp (pNewIcon, pIcon) < 0) { if (ic->prev == NULL) pNewIcon->fOrder = pIcon->fOrder - 1; else { Icon *pPrevIcon = ic->prev->data; pNewIcon->fOrder = (pIcon->fOrder + pPrevIcon->fOrder) / 2; } cd_debug (" name : %s < %s -> %.2f", pNewIcon->cName, pIcon->cName, pNewIcon->fOrder); break; } pNewIcon->fOrder = pIcon->fOrder + 1; cd_debug (" fOrder <- %.2f", pNewIcon->fOrder); } } static void _manage_event_on_file (CairoDockFMEventType iEventType, const gchar *cBaseURI, GList *pIconsList, GldiContainer *pContainer, GldiModuleInstance *myApplet) { if (!cBaseURI) return; gchar *cURI = g_strdup (cBaseURI); cairo_dock_remove_html_spaces (cURI); cd_debug (" * event %d on '%s'", iEventType, cURI); if (!myConfig.bShowHiddenFiles) { gchar *str = strrchr (cBaseURI, '/'); if (str && *(str+1) == '.') return; } switch (iEventType) { case CAIRO_DOCK_FILE_DELETED : // un fichier a ete supprime (ce peut etre du a un renommage). { if (strcmp (myConfig.cDirPath, cBaseURI) == 0) { cd_debug ("our folder has been removed"); _cd_folders_remove_all_icons (myApplet); return; } Icon *pConcernedIcon = cairo_dock_get_icon_with_base_uri (pIconsList, cURI); if (pConcernedIcon == NULL) // on cherche par nom. { pConcernedIcon = cairo_dock_get_icon_with_name (pIconsList, cURI); } if (pConcernedIcon == NULL) { cd_warning (" an unknown file was removed"); return ; } cd_debug (" %s will be removed", pConcernedIcon->cName); // on l'enleve du container. CD_APPLET_REMOVE_ICON_FROM_MY_ICONS_LIST (pConcernedIcon); // detruit l'icone. } break ; case CAIRO_DOCK_FILE_CREATED : // un point de montage a ete connecte. { if (strcmp (myConfig.cDirPath, cBaseURI) == 0) { cd_debug ("our folder has been re-created"); cairo_dock_launch_task (myData.pTask); return; } //\_______________________ on verifie qu'elle n'existe pas deja. Icon *pSameIcon = cairo_dock_get_icon_with_base_uri (pIconsList, cURI); if (pSameIcon != NULL) { cd_warning ("this file (%s) already exists", pSameIcon->cName); return; // on decide de ne rien faire, c'est surement un signal inutile. } //\_______________________ on cree une icone pour cette nouvelle URI. Icon *pNewIcon = cairo_dock_fm_create_icon_from_URI (cURI, pContainer, myConfig.iSortType); if (pNewIcon == NULL) { cd_warning ("couldn't create an icon for this file"); return ; } pNewIcon->iGroup = (myConfig.bFoldersFirst && pNewIcon->iVolumeID == -1 ? 6 : 8); //\_______________________ on la place au bon endroit suivant son nom. cd_shortcuts_set_icon_order (pNewIcon, pIconsList, myData.comp); cd_debug (" new file : %s, order = %.2f", pNewIcon->cName, pNewIcon->fOrder); CD_APPLET_ADD_ICON_IN_MY_ICONS_LIST (pNewIcon); } break ; case CAIRO_DOCK_FILE_MODIFIED : // un point de montage a ete (de)monte { Icon *pConcernedIcon = cairo_dock_get_icon_with_base_uri (pIconsList, cURI); if (pConcernedIcon == NULL) // on cherche par nom. { pConcernedIcon = cairo_dock_get_icon_with_name (pIconsList, cURI); } if (pConcernedIcon == NULL) { cd_warning (" an unknown file was modified"); return ; } cd_debug (" %s is modified", pConcernedIcon->cName); //\_______________________ on recupere les infos actuelles. Icon *pNewIcon = cairo_dock_fm_create_icon_from_URI (cURI, pContainer, myConfig.iSortType); if (pNewIcon == NULL) { cd_warning ("couldn't create an icon for this file"); return ; } pNewIcon->iGroup = (myConfig.bFoldersFirst && pNewIcon->iVolumeID == -1 ? 6 : 8); double fCurrentOrder = pConcernedIcon->fOrder; if (myConfig.iSortType == 1 || myConfig.iSortType == 2) // sort by date or size. pConcernedIcon->fOrder = pNewIcon->fOrder; //\_______________________ on gere le changement de nom. if (cairo_dock_strings_differ (pConcernedIcon->cName, pNewIcon->cName)) // le nom a change. { cd_debug (" name changed : '%s' -> '%s'", pConcernedIcon->cName, pNewIcon->cName); gldi_icon_set_name (pConcernedIcon, pNewIcon->cName); cd_shortcuts_set_icon_order (pConcernedIcon, pIconsList, myData.comp); } //\_______________________ on gere le changement d'image. if (cairo_dock_strings_differ (pConcernedIcon->cFileName, pNewIcon->cFileName)) { cd_debug (" image changed : '%s' -> '%s'", pConcernedIcon->cFileName, pNewIcon->cFileName); g_free (pConcernedIcon->cFileName); pConcernedIcon->cFileName = g_strdup (pNewIcon->cFileName); if (pConcernedIcon->image.pSurface != NULL) cairo_dock_load_icon_image (pConcernedIcon, pContainer); } //\_______________________ on gere le changement d'ordre (du au changement de nom, d'extension, ou de taille, suivant le classement utilise). if (pConcernedIcon->fOrder != fCurrentOrder) { cd_debug (" order changed : %.2f -> %.2f", fCurrentOrder, pConcernedIcon->fOrder); // on la detache. CD_APPLET_DETACH_ICON_FROM_MY_ICONS_LIST (pConcernedIcon); pIconsList = CD_APPLET_MY_ICONS_LIST; CD_APPLET_ADD_ICON_IN_MY_ICONS_LIST (pConcernedIcon); } gldi_object_unref (GLDI_OBJECT (pNewIcon)); } break ; case CAIRO_DOCK_NB_EVENT_ON_FILES : break ; } g_free (cURI); } static void _cd_folders_on_file_event (CairoDockFMEventType iEventType, const gchar *cURI, GldiModuleInstance *myApplet) { g_return_if_fail (cURI != NULL); CD_APPLET_ENTER; //\________________ On gere l'evenement sur le fichier. GList *pIconsList = CD_APPLET_MY_ICONS_LIST; GldiContainer *pContainer = CD_APPLET_MY_ICONS_LIST_CONTAINER; CD_APPLET_LEAVE_IF_FAIL (pContainer != NULL); _manage_event_on_file (iEventType, cURI, pIconsList, pContainer, myApplet); CD_APPLET_LEAVE(); } static void _cd_folders_get_data (CDSharedMemory *pSharedMemory) { //\_______________________ On recupere les fichiers. gchar *cCommand = NULL; pSharedMemory->pIconList = cairo_dock_fm_list_directory (pSharedMemory->cDirPath, pSharedMemory->iSortType, 8, pSharedMemory->bShowHiddenFiles, 1e4, &cCommand); g_free (cCommand); //\_______________________ on classe les icones. if (pSharedMemory->bFoldersFirst) { Icon *pIcon; GList *ic; for (ic = pSharedMemory->pIconList; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->iVolumeID != 0) // repertoire pIcon->iGroup = 6; } } if (pSharedMemory->iSortType == 0) // sort by name { pSharedMemory->pIconList = g_list_sort (pSharedMemory->pIconList, (GCompareFunc) cairo_dock_compare_icons_name); } else if (pSharedMemory->iSortType == 3) // sort by type { pSharedMemory->pIconList = g_list_sort (pSharedMemory->pIconList, (GCompareFunc) cairo_dock_compare_icons_extension); } else // sort by date or size { pSharedMemory->pIconList = g_list_sort (pSharedMemory->pIconList, (GCompareFunc) cairo_dock_compare_icons_order); } //g_print ("=== files to display: ===\n"); Icon *pIcon; int iOrder = 0; GList *ic; for (ic = pSharedMemory->pIconList; ic != NULL; ic = ic->next) { pIcon = ic->data; //g_print (" %s (%d)\n", pIcon->cName, pIcon->iVolumeID); pIcon->fOrder = iOrder ++; } } static gboolean _cd_folders_load_icons_from_data (CDSharedMemory *pSharedMemory) { GldiModuleInstance *myApplet = pSharedMemory->pApplet; g_return_val_if_fail (myIcon != NULL, FALSE); // paranoia CD_APPLET_ENTER; //\_______________________ On efface l'ancienne liste. CD_APPLET_DELETE_MY_ICONS_LIST; //\_______________________ On charge la nouvelle liste. CD_APPLET_LOAD_MY_ICONS_LIST (pSharedMemory->pIconList, myConfig.cRenderer, "Viewport", NULL); pSharedMemory->pIconList = NULL; //\_______________________ On se place en ecoute. cairo_dock_fm_add_monitor_full (pSharedMemory->cDirPath, TRUE, NULL, (CairoDockFMMonitorCallback) _cd_folders_on_file_event, myApplet); cairo_dock_discard_task (myData.pTask); myData.pTask = NULL; CD_APPLET_LEAVE (TRUE); } static void _free_shared_memory (CDSharedMemory *pSharedMemory) { g_free (pSharedMemory->cDirPath); g_list_foreach (pSharedMemory->pIconList, (GFunc)g_free, NULL); g_list_free (pSharedMemory->pIconList); g_free (pSharedMemory); } void cd_folders_start (GldiModuleInstance *myApplet) { if (myData.pTask != NULL) { cairo_dock_discard_task (myData.pTask); myData.pTask = NULL; } CDSharedMemory *pSharedMemory = g_new0 (CDSharedMemory, 1); pSharedMemory->cDirPath = g_strdup (myConfig.cDirPath); pSharedMemory->bShowFiles = myConfig.bShowFiles; pSharedMemory->iSortType = myConfig.iSortType; pSharedMemory->bFoldersFirst = myConfig.bFoldersFirst; pSharedMemory->bShowHiddenFiles = myConfig.bShowHiddenFiles; pSharedMemory->pApplet = myApplet; myData.pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _cd_folders_get_data, (CairoDockUpdateSyncFunc) _cd_folders_load_icons_from_data, (GFreeFunc) _free_shared_memory, pSharedMemory); cairo_dock_launch_task_delayed (myData.pTask, 0); // le delai est la pour laisser le temps au backend gvfs de s'initialiser (sinon on a un "g_hash_table_lookup: assertion `hash_table != NULL' failed" lors du listing d'un repertoire, avec en consequence des icones non trouvees). } static void _cd_folders_remove_all_icons (GldiModuleInstance *myApplet) { //\_______________________ On stoppe la tache. cairo_dock_discard_task (myData.pTask); myData.pTask = NULL; //\_______________________ On detruit ensuite les icones chargees dans le container. CD_APPLET_DELETE_MY_ICONS_LIST; // si le container a change entre-temps, le ModuleManager se chargera de nettoyer derriere nous. } void cd_folders_free_all_data (GldiModuleInstance *myApplet) { //\_______________________ On arrete de surveiller le repertoire. cairo_dock_fm_remove_monitor_full (myConfig.cDirPath, TRUE, NULL); _cd_folders_remove_all_icons (myApplet); cd_folders_free_apps_list (myApplet); } static void _get_order (Icon *pIcon, gpointer data) { CairoDockFMSortType iSortType = GPOINTER_TO_INT (data); gchar *cName = NULL, *cURI = NULL, *cIconName = NULL; gboolean bIsDirectory; int iVolumeID; double fOrder; cairo_dock_fm_get_file_info (pIcon->cBaseURI, &cName, &cURI, &cIconName, &bIsDirectory, &iVolumeID, &fOrder, iSortType); g_free (cName); g_free (cURI); g_free (cIconName); pIcon->fOrder = fOrder; } GList *cairo_dock_sort_icons_by_extension (GList *pIconList) { GList *pSortedIconList = g_list_sort (pIconList, (GCompareFunc) cairo_dock_compare_icons_extension); guint iCurrentGroup = -1; double fCurrentOrder = 0.; Icon *icon; GList *ic; for (ic = pIconList; ic != NULL; ic = ic->next) { icon = ic->data; if (icon->iGroup != iCurrentGroup) { iCurrentGroup = icon->iGroup; fCurrentOrder = 0.; } icon->fOrder = fCurrentOrder++; } return pSortedIconList; } void cd_folders_sort_icons (GldiModuleInstance *myApplet, CairoDockFMSortType iSortType) { GList *pIconsList = CD_APPLET_MY_ICONS_LIST; GldiContainer *pContainer = CD_APPLET_MY_ICONS_LIST_CONTAINER; if (!pIconsList || !pContainer) // nothing to do. return; switch (iSortType) { case CAIRO_DOCK_FM_SORT_BY_NAME: pIconsList = cairo_dock_sort_icons_by_name (pIconsList); break; case CAIRO_DOCK_FM_SORT_BY_DATE: g_list_foreach (pIconsList, (GFunc)_get_order, GINT_TO_POINTER (CAIRO_DOCK_FM_SORT_BY_DATE)); pIconsList = cairo_dock_sort_icons_by_order (pIconsList); break; case CAIRO_DOCK_FM_SORT_BY_SIZE: g_list_foreach (pIconsList, (GFunc)_get_order, GINT_TO_POINTER (CAIRO_DOCK_FM_SORT_BY_SIZE)); pIconsList = cairo_dock_sort_icons_by_order (pIconsList); break; case CAIRO_DOCK_FM_SORT_BY_TYPE: pIconsList = cairo_dock_sort_icons_by_extension (pIconsList); break; default: break; } if (myDock) { CairoDock *pSubDock = CAIRO_DOCK (pContainer); pSubDock->icons = pIconsList; cairo_dock_calculate_dock_icons (pSubDock); cairo_dock_update_dock_size (pSubDock); } else { myDesklet->icons = pIconsList; if (myDesklet->pRenderer && myDesklet->pRenderer->calculate_icons != NULL) myDesklet->pRenderer->calculate_icons (myDesklet); // don't use cairo_dock_update_desklet_icons(), since the number of icons didn't change. } // redraw cairo_dock_redraw_container (pContainer); myConfig.iSortType = iSortType; // we don't update the conf file, it's a temporary modification. } cairo-dock-plugins-3.3.2/Folders/src/applet-config.c000775 001750 001750 00000006321 12223247501 023433 0ustar00mbaertsmbaerts000000 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 "applet-struct.h" #include "applet-load-icons.h" #include "applet-config.h" //\_________________ Here you have to get all your parameters from the conf file. Use the macros CD_CONFIG_GET_BOOLEAN, CD_CONFIG_GET_INTEGER, CD_CONFIG_GET_STRING, etc. myConfig has been reseted to 0 at this point. This function is called at the beginning of init and reload. CD_APPLET_GET_CONFIG_BEGIN myConfig.cDefaultTitle = CD_CONFIG_GET_STRING ("Icon", "name"); myConfig.cImageFile = CD_CONFIG_GET_STRING ("Icon", "image file"); myConfig.cDirPath = CD_CONFIG_GET_STRING ("Configuration", "dir path"); if (myConfig.cDirPath) // transform the pah into an URI. { if (*myConfig.cDirPath == '~') { gchar *tmp = myConfig.cDirPath; myConfig.cDirPath = g_strdup_printf ("%s%s", g_getenv ("HOME"), myConfig.cDirPath+1); g_free (tmp); } if (*myConfig.cDirPath == '/') { gchar *tmp = myConfig.cDirPath; myConfig.cDirPath = g_filename_to_uri (myConfig.cDirPath, NULL, NULL); g_free (tmp); } } myConfig.bShowFiles = CD_CONFIG_GET_BOOLEAN_WITH_DEFAULT ("Configuration", "show files", TRUE); myConfig.cRenderer = CD_CONFIG_GET_STRING ("Configuration", "renderer"); myConfig.iSortType = CD_CONFIG_GET_INTEGER ("Configuration", "sort type"); myConfig.bFoldersFirst = CD_CONFIG_GET_BOOLEAN ("Configuration", "folders first"); myConfig.bShowHiddenFiles = CD_CONFIG_GET_BOOLEAN ("Configuration", "show hidden"); if (myConfig.bShowFiles) myConfig.iSubdockViewType = CD_CONFIG_GET_INTEGER ("Icon", "view type"); else myConfig.iSubdockViewType = 0; // image definie en conf. CD_APPLET_GET_CONFIG_END //\_________________ Here you have to free all ressources allocated for myConfig. This one will be reseted to 0 at the end of this function. This function is called right before you get the applet's config, and when your applet is stopped, in the end. CD_APPLET_RESET_CONFIG_BEGIN g_free (myConfig.cImageFile); g_free (myConfig.cDefaultTitle); if (myConfig.cDirPath) { cairo_dock_fm_remove_monitor_full (myConfig.cDirPath, TRUE, NULL); g_free (myConfig.cDirPath); } g_free (myConfig.cRenderer); CD_APPLET_RESET_CONFIG_END //\_________________ Here you have to free all ressources allocated for myData. This one will be reseted to 0 at the end of this function. This function is called when your applet is stopped, in the very end. CD_APPLET_RESET_DATA_BEGIN cd_folders_free_all_data (myApplet); CD_APPLET_RESET_DATA_END cairo-dock-plugins-3.3.2/Folders/src/applet-config.h000775 001750 001750 00000001565 12223247501 023445 0ustar00mbaertsmbaerts000000 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 __APPLET_CONFIG__ #define __APPLET_CONFIG__ #include CD_APPLET_CONFIG_H #endif cairo-dock-plugins-3.3.2/Folders/CMakeLists.txt000664 001750 001750 00000000055 12223247501 022503 0ustar00mbaertsmbaerts000000 000000 add_subdirectory(src) add_subdirectory(data) cairo-dock-plugins-3.3.2/Folders/data/icon.png000664 001750 001750 00000006025 12223247501 022315 0ustar00mbaertsmbaerts000000 000000 PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org< IDATx[MlWΝy?~&qJ$W ƕJĂk$X` "bQ $`!jҢ_ئvm7ͽ簘;3wͼ;O:xfy|;;&A'y {*J|222855{hn\ti's;)ߞ{ T\~Rj_?>vg._\Ԑ 񹒯0c8W>Rʕ+ܹs~G S arr[XXŋ/UfߟP"z}ff2ٯ|V|vv o6X__QɞZ*|p—R_ 3v||ԩsEj=mkk 7o\>pRk"k6]Q:N>R DwJ>h_&"Xԁ06P qIU8 "^6]&^^XS'x (JX\\D#G];e@gNFՇe#mVX\\ĭ[PV$nB-:7@DN׌1WgϞ] s=_.Yq_Vԃ{]afSC)R)0==m4 ӭVkŋKD?R/(Vabb###gΜX!.]ѣGK{*z5,,,8v=:np@mddqٻxkgtlѰ~zhO 7#vO"uJ h~{CX+ p5cpp}o\zutjjBұ LCPױ f>0rT민 <;;u0 >`"TT6ygF[\0,3ȝJcΈVd_3gym&<kd^+IiI1a)3%9#ꋀ%kl|m4#0"Z֚ť1wLBp!XFC"otv(gmƹDF0`a^=E+ ΐK{V"$B'qīk zw4#/Gb(,Fk1oVHh.eP-#cա`ai1*Q:BG86㜜>+R묱J `50"rc%S\g`iR X@{Tx_ zφR^3'U`.p񙧙@A$ms^۳ߓaUq%\Ij쾵b"d c ݥHӿ yp(̼v x?D4&|ɴW<paz,OTy JrCt9 :RA۳ҘiYj@nhyv>)', b-cg z^4--,1FF /fKj-Yia )TT $3s)=vDkuhn@ u# /Do{!" _f}I8 )ۇ|5eTIENDB`cairo-dock-plugins-3.3.2/Folders/data/preview.jpg000664 001750 001750 00000177263 12223247501 023057 0ustar00mbaertsmbaerts000000 000000 JFIFHHC  !"$"$C7=" e !1A"Qaq'2STU#&BRVt$3Cbs67DFr%4Eud 5ce7!1QAaq"2R#3B$4S ??tgMVn ZݗYL8iV *' wV}=,j:VVr@J)@~>mG+Q|SsIv)Gʔ'S@_L}(v[O:b@OEB,k3r`'<Ʈ. 3*zJ(JVJT{Ar5dq9+1r,t'N0itTF8ҊĒ$)*=E$(A7Խ?JMeȐތIߦwOE8twRI6+Z ڥ$$ ;7')lUiȗcLz)åL>5dүKn/_!åOsSK&~\8W7~gLZYC6PBR-D%)*RPH*'O!QȗåޒLnz)}ޒLnz+HMEjyWES^B6lN3eQV’etJnz)~񇢪ChVOPǗ<OcsVr:M|a觎uD=[-0k>Dދ0/^OJ:K׿0UgixhS!V(񇢗?Iaaa>Yp2pRTzI$vnOSvQȐދP+]N$Ufq8qiiRRHBwQ)HoEtIa54=Qy<ۍ(+ ZJIJ`{Ar4HoEIa4=RG17͈*Qϳo16%񇢜:F0U3Ay`To"DoEt?Ig|a},=J%g?;"Cz.]q۩'|a5$=G l!Ҋi)RBRAG#QȐދ[~NJ:Cߤs0UWvbXC.V!)!%I$ٹ>1ND輎=-j9z*Og)ޝ!K g|jْ5Eg{`n*6yl 8)Da#[1qM6[j+F#jjzBQ5[أqy[lnRTYƙn7.|t 3S0oW%q*m$osn@TPZy]tGVPt J\'#c 78AR%(BYl 8P|-%ہ'>>ŗWY/P[Q+Ru+PNHϴTI&-Z[#W5{S蒷})yi`o"S槤C/Z8&C7UɎ$D0AB7JJTԷJep"(x`vUˮ&4\$ o8 Ri R%Dr j61l6#fpzk2)>)iRHA!$skm̋t&|K%l[_‹ (WXlK#pۋ1).JQ[uĶd4zR 5!Fxiqm ;W-Yi,s}/M{H3!ruRJQJV RRpq^~oݥծx0ETI!ډI8|Lsw۫W(ԘZX-i(BVvm%<1n.ѤLy@iA­qWe›-$2|g9J3vMtV1 ACIRW6E-̸opKn!VATbVH.߻#-M~d<!!$0)R98xj(ZbԚ]9>|dTg/'v*NB`%8Lj; FbakfSJ܌,P4 kÐߒy a-lJ6zv ԥJϽ2HXvLhX9S-$5]sS_sqmhSqVZeP i ExL %CTxl`>$% )H‼NrpH9lEݤw2"Ȑխ")S !;G}rlGKsZ/`$;% [v)8rQ6}}֨(U[$g![UӟJy*řV{m˭+clˎ!qwJT69ES'H~t:yuj$GI&.ZT_Z(butH۾pAR`fQA4>##ݐɸ1H' ~-+Ѓ#"͞ M1lUWXڎ0X!+)Pr:mne;-!+)PJħr'&Uenw.9SB j T6HE A'z+#Tţ.\;J7`s *b6_o v FtM.8Pq(8߆+vΣ%LzTx?Fox@)Q0`rH֫ڡۜʵ[nT,MKm7`NG!Y8m V^/znھW :t4eK)E'y$N P5^fŘ|fmnF wh%_ 6U뽦vn|n.GR:r6Zq Ny7BSqPk-Qb KM)YP {T8 B#Ab:h:@x[ ;pI6T)+8N:'I 'aZdXl'u?}[׺LLqm*@Tz@u.r\[]JY4FŵյXRm`o|v=;&2sNۥ'1$V i)*7ׅ ȽܤYhw6S@VQJs!@vcԯ=d?s7<䵻KaN;W9j F)cL 6ڑ!RP"9{ɭj}*nVWaPd*éqHxp H@J<\kj eۄ[s}x ޠ[CwM8vBWqAz9YWBjFl M[kH0ZK-!) Sm[w5"[L1C/[[R78PR3U+=hqyymNrq*BFFAee'T_Maoi_B0ҔAk HNIBwvD?hu=˄lNvZ}aOjJҍAXIʰ3%l9}1sZL7t8HX[6{p7 c*Hd4IHZӄ TBNy9v$E**kí T][!?3Ǣdd}Ffdd}FbYA^S0|FxU P_yM9dv(55DECNRfE Է~pwHT@THizxg&N43$F%D$5zOF4RkI<ĖKn±i1͏bUQJ| FEY:whsQFnov"gn7K|gT+I&/ciSO@S^Hf̕ws<º" ׀*k$OѧN~b}< E#<]^TMZG& y_mK g$%GI"u7ܫ[s]I7c#(G:uӨO75ՖbƧ$F+Ώ?aҷ\AC)aEamψkƩgo--_7H+<:{APHyr'*;b}o 9 G!.G tl9gq\TtZ̚9K539ReoSo|Dx^J)̒eܓ6)T6rOhaN4m;{㵵K $AO9,V2*59G!6%ru>k/DW\o #cآ@zx!!\JG85ͭ_I?Ŧ+TGA$ S5_>[vieN͐ڜi>#V8$E Ғqy;jV#oz6zl|L$+cB)$ctک崤OMe_\jdTdEm,qZ)QՔ a枣QABmOu!vm9:Dxo:jrintzR)J^7"KvcHjK(P>\|#k*Pn<|*M ^:pRt);@ ~!-!A.Ie J O,Km)S 4 G=Uu0Mp_[iRa>ZZ!ԝ/çfTȸ%-K[RVێS;;+ } 쁷\JRN|iA~߁NI3j{&=hӯ^{JҘ}0Hp%LRJǃH VbuYZĽ mr2 p^<%SY+K0 ES^8B2I$$'ScaJK q^`bUtm0 &W[ьU#ўULsPտf]$W0(+3@(@:xvVc6}ǝ NIW[[oO;v>;3}qrG<μ=7#'am$hB|GsŃ6i㓙7{`+&~R#,O{-ckWY-6Jm;)AC^}K! I8!G^Fxʱc%y8<ʶ{^S>vH1J*ً.NZOT! >Ej+l՗;ОaWI l‚r: ٴ!Ćd* qmcbQ!-nܻ_wY2rOs-A)%sPl' 'XTvRXJ ^u/==}*peJ.+" pOH pS/W[Z>+4e#yK(6%I]nWQ<<YjK7R$휎z. )dpSa'.ZU}|yܣtv\qOMYQmj+lhP\JUHWPF/ԐS"m(S p:2kyǶ[Jp=}g5(םnɆ0a!Fs'>ZR[PH<ǘ5{%p-.4y) q:uK# T RJ=G3"ui:XV鋟I7ckQ[,ִwHCآx+QS \R^)R)P{mY<}E}]'rV7[h <]ߝnzYQҮ/zYO>]@|zj׏EQOחT~~Tp((3@ )@@uwAG\WjҤ!.%-+e(Ŋ),ܢxc#G\H8 pZٱS,k}KP1J+O!ҕ\J7)491Z )WQ*TFNx$=")P< P)@j&trWBhבn0*991Cgau IRHyWOς9]1x~"E"dr^C^ja&|PSy^  x>6='wKRc> , I+_\ǯ#k{{J]Z9G , #rqPS6dR܄S*E(ONH]96JliPdP))TI+xϋ'=|`1[#Jn+7)\# Z'K_&L.8ճoEu"[ $xGMÀcc}N3\x{Uz~/_wIO&-s^E|$ m\ynDYuOQINqQ iQ}kK.t'HvT q" YF\r˟I',>=?FBr]Fy ^>Z ~ښzՑ]S5ĖfMA}`wY'81d!z ┡&9{rc27N˧-3zXmη7 È”Hrz9%$G0ka޺bַ6TdƆ&+qGD]\XpP^NC)U"O)b-(@b>’UnД+iͪ HO/>*@Rqp}$%$ou[%+SUj` FSov.!=ngGl$l~.-%ĬI$g`G/ 0 pc6UQ,))@ v( =v,wʣWǮ9@m<]{ߝnOӸֽyG>GOדT~~T*Lz @S p pS(:xN pOH xf D ZP(S pS p( pN@)$bN p8 QJh xODxO@)P)P8 P)x pb)OH x S(="D< @(h@4㧁@RJ(3N P( pNH xN pv(W^*WGع@m+St=uo^v~źUu;?bј~>]\oј~~>]@|zOERO_S~T(Hޔf;jqdgVx=ԖH̵`d~5\Sjҫms͵+ة2Y6<m9;5xDisHMl:~;W7+|KR: $^@$V"m7cf7jX;L}v㉍.U+d -=>\WKYd]-sѽꌶp9mpKvTpvL*̣5=>p}魗x(6+u6hKN> N@J)93ϝE tɣvcGN$rʡbWde$Z.Ӆxgzlp$\$\r/'ڌl}{9 İۏ,6]qA )j'9O (?Qai=>p|kcYZ`n.茦P 8x pFqU!jc-,8TRB$+G`Rs)ʅՍ̧$WXIR(*zg^@UsgI? M2([f~pӅ_t%frn;Dq <>d=c^Y76[e@yJ[F8Cgr ɎS/ھpӄ ^󇦭4*$Y~̉F\W#|4x9)eBI_%_lIP=Jّ j—WyzZ5 6ۛM2qĥJ+R|.Uukv:D8Dc-m3>~QʅՓ ONQVv2gCϓ(̙ Zdc9ZysEd I0| O8SڤEe oqIN{<ʅՍ̫g)+>QRXzTbiO>mֵ)RH}##ݑpʔevp. ڑcp9:0IZm[ufvɦWZrMzPB)<ԤA)ǃy&TME?d#qTq|=c^?7QdK81^cLZ|IJFI f~zۓ)*v!8HJ 9* [d)6VO[nmnܣZH ȐeygXOiWYd·k&$Q2r̊T} dȑ $U̎rC?Q! yݭk;fi[]q;Vʔ<`,G6C.efC[1iR)N ?sryQ4Tn>ig-6Hlk(DGXaJ6yg{Ť2n֋HIS&\U)2:b$nfGuϚhةEĒʼޙݭ@\Gs̜u׭M;4dIͱ6f@u)dN8>*T<1^jK)y]G#XIR#-qZc: =37UpߵK<77W%<^Lm&Muz#R`@Z7<\(s9,'Yom:v}K"2!S8Dⷄr9X}zNK|SiG>$±Ir%Gm.HݵlV68(ӷ)"×EZ^Y\*g \/i-Swo7OF5yv!wH`!_eH*P| qS4+Q_I !hxpPy%£v?ChoM/}{C^~bqV8 JuŐ9! 8*]dȷuA9&/Lw3aشmQ9U/bHSzEG'I~>vp.ۜHSh[)ad. HWۧi=1S.,\[2$!E<`AdČΝ`_OQh1qe[xBC|WB\tSmoܑ re*Pղ*^: vo;bTdm+S=u/>v~ź@Vz|tGFv=qFv-ũ]?PHxzoO*bc'z;l+k({eT) -lRt`J垽an }iy'P紎^.fmOWa[`-J&5]喛)8P[rcp*+J2d폴d>[mh2<,g NŻ1^^۽袄p_ݻ]r"CZ.$8RhUWn[wNEu2ŒC!ZSqRWʚ/t|z){bWr-t]P6$Ŵ6ؐZxĆ]BAt%K;(ZN@C'-7w]xn)Jd3%8c*3=+G} WB ԛ~ +յtʥ:r9m-lNKNV7Htk>CF۔ Z R`2SOV<#DurSG|W#^X%1.4[֓* }H_ͦE{M騺jDv*u(%7$GFӇU[\ $3-ز[}!!,ĭ&>R;(N@CaR|vCo^k˕&?tkRgPB|GU0V@p3EJ;-v5/E͛jrb\$/%V(6Bmd1S#N1&4X}ƝiJJZNRs#"lf-NşUZ.&%)(nPmĬV;1U'Ra!R*cOa{s8K{)*嬵5nz>#1*D?)dMlZ FÌE^&̒ꔢCeO:KBs$pSJEd)WFDg,BdHL`&n\F)b:*[T Ç4֚"i!pHa xa9HO%gj-]G cr %znOj2Cb]5=Tyj ?u2Z CQN1re[G:J# ຾*TINNlSS :\(A.ٙnQ.:qaEf\פ6 p.eD>fn4Ļ";>OuˍHPly\jWk^@xqܞidpI8&.ɒ㮺JQI$O2MK; %xď˻=;/-ӱIIG8Jꨧ3 U;̼{junRRVMP>*]T(uL[Zx@{PSN8ڐ`9_w8Gk%5k2`xCRG^1&4ueiqZYJZNRs#"nzW]!9/9$yW7mx J FGXRTߩg]);xJeLi!2]q!UyDxʸqİiBF켄(Xx){"8N~o^Ф1U1J2MXƤ+^,.m9΢S8_ *XJW$F Rv8,+l) *##S,QnQkz5h2̴Е~ 8 'r'U'G뛤8mT [q-$r#{>QS6Emk<[6N2I'$՝"3䖝!jN'jfMġO|<2Yu$wc^Om7; e9llFԩ<]{N*r[&Kdyjq]srZT(I$̓KѤ&2aVu6-*J A0kN)Vhj6H3%r A BյġJZRA$bnE<9!u]f2BP!I }H]Dr5:E/q*R]_Z7Gx6`} a)îg0hlwiO*]y*Uj)hx},quUFNͦW|J`J#aQ;o| _jXWt>&Ae M-,J@oJ R85_խZ"@è { fqYB:АR @QĺOfun,rr-RU`L!|CQղ[v5~oKo7@CH9 $3Y΀Ŵ)pPG0zp)Ґ/)l#9k<6%PgD$-#R3q֢6JSKVq(Jʎ1C=jW[Cg IPlz &{b#ڗeMwh#&[HAa8·=NJbט6 8=](*jy?>pT{rT':&MƑMO٭o0wT(R$IQ9d "%.4-VXˡ%"pq$É ^fjyn_>h'n\U: @q;I*n6l-lΘb-4)+@kpQly*]CJ[e`<6]Sk(q))*ZT7 &# Sr#M~YFX!1m}zCr\esS#jXPB#56D = d|a詐*.AN{\HAJ{WUb?NCJgQ[`Vz^|(F5:G _N׃S~~T*ӰԿU( ((S.&5o޷Fir~ 9H RpF_ED$ܤuXaﮢY:?xDmMlMR\(qnXCF-)YE<{k tap|+ZS*RSFhg]UQi3: pS x pN)x GwoWD)n! vך?`.'\ԑKc)eXZoUb3$O1MohVۅ"iRXҋl}J>J VLU nRٽ%+5\i펠s.sIDh oE"S%2y r59)m!bkiI,rG׺ǡkIWå.`^`;{ͥNOx+Kh3@~S]rétg+ٟ^tVpQPj8@ W%cI']ycY#R]Vq,ӀS pj)@ pN uGT\۵ShYT 0py䜒 ^ҩVն  n3IAPm ;R@ʏfjjU:#b4)#'>gSsj/c-&#ףG=&i$ 3i.f]l:BҤd(8@Vyz*m/6@9=XjV9+3nW&W]XpҠԾ{F\K 3rC$A @uX=aiϟŃJ2#^2u)y+uc(Va^T#nysN1S@ό]qZ7N/6qïU`Fl }E]c9]i?bgY(RB@ p$S =twuJ]7]Hd0t=to>v~u7 x("z6vk됺7kh:]?P`vz_*S@*lk<Αl'6Rdgɚף+[NR()'GUV[VeDY uw@ՠ'q8ܬgk6L—Qʩ A|-HrPx:̴"Wܻ+qL^2v4fZfZVoQ}2_Ovl6t:[2̐zҔicv{a|??.)@D(:p8 P)PW:ں9JB۴5:E (re )!žXNgZՑ tƍ5 HZV!P ݎ`cw?(IҦdpR|.p|xRG\+YtbtZ>^MGt*vm ]>}+uڝU{=}.yZvn^_Jhҥ(R\d>ڮH+L,c( j*Thor ;ɿtMݨ5|{c[V6Paی}~Vwn浙7۶uk)P8 5RN8 ҁK@ܧءΞ2#~0yC2El.nUO Nd01̼*‚b[n3Gj>piIJx"Ac?M`a<ʫ3=+ǍRe>: WskcVݹt}c1nmE|S|F*F4)@^ODxN( :VlҖ69k4F]}1jIF簲GpH?1ҷV siѭs􍩒Avuf:иR 8>Re^Uud( 7EIpyU33vΒ89ŷ&X[+VS:˄ekp+pՐN pR&)QrEN P(h#[ @:,Z/7A5v`H#2YFޜ)?6;Og=uʽ-ddc=E[) I=G V#%ƅVऴ>`r/jI HZ" g.dr񦤂A*mGZI>,L_bǿOx9% (Km7sOcT_P8[Kp|jrES)P8 B#'}*АϳQ\hϼyWTW,v_FգnգNcsR~T*ӐԟU6@1J(( pz^ݚEf[Td-+)!IRH'pJGgr:8 X'rI)tL  Qc=pSOM #$`LtZ p_u|,U&ypY8m9ֵ,dIY5\ P*(*pO)PiQN i ^7˨-o:j]+vO8 s*MS%:;Ekѕ&KT3RO˓^sEMB\uO hWO)PW捗8lsuoJꖸ }Q)Š[sA>JJS$9>_㺖lmq8erG5A ]y$6@*J:( xN P3@M-B@ndImGZԐR r>SQ!4>©QN9ֽ X?NQ͂:x3TGi#G<ş+F/Dg}G;mv 6K!Vd-+`PJF@xGUh P)@IR1m rEIF)P8 P)Pа%6O!~"nj+bn [q-G=n|ɀWW>өGMpV˱zk }4'M|R& V:^QQ$ʨ@SOҜ SS( v(B:wWT*ЧͳI\_μyWRW.t=s.آ~<XQJ~<XQ>mt'M8]IS@3N p: xN P( P)@ xN p RP3N@)RO@)RN P( pxP8 P1Jh ((PRODpN1N)P8 P)hbN pxN pN)@)Rp8 $RN)PS pN)bN)@*Ш̴+b㫗B2wW@tk"*$DV+ X@DW6t.vznZ@ٯQS&Blu)RH%@((`"I}EqjyN\cMڛ]iwJyT?($NŤ5uɽ{O5TǮ֣pBUϦពuOɶD%j!`u%C!) _v^tv~KrR ʥ8I[qIXJo뭘%trCb2)pڥ$$ Hܟ_jƯ(d_G=J޿\BEbZ4 |c+N[.)˃7ǒYA?){ FzԩCDS)ھq8\.@gQCܴ 'q%9R$ԕã!\Q6jKDS;J9<ߏk84*HH[qbDGkrȫfT:e*)kh~9R<IpaSRCz~~$Bv!-I[|V-`#x‘&tD2Rws3)WHR#ʸ[eFI!rTgKFTt)N,{%(IsXDmeEuH2aD!Kʷe\ǧAQv34w;_rtuR!ncP K̠{v%I'9Z@^u0>㉐e< BTVmIEbuﴰ!_$Ӷ rN xiʓ'WfjF 6kn; ^wAV9~3n0ݚ#w6RK&E!˪!90},~"F덝ɍ%%3^a,6 mnʁʁ'v?X? Opz ʹAf<{ʚ)$-%%,sRZe9 RP'؃nV?oޮ.;.K0ʒeE$IJxiyc\e5Klg[RPT()( 89 "a;q6`ciRҤ[ՒG>M e_${gd'qGZi?*S&W{ȏ܅]T"<u_p6KQJ./]ރa|HB#m.RB*<,8Xd)'~h[+v1@xɫ-ZvgJ{5 THJ[pKH-,%%KH#>[g{ Ecuh!J!hBR1'(ItSql,!@(H8,4\%<J}+u{)"|n%݆0mmkR ^F=6Еقw܏#,kjРpRFAA̸>KHCJHIRA i$vnOVbpڶsxm7V#c2O9::TYƝb˟qiKuav- BZ B%)9uV[S*"38ŸE/|\4cp\}Iv[m$8xNTR +vEJϽ2HXvLhX9S-$5;"QoSܟsm -8)M;qnJڒ:;Vb۵֕t⺦}TvTTw2lH׃sUojJE}N)ҷ)#a`*m ӠW{?b}d}^}/an6TdГ.;V!bI?=A39f~Λ([qlȒԅ:{"HRH|0 H2}2987BwQ!I=o}>UEfqrro6 :3mV6T ciEO<.0p9-; s=u+$EPUˡqh+xq`zZ<#eЗ4&>XK1+uժ9BG@s d֛T] C:z"| i[{#um~ZJvy4ѐnWl V>\u'˕m[Eadh Nv>0q*u`/8j㵫'McQ~T*`_U< B@.8jmԗ 4奢NOv>)q.$=D|o%e r}抾9"RF-;OM.dAKoP ]+7FAvliNd?eG.9 R=p#>AYsq#k,=Ey;:hv9 Ƕ #RսJexɼ\̻K~Q[p_ #>@a9q+V:euض[\okmْI<@$ `äCXVO+']-?$%q(iG +K B@J }7R )DyK0HqA?!Pǒ#4;UU~ v7T%䘭Q%Lk|xĖOHR * ^{]mȸMPBa;炒n(u(C~wN _3 oyr""JS)^q՟-WjٔZ.+ȉ ݷ\'|Z1!ˌKPXӏ(8N!HJ)*k^:?t{ g2?uߪ\8Ӓ2nכikuFh|M# 8mW)n=sjBlgdZ8pvun~> qbKK* O29̞MWHߖlrV$-ԴF-u$p).!%PI%Tlͺ[(DwИchՐPG0 G[ߖ2OUDTz)q! *+!I P'#Ϙ:jBTO1P*-2I5613m8.R3+JС%@I#*Izwou>/s?pXx~;04 n8AAW|y`cԷxU߻x jhpE<>6N^pfrnSFVPmQ ,iԥd'9':Xϔ҈SNf?=ʑ.c}.-YZ*QIwQƙ"sBS8@\4ry5A>NFp[ #rFr3JT:q:0ݶd}k7,S}WV)w7)ם=ٽ PR YWϟ0ֈklc4^JxlڈIV# u ϽZ:h&rntT}+N3Tq9Q-F >BJLlImǔI.pB`TvۚSq$BLN|g O,$)m6KD#m+$ZGW-PO=^˙". Qrc>!- $+ ysV_pWȐP1MG @BP( @$''ި":1 &̀pHBAD`"YǬ'ReɒFw{p,GN66\[Ħ#.z( mńk(JIPB$X/wJ22bDh,GCPR+pGn #"],ծjπY}!*)` 嫸m0St;cjUf9yFYLR/w62w7섆9-0[[*)Jvf]`!*[8vW[})E|OܧYsme:l^kK⣧# m@=]Qk)V`^IvD@\zV;bWM.2:n_vHu &XAquudo;_d3j}FWj}F`_U< t3ҶpB PJ8 ?h~ų̔#p=}gh 03[ȸ=c)jJ(;G36001ϳ;OO?A/~vas(j"G5-{W˖|uǗ'וWf$~J,>-^ i'mXV6x9]t p>^`bW$qBUы]N\vݷ-3Wn/!.W<^zj|enWpѱ pN pOJhs>r2&l#:IJG,Èw8&ѷc1V=΀y C'˃]M;X=fE};w#ġ]bR'IS%2?JV0)|g6qws8 P.!JV$۱myF J&IwU(*J!:: .q++)(rk_ʒ^M-uV J(4 P)@8 J8 P@Q[XBوmAF{J%i#8Ң}d`<W~G4KA#A<ەݤL$^/ɯ7ᔞIOǗ"J*=)9MWHĽ%lϷ-O`s?NO}*pXT־jcQvh@)P8 J.( pN@"E< @IHv=uugQ=4]MCT@S(4u/X5U;Jm FGQ`xP 4q )m şuCIW!7Fzͻ>U%7B\B6@HFG*yP8&K^"9ί?_-$}feZ\i$?:[$[/z;~/Aӷ>o'n VQ_Q&&\\)PqģrH #xk3]K˨V!~H*)^Ja< }Sᣗί6UKeo2 f:${Z(}%(4$i=b(ŵM&8x)pG#]&,rSUgImvDJ(+i8 P5i*э͛fi3K0rV+O` Q>Jw5r AFH[MF?q.(汄 kHljJ`-22'MA՝yq$~g5޹%;Ǐr?氖(Rڢխ:Ke vTwisR? dɺ) 檠tm7Er %3p) yd'⚳;j+rqQ\n+,\l =\$ -y.5)ܬxHM]b}q}S Ҋ "U[CR ;JjZ 0=3 Z8d)@ xT ʊP( pNc1:~kXp }k; ?4h/Ѩb\yËy)@r9[go!\jn1YˌL+>J厢|5,yF=ȗfT5+{-ZrS9CwsV;*-R1$YnV;J-&y (zz\enfy3^RP`BH 899Î[Y^/kS+ZSPCwU *Ƶy%X =0\kEm+Tt=qnvwGu%rVk]4]MCTj8Jz @ O(1@ )@@ @((]?@|zj*\:e: @ ) Е'Yy|v+RdES>*pI/)xlhLPSi^@8 @h/РS08|Sd C@` SyLDZk9jUzӊYziss6ٷ!E;oMgiUR;FY6\k p˼G >Z[۵IO#VzK:VvΪw+=˪O IIR\F¤œ'4LEBaݣ9&cXhbBq )IINYue5o$+ͦ LvLN9dFF|5Pݩ0\\nqVxŵ:Tf@Ô99)HkVgݣ[; (Q6ұPi G[W{6{L{oAj٦8N\([d4rxK쓎`dg+Ql"_ٳI:eҐ&RҴUX‘~GYcJqW rG) Qs*Q p fպuu{_TޮI mI=!1J: |`dg mhVۺ=qHöA\x,)[䫐IktXJ?dzp_"X)J *$rə޷o-Dtv8 ups[m2;]fZѭz][.*!Kp\ːU)JTIPw aJL%D~BuƸ*lFݭT7%KTFpws#! k5xJkp[mLHx5y,5 sSٯ50l%Z>F[6#n!8n`XW6)ȷ>pͶҝ1CZ FVjÙ5nR&MDNxǎO#!K@W<jxz;~jlޮs{M J ͵s@!AHG< ޤ˕wNR=K[6‚: a"AՙTޭb* 3adH'r3򳷝e77ԅE~jg&>ly1Ӫ9<.tۥjܷ[t||Q@Z4ڙfn_U}̸J0J%' pyxȩ)[Q1ؒ ᇖ҃n0VyԆڢ̻N=;stRRQD2N캩,eEe-} m#clqϯu`Iɦ%%gH6WI¢m{Twe;L-Ŵ,8@yddSز?@ۡCCϛ^j],šA PR׷j P ;R2Pr[?:=-%w)*}@H[A {p L\moE͕҅q;'h!͎! ;ve2D;4"{;-V&tN+KHV189PF"y]QO)بeZ0qxN ֋cq2cFf!Cj}3%J8S$X68ѪQwKZje R̭IJIN ܐ:sTApȍh LHR$x9DR ޶Gtܩ7f&Rm %)%ƖS<5MEɩβn 5K}N@RR0- ơ:B;eI;ZDVeM0q !X=I"SVi[JneY0H[J)O)s,AK{\{ \b-JJCr<+CCMݵ]=;Zd)A!KVђ fZM6Vr; ^䨇.9wvg-ߓV)+f4uo$qϪ3GZpoPl 2 F0X|w^V{SrW]5a-S)trѽO vd gmv>s$  q׻9巷< Wk]em=zfY[KqIBs$0k'X*Ѩ.3{!n$:_FSRA pN:st6{)LwjN){+nԎ A%!iꭱ.pOztKjaoKnn%ր qN% *:ڒ9VKt+la+1'x-Rd(+bB*i?B\Qe* 0k:aKIN#8N2=n{3xY:Kȵ𷤵1G%Bv%$,/'WP]KVZ m;fTg*[mY;ҕrX d򽶈Qk-ݷp:U}ͷ2"_@ĈjXDprTn *eBI~w~uU_D|#jZt>VU=pnv~kk4(nl>]/@pLc>TwL#:uUP eĸ(2yuN ձ(F.)RWYs6!y2j BЭB `".Kܼ]75 [TkxVNiƵ&j$T(.L{sR ًaH?=OǧS.ťUq4 ixN~o[ZGKG'Dm+)!)R u~8uǰ ~hp˧~Z^򊚾M:ִFj;20~~#Sb0;E|Sϐ؄_fJ9pPۜɌs)xM%"G8T8'VFDrO8QR} FRpLx)aK<G<d9Psde [e{W;W|)^*Ӛu=zI?^*='%W;3~pi{b\ D[:tN%X獹Iq`niGt 2'R {3~p󇦬S|"SS[qƶg'p= pT풕vm"9%`i G>ٜ Ak՘ Ӏ9#b+M{V)@lEW7si{q?OHӖ3\MU%i F6N:NIfGzkb7 w^f)*HН{Y=R϶R jz  㫐VUƞ*?;騭_h3`jܸ.W h-$8 1qN1Cb9S;fv;{ov>Jz{.9n7c\DVRr v,eX y g;`~o>Tzh9yң[M"708R฽$RN3 + jS!_JM/׸`S>Cb#tWYcǐveDy7[.3#8}(+K,%Id91Ř P*6F3|ңJ4?JMl)UԽ?JMMfq:q27κ+2ў5`WWiI8 ]H@)x( P)@@ )@uLv%+iFNs@^`ob*6' ٚjX!JH揇XیqĥDiDD\qR`r96]ǯ~Ǐ+o"Q?EW:C n6@9[ eX9n;+jV2m:Mm9I4=t68MX擸g:zk]*)P) 9W g5vp(G#444n '**y7x<FTW-.)w)I%6U)G 3ɾlbtm1IpkQ")@tlɹ=hAIt2«EN;vV:-db. ݌!l')RqO Ŵus\gW#]òj2nI}LqF.gg*:q v5dzLJ->ⴾ#iZT[M)#US@ެUhVKM,DIQP3^ lR9rv)x@8 ȁE8f(( ޏūPKNGSKV~I+o)-Kڸ؆Z [T*$K _D Ry]f gLE{krrTL3?Ub '}8>b|._o᧦$]R-GMi70$p)$QmMa <'83U{nyw7Ҕ%:99uWW%٧̲ф8 \R[J((S t]={nLQs.  Vm"tqSƎ ^0|d!6"0lgIL'UC ByzT᭢c5_^/98kagPr~Gh P6v1u^Ojm<7N6̷'z^Xt1ˬS((S pR@S__#fF79)l+Hibڿeds2H=bA[Cǘ'qHy!Cyuxg4GN7ed-NE˪H%8iD']CjJ\w `ֽܵfpwPi.% %i{;*ϹÁ=!f޾-@4R'K(b3H[  grgi_sİc5y=EG.Nyk0 )@()P( P(+gDuЖv\H~@;_g6n+8J8ߴ"(H[\qญ[Dz=BRMŴh2Nk`5|.9/2OgV/ڐ̈́n2o%( $ VQ|1MբF윜W04gp*^R >(B;rO sU~o_Yl4$PzLf1޻n!N=C'oY nmLӚKtXiQm[S pA (Vgϲ]UWECs@m0+Vt?~vkU뗝Eea=UۿQ8;}hBU}hBxS pOh)@@ )P((fS pN pN P( P)@Ӏ"7(H_FE/4*yxN/4){v_ѧND^T?Tu=[FS$ܕ ԑj97(KOW"6wGVԝyV(wdL=K܍)k_z͸w_uP aUa eCɑ im􄄭Iܨ@9A5% |z*!Z%ʍ(}RHWڇP28Ҋ$)*OQI G#Yr$Fl@)VM|o#BM#*"Cz6XVNe30=zpNDRⵏ\&R{Q4HoF U߈\2Q#i}U(Dm)biR< dCP;a|K8Tmہjj@a9q+V:P]੃S{XHm:aNڐq@LjbvMvbg^.47c#>yxwbuM2IOV*r:N/ݞ5**g:|bZ !ᒔl$2$]$bd5/OL8+Tf$JRO^ULwGOcPlIm7vte>F_˥=Ih +y6ָuʸ- %$#!Wt)$$+>ȏW;-c7jnyl 8)Da".Żhu(uh. s8 PybP]6*!s}aˈi؊إN)(Vjd OZ޷^i(uqSx@sĩcPei|reDy|n- B~ҰRS)sV,NQu + Dr%*Y+qy$'׹WŋcmJZla;VSH,*RywݲdʩVm$X\eEW5*ɼ96%G9C6<.:jwv{k#])*$; () VOaƓ|i\ӑLE6v@d7# j\e'h%$-vh>BҹqYq!Iᅨ)G v5#}\ҷ[Cw 76J|BIFv6Uw˔UESnFpEL&d!-)պRP~ū$3q^ѵ5=ۃoS1VmgH;-9)3!hnf_|$EҮ3]JKP@Q椶RXYΞ.d&4ȑf0IyVT-2swu4˷]9#PLvޤ!(dZ,B2w!GH##‰ #>cq*ڐun2͇RIuA.)AWJ#daZm6TEQ)@yT7oy`sj[btSpDbĺŐ䗖ĴqJJcQ\ߴ7i}B.DeO6 xB+$2Iu|,$6\V[%+H%9)K;dr"6K FF G4u&PYar9)dr䓓9*eKHA-뜙9r&"VwB ڐV1SʅcZnRtD/qg ㉌U];>=q^Ē KYYڷSοCzjnauփ<UҌv1M$Y,},VEW$T*zKm(mm)JnaGMtzb7Pζ1btDd8XHm BKvyh\ n.nH%ݒ.$6w15v#Kې܋C ԥ =dӶiۢC\gc51a;<0ps</#r&-/]^qgR8ym*P^)X=ukfiW!*c"O| ܮ-!o:"wezʘpH̔-A)(u OZGN39>/7vo߿n۞x1arPiAhKhIJFzd6L6Nn8VFk\UgQZ% eˆC h(-KX$n8ʹA˺e͹͓$"ꥪr$qK8 ˉJucd9o5oB6nSj#4-7`$)D Be->VƢʙC{B09ˬs <byjҷNdH5d[vr"fϝ%v!LpJma2R3dT#:մ[*9dF\Dpc0 m/)ԤJN9UdvGBZ4t␒BUa-d5)d-se/Y\m#7h\lCabJBs"Z˥ͷvxq6c.(pBuxp g/Tdȃ f;[8LEq{7 !JPmd)%{䗠ep[{Cn/hZ I:9y6zVΫĆ=2;wX7~A PIܕuuŊs uFE-}[ADRZ@Jp%I8 ȅPݝz]LE(␣BB/h5%;X$Z졷k2B ̈́yճXhnM,KL1Ⱥ~U=+I⑇޸>'MgS^H  ҕ%2 !jX$q=xv 8 I-szio?WS^H`wMHٴb t[Y┄eJ<^ ۝$l)2$+Jw#vpN)sXvcʶp:23دo9Ng<E)J6$cv<Rrfkj5r|Ł@Ĕg95Vwa9Zx Wcik)i@&N)P8 PG-y;i6='\ ?-4_uIJ I*_T=LVuɨE2e8Bw5NLaQ4SJ5=tHu[Gf?7%N'RTI8) A•hoSp5ΣMSb頻HTlytmw&W-\Xqե6(ݞX* S nPM*(NcRj5%r[i8 =$|@P(@ 9P0~l\ٝ,#RY 'vrY*Sn  41Z=KN~Ī%V+- *bw֕U[ZC2n,WvoO&G;K ZTxxJI {gJtqcX՜ pJj(fs-:[[=IBI'~pnb$c6RFBuTAt n*FwƐ<$͍e2HynpX!RUW<8bnEM JBs|^8[DeTzGXErU|Fr]b1py>MTo6gܒ7Ê.!͹NysTh[^k͵406u-3m;W6wRJ(PRJ(( prv8,(;K,4\WRP@J{TAKiJ GGUX7J@>jo -(_RoX_4߼v*fԦt缰t*fԮt缰v*fԶ/m;4?݊-}G};w|YPQkW%g@`wZV}y^){k0{kc( (((( (((( ((F?Mخ[D/vc9R1Ͽ>-ԬIhTVp^rJ>_ܷR%Z6U~_ܷR>-ԦxEk_>-ԣϥy)^eQUO7m2}l0H#>Z5DQP( (((( (((( (((( (((( (((( (((( (((( (zZ_T˾O$vyPFvt.~KM**YKHRi %Jg9-tvyqF\o$deHS3cWb!Di[q_Í!0; *ZA̓[UF -QTyQ} [2c8ӈI!!JJ)IQJB)ڈ KQ !)eEXV݊·+ޜ30 AvRܑ-oƌKMHCi8`ʖz̲1nI ^`5TdH;Si)NUrӘ/Y*Zsb\O0܎_m-Fg=Uf~ECpHyqQ!D$9ܠv9yr .ز!Ixi"8dG09 $6F3jU%qHtpm+BC{ex+#G)Zl Y@! 8>9D)W(O}F"DXu1J (or"S5+*jm9 $|庣zZr4Dr!JXLeB$,a 9l~Jj-?A=@m_[aȷx՗b9 hj's( ($((( (((( (((( (((( (((( (((( ((((<Ԛǧ)?9@fߺ!:>)1 8H-WϞ> VIUzVu'`C%?Uv7E+wI#vȆ'WP(4rsnV̷!KJdB}g6O;i!%KRRII")/=~/=~нsd6E}g6O;}g6O;{#zh^6Cj4W_V{d@_UGwBd I QmF裣zN|dw:`)$(H[+v (Q@QEQEEPQ@QEQEEPQ@QEQEEPQ@QEQEEPQ@QEQEEPQ@QEQEEPQ@QEחiK?3Z/u.= PR\AݴCnړ\4W9w9 !v<9>,Z74z|z)~>4RJ&9\V>jôtyuIKqʜχHK<3Tent+bսS>sDANȂpuԷH]S ,BȄSNT|ƍ= cwHpZYrIGOGvDEGA=dWk?H.wn%䧣>R:e_ʏ6+rwo @S1|HZIkc+ԛ!ICje.d6 j c)+$(D%$2jzDLuԶDR涂J:@s^QEE k:zxgv řmZHw.ё@LEc͝ #J^p 4 YEPTul-HPujqdxIH4V ZTIPrs65р*QEEPQ@x L}*]= :^PKj>xVp0]e"he]qĥkYmgCZJHʐ3T.>PZlVAUioavufFDʥa]t&Yjݱڶ#UB8 :RK'\:*f@)p#=Kٺ$-An_NOŠzZEEmA4RV9v9xny70plmi<>8)6|v|,yEkGQQ+M8Yh)j=jR'΅ϯXHT51IWf垯WӨ=g7IWcnT[d(TV@&&ߔ]dFTeD+oMa1Bu IV0ŝ.&d),Hq@ <4=B1k⨑h)N:8??nK?pM{\&YI@ԗJYMLt>–2 ~WGsR--I I )~MfiV($@dYϜ jQEEP K֡;SEz{q5@=c]zֲFU,Brb ?7`/GylHi]A)ZIJ|Dyj?QWbkn^UI#um͠ -l~Q\FdD;7!h%C@<㮸VꔥL=* 6#H T3<[3ou]#u+\+.1[WLOJ ov 'bjRD7]HuR ϓ*m%˳)&Zpuv[.9ZRßPHfyفP{9?^wa)C)AQX|Yj9ql3ci nUpT>P8@IHV9p2+IIC}AM<^Z—6k;f)W;p N>Ӎ3-eN6َd`UcrGEo_q+U/o{:]k:c)vaAAIH[hˢw~ t)mt&kC÷ɳmI83?k>dӍqq gmoh֞qrwwKbI O(^niXB䬖B1SN_a>/qUc k&~SUS# #n~-UF[ e8Q)x)$i?᭷r\pR(9 V ?e[KOSs]e OBȹo&3 !A%dؐqE9kHf>%IQʝRJzQ$׏A~fͨtӯD`O +AR>*j+WꤵiLGóKA( sȒysqklNFҬKmL%`a`F$HPBCg/ٌ|!Iq`[B]Zr2H ~$\~J2$^L26d  ߆ PRBr>:݃^\g؞\շL(iOR>AUKYᗧ_nN ^KZKj3Sjoh ݴ)'=oCgp]uWJmxܑ#T }[OQZHuY>z;[ g4y?=z6UZykiIueD u ۪i8uK[y2|>zW7Y93PΆeWBնd^kO nxj\7VkKfDgs"ygcd})Ah[`9'9DQ/GD K-ͫ<ÄmK 4,)̄.bBlh8 cV7o% :vG-Y*-;IkAuvƖ^v5sm! =V:vi~qK@`8l~韹綠M@UKm8h##=Fؔ\]4Hӯoֽ_`D"SA AOYN9ַPiMEQи)% %n?IsMCKQrC^Sn#JOX1'/ ts118R,`aYP6C_t tLqE`{[LdO,YRj! !@'cu;ȍ>S;S?h*-⫗Gڞ6Zv-˹be(IV)exzy:bŢӛu]}]iDxviD%%!Ps Wc6ұ(3Q~g6(kc΃#6’s4*Y)IV#WF-_S4r(RkzZS쇮g\|7!Ք,3UBȸ^'",V6zHǟmm5VKl\%CBI=e$]5^p%Me޶b)Ц8ؐFyq/ kntj41dIS -66n96Mj'l[`)QBύArkw ɮ94rKQEqL*.VP{v@gc0O$R})EjMN).y¯ ֿoE,8# PG`|ˬËH('wy,)ءsm >+oڻQ_ \:JAԞzB-ů(lwg?/ƾ³tɍwZH!?֦+5Iz"g %ABBQȭyOiն1Rdj>17(]m]OKΥ*Cͤ5.wI wC* F9[a.cV}jC)HPAAQ!]~Jd6pqC$_mQJ;xKY]KCOq|C -ut.=&L7Ri<wJ]bNe|G)SNJIU3u)RX@itX94K}J-^m(i .(ׁ뭘`ݦSiM*GRl3RP{ònq ZݍǯbjHMi/#Fa8k'Mv7|)޹vp$88?&Y2F/ԫ489/C#n}t?>+?k 9VˆqĠ~+V,.#ktգY\I4$M<<ظ'pdbeұҟO8~p+*h4/+7z}P@jϺwΓ$1seʰ:G*MԇT{J#:I |$VK6҄5 e|?Ω Jxb-GBgIe)j9RrI?d]<Ц?,tiBGPy@_W_W>x_35裥MArru-.V&tZo㭎LyX:{?$Md.]X}/PtGzZni3)qKyd<3ζvKĉ qp=x5gJ׽Aafz6XF6=T[1o6ˉqGk|,S=U/0l)|6|U7g֑/ִ\-qY#$`:fѳȏۮKIZxjV㔨{F] @$~J>M{#_[eM<$~=1^_5_܉ܔwz<6ʗ),-gp9OG,i=,:qᔄ)),k-AlwvRe)IId,yꉬ.B^!n$V˛nh7KaMiyt\qVI!HG!T{+p/bo-u4O9rS"0z4LMe֋۵ݣa+ ;Y|H=@q=FA9.]?~[4eqFҋ\H64-|[˜8$<.yQlGn R8=]\Y7"CqAzQHNNN;NOo9(muULIit~$֠Yi+qjI$<P#O|Tm(灌;ZkiqR㼱I)ur3Ӧ9j$dn >R}kSDZA=ۻ V{GaG޷5g6,nIW\֖a˖lYv]zqj"1|x 5{C֛N))$cnՊsK)?_o?MC^%yy VdݒҋFnnvXCh$sRqs8[ۣm_4v.7L;21I:Պ)}16W.jGP8يJmM4sjeY}}uk+ܮ-Yܵq#k; QKQzuw|ڂJo8 zkfqnmjBi85m(Ej%\LP[R,eE (J% @#]*tx:*r# 7@"VJʊ@#'Z4WIV3+gvYl x?M\jk<9Pj69H$((2 R)Up$%ѳZ3 6mgbya2AbmGٞ󫵕K6]iJRV;GYSz|q*SV+:0T| Ho[#j~!p5cy/RPUIzsU'd>ꊖ'']Vr(PIa[Ri֘i=IJTQOjI-2ŧl&k,m8*K.cP AT0Y6'YMWzךr^5|P;W.W*',gj,3sE-fCj8by=am'O_yGE_[&,R'8y zchi7 yq(jGeΑne1dHjlo,AK*NIF0<qҗE5l<ICmBFFG-Q^O~\T[FlCGc~ZOEWwMNb #H솙 PNg=x[MѴ 7cNG֪xӏ {QEq^/6B=]e{mV3ꉘʣL[n2R ۷9ɢM$Tʶ4kO ͲSȂٟTQQŲ"n:e#)SB3IPJ??u|RA㶲?"+hХ7 /SV{9XnD(K,~h1"tSqRҵ<>@V6vdr002~Z(3ytm l$SR Q$r $~f*#{]}(\CMduu}tQZFmҳ dgՊ1Ej)I'}EgaInyE