1 
2 #include "jayatana-window.h"
3 
jayatana_window_new()4 JAyatanaWindow *jayatana_window_new()
5 {
6 	JAyatanaWindow *ret = (JAyatanaWindow *)g_malloc0(sizeof(JAyatanaWindow));
7 	ret->menu_items   = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
8 	ret->menu_counter = 1;
9 	return ret;
10 }
11 
jayatana_window_copy(JAyatanaWindow * src)12 JAyatanaWindow *jayatana_window_copy(JAyatanaWindow *src)
13 {
14 	JAyatanaWindow *ret = (JAyatanaWindow *)g_malloc0(sizeof(JAyatanaWindow));
15 	ret->windowXID      = src->windowXID;
16 	ret->globalThat     = src->globalThat;
17 	ret->menu_counter   = src->menu_counter;
18 
19 	ret->windowXIDPath        = g_strdup(src->windowXIDPath);
20 	ret->gdBusProxyRegistered = src->gdBusProxyRegistered;
21 	ret->gBusWatcher          = src->gBusWatcher;
22 	ret->dbBusProxy           = G_DBUS_PROXY(g_object_ref(src->dbBusProxy));
23 	ret->dbBusProxyCallSync   = g_variant_ref(src->dbBusProxyCallSync);
24 
25 	ret->dbusMenuServer = DBUSMENU_SERVER(g_object_ref(src->dbusMenuServer));
26 	ret->dbusMenuRoot   = DBUSMENU_MENUITEM(g_object_ref(src->dbusMenuRoot));
27 
28 	ret->registerState = src->registerState;
29 	ret->menu_items    = g_hash_table_ref(src->menu_items);
30 	return ret;
31 }
32 
jayatana_window_free(JAyatanaWindow * window)33 void jayatana_window_free(JAyatanaWindow *window)
34 {
35 	if (window->gdBusProxyRegistered)
36 	{
37 		g_clear_pointer(&window->windowXIDPath, g_free);
38 		g_clear_object(&window->dbBusProxy);
39 		g_clear_pointer(&window->dbBusProxyCallSync, g_variant_unref);
40 		g_clear_object(&window->dbusMenuServer);
41 		g_clear_object(&window->dbusMenuRoot);
42 	}
43 	g_clear_pointer(&window->menu_items, g_hash_table_unref);
44 	g_clear_pointer(&window, g_free);
45 }
46 
47 G_DEFINE_BOXED_TYPE(JAyatanaWindow, jayatana_window, (GBoxedCopyFunc)jayatana_window_copy,
48                     (GBoxedFreeFunc)jayatana_window_free)
49 
50 extern void jayatana_item_activated(DbusmenuMenuitem *item, guint timestamp, gpointer user_data);
51 extern void jayatana_item_events(DbusmenuMenuitem *item, const char *event);
52 extern void jayatana_item_about_to_show(DbusmenuMenuitem *item);
53 
jayatana_window_get_dbusmenu_item(JAyatanaWindow * win,jint id,const char * cclabel)54 DbusmenuMenuitem *jayatana_window_get_dbusmenu_item(JAyatanaWindow *win, jint id,
55                                                     const char *cclabel)
56 {
57 	DbusmenuMenuitem *it;
58 	char *checksum = g_compute_checksum_for_data(G_CHECKSUM_SHA512,
59 	                                             (const unsigned char *)cclabel,
60 	                                             strlen(cclabel));
61 	it             = DBUSMENU_MENUITEM(g_hash_table_lookup(win->menu_items, checksum));
62 	if (it == NULL)
63 	{
64 		it = dbusmenu_menuitem_new_with_id(id > 0 ? id : win->menu_counter++);
65 		g_hash_table_insert(win->menu_items, checksum, it);
66 	}
67 	else
68 	{
69 		g_signal_handlers_disconnect_by_func(it, (gpointer)jayatana_item_activated, NULL);
70 		g_signal_handlers_disconnect_by_func(it, (gpointer)jayatana_item_events, NULL);
71 		g_signal_handlers_disconnect_by_func(it,
72 		                                     (gpointer)jayatana_item_about_to_show,
73 		                                     NULL);
74 	}
75 	return it;
76 }
77 
jayatana_window_remove_unparented(JAyatanaWindow * win)78 void jayatana_window_remove_unparented(JAyatanaWindow *win)
79 {
80 	GHashTableIter iter;
81 	char *key;
82 	DbusmenuMenuitem *value;
83 	g_hash_table_iter_init(&iter, win->menu_items);
84 	while (g_hash_table_iter_next(&iter, (void **)&key, (void **)&value))
85 	{
86 		if (dbusmenu_menuitem_get_parent(value) == NULL)
87 			g_hash_table_iter_remove(&iter);
88 	}
89 }
90