1 /* WindowsWM extension is based on AppleWM extension */
2 /**************************************************************************
4 Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
5 Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sub license, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial portions
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
29 #ifdef HAVE_XWIN_CONFIG_H
30 #include <xwin-config.h>
35 #include "dixstruct.h"
36 #include "extnsionst.h"
37 #include "colormapst.h"
38 #include "cursorstr.h"
39 #include "scrnintstr.h"
42 #define _WINDOWSWM_SERVER_
43 #include <X11/extensions/windowswmstr.h>
44 #include "protocol-versions.h"
46 static int WMErrorBase
;
47 static unsigned char WMReqCode
= 0;
48 static int WMEventBase
= 0;
50 static RESTYPE ClientType
, eventResourceType
; /* resource types for event masks */
51 static XID eventResource
;
53 /* Currently selected events */
54 static unsigned int eventMask
= 0;
56 static int WMFreeClient(pointer data
, XID id
);
57 static int WMFreeEvents(pointer data
, XID id
);
58 static void SNotifyEvent(xWindowsWMNotifyEvent
* from
,
59 xWindowsWMNotifyEvent
* to
);
61 typedef struct _WMEvent
*WMEventPtr
;
62 typedef struct _WMEvent
{
70 ProcWindowsWMQueryVersion(ClientPtr client
)
72 xWindowsWMQueryVersionReply rep
;
74 REQUEST_SIZE_MATCH(xWindowsWMQueryVersionReq
);
77 rep
.sequenceNumber
= client
->sequence
;
78 rep
.majorVersion
= SERVER_WINDOWSWM_MAJOR_VERSION
;
79 rep
.minorVersion
= SERVER_WINDOWSWM_MINOR_VERSION
;
80 rep
.patchVersion
= SERVER_WINDOWSWM_PATCH_VERSION
;
81 if (client
->swapped
) {
82 swaps(&rep
.sequenceNumber
);
85 WriteToClient(client
, sizeof(xWindowsWMQueryVersionReply
), &rep
);
92 updateEventMask(WMEventPtr
* pHead
)
97 for (pCur
= *pHead
; pCur
!= NULL
; pCur
= pCur
->next
)
98 eventMask
|= pCur
->mask
;
101 /*ARGSUSED*/ static int
102 WMFreeClient(pointer data
, XID id
)
105 WMEventPtr
*pHead
, pCur
, pPrev
;
107 pEvent
= (WMEventPtr
) data
;
108 dixLookupResourceByType((pointer
) &pHead
, eventResource
, eventResourceType
,
109 NullClient
, DixUnknownAccess
);
112 for (pCur
= *pHead
; pCur
&& pCur
!= pEvent
; pCur
= pCur
->next
)
116 pPrev
->next
= pEvent
->next
;
118 *pHead
= pEvent
->next
;
120 updateEventMask(pHead
);
122 free((pointer
) pEvent
);
126 /*ARGSUSED*/ static int
127 WMFreeEvents(pointer data
, XID id
)
129 WMEventPtr
*pHead
, pCur
, pNext
;
131 pHead
= (WMEventPtr
*) data
;
132 for (pCur
= *pHead
; pCur
; pCur
= pNext
) {
134 FreeResource(pCur
->clientResource
, ClientType
);
135 free((pointer
) pCur
);
137 free((pointer
) pHead
);
143 ProcWindowsWMSelectInput(ClientPtr client
)
145 REQUEST(xWindowsWMSelectInputReq
);
146 WMEventPtr pEvent
, pNewEvent
, *pHead
;
149 REQUEST_SIZE_MATCH(xWindowsWMSelectInputReq
);
150 dixLookupResourceByType((pointer
) &pHead
, eventResource
, eventResourceType
,
151 client
, DixWriteAccess
);
152 if (stuff
->mask
!= 0) {
154 /* check for existing entry. */
155 for (pEvent
= *pHead
; pEvent
; pEvent
= pEvent
->next
) {
156 if (pEvent
->client
== client
) {
157 pEvent
->mask
= stuff
->mask
;
158 updateEventMask(pHead
);
164 /* build the entry */
165 pNewEvent
= (WMEventPtr
) malloc(sizeof(WMEventRec
));
169 pNewEvent
->client
= client
;
170 pNewEvent
->mask
= stuff
->mask
;
172 * add a resource that will be deleted when
173 * the client goes away
175 clientResource
= FakeClientID(client
->index
);
176 pNewEvent
->clientResource
= clientResource
;
177 if (!AddResource(clientResource
, ClientType
, (pointer
) pNewEvent
))
180 * create a resource to contain a pointer to the list
181 * of clients selecting input. This must be indirect as
182 * the list may be arbitrarily rearranged which cannot be
183 * done through the resource database.
186 pHead
= (WMEventPtr
*) malloc(sizeof(WMEventPtr
));
188 !AddResource(eventResource
, eventResourceType
, (pointer
) pHead
))
190 FreeResource(clientResource
, RT_NONE
);
195 pNewEvent
->next
= *pHead
;
197 updateEventMask(pHead
);
199 else if (stuff
->mask
== 0) {
200 /* delete the interest */
203 for (pEvent
= *pHead
; pEvent
; pEvent
= pEvent
->next
) {
204 if (pEvent
->client
== client
)
209 FreeResource(pEvent
->clientResource
, ClientType
);
211 pNewEvent
->next
= pEvent
->next
;
213 *pHead
= pEvent
->next
;
215 updateEventMask(pHead
);
220 client
->errorValue
= stuff
->mask
;
231 winWindowsWMSendEvent(int type
, unsigned int mask
, int which
, int arg
,
232 Window window
, int x
, int y
, int w
, int h
)
234 WMEventPtr
*pHead
, pEvent
;
236 xWindowsWMNotifyEvent se
;
238 #if CYGMULTIWINDOW_DEBUG
239 ErrorF("winWindowsWMSendEvent %d %d %d %d, %d %d - %d %d\n",
240 type
, mask
, which
, arg
, x
, y
, w
, h
);
242 dixLookupResourceByType((pointer
) &pHead
, eventResource
, eventResourceType
,
243 NullClient
, DixUnknownAccess
);
246 for (pEvent
= *pHead
; pEvent
; pEvent
= pEvent
->next
) {
247 client
= pEvent
->client
;
248 #if CYGMULTIWINDOW_DEBUG
249 ErrorF("winWindowsWMSendEvent - %p\n", client
);
251 if ((pEvent
->mask
& mask
) == 0) {
254 #if CYGMULTIWINDOW_DEBUG
255 ErrorF("winWindowsWMSendEvent - send\n");
257 se
.type
= type
+ WMEventBase
;
265 se
.time
= currentTime
.milliseconds
;
266 WriteEventsToClient(client
, 1, (xEvent
*) &se
);
270 /* general utility functions */
273 ProcWindowsWMDisableUpdate(ClientPtr client
)
275 REQUEST_SIZE_MATCH(xWindowsWMDisableUpdateReq
);
277 //winDisableUpdate();
283 ProcWindowsWMReenableUpdate(ClientPtr client
)
285 REQUEST_SIZE_MATCH(xWindowsWMReenableUpdateReq
);
292 /* window functions */
295 ProcWindowsWMSetFrontProcess(ClientPtr client
)
297 REQUEST_SIZE_MATCH(xWindowsWMSetFrontProcessReq
);
299 //QuartzMessageMainThread(kWindowsSetFrontProcess, NULL, 0);
304 /* frame functions */
307 ProcWindowsWMFrameGetRect(ClientPtr client
)
309 xWindowsWMFrameGetRectReply rep
;
312 REQUEST(xWindowsWMFrameGetRectReq
);
314 #if CYGMULTIWINDOW_DEBUG
315 ErrorF("ProcWindowsWMFrameGetRect %d %d\n",
316 (sizeof(xWindowsWMFrameGetRectReq
) >> 2), (int) client
->req_len
);
319 REQUEST_SIZE_MATCH(xWindowsWMFrameGetRectReq
);
322 rep
.sequenceNumber
= client
->sequence
;
324 if (stuff
->frame_rect
!= 0) {
325 ErrorF("ProcWindowsWMFrameGetRect - stuff->frame_rect != 0\n");
329 /* Store the origin, height, and width in a rectangle structure */
330 SetRect(&rcNew
, stuff
->ix
, stuff
->iy
,
331 stuff
->ix
+ stuff
->iw
, stuff
->iy
+ stuff
->ih
);
333 #if CYGMULTIWINDOW_DEBUG
334 ErrorF("ProcWindowsWMFrameGetRect - %d %d %d %d\n",
335 stuff
->ix
, stuff
->iy
, stuff
->ix
+ stuff
->iw
, stuff
->iy
+ stuff
->ih
);
339 * Calculate the required size of the Windows window rectangle,
340 * given the size of the Windows window client area.
342 AdjustWindowRectEx(&rcNew
, stuff
->frame_style
, FALSE
,
343 stuff
->frame_style_ex
);
346 rep
.w
= rcNew
.right
- rcNew
.left
;
347 rep
.h
= rcNew
.bottom
- rcNew
.top
;
348 #if CYGMULTIWINDOW_DEBUG
349 ErrorF("ProcWindowsWMFrameGetRect - %d %d %d %d\n",
350 rep
.x
, rep
.y
, rep
.w
, rep
.h
);
353 WriteToClient(client
, sizeof(xWindowsWMFrameGetRectReply
), &rep
);
358 ProcWindowsWMFrameDraw(ClientPtr client
)
360 REQUEST(xWindowsWMFrameDrawReq
);
362 win32RootlessWindowPtr pRLWinPriv
;
367 REQUEST_SIZE_MATCH(xWindowsWMFrameDrawReq
);
369 #if CYGMULTIWINDOW_DEBUG
370 ErrorF("ProcWindowsWMFrameDraw\n");
372 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixReadAccess
);
375 #if CYGMULTIWINDOW_DEBUG
376 ErrorF("ProcWindowsWMFrameDraw - Window found\n");
379 pRLWinPriv
= (win32RootlessWindowPtr
) RootlessFrameForWindow(pWin
, TRUE
);
383 #if CYGMULTIWINDOW_DEBUG
384 ErrorF("ProcWindowsWMFrameDraw - HWND %p 0x%08x 0x%08x\n",
385 pRLWinPriv
->hWnd
, (int) stuff
->frame_style
,
386 (int) stuff
->frame_style_ex
);
387 ErrorF("ProcWindowsWMFrameDraw - %d %d %d %d\n",
388 stuff
->ix
, stuff
->iy
, stuff
->iw
, stuff
->ih
);
391 /* Store the origin, height, and width in a rectangle structure */
392 SetRect(&rcNew
, stuff
->ix
, stuff
->iy
,
393 stuff
->ix
+ stuff
->iw
, stuff
->iy
+ stuff
->ih
);
396 * Calculate the required size of the Windows window rectangle,
397 * given the size of the Windows window client area.
399 AdjustWindowRectEx(&rcNew
, stuff
->frame_style
, FALSE
,
400 stuff
->frame_style_ex
);
402 /* Set the window extended style flags */
403 if (!SetWindowLongPtr(pRLWinPriv
->hWnd
, GWL_EXSTYLE
, stuff
->frame_style_ex
)) {
407 /* Set the window standard style flags */
408 if (!SetWindowLongPtr(pRLWinPriv
->hWnd
, GWL_STYLE
, stuff
->frame_style
)) {
412 /* Flush the window style */
413 if (!SetWindowPos(pRLWinPriv
->hWnd
, NULL
,
414 rcNew
.left
, rcNew
.top
,
415 rcNew
.right
- rcNew
.left
, rcNew
.bottom
- rcNew
.top
,
416 SWP_NOZORDER
| SWP_FRAMECHANGED
| SWP_NOACTIVATE
)) {
419 if (!IsWindowVisible(pRLWinPriv
->hWnd
))
422 nCmdShow
= SW_SHOWNA
;
424 ShowWindow(pRLWinPriv
->hWnd
, nCmdShow
);
426 if (wBoundingShape(pWin
) != NULL
) {
427 /* wBoundingShape is relative to *inner* origin of window.
428 Translate by borderWidth to get the outside-relative position. */
430 RegionNull(&newShape
);
431 RegionCopy(&newShape
, wBoundingShape(pWin
));
432 RegionTranslate(&newShape
, pWin
->borderWidth
, pWin
->borderWidth
);
433 winMWExtWMReshapeFrame(pRLWinPriv
, &newShape
);
434 RegionUninit(&newShape
);
436 #if CYGMULTIWINDOW_DEBUG
437 ErrorF("ProcWindowsWMFrameDraw - done\n");
444 ProcWindowsWMFrameSetTitle(ClientPtr client
)
446 unsigned int title_length
, title_max
;
449 REQUEST(xWindowsWMFrameSetTitleReq
);
451 win32RootlessWindowPtr pRLWinPriv
;
454 #if CYGMULTIWINDOW_DEBUG
455 ErrorF("ProcWindowsWMFrameSetTitle\n");
458 REQUEST_AT_LEAST_SIZE(xWindowsWMFrameSetTitleReq
);
460 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixReadAccess
);
463 #if CYGMULTIWINDOW_DEBUG
464 ErrorF("ProcWindowsWMFrameSetTitle - Window found\n");
467 title_length
= stuff
->title_length
;
468 title_max
= (stuff
->length
<< 2) - sizeof(xWindowsWMFrameSetTitleReq
);
470 if (title_max
< title_length
)
473 #if CYGMULTIWINDOW_DEBUG
474 ErrorF("ProcWindowsWMFrameSetTitle - length is valid\n");
477 title_bytes
= malloc(title_length
+ 1);
478 strncpy(title_bytes
, (char *) &stuff
[1], title_length
);
479 title_bytes
[title_length
] = '\0';
481 pRLWinPriv
= (win32RootlessWindowPtr
) RootlessFrameForWindow(pWin
, FALSE
);
483 if (pRLWinPriv
== 0) {
488 /* Flush the window style */
489 SetWindowText(pRLWinPriv
->hWnd
, title_bytes
);
493 #if CYGMULTIWINDOW_DEBUG
494 ErrorF("ProcWindowsWMFrameSetTitle - done\n");
503 ProcWindowsWMDispatch(ClientPtr client
)
507 switch (stuff
->data
) {
508 case X_WindowsWMQueryVersion
:
509 return ProcWindowsWMQueryVersion(client
);
513 return WMErrorBase
+ WindowsWMClientNotLocal
;
515 switch (stuff
->data
) {
516 case X_WindowsWMSelectInput
:
517 return ProcWindowsWMSelectInput(client
);
518 case X_WindowsWMDisableUpdate
:
519 return ProcWindowsWMDisableUpdate(client
);
520 case X_WindowsWMReenableUpdate
:
521 return ProcWindowsWMReenableUpdate(client
);
522 case X_WindowsWMSetFrontProcess
:
523 return ProcWindowsWMSetFrontProcess(client
);
524 case X_WindowsWMFrameGetRect
:
525 return ProcWindowsWMFrameGetRect(client
);
526 case X_WindowsWMFrameDraw
:
527 return ProcWindowsWMFrameDraw(client
);
528 case X_WindowsWMFrameSetTitle
:
529 return ProcWindowsWMFrameSetTitle(client
);
536 SNotifyEvent(xWindowsWMNotifyEvent
* from
, xWindowsWMNotifyEvent
* to
)
538 to
->type
= from
->type
;
539 to
->kind
= from
->kind
;
540 cpswaps(from
->sequenceNumber
, to
->sequenceNumber
);
541 cpswapl(from
->window
, to
->window
);
542 cpswapl(from
->time
, to
->time
);
543 cpswapl(from
->arg
, to
->arg
);
547 SProcWindowsWMQueryVersion(ClientPtr client
)
549 REQUEST(xWindowsWMQueryVersionReq
);
550 swaps(&stuff
->length
);
551 return ProcWindowsWMQueryVersion(client
);
555 SProcWindowsWMDispatch(ClientPtr client
)
559 /* It is bound to be non-local when there is byte swapping */
561 return WMErrorBase
+ WindowsWMClientNotLocal
;
563 /* only local clients are allowed WM access */
564 switch (stuff
->data
) {
565 case X_WindowsWMQueryVersion
:
566 return SProcWindowsWMQueryVersion(client
);
573 winWindowsWMExtensionInit(void)
575 ExtensionEntry
*extEntry
;
577 ClientType
= CreateNewResourceType(WMFreeClient
, "WMClient");
578 eventResourceType
= CreateNewResourceType(WMFreeEvents
, "WMEvent");
579 eventResource
= FakeClientID(0);
581 if (ClientType
&& eventResourceType
&&
582 (extEntry
= AddExtension(WINDOWSWMNAME
,
583 WindowsWMNumberEvents
,
584 WindowsWMNumberErrors
,
585 ProcWindowsWMDispatch
,
586 SProcWindowsWMDispatch
,
587 NULL
, StandardMinorOpcode
))) {
590 WMReqCode
= (unsigned char) extEntry
->base
;
591 WMErrorBase
= extEntry
->errorBase
;
592 WMEventBase
= extEntry
->eventBase
;
593 for (i
= 0; i
< WindowsWMNumberEvents
; i
++)
594 EventSwapVector
[WMEventBase
+ i
] = (EventSwapPtr
) SNotifyEvent
;