1 /*
2 A small subclass of the menuitem for using clients.
3 
4 Copyright 2010 Canonical Ltd.
5 
6 Authors:
7     Ted Gould <ted@canonical.com>
8 
9 This program is free software: you can redistribute it and/or modify it
10 under the terms of either or both of the following licenses:
11 
12 1) the GNU Lesser General Public License version 3, as published by the
13 Free Software Foundation; and/or
14 2) the GNU Lesser General Public License version 2.1, as published by
15 the Free Software Foundation.
16 
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranties of
19 MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
20 PURPOSE.  See the applicable version of the GNU Lesser General Public
21 License for more details.
22 
23 You should have received a copy of both the GNU Lesser General Public
24 License version 3 and version 2.1 along with this program.  If not, see
25 <http://www.gnu.org/licenses/>
26 */
27 
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31 
32 #include "client-menuitem.h"
33 #include "client-private.h"
34 
35 typedef struct _DbusmenuClientMenuitemPrivate DbusmenuClientMenuitemPrivate;
36 
37 struct _DbusmenuClientMenuitemPrivate
38 {
39 	DbusmenuClient * client;
40 };
41 
42 #define DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(o) \
43 (G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_CLIENT_MENUITEM, DbusmenuClientMenuitemPrivate))
44 
45 static void dbusmenu_client_menuitem_class_init (DbusmenuClientMenuitemClass *klass);
46 static void dbusmenu_client_menuitem_init       (DbusmenuClientMenuitem *self);
47 static void dbusmenu_client_menuitem_dispose    (GObject *object);
48 static void dbusmenu_client_menuitem_finalize   (GObject *object);
49 static void handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * value, guint timestamp);
50 static void send_about_to_show (DbusmenuMenuitem * mi, void (*cb) (DbusmenuMenuitem * mi, gpointer user_data), gpointer cb_data);
51 
52 G_DEFINE_TYPE (DbusmenuClientMenuitem, dbusmenu_client_menuitem, DBUSMENU_TYPE_MENUITEM);
53 
54 static void
dbusmenu_client_menuitem_class_init(DbusmenuClientMenuitemClass * klass)55 dbusmenu_client_menuitem_class_init (DbusmenuClientMenuitemClass *klass)
56 {
57 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
58 
59 	g_type_class_add_private (klass, sizeof (DbusmenuClientMenuitemPrivate));
60 
61 	object_class->dispose = dbusmenu_client_menuitem_dispose;
62 	object_class->finalize = dbusmenu_client_menuitem_finalize;
63 
64 	DbusmenuMenuitemClass * mclass = DBUSMENU_MENUITEM_CLASS(klass);
65 	mclass->handle_event = handle_event;
66 	mclass->send_about_to_show = send_about_to_show;
67 
68 	return;
69 }
70 
71 static void
dbusmenu_client_menuitem_init(DbusmenuClientMenuitem * self)72 dbusmenu_client_menuitem_init (DbusmenuClientMenuitem *self)
73 {
74 
75 	return;
76 }
77 
78 static void
dbusmenu_client_menuitem_dispose(GObject * object)79 dbusmenu_client_menuitem_dispose (GObject *object)
80 {
81 
82 	G_OBJECT_CLASS (dbusmenu_client_menuitem_parent_class)->dispose (object);
83 	return;
84 }
85 
86 static void
dbusmenu_client_menuitem_finalize(GObject * object)87 dbusmenu_client_menuitem_finalize (GObject *object)
88 {
89 
90 	G_OBJECT_CLASS (dbusmenu_client_menuitem_parent_class)->finalize (object);
91 	return;
92 }
93 
94 /* Creates the item and associates the client */
95 DbusmenuClientMenuitem *
dbusmenu_client_menuitem_new(gint id,DbusmenuClient * client)96 dbusmenu_client_menuitem_new (gint id, DbusmenuClient * client)
97 {
98 	DbusmenuClientMenuitem * mi = g_object_new(DBUSMENU_TYPE_CLIENT_MENUITEM, "id", id, NULL);
99 	DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi);
100 	priv->client = client;
101 	return mi;
102 }
103 
104 /* Passes the event signal on through the client. */
105 static void
handle_event(DbusmenuMenuitem * mi,const gchar * name,GVariant * variant,guint timestamp)106 handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * variant, guint timestamp)
107 {
108 	DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi);
109 	dbusmenu_client_send_event(priv->client, dbusmenu_menuitem_get_id(mi), name, variant, timestamp, mi);
110 	return;
111 }
112 
113 typedef struct _about_to_show_t about_to_show_t;
114 struct _about_to_show_t {
115 	DbusmenuMenuitem * mi;
116 	void (*cb) (DbusmenuMenuitem * mi, gpointer user_data);
117 	gpointer cb_data;
118 };
119 
120 /* Handles calling the callback that we were called with */
121 static void
about_to_show_cb(gpointer user_data)122 about_to_show_cb (gpointer user_data)
123 {
124 	about_to_show_t * data = (about_to_show_t *)user_data;
125 
126 	data->cb(data->mi, data->cb_data);
127 
128 	g_object_unref(data->mi);
129 	g_free(user_data);
130 	return;
131 }
132 
133 /* Passes the about to show signal on through the client. */
134 static void
send_about_to_show(DbusmenuMenuitem * mi,void (* cb)(DbusmenuMenuitem * mi,gpointer user_data),gpointer cb_data)135 send_about_to_show (DbusmenuMenuitem * mi, void (*cb) (DbusmenuMenuitem * mi, gpointer user_data), gpointer cb_data)
136 {
137 	DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi);
138 	if (cb == NULL) {
139 		/* Common enough that we don't want to bother
140 		   with the allocation */
141 		dbusmenu_client_send_about_to_show(priv->client, dbusmenu_menuitem_get_id(mi), NULL, NULL);
142 	} else {
143 		about_to_show_t * data = g_new0(about_to_show_t, 1);
144 		data->mi = mi;
145 		data->cb = cb;
146 		data->cb_data = cb_data;
147 		g_object_ref(mi);
148 
149 		dbusmenu_client_send_about_to_show(priv->client, dbusmenu_menuitem_get_id(mi), about_to_show_cb, data);
150 	}
151 	return;
152 }
153