~ubuntu-branches/ubuntu/maverick/ekiga/maverick

« back to all changes in this revision

Viewing changes to lib/gui/gmtray/gmtray-win32.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2008-12-07 10:30:45 UTC
  • mfrom: (1.2.3 experimental)
  • Revision ID: james.westby@ubuntu.com-20081207103045-iaurrjo4p7d1nngo
Tags: 3.0.1-1ubuntu1
* Merge to Debian experimental, to get Ekiga 3. (LP: #274085) Remaining
  Ubuntu changes:
  - Launchpad Integration: (Ubuntu specific)
    + debian/control.in: Add liblaunchpad-integration-dev build dependency.
    + Add ubuntu_lpi.patch: Call launchpad_integration_add_items() in main() and
      check for the launchpad-integration pkg-config module.
    + Add autoconf.patch: autoconf changes from above patch.
  - Add ubuntu_desktop-file-onlyshowin.patch: Show ekiga in Mobile, too.
    (Ubuntu specific).
  - debian/control.in: Add missing fdupes build dependency for identical
    GNOME help file symlinking. (Debian #505536)
* Drop 42_change_pixmaps.dpatch: Many of the old icons do not exist any
  more, some have been replaced, and keeping the remaining three would make
  them look very inconsistent.
* Convert our dpatches to quilt patches and rewrite them for new upstream
  version.
* Add migrate_2.0_settings.patch: Properly migrate settings from
  2.0. Taken from upstream SVN, thanks to Damien Sandras!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/* Ekiga -- A VoIP and Video-Conferencing application
3
 
 * Copyright (C) 2000-2006 Damien Sandras
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software Foundation,
17
 
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18
 
 *
19
 
 *
20
 
 * Ekiga is licensed under the GPL license and as a special exception,
21
 
 * you have permission to link or otherwise combine this program with the
22
 
 * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
23
 
 * without applying the requirements of the GNU GPL to the OPAL, OpenH323
24
 
 * and PWLIB programs, as long as you do follow the requirements of the
25
 
 * GNU GPL for all the rest of the software thus combined.
26
 
 */
27
 
 
28
 
/*
29
 
 * Authors: Julien Puydt <jpuydt@free.fr>
30
 
 */
31
 
 
32
 
/*
33
 
 *                         gmtray-win32.c  -  description
34
 
 *                         ------------------------
35
 
 *   begin                : Sat Jan 7 2002
36
 
 *   copyright            : (C) 2000-2006 by Damien Sandras
37
 
 *   description          : Win32 implementation of the tray
38
 
 */
39
 
 
40
 
#define __GMTRAY_IMPLEMENTATION__
41
 
 
42
 
#include "../../../config.h"
43
 
 
44
 
#include <windows.h>
45
 
 
46
 
#include "gmtray-internal.h"
47
 
 
48
 
#include "pixbuf_to_hicon.h"
49
 
 
50
 
struct _GmTraySpecific
51
 
{
52
 
  NOTIFYICONDATA nid; /* this is the windows tray */
53
 
  GtkWidget *stupid_platform; /* we need this widget we never show to render
54
 
                               * the icons in it... */
55
 
};
56
 
 
57
 
 
58
 
/* helper functions */
59
 
 
60
 
/* this function will hide the popup menu when triggered by a timer
61
 
 * (this is because on win32, GTK+ doesn't hide a menu when the user goes
62
 
 * away -- thanks to the gaim project for that nice workaround !)
63
 
 */
64
 
static gboolean
65
 
popup_menu_hider (gpointer data)
66
 
{
67
 
  g_return_val_if_fail (GTK_IS_MENU (data), FALSE);
68
 
 
69
 
  gtk_menu_popdown (GTK_MENU (data));
70
 
 
71
 
  return FALSE;
72
 
}
73
 
 
74
 
 
75
 
/* this function checks if we leave/enter the popup menu, and decides to hide
76
 
 * it after some time if needed (this is because on win32, GTK+ doesn't hide a
77
 
 * menu when the user goes away -- thanks to the gaim project for that nice
78
 
 * workaround !)
79
 
 */
80
 
static gboolean
81
 
popup_menu_leave_enter_callback (GtkWidget *menu,
82
 
                                 GdkEventCrossing *event,
83
 
                                 gpointer data)
84
 
{
85
 
  static guint timer = 0;
86
 
 
87
 
  if (event->type == GDK_LEAVE_NOTIFY
88
 
      && event->detail == GDK_NOTIFY_ANCESTOR) {
89
 
 
90
 
    /* user is going away ! */
91
 
    if (timer == 0)
92
 
      timer = g_timeout_add (500, popup_menu_hider, (gpointer)menu);
93
 
 
94
 
  } else if (event->type == GDK_ENTER_NOTIFY
95
 
             && event->detail == GDK_NOTIFY_ANCESTOR) {
96
 
 
97
 
    /* wait ! Finally the user comes back ! */
98
 
    if (timer != 0) {
99
 
 
100
 
      (void)g_source_remove (timer);
101
 
      timer = 0;
102
 
    }
103
 
  }
104
 
}
105
 
 
106
 
/* this function receives events on the tray, and decides whether to call
107
 
 * the click callback, show the menu or ignore
108
 
 */
109
 
static LRESULT CALLBACK
110
 
message_handler (HWND hwnd,
111
 
                 UINT msg,
112
 
                 WPARAM wparam,
113
 
                 LPARAM lparam)
114
 
{
115
 
  GmTray *tray = NULL;
116
 
 
117
 
  tray = (GmTray *)wparam;
118
 
 
119
 
  if (msg == WM_USER) {
120
 
 
121
 
    if (lparam == WM_LBUTTONDOWN) {
122
 
 
123
 
      if (tray->left_clicked_callback)
124
 
        tray->left_clicked_callback (tray->left_clicked_callback_data);
125
 
    } else if (lparam == WM_MBUTTONDOWN) {
126
 
 
127
 
      if (tray->middle_clicked_callback)
128
 
        tray->middle_clicked_callback (tray->middle_clicked_callback_data);
129
 
    } else if (lparam == WM_RBUTTONDOWN) {
130
 
 
131
 
      gmtray_menu (tray);
132
 
    }
133
 
    return 0;
134
 
  }
135
 
 
136
 
  return DefWindowProc (hwnd, msg, wparam, lparam);
137
 
}
138
 
 
139
 
 
140
 
/* creates a sort of win32 event box, associated with
141
 
 * our message callback function
142
 
 */
143
 
static HWND
144
 
create_message_window ()
145
 
{
146
 
  WNDCLASS wclass;
147
 
  ATOM klass;
148
 
  HINSTANCE hmodule = GetModuleHandle (NULL);
149
 
 
150
 
  memset (&wclass, 0, sizeof (WNDCLASS));
151
 
  wclass.lpszClassName = PACKAGE_NAME "-tray";
152
 
  wclass.lpfnWndProc = message_handler;
153
 
 
154
 
  klass = RegisterClass (&wclass);
155
 
 
156
 
  return CreateWindow (MAKEINTRESOURCE (klass), NULL, WS_POPUP,
157
 
                       0, 0, 1, 1, NULL, NULL,
158
 
                       hmodule, NULL);
159
 
 
160
 
}
161
 
 
162
 
 
163
 
/* public api implementation */
164
 
 
165
 
 
166
 
GmTray *
167
 
gmtray_new (const gchar *image)
168
 
{
169
 
  GmTray    *result = NULL;
170
 
  GdkPixbuf *pixbuf = NULL;
171
 
  GtkWidget *stupid = NULL;
172
 
 
173
 
  stupid = gtk_label_new ("");
174
 
  pixbuf = gtk_widget_render_icon (stupid, image,
175
 
                                   GTK_ICON_SIZE_MENU, NULL);
176
 
 
177
 
  result = gmtray_new_common (image);
178
 
 
179
 
  result->specific = g_new (GmTraySpecific, 1);
180
 
 
181
 
  result->specific->stupid_platform = stupid;
182
 
 
183
 
  memset (&result->specific->nid, 0, sizeof (result->specific->nid));
184
 
  result->specific->nid.hWnd = create_message_window ();
185
 
  result->specific->nid.uID = GPOINTER_TO_UINT (result);
186
 
  result->specific->nid.uCallbackMessage = WM_USER;
187
 
  result->specific->nid.uFlags = NIF_ICON | NIF_MESSAGE;
188
 
  result->specific->nid.hIcon = _gdk_win32_pixbuf_to_hicon (pixbuf);
189
 
 
190
 
  Shell_NotifyIcon (NIM_ADD, &result->specific->nid);
191
 
 
192
 
  g_object_unref (pixbuf);
193
 
 
194
 
  return result;
195
 
}
196
 
 
197
 
 
198
 
void
199
 
gmtray_delete (GmTray *tray)
200
 
{
201
 
  g_return_if_fail (tray != NULL);
202
 
 
203
 
  gtk_widget_destroy (tray->specific->stupid_platform);
204
 
  Shell_NotifyIcon (NIM_DELETE, &tray->specific->nid);
205
 
  g_free (tray->specific);
206
 
  gmtray_delete_common (tray);
207
 
}
208
 
 
209
 
 
210
 
void
211
 
gmtray_show_image (GmTray *tray,
212
 
                   const gchar *image)
213
 
{
214
 
  GdkPixbuf *pixbuf = NULL;
215
 
 
216
 
  g_return_if_fail (tray != NULL);
217
 
 
218
 
  pixbuf = gtk_widget_render_icon (tray->specific->stupid_platform,
219
 
                                   image, GTK_ICON_SIZE_MENU, NULL);
220
 
 
221
 
  tray->specific->nid.hIcon = _gdk_win32_pixbuf_to_hicon (pixbuf);
222
 
  tray->specific->nid.uFlags |= NIF_ICON;
223
 
 
224
 
  Shell_NotifyIcon (NIM_MODIFY, &tray->specific->nid);
225
 
 
226
 
  g_object_unref (pixbuf);
227
 
}
228
 
 
229
 
 
230
 
void
231
 
gmtray_menu (GmTray *tray)
232
 
{
233
 
  GtkMenu *menu = NULL;
234
 
 
235
 
  g_return_if_fail (tray != NULL);
236
 
 
237
 
  if (tray->menu_callback == NULL)
238
 
    return;
239
 
 
240
 
  menu = tray->menu_callback (tray->menu_callback_data);
241
 
 
242
 
  gtk_widget_show_all (GTK_WIDGET (menu));
243
 
 
244
 
  g_signal_connect (menu, "leave-notify-event",
245
 
                    G_CALLBACK(popup_menu_leave_enter_callback), NULL);
246
 
  g_signal_connect (menu, "enter-notify-event",
247
 
                    G_CALLBACK(popup_menu_leave_enter_callback), NULL);
248
 
 
249
 
  gtk_menu_popup (menu, NULL, NULL, NULL, NULL,
250
 
                  0, gtk_get_current_event_time ());
251
 
}