6317985ef50709e7a7124dfbc55ee814d99eacd7
[hildon] / hildon-widgets / hildon-dialoghelp.c
1 /*
2  * This file is part of hildon-libs
3  *
4  * Copyright (C) 2005 Nokia Corporation.
5  *
6  * Contact: Luc Pionchon <luc.pionchon@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  */
24
25 /*
26  *  @file hildon-dialoghelp.c
27  *
28  *  This file provides API for the help dialog with
29  *  the optional icon.
30  *
31  */
32
33 #include <stdlib.h>
34 #include <gdk/gdkx.h>
35 #include "hildon-dialoghelp.h"
36
37 static guint help_signal = 0;
38
39 static GdkFilterReturn
40 handle_xevent(GdkXEvent * xevent, GdkEvent * event, gpointer dialog)
41 {
42     XAnyEvent *eventti = xevent;
43
44     if (eventti->type == ClientMessage) {
45         Atom help_atom, wm_atom;
46         Display *disp;
47         XClientMessageEvent *cm;
48
49         disp = GDK_DISPLAY();
50         cm = xevent;
51
52         help_atom = XInternAtom(disp, "_NET_WM_CONTEXT_HELP", True);
53         wm_atom = XInternAtom(disp, "WM_PROTOCOLS", True);
54
55         if (cm->message_type == wm_atom && cm->data.l[0] == help_atom) {
56             /* XClientMessageEvent *cm = xevent; */
57             g_signal_emit(G_OBJECT(dialog), help_signal, 0);
58         }
59
60         return GDK_FILTER_REMOVE;       /* Event handled, don't process
61                                            further */
62     }
63
64     return GDK_FILTER_CONTINUE; /* Event not handled */
65 }
66
67 /**
68  * gtk_dialog_help_enable:
69  * @dialog: The dialog for which help is to be enabled.
70  *
71  * Enables context help button for given dialog. The signal "help" can be
72  * connected to handler by normal gtk methods. Note that this function
73  * has to be called before the dialog is shown.
74  *
75  * The "help" signal itself has no other parameters than the dialog where
76  * it is connected to, ie.:
77  * void user_function(GtkDialog *dialog, gpointer user_data);
78  **/
79 void gtk_dialog_help_enable(GtkDialog * dialog)
80 {
81     GdkWindow *window;
82     GdkDisplay *display;
83     Atom *protocols;
84     Atom *list;
85     Atom helpatom;
86     int amount = 0;
87     int n = 0;
88     int i = 0;
89     int help_enabled = 0;
90     
91     /* Create help signal if it didn't exist */   
92     if (help_signal == 0) {
93         help_signal = g_signal_new("help", GTK_TYPE_DIALOG,
94                                    G_SIGNAL_ACTION, (guint) - 1, NULL,
95                                    NULL, g_cclosure_marshal_VOID__VOID,
96                                    G_TYPE_NONE, 0);
97     }
98
99     g_return_if_fail(GTK_IS_DIALOG(dialog));
100
101     gtk_widget_realize(GTK_WIDGET(dialog));
102     window = GTK_WIDGET(dialog)->window;
103     display = gdk_drawable_get_display (window);
104
105     /* Create a list of atoms stored in GdkWindow */
106     XGetWMProtocols(GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
107                     &list, &amount);
108     
109     protocols = (Atom *) malloc ((amount+1) * sizeof (Atom));
110     helpatom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_CONTEXT_HELP");
111
112     /* Enable the dialoghelp if help_atom is in the atoms' list */
113     for (i=0; i<amount; i++)
114     {
115             protocols[n++] = list[i];
116             if (list[i] == helpatom)
117             {
118                     help_enabled = 1;
119             }
120     }
121     XFree (list);
122
123     /* Add the help_atom to the atoms' list if it was not in it */ 
124     if (!help_enabled)
125     {
126             protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_CONTEXT_HELP");
127     }
128     
129     /* Replace the protocol property of the GdkWindow with the new atoms' list */
130     XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
131     free (protocols);
132     
133     /* Add a callback function as event filter */ 
134     gdk_window_add_filter(window, handle_xevent, dialog);
135 }
136
137 /**
138  * gtk_dialog_help_disable:
139  * @dialog: The dialog for which help is to be disabled.
140  *
141  * Disables context help button for the given dialog.
142  **/
143 void gtk_dialog_help_disable(GtkDialog * dialog)
144 {
145     GdkWindow *window=NULL;
146     GdkDisplay *display;
147     Atom *protocols;
148     Atom *list;
149     Atom helpatom;
150     int amount = 0;
151     int n = 0;
152     int i = 0;
153     
154     g_return_if_fail(GTK_IS_DIALOG(dialog));
155
156     gtk_widget_realize(GTK_WIDGET(dialog));
157     window = GTK_WIDGET(dialog)->window;
158     display = gdk_drawable_get_display (window);
159
160     /* Create a list of atoms stored in GdkWindow */
161     XGetWMProtocols(GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
162                     &list, &amount);
163     
164     helpatom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_CONTEXT_HELP");
165     protocols = (Atom *) malloc (amount * sizeof (Atom));
166
167     /* Remove the help_atom if it is in the atoms' list */
168     for (i=0; i<amount; i++)
169     {
170             if (list[i] != helpatom)
171             {
172                     protocols[n++] = list[i];
173             }
174     }
175     XFree (list);
176     
177     /* Replace the protocol property of the GdkWindow with the new atoms' list */
178     XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
179     free (protocols);
180
181     /* Remove the event filter */
182     gdk_window_remove_filter(window, handle_xevent, dialog);
183 }
184
185
186
187