source: trunk/common.c@ 151

Last change on this file since 151 was 151, checked in by Gregg Young, 7 years ago

Fix hang on shutdown Ticket #71

File size: 73.6 KB
Line 
1/*
2 * Copyright (C) 1997-2006 Andrei Los.
3 * This file is part of the lSwitcher source package.
4 * lSwitcher is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, in version 2 as it comes in the
7 * "COPYING" file of the lSwitcher main distribution.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <process.h>
15#include <string.h>
16#include <stdio.h>
17#include <ctype.h>
18#include "common.h"
19#include "apm.h"
20#include "prmdlg.h"
21#include "settings.h"
22#include "taskbar.h"
23#include "fspopup.h"
24#include "pmpopup.h"
25#include "lswres.h"
26#include "eastring.h"
27#include "object.h"
28
29#ifdef XWORKPLACE
30#include "dlgids.h"
31#endif
32
33HELPINIT hini;
34HWND hwndHelp;
35
36LONG SwitcherInit(HAB hab, HMQ hmq, UCHAR * ucErrMsg, USHORT usMsgLen,
37 PVOID * ppData, USHORT usFunc)
38{
39 ULONG flFrameFlags, ulHookVer;
40 LONG rc, rc1 = 0;
41 LSWDATA *plswData;
42 UCHAR ucFName[CCHMAXPATH], ucFound = 0, ucLangStr[32];
43 USHORT usResLang;
44 SWCNTRL swctl;
45 CHAR s[100];
46
47 // usFunc is 0 for app initialization, 1 and for widget phases 1 and 2 initialization
48#ifdef __PMPRINTF__
49 PmPrintfDisplayInterfaceVersionInfo();
50 PmPrintfQueueNameThisProcess(NULL);
51#endif
52 if (usFunc != 1)
53 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, +31, 0);
54
55 if (usFunc != 2) {
56//need to loop so that search handle is closed
57 while (FindResDll(ucFName, sizeof(ucFName), &usResLang, ucLangStr,
58 sizeof(ucLangStr)))
59 if (usResLang != 0)
60 ucFound = 1;
61
62 if (!ucFound) {
63 strncpy(ucErrMsg,
64 "Could not find resource DLL or resource DLL invalid",
65 usMsgLen);
66 return 1;
67 }
68
69 ulHookVer = lswHookGetVersion();
70 if (LOUCHAR(LOUSHORT(ulHookVer)) < LASTHOOKVERMAJOROK ||
71 HIUCHAR(LOUSHORT(ulHookVer)) < LASTHOOKVERMINOROK ||
72 LOUCHAR(HIUSHORT(ulHookVer)) < LASTHOOKREVISIONOK) {
73 strncpy(ucErrMsg, "Wrong hook DLL version", usMsgLen);
74 return 1;
75 }
76
77 if (!WinRegisterClass
78 (hab, LSWPOPUPCLASS, PopupWndProc, CS_SAVEBITS | CS_SYNCPAINT,
79 sizeof(PLSWDATA))) {
80 strncpy(ucErrMsg, "WinRegisterClass(lswPopupClass) error",
81 usMsgLen);
82 return WinGetLastError(hab);
83 }
84
85 if ((rc =
86 DosAllocSharedMem((VOID *) & plswData, SHAREMEM_NAME,
87 sizeof(LSWDATA),
88 PAG_COMMIT | PAG_READ | PAG_WRITE)) != 0) {
89 sprintf(s,"DosAllocSharedMem error %i", rc);
90 strncpy(ucErrMsg, s, usMsgLen);
91 return rc;
92 }
93
94 memset(plswData, 0, sizeof(LSWDATA));
95 *ppData = (PVOID) plswData;
96
97#ifdef XWORKPLACE
98 plswData->bWidget = TRUE;
99#endif
100
101 plswData->hab = hab;
102 plswData->hmq = hmq;
103
104 GetIniFileName(ucFName, sizeof(ucFName));
105 if (LoadSettings(hab, ucFName, &plswData->Settings) != 0)
106 rc1 = LSWERRCANTLOADSETTINGS;
107 if (rc1 == 0 && !CheckSettings(&plswData->Settings))
108 rc1 = LSWERROLDSETTINGS;
109
110 if (rc1 < 0)
111 InitSettings(&plswData->Settings);
112 else if (plswData->Settings.sTskBarCX >
113 WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) + 2) {
114 plswData->Settings.sTskBarX = -TSKBARFRAMEWIDTH;
115 if (plswData->Settings.bTaskBarTopScr)
116 plswData->Settings.sTskBarY =
117 WinQuerySysValue(HWND_DESKTOP,
118 SV_CYSCREEN) -
119 plswData->Settings.sTskBarCY + TSKBARFRAMEWIDTH;
120 else
121 plswData->Settings.sTskBarY = -TSKBARFRAMEWIDTH;
122 plswData->Settings.sTskBarCX =
123 WinQuerySysValue(HWND_DESKTOP,
124 SV_CXSCREEN) + 2 * TSKBARFRAMEWIDTH;
125 plswData->Settings.sTskBarCY =
126 WinQuerySysValue(HWND_DESKTOP,
127 SV_CYICON) / 2 + 4 + 2 * BUTTONBORDERWIDTH +
128 2 + 2 * TSKBARFRAMEWIDTH;
129 }
130 }
131
132 if (usFunc != 1) {
133#ifdef XWORKPLACE
134 if (usFunc == 2)
135 plswData = (PLSWDATA) (*ppData);
136#endif
137
138 if ((plswData->hmodRes =
139 LoadResource(plswData->Settings.usLanguage, plswData,
140 TRUE)) == 0) {
141 strncpy(ucErrMsg, "Could not load resources ", usMsgLen);
142 return 1;
143 }
144
145 if ((rc =
146 DosCreateEventSem(SEMRUNNINGNAME, &plswData->hevRunning, 0, 0))
147 || (rc =
148 DosCreateEventSem(SEMCTRLTABNAME, &plswData->hevCtrlTab, 0,
149 (plswData->Settings.ucPopupHotKey == 1)))
150 ) {
151 strncpy(ucErrMsg, "DosCreateEventSem", usMsgLen);
152 return rc;
153 }
154#ifdef XWORKPLACE
155 if (rc = DosCreateEventSem(SEMFSMONDISPATRUNNING,
156 &plswData->hevFSMonDispatRunning,
157 0, FALSE)) {
158 strncpy(ucErrMsg,"DosCreateEventSem2", usMsgLen);
159 return rc;
160 }
161#endif
162 flFrameFlags = 0;
163#ifndef XWORKPLACE
164 flFrameFlags |= FCF_TASKLIST | FCF_ICON;
165#endif
166 plswData->hwndPopup =
167 WinCreateStdWindow(HWND_DESKTOP, 0, &flFrameFlags, LSWPOPUPCLASS,
168 "", 0, 0, ID_POPUPWIN,
169 &plswData->hwndPopClient);
170
171 if (plswData->hwndPopup == NULLHANDLE) {
172 strncpy(ucErrMsg, "WinCreateStdWin(lswPopupWin)", usMsgLen);
173 return WinGetLastError(hab);
174 }
175
176 WinSetWindowPos(plswData->hwndPopup, HWND_BOTTOM, POPUPWINHIDEPOSX,
177 POPUPWINHIDEPOSY, 0, 0,
178 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_DEACTIVATE |
179 SWP_ZORDER);
180 //subsclassing must go after setting position so that desktop number which is
181 //calculated by the frame wnd proc relative to the hide position is done correctly
182 WinSetWindowPtr(plswData->hwndPopup, 0,
183 (VOID *) WinSubclassWindow(plswData->hwndPopup,
184 FrameWndProc));
185
186 plswData->hwndBubble = WinCreateWindow(HWND_DESKTOP, WC_STATIC, "",
187 SS_TEXT | DT_CENTER |
188 DT_VCENTER, 0, 0, 0, 0, 0,
189 HWND_BOTTOM, ID_BUBBLE, NULL,
190 NULL);
191 WinSetPresParam(plswData->hwndBubble, PP_FONTNAMESIZE, 7, "8.Helv");
192 WinSetPresParam(plswData->hwndBubble, PP_BACKGROUNDCOLOR,
193 sizeof(plswData->Settings.lBubbleRGBCol),
194 &plswData->Settings.lBubbleRGBCol);
195 WinSetPresParam(plswData->hwndBubble, PP_FOREGROUNDCOLOR,
196 sizeof(plswData->Settings.lBubbleTextRGBCol),
197 &plswData->Settings.lBubbleTextRGBCol);
198 WinCreateWindow(plswData->hwndBubble, WC_STATIC, "", SS_HALFTONEFRAME,
199 0, 0, 0, 0, 0, HWND_TOP, ID_BUBBLEFRAME, NULL, NULL);
200
201 if ((plswData->itidFSDispat =
202 _beginthread(FSMonDispat, NULL, 0x4000, plswData)) < 0) {
203 strncpy(ucErrMsg, "_beginthread", usMsgLen);
204 return plswData->itidFSDispat;
205 }
206
207 if ((rc = lswHookInit(plswData)) < 0) {
208 strncpy(ucErrMsg, "lswHookInit", usMsgLen);
209 return (-rc);
210 }
211
212#ifndef XWORKPLACE
213 plswData->hswitch = WinQuerySwitchHandle(plswData->hwndPopup, 0);
214 WinQuerySwitchEntry(plswData->hswitch, &swctl);
215 swctl.uchVisibility =
216 plswData->Settings.bShowInWinList ? SWL_VISIBLE : SWL_INVISIBLE;
217 WinChangeSwitchEntry(plswData->hswitch, &swctl);
218
219 if (plswData->Settings.bTaskBarOn)
220 if ((rc = InitTaskBar(plswData, ucErrMsg, usMsgLen)) != 0)
221 return rc;
222
223 if ((rc = DosExitList(EXLST_ADD, (PFNEXITLIST) lswExitProc)) != 0) {
224 strncpy(ucErrMsg, "DosExitList", usMsgLen);
225 return rc;
226 }
227#else
228 if (plswData->pWidget->pGlobals != NULL)
229 plswData->hswitch =
230 WinQuerySwitchHandle(plswData->pWidget->pGlobals->hwndFrame,
231 0);
232#endif
233 WinAddAtom(WinQuerySystemAtomTable(), LSWM_SETPRIORITY);
234
235 memset(&hini, 0, sizeof(HELPINIT));
236 hini.cb = sizeof(HELPINIT);
237 hini.phtHelpTable = (PHELPTABLE) MAKELONG(ID_HELPTABLE, 0xffff);
238 hini.hmodAccelActionBarModule = (HMODULE) 0;
239 hini.pszHelpWindowTitle = "lSwitcher Help";
240 hini.hmodHelpTableModule = plswData->hmodRes;
241 hini.fShowPanelId = CMIC_HIDE_PANEL_ID;
242#ifndef XWORKPLACE
243 hini.pszHelpLibraryName = "lswitch.hlp";
244#else
245 ucFName[0] = 0;
246 PrfQueryProfileString(HINI_USERPROFILE, "XWorkplace", "XFolderPath",
247 0, ucFName, CCHMAXPATH);
248 if (ucFName)
249 strcat(ucFName, "\\plugins\\xcenter\\lswitch.hlp");
250 else
251 strcpy(ucFName, "lswitch.hlp");
252 hini.pszHelpLibraryName = ucFName;
253#endif
254 hwndHelp = WinCreateHelpInstance(hab, &hini);
255
256 if (hwndHelp) {
257 WinAssociateHelpInstance(hwndHelp, plswData->hwndParamDlg);
258 }
259 else {
260 strncpy(ucErrMsg, "Could not load help instance", usMsgLen);
261 return 1;
262 }
263 }
264
265 return rc1;
266}
267
268VOID SwitcherTerm(LSWDATA * plswData, USHORT usFunc)
269{
270 UCHAR ucFName[CCHMAXPATH];
271
272 GetIniFileName(ucFName, sizeof(ucFName));
273 SaveSettings(plswData->hab, ucFName, &plswData->Settings);
274// usFunc is 0 for app termination, 1 and 2 for widget phases 1 and 2 termination
275 if (usFunc != 2) {
276 HATOMTBL hatomtblAtomTbl = WinQuerySystemAtomTable();
277
278
279
280 WinDeleteAtom(hatomtblAtomTbl,
281 WinFindAtom(hatomtblAtomTbl, LSWM_SETPRIORITY));
282
283 lswHookTerm(plswData);
284
285 WinAssociateHelpInstance( NULLHANDLE, plswData->hwndParamDlg);
286 WinDestroyHelpInstance( hwndHelp );
287
288 DoneTaskBar(plswData);
289
290 DosPostEventSem(plswData->hevRunning);
291#ifdef XWORKPLACE
292 DosWaitEventSem(plswData->hevFSMonDispatRunning, SEM_INDEFINITE_WAIT);
293 DosCloseEventSem(plswData->hevFSMonDispatRunning);
294#endif
295 DosCloseEventSem(plswData->hevShift);
296 DosCloseEventSem(plswData->hevPopup);
297 DosCloseEventSem(plswData->hevRunning);
298 DosCloseEventSem(plswData->hevCtrlTab);
299
300 WinDestroyWindow(plswData->hwndPopup);
301 if (WinIsWindow(plswData->hab, plswData->hwndParamDlg))
302 WinDestroyWindow(plswData->hwndParamDlg);
303
304 DosFreeModule(plswData->hmodRes);
305 }
306
307#ifndef XWORKPLACE
308 WinDestroyMsgQueue(plswData->hmq);
309 WinTerminate(plswData->hab);
310#endif
311
312 if (usFunc != 1) {
313 if (plswData) {
314 DosFreeMem(plswData);
315 plswData = NULL;
316 }
317 }
318}
319
320VOID APIENTRY lswExitProc()
321{
322 LSWDATA *plswData;
323
324 DosGetNamedSharedMem((PVOID *) & plswData, SHAREMEM_NAME,
325 PAG_READ | PAG_WRITE);
326
327 if (plswData != NULL)
328 SwitcherTerm(plswData, 0);
329
330 DosExitList(EXLST_EXIT, (PFNEXITLIST) lswExitProc);
331}
332
333ULONG MapCommand(USHORT cmd)
334{
335 switch (cmd) {
336 case CMD_HIDE:
337 return MAKEULONG(SC_HIDE, SWP_HIDE);
338 case CMD_MAXIMIZE:
339 return MAKEULONG(SC_MAXIMIZE, SWP_MAXIMIZE);
340 case CMD_MINIMIZE:
341 return MAKEULONG(SC_MINIMIZE, SWP_MINIMIZE);
342 case CMD_RESTORE:
343 return MAKEULONG(SC_RESTORE, SWP_RESTORE);
344 case CMD_SHOW:
345 return MAKEULONG(0, SWP_SHOW);
346 case CMD_MOVE:
347 return MAKEULONG(SC_MOVE, SWP_MOVE);
348 case CMD_CLOSE:
349 return MAKEULONG(SC_CLOSE, 0);
350 default:
351 return 0;
352 }
353}
354
355/* This advanced killing Copyright (C)1996 by Holger.Veit@gmd.de */
356HFILE OpenXF86(VOID)
357{
358 HFILE hfd;
359 ULONG action;
360
361 if (DosOpen
362 ((PSZ) "/dev/fastio$", (PHFILE) & hfd, &action, 0, FILE_SYSTEM,
363 FILE_OPEN,
364 OPEN_SHARE_DENYNONE | OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY,
365 0) != 0)
366 return 0;
367 else
368 return hfd;
369}
370
371HFILE OpenCADH(VOID)
372{
373 HFILE hfd;
374 ULONG action;
375
376 if (DosOpen
377 ((PSZ) "/DEV/CADH$$$$", (PHFILE) & hfd, &action, 0, FILE_SYSTEM,
378 FILE_OPEN,
379 OPEN_SHARE_DENYNONE | OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY,
380 0) != 0)
381 return 0;
382 else
383 return hfd;
384}
385
386BOOL XF86Installed(VOID)
387{
388 HFILE hfd;
389
390 if ((hfd = OpenXF86()) != 0)
391 DosClose(hfd);
392 return (hfd != 0);
393}
394
395BOOL CADHInstalled(VOID)
396{
397 HFILE hfd;
398
399 if ((hfd = OpenCADH()) != 0)
400 DosClose(hfd);
401 return (hfd != 0);
402}
403
404BOOL Death(PID pid)
405{
406 HFILE hfdX, hfdC;
407 ULONG plen;
408 USHORT param;
409
410 if ((hfdX = OpenXF86()) == 0 && (hfdC = OpenCADH()) == 0)
411 return FALSE;
412 param = pid;
413
414 if (hfdX) {
415 if (DosDevIOCtl
416 (hfdX, 0x76, 0x65, (PULONG *) & param, sizeof(USHORT), &plen, NULL, 0,
417 NULL) != 0) {
418 DosClose(hfdX);
419 if (hfdC)
420 DosClose(hfdC);
421 return FALSE;
422 }
423 }
424 else if (hfdC) {
425 if (DosDevIOCtl
426 (hfdC, 0x80, 0x05, (PULONG *) & param, sizeof(USHORT), &plen, NULL, 0,
427 NULL) != 0) {
428 DosClose(hfdC);
429 return FALSE;
430 }
431 }
432 else
433 return FALSE;
434
435 if (hfdX)
436 DosClose(hfdX);
437 if (hfdC)
438 DosClose(hfdC);
439 return TRUE;
440}
441
442BOOL Tile(HAB hab, HWND hwnd, LONG lCurrDesktop)
443{
444 SWP swp;
445 RECTL Rectl;
446 BOOL rc;
447 USHORT usCXScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN),
448 usCYScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
449
450 WinSetRect(hab,&Rectl, usCXScreen*((lCurrDesktop&0xFF00)>>8),
451 usCYScreen*(lCurrDesktop&0xFF), usCXScreen*(((lCurrDesktop&0xFF00)>>8)+1),
452 usCYScreen*((lCurrDesktop&0xFF)+1));
453 WinQueryWindowPos(hwnd, &swp);
454 swp.y = ((Rectl.yTop - Rectl.yBottom)/ 8);
455 swp.cy = (((Rectl.yTop - Rectl.yBottom) * 7) / 8);
456 if (swp.x != 0)
457 swp.x = 0;
458 //if (swp.x + swp.cx > Rectl.xRight - Rectl.xLeft)
459 // swp.cx = Rectl.xRight - Rectl.xLeft;
460 rc = WinSetWindowPos(hwnd, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
461 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_RESTORE | SWP_ZORDER);
462 return rc;
463}
464
465BOOL Cascade(HAB hab, HWND hwnd, LONG lCurrDesktop)
466{
467 SWP swp;
468 RECTL Rectl;
469 BOOL rc;
470 USHORT usCXScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN),
471 usCYScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
472
473 WinSetRect(hab,&Rectl, usCXScreen*((lCurrDesktop&0xFF00)>>8),
474 usCYScreen*(lCurrDesktop&0xFF), usCXScreen*(((lCurrDesktop&0xFF00)>>8)+1),
475 usCYScreen*((lCurrDesktop&0xFF)+1));
476 WinQueryWindowPos(hwnd, &swp);
477 swp.y = (Rectl.yTop - Rectl.yBottom) / 2;
478 swp.cy = (Rectl.yTop - Rectl.yBottom) / 2;
479 if (swp.x != 0)
480 swp.x = 0;
481 swp.cx = ((Rectl.xRight - Rectl.xLeft) * 2) / 3;
482 rc = WinSetWindowPos(hwnd,
483 HWND_TOP,
484 swp.x,
485 swp.y,
486 swp.cx,
487 swp.cy,
488 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_RESTORE | SWP_ZORDER);
489 return rc;
490}
491
492BOOL IsWPSPid(PID pid)
493{
494 UCHAR szPidPath[_MAX_PATH] = { 0 };
495
496 DosQueryModuleName(HmteFromPID(pid), sizeof(szPidPath), szPidPath);
497 return (strstr(szPidPath, "PMSHELL.EXE") != NULL);
498}
499
500BOOL ChangeWindowPos(LSWDATA * plswData, SHORT iItemNum, USHORT cmd)
501{
502 USHORT cmd1;
503 BOOL bDoIt;
504
505 cmd1 = LOUSHORT(MapCommand(cmd));
506
507 bDoIt =
508 ((cmd == CMD_KILL || cmd == CMD_DEATH || cmd == CMD_CLOSE
509 || cmd == CMD_CLOSEQUIT || cmd == CMD_CASCADE
510 || cmd == CMD_TILE) ? TRUE : cmd ==
511 CMD_SHOW ? (!(plswData->TaskArr[iItemNum].fl & SWP_SHOW)) :
512 WndHasControl(plswData->hab, plswData->TaskArr[iItemNum].hwnd,
513 cmd1));
514
515 if (bDoIt) {
516 if (cmd == CMD_SHOW)
517 WinSetWindowPos(plswData->TaskArr[iItemNum].hwnd, HWND_TOP, 0, 0, 0, 0,
518 SWP_ZORDER | SWP_SHOW | SWP_ACTIVATE);
519 else if (cmd == CMD_CLOSEQUIT)
520 WinPostMsg(plswData->TaskArr[iItemNum].hwnd, WM_QUIT, 0, 0);
521 else if (cmd == CMD_KILL)
522 DosKillProcess(DKP_PROCESS, plswData->TaskArr[iItemNum].pid);
523 else if (cmd == CMD_DEATH)
524 Death(plswData->TaskArr[iItemNum].pid);
525 else if (cmd == CMD_CASCADE)
526 Cascade(plswData->hab, plswData->TaskArr[iItemNum].hwnd,
527 plswData->lCurrDesktop);
528 else if (cmd == CMD_TILE)
529 Tile(plswData->hab, plswData->TaskArr[iItemNum].hwnd,
530 plswData->lCurrDesktop);
531 else if (cmd == CMD_MAXIMIZE)
532 WinSetWindowPos(plswData->TaskArr[iItemNum].hwnd, HWND_TOP, 0, 0, 0, 0,
533 SWP_ZORDER | SWP_SHOW | SWP_MAXIMIZE | SWP_ACTIVATE);
534 else if (cmd == CMD_RESTORE)
535 WinSetWindowPos(plswData->TaskArr[iItemNum].hwnd, HWND_TOP, 0, 0, 0, 0,
536 SWP_ZORDER | SWP_SHOW | SWP_RESTORE | SWP_ACTIVATE);
537 else
538 WinPostMsg(plswData->TaskArr[iItemNum].hwnd, WM_SYSCOMMAND,
539 MPFROMSHORT(cmd1), MPFROM2SHORT(CMDSRC_OTHER, FALSE));
540 }
541
542 return bDoIt;
543}
544
545/* this procedure returns TRUE if the the popup menu for the usItem item in
546 the TaskArr needs the menu item usId. If yes, the title is returned also */
547BOOL MenuNeedsItem(LSWDATA * plswData, USHORT usItem, USHORT usId,
548 UCHAR * pszTitle, USHORT usLen, BOOL bGroup)
549{
550 BOOL bNeedsItem = FALSE;
551 USHORT k;
552
553 if (bGroup) {
554 for (k = 0; k < plswData->usItems && bNeedsItem == FALSE; k++) {
555 if (HmteFromPID(plswData->TaskArr[k].pid) !=
556 HmteFromPID(plswData->TaskArr[usItem].pid))
557 continue;
558
559 if (usId == CMD_SHOW && (plswData->TaskArr[k].fl & SWP_HIDE))
560 bNeedsItem = TRUE;
561 else if (usId >= CMD_HIDE && usId <= CMD_CLOSE
562 && usId != CMD_MOVE) {
563 bNeedsItem =
564 WndHasControl(plswData->hab, plswData->TaskArr[k].hwnd,
565 LOUSHORT(MapCommand(usId)));
566 if (usId == CMD_HIDE)
567 bNeedsItem &= (!(plswData->TaskArr[k].fl & SWP_HIDE));
568
569 if ((usId >= CMD_HIDE && usId <= CMD_MAXIMIZE))
570 bNeedsItem &= FALSE;
571 /* IsInDesktop(plswData->hab, plswData->TaskArr[k].hwnd,
572 plswData->lCurrDesktop); */
573 }
574 }
575 }
576 else {
577 if (usId == CMD_CLOSEQUIT || usId == CMD_ADDFILTER ||
578 (usId == CMD_SHOW && (plswData->TaskArr[usItem].fl & SWP_HIDE)))
579 bNeedsItem = TRUE;
580 else if (usId == CMD_SWITCHFROMPM)
581 bNeedsItem =
582 ((plswData->TaskArr[usItem].fl & (SWP_HIDE | SWP_MINIMIZE))
583 || plswData->TaskArr[usItem].hwnd !=
584 WinQueryActiveWindow(HWND_DESKTOP)
585 || !IsInDesktop(plswData->hab,
586 plswData->TaskArr[usItem].hwnd,
587 plswData->lCurrDesktop));
588 else if (usId == CMD_KILL || usId == CMD_DEATH
589 || usId == CMD_PRIORITY || usId == CMD_CASCADE || usId == CMD_TILE) {
590 bNeedsItem = (!IsWPSPid(plswData->TaskArr[usItem].pid));
591 if (usId == CMD_DEATH)
592 bNeedsItem &= XF86Installed() || CADHInstalled();
593 }
594 else if (usId == CMD_MOVE) {
595 bNeedsItem =
596 (!(plswData->TaskArr[usItem].fl & SWP_HIDE) &&
597 !IsMinToViewer(plswData->TaskArr[usItem].hwnd,
598 plswData->TaskArr[usItem].fl)
599 && WndHasControl(plswData->hab,
600 plswData->TaskArr[usItem].hwnd, SC_MOVE));
601 }
602 else {
603 bNeedsItem =
604 WndHasControl(plswData->hab, plswData->TaskArr[usItem].hwnd,
605 LOUSHORT(MapCommand(usId)));
606 if (usId == CMD_HIDE)
607 bNeedsItem &= (!(plswData->TaskArr[usItem].fl & SWP_HIDE));
608 }
609
610 if (usId >= CMD_HIDE && usId <= CMD_MAXIMIZE)
611 bNeedsItem &=
612 IsInDesktop(plswData->hab, plswData->TaskArr[usItem].hwnd,
613 plswData->lCurrDesktop);
614
615 }
616
617 if (bNeedsItem && pszTitle != NULL)
618 WinLoadString(plswData->hab, plswData->hmodRes, usId, usLen,
619 pszTitle);
620
621 return bNeedsItem;
622}
623
624BOOL WndHasControl(HAB hab, HWND hwndToCheck, USHORT usControl)
625{
626 HWND hwndSysMenu, hwndMinMax;
627
628 return
629 (WinIsWindow(hab, hwndToCheck) && WinIsWindowEnabled(hwndToCheck) &&
630 (((hwndSysMenu =
631 WinWindowFromID(hwndToCheck, FID_SYSMENU)) != NULLHANDLE
632 &&
633 SHORT1FROMMR(WinSendMsg
634 (hwndSysMenu, MM_ISITEMVALID,
635 MPFROM2SHORT(usControl, TRUE), 0)) == TRUE)
636 || ((hwndMinMax = WinWindowFromID(hwndToCheck, FID_MINMAX)) !=
637 NULLHANDLE
638 && SHORT1FROMMR(WinSendMsg(hwndMinMax, MM_QUERYITEMCOUNT, 0, 0))
639 > 0
640 && (SHORT) WinSendMsg(hwndMinMax, MM_ITEMPOSITIONFROMID,
641 MPFROM2SHORT(usControl, 0),
642 0) != MIT_NONE)
643 )
644 );
645}
646
647SHORT InsertMenuItem(HWND hwndMenu, HWND hwndSubMenu, SHORT iPosition,
648 SHORT sItemId, char *ItemTitle, SHORT afStyle,
649 SHORT afAttr, ULONG hItem)
650{
651 MENUITEM mi;
652
653 mi.iPosition = iPosition;
654 mi.afStyle = afStyle;
655 mi.afAttribute = afAttr;
656 mi.id = sItemId;
657 mi.hwndSubMenu = hwndSubMenu;
658 mi.hItem = hItem;
659 return
660 SHORT1FROMMR(WinSendMsg
661 (hwndMenu, MM_INSERTITEM, (MPARAM) & mi,
662 (MPARAM) ItemTitle));
663}
664
665VOID InitTaskActionsMenu(HWND hwndMenu, LSWDATA * plswData, SHORT iMenuAtItem,
666 BOOL bTaskBar, BOOL bGroup)
667{
668 SHORT sItemId, sItemNum, sLastId, sAttr;
669 UCHAR ucBuf[64];
670 HWND hwndSubmenu;
671
672 sItemNum = SHORT1FROMMR(WinSendMsg(hwndMenu, MM_QUERYITEMCOUNT, 0, 0));
673 while (sItemNum > 0) {
674 sItemId = SHORT1FROMMR(WinSendMsg(hwndMenu, MM_ITEMIDFROMPOSITION,
675 MPFROMSHORT(sItemNum - 1), 0));
676 sItemNum = SHORT1FROMMR(WinSendMsg(hwndMenu,
677 sItemId ==
678 CMD_XCENTERSUBMENU ? MM_REMOVEITEM
679 : MM_DELETEITEM,
680 MPFROM2SHORT(sItemId, FALSE), 0));
681 }
682
683 if (iMenuAtItem >= 0 && !bGroup) { //neither an empty spot on the taskbar nor the Desktop button, show context menu
684 for (sItemId = CMD_SWITCHFROMPM, sLastId = 0; sItemId <= CMD_MOVE;
685 sItemId++) {
686 if (!bTaskBar && sItemId == CMD_MOVE)
687 continue;
688 if (MenuNeedsItem(plswData, iMenuAtItem, sItemId, ucBuf,
689 sizeof(ucBuf), bGroup)) {
690 if ((sItemId == CMD_CLOSE || sItemId == CMD_KILL
691 || sLastId == CMD_SWITCHFROMPM)
692 &&
693 SHORT1FROMMR(WinSendMsg
694 (hwndMenu, MM_QUERYITEMCOUNT, 0, 0)) > 0)
695 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, 0, "",
696 MIS_SEPARATOR, 0, 0);
697 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, sItemId, ucBuf,
698 MIS_TEXT, 0, 0);
699 sLastId = sItemId;
700 }
701 }
702
703 if (!IsDesktop(plswData->TaskArr[iMenuAtItem].hwnd)) {
704 WinLoadString(plswData->hab, plswData->hmodRes, CMD_CLOSE,
705 sizeof(ucBuf), ucBuf);
706 if (SHORT1FROMMR(WinSendMsg(hwndMenu, MM_QUERYITEMCOUNT, 0, 0)) >
707 0)
708 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, 0, "",
709 MIS_SEPARATOR, 0, 0);
710
711 hwndSubmenu = WinCreateMenu(hwndMenu, NULL);
712
713 if (hwndSubmenu != NULLHANDLE) {
714 WinSetWindowULong(hwndSubmenu, QWL_STYLE,
715 WinQueryWindowULong(hwndSubmenu,
716 QWL_STYLE) |
717 MS_CONDITIONALCASCADE);
718 sItemId =
719 InsertMenuItem(hwndMenu, hwndSubmenu, MIT_END, CMD_CLOSE,
720 ucBuf, MIS_TEXT | MIS_SUBMENU, 0, 0);
721
722 if (sItemId != MIT_MEMERROR && sItemId != MIT_ERROR) {
723 sAttr = MIA_CHECKED;
724 if (MenuNeedsItem
725 (plswData, iMenuAtItem, CMD_CLOSE, ucBuf,
726 sizeof(ucBuf), bGroup)) {
727 WinLoadString(plswData->hab, plswData->hmodRes, CMD_CLOSE,
728 sizeof(ucBuf), ucBuf);
729 InsertMenuItem(hwndSubmenu, NULLHANDLE, MIT_END,
730 CMD_CLOSE, ucBuf, MIS_TEXT,
731 MIA_CHECKED, 0);
732 sAttr = 0;
733 }
734 WinLoadString(plswData->hab, plswData->hmodRes, STRID_QUIT,
735 sizeof(ucBuf), ucBuf);
736 InsertMenuItem(hwndSubmenu, NULLHANDLE, MIT_END,
737 CMD_CLOSEQUIT, ucBuf, MIS_TEXT, sAttr,
738 0);
739
740 if (MenuNeedsItem
741 (plswData, iMenuAtItem, CMD_KILL, ucBuf,
742 sizeof(ucBuf), bGroup))
743 InsertMenuItem(hwndSubmenu, NULLHANDLE, MIT_END,
744 CMD_KILL, ucBuf, MIS_TEXT, 0, 0);
745
746 if (MenuNeedsItem
747 (plswData, iMenuAtItem, CMD_DEATH, ucBuf,
748 sizeof(ucBuf), bGroup))
749 InsertMenuItem(hwndSubmenu, NULLHANDLE, MIT_END,
750 CMD_DEATH, ucBuf, MIS_TEXT, 0, 0);
751 }
752 }
753 }
754
755 if (MenuNeedsItem
756 (plswData, iMenuAtItem, CMD_PRIORITY, ucBuf, sizeof(ucBuf),
757 bGroup)) {
758 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, 0, "",
759 MIS_SEPARATOR, 0, 0);
760 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, CMD_PRIORITY, ucBuf,
761 MIS_TEXT, 0, 0);
762 }
763
764 if (MenuNeedsItem
765 (plswData, iMenuAtItem, CMD_ADDFILTER, ucBuf, sizeof(ucBuf),
766 bGroup)) {
767 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, 0, "",
768 MIS_SEPARATOR, 0, 0);
769 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, CMD_ADDFILTER,
770 ucBuf, MIS_TEXT, 0, 0);
771 }
772 }
773#ifndef XWORKPLACE
774 else { //iMenuAtItem==-1, either an empty spot on the taskbar or the Desktop button, show generic menu
775 WinLoadString(plswData->hab, plswData->hmodRes, STRID_RUN,
776 sizeof(ucBuf), ucBuf);
777 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, CMD_RUN, ucBuf,
778 MIS_TEXT, 0, 0);
779 //InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, 0, "", MIS_SEPARATOR, 0,
780 // 0);
781 //WinLoadString(plswData->hab, plswData->hmodRes, STRID_SUSPEND,
782 // sizeof(ucBuf), ucBuf);
783 //InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, CMD_SUSPEND, ucBuf,
784 // MIS_TEXT, 0, 0);
785 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, 0, "", MIS_SEPARATOR, 0,
786 0);
787 WinLoadString(plswData->hab, plswData->hmodRes, STRID_SHOWSETTINGS,
788 sizeof(ucBuf), ucBuf);
789 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, CMD_SHOWSETTINGS, ucBuf,
790 MIS_TEXT, 0, 0);
791 WinLoadString(plswData->hab, plswData->hmodRes, STRID_HELP,
792 sizeof(ucBuf), ucBuf);
793 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, CMD_HELP, ucBuf,
794 MIS_TEXT, 0, 0);
795 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, 0, "", MIS_SEPARATOR, 0,
796 0);
797 WinLoadString(plswData->hab, plswData->hmodRes, STRID_QUIT,
798 sizeof(ucBuf), ucBuf);
799 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, CMD_QUIT, ucBuf,
800 MIS_TEXT, 0, 0);
801 }
802#else
803 WinSetPresParam(plswData->pWidget->hwndContextMenu, PP_FONTNAMESIZE, 7,
804 "8.Helv");
805
806 if (bTaskBar && iMenuAtItem >= 0) {
807 // now set the old context menu as submenu;
808 if (!bGroup)
809 InsertMenuItem(hwndMenu, NULLHANDLE, MIT_END, 0, "", MIS_SEPARATOR, 0,
810 0);
811
812 WinLoadString(plswData->hab, plswData->hmodRes, STRID_XCENTERSUBMENU,
813 sizeof(ucBuf), ucBuf);
814 InsertMenuItem(hwndMenu, plswData->pWidget->hwndContextMenu, MIT_END,
815 CMD_XCENTERSUBMENU, ucBuf, MIS_TEXT | MIS_SUBMENU, 0,
816 0);
817 }
818#endif
819}
820
821VOID ShowMenu(LSWDATA * plswData, SHORT iMenuAtItem, BOOL bTaskBar,
822 BOOL bGroup)
823{
824 POINTL ptl;
825
826 InitTaskActionsMenu(plswData->hwndMenu, plswData, iMenuAtItem, bTaskBar,
827 bGroup);
828 WinQueryPointerPos(HWND_DESKTOP, &ptl);
829
830#ifdef XWORKPLACE
831 WinPopupMenu(HWND_DESKTOP,
832 bTaskBar ? plswData->hwndTaskBarClient : plswData->
833 hwndPopClient, (iMenuAtItem < 0
834 && bTaskBar) ? plswData->pWidget->
835 hwndContextMenu : plswData->hwndMenu, ptl.x, ptl.y, 0,
836 PU_HCONSTRAIN | PU_VCONSTRAIN | PU_MOUSEBUTTON1 |
837 PU_MOUSEBUTTON2 | PU_KEYBOARD);
838#else
839 WinPopupMenu(HWND_DESKTOP,
840 bTaskBar ? plswData->hwndTaskBarClient : plswData->
841 hwndPopClient, plswData->hwndMenu, ptl.x, ptl.y, 0,
842 PU_HCONSTRAIN | PU_VCONSTRAIN | PU_MOUSEBUTTON1 |
843 PU_MOUSEBUTTON2 | PU_KEYBOARD);
844#endif
845}
846
847VOID ShowBubble(LSWDATA * plswData, SHORT iMouseIsAtItem, USHORT usX,
848 USHORT usY, SHORT iFunc, UCHAR * ucTitle2)
849{
850 static SHORT iMouseWasAtItem = -1, iCounter1 = 0, iBubbleAtItem =
851 -1, iSource;
852 USHORT usSizeX, usSizeY;
853 POINTL aptl[TXTBOX_COUNT];
854 UCHAR ucTitle[NAMELEN];
855 HPS hps;
856 LONG cxScreen;
857 SWP swp;
858
859 if (iFunc > 0) {
860 if (iFunc <= 10) { //iFunc==11 -- update bubble text
861 if (iMouseIsAtItem == iMouseWasAtItem || iMouseWasAtItem < 0)
862 iCounter1 += BUBBLETIMERINTERVAL;
863 else
864 iCounter1 = 0;
865 iMouseWasAtItem = iMouseIsAtItem;
866 iSource = iFunc;
867 }
868
869 if ((iFunc <= 10
870 && ((iCounter1 >= 800 /*ms */ && iBubbleAtItem < 0) ||
871 (iBubbleAtItem >= 0 && iBubbleAtItem != iMouseIsAtItem)))
872 || (iFunc == 11 && iMouseIsAtItem == iBubbleAtItem)) {
873 if (ucTitle2 == NULL)
874 GetItemTitle(plswData->TaskArr[iMouseIsAtItem].hsw, ucTitle,
875 sizeof(ucTitle), FALSE);
876 else
877 strncpy(ucTitle, ucTitle2, sizeof(ucTitle) - 1);
878 hps = WinGetPS(plswData->hwndBubble);
879 GpiQueryTextBox(hps, strlen(ucTitle), ucTitle, TXTBOX_COUNT,
880 aptl);
881 WinReleasePS(hps);
882 if (iFunc == 11) {
883 WinQueryWindowPos(plswData->hwndBubble, &swp);
884 usX = swp.x;
885 usY = swp.y;
886 }
887 usSizeX = aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x + 8;
888 usSizeY = aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y + 4;
889 cxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
890 if (usX + usSizeX > cxScreen)
891 usX -= usX + usSizeX - cxScreen;
892 WinSetWindowPos(plswData->hwndBubble, HWND_TOP,
893 usX, usY, usSizeX, usSizeY,
894 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);
895 WinSetWindowPos(WinWindowFromID
896 (plswData->hwndBubble, ID_BUBBLEFRAME), 0, 0, 0,
897 usSizeX, usSizeY, SWP_MOVE | SWP_SIZE | SWP_SHOW);
898 WinSetWindowText(plswData->hwndBubble, ucTitle);
899 iBubbleAtItem = iMouseIsAtItem;
900 }
901 else if (iBubbleAtItem >= 0 &&
902 (WinQueryWindowPos(plswData->hwndBubble, &swp),
903 aptl[0].x = swp.x, aptl[0].y = aptl[1].y =
904 swp.y + swp.cy - 1, aptl[1].x =
905 swp.x + swp.cx - 1, WinWindowFromPoint(HWND_DESKTOP,
906 &aptl[0],
907 FALSE) !=
908 plswData->hwndBubble
909 || WinWindowFromPoint(HWND_DESKTOP, &aptl[1],
910 FALSE) != plswData->hwndBubble)) {
911 WinSetWindowPos(plswData->hwndBubble, HWND_TOP, 0, 0, 0, 0,
912 SWP_ZORDER);
913 WinInvalidateRect(plswData->hwndBubble, NULL, TRUE);
914 }
915 }
916 else if (abs(iFunc) == iSource) {
917 UCHAR ucBuf[32];
918
919 if (WinIsWindowVisible(plswData->hwndBubble))
920 WinSetWindowPos(plswData->hwndBubble, HWND_BOTTOM, 0, 0, 0, 0,
921 SWP_HIDE | SWP_ZORDER);
922 iBubbleAtItem = -1;
923 iMouseWasAtItem = -1;
924 iCounter1 = 0;
925
926 WinQueryPresParam(plswData->hwndBubble, PP_BACKGROUNDCOLOR, 0, NULL,
927 sizeof(ucBuf), ucBuf, QPF_NOINHERIT);
928 plswData->Settings.lBubbleRGBCol =
929 ucBuf[0] + ucBuf[1] * 256 + ucBuf[2] * 65536;
930 WinQueryPresParam(plswData->hwndBubble, PP_FOREGROUNDCOLOR, 0, NULL,
931 sizeof(ucBuf), ucBuf, QPF_NOINHERIT);
932 plswData->Settings.lBubbleTextRGBCol =
933 ucBuf[0] + ucBuf[1] * 256 + ucBuf[2] * 65536;
934 }
935}
936
937BOOL IsWindowClass(HWND hwnd, UCHAR * pszClassName)
938{
939 UCHAR ucBuf[128];
940
941 WinQueryClassName(hwnd, sizeof(ucBuf), ucBuf);
942 return (strcmp(ucBuf, pszClassName) == 0);
943}
944
945// returns a pointer to PSWBLOCK and the item count; a second call with bInit=FALSE
946// is needed to free the memory allocated for PSWBLOCK
947PVOID GetSwitchList(HAB hab, BOOL bInit, ULONG * ItemCount)
948{
949 static PSWBLOCK pSwb = NULL;
950 static ULONG ulItemCount, ulRecCount = 0;
951
952 if (bInit) {
953 ulRecCount++;
954 if (pSwb != NULL) {
955 *ItemCount = ulItemCount;
956 return pSwb;
957 }
958 if ((ulItemCount = WinQuerySwitchList(hab, NULL, 0)) == 0 ||
959 (pSwb =
960 malloc(sizeof(HSWITCH) + sizeof(SWENTRY) * ulItemCount)) ==
961 NULL) {
962 return NULL;
963 }
964 /* get all switch entries in one call; calling WinQuerySwitchHandle/SwitchEntry
965 for each window turns out to be noticeably slower */
966 ulItemCount =
967 WinQuerySwitchList(hab, pSwb,
968 sizeof(HSWITCH) +
969 sizeof(SWENTRY) * ulItemCount);
970 *ItemCount = ulItemCount;
971 return pSwb;
972 }
973 else {
974 ulRecCount--;
975 if (ulRecCount == 0) {
976 if (pSwb != NULL)
977 free(pSwb);
978 pSwb = NULL;
979 }
980 return NULL;
981 }
982}
983
984BOOL IsMinToViewer(HWND hwnd, ULONG flopt)
985{
986 return
987 ((flopt & SWP_MINIMIZE)
988 && WinQueryWindowUShort(hwnd, QWS_YMINIMIZE) == 33536);
989}
990
991//returns TRUE if any part of the hwnd is currently within desktop
992BOOL IsInDesktop(HAB hab, HWND hwnd, LONG lCurrDesktop)
993{
994 SWP swp;
995 RECTL rcl1, rcl2, rcl3;
996 USHORT usCXScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN),
997 usCYScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
998
999 WinQueryWindowPos(hwnd, &swp);
1000#if 0
1001 if (swp.fl & SWP_MINIMIZE) {
1002 swp.x = WinQueryWindowUShort(hwnd,QWS_XRESTORE);
1003 swp.y = WinQueryWindowUShort(hwnd,QWS_YRESTORE);
1004 swp.cx = WinQueryWindowUShort(hwnd,QWS_CXRESTORE);
1005 swp.cy = WinQueryWindowUShort(hwnd,QWS_CYRESTORE);
1006 }
1007#endif
1008 WinSetRect(hab, &rcl1, swp.x, swp.y, swp.x + swp.cx, swp.y + swp.cy);
1009#if 0
1010 // +8 may need to be added to CXScreen and CYScreen as virtual desktop dimensions seem to be 8 points larger than screen size
1011 WinSetRect(hab,&rcl2, usCXScreen*((lCurrDesktop&0xFF00)>>8),
1012 usCYScreen*(lCurrDesktop&0xFF), usCXScreen*(((lCurrDesktop&0xFF00)>>8)+1),
1013 usCYScreen*((lCurrDesktop&0xFF)+1));
1014#endif
1015 WinSetRect(hab, &rcl2, 0, 0, usCXScreen, usCYScreen);
1016
1017 WinIntersectRect(hab, &rcl3, &rcl1, &rcl2);
1018
1019 return (!WinIsRectEmpty(hab, &rcl3));
1020}
1021
1022#if 0
1023//get the virtual desktop number relative to the one in which the program was started
1024LONG GetCurrDesktop(LSWDATA *plswData)
1025{ USHORT usCXScreen=WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN),
1026 usCYScreen=WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN);
1027 SWP swp;
1028 SHORT x,y;
1029
1030 if (plswData->bNowActive) return -1;
1031
1032 WinQueryWindowPos(plswData->hwndPopup,&swp);
1033 x=(POPUPWINHIDEPOSX-swp.x)/usCXScreen;
1034 y=(POPUPWINHIDEPOSY-swp.y)/usCYScreen;
1035 return ((x<<8)+y);
1036}
1037#endif
1038
1039VOID MinimizeHideAll(LSWDATA * plswData, BOOL bReset, HWND hwndReset)
1040{
1041 SHORT i;
1042 HSWITCH hswDesktop;
1043 static USHORT usNumWin;
1044 static BOOL bRestoreAll = FALSE;
1045 static LONG lDskNum;
1046 static HWND *hwndList = NULL;
1047
1048 if (bReset) {
1049 if (hwndList != NULL)
1050 for (i = 0; i < usNumWin; i++)
1051 if (hwndReset == hwndList[i]) {
1052 free(hwndList);
1053 hwndList = NULL;
1054 bRestoreAll = FALSE;
1055 break;
1056 }
1057 return;
1058 }
1059
1060 if (!bRestoreAll) {
1061 if (hwndList != NULL)
1062 free(hwndList);
1063 hswDesktop = plswData->TaskArr[plswData->usCurrItem].hsw;
1064 InitTaskArr(plswData, FALSE, FALSE, FALSE);
1065 if ((hwndList = malloc(plswData->usItems * sizeof(HWND))) != NULL)
1066 for (i = plswData->usItems - 2, usNumWin = 0; i >= 0; i--) {
1067 if ((MenuNeedsItem(plswData, i, CMD_MINIMIZE, NULL, 0, FALSE)
1068 && ChangeWindowPos(plswData, i, CMD_MINIMIZE))
1069 || (MenuNeedsItem(plswData, i, CMD_HIDE, NULL, 0, FALSE)
1070 && ChangeWindowPos(plswData, i, CMD_HIDE)))
1071 hwndList[usNumWin++] = plswData->TaskArr[i].hwnd;
1072 }
1073 lDskNum = plswData->lCurrDesktop; //GetCurrDesktop(plswData);
1074 WinSwitchToProgram(hswDesktop);
1075 }
1076 else {
1077 if (hwndList == NULL || lDskNum != plswData->lCurrDesktop) //GetCurrDesktop(plswData)
1078 return;
1079
1080 for (i = 0; i < usNumWin; i++) {
1081 WinSetWindowPos(hwndList[i], HWND_TOP, 0, 0, 0, 0,
1082 SWP_SHOW | SWP_ZORDER);
1083 WinSwitchToProgram(WinQuerySwitchHandle(hwndList[i], 0));
1084 }
1085
1086 free(hwndList);
1087 hwndList = NULL;
1088 }
1089
1090 bRestoreAll ^= TRUE;
1091}
1092
1093VOID GetItemTitle(HSWITCH hsw, UCHAR * ucTitle, USHORT usLen, BOOL bSessNum)
1094{
1095 SWCNTRL swctl;
1096 USHORT k;
1097
1098 if (WinQuerySwitchEntry(hsw, &swctl) != 0) {
1099 strcpy(ucTitle, "");
1100 return;
1101 }
1102
1103 if (bSessNum)
1104 sprintf(ucTitle, "%.*s (0x%X)", usLen - 6, swctl.szSwtitle,
1105 swctl.idProcess);
1106 else
1107 strncpy(ucTitle, swctl.szSwtitle, usLen - 1);
1108
1109 for (k = 0; k < strlen(ucTitle); k++)
1110 if (ucTitle[k] == '\r' || ucTitle[k] == '\n')
1111 ucTitle[k] = ' ';
1112}
1113
1114HPOINTER GetWndIcon(HWND hwnd)
1115{
1116 HPOINTER hIcon;
1117 UCHAR *pszPath;
1118 HWND hwnd1;
1119
1120 if ((hIcon =
1121 (HPOINTER) WinSendMsg(hwnd, WM_QUERYICON, 0, 0)) != NULLHANDLE)
1122 return hIcon;
1123
1124 if (IsWindowClass
1125 ((hwnd1 = WinWindowFromID(hwnd, FID_CLIENT)), "SeamlessClass")) {
1126 pszPath = (UCHAR *) WinQueryWindowULong(hwnd1, 0L);
1127 hIcon = WinLoadFileIcon(pszPath, FALSE);
1128 } /*else {
1129 ULONG ulItemCount;
1130 LONG k;
1131 PSWBLOCK pSwb;
1132 PID pid;
1133 TID tid;
1134
1135 if ((pSwb=GetSwitchList(0,TRUE,&ulItemCount))!=NULL) {
1136 for (k=ulItemCount-1;k>=0 && hIcon==NULLHANDLE;k--) {
1137 WinQueryWindowProcess(hwnd,&pid,&tid);
1138 if (pSwb->aswentry[k].swctl.hwnd!=hwnd && pSwb->aswentry[k].swctl.idProcess==pid)
1139 hIcon=(HPOINTER)WinSendMsg(pSwb->aswentry[k].swctl.hwnd,WM_QUERYICON,0,0);
1140 }
1141 GetSwitchList(0,FALSE,NULL);
1142 }
1143 } */
1144
1145 if (hIcon == NULLHANDLE)
1146 hIcon = WinQuerySysPointer(HWND_DESKTOP, SPTR_PROGRAM, FALSE);
1147
1148 return hIcon;
1149}
1150
1151/*
1152PSZ GetObjectName(USHORT usObjHandle)
1153{ UCHAR ucKey[16],*pucObjData,*substr=NULL,*pszName=NULL;
1154 ULONG k,ulDataSize;
1155
1156 if ((pucObjData=malloc(ulDataSize=1024))==NULL) return NULL;
1157 sprintf(ucKey,"%X",usObjHandle);
1158 if (PrfQueryProfileData(HINI_USERPROFILE,"PM_Abstract:Objects",ucKey,pucObjData,&ulDataSize))
1159 for (k=0,substr=NULL;substr==NULL && k<ulDataSize-strlen("WPAbstract");k++)
1160 if ((substr=strstr(&pucObjData[k],"WPAbstract"))!=NULL) substr+=17;
1161
1162 if (substr!=NULL) pszName=strdup(substr);
1163 free(pucObjData);
1164 return pszName;
1165}
1166*/
1167BOOL IsDesktop(HWND hwnd)
1168{
1169 return (hwnd == WinQueryWindow(HWND_DESKTOP, QW_BOTTOM) &&
1170 (IsWindowClass(hwnd, "wpFolder window")));
1171}
1172
1173//Written by Staffan Ulfberg
1174char Match(char *string, char *pattern)
1175{
1176 for (; '*' ^ *pattern; ++pattern, ++string) {
1177 if (!*string)
1178 return (!*pattern);
1179 if (toupper(*string) ^ toupper(*pattern) && '?' ^ *pattern)
1180 return FALSE;
1181 }
1182 /* two-line patch to prevent *too* much recursiveness: */
1183 while ('*' == pattern[1])
1184 pattern++;
1185 do {
1186 if (Match(string, pattern + 1))
1187 return TRUE;
1188 } while (*string++);
1189 return FALSE;
1190}
1191
1192BOOL IsInSkipList(SKIPLIST * pSkipList, UCHAR * ucTitle)
1193{
1194 BOOL bFound;
1195 USHORT j;
1196
1197 for (j = 0, bFound = FALSE;
1198 j < MAXITEMS && (*pSkipList)[j] != NULL &&
1199 !(bFound = Match(ucTitle, (*pSkipList)[j])); j++) ;
1200
1201 return bFound;
1202}
1203
1204BOOL AddFilter(SKIPLIST * pSkipList, UCHAR * ucName)
1205{
1206 SHORT iNum;
1207
1208 if (strlen(ucName) == 0 || IsInSkipList(pSkipList, ucName))
1209 return FALSE;
1210
1211 for (iNum = 0; (*pSkipList)[iNum] != NULL && iNum < MAXITEMS; iNum++) ;
1212 if (iNum == MAXITEMS)
1213 return FALSE;
1214
1215 (*pSkipList)[iNum++] = strdup(ucName);
1216 return TRUE;
1217}
1218
1219BOOL RemoveFilter(SKIPLIST * pSkipList, UCHAR * ucName)
1220{
1221 SHORT iNum, k;
1222
1223 for (iNum = 0; (*pSkipList)[iNum] != NULL && iNum < MAXITEMS; iNum++) ;
1224
1225 for (k = 0; k < iNum; k++)
1226 if (strcmp((*pSkipList)[k], ucName) == 0) {
1227 free((*pSkipList)[k]);
1228 memmove(&(*pSkipList)[k], &(*pSkipList)[k + 1],
1229 sizeof(*pSkipList[0]) * (iNum - k - 1));
1230 (*pSkipList)[--iNum] = NULL;
1231 return TRUE;
1232 }
1233
1234 return FALSE;
1235}
1236#if 0
1237VOID SetPriorityFromList(PID pid HWND hwnd)
1238{
1239 // This needs to be added to InitTaskArr and where ever new processes get added.
1240 // This is already stored pbData->hMte but has it been initialized at this point?
1241 // Can get it with HmteFromPID(swctl.idProcess) if not.
1242 CHAR s[1036];
1243 INT rc;
1244 QSPTRREC *pbh;
1245 QSLREC *pmi;
1246
1247 pbh = malloc(2048);
1248 if (pbh) {
1249 rc = DosQuerySysState(QS_MTE, pid, 0, 0, pbh, 2048);
1250 if (!rc) {
1251 pmi = pbh->pLibRec;
1252 if (pmi) {
1253 if (!stricmp((CHAR *) pmi->pName, "SYSINIT"))
1254 GetDosPgmName(pid, s); // probably won't work
1255 else {
1256 if (*pmi->pName)
1257 strcpy(s, (CHAR *) pmi->pName);
1258 else
1259 return;
1260 }
1261 p = strrchr(s , '\\');
1262 if (p)
1263 p++;
1264 else
1265 return;
1266 strcpy(fname, p);
1267 if (IsInSkipList(plswData->Settings.ListPriority, fname)) {
1268 SHORT sPrtyC, sPrtyD;
1269 BOOL bDesc;
1270
1271 PrfQueryProfileString(hini, PRF_APPNAME, fname, "2000",
1272 s, sizeof(s));
1273 bDesc = atoi(s[3]);
1274 s[3] = '\0';
1275 sPrtyD = atoi(s[1];
1276 s[1] = '\0';
1277 sPrtyC = atoi(s[0]);
1278 WinPostMsg(hwnd, WinFindAtom(WinQuerySystemAtomTable(),
1279 LSWM_SETPRIORITY),
1280 MPFROM2SHORT(((sPrtyC << 8) +
1281 sPrtyD) | (bDesc ? 0x8000 : 0), 0),
1282 MPFROMLONG(pid));
1283 }
1284 }
1285 }
1286 }
1287}
1288#endif
1289
1290VOID InitTaskArr(LSWDATA * plswData, BOOL bFullScreen, BOOL bTaskBar,
1291 BOOL bUseFilters)
1292{
1293 ULONG sidCurr, ulItemCount, ulItem;
1294 PSWBLOCK pSwb;
1295 HENUM henum;
1296 HWND hwndNext, hwndActive;
1297 SWP swp;
1298 UCHAR ucIndex;
1299 SWITEM ditem;
1300 BOOL bFound, bIsCurrent;
1301 SKIPLIST *pSkipList =
1302 bTaskBar ? &plswData->Settings.SkipListTskBar : &plswData->Settings.
1303 SkipListPopup;
1304
1305 sidCurr = 0;
1306 hwndActive = NULLHANDLE;
1307
1308 plswData->usItems = plswData->usCurrItem = plswData->iShift = 0;
1309 memset(plswData->TaskArr, 0, sizeof(plswData->TaskArr));
1310
1311 if ((pSwb = GetSwitchList(plswData->hab, TRUE, &ulItemCount)) == NULL)
1312 return;
1313/* get SID of the current fullscreen process */
1314 if (bFullScreen) {
1315 if (DosQuerySysInfo(24, 24, &sidCurr, sizeof(sidCurr)) != 0)
1316 sidCurr = 0;
1317 }
1318 else {
1319 hwndActive =
1320 WinQueryActiveWindow(WinQueryDesktopWindow
1321 (plswData->hab, NULLHANDLE));
1322 }
1323
1324 henum =
1325 WinBeginEnumWindows(WinQueryDesktopWindow(plswData->hab, NULLHANDLE));
1326
1327 while ((hwndNext = WinGetNextWindow(henum)) != NULLHANDLE
1328 && plswData->usItems < MAXITEMS - 1) {
1329 for (ulItem = 0, bFound = FALSE; ulItem < ulItemCount; ulItem++)
1330 if ((bFound =
1331 (hwndNext == pSwb->aswentry[ulItem].swctl.hwnd)) == TRUE)
1332 break;
1333
1334 if (!bFound || !WinIsWindow(plswData->hab, hwndNext) ||
1335 pSwb->aswentry[ulItem].swctl.uchVisibility != SWL_VISIBLE)
1336 continue;
1337
1338 WinQueryWindowPos(hwndNext, &swp);
1339
1340 bFound = (!bUseFilters
1341 || (sidCurr == pSwb->aswentry[ulItem].swctl.idSession
1342 ||
1343 (((bTaskBar ? plswData->Settings.
1344 bShowHiddenTskBar : plswData->Settings.bShowHidden)
1345 || !(swp.fl & SWP_HIDE))
1346 &&
1347 ((bTaskBar ? plswData->Settings.
1348 bShowViewerTskBar : plswData->Settings.bShowViewer)
1349 || !IsMinToViewer(hwndNext, swp.fl))))
1350 && !IsInSkipList(pSkipList,
1351 pSwb->aswentry[ulItem].swctl.szSwtitle));
1352
1353 /* save the current entry in the last element of the array even if it's
1354 not supposed to be switched to. It will be used if switching is cancelled */
1355 bIsCurrent = ((!bFullScreen &&
1356 (hwndNext == hwndActive ||
1357 hwndNext == WinQueryWindow(hwndActive, QW_OWNER))) ||
1358 (bFullScreen
1359 && pSwb->aswentry[ulItem].swctl.idSession == sidCurr));
1360
1361 if (bFound) {
1362 ucIndex = plswData->usItems;
1363 plswData->usItems++;
1364 }
1365 else if (bIsCurrent)
1366 ucIndex = MAXITEMS - 1;
1367 else
1368 continue;
1369
1370 plswData->TaskArr[ucIndex].ulType =
1371 pSwb->aswentry[ulItem].swctl.bProgType;
1372 plswData->TaskArr[ucIndex].fl = swp.fl;
1373 plswData->TaskArr[ucIndex].hsw = pSwb->aswentry[ulItem].hswitch;
1374 plswData->TaskArr[ucIndex].hwnd = hwndNext;
1375 plswData->TaskArr[ucIndex].hIcon = GetWndIcon(hwndNext);
1376 plswData->TaskArr[ucIndex].pid =
1377 pSwb->aswentry[ulItem].swctl.idProcess;
1378
1379 if (bFound && bIsCurrent) {
1380 memcpy(&plswData->TaskArr[MAXITEMS - 1],
1381 &plswData->TaskArr[ucIndex], sizeof(SWITEM));
1382 /* make sure current session or window is in the 0th element of the TaskArr */
1383 if (ucIndex != 0) {
1384 memcpy(&ditem, &plswData->TaskArr[ucIndex], sizeof(ditem));
1385 memmove(&plswData->TaskArr[1], &plswData->TaskArr[0],
1386 sizeof(ditem) * ucIndex);
1387 memcpy(&plswData->TaskArr[0], &ditem, sizeof(ditem));
1388 }
1389 }
1390 }
1391
1392 WinEndEnumWindows(henum);
1393
1394 GetSwitchList(0, FALSE, NULL);
1395
1396 if (plswData->TaskArr[MAXITEMS - 1].hsw == 0)
1397 plswData->TaskArr[MAXITEMS - 1].hwnd = hwndActive;
1398}
1399
1400USHORT RunCommand(LSWDATA * plswData, UCHAR * ucCommand, UCHAR * ucErrMsg,
1401 USHORT usErrMsgLen)
1402{
1403 STARTDATA SData;
1404 static UCHAR k, ucCmdLine[_MAX_PATH] =
1405 "", ucPath[_MAX_PATH], ucPgmInp[_MAX_PATH], drive[_MAX_DRIVE],
1406 dir[_MAX_DIR], name[_MAX_FNAME], ext[_MAX_EXT], *args,
1407 ucExtStr[4][4] = { "bat\0", "cmd\0", "com\0", "exe\0" };
1408 APIRET rc;
1409 PID pid;
1410 ULONG ulSessID, ulAppType;
1411
1412 if ((args = strchr(ucCommand, ' ')) != NULL) {
1413 strcpy(ucCmdLine, args);
1414 *args = '\0';
1415 }
1416 strcpy(ucPath, ucCommand);
1417
1418 _splitpath(ucPath, drive, dir, name, ext);
1419
1420 for (k = 0, rc = 0; k < (strlen(ext) == 0 ? 4 : 1); k++) { //add an extension if needed and find if file exists
1421 if (strlen(ext) == 0)
1422 _makepath(ucPath, drive, dir, name, ucExtStr[k]);
1423 ulAppType = 0;
1424 rc = DosQueryAppType(ucPath, &ulAppType);
1425 if (rc == 0 || rc == 191 || rc == 193)
1426 break;
1427 else
1428 strncpy(ucPath, name, sizeof(ucPath));
1429 }
1430
1431 memset(&SData, 0, sizeof(SData));
1432 SData.Length = sizeof(SData);
1433 SData.Related = SSF_RELATED_INDEPENDENT;
1434 SData.FgBg = SSF_FGBG_FORE;
1435 SData.TraceOpt = SSF_TRACEOPT_NONE;
1436 SData.InheritOpt = SSF_INHERTOPT_SHELL;
1437 SData.PgmControl = SSF_CONTROL_VISIBLE;
1438 SData.SessionType = SSF_TYPE_DEFAULT;
1439
1440 if (ulAppType == 0x20
1441 || strcmpi(ucPath + strlen(ucPath) - 4, ".BAT") == 0)
1442 SData.SessionType = SSF_TYPE_WINDOWEDVDM;
1443
1444 if (ulAppType &
1445 (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31)) {
1446 SData.PgmName = "WINOS2.COM";
1447 sprintf(ucPgmInp, "/3 %s %s", ucPath, ucCmdLine);
1448 SData.SessionType = PROG_31_ENHSEAMLESSCOMMON;
1449 }
1450 else if (rc != 0 || strcmpi(ucPath + strlen(ucPath) - 4, ".CMD") == 0) {
1451 sprintf(ucPgmInp, "/C%s %s", ucPath, ucCmdLine);
1452 }
1453 else {
1454 SData.PgmName = ucPath;
1455 strcpy(ucPgmInp, ucCmdLine);
1456 }
1457 SData.PgmInputs = ucPgmInp;
1458
1459 if ((rc = DosStartSession(&SData, &ulSessID, &pid)) != 0) {
1460 WinLoadString(plswData->hab, plswData->hmodRes, MSG_CANTEXECUTE,
1461 usErrMsgLen, ucErrMsg);
1462 strncat(ucErrMsg, SData.PgmName, usErrMsgLen - strlen(ucErrMsg) - 1);
1463 return rc;
1464 }
1465
1466 return 0;
1467}
1468
1469VOID SetControlsFont(HWND hwnd, BOOL bDoTitleBar)
1470{
1471 ULONG aulSysInfo[2] = { 0 };
1472 UCHAR ucFont[FACESIZE];
1473 HWND hwndCtl;
1474 HENUM henum;
1475
1476 DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_VERSION_MINOR, aulSysInfo,
1477 sizeof(aulSysInfo));
1478 strcpy(ucFont,
1479 (aulSysInfo[0] == 20
1480 && aulSysInfo[1] >= 40) ? DEFTITLEFONT4 : DEFTITLEFONT3);
1481
1482 henum = WinBeginEnumWindows(hwnd);
1483 while ((hwndCtl = WinGetNextWindow(henum)) != NULLHANDLE) {
1484 if (!bDoTitleBar && IsWindowClass(hwndCtl, "#9"))
1485 continue;
1486 WinSetPresParam(hwndCtl, PP_FONTNAMESIZE, strlen(ucFont) + 1, ucFont);
1487 }
1488 WinEndEnumWindows(henum);
1489}
1490
1491VOID GetStartupDir(UCHAR * ucDir, USHORT usLen)
1492{
1493 SHORT k;
1494
1495#ifndef XWORKPLACE
1496 PPIB ppib;
1497
1498 DosGetInfoBlocks(NULL, &ppib);
1499 DosQueryModuleName(ppib->pib_hmte, usLen, ucDir);
1500#else
1501 DosQueryModuleName(hmodWidgetDll, usLen, ucDir);
1502#endif
1503
1504 for (k = strlen(ucDir) - 1; ucDir[k] != '\\' && k >= 0; k--) ;
1505 ucDir[k + 1] = '\0';
1506}
1507
1508BOOL queryAppInstance(VOID)
1509{
1510 HEV hev = 0;
1511 APIRET rc = DosOpenEventSem(SEMRUNNINGNAME, &hev);
1512
1513 //PmpfF(("AppInstance error code \"%i\"", rc));
1514
1515 if (rc == 187)
1516 return FALSE;
1517 else if (rc)
1518 return TRUE;
1519 else {
1520 DosCloseEventSem(hev);
1521 return TRUE;
1522 }
1523}
1524
1525BOOL UpdateWinFlags(ULONG * OldFlags, ULONG NewFlags)
1526{
1527 BOOL bNeedUpdate;
1528
1529 NewFlags &=
1530 (SWP_MINIMIZE | SWP_MAXIMIZE | SWP_RESTORE | SWP_SHOW | SWP_HIDE |
1531 SWP_ACTIVATE | SWP_DEACTIVATE);
1532
1533 bNeedUpdate = (((NewFlags & SWP_MINIMIZE) && !(*OldFlags & SWP_MINIMIZE))
1534 || ((NewFlags & SWP_ACTIVATE)
1535 && !(*OldFlags & SWP_ACTIVATE))
1536 || ((NewFlags & SWP_DEACTIVATE)
1537 && !(*OldFlags & SWP_DEACTIVATE))
1538 || ((NewFlags & SWP_SHOW) && !(*OldFlags & SWP_SHOW))
1539 || ((NewFlags & SWP_HIDE) && !(*OldFlags & SWP_HIDE))
1540 || ((NewFlags & SWP_RESTORE) && (*OldFlags & SWP_MINIMIZE))
1541 || ((NewFlags & SWP_MAXIMIZE)
1542 && (*OldFlags & SWP_MINIMIZE))
1543 );
1544
1545 *OldFlags |= NewFlags;
1546
1547 if (NewFlags & SWP_MINIMIZE)
1548 *OldFlags &= (~(SWP_RESTORE | SWP_MAXIMIZE));
1549 if (NewFlags & SWP_RESTORE)
1550 *OldFlags &= (~(SWP_MINIMIZE | SWP_MAXIMIZE));
1551 if (NewFlags & SWP_MAXIMIZE)
1552 *OldFlags &= (~(SWP_MINIMIZE | SWP_RESTORE));
1553
1554 if (NewFlags & SWP_HIDE)
1555 *OldFlags &= (~SWP_SHOW);
1556 if (NewFlags & SWP_SHOW)
1557 *OldFlags &= (~SWP_HIDE);
1558
1559 if (NewFlags & SWP_ACTIVATE)
1560 *OldFlags &= (~SWP_DEACTIVATE);
1561 if (NewFlags & SWP_DEACTIVATE)
1562 *OldFlags &= (~SWP_ACTIVATE);
1563
1564 return bNeedUpdate;
1565}
1566
1567VOID MakeFitStr(HPS hps, UCHAR * ucStr, USHORT usStrSize, USHORT usStrWid)
1568{
1569 USHORT usLen, usEllWid;
1570 POINTL aptl[TXTBOX_COUNT];
1571
1572 usLen = strlen(ucStr);
1573 GpiQueryTextBox(hps, usLen, ucStr, TXTBOX_COUNT, aptl);
1574 if (aptl[TXTBOX_BOTTOMRIGHT].x - aptl[TXTBOX_BOTTOMLEFT].x <= usStrWid)
1575 return;
1576
1577 GpiQueryTextBox(hps, 2, "..", TXTBOX_COUNT, aptl);
1578 usEllWid = aptl[TXTBOX_BOTTOMRIGHT].x - aptl[TXTBOX_BOTTOMLEFT].x;
1579
1580 do {
1581 GpiQueryTextBox(hps, --usLen, ucStr, TXTBOX_COUNT, aptl);
1582 } while (usLen > 0
1583 && aptl[TXTBOX_BOTTOMRIGHT].x - aptl[TXTBOX_BOTTOMLEFT].x +
1584 usEllWid > usStrWid);
1585
1586 ucStr[usLen] = '\0';
1587 strncat(ucStr, "..", usStrSize - usLen);
1588}
1589
1590USHORT FindResDll(UCHAR * ucDllName, USHORT usNameLen, USHORT * usLang,
1591 UCHAR * ucLangStr, USHORT usLangStrLen)
1592{
1593 static UCHAR ucDir[_MAX_PATH], ucName[_MAX_PATH], ucErr[32];
1594 static HDIR hdir = HDIR_CREATE;
1595 HMODULE hmodRes;
1596 FILEFINDBUF3 FindBuffer = { 0 };
1597 ULONG ulResultBufLen, ulFindCount;
1598 APIRET rc;
1599 RESVERPROC *ResVerProc;
1600 ULONG ulVer;
1601
1602 ulResultBufLen = sizeof(FILEFINDBUF3);
1603 ulFindCount = 1;
1604
1605 if (hdir == HDIR_CREATE) {
1606 GetStartupDir(ucDir, sizeof(ucDir));
1607 sprintf(ucName, "%s*.dll", ucDir);
1608 rc = DosFindFirst(ucName, &hdir, FILE_NORMAL, &FindBuffer,
1609 ulResultBufLen, &ulFindCount, FIL_STANDARD);
1610 }
1611 else
1612 rc = DosFindNext(hdir, &FindBuffer, ulResultBufLen, &ulFindCount);
1613
1614 if (rc == 0) {
1615 sprintf(ucName, "%s%s", ucDir, FindBuffer.achName);
1616 if (DosLoadModule(ucErr, sizeof(ucErr), ucName, &hmodRes) == 0) {
1617 if (DosQueryProcAddr
1618 (hmodRes, 0, "QueryResourceVersion", &ResVerProc) == 0
1619 && (ResVerProc(&ulVer, usLang, ucLangStr, usLangStrLen),
1620 (LOUCHAR(LOUSHORT(ulVer)) >= LASTINIVERMAJOROK
1621 && HIUCHAR(LOUSHORT(ulVer)) >= LASTINIVERMINOROK
1622 && LOUCHAR(HIUSHORT(ulVer)) >= LASTINIREVISIONOK))) {
1623 strncpy(ucDllName, ucName, usNameLen);
1624 }
1625 else
1626 *usLang = 0;
1627 DosFreeModule(hmodRes);
1628 }
1629 }
1630 else {
1631 DosFindClose(hdir);
1632 hdir = HDIR_CREATE;
1633 return 0;
1634 }
1635 return 1;
1636}
1637
1638HMODULE LoadResource(USHORT usLang, LSWDATA * plswData, BOOL bEngOk)
1639{
1640 static UCHAR ucDllName[_MAX_PATH], ucLangStr[32], ucErr[32],
1641 ucFoundDllName[_MAX_PATH];
1642 HMODULE hmodRes;
1643 USHORT usFound = 0, usResLang;
1644
1645 while (FindResDll
1646 (ucDllName, sizeof(ucDllName), &usResLang, ucLangStr,
1647 sizeof(ucLangStr)))
1648 if (usResLang != 0) {
1649 if (usResLang == usLang)
1650 usFound = 1;
1651 else if (bEngOk && usResLang == EN && usFound == 0)
1652 usFound = 2;
1653 else
1654 continue;
1655 strcpy(ucFoundDllName, ucDllName);
1656 }
1657
1658 if (usFound
1659 && DosLoadModule(ucErr, sizeof(ucErr), ucFoundDllName,
1660 &hmodRes) == 0) {
1661 if ((plswData->haccAlt =
1662 WinLoadAccelTable(plswData->hab, hmodRes, ID_ALTACCELTABLE)) == 0
1663 || (plswData->haccCtrl =
1664 WinLoadAccelTable(plswData->hab, hmodRes,
1665 ID_CTRLACCELTABLE)) == 0
1666 || (plswData->haccNoAlt =
1667 WinLoadAccelTable(plswData->hab, hmodRes,
1668 ID_NOALTACCELTABLE)) == 0) {
1669 DosFreeModule(hmodRes);
1670 return 0;
1671 }
1672 else {
1673 plswData->Settings.usLanguage = (usFound == 1 ? usLang : EN);
1674 return hmodRes;
1675 }
1676 }
1677 else
1678 return 0;
1679}
1680
1681/* this function is adapted from Roman Stangle's APM/2 package */
1682USHORT ProcessAPMOffRequest(USHORT usPowerState, USHORT usDevice)
1683{
1684 APIRET rc = NO_ERROR;
1685 ULONG ulPacketSize, ulDataSize, ulVersion[2], ulAction = 0;
1686 struct POWERRETURNCODE powerRC;
1687 struct SENDPOWEREVENT sendpowereventAPM;
1688 HFILE hfileAPM;
1689
1690 /* For /Shutdown "Request", we need Warp 4 otherwise at least a CHKDSK reliably occurs (if the request
1691 does work at all) */
1692 DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_VERSION_MINOR, ulVersion,
1693 sizeof(ulVersion));
1694 if (usPowerState == POWERSTATE_OFF) {
1695 if ((ulVersion[0] < 0x14) || (ulVersion[1] < 0x28))
1696 return 1;
1697 }
1698
1699 if (DosOpen
1700 ("\\DEV\\APM$", &hfileAPM, &ulAction, 0, FILE_NORMAL,
1701 OPEN_ACTION_OPEN_IF_EXISTS,
1702 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_SHARE_DENYNONE |
1703 OPEN_ACCESS_READWRITE, NULL) != NO_ERROR)
1704 return 2;
1705
1706 memset(&sendpowereventAPM, 0, sizeof(sendpowereventAPM));
1707 powerRC.usReturnCode = 0;
1708 /* Enable PWR MGMT function */
1709 sendpowereventAPM.usSubID = SUBID_ENABLE_POWER_MANAGEMENT;
1710 ulPacketSize = sizeof(sendpowereventAPM);
1711 ulDataSize = sizeof(powerRC);
1712 rc = DosDevIOCtl(hfileAPM, IOCTL_POWER, POWER_SENDPOWEREVENT,
1713 &sendpowereventAPM, ulPacketSize, &ulPacketSize,
1714 &powerRC, ulDataSize, &ulDataSize);
1715 if (rc != NO_ERROR || powerRC.usReturnCode != POWER_NOERROR) {
1716 DosClose(hfileAPM);
1717 return 3;
1718 }
1719
1720 DosSleep(1000); /* need a delay before the set state call for some reason */
1721 /* Invoke APM request */
1722 memset(&sendpowereventAPM, 0, sizeof(sendpowereventAPM));
1723 powerRC.usReturnCode = 0;
1724 sendpowereventAPM.usSubID = SUBID_SET_POWER_STATE;
1725 sendpowereventAPM.usData1 = usDevice;
1726 sendpowereventAPM.usData2 = usPowerState;
1727 ulPacketSize = sizeof(sendpowereventAPM);
1728 ulDataSize = sizeof(powerRC);
1729 rc = DosDevIOCtl(hfileAPM, IOCTL_POWER, POWER_SENDPOWEREVENT,
1730 &sendpowereventAPM, ulPacketSize, &ulPacketSize,
1731 &powerRC, ulDataSize, &ulDataSize);
1732 DosClose(hfileAPM);
1733
1734 if (rc != NO_ERROR || powerRC.usReturnCode != POWER_NOERROR)
1735 return 4;
1736 else
1737 return 0;
1738}
1739
1740VOID FillRectGradient(HPS hps, RECTL * rcl, RECTL * rclClip, LONG RGBDark,
1741 LONG RGBLight, BOOL bReverse)
1742{
1743 USHORT k, usRDark, usGDark, usBDark, usRLight, usGLight, usBLight,
1744 usYDiff;
1745 float fRGrad, fGGrad, fBGrad;
1746 POINTL ptl;
1747
1748 usRDark = (RGBDark & 0xFF0000) >> 16,
1749 usGDark = (RGBDark & 0xFF00) >> 8, usBDark = (RGBDark & 0xFF);
1750 usRLight = (RGBLight & 0xFF0000) >> 16,
1751 usGLight = (RGBLight & 0xFF00) >> 8, usBLight = (RGBLight & 0xFF);
1752 usYDiff = max(1, rcl->yTop - rcl->yBottom);
1753 fRGrad = (float)(usRLight - usRDark) / (float)usYDiff;
1754 fGGrad = (float)(usGLight - usGDark) / (float)usYDiff;
1755 fBGrad = (float)(usBLight - usBDark) / (float)usYDiff;
1756
1757 for (k = 0; k < rcl->yTop - rcl->yBottom; k++) {
1758 ptl.x = rcl->xLeft;
1759 ptl.y = bReverse ? rcl->yTop - k - 1 : rcl->yBottom + k;
1760 if (rclClip != NULL
1761 && (ptl.y < rclClip->yBottom || ptl.y > rclClip->yTop))
1762 continue;
1763 GpiMove(hps, &ptl);
1764 ptl.x = rcl->xRight - 1;
1765 GpiSetColor(hps,
1766 (int)(usRDark + fRGrad * k) * 65536 + (int)(usGDark +
1767 fGGrad * k) *
1768 256 + (int)(usBDark + fBGrad * k));
1769 GpiLine(hps, &ptl);
1770 }
1771}
1772
1773LONG CalcBrightCol(LONG lColor, UCHAR ucBright)
1774{
1775 UCHAR ucR, ucG, ucB, ucMax;
1776
1777 ucB = lColor & 0xFF;
1778 ucG = (lColor & 0xFF00) >> 8;
1779 ucR = (lColor & 0xFF0000) >> 16;
1780 ucMax = max(1, max(ucR, max(ucG, ucB)));
1781 return (ucBright * ucR / ucMax * 65536 + ucBright * ucG / ucMax * 256 +
1782 ucBright * ucB / ucMax);
1783}
1784
1785#if 0
1786BOOL AddPriorityToList(PID pid, SHORT sPrtyC, sPrtyD, BOOL bDesc)
1787{
1788 // Only needs to be added in PrtyDlgProc as setting page will call the dialog
1789 // Consider adding a BOOL so this could be used to edit (skip AddFilter but update ini)
1790 CHAR s[5];
1791 INT rc;
1792 QSPTRREC *pbh;
1793 QSLREC *pmi;
1794
1795 pbh = malloc(2048);
1796 if (pbh) {
1797 rc = DosQuerySysState(QS_MTE, pid, 0, 0, pbh, 2048);
1798 if (!rc) {
1799 pmi = pbh->pLibRec;
1800 if (pmi) {
1801 if (!stricmp((CHAR *) pmi->pName, "SYSINIT"))
1802 GetDosPgmName(pid, s); // probably won't work
1803 else {
1804 if (*pmi->pName)
1805 strcpy(s, (CHAR *) pmi->pName);
1806 else
1807 return 0;
1808 }
1809 p = strrchr(s, '\\');
1810 if (p)
1811 p++;
1812 else
1813 return 0;
1814 strcpy(fname, p);
1815 s[0] = utoa(sPrtyC);
1816 if (sPrtyD < 10) {
1817 s[1] = utoa(0);
1818 s[2] = utoa(sPrtyD);
1819 }
1820 else
1821 s[1] = utoa(sPrtyD);
1822 s[3] = utoa(bDesc);
1823 s[4] = '\0';
1824 rc = AddFilter(AddFilterplswData->Settings.ListPriority, fname);
1825 if (rc)
1826 PrfQueryProfileString(hini, PRF_APPNAME, fname, s);
1827 return rc;
1828 }
1829 }
1830 }
1831}
1832#endif
1833
1834static MRESULT EXPENTRY PrtyDlgProc(HWND hwnd, ULONG msg, MPARAM mp1,
1835 MPARAM mp2)
1836{
1837 static HWND hwndPrty;
1838 static PID pidPrty;
1839
1840 switch (msg) {
1841 case WM_INITDLG:{
1842 USHORT usPrty;
1843 SHORT sPrtyC, sPrtyD;
1844 UCHAR ucBuf[128], ucTitle[NAMELEN];
1845 HPS hps;
1846 HWND hwndTBar;
1847 RECTL rcl;
1848 POINTL aptl[TXTBOX_COUNT];
1849
1850 LSWDATA *plswData;
1851
1852 SetControlsFont(hwnd, TRUE);
1853
1854 plswData = (LSWDATA *) PVOIDFROMMP(mp2);
1855 hwndPrty = plswData->TaskArr[plswData->iMenuAtItem].hwnd;
1856 pidPrty = plswData->TaskArr[plswData->iMenuAtItem].pid;
1857
1858 WinQueryDlgItemText(hwnd, FID_TITLEBAR, sizeof(ucBuf), ucBuf);
1859 GetItemTitle(plswData->TaskArr[plswData->iMenuAtItem].hsw,
1860 ucTitle, sizeof(ucTitle), TRUE);
1861 strncat(ucBuf, ": ", sizeof(ucBuf) - strlen(ucTitle) - 1);
1862 strncat(ucBuf, ucTitle, sizeof(ucBuf) - strlen(ucTitle) - 1);
1863
1864 hwndTBar = WinWindowFromID(hwnd, FID_TITLEBAR);
1865 hps = WinGetPS(hwndTBar);
1866 WinQueryWindowRect(hwndTBar, &rcl);
1867 GpiQueryTextBox(hps, 1, "W", TXTBOX_COUNT, aptl);
1868
1869 MakeFitStr(hps, ucBuf, sizeof(ucBuf),
1870 rcl.xRight - rcl.xLeft - aptl[TXTBOX_BOTTOMRIGHT].x -
1871 aptl[TXTBOX_BOTTOMLEFT].x);
1872 WinReleasePS(hps);
1873
1874 WinSetDlgItemText(hwnd, FID_TITLEBAR, ucBuf);
1875
1876 DosGetPrty(PRTYS_PROCESS, &usPrty, pidPrty);
1877 sPrtyC = (usPrty + PRTYD_MAXIMUM) >> 8;
1878 sPrtyD = usPrty - (sPrtyC << 8);
1879
1880 WinCheckButton(hwnd, sPrtyC == PRTYC_IDLETIME ? RAD_IDLETIME :
1881 sPrtyC == PRTYC_REGULAR ? RAD_REGULAR :
1882 sPrtyC ==
1883 PRTYC_TIMECRITICAL ? RAD_CRITICAL : RAD_FGNDSERVER,
1884 TRUE);
1885
1886 WinSendDlgItemMsg(hwnd, SPIN_DELTA, SPBM_SETLIMITS,
1887 MPFROMLONG(PRTYD_MAXIMUM), MPFROMLONG(0));
1888 WinSendDlgItemMsg(hwnd, SPIN_DELTA, SPBM_SETTEXTLIMIT,
1889 MPFROMSHORT(3), 0);
1890 WinSendDlgItemMsg(hwnd, SPIN_DELTA, SPBM_SETCURRENTVALUE,
1891 MPFROMLONG(sPrtyD), 0);
1892
1893 break;
1894 }
1895 case WM_COMMAND:
1896 if (SHORT1FROMMP(mp1) == DID_OK) {
1897 SHORT sPrtyC, sPrtyD;
1898 BOOL bDesc;
1899
1900 WinSendDlgItemMsg(hwnd, SPIN_DELTA, SPBM_QUERYVALUE,
1901 MPFROMP(&sPrtyD), MPFROM2SHORT(0,
1902 SPBQ_ALWAYSUPDATE));
1903 if (WinQueryButtonCheckstate(hwnd, RAD_IDLETIME))
1904 sPrtyC = PRTYC_IDLETIME;
1905 else if (WinQueryButtonCheckstate(hwnd, RAD_REGULAR))
1906 sPrtyC = PRTYC_REGULAR;
1907 else if (WinQueryButtonCheckstate(hwnd, RAD_CRITICAL))
1908 sPrtyC = PRTYC_TIMECRITICAL;
1909 else
1910 sPrtyC = PRTYC_FOREGROUNDSERVER;
1911
1912 bDesc = (WinQueryButtonCheckstate(hwnd, CHK_DESCENDANTS));
1913
1914 WinPostMsg(hwndPrty,
1915 WinFindAtom(WinQuerySystemAtomTable(),
1916 LSWM_SETPRIORITY),
1917 MPFROM2SHORT(((sPrtyC << 8) +
1918 sPrtyD) | (bDesc ? 0x8000 : 0), 0),
1919 MPFROMLONG(pidPrty));
1920 }
1921 default:
1922 return WinDefDlgProc(hwnd, msg, mp1, mp2);
1923 }
1924 return 0;
1925}
1926
1927static MRESULT EXPENTRY RunDlgProc(HWND hwnd, ULONG msg, MPARAM mp1,
1928 MPARAM mp2)
1929{
1930 static HWND hwndList;
1931 static UCHAR ucFName[_MAX_PATH];
1932
1933 switch (msg) {
1934 case WM_INITDLG:{
1935 UCHAR *ucBuf;
1936 HFILE hFile;
1937 ULONG ulAction, ulcbRead, k, pos;
1938 APIRET rc;
1939
1940 SetControlsFont(hwnd, FALSE);
1941 hwndList = WinWindowFromID(hwnd, CB_RUNCOMMAND);
1942 WinSendMsg(hwndList, EM_SETTEXTLIMIT, MPFROMSHORT(_MAX_PATH), 0);
1943 GetStartupDir(ucFName, sizeof(ucFName));
1944 strncat(ucFName, HSTFILENAME,
1945 sizeof(ucFName) - strlen(ucFName) - 1);
1946 rc = DosOpen(ucFName, &hFile, &ulAction, 0,
1947 FILE_ARCHIVED | FILE_NORMAL,
1948 OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
1949 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_SHARE_DENYWRITE |
1950 OPEN_ACCESS_READWRITE, 0);
1951 if (rc == 0) {
1952 if ((ucBuf = malloc((_MAX_PATH + 2) * MAXRUNLISTHST)) == NULL) {
1953 DosClose(hFile);
1954 break;
1955 }
1956 DosRead(hFile, ucBuf, (_MAX_PATH + 2) * MAXRUNLISTHST,
1957 &ulcbRead);
1958 DosClose(hFile);
1959 for (k = 0, pos = 0; k < ulcbRead; k++)
1960 if (ucBuf[k] == '\n') {
1961 ucBuf[k] = ucBuf[k - 1] = '\0';
1962 WinSendMsg(hwndList, LM_INSERTITEM,
1963 MPFROMSHORT(LIT_END),
1964 MPFROMP(&ucBuf[pos]));
1965 pos = k + 1;
1966 }
1967 free(ucBuf);
1968 WinSendMsg(hwndList, LM_SELECTITEM, MPFROMSHORT(0),
1969 MPFROMSHORT(TRUE));
1970 }
1971
1972 break;
1973 }
1974
1975 case WM_COMMAND:
1976 switch (SHORT1FROMMP(mp1)) {
1977 case DID_OK:{
1978 UCHAR ucCmd[_MAX_PATH + 2], ucErrMsg[128],
1979 ucItemText[_MAX_PATH];
1980 USHORT k, usItemCount;
1981 SHORT sIndex;
1982 ULONG ulcbWrite, ulAction;
1983 APIRET rc;
1984 HFILE hFile;
1985 LSWDATA *plswData;
1986
1987 WinQueryWindowText(hwndList, sizeof(ucCmd), ucCmd);
1988 strcpy(ucItemText, ucCmd); //RunCommand changes ucCmd
1989
1990 if (DosGetNamedSharedMem
1991 ((PVOID *) & plswData, SHAREMEM_NAME,
1992 PAG_READ | PAG_WRITE) == 0
1993 && (rc =
1994 RunCommand(plswData, ucCmd, ucErrMsg,
1995 sizeof(ucErrMsg))) != 0) {
1996 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, ucErrMsg,
1997 PGMNAME, 0, MB_ERROR | MB_CANCEL);
1998 DosFreeMem(plswData);
1999 break;
2000 }
2001
2002 sIndex =
2003 (SHORT) WinSendMsg(hwndList, LM_SEARCHSTRING,
2004 MPFROM2SHORT(0, LIT_FIRST),
2005 MPFROMP(ucItemText));
2006 if (sIndex != LIT_NONE)
2007 WinSendMsg(hwndList, LM_DELETEITEM, MPFROMSHORT(sIndex),
2008 0);
2009 WinSendMsg(hwndList, LM_INSERTITEM, MPFROMSHORT(0),
2010 MPFROMP(ucItemText));
2011
2012 rc = DosOpen(ucFName, &hFile, &ulAction, 0,
2013 FILE_ARCHIVED | FILE_NORMAL,
2014 OPEN_ACTION_REPLACE_IF_EXISTS |
2015 OPEN_ACTION_CREATE_IF_NEW,
2016 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_SHARE_DENYWRITE |
2017 OPEN_ACCESS_READWRITE, 0);
2018 if (rc == 0) {
2019 usItemCount =
2020 LONGFROMMR(WinSendMsg
2021 (hwndList, LM_QUERYITEMCOUNT, 0, 0));
2022 for (k = 0; k < usItemCount && k < MAXRUNLISTHST; k++) {
2023 WinSendMsg(hwndList, LM_QUERYITEMTEXT,
2024 MPFROM2SHORT(k, sizeof(ucItemText)),
2025 MPFROMP(ucItemText));
2026 sprintf(ucCmd, "%s\r\n", ucItemText);
2027 DosWrite(hFile, ucCmd, strlen(ucCmd), &ulcbWrite);
2028 }
2029 DosClose(hFile);
2030 }
2031
2032 return WinDefDlgProc(hwnd, msg, mp1, mp2);
2033 }
2034 case PB_BROWSE:{
2035 static FILEDLG fild = { 0 };
2036 HWND hwndFDlg;
2037 SHORT k;
2038
2039 fild.cbSize = sizeof(FILEDLG);
2040 fild.fl = FDS_CENTER | FDS_OPEN_DIALOG;
2041 hwndFDlg = WinFileDlg(HWND_DESKTOP, hwnd, &fild);
2042 if (hwndFDlg != NULLHANDLE && (fild.lReturn == DID_OK))
2043 WinSetWindowText(hwndList,
2044 (PCHAR) PVOIDFROMMP(fild.szFullFile));
2045 for (k = strlen(fild.szFullFile); k >= 0; k--)
2046 if (fild.szFullFile[k] == '\\') {
2047 fild.szFullFile[k + 1] = '\0';
2048 strcat(fild.szFullFile, "*.EXE");
2049 break;
2050 }
2051
2052 break;
2053 }
2054 case DID_CANCEL:
2055 WinSendDlgItemMsg(hwnd, CB_RUNCOMMAND, CBM_SHOWLIST,
2056 MPFROMSHORT(FALSE), 0);
2057 return WinDefDlgProc(hwnd, msg, mp1, mp2);
2058
2059 default:
2060 return WinDefDlgProc(hwnd, msg, mp1, mp2);
2061 }
2062 break;
2063 default:
2064 return WinDefDlgProc(hwnd, msg, mp1, mp2);
2065 }
2066 return 0;
2067}
2068
2069VOID ProcessCommand(USHORT cmd, USHORT src, LSWDATA * plswData, BOOL bTaskBar,
2070 BOOL bAll)
2071{
2072 switch (cmd) {
2073 case CMD_CANCELPOPUP:
2074 case CMD_CANCELPOPUP1:
2075 plswData->usCurrItem = MAXITEMS - 1;
2076
2077 case CMD_SWITCHFROMPM:
2078 if (plswData->bNowActive) {
2079 WinStopTimer(plswData->hab, plswData->hwndPopClient, 0);
2080 WinSetWindowPos(plswData->hwndPopup, HWND_BOTTOM,
2081 POPUPWINHIDEPOSX, POPUPWINHIDEPOSY, 0, 0,
2082 SWP_MOVE | SWP_SIZE | SWP_ZORDER);
2083 ShowBubble(plswData, 0, 0, 0, -1, NULL);
2084 }
2085
2086 if (src == CMDSRC_MENU)
2087 plswData->usCurrItem = plswData->iMenuAtItem;
2088//no break here
2089 case CMD_SWITCHFROMFS:
2090 /* turn the flag off only after the window has been repositioned or
2091 our subclassed frame window function won't let do this */
2092 plswData->bNowActive = FALSE;
2093
2094 if (cmd != CMD_CANCELPOPUP && cmd != CMD_CANCELPOPUP1) {
2095 if (plswData->Settings.bDesktopMinimizes
2096 && IsDesktop(plswData->TaskArr[plswData->usCurrItem].hwnd)) {
2097 MinimizeHideAll(plswData, FALSE, 0);
2098 break; //switching to desktop is done in MinimizeHideAll function
2099 }
2100
2101 // for some weird reason WinSwitchToProgram does not always bring the window to top
2102 // showing is needed for hidden windows and won't hurt in other cases
2103 WinSetWindowPos(plswData->TaskArr[plswData->usCurrItem].hwnd,
2104 HWND_TOP, 0, 0, 0, 0, SWP_SHOW | SWP_ZORDER);
2105 }
2106
2107 /* don't switch if the popup has been cancelled and current program
2108 has been minimized or hidden or if a close window query has popped up and
2109 changed the focus to itself (and the POPUP_CANCEL has been triggered by
2110 the WM_TIMER) after the close command has been sent to a window */
2111
2112 if (cmd != CMD_CANCELPOPUP1) {
2113 if (cmd != CMD_CANCELPOPUP ||
2114 ((plswData->TaskArr[plswData->usCurrItem].
2115 fl & (SWP_HIDE | SWP_MINIMIZE)) == 0)
2116 ||
2117 ((plswData->TaskArr[plswData->usCurrItem].ulType ==
2118 PROG_FULLSCREEN
2119 || plswData->TaskArr[plswData->usCurrItem].ulType ==
2120 PROG_VDM) && plswData->Settings.bPMPopupInFS))
2121// if we want to switch to the currently active window, which may be required if it's in
2122// another virtual desktop, activate desktop first, otherwise WinSwitchToProgram will not work
2123 if (WinQueryActiveWindow(HWND_DESKTOP) ==
2124 plswData->TaskArr[plswData->usCurrItem].hwnd)
2125 WinSetActiveWindow(HWND_DESKTOP,
2126 plswData->TaskArr[plswData->usItems -
2127 1].hwnd);
2128
2129 if (plswData->TaskArr[plswData->usCurrItem].hsw != 0)
2130 WinSwitchToProgram(plswData->TaskArr[plswData->usCurrItem].
2131 hsw);
2132 else
2133 WinSetWindowPos(plswData->TaskArr[plswData->usCurrItem].hwnd,
2134 HWND_TOP, 0, 0, 0, 0,
2135 SWP_ACTIVATE | SWP_ZORDER);
2136
2137 /* this is needed to make a full screen session current */
2138 if (plswData->TaskArr[plswData->usCurrItem].ulType ==
2139 PROG_FULLSCREEN
2140 || plswData->TaskArr[plswData->usCurrItem].ulType == PROG_VDM)
2141 WinSetWindowPos(plswData->TaskArr[plswData->usCurrItem].hwnd,
2142 HWND_TOP, 0, 0, 0, 0,
2143 SWP_ZORDER | SWP_ACTIVATE);
2144 }
2145 break;
2146
2147 case CMD_SHOWSETTINGS:
2148 if (!plswData->bNowActive) {
2149 EditSettings(plswData);
2150 //WinPostMsg(plswData->hwndTaskBar, LSWM_MOUSEOVERBTN, 0, 0);
2151 }
2152 break;
2153
2154 case CMD_PRIORITY:
2155 if (src == CMDSRC_ACCELERATOR) {
2156 if (!MenuNeedsItem
2157 (plswData, plswData->usCurrItem, CMD_PRIORITY, NULL, 0,
2158 FALSE))
2159 break;
2160
2161 plswData->iMenuAtItem = plswData->usCurrItem;
2162 }
2163
2164 WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, PrtyDlgProc, plswData->hmodRes,
2165 DLG_PRTY, plswData);
2166 break;
2167
2168 case CMD_ADDFILTER:{
2169 static ENTRYNAME ucName, ucName1;
2170 USHORT k;
2171
2172 if (src == CMDSRC_ACCELERATOR)
2173 plswData->iMenuAtItem = plswData->usCurrItem;
2174
2175 GetItemTitle(plswData->TaskArr[plswData->iMenuAtItem].hsw, ucName,
2176 sizeof(ucName), FALSE);
2177 if (AddFilter
2178 (bTaskBar ? &plswData->Settings.SkipListTskBar : &plswData->
2179 Settings.SkipListPopup, ucName)) {
2180 if (WinIsWindow(plswData->hab, plswData->hwndParamDlg))
2181 WinPostMsg(plswData->hwndParamDlg, LSWM_UPDATEEXCLUDEDLG,
2182 0,
2183 MPFROMSHORT(bTaskBar ? UPDATETSKBARLIST :
2184 UPDATEPOPUPLIST));
2185
2186 for (k = 0; k < plswData->usItems; k++) { //check for entries with the same name and update popup window or taskbar
2187 GetItemTitle(plswData->TaskArr[k].hsw, ucName1,
2188 sizeof(ucName1), FALSE);
2189 if (strcmp(ucName, ucName1) == 0)
2190 WinPostMsg(bTaskBar ? plswData->
2191 hwndTaskBarClient : plswData->
2192 hwndPopClient, LSWM_SWITCHLISTCHANGED,
2193 MPFROMLONG(2),
2194 MPFROMLONG(plswData->TaskArr[k].hsw));
2195 }
2196 }
2197
2198 break;
2199 }
2200
2201 case CMD_HIDE:
2202 case CMD_SHOW:
2203 case CMD_RESTORE:
2204 case CMD_MINIMIZE:
2205 case CMD_MAXIMIZE:
2206 case CMD_MOVE:
2207 case CMD_CLOSE:
2208 case CMD_KILL:
2209 case CMD_DEATH:
2210 case CMD_CASCADE:
2211 case CMD_TILE:
2212 case CMD_CLOSEQUIT:
2213 if (bAll && cmd >= CMD_HIDE && cmd <= CMD_TILE) {
2214 SHORT k, item;
2215 LHANDLE hMte1;
2216 SWCNTRL swctl1, swctl2;
2217
2218 item =
2219 src ==
2220 CMDSRC_MENU ? plswData->iMenuAtItem : plswData->usCurrItem;
2221 hMte1 = HmteFromPID(plswData->TaskArr[item].pid);
2222 WinQuerySwitchEntry(WinQuerySwitchHandle
2223 (plswData->TaskArr[item].hwnd, 0), &swctl1);
2224
2225 for (k = plswData->usItems - 1; k >= 0; k--)
2226 if (hMte1 == HmteFromPID(plswData->TaskArr[k].pid) &&
2227 !IsDesktop(plswData->TaskArr[k].hwnd) &&
2228 (WinQuerySwitchEntry
2229 (WinQuerySwitchHandle(plswData->TaskArr[k].hwnd, 0),
2230 &swctl2), swctl2.bProgType == swctl1.bProgType)
2231 && (cmd != CMD_CLOSE
2232 || (cmd == CMD_CLOSE
2233 && WndHasControl(plswData->hab,
2234 plswData->TaskArr[k].hwnd,
2235 SC_CLOSE))))
2236 ChangeWindowPos(plswData, k, cmd);
2237 }
2238 else
2239 /* if this command comes from the keyboard use plswData->usCurrItem */
2240 ChangeWindowPos(plswData,
2241 src ==
2242 CMDSRC_MENU ? plswData->iMenuAtItem : plswData->
2243 usCurrItem, cmd);
2244 break;
2245
2246 case CMD_RUN:{
2247 static HWND hwndRunDlg = NULLHANDLE;
2248
2249 if (!WinIsWindow(plswData->hab, hwndRunDlg))
2250 hwndRunDlg =
2251 WinLoadDlg(HWND_DESKTOP, NULLHANDLE, RunDlgProc,
2252 plswData->hmodRes, DLG_RUN, NULL);
2253 if (hwndRunDlg != NULLHANDLE) {
2254 WinSetWindowPos(hwndRunDlg, HWND_TOP, 0, 0, 0, 0,
2255 SWP_SHOW | SWP_ZORDER | SWP_ACTIVATE);
2256 WinProcessDlg(hwndRunDlg);
2257 WinDestroyWindow(hwndRunDlg);
2258 //WinPostMsg(plswData->hwndTaskBar, LSWM_MOUSEOVERBTN, 0, 0);
2259 }
2260 break;
2261 }
2262
2263 case CMD_QUIT:
2264 {
2265 WinPostMsg(plswData->hwndPopup, WM_QUIT, 0, 0);
2266 break;
2267 }
2268
2269 case CMD_HELP:
2270 {
2271 if (bTaskBar) {
2272 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
2273 MPFROM2SHORT(30004, 0), MPFROMSHORT(HM_RESOURCEID));
2274 //WinPostMsg(plswData->hwndTaskBar, LSWM_MOUSEOVERBTN, 0, 0);
2275 }
2276 else
2277 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
2278 MPFROM2SHORT(30003, 0), MPFROMSHORT(HM_RESOURCEID));
2279 break;
2280 }
2281 }
2282 WinPostMsg(plswData->hwndTaskBar, LSWM_MOUSEOVERBTN,0, 0);
2283 //MPFROMHWND(plswData->TaskArr[plswData->usCurrItem].hwnd), 0);
2284}
2285
2286LHANDLE HmteFromPID(PID pid)
2287{
2288 UCHAR *pBuf;
2289 QSPTRREC *pRecHead;
2290 QSPREC *pApp;
2291 LHANDLE hmte;
2292
2293 pBuf = (char *)malloc(0x8000);
2294 memset(pBuf, 0, 0x8000);
2295 DosQuerySysState(QS_PROCESS, 0, 0, 0, (char *)pBuf, 0x8000); // Get processes
2296 for (pRecHead = (QSPTRREC *) pBuf, pApp = pRecHead->pProcRec; pApp != NULL && pApp->RecType == 1; pApp = (QSPREC *) ((pApp->pThrdRec) + pApp->cTCB)) { // While its a process record
2297 if (pApp->pid == pid) {
2298 hmte = pApp->hMte;
2299 break;
2300 }
2301 }
2302 free(pBuf);
2303 return hmte;
2304}
2305
2306PSZ GetDataFName(ULONG ObjID)
2307{
2308 UCHAR fpath[_MAX_PATH], fname[_MAX_FNAME];
2309
2310 if (!GetObjectName(ObjID, fpath, _MAX_PATH))
2311 return NULL;
2312
2313 if (EAQueryString(fpath, ".LONGNAME", sizeof(fname), fname) != 0)
2314 _splitpath(fpath, NULL, NULL, fname, NULL);
2315
2316 return strdup(fname);
2317}
2318
2319/**********************************************************************
2320* Check the EA's of a file; adapted from Hektools package
2321**********************************************************************/
2322/*
2323PFEA2LIST GetLongFName(PSZ pszName)
2324{ ULONG ulDenaCnt, ulActionTaken;
2325 APIRET rc;
2326 PFEA2LIST pFea2List;
2327 PDENA2 pDenaBlock, pDena;
2328 ULONG ulFEASize, ulGEASize, ulIndex;
2329 EAOP2 EAop2;
2330 PGEA2 pGea;
2331
2332 ulDenaCnt = (ULONG)-1;
2333 if ((pDenaBlock=calloc(1,2000))=NULL)
2334 return 1;
2335
2336 rc = DosEnumAttribute(ENUMEA_REFTYPE_PATH, pszName, 1, pDenaBlock, 2000,
2337 &ulDenaCnt, ENUMEA_LEVEL_NO_VALUE);
2338 if (rc || !ulDenaCnt) {
2339 free(pDenaBlock);
2340 return 2;
2341 }
2342
2343 // Calculate size of needed buffers
2344 ulFEASize = sizeof (ULONG); ulGEASize = sizeof (ULONG);
2345 pDena = (PDENA2)pDenaBlock;
2346 for (ulIndex = 0; ulIndex < ulDenaCnt; ulIndex++) {
2347 if (strcmpi(pDena->szName,".LONGNAME")==0) {
2348 ULONG ulFSize = sizeof (FEA2) + pDena->cbName + pDena->cbValue;
2349 ULONG ulGSize = sizeof (GEA2) + pDena->cbName;
2350 ulFSize += (4 - (ulFSize % 4)); ulFEASize += ulFSize;
2351 ulGSize += (4 - (ulGSize % 4)); ulGEASize += ulGSize;
2352 break;
2353 }
2354
2355 if (!pDena->oNextEntryOffset)
2356 break;
2357 pDena = (PDENA2) ((PBYTE)pDena + pDena->oNextEntryOffset);
2358 }
2359
2360 // Allocate needed buffers
2361 if ((EAop2.fpGEA2List = calloc(1,ulGEASize))==NULL) {
2362 free(pDenaBlock);
2363 return 2;
2364 }
2365 if ((EAop2.fpFEA2List = calloc(1,ulFEASize))==NULL) {
2366 free(EAop2.fpGEA2List); free(pDenaBlock);
2367 return 2;
2368 }
2369
2370 // Build the PGEALIST
2371 EAop2.fpGEA2List->cbList = ulGEASize; EAop2.fpFEA2List->cbList = ulFEASize;
2372
2373 pDena = (PDENA2)pDenaBlock;
2374 pGea = EAop2.fpGEA2List->list;
2375 pGea->cbName = pDena->cbName;
2376 memcpy(pGea->szName, pDena->szName, pDena->cbName + 1);
2377
2378 rc = DosQueryPathInfo(pszName, FIL_QUERYEASFROMLIST, (PBYTE) &EAop2, sizeof EAop2);
2379
2380 if (rc) {
2381 MessageBox(TITLE, "DosQueryXXXXInfo on %s :\n %s", pszName, GetOS2Error(rc));
2382 free(EAop2.fpGEA2List); free(EAop2.fpFEA2List); free(bDena);
2383 return NULL;
2384 }
2385
2386 free(EAop2.fpGEA2List);
2387 return EAop2.fpFEA2List;
2388}
2389*/
Note: See TracBrowser for help on using the repository browser.