tsolprotocol.c revision 168
98N/A/* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
0N/A *
0N/A * Permission is hereby granted, free of charge, to any person obtaining a
0N/A * copy of this software and associated documentation files (the
0N/A * "Software"), to deal in the Software without restriction, including
0N/A * without limitation the rights to use, copy, modify, merge, publish,
0N/A * distribute, and/or sell copies of the Software, and to permit persons
0N/A * to whom the Software is furnished to do so, provided that the above
0N/A * copyright notice(s) and this permission notice appear in all copies of
0N/A * the Software and that both the above copyright notice(s) and this
0N/A * permission notice appear in supporting documentation.
0N/A *
0N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0N/A * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0N/A * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
0N/A * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
0N/A * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
0N/A * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
0N/A * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
0N/A * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
0N/A * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0N/A *
0N/A * Except as contained in this notice, the name of a copyright holder
0N/A * shall not be used in advertising or otherwise to promote the sale, use
0N/A * or other dealings in this Software without prior written authorization
0N/A * of the copyright holder.
0N/A */
0N/A
168N/A#pragma ident "@(#)tsolprotocol.c 1.19 07/06/08 SMI"
168N/A
168N/A#ifdef HAVE_DIX_CONFIG_H
168N/A#include <dix-config.h>
168N/A#endif
0N/A
0N/A#include <sys/param.h>
0N/A#include <fcntl.h>
0N/A#include <sys/types.h>
0N/A#include <sys/stat.h>
0N/A#include <unistd.h>
0N/A#include <ucred.h>
0N/A#include <pwd.h>
0N/A#include <strings.h>
0N/A#include <sys/wait.h>
0N/A#include <bsm/auditwrite.h>
0N/A#include <bsm/libbsm.h>
0N/A#include <bsm/audit_uevents.h>
0N/A#include "tsol.h"
0N/A
0N/A#include "inputstr.h"
0N/A
0N/A#define NEED_REPLIES
0N/A
0N/A#include "selection.h"
0N/A#include "osdep.h"
0N/A#include "tsolpolicy.h"
0N/A#include "swaprep.h"
0N/A#include "swapreq.h"
0N/A#include "servermd.h"
0N/A#ifdef PANORAMIX
0N/A#include "../Xext/panoramiXsrv.h"
0N/A#endif
0N/A#ifdef XCSECURITY
0N/A#define _SECURITY_SERVER
0N/A#include "security.h"
0N/A#endif
0N/A
0N/A/*
0N/A * The event # here match those in /usr/include/bsm/audit_uevents.h.
0N/A * Changes in one should go with corresponding changes in another.
0N/A */
0N/A
0N/A#define MAX_AUDIT_EVENTS 100
0N/A
0N/Aint audit_eventsid[100][2] = {
36N/A X_CreateWindow, AUE_CreateWindow,
36N/A X_ChangeWindowAttributes, AUE_ChangeWindowAttributes,
36N/A X_GetWindowAttributes, AUE_GetWindowAttributes,
36N/A X_DestroyWindow, AUE_DestroyWindow,
36N/A X_DestroySubwindows, AUE_DestroySubwindows,
36N/A X_ChangeSaveSet, AUE_ChangeSaveSet,
36N/A X_ReparentWindow, AUE_ReparentWindow,
36N/A X_MapWindow, AUE_MapWindow,
36N/A X_MapSubwindows, AUE_MapSubwindows,
36N/A X_UnmapWindow, AUE_UnmapWindow,
36N/A X_UnmapSubwindows, AUE_UnmapSubwindows,
36N/A X_ConfigureWindow, AUE_ConfigureWindow,
36N/A X_CirculateWindow, AUE_CirculateWindow,
36N/A X_GetGeometry, AUE_GetGeometry,
36N/A X_QueryTree, AUE_QueryTree,
36N/A X_InternAtom, AUE_InternAtom,
36N/A X_GetAtomName, AUE_GetAtomName,
36N/A X_ChangeProperty, AUE_ChangeProperty,
36N/A X_DeleteProperty, AUE_DeleteProperty,
36N/A X_GetProperty, AUE_GetProperty,
36N/A X_ListProperties, AUE_ListProperties,
36N/A X_SetSelectionOwner, AUE_SetSelectionOwner,
36N/A X_GetSelectionOwner, AUE_GetSelectionOwner,
36N/A X_ConvertSelection, AUE_ConvertSelection,
36N/A X_SendEvent, AUE_SendEvent,
36N/A X_GrabPointer, AUE_GrabPointer,
36N/A X_UngrabPointer, AUE_UngrabPointer,
36N/A X_GrabButton, AUE_GrabButton,
36N/A X_UngrabButton, AUE_UngrabButton,
36N/A X_ChangeActivePointerGrab, AUE_ChangeActivePointerGrab,
36N/A X_GrabKeyboard, AUE_GrabKeyboard,
36N/A X_UngrabKeyboard, AUE_UngrabKeyboard,
36N/A X_GrabKey, AUE_GrabKey,
36N/A X_UngrabKey, AUE_UngrabKey,
36N/A X_GrabServer, AUE_GrabServer,
36N/A X_UngrabServer, AUE_UngrabServer,
36N/A X_QueryPointer, AUE_QueryPointer,
36N/A X_GetMotionEvents, AUE_GetMotionEvents,
36N/A X_TranslateCoords, AUE_TranslateCoords,
36N/A X_WarpPointer, AUE_WarpPointer,
36N/A X_SetInputFocus, AUE_SetInputFocus,
36N/A X_GetInputFocus, AUE_GetInputFocus,
36N/A X_QueryKeymap, AUE_QueryKeymap,
36N/A X_SetFontPath, AUE_SetFontPath,
36N/A X_FreePixmap, AUE_FreePixmap,
36N/A X_ChangeGC, AUE_ChangeGC,
36N/A X_CopyGC, AUE_CopyGC,
36N/A X_SetDashes, AUE_SetDashes,
36N/A X_SetClipRectangles, AUE_SetClipRectangles,
36N/A X_FreeGC, AUE_FreeGC,
36N/A X_ClearArea, AUE_ClearArea,
36N/A X_CopyArea, AUE_CopyArea,
36N/A X_CopyPlane, AUE_CopyPlane,
36N/A X_PolyPoint, AUE_PolyPoint,
36N/A X_PolyLine, AUE_PolyLine,
36N/A X_PolySegment, AUE_PolySegment,
36N/A X_PolyRectangle, AUE_PolyRectangle,
36N/A X_PolyArc, AUE_PolyArc,
36N/A X_FillPoly, AUE_FillPolygon,
36N/A X_PolyFillRectangle, AUE_PolyFillRectangle,
36N/A X_PolyFillArc, AUE_PolyFillArc,
36N/A X_PutImage, AUE_PutImage,
36N/A X_GetImage, AUE_GetImage,
36N/A X_PolyText8, AUE_PolyText8,
36N/A X_PolyText16, AUE_PolyText16,
36N/A X_ImageText8, AUE_ImageText8,
36N/A X_ImageText16, AUE_ImageText16,
36N/A X_CreateColormap, AUE_CreateColormap,
36N/A X_FreeColormap, AUE_FreeColormap,
36N/A X_CopyColormapAndFree, AUE_CopyColormapAndFree,
36N/A X_InstallColormap, AUE_InstallColormap,
36N/A X_UninstallColormap, AUE_UninstallColormap,
36N/A X_ListInstalledColormaps, AUE_ListInstalledColormaps,
36N/A X_AllocColor, AUE_AllocColor,
36N/A X_AllocNamedColor, AUE_AllocNamedColor,
36N/A X_AllocColorCells, AUE_AllocColorCells,
36N/A X_AllocColorPlanes, AUE_AllocColorPlanes,
36N/A X_FreeColors, AUE_FreeColors,
36N/A X_StoreColors, AUE_StoreColors,
36N/A X_StoreNamedColor, AUE_StoreNamedColor,
36N/A X_QueryColors, AUE_QueryColors,
36N/A X_LookupColor, AUE_LookupColor,
36N/A X_CreateCursor, AUE_CreateCursor,
36N/A X_CreateGlyphCursor, AUE_CreateGlyphCursor,
36N/A X_FreeCursor, AUE_FreeCursor,
36N/A X_RecolorCursor, AUE_RecolorCursor,
36N/A X_ChangeKeyboardMapping, AUE_ChangeKeyboardMapping,
36N/A X_ChangeKeyboardControl, AUE_ChangeKeyboardControl,
36N/A X_Bell, AUE_Bell,
36N/A X_ChangePointerControl, AUE_ChangePointerControl,
36N/A X_SetScreenSaver, AUE_SetScreenSaver,
36N/A X_ChangeHosts, AUE_ChangeHosts,
36N/A X_SetAccessControl, AUE_SetAccessControl,
36N/A X_SetCloseDownMode, AUE_SetCloseDownMode,
36N/A X_KillClient, AUE_KillClient,
36N/A X_RotateProperties, AUE_RotateProperties,
36N/A X_ForceScreenSaver, AUE_ForceScreenSaver,
36N/A X_SetPointerMapping, AUE_SetPointerMapping,
36N/A X_SetModifierMapping, AUE_SetModifierMapping,
36N/A X_NoOperation, AUE_XExtensions
0N/A};
0N/Aextern void Swap32Write();
0N/Aextern int (*TsolSavedProcVector[PROCVECTORSIZE])(ClientPtr /*client*/);
0N/Aextern int (*TsolSavedSwappedProcVector[PROCVECTORSIZE])(ClientPtr /*client*/);
0N/A
0N/A
0N/AAtom MakeTSOLAtom(ClientPtr client, char *string, unsigned int len, Bool makeit);
0N/A
0N/A#define INITIAL_TSOL_NODELENGTH 1500
0N/A
73N/Aextern WindowPtr XYToWindow(int x, int y);
73N/Aextern WindowPtr AnyWindowOverlapsJustMe(WindowPtr pWin,
73N/A WindowPtr pHead, BoxPtr box);
73N/A
0N/Aextern Atom tsol_lastAtom;
0N/Aextern int tsol_nodelength;
0N/Aextern TsolNodePtr tsol_node;
0N/Aextern int NumCurrentSelections;
0N/Aextern Selection *CurrentSelections;
0N/Aextern WindowPtr tpwin;
73N/Aextern int tsolMultiLevel;
0N/A
0N/Astatic int tsol_sel_agnt = -1; /* index this to CurrentSelection to get seln */
0N/A
0N/A/*
0N/A * Get number of atoms defined in the system
0N/A */
0N/Astatic Atom
0N/AGetLastAtom()
0N/A{
0N/A Atom a = (Atom) 1; /* atoms start at 1 */
0N/A
0N/A while (ValidAtom(a)) {
0N/A a++;
0N/A }
0N/A
0N/A return (--a);
0N/A}
0N/A
0N/A/*
0N/A * Update Tsol info for atoms. This function gets
0N/A * called typically during initialization. But, it could also get
0N/A * called if some atoms are created internally by server.
0N/A */
0N/Avoid
0N/AUpdateTsolNode()
0N/A{
0N/A Atom lastAtom = GetLastAtom();
0N/A Atom ia;
0N/A
0N/A /* Update may not be needed */
0N/A if (lastAtom == None || lastAtom == tsol_lastAtom)
0N/A return;
0N/A
0N/A if (tsol_node == NULL) {
0N/A int newsize = (lastAtom > INITIAL_TSOL_NODELENGTH ? lastAtom : INITIAL_TSOL_NODELENGTH);
0N/A
0N/A /* Initialize */
0N/A tsol_node = (TsolNodePtr )xalloc((newsize + 1) * sizeof(TsolNodeRec));
0N/A tsol_nodelength = newsize;
0N/A
0N/A if (tsol_node != NULL) {
0N/A /* Atom id 0 is invalid */
0N/A tsol_lastAtom = 0;
0N/A tsol_node[0].flags = 0;
0N/A tsol_node[0].slcount = 0;
0N/A tsol_node[0].sl = NULL;
0N/A tsol_node[0].slsize = 0;
0N/A tsol_node[0].IsSpecial = 0;
0N/A }
0N/A }
0N/A
0N/A if (tsol_nodelength <= lastAtom) {
0N/A tsol_node = (TsolNodePtr )xrealloc(tsol_node, (lastAtom + 1) * sizeof(TsolNodeRec));
0N/A tsol_nodelength = lastAtom + 1;
0N/A }
0N/A
0N/A if (tsol_node == NULL) {
0N/A ErrorF("Cannot allocate memory for Tsol node\n");
0N/A return;
0N/A }
0N/A
0N/A /*
0N/A * Initialize the tsol node for each atom
0N/A */
0N/A for (ia = tsol_lastAtom + 1; ia <= lastAtom; ia++) {
0N/A char *atomname = NameForAtom(ia);
0N/A
0N/A tsol_node[ia].slcount = 0;
0N/A tsol_node[ia].sl = NULL;
0N/A tsol_node[ia].slsize= 0;
0N/A tsol_node[ia].flags = MatchTsolConfig(atomname, strlen(atomname));
0N/A tsol_node[ia].IsSpecial = SpecialName(atomname, strlen(atomname));
0N/A
0N/A }
0N/A tsol_lastAtom = lastAtom;
0N/A}
0N/A
0N/Aint
0N/AProcTsolInternAtom(client)
0N/A register ClientPtr client;
0N/A{
0N/A Atom atom;
0N/A char *tchar;
0N/A REQUEST(xInternAtomReq);
0N/A
0N/A REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
0N/A if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
0N/A {
0N/A client->errorValue = stuff->onlyIfExists;
0N/A return(BadValue);
0N/A }
0N/A tchar = (char *) &stuff[1];
0N/A atom = MakeTSOLAtom(client, tchar, stuff->nbytes, !stuff->onlyIfExists);
0N/A if (atom != BAD_RESOURCE)
0N/A {
0N/A xInternAtomReply reply;
0N/A reply.type = X_Reply;
0N/A reply.length = 0;
0N/A reply.sequenceNumber = client->sequence;
0N/A reply.atom = atom;
0N/A WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
0N/A return(client->noClientException);
0N/A }
0N/A else
0N/A return (BadAlloc);
0N/A}
0N/A
0N/Aint
0N/AProcTsolGetAtomName(client)
0N/A register ClientPtr client;
0N/A{
0N/A char *str;
0N/A xGetAtomNameReply reply;
0N/A int len;
0N/A REQUEST(xResourceReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xResourceReq);
0N/A /* TBD: NameForTSOLAtom */
0N/A if ( (str = NameForAtom(stuff->id)) )
0N/A {
0N/A len = strlen(str);
0N/A reply.type = X_Reply;
0N/A reply.length = (len + 3) >> 2;
0N/A reply.sequenceNumber = client->sequence;
0N/A reply.nameLength = len;
0N/A WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
0N/A (void)WriteToClient(client, len, str);
0N/A return(client->noClientException);
0N/A }
0N/A else
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadAtom);
0N/A }
0N/A}
0N/A
0N/AAtom
0N/AMakeTSOLAtom(ClientPtr client, char *string, unsigned int len, Bool makeit)
0N/A{
0N/A TsolNodePtr tndp;
0N/A int count;
0N/A int k;
0N/A int newsize;
0N/A Atom lastAtom;
0N/A Atom newAtom;
0N/A bslabel_t **newsl;
0N/A
0N/A TsolInfoPtr tsolinfo;
0N/A bslabel_t *sl;
0N/A
0N/A
0N/A /* Make the atom as usual */
0N/A newAtom = MakeAtom(string, len, makeit);
0N/A if (newAtom == None || newAtom == BAD_RESOURCE) {
0N/A return (newAtom);
0N/A }
0N/A
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A
0N/A /* tsol node info already present? */
0N/A if (newAtom <= tsol_lastAtom) {
0N/A tndp = &(tsol_node[newAtom]);
0N/A
0N/A /* public atoms have null sl */
0N/A if (tndp->sl == NULL) {
0N/A return newAtom;
0N/A }
0N/A
0N/A /* private atoms must have a matching sl */
0N/A for (k = 0; k < tndp->slcount; k++) {
0N/A if (tsolinfo->sl == tndp->sl[k]) {
0N/A return newAtom; /* found one */
0N/A }
0N/A }
0N/A
0N/A } else {
0N/A /* tsol node table not big enough, expand it */
0N/A UpdateTsolNode();
0N/A tndp = &(tsol_node[newAtom]);
0N/A }
0N/A
0N/A /* Allocate storage for sl if needed */
0N/A if (tndp->sl == NULL) {
0N/A tndp->sl = (bslabel_t **)xalloc(NODE_SLSIZE * (sizeof(bslabel_t *)));
0N/A tndp->slcount = 0;
0N/A tndp->slsize = NODE_SLSIZE;
0N/A }
0N/A
0N/A /* Expand storage space for sl if needed */
0N/A if (tndp->slsize < tndp->slcount) {
0N/A newsize = tndp->slsize + NODE_SLSIZE;
0N/A tndp->sl = (bslabel_t **)xrealloc(tndp->sl, newsize * (sizeof(bslabel_t *)));
0N/A tndp->slsize = newsize;
0N/A }
0N/A
0N/A if (tndp->sl == NULL) {
0N/A ErrorF("Not enough memory for atoms\n");
0N/A return (Atom)None;
0N/A }
0N/A
0N/A /* Store client's sl */
0N/A tndp->sl[tndp->slcount] = tsolinfo->sl;
0N/A tndp->slcount++;
0N/A
0N/A return newAtom;
0N/A}
0N/A
0N/A
0N/Aint
0N/AProcTsolSetSelectionOwner(client)
0N/A register ClientPtr client;
0N/A{
0N/A WindowPtr pWin;
0N/A TimeStamp time;
0N/A REQUEST(xSetSelectionOwnerReq);
0N/A
0N/A#ifdef TSOL
0N/A TsolSelnPtr tsolseln = NULL;
0N/A TsolSelnPtr prevtsolseln = NULL;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A#endif /* TSOL */
0N/A
0N/A REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
0N/A UpdateCurrentTime();
0N/A time = ClientTimeToServerTime(stuff->time);
0N/A
0N/A /* If the client's time stamp is in the future relative to the server's
0N/A time stamp, do not set the selection, just return success. */
0N/A if (CompareTimeStamps(time, currentTime) == LATER)
0N/A return Success;
0N/A if (stuff->window != None)
0N/A {
0N/A pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
0N/A SecurityReadAccess);
0N/A if (!pWin)
0N/A return(BadWindow);
0N/A }
0N/A else
0N/A pWin = (WindowPtr)None;
0N/A if (ValidAtom(stuff->selection))
0N/A {
0N/A int i = 0;
0N/A
0N/A /*
0N/A * First, see if the selection is already set...
0N/A */
0N/A while ((i < NumCurrentSelections) &&
0N/A CurrentSelections[i].selection != stuff->selection)
0N/A i++;
0N/A
0N/A#ifdef TSOL
0N/A /*
0N/A * special processing for selection agent. Just note
0N/A * the owner of this special selection
0N/A */
0N/A if (stuff->selection == MakeAtom("_TSOL_SEL_AGNT", 14, 1))
0N/A {
0N/A if (HasWinSelection(tsolinfo))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A auditwrite(AW_USEOFPRIV, 1, PRIV_WIN_SELECTION,
0N/A AW_APPEND, AW_END);
0N/A tsol_sel_agnt = i; /* owner of this seln */
0N/A }
0N/A else
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A auditwrite(AW_USEOFPRIV, 0, PRIV_WIN_SELECTION,
0N/A AW_APPEND, AW_END);
0N/A client->errorValue = stuff->selection;
0N/A return(BadAtom);
0N/A }
0N/A }
0N/A#endif /* TSOL */
0N/A
0N/A if (i < NumCurrentSelections)
0N/A {
0N/A xEvent event;
0N/A
0N/A #ifdef TSOL
0N/A /* for poly-selections, search further to see if sl,uid match */
0N/A tsolseln = (TsolSelnPtr)CurrentSelections[i].secPrivate;
0N/A if (PolySelection(CurrentSelections[i].selection))
0N/A {
0N/A prevtsolseln = tsolseln;
0N/A while (tsolseln)
0N/A {
0N/A if (tsolseln->uid == tsolinfo->uid &&
0N/A tsolseln->sl == tsolinfo->sl)
0N/A break; /* match found */
0N/A prevtsolseln = tsolseln;
0N/A tsolseln = tsolseln->next;
0N/A }
0N/A }
0N/A if (PolySelection(CurrentSelections[i].selection) && tsolseln)
0N/A {
0N/A if (CompareTimeStamps(time, tsolseln->lastTimeChanged) == EARLIER)
0N/A return Success;
0N/A if (tsolseln->client && (!pWin || (tsolseln->client != client)))
0N/A {
0N/A event.u.u.type = SelectionClear;
0N/A event.u.selectionClear.time = time.milliseconds;
0N/A event.u.selectionClear.window = tsolseln->window;
0N/A event.u.selectionClear.atom = CurrentSelections[i].selection;
0N/A (void)TryClientEvents (tsolseln->client,
0N/A &event,
0N/A 1,
0N/A NoEventMask,
0N/A NoEventMask /* CantBeFiltered */,
0N/A NullGrab);
0N/A }
0N/A }
0N/A else if (tsolseln)
0N/A {
0N/A /* we use the existing code. So we left it unindented */
0N/A#endif /* TSOL */
0N/A
0N/A /* If the timestamp in client's request is in the past relative
0N/A to the time stamp indicating the last time the owner of the
0N/A selection was set, do not set the selection, just return
0N/A success. */
0N/A if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
0N/A == EARLIER)
0N/A return Success;
0N/A if (CurrentSelections[i].client &&
0N/A (!pWin || (CurrentSelections[i].client != client)))
0N/A {
0N/A event.u.u.type = SelectionClear;
0N/A event.u.selectionClear.time = time.milliseconds;
0N/A event.u.selectionClear.window = CurrentSelections[i].window;
0N/A event.u.selectionClear.atom = CurrentSelections[i].selection;
0N/A (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
0N/A NoEventMask, NoEventMask /* CantBeFiltered */,
0N/A NullGrab);
0N/A }
0N/A#ifdef TSOL
0N/A }
0N/A#endif /* TSOL */
0N/A }
0N/A else
0N/A {
0N/A /*
0N/A * It doesn't exist, so add it...
0N/A */
0N/A Selection *newsels;
0N/A
0N/A if (i == 0)
0N/A newsels = (Selection *)xalloc(sizeof(Selection));
0N/A else
0N/A newsels = (Selection *)xrealloc(CurrentSelections,
0N/A (NumCurrentSelections + 1) * sizeof(Selection));
0N/A if (!newsels)
0N/A return BadAlloc;
0N/A NumCurrentSelections++;
0N/A CurrentSelections = newsels;
0N/A CurrentSelections[i].selection = stuff->selection;
0N/A }
0N/A#ifdef TSOL
0N/A /*
0N/A * tsolseln == NULL, either seln does not exist,
0N/A * or there is no sl,uid match
0N/A */
0N/A if (!tsolseln)
0N/A {
0N/A /* create one & put it in place */
0N/A tsolseln = (TsolSelnPtr)xalloc(sizeof(TsolSelnRec));
0N/A if (!tsolseln)
0N/A return BadAlloc;
0N/A tsolseln->next = (TsolSelnPtr)NULL;
0N/A
0N/A /* if necessary put at the end of the list */
0N/A if (prevtsolseln)
0N/A prevtsolseln->next = tsolseln;
0N/A else
0N/A CurrentSelections[i].secPrivate = (pointer)tsolseln;
0N/A }
0N/A /* fill it in */
0N/A tsolseln->sl = tsolinfo->sl;
0N/A tsolseln->uid = tsolinfo->uid;
0N/A tsolseln->lastTimeChanged = time;
0N/A tsolseln->window = stuff->window;
0N/A tsolseln->pWin = pWin;
0N/A tsolseln->client = (pWin ? client : NullClient);
0N/A if (!PolySelection(CurrentSelections[i].selection))
0N/A {
0N/A /* no change to existing code. left as it is */
0N/A#endif /* TSOL */
0N/A
0N/A CurrentSelections[i].lastTimeChanged = time;
0N/A CurrentSelections[i].window = stuff->window;
0N/A CurrentSelections[i].pWin = pWin;
0N/A CurrentSelections[i].client = (pWin ? client : NullClient);
0N/A if (SelectionCallback)
0N/A {
0N/A SelectionInfoRec info;
0N/A
0N/A info.selection = &CurrentSelections[i];
0N/A info.kind= SelectionSetOwner;
0N/A CallCallbacks(&SelectionCallback, &info);
0N/A }
0N/A#ifdef TSOL
0N/A }
0N/A#endif /* TSOL */
0N/A
0N/A return (client->noClientException);
0N/A }
0N/A else
0N/A {
0N/A client->errorValue = stuff->selection;
0N/A return (BadAtom);
0N/A }
0N/A}
0N/A
0N/Aint
0N/AProcTsolGetSelectionOwner(client)
0N/A register ClientPtr client;
0N/A{
0N/A REQUEST(xResourceReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xResourceReq);
0N/A if (ValidAtom(stuff->id))
0N/A {
0N/A int i;
0N/A xGetSelectionOwnerReply reply;
0N/A
0N/A i = 0;
0N/A while ((i < NumCurrentSelections) &&
0N/A CurrentSelections[i].selection != stuff->id) i++;
0N/A reply.type = X_Reply;
0N/A reply.length = 0;
0N/A reply.sequenceNumber = client->sequence;
0N/A if (i < NumCurrentSelections)
0N/A#ifdef TSOL
0N/A {
0N/A TsolSelnPtr tsolseln;
0N/A TsolInfoPtr tsolinfo; /* tsol client info */
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A /* find matching sl,uid in case of poly selns */
0N/A tsolseln = (TsolSelnPtr)CurrentSelections[i].secPrivate;
0N/A if (PolySelection(CurrentSelections[i].selection))
0N/A {
0N/A while (tsolseln)
0N/A {
0N/A if (tsolseln->uid == tsolinfo->uid &&
0N/A tsolseln->sl == tsolinfo->sl)
0N/A break; /* match found */
0N/A tsolseln = tsolseln->next;
0N/A }
0N/A if (tsolseln)
0N/A reply.owner = tsolseln->window;
0N/A else
0N/A reply.owner = None;
0N/A }
0N/A else
0N/A {
0N/A reply.owner = CurrentSelections[i].window;
0N/A }
0N/A /*
0N/A * Selection Agent processing. Override the owner
0N/A */
0N/A if (!HasWinSelection(tsolinfo) &&
0N/A client->index != CLIENT_ID(reply.owner) &&
0N/A reply.owner != None &&
0N/A tsol_sel_agnt != -1 &&
0N/A CurrentSelections[tsol_sel_agnt].client)
0N/A {
0N/A WindowPtr pWin;
0N/A pWin = (WindowPtr)LookupWindow(reply.owner, client);
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A auditwrite(AW_USEOFPRIV, 0, PRIV_WIN_SELECTION,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A else if (HasWinSelection(tsolinfo) &&
0N/A tsolinfo->flags & TSOL_AUDITEVENT)
0N/A {
0N/A auditwrite(AW_USEOFPRIV, 1, PRIV_WIN_SELECTION,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A /* end seln agent processing */
0N/A }
0N/A#else /* TSOL */
0N/A reply.owner = CurrentSelections[i].window;
0N/A#endif /* TSOL */
0N/A else
0N/A reply.owner = None;
0N/A WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
0N/A return(client->noClientException);
0N/A }
0N/A else
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadAtom);
0N/A }
0N/A}
0N/A
0N/Aint
0N/AProcTsolConvertSelection(client)
0N/A register ClientPtr client;
0N/A{
0N/A Bool paramsOkay;
0N/A xEvent event;
0N/A WindowPtr pWin;
0N/A REQUEST(xConvertSelectionReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xConvertSelectionReq);
0N/A pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
0N/A SecurityReadAccess);
0N/A if (!pWin)
0N/A return(BadWindow);
0N/A
0N/A paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
0N/A if (stuff->property != None)
0N/A paramsOkay &= ValidAtom(stuff->property);
0N/A if (paramsOkay)
0N/A {
0N/A int i;
0N/A
0N/A i = 0;
0N/A while ((i < NumCurrentSelections) &&
0N/A CurrentSelections[i].selection != stuff->selection) i++;
0N/A#ifdef TSOL
0N/A if (i < NumCurrentSelections)
0N/A {
0N/A TsolSelnPtr tsolseln;
0N/A TsolInfoPtr tsolinfo; /* tsol client info */
0N/A Window twin; /* temporary win */
0N/A ClientPtr tclient; /* temporary client */
0N/A
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A /* find matching sl,uid in case of poly selns */
0N/A tsolseln = (TsolSelnPtr)CurrentSelections[i].secPrivate;
0N/A if (PolySelection(CurrentSelections[i].selection))
0N/A {
0N/A while (tsolseln)
0N/A {
0N/A if (tsolseln->uid == tsolinfo->uid &&
0N/A tsolseln->sl == tsolinfo->sl)
0N/A break; /* match found */
0N/A tsolseln = tsolseln->next;
0N/A }
0N/A if (!tsolseln)
0N/A {
0N/A client->errorValue = stuff->property;
0N/A return (BadAtom);
0N/A }
0N/A twin = tsolseln->window;
0N/A tclient = tsolseln->client;
0N/A }
0N/A else
0N/A {
0N/A twin = CurrentSelections[i].window;
0N/A tclient = CurrentSelections[i].client;
0N/A }
0N/A /*
0N/A * Special case for seln agent.
0N/A * SelectionRequest event is redirected to selection
0N/A * agent for unpirvileged clients and who do not own
0N/A * the selection
0N/A */
0N/A if (tsol_sel_agnt != -1 && CurrentSelections[tsol_sel_agnt].client)
0N/A {
0N/A /* Redirect only if client other than owner & does not have priv */
0N/A if (!HasWinSelection(tsolinfo) && (client != tclient))
0N/A {
0N/A tclient = CurrentSelections[tsol_sel_agnt].client;
0N/A twin = CurrentSelections[tsol_sel_agnt].window;
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A auditwrite(AW_USEOFPRIV, 1, PRIV_WIN_SELECTION,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A else if (HasWinSelection(tsolinfo) &&
0N/A tsolinfo->flags & TSOL_AUDITEVENT)
0N/A {
0N/A auditwrite(AW_USEOFPRIV, 0, PRIV_WIN_SELECTION,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A }
0N/A /* end of special case seln handling */
0N/A
0N/A if (twin != None)
0N/A {
0N/A event.u.u.type = SelectionRequest;
0N/A event.u.selectionRequest.time = stuff->time;
0N/A event.u.selectionRequest.owner = twin;
0N/A event.u.selectionRequest.requestor = stuff->requestor;
0N/A event.u.selectionRequest.selection = stuff->selection;
0N/A event.u.selectionRequest.target = stuff->target;
0N/A event.u.selectionRequest.property = stuff->property;
0N/A if (TryClientEvents(tclient, &event, 1,
0N/A NoEventMask, NoEventMask /* CantBeFiltered */,
0N/A NullGrab))
0N/A return (client->noClientException);
0N/A }
0N/A }
0N/A#else /* TSOL */
0N/A if ((i < NumCurrentSelections) &&
0N/A (CurrentSelections[i].window != None)
0N/A#ifdef XCSECURITY
0N/A && (!client->CheckAccess ||
0N/A (* client->CheckAccess)(client, CurrentSelections[i].window,
0N/A RT_WINDOW, SecurityReadAccess,
0N/A CurrentSelections[i].pWin))
0N/A#endif
0N/A )
0N/A {
0N/A event.u.u.type = SelectionRequest;
0N/A event.u.selectionRequest.time = stuff->time;
0N/A event.u.selectionRequest.owner =
0N/A CurrentSelections[i].window;
0N/A event.u.selectionRequest.requestor = stuff->requestor;
0N/A event.u.selectionRequest.selection = stuff->selection;
0N/A event.u.selectionRequest.target = stuff->target;
0N/A event.u.selectionRequest.property = stuff->property;
0N/A if (TryClientEvents(
0N/A CurrentSelections[i].client, &event, 1, NoEventMask,
0N/A NoEventMask /* CantBeFiltered */, NullGrab))
0N/A return (client->noClientException);
0N/A }
0N/A#endif /* TSOL */
0N/A
0N/A event.u.u.type = SelectionNotify;
0N/A event.u.selectionNotify.time = stuff->time;
0N/A event.u.selectionNotify.requestor = stuff->requestor;
0N/A event.u.selectionNotify.selection = stuff->selection;
0N/A event.u.selectionNotify.target = stuff->target;
0N/A event.u.selectionNotify.property = None;
0N/A (void) TryClientEvents(client, &event, 1, NoEventMask,
0N/A NoEventMask /* CantBeFiltered */, NullGrab);
0N/A return (client->noClientException);
0N/A }
0N/A else
0N/A {
0N/A client->errorValue = stuff->property;
0N/A return (BadAtom);
0N/A }
0N/A}
0N/A
0N/A/* Allocate and initialize a tsolprop */
0N/A
0N/ATsolPropPtr
0N/AAllocTsolProp()
0N/A{
0N/A TsolPropPtr tsolprop;
0N/A
0N/A tsolprop = (TsolPropPtr)Xcalloc(sizeof(TsolPropRec));
0N/A
0N/A if (tsolprop)
0N/A {
0N/A tsolprop->size = 0;
0N/A tsolprop->data = NULL;
0N/A tsolprop->next = NULL;
168N/A tsolprop->serverOwned = FALSE;
168N/A }
168N/A
168N/A return tsolprop;
168N/A}
168N/A
168N/A/*
168N/A * Allocate and initialize tsolprop created
168N/A * internally by the X server
168N/A */
168N/A
168N/ATsolPropPtr
168N/AAllocServerTsolProp()
168N/A{
168N/A TsolPropPtr tsolprop;
168N/A
168N/A tsolprop = (TsolPropPtr)Xcalloc(sizeof(TsolPropRec));
168N/A
168N/A if (tsolprop)
168N/A {
168N/A tsolprop->size = 0;
168N/A tsolprop->data = NULL;
168N/A tsolprop->next = NULL;
168N/A
168N/A tsolprop->serverOwned = TRUE;
168N/A tsolprop->uid = getuid(); /* of server process */
168N/A tsolprop->pid = getpid(); /* of server process */
168N/A tsolprop->sl = (bslabel_t *)lookupSL_low();
0N/A }
0N/A
0N/A return tsolprop;
0N/A}
0N/A
0N/A/*
0N/A * property data/len is stored in pProp for single
0N/A * instantiated properties. Polyinstanticated property
0N/A * data/len stored in the tsolprop structure
0N/A */
0N/A
0N/Aint
0N/ATsolChangeWindowProperty(client, pWin, property, type,
0N/A format, mode, len, value, sendevent)
0N/A ClientPtr client;
0N/A WindowPtr pWin;
0N/A Atom property, type;
0N/A int format, mode;
0N/A unsigned long len;
0N/A pointer value;
0N/A Bool sendevent;
0N/A{
0N/A PropertyPtr pProp;
0N/A xEvent event;
0N/A int sizeInBytes;
0N/A int totalSize;
0N/A pointer data;
0N/A TsolPropPtr tsolprop;
0N/A TsolInfoPtr tsolinfo;
0N/A TsolResPtr tsolres;
0N/A int result;
0N/A int polyprop = PolyProperty(property, pWin);
0N/A
0N/A
0N/A if (!polyprop)
0N/A {
0N/A result = ChangeWindowProperty(pWin, property, type,
0N/A format, mode, len, value, sendevent);
0N/A if (result != Success)
0N/A return (result);
0N/A }
0N/A
0N/A sizeInBytes = format>>3;
0N/A totalSize = len * sizeInBytes;
0N/A
0N/A /* first see if property already exists */
0N/A
0N/A pProp = wUserProps (pWin);
0N/A while (pProp )
0N/A {
0N/A if (pProp->propertyName == property)
0N/A break;
0N/A pProp = pProp->next;
0N/A }
0N/A
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A tsolres = (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A /* Initialize secPrviate if property is not polyinstantiated */
0N/A if (!polyprop && pProp)
0N/A {
0N/A /* Initialize for internally created properties */
0N/A if (!pProp->secPrivate)
0N/A pProp->secPrivate = (pointer)AllocTsolProp();
0N/A
0N/A if (!pProp->secPrivate)
0N/A return(BadAlloc);
0N/A
0N/A tsolprop = (TsolPropPtr)(pProp->secPrivate);
0N/A if (WindowIsRoot(pWin))
0N/A {
0N/A tsolprop->sl = tsolinfo->sl; /* use client's sl/uid */
0N/A tsolprop->uid = tsolinfo->uid;
168N/A tsolprop->pid = tsolinfo->pid;
0N/A }
0N/A else
0N/A {
0N/A tsolprop->sl = tsolres->sl; /* use window's sl/uid */
0N/A tsolprop->uid = tsolres->uid;
168N/A tsolprop->pid = tsolres->pid;
0N/A }
0N/A
0N/A return (result);
0N/A }
0N/A
0N/A /* Handle polyinstantiated property */
0N/A if (!pProp) /* just add to list */
0N/A {
0N/A if (!pWin->optional && !MakeWindowOptional (pWin))
0N/A return(BadAlloc);
0N/A pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
0N/A if (!pProp)
0N/A return(BadAlloc);
0N/A pProp->secPrivate = (pointer)Xcalloc(sizeof(TsolPropRec));
0N/A if (!pProp->secPrivate)
0N/A return(BadAlloc);
0N/A data = (pointer)xalloc(totalSize);
0N/A if (!data && len)
0N/A {
0N/A xfree(pProp->secPrivate);
0N/A xfree(pProp);
0N/A return(BadAlloc);
0N/A }
0N/A pProp->propertyName = property;
0N/A pProp->type = type;
0N/A pProp->format = format;
0N/A pProp->data = data;
0N/A if (len)
0N/A bcopy((char *)value, (char *)data, totalSize);
0N/A pProp->size = len;
0N/A tsolprop = (TsolPropPtr)(pProp->secPrivate);
0N/A if (WindowIsRoot(pWin))
0N/A {
0N/A tsolprop->sl = tsolinfo->sl;
0N/A tsolprop->uid = tsolinfo->uid;
0N/A }
0N/A else
0N/A {
0N/A tsolprop->sl = tsolres->sl;
0N/A tsolprop->uid = tsolres->uid;
0N/A }
0N/A tsolprop->data = data;
0N/A tsolprop->size = len;
0N/A tsolprop->next = (TsolPropPtr)NULL;
0N/A pProp->next = pWin->optional->userProps;
0N/A pWin->optional->userProps = pProp;
0N/A } /* end if !prop */
0N/A else
0N/A {
0N/A /* To append or prepend to a property the request format and type
0N/A * must match those of the already defined property. The
0N/A * existing format and type are irrelevant when using the mode
0N/A * "PropModeReplace" since they will be written over.
0N/A */
0N/A if ((format != pProp->format) && (mode != PropModeReplace))
0N/A return(BadMatch);
0N/A if ((pProp->type != type) && (mode != PropModeReplace))
0N/A return(BadMatch);
0N/A
0N/A tsolprop = (TsolPropPtr)(pProp->secPrivate);
0N/A /* search for a matching (sl, uid) pair */
0N/A while (tsolprop)
0N/A {
0N/A if (tsolprop->uid == tsolinfo->uid && tsolprop->sl == tsolinfo->sl)
0N/A break; /* match found */
0N/A tsolprop = tsolprop->next;
0N/A }
0N/A
0N/A if (!tsolprop)
0N/A {
0N/A /* no match found. Create one */
0N/A TsolPropPtr newtsol = (TsolPropPtr)Xcalloc(sizeof(TsolPropRec));
0N/A if (!newtsol)
0N/A return(BadAlloc);
0N/A data = (pointer)Xcalloc(totalSize);
0N/A if (!data && totalSize)
0N/A {
0N/A xfree(newtsol);
0N/A return(BadAlloc);
0N/A }
0N/A if (len)
0N/A memcpy((char *)data, (char *)value, totalSize);
0N/A
0N/A newtsol->sl = tsolinfo->sl;
0N/A newtsol->uid = tsolinfo->uid;
0N/A newtsol->data = data;
0N/A newtsol->size = len;
0N/A newtsol->next = (TsolPropPtr)(pProp->secPrivate);
0N/A pProp->secPrivate = (pointer)newtsol;
0N/A }
0N/A else
0N/A {
0N/A switch (mode)
0N/A {
0N/A case PropModeReplace:
0N/A if (totalSize != tsolprop->size * (pProp->format >> 3))
0N/A {
0N/A data = (pointer)xrealloc(tsolprop->data, totalSize);
0N/A if (!data && len)
0N/A return(BadAlloc);
0N/A tsolprop->data = data;
0N/A }
0N/A if (len)
0N/A bcopy((char *)value, (char *)tsolprop->data, totalSize);
0N/A tsolprop->size = len;
0N/A pProp->type = type;
0N/A pProp->format = format;
0N/A break;
0N/A
0N/A case PropModeAppend:
0N/A if (len)
0N/A {
0N/A data =
0N/A (pointer)xrealloc(tsolprop->data,
0N/A sizeInBytes*(len+tsolprop->size));
0N/A if (!data)
0N/A return(BadAlloc);
0N/A tsolprop->data = data;
0N/A bcopy((char *)value,
0N/A &((char *)data)[tsolprop->size * sizeInBytes],
0N/A totalSize);
0N/A tsolprop->size += len;
0N/A }
0N/A break;
0N/A
0N/A case PropModePrepend:
0N/A if (len)
0N/A {
0N/A data =
0N/A (pointer)xalloc(sizeInBytes*(len + tsolprop->size));
0N/A if (!data)
0N/A return(BadAlloc);
0N/A bcopy((char *)tsolprop->data,
0N/A &((char *)data)[totalSize],
0N/A (int)(tsolprop->size * sizeInBytes));
0N/A bcopy((char *)value, (char *)data, totalSize);
0N/A xfree(tsolprop->data);
0N/A tsolprop->data = data;
0N/A tsolprop->size += len;
0N/A }
0N/A break;
0N/A }
0N/A }
0N/A } /* end else if !prop */
0N/A
0N/A event.u.u.type = PropertyNotify;
0N/A event.u.property.window = pWin->drawable.id;
0N/A event.u.property.state = PropertyNewValue;
0N/A event.u.property.atom = pProp->propertyName;
0N/A event.u.property.time = currentTime.milliseconds;
0N/A DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
0N/A
0N/A return(Success);
0N/A}
0N/A
0N/Aint
0N/ATsolInitWindow(client, pWin)
0N/A ClientPtr client;
0N/A WindowPtr pWin;
0N/A{
0N/A TsolInfoPtr tsolinfo;
0N/A TsolResPtr tsolres = (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A if (client == serverClient)
0N/A {
0N/A tsolres->uid = 0;
0N/A tsolres->sl = (bslabel_t *)lookupSL_low();
0N/A }
0N/A else
0N/A {
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A tsolres->uid = tsolinfo->uid;
0N/A tsolres->sl = tsolinfo->sl;
0N/A }
36N/A
36N/A return (Success);
0N/A}
0N/A
0N/Aint
0N/ATsolDeleteProperty(client, pWin, propName)
0N/A ClientPtr client;
0N/A WindowPtr pWin;
0N/A Atom propName;
0N/A{
0N/A PropertyPtr pProp, prevProp;
0N/A xEvent event;
0N/A TsolPropPtr tsolprop, tail_prop, prevtsolprop;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (!(pProp = wUserProps (pWin)))
0N/A return(Success);
0N/A
0N/A if (!PolyProperty(propName, pWin))
0N/A return (DeleteProperty(pWin, propName));
0N/A
0N/A prevProp = (PropertyPtr)NULL;
0N/A while (pProp)
0N/A {
0N/A if (pProp->propertyName == propName)
0N/A {
0N/A tsolprop = (TsolPropPtr)(pProp->secPrivate);
0N/A /* Found a matching name. Further match for SL,UID */
0N/A prevtsolprop = (TsolPropPtr)NULL;
0N/A tail_prop = tsolprop;
0N/A while (tsolprop)
0N/A {
0N/A if (tsolpolyinstinfo.enabled)
0N/A {
0N/A if (tsolprop->uid == tsolpolyinstinfo.uid &&
0N/A tsolprop->sl == tsolpolyinstinfo.sl)
0N/A {
0N/A break;
0N/A }
0N/A }
0N/A else
0N/A {
0N/A if (tsolprop->uid == tsolinfo->uid &&
0N/A tsolprop->sl == tsolinfo->sl)
0N/A {
0N/A break;
0N/A }
0N/A }
0N/A prevtsolprop = tsolprop;
0N/A tsolprop = tsolprop->next;
0N/A }
0N/A break;
0N/A }
0N/A prevProp = pProp;
0N/A pProp = pProp->next;
0N/A }
0N/A
0N/A if (pProp)
0N/A {
0N/A event.u.u.type = PropertyNotify;
0N/A event.u.property.window = pWin->drawable.id;
0N/A event.u.property.state = PropertyDelete;
0N/A event.u.property.atom = pProp->propertyName;
0N/A event.u.property.time = currentTime.milliseconds;
0N/A DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
0N/A
0N/A if (tsolprop)
0N/A {
0N/A if ((TsolPropPtr)(pProp->secPrivate) == tsolprop)
0N/A pProp->secPrivate = (pointer)(tsolprop->next);
0N/A
0N/A if (prevtsolprop)
0N/A {
0N/A prevtsolprop->next = tsolprop->next;
0N/A }
0N/A xfree(tsolprop->data);
0N/A xfree(tsolprop);
0N/A
0N/A }
0N/A }
0N/A return(Success);
0N/A}
0N/A
0N/Aint
0N/AProcTsolListProperties(client)
0N/A ClientPtr client;
0N/A{
0N/A Atom *pAtoms, *temppAtoms;
0N/A xListPropertiesReply xlpr;
0N/A int numProps = 0;
0N/A WindowPtr pWin;
0N/A PropertyPtr pProp;
0N/A REQUEST(xResourceReq);
0N/A int err_code;
0N/A
0N/A REQUEST_SIZE_MATCH(xResourceReq);
0N/A pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
0N/A SecurityReadAccess);
0N/A if (!pWin)
0N/A return(BadWindow);
0N/A
0N/A /* policy check for window */
0N/A if (err_code = xtsol_policy(TSOL_RES_PROPWIN, TSOL_READ, pWin,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (err_code);
0N/A }
0N/A
0N/A pProp = wUserProps (pWin);
0N/A while (pProp)
0N/A {
0N/A if (PolyProperty(pProp->propertyName, pWin))
0N/A {
0N/A if (PolyPropReadable(pProp, client))
0N/A numProps++;
0N/A }
0N/A else
0N/A {
0N/A /* error ignored */
0N/A if (!xtsol_policy(TSOL_RES_PROPERTY, TSOL_READ, pProp,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A numProps++;
0N/A }
0N/A pProp = pProp->next;
0N/A }
0N/A
0N/A if (numProps)
0N/A if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
0N/A return(BadAlloc);
0N/A
0N/A xlpr.type = X_Reply;
0N/A xlpr.nProperties = numProps;
0N/A xlpr.length = (numProps * sizeof(Atom)) >> 2;
0N/A xlpr.sequenceNumber = client->sequence;
0N/A pProp = wUserProps (pWin);
0N/A temppAtoms = pAtoms;
0N/A while (pProp)
0N/A {
0N/A if (PolyProperty(pProp->propertyName, pWin))
0N/A {
0N/A if (PolyPropReadable(pProp, client))
0N/A *temppAtoms++ = pProp->propertyName;
0N/A }
0N/A else
0N/A {
0N/A /* error ignored */
0N/A if (!xtsol_policy(TSOL_RES_PROPERTY, TSOL_READ, pProp,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A *temppAtoms++ = pProp->propertyName;
0N/A }
0N/A pProp = pProp->next;
0N/A }
0N/A WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
0N/A if (numProps)
0N/A {
0N/A client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
0N/A WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
0N/A DEALLOCATE_LOCAL(pAtoms);
0N/A }
0N/A return(client->noClientException);
0N/A}
0N/A
0N/Aint
0N/AProcTsolGetProperty(client)
0N/A ClientPtr client;
0N/A{
0N/A PropertyPtr pProp, prevProp;
0N/A unsigned long n, len, ind;
0N/A WindowPtr pWin;
0N/A xGetPropertyReply reply;
0N/A TsolPropPtr tsolprop;
0N/A TsolPropPtr prevtsolprop;
0N/A int err_code;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A REQUEST(xGetPropertyReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xGetPropertyReq);
0N/A if (stuff->delete)
0N/A UpdateCurrentTime();
0N/A pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
0N/A SecurityReadAccess);
0N/A if (!pWin)
0N/A return BadWindow;
0N/A
0N/A if (!ValidAtom(stuff->property))
0N/A {
0N/A client->errorValue = stuff->property;
0N/A return(BadAtom);
0N/A }
0N/A if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
0N/A {
0N/A client->errorValue = stuff->delete;
0N/A return(BadValue);
0N/A }
0N/A
0N/A if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
0N/A {
0N/A client->errorValue = stuff->type;
0N/A return(BadAtom);
0N/A }
0N/A
0N/A
0N/A /* policy check for window */
0N/A if (err_code = xtsol_policy(TSOL_RES_PROPWIN, TSOL_READ, pWin,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A client->errorValue = stuff->window;
0N/A return (err_code);
0N/A }
0N/A
0N/A if (!PolyProperty(stuff->property, pWin))
0N/A {
0N/A return (*TsolSavedProcVector[X_GetProperty])(client);
0N/A }
0N/A
0N/A pProp = wUserProps (pWin);
0N/A prevProp = (PropertyPtr)NULL;
0N/A
0N/A while (pProp)
0N/A {
0N/A if (pProp->propertyName == stuff->property)
0N/A {
0N/A tsolprop = (TsolPropPtr)(pProp->secPrivate);
0N/A prevtsolprop = tsolprop;
0N/A while (tsolprop)
0N/A {
0N/A if (tsolpolyinstinfo.enabled)
0N/A {
0N/A if (tsolprop->uid == tsolpolyinstinfo.uid &&
0N/A tsolprop->sl == tsolpolyinstinfo.sl)
0N/A break;
0N/A }
0N/A else
0N/A {
0N/A if (tsolprop->uid == tsolinfo->uid &&
0N/A tsolprop->sl == tsolinfo->sl)
0N/A break; /* match found */
0N/A }
0N/A prevtsolprop = tsolprop;
0N/A tsolprop = tsolprop->next;
0N/A }
0N/A break;
0N/A }
0N/A prevProp = pProp;
0N/A pProp = pProp->next;
0N/A }
0N/A
0N/A reply.type = X_Reply;
0N/A reply.sequenceNumber = client->sequence;
0N/A
0N/A if ( (!pProp) || (!tsolprop) || err_code)
0N/A {
0N/A reply.nItems = 0;
0N/A reply.length = 0;
0N/A reply.bytesAfter = 0;
0N/A reply.propertyType = None;
0N/A reply.format = 0;
0N/A WriteReplyToClient(client, sizeof(xGenericReply), &reply);
0N/A }
0N/A else
0N/A {
0N/A /* If the request type and actual type don't match. Return the
0N/A property information, but not the data. */
0N/A
0N/A if (((stuff->type != pProp->type) &&
0N/A (stuff->type != AnyPropertyType)))
0N/A {
0N/A reply.bytesAfter = tsolprop->size;
0N/A reply.format = pProp->format;
0N/A reply.length = 0;
0N/A reply.nItems = 0;
0N/A reply.propertyType = pProp->type;
0N/A WriteReplyToClient(client, sizeof(xGenericReply), &reply);
0N/A return(Success);
0N/A }
0N/A
0N/A /*
0N/A * Return type, format, value to client
0N/A */
0N/A n = (pProp->format/8) * tsolprop->size;
0N/A
0N/A ind = stuff->longOffset << 2;
0N/A
0N/A /* If longOffset is invalid such that it causes "len" to
0N/A be negative, it's a value error. */
0N/A
0N/A if (n < ind)
0N/A {
0N/A client->errorValue = stuff->longOffset;
0N/A return BadValue;
0N/A }
0N/A
0N/A len = min(n - ind, 4 * stuff->longLength);
0N/A
0N/A reply.bytesAfter = n - (ind + len);
0N/A reply.format = pProp->format;
0N/A reply.length = (len + 3) >> 2;
0N/A reply.nItems = len / (pProp->format / 8 );
0N/A reply.propertyType = pProp->type;
0N/A
0N/A /* policy check for delete error ignored */
0N/A if (stuff->delete && (reply.bytesAfter == 0) &&
0N/A (!xtsol_policy(TSOL_RES_PROPERTY, TSOL_DESTROY, pProp,
0N/A client, TSOL_ALL, (void *)MAJOROP)))
0N/A { /* send the event */
0N/A xEvent event;
0N/A
0N/A event.u.u.type = PropertyNotify;
0N/A event.u.property.window = pWin->drawable.id;
0N/A event.u.property.state = PropertyDelete;
0N/A event.u.property.atom = pProp->propertyName;
0N/A event.u.property.time = currentTime.milliseconds;
0N/A DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
0N/A }
0N/A
0N/A WriteReplyToClient(client, sizeof(xGenericReply), &reply);
0N/A if (len)
0N/A {
0N/A switch (reply.format) {
0N/A case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
0N/A case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
0N/A default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
0N/A }
0N/A WriteSwappedDataToClient(client, len, (char *)tsolprop->data + ind);
0N/A }
0N/A
0N/A if (stuff->delete && (reply.bytesAfter == 0))
0N/A { /* delete the Property */
0N/A if (prevProp == (PropertyPtr)NULL) /* takes care of head */
0N/A {
0N/A if (!(pWin->optional->userProps = pProp->next))
0N/A CheckWindowOptionalNeed (pWin);
0N/A }
0N/A else
0N/A prevProp->next = pProp->next;
0N/A
0N/A /* remove the tsol struct */
0N/A prevtsolprop->next = tsolprop->next;
0N/A xfree(tsolprop->data);
0N/A xfree(tsolprop);
0N/A /* delete the prop for last reference */
0N/A if (tsolprop == prevtsolprop)
0N/A xfree(pProp);
0N/A }
0N/A }
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Aint
0N/AProcTsolChangeKeyboardMapping(client)
0N/A ClientPtr client;
0N/A{
36N/A int status;
36N/A int savedtrust = client->trustLevel;
0N/A
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A
36N/A if (xtsol_policy(TSOL_RES_KEYMAP, TSOL_MODIFY,
0N/A NULL, client, TSOL_ALL, (void *)MAJOROP))
0N/A {
36N/A status = client->noClientException; /* ignore error */
0N/A }
0N/A else
0N/A {
36N/A status = (*TsolSavedProcVector[X_ChangeKeyboardMapping])(client);
0N/A }
36N/A
36N/A client->trustLevel = savedtrust;
36N/A return (status);
0N/A}
0N/A
0N/Aint
0N/AProcTsolSetPointerMapping(client)
0N/A ClientPtr client;
0N/A{
36N/A int status;
36N/A int savedtrust = client->trustLevel;
0N/A
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A
36N/A if (xtsol_policy(TSOL_RES_PTRMAP, TSOL_MODIFY,
0N/A NULL, client, TSOL_ALL, (void *)MAJOROP))
0N/A {
36N/A status = Success; /* ignore error */
0N/A }
0N/A else
0N/A {
36N/A status = (*TsolSavedProcVector[X_SetPointerMapping])(client);
0N/A }
36N/A
36N/A client->trustLevel = savedtrust;
36N/A return (status);
0N/A}
0N/A
0N/Aint
0N/AProcTsolChangeKeyboardControl(client)
0N/A ClientPtr client;
0N/A{
36N/A int status;
36N/A int savedtrust = client->trustLevel;
0N/A
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A
36N/A if (xtsol_policy(TSOL_RES_KBDCTL, TSOL_MODIFY,
0N/A NULL, client, TSOL_ALL, (void *)MAJOROP))
0N/A {
36N/A status = Success; /* ignore error */
0N/A }
0N/A else
0N/A {
36N/A status = (*TsolSavedProcVector[X_ChangeKeyboardControl])(client);
0N/A }
36N/A
36N/A client->trustLevel = savedtrust;
36N/A return (status);
0N/A}
0N/A
0N/Aint
0N/AProcTsolBell(client)
0N/A ClientPtr client;
0N/A{
36N/A int status;
36N/A int savedtrust = client->trustLevel;
0N/A
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A
36N/A if (xtsol_policy(TSOL_RES_BELL, TSOL_MODIFY,
0N/A NULL, client, TSOL_ALL, (void *)MAJOROP))
0N/A {
36N/A status = Success; /* ignore error */
0N/A }
0N/A else
0N/A {
36N/A status = (*TsolSavedProcVector[X_Bell])(client);
0N/A }
36N/A
36N/A client->trustLevel = savedtrust;
36N/A return (status);
0N/A}
0N/A
0N/Aint
0N/AProcTsolChangePointerControl(client)
0N/A ClientPtr client;
0N/A{
36N/A int status;
36N/A int savedtrust = client->trustLevel;
0N/A
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A
36N/A if (xtsol_policy(TSOL_RES_PTRCTL, TSOL_MODIFY,
0N/A NULL, client, TSOL_ALL, (void *)MAJOROP))
0N/A {
36N/A status = Success; /* ignore error */
0N/A }
0N/A else
0N/A {
36N/A status = (*TsolSavedProcVector[X_ChangePointerControl])(client);
0N/A }
36N/A
36N/A client->trustLevel = savedtrust;
36N/A return (status);
0N/A}
0N/A
0N/Aint
0N/AProcTsolSetModifierMapping(client)
0N/A ClientPtr client;
0N/A{
36N/A
0N/A xSetModifierMappingReply rep;
0N/A REQUEST(xSetModifierMappingReq);
0N/A KeyCode *inputMap;
0N/A int inputMapLen;
0N/A register int i;
36N/A int status;
0N/A DeviceIntPtr keybd = inputInfo.keyboard;
0N/A register KeyClassPtr keyc = keybd->key;
36N/A int savedtrust = client->trustLevel;
0N/A
0N/A REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
0N/A
0N/A if (client->req_len != ((stuff->numKeyPerModifier<<1) +
0N/A (sizeof (xSetModifierMappingReq)>>2)))
0N/A return BadLength;
0N/A
0N/A inputMapLen = 8*stuff->numKeyPerModifier;
0N/A inputMap = (KeyCode *)&stuff[1];
0N/A
0N/A /*
0N/A * Now enforce the restriction that "all of the non-zero keycodes must be
0N/A * in the range specified by min-keycode and max-keycode in the
0N/A * connection setup (else a Value error)"
0N/A */
0N/A i = inputMapLen;
0N/A while (i--)
0N/A {
0N/A if (inputMap[i]
0N/A && (inputMap[i] < keyc->curKeySyms.minKeyCode
0N/A || inputMap[i] > keyc->curKeySyms.maxKeyCode))
0N/A {
0N/A client->errorValue = inputMap[i];
0N/A return BadValue;
0N/A }
0N/A }
0N/A
0N/A rep.type = X_Reply;
0N/A rep.length = 0;
0N/A rep.sequenceNumber = client->sequence;
0N/A rep.success = MappingSuccess;
0N/A
36N/A client->trustLevel = XSecurityClientTrusted;
0N/A
36N/A if (xtsol_policy(TSOL_RES_MODMAP, TSOL_MODIFY,
0N/A NULL, client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A /*
0N/A * silently ignore the request. xview apps
0N/A * complain if we return error code. If we don't
0N/A * send the map notify event application hangs
0N/A */
0N/A SendMappingNotify(MappingModifier, 0, 0,client);
0N/A WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
36N/A status = client->noClientException;
0N/A }
0N/A else
0N/A {
36N/A status = (*TsolSavedProcVector[X_SetModifierMapping])(client);
0N/A }
36N/A
36N/A client->trustLevel = savedtrust;
36N/A return (status);
0N/A}
0N/A
0N/Avoid
0N/ARemoveStripeWindow()
0N/A{
0N/A WindowPtr pParent;
0N/A WindowPtr pHead;
0N/A
0N/A if (!tpwin)
0N/A return;
0N/A
0N/A pParent = tpwin->parent;
0N/A pHead = pParent->firstChild;
0N/A if (tpwin == pHead) {
0N/A pHead = tpwin->nextSib;
0N/A tpwin->nextSib->prevSib = tpwin->prevSib;
0N/A }
0N/A
0N/A if (tpwin == pParent->lastChild) {
0N/A pParent->lastChild = tpwin->nextSib;
0N/A }
0N/A}
0N/A
36N/Astatic void
36N/AResetStripeWindow(ClientPtr client)
0N/A{
0N/A WindowPtr pParent;
36N/A WindowPtr pWin = NULL;
0N/A
36N/A /* Validate trusted stripe window */
36N/A if (tpwin)
36N/A pWin = LookupWindow(tpwin->drawable.id, client);
36N/A
36N/A if (tpwin == NullWindow || pWin == NullWindow)
0N/A return;
0N/A
0N/A pParent = tpwin->parent;
0N/A /* stripe is already at head, nothing to do */
0N/A if (!pParent || pParent->firstChild == tpwin)
0N/A return;
0N/A
0N/A ReflectStackChange(tpwin, pParent->firstChild, VTStack);
0N/A}
0N/A
0N/Aint
0N/AProcTsolCreateWindow(client)
0N/A ClientPtr client;
0N/A{
0N/A int result;
0N/A WindowPtr pParent;
0N/A WindowPtr pWin;
0N/A bslabel_t admin_low;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres;
0N/A
0N/A REQUEST(xCreateWindowReq);
0N/A
0N/A REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
0N/A
0N/A LEGAL_NEW_RESOURCE(stuff->wid, client);
0N/A if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
0N/A SecurityWriteAccess)))
0N/A return BadWindow;
0N/A
0N/A
0N/A if (result = xtsol_policy(TSOL_RES_WINDOW, TSOL_CREATE, pParent,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A return (result);
0N/A
0N/A /* Initialize tsol security attributes */
0N/A result = (*TsolSavedProcVector[X_CreateWindow])(client);
0N/A pWin = pParent->firstChild;
0N/A tsolres = (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A /* stuff tsol info into window from client */
0N/A if (tsolinfo == NULL || client == serverClient) {
0N/A /* Client is Server itself */
0N/A tsolres->uid = 0;
0N/A tsolres->sl = (bslabel_t *)lookupSL_low();
0N/A }
0N/A else
0N/A {
0N/A tsolres->uid = tsolinfo->uid;
0N/A tsolres->sl = tsolinfo->sl;
0N/A }
0N/A
0N/A bsllow(&admin_low);
0N/A if (blequal(tsolres->sl, &admin_low))
0N/A tsolres->flags = TRUSTED_MASK;
0N/A else
0N/A tsolres->flags = 0;
0N/A
36N/A ResetStripeWindow(client);
0N/A
0N/A return result;
0N/A}
0N/A
0N/Aint
0N/AProcTsolChangeWindowAttributes(client)
0N/A register ClientPtr client;
0N/A{
0N/A register WindowPtr pWin;
0N/A REQUEST(xChangeWindowAttributesReq);
0N/A int result;
0N/A
0N/A REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
0N/A pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
0N/A SecurityWriteAccess);
0N/A if (!pWin)
0N/A return(BadWindow);
0N/A
0N/A if (result = xtsol_policy(TSOL_RES_WINDOW, TSOL_MODIFY, pWin,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A if (!WindowIsRoot(pWin))
0N/A return (result);
0N/A }
0N/A
0N/A result = (*TsolSavedProcVector[X_ChangeWindowAttributes])(client);
36N/A ResetStripeWindow(client);
0N/A
0N/A return result;
0N/A}
0N/A
0N/Aint
0N/AProcTsolConfigureWindow(client)
0N/A register ClientPtr client;
0N/A{
0N/A int result;
0N/A
0N/A result = (*TsolSavedProcVector[X_ConfigureWindow])(client);
36N/A ResetStripeWindow(client);
0N/A
0N/A return result;
0N/A}
0N/A
0N/Aint
0N/AProcTsolCirculateWindow(client)
0N/A register ClientPtr client;
0N/A{
0N/A int result;
0N/A
0N/A result = (*TsolSavedProcVector[X_CirculateWindow])(client);
36N/A ResetStripeWindow(client);
0N/A
0N/A return result;
0N/A}
0N/A
0N/Aint
0N/AProcTsolReparentWindow(client)
0N/A register ClientPtr client;
0N/A{
0N/A int result;
0N/A
0N/A result = (*TsolSavedProcVector[X_ReparentWindow])(client);
36N/A ResetStripeWindow(client);
0N/A
0N/A return result;
0N/A}
0N/A
0N/Aint
0N/AProcTsolSendEvent(client)
0N/A register ClientPtr client;
0N/A{
0N/A WindowPtr pWin;
0N/A REQUEST(xSendEventReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xSendEventReq);
0N/A
0N/A pWin = LookupWindow(stuff->destination, client);
0N/A
0N/A if (!pWin)
0N/A return BadWindow;
0N/A
0N/A if (xtsol_policy(TSOL_RES_EVENTWIN, TSOL_MODIFY,
0N/A pWin, client, TSOL_ALL, (void *)MAJOROP))
0N/A return Success; /* ignore error */
0N/A
0N/A return (*TsolSavedProcVector[X_SendEvent])(client);
0N/A}
0N/A
0N/A
0N/A/*
0N/A * HandleHotKey -
0N/A * HotKey is Meta(Diamond)+ Stop Key
0N/A * Breaks untusted Ptr and Kbd grabs.
0N/A * Trusted Grabs are NOT broken
0N/A * Warps pointer to the Trusted Stripe if not Trusted grabs in force.
0N/A */
0N/Avoid
0N/AHandleHotKey()
0N/A{
0N/A extern unsigned int StripeHeight;
0N/A int x, y;
0N/A Bool trusted_grab = FALSE;
0N/A ClientPtr client;
0N/A DeviceIntPtr mouse = inputInfo.pointer;
0N/A DeviceIntPtr keybd = inputInfo.keyboard;
0N/A TsolInfoPtr tsolinfo;
0N/A GrabPtr ptrgrab = mouse->grab;
0N/A GrabPtr kbdgrab = keybd->grab;
0N/A ScreenPtr pScreen;
0N/A
0N/A if (kbdgrab)
0N/A {
0N/A client = clients[CLIENT_ID(kbdgrab->resource)];
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (tsolinfo)
0N/A {
0N/A if (HasTrustedPath(tsolinfo))
0N/A trusted_grab = TRUE;
0N/A else
0N/A (*keybd->DeactivateGrab)(keybd);
0N/A }
0N/A
0N/A if (ptrgrab)
0N/A {
0N/A client = clients[CLIENT_ID(ptrgrab->resource)];
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (tsolinfo)
0N/A {
0N/A if (HasTrustedPath(tsolinfo))
0N/A trusted_grab = TRUE;
0N/A else
0N/A (*mouse->DeactivateGrab)(mouse);
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (!trusted_grab)
0N/A {
0N/A /*
0N/A * Warp the pointer to the Trusted Stripe
0N/A */
0N/A pScreen = screenInfo.screens[0];
0N/A x = pScreen->width/2;
0N/A y = pScreen->height - StripeHeight/2;
0N/A (*pScreen->SetCursorPosition)(pScreen, x, y, TRUE);
0N/A }
0N/A}
0N/A
0N/Aint
0N/AProcTsolSetInputFocus(client)
0N/A ClientPtr client;
0N/A{
0N/A
0N/A REQUEST(xSetInputFocusReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xSetInputFocusReq);
0N/A
0N/A if (stuff->focus != None)
0N/A {
0N/A WindowPtr focuswin;
0N/A
0N/A focuswin = LookupWindow(stuff->focus, client);
0N/A if ((focuswin != NullWindow) &&
0N/A xtsol_policy(TSOL_RES_FOCUSWIN, TSOL_MODIFY, focuswin,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A return (client->noClientException);
0N/A }
0N/A }
0N/A return (*TsolSavedProcVector[X_SetInputFocus])(client);
0N/A}
0N/A
0N/Aint
0N/AProcTsolGetInputFocus(client)
0N/A ClientPtr client;
0N/A{
0N/A xGetInputFocusReply rep;
0N/A REQUEST(xReq);
0N/A FocusClassPtr focus = inputInfo.keyboard->focus;
0N/A
0N/A REQUEST_SIZE_MATCH(xReq);
0N/A#ifdef PANORAMIX
0N/A if ( !noPanoramiXExtension )
0N/A return PanoramiXGetInputFocus(client);
0N/A#endif
0N/A rep.type = X_Reply;
0N/A rep.length = 0;
0N/A rep.sequenceNumber = client->sequence;
0N/A if (focus->win == NoneWin)
0N/A rep.focus = None;
0N/A else if (focus->win == PointerRootWin)
0N/A rep.focus = PointerRoot;
0N/A else if (xtsol_policy(TSOL_RES_FOCUSWIN, TSOL_READ,
0N/A focus->win, client, TSOL_ALL, (void *)MAJOROP))
0N/A rep.focus = RootOf(focus->win); /* root window on access failure */
0N/A else rep.focus = focus->win->drawable.id;
0N/A rep.revertTo = focus->revert;
0N/A WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
0N/A return Success;
0N/A}
0N/A
0N/Avoid
0N/APrintSiblings(p1)
0N/A WindowPtr p1;
0N/A{
0N/A WindowPtr p2;
0N/A
0N/A if (p1 == NULL || p1->parent == NULL) return;
0N/A
0N/A p2 = p1->parent->firstChild;
0N/A while (p2)
0N/A {
0N/A ErrorF( "(%x, %d, %d, %x)\n", p2, p2->drawable.width,
0N/A p2->drawable.height, p2->prevSib);
0N/A p2 = p2->nextSib;
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * Checks that tpwin & its siblings have same
0N/A * parents. Returns 0 if OK, a # indicating which
0N/A * Sibling has a bad parent
0N/A */
0N/Aint
0N/ACheckTPWin()
0N/A{
0N/A WindowPtr pWin;
0N/A int count = 1;
0N/A
0N/A pWin = tpwin->nextSib;
0N/A while (pWin)
0N/A {
0N/A if (pWin->parent->parent)
0N/A return count;
0N/A pWin = pWin->nextSib;
0N/A ++count;
0N/A }
0N/A return 0;
0N/A}
0N/A
0N/A/* NEW */
0N/A
0N/Aint
0N/AProcTsolGetGeometry(client)
0N/A register ClientPtr client;
0N/A{
0N/A xGetGeometryReply rep;
0N/A int status;
0N/A
0N/A REQUEST(xResourceReq);
0N/A
0N/A if ((status = GetGeometry(client, &rep)) != Success)
0N/A return status;
0N/A
0N/A /* Reduce root window height = stripe height */
0N/A if (stuff->id == rep.root)
0N/A {
0N/A extern unsigned int StripeHeight;
0N/A rep.height -= StripeHeight;
0N/A }
0N/A
0N/A WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
0N/A return(client->noClientException);
0N/A}
0N/A
0N/Aint
0N/AProcTsolGrabServer(client)
0N/A register ClientPtr client;
0N/A{
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A REQUEST(xResourceReq);
0N/A REQUEST_SIZE_MATCH(xReq);
0N/A
0N/A if (xtsol_policy(TSOL_RES_SRVGRAB, TSOL_CREATE, NULL,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A /* turn off auditing because operation ignored */
0N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A
0N/A return(client->noClientException);
0N/A }
0N/A
0N/A return (*TsolSavedProcVector[X_GrabServer])(client);
0N/A}
0N/A
0N/Aint
0N/AProcTsolUngrabServer(client)
0N/A register ClientPtr client;
0N/A{
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A REQUEST(xResourceReq);
0N/A REQUEST_SIZE_MATCH(xReq);
0N/A
0N/A if (xtsol_policy(TSOL_RES_SRVGRAB, TSOL_DESTROY, NULL,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A /* turn off auditing because operation ignored */
0N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A
0N/A return(client->noClientException);
0N/A }
0N/A
0N/A return (*TsolSavedProcVector[X_UngrabServer])(client);
0N/A}
0N/A
0N/Aint
0N/AProcTsolCreatePixmap(client)
0N/A register ClientPtr client;
0N/A{
0N/A PixmapPtr pMap;
0N/A int result;
0N/A
0N/A REQUEST(xCreatePixmapReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xCreatePixmapReq);
0N/A
0N/A result = (*TsolSavedProcVector[X_CreatePixmap])(client);
0N/A
0N/A pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->pid, RT_PIXMAP,
0N/A SecurityDestroyAccess);
0N/A if (pMap)
0N/A {
0N/A /* Initialize security info */
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pMap->devPrivates[tsolPixmapPrivateIndex].ptr);
0N/A
0N/A if (tsolinfo == NULL || client == serverClient)
0N/A {
0N/A /* Client is Server itself */
0N/A tsolres->uid = 0;
0N/A tsolres->sl = (bslabel_t *)lookupSL_low();
0N/A }
0N/A else
0N/A {
0N/A tsolres->uid = tsolinfo->uid;
0N/A tsolres->sl = tsolinfo->sl;
0N/A }
0N/A tsolres->flags = 0;
0N/A }
0N/A
0N/A return result;
0N/A}
0N/Aint
0N/AProcTsolSetScreenSaver(client)
0N/A register ClientPtr client;
0N/A{
0N/A int result;
0N/A
0N/A REQUEST(xSetScreenSaverReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xSetScreenSaverReq);
0N/A
0N/A if (result = xtsol_policy(TSOL_RES_SCRSAVER, TSOL_MODIFY, NULL,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A return (result);
0N/A
0N/A return (*TsolSavedProcVector[X_SetScreenSaver])(client);
0N/A}
0N/A
0N/Aint
0N/AProcTsolChangeHosts(client)
0N/A register ClientPtr client;
0N/A{
0N/A int result;
36N/A int savedtrust = client->trustLevel;
0N/A
0N/A REQUEST(xChangeHostsReq);
0N/A
0N/A REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
0N/A
0N/A if (result = xtsol_policy(TSOL_RES_ACL, TSOL_MODIFY, NULL,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A return (result);
0N/A
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A result = (*TsolSavedProcVector[X_ChangeHosts])(client);
36N/A client->trustLevel = savedtrust;
36N/A
36N/A return (result);
0N/A}
0N/A
0N/Aint
0N/AProcTsolChangeAccessControl(client)
0N/A register ClientPtr client;
0N/A{
0N/A int result;
36N/A int savedtrust = client->trustLevel;
0N/A
0N/A REQUEST(xSetAccessControlReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xSetAccessControlReq);
0N/A
0N/A if (result = xtsol_policy(TSOL_RES_ACL, TSOL_MODIFY,
0N/A (void *)stuff->mode, client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A client->errorValue = stuff->mode;
0N/A return (result);
0N/A }
0N/A
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A result = (*TsolSavedProcVector[X_SetAccessControl])(client);
36N/A client->trustLevel = savedtrust;
36N/A
36N/A return (result);
0N/A}
0N/A
0N/Aint
0N/AProcTsolKillClient(client)
0N/A register ClientPtr client;
0N/A{
0N/A int result;
0N/A
0N/A REQUEST(xResourceReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xResourceReq);
0N/A
0N/A if (result = xtsol_policy(TSOL_RES_CLIENT, TSOL_DESTROY,
0N/A (void *)stuff->id, client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (result);
0N/A }
0N/A
0N/A return (*TsolSavedProcVector[X_KillClient])(client);
0N/A}
0N/A
0N/Aint
0N/AProcTsolSetFontPath(client)
0N/A register ClientPtr client;
0N/A{
0N/A REQUEST(xSetFontPathReq);
0N/A
0N/A REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
0N/A
0N/A if (xtsol_policy(TSOL_RES_FONTPATH, TSOL_MODIFY, NULL,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A return (BadValue);
0N/A }
0N/A
0N/A return (*TsolSavedProcVector[X_SetFontPath])(client);
0N/A}
0N/A
0N/Aint
0N/AProcTsolChangeCloseDownMode(client)
0N/A register ClientPtr client;
0N/A{
0N/A REQUEST(xSetCloseDownModeReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
0N/A
0N/A if (xtsol_policy(TSOL_RES_CLIENT, TSOL_MODIFY, NULL,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A return (client->noClientException); /* Ignore error */
0N/A
0N/A return (*TsolSavedProcVector[X_SetCloseDownMode])(client);
0N/A}
0N/A
0N/Aint ProcTsolForceScreenSaver(client)
0N/A register ClientPtr client;
0N/A{
0N/A int result;
0N/A
0N/A REQUEST(xForceScreenSaverReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xForceScreenSaverReq);
0N/A
0N/A
0N/A if (result = xtsol_policy(TSOL_RES_SCRSAVER, TSOL_MODIFY, NULL,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A return (result);
0N/A
0N/A return (*TsolSavedProcVector[X_ForceScreenSaver])(client);
0N/A}
0N/A
0N/Avoid
0N/ATsolDeleteWindowFromAnySelections(pWin)
0N/A WindowPtr pWin;
0N/A{
0N/A register int i;
0N/A TsolSelnPtr tsolseln = NULL;
0N/A TsolSelnPtr prevtsolseln = NULL;
0N/A
0N/A for (i = 0; i< NumCurrentSelections; i++)
0N/A {
0N/A if (PolySelection(CurrentSelections[i].selection))
0N/A {
0N/A tsolseln = (TsolSelnPtr)CurrentSelections[i].secPrivate;
0N/A prevtsolseln = tsolseln;
0N/A while (tsolseln)
0N/A {
0N/A if (tsolseln->pWin == pWin)
0N/A break; /* match found */
0N/A prevtsolseln = tsolseln;
0N/A tsolseln = tsolseln->next;
0N/A }
0N/A
0N/A if (tsolseln)
0N/A {
0N/A if (SelectionCallback)
0N/A {
0N/A SelectionInfoRec info;
0N/A
0N/A info.selection = &CurrentSelections[i];
0N/A info.kind = SelectionClientClose;
0N/A CallCallbacks(&SelectionCallback, &info);
0N/A }
0N/A
0N/A /* first on the list */
0N/A if (prevtsolseln == tsolseln)
0N/A CurrentSelections[i].secPrivate = (pointer)tsolseln->next;
0N/A else
0N/A prevtsolseln->next = tsolseln->next;
0N/A xfree(tsolseln);
0N/A
0N/A /* handle the last reference */
0N/A if (CurrentSelections[i].secPrivate == NULL)
0N/A {
0N/A CurrentSelections[i].pWin = (WindowPtr)NULL;
0N/A CurrentSelections[i].window = None;
0N/A CurrentSelections[i].client = NullClient;
0N/A }
0N/A }
0N/A }
0N/A else
0N/A {
0N/A if (CurrentSelections[i].pWin == pWin)
0N/A {
0N/A CurrentSelections[i].pWin = (WindowPtr)NULL;
0N/A CurrentSelections[i].window = None;
0N/A CurrentSelections[i].client = NullClient;
0N/A }
0N/A }
0N/A }
0N/A}
0N/A
0N/Avoid
0N/ATsolDeleteClientFromAnySelections(client)
0N/A ClientPtr client;
0N/A{
0N/A register int i;
0N/A TsolSelnPtr tsolseln = NULL;
0N/A TsolSelnPtr prevtsolseln = NULL;
0N/A
0N/A for (i = 0; i< NumCurrentSelections; i++)
0N/A {
0N/A if (PolySelection(CurrentSelections[i].selection))
0N/A {
0N/A tsolseln = (TsolSelnPtr)CurrentSelections[i].secPrivate;
0N/A prevtsolseln = tsolseln;
0N/A while (tsolseln)
0N/A {
0N/A if (tsolseln->client == client)
0N/A break; /* match found */
0N/A prevtsolseln = tsolseln;
0N/A tsolseln = tsolseln->next;
0N/A }
0N/A
0N/A if (tsolseln)
0N/A {
0N/A if (SelectionCallback)
0N/A {
0N/A SelectionInfoRec info;
0N/A
0N/A info.selection = &CurrentSelections[i];
0N/A info.kind = SelectionClientClose;
0N/A CallCallbacks(&SelectionCallback, &info);
0N/A }
0N/A
0N/A /* first on the list */
0N/A if (prevtsolseln == tsolseln)
0N/A CurrentSelections[i].secPrivate = (pointer)tsolseln->next;
0N/A else
0N/A prevtsolseln->next = tsolseln->next;
0N/A xfree(tsolseln);
0N/A
0N/A /* handle the last reference */
0N/A if (CurrentSelections[i].secPrivate == NULL)
0N/A {
0N/A CurrentSelections[i].pWin = (WindowPtr)NULL;
0N/A CurrentSelections[i].window = None;
0N/A CurrentSelections[i].client = NullClient;
0N/A }
0N/A }
0N/A }
0N/A else
0N/A {
0N/A if (CurrentSelections[i].client == client)
0N/A {
0N/A CurrentSelections[i].pWin = (WindowPtr)NULL;
0N/A CurrentSelections[i].window = None;
0N/A CurrentSelections[i].client = NullClient;
0N/A }
0N/A }
0N/A }
0N/A}
0N/A
0N/Aint
0N/AProcTsolListInstalledColormaps(client)
0N/A register ClientPtr client;
0N/A{
0N/A xListInstalledColormapsReply *preply;
0N/A int nummaps;
0N/A WindowPtr pWin;
0N/A REQUEST(xResourceReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xResourceReq);
0N/A pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
0N/A SecurityReadAccess);
0N/A
0N/A if (!pWin)
0N/A return(BadWindow);
0N/A
0N/A preply = (xListInstalledColormapsReply *)
0N/A ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
0N/A pWin->drawable.pScreen->maxInstalledCmaps *
0N/A sizeof(Colormap));
0N/A if(!preply)
0N/A return(BadAlloc);
0N/A
0N/A preply->type = X_Reply;
0N/A preply->sequenceNumber = client->sequence;
0N/A nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
0N/A (pWin->drawable.pScreen, (Colormap *)&preply[1]);
0N/A preply->nColormaps = nummaps;
0N/A preply->length = nummaps;
0N/A#ifdef TSOL
0N/A {
0N/A int err_code, i;
0N/A Colormap *pcmap = (Colormap *)&preply[1];
0N/A ColormapPtr pcmp;
0N/A
0N/A /*
0N/A * check every colormap id for access. return default colormap
0N/A * id in case of failure
0N/A */
0N/A for (i = 0; i < nummaps; i++, pcmap++)
0N/A {
0N/A pcmp = (ColormapPtr )LookupIDByType(*pcmap, RT_COLORMAP);
0N/A if (err_code = xtsol_policy(TSOL_RES_CMAP, TSOL_READ, pcmp,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A *pcmap = pWin->drawable.pScreen->defColormap;
0N/A }
0N/A }
0N/A }
0N/A#endif /* TSOL */
0N/A WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
0N/A client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
0N/A WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
0N/A DEALLOCATE_LOCAL(preply);
0N/A return(client->noClientException);
0N/A}
0N/A
0N/A
0N/Aint
0N/AProcTsolQueryTree(client)
0N/A register ClientPtr client;
0N/A{
0N/A xQueryTreeReply reply;
0N/A int numChildren = 0;
0N/A register WindowPtr pChild, pWin, pHead;
0N/A Window *childIDs = (Window *)NULL;
0N/A#if defined(PANORAMIX) && !defined(IN_MODULE)
0N/A PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
0N/A int j, thisScreen;
0N/A#endif
0N/A
0N/A#ifdef TSOL
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A#endif /* TSOL */
0N/A
0N/A REQUEST(xResourceReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xResourceReq);
0N/A pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
0N/A SecurityReadAccess);
0N/A if (!pWin)
0N/A return(BadWindow);
0N/A
0N/A#ifdef TSOL
0N/A if (xtsol_policy(TSOL_RES_WINDOW, TSOL_READ, pWin,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A return(BadWindow);
0N/A }
0N/A /*
0N/A * Because of its recursive nature, QuerryTree can leave a huge trail
0N/A * of audit records which could make deciphering the audit log for
0N/A * critical records difficult. So we turn off any more auditing of
0N/A * this protocol.
0N/A */
0N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A#endif /* TSOL */
0N/A
0N/A reply.type = X_Reply;
0N/A reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
0N/A reply.sequenceNumber = client->sequence;
0N/A if (pWin->parent)
0N/A reply.parent = pWin->parent->drawable.id;
0N/A else
0N/A reply.parent = (Window)None;
0N/A#if defined(SUNSOFT) && defined(PANORAMIX) && !defined(IN_MODULE)
0N/A if ( !noPanoramiXExtension ) {
0N/A thisScreen = 0;
0N/A for (j = 0; j <= PanoramiXNumScreens - 1; j++) {
0N/A if ( pWin->winSize.extents.x1 < (panoramiXdataPtr[j].x +
0N/A panoramiXdataPtr[j].width)) {
0N/A thisScreen = j;
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A if ( !noPanoramiXExtension && thisScreen ) {
0N/A PANORAMIXFIND_ID(pPanoramiXWin, pWin->drawable.id);
0N/A IF_RETURN(!pPanoramiXWin, BadWindow);
0N/A pWin =
0N/A (WindowPtr)SecurityLookupWindow(pPanoramiXWin->info[thisScreen].id,
0N/A client,
0N/A SecurityReadAccess);
0N/A if (!pWin)
0N/A return(BadWindow);
0N/A pHead = RealChildHead(pWin);
0N/A for(pChild = pWin->lastChild;pChild != pHead; pChild = pChild->prevSib)
0N/A numChildren++;
0N/A if (numChildren)
0N/A {
0N/A int curChild = 0;
0N/A childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
0N/A if (!childIDs)
0N/A return BadAlloc;
0N/A for (pChild = pWin->lastChild; pChild != pHead;
0N/A pChild = pChild->prevSib) {
0N/A pPanoramiXWin = PanoramiXWinRoot;
0N/A PANORAMIXFIND_ID_BY_SCRNUM(pPanoramiXWin, pChild->drawable.id,
0N/A thisScreen);
0N/A IF_RETURN(!pPanoramiXWin, BadWindow);
0N/A childIDs[curChild++] = pPanoramiXWin->info[0].id;
0N/A }
0N/A } /* numChildren */
0N/A }else { /* otherwise its screen 0, and nothing changes */
0N/A pHead = RealChildHead(pWin);
0N/A for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
0N/A#ifdef TSOL
0N/A {
0N/A /* error ignored */
0N/A if (!xtsol_policy(TSOL_RES_WINDOW, TSOL_READ, pChild,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A numChildren++;
0N/A }
0N/A }
0N/A#else /* !TSOL */
0N/A numChildren++;
0N/A#endif /* TSOL */
0N/A if (numChildren)
0N/A {
0N/A int curChild = 0;
0N/A
0N/A childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
0N/A if (!childIDs)
0N/A return BadAlloc;
0N/A for (pChild = pWin->lastChild; pChild != pHead;
0N/A pChild = pChild->prevSib)
0N/A#ifdef TSOL
0N/A {
0N/A
0N/A /* error ignored */
0N/A if (!xtsol_policy(TSOL_RES_WINDOW, TSOL_READ, pChild,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A childIDs[curChild++] = pChild->drawable.id;
0N/A }
0N/A }
0N/A#else /* !TSOL */
0N/A childIDs[curChild++] = pChild->drawable.id;
0N/A#endif /* TSOL */
0N/A }
0N/A }
0N/A#else
0N/A pHead = RealChildHead(pWin);
0N/A for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
0N/A#ifdef TSOL
0N/A {
0N/A /* error ignored */
0N/A if (!xtsol_policy(TSOL_RES_WINDOW, TSOL_READ, pChild,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A numChildren++;
0N/A }
0N/A }
0N/A#else /* !TSOL */
0N/A numChildren++;
0N/A#endif /* TSOL */
0N/A if (numChildren)
0N/A {
0N/A int curChild = 0;
0N/A
0N/A childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
0N/A if (!childIDs)
0N/A return BadAlloc;
0N/A for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
0N/A#ifdef TSOL
0N/A {
0N/A
0N/A /* error ignored */
0N/A if (!xtsol_policy(TSOL_RES_WINDOW, TSOL_READ, pChild,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A {
0N/A childIDs[curChild++] = pChild->drawable.id;
0N/A }
0N/A }
0N/A#else /* !TSOL */
0N/A childIDs[curChild++] = pChild->drawable.id;
0N/A#endif /* TSOL */
0N/A }
0N/A#endif
0N/A
0N/A reply.nChildren = numChildren;
0N/A reply.length = (numChildren * sizeof(Window)) >> 2;
0N/A
0N/A WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
0N/A if (numChildren)
0N/A {
0N/A client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
0N/A WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
0N/A DEALLOCATE_LOCAL(childIDs);
0N/A }
0N/A
0N/A return(client->noClientException);
0N/A}
0N/A
0N/Avoid
0N/ATsolAuditStart(ClientPtr client)
0N/A{
0N/A extern Bool system_audit_on;
0N/A unsigned int protocol;
0N/A int xevent_num;
0N/A int count = 0;
0N/A int status = 0;
0N/A Bool do_x_audit = FALSE;
0N/A Bool audit_event = FALSE;
0N/A char audit_ret = (char)NULL;
0N/A TsolInfoPtr tsolinfo = (TsolInfoPtr)NULL;
0N/A tsolinfo = GetClientTsolInfo(client);
36N/A if (system_audit_on &&
36N/A (tsolinfo->amask.am_success || tsolinfo->amask.am_failure)) {
36N/A
36N/A do_x_audit = TRUE;
36N/A auditwrite(AW_PRESELECT, &(tsolinfo->amask), AW_END);
36N/A
36N/A /*
36N/A * X audit events start from 9101 in audit_uevents.h. The first two
36N/A * events are non-protocol ones viz. ClientConnect, mapped to 9101
36N/A * and ClientDisconnect, mapped to 9102.
36N/A * The protocol events are mapped from 9103 onwards in the serial
36N/A * order of their respective protocol opcode, for eg, the protocol
36N/A * UngrabPointer which is has a protocol opcode 27 is mapped to
36N/A * 9129 (9102 + 27).
36N/A * All extension protocols are mapped to a single audit event
36N/A * AUE_XExtension as opcodes are assigined dynamically to these
36N/A * protocols. We set the extension protocol opcode to be 128, one
36N/A * more than the last standard opcode.
36N/A */
36N/A protocol = (unsigned int)MAJOROP;
36N/A if (protocol > X_NoOperation) {
36N/A xevent_num = audit_eventsid[MAX_AUDIT_EVENTS - 1][1];
36N/A audit_event = TRUE;
36N/A } else {
36N/A for (count = 0; count < MAX_AUDIT_EVENTS; count++) {
36N/A if (protocol == audit_eventsid[count][0]) {
36N/A xevent_num = audit_eventsid[count][1];
0N/A audit_event = TRUE;
0N/A break;
36N/A }
36N/A }
36N/A }
0N/A
36N/A /*
36N/A * Exclude Clients with Trusted Path such as tsoldtwm, tsoldtsession etc
36N/A * from generating the audit records for X protocols
36N/A */
36N/A if (audit_event && do_x_audit && !HasTrustedPath(tsolinfo) &&
36N/A (au_preselect(xevent_num, &(tsolinfo->amask), AU_PRS_BOTH,
36N/A AU_PRS_USECACHE) == 1)) {
36N/A tsolinfo->flags |= TSOL_AUDITEVENT;
36N/A status = auditwrite(AW_EVENTNUM, xevent_num, AW_APPEND, AW_END);
36N/A } else {
36N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
36N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
36N/A }
36N/A }
0N/A}
0N/A
0N/Avoid
0N/ATsolAuditEnd(ClientPtr client, int result)
0N/A{
0N/A extern Bool system_audit_on;
0N/A unsigned int protocol;
0N/A int xevent_num;
0N/A int count = 0;
0N/A int status = 0;
0N/A Bool do_x_audit = FALSE;
0N/A Bool audit_event = FALSE;
0N/A char audit_ret = (char)NULL;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (tsolinfo->flags & TSOL_DOXAUDIT)
0N/A {
0N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A if (result != Success)
0N/A audit_ret = -1;
0N/A else
0N/A audit_ret = 0;
0N/A auditwrite(AW_RETURN, audit_ret, (u_int)result,
0N/A AW_WRITE, AW_END);
0N/A }
0N/A else if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A {
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A auditwrite(AW_DISCARDRD, -1, AW_END);
0N/A }
0N/A}
0N/A
0N/Aint
0N/AProcTsolQueryPointer(client)
0N/A ClientPtr client;
0N/A{
0N/A xQueryPointerReply rep;
0N/A WindowPtr pWin, t, ptrWin;
0N/A REQUEST(xResourceReq);
0N/A DeviceIntPtr mouse = inputInfo.pointer;
0N/A
0N/A REQUEST_SIZE_MATCH(xResourceReq);
0N/A pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
0N/A if (!pWin)
0N/A return BadWindow;
0N/A
0N/A ptrWin = TsolPointerWindow();
0N/A if (!xtsol_policy(TSOL_RES_WINDOW, TSOL_READ, ptrWin,
0N/A client, TSOL_ALL, (void *)MAJOROP))
0N/A return (*TsolSavedProcVector[X_QueryPointer])(client);
0N/A
0N/A if (mouse->valuator->motionHintWindow)
0N/A MaybeStopHint(mouse, client);
0N/A rep.type = X_Reply;
0N/A rep.sequenceNumber = client->sequence;
0N/A rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
0N/A rep.length = 0;
0N/A rep.root = RootOf(pWin);
0N/A rep.rootX = 0;
0N/A rep.rootY = 0;
0N/A rep.child = None;
0N/A rep.sameScreen = xTrue;
0N/A rep.winX = 0;
0N/A rep.winY = 0;
0N/A
0N/A WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
0N/A
0N/A return(Success);
0N/A}
36N/A
36N/Aint
36N/AProcTsolQueryExtension(client)
36N/A ClientPtr client;
36N/A{
36N/A xQueryExtensionReply reply;
36N/A int savedtrust;
36N/A int status = client->noClientException;
36N/A
36N/A REQUEST(xQueryExtensionReq);
36N/A
36N/A REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
36N/A
36N/A reply.type = X_Reply;
36N/A reply.length = 0;
36N/A reply.major_opcode = 0;
36N/A reply.sequenceNumber = client->sequence;
36N/A
36N/A /* Allow extensions in the labeled zones */
36N/A savedtrust = client->trustLevel;
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A
36N/A if (!TsolDisabledExtension((char *)&stuff[1], stuff->nbytes)) {
36N/A status = (*TsolSavedProcVector[X_QueryExtension])(client);
36N/A } else {
36N/A /* Hide this extension */
36N/A reply.present = xFalse;
36N/A WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
36N/A status = client->noClientException;
36N/A }
36N/A
36N/A client->trustLevel = savedtrust;
36N/A
36N/A return (status);
36N/A}
36N/A
36N/Aint
36N/AProcTsolListExtensions(client)
36N/A ClientPtr client;
36N/A{
36N/A int savedtrust;
36N/A int status;
36N/A
36N/A REQUEST(xReq);
36N/A REQUEST_SIZE_MATCH(xReq);
36N/A
36N/A /* Allow extensions in the labeled zones */
36N/A savedtrust = client->trustLevel;
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A status = (*TsolSavedProcVector[X_ListExtensions])(client);
36N/A client->trustLevel = savedtrust;
36N/A
36N/A return (status);
36N/A}
36N/A
36N/Aint
36N/AProcTsolMapWindow(register ClientPtr client)
36N/A{
36N/A int savedtrust;
36N/A
36N/A WindowPtr pWin;
36N/A REQUEST(xResourceReq);
36N/A
36N/A REQUEST_SIZE_MATCH(xResourceReq);
36N/A pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
36N/A SecurityReadAccess);
36N/A if (!pWin)
36N/A return(BadWindow);
36N/A savedtrust = client->trustLevel;
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A MapWindow(pWin, client);
36N/A client->trustLevel = savedtrust;
36N/A
36N/A return(client->noClientException);
36N/A}
36N/A
36N/Aint
36N/AProcTsolMapSubwindows(register ClientPtr client)
36N/A{
36N/A int savedtrust;
36N/A
36N/A WindowPtr pWin;
36N/A REQUEST(xResourceReq);
36N/A
36N/A REQUEST_SIZE_MATCH(xResourceReq);
36N/A pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
36N/A SecurityReadAccess);
36N/A if (!pWin)
36N/A return(BadWindow);
36N/A savedtrust = client->trustLevel;
36N/A client->trustLevel = XSecurityClientTrusted;
36N/A MapSubwindows(pWin, client);
36N/A client->trustLevel = savedtrust;
36N/A
36N/A return(client->noClientException);
36N/A}
64N/A
64N/Astatic int
64N/ATsolDoGetImage(client, format, drawable, x, y, width, height, planemask, im_return)
64N/A register ClientPtr client;
64N/A Drawable drawable;
64N/A int format;
64N/A int x, y, width, height;
64N/A Mask planemask;
64N/A xGetImageReply **im_return;
64N/A{
64N/A register DrawablePtr pDraw;
64N/A int nlines, linesPerBuf;
64N/A register int linesDone;
64N/A long widthBytesLine, length;
64N/A Mask plane = 0;
64N/A char *pBuf;
64N/A xGetImageReply xgi;
64N/A RegionPtr pVisibleRegion = NULL;
64N/A
64N/A#ifdef TSOL
64N/A Bool getimage_ok = TRUE; /* if false get all 0s */
64N/A Bool overlap = FALSE;
64N/A Bool not_root_window = FALSE;
64N/A WindowPtr pHead, pWin, pRoot, pChild;
64N/A TsolResPtr tsolres_win;
64N/A BoxRec winbox, box;
64N/A BoxPtr pwinbox;
64N/A DrawablePtr pDrawtmp;
64N/A#endif /* TSOL */
64N/A
64N/A if ((format != XYPixmap) && (format != ZPixmap))
64N/A {
64N/A client->errorValue = format;
64N/A return(BadValue);
64N/A }
64N/A SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
73N/A
73N/A#ifdef TSOL
73N/A if (!xtsol_policy(TSOL_RES_PIXEL, TSOL_READ,
73N/A pDraw, client, TSOL_ALL, (void *)MAJOROP) &&
73N/A (DrawableIsRoot(pDraw) || !tsolMultiLevel))
64N/A {
73N/A return DoGetImage(client, format, drawable, x, y,
73N/A width, height, planemask, im_return);
73N/A }
73N/A
73N/A if (pDraw->type == DRAWABLE_WINDOW)
73N/A {
64N/A if (DrawableIsRoot(pDraw))
64N/A {
73N/A pWin = XYToWindow(x, y);
64N/A if (!WindowIsRoot(pWin))
64N/A {
64N/A pDrawtmp = &(pWin->parent->drawable);
64N/A if (((WindowPtr) pDrawtmp)->realized)
64N/A {
73N/A int tmpx, tmpy;
73N/A
73N/A tmpx = x - pDrawtmp->x;
73N/A tmpy = y - pDrawtmp->y;
73N/A
73N/A /* requested area must be a subset of the window area */
73N/A if (tmpx >= 0 && tmpy >= 0 &&
73N/A width <= pDrawtmp->width &&
73N/A height <= pDrawtmp->height)
73N/A {
73N/A pDraw = pDrawtmp;
73N/A x = tmpx;
73N/A y = tmpy;
73N/A not_root_window = TRUE;
73N/A }
64N/A }
64N/A }
64N/A }
64N/A else
64N/A {
64N/A not_root_window = TRUE;
64N/A }
64N/A
64N/A if (not_root_window)
64N/A {
64N/A Window root;
64N/A WindowPtr tmpwin;
64N/A
73N/A not_root_window = TRUE;
64N/A tmpwin = (WindowPtr)LookupWindow(pDraw->id, client);
64N/A while (tmpwin)
64N/A {
64N/A if (tmpwin->parent && WindowIsRoot(tmpwin->parent))
64N/A {
64N/A pWin = tmpwin;
64N/A break;
64N/A }
64N/A tmpwin = tmpwin->parent;
64N/A }
64N/A pwinbox = WindowExtents(pWin, &winbox);
64N/A box.x1 = pwinbox->x1;
64N/A box.y1 = pwinbox->y1;
64N/A box.x2 = pwinbox->x2;
64N/A box.y2 = box.y1;
64N/A tsolres_win =
64N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
64N/A root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
64N/A pRoot = (WindowPtr)LookupIDByType(root, RT_WINDOW);
64N/A pHead = pRoot->firstChild;
64N/A }
64N/A
64N/A if (xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, pDraw,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A getimage_ok = FALSE;
73N/A else
73N/A getimage_ok = TRUE;
73N/A }
64N/A#endif /* TSOL */
64N/A
73N/A if(pDraw->type == DRAWABLE_WINDOW)
73N/A {
73N/A
64N/A if( /* check for being viewable */
64N/A !((WindowPtr) pDraw)->realized ||
64N/A /* check for being on screen */
64N/A pDraw->x + x < 0 ||
64N/A pDraw->x + x + width > pDraw->pScreen->width ||
64N/A pDraw->y + y < 0 ||
64N/A pDraw->y + y + height > pDraw->pScreen->height ||
64N/A /* check for being inside of border */
64N/A x < - wBorderWidth((WindowPtr)pDraw) ||
64N/A x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
64N/A y < -wBorderWidth((WindowPtr)pDraw) ||
64N/A y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
64N/A )
64N/A return(BadMatch);
64N/A xgi.visual = wVisual (((WindowPtr) pDraw));
64N/A }
64N/A else
64N/A {
64N/A if(x < 0 ||
64N/A x+width > (int)pDraw->width ||
64N/A y < 0 ||
64N/A y+height > (int)pDraw->height
64N/A )
64N/A return(BadMatch);
64N/A xgi.visual = None;
64N/A }
64N/A
64N/A SET_DBE_SRCBUF(pDraw, drawable);
64N/A
64N/A xgi.type = X_Reply;
64N/A xgi.sequenceNumber = client->sequence;
64N/A xgi.depth = pDraw->depth;
64N/A if(format == ZPixmap)
64N/A {
64N/A widthBytesLine = PixmapBytePad(width, pDraw->depth);
64N/A length = widthBytesLine * height;
64N/A
64N/A }
64N/A else
64N/A {
64N/A widthBytesLine = BitmapBytePad(width);
64N/A plane = ((Mask)1) << (pDraw->depth - 1);
64N/A /* only planes asked for */
64N/A length = widthBytesLine * height *
64N/A Ones(planemask & (plane | (plane - 1)));
64N/A
64N/A }
64N/A
64N/A xgi.length = length;
64N/A
64N/A if (im_return) {
64N/A pBuf = (char *)xalloc(sz_xGetImageReply + length);
64N/A if (!pBuf)
64N/A return (BadAlloc);
64N/A if (widthBytesLine == 0)
64N/A linesPerBuf = 0;
64N/A else
64N/A linesPerBuf = height;
64N/A *im_return = (xGetImageReply *)pBuf;
64N/A *(xGetImageReply *)pBuf = xgi;
64N/A pBuf += sz_xGetImageReply;
64N/A } else {
64N/A xgi.length = (xgi.length + 3) >> 2;
64N/A if (widthBytesLine == 0 || height == 0)
64N/A linesPerBuf = 0;
64N/A else if (widthBytesLine >= IMAGE_BUFSIZE)
64N/A linesPerBuf = 1;
64N/A else
64N/A {
64N/A linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
64N/A if (linesPerBuf > height)
64N/A linesPerBuf = height;
64N/A }
64N/A length = linesPerBuf * widthBytesLine;
64N/A if (linesPerBuf < height)
64N/A {
64N/A /* we have to make sure intermediate buffers don't need padding */
64N/A while ((linesPerBuf > 1) &&
64N/A (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
64N/A {
64N/A linesPerBuf--;
64N/A length -= widthBytesLine;
64N/A }
64N/A while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
64N/A {
64N/A linesPerBuf++;
64N/A length += widthBytesLine;
64N/A }
64N/A }
64N/A if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
64N/A return (BadAlloc);
64N/A WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
64N/A }
64N/A
64N/A if (linesPerBuf == 0)
64N/A {
64N/A /* nothing to do */
64N/A }
64N/A else if (format == ZPixmap)
64N/A {
64N/A linesDone = 0;
64N/A while (height - linesDone > 0)
64N/A {
64N/A nlines = min(linesPerBuf, height - linesDone);
64N/A (*pDraw->pScreen->GetImage) (pDraw,
64N/A x,
64N/A y + linesDone,
64N/A width,
64N/A nlines,
64N/A format,
64N/A planemask,
64N/A (pointer) pBuf);
64N/A#ifdef TSOL
64N/A if (not_root_window)
64N/A {
64N/A WindowPtr over_win = (WindowPtr)NULL;
64N/A
64N/A box.y1 = y + linesDone + pDraw->y;
64N/A box.y2 = box.y1 + nlines;
64N/A over_win = AnyWindowOverlapsJustMe(pWin, pHead, &box);
64N/A if (over_win &&
64N/A xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, over_win,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A overlap = TRUE;
64N/A }
64N/A }
64N/A
64N/A /*
64N/A * fill the buffer with zeros in case of security failure
64N/A */
64N/A if (!getimage_ok || overlap)
64N/A {
64N/A if (overlap)
64N/A overlap = FALSE;
64N/A memset(pBuf, 0, (int)(nlines * widthBytesLine));
64N/A
64N/A }
64N/A#endif /* TSOL */
64N/A
64N/A /* Note that this is NOT a call to WriteSwappedDataToClient,
64N/A as we do NOT byte swap */
64N/A if (!im_return)
64N/A {
64N/A/* Don't split me, gcc pukes when you do */
64N/A (void)WriteToClient(client,
64N/A (int)(nlines * widthBytesLine),
64N/A pBuf);
64N/A }
64N/A linesDone += nlines;
64N/A }
64N/A }
64N/A else /* XYPixmap */
64N/A {
64N/A for (; plane; plane >>= 1)
64N/A {
64N/A if (planemask & plane)
64N/A {
64N/A linesDone = 0;
64N/A while (height - linesDone > 0)
64N/A {
64N/A nlines = min(linesPerBuf, height - linesDone);
64N/A (*pDraw->pScreen->GetImage) (pDraw,
64N/A x,
64N/A y + linesDone,
64N/A width,
64N/A nlines,
64N/A format,
64N/A plane,
64N/A (pointer)pBuf);
64N/A#ifdef TSOL
64N/A if (not_root_window)
64N/A {
64N/A WindowPtr over_win = (WindowPtr)NULL;
64N/A
64N/A box.y1 = y + linesDone + pDraw->y;
64N/A box.y2 = box.y1 + nlines;
64N/A over_win = AnyWindowOverlapsJustMe(pWin, pHead, &box);
64N/A if (over_win &&
64N/A xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, over_win,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A overlap = TRUE;
64N/A }
64N/A }
64N/A /*
64N/A * fill the buffer with zeros in case of security failure
64N/A */
64N/A if (!getimage_ok || overlap)
64N/A {
64N/A if (overlap)
64N/A overlap = FALSE;
64N/A memset(pBuf, 0, (int)(nlines * widthBytesLine));
64N/A
64N/A }
64N/A#endif /* TSOL */
64N/A
64N/A /* Note: NOT a call to WriteSwappedDataToClient,
64N/A as we do NOT byte swap */
64N/A if (im_return) {
64N/A pBuf += nlines * widthBytesLine;
64N/A } else {
64N/A/* Don't split me, gcc pukes when you do */
64N/A (void)WriteToClient(client,
64N/A (int)(nlines * widthBytesLine),
64N/A pBuf);
64N/A }
64N/A linesDone += nlines;
64N/A }
64N/A }
64N/A }
64N/A }
64N/A
64N/A if (!im_return)
64N/A DEALLOCATE_LOCAL(pBuf);
64N/A return (client->noClientException);
64N/A}
64N/A
64N/Aint
64N/AProcTsolGetImage(client)
64N/A register ClientPtr client;
64N/A{
64N/A int status;
64N/A int savedtrust = client->trustLevel;
64N/A
64N/A client->trustLevel = XSecurityClientTrusted;
64N/A
64N/A REQUEST(xGetImageReq);
64N/A
64N/A REQUEST_SIZE_MATCH(xGetImageReq);
64N/A
64N/A status = TsolDoGetImage(client, stuff->format, stuff->drawable,
64N/A stuff->x, stuff->y,
64N/A (int)stuff->width, (int)stuff->height,
64N/A stuff->planeMask, (xGetImageReply **)NULL);
64N/A
64N/A client->trustLevel = savedtrust;
64N/A return (status);
64N/A}
64N/A
64N/Aint
64N/AProcTsolPolySegment(client)
64N/A register ClientPtr client;
64N/A{
64N/A int savedtrust;
64N/A int status;
64N/A GC *pGC;
64N/A DrawablePtr pDraw;
64N/A REQUEST(xPolySegmentReq);
64N/A
64N/A REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
64N/A
64N/A savedtrust = client->trustLevel;
64N/A client->trustLevel = XSecurityClientTrusted;
64N/A
64N/A VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
64N/A
64N/A if (xtsol_policy(TSOL_RES_PIXEL, TSOL_MODIFY, pDraw,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A /* ignore the error message for DnD zap effect */
64N/A return (client->noClientException);
64N/A }
64N/A if (xtsol_policy(TSOL_RES_GC, TSOL_READ, (void *)stuff->gc,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A client->errorValue = stuff->gc;
64N/A return (BadGC);
64N/A }
64N/A
64N/A status = (*TsolSavedProcVector[X_PolySegment])(client);
64N/A client->trustLevel = savedtrust;
64N/A
64N/A return (status);
64N/A}
64N/A
64N/Aint
64N/AProcTsolPolyRectangle (client)
64N/A register ClientPtr client;
64N/A{
64N/A int savedtrust;
64N/A int status;
64N/A GC *pGC;
64N/A DrawablePtr pDraw;
64N/A
64N/A REQUEST(xPolyRectangleReq);
64N/A REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
64N/A
64N/A savedtrust = client->trustLevel;
64N/A client->trustLevel = XSecurityClientTrusted;
64N/A
64N/A VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
64N/A
64N/A if (xtsol_policy(TSOL_RES_PIXEL, TSOL_MODIFY, pDraw,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A /* ignore the error message */
64N/A return (client->noClientException);
64N/A }
64N/A if (xtsol_policy(TSOL_RES_GC, TSOL_READ, (void *)stuff->gc,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A client->errorValue = stuff->gc;
64N/A return (BadGC);
64N/A }
64N/A
64N/A status = (*TsolSavedProcVector[X_PolyRectangle])(client);
64N/A client->trustLevel = savedtrust;
64N/A
64N/A return (status);
64N/A}
64N/A
64N/Aint
64N/AProcTsolCopyArea (client)
64N/A register ClientPtr client;
64N/A{
64N/A int savedtrust;
64N/A int status;
64N/A register DrawablePtr pDst;
64N/A register DrawablePtr pSrc;
64N/A register GC *pGC;
64N/A REQUEST(xCopyAreaReq);
64N/A
64N/A REQUEST_SIZE_MATCH(xCopyAreaReq);
64N/A
64N/A savedtrust = client->trustLevel;
64N/A client->trustLevel = XSecurityClientTrusted;
64N/A
64N/A VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
64N/A
64N/A if (stuff->dstDrawable != stuff->srcDrawable)
64N/A {
64N/A SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
64N/A SecurityReadAccess);
64N/A if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
64N/A {
64N/A client->errorValue = stuff->dstDrawable;
64N/A return (BadMatch);
64N/A }
64N/A }
64N/A else
64N/A pSrc = pDst;
64N/A
64N/A SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
64N/A
64N/A if (xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, pSrc,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A /* ignore the error message for DnD zap effect */
64N/A return(client->noClientException);
64N/A }
64N/A if (xtsol_policy(TSOL_RES_PIXEL, TSOL_MODIFY, pDst,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A /* ignore the error message for DnD zap effect */
64N/A return(client->noClientException);
64N/A }
64N/A if (xtsol_policy(TSOL_RES_GC, TSOL_READ, (void *)stuff->gc,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A client->errorValue = stuff->gc;
64N/A return (BadGC);
64N/A }
64N/A
64N/A status = (*TsolSavedProcVector[X_CopyArea])(client);
64N/A client->trustLevel = savedtrust;
64N/A
64N/A return (status);
64N/A}
64N/A
64N/Aint
64N/AProcTsolCopyPlane(client)
64N/A register ClientPtr client;
64N/A{
64N/A int savedtrust;
64N/A int status;
64N/A register DrawablePtr psrcDraw, pdstDraw;
64N/A register GC *pGC;
64N/A REQUEST(xCopyPlaneReq);
64N/A RegionPtr pRgn;
64N/A
64N/A REQUEST_SIZE_MATCH(xCopyPlaneReq);
64N/A
64N/A savedtrust = client->trustLevel;
64N/A client->trustLevel = XSecurityClientTrusted;
64N/A
64N/A VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
64N/A
64N/A if (stuff->dstDrawable != stuff->srcDrawable)
64N/A {
64N/A SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
64N/A SecurityReadAccess);
64N/A if (pdstDraw->pScreen != psrcDraw->pScreen)
64N/A {
64N/A client->errorValue = stuff->dstDrawable;
64N/A return (BadMatch);
64N/A }
64N/A }
64N/A else
64N/A psrcDraw = pdstDraw;
64N/A
64N/A SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
64N/A
64N/A if (xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, psrcDraw,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A /* ignore the error message for DnD zap effect */
64N/A return(client->noClientException);
64N/A }
64N/A if (xtsol_policy(TSOL_RES_PIXEL, TSOL_MODIFY, pdstDraw,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A /* ignore the error message for DnD zap effect */
64N/A return(client->noClientException);
64N/A }
64N/A if (xtsol_policy(TSOL_RES_GC, TSOL_READ, (void *)stuff->gc,
64N/A client, TSOL_ALL, (void *)MAJOROP))
64N/A {
64N/A client->errorValue = stuff->gc;
64N/A return (BadGC);
64N/A }
64N/A
64N/A status = (*TsolSavedProcVector[X_CopyPlane])(client);
64N/A client->trustLevel = savedtrust;
64N/A
64N/A return (status);
64N/A}