159ef49a554e199292dcda2207a67c8675f63ded
[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 DeclFuncByORD(HSWITCH, myWinQuerySwitchHandle,  ORD_WinQuerySwitchHandle,
249                   (HWND hwnd, PID pid), (hwnd, pid))
250 DeclFuncByORD(ULONG, myWinQuerySwitchEntry,  ORD_WinQuerySwitchEntry,
251                   (HSWITCH hsw, PSWCNTRL pswctl), (hsw, pswctl))
252 DeclFuncByORD(ULONG, myWinSetWindowText,  ORD_WinSetWindowText,
253                   (HWND hwnd, char* text), (hwnd, text))
254 DeclFuncByORD(BOOL, myWinQueryWindowProcess,  ORD_WinQueryWindowProcess,
255                   (HWND hwnd, PPID ppid, PTID ptid), (hwnd, ppid, ptid))
256
257 DeclFuncByORD(ULONG, XmyWinSwitchToProgram,  ORD_WinSwitchToProgram,
258                   (HSWITCH hsw), (hsw))
259 #define myWinSwitchToProgram(hsw) (!CheckOSError(XmyWinSwitchToProgram(hsw)))
260
261 DeclFuncByORD(HWND, myWinQueryActiveWindow,  ORD_WinQueryActiveWindow,
262                   (HWND hwnd), (hwnd))
263
264
265 ULONG (*pWinQuerySwitchList) (HAB hab, PSWBLOCK pswblk, ULONG usDataLength);
266 ULONG (*pWinChangeSwitchEntry) (HSWITCH hsw, __const__ SWCNTRL *pswctl);
267
268 HWND (*pWinQueryWindow) (HWND hwnd, LONG cmd);
269 BOOL (*pWinQueryWindowPos) (HWND hwnd, PSWP pswp);
270 LONG (*pWinQueryWindowText) (HWND hwnd, LONG cchBufferMax, PCH pchBuffer);
271 LONG (*pWinQueryWindowTextLength) (HWND hwnd);
272 LONG (*pWinQueryClassName) (HWND hwnd, LONG cchMax, PCH pch);
273 HWND (*pWinQueryFocus) (HWND hwndDesktop);
274 BOOL (*pWinSetFocus) (HWND hwndDesktop, HWND hwndFocus);
275 BOOL (*pWinShowWindow) (HWND hwnd, BOOL fShow);
276 BOOL (*pWinPostMsg) (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
277 BOOL (*pWinSetWindowPos) (HWND hwnd, HWND hwndInsertBehind, LONG x, LONG y,
278     LONG cx, LONG cy, ULONG fl);
279 HENUM (*pWinBeginEnumWindows) (HWND hwnd);
280 BOOL (*pWinEndEnumWindows) (HENUM henum);
281 HWND (*pWinGetNextWindow) (HENUM henum);
282 BOOL (*pWinIsWindow) (HAB hab, HWND hwnd);
283 HWND (*pWinQueryWindow) (HWND hwnd, LONG cmd);
284
285 DeclWinFuncByORD(HWND, IsChild,  ORD_WinIsChild,
286                  (HWND hwnd, HWND hwndParent), (hwnd, hwndParent))
287 DeclWinFuncByORD(HWND, WindowFromId,  ORD_WinWindowFromId,
288                  (HWND hwnd, ULONG id), (hwnd, id))
289
290 HWND (*pWinWindowFromPoint)(HWND hwnd, __const__ POINTL *pptl, BOOL fChildren);
291
292 DeclWinFuncByORD(HWND, EnumDlgItem, ORD_WinEnumDlgItem,
293                  (HWND hwndDlg, HWND hwnd, ULONG code), (hwndDlg, hwnd, code));
294
295 int
296 WindowText_set(HWND hwnd, char* text)
297 {
298    return !CheckWinError(myWinSetWindowText(hwnd, text));
299 }
300
301 LONG
302 QueryWindowTextLength(HWND hwnd)
303 {
304     LONG ret;
305
306     if (!pWinQueryWindowTextLength)
307         AssignFuncPByORD(pWinQueryWindowTextLength, ORD_WinQueryWindowTextLength);
308     ret = pWinQueryWindowTextLength(hwnd);
309     CheckWinError(ret);                 /* May put false positive */
310     return ret;
311 }
312
313 SV *
314 QueryWindowText(HWND hwnd)
315 {
316     LONG l = QueryWindowTextLength(hwnd);
317     SV *sv = newSVpvn("", 0);
318     STRLEN n_a;
319
320     if (l == 0)
321         return sv;
322     SvGROW(sv, l + 1);
323     if (!pWinQueryWindowText)
324         AssignFuncPByORD(pWinQueryWindowText, ORD_WinQueryWindowText);
325     CheckWinError(l = pWinQueryWindowText(hwnd, l + 1, SvPV_force(sv, n_a)));
326     SvCUR_set(sv, l);
327     return sv;
328 }
329
330 SWP
331 QueryWindowSWP_(HWND hwnd)
332 {
333     SWP swp;
334
335     if (!pWinQueryWindowPos)
336         AssignFuncPByORD(pWinQueryWindowPos, ORD_WinQueryWindowPos);
337     if (CheckWinError(pWinQueryWindowPos(hwnd, &swp)))
338         croak("WinQueryWindowPos() error");
339     return swp;
340 }
341
342 SV *
343 QueryWindowSWP(HWND hwnd)
344 {
345     SWP swp = QueryWindowSWP_(hwnd);
346
347     return newSVpvn((char*)&swp, sizeof(swp));
348 }
349
350 SV *
351 QueryClassName(HWND hwnd)
352 {
353     SV *sv = newSVpvn("",0);
354     STRLEN l = 46, len = 0, n_a;
355
356     if (!pWinQueryClassName)
357         AssignFuncPByORD(pWinQueryClassName, ORD_WinQueryClassName);
358     while (l + 1 >= len) {
359         if (len)
360             len = 2*len + 10;           /* Grow quick */
361         else
362             len = l + 2;
363         SvGROW(sv, len);
364         l = pWinQueryClassName(hwnd, len, SvPV_force(sv, n_a));
365         CheckWinError(l);
366         SvCUR_set(sv, l);
367     }
368     return sv;
369 }
370
371 HWND
372 QueryFocusWindow(HWND hwndDesktop)
373 {
374     HWND ret;
375
376     if (!pWinQueryFocus)
377         AssignFuncPByORD(pWinQueryFocus, ORD_WinQueryFocus);
378     ret = pWinQueryFocus(hwndDesktop);
379     CheckWinError(ret);
380     return ret;
381 }
382
383 BOOL
384 FocusWindow_set(HWND hwndFocus, HWND hwndDesktop)
385 {
386     if (!pWinSetFocus)
387         AssignFuncPByORD(pWinSetFocus, ORD_WinSetFocus);
388     return !CheckWinError(pWinSetFocus(hwndDesktop, hwndFocus));
389 }
390
391 BOOL
392 ShowWindow(HWND hwnd, BOOL fShow)
393 {
394     if (!pWinShowWindow)
395         AssignFuncPByORD(pWinShowWindow, ORD_WinShowWindow);
396     return !CheckWinError(pWinShowWindow(hwnd, fShow));
397 }
398
399 BOOL
400 PostMsg(HWND hwnd, ULONG msg, ULONG mp1, ULONG mp2)
401 {
402     if (!pWinPostMsg)
403         AssignFuncPByORD(pWinPostMsg, ORD_WinPostMsg);
404     return !CheckWinError(pWinPostMsg(hwnd, msg, (MPARAM)mp1, (MPARAM)mp2));
405 }
406
407 BOOL
408 WindowPos_set(HWND hwnd, LONG x, LONG y, ULONG fl, LONG cx, LONG cy, 
409               HWND hwndInsertBehind)
410 {
411     if (!pWinSetWindowPos)
412         AssignFuncPByORD(pWinSetWindowPos, ORD_WinSetWindowPos);
413     return !CheckWinError(pWinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl));
414 }
415
416 HENUM
417 BeginEnumWindows(HWND hwnd)
418 {
419     if (!pWinBeginEnumWindows)
420         AssignFuncPByORD(pWinBeginEnumWindows, ORD_WinBeginEnumWindows);
421     return SaveWinError(pWinBeginEnumWindows(hwnd));
422 }
423
424 BOOL
425 EndEnumWindows(HENUM henum)
426 {
427     if (!pWinEndEnumWindows)
428         AssignFuncPByORD(pWinEndEnumWindows, ORD_WinEndEnumWindows);
429     return !CheckWinError(pWinEndEnumWindows(henum));
430 }
431
432 HWND
433 GetNextWindow(HENUM henum)
434 {
435     if (!pWinGetNextWindow)
436         AssignFuncPByORD(pWinGetNextWindow, ORD_WinGetNextWindow);
437     return SaveWinError(pWinGetNextWindow(henum));
438 }
439
440 BOOL
441 IsWindow(HWND hwnd, HAB hab)
442 {
443     if (!pWinIsWindow)
444         AssignFuncPByORD(pWinIsWindow, ORD_WinIsWindow);
445     return !CheckWinError(pWinIsWindow(hab, hwnd));
446 }
447
448 HWND
449 QueryWindow(HWND hwnd, LONG cmd)
450 {
451     if (!pWinQueryWindow)
452         AssignFuncPByORD(pWinQueryWindow, ORD_WinQueryWindow);
453     return !CheckWinError(pWinQueryWindow(hwnd, cmd));
454 }
455
456 HWND
457 WindowFromPoint(long x, long y, HWND hwnd, BOOL fChildren)
458 {
459     POINTL ppl;
460
461     ppl.x = x; ppl.y = y;
462     if (!pWinWindowFromPoint)
463         AssignFuncPByORD(pWinWindowFromPoint, ORD_WinWindowFromPoint);
464     return SaveWinError(pWinWindowFromPoint(hwnd, &ppl, fChildren));
465 }
466
467 static void
468 fill_swentry(SWENTRY *swentryp, HWND hwnd, PID pid)
469 {
470          int rc;
471          HSWITCH hSwitch;    
472
473          if (!(_emx_env & 0x200)) 
474              croak("switch_entry not implemented on DOS"); /* not OS/2. */
475          if (CheckWinError(hSwitch = 
476                            myWinQuerySwitchHandle(hwnd, pid)))
477              croak("WinQuerySwitchHandle err %ld", Perl_rc);
478          swentryp->hswitch = hSwitch;
479          if (CheckOSError(myWinQuerySwitchEntry(hSwitch, &swentryp->swctl)))
480              croak("WinQuerySwitchEntry err %ld", rc);
481 }
482
483 static void
484 fill_swentry_default(SWENTRY *swentryp)
485 {
486         fill_swentry(swentryp, NULLHANDLE, getpid());
487 }
488
489 /* static ULONG (* APIENTRY16 pDosSmSetTitle)(ULONG, PSZ); */
490 ULONG _THUNK_FUNCTION(DosSmSetTitle)(ULONG, PSZ);
491
492 #if 0                   /*  Does not work.  */
493 static ULONG (*pDosSmSetTitle)(ULONG, PSZ);
494
495 static void
496 sesmgr_title_set(char *s)
497 {
498     SWENTRY swentry;
499     static HMODULE hdosc = 0;
500     BYTE buf[20];
501     long rc;
502
503     fill_swentry_default(&swentry);
504     if (!pDosSmSetTitle || !hdosc) {
505         if (CheckOSError(DosLoadModule(buf, sizeof buf, "sesmgr", &hdosc)))
506             croak("Cannot load SESMGR: no `%s'", buf);
507         if (CheckOSError(DosQueryProcAddr(hdosc, 0, "DOSSMSETTITLE",
508                                           (PFN*)&pDosSmSetTitle)))
509             croak("Cannot load SESMGR.DOSSMSETTITLE, err=%ld", rc);
510     }
511 /*     (pDosSmSetTitle)(swcntrl.idSession,s); */
512     rc = ((USHORT)
513           (_THUNK_PROLOG (2+4);
514            _THUNK_SHORT (swcntrl.idSession);
515            _THUNK_FLAT (s);
516            _THUNK_CALLI (*pDosSmSetTitle)));
517     if (CheckOSError(rc))
518         warn("*DOSSMSETTITLE: err=%ld, ses=%ld, addr=%x, *paddr=%x", 
519              rc, swcntrl.idSession, &_THUNK_FUNCTION(DosSmSetTitle),
520              pDosSmSetTitle);
521 }
522
523 #else /* !0 */
524
525 static bool
526 sesmgr_title_set(char *s)
527 {
528     SWENTRY swentry;
529     long rc;
530
531     fill_swentry_default(&swentry);
532     rc = ((USHORT)
533           (_THUNK_PROLOG (2+4);
534            _THUNK_SHORT (swentry.swctl.idSession);
535            _THUNK_FLAT (s);
536            _THUNK_CALL (DosSmSetTitle)));
537 #if 0
538     if (CheckOSError(rc))
539         warn("DOSSMSETTITLE: err=%ld, ses=%ld, addr=%x", 
540              rc, swcntrl.idSession, _THUNK_FUNCTION(DosSmSetTitle));
541 #endif
542     return !CheckOSError(rc);
543 }
544 #endif /* !0 */
545
546 #if 0                   /*  Does not work.  */
547 USHORT _THUNK_FUNCTION(Win16SetTitle) ();
548
549 static void
550 set_title2(char *s)
551 {
552     long rc;
553
554     rc = ((USHORT)
555           (_THUNK_PROLOG (4);
556            _THUNK_FLAT (s);
557            _THUNK_CALL (Win16SetTitle)));
558     if (CheckWinError(rc))
559         warn("Win16SetTitle: err=%ld", rc);
560 }
561 #endif
562
563 SV *
564 process_swentry(unsigned long pid, unsigned long hwnd)
565 {
566     SWENTRY swentry;
567
568     if (!(_emx_env & 0x200)) 
569              croak("process_swentry not implemented on DOS"); /* not OS/2. */
570     fill_swentry(&swentry, hwnd, pid);
571     return newSVpvn((char*)&swentry, sizeof(swentry));
572 }
573
574 SV *
575 swentries_list()
576 {
577     int num, n = 0;
578     STRLEN n_a;
579     PSWBLOCK pswblk;
580     SV *sv = newSVpvn("",0);
581
582     if (!(_emx_env & 0x200)) 
583              croak("swentries_list not implemented on DOS"); /* not OS/2. */
584     if (!pWinQuerySwitchList)
585         AssignFuncPByORD(pWinQuerySwitchList, ORD_WinQuerySwitchList);
586     num = pWinQuerySwitchList(0, NULL, 0);      /* HAB is not required */
587     if (!num)
588         croak("(Unknown) error during WinQuerySwitchList()");
589     /* Allow one extra entry to allow overflow detection (may happen
590         if the list has been changed). */
591     while (num > n) {
592         if (n == 0)
593             n = num + 1;
594         else
595             n = 2*num + 10;                     /* Enlarge quickly */
596         SvGROW(sv, sizeof(ULONG) + sizeof(SWENTRY) * n + 1);
597         pswblk = (PSWBLOCK) SvPV_force(sv, n_a);
598         num = pWinQuerySwitchList(0, pswblk, SvLEN(sv));
599     }
600     SvCUR_set(sv, sizeof(ULONG) + sizeof(SWENTRY) * num);
601     *SvEND(sv) = 0;
602     return sv;
603 }
604
605 SWENTRY
606 swentry( char *title, HWND sw_hwnd, HWND icon_hwnd, HPROGRAM owner_phandle,
607          PID owner_pid, ULONG owner_sid, ULONG visible, ULONG nonswitchable,
608          ULONG jumpable, ULONG ptype, HSWITCH sw_entry)
609 {
610   SWENTRY e;
611
612   strncpy(e.swctl.szSwtitle, title, MAXNAMEL);
613   e.swctl.szSwtitle[60] = 0;
614   e.swctl.hwnd = sw_hwnd;
615   e.swctl.hwndIcon = icon_hwnd;
616   e.swctl.hprog = owner_phandle;
617   e.swctl.idProcess = owner_pid;
618   e.swctl.idSession = owner_sid;
619   e.swctl.uchVisibility = ((visible ? SWL_VISIBLE : SWL_INVISIBLE)
620                            | (nonswitchable ? SWL_GRAYED : 0));
621   e.swctl.fbJump = (jumpable ? SWL_JUMPABLE : 0);
622   e.swctl.bProgType = ptype;
623   e.hswitch = sw_entry;
624   return e;
625 }
626
627 SV *
628 create_swentry( char *title, HWND owner_hwnd, HWND icon_hwnd, HPROGRAM owner_phandle,
629          PID owner_pid, ULONG owner_sid, ULONG visible, ULONG nonswitchable,
630          ULONG jumpable, ULONG ptype, HSWITCH sw_entry)
631 {
632     SWENTRY e = swentry(title, owner_hwnd, icon_hwnd, owner_phandle, owner_pid,
633                         owner_sid, visible, nonswitchable, jumpable, ptype,
634                         sw_entry);
635
636     return newSVpvn((char*)&e, sizeof(e));
637 }
638
639 int
640 change_swentrysw(SWENTRY *sw)
641 {
642     ULONG rc;                   /* For CheckOSError */
643
644     if (!(_emx_env & 0x200)) 
645              croak("change_entry() not implemented on DOS"); /* not OS/2. */
646     if (!pWinChangeSwitchEntry)
647         AssignFuncPByORD(pWinChangeSwitchEntry, ORD_WinChangeSwitchEntry);
648     return !CheckOSError(pWinChangeSwitchEntry(sw->hswitch, &sw->swctl));
649 }
650
651 int
652 change_swentry(SV *sv)
653 {
654     STRLEN l;
655     PSWENTRY pswentry = (PSWENTRY)SvPV(sv, l);
656
657     if (l != sizeof(SWENTRY))
658         croak("Wrong structure size %ld!=%ld in change_swentry()", (long)l, (long)sizeof(SWENTRY));
659     return change_swentrysw(pswentry);
660 }
661
662
663 #define swentry_size()          (sizeof(SWENTRY))
664
665 void
666 getscrsize(int *wp, int *hp)
667 {
668     int i[2];
669
670     _scrsize(i);
671     *wp = i[0];
672     *hp = i[1];
673 }
674
675 /* Force vio to not cross 64K-boundary: */
676 #define VIO_FROM_VIOB                   \
677     vio = viob;                         \
678     if (!_THUNK_PTR_STRUCT_OK(vio))     \
679         vio++
680
681 bool
682 scrsize_set(int w, int h)
683 {
684     VIOMODEINFO viob[2], *vio;
685     ULONG rc;
686
687     VIO_FROM_VIOB;
688
689     if (h == -9999)
690         h = w, w = 0;
691     vio->cb = sizeof(*vio);
692     if (CheckOSError(VioGetMode( vio, 0 )))
693         return 0;
694
695     if( w > 0 )
696       vio->col = (USHORT)w;
697
698     if( h > 0 )
699       vio->row = (USHORT)h;
700
701     vio->cb = 8;
702     if (CheckOSError(VioSetMode( vio, 0 )))
703         return 0;
704     return 1;
705 }
706
707 void
708 cursor(int *sp, int *ep, int *wp, int *ap)
709 {
710     VIOCURSORINFO viob[2], *vio;
711     ULONG rc;
712
713     VIO_FROM_VIOB;
714
715     if (CheckOSError(VioGetCurType( vio, 0 )))
716         croak("VioGetCurType() error");
717
718     *sp = vio->yStart;
719     *ep = vio->cEnd;
720     *wp = vio->cx;
721     *ep = vio->attr;
722 }
723
724 bool
725 cursor__(int is_a)
726 {
727     int s,e,w,a;
728
729     cursor(&s, &e, &w, &a);
730     if (is_a)
731         return a;
732     else
733         return w;
734 }
735
736 bool
737 cursor_set(int s, int e, int w, int a)
738 {
739     VIOCURSORINFO viob[2], *vio;
740     ULONG rc;
741
742     VIO_FROM_VIOB;
743
744     vio->yStart = s;
745     vio->cEnd = e;
746     vio->cx = w;
747     vio->attr = a;
748     return !CheckOSError(VioSetCurType( vio, 0 ));
749 }
750
751 static int
752 bufsize(void)
753 {
754 #if 1
755     VIOMODEINFO viob[2], *vio;
756     ULONG rc;
757
758     VIO_FROM_VIOB;
759
760     vio->cb = sizeof(*vio);
761     if (CheckOSError(VioGetMode( vio, 0 )))
762         croak("Can't get size of buffer for screen");
763 #if 0   /* buf=323552247, full=1118455, partial=0 */
764     croak("Lengths: buf=%d, full=%d, partial=%d",vio->buf_length,vio->full_length,vio->partial_length);
765     return newSVpvn((char*)vio->buf_addr, vio->full_length);
766 #endif
767     return vio->col * vio->row * 2;     /* How to get bytes/cell?  2 or 4? */
768 #else   /* 0 */
769     int i[2];
770
771     _scrsize(i);
772     return i[0]*i[1]*2;
773 #endif  /* 0 */
774 }
775     
776 SV *
777 screen(void)
778 {
779     ULONG rc;
780     USHORT bufl = bufsize();
781     char b[(1<<16) * 3]; /* This/3 is enough for 16-bit calls, we need
782                             2x overhead due to 2 vs 4 issue, and extra
783                             64K due to alignment logic */
784     char *buf = b;
785     
786     if (((ULONG)buf) & 0xFFFF)
787         buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
788     if ((sizeof(b) - (buf - b)) < 2*bufl)
789         croak("panic: VIO buffer allocation");
790     if (CheckOSError(VioReadCellStr( buf, &bufl, 0, 0, 0 )))
791         return &PL_sv_undef;
792     return newSVpvn(buf,bufl);
793 }
794
795 bool
796 screen_set(SV *sv)
797 {
798     ULONG rc;
799     STRLEN l = SvCUR(sv), bufl = bufsize();
800     char b[(1<<16) * 2]; /* This/2 is enough for 16-bit calls, we need
801                             extra 64K due to alignment logic */
802     char *buf = b;
803     
804     if (((ULONG)buf) & 0xFFFF)
805         buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
806     if (!SvPOK(sv) || ((l != bufl) && (l != 2*bufl)))
807         croak("Wrong size %d of saved screen data", SvCUR(sv));
808     if ((sizeof(b) - (buf - b)) < l)
809         croak("panic: VIO buffer allocation");
810     Copy(SvPV(sv,l), buf, bufl, char);
811     if (CheckOSError(VioWrtCellStr( buf, bufl, 0, 0, 0 )))
812         return 0;
813     return 1;
814 }
815
816 int
817 process_codepages()
818 {
819     ULONG cps[4], cp, rc;
820
821     if (CheckOSError(DosQueryCp( sizeof(cps), cps, &cp )))
822         croak("DosQueryCp() error");
823     return cp;
824 }
825
826 int
827 out_codepage()
828 {
829     USHORT cp, rc;
830
831     if (CheckOSError(VioGetCp( 0, &cp, 0 )))
832         croak("VioGetCp() error");
833     return cp;
834 }
835
836 bool
837 out_codepage_set(int cp)
838 {
839     USHORT rc;
840
841     return !(CheckOSError(VioSetCp( 0, cp, 0 )));
842 }
843
844 int
845 in_codepage()
846 {
847     USHORT cp, rc;
848
849     if (CheckOSError(KbdGetCp( 0, &cp, 0 )))
850         croak("KbdGetCp() error");
851     return cp;
852 }
853
854 bool
855 in_codepage_set(int cp)
856 {
857     USHORT rc;
858
859     return !(CheckOSError(KbdSetCp( 0, cp, 0 )));
860 }
861
862 bool
863 process_codepage_set(int cp)
864 {
865     USHORT rc;
866
867     return !(CheckOSError(DosSetProcessCp( cp )));
868 }
869
870 int
871 ppidOf(int pid)
872 {
873   PQTOPLEVEL psi;
874   int ppid;
875
876   if (!pid)
877       return -1;
878   psi = get_sysinfo(pid, QSS_PROCESS);
879   if (!psi)
880       return -1;
881   ppid = psi->procdata->ppid;
882   Safefree(psi);
883   return ppid;
884 }
885
886 int
887 sidOf(int pid)
888 {
889   PQTOPLEVEL psi;
890   int sid;
891
892   if (!pid)
893       return -1;
894   psi = get_sysinfo(pid, QSS_PROCESS);
895   if (!psi)
896       return -1;
897   sid = psi->procdata->sessid;
898   Safefree(psi);
899   return sid;
900 }
901
902 MODULE = OS2::Process           PACKAGE = OS2::Process
903
904
905 unsigned long
906 constant(name,arg)
907         char *          name
908         int             arg
909
910 char *
911 my_type()
912
913 U32
914 file_type(path)
915     char *path
916
917 SV *
918 swentry_expand( SV *sv )
919     PPCODE:
920      {
921          STRLEN l;
922          PSWENTRY pswentry = (PSWENTRY)SvPV(sv, l);
923
924          if (l != sizeof(SWENTRY))
925                 croak("Wrong structure size %ld!=%ld in swentry_expand()", (long)l, (long)sizeof(SWENTRY));
926          EXTEND(sp,11);
927          PUSHs(sv_2mortal(newSVpv(pswentry->swctl.szSwtitle, 0)));
928          PUSHs(sv_2mortal(newSVnv(pswentry->swctl.hwnd)));
929          PUSHs(sv_2mortal(newSVnv(pswentry->swctl.hwndIcon)));
930          PUSHs(sv_2mortal(newSViv(pswentry->swctl.hprog)));
931          PUSHs(sv_2mortal(newSViv(pswentry->swctl.idProcess)));
932          PUSHs(sv_2mortal(newSViv(pswentry->swctl.idSession)));
933          PUSHs(sv_2mortal(newSViv(pswentry->swctl.uchVisibility & SWL_VISIBLE)));
934          PUSHs(sv_2mortal(newSViv(pswentry->swctl.uchVisibility & SWL_GRAYED)));
935          PUSHs(sv_2mortal(newSViv(pswentry->swctl.fbJump == SWL_JUMPABLE)));
936          PUSHs(sv_2mortal(newSViv(pswentry->swctl.bProgType)));
937          PUSHs(sv_2mortal(newSViv(pswentry->hswitch)));
938      }
939
940 SV *
941 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)
942
943 int
944 change_swentry( SV *sv )
945
946 bool
947 sesmgr_title_set(s)
948     char *s
949
950 SV *
951 process_swentry(unsigned long pid = getpid(), unsigned long hwnd = NULLHANDLE);
952
953 int
954 swentry_size()
955
956 SV *
957 swentries_list()
958
959 int
960 WindowText_set(unsigned long hwndFrame, char *title)
961
962 bool
963 FocusWindow_set(unsigned long hwndFocus, unsigned long hwndDesktop = HWND_DESKTOP)
964
965 bool
966 ShowWindow(unsigned long hwnd, bool fShow = TRUE)
967
968 bool
969 PostMsg(unsigned long hwnd, unsigned long msg, unsigned long mp1 = 0, unsigned long mp2 = 0)
970
971 bool
972 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)
973
974 unsigned long
975 BeginEnumWindows(unsigned long hwnd)
976
977 bool
978 EndEnumWindows(unsigned long henum)
979
980 unsigned long
981 GetNextWindow(unsigned long henum)
982
983 bool
984 IsWindow(unsigned long hwnd, unsigned long hab = Acquire_hab())
985
986 unsigned long
987 QueryWindow(unsigned long hwnd, long cmd)
988
989 unsigned long
990 IsChild(unsigned long hwnd, unsigned long hwndParent)
991
992 unsigned long
993 WindowFromId(unsigned long hwndParent, unsigned long id)
994
995 unsigned long
996 WindowFromPoint(long x, long y, unsigned long hwnd, bool fChildren = 0)
997
998 unsigned long
999 EnumDlgItem(unsigned long hwndDlg, unsigned long code, unsigned long hwnd = NULLHANDLE)
1000    C_ARGS: hwndDlg, hwnd, code
1001
1002 int
1003 out_codepage()
1004
1005 bool
1006 out_codepage_set(int cp)
1007
1008 int
1009 in_codepage()
1010
1011 bool
1012 in_codepage_set(int cp)
1013
1014 SV *
1015 screen()
1016
1017 bool
1018 screen_set(SV *sv)
1019
1020 SV *
1021 process_codepages()
1022   PPCODE:
1023   {
1024     ULONG cps[4], c, i = 0, rc;
1025
1026     if (CheckOSError(DosQueryCp( sizeof(cps), cps, &c )))
1027         c = 0;
1028     c /= sizeof(ULONG);
1029     if (c >= 3)
1030     EXTEND(sp, c);
1031     while (i < c)
1032         PUSHs(sv_2mortal(newSViv(cps[i++])));
1033   }
1034
1035 bool
1036 process_codepage_set(int cp)
1037
1038 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = Query
1039
1040 unsigned long
1041 QueryFocusWindow(unsigned long hwndDesktop = HWND_DESKTOP)
1042
1043 long
1044 QueryWindowTextLength(unsigned long hwnd)
1045
1046 SV *
1047 QueryWindowText(unsigned long hwnd)
1048
1049 SV *
1050 QueryWindowSWP(unsigned long hwnd)
1051
1052 SV *
1053 QueryClassName(unsigned long hwnd)
1054
1055 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = myWin
1056
1057 NO_OUTPUT BOOL
1058 myWinQueryWindowProcess(unsigned long hwnd, OUTLIST unsigned long pid, OUTLIST unsigned long tid)
1059    POSTCALL:
1060         if (CheckWinError(RETVAL))
1061             croak("QueryWindowProcess() error");
1062
1063 void
1064 cursor(OUTLIST int stp, OUTLIST int ep, OUTLIST int wp, OUTLIST int ap)
1065
1066 bool
1067 cursor_set(int s, int e, int w = cursor__(0), int a = cursor__(1))
1068
1069 int
1070 myWinSwitchToProgram(unsigned long hsw)
1071     PREINIT:
1072         ULONG rc;
1073
1074 unsigned long
1075 myWinQueryActiveWindow(unsigned long hwnd = HWND_DESKTOP)
1076
1077 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = get
1078
1079 int
1080 getppid()
1081
1082 int
1083 ppidOf(int pid = getpid())
1084
1085 int
1086 sidOf(int pid = getpid())
1087
1088 void
1089 getscrsize(OUTLIST int wp, OUTLIST int hp)
1090
1091 bool
1092 scrsize_set(int w_or_h, int h = -9999)