comparison win/dw.c @ 2088:94ea915bd917

Win: Initial implementation of notifications on Windows. Currently using WinToast. Update readme regarding WinToast support and in-source comments regarding the API. Fix missing "API" calling conventions on OS/2 and Windows.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 05 Jun 2020 16:27:00 +0000
parents f1acc157b2dd
children bcc7877dcdac
comparison
equal deleted inserted replaced
2087:082d743f3214 2088:94ea915bd917
276 * an alternate temporary directory if TMP is not set, so we get the value 276 * an alternate temporary directory if TMP is not set, so we get the value
277 * of TEMP and store it here. 277 * of TEMP and store it here.
278 */ 278 */
279 static char _dw_alternate_temp_dir[MAX_PATH+1] = {0}; 279 static char _dw_alternate_temp_dir[MAX_PATH+1] = {0};
280 static char _dw_exec_dir[MAX_PATH+1] = {0}; 280 static char _dw_exec_dir[MAX_PATH+1] = {0};
281 #ifdef BUILD_TOAST
281 static char _dw_app_id[101]= {0}; 282 static char _dw_app_id[101]= {0};
283 static char _dw_app_name[101]= {0};
284 #endif
282 285
283 int main(int argc, char *argv[]); 286 int main(int argc, char *argv[]);
284 287
285 #define ICON_INDEX_LIMIT 200 288 #define ICON_INDEX_LIMIT 200
286 HICON lookup[200]; 289 HICON lookup[200];
315 BOOL _dw_edge_detect(VOID); 318 BOOL _dw_edge_detect(VOID);
316 BOOL _DW_EDGE_DETECTED = FALSE; 319 BOOL _DW_EDGE_DETECTED = FALSE;
317 LRESULT CALLBACK _edgeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 320 LRESULT CALLBACK _edgeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
318 #endif 321 #endif
319 #endif 322 #endif
323 #ifdef BUILD_TOAST
324 void _dw_toast_init(LPWSTR AppName, LPWSTR AppID);
325 void *_dw_notification_new(LPWSTR title, LPWSTR image, LPWSTR description);
326 int _dw_notification_send(void *notification);
327 #endif
320 LRESULT CALLBACK _colorwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2); 328 LRESULT CALLBACK _colorwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2);
321 void _resize_notebook_page(HWND handle, int pageid); 329 void _resize_notebook_page(HWND handle, int pageid);
322 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y); 330 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
323 int _lookup_icon(HWND handle, HICON hicon, int type); 331 int _lookup_icon(HWND handle, HICON hicon, int type);
324 HFONT _acquire_font(HWND handle, const char *fontname); 332 HFONT _acquire_font(HWND handle, const char *fontname);
429 tmp++; 437 tmp++;
430 } 438 }
431 } 439 }
432 440
433 argv = (char **)malloc(sizeof(char *) * ((*count)+1)); 441 argv = (char **)malloc(sizeof(char *) * ((*count)+1));
434 argv[0] = malloc(260); 442 argv[0] = calloc(261, 1);
435 GetModuleFileNameA(DWInstance, argv[0], 260); 443 GetModuleFileNameA(DWInstance, argv[0], 260);
436 444
437 argstart = tmp = start; 445 argstart = tmp = start;
438 446
439 if(*start) 447 if(*start)
4243 /* Just to be safe try the unix style */ 4251 /* Just to be safe try the unix style */
4244 if(!pos) 4252 if(!pos)
4245 pos = strrchr(argv[0], '/'); 4253 pos = strrchr(argv[0], '/');
4246 4254
4247 if(pos) 4255 if(pos)
4256 {
4248 strncpy(_dw_exec_dir, argv[0], (size_t)(pos - argv[0])); 4257 strncpy(_dw_exec_dir, argv[0], (size_t)(pos - argv[0]));
4258 #ifdef BUILD_TOAST
4259 if((pos++) && !_dw_app_id[0])
4260 {
4261 /* If we have a binary name, use that for the Application ID instead. */
4262 snprintf(_dw_app_id, 100, "%s.%s", DW_APP_DOMAIN_DEFAULT, pos);
4263 strncpy(_dw_app_name, pos, 100);
4264 }
4265 #endif
4266 }
4249 } 4267 }
4250 /* If that failed... just get the current directory */ 4268 /* If that failed... just get the current directory */
4251 if(!_dw_exec_dir[0]) 4269 if(!_dw_exec_dir[0])
4252 GetCurrentDirectoryA(MAX_PATH, _dw_exec_dir); 4270 GetCurrentDirectoryA(MAX_PATH, _dw_exec_dir);
4253 4271
4404 wc.style = CS_HREDRAW | CS_VREDRAW; 4422 wc.style = CS_HREDRAW | CS_VREDRAW;
4405 #ifdef BUILD_EDGE 4423 #ifdef BUILD_EDGE
4406 /* Check if Microsoft Edge (Chromium) is installed */ 4424 /* Check if Microsoft Edge (Chromium) is installed */
4407 if (_DW_EDGE_DETECTED = _dw_edge_detect()) 4425 if (_DW_EDGE_DETECTED = _dw_edge_detect())
4408 { 4426 {
4409 wc.lpfnWndProc = (WNDPROC)_edgeWindowProc; 4427 wc.lpfnWndProc = (WNDPROC)_edgeWindowProc;
4410 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 4428 //wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
4411 } 4429 }
4412 else 4430 else
4413 #endif 4431 #endif
4414 { 4432 {
4415 wc.lpfnWndProc = (WNDPROC)_browserWindowProc; 4433 wc.lpfnWndProc = (WNDPROC)_browserWindowProc;
4416 } 4434 }
4417 RegisterClass(&wc); 4435 RegisterClass(&wc);
4418 #endif 4436 #endif
4419 4437
4420 /* Create a tooltip. */ 4438 /* Create a tooltip. */
4461 if(!(hmsftedit = LoadLibrary(TEXT("msftedit")))) 4479 if(!(hmsftedit = LoadLibrary(TEXT("msftedit"))))
4462 { 4480 {
4463 if(!(hrichedit = LoadLibrary(TEXT("riched20")))) 4481 if(!(hrichedit = LoadLibrary(TEXT("riched20"))))
4464 hrichedit = LoadLibrary(TEXT("riched32")); 4482 hrichedit = LoadLibrary(TEXT("riched32"));
4465 } 4483 }
4484 #endif
4485 #ifdef BUILD_TOAST
4486 if(!_dw_app_id[0])
4487 {
4488 /* Generate an Application ID based on the PID if all else fails. */
4489 snprintf(_dw_app_id, 100, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid());
4490 }
4491 if(!_dw_app_name[0])
4492 {
4493 /* If we still don't have an app name, get the executable name */
4494 char fullpath[261] = {0}, *pos;
4495 GetModuleFileNameA(DWInstance, fullpath, 260);
4496 pos = strrchr(fullpath, '\\');
4497 if(pos)
4498 pos++;
4499 strncpy(_dw_app_name, pos ? pos : fullpath, 100);
4500 }
4501 _dw_toast_init(UTF8toWide(_dw_app_name), UTF8toWide(_dw_app_id));
4466 #endif 4502 #endif
4467 return 0; 4503 return 0;
4468 } 4504 }
4469 4505
4470 static int _dw_main_running = FALSE; 4506 static int _dw_main_running = FALSE;
12356 * or NULL if it fails or notifications are not supported by the system. 12392 * or NULL if it fails or notifications are not supported by the system.
12357 * Remarks: 12393 * Remarks:
12358 * This will create a system notification that will show in the notifaction panel 12394 * This will create a system notification that will show in the notifaction panel
12359 * on supported systems, which may be clicked to perform another task. 12395 * on supported systems, which may be clicked to perform another task.
12360 */ 12396 */
12361 HWND dw_notification_new(const char *title, HPIXMAP pixmap, const char *description, ...) 12397 HWND API dw_notification_new(const char *title, HPIXMAP pixmap, const char *description, ...)
12362 { 12398 {
12399 #ifdef BUILD_TOAST
12400 char outbuf[1025] = {0};
12401
12402 if(description)
12403 {
12404 va_list args;
12405
12406 va_start(args, description);
12407 vsnprintf(outbuf, 1024, description, args);
12408 va_end(args);
12409 }
12410 return (HWND)_dw_notification_new(UTF8toWide(title), NULL, UTF8toWide(outbuf));
12411 #else
12363 return NULL; 12412 return NULL;
12413 #endif
12364 } 12414 }
12365 12415
12366 /* 12416 /*
12367 * Sends a notification created by dw_notification_new() after attaching signal handler. 12417 * Sends a notification created by dw_notification_new() after attaching signal handler.
12368 * Parameters: 12418 * Parameters:
12369 * notification: The handle to the notification returned by dw_notification_new(). 12419 * notification: The handle to the notification returned by dw_notification_new().
12370 * Returns: 12420 * Returns:
12371 * DW_ERROR_NONE on success, DW_ERROR_UNKNOWN on error or not supported. 12421 * DW_ERROR_NONE on success, DW_ERROR_UNKNOWN on error or not supported.
12372 */ 12422 */
12373 int dw_notification_send(HWND notification) 12423 int API dw_notification_send(HWND notification)
12374 { 12424 {
12425 #ifdef BUILD_TOAST
12426 return _dw_notification_send((void *)notification);
12427 #else
12375 return DW_ERROR_UNKNOWN; 12428 return DW_ERROR_UNKNOWN;
12429 #endif
12376 } 12430 }
12377 12431
12378 /* 12432 /*
12379 * Returns some information about the current operating environment. 12433 * Returns some information about the current operating environment.
12380 * Parameters: 12434 * Parameters:
12827 12881
12828 /* 12882 /*
12829 * Sets the application ID used by this Dynamic Windows application instance. 12883 * Sets the application ID used by this Dynamic Windows application instance.
12830 * Parameters: 12884 * Parameters:
12831 * appid: A string typically in the form: com.company.division.application 12885 * appid: A string typically in the form: com.company.division.application
12832 * appguid: A globally unique identifier required on Windows or NULL. 12886 * appname: The application name used on Windows or NULL.
12833 * Returns: 12887 * Returns:
12834 * DW_ERROR_NONE after successfully setting the application ID. 12888 * DW_ERROR_NONE after successfully setting the application ID.
12835 * DW_ERROR_UNKNOWN if unsupported on this system. 12889 * DW_ERROR_UNKNOWN if unsupported on this system.
12836 * DW_ERROR_GENERAL if the application ID is not allowed. 12890 * DW_ERROR_GENERAL if the application ID is not allowed.
12837 * Remarks: 12891 * Remarks:
12838 * This must be called before dw_init(). If dw_init() is called first 12892 * This must be called before dw_init(). If dw_init() is called first
12839 * it will create a unique ID in the form: org.dbsoft.dwindows.application 12893 * it will create a unique ID in the form: org.dbsoft.dwindows.application
12840 * or if the application name cannot be detected: org.dbsoft.dwindows.pid.# 12894 * or if the application name cannot be detected: org.dbsoft.dwindows.pid.#
12841 * The GUID is only required on Windows, NULL can be passed on other platforms. 12895 * The appname is only required on Windows. If NULL is passed the detected
12842 */ 12896 * application name will be used, but a prettier name may be desired.
12843 int dw_app_id_set(const char *appid, const char *appguid) 12897 */
12844 { 12898 int API dw_app_id_set(const char *appid, const char *appname)
12899 {
12900 #ifdef BUILD_TOAST
12901 strncpy(_dw_app_id, appid, 100);
12902 if(appname)
12903 strncpy(_dw_app_name, appname, 100);
12904 return DW_ERROR_NONE;
12905 #else
12845 return DW_ERROR_UNKNOWN; 12906 return DW_ERROR_UNKNOWN;
12907 #endif
12846 } 12908 }
12847 12909
12848 /* 12910 /*
12849 * Call a function from the window (widget)'s context. 12911 * Call a function from the window (widget)'s context.
12850 * Parameters: 12912 * Parameters: