comparison os2/dw.c @ 63:a6801a2260af

Synched up with the latest dynamic windows, has new slider support and transparency, focus, and other bug fixes on various platforms.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 14 Jan 2002 00:48:08 +0000
parents 2be5174bdb5d
children ab9b0fa6c66e
comparison
equal deleted inserted replaced
62:2be5174bdb5d 63:a6801a2260af
1 /* 1 /*
2 * Dynamic Windows: 2 * Dynamic Windows:
3 * A GTK like implementation of the PM GUI 3 * A GTK like implementation of the PM GUI
4 * 4 *
5 * (C) 2000,2001 Brian Smith <dbsoft@technologist.com> 5 * (C) 2000-2002 Brian Smith <dbsoft@technologist.com>
6 * (C) 2000 Achim Hasenmueller <achimha@innotek.de> 6 * (C) 2000 Achim Hasenmueller <achimha@innotek.de>
7 * (C) 2000 Peter Nielsen <peter@pmview.com> 7 * (C) 2000 Peter Nielsen <peter@pmview.com>
8 * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit) 8 * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit)
9 * 9 *
10 */ 10 */
91 char name[30]; 91 char name[30];
92 92
93 } SignalList; 93 } SignalList;
94 94
95 /* List of signals and their equivilent OS/2 message */ 95 /* List of signals and their equivilent OS/2 message */
96 #define SIGNALMAX 14 96 #define SIGNALMAX 15
97 97
98 SignalList SignalTranslate[SIGNALMAX] = { 98 SignalList SignalTranslate[SIGNALMAX] = {
99 { WM_SIZE, "configure_event" }, 99 { WM_SIZE, "configure_event" },
100 { WM_CHAR, "key_press_event" }, 100 { WM_CHAR, "key_press_event" },
101 { WM_BUTTON1DOWN, "button_press_event" }, 101 { WM_BUTTON1DOWN, "button_press_event" },
107 { CN_ENTER, "container-select" }, 107 { CN_ENTER, "container-select" },
108 { CN_CONTEXTMENU, "container-context" }, 108 { CN_CONTEXTMENU, "container-context" },
109 { LN_SELECT, "item-select" }, 109 { LN_SELECT, "item-select" },
110 { CN_EMPHASIS, "tree-select" }, 110 { CN_EMPHASIS, "tree-select" },
111 { WM_SETFOCUS, "set-focus" }, 111 { WM_SETFOCUS, "set-focus" },
112 { WM_USER+1, "lose-focus" } 112 { WM_USER+1, "lose-focus" },
113 { SLN_SLIDERTRACK, "value_changed" }
113 }; 114 };
114 115
115 /* This function adds a signal handler callback into the linked list. 116 /* This function adds a signal handler callback into the linked list.
116 */ 117 */
117 void _new_signal(ULONG message, HWND window, void *signalfunction, void *data) 118 void _new_signal(ULONG message, HWND window, void *signalfunction, void *data)
184 185
185 WinQueryClassName(child, 99, tmpbuf); 186 WinQueryClassName(child, 99, tmpbuf);
186 187
187 if(strncmp(tmpbuf, "#3", 3)==0 && dw) /* Button */ 188 if(strncmp(tmpbuf, "#3", 3)==0 && dw) /* Button */
188 WinSetOwner(child, dw); 189 WinSetOwner(child, dw);
189 if(strncmp(tmpbuf, "#38", 4)==0 && dw) /* Slider */
190 WinSetOwner(child, 0);
191 else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0) 190 else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0)
192 dw = child; 191 dw = child;
193 192
194 _fix_button_owner(child, dw); 193 _fix_button_owner(child, dw);
195 } 194 }
260 */ 259 */
261 if(strncmp(tmpbuf, "#2", 3)==0 || /* Combobox */ 260 if(strncmp(tmpbuf, "#2", 3)==0 || /* Combobox */
262 strncmp(tmpbuf, "#3", 3)==0 || /* Button */ 261 strncmp(tmpbuf, "#3", 3)==0 || /* Button */
263 strncmp(tmpbuf, "#6", 3)==0 || /* Entryfield */ 262 strncmp(tmpbuf, "#6", 3)==0 || /* Entryfield */
264 strncmp(tmpbuf, "#7", 3)==0 || /* List box */ 263 strncmp(tmpbuf, "#7", 3)==0 || /* List box */
265 strncmp(tmpbuf, "#10", 3)==0 || /* MLE */ 264 strncmp(tmpbuf, "#10", 4)==0 || /* MLE */
266 strncmp(tmpbuf, "#32", 3)==0 || /* Spinbutton */ 265 strncmp(tmpbuf, "#32", 4)==0 || /* Spinbutton */
267 strncmp(tmpbuf, "#37", 3)== 0) /* Container */ 266 strncmp(tmpbuf, "#37", 4)==0 || /* Container */
267 strncmp(tmpbuf, "#38", 4)== 0) /* Slider */
268 return 1; 268 return 1;
269 return 0; 269 return 0;
270 } 270 }
271 271
272 int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem) 272 int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem)
348 else 348 else
349 { 349 {
350 char tmpbuf[100] = ""; 350 char tmpbuf[100] = "";
351 351
352 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); 352 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf);
353 if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ 353 if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */
354 { 354 {
355 Box *notebox; 355 Box *notebox;
356 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, 356 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND,
357 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); 357 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0);
358 358
418 else 418 else
419 { 419 {
420 char tmpbuf[100] = ""; 420 char tmpbuf[100] = "";
421 421
422 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); 422 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf);
423 if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ 423 if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */
424 { 424 {
425 Box *notebox; 425 Box *notebox;
426 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, 426 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND,
427 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); 427 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0);
428 428
520 else 520 else
521 { 521 {
522 char tmpbuf[100] = ""; 522 char tmpbuf[100] = "";
523 523
524 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); 524 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf);
525 if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ 525 if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */
526 { 526 {
527 Box *notebox; 527 Box *notebox;
528 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, 528 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND,
529 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); 529 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0);
530 530
590 else 590 else
591 { 591 {
592 char tmpbuf[100] = ""; 592 char tmpbuf[100] = "";
593 593
594 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); 594 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf);
595 if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ 595 if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */
596 { 596 {
597 Box *notebox; 597 Box *notebox;
598 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, 598 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND,
599 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); 599 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0);
600 600
695 SWP swp; 695 SWP swp;
696 696
697 WinQueryWindowPos(hwndFrame, &swp); 697 WinQueryWindowPos(hwndFrame, &swp);
698 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, swp.cx, swp.cy-1, SWP_SIZE); 698 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, swp.cx, swp.cy-1, SWP_SIZE);
699 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, swp.cx, swp.cy, SWP_SIZE); 699 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, swp.cx, swp.cy, SWP_SIZE);
700 }
701
702 /* Focus toplevel window */
703 void _toplevel_focus(HWND handle)
704 {
705 HWND box, lastbox = WinQueryWindow(handle, QW_PARENT);
706
707 /* Find the toplevel window */
708 while((box = WinQueryWindow(lastbox, QW_PARENT)) > 0x80000001)
709 {
710 lastbox = box;
711 }
712
713 box = WinWindowFromID(lastbox, FID_CLIENT);
714 if(box)
715 WinSetActiveWindow(HWND_DESKTOP, lastbox);
700 } 716 }
701 717
702 /* This function will recursively search a box and add up the total height of it */ 718 /* This function will recursively search a box and add up the total height of it */
703 void _count_size(HWND box, int type, int *xsize, int *xorigsize) 719 void _count_size(HWND box, int type, int *xsize, int *xorigsize)
704 { 720 {
1236 1252
1237 /* This procedure handles WM_QUERYTRACKINFO requests from the frame */ 1253 /* This procedure handles WM_QUERYTRACKINFO requests from the frame */
1238 MRESULT EXPENTRY _sizeproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) 1254 MRESULT EXPENTRY _sizeproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1239 { 1255 {
1240 PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); 1256 PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
1241 1257 Box *thisbox = NULL;
1242 switch(msg) 1258 HWND box;
1243 { 1259
1244 case WM_QUERYTRACKINFO: 1260 box = WinWindowFromID(hWnd, FID_CLIENT);
1261 if(box)
1262 thisbox = WinQueryWindowPtr(box, QWP_USER);
1263
1264 if(thisbox && !thisbox->titlebar)
1265 {
1266 switch(msg)
1245 { 1267 {
1246 if(blah && *blah) 1268 case WM_QUERYTRACKINFO:
1247 { 1269 {
1248 PTRACKINFO ptInfo; 1270 if(blah && *blah)
1249 int res; 1271 {
1250 PFNWP myfunc = *blah; 1272 PTRACKINFO ptInfo;
1251 res = (int)myfunc(hWnd, msg, mp1, mp2); 1273 int res;
1252 1274 PFNWP myfunc = *blah;
1253 ptInfo = (PTRACKINFO)(mp2); 1275 res = (int)myfunc(hWnd, msg, mp1, mp2);
1254 1276
1255 ptInfo->ptlMinTrackSize.y = 8; 1277 ptInfo = (PTRACKINFO)(mp2);
1256 ptInfo->ptlMinTrackSize.x = 8; 1278
1257 1279 ptInfo->ptlMinTrackSize.y = 8;
1258 return (MRESULT)res; 1280 ptInfo->ptlMinTrackSize.x = 8;
1281
1282 return (MRESULT)res;
1283 }
1259 } 1284 }
1260 } 1285 }
1261 } 1286 }
1287
1262 if(blah && *blah) 1288 if(blah && *blah)
1263 { 1289 {
1264 PFNWP myfunc = *blah; 1290 PFNWP myfunc = *blah;
1265 return myfunc(hWnd, msg, mp1, mp2); 1291 return myfunc(hWnd, msg, mp1, mp2);
1266 } 1292 }
1356 return (MRESULT)TRUE; 1382 return (MRESULT)TRUE;
1357 } 1383 }
1358 } 1384 }
1359 return myfunc(hWnd, msg, mp1, mp2); 1385 return myfunc(hWnd, msg, mp1, mp2);
1360 } 1386 }
1361
1362 return WinDefWindowProc(hWnd, msg, mp1, mp2);
1363 }
1364
1365 /* This procedure handles drawing of a percent bar */
1366 MRESULT EXPENTRY _percentproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1367 {
1368 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
1369
1370 if(blah)
1371 return blah->oldproc(hWnd, msg, mp1, mp2);
1372 1387
1373 return WinDefWindowProc(hWnd, msg, mp1, mp2); 1388 return WinDefWindowProc(hWnd, msg, mp1, mp2);
1374 } 1389 }
1375 1390
1376 void _click_default(HWND handle) 1391 void _click_default(HWND handle)
1414 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); 1429 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
1415 1430
1416 switch(msg) 1431 switch(msg)
1417 { 1432 {
1418 case WM_SETFOCUS: 1433 case WM_SETFOCUS:
1434 _toplevel_focus(hWnd);
1419 _run_event(hWnd, msg, mp1, mp2); 1435 _run_event(hWnd, msg, mp1, mp2);
1420 break; 1436 break;
1421 } 1437 }
1422 1438
1423 if(blah && blah->oldproc) 1439 if(blah && blah->oldproc)
1445 { 1461 {
1446 char tmpbuf[100]; 1462 char tmpbuf[100];
1447 1463
1448 WinQueryClassName(hWnd, 99, tmpbuf); 1464 WinQueryClassName(hWnd, 99, tmpbuf);
1449 1465
1450 if(strncmp(tmpbuf, "#32", 3)==0) 1466 if(strncmp(tmpbuf, "#32", 4)==0)
1451 _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); 1467 _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
1452 } 1468 }
1453 break; 1469 break;
1470 case WM_CONTROL:
1471 {
1472 char tmpbuf[100];
1473
1474 WinQueryClassName(hWnd, 99, tmpbuf);
1475
1476 if(strncmp(tmpbuf, "#38", 4)==0)
1477 _run_event(hWnd, msg, mp1, mp2);
1478 }
1479 break;
1454 case WM_SETFOCUS: 1480 case WM_SETFOCUS:
1481 _toplevel_focus(hWnd);
1455 _run_event(hWnd, msg, mp1, mp2); 1482 _run_event(hWnd, msg, mp1, mp2);
1456 break; 1483 break;
1457 case WM_CHAR: 1484 case WM_CHAR:
1458 if(SHORT1FROMMP(mp2) == '\t') 1485 if(SHORT1FROMMP(mp2) == '\t')
1459 { 1486 {
1504 case WM_BUTTON2DOWN: 1531 case WM_BUTTON2DOWN:
1505 case WM_BUTTON3DOWN: 1532 case WM_BUTTON3DOWN:
1506 _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); 1533 _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
1507 break; 1534 break;
1508 case WM_SETFOCUS: 1535 case WM_SETFOCUS:
1536 _toplevel_focus(hWnd);
1509 _run_event(hWnd, msg, mp1, mp2); 1537 _run_event(hWnd, msg, mp1, mp2);
1510 break; 1538 break;
1511 case WM_PAINT: 1539 case WM_PAINT:
1512 { 1540 {
1513 HWND parent = WinQueryWindow(hWnd, QW_PARENT); 1541 HWND parent = WinQueryWindow(hWnd, QW_PARENT);
1758 tmp = NULL; 1786 tmp = NULL;
1759 } 1787 }
1760 } 1788 }
1761 break; 1789 break;
1762 case WM_CONTROL: 1790 case WM_CONTROL:
1763 if(tmp->message == SHORT2FROMMP(mp1)) 1791 if(tmp->message == SHORT2FROMMP(mp1) || (tmp->message == SLN_SLIDERTRACK && SHORT2FROMMP(mp1) == SLN_CHANGE))
1764 { 1792 {
1765 switch(SHORT2FROMMP(mp1)) 1793 switch(SHORT2FROMMP(mp1))
1766 { 1794 {
1767 case CN_ENTER: 1795 case CN_ENTER:
1768 { 1796 {
1864 } 1892 }
1865 } 1893 }
1866 break; 1894 break;
1867 case LN_SELECT: 1895 case LN_SELECT:
1868 { 1896 {
1869 int (*listboxselectfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction; 1897 char classbuf[100];
1870 int id = SHORT1FROMMP(mp1); 1898
1871 HWND conthwnd = dw_window_from_id(hWnd, id); 1899 WinQueryClassName(tmp->window, 99, classbuf);
1872 static int _recursing = 0; 1900
1873 1901 if(strncmp(classbuf, "#38", 4) == 0)
1874 if(_recursing == 0 && (tmp->window == conthwnd || (!id && tmp->window == (HWND)mp2)))
1875 { 1902 {
1876 char buf1[500], classbuf[100]; 1903 int (*valuechangedfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction;
1877 unsigned int index = dw_listbox_selected(tmp->window); 1904
1878 1905 if(tmp->window == hWnd || WinQueryWindow(tmp->window, QW_PARENT) == hWnd)
1879 dw_listbox_query_text(tmp->window, index, buf1, 500);
1880
1881 WinQueryClassName(tmp->window, 99, classbuf);
1882
1883 _recursing = 1;
1884
1885 if(id && strncmp(classbuf, "#2", 3)==0)
1886 { 1906 {
1887 char *buf2; 1907 static int lastvalue = -1;
1888 1908 static HWND lasthwnd = NULLHANDLE;
1889 buf2 = dw_window_get_text(tmp->window); 1909 int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
1890 1910 if(lastvalue != ulValue || lasthwnd != tmp->window)
1891 /* This is to make sure the listboxselect function doesn't 1911 {
1892 * get called if the user is modifying the entry text. 1912 result = valuechangedfunc(tmp->window, ulValue, tmp->data);
1893 */ 1913 lastvalue = ulValue;
1894 if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0) 1914 lasthwnd = tmp->window;
1915 }
1916 tmp = NULL;
1917 }
1918 }
1919 else
1920 {
1921 int (*listboxselectfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction;
1922 int id = SHORT1FROMMP(mp1);
1923 HWND conthwnd = dw_window_from_id(hWnd, id);
1924 static int _recursing = 0;
1925
1926 if(_recursing == 0 && (tmp->window == conthwnd || (!id && tmp->window == (HWND)mp2)))
1927 {
1928 char buf1[500];
1929 unsigned int index = dw_listbox_selected(tmp->window);
1930
1931 dw_listbox_query_text(tmp->window, index, buf1, 500);
1932
1933 _recursing = 1;
1934
1935 if(id && strncmp(classbuf, "#2", 3)==0)
1936 {
1937 char *buf2;
1938
1939 buf2 = dw_window_get_text(tmp->window);
1940
1941 /* This is to make sure the listboxselect function doesn't
1942 * get called if the user is modifying the entry text.
1943 */
1944 if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0)
1945 result = listboxselectfunc(tmp->window, index, tmp->data);
1946
1947 if(buf2)
1948 free(buf2);
1949 }
1950 else
1895 result = listboxselectfunc(tmp->window, index, tmp->data); 1951 result = listboxselectfunc(tmp->window, index, tmp->data);
1896 1952
1897 if(buf2) 1953 _recursing = 0;
1898 free(buf2); 1954 tmp = NULL;
1899 } 1955 }
1900 else 1956 }
1901 result = listboxselectfunc(tmp->window, index, tmp->data); 1957 }
1902 1958 break;
1903 _recursing = 0; 1959 case SLN_SLIDERTRACK:
1960 {
1961 int (*valuechangedfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction;
1962
1963 if(tmp->window == hWnd || WinQueryWindow(tmp->window, QW_PARENT) == hWnd)
1964 {
1965 static int lastvalue = -1;
1966 static HWND lasthwnd = NULLHANDLE;
1967 int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
1968 if(lastvalue != ulValue || lasthwnd != tmp->window)
1969 {
1970 result = valuechangedfunc(tmp->window, ulValue, tmp->data);
1971 lastvalue = ulValue;
1972 lasthwnd = tmp->window;
1973 }
1904 tmp = NULL; 1974 tmp = NULL;
1905 } 1975 }
1906 } 1976 }
1977
1907 break; 1978 break;
1908 } 1979 }
1909 } 1980 }
1910 break; 1981 break;
1911 } 1982 }
1918 1989
1919 return (MRESULT)result; 1990 return (MRESULT)result;
1920 } 1991 }
1921 #endif 1992 #endif
1922 1993
1994 int _warp4_focus_fix(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1995 {
1996 /* This is a hack to stop an infinite loop in the
1997 * Warp 4 default window procedure. It seems that
1998 * under very rare circumstances, the same WM_FOCUSCHANGE
1999 * message will bounce between an entryfield and
2000 * the frame it sits on, this will stop duplicate
2001 * messages and thus prevent the infinite loop.
2002 */
2003 if(msg == WM_FOCUSCHANGE && SHORT1FROMMP(mp2))
2004 {
2005 static HWND lastfocus = 0;
2006 static time_t lasttime = 0;
2007 static int count = 0;
2008 time_t currtime = time(NULL);
2009
2010 if(lastfocus == (HWND)mp1 && currtime == lasttime)
2011 {
2012 if(count > 5)
2013 {
2014 count = 0;
2015 return 1;
2016 }
2017 count++;
2018 return 0;
2019 }
2020
2021 count = 0;
2022 lastfocus = (HWND)mp1;
2023 lasttime = currtime;
2024 }
2025 return 0;
2026 }
2027
1923 /* Handles control messages sent to the box (owner). */ 2028 /* Handles control messages sent to the box (owner). */
1924 MRESULT EXPENTRY _controlproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) 2029 MRESULT EXPENTRY _controlproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1925 { 2030 {
1926 Box *blah = WinQueryWindowPtr(hWnd, QWP_USER); 2031 Box *blah = WinQueryWindowPtr(hWnd, QWP_USER);
1927 2032
1931 case WM_CONTROL: 2036 case WM_CONTROL:
1932 _run_event(hWnd, msg, mp1, mp2); 2037 _run_event(hWnd, msg, mp1, mp2);
1933 break; 2038 break;
1934 } 2039 }
1935 #endif 2040 #endif
2041
2042 if(_warp4_focus_fix(hWnd, msg, mp1, mp2))
2043 return (MRESULT)0;
2044 if(msg == WM_SETFOCUS)
2045 _toplevel_focus(hWnd);
2046
1936 if(blah && blah->oldproc) 2047 if(blah && blah->oldproc)
1937 {
1938 return blah->oldproc(hWnd, msg, mp1, mp2); 2048 return blah->oldproc(hWnd, msg, mp1, mp2);
1939 }
1940 2049
1941 return WinDefWindowProc(hWnd, msg, mp1, mp2); 2050 return WinDefWindowProc(hWnd, msg, mp1, mp2);
1942 } 2051 }
1943 2052
1944 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */ 2053 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */
2042 char tmpbuf[100]; 2151 char tmpbuf[100];
2043 2152
2044 WinQueryClassName(mybox->items[z].hwnd, 99, tmpbuf); 2153 WinQueryClassName(mybox->items[z].hwnd, 99, tmpbuf);
2045 2154
2046 /* If we have a notebook we resize the page again. */ 2155 /* If we have a notebook we resize the page again. */
2047 if(strncmp(tmpbuf, "#40", 3)==0) 2156 if(strncmp(tmpbuf, "#40", 4)==0)
2048 { 2157 {
2049 unsigned long x, y, width, height; 2158 unsigned long x, y, width, height;
2050 int page = dw_notebook_page_query(mybox->items[z].hwnd); 2159 int page = dw_notebook_page_query(mybox->items[z].hwnd);
2051 HWND pagehwnd = (HWND)WinSendMsg(mybox->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0); 2160 HWND pagehwnd = (HWND)WinSendMsg(mybox->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0);
2052 RECTL rc; 2161 RECTL rc;
2129 case WM_DESTROY: 2238 case WM_DESTROY:
2130 /* Free memory before destroying */ 2239 /* Free memory before destroying */
2131 _free_window_memory(hWnd); 2240 _free_window_memory(hWnd);
2132 break; 2241 break;
2133 } 2242 }
2243
2244 if(_warp4_focus_fix(hWnd, msg, mp1, mp2))
2245 return (MRESULT)0;
2246
2134 if(result != -1) 2247 if(result != -1)
2135 return (MRESULT)result; 2248 return (MRESULT)result;
2136 else 2249 else
2137 return WinDefWindowProc(hWnd, msg, mp1, mp2); 2250 return WinDefWindowProc(hWnd, msg, mp1, mp2);
2138 } 2251 }
2671 { 2784 {
2672 case WM_BUTTON1DOWN: 2785 case WM_BUTTON1DOWN:
2673 case WM_BUTTON2DOWN: 2786 case WM_BUTTON2DOWN:
2674 case WM_BUTTON3DOWN: 2787 case WM_BUTTON3DOWN:
2675 if(!res) 2788 if(!res)
2676 WinSetFocus(HWND_DESKTOP, hwnd); 2789 _toplevel_focus(hwnd);
2677 return (MPARAM)TRUE; 2790 return (MPARAM)TRUE;
2678 } 2791 }
2679 return WinDefWindowProc(hwnd, msg, mp1, mp2); 2792 return WinDefWindowProc(hwnd, msg, mp1, mp2);
2680 } 2793 }
2681 2794
2754 WinTerminate(dwhab); 2867 WinTerminate(dwhab);
2755 } 2868 }
2756 } 2869 }
2757 2870
2758 /* 2871 /*
2759 * Runs a message loop for Dynamic Windows, for a period of seconds. 2872 * Runs a message loop for Dynamic Windows, for a period of milliseconds.
2760 * Parameters: 2873 * Parameters:
2761 * seconds: Number of seconds to run the loop for. 2874 * milliseconds: Number of milliseconds to run the loop for.
2762 */ 2875 */
2763 void dw_main_sleep(int seconds) 2876 void dw_main_sleep(int milliseconds)
2764 { 2877 {
2765 QMSG qmsg; 2878 QMSG qmsg;
2766 time_t start = time(NULL); 2879 double start = (double)clock();
2767 2880
2768 while(time(NULL) - start <= seconds) 2881 while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds)
2769 { 2882 {
2770 if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE)) 2883 if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE))
2771 { 2884 {
2772 WinGetMsg(dwhab, &qmsg, 0, 0, 0); 2885 WinGetMsg(dwhab, &qmsg, 0, 0, 0);
2773 WinDispatchMsg(dwhab, &qmsg); 2886 WinDispatchMsg(dwhab, &qmsg);
3702 NULLHANDLE, 3815 NULLHANDLE,
3703 HWND_TOP, 3816 HWND_TOP,
3704 id, 3817 id,
3705 NULL, 3818 NULL,
3706 NULL); 3819 NULL);
3707 dw_window_set_font(tmp, DefaultFont);
3708 dw_window_set_font(tmp, DefaultFont); 3820 dw_window_set_font(tmp, DefaultFont);
3709 blah->oldproc = WinSubclassWindow(tmp, _comboentryproc); 3821 blah->oldproc = WinSubclassWindow(tmp, _comboentryproc);
3710 WinSetWindowPtr(tmp, QWP_USER, blah); 3822 WinSetWindowPtr(tmp, QWP_USER, blah);
3711 return tmp; 3823 return tmp;
3712 } 3824 }
3950 WinSetWindowPtr(tmp, QWP_USER, blah); 4062 WinSetWindowPtr(tmp, QWP_USER, blah);
3951 return tmp; 4063 return tmp;
3952 } 4064 }
3953 4065
3954 /* 4066 /*
4067 * Create a new slider window (widget) to be packed.
4068 * Parameters:
4069 * vertical: TRUE or FALSE if slider is vertical.
4070 * increments: Number of increments available.
4071 * id: An ID to be used with WinWindowFromID() or 0L.
4072 */
4073 HWND dw_slider_new(int vertical, int increments, ULONG id)
4074 {
4075 WindowData *blah = calloc(1, sizeof(WindowData));
4076 SLDCDATA sldcData = { sizeof(SLDCDATA), increments, 0, 0, 0 };
4077 HWND tmp = WinCreateWindow(HWND_OBJECT,
4078 WC_SLIDER,
4079 "",
4080 WS_VISIBLE | SLS_SNAPTOINCREMENT |
4081 (vertical ? SLS_VERTICAL : SLS_HORIZONTAL),
4082 0,0,2000,1000,
4083 NULLHANDLE,
4084 HWND_TOP,
4085 id,
4086 &sldcData,
4087 NULL);
4088
4089 blah->oldproc = WinSubclassWindow(tmp, _entryproc);
4090 WinSetWindowPtr(tmp, QWP_USER, blah);
4091 return tmp;
4092 }
4093
4094 /*
3955 * Create a new percent bar window (widget) to be packed. 4095 * Create a new percent bar window (widget) to be packed.
3956 * Parameters: 4096 * Parameters:
3957 * id: An ID to be used with WinWindowFromID() or 0L. 4097 * id: An ID to be used with WinWindowFromID() or 0L.
3958 */ 4098 */
3959 HWND dw_percent_new(ULONG id) 4099 HWND dw_percent_new(ULONG id)
3960 { 4100 {
3961 WindowData *blah = calloc(1, sizeof(WindowData));
3962 HWND tmp = WinCreateWindow(HWND_OBJECT, 4101 HWND tmp = WinCreateWindow(HWND_OBJECT,
3963 WC_SLIDER, 4102 WC_SLIDER,
3964 "", 4103 "",
3965 WS_VISIBLE | SLS_READONLY 4104 WS_VISIBLE | SLS_READONLY
3966 | SLS_RIBBONSTRIP, 4105 | SLS_RIBBONSTRIP,
3968 NULLHANDLE, 4107 NULLHANDLE,
3969 HWND_TOP, 4108 HWND_TOP,
3970 id, 4109 id,
3971 NULL, 4110 NULL,
3972 NULL); 4111 NULL);
3973 4112 dw_window_disable(tmp);
3974 blah->oldproc = WinSubclassWindow(tmp, _percentproc);
3975 WinSetWindowPtr(tmp, QWP_USER, blah);
3976 return tmp; 4113 return tmp;
3977 } 4114 }
3978 4115
3979 /* 4116 /*
3980 * Create a new checkbox window (widget) to be packed. 4117 * Create a new checkbox window (widget) to be packed.
4176 } 4313 }
4177 } 4314 }
4178 4315
4179 void dw_box_pack_end_stub(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) 4316 void dw_box_pack_end_stub(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
4180 { 4317 {
4181 HWND boxowner = NULLHANDLE;
4182 Box *thisbox; 4318 Box *thisbox;
4183 4319
4184 if(WinWindowFromID(box, FID_CLIENT)) 4320 if(WinWindowFromID(box, FID_CLIENT))
4185 { 4321 {
4186 box = WinWindowFromID(box, FID_CLIENT); 4322 box = WinWindowFromID(box, FID_CLIENT);
4241 4377
4242 thisbox->count++; 4378 thisbox->count++;
4243 4379
4244 /* Don't set the ownership if it's an entryfield or spinbutton */ 4380 /* Don't set the ownership if it's an entryfield or spinbutton */
4245 WinQueryClassName(item, 99, tmpbuf); 4381 WinQueryClassName(item, 99, tmpbuf);
4246 if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 3)!=0) 4382 if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0)
4247 { 4383 WinSetOwner(item, box);
4248 if((boxowner = WinQueryWindow(box, QW_OWNER)) != 0)
4249 WinSetOwner(item, boxowner);
4250 else
4251 WinSetOwner(item, box);
4252 }
4253 WinSetParent(item, box, FALSE); 4384 WinSetParent(item, box, FALSE);
4254 } 4385 }
4255 } 4386 }
4256 4387
4257 /* 4388 /*
4820 } 4951 }
4821 4952
4822 /* 4953 /*
4823 * Returns the range of the percent bar. 4954 * Returns the range of the percent bar.
4824 * Parameters: 4955 * Parameters:
4956 * handle: Handle to the percent bar to be queried.
4957 */
4958 unsigned int dw_percent_query_range(HWND handle)
4959 {
4960 return SHORT2FROMMP(WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0));
4961 }
4962
4963 /*
4964 * Sets the percent bar position.
4965 * Parameters:
4966 * handle: Handle to the percent bar to be set.
4967 * position: Position of the percent bar withing the range.
4968 */
4969 void dw_percent_set_pos(HWND handle, unsigned int position)
4970 {
4971 WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)position);
4972 }
4973
4974 /*
4975 * Returns the position of the slider.
4976 * Parameters:
4825 * handle: Handle to the slider to be queried. 4977 * handle: Handle to the slider to be queried.
4826 */ 4978 */
4827 unsigned int dw_percent_query_range(HWND handle) 4979 unsigned int dw_slider_query_pos(HWND handle)
4828 { 4980 {
4829 return SHORT2FROMMP(WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0)); 4981 return (unsigned int)WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
4830 } 4982 }
4831 4983
4832 /* 4984 /*
4833 * Sets the percent bar position. 4985 * Sets the slider position.
4834 * Parameters: 4986 * Parameters:
4835 * handle: Handle to the slider to be set. 4987 * handle: Handle to the slider to be set.
4836 * position: Position of the slider withing the range. 4988 * position: Position of the slider withing the range.
4837 */ 4989 */
4838 void dw_percent_set_pos(HWND handle, unsigned int position) 4990 void dw_slider_set_pos(HWND handle, unsigned int position)
4839 { 4991 {
4840 WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)position); 4992 WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)position);
4841 } 4993 }
4842 4994
4843 /* 4995 /*
4844 * Sets the spinbutton value. 4996 * Sets the spinbutton value.
4845 * Parameters: 4997 * Parameters:
6158 DosCloseMutexSem(mutex); 6310 DosCloseMutexSem(mutex);
6159 } 6311 }
6160 6312
6161 /* 6313 /*
6162 * Tries to gain access to the semaphore, if it can't it blocks. 6314 * Tries to gain access to the semaphore, if it can't it blocks.
6315 * If we are in a callback we must keep the message loop running
6316 * while blocking.
6163 * Parameters: 6317 * Parameters:
6164 * mutex: The handle to the mutex returned by dw_mutex_new(). 6318 * mutex: The handle to the mutex returned by dw_mutex_new().
6165 */ 6319 */
6166 void dw_mutex_lock(HMTX mutex) 6320 void dw_mutex_lock(HMTX mutex)
6167 { 6321 {
6168 DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT); 6322 if(_dwtid == dw_thread_id())
6323 {
6324 int rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
6325
6326 while(rc == ERROR_TIMEOUT)
6327 {
6328 dw_main_sleep(10);
6329 rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
6330 }
6331 }
6332 else
6333 DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT);
6169 } 6334 }
6170 6335
6171 /* 6336 /*
6172 * Reliquishes the access to the semaphore. 6337 * Reliquishes the access to the semaphore.
6173 * Parameters: 6338 * Parameters:
6419 } 6584 }
6420 } 6585 }
6421 6586
6422 void dw_box_pack_start_stub(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) 6587 void dw_box_pack_start_stub(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
6423 { 6588 {
6424 HWND boxowner = NULLHANDLE;
6425 Box *thisbox; 6589 Box *thisbox;
6426 6590
6427 if(WinWindowFromID(box, FID_CLIENT)) 6591 if(WinWindowFromID(box, FID_CLIENT))
6428 { 6592 {
6429 box = WinWindowFromID(box, FID_CLIENT); 6593 box = WinWindowFromID(box, FID_CLIENT);
6474 6638
6475 thisbox->count++; 6639 thisbox->count++;
6476 6640
6477 WinQueryClassName(item, 99, tmpbuf); 6641 WinQueryClassName(item, 99, tmpbuf);
6478 /* Don't set the ownership if it's an entryfield or spinbutton */ 6642 /* Don't set the ownership if it's an entryfield or spinbutton */
6479 if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 3)!=0) 6643 if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0)
6480 { 6644 WinSetOwner(item, box);
6481 if((boxowner = WinQueryWindow(box, QW_OWNER)) != 0)
6482 WinSetOwner(item, boxowner);
6483 else
6484 WinSetOwner(item, box);
6485 }
6486 WinSetParent(item, box, FALSE); 6645 WinSetParent(item, box, FALSE);
6487 } 6646 }
6488 } 6647 }
6489 6648
6490 /* The following two functions graciously contributed by Peter Nielsen. */ 6649 /* The following two functions graciously contributed by Peter Nielsen. */