librewolf: update to 134.0-1
[oi-userland.git] / components / x11 / xorg-server / srcs / IA / interactive.c
blobe5c3b072c15ba17dd508542593b941675423ae7a
1 /*
2 * Copyright (c) 1993, 2015, Oracle and/or its affiliates. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 /************************************************************
26 Basic boilerplate extension.
28 This file also contains the code to make the priocntl on behalf
29 of the clients.
31 Note that ChangePriority also sets the last client with focus
32 to the normal priority.
34 If there are knobs to be added to the system, for say the nice
35 values for the IA class, they would be added here.
36 ********************************************************/
38 /* THIS IS NOT AN X CONSORTIUM STANDARD */
40 #ifdef HAVE_DIX_CONFIG_H
41 #include <dix-config.h>
42 #endif
44 #include <errno.h>
45 #include <sys/types.h>
46 #include <stdio.h>
48 #include <sys/priocntl.h>
49 #include <sys/iapriocntl.h>
50 #include <unistd.h>
53 #include <X11/X.h>
54 #include <X11/Xproto.h>
55 #include "os.h"
56 #include "dixstruct.h"
57 #include "windowstr.h"
58 #include "inputstr.h"
59 #include "extnsionst.h"
60 #define _XIA_SERVER_
61 #include <X11/extensions/interactive.h>
62 #include <X11/Xfuncproto.h>
63 #include "dix.h"
64 #include "client.h"
66 #include "interactive_srv.h"
68 static int ProcIADispatch(ClientPtr client);
69 static int SProcIADispatch(ClientPtr client);
70 static int ProcIASetProcessInfo(ClientPtr client);
71 static int SProcIASetProcessInfo(ClientPtr client);
72 static int ProcIAGetProcessInfo(ClientPtr client);
73 static int SProcIAGetProcessInfo(ClientPtr client);
74 static int ProcIAQueryVersion(ClientPtr client);
75 static int SProcIAQueryVersion(ClientPtr client);
76 static void IACloseDown(ExtensionEntry *ext);
77 static void IAClientStateChange(CallbackListPtr *pcbl, void *nulldata,
78 void *calldata);
80 static int InitializeClass(void);
81 static void SetIAPrivate(int *);
82 static void ChangeInteractive(ClientPtr);
83 static int SetPriority(const ClientProcessPtr, int);
84 static void ChangePriority(register ClientPtr client);
86 static int SetClientPrivate(ClientPtr client, ConnectionPidPtr stuff,
87 int length);
88 static void FreeProcessList(IAClientPrivatePtr priv);
89 /* static int LocalConnection(OsCommPtr); */
90 static int PidSetEqual(ClientProcessPtr, ClientProcessPtr);
92 static int IAWrapProcVectors(void);
93 static int IAUnwrapProcVectors(void);
95 static CARD32 IAInitTimerCall(OsTimerPtr timer, CARD32 now, void *arg);
97 static iaclass_t IAClass;
98 static id_t TScid;
99 static ClientProcessPtr LastPids = NULL;
100 static int ia_nice = IA_BOOST;
101 static Bool InteractiveOS = TRUE;
102 static unsigned long IAExtensionGeneration = 0;
103 static OsTimerPtr IAInitTimer = NULL;
104 static int (* IASavedProcVector[256]) (ClientPtr client);
106 static DevPrivateKeyRec IAPrivKeyRec;
107 #define IAPrivKey (&IAPrivKeyRec)
109 #define GetIAClient(pClient) \
110 ((IAClientPrivatePtr) dixLookupPrivate(&(pClient)->devPrivates, IAPrivKey))
112 static inline ClientProcessPtr
113 GetConnectionPids(ClientPtr pClient)
115 IAClientPrivatePtr priv = GetIAClient(pClient);
117 if (priv == NULL) {
118 return NULL;
119 } else {
120 return priv->process;
124 /* Set via xorg.conf option in loadable module */
125 int IADebugLevel = 0;
127 #define IA_DEBUG(level, func) \
128 if (IADebugLevel >= level) { func; } else (void)(0)
130 #define IA_DEBUG_BASIC 1
131 #define IA_DEBUG_PRIOCNTL 3
133 void
134 IAExtensionInit(void)
136 ConnectionPidRec myPid = P_MYID;
137 ClientProcessRec myProc = { 1, &myPid, FALSE };
139 IA_DEBUG(IA_DEBUG_BASIC,
140 LogMessage(X_INFO, "SolarisIA: Initializing (generation %ld)\n",
141 IAExtensionGeneration));
143 if (IAExtensionGeneration == serverGeneration)
144 return;
146 InteractiveOS = FALSE;
148 if (InitializeClass() != Success)
149 return;
151 if (SetPriority(&myProc, SET_INTERACTIVE) != Success)
152 return;
154 if (SetPriority(&myProc, SET_PRIORITY) != Success)
155 return;
157 if (!dixRegisterPrivateKey(&IAPrivKeyRec, PRIVATE_CLIENT, 0))
158 return;
160 if (!AddCallback(&ClientStateCallback, IAClientStateChange, NULL))
161 return;
163 if (IAWrapProcVectors() != 0)
164 return;
166 if (!AddExtension(IANAME, IANumberEvents, IANumberErrors,
167 ProcIADispatch, SProcIADispatch,
168 IACloseDown, StandardMinorOpcode))
169 return;
171 /* InitExtensions is called before InitClientPrivates(serverClient)
172 so we set this timer to callback as soon as we hit WaitForSomething
173 to initialize the serverClient */
174 IAInitTimer = TimerSet(IAInitTimer, 0, 1, IAInitTimerCall, NULL);
176 InteractiveOS = TRUE;
177 IAExtensionGeneration = serverGeneration;
179 IA_DEBUG(IA_DEBUG_BASIC,
180 LogMessage(X_INFO,
181 "SolarisIA: Finished initializing (generation %ld)\n",
182 IAExtensionGeneration));
185 /* Allocate client private structure for this client */
186 static int
187 IAInitClientPrivate(ClientPtr pClient)
189 IAClientPrivatePtr priv;
191 priv = GetIAClient(pClient);
192 if (priv != NULL) {
193 return Success;
196 priv = malloc(sizeof(IAClientPrivateRec));
197 if (priv == NULL) {
198 return BadAlloc;
201 priv->process = NULL;
202 priv->wmgr = FALSE;
204 dixSetPrivate(&(pClient)->devPrivates, IAPrivKey, priv);
206 return Success;
209 /* Called when we first hit WaitForSomething to initialize serverClient */
210 static CARD32
211 IAInitTimerCall(OsTimerPtr timer, CARD32 now, void *arg)
213 ConnectionPidRec serverPid;
215 if (InteractiveOS != TRUE)
216 return 0;
218 IAInitClientPrivate(serverClient);
220 serverPid = getpid();
221 SetClientPrivate(serverClient, &serverPid, 1);
223 ChangePriority(serverClient);
224 return 0;
227 /* Called when new client connects or existing client disconnects */
228 static void
229 IAClientStateChange(CallbackListPtr *pcbl, void *nulldata, void *calldata)
231 NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
232 ClientPtr pClient = pci->client;
233 ClientProcessPtr CurrentPids;
234 IAClientPrivatePtr priv;
235 LocalClientCredRec *lcc;
237 switch (pClient->clientState) {
238 case ClientStateGone:
239 case ClientStateRetained:
240 priv = GetIAClient(pClient);
241 if (priv == NULL) {
242 return;
244 CurrentPids = priv->process;
246 if (priv->wmgr) {
247 IA_DEBUG(IA_DEBUG_BASIC,
248 LogMessage(X_INFO,
249 "SolarisIA: WindowManager closed (pid %d)\n",
250 (CurrentPids && CurrentPids->pids) ?
251 CurrentPids->pids[0] : -1));
254 if (CurrentPids && CurrentPids->boosted) {
255 SetPriority(CurrentPids, UNSET_PRIORITY);
258 if (CurrentPids && LastPids && PidSetEqual(CurrentPids, LastPids)) {
259 LastPids = NULL;
262 FreeProcessList(priv);
263 free(priv);
264 dixSetPrivate(&(pClient)->devPrivates, IAPrivKey, NULL);
265 break;
267 case ClientStateInitial:
268 IAInitClientPrivate(pClient);
270 ConnectionPidRec clientPid = GetClientPid(pClient);
271 if (clientPid != -1) {
272 SetClientPrivate(pClient, &clientPid, 1);
273 ChangeInteractive(pClient);
276 break;
278 default:
279 break;
284 static int
285 ProcIADispatch (ClientPtr client)
287 REQUEST(xReq);
288 switch (stuff->data)
290 case X_IAQueryVersion:
291 return ProcIAQueryVersion(client);
292 case X_IASetProcessInfo:
293 return ProcIASetProcessInfo(client);
294 case X_IAGetProcessInfo:
295 return ProcIAGetProcessInfo(client);
296 default:
297 return BadRequest;
301 static int
302 ProcIAQueryVersion(ClientPtr client)
304 REQUEST(xIAQueryVersionReq);
305 xIAQueryVersionReply rep;
307 REQUEST_SIZE_MATCH(xIAQueryVersionReq);
308 rep.type = X_Reply;
309 rep.length = 0;
310 rep.sequenceNumber = client->sequence;
311 rep.majorVersion = IA_MAJOR_VERSION;
312 rep.minorVersion = IA_MINOR_VERSION;
313 WriteToClient(client, sizeof(xIAQueryVersionReply), (char *)&rep);
314 return (client->noClientException);
317 static int
318 ProcIASetProcessInfo(ClientPtr client)
321 REQUEST(xIASetProcessInfoReq);
322 register int length;
323 static uid_t ServerUid = (uid_t)-1;
325 REQUEST_AT_LEAST_SIZE(xIASetProcessInfoReq);
327 if (ServerUid == (uid_t)-1)
328 ServerUid=getuid();
330 if ((stuff->flags & INTERACTIVE_INFO) &&
331 (stuff->uid==ServerUid || ServerUid==0 || stuff->uid==0) &&
332 client->local) {
333 length = stuff->length - (sizeof(xIASetProcessInfoReq)>>2);
334 SetClientPrivate(client, (ConnectionPidPtr)&stuff[1], length);
335 ChangeInteractive(client);
338 if ((stuff->flags & INTERACTIVE_SETTING) &&
339 (stuff->uid==ServerUid || ServerUid==0) &&
340 client->local) {
341 SetIAPrivate((int *)&stuff[1]);
344 return (client->noClientException);
347 static int
348 ProcIAGetProcessInfo(ClientPtr client)
350 IAClientPrivatePtr priv;
351 ClientProcessPtr CurrentPids;
352 REQUEST(xIAGetProcessInfoReq);
353 xIAGetProcessInfoReply rep;
354 register int length = 0;
355 int i;
356 int32_t *write_back = NULL;
358 REQUEST_SIZE_MATCH(xIAGetProcessInfoReq);
359 rep.type = X_Reply;
360 rep.length = 0;
361 rep.sequenceNumber = client->sequence;
363 if (stuff->flags & INTERACTIVE_INFO) {
364 priv = GetIAClient(client);
365 if ( (priv == NULL) || (priv->process == NULL) ) {
366 rep.count = 0;
367 } else {
368 CurrentPids = priv->process;
369 rep.count = CurrentPids->count;
370 length = rep.count << 2;
371 rep.length = rep.count;
372 write_back = malloc((size_t) rep.count * sizeof(int32_t));
373 if (write_back == NULL)
374 return ~Success;
375 else {
376 int32_t *tmp = write_back;
378 for (i = 0; i < CurrentPids->count; ++i)
379 *tmp++ = *CurrentPids->pids++;
383 if (stuff->flags & INTERACTIVE_SETTING) {
384 rep.count=1;
385 length=rep.count << 2;
386 rep.length = rep.count;
388 write_back = malloc(sizeof(int32_t));
389 if (write_back == NULL)
390 return ~Success;
392 *write_back = (int32_t) ia_nice;
395 WriteToClient(client, sizeof(xIAGetProcessInfoReply), (char *)&rep);
397 if (rep.length > 0) {
398 (void) WriteToClient(client, (int) sizeof(int32_t) * rep.count,
399 (char *) write_back);
400 free(write_back);
403 return (client->noClientException);
406 static void
407 IACloseDown(ExtensionEntry *ext)
409 InteractiveOS = FALSE;
411 IAUnwrapProcVectors();
413 DeleteCallback(&ClientStateCallback, IAClientStateChange, NULL);
417 The SProc* functions are here for completeness. They should never get
418 called. But since they do the server has to eat the request and
419 return thanks for sharing.
422 /*ARGSUSED*/
423 static int
424 SProcIADispatch (ClientPtr client)
426 REQUEST(xReq);
427 switch (stuff->data)
429 case X_IAQueryVersion:
430 return SProcIAQueryVersion(client);
431 case X_IASetProcessInfo:
432 return SProcIASetProcessInfo(client);
433 case X_IAGetProcessInfo:
434 return SProcIAGetProcessInfo(client);
435 default:
436 return BadRequest;
440 /*ARGSUSED*/
441 static int
442 SProcIAQueryVersion(ClientPtr client)
444 REQUEST_SIZE_MATCH(xIAQueryVersionReq);
445 return (client->noClientException);
448 /*ARGSUSED*/
449 static int
450 SProcIASetProcessInfo(ClientPtr client)
452 REQUEST(xIASetProcessInfoReq);
453 REQUEST_AT_LEAST_SIZE(xIASetProcessInfoReq);
455 return (client->noClientException);
458 /*ARGSUSED*/
459 static int
460 SProcIAGetProcessInfo(ClientPtr client)
462 REQUEST(xIAGetProcessInfoReq);
463 REQUEST_SIZE_MATCH(xIAGetProcessInfoReq);
465 return (client->noClientException);
468 static void
469 ChangeInteractive(ClientPtr client)
471 ClientProcessPtr CurrentPids = GetConnectionPids(client);
473 if (InteractiveOS==FALSE)
474 return;
476 if (!CurrentPids || !CurrentPids->pids)
477 return;
479 SetPriority(CurrentPids, SET_INTERACTIVE);
483 * Loop through pids associated with client. Magically make last focus
484 * group go non-interactive -IA_BOOST.
486 static void
487 ChangePriority(register ClientPtr client)
489 IAClientPrivatePtr priv = GetIAClient(client);
490 ClientProcessPtr CurrentPids = (priv == NULL ? NULL : priv->process);
492 if (CurrentPids && LastPids && PidSetEqual(CurrentPids, LastPids)) {
493 /* Shortcut. Focus changed between two windows with same pid */
494 return;
497 /* Remove priority boost for last focus group */
498 if (LastPids) {
499 SetPriority(LastPids, UNSET_PRIORITY);
500 LastPids = NULL;
503 /* If no pid info for current client, then we're done here.
504 * This can happen if we have a remote client with focus or if the client
505 * is statically linked or if it is using a down rev version of libX11.
507 if ( (CurrentPids == NULL) || (CurrentPids->count == 0) ||
508 (CurrentPids->pids == NULL) ) {
509 return;
512 /* Set the priority boost if it isn't already active */
513 if (!CurrentPids->boosted) {
514 SetPriority(CurrentPids, SET_PRIORITY);
517 /* Make sure server or wmgr isn't unset by testing for them, so
518 * that LastPids is never set to point to the server or wmgr pid.
520 if ((client->index != serverClient->index) && (priv->wmgr != TRUE)) {
521 LastPids = CurrentPids;
525 static int
526 InitializeClass(void)
528 pcinfo_t pcinfo;
530 /* Get TS class information */
531 strcpy (pcinfo.pc_clname, "TS");
532 priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo);
533 TScid = pcinfo.pc_cid;
535 /* Get IA class information */
536 strcpy (pcinfo.pc_clname, "IA");
537 if ((priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo)) == -1)
538 return ~Success;
540 IAClass.pc_cid = pcinfo.pc_cid;
541 ((iaparms_t*)IAClass.pc_clparms)->ia_uprilim = IA_NOCHANGE;
542 ((iaparms_t*)IAClass.pc_clparms)->ia_upri = IA_NOCHANGE;
544 return Success;
547 static int
548 SetPriority(const ClientProcessPtr cpp, int cmd)
550 pcparms_t pcinfo;
551 long ret = Success;
552 gid_t usr_egid = getegid();
553 int i;
555 if ( (cpp == NULL) || (cpp->pids == NULL) || (cpp->count == 0) ) {
556 return Success;
559 if ( setegid(0) < 0 ) {
560 ErrorF("Error in setting egid to 0: %s\n", strerror(errno));
563 for (i = 0; i < cpp->count ; i++) {
564 id_t pid = cpp->pids[i];
566 pcinfo.pc_cid = PC_CLNULL;
567 if ((priocntl(P_PID, pid, PC_GETPARMS, (caddr_t)&pcinfo)) < 0) {
568 if ( setegid(usr_egid) < 0 ) {
569 ErrorF("Error in resetting egid: %s\n", strerror(errno));
571 return ~Success; /* Scary time; punt */
574 /* If process is in TS or IA class we can safely set parameters */
575 if ((pcinfo.pc_cid == IAClass.pc_cid) || (pcinfo.pc_cid == TScid)) {
577 switch (cmd) {
578 case UNSET_PRIORITY:
579 ((iaparms_t*)IAClass.pc_clparms)->ia_mode=IA_INTERACTIVE_OFF;
580 break;
581 case SET_PRIORITY:
582 ((iaparms_t*)IAClass.pc_clparms)->ia_mode=IA_SET_INTERACTIVE;
583 break;
584 case SET_INTERACTIVE:
585 /* If this returns true, the process is already in the */
586 /* IA class, so we don't need to update it. */
587 if ( pcinfo.pc_cid == IAClass.pc_cid)
588 continue;
590 ((iaparms_t*)IAClass.pc_clparms)->ia_mode=IA_INTERACTIVE_OFF;
591 break;
594 if (priocntl(P_PID, pid, PC_SETPARMS, (caddr_t)&IAClass) == -1)
596 ret = ~Success;
599 IA_DEBUG(IA_DEBUG_PRIOCNTL,
601 const char *cmdmsg;
603 switch (cmd) {
604 case UNSET_PRIORITY: cmdmsg = "UNSET_PRIORITY"; break;
605 case SET_PRIORITY: cmdmsg = "SET_PRIORITY"; break;
606 case SET_INTERACTIVE: cmdmsg = "SET_INTERACTIVE"; break;
607 default: cmdmsg = "UNKNOWN_CMD!!!"; break;
609 LogMessage(X_INFO, "SolarisIA: SetPriority(%d, %s): %s\n",
610 pid, cmdmsg,
611 (ret == Success) ? "succeeeded" : "failed");
616 if (setegid(usr_egid) < 0)
617 ErrorF("Error in resetting egid: %s\n", strerror(errno));
619 if (ret == Success) {
620 if (cmd == SET_PRIORITY) {
621 cpp->boosted = TRUE;
622 } else if (cmd == UNSET_PRIORITY) {
623 cpp->boosted = FALSE;
627 return ret;
630 static void
631 SetIAPrivate(int *value)
633 ia_nice = *value;
636 /*****************************************************************************
637 * Various utility functions - in Xsun these lived in Xserver/os/process.c
640 /* In Xsun we used the osPrivate in OsCommPtr, so this was SetOsPrivate. */
641 static int
642 SetClientPrivate(ClientPtr client, ConnectionPidPtr stuff, int length)
644 ClientProcessPtr cpp;
645 IAClientPrivatePtr priv;
647 priv = GetIAClient(client);
648 if (priv == NULL) {
649 IAInitClientPrivate(client);
650 } else {
651 FreeProcessList(priv);
654 cpp = malloc(sizeof(ClientProcessRec));
656 if (cpp == NULL)
657 return BadAlloc;
659 cpp->pids = malloc(sizeof(ConnectionPidRec)*length);
661 if (cpp->pids == NULL) {
662 free(cpp);
663 return BadAlloc;
666 cpp->count = length;
667 memcpy(cpp->pids, stuff, sizeof(ConnectionPidRec)*length);
668 cpp->boosted = FALSE;
670 priv->process = cpp;
671 return Success;
674 static void
675 FreeProcessList(IAClientPrivatePtr priv)
677 ClientProcessPtr cpp = priv->process;
679 if (cpp == NULL)
680 return;
681 priv->process = NULL;
683 if (LastPids == cpp)
684 LastPids = NULL;
686 if (cpp->pids != NULL)
687 free(cpp->pids);
689 free(cpp);
693 Check to see that all in current (a) are in last (b).
694 And that a and b have the same number of members in the set.
696 static int
697 PidSetEqual(ClientProcessPtr a, ClientProcessPtr b)
699 int aN, bN;
700 int count = a->count;
701 int retval = 1;
703 if (a->count != b->count) {
704 return 0; /* definately NOT the same set */
707 for (aN = 0; aN < count; aN++) {
708 retval = 0;
709 for (bN = 0; bN < count ; bN++) {
710 if (a->pids[aN] == b->pids[bN]) {
711 retval = 1;
712 break;
715 if (retval == 0)
716 return retval;
719 return retval;
723 /*****************************************************************************
724 * Wrappers for normal procs - in Xsun we modified the original procs directly
725 * in dix, but here we wrap them for a small performance loss but a large
726 * increase in maintainability and ease of porting to new releases.
729 static int
730 IAProcSetInputFocus(ClientPtr client)
732 int res;
733 Window focusID;
734 WindowPtr focusWin;
735 REQUEST(xSetInputFocusReq);
737 res = (*IASavedProcVector[X_SetInputFocus])(client);
738 if ((res != Success) || (InteractiveOS != TRUE))
739 return res;
741 focusID = stuff->focus;
743 switch (focusID) {
744 case None:
745 focusWin = NullWindow;
746 break;
747 case PointerRoot:
748 focusWin = PointerRootWin;
749 break;
750 default:
751 res = dixLookupWindow(&focusWin, focusID, client, DixReadAccess);
752 if (res != Success)
753 return res;
756 if ((focusWin != NullWindow) && (focusWin != PointerRootWin)) {
757 register ClientPtr requestee = wClient(focusWin);
758 ChangePriority(requestee);
761 return res;
764 static int
765 IAProcSendEvent(ClientPtr client)
767 int res;
768 REQUEST(xSendEventReq);
770 res = (*IASavedProcVector[X_SendEvent])(client);
771 if ((res != Success) || (InteractiveOS != TRUE))
772 return res;
774 if ((InteractiveOS==TRUE) &&
775 (GetIAClient(client)->wmgr == TRUE) &&
776 (stuff->event.u.u.type == ClientMessage) &&
777 (stuff->event.u.u.detail == 32) ) {
779 register ClientPtr requestee;
780 WindowPtr pWin = NULL;
781 DeviceIntPtr pPtr = PickPointer(client);
783 if (stuff->destination == PointerWindow)
784 pWin = GetSpriteWindow(pPtr);
785 else if (stuff->destination == InputFocus)
787 WindowPtr inputFocus = inputInfo.keyboard->focus->win;
789 if (inputFocus == NoneWin)
790 return Success;
792 /* If the input focus is PointerRootWin, send the event to where
793 the pointer is if possible, then perhaps propogate up to root. */
794 if (inputFocus == PointerRootWin)
795 inputFocus = GetCurrentRootWindow(pPtr);
797 if (IsParent(inputFocus, GetSpriteWindow(pPtr)))
798 pWin = GetSpriteWindow(pPtr);
799 else
800 pWin = inputFocus;
802 else
804 res = dixLookupWindow(&pWin, stuff->destination, client,
805 DixReadAccess);
806 if (res != Success)
807 return res;
811 if (!pWin)
812 return BadWindow;
814 requestee = wClient(pWin);
815 ChangePriority(requestee);
817 return res;
820 static Bool
821 IAProcChangeWindowAttributes(ClientPtr client)
823 REQUEST(xChangeWindowAttributesReq);
825 if ((InteractiveOS==TRUE) && (stuff->valueMask & CWEventMask) &&
826 (GetIAClient(client)->wmgr == FALSE) ) {
828 register XID *pVlist = (XID *) &stuff[1];
829 register Mask tmask = stuff->valueMask;
830 register Mask index2 = 0;
832 while (tmask) {
833 index2 = (Mask) lowbit (tmask);
834 tmask &= ~index2;
835 if (index2 == CWEventMask) {
836 break;
838 pVlist++;
841 if ((index2 == CWEventMask) && (*pVlist & SubstructureRedirectMask)) {
842 IA_DEBUG(IA_DEBUG_BASIC,
843 ClientProcessPtr CurrentPids=GetConnectionPids(client);
845 LogMessage(X_INFO,
846 "SolarisIA: WindowManager detected (pid %d)\n",
847 (CurrentPids && CurrentPids->pids) ?
848 CurrentPids->pids[0] : -1));
850 GetIAClient(client)->wmgr = TRUE;
851 ChangePriority(client);
852 LastPids = NULL;
856 return (*IASavedProcVector[X_ChangeWindowAttributes])(client);
860 static int
861 IAWrapProcVectors(void)
863 IASavedProcVector[X_SetInputFocus] = ProcVector[X_SetInputFocus];
864 ProcVector[X_SetInputFocus] = IAProcSetInputFocus;
866 IASavedProcVector[X_SendEvent] = ProcVector[X_SendEvent];
867 ProcVector[X_SendEvent] = IAProcSendEvent;
869 IASavedProcVector[X_ChangeWindowAttributes]
870 = ProcVector[X_ChangeWindowAttributes];
871 ProcVector[X_ChangeWindowAttributes] = IAProcChangeWindowAttributes;
873 return 0;
876 static int
877 IAUnwrapProcVectors(void)
879 ProcVector[X_SetInputFocus] = IASavedProcVector[X_SetInputFocus];
880 ProcVector[X_SendEvent] = IASavedProcVector[X_SendEvent];
881 ProcVector[X_ChangeWindowAttributes] = IASavedProcVector[X_ChangeWindowAttributes];
883 return 0;