diff gtk/dw.c @ 2066:2c2530f8cbef

Initial design for system notification support on GTK. Windows, Mac and possibly OS/2 Support will follow. GTK support requires Glib 2.40 or higher.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 14 May 2020 01:52:27 +0000
parents f7c462f27829
children c2f13c5eefac
line wrap: on
line diff
--- a/gtk/dw.c	Mon Apr 27 08:55:40 2020 +0000
+++ b/gtk/dw.c	Thu May 14 01:52:27 2020 +0000
@@ -119,6 +119,9 @@
 GdkPixmap *_dw_tmppixmap = NULL;
 GdkBitmap *_dw_tmpbitmap = NULL;
 
+#if GLIB_CHECK_VERSION(2,28,0)
+GApplication *_DWApp = NULL;
+#endif
 char *_DWDefaultFont = NULL;
 static char _dw_share_path[PATH_MAX+1] = { 0 };
 
@@ -1976,6 +1979,8 @@
 }
 #endif
 
+#define DW_APP_DOMAIN_DEFAULT "org.dbsoft.dwindows"
+
 /*
  * Initializes the Dynamic Windows engine.
  * Parameters:
@@ -1990,6 +1995,12 @@
       "1 1 1 1",
       " 	c None",
       " "};
+#if GLIB_CHECK_VERSION(2,28,0)
+   char appid[101] = {0};
+   
+   /* Generate an Application ID based on the PID initially. */
+   snprintf(appid, 100, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid());
+#endif
 
    if(res)
    {
@@ -2024,6 +2035,10 @@
             strcpy(_dw_share_path, "/usr/local");
          strcat(_dw_share_path, "/share/");
          strcat(_dw_share_path, binname);
+#if GLIB_CHECK_VERSION(2,28,0)
+         /* If we have a binary name, use that for the Application ID instead. */
+         snprintf(appid, 100, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname);
+#endif
       }
       if(pathcopy)
          free(pathcopy);
@@ -2094,6 +2109,15 @@
       dbgfp = fopen( fname, "w" );
    }
 
+#if GLIB_CHECK_VERSION(2,28,0)
+   /* Initialize the application subsystem on supported versions...
+    * we generate an application ID based on the binary name or PID
+    * instead of passing NULL to enable full application support.
+    */
+   _DWApp = g_application_new(appid, G_APPLICATION_FLAGS_NONE);
+   if(g_application_register(_DWApp, NULL, NULL))
+      g_application_activate(_DWApp);
+#endif
    return TRUE;
 }
 
@@ -12299,6 +12323,75 @@
 }
 
 /*
+ * Creates a new system notification if possible.
+ * Parameters:
+ *         title: The short title of the notification.
+ *         pixmap: Handle to an image to display or NULL if none.
+ *         description: A longer description of the notification,
+ *                      or NULL if none is necessary.
+ * Returns:
+ *         A handle to the notification which can be used to attach a "clicked" event if desired,
+ *         or NULL if it fails or notifications are not supported by the system.
+ * Remarks:
+ *          This will create a system notification that will show in the notifaction panel 
+ *          on supported systems, which may be clicked to perform another task.
+ */
+HWND dw_notification_new(const char *title, HPIXMAP pixmap, const char *description, ...)
+{
+#if GLIB_CHECK_VERSION(2,40,0)
+   GNotification *notification = g_notification_new(title);
+   
+   if(notification)
+   {
+      if(description)
+      {
+         va_list args;
+         char outbuf[1025] = {0};
+
+         va_start(args, description);
+         vsnprintf(outbuf, 1024, description, args);
+         va_end(args);
+
+         g_notification_set_body(notification, outbuf);
+      }
+#if GTK_MAJOR_VERSION > 1
+      /* GTK 1.x is not implemented as pixbuf, so only allow icons on 2.x */
+      if(pixmap && pixmap->pixbuf)
+         g_notification_set_icon(notification, G_ICON(pixmap->pixbuf));
+#endif         
+   }
+   return (HWND)notification;
+#else
+   return NULL;
+#endif
+}
+
+/*
+ * Sends a notification created by dw_notification_new() after attaching signal handler.
+ * Parameters:
+ *         notification: The handle to the notification returned by dw_notification_new().
+ * Returns:
+ *         DW_ERROR_NONE on success, DW_ERROR_UNKNOWN on error or not supported.
+ */
+int dw_notification_send(HWND notification)
+{
+#if GLIB_CHECK_VERSION(2,40,0)
+   if(notification)
+   {
+      char id[101] = {0};
+      
+      /* Generate a unique ID based on the notification handle, 
+       * so we can use it to remove the notification in dw_window_destroy().
+       */
+      snprintf(id, 100, "dw-notification-%llu", (unsigned long long)notification);
+      g_application_send_notification(_DWApp, id, (GNotification *)notification);
+      return DW_ERROR_NONE;
+   }
+#endif
+   return DW_ERROR_UNKNOWN;
+}
+
+/*
  * Returns some information about the current operating environment.
  * Parameters:
  *       env: Pointer to a DWEnv struct.