OS/2-specific fixes, round II
[p5sagit/p5-mst-13.2.git] / os2 / OS2 / Process / Process.xs
index 159ef49..05befa0 100644 (file)
@@ -7,6 +7,8 @@
 #define INCL_WININPUT
 #define INCL_VIO
 #define INCL_KBD
+#define INCL_WINCLIPBOARD
+#define INCL_WINATOM
 #include <os2.h>
 
 #include "EXTERN.h"
@@ -234,17 +236,21 @@ file_type(char *path)
     if (!(_emx_env & 0x200)) 
        croak("file_type not implemented on DOS"); /* not OS/2. */
     if (CheckOSError(DosQueryAppType(path, &apptype))) {
+#if 0
        if (rc == ERROR_INVALID_EXE_SIGNATURE) 
            croak("Invalid EXE signature"); 
        else if (rc == ERROR_EXE_MARKED_INVALID) {
            croak("EXE marked invalid"); 
        }
-       croak("DosQueryAppType err %ld", rc); 
+#endif
+       croak_with_os2error("DosQueryAppType"); 
     }
     
     return apptype;
 }
 
+/* These use different type of wrapper.  Good to check wrappers. ;-)  */
+/* XXXX This assumes DOS type return type, without SEVERITY?! */
 DeclFuncByORD(HSWITCH, myWinQuerySwitchHandle,  ORD_WinQuerySwitchHandle,
                  (HWND hwnd, PID pid), (hwnd, pid))
 DeclFuncByORD(ULONG, myWinQuerySwitchEntry,  ORD_WinQuerySwitchEntry,
@@ -253,44 +259,155 @@ DeclFuncByORD(ULONG, myWinSetWindowText,  ORD_WinSetWindowText,
                  (HWND hwnd, char* text), (hwnd, text))
 DeclFuncByORD(BOOL, myWinQueryWindowProcess,  ORD_WinQueryWindowProcess,
                  (HWND hwnd, PPID ppid, PTID ptid), (hwnd, ppid, ptid))
-
 DeclFuncByORD(ULONG, XmyWinSwitchToProgram,  ORD_WinSwitchToProgram,
                  (HSWITCH hsw), (hsw))
 #define myWinSwitchToProgram(hsw) (!CheckOSError(XmyWinSwitchToProgram(hsw)))
 
-DeclFuncByORD(HWND, myWinQueryActiveWindow,  ORD_WinQueryActiveWindow,
-                 (HWND hwnd), (hwnd))
 
+/* These function croak if the return value is 0. */
+DeclWinFunc_CACHE(HWND, QueryWindow, (HWND hwnd, LONG cmd), (hwnd, cmd))
+DeclWinFunc_CACHE(BOOL, QueryWindowPos, (HWND hwnd, PSWP pswp),
+                 (hwnd, pswp))
+DeclWinFunc_CACHE(LONG, QueryWindowText,
+                 (HWND hwnd, LONG cchBufferMax, PCH pchBuffer),
+                 (hwnd, cchBufferMax, pchBuffer))
+DeclWinFunc_CACHE(LONG, QueryClassName, (HWND hwnd, LONG cchMax, PCH pch),
+                 (hwnd, cchMax, pch))
+DeclWinFunc_CACHE(HWND, QueryFocus, (HWND hwndDesktop), (hwndDesktop))
+DeclWinFunc_CACHE(BOOL, SetFocus, (HWND hwndDesktop, HWND hwndFocus),
+                 (hwndDesktop, hwndFocus))
+DeclWinFunc_CACHE(BOOL, ShowWindow, (HWND hwnd, BOOL fShow), (hwnd, fShow))
+DeclWinFunc_CACHE(BOOL, EnableWindow, (HWND hwnd, BOOL fEnable),
+                     (hwnd, fEnable))
+DeclWinFunc_CACHE(BOOL, SetWindowPos,
+                 (HWND hwnd, HWND hwndInsertBehind, LONG x, LONG y,
+                  LONG cx, LONG cy, ULONG fl),
+                 (hwnd, hwndInsertBehind, x, y, cx, cy, fl))
+DeclWinFunc_CACHE(HENUM, BeginEnumWindows, (HWND hwnd), (hwnd))
+DeclWinFunc_CACHE(BOOL, EndEnumWindows, (HENUM henum), (henum))
+DeclWinFunc_CACHE(BOOL, EnableWindowUpdate, (HWND hwnd, BOOL fEnable),
+                 (hwnd, fEnable))
+DeclWinFunc_CACHE(BOOL, SetWindowBits,
+                 (HWND hwnd, LONG index, ULONG flData, ULONG flMask),
+                 (hwnd, index, flData, flMask))
+DeclWinFunc_CACHE(BOOL, SetWindowPtr, (HWND hwnd, LONG index, PVOID p),
+                 (hwnd, index, p))
+DeclWinFunc_CACHE(BOOL, SetWindowULong, (HWND hwnd, LONG index, ULONG ul),
+                 (hwnd, index, ul))
+DeclWinFunc_CACHE(BOOL, SetWindowUShort, (HWND hwnd, LONG index, USHORT us),
+                 (hwnd, index, us))
+DeclWinFunc_CACHE(HWND, IsChild, (HWND hwnd, HWND hwndParent),
+                 (hwnd, hwndParent))
+DeclWinFunc_CACHE(HWND, WindowFromId, (HWND hwnd, ULONG id), (hwnd, id))
+DeclWinFunc_CACHE(HWND, EnumDlgItem, (HWND hwndDlg, HWND hwnd, ULONG code),
+                 (hwndDlg, hwnd, code))
+DeclWinFunc_CACHE(HWND, QueryDesktopWindow, (HAB hab, HDC hdc), (hab, hdc));
+DeclWinFunc_CACHE(BOOL, SetActiveWindow, (HWND hwndDesktop, HWND hwnd),
+                 (hwndDesktop, hwnd));
+DeclWinFunc_CACHE(BOOL, QueryActiveDesktopPathname, (PSZ pszPathName, ULONG ulSize),
+                 (pszPathName, ulSize));
+DeclWinFunc_CACHE(BOOL, InvalidateRect,
+                 (HWND hwnd, /*RECTL*/ char *prcl, BOOL fIncludeChildren),
+                 (hwnd, prcl, fIncludeChildren));
+DeclWinFunc_CACHE(BOOL, CreateFrameControls,
+                 (HWND hwndFrame, /*PFRAMECDATA*/ char* pfcdata, PCSZ pszTitle),
+                 (hwndFrame, pfcdata, pszTitle));
+DeclWinFunc_CACHE(BOOL, OpenClipbrd, (HAB hab), (hab));
+DeclWinFunc_CACHE(BOOL, EmptyClipbrd, (HAB hab), (hab));
+DeclWinFunc_CACHE(BOOL, CloseClipbrd, (HAB hab), (hab));
+DeclWinFunc_CACHE(BOOL, QueryClipbrdFmtInfo, (HAB hab, ULONG fmt, PULONG prgfFmtInfo), (hab, fmt, prgfFmtInfo));
+DeclWinFunc_CACHE(ULONG, QueryClipbrdData, (HAB hab, ULONG fmt), (hab, fmt));
+DeclWinFunc_CACHE(HWND, SetClipbrdViewer, (HAB hab, HWND hwnd), (hab, hwnd));
+DeclWinFunc_CACHE(HWND, SetClipbrdOwner, (HAB hab, HWND hwnd), (hab, hwnd));
+DeclWinFunc_CACHE(ULONG, EnumClipbrdFmts, (HAB hab, ULONG fmt), (hab, fmt));
+DeclWinFunc_CACHE(ATOM, AddAtom, (HATOMTBL hAtomTbl, PCSZ pszAtomName),
+                 (hAtomTbl, pszAtomName));
+DeclWinFunc_CACHE(ULONG, QueryAtomUsage, (HATOMTBL hAtomTbl, ATOM atom),
+                 (hAtomTbl, atom));
+DeclWinFunc_CACHE(ULONG, QueryAtomLength, (HATOMTBL hAtomTbl, ATOM atom),
+                 (hAtomTbl, atom));
+DeclWinFunc_CACHE(ULONG, QueryAtomName,
+                 (HATOMTBL hAtomTbl, ATOM atom, PSZ pchBuffer, ULONG cchBufferMax),
+                 (hAtomTbl, atom, pchBuffer, cchBufferMax));
+DeclWinFunc_CACHE(HATOMTBL, QuerySystemAtomTable, (VOID), ());
+DeclWinFunc_CACHE(HATOMTBL, CreateAtomTable, (ULONG initial, ULONG buckets),
+                 (initial, buckets));
+DeclWinFunc_CACHE(ULONG, MessageBox, (HWND hwndParent, HWND hwndOwner, PCSZ pszText, PCSZ pszCaption, ULONG idWindow, ULONG flStyle), (hwndParent, hwndOwner, pszText, pszCaption, idWindow, flStyle));
+DeclWinFunc_CACHE(ULONG, MessageBox2,
+                 (HWND hwndParent, HWND hwndOwner, PCSZ pszText,
+                  PCSZ pszCaption, ULONG idWindow, PMB2INFO pmb2info),
+                 (hwndParent, hwndOwner, pszText, pszCaption, idWindow, pmb2info));
+DeclWinFunc_CACHE(HPOINTER, LoadPointer,
+                 (HWND hwndDesktop, HMODULE hmod, ULONG idres),
+                 (hwndDesktop, hmod, idres));
+DeclWinFunc_CACHE(HPOINTER, QuerySysPointer,
+                 (HWND hwndDesktop, LONG lId, BOOL fCopy),
+                 (hwndDesktop, lId, fCopy));
+DeclWinFunc_CACHE(BOOL, Alarm, (HWND hwndDesktop, ULONG rgfType), (hwndDesktop, rgfType));
+DeclWinFunc_CACHE(BOOL, FlashWindow, (HWND hwndFrame, BOOL fFlash), (hwndFrame, fFlash));
+
+#if 0          /* Need to have the entry points described in the parent */
+DeclWinFunc_CACHE(BOOL, QueryClassInfo, (HAB hab, char* pszClassName, PCLASSINFO pClassInfo), (hab, pszClassName, pClassInfo));
+
+#define _QueryClassInfo(hab, pszClassName, pClassInfo) \
+       QueryClassInfo(hab, pszClassName, (PCLASSINFO)pClassInfo)
 
+#endif
+
+/* These functions do not croak on error */
+DeclWinFunc_CACHE_survive(BOOL, SetClipbrdData,
+                         (HAB hab, ULONG ulData, ULONG fmt, ULONG rgfFmtInfo),
+                         (hab, ulData, fmt, rgfFmtInfo));
+
+#define get_InvalidateRect     InvalidateRect
+#define get_CreateFrameControls        CreateFrameControls
+
+/* These functions may return 0 on success; check $^E/Perl_rc on res==0: */
+DeclWinFunc_CACHE_resetError(PVOID, QueryWindowPtr, (HWND hwnd, LONG index),
+                            (hwnd, index))
+DeclWinFunc_CACHE_resetError(ULONG, QueryWindowULong, (HWND hwnd, LONG index),
+                            (hwnd, index))
+DeclWinFunc_CACHE_resetError(SHORT, QueryWindowUShort, (HWND hwnd, LONG index),
+                            (hwnd, index))
+DeclWinFunc_CACHE_resetError(LONG,  QueryWindowTextLength, (HWND hwnd), (hwnd))
+DeclWinFunc_CACHE_resetError(HWND,  QueryActiveWindow, (HWND hwnd), (hwnd))
+DeclWinFunc_CACHE_resetError(BOOL, PostMsg,
+                            (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2),
+                            (hwnd, msg, mp1, mp2))
+DeclWinFunc_CACHE_resetError(HWND, GetNextWindow, (HENUM henum), (henum))
+DeclWinFunc_CACHE_resetError(BOOL, IsWindowEnabled, (HWND hwnd), (hwnd))
+DeclWinFunc_CACHE_resetError(BOOL, IsWindowVisible, (HWND hwnd), (hwnd))
+DeclWinFunc_CACHE_resetError(BOOL, IsWindowShowing, (HWND hwnd), (hwnd))
+DeclWinFunc_CACHE_resetError(ATOM, FindAtom, (HATOMTBL hAtomTbl, PCSZ pszAtomName),
+                            (hAtomTbl, pszAtomName));
+DeclWinFunc_CACHE_resetError(ATOM, DeleteAtom, (HATOMTBL hAtomTbl, ATOM atom),
+                            (hAtomTbl, atom));
+DeclWinFunc_CACHE_resetError(HATOMTBL, DestroyAtomTable, (HATOMTBL hAtomTbl), (hAtomTbl));
+DeclWinFunc_CACHE_resetError(HWND, QueryClipbrdViewer, (HAB hab), (hab));
+DeclWinFunc_CACHE_resetError(HWND, QueryClipbrdOwner, (HAB hab), (hab));
+
+#define _DeleteAtom            DeleteAtom
+#define _DestroyAtomTable      DestroyAtomTable
+
+/* No die()ing on error */
+DeclWinFunc_CACHE_survive(BOOL, IsWindow, (HAB hab, HWND hwnd), (hab, hwnd))
+
+/* These functions are called frow complicated wrappers: */
 ULONG (*pWinQuerySwitchList) (HAB hab, PSWBLOCK pswblk, ULONG usDataLength);
 ULONG (*pWinChangeSwitchEntry) (HSWITCH hsw, __const__ SWCNTRL *pswctl);
-
-HWND (*pWinQueryWindow) (HWND hwnd, LONG cmd);
-BOOL (*pWinQueryWindowPos) (HWND hwnd, PSWP pswp);
-LONG (*pWinQueryWindowText) (HWND hwnd, LONG cchBufferMax, PCH pchBuffer);
-LONG (*pWinQueryWindowTextLength) (HWND hwnd);
-LONG (*pWinQueryClassName) (HWND hwnd, LONG cchMax, PCH pch);
-HWND (*pWinQueryFocus) (HWND hwndDesktop);
-BOOL (*pWinSetFocus) (HWND hwndDesktop, HWND hwndFocus);
-BOOL (*pWinShowWindow) (HWND hwnd, BOOL fShow);
-BOOL (*pWinPostMsg) (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
-BOOL (*pWinSetWindowPos) (HWND hwnd, HWND hwndInsertBehind, LONG x, LONG y,
-    LONG cx, LONG cy, ULONG fl);
-HENUM (*pWinBeginEnumWindows) (HWND hwnd);
-BOOL (*pWinEndEnumWindows) (HENUM henum);
-HWND (*pWinGetNextWindow) (HENUM henum);
-BOOL (*pWinIsWindow) (HAB hab, HWND hwnd);
-HWND (*pWinQueryWindow) (HWND hwnd, LONG cmd);
-
-DeclWinFuncByORD(HWND, IsChild,  ORD_WinIsChild,
-                (HWND hwnd, HWND hwndParent), (hwnd, hwndParent))
-DeclWinFuncByORD(HWND, WindowFromId,  ORD_WinWindowFromId,
-                (HWND hwnd, ULONG id), (hwnd, id))
-
 HWND (*pWinWindowFromPoint)(HWND hwnd, __const__ POINTL *pptl, BOOL fChildren);
 
-DeclWinFuncByORD(HWND, EnumDlgItem, ORD_WinEnumDlgItem,
-                (HWND hwndDlg, HWND hwnd, ULONG code), (hwndDlg, hwnd, code));
+
+/* These functions have different names/signatures than what is
+   declared above */
+#define QueryFocusWindow QueryFocus
+#define FocusWindow_set(hwndFocus, hwndDesktop) SetFocus(hwndDesktop, hwndFocus)
+#define WindowPos_set(hwnd, x, y, fl, cx, cy, hwndInsertBehind)        \
+       SetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl)
+#define myWinQueryWindowPtr(hwnd, i)   ((ULONG)QueryWindowPtr(hwnd, i))
+#define _ClipbrdData_set SetClipbrdData
+#define ClipbrdOwner_set SetClipbrdOwner
+#define ClipbrdViewer_set SetClipbrdViewer
 
 int
 WindowText_set(HWND hwnd, char* text)
@@ -298,31 +415,25 @@ WindowText_set(HWND hwnd, char* text)
    return !CheckWinError(myWinSetWindowText(hwnd, text));
 }
 
-LONG
-QueryWindowTextLength(HWND hwnd)
-{
-    LONG ret;
-
-    if (!pWinQueryWindowTextLength)
-       AssignFuncPByORD(pWinQueryWindowTextLength, ORD_WinQueryWindowTextLength);
-    ret = pWinQueryWindowTextLength(hwnd);
-    CheckWinError(ret);                        /* May put false positive */
-    return ret;
-}
-
 SV *
-QueryWindowText(HWND hwnd)
+myQueryWindowText(HWND hwnd)
 {
-    LONG l = QueryWindowTextLength(hwnd);
-    SV *sv = newSVpvn("", 0);
+    LONG l = QueryWindowTextLength(hwnd), len;
+    SV *sv;
     STRLEN n_a;
 
-    if (l == 0)
-       return sv;
+    if (l == 0) {
+       if (Perl_rc)            /* Last error */
+           return &PL_sv_undef;
+       return &PL_sv_no;
+    }
+    sv = newSVpvn("", 0);
     SvGROW(sv, l + 1);
-    if (!pWinQueryWindowText)
-       AssignFuncPByORD(pWinQueryWindowText, ORD_WinQueryWindowText);
-    CheckWinError(l = pWinQueryWindowText(hwnd, l + 1, SvPV_force(sv, n_a)));
+    len = QueryWindowText(hwnd, l + 1, SvPV_force(sv, n_a));
+    if (len != l) {
+       Safefree(sv);
+       croak("WinQueryWindowText() uncompatible with WinQueryWindowTextLength()");
+    }
     SvCUR_set(sv, l);
     return sv;
 }
@@ -332,9 +443,7 @@ QueryWindowSWP_(HWND hwnd)
 {
     SWP swp;
 
-    if (!pWinQueryWindowPos)
-       AssignFuncPByORD(pWinQueryWindowPos, ORD_WinQueryWindowPos);
-    if (CheckWinError(pWinQueryWindowPos(hwnd, &swp)))
+    if (!QueryWindowPos(hwnd, &swp))
        croak("WinQueryWindowPos() error");
     return swp;
 }
@@ -348,143 +457,212 @@ QueryWindowSWP(HWND hwnd)
 }
 
 SV *
-QueryClassName(HWND hwnd)
+myQueryClassName(HWND hwnd)
 {
     SV *sv = newSVpvn("",0);
     STRLEN l = 46, len = 0, n_a;
 
-    if (!pWinQueryClassName)
-       AssignFuncPByORD(pWinQueryClassName, ORD_WinQueryClassName);
     while (l + 1 >= len) {
        if (len)
            len = 2*len + 10;           /* Grow quick */
        else
            len = l + 2;
        SvGROW(sv, len);
-       l = pWinQueryClassName(hwnd, len, SvPV_force(sv, n_a));
-       CheckWinError(l);
-       SvCUR_set(sv, l);
+       l = QueryClassName(hwnd, len, SvPV_force(sv, n_a));
     }
+    SvCUR_set(sv, l);
     return sv;
 }
 
 HWND
-QueryFocusWindow(HWND hwndDesktop)
+WindowFromPoint(long x, long y, HWND hwnd, BOOL fChildren)
 {
-    HWND ret;
+    POINTL ppl;
 
-    if (!pWinQueryFocus)
-       AssignFuncPByORD(pWinQueryFocus, ORD_WinQueryFocus);
-    ret = pWinQueryFocus(hwndDesktop);
-    CheckWinError(ret);
-    return ret;
+    ppl.x = x; ppl.y = y;
+    if (!pWinWindowFromPoint)
+       AssignFuncPByORD(pWinWindowFromPoint, ORD_WinWindowFromPoint);
+    return SaveWinError(pWinWindowFromPoint(hwnd, &ppl, fChildren));
 }
 
-BOOL
-FocusWindow_set(HWND hwndFocus, HWND hwndDesktop)
+static HSWITCH
+switch_of(HWND hwnd, PID pid)
 {
-    if (!pWinSetFocus)
-       AssignFuncPByORD(pWinSetFocus, ORD_WinSetFocus);
-    return !CheckWinError(pWinSetFocus(hwndDesktop, hwndFocus));
-}
+        HSWITCH hSwitch;    
 
-BOOL
-ShowWindow(HWND hwnd, BOOL fShow)
-{
-    if (!pWinShowWindow)
-       AssignFuncPByORD(pWinShowWindow, ORD_WinShowWindow);
-    return !CheckWinError(pWinShowWindow(hwnd, fShow));
+        if (!(_emx_env & 0x200)) 
+            croak("switch_entry not implemented on DOS"); /* not OS/2. */
+        if (CheckWinError(hSwitch = 
+                          myWinQuerySwitchHandle(hwnd, pid)))
+            croak_with_os2error("WinQuerySwitchHandle");
+        return hSwitch;
 }
 
-BOOL
-PostMsg(HWND hwnd, ULONG msg, ULONG mp1, ULONG mp2)
-{
-    if (!pWinPostMsg)
-       AssignFuncPByORD(pWinPostMsg, ORD_WinPostMsg);
-    return !CheckWinError(pWinPostMsg(hwnd, msg, (MPARAM)mp1, (MPARAM)mp2));
-}
 
-BOOL
-WindowPos_set(HWND hwnd, LONG x, LONG y, ULONG fl, LONG cx, LONG cy, 
-             HWND hwndInsertBehind)
+static void
+fill_swentry(SWENTRY *swentryp, HWND hwnd, PID pid)
 {
-    if (!pWinSetWindowPos)
-       AssignFuncPByORD(pWinSetWindowPos, ORD_WinSetWindowPos);
-    return !CheckWinError(pWinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl));
+        int rc;
+        HSWITCH hSwitch = switch_of(hwnd, pid);
+
+        swentryp->hswitch = hSwitch;
+        if (CheckOSError(myWinQuerySwitchEntry(hSwitch, &swentryp->swctl)))
+            croak_with_os2error("WinQuerySwitchEntry");
 }
 
-HENUM
-BeginEnumWindows(HWND hwnd)
+static void
+fill_swentry_default(SWENTRY *swentryp)
 {
-    if (!pWinBeginEnumWindows)
-       AssignFuncPByORD(pWinBeginEnumWindows, ORD_WinBeginEnumWindows);
-    return SaveWinError(pWinBeginEnumWindows(hwnd));
+       fill_swentry(swentryp, NULLHANDLE, getpid());
 }
 
-BOOL
-EndEnumWindows(HENUM henum)
+static SV*
+myWinQueryActiveDesktopPathname()
 {
-    if (!pWinEndEnumWindows)
-       AssignFuncPByORD(pWinEndEnumWindows, ORD_WinEndEnumWindows);
-    return !CheckWinError(pWinEndEnumWindows(henum));
+    SV *buf = newSVpv("",0);
+    STRLEN n_a;
+
+    SvGROW(buf, MAXPATHLEN);
+    QueryActiveDesktopPathname(SvPV(buf,n_a), MAXPATHLEN);
+    SvCUR_set(buf, strlen(SvPV(buf, n_a)));
+    return buf;
 }
 
-HWND
-GetNextWindow(HENUM henum)
+SV *
+myWinQueryAtomName(ATOM atom, HATOMTBL hAtomTbl)
 {
-    if (!pWinGetNextWindow)
-       AssignFuncPByORD(pWinGetNextWindow, ORD_WinGetNextWindow);
-    return SaveWinError(pWinGetNextWindow(henum));
+  ULONG len = QueryAtomLength(hAtomTbl, atom);
+
+  if (len) {                   /* Probably always so... */
+    SV *sv = newSVpvn("",0);
+    STRLEN n_a;
+
+    SvGROW(sv, len + 1);
+    len = QueryAtomName(hAtomTbl, atom, SvPV(sv, n_a), len + 1);
+    if (len) {                 /* Probably always so... */
+      SvCUR_set(sv, len);
+      *SvEND(sv) = 0;
+      return sv;
+    }
+    SvREFCNT_dec(sv);
+  }
+  return &PL_sv_undef;
 }
 
-BOOL
-IsWindow(HWND hwnd, HAB hab)
+#define myWinQueryClipbrdFmtInfo       QueryClipbrdFmtInfo
+
+/* Put data into shared memory, then call SetClipbrdData */
+void
+ClipbrdData_set(SV *sv, int convert_nl, unsigned long fmt, unsigned long rgfFmtInfo, HAB hab)
 {
-    if (!pWinIsWindow)
-       AssignFuncPByORD(pWinIsWindow, ORD_WinIsWindow);
-    return !CheckWinError(pWinIsWindow(hab, hwnd));
+    STRLEN len;
+    char *buf;
+    char *pByte = 0, *s, c;
+    ULONG nls = 0, rc, handle;
+
+    if (rgfFmtInfo & CFI_POINTER) {
+      s = buf = SvPV_force(sv, len);
+      if (convert_nl) {
+       while ((c = *s++)) {
+           if (c == '\r' && *s == '\n')
+               s++;
+           else if (c == '\n')
+               nls++;
+       }
+      }
+
+      if (CheckOSError(DosAllocSharedMem((PPVOID)&pByte, 0, len + nls + 1,
+                                      PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE | OBJ_GETTABLE)))
+       croak_with_os2error("ClipbrdData_set: DosAllocSharedMem error");
+
+      if (!nls)
+       memcpy(pByte, buf, len + 1);
+      else {
+       char *t = pByte, *e = buf + len;
+
+       while (buf < e) {
+           c = *t++ = *buf++;
+           if (c == '\n' && (t == pByte + 1 || t[-2] != '\r'))
+               t[-1] = '\r', *t++ = '\n';
+       }
+      }
+      handle = (ULONG)pByte;
+    } else {
+      handle = (ULONG)SvUV(sv);
+    }
+
+    if (!SetClipbrdData(hab, handle, fmt, rgfFmtInfo)) {
+       if (fmt & CFI_POINTER)
+           DosFreeMem((PPVOID)&pByte);
+       croak_with_os2error("ClipbrdData_set: WinSetClipbrdData error");
+    }
 }
 
-HWND
-QueryWindow(HWND hwnd, LONG cmd)
+ULONG
+QueryMemoryRegionSize(ULONG addr, ULONG *flagp, ULONG len, I32 interrupt)
 {
-    if (!pWinQueryWindow)
-       AssignFuncPByORD(pWinQueryWindow, ORD_WinQueryWindow);
-    return !CheckWinError(pWinQueryWindow(hwnd, cmd));
+    ULONG l, f;                                /* Modifiable copy */
+    ULONG rc;
+
+    do {
+       l = len;
+       rc = DosQueryMem((void *)addr, &l, &f);
+    } while ( interrupt ? 0 : rc == ERROR_INTERRUPT );
+
+    /* We assume this is not about addr */
+/*
+    if (rc == ERROR_INVALID_ADDRESS)
+       return 0xFFFFFFFF;
+*/
+    os2cp_croak(rc,"QueryMemoryRegionSize");
+    if (flagp)
+       *flagp = f;
+    return l;
 }
 
-HWND
-WindowFromPoint(long x, long y, HWND hwnd, BOOL fChildren)
+static ULONG
+default_fmtInfo(ULONG fmt)
 {
-    POINTL ppl;
-
-    ppl.x = x; ppl.y = y;
-    if (!pWinWindowFromPoint)
-       AssignFuncPByORD(pWinWindowFromPoint, ORD_WinWindowFromPoint);
-    return SaveWinError(pWinWindowFromPoint(hwnd, &ppl, fChildren));
+   switch (fmt) {
+     case CF_PALETTE:  /* Actually, fmtInfo not documented for palette... */
+     case CF_BITMAP:
+     case CF_METAFILE:
+     case CF_DSPBITMAP:
+     case CF_DSPMETAFILE:
+       return CFI_HANDLE;
+     default:
+       return CFI_POINTER;
+   }
 }
 
-static void
-fill_swentry(SWENTRY *swentryp, HWND hwnd, PID pid)
+#if 0
+
+ULONG
+myWinMessageBox(HWND hwndParent, HWND hwndOwner, PCSZ pszText, PCSZ pszCaption, ULONG idWindow, ULONG flStyle)
 {
-        int rc;
-        HSWITCH hSwitch;    
+    ULONG rc = MessageBox(hwndParent, hwndOwner, pszText, pszCaption,
+                         idWindow, flStyle);
 
-        if (!(_emx_env & 0x200)) 
-            croak("switch_entry not implemented on DOS"); /* not OS/2. */
-        if (CheckWinError(hSwitch = 
-                          myWinQuerySwitchHandle(hwnd, pid)))
-            croak("WinQuerySwitchHandle err %ld", Perl_rc);
-        swentryp->hswitch = hSwitch;
-        if (CheckOSError(myWinQuerySwitchEntry(hSwitch, &swentryp->swctl)))
-            croak("WinQuerySwitchEntry err %ld", rc);
+    if (rc == MBID_ERROR)
+       rc = 0;
+    if (CheckWinError(rc))
+       croak_with_os2error("MessageBox");
+    return rc;
 }
 
-static void
-fill_swentry_default(SWENTRY *swentryp)
+ULONG
+myWinMessageBox2(HWND hwndParent, HWND hwndOwner, PCSZ pszText,
+                  PCSZ pszCaption, ULONG idWindow, PMB2INFO pmb2info)
 {
-       fill_swentry(swentryp, NULLHANDLE, getpid());
+    ULONG rc = MessageBox2(hwndParent, hwndOwner, pszText, pszCaption, idWindow, pmb2info);
+
+    if (rc == MBID_ERROR)
+       rc = 0;
+    if (CheckWinError(rc))
+       croak_with_os2error("MessageBox2");
+    return rc;
 }
+#endif
 
 /* static ULONG (* APIENTRY16 pDosSmSetTitle)(ULONG, PSZ); */
 ULONG _THUNK_FUNCTION(DosSmSetTitle)(ULONG, PSZ);
@@ -561,7 +739,7 @@ set_title2(char *s)
 #endif
 
 SV *
-process_swentry(unsigned long pid, unsigned long hwnd)
+process_swentry(unsigned long pid, HWND hwnd)
 {
     SWENTRY swentry;
 
@@ -713,7 +891,7 @@ cursor(int *sp, int *ep, int *wp, int *ap)
     VIO_FROM_VIOB;
 
     if (CheckOSError(VioGetCurType( vio, 0 )))
-       croak("VioGetCurType() error");
+       croak_with_os2error("VioGetCurType() error");
 
     *sp = vio->yStart;
     *ep = vio->cEnd;
@@ -759,7 +937,7 @@ bufsize(void)
 
     vio->cb = sizeof(*vio);
     if (CheckOSError(VioGetMode( vio, 0 )))
-       croak("Can't get size of buffer for screen");
+       croak_with_os2error("Can't get size of buffer for screen");
 #if 0  /* buf=323552247, full=1118455, partial=0 */
     croak("Lengths: buf=%d, full=%d, partial=%d",vio->buf_length,vio->full_length,vio->partial_length);
     return newSVpvn((char*)vio->buf_addr, vio->full_length);
@@ -772,7 +950,286 @@ bufsize(void)
     return i[0]*i[1]*2;
 #endif /* 0 */
 }
-    
+
+SV*
+_kbdChar(unsigned int nowait, int handle)
+{
+    KBDKEYINFO viob[2], *vio;
+    ULONG rc;
+
+    VIO_FROM_VIOB;
+
+    if (nowait > 2)
+       croak("unexpected nowait");
+    if (CheckOSError(nowait == 2
+                    ? KbdPeek( vio, handle )
+                    : KbdCharIn( vio, nowait == 1, handle )))
+       croak_with_os2error("Can't _kbdChar");
+    return newSVpvn((char*)vio, sizeof(*vio));
+}
+
+SV*
+_kbdStatus(int handle)
+{
+    KBDINFO viob[2], *vio;
+    ULONG rc;
+
+    VIO_FROM_VIOB;
+
+    vio->cb = sizeof(*vio);
+    if (CheckOSError(KbdGetStatus( vio, handle )))
+       croak_with_os2error("Can't _kbdStatus");
+    return newSVpvn((char*)vio, sizeof(*vio));
+}
+
+void
+_kbdStatus_set(SV* sv, int handle)
+{
+    KBDINFO viob[2], *vio;
+    ULONG rc;
+    STRLEN l;
+    char *s = SvPV(sv, l);
+
+    VIO_FROM_VIOB;
+
+    if (l != sizeof(*vio))
+       croak("unexpected datasize");
+    Copy((KBDINFO*)s, vio, 1, KBDINFO);
+    if (vio->cb != sizeof(*vio))
+       croak("unexpected datasize");
+    if (CheckOSError(KbdSetStatus( vio, handle )))
+       croak_with_os2error("Can't kbdStatus_set()");
+}
+
+SV*
+_vioConfig(int which, int handle)
+{
+    struct {VIOCONFIGINFO i; short a[20];} viob[2], *vio;
+    ULONG rc;
+
+    VIO_FROM_VIOB;
+
+    vio->i.cb = 2;
+    if (CheckOSError(VioGetConfig( which, &vio->i, handle )))
+       croak_with_os2error("Can't get VIO config size");
+    if (vio->i.cb > sizeof(*vio))
+       vio->i.cb = sizeof(*vio);
+    if (CheckOSError(VioGetConfig( which, &vio->i, handle )))
+       croak_with_os2error("Can't get VIO config");
+    return newSVpvn((char*)vio, vio->i.cb);
+}
+
+SV*
+_vioMode(void)
+{
+    VIOMODEINFO viob[2], *vio;
+    ULONG rc;
+
+    VIO_FROM_VIOB;
+
+    vio->cb = sizeof(*vio);
+    if (CheckOSError(VioGetMode( vio, 0 )))
+       croak_with_os2error("Can't get VIO mode");
+    return newSVpvn((char*)vio, sizeof(*vio));
+}
+
+void
+_vioMode_set(SV* sv)
+{
+    VIOMODEINFO viob[2], *vio;
+    ULONG rc;
+    STRLEN l;
+    char *s = SvPV(sv, l);
+
+    VIO_FROM_VIOB;
+
+    Copy((VIOMODEINFO*)s, vio, 1, VIOMODEINFO);
+    if (vio->cb != sizeof(*vio) || l != vio->cb)
+       croak("unexpected datasize");
+    if (CheckOSError(VioSetMode( vio, 0 )))
+       croak_with_os2error("Can't set VIO mode");
+}
+
+SV*
+vioFont(int type, int *w, int *h) /* 0 for actual RAM font, 1 for ROM font */
+{
+    VIOFONTINFO viob[2], *vio;
+    ULONG rc;
+    UCHAR b[1<<17];
+    UCHAR *buf = b;
+    SV *sv;
+
+    VIO_FROM_VIOB;
+
+    /* Should not cross 64K boundaries too: */
+    if (((ULONG)buf) & 0xFFFF)
+       buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
+
+    vio->cb = sizeof(*vio);
+    vio->type = type;                  /* BIOS or the loaded font. */
+    vio->cbData = 0xFFFF;              /* How large is my buffer? */
+    vio->pbData = _emx_32to16(buf);    /* Wants an 16:16 pointer */
+    if (CheckOSError(VioGetFont( vio, 0 )))
+       croak_with_os2error("Can't get VIO font");
+    *w = vio->cxCell;
+    *h = vio->cyCell;
+    return newSVpvn(buf,vio->cbData);
+}
+
+void
+vioFont_set(SV *sv, int cellwidth, int cellheight, int type)
+{
+    VIOFONTINFO viob[2], *vio;
+    ULONG rc;
+    UCHAR b[1<<17];
+    UCHAR *buf = b;
+    STRLEN l;
+    char *s = SvPV(sv, l);
+
+    VIO_FROM_VIOB;
+
+    /* Should not cross 64K boundaries too: */
+    if (((ULONG)buf) & 0xFFFF)
+       buf += 0x10000 - (((ULONG)buf) & 0xFFFF);
+
+    if (l > 0xFFFF)
+       croak("length overflow of VIO font");
+    if (l != (cellwidth + 7)/8 * cellheight * 256)
+       warn("unexpected length of VIO font");
+    vio->cb = sizeof(*vio);
+    vio->type = type;                  /* BIOS or the loaded font. */
+    vio->cbData = l;                   /* How large is my buffer? */
+    vio->pbData = _emx_32to16(buf);    /* Wants an 16:16 pointer */
+    vio->cxCell = cellwidth;
+    vio->cyCell = cellheight;
+    Copy(s, buf, l, char);
+
+    if (CheckOSError(VioSetFont( vio, 0 )))
+       croak_with_os2error("Can't set VIO font");
+}
+
+/*
+  uses use32,os2def,os2base,crt,defs;
+  var   Plt :Plt256;
+  const Pal :VioPalState=(Cb:sizeof(VioPalState);rType:0;iFirst:0;
+    Acolor:($FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF));
+        CReg:VioColorReg=(Cb:sizeof(VioColorReg);rType:3;FirstColorReg:0;
+    NumColorRegs:256; ColorRegAddr:@Plt);
+  var   ii:Pointer;
+  begin
+   VioGetState(Pal,0);
+   Pal.Acolor[09]:=$0F;
+   Pal.Acolor[10]:=$A;
+   Pal.Acolor[13]:=$2F;
+   VioSetState(Pal,0); // ce smena EGA registrov
+   asm
+  lea   eax,Plt
+     call  DosFlatToSel
+     mov   ii,eax
+   end;
+   CReg.ColorRegAddr:=ii;
+   VioGetState(CReg,0);
+   Plt[10,0]:=$00;
+   Plt[10,1]:=$32;
+   Plt[10,2]:=$2A;
+   VioSetState(CReg,0); // a ce - VGA registrov
+  end.
+*/
+
+typedef union {
+  VIOPALSTATE pal;
+  struct { VIOPALSTATE pal; USHORT a[15]; } pal_padded;
+  VIOOVERSCAN overscan;
+  VIOINTENSITY intensity;
+  VIOCOLORREG colorreg;
+  struct { VIOCOLORREG reg; char rgb[3*256]; } colorreg_padded;
+  VIOSETULINELOC lineloc;
+  VIOSETTARGET target;
+} my_VIOSTATE;
+
+int
+vio_state_size(int what)
+{
+    static const char sizes[] = {
+       sizeof(VIOPALSTATE),
+       sizeof(VIOOVERSCAN),
+       sizeof(VIOINTENSITY),
+       sizeof(VIOCOLORREG),
+       6,                              /* Random number: Reserved entry */
+       sizeof(VIOSETULINELOC),
+       sizeof(VIOSETTARGET)
+    };
+    if (what < 0 || what >= sizeof(sizes))
+       croak("Unexpected VIO state type");
+    return sizes[what];
+}
+
+SV*
+_vioState(int what, int first, int count)
+{
+    my_VIOSTATE viob[2], *vio;
+    ULONG rc, size = vio_state_size(what);
+
+    VIO_FROM_VIOB;
+
+    vio->pal.cb = size;
+    vio->pal.type = what;
+    if (what == 0) {
+       vio->pal.iFirst = first;
+       if (first < 0 || first >= 16)
+           croak("unexpected palette start value");
+       if (count < 0 || count > 16)
+           croak("unexpected palette count");
+       vio->pal.cb = (size += (count - 1) * sizeof(short));
+    } else if (what == 3) {
+       /* Wants an 16:16 pointer */
+       if (count < 0 || count > 256)
+           croak("unexpected palette count");
+       vio->colorreg.colorregaddr = (PCH)_emx_32to16(vio->colorreg_padded.rgb);
+       vio->colorreg.numcolorregs = count;             /* 256 is max */
+       vio->colorreg.firstcolorreg = first;
+       size += 3 * count;
+    }
+    if (CheckOSError(VioGetState( (void*)vio, 0 )))
+       croak_with_os2error("Can't get VIO state");
+    return newSVpvn((char*)vio, size);
+}
+
+void
+_vioState_set(SV *sv)
+{
+    my_VIOSTATE viob[2], *ovio = (my_VIOSTATE*)SvPV_nolen(sv), *vio = ovio;
+    int what = ovio->pal.type, cb = ovio->pal.cb;
+    ULONG rc, size = vio_state_size(what);
+    STRLEN l;
+    char *s = SvPV(sv, l);
+
+    VIO_FROM_VIOB;
+
+    switch (what) {
+    case 0:
+       if ( cb < size || cb > size + 15*sizeof(SHORT) || l != cb)
+           croak("unexpected datasize");
+       size = l;
+       break;
+    case 3:
+       if (l != cb + 3 * ovio->colorreg.numcolorregs || cb != size)
+           croak("unexpected datasize");
+       size = l;
+       break;
+    default:
+       if (l != cb || l != size )
+           croak("unexpected datasize");
+       break;
+    }
+    Copy(s, (char*)vio, size, char);
+    if (what == 3)     /* We expect colors put after VIOCOLORREG */
+       vio->colorreg.colorregaddr = (PCH)_emx_32to16(vio->colorreg_padded.rgb);
+
+    if (CheckOSError(VioSetState( (void*)vio, 0 )))
+       croak_with_os2error("Can't set VIO state");
+}
+
 SV *
 screen(void)
 {
@@ -819,7 +1276,7 @@ process_codepages()
     ULONG cps[4], cp, rc;
 
     if (CheckOSError(DosQueryCp( sizeof(cps), cps, &cp )))
-       croak("DosQueryCp() error");
+       croak_with_os2error("DosQueryCp()");
     return cp;
 }
 
@@ -829,7 +1286,7 @@ out_codepage()
     USHORT cp, rc;
 
     if (CheckOSError(VioGetCp( 0, &cp, 0 )))
-       croak("VioGetCp() error");
+       croak_with_os2error("VioGetCp()");
     return cp;
 }
 
@@ -847,7 +1304,7 @@ in_codepage()
     USHORT cp, rc;
 
     if (CheckOSError(KbdGetCp( 0, &cp, 0 )))
-       croak("KbdGetCp() error");
+       croak_with_os2error("KbdGetCp()");
     return cp;
 }
 
@@ -899,8 +1356,68 @@ sidOf(int pid)
   return sid;
 }
 
+STRLEN
+StrLen(ULONG addr, ULONG lim, I32 unitsize)
+{
+    switch (unitsize) {
+      case 1:
+       {
+           char *s = (char *)addr;
+           char *s1 = s, *e = (char *)(addr + lim);
+
+           while (s < e && *s)
+               s++;
+           return s - s1;
+       }
+       break;
+      case 2:
+       {
+           short *s = (short *)addr;
+           short *s1 = s, *e = (short *)(addr + lim);
+
+           while (s < e && *s)
+               s++;
+           return (char*)s - (char*)s1;
+       }
+       break;
+      case 4:
+       {
+           int *s = (int *)addr;
+           int *s1 = s, *e = (int *)(addr + lim);
+
+           while (s < e && *s)
+               s++;
+           return (char*)s - (char*)s1;
+       }
+       break;
+      case 8:
+       {
+           long long *s = (long long *)addr;
+           long long *s1 = s, *e = (long long *)(addr + lim);
+
+           while (s < e && *s)
+               s++;
+           return (char*)s - (char*)s1;
+       }
+       break;
+      default:
+       croak("StrLen: unknown unitsize %d", (int)unitsize);
+    }
+}
+
+#define ulMPFROMSHORT(i)               ((unsigned long)MPFROMSHORT(i))
+#define ulMPVOID()                     ((unsigned long)MPVOID)
+#define ulMPFROMCHAR(i)                        ((unsigned long)MPFROMCHAR(i))
+#define ulMPFROM2SHORT(x1,x2)          ((unsigned long)MPFROM2SHORT(x1,x2))
+#define ulMPFROMSH2CH(s, c1, c2)       ((unsigned long)MPFROMSH2CH(s, c1, c2))
+#define ulMPFROMLONG(x)                        ((unsigned long)MPFROMLONG(x))
+
+#define _MessageBox                    MessageBox
+#define _MessageBox2                   MessageBox2
+
 MODULE = OS2::Process          PACKAGE = OS2::Process
 
+PROTOTYPES: ENABLE
 
 unsigned long
 constant(name,arg)
@@ -939,6 +1456,7 @@ swentry_expand( SV *sv )
 
 SV *
 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)
+PROTOTYPE: DISABLE
 
 int
 change_swentry( SV *sv )
@@ -948,7 +1466,8 @@ sesmgr_title_set(s)
     char *s
 
 SV *
-process_swentry(unsigned long pid = getpid(), unsigned long hwnd = NULLHANDLE);
+process_swentry(unsigned long pid = getpid(), HWND hwnd = NULLHANDLE);
+  PROTOTYPE: DISABLE
 
 int
 swentry_size()
@@ -956,23 +1475,33 @@ swentry_size()
 SV *
 swentries_list()
 
+void
+ResetWinError()
+   POSTCALL:
+       XSRETURN_YES;
+
 int
-WindowText_set(unsigned long hwndFrame, char *title)
+WindowText_set(HWND hwndFrame, char *title)
+
+bool
+FocusWindow_set(HWND hwndFocus, HWND hwndDesktop = HWND_DESKTOP)
 
 bool
-FocusWindow_set(unsigned long hwndFocus, unsigned long hwndDesktop = HWND_DESKTOP)
+ShowWindow(HWND hwnd, bool fShow = TRUE)
 
 bool
-ShowWindow(unsigned long hwnd, bool fShow = TRUE)
+EnableWindow(HWND hwnd, bool fEnable = TRUE)
 
 bool
-PostMsg(unsigned long hwnd, unsigned long msg, unsigned long mp1 = 0, unsigned long mp2 = 0)
+PostMsg(HWND hwnd, unsigned long msg, unsigned long mp1 = 0, unsigned long mp2 = 0)
+    C_ARGS: hwnd, msg, (MPARAM)mp1, (MPARAM)mp2
 
 bool
-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)
+WindowPos_set(HWND hwnd, long x, long y, unsigned long fl = SWP_MOVE, long cx = 0, long cy = 0, HWND hwndInsertBehind = HWND_TOP)
+  PROTOTYPE: DISABLE
 
 unsigned long
-BeginEnumWindows(unsigned long hwnd)
+BeginEnumWindows(HWND hwnd)
 
 bool
 EndEnumWindows(unsigned long henum)
@@ -981,24 +1510,60 @@ unsigned long
 GetNextWindow(unsigned long henum)
 
 bool
-IsWindow(unsigned long hwnd, unsigned long hab = Acquire_hab())
+IsWindowVisible(HWND hwnd)
+
+bool
+IsWindowEnabled(HWND hwnd)
+
+bool
+IsWindowShowing(HWND hwnd)
 
 unsigned long
-QueryWindow(unsigned long hwnd, long cmd)
+QueryWindow(HWND hwnd, long cmd)
 
 unsigned long
-IsChild(unsigned long hwnd, unsigned long hwndParent)
+IsChild(HWND hwnd, HWND hwndParent)
 
 unsigned long
-WindowFromId(unsigned long hwndParent, unsigned long id)
+WindowFromId(HWND hwndParent, unsigned long id)
 
 unsigned long
-WindowFromPoint(long x, long y, unsigned long hwnd, bool fChildren = 0)
+WindowFromPoint(long x, long y, HWND hwnd = HWND_DESKTOP, bool fChildren = TRUE)
+PROTOTYPE: DISABLE
 
 unsigned long
-EnumDlgItem(unsigned long hwndDlg, unsigned long code, unsigned long hwnd = NULLHANDLE)
+EnumDlgItem(HWND hwndDlg, unsigned long code, HWND hwnd = NULLHANDLE)
    C_ARGS: hwndDlg, hwnd, code
 
+bool
+EnableWindowUpdate(HWND hwnd, bool fEnable = TRUE)
+
+bool
+SetWindowBits(HWND hwnd, long index, unsigned long flData, unsigned long flMask)
+
+bool
+SetWindowPtr(HWND hwnd, long index, unsigned long p)
+    C_ARGS: hwnd, index, (PVOID)p
+
+bool
+SetWindowULong(HWND hwnd, long index, unsigned long i)
+
+bool
+SetWindowUShort(HWND hwnd, long index, unsigned short i)
+
+bool
+IsWindow(HWND hwnd, HAB hab = Acquire_hab())
+    C_ARGS: hab, hwnd
+
+BOOL
+ActiveWindow_set(HWND hwnd, HWND hwndDesktop = HWND_DESKTOP)
+    CODE:
+       RETVAL = SetActiveWindow(hwndDesktop, hwnd);
+
+unsigned long
+LoadPointer(unsigned long idres, unsigned long hmod = 0, HWND hwndDesktop = HWND_DESKTOP)
+    C_ARGS: hwndDesktop, hmod, idres
+
 int
 out_codepage()
 
@@ -1035,44 +1600,253 @@ process_codepages()
 bool
 process_codepage_set(int cp)
 
-MODULE = OS2::Process          PACKAGE = OS2::Process  PREFIX = Query
+void
+cursor(OUTLIST int stp, OUTLIST int ep, OUTLIST int wp, OUTLIST int ap)
+  PROTOTYPE:
+
+bool
+cursor_set(int s, int e, int w = cursor__(0), int a = cursor__(1))
+
+SV*
+_kbdChar(int nowait = 0, int handle = 0)
+
+SV*
+_kbdStatus(int handle = 0)
+
+void
+_kbdStatus_set(SV *sv, int handle = 0)
+   POSTCALL:
+       XSRETURN_YES;
+
+SV*
+_vioConfig(int which = 0, int handle = 0)
+
+SV*
+_vioMode()
+
+void
+_vioMode_set(SV *buffer)
+   POSTCALL:
+       XSRETURN_YES;
+
+SV*
+_vioState(int what, int first = -1, int count = -1)
+
+void
+_vioState_set(SV *buffer)
+   POSTCALL:
+       XSRETURN_YES;
+
+SV*
+vioFont( int type = 0, OUTLIST int w, OUTLIST int h)
+
+void
+vioFont_set(SV *buffer, int cellwidth, int cellheight, int type = 0)
+   POSTCALL:
+       XSRETURN_YES;
+
+NO_OUTPUT bool
+_ClipbrdData_set(unsigned long ulData, unsigned long fmt = CF_TEXT, unsigned long rgfFmtInfo = default_fmtInfo(fmt), HAB hab = perl_hab_GET())
+    PROTOTYPE: DISABLE
+    C_ARGS: hab, ulData, fmt, rgfFmtInfo
+    POSTCALL:
+       if (CheckWinError(RETVAL))
+           croak_with_os2error("_ClipbrdData_set() error");
+       XSRETURN_YES;
+
+void
+ClipbrdData_set(SV *text, int convert_nl = 1, unsigned long fmt = CF_TEXT, unsigned long rgfFmtInfo = default_fmtInfo(fmt), HAB hab = perl_hab_GET())
+    PROTOTYPE: DISABLE
+    POSTCALL:
+       XSRETURN_YES;
+
+void
+ClipbrdOwner_set(HWND hwnd, HAB hab = perl_hab_GET())
+    C_ARGS: hab, hwnd
+    POSTCALL:
+       XSRETURN_YES;
+
+void
+ClipbrdViewer_set(HWND hwnd, HAB hab = perl_hab_GET())
+    C_ARGS: hab, hwnd
+    POSTCALL:
+       XSRETURN_YES;
 
 unsigned long
-QueryFocusWindow(unsigned long hwndDesktop = HWND_DESKTOP)
+EnumClipbrdFmts(unsigned long fmt = 0, HAB hab = perl_hab_GET())
+    C_ARGS: hab, fmt
 
-long
-QueryWindowTextLength(unsigned long hwnd)
+unsigned long
+AddAtom(char *pszAtomName, HATOMTBL hAtomTbl = QuerySystemAtomTable())
+    C_ARGS: hAtomTbl, pszAtomName
+
+unsigned long
+FindAtom(char *pszAtomName, HATOMTBL hAtomTbl = QuerySystemAtomTable())
+    C_ARGS: hAtomTbl, pszAtomName
+
+unsigned long
+_DeleteAtom(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
+    PROTOTYPE: DISABLE
+    C_ARGS: hAtomTbl, atom
+
+#if 0
+
+unsigned long
+WinDeleteAtom(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
+    C_ARGS: hAtomTbl, atom
+
+#endif
+
+void
+Alarm(unsigned long rgfType = WA_ERROR, HWND hwndDesktop = HWND_DESKTOP)
+    C_ARGS: hwndDesktop, rgfType
+    POSTCALL:
+       XSRETURN_YES;
+
+void
+FlashWindow(HWND hwndFrame, bool fFlash)
+    POSTCALL:
+       XSRETURN_YES;
+
+STRLEN
+StrLen(ULONG addr, ULONG lim, I32 unitsize = 1)
+
+MODULE = OS2::Process          PACKAGE = OS2::Process  PREFIX = myQuery
 
 SV *
-QueryWindowText(unsigned long hwnd)
+myQueryWindowText(HWND hwnd)
 
 SV *
-QueryWindowSWP(unsigned long hwnd)
+myQueryClassName(HWND hwnd)
+
+MODULE = OS2::Process          PACKAGE = OS2::Process  PREFIX = Query
+
+unsigned long
+QueryFocusWindow(HWND hwndDesktop = HWND_DESKTOP)
+
+long
+QueryWindowTextLength(HWND hwnd)
 
 SV *
-QueryClassName(unsigned long hwnd)
+QueryWindowSWP(HWND hwnd)
 
-MODULE = OS2::Process          PACKAGE = OS2::Process  PREFIX = myWin
+unsigned long
+QueryWindowULong(HWND hwnd, long index)
+
+unsigned short
+QueryWindowUShort(HWND hwnd, long index)
+
+unsigned long
+QueryActiveWindow(HWND hwnd = HWND_DESKTOP)
+
+unsigned long
+QueryDesktopWindow(HAB hab = Acquire_hab(), unsigned long hdc = NULLHANDLE)
+
+unsigned long
+QueryClipbrdData(unsigned long fmt = CF_TEXT, HAB hab = perl_hab_GET())
+    C_ARGS: hab, fmt
+    PROTOTYPE: DISABLE
+
+ULONG
+QueryMemoryRegionSize(ULONG addr, OUTLIST ULONG flagp, ULONG len = 0xFFFFFFFF - addr, I32 interrupt = 1)
+
+unsigned long
+QueryClipbrdViewer(HAB hab = perl_hab_GET())
+
+unsigned long
+QueryClipbrdOwner(HAB hab = perl_hab_GET())
+
+void
+CloseClipbrd(HAB hab = perl_hab_GET())
+    POSTCALL:
+       XSRETURN_YES;
+
+void
+EmptyClipbrd(HAB hab = perl_hab_GET())
+   POSTCALL:
+       XSRETURN_YES;
+
+bool
+OpenClipbrd(HAB hab = perl_hab_GET())
+
+unsigned long
+QueryAtomUsage(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
+    C_ARGS: hAtomTbl, atom
+
+unsigned long
+QueryAtomLength(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
+    C_ARGS: hAtomTbl, atom
+   POSTCALL:
+       if (!RETVAL)
+           XSRETURN_EMPTY;
+
+unsigned long
+QuerySystemAtomTable()
+
+unsigned long
+QuerySysPointer(long lId, bool fCopy = 1, HWND hwndDesktop = HWND_DESKTOP)
+    C_ARGS: hwndDesktop, lId, fCopy
+
+unsigned long
+CreateAtomTable(unsigned long initial = 0, unsigned long buckets = 0)
+
+unsigned long
+_DestroyAtomTable(HATOMTBL hAtomTbl)
+    PROTOTYPE: DISABLE
+
+
+MODULE = OS2::Process          PACKAGE = OS2::Process  PREFIX = myWinQuery
+
+unsigned long
+myWinQueryWindowPtr(HWND hwnd, long index)
 
 NO_OUTPUT BOOL
-myWinQueryWindowProcess(unsigned long hwnd, OUTLIST unsigned long pid, OUTLIST unsigned long tid)
+myWinQueryWindowProcess(HWND hwnd, OUTLIST unsigned long pid, OUTLIST unsigned long tid)
+   PROTOTYPE: $
    POSTCALL:
        if (CheckWinError(RETVAL))
-           croak("QueryWindowProcess() error");
+           croak_with_os2error("WindowProcess() error");
+
+SV *
+myWinQueryActiveDesktopPathname()
 
 void
-cursor(OUTLIST int stp, OUTLIST int ep, OUTLIST int wp, OUTLIST int ap)
+myWinQueryClipbrdFmtInfo(OUTLIST unsigned long prgfFmtInfo, unsigned long fmt = CF_TEXT, HAB hab = perl_hab_GET())
+   C_ARGS: hab, fmt, &prgfFmtInfo
 
-bool
-cursor_set(int s, int e, int w = cursor__(0), int a = cursor__(1))
+SV *
+myWinQueryAtomName(ATOM atom, HATOMTBL hAtomTbl = QuerySystemAtomTable())
+
+MODULE = OS2::Process          PACKAGE = OS2::Process  PREFIX = myWin
 
 int
-myWinSwitchToProgram(unsigned long hsw)
+myWinSwitchToProgram(HSWITCH hsw = switch_of(NULLHANDLE, getpid()))
     PREINIT:
        ULONG rc;
 
+#if 0
+
 unsigned long
-myWinQueryActiveWindow(unsigned long hwnd = HWND_DESKTOP)
+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)
+    C_ARGS: hwndParent, hwndOwner, pszText, pszCaption, idWindow, flStyle
+
+#endif
+
+unsigned long
+_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)
+    C_ARGS: hwndParent, hwndOwner, pszText, pszCaption, idWindow, flStyle
+    POSTCALL:
+       if (RETVAL == MBID_ERROR)
+           RETVAL = 0;
+
+unsigned long
+_MessageBox2(char *pszText, char* pmb2info, char *pszCaption = "Perl script message", HWND hwndParent = HWND_DESKTOP, HWND hwndOwner = NULLHANDLE, unsigned long idWindow = 0)
+    C_ARGS: hwndParent, hwndOwner, pszText, pszCaption, idWindow, (PMB2INFO)pmb2info
+    POSTCALL:
+       if (RETVAL == MBID_ERROR)
+           RETVAL = 0;
+
+MODULE = OS2::Process          PACKAGE = OS2::Process  PREFIX = myWinQuery
 
 MODULE = OS2::Process          PACKAGE = OS2::Process  PREFIX = get
 
@@ -1087,6 +1861,36 @@ sidOf(int pid = getpid())
 
 void
 getscrsize(OUTLIST int wp, OUTLIST int hp)
+  PROTOTYPE:
 
 bool
 scrsize_set(int w_or_h, int h = -9999)
+
+void
+get_InvalidateRect(HWND hwnd, char *prcl, bool fIncludeChildren)
+
+void
+get_CreateFrameControls(HWND hwndFrame, char *pfcdata, char* pszTitle)
+
+MODULE = OS2::Process          PACKAGE = OS2::Process  PREFIX = ul
+
+unsigned long
+ulMPFROMSHORT(unsigned short i)
+
+unsigned long
+ulMPVOID()
+
+unsigned long
+ulMPFROMCHAR(unsigned char i)
+
+unsigned long
+ulMPFROM2SHORT(unsigned short x1, unsigned short x2)
+  PROTOTYPE: DISABLE
+
+unsigned long
+ulMPFROMSH2CH(unsigned short s, unsigned char c1, unsigned char c2)
+  PROTOTYPE: DISABLE
+
+unsigned long
+ulMPFROMLONG(unsigned long x)
+