home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / evbl0627.zip / everblue_20010627.zip / x11 / Xlib_pmctls.c < prev    next >
C/C++ Source or Header  |  2001-04-30  |  40KB  |  1,094 lines

  1.  
  2. #include "Xlib_private.h"
  3. #include <time.h>
  4. #include "Xatomtype.h"
  5.  
  6. #define UM_UNMAP (WM_USER+10)
  7. #define UM_MAP (WM_USER+11)
  8. #define UM_GRAVITY (WM_USER+12)
  9. #define UM_RESIZE (WM_USER+13)
  10. #define UM_SETFOCUS (WM_USER+14)
  11. #define UM_GIMMIE (WM_USER+15)
  12. #define UM_CHARSEQ (WM_USER+16)
  13. #define UM_REPARENT (WM_USER+17)
  14.  
  15. #include "x11pmvk.h"
  16.  
  17. HAB pmctls_hab = 0;
  18. HACCEL haccel;
  19. int serial = 0;
  20. HMODULE hk_module = NULLHANDLE;
  21. Atom (*Xlib_XInternAtom)(char*, Bool);
  22. char *(*Xlib_GetAtomName)(Atom);
  23.  
  24. int Xlib_PMWM_Handler0(HWND*, ULONG*, MPARAM*, MPARAM*);
  25. int Xlib_PMWM_Handler1(HWND*, ULONG*, MPARAM*, MPARAM*);
  26.  
  27. MRESULT EXPENTRY pmhwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  28. {
  29.     MRESULT result = (MRESULT)0;
  30.     Xlib_PMWM_Handler0(&hWnd, &msg, &mp1, &mp2);
  31.     switch(msg) {
  32.     case UM_CreateWindow:
  33.         {
  34.             /*static ULONG flStyle = FCF_MINMAX | FCF_SYSMENU | FCF_TITLEBAR |
  35.              FCF_SIZEBORDER | FCF_TASKLIST;*/
  36.             Xlib_CreateWindow *args = PVOIDFROMMP(mp1);
  37.             HPOINTER tmpicon = 0;
  38.             HMODULE x11mod = 0;
  39.             HWND hwndClient, hwndFrame = args->hwndParent;
  40.             if (mp2)
  41.                 hwndFrame = WinCreateStdWindow( args->hwndParent, args->flStyle,
  42.                                                 &args->frameStyle, NULL, args->pszTitle, 0L, NULLHANDLE, 0, NULL);
  43.             hwndClient = WinCreateWindow( hwndFrame,
  44.                                           "XPMChild", args->pszTitle, args->flStyle,
  45.                                           args->x, args->y, args->cx, args->cy, NULLHANDLE,
  46.                                           HWND_TOP, FID_CLIENT, args->winattrib, NULL);
  47.             if (hwndClient) wndcount++;
  48.             if(mp2)
  49.             {
  50.                 DosQueryModuleHandle("X11", &x11mod);
  51.                 if(x11mod && (tmpicon = WinLoadPointer(HWND_DESKTOP,x11mod,PMXLIB_DEFAULT_ICON)))
  52.                     WinSendMsg(hwndFrame, WM_SETICON,(MPARAM)tmpicon, 0);
  53.             }
  54.             if (mp2) WinSetWindowULong(hwndClient, QWP_FRAMEHWND, hwndFrame);
  55.             else     WinSetWindowULong(hwndClient, QWP_FRAMEHWND, hwndClient);
  56.             args->winattrib->hdc = WinOpenWindowDC(hwndClient);
  57.             /*WinSetVisibleRegionNotify(hwndClient, TRUE);*/
  58.             result = MPFROMHWND(hwndClient);
  59.             break;
  60.         }
  61.     case UM_DestroyWindow:
  62.         {
  63.             BOOL rc;
  64.             rc = WinDestroyWindow((HWND)mp1);
  65.             if (rc) {
  66.                 wndcount--;
  67.                 result = (MRESULT)TRUE;
  68.             }
  69.             break;
  70.         }
  71.     case UM_SetWindowPos:
  72.         {
  73.             Xlib_SetWindowPos *args = PVOIDFROMMP(mp1);
  74.  
  75.             result = (MRESULT)
  76.                 WinSetWindowPos( args->hwnd, args->hwndInsertBehind,
  77.                                  args->x, args->y, args->cx, args->cy, args->fl);
  78.  
  79.             if (args->fl & SWP_HIDE)
  80.                 WinPostMsg(args->hwnd, UM_UNMAP, MPFROMHWND(args->hwnd), (MPARAM)1); else
  81.                     if (args->fl & SWP_SHOW)
  82.                         WinPostMsg(args->hwnd, UM_MAP, MPFROMHWND(args->hwnd), (MPARAM)1);
  83.  
  84.             break;
  85.         }
  86.     case UM_ReparentWindow:
  87.         {
  88.             Xlib_ReparentWindow *args = PVOIDFROMMP(mp1);
  89.             if (WinSetParent((HWND)args->w, (HWND)args->p, FALSE)) {
  90.                 SWP swp;
  91.                 WinQueryWindowPos((HWND)args->p, &swp);
  92.                 WinSetWindowPos((HWND)args->w, 0, args->x, swp.cy - args->y, 0, 0, SWP_MOVE);
  93.                 result = (MRESULT)1;
  94.             }
  95.             break;
  96.         }
  97.     case UM_ChangeProperty:
  98.         {
  99.             Xlib_ChangeProperty *args = PVOIDFROMMP(mp1);
  100.             XWindowAttributes *winattrib = GetWinAttrib(args->w, NULL);
  101.             WinAttribData *attrib = (winattrib)?WinQueryWindowPtr(args->w, QWP_WINATTRIB):NULL;
  102.             char *st1, *st2;
  103.             int state=PropertyNewValue, i;
  104.             Atom tmpatm;
  105.  
  106.             if (!mp1 || !args->property || !attrib) return (MRESULT)0;
  107.  
  108.             if (args->property == XA_WM_NAME && args->type == XA_STRING) {
  109.                 if (attrib) {
  110.                     if (attrib->wm_name) free(attrib->wm_name);
  111.                     attrib->wm_name = malloc(args->nelements+1);
  112.                     strncpy(attrib->wm_name, args->data, args->nelements);
  113.                     attrib->wm_name[args->nelements] = '\0';
  114.                 }
  115.             } else
  116.                 if (args->property == XA_WM_ICON_NAME && args->type == XA_STRING) {
  117.                     if (attrib && args->nelements) {
  118.                         if (attrib->wm_iconname) free(attrib->wm_iconname);
  119.                         attrib->wm_iconname = malloc(args->nelements+1);
  120.                         strncpy(attrib->wm_iconname, args->data, args->nelements);
  121.                         attrib->wm_iconname[args->nelements] = '\0';
  122.                     }
  123.                 } else
  124.                     if (args->property == XA_WM_COMMAND && args->type == XA_STRING) {
  125.                         if (attrib) {
  126.                             st1 = malloc(args->nelements+1);
  127.                             strncpy(st1, args->data, args->nelements);
  128.                             st1[args->nelements] = '\0';
  129.                             WinSetWindowText(mainhwnd,st1);
  130.                             free(st1);
  131.                         }
  132.                     } else
  133.                         if (args->property == XA_WM_CLASS && args->type == XA_STRING) {
  134.                             if (attrib && args->nelements) {
  135.                                 if (attrib->wm_class) free(attrib->wm_class);
  136.                                 attrib->wm_class = malloc(args->nelements+1);
  137.                                 strncpy(attrib->wm_class, args->data, args->nelements);
  138.                                 attrib->wm_class[args->nelements] = '\0';
  139.                             }
  140.                         } else
  141.                             if (args->property == XA_WM_NORMAL_HINTS && args->type == XA_WM_SIZE_HINTS) {
  142.                                 if (attrib && args->nelements) {
  143.                                     if (attrib->sizehints) free(attrib->sizehints);
  144.                                     attrib->sizehints = calloc(1, sizeof(XSizeHints) );
  145.                                     memcpy(attrib->sizehints, args->data,
  146.                                            (args->format * args->nelements) / 8);
  147.                                 }
  148.                             } else
  149.                                 if (args->property == XA_WM_HINTS && args->type == XA_WM_HINTS) {
  150.                                     if (attrib && args->nelements) {
  151.                                         if (attrib->hints) free(attrib->hints);
  152.                                         attrib->hints = calloc(1, sizeof(XWMHints) );
  153.                                         memcpy(attrib->hints, args->data,
  154.                                                (args->format * args->nelements) / 8);
  155.                                     }
  156.                                 } else
  157.                                     if (args->property == XA_WM_CLIENT_MACHINE
  158.                                         || ((tmpatm = XInternAtom(maindisplay,"__SWM_VROOT", True)) && tmpatm == args->property)
  159.                                         || ((tmpatm = XInternAtom(maindisplay,"WM_LOCALE_NAME", True)) && tmpatm == args->property)
  160.                                        ){ /* not useful in Everblue */ } else
  161.                                            if ((tmpatm = XInternAtom(maindisplay,"WM_CLIENT_LEADER", True)) &&
  162.                                                args->property == tmpatm && args->type == XA_WINDOW) {
  163.                                                if (attrib && args->nelements) {
  164.                                                    attrib->wm_client_leader = ((Window *)args->data)[0];
  165.                                                }
  166.                                            } else
  167.                                                if ((tmpatm = XInternAtom(maindisplay,"WM_TRANSIENT_FOR", True)) &&
  168.                                                    args->property == tmpatm && args->type == XA_WINDOW) {
  169.                                                    if (attrib && args->nelements) {
  170.                                                        /* This appears to be broken - Brian */
  171.                                                        /*  XWindowAttributes *mattrib = GetWinAttrib(((Window *)args->data)[0], NULL);
  172.                                                         HWND hwndframe = mattrib?
  173.                                                         WinQueryWindowULong(((Window *)args->data)[0],
  174.                                                         QWP_FRAMEHWND):((Window *)args->data)[0];
  175.                                                         WinSetOwner(args->w, hwndframe);
  176.                                                         if(mattrib)
  177.                                                         free(mattrib);*/
  178.                                                    }
  179.                                                } else
  180.                                                    if ((tmpatm = XInternAtom(maindisplay,"WM_PROTOCOLS", True)) &&
  181.                                                        args->property == tmpatm && args->type == XA_ATOM)
  182.                                                        for (i=0; i<args->nelements; i++)
  183.                                                        {
  184.                                                            Atom atom = ((Atom*)(args->data))[i];
  185.                                                            char *protocol = XGetAtomName(maindisplay, atom);
  186.                                                            if (!protocol) continue;
  187.                                                            if (!strcmp(protocol,"WM_DELETE_WINDOW") && attrib)
  188.                                                                attrib->delete_window_notify = TRUE; else
  189.                                                                    printf("Unhandled WM_PROTOCOL method '%s'\n",protocol);
  190.                                                            free(protocol);
  191.                                                        } else {
  192.                                                            fprintf(stderr,"UM_ChangeProperty not implemented!\n   property='%s'(%ld), type='%s'(%ld), format=%d, mode=%d, ",
  193.                                                                    st1=XGetAtomName(maindisplay, args->property), args->property,
  194.                                                                    st2=XGetAtomName(maindisplay, args->type), args->type, args->format, args->mode);
  195.                                                            free(st1); free(st2);
  196.                                                            if (!args->nelements)
  197.                                                                fprintf(stderr,"no args\n");
  198.                                                            else {
  199.                                                                fprintf(stderr,"{ ");
  200.                                                                if (args->type == XA_ATOM)
  201.                                                                    for (i=0; i<args->nelements; i++) {
  202.                                                                        fprintf(stderr,"'%s' ",
  203.                                                                                st1=XGetAtomName(maindisplay, ((Atom *)(args->data))[i]));
  204.                                                                        free(st1);
  205.                                                                    } else
  206.                                                                        if (args->type == XA_STRING) {
  207.                                                                            st1 = malloc(args->nelements+1);
  208.                                                                            strncpy(st1, args->data, args->nelements);
  209.                                                                            st1[args->nelements] = '\0';
  210.                                                                            fprintf(stderr,"'%s' ",st1);
  211.                                                                            free(st1);
  212.                                                                        } else
  213.                                                                            fprintf(stderr,"%d elements ",args->nelements);
  214.                                                                fprintf(stderr,"}\n");
  215.                                                            }
  216.                                                        }
  217.             WinPostMsg((HWND)args->w,UM_ChangeProperty,(MPARAM)args->property,(MPARAM)state);
  218.             break;
  219.         }
  220.     case UM_GetWinProperty:
  221.         {
  222.             Xlib_GetWinProperty *args = PVOIDFROMMP(mp1);
  223.             XWindowAttributes *winattrib = GetWinAttrib(args->w, NULL);
  224.             WinAttribData *attrib = (winattrib)?WinQueryWindowPtr(args->w, QWP_WINATTRIB):NULL;
  225.             Atom tmpatm;
  226.  
  227.             *args->prop_return = NULL;
  228.             *args->actual_type_return = None;
  229.  
  230.             if (((tmpatm = XInternAtom(maindisplay,"__SWM_VROOT", True)) && tmpatm == args->property)) {
  231.                 /* not useful in Everblue */
  232.             } else if((tmpatm = XInternAtom(maindisplay,"WM_NORMAL_HINTS", True)) && tmpatm == args->property) {
  233.                 if(attrib->hints /*&& args->req_type == (XA_WM_HINTS || AnyPropertyType)*/)
  234.                 {
  235.                     *args->actual_type_return = XA_WM_SIZE_HINTS;
  236.                     *args->nitems_return = OldNumPropSizeElements;
  237.                     *args->actual_format_return = 32;
  238.                     *args->prop_return = (unsigned char *)malloc(sizeof(XSizeHints));
  239.                     memcpy(*args->prop_return, attrib->sizehints, sizeof(XSizeHints));
  240.                 }
  241.             } else if((tmpatm = XInternAtom(maindisplay,"WM_HINTS", True)) && tmpatm == args->property) {
  242.                 if(attrib->hints /*&& args->req_type == (XA_WM_HINTS || AnyPropertyType)*/)
  243.                 {
  244.                     *args->actual_type_return = XA_WM_HINTS;
  245.                     *args->nitems_return = NumPropWMHintsElements;
  246.                     *args->actual_format_return = 32;
  247.                     *args->prop_return = (unsigned char *)malloc(sizeof(XWMHints));
  248.                     memcpy(*args->prop_return, attrib->hints, sizeof(XWMHints));
  249.                 }
  250.             } else if((tmpatm = XInternAtom(maindisplay,"RESOURCE_MANAGER", True)) && tmpatm == args->property) {
  251.                 if(maindisplay->xdefaults)
  252.                 {
  253.                     *args->actual_type_return = XA_RESOURCE_MANAGER;
  254.                     *args->nitems_return = 1;
  255.                     *args->actual_format_return = 32;
  256.                     *args->prop_return = (unsigned char *)strdup(maindisplay->xdefaults);
  257.                 }
  258.             } else {
  259.                 char *st1, *st2;
  260.                 fprintf(stderr,"UM_GetWinProperty not implemented!\n   property='%s', type='%s', \n",
  261.                         st1=XGetAtomName(maindisplay, args->property),
  262.                         st2=XGetAtomName(maindisplay, args->req_type));
  263.                 free(st1); free(st2);
  264.                 *args->actual_type_return = None;
  265.                 *args->nitems_return = 0;
  266.                 *args->prop_return = NULL;
  267.             }
  268.             break;
  269.         }
  270.     case UM_CreateGC:
  271.         fprintf(stderr,"UM_CreateGC obseleted!\n");
  272.         break;
  273.     default:
  274.         result = WinDefWindowProc(hWnd, msg, mp1, mp2);
  275.     }
  276.     Xlib_PMWM_Handler1(&hWnd, &msg, &mp1, &mp2);
  277.     return result;
  278. }
  279.  
  280. MRESULT EXPENTRY xpmwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  281. {
  282.     MRESULT result = (MRESULT)0;
  283.     WinAttribData *attrib = WinQueryWindowPtr(hWnd, QWP_WINATTRIB);
  284.     XWindowAttributes *winattrib = (attrib)?GetWinAttrib(hWnd,NULL):NULL;
  285.     XEvent *new = Xlib_NewEvent();
  286.     new->xany.serial = serial++;
  287.     new->xany.display = maindisplay;
  288.     new->xany.window = hWnd;
  289.     new->xany.send_event = False;
  290.  
  291.     Xlib_PMWM_Handler0(&hWnd, &msg, &mp1, &mp2);
  292.     switch(msg) {
  293.     case WM_CREATE:
  294.         attrib = ((CREATESTRUCT *)(PVOIDFROMMP(mp2)))->pCtlData;
  295.         winattrib = &attrib->winattrib;
  296.  
  297.         /*x11_console_notice("CreateNotify");*/
  298.         new->type = CreateNotify;
  299.         new->xcreatewindow.x = winattrib->x;
  300.         new->xcreatewindow.y = winattrib->y;
  301.         new->xcreatewindow.width = winattrib->width;
  302.         new->xcreatewindow.height = winattrib->height;
  303.         new->xcreatewindow.border_width = winattrib->border_width;
  304.         winattrib->root = hwndDesktop;
  305.         WinSetWindowPtr(hWnd, QWP_WINATTRIB, attrib);
  306.         WinPostMsg(hWnd,WM_SEM3,0,0);
  307.         break;
  308.     case WM_DESTROY:
  309.         if (!attrib) goto passover;
  310.         free(attrib);
  311.         x11_console_notice("DestroyNotify");
  312.         new->type = DestroyNotify;
  313.         new->xdestroywindow.event = hWnd;
  314.         break;
  315.     case WM_REALIZEPALETTE:
  316.         {
  317.             ULONG pc;
  318.             HPS hps;
  319.  
  320.             hps = WinBeginPaint(hWnd, NULLHANDLE, NULL);
  321.             WinRealizePalette(hWnd, hps, &pc);
  322.             WinEndPaint(hps);
  323.         }
  324.         break;
  325.         case WM_CLOSE:
  326.             if (attrib && attrib->delete_window_notify) {
  327.                 /*x11_console_notice("WM_DELETE_WINDOW");*/
  328.                 new->type = ClientMessage;
  329.                 new->xclient.message_type = XInternAtom(maindisplay,"WM_PROTOCOLS", False);
  330.                 new->xclient.format = 32;
  331.                 new->xclient.data.l[0] = XInternAtom(maindisplay,"WM_DELETE_WINDOW",False);
  332.                 new->xclient.data.l[1] = 0;
  333.                 new->xclient.send_event = True;
  334.                 if (attrib->wm_client_leader)
  335.                     new->xclient.window = attrib->wm_client_leader;
  336.             } else {
  337.                 Xlib_RemoveEvent(new);
  338.                 WinDestroyWindow(hWnd);
  339.                 goto endproc;
  340.             }
  341.             break;
  342.     case UM_SETFOCUS:
  343.         {
  344.             char winclass[32];
  345.             HWND parent = WinQueryWindow(hWnd, QW_PARENT);
  346.             winclass[WinQueryClassName(parent, sizeof(winclass), winclass)] = 0;
  347.             if (!strcmp(winclass,"XPMChild"))
  348.                 WinPostMsg(parent, UM_SETFOCUS, mp1, mp2);
  349.             if (!(winattrib->your_event_mask & FocusChangeMask))
  350.                 goto nonevent;
  351.             if (SHORT1FROMMP(mp2)==TRUE) {
  352.                 /*x11_console_notice("FocusIn");*/
  353.                 new->type = FocusIn;
  354.             } else {
  355.                 /*x11_console_notice("FocusOut");*/
  356.                 new->type = FocusOut;
  357.             }
  358.             new->xfocus.mode = NotifyNormal;
  359.             new->xfocus.detail = NotifyNonlinear;
  360.             break;
  361.         }
  362.     case WM_SETFOCUS:
  363.         {
  364.             char winclass[32];
  365.             HWND parent = WinQueryWindow(hWnd, QW_PARENT);
  366.             winclass[WinQueryClassName(parent, sizeof(winclass), winclass)] = 0;
  367.             if (!strcmp(winclass,"XPMChild"))
  368.                 WinPostMsg(parent, UM_SETFOCUS, mp1, mp2);
  369.             if (!(winattrib->your_event_mask & FocusChangeMask))
  370.                 goto nonevent;
  371.             if (SHORT1FROMMP(mp2)==TRUE) {
  372.                 /*x11_console_notice("FocusIn");*/
  373.                 new->type = FocusIn;
  374.             } else {
  375.                 /*x11_console_notice("FocusOut");*/
  376.                 new->type = FocusOut;
  377.             }
  378.             new->xfocus.mode = NotifyNormal;
  379.             new->xfocus.detail = NotifyPointer;
  380.             break;
  381.         }
  382.     case WM_MOVE:
  383.         {
  384.             HWND hwndframe = WinQueryWindowULong(hWnd, QWP_FRAMEHWND);
  385.             SWP swp, parent;
  386.             if (!winattrib || !hwndframe)
  387.                 goto passover;
  388.             WinQueryWindowPos(hwndframe,&swp);
  389.             if (!(swp.fl &(SWP_HIDE|SWP_MINIMIZE)) && attrib->wm_name)
  390.                 WinSetWindowText(hwndframe, attrib->wm_name);
  391.             if ((swp.fl &(SWP_HIDE|SWP_MINIMIZE)) && attrib->wm_iconname)
  392.                 WinSetWindowText(hwndframe, attrib->wm_iconname);
  393.             WinQueryWindowPos(WinQueryWindow(hwndframe,QW_PARENT),&parent);
  394.             new->type = ConfigureNotify;
  395.             new->xconfigure.event = hWnd;
  396.             if (hwndframe == hWnd) {
  397.                 new->xconfigure.x = winattrib->x = swp.x;
  398.                 new->xconfigure.y = winattrib->y = parent.cy - swp.y - swp.cy;
  399.             } else {
  400.                 new->xconfigure.x = winattrib->x = swp.x + winattrib->border_width;
  401.                 new->xconfigure.y = winattrib->y = parent.cy - swp.y - swp.cy +
  402.                     winattrib->border_width + WinQuerySysValue(hwndDesktop,SV_CYTITLEBAR);
  403.             }
  404.             new->xconfigure.width = winattrib->width;
  405.             new->xconfigure.height = winattrib->height;
  406.             new->xconfigure.border_width = winattrib->border_width;
  407.             if (attrib->wm_client_leader)
  408.                 new->xconfigure.window = attrib->wm_client_leader;
  409.             pthread_mutex_lock(&evmutex);
  410.             if (attrib->lastconfigure) {
  411.                 XEvent *last = attrib->lastconfigure;
  412.                 memcpy(last, new, sizeof(XEvent));
  413.                 pthread_mutex_unlock(&evmutex);
  414.                 goto nonevent;
  415.             }
  416.             attrib->lastconfigure = new;
  417.             pthread_mutex_unlock(&evmutex);
  418.             break;
  419.         }
  420.     case UM_UNMAP:
  421.     case UM_MAP:
  422.         if (msg == UM_UNMAP)
  423.             new->type = UnmapNotify;
  424.         else
  425.             new->type = MapNotify;
  426.         new->xunmap.event = HWNDFROMMP(mp1);
  427.         new->xunmap.from_configure = mp2?TRUE:FALSE;
  428.         if (!(GetWinAttrib(hWnd,NULL)->your_event_mask &
  429.               (StructureNotifyMask | SubstructureNotifyMask)))
  430.             goto nonevent;
  431.         break;
  432.     case WM_SIZE:
  433.         {
  434.             POINTL delta;
  435.             HENUM children;
  436.             HWND child;
  437.             if (!winattrib) goto passover;
  438.             delta.x = SHORT1FROMMP(mp2) - winattrib->width;
  439.             delta.y = SHORT2FROMMP(mp2) - winattrib->height;
  440.             children = WinBeginEnumWindows(hWnd);
  441.             while ((child = WinGetNextWindow(children))) {
  442.                 XWindowAttributes *chattrib = GetWinAttrib(child,NULL);
  443.                 int change = 0;
  444.                 SWP swp;
  445.                 if (!chattrib) continue;
  446.                 WinQueryWindowPos(child, &swp);
  447.                 switch (chattrib->win_gravity) {
  448.                 case ForgetGravity:
  449.                     WinSetWindowPos(child,NULLHANDLE,0,0,0,0,SWP_HIDE);
  450.                     WinPostMsg(child,UM_UNMAP,MPFROMHWND(child),(MPARAM)1);
  451.                     continue;
  452.                 case NorthWestGravity:
  453.                 case NorthGravity:
  454.                 case NorthEastGravity:
  455.                 case StaticGravity:
  456.                     swp.y += delta.y / 2;
  457.                 case WestGravity:
  458.                 case CenterGravity:
  459.                 case EastGravity:
  460.                     swp.y += delta.y - (delta.y / 2);
  461.                     change++;
  462.                 }
  463.                 switch (chattrib->win_gravity) {
  464.                 case NorthEastGravity:
  465.                 case EastGravity:
  466.                 case SouthEastGravity:
  467.                     swp.x += delta.x / 2;
  468.                 case NorthGravity:
  469.                 case CenterGravity:
  470.                 case SouthGravity:
  471.                     swp.x += delta.x - (delta.x / 2);
  472.                     change++;
  473.                 }
  474.                 if (change)
  475.                     WinSetWindowPos(child, NULLHANDLE, swp.x, swp.y,
  476.                                     0, 0, SWP_MOVE | SWP_NOREDRAW);
  477.                 WinPostMsg(child, UM_GRAVITY,
  478.                            MPFROM2SHORT(swp.x, winattrib->height-swp.y), (MPARAM)hWnd);
  479.             }
  480.             WinEndEnumWindows(children);
  481.             new->type = ConfigureNotify;
  482.             new->xconfigure.x = winattrib->x;
  483.             new->xconfigure.y = winattrib->y;
  484.             new->xconfigure.width = winattrib->width = SHORT1FROMMP(mp2);
  485.             new->xconfigure.height = winattrib->height = SHORT2FROMMP(mp2);
  486.             new->xconfigure.border_width = winattrib->border_width;
  487.             if (attrib->wm_client_leader)
  488.                 new->xconfigure.window = attrib->wm_client_leader;
  489.             pthread_mutex_lock(&evmutex);
  490.             if (attrib->lastconfigure) {
  491.                 XEvent *last = attrib->lastconfigure;
  492.                 memcpy(last, new, sizeof(XEvent));
  493.                 pthread_mutex_unlock(&evmutex);
  494.                 goto nonevent;
  495.             }
  496.             attrib->lastconfigure = new;
  497.             pthread_mutex_unlock(&evmutex);
  498.             break;
  499.         }
  500.     case UM_GRAVITY:
  501.         new->type = GravityNotify;
  502.         new->xgravity.x = SHORT1FROMMP(mp1);
  503.         new->xgravity.y = SHORT2FROMMP(mp1);
  504.         new->xgravity.event = (Window) mp2;
  505.         break;
  506.     case UM_CHARSEQ:
  507.         new->type = SHORT1FROMMP(mp2);
  508.         new->xkey.root = hwndDesktop;
  509.         new->xkey.keycode = SHORT1FROMMP(mp1);
  510.         new->xkey.state = SHORT2FROMMP(mp1);
  511.         new->xkey.time = WinGetCurrentTime(pmctls_hab);
  512.         break;
  513.     case WM_CHAR:
  514.         if (!attrib || !winattrib) goto passover;
  515.  
  516.         if (SHORT1FROMMP(mp1) & KC_KEYUP) {
  517.             new->type = KeyRelease;
  518.             if (!(winattrib->your_event_mask & KeyReleaseMask))
  519.                 goto nonevent;
  520.         } else {
  521.             new->type = KeyPress;
  522.             if (SHORT1FROMMP(mp1) & KC_PREVDOWN) {
  523.                 /* Key repeat! */
  524.                 Xlib_RemoveEvent(new);
  525.                 if (auto_repeat) {
  526.                     SHORT us1 = SHORT1FROMMP((MPARAM)attrib->prevkeystate);
  527.                     SHORT us2 = SHORT2FROMMP((MPARAM)attrib->prevkeystate);
  528.                     MPARAM mp2 = (MPARAM)attrib->prevkeycode;
  529.                     xpmwndproc(hWnd, msg, MPFROM2SHORT(us1 | KC_KEYUP, us2), mp2);
  530.                     xpmwndproc(hWnd, msg, MPFROM2SHORT(us1, us2), mp2);
  531.                 }
  532.                 goto endproc;
  533.             }
  534.             attrib->prevkeycode = (unsigned int)mp2;
  535.             attrib->prevkeystate = (unsigned int)mp1;
  536.             if (!(winattrib->your_event_mask & KeyPressMask))
  537.                 goto nonevent;
  538.         }
  539.         new->xkey.root = hwndDesktop;
  540.         /* There will probably need to be lots of keycode translations */
  541.         /* Keycode translations happen in XKeycodeToKeysym() funcs */
  542.         new->xkey.state = 0;
  543.  
  544.         if (SHORT1FROMMP(mp1) & KC_SHIFT) new->xkey.state |= ShiftMask;
  545.         if (SHORT1FROMMP(mp1) & KC_CTRL) new->xkey.state |= ControlMask;
  546.         if (SHORT1FROMMP(mp1) & KC_ALT) new->xkey.state |= Mod2Mask;
  547.         if (WinGetKeyState(hwndDesktop, VK_CAPSLOCK)&0x0001)
  548.             new->xkey.state |= LockMask;
  549.         if (WinGetKeyState(hwndDesktop, VK_BUTTON1)&0x8000)
  550.             new->xkey.state |= Button1Mask;
  551.         if (WinGetKeyState(hwndDesktop, VK_BUTTON2)&0x8000)
  552.             new->xkey.state |= Button2Mask;
  553.         if (WinGetKeyState(hwndDesktop, VK_BUTTON3)&0x8000)
  554.             new->xkey.state |= Button3Mask;
  555.  
  556.         if (SHORT1FROMMP(mp1) & KC_CHAR && !(SHORT1FROMMP(mp2) & 0xff80))
  557.             new->xkey.keycode = SHORT1FROMMP(mp2); else
  558.                 if (SHORT1FROMMP(mp1) & KC_CHAR && !(SHORT1FROMMP(mp2) & 0xff00)) {
  559.                     new->xkey.keycode = SHORT1FROMMP(mp2);
  560.                     new->xkey.state |= Mod1Mask;
  561.                     /*MPARAM rp1a = MPFROM2SHORT(17, new->xkey.state);
  562.                      MPARAM rp1b = MPFROM2SHORT(SHORT1FROMMP(mp2), new->xkey.state | Mod1Mask);
  563.                      MPARAM rp2 = MPFROM2SHORT(new->type, 0);
  564.                      Xlib_RemoveEvent(new);
  565.                      xpmwndproc(hWnd, UM_CHARSEQ, rp1a, rp2);
  566.                      xpmwndproc(hWnd, UM_CHARSEQ, rp1b, rp2);
  567.                      goto endproc;*/
  568.                 } else
  569.                     if (SHORT1FROMMP(mp1) & KC_SCANCODE && CHAR4FROMMP(mp1))
  570.                         new->xkey.keycode = CHAR4FROMMP(mp1) | 0x80;
  571.                     else    goto nonevent;
  572.         if (new->xkey.keycode < maindisplay->min_keycode ||
  573.             new->xkey.keycode > maindisplay->max_keycode)
  574.             goto nonevent;
  575.         if (SHORT1FROMMP(mp1) & KC_SCANCODE)
  576.             switch (CHAR4FROMMP(mp1)) {
  577.             case 0x2a:      /* Shift_L */
  578.             case 0x36:      /* Shift_R */
  579.             case 0x1d:      /* Control_L */
  580.             case 0x5b:      /* Control_R */
  581.             case 0x38:      /* Alt_L */
  582.             case 0x5e:      /* Alt_R */
  583.             case 0x3a:      /* Caps Lock */
  584.             case 0x39:      /* Spacebar */
  585.             case 0x5c:      /* KP_Divide */
  586.             case 0x37:      /* KP_Multiply */
  587.             case 0x4a:      /* KP_Subtract */
  588.             case 0x4e:      /* KP_Add */
  589.             case 0x5a:      /* KP_Enter */
  590.                 new->xkey.keycode = CHAR4FROMMP(mp1) | 0x80;
  591.                 new->xkey.state &= ~Mod1Mask;
  592.                 break;
  593.             case 0x53:      /* KP_Decimal */
  594.             case 0x52:      /* KP_0 */
  595.             case 0x4f:      /* KP_1 */
  596.             case 0x50:      /* KP_2 */
  597.             case 0x51:      /* KP_3 */
  598.             case 0x4b:      /* KP_4 */
  599.             case 0x4c:      /* KP_5 */
  600.             case 0x4d:      /* KP_6 */
  601.             case 0x47:      /* KP_7 */
  602.             case 0x48:      /* KP_8 */
  603.             case 0x49:      /* KP_9 */
  604.                 new->xkey.keycode = CHAR4FROMMP(mp1) | 0x80;
  605.                 if (((WinGetKeyState(hwndDesktop, VK_NUMLOCK)&0x0001)==1) ==
  606.                     ((new->xkey.state & ShiftMask) == ShiftMask)) {
  607.                     new->xkey.keycode &= 0x7f;
  608.                     new->xkey.state |= Mod1Mask;
  609.                     /*MPARAM rp1a = MPFROM2SHORT(17, new->xkey.state);
  610.                      MPARAM rp1b = MPFROM2SHORT(new->xkey.keycode & 0x7f, new->xkey.state | Mod1Mask);
  611.                      MPARAM rp2 = MPFROM2SHORT(new->type, 0);
  612.                      Xlib_RemoveEvent(new);
  613.                      xpmwndproc(hWnd, UM_CHARSEQ, rp1a, rp2);
  614.                      xpmwndproc(hWnd, UM_CHARSEQ, rp1b, rp2);
  615.                      goto endproc;*/
  616.                 }
  617.                 break;
  618.             }
  619.         new->xkey.time = WinGetCurrentTime(pmctls_hab);
  620.         break;
  621.         /*case UM_MAPPINGNOTIFY:
  622.          new->type = MappingNotify;
  623.          new->xmapping.request = */
  624.     case WM_MOUSEMOVE:
  625.     case WM_BUTTON1MOTIONSTART:
  626.     case WM_BUTTON2MOTIONSTART:
  627.     case WM_BUTTON3MOTIONSTART:
  628.     case WM_BUTTON1MOTIONEND:
  629.     case WM_BUTTON2MOTIONEND:
  630.     case WM_BUTTON3MOTIONEND:
  631.     case WM_SEM4:
  632.         {
  633.             POINTL ptls = { SHORT1FROMMP(mp1), SHORT2FROMMP(mp1) };
  634.             LONG btns=0, btnmask = 0;
  635.  
  636.             new->type = MotionNotify;
  637.             new->xmotion.state = 0;
  638.             new->xmotion.root = hwndDesktop;
  639.             new->xmotion.x = ptls.x;
  640.             new->xmotion.y = winattrib->height - ptls.y;
  641.             new->xmotion.is_hint = (msg == WM_SEM4);
  642.             new->xmotion.same_screen = 1;
  643.             if ((msg != WM_SEM4 && (winattrib->your_event_mask & PointerMotionHintMask))
  644.                 || !WinMapWindowPoints(hWnd, hwndDesktop, &ptls, 1)) {
  645.                 WinPostMsg(hWnd, WM_SEM4, 0, 0);
  646.                 if (msg == WM_MOUSEMOVE && attrib->cursor)
  647.                     WinSetPointer(hwndDesktop, attrib->cursor);
  648.                 else    goto passover;
  649.                 goto nonevent;
  650.             }
  651.             new->xmotion.x_root = ptls.x;
  652.             new->xmotion.y_root = WinQuerySysValue(hwndDesktop,SV_CYSCREEN) - ptls.y;
  653.             if (WinGetKeyState(hwndDesktop,VK_BUTTON1) & 0x8000) btns |= 1;
  654.             if (WinGetKeyState(hwndDesktop,VK_BUTTON2) & 0x8000) btns |= 2;
  655.             if (WinGetKeyState(hwndDesktop,VK_BUTTON3) & 0x8000) btns |= 4;
  656.             if (!(winattrib->your_event_mask & PointerMotionMask)) {
  657.                 if (winattrib->your_event_mask & ButtonMotionMask) btnmask |= 7;
  658.                 else {
  659.                     if (winattrib->your_event_mask & Button1MotionMask) btnmask |= 1;
  660.                     if (winattrib->your_event_mask & Button2MotionMask) btnmask |= 2;
  661.                     if (winattrib->your_event_mask & Button3MotionMask) btnmask |= 4;
  662.                 }
  663.                 if (!(btns & btnmask)) {
  664.                     if (msg == WM_MOUSEMOVE && attrib->cursor)
  665.                         WinSetPointer(hwndDesktop, attrib->cursor);
  666.                     else result = WinDefWindowProc(hWnd, msg, mp1, mp2);
  667.                     goto nonevent;
  668.                 }
  669.             }
  670.             if (btns & 1) new->xmotion.state |= Button1Mask;
  671.             if (btns & 2) new->xmotion.state |= Button2Mask;
  672.             if (btns & 4) new->xmotion.state |= Button3Mask;
  673.             if (WinGetKeyState(hwndDesktop,VK_CAPSLOCK) & 0x0001) new->xmotion.state |= LockMask;
  674.             if (WinGetKeyState(hwndDesktop,VK_SHIFT) & 0x8000) new->xmotion.state |= ShiftMask;
  675.             if (WinGetKeyState(hwndDesktop,VK_CTRL) & 0x8000) new->xmotion.state |= ControlMask;
  676.             if (WinGetKeyState(hwndDesktop,VK_ALT) & 0x8000) new->xmotion.state |= Mod2Mask;
  677.             new->xmotion.time = WinGetCurrentTime(pmctls_hab);
  678.         }
  679.         break;
  680.     case WM_ACTIVATE:
  681.         WinPostMsg(hWnd, WM_MOVE, NULL, NULL);
  682.         goto nonevent;
  683.     case UM_GIMMIE:
  684.         WinSetFocus(hwndDesktop, hWnd);
  685.         goto nonevent;
  686.     case WM_BUTTON1UP:
  687.     case WM_BUTTON2UP:
  688.     case WM_BUTTON3UP:
  689.     case WM_BUTTON1DOWN:
  690.     case WM_BUTTON2DOWN:
  691.     case WM_BUTTON3DOWN:
  692.         {
  693.             POINTL ptls = { SHORT1FROMMP(mp1), SHORT2FROMMP(mp1) };
  694.             if (!winattrib) goto passover;
  695.             /* Will need to map the window points for x and y since X expects
  696.              * them to be relative to the event window */
  697.             if (msg == WM_BUTTON1UP || msg == WM_BUTTON2UP || msg == WM_BUTTON3UP) {
  698.                 if (!(winattrib->your_event_mask & ButtonReleaseMask))
  699.                     goto nonevent;
  700.                 /*x11_console_notice("ButtonRelease");*/
  701.                 new->type = ButtonRelease;
  702.             } else {
  703.                 if (!(WinQueryFocus(hwndDesktop) == hWnd)) {
  704.                     WinPostMsg(hWnd, UM_GIMMIE, 0, 0);
  705.                 }
  706.                 if (!(winattrib->your_event_mask & ButtonPressMask))
  707.                     goto nonevent;
  708.                 /*x11_console_notice("ButtonPress");*/
  709.                 new->type = ButtonPress;
  710.             }
  711.  
  712.             new->xbutton.state = 0;
  713.  
  714.             if (msg == WM_BUTTON1UP || msg == WM_BUTTON1DOWN)
  715.                 new->xbutton.button = 1; else
  716.                     if (msg == WM_BUTTON3UP || msg == WM_BUTTON3DOWN)
  717.                         new->xbutton.button = 2; else
  718.                             if (msg == WM_BUTTON2UP || msg == WM_BUTTON2DOWN)
  719.                                 new->xbutton.button = 3;
  720.  
  721.             if (SHORT1FROMMP(mp1) & KC_SHIFT) new->xbutton.state |= ShiftMask;
  722.             if (SHORT1FROMMP(mp1) & KC_CTRL) new->xbutton.state |= ControlMask;
  723.             if (SHORT1FROMMP(mp1) & KC_ALT) new->xbutton.state |= Mod2Mask;
  724.             if (WinGetKeyState(hwndDesktop, VK_CAPSLOCK)&0x0001)
  725.                 new->xbutton.state |= LockMask;
  726.             if (WinGetKeyState(hwndDesktop, VK_BUTTON1)&0x8000)
  727.                         new->xbutton.state |= Button1Mask;
  728.             if (WinGetKeyState(hwndDesktop, VK_BUTTON2)&0x8000)
  729.                 new->xbutton.state |= Button2Mask;
  730.             if (WinGetKeyState(hwndDesktop, VK_BUTTON3)&0x8000)
  731.                 new->xbutton.state |= Button3Mask;
  732.  
  733.             new->xbutton.root = hwndDesktop;
  734.             new->xbutton.x = ptls.x;
  735.             new->xbutton.y = winattrib->height - ptls.y;
  736.             if (!WinMapWindowPoints(hWnd, new->xbutton.root, &ptls, 1))
  737.                 goto nonevent;
  738.             new->xbutton.x_root = ptls.x;
  739.             new->xbutton.y_root = WinQuerySysValue(hwndDesktop,SV_CYSCREEN) - ptls.y;
  740.             new->xbutton.time = WinGetCurrentTime(pmctls_hab);
  741.             break;
  742.         }
  743.     case WM_PAINT:
  744.         {
  745.             RECTL rectl;
  746.             SWP swp;
  747.             if (!attrib) goto passover;
  748.             /* x11_console_notice("Expose"); */
  749.             WinQueryWindowPos(hWnd, &swp);
  750.  
  751.             new->type = Expose;
  752.             new->xexpose.count = 0;
  753.  
  754.             if (!WinQueryUpdateRect(hWnd, &rectl)) {
  755.                 new->xexpose.x = rectl.xLeft = 0;
  756.                 new->xexpose.y = rectl.yBottom = 0;
  757.                 new->xexpose.width = rectl.xRight = swp.cx;
  758.                 new->xexpose.height = rectl.yTop = swp.cy;
  759.             } else {
  760.                 new->xexpose.x = rectl.xLeft;
  761.                 new->xexpose.y = swp.cy - rectl.yTop;
  762.                 new->xexpose.width = rectl.xRight - rectl.xLeft;
  763.                 new->xexpose.height = rectl.yTop - rectl.yBottom;
  764.             }
  765.             /*if (attrib->background_pixmap != ParentRelative)*/
  766.             {
  767.                 HPS hps;
  768.                 hps = WinBeginPaint(hWnd, NULLHANDLE, &rectl);
  769.                 GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL );
  770.                 WinFillRect(hps, &rectl, attrib->background_pixel);
  771.                 WinEndPaint(hps);
  772.             }/* else
  773.             if (!attrib->inhiding) {
  774.             HWND hwndframe = WinQueryWindowULong(hWnd, QWP_FRAMEHWND);
  775.             HWND parent = WinQueryWindow(hwndframe, QW_PARENT);
  776.             RECTL rectl1 = { 0, 0, attrib->winattrib.width, attrib->winattrib.height};
  777.             RECTL rectl2 = { 0, 0, attrib->winattrib.width, attrib->winattrib.height};
  778.             WinMapWindowPoints(hWnd, parent, (PPOINTL)&rectl1, 2);
  779.             WinEnableWindowUpdate(hwndframe, FALSE);
  780.             WinInvalidateRect(parent, &rectl1, TRUE);
  781.             attrib->inhiding = 1;
  782.             WinUpdateWindow(parent);
  783.             }*/
  784.             if (!(attrib->winattrib.your_event_mask & ExposureMask))
  785.                 goto passover;
  786.  
  787. #if 1
  788.             pthread_mutex_lock(&evmutex);
  789.             if (attrib->lastexpose) {
  790.                 XEvent *last = attrib->lastexpose;
  791.                 int i;
  792.  
  793.                 if (new->xexpose.x < last->xexpose.x) {
  794.                     last->xexpose.width += last->xexpose.x - new->xexpose.x;
  795.                     last->xexpose.x = new->xexpose.x;
  796.                 }
  797.                 if (last->xexpose.x > swp.cx) last->xexpose.x = swp.cx;
  798.                 i = new->xexpose.x + new->xexpose.width - last->xexpose.x;
  799.                 if (last->xexpose.width < i) last->xexpose.width = i;
  800.                 if (last->xexpose.width > swp.cx - last->xexpose.x)
  801.                     last->xexpose.width = swp.cx - last->xexpose.x;
  802.  
  803.                 if (new->xexpose.y < last->xexpose.y) {
  804.                     last->xexpose.height += last->xexpose.y - new->xexpose.y;
  805.                     last->xexpose.y = new->xexpose.y;
  806.                 }
  807.                 if (last->xexpose.y > swp.cy) last->xexpose.y = swp.cy;
  808.                 i = new->xexpose.y + new->xexpose.height - last->xexpose.y;
  809.                 if (last->xexpose.height < i) last->xexpose.height = i;
  810.                 if (last->xexpose.height > swp.cy - last->xexpose.y)
  811.                     last->xexpose.height = swp.cy - last->xexpose.y;
  812.  
  813.                 pthread_mutex_unlock(&evmutex);
  814.                 goto passover;
  815.             }
  816.             attrib->lastexpose = new;
  817.             pthread_mutex_unlock(&evmutex);
  818. #endif
  819.             break;
  820.         }
  821.     case 0x041e:
  822.         {
  823.             POINTL ptl;
  824.             new->type = EnterNotify;
  825.             if (!winattrib || !(winattrib->your_event_mask & EnterWindowMask))
  826.                 goto nonevent;
  827.             WinQueryPointerPos(hwndDesktop, &ptl);
  828.             new->xcrossing.x_root = ptl.x;
  829.             new->xcrossing.y_root = WinQuerySysValue(hwndDesktop,SV_CYSCREEN) - ptl.y;
  830.             WinMapWindowPoints(hwndDesktop, hWnd, &ptl, 1);
  831.             new->xcrossing.x = ptl.x;
  832.             new->xcrossing.y = winattrib->height - ptl.y;
  833.             new->xcrossing.mode = NotifyNormal;
  834.             new->xcrossing.focus = WinIsChild(hWnd,WinQueryFocus(hwndDesktop));
  835.             new->xcrossing.subwindow = hWnd;
  836.             new->xcrossing.same_screen = 1;
  837.             new->xcrossing.time = WinGetCurrentTime(pmctls_hab);
  838.             break;
  839.         }
  840.     case 0x041f:
  841.         {
  842.             POINTL ptl;
  843.             new->type = LeaveNotify;
  844.             if (!winattrib || !(winattrib->your_event_mask & LeaveWindowMask))
  845.                 goto nonevent;
  846.             WinQueryPointerPos(hwndDesktop, &ptl);
  847.             new->xcrossing.x_root = ptl.x;
  848.             new->xcrossing.y_root = WinQuerySysValue(hwndDesktop,SV_CYSCREEN) - ptl.y;
  849.             WinMapWindowPoints(hwndDesktop, hWnd, &ptl, 1);
  850.             if (ptl.x < 0) ptl.x = 0; else if (ptl.x > winattrib->width) ptl.x = winattrib->width;
  851.             if (ptl.y < 0) ptl.y = 0; else if (ptl.y > winattrib->height) ptl.y = winattrib->height;
  852.             new->xcrossing.x = ptl.x;
  853.             new->xcrossing.y = winattrib->height - ptl.y;
  854.             new->xcrossing.mode = NotifyNormal;
  855.             new->xcrossing.focus = WinIsChild(hWnd,WinQueryFocus(hwndDesktop))?1:0;
  856.             new->xcrossing.subwindow = None;
  857.             new->xcrossing.same_screen = 1;
  858.             new->xcrossing.time = WinGetCurrentTime(pmctls_hab);
  859.             break;
  860.         }
  861.     case UM_ChangeProperty:
  862.         {
  863.             HWND hwndframe = WinQueryWindowULong(hWnd, QWP_FRAMEHWND);
  864.             new->type = PropertyNotify;
  865.             new->xproperty.atom = (Atom)mp1;
  866.             new->xproperty.state = (int)mp2;
  867.             new->xproperty.time = (Time)time(NULL);
  868.             switch (new->xproperty.atom) {
  869.             case XA_WM_NAME:
  870.                 {
  871.                     SWP swp;
  872.                     WinQueryWindowPos(hwndframe,&swp);
  873.                     if (!(swp.fl &(SWP_HIDE|SWP_MINIMIZE)))
  874.                         WinSetWindowText(hwndframe, attrib->wm_name);
  875.                     break;
  876.                 }
  877.             case XA_WM_ICON_NAME:
  878.                 {
  879.                     SWP swp;
  880.                     WinQueryWindowPos(hwndframe,&swp);
  881.                     if ((swp.fl &(SWP_HIDE|SWP_MINIMIZE)))
  882.                         WinSetWindowText(hwndframe, attrib->wm_iconname);
  883.  
  884.                 }
  885.                 default:
  886.                     /* nothing happens here */
  887.             }
  888.             if (attrib->wm_client_leader)
  889.                 new->xproperty.window = attrib->wm_client_leader;
  890.             break;
  891.         }
  892.     case UM_REPARENT:
  893.         {
  894.             SWP swp, pswp;
  895.             new->type = ReparentNotify;
  896.             new->xreparent.parent = WinQueryWindow(hWnd, QW_PARENT);
  897.             WinQueryWindowPos(hWnd, &swp);
  898.             WinQueryWindowPos(new->xreparent.parent, &pswp);
  899.             new->xreparent.x = swp.x;
  900.             new->xreparent.y = pswp.cy - swp.y;
  901.             new->xreparent.override_redirect = attrib->winattrib.override_redirect;
  902.             if (attrib->wm_client_leader)
  903.                 new->xreparent.window = attrib->wm_client_leader;
  904.             break;
  905.         }
  906.     default:
  907.         goto passover;
  908.     }
  909.     maindisplay->qlen++;
  910.     write(pmout[1], (char *) &new, sizeof(void *));
  911.     if (msg == WM_MOUSEMOVE && attrib->cursor) {
  912.         WinSetPointer(hwndDesktop, attrib->cursor);
  913.     } else
  914.         if (msg == WM_PAINT || msg == WM_MOUSEMOVE || msg == WM_DESTROY)
  915.             result = WinDefWindowProc(hWnd, msg, mp1, mp2);
  916.     goto endproc;
  917. passover:
  918.     result = WinDefWindowProc(hWnd, msg, mp1, mp2);
  919. nonevent:
  920.     /* If you return from this procedure without adding to the
  921.      * queue you MUST remove the event from the queue, otherwise
  922.      * the linked list will become out of sync with the pipe.
  923.      * Brian Smith.
  924.      */
  925.     Xlib_RemoveEvent(new);
  926. endproc:
  927.     Xlib_PMWM_Handler1(&hWnd, &msg, &mp1, &mp2);
  928.         return result;
  929. }
  930.  
  931. VOID APIENTRY Xlib_ExitHandler(VOID)
  932. {
  933.     APIRET erc = NO_ERROR;
  934.  
  935.     if(WinReleaseHook(pmctls_hab, NULLHANDLE, HK_INPUT, Xlib_InputQueueHook, hk_module)==FALSE)
  936.         x11_console_notice("Error removing the input hook!\n");
  937.         else
  938.         {
  939.             x11_console_notice("Xlib/PM successfully shutdown. (Xlib_ExitHandler)\n");
  940.             DosFreeModule(hk_module);       /* Decrement the DLL usage count*/
  941.         }
  942.  
  943. #ifdef DEBUG
  944.     if (Xlib_DebugOffset) {
  945.         struct Xlib_DebugInfo_st *info =
  946.             (struct Xlib_DebugInfo_st *)&Xlib_DebugInfo[Xlib_DebugOffset];
  947.         int i = Xlib_DebugOffset;
  948.         fprintf(stderr,"Post-mortem: \n - body found in %s(), line %i, %s, %s\n",
  949.                 info->procname, info->linenumb, info->filename, info->procinfo);
  950.         while (--i) {
  951.             info--;
  952.             fprintf(stderr,"   + called from %s(), line %i, %s, %s\n",
  953.                     info->procname, info->linenumb, info->filename, info->procinfo);
  954.         }
  955.     } else {
  956.         struct Xlib_DebugInfo_st *info =
  957.                         (struct Xlib_DebugInfo_st *)&Xlib_DebugInfo[1];
  958.         fprintf(stderr,"Last touched %s(), line %d, %s, %s\n",
  959.                 info->procname, info->linenumb, info->filename, info->procinfo);
  960.     }
  961. #endif
  962.  
  963.     erc = DosExitList(EXLST_EXIT, (PFNEXITLIST)NULL);
  964.     x11_console_notice("Error in ExitList");
  965.     return;
  966. }
  967.  
  968. void * pm_thread(void * arg)
  969. {
  970.     HMQ hmq = 0;
  971.     QMSG qmsg;
  972.     ULONG fstyle = FCF_TASKLIST;
  973.     APIRET rc;
  974.     int z, ulAccelLen;
  975.     PACCELTABLE  pacctAccelTable = NULL;
  976.     HACCEL holdaccel;
  977.     /* Our replacement accellerator table */
  978.     ACCEL   acctable[] = {
  979.         { AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F4 , SC_CLOSE },
  980.         { AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_ENTER, SC_RESTORE },
  981.         { AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_NEWLINE, SC_RESTORE },
  982.         { AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F5, SC_RESTORE },
  983.         { AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F6, SC_NEXTFRAME },
  984.         { AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F7, SC_MOVE },
  985.         { AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F8, SC_SIZE },
  986.         { AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F9, SC_MINIMIZE },
  987.         { AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F10, SC_MAXIMIZE },
  988.         { AF_SYSCOMMAND | AF_VIRTUALKEY, VK_F10, SC_APPMENU },
  989.         { AF_SYSCOMMAND | AF_LONEKEY | AF_VIRTUALKEY, VK_ALT, SC_APPMENU },
  990.         { AF_SYSCOMMAND | AF_LONEKEY | AF_VIRTUALKEY, VK_ALTGRAF, SC_APPMENU },
  991.         { AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_SPACE, SC_SYSMENU },
  992.         { AF_SYSCOMMAND | AF_SHIFT | AF_VIRTUALKEY, VK_ESC, SC_SYSMENU },
  993.         { AF_SYSCOMMAND | AF_CONTROL | AF_VIRTUALKEY, VK_ESC, SC_TASKMANAGER }
  994.     };
  995.  
  996.     pmctls_hab = WinInitialize(0);
  997.     hmq = WinCreateMsgQueue(pmctls_hab, 0);
  998.  
  999.     EventQueue = NULL;
  1000.     /*Grab = NULL;*/
  1001.  
  1002.     /* NOTE: Brian, I don't think so... Antony.
  1003.      signal(SIGSEGV, Xlib_crash);
  1004.      */
  1005.  
  1006.     if ((!pmctls_hab) || (!hmq)) {
  1007.         x11_console_notice("Error init PM instance\n");
  1008.         pthread_kill(mainthread, SIGABRT);
  1009.         pthread_exit(NULL);
  1010.     }
  1011.  
  1012.     rc = WinRegisterClass(pmctls_hab, "ObjClass", pmhwndproc, 0, 0);
  1013.     rc = WinRegisterClass(pmctls_hab, "XPMChild", xpmwndproc, CS_SIZEREDRAW | CS_MOVENOTIFY, 8);
  1014.  
  1015.     mainhwnd = WinCreateStdWindow(HWND_OBJECT, 0, &fstyle,
  1016.                                   "ObjClass", "X Application", 0, NULLHANDLE, 0, NULL);
  1017.  
  1018.     if (mainhwnd == NULLHANDLE) {
  1019.         x11_console_notice("Error creating PM instance\n");
  1020.         pthread_kill(mainthread, SIGABRT);
  1021.         pthread_exit(NULL);
  1022.     }
  1023.  
  1024.     if (!hk_module) {
  1025.         if (DosLoadModule(NULL,0,"X11pmhk.dll",&hk_module))
  1026.             x11_console_notice("Could not acquire handle for X11pmhk.DLL\n");
  1027.         else {
  1028.             DosQueryProcAddr(hk_module, 0, "Xlib_NewGrab", (PFN *)&Xlib_NewGrab);
  1029.             DosQueryProcAddr(hk_module, 0, "Xlib_FindGrab", (PFN *)&Xlib_FindGrab);
  1030.             DosQueryProcAddr(hk_module, 0, "Xlib_RemoveGrab", (PFN *)&Xlib_RemoveGrab);
  1031.             DosQueryProcAddr(hk_module, 0, "Xlib_RemoveGrabAny", (PFN *)&Xlib_RemoveGrabAny);
  1032.             DosQueryProcAddr(hk_module, 0, "Xlib_InputQueueHook", (PFN *)&Xlib_InputQueueHook);
  1033.             DosQueryProcAddr(hk_module, 0, "Xlib_XInternAtom", (PFN *)&Xlib_XInternAtom);
  1034.             DosQueryProcAddr(hk_module, 0, "Xlib_GetAtomName", (PFN *)&Xlib_GetAtomName);
  1035.  
  1036.             if (!WinSetHook(pmctls_hab, NULLHANDLE, HK_INPUT, Xlib_InputQueueHook, hk_module))
  1037.                 x11_console_notice("Could not set PM input hook, XGrab* API will not function.\n");
  1038.             else
  1039.                 DosExitList(EXLST_ADD,(PFNEXITLIST)Xlib_ExitHandler);
  1040.         }
  1041.     }
  1042.  
  1043.     ulAccelLen = sizeof( acctable ) + sizeof( ACCELTABLE );
  1044.     pacctAccelTable = (PACCELTABLE) malloc ( ulAccelLen );
  1045.  
  1046.     pacctAccelTable->cAccel = 15;                /* Number of ACCEL entries */
  1047.     pacctAccelTable->codepage = 437;             /* Code page */
  1048.     for(z=0;z<pacctAccelTable->cAccel;z++)
  1049.         pacctAccelTable->aaccel[z] = acctable[z];
  1050.  
  1051.     holdaccel = WinQueryAccelTable(mainhab, NULLHANDLE);
  1052.  
  1053.     /* Clear all accellerators */
  1054.     WinSetAccelTable(pmctls_hab, 0, NULLHANDLE);
  1055.  
  1056.     /* Delete the old accellerator */
  1057.     WinDestroyAccelTable(holdaccel);
  1058.  
  1059.     /* Create the new accellerator */
  1060.     haccel = WinCreateAccelTable(pmctls_hab, pacctAccelTable);
  1061.  
  1062.     /* Set it as the default for the queue */
  1063.     WinSetAccelTable(pmctls_hab, haccel, NULLHANDLE);
  1064.  
  1065.     xinitialized = TRUE;
  1066.  
  1067.     while (WinGetMsg(pmctls_hab, &qmsg, 0, 0, 0)) {
  1068.         WinDispatchMsg(pmctls_hab, &qmsg);
  1069.     }
  1070.  
  1071.     if (hk_module && !WinReleaseHook(pmctls_hab, NULLHANDLE, HK_INPUT, Xlib_InputQueueHook, hk_module))
  1072.         x11_console_notice("Error removing the input hook!\n");
  1073.     else
  1074.     {
  1075.         /* I want to make sure the hook is getting removed. */
  1076.         x11_console_notice("Xlib/PM successfully shutdown. (pm_thread)\n");
  1077.  
  1078.         if (hk_module) {
  1079.             DosFreeModule(hk_module);       /* Decrement the DLL usage count*/
  1080.             hk_module = NULLHANDLE;
  1081.             DosExitList(EXLST_REMOVE,(PFNEXITLIST)Xlib_ExitHandler);
  1082.         }
  1083.     }
  1084.  
  1085.     WinDestroyWindow(mainhwnd);
  1086.     WinDestroyMsgQueue(hmq);
  1087.     WinTerminate(pmctls_hab);
  1088.  
  1089.     xinitialized = FALSE;
  1090.  
  1091.     return NULL;
  1092. }
  1093.  
  1094.