summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/darwin/bundle/rootlessAquaGlue.c
blob: f3b0416363ac5632cca79d635c40f504438f9b68 (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
/*
 * Generic rootless to Aqua specific glue code
 *
 * This code acts as a glue between the generic rootless X server code
 * and the Aqua specific implementation, which includes definitions that
 * conflict with stardard X types.
 *
 * Greg Parker     gparker@cs.stanford.edu
 */
/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessAquaGlue.c,v 1.7 2001/12/22 05:28:35 torrey Exp $ */

#include "quartzCommon.h"
#include "darwin.h"
#include "rootlessAqua.h"
#include "rootlessAquaImp.h"
#include "rootless.h"

#include "regionstr.h"
#include "scrnintstr.h"
#include "globals.h" // dixScreenOrigins[]


/////////////////////////////////////////
// Rootless mode callback glue

static void
AquaGlueCreateFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
                    RootlessFramePtr pUpper)
{
    int sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
    int sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;

    pFrame->devPrivate = AquaNewWindow(pUpper ? pUpper->devPrivate : NULL,
                                       pFrame->x + sx, pFrame->y + sy,
                                       pFrame->w, pFrame->h,
                                       pFrame->isRoot);
    AquaGetPixmap(pFrame->devPrivate, &pFrame->pixelData,
                  &pFrame->bytesPerRow, &pFrame->depth,
                  &pFrame->bitsPerPixel);
}


static void
AquaGlueDestroyFrame(ScreenPtr pScreen, RootlessFramePtr pFrame)
{
    AquaDestroyWindow(pFrame->devPrivate);
}

static void
AquaGlueMoveFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
                  int oldX, int oldY)
{
    int sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
    int sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;

    AquaMoveWindow(pFrame->devPrivate, pFrame->x + sx, pFrame->y + sy);
}


static void
AquaGlueStartResizeFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
                         int oldX, int oldY,
                         unsigned int oldW, unsigned int oldH)
{
    int sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
    int sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;

    AquaStartResizeWindow(pFrame->devPrivate,
                          pFrame->x + sx, pFrame->y + sy, pFrame->w, pFrame->h);
    AquaGetPixmap(pFrame->devPrivate, &pFrame->pixelData,
                  &pFrame->bytesPerRow, &pFrame->depth,
                  &pFrame->bitsPerPixel);
}

static void
AquaGlueFinishResizeFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
                          int oldX, int oldY,
                          unsigned int oldW, unsigned int oldH)
{
    int sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
    int sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;

    AquaFinishResizeWindow(pFrame->devPrivate,
                           pFrame->x + sx, pFrame->y + sy,
                           pFrame->w, pFrame->h);
}


static void
AquaGlueRestackFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
                     RootlessFramePtr pOldPrev,
                     RootlessFramePtr pNewPrev)
{
    AquaRestackWindow(pFrame->devPrivate,
                      pNewPrev ? pNewPrev->devPrivate : NULL);
}

static void
AquaGlueReshapeFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
                     RegionPtr pNewShape)
{
    // Don't correct for dixScreenOrigins here.
    // pNewShape is in window-local coordinates.
    BoxRec shapeBox = {0, 0, pFrame->w, pFrame->h};
    if (pFrame->isRoot) return; // shouldn't happen; mi or dix covers this

    REGION_INVERSE(pScreen, pNewShape, pNewShape, &shapeBox);
    AquaReshapeWindow(pFrame->devPrivate,
                      (fakeBoxRec *) REGION_RECTS(pNewShape),
                      REGION_NUM_RECTS(pNewShape));
}

static void
AquaGlueUpdateRegion(ScreenPtr pScreen, RootlessFramePtr pFrame,
                     RegionPtr pDamage)
{
    AquaUpdateRects(pFrame->devPrivate,
                    (fakeBoxRec *) REGION_RECTS(pDamage),
                    REGION_NUM_RECTS(pDamage));
}

#if 0
static void
AquaGlueStartDrawing(ScreenPtr pScreen, RootlessFramePtr pFrame)
{
    AquaStartDrawing(pFrame->devPrivate, &pFrame->pixelData,
                     &pFrame->bytesPerRow, &pFrame->depth,
                     &pFrame->bitsPerPixel);
}

static void
AquaGlueStopDrawing(ScreenPtr pScreen, RootlessFramePtr pFrame)
{
    AquaStopDrawing(pFrame->devPrivate);
}
#endif

static RootlessFrameProcs aquaRootlessProcs = {
    AquaGlueCreateFrame,
    AquaGlueDestroyFrame,
    AquaGlueMoveFrame,
    AquaGlueStartResizeFrame,
    AquaGlueFinishResizeFrame,
    AquaGlueRestackFrame,
    AquaGlueReshapeFrame,
    AquaGlueUpdateRegion
};


///////////////////////////////////////
// Rootless mode initialization.
// Exported by rootlessAqua.h

/*
 * AquaDisplayInit
 *  Find all Aqua screens.
 */
void
AquaDisplayInit(void)
{
    darwinScreensFound = AquaDisplayCount();
}


/*
 * AquaAddScreen
 *  Init the framebuffer and record pixmap parameters for the screen.
 */
Bool
AquaAddScreen(int index, ScreenPtr pScreen)
{
    DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
    QuartzScreenPtr displayInfo = QUARTZ_PRIV(pScreen);
    CGRect cgRect;
    CGDisplayCount numDisplays;
    CGDisplayCount allocatedDisplays = 0;
    CGDirectDisplayID *displays = NULL;
    CGDisplayErr cgErr;

    dfb->pixelInfo.pixelType = kIORGBDirectPixels;
    AquaScreenInit(index, &dfb->x, &dfb->y, &dfb->width, &dfb->height,
                    &dfb->pitch, &dfb->pixelInfo.bitsPerComponent,
                    &dfb->pixelInfo.componentCount, &dfb->bitsPerPixel);
    dfb->colorBitsPerPixel = dfb->pixelInfo.bitsPerComponent *
                             dfb->pixelInfo.componentCount;

    // No frame buffer - it's all in window pixmaps.
    dfb->framebuffer = NULL; // malloc(dfb.pitch * dfb.height);

    // Get all CoreGraphics displays covered by this X11 display.
    cgRect = CGRectMake(dfb->x, dfb->y, dfb->width, dfb->height);
    do {
        cgErr = CGGetDisplaysWithRect(cgRect, 0, NULL, &numDisplays);
        if (cgErr) break;
        allocatedDisplays = numDisplays;
        displays = xrealloc(displays,
                            numDisplays * sizeof(CGDirectDisplayID));
        cgErr = CGGetDisplaysWithRect(cgRect, allocatedDisplays, displays,
                                      &numDisplays);
        if (cgErr != CGDisplayNoErr) break;
    } while (numDisplays > allocatedDisplays);

    if (cgErr != CGDisplayNoErr || numDisplays == 0) {
        ErrorF("Could not find CGDirectDisplayID(s) for X11 screen %d: %dx%d @ %d,%d.\n",
               index, dfb->width, dfb->height, dfb->x, dfb->y);
        return FALSE;
    }

    // This X11 screen covers all CoreGraphics displays we just found.
    // If there's more than one CG display, then video mirroring is on
    // or PseudoramiX is on.
    displayInfo->displayCount = allocatedDisplays;
    displayInfo->displayIDs = displays;

    return TRUE;
}

/*
 * AquaSetupScreen
 *  Setup the screen for rootless access.
 */
Bool
AquaSetupScreen(int index, ScreenPtr pScreen)
{
    return RootlessInit(pScreen, &aquaRootlessProcs);
}