558 lines
18 KiB
C
558 lines
18 KiB
C
/* SPDX-License-Identifier: MIT OR X11
|
|
*
|
|
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
|
|
*/
|
|
#ifndef _XSERVER_DIX_PRIV_H
|
|
#define _XSERVER_DIX_PRIV_H
|
|
|
|
#include <X11/Xdefs.h>
|
|
|
|
/* This file holds global DIX settings to be used inside the Xserver,
|
|
* but NOT supposed to be accessed directly by external server modules like
|
|
* drivers or extension modules. Thus the definitions here are not part of the
|
|
* Xserver's module API/ABI.
|
|
*/
|
|
|
|
#include <X11/Xdefs.h>
|
|
#include <X11/Xfuncproto.h>
|
|
#include <X11/extensions/XI.h>
|
|
|
|
#include "dix/input_priv.h"
|
|
|
|
#include "include/callback.h"
|
|
#include "include/cursor.h"
|
|
#include "include/dix.h"
|
|
#include "include/events.h"
|
|
#include "include/gc.h"
|
|
#include "include/input.h"
|
|
#include "include/os.h"
|
|
#include "include/window.h"
|
|
|
|
/* server setting: maximum size for big requests */
|
|
#define MAX_BIG_REQUEST_SIZE 4194303
|
|
extern long maxBigRequestSize;
|
|
|
|
extern char dispatchExceptionAtReset;
|
|
extern int terminateDelay;
|
|
extern Bool touchEmulatePointer;
|
|
|
|
extern HWEventQueuePtr checkForInput[2];
|
|
|
|
/* -retro mode */
|
|
extern Bool party_like_its_1989;
|
|
|
|
static inline _X_NOTSAN Bool
|
|
InputCheckPending(void)
|
|
{
|
|
return (*checkForInput[0] != *checkForInput[1]);
|
|
}
|
|
|
|
void ClearWorkQueue(void);
|
|
void ProcessWorkQueue(void);
|
|
void ProcessWorkQueueZombies(void);
|
|
|
|
void CloseDownClient(ClientPtr client);
|
|
ClientPtr GetCurrentClient(void);
|
|
void InitClient(ClientPtr client, int i, void *ospriv);
|
|
|
|
/* lookup builtin color by name */
|
|
Bool dixLookupBuiltinColor(int screen,
|
|
char *name,
|
|
unsigned len,
|
|
unsigned short *pred,
|
|
unsigned short *pgreen,
|
|
unsigned short *pblue);
|
|
|
|
void DeleteWindowFromAnySaveSet(WindowPtr pWin);
|
|
|
|
#define VALIDATE_DRAWABLE_AND_GC(drawID, pDraw, mode) \
|
|
do { \
|
|
int tmprc = dixLookupDrawable(&(pDraw), drawID, client, M_ANY, mode); \
|
|
if (tmprc != Success) \
|
|
return tmprc; \
|
|
tmprc = dixLookupGC(&(pGC), stuff->gc, client, DixUseAccess); \
|
|
if (tmprc != Success) \
|
|
return tmprc; \
|
|
if ((pGC->depth != pDraw->depth) || (pGC->pScreen != pDraw->pScreen)) \
|
|
return BadMatch; \
|
|
if (pGC->serialNumber != pDraw->serialNumber) \
|
|
ValidateGC(pDraw, pGC); \
|
|
} while (0)
|
|
|
|
int dixLookupGC(GCPtr *result,
|
|
XID id,
|
|
ClientPtr client,
|
|
Mask access_mode);
|
|
|
|
int dixLookupClient(ClientPtr *result,
|
|
XID id,
|
|
ClientPtr client,
|
|
Mask access_mode);
|
|
|
|
Bool CreateConnectionBlock(void);
|
|
|
|
void EnableLimitedSchedulingLatency(void);
|
|
|
|
void DisableLimitedSchedulingLatency(void);
|
|
|
|
int dix_main(int argc, char *argv[], char *envp[]);
|
|
|
|
void SetMaskForEvent(int deviceid, Mask mask, int event);
|
|
|
|
void EnqueueEvent(InternalEvent *ev, DeviceIntPtr device);
|
|
|
|
void PlayReleasedEvents(void);
|
|
|
|
void ActivatePointerGrab(DeviceIntPtr mouse,
|
|
GrabPtr grab,
|
|
TimeStamp time,
|
|
Bool autoGrab);
|
|
|
|
void DeactivatePointerGrab(DeviceIntPtr mouse);
|
|
|
|
void ActivateKeyboardGrab(DeviceIntPtr keybd,
|
|
GrabPtr grab,
|
|
TimeStamp time,
|
|
Bool passive);
|
|
|
|
void DeactivateKeyboardGrab(DeviceIntPtr keybd);
|
|
|
|
BOOL ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win);
|
|
|
|
void AllowSome(ClientPtr client,
|
|
TimeStamp time,
|
|
DeviceIntPtr thisDev,
|
|
int newState);
|
|
|
|
void ReleaseActiveGrabs(ClientPtr client);
|
|
|
|
GrabPtr CheckPassiveGrabsOnWindow(WindowPtr pWin,
|
|
DeviceIntPtr device,
|
|
InternalEvent *event,
|
|
BOOL checkCore,
|
|
BOOL activate);
|
|
|
|
int DeliverDeviceEvents(WindowPtr pWin,
|
|
InternalEvent *event,
|
|
GrabPtr grab,
|
|
WindowPtr stopAt,
|
|
DeviceIntPtr dev);
|
|
|
|
int DeliverOneGrabbedEvent(InternalEvent *event,
|
|
DeviceIntPtr dev,
|
|
enum InputLevel level);
|
|
|
|
void DeliverTouchEvents(DeviceIntPtr dev,
|
|
TouchPointInfoPtr ti,
|
|
InternalEvent *ev,
|
|
XID resource);
|
|
|
|
Bool DeliverGestureEventToOwner(DeviceIntPtr dev,
|
|
GestureInfoPtr gi,
|
|
InternalEvent *ev);
|
|
|
|
void InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin);
|
|
void FreeSprite(DeviceIntPtr pDev);
|
|
void UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen);
|
|
|
|
Bool CheckDeviceGrabs(DeviceIntPtr device,
|
|
InternalEvent *event,
|
|
WindowPtr ancestor);
|
|
|
|
void DeliverFocusedEvent(DeviceIntPtr keybd,
|
|
InternalEvent *event,
|
|
WindowPtr window);
|
|
|
|
int DeliverGrabbedEvent(InternalEvent *event,
|
|
DeviceIntPtr thisDev,
|
|
Bool deactivateGrab);
|
|
|
|
void FreezeThisEventIfNeededForSyncGrab(DeviceIntPtr thisDev,
|
|
InternalEvent *event);
|
|
|
|
void FixKeyState(DeviceEvent *event, DeviceIntPtr keybd);
|
|
|
|
void RecalculateDeliverableEvents(WindowPtr pWin);
|
|
|
|
void DoFocusEvents(DeviceIntPtr dev,
|
|
WindowPtr fromWin,
|
|
WindowPtr toWin,
|
|
int mode);
|
|
|
|
int SetInputFocus(ClientPtr client,
|
|
DeviceIntPtr dev,
|
|
Window focusID,
|
|
CARD8 revertTo,
|
|
Time ctime,
|
|
Bool followOK);
|
|
|
|
int GrabDevice(ClientPtr client,
|
|
DeviceIntPtr dev,
|
|
unsigned this_mode,
|
|
unsigned other_mode,
|
|
Window grabWindow,
|
|
unsigned ownerEvents,
|
|
Time ctime,
|
|
GrabMask *mask,
|
|
int grabtype,
|
|
Cursor curs,
|
|
Window confineToWin,
|
|
CARD8 *status);
|
|
|
|
void InitEvents(void);
|
|
|
|
void CloseDownEvents(void);
|
|
|
|
void DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources);
|
|
|
|
Mask EventMaskForClient(WindowPtr pWin, ClientPtr client);
|
|
|
|
Bool CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev);
|
|
|
|
int SetClientPointer(ClientPtr client, DeviceIntPtr device);
|
|
|
|
Bool IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent *events);
|
|
|
|
int XItoCoreType(int xi_type);
|
|
|
|
Bool DevHasCursor(DeviceIntPtr pDev);
|
|
|
|
Bool IsPointerEvent(InternalEvent *event);
|
|
|
|
Bool IsTouchEvent(InternalEvent *event);
|
|
|
|
Bool IsGestureEvent(InternalEvent *event);
|
|
|
|
Bool IsGestureBeginEvent(InternalEvent *event);
|
|
|
|
Bool IsGestureEndEvent(InternalEvent *event);
|
|
|
|
void CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
|
|
|
|
int CorePointerProc(DeviceIntPtr dev, int what);
|
|
|
|
int CoreKeyboardProc(DeviceIntPtr dev, int what);
|
|
|
|
extern Bool whiteRoot;
|
|
|
|
extern volatile char isItTimeToYield;
|
|
|
|
/* bit values for dispatchException */
|
|
#define DE_RESET 1
|
|
#define DE_TERMINATE 2
|
|
#define DE_PRIORITYCHANGE 4 /* set when a client's priority changes */
|
|
|
|
extern volatile char dispatchException;
|
|
|
|
extern int ScreenSaverBlanking;
|
|
extern int ScreenSaverAllowExposures;
|
|
extern int defaultScreenSaverBlanking;
|
|
extern int defaultScreenSaverAllowExposures;
|
|
extern const char *display;
|
|
extern int displayfd;
|
|
extern Bool explicit_display;
|
|
|
|
extern Bool disableBackingStore;
|
|
extern Bool enableBackingStore;
|
|
|
|
/* in generated BuiltInAtoms.c */
|
|
void MakePredeclaredAtoms(void);
|
|
|
|
/*
|
|
* @brief mark event ID as critical
|
|
* @param event the event to add to the critical events bitmap
|
|
*/
|
|
void SetCriticalEvent(int event);
|
|
|
|
/**
|
|
* @brief try to deliver (single) event to interested parties.
|
|
*
|
|
* @param pWindow target window
|
|
* @param pEvent event to be delivered
|
|
* @param filter filter mask based on event type
|
|
* @param skipClient don't deliver to this client (if not NULL)
|
|
* @return TRUE when event was delivered
|
|
*/
|
|
Bool MaybeDeliverEventToClient(WindowPtr pWindow,
|
|
xEvent *pEvent,
|
|
Mask filter,
|
|
ClientPtr skipClient)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1,2);
|
|
|
|
/*
|
|
* @brief select window events to listen on
|
|
*
|
|
* @param pWindow window to listen on
|
|
* @param pClient the client that's listening on the events
|
|
* @param mask mask of events to listen on
|
|
* @return X error code
|
|
*/
|
|
XRetCode EventSelectForWindow(WindowPtr pWindow, ClientPtr pClient, Mask mask)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1,2);
|
|
|
|
/*
|
|
* @brief set block propagation of specific events on window
|
|
*
|
|
* @param pWindow window to act on
|
|
* @param pClient client to act on
|
|
* @param mask mask of events to not propagate
|
|
* @param checkOptional set to w/ TRUE when window's optional structure changed
|
|
* @return X error code
|
|
*/
|
|
int EventSuppressForWindow(WindowPtr pWindow,
|
|
ClientPtr pClient,
|
|
Mask mask,
|
|
Bool *checkOptional)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1,2,4);
|
|
|
|
/*
|
|
* @brief allocate new ClientRec and initialize it
|
|
*
|
|
* Returns NULL on allocation failure or when client limit reached.
|
|
*
|
|
* @param ospriv pointer to OS layer's internal data
|
|
* @return pointer to new ClientRec or NULL on failure
|
|
*/
|
|
ClientPtr NextAvailableClient(void *ospriv);
|
|
|
|
/*
|
|
* @brief mark exception on client - will be closed down later
|
|
*
|
|
* @param pClient pointer to client that has exception
|
|
*/
|
|
void MarkClientException(ClientPtr pClient)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1);
|
|
|
|
typedef Bool (*ClientSleepProcPtr) (ClientPtr client, void *closure);
|
|
|
|
/*
|
|
* @brief put a client to sleep
|
|
*
|
|
* @param pClient the client to put into sleep
|
|
* @param func called when client wakes up
|
|
* @param closure data passed to the callback function
|
|
*/
|
|
Bool ClientSleep(ClientPtr pClient, ClientSleepProcPtr func, void *closure)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1,2);
|
|
|
|
/*
|
|
* @brief signal to sleeping client there's work to do
|
|
*
|
|
* @param pClient the client to signal to
|
|
* @return TRUE on success
|
|
*/
|
|
Bool dixClientSignal(ClientPtr pClient)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1);
|
|
|
|
#define CLIENT_SIGNAL_ANY ((void *)-1)
|
|
/*
|
|
* @brief signal to all sleeping clients matching client, func, closure
|
|
*
|
|
* If any of the client, func and closure parameters may be CLIENT_SIGNAL_ANY,
|
|
* so those will be matching any value
|
|
*
|
|
* @param pClient match for client
|
|
* @param func match for callback function
|
|
* @param closure match for callback closure
|
|
* @return number of matched / queued clients
|
|
*/
|
|
int ClientSignalAll(ClientPtr pClient, ClientSleepProcPtr func, void *closure)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1,2);
|
|
|
|
/*
|
|
* @brief wake up a client and restart request processing of this client
|
|
*
|
|
* @param pClient pointer to client structure
|
|
*/
|
|
void ClientWakeup(ClientPtr pclient)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1);
|
|
|
|
/*
|
|
* @brief check whether client is asleep
|
|
*
|
|
* @param pClient pointer to client structure
|
|
* @return TRUE if client is sleeping and has no work to do
|
|
*/
|
|
Bool ClientIsAsleep(ClientPtr pClient)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1);
|
|
|
|
/*
|
|
* @brief send error packet (xError) to client
|
|
*
|
|
* @param pClient pointer to client structure
|
|
* @param majorCode major opcode of failed request
|
|
* @param minorCode minor opcode of failed request
|
|
* @param resId ID of resource the failure occured on
|
|
* @param errorCode error code value
|
|
*/
|
|
void SendErrorToClient(ClientPtr pClient,
|
|
CARD8 majorCode,
|
|
CARD16 minorCode,
|
|
XID resId,
|
|
BYTE errorCode)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1);
|
|
|
|
/*
|
|
* @brief send GraphicsExposure events for given region to client
|
|
|
|
* Sends a series of GraphicsExposure events spanning the given region to the
|
|
* client. If region is empty or NULL, sending NoExpose event instead.
|
|
*
|
|
+ @param pClient the client to send events to
|
|
* @param pRegion the region the events are based on
|
|
* @param drawable ID of the drawable the events are related to
|
|
* @param majorOpcode major opcode of request which caused the expose event
|
|
* @param minorOpcode minor opcode of request which caused the expose event
|
|
*/
|
|
void SendGraphicsExpose(ClientPtr pClient, RegionPtr pRegion, XID drawable,
|
|
BYTE majorOpcode, CARD16 minorOpcode)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1);
|
|
|
|
/*
|
|
* @brief alter the SaveSet of a window (see automatic reparenting when client gone)
|
|
*
|
|
* @param pClient pointer to client structure
|
|
* @param pWindow pointer to window structure whose SaveSet is changed
|
|
* @param mode what to do when client goes away
|
|
* @param toRoot TRUE to reparent to root when parent's client gone
|
|
* @param map TRUE if window shall remain mapped
|
|
* @return X return code
|
|
*/
|
|
XRetCode AlterSaveSetForClient(ClientPtr pClient,
|
|
WindowPtr pWin,
|
|
unsigned mode,
|
|
Bool toRoot,
|
|
Bool map);
|
|
|
|
/**
|
|
* @brief deliver the given events to the given client.
|
|
*
|
|
* More than one event may be delivered at a time. This is the case with
|
|
* DeviceMotionNotifies which may be followed by DeviceValuator events.
|
|
*
|
|
* TryClientEvents() is the last station before actually writing the events to
|
|
* the socket. Anything that is not filtered here, will get delivered to the
|
|
* client.
|
|
* An event is only delivered if
|
|
* - mask and filter match up.
|
|
* - no other client has a grab on the device that caused the event.
|
|
*
|
|
*
|
|
* @param client The target client to deliver to.
|
|
* @param dev The device the event came from. May be NULL.
|
|
* @param pEvents The events to be delivered.
|
|
* @param count Number of elements in pEvents.
|
|
* @param mask Event mask as set by the window.
|
|
* @param filter Mask based on event type.
|
|
* @param grab Possible grab on the device that caused the event.
|
|
*
|
|
* @return 1 if event was delivered, 0 if not or -1 if grab was not set by the
|
|
* client.
|
|
*/
|
|
int TryClientEvents(ClientPtr pClient,
|
|
DeviceIntPtr device,
|
|
xEventPtr pEvents,
|
|
size_t count,
|
|
Mask mask,
|
|
Mask filter,
|
|
GrabPtr grab)
|
|
_X_ATTRIBUTE_NONNULL_ARG(3);
|
|
|
|
/**
|
|
* @brief deliver event to a window and its immediate parent.
|
|
*
|
|
* Used for most window events (CreateNotify, ConfigureNotify, etc.).
|
|
* Not useful for events that propagate up the tree or extension events
|
|
*
|
|
* In case of a ReparentNotify event, the event will be delivered to the
|
|
* otherParent as well.
|
|
*
|
|
* @param pWindow Window to deliver events to.
|
|
* @param events Events to deliver.
|
|
* @param count number of events in xE.
|
|
* @param otherParent Used for ReparentNotify events.
|
|
*/
|
|
enum EventDeliveryState DeliverEvents(WindowPtr pWindow,
|
|
xEventPtr events,
|
|
size_t nEvents,
|
|
WindowPtr otherParent)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1,2);
|
|
|
|
/**
|
|
* @brief deliver events to a window.
|
|
*
|
|
* At this point, we do not yet know if the event actually needs to be delivered.
|
|
* May activate a grab if the event is a button press.
|
|
*
|
|
* Core events are always delivered to the window owner. If the filter is
|
|
* something other than CantBeFiltered, the event is also delivered to other
|
|
* clients with the matching mask on the window.
|
|
*
|
|
* More than one event may be delivered at a time. This is the case with
|
|
* DeviceMotionNotifies which may be followed by DeviceValuator events.
|
|
*
|
|
* @param pWindow The window that would get the event.
|
|
* @param pEvents The events to be delivered.
|
|
* @param count Number of elements in pEvents.
|
|
* @param filter Mask based on event type.
|
|
* @param grab Possible grab on the device that caused the event.
|
|
*
|
|
* @return a positive number if at least one successful delivery has been
|
|
* made, 0 if no events were delivered, or a negative number if the event
|
|
* has not been delivered _and_ rejected by at least one client.
|
|
*/
|
|
int DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWindow, xEventPtr pEvents,
|
|
size_t count, Mask filter, GrabPtr grab)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1,2,3);
|
|
|
|
/*
|
|
* @brief callback when root window has is finalized
|
|
*/
|
|
extern CallbackListPtr RootWindowFinalizeCallback;
|
|
|
|
/*
|
|
* @brief do post actions necessary when window got a new cursor
|
|
*
|
|
* currently just for updating cursors on input devices
|
|
*
|
|
* @param pWindow window that just got a new cursor
|
|
*/
|
|
void WindowHasNewCursor(WindowPtr pWin)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1);
|
|
|
|
/*
|
|
* @brief do post actions necessary when windows have been restructured
|
|
*
|
|
* currently updates the sprite position and the sprite's cursor.
|
|
*/
|
|
void WindowsRestructured(void);
|
|
|
|
/*
|
|
* @brief do post actions necessary whn screens have been restructured
|
|
*
|
|
* currently eg. fixing up cursors and their confinements (randr)
|
|
*/
|
|
void ScreenRestructured(ScreenPtr pScreen)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1);
|
|
|
|
/*
|
|
* @brief destructor for X11_RESTYPE_OTHERCLIENT resources
|
|
*
|
|
* @param value pointer to resource data
|
|
* @param id ID of the resource
|
|
* @return (undefined/ignored)
|
|
*/
|
|
int OtherClientGone(void *value, XID id);
|
|
|
|
/*
|
|
* @brief check whether one window is parent of another
|
|
*
|
|
* @param parent the alleged parent
|
|
* @param child the alleged child
|
|
* @return TRUE if `child` is a child window of `parent`
|
|
*/
|
|
Bool WindowIsParent(WindowPtr parent, WindowPtr child)
|
|
_X_ATTRIBUTE_NONNULL_ARG(1,2);
|
|
|
|
#endif /* _XSERVER_DIX_PRIV_H */
|