Mercurial > dwindows
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: |