1 #include <process.h>
2 #define INCL_DOS
3 #define INCL_DOSERRORS
4 #define INCL_DOSNLS
5 #define INCL_WINSWITCHLIST
6 #define INCL_WINWINDOWMGR
7 #define INCL_WININPUT
8 #define INCL_VIO
9 #define INCL_KBD
10 #define INCL_WINCLIPBOARD
11 #define INCL_WINATOM
12 #include <os2.h>
13 
14 #include "EXTERN.h"
15 #include "perl.h"
16 #include "XSUB.h"
17 
18 static unsigned long
constant(char * name,int arg)19 constant(char *name, int arg)
20 {
21     errno = 0;
22     if (name[0] == 'P' && name[1] == '_') {
23 	if (strEQ(name, "P_BACKGROUND"))
24 #ifdef P_BACKGROUND
25 	    return P_BACKGROUND;
26 #else
27 	    goto not_there;
28 #endif
29 	if (strEQ(name, "P_DEBUG"))
30 #ifdef P_DEBUG
31 	    return P_DEBUG;
32 #else
33 	    goto not_there;
34 #endif
35 	if (strEQ(name, "P_DEFAULT"))
36 #ifdef P_DEFAULT
37 	    return P_DEFAULT;
38 #else
39 	    goto not_there;
40 #endif
41 	if (strEQ(name, "P_DETACH"))
42 #ifdef P_DETACH
43 	    return P_DETACH;
44 #else
45 	    goto not_there;
46 #endif
47 	if (strEQ(name, "P_FOREGROUND"))
48 #ifdef P_FOREGROUND
49 	    return P_FOREGROUND;
50 #else
51 	    goto not_there;
52 #endif
53 	if (strEQ(name, "P_FULLSCREEN"))
54 #ifdef P_FULLSCREEN
55 	    return P_FULLSCREEN;
56 #else
57 	    goto not_there;
58 #endif
59 	if (strEQ(name, "P_MAXIMIZE"))
60 #ifdef P_MAXIMIZE
61 	    return P_MAXIMIZE;
62 #else
63 	    goto not_there;
64 #endif
65 	if (strEQ(name, "P_MINIMIZE"))
66 #ifdef P_MINIMIZE
67 	    return P_MINIMIZE;
68 #else
69 	    goto not_there;
70 #endif
71 	if (strEQ(name, "P_NOCLOSE"))
72 #ifdef P_NOCLOSE
73 	    return P_NOCLOSE;
74 #else
75 	    goto not_there;
76 #endif
77 	if (strEQ(name, "P_NOSESSION"))
78 #ifdef P_NOSESSION
79 	    return P_NOSESSION;
80 #else
81 	    goto not_there;
82 #endif
83 	if (strEQ(name, "P_NOWAIT"))
84 #ifdef P_NOWAIT
85 	    return P_NOWAIT;
86 #else
87 	    goto not_there;
88 #endif
89 	if (strEQ(name, "P_OVERLAY"))
90 #ifdef P_OVERLAY
91 	    return P_OVERLAY;
92 #else
93 	    goto not_there;
94 #endif
95 	if (strEQ(name, "P_PM"))
96 #ifdef P_PM
97 	    return P_PM;
98 #else
99 	    goto not_there;
100 #endif
101 	if (strEQ(name, "P_QUOTE"))
102 #ifdef P_QUOTE
103 	    return P_QUOTE;
104 #else
105 	    goto not_there;
106 #endif
107 	if (strEQ(name, "P_SESSION"))
108 #ifdef P_SESSION
109 	    return P_SESSION;
110 #else
111 	    goto not_there;
112 #endif
113 	if (strEQ(name, "P_TILDE"))
114 #ifdef P_TILDE
115 	    return P_TILDE;
116 #else
117 	    goto not_there;
118 #endif
119 	if (strEQ(name, "P_UNRELATED"))
120 #ifdef P_UNRELATED
121 	    return P_UNRELATED;
122 #else
123 	    goto not_there;
124 #endif
125 	if (strEQ(name, "P_WAIT"))
126 #ifdef P_WAIT
127 	    return P_WAIT;
128 #else
129 	    goto not_there;
130 #endif
131 	if (strEQ(name, "P_WINDOWED"))
132 #ifdef P_WINDOWED
133 	    return P_WINDOWED;
134 #else
135 	    goto not_there;
136 #endif
137     } else if (name[0] == 'T' && name[1] == '_') {
138 	if (strEQ(name, "FAPPTYP_NOTSPEC"))
139 #ifdef FAPPTYP_NOTSPEC
140 	    return FAPPTYP_NOTSPEC;
141 #else
142 	    goto not_there;
143 #endif
144 	if (strEQ(name, "T_NOTWINDOWCOMPAT"))
145 #ifdef FAPPTYP_NOTWINDOWCOMPAT
146 	    return FAPPTYP_NOTWINDOWCOMPAT;
147 #else
148 	    goto not_there;
149 #endif
150 	if (strEQ(name, "T_WINDOWCOMPAT"))
151 #ifdef FAPPTYP_WINDOWCOMPAT
152 	    return FAPPTYP_WINDOWCOMPAT;
153 #else
154 	    goto not_there;
155 #endif
156 	if (strEQ(name, "T_WINDOWAPI"))
157 #ifdef FAPPTYP_WINDOWAPI
158 	    return FAPPTYP_WINDOWAPI;
159 #else
160 	    goto not_there;
161 #endif
162 	if (strEQ(name, "T_BOUND"))
163 #ifdef FAPPTYP_BOUND
164 	    return FAPPTYP_BOUND;
165 #else
166 	    goto not_there;
167 #endif
168 	if (strEQ(name, "T_DLL"))
169 #ifdef FAPPTYP_DLL
170 	    return FAPPTYP_DLL;
171 #else
172 	    goto not_there;
173 #endif
174 	if (strEQ(name, "T_DOS"))
175 #ifdef FAPPTYP_DOS
176 	    return FAPPTYP_DOS;
177 #else
178 	    goto not_there;
179 #endif
180 	if (strEQ(name, "T_PHYSDRV"))
181 #ifdef FAPPTYP_PHYSDRV
182 	    return FAPPTYP_PHYSDRV;
183 #else
184 	    goto not_there;
185 #endif
186 	if (strEQ(name, "T_VIRTDRV"))
187 #ifdef FAPPTYP_VIRTDRV
188 	    return FAPPTYP_VIRTDRV;
189 #else
190 	    goto not_there;
191 #endif
192 	if (strEQ(name, "T_PROTDLL"))
193 #ifdef FAPPTYP_PROTDLL
194 	    return FAPPTYP_PROTDLL;
195 #else
196 	    goto not_there;
197 #endif
198 	if (strEQ(name, "T_32BIT"))
199 #ifdef FAPPTYP_32BIT
200 	    return FAPPTYP_32BIT;
201 #else
202 	    goto not_there;
203 #endif
204     }
205 
206     errno = EINVAL;
207     return 0;
208 
209 not_there:
210     errno = ENOENT;
211     return 0;
212 }
213 
214 const char* const ptypes[] = { "FS", "DOS", "VIO", "PM", "DETACH" };
215 
216 static char *
my_type()217 my_type()
218 {
219     int rc;
220     TIB *tib;
221     PIB *pib;
222 
223     if (!(_emx_env & 0x200)) return (char*)ptypes[1]; /* not OS/2. */
224     if (CheckOSError(DosGetInfoBlocks(&tib, &pib)))
225 	return NULL;
226 
227     return (pib->pib_ultype <= 4 ? (char*)ptypes[pib->pib_ultype] : "UNKNOWN");
228 }
229 
230 static ULONG
file_type(char * path)231 file_type(char *path)
232 {
233     int rc;
234     ULONG apptype;
235 
236     if (!(_emx_env & 0x200))
237 	croak("file_type not implemented on DOS"); /* not OS/2. */
238     if (CheckOSError(DosQueryAppType(path, &apptype))) {
239 #if 0
240 	if (rc == ERROR_INVALID_EXE_SIGNATURE)
241 	    croak("Invalid EXE signature");
242 	else if (rc == ERROR_EXE_MARKED_INVALID) {
243 	    croak("EXE marked invalid");
244 	}
245 #endif
246 	croak_with_os2error("DosQueryAppType");
247     }
248 
249     return apptype;
250 }
251 
252 /* These use different type of wrapper.  Good to check wrappers. ;-)  */
253 /* XXXX This assumes DOS type return type, without SEVERITY?! */
254 DeclFuncByORD(HSWITCH, myWinQuerySwitchHandle,  ORD_WinQuerySwitchHandle,
255 		  (HWND hwnd, PID pid), (hwnd, pid))
256 DeclFuncByORD(ULONG, myWinQuerySwitchEntry,  ORD_WinQuerySwitchEntry,
257 		  (HSWITCH hsw, PSWCNTRL pswctl), (hsw, pswctl))
258 DeclFuncByORD(ULONG, myWinSetWindowText,  ORD_WinSetWindowText,
259 		  (HWND hwnd, char* text), (hwnd, text))
260 DeclFuncByORD(BOOL, myWinQueryWindowProcess,  ORD_WinQueryWindowProcess,
261 		  (HWND hwnd, PPID ppid, PTID ptid), (hwnd, ppid, ptid))
262 DeclFuncByORD(ULONG, XmyWinSwitchToProgram,  ORD_WinSwitchToProgram,
263 		  (HSWITCH hsw), (hsw))
264 #define myWinSwitchToProgram(hsw) (!CheckOSError(XmyWinSwitchToProgram(hsw)))
265 
266 
267 /* These function croak if the return value is 0. */
268 DeclWinFunc_CACHE(HWND, QueryWindow, (HWND hwnd, LONG cmd), (hwnd, cmd))
269 DeclWinFunc_CACHE(BOOL, QueryWindowPos, (HWND hwnd, PSWP pswp),
270 		  (hwnd, pswp))
271 DeclWinFunc_CACHE(LONG, QueryWindowText,
272 		  (HWND hwnd, LONG cchBufferMax, PCH pchBuffer),
273 		  (hwnd, cchBufferMax, pchBuffer))
274 DeclWinFunc_CACHE(LONG, QueryClassName, (HWND hwnd, LONG cchMax, PCH pch),
275 		  (hwnd, cchMax, pch))
276 DeclWinFunc_CACHE(HWND, QueryFocus, (HWND hwndDesktop), (hwndDesktop))
277 DeclWinFunc_CACHE(BOOL, SetFocus, (HWND hwndDesktop, HWND hwndFocus),
278 		  (hwndDesktop, hwndFocus))
279 DeclWinFunc_CACHE(BOOL, ShowWindow, (HWND hwnd, BOOL fShow), (hwnd, fShow))
280 DeclWinFunc_CACHE(BOOL, EnableWindow, (HWND hwnd, BOOL fEnable),
281 		      (hwnd, fEnable))
282 DeclWinFunc_CACHE(BOOL, SetWindowPos,
283 		  (HWND hwnd, HWND hwndInsertBehind, LONG x, LONG y,
284 		   LONG cx, LONG cy, ULONG fl),
285 		  (hwnd, hwndInsertBehind, x, y, cx, cy, fl))
286 DeclWinFunc_CACHE(HENUM, BeginEnumWindows, (HWND hwnd), (hwnd))
287 DeclWinFunc_CACHE(BOOL, EndEnumWindows, (HENUM henum), (henum))
288 DeclWinFunc_CACHE(BOOL, EnableWindowUpdate, (HWND hwnd, BOOL fEnable),
289 		  (hwnd, fEnable))
290 DeclWinFunc_CACHE(BOOL, SetWindowBits,
291 		  (HWND hwnd, LONG index, ULONG flData, ULONG flMask),
292 		  (hwnd, index, flData, flMask))
293 DeclWinFunc_CACHE(BOOL, SetWindowPtr, (HWND hwnd, LONG index, PVOID p),
294 		  (hwnd, index, p))
295 DeclWinFunc_CACHE(BOOL, SetWindowULong, (HWND hwnd, LONG index, ULONG ul),
296 		  (hwnd, index, ul))
297 DeclWinFunc_CACHE(BOOL, SetWindowUShort, (HWND hwnd, LONG index, USHORT us),
298 		  (hwnd, index, us))
299 DeclWinFunc_CACHE(HWND, IsChild, (HWND hwnd, HWND hwndParent),
300 		  (hwnd, hwndParent))
301 DeclWinFunc_CACHE(HWND, WindowFromId, (HWND hwnd, ULONG id), (hwnd, id))
302 DeclWinFunc_CACHE(HWND, EnumDlgItem, (HWND hwndDlg, HWND hwnd, ULONG code),
303 		  (hwndDlg, hwnd, code))
304 DeclWinFunc_CACHE(HWND, QueryDesktopWindow, (HAB hab, HDC hdc), (hab, hdc));
305 DeclWinFunc_CACHE(BOOL, SetActiveWindow, (HWND hwndDesktop, HWND hwnd),
306 		  (hwndDesktop, hwnd));
307 DeclWinFunc_CACHE(BOOL, QueryActiveDesktopPathname, (PSZ pszPathName, ULONG ulSize),
308 		  (pszPathName, ulSize));
309 DeclWinFunc_CACHE(BOOL, InvalidateRect,
310 		  (HWND hwnd, /*RECTL*/ char *prcl, BOOL fIncludeChildren),
311 		  (hwnd, prcl, fIncludeChildren));
312 DeclWinFunc_CACHE(BOOL, CreateFrameControls,
313 		  (HWND hwndFrame, /*PFRAMECDATA*/ char* pfcdata, PCSZ pszTitle),
314 		  (hwndFrame, pfcdata, pszTitle));
315 DeclWinFunc_CACHE(BOOL, OpenClipbrd, (HAB hab), (hab));
316 DeclWinFunc_CACHE(BOOL, EmptyClipbrd, (HAB hab), (hab));
317 DeclWinFunc_CACHE(BOOL, CloseClipbrd, (HAB hab), (hab));
318 DeclWinFunc_CACHE(HWND, QueryClipbrdViewer, (HAB hab), (hab));
319 DeclWinFunc_CACHE(HWND, QueryClipbrdOwner, (HAB hab), (hab));
320 DeclWinFunc_CACHE(BOOL, QueryClipbrdFmtInfo, (HAB hab, ULONG fmt, PULONG prgfFmtInfo), (hab, fmt, prgfFmtInfo));
321 DeclWinFunc_CACHE(ULONG, QueryClipbrdData, (HAB hab, ULONG fmt), (hab, fmt));
322 DeclWinFunc_CACHE(HWND, SetClipbrdViewer, (HAB hab, HWND hwnd), (hab, hwnd));
323 DeclWinFunc_CACHE(HWND, SetClipbrdOwner, (HAB hab, HWND hwnd), (hab, hwnd));
324 DeclWinFunc_CACHE(ULONG, EnumClipbrdFmts, (HAB hab, ULONG fmt), (hab, fmt));
325 DeclWinFunc_CACHE(ATOM, AddAtom, (HATOMTBL hAtomTbl, PCSZ pszAtomName),
326 		  (hAtomTbl, pszAtomName));
327 DeclWinFunc_CACHE(ATOM, FindAtom, (HATOMTBL hAtomTbl, PCSZ pszAtomName),
328 		  (hAtomTbl, pszAtomName));
329 DeclWinFunc_CACHE(ATOM, DeleteAtom, (HATOMTBL hAtomTbl, PCSZ pszAtomName),
330 		  (hAtomTbl, pszAtomName));
331 DeclWinFunc_CACHE(ULONG, QueryAtomUsage, (HATOMTBL hAtomTbl, ATOM atom),
332 		  (hAtomTbl, atom));
333 DeclWinFunc_CACHE(ULONG, QueryAtomLength, (HATOMTBL hAtomTbl, ATOM atom),
334 		  (hAtomTbl, atom));
335 DeclWinFunc_CACHE(ULONG, QueryAtomName,
336 		  (HATOMTBL hAtomTbl, ATOM atom, PSZ pchBuffer, ULONG cchBufferMax),
337 		  (hAtomTbl, atom, pchBuffer, cchBufferMax));
338 DeclWinFunc_CACHE(HATOMTBL, QuerySystemAtomTable, (VOID), ());
339 DeclWinFunc_CACHE(HATOMTBL, CreateAtomTable, (ULONG initial, ULONG buckets),
340 		  (initial, buckets));
341 DeclWinFunc_CACHE(HATOMTBL, DestroyAtomTable, (HATOMTBL hAtomTbl), (hAtomTbl));
342 DeclWinFunc_CACHE(ULONG, MessageBox, (HWND hwndParent, HWND hwndOwner, PCSZ pszText, PCSZ pszCaption, ULONG idWindow, ULONG flStyle), (hwndParent, hwndOwner, pszText, pszCaption, idWindow, flStyle));
343 DeclWinFunc_CACHE(ULONG, MessageBox2,
344 		  (HWND hwndParent, HWND hwndOwner, PCSZ pszText,
345 		   PCSZ pszCaption, ULONG idWindow, PMB2INFO pmb2info),
346 		  (hwndParent, hwndOwner, pszText, pszCaption, idWindow, pmb2info));
347 DeclWinFunc_CACHE(HPOINTER, LoadPointer,
348 		  (HWND hwndDesktop, HMODULE hmod, ULONG idres),
349 		  (hwndDesktop, hmod, idres));
350 DeclWinFunc_CACHE(HPOINTER, QuerySysPointer,
351 		  (HWND hwndDesktop, LONG lId, BOOL fCopy),
352 		  (hwndDesktop, lId, fCopy));
353 DeclWinFunc_CACHE(BOOL, Alarm, (HWND hwndDesktop, ULONG rgfType), (hwndDesktop, rgfType));
354 DeclWinFunc_CACHE(BOOL, FlashWindow, (HWND hwndFrame, BOOL fFlash), (hwndFrame, fFlash));
355 
356 
357 /* These functions do not croak on error */
358 DeclWinFunc_CACHE_survive(BOOL, SetClipbrdData,
359 			  (HAB hab, ULONG ulData, ULONG fmt, ULONG rgfFmtInfo),
360 			  (hab, ulData, fmt, rgfFmtInfo));
361 
362 #define get_InvalidateRect	InvalidateRect
363 #define get_CreateFrameControls	CreateFrameControls
364 
365 /* These functions may return 0 on success; check $^E/Perl_rc on res==0: */
366 DeclWinFunc_CACHE_resetError(PVOID, QueryWindowPtr, (HWND hwnd, LONG index),
367 			     (hwnd, index))
368 DeclWinFunc_CACHE_resetError(ULONG, QueryWindowULong, (HWND hwnd, LONG index),
369 			     (hwnd, index))
370 DeclWinFunc_CACHE_resetError(SHORT, QueryWindowUShort, (HWND hwnd, LONG index),
371 			     (hwnd, index))
372 DeclWinFunc_CACHE_resetError(LONG,  QueryWindowTextLength, (HWND hwnd), (hwnd))
373 DeclWinFunc_CACHE_resetError(HWND,  QueryActiveWindow, (HWND hwnd), (hwnd))
374 DeclWinFunc_CACHE_resetError(BOOL, PostMsg,
375 			     (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2),
376 			     (hwnd, msg, mp1, mp2))
377 DeclWinFunc_CACHE_resetError(HWND, GetNextWindow, (HENUM henum), (henum))
378 DeclWinFunc_CACHE_resetError(BOOL, IsWindowEnabled, (HWND hwnd), (hwnd))
379 DeclWinFunc_CACHE_resetError(BOOL, IsWindowVisible, (HWND hwnd), (hwnd))
380 DeclWinFunc_CACHE_resetError(BOOL, IsWindowShowing, (HWND hwnd), (hwnd))
381 
382 /* No die()ing on error */
383 DeclWinFunc_CACHE_survive(BOOL, IsWindow, (HAB hab, HWND hwnd), (hab, hwnd))
384 
385 /* These functions are called frow complicated wrappers: */
386 ULONG (*pWinQuerySwitchList) (HAB hab, PSWBLOCK pswblk, ULONG usDataLength);
387 ULONG (*pWinChangeSwitchEntry) (HSWITCH hsw, __const__ SWCNTRL *pswctl);
388 HWND (*pWinWindowFromPoint)(HWND hwnd, __const__ POINTL *pptl, BOOL fChildren);
389 
390 
391 /* These functions have different names/signatures than what is
392    declared above */
393 #define QueryFocusWindow QueryFocus
394 #define FocusWindow_set(hwndFocus, hwndDesktop) SetFocus(hwndDesktop, hwndFocus)
395 #define WindowPos_set(hwnd, x, y, fl, cx, cy, hwndInsertBehind)	\
396 	SetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl)
397 #define myWinQueryWindowPtr(hwnd, i)	((ULONG)QueryWindowPtr(hwnd, i))
398 #define _ClipbrdData_set SetClipbrdData
399 #define ClipbrdOwner_set SetClipbrdOwner
400 #define ClipbrdViewer_set SetClipbrdViewer
401 
402 int
WindowText_set(HWND hwnd,char * text)403 WindowText_set(HWND hwnd, char* text)
404 {
405    return !CheckWinError(myWinSetWindowText(hwnd, text));
406 }
407 
408 SV *
myQueryWindowText(HWND hwnd)409 myQueryWindowText(HWND hwnd)
410 {
411     LONG l = QueryWindowTextLength(hwnd), len;
412     SV *sv;
413     STRLEN n_a;
414 
415     if (l == 0) {
416 	if (Perl_rc)		/* Last error */
417 	    return &PL_sv_undef;
418 	return &PL_sv_no;
419     }
420     sv = newSVpvn("", 0);
421     SvGROW(sv, l + 1);
422     len = QueryWindowText(hwnd, l + 1, SvPV_force(sv, n_a));
423     if (len != l) {
424 	Safefree(sv);
425 	croak("WinQueryWindowText() uncompatible with WinQueryWindowTextLength()");
426     }
427     SvCUR_set(sv, l);
428     return sv;
429 }
430 
431 SWP
QueryWindowSWP_(HWND hwnd)432 QueryWindowSWP_(HWND hwnd)
433 {
434     SWP swp;
435 
436     if (!QueryWindowPos(hwnd, &swp))
437 	croak("WinQueryWindowPos() error");
438     return swp;
439 }
440 
441 SV *
QueryWindowSWP(HWND hwnd)442 QueryWindowSWP(HWND hwnd)
443 {
444     SWP swp = QueryWindowSWP_(hwnd);
445 
446     return newSVpvn((char*)&swp, sizeof(swp));
447 }
448 
449 SV *
myQueryClassName(HWND hwnd)450 myQueryClassName(HWND hwnd)
451 {
452     SV *sv = newSVpvn("",0);
453     STRLEN l = 46, len = 0, n_a;
454 
455     while (l + 1 >= len) {
456 	if (len)
457 	    len = 2*len + 10;		/* Grow quick */
458 	else
459 	    len = l + 2;
460 	SvGROW(sv, len);
461 	l = QueryClassName(hwnd, len, SvPV_force(sv, n_a));
462     }
463     SvCUR_set(sv, l);
464     return sv;
465 }
466 
467 HWND
WindowFromPoint(long x,long y,HWND hwnd,BOOL fChildren)468 WindowFromPoint(long x, long y, HWND hwnd, BOOL fChildren)
469 {
470     POINTL ppl;
471 
472     ppl.x = x; ppl.y = y;
473     if (!pWinWindowFromPoint)
474 	AssignFuncPByORD(pWinWindowFromPoint, ORD_WinWindowFromPoint);
475     return SaveWinError(pWinWindowFromPoint(hwnd, &ppl, fChildren));
476 }
477 
478 static HSWITCH
switch_of(HWND hwnd,PID pid)479 switch_of(HWND hwnd, PID pid)
480 {
481 	 HSWITCH hSwitch;
482 
483 	 if (!(_emx_env & 0x200))
484 	     croak("switch_entry not implemented on DOS"); /* not OS/2. */
485 	 if (CheckWinError(hSwitch =
486 			   myWinQuerySwitchHandle(hwnd, pid)))
487 	     croak_with_os2error("WinQuerySwitchHandle");
488 	 return hSwitch;
489 }
490 
491 
492 static void
fill_swentry(SWENTRY * swentryp,HWND hwnd,PID pid)493 fill_swentry(SWENTRY *swentryp, HWND hwnd, PID pid)
494 {
495 	 int rc;
496 	 HSWITCH hSwitch = switch_of(hwnd, pid);
497 
498 	 swentryp->hswitch = hSwitch;
499 	 if (CheckOSError(myWinQuerySwitchEntry(hSwitch, &swentryp->swctl)))
500 	     croak_with_os2error("WinQuerySwitchEntry");
501 }
502 
503 static void
fill_swentry_default(SWENTRY * swentryp)504 fill_swentry_default(SWENTRY *swentryp)
505 {
506 	fill_swentry(swentryp, NULLHANDLE, getpid());
507 }
508 
509 static SV*
myWinQueryActiveDesktopPathname()510 myWinQueryActiveDesktopPathname()
511 {
512     SV *buf = newSVpv("",0);
513     STRLEN n_a;
514 
515     SvGROW(buf, MAXPATHLEN);
516     QueryActiveDesktopPathname(SvPV(buf,n_a), MAXPATHLEN);
517     SvCUR_set(buf, strlen(SvPV(buf, n_a)));
518     return buf;
519 }
520 
521 SV *
myWinQueryAtomName(ATOM atom,HATOMTBL hAtomTbl)522 myWinQueryAtomName(ATOM atom, HATOMTBL hAtomTbl)
523 {
524     ULONG len = QueryAtomLength(hAtomTbl, atom);
525     SV *sv = newSVpvn("",0);
526     STRLEN n_a;
527 
528     SvGROW(sv, len + 1);
529     QueryAtomName(hAtomTbl, atom, SvPV(sv, n_a), len);
530     SvCUR_set(sv, len);
531     *SvEND(sv) = 0;
532     return sv;
533 }
534 
535 #define myWinQueryClipbrdFmtInfo	QueryClipbrdFmtInfo
536 
537 /* Put data into shared memory, then call SetClipbrdData */
538 void
ClipbrdData_set(SV * sv,int convert_nl,unsigned long fmt,unsigned long rgfFmtInfo,HAB hab)539 ClipbrdData_set(SV *sv, int convert_nl, unsigned long fmt, unsigned long rgfFmtInfo, HAB hab)
540 {
541     STRLEN len;
542     char *buf = SvPV_force(sv, len);
543     char *pByte = 0, *s = buf, c;
544     ULONG nls = 0, rc;
545 
546     if (convert_nl) {
547 	while ((c = *s++)) {
548 	    if (c == '\r' && *s == '\n')
549 		s++;
550 	    else if (c == '\n')
551 		nls++;
552 	}
553     }
554 
555     if (CheckOSError(DosAllocSharedMem((PPVOID)&pByte, 0, len + nls + 1,
556 				       PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE | OBJ_GETTABLE)))
557 	croak_with_os2error("ClipbrdData_set: DosAllocSharedMem error");
558 
559     if (!nls)
560 	memcpy(pByte, buf, len + 1);
561     else {
562 	char *t = pByte, *e = buf + len;
563 
564 	while (buf < e) {
565 	    c = *t++ = *buf++;
566 	    if (c == '\n' && (t == pByte + 1 || t[-2] != '\r'))
567 		t[-1] = '\r', *t++ = '\n';
568 	}
569     }
570 
571     if (!SetClipbrdData(hab, (ULONG)pByte, fmt, rgfFmtInfo)) {
572 	DosFreeMem((PPVOID)&pByte);
573 	croak_with_os2error("ClipbrdData_set: WinSetClipbrdData error");
574     }
575 }
576 
577 #if 0
578 
579 ULONG
580 myWinMessageBox(HWND hwndParent, HWND hwndOwner, PCSZ pszText, PCSZ pszCaption, ULONG idWindow, ULONG flStyle)
581 {
582     ULONG rc = MessageBox(hwndParent, hwndOwner, pszText, pszCaption,
583 			  idWindow, flStyle);
584 
585     if (rc == MBID_ERROR)
586 	rc = 0;
587     if (CheckWinError(rc))
588 	croak_with_os2error("MessageBox");
589     return rc;
590 }
591 
592 ULONG
593 myWinMessageBox2(HWND hwndParent, HWND hwndOwner, PCSZ pszText,
594 		   PCSZ pszCaption, ULONG idWindow, PMB2INFO pmb2info)
595 {
596     ULONG rc = MessageBox2(hwndParent, hwndOwner, pszText, pszCaption, idWindow, pmb2info);
597 
598     if (rc == MBID_ERROR)
599 	rc = 0;
600     if (CheckWinError(rc))
601 	croak_with_os2error("MessageBox2");
602     return rc;
603 }
604 #endif
605 
606 /* static ULONG (* APIENTRY16 pDosSmSetTitle)(ULONG, PSZ); */
607 ULONG _THUNK_FUNCTION(DosSmSetTitle)(ULONG, PSZ);
608 
609 #if 0			/*  Does not work.  */
610 static ULONG (*pDosSmSetTitle)(ULONG, PSZ);
611 
612 static void
613 sesmgr_title_set(char *s)
614 {
615     SWENTRY swentry;
616     static HMODULE hdosc = 0;
617     BYTE buf[20];
618     long rc;
619 
620     fill_swentry_default(&swentry);
621     if (!pDosSmSetTitle || !hdosc) {
622 	if (CheckOSError(DosLoadModule(buf, sizeof buf, "sesmgr", &hdosc)))
623 	    croak("Cannot load SESMGR: no `%s'", buf);
624 	if (CheckOSError(DosQueryProcAddr(hdosc, 0, "DOSSMSETTITLE",
625 					  (PFN*)&pDosSmSetTitle)))
626 	    croak("Cannot load SESMGR.DOSSMSETTITLE, err=%ld", rc);
627     }
628 /*     (pDosSmSetTitle)(swcntrl.idSession,s); */
629     rc = ((USHORT)
630           (_THUNK_PROLOG (2+4);
631            _THUNK_SHORT (swcntrl.idSession);
632            _THUNK_FLAT (s);
633            _THUNK_CALLI (*pDosSmSetTitle)));
634     if (CheckOSError(rc))
635 	warn("*DOSSMSETTITLE: err=%ld, ses=%ld, addr=%x, *paddr=%x",
636 	     rc, swcntrl.idSession, &_THUNK_FUNCTION(DosSmSetTitle),
637 	     pDosSmSetTitle);
638 }
639 
640 #else /* !0 */
641 
642 static bool
sesmgr_title_set(char * s)643 sesmgr_title_set(char *s)
644 {
645     SWENTRY swentry;
646     long rc;
647 
648     fill_swentry_default(&swentry);
649     rc = ((USHORT)
650           (_THUNK_PROLOG (2+4);
651            _THUNK_SHORT (swentry.swctl.idSession);
652            _THUNK_FLAT (s);
653            _THUNK_CALL (DosSmSetTitle)));
654 #if 0
655     if (CheckOSError(rc))
656 	warn("DOSSMSETTITLE: err=%ld, ses=%ld, addr=%x",
657 	     rc, swcntrl.idSession, _THUNK_FUNCTION(DosSmSetTitle));
658 #endif
659     return !CheckOSError(rc);
660 }
661 #endif /* !0 */
662 
663 #if 0			/*  Does not work.  */
664 USHORT _THUNK_FUNCTION(Win16SetTitle) ();
665 
666 static void
667 set_title2(char *s)
668 {
669     long rc;
670 
671     rc = ((USHORT)
672           (_THUNK_PROLOG (4);
673            _THUNK_FLAT (s);
674            _THUNK_CALL (Win16SetTitle)));
675     if (CheckWinError(rc))
676 	warn("Win16SetTitle: err=%ld", rc);
677 }
678 #endif
679 
680 SV *
process_swentry(unsigned long pid,HWND hwnd)681 process_swentry(unsigned long pid, HWND hwnd)
682 {
683     SWENTRY swentry;
684 
685     if (!(_emx_env & 0x200))
686 	     croak("process_swentry not implemented on DOS"); /* not OS/2. */
687     fill_swentry(&swentry, hwnd, pid);
688     return newSVpvn((char*)&swentry, sizeof(swentry));
689 }
690 
691 SV *
swentries_list()692 swentries_list()
693 {
694     int num, n = 0;
695     STRLEN n_a;
696     PSWBLOCK pswblk;
697     SV *sv = newSVpvn("",0);
698 
699     if (!(_emx_env & 0x200))
700 	     croak("swentries_list not implemented on DOS"); /* not OS/2. */
701     if (!pWinQuerySwitchList)
702 	AssignFuncPByORD(pWinQuerySwitchList, ORD_WinQuerySwitchList);
703     num = pWinQuerySwitchList(0, NULL, 0);	/* HAB is not required */
704     if (!num)
705 	croak("(Unknown) error during WinQuerySwitchList()");
706     /* Allow one extra entry to allow overflow detection (may happen
707 	if the list has been changed). */
708     while (num > n) {
709 	if (n == 0)
710 	    n = num + 1;
711 	else
712 	    n = 2*num + 10;			/* Enlarge quickly */
713 	SvGROW(sv, sizeof(ULONG) + sizeof(SWENTRY) * n + 1);
714 	pswblk = (PSWBLOCK) SvPV_force(sv, n_a);
715 	num = pWinQuerySwitchList(0, pswblk, SvLEN(sv));
716     }
717     SvCUR_set(sv, sizeof(ULONG) + sizeof(SWENTRY) * num);
718     *SvEND(sv) = 0;
719     return sv;
720 }
721 
722 SWENTRY
swentry(char * title,HWND sw_hwnd,HWND icon_hwnd,HPROGRAM owner_phandle,PID owner_pid,ULONG owner_sid,ULONG visible,ULONG nonswitchable,ULONG jumpable,ULONG ptype,HSWITCH sw_entry)723 swentry( char *title, HWND sw_hwnd, HWND icon_hwnd, HPROGRAM owner_phandle,
724 	 PID owner_pid, ULONG owner_sid, ULONG visible, ULONG nonswitchable,
725 	 ULONG jumpable, ULONG ptype, HSWITCH sw_entry)
726 {
727   SWENTRY e;
728 
729   strncpy(e.swctl.szSwtitle, title, MAXNAMEL);
730   e.swctl.szSwtitle[60] = 0;
731   e.swctl.hwnd = sw_hwnd;
732   e.swctl.hwndIcon = icon_hwnd;
733   e.swctl.hprog = owner_phandle;
734   e.swctl.idProcess = owner_pid;
735   e.swctl.idSession = owner_sid;
736   e.swctl.uchVisibility = ((visible ? SWL_VISIBLE : SWL_INVISIBLE)
737 			   | (nonswitchable ? SWL_GRAYED : 0));
738   e.swctl.fbJump = (jumpable ? SWL_JUMPABLE : 0);
739   e.swctl.bProgType = ptype;
740   e.hswitch = sw_entry;
741   return e;
742 }
743 
744 SV *
create_swentry(char * title,HWND owner_hwnd,HWND icon_hwnd,HPROGRAM owner_phandle,PID owner_pid,ULONG owner_sid,ULONG visible,ULONG nonswitchable,ULONG jumpable,ULONG ptype,HSWITCH sw_entry)745 create_swentry( char *title, HWND owner_hwnd, HWND icon_hwnd, HPROGRAM owner_phandle,
746 	 PID owner_pid, ULONG owner_sid, ULONG visible, ULONG nonswitchable,
747 	 ULONG jumpable, ULONG ptype, HSWITCH sw_entry)
748 {
749     SWENTRY e = swentry(title, owner_hwnd, icon_hwnd, owner_phandle, owner_pid,
750 			owner_sid, visible, nonswitchable, jumpable, ptype,
751 			sw_entry);
752 
753     return newSVpvn((char*)&e, sizeof(e));
754 }
755 
756 int
change_swentrysw(SWENTRY * sw)757 change_swentrysw(SWENTRY *sw)
758 {
759     ULONG rc;			/* For CheckOSError */
760 
761     if (!(_emx_env & 0x200))
762 	     croak("change_entry() not implemented on DOS"); /* not OS/2. */
763     if (!pWinChangeSwitchEntry)
764 	AssignFuncPByORD(pWinChangeSwitchEntry, ORD_WinChangeSwitchEntry);
765     return !CheckOSError(pWinChangeSwitchEntry(sw->hswitch, &sw->swctl));
766 }
767 
768 int
change_swentry(SV * sv)769 change_swentry(SV *sv)
770 {
771     STRLEN l;
772     PSWENTRY pswentry = (PSWENTRY)SvPV(sv, l);
773 
774     if (l != sizeof(SWENTRY))
775 	croak("Wrong structure size %ld!=%ld in change_swentry()", (long)l, (long)sizeof(SWENTRY));
776     return change_swentrysw(pswentry);
777 }
778 
779 
780 #define swentry_size()		(sizeof(SWENTRY))
781 
782 void
getscrsize(int * wp,int * hp)783 getscrsize(int *wp, int *hp)
784 {
785     int i[2];
786 
787     _scrsize(i);
788     *wp = i[0];
789     *hp = i[1];
790 }
791 
792 /* Force vio to not cross 64K-boundary: */
793 #define VIO_FROM_VIOB			\
794     vio = viob;				\
795     if (!_THUNK_PTR_STRUCT_OK(vio))	\
796 	vio++
797 
798 bool
scrsize_set(int w,int h)799 scrsize_set(int w, int h)
800 {
801     VIOMODEINFO viob[2], *vio;
802     ULONG rc;
803 
804     VIO_FROM_VIOB;
805 
806     if (h == -9999)
807 	h = w, w = 0;
808     vio->cb = sizeof(*vio);
809     if (CheckOSError(VioGetMode( vio, 0 )))
810 	return 0;
811 
812     if( w > 0 )
813       vio->col = (USHORT)w;
814 
815     if( h > 0 )
816       vio->row = (USHORT)h;
817 
818     vio->cb = 8;
819     if (CheckOSError(VioSetMode( vio, 0 )))
820 	return 0;
821     return 1;
822 }
823 
824 void
cursor(int * sp,int * ep,int * wp,int * ap)825 cursor(int *sp, int *ep, int *wp, int *ap)
826 {
827     VIOCURSORINFO viob[2], *vio;
828     ULONG rc;
829 
830     VIO_FROM_VIOB;
831 
832     if (CheckOSError(VioGetCurType( vio, 0 )))
833 	croak_with_os2error("VioGetCurType() error");
834 
835     *sp = vio->yStart;
836     *ep = vio->cEnd;
837     *wp = vio->cx;
838     *ep = vio->attr;
839 }
840 
841 bool
cursor__(int is_a)842 cursor__(int is_a)
843 {
844     int s,e,w,a;
845 
846     cursor(&s, &e, &w, &a);
847     if (is_a)
848 	return a;
849     else
850 	return w;
851 }
852 
853 bool
cursor_set(int s,int e,int w,int a)854 cursor_set(int s, int e, int w, int a)
855 {
856     VIOCURSORINFO viob[2], *vio;
857     ULONG rc;
858 
859     VIO_FROM_VIOB;
860 
861     vio->yStart = s;
862     vio->cEnd = e;
863     vio->cx = w;
864     vio->attr = a;
865     return !CheckOSError(VioSetCurType( vio, 0 ));
866 }
867 
868 static int
bufsize(void)869 bufsize(void)
870 {
871 #if 1
872     VIOMODEINFO viob[2], *vio;
873     ULONG rc;
874 
875     VIO_FROM_VIOB;
876 
877     vio->cb = sizeof(*vio);
878     if (CheckOSError(VioGetMode( vio, 0 )))
879 	croak_with_os2error("Can't get size of buffer for screen");
880 #if 0	/* buf=323552247, full=1118455, partial=0 */
881     croak("Lengths: buf=%d, full=%d, partial=%d",vio->buf_length,vio->full_length,vio->partial_length);
882     return newSVpvn((char*)vio->buf_addr, vio->full_length);
883 #endif
884     return vio->col * vio->row * 2;	/* How to get bytes/cell?  2 or 4? */
885 #else	/* 0 */
886     int i[2];
887 
888     _scrsize(i);
889     return i[0]*i[1]*2;
890 #endif	/* 0 */
891 }
892 
893 SV*
_kbdChar(unsigned int nowait,int handle)894 _kbdChar(unsigned int nowait, int handle)
895 {
896     KBDKEYINFO viob[2], *vio;
897     ULONG rc;
898 
899     VIO_FROM_VIOB;
900 
901     if (nowait > 2)
902 	croak("unexpected nowait");
903     if (CheckOSError(nowait == 2
904 		     ? KbdPeek( vio, handle )
905 		     : KbdCharIn( vio, nowait == 1, handle )))
906 	croak_with_os2error("Can't _kbdChar");
907     return newSVpvn((char*)vio, sizeof(*vio));
908 }
909 
910 SV*
_kbdStatus(int handle)911 _kbdStatus(int handle)
912 {
913     KBDINFO viob[2], *vio;
914     ULONG rc;
915 
916     VIO_FROM_VIOB;
917 
918     vio->cb = sizeof(*vio);
919     if (CheckOSError(KbdGetStatus( vio, handle )))
920 	croak_with_os2error("Can't _kbdStatus");
921     return newSVpvn((char*)vio, sizeof(*vio));
922 }
923 
924 void
_kbdStatus_set(SV * sv,int handle)925 _kbdStatus_set(SV* sv, int handle)
926 {
927     KBDINFO viob[2], *vio;
928     ULONG rc;
929     STRLEN l;
930     char *s = SvPV(sv, l);
931 
932     VIO_FROM_VIOB;
933 
934     if (l != sizeof(*vio))
935 	croak("unexpected datasize");
936     Copy((KBDINFO*)s, vio, 1, KBDINFO);
937     if (vio->cb != sizeof(*vio))
938 	croak("unexpected datasize");
939     if (CheckOSError(KbdSetStatus( vio, handle )))
940 	croak_with_os2error("Can't kbdStatus_set()");
941 }
942 
943 SV*
_vioConfig(int which,int handle)944 _vioConfig(int which, int handle)
945 {
946     struct {VIOCONFIGINFO i; short a[20];} viob[2], *vio;
947     ULONG rc;
948 
949     VIO_FROM_VIOB;
950 
951     vio->i.cb = 2;
952     if (CheckOSError(VioGetConfig( which, &vio->i, handle )))
953 	croak_with_os2error("Can't get VIO config size");
954     if (vio->i.cb > sizeof(*vio))
955 	vio->i.cb = sizeof(*vio);
956     if (CheckOSError(VioGetConfig( which, &vio->i, handle )))
957 	croak_with_os2error("Can't get VIO config");
958     return newSVpvn((char*)vio, vio->i.cb);
959 }
960 
961 SV*
_vioMode(void)962 _vioMode(void)
963 {
964     VIOMODEINFO viob[2], *vio;
965     ULONG rc;
966 
967     VIO_FROM_VIOB;
968 
969     vio->cb = sizeof(*vio);
970     if (CheckOSError(VioGetMode( vio, 0 )))
971 	croak_with_os2error("Can't get VIO mode");
972     return newSVpvn((char*)vio, sizeof(*vio));
973 }
974 
975 void
_vioMode_set(SV * sv)976 _vioMode_set(SV* sv)
977 {
978     VIOMODEINFO viob[2], *vio;
979     ULONG rc;
980     STRLEN l;
981     char *s = SvPV(sv, l);
982 
983     VIO_FROM_VIOB;
984 
985     Copy((VIOMODEINFO*)s, vio, 1, VIOMODEINFO);
986     if (vio->cb != sizeof(*vio) || l != vio->cb)
987 	croak("unexpected datasize");
988     if (CheckOSError(VioSetMode( vio, 0 )))
989 	croak_with_os2error("Can't set VIO mode");
990 }
991 
992 SV*
vioFont(int type,int * w,int * h)993 vioFont(int type, int *w, int *h) /* 0 for actual RAM font, 1 for ROM font */
994 {
995     VIOFONTINFO viob[2], *vio;
996     ULONG rc;
997     UCHAR b[1<<17];
998     UCHAR *buf = b;
999     SV *sv;
1000 
1001     VIO_FROM_VIOB;
1002 
1003     /* Should not cross 64K boundaries too: */
1004     if (((ULONG)buf) & 0xFFFF)
1005 	buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
1006 
1007     vio->cb = sizeof(*vio);
1008     vio->type = type;			/* BIOS or the loaded font. */
1009     vio->cbData = 0xFFFF;		/* How large is my buffer? */
1010     vio->pbData = _emx_32to16(buf);	/* Wants an 16:16 pointer */
1011     if (CheckOSError(VioGetFont( vio, 0 )))
1012 	croak_with_os2error("Can't get VIO font");
1013     *w = vio->cxCell;
1014     *h = vio->cyCell;
1015     return newSVpvn(buf,vio->cbData);
1016 }
1017 
1018 void
vioFont_set(SV * sv,int cellwidth,int cellheight,int type)1019 vioFont_set(SV *sv, int cellwidth, int cellheight, int type)
1020 {
1021     VIOFONTINFO viob[2], *vio;
1022     ULONG rc;
1023     UCHAR b[1<<17];
1024     UCHAR *buf = b;
1025     STRLEN l;
1026     char *s = SvPV(sv, l);
1027 
1028     VIO_FROM_VIOB;
1029 
1030     /* Should not cross 64K boundaries too: */
1031     if (((ULONG)buf) & 0xFFFF)
1032 	buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
1033 
1034     if (l > 0xFFFF)
1035 	croak("length overflow of VIO font");
1036     if (l != (cellwidth + 7)/8 * cellheight * 256)
1037 	warn("unexpected length of VIO font");
1038     vio->cb = sizeof(*vio);
1039     vio->type = type;			/* BIOS or the loaded font. */
1040     vio->cbData = l;			/* How large is my buffer? */
1041     vio->pbData = _emx_32to16(buf);	/* Wants an 16:16 pointer */
1042     vio->cxCell = cellwidth;
1043     vio->cyCell = cellheight;
1044     Copy(s, buf, l, char);
1045 
1046     if (CheckOSError(VioSetFont( vio, 0 )))
1047 	croak_with_os2error("Can't set VIO font");
1048 }
1049 
1050 /*
1051   uses use32,os2def,os2base,crt,defs;
1052   var   Plt :Plt256;
1053   const Pal :VioPalState=(Cb:sizeof(VioPalState);rType:0;iFirst:0;
1054     Acolor:($FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF));
1055         CReg:VioColorReg=(Cb:sizeof(VioColorReg);rType:3;FirstColorReg:0;
1056     NumColorRegs:256; ColorRegAddr:@Plt);
1057   var   ii:Pointer;
1058   begin
1059    VioGetState(Pal,0);
1060    Pal.Acolor[09]:=$0F;
1061    Pal.Acolor[10]:=$A;
1062    Pal.Acolor[13]:=$2F;
1063    VioSetState(Pal,0); // ce smena EGA registrov
1064    asm
1065   lea   eax,Plt
1066      call  DosFlatToSel
1067      mov   ii,eax
1068    end;
1069    CReg.ColorRegAddr:=ii;
1070    VioGetState(CReg,0);
1071    Plt[10,0]:=$00;
1072    Plt[10,1]:=$32;
1073    Plt[10,2]:=$2A;
1074    VioSetState(CReg,0); // a ce - VGA registrov
1075   end.
1076 */
1077 
1078 typedef union {
1079   VIOPALSTATE pal;
1080   struct { VIOPALSTATE pal; USHORT a[15]; } pal_padded;
1081   VIOOVERSCAN overscan;
1082   VIOINTENSITY intensity;
1083   VIOCOLORREG colorreg;
1084   struct { VIOCOLORREG reg; char rgb[3*256]; } colorreg_padded;
1085   VIOSETULINELOC lineloc;
1086   VIOSETTARGET target;
1087 } my_VIOSTATE;
1088 
1089 int
vio_state_size(int what)1090 vio_state_size(int what)
1091 {
1092     static const char sizes[] = {
1093 	sizeof(VIOPALSTATE),
1094 	sizeof(VIOOVERSCAN),
1095 	sizeof(VIOINTENSITY),
1096 	sizeof(VIOCOLORREG),
1097 	6,				/* Random number: Reserved entry */
1098 	sizeof(VIOSETULINELOC),
1099 	sizeof(VIOSETTARGET)
1100     };
1101     if (what < 0 || what >= sizeof(sizes))
1102 	croak("Unexpected VIO state type");
1103     return sizes[what];
1104 }
1105 
1106 SV*
_vioState(int what,int first,int count)1107 _vioState(int what, int first, int count)
1108 {
1109     my_VIOSTATE viob[2], *vio;
1110     ULONG rc, size = vio_state_size(what);
1111 
1112     VIO_FROM_VIOB;
1113 
1114     vio->pal.cb = size;
1115     vio->pal.type = what;
1116     if (what == 0) {
1117 	vio->pal.iFirst = first;
1118 	if (first < 0 || first >= 16)
1119 	    croak("unexpected palette start value");
1120 	if (count < 0 || count > 16)
1121 	    croak("unexpected palette count");
1122 	vio->pal.cb = (size += (count - 1) * sizeof(short));
1123     } else if (what == 3) {
1124 	/* Wants an 16:16 pointer */
1125 	if (count < 0 || count > 256)
1126 	    croak("unexpected palette count");
1127 	vio->colorreg.colorregaddr = (PCH)_emx_32to16(vio->colorreg_padded.rgb);
1128 	vio->colorreg.numcolorregs = count;		/* 256 is max */
1129 	vio->colorreg.firstcolorreg = first;
1130 	size += 3 * count;
1131     }
1132     if (CheckOSError(VioGetState( (void*)vio, 0 )))
1133 	croak_with_os2error("Can't get VIO state");
1134     return newSVpvn((char*)vio, size);
1135 }
1136 
1137 void
_vioState_set(SV * sv)1138 _vioState_set(SV *sv)
1139 {
1140     my_VIOSTATE viob[2], *ovio = (my_VIOSTATE*)SvPV_nolen(sv), *vio = ovio;
1141     int what = ovio->pal.type, cb = ovio->pal.cb;
1142     ULONG rc, size = vio_state_size(what);
1143     STRLEN l;
1144     char *s = SvPV(sv, l);
1145 
1146     VIO_FROM_VIOB;
1147 
1148     switch (what) {
1149     case 0:
1150 	if ( cb < size || cb > size + 15*sizeof(SHORT) || l != cb)
1151 	    croak("unexpected datasize");
1152 	size = l;
1153 	break;
1154     case 3:
1155 	if (l != cb + 3 * ovio->colorreg.numcolorregs || cb != size)
1156 	    croak("unexpected datasize");
1157 	size = l;
1158 	break;
1159     default:
1160 	if (l != cb || l != size )
1161 	    croak("unexpected datasize");
1162 	break;
1163     }
1164     Copy(s, (char*)vio, size, char);
1165     if (what == 3)	/* We expect colors put after VIOCOLORREG */
1166 	vio->colorreg.colorregaddr = (PCH)_emx_32to16(vio->colorreg_padded.rgb);
1167 
1168     if (CheckOSError(VioSetState( (void*)vio, 0 )))
1169 	croak_with_os2error("Can't set VIO state");
1170 }
1171 
1172 SV *
screen(void)1173 screen(void)
1174 {
1175     ULONG rc;
1176     USHORT bufl = bufsize();
1177     char b[(1<<16) * 3]; /* This/3 is enough for 16-bit calls, we need
1178 			    2x overhead due to 2 vs 4 issue, and extra
1179 			    64K due to alignment logic */
1180     char *buf = b;
1181 
1182     if (((ULONG)buf) & 0xFFFF)
1183 	buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
1184     if ((sizeof(b) - (buf - b)) < 2*bufl)
1185 	croak("panic: VIO buffer allocation");
1186     if (CheckOSError(VioReadCellStr( buf, &bufl, 0, 0, 0 )))
1187 	return &PL_sv_undef;
1188     return newSVpvn(buf,bufl);
1189 }
1190 
1191 bool
screen_set(SV * sv)1192 screen_set(SV *sv)
1193 {
1194     ULONG rc;
1195     STRLEN l = SvCUR(sv), bufl = bufsize();
1196     char b[(1<<16) * 2]; /* This/2 is enough for 16-bit calls, we need
1197 			    extra 64K due to alignment logic */
1198     char *buf = b;
1199 
1200     if (((ULONG)buf) & 0xFFFF)
1201 	buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
1202     if (!SvPOK(sv) || ((l != bufl) && (l != 2*bufl)))
1203 	croak("Wrong size %d of saved screen data", SvCUR(sv));
1204     if ((sizeof(b) - (buf - b)) < l)
1205 	croak("panic: VIO buffer allocation");
1206     Copy(SvPV(sv,l), buf, bufl, char);
1207     if (CheckOSError(VioWrtCellStr( buf, bufl, 0, 0, 0 )))
1208 	return 0;
1209     return 1;
1210 }
1211 
1212 int
process_codepages()1213 process_codepages()
1214 {
1215     ULONG cps[4], cp, rc;
1216 
1217     if (CheckOSError(DosQueryCp( sizeof(cps), cps, &cp )))
1218 	croak_with_os2error("DosQueryCp()");
1219     return cp;
1220 }
1221 
1222 int
out_codepage()1223 out_codepage()
1224 {
1225     USHORT cp, rc;
1226 
1227     if (CheckOSError(VioGetCp( 0, &cp, 0 )))
1228 	croak_with_os2error("VioGetCp()");
1229     return cp;
1230 }
1231 
1232 bool
out_codepage_set(int cp)1233 out_codepage_set(int cp)
1234 {
1235     USHORT rc;
1236 
1237     return !(CheckOSError(VioSetCp( 0, cp, 0 )));
1238 }
1239 
1240 int
in_codepage()1241 in_codepage()
1242 {
1243     USHORT cp, rc;
1244 
1245     if (CheckOSError(KbdGetCp( 0, &cp, 0 )))
1246 	croak_with_os2error("KbdGetCp()");
1247     return cp;
1248 }
1249 
1250 bool
in_codepage_set(int cp)1251 in_codepage_set(int cp)
1252 {
1253     USHORT rc;
1254 
1255     return !(CheckOSError(KbdSetCp( 0, cp, 0 )));
1256 }
1257 
1258 bool
process_codepage_set(int cp)1259 process_codepage_set(int cp)
1260 {
1261     USHORT rc;
1262 
1263     return !(CheckOSError(DosSetProcessCp( cp )));
1264 }
1265 
1266 int
ppidOf(int pid)1267 ppidOf(int pid)
1268 {
1269   PQTOPLEVEL psi;
1270   int ppid;
1271 
1272   if (!pid)
1273       return -1;
1274   psi = get_sysinfo(pid, QSS_PROCESS);
1275   if (!psi)
1276       return -1;
1277   ppid = psi->procdata->ppid;
1278   Safefree(psi);
1279   return ppid;
1280 }
1281 
1282 int
sidOf(int pid)1283 sidOf(int pid)
1284 {
1285   PQTOPLEVEL psi;
1286   int sid;
1287 
1288   if (!pid)
1289       return -1;
1290   psi = get_sysinfo(pid, QSS_PROCESS);
1291   if (!psi)
1292       return -1;
1293   sid = psi->procdata->sessid;
1294   Safefree(psi);
1295   return sid;
1296 }
1297 
1298 #define ulMPFROMSHORT(i)		((unsigned long)MPFROMSHORT(i))
1299 #define ulMPVOID()			((unsigned long)MPVOID)
1300 #define ulMPFROMCHAR(i)			((unsigned long)MPFROMCHAR(i))
1301 #define ulMPFROM2SHORT(x1,x2)		((unsigned long)MPFROM2SHORT(x1,x2))
1302 #define ulMPFROMSH2CH(s, c1, c2)	((unsigned long)MPFROMSH2CH(s, c1, c2))
1303 #define ulMPFROMLONG(x)			((unsigned long)MPFROMLONG(x))
1304 
1305 #define _MessageBox			MessageBox
1306 #define _MessageBox2			MessageBox2
1307 
1308 MODULE = OS2::Process		PACKAGE = OS2::Process
1309 
1310 PROTOTYPES: ENABLE
1311 
1312 unsigned long
constant(name,arg)1313 constant(name,arg)
1314 	char *		name
1315 	int		arg
1316 
1317 char *
1318 my_type()
1319 
1320 U32
1321 file_type(path)
1322     char *path
1323 
1324 SV *
1325 swentry_expand( SV *sv )
1326     PPCODE:
1327      {
1328 	 STRLEN l;
1329 	 PSWENTRY pswentry = (PSWENTRY)SvPV(sv, l);
1330 
1331 	 if (l != sizeof(SWENTRY))
1332 		croak("Wrong structure size %ld!=%ld in swentry_expand()", (long)l, (long)sizeof(SWENTRY));
1333 	 EXTEND(sp,11);
1334 	 PUSHs(sv_2mortal(newSVpv(pswentry->swctl.szSwtitle, 0)));
1335 	 PUSHs(sv_2mortal(newSVnv(pswentry->swctl.hwnd)));
1336 	 PUSHs(sv_2mortal(newSVnv(pswentry->swctl.hwndIcon)));
1337 	 PUSHs(sv_2mortal(newSViv(pswentry->swctl.hprog)));
1338 	 PUSHs(sv_2mortal(newSViv(pswentry->swctl.idProcess)));
1339 	 PUSHs(sv_2mortal(newSViv(pswentry->swctl.idSession)));
1340 	 PUSHs(sv_2mortal(newSViv(pswentry->swctl.uchVisibility & SWL_VISIBLE)));
1341 	 PUSHs(sv_2mortal(newSViv(pswentry->swctl.uchVisibility & SWL_GRAYED)));
1342 	 PUSHs(sv_2mortal(newSViv(pswentry->swctl.fbJump == SWL_JUMPABLE)));
1343 	 PUSHs(sv_2mortal(newSViv(pswentry->swctl.bProgType)));
1344 	 PUSHs(sv_2mortal(newSViv(pswentry->hswitch)));
1345      }
1346 
1347 SV *
1348 create_swentry( char *title, unsigned long sw_hwnd, unsigned long icon_hwnd, unsigned long owner_phandle, unsigned long owner_pid, unsigned long owner_sid, unsigned long visible, unsigned long switchable,	 unsigned long jumpable, unsigned long ptype, unsigned long sw_entry)
1349 PROTOTYPE: DISABLE
1350 
1351 int
1352 change_swentry( SV *sv )
1353 
1354 bool
1355 sesmgr_title_set(s)
1356     char *s
1357 
1358 SV *
1359 process_swentry(unsigned long pid = getpid(), HWND hwnd = NULLHANDLE);
1360   PROTOTYPE: DISABLE
1361 
1362 int
1363 swentry_size()
1364 
1365 SV *
1366 swentries_list()
1367 
1368 void
1369 ResetWinError()
1370 
1371 int
1372 WindowText_set(HWND hwndFrame, char *title)
1373 
1374 bool
1375 FocusWindow_set(HWND hwndFocus, HWND hwndDesktop = HWND_DESKTOP)
1376 
1377 bool
1378 ShowWindow(HWND hwnd, bool fShow = TRUE)
1379 
1380 bool
1381 EnableWindow(HWND hwnd, bool fEnable = TRUE)
1382 
1383 bool
1384 PostMsg(HWND hwnd, unsigned long msg, unsigned long mp1 = 0, unsigned long mp2 = 0)
1385     C_ARGS: hwnd, msg, (MPARAM)mp1, (MPARAM)mp2
1386 
1387 bool
1388 WindowPos_set(HWND hwnd, long x, long y, unsigned long fl = SWP_MOVE, long cx = 0, long cy = 0, HWND hwndInsertBehind = HWND_TOP)
1389   PROTOTYPE: DISABLE
1390 
1391 unsigned long
1392 BeginEnumWindows(HWND hwnd)
1393 
1394 bool
1395 EndEnumWindows(unsigned long henum)
1396 
1397 unsigned long
1398 GetNextWindow(unsigned long henum)
1399 
1400 bool
1401 IsWindowVisible(HWND hwnd)
1402 
1403 bool
1404 IsWindowEnabled(HWND hwnd)
1405 
1406 bool
1407 IsWindowShowing(HWND hwnd)
1408 
1409 unsigned long
1410 QueryWindow(HWND hwnd, long cmd)
1411 
1412 unsigned long
1413 IsChild(HWND hwnd, HWND hwndParent)
1414 
1415 unsigned long
1416 WindowFromId(HWND hwndParent, unsigned long id)
1417 
1418 unsigned long
1419 WindowFromPoint(long x, long y, HWND hwnd = HWND_DESKTOP, bool fChildren = TRUE)
1420 PROTOTYPE: DISABLE
1421 
1422 unsigned long
1423 EnumDlgItem(HWND hwndDlg, unsigned long code, HWND hwnd = NULLHANDLE)
1424    C_ARGS: hwndDlg, hwnd, code
1425 
1426 bool
1427 EnableWindowUpdate(HWND hwnd, bool fEnable = TRUE)
1428 
1429 bool
1430 SetWindowBits(HWND hwnd, long index, unsigned long flData, unsigned long flMask)
1431 
1432 bool
1433 SetWindowPtr(HWND hwnd, long index, unsigned long p)
1434     C_ARGS: hwnd, index, (PVOID)p
1435 
1436 bool
1437 SetWindowULong(HWND hwnd, long index, unsigned long i)
1438 
1439 bool
1440 SetWindowUShort(HWND hwnd, long index, unsigned short i)
1441 
1442 bool
1443 IsWindow(HWND hwnd, HAB hab = Acquire_hab())
1444     C_ARGS: hab, hwnd
1445 
1446 BOOL
1447 ActiveWindow_set(HWND hwnd, HWND hwndDesktop = HWND_DESKTOP)
1448     CODE:
1449 	RETVAL = SetActiveWindow(hwndDesktop, hwnd);
1450 
1451 unsigned long
1452 LoadPointer(unsigned long idres, unsigned long hmod = 0, HWND hwndDesktop = HWND_DESKTOP)
1453     C_ARGS: hwndDesktop, hmod, idres
1454 
1455 int
1456 out_codepage()
1457 
1458 bool
1459 out_codepage_set(int cp)
1460 
1461 int
1462 in_codepage()
1463 
1464 bool
1465 in_codepage_set(int cp)
1466 
1467 SV *
1468 screen()
1469 
1470 bool
1471 screen_set(SV *sv)
1472 
1473 SV *
1474 process_codepages()
1475   PPCODE:
1476   {
1477     ULONG cps[4], c, i = 0, rc;
1478 
1479     if (CheckOSError(DosQueryCp( sizeof(cps), cps, &c )))
1480 	c = 0;
1481     c /= sizeof(ULONG);
1482     if (c >= 3)
1483     EXTEND(sp, c);
1484     while (i < c)
1485 	PUSHs(sv_2mortal(newSViv(cps[i++])));
1486   }
1487 
1488 bool
1489 process_codepage_set(int cp)
1490 
1491 void
1492 cursor(OUTLIST int stp, OUTLIST int ep, OUTLIST int wp, OUTLIST int ap)
1493   PROTOTYPE:
1494 
1495 bool
1496 cursor_set(int s, int e, int w = cursor__(0), int a = cursor__(1))
1497 
1498 SV*
1499 _kbdChar(int nowait = 0, int handle = 0)
1500 
1501 SV*
1502 _kbdStatus(int handle = 0)
1503 
1504 void
1505 _kbdStatus_set(SV *sv, int handle = 0)
1506 
1507 SV*
1508 _vioConfig(int which = 0, int handle = 0)
1509 
1510 SV*
1511 _vioMode()
1512 
1513 void
1514 _vioMode_set(SV *buffer)
1515 
1516 SV*
1517 _vioState(int what, int first = -1, int count = -1)
1518 
1519 void
1520 _vioState_set(SV *buffer)
1521 
1522 SV*
1523 vioFont( int type = 0, OUTLIST int w, OUTLIST int h)
1524 
1525 void
1526 vioFont_set(SV *buffer, int cellwidth, int cellheight, int type = 0)
1527 
1528 NO_OUTPUT bool
1529 _ClipbrdData_set(unsigned long ulData, unsigned long fmt = CF_TEXT, unsigned long rgfFmtInfo = ((fmt == CF_TEXT || fmt == CF_DSPTEXT) ? CFI_POINTER : CFI_HANDLE), HAB hab = perl_hab_GET())
1530     PROTOTYPE: DISABLE
1531     C_ARGS: hab, ulData, fmt, rgfFmtInfo
1532     POSTCALL:
1533 	if (CheckWinError(RETVAL))
1534 	    croak_with_os2error("_ClipbrdData_set() error");
1535 
1536 void
1537 ClipbrdData_set(SV *text, int convert_nl = 1, unsigned long fmt = CF_TEXT, unsigned long rgfFmtInfo = ((fmt == CF_TEXT || fmt == CF_DSPTEXT) ? CFI_POINTER : CFI_HANDLE), HAB hab = perl_hab_GET())
1538     PROTOTYPE: DISABLE
1539 
1540 void
1541 ClipbrdOwner_set(HWND hwnd, HAB hab = perl_hab_GET())
1542     C_ARGS: hab, hwnd
1543 
1544 void
1545 ClipbrdViewer_set(HWND hwnd, HAB hab = perl_hab_GET())
1546     C_ARGS: hab, hwnd
1547 
1548 unsigned long
1549 EnumClipbrdFmts(unsigned long fmt = 0, HAB hab = perl_hab_GET())
1550     C_ARGS: hab, fmt
1551 
1552 unsigned long
1553 AddAtom(char *pszAtomName, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1554     C_ARGS: hAtomTbl, pszAtomName
1555 
1556 unsigned long
1557 FindAtom(char *pszAtomName, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1558     C_ARGS: hAtomTbl, pszAtomName
1559 
1560 unsigned long
1561 DeleteAtom(char *pszAtomName, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1562     C_ARGS: hAtomTbl, pszAtomName
1563 
1564 void
1565 Alarm(unsigned long rgfType = WA_ERROR, HWND hwndDesktop = HWND_DESKTOP)
1566     C_ARGS: hwndDesktop, rgfType
1567 
1568 void
1569 FlashWindow(HWND hwndFrame, bool fFlash)
1570 
1571 MODULE = OS2::Process		PACKAGE = OS2::Process	PREFIX = myQuery
1572 
1573 SV *
1574 myQueryWindowText(HWND hwnd)
1575 
1576 SV *
1577 myQueryClassName(HWND hwnd)
1578 
1579 MODULE = OS2::Process		PACKAGE = OS2::Process	PREFIX = Query
1580 
1581 unsigned long
1582 QueryFocusWindow(HWND hwndDesktop = HWND_DESKTOP)
1583 
1584 long
1585 QueryWindowTextLength(HWND hwnd)
1586 
1587 SV *
1588 QueryWindowSWP(HWND hwnd)
1589 
1590 unsigned long
1591 QueryWindowULong(HWND hwnd, long index)
1592 
1593 unsigned short
1594 QueryWindowUShort(HWND hwnd, long index)
1595 
1596 unsigned long
1597 QueryActiveWindow(HWND hwnd = HWND_DESKTOP)
1598 
1599 unsigned long
1600 QueryDesktopWindow(HAB hab = Acquire_hab(), unsigned long hdc = NULLHANDLE)
1601 
1602 unsigned long
1603 QueryClipbrdData(unsigned long fmt = CF_TEXT, HAB hab = perl_hab_GET())
1604     C_ARGS: hab, fmt
1605     PROTOTYPE: DISABLE
1606 
1607 unsigned long
1608 QueryClipbrdViewer(HAB hab = perl_hab_GET())
1609 
1610 unsigned long
1611 QueryClipbrdOwner(HAB hab = perl_hab_GET())
1612 
1613 void
1614 CloseClipbrd(HAB hab = perl_hab_GET())
1615 
1616 void
1617 EmptyClipbrd(HAB hab = perl_hab_GET())
1618 
1619 bool
1620 OpenClipbrd(HAB hab = perl_hab_GET())
1621 
1622 unsigned long
1623 QueryAtomUsage(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1624     C_ARGS: hAtomTbl, atom
1625 
1626 unsigned long
1627 QueryAtomLength(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1628     C_ARGS: hAtomTbl, atom
1629 
1630 unsigned long
1631 QuerySystemAtomTable()
1632 
1633 unsigned long
1634 QuerySysPointer(long lId, bool fCopy = 1, HWND hwndDesktop = HWND_DESKTOP)
1635     C_ARGS: hwndDesktop, lId, fCopy
1636 
1637 unsigned long
1638 CreateAtomTable(unsigned long initial = 0, unsigned long buckets = 0)
1639 
1640 unsigned long
1641 DestroyAtomTable(HATOMTBL hAtomTbl)
1642 
1643 
1644 MODULE = OS2::Process		PACKAGE = OS2::Process	PREFIX = myWinQuery
1645 
1646 unsigned long
1647 myWinQueryWindowPtr(HWND hwnd, long index)
1648 
1649 NO_OUTPUT BOOL
1650 myWinQueryWindowProcess(HWND hwnd, OUTLIST unsigned long pid, OUTLIST unsigned long tid)
1651    PROTOTYPE: $
1652    POSTCALL:
1653 	if (CheckWinError(RETVAL))
1654 	    croak_with_os2error("WindowProcess() error");
1655 
1656 SV *
1657 myWinQueryActiveDesktopPathname()
1658 
1659 void
1660 myWinQueryClipbrdFmtInfo(OUTLIST unsigned long prgfFmtInfo, unsigned long fmt = CF_TEXT, HAB hab = perl_hab_GET())
1661    C_ARGS: hab, fmt, &prgfFmtInfo
1662 
1663 SV *
1664 myWinQueryAtomName(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1665 
1666 MODULE = OS2::Process		PACKAGE = OS2::Process	PREFIX = myWin
1667 
1668 int
1669 myWinSwitchToProgram(HSWITCH hsw = switch_of(NULLHANDLE, getpid()))
1670     PREINIT:
1671 	ULONG rc;
1672 
1673 #if 0
1674 
1675 unsigned long
1676 myWinMessageBox(unsigned long pszText, char* pszCaption = "Perl script error", unsigned long flStyle = MB_CANCEL | MB_ICONHAND, HWND hwndParent = HWND_DESKTOP, HWND hwndOwner = HWND_DESKTOP, unsigned long idWindow = 0)
1677     C_ARGS: hwndParent, hwndOwner, pszText, pszCaption, idWindow, flStyle
1678 
1679 #endif
1680 
1681 unsigned long
1682 _MessageBox(char* pszText, char* pszCaption = "Perl script error", unsigned long flStyle = MB_CANCEL | MB_INFORMATION | MB_MOVEABLE, HWND hwndParent = HWND_DESKTOP, HWND hwndOwner = NULLHANDLE, unsigned long idWindow = 0)
1683     C_ARGS: hwndParent, hwndOwner, pszText, pszCaption, idWindow, flStyle
1684     POSTCALL:
1685 	if (RETVAL == MBID_ERROR)
1686 	    RETVAL = 0;
1687 
1688 unsigned long
1689 _MessageBox2(char *pszText, char* pmb2info, char *pszCaption, HWND hwndParent = HWND_DESKTOP, HWND hwndOwner = NULLHANDLE, unsigned long idWindow = 0)
1690     C_ARGS: hwndParent, hwndOwner, pszText, pszCaption, idWindow, (PMB2INFO)pmb2info
1691     POSTCALL:
1692 	if (RETVAL == MBID_ERROR)
1693 	    RETVAL = 0;
1694 
1695 MODULE = OS2::Process		PACKAGE = OS2::Process	PREFIX = myWinQuery
1696 
1697 MODULE = OS2::Process		PACKAGE = OS2::Process	PREFIX = get
1698 
1699 int
1700 getppid()
1701 
1702 int
1703 ppidOf(int pid = getpid())
1704 
1705 int
1706 sidOf(int pid = getpid())
1707 
1708 void
1709 getscrsize(OUTLIST int wp, OUTLIST int hp)
1710   PROTOTYPE:
1711 
1712 bool
1713 scrsize_set(int w_or_h, int h = -9999)
1714 
1715 void
1716 get_InvalidateRect(HWND hwnd, char *prcl, bool fIncludeChildren)
1717 
1718 void
1719 get_CreateFrameControls(HWND hwndFrame, char *pfcdata, char* pszTitle)
1720 
1721 MODULE = OS2::Process		PACKAGE = OS2::Process	PREFIX = ul
1722 
1723 unsigned long
1724 ulMPFROMSHORT(unsigned short i)
1725 
1726 unsigned long
1727 ulMPVOID()
1728 
1729 unsigned long
1730 ulMPFROMCHAR(unsigned char i)
1731 
1732 unsigned long
1733 ulMPFROM2SHORT(unsigned short x1, unsigned short x2)
1734   PROTOTYPE: DISABLE
1735 
1736 unsigned long
1737 ulMPFROMSH2CH(unsigned short s, unsigned char c1, unsigned char c2)
1738   PROTOTYPE: DISABLE
1739 
1740 unsigned long
1741 ulMPFROMLONG(unsigned long x)
1742 
1743