cda4847c83af06608973ededca8939df57e18171
[p5sagit/p5-mst-13.2.git] / os2 / OS2 / Process / Process.xs
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
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 *
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
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
403 WindowText_set(HWND hwnd, char* text)
404 {
405    return !CheckWinError(myWinSetWindowText(hwnd, text));
406 }
407
408 SV *
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
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 *
442 QueryWindowSWP(HWND hwnd)
443 {
444     SWP swp = QueryWindowSWP_(hwnd);
445
446     return newSVpvn((char*)&swp, sizeof(swp));
447 }
448
449 SV *
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
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
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
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
504 fill_swentry_default(SWENTRY *swentryp)
505 {
506         fill_swentry(swentryp, NULLHANDLE, getpid());
507 }
508
509 static SV*
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 *
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
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
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 *
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 *
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
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 *
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
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
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
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
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
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
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
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
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*
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*
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
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*
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*
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
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*
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
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
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*
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
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 *
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
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
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
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
1233 out_codepage_set(int cp)
1234 {
1235     USHORT rc;
1236
1237     return !(CheckOSError(VioSetCp( 0, cp, 0 )));
1238 }
1239
1240 int
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
1251 in_codepage_set(int cp)
1252 {
1253     USHORT rc;
1254
1255     return !(CheckOSError(KbdSetCp( 0, cp, 0 )));
1256 }
1257
1258 bool
1259 process_codepage_set(int cp)
1260 {
1261     USHORT rc;
1262
1263     return !(CheckOSError(DosSetProcessCp( cp )));
1264 }
1265
1266 int
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
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
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