xref: /OK3568_Linux_fs/external/xserver/hw/xwin/winwindowswm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* WindowsWM extension is based on AppleWM extension */
2*4882a593Smuzhiyun /**************************************************************************
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
5*4882a593Smuzhiyun Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun Permission is hereby granted, free of charge, to any person obtaining a
8*4882a593Smuzhiyun copy of this software and associated documentation files (the
9*4882a593Smuzhiyun "Software"), to deal in the Software without restriction, including
10*4882a593Smuzhiyun without limitation the rights to use, copy, modify, merge, publish,
11*4882a593Smuzhiyun distribute, sub license, and/or sell copies of the Software, and to
12*4882a593Smuzhiyun permit persons to whom the Software is furnished to do so, subject to
13*4882a593Smuzhiyun the following conditions:
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun The above copyright notice and this permission notice (including the
16*4882a593Smuzhiyun next paragraph) shall be included in all copies or substantial portions
17*4882a593Smuzhiyun of the Software.
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20*4882a593Smuzhiyun OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22*4882a593Smuzhiyun IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23*4882a593Smuzhiyun ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24*4882a593Smuzhiyun TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25*4882a593Smuzhiyun SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun **************************************************************************/
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #ifdef HAVE_XWIN_CONFIG_H
30*4882a593Smuzhiyun #include <xwin-config.h>
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun #include "win.h"
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #include "misc.h"
35*4882a593Smuzhiyun #include "dixstruct.h"
36*4882a593Smuzhiyun #include "extnsionst.h"
37*4882a593Smuzhiyun #include "colormapst.h"
38*4882a593Smuzhiyun #include "cursorstr.h"
39*4882a593Smuzhiyun #include "scrnintstr.h"
40*4882a593Smuzhiyun #include "servermd.h"
41*4882a593Smuzhiyun #include "swaprep.h"
42*4882a593Smuzhiyun #define _WINDOWSWM_SERVER_
43*4882a593Smuzhiyun #include <X11/extensions/windowswmstr.h>
44*4882a593Smuzhiyun #include "protocol-versions.h"
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun static int WMErrorBase;
47*4882a593Smuzhiyun static unsigned char WMReqCode = 0;
48*4882a593Smuzhiyun static int WMEventBase = 0;
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun static RESTYPE ClientType, eventResourceType;   /* resource types for event masks */
51*4882a593Smuzhiyun static XID eventResource;
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun /* Currently selected events */
54*4882a593Smuzhiyun static unsigned int eventMask = 0;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun static int WMFreeClient(void *data, XID id);
57*4882a593Smuzhiyun static int WMFreeEvents(void *data, XID id);
58*4882a593Smuzhiyun static void SNotifyEvent(xWindowsWMNotifyEvent * from,
59*4882a593Smuzhiyun                          xWindowsWMNotifyEvent * to);
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun typedef struct _WMEvent *WMEventPtr;
62*4882a593Smuzhiyun typedef struct _WMEvent {
63*4882a593Smuzhiyun     WMEventPtr next;
64*4882a593Smuzhiyun     ClientPtr client;
65*4882a593Smuzhiyun     XID clientResource;
66*4882a593Smuzhiyun     unsigned int mask;
67*4882a593Smuzhiyun } WMEventRec;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun static int
ProcWindowsWMQueryVersion(ClientPtr client)70*4882a593Smuzhiyun ProcWindowsWMQueryVersion(ClientPtr client)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun     xWindowsWMQueryVersionReply rep;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xWindowsWMQueryVersionReq);
75*4882a593Smuzhiyun     rep.type = X_Reply;
76*4882a593Smuzhiyun     rep.length = 0;
77*4882a593Smuzhiyun     rep.sequenceNumber = client->sequence;
78*4882a593Smuzhiyun     rep.majorVersion = SERVER_WINDOWSWM_MAJOR_VERSION;
79*4882a593Smuzhiyun     rep.minorVersion = SERVER_WINDOWSWM_MINOR_VERSION;
80*4882a593Smuzhiyun     rep.patchVersion = SERVER_WINDOWSWM_PATCH_VERSION;
81*4882a593Smuzhiyun     if (client->swapped) {
82*4882a593Smuzhiyun         swaps(&rep.sequenceNumber);
83*4882a593Smuzhiyun         swapl(&rep.length);
84*4882a593Smuzhiyun     }
85*4882a593Smuzhiyun     WriteToClient(client, sizeof(xWindowsWMQueryVersionReply), &rep);
86*4882a593Smuzhiyun     return Success;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun /* events */
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun static inline void
updateEventMask(WMEventPtr * pHead)92*4882a593Smuzhiyun updateEventMask(WMEventPtr * pHead)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun     WMEventPtr pCur;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun     eventMask = 0;
97*4882a593Smuzhiyun     for (pCur = *pHead; pCur != NULL; pCur = pCur->next)
98*4882a593Smuzhiyun         eventMask |= pCur->mask;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun  /*ARGSUSED*/ static int
WMFreeClient(void * data,XID id)102*4882a593Smuzhiyun WMFreeClient(void *data, XID id)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun     WMEventPtr pEvent;
105*4882a593Smuzhiyun     WMEventPtr *pHead, pCur, pPrev;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun     pEvent = (WMEventPtr) data;
108*4882a593Smuzhiyun     dixLookupResourceByType((void *) &pHead, eventResource, eventResourceType,
109*4882a593Smuzhiyun                             NullClient, DixUnknownAccess);
110*4882a593Smuzhiyun     if (pHead) {
111*4882a593Smuzhiyun         pPrev = 0;
112*4882a593Smuzhiyun         for (pCur = *pHead; pCur && pCur != pEvent; pCur = pCur->next)
113*4882a593Smuzhiyun             pPrev = pCur;
114*4882a593Smuzhiyun         if (pCur) {
115*4882a593Smuzhiyun             if (pPrev)
116*4882a593Smuzhiyun                 pPrev->next = pEvent->next;
117*4882a593Smuzhiyun             else
118*4882a593Smuzhiyun                 *pHead = pEvent->next;
119*4882a593Smuzhiyun         }
120*4882a593Smuzhiyun         updateEventMask(pHead);
121*4882a593Smuzhiyun     }
122*4882a593Smuzhiyun     free((void *) pEvent);
123*4882a593Smuzhiyun     return 1;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun  /*ARGSUSED*/ static int
WMFreeEvents(void * data,XID id)127*4882a593Smuzhiyun WMFreeEvents(void *data, XID id)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun     WMEventPtr *pHead, pCur, pNext;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun     pHead = (WMEventPtr *) data;
132*4882a593Smuzhiyun     for (pCur = *pHead; pCur; pCur = pNext) {
133*4882a593Smuzhiyun         pNext = pCur->next;
134*4882a593Smuzhiyun         FreeResource(pCur->clientResource, ClientType);
135*4882a593Smuzhiyun         free((void *) pCur);
136*4882a593Smuzhiyun     }
137*4882a593Smuzhiyun     free((void *) pHead);
138*4882a593Smuzhiyun     eventMask = 0;
139*4882a593Smuzhiyun     return 1;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun static int
ProcWindowsWMSelectInput(ClientPtr client)143*4882a593Smuzhiyun ProcWindowsWMSelectInput(ClientPtr client)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun     REQUEST(xWindowsWMSelectInputReq);
146*4882a593Smuzhiyun     WMEventPtr pEvent, pNewEvent, *pHead;
147*4882a593Smuzhiyun     XID clientResource;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xWindowsWMSelectInputReq);
150*4882a593Smuzhiyun     dixLookupResourceByType((void *) &pHead, eventResource, eventResourceType,
151*4882a593Smuzhiyun                             client, DixWriteAccess);
152*4882a593Smuzhiyun     if (stuff->mask != 0) {
153*4882a593Smuzhiyun         if (pHead) {
154*4882a593Smuzhiyun             /* check for existing entry. */
155*4882a593Smuzhiyun             for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
156*4882a593Smuzhiyun                 if (pEvent->client == client) {
157*4882a593Smuzhiyun                     pEvent->mask = stuff->mask;
158*4882a593Smuzhiyun                     updateEventMask(pHead);
159*4882a593Smuzhiyun                     return Success;
160*4882a593Smuzhiyun                 }
161*4882a593Smuzhiyun             }
162*4882a593Smuzhiyun         }
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun         /* build the entry */
165*4882a593Smuzhiyun         pNewEvent = malloc(sizeof(WMEventRec));
166*4882a593Smuzhiyun         if (!pNewEvent)
167*4882a593Smuzhiyun             return BadAlloc;
168*4882a593Smuzhiyun         pNewEvent->next = 0;
169*4882a593Smuzhiyun         pNewEvent->client = client;
170*4882a593Smuzhiyun         pNewEvent->mask = stuff->mask;
171*4882a593Smuzhiyun         /*
172*4882a593Smuzhiyun          * add a resource that will be deleted when
173*4882a593Smuzhiyun          * the client goes away
174*4882a593Smuzhiyun          */
175*4882a593Smuzhiyun         clientResource = FakeClientID(client->index);
176*4882a593Smuzhiyun         pNewEvent->clientResource = clientResource;
177*4882a593Smuzhiyun         if (!AddResource(clientResource, ClientType, (void *) pNewEvent))
178*4882a593Smuzhiyun             return BadAlloc;
179*4882a593Smuzhiyun         /*
180*4882a593Smuzhiyun          * create a resource to contain a pointer to the list
181*4882a593Smuzhiyun          * of clients selecting input.  This must be indirect as
182*4882a593Smuzhiyun          * the list may be arbitrarily rearranged which cannot be
183*4882a593Smuzhiyun          * done through the resource database.
184*4882a593Smuzhiyun          */
185*4882a593Smuzhiyun         if (!pHead) {
186*4882a593Smuzhiyun             pHead = malloc(sizeof(WMEventPtr));
187*4882a593Smuzhiyun             if (!pHead ||
188*4882a593Smuzhiyun                 !AddResource(eventResource, eventResourceType, (void *) pHead))
189*4882a593Smuzhiyun             {
190*4882a593Smuzhiyun                 FreeResource(clientResource, RT_NONE);
191*4882a593Smuzhiyun                 return BadAlloc;
192*4882a593Smuzhiyun             }
193*4882a593Smuzhiyun             *pHead = 0;
194*4882a593Smuzhiyun         }
195*4882a593Smuzhiyun         pNewEvent->next = *pHead;
196*4882a593Smuzhiyun         *pHead = pNewEvent;
197*4882a593Smuzhiyun         updateEventMask(pHead);
198*4882a593Smuzhiyun     }
199*4882a593Smuzhiyun     else if (stuff->mask == 0) {
200*4882a593Smuzhiyun         /* delete the interest */
201*4882a593Smuzhiyun         if (pHead) {
202*4882a593Smuzhiyun             pNewEvent = 0;
203*4882a593Smuzhiyun             for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
204*4882a593Smuzhiyun                 if (pEvent->client == client)
205*4882a593Smuzhiyun                     break;
206*4882a593Smuzhiyun                 pNewEvent = pEvent;
207*4882a593Smuzhiyun             }
208*4882a593Smuzhiyun             if (pEvent) {
209*4882a593Smuzhiyun                 FreeResource(pEvent->clientResource, ClientType);
210*4882a593Smuzhiyun                 if (pNewEvent)
211*4882a593Smuzhiyun                     pNewEvent->next = pEvent->next;
212*4882a593Smuzhiyun                 else
213*4882a593Smuzhiyun                     *pHead = pEvent->next;
214*4882a593Smuzhiyun                 free(pEvent);
215*4882a593Smuzhiyun                 updateEventMask(pHead);
216*4882a593Smuzhiyun             }
217*4882a593Smuzhiyun         }
218*4882a593Smuzhiyun     }
219*4882a593Smuzhiyun     else {
220*4882a593Smuzhiyun         client->errorValue = stuff->mask;
221*4882a593Smuzhiyun         return BadValue;
222*4882a593Smuzhiyun     }
223*4882a593Smuzhiyun     return Success;
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun /*
227*4882a593Smuzhiyun  * deliver the event
228*4882a593Smuzhiyun  */
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun void
winWindowsWMSendEvent(int type,unsigned int mask,int which,int arg,Window window,int x,int y,int w,int h)231*4882a593Smuzhiyun winWindowsWMSendEvent(int type, unsigned int mask, int which, int arg,
232*4882a593Smuzhiyun                       Window window, int x, int y, int w, int h)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun     WMEventPtr *pHead, pEvent;
235*4882a593Smuzhiyun     ClientPtr client;
236*4882a593Smuzhiyun     xWindowsWMNotifyEvent se;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
239*4882a593Smuzhiyun     ErrorF("winWindowsWMSendEvent %d %d %d %d,  %d %d - %d %d\n",
240*4882a593Smuzhiyun            type, mask, which, arg, x, y, w, h);
241*4882a593Smuzhiyun #endif
242*4882a593Smuzhiyun     dixLookupResourceByType((void *) &pHead, eventResource, eventResourceType,
243*4882a593Smuzhiyun                             NullClient, DixUnknownAccess);
244*4882a593Smuzhiyun     if (!pHead)
245*4882a593Smuzhiyun         return;
246*4882a593Smuzhiyun     for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
247*4882a593Smuzhiyun         client = pEvent->client;
248*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
249*4882a593Smuzhiyun         ErrorF("winWindowsWMSendEvent - %p\n", client);
250*4882a593Smuzhiyun #endif
251*4882a593Smuzhiyun         if ((pEvent->mask & mask) == 0) {
252*4882a593Smuzhiyun             continue;
253*4882a593Smuzhiyun         }
254*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
255*4882a593Smuzhiyun         ErrorF("winWindowsWMSendEvent - send\n");
256*4882a593Smuzhiyun #endif
257*4882a593Smuzhiyun         se.type = type + WMEventBase;
258*4882a593Smuzhiyun         se.kind = which;
259*4882a593Smuzhiyun         se.window = window;
260*4882a593Smuzhiyun         se.arg = arg;
261*4882a593Smuzhiyun         se.x = x;
262*4882a593Smuzhiyun         se.y = y;
263*4882a593Smuzhiyun         se.w = w;
264*4882a593Smuzhiyun         se.h = h;
265*4882a593Smuzhiyun         se.time = currentTime.milliseconds;
266*4882a593Smuzhiyun         WriteEventsToClient(client, 1, (xEvent *) &se);
267*4882a593Smuzhiyun     }
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun /* general utility functions */
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun static int
ProcWindowsWMDisableUpdate(ClientPtr client)273*4882a593Smuzhiyun ProcWindowsWMDisableUpdate(ClientPtr client)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xWindowsWMDisableUpdateReq);
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun     //winDisableUpdate();
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun     return Success;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun static int
ProcWindowsWMReenableUpdate(ClientPtr client)283*4882a593Smuzhiyun ProcWindowsWMReenableUpdate(ClientPtr client)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xWindowsWMReenableUpdateReq);
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun     //winEnableUpdate();
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun     return Success;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun /* window functions */
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun static int
ProcWindowsWMSetFrontProcess(ClientPtr client)295*4882a593Smuzhiyun ProcWindowsWMSetFrontProcess(ClientPtr client)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xWindowsWMSetFrontProcessReq);
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun     //QuartzMessageMainThread(kWindowsSetFrontProcess, NULL, 0);
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun     return Success;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun /* frame functions */
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun static int
ProcWindowsWMFrameGetRect(ClientPtr client)307*4882a593Smuzhiyun ProcWindowsWMFrameGetRect(ClientPtr client)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun     xWindowsWMFrameGetRectReply rep;
310*4882a593Smuzhiyun     RECT rcNew;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun     REQUEST(xWindowsWMFrameGetRectReq);
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
315*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameGetRect %zu %d\n",
316*4882a593Smuzhiyun            (sizeof(xWindowsWMFrameGetRectReq) >> 2), (int) client->req_len);
317*4882a593Smuzhiyun #endif
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xWindowsWMFrameGetRectReq);
320*4882a593Smuzhiyun     rep.type = X_Reply;
321*4882a593Smuzhiyun     rep.length = 0;
322*4882a593Smuzhiyun     rep.sequenceNumber = client->sequence;
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun     if (stuff->frame_rect != 0) {
325*4882a593Smuzhiyun         ErrorF("ProcWindowsWMFrameGetRect - stuff->frame_rect != 0\n");
326*4882a593Smuzhiyun         return BadValue;
327*4882a593Smuzhiyun     }
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun     /* Store the origin, height, and width in a rectangle structure */
330*4882a593Smuzhiyun     SetRect(&rcNew, stuff->ix, stuff->iy,
331*4882a593Smuzhiyun             stuff->ix + stuff->iw, stuff->iy + stuff->ih);
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
334*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameGetRect - %d %d %d %d\n",
335*4882a593Smuzhiyun            stuff->ix, stuff->iy, stuff->ix + stuff->iw, stuff->iy + stuff->ih);
336*4882a593Smuzhiyun #endif
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun     /*
339*4882a593Smuzhiyun      * Calculate the required size of the Windows window rectangle,
340*4882a593Smuzhiyun      * given the size of the Windows window client area.
341*4882a593Smuzhiyun      */
342*4882a593Smuzhiyun     AdjustWindowRectEx(&rcNew, stuff->frame_style, FALSE,
343*4882a593Smuzhiyun                        stuff->frame_style_ex);
344*4882a593Smuzhiyun     rep.x = rcNew.left;
345*4882a593Smuzhiyun     rep.y = rcNew.top;
346*4882a593Smuzhiyun     rep.w = rcNew.right - rcNew.left;
347*4882a593Smuzhiyun     rep.h = rcNew.bottom - rcNew.top;
348*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
349*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameGetRect - %d %d %d %d\n",
350*4882a593Smuzhiyun            rep.x, rep.y, rep.w, rep.h);
351*4882a593Smuzhiyun #endif
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun     WriteToClient(client, sizeof(xWindowsWMFrameGetRectReply), &rep);
354*4882a593Smuzhiyun     return Success;
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun static int
ProcWindowsWMFrameDraw(ClientPtr client)358*4882a593Smuzhiyun ProcWindowsWMFrameDraw(ClientPtr client)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun     REQUEST(xWindowsWMFrameDrawReq);
361*4882a593Smuzhiyun     WindowPtr pWin;
362*4882a593Smuzhiyun     win32RootlessWindowPtr pRLWinPriv;
363*4882a593Smuzhiyun     RECT rcNew;
364*4882a593Smuzhiyun     int nCmdShow, rc;
365*4882a593Smuzhiyun     RegionRec newShape;
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xWindowsWMFrameDrawReq);
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
370*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameDraw\n");
371*4882a593Smuzhiyun #endif
372*4882a593Smuzhiyun     rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
373*4882a593Smuzhiyun     if (rc != Success)
374*4882a593Smuzhiyun         return rc;
375*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
376*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameDraw - Window found\n");
377*4882a593Smuzhiyun #endif
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun     pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow(pWin, TRUE);
380*4882a593Smuzhiyun     if (pRLWinPriv == 0)
381*4882a593Smuzhiyun         return BadWindow;
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
384*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameDraw - HWND %p 0x%08x 0x%08x\n",
385*4882a593Smuzhiyun            pRLWinPriv->hWnd, (int) stuff->frame_style,
386*4882a593Smuzhiyun            (int) stuff->frame_style_ex);
387*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameDraw - %d %d %d %d\n",
388*4882a593Smuzhiyun            stuff->ix, stuff->iy, stuff->iw, stuff->ih);
389*4882a593Smuzhiyun #endif
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun     /* Store the origin, height, and width in a rectangle structure */
392*4882a593Smuzhiyun     SetRect(&rcNew, stuff->ix, stuff->iy,
393*4882a593Smuzhiyun             stuff->ix + stuff->iw, stuff->iy + stuff->ih);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun     /*
396*4882a593Smuzhiyun      * Calculate the required size of the Windows window rectangle,
397*4882a593Smuzhiyun      * given the size of the Windows window client area.
398*4882a593Smuzhiyun      */
399*4882a593Smuzhiyun     AdjustWindowRectEx(&rcNew, stuff->frame_style, FALSE,
400*4882a593Smuzhiyun                        stuff->frame_style_ex);
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun     /* Set the window extended style flags */
403*4882a593Smuzhiyun     if (!SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, stuff->frame_style_ex)) {
404*4882a593Smuzhiyun         return BadValue;
405*4882a593Smuzhiyun     }
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun     /* Set the window standard style flags */
408*4882a593Smuzhiyun     if (!SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE, stuff->frame_style)) {
409*4882a593Smuzhiyun         return BadValue;
410*4882a593Smuzhiyun     }
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun     /* Flush the window style */
413*4882a593Smuzhiyun     if (!SetWindowPos(pRLWinPriv->hWnd, NULL,
414*4882a593Smuzhiyun                       rcNew.left, rcNew.top,
415*4882a593Smuzhiyun                       rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
416*4882a593Smuzhiyun                       SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE)) {
417*4882a593Smuzhiyun         return BadValue;
418*4882a593Smuzhiyun     }
419*4882a593Smuzhiyun     if (!IsWindowVisible(pRLWinPriv->hWnd))
420*4882a593Smuzhiyun         nCmdShow = SW_HIDE;
421*4882a593Smuzhiyun     else
422*4882a593Smuzhiyun         nCmdShow = SW_SHOWNA;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun     ShowWindow(pRLWinPriv->hWnd, nCmdShow);
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun     if (wBoundingShape(pWin) != NULL) {
427*4882a593Smuzhiyun         /* wBoundingShape is relative to *inner* origin of window.
428*4882a593Smuzhiyun            Translate by borderWidth to get the outside-relative position. */
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun         RegionNull(&newShape);
431*4882a593Smuzhiyun         RegionCopy(&newShape, wBoundingShape(pWin));
432*4882a593Smuzhiyun         RegionTranslate(&newShape, pWin->borderWidth, pWin->borderWidth);
433*4882a593Smuzhiyun         winMWExtWMReshapeFrame(pRLWinPriv, &newShape);
434*4882a593Smuzhiyun         RegionUninit(&newShape);
435*4882a593Smuzhiyun     }
436*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
437*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameDraw - done\n");
438*4882a593Smuzhiyun #endif
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun     return Success;
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun static int
ProcWindowsWMFrameSetTitle(ClientPtr client)444*4882a593Smuzhiyun ProcWindowsWMFrameSetTitle(ClientPtr client)
445*4882a593Smuzhiyun {
446*4882a593Smuzhiyun     unsigned int title_length, title_max;
447*4882a593Smuzhiyun     char *title_bytes;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun     REQUEST(xWindowsWMFrameSetTitleReq);
450*4882a593Smuzhiyun     WindowPtr pWin;
451*4882a593Smuzhiyun     win32RootlessWindowPtr pRLWinPriv;
452*4882a593Smuzhiyun     int rc;
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
455*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameSetTitle\n");
456*4882a593Smuzhiyun #endif
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xWindowsWMFrameSetTitleReq);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun     rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
461*4882a593Smuzhiyun     if (rc != Success)
462*4882a593Smuzhiyun         return rc;
463*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
464*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameSetTitle - Window found\n");
465*4882a593Smuzhiyun #endif
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun     title_length = stuff->title_length;
468*4882a593Smuzhiyun     title_max = (stuff->length << 2) - sizeof(xWindowsWMFrameSetTitleReq);
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun     if (title_max < title_length)
471*4882a593Smuzhiyun         return BadValue;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
474*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameSetTitle - length is valid\n");
475*4882a593Smuzhiyun #endif
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun     title_bytes = malloc(title_length + 1);
478*4882a593Smuzhiyun     strncpy(title_bytes, (char *) &stuff[1], title_length);
479*4882a593Smuzhiyun     title_bytes[title_length] = '\0';
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun     pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow(pWin, FALSE);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun     if (pRLWinPriv == 0) {
484*4882a593Smuzhiyun         free(title_bytes);
485*4882a593Smuzhiyun         return BadWindow;
486*4882a593Smuzhiyun     }
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun     /* Flush the window style */
489*4882a593Smuzhiyun     SetWindowText(pRLWinPriv->hWnd, title_bytes);
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun     free(title_bytes);
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
494*4882a593Smuzhiyun     ErrorF("ProcWindowsWMFrameSetTitle - done\n");
495*4882a593Smuzhiyun #endif
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun     return Success;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun /* dispatch */
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun static int
ProcWindowsWMDispatch(ClientPtr client)503*4882a593Smuzhiyun ProcWindowsWMDispatch(ClientPtr client)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun     REQUEST(xReq);
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun     switch (stuff->data) {
508*4882a593Smuzhiyun     case X_WindowsWMQueryVersion:
509*4882a593Smuzhiyun         return ProcWindowsWMQueryVersion(client);
510*4882a593Smuzhiyun     }
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun     if (!client->local)
513*4882a593Smuzhiyun         return WMErrorBase + WindowsWMClientNotLocal;
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun     switch (stuff->data) {
516*4882a593Smuzhiyun     case X_WindowsWMSelectInput:
517*4882a593Smuzhiyun         return ProcWindowsWMSelectInput(client);
518*4882a593Smuzhiyun     case X_WindowsWMDisableUpdate:
519*4882a593Smuzhiyun         return ProcWindowsWMDisableUpdate(client);
520*4882a593Smuzhiyun     case X_WindowsWMReenableUpdate:
521*4882a593Smuzhiyun         return ProcWindowsWMReenableUpdate(client);
522*4882a593Smuzhiyun     case X_WindowsWMSetFrontProcess:
523*4882a593Smuzhiyun         return ProcWindowsWMSetFrontProcess(client);
524*4882a593Smuzhiyun     case X_WindowsWMFrameGetRect:
525*4882a593Smuzhiyun         return ProcWindowsWMFrameGetRect(client);
526*4882a593Smuzhiyun     case X_WindowsWMFrameDraw:
527*4882a593Smuzhiyun         return ProcWindowsWMFrameDraw(client);
528*4882a593Smuzhiyun     case X_WindowsWMFrameSetTitle:
529*4882a593Smuzhiyun         return ProcWindowsWMFrameSetTitle(client);
530*4882a593Smuzhiyun     default:
531*4882a593Smuzhiyun         return BadRequest;
532*4882a593Smuzhiyun     }
533*4882a593Smuzhiyun }
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun static void
SNotifyEvent(xWindowsWMNotifyEvent * from,xWindowsWMNotifyEvent * to)536*4882a593Smuzhiyun SNotifyEvent(xWindowsWMNotifyEvent * from, xWindowsWMNotifyEvent * to)
537*4882a593Smuzhiyun {
538*4882a593Smuzhiyun     to->type = from->type;
539*4882a593Smuzhiyun     to->kind = from->kind;
540*4882a593Smuzhiyun     cpswaps(from->sequenceNumber, to->sequenceNumber);
541*4882a593Smuzhiyun     cpswapl(from->window, to->window);
542*4882a593Smuzhiyun     cpswapl(from->time, to->time);
543*4882a593Smuzhiyun     cpswapl(from->arg, to->arg);
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun static int
SProcWindowsWMQueryVersion(ClientPtr client)547*4882a593Smuzhiyun SProcWindowsWMQueryVersion(ClientPtr client)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun     REQUEST(xWindowsWMQueryVersionReq);
550*4882a593Smuzhiyun     swaps(&stuff->length);
551*4882a593Smuzhiyun     return ProcWindowsWMQueryVersion(client);
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun static int
SProcWindowsWMDispatch(ClientPtr client)555*4882a593Smuzhiyun SProcWindowsWMDispatch(ClientPtr client)
556*4882a593Smuzhiyun {
557*4882a593Smuzhiyun     REQUEST(xReq);
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun     /* It is bound to be non-local when there is byte swapping */
560*4882a593Smuzhiyun     if (!client->local)
561*4882a593Smuzhiyun         return WMErrorBase + WindowsWMClientNotLocal;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun     /* only local clients are allowed WM access */
564*4882a593Smuzhiyun     switch (stuff->data) {
565*4882a593Smuzhiyun     case X_WindowsWMQueryVersion:
566*4882a593Smuzhiyun         return SProcWindowsWMQueryVersion(client);
567*4882a593Smuzhiyun     default:
568*4882a593Smuzhiyun         return BadRequest;
569*4882a593Smuzhiyun     }
570*4882a593Smuzhiyun }
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun void
winWindowsWMExtensionInit(void)573*4882a593Smuzhiyun winWindowsWMExtensionInit(void)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun     ExtensionEntry *extEntry;
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun     ClientType = CreateNewResourceType(WMFreeClient, "WMClient");
578*4882a593Smuzhiyun     eventResourceType = CreateNewResourceType(WMFreeEvents, "WMEvent");
579*4882a593Smuzhiyun     eventResource = FakeClientID(0);
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun     if (ClientType && eventResourceType &&
582*4882a593Smuzhiyun         (extEntry = AddExtension(WINDOWSWMNAME,
583*4882a593Smuzhiyun                                  WindowsWMNumberEvents,
584*4882a593Smuzhiyun                                  WindowsWMNumberErrors,
585*4882a593Smuzhiyun                                  ProcWindowsWMDispatch,
586*4882a593Smuzhiyun                                  SProcWindowsWMDispatch,
587*4882a593Smuzhiyun                                  NULL, StandardMinorOpcode))) {
588*4882a593Smuzhiyun         size_t i;
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun         WMReqCode = (unsigned char) extEntry->base;
591*4882a593Smuzhiyun         WMErrorBase = extEntry->errorBase;
592*4882a593Smuzhiyun         WMEventBase = extEntry->eventBase;
593*4882a593Smuzhiyun         for (i = 0; i < WindowsWMNumberEvents; i++)
594*4882a593Smuzhiyun             EventSwapVector[WMEventBase + i] = (EventSwapPtr) SNotifyEvent;
595*4882a593Smuzhiyun     }
596*4882a593Smuzhiyun }
597