comparison gtk3/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
comparison
equal deleted inserted replaced
2065:2dacac5e4023 2066:2c2530f8cbef
1 /* 1 /*
2 * Dynamic Windows: 2 * Dynamic Windows:
3 * A GTK like cross-platform GUI 3 * A GTK like cross-platform GUI
4 * GTK3 forwarder module for portabilty. 4 * GTK3 forwarder module for portabilty.
5 * 5 *
6 * (C) 2000-2019 Brian Smith <brian@dbsoft.org> 6 * (C) 2000-2020 Brian Smith <brian@dbsoft.org>
7 * (C) 2003-2011 Mark Hessling <mark@rexx.org> 7 * (C) 2003-2011 Mark Hessling <mark@rexx.org>
8 * (C) 2002 Nickolay V. Shmyrev <shmyrev@yandex.ru> 8 * (C) 2002 Nickolay V. Shmyrev <shmyrev@yandex.ru>
9 */ 9 */
10 #include "config.h" 10 #include "config.h"
11 #include "dw.h" 11 #include "dw.h"
167 #endif 167 #endif
168 #endif 168 #endif
169 static void _dw_signal_disconnect(gpointer data, GClosure *closure); 169 static void _dw_signal_disconnect(gpointer data, GClosure *closure);
170 170
171 GObject *_DWObject = NULL; 171 GObject *_DWObject = NULL;
172 #if GLIB_CHECK_VERSION(2,28,0)
173 GApplication *_DWApp = NULL;
174 #endif
172 char *_DWDefaultFont = NULL; 175 char *_DWDefaultFont = NULL;
173 static char _dw_share_path[PATH_MAX+1] = { 0 }; 176 static char _dw_share_path[PATH_MAX+1] = { 0 };
174 177
175 typedef struct 178 typedef struct
176 { 179 {
1949 return icon_pixbuf; 1952 return icon_pixbuf;
1950 } 1953 }
1951 return NULL; 1954 return NULL;
1952 } 1955 }
1953 1956
1957 #define DW_APP_DOMAIN_DEFAULT "org.dbsoft.dwindows"
1958
1954 /* 1959 /*
1955 * Initializes the Dynamic Windows engine. 1960 * Initializes the Dynamic Windows engine.
1956 * Parameters: 1961 * Parameters:
1957 * newthread: True if this is the only thread. 1962 * newthread: True if this is the only thread.
1958 * False if there is already a message loop running. 1963 * False if there is already a message loop running.
1959 */ 1964 */
1960 int dw_int_init(DWResources *res, int newthread, int *argc, char **argv[]) 1965 int dw_int_init(DWResources *res, int newthread, int *argc, char **argv[])
1961 { 1966 {
1967 #if GLIB_CHECK_VERSION(2,28,0)
1968 char appid[101] = {0};
1969
1970 /* Generate an Application ID based on the PID initially. */
1971 snprintf(appid, 100, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid());
1972 #endif
1962 if(res) 1973 if(res)
1963 { 1974 {
1964 _resources.resource_max = res->resource_max; 1975 _resources.resource_max = res->resource_max;
1965 _resources.resource_id = res->resource_id; 1976 _resources.resource_id = res->resource_id;
1966 _resources.resource_data = res->resource_data; 1977 _resources.resource_data = res->resource_data;
1990 strncpy(_dw_share_path, pathcopy, (size_t)(binpos - pathcopy)); 2001 strncpy(_dw_share_path, pathcopy, (size_t)(binpos - pathcopy));
1991 else 2002 else
1992 strcpy(_dw_share_path, "/usr/local"); 2003 strcpy(_dw_share_path, "/usr/local");
1993 strcat(_dw_share_path, "/share/"); 2004 strcat(_dw_share_path, "/share/");
1994 strcat(_dw_share_path, binname); 2005 strcat(_dw_share_path, binname);
2006 #if GLIB_CHECK_VERSION(2,28,0)
2007 /* If we have a binary name, use that for the Application ID instead. */
2008 snprintf(appid, 100, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname);
2009 #endif
1995 } 2010 }
1996 if(pathcopy) 2011 if(pathcopy)
1997 free(pathcopy); 2012 free(pathcopy);
1998 } 2013 }
1999 /* If that failed... just get the current directory */ 2014 /* If that failed... just get the current directory */
2019 2034
2020 _dw_init_thread(); 2035 _dw_init_thread();
2021 2036
2022 /* Create a global object for glib activities */ 2037 /* Create a global object for glib activities */
2023 _DWObject = g_object_new(G_TYPE_OBJECT, NULL); 2038 _DWObject = g_object_new(G_TYPE_OBJECT, NULL);
2024 2039
2040 #if GLIB_CHECK_VERSION(2,28,0)
2041 /* Initialize the application subsystem on supported versions...
2042 * we generate an application ID based on the binary name or PID
2043 * instead of passing NULL to enable full application support.
2044 */
2045 _DWApp = g_application_new(appid, G_APPLICATION_FLAGS_NONE);
2046 if(g_application_register(_DWApp, NULL, NULL))
2047 g_application_activate(_DWApp);
2048 #endif
2025 return TRUE; 2049 return TRUE;
2026 } 2050 }
2027 2051
2028 /* 2052 /*
2029 * Runs a message loop for Dynamic Windows. 2053 * Runs a message loop for Dynamic Windows.
11000 DW_MUTEX_LOCK; 11024 DW_MUTEX_LOCK;
11001 g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(_default_key_press_event), next); 11025 g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(_default_key_press_event), next);
11002 DW_MUTEX_UNLOCK; 11026 DW_MUTEX_UNLOCK;
11003 } 11027 }
11004 11028
11029
11030 /*
11031 * Creates a new system notification if possible.
11032 * Parameters:
11033 * title: The short title of the notification.
11034 * pixmap: Handle to an image to display or NULL if none.
11035 * description: A longer description of the notification,
11036 * or NULL if none is necessary.
11037 * Returns:
11038 * A handle to the notification which can be used to attach a "clicked" event if desired,
11039 * or NULL if it fails or notifications are not supported by the system.
11040 * Remarks:
11041 * This will create a system notification that will show in the notifaction panel
11042 * on supported systems, which may be clicked to perform another task.
11043 */
11044 HWND dw_notification_new(const char *title, HPIXMAP pixmap, const char *description, ...)
11045 {
11046 #if GLIB_CHECK_VERSION(2,40,0)
11047 GNotification *notification = g_notification_new(title);
11048
11049 if(notification)
11050 {
11051 if(description)
11052 {
11053 va_list args;
11054 char outbuf[1025] = {0};
11055
11056 va_start(args, description);
11057 vsnprintf(outbuf, 1024, description, args);
11058 va_end(args);
11059
11060 g_notification_set_body(notification, outbuf);
11061 }
11062 if(pixmap && pixmap->pixbuf)
11063 g_notification_set_icon(notification, G_ICON(pixmap->pixbuf));
11064 }
11065 return (HWND)notification;
11066 #else
11067 return NULL;
11068 #endif
11069 }
11070
11071 /*
11072 * Sends a notification created by dw_notification_new() after attaching signal handler.
11073 * Parameters:
11074 * notification: The handle to the notification returned by dw_notification_new().
11075 * Returns:
11076 * DW_ERROR_NONE on success, DW_ERROR_UNKNOWN on error or not supported.
11077 */
11078 int dw_notification_send(HWND notification)
11079 {
11080 #if GLIB_CHECK_VERSION(2,40,0)
11081 if(notification)
11082 {
11083 char id[101] = {0};
11084
11085 /* Generate a unique ID based on the notification handle,
11086 * so we can use it to remove the notification in dw_window_destroy().
11087 */
11088 snprintf(id, 100, "dw-notification-%llu", (unsigned long long)notification);
11089 g_application_send_notification(_DWApp, id, (GNotification *)notification);
11090 return DW_ERROR_NONE;
11091 }
11092 #endif
11093 return DW_ERROR_UNKNOWN;
11094 }
11095
11005 /* 11096 /*
11006 * Returns some information about the current operating environment. 11097 * Returns some information about the current operating environment.
11007 * Parameters: 11098 * Parameters:
11008 * env: Pointer to a DWEnv struct. 11099 * env: Pointer to a DWEnv struct.
11009 */ 11100 */