summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/darwin/quartz/rootlessCommon.h
blob: 43a74e1062ca6b1bfc7596ec7c1c2724d2a03e59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/*
 * Common internal rootless definitions and code
 *
 * Greg Parker     gparker@cs.stanford.edu
 */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/rootlessCommon.h,v 1.6 2002/07/24 05:58:33 torrey Exp $ */

#ifndef _ROOTLESSCOMMON_H
#define _ROOTLESSCOMMON_H

#include "rootless.h"

#include "pixmapstr.h"
#include "windowstr.h"

#ifdef RENDER
#include "picturestr.h"
#endif


// Debug output, or not.
#ifdef ROOTLESSDEBUG
#define RL_DEBUG_MSG ErrorF
#else
#define RL_DEBUG_MSG(a, ...)
#endif


// Global variables
extern int rootlessGCPrivateIndex;
extern int rootlessScreenPrivateIndex;
extern int rootlessWindowPrivateIndex;


// RootlessGCRec: private per-gc data
typedef struct {
    GCFuncs *originalFuncs;
    GCOps *originalOps;
} RootlessGCRec;


// RootlessWindowRec: private per-window data
typedef struct RootlessWindowRec {
    RootlessFrameRec frame;
    RegionRec damage;
    unsigned int borderWidth; // needed for MoveWindow(VTOther) (%$#@!!!)
    PixmapPtr pixmap;
    PixmapPtr oldPixmap;
    BOOL drawing;       // TRUE if currently drawing
#ifdef SHAPE
    BOOL shapeDamage;   // TRUE if shape has changed
#endif
} RootlessWindowRec;


// RootlessScreenRec: per-screen private data
typedef struct {
    ScreenPtr pScreen;
    RootlessFrameProcs frameProcs;

    CloseScreenProcPtr CloseScreen;

    CreateWindowProcPtr CreateWindow;
    DestroyWindowProcPtr DestroyWindow;
    RealizeWindowProcPtr RealizeWindow;
    UnrealizeWindowProcPtr UnrealizeWindow;
    MoveWindowProcPtr MoveWindow;
    ResizeWindowProcPtr ResizeWindow;
    RestackWindowProcPtr RestackWindow;
    ChangeBorderWidthProcPtr ChangeBorderWidth;
    PositionWindowProcPtr PositionWindow;
    ChangeWindowAttributesProcPtr ChangeWindowAttributes;

    CreateGCProcPtr CreateGC;
    PaintWindowBackgroundProcPtr PaintWindowBackground;
    PaintWindowBorderProcPtr PaintWindowBorder;
    CopyWindowProcPtr CopyWindow;
    GetImageProcPtr GetImage;
    SourceValidateProcPtr SourceValidate;

    MarkOverlappedWindowsProcPtr MarkOverlappedWindows;
    ValidateTreeProcPtr ValidateTree;

#ifdef SHAPE
    SetShapeProcPtr SetShape;
#endif

#ifdef RENDER
    CompositeProcPtr Composite;
    GlyphsProcPtr Glyphs;
#endif

} RootlessScreenRec;


// "Definition of the Porting Layer for the X11 Sample Server" says
// unwrap and rewrap of screen functions is unnecessary, but
// screen->CreateGC changes after a call to cfbCreateGC.

#define SCREEN_UNWRAP(screen, fn) \
    screen->fn = SCREENREC(screen)->fn;

#define SCREEN_WRAP(screen, fn) \
    SCREENREC(screen)->fn = screen->fn; \
    screen->fn = Rootless##fn


// Accessors for screen and window privates

#define SCREENREC(pScreen) \
   ((RootlessScreenRec*)(pScreen)->devPrivates[rootlessScreenPrivateIndex].ptr)

#define WINREC(pWin) \
    ((RootlessWindowRec *)(pWin)->devPrivates[rootlessWindowPrivateIndex].ptr)


// Call a rootless implementation function.
// Many rootless implementation functions are allowed to be NULL.
#define CallFrameProc(pScreen, proc, params) \
    if (SCREENREC(pScreen)->frameProcs.proc) { \
        RL_DEBUG_MSG("calling frame proc " #proc " "); \
        SCREENREC(pScreen)->frameProcs.proc params; \
    }


// BoxRec manipulators
// Copied from shadowfb

#define TRIM_BOX(box, pGC) { \
    BoxPtr extents = &pGC->pCompositeClip->extents;\
    if(box.x1 < extents->x1) box.x1 = extents->x1; \
    if(box.x2 > extents->x2) box.x2 = extents->x2; \
    if(box.y1 < extents->y1) box.y1 = extents->y1; \
    if(box.y2 > extents->y2) box.y2 = extents->y2; \
}

#define TRANSLATE_BOX(box, pDraw) { \
    box.x1 += pDraw->x; \
    box.x2 += pDraw->x; \
    box.y1 += pDraw->y; \
    box.y2 += pDraw->y; \
}

#define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \
    TRANSLATE_BOX(box, pDraw); \
    TRIM_BOX(box, pGC); \
}

#define BOX_NOT_EMPTY(box) \
    (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))


// HUGE_ROOT and NORMAL_ROOT
// We don't want to clip windows to the edge of the screen.
// HUGE_ROOT temporarily makes the root window really big.
// This is needed as a wrapper around any function that calls
// SetWinSize or SetBorderSize which clip a window against its
// parents, including the root.

extern RegionRec rootlessHugeRoot;

#define HUGE_ROOT(pWin) \
    { \
        WindowPtr w = pWin; \
        while (w->parent) w = w->parent; \
        saveRoot = w->winSize; \
        w->winSize = rootlessHugeRoot; \
    }

#define NORMAL_ROOT(pWin) \
    { \
        WindowPtr w = pWin; \
        while (w->parent) w = w->parent; \
        w->winSize = saveRoot; \
    }


// Returns TRUE if this window is a top-level window (i.e. child of the root)
// The root is not a top-level window.
#define IsTopLevel(pWin) \
    ((pWin)  &&  (pWin)->parent  &&  !(pWin)->parent->parent)

// Returns TRUE if this window is a root window
#define IsRoot(pWin) \
    ((pWin) == WindowTable[(pWin)->drawable.pScreen->myNum])


/*
 * SetPixmapBaseToScreen
 *  Move the given pixmap's base address to where pixel (0, 0)
 *  would be if the pixmap's actual data started at (x, y).
 */
#define SetPixmapBaseToScreen(pix, x, y) { \
    PixmapPtr   _pPix = (PixmapPtr) (pix); \
    _pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \
                            ((int)(x) * _pPix->drawable.bitsPerPixel/8 + \
                             (int)(y) * _pPix->devKind); \
}


// Returns the top-level parent of pWindow.
// The root is the top-level parent of itself, even though the root is
// not otherwise considered to be a top-level window.
WindowPtr TopLevelParent(WindowPtr pWindow);

// Returns TRUE if this window is visible inside a frame
// (e.g. it is visible and has a top-level or root parent)
Bool IsFramedWindow(WindowPtr pWin);

// Prepare a window for direct access to its backing buffer.
void RootlessStartDrawing(WindowPtr pWindow);

// Finish drawing to a window's backing buffer.
void RootlessStopDrawing(WindowPtr pWindow);

// Routines that cause regions to get redrawn.
// DamageRegion and DamageRect are in global coordinates.
// DamageBox is in window-local coordinates.
void RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion);
void RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h);
void RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox);
void RootlessRedisplay(WindowPtr pWindow);
void RootlessRedisplayScreen(ScreenPtr pScreen);

// Window reshape needs to be updated. The reshape also forces complete redraw.
void RootlessDamageShape(WindowPtr pWin);

#endif // _ROOTLESSCOMMON_H