OS/2-specific fixes, round II
[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(BOOL, QueryClipbrdFmtInfo, (HAB hab, ULONG fmt, PULONG prgfFmtInfo), (hab, fmt, prgfFmtInfo));
319 DeclWinFunc_CACHE(ULONG, QueryClipbrdData, (HAB hab, ULONG fmt), (hab, fmt));
320 DeclWinFunc_CACHE(HWND, SetClipbrdViewer, (HAB hab, HWND hwnd), (hab, hwnd));
321 DeclWinFunc_CACHE(HWND, SetClipbrdOwner, (HAB hab, HWND hwnd), (hab, hwnd));
322 DeclWinFunc_CACHE(ULONG, EnumClipbrdFmts, (HAB hab, ULONG fmt), (hab, fmt));
323 DeclWinFunc_CACHE(ATOM, AddAtom, (HATOMTBL hAtomTbl, PCSZ pszAtomName),
324                   (hAtomTbl, pszAtomName));
325 DeclWinFunc_CACHE(ULONG, QueryAtomUsage, (HATOMTBL hAtomTbl, ATOM atom),
326                   (hAtomTbl, atom));
327 DeclWinFunc_CACHE(ULONG, QueryAtomLength, (HATOMTBL hAtomTbl, ATOM atom),
328                   (hAtomTbl, atom));
329 DeclWinFunc_CACHE(ULONG, QueryAtomName,
330                   (HATOMTBL hAtomTbl, ATOM atom, PSZ pchBuffer, ULONG cchBufferMax),
331                   (hAtomTbl, atom, pchBuffer, cchBufferMax));
332 DeclWinFunc_CACHE(HATOMTBL, QuerySystemAtomTable, (VOID), ());
333 DeclWinFunc_CACHE(HATOMTBL, CreateAtomTable, (ULONG initial, ULONG buckets),
334                   (initial, buckets));
335 DeclWinFunc_CACHE(ULONG, MessageBox, (HWND hwndParent, HWND hwndOwner, PCSZ pszText, PCSZ pszCaption, ULONG idWindow, ULONG flStyle), (hwndParent, hwndOwner, pszText, pszCaption, idWindow, flStyle));
336 DeclWinFunc_CACHE(ULONG, MessageBox2,
337                   (HWND hwndParent, HWND hwndOwner, PCSZ pszText,
338                    PCSZ pszCaption, ULONG idWindow, PMB2INFO pmb2info),
339                   (hwndParent, hwndOwner, pszText, pszCaption, idWindow, pmb2info));
340 DeclWinFunc_CACHE(HPOINTER, LoadPointer,
341                   (HWND hwndDesktop, HMODULE hmod, ULONG idres),
342                   (hwndDesktop, hmod, idres));
343 DeclWinFunc_CACHE(HPOINTER, QuerySysPointer,
344                   (HWND hwndDesktop, LONG lId, BOOL fCopy),
345                   (hwndDesktop, lId, fCopy));
346 DeclWinFunc_CACHE(BOOL, Alarm, (HWND hwndDesktop, ULONG rgfType), (hwndDesktop, rgfType));
347 DeclWinFunc_CACHE(BOOL, FlashWindow, (HWND hwndFrame, BOOL fFlash), (hwndFrame, fFlash));
348
349 #if 0           /* Need to have the entry points described in the parent */
350 DeclWinFunc_CACHE(BOOL, QueryClassInfo, (HAB hab, char* pszClassName, PCLASSINFO pClassInfo), (hab, pszClassName, pClassInfo));
351
352 #define _QueryClassInfo(hab, pszClassName, pClassInfo)  \
353         QueryClassInfo(hab, pszClassName, (PCLASSINFO)pClassInfo)
354
355 #endif
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 DeclWinFunc_CACHE_resetError(ATOM, FindAtom, (HATOMTBL hAtomTbl, PCSZ pszAtomName),
382                              (hAtomTbl, pszAtomName));
383 DeclWinFunc_CACHE_resetError(ATOM, DeleteAtom, (HATOMTBL hAtomTbl, ATOM atom),
384                              (hAtomTbl, atom));
385 DeclWinFunc_CACHE_resetError(HATOMTBL, DestroyAtomTable, (HATOMTBL hAtomTbl), (hAtomTbl));
386 DeclWinFunc_CACHE_resetError(HWND, QueryClipbrdViewer, (HAB hab), (hab));
387 DeclWinFunc_CACHE_resetError(HWND, QueryClipbrdOwner, (HAB hab), (hab));
388
389 #define _DeleteAtom             DeleteAtom
390 #define _DestroyAtomTable       DestroyAtomTable
391
392 /* No die()ing on error */
393 DeclWinFunc_CACHE_survive(BOOL, IsWindow, (HAB hab, HWND hwnd), (hab, hwnd))
394
395 /* These functions are called frow complicated wrappers: */
396 ULONG (*pWinQuerySwitchList) (HAB hab, PSWBLOCK pswblk, ULONG usDataLength);
397 ULONG (*pWinChangeSwitchEntry) (HSWITCH hsw, __const__ SWCNTRL *pswctl);
398 HWND (*pWinWindowFromPoint)(HWND hwnd, __const__ POINTL *pptl, BOOL fChildren);
399
400
401 /* These functions have different names/signatures than what is
402    declared above */
403 #define QueryFocusWindow QueryFocus
404 #define FocusWindow_set(hwndFocus, hwndDesktop) SetFocus(hwndDesktop, hwndFocus)
405 #define WindowPos_set(hwnd, x, y, fl, cx, cy, hwndInsertBehind) \
406         SetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl)
407 #define myWinQueryWindowPtr(hwnd, i)    ((ULONG)QueryWindowPtr(hwnd, i))
408 #define _ClipbrdData_set SetClipbrdData
409 #define ClipbrdOwner_set SetClipbrdOwner
410 #define ClipbrdViewer_set SetClipbrdViewer
411
412 int
413 WindowText_set(HWND hwnd, char* text)
414 {
415    return !CheckWinError(myWinSetWindowText(hwnd, text));
416 }
417
418 SV *
419 myQueryWindowText(HWND hwnd)
420 {
421     LONG l = QueryWindowTextLength(hwnd), len;
422     SV *sv;
423     STRLEN n_a;
424
425     if (l == 0) {
426         if (Perl_rc)            /* Last error */
427             return &PL_sv_undef;
428         return &PL_sv_no;
429     }
430     sv = newSVpvn("", 0);
431     SvGROW(sv, l + 1);
432     len = QueryWindowText(hwnd, l + 1, SvPV_force(sv, n_a));
433     if (len != l) {
434         Safefree(sv);
435         croak("WinQueryWindowText() uncompatible with WinQueryWindowTextLength()");
436     }
437     SvCUR_set(sv, l);
438     return sv;
439 }
440
441 SWP
442 QueryWindowSWP_(HWND hwnd)
443 {
444     SWP swp;
445
446     if (!QueryWindowPos(hwnd, &swp))
447         croak("WinQueryWindowPos() error");
448     return swp;
449 }
450
451 SV *
452 QueryWindowSWP(HWND hwnd)
453 {
454     SWP swp = QueryWindowSWP_(hwnd);
455
456     return newSVpvn((char*)&swp, sizeof(swp));
457 }
458
459 SV *
460 myQueryClassName(HWND hwnd)
461 {
462     SV *sv = newSVpvn("",0);
463     STRLEN l = 46, len = 0, n_a;
464
465     while (l + 1 >= len) {
466         if (len)
467             len = 2*len + 10;           /* Grow quick */
468         else
469             len = l + 2;
470         SvGROW(sv, len);
471         l = QueryClassName(hwnd, len, SvPV_force(sv, n_a));
472     }
473     SvCUR_set(sv, l);
474     return sv;
475 }
476
477 HWND
478 WindowFromPoint(long x, long y, HWND hwnd, BOOL fChildren)
479 {
480     POINTL ppl;
481
482     ppl.x = x; ppl.y = y;
483     if (!pWinWindowFromPoint)
484         AssignFuncPByORD(pWinWindowFromPoint, ORD_WinWindowFromPoint);
485     return SaveWinError(pWinWindowFromPoint(hwnd, &ppl, fChildren));
486 }
487
488 static HSWITCH
489 switch_of(HWND hwnd, PID pid)
490 {
491          HSWITCH hSwitch;    
492
493          if (!(_emx_env & 0x200)) 
494              croak("switch_entry not implemented on DOS"); /* not OS/2. */
495          if (CheckWinError(hSwitch = 
496                            myWinQuerySwitchHandle(hwnd, pid)))
497              croak_with_os2error("WinQuerySwitchHandle");
498          return hSwitch;
499 }
500
501
502 static void
503 fill_swentry(SWENTRY *swentryp, HWND hwnd, PID pid)
504 {
505          int rc;
506          HSWITCH hSwitch = switch_of(hwnd, pid);
507
508          swentryp->hswitch = hSwitch;
509          if (CheckOSError(myWinQuerySwitchEntry(hSwitch, &swentryp->swctl)))
510              croak_with_os2error("WinQuerySwitchEntry");
511 }
512
513 static void
514 fill_swentry_default(SWENTRY *swentryp)
515 {
516         fill_swentry(swentryp, NULLHANDLE, getpid());
517 }
518
519 static SV*
520 myWinQueryActiveDesktopPathname()
521 {
522     SV *buf = newSVpv("",0);
523     STRLEN n_a;
524
525     SvGROW(buf, MAXPATHLEN);
526     QueryActiveDesktopPathname(SvPV(buf,n_a), MAXPATHLEN);
527     SvCUR_set(buf, strlen(SvPV(buf, n_a)));
528     return buf;
529 }
530
531 SV *
532 myWinQueryAtomName(ATOM atom, HATOMTBL hAtomTbl)
533 {
534   ULONG len = QueryAtomLength(hAtomTbl, atom);
535
536   if (len) {                    /* Probably always so... */
537     SV *sv = newSVpvn("",0);
538     STRLEN n_a;
539
540     SvGROW(sv, len + 1);
541     len = QueryAtomName(hAtomTbl, atom, SvPV(sv, n_a), len + 1);
542     if (len) {                  /* Probably always so... */
543       SvCUR_set(sv, len);
544       *SvEND(sv) = 0;
545       return sv;
546     }
547     SvREFCNT_dec(sv);
548   }
549   return &PL_sv_undef;
550 }
551
552 #define myWinQueryClipbrdFmtInfo        QueryClipbrdFmtInfo
553
554 /* Put data into shared memory, then call SetClipbrdData */
555 void
556 ClipbrdData_set(SV *sv, int convert_nl, unsigned long fmt, unsigned long rgfFmtInfo, HAB hab)
557 {
558     STRLEN len;
559     char *buf;
560     char *pByte = 0, *s, c;
561     ULONG nls = 0, rc, handle;
562
563     if (rgfFmtInfo & CFI_POINTER) {
564       s = buf = SvPV_force(sv, len);
565       if (convert_nl) {
566         while ((c = *s++)) {
567             if (c == '\r' && *s == '\n')
568                 s++;
569             else if (c == '\n')
570                 nls++;
571         }
572       }
573
574       if (CheckOSError(DosAllocSharedMem((PPVOID)&pByte, 0, len + nls + 1,
575                                        PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE | OBJ_GETTABLE)))
576         croak_with_os2error("ClipbrdData_set: DosAllocSharedMem error");
577
578       if (!nls)
579         memcpy(pByte, buf, len + 1);
580       else {
581         char *t = pByte, *e = buf + len;
582
583         while (buf < e) {
584             c = *t++ = *buf++;
585             if (c == '\n' && (t == pByte + 1 || t[-2] != '\r'))
586                 t[-1] = '\r', *t++ = '\n';
587         }
588       }
589       handle = (ULONG)pByte;
590     } else {
591       handle = (ULONG)SvUV(sv);
592     }
593
594     if (!SetClipbrdData(hab, handle, fmt, rgfFmtInfo)) {
595         if (fmt & CFI_POINTER)
596             DosFreeMem((PPVOID)&pByte);
597         croak_with_os2error("ClipbrdData_set: WinSetClipbrdData error");
598     }
599 }
600
601 ULONG
602 QueryMemoryRegionSize(ULONG addr, ULONG *flagp, ULONG len, I32 interrupt)
603 {
604     ULONG l, f;                         /* Modifiable copy */
605     ULONG rc;
606
607     do {
608         l = len;
609         rc = DosQueryMem((void *)addr, &l, &f);
610     } while ( interrupt ? 0 : rc == ERROR_INTERRUPT );
611
612     /* We assume this is not about addr */
613 /*
614     if (rc == ERROR_INVALID_ADDRESS)
615         return 0xFFFFFFFF;
616 */
617     os2cp_croak(rc,"QueryMemoryRegionSize");
618     if (flagp)
619         *flagp = f;
620     return l;
621 }
622
623 static ULONG
624 default_fmtInfo(ULONG fmt)
625 {
626    switch (fmt) {
627      case CF_PALETTE:   /* Actually, fmtInfo not documented for palette... */
628      case CF_BITMAP:
629      case CF_METAFILE:
630      case CF_DSPBITMAP:
631      case CF_DSPMETAFILE:
632         return CFI_HANDLE;
633      default:
634         return CFI_POINTER;
635    }
636 }
637
638 #if 0
639
640 ULONG
641 myWinMessageBox(HWND hwndParent, HWND hwndOwner, PCSZ pszText, PCSZ pszCaption, ULONG idWindow, ULONG flStyle)
642 {
643     ULONG rc = MessageBox(hwndParent, hwndOwner, pszText, pszCaption,
644                           idWindow, flStyle);
645
646     if (rc == MBID_ERROR)
647         rc = 0;
648     if (CheckWinError(rc))
649         croak_with_os2error("MessageBox");
650     return rc;
651 }
652
653 ULONG
654 myWinMessageBox2(HWND hwndParent, HWND hwndOwner, PCSZ pszText,
655                    PCSZ pszCaption, ULONG idWindow, PMB2INFO pmb2info)
656 {
657     ULONG rc = MessageBox2(hwndParent, hwndOwner, pszText, pszCaption, idWindow, pmb2info);
658
659     if (rc == MBID_ERROR)
660         rc = 0;
661     if (CheckWinError(rc))
662         croak_with_os2error("MessageBox2");
663     return rc;
664 }
665 #endif
666
667 /* static ULONG (* APIENTRY16 pDosSmSetTitle)(ULONG, PSZ); */
668 ULONG _THUNK_FUNCTION(DosSmSetTitle)(ULONG, PSZ);
669
670 #if 0                   /*  Does not work.  */
671 static ULONG (*pDosSmSetTitle)(ULONG, PSZ);
672
673 static void
674 sesmgr_title_set(char *s)
675 {
676     SWENTRY swentry;
677     static HMODULE hdosc = 0;
678     BYTE buf[20];
679     long rc;
680
681     fill_swentry_default(&swentry);
682     if (!pDosSmSetTitle || !hdosc) {
683         if (CheckOSError(DosLoadModule(buf, sizeof buf, "sesmgr", &hdosc)))
684             croak("Cannot load SESMGR: no `%s'", buf);
685         if (CheckOSError(DosQueryProcAddr(hdosc, 0, "DOSSMSETTITLE",
686                                           (PFN*)&pDosSmSetTitle)))
687             croak("Cannot load SESMGR.DOSSMSETTITLE, err=%ld", rc);
688     }
689 /*     (pDosSmSetTitle)(swcntrl.idSession,s); */
690     rc = ((USHORT)
691           (_THUNK_PROLOG (2+4);
692            _THUNK_SHORT (swcntrl.idSession);
693            _THUNK_FLAT (s);
694            _THUNK_CALLI (*pDosSmSetTitle)));
695     if (CheckOSError(rc))
696         warn("*DOSSMSETTITLE: err=%ld, ses=%ld, addr=%x, *paddr=%x", 
697              rc, swcntrl.idSession, &_THUNK_FUNCTION(DosSmSetTitle),
698              pDosSmSetTitle);
699 }
700
701 #else /* !0 */
702
703 static bool
704 sesmgr_title_set(char *s)
705 {
706     SWENTRY swentry;
707     long rc;
708
709     fill_swentry_default(&swentry);
710     rc = ((USHORT)
711           (_THUNK_PROLOG (2+4);
712            _THUNK_SHORT (swentry.swctl.idSession);
713            _THUNK_FLAT (s);
714            _THUNK_CALL (DosSmSetTitle)));
715 #if 0
716     if (CheckOSError(rc))
717         warn("DOSSMSETTITLE: err=%ld, ses=%ld, addr=%x", 
718              rc, swcntrl.idSession, _THUNK_FUNCTION(DosSmSetTitle));
719 #endif
720     return !CheckOSError(rc);
721 }
722 #endif /* !0 */
723
724 #if 0                   /*  Does not work.  */
725 USHORT _THUNK_FUNCTION(Win16SetTitle) ();
726
727 static void
728 set_title2(char *s)
729 {
730     long rc;
731
732     rc = ((USHORT)
733           (_THUNK_PROLOG (4);
734            _THUNK_FLAT (s);
735            _THUNK_CALL (Win16SetTitle)));
736     if (CheckWinError(rc))
737         warn("Win16SetTitle: err=%ld", rc);
738 }
739 #endif
740
741 SV *
742 process_swentry(unsigned long pid, HWND hwnd)
743 {
744     SWENTRY swentry;
745
746     if (!(_emx_env & 0x200)) 
747              croak("process_swentry not implemented on DOS"); /* not OS/2. */
748     fill_swentry(&swentry, hwnd, pid);
749     return newSVpvn((char*)&swentry, sizeof(swentry));
750 }
751
752 SV *
753 swentries_list()
754 {
755     int num, n = 0;
756     STRLEN n_a;
757     PSWBLOCK pswblk;
758     SV *sv = newSVpvn("",0);
759
760     if (!(_emx_env & 0x200)) 
761              croak("swentries_list not implemented on DOS"); /* not OS/2. */
762     if (!pWinQuerySwitchList)
763         AssignFuncPByORD(pWinQuerySwitchList, ORD_WinQuerySwitchList);
764     num = pWinQuerySwitchList(0, NULL, 0);      /* HAB is not required */
765     if (!num)
766         croak("(Unknown) error during WinQuerySwitchList()");
767     /* Allow one extra entry to allow overflow detection (may happen
768         if the list has been changed). */
769     while (num > n) {
770         if (n == 0)
771             n = num + 1;
772         else
773             n = 2*num + 10;                     /* Enlarge quickly */
774         SvGROW(sv, sizeof(ULONG) + sizeof(SWENTRY) * n + 1);
775         pswblk = (PSWBLOCK) SvPV_force(sv, n_a);
776         num = pWinQuerySwitchList(0, pswblk, SvLEN(sv));
777     }
778     SvCUR_set(sv, sizeof(ULONG) + sizeof(SWENTRY) * num);
779     *SvEND(sv) = 0;
780     return sv;
781 }
782
783 SWENTRY
784 swentry( char *title, HWND sw_hwnd, HWND icon_hwnd, HPROGRAM owner_phandle,
785          PID owner_pid, ULONG owner_sid, ULONG visible, ULONG nonswitchable,
786          ULONG jumpable, ULONG ptype, HSWITCH sw_entry)
787 {
788   SWENTRY e;
789
790   strncpy(e.swctl.szSwtitle, title, MAXNAMEL);
791   e.swctl.szSwtitle[60] = 0;
792   e.swctl.hwnd = sw_hwnd;
793   e.swctl.hwndIcon = icon_hwnd;
794   e.swctl.hprog = owner_phandle;
795   e.swctl.idProcess = owner_pid;
796   e.swctl.idSession = owner_sid;
797   e.swctl.uchVisibility = ((visible ? SWL_VISIBLE : SWL_INVISIBLE)
798                            | (nonswitchable ? SWL_GRAYED : 0));
799   e.swctl.fbJump = (jumpable ? SWL_JUMPABLE : 0);
800   e.swctl.bProgType = ptype;
801   e.hswitch = sw_entry;
802   return e;
803 }
804
805 SV *
806 create_swentry( char *title, HWND owner_hwnd, HWND icon_hwnd, HPROGRAM owner_phandle,
807          PID owner_pid, ULONG owner_sid, ULONG visible, ULONG nonswitchable,
808          ULONG jumpable, ULONG ptype, HSWITCH sw_entry)
809 {
810     SWENTRY e = swentry(title, owner_hwnd, icon_hwnd, owner_phandle, owner_pid,
811                         owner_sid, visible, nonswitchable, jumpable, ptype,
812                         sw_entry);
813
814     return newSVpvn((char*)&e, sizeof(e));
815 }
816
817 int
818 change_swentrysw(SWENTRY *sw)
819 {
820     ULONG rc;                   /* For CheckOSError */
821
822     if (!(_emx_env & 0x200)) 
823              croak("change_entry() not implemented on DOS"); /* not OS/2. */
824     if (!pWinChangeSwitchEntry)
825         AssignFuncPByORD(pWinChangeSwitchEntry, ORD_WinChangeSwitchEntry);
826     return !CheckOSError(pWinChangeSwitchEntry(sw->hswitch, &sw->swctl));
827 }
828
829 int
830 change_swentry(SV *sv)
831 {
832     STRLEN l;
833     PSWENTRY pswentry = (PSWENTRY)SvPV(sv, l);
834
835     if (l != sizeof(SWENTRY))
836         croak("Wrong structure size %ld!=%ld in change_swentry()", (long)l, (long)sizeof(SWENTRY));
837     return change_swentrysw(pswentry);
838 }
839
840
841 #define swentry_size()          (sizeof(SWENTRY))
842
843 void
844 getscrsize(int *wp, int *hp)
845 {
846     int i[2];
847
848     _scrsize(i);
849     *wp = i[0];
850     *hp = i[1];
851 }
852
853 /* Force vio to not cross 64K-boundary: */
854 #define VIO_FROM_VIOB                   \
855     vio = viob;                         \
856     if (!_THUNK_PTR_STRUCT_OK(vio))     \
857         vio++
858
859 bool
860 scrsize_set(int w, int h)
861 {
862     VIOMODEINFO viob[2], *vio;
863     ULONG rc;
864
865     VIO_FROM_VIOB;
866
867     if (h == -9999)
868         h = w, w = 0;
869     vio->cb = sizeof(*vio);
870     if (CheckOSError(VioGetMode( vio, 0 )))
871         return 0;
872
873     if( w > 0 )
874       vio->col = (USHORT)w;
875
876     if( h > 0 )
877       vio->row = (USHORT)h;
878
879     vio->cb = 8;
880     if (CheckOSError(VioSetMode( vio, 0 )))
881         return 0;
882     return 1;
883 }
884
885 void
886 cursor(int *sp, int *ep, int *wp, int *ap)
887 {
888     VIOCURSORINFO viob[2], *vio;
889     ULONG rc;
890
891     VIO_FROM_VIOB;
892
893     if (CheckOSError(VioGetCurType( vio, 0 )))
894         croak_with_os2error("VioGetCurType() error");
895
896     *sp = vio->yStart;
897     *ep = vio->cEnd;
898     *wp = vio->cx;
899     *ep = vio->attr;
900 }
901
902 bool
903 cursor__(int is_a)
904 {
905     int s,e,w,a;
906
907     cursor(&s, &e, &w, &a);
908     if (is_a)
909         return a;
910     else
911         return w;
912 }
913
914 bool
915 cursor_set(int s, int e, int w, int a)
916 {
917     VIOCURSORINFO viob[2], *vio;
918     ULONG rc;
919
920     VIO_FROM_VIOB;
921
922     vio->yStart = s;
923     vio->cEnd = e;
924     vio->cx = w;
925     vio->attr = a;
926     return !CheckOSError(VioSetCurType( vio, 0 ));
927 }
928
929 static int
930 bufsize(void)
931 {
932 #if 1
933     VIOMODEINFO viob[2], *vio;
934     ULONG rc;
935
936     VIO_FROM_VIOB;
937
938     vio->cb = sizeof(*vio);
939     if (CheckOSError(VioGetMode( vio, 0 )))
940         croak_with_os2error("Can't get size of buffer for screen");
941 #if 0   /* buf=323552247, full=1118455, partial=0 */
942     croak("Lengths: buf=%d, full=%d, partial=%d",vio->buf_length,vio->full_length,vio->partial_length);
943     return newSVpvn((char*)vio->buf_addr, vio->full_length);
944 #endif
945     return vio->col * vio->row * 2;     /* How to get bytes/cell?  2 or 4? */
946 #else   /* 0 */
947     int i[2];
948
949     _scrsize(i);
950     return i[0]*i[1]*2;
951 #endif  /* 0 */
952 }
953
954 SV*
955 _kbdChar(unsigned int nowait, int handle)
956 {
957     KBDKEYINFO viob[2], *vio;
958     ULONG rc;
959
960     VIO_FROM_VIOB;
961
962     if (nowait > 2)
963         croak("unexpected nowait");
964     if (CheckOSError(nowait == 2
965                      ? KbdPeek( vio, handle )
966                      : KbdCharIn( vio, nowait == 1, handle )))
967         croak_with_os2error("Can't _kbdChar");
968     return newSVpvn((char*)vio, sizeof(*vio));
969 }
970
971 SV*
972 _kbdStatus(int handle)
973 {
974     KBDINFO viob[2], *vio;
975     ULONG rc;
976
977     VIO_FROM_VIOB;
978
979     vio->cb = sizeof(*vio);
980     if (CheckOSError(KbdGetStatus( vio, handle )))
981         croak_with_os2error("Can't _kbdStatus");
982     return newSVpvn((char*)vio, sizeof(*vio));
983 }
984
985 void
986 _kbdStatus_set(SV* sv, int handle)
987 {
988     KBDINFO viob[2], *vio;
989     ULONG rc;
990     STRLEN l;
991     char *s = SvPV(sv, l);
992
993     VIO_FROM_VIOB;
994
995     if (l != sizeof(*vio))
996         croak("unexpected datasize");
997     Copy((KBDINFO*)s, vio, 1, KBDINFO);
998     if (vio->cb != sizeof(*vio))
999         croak("unexpected datasize");
1000     if (CheckOSError(KbdSetStatus( vio, handle )))
1001         croak_with_os2error("Can't kbdStatus_set()");
1002 }
1003
1004 SV*
1005 _vioConfig(int which, int handle)
1006 {
1007     struct {VIOCONFIGINFO i; short a[20];} viob[2], *vio;
1008     ULONG rc;
1009
1010     VIO_FROM_VIOB;
1011
1012     vio->i.cb = 2;
1013     if (CheckOSError(VioGetConfig( which, &vio->i, handle )))
1014         croak_with_os2error("Can't get VIO config size");
1015     if (vio->i.cb > sizeof(*vio))
1016         vio->i.cb = sizeof(*vio);
1017     if (CheckOSError(VioGetConfig( which, &vio->i, handle )))
1018         croak_with_os2error("Can't get VIO config");
1019     return newSVpvn((char*)vio, vio->i.cb);
1020 }
1021
1022 SV*
1023 _vioMode(void)
1024 {
1025     VIOMODEINFO viob[2], *vio;
1026     ULONG rc;
1027
1028     VIO_FROM_VIOB;
1029
1030     vio->cb = sizeof(*vio);
1031     if (CheckOSError(VioGetMode( vio, 0 )))
1032         croak_with_os2error("Can't get VIO mode");
1033     return newSVpvn((char*)vio, sizeof(*vio));
1034 }
1035
1036 void
1037 _vioMode_set(SV* sv)
1038 {
1039     VIOMODEINFO viob[2], *vio;
1040     ULONG rc;
1041     STRLEN l;
1042     char *s = SvPV(sv, l);
1043
1044     VIO_FROM_VIOB;
1045
1046     Copy((VIOMODEINFO*)s, vio, 1, VIOMODEINFO);
1047     if (vio->cb != sizeof(*vio) || l != vio->cb)
1048         croak("unexpected datasize");
1049     if (CheckOSError(VioSetMode( vio, 0 )))
1050         croak_with_os2error("Can't set VIO mode");
1051 }
1052
1053 SV*
1054 vioFont(int type, int *w, int *h) /* 0 for actual RAM font, 1 for ROM font */
1055 {
1056     VIOFONTINFO viob[2], *vio;
1057     ULONG rc;
1058     UCHAR b[1<<17];
1059     UCHAR *buf = b;
1060     SV *sv;
1061
1062     VIO_FROM_VIOB;
1063
1064     /* Should not cross 64K boundaries too: */
1065     if (((ULONG)buf) & 0xFFFF)
1066         buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
1067
1068     vio->cb = sizeof(*vio);
1069     vio->type = type;                   /* BIOS or the loaded font. */
1070     vio->cbData = 0xFFFF;               /* How large is my buffer? */
1071     vio->pbData = _emx_32to16(buf);     /* Wants an 16:16 pointer */
1072     if (CheckOSError(VioGetFont( vio, 0 )))
1073         croak_with_os2error("Can't get VIO font");
1074     *w = vio->cxCell;
1075     *h = vio->cyCell;
1076     return newSVpvn(buf,vio->cbData);
1077 }
1078
1079 void
1080 vioFont_set(SV *sv, int cellwidth, int cellheight, int type)
1081 {
1082     VIOFONTINFO viob[2], *vio;
1083     ULONG rc;
1084     UCHAR b[1<<17];
1085     UCHAR *buf = b;
1086     STRLEN l;
1087     char *s = SvPV(sv, l);
1088
1089     VIO_FROM_VIOB;
1090
1091     /* Should not cross 64K boundaries too: */
1092     if (((ULONG)buf) & 0xFFFF)
1093         buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
1094
1095     if (l > 0xFFFF)
1096         croak("length overflow of VIO font");
1097     if (l != (cellwidth + 7)/8 * cellheight * 256)
1098         warn("unexpected length of VIO font");
1099     vio->cb = sizeof(*vio);
1100     vio->type = type;                   /* BIOS or the loaded font. */
1101     vio->cbData = l;                    /* How large is my buffer? */
1102     vio->pbData = _emx_32to16(buf);     /* Wants an 16:16 pointer */
1103     vio->cxCell = cellwidth;
1104     vio->cyCell = cellheight;
1105     Copy(s, buf, l, char);
1106
1107     if (CheckOSError(VioSetFont( vio, 0 )))
1108         croak_with_os2error("Can't set VIO font");
1109 }
1110
1111 /*
1112   uses use32,os2def,os2base,crt,defs;
1113   var   Plt :Plt256;
1114   const Pal :VioPalState=(Cb:sizeof(VioPalState);rType:0;iFirst:0;
1115     Acolor:($FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF));
1116         CReg:VioColorReg=(Cb:sizeof(VioColorReg);rType:3;FirstColorReg:0;
1117     NumColorRegs:256; ColorRegAddr:@Plt);
1118   var   ii:Pointer;
1119   begin
1120    VioGetState(Pal,0);
1121    Pal.Acolor[09]:=$0F;
1122    Pal.Acolor[10]:=$A;
1123    Pal.Acolor[13]:=$2F;
1124    VioSetState(Pal,0); // ce smena EGA registrov
1125    asm
1126   lea   eax,Plt
1127      call  DosFlatToSel
1128      mov   ii,eax
1129    end;
1130    CReg.ColorRegAddr:=ii;
1131    VioGetState(CReg,0);
1132    Plt[10,0]:=$00;
1133    Plt[10,1]:=$32;
1134    Plt[10,2]:=$2A;
1135    VioSetState(CReg,0); // a ce - VGA registrov
1136   end.
1137 */
1138
1139 typedef union {
1140   VIOPALSTATE pal;
1141   struct { VIOPALSTATE pal; USHORT a[15]; } pal_padded;
1142   VIOOVERSCAN overscan;
1143   VIOINTENSITY intensity;
1144   VIOCOLORREG colorreg;
1145   struct { VIOCOLORREG reg; char rgb[3*256]; } colorreg_padded;
1146   VIOSETULINELOC lineloc;
1147   VIOSETTARGET target;
1148 } my_VIOSTATE;
1149
1150 int
1151 vio_state_size(int what)
1152 {
1153     static const char sizes[] = {
1154         sizeof(VIOPALSTATE),
1155         sizeof(VIOOVERSCAN),
1156         sizeof(VIOINTENSITY),
1157         sizeof(VIOCOLORREG),
1158         6,                              /* Random number: Reserved entry */
1159         sizeof(VIOSETULINELOC),
1160         sizeof(VIOSETTARGET)
1161     };
1162     if (what < 0 || what >= sizeof(sizes))
1163         croak("Unexpected VIO state type");
1164     return sizes[what];
1165 }
1166
1167 SV*
1168 _vioState(int what, int first, int count)
1169 {
1170     my_VIOSTATE viob[2], *vio;
1171     ULONG rc, size = vio_state_size(what);
1172
1173     VIO_FROM_VIOB;
1174
1175     vio->pal.cb = size;
1176     vio->pal.type = what;
1177     if (what == 0) {
1178         vio->pal.iFirst = first;
1179         if (first < 0 || first >= 16)
1180             croak("unexpected palette start value");
1181         if (count < 0 || count > 16)
1182             croak("unexpected palette count");
1183         vio->pal.cb = (size += (count - 1) * sizeof(short));
1184     } else if (what == 3) {
1185         /* Wants an 16:16 pointer */
1186         if (count < 0 || count > 256)
1187             croak("unexpected palette count");
1188         vio->colorreg.colorregaddr = (PCH)_emx_32to16(vio->colorreg_padded.rgb);
1189         vio->colorreg.numcolorregs = count;             /* 256 is max */
1190         vio->colorreg.firstcolorreg = first;
1191         size += 3 * count;
1192     }
1193     if (CheckOSError(VioGetState( (void*)vio, 0 )))
1194         croak_with_os2error("Can't get VIO state");
1195     return newSVpvn((char*)vio, size);
1196 }
1197
1198 void
1199 _vioState_set(SV *sv)
1200 {
1201     my_VIOSTATE viob[2], *ovio = (my_VIOSTATE*)SvPV_nolen(sv), *vio = ovio;
1202     int what = ovio->pal.type, cb = ovio->pal.cb;
1203     ULONG rc, size = vio_state_size(what);
1204     STRLEN l;
1205     char *s = SvPV(sv, l);
1206
1207     VIO_FROM_VIOB;
1208
1209     switch (what) {
1210     case 0:
1211         if ( cb < size || cb > size + 15*sizeof(SHORT) || l != cb)
1212             croak("unexpected datasize");
1213         size = l;
1214         break;
1215     case 3:
1216         if (l != cb + 3 * ovio->colorreg.numcolorregs || cb != size)
1217             croak("unexpected datasize");
1218         size = l;
1219         break;
1220     default:
1221         if (l != cb || l != size )
1222             croak("unexpected datasize");
1223         break;
1224     }
1225     Copy(s, (char*)vio, size, char);
1226     if (what == 3)      /* We expect colors put after VIOCOLORREG */
1227         vio->colorreg.colorregaddr = (PCH)_emx_32to16(vio->colorreg_padded.rgb);
1228
1229     if (CheckOSError(VioSetState( (void*)vio, 0 )))
1230         croak_with_os2error("Can't set VIO state");
1231 }
1232
1233 SV *
1234 screen(void)
1235 {
1236     ULONG rc;
1237     USHORT bufl = bufsize();
1238     char b[(1<<16) * 3]; /* This/3 is enough for 16-bit calls, we need
1239                             2x overhead due to 2 vs 4 issue, and extra
1240                             64K due to alignment logic */
1241     char *buf = b;
1242     
1243     if (((ULONG)buf) & 0xFFFF)
1244         buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
1245     if ((sizeof(b) - (buf - b)) < 2*bufl)
1246         croak("panic: VIO buffer allocation");
1247     if (CheckOSError(VioReadCellStr( buf, &bufl, 0, 0, 0 )))
1248         return &PL_sv_undef;
1249     return newSVpvn(buf,bufl);
1250 }
1251
1252 bool
1253 screen_set(SV *sv)
1254 {
1255     ULONG rc;
1256     STRLEN l = SvCUR(sv), bufl = bufsize();
1257     char b[(1<<16) * 2]; /* This/2 is enough for 16-bit calls, we need
1258                             extra 64K due to alignment logic */
1259     char *buf = b;
1260     
1261     if (((ULONG)buf) & 0xFFFF)
1262         buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
1263     if (!SvPOK(sv) || ((l != bufl) && (l != 2*bufl)))
1264         croak("Wrong size %d of saved screen data", SvCUR(sv));
1265     if ((sizeof(b) - (buf - b)) < l)
1266         croak("panic: VIO buffer allocation");
1267     Copy(SvPV(sv,l), buf, bufl, char);
1268     if (CheckOSError(VioWrtCellStr( buf, bufl, 0, 0, 0 )))
1269         return 0;
1270     return 1;
1271 }
1272
1273 int
1274 process_codepages()
1275 {
1276     ULONG cps[4], cp, rc;
1277
1278     if (CheckOSError(DosQueryCp( sizeof(cps), cps, &cp )))
1279         croak_with_os2error("DosQueryCp()");
1280     return cp;
1281 }
1282
1283 int
1284 out_codepage()
1285 {
1286     USHORT cp, rc;
1287
1288     if (CheckOSError(VioGetCp( 0, &cp, 0 )))
1289         croak_with_os2error("VioGetCp()");
1290     return cp;
1291 }
1292
1293 bool
1294 out_codepage_set(int cp)
1295 {
1296     USHORT rc;
1297
1298     return !(CheckOSError(VioSetCp( 0, cp, 0 )));
1299 }
1300
1301 int
1302 in_codepage()
1303 {
1304     USHORT cp, rc;
1305
1306     if (CheckOSError(KbdGetCp( 0, &cp, 0 )))
1307         croak_with_os2error("KbdGetCp()");
1308     return cp;
1309 }
1310
1311 bool
1312 in_codepage_set(int cp)
1313 {
1314     USHORT rc;
1315
1316     return !(CheckOSError(KbdSetCp( 0, cp, 0 )));
1317 }
1318
1319 bool
1320 process_codepage_set(int cp)
1321 {
1322     USHORT rc;
1323
1324     return !(CheckOSError(DosSetProcessCp( cp )));
1325 }
1326
1327 int
1328 ppidOf(int pid)
1329 {
1330   PQTOPLEVEL psi;
1331   int ppid;
1332
1333   if (!pid)
1334       return -1;
1335   psi = get_sysinfo(pid, QSS_PROCESS);
1336   if (!psi)
1337       return -1;
1338   ppid = psi->procdata->ppid;
1339   Safefree(psi);
1340   return ppid;
1341 }
1342
1343 int
1344 sidOf(int pid)
1345 {
1346   PQTOPLEVEL psi;
1347   int sid;
1348
1349   if (!pid)
1350       return -1;
1351   psi = get_sysinfo(pid, QSS_PROCESS);
1352   if (!psi)
1353       return -1;
1354   sid = psi->procdata->sessid;
1355   Safefree(psi);
1356   return sid;
1357 }
1358
1359 STRLEN
1360 StrLen(ULONG addr, ULONG lim, I32 unitsize)
1361 {
1362     switch (unitsize) {
1363       case 1:
1364         {
1365             char *s = (char *)addr;
1366             char *s1 = s, *e = (char *)(addr + lim);
1367
1368             while (s < e && *s)
1369                 s++;
1370             return s - s1;
1371         }
1372         break;
1373       case 2:
1374         {
1375             short *s = (short *)addr;
1376             short *s1 = s, *e = (short *)(addr + lim);
1377
1378             while (s < e && *s)
1379                 s++;
1380             return (char*)s - (char*)s1;
1381         }
1382         break;
1383       case 4:
1384         {
1385             int *s = (int *)addr;
1386             int *s1 = s, *e = (int *)(addr + lim);
1387
1388             while (s < e && *s)
1389                 s++;
1390             return (char*)s - (char*)s1;
1391         }
1392         break;
1393       case 8:
1394         {
1395             long long *s = (long long *)addr;
1396             long long *s1 = s, *e = (long long *)(addr + lim);
1397
1398             while (s < e && *s)
1399                 s++;
1400             return (char*)s - (char*)s1;
1401         }
1402         break;
1403       default:
1404         croak("StrLen: unknown unitsize %d", (int)unitsize);
1405     }
1406 }
1407
1408 #define ulMPFROMSHORT(i)                ((unsigned long)MPFROMSHORT(i))
1409 #define ulMPVOID()                      ((unsigned long)MPVOID)
1410 #define ulMPFROMCHAR(i)                 ((unsigned long)MPFROMCHAR(i))
1411 #define ulMPFROM2SHORT(x1,x2)           ((unsigned long)MPFROM2SHORT(x1,x2))
1412 #define ulMPFROMSH2CH(s, c1, c2)        ((unsigned long)MPFROMSH2CH(s, c1, c2))
1413 #define ulMPFROMLONG(x)                 ((unsigned long)MPFROMLONG(x))
1414
1415 #define _MessageBox                     MessageBox
1416 #define _MessageBox2                    MessageBox2
1417
1418 MODULE = OS2::Process           PACKAGE = OS2::Process
1419
1420 PROTOTYPES: ENABLE
1421
1422 unsigned long
1423 constant(name,arg)
1424         char *          name
1425         int             arg
1426
1427 char *
1428 my_type()
1429
1430 U32
1431 file_type(path)
1432     char *path
1433
1434 SV *
1435 swentry_expand( SV *sv )
1436     PPCODE:
1437      {
1438          STRLEN l;
1439          PSWENTRY pswentry = (PSWENTRY)SvPV(sv, l);
1440
1441          if (l != sizeof(SWENTRY))
1442                 croak("Wrong structure size %ld!=%ld in swentry_expand()", (long)l, (long)sizeof(SWENTRY));
1443          EXTEND(sp,11);
1444          PUSHs(sv_2mortal(newSVpv(pswentry->swctl.szSwtitle, 0)));
1445          PUSHs(sv_2mortal(newSVnv(pswentry->swctl.hwnd)));
1446          PUSHs(sv_2mortal(newSVnv(pswentry->swctl.hwndIcon)));
1447          PUSHs(sv_2mortal(newSViv(pswentry->swctl.hprog)));
1448          PUSHs(sv_2mortal(newSViv(pswentry->swctl.idProcess)));
1449          PUSHs(sv_2mortal(newSViv(pswentry->swctl.idSession)));
1450          PUSHs(sv_2mortal(newSViv(pswentry->swctl.uchVisibility & SWL_VISIBLE)));
1451          PUSHs(sv_2mortal(newSViv(pswentry->swctl.uchVisibility & SWL_GRAYED)));
1452          PUSHs(sv_2mortal(newSViv(pswentry->swctl.fbJump == SWL_JUMPABLE)));
1453          PUSHs(sv_2mortal(newSViv(pswentry->swctl.bProgType)));
1454          PUSHs(sv_2mortal(newSViv(pswentry->hswitch)));
1455      }
1456
1457 SV *
1458 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)
1459 PROTOTYPE: DISABLE
1460
1461 int
1462 change_swentry( SV *sv )
1463
1464 bool
1465 sesmgr_title_set(s)
1466     char *s
1467
1468 SV *
1469 process_swentry(unsigned long pid = getpid(), HWND hwnd = NULLHANDLE);
1470   PROTOTYPE: DISABLE
1471
1472 int
1473 swentry_size()
1474
1475 SV *
1476 swentries_list()
1477
1478 void
1479 ResetWinError()
1480    POSTCALL:
1481         XSRETURN_YES;
1482
1483 int
1484 WindowText_set(HWND hwndFrame, char *title)
1485
1486 bool
1487 FocusWindow_set(HWND hwndFocus, HWND hwndDesktop = HWND_DESKTOP)
1488
1489 bool
1490 ShowWindow(HWND hwnd, bool fShow = TRUE)
1491
1492 bool
1493 EnableWindow(HWND hwnd, bool fEnable = TRUE)
1494
1495 bool
1496 PostMsg(HWND hwnd, unsigned long msg, unsigned long mp1 = 0, unsigned long mp2 = 0)
1497     C_ARGS: hwnd, msg, (MPARAM)mp1, (MPARAM)mp2
1498
1499 bool
1500 WindowPos_set(HWND hwnd, long x, long y, unsigned long fl = SWP_MOVE, long cx = 0, long cy = 0, HWND hwndInsertBehind = HWND_TOP)
1501   PROTOTYPE: DISABLE
1502
1503 unsigned long
1504 BeginEnumWindows(HWND hwnd)
1505
1506 bool
1507 EndEnumWindows(unsigned long henum)
1508
1509 unsigned long
1510 GetNextWindow(unsigned long henum)
1511
1512 bool
1513 IsWindowVisible(HWND hwnd)
1514
1515 bool
1516 IsWindowEnabled(HWND hwnd)
1517
1518 bool
1519 IsWindowShowing(HWND hwnd)
1520
1521 unsigned long
1522 QueryWindow(HWND hwnd, long cmd)
1523
1524 unsigned long
1525 IsChild(HWND hwnd, HWND hwndParent)
1526
1527 unsigned long
1528 WindowFromId(HWND hwndParent, unsigned long id)
1529
1530 unsigned long
1531 WindowFromPoint(long x, long y, HWND hwnd = HWND_DESKTOP, bool fChildren = TRUE)
1532 PROTOTYPE: DISABLE
1533
1534 unsigned long
1535 EnumDlgItem(HWND hwndDlg, unsigned long code, HWND hwnd = NULLHANDLE)
1536    C_ARGS: hwndDlg, hwnd, code
1537
1538 bool
1539 EnableWindowUpdate(HWND hwnd, bool fEnable = TRUE)
1540
1541 bool
1542 SetWindowBits(HWND hwnd, long index, unsigned long flData, unsigned long flMask)
1543
1544 bool
1545 SetWindowPtr(HWND hwnd, long index, unsigned long p)
1546     C_ARGS: hwnd, index, (PVOID)p
1547
1548 bool
1549 SetWindowULong(HWND hwnd, long index, unsigned long i)
1550
1551 bool
1552 SetWindowUShort(HWND hwnd, long index, unsigned short i)
1553
1554 bool
1555 IsWindow(HWND hwnd, HAB hab = Acquire_hab())
1556     C_ARGS: hab, hwnd
1557
1558 BOOL
1559 ActiveWindow_set(HWND hwnd, HWND hwndDesktop = HWND_DESKTOP)
1560     CODE:
1561         RETVAL = SetActiveWindow(hwndDesktop, hwnd);
1562
1563 unsigned long
1564 LoadPointer(unsigned long idres, unsigned long hmod = 0, HWND hwndDesktop = HWND_DESKTOP)
1565     C_ARGS: hwndDesktop, hmod, idres
1566
1567 int
1568 out_codepage()
1569
1570 bool
1571 out_codepage_set(int cp)
1572
1573 int
1574 in_codepage()
1575
1576 bool
1577 in_codepage_set(int cp)
1578
1579 SV *
1580 screen()
1581
1582 bool
1583 screen_set(SV *sv)
1584
1585 SV *
1586 process_codepages()
1587   PPCODE:
1588   {
1589     ULONG cps[4], c, i = 0, rc;
1590
1591     if (CheckOSError(DosQueryCp( sizeof(cps), cps, &c )))
1592         c = 0;
1593     c /= sizeof(ULONG);
1594     if (c >= 3)
1595     EXTEND(sp, c);
1596     while (i < c)
1597         PUSHs(sv_2mortal(newSViv(cps[i++])));
1598   }
1599
1600 bool
1601 process_codepage_set(int cp)
1602
1603 void
1604 cursor(OUTLIST int stp, OUTLIST int ep, OUTLIST int wp, OUTLIST int ap)
1605   PROTOTYPE:
1606
1607 bool
1608 cursor_set(int s, int e, int w = cursor__(0), int a = cursor__(1))
1609
1610 SV*
1611 _kbdChar(int nowait = 0, int handle = 0)
1612
1613 SV*
1614 _kbdStatus(int handle = 0)
1615
1616 void
1617 _kbdStatus_set(SV *sv, int handle = 0)
1618    POSTCALL:
1619         XSRETURN_YES;
1620
1621 SV*
1622 _vioConfig(int which = 0, int handle = 0)
1623
1624 SV*
1625 _vioMode()
1626
1627 void
1628 _vioMode_set(SV *buffer)
1629    POSTCALL:
1630         XSRETURN_YES;
1631
1632 SV*
1633 _vioState(int what, int first = -1, int count = -1)
1634
1635 void
1636 _vioState_set(SV *buffer)
1637    POSTCALL:
1638         XSRETURN_YES;
1639
1640 SV*
1641 vioFont( int type = 0, OUTLIST int w, OUTLIST int h)
1642
1643 void
1644 vioFont_set(SV *buffer, int cellwidth, int cellheight, int type = 0)
1645    POSTCALL:
1646         XSRETURN_YES;
1647
1648 NO_OUTPUT bool
1649 _ClipbrdData_set(unsigned long ulData, unsigned long fmt = CF_TEXT, unsigned long rgfFmtInfo = default_fmtInfo(fmt), HAB hab = perl_hab_GET())
1650     PROTOTYPE: DISABLE
1651     C_ARGS: hab, ulData, fmt, rgfFmtInfo
1652     POSTCALL:
1653         if (CheckWinError(RETVAL))
1654             croak_with_os2error("_ClipbrdData_set() error");
1655         XSRETURN_YES;
1656
1657 void
1658 ClipbrdData_set(SV *text, int convert_nl = 1, unsigned long fmt = CF_TEXT, unsigned long rgfFmtInfo = default_fmtInfo(fmt), HAB hab = perl_hab_GET())
1659     PROTOTYPE: DISABLE
1660     POSTCALL:
1661         XSRETURN_YES;
1662
1663 void
1664 ClipbrdOwner_set(HWND hwnd, HAB hab = perl_hab_GET())
1665     C_ARGS: hab, hwnd
1666     POSTCALL:
1667         XSRETURN_YES;
1668
1669 void
1670 ClipbrdViewer_set(HWND hwnd, HAB hab = perl_hab_GET())
1671     C_ARGS: hab, hwnd
1672     POSTCALL:
1673         XSRETURN_YES;
1674
1675 unsigned long
1676 EnumClipbrdFmts(unsigned long fmt = 0, HAB hab = perl_hab_GET())
1677     C_ARGS: hab, fmt
1678
1679 unsigned long
1680 AddAtom(char *pszAtomName, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1681     C_ARGS: hAtomTbl, pszAtomName
1682
1683 unsigned long
1684 FindAtom(char *pszAtomName, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1685     C_ARGS: hAtomTbl, pszAtomName
1686
1687 unsigned long
1688 _DeleteAtom(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1689     PROTOTYPE: DISABLE
1690     C_ARGS: hAtomTbl, atom
1691
1692 #if 0
1693
1694 unsigned long
1695 WinDeleteAtom(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1696     C_ARGS: hAtomTbl, atom
1697
1698 #endif
1699
1700 void
1701 Alarm(unsigned long rgfType = WA_ERROR, HWND hwndDesktop = HWND_DESKTOP)
1702     C_ARGS: hwndDesktop, rgfType
1703     POSTCALL:
1704         XSRETURN_YES;
1705
1706 void
1707 FlashWindow(HWND hwndFrame, bool fFlash)
1708     POSTCALL:
1709         XSRETURN_YES;
1710
1711 STRLEN
1712 StrLen(ULONG addr, ULONG lim, I32 unitsize = 1)
1713
1714 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = myQuery
1715
1716 SV *
1717 myQueryWindowText(HWND hwnd)
1718
1719 SV *
1720 myQueryClassName(HWND hwnd)
1721
1722 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = Query
1723
1724 unsigned long
1725 QueryFocusWindow(HWND hwndDesktop = HWND_DESKTOP)
1726
1727 long
1728 QueryWindowTextLength(HWND hwnd)
1729
1730 SV *
1731 QueryWindowSWP(HWND hwnd)
1732
1733 unsigned long
1734 QueryWindowULong(HWND hwnd, long index)
1735
1736 unsigned short
1737 QueryWindowUShort(HWND hwnd, long index)
1738
1739 unsigned long
1740 QueryActiveWindow(HWND hwnd = HWND_DESKTOP)
1741
1742 unsigned long
1743 QueryDesktopWindow(HAB hab = Acquire_hab(), unsigned long hdc = NULLHANDLE)
1744
1745 unsigned long
1746 QueryClipbrdData(unsigned long fmt = CF_TEXT, HAB hab = perl_hab_GET())
1747     C_ARGS: hab, fmt
1748     PROTOTYPE: DISABLE
1749
1750 ULONG
1751 QueryMemoryRegionSize(ULONG addr, OUTLIST ULONG flagp, ULONG len = 0xFFFFFFFF - addr, I32 interrupt = 1)
1752
1753 unsigned long
1754 QueryClipbrdViewer(HAB hab = perl_hab_GET())
1755
1756 unsigned long
1757 QueryClipbrdOwner(HAB hab = perl_hab_GET())
1758
1759 void
1760 CloseClipbrd(HAB hab = perl_hab_GET())
1761     POSTCALL:
1762         XSRETURN_YES;
1763
1764 void
1765 EmptyClipbrd(HAB hab = perl_hab_GET())
1766    POSTCALL:
1767         XSRETURN_YES;
1768
1769 bool
1770 OpenClipbrd(HAB hab = perl_hab_GET())
1771
1772 unsigned long
1773 QueryAtomUsage(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1774     C_ARGS: hAtomTbl, atom
1775
1776 unsigned long
1777 QueryAtomLength(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1778     C_ARGS: hAtomTbl, atom
1779    POSTCALL:
1780         if (!RETVAL)
1781             XSRETURN_EMPTY;
1782
1783 unsigned long
1784 QuerySystemAtomTable()
1785
1786 unsigned long
1787 QuerySysPointer(long lId, bool fCopy = 1, HWND hwndDesktop = HWND_DESKTOP)
1788     C_ARGS: hwndDesktop, lId, fCopy
1789
1790 unsigned long
1791 CreateAtomTable(unsigned long initial = 0, unsigned long buckets = 0)
1792
1793 unsigned long
1794 _DestroyAtomTable(HATOMTBL hAtomTbl)
1795     PROTOTYPE: DISABLE
1796
1797
1798 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = myWinQuery
1799
1800 unsigned long
1801 myWinQueryWindowPtr(HWND hwnd, long index)
1802
1803 NO_OUTPUT BOOL
1804 myWinQueryWindowProcess(HWND hwnd, OUTLIST unsigned long pid, OUTLIST unsigned long tid)
1805    PROTOTYPE: $
1806    POSTCALL:
1807         if (CheckWinError(RETVAL))
1808             croak_with_os2error("WindowProcess() error");
1809
1810 SV *
1811 myWinQueryActiveDesktopPathname()
1812
1813 void
1814 myWinQueryClipbrdFmtInfo(OUTLIST unsigned long prgfFmtInfo, unsigned long fmt = CF_TEXT, HAB hab = perl_hab_GET())
1815    C_ARGS: hab, fmt, &prgfFmtInfo
1816
1817 SV *
1818 myWinQueryAtomName(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
1819
1820 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = myWin
1821
1822 int
1823 myWinSwitchToProgram(HSWITCH hsw = switch_of(NULLHANDLE, getpid()))
1824     PREINIT:
1825         ULONG rc;
1826
1827 #if 0
1828
1829 unsigned long
1830 myWinMessageBox(unsigned long pszText, char* pszCaption = "Perl script message", unsigned long flStyle = MB_CANCEL | MB_ICONHAND, HWND hwndParent = HWND_DESKTOP, HWND hwndOwner = HWND_DESKTOP, unsigned long idWindow = 0)
1831     C_ARGS: hwndParent, hwndOwner, pszText, pszCaption, idWindow, flStyle
1832
1833 #endif
1834
1835 unsigned long
1836 _MessageBox(char* pszText, char* pszCaption = "Perl script message", unsigned long flStyle = MB_CANCEL | MB_INFORMATION | MB_MOVEABLE, HWND hwndParent = HWND_DESKTOP, HWND hwndOwner = NULLHANDLE, unsigned long idWindow = 0)
1837     C_ARGS: hwndParent, hwndOwner, pszText, pszCaption, idWindow, flStyle
1838     POSTCALL:
1839         if (RETVAL == MBID_ERROR)
1840             RETVAL = 0;
1841
1842 unsigned long
1843 _MessageBox2(char *pszText, char* pmb2info, char *pszCaption = "Perl script message", HWND hwndParent = HWND_DESKTOP, HWND hwndOwner = NULLHANDLE, unsigned long idWindow = 0)
1844     C_ARGS: hwndParent, hwndOwner, pszText, pszCaption, idWindow, (PMB2INFO)pmb2info
1845     POSTCALL:
1846         if (RETVAL == MBID_ERROR)
1847             RETVAL = 0;
1848
1849 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = myWinQuery
1850
1851 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = get
1852
1853 int
1854 getppid()
1855
1856 int
1857 ppidOf(int pid = getpid())
1858
1859 int
1860 sidOf(int pid = getpid())
1861
1862 void
1863 getscrsize(OUTLIST int wp, OUTLIST int hp)
1864   PROTOTYPE:
1865
1866 bool
1867 scrsize_set(int w_or_h, int h = -9999)
1868
1869 void
1870 get_InvalidateRect(HWND hwnd, char *prcl, bool fIncludeChildren)
1871
1872 void
1873 get_CreateFrameControls(HWND hwndFrame, char *pfcdata, char* pszTitle)
1874
1875 MODULE = OS2::Process           PACKAGE = OS2::Process  PREFIX = ul
1876
1877 unsigned long
1878 ulMPFROMSHORT(unsigned short i)
1879
1880 unsigned long
1881 ulMPVOID()
1882
1883 unsigned long
1884 ulMPFROMCHAR(unsigned char i)
1885
1886 unsigned long
1887 ulMPFROM2SHORT(unsigned short x1, unsigned short x2)
1888   PROTOTYPE: DISABLE
1889
1890 unsigned long
1891 ulMPFROMSH2CH(unsigned short s, unsigned char c1, unsigned char c2)
1892   PROTOTYPE: DISABLE
1893
1894 unsigned long
1895 ulMPFROMLONG(unsigned long x)
1896