[Galago-commits] r1996 - in trunk/notification-daemon: . src

galago-commits at freedesktop.org galago-commits at freedesktop.org
Thu Jun 30 23:50:02 PDT 2005


Author: chipx86
Date: 2005-06-30 23:49:58 -0700 (Thu, 30 Jun 2005)
New Revision: 1996

Modified:
   trunk/notification-daemon/ChangeLog
   trunk/notification-daemon/src/PopupNotification.cpp
   trunk/notification-daemon/src/main.cpp
   trunk/notification-daemon/src/notifier.h
Log:
- Separated the dict parsing code into a single function so that the action and hint code will be cleaned up.
- Added very basic support for hints.
- Add preliminary support for a little pointer arrow for x, y hints.


Modified: trunk/notification-daemon/ChangeLog
===================================================================
--- trunk/notification-daemon/ChangeLog	2005-07-01 06:42:29 UTC (rev 1995)
+++ trunk/notification-daemon/ChangeLog	2005-07-01 06:49:58 UTC (rev 1996)
@@ -1,3 +1,13 @@
+Thu Jun 30 21:38:27 PDT 2005  Christian Hammond <chipx86 at chipx86.com>
+
+	* src/PopupNotification.cpp:
+	* src/main.cpp:
+	* src/notifier.h:
+	  - Separated the dict parsing code into a single function so that
+	    the action and hint code will be cleaned up.
+	  - Added very basic support for hints.
+	  - Add preliminary support for a little pointer arrow for x, y hints.
+
 Sat Jun 25 17:45:38 PDT 2005  Christian Hammond <chipx86 at chipx86.com>
 
 	* src/Makefile.am:

Modified: trunk/notification-daemon/src/PopupNotification.cpp
===================================================================
--- trunk/notification-daemon/src/PopupNotification.cpp	2005-07-01 06:42:29 UTC (rev 1995)
+++ trunk/notification-daemon/src/PopupNotification.cpp	2005-07-01 06:49:58 UTC (rev 1996)
@@ -479,10 +479,69 @@
         workarea.height = gdk_screen_height();
     }
 
-    gtk_window_move(GTK_WINDOW(window),
-                    workarea.x + workarea.width - req.width,
-                    workarea.y + workarea.height - get_height() -
-                    height_offset);
+	int x, y;
+
+	TRACE("hint x = %d, hint y = %d\n", hint_x, hint_y);
+
+	/*
+	 * See if the caller has specified where the want the notification to
+	 * point to.
+	 */
+	if (hint_x != -1 && hint_y != -1)
+	{
+		GdkDisplay *display = gtk_widget_get_display(window);
+		GdkScreen *screen   = gdk_display_get_screen(display, disp_screen);
+		int screen_width    = gdk_screen_get_width(screen);
+		int screen_height   = gdk_screen_get_height(screen);
+		int new_height      = get_height() + ARROW_LENGTH;
+
+		/*
+		 * TODO: Maybe try to make the notification stay in the workarea,
+		 *       and just extend the arrow? Dunno.
+		 */
+
+		x = CLAMP(hint_x, 0, screen_width  - req.width);
+		y = CLAMP(hint_y, 0, screen_height - new_height);
+
+		gtk_widget_realize(window);
+		GdkRegion *win_region =
+			gdk_drawable_get_clip_region(GDK_DRAWABLE(window->window));
+
+		/* TODO: Be smarter about the location of the arrow. */
+		GdkPoint points[7];
+		points[0].x = 0;
+		points[0].y = ARROW_LENGTH;
+
+		points[1].x = 10;
+		points[1].y = ARROW_LENGTH;
+
+		points[2].x = 10;
+		points[2].y = 0;
+
+		points[3].x = 20;
+		points[3].y = ARROW_LENGTH;
+
+		points[4].x = req.width;
+		points[4].y = ARROW_LENGTH;
+
+		points[5].x = req.width;
+		points[5].y = new_height;
+
+		points[6].x = 0;
+		points[6].y = new_height;
+
+		GdkRegion *region = gdk_region_polygon(points, G_N_ELEMENTS(points),
+											   GDK_EVEN_ODD_RULE);
+
+//		gdk_window_shape_combine_region(window->window, region, 0, 0);
+	}
+	else
+	{
+		x = workarea.x + workarea.width - req.width;
+		y = workarea.y + workarea.height - get_height() - height_offset;
+	}
+
+    gtk_window_move(GTK_WINDOW(window), x, y);
 }
 
 bool

Modified: trunk/notification-daemon/src/main.cpp
===================================================================
--- trunk/notification-daemon/src/main.cpp	2005-07-01 06:42:29 UTC (rev 1995)
+++ trunk/notification-daemon/src/main.cpp	2005-07-01 06:49:58 UTC (rev 1996)
@@ -72,6 +72,93 @@
 static GMainLoop *loop;
 static DBusConnection *dbus_conn;
 
+static GHashTable *
+read_dict(DBusMessageIter *iter, char valueType)
+{
+	DBusMessageIter dict_iter;
+	GDestroyNotify value_destroy_func = NULL;
+
+	if (valueType == DBUS_TYPE_UINT32)
+	{
+		value_destroy_func = NULL;
+	}
+	else if (valueType == DBUS_TYPE_STRING)
+	{
+		value_destroy_func = g_free;
+	}
+	else
+	{
+		ERROR("Unknown D-BUS type %c passed to read_table\n", valueType);
+		return NULL;
+	}
+
+	GHashTable *table = g_hash_table_new_full(g_str_hash, g_str_equal,
+											  g_free, value_destroy_func);
+
+#if NOTIFYD_CHECK_DBUS_VERSION(0, 30)
+	dbus_message_iter_recurse(iter, &dictiter);
+
+	while (dbus_message_iter_get_arg_type(&hint_iter) == DBUS_TYPE_DICT_ENTRY)
+	{
+		DBusMessageIter entry_iter;
+		char *key;
+		void *value;
+
+		dbus_message_iter_recurse(&dict_iter, &etnry_iter);
+		dbus_message_iter_get_basic(&entry_iter, &key);
+		dbus_message_iter_next(&entry_iter);
+		dbus_message_iter_get_basic(&entry_iter, &value);
+
+		g_hash_table_replace(table, key, value);
+	}
+#else /* D-BUS < 0.30 */
+	if (dbus_message_iter_init_dict_iterator(iter, &dict_iter))
+	{
+		do
+		{
+			char *key = dbus_message_iter_get_dict_key(&dict_iter);
+
+			if (valueType == DBUS_TYPE_STRING)
+			{
+				char *value = dbus_message_iter_get_string(&dict_iter);
+
+				g_hash_table_replace(table, g_strdup(key), g_strdup(value));
+
+				dbus_free(value);
+			}
+			else if (valueType == DBUS_TYPE_UINT32)
+			{
+				dbus_uint32_t value = dbus_message_iter_get_uint32(&dict_iter);
+
+				g_hash_table_replace(table, g_strdup(key),
+									 GINT_TO_POINTER(value));
+			}
+
+			dbus_free(key);
+		}
+		while (dbus_message_iter_next(&dict_iter));
+	}
+#endif /* D-BUS < 0.30 */
+
+	return table;
+}
+
+static void
+action_foreach_func(const char *key, gpointer value, Notification *n)
+{
+	/*
+	 * Confusingly on the wire, the dict maps action text to ID,
+	 * whereas internally we map the id to the action text.
+	 */
+	n->actions[GPOINTER_TO_INT(value)] = g_strdup(key);
+}
+
+static void
+hint_foreach_func(const char *key, const char *value, Notification *n)
+{
+	n->hints[key] = value;
+}
+
 static DBusMessage *
 handle_notify(DBusConnection *incoming, DBusMessage *message)
 {
@@ -237,57 +324,21 @@
     /*********************************************************************
      * Actions
      *********************************************************************/
-	DBusMessageIter action_iter;
-
 #if NOTIFYD_CHECK_DBUS_VERSION(0, 30)
     validate(type == DBUS_TYPE_ARRAY, NULL,
              "Invalid notify message. Actions argument is not an array\n" );
-
-	dbus_message_iter_recurse(&iter, &action_iter);
 #else
     validate(type == DBUS_TYPE_DICT, NULL,
              "Invalid notify message. Actions argument is not a dict\n" );
-
-	dbus_message_iter_init_dict_iterator(&iter, &action_iter);
 #endif
 
-#if NOTIFYD_CHECK_DBUS_VERSION(0, 30)
-	while (dbus_message_iter_get_arg_type(&action_iter) == DBUS_TYPE_DICT_ENTRY)
-#else
-	do
-#endif
+	GHashTable *actions = read_dict(&iter, DBUS_TYPE_UINT32);
+
+	if (actions != NULL)
 	{
-		/*
-		 * Confusingly on the wire, the dict maps action text to ID,
-		 * whereas internally we map the id to the action text.
-		 */
-		char *key;
-		uint actionid;
-
-#if NOTIFYD_CHECK_DBUS_VERSION(0, 30)
-		DBusMessageIter entry_iter;
-		dbus_message_iter_recurse(&action_iter, &entry_iter);
-		dbus_message_iter_get_basic(&entry_iter, &key);
-		dbus_message_iter_next(&entry_iter);
-		dbus_message_iter_get_basic(&entry_iter, &actionid);
-#else
-		key = dbus_message_iter_get_dict_key(&action_iter);
-		actionid = dbus_message_iter_get_uint32(&action_iter);
-#endif
-
-		TRACE("demarshal: action %d : %s\n", actionid, key);
-
-		n->actions[actionid] = strdup(key);
-
-#if !NOTIFYD_CHECK_DBUS_VERSION(0, 30)
-		dbus_free(key);
-#else
-		dbus_message_iter_next(&action_iter);
-#endif
+		g_hash_table_foreach(actions, (GHFunc)action_foreach_func, n);
+		g_hash_table_destroy(actions);
 	}
-#if !NOTIFYD_CHECK_DBUS_VERSION(0, 30)
-	while (dbus_message_iter_next(&action_iter));
-#endif
 
     dbus_message_iter_next(&iter);
 
@@ -301,6 +352,29 @@
     validate(type == DBUS_TYPE_DICT, NULL,
              "Invalid notify message. Hints argument is not a dict\n" );
 #endif
+
+	GHashTable *hints = read_dict(&iter, DBUS_TYPE_STRING);
+
+	if (hints != NULL)
+	{
+		char *x = (char *)g_hash_table_lookup(hints, "x");
+		char *y = (char *)g_hash_table_lookup(hints, "y");
+
+		if (x != NULL && y != NULL)
+		{
+			n->hint_x = atoi(x);
+			n->hint_y = atoi(y);
+		}
+		else
+		{
+			n->hint_x = -1;
+			n->hint_y = -1;
+		}
+
+		g_hash_table_foreach(hints, (GHFunc)hint_foreach_func, n);
+		g_hash_table_destroy(hints);
+	}
+
     dbus_message_iter_next(&iter);
 
     /*********************************************************************

Modified: trunk/notification-daemon/src/notifier.h
===================================================================
--- trunk/notification-daemon/src/notifier.h	2005-07-01 06:42:29 UTC (rev 1995)
+++ trunk/notification-daemon/src/notifier.h	2005-07-01 06:49:58 UTC (rev 1996)
@@ -67,6 +67,7 @@
  */
 
 typedef std::map<int, char*> ActionsMap;
+typedef std::map<std::string, std::string> HintsMap;
 typedef std::vector<Image*> ImageList;
 
 class Notification
@@ -81,9 +82,13 @@
     bool use_timeout;         /* should the notification ever time out? */
 
     ActionsMap actions;       /* the mapping of action ids to action strings */
+	HintsMap hints;          /* The mapping of hints. */
 
     int id;
 
+	int hint_x;
+	int hint_y;
+
     /* the connection which generated this notification. used for signal dispatch */
     DBusConnection *connection;
 
@@ -94,6 +99,9 @@
     virtual void update() {;} /* called when the contents have changed */
 
     virtual void action_invoke(uint aid);
+
+protected:
+	static const int ARROW_LENGTH = 20;
 };
 
 typedef std::map<int, Notification*> NotificationsMap;



More information about the galago-commits mailing list