]> Pileus Git - ~andy/gtk/blob - gtk/gtkstatusicon.c
Fix the build
[~andy/gtk] / gtk / gtkstatusicon.c
1 /* gtkstatusicon.c:
2  *
3  * Copyright (C) 2003 Sun Microsystems, Inc.
4  * Copyright (C) 2005 Hans Breuer <hans@breuer.org>
5  * Copyright (C) 2005 Novell, Inc.
6  * Copyright (C) 2006 Imendio AB
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  *
23  * Authors:
24  *      Mark McLoughlin <mark@skynet.ie>
25  *      Hans Breuer <hans@breuer.org>
26  *      Tor Lillqvist <tml@novell.com>
27  *      Mikael Hallendal <micke@imendio.com>
28  */
29
30 #include <config.h>
31 #include <string.h>
32
33 #include "gtkstatusicon.h"
34
35 #include "gtkintl.h"
36 #include "gtkiconfactory.h"
37 #include "gtkmarshalers.h"
38 #include "gtktrayicon.h"
39
40 #include "gtkprivate.h"
41 #include "gtkwidget.h"
42
43 #ifdef GDK_WINDOWING_WIN32
44 #include "gtkicontheme.h"
45 #include "gtklabel.h"
46
47 #include "win32/gdkwin32.h"
48 #define WM_GTK_TRAY_NOTIFICATION (WM_USER+1)
49 #endif
50
51 #ifdef GDK_WINDOWING_QUARTZ
52 #include "gtkicontheme.h"
53 #include "gtklabel.h"
54 #endif  
55
56 #include "gdkkeysyms.h"
57
58 #include "gtkalias.h"
59
60 #define BLINK_TIMEOUT 500
61
62 enum
63 {
64   PROP_0,
65   PROP_PIXBUF,
66   PROP_FILE,
67   PROP_STOCK,
68   PROP_ICON_NAME,
69   PROP_STORAGE_TYPE,
70   PROP_SIZE,
71   PROP_SCREEN,
72   PROP_VISIBLE,
73   PROP_ORIENTATION,
74   PROP_EMBEDDED,
75   PROP_BLINKING
76 };
77
78 enum 
79 {
80   ACTIVATE_SIGNAL,
81   POPUP_MENU_SIGNAL,
82   SIZE_CHANGED_SIGNAL,
83   LAST_SIGNAL
84 };
85
86 static guint status_icon_signals [LAST_SIGNAL] = { 0 };
87
88 #ifdef GDK_WINDOWING_QUARTZ
89 #include "gtkstatusicon-quartz.c"
90 #endif
91
92 struct _GtkStatusIconPrivate
93 {
94 #ifdef GDK_WINDOWING_X11
95   GtkWidget    *tray_icon;
96   GtkWidget    *image;
97 #endif
98
99 #ifdef GDK_WINDOWING_WIN32
100   GtkWidget     *dummy_widget;
101   NOTIFYICONDATAW nid;
102   gint          last_click_x, last_click_y;
103   GtkOrientation orientation;
104 #endif
105         
106 #ifdef GDK_WINDOWING_QUARTZ
107   GtkWidget     *dummy_widget;
108   GtkQuartzStatusIcon *status_item;
109 #endif
110
111   gint          size;
112
113   gint          image_width;
114   gint          image_height;
115
116   GtkImageType  storage_type;
117
118   union
119     {
120       GdkPixbuf *pixbuf;
121       gchar     *stock_id;
122       gchar     *icon_name;
123     } image_data;
124
125   GdkPixbuf    *blank_icon;
126   guint         blinking_timeout;
127
128   guint         blinking : 1;
129   guint         blink_off : 1;
130   guint         visible : 1;
131 };
132
133 static GObject* gtk_status_icon_constructor      (GType                  type,
134                                                   guint                  n_construct_properties,
135                                                   GObjectConstructParam *construct_params);
136 static void     gtk_status_icon_finalize         (GObject        *object);
137 static void     gtk_status_icon_set_property     (GObject        *object,
138                                                   guint           prop_id,
139                                                   const GValue   *value,
140                                                   GParamSpec     *pspec);
141 static void     gtk_status_icon_get_property     (GObject        *object,
142                                                   guint           prop_id,
143                                                   GValue         *value,
144                                                   GParamSpec     *pspec);
145
146 #ifdef GDK_WINDOWING_X11
147 static void     gtk_status_icon_size_allocate    (GtkStatusIcon  *status_icon,
148                                                   GtkAllocation  *allocation);
149 static void     gtk_status_icon_screen_changed   (GtkStatusIcon  *status_icon,
150                                                   GdkScreen      *old_screen);
151 static void     gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon);
152 static void     gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon);
153
154 #endif
155 static gboolean gtk_status_icon_key_press        (GtkStatusIcon  *status_icon,
156                                                   GdkEventKey    *event);
157 static void     gtk_status_icon_popup_menu       (GtkStatusIcon  *status_icon);
158 static gboolean gtk_status_icon_button_press     (GtkStatusIcon  *status_icon,
159                                                   GdkEventButton *event);
160 static void     gtk_status_icon_disable_blinking (GtkStatusIcon  *status_icon);
161 static void     gtk_status_icon_reset_image_data (GtkStatusIcon  *status_icon);
162                                            
163
164 G_DEFINE_TYPE (GtkStatusIcon, gtk_status_icon, G_TYPE_OBJECT)
165
166 static void
167 gtk_status_icon_class_init (GtkStatusIconClass *class)
168 {
169   GObjectClass *gobject_class = (GObjectClass *) class;
170
171   gobject_class->constructor  = gtk_status_icon_constructor;
172   gobject_class->finalize     = gtk_status_icon_finalize;
173   gobject_class->set_property = gtk_status_icon_set_property;
174   gobject_class->get_property = gtk_status_icon_get_property;
175
176   g_object_class_install_property (gobject_class,
177                                    PROP_PIXBUF,
178                                    g_param_spec_object ("pixbuf",
179                                                         P_("Pixbuf"),
180                                                         P_("A GdkPixbuf to display"),
181                                                         GDK_TYPE_PIXBUF,
182                                                         GTK_PARAM_READWRITE));
183
184   g_object_class_install_property (gobject_class,
185                                    PROP_FILE,
186                                    g_param_spec_string ("file",
187                                                         P_("Filename"),
188                                                         P_("Filename to load and display"),
189                                                         NULL,
190                                                         GTK_PARAM_WRITABLE));
191
192   g_object_class_install_property (gobject_class,
193                                    PROP_STOCK,
194                                    g_param_spec_string ("stock",
195                                                         P_("Stock ID"),
196                                                         P_("Stock ID for a stock image to display"),
197                                                         NULL,
198                                                         GTK_PARAM_READWRITE));
199   
200   g_object_class_install_property (gobject_class,
201                                    PROP_ICON_NAME,
202                                    g_param_spec_string ("icon-name",
203                                                         P_("Icon Name"),
204                                                         P_("The name of the icon from the icon theme"),
205                                                         NULL,
206                                                         GTK_PARAM_READWRITE));
207   
208   g_object_class_install_property (gobject_class,
209                                    PROP_STORAGE_TYPE,
210                                    g_param_spec_enum ("storage-type",
211                                                       P_("Storage type"),
212                                                       P_("The representation being used for image data"),
213                                                       GTK_TYPE_IMAGE_TYPE,
214                                                       GTK_IMAGE_EMPTY,
215                                                       GTK_PARAM_READABLE));
216
217   g_object_class_install_property (gobject_class,
218                                    PROP_SIZE,
219                                    g_param_spec_int ("size",
220                                                      P_("Size"),
221                                                      P_("The size of the icon"),
222                                                      0,
223                                                      G_MAXINT,
224                                                      0,
225                                                      GTK_PARAM_READABLE));
226
227   g_object_class_install_property (gobject_class,
228                                    PROP_SCREEN,
229                                    g_param_spec_object ("screen",
230                                                         P_("Screen"),
231                                                         P_("The screen where this status icon will be displayed"),
232                                                         GDK_TYPE_SCREEN,
233                                                         GTK_PARAM_READWRITE));
234
235   g_object_class_install_property (gobject_class,
236                                    PROP_BLINKING,
237                                    g_param_spec_boolean ("blinking",
238                                                          P_("Blinking"),
239                                                          P_("Whether or not the status icon is blinking"),
240                                                          FALSE,
241                                                          GTK_PARAM_READWRITE));
242
243   g_object_class_install_property (gobject_class,
244                                    PROP_VISIBLE,
245                                    g_param_spec_boolean ("visible",
246                                                          P_("Visible"),
247                                                          P_("Whether or not the status icon is visible"),
248                                                          TRUE,
249                                                          GTK_PARAM_READWRITE));
250
251
252   /**
253    * GtkStatusIcon:embedded: 
254    *
255    * %TRUE if the statusicon is embedded in a notification area.
256    *
257    * Since: 2.12
258    */
259   g_object_class_install_property (gobject_class,
260                                    PROP_EMBEDDED,
261                                    g_param_spec_boolean ("embedded",
262                                                          P_("Embedded"),
263                                                          P_("Whether or not the status icon is embedded"),
264                                                          FALSE,
265                                                          GTK_PARAM_READABLE));
266
267   /**
268    * GtkStatusIcon:orientation:
269    *
270    * The orientation of the tray in which the statusicon 
271    * is embedded. 
272    *
273    * Since: 2.12
274    */
275   g_object_class_install_property (gobject_class,
276                                    PROP_ORIENTATION,
277                                    g_param_spec_enum ("orientation",
278                                                       P_("Orientation"),
279                                                       P_("The orientation of the tray"),
280                                                       GTK_TYPE_ORIENTATION,
281                                                       GTK_ORIENTATION_HORIZONTAL,
282                                                       GTK_PARAM_READABLE));
283
284
285   /**
286    * GtkStatusIcon::activate:
287    * @status_icon: the object which received the signal
288    *
289    * Gets emitted when the user activates the status icon. 
290    * If and how status icons can activated is platform-dependent.
291    *
292    * Since: 2.10
293    */
294   status_icon_signals [ACTIVATE_SIGNAL] =
295     g_signal_new (I_("activate"),
296                   G_TYPE_FROM_CLASS (gobject_class),
297                   G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
298                   G_STRUCT_OFFSET (GtkStatusIconClass, activate),
299                   NULL,
300                   NULL,
301                   g_cclosure_marshal_VOID__VOID,
302                   G_TYPE_NONE,
303                   0);
304
305   /**
306    * GtkStatusIcon::popup-menu:
307    * @status_icon: the object which received the signal
308    * @button: the button that was pressed, or 0 if the 
309    *   signal is not emitted in response to a button press event
310    * @activate_time: the timestamp of the event that
311    *   triggered the signal emission
312    *
313    * Gets emitted when the user brings up the context menu
314    * of the status icon. Whether status icons can have context 
315    * menus and how these are activated is platform-dependent.
316    *
317    * The @button and @activate_timeout parameters should be 
318    * passed as the last to arguments to gtk_menu_popup().
319    *
320    * Since: 2.10
321    */
322   status_icon_signals [POPUP_MENU_SIGNAL] =
323     g_signal_new (I_("popup_menu"),
324                   G_TYPE_FROM_CLASS (gobject_class),
325                   G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
326                   G_STRUCT_OFFSET (GtkStatusIconClass, popup_menu),
327                   NULL,
328                   NULL,
329                   _gtk_marshal_VOID__UINT_UINT,
330                   G_TYPE_NONE,
331                   2,
332                   G_TYPE_UINT,
333                   G_TYPE_UINT);
334
335   /**
336    * GtkStatusIcon::size-changed:
337    * @status_icon: the object which received the signal
338    * @size: the new size
339    *
340    * Gets emitted when the size available for the image
341    * changes, e.g. because the notification area got resized.
342    *
343    * Return value: %TRUE if the icon was updated for the new
344    * size. Otherwise, GTK+ will scale the icon as necessary.
345    *
346    * Since: 2.10
347    */
348   status_icon_signals [SIZE_CHANGED_SIGNAL] =
349     g_signal_new (I_("size_changed"),
350                   G_TYPE_FROM_CLASS (gobject_class),
351                   G_SIGNAL_RUN_LAST,
352                   G_STRUCT_OFFSET (GtkStatusIconClass, size_changed),
353                   g_signal_accumulator_true_handled,
354                   NULL,
355                   _gtk_marshal_BOOLEAN__INT,
356                   G_TYPE_BOOLEAN,
357                   1,
358                   G_TYPE_INT);
359
360   g_type_class_add_private (class, sizeof (GtkStatusIconPrivate));
361 }
362
363 #ifdef GDK_WINDOWING_WIN32
364
365 static void
366 build_button_event (GtkStatusIconPrivate *priv,
367                     GdkEventButton       *e,
368                     guint                 button)
369 {
370   POINT pos;
371   GdkRectangle monitor0;
372
373   /* We know that gdk/win32 puts the primary monitor at index 0 */
374   gdk_screen_get_monitor_geometry (gdk_screen_get_default (), 0, &monitor0);
375   e->window = g_object_ref (gdk_get_default_root_window ());
376   e->send_event = TRUE;
377   e->time = GetTickCount ();
378   GetCursorPos (&pos);
379   priv->last_click_x = e->x = pos.x + monitor0.x;
380   priv->last_click_y = e->y = pos.y + monitor0.y;
381   e->axes = NULL;
382   e->state = 0;
383   e->button = button;
384   e->device = gdk_display_get_default ()->core_pointer;
385   e->x_root = e->x;
386   e->y_root = e->y;
387 }
388
389 typedef struct
390 {
391   GtkStatusIcon *status_icon;
392   GdkEventButton *event;
393 } ButtonCallbackData;
394
395 static gboolean
396 button_callback (gpointer data)
397 {
398   ButtonCallbackData *bc = (ButtonCallbackData *) data;
399
400   gtk_status_icon_button_press (bc->status_icon, bc->event);
401
402   gdk_event_free ((GdkEvent *) bc->event);
403   g_free (data);
404
405   return FALSE;
406 }
407
408 static LRESULT CALLBACK
409 wndproc (HWND   hwnd,
410          UINT   message,
411          WPARAM wparam,
412          LPARAM lparam)
413 {
414   if (message == WM_GTK_TRAY_NOTIFICATION)
415     {
416       ButtonCallbackData *bc;
417       
418       switch (lparam)
419         {
420         case WM_LBUTTONDOWN:
421         case WM_RBUTTONDOWN:
422           bc = g_new (ButtonCallbackData, 1);
423           bc->event = (GdkEventButton *) gdk_event_new (GDK_BUTTON_PRESS);
424           bc->status_icon = GTK_STATUS_ICON (wparam);
425           build_button_event (bc->status_icon->priv, bc->event, (lparam == WM_LBUTTONDOWN) ? 1 : 3);
426           g_idle_add (button_callback, bc);
427           break;
428         default :
429           break;
430         }
431         return 0;
432     }
433   else
434     {
435       return DefWindowProc (hwnd, message, wparam, lparam);
436     }
437 }
438
439 static HWND
440 create_tray_observer (void)
441 {
442   WNDCLASS    wclass;
443   static HWND hwnd = NULL;
444   ATOM        klass;
445   HINSTANCE   hmodule = GetModuleHandle (NULL);
446
447   if (hwnd)
448     return hwnd;
449
450   memset (&wclass, 0, sizeof(WNDCLASS));
451   wclass.lpszClassName = "gtkstatusicon-observer";
452   wclass.lpfnWndProc   = wndproc;
453   wclass.hInstance     = hmodule;
454
455   klass = RegisterClass (&wclass);
456   if (!klass)
457     return NULL;
458
459   hwnd = CreateWindow (MAKEINTRESOURCE(klass),
460                        NULL, WS_POPUP,
461                        0, 0, 1, 1, NULL, NULL,
462                        hmodule, NULL);
463   if (!hwnd)
464     {
465       UnregisterClass (MAKEINTRESOURCE(klass), hmodule);
466       return NULL;
467     }
468
469   return hwnd;
470 }
471
472 #endif
473
474 static void
475 gtk_status_icon_init (GtkStatusIcon *status_icon)
476 {
477   GtkStatusIconPrivate *priv;
478
479   priv = G_TYPE_INSTANCE_GET_PRIVATE (status_icon, GTK_TYPE_STATUS_ICON,
480                                       GtkStatusIconPrivate);
481   status_icon->priv = priv;
482   
483   priv->storage_type = GTK_IMAGE_EMPTY;
484   priv->visible      = TRUE;
485
486 #ifdef GDK_WINDOWING_X11
487   priv->size         = 0;
488   priv->image_width  = 0;
489   priv->image_height = 0;
490
491   priv->tray_icon = GTK_WIDGET (_gtk_tray_icon_new (NULL));
492
493   gtk_widget_add_events (GTK_WIDGET (priv->tray_icon),
494                          GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
495
496   g_signal_connect_swapped (priv->tray_icon, "key-press-event",
497                             G_CALLBACK (gtk_status_icon_key_press), status_icon);
498   g_signal_connect_swapped (priv->tray_icon, "popup-menu",
499                             G_CALLBACK (gtk_status_icon_popup_menu), status_icon);
500   g_signal_connect_swapped (priv->tray_icon, "notify::embedded",
501                             G_CALLBACK (gtk_status_icon_embedded_changed), status_icon);
502   g_signal_connect_swapped (priv->tray_icon, "notify::orientation",
503                             G_CALLBACK (gtk_status_icon_orientation_changed), status_icon);
504   g_signal_connect_swapped (priv->tray_icon, "button-press-event",
505                             G_CALLBACK (gtk_status_icon_button_press), status_icon);
506   g_signal_connect_swapped (priv->tray_icon, "screen-changed",
507                             G_CALLBACK (gtk_status_icon_screen_changed), status_icon);
508   priv->image = gtk_image_new ();
509   GTK_WIDGET_SET_FLAGS (priv->image, GTK_CAN_FOCUS);
510   gtk_container_add (GTK_CONTAINER (priv->tray_icon), priv->image);
511   gtk_widget_show (priv->image);
512
513   g_signal_connect_swapped (priv->image, "size-allocate",
514                             G_CALLBACK (gtk_status_icon_size_allocate), status_icon);
515
516 #endif
517
518 #ifdef GDK_WINDOWING_WIN32
519
520   /* Get position and orientation of Windows taskbar. */
521   {
522     APPBARDATA abd;
523     
524     abd.cbSize = sizeof (abd);
525     SHAppBarMessage (ABM_GETTASKBARPOS, &abd);
526     if (abd.rc.bottom - abd.rc.top > abd.rc.right - abd.rc.left)
527       priv->orientation = GTK_ORIENTATION_VERTICAL;
528     else
529       priv->orientation = GTK_ORIENTATION_HORIZONTAL;
530   }
531
532   priv->last_click_x = priv->last_click_y = 0;
533
534   /* Are the system tray icons always 16 pixels square? */
535   priv->size         = 16;
536   priv->image_width  = 16;
537   priv->image_height = 16;
538
539   priv->dummy_widget = gtk_label_new ("");
540
541   memset (&priv->nid, 0, sizeof (priv->nid));
542
543   priv->nid.hWnd = create_tray_observer ();
544   priv->nid.uID = GPOINTER_TO_UINT (status_icon);
545   priv->nid.uCallbackMessage = WM_GTK_TRAY_NOTIFICATION;
546   priv->nid.uFlags = NIF_MESSAGE;
547
548   if (!Shell_NotifyIconW (NIM_ADD, &priv->nid))
549     {
550       g_warning ("%s:%d:Shell_NotifyIcon(NIM_ADD) failed", __FILE__, __LINE__-2);
551       priv->nid.hWnd = NULL;
552     }
553 #endif
554         
555 #ifdef GDK_WINDOWING_QUARTZ
556   priv->dummy_widget = gtk_label_new ("");
557
558   QUARTZ_POOL_ALLOC;
559
560   priv->status_item = [[GtkQuartzStatusIcon alloc] initWithStatusIcon:status_icon];
561
562   priv->image_width = priv->image_height = [priv->status_item getHeight];
563   priv->size = priv->image_height;
564
565   QUARTZ_POOL_RELEASE;
566
567 #endif 
568 }
569
570 static GObject*
571 gtk_status_icon_constructor (GType                  type,
572                              guint                  n_construct_properties,
573                              GObjectConstructParam *construct_params)
574 {
575   GObject *object;
576   GtkStatusIcon *status_icon;
577   GtkStatusIconPrivate *priv;
578   
579   object = G_OBJECT_CLASS (gtk_status_icon_parent_class)->constructor (type,
580                                                                        n_construct_properties,
581                                                                        construct_params);
582
583 #ifdef GDK_WINDOWING_X11
584   status_icon = GTK_STATUS_ICON (object);
585   priv = status_icon->priv;
586   
587   if (priv->visible)
588     gtk_widget_show (priv->tray_icon);
589 #endif
590
591   return object;
592 }
593
594 static void
595 gtk_status_icon_finalize (GObject *object)
596 {
597   GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
598   GtkStatusIconPrivate *priv = status_icon->priv;
599
600   gtk_status_icon_disable_blinking (status_icon);
601   
602   gtk_status_icon_reset_image_data (status_icon);
603
604   if (priv->blank_icon)
605     g_object_unref (priv->blank_icon);
606   priv->blank_icon = NULL;
607
608 #ifdef GDK_WINDOWING_X11
609   gtk_widget_destroy (priv->tray_icon);
610 #endif
611
612 #ifdef GDK_WINDOWING_WIN32
613   if (priv->nid.hWnd != NULL && priv->visible)
614     Shell_NotifyIconW (NIM_DELETE, &priv->nid);
615   if (priv->nid.hIcon)
616     DestroyIcon (priv->nid.hIcon);
617
618   gtk_widget_destroy (priv->dummy_widget);
619 #endif
620         
621 #ifdef GDK_WINDOWING_QUARTZ
622   QUARTZ_POOL_ALLOC;
623   [priv->status_item release];
624   QUARTZ_POOL_RELEASE;
625 #endif
626
627   G_OBJECT_CLASS (gtk_status_icon_parent_class)->finalize (object);
628 }
629
630 static void
631 gtk_status_icon_set_property (GObject      *object,
632                               guint         prop_id,
633                               const GValue *value,
634                               GParamSpec   *pspec)
635 {
636   GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
637
638   switch (prop_id)
639     {
640     case PROP_PIXBUF:
641       gtk_status_icon_set_from_pixbuf (status_icon, g_value_get_object (value));
642       break;
643     case PROP_FILE:
644       gtk_status_icon_set_from_file (status_icon, g_value_get_string (value));
645       break;
646     case PROP_STOCK:
647       gtk_status_icon_set_from_stock (status_icon, g_value_get_string (value));
648       break;
649     case PROP_ICON_NAME:
650       gtk_status_icon_set_from_icon_name (status_icon, g_value_get_string (value));
651       break;
652     case PROP_SCREEN:
653       gtk_status_icon_set_screen (status_icon, g_value_get_object (value));
654       break;
655     case PROP_BLINKING:
656       gtk_status_icon_set_blinking (status_icon, g_value_get_boolean (value));
657       break;
658     case PROP_VISIBLE:
659       gtk_status_icon_set_visible (status_icon, g_value_get_boolean (value));
660       break;
661     default:
662       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
663       break;
664     }
665 }
666
667 static void
668 gtk_status_icon_get_property (GObject    *object,
669                               guint       prop_id,
670                               GValue     *value,
671                               GParamSpec *pspec)
672 {
673   GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
674   GtkStatusIconPrivate *priv = status_icon->priv;
675
676   /* The "getter" functions whine if you try to get the wrong
677    * storage type. This function is instead robust against that,
678    * so that GUI builders don't have to jump through hoops
679    * to avoid g_warning
680    */
681
682   switch (prop_id)
683     {
684     case PROP_PIXBUF:
685       if (priv->storage_type != GTK_IMAGE_PIXBUF)
686         g_value_set_object (value, NULL);
687       else
688         g_value_set_object (value, gtk_status_icon_get_pixbuf (status_icon));
689       break;
690     case PROP_STOCK:
691       if (priv->storage_type != GTK_IMAGE_STOCK)
692         g_value_set_string (value, NULL);
693       else
694         g_value_set_string (value, gtk_status_icon_get_stock (status_icon));
695       break;
696     case PROP_ICON_NAME:
697       if (priv->storage_type != GTK_IMAGE_ICON_NAME)
698         g_value_set_string (value, NULL);
699       else
700         g_value_set_string (value, gtk_status_icon_get_icon_name (status_icon));
701       break;
702     case PROP_STORAGE_TYPE:
703       g_value_set_enum (value, gtk_status_icon_get_storage_type (status_icon));
704       break;
705     case PROP_SIZE:
706       g_value_set_int (value, gtk_status_icon_get_size (status_icon));
707       break;
708     case PROP_SCREEN:
709       g_value_set_object (value, gtk_status_icon_get_screen (status_icon));
710       break;
711     case PROP_BLINKING:
712       g_value_set_boolean (value, gtk_status_icon_get_blinking (status_icon));
713       break;
714     case PROP_VISIBLE:
715       g_value_set_boolean (value, gtk_status_icon_get_visible (status_icon));
716       break;
717     case PROP_EMBEDDED:
718       g_value_set_boolean (value, gtk_status_icon_is_embedded (status_icon));
719       break;
720     case PROP_ORIENTATION:
721 #ifdef GDK_WINDOWING_X11
722       g_value_set_enum (value, _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (status_icon->priv->tray_icon)));
723 #endif
724 #ifdef GDK_WINDOWING_WIN32
725       g_value_set_enum (value, status_icon->priv->orientation);
726 #endif
727       break;
728     default:
729       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
730       break;
731     }
732 }
733
734 /**
735  * gtk_status_icon_new:
736  * 
737  * Creates an empty status icon object.
738  * 
739  * Return value: a new #GtkStatusIcon
740  *
741  * Since: 2.10
742  **/
743 GtkStatusIcon *
744 gtk_status_icon_new (void)
745 {
746   return g_object_new (GTK_TYPE_STATUS_ICON, NULL);
747 }
748
749 /**
750  * gtk_status_icon_new_from_pixbuf:
751  * @pixbuf: a #GdkPixbuf
752  * 
753  * Creates a status icon displaying @pixbuf. 
754  *
755  * The image will be scaled down to fit in the available 
756  * space in the notification area, if necessary.
757  * 
758  * Return value: a new #GtkStatusIcon
759  *
760  * Since: 2.10
761  **/
762 GtkStatusIcon *
763 gtk_status_icon_new_from_pixbuf (GdkPixbuf *pixbuf)
764 {
765   return g_object_new (GTK_TYPE_STATUS_ICON,
766                        "pixbuf", pixbuf,
767                        NULL);
768 }
769
770 /**
771  * gtk_status_icon_new_from_file:
772  * @filename: a filename
773  * 
774  * Creates a status icon displaying the file @filename. 
775  *
776  * The image will be scaled down to fit in the available 
777  * space in the notification area, if necessary.
778  * 
779  * Return value: a new #GtkStatusIcon
780  *
781  * Since: 2.10
782  **/
783 GtkStatusIcon *
784 gtk_status_icon_new_from_file (const gchar *filename)
785 {
786   return g_object_new (GTK_TYPE_STATUS_ICON,
787                        "file", filename,
788                        NULL);
789 }
790
791 /**
792  * gtk_status_icon_new_from_stock:
793  * @stock_id: a stock icon id
794  * 
795  * Creates a status icon displaying a stock icon. Sample stock icon
796  * names are #GTK_STOCK_OPEN, #GTK_STOCK_QUIT. You can register your 
797  * own stock icon names, see gtk_icon_factory_add_default() and 
798  * gtk_icon_factory_add(). 
799  *
800  * Return value: a new #GtkStatusIcon
801  *
802  * Since: 2.10
803  **/
804 GtkStatusIcon *
805 gtk_status_icon_new_from_stock (const gchar *stock_id)
806 {
807   return g_object_new (GTK_TYPE_STATUS_ICON,
808                        "stock", stock_id,
809                        NULL);
810 }
811
812 /**
813  * gtk_status_icon_new_from_icon_name:
814  * @icon_name: an icon name
815  * 
816  * Creates a status icon displaying an icon from the current icon theme.
817  * If the current icon theme is changed, the icon will be updated 
818  * appropriately.
819  * 
820  * Return value: a new #GtkStatusIcon
821  *
822  * Since: 2.10
823  **/
824 GtkStatusIcon *
825 gtk_status_icon_new_from_icon_name (const gchar *icon_name)
826 {
827   return g_object_new (GTK_TYPE_STATUS_ICON,
828                        "icon-name", icon_name,
829                        NULL);
830 }
831
832 static void
833 emit_activate_signal (GtkStatusIcon *status_icon)
834 {
835   g_signal_emit (status_icon,
836                  status_icon_signals [ACTIVATE_SIGNAL], 0);
837 }
838
839 static void
840 emit_popup_menu_signal (GtkStatusIcon *status_icon,
841                         guint          button,
842                         guint32        activate_time)
843 {
844   g_signal_emit (status_icon,
845                  status_icon_signals [POPUP_MENU_SIGNAL], 0,
846                  button,
847                  activate_time);
848 }
849
850 #ifdef GDK_WINDOWING_X11
851
852 static gboolean
853 emit_size_changed_signal (GtkStatusIcon *status_icon,
854                           gint           size)
855 {
856   gboolean handled = FALSE;
857   
858   g_signal_emit (status_icon,
859                  status_icon_signals [SIZE_CHANGED_SIGNAL], 0,
860                  size,
861                  &handled);
862
863   return handled;
864 }
865
866 #endif
867
868 static GdkPixbuf *
869 gtk_status_icon_blank_icon (GtkStatusIcon *status_icon)
870 {
871   GtkStatusIconPrivate *priv = status_icon->priv;
872
873   if (priv->blank_icon)
874     {
875       gint width, height;
876
877       width  = gdk_pixbuf_get_width (priv->blank_icon);
878       height = gdk_pixbuf_get_height (priv->blank_icon);
879
880
881       if (width == priv->image_width && height == priv->image_height)
882         return priv->blank_icon;
883       else
884         {
885           g_object_unref (priv->blank_icon);
886           priv->blank_icon = NULL;
887         }
888     }
889
890   priv->blank_icon = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
891                                      priv->image_width, 
892                                      priv->image_height);
893   if (priv->blank_icon)
894     gdk_pixbuf_fill (priv->blank_icon, 0);
895
896   return priv->blank_icon;
897 }
898
899 #ifdef GDK_WINDOWING_X11
900
901 static GtkIconSize
902 find_icon_size (GtkWidget *widget, 
903                 gint       pixel_size)
904 {
905   GdkScreen *screen;
906   GtkSettings *settings;
907   GtkIconSize s, size;
908   gint w, h, d, dist;
909
910   screen = gtk_widget_get_screen (widget);
911
912   if (!screen)
913     return GTK_ICON_SIZE_MENU;
914
915   settings = gtk_settings_get_for_screen (screen);
916   
917   dist = G_MAXINT;
918   size = GTK_ICON_SIZE_MENU;
919
920   for (s = GTK_ICON_SIZE_MENU; s < GTK_ICON_SIZE_DIALOG; s++)
921     {
922       if (gtk_icon_size_lookup_for_settings (settings, s, &w, &h) &&
923           w <= pixel_size && h <= pixel_size)
924         {
925           d = MAX (pixel_size - w, pixel_size - h);
926           if (d < dist)
927             {
928               dist = d;
929               size = s;
930             }
931         }
932     }
933   
934   return size;
935 }
936
937 #endif
938
939 static void
940 gtk_status_icon_update_image (GtkStatusIcon *status_icon)
941 {
942   GtkStatusIconPrivate *priv = status_icon->priv;
943 #ifdef GDK_WINDOWING_WIN32
944   HICON prev_hicon;
945 #endif
946
947   if (priv->blink_off)
948     {
949 #ifdef GDK_WINDOWING_X11
950       gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image),
951                                  gtk_status_icon_blank_icon (status_icon));
952 #endif
953 #ifdef GDK_WINDOWING_WIN32
954       prev_hicon = priv->nid.hIcon;
955       priv->nid.hIcon = gdk_win32_pixbuf_to_hicon_libgtk_only (gtk_status_icon_blank_icon (status_icon));
956       priv->nid.uFlags |= NIF_ICON;
957       if (priv->nid.hWnd != NULL && priv->visible)
958         if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
959           g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
960       if (prev_hicon)
961         DestroyIcon (prev_hicon);
962 #endif
963 #ifdef GDK_WINDOWING_QUARTZ
964       QUARTZ_POOL_ALLOC;
965       [priv->status_item setImage:gtk_status_icon_blank_icon (status_icon)];
966       QUARTZ_POOL_RELEASE;
967 #endif
968       return;
969     }
970
971   switch (priv->storage_type)
972     {
973     case GTK_IMAGE_PIXBUF:
974       {
975         GdkPixbuf *pixbuf;
976
977         pixbuf = priv->image_data.pixbuf;
978
979         if (pixbuf)
980           {
981             GdkPixbuf *scaled;
982             gint size;
983             gint width;
984             gint height;
985
986             size = priv->size;
987
988             width  = gdk_pixbuf_get_width  (pixbuf);
989             height = gdk_pixbuf_get_height (pixbuf);
990
991             if (width > size || height > size)
992               scaled = gdk_pixbuf_scale_simple (pixbuf,
993                                                 MIN (size, width),
994                                                 MIN (size, height),
995                                                 GDK_INTERP_BILINEAR);
996             else
997               scaled = g_object_ref (pixbuf);
998
999 #ifdef GDK_WINDOWING_X11
1000             gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), scaled);
1001 #endif
1002 #ifdef GDK_WINDOWING_WIN32
1003             prev_hicon = priv->nid.hIcon;
1004             priv->nid.hIcon = gdk_win32_pixbuf_to_hicon_libgtk_only (scaled);
1005             priv->nid.uFlags |= NIF_ICON;
1006             if (priv->nid.hWnd != NULL && priv->visible)
1007               if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
1008                   g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
1009             if (prev_hicon)
1010               DestroyIcon (prev_hicon);
1011 #endif
1012 #ifdef GDK_WINDOWING_QUARTZ
1013       QUARTZ_POOL_ALLOC;
1014       [priv->status_item setImage:scaled];
1015       QUARTZ_POOL_RELEASE;
1016 #endif
1017                         
1018             g_object_unref (scaled);
1019           }
1020         else
1021           {
1022 #ifdef GDK_WINDOWING_X11
1023             gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), NULL);
1024 #endif
1025 #ifdef GDK_WINDOWING_WIN32
1026             priv->nid.uFlags &= ~NIF_ICON;
1027             if (priv->nid.hWnd != NULL && priv->visible)
1028               if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
1029                 g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
1030 #endif
1031 #ifdef GDK_WINDOWING_QUARTZ
1032       [priv->status_item setImage:NULL];
1033 #endif
1034           }
1035       }
1036       break;
1037
1038     case GTK_IMAGE_STOCK:
1039       {
1040 #ifdef GDK_WINDOWING_X11
1041         GtkIconSize size = find_icon_size (priv->image, priv->size);
1042         gtk_image_set_from_stock (GTK_IMAGE (priv->image),
1043                                   priv->image_data.stock_id,
1044                                   size);
1045 #endif
1046 #ifdef GDK_WINDOWING_WIN32
1047         {
1048           GdkPixbuf *pixbuf =
1049             gtk_widget_render_icon (priv->dummy_widget,
1050                                     priv->image_data.stock_id,
1051                                     GTK_ICON_SIZE_SMALL_TOOLBAR,
1052                                     NULL);
1053
1054           prev_hicon = priv->nid.hIcon;
1055           priv->nid.hIcon = gdk_win32_pixbuf_to_hicon_libgtk_only (pixbuf);
1056           priv->nid.uFlags |= NIF_ICON;
1057           if (priv->nid.hWnd != NULL && priv->visible)
1058             if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
1059               g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
1060           if (prev_hicon)
1061             DestroyIcon (prev_hicon);
1062           g_object_unref (pixbuf);
1063         }
1064 #endif
1065 #ifdef GDK_WINDOWING_QUARTZ
1066         {
1067           GdkPixbuf *pixbuf;
1068
1069           pixbuf = gtk_widget_render_icon (priv->dummy_widget,
1070                                            priv->image_data.stock_id,
1071                                            GTK_ICON_SIZE_SMALL_TOOLBAR,
1072                                            NULL);
1073           QUARTZ_POOL_ALLOC;
1074           [priv->status_item setImage:pixbuf];
1075           QUARTZ_POOL_RELEASE;
1076           g_object_unref (pixbuf);
1077         }       
1078 #endif
1079       }
1080       break;
1081       
1082     case GTK_IMAGE_ICON_NAME:
1083       {
1084 #ifdef GDK_WINDOWING_X11
1085         GtkIconSize size = find_icon_size (priv->image, priv->size);
1086         gtk_image_set_from_icon_name (GTK_IMAGE (priv->image),
1087                                       priv->image_data.icon_name,
1088                                       size);
1089 #endif
1090 #ifdef GDK_WINDOWING_WIN32
1091         {
1092           GdkPixbuf *pixbuf =
1093             gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
1094                                       priv->image_data.icon_name,
1095                                       priv->size,
1096                                       0, NULL);
1097           
1098           prev_hicon = priv->nid.hIcon;
1099           priv->nid.hIcon = gdk_win32_pixbuf_to_hicon_libgtk_only (pixbuf);
1100           priv->nid.uFlags |= NIF_ICON;
1101           if (priv->nid.hWnd != NULL && priv->visible)
1102             if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
1103               g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
1104           if (prev_hicon)
1105             DestroyIcon (prev_hicon);
1106           g_object_unref (pixbuf);
1107         }
1108 #endif
1109 #ifdef GDK_WINDOWING_QUARTZ
1110         {
1111           GdkPixbuf *pixbuf;
1112
1113           pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
1114                                              priv->image_data.icon_name,
1115                                              priv->size,
1116                                              0, NULL);
1117
1118           QUARTZ_POOL_ALLOC;
1119           [priv->status_item setImage:pixbuf];
1120           QUARTZ_POOL_RELEASE;
1121           g_object_unref (pixbuf);
1122         }
1123 #endif
1124         
1125       }
1126       break;
1127       
1128     case GTK_IMAGE_EMPTY:
1129 #ifdef GDK_WINDOWING_X11
1130       gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), NULL);
1131 #endif
1132 #ifdef GDK_WINDOWING_WIN32
1133       priv->nid.uFlags &= ~NIF_ICON;
1134       if (priv->nid.hWnd != NULL && priv->visible)
1135         if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
1136           g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
1137 #endif
1138 #ifdef GDK_WINDOWING_QUARTZ
1139         {
1140           QUARTZ_POOL_ALLOC;
1141           [priv->status_item setImage:NULL];
1142           QUARTZ_POOL_RELEASE;
1143         }
1144 #endif
1145       break;
1146     default:
1147       g_assert_not_reached ();
1148       break;
1149     }
1150 }
1151
1152 #ifdef GDK_WINDOWING_X11
1153
1154 static void
1155 gtk_status_icon_size_allocate (GtkStatusIcon *status_icon,
1156                                GtkAllocation *allocation)
1157 {
1158   GtkStatusIconPrivate *priv = status_icon->priv;
1159   GtkOrientation orientation;
1160   gint size;
1161
1162   orientation = _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (priv->tray_icon));
1163
1164   if (orientation == GTK_ORIENTATION_HORIZONTAL)
1165     size = allocation->height;
1166   else
1167     size = allocation->width;
1168
1169   priv->image_width = allocation->width - GTK_MISC (priv->image)->xpad * 2;
1170   priv->image_height = allocation->height - GTK_MISC (priv->image)->ypad * 2;
1171
1172   if (priv->size != size)
1173     {
1174       priv->size = size;
1175
1176       g_object_notify (G_OBJECT (status_icon), "size");
1177
1178       if (!emit_size_changed_signal (status_icon, size))
1179         gtk_status_icon_update_image (status_icon);
1180     }
1181 }
1182
1183 static void
1184 gtk_status_icon_screen_changed (GtkStatusIcon *status_icon,
1185                                 GdkScreen *old_screen)
1186 {
1187   GtkStatusIconPrivate *priv = status_icon->priv;
1188
1189   if (gtk_widget_get_screen (priv->tray_icon) != old_screen)
1190     {
1191       g_object_notify (G_OBJECT (status_icon), "screen");
1192     }
1193 }
1194
1195 #endif
1196
1197 #ifdef GDK_WINDOWING_X11
1198
1199 static void
1200 gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon)
1201 {
1202   g_object_notify (G_OBJECT (status_icon), "embedded");
1203 }
1204
1205 static void
1206 gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon)
1207 {
1208   g_object_notify (G_OBJECT (status_icon), "orientation");
1209 }
1210
1211 #endif
1212
1213 static gboolean
1214 gtk_status_icon_key_press (GtkStatusIcon  *status_icon,
1215                            GdkEventKey    *event)
1216 {
1217   guint state, keyval;
1218
1219   state = event->state & gtk_accelerator_get_default_mod_mask ();
1220   keyval = event->keyval;
1221   if (state == 0 &&
1222       (keyval == GDK_Return ||
1223        keyval == GDK_KP_Enter ||
1224        keyval == GDK_ISO_Enter ||
1225        keyval == GDK_space ||
1226        keyval == GDK_KP_Space))
1227     {
1228       emit_activate_signal (status_icon);
1229       return TRUE;
1230     }
1231
1232   return FALSE;
1233 }
1234
1235 static void
1236 gtk_status_icon_popup_menu (GtkStatusIcon  *status_icon)
1237 {
1238   emit_popup_menu_signal (status_icon, 0, gtk_get_current_event_time ());
1239 }
1240
1241 static gboolean
1242 gtk_status_icon_button_press (GtkStatusIcon  *status_icon,
1243                               GdkEventButton *event)
1244 {
1245   if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
1246     {
1247       emit_activate_signal (status_icon);
1248       return TRUE;
1249     }
1250   else if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
1251     {
1252       emit_popup_menu_signal (status_icon, event->button, event->time);
1253       return TRUE;
1254     }
1255
1256   return FALSE;
1257 }
1258
1259 static void
1260 gtk_status_icon_reset_image_data (GtkStatusIcon *status_icon)
1261 {
1262   GtkStatusIconPrivate *priv = status_icon->priv;
1263
1264   switch (priv->storage_type)
1265   {
1266     case GTK_IMAGE_PIXBUF:
1267       if (priv->image_data.pixbuf)
1268         g_object_unref (priv->image_data.pixbuf);
1269       priv->image_data.pixbuf = NULL;
1270       g_object_notify (G_OBJECT (status_icon), "pixbuf");
1271       break;
1272
1273     case GTK_IMAGE_STOCK:
1274       g_free (priv->image_data.stock_id);
1275       priv->image_data.stock_id = NULL;
1276
1277       g_object_notify (G_OBJECT (status_icon), "stock");
1278       break;
1279       
1280     case GTK_IMAGE_ICON_NAME:
1281       g_free (priv->image_data.icon_name);
1282       priv->image_data.icon_name = NULL;
1283
1284       g_object_notify (G_OBJECT (status_icon), "icon-name");
1285       break;
1286       
1287     case GTK_IMAGE_EMPTY:
1288       break;
1289     default:
1290       g_assert_not_reached ();
1291       break;
1292   }
1293
1294   priv->storage_type = GTK_IMAGE_EMPTY;
1295   g_object_notify (G_OBJECT (status_icon), "storage-type");
1296 }
1297
1298 static void
1299 gtk_status_icon_set_image (GtkStatusIcon *status_icon,
1300                            GtkImageType   storage_type,
1301                            gpointer       data)
1302 {
1303   GtkStatusIconPrivate *priv = status_icon->priv;
1304
1305   g_object_freeze_notify (G_OBJECT (status_icon));
1306
1307   gtk_status_icon_reset_image_data (status_icon);
1308
1309   priv->storage_type = storage_type;
1310   g_object_notify (G_OBJECT (status_icon), "storage-type");
1311
1312   switch (storage_type) 
1313     {
1314     case GTK_IMAGE_PIXBUF:
1315       priv->image_data.pixbuf = (GdkPixbuf *)data;
1316       g_object_notify (G_OBJECT (status_icon), "pixbuf");
1317       break;
1318     case GTK_IMAGE_STOCK:
1319       priv->image_data.stock_id = g_strdup ((const gchar *)data);
1320       g_object_notify (G_OBJECT (status_icon), "stock");
1321       break;
1322     case GTK_IMAGE_ICON_NAME:
1323       priv->image_data.icon_name = g_strdup ((const gchar *)data);
1324       g_object_notify (G_OBJECT (status_icon), "icon-name");
1325       break;
1326     default:
1327       g_warning ("Image type %u not handled by GtkStatusIcon", storage_type);
1328     }
1329
1330   g_object_thaw_notify (G_OBJECT (status_icon));
1331
1332   gtk_status_icon_update_image (status_icon);
1333 }
1334
1335 /**
1336  * gtk_status_icon_set_from_pixbuf:
1337  * @status_icon: a #GtkStatusIcon
1338  * @pixbuf: a #GdkPixbuf or %NULL
1339  * 
1340  * Makes @status_icon display @pixbuf. 
1341  * See gtk_status_icon_new_from_pixbuf() for details.
1342  *
1343  * Since: 2.10
1344  **/
1345 void
1346 gtk_status_icon_set_from_pixbuf (GtkStatusIcon *status_icon,
1347                                  GdkPixbuf     *pixbuf)
1348 {
1349   g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
1350   g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
1351
1352   if (pixbuf)
1353     g_object_ref (pixbuf);
1354
1355   gtk_status_icon_set_image (status_icon, GTK_IMAGE_PIXBUF,
1356                              (gpointer) pixbuf);
1357 }
1358
1359 /**
1360  * gtk_status_icon_set_from_file:
1361  * @status_icon: a #GtkStatusIcon
1362  * @filename: a filename
1363  * 
1364  * Makes @status_icon display the file @filename.
1365  * See gtk_status_icon_new_from_file() for details.
1366  *
1367  * Since: 2.10 
1368  **/
1369 void
1370 gtk_status_icon_set_from_file (GtkStatusIcon *status_icon,
1371                                const gchar   *filename)
1372 {
1373   GdkPixbuf *pixbuf;
1374   
1375   g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
1376   g_return_if_fail (filename != NULL);
1377   
1378   pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1379   
1380   gtk_status_icon_set_from_pixbuf (status_icon, pixbuf);
1381   
1382   if (pixbuf)
1383     g_object_unref (pixbuf);
1384 }
1385
1386 /**
1387  * gtk_status_icon_set_from_stock:
1388  * @status_icon: a #GtkStatusIcon
1389  * @stock_id: a stock icon id
1390  * 
1391  * Makes @status_icon display the stock icon with the id @stock_id.
1392  * See gtk_status_icon_new_from_stock() for details.
1393  *
1394  * Since: 2.10 
1395  **/
1396 void
1397 gtk_status_icon_set_from_stock (GtkStatusIcon *status_icon,
1398                                 const gchar   *stock_id)
1399 {
1400   g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
1401   g_return_if_fail (stock_id != NULL);
1402
1403   gtk_status_icon_set_image (status_icon, GTK_IMAGE_STOCK,
1404                              (gpointer) stock_id);
1405 }
1406
1407 /**
1408  * gtk_status_icon_set_from_icon_name:
1409  * @status_icon: a #GtkStatusIcon
1410  * @icon_name: an icon name
1411  * 
1412  * Makes @status_icon display the icon named @icon_name from the 
1413  * current icon theme.
1414  * See gtk_status_icon_new_from_icon_name() for details.
1415  *
1416  * Since: 2.10 
1417  **/
1418 void
1419 gtk_status_icon_set_from_icon_name (GtkStatusIcon *status_icon,
1420                                     const gchar   *icon_name)
1421 {
1422   g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
1423   g_return_if_fail (icon_name != NULL);
1424
1425   gtk_status_icon_set_image (status_icon, GTK_IMAGE_ICON_NAME,
1426                              (gpointer) icon_name);
1427 }
1428
1429 /**
1430  * gtk_status_icon_get_storage_type:
1431  * @status_icon: a #GtkStatusIcon
1432  * 
1433  * Gets the type of representation being used by the #GtkStatusIcon
1434  * to store image data. If the #GtkStatusIcon has no image data,
1435  * the return value will be %GTK_IMAGE_EMPTY. 
1436  * 
1437  * Return value: the image representation being used
1438  *
1439  * Since: 2.10
1440  **/
1441 GtkImageType
1442 gtk_status_icon_get_storage_type (GtkStatusIcon *status_icon)
1443 {
1444   g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), GTK_IMAGE_EMPTY);
1445
1446   return status_icon->priv->storage_type;
1447 }
1448 /**
1449  * gtk_status_icon_get_pixbuf:
1450  * @status_icon: a #GtkStatusIcon
1451  * 
1452  * Gets the #GdkPixbuf being displayed by the #GtkStatusIcon.
1453  * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
1454  * %GTK_IMAGE_PIXBUF (see gtk_status_icon_get_storage_type()).
1455  * The caller of this function does not own a reference to the
1456  * returned pixbuf.
1457  * 
1458  * Return value: the displayed pixbuf, or %NULL if the image is empty.
1459  *
1460  * Since: 2.10
1461  **/
1462 GdkPixbuf *
1463 gtk_status_icon_get_pixbuf (GtkStatusIcon *status_icon)
1464 {
1465   GtkStatusIconPrivate *priv;
1466
1467   g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
1468
1469   priv = status_icon->priv;
1470
1471   g_return_val_if_fail (priv->storage_type == GTK_IMAGE_PIXBUF ||
1472                         priv->storage_type == GTK_IMAGE_EMPTY, NULL);
1473
1474   if (priv->storage_type == GTK_IMAGE_EMPTY)
1475     priv->image_data.pixbuf = NULL;
1476
1477   return priv->image_data.pixbuf;
1478 }
1479
1480 /**
1481  * gtk_status_icon_get_stock:
1482  * @status_icon: a #GtkStatusIcon
1483  * 
1484  * Gets the id of the stock icon being displayed by the #GtkStatusIcon.
1485  * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
1486  * %GTK_IMAGE_STOCK (see gtk_status_icon_get_storage_type()).
1487  * The returned string is owned by the #GtkStatusIcon and should not
1488  * be freed or modified.
1489  * 
1490  * Return value: stock id of the displayed stock icon,
1491  *   or %NULL if the image is empty.
1492  *
1493  * Since: 2.10
1494  **/
1495 G_CONST_RETURN gchar *
1496 gtk_status_icon_get_stock (GtkStatusIcon *status_icon)
1497 {
1498   GtkStatusIconPrivate *priv;
1499
1500   g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
1501
1502   priv = status_icon->priv;
1503
1504   g_return_val_if_fail (priv->storage_type == GTK_IMAGE_STOCK ||
1505                         priv->storage_type == GTK_IMAGE_EMPTY, NULL);
1506   
1507   if (priv->storage_type == GTK_IMAGE_EMPTY)
1508     priv->image_data.stock_id = NULL;
1509
1510   return priv->image_data.stock_id;
1511 }
1512
1513 /**
1514  * gtk_status_icon_get_icon_name:
1515  * @status_icon: a #GtkStatusIcon
1516  * 
1517  * Gets the name of the icon being displayed by the #GtkStatusIcon.
1518  * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
1519  * %GTK_IMAGE_ICON_NAME (see gtk_status_icon_get_storage_type()).
1520  * The returned string is owned by the #GtkStatusIcon and should not
1521  * be freed or modified.
1522  * 
1523  * Return value: name of the displayed icon, or %NULL if the image is empty.
1524  *
1525  * Since: 2.10
1526  **/
1527 G_CONST_RETURN gchar *
1528 gtk_status_icon_get_icon_name (GtkStatusIcon *status_icon)
1529 {
1530   GtkStatusIconPrivate *priv;
1531   
1532   g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
1533
1534   priv = status_icon->priv;
1535
1536   g_return_val_if_fail (priv->storage_type == GTK_IMAGE_ICON_NAME ||
1537                         priv->storage_type == GTK_IMAGE_EMPTY, NULL);
1538
1539   if (priv->storage_type == GTK_IMAGE_EMPTY)
1540     priv->image_data.icon_name = NULL;
1541
1542   return priv->image_data.icon_name;
1543 }
1544
1545 /**
1546  * gtk_status_icon_get_size:
1547  * @status_icon: a #GtkStatusIcon
1548  * 
1549  * Gets the size in pixels that is available for the image. 
1550  * Stock icons and named icons adapt their size automatically
1551  * if the size of the notification area changes. For other
1552  * storage types, the size-changed signal can be used to
1553  * react to size changes.
1554  *
1555  * Note that the returned size is only meaningful while the 
1556  * status icon is embedded (see gtk_status_icon_is_embedded()).
1557  * 
1558  * Return value: the size that is available for the image
1559  *
1560  * Since: 2.10
1561  **/
1562 gint
1563 gtk_status_icon_get_size (GtkStatusIcon *status_icon)
1564 {
1565   g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), 0);
1566
1567   return status_icon->priv->size;
1568 }
1569
1570 /**
1571  * gtk_status_icon_set_screen:
1572  * @status_icon: a #GtkStatusIcon
1573  * @screen: a #GdkScreen
1574  *
1575  * Sets the #GdkScreen where @status_icon is displayed; if
1576  * the icon is already mapped, it will be unmapped, and
1577  * then remapped on the new screen.
1578  *
1579  * Since: 2.12
1580  */
1581 void
1582 gtk_status_icon_set_screen (GtkStatusIcon *status_icon,
1583                             GdkScreen     *screen)
1584 {
1585   g_return_if_fail (GDK_IS_SCREEN (screen));
1586
1587 #ifdef GDK_WINDOWING_X11
1588   gtk_window_set_screen (GTK_WINDOW (status_icon->priv->tray_icon), screen);
1589 #endif
1590 }
1591
1592 /** 
1593  * gtk_status_icon_get_screen:
1594  * @status_icon: a #GtkStatusIcon
1595  *
1596  * Returns the #GdkScreen associated with @status_icon.
1597  *
1598  * Return value: a #GdkScreen.
1599  *
1600  * Since: 2.12
1601  */
1602 GdkScreen *
1603 gtk_status_icon_get_screen (GtkStatusIcon *status_icon)
1604 {
1605   g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
1606
1607 #ifdef GDK_WINDOWING_X11   
1608   return gtk_window_get_screen (GTK_WINDOW (status_icon->priv->tray_icon));
1609 #else
1610   return gdk_screen_get_default ();
1611 #endif
1612 }
1613
1614 /**
1615  * gtk_status_icon_set_tooltip:
1616  * @status_icon: a #GtkStatusIcon
1617  * @tooltip_text: the tooltip text, or %NULL
1618  * 
1619  * Sets the tooltip of the status icon.
1620  * 
1621  * Since: 2.10
1622  **/ 
1623 void
1624 gtk_status_icon_set_tooltip (GtkStatusIcon *status_icon,
1625                              const gchar   *tooltip_text)
1626 {
1627   GtkStatusIconPrivate *priv;
1628
1629   g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
1630
1631   priv = status_icon->priv;
1632
1633 #ifdef GDK_WINDOWING_X11
1634
1635   gtk_widget_set_tooltip_text (priv->tray_icon, tooltip_text);
1636
1637 #endif
1638 #ifdef GDK_WINDOWING_WIN32
1639   if (tooltip_text == NULL)
1640     priv->nid.uFlags &= ~NIF_TIP;
1641   else
1642     {
1643       WCHAR *wcs = g_utf8_to_utf16 (tooltip_text, -1, NULL, NULL, NULL);
1644
1645       priv->nid.uFlags |= NIF_TIP;
1646       wcsncpy (priv->nid.szTip, wcs, G_N_ELEMENTS (priv->nid.szTip) - 1);
1647       priv->nid.szTip[G_N_ELEMENTS (priv->nid.szTip) - 1] = 0;
1648       g_free (wcs);
1649     }
1650   if (priv->nid.hWnd != NULL && priv->visible)
1651     if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
1652       g_warning ("%s:%d:Shell_NotifyIconW(NIM_MODIFY) failed", __FILE__, __LINE__-1);
1653 #endif
1654 #ifdef GDK_WINDOWING_QUARTZ
1655   QUARTZ_POOL_ALLOC;
1656   [priv->status_item setToolTip:tooltip_text];
1657   QUARTZ_POOL_RELEASE;
1658 #endif
1659 }
1660
1661 static gboolean
1662 gtk_status_icon_blinker (GtkStatusIcon *status_icon)
1663 {
1664   GtkStatusIconPrivate *priv = status_icon->priv;
1665   
1666   priv->blink_off = !priv->blink_off;
1667
1668   gtk_status_icon_update_image (status_icon);
1669
1670   return TRUE;
1671 }
1672
1673 static void
1674 gtk_status_icon_enable_blinking (GtkStatusIcon *status_icon)
1675 {
1676   GtkStatusIconPrivate *priv = status_icon->priv;
1677   
1678   if (!priv->blinking_timeout)
1679     {
1680       gtk_status_icon_blinker (status_icon);
1681
1682       priv->blinking_timeout =
1683         gdk_threads_add_timeout (BLINK_TIMEOUT, 
1684                        (GSourceFunc) gtk_status_icon_blinker, 
1685                        status_icon);
1686     }
1687 }
1688
1689 static void
1690 gtk_status_icon_disable_blinking (GtkStatusIcon *status_icon)
1691 {
1692   GtkStatusIconPrivate *priv = status_icon->priv;
1693   
1694   if (priv->blinking_timeout)
1695     {
1696       g_source_remove (priv->blinking_timeout);
1697       priv->blinking_timeout = 0;
1698       priv->blink_off = FALSE;
1699
1700       gtk_status_icon_update_image (status_icon);
1701     }
1702 }
1703
1704 /**
1705  * gtk_status_icon_set_visible:
1706  * @status_icon: a #GtkStatusIcon
1707  * @visible: %TRUE to show the status icon, %FALSE to hide it
1708  * 
1709  * Shows or hides a status icon.
1710  *
1711  * Since: 2.10
1712  **/
1713 void
1714 gtk_status_icon_set_visible (GtkStatusIcon *status_icon,
1715                              gboolean       visible)
1716 {
1717   GtkStatusIconPrivate *priv;
1718
1719   g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
1720
1721   priv = status_icon->priv;
1722
1723   visible = visible != FALSE;
1724
1725   if (priv->visible != visible)
1726     {
1727       priv->visible = visible;
1728
1729 #ifdef GDK_WINDOWING_X11
1730       if (visible)
1731         gtk_widget_show (priv->tray_icon);
1732       else if (GTK_WIDGET_REALIZED (priv->tray_icon)) 
1733         {
1734           gtk_widget_hide (priv->tray_icon);
1735           gtk_widget_unrealize (priv->tray_icon);
1736         }
1737 #endif
1738 #ifdef GDK_WINDOWING_WIN32
1739       if (priv->nid.hWnd != NULL)
1740         {
1741           if (visible)
1742             Shell_NotifyIconW (NIM_ADD, &priv->nid);
1743           else
1744             Shell_NotifyIconW (NIM_DELETE, &priv->nid);
1745         }
1746 #endif
1747 #ifdef GDK_WINDOWING_QUARTZ
1748       QUARTZ_POOL_ALLOC;
1749       [priv->status_item setVisible:visible];
1750       QUARTZ_POOL_RELEASE;
1751 #endif
1752       g_object_notify (G_OBJECT (status_icon), "visible");
1753     }
1754 }
1755
1756 /**
1757  * gtk_status_icon_get_visible:
1758  * @status_icon: a #GtkStatusIcon
1759  * 
1760  * Returns whether the status icon is visible or not. 
1761  * Note that being visible does not guarantee that 
1762  * the user can actually see the icon, see also 
1763  * gtk_status_icon_is_embedded().
1764  * 
1765  * Return value: %TRUE if the status icon is visible
1766  *
1767  * Since: 2.10
1768  **/
1769 gboolean
1770 gtk_status_icon_get_visible (GtkStatusIcon *status_icon)
1771 {
1772   g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
1773
1774   return status_icon->priv->visible;
1775 }
1776
1777 /**
1778  * gtk_status_icon_set_blinking:
1779  * @status_icon: a #GtkStatusIcon
1780  * @blinking: %TRUE to turn blinking on, %FALSE to turn it off
1781  * 
1782  * Makes the status icon start or stop blinking. 
1783  * Note that blinking user interface elements may be problematic
1784  * for some users, and thus may be turned off, in which case
1785  * this setting has no effect.
1786  *
1787  * Since: 2.10
1788  **/
1789 void
1790 gtk_status_icon_set_blinking (GtkStatusIcon *status_icon,
1791                               gboolean       blinking)
1792 {
1793   GtkStatusIconPrivate *priv;
1794
1795   g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
1796
1797   priv = status_icon->priv;
1798
1799   blinking = blinking != FALSE;
1800
1801   if (priv->blinking != blinking)
1802     {
1803       priv->blinking = blinking;
1804
1805       if (blinking)
1806         gtk_status_icon_enable_blinking (status_icon);
1807       else
1808         gtk_status_icon_disable_blinking (status_icon);
1809
1810       g_object_notify (G_OBJECT (status_icon), "blinking");
1811     }
1812 }
1813
1814 /**
1815  * gtk_status_icon_get_blinking:
1816  * @status_icon: a #GtkStatusIcon
1817  * 
1818  * Returns whether the icon is blinking, see 
1819  * gtk_status_icon_set_blinking().
1820  * 
1821  * Return value: %TRUE if the icon is blinking
1822  *
1823  * Since: 2.10
1824  **/
1825 gboolean
1826 gtk_status_icon_get_blinking (GtkStatusIcon *status_icon)
1827 {
1828   g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
1829
1830   return status_icon->priv->blinking;
1831 }
1832
1833 /**
1834  * gtk_status_icon_is_embedded:
1835  * @status_icon: a #GtkStatusIcon
1836  * 
1837  * Returns whether the status icon is embedded in a notification
1838  * area. 
1839  * 
1840  * Return value: %TRUE if the status icon is embedded in
1841  *   a notification area.
1842  *
1843  * Since: 2.10
1844  **/
1845 gboolean
1846 gtk_status_icon_is_embedded (GtkStatusIcon *status_icon)
1847 {
1848 #ifdef GDK_WINDOWING_X11
1849   GtkPlug *plug;
1850 #endif
1851
1852   g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
1853
1854 #ifdef GDK_WINDOWING_X11
1855   plug = GTK_PLUG (status_icon->priv->tray_icon);
1856
1857   if (plug->socket_window)
1858     return TRUE;
1859   else
1860     return FALSE;
1861 #endif
1862 #ifdef GDK_WINDOWING_WIN32
1863   return TRUE;
1864 #endif
1865 #ifdef GDK_WINDOWING_QUARTZ
1866   return TRUE;
1867 #endif
1868 }
1869
1870 /**
1871  * gtk_status_icon_position_menu:
1872  * @menu: the #GtkMenu
1873  * @x: return location for the x position
1874  * @y: return location for the y position
1875  * @push_in: whether the first menu item should be offset (pushed in) to be
1876  *           aligned with the menu popup position (only useful for GtkOptionMenu).
1877  * @user_data: the status icon to position the menu on
1878  *
1879  * Menu positioning function to use with gtk_menu_popup()
1880  * to position @menu aligned to the status icon @user_data.
1881  * 
1882  * Since: 2.10
1883  **/
1884 void
1885 gtk_status_icon_position_menu (GtkMenu  *menu,
1886                                gint     *x,
1887                                gint     *y,
1888                                gboolean *push_in,
1889                                gpointer  user_data)
1890 {
1891 #ifdef GDK_WINDOWING_X11
1892   GtkStatusIcon *status_icon;
1893   GtkStatusIconPrivate *priv;
1894   GtkTrayIcon *tray_icon;
1895   GtkWidget *widget;
1896   GdkScreen *screen;
1897   GtkTextDirection direction;
1898   GtkRequisition menu_req;
1899   GdkRectangle monitor;
1900   gint monitor_num, height, width, xoffset, yoffset;
1901   
1902   g_return_if_fail (GTK_IS_MENU (menu));
1903   g_return_if_fail (GTK_IS_STATUS_ICON (user_data));
1904
1905   status_icon = GTK_STATUS_ICON (user_data);
1906   priv = status_icon->priv;
1907   tray_icon = GTK_TRAY_ICON (priv->tray_icon);
1908   widget = priv->tray_icon;
1909
1910   direction = gtk_widget_get_direction (widget);
1911
1912   screen = gtk_widget_get_screen (widget);
1913   gtk_menu_set_screen (menu, screen);
1914
1915   monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
1916   if (monitor_num < 0)
1917     monitor_num = 0;
1918   gtk_menu_set_monitor (menu, monitor_num);
1919
1920   gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
1921
1922   gdk_window_get_origin (widget->window, x, y);
1923   
1924   gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
1925
1926   if (_gtk_tray_icon_get_orientation (tray_icon) == GTK_ORIENTATION_VERTICAL)
1927     {
1928       width = 0;
1929       height = widget->allocation.height;
1930       xoffset = widget->allocation.width;
1931       yoffset = 0;
1932     }
1933   else
1934     {
1935       width = widget->allocation.width;
1936       height = 0;
1937       xoffset = 0;
1938       yoffset = widget->allocation.height;
1939     }
1940
1941   if (direction == GTK_TEXT_DIR_RTL)
1942     {
1943       if ((*x - (menu_req.width - width)) >= monitor.x)
1944         *x -= menu_req.width - width;
1945       else if ((*x + xoffset + menu_req.width) < (monitor.x + monitor.width))
1946         *x += xoffset;
1947       else if ((monitor.x + monitor.width - (*x + xoffset)) < *x)
1948         *x -= menu_req.width - width;
1949       else
1950         *x += xoffset;
1951     }
1952   else
1953     {
1954       if ((*x + xoffset + menu_req.width) < (monitor.x + monitor.width))
1955         *x += xoffset;
1956       else if ((*x - (menu_req.width - width)) >= monitor.x)
1957         *x -= menu_req.width - width;
1958       else if ((monitor.x + monitor.width - (*x + xoffset)) > *x)
1959         *x += xoffset;
1960       else 
1961         *x -= menu_req.width - width;
1962     }
1963
1964   if ((*y + yoffset + menu_req.height) < (monitor.y + monitor.height))
1965     *y += yoffset;
1966   else if ((*y - (menu_req.height - height)) >= monitor.y)
1967     *y -= menu_req.height - height;
1968   else if (monitor.y + monitor.height - (*y + yoffset) > *y)
1969     *y += yoffset;
1970   else 
1971     *y -= menu_req.height - height;
1972
1973   *push_in = FALSE;
1974 #endif /* GDK_WINDOWING_X11 */
1975
1976 #ifdef GDK_WINDOWING_WIN32
1977   GtkStatusIcon *status_icon;
1978   GtkStatusIconPrivate *priv;
1979   
1980   g_return_if_fail (GTK_IS_MENU (menu));
1981   g_return_if_fail (GTK_IS_STATUS_ICON (user_data));
1982
1983   status_icon = GTK_STATUS_ICON (user_data);
1984   priv = status_icon->priv;
1985
1986   *x = priv->last_click_x;
1987   *y = priv->last_click_y;
1988   *push_in = TRUE;
1989 #endif
1990 }
1991
1992 /**
1993  * gtk_status_icon_get_geometry:
1994  * @status_icon: a #GtkStatusIcon
1995  * @screen: return location for the screen, or %NULL if the
1996  *          information is not needed 
1997  * @area: return location for the area occupied by the status 
1998  *        icon, or %NULL
1999  * @orientation: return location for the orientation of the panel 
2000  *    in which the status icon is embedded, or %NULL. A panel 
2001  *    at the top or bottom of the screen is horizontal, a panel 
2002  *    at the left or right is vertical.
2003  *
2004  * Obtains information about the location of the status icon
2005  * on screen. This information can be used to e.g. position 
2006  * popups like notification bubbles. 
2007  *
2008  * See gtk_status_icon_position_menu() for a more convenient 
2009  * alternative for positioning menus.
2010  *
2011  * Note that some platforms do not allow GTK+ to provide 
2012  * this information, and even on platforms that do allow it,
2013  * the information is not reliable unless the status icon
2014  * is embedded in a notification area, see
2015  * gtk_status_icon_is_embedded().
2016  *
2017  * Return value: %TRUE if the location information has 
2018  *               been filled in
2019  *
2020  * Since: 2.10
2021  */
2022 gboolean  
2023 gtk_status_icon_get_geometry (GtkStatusIcon    *status_icon,
2024                               GdkScreen       **screen,
2025                               GdkRectangle     *area,
2026                               GtkOrientation   *orientation)
2027 {
2028 #ifdef GDK_WINDOWING_X11   
2029   GtkWidget *widget;
2030   GtkStatusIconPrivate *priv;
2031   gint x, y;
2032
2033   g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
2034
2035   priv = status_icon->priv;
2036   widget = priv->tray_icon;
2037
2038   if (screen)
2039     *screen = gtk_widget_get_screen (widget);
2040
2041   if (area)
2042     {
2043       gdk_window_get_origin (widget->window, &x, &y);
2044       area->x = x;
2045       area->y = y;
2046       area->width = widget->allocation.width;
2047       area->height = widget->allocation.height;
2048     }
2049
2050   if (orientation)
2051     *orientation = _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (widget));
2052
2053   return TRUE;
2054 #else
2055   return FALSE;
2056 #endif /* GDK_WINDOWING_X11 */
2057 }
2058
2059
2060 #define __GTK_STATUS_ICON_C__
2061 #include "gtkaliasdef.c"