comparison os2/dw.c @ 55:b6948eac375a

Sync with the latest dynamic windows, tree fixes, and other miscellaneous stuff.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 21 Nov 2001 22:31:55 +0000
parents c4e1139d9872
children 5c66a108aa47
comparison
equal deleted inserted replaced
54:c4e1139d9872 55:b6948eac375a
43 LONG _foreground = 0xAAAAAA, _background = 0; 43 LONG _foreground = 0xAAAAAA, _background = 0;
44 44
45 HWND hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE; 45 HWND hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE;
46 PRECORDCORE pCore = NULL; 46 PRECORDCORE pCore = NULL;
47 ULONG aulBuffer[4]; 47 ULONG aulBuffer[4];
48 HWND lasthcnr = 0, lastitem = 0;
48 49
49 #define IS_WARP4() (aulBuffer[0] == 20 && aulBuffer[1] >= 40) 50 #define IS_WARP4() (aulBuffer[0] == 20 && aulBuffer[1] >= 40)
50 51
51 #ifndef min 52 #ifndef min
52 #define min(a, b) (((a < b) ? a : b)) 53 #define min(a, b) (((a < b) ? a : b))
90 char name[30]; 91 char name[30];
91 92
92 } SignalList; 93 } SignalList;
93 94
94 /* List of signals and their equivilent OS/2 message */ 95 /* List of signals and their equivilent OS/2 message */
95 #define SIGNALMAX 13 96 #define SIGNALMAX 14
96 97
97 SignalList SignalTranslate[SIGNALMAX] = { 98 SignalList SignalTranslate[SIGNALMAX] = {
98 { WM_SIZE, "configure_event" }, 99 { WM_SIZE, "configure_event" },
99 { WM_CHAR, "key_press_event" }, 100 { WM_CHAR, "key_press_event" },
100 { WM_BUTTON1DOWN, "button_press_event" }, 101 { WM_BUTTON1DOWN, "button_press_event" },
105 { WM_COMMAND, "clicked" }, 106 { WM_COMMAND, "clicked" },
106 { CN_ENTER, "container-select" }, 107 { CN_ENTER, "container-select" },
107 { CN_CONTEXTMENU, "container-context" }, 108 { CN_CONTEXTMENU, "container-context" },
108 { LN_SELECT, "item-select" }, 109 { LN_SELECT, "item-select" },
109 { CN_EMPHASIS, "tree-select" }, 110 { CN_EMPHASIS, "tree-select" },
110 { WM_SETFOCUS, "set-focus" } 111 { WM_SETFOCUS, "set-focus" },
112 { WM_USER+1, "lose-focus" }
111 }; 113 };
112 114
113 /* This function adds a signal handler callback into the linked list. 115 /* This function adds a signal handler callback into the linked list.
114 */ 116 */
115 void _new_signal(ULONG message, HWND window, void *signalfunction, void *data) 117 void _new_signal(ULONG message, HWND window, void *signalfunction, void *data)
116 { 118 {
117 SignalHandler *new = malloc(sizeof(SignalHandler)); 119 SignalHandler *new = malloc(sizeof(SignalHandler));
120
121 #ifndef NO_SIGNALS
122 if(message == WM_COMMAND)
123 dw_signal_disconnect_by_window(window);
124 #endif
118 125
119 new->message = message; 126 new->message = message;
120 new->window = window; 127 new->window = window;
121 new->signalfunction = signalfunction; 128 new->signalfunction = signalfunction;
122 new->data = data; 129 new->data = data;
186 } 193 }
187 WinEndEnumWindows(henum); 194 WinEndEnumWindows(henum);
188 return; 195 return;
189 } 196 }
190 197
198 void _disconnect_windows(HWND handle)
199 {
200 HENUM henum;
201 HWND child;
202
203 #ifndef NO_SIGNALS
204 dw_signal_disconnect_by_window(handle);
205 #endif
206
207 henum = WinBeginEnumWindows(handle);
208 while((child = WinGetNextWindow(henum)) != NULLHANDLE)
209 _disconnect_windows(child);
210
211 WinEndEnumWindows(henum);
212 }
213
191 /* This function removes and handlers on windows and frees 214 /* This function removes and handlers on windows and frees
192 * the user memory allocated to it. 215 * the user memory allocated to it.
193 */ 216 */
194 void _free_window_memory(HWND handle) 217 void _free_window_memory(HWND handle)
195 { 218 {
231 WinQueryClassName(handle, 99, tmpbuf); 254 WinQueryClassName(handle, 99, tmpbuf);
232 255
233 /* These are the window classes which can 256 /* These are the window classes which can
234 * obtain input focus. 257 * obtain input focus.
235 */ 258 */
236 if(strncmp(tmpbuf, "#2", 3)==0 || /* Entryfield */ 259 if(strncmp(tmpbuf, "#2", 3)==0 || /* Combobox */
237 strncmp(tmpbuf, "#3", 3)==0 || /* Button */ 260 strncmp(tmpbuf, "#3", 3)==0 || /* Button */
238 strncmp(tmpbuf, "#6", 3)==0 || /* Combobox */ 261 strncmp(tmpbuf, "#6", 3)==0 || /* Entryfield */
239 strncmp(tmpbuf, "#7", 3)==0 || /* List box */ 262 strncmp(tmpbuf, "#7", 3)==0 || /* List box */
240 strncmp(tmpbuf, "#10", 3)==0 || /* MLE */ 263 strncmp(tmpbuf, "#10", 3)==0 || /* MLE */
241 strncmp(tmpbuf, "#32", 3)==0 || /* Spinbutton */ 264 strncmp(tmpbuf, "#32", 3)==0 || /* Spinbutton */
242 strncmp(tmpbuf, "#37", 3)== 0) /* Container */ 265 strncmp(tmpbuf, "#37", 3)== 0) /* Container */
243 return 1; 266 return 1;
417 } 440 }
418 441
419 /* This function finds the first widget in the 442 /* This function finds the first widget in the
420 * layout and moves the current focus to it. 443 * layout and moves the current focus to it.
421 */ 444 */
422 void _initial_focus(HWND handle) 445 int _initial_focus(HWND handle)
423 { 446 {
424 Box *thisbox = NULL; 447 Box *thisbox = NULL;
425 HWND box; 448 HWND box;
426 449
427 box = WinWindowFromID(handle, FID_CLIENT); 450 box = WinWindowFromID(handle, FID_CLIENT);
428 if(box) 451 if(box)
429 thisbox = WinQueryWindowPtr(box, QWP_USER); 452 thisbox = WinQueryWindowPtr(box, QWP_USER);
453 else
454 return 1;
430 455
431 if(thisbox) 456 if(thisbox)
432 {
433 _focus_check_box(thisbox, handle, 3, thisbox->defaultitem); 457 _focus_check_box(thisbox, handle, 3, thisbox->defaultitem);
434 } 458 return 0;
435 } 459 }
436 460
437 /* This function finds the current widget in the 461 /* This function finds the current widget in the
438 * layout and moves the current focus to the next item. 462 * layout and moves the current focus to the next item.
439 */ 463 */
1236 } 1260 }
1237 else 1261 else
1238 WinSetFocus(HWND_DESKTOP, handle); 1262 WinSetFocus(HWND_DESKTOP, handle);
1239 } 1263 }
1240 1264
1265 MRESULT EXPENTRY _comboentryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1266 {
1267 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
1268
1269 switch(msg)
1270 {
1271 case WM_SETFOCUS:
1272 _run_event(hWnd, msg, mp1, mp2);
1273 break;
1274 }
1275
1276 if(blah && blah->oldproc)
1277 return blah->oldproc(hWnd, msg, mp1, mp2);
1278
1279 return WinDefWindowProc(hWnd, msg, mp1, mp2);
1280 }
1281
1241 /* Originally just intended for entryfields, it now serves as a generic 1282 /* Originally just intended for entryfields, it now serves as a generic
1242 * procedure for handling TAB presses to change input focus on controls. 1283 * procedure for handling TAB presses to change input focus on controls.
1243 */ 1284 */
1244 MRESULT EXPENTRY _entryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) 1285 MRESULT EXPENTRY _entryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1245 { 1286 {
1246 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); 1287 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
1288 PFNWP oldproc = 0;
1289
1290 if(blah)
1291 oldproc = blah->oldproc;
1247 1292
1248 switch(msg) 1293 switch(msg)
1249 { 1294 {
1250 case WM_BUTTON1DOWN: 1295 case WM_BUTTON1DOWN:
1251 case WM_BUTTON2DOWN: 1296 case WM_BUTTON2DOWN:
1271 else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault) 1316 else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
1272 _click_default(blah->clickdefault); 1317 _click_default(blah->clickdefault);
1273 1318
1274 break; 1319 break;
1275 } 1320 }
1276 if(blah && blah->oldproc) 1321
1277 return blah->oldproc(hWnd, msg, mp1, mp2); 1322 if(oldproc)
1323 return oldproc(hWnd, msg, mp1, mp2);
1278 1324
1279 return WinDefWindowProc(hWnd, msg, mp1, mp2); 1325 return WinDefWindowProc(hWnd, msg, mp1, mp2);
1280 } 1326 }
1281 1327
1282 /* Handle correct painting of a combobox with the WS_CLIPCHILDREN 1328 /* Handle correct painting of a combobox with the WS_CLIPCHILDREN
1283 * flag enabled, and also handle TABs to switch input focus. 1329 * flag enabled, and also handle TABs to switch input focus.
1284 */ 1330 */
1285 MRESULT EXPENTRY _comboproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) 1331 MRESULT EXPENTRY _comboproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1286 { 1332 {
1287 WindowData *blah = WinQueryWindowPtr(hWnd, QWP_USER); 1333 WindowData *blah = WinQueryWindowPtr(hWnd, QWP_USER);
1334 PFNWP oldproc = 0;
1335
1336 if(blah)
1337 oldproc = blah->oldproc;
1288 1338
1289 switch(msg) 1339 switch(msg)
1290 { 1340 {
1291 case WM_CHAR: 1341 case WM_CHAR:
1292 if(SHORT1FROMMP(mp2) == '\t') 1342 if(SHORT1FROMMP(mp2) == '\t')
1329 1379
1330 WinReleasePS(hpsPaint); 1380 WinReleasePS(hpsPaint);
1331 } 1381 }
1332 break; 1382 break;
1333 } 1383 }
1334 if(blah && blah->oldproc) 1384 if(oldproc)
1335 return blah->oldproc(hWnd, msg, mp1, mp2); 1385 return oldproc(hWnd, msg, mp1, mp2);
1336 1386
1337 return WinDefWindowProc(hWnd, msg, mp1, mp2); 1387 return WinDefWindowProc(hWnd, msg, mp1, mp2);
1338 } 1388 }
1339 1389
1340 void _GetPPFont(HWND hwnd, char *buff) 1390 void _GetPPFont(HWND hwnd, char *buff)
1393 msg = WM_BUTTON1UP; 1443 msg = WM_BUTTON1UP;
1394 1444
1395 /* Find any callbacks for this function */ 1445 /* Find any callbacks for this function */
1396 while(tmp) 1446 while(tmp)
1397 { 1447 {
1398 if(tmp->message == msg || msg == WM_CONTROL) 1448 if(tmp->message == msg || msg == WM_CONTROL || tmp->message == WM_USER+1)
1399 { 1449 {
1400 switch(msg) 1450 switch(msg)
1401 { 1451 {
1402 case WM_SETFOCUS: 1452 case WM_SETFOCUS:
1403 { 1453 {
1404 if(mp2) 1454 if((mp2 && tmp->message == WM_SETFOCUS) || (!mp2 && tmp->message == WM_USER+1))
1405 { 1455 {
1406 int (*setfocusfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction; 1456 int (*setfocusfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction;
1407 1457
1408 if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) 1458 if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd)
1409 { 1459 {
1614 dw_tree_item_select(tmp->window, (HWND)mp2); 1664 dw_tree_item_select(tmp->window, (HWND)mp2);
1615 pre.pRecord = mp2; 1665 pre.pRecord = mp2;
1616 pre.fEmphasisMask = CRA_CURSORED; 1666 pre.fEmphasisMask = CRA_CURSORED;
1617 pre.hwndCnr = tmp->window; 1667 pre.hwndCnr = tmp->window;
1618 _run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre); 1668 _run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre);
1669 pre.pRecord->flRecordAttr |= CRA_CURSORED;
1619 } 1670 }
1620 result = containercontextfunc(tmp->window, text, x, y, tmp->data, user); 1671 result = containercontextfunc(tmp->window, text, x, y, tmp->data, user);
1621 tmp = NULL; 1672 tmp = NULL;
1622 } 1673 }
1623 } 1674 }
1635 { 1686 {
1636 if(tmp->window == pre->hwndCnr) 1687 if(tmp->window == pre->hwndCnr)
1637 { 1688 {
1638 PCNRITEM pci = (PCNRITEM)pre->pRecord; 1689 PCNRITEM pci = (PCNRITEM)pre->pRecord;
1639 1690
1640 if(pci && pre->fEmphasisMask & CRA_CURSORED) 1691 if(pci && pre->fEmphasisMask & CRA_CURSORED && (pci->rc.flRecordAttr & CRA_CURSORED))
1641 { 1692 {
1642 int (*treeselectfunc)(HWND, HWND, char *, void *, void *) = (int (*)(HWND, HWND, char *, void *, void *))tmp->signalfunction; 1693 int (*treeselectfunc)(HWND, HWND, char *, void *, void *) = (int (*)(HWND, HWND, char *, void *, void *))tmp->signalfunction;
1643 1694
1644 result = treeselectfunc(tmp->window, (HWND)pci, pci->rc.pszIcon, pci->user, tmp->data); 1695 if(lasthcnr == tmp->window && lastitem == (HWND)pci)
1645 1696 {
1697 lasthcnr = 0;
1698 lastitem = 0;
1699 }
1700 else
1701 {
1702 lasthcnr = tmp->window;
1703 lastitem = (HWND)pci;
1704 result = treeselectfunc(tmp->window, (HWND)pci, pci->rc.pszIcon, pci->user, tmp->data);
1705 }
1646 tmp = NULL; 1706 tmp = NULL;
1647 } 1707 }
1648 } 1708 }
1649 } 1709 }
1650 emph_recurse = 0; 1710 emph_recurse = 0;
2785 2845
2786 thisbox->items = tmpitem; 2846 thisbox->items = tmpitem;
2787 free(thisitem); 2847 free(thisitem);
2788 thisbox->count--; 2848 thisbox->count--;
2789 } 2849 }
2790 _free_window_memory(handle); 2850 _disconnect_windows(handle);
2791 return WinDestroyWindow(handle); 2851 return WinDestroyWindow(handle);
2792 } 2852 }
2793 2853
2794 /* Causes entire window to be invalidated and redrawn. 2854 /* Causes entire window to be invalidated and redrawn.
2795 * Parameters: 2855 * Parameters:
3517 NULLHANDLE, 3577 NULLHANDLE,
3518 HWND_TOP, 3578 HWND_TOP,
3519 id, 3579 id,
3520 NULL, 3580 NULL,
3521 NULL); 3581 NULL);
3582 HENUM henum = WinBeginEnumWindows(tmp);
3583 HWND child;
3584
3585 while((child = WinGetNextWindow(henum)) != NULLHANDLE)
3586 {
3587 WindowData *moreblah = calloc(1, sizeof(WindowData));
3588 moreblah->oldproc = WinSubclassWindow(child, _comboentryproc);
3589 WinSetWindowPtr(child, QWP_USER, moreblah);
3590 }
3591 WinEndEnumWindows(henum);
3522 dw_window_set_font(tmp, DefaultFont); 3592 dw_window_set_font(tmp, DefaultFont);
3523 dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE); 3593 dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
3524 blah->oldproc = WinSubclassWindow(tmp, _comboproc); 3594 blah->oldproc = WinSubclassWindow(tmp, _comboproc);
3525 WinSetWindowPtr(tmp, QWP_USER, blah); 3595 WinSetWindowPtr(tmp, QWP_USER, blah);
3526 return tmp; 3596 return tmp;
4676 pci = WinSendMsg(handle, CM_ALLOCRECORD, MPFROMLONG(cbExtra), MPFROMSHORT(1)); 4746 pci = WinSendMsg(handle, CM_ALLOCRECORD, MPFROMLONG(cbExtra), MPFROMSHORT(1));
4677 4747
4678 /* Fill in the parent record data */ 4748 /* Fill in the parent record data */
4679 4749
4680 pci->rc.cb = sizeof(MINIRECORDCORE); 4750 pci->rc.cb = sizeof(MINIRECORDCORE);
4681 pci->rc.pszIcon = title; 4751 pci->rc.pszIcon = strdup(title);
4682 pci->rc.hptrIcon = icon; 4752 pci->rc.hptrIcon = icon;
4683 4753
4684 pci->hptrIcon = icon; 4754 pci->hptrIcon = icon;
4685 pci->user = itemdata; 4755 pci->user = itemdata;
4686 4756
4717 PCNRITEM pci = (PCNRITEM)item; 4787 PCNRITEM pci = (PCNRITEM)item;
4718 4788
4719 if(!pci) 4789 if(!pci)
4720 return; 4790 return;
4721 4791
4722 pci->rc.pszIcon = title; 4792 if(pci->rc.pszIcon)
4793 free(pci->rc.pszIcon);
4794
4795 pci->rc.pszIcon = strdup(title);
4723 pci->rc.hptrIcon = icon; 4796 pci->rc.hptrIcon = icon;
4724 4797
4725 pci->hptrIcon = icon; 4798 pci->hptrIcon = icon;
4726 4799
4727 WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED)); 4800 WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED));
4759 if(pCore->flRecordAttr & CRA_SELECTED) 4832 if(pCore->flRecordAttr & CRA_SELECTED)
4760 WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED)); 4833 WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED));
4761 pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); 4834 pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
4762 } 4835 }
4763 WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)item, MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED)); 4836 WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)item, MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED));
4837 lastitem = 0;
4838 lasthcnr = 0;
4764 } 4839 }
4765 4840
4766 /* 4841 /*
4767 * Removes all nodes from a tree. 4842 * Removes all nodes from a tree.
4768 * Parameters: 4843 * Parameters:
4802 * item: Handle to node to be deleted. 4877 * item: Handle to node to be deleted.
4803 */ 4878 */
4804 void dw_tree_delete(HWND handle, HWND item) 4879 void dw_tree_delete(HWND handle, HWND item)
4805 { 4880 {
4806 PCNRITEM pci = (PCNRITEM)item; 4881 PCNRITEM pci = (PCNRITEM)item;
4882
4883 if(!item)
4884 return;
4885
4886 if(pci->rc.pszIcon)
4887 free(pci->rc.pszIcon);
4888
4807 WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_INVALIDATE | CMA_FREE)); 4889 WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_INVALIDATE | CMA_FREE));
4808 } 4890 }
4809 4891
4810 /* Some OS/2 specific container structs */ 4892 /* Some OS/2 specific container structs */
4811 typedef struct _containerinfo { 4893 typedef struct _containerinfo {
6437 * Returns: 6519 * Returns:
6438 * -1 on error. 6520 * -1 on error.
6439 */ 6521 */
6440 int dw_exec(char *program, int type, char **params) 6522 int dw_exec(char *program, int type, char **params)
6441 { 6523 {
6442 return spawnvp(P_NOWAIT, program, params); 6524 return spawnvp(P_NOWAIT, program, (const char **)params);
6443 } 6525 }
6444 6526
6445 /* 6527 /*
6446 * Loads a web browser pointed at the given URL. 6528 * Loads a web browser pointed at the given URL.
6447 * Parameters: 6529 * Parameters:
6531 */ 6613 */
6532 void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) 6614 void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
6533 { 6615 {
6534 ULONG message = 0L; 6616 ULONG message = 0L;
6535 6617
6618 if(strcmp(signame, "lose-focus") == 0)
6619 {
6620 char tmpbuf[100];
6621
6622 WinQueryClassName(window, 99, tmpbuf);
6623
6624 if(strncmp(tmpbuf, "#2", 3) == 0)
6625 {
6626 HENUM henum = WinBeginEnumWindows(window);
6627 HWND child = WinGetNextWindow(henum);
6628 WinEndEnumWindows(henum);
6629 if(child)
6630 window = child;
6631 }
6632 }
6536 if(window && signame && sigfunc) 6633 if(window && signame && sigfunc)
6537 { 6634 {
6538 if((message = _findsigmessage(signame)) != 0) 6635 if((message = _findsigmessage(signame)) != 0)
6539 _new_signal(message, window, sigfunc, data); 6636 _new_signal(message, window, sigfunc, data);
6540 } 6637 }