1706f2543Smrg/* WindowsWM extension is based on AppleWM extension */
2706f2543Smrg/**************************************************************************
3706f2543Smrg
4706f2543SmrgCopyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
5706f2543SmrgCopyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
6706f2543Smrg
7706f2543SmrgPermission is hereby granted, free of charge, to any person obtaining a
8706f2543Smrgcopy of this software and associated documentation files (the
9706f2543Smrg"Software"), to deal in the Software without restriction, including
10706f2543Smrgwithout limitation the rights to use, copy, modify, merge, publish,
11706f2543Smrgdistribute, sub license, and/or sell copies of the Software, and to
12706f2543Smrgpermit persons to whom the Software is furnished to do so, subject to
13706f2543Smrgthe following conditions:
14706f2543Smrg
15706f2543SmrgThe above copyright notice and this permission notice (including the
16706f2543Smrgnext paragraph) shall be included in all copies or substantial portions
17706f2543Smrgof the Software.
18706f2543Smrg
19706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20706f2543SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21706f2543SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22706f2543SmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23706f2543SmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24706f2543SmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25706f2543SmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26706f2543Smrg
27706f2543Smrg**************************************************************************/
28706f2543Smrg
29706f2543Smrg#ifdef HAVE_XWIN_CONFIG_H
30706f2543Smrg#include <xwin-config.h>
31706f2543Smrg#endif
32706f2543Smrg#include "win.h"
33706f2543Smrg
34706f2543Smrg#include "misc.h"
35706f2543Smrg#include "dixstruct.h"
36706f2543Smrg#include "extnsionst.h"
37706f2543Smrg#include "colormapst.h"
38706f2543Smrg#include "cursorstr.h"
39706f2543Smrg#include "scrnintstr.h"
40706f2543Smrg#include "servermd.h"
41706f2543Smrg#include "swaprep.h"
42706f2543Smrg#define _WINDOWSWM_SERVER_
43706f2543Smrg#include <X11/extensions/windowswmstr.h>
44706f2543Smrg#include "protocol-versions.h"
45706f2543Smrg
46706f2543Smrgstatic int WMErrorBase;
47706f2543Smrgstatic unsigned char WMReqCode = 0;
48706f2543Smrgstatic int WMEventBase = 0;
49706f2543Smrg
50706f2543Smrgstatic RESTYPE ClientType, eventResourceType; /* resource types for event masks */
51706f2543Smrgstatic XID eventResource;
52706f2543Smrg
53706f2543Smrg/* Currently selected events */
54706f2543Smrgstatic unsigned int eventMask = 0;
55706f2543Smrg
56706f2543Smrgstatic int WMFreeClient (pointer data, XID id);
57706f2543Smrgstatic int WMFreeEvents (pointer data, XID id);
58706f2543Smrgstatic void SNotifyEvent(xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to);
59706f2543Smrg
60706f2543Smrgtypedef struct _WMEvent *WMEventPtr;
61706f2543Smrgtypedef struct _WMEvent {
62706f2543Smrg  WMEventPtr      next;
63706f2543Smrg  ClientPtr	    client;
64706f2543Smrg  XID		    clientResource;
65706f2543Smrg  unsigned int    mask;
66706f2543Smrg} WMEventRec;
67706f2543Smrg
68706f2543Smrgstatic inline BoxRec
69706f2543Smrgmake_box (int x, int y, int w, int h)
70706f2543Smrg{
71706f2543Smrg  BoxRec r;
72706f2543Smrg  r.x1 = x;
73706f2543Smrg  r.y1 = y;
74706f2543Smrg  r.x2 = x + w;
75706f2543Smrg  r.y2 = y + h;
76706f2543Smrg  return r;
77706f2543Smrg}
78706f2543Smrg
79706f2543Smrgstatic int
80706f2543SmrgProcWindowsWMQueryVersion(ClientPtr client)
81706f2543Smrg{
82706f2543Smrg  xWindowsWMQueryVersionReply rep;
83706f2543Smrg  int n;
84706f2543Smrg
85706f2543Smrg  REQUEST_SIZE_MATCH(xWindowsWMQueryVersionReq);
86706f2543Smrg  rep.type = X_Reply;
87706f2543Smrg  rep.length = 0;
88706f2543Smrg  rep.sequenceNumber = client->sequence;
89706f2543Smrg  rep.majorVersion = SERVER_WINDOWSWM_MAJOR_VERSION;
90706f2543Smrg  rep.minorVersion = SERVER_WINDOWSWM_MINOR_VERSION;
91706f2543Smrg  rep.patchVersion = SERVER_WINDOWSWM_PATCH_VERSION;
92706f2543Smrg  if (client->swapped)
93706f2543Smrg    {
94706f2543Smrg      swaps(&rep.sequenceNumber, n);
95706f2543Smrg      swapl(&rep.length, n);
96706f2543Smrg    }
97706f2543Smrg  WriteToClient(client, sizeof(xWindowsWMQueryVersionReply), (char *)&rep);
98706f2543Smrg  return Success;
99706f2543Smrg}
100706f2543Smrg
101706f2543Smrg
102706f2543Smrg/* events */
103706f2543Smrg
104706f2543Smrgstatic inline void
105706f2543SmrgupdateEventMask (WMEventPtr *pHead)
106706f2543Smrg{
107706f2543Smrg  WMEventPtr pCur;
108706f2543Smrg
109706f2543Smrg  eventMask = 0;
110706f2543Smrg  for (pCur = *pHead; pCur != NULL; pCur = pCur->next)
111706f2543Smrg    eventMask |= pCur->mask;
112706f2543Smrg}
113706f2543Smrg
114706f2543Smrg/*ARGSUSED*/
115706f2543Smrgstatic int
116706f2543SmrgWMFreeClient (pointer data, XID id)
117706f2543Smrg{
118706f2543Smrg  WMEventPtr   pEvent;
119706f2543Smrg  WMEventPtr   *pHead, pCur, pPrev;
120706f2543Smrg
121706f2543Smrg  pEvent = (WMEventPtr) data;
122706f2543Smrg  dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType,
123706f2543Smrg				NullClient, DixUnknownAccess);
124706f2543Smrg  if (pHead)
125706f2543Smrg    {
126706f2543Smrg      pPrev = 0;
127706f2543Smrg      for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next)
128706f2543Smrg	pPrev = pCur;
129706f2543Smrg      if (pCur)
130706f2543Smrg	{
131706f2543Smrg	  if (pPrev)
132706f2543Smrg	    pPrev->next = pEvent->next;
133706f2543Smrg	  else
134706f2543Smrg	    *pHead = pEvent->next;
135706f2543Smrg	}
136706f2543Smrg      updateEventMask (pHead);
137706f2543Smrg    }
138706f2543Smrg  free((pointer) pEvent);
139706f2543Smrg  return 1;
140706f2543Smrg}
141706f2543Smrg
142706f2543Smrg/*ARGSUSED*/
143706f2543Smrgstatic int
144706f2543SmrgWMFreeEvents (pointer data, XID id)
145706f2543Smrg{
146706f2543Smrg  WMEventPtr   *pHead, pCur, pNext;
147706f2543Smrg
148706f2543Smrg  pHead = (WMEventPtr *) data;
149706f2543Smrg  for (pCur = *pHead; pCur; pCur = pNext)
150706f2543Smrg    {
151706f2543Smrg      pNext = pCur->next;
152706f2543Smrg      FreeResource (pCur->clientResource, ClientType);
153706f2543Smrg      free((pointer) pCur);
154706f2543Smrg    }
155706f2543Smrg  free((pointer) pHead);
156706f2543Smrg  eventMask = 0;
157706f2543Smrg  return 1;
158706f2543Smrg}
159706f2543Smrg
160706f2543Smrgstatic int
161706f2543SmrgProcWindowsWMSelectInput (ClientPtr client)
162706f2543Smrg{
163706f2543Smrg  REQUEST(xWindowsWMSelectInputReq);
164706f2543Smrg  WMEventPtr		pEvent, pNewEvent, *pHead;
165706f2543Smrg  XID			clientResource;
166706f2543Smrg
167706f2543Smrg  REQUEST_SIZE_MATCH (xWindowsWMSelectInputReq);
168706f2543Smrg  dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType, client, DixWriteAccess);
169706f2543Smrg  if (stuff->mask != 0)
170706f2543Smrg    {
171706f2543Smrg      if (pHead)
172706f2543Smrg	{
173706f2543Smrg	  /* check for existing entry. */
174706f2543Smrg	  for (pEvent = *pHead; pEvent; pEvent = pEvent->next)
175706f2543Smrg	    {
176706f2543Smrg	      if (pEvent->client == client)
177706f2543Smrg		{
178706f2543Smrg		  pEvent->mask = stuff->mask;
179706f2543Smrg		  updateEventMask (pHead);
180706f2543Smrg		  return Success;
181706f2543Smrg		}
182706f2543Smrg	    }
183706f2543Smrg	}
184706f2543Smrg
185706f2543Smrg      /* build the entry */
186706f2543Smrg      pNewEvent = (WMEventPtr) malloc(sizeof (WMEventRec));
187706f2543Smrg      if (!pNewEvent)
188706f2543Smrg	return BadAlloc;
189706f2543Smrg      pNewEvent->next = 0;
190706f2543Smrg      pNewEvent->client = client;
191706f2543Smrg      pNewEvent->mask = stuff->mask;
192706f2543Smrg      /*
193706f2543Smrg       * add a resource that will be deleted when
194706f2543Smrg       * the client goes away
195706f2543Smrg       */
196706f2543Smrg      clientResource = FakeClientID (client->index);
197706f2543Smrg      pNewEvent->clientResource = clientResource;
198706f2543Smrg      if (!AddResource (clientResource, ClientType, (pointer)pNewEvent))
199706f2543Smrg	return BadAlloc;
200706f2543Smrg      /*
201706f2543Smrg       * create a resource to contain a pointer to the list
202706f2543Smrg       * of clients selecting input.  This must be indirect as
203706f2543Smrg       * the list may be arbitrarily rearranged which cannot be
204706f2543Smrg       * done through the resource database.
205706f2543Smrg       */
206706f2543Smrg      if (!pHead)
207706f2543Smrg	{
208706f2543Smrg	  pHead = (WMEventPtr *) malloc(sizeof (WMEventPtr));
209706f2543Smrg	  if (!pHead ||
210706f2543Smrg	      !AddResource (eventResource, eventResourceType, (pointer)pHead))
211706f2543Smrg	    {
212706f2543Smrg	      FreeResource (clientResource, RT_NONE);
213706f2543Smrg	      return BadAlloc;
214706f2543Smrg	    }
215706f2543Smrg	  *pHead = 0;
216706f2543Smrg	}
217706f2543Smrg      pNewEvent->next = *pHead;
218706f2543Smrg      *pHead = pNewEvent;
219706f2543Smrg      updateEventMask (pHead);
220706f2543Smrg    }
221706f2543Smrg  else if (stuff->mask == 0)
222706f2543Smrg    {
223706f2543Smrg      /* delete the interest */
224706f2543Smrg      if (pHead)
225706f2543Smrg	{
226706f2543Smrg	  pNewEvent = 0;
227706f2543Smrg	  for (pEvent = *pHead; pEvent; pEvent = pEvent->next)
228706f2543Smrg	    {
229706f2543Smrg	      if (pEvent->client == client)
230706f2543Smrg		break;
231706f2543Smrg	      pNewEvent = pEvent;
232706f2543Smrg	    }
233706f2543Smrg	  if (pEvent)
234706f2543Smrg	    {
235706f2543Smrg	      FreeResource (pEvent->clientResource, ClientType);
236706f2543Smrg	      if (pNewEvent)
237706f2543Smrg		pNewEvent->next = pEvent->next;
238706f2543Smrg	      else
239706f2543Smrg		*pHead = pEvent->next;
240706f2543Smrg	      free(pEvent);
241706f2543Smrg	      updateEventMask (pHead);
242706f2543Smrg	    }
243706f2543Smrg	}
244706f2543Smrg    }
245706f2543Smrg  else
246706f2543Smrg    {
247706f2543Smrg      client->errorValue = stuff->mask;
248706f2543Smrg      return BadValue;
249706f2543Smrg    }
250706f2543Smrg  return Success;
251706f2543Smrg}
252706f2543Smrg
253706f2543Smrg/*
254706f2543Smrg * deliver the event
255706f2543Smrg */
256706f2543Smrg
257706f2543Smrgvoid
258706f2543SmrgwinWindowsWMSendEvent (int type, unsigned int mask, int which, int arg,
259706f2543Smrg		       Window window, int x, int y, int w, int h)
260706f2543Smrg{
261706f2543Smrg  WMEventPtr		*pHead, pEvent;
262706f2543Smrg  ClientPtr		client;
263706f2543Smrg  xWindowsWMNotifyEvent se;
264706f2543Smrg#if CYGMULTIWINDOW_DEBUG
265706f2543Smrg  ErrorF ("winWindowsWMSendEvent %d %d %d %d,  %d %d - %d %d\n",
266706f2543Smrg	  type, mask, which, arg, x, y, w, h);
267706f2543Smrg#endif
268706f2543Smrg  dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType,
269706f2543Smrg				NullClient, DixUnknownAccess);
270706f2543Smrg  if (!pHead)
271706f2543Smrg    return;
272706f2543Smrg  for (pEvent = *pHead; pEvent; pEvent = pEvent->next)
273706f2543Smrg    {
274706f2543Smrg      client = pEvent->client;
275706f2543Smrg#if CYGMULTIWINDOW_DEBUG
276706f2543Smrg      ErrorF ("winWindowsWMSendEvent - x%08x\n", (int) client);
277706f2543Smrg#endif
278706f2543Smrg      if ((pEvent->mask & mask) == 0)
279706f2543Smrg	{
280706f2543Smrg	  continue;
281706f2543Smrg	}
282706f2543Smrg#if CYGMULTIWINDOW_DEBUG
283706f2543Smrg      ErrorF ("winWindowsWMSendEvent - send\n");
284706f2543Smrg#endif
285706f2543Smrg      se.type = type + WMEventBase;
286706f2543Smrg      se.kind = which;
287706f2543Smrg      se.window = window;
288706f2543Smrg      se.arg = arg;
289706f2543Smrg      se.x = x;
290706f2543Smrg      se.y = y;
291706f2543Smrg      se.w = w;
292706f2543Smrg      se.h = h;
293706f2543Smrg      se.time = currentTime.milliseconds;
294706f2543Smrg      WriteEventsToClient (client, 1, (xEvent *) &se);
295706f2543Smrg    }
296706f2543Smrg}
297706f2543Smrg
298706f2543Smrg/* general utility functions */
299706f2543Smrg
300706f2543Smrgstatic int
301706f2543SmrgProcWindowsWMDisableUpdate (ClientPtr client)
302706f2543Smrg{
303706f2543Smrg  REQUEST_SIZE_MATCH(xWindowsWMDisableUpdateReq);
304706f2543Smrg
305706f2543Smrg  //winDisableUpdate();
306706f2543Smrg
307706f2543Smrg  return Success;
308706f2543Smrg}
309706f2543Smrg
310706f2543Smrgstatic int
311706f2543SmrgProcWindowsWMReenableUpdate (ClientPtr client)
312706f2543Smrg{
313706f2543Smrg  REQUEST_SIZE_MATCH(xWindowsWMReenableUpdateReq);
314706f2543Smrg
315706f2543Smrg  //winEnableUpdate();
316706f2543Smrg
317706f2543Smrg  return Success;
318706f2543Smrg}
319706f2543Smrg
320706f2543Smrg
321706f2543Smrg/* window functions */
322706f2543Smrg
323706f2543Smrgstatic int
324706f2543SmrgProcWindowsWMSetFrontProcess (ClientPtr client)
325706f2543Smrg{
326706f2543Smrg  REQUEST_SIZE_MATCH(xWindowsWMSetFrontProcessReq);
327706f2543Smrg
328706f2543Smrg  //QuartzMessageMainThread(kWindowsSetFrontProcess, NULL, 0);
329706f2543Smrg
330706f2543Smrg  return Success;
331706f2543Smrg}
332706f2543Smrg
333706f2543Smrg
334706f2543Smrg/* frame functions */
335706f2543Smrg
336706f2543Smrgstatic int
337706f2543SmrgProcWindowsWMFrameGetRect (ClientPtr client)
338706f2543Smrg{
339706f2543Smrg  xWindowsWMFrameGetRectReply rep;
340706f2543Smrg  BoxRec ir;
341706f2543Smrg  RECT rcNew;
342706f2543Smrg  REQUEST(xWindowsWMFrameGetRectReq);
343706f2543Smrg
344706f2543Smrg#if CYGMULTIWINDOW_DEBUG
345706f2543Smrg  ErrorF ("ProcWindowsWMFrameGetRect %d %d\n",
346706f2543Smrg	  (sizeof(xWindowsWMFrameGetRectReq) >> 2), (int) client->req_len);
347706f2543Smrg#endif
348706f2543Smrg
349706f2543Smrg  REQUEST_SIZE_MATCH(xWindowsWMFrameGetRectReq);
350706f2543Smrg  rep.type = X_Reply;
351706f2543Smrg  rep.length = 0;
352706f2543Smrg  rep.sequenceNumber = client->sequence;
353706f2543Smrg
354706f2543Smrg  ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
355706f2543Smrg
356706f2543Smrg  if (stuff->frame_rect != 0)
357706f2543Smrg    {
358706f2543Smrg      ErrorF ("ProcWindowsWMFrameGetRect - stuff->frame_rect != 0\n");
359706f2543Smrg      return BadValue;
360706f2543Smrg    }
361706f2543Smrg
362706f2543Smrg  /* Store the origin, height, and width in a rectangle structure */
363706f2543Smrg  SetRect (&rcNew, stuff->ix, stuff->iy,
364706f2543Smrg	   stuff->ix + stuff->iw, stuff->iy + stuff->ih);
365706f2543Smrg
366706f2543Smrg#if CYGMULTIWINDOW_DEBUG
367706f2543Smrg  ErrorF ("ProcWindowsWMFrameGetRect - %d %d %d %d\n",
368706f2543Smrg	  stuff->ix, stuff->iy, stuff->ix + stuff->iw, stuff->iy + stuff->ih);
369706f2543Smrg#endif
370706f2543Smrg
371706f2543Smrg  /*
372706f2543Smrg   * Calculate the required size of the Windows window rectangle,
373706f2543Smrg   * given the size of the Windows window client area.
374706f2543Smrg   */
375706f2543Smrg  AdjustWindowRectEx (&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex);
376706f2543Smrg  rep.x = rcNew.left;
377706f2543Smrg  rep.y = rcNew.top;
378706f2543Smrg  rep.w = rcNew.right - rcNew.left;
379706f2543Smrg  rep.h = rcNew.bottom - rcNew.top;
380706f2543Smrg#if CYGMULTIWINDOW_DEBUG
381706f2543Smrg  ErrorF ("ProcWindowsWMFrameGetRect - %d %d %d %d\n",
382706f2543Smrg	  rep.x, rep.y, rep.w, rep.h);
383706f2543Smrg#endif
384706f2543Smrg
385706f2543Smrg  WriteToClient(client, sizeof(xWindowsWMFrameGetRectReply), (char *)&rep);
386706f2543Smrg  return Success;
387706f2543Smrg}
388706f2543Smrg
389706f2543Smrg
390706f2543Smrgstatic int
391706f2543SmrgProcWindowsWMFrameDraw (ClientPtr client)
392706f2543Smrg{
393706f2543Smrg  REQUEST(xWindowsWMFrameDrawReq);
394706f2543Smrg  WindowPtr pWin;
395706f2543Smrg  win32RootlessWindowPtr pRLWinPriv;
396706f2543Smrg  RECT rcNew;
397706f2543Smrg  int nCmdShow, rc;
398706f2543Smrg  RegionRec newShape;
399706f2543Smrg
400706f2543Smrg  REQUEST_SIZE_MATCH (xWindowsWMFrameDrawReq);
401706f2543Smrg
402706f2543Smrg#if CYGMULTIWINDOW_DEBUG
403706f2543Smrg  ErrorF ("ProcWindowsWMFrameDraw\n");
404706f2543Smrg#endif
405706f2543Smrg  rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
406706f2543Smrg  if (rc != Success)
407706f2543Smrg      return rc;
408706f2543Smrg#if CYGMULTIWINDOW_DEBUG
409706f2543Smrg  ErrorF ("ProcWindowsWMFrameDraw - Window found\n");
410706f2543Smrg#endif
411706f2543Smrg
412706f2543Smrg  pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, TRUE);
413706f2543Smrg  if (pRLWinPriv == 0) return BadWindow;
414706f2543Smrg
415706f2543Smrg#if CYGMULTIWINDOW_DEBUG
416706f2543Smrg  ErrorF ("ProcWindowsWMFrameDraw - HWND 0x%08x 0x%08x 0x%08x\n",
417706f2543Smrg	  (int) pRLWinPriv->hWnd, (int) stuff->frame_style,
418706f2543Smrg	  (int) stuff->frame_style_ex);
419706f2543Smrg  ErrorF ("ProcWindowsWMFrameDraw - %d %d %d %d\n",
420706f2543Smrg	  stuff->ix, stuff->iy, stuff->iw, stuff->ih);
421706f2543Smrg#endif
422706f2543Smrg
423706f2543Smrg  /* Store the origin, height, and width in a rectangle structure */
424706f2543Smrg  SetRect (&rcNew, stuff->ix, stuff->iy,
425706f2543Smrg	   stuff->ix + stuff->iw, stuff->iy + stuff->ih);
426706f2543Smrg
427706f2543Smrg  /*
428706f2543Smrg   * Calculate the required size of the Windows window rectangle,
429706f2543Smrg   * given the size of the Windows window client area.
430706f2543Smrg   */
431706f2543Smrg  AdjustWindowRectEx (&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex);
432706f2543Smrg
433706f2543Smrg  /* Set the window extended style flags */
434706f2543Smrg  if (!SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, stuff->frame_style_ex))
435706f2543Smrg    {
436706f2543Smrg      return BadValue;
437706f2543Smrg    }
438706f2543Smrg
439706f2543Smrg  /* Set the window standard style flags */
440706f2543Smrg  if (!SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, stuff->frame_style))
441706f2543Smrg    {
442706f2543Smrg      return BadValue;
443706f2543Smrg    }
444706f2543Smrg
445706f2543Smrg  /* Flush the window style */
446706f2543Smrg  if (!SetWindowPos (pRLWinPriv->hWnd, NULL,
447706f2543Smrg		     rcNew.left, rcNew.top,
448706f2543Smrg		     rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
449706f2543Smrg		     SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE))
450706f2543Smrg    {
451706f2543Smrg      return BadValue;
452706f2543Smrg    }
453706f2543Smrg  if (!IsWindowVisible(pRLWinPriv->hWnd))
454706f2543Smrg    nCmdShow = SW_HIDE;
455706f2543Smrg  else
456706f2543Smrg    nCmdShow = SW_SHOWNA;
457706f2543Smrg
458706f2543Smrg  ShowWindow (pRLWinPriv->hWnd, nCmdShow);
459706f2543Smrg
460706f2543Smrg  winMWExtWMUpdateIcon (pWin->drawable.id);
461706f2543Smrg
462706f2543Smrg  if (wBoundingShape(pWin) != NULL)
463706f2543Smrg    {
464706f2543Smrg      /* wBoundingShape is relative to *inner* origin of window.
465706f2543Smrg	 Translate by borderWidth to get the outside-relative position. */
466706f2543Smrg
467706f2543Smrg      RegionNull(&newShape);
468706f2543Smrg      RegionCopy(&newShape, wBoundingShape(pWin));
469706f2543Smrg      RegionTranslate(&newShape, pWin->borderWidth, pWin->borderWidth);
470706f2543Smrg      winMWExtWMReshapeFrame (pRLWinPriv, &newShape);
471706f2543Smrg      RegionUninit(&newShape);
472706f2543Smrg    }
473706f2543Smrg#if CYGMULTIWINDOW_DEBUG
474706f2543Smrg  ErrorF ("ProcWindowsWMFrameDraw - done\n");
475706f2543Smrg#endif
476706f2543Smrg
477706f2543Smrg  return Success;
478706f2543Smrg}
479706f2543Smrg
480706f2543Smrgstatic int
481706f2543SmrgProcWindowsWMFrameSetTitle(ClientPtr client)
482706f2543Smrg{
483706f2543Smrg  unsigned int title_length, title_max;
484706f2543Smrg  char *title_bytes;
485706f2543Smrg  REQUEST(xWindowsWMFrameSetTitleReq);
486706f2543Smrg  WindowPtr pWin;
487706f2543Smrg  win32RootlessWindowPtr pRLWinPriv;
488706f2543Smrg  int rc;
489706f2543Smrg
490706f2543Smrg#if CYGMULTIWINDOW_DEBUG
491706f2543Smrg  ErrorF ("ProcWindowsWMFrameSetTitle\n");
492706f2543Smrg#endif
493706f2543Smrg
494706f2543Smrg  REQUEST_AT_LEAST_SIZE(xWindowsWMFrameSetTitleReq);
495706f2543Smrg
496706f2543Smrg  rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
497706f2543Smrg  if (rc != Success)
498706f2543Smrg      return rc;
499706f2543Smrg#if CYGMULTIWINDOW_DEBUG
500706f2543Smrg  ErrorF ("ProcWindowsWMFrameSetTitle - Window found\n");
501706f2543Smrg#endif
502706f2543Smrg
503706f2543Smrg  title_length = stuff->title_length;
504706f2543Smrg  title_max = (stuff->length << 2) - sizeof(xWindowsWMFrameSetTitleReq);
505706f2543Smrg
506706f2543Smrg  if (title_max < title_length)
507706f2543Smrg    return BadValue;
508706f2543Smrg
509706f2543Smrg#if CYGMULTIWINDOW_DEBUG
510706f2543Smrg  ErrorF ("ProcWindowsWMFrameSetTitle - length is valid\n");
511706f2543Smrg#endif
512706f2543Smrg
513706f2543Smrg  title_bytes = malloc (title_length+1);
514706f2543Smrg  strncpy (title_bytes, (unsigned char *) &stuff[1], title_length);
515706f2543Smrg  title_bytes[title_length] = '\0';
516706f2543Smrg
517706f2543Smrg  pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
518706f2543Smrg
519706f2543Smrg  if (pRLWinPriv == 0)
520706f2543Smrg    {
521706f2543Smrg      free (title_bytes);
522706f2543Smrg      return BadWindow;
523706f2543Smrg    }
524706f2543Smrg
525706f2543Smrg  /* Flush the window style */
526706f2543Smrg  SetWindowText (pRLWinPriv->hWnd, title_bytes);
527706f2543Smrg
528706f2543Smrg  free (title_bytes);
529706f2543Smrg
530706f2543Smrg#if CYGMULTIWINDOW_DEBUG
531706f2543Smrg  ErrorF ("ProcWindowsWMFrameSetTitle - done\n");
532706f2543Smrg#endif
533706f2543Smrg
534706f2543Smrg  return Success;
535706f2543Smrg}
536706f2543Smrg
537706f2543Smrg
538706f2543Smrg/* dispatch */
539706f2543Smrg
540706f2543Smrgstatic int
541706f2543SmrgProcWindowsWMDispatch (ClientPtr client)
542706f2543Smrg{
543706f2543Smrg  REQUEST(xReq);
544706f2543Smrg
545706f2543Smrg  switch (stuff->data)
546706f2543Smrg    {
547706f2543Smrg    case X_WindowsWMQueryVersion:
548706f2543Smrg      return ProcWindowsWMQueryVersion(client);
549706f2543Smrg    }
550706f2543Smrg
551706f2543Smrg  if (!LocalClient(client))
552706f2543Smrg    return WMErrorBase + WindowsWMClientNotLocal;
553706f2543Smrg
554706f2543Smrg  switch (stuff->data)
555706f2543Smrg    {
556706f2543Smrg    case X_WindowsWMSelectInput:
557706f2543Smrg      return ProcWindowsWMSelectInput(client);
558706f2543Smrg    case X_WindowsWMDisableUpdate:
559706f2543Smrg      return ProcWindowsWMDisableUpdate(client);
560706f2543Smrg    case X_WindowsWMReenableUpdate:
561706f2543Smrg      return ProcWindowsWMReenableUpdate(client);
562706f2543Smrg    case X_WindowsWMSetFrontProcess:
563706f2543Smrg      return ProcWindowsWMSetFrontProcess(client);
564706f2543Smrg    case X_WindowsWMFrameGetRect:
565706f2543Smrg      return ProcWindowsWMFrameGetRect(client);
566706f2543Smrg    case X_WindowsWMFrameDraw:
567706f2543Smrg      return ProcWindowsWMFrameDraw(client);
568706f2543Smrg    case X_WindowsWMFrameSetTitle:
569706f2543Smrg      return ProcWindowsWMFrameSetTitle(client);
570706f2543Smrg    default:
571706f2543Smrg      return BadRequest;
572706f2543Smrg    }
573706f2543Smrg}
574706f2543Smrg
575706f2543Smrgstatic void
576706f2543SmrgSNotifyEvent (xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to)
577706f2543Smrg{
578706f2543Smrg  to->type = from->type;
579706f2543Smrg  to->kind = from->kind;
580706f2543Smrg  cpswaps (from->sequenceNumber, to->sequenceNumber);
581706f2543Smrg  cpswapl (from->window, to->window);
582706f2543Smrg  cpswapl (from->time, to->time);
583706f2543Smrg  cpswapl (from->arg, to->arg);
584706f2543Smrg}
585706f2543Smrg
586706f2543Smrgstatic int
587706f2543SmrgSProcWindowsWMQueryVersion (ClientPtr client)
588706f2543Smrg{
589706f2543Smrg  int n;
590706f2543Smrg  REQUEST(xWindowsWMQueryVersionReq);
591706f2543Smrg  swaps(&stuff->length, n);
592706f2543Smrg  return ProcWindowsWMQueryVersion(client);
593706f2543Smrg}
594706f2543Smrg
595706f2543Smrgstatic int
596706f2543SmrgSProcWindowsWMDispatch (ClientPtr client)
597706f2543Smrg{
598706f2543Smrg  REQUEST(xReq);
599706f2543Smrg
600706f2543Smrg  /* It is bound to be non-local when there is byte swapping */
601706f2543Smrg  if (!LocalClient(client))
602706f2543Smrg    return WMErrorBase + WindowsWMClientNotLocal;
603706f2543Smrg
604706f2543Smrg  /* only local clients are allowed WM access */
605706f2543Smrg  switch (stuff->data)
606706f2543Smrg    {
607706f2543Smrg    case X_WindowsWMQueryVersion:
608706f2543Smrg      return SProcWindowsWMQueryVersion(client);
609706f2543Smrg    default:
610706f2543Smrg      return BadRequest;
611706f2543Smrg    }
612706f2543Smrg}
613706f2543Smrg
614706f2543Smrgvoid
615706f2543SmrgwinWindowsWMExtensionInit (void)
616706f2543Smrg{
617706f2543Smrg  ExtensionEntry* extEntry;
618706f2543Smrg
619706f2543Smrg  ClientType = CreateNewResourceType(WMFreeClient, "WMClient");
620706f2543Smrg  eventResourceType = CreateNewResourceType(WMFreeEvents, "WMEvent");
621706f2543Smrg  eventResource = FakeClientID(0);
622706f2543Smrg
623706f2543Smrg  if (ClientType && eventResourceType &&
624706f2543Smrg      (extEntry = AddExtension(WINDOWSWMNAME,
625706f2543Smrg			       WindowsWMNumberEvents,
626706f2543Smrg			       WindowsWMNumberErrors,
627706f2543Smrg			       ProcWindowsWMDispatch,
628706f2543Smrg			       SProcWindowsWMDispatch,
629706f2543Smrg			       NULL,
630706f2543Smrg			       StandardMinorOpcode)))
631706f2543Smrg    {
632706f2543Smrg      size_t i;
633706f2543Smrg      WMReqCode = (unsigned char)extEntry->base;
634706f2543Smrg      WMErrorBase = extEntry->errorBase;
635706f2543Smrg      WMEventBase = extEntry->eventBase;
636706f2543Smrg      for (i=0; i < WindowsWMNumberEvents; i++)
637706f2543Smrg        EventSwapVector[WMEventBase + i] = (EventSwapPtr) SNotifyEvent;
638706f2543Smrg    }
639706f2543Smrg}
640