comparison gtk4/dw.c @ 2857:59106bf7f9f4

GTK2/3/4: Refactor dw_init(), splitting off path detection into _dw_init_path(). Using argv[0] to detect the executable path is very inaccurate, so we will add platform specific code for Linux and FreeBSD to query the executable path. If platform specific code fails, fall back to argv[0] like before.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 15 Nov 2022 10:18:52 +0000
parents 86286f528adf
children ecfbc48e933a
comparison
equal deleted inserted replaced
2856:de1a0cd26691 2857:59106bf7f9f4
36 #ifdef USE_WEBKIT 36 #ifdef USE_WEBKIT
37 #include <webkit2/webkit2.h> 37 #include <webkit2/webkit2.h>
38 #endif 38 #endif
39 39
40 #include <gdk-pixbuf/gdk-pixbuf.h> 40 #include <gdk-pixbuf/gdk-pixbuf.h>
41
42 #ifdef __FreeBSD__
43 #include <sys/param.h>
44 #include <sys/sysctl.h>
45 #endif
41 46
42 #if __STDC_VERSION__ < 199901L 47 #if __STDC_VERSION__ < 199901L
43 # if __GNUC__ >= 2 48 # if __GNUC__ >= 2
44 # define __func__ __FUNCTION__ 49 # define __func__ __FUNCTION__
45 # else 50 # else
1501 * when this signal is not connected, so putting this here to 1506 * when this signal is not connected, so putting this here to
1502 * quell the warning and can be used at a later point if needed. 1507 * quell the warning and can be used at a later point if needed.
1503 */ 1508 */
1504 } 1509 }
1505 1510
1506 /* 1511 void _dw_init_path(char *arg)
1507 * Initializes the Dynamic Windows engine. 1512 {
1508 * Parameters: 1513 char path[PATH_MAX+1] = {0};
1509 * newthread: True if this is the only thread. 1514
1510 * False if there is already a message loop running. 1515 #ifdef __linux__
1511 */ 1516 if(readlink("/proc/self/exe", path, PATH_MAX) == -1)
1512 int API dw_init(int newthread, int argc, char *argv[]) 1517 #elif defined(__FreeBSD__)
1513 { 1518 int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
1514 /* Setup the private data directory */ 1519 size_t length = PATH_MAX;
1515 if(argc > 0 && argv[0]) 1520
1516 { 1521 if(sysctl(name, 4, exe, &length, NULL, 0) == -1 || length <= 1)
1517 char *pathcopy = strdup(argv[0]); 1522 #endif
1518 char *pos = strrchr(pathcopy, '/'); 1523 strncpy(path, arg ? arg : "", PATH_MAX);
1519 char *binname = pathcopy; 1524
1525 if(path[0])
1526 {
1527 char *pos = strrchr(path, '/');
1528 char *binname = path;
1520 1529
1521 /* If we have a / then... 1530 /* If we have a / then...
1522 * the binary name should be at the end. 1531 * the binary name should be at the end.
1523 */ 1532 */
1524 if(pos) 1533 if(pos)
1527 *pos = 0; 1536 *pos = 0;
1528 } 1537 }
1529 1538
1530 if(*binname) 1539 if(*binname)
1531 { 1540 {
1532 char *binpos = strstr(pathcopy, "/bin"); 1541 char *binpos = strstr(path, "/bin");
1533 1542
1534 if(binpos) 1543 if(binpos)
1535 strncpy(_dw_share_path, pathcopy, (size_t)(binpos - pathcopy)); 1544 strncpy(_dw_share_path, path, (size_t)(binpos - path));
1536 else 1545 else
1537 strcpy(_dw_share_path, "/usr/local"); 1546 strcpy(_dw_share_path, "/usr/local");
1538 strcat(_dw_share_path, "/share/"); 1547 strcat(_dw_share_path, "/share/");
1539 strcat(_dw_share_path, binname); 1548 strcat(_dw_share_path, binname);
1540 if(!_dw_app_id[0]) 1549 if(!_dw_app_id[0])
1541 { 1550 {
1542 /* If we have a binary name, use that for the Application ID instead. */ 1551 /* If we have a binary name, use that for the Application ID instead. */
1543 snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname); 1552 snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname);
1544 } 1553 }
1545 } 1554 }
1546 if(pathcopy) 1555 }
1547 free(pathcopy);
1548 }
1549 /* If that failed... just get the current directory */ 1556 /* If that failed... just get the current directory */
1550 if(!_dw_share_path[0] && !getcwd(_dw_share_path, PATH_MAX)) 1557 if(!_dw_share_path[0] && !getcwd(_dw_share_path, PATH_MAX))
1551 _dw_share_path[0] = '/'; 1558 _dw_share_path[0] = '/';
1559 }
1560
1561 /*
1562 * Initializes the Dynamic Windows engine.
1563 * Parameters:
1564 * newthread: True if this is the only thread.
1565 * False if there is already a message loop running.
1566 */
1567 int API dw_init(int newthread, int argc, char *argv[])
1568 {
1569 /* Setup the private data directory */
1570 _dw_init_path(argc > 0 ? argv[0] : NULL);
1552 1571
1553 gtk_init(); 1572 gtk_init();
1554 1573
1555 _DWMainLoop = g_main_loop_new(NULL, FALSE); 1574 _DWMainLoop = g_main_loop_new(NULL, FALSE);
1556 g_main_loop_ref(_DWMainLoop); 1575 g_main_loop_ref(_DWMainLoop);