Integrate mainline
[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 #include <os2.h>
11
12 #include "EXTERN.h"
13 #include "perl.h"
14 #include "XSUB.h"
15
16 static unsigned long
17 constant(char *name, int arg)
18 {
19     errno = 0;
20     if (name[0] == 'P' && name[1] == '_') {
21         if (strEQ(name, "P_BACKGROUND"))
22 #ifdef P_BACKGROUND
23             return P_BACKGROUND;
24 #else
25             goto not_there;
26 #endif
27         if (strEQ(name, "P_DEBUG"))
28 #ifdef P_DEBUG
29             return P_DEBUG;
30 #else
31             goto not_there;
32 #endif
33         if (strEQ(name, "P_DEFAULT"))
34 #ifdef P_DEFAULT
35             return P_DEFAULT;
36 #else
37             goto not_there;
38 #endif
39         if (strEQ(name, "P_DETACH"))
40 #ifdef P_DETACH
41             return P_DETACH;
42 #else
43             goto not_there;
44 #endif
45         if (strEQ(name, "P_FOREGROUND"))
46 #ifdef P_FOREGROUND
47             return P_FOREGROUND;
48 #else
49             goto not_there;
50 #endif
51         if (strEQ(name, "P_FULLSCREEN"))
52 #ifdef P_FULLSCREEN
53             return P_FULLSCREEN;
54 #else
55             goto not_there;
56 #endif
57         if (strEQ(name, "P_MAXIMIZE"))
58 #ifdef P_MAXIMIZE
59             return P_MAXIMIZE;
60 #else
61             goto not_there;
62 #endif
63         if (strEQ(name, "P_MINIMIZE"))
64 #ifdef P_MINIMIZE
65             return P_MINIMIZE;
66 #else
67             goto not_there;
68 #endif
69         if (strEQ(name, "P_NOCLOSE"))
70 #ifdef P_NOCLOSE
71             return P_NOCLOSE;
72 #else
73             goto not_there;
74 #endif
75         if (strEQ(name, "P_NOSESSION"))
76 #ifdef P_NOSESSION
77             return P_NOSESSION;
78 #else
79             goto not_there;
80 #endif
81         if (strEQ(name, "P_NOWAIT"))
82 #ifdef P_NOWAIT
83             return P_NOWAIT;
84 #else
85             goto not_there;
86 #endif
87         if (strEQ(name, "P_OVERLAY"))
88 #ifdef P_OVERLAY
89             return P_OVERLAY;
90 #else
91             goto not_there;
92 #endif
93         if (strEQ(name, "P_PM"))
94 #ifdef P_PM
95             return P_PM;
96 #else
97             goto not_there;
98 #endif
99         if (strEQ(name, "P_QUOTE"))
100 #ifdef P_QUOTE
101             return P_QUOTE;
102 #else
103             goto not_there;
104 #endif
105         if (strEQ(name, "P_SESSION"))
106 #ifdef P_SESSION
107             return P_SESSION;
108 #else
109             goto not_there;
110 #endif
111         if (strEQ(name, "P_TILDE"))
112 #ifdef P_TILDE
113             return P_TILDE;
114 #else
115             goto not_there;
116 #endif
117         if (strEQ(name, "P_UNRELATED"))
118 #ifdef P_UNRELATED
119             return P_UNRELATED;
120 #else
121             goto not_there;
122 #endif
123         if (strEQ(name, "P_WAIT"))
124 #ifdef P_WAIT
125             return P_WAIT;
126 #else
127             goto not_there;
128 #endif
129         if (strEQ(name, "P_WINDOWED"))
130 #ifdef P_WINDOWED
131             return P_WINDOWED;
132 #else
133             goto not_there;
134 #endif
135     } else if (name[0] == 'T' && name[1] == '_') {
136         if (strEQ(name, "FAPPTYP_NOTSPEC"))
137 #ifdef FAPPTYP_NOTSPEC
138             return FAPPTYP_NOTSPEC;
139 #else
140             goto not_there;
141 #endif
142         if (strEQ(name, "T_NOTWINDOWCOMPAT"))
143 #ifdef FAPPTYP_NOTWINDOWCOMPAT
144             return FAPPTYP_NOTWINDOWCOMPAT;
145 #else
146             goto not_there;
147 #endif
148         if (strEQ(name, "T_WINDOWCOMPAT"))
149 #ifdef FAPPTYP_WINDOWCOMPAT
150             return FAPPTYP_WINDOWCOMPAT;
151 #else
152             goto not_there;
153 #endif
154         if (strEQ(name, "T_WINDOWAPI"))
155 #ifdef FAPPTYP_WINDOWAPI
156             return FAPPTYP_WINDOWAPI;
157 #else
158             goto not_there;
159 #endif
160         if (strEQ(name, "T_BOUND"))
161 #ifdef FAPPTYP_BOUND
162             return FAPPTYP_BOUND;
163 #else
164             goto not_there;
165 #endif
166         if (strEQ(name, "T_DLL"))
167 #ifdef FAPPTYP_DLL
168             return FAPPTYP_DLL;
169 #else
170             goto not_there;
171 #endif
172         if (strEQ(name, "T_DOS"))
173 #ifdef FAPPTYP_DOS
174             return FAPPTYP_DOS;
175 #else
176             goto not_there;
177 #endif
178         if (strEQ(name, "T_PHYSDRV"))
179 #ifdef FAPPTYP_PHYSDRV
180             return FAPPTYP_PHYSDRV;
181 #else
182             goto not_there;
183 #endif
184         if (strEQ(name, "T_VIRTDRV"))
185 #ifdef FAPPTYP_VIRTDRV
186             return FAPPTYP_VIRTDRV;
187 #else
188             goto not_there;
189 #endif
190         if (strEQ(name, "T_PROTDLL"))
191 #ifdef FAPPTYP_PROTDLL
192             return FAPPTYP_PROTDLL;
193 #else
194             goto not_there;
195 #endif
196         if (strEQ(name, "T_32BIT"))
197 #ifdef FAPPTYP_32BIT
198             return FAPPTYP_32BIT;
199 #else
200             goto not_there;
201 #endif
202     }
203
204     errno = EINVAL;
205     return 0;
206
207 not_there:
208     errno = ENOENT;
209     return 0;
210 }
211
212 const char* const ptypes[] = { "FS", "DOS", "VIO", "PM", "DETACH" };
213
214 static char *
215 my_type()
216 {
217     int rc;
218     TIB *tib;
219     PIB *pib;
220     
221     if (!(_emx_env & 0x200)) return (char*)ptypes[1]; /* not OS/2. */
222     if (CheckOSError(DosGetInfoBlocks(&tib, &pib))) 
223         return NULL; 
224     
225     return (pib->pib_ultype <= 4 ? (char*)ptypes[pib->pib_ultype] : "UNKNOWN");
226 }
227
228 static ULONG
229 file_type(char *path)
230 {
231     int rc;
232     ULONG apptype;
233     
234     if (!(_emx_env & 0x200)) 
235         croak("file_type not implemented on DOS"); /* not OS/2. */
236     if (CheckOSError(DosQueryAppType(path, &apptype))) {
237         if (rc == ERROR_INVALID_EXE_SIGNATURE) 
238             croak("Invalid EXE signature"); 
239         else if (rc == ERROR_EXE_MARKED_INVALID) {
240             croak("EXE marked invalid"); 
241         }
242         croak("DosQueryAppType err %ld", rc); 
243     }
244     
245     return apptype;
246 }
247
248 /* These use different type of wrapper.  Good to check wrappers. ;-)  */
249 /* XXXX This assumes DOS type return type, without SEVERITY?! */
250 DeclFuncByORD(HSWITCH, myWinQuerySwitchHandle,  ORD_WinQuerySwitchHandle,
251                   (HWND hwnd, PID pid), (hwnd, pid))
252 DeclFuncByORD(ULONG, myWinQuerySwitchEntry,  ORD_WinQuerySwitchEntry,
253                   (HSWITCH hsw, PSWCNTRL pswctl), (hsw, pswctl))
254 DeclFuncByORD(ULONG, myWinSetWindowText,  ORD_WinSetWindowText,
255                   (HWND hwnd, char* text), (hwnd, text))
256 DeclFuncByORD(BOOL, myWinQueryWindowProcess,  ORD_WinQueryWindowProcess,
257                   (HWND hwnd, PPID ppid, PTID ptid), (hwnd, ppid, ptid))
258 DeclFuncByORD(ULONG, XmyWinSwitchToProgram,  ORD_WinSwitchToProgram,
259                   (HSWITCH hsw), (hsw))
260 #define myWinSwitchToProgram(hsw) (!CheckOSError(XmyWinSwitchToProgram(hsw)))
261
262
263
264 DeclWinFunc_CACHE(HWND, QueryWindow, (HWND hwnd, LONG cmd), (hwnd, cmd))
265 DeclWinFunc_CACHE(BOOL, QueryWindowPos, (HWND hwnd, PSWP pswp),
266                   (hwnd, pswp))
267 DeclWinFunc_CACHE(LONG, QueryWindowText,
268                   (HWND hwnd, LONG cchBufferMax, PCH pchBuffer),
269                   (hwnd, cchBufferMax, pchBuffer))
270 DeclWinFunc_CACHE(LONG, QueryClassName, (HWND hwnd, LONG cchMax, PCH pch),
271                   (hwnd, cchMax, pch))
272 DeclWinFunc_CACHE(HWND, QueryFocus, (HWND hwndDesktop), (hwndDesktop))
273 DeclWinFunc_CACHE(BOOL, SetFocus, (HWND hwndDesktop, HWND hwndFocus),
274                   (hwndDesktop, hwndFocus))
275 DeclWinFunc_CACHE(BOOL, ShowWindow, (HWND hwnd, BOOL fShow), (hwnd, fShow))
276 DeclWinFunc_CACHE(BOOL, EnableWindow, (HWND hwnd, BOOL fEnable),
277                       (hwnd, fEnable))
278 DeclWinFunc_CACHE(BOOL, SetWindowPos,
279                   (HWND hwnd, HWND hwndInsertBehind, LONG x, LONG y,
280                    LONG cx, LONG cy, ULONG fl),
281                   (hwnd, hwndInsertBehind, x, y, cx, cy, fl))
282 DeclWinFunc_CACHE(HENUM, BeginEnumWindows, (HWND hwnd), (hwnd))
283 DeclWinFunc_CACHE(BOOL, EndEnumWindows, (HENUM henum), (henum))
284 DeclWinFunc_CACHE(BOOL, EnableWindowUpdate, (HWND hwnd, BOOL fEnable),
285                   (hwnd, fEnable))
286 DeclWinFunc_CACHE(BOOL, SetWindowBits,
287                   (HWND hwnd, LONG index, ULONG flData, ULONG flMask),
288                   (hwnd, index, flData, flMask))
289 DeclWinFunc_CACHE(BOOL, SetWindowPtr, (HWND hwnd, LONG index, PVOID p),
290                   (hwnd, index, p))
291 DeclWinFunc_CACHE(BOOL, SetWindowULong, (HWND hwnd, LONG index, ULONG ul),
292                   (hwnd, index, ul))
293 DeclWinFunc_CACHE(BOOL, SetWindowUShort, (HWND hwnd, LONG index, USHORT us),
294                   (hwnd, index, us))
295 DeclWinFunc_CACHE(HWND, IsChild, (HWND hwnd, HWND hwndParent),
296                   (hwnd, hwndParent))
297 DeclWinFunc_CACHE(HWND, WindowFromId, (HWND hwnd, ULONG id), (hwnd, id))
298 DeclWinFunc_CACHE(HWND, EnumDlgItem, (HWND hwndDlg, HWND hwnd, ULONG code),
299                   (hwndDlg, hwnd, code))
300 DeclWinFunc_CACHE(HWND, QueryDesktopWindow, (HAB hab, HDC hdc), (hab, hdc));
301 DeclWinFunc_CACHE(BOOL, SetActiveWindow, (HWND hwndDesktop, HWND hwnd),
302                   (hwndDesktop, hwnd));
303
304 /* These functions may return 0 on success; check $^E/Perl_rc on res==0: */
305 DeclWinFunc_CACHE_resetError(PVOID, QueryWindowPtr, (HWND hwnd, LONG index),
306                              (hwnd, index))
307 DeclWinFunc_CACHE_resetError(ULONG, QueryWindowULong, (HWND hwnd, LONG index),
308                              (hwnd, index))
309 DeclWinFunc_CACHE_resetError(SHORT, QueryWindowUShort, (HWND hwnd, LONG index),
310                              (hwnd, index))
311 DeclWinFunc_CACHE_resetError(LONG,  QueryWindowTextLength, (HWND hwnd), (hwnd))
312 DeclWinFunc_CACHE_resetError(HWND,  QueryActiveWindow, (HWND hwnd), (hwnd))
313 DeclWinFunc_CACHE_resetError(BOOL, PostMsg,
314                              (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2),
315                              (hwnd, msg, mp1, mp2))
316 DeclWinFunc_CACHE_resetError(HWND, GetNextWindow, (HENUM henum), (henum))
317 DeclWinFunc_CACHE_resetError(BOOL, IsWindowEnabled, (HWND hwnd), (hwnd))
318 DeclWinFunc_CACHE_resetError(BOOL, IsWindowVisible, (HWND hwnd), (hwnd))
319 DeclWinFunc_CACHE_resetError(BOOL, IsWindowShowing, (HWND hwnd), (hwnd))
320
321 /* No die()ing on error */
322 DeclWinFunc_CACHE_survive(BOOL, IsWindow, (HAB hab, HWND hwnd), (hab, hwnd))
323
324 /* These functions are called frow complicated wrappers: */
325 ULONG (*pWinQuerySwitchList) (HAB hab, PSWBLOCK pswblk, ULONG usDataLength);
326 ULONG (*pWinChangeSwitchEntry) (HSWITCH hsw, __const__ SWCNTRL *pswctl);
327 HWND (*pWinWindowFromPoint)(HWND hwnd, __const__ POINTL *pptl, BOOL fChildren);
328
329
330 /* These functions have different names/signatures than what is
331    declared above */
332 #define QueryFocusWindow QueryFocus
333 #define FocusWindow_set(hwndFocus, hwndDesktop) SetFocus(hwndDesktop, hwndFocus)
334 #define WindowPos_set(hwnd, x, y, fl, cx, cy, hwndInsertBehind) \
335         SetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl)
336 #define myWinQueryWindowPtr(hwnd, i)    ((ULONG)QueryWindowPtr(hwnd, i))
337
338 int
339 WindowText_set(HWND hwnd, char* text)
340 {
341    return !CheckWinError(myWinSetWindowText(hwnd, text));
342 }
343
344 SV *
345 myQueryWindowText(HWND hwnd)
346 {
347     LONG l = QueryWindowTextLength(hwnd), len;
348     SV *sv;
349     STRLEN n_a;
350
351     if (l == 0) {
352         if (Perl_rc)            /* Last error */
353             return &PL_sv_undef;
354         return &PL_sv_no;
355     }
356     sv = newSVpvn("", 0);
357     SvGROW(sv, l + 1);
358     len = WinQueryWindowText(hwnd, l + 1, SvPV_force(sv, n_a));
359     if (len != l) {
360         Safefree(sv);
361         croak("WinQueryWindowText() uncompatible with WinQueryWindowTextLength()");
362     }
363     SvCUR_set(sv, l);
364     return sv;
365 }
366
367 SWP
368 QueryWindowSWP_(HWND hwnd)
369 {
370     SWP swp;
371
372     if (!QueryWindowPos(hwnd, &swp))
373         croak("WinQueryWindowPos() error");
374     return swp;
375 }
376
377 SV *
378 QueryWindowSWP(HWND hwnd)
379 {
380     SWP swp = QueryWindowSWP_(hwnd);
381
382     return newSVpvn((char*)&swp, sizeof(swp));
383 }
384
385 SV *
386 myQueryClassName(HWND hwnd)
387 {
388     SV *sv = newSVpvn("",0);
389     STRLEN l = 46, len = 0, n_a;
390
391     while (l + 1 >= len) {
392         if (len)
393             len = 2*len + 10;           /* Grow quick */
394         else
395             len = l + 2;
396         SvGROW(sv, len);
397         l = QueryClassName(hwnd, len, SvPV_force(sv, n_a));
398     }
399     SvCUR_set(sv, l);
400     return sv;
401 }
402
403 HWND
404 WindowFromPoint(long x, long y, HWND hwnd, BOOL fChildren)
405 {
406     POINTL ppl;
407
408     ppl.x = x; ppl.y = y;
409     if (!pWinWindowFromPoint)
410         AssignFuncPByORD(pWinWindowFromPoint, ORD_WinWindowFromPoint);
411     return SaveWinError(pWinWindowFromPoint(hwnd, &ppl, fChildren));
412 }
413
414 static void
415 fill_swentry(SWENTRY *swentryp, HWND hwnd, PID pid)
416 {
417          int rc;
418          HSWITCH hSwitch;    
419
420          if (!(_emx_env & 0x200)) 
421              croak("switch_entry not implemented on DOS"); /* not OS/2. */
422          if (CheckWinError(hSwitch = 
423                            myWinQuerySwitchHandle(hwnd, pid)))
424              croak("WinQuerySwitchHandle: %s", os2error(Perl_rc));
425          swentryp->hswitch = hSwitch;
426          if (CheckOSError(myWinQuerySwitchEntry(hSwitch, &swentryp->swctl)))
427              croak("WinQuerySwitchEntry err %ld", rc);
428 }
429
430 static void
431 fill_swentry_default(SWENTRY *swentryp)
432 {
433         fill_swentry(swentryp, NULLHANDLE, getpid());
434 }
435
436 /* static ULONG (* APIENTRY16 pDosSmSetTitle)(ULONG, PSZ); */
437 ULONG _THUNK_FUNCTION(DosSmSetTitle)(ULONG, PSZ);
438
439 #if 0                   /*  Does not work.  */
440 static ULONG (*pDosSmSetTitle)(ULONG, PSZ);
441
442 static void
443 sesmgr_title_set(char *s)
444 {
445     SWENTRY swentry;
446     static HMODULE hdosc = 0;
447     BYTE buf[20];
448     long rc;
449
450     fill_swentry_default(&swentry);
451     if (!pDosSmSetTitle || !hdosc) {
452         if (CheckOSError(DosLoadModule(buf, sizeof buf, "sesmgr", &hdosc)))
453             croak("Cannot load SESMGR: no `%s'", buf);
454         if (CheckOSError(DosQueryProcAddr(hdosc, 0, "DOSSMSETTITLE",
455                                           (PFN*)&pDosSmSetTitle)))
456             croak("Cannot load SESMGR.DOSSMSETTITLE, err=%ld", rc);
457     }
458 /*     (pDosSmSetTitle)(swcntrl.idSession,s); */
459     rc = ((USHORT)
460           (_THUNK_PROLOG (2+4);
461            _THUNK_SHORT (swcntrl.idSession);
462            _THUNK_FLAT (s);
463            _THUNK_CALLI (*pDosSmSetTitle)));
464     if (CheckOSError(rc))
465         warn("*DOSSMSETTITLE: err=%ld, ses=%ld, addr=%x, *paddr=%x", 
466              rc, swcntrl.idSession, &_THUNK_FUNCTION(DosSmSetTitle),
467              pDosSmSetTitle);
468 }
469
470 #else /* !0 */
471
472 static bool
473 sesmgr_title_set(char *s)
474 {
475     SWENTRY swentry;
476     long rc;
477
478     fill_swentry_default(&swentry);
479     rc = ((USHORT)
480           (_THUNK_PROLOG (2+4);
481            _THUNK_SHORT (swentry.swctl.idSession);
482            _THUNK_FLAT (s);
483            _THUNK_CALL (DosSmSetTitle)));
484 #if 0
485     if (CheckOSError(rc))
486         warn("DOSSMSETTITLE: err=%ld, ses=%ld, addr=%x", 
487              rc, swcntrl.idSession, _THUNK_FUNCTION(DosSmSetTitle));
488 #endif
489     return !CheckOSError(rc);
490 }
491 #endif /* !0 */
492
493 #if 0                   /*  Does not work.  */
494 USHORT _THUNK_FUNCTION(Win16SetTitle) ();
495
496 static void
497 set_title2(char *s)
498 {
499     long rc;
500
501     rc = ((USHORT)
502           (_THUNK_PROLOG (4);
503            _THUNK_FLAT (s);
504            _THUNK_CALL (Win16SetTitle)));
505     if (CheckWinError(rc))
506         warn("Win16SetTitle: err=%ld", rc);
507 }
508 #endif
509
510 SV *
511 process_swentry(unsigned long pid, unsigned long hwnd)
512 {
513     SWENTRY swentry;
514
515     if (!(_emx_env & 0x200)) 
516              croak("process_swentry not implemented on DOS"); /* not OS/2. */
517     fill_swentry(&swentry, hwnd, pid);
518     return newSVpvn((char*)&swentry, sizeof(swentry));
519 }
520
521 SV *
522 swentries_list()
523 {
524     int num, n = 0;
525     STRLEN n_a;
526     PSWBLOCK pswblk;
527     SV *sv = newSVpvn("",0);
528
529     if (!(_emx_env & 0x200)) 
530              croak("swentries_list not implemented on DOS"); /* not OS/2. */
531     if (!pWinQuerySwitchList)
532         AssignFuncPByORD(pWinQuerySwitchList, ORD_WinQuerySwitchList);
533     num = pWinQuerySwitchList(0, NULL, 0);      /* HAB is not required */
534     if (!num)
535         croak("(Unknown) error during WinQuerySwitchList()");
536     /* Allow one extra entry to allow overflow detection (may happen
537         if the list has been changed). */
538     while (num > n) {
539         if (n == 0)
540             n = num + 1;
541         else
542             n = 2*num + 10;                     /* Enlarge quickly */
543         SvGROW(sv, sizeof(ULONG) + sizeof(SWENTRY) * n + 1);
544         pswblk = (PSWBLOCK) SvPV_force(sv, n_a);
545         num = pWinQuerySwitchList(0, pswblk, SvLEN(sv));
546     }
547     SvCUR_set(sv, sizeof(ULONG) + sizeof(SWENTRY) * num);
548     *SvEND(sv) = 0;
549     return sv;
550 }
551
552 SWENTRY
553 swentry( char *title, HWND sw_hwnd, HWND icon_hwnd, HPROGRAM owner_phandle,
554          PID owner_pid, ULONG owner_sid, ULONG visible, ULONG nonswitchable,
555          ULONG jumpable, ULONG ptype, HSWITCH sw_entry)
556 {
557   SWENTRY e;
558
559   strncpy(e.swctl.szSwtitle, title, MAXNAMEL);
560   e.swctl.szSwtitle[60] = 0;
561   e.swctl.hwnd = sw_hwnd;
562   e.swctl.hwndIcon = icon_hwnd;
563   e.swctl.hprog = owner_phandle;
564   e.swctl.idProcess = owner_pid;
565   e.swctl.idSession = owner_sid;
566   e.swctl.uchVisibility = ((visible ? SWL_VISIBLE : SWL_INVISIBLE)
567                            | (nonswitchable ? SWL_GRAYED : 0));
568   e.swctl.fbJump = (jumpable ? SWL_JUMPABLE : 0);
569   e.swctl.bProgType = ptype;
570   e.hswitch = sw_entry;
571   return e;
572 }
573
574 SV *
575 create_swentry( char *title, HWND owner_hwnd, HWND icon_hwnd, HPROGRAM owner_phandle,
576          PID owner_pid, ULONG owner_sid, ULONG visible, ULONG nonswitchable,
577          ULONG jumpable, ULONG ptype, HSWITCH sw_entry)
578 {
579     SWENTRY e = swentry(title, owner_hwnd, icon_hwnd, owner_phandle, owner_pid,
580                         owner_sid, visible, nonswitchable, jumpable, ptype,
581                         sw_entry);
582
583     return newSVpvn((char*)&e, sizeof(e));
584 }
585
586 int
587 change_swentrysw(SWENTRY *sw)
588 {
589     ULONG rc;                   /* For CheckOSError */
590
591     if (!(_emx_env & 0x200)) 
592              croak("change_entry() not implemented on DOS"); /* not OS/2. */
593     if (!pWinChangeSwitchEntry)
594         AssignFuncPByORD(pWinChangeSwitchEntry, ORD_WinChangeSwitchEntry);
595     return !CheckOSError(pWinChangeSwitchEntry(sw->hswitch, &sw->swctl));
596 }
597
598 int
599 change_swentry(SV *sv)
600 {
601     STRLEN l;
602     PSWENTRY pswentry = (PSWENTRY)SvPV(sv, l);
603
604     if (l != sizeof(SWENTRY))
605         croak("Wrong structure size %ld!=%ld in change_swentry()", (long)l, (long)sizeof(SWENTRY));
606     return change_swentrysw(pswentry);
607 }
608
609
610 #define swentry_size()          (sizeof(SWENTRY))
611
612 void
613 getscrsize(int *wp, int *hp)
614 {
615     int i[2];
616
617     _scrsize(i);
618     *wp = i[0];
619     *hp = i[1];
620 }
621
622 /* Force vio to not cross 64K-boundary: */
623 #define VIO_FROM_VIOB                   \
624     vio = viob;                         \
625     if (!_THUNK_PTR_STRUCT_OK(vio))     \
626         vio++
627
628 bool
629 scrsize_set(int w, int h)
630 {
631     VIOMODEINFO viob[2], *vio;
632     ULONG rc;
633
634     VIO_FROM_VIOB;
635
636     if (h == -9999)
637         h = w, w = 0;
638     vio->cb = sizeof(*vio);
639     if (CheckOSError(VioGetMode( vio, 0 )))
640         return 0;
641
642     if( w > 0 )
643       vio->col = (USHORT)w;
644
645     if( h > 0 )
646       vio->row = (USHORT)h;
647
648     vio->cb = 8;
649     if (CheckOSError(VioSetMode( vio, 0 )))
650         return 0;
651     return 1;
652 }
653
654 void
655 cursor(int *sp, int *ep, int *wp, int *ap)
656 {
657     VIOCURSORINFO viob[2], *vio;
658     ULONG rc;
659
660     VIO_FROM_VIOB;
661
662     if (CheckOSError(VioGetCurType( vio, 0 )))
663         croak("VioGetCurType() error");
664
665     *sp = vio->yStart;
666     *ep = vio->cEnd;
667     *wp = vio->cx;
668     *ep = vio->attr;
669 }
670
671 bool
672 cursor__(int is_a)
673 {
674     int s,e,w,a;
675
676     cursor(&s, &e, &w, &a);
677     if (is_a)
678         return a;
679     else
680         return w;
681 }
682
683 bool
684 cursor_set(int s, int e, int w, int a)
685 {
686     VIOCURSORINFO viob[2], *vio;
687     ULONG rc;
688
689     VIO_FROM_VIOB;
690
691     vio->yStart = s;
692     vio->cEnd = e;
693     vio->cx = w;
694     vio->attr = a;
695     return !CheckOSError(VioSetCurType( vio, 0 ));
696 }
697
698 static int
699 bufsize(void)
700 {
701 #if 1
702     VIOMODEINFO viob[2], *vio;
703     ULONG rc;
704
705     VIO_FROM_VIOB;
706
707     vio->cb = sizeof(*vio);
708     if (CheckOSError(VioGetMode( vio, 0 )))
709         croak("Can't get size of buffer for screen");
710 #if 0   /* buf=323552247, full=1118455, partial=0 */
711     croak("Lengths: buf=%d, full=%d, partial=%d",vio->buf_length,vio->full_length,vio->partial_length);
712     return newSVpvn((char*)vio->buf_addr, vio->full_length);
713 #endif
714     return vio->col * vio->row * 2;     /* How to get bytes/cell?  2 or 4? */
715 #else   /* 0 */
716     int i[2];
717
718     _scrsize(i);
719     return i[0]*i[1]*2;
720 #endif  /* 0 */
721 }
722     
723 SV *
724 screen(void)
725 {
726     ULONG rc;
727     USHORT bufl = bufsize();
728     char b[(1<<16) * 3]; /* This/3 is enough for 16-bit calls, we need
729                             2x overhead due to 2 vs 4 issue, and extra
730                             64K due to alignment logic */
731     char *buf = b;
732     
733     if (((ULONG)buf) & 0xFFFF)
734         buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
735     if ((sizeof(b) - (buf - b)) < 2*bufl)
736         croak("panic: VIO buffer allocation");
737     if (CheckOSError(VioReadCellStr( buf, &bufl, 0, 0, 0 )))
738         return &PL_sv_undef;
739     return newSVpvn(buf,bufl);
740 }
741
742 bool
743 screen_set(SV *sv)
744 {
745     ULONG rc;
746     STRLEN l = SvCUR(sv), bufl = bufsize();
747     char b[(1<<16) * 2]; /* This/2 is enough for 16-bit calls, we need
748                             extra 64K due to alignment logic */
749     char *buf = b;
750     
751     if (((ULONG)buf) & 0xFFFF)
752         buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
753     if (!SvPOK(sv) || ((l != bufl) && (l != 2*bufl)))
754         croak("Wrong size %d of saved screen data", SvCUR(sv));
755     if ((sizeof(b) - (buf - b)) < l)
756         croak("panic: VIO buffer allocation");
757     Copy(SvPV(sv,l), buf, bufl, char);
758     if (CheckOSError(VioWrtCellStr( buf, bufl, 0, 0, 0 )))
759         return 0;
760     return 1;
761 }
762
763 int
764 process_codepages()
765 {
766     ULONG cps[4], cp, rc;
767
768     if (CheckOSError(DosQueryCp( sizeof(cps), cps, &cp )))
769         croak("DosQueryCp() error");
770     return cp;
771 }
772
773 int
774 out_codepage()
775 {
776     USHORT cp, rc;
777
778     if (CheckOSError(VioGetCp( 0, &cp, 0 )))
779         croak("VioGetCp() error");
780     return cp;
781 }
782
783 bool
784 out_codepage_set(int cp)
785 {
786     USHORT rc;
787
788     return !(CheckOSError(VioSetCp( 0, cp, 0 )));
789 }
790
791 int
792 in_codepage()
793 {
794     USHORT cp, rc;
795
796     if (CheckOSError(KbdGetCp( 0, &cp, 0 )))
797         croak("KbdGetCp() error");
798     return cp;
799 }
800
801 bool
802 in_codepage_set(int cp)
803 {
804     USHORT rc;
805
806     return !(CheckOSError(KbdSetCp( 0, cp, 0 )));
807 }
808
809 bool
810 process_codepage_set(int cp)
811 {
812     USHORT rc;
813
814     return !(CheckOSError(DosSetProcessCp( cp )));
815 }
816
817 int
818 ppidOf(int pid)
819 {
820   PQTOPLEVEL psi;
821   int ppid;
822
823   if (!pid)
824       return -1;
825   psi = get_sysinfo(pid, QSS_PROCESS);
826   if (!psi)
827       return -1;
828   ppid = psi->procdata->ppid;
829   Safefree(psi);
830   return ppid;
831 }
832
833 int
834 sidOf(int pid)
835 {
836   PQTOPLEVEL psi;
837   int sid;
838
839   if (!pid)
840       return -1;
841   psi = get_sysinfo(pid, QSS_PROCESS);
842   if (!psi)
843       return -1;
844   sid = psi->procdata->sessid;
845   Safefree(psi);
846   return sid;
847 }
848
849 #define ulMPFROMSHORT(i)                ((unsigned long)MPFROMSHORT(i))
850 #define ulMPVOID()                      ((unsigned long)MPVOID)
851 #define ulMPFROMCHAR(i)                 ((unsigned long)MPFROMCHAR(i))
852 #define ulMPFROM2SHORT(x1,x2)           ((unsigned long)MPFROM2SHORT(x1,x2))
853 #define ulMPFROMSH2CH(s, c1, c2)        ((unsigned long)MPFROMSH2CH(s, c1, c2))
854 #define ulMPFROMLONG(x)                 ((unsigned long)MPFROMLONG(x))
855
856 MODULE = OS2::Process           PACKAGE = OS2::Process
857
858 PROTOTYPES: ENABLE
859
860 unsigned long
861 constant(name,arg)
862         char *          name
863         int             arg
864
865 char *
866 my_type()
867
868 U32
869 file_type(path)
870     char *path
871
872 SV *
873 swentry_expand( SV *sv )
874     PPCODE:
875      {
876          STRLEN l;
877          PSWENTRY pswentry = (PSWENTRY)SvPV(sv, l);
878
879          if (l != sizeof(SWENTRY))
880                 croak("Wrong structure size %ld!=%ld in swentry_expand()", (long)l, (long)sizeof(SWENTRY));
881          EXTEND(sp,11);
882          PUSHs(sv_2mortal(newSVpv(pswentry->swctl.szSwtitle, 0)));
883          PUSHs(sv_2mortal(newSVnv(pswentry->swctl.hwnd)));
884          PUSHs(sv_2mortal(newSVnv(pswentry->swctl.hwndIcon)));
885          PUSHs(sv_2mortal(newSViv(pswentry->swctl.hprog)));
886          PUSHs(sv_2mortal(newSViv(pswentry->swctl.idProcess)));
887          PUSHs(sv_2mortal(newSViv(pswentry->swctl.idSession)));
888          PUSHs(sv_2mortal(newSViv(pswentry->swctl.uchVisibility & SWL_VISIBLE)));
889          PUSHs(sv_2mortal(newSViv(pswentry->swctl.uchVisibility & SWL_GRAYED)));
890          PUSHs(sv_2mortal(newSViv(pswentry->swctl.fbJump == SWL_JUMPABLE)));
891          PUSHs(sv_2mortal(newSViv(pswentry->swctl.bProgType)));
892          PUSHs(sv_2mortal(newSViv(pswentry->hswitch)));
893      }
894
895 SV *
896 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)
897 PROTOTYPE: DISABLE
898
899 int
900 change_swentry( SV *sv )
901
902 bool
903 sesmgr_title_set(s)
904     char *s
905
906 SV *
907 process_swentry(unsigned long pid = getpid(), unsigned long hwnd = NULLHANDLE);
908   PROTOTYPE: DISABLE
909
910 int
911 swentry_size()
912
913 SV *
914 swentries_list()
915
916 void
917 ResetWinError()
918
919 int
920 WindowText_set(unsigned long hwndFrame, char *title)
921
922 bool
923 FocusWindow_set(unsigned long hwndFocus, unsigned long hwndDesktop = HWND_DESKTOP)
924
925 bool
926 ShowWindow(unsigned long hwnd, bool fShow = TRUE)
927
928 bool
929 EnableWindow(unsigned long hwnd, bool fEnable = TRUE)
930
931 bool
932 PostMsg(unsigned long hwnd, unsigned long msg, unsigned long mp1 = 0, unsigned long mp2 = 0)
933     C_ARGS: hwnd, msg, (MPARAM)mp1, (MPARAM)mp2
934
935 bool
936 WindowPos_set(unsigned long hwnd, long x, long y, unsigned long fl = SWP_MOVE, long cx = 0, long cy = 0, unsigned long hwndInsertBehind = HWND_TOP)
937   PROTOTYPE: DISABLE
938
939 unsigned long
940 BeginEnumWindows(unsigned long hwnd)
941
942 bool
943 EndEnumWindows(unsigned long henum)
944
945 unsigned long
946 GetNextWindow(unsigned long henum)
947
948 bool
949 IsWindowVisible(unsigned long hwnd)
950
951 bool
952 IsWindowEnabled(unsigned long hwnd)
953
954 bool
955 IsWindowShowing(unsigned long hwnd)
956
957 unsigned long
958 QueryWindow(unsigned long hwnd, long cmd)
959
960 unsigned long
961 IsChild(unsigned long hwnd, unsigned long hwndParent)
962
963 unsigned long
964 WindowFromId(unsigned long hwndParent, unsigned long id)
965
966 unsigned long
967 WindowFromPoint(long x, long y, unsigned long hwnd = HWND_DESKTOP, bool fChildren = TRUE)
968 PROTOTYPE: DISABLE
969
970 unsigned long
971 EnumDlgItem(unsigned long hwndDlg, unsigned long code, unsigned long hwnd = NULLHANDLE)
972    C_ARGS: hwndDlg, hwnd, code
973
974 bool
975 EnableWindowUpdate(unsigned long hwnd, bool fEnable = TRUE)
976
977 bool
978 SetWindowBits(unsigned long hwnd, long index, unsigned long flData, unsigned long flMask)
979
980 bool
981 SetWindowPtr(unsigned long hwnd, long index, unsigned long p)
982     C_ARGS: hwnd, index, (PVOID)p
983
984 bool
985 SetWindowULong(unsigned long hwnd, long index, unsigned long i)
986
987 bool
988 SetWindowUShort(unsigned long hwnd, long index, unsigned short i)
989
990 bool
991 IsWindow(unsigned long hwnd, unsigned long hab = Acquire_hab())
992     C_ARGS: hab, hwnd
993
994 BOOL
995 ActiveWindow_set(unsigned long hwnd, unsigned long hwndDesktop = HWND_DESKTOP)
996     CODE:
997         RETVAL = SetActiveWindow(hwndDesktop, hwnd);
998
999 int
1000 out_codepage()
1001
1002 bool
1003 out_codepage_set(int cp)
1004
1005 int
1006 in_codepage()
1007
1008 bool
1009 in_codepage_set(int cp)
1010
1011 SV *
1012 screen()
1013
1014 bool
1015 screen_set(SV *sv)
1016
1017 SV *
1018 process_codepages()
1019   PPCODE:
1020   {
1021     ULONG cps[4], c, i = 0, rc;
1022
1023     if (CheckOSError(DosQueryCp( sizeof(cps), cps, &c )))
1024         c = 0;
1025     c /= sizeof(ULONG);
1026     if (c >= 3)
1027     EXTEND(sp, c);
1028     while (i < c)
1029         PUSHs(sv_2mortal(newSViv(cps[i++])));
1030   }
1031
1032 bool
1033 process_codepage_set(int cp)
1034
1035 void
1036 cursor(OUTLIST int stp, OUTLIST int ep, OUTLIST int wp, OUTLIST int ap)
1037   PROTOTYPE:
1038
1039 bool
1040 cursor_set(int s, int e, int w = cursor__(0), int a = cursor__(1))
1041
1042 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = myQuery
1043
1044 SV *
1045 myQueryWindowText(unsigned long hwnd)
1046
1047 SV *
1048 myQueryClassName(unsigned long hwnd)
1049
1050 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = Query
1051
1052 unsigned long
1053 QueryFocusWindow(unsigned long hwndDesktop = HWND_DESKTOP)
1054
1055 long
1056 QueryWindowTextLength(unsigned long hwnd)
1057
1058 SV *
1059 QueryWindowSWP(unsigned long hwnd)
1060
1061 unsigned long
1062 QueryWindowULong(unsigned long hwnd, long index)
1063
1064 unsigned short
1065 QueryWindowUShort(unsigned long hwnd, long index)
1066
1067 unsigned long
1068 QueryActiveWindow(unsigned long hwnd = HWND_DESKTOP)
1069
1070 unsigned long
1071 QueryDesktopWindow(unsigned long hab = Acquire_hab(), unsigned long hdc = NULLHANDLE)
1072
1073 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = myWinQuery
1074
1075 unsigned long
1076 myWinQueryWindowPtr(unsigned long hwnd, long index)
1077
1078 NO_OUTPUT BOOL
1079 myWinQueryWindowProcess(unsigned long hwnd, OUTLIST unsigned long pid, OUTLIST unsigned long tid)
1080    PROTOTYPE: $
1081    POSTCALL:
1082         if (CheckWinError(RETVAL))
1083             croak("WindowProcess() error");
1084
1085 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = myWin
1086
1087 int
1088 myWinSwitchToProgram(unsigned long hsw)
1089     PREINIT:
1090         ULONG rc;
1091
1092 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = myWinQuery
1093
1094 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = get
1095
1096 int
1097 getppid()
1098
1099 int
1100 ppidOf(int pid = getpid())
1101
1102 int
1103 sidOf(int pid = getpid())
1104
1105 void
1106 getscrsize(OUTLIST int wp, OUTLIST int hp)
1107   PROTOTYPE:
1108
1109 bool
1110 scrsize_set(int w_or_h, int h = -9999)
1111
1112 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = ul
1113
1114 unsigned long
1115 ulMPFROMSHORT(unsigned short i)
1116
1117 unsigned long
1118 ulMPVOID()
1119
1120 unsigned long
1121 ulMPFROMCHAR(unsigned char i)
1122
1123 unsigned long
1124 ulMPFROM2SHORT(unsigned short x1, unsigned short x2)
1125   PROTOTYPE: DISABLE
1126
1127 unsigned long
1128 ulMPFROMSH2CH(unsigned short s, unsigned char c1, unsigned char c2)
1129   PROTOTYPE: DISABLE
1130
1131 unsigned long
1132 ulMPFROMLONG(unsigned long x)
1133