Compare commits
146 Commits
master
...
backport/2
Author | SHA1 | Date | |
---|---|---|---|
|
934a299066 | ||
|
68129d7369 | ||
|
8407181c7d | ||
|
be2767845d | ||
|
b4ea6f9eb6 | ||
|
f54647dfa6 | ||
|
101caa1b03 | ||
|
1173156404 | ||
|
0e34d8ebc9 | ||
|
cea92ca78f | ||
|
8a7cd0e3ef | ||
|
5ca3a95135 | ||
|
5d7272f05d | ||
|
8a46a463f6 | ||
|
f653d9a0af | ||
|
8b75ec34df | ||
|
31407c0199 | ||
|
a4f0e9466f | ||
|
8d825f72da | ||
|
5c4816afa7 | ||
|
7b5694368b | ||
|
6236342157 | ||
|
8887cb1f27 | ||
|
7173a8911e | ||
|
c494debaa7 | ||
|
4e78bc3a6e | ||
|
c338d19f74 | ||
|
15e2409776 | ||
|
a7bda3080d | ||
|
58e83c6839 | ||
|
c1ad8df2fc | ||
|
6197bea02e | ||
|
3e290b3c7c | ||
|
f2922f6ffa | ||
|
2c33ee9f1d | ||
|
b98fc07d34 | ||
|
7c791b1550 | ||
|
fb51d5dd53 | ||
|
6bed5cfd51 | ||
|
af9111ac7f | ||
|
9ca7d3f61a | ||
|
4b925d388f | ||
|
44d6c82ac8 | ||
|
1317083fbc | ||
|
a6c49106ce | ||
|
a220f53cb8 | ||
|
07f9689507 | ||
|
8ea43dd8bf | ||
|
aa0d8d440c | ||
|
8feba178f8 | ||
|
c8ef9e3818 | ||
|
a0216de236 | ||
|
264272f3d7 | ||
|
20f380c6d9 | ||
|
59b6fc88ed | ||
|
b7760d41c1 | ||
|
69ab3bcaa0 | ||
|
5dbb2b52cf | ||
|
becf9d51c3 | ||
|
61d18bed66 | ||
|
f292fbfaac | ||
|
e860bbce4f | ||
|
8a1fa008b2 | ||
|
40f431de8a | ||
|
d6c7de9ead | ||
|
67927cc41f | ||
|
a6c0d7b142 | ||
|
936d34bdff | ||
|
5f2d652377 | ||
|
3dee0aac2c | ||
|
5d302c378d | ||
|
6bf62381d0 | ||
|
06b23cccb1 | ||
|
e3a530540f | ||
|
e758405657 | ||
|
f3d9c6ff12 | ||
|
147c17fc78 | ||
|
9e2fc7e248 | ||
|
86ace20398 | ||
|
855b96a85b | ||
|
9d05ee10c2 | ||
|
b713e717c3 | ||
|
cd3d21d8c4 | ||
|
f575524314 | ||
|
419fbf639d | ||
|
66ac50090d | ||
|
033d93a021 | ||
|
433f53a1a0 | ||
|
3868f36472 | ||
|
afcaaac967 | ||
|
6bb98fc62d | ||
|
4ea6f661ed | ||
|
a6a20a7c40 | ||
|
37285e6252 | ||
|
96e7b55c5d | ||
|
6465263be8 | ||
|
e48acd9c40 | ||
|
140d9a0f75 | ||
|
03ec5b132f | ||
|
6df6178bb9 | ||
|
c6c1cba397 | ||
|
663af2f17e | ||
|
bd3564cf37 | ||
|
53173fdab4 | ||
|
6977404471 | ||
|
85397cc2ef | ||
|
001feb6692 | ||
|
66890ca569 | ||
|
fec0e2501b | ||
|
8223a9d6d9 | ||
|
b27eaa7283 | ||
|
9852b29380 | ||
|
9fe2991075 | ||
|
0b67785cd1 | ||
|
7209982d2a | ||
|
6f09e7d391 | ||
|
a82d523edb | ||
|
a39218d99c | ||
|
fc2eb7e8cc | ||
|
7caf29ca66 | ||
|
101791f80f | ||
|
2c6989f81e | ||
|
49444ce9f7 | ||
|
6f11b3c803 | ||
|
8eb1396d3e | ||
|
6834f977a5 | ||
|
0ed7b1224e | ||
|
6b997fb74e | ||
|
70a0c48ff3 | ||
|
db0da823f5 | ||
|
fdb266ff81 | ||
|
27a0ee32cc | ||
|
d4944ceda1 | ||
|
e59faa4b8c | ||
|
3fb94f3c5c | ||
|
b89fdd523e | ||
|
fbc690ccaf | ||
|
22f4ff1026 | ||
|
0d0986bf3b | ||
|
bc1327e6de | ||
|
b87536682c | ||
|
473a48660f | ||
|
b33f487a7c | ||
|
d1ca47e124 | ||
|
d00e7dfc9d | ||
|
4ee66f574a |
|
@ -11,7 +11,8 @@ variables:
|
|||
FDO_UPSTREAM_REPO: xorg/xserver
|
||||
FDO_DISTRIBUTION_VERSION: buster-slim
|
||||
FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} bash .gitlab-ci/debian-install.sh'
|
||||
FDO_DISTRIBUTION_TAG: "2021-07-09"
|
||||
FDO_DISTRIBUTION_TAG: "2024-08-23-21.1-fix-cross"
|
||||
MESON_BUILDDIR: "build"
|
||||
|
||||
include:
|
||||
- project: 'freedesktop/ci-templates'
|
||||
|
|
|
@ -11,7 +11,7 @@ HOST=$1
|
|||
cat >/usr/local/bin/${HOST}-pkg-config <<EOF
|
||||
#!/bin/sh
|
||||
|
||||
PKG_CONFIG_SYSROOT_DIR=/usr/${HOST} PKG_CONFIG_LIBDIR=/usr/${HOST}/lib/pkgconfig:/usr/share/pkgconfig pkg-config \$@
|
||||
PKG_CONFIG_SYSROOT_DIR=/usr/${HOST} PKG_CONFIG_LIBDIR=/usr/${HOST}/lib/pkgconfig:/usr/${HOST}/share/pkgconfig pkg-config \$@
|
||||
EOF
|
||||
chmod +x /usr/local/bin/${HOST}-pkg-config
|
||||
|
||||
|
|
13
Makefile.am
13
Makefile.am
|
@ -147,6 +147,8 @@ EXTRA_DIST += \
|
|||
damageext/meson.build \
|
||||
dbe/meson.build \
|
||||
dix/meson.build \
|
||||
doc/dtrace/meson.build \
|
||||
doc/meson.build \
|
||||
dri3/meson.build \
|
||||
exa/meson.build \
|
||||
fb/meson.build \
|
||||
|
@ -160,8 +162,10 @@ EXTRA_DIST += \
|
|||
hw/xfree86/common/meson.build \
|
||||
hw/xfree86/ddc/meson.build \
|
||||
hw/xfree86/dixmods/meson.build \
|
||||
hw/xfree86/doc/meson.build \
|
||||
hw/xfree86/dri2/meson.build \
|
||||
hw/xfree86/dri/meson.build \
|
||||
hw/xfree86/drivers/inputtest/meson.build \
|
||||
hw/xfree86/drivers/modesetting/meson.build \
|
||||
hw/xfree86/exa/meson.build \
|
||||
hw/xfree86/fbdevhw/meson.build \
|
||||
|
@ -179,8 +183,12 @@ EXTRA_DIST += \
|
|||
hw/xfree86/x86emu/meson.build \
|
||||
hw/xfree86/xkb/meson.build \
|
||||
hw/xnest/meson.build \
|
||||
hw/xquartz/bundle/meson.build \
|
||||
hw/xquartz/GL/meson.build \
|
||||
hw/xquartz/mach-startup/meson.build \
|
||||
hw/xquartz/meson.build \
|
||||
hw/xwayland/meson.build \
|
||||
hw/xquartz/pbproxy/meson.build \
|
||||
hw/xquartz/xpr/meson.build \
|
||||
hw/xwin/dri/meson.build \
|
||||
hw/xwin/glx/meson.build \
|
||||
hw/xwin/meson.build \
|
||||
|
@ -188,6 +196,7 @@ EXTRA_DIST += \
|
|||
include/meson.build \
|
||||
meson.build \
|
||||
miext/damage/meson.build \
|
||||
miext/rootless/meson.build \
|
||||
miext/shadow/meson.build \
|
||||
miext/sync/meson.build \
|
||||
mi/meson.build \
|
||||
|
@ -199,6 +208,8 @@ EXTRA_DIST += \
|
|||
render/meson.build \
|
||||
test/bigreq/meson.build \
|
||||
test/bigreq/request-length.c \
|
||||
test/damage/meson.build \
|
||||
test/damage/primitives.c \
|
||||
test/meson.build \
|
||||
test/sync/meson.build \
|
||||
test/sync/sync.c \
|
||||
|
|
|
@ -1051,7 +1051,7 @@ ScreenSaverSetAttributes(ClientPtr client)
|
|||
pVlist++;
|
||||
}
|
||||
if (pPriv->attr)
|
||||
FreeScreenAttr(pPriv->attr);
|
||||
FreeResource(pPriv->attr->resource, AttrType);
|
||||
pPriv->attr = pAttr;
|
||||
pAttr->resource = FakeClientID(client->index);
|
||||
if (!AddResource(pAttr->resource, AttrType, (void *) pAttr))
|
||||
|
@ -1351,8 +1351,8 @@ SProcScreenSaverSuspend(ClientPtr client)
|
|||
REQUEST(xScreenSaverSuspendReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
swapl(&stuff->suspend);
|
||||
REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
|
||||
swapl(&stuff->suspend);
|
||||
return ProcScreenSaverSuspend(client);
|
||||
}
|
||||
|
||||
|
|
|
@ -2318,6 +2318,7 @@ SProcSyncCreateFence(ClientPtr client)
|
|||
REQUEST(xSyncCreateFenceReq);
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xSyncCreateFenceReq);
|
||||
swapl(&stuff->d);
|
||||
swapl(&stuff->fid);
|
||||
|
||||
return ProcSyncCreateFence(client);
|
||||
|
|
|
@ -502,10 +502,11 @@ XTestSwapFakeInput(ClientPtr client, xReq * req)
|
|||
|
||||
nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
|
||||
for (ev = (xEvent *) &req[1]; --nev >= 0; ev++) {
|
||||
int evtype = ev->u.u.type & 0177;
|
||||
/* Swap event */
|
||||
proc = EventSwapVector[ev->u.u.type & 0177];
|
||||
proc = EventSwapVector[evtype];
|
||||
/* no swapping proc; invalid event type? */
|
||||
if (!proc || proc == NotImplemented) {
|
||||
if (!proc || proc == NotImplemented || evtype == GenericEvent) {
|
||||
client->errorValue = ev->u.u.type;
|
||||
return BadValue;
|
||||
}
|
||||
|
|
|
@ -811,8 +811,10 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff)
|
|||
tpn = pn;
|
||||
while (tpn) {
|
||||
if (tpn->client == client) {
|
||||
if (!onoff)
|
||||
if (!onoff) {
|
||||
tpn->client = NULL;
|
||||
FreeResource(tpn->id, XvRTVideoNotify);
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
if (!tpn->client)
|
||||
|
|
|
@ -605,22 +605,25 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
|
|||
to->button = calloc(1, sizeof(ButtonClassRec));
|
||||
if (!to->button)
|
||||
FatalError("[Xi] no memory for class shift.\n");
|
||||
to->button->numButtons = from->button->numButtons;
|
||||
}
|
||||
else
|
||||
classes->button = NULL;
|
||||
}
|
||||
|
||||
if (from->button->xkb_acts) {
|
||||
if (!to->button->xkb_acts) {
|
||||
to->button->xkb_acts = calloc(1, sizeof(XkbAction));
|
||||
if (!to->button->xkb_acts)
|
||||
FatalError("[Xi] not enough memory for xkb_acts.\n");
|
||||
}
|
||||
size_t maxbuttons = max(to->button->numButtons, from->button->numButtons);
|
||||
to->button->xkb_acts = xnfreallocarray(to->button->xkb_acts,
|
||||
maxbuttons,
|
||||
sizeof(XkbAction));
|
||||
memset(to->button->xkb_acts, 0, maxbuttons * sizeof(XkbAction));
|
||||
memcpy(to->button->xkb_acts, from->button->xkb_acts,
|
||||
sizeof(XkbAction));
|
||||
from->button->numButtons * sizeof(XkbAction));
|
||||
}
|
||||
else
|
||||
else {
|
||||
free(to->button->xkb_acts);
|
||||
to->button->xkb_acts = NULL;
|
||||
}
|
||||
|
||||
memcpy(to->button->labels, from->button->labels,
|
||||
from->button->numButtons * sizeof(Atom));
|
||||
|
@ -1524,7 +1527,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
|||
g = AllocGrab(devgrab);
|
||||
BUG_WARN(!g);
|
||||
|
||||
*dev->deviceGrab.sync.event = *ev;
|
||||
CopyPartialInternalEvent(dev->deviceGrab.sync.event, ev);
|
||||
|
||||
/* The listener array has a sequence of grabs and then one event
|
||||
* selection. Implicit grab activation occurs through delivering an
|
||||
|
@ -1901,7 +1904,7 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
|
|||
* nested) to clients. */
|
||||
if (event->source_type == EVENT_SOURCE_FOCUS)
|
||||
return;
|
||||
if (!grab && CheckDeviceGrabs(device, event, 0))
|
||||
if (!grab && CheckDeviceGrabs(device, ev, 0))
|
||||
return;
|
||||
break;
|
||||
case ET_KeyRelease:
|
||||
|
@ -1914,7 +1917,7 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
|
|||
if (b->map[key] == 0) /* there's no button 0 */
|
||||
return;
|
||||
event->detail.button = b->map[key];
|
||||
if (!grab && CheckDeviceGrabs(device, event, 0)) {
|
||||
if (!grab && CheckDeviceGrabs(device, ev, 0)) {
|
||||
/* if a passive grab was activated, the event has been sent
|
||||
* already */
|
||||
return;
|
||||
|
|
|
@ -416,6 +416,11 @@ ProcXIChangeHierarchy(ClientPtr client)
|
|||
size_t len; /* length of data remaining in request */
|
||||
int rc = Success;
|
||||
int flags[MAXDEVICES] = { 0 };
|
||||
enum {
|
||||
NO_CHANGE,
|
||||
FLUSH,
|
||||
CHANGED,
|
||||
} changes = NO_CHANGE;
|
||||
|
||||
REQUEST(xXIChangeHierarchyReq);
|
||||
REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq);
|
||||
|
@ -465,8 +470,9 @@ ProcXIChangeHierarchy(ClientPtr client)
|
|||
rc = add_master(client, c, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
}
|
||||
changes = FLUSH;
|
||||
break;
|
||||
}
|
||||
case XIRemoveMaster:
|
||||
{
|
||||
xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
|
||||
|
@ -475,8 +481,9 @@ ProcXIChangeHierarchy(ClientPtr client)
|
|||
rc = remove_master(client, r, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
}
|
||||
changes = FLUSH;
|
||||
break;
|
||||
}
|
||||
case XIDetachSlave:
|
||||
{
|
||||
xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
|
||||
|
@ -485,8 +492,9 @@ ProcXIChangeHierarchy(ClientPtr client)
|
|||
rc = detach_slave(client, c, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
}
|
||||
changes = CHANGED;
|
||||
break;
|
||||
}
|
||||
case XIAttachSlave:
|
||||
{
|
||||
xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
|
||||
|
@ -495,16 +503,25 @@ ProcXIChangeHierarchy(ClientPtr client)
|
|||
rc = attach_slave(client, c, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
}
|
||||
changes = CHANGED;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (changes == FLUSH) {
|
||||
XISendDeviceHierarchyEvent(flags);
|
||||
memset(flags, 0, sizeof(flags));
|
||||
changes = NO_CHANGE;
|
||||
}
|
||||
|
||||
len -= any->length * 4;
|
||||
any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4);
|
||||
}
|
||||
|
||||
unwind:
|
||||
|
||||
XISendDeviceHierarchyEvent(flags);
|
||||
if (changes != NO_CHANGE)
|
||||
XISendDeviceHierarchyEvent(flags);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
|
|||
GrabParameters param;
|
||||
void *tmp;
|
||||
int mask_len;
|
||||
uint32_t length;
|
||||
|
||||
REQUEST(xXIPassiveGrabDeviceReq);
|
||||
REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
|
||||
|
@ -137,6 +138,12 @@ ProcXIPassiveGrabDevice(ClientPtr client)
|
|||
return BadValue;
|
||||
}
|
||||
|
||||
/* XI2 allows 32-bit keycodes but thanks to XKB we can never
|
||||
* implement this. Just return an error for all keycodes that
|
||||
* cannot work anyway, same for buttons > 255. */
|
||||
if (stuff->detail > 255)
|
||||
return XIAlreadyGrabbed;
|
||||
|
||||
if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
|
||||
stuff->mask_len * 4) != Success)
|
||||
return BadValue;
|
||||
|
@ -207,14 +214,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
|
|||
¶m, XI2, &mask);
|
||||
break;
|
||||
case XIGrabtypeKeycode:
|
||||
/* XI2 allows 32-bit keycodes but thanks to XKB we can never
|
||||
* implement this. Just return an error for all keycodes that
|
||||
* cannot work anyway */
|
||||
if (stuff->detail > 255)
|
||||
status = XIAlreadyGrabbed;
|
||||
else
|
||||
status = GrabKey(client, dev, mod_dev, stuff->detail,
|
||||
¶m, XI2, &mask);
|
||||
status = GrabKey(client, dev, mod_dev, stuff->detail,
|
||||
¶m, XI2, &mask);
|
||||
break;
|
||||
case XIGrabtypeEnter:
|
||||
case XIGrabtypeFocusIn:
|
||||
|
@ -247,9 +248,11 @@ ProcXIPassiveGrabDevice(ClientPtr client)
|
|||
}
|
||||
}
|
||||
|
||||
/* save the value before SRepXIPassiveGrabDevice swaps it */
|
||||
length = rep.length;
|
||||
WriteReplyToClient(client, sizeof(rep), &rep);
|
||||
if (rep.num_modifiers)
|
||||
WriteToClient(client, rep.length * 4, modifiers_failed);
|
||||
WriteToClient(client, length * 4, modifiers_failed);
|
||||
|
||||
out:
|
||||
free(modifiers_failed);
|
||||
|
@ -334,6 +337,12 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
|
|||
return BadValue;
|
||||
}
|
||||
|
||||
/* We don't allow passive grabs for details > 255 anyway */
|
||||
if (stuff->detail > 255) {
|
||||
client->errorValue = stuff->detail;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
|
|
|
@ -730,7 +730,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
|
|||
XIDestroyDeviceProperty(prop);
|
||||
return BadAlloc;
|
||||
}
|
||||
new_value.size = len;
|
||||
new_value.size = total_len;
|
||||
new_value.type = type;
|
||||
new_value.format = format;
|
||||
|
||||
|
@ -747,7 +747,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
|
|||
case PropModePrepend:
|
||||
new_data = new_value.data;
|
||||
old_data = (void *) (((char *) new_value.data) +
|
||||
(prop_value->size * size_in_bytes));
|
||||
(len * size_in_bytes));
|
||||
break;
|
||||
}
|
||||
if (new_data)
|
||||
|
@ -890,7 +890,7 @@ ProcXChangeDeviceProperty(ClientPtr client)
|
|||
REQUEST(xChangeDevicePropertyReq);
|
||||
DeviceIntPtr dev;
|
||||
unsigned long len;
|
||||
int totalSize;
|
||||
uint64_t totalSize;
|
||||
int rc;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq);
|
||||
|
@ -902,6 +902,8 @@ ProcXChangeDeviceProperty(ClientPtr client)
|
|||
|
||||
rc = check_change_property(client, stuff->property, stuff->type,
|
||||
stuff->format, stuff->mode, stuff->nUnits);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
|
||||
len = stuff->nUnits;
|
||||
if (len > (bytes_to_int32(0xffffffff - sizeof(xChangeDevicePropertyReq))))
|
||||
|
@ -1128,7 +1130,7 @@ ProcXIChangeProperty(ClientPtr client)
|
|||
{
|
||||
int rc;
|
||||
DeviceIntPtr dev;
|
||||
int totalSize;
|
||||
uint64_t totalSize;
|
||||
unsigned long len;
|
||||
|
||||
REQUEST(xXIChangePropertyReq);
|
||||
|
@ -1141,6 +1143,9 @@ ProcXIChangeProperty(ClientPtr client)
|
|||
|
||||
rc = check_change_property(client, stuff->property, stuff->type,
|
||||
stuff->format, stuff->mode, stuff->num_items);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
|
||||
len = stuff->num_items;
|
||||
if (len > bytes_to_int32(0xffffffff - sizeof(xXIChangePropertyReq)))
|
||||
return BadLength;
|
||||
|
|
|
@ -149,8 +149,7 @@ ProcXIQueryPointer(ClientPtr client)
|
|||
if (pDev->button) {
|
||||
int i;
|
||||
|
||||
rep.buttons_len =
|
||||
bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
|
||||
rep.buttons_len = bytes_to_int32(bits_to_bytes(256)); /* button map up to 255 */
|
||||
rep.length += rep.buttons_len;
|
||||
buttons = calloc(rep.buttons_len, 4);
|
||||
if (!buttons)
|
||||
|
|
|
@ -349,6 +349,7 @@ ProcXIGetSelectedEvents(ClientPtr client)
|
|||
InputClientsPtr others = NULL;
|
||||
xXIEventMask *evmask = NULL;
|
||||
DeviceIntPtr dev;
|
||||
uint32_t length;
|
||||
|
||||
REQUEST(xXIGetSelectedEventsReq);
|
||||
REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq);
|
||||
|
@ -418,10 +419,12 @@ ProcXIGetSelectedEvents(ClientPtr client)
|
|||
}
|
||||
}
|
||||
|
||||
/* save the value before SRepXIGetSelectedEvents swaps it */
|
||||
length = reply.length;
|
||||
WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply);
|
||||
|
||||
if (reply.num_masks)
|
||||
WriteToClient(client, reply.length * 4, buffer);
|
||||
WriteToClient(client, length * 4, buffer);
|
||||
|
||||
free(buffer);
|
||||
return Success;
|
||||
|
|
|
@ -620,6 +620,11 @@ compDestroyWindow(WindowPtr pWin)
|
|||
ret = (*pScreen->DestroyWindow) (pWin);
|
||||
cs->DestroyWindow = pScreen->DestroyWindow;
|
||||
pScreen->DestroyWindow = compDestroyWindow;
|
||||
|
||||
/* Did we just destroy the overlay window? */
|
||||
if (pWin == cs->pOverlayWin)
|
||||
cs->pOverlayWin = NULL;
|
||||
|
||||
/* compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/
|
||||
return ret;
|
||||
}
|
||||
|
|
121
configure.ac
121
configure.ac
|
@ -26,9 +26,9 @@ dnl
|
|||
dnl Process this file with autoconf to create configure.
|
||||
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT([xorg-server], 21.0.99.1, [https://gitlab.freedesktop.org/xorg/xserver/issues], xorg-server)
|
||||
RELEASE_DATE="2021-07-05"
|
||||
RELEASE_NAME="Carrot and Ginger Soup"
|
||||
AC_INIT([xorg-server], 21.1.13, [https://gitlab.freedesktop.org/xorg/xserver/issues], xorg-server)
|
||||
RELEASE_DATE="2024-04-12"
|
||||
RELEASE_NAME="Caramel Ice Cream"
|
||||
AC_CONFIG_SRCDIR([Makefile.am])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE([foreign dist-xz])
|
||||
|
@ -67,8 +67,6 @@ dnl xkb-config.h covers XKB for the Xorg and Xnest DDXs.
|
|||
AC_CONFIG_HEADERS(include/xkb-config.h)
|
||||
dnl xwin-config.h covers the XWin DDX.
|
||||
AC_CONFIG_HEADERS(include/xwin-config.h)
|
||||
dnl xwayland-config.h covers Xwayland.
|
||||
AC_CONFIG_HEADERS(include/xwayland-config.h)
|
||||
dnl version-config.h covers the version numbers so they can be bumped without
|
||||
dnl forcing an entire recompile.x
|
||||
AC_CONFIG_HEADERS(include/version-config.h)
|
||||
|
@ -166,8 +164,16 @@ AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup\
|
|||
timingsafe_memcmp])
|
||||
AM_CONDITIONAL(POLL, [test "x$ac_cv_func_poll" = "xyes"])
|
||||
|
||||
AC_CHECK_LIB([bsd], [arc4random_buf])
|
||||
AC_CHECK_FUNCS([arc4random_buf])
|
||||
# Checks for non-standard functions and fallback to libbsd if we can
|
||||
# We only check for arc4random_buf, because if we have that, we don't
|
||||
# need/use getentropy.
|
||||
AC_LINK_IFELSE([AC_LANG_CALL([], [arc4random_buf])],
|
||||
[TRY_LIBBSD="no"], [TRY_LIBBSD="yes"])
|
||||
AS_IF([test "x$TRY_LIBBSD" = "xyes"],
|
||||
[PKG_CHECK_MODULES([LIBBSD], [libbsd-overlay], [
|
||||
CFLAGS="$CFLAGS $LIBBSD_CFLAGS"
|
||||
LIBS="$LIBS $LIBBSD_LIBS"
|
||||
], [:])])
|
||||
|
||||
AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]])
|
||||
|
||||
|
@ -575,10 +581,6 @@ AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server
|
|||
AC_ARG_ENABLE(xvfb, AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes])
|
||||
AC_ARG_ENABLE(xnest, AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto])
|
||||
AC_ARG_ENABLE(xquartz, AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
|
||||
AC_ARG_ENABLE(xwayland, AS_HELP_STRING([--enable-xwayland], [Build Xwayland server (default: auto)]), [XWAYLAND=$enableval], [XWAYLAND=auto])
|
||||
AC_ARG_ENABLE(xwayland-eglstream, AS_HELP_STRING([--enable-xwayland-eglstream], [Build Xwayland eglstream support (default: no)]), [XWAYLAND_EGLSTREAM=$enableval], [XWAYLAND_EGLSTREAM=no])
|
||||
AC_ARG_WITH(xwayland-path, AS_HELP_STRING([--with-xwayland-path=PATH], [Directory containing Xwayland executable (default: ${bindir})]),
|
||||
[ xwayland_path="$withval" ], [ xwayland_path="$bindir" ])
|
||||
AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
|
||||
AC_ARG_ENABLE(xwin, AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
|
||||
AC_ARG_ENABLE(glamor, AS_HELP_STRING([--enable-glamor], [Build glamor dix module (default: auto)]), [GLAMOR=$enableval], [GLAMOR=auto])
|
||||
|
@ -685,9 +687,7 @@ case $host_os in
|
|||
XQUARTZ=yes
|
||||
XVFB=no
|
||||
XNEST=no
|
||||
XWAYLAND=no
|
||||
|
||||
COMPOSITE=no
|
||||
DGA=no
|
||||
DPMSExtension=no
|
||||
XF86VIDMODE=no
|
||||
|
@ -763,7 +763,7 @@ PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN)
|
|||
REQUIRED_LIBS="$REQUIRED_LIBS $LIBPIXMAN $LIBXFONT xau"
|
||||
|
||||
dnl Core modules for most extensions, et al.
|
||||
SDK_REQUIRED_MODULES="$XPROTO $RANDRPROTO $RENDERPROTO $XEXTPROTO $INPUTPROTO $KBPROTO $FONTSPROTO $LIBPIXMAN $LIBXCVT"
|
||||
SDK_REQUIRED_MODULES="$XPROTO $RANDRPROTO $RENDERPROTO $XEXTPROTO $INPUTPROTO $KBPROTO $FONTSPROTO $LIBPIXMAN"
|
||||
# Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc
|
||||
AC_SUBST(SDK_REQUIRED_MODULES)
|
||||
|
||||
|
@ -2019,7 +2019,7 @@ AM_CONDITIONAL([XORG_DRIVER_INPUT_INPUTTEST], [test "x$XORG_DRIVER_INPUT_INPUTTE
|
|||
|
||||
dnl glamor
|
||||
if test "x$GLAMOR" = xauto; then
|
||||
if echo "$XORG" "$XEPHYR" "$XWAYLAND" | grep -q yes ; then
|
||||
if echo "$XORG" "$XEPHYR" | grep -q yes ; then
|
||||
GLAMOR=yes
|
||||
fi
|
||||
fi
|
||||
|
@ -2142,7 +2142,7 @@ if test "x$XQUARTZ" = xyes; then
|
|||
AC_DEFINE(XQUARTZ,1,[Have Quartz])
|
||||
AC_DEFINE(ROOTLESS,1,[Build Rootless code])
|
||||
|
||||
XQUARTZ_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB $PRESENT_LIB"
|
||||
XQUARTZ_LIBS="$COMPOSITE_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB $PRESENT_LIB"
|
||||
AC_SUBST([XQUARTZ_LIBS])
|
||||
|
||||
AC_CHECK_LIB([Xplugin],[xp_init],[:])
|
||||
|
@ -2234,92 +2234,6 @@ AC_SUBST([KDRIVE_LOCAL_LIBS])
|
|||
AC_SUBST([KDRIVE_LIBS])
|
||||
AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes])
|
||||
|
||||
dnl Xwayland DDX
|
||||
|
||||
XWAYLANDMODULES="wayland-client >= 1.5.0 wayland-protocols >= 1.18"
|
||||
if test "x$XF86VIDMODE" = xyes; then
|
||||
XWAYLANDMODULES="$XWAYLANDMODULES $VIDMODEPROTO"
|
||||
fi
|
||||
if test "x$DRM" = xyes; then
|
||||
XWAYLANDMODULES="$XWAYLANDMODULES $LIBDRM"
|
||||
fi
|
||||
if test "x$GLAMOR" = xyes; then
|
||||
XWAYLANDMODULES="$XWAYLANDMODULES epoxy"
|
||||
fi
|
||||
PKG_CHECK_MODULES(XWAYLANDMODULES, [$XWAYLANDMODULES], [have_xwayland=yes], [have_xwayland=no])
|
||||
AC_MSG_CHECKING([whether to build Xwayland DDX])
|
||||
if test "x$XWAYLAND" = xauto; then
|
||||
XWAYLAND="$have_xwayland"
|
||||
fi
|
||||
AC_MSG_RESULT([$XWAYLAND])
|
||||
AM_CONDITIONAL(XWAYLAND, [test "x$XWAYLAND" = xyes])
|
||||
|
||||
if test "x$XWAYLAND" = xyes; then
|
||||
if test "x$have_xwayland" = xno; then
|
||||
AC_MSG_ERROR([Xwayland build explicitly requested, but required modules not found.])
|
||||
fi
|
||||
|
||||
if test "x$GLAMOR" = xyes && test "x$GBM" = xyes; then
|
||||
AC_DEFINE(XWL_HAS_GLAMOR, 1,
|
||||
[Build xwayland with glamor support])
|
||||
AC_SUBST(have_glamor, "true")
|
||||
else
|
||||
AC_SUBST(have_glamor, "false")
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(WAYLAND_EGLSTREAM, [wayland-eglstream-protocols >= 1.0.2], [have_wl_eglstream=yes], [have_wl_eglstream=no])
|
||||
|
||||
if test "x$XWAYLAND_EGLSTREAM" = xauto; then
|
||||
if test "x$have_wl_eglstream" = xyes && test "x$GLAMOR" = xyes; then
|
||||
XWAYLAND_EGLSTREAM=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$XWAYLAND_EGLSTREAM" = xyes; then
|
||||
if test "x$GLAMOR" != xyes; then
|
||||
AC_MSG_ERROR([Xwayland eglstream support explicitly requested, but required modules not found.])
|
||||
fi
|
||||
|
||||
if test "x$have_wl_eglstream" = xno; then
|
||||
AC_MSG_ERROR([Xwayland eglstream support requires wayland-eglstream-protocols >= 1.0.2])
|
||||
fi
|
||||
|
||||
AC_SUBST(WAYLAND_EGLSTREAM_DATADIR, `$PKG_CONFIG --variable=pkgdatadir wayland-eglstream-protocols`)
|
||||
AC_DEFINE(XWL_HAS_EGLSTREAM, 1,
|
||||
[Build xwayland with eglstream support])
|
||||
AC_SUBST(have_eglstream, "true")
|
||||
else
|
||||
AC_SUBST(have_eglstream, "false")
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES([LIBXCVT], $LIBXCVT)
|
||||
|
||||
XWAYLAND_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB"
|
||||
XWAYLAND_SYS_LIBS="$XWAYLANDMODULES_LIBS $GLX_SYS_LIBS $LIBXCVT_LIBS"
|
||||
AC_SUBST([XWAYLAND_LIBS])
|
||||
AC_SUBST([XWAYLAND_SYS_LIBS])
|
||||
|
||||
if test "x$MONOTONIC_CLOCK" != xyes; then
|
||||
AC_MSG_ERROR([Xwayland requires CLOCK_MONOTONIC support.])
|
||||
fi
|
||||
|
||||
AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner])
|
||||
if test "x$WAYLAND_SCANNER" = x; then
|
||||
PKG_CHECK_MODULES(WAYLAND_SCANNER, [wayland-scanner])
|
||||
AC_SUBST(WAYLAND_SCANNER, `$PKG_CONFIG --variable=wayland_scanner wayland-scanner`)
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(WAYLAND_SCANNER, [wayland-scanner >= 1.14.91],
|
||||
AC_SUBST(SCANNER_ARG, 'private-code'),
|
||||
AC_SUBST(SCANNER_ARG, 'code'))
|
||||
|
||||
AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, `$PKG_CONFIG --variable=pkgdatadir wayland-protocols`)
|
||||
|
||||
AC_SUBST(xwayland_path)
|
||||
|
||||
fi
|
||||
AM_CONDITIONAL(XWAYLAND_EGLSTREAM, [test "x$XWAYLAND_EGLSTREAM" = "xyes"])
|
||||
|
||||
|
||||
dnl and the rest of these are generic, so they're in config.h
|
||||
dnl
|
||||
|
@ -2450,9 +2364,6 @@ hw/kdrive/Makefile
|
|||
hw/kdrive/ephyr/Makefile
|
||||
hw/kdrive/ephyr/man/Makefile
|
||||
hw/kdrive/src/Makefile
|
||||
hw/xwayland/Makefile
|
||||
hw/xwayland/man/Makefile
|
||||
hw/xwayland/xwayland.pc
|
||||
test/Makefile
|
||||
xserver.ent
|
||||
xorg-server.pc
|
||||
|
|
|
@ -447,14 +447,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
|||
{
|
||||
DeviceIntPtr *prev, other;
|
||||
BOOL enabled;
|
||||
BOOL dev_in_devices_list = FALSE;
|
||||
int flags[MAXDEVICES] = { 0 };
|
||||
|
||||
if (!dev->enabled)
|
||||
return TRUE;
|
||||
|
||||
for (prev = &inputInfo.devices;
|
||||
*prev && (*prev != dev); prev = &(*prev)->next);
|
||||
if (*prev != dev)
|
||||
for (other = inputInfo.devices; other; other = other->next) {
|
||||
if (other == dev) {
|
||||
dev_in_devices_list = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev_in_devices_list)
|
||||
return FALSE;
|
||||
|
||||
TouchEndPhysicallyActiveTouches(dev);
|
||||
|
@ -471,6 +477,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
|||
flags[other->id] |= XISlaveDetached;
|
||||
}
|
||||
}
|
||||
|
||||
for (other = inputInfo.off_devices; other; other = other->next) {
|
||||
if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) {
|
||||
AttachDevice(NULL, other, NULL);
|
||||
flags[other->id] |= XISlaveDetached;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (other = inputInfo.devices; other; other = other->next) {
|
||||
|
@ -505,6 +518,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
|||
LeaveWindow(dev);
|
||||
SetFocusOut(dev);
|
||||
|
||||
for (prev = &inputInfo.devices;
|
||||
*prev && (*prev != dev); prev = &(*prev)->next);
|
||||
|
||||
*prev = dev->next;
|
||||
dev->next = inputInfo.off_devices;
|
||||
inputInfo.off_devices = dev;
|
||||
|
@ -520,6 +536,7 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
|||
}
|
||||
|
||||
RecalculateMasterButtons(dev);
|
||||
dev->master = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1064,6 +1081,11 @@ CloseDownDevices(void)
|
|||
dev->master = NULL;
|
||||
}
|
||||
|
||||
for (dev = inputInfo.off_devices; dev; dev = dev->next) {
|
||||
if (!IsMaster(dev) && !IsFloating(dev))
|
||||
dev->master = NULL;
|
||||
}
|
||||
|
||||
CloseDeviceList(&inputInfo.devices);
|
||||
CloseDeviceList(&inputInfo.off_devices);
|
||||
|
||||
|
@ -2525,6 +2547,8 @@ RecalculateMasterButtons(DeviceIntPtr slave)
|
|||
|
||||
if (master->button && master->button->numButtons != maxbuttons) {
|
||||
int i;
|
||||
int last_num_buttons = master->button->numButtons;
|
||||
|
||||
DeviceChangedEvent event = {
|
||||
.header = ET_Internal,
|
||||
.type = ET_DeviceChanged,
|
||||
|
@ -2535,6 +2559,14 @@ RecalculateMasterButtons(DeviceIntPtr slave)
|
|||
};
|
||||
|
||||
master->button->numButtons = maxbuttons;
|
||||
if (last_num_buttons < maxbuttons) {
|
||||
master->button->xkb_acts = xnfreallocarray(master->button->xkb_acts,
|
||||
maxbuttons,
|
||||
sizeof(XkbAction));
|
||||
memset(&master->button->xkb_acts[last_num_buttons],
|
||||
0,
|
||||
(maxbuttons - last_num_buttons) * sizeof(XkbAction));
|
||||
}
|
||||
|
||||
memcpy(&event.buttons.names, master->button->labels, maxbuttons *
|
||||
sizeof(Atom));
|
||||
|
|
|
@ -3780,9 +3780,11 @@ ProcEstablishConnection(ClientPtr client)
|
|||
auth_proto = (char *) prefix + sz_xConnClientPrefix;
|
||||
auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
|
||||
|
||||
if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
|
||||
pad_to_int32(prefix->nbytesAuthProto) +
|
||||
pad_to_int32(prefix->nbytesAuthString))
|
||||
if (client->swapped && !AllowByteSwappedClients) {
|
||||
reason = "Prohibited client endianess, see the Xserver man page ";
|
||||
} else if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
|
||||
pad_to_int32(prefix->nbytesAuthProto) +
|
||||
pad_to_int32(prefix->nbytesAuthString))
|
||||
reason = "Bad length";
|
||||
else if ((prefix->majorVersion != X_PROTOCOL) ||
|
||||
(prefix->minorVersion != X_PROTOCOL_REVISION))
|
||||
|
|
124
dix/enterleave.c
124
dix/enterleave.c
|
@ -615,9 +615,15 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
|
|||
|
||||
ev->type = DeviceValuator;
|
||||
ev->deviceid = dev->id;
|
||||
ev->num_valuators = nval < 3 ? nval : 3;
|
||||
ev->num_valuators = nval < 6 ? nval : 6;
|
||||
ev->first_valuator = first;
|
||||
switch (ev->num_valuators) {
|
||||
case 6:
|
||||
ev->valuator2 = v->axisVal[first + 5];
|
||||
case 5:
|
||||
ev->valuator2 = v->axisVal[first + 4];
|
||||
case 4:
|
||||
ev->valuator2 = v->axisVal[first + 3];
|
||||
case 3:
|
||||
ev->valuator2 = v->axisVal[first + 2];
|
||||
case 2:
|
||||
|
@ -626,7 +632,6 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
|
|||
ev->valuator0 = v->axisVal[first];
|
||||
break;
|
||||
}
|
||||
first += ev->num_valuators;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -646,7 +651,7 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
|
|||
ev->num_buttons = b->numButtons;
|
||||
memcpy((char *) ev->buttons, (char *) b->down, 4);
|
||||
}
|
||||
else if (k) {
|
||||
if (k) {
|
||||
ev->classes_reported |= (1 << KeyClass);
|
||||
ev->num_keys = k->xkbInfo->desc->max_key_code -
|
||||
k->xkbInfo->desc->min_key_code;
|
||||
|
@ -670,14 +675,26 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The device state notify event is split across multiple 32-byte events.
|
||||
* The first one contains the first 32 button state bits, the first 32
|
||||
* key state bits, and the first 3 valuator values.
|
||||
*
|
||||
* If a device has more than that, the server sends out:
|
||||
* - one deviceButtonStateNotify for buttons 32 and above
|
||||
* - one deviceKeyStateNotify for keys 32 and above
|
||||
* - one deviceValuator event per 6 valuators above valuator 4
|
||||
*
|
||||
* All events but the last one have the deviceid binary ORed with MORE_EVENTS,
|
||||
*/
|
||||
static void
|
||||
DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
{
|
||||
/* deviceStateNotify, deviceKeyStateNotify, deviceButtonStateNotify
|
||||
* and one deviceValuator for each 6 valuators */
|
||||
deviceStateNotify sev[3 + (MAX_VALUATORS + 6)/6];
|
||||
int evcount = 1;
|
||||
deviceStateNotify *ev, *sev;
|
||||
deviceKeyStateNotify *kev;
|
||||
deviceButtonStateNotify *bev;
|
||||
deviceStateNotify *ev = sev;
|
||||
|
||||
KeyClassPtr k;
|
||||
ButtonClassPtr b;
|
||||
|
@ -690,87 +707,53 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
|||
|
||||
if ((b = dev->button) != NULL) {
|
||||
nbuttons = b->numButtons;
|
||||
if (nbuttons > 32)
|
||||
if (nbuttons > 32) /* first 32 are encoded in deviceStateNotify */
|
||||
evcount++;
|
||||
}
|
||||
if ((k = dev->key) != NULL) {
|
||||
nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code;
|
||||
if (nkeys > 32)
|
||||
if (nkeys > 32) /* first 32 are encoded in deviceStateNotify */
|
||||
evcount++;
|
||||
if (nbuttons > 0) {
|
||||
evcount++;
|
||||
}
|
||||
}
|
||||
if ((v = dev->valuator) != NULL) {
|
||||
nval = v->numAxes;
|
||||
|
||||
if (nval > 3)
|
||||
evcount++;
|
||||
if (nval > 6) {
|
||||
if (!(k && b))
|
||||
evcount++;
|
||||
if (nval > 9)
|
||||
evcount += ((nval - 7) / 3);
|
||||
}
|
||||
/* first three are encoded in deviceStateNotify, then
|
||||
* it's 6 per deviceValuator event */
|
||||
evcount += ((nval - 3) + 6)/6;
|
||||
}
|
||||
|
||||
sev = ev = xallocarray(evcount, sizeof(xEvent));
|
||||
FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
|
||||
BUG_RETURN(evcount <= ARRAY_SIZE(sev));
|
||||
|
||||
if (b != NULL) {
|
||||
FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
|
||||
first += 3;
|
||||
nval -= 3;
|
||||
if (nbuttons > 32) {
|
||||
(ev - 1)->deviceid |= MORE_EVENTS;
|
||||
bev = (deviceButtonStateNotify *) ev++;
|
||||
bev->type = DeviceButtonStateNotify;
|
||||
bev->deviceid = dev->id;
|
||||
memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
|
||||
DOWN_LENGTH - 4);
|
||||
}
|
||||
if (nval > 0) {
|
||||
(ev - 1)->deviceid |= MORE_EVENTS;
|
||||
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
|
||||
first += 3;
|
||||
nval -= 3;
|
||||
}
|
||||
FixDeviceStateNotify(dev, ev, k, b, v, first);
|
||||
|
||||
if (b != NULL && nbuttons > 32) {
|
||||
deviceButtonStateNotify *bev = (deviceButtonStateNotify *) ++ev;
|
||||
(ev - 1)->deviceid |= MORE_EVENTS;
|
||||
bev->type = DeviceButtonStateNotify;
|
||||
bev->deviceid = dev->id;
|
||||
memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
|
||||
DOWN_LENGTH - 4);
|
||||
}
|
||||
|
||||
if (k != NULL) {
|
||||
FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
|
||||
first += 3;
|
||||
nval -= 3;
|
||||
if (nkeys > 32) {
|
||||
(ev - 1)->deviceid |= MORE_EVENTS;
|
||||
kev = (deviceKeyStateNotify *) ev++;
|
||||
kev->type = DeviceKeyStateNotify;
|
||||
kev->deviceid = dev->id;
|
||||
memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
|
||||
}
|
||||
if (nval > 0) {
|
||||
(ev - 1)->deviceid |= MORE_EVENTS;
|
||||
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
|
||||
first += 3;
|
||||
nval -= 3;
|
||||
}
|
||||
if (k != NULL && nkeys > 32) {
|
||||
deviceKeyStateNotify *kev = (deviceKeyStateNotify *) ++ev;
|
||||
(ev - 1)->deviceid |= MORE_EVENTS;
|
||||
kev->type = DeviceKeyStateNotify;
|
||||
kev->deviceid = dev->id;
|
||||
memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
|
||||
}
|
||||
|
||||
first = 3;
|
||||
nval -= 3;
|
||||
while (nval > 0) {
|
||||
FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
|
||||
first += 3;
|
||||
nval -= 3;
|
||||
if (nval > 0) {
|
||||
(ev - 1)->deviceid |= MORE_EVENTS;
|
||||
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
|
||||
first += 3;
|
||||
nval -= 3;
|
||||
}
|
||||
ev->deviceid |= MORE_EVENTS;
|
||||
FixDeviceValuator(dev, (deviceValuator *) ++ev, v, first);
|
||||
first += 6;
|
||||
nval -= 6;
|
||||
}
|
||||
|
||||
DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
|
||||
DeviceStateNotifyMask, NullGrab);
|
||||
free(sev);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -784,8 +767,9 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
|
|||
|
||||
mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER);
|
||||
|
||||
/* XI 2 event */
|
||||
btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
|
||||
/* XI 2 event contains the logical button map - maps are CARD8
|
||||
* so we need 256 bits for the possibly maximum mapping */
|
||||
btlen = (mouse->button) ? bits_to_bytes(256) : 0;
|
||||
btlen = bytes_to_int32(btlen);
|
||||
len = sizeof(xXIFocusInEvent) + btlen * 4;
|
||||
|
||||
|
|
|
@ -58,8 +58,6 @@ extern void DeviceFocusEvent(DeviceIntPtr dev,
|
|||
|
||||
extern void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode);
|
||||
|
||||
extern void LeaveWindow(DeviceIntPtr dev);
|
||||
|
||||
extern void CoreFocusEvent(DeviceIntPtr kbd,
|
||||
int type, int mode, int detail, WindowPtr pWin);
|
||||
|
||||
|
|
88
dix/events.c
88
dix/events.c
|
@ -467,6 +467,20 @@ WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev)
|
|||
return xi2mask_isset(inputMasks->xi2mask, dev, evtype);
|
||||
}
|
||||
|
||||
/**
|
||||
* When processing events we operate on InternalEvent pointers. They may actually refer to a
|
||||
* an instance of DeviceEvent, GestureEvent or any other event that comprises the InternalEvent
|
||||
* union. This works well in practice because we always look into event type before doing anything,
|
||||
* except in the case of copying the event. Any copying of InternalEvent should use this function
|
||||
* instead of doing *dst_event = *src_event whenever it's not clear whether source event actually
|
||||
* points to full InternalEvent instance.
|
||||
*/
|
||||
void
|
||||
CopyPartialInternalEvent(InternalEvent* dst_event, const InternalEvent* src_event)
|
||||
{
|
||||
memcpy(dst_event, src_event, src_event->any.length);
|
||||
}
|
||||
|
||||
Mask
|
||||
GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients * other)
|
||||
{
|
||||
|
@ -1191,7 +1205,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
|
|||
}
|
||||
}
|
||||
|
||||
eventlen = event->length;
|
||||
eventlen = sizeof(InternalEvent);
|
||||
|
||||
qe = malloc(sizeof(QdEventRec) + eventlen);
|
||||
if (!qe)
|
||||
|
@ -1201,7 +1215,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
|
|||
qe->pScreen = pSprite->hotPhys.pScreen;
|
||||
qe->months = currentTime.months;
|
||||
qe->event = (InternalEvent *) (qe + 1);
|
||||
memcpy(qe->event, event, eventlen);
|
||||
CopyPartialInternalEvent(qe->event, (InternalEvent *)event);
|
||||
xorg_list_append(&qe->next, &syncEvents.pending);
|
||||
}
|
||||
|
||||
|
@ -1319,7 +1333,7 @@ ComputeFreezes(void)
|
|||
|
||||
syncEvents.replayDev = (DeviceIntPtr) NULL;
|
||||
|
||||
if (!CheckDeviceGrabs(replayDev, &event->device_event,
|
||||
if (!CheckDeviceGrabs(replayDev, event,
|
||||
syncEvents.replayWin)) {
|
||||
if (IsTouchEvent(event)) {
|
||||
TouchPointInfoPtr ti =
|
||||
|
@ -1491,16 +1505,13 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
|
|||
CLIENT_BITS(listener->listener) == grab->resource) {
|
||||
if (grab->grabtype == CORE || grab->grabtype == XI ||
|
||||
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin)) {
|
||||
/* Note that the grab will override any current listeners and if these listeners
|
||||
already received touch events then this is the place to send touch end event
|
||||
to complete the touch sequence.
|
||||
|
||||
if (listener->type == TOUCH_LISTENER_REGULAR &&
|
||||
listener->state != TOUCH_LISTENER_AWAITING_BEGIN &&
|
||||
listener->state != TOUCH_LISTENER_HAS_END) {
|
||||
/* if the listener already got any events relating to the touch, we must send
|
||||
a touch end because the grab overrides the previous listener and won't
|
||||
itself send any touch events.
|
||||
*/
|
||||
TouchEmitTouchEnd(mouse, ti, 0, listener->listener);
|
||||
}
|
||||
Unfortunately GTK3 menu widget implementation relies on not getting touch end
|
||||
event, so we can't fix the current behavior.
|
||||
*/
|
||||
listener->type = TOUCH_LISTENER_POINTER_GRAB;
|
||||
} else {
|
||||
listener->type = TOUCH_LISTENER_GRAB;
|
||||
|
@ -3027,7 +3038,7 @@ BOOL
|
|||
ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
DeviceEvent event;
|
||||
InternalEvent event;
|
||||
|
||||
if (dev->deviceGrab.grab) {
|
||||
if (!dev->deviceGrab.fromPassiveGrab ||
|
||||
|
@ -3042,16 +3053,16 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
|
|||
if (win == NoneWin || win == PointerRootWin)
|
||||
return FALSE;
|
||||
|
||||
event = (DeviceEvent) {
|
||||
.header = ET_Internal,
|
||||
.type = ET_FocusIn,
|
||||
.length = sizeof(DeviceEvent),
|
||||
.time = GetTimeInMillis(),
|
||||
.deviceid = dev->id,
|
||||
.sourceid = dev->id,
|
||||
.detail.button = 0
|
||||
event = (InternalEvent) {
|
||||
.device_event.header = ET_Internal,
|
||||
.device_event.type = ET_FocusIn,
|
||||
.device_event.length = sizeof(DeviceEvent),
|
||||
.device_event.time = GetTimeInMillis(),
|
||||
.device_event.deviceid = dev->id,
|
||||
.device_event.sourceid = dev->id,
|
||||
.device_event.detail.button = 0
|
||||
};
|
||||
rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
|
||||
rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE,
|
||||
TRUE) != NULL);
|
||||
if (rc)
|
||||
DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab);
|
||||
|
@ -3068,7 +3079,7 @@ static BOOL
|
|||
ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
DeviceEvent event;
|
||||
InternalEvent event;
|
||||
|
||||
if (dev->deviceGrab.grab) {
|
||||
if (!dev->deviceGrab.fromPassiveGrab ||
|
||||
|
@ -3080,16 +3091,16 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
|
|||
(*dev->deviceGrab.DeactivateGrab) (dev);
|
||||
}
|
||||
|
||||
event = (DeviceEvent) {
|
||||
.header = ET_Internal,
|
||||
.type = ET_Enter,
|
||||
.length = sizeof(DeviceEvent),
|
||||
.time = GetTimeInMillis(),
|
||||
.deviceid = dev->id,
|
||||
.sourceid = dev->id,
|
||||
.detail.button = 0
|
||||
event = (InternalEvent) {
|
||||
.device_event.header = ET_Internal,
|
||||
.device_event.type = ET_Enter,
|
||||
.device_event.length = sizeof(DeviceEvent),
|
||||
.device_event.time = GetTimeInMillis(),
|
||||
.device_event.deviceid = dev->id,
|
||||
.device_event.sourceid = dev->id,
|
||||
.device_event.detail.button = 0
|
||||
};
|
||||
rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
|
||||
rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE,
|
||||
TRUE) != NULL);
|
||||
if (rc)
|
||||
DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab);
|
||||
|
@ -3873,7 +3884,7 @@ void ActivateGrabNoDelivery(DeviceIntPtr dev, GrabPtr grab,
|
|||
|
||||
if (grabinfo->sync.state == FROZEN_NO_EVENT)
|
||||
grabinfo->sync.state = FROZEN_WITH_EVENT;
|
||||
*grabinfo->sync.event = *real_event;
|
||||
CopyPartialInternalEvent(grabinfo->sync.event, real_event);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
|
@ -4141,14 +4152,15 @@ CheckPassiveGrabsOnWindow(WindowPtr pWin,
|
|||
*/
|
||||
|
||||
Bool
|
||||
CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
|
||||
CheckDeviceGrabs(DeviceIntPtr device, InternalEvent *ievent, WindowPtr ancestor)
|
||||
{
|
||||
int i;
|
||||
WindowPtr pWin = NULL;
|
||||
FocusClassPtr focus =
|
||||
IsPointerEvent((InternalEvent *) event) ? NULL : device->focus;
|
||||
IsPointerEvent(ievent) ? NULL : device->focus;
|
||||
BOOL sendCore = (IsMaster(device) && device->coreEvents);
|
||||
Bool ret = FALSE;
|
||||
DeviceEvent *event = &ievent->device_event;
|
||||
|
||||
if (event->type != ET_ButtonPress && event->type != ET_KeyPress)
|
||||
return FALSE;
|
||||
|
@ -4171,7 +4183,7 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
|
|||
if (focus) {
|
||||
for (; i < focus->traceGood; i++) {
|
||||
pWin = focus->trace[i];
|
||||
if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
|
||||
if (CheckPassiveGrabsOnWindow(pWin, device, ievent,
|
||||
sendCore, TRUE)) {
|
||||
ret = TRUE;
|
||||
goto out;
|
||||
|
@ -4186,7 +4198,7 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
|
|||
|
||||
for (; i < device->spriteInfo->sprite->spriteTraceGood; i++) {
|
||||
pWin = device->spriteInfo->sprite->spriteTrace[i];
|
||||
if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
|
||||
if (CheckPassiveGrabsOnWindow(pWin, device, ievent,
|
||||
sendCore, TRUE)) {
|
||||
ret = TRUE;
|
||||
goto out;
|
||||
|
@ -4454,7 +4466,7 @@ FreezeThisEventIfNeededForSyncGrab(DeviceIntPtr thisDev, InternalEvent *event)
|
|||
case FREEZE_NEXT_EVENT:
|
||||
grabinfo->sync.state = FROZEN_WITH_EVENT;
|
||||
FreezeThaw(thisDev, TRUE);
|
||||
*grabinfo->sync.event = *event;
|
||||
CopyPartialInternalEvent(grabinfo->sync.event, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,14 +155,13 @@ dixMovePrivates(PrivatePtr *privates, int new_offset, unsigned bytes)
|
|||
static Bool
|
||||
fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes)
|
||||
{
|
||||
intptr_t dist;
|
||||
char *old;
|
||||
uintptr_t old;
|
||||
char *new;
|
||||
DevPrivateKey *keyp, key;
|
||||
DevPrivateType type;
|
||||
int size;
|
||||
|
||||
old = (char *) pScreen->devPrivates;
|
||||
old = (uintptr_t) pScreen->devPrivates;
|
||||
size = global_keys[PRIVATE_SCREEN].offset;
|
||||
if (!fixup (&pScreen->devPrivates, size, bytes))
|
||||
return FALSE;
|
||||
|
@ -182,9 +181,7 @@ fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes)
|
|||
if (fixup == dixMovePrivates)
|
||||
new += bytes;
|
||||
|
||||
dist = new - old;
|
||||
|
||||
if (dist) {
|
||||
if ((uintptr_t) new != old) {
|
||||
for (type = PRIVATE_XSELINUX; type < PRIVATE_LAST; type++)
|
||||
|
||||
/* Walk the privates list, being careful as the
|
||||
|
@ -199,10 +196,11 @@ fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes)
|
|||
* is contained within the allocation. Privates
|
||||
* stored elsewhere will be left alone
|
||||
*/
|
||||
if (old <= (char *) key && (char *) key < old + size)
|
||||
if (old <= (uintptr_t) key && (uintptr_t) key < old + size)
|
||||
{
|
||||
/* Compute new location of key */
|
||||
key = (DevPrivateKey) ((char *) key + dist);
|
||||
/* Compute new location of key (deriving from the new
|
||||
* allocation to avoid UB) */
|
||||
key = (DevPrivateKey) (new + ((uintptr_t) key - old));
|
||||
|
||||
/* Patch the list */
|
||||
*keyp = key;
|
||||
|
|
|
@ -205,7 +205,8 @@ ProcChangeProperty(ClientPtr client)
|
|||
WindowPtr pWin;
|
||||
char format, mode;
|
||||
unsigned long len;
|
||||
int sizeInBytes, totalSize, err;
|
||||
int sizeInBytes, err;
|
||||
uint64_t totalSize;
|
||||
|
||||
REQUEST(xChangePropertyReq);
|
||||
|
||||
|
|
|
@ -620,12 +620,15 @@ ilog2(int val)
|
|||
unsigned int
|
||||
ResourceClientBits(void)
|
||||
{
|
||||
static unsigned int cached = 0;
|
||||
static unsigned int cache_ilog2 = 0;
|
||||
static unsigned int cache_limit = 0;
|
||||
|
||||
if (cached == 0)
|
||||
cached = ilog2(LimitClients);
|
||||
if (LimitClients != cache_limit) {
|
||||
cache_limit = LimitClients;
|
||||
cache_ilog2 = ilog2(LimitClients);
|
||||
}
|
||||
|
||||
return cached;
|
||||
return cache_ilog2;
|
||||
}
|
||||
|
||||
/*****************
|
||||
|
|
|
@ -260,8 +260,8 @@ glamor_build_program(ScreenPtr screen,
|
|||
char *fs_vars = NULL;
|
||||
char *vs_vars = NULL;
|
||||
|
||||
char *vs_prog_string;
|
||||
char *fs_prog_string;
|
||||
char *vs_prog_string = NULL;
|
||||
char *fs_prog_string = NULL;
|
||||
|
||||
GLint fs_prog, vs_prog;
|
||||
Bool gpu_shader4 = FALSE;
|
||||
|
@ -383,6 +383,8 @@ fail:
|
|||
glDeleteProgram(prog->prog);
|
||||
prog->prog = 0;
|
||||
}
|
||||
free(vs_prog_string);
|
||||
free(fs_prog_string);
|
||||
free(version_string);
|
||||
free(fs_vars);
|
||||
free(vs_vars);
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "indirect_util.h"
|
||||
#include "protocol-versions.h"
|
||||
#include "glxvndabi.h"
|
||||
#include "xace.h"
|
||||
|
||||
static char GLXServerVendorName[] = "SGI";
|
||||
|
||||
|
@ -1392,6 +1393,13 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
|
|||
if (!pPixmap)
|
||||
return BadAlloc;
|
||||
|
||||
err = XaceHook(XACE_RESOURCE_ACCESS, client, glxDrawableId, RT_PIXMAP,
|
||||
pPixmap, RT_NONE, NULL, DixCreateAccess);
|
||||
if (err != Success) {
|
||||
(*pGlxScreen->pScreen->DestroyPixmap) (pPixmap);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Assign the pixmap the same id as the pbuffer and add it as a
|
||||
* resource so it and the DRI2 drawable will be reclaimed when the
|
||||
* pbuffer is destroyed. */
|
||||
|
|
|
@ -115,6 +115,16 @@ render_type_is_pbuffer_only(unsigned renderType)
|
|||
| __DRI_ATTRIB_FLOAT_BIT));
|
||||
}
|
||||
|
||||
static int
|
||||
server_has_depth(int depth)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < screenInfo.numPixmapFormats; i++)
|
||||
if (screenInfo.formats[i].depth == depth)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __GLXconfig *
|
||||
createModeFromConfig(const __DRIcoreExtension * core,
|
||||
const __DRIconfig * driConfig,
|
||||
|
@ -178,6 +188,16 @@ createModeFromConfig(const __DRIcoreExtension * core,
|
|||
if (!render_type_is_pbuffer_only(renderType))
|
||||
drawableType |= GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
|
||||
|
||||
/* Make sure we don't advertise things the server isn't configured for */
|
||||
if ((drawableType & (GLX_PBUFFER_BIT | GLX_PIXMAP_BIT)) &&
|
||||
!server_has_depth(config->config.rgbBits)) {
|
||||
drawableType &= ~(GLX_PBUFFER_BIT | GLX_PIXMAP_BIT);
|
||||
if (!drawableType) {
|
||||
free(config);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
config->config.next = NULL;
|
||||
config->config.visualType = visualType;
|
||||
config->config.renderType = renderType;
|
||||
|
|
|
@ -22,20 +22,15 @@ if XQUARTZ
|
|||
XQUARTZ_SUBDIRS = xquartz
|
||||
endif
|
||||
|
||||
if XWAYLAND
|
||||
XWAYLAND_SUBDIRS = xwayland
|
||||
endif
|
||||
|
||||
SUBDIRS = \
|
||||
$(XORG_SUBDIRS) \
|
||||
$(XWIN_SUBDIRS) \
|
||||
$(XVFB_SUBDIRS) \
|
||||
$(XNEST_SUBDIRS) \
|
||||
$(KDRIVE_SUBDIRS) \
|
||||
$(XQUARTZ_SUBDIRS) \
|
||||
$(XWAYLAND_SUBDIRS)
|
||||
$(XQUARTZ_SUBDIRS)
|
||||
|
||||
DIST_SUBDIRS = xfree86 vfb xnest xwin xquartz kdrive xwayland
|
||||
DIST_SUBDIRS = xfree86 vfb xnest xwin xquartz kdrive
|
||||
|
||||
relink:
|
||||
$(AM_V_at)for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink || exit 1 ; done
|
||||
|
|
|
@ -50,16 +50,16 @@ ephyr_glamor_xv_stop_video(KdScreenInfo *screen, void *data, Bool cleanup)
|
|||
|
||||
static int
|
||||
ephyr_glamor_xv_set_port_attribute(KdScreenInfo *screen,
|
||||
Atom attribute, INT32 value, void *data)
|
||||
Atom attribute, int value, void *data)
|
||||
{
|
||||
return glamor_xv_set_port_attribute(data, attribute, value);
|
||||
return glamor_xv_set_port_attribute(data, attribute, (INT32)value);
|
||||
}
|
||||
|
||||
static int
|
||||
ephyr_glamor_xv_get_port_attribute(KdScreenInfo *screen,
|
||||
Atom attribute, INT32 *value, void *data)
|
||||
Atom attribute, int *value, void *data)
|
||||
{
|
||||
return glamor_xv_get_port_attribute(data, attribute, value);
|
||||
return glamor_xv_get_port_attribute(data, attribute, (INT32 *)value);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -246,7 +246,7 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
|
|||
Bool
|
||||
ephyrCursorInit(ScreenPtr screen)
|
||||
{
|
||||
if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR_BITS,
|
||||
if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR,
|
||||
sizeof(ephyrCursorRec)))
|
||||
return FALSE;
|
||||
|
||||
|
|
|
@ -70,25 +70,23 @@ InitInput(int argc, char **argv)
|
|||
KdKeyboardInfo *ki;
|
||||
KdPointerInfo *pi;
|
||||
|
||||
if (!SeatId) {
|
||||
KdAddKeyboardDriver(&EphyrKeyboardDriver);
|
||||
KdAddPointerDriver(&EphyrMouseDriver);
|
||||
KdAddKeyboardDriver(&EphyrKeyboardDriver);
|
||||
KdAddPointerDriver(&EphyrMouseDriver);
|
||||
|
||||
if (!kdHasKbd) {
|
||||
ki = KdNewKeyboard();
|
||||
if (!ki)
|
||||
FatalError("Couldn't create Xephyr keyboard\n");
|
||||
ki->driver = &EphyrKeyboardDriver;
|
||||
KdAddKeyboard(ki);
|
||||
}
|
||||
if (!kdHasKbd) {
|
||||
ki = KdNewKeyboard();
|
||||
if (!ki)
|
||||
FatalError("Couldn't create Xephyr keyboard\n");
|
||||
ki->driver = &EphyrKeyboardDriver;
|
||||
KdAddKeyboard(ki);
|
||||
}
|
||||
|
||||
if (!kdHasPointer) {
|
||||
pi = KdNewPointer();
|
||||
if (!pi)
|
||||
FatalError("Couldn't create Xephyr pointer\n");
|
||||
pi->driver = &EphyrMouseDriver;
|
||||
KdAddPointer(pi);
|
||||
}
|
||||
if (!kdHasPointer) {
|
||||
pi = KdNewPointer();
|
||||
if (!pi)
|
||||
FatalError("Couldn't create Xephyr pointer\n");
|
||||
pi->driver = &EphyrMouseDriver;
|
||||
KdAddPointer(pi);
|
||||
}
|
||||
|
||||
KdInitInput();
|
||||
|
|
|
@ -18,10 +18,6 @@ if build_xquartz
|
|||
subdir('xquartz')
|
||||
endif
|
||||
|
||||
if build_xwayland
|
||||
subdir('xwayland')
|
||||
endif
|
||||
|
||||
if build_xwin
|
||||
subdir('xwin')
|
||||
endif
|
||||
|
|
|
@ -71,6 +71,10 @@ endif
|
|||
|
||||
if get_option('pciaccess')
|
||||
srcs_xorg_common += ['xf86pciBus.c', 'xf86VGAarbiter.c']
|
||||
|
||||
if host_machine.cpu() == 'sparc' or host_machine.cpu() == 'sparc64'
|
||||
srcs_xorg_common += 'xf86sbusBus.c'
|
||||
endif
|
||||
endif
|
||||
|
||||
srcs_xorg_common += custom_target(
|
||||
|
|
|
@ -646,6 +646,7 @@ typedef enum {
|
|||
FLAG_MAX_CLIENTS,
|
||||
FLAG_IGLX,
|
||||
FLAG_DEBUG,
|
||||
FLAG_ALLOW_BYTE_SWAPPED_CLIENTS,
|
||||
} FlagValues;
|
||||
|
||||
/**
|
||||
|
@ -705,6 +706,8 @@ static OptionInfoRec FlagOptions[] = {
|
|||
{0}, FALSE},
|
||||
{FLAG_DEBUG, "Debug", OPTV_STRING,
|
||||
{0}, FALSE},
|
||||
{FLAG_ALLOW_BYTE_SWAPPED_CLIENTS, "AllowByteSwappedClients", OPTV_BOOLEAN,
|
||||
{0}, FALSE},
|
||||
{-1, NULL, OPTV_NONE,
|
||||
{0}, FALSE},
|
||||
};
|
||||
|
@ -746,6 +749,14 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
|
|||
xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
|
||||
}
|
||||
|
||||
xf86GetOptValBool(FlagOptions, FLAG_ALLOW_BYTE_SWAPPED_CLIENTS, &AllowByteSwappedClients);
|
||||
if (AllowByteSwappedClients) {
|
||||
xf86Msg(X_CONFIG, "Allowing byte-swapped clients\n");
|
||||
}
|
||||
else {
|
||||
xf86Msg(X_CONFIG, "Prohibiting byte-swapped clients\n");
|
||||
}
|
||||
|
||||
if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
|
||||
xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
|
||||
&xf86Info.autoAddDevices);
|
||||
|
|
|
@ -382,6 +382,10 @@ xf86VTLeave(void)
|
|||
for (i = 0; i < xf86NumGPUScreens; i++)
|
||||
xf86GPUScreens[i]->LeaveVT(xf86GPUScreens[i]);
|
||||
|
||||
if (systemd_logind_controls_session()) {
|
||||
systemd_logind_drop_master();
|
||||
}
|
||||
|
||||
if (!xf86VTSwitchAway())
|
||||
goto switch_failed;
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include "xf86Xinput.h"
|
||||
#include "xf86InPriv.h"
|
||||
#include "mivalidate.h"
|
||||
#include "xf86Crtc.h"
|
||||
|
||||
/* For xf86GetClocks */
|
||||
#if defined(CSRG_BASED) || defined(__GNU__)
|
||||
|
@ -852,9 +851,8 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
|
|||
{
|
||||
MessageType from = X_DEFAULT;
|
||||
xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC);
|
||||
int probedWidthmm, probedHeightmm;
|
||||
int ddcWidthmm, ddcHeightmm;
|
||||
int widthErr, heightErr;
|
||||
xf86OutputPtr compat = xf86CompatOutput(pScrn);
|
||||
|
||||
/* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
|
||||
pScrn->widthmm = pScrn->monitor->widthmm;
|
||||
|
@ -864,15 +862,11 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
|
|||
/* DDC gives display size in mm for individual modes,
|
||||
* but cm for monitor
|
||||
*/
|
||||
probedWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
|
||||
probedHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
|
||||
}
|
||||
else if (compat && compat->mm_width > 0 && compat->mm_height > 0) {
|
||||
probedWidthmm = compat->mm_width;
|
||||
probedHeightmm = compat->mm_height;
|
||||
ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
|
||||
ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
|
||||
}
|
||||
else {
|
||||
probedWidthmm = probedHeightmm = 0;
|
||||
ddcWidthmm = ddcHeightmm = 0;
|
||||
}
|
||||
|
||||
if (monitorResolution > 0) {
|
||||
|
@ -898,15 +892,15 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
|
|||
pScrn->widthmm, pScrn->heightmm);
|
||||
|
||||
/* Warn if config and probe disagree about display size */
|
||||
if (probedWidthmm && probedHeightmm) {
|
||||
if (ddcWidthmm && ddcHeightmm) {
|
||||
if (pScrn->widthmm > 0) {
|
||||
widthErr = abs(probedWidthmm - pScrn->widthmm);
|
||||
widthErr = abs(ddcWidthmm - pScrn->widthmm);
|
||||
}
|
||||
else {
|
||||
widthErr = 0;
|
||||
}
|
||||
if (pScrn->heightmm > 0) {
|
||||
heightErr = abs(probedHeightmm - pScrn->heightmm);
|
||||
heightErr = abs(ddcHeightmm - pScrn->heightmm);
|
||||
}
|
||||
else {
|
||||
heightErr = 0;
|
||||
|
@ -915,17 +909,17 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
|
|||
/* Should include config file name for monitor here */
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
|
||||
"Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
|
||||
probedWidthmm, probedHeightmm, pScrn->widthmm,
|
||||
ddcWidthmm, ddcHeightmm, pScrn->widthmm,
|
||||
pScrn->heightmm);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (probedWidthmm && probedHeightmm) {
|
||||
else if (ddcWidthmm && ddcHeightmm) {
|
||||
from = X_PROBED;
|
||||
xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
|
||||
probedWidthmm, probedHeightmm);
|
||||
pScrn->widthmm = probedWidthmm;
|
||||
pScrn->heightmm = probedHeightmm;
|
||||
ddcWidthmm, ddcHeightmm);
|
||||
pScrn->widthmm = ddcWidthmm;
|
||||
pScrn->heightmm = ddcHeightmm;
|
||||
if (pScrn->widthmm > 0) {
|
||||
pScrn->xDpi =
|
||||
(int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm);
|
||||
|
|
|
@ -85,6 +85,11 @@
|
|||
#include <X11/extensions/dpmsconst.h>
|
||||
#include "dpmsproc.h"
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/major.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
#include <hotplug.h>
|
||||
|
||||
void (*xf86OSPMClose) (void) = NULL;
|
||||
|
@ -105,23 +110,10 @@ static PixmapFormatRec formats[MAXFORMATS] = {
|
|||
static int numFormats = 7;
|
||||
static Bool formatsDone = FALSE;
|
||||
|
||||
#ifndef PRE_RELEASE
|
||||
#define PRE_RELEASE XORG_VERSION_SNAP
|
||||
#endif
|
||||
|
||||
static void
|
||||
xf86PrintBanner(void)
|
||||
{
|
||||
#if PRE_RELEASE
|
||||
xf86ErrorFVerb(0, "\n"
|
||||
"This is a pre-release version of the X server from "
|
||||
XVENDORNAME ".\n" "It is not supported in any way.\n"
|
||||
"Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
|
||||
"Select the \"xorg\" product for bugs you find in this release.\n"
|
||||
"Before reporting bugs in pre-release versions please check the\n"
|
||||
"latest version in the X.Org Foundation git repository.\n"
|
||||
"See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
|
||||
#endif
|
||||
xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
|
||||
XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH);
|
||||
#if XORG_VERSION_SNAP > 0
|
||||
|
@ -201,6 +193,17 @@ xf86PrivsElevated(void)
|
|||
return PrivsElevated();
|
||||
}
|
||||
|
||||
Bool
|
||||
xf86HasTTYs(void)
|
||||
{
|
||||
#ifdef __linux__
|
||||
struct stat tty0devAttributes;
|
||||
return (stat("/dev/tty0", &tty0devAttributes) == 0 && major(tty0devAttributes.st_rdev) == TTY_MAJOR);
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
xf86AutoConfigOutputDevices(void)
|
||||
{
|
||||
|
@ -425,7 +428,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
|
|||
want_hw_access = TRUE;
|
||||
|
||||
/* Non-seat0 X servers should not open console */
|
||||
if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0())
|
||||
if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0() && xf86HasTTYs())
|
||||
xorgHWOpenConsole = TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -507,6 +507,8 @@ xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
|
|||
/* scan through the modes in the sort order above */
|
||||
if ((p->type & type) != type)
|
||||
continue;
|
||||
if (p->name == NULL)
|
||||
continue;
|
||||
|
||||
if (strcmp(p->name, modep->name) == 0) {
|
||||
|
||||
|
|
|
@ -158,6 +158,8 @@ extern _X_EXPORT Bool
|
|||
xf86CallDriverProbe(struct _DriverRec *drv, Bool detect_only);
|
||||
extern _X_EXPORT Bool
|
||||
xf86PrivsElevated(void);
|
||||
extern _X_EXPORT Bool
|
||||
xf86HasTTYs(void);
|
||||
|
||||
#endif /* _NO_XF86_PROTOTYPES */
|
||||
|
||||
|
|
|
@ -557,8 +557,13 @@ xf86platformProbeDev(DriverPtr drvp)
|
|||
}
|
||||
else {
|
||||
/* for non-seat0 servers assume first device is the master */
|
||||
if (ServerIsNotSeat0())
|
||||
if (ServerIsNotSeat0()) {
|
||||
break;
|
||||
} else {
|
||||
/* Accept the device if the driver is simpledrm */
|
||||
if (strcmp(xf86_platform_devices[j].attribs->driver, "simpledrm") == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (xf86IsPrimaryPlatform(&xf86_platform_devices[j]))
|
||||
break;
|
||||
|
|
|
@ -507,7 +507,7 @@ handle_detailed_print(struct detailed_monitor_section *det_mon, void *data)
|
|||
}
|
||||
if (det_mon->type >= DS_VENDOR && det_mon->type <= DS_VENDOR_MAX) {
|
||||
xf86DrvMsg(scrnIndex, X_INFO,
|
||||
"Unknown vendor-specific block %hx\n",
|
||||
"Unknown vendor-specific block %x\n",
|
||||
det_mon->type - DS_VENDOR);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\" shorthand for double quote that works everywhere.
|
||||
.ds q \N'34'
|
||||
.TH INPUTTEST __drivermansuffix__ __vendorversion__
|
||||
.TH INPUTTEST @drivermansuffix@ @vendorversion@
|
||||
.SH NAME
|
||||
inputtest \- An X.Org input driver for testing
|
||||
.SH SYNOPSIS
|
||||
|
@ -21,7 +21,7 @@ exposed by Xorg. The primary use cases of this input driver are various
|
|||
integration tests that need to interface with the input subsystem.
|
||||
|
||||
.SH CONFIGURATION DETAILS
|
||||
Please refer to __xconfigfile__(__filemansuffix__) for general configuration
|
||||
Please refer to @xconfigfile@(@filemansuffix@) for general configuration
|
||||
details and for options that can be used with all input drivers. This
|
||||
section only covers configuration details specific to this driver.
|
||||
.PP
|
||||
|
@ -109,4 +109,4 @@ processed all input events sent to it so far.
|
|||
.SH AUTHORS
|
||||
Povilas Kanapickas <povilas@radix.lt>
|
||||
.SH "SEE ALSO"
|
||||
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
|
||||
@xservername@(@appmansuffix@), @xconfigfile@(@filemansuffix@), Xserver(@appmansuffix@), X(@miscmansuffix@)
|
||||
|
|
|
@ -856,39 +856,48 @@ read_input_from_connection(InputInfoPtr pInfo)
|
|||
driver_data->buffer.valid_length += read_size;
|
||||
|
||||
while (1) {
|
||||
xf86ITEventHeader *event_header;
|
||||
xf86ITEventHeader event_header;
|
||||
char *event_begin = driver_data->buffer.data + processed_size;
|
||||
|
||||
if (driver_data->buffer.valid_length - processed_size < sizeof(xf86ITEventHeader))
|
||||
break;
|
||||
|
||||
event_header = (xf86ITEventHeader*) event_begin;
|
||||
/* Note that event_begin pointer is not aligned, accessing it directly is
|
||||
undefined behavior. We must use memcpy to copy the data to aligned data
|
||||
area. Most compilers will optimize out this call out and use whatever
|
||||
is most efficient to access unaligned data on a particular platform */
|
||||
memcpy(&event_header, event_begin, sizeof(xf86ITEventHeader));
|
||||
|
||||
if (event_header->length >= EVENT_BUFFER_SIZE) {
|
||||
if (event_header.length >= EVENT_BUFFER_SIZE) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR, "Received event with too long length: %d\n",
|
||||
event_header->length);
|
||||
event_header.length);
|
||||
teardown_client_connection(pInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (driver_data->buffer.valid_length - processed_size < event_header->length)
|
||||
if (driver_data->buffer.valid_length - processed_size < event_header.length)
|
||||
break;
|
||||
|
||||
if (is_supported_event(event_header->type)) {
|
||||
int expected_event_size = get_event_size(event_header->type);
|
||||
if (is_supported_event(event_header.type)) {
|
||||
int expected_event_size = get_event_size(event_header.type);
|
||||
|
||||
if (event_header->length != expected_event_size) {
|
||||
if (event_header.length != expected_event_size) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR, "Unexpected event length: was %d bytes, "
|
||||
"expected %d (event type: %d)\n",
|
||||
event_header->length, expected_event_size,
|
||||
(int) event_header->type);
|
||||
event_header.length, expected_event_size,
|
||||
(int) event_header.type);
|
||||
teardown_client_connection(pInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
handle_event(pInfo, (xf86ITEventAny*) event_begin);
|
||||
/* We could use event_begin pointer directly, but we want to ensure correct
|
||||
data alignment (if only so that address sanitizer does not complain) */
|
||||
xf86ITEventAny event_data;
|
||||
memset(&event_data, 0, sizeof(event_data));
|
||||
memcpy(&event_data, event_begin, event_header.length);
|
||||
handle_event(pInfo, &event_data);
|
||||
}
|
||||
processed_size += event_header->length;
|
||||
processed_size += event_header.length;
|
||||
}
|
||||
|
||||
if (processed_size > 0) {
|
||||
|
@ -1005,7 +1014,19 @@ pre_init(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
|
|||
|
||||
unlink(driver_data->socket_path);
|
||||
|
||||
#ifdef SOCK_NONBLOCK
|
||||
driver_data->socket_fd = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||
#else
|
||||
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd >= 0) {
|
||||
flags = fcntl(fd, F_GETFL, 0);
|
||||
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
driver_data->socket_fd = fd;
|
||||
#endif
|
||||
|
||||
if (driver_data->socket_fd < 0) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR, "Failed to create a socket for communication: %s\n",
|
||||
strerror(errno));
|
||||
|
|
|
@ -1086,7 +1086,8 @@ ms_dri2_screen_init(ScreenPtr screen)
|
|||
* guess that the DRI and VDPAU drivers have the same name.
|
||||
*/
|
||||
if (strcmp(driver_names[0], "i965") == 0 ||
|
||||
strcmp(driver_names[0], "iris") == 0) {
|
||||
strcmp(driver_names[0], "iris") == 0 ||
|
||||
strcmp(driver_names[0], "crocus") == 0) {
|
||||
driver_names[1] = "va_gl";
|
||||
} else {
|
||||
driver_names[1] = driver_names[0];
|
||||
|
|
|
@ -2404,24 +2404,23 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res
|
|||
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
|
||||
"Allocated crtc nr. %d to this screen.\n", num);
|
||||
|
||||
drmmode_crtc->use_gamma_lut =
|
||||
drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].prop_id &&
|
||||
/* Only use GAMMA_LUT if the size is 1024.
|
||||
*
|
||||
* Currently, the modesetting driver always passes a sigRGBbits value of
|
||||
* 10 to xf86HandleColormaps. This causes it to create a RRCrtc gamma
|
||||
* ramp of 1024 elements. If DRMMODE_CRTC_GAMMA_LUT_SIZE is larger than
|
||||
* 1024 (for example on Intel GEN11, where it has a value of 262145)
|
||||
* then xf86RandR12CrtcSetGamma will read past the end of the RRCrtc's
|
||||
* gamma ramp when trying to copy it into the larger xf86Crtc gamma
|
||||
* ramp.
|
||||
*
|
||||
* Since the larger GEN11 gamma ramp size hasn't been tested, just
|
||||
* disable it for now. This will cause the modesetting driver to disable
|
||||
* the CTM property and use the legacy DRM gamma ramp rather than the
|
||||
* GAMMA_LUT property. */
|
||||
drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value == 1024 &&
|
||||
xf86ReturnOptValBool(drmmode->Options, OPTION_USE_GAMMA_LUT, TRUE);
|
||||
if (drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].prop_id &&
|
||||
drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value) {
|
||||
/*
|
||||
* GAMMA_LUT property supported, and so far tested to be safe to use by
|
||||
* default for lut sizes up to 4096 slots. Intel Tigerlake+ has some
|
||||
* issues, and a large GAMMA_LUT with 262145 slots, so keep GAMMA_LUT
|
||||
* off for large lut sizes by default for now.
|
||||
*/
|
||||
drmmode_crtc->use_gamma_lut = drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value <= 4096;
|
||||
|
||||
/* Allow config override. */
|
||||
drmmode_crtc->use_gamma_lut = xf86ReturnOptValBool(drmmode->Options,
|
||||
OPTION_USE_GAMMA_LUT,
|
||||
drmmode_crtc->use_gamma_lut);
|
||||
} else {
|
||||
drmmode_crtc->use_gamma_lut = FALSE;
|
||||
}
|
||||
|
||||
if (drmmode_crtc->use_gamma_lut &&
|
||||
drmmode_crtc->props[DRMMODE_CRTC_CTM].prop_id) {
|
||||
|
@ -3310,7 +3309,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
|
|||
}
|
||||
}
|
||||
|
||||
ms->is_connector_vrr_capable =
|
||||
ms->is_connector_vrr_capable |=
|
||||
drmmode_connector_check_vrr_capable(drmmode->fd,
|
||||
drmmode_output->output_id);
|
||||
return 1;
|
||||
|
|
|
@ -71,6 +71,13 @@ One of \*qglamor\*q or \*qnone\*q. Default: glamor.
|
|||
Enable DRI3 page flipping. The default is
|
||||
.B on.
|
||||
.TP
|
||||
.BI "Option \*qVariableRefresh\*q \*q" boolean \*q
|
||||
Enables support for enabling variable refresh on the Screen's CRTCs
|
||||
when an suitable application is flipping via the Present extension.
|
||||
.br
|
||||
The default is
|
||||
.B off.
|
||||
.TP
|
||||
.BI "Option \*qAsyncFlipSecondaries\*q \*q" boolean \*q
|
||||
Use async flips for secondary video outputs on multi-display setups. If a screen
|
||||
has multiple displays attached and DRI3 page flipping is used, then only one of
|
||||
|
@ -99,8 +106,8 @@ will assign xrandr outputs LVDS and VGA-0 to this instance of the driver.
|
|||
.BI "Option \*qUseGammaLUT\*q \*q" boolean \*q
|
||||
Enable or disable use of the GAMMA_LUT property, when available.
|
||||
When enabled, this option allows the driver to use gamma ramps with more
|
||||
entries, if supported by the kernel.
|
||||
Default: on.
|
||||
entries, if supported by the kernel. By default, GAMMA_LUT will be used for
|
||||
kms drivers which are known to be safe for use of GAMMA_LUT.
|
||||
.TP
|
||||
.SH "SEE ALSO"
|
||||
@xservername@(@appmansuffix@), @xconfigfile@(@filemansuffix@), Xserver(@appmansuffix@),
|
||||
|
|
|
@ -120,7 +120,8 @@ static RRCrtcPtr
|
|||
rr_crtc_covering_box(ScreenPtr pScreen, BoxPtr box, Bool screen_is_xf86_hint)
|
||||
{
|
||||
rrScrPrivPtr pScrPriv;
|
||||
RRCrtcPtr crtc, best_crtc;
|
||||
RROutputPtr primary_output;
|
||||
RRCrtcPtr crtc, best_crtc, primary_crtc;
|
||||
int coverage, best_coverage;
|
||||
int c;
|
||||
BoxRec crtc_box, cover_box;
|
||||
|
@ -136,6 +137,11 @@ rr_crtc_covering_box(ScreenPtr pScreen, BoxPtr box, Bool screen_is_xf86_hint)
|
|||
if (!pScrPriv)
|
||||
return NULL;
|
||||
|
||||
primary_crtc = NULL;
|
||||
primary_output = RRFirstOutput(pScreen);
|
||||
if (primary_output)
|
||||
primary_crtc = primary_output->crtc;
|
||||
|
||||
for (c = 0; c < pScrPriv->numCrtcs; c++) {
|
||||
crtc = pScrPriv->crtcs[c];
|
||||
|
||||
|
@ -146,7 +152,8 @@ rr_crtc_covering_box(ScreenPtr pScreen, BoxPtr box, Bool screen_is_xf86_hint)
|
|||
rr_crtc_box(crtc, &crtc_box);
|
||||
box_intersect(&cover_box, &crtc_box, box);
|
||||
coverage = box_area(&cover_box);
|
||||
if (coverage > best_coverage) {
|
||||
if ((coverage > best_coverage) ||
|
||||
(coverage == best_coverage && crtc == primary_crtc)) {
|
||||
best_crtc = crtc;
|
||||
best_coverage = coverage;
|
||||
}
|
||||
|
|
|
@ -677,6 +677,9 @@ Possible values are
|
|||
or
|
||||
.BR sync .
|
||||
Unset by default.
|
||||
.TP 7
|
||||
.BI "Option \*qAllowByteSwappedClients\*q \*q" boolean \*q
|
||||
Allow clients with a different byte-order than the server. Enabled by default.
|
||||
.SH "MODULE SECTION"
|
||||
The
|
||||
.B Module
|
||||
|
|
|
@ -75,7 +75,7 @@ endif
|
|||
|
||||
if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
|
||||
linker_export_flags = '-Wl,--export-all-symbols'
|
||||
elif host_machine.system() == 'sunos'
|
||||
elif host_machine.system() == 'sunos' or host_machine.system() == 'darwin'
|
||||
linker_export_flags = []
|
||||
else
|
||||
linker_export_flags = '-Wl,--export-dynamic'
|
||||
|
|
|
@ -3256,10 +3256,8 @@ xf86OutputSetEDID(xf86OutputPtr output, xf86MonPtr edid_mon)
|
|||
free(output->MonInfo);
|
||||
|
||||
output->MonInfo = edid_mon;
|
||||
if (edid_mon) {
|
||||
output->mm_width = 0;
|
||||
output->mm_height = 0;
|
||||
}
|
||||
output->mm_width = 0;
|
||||
output->mm_height = 0;
|
||||
|
||||
if (debug_modes) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n",
|
||||
|
|
|
@ -839,6 +839,9 @@ xf86CompatOutput(ScrnInfoPtr pScrn)
|
|||
{
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
|
||||
if (xf86CrtcConfigPrivateIndex == -1)
|
||||
return NULL;
|
||||
|
||||
if (config->compat_output < 0)
|
||||
return NULL;
|
||||
return config->output[config->compat_output];
|
||||
|
|
|
@ -803,10 +803,14 @@ xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
|
|||
{
|
||||
struct libxcvt_mode_info *libxcvt_mode_info;
|
||||
DisplayModeRec *Mode = xnfcalloc(1, sizeof(DisplayModeRec));
|
||||
char *tmp;
|
||||
|
||||
libxcvt_mode_info =
|
||||
libxcvt_gen_mode_info(HDisplay, VDisplay, VRefresh, Reduced, Interlaced);
|
||||
|
||||
XNFasprintf(&tmp, "%dx%d", HDisplay, VDisplay);
|
||||
Mode->name = tmp;
|
||||
|
||||
Mode->VDisplay = libxcvt_mode_info->vdisplay;
|
||||
Mode->HDisplay = libxcvt_mode_info->hdisplay;
|
||||
Mode->Clock = libxcvt_mode_info->dot_clock;
|
||||
|
|
|
@ -806,12 +806,6 @@ xf86RandR12CreateScreenResources(ScreenPtr pScreen)
|
|||
mmWidth = output->conf_monitor->mon_width;
|
||||
mmHeight = output->conf_monitor->mon_height;
|
||||
}
|
||||
else if (output &&
|
||||
(output->mm_width > 0 &&
|
||||
output->mm_height > 0)) {
|
||||
mmWidth = output->mm_width;
|
||||
mmHeight = output->mm_height;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Otherwise, just set the screen to DEFAULT_DPI
|
||||
|
@ -1255,8 +1249,8 @@ xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette,
|
|||
{
|
||||
int gamma_slots;
|
||||
unsigned shift;
|
||||
CARD32 value;
|
||||
int i, j;
|
||||
CARD32 value = 0;
|
||||
|
||||
for (shift = 0; (gamma_size << shift) < (1 << 16); shift++);
|
||||
|
||||
|
@ -1273,6 +1267,10 @@ xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette,
|
|||
for (j = 0; j < gamma_slots; j++)
|
||||
crtc->gamma_red[i * gamma_slots + j] = value;
|
||||
}
|
||||
|
||||
/* Replicate last value until end of crtc for gamma_size not a power of 2 */
|
||||
for (j = i * gamma_slots; j < crtc->gamma_size; j++)
|
||||
crtc->gamma_red[j] = value;
|
||||
} else {
|
||||
/* Downsampling of larger palette to smaller hw lut size */
|
||||
for (i = 0; i < crtc->gamma_size; i++) {
|
||||
|
@ -1299,6 +1297,10 @@ xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette,
|
|||
for (j = 0; j < gamma_slots; j++)
|
||||
crtc->gamma_green[i * gamma_slots + j] = value;
|
||||
}
|
||||
|
||||
/* Replicate last value until end of crtc for gamma_size not a power of 2 */
|
||||
for (j = i * gamma_slots; j < crtc->gamma_size; j++)
|
||||
crtc->gamma_green[j] = value;
|
||||
} else {
|
||||
/* Downsampling of larger palette to smaller hw lut size */
|
||||
for (i = 0; i < crtc->gamma_size; i++) {
|
||||
|
@ -1325,6 +1327,10 @@ xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette,
|
|||
for (j = 0; j < gamma_slots; j++)
|
||||
crtc->gamma_blue[i * gamma_slots + j] = value;
|
||||
}
|
||||
|
||||
/* Replicate last value until end of crtc for gamma_size not a power of 2 */
|
||||
for (j = i * gamma_slots; j < crtc->gamma_size; j++)
|
||||
crtc->gamma_blue[j] = value;
|
||||
} else {
|
||||
/* Downsampling of larger palette to smaller hw lut size */
|
||||
for (i = 0; i < crtc->gamma_size; i++) {
|
||||
|
@ -1358,6 +1364,7 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
|
|||
{
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
||||
int max_size = crtc->gamma_size;
|
||||
|
||||
if (crtc->funcs->gamma_set == NULL)
|
||||
return FALSE;
|
||||
|
@ -1372,12 +1379,15 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
|
|||
randr_crtc->gammaBlue,
|
||||
randr_crtc->gammaSize);
|
||||
} else {
|
||||
if (max_size > randr_crtc->gammaSize)
|
||||
max_size = randr_crtc->gammaSize;
|
||||
|
||||
memcpy(crtc->gamma_red, randr_crtc->gammaRed,
|
||||
crtc->gamma_size * sizeof(crtc->gamma_red[0]));
|
||||
max_size * sizeof(crtc->gamma_red[0]));
|
||||
memcpy(crtc->gamma_green, randr_crtc->gammaGreen,
|
||||
crtc->gamma_size * sizeof(crtc->gamma_green[0]));
|
||||
max_size * sizeof(crtc->gamma_green[0]));
|
||||
memcpy(crtc->gamma_blue, randr_crtc->gammaBlue,
|
||||
crtc->gamma_size * sizeof(crtc->gamma_blue[0]));
|
||||
max_size * sizeof(crtc->gamma_blue[0]));
|
||||
}
|
||||
|
||||
xf86RandR12CrtcReloadGamma(crtc);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "xf86.h"
|
||||
#include "xf86platformBus.h"
|
||||
#include "xf86Xinput.h"
|
||||
#include "xf86Priv.h"
|
||||
#include "globals.h"
|
||||
|
||||
#include "systemd-logind.h"
|
||||
|
@ -302,6 +303,37 @@ cleanup:
|
|||
dbus_error_free(&error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a message to logind, to pause the drm device
|
||||
* and ensure the drm_drop_master is done before
|
||||
* VT_RELDISP when switching VT
|
||||
*/
|
||||
void systemd_logind_drop_master(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < xf86_num_platform_devices; i++) {
|
||||
if (xf86_platform_devices[i].flags & XF86_PDEV_SERVER_FD) {
|
||||
dbus_int32_t major, minor;
|
||||
struct systemd_logind_info *info = &logind_info;
|
||||
|
||||
xf86_platform_devices[i].flags |= XF86_PDEV_PAUSED;
|
||||
major = xf86_platform_odev_attributes(i)->major;
|
||||
minor = xf86_platform_odev_attributes(i)->minor;
|
||||
systemd_logind_ack_pause(info, minor, major);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Bool are_platform_devices_resumed(void) {
|
||||
int i;
|
||||
for (i = 0; i < xf86_num_platform_devices; i++) {
|
||||
if (xf86_platform_devices[i].flags & XF86_PDEV_PAUSED) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static DBusHandlerResult
|
||||
message_filter(DBusConnection * connection, DBusMessage * message, void *data)
|
||||
{
|
||||
|
@ -393,14 +425,14 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
|
|||
/* info->vt_active gets set by systemd_logind_vtenter() */
|
||||
info->active = TRUE;
|
||||
|
||||
if (pdev)
|
||||
if (pdev) {
|
||||
pdev->flags &= ~XF86_PDEV_PAUSED;
|
||||
else
|
||||
} else
|
||||
systemd_logind_set_input_fd_for_all_devs(major, minor, fd,
|
||||
info->vt_active);
|
||||
|
||||
/* Always call vtenter(), in case there are only legacy video devs */
|
||||
systemd_logind_vtenter();
|
||||
/* Call vtenter if all platform devices are resumed, or if there are no platform device */
|
||||
if (are_platform_devices_resumed())
|
||||
systemd_logind_vtenter();
|
||||
}
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
@ -583,7 +615,7 @@ static struct dbus_core_hook core_hook = {
|
|||
int
|
||||
systemd_logind_init(void)
|
||||
{
|
||||
if (!ServerIsNotSeat0() && linux_parse_vt_settings(TRUE) && !linux_get_keeptty()) {
|
||||
if (!ServerIsNotSeat0() && xf86HasTTYs() && linux_parse_vt_settings(TRUE) && !linux_get_keeptty()) {
|
||||
LogMessage(X_INFO,
|
||||
"systemd-logind: logind integration requires -keeptty and "
|
||||
"-keeptty was not provided, disabling logind integration\n");
|
||||
|
|
|
@ -19,7 +19,7 @@ if get_option('pciaccess')
|
|||
if host_machine.system() != 'linux'
|
||||
srcs_xorg_os_support += 'bus/bsd_pci.c'
|
||||
endif
|
||||
if host_machine.cpu() == 'sparc'
|
||||
if host_machine.cpu() == 'sparc' or host_machine.cpu() == 'sparc64'
|
||||
srcs_xorg_os_support += 'bus/Sbus.c'
|
||||
install_data('bus/xf86Sbus.h', install_dir: xorgsdkdir)
|
||||
endif
|
||||
|
|
|
@ -2,13 +2,14 @@ noinst_LTLIBRARIES = libXquartz.la
|
|||
AM_CFLAGS = $(DIX_CFLAGS)
|
||||
AM_OBJCFLAGS = $(DIX_CFLAGS)
|
||||
AM_CPPFLAGS = \
|
||||
-DXQUARTZ_DATA_DIR=\"$(datadir)/X11/XQuartz\" \
|
||||
-DXSERVER_VERSION=\"$(VERSION)\" \
|
||||
-DBUNDLE_ID_PREFIX=\"$(BUNDLE_ID_PREFIX)\" \
|
||||
-DUSE_NEW_CLUT \
|
||||
-DXFree86Server \
|
||||
-I$(top_srcdir)/miext/rootless \
|
||||
-I$(top_builddir)/pseudoramiX \
|
||||
-I$(top_builddir) \
|
||||
-DX11LIBDIR=\"$(libdir)\"
|
||||
-I$(top_builddir)
|
||||
|
||||
if GLX
|
||||
GL_DIR = GL
|
||||
|
@ -21,6 +22,7 @@ DIST_SUBDIRS = bundle . GL xpr pbproxy mach-startup man
|
|||
libXquartz_la_SOURCES = \
|
||||
$(top_srcdir)/mi/miinitext.c \
|
||||
$(top_srcdir)/mi/miinitext.h \
|
||||
NSUserDefaults+XQuartzDefaults.m \
|
||||
X11Application.m \
|
||||
X11Controller.m \
|
||||
applewm.c \
|
||||
|
@ -36,12 +38,14 @@ libXquartz_la_SOURCES = \
|
|||
libXquartz_la_LIBADD = $(top_builddir)/pseudoramiX/libPseudoramiX.la
|
||||
|
||||
EXTRA_DIST = \
|
||||
NSUserDefaults+XQuartzDefaults.h \
|
||||
X11Application.h \
|
||||
X11Controller.h \
|
||||
applewmExt.h \
|
||||
darwin.h \
|
||||
darwinfb.h \
|
||||
darwinEvents.h \
|
||||
defaults.plist \
|
||||
keysym2ucs.h \
|
||||
quartz.h \
|
||||
quartzKeyboard.h \
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// NSUserDefaults+XQuartzDefaults.h
|
||||
// XQuartz
|
||||
//
|
||||
// Created by Jeremy Huddleston Sequoia on 2021.02.19.
|
||||
// Copyright (c) 2021 Apple Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
extern NSString * const XQuartzPrefKeyAppsMenu;
|
||||
extern NSString * const XQuartzPrefKeyFakeButtons;
|
||||
extern NSString * const XQuartzPrefKeyFakeButton2;
|
||||
extern NSString * const XQuartzPrefKeyFakeButton3;
|
||||
extern NSString * const XQuartzPrefKeyKeyEquivs;
|
||||
extern NSString * const XQuartzPrefKeyFullscreenHotkeys;
|
||||
extern NSString * const XQuartzPrefKeyFullscreenMenu;
|
||||
extern NSString * const XQuartzPrefKeySyncKeymap;
|
||||
extern NSString * const XQuartzPrefKeyDepth;
|
||||
extern NSString * const XQuartzPrefKeyNoAuth;
|
||||
extern NSString * const XQuartzPrefKeyNoTCP;
|
||||
extern NSString * const XQuartzPrefKeyDoneXinitCheck;
|
||||
extern NSString * const XQuartzPrefKeyNoQuitAlert;
|
||||
extern NSString * const XQuartzPrefKeyNoRANDRAlert;
|
||||
extern NSString * const XQuartzPrefKeyOptionSendsAlt;
|
||||
extern NSString * const XQuartzPrefKeyAppKitModifiers;
|
||||
extern NSString * const XQuartzPrefKeyWindowItemModifiers;
|
||||
extern NSString * const XQuartzPrefKeyRootless;
|
||||
extern NSString * const XQuartzPrefKeyRENDERExtension;
|
||||
extern NSString * const XQuartzPrefKeyTESTExtension;
|
||||
extern NSString * const XQuartzPrefKeyLoginShell;
|
||||
extern NSString * const XQuartzPrefKeyClickThrough;
|
||||
extern NSString * const XQuartzPrefKeyFocusFollowsMouse;
|
||||
extern NSString * const XQuartzPrefKeyFocusOnNewWindow;
|
||||
|
||||
extern NSString * const XQuartzPrefKeyScrollInDeviceDirection;
|
||||
extern NSString * const XQuartzPrefKeySyncPasteboard;
|
||||
extern NSString * const XQuartzPrefKeySyncPasteboardToClipboard;
|
||||
extern NSString * const XQuartzPrefKeySyncPasteboardToPrimary;
|
||||
extern NSString * const XQuartzPrefKeySyncClipboardToPasteBoard;
|
||||
extern NSString * const XQuartzPrefKeySyncPrimaryOnSelect;
|
||||
|
||||
@interface NSUserDefaults (XQuartzDefaults)
|
||||
|
||||
+ (NSUserDefaults *)globalDefaults;
|
||||
+ (NSUserDefaults *)dockDefaults;
|
||||
+ (NSUserDefaults *)xquartzDefaults;
|
||||
|
||||
@end
|
|
@ -0,0 +1,148 @@
|
|||
//
|
||||
// NSUserDefaults+XQuartzDefaults.m
|
||||
// XQuartz
|
||||
//
|
||||
// Created by Jeremy Huddleston Sequoia on 2021.02.19.
|
||||
// Copyright (c) 2021 Apple Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSUserDefaults+XQuartzDefaults.h"
|
||||
#import <dispatch/dispatch.h>
|
||||
|
||||
NSString * const XQuartzPrefKeyAppsMenu = @"apps_menu";
|
||||
NSString * const XQuartzPrefKeyFakeButtons = @"enable_fake_buttons";
|
||||
NSString * const XQuartzPrefKeyFakeButton2 = @"fake_button2";
|
||||
NSString * const XQuartzPrefKeyFakeButton3 = @"fake_button3";
|
||||
NSString * const XQuartzPrefKeyKeyEquivs = @"enable_key_equivalents";
|
||||
NSString * const XQuartzPrefKeyFullscreenHotkeys = @"fullscreen_hotkeys";
|
||||
NSString * const XQuartzPrefKeyFullscreenMenu = @"fullscreen_menu";
|
||||
NSString * const XQuartzPrefKeySyncKeymap = @"sync_keymap";
|
||||
NSString * const XQuartzPrefKeyDepth = @"depth";
|
||||
NSString * const XQuartzPrefKeyNoAuth = @"no_auth";
|
||||
NSString * const XQuartzPrefKeyNoTCP = @"nolisten_tcp";
|
||||
NSString * const XQuartzPrefKeyDoneXinitCheck = @"done_xinit_check";
|
||||
NSString * const XQuartzPrefKeyNoQuitAlert = @"no_quit_alert";
|
||||
NSString * const XQuartzPrefKeyNoRANDRAlert = @"no_randr_alert";
|
||||
NSString * const XQuartzPrefKeyOptionSendsAlt = @"option_sends_alt";
|
||||
NSString * const XQuartzPrefKeyAppKitModifiers = @"appkit_modifiers";
|
||||
NSString * const XQuartzPrefKeyWindowItemModifiers = @"window_item_modifiers";
|
||||
NSString * const XQuartzPrefKeyRootless = @"rootless";
|
||||
NSString * const XQuartzPrefKeyRENDERExtension = @"enable_render_extension";
|
||||
NSString * const XQuartzPrefKeyTESTExtension = @"enable_test_extensions";
|
||||
NSString * const XQuartzPrefKeyLoginShell = @"login_shell";
|
||||
NSString * const XQuartzPrefKeyUpdateFeed = @"update_feed";
|
||||
NSString * const XQuartzPrefKeyClickThrough = @"wm_click_through";
|
||||
NSString * const XQuartzPrefKeyFocusFollowsMouse = @"wm_ffm";
|
||||
NSString * const XQuartzPrefKeyFocusOnNewWindow = @"wm_focus_on_new_window";
|
||||
|
||||
NSString * const XQuartzPrefKeyScrollInDeviceDirection = @"scroll_in_device_direction";
|
||||
NSString * const XQuartzPrefKeySyncPasteboard = @"sync_pasteboard";
|
||||
NSString * const XQuartzPrefKeySyncPasteboardToClipboard = @"sync_pasteboard_to_clipboard";
|
||||
NSString * const XQuartzPrefKeySyncPasteboardToPrimary = @"sync_pasteboard_to_primary";
|
||||
NSString * const XQuartzPrefKeySyncClipboardToPasteBoard = @"sync_clipboard_to_pasteboard";
|
||||
NSString * const XQuartzPrefKeySyncPrimaryOnSelect = @"sync_primary_on_select";
|
||||
|
||||
@implementation NSUserDefaults (XQuartzDefaults)
|
||||
|
||||
+ (NSUserDefaults *)globalDefaults
|
||||
{
|
||||
static dispatch_once_t once;
|
||||
static NSUserDefaults *defaults;
|
||||
|
||||
dispatch_once(&once, ^{
|
||||
NSString * const defaultsDomain = @".GlobalPreferences";
|
||||
defaults = [[[NSUserDefaults alloc] initWithSuiteName:defaultsDomain] retain];
|
||||
|
||||
NSDictionary<NSString *, id> * const defaultDefaultsDict = @{
|
||||
@"AppleSpacesSwitchOnActivate" : @(YES),
|
||||
};
|
||||
|
||||
[defaults registerDefaults:defaultDefaultsDict];
|
||||
});
|
||||
|
||||
return defaults;
|
||||
}
|
||||
|
||||
+ (NSUserDefaults *)dockDefaults
|
||||
{
|
||||
static dispatch_once_t once;
|
||||
static NSUserDefaults *defaults;
|
||||
|
||||
dispatch_once(&once, ^{
|
||||
NSString * const defaultsDomain = @"com.apple.dock";
|
||||
defaults = [[[NSUserDefaults alloc] initWithSuiteName:defaultsDomain] retain];
|
||||
|
||||
NSDictionary<NSString *, id> * const defaultDefaultsDict = @{
|
||||
@"workspaces" : @(NO),
|
||||
};
|
||||
|
||||
[defaults registerDefaults:defaultDefaultsDict];
|
||||
});
|
||||
|
||||
return defaults;
|
||||
}
|
||||
|
||||
+ (NSUserDefaults *)xquartzDefaults
|
||||
{
|
||||
static dispatch_once_t once;
|
||||
static NSUserDefaults *defaults;
|
||||
|
||||
dispatch_once(&once, ^{
|
||||
NSString * const defaultsDomain = @(BUNDLE_ID_PREFIX ".X11");
|
||||
NSString * const defaultDefaultsDomain = NSBundle.mainBundle.bundleIdentifier;
|
||||
if ([defaultsDomain isEqualToString:defaultDefaultsDomain]) {
|
||||
defaults = [NSUserDefaults.standardUserDefaults retain];
|
||||
} else {
|
||||
defaults = [[[NSUserDefaults alloc] initWithSuiteName:defaultsDomain] retain];
|
||||
}
|
||||
|
||||
NSString *defaultWindowItemModifiers = @"command";
|
||||
NSString * const defaultWindowItemModifiersLocalized = NSLocalizedString(@"window item modifiers", @"window item modifiers");
|
||||
if (![defaultWindowItemModifiersLocalized isEqualToString:@"window item modifiers"]) {
|
||||
defaultWindowItemModifiers = defaultWindowItemModifiersLocalized;
|
||||
}
|
||||
|
||||
NSDictionary<NSString *, id> * const defaultDefaultsDict = @{
|
||||
XQuartzPrefKeyFakeButtons : @(NO),
|
||||
// XQuartzPrefKeyFakeButton2 nil default
|
||||
// XQuartzPrefKeyFakeButton3 nil default
|
||||
XQuartzPrefKeyKeyEquivs : @(YES),
|
||||
XQuartzPrefKeyFullscreenHotkeys : @(NO),
|
||||
XQuartzPrefKeyFullscreenMenu : @(NO),
|
||||
XQuartzPrefKeySyncKeymap : @(NO),
|
||||
XQuartzPrefKeyDepth : @(-1),
|
||||
XQuartzPrefKeyNoAuth : @(NO),
|
||||
XQuartzPrefKeyNoTCP : @(NO),
|
||||
XQuartzPrefKeyDoneXinitCheck : @(NO),
|
||||
XQuartzPrefKeyNoQuitAlert : @(NO),
|
||||
XQuartzPrefKeyNoRANDRAlert : @(NO),
|
||||
XQuartzPrefKeyOptionSendsAlt : @(NO),
|
||||
// XQuartzPrefKeyAppKitModifiers nil default
|
||||
XQuartzPrefKeyWindowItemModifiers : defaultWindowItemModifiers,
|
||||
XQuartzPrefKeyRootless : @(YES),
|
||||
XQuartzPrefKeyRENDERExtension : @(YES),
|
||||
XQuartzPrefKeyTESTExtension : @(NO),
|
||||
XQuartzPrefKeyLoginShell : @"/bin/sh",
|
||||
XQuartzPrefKeyClickThrough : @(NO),
|
||||
XQuartzPrefKeyFocusFollowsMouse : @(NO),
|
||||
XQuartzPrefKeyFocusOnNewWindow : @(YES),
|
||||
|
||||
XQuartzPrefKeyScrollInDeviceDirection : @(NO),
|
||||
XQuartzPrefKeySyncPasteboard : @(YES),
|
||||
XQuartzPrefKeySyncPasteboardToClipboard : @(YES),
|
||||
XQuartzPrefKeySyncPasteboardToPrimary : @(YES),
|
||||
XQuartzPrefKeySyncClipboardToPasteBoard : @(YES),
|
||||
XQuartzPrefKeySyncPrimaryOnSelect : @(NO),
|
||||
};
|
||||
|
||||
[defaults registerDefaults:defaultDefaultsDict];
|
||||
|
||||
NSString * const systemDefaultsPlistPath = [@(XQUARTZ_DATA_DIR) stringByAppendingPathComponent:@"defaults.plist"];
|
||||
NSDictionary <NSString *, id> * const systemDefaultsDict = [NSDictionary dictionaryWithContentsOfFile:systemDefaultsPlistPath];
|
||||
[defaults registerDefaults:systemDefaultsDict];
|
||||
});
|
||||
|
||||
return defaults;
|
||||
}
|
||||
|
||||
@end
|
|
@ -42,20 +42,6 @@
|
|||
@property (nonatomic, readwrite, strong) X11Controller *controller;
|
||||
@property (nonatomic, readonly, assign) OSX_BOOL x_active;
|
||||
|
||||
- (CFPropertyListRef)prefs_get_copy:(NSString *)key CF_RETURNS_RETAINED;
|
||||
- (int)prefs_get_integer:(NSString *)key default:(int)def;
|
||||
- (const char *)prefs_get_string:(NSString *)key default:(const char *)def;
|
||||
- (float)prefs_get_float:(NSString *)key default:(float)def;
|
||||
- (int)prefs_get_boolean:(NSString *)key default:(int)def;
|
||||
- (NSURL *)prefs_copy_url:(NSString *)key default:(NSURL *)def
|
||||
NS_RETURNS_RETAINED;
|
||||
- (NSArray *)prefs_get_array:(NSString *)key;
|
||||
- (void)prefs_set_integer:(NSString *)key value:(int)value;
|
||||
- (void)prefs_set_float:(NSString *)key value:(float)value;
|
||||
- (void)prefs_set_boolean:(NSString *)key value:(int)value;
|
||||
- (void)prefs_set_array:(NSString *)key value:(NSArray *)value;
|
||||
- (void)prefs_set_string:(NSString *)key value:(NSString *)value;
|
||||
- (void)prefs_synchronize;
|
||||
@end
|
||||
|
||||
extern X11Application * X11App;
|
||||
|
@ -84,40 +70,6 @@ X11ApplicationCanEnterRandR(void);
|
|||
void
|
||||
X11ApplicationMain(int argc, char **argv, char **envp);
|
||||
|
||||
#define PREFS_APPSMENU "apps_menu"
|
||||
#define PREFS_FAKEBUTTONS "enable_fake_buttons"
|
||||
#define PREFS_KEYEQUIVS "enable_key_equivalents"
|
||||
#define PREFS_FULLSCREEN_HOTKEYS "fullscreen_hotkeys"
|
||||
#define PREFS_FULLSCREEN_MENU "fullscreen_menu"
|
||||
#define PREFS_SYNC_KEYMAP "sync_keymap"
|
||||
#define PREFS_DEPTH "depth"
|
||||
#define PREFS_NO_AUTH "no_auth"
|
||||
#define PREFS_NO_TCP "nolisten_tcp"
|
||||
#define PREFS_DONE_XINIT_CHECK "done_xinit_check"
|
||||
#define PREFS_NO_QUIT_ALERT "no_quit_alert"
|
||||
#define PREFS_NO_RANDR_ALERT "no_randr_alert"
|
||||
#define PREFS_OPTION_SENDS_ALT "option_sends_alt"
|
||||
#define PREFS_FAKE_BUTTON2 "fake_button2"
|
||||
#define PREFS_FAKE_BUTTON3 "fake_button3"
|
||||
#define PREFS_APPKIT_MODIFIERS "appkit_modifiers"
|
||||
#define PREFS_WINDOW_ITEM_MODIFIERS "window_item_modifiers"
|
||||
#define PREFS_ROOTLESS "rootless"
|
||||
#define PREFS_RENDER_EXTENSION "enable_render_extension"
|
||||
#define PREFS_TEST_EXTENSIONS "enable_test_extensions"
|
||||
#define PREFS_XP_OPTIONS "xp_options"
|
||||
#define PREFS_LOGIN_SHELL "login_shell"
|
||||
#define PREFS_UPDATE_FEED "update_feed"
|
||||
#define PREFS_CLICK_THROUGH "wm_click_through"
|
||||
#define PREFS_FFM "wm_ffm"
|
||||
#define PREFS_FOCUS_ON_NEW_WINDOW "wm_focus_on_new_window"
|
||||
|
||||
#define PREFS_SCROLL_IN_DEV_DIRECTION "scroll_in_device_direction"
|
||||
extern Bool XQuartzScrollInDeviceDirection;
|
||||
|
||||
#define PREFS_SYNC_PB "sync_pasteboard"
|
||||
#define PREFS_SYNC_PB_TO_CLIPBOARD "sync_pasteboard_to_clipboard"
|
||||
#define PREFS_SYNC_PB_TO_PRIMARY "sync_pasteboard_to_primary"
|
||||
#define PREFS_SYNC_CLIPBOARD_TO_PB "sync_clipboard_to_pasteboard"
|
||||
#define PREFS_SYNC_PRIMARY_ON_SELECT "sync_primary_on_select"
|
||||
|
||||
#endif /* X11APPLICATION_H */
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#endif
|
||||
|
||||
#import "X11Application.h"
|
||||
#import "NSUserDefaults+XQuartzDefaults.h"
|
||||
|
||||
#include "darwin.h"
|
||||
#include "quartz.h"
|
||||
|
@ -55,8 +56,6 @@
|
|||
extern int
|
||||
xpbproxy_run(void);
|
||||
|
||||
#define DEFAULTS_FILE X11LIBDIR "/X11/xserver/Xquartz.plist"
|
||||
|
||||
#ifndef XSERVER_VERSION
|
||||
#define XSERVER_VERSION "?"
|
||||
#endif
|
||||
|
@ -101,8 +100,6 @@ static BOOL bgMouseLocationUpdated = FALSE;
|
|||
|
||||
X11Application *X11App;
|
||||
|
||||
CFStringRef app_prefs_domain_cfstr = NULL;
|
||||
|
||||
#define ALL_KEY_MASKS (NSShiftKeyMask | NSControlKeyMask | \
|
||||
NSAlternateKeyMask | NSCommandKeyMask)
|
||||
|
||||
|
@ -270,6 +267,8 @@ QuartzModeBundleInit(void);
|
|||
case NSLeftMouseUp:
|
||||
case NSRightMouseUp:
|
||||
case NSOtherMouseUp:
|
||||
case NSScrollWheel:
|
||||
|
||||
if ([e window] != nil) {
|
||||
/* Pointer event has an (AppKit) window. Probably something for the kit. */
|
||||
for_x = NO;
|
||||
|
@ -420,7 +419,7 @@ QuartzModeBundleInit(void);
|
|||
case NSApplicationActivatedEventType:
|
||||
for_x = NO;
|
||||
if ([e window] == nil && x_was_active) {
|
||||
BOOL order_all_windows = YES, workspaces, ok;
|
||||
BOOL order_all_windows = YES;
|
||||
for_appkit = NO;
|
||||
|
||||
#if APPKIT_APPFLAGS_HACK
|
||||
|
@ -433,26 +432,9 @@ QuartzModeBundleInit(void);
|
|||
[self set_front_process:nil];
|
||||
|
||||
/* Get the Spaces preference for SwitchOnActivate */
|
||||
(void)CFPreferencesAppSynchronize(CFSTR("com.apple.dock"));
|
||||
workspaces =
|
||||
CFPreferencesGetAppBooleanValue(CFSTR("workspaces"),
|
||||
CFSTR(
|
||||
"com.apple.dock"),
|
||||
&ok);
|
||||
if (!ok)
|
||||
workspaces = NO;
|
||||
|
||||
BOOL const workspaces = [NSUserDefaults.dockDefaults boolForKey:@"workspaces"];
|
||||
if (workspaces) {
|
||||
(void)CFPreferencesAppSynchronize(CFSTR(
|
||||
".GlobalPreferences"));
|
||||
order_all_windows =
|
||||
CFPreferencesGetAppBooleanValue(CFSTR(
|
||||
"AppleSpacesSwitchOnActivate"),
|
||||
CFSTR(
|
||||
".GlobalPreferences"),
|
||||
&ok);
|
||||
if (!ok)
|
||||
order_all_windows = YES;
|
||||
order_all_windows = [NSUserDefaults.globalDefaults boolForKey:@"AppleSpacesSwitchOnActivate"];
|
||||
}
|
||||
|
||||
/* TODO: In the workspaces && !AppleSpacesSwitchOnActivate case, the windows are ordered
|
||||
|
@ -463,8 +445,7 @@ QuartzModeBundleInit(void);
|
|||
* be restoring one of them.
|
||||
*/
|
||||
if ([e data2] & 0x10) { // 0x10 (bfCPSOrderAllWindowsForward) is set when we use cmd-tab or the dock icon
|
||||
DarwinSendDDXEvent(kXquartzBringAllToFront, 1,
|
||||
order_all_windows);
|
||||
DarwinSendDDXEvent(kXquartzBringAllToFront, 1, order_all_windows);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -487,12 +468,14 @@ QuartzModeBundleInit(void);
|
|||
break; /* for gcc */
|
||||
}
|
||||
|
||||
if (for_appkit) [super sendEvent:e];
|
||||
if (for_appkit) {
|
||||
[super sendEvent:e];
|
||||
}
|
||||
|
||||
if (for_x) {
|
||||
dispatch_async(eventTranslationQueue, ^{
|
||||
[self sendX11NSEvent:e];
|
||||
});
|
||||
[self sendX11NSEvent:e];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -524,404 +507,50 @@ QuartzModeBundleInit(void);
|
|||
(void)[self.controller application:self openFile:cmd];
|
||||
}
|
||||
|
||||
/* user preferences */
|
||||
|
||||
/* Note that these functions only work for arrays whose elements
|
||||
can be toll-free-bridged between NS and CF worlds. */
|
||||
|
||||
static const void *
|
||||
cfretain(CFAllocatorRef a, const void *b)
|
||||
{
|
||||
return CFRetain(b);
|
||||
}
|
||||
|
||||
static void
|
||||
cfrelease(CFAllocatorRef a, const void *b)
|
||||
{
|
||||
CFRelease(b);
|
||||
}
|
||||
|
||||
CF_RETURNS_RETAINED
|
||||
static CFMutableArrayRef
|
||||
nsarray_to_cfarray(NSArray *in)
|
||||
{
|
||||
CFMutableArrayRef out;
|
||||
CFArrayCallBacks cb;
|
||||
NSObject *ns;
|
||||
const CFTypeRef *cf;
|
||||
int i, count;
|
||||
|
||||
memset(&cb, 0, sizeof(cb));
|
||||
cb.version = 0;
|
||||
cb.retain = cfretain;
|
||||
cb.release = cfrelease;
|
||||
|
||||
count = [in count];
|
||||
out = CFArrayCreateMutable(NULL, count, &cb);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
ns = [in objectAtIndex:i];
|
||||
|
||||
if ([ns isKindOfClass:[NSArray class]])
|
||||
cf = (CFTypeRef)nsarray_to_cfarray((NSArray *)ns);
|
||||
else
|
||||
cf = CFRetain((CFTypeRef)ns);
|
||||
|
||||
CFArrayAppendValue(out, cf);
|
||||
CFRelease(cf);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static NSMutableArray *
|
||||
cfarray_to_nsarray(CFArrayRef in)
|
||||
{
|
||||
NSMutableArray *out;
|
||||
const CFTypeRef *cf;
|
||||
NSObject *ns;
|
||||
int i, count;
|
||||
|
||||
count = CFArrayGetCount(in);
|
||||
out = [[NSMutableArray alloc] initWithCapacity:count];
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
cf = CFArrayGetValueAtIndex(in, i);
|
||||
|
||||
if (CFGetTypeID(cf) == CFArrayGetTypeID())
|
||||
ns = cfarray_to_nsarray((CFArrayRef)cf);
|
||||
else
|
||||
ns = [(id) cf retain];
|
||||
|
||||
[out addObject:ns];
|
||||
[ns release];
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
- (CFPropertyListRef) prefs_get_copy:(NSString *)key
|
||||
{
|
||||
CFPropertyListRef value;
|
||||
|
||||
value = CFPreferencesCopyAppValue((CFStringRef)key,
|
||||
app_prefs_domain_cfstr);
|
||||
|
||||
if (value == NULL) {
|
||||
static CFDictionaryRef defaults;
|
||||
|
||||
if (defaults == NULL) {
|
||||
CFStringRef error = NULL;
|
||||
CFDataRef data;
|
||||
CFURLRef url;
|
||||
SInt32 error_code;
|
||||
|
||||
url = (CFURLCreateFromFileSystemRepresentation
|
||||
(NULL, (unsigned char *)DEFAULTS_FILE,
|
||||
strlen(DEFAULTS_FILE), false));
|
||||
if (CFURLCreateDataAndPropertiesFromResource(NULL, url, &data,
|
||||
NULL, NULL,
|
||||
&error_code)) {
|
||||
defaults = (CFPropertyListCreateFromXMLData
|
||||
(NULL, data,
|
||||
kCFPropertyListMutableContainersAndLeaves,
|
||||
&error));
|
||||
if (error != NULL) CFRelease(error);
|
||||
CFRelease(data);
|
||||
}
|
||||
CFRelease(url);
|
||||
|
||||
if (defaults != NULL) {
|
||||
NSMutableArray *apps, *elt;
|
||||
int count, i;
|
||||
NSString *name, *nname;
|
||||
|
||||
/* Localize the names in the default apps menu. */
|
||||
|
||||
apps =
|
||||
[(NSDictionary *) defaults objectForKey:@PREFS_APPSMENU];
|
||||
if (apps != nil) {
|
||||
count = [apps count];
|
||||
for (i = 0; i < count; i++) {
|
||||
elt = [apps objectAtIndex:i];
|
||||
if (elt != nil &&
|
||||
[elt isKindOfClass:[NSArray class]]) {
|
||||
name = [elt objectAtIndex:0];
|
||||
if (name != nil) {
|
||||
nname = NSLocalizedString(name, nil);
|
||||
if (nname != nil && nname != name)
|
||||
[elt replaceObjectAtIndex:0 withObject:
|
||||
nname];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defaults != NULL) value = CFDictionaryGetValue(defaults, key);
|
||||
if (value != NULL) CFRetain(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
- (int) prefs_get_integer:(NSString *)key default:(int)def
|
||||
{
|
||||
CFPropertyListRef value;
|
||||
int ret;
|
||||
|
||||
value = [self prefs_get_copy:key];
|
||||
|
||||
if (value != NULL && CFGetTypeID(value) == CFNumberGetTypeID())
|
||||
CFNumberGetValue(value, kCFNumberIntType, &ret);
|
||||
else if (value != NULL && CFGetTypeID(value) == CFStringGetTypeID())
|
||||
ret = CFStringGetIntValue(value);
|
||||
else
|
||||
ret = def;
|
||||
|
||||
if (value != NULL) CFRelease(value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (const char *) prefs_get_string:(NSString *)key default:(const char *)def
|
||||
{
|
||||
CFPropertyListRef value;
|
||||
const char *ret = NULL;
|
||||
|
||||
value = [self prefs_get_copy:key];
|
||||
|
||||
if (value != NULL && CFGetTypeID(value) == CFStringGetTypeID()) {
|
||||
NSString *s = (NSString *)value;
|
||||
|
||||
ret = [s UTF8String];
|
||||
}
|
||||
|
||||
if (value != NULL) CFRelease(value);
|
||||
|
||||
return ret != NULL ? ret : def;
|
||||
}
|
||||
|
||||
- (NSURL *) prefs_copy_url:(NSString *)key default:(NSURL *)def
|
||||
{
|
||||
CFPropertyListRef value;
|
||||
NSURL *ret = NULL;
|
||||
|
||||
value = [self prefs_get_copy:key];
|
||||
|
||||
if (value != NULL && CFGetTypeID(value) == CFStringGetTypeID()) {
|
||||
NSString *s = (NSString *)value;
|
||||
|
||||
ret = [NSURL URLWithString:s];
|
||||
[ret retain];
|
||||
}
|
||||
|
||||
if (value != NULL) CFRelease(value);
|
||||
|
||||
return ret != NULL ? ret : def;
|
||||
}
|
||||
|
||||
- (float) prefs_get_float:(NSString *)key default:(float)def
|
||||
{
|
||||
CFPropertyListRef value;
|
||||
float ret = def;
|
||||
|
||||
value = [self prefs_get_copy:key];
|
||||
|
||||
if (value != NULL
|
||||
&& CFGetTypeID(value) == CFNumberGetTypeID()
|
||||
&& CFNumberIsFloatType(value))
|
||||
CFNumberGetValue(value, kCFNumberFloatType, &ret);
|
||||
else if (value != NULL && CFGetTypeID(value) == CFStringGetTypeID())
|
||||
ret = CFStringGetDoubleValue(value);
|
||||
|
||||
if (value != NULL) CFRelease(value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (int) prefs_get_boolean:(NSString *)key default:(int)def
|
||||
{
|
||||
CFPropertyListRef value;
|
||||
int ret = def;
|
||||
|
||||
value = [self prefs_get_copy:key];
|
||||
|
||||
if (value != NULL) {
|
||||
if (CFGetTypeID(value) == CFNumberGetTypeID())
|
||||
CFNumberGetValue(value, kCFNumberIntType, &ret);
|
||||
else if (CFGetTypeID(value) == CFBooleanGetTypeID())
|
||||
ret = CFBooleanGetValue(value);
|
||||
else if (CFGetTypeID(value) == CFStringGetTypeID()) {
|
||||
const char *tem = [(NSString *) value UTF8String];
|
||||
if (strcasecmp(tem, "true") == 0 || strcasecmp(tem, "yes") == 0)
|
||||
ret = YES;
|
||||
else
|
||||
ret = NO;
|
||||
}
|
||||
|
||||
CFRelease(value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (NSArray *) prefs_get_array:(NSString *)key
|
||||
{
|
||||
NSArray *ret = nil;
|
||||
CFPropertyListRef value;
|
||||
|
||||
value = [self prefs_get_copy:key];
|
||||
|
||||
if (value != NULL) {
|
||||
if (CFGetTypeID(value) == CFArrayGetTypeID())
|
||||
ret = [cfarray_to_nsarray (value)autorelease];
|
||||
|
||||
CFRelease(value);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (void) prefs_set_integer:(NSString *)key value:(int)value
|
||||
{
|
||||
CFNumberRef x;
|
||||
|
||||
x = CFNumberCreate(NULL, kCFNumberIntType, &value);
|
||||
|
||||
CFPreferencesSetValue((CFStringRef)key, (CFTypeRef)x,
|
||||
app_prefs_domain_cfstr,
|
||||
kCFPreferencesCurrentUser,
|
||||
kCFPreferencesAnyHost);
|
||||
|
||||
CFRelease(x);
|
||||
}
|
||||
|
||||
- (void) prefs_set_float:(NSString *)key value:(float)value
|
||||
{
|
||||
CFNumberRef x;
|
||||
|
||||
x = CFNumberCreate(NULL, kCFNumberFloatType, &value);
|
||||
|
||||
CFPreferencesSetValue((CFStringRef)key, (CFTypeRef)x,
|
||||
app_prefs_domain_cfstr,
|
||||
kCFPreferencesCurrentUser,
|
||||
kCFPreferencesAnyHost);
|
||||
|
||||
CFRelease(x);
|
||||
}
|
||||
|
||||
- (void) prefs_set_boolean:(NSString *)key value:(int)value
|
||||
{
|
||||
CFPreferencesSetValue(
|
||||
(CFStringRef)key,
|
||||
(CFTypeRef)(value ? kCFBooleanTrue
|
||||
: kCFBooleanFalse),
|
||||
app_prefs_domain_cfstr,
|
||||
kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
|
||||
|
||||
}
|
||||
|
||||
- (void) prefs_set_array:(NSString *)key value:(NSArray *)value
|
||||
{
|
||||
CFArrayRef cfarray;
|
||||
|
||||
cfarray = nsarray_to_cfarray(value);
|
||||
CFPreferencesSetValue((CFStringRef)key,
|
||||
(CFTypeRef)cfarray,
|
||||
app_prefs_domain_cfstr,
|
||||
kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
|
||||
CFRelease(cfarray);
|
||||
}
|
||||
|
||||
- (void) prefs_set_string:(NSString *)key value:(NSString *)value
|
||||
{
|
||||
CFPreferencesSetValue((CFStringRef)key, (CFTypeRef)value,
|
||||
app_prefs_domain_cfstr, kCFPreferencesCurrentUser,
|
||||
kCFPreferencesAnyHost);
|
||||
}
|
||||
|
||||
- (void) prefs_synchronize
|
||||
{
|
||||
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
|
||||
}
|
||||
|
||||
- (void) read_defaults
|
||||
{
|
||||
NSString *nsstr;
|
||||
const char *tem;
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
|
||||
XQuartzRootlessDefault = [self prefs_get_boolean:@PREFS_ROOTLESS
|
||||
default :XQuartzRootlessDefault];
|
||||
XQuartzFullscreenMenu = [self prefs_get_boolean:@PREFS_FULLSCREEN_MENU
|
||||
default :XQuartzFullscreenMenu];
|
||||
XQuartzFullscreenDisableHotkeys =
|
||||
![self prefs_get_boolean:@PREFS_FULLSCREEN_HOTKEYS
|
||||
default :!
|
||||
XQuartzFullscreenDisableHotkeys];
|
||||
darwinFakeButtons = [self prefs_get_boolean:@PREFS_FAKEBUTTONS
|
||||
default :darwinFakeButtons];
|
||||
XQuartzOptionSendsAlt = [self prefs_get_boolean:@PREFS_OPTION_SENDS_ALT
|
||||
default :XQuartzOptionSendsAlt];
|
||||
XQuartzRootlessDefault = [defaults boolForKey:XQuartzPrefKeyRootless];
|
||||
XQuartzFullscreenMenu = [defaults boolForKey:XQuartzPrefKeyFullscreenMenu];
|
||||
XQuartzFullscreenDisableHotkeys = ![defaults boolForKey:XQuartzPrefKeyFullscreenHotkeys];
|
||||
|
||||
darwinFakeButtons = [defaults boolForKey:XQuartzPrefKeyFakeButtons];
|
||||
XQuartzOptionSendsAlt = [defaults boolForKey:XQuartzPrefKeyOptionSendsAlt];
|
||||
|
||||
if (darwinFakeButtons) {
|
||||
const char *fake2, *fake3;
|
||||
NSString * const fake2 = [defaults stringForKey:XQuartzPrefKeyFakeButton2];
|
||||
if (fake2) {
|
||||
darwinFakeMouse2Mask = DarwinParseModifierList(fake2.UTF8String, TRUE);
|
||||
}
|
||||
|
||||
fake2 = [self prefs_get_string:@PREFS_FAKE_BUTTON2 default:NULL];
|
||||
fake3 = [self prefs_get_string:@PREFS_FAKE_BUTTON3 default:NULL];
|
||||
|
||||
if (fake2 != NULL) darwinFakeMouse2Mask = DarwinParseModifierList(
|
||||
fake2, TRUE);
|
||||
if (fake3 != NULL) darwinFakeMouse3Mask = DarwinParseModifierList(
|
||||
fake3, TRUE);
|
||||
}
|
||||
|
||||
tem = [self prefs_get_string:@PREFS_APPKIT_MODIFIERS default:NULL];
|
||||
if (tem != NULL) darwinAppKitModMask = DarwinParseModifierList(tem, TRUE);
|
||||
|
||||
tem = [self prefs_get_string:@PREFS_WINDOW_ITEM_MODIFIERS default:NULL];
|
||||
if (tem != NULL) {
|
||||
windowItemModMask = DarwinParseModifierList(tem, FALSE);
|
||||
}
|
||||
else {
|
||||
nsstr = NSLocalizedString(@"window item modifiers",
|
||||
@"window item modifiers");
|
||||
if (nsstr != NULL) {
|
||||
tem = [nsstr UTF8String];
|
||||
if ((tem != NULL) && strcmp(tem, "window item modifiers")) {
|
||||
windowItemModMask = DarwinParseModifierList(tem, FALSE);
|
||||
}
|
||||
NSString * const fake3 = [defaults stringForKey:XQuartzPrefKeyFakeButton3];
|
||||
if (fake3) {
|
||||
darwinFakeMouse3Mask = DarwinParseModifierList(fake3.UTF8String, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
XQuartzEnableKeyEquivalents = [self prefs_get_boolean:@PREFS_KEYEQUIVS
|
||||
default :
|
||||
XQuartzEnableKeyEquivalents];
|
||||
|
||||
darwinSyncKeymap = [self prefs_get_boolean:@PREFS_SYNC_KEYMAP
|
||||
default :darwinSyncKeymap];
|
||||
|
||||
darwinDesiredDepth = [self prefs_get_integer:@PREFS_DEPTH
|
||||
default :darwinDesiredDepth];
|
||||
|
||||
noTestExtensions = ![self prefs_get_boolean:@PREFS_TEST_EXTENSIONS
|
||||
default :FALSE];
|
||||
|
||||
noRenderExtension = ![self prefs_get_boolean:@PREFS_RENDER_EXTENSION
|
||||
default :TRUE];
|
||||
|
||||
XQuartzScrollInDeviceDirection =
|
||||
[self prefs_get_boolean:@PREFS_SCROLL_IN_DEV_DIRECTION
|
||||
default :
|
||||
XQuartzScrollInDeviceDirection];
|
||||
|
||||
#if XQUARTZ_SPARKLE
|
||||
NSURL *url = [self prefs_copy_url:@PREFS_UPDATE_FEED default:nil];
|
||||
if (url) {
|
||||
[[SUUpdater sharedUpdater] setFeedURL:url];
|
||||
[url release];
|
||||
NSString * const appKitModifiers = [defaults stringForKey:XQuartzPrefKeyAppKitModifiers];
|
||||
if (appKitModifiers) {
|
||||
darwinAppKitModMask = DarwinParseModifierList(appKitModifiers.UTF8String, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
NSString * const windowItemModifiers = [defaults stringForKey:XQuartzPrefKeyWindowItemModifiers];
|
||||
if (windowItemModifiers) {
|
||||
windowItemModMask = DarwinParseModifierList(windowItemModifiers.UTF8String, FALSE);
|
||||
}
|
||||
|
||||
XQuartzEnableKeyEquivalents = [defaults boolForKey:XQuartzPrefKeyKeyEquivs];
|
||||
|
||||
darwinSyncKeymap = [defaults boolForKey:XQuartzPrefKeySyncKeymap];
|
||||
|
||||
darwinDesiredDepth = [defaults integerForKey:XQuartzPrefKeyDepth];
|
||||
|
||||
noTestExtensions = ![defaults boolForKey:XQuartzPrefKeyTESTExtension];
|
||||
noRenderExtension = ![defaults boolForKey:XQuartzPrefKeyRENDERExtension];
|
||||
|
||||
XQuartzScrollInDeviceDirection = [defaults boolForKey:XQuartzPrefKeyScrollInDeviceDirection];
|
||||
}
|
||||
|
||||
/* This will end up at the end of the responder chain. */
|
||||
|
@ -1018,8 +647,9 @@ Bool
|
|||
X11ApplicationCanEnterRandR(void)
|
||||
{
|
||||
NSString *title, *msg;
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
|
||||
if ([X11App prefs_get_boolean:@PREFS_NO_RANDR_ALERT default:NO] ||
|
||||
if ([defaults boolForKey:XQuartzPrefKeyNoRANDRAlert] ||
|
||||
XQuartzShieldingWindowLevel != 0)
|
||||
return TRUE;
|
||||
|
||||
|
@ -1042,8 +672,7 @@ X11ApplicationCanEnterRandR(void)
|
|||
|
||||
switch (alert_result) {
|
||||
case NSAlertOtherReturn:
|
||||
[X11App prefs_set_boolean:@PREFS_NO_RANDR_ALERT value:YES];
|
||||
[X11App prefs_synchronize];
|
||||
[defaults setBool:YES forKey:XQuartzPrefKeyNoRANDRAlert];
|
||||
|
||||
case NSAlertDefaultReturn:
|
||||
return YES;
|
||||
|
@ -1058,8 +687,9 @@ check_xinitrc(void)
|
|||
{
|
||||
char *tem, buf[1024];
|
||||
NSString *msg;
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
|
||||
if ([X11App prefs_get_boolean:@PREFS_DONE_XINIT_CHECK default:NO])
|
||||
if ([defaults boolForKey:XQuartzPrefKeyDoneXinitCheck])
|
||||
return;
|
||||
|
||||
tem = getenv("HOME");
|
||||
|
@ -1093,8 +723,7 @@ check_xinitrc(void)
|
|||
}
|
||||
|
||||
done:
|
||||
[X11App prefs_set_boolean:@PREFS_DONE_XINIT_CHECK value:YES];
|
||||
[X11App prefs_synchronize];
|
||||
[defaults setBool:YES forKey:XQuartzPrefKeyDoneXinitCheck];
|
||||
}
|
||||
|
||||
static inline pthread_t
|
||||
|
@ -1130,15 +759,8 @@ X11ApplicationMain(int argc, char **argv, char **envp)
|
|||
|
||||
@autoreleasepool {
|
||||
X11App = (X11Application *)[X11Application sharedApplication];
|
||||
[X11App read_defaults];
|
||||
|
||||
app_prefs_domain_cfstr = (CFStringRef)[[NSBundle mainBundle] bundleIdentifier];
|
||||
|
||||
if (app_prefs_domain_cfstr == NULL) {
|
||||
ErrorF("X11ApplicationMain: Unable to determine bundle identifier. Your installation of XQuartz may be broken.\n");
|
||||
app_prefs_domain_cfstr = CFSTR(BUNDLE_ID_PREFIX ".X11");
|
||||
}
|
||||
|
||||
[NSApp read_defaults];
|
||||
[NSBundle loadNibNamed:@"main" owner:NSApp];
|
||||
[NSNotificationCenter.defaultCenter addObserver:NSApp
|
||||
selector:@selector (became_key:)
|
||||
|
@ -1701,8 +1323,17 @@ handle_mouse:
|
|||
}
|
||||
|
||||
if (darwinSyncKeymap) {
|
||||
TISInputSourceRef key_layout =
|
||||
TISCopyCurrentKeyboardLayoutInputSource();
|
||||
__block TISInputSourceRef key_layout;
|
||||
dispatch_block_t copyCurrentKeyboardLayoutInputSource = ^{
|
||||
key_layout = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
};
|
||||
/* This is an ugly ant-pattern, but it is more expedient to address the problem right now. */
|
||||
if (pthread_main_np()) {
|
||||
copyCurrentKeyboardLayoutInputSource();
|
||||
} else {
|
||||
dispatch_sync(dispatch_get_main_queue(), copyCurrentKeyboardLayoutInputSource);
|
||||
}
|
||||
|
||||
TISInputSourceRef clear;
|
||||
if (CFEqual(key_layout, last_key_layout)) {
|
||||
CFRelease(key_layout);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#import "X11Controller.h"
|
||||
#import "X11Application.h"
|
||||
#import "NSUserDefaults+XQuartzDefaults.h"
|
||||
|
||||
#include "opaque.h"
|
||||
#include "darwin.h"
|
||||
|
@ -61,8 +62,8 @@ extern char *bundle_id_prefix;
|
|||
@property (nonatomic, readwrite, strong) NSMenuItem *check_for_updates_item; // Programatically enabled
|
||||
#endif
|
||||
|
||||
@property (nonatomic, readwrite, strong) NSArray *apps;
|
||||
@property (nonatomic, readwrite, strong) NSMutableArray *table_apps;
|
||||
@property (nonatomic, readwrite, strong) NSArray <NSArray <NSString *> *> *apps;
|
||||
@property (nonatomic, readwrite, strong) NSMutableArray <NSMutableArray <NSString *> *> *table_apps;
|
||||
@property (nonatomic, readwrite, assign) NSInteger windows_menu_nitems;
|
||||
@property (nonatomic, readwrite, assign) int checked_window_item;
|
||||
@property (nonatomic, readwrite, assign) x_list *pending_apps;
|
||||
|
@ -74,21 +75,19 @@ extern char *bundle_id_prefix;
|
|||
- (void) awakeFromNib
|
||||
{
|
||||
X11Application *xapp = NSApp;
|
||||
NSArray *array;
|
||||
|
||||
/* Point X11Application at ourself. */
|
||||
xapp.controller = self;
|
||||
|
||||
array = [xapp prefs_get_array:@PREFS_APPSMENU];
|
||||
if (array != nil) {
|
||||
int count;
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
NSArray *appsMenu = [defaults arrayForKey:XQuartzPrefKeyAppsMenu];
|
||||
|
||||
if (appsMenu) {
|
||||
int count = appsMenu.count;
|
||||
|
||||
/* convert from [TITLE1 COMMAND1 TITLE2 COMMAND2 ...]
|
||||
to [[TITLE1 COMMAND1] [TITLE2 COMMAND2] ...] format. */
|
||||
|
||||
count = [array count];
|
||||
if (count > 0
|
||||
&& ![[array objectAtIndex:0] isKindOfClass:[NSArray class]]) {
|
||||
if (count > 0 && ![appsMenu[0] isKindOfClass:NSArray.class]) {
|
||||
int i;
|
||||
NSMutableArray *copy, *sub;
|
||||
|
||||
|
@ -96,24 +95,24 @@ extern char *bundle_id_prefix;
|
|||
|
||||
for (i = 0; i < count / 2; i++) {
|
||||
sub = [[NSMutableArray alloc] initWithCapacity:3];
|
||||
[sub addObject:[array objectAtIndex:i * 2]];
|
||||
[sub addObject:[array objectAtIndex:i * 2 + 1]];
|
||||
[sub addObject:appsMenu[i * 2]];
|
||||
[sub addObject:appsMenu[i * 2 + 1]];
|
||||
[sub addObject:@""];
|
||||
[copy addObject:sub];
|
||||
[sub release];
|
||||
}
|
||||
|
||||
array = copy;
|
||||
appsMenu = copy;
|
||||
[defaults setObject:appsMenu forKey:XQuartzPrefKeyAppsMenu];
|
||||
}
|
||||
|
||||
[self set_apps_menu:array];
|
||||
[self set_apps_menu:appsMenu];
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(apps_table_done:)
|
||||
name: NSWindowWillCloseNotification
|
||||
object: self.apps_table.window];
|
||||
[NSNotificationCenter.defaultCenter addObserver:self
|
||||
selector:@selector(apps_table_done:)
|
||||
name:NSWindowWillCloseNotification
|
||||
object:self.apps_table.window];
|
||||
}
|
||||
|
||||
- (void) item_selected:sender
|
||||
|
@ -156,10 +155,10 @@ extern char *bundle_id_prefix;
|
|||
self.apps = nil;
|
||||
}
|
||||
|
||||
- (void) prepend_apps_item:(NSArray *)list index:(int)i menu:(NSMenu *)menu
|
||||
- (void) prepend_apps_item:(NSArray <NSArray <NSString *> *> *)list index:(int)i menu:(NSMenu *)menu
|
||||
{
|
||||
NSString *title, *shortcut = @"";
|
||||
NSArray *group;
|
||||
NSArray <NSString *> *group;
|
||||
NSMenuItem *item;
|
||||
|
||||
group = [list objectAtIndex:i];
|
||||
|
@ -183,7 +182,7 @@ extern char *bundle_id_prefix;
|
|||
[item setTag:i + 1]; /* can't be zero, so add one */
|
||||
}
|
||||
|
||||
- (void) install_apps_menu:(NSArray *)list
|
||||
- (void) install_apps_menu:(NSArray <NSArray <NSString *> *> *)list
|
||||
{
|
||||
NSMenu *menu;
|
||||
int i, count;
|
||||
|
@ -207,7 +206,7 @@ extern char *bundle_id_prefix;
|
|||
self.apps = list;
|
||||
}
|
||||
|
||||
- (void) set_window_menu:(NSArray *)list
|
||||
- (void) set_window_menu:(NSArray <NSArray <NSString *> *> *)list
|
||||
{
|
||||
NSMenu * const menu = X11App.windowsMenu;
|
||||
NSMenu * const dock_menu = self.dock_menu;
|
||||
|
@ -303,7 +302,7 @@ extern char *bundle_id_prefix;
|
|||
self.checked_window_item = n;
|
||||
}
|
||||
|
||||
- (void) set_apps_menu:(NSArray *)list
|
||||
- (void) set_apps_menu:(NSArray <NSArray <NSString *> *> *)list
|
||||
{
|
||||
[self remove_apps_menu];
|
||||
[self install_apps_menu:list];
|
||||
|
@ -349,9 +348,12 @@ extern char *bundle_id_prefix;
|
|||
int stdout_pipe[2];
|
||||
int stderr_pipe[2];
|
||||
|
||||
newargv[0] = [X11App prefs_get_string:@PREFS_LOGIN_SHELL default:"/bin/sh"];
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
NSString * const shell = [defaults stringForKey:XQuartzPrefKeyLoginShell];
|
||||
|
||||
newargv[0] = shell.fileSystemRepresentation;
|
||||
newargv[1] = "-c";
|
||||
newargv[2] = [filename UTF8String];
|
||||
newargv[2] = filename.fileSystemRepresentation;
|
||||
newargv[3] = NULL;
|
||||
|
||||
s = getenv("DISPLAY");
|
||||
|
@ -446,7 +448,7 @@ extern char *bundle_id_prefix;
|
|||
{
|
||||
int tag;
|
||||
NSString *item;
|
||||
NSArray * const apps = self.apps;
|
||||
NSArray <NSArray <NSString *> *> * const apps = self.apps;
|
||||
|
||||
tag = [sender tag] - 1;
|
||||
if (apps == nil || tag < 0 || tag >= [apps count])
|
||||
|
@ -460,15 +462,18 @@ extern char *bundle_id_prefix;
|
|||
- (IBAction) apps_table_show:sender
|
||||
{
|
||||
NSArray *columns;
|
||||
NSMutableArray *oldapps = self.table_apps;
|
||||
NSMutableArray <NSMutableArray <NSString *> *> * const oldapps = self.table_apps;
|
||||
NSTableView * const apps_table = self.apps_table;
|
||||
|
||||
NSMutableArray * const table_apps = [[NSMutableArray alloc] initWithCapacity:1];
|
||||
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = [[NSMutableArray alloc] initWithCapacity:1];
|
||||
self.table_apps = table_apps;
|
||||
|
||||
NSArray * const apps = self.apps;
|
||||
if (apps != nil)
|
||||
[table_apps addObjectsFromArray:apps];
|
||||
NSArray <NSArray <NSString *> *> * const apps = self.apps;
|
||||
if (apps != nil) {
|
||||
for (NSArray <NSString *> * row in apps) {
|
||||
[table_apps addObject:row.mutableCopy];
|
||||
}
|
||||
}
|
||||
|
||||
columns = [apps_table tableColumns];
|
||||
[[columns objectAtIndex:0] setIdentifier:@"0"];
|
||||
|
@ -487,15 +492,15 @@ extern char *bundle_id_prefix;
|
|||
|
||||
- (IBAction) apps_table_done:sender
|
||||
{
|
||||
NSMutableArray * const table_apps = self.table_apps;
|
||||
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
|
||||
NSTableView * const apps_table = self.apps_table;
|
||||
[apps_table deselectAll:sender]; /* flush edits? */
|
||||
|
||||
[self remove_apps_menu];
|
||||
[self install_apps_menu:table_apps];
|
||||
|
||||
[NSApp prefs_set_array:@PREFS_APPSMENU value:table_apps];
|
||||
[NSApp prefs_synchronize];
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
[defaults setObject:table_apps forKey:XQuartzPrefKeyAppsMenu];
|
||||
|
||||
[[apps_table window] orderOut:sender];
|
||||
|
||||
|
@ -505,7 +510,7 @@ extern char *bundle_id_prefix;
|
|||
- (IBAction) apps_table_new:sender
|
||||
{
|
||||
NSMutableArray *item;
|
||||
NSMutableArray * const table_apps = self.table_apps;
|
||||
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
|
||||
NSTableView * const apps_table = self.apps_table;
|
||||
|
||||
int row = [apps_table selectedRow], i;
|
||||
|
@ -534,10 +539,10 @@ extern char *bundle_id_prefix;
|
|||
|
||||
- (IBAction) apps_table_duplicate:sender
|
||||
{
|
||||
NSMutableArray * const table_apps = self.table_apps;
|
||||
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
|
||||
NSTableView * const apps_table = self.apps_table;
|
||||
int row = [apps_table selectedRow], i;
|
||||
NSObject *item;
|
||||
NSMutableArray <NSString *> *item;
|
||||
|
||||
if (row < 0) {
|
||||
[self apps_table_new:sender];
|
||||
|
@ -560,7 +565,7 @@ extern char *bundle_id_prefix;
|
|||
|
||||
- (IBAction) apps_table_delete:sender
|
||||
{
|
||||
NSMutableArray * const table_apps = self.table_apps;
|
||||
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
|
||||
NSTableView * const apps_table = self.apps_table;
|
||||
int row = [apps_table selectedRow];
|
||||
|
||||
|
@ -584,7 +589,7 @@ extern char *bundle_id_prefix;
|
|||
|
||||
- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView
|
||||
{
|
||||
NSMutableArray * const table_apps = self.table_apps;
|
||||
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
|
||||
if (table_apps == nil) return 0;
|
||||
|
||||
return [table_apps count];
|
||||
|
@ -593,7 +598,7 @@ extern char *bundle_id_prefix;
|
|||
- (id) tableView:(NSTableView *)tableView
|
||||
objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
|
||||
{
|
||||
NSMutableArray * const table_apps = self.table_apps;
|
||||
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
|
||||
NSArray *item;
|
||||
int col;
|
||||
|
||||
|
@ -611,8 +616,8 @@ extern char *bundle_id_prefix;
|
|||
- (void) tableView:(NSTableView *)tableView setObjectValue:(id)object
|
||||
forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
|
||||
{
|
||||
NSMutableArray * const table_apps = self.table_apps;
|
||||
NSMutableArray *item;
|
||||
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
|
||||
NSMutableArray <NSString *> *item;
|
||||
int col;
|
||||
|
||||
if (table_apps == nil) return;
|
||||
|
@ -672,15 +677,15 @@ extern char *bundle_id_prefix;
|
|||
|
||||
- (IBAction) enable_fullscreen_changed:sender
|
||||
{
|
||||
XQuartzRootlessDefault = !self.enable_fullscreen.intValue;
|
||||
XQuartzRootlessDefault = !self.enable_fullscreen.state;
|
||||
|
||||
[self.enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault];
|
||||
[self.enable_fullscreen_menu_text setTextColor:XQuartzRootlessDefault ? NSColor.disabledControlTextColor : NSColor.controlTextColor];
|
||||
|
||||
DarwinSendDDXEvent(kXquartzSetRootless, 1, XQuartzRootlessDefault);
|
||||
|
||||
[NSApp prefs_set_boolean:@PREFS_ROOTLESS value:XQuartzRootlessDefault];
|
||||
[NSApp prefs_synchronize];
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
[defaults setBool:XQuartzRootlessDefault forKey:XQuartzPrefKeyRootless];
|
||||
}
|
||||
|
||||
- (IBAction) toggle_fullscreen:sender
|
||||
|
@ -693,55 +698,43 @@ extern char *bundle_id_prefix;
|
|||
if (!sender)
|
||||
return;
|
||||
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
|
||||
if (sender == self.fake_buttons) {
|
||||
darwinFakeButtons = self.fake_buttons.intValue;
|
||||
[NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons];
|
||||
}
|
||||
else if (sender == self.enable_keyequivs) {
|
||||
XQuartzEnableKeyEquivalents = self.enable_keyequivs.intValue;
|
||||
[NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:
|
||||
XQuartzEnableKeyEquivalents];
|
||||
}
|
||||
else if (sender == self.sync_keymap) {
|
||||
darwinSyncKeymap = self.sync_keymap.intValue;
|
||||
[NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap];
|
||||
}
|
||||
else if (sender == self.enable_fullscreen_menu) {
|
||||
XQuartzFullscreenMenu = self.enable_fullscreen_menu.intValue;
|
||||
[NSApp prefs_set_boolean:@PREFS_FULLSCREEN_MENU value:
|
||||
XQuartzFullscreenMenu];
|
||||
}
|
||||
else if (sender == self.option_sends_alt) {
|
||||
darwinFakeButtons = !!self.fake_buttons.state;
|
||||
[defaults setBool:darwinFakeButtons forKey:XQuartzPrefKeyFakeButtons];
|
||||
} else if (sender == self.enable_keyequivs) {
|
||||
XQuartzEnableKeyEquivalents = !!self.enable_keyequivs.state;
|
||||
[defaults setBool:XQuartzEnableKeyEquivalents forKey:XQuartzPrefKeyKeyEquivs];
|
||||
} else if (sender == self.sync_keymap) {
|
||||
darwinSyncKeymap = !!self.sync_keymap.state;
|
||||
[defaults setBool:darwinSyncKeymap forKey:XQuartzPrefKeySyncKeymap];
|
||||
} else if (sender == self.enable_fullscreen_menu) {
|
||||
XQuartzFullscreenMenu = !!self.enable_fullscreen_menu.state;
|
||||
[defaults setBool:XQuartzFullscreenMenu forKey:XQuartzPrefKeyFullscreenMenu];
|
||||
} else if (sender == self.option_sends_alt) {
|
||||
BOOL prev_opt_sends_alt = XQuartzOptionSendsAlt;
|
||||
|
||||
XQuartzOptionSendsAlt = self.option_sends_alt.intValue;
|
||||
[NSApp prefs_set_boolean:@PREFS_OPTION_SENDS_ALT value:
|
||||
XQuartzOptionSendsAlt];
|
||||
XQuartzOptionSendsAlt = !!self.option_sends_alt.state;
|
||||
[defaults setBool:XQuartzOptionSendsAlt forKey:XQuartzPrefKeyOptionSendsAlt];
|
||||
|
||||
if (prev_opt_sends_alt != XQuartzOptionSendsAlt)
|
||||
QuartsResyncKeymap(TRUE);
|
||||
}
|
||||
else if (sender == self.click_through) {
|
||||
[NSApp prefs_set_boolean:@PREFS_CLICK_THROUGH value:self.click_through.intValue];
|
||||
}
|
||||
else if (sender == self.focus_follows_mouse) {
|
||||
[NSApp prefs_set_boolean:@PREFS_FFM value:self.focus_follows_mouse.intValue];
|
||||
}
|
||||
else if (sender == self.focus_on_new_window) {
|
||||
[NSApp prefs_set_boolean:@PREFS_FOCUS_ON_NEW_WINDOW value:self.focus_on_new_window.intValue];
|
||||
}
|
||||
else if (sender == self.enable_auth) {
|
||||
[NSApp prefs_set_boolean:@PREFS_NO_AUTH value:!self.enable_auth.intValue];
|
||||
}
|
||||
else if (sender == self.enable_tcp) {
|
||||
[NSApp prefs_set_boolean:@PREFS_NO_TCP value:!self.enable_tcp.intValue];
|
||||
}
|
||||
else if (sender == self.depth) {
|
||||
[NSApp prefs_set_integer:@PREFS_DEPTH value:self.depth.selectedTag];
|
||||
}
|
||||
else if (sender == self.sync_pasteboard) {
|
||||
} else if (sender == self.click_through) {
|
||||
[defaults setBool:!!self.click_through.state forKey:XQuartzPrefKeyClickThrough];
|
||||
} else if (sender == self.focus_follows_mouse) {
|
||||
[defaults setBool:!!self.focus_follows_mouse.state forKey:XQuartzPrefKeyFocusFollowsMouse];
|
||||
} else if (sender == self.focus_on_new_window) {
|
||||
[defaults setBool:!!self.focus_on_new_window.state forKey:XQuartzPrefKeyFocusOnNewWindow];
|
||||
} else if (sender == self.enable_auth) {
|
||||
[defaults setBool:!self.enable_auth.state forKey:XQuartzPrefKeyNoAuth];
|
||||
} else if (sender == self.enable_tcp) {
|
||||
[defaults setBool:!self.enable_tcp.state forKey:XQuartzPrefKeyNoTCP];
|
||||
} else if (sender == self.depth) {
|
||||
[defaults setInteger:self.depth.selectedTag forKey:XQuartzPrefKeyDepth];
|
||||
} else if (sender == self.sync_pasteboard) {
|
||||
BOOL pbproxy_active = self.sync_pasteboard.intValue;
|
||||
[NSApp prefs_set_boolean:@PREFS_SYNC_PB value:pbproxy_active];
|
||||
[defaults setBool:pbproxy_active forKey:XQuartzPrefKeySyncPasteboard];
|
||||
|
||||
[self.sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
|
||||
[self.sync_pasteboard_to_primary setEnabled:pbproxy_active];
|
||||
|
@ -751,33 +744,27 @@ extern char *bundle_id_prefix;
|
|||
// setEnabled doesn't do this...
|
||||
[self.sync_text1 setTextColor:pbproxy_active ? NSColor.controlTextColor : NSColor.disabledControlTextColor];
|
||||
[self.sync_text2 setTextColor:pbproxy_active ? NSColor.controlTextColor : NSColor.disabledControlTextColor];
|
||||
} else if (sender == self.sync_pasteboard_to_clipboard) {
|
||||
[defaults setBool:!!self.sync_pasteboard_to_clipboard.state forKey:XQuartzPrefKeySyncPasteboardToClipboard];
|
||||
} else if (sender == self.sync_pasteboard_to_primary) {
|
||||
[defaults setBool:!!self.sync_pasteboard_to_primary.state forKey:XQuartzPrefKeySyncPasteboardToPrimary];
|
||||
} else if (sender == self.sync_clipboard_to_pasteboard) {
|
||||
[defaults setBool:!!self.sync_clipboard_to_pasteboard.state forKey:XQuartzPrefKeySyncClipboardToPasteBoard];
|
||||
} else if (sender == self.sync_primary_immediately) {
|
||||
[defaults setBool:!!self.sync_primary_immediately.state forKey:XQuartzPrefKeySyncPrimaryOnSelect];
|
||||
} else if (sender == self.scroll_in_device_direction) {
|
||||
XQuartzScrollInDeviceDirection = !!self.scroll_in_device_direction.state;
|
||||
[defaults setBool:XQuartzScrollInDeviceDirection forKey:XQuartzPrefKeyScrollInDeviceDirection];
|
||||
}
|
||||
else if (sender == self.sync_pasteboard_to_clipboard) {
|
||||
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD value:self.sync_pasteboard_to_clipboard.intValue];
|
||||
}
|
||||
else if (sender == self.sync_pasteboard_to_primary) {
|
||||
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_PRIMARY value:self.sync_pasteboard_to_primary.intValue];
|
||||
}
|
||||
else if (sender == self.sync_clipboard_to_pasteboard) {
|
||||
[NSApp prefs_set_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB value:self.sync_clipboard_to_pasteboard.intValue];
|
||||
}
|
||||
else if (sender == self.sync_primary_immediately) {
|
||||
[NSApp prefs_set_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT value:self.sync_primary_immediately.intValue];
|
||||
}
|
||||
else if (sender == self.scroll_in_device_direction) {
|
||||
XQuartzScrollInDeviceDirection = self.scroll_in_device_direction.intValue;
|
||||
[NSApp prefs_set_boolean:@PREFS_SCROLL_IN_DEV_DIRECTION value:XQuartzScrollInDeviceDirection];
|
||||
}
|
||||
|
||||
[NSApp prefs_synchronize];
|
||||
|
||||
DarwinSendDDXEvent(kXquartzReloadPreferences, 0);
|
||||
}
|
||||
|
||||
- (IBAction) prefs_show:sender
|
||||
{
|
||||
BOOL pbproxy_active =
|
||||
[NSApp prefs_get_boolean:@PREFS_SYNC_PB default:YES];
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
|
||||
BOOL pbproxy_active = [defaults boolForKey:XQuartzPrefKeySyncPasteboard];
|
||||
|
||||
[self.scroll_in_device_direction setIntValue:XQuartzScrollInDeviceDirection];
|
||||
|
||||
|
@ -785,20 +772,20 @@ extern char *bundle_id_prefix;
|
|||
[self.enable_keyequivs setIntValue:XQuartzEnableKeyEquivalents];
|
||||
[self.sync_keymap setIntValue:darwinSyncKeymap];
|
||||
[self.option_sends_alt setIntValue:XQuartzOptionSendsAlt];
|
||||
[self.click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH default:NO]];
|
||||
[self.focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM default:NO]];
|
||||
[self.focus_on_new_window setIntValue:[NSApp prefs_get_boolean:@PREFS_FOCUS_ON_NEW_WINDOW default:YES]];
|
||||
[self.click_through setIntValue:[defaults boolForKey:XQuartzPrefKeyClickThrough]];
|
||||
[self.focus_follows_mouse setIntValue:[defaults boolForKey:XQuartzPrefKeyFocusFollowsMouse]];
|
||||
[self.focus_on_new_window setIntValue:[defaults boolForKey:XQuartzPrefKeyFocusOnNewWindow]];
|
||||
|
||||
[self.enable_auth setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_AUTH default:NO]];
|
||||
[self.enable_tcp setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_TCP default:NO]];
|
||||
[self.enable_auth setIntValue:![defaults boolForKey:XQuartzPrefKeyNoAuth]];
|
||||
[self.enable_tcp setIntValue:![defaults boolForKey:XQuartzPrefKeyNoTCP]];
|
||||
|
||||
[self.depth selectItemAtIndex:[self.depth indexOfItemWithTag:[NSApp prefs_get_integer:@PREFS_DEPTH default:-1]]];
|
||||
[self.depth selectItemAtIndex:[self.depth indexOfItemWithTag:[defaults integerForKey:XQuartzPrefKeyDepth]]];
|
||||
|
||||
[self.sync_pasteboard setIntValue:pbproxy_active];
|
||||
[self.sync_pasteboard_to_clipboard setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD default:YES]];
|
||||
[self.sync_pasteboard_to_primary setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PB_TO_PRIMARY default:YES]];
|
||||
[self.sync_clipboard_to_pasteboard setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB default:YES]];
|
||||
[self.sync_primary_immediately setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT default:NO]];
|
||||
[self.sync_pasteboard_to_clipboard setIntValue:[defaults boolForKey:XQuartzPrefKeySyncPasteboardToClipboard]];
|
||||
[self.sync_pasteboard_to_primary setIntValue:[defaults boolForKey:XQuartzPrefKeySyncPasteboardToPrimary]];
|
||||
[self.sync_clipboard_to_pasteboard setIntValue:[defaults boolForKey:XQuartzPrefKeySyncClipboardToPasteBoard]];
|
||||
[self.sync_primary_immediately setIntValue:[defaults boolForKey:XQuartzPrefKeySyncPrimaryOnSelect]];
|
||||
|
||||
[self.sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
|
||||
[self.sync_pasteboard_to_primary setEnabled:pbproxy_active];
|
||||
|
@ -863,9 +850,11 @@ extern char *bundle_id_prefix;
|
|||
NSString *msg;
|
||||
NSString *title;
|
||||
|
||||
if (self.can_quit ||
|
||||
[X11App prefs_get_boolean:@PREFS_NO_QUIT_ALERT default:NO])
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
|
||||
if (self.can_quit || [defaults boolForKey:XQuartzPrefKeyNoQuitAlert]) {
|
||||
return NSTerminateNow;
|
||||
}
|
||||
|
||||
/* Make sure we're frontmost. */
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
@ -887,8 +876,6 @@ extern char *bundle_id_prefix;
|
|||
|
||||
- (void) applicationWillTerminate:(NSNotification *)aNotification _X_NORETURN
|
||||
{
|
||||
[X11App prefs_synchronize];
|
||||
|
||||
/* shutdown the X server, it will exit () for us. */
|
||||
DarwinSendDDXEvent(kXquartzQuit, 0);
|
||||
|
||||
|
|
|
@ -28,20 +28,45 @@
|
|||
<true/>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
|
||||
<!-- Add generic usage descriptions for TCC
|
||||
https://github.com/XQuartz/XQuartz/issues/245
|
||||
-->
|
||||
<key>NSAppleEventsUsageDescription</key>
|
||||
<string>A process launched by APPLE_APPLICATION_NAME wants to use AppleScript.</string>
|
||||
<key>NSCalendarsUsageDescription</key>
|
||||
<string>A process launched by APPLE_APPLICATION_NAME wants access to your calendar data.</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>A process launched by APPLE_APPLICATION_NAME wants access to your camera.</string>
|
||||
<key>NSContactsUsageDescription</key>
|
||||
<string>A process launched by APPLE_APPLICATION_NAME wants access to your contacts.</string>
|
||||
<key>NSLocationAlwaysUsageDescription</key>
|
||||
<string>A process launched by APPLE_APPLICATION_NAME wants access to your location information, even when not in use.</string>
|
||||
<key>NSLocationUsageDescription</key>
|
||||
<string>A process launched by APPLE_APPLICATION_NAME wants access to your location information.</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>A process launched by APPLE_APPLICATION_NAME wants access to your location information when in use.</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>A process launched by APPLE_APPLICATION_NAME wants access to your microphone.</string>
|
||||
<key>NSRemindersUsageDescription</key>
|
||||
<string>A process launched by APPLE_APPLICATION_NAME wants access to your reminders.</string>
|
||||
<key>NSSystemAdministrationUsageDescription</key>
|
||||
<string>A process launched by APPLE_APPLICATION_NAME wants admin privileges.</string>
|
||||
|
||||
#ifdef XQUARTZ_SPARKLE
|
||||
<key>SUEnableAutomaticChecks</key>
|
||||
<true/>
|
||||
<key>SUPublicDSAKeyFile</key>
|
||||
<string>sparkle.pem</string>
|
||||
<key>SUPublicEDKey</key>
|
||||
<string>XQUARTZ_SPARKLE_PUBLIC_EDKEY</string>
|
||||
<key>SUFeedURL</key>
|
||||
<string>XQUARTZ_SPARKLE_FEED_URL</string>
|
||||
#endif
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>© 2003-2021 Apple Inc.
|
||||
<string>© 2003-2023 Apple Inc.
|
||||
© 2003 XFree86 Project, Inc.
|
||||
© 2003-2021 X.org Foundation, Inc.
|
||||
© 2003-2023 X.org Foundation, Inc.
|
||||
</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>main</string>
|
||||
|
|
|
@ -23,10 +23,8 @@ noinst_DATA = $(noinst_PRE:plist.cpp=plist)
|
|||
|
||||
CLEANFILES = $(noinst_DATA)
|
||||
|
||||
resourcedir=$(libdir)/X11/xserver
|
||||
resource_DATA = Xquartz.plist
|
||||
|
||||
EXTRA_DIST = \
|
||||
chown-bundle.sh \
|
||||
mk_bundke.sh \
|
||||
X11.sh \
|
||||
Info.plist.cpp \
|
||||
|
@ -181,5 +179,5 @@ EXTRA_DIST = \
|
|||
Resources/zh_TW.lproj/Localizable.strings \
|
||||
Resources/zh_TW.lproj/locversion.plist \
|
||||
Resources/zh_TW.lproj/main.nib/designable.nib \
|
||||
Resources/zh_TW.lproj/main.nib/keyedobjects.nib
|
||||
Resources/zh_TW.lproj/main.nib/keyedobjects.nib \
|
||||
Resources/zh_TW.lproj/main.nib/keyedobjects-110000.nib
|
||||
|
|
|
@ -10,10 +10,7 @@ cpp_defs = [
|
|||
]
|
||||
|
||||
if build_sparkle
|
||||
cpp_defs += [
|
||||
'-DXQUARTZ_SPARKLE',
|
||||
'-DXQUARTZ_SPARKLE_FEED_URL=@0@'.format(xquartz_sparkle_feed_url),
|
||||
]
|
||||
cpp_defs += sparkle_defs
|
||||
endif
|
||||
|
||||
# bundle data
|
||||
|
@ -56,7 +53,6 @@ install_data('PkgInfo',
|
|||
install_mode: 'rw-r--r--')
|
||||
|
||||
install_data('X11.sh',
|
||||
rename: 'X11',
|
||||
install_dir: join_paths(bundle_root, 'Contents/MacOS'),
|
||||
install_mode: 'rwxr-xr-x')
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
|
||||
<!-- This file contains system-wide defaults for the Apple X11 server -->
|
||||
<!-- This file contains system-wide defaults for XQuartz -->
|
||||
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
|
@ -12,16 +12,6 @@
|
|||
<string>xterm</string>
|
||||
<string>n</string>
|
||||
</array>
|
||||
<array>
|
||||
<string>xman</string>
|
||||
<string>xman</string>
|
||||
<string></string>
|
||||
</array>
|
||||
<array>
|
||||
<string>xlogo</string>
|
||||
<string>xlogo</string>
|
||||
<string></string>
|
||||
</array>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -72,6 +72,10 @@ FatalError(const char *f, ...) _X_ATTRIBUTE_PRINTF(1, 2) _X_NORETURN;
|
|||
|
||||
extern int noPanoramiXExtension;
|
||||
|
||||
#ifdef COMPOSITE
|
||||
extern Bool noCompositeExtension;
|
||||
#endif
|
||||
|
||||
#define DEFAULT_CLIENT X11BINDIR "/xterm"
|
||||
#define DEFAULT_STARTX X11BINDIR "/startx -- " X11BINDIR "/Xquartz"
|
||||
#define DEFAULT_SHELL "/bin/sh"
|
||||
|
@ -626,12 +630,20 @@ main(int argc, char **argv, char **envp)
|
|||
mach_port_t mp;
|
||||
kern_return_t kr;
|
||||
|
||||
/* Ignore SIGPIPE */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
/* Setup our environment for our children */
|
||||
setup_env();
|
||||
|
||||
/* The server must not run the PanoramiX operations. */
|
||||
noPanoramiXExtension = TRUE;
|
||||
|
||||
#ifdef COMPOSITE
|
||||
/* https://gitlab.freedesktop.org/xorg/xserver/-/issues/1409 */
|
||||
noCompositeExtension = TRUE;
|
||||
#endif
|
||||
|
||||
/* Setup the initial crasherporter info */
|
||||
strlcpy(__crashreporter_info_buff__, __crashreporter_info__base,
|
||||
sizeof(__crashreporter_info_buff__));
|
||||
|
|
|
@ -70,6 +70,17 @@ x11_bin = executable('X11.bin',
|
|||
install_dir: x11appdir,
|
||||
)
|
||||
|
||||
# X11 (Bundle trampoline)
|
||||
x11 = executable('X11',
|
||||
[
|
||||
'bundle_trampoline.c',
|
||||
],
|
||||
c_args: xquartz_defs,
|
||||
link_args: ['-Objc'],
|
||||
install: true,
|
||||
install_dir: x11appdir,
|
||||
)
|
||||
|
||||
# Xquartz
|
||||
xquartz_deps = [
|
||||
dependency('CoreServices', method: 'extraframework'),
|
||||
|
|
|
@ -52,39 +52,25 @@
|
|||
|
||||
#include "launchd_fd.h"
|
||||
|
||||
static char x11_path[PATH_MAX + 1];
|
||||
static CFURLRef x11appURL;
|
||||
static FSRef x11_appRef;
|
||||
static pid_t x11app_pid = 0;
|
||||
aslclient aslc;
|
||||
|
||||
static void
|
||||
set_x11_path(void)
|
||||
{
|
||||
CFURLRef appURL = NULL;
|
||||
OSStatus osstatus =
|
||||
LSFindApplicationForInfo(kLSUnknownCreator, CFSTR(
|
||||
kX11AppBundleId), nil, nil, &appURL);
|
||||
OSStatus osstatus = LSFindApplicationForInfo(kLSUnknownCreator, CFSTR(kX11AppBundleId),
|
||||
nil, &x11_appRef, &x11appURL);
|
||||
|
||||
switch (osstatus) {
|
||||
case noErr:
|
||||
if (appURL == NULL) {
|
||||
asl_log(
|
||||
aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: Invalid response from LSFindApplicationForInfo(%s)",
|
||||
kX11AppBundleId);
|
||||
if (x11appURL == NULL) {
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: Invalid response from LSFindApplicationForInfo(%s)",
|
||||
kX11AppBundleId);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!CFURLGetFileSystemRepresentation(appURL, true,
|
||||
(unsigned char *)x11_path,
|
||||
sizeof(x11_path))) {
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: Error resolving URL for %s",
|
||||
kX11AppBundleId);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
strlcat(x11_path, kX11AppBundlePath, sizeof(x11_path));
|
||||
asl_log(aslc, NULL, ASL_LEVEL_INFO, "Xquartz: X11.app = %s", x11_path);
|
||||
break;
|
||||
|
||||
case kLSApplicationNotFoundErr:
|
||||
|
@ -96,8 +82,7 @@ set_x11_path(void)
|
|||
default:
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: Unable to find application for %s, error code = %d",
|
||||
kX11AppBundleId,
|
||||
(int)osstatus);
|
||||
kX11AppBundleId, (int)osstatus);
|
||||
exit(11);
|
||||
}
|
||||
}
|
||||
|
@ -122,18 +107,15 @@ connect_to_socket(const char *filename)
|
|||
ret_fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (ret_fd == -1) {
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: Failed to create socket: %s - %s", filename,
|
||||
strerror(
|
||||
errno));
|
||||
"Xquartz: Failed to create socket: %s - %d - %s",
|
||||
filename, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (connect(ret_fd, servaddr, servaddr_len) < 0) {
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: Failed to connect to socket: %s - %d - %s",
|
||||
filename, errno,
|
||||
strerror(
|
||||
errno));
|
||||
filename, errno, strerror(errno));
|
||||
close(ret_fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -176,10 +158,9 @@ send_fd_handoff(int connected_fd, int launchd_fd)
|
|||
*((int *)CMSG_DATA(cmsg)) = launchd_fd;
|
||||
|
||||
if (sendmsg(connected_fd, &msg, 0) < 0) {
|
||||
asl_log(
|
||||
aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: Error sending $DISPLAY file descriptor over fd %d: %d -- %s",
|
||||
connected_fd, errno, strerror(errno));
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: Error sending $DISPLAY file descriptor over fd %d: %d -- %s",
|
||||
connected_fd, errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -253,24 +234,23 @@ main(int argc, char **argv, char **envp)
|
|||
server_bootstrap_name);
|
||||
set_x11_path();
|
||||
|
||||
/* This forking is ugly and will be cleaned up later */
|
||||
child = fork();
|
||||
if (child == -1) {
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Could not fork: %s",
|
||||
strerror(
|
||||
errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
char *listenOnlyArg = "--listenonly";
|
||||
CFStringRef silentLaunchArg = CFStringCreateWithCString(NULL, listenOnlyArg, kCFStringEncodingUTF8);
|
||||
CFStringRef args[] = { silentLaunchArg };
|
||||
CFArrayRef passArgv = CFArrayCreate(NULL, (const void**) args, 1, NULL);
|
||||
LSApplicationParameters params = { 0, /* CFIndex version == 0 */
|
||||
kLSLaunchDefaults, /* LSLaunchFlags flags */
|
||||
&x11_appRef, /* FSRef application */
|
||||
NULL, /* void* asyncLaunchRefCon*/
|
||||
NULL, /* CFDictionaryRef environment */
|
||||
passArgv, /* CFArrayRef arguments */
|
||||
NULL /* AppleEvent* initialEvent */
|
||||
};
|
||||
|
||||
if (child == 0) {
|
||||
char *_argv[3];
|
||||
_argv[0] = x11_path;
|
||||
_argv[1] = "--listenonly";
|
||||
_argv[2] = NULL;
|
||||
asl_log(aslc, NULL, ASL_LEVEL_NOTICE,
|
||||
"Xquartz: Starting X server: %s --listenonly",
|
||||
x11_path);
|
||||
return execvp(x11_path, _argv);
|
||||
OSStatus status = LSOpenApplication(¶ms, NULL);
|
||||
if (status != noErr) {
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Unable to launch: %d", (int)status);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Try connecting for 10 seconds */
|
||||
|
@ -283,8 +263,7 @@ main(int argc, char **argv, char **envp)
|
|||
|
||||
if (kr != KERN_SUCCESS) {
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: bootstrap_look_up(): %s", bootstrap_strerror(
|
||||
kr));
|
||||
"Xquartz: bootstrap_look_up(): %s", bootstrap_strerror(kr));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -298,13 +277,10 @@ main(int argc, char **argv, char **envp)
|
|||
int handoff_fd = -1;
|
||||
|
||||
for (try = 0, try_max = 5; try < try_max; try++) {
|
||||
if (request_fd_handoff_socket(mp,
|
||||
handoff_socket_filename) !=
|
||||
KERN_SUCCESS) {
|
||||
asl_log(
|
||||
aslc, NULL, ASL_LEVEL_INFO,
|
||||
"Xquartz: Failed to request a socket from the server to send the $DISPLAY fd over (try %d of %d)",
|
||||
(int)try + 1, (int)try_max);
|
||||
if (request_fd_handoff_socket(mp, handoff_socket_filename) != KERN_SUCCESS) {
|
||||
asl_log(aslc, NULL, ASL_LEVEL_INFO,
|
||||
"Xquartz: Failed to request a socket from the server to send the $DISPLAY fd over (try %d of %d)",
|
||||
(int)try + 1, (int)try_max);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -312,16 +288,13 @@ main(int argc, char **argv, char **envp)
|
|||
if (handoff_fd == -1) {
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: Failed to connect to socket (try %d of %d)",
|
||||
(int)try + 1,
|
||||
(int)try_max);
|
||||
(int)try + 1, (int)try_max);
|
||||
continue;
|
||||
}
|
||||
|
||||
asl_log(
|
||||
aslc, NULL, ASL_LEVEL_INFO,
|
||||
"Xquartz: Handoff connection established (try %d of %d) on fd %d, \"%s\". Sending message.",
|
||||
(int)try + 1, (int)try_max, handoff_fd,
|
||||
handoff_socket_filename);
|
||||
asl_log(aslc, NULL, ASL_LEVEL_INFO,
|
||||
"Xquartz: Handoff connection established (try %d of %d) on fd %d, \"%s\". Sending message.",
|
||||
(int)try + 1, (int)try_max, handoff_fd, handoff_socket_filename);
|
||||
send_fd_handoff(handoff_fd, launchd_fd);
|
||||
close(handoff_fd);
|
||||
break;
|
||||
|
@ -342,8 +315,7 @@ main(int argc, char **argv, char **envp)
|
|||
free(newargv);
|
||||
free(newenvp);
|
||||
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR,
|
||||
"Xquartz: Memory allocation failure");
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Memory allocation failure");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -361,8 +333,7 @@ main(int argc, char **argv, char **envp)
|
|||
|
||||
if (kr != KERN_SUCCESS) {
|
||||
asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: start_x11_server: %s",
|
||||
mach_error_string(
|
||||
kr));
|
||||
mach_error_string(kr));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
@ -4,22 +4,44 @@ apple_applications_dir = get_option('apple-applications-dir')
|
|||
apple_application_name = get_option('apple-application-name')
|
||||
bundle_id_prefix = get_option('bundle-id-prefix')
|
||||
xquartz_sparkle_feed_url = get_option('sparkle-feed-url')
|
||||
xquartz_sparkle_public_edkey = get_option('sparkle-public-edkey')
|
||||
|
||||
bundle_version_string = meson.project_version() # CFBundleShortVersionString
|
||||
bundle_version = release # CFBundleVersion
|
||||
bundle_version_string = get_option('bundle-version-string') # CFBundleShortVersionString
|
||||
if bundle_version_string == 'auto'
|
||||
bundle_version_string = meson.project_version()
|
||||
endif
|
||||
|
||||
bundle_version = get_option('bundle-version') # CFBundleVersion
|
||||
if bundle_version == 'auto'
|
||||
version_arr = bundle_version_string.split('.')
|
||||
version_major = version_arr[0].to_int()
|
||||
version_minor = version_arr[1].to_int()
|
||||
version_tiny = version_arr[2].to_int()
|
||||
bundle_version = '@0@.@1@.@2@'.format(version_major, version_minor, version_tiny)
|
||||
endif
|
||||
|
||||
bundle_id_def = '-DBUNDLE_ID_PREFIX="@0@"'.format(bundle_id_prefix)
|
||||
|
||||
bundle_root = join_paths(apple_applications_dir, apple_application_name + '.app')
|
||||
xquartz_data_dir = join_paths(get_option('prefix'), get_option('datadir'),'X11', 'XQuartz')
|
||||
|
||||
# using sparkle update framework?
|
||||
build_sparkle = xquartz_sparkle_feed_url != ''
|
||||
build_sparkle = xquartz_sparkle_feed_url != '' and xquartz_sparkle_public_edkey != ''
|
||||
if build_sparkle
|
||||
sparkle = dependency('Sparkle', method: 'extraframework')
|
||||
|
||||
sparkle_defs = [
|
||||
'-DXQUARTZ_SPARKLE',
|
||||
'-DXQUARTZ_SPARKLE_FEED_URL=@0@'.format(xquartz_sparkle_feed_url),
|
||||
'-DXQUARTZ_SPARKLE_PUBLIC_EDKEY=@0@'.format(xquartz_sparkle_public_edkey),
|
||||
]
|
||||
else
|
||||
sparkle_defs = []
|
||||
endif
|
||||
|
||||
# libxquartz
|
||||
srcs_libxquartz = [
|
||||
'NSUserDefaults+XQuartzDefaults.m',
|
||||
'X11Application.m',
|
||||
'X11Controller.m',
|
||||
'applewm.c',
|
||||
|
@ -37,12 +59,12 @@ srcs_libxquartz = [
|
|||
|
||||
libxquartz_defs = [
|
||||
'-DUSE_NEW_CLUT',
|
||||
'-DX11LIBDIR="@0@"'.format(join_paths(get_option('prefix'),
|
||||
get_option('libdir'))),
|
||||
'-DXFree86Server',
|
||||
'-DXQUARTZ',
|
||||
'-DXQUARTZ_DATA_DIR="@0@"'.format(xquartz_data_dir),
|
||||
'-DXSERVER_VERSION="@0@"'.format(meson.project_version()),
|
||||
bundle_id_def,
|
||||
sparkle_defs,
|
||||
]
|
||||
|
||||
if cc.has_function('dispatch_async')
|
||||
|
@ -73,3 +95,7 @@ xquartz_man = configure_file(
|
|||
configuration: manpage_config,
|
||||
)
|
||||
install_man(xquartz_man)
|
||||
|
||||
install_data('defaults.plist',
|
||||
install_dir: xquartz_data_dir,
|
||||
install_mode: 'rw-r--r--')
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
AM_CPPFLAGS=-DBUNDLE_ID_PREFIX=\"$(BUNDLE_ID_PREFIX)\"
|
||||
AM_CPPFLAGS=-I.. -DXQUARTZ_DATA_DIR=\"$(datadir)/X11/XQuartz\"
|
||||
|
||||
AM_CFLAGS=$(XPBPROXY_CFLAGS)
|
||||
AM_OBJCFLAGS=$(XPBPROXY_CFLAGS)
|
||||
|
@ -15,7 +15,7 @@ libxpbproxy_la_LDFLAGS=$(XPBPROXY_LIBS)
|
|||
if STANDALONE_XPBPROXY
|
||||
|
||||
bin_PROGRAMS = xpbproxy
|
||||
xpbproxy_SOURCES = app-main.m
|
||||
xpbproxy_SOURCES = app-main.m ../NSUserDefaults+XQuartzDefaults.m
|
||||
xpbproxy_LDADD = libxpbproxy.la
|
||||
xpbproxy_LDFLAGS = -Wl,-framework,Cocoa
|
||||
|
||||
|
|
|
@ -31,13 +31,6 @@
|
|||
#include "pbproxy.h"
|
||||
#import "x-selection.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h> /*for getpid*/
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
static const char *app_prefs_domain = BUNDLE_ID_PREFIX ".xpbproxy";
|
||||
CFStringRef app_prefs_domain_cfstr;
|
||||
|
||||
/* Stubs */
|
||||
char *display = NULL;
|
||||
|
||||
|
@ -82,41 +75,8 @@ xq_asl_log(int level, const char *subsystem, const char *file,
|
|||
int
|
||||
main(int argc, const char *argv[])
|
||||
{
|
||||
const char *s;
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
ErrorF("pid: %u\n", getpid());
|
||||
#endif
|
||||
|
||||
xpbproxy_is_standalone = YES;
|
||||
|
||||
if ((s = getenv("X11_PREFS_DOMAIN")))
|
||||
app_prefs_domain = s;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--prefs-domain") == 0 && i + 1 < argc) {
|
||||
app_prefs_domain = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "--help") == 0) {
|
||||
ErrorF(
|
||||
"usage: xpbproxy OPTIONS\n"
|
||||
"Pasteboard proxying for X11.\n\n"
|
||||
"--prefs-domain <domain> Change the domain used for reading preferences\n"
|
||||
" (default: %s)\n",
|
||||
app_prefs_domain);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
ErrorF("usage: xpbproxy OPTIONS...\n"
|
||||
"Try 'xpbproxy --help' for more information.\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
app_prefs_domain_cfstr = CFStringCreateWithCString(NULL, app_prefs_domain,
|
||||
kCFStringEncodingUTF8);
|
||||
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
signal(SIGHUP, signal_handler);
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
build_standalone_pbproxy = get_option('xpbproxy')
|
||||
|
||||
pbproxy_defs = [bundle_id_def]
|
||||
pbproxy_defs = [
|
||||
'-DXQUARTZ_DATA_DIR="@0@"'.format(xquartz_data_dir),
|
||||
bundle_id_def
|
||||
]
|
||||
if build_standalone_pbproxy
|
||||
pbproxy_defs += ['-DSTANDALONE_XPBPROXY']
|
||||
endif
|
||||
|
@ -8,9 +11,11 @@ endif
|
|||
libapplewm_dep = dependency('applewm', version: '>=1.4')
|
||||
|
||||
libxpbproxy = static_library('xpbproxy',
|
||||
['main.m',
|
||||
['../NSUserDefaults+XQuartzDefaults.m',
|
||||
'main.m',
|
||||
'x-input.m',
|
||||
'x-selection.m'],
|
||||
include_directories: ['..'],
|
||||
dependencies: [applewmproto_dep, libapplewm_dep, dependency('xfixes'), dependency('x11')],
|
||||
objc_args: pbproxy_defs,
|
||||
)
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#import <AppKit/NSImage.h>
|
||||
#import <AppKit/NSBitmapImageRep.h>
|
||||
|
||||
#import "NSUserDefaults+XQuartzDefaults.h"
|
||||
|
||||
/*
|
||||
* The basic design of the pbproxy code is as follows.
|
||||
*
|
||||
|
@ -99,18 +101,6 @@ dump_prefs()
|
|||
}
|
||||
#endif
|
||||
|
||||
extern CFStringRef app_prefs_domain_cfstr;
|
||||
|
||||
static BOOL
|
||||
prefs_get_bool(CFStringRef key, BOOL defaultValue)
|
||||
{
|
||||
Boolean value, ok;
|
||||
|
||||
value = CFPreferencesGetAppBooleanValue(key, app_prefs_domain_cfstr, &ok);
|
||||
|
||||
return ok ? (BOOL)value : defaultValue;
|
||||
}
|
||||
|
||||
static void
|
||||
init_propdata(struct propdata *pdata)
|
||||
{
|
||||
|
@ -1394,35 +1384,18 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete,
|
|||
|
||||
- (void) reload_preferences
|
||||
{
|
||||
/*
|
||||
* It's uncertain how we could handle the synchronization failing, so cast to void.
|
||||
* The prefs_get_bool should fall back to defaults if the org.x.X11 plist doesn't exist or is invalid.
|
||||
*/
|
||||
(void)CFPreferencesAppSynchronize(app_prefs_domain_cfstr);
|
||||
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
|
||||
|
||||
#ifdef STANDALONE_XPBPROXY
|
||||
if (xpbproxy_is_standalone)
|
||||
pbproxy_prefs.active = YES;
|
||||
else
|
||||
#endif
|
||||
pbproxy_prefs.active = prefs_get_bool(CFSTR(
|
||||
"sync_pasteboard"),
|
||||
pbproxy_prefs.active);
|
||||
pbproxy_prefs.primary_on_grab =
|
||||
prefs_get_bool(CFSTR(
|
||||
"sync_primary_on_select"),
|
||||
pbproxy_prefs.primary_on_grab);
|
||||
pbproxy_prefs.clipboard_to_pasteboard =
|
||||
prefs_get_bool(CFSTR(
|
||||
"sync_clipboard_to_pasteboard"),
|
||||
pbproxy_prefs.clipboard_to_pasteboard);
|
||||
pbproxy_prefs.pasteboard_to_primary =
|
||||
prefs_get_bool(CFSTR(
|
||||
"sync_pasteboard_to_primary"),
|
||||
pbproxy_prefs.pasteboard_to_primary);
|
||||
pbproxy_prefs.pasteboard_to_clipboard =
|
||||
prefs_get_bool(CFSTR(
|
||||
"sync_pasteboard_to_clipboard"),
|
||||
pbproxy_prefs.pasteboard_to_clipboard);
|
||||
pbproxy_prefs.active = [defaults boolForKey:XQuartzPrefKeySyncPasteboard];
|
||||
pbproxy_prefs.primary_on_grab = [defaults boolForKey:XQuartzPrefKeySyncPrimaryOnSelect];
|
||||
pbproxy_prefs.clipboard_to_pasteboard = [defaults boolForKey:XQuartzPrefKeySyncClipboardToPasteBoard];
|
||||
pbproxy_prefs.pasteboard_to_primary = [defaults boolForKey:XQuartzPrefKeySyncPasteboardToPrimary];
|
||||
pbproxy_prefs.pasteboard_to_clipboard = [defaults boolForKey:XQuartzPrefKeySyncPasteboardToClipboard];
|
||||
|
||||
/* This is used for debugging. */
|
||||
//dump_prefs();
|
||||
|
|
|
@ -85,14 +85,16 @@ int aquaMenuBarHeight = 0;
|
|||
QuartzModeProcsPtr quartzProcs = NULL;
|
||||
const char *quartzOpenGLBundle = NULL;
|
||||
|
||||
Bool XQuartzFullscreenDisableHotkeys = TRUE;
|
||||
Bool XQuartzOptionSendsAlt = FALSE;
|
||||
Bool XQuartzEnableKeyEquivalents = TRUE;
|
||||
/* These are initialized by X11Application with default values set in NSUserDefaults+XQuartzDefaults */
|
||||
Bool XQuartzFullscreenDisableHotkeys;
|
||||
Bool XQuartzOptionSendsAlt;
|
||||
Bool XQuartzEnableKeyEquivalents;
|
||||
Bool XQuartzFullscreenMenu;
|
||||
Bool XQuartzRootlessDefault;
|
||||
|
||||
Bool XQuartzFullscreenVisible = FALSE;
|
||||
Bool XQuartzRootlessDefault = TRUE;
|
||||
Bool XQuartzIsRootless = TRUE;
|
||||
Bool XQuartzServerVisible = FALSE;
|
||||
Bool XQuartzFullscreenMenu = FALSE;
|
||||
|
||||
int32_t XQuartzShieldingWindowLevel = 0;
|
||||
|
||||
|
|
|
@ -272,6 +272,7 @@ ProcAppleDRICreatePixmap(ClientPtr client)
|
|||
xAppleDRICreatePixmapReply rep;
|
||||
int width, height, pitch, bpp;
|
||||
void *ptr;
|
||||
CARD32 stringLength;
|
||||
|
||||
REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq);
|
||||
|
||||
|
@ -307,6 +308,7 @@ ProcAppleDRICreatePixmap(ClientPtr client)
|
|||
if (sizeof(rep) != sz_xAppleDRICreatePixmapReply)
|
||||
ErrorF("error sizeof(rep) is %zu\n", sizeof(rep));
|
||||
|
||||
stringLength = rep.stringLength; /* save unswapped value */
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
|
@ -319,7 +321,7 @@ ProcAppleDRICreatePixmap(ClientPtr client)
|
|||
}
|
||||
|
||||
WriteToClient(client, sizeof(rep), &rep);
|
||||
WriteToClient(client, rep.stringLength, path);
|
||||
WriteToClient(client, stringLength, path);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
|
|
@ -45,10 +45,6 @@
|
|||
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
#ifdef DEBUG_XP_LOCK_WINDOW
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
#define DEFINE_ATOM_HELPER(func, atom_name) \
|
||||
static Atom func(void) { \
|
||||
static int generation; \
|
||||
|
@ -353,15 +349,8 @@ xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
|
|||
xp_error err;
|
||||
|
||||
#ifdef DEBUG_XP_LOCK_WINDOW
|
||||
void* callstack[128];
|
||||
int i, frames = backtrace(callstack, 128);
|
||||
char** strs = backtrace_symbols(callstack, frames);
|
||||
|
||||
ErrorF("=== LOCK %d ===\n", (int)x_cvt_vptr_to_uint(wid));
|
||||
for (i = 0; i < frames; ++i) {
|
||||
ErrorF(" %s\n", strs[i]);
|
||||
}
|
||||
free(strs);
|
||||
xorg_backtrace();
|
||||
#endif
|
||||
|
||||
err = xp_lock_window(x_cvt_vptr_to_uint(
|
||||
|
@ -371,6 +360,10 @@ xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
|
|||
(int)x_cvt_vptr_to_uint(
|
||||
wid), (int)err);
|
||||
|
||||
#ifdef DEBUG_XP_LOCK_WINDOW
|
||||
ErrorF(" bits: %p\n", *data);
|
||||
#endif
|
||||
|
||||
*pixelData = data[0];
|
||||
*bytesPerRow = rowbytes[0];
|
||||
}
|
||||
|
@ -384,15 +377,8 @@ xprStopDrawing(RootlessFrameID wid, Bool flush)
|
|||
xp_error err;
|
||||
|
||||
#ifdef DEBUG_XP_LOCK_WINDOW
|
||||
void* callstack[128];
|
||||
int i, frames = backtrace(callstack, 128);
|
||||
char** strs = backtrace_symbols(callstack, frames);
|
||||
|
||||
ErrorF("=== UNLOCK %d ===\n", (int)x_cvt_vptr_to_uint(wid));
|
||||
for (i = 0; i < frames; ++i) {
|
||||
ErrorF(" %s\n", strs[i]);
|
||||
}
|
||||
free(strs);
|
||||
xorg_backtrace();
|
||||
#endif
|
||||
|
||||
err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush);
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
Xwayland
|
||||
drm-client-protocol.h
|
||||
drm-protocol.c
|
||||
linux-dmabuf-unstable-v1-client-protocol.h
|
||||
linux-dmabuf-unstable-v1-protocol.c
|
||||
pointer-constraints-unstable-v1-client-protocol.h
|
||||
pointer-constraints-unstable-v1-protocol.c
|
||||
relative-pointer-unstable-v1-client-protocol.h
|
||||
relative-pointer-unstable-v1-protocol.c
|
||||
tablet-unstable-v2-client-protocol.h
|
||||
tablet-unstable-v2-protocol.c
|
||||
viewporter-client-protocol.h
|
||||
viewporter-protocol.c
|
||||
xdg-output-unstable-v1-client-protocol.h
|
||||
xdg-output-unstable-v1-protocol.c
|
||||
xwayland-keyboard-grab-unstable-v1-client-protocol.h
|
||||
xwayland-keyboard-grab-unstable-v1-protocol.c
|
|
@ -1,189 +0,0 @@
|
|||
SUBDIRS = man
|
||||
|
||||
DIST_SUBDIRS = man
|
||||
|
||||
bindir = @xwayland_path@
|
||||
bin_PROGRAMS = Xwayland
|
||||
|
||||
Xwayland_CFLAGS = \
|
||||
-I$(top_srcdir)/glamor \
|
||||
-I$(top_srcdir)/dri3 \
|
||||
-DHAVE_DIX_CONFIG_H \
|
||||
$(XWAYLANDMODULES_CFLAGS) \
|
||||
$(DIX_CFLAGS) \
|
||||
$(GLAMOR_CFLAGS) \
|
||||
$(GBM_CFLAGS) \
|
||||
$(LIBXCVT_CFLAGS)
|
||||
|
||||
Xwayland_SOURCES = \
|
||||
xwayland.c \
|
||||
xwayland-input.c \
|
||||
xwayland-input.h \
|
||||
xwayland-cursor.c \
|
||||
xwayland-cursor.h \
|
||||
xwayland-glamor.h \
|
||||
xwayland-glx.h \
|
||||
xwayland-pixmap.c \
|
||||
xwayland-pixmap.h \
|
||||
xwayland-present.h \
|
||||
xwayland-screen.c \
|
||||
xwayland-screen.h \
|
||||
xwayland-shm.c \
|
||||
xwayland-shm.h \
|
||||
xwayland-types.h \
|
||||
xwayland-output.c \
|
||||
xwayland-output.h \
|
||||
xwayland-cvt.c \
|
||||
xwayland-cvt.h \
|
||||
xwayland-vidmode.c \
|
||||
xwayland-vidmode.h \
|
||||
xwayland-window.c \
|
||||
xwayland-window.h \
|
||||
xwayland-window-buffers.c \
|
||||
xwayland-window-buffers.h \
|
||||
$(top_srcdir)/Xi/stubs.c \
|
||||
$(top_srcdir)/mi/miinitext.c \
|
||||
$(top_srcdir)/mi/miinitext.h
|
||||
|
||||
if GLAMOR
|
||||
if GLX
|
||||
Xwayland_SOURCES += \
|
||||
xwayland-glx.c
|
||||
Xwayland_CFLAGS += \
|
||||
-I$(top_srcdir)/glx
|
||||
GLXVND_LIB = $(top_builddir)/glx/libglxvnd.la
|
||||
endif #GLX
|
||||
endif # GLAMOR
|
||||
|
||||
Xwayland_LDADD = \
|
||||
$(glamor_lib) \
|
||||
$(XWAYLAND_LIBS) \
|
||||
$(GLXVND_LIB) \
|
||||
$(XWAYLAND_SYS_LIBS) \
|
||||
$(top_builddir)/Xext/libXvidmode.la \
|
||||
$(XSERVER_SYS_LIBS) \
|
||||
$(LIBXCVT_LIBS)
|
||||
Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
|
||||
|
||||
Xwayland_built_sources =
|
||||
|
||||
if GLAMOR_EGL
|
||||
Xwayland_SOURCES += \
|
||||
xwayland-glamor.c \
|
||||
xwayland-glamor-gbm.c \
|
||||
xwayland-present.c
|
||||
if XV
|
||||
Xwayland_SOURCES += \
|
||||
xwayland-glamor-xv.c
|
||||
endif
|
||||
|
||||
if XWAYLAND_EGLSTREAM
|
||||
Xwayland_SOURCES += \
|
||||
xwayland-glamor-eglstream.c
|
||||
endif
|
||||
|
||||
glamor_built_sources = \
|
||||
drm-client-protocol.h \
|
||||
drm-protocol.c
|
||||
|
||||
Xwayland_built_sources += $(glamor_built_sources)
|
||||
|
||||
glamor_lib = $(top_builddir)/glamor/libglamor.la
|
||||
|
||||
Xwayland_LDADD += $(GLAMOR_LIBS) $(GBM_LIBS) -lEGL -lGL
|
||||
Xwayland_DEPENDENCIES = $(glamor_lib) $(XWAYLAND_LIBS)
|
||||
endif
|
||||
|
||||
Xwayland_built_sources += \
|
||||
relative-pointer-unstable-v1-client-protocol.h \
|
||||
relative-pointer-unstable-v1-protocol.c \
|
||||
pointer-constraints-unstable-v1-client-protocol.h \
|
||||
pointer-constraints-unstable-v1-protocol.c \
|
||||
tablet-unstable-v2-client-protocol.h \
|
||||
tablet-unstable-v2-protocol.c \
|
||||
xwayland-keyboard-grab-unstable-v1-protocol.c \
|
||||
xwayland-keyboard-grab-unstable-v1-client-protocol.h \
|
||||
xdg-output-unstable-v1-protocol.c \
|
||||
xdg-output-unstable-v1-client-protocol.h \
|
||||
linux-dmabuf-unstable-v1-client-protocol.h \
|
||||
linux-dmabuf-unstable-v1-protocol.c \
|
||||
viewporter-client-protocol.h \
|
||||
viewporter-protocol.c\
|
||||
xdg-shell-client-protocol.h\
|
||||
xdg-shell-protocol.c
|
||||
|
||||
if XWAYLAND_EGLSTREAM
|
||||
Xwayland_built_sources += \
|
||||
wayland-eglstream-client-protocol.h \
|
||||
wayland-eglstream-protocol.c \
|
||||
wayland-eglstream-controller-client-protocol.h \
|
||||
wayland-eglstream-controller-protocol.c
|
||||
endif
|
||||
|
||||
nodist_Xwayland_SOURCES = $(Xwayland_built_sources)
|
||||
CLEANFILES = $(Xwayland_built_sources)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = xwayland.pc
|
||||
|
||||
EXTRA_DIST = xwayland.pc.in drm.xml
|
||||
|
||||
$(Xwayland_SOURCES): $(Xwayland_built_sources)
|
||||
|
||||
relink:
|
||||
$(AM_V_at)rm -f Xwayland$(EXEEXT) && $(MAKE) Xwayland$(EXEEXT)
|
||||
|
||||
relative-pointer-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/relative-pointer/relative-pointer-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
|
||||
relative-pointer-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/relative-pointer/relative-pointer-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
||||
|
||||
pointer-constraints-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
|
||||
pointer-constraints-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
||||
|
||||
tablet-unstable-v2-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
|
||||
tablet-unstable-v2-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
||||
|
||||
xwayland-keyboard-grab-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
|
||||
xwayland-keyboard-grab-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
||||
xdg-output-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xdg-output/xdg-output-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
|
||||
xdg-output-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xdg-output/xdg-output-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
||||
|
||||
linux-dmabuf-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
|
||||
linux-dmabuf-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
||||
|
||||
viewporter-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
|
||||
viewporter-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
||||
|
||||
xdg-shell-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
|
||||
xdg-shell-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
||||
|
||||
wayland-eglstream-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
||||
wayland-eglstream-controller-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream-controller.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
||||
|
||||
wayland-eglstream-protocol.c : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
|
||||
wayland-eglstream-controller-protocol.c : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream-controller.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
|
||||
|
||||
%-protocol.c : %.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
|
||||
|
||||
%-client-protocol.h : %.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
|
|
@ -1,185 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="drm">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2008-2011 Kristian Høgsberg
|
||||
Copyright © 2010-2011 Intel Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that\n the above copyright notice appear in
|
||||
all copies and that both that copyright notice and this permission
|
||||
notice appear in supporting documentation, and that the name of
|
||||
the copyright holders not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission. The copyright holders make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<!-- drm support. This object is created by the server and published
|
||||
using the display's global event. -->
|
||||
<interface name="wl_drm" version="2">
|
||||
<enum name="error">
|
||||
<entry name="authenticate_fail" value="0"/>
|
||||
<entry name="invalid_format" value="1"/>
|
||||
<entry name="invalid_name" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="format">
|
||||
<!-- The drm format codes match the #defines in drm_fourcc.h.
|
||||
The formats actually supported by the compositor will be
|
||||
reported by the format event. -->
|
||||
<entry name="c8" value="0x20203843"/>
|
||||
<entry name="rgb332" value="0x38424752"/>
|
||||
<entry name="bgr233" value="0x38524742"/>
|
||||
<entry name="xrgb4444" value="0x32315258"/>
|
||||
<entry name="xbgr4444" value="0x32314258"/>
|
||||
<entry name="rgbx4444" value="0x32315852"/>
|
||||
<entry name="bgrx4444" value="0x32315842"/>
|
||||
<entry name="argb4444" value="0x32315241"/>
|
||||
<entry name="abgr4444" value="0x32314241"/>
|
||||
<entry name="rgba4444" value="0x32314152"/>
|
||||
<entry name="bgra4444" value="0x32314142"/>
|
||||
<entry name="xrgb1555" value="0x35315258"/>
|
||||
<entry name="xbgr1555" value="0x35314258"/>
|
||||
<entry name="rgbx5551" value="0x35315852"/>
|
||||
<entry name="bgrx5551" value="0x35315842"/>
|
||||
<entry name="argb1555" value="0x35315241"/>
|
||||
<entry name="abgr1555" value="0x35314241"/>
|
||||
<entry name="rgba5551" value="0x35314152"/>
|
||||
<entry name="bgra5551" value="0x35314142"/>
|
||||
<entry name="rgb565" value="0x36314752"/>
|
||||
<entry name="bgr565" value="0x36314742"/>
|
||||
<entry name="rgb888" value="0x34324752"/>
|
||||
<entry name="bgr888" value="0x34324742"/>
|
||||
<entry name="xrgb8888" value="0x34325258"/>
|
||||
<entry name="xbgr8888" value="0x34324258"/>
|
||||
<entry name="rgbx8888" value="0x34325852"/>
|
||||
<entry name="bgrx8888" value="0x34325842"/>
|
||||
<entry name="argb8888" value="0x34325241"/>
|
||||
<entry name="abgr8888" value="0x34324241"/>
|
||||
<entry name="rgba8888" value="0x34324152"/>
|
||||
<entry name="bgra8888" value="0x34324142"/>
|
||||
<entry name="xrgb2101010" value="0x30335258"/>
|
||||
<entry name="xbgr2101010" value="0x30334258"/>
|
||||
<entry name="rgbx1010102" value="0x30335852"/>
|
||||
<entry name="bgrx1010102" value="0x30335842"/>
|
||||
<entry name="argb2101010" value="0x30335241"/>
|
||||
<entry name="abgr2101010" value="0x30334241"/>
|
||||
<entry name="rgba1010102" value="0x30334152"/>
|
||||
<entry name="bgra1010102" value="0x30334142"/>
|
||||
<entry name="yuyv" value="0x56595559"/>
|
||||
<entry name="yvyu" value="0x55595659"/>
|
||||
<entry name="uyvy" value="0x59565955"/>
|
||||
<entry name="vyuy" value="0x59555956"/>
|
||||
<entry name="ayuv" value="0x56555941"/>
|
||||
<entry name="nv12" value="0x3231564e"/>
|
||||
<entry name="nv21" value="0x3132564e"/>
|
||||
<entry name="nv16" value="0x3631564e"/>
|
||||
<entry name="nv61" value="0x3136564e"/>
|
||||
<entry name="yuv410" value="0x39565559"/>
|
||||
<entry name="yvu410" value="0x39555659"/>
|
||||
<entry name="yuv411" value="0x31315559"/>
|
||||
<entry name="yvu411" value="0x31315659"/>
|
||||
<entry name="yuv420" value="0x32315559"/>
|
||||
<entry name="yvu420" value="0x32315659"/>
|
||||
<entry name="yuv422" value="0x36315559"/>
|
||||
<entry name="yvu422" value="0x36315659"/>
|
||||
<entry name="yuv444" value="0x34325559"/>
|
||||
<entry name="yvu444" value="0x34325659"/>
|
||||
</enum>
|
||||
|
||||
<!-- Call this request with the magic received from drmGetMagic().
|
||||
It will be passed on to the drmAuthMagic() or
|
||||
DRIAuthConnection() call. This authentication must be
|
||||
completed before create_buffer could be used. -->
|
||||
<request name="authenticate">
|
||||
<arg name="id" type="uint"/>
|
||||
</request>
|
||||
|
||||
<!-- Create a wayland buffer for the named DRM buffer. The DRM
|
||||
surface must have a name using the flink ioctl -->
|
||||
<request name="create_buffer">
|
||||
<arg name="id" type="new_id" interface="wl_buffer"/>
|
||||
<arg name="name" type="uint"/>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
<arg name="stride" type="uint"/>
|
||||
<arg name="format" type="uint"/>
|
||||
</request>
|
||||
|
||||
<!-- Create a wayland buffer for the named DRM buffer. The DRM
|
||||
surface must have a name using the flink ioctl -->
|
||||
<request name="create_planar_buffer">
|
||||
<arg name="id" type="new_id" interface="wl_buffer"/>
|
||||
<arg name="name" type="uint"/>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
<arg name="format" type="uint"/>
|
||||
<arg name="offset0" type="int"/>
|
||||
<arg name="stride0" type="int"/>
|
||||
<arg name="offset1" type="int"/>
|
||||
<arg name="stride1" type="int"/>
|
||||
<arg name="offset2" type="int"/>
|
||||
<arg name="stride2" type="int"/>
|
||||
</request>
|
||||
|
||||
<!-- Notification of the path of the drm device which is used by
|
||||
the server. The client should use this device for creating
|
||||
local buffers. Only buffers created from this device should
|
||||
be be passed to the server using this drm object's
|
||||
create_buffer request. -->
|
||||
<event name="device">
|
||||
<arg name="name" type="string"/>
|
||||
</event>
|
||||
|
||||
<event name="format">
|
||||
<arg name="format" type="uint"/>
|
||||
</event>
|
||||
|
||||
<!-- Raised if the authenticate request succeeded -->
|
||||
<event name="authenticated"/>
|
||||
|
||||
<enum name="capability" since="2">
|
||||
<description summary="wl_drm capability bitmask">
|
||||
Bitmask of capabilities.
|
||||
</description>
|
||||
<entry name="prime" value="1" summary="wl_drm prime available"/>
|
||||
</enum>
|
||||
|
||||
<event name="capabilities">
|
||||
<arg name="value" type="uint"/>
|
||||
</event>
|
||||
|
||||
<!-- Version 2 additions -->
|
||||
|
||||
<!-- Create a wayland buffer for the prime fd. Use for regular and planar
|
||||
buffers. Pass 0 for offset and stride for unused planes. -->
|
||||
<request name="create_prime_buffer" since="2">
|
||||
<arg name="id" type="new_id" interface="wl_buffer"/>
|
||||
<arg name="name" type="fd"/>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
<arg name="format" type="uint"/>
|
||||
<arg name="offset0" type="int"/>
|
||||
<arg name="stride0" type="int"/>
|
||||
<arg name="offset1" type="int"/>
|
||||
<arg name="stride1" type="int"/>
|
||||
<arg name="offset2" type="int"/>
|
||||
<arg name="stride2" type="int"/>
|
||||
</request>
|
||||
|
||||
</interface>
|
||||
|
||||
</protocol>
|
|
@ -1,2 +0,0 @@
|
|||
include $(top_srcdir)/manpages.am
|
||||
appman_PRE = Xwayland.man
|
|
@ -1,107 +0,0 @@
|
|||
'\" t
|
||||
.\"
|
||||
.\" Copyright 1984 - 1991, 1993, 1994, 1998 The Open Group
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, distribute, and sell this software and its
|
||||
.\" documentation for any purpose is hereby granted without fee, provided that
|
||||
.\" the above copyright notice appear in all copies and that both that
|
||||
.\" copyright notice and this permission notice appear in supporting
|
||||
.\" documentation.
|
||||
.\"
|
||||
.\" The above copyright notice and this permission notice shall be included
|
||||
.\" in all copies or substantial portions of the Software.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
.\" OTHER DEALINGS IN THE SOFTWARE.
|
||||
.\"
|
||||
.\" Except as contained in this notice, the name of The Open Group shall
|
||||
.\" not be used in advertising or otherwise to promote the sale, use or
|
||||
.\" other dealings in this Software without prior written authorization
|
||||
.\" from The Open Group.
|
||||
.\" shorthand for double quote that works everywhere.
|
||||
.ds q \N'34'
|
||||
.TH XWAYLAND 1 @xorgversion@
|
||||
.SH NAME
|
||||
Xwayland \- an X server for running X clients under Wayland.
|
||||
.SH SYNOPSIS
|
||||
.B Xwayland
|
||||
[option ...]
|
||||
.SH DESCRIPTION
|
||||
.I Xwayland
|
||||
is an X server and a Wayland client. It plays the role of a proxy between
|
||||
legacy X clients which do not support the Wayland protocols and the Wayland
|
||||
server.
|
||||
.PP
|
||||
Usually, \fIXwayland\fP is spawned automatically by the Wayland server
|
||||
and runs rootless so that X clients integrate seamlessly with the rest
|
||||
of the Wayland desktop. It is however possible for a user to launch Xwayland
|
||||
non-rootless, mainly for testing purposes.
|
||||
.PP
|
||||
Like all of the X servers, \fIXwayland\fP accepts the command line options
|
||||
described in the \fIXserver\fP(@miscmansuffix@) manual page.
|
||||
The following additional arguments are supported as well.
|
||||
.TP 8
|
||||
.B \-eglstream
|
||||
Use EGLStream backend for NVidia GPUs. If \fIXwayland\fP was compiled with
|
||||
EGLStream support, this option will instruct \fIXwayland\fP to try that
|
||||
backend first, then fallback to the GBM backend if EGLStream is not supported
|
||||
by the Wayland server. Without this option, \fIXwayland\fP tries the GBM
|
||||
backend first, and fallback to EGLStream if GBM is not usable.
|
||||
.TP 8
|
||||
.B \-initfd \fIfd\fP
|
||||
Add the given \fIfd\fP as a listen socket for initialization of X clients.
|
||||
This options is aimed at \fIWayland\fP servers which run \fIXwayland\fP
|
||||
on-demand, to be able to spawn specific X clients which need to complete
|
||||
before other regular X clients can connect to \fIXwayland\fP, like \fIxrdb\fP.
|
||||
.TP 8
|
||||
.B \-listen \fIfd\fP
|
||||
deprecated, use \fI\-listenfd\fP instead.
|
||||
.TP 8
|
||||
.B \-listenfd \fIfd\\fP
|
||||
Add given fd as a listen socket. This option is used by the \fIWayland\fP
|
||||
server to pass \fIXwayland\fP the socket where X clients connect.
|
||||
.TP 8
|
||||
.B \-noTouchPointerEmulation
|
||||
Disable touch pointer emulation. This allows the Wayland compositor to
|
||||
implement its own pointer emulation mechanism for X11 clients that don't
|
||||
support touch input.
|
||||
.TP 8
|
||||
.B \-rootless
|
||||
Run \fIXwayland\fP rootless, so that X clients integrate seamlessly with
|
||||
Wayland clients in a Wayland desktop. That requires the Wayland server
|
||||
to be an X window manager as well.
|
||||
.TP 8
|
||||
.BI \-shm
|
||||
Force the shared memory backend instead of glamor (if available) for passing
|
||||
buffers to the Wayland server.
|
||||
.TP 8
|
||||
.BR \-verbose " [\fIn\fP]"
|
||||
Sets the verbosity level for information printed on stderr. If the
|
||||
.I n
|
||||
value isn't supplied, each occurrence of this option increments the
|
||||
verbosity level. When the
|
||||
.I n
|
||||
value is supplied, the verbosity level is set to that value. The default
|
||||
verbosity level is 0.
|
||||
.TP 8
|
||||
.BI \-version
|
||||
Show the server version and exit.
|
||||
.TP 8
|
||||
.B \-wm \fIfd\fP
|
||||
This option is used by the \fIWayland\fP server to pass \fIXwayland\fP
|
||||
the socket where the X window manager client connects, when \fIXwayland\fP
|
||||
is running with \fI-rootless\fP.
|
||||
.SH ENVIRONMENT
|
||||
.TP 8
|
||||
.B WAYLAND_DISPLAY
|
||||
the name of the display of the Wayland server.
|
||||
.TP 8
|
||||
.B XWAYLAND_NO_GLAMOR
|
||||
disable glamor and DRI3 support in \fIXwayland\fP, for testing purposes.
|
||||
.SH "SEE ALSO"
|
||||
General information: \fIX\fP(@miscmansuffix@)
|
|
@ -1,160 +0,0 @@
|
|||
srcs = [
|
||||
'xwayland.c',
|
||||
'xwayland-input.c',
|
||||
'xwayland-input.h',
|
||||
'xwayland-cursor.c',
|
||||
'xwayland-cursor.h',
|
||||
'xwayland-glamor.h',
|
||||
'xwayland-glx.h',
|
||||
'xwayland-pixmap.c',
|
||||
'xwayland-pixmap.h',
|
||||
'xwayland-present.h',
|
||||
'xwayland-screen.c',
|
||||
'xwayland-screen.h',
|
||||
'xwayland-shm.c',
|
||||
'xwayland-shm.h',
|
||||
'xwayland-types.h',
|
||||
'xwayland-output.c',
|
||||
'xwayland-output.h',
|
||||
'xwayland-cvt.c',
|
||||
'xwayland-cvt.h',
|
||||
'xwayland-vidmode.c',
|
||||
'xwayland-vidmode.h',
|
||||
'xwayland-window.c',
|
||||
'xwayland-window.h',
|
||||
'xwayland-window-buffers.c',
|
||||
'xwayland-window-buffers.h',
|
||||
'../../mi/miinitext.c',
|
||||
'../../mi/miinitext.h',
|
||||
]
|
||||
|
||||
scanner_dep = dependency('wayland-scanner', native: true)
|
||||
scanner = find_program(scanner_dep.get_pkgconfig_variable('wayland_scanner'))
|
||||
|
||||
protocols_dep = dependency('wayland-protocols', version: wayland_protocols_req)
|
||||
protodir = protocols_dep.get_pkgconfig_variable('pkgdatadir')
|
||||
|
||||
pointer_xml = join_paths(protodir, 'unstable', 'pointer-constraints', 'pointer-constraints-unstable-v1.xml')
|
||||
relative_xml = join_paths(protodir, 'unstable', 'relative-pointer', 'relative-pointer-unstable-v1.xml')
|
||||
tablet_xml = join_paths(protodir, 'unstable', 'tablet', 'tablet-unstable-v2.xml')
|
||||
kbgrab_xml = join_paths(protodir, 'unstable', 'xwayland-keyboard-grab', 'xwayland-keyboard-grab-unstable-v1.xml')
|
||||
xdg_output_xml = join_paths(protodir, 'unstable', 'xdg-output', 'xdg-output-unstable-v1.xml')
|
||||
dmabuf_xml = join_paths(protodir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unstable-v1.xml')
|
||||
viewporter_xml = join_paths(protodir, 'stable', 'viewporter', 'viewporter.xml')
|
||||
xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
|
||||
|
||||
client_header = generator(scanner,
|
||||
output : '@BASENAME@-client-protocol.h',
|
||||
arguments : ['client-header', '@INPUT@', '@OUTPUT@']
|
||||
)
|
||||
|
||||
if scanner_dep.version().version_compare('>= 1.14.91')
|
||||
scanner_argument = 'private-code'
|
||||
else
|
||||
scanner_argument = 'code'
|
||||
endif
|
||||
|
||||
code = generator(scanner,
|
||||
output : '@BASENAME@-protocol.c',
|
||||
arguments : [scanner_argument, '@INPUT@', '@OUTPUT@']
|
||||
)
|
||||
srcs += client_header.process(relative_xml)
|
||||
srcs += client_header.process(pointer_xml)
|
||||
srcs += client_header.process(tablet_xml)
|
||||
srcs += client_header.process(kbgrab_xml)
|
||||
srcs += client_header.process(xdg_output_xml)
|
||||
srcs += client_header.process(dmabuf_xml)
|
||||
srcs += client_header.process(viewporter_xml)
|
||||
srcs += client_header.process(xdg_shell_xml)
|
||||
srcs += code.process(relative_xml)
|
||||
srcs += code.process(pointer_xml)
|
||||
srcs += code.process(tablet_xml)
|
||||
srcs += code.process(kbgrab_xml)
|
||||
srcs += code.process(xdg_output_xml)
|
||||
srcs += code.process(dmabuf_xml)
|
||||
srcs += code.process(viewporter_xml)
|
||||
srcs += code.process(xdg_shell_xml)
|
||||
|
||||
xwayland_glamor = []
|
||||
eglstream_srcs = []
|
||||
if build_glamor
|
||||
srcs += 'xwayland-glamor.c'
|
||||
if build_glx
|
||||
srcs += 'xwayland-glx.c'
|
||||
endif
|
||||
if gbm_dep.found()
|
||||
srcs += 'xwayland-glamor-gbm.c'
|
||||
endif
|
||||
if build_eglstream
|
||||
eglstream_protodir = eglstream_dep.get_pkgconfig_variable('pkgdatadir')
|
||||
eglstream_xml = join_paths(eglstream_protodir, 'wayland-eglstream.xml')
|
||||
eglstream_controller_xml = join_paths(eglstream_protodir, 'wayland-eglstream-controller.xml')
|
||||
|
||||
srcs += client_header.process(eglstream_xml)
|
||||
srcs += client_header.process(eglstream_controller_xml)
|
||||
srcs += code.process(eglstream_xml)
|
||||
srcs += code.process(eglstream_controller_xml)
|
||||
|
||||
srcs += 'xwayland-glamor-eglstream.c'
|
||||
endif
|
||||
srcs += 'xwayland-present.c'
|
||||
if build_xv
|
||||
srcs += 'xwayland-glamor-xv.c'
|
||||
endif
|
||||
|
||||
srcs += client_header.process('drm.xml')
|
||||
srcs += code.process('drm.xml')
|
||||
xwayland_dep += gbm_dep
|
||||
xwayland_glamor += glamor
|
||||
endif
|
||||
|
||||
wayland_inc = [ inc, ]
|
||||
if build_glx
|
||||
wayland_inc += glx_inc
|
||||
endif
|
||||
|
||||
xwayland_server = executable(
|
||||
'Xwayland',
|
||||
srcs,
|
||||
include_directories: wayland_inc,
|
||||
dependencies: [
|
||||
common_dep,
|
||||
xwayland_dep,
|
||||
],
|
||||
link_with: [
|
||||
libxserver_main,
|
||||
xwayland_glamor,
|
||||
libxserver_fb,
|
||||
libxserver,
|
||||
libxserver_xext_vidmode,
|
||||
libxserver_xkb_stubs,
|
||||
libxserver_xi_stubs,
|
||||
libxserver_glx,
|
||||
libglxvnd,
|
||||
],
|
||||
install: true,
|
||||
install_dir: xwayland_path
|
||||
)
|
||||
|
||||
xwayland_data = configuration_data()
|
||||
xwayland_data.set('prefix', get_option('prefix'))
|
||||
xwayland_data.set('exec_prefix', '${prefix}')
|
||||
xwayland_data.set('PACKAGE_VERSION', meson.project_version())
|
||||
xwayland_data.set('xwayland_path', xwayland_path)
|
||||
xwayland_data.set('have_glamor', build_glamor ? 'true' : 'false')
|
||||
xwayland_data.set('have_eglstream', build_eglstream ? 'true' : 'false')
|
||||
configure_file(
|
||||
input: 'xwayland.pc.in',
|
||||
output: 'xwayland.pc',
|
||||
configuration: xwayland_data,
|
||||
install_dir: join_paths(get_option('prefix'),
|
||||
get_option('libdir'),
|
||||
'pkgconfig'),
|
||||
)
|
||||
|
||||
xwayland_manpage = configure_file(
|
||||
input: 'man/Xwayland.man',
|
||||
output: 'Xwayland.1',
|
||||
configuration: manpage_config,
|
||||
)
|
||||
install_man(xwayland_manpage)
|
|
@ -1,428 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2014 Intel Corporation
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include "scrnintstr.h"
|
||||
#include "servermd.h"
|
||||
#include "cursorstr.h"
|
||||
#include "inputstr.h"
|
||||
#include "mipointer.h"
|
||||
|
||||
#include "xwayland-cursor.h"
|
||||
#include "xwayland-input.h"
|
||||
#include "xwayland-pixmap.h"
|
||||
#include "xwayland-screen.h"
|
||||
#include "xwayland-shm.h"
|
||||
#include "xwayland-types.h"
|
||||
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
|
||||
#define DELAYED_X_CURSOR_TIMEOUT 5 /* ms */
|
||||
|
||||
static DevPrivateKeyRec xwl_cursor_private_key;
|
||||
|
||||
static void
|
||||
expand_source_and_mask(CursorPtr cursor, CARD32 *data)
|
||||
{
|
||||
CARD32 *p, d, fg, bg;
|
||||
CursorBitsPtr bits = cursor->bits;
|
||||
int x, y, stride, i, bit;
|
||||
|
||||
p = data;
|
||||
fg = ((cursor->foreRed & 0xff00) << 8) |
|
||||
(cursor->foreGreen & 0xff00) | (cursor->foreGreen >> 8);
|
||||
bg = ((cursor->backRed & 0xff00) << 8) |
|
||||
(cursor->backGreen & 0xff00) | (cursor->backGreen >> 8);
|
||||
stride = BitmapBytePad(bits->width);
|
||||
for (y = 0; y < bits->height; y++)
|
||||
for (x = 0; x < bits->width; x++) {
|
||||
i = y * stride + x / 8;
|
||||
bit = 1 << (x & 7);
|
||||
if (bits->source[i] & bit)
|
||||
d = fg;
|
||||
else
|
||||
d = bg;
|
||||
if (bits->mask[i] & bit)
|
||||
d |= 0xff000000;
|
||||
else
|
||||
d = 0x00000000;
|
||||
|
||||
*p++ = d;
|
||||
}
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
|
||||
{
|
||||
PixmapPtr pixmap;
|
||||
|
||||
pixmap = xwl_shm_create_pixmap(screen, cursor->bits->width,
|
||||
cursor->bits->height, 32,
|
||||
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
|
||||
dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, pixmap);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
|
||||
{
|
||||
PixmapPtr pixmap;
|
||||
struct xwl_screen *xwl_screen;
|
||||
struct xwl_seat *xwl_seat;
|
||||
|
||||
pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
|
||||
if (!pixmap)
|
||||
return TRUE;
|
||||
|
||||
dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, NULL);
|
||||
|
||||
/* When called from FreeCursor(), device is always NULL */
|
||||
xwl_screen = xwl_screen_get(screen);
|
||||
xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
|
||||
if (cursor == xwl_seat->x_cursor)
|
||||
xwl_seat->x_cursor = NULL;
|
||||
}
|
||||
|
||||
return xwl_shm_destroy_pixmap(pixmap);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_cursor_frame_callback(struct xwl_cursor *xwl_cursor)
|
||||
{
|
||||
if (xwl_cursor->frame_cb) {
|
||||
wl_callback_destroy (xwl_cursor->frame_cb);
|
||||
xwl_cursor->frame_cb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
frame_callback(void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
struct xwl_cursor *xwl_cursor = data;
|
||||
|
||||
clear_cursor_frame_callback(xwl_cursor);
|
||||
if (xwl_cursor->needs_update) {
|
||||
xwl_cursor->needs_update = FALSE;
|
||||
xwl_cursor->update_proc(xwl_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener frame_listener = {
|
||||
frame_callback
|
||||
};
|
||||
|
||||
static void
|
||||
xwl_cursor_buffer_release_callback(void *data)
|
||||
{
|
||||
/* drop the reference we took in set_cursor */
|
||||
xwl_shm_destroy_pixmap(data);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_cursor_copy_bits_to_pixmap(CursorPtr cursor, PixmapPtr pixmap)
|
||||
{
|
||||
int stride;
|
||||
|
||||
stride = cursor->bits->width * 4;
|
||||
if (cursor->bits->argb)
|
||||
memcpy(pixmap->devPrivate.ptr,
|
||||
cursor->bits->argb, cursor->bits->height * stride);
|
||||
else
|
||||
expand_source_and_mask(cursor, pixmap->devPrivate.ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
|
||||
struct xwl_cursor *xwl_cursor, PixmapPtr pixmap)
|
||||
{
|
||||
struct wl_buffer *buffer;
|
||||
|
||||
buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
|
||||
if (!buffer) {
|
||||
ErrorF("cursor: Error getting buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_surface_attach(xwl_cursor->surface, buffer, 0, 0);
|
||||
xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0,
|
||||
xwl_seat->x_cursor->bits->width,
|
||||
xwl_seat->x_cursor->bits->height);
|
||||
|
||||
xwl_cursor->frame_cb = wl_surface_frame(xwl_cursor->surface);
|
||||
wl_callback_add_listener(xwl_cursor->frame_cb, &frame_listener, xwl_cursor);
|
||||
|
||||
/* Hold a reference on the pixmap until it's released by the compositor */
|
||||
pixmap->refcnt++;
|
||||
xwl_pixmap_set_buffer_release_cb(pixmap,
|
||||
xwl_cursor_buffer_release_callback,
|
||||
pixmap);
|
||||
|
||||
wl_surface_commit(xwl_cursor->surface);
|
||||
}
|
||||
|
||||
void
|
||||
xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
|
||||
{
|
||||
struct xwl_cursor *xwl_cursor = &xwl_seat->cursor;
|
||||
PixmapPtr pixmap;
|
||||
CursorPtr cursor;
|
||||
|
||||
if (!xwl_seat->wl_pointer)
|
||||
return;
|
||||
|
||||
if (!xwl_seat->x_cursor) {
|
||||
wl_pointer_set_cursor(xwl_seat->wl_pointer,
|
||||
xwl_seat->pointer_enter_serial, NULL, 0, 0);
|
||||
clear_cursor_frame_callback(xwl_cursor);
|
||||
xwl_cursor->needs_update = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (xwl_cursor->frame_cb) {
|
||||
xwl_cursor->needs_update = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
cursor = xwl_seat->x_cursor;
|
||||
pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
|
||||
if (!pixmap)
|
||||
return;
|
||||
|
||||
xwl_cursor_copy_bits_to_pixmap(cursor, pixmap);
|
||||
|
||||
wl_pointer_set_cursor(xwl_seat->wl_pointer,
|
||||
xwl_seat->pointer_enter_serial,
|
||||
xwl_cursor->surface,
|
||||
xwl_seat->x_cursor->bits->xhot,
|
||||
xwl_seat->x_cursor->bits->yhot);
|
||||
|
||||
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
|
||||
}
|
||||
|
||||
void
|
||||
xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
|
||||
struct xwl_cursor *xwl_cursor = &xwl_tablet_tool->cursor;
|
||||
PixmapPtr pixmap;
|
||||
CursorPtr cursor;
|
||||
|
||||
if (!xwl_seat->x_cursor) {
|
||||
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
|
||||
xwl_tablet_tool->proximity_in_serial,
|
||||
NULL, 0, 0);
|
||||
clear_cursor_frame_callback(xwl_cursor);
|
||||
xwl_cursor->needs_update = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (xwl_cursor->frame_cb) {
|
||||
xwl_cursor->needs_update = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
cursor = xwl_seat->x_cursor;
|
||||
pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
|
||||
if (!pixmap)
|
||||
return;
|
||||
|
||||
xwl_cursor_copy_bits_to_pixmap(cursor, pixmap);
|
||||
|
||||
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
|
||||
xwl_tablet_tool->proximity_in_serial,
|
||||
xwl_cursor->surface,
|
||||
xwl_seat->x_cursor->bits->xhot,
|
||||
xwl_seat->x_cursor->bits->yhot);
|
||||
|
||||
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_seat_update_cursor(struct xwl_seat *xwl_seat)
|
||||
{
|
||||
struct xwl_tablet_tool *xwl_tablet_tool;
|
||||
|
||||
xwl_seat_set_cursor(xwl_seat);
|
||||
|
||||
xorg_list_for_each_entry(xwl_tablet_tool, &xwl_seat->tablet_tools, link) {
|
||||
if (xwl_tablet_tool->proximity_in_serial != 0)
|
||||
xwl_tablet_tool_set_cursor(xwl_tablet_tool);
|
||||
}
|
||||
|
||||
/* Clear delayed cursor if any */
|
||||
xwl_seat->pending_x_cursor = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_seat_update_cursor_visibility(struct xwl_seat *xwl_seat)
|
||||
{
|
||||
xwl_seat->x_cursor = xwl_seat->pending_x_cursor;
|
||||
xwl_seat_cursor_visibility_changed(xwl_seat);
|
||||
xwl_seat_update_cursor(xwl_seat);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_set_cursor_free_timer(struct xwl_seat *xwl_seat)
|
||||
{
|
||||
if (xwl_seat->x_cursor_timer) {
|
||||
TimerFree(xwl_seat->x_cursor_timer);
|
||||
xwl_seat->x_cursor_timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static CARD32
|
||||
xwl_set_cursor_timer_callback(OsTimerPtr timer, CARD32 time, void *arg)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = arg;
|
||||
|
||||
xwl_set_cursor_free_timer(xwl_seat);
|
||||
xwl_seat_update_cursor_visibility(xwl_seat);
|
||||
|
||||
/* Don't re-arm the timer */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_set_cursor_delayed(struct xwl_seat *xwl_seat, CursorPtr cursor)
|
||||
{
|
||||
xwl_seat->pending_x_cursor = cursor;
|
||||
|
||||
if (xwl_seat->x_cursor_timer == NULL) {
|
||||
xwl_seat->x_cursor_timer = TimerSet(xwl_seat->x_cursor_timer,
|
||||
0, DELAYED_X_CURSOR_TIMEOUT,
|
||||
&xwl_set_cursor_timer_callback,
|
||||
xwl_seat);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_set_cursor(DeviceIntPtr device,
|
||||
ScreenPtr screen, CursorPtr cursor, int x, int y)
|
||||
{
|
||||
struct xwl_seat *xwl_seat;
|
||||
Bool cursor_visibility_changed;
|
||||
|
||||
xwl_seat = device->public.devicePrivate;
|
||||
if (xwl_seat == NULL)
|
||||
return;
|
||||
|
||||
cursor_visibility_changed = !!xwl_seat->x_cursor ^ !!cursor;
|
||||
|
||||
if (!cursor_visibility_changed) {
|
||||
/* Cursor remains shown or hidden, apply the change immediately */
|
||||
xwl_set_cursor_free_timer(xwl_seat);
|
||||
xwl_seat->x_cursor = cursor;
|
||||
xwl_seat_update_cursor(xwl_seat);
|
||||
return;
|
||||
}
|
||||
|
||||
xwl_seat->pending_x_cursor = cursor;
|
||||
if (cursor) {
|
||||
/* Cursor is being shown, delay the change until moved or timed out */
|
||||
xwl_set_cursor_delayed(xwl_seat, cursor);
|
||||
} else {
|
||||
/* Cursor is being hidden, apply the change immediately */
|
||||
xwl_seat_update_cursor_visibility(xwl_seat);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y)
|
||||
{
|
||||
struct xwl_seat *xwl_seat;
|
||||
|
||||
xwl_seat = device->public.devicePrivate;
|
||||
if (xwl_seat == NULL)
|
||||
return;
|
||||
|
||||
xwl_set_cursor_free_timer(xwl_seat);
|
||||
|
||||
if (xwl_seat->pending_x_cursor)
|
||||
xwl_seat_update_cursor_visibility(xwl_seat);
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr screen)
|
||||
{
|
||||
struct xwl_seat *xwl_seat;
|
||||
|
||||
xwl_seat = device->public.devicePrivate;
|
||||
if (xwl_seat)
|
||||
xwl_set_cursor_free_timer(xwl_seat);
|
||||
}
|
||||
|
||||
static miPointerSpriteFuncRec xwl_pointer_sprite_funcs = {
|
||||
xwl_realize_cursor,
|
||||
xwl_unrealize_cursor,
|
||||
xwl_set_cursor,
|
||||
xwl_move_cursor,
|
||||
xwl_device_cursor_initialize,
|
||||
xwl_device_cursor_cleanup
|
||||
};
|
||||
|
||||
static Bool
|
||||
xwl_cursor_off_screen(ScreenPtr *ppScreen, int *x, int *y)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_cross_screen(ScreenPtr pScreen, Bool entering)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_pointer_warp_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
|
||||
{
|
||||
miPointerWarpCursor(pDev, pScreen, x, y);
|
||||
}
|
||||
|
||||
static miPointerScreenFuncRec xwl_pointer_screen_funcs = {
|
||||
xwl_cursor_off_screen,
|
||||
xwl_cross_screen,
|
||||
xwl_pointer_warp_cursor
|
||||
};
|
||||
|
||||
Bool
|
||||
xwl_screen_init_cursor(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR_BITS, 0))
|
||||
return FALSE;
|
||||
|
||||
return miPointerInitialize(xwl_screen->screen,
|
||||
&xwl_pointer_sprite_funcs,
|
||||
&xwl_pointer_screen_funcs, TRUE);
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2014 Intel Corporation
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XWAYLAND_CURSOR_H
|
||||
#define XWAYLAND_CURSOR_H
|
||||
|
||||
#include <xwayland-config.h>
|
||||
#include <xwayland-types.h>
|
||||
#include <xwayland-input.h>
|
||||
|
||||
void xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *tool);
|
||||
void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
|
||||
Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);
|
||||
|
||||
#endif /* XWAYLAND_CURSOR_H */
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright 2005-2006 Luc Verhaegen.
|
||||
* Copyright © 2021 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <randrstr.h>
|
||||
#include <libxcvt/libxcvt.h>
|
||||
|
||||
#include "xwayland-cvt.h"
|
||||
|
||||
RRModePtr
|
||||
xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced,
|
||||
Bool interlaced)
|
||||
{
|
||||
struct libxcvt_mode_info *libxcvt_mode_info;
|
||||
char name[128];
|
||||
xRRModeInfo modeinfo;
|
||||
|
||||
libxcvt_mode_info =
|
||||
libxcvt_gen_mode_info(hdisplay, vdisplay, vrefresh, reduced, interlaced);
|
||||
|
||||
memset(&modeinfo, 0, sizeof modeinfo);
|
||||
modeinfo.width = libxcvt_mode_info->hdisplay;
|
||||
modeinfo.height = libxcvt_mode_info->vdisplay;
|
||||
modeinfo.dotClock = libxcvt_mode_info->dot_clock * 1000.0;
|
||||
modeinfo.hSyncStart = libxcvt_mode_info->hsync_start;
|
||||
modeinfo.hSyncEnd = libxcvt_mode_info->hsync_end;
|
||||
modeinfo.hTotal = libxcvt_mode_info->htotal;
|
||||
modeinfo.vSyncStart = libxcvt_mode_info->vsync_start;
|
||||
modeinfo.vSyncEnd = libxcvt_mode_info->vsync_end;
|
||||
modeinfo.vTotal = libxcvt_mode_info->vtotal;
|
||||
modeinfo.modeFlags = libxcvt_mode_info->mode_flags;
|
||||
|
||||
free(libxcvt_mode_info);
|
||||
|
||||
snprintf(name, sizeof name, "%dx%d",
|
||||
modeinfo.width, modeinfo.height);
|
||||
modeinfo.nameLength = strlen(name);
|
||||
|
||||
return RRModeGet(&modeinfo, name);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2005-2006 Luc Verhaegen.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XWAYLAND_CVT_H
|
||||
#define XWAYLAND_CVT_H
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include <dix.h>
|
||||
#include <randrstr.h>
|
||||
|
||||
RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
|
||||
float VRefresh, Bool Reduced, Bool Interlaced);
|
||||
|
||||
#endif /* XWAYLAND_CVT_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,974 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2011-2014 Intel Corporation
|
||||
* Copyright © 2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including
|
||||
* the next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Lyude Paul <lyude@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <xf86drm.h>
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
#define MESA_EGL_NO_X11_HEADERS
|
||||
#define EGL_NO_X11
|
||||
#include <gbm.h>
|
||||
#include <glamor_egl.h>
|
||||
|
||||
#include <glamor.h>
|
||||
#include <glamor_context.h>
|
||||
#include <dri3.h>
|
||||
#include "drm-client-protocol.h"
|
||||
|
||||
#include "xwayland-glamor.h"
|
||||
#include "xwayland-pixmap.h"
|
||||
#include "xwayland-screen.h"
|
||||
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
|
||||
struct xwl_gbm_private {
|
||||
char *device_name;
|
||||
struct gbm_device *gbm;
|
||||
struct wl_drm *drm;
|
||||
int drm_fd;
|
||||
int fd_render_node;
|
||||
Bool drm_authenticated;
|
||||
uint32_t capabilities;
|
||||
int dmabuf_capable;
|
||||
};
|
||||
|
||||
struct xwl_pixmap {
|
||||
struct wl_buffer *buffer;
|
||||
EGLImage image;
|
||||
unsigned int texture;
|
||||
struct gbm_bo *bo;
|
||||
};
|
||||
|
||||
static DevPrivateKeyRec xwl_gbm_private_key;
|
||||
static DevPrivateKeyRec xwl_auth_state_private_key;
|
||||
|
||||
static inline struct xwl_gbm_private *
|
||||
xwl_gbm_get(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
return dixLookupPrivate(&xwl_screen->screen->devPrivates,
|
||||
&xwl_gbm_private_key);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
gbm_format_for_depth(int depth)
|
||||
{
|
||||
switch (depth) {
|
||||
case 16:
|
||||
return GBM_FORMAT_RGB565;
|
||||
case 24:
|
||||
return GBM_FORMAT_XRGB8888;
|
||||
case 30:
|
||||
return GBM_FORMAT_ARGB2101010;
|
||||
default:
|
||||
ErrorF("unexpected depth: %d\n", depth);
|
||||
case 32:
|
||||
return GBM_FORMAT_ARGB8888;
|
||||
}
|
||||
}
|
||||
|
||||
static char
|
||||
is_device_path_render_node (const char *device_path)
|
||||
{
|
||||
char is_render_node;
|
||||
int fd;
|
||||
|
||||
fd = open(device_path, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
is_render_node = (drmGetNodeTypeFromFd(fd) == DRM_NODE_RENDER);
|
||||
close(fd);
|
||||
|
||||
return is_render_node;
|
||||
}
|
||||
|
||||
static PixmapPtr
|
||||
xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
|
||||
int depth)
|
||||
{
|
||||
PixmapPtr pixmap;
|
||||
struct xwl_pixmap *xwl_pixmap;
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
|
||||
xwl_pixmap = calloc(1, sizeof(*xwl_pixmap));
|
||||
if (xwl_pixmap == NULL)
|
||||
return NULL;
|
||||
|
||||
pixmap = glamor_create_pixmap(screen,
|
||||
gbm_bo_get_width(bo),
|
||||
gbm_bo_get_height(bo),
|
||||
depth,
|
||||
GLAMOR_CREATE_PIXMAP_NO_TEXTURE);
|
||||
if (!pixmap) {
|
||||
free(xwl_pixmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xwl_glamor_egl_make_current(xwl_screen);
|
||||
xwl_pixmap->bo = bo;
|
||||
xwl_pixmap->buffer = NULL;
|
||||
xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
|
||||
xwl_screen->egl_context,
|
||||
EGL_NATIVE_PIXMAP_KHR,
|
||||
xwl_pixmap->bo, NULL);
|
||||
if (xwl_pixmap->image == EGL_NO_IMAGE_KHR)
|
||||
goto error;
|
||||
|
||||
glGenTextures(1, &xwl_pixmap->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, xwl_pixmap->texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image);
|
||||
if (eglGetError() != EGL_SUCCESS)
|
||||
goto error;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (!glamor_set_pixmap_texture(pixmap, xwl_pixmap->texture))
|
||||
goto error;
|
||||
|
||||
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
|
||||
xwl_pixmap_set_private(pixmap, xwl_pixmap);
|
||||
|
||||
return pixmap;
|
||||
|
||||
error:
|
||||
if (xwl_pixmap->image != EGL_NO_IMAGE_KHR)
|
||||
eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
|
||||
if (pixmap)
|
||||
glamor_destroy_pixmap(pixmap);
|
||||
free(xwl_pixmap);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PixmapPtr
|
||||
xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
|
||||
int width, int height, int depth,
|
||||
unsigned int hint)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
struct gbm_bo *bo;
|
||||
PixmapPtr pixmap = NULL;
|
||||
|
||||
if (width > 0 && height > 0 && depth >= 15 &&
|
||||
(hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP ||
|
||||
hint == CREATE_PIXMAP_USAGE_SHARED ||
|
||||
(xwl_screen->rootless && hint == 0))) {
|
||||
uint32_t format = gbm_format_for_depth(depth);
|
||||
|
||||
#ifdef GBM_BO_WITH_MODIFIERS
|
||||
if (xwl_gbm->dmabuf_capable) {
|
||||
uint32_t num_modifiers;
|
||||
uint64_t *modifiers = NULL;
|
||||
|
||||
xwl_glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
|
||||
bo = gbm_bo_create_with_modifiers(xwl_gbm->gbm, width, height,
|
||||
format, modifiers, num_modifiers);
|
||||
free(modifiers);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
bo = gbm_bo_create(xwl_gbm->gbm, width, height, format,
|
||||
GBM_BO_USE_RENDERING);
|
||||
}
|
||||
|
||||
if (bo) {
|
||||
pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth);
|
||||
|
||||
if (!pixmap) {
|
||||
gbm_bo_destroy(bo);
|
||||
}
|
||||
else if (xwl_screen->rootless && hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP) {
|
||||
glamor_clear_pixmap(pixmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pixmap)
|
||||
pixmap = glamor_create_pixmap(screen, width, height, depth, hint);
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_gbm_destroy_pixmap(PixmapPtr pixmap)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
|
||||
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||
|
||||
if (xwl_pixmap && pixmap->refcnt == 1) {
|
||||
xwl_pixmap_del_buffer_release_cb(pixmap);
|
||||
if (xwl_pixmap->buffer)
|
||||
wl_buffer_destroy(xwl_pixmap->buffer);
|
||||
|
||||
eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
|
||||
if (xwl_pixmap->bo)
|
||||
gbm_bo_destroy(xwl_pixmap->bo);
|
||||
free(xwl_pixmap);
|
||||
}
|
||||
|
||||
return glamor_destroy_pixmap(pixmap);
|
||||
}
|
||||
|
||||
static const struct wl_buffer_listener xwl_glamor_gbm_buffer_listener = {
|
||||
xwl_pixmap_buffer_release_cb,
|
||||
};
|
||||
|
||||
static struct wl_buffer *
|
||||
xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
|
||||
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
unsigned short width = pixmap->drawable.width;
|
||||
unsigned short height = pixmap->drawable.height;
|
||||
uint32_t format;
|
||||
int prime_fd;
|
||||
int num_planes;
|
||||
uint32_t strides[4];
|
||||
uint32_t offsets[4];
|
||||
uint64_t modifier;
|
||||
int i;
|
||||
|
||||
if (xwl_pixmap == NULL)
|
||||
return NULL;
|
||||
|
||||
if (xwl_pixmap->buffer) {
|
||||
/* Buffer already exists. */
|
||||
return xwl_pixmap->buffer;
|
||||
}
|
||||
|
||||
if (!xwl_pixmap->bo)
|
||||
return NULL;
|
||||
|
||||
format = wl_drm_format_for_depth(pixmap->drawable.depth);
|
||||
|
||||
prime_fd = gbm_bo_get_fd(xwl_pixmap->bo);
|
||||
if (prime_fd == -1)
|
||||
return NULL;
|
||||
|
||||
#ifdef GBM_BO_WITH_MODIFIERS
|
||||
num_planes = gbm_bo_get_plane_count(xwl_pixmap->bo);
|
||||
modifier = gbm_bo_get_modifier(xwl_pixmap->bo);
|
||||
for (i = 0; i < num_planes; i++) {
|
||||
strides[i] = gbm_bo_get_stride_for_plane(xwl_pixmap->bo, i);
|
||||
offsets[i] = gbm_bo_get_offset(xwl_pixmap->bo, i);
|
||||
}
|
||||
#else
|
||||
num_planes = 1;
|
||||
modifier = DRM_FORMAT_MOD_INVALID;
|
||||
strides[0] = gbm_bo_get_stride(xwl_pixmap->bo);
|
||||
offsets[0] = 0;
|
||||
#endif
|
||||
|
||||
if (xwl_screen->dmabuf &&
|
||||
xwl_glamor_is_modifier_supported(xwl_screen, format, modifier)) {
|
||||
struct zwp_linux_buffer_params_v1 *params;
|
||||
|
||||
params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
|
||||
for (i = 0; i < num_planes; i++) {
|
||||
zwp_linux_buffer_params_v1_add(params, prime_fd, i,
|
||||
offsets[i], strides[i],
|
||||
modifier >> 32, modifier & 0xffffffff);
|
||||
}
|
||||
|
||||
xwl_pixmap->buffer =
|
||||
zwp_linux_buffer_params_v1_create_immed(params, width, height,
|
||||
format, 0);
|
||||
zwp_linux_buffer_params_v1_destroy(params);
|
||||
} else if (num_planes == 1) {
|
||||
xwl_pixmap->buffer =
|
||||
wl_drm_create_prime_buffer(xwl_gbm->drm, prime_fd, width, height,
|
||||
format,
|
||||
0, gbm_bo_get_stride(xwl_pixmap->bo),
|
||||
0, 0,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
close(prime_fd);
|
||||
|
||||
/* Add our listener now */
|
||||
wl_buffer_add_listener(xwl_pixmap->buffer,
|
||||
&xwl_glamor_gbm_buffer_listener, pixmap);
|
||||
|
||||
return xwl_pixmap->buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_glamor_gbm_cleanup(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
|
||||
if (xwl_gbm->device_name)
|
||||
free(xwl_gbm->device_name);
|
||||
if (xwl_gbm->drm_fd)
|
||||
close(xwl_gbm->drm_fd);
|
||||
if (xwl_gbm->drm)
|
||||
wl_drm_destroy(xwl_gbm->drm);
|
||||
if (xwl_gbm->gbm)
|
||||
gbm_device_destroy(xwl_gbm->gbm);
|
||||
|
||||
free(xwl_gbm);
|
||||
}
|
||||
|
||||
struct xwl_auth_state {
|
||||
int fd;
|
||||
ClientPtr client;
|
||||
struct wl_callback *callback;
|
||||
};
|
||||
|
||||
static void
|
||||
free_xwl_auth_state(ClientPtr pClient, struct xwl_auth_state *state)
|
||||
{
|
||||
dixSetPrivate(&pClient->devPrivates, &xwl_auth_state_private_key, NULL);
|
||||
if (state) {
|
||||
wl_callback_destroy(state->callback);
|
||||
free(state);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_auth_state_client_callback(CallbackListPtr *pcbl, void *unused, void *data)
|
||||
{
|
||||
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
|
||||
ClientPtr pClient = clientinfo->client;
|
||||
struct xwl_auth_state *state;
|
||||
|
||||
switch (pClient->clientState) {
|
||||
case ClientStateGone:
|
||||
case ClientStateRetained:
|
||||
state = dixLookupPrivate(&pClient->devPrivates,
|
||||
&xwl_auth_state_private_key);
|
||||
free_xwl_auth_state(pClient, state);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
|
||||
{
|
||||
struct xwl_auth_state *state = data;
|
||||
ClientPtr client = state->client;
|
||||
|
||||
/* if the client is gone, the callback is cancelled so it's safe to
|
||||
* assume the client is still in ClientStateRunning at this point...
|
||||
*/
|
||||
dri3_send_open_reply(client, state->fd);
|
||||
AttendClient(client);
|
||||
free_xwl_auth_state(client, state);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener sync_listener = {
|
||||
sync_callback
|
||||
};
|
||||
|
||||
static int
|
||||
xwl_dri3_open_client(ClientPtr client,
|
||||
ScreenPtr screen,
|
||||
RRProviderPtr provider,
|
||||
int *pfd)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
struct xwl_auth_state *state;
|
||||
drm_magic_t magic;
|
||||
int fd;
|
||||
|
||||
fd = open(xwl_gbm->device_name, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return BadAlloc;
|
||||
if (xwl_gbm->fd_render_node) {
|
||||
*pfd = fd;
|
||||
return Success;
|
||||
}
|
||||
|
||||
state = malloc(sizeof *state);
|
||||
if (state == NULL) {
|
||||
close(fd);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
state->client = client;
|
||||
state->fd = fd;
|
||||
|
||||
if (drmGetMagic(state->fd, &magic) < 0) {
|
||||
close(state->fd);
|
||||
free(state);
|
||||
return BadMatch;
|
||||
}
|
||||
|
||||
wl_drm_authenticate(xwl_gbm->drm, magic);
|
||||
state->callback = wl_display_sync(xwl_screen->display);
|
||||
wl_callback_add_listener(state->callback, &sync_listener, state);
|
||||
dixSetPrivate(&client->devPrivates, &xwl_auth_state_private_key, state);
|
||||
|
||||
IgnoreClient(client);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
_X_EXPORT PixmapPtr
|
||||
glamor_pixmap_from_fds(ScreenPtr screen, CARD8 num_fds, const int *fds,
|
||||
CARD16 width, CARD16 height,
|
||||
const CARD32 *strides, const CARD32 *offsets,
|
||||
CARD8 depth, CARD8 bpp, uint64_t modifier)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
struct gbm_bo *bo = NULL;
|
||||
PixmapPtr pixmap;
|
||||
int i;
|
||||
|
||||
if (width == 0 || height == 0 || num_fds == 0 ||
|
||||
depth < 15 || bpp != BitsPerPixel(depth) ||
|
||||
strides[0] < width * bpp / 8)
|
||||
goto error;
|
||||
|
||||
if (xwl_gbm->dmabuf_capable && modifier != DRM_FORMAT_MOD_INVALID) {
|
||||
#ifdef GBM_BO_WITH_MODIFIERS
|
||||
struct gbm_import_fd_modifier_data data;
|
||||
|
||||
data.width = width;
|
||||
data.height = height;
|
||||
data.num_fds = num_fds;
|
||||
data.format = gbm_format_for_depth(depth);
|
||||
data.modifier = modifier;
|
||||
for (i = 0; i < num_fds; i++) {
|
||||
data.fds[i] = fds[i];
|
||||
data.strides[i] = strides[i];
|
||||
data.offsets[i] = offsets[i];
|
||||
}
|
||||
bo = gbm_bo_import(xwl_gbm->gbm, GBM_BO_IMPORT_FD_MODIFIER, &data,
|
||||
GBM_BO_USE_RENDERING);
|
||||
#endif
|
||||
} else if (num_fds == 1) {
|
||||
struct gbm_import_fd_data data;
|
||||
|
||||
data.fd = fds[0];
|
||||
data.width = width;
|
||||
data.height = height;
|
||||
data.stride = strides[0];
|
||||
data.format = gbm_format_for_depth(depth);
|
||||
bo = gbm_bo_import(xwl_gbm->gbm, GBM_BO_IMPORT_FD, &data,
|
||||
GBM_BO_USE_RENDERING);
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (bo == NULL)
|
||||
goto error;
|
||||
|
||||
pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth);
|
||||
if (pixmap == NULL) {
|
||||
gbm_bo_destroy(bo);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return pixmap;
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_X_EXPORT int
|
||||
glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
|
||||
uint32_t *strides, uint32_t *offsets,
|
||||
uint64_t *modifier)
|
||||
{
|
||||
struct xwl_pixmap *xwl_pixmap;
|
||||
#ifdef GBM_BO_WITH_MODIFIERS
|
||||
uint32_t num_fds;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||
|
||||
if (xwl_pixmap == NULL)
|
||||
return 0;
|
||||
|
||||
if (!xwl_pixmap->bo)
|
||||
return 0;
|
||||
|
||||
#ifdef GBM_BO_WITH_MODIFIERS
|
||||
num_fds = gbm_bo_get_plane_count(xwl_pixmap->bo);
|
||||
*modifier = gbm_bo_get_modifier(xwl_pixmap->bo);
|
||||
|
||||
for (i = 0; i < num_fds; i++) {
|
||||
fds[i] = gbm_bo_get_fd(xwl_pixmap->bo);
|
||||
strides[i] = gbm_bo_get_stride_for_plane(xwl_pixmap->bo, i);
|
||||
offsets[i] = gbm_bo_get_offset(xwl_pixmap->bo, i);
|
||||
}
|
||||
|
||||
return num_fds;
|
||||
#else
|
||||
*modifier = DRM_FORMAT_MOD_INVALID;
|
||||
fds[0] = gbm_bo_get_fd(xwl_pixmap->bo);
|
||||
strides[0] = gbm_bo_get_stride(xwl_pixmap->bo);
|
||||
offsets[0] = 0;
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Not actually used, just defined here so there's something for
|
||||
* _glamor_egl_fds_from_pixmap() to link against
|
||||
*/
|
||||
_X_EXPORT int
|
||||
glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
|
||||
CARD16 *stride, CARD32 *size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const dri3_screen_info_rec xwl_dri3_info = {
|
||||
.version = 2,
|
||||
.open = NULL,
|
||||
.pixmap_from_fds = glamor_pixmap_from_fds,
|
||||
.fds_from_pixmap = glamor_fds_from_pixmap,
|
||||
.open_client = xwl_dri3_open_client,
|
||||
.get_formats = xwl_glamor_get_formats,
|
||||
.get_modifiers = xwl_glamor_get_modifiers,
|
||||
.get_drawable_modifiers = glamor_get_drawable_modifiers,
|
||||
};
|
||||
|
||||
static const char *
|
||||
get_render_node_path_for_device(const drmDevicePtr drm_device,
|
||||
const char *device_path)
|
||||
{
|
||||
char *render_node_path = NULL;
|
||||
char device_found = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DRM_NODE_MAX; i++) {
|
||||
if ((drm_device->available_nodes & (1 << i)) == 0)
|
||||
continue;
|
||||
|
||||
if (!strcmp (device_path, drm_device->nodes[i]))
|
||||
device_found = 1;
|
||||
|
||||
if (is_device_path_render_node(drm_device->nodes[i]))
|
||||
render_node_path = drm_device->nodes[i];
|
||||
|
||||
if (device_found && render_node_path)
|
||||
return render_node_path;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_render_node_path(const char *device_path)
|
||||
{
|
||||
drmDevicePtr *devices = NULL;
|
||||
char *render_node_path = NULL;
|
||||
int i, n_devices, max_devices;
|
||||
|
||||
max_devices = drmGetDevices2(0, NULL, 0);
|
||||
if (max_devices <= 0)
|
||||
goto out;
|
||||
|
||||
devices = calloc(max_devices, sizeof(drmDevicePtr));
|
||||
if (!devices)
|
||||
goto out;
|
||||
|
||||
n_devices = drmGetDevices2(0, devices, max_devices);
|
||||
if (n_devices < 0)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < n_devices; i++) {
|
||||
const char *node_path = get_render_node_path_for_device(devices[i],
|
||||
device_path);
|
||||
if (node_path) {
|
||||
render_node_path = strdup(node_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
free(devices);
|
||||
return render_node_path;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = data;
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
drm_magic_t magic;
|
||||
char *render_node_path = NULL;
|
||||
|
||||
if (!is_device_path_render_node(device))
|
||||
render_node_path = get_render_node_path(device);
|
||||
|
||||
if (render_node_path)
|
||||
xwl_gbm->device_name = render_node_path;
|
||||
else
|
||||
xwl_gbm->device_name = strdup(device);
|
||||
|
||||
if (!xwl_gbm->device_name) {
|
||||
xwl_glamor_gbm_cleanup(xwl_screen);
|
||||
return;
|
||||
}
|
||||
|
||||
xwl_gbm->drm_fd = open(xwl_gbm->device_name, O_RDWR | O_CLOEXEC);
|
||||
if (xwl_gbm->drm_fd == -1) {
|
||||
ErrorF("wayland-egl: could not open %s (%s)\n",
|
||||
xwl_gbm->device_name, strerror(errno));
|
||||
xwl_glamor_gbm_cleanup(xwl_screen);
|
||||
return;
|
||||
}
|
||||
|
||||
if (drmGetNodeTypeFromFd(xwl_gbm->drm_fd) == DRM_NODE_RENDER) {
|
||||
xwl_gbm->fd_render_node = 1;
|
||||
xwl_screen->expecting_event--;
|
||||
} else {
|
||||
drmGetMagic(xwl_gbm->drm_fd, &magic);
|
||||
wl_drm_authenticate(xwl_gbm->drm, magic);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_drm_handle_authenticated(void *data, struct wl_drm *drm)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = data;
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
|
||||
xwl_gbm->drm_authenticated = TRUE;
|
||||
xwl_screen->expecting_event--;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value)
|
||||
{
|
||||
xwl_gbm_get(data)->capabilities = value;
|
||||
}
|
||||
|
||||
static const struct wl_drm_listener xwl_drm_listener = {
|
||||
xwl_drm_handle_device,
|
||||
xwl_drm_handle_format,
|
||||
xwl_drm_handle_authenticated,
|
||||
xwl_drm_handle_capabilities
|
||||
};
|
||||
|
||||
Bool
|
||||
xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
|
||||
uint32_t id, uint32_t version)
|
||||
{
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
|
||||
if (version < 2)
|
||||
return FALSE;
|
||||
|
||||
xwl_gbm->drm =
|
||||
wl_registry_bind(xwl_screen->registry, id, &wl_drm_interface, 2);
|
||||
wl_drm_add_listener(xwl_gbm->drm, &xwl_drm_listener, xwl_screen);
|
||||
xwl_screen->expecting_event++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t id, const char *name,
|
||||
uint32_t version)
|
||||
{
|
||||
if (strcmp(name, "wl_drm") == 0) {
|
||||
xwl_screen_set_drm_interface(xwl_screen, id, version);
|
||||
return TRUE;
|
||||
} else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) {
|
||||
xwl_screen_set_dmabuf_interface(xwl_screen, id, version);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* no match */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_gbm_has_egl_extension(void)
|
||||
{
|
||||
return (epoxy_has_egl_extension(NULL, "EGL_MESA_platform_gbm") ||
|
||||
epoxy_has_egl_extension(NULL, "EGL_KHR_platform_gbm"));
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_gbm_has_wl_interfaces(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
|
||||
if (xwl_gbm->drm == NULL) {
|
||||
ErrorF("glamor: 'wl_drm' not supported\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_try_to_make_context_current(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
if (xwl_screen->egl_context == EGL_NO_CONTEXT)
|
||||
return FALSE;
|
||||
|
||||
return eglMakeCurrent(xwl_screen->egl_display, EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE, xwl_screen->egl_context);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_glamor_maybe_destroy_context(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
if (xwl_screen->egl_context == EGL_NO_CONTEXT)
|
||||
return;
|
||||
|
||||
eglMakeCurrent(xwl_screen->egl_display, EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglDestroyContext(xwl_screen->egl_display, xwl_screen->egl_context);
|
||||
xwl_screen->egl_context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_try_big_gl_api(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
static const EGLint config_attribs_core[] = {
|
||||
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
|
||||
EGL_CONTEXT_MAJOR_VERSION_KHR,
|
||||
GLAMOR_GL_CORE_VER_MAJOR,
|
||||
EGL_CONTEXT_MINOR_VERSION_KHR,
|
||||
GLAMOR_GL_CORE_VER_MINOR,
|
||||
EGL_NONE
|
||||
};
|
||||
int gl_version;
|
||||
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
|
||||
xwl_screen->egl_context =
|
||||
eglCreateContext(xwl_screen->egl_display, NULL,
|
||||
EGL_NO_CONTEXT, config_attribs_core);
|
||||
|
||||
if (xwl_screen->egl_context == EGL_NO_CONTEXT)
|
||||
xwl_screen->egl_context =
|
||||
eglCreateContext(xwl_screen->egl_display, NULL,
|
||||
EGL_NO_CONTEXT, NULL);
|
||||
|
||||
if (!xwl_glamor_try_to_make_context_current(xwl_screen)) {
|
||||
ErrorF("Failed to make EGL context current with GL\n");
|
||||
xwl_glamor_maybe_destroy_context(xwl_screen);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* glamor needs at least GL 2.1, if the GL version is less than 2.1,
|
||||
* drop the context we created, it's useless.
|
||||
*/
|
||||
gl_version = epoxy_gl_version();
|
||||
if (gl_version < 21) {
|
||||
ErrorF("Supported GL version is not sufficient (required 21, found %i)\n",
|
||||
gl_version);
|
||||
xwl_glamor_maybe_destroy_context(xwl_screen);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_try_gles_api(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
const EGLint gles_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION,
|
||||
2,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display, NULL,
|
||||
EGL_NO_CONTEXT, gles_attribs);
|
||||
|
||||
if (!xwl_glamor_try_to_make_context_current(xwl_screen)) {
|
||||
ErrorF("Failed to make EGL context current with GLES2\n");
|
||||
xwl_glamor_maybe_destroy_context(xwl_screen);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
EGLint major, minor;
|
||||
const GLubyte *renderer;
|
||||
|
||||
if (!xwl_gbm->fd_render_node && !xwl_gbm->drm_authenticated) {
|
||||
ErrorF("Failed to get wl_drm, disabling Glamor and DRI3\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xwl_gbm->gbm = gbm_create_device(xwl_gbm->drm_fd);
|
||||
if (!xwl_gbm->gbm) {
|
||||
ErrorF("couldn't create gbm device\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
xwl_screen->egl_display = glamor_egl_get_display(EGL_PLATFORM_GBM_MESA,
|
||||
xwl_gbm->gbm);
|
||||
if (xwl_screen->egl_display == EGL_NO_DISPLAY) {
|
||||
ErrorF("glamor_egl_get_display() failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!eglInitialize(xwl_screen->egl_display, &major, &minor)) {
|
||||
ErrorF("eglInitialize() failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!xwl_glamor_try_big_gl_api(xwl_screen) &&
|
||||
!xwl_glamor_try_gles_api(xwl_screen)) {
|
||||
ErrorF("Cannot use neither GL nor GLES2\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
renderer = glGetString(GL_RENDERER);
|
||||
if (!renderer) {
|
||||
ErrorF("glGetString() returned NULL, your GL is broken\n");
|
||||
goto error;
|
||||
}
|
||||
if (strstr((const char *)renderer, "llvmpipe")) {
|
||||
ErrorF("Refusing to try glamor on llvmpipe\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!epoxy_has_gl_extension("GL_OES_EGL_image")) {
|
||||
ErrorF("GL_OES_EGL_image not available\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (epoxy_has_egl_extension(xwl_screen->egl_display,
|
||||
"EXT_image_dma_buf_import") &&
|
||||
epoxy_has_egl_extension(xwl_screen->egl_display,
|
||||
"EXT_image_dma_buf_import_modifiers"))
|
||||
xwl_gbm->dmabuf_capable = TRUE;
|
||||
|
||||
return TRUE;
|
||||
error:
|
||||
if (xwl_screen->egl_display != EGL_NO_DISPLAY) {
|
||||
xwl_glamor_maybe_destroy_context(xwl_screen);
|
||||
eglTerminate(xwl_screen->egl_display);
|
||||
xwl_screen->egl_display = EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
xwl_glamor_gbm_cleanup(xwl_screen);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||
|
||||
if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
|
||||
ErrorF("Failed to initialize dri3\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (xwl_gbm->fd_render_node)
|
||||
goto skip_drm_auth;
|
||||
|
||||
if (!dixRegisterPrivateKey(&xwl_auth_state_private_key, PRIVATE_CLIENT,
|
||||
0)) {
|
||||
ErrorF("Failed to register private key\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!AddCallback(&ClientStateCallback, xwl_auth_state_client_callback,
|
||||
NULL)) {
|
||||
ErrorF("Failed to add client state callback\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
skip_drm_auth:
|
||||
xwl_screen->screen->CreatePixmap = xwl_glamor_gbm_create_pixmap;
|
||||
xwl_screen->screen->DestroyPixmap = xwl_glamor_gbm_destroy_pixmap;
|
||||
|
||||
return TRUE;
|
||||
error:
|
||||
xwl_glamor_gbm_cleanup(xwl_screen);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
struct xwl_gbm_private *xwl_gbm;
|
||||
|
||||
xwl_screen->gbm_backend.is_available = FALSE;
|
||||
|
||||
if (!xwl_glamor_gbm_has_egl_extension())
|
||||
return;
|
||||
|
||||
if (!dixRegisterPrivateKey(&xwl_gbm_private_key, PRIVATE_SCREEN, 0))
|
||||
return;
|
||||
|
||||
xwl_gbm = calloc(sizeof(*xwl_gbm), 1);
|
||||
if (!xwl_gbm) {
|
||||
ErrorF("glamor: Not enough memory to setup GBM, disabling\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key,
|
||||
xwl_gbm);
|
||||
|
||||
xwl_screen->gbm_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry;
|
||||
xwl_screen->gbm_backend.has_wl_interfaces = xwl_glamor_gbm_has_wl_interfaces;
|
||||
xwl_screen->gbm_backend.init_egl = xwl_glamor_gbm_init_egl;
|
||||
xwl_screen->gbm_backend.init_screen = xwl_glamor_gbm_init_screen;
|
||||
xwl_screen->gbm_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap;
|
||||
xwl_screen->gbm_backend.check_flip = NULL;
|
||||
xwl_screen->gbm_backend.is_available = TRUE;
|
||||
xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
|
||||
XWL_EGL_BACKEND_NEEDS_N_BUFFERING;
|
||||
}
|
|
@ -1,415 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2003 by The XFree86 Project, Inc.
|
||||
* Copyright © 2013 Red Hat
|
||||
* Copyright © 2014 Intel Corporation
|
||||
* Copyright © 2016 Red Hat
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Olivier Fourdan <ofourdan@redhat.com>
|
||||
*
|
||||
* Derived from the glamor_xf86_xv, ephyr_glamor_xv and xf86xv
|
||||
* implementations
|
||||
*/
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
#include <X11/extensions/Xv.h>
|
||||
|
||||
#include "xwayland-glamor.h"
|
||||
|
||||
#define NUM_FORMATS 3
|
||||
#define NUM_PORTS 16
|
||||
#define ADAPTOR_NAME "glamor textured video"
|
||||
#define ENCODER_NAME "XV_IMAGE"
|
||||
|
||||
static DevPrivateKeyRec xwlXvScreenPrivateKeyRec;
|
||||
#define xwlXvScreenPrivateKey (&xwlXvScreenPrivateKeyRec)
|
||||
|
||||
typedef struct {
|
||||
XvAdaptorPtr glxv_adaptor; /* We have only one adaptor, glamor Xv */
|
||||
glamor_port_private *port_privates;
|
||||
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
} xwlXvScreenRec, *xwlXvScreenPtr;
|
||||
|
||||
typedef struct {
|
||||
char depth;
|
||||
short class;
|
||||
} xwlVideoFormatRec, *xwlVideoFormatPtr;
|
||||
|
||||
static xwlVideoFormatRec Formats[NUM_FORMATS] = {
|
||||
{15, TrueColor},
|
||||
{16, TrueColor},
|
||||
{24, TrueColor}
|
||||
};
|
||||
|
||||
static int
|
||||
xwl_glamor_xv_stop_video(XvPortPtr pPort,
|
||||
DrawablePtr pDraw)
|
||||
{
|
||||
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
|
||||
|
||||
if (pDraw->type != DRAWABLE_WINDOW)
|
||||
return BadAlloc;
|
||||
|
||||
glamor_xv_stop_video(gpp);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_glamor_xv_set_port_attribute(XvPortPtr pPort,
|
||||
Atom attribute,
|
||||
INT32 value)
|
||||
{
|
||||
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
|
||||
|
||||
return glamor_xv_set_port_attribute(gpp, attribute, value);
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_glamor_xv_get_port_attribute(XvPortPtr pPort,
|
||||
Atom attribute,
|
||||
INT32 *pValue)
|
||||
{
|
||||
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
|
||||
|
||||
return glamor_xv_get_port_attribute(gpp, attribute, pValue);
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_glamor_xv_query_best_size(XvPortPtr pPort,
|
||||
CARD8 motion,
|
||||
CARD16 vid_w,
|
||||
CARD16 vid_h,
|
||||
CARD16 drw_w,
|
||||
CARD16 drw_h,
|
||||
unsigned int *p_w,
|
||||
unsigned int *p_h)
|
||||
{
|
||||
*p_w = drw_w;
|
||||
*p_h = drw_h;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_glamor_xv_query_image_attributes(XvPortPtr pPort,
|
||||
XvImagePtr format,
|
||||
CARD16 *width,
|
||||
CARD16 *height,
|
||||
int *pitches,
|
||||
int *offsets)
|
||||
{
|
||||
return glamor_xv_query_image_attributes(format->id,
|
||||
width,
|
||||
height,
|
||||
pitches,
|
||||
offsets);
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_glamor_xv_put_image(DrawablePtr pDrawable,
|
||||
XvPortPtr pPort,
|
||||
GCPtr pGC,
|
||||
INT16 src_x,
|
||||
INT16 src_y,
|
||||
CARD16 src_w,
|
||||
CARD16 src_h,
|
||||
INT16 drw_x,
|
||||
INT16 drw_y,
|
||||
CARD16 drw_w,
|
||||
CARD16 drw_h,
|
||||
XvImagePtr format,
|
||||
unsigned char *data,
|
||||
Bool sync,
|
||||
CARD16 width,
|
||||
CARD16 height)
|
||||
{
|
||||
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
|
||||
|
||||
RegionRec WinRegion;
|
||||
RegionRec ClipRegion;
|
||||
BoxRec WinBox;
|
||||
int ret = Success;
|
||||
|
||||
if (pDrawable->type != DRAWABLE_WINDOW)
|
||||
return BadWindow;
|
||||
|
||||
WinBox.x1 = pDrawable->x + drw_x;
|
||||
WinBox.y1 = pDrawable->y + drw_y;
|
||||
WinBox.x2 = WinBox.x1 + drw_w;
|
||||
WinBox.y2 = WinBox.y1 + drw_h;
|
||||
|
||||
RegionInit(&WinRegion, &WinBox, 1);
|
||||
RegionInit(&ClipRegion, NullBox, 1);
|
||||
RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
|
||||
|
||||
if (RegionNotEmpty(&ClipRegion))
|
||||
ret = glamor_xv_put_image(gpp,
|
||||
pDrawable,
|
||||
src_x,
|
||||
src_y,
|
||||
pDrawable->x + drw_x,
|
||||
pDrawable->y + drw_y,
|
||||
src_w,
|
||||
src_h,
|
||||
drw_w,
|
||||
drw_h,
|
||||
format->id,
|
||||
data,
|
||||
width,
|
||||
height,
|
||||
sync,
|
||||
&ClipRegion);
|
||||
|
||||
RegionUninit(&WinRegion);
|
||||
RegionUninit(&ClipRegion);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_xv_add_formats(XvAdaptorPtr pa)
|
||||
{
|
||||
ScreenPtr pScreen;
|
||||
XvFormatPtr pFormat, pf;
|
||||
VisualPtr pVisual;
|
||||
int numFormat;
|
||||
int totFormat;
|
||||
int numVisuals;
|
||||
int i;
|
||||
|
||||
totFormat = NUM_FORMATS;
|
||||
pFormat = xnfcalloc(totFormat, sizeof(XvFormatRec));
|
||||
pScreen = pa->pScreen;
|
||||
for (pf = pFormat, i = 0, numFormat = 0; i < NUM_FORMATS; i++) {
|
||||
numVisuals = pScreen->numVisuals;
|
||||
pVisual = pScreen->visuals;
|
||||
|
||||
while (numVisuals--) {
|
||||
if ((pVisual->class == Formats[i].class) &&
|
||||
(pVisual->nplanes == Formats[i].depth)) {
|
||||
if (numFormat >= totFormat) {
|
||||
void *moreSpace;
|
||||
|
||||
totFormat *= 2;
|
||||
moreSpace = xnfreallocarray(pFormat, totFormat,
|
||||
sizeof(XvFormatRec));
|
||||
pFormat = moreSpace;
|
||||
pf = pFormat + numFormat;
|
||||
}
|
||||
|
||||
pf->visual = pVisual->vid;
|
||||
pf->depth = Formats[i].depth;
|
||||
|
||||
pf++;
|
||||
numFormat++;
|
||||
}
|
||||
pVisual++;
|
||||
}
|
||||
}
|
||||
pa->nFormats = numFormat;
|
||||
pa->pFormats = pFormat;
|
||||
|
||||
return numFormat != 0;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_xv_add_ports(XvAdaptorPtr pa)
|
||||
{
|
||||
XvPortPtr pPorts, pp;
|
||||
xwlXvScreenPtr xwlXvScreen;
|
||||
unsigned long PortResource = 0;
|
||||
int nPorts;
|
||||
int i;
|
||||
|
||||
pPorts = xnfcalloc(NUM_PORTS, sizeof(XvPortRec));
|
||||
xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates,
|
||||
xwlXvScreenPrivateKey);
|
||||
xwlXvScreen->port_privates = xnfcalloc(NUM_PORTS,
|
||||
sizeof(glamor_port_private));
|
||||
|
||||
PortResource = XvGetRTPort();
|
||||
for (pp = pPorts, i = 0, nPorts = 0; i < NUM_PORTS; i++) {
|
||||
if (!(pp->id = FakeClientID(0)))
|
||||
continue;
|
||||
|
||||
pp->pAdaptor = pa;
|
||||
|
||||
glamor_xv_init_port(&xwlXvScreen->port_privates[i]);
|
||||
pp->devPriv.ptr = &xwlXvScreen->port_privates[i];
|
||||
|
||||
if (AddResource(pp->id, PortResource, pp)) {
|
||||
pp++;
|
||||
nPorts++;
|
||||
}
|
||||
}
|
||||
|
||||
pa->base_id = pPorts->id;
|
||||
pa->nPorts = nPorts;
|
||||
pa->pPorts = pPorts;
|
||||
|
||||
return nPorts != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_glamor_xv_add_attributes(XvAdaptorPtr pa)
|
||||
{
|
||||
int i;
|
||||
|
||||
pa->pAttributes = xnfcalloc(glamor_xv_num_attributes, sizeof(XvAttributeRec));
|
||||
memcpy(pa->pAttributes, glamor_xv_attributes,
|
||||
glamor_xv_num_attributes * sizeof(XvAttributeRec));
|
||||
|
||||
for (i = 0; i < glamor_xv_num_attributes; i++)
|
||||
pa->pAttributes[i].name = strdup(glamor_xv_attributes[i].name);
|
||||
|
||||
pa->nAttributes = glamor_xv_num_attributes;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_glamor_xv_add_images(XvAdaptorPtr pa)
|
||||
{
|
||||
pa->pImages = xnfcalloc(glamor_xv_num_images, sizeof(XvImageRec));
|
||||
memcpy(pa->pImages, glamor_xv_images, glamor_xv_num_images * sizeof(XvImageRec));
|
||||
|
||||
pa->nImages = glamor_xv_num_images;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_glamor_xv_add_encodings(XvAdaptorPtr pa)
|
||||
{
|
||||
XvEncodingPtr pe;
|
||||
GLint texsize;
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texsize);
|
||||
|
||||
pe = xnfcalloc(1, sizeof(XvEncodingRec));
|
||||
pe->id = 0;
|
||||
pe->pScreen = pa->pScreen;
|
||||
pe->name = strdup(ENCODER_NAME);
|
||||
pe->width = texsize;
|
||||
pe->height = texsize;
|
||||
pe->rate.numerator = 1;
|
||||
pe->rate.denominator = 1;
|
||||
|
||||
pa->pEncodings = pe;
|
||||
pa->nEncodings = 1;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_xv_add_adaptors(ScreenPtr pScreen)
|
||||
{
|
||||
DevPrivateKey XvScreenKey;
|
||||
XvScreenPtr XvScreen;
|
||||
xwlXvScreenPtr xwlXvScreen;
|
||||
XvAdaptorPtr pa;
|
||||
|
||||
if (XvScreenInit(pScreen) != Success)
|
||||
return FALSE;
|
||||
|
||||
XvScreenKey = XvGetScreenKey();
|
||||
XvScreen = dixLookupPrivate(&(pScreen)->devPrivates, XvScreenKey);
|
||||
|
||||
XvScreen->nAdaptors = 0;
|
||||
XvScreen->pAdaptors = NULL;
|
||||
|
||||
pa = xnfcalloc(1, sizeof(XvAdaptorRec));
|
||||
pa->pScreen = pScreen;
|
||||
pa->type = (unsigned char) (XvInputMask | XvImageMask);
|
||||
pa->ddStopVideo = xwl_glamor_xv_stop_video;
|
||||
pa->ddPutImage = xwl_glamor_xv_put_image;
|
||||
pa->ddSetPortAttribute = xwl_glamor_xv_set_port_attribute;
|
||||
pa->ddGetPortAttribute = xwl_glamor_xv_get_port_attribute;
|
||||
pa->ddQueryBestSize = xwl_glamor_xv_query_best_size;
|
||||
pa->ddQueryImageAttributes = xwl_glamor_xv_query_image_attributes;
|
||||
pa->name = strdup(ADAPTOR_NAME);
|
||||
|
||||
xwl_glamor_xv_add_encodings(pa);
|
||||
xwl_glamor_xv_add_images(pa);
|
||||
xwl_glamor_xv_add_attributes(pa);
|
||||
if (!xwl_glamor_xv_add_formats(pa))
|
||||
goto failed;
|
||||
if (!xwl_glamor_xv_add_ports(pa))
|
||||
goto failed;
|
||||
|
||||
/* We're good now with out Xv adaptor */
|
||||
XvScreen->nAdaptors = 1;
|
||||
XvScreen->pAdaptors = pa;
|
||||
|
||||
xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates,
|
||||
xwlXvScreenPrivateKey);
|
||||
xwlXvScreen->glxv_adaptor = pa;
|
||||
|
||||
return TRUE;
|
||||
|
||||
failed:
|
||||
XvFreeAdaptor(pa);
|
||||
free(pa);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_xv_close_screen(ScreenPtr pScreen)
|
||||
{
|
||||
xwlXvScreenPtr xwlXvScreen;
|
||||
|
||||
xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates,
|
||||
xwlXvScreenPrivateKey);
|
||||
|
||||
if (xwlXvScreen->glxv_adaptor) {
|
||||
XvFreeAdaptor(xwlXvScreen->glxv_adaptor);
|
||||
free(xwlXvScreen->glxv_adaptor);
|
||||
}
|
||||
free(xwlXvScreen->port_privates);
|
||||
|
||||
pScreen->CloseScreen = xwlXvScreen->CloseScreen;
|
||||
|
||||
return pScreen->CloseScreen(pScreen);
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_xv_init(ScreenPtr pScreen)
|
||||
{
|
||||
xwlXvScreenPtr xwlXvScreen;
|
||||
|
||||
if (!dixRegisterPrivateKey(xwlXvScreenPrivateKey, PRIVATE_SCREEN,
|
||||
sizeof(xwlXvScreenRec)))
|
||||
return FALSE;
|
||||
|
||||
xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates,
|
||||
xwlXvScreenPrivateKey);
|
||||
|
||||
xwlXvScreen->port_privates = NULL;
|
||||
xwlXvScreen->glxv_adaptor = NULL;
|
||||
xwlXvScreen->CloseScreen = pScreen->CloseScreen;
|
||||
pScreen->CloseScreen = xwl_glamor_xv_close_screen;
|
||||
|
||||
glamor_xv_core_init(pScreen);
|
||||
|
||||
return xwl_glamor_xv_add_adaptors(pScreen);
|
||||
}
|
|
@ -1,491 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2011-2014 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#define MESA_EGL_NO_X11_HEADERS
|
||||
#define EGL_NO_X11
|
||||
#include <glamor_egl.h>
|
||||
|
||||
#include <glamor.h>
|
||||
#include <glamor_context.h>
|
||||
#ifdef GLXEXT
|
||||
#include "glx_extinit.h"
|
||||
#endif
|
||||
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
#include "drm-client-protocol.h"
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
#include "xwayland-glamor.h"
|
||||
#include "xwayland-glx.h"
|
||||
#include "xwayland-screen.h"
|
||||
#include "xwayland-window.h"
|
||||
|
||||
static void
|
||||
glamor_egl_make_current(struct glamor_context *glamor_ctx)
|
||||
{
|
||||
eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (!eglMakeCurrent(glamor_ctx->display,
|
||||
EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
glamor_ctx->ctx))
|
||||
FatalError("Failed to make EGL context current\n");
|
||||
}
|
||||
|
||||
void
|
||||
xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
if (lastGLContext == xwl_screen->glamor_ctx)
|
||||
return;
|
||||
|
||||
lastGLContext = xwl_screen->glamor_ctx;
|
||||
xwl_screen->glamor_ctx->make_current(xwl_screen->glamor_ctx);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
|
||||
glamor_enable_dri3(screen);
|
||||
glamor_ctx->ctx = xwl_screen->egl_context;
|
||||
glamor_ctx->display = xwl_screen->egl_display;
|
||||
|
||||
glamor_ctx->make_current = glamor_egl_make_current;
|
||||
|
||||
xwl_screen->glamor_ctx = glamor_ctx;
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_check_flip(PixmapPtr pixmap)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
|
||||
|
||||
if (!xwl_glamor_pixmap_get_wl_buffer(pixmap))
|
||||
return FALSE;
|
||||
|
||||
if (xwl_screen->egl_backend->check_flip)
|
||||
return xwl_screen->egl_backend->check_flip(pixmap);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
|
||||
uint32_t format, uint64_t modifier)
|
||||
{
|
||||
struct xwl_format *xwl_format = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < xwl_screen->num_formats; i++) {
|
||||
if (xwl_screen->formats[i].format == format) {
|
||||
xwl_format = &xwl_screen->formats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (xwl_format) {
|
||||
for (i = 0; i < xwl_format->num_modifiers; i++) {
|
||||
if (xwl_format->modifiers[i] == modifier) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
wl_drm_format_for_depth(int depth)
|
||||
{
|
||||
switch (depth) {
|
||||
case 15:
|
||||
return WL_DRM_FORMAT_XRGB1555;
|
||||
case 16:
|
||||
return WL_DRM_FORMAT_RGB565;
|
||||
case 24:
|
||||
return WL_DRM_FORMAT_XRGB8888;
|
||||
case 30:
|
||||
return WL_DRM_FORMAT_ARGB2101010;
|
||||
default:
|
||||
ErrorF("unexpected depth: %d\n", depth);
|
||||
case 32:
|
||||
return WL_DRM_FORMAT_ARGB8888;
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_get_formats(ScreenPtr screen,
|
||||
CARD32 *num_formats, CARD32 **formats)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
int i;
|
||||
|
||||
/* Explicitly zero the count as the caller may ignore the return value */
|
||||
*num_formats = 0;
|
||||
|
||||
if (!xwl_screen->dmabuf)
|
||||
return FALSE;
|
||||
|
||||
if (xwl_screen->num_formats == 0)
|
||||
return TRUE;
|
||||
|
||||
*formats = calloc(xwl_screen->num_formats, sizeof(CARD32));
|
||||
if (*formats == NULL)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < xwl_screen->num_formats; i++)
|
||||
(*formats)[i] = xwl_screen->formats[i].format;
|
||||
*num_formats = xwl_screen->num_formats;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
|
||||
uint32_t *num_modifiers, uint64_t **modifiers)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
struct xwl_format *xwl_format = NULL;
|
||||
int i;
|
||||
|
||||
/* Explicitly zero the count as the caller may ignore the return value */
|
||||
*num_modifiers = 0;
|
||||
|
||||
if (!xwl_screen->dmabuf)
|
||||
return FALSE;
|
||||
|
||||
if (xwl_screen->num_formats == 0)
|
||||
return TRUE;
|
||||
|
||||
for (i = 0; i < xwl_screen->num_formats; i++) {
|
||||
if (xwl_screen->formats[i].format == format) {
|
||||
xwl_format = &xwl_screen->formats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!xwl_format ||
|
||||
(xwl_format->num_modifiers == 1 &&
|
||||
xwl_format->modifiers[0] == DRM_FORMAT_MOD_INVALID))
|
||||
return FALSE;
|
||||
|
||||
*modifiers = calloc(xwl_format->num_modifiers, sizeof(uint64_t));
|
||||
if (*modifiers == NULL)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < xwl_format->num_modifiers; i++)
|
||||
(*modifiers)[i] = xwl_format->modifiers[i];
|
||||
*num_modifiers = xwl_format->num_modifiers;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
|
||||
uint32_t format)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
|
||||
uint32_t format, uint32_t modifier_hi,
|
||||
uint32_t modifier_lo)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = data;
|
||||
struct xwl_format *xwl_format = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < xwl_screen->num_formats; i++) {
|
||||
if (xwl_screen->formats[i].format == format) {
|
||||
xwl_format = &xwl_screen->formats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (xwl_format == NULL) {
|
||||
xwl_screen->num_formats++;
|
||||
xwl_screen->formats = realloc(xwl_screen->formats,
|
||||
xwl_screen->num_formats * sizeof(*xwl_format));
|
||||
if (!xwl_screen->formats)
|
||||
return;
|
||||
xwl_format = &xwl_screen->formats[xwl_screen->num_formats - 1];
|
||||
xwl_format->format = format;
|
||||
xwl_format->num_modifiers = 0;
|
||||
xwl_format->modifiers = NULL;
|
||||
}
|
||||
|
||||
xwl_format->num_modifiers++;
|
||||
xwl_format->modifiers = realloc(xwl_format->modifiers,
|
||||
xwl_format->num_modifiers * sizeof(uint64_t));
|
||||
if (!xwl_format->modifiers)
|
||||
return;
|
||||
xwl_format->modifiers[xwl_format->num_modifiers - 1] = (uint64_t) modifier_lo;
|
||||
xwl_format->modifiers[xwl_format->num_modifiers - 1] |= (uint64_t) modifier_hi << 32;
|
||||
}
|
||||
|
||||
static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
|
||||
.format = xwl_dmabuf_handle_format,
|
||||
.modifier = xwl_dmabuf_handle_modifier
|
||||
};
|
||||
|
||||
Bool
|
||||
xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
|
||||
uint32_t id, uint32_t version)
|
||||
{
|
||||
if (version < 3)
|
||||
return FALSE;
|
||||
|
||||
xwl_screen->dmabuf =
|
||||
wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, 3);
|
||||
zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
|
||||
struct wl_registry *registry,
|
||||
uint32_t id, const char *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
if (xwl_screen->gbm_backend.is_available &&
|
||||
xwl_screen->gbm_backend.init_wl_registry(xwl_screen,
|
||||
registry,
|
||||
id,
|
||||
interface,
|
||||
version)) {
|
||||
/* no-op */
|
||||
} else if (xwl_screen->eglstream_backend.is_available &&
|
||||
xwl_screen->eglstream_backend.init_wl_registry(xwl_screen,
|
||||
registry,
|
||||
id,
|
||||
interface,
|
||||
version)) {
|
||||
/* no-op */
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
|
||||
struct xwl_egl_backend *xwl_egl_backend)
|
||||
{
|
||||
return xwl_egl_backend->has_wl_interfaces(xwl_screen);
|
||||
}
|
||||
|
||||
struct wl_buffer *
|
||||
xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
|
||||
|
||||
if (xwl_screen->egl_backend->get_wl_buffer_for_pixmap)
|
||||
return xwl_screen->egl_backend->get_wl_buffer_for_pixmap(pixmap);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_post_damage(struct xwl_window *xwl_window,
|
||||
PixmapPtr pixmap, RegionPtr region)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
|
||||
|
||||
if (xwl_screen->egl_backend->post_damage)
|
||||
return xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_allow_commits(struct xwl_window *xwl_window)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
|
||||
|
||||
if (xwl_screen->egl_backend->allow_commits)
|
||||
return xwl_screen->egl_backend->allow_commits(xwl_window);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_create_screen_resources(ScreenPtr screen)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
int ret;
|
||||
|
||||
screen->CreateScreenResources = xwl_screen->CreateScreenResources;
|
||||
ret = (*screen->CreateScreenResources) (screen);
|
||||
xwl_screen->CreateScreenResources = screen->CreateScreenResources;
|
||||
screen->CreateScreenResources = xwl_glamor_create_screen_resources;
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
if (xwl_screen->rootless) {
|
||||
screen->devPrivate =
|
||||
fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0);
|
||||
}
|
||||
else {
|
||||
screen->devPrivate = screen->CreatePixmap(
|
||||
screen, screen->width, screen->height, screen->rootDepth,
|
||||
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
|
||||
}
|
||||
|
||||
SetRootClip(screen, xwl_screen->root_clip_mode);
|
||||
|
||||
return screen->devPrivate != NULL;
|
||||
}
|
||||
|
||||
int
|
||||
glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
|
||||
PixmapPtr pixmap,
|
||||
CARD16 *stride, CARD32 *size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
if (!xwl_screen->glamor || !xwl_screen->egl_backend)
|
||||
return FALSE;
|
||||
|
||||
return (xwl_screen->egl_backend->backend_flags &
|
||||
XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH);
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
/* wl_shm benefits from n-buffering */
|
||||
if (!xwl_screen->glamor || !xwl_screen->egl_backend)
|
||||
return TRUE;
|
||||
|
||||
return (xwl_screen->egl_backend->backend_flags &
|
||||
XWL_EGL_BACKEND_NEEDS_N_BUFFERING);
|
||||
}
|
||||
|
||||
void
|
||||
xwl_glamor_init_backends(struct xwl_screen *xwl_screen, Bool use_eglstream)
|
||||
{
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
xwl_glamor_init_gbm(xwl_screen);
|
||||
if (!xwl_screen->gbm_backend.is_available && !use_eglstream)
|
||||
ErrorF("xwayland glamor: GBM backend (default) is not available\n");
|
||||
#endif
|
||||
#ifdef XWL_HAS_EGLSTREAM
|
||||
xwl_glamor_init_eglstream(xwl_screen);
|
||||
if (!xwl_screen->eglstream_backend.is_available && use_eglstream)
|
||||
ErrorF("xwayland glamor: EGLStream backend requested but not available\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_select_gbm_backend(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
if (xwl_screen->gbm_backend.is_available &&
|
||||
xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->gbm_backend)) {
|
||||
xwl_screen->egl_backend = &xwl_screen->gbm_backend;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
ErrorF("Missing Wayland requirements for glamor GBM backend\n");
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
#ifdef XWL_HAS_EGLSTREAM
|
||||
if (xwl_screen->eglstream_backend.is_available &&
|
||||
xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->eglstream_backend)) {
|
||||
xwl_screen->egl_backend = &xwl_screen->eglstream_backend;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
ErrorF("Missing Wayland requirements for glamor EGLStream backend\n");
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
xwl_glamor_select_backend(struct xwl_screen *xwl_screen, Bool use_eglstream)
|
||||
{
|
||||
if (use_eglstream) {
|
||||
if (!xwl_glamor_select_eglstream_backend(xwl_screen))
|
||||
xwl_glamor_select_gbm_backend(xwl_screen);
|
||||
}
|
||||
else {
|
||||
if (!xwl_glamor_select_gbm_backend(xwl_screen))
|
||||
xwl_glamor_select_eglstream_backend(xwl_screen);
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_glamor_init(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
ScreenPtr screen = xwl_screen->screen;
|
||||
const char *no_glamor_env;
|
||||
|
||||
no_glamor_env = getenv("XWAYLAND_NO_GLAMOR");
|
||||
if (no_glamor_env && *no_glamor_env != '0') {
|
||||
ErrorF("Disabling glamor and dri3 support, XWAYLAND_NO_GLAMOR is set\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!xwl_screen->egl_backend->init_egl(xwl_screen)) {
|
||||
ErrorF("EGL setup failed, disabling glamor\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!glamor_init(xwl_screen->screen, GLAMOR_USE_EGL_SCREEN)) {
|
||||
ErrorF("Failed to initialize glamor\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!xwl_screen->egl_backend->init_screen(xwl_screen)) {
|
||||
ErrorF("EGL backend init_screen() failed, disabling glamor\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xwl_screen->CreateScreenResources = screen->CreateScreenResources;
|
||||
screen->CreateScreenResources = xwl_glamor_create_screen_resources;
|
||||
|
||||
#ifdef XV
|
||||
if (!xwl_glamor_xv_init(screen))
|
||||
ErrorF("Failed to initialize glamor Xv extension\n");
|
||||
#endif
|
||||
|
||||
#ifdef GLXEXT
|
||||
GlxPushProvider(&glamor_provider);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2011-2014 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XWAYLAND_GLAMOR_H
|
||||
#define XWAYLAND_GLAMOR_H
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include "xwayland-types.h"
|
||||
|
||||
typedef enum _xwl_egl_backend_flags {
|
||||
XWL_EGL_BACKEND_NO_FLAG = 0,
|
||||
XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH = (1 << 0),
|
||||
XWL_EGL_BACKEND_NEEDS_N_BUFFERING = (1 << 1),
|
||||
} xwl_egl_backend_flags;
|
||||
|
||||
struct xwl_egl_backend {
|
||||
/* Set by the backend if available */
|
||||
Bool is_available;
|
||||
|
||||
/* Features and requirements set by the backend */
|
||||
xwl_egl_backend_flags backend_flags;
|
||||
|
||||
/* Called once for each interface in the global registry. Backends
|
||||
* should use this to bind to any wayland interfaces they need.
|
||||
*/
|
||||
Bool (*init_wl_registry)(struct xwl_screen *xwl_screen,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t id, const char *name,
|
||||
uint32_t version);
|
||||
|
||||
/* Check that the required Wayland interfaces are available.
|
||||
*/
|
||||
Bool (*has_wl_interfaces)(struct xwl_screen *xwl_screen);
|
||||
|
||||
/* Called before glamor has been initialized. Backends should setup a
|
||||
* valid, glamor compatible EGL context in this hook.
|
||||
*/
|
||||
Bool (*init_egl)(struct xwl_screen *xwl_screen);
|
||||
|
||||
/* Called after glamor has been initialized, and after all of the
|
||||
* common Xwayland DDX hooks have been connected. Backends should use
|
||||
* this to setup any required wraps around X server callbacks like
|
||||
* CreatePixmap.
|
||||
*/
|
||||
Bool (*init_screen)(struct xwl_screen *xwl_screen);
|
||||
|
||||
/* Called by Xwayland to retrieve a pointer to a valid wl_buffer for
|
||||
* the given window/pixmap combo so that damage to the pixmap may be
|
||||
* displayed on-screen. Backends should use this to create a new
|
||||
* wl_buffer for a currently buffer-less pixmap, or simply return the
|
||||
* pixmap they've prepared beforehand.
|
||||
*/
|
||||
struct wl_buffer *(*get_wl_buffer_for_pixmap)(PixmapPtr pixmap);
|
||||
|
||||
/* Called by Xwayland to perform any pre-wl_surface damage routines
|
||||
* that are required by the backend. If your backend is poorly
|
||||
* designed and lacks the ability to render directly to a surface,
|
||||
* you should implement blitting from the glamor pixmap to the wayland
|
||||
* pixmap here. Otherwise, this callback is optional.
|
||||
*/
|
||||
Bool (*post_damage)(struct xwl_window *xwl_window,
|
||||
PixmapPtr pixmap, RegionPtr region);
|
||||
|
||||
/* Called by Xwayland to confirm with the egl backend that the given
|
||||
* pixmap is completely setup and ready for display on-screen. This
|
||||
* callback is optional.
|
||||
*/
|
||||
Bool (*allow_commits)(struct xwl_window *xwl_window);
|
||||
|
||||
/* Called by Xwayland to check whether the given pixmap can be
|
||||
* presented by xwl_present_flip. If not implemented, assumed TRUE.
|
||||
*/
|
||||
Bool (*check_flip)(PixmapPtr pixmap);
|
||||
};
|
||||
|
||||
#ifdef XWL_HAS_GLAMOR
|
||||
|
||||
void xwl_glamor_init_backends(struct xwl_screen *xwl_screen,
|
||||
Bool use_eglstream);
|
||||
void xwl_glamor_select_backend(struct xwl_screen *xwl_screen,
|
||||
Bool use_eglstream);
|
||||
Bool xwl_glamor_init(struct xwl_screen *xwl_screen);
|
||||
|
||||
Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
|
||||
uint32_t id, uint32_t version);
|
||||
Bool xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
|
||||
uint32_t id, uint32_t version);
|
||||
struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap);
|
||||
void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
|
||||
struct wl_registry *registry,
|
||||
uint32_t id, const char *interface,
|
||||
uint32_t version);
|
||||
Bool xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
|
||||
struct xwl_egl_backend *xwl_egl_backend);
|
||||
Bool xwl_glamor_post_damage(struct xwl_window *xwl_window,
|
||||
PixmapPtr pixmap, RegionPtr region);
|
||||
Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
|
||||
void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
|
||||
Bool xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen);
|
||||
Bool xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen);
|
||||
Bool xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
|
||||
uint32_t format, uint64_t modifier);
|
||||
uint32_t wl_drm_format_for_depth(int depth);
|
||||
Bool xwl_glamor_get_formats(ScreenPtr screen,
|
||||
CARD32 *num_formats, CARD32 **formats);
|
||||
Bool xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
|
||||
uint32_t *num_modifiers, uint64_t **modifiers);
|
||||
Bool xwl_glamor_check_flip(PixmapPtr pixmap);
|
||||
|
||||
#ifdef XV
|
||||
/* glamor Xv Adaptor */
|
||||
Bool xwl_glamor_xv_init(ScreenPtr pScreen);
|
||||
#endif /* XV */
|
||||
|
||||
#endif /* XWL_HAS_GLAMOR */
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen);
|
||||
#else
|
||||
static inline void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XWL_HAS_EGLSTREAM
|
||||
void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen);
|
||||
#else
|
||||
static inline void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* XWAYLAND_GLAMOR_H */
|
|
@ -1,397 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Adam Jackson <ajax@redhat.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Sets up GLX capabilities based on the EGL capabilities of the glamor
|
||||
* renderer for the screen. Without this you will get whatever swrast
|
||||
* can do, which often does not include things like multisample visuals.
|
||||
*/
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#define MESA_EGL_NO_X11_HEADERS
|
||||
#define EGL_NO_X11
|
||||
// #include <EGL/egl.h>
|
||||
#include <epoxy/egl.h>
|
||||
#include "glxserver.h"
|
||||
#include "glxutil.h"
|
||||
#include "compint.h"
|
||||
#include <X11/extensions/composite.h>
|
||||
#include "glamor_context.h"
|
||||
#include "glamor.h"
|
||||
|
||||
#include "xwayland-screen.h"
|
||||
|
||||
/* Can't get these from <GL/glx.h> since it pulls in client headers */
|
||||
#define GLX_RGBA_BIT 0x00000001
|
||||
#define GLX_WINDOW_BIT 0x00000001
|
||||
#define GLX_PIXMAP_BIT 0x00000002
|
||||
#define GLX_PBUFFER_BIT 0x00000004
|
||||
#define GLX_NONE 0x8000
|
||||
#define GLX_SLOW_CONFIG 0x8001
|
||||
#define GLX_TRUE_COLOR 0x8002
|
||||
#define GLX_DIRECT_COLOR 0x8003
|
||||
#define GLX_NON_CONFORMANT_CONFIG 0x800D
|
||||
#define GLX_DONT_CARE 0xFFFFFFFF
|
||||
#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
|
||||
#define GLX_SWAP_UNDEFINED_OML 0x8063
|
||||
|
||||
struct egl_config {
|
||||
__GLXconfig base;
|
||||
EGLConfig config;
|
||||
};
|
||||
|
||||
struct egl_screen {
|
||||
__GLXscreen base;
|
||||
EGLDisplay display;
|
||||
EGLConfig *configs;
|
||||
};
|
||||
|
||||
static void
|
||||
egl_screen_destroy(__GLXscreen *_screen)
|
||||
{
|
||||
struct egl_screen *screen = (struct egl_screen *)_screen;
|
||||
|
||||
/* XXX do we leak the fbconfig list? */
|
||||
|
||||
free(screen->configs);
|
||||
__glXScreenDestroy(_screen);
|
||||
free(_screen);
|
||||
}
|
||||
|
||||
static void
|
||||
egl_drawable_destroy(__GLXdrawable *draw)
|
||||
{
|
||||
free(draw);
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
egl_drawable_swap_buffers(ClientPtr client, __GLXdrawable *draw)
|
||||
{
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
egl_drawable_copy_sub_buffer(__GLXdrawable *draw, int x, int y, int w, int h)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
egl_drawable_wait_x(__GLXdrawable *draw)
|
||||
{
|
||||
glamor_block_handler(draw->pDraw->pScreen);
|
||||
}
|
||||
|
||||
static void
|
||||
egl_drawable_wait_gl(__GLXdrawable *draw)
|
||||
{
|
||||
}
|
||||
|
||||
static __GLXdrawable *
|
||||
egl_create_glx_drawable(ClientPtr client, __GLXscreen *screen,
|
||||
DrawablePtr draw, XID drawid, int type,
|
||||
XID glxdrawid, __GLXconfig *modes)
|
||||
{
|
||||
__GLXdrawable *ret;
|
||||
|
||||
ret = calloc(1, sizeof *ret);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
if (!__glXDrawableInit(ret, screen, draw, type, glxdrawid, modes)) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->destroy = egl_drawable_destroy;
|
||||
ret->swapBuffers = egl_drawable_swap_buffers;
|
||||
ret->copySubBuffer = egl_drawable_copy_sub_buffer;
|
||||
ret->waitX = egl_drawable_wait_x;
|
||||
ret->waitGL = egl_drawable_wait_gl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* - figure out sRGB
|
||||
* - bindToTextureTargets is suspicious
|
||||
* - better channel mask setup
|
||||
* - drawable type masks is suspicious
|
||||
*/
|
||||
static struct egl_config *
|
||||
translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
|
||||
struct egl_config *chain, Bool direct_color,
|
||||
Bool double_buffer, Bool duplicate_for_composite)
|
||||
{
|
||||
EGLint value;
|
||||
struct egl_config *c = calloc(1, sizeof *c);
|
||||
|
||||
if (!c)
|
||||
return chain;
|
||||
|
||||
/* constants. changing these requires (at least) new EGL extensions */
|
||||
c->base.stereoMode = GL_FALSE;
|
||||
c->base.numAuxBuffers = 0;
|
||||
c->base.level = 0;
|
||||
c->base.transparentAlpha = 0;
|
||||
c->base.transparentIndex = 0;
|
||||
c->base.transparentPixel = GLX_NONE;
|
||||
c->base.visualSelectGroup = 0;
|
||||
c->base.indexBits = 0;
|
||||
c->base.optimalPbufferWidth = 0;
|
||||
c->base.optimalPbufferHeight = 0;
|
||||
c->base.bindToMipmapTexture = 0;
|
||||
c->base.bindToTextureTargets = GLX_DONT_CARE;
|
||||
c->base.sRGBCapable = 0;
|
||||
c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
|
||||
|
||||
/* this is... suspect */
|
||||
c->base.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
|
||||
|
||||
/* hmm */
|
||||
c->base.bindToTextureRgb = GL_TRUE;
|
||||
c->base.bindToTextureRgba = GL_TRUE;
|
||||
|
||||
/*
|
||||
* glx conformance failure: there's no such thing as accumulation
|
||||
* buffers in EGL. they should be emulable with shaders and fbos,
|
||||
* but i'm pretty sure nobody's using this feature since it's
|
||||
* entirely software. note that glx conformance merely requires
|
||||
* that an accum buffer _exist_, not a minimum bitness.
|
||||
*/
|
||||
c->base.accumRedBits = 0;
|
||||
c->base.accumGreenBits = 0;
|
||||
c->base.accumBlueBits = 0;
|
||||
c->base.accumAlphaBits = 0;
|
||||
|
||||
/* parametric state */
|
||||
if (direct_color)
|
||||
c->base.visualType = GLX_DIRECT_COLOR;
|
||||
else
|
||||
c->base.visualType = GLX_TRUE_COLOR;
|
||||
|
||||
if (double_buffer)
|
||||
c->base.doubleBufferMode = GL_TRUE;
|
||||
else
|
||||
c->base.doubleBufferMode = GL_FALSE;
|
||||
|
||||
/* direct-mapped state */
|
||||
#define GET(attr, slot) \
|
||||
eglGetConfigAttrib(screen->display, hc, attr, &c->base.slot)
|
||||
GET(EGL_RED_SIZE, redBits);
|
||||
GET(EGL_GREEN_SIZE, greenBits);
|
||||
GET(EGL_BLUE_SIZE, blueBits);
|
||||
GET(EGL_ALPHA_SIZE, alphaBits);
|
||||
GET(EGL_BUFFER_SIZE, rgbBits);
|
||||
GET(EGL_DEPTH_SIZE, depthBits);
|
||||
GET(EGL_STENCIL_SIZE, stencilBits);
|
||||
GET(EGL_TRANSPARENT_RED_VALUE, transparentRed);
|
||||
GET(EGL_TRANSPARENT_GREEN_VALUE, transparentGreen);
|
||||
GET(EGL_TRANSPARENT_BLUE_VALUE, transparentBlue);
|
||||
GET(EGL_SAMPLE_BUFFERS, sampleBuffers);
|
||||
GET(EGL_SAMPLES, samples);
|
||||
if (c->base.renderType & GLX_PBUFFER_BIT) {
|
||||
GET(EGL_MAX_PBUFFER_WIDTH, maxPbufferWidth);
|
||||
GET(EGL_MAX_PBUFFER_HEIGHT, maxPbufferHeight);
|
||||
GET(EGL_MAX_PBUFFER_PIXELS, maxPbufferPixels);
|
||||
}
|
||||
#undef GET
|
||||
|
||||
/* derived state: config caveats */
|
||||
eglGetConfigAttrib(screen->display, hc, EGL_CONFIG_CAVEAT, &value);
|
||||
if (value == EGL_NONE)
|
||||
c->base.visualRating = GLX_NONE;
|
||||
else if (value == EGL_SLOW_CONFIG)
|
||||
c->base.visualRating = GLX_SLOW_CONFIG;
|
||||
else if (value == EGL_NON_CONFORMANT_CONFIG)
|
||||
c->base.visualRating = GLX_NON_CONFORMANT_CONFIG;
|
||||
/* else panic */
|
||||
|
||||
/* derived state: float configs */
|
||||
c->base.renderType = GLX_RGBA_BIT;
|
||||
if (eglGetConfigAttrib(screen->display, hc, EGL_COLOR_COMPONENT_TYPE_EXT,
|
||||
&value) == EGL_TRUE) {
|
||||
if (value == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) {
|
||||
c->base.renderType = GLX_RGBA_FLOAT_BIT_ARB;
|
||||
}
|
||||
/* else panic */
|
||||
}
|
||||
|
||||
/* map to the backend's config */
|
||||
c->config = hc;
|
||||
|
||||
/*
|
||||
* XXX do something less ugly
|
||||
*/
|
||||
if (c->base.renderType == GLX_RGBA_BIT) {
|
||||
if (c->base.redBits == 5 &&
|
||||
(c->base.rgbBits == 15 || c->base.rgbBits == 16)) {
|
||||
c->base.blueMask = 0x0000001f;
|
||||
if (c->base.alphaBits) {
|
||||
c->base.greenMask = 0x000003e0;
|
||||
c->base.redMask = 0x00007c00;
|
||||
c->base.alphaMask = 0x00008000;
|
||||
} else {
|
||||
c->base.greenMask = 0x000007e0;
|
||||
c->base.redMask = 0x0000f800;
|
||||
c->base.alphaMask = 0x00000000;
|
||||
}
|
||||
}
|
||||
else if (c->base.redBits == 8 &&
|
||||
(c->base.rgbBits == 24 || c->base.rgbBits == 32)) {
|
||||
c->base.blueMask = 0x000000ff;
|
||||
c->base.greenMask = 0x0000ff00;
|
||||
c->base.redMask = 0x00ff0000;
|
||||
if (c->base.alphaBits)
|
||||
/* assume all remaining bits are alpha */
|
||||
c->base.alphaMask = 0xff000000;
|
||||
}
|
||||
else if (c->base.redBits == 10 &&
|
||||
(c->base.rgbBits == 30 || c->base.rgbBits == 32)) {
|
||||
c->base.blueMask = 0x000003ff;
|
||||
c->base.greenMask = 0x000ffc00;
|
||||
c->base.redMask = 0x3ff00000;
|
||||
if (c->base.alphaBits)
|
||||
/* assume all remaining bits are alpha */
|
||||
c->base.alphaMask = 0xc000000;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we decide which fbconfigs will be duplicated for compositing.
|
||||
* fgbconfigs marked with duplicatedForComp will be reserved for
|
||||
* compositing visuals.
|
||||
* It might look strange to do this decision this late when translation
|
||||
* from an EGLConfig is already done, but using the EGLConfig
|
||||
* accessor functions becomes worse both with respect to code complexity
|
||||
* and CPU usage.
|
||||
*/
|
||||
if (duplicate_for_composite &&
|
||||
(c->base.renderType == GLX_RGBA_FLOAT_BIT_ARB ||
|
||||
c->base.rgbBits != 32 ||
|
||||
c->base.redBits != 8 ||
|
||||
c->base.greenBits != 8 ||
|
||||
c->base.blueBits != 8 ||
|
||||
c->base.visualRating != GLX_NONE ||
|
||||
c->base.sampleBuffers != 0)) {
|
||||
free(c);
|
||||
return chain;
|
||||
}
|
||||
c->base.duplicatedForComp = duplicate_for_composite;
|
||||
|
||||
c->base.next = chain ? &chain->base : NULL;
|
||||
return c;
|
||||
}
|
||||
|
||||
static __GLXconfig *
|
||||
egl_mirror_configs(ScreenPtr pScreen, struct egl_screen *screen)
|
||||
{
|
||||
int i, j, k, nconfigs;
|
||||
struct egl_config *c = NULL;
|
||||
EGLConfig *host_configs = NULL;
|
||||
|
||||
eglGetConfigs(screen->display, NULL, 0, &nconfigs);
|
||||
if (!(host_configs = calloc(nconfigs, sizeof *host_configs)))
|
||||
return NULL;
|
||||
|
||||
eglGetConfigs(screen->display, host_configs, nconfigs, &nconfigs);
|
||||
|
||||
/* We walk the EGL configs backwards to make building the
|
||||
* ->next chain easier.
|
||||
*/
|
||||
for (i = nconfigs - 1; i > 0; i--)
|
||||
for (j = 0; j < 3; j++) /* direct_color */
|
||||
for (k = 0; k < 2; k++) /* double_buffer */
|
||||
c = translate_eglconfig(screen, host_configs[i], c,
|
||||
/* direct_color */ j == 1,
|
||||
/* double_buffer */ k > 0,
|
||||
/* duplicate_for_composite */ j == 0);
|
||||
|
||||
screen->configs = host_configs;
|
||||
return c ? &c->base : NULL;
|
||||
}
|
||||
|
||||
static __GLXscreen *
|
||||
egl_screen_probe(ScreenPtr pScreen)
|
||||
{
|
||||
struct egl_screen *screen;
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
|
||||
__GLXscreen *base;
|
||||
|
||||
if (enableIndirectGLX)
|
||||
return NULL; /* not implemented */
|
||||
|
||||
if (!(screen = calloc(1, sizeof *screen)))
|
||||
return NULL;
|
||||
|
||||
base = &screen->base;
|
||||
base->destroy = egl_screen_destroy;
|
||||
base->createDrawable = egl_create_glx_drawable;
|
||||
/* base.swapInterval = NULL; */
|
||||
|
||||
screen->display = xwl_screen->glamor_ctx->display;
|
||||
|
||||
__glXInitExtensionEnableBits(screen->base.glx_enable_bits);
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_context_flush_control");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_no_error");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_profile");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_robustness");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_fbconfig_float");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es2_profile");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es_profile");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_fbconfig_packed_float");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_framebuffer_sRGB");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_no_config_context");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_texture_from_pixmap");
|
||||
__glXEnableExtension(base->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
|
||||
// __glXEnableExtension(base->glx_enable_bits, "GLX_SGI_swap_control");
|
||||
|
||||
base->fbconfigs = egl_mirror_configs(pScreen, screen);
|
||||
if (!base->fbconfigs) {
|
||||
free(screen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!screen->base.glvnd && xwl_screen->glvnd_vendor)
|
||||
screen->base.glvnd = strdup(xwl_screen->glvnd_vendor);
|
||||
|
||||
if (!screen->base.glvnd)
|
||||
screen->base.glvnd = strdup("mesa");
|
||||
|
||||
__glXScreenInit(base, pScreen);
|
||||
__glXsetGetProcAddress(eglGetProcAddress);
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
__GLXprovider glamor_provider = {
|
||||
egl_screen_probe,
|
||||
"glamor",
|
||||
NULL
|
||||
};
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Adam Jackson <ajax@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef XWAYLAND_GLX_H
|
||||
#define XWAYLAND_GLX_H
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#ifdef GLXEXT
|
||||
#include "glx_extinit.h"
|
||||
extern __GLXprovider glamor_provider;
|
||||
#endif
|
||||
|
||||
#endif /* XWAYLAND_GLX_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2014 Intel Corporation
|
||||
* Copyright © 2008 Kristian Høgsberg
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XWAYLAND_INPUT_H
|
||||
#define XWAYLAND_INPUT_H
|
||||
|
||||
#include <xwayland-config.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include <dix.h>
|
||||
#include <input.h>
|
||||
|
||||
struct xwl_touch {
|
||||
struct xwl_window *window;
|
||||
int32_t id;
|
||||
int x, y;
|
||||
struct xorg_list link_touch;
|
||||
};
|
||||
|
||||
struct xwl_pointer_warp_emulator {
|
||||
struct xwl_seat *xwl_seat;
|
||||
struct xwl_window *locked_window;
|
||||
struct zwp_locked_pointer_v1 *locked_pointer;
|
||||
};
|
||||
|
||||
struct xwl_cursor {
|
||||
void (* update_proc) (struct xwl_cursor *);
|
||||
struct wl_surface *surface;
|
||||
struct wl_callback *frame_cb;
|
||||
Bool needs_update;
|
||||
};
|
||||
|
||||
struct xwl_seat {
|
||||
DeviceIntPtr pointer;
|
||||
DeviceIntPtr relative_pointer;
|
||||
DeviceIntPtr keyboard;
|
||||
DeviceIntPtr touch;
|
||||
DeviceIntPtr stylus;
|
||||
DeviceIntPtr eraser;
|
||||
DeviceIntPtr puck;
|
||||
struct xwl_screen *xwl_screen;
|
||||
struct wl_seat *seat;
|
||||
struct wl_pointer *wl_pointer;
|
||||
struct zwp_relative_pointer_v1 *wp_relative_pointer;
|
||||
struct wl_keyboard *wl_keyboard;
|
||||
struct wl_touch *wl_touch;
|
||||
struct zwp_tablet_seat_v2 *tablet_seat;
|
||||
struct wl_array keys;
|
||||
struct xwl_window *focus_window;
|
||||
struct xwl_window *tablet_focus_window;
|
||||
uint32_t id;
|
||||
uint32_t pointer_enter_serial;
|
||||
struct xorg_list link;
|
||||
CursorPtr x_cursor;
|
||||
OsTimerPtr x_cursor_timer;
|
||||
CursorPtr pending_x_cursor;
|
||||
struct xwl_cursor cursor;
|
||||
WindowPtr last_xwindow;
|
||||
|
||||
struct xorg_list touches;
|
||||
|
||||
size_t keymap_size;
|
||||
char *keymap;
|
||||
struct wl_surface *keyboard_focus;
|
||||
|
||||
struct xorg_list axis_discrete_pending;
|
||||
struct xorg_list sync_pending;
|
||||
|
||||
struct xwl_pointer_warp_emulator *pointer_warp_emulator;
|
||||
|
||||
struct xwl_window *cursor_confinement_window;
|
||||
struct zwp_confined_pointer_v1 *confined_pointer;
|
||||
|
||||
struct {
|
||||
Bool has_absolute;
|
||||
wl_fixed_t x;
|
||||
wl_fixed_t y;
|
||||
|
||||
Bool has_relative;
|
||||
double dx;
|
||||
double dy;
|
||||
double dx_unaccel;
|
||||
double dy_unaccel;
|
||||
} pending_pointer_event;
|
||||
|
||||
struct xorg_list tablets;
|
||||
struct xorg_list tablet_tools;
|
||||
struct xorg_list tablet_pads;
|
||||
struct zwp_xwayland_keyboard_grab_v1 *keyboard_grab;
|
||||
};
|
||||
|
||||
struct xwl_tablet {
|
||||
struct xorg_list link;
|
||||
struct zwp_tablet_v2 *tablet;
|
||||
struct xwl_seat *seat;
|
||||
};
|
||||
|
||||
struct xwl_tablet_tool {
|
||||
struct xorg_list link;
|
||||
struct zwp_tablet_tool_v2 *tool;
|
||||
struct xwl_seat *seat;
|
||||
|
||||
DeviceIntPtr xdevice;
|
||||
uint32_t proximity_in_serial;
|
||||
double x;
|
||||
double y;
|
||||
uint32_t pressure;
|
||||
double tilt_x;
|
||||
double tilt_y;
|
||||
double rotation;
|
||||
double slider;
|
||||
|
||||
uint32_t buttons_now,
|
||||
buttons_prev;
|
||||
|
||||
int32_t wheel_clicks;
|
||||
|
||||
struct xwl_cursor cursor;
|
||||
};
|
||||
|
||||
struct xwl_tablet_pad_ring {
|
||||
unsigned int index;
|
||||
struct xorg_list link;
|
||||
struct xwl_tablet_pad_group *group;
|
||||
struct zwp_tablet_pad_ring_v2 *ring;
|
||||
};
|
||||
|
||||
struct xwl_tablet_pad_strip {
|
||||
unsigned int index;
|
||||
struct xorg_list link;
|
||||
struct xwl_tablet_pad_group *group;
|
||||
struct zwp_tablet_pad_strip_v2 *strip;
|
||||
};
|
||||
|
||||
struct xwl_tablet_pad_group {
|
||||
struct xorg_list link;
|
||||
struct xwl_tablet_pad *pad;
|
||||
struct zwp_tablet_pad_group_v2 *group;
|
||||
|
||||
struct xorg_list pad_group_ring_list;
|
||||
struct xorg_list pad_group_strip_list;
|
||||
};
|
||||
|
||||
struct xwl_tablet_pad {
|
||||
struct xorg_list link;
|
||||
struct zwp_tablet_pad_v2 *pad;
|
||||
struct xwl_seat *seat;
|
||||
|
||||
DeviceIntPtr xdevice;
|
||||
|
||||
unsigned int nbuttons;
|
||||
struct xorg_list pad_group_list;
|
||||
};
|
||||
|
||||
void xwl_seat_destroy(struct xwl_seat *xwl_seat);
|
||||
|
||||
void xwl_seat_clear_touch(struct xwl_seat *xwl_seat, WindowPtr window);
|
||||
|
||||
void xwl_seat_emulate_pointer_warp(struct xwl_seat *xwl_seat,
|
||||
struct xwl_window *xwl_window,
|
||||
SpritePtr sprite,
|
||||
int x, int y);
|
||||
|
||||
void xwl_seat_destroy_pointer_warp_emulator(struct xwl_seat *xwl_seat);
|
||||
|
||||
void xwl_seat_cursor_visibility_changed(struct xwl_seat *xwl_seat);
|
||||
|
||||
void xwl_seat_confine_pointer(struct xwl_seat *xwl_seat,
|
||||
struct xwl_window *xwl_window);
|
||||
void xwl_seat_unconfine_pointer(struct xwl_seat *xwl_seat);
|
||||
|
||||
void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
|
||||
|
||||
#endif /* XWAYLAND_INPUT_H */
|
|
@ -1,881 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2011-2014 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include <randrstr.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include "xwayland-cvt.h"
|
||||
#include "xwayland-output.h"
|
||||
#include "xwayland-screen.h"
|
||||
#include "xwayland-window.h"
|
||||
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
|
||||
#define ALL_ROTATIONS (RR_Rotate_0 | \
|
||||
RR_Rotate_90 | \
|
||||
RR_Rotate_180 | \
|
||||
RR_Rotate_270 | \
|
||||
RR_Reflect_X | \
|
||||
RR_Reflect_Y)
|
||||
|
||||
static void xwl_output_get_xdg_output(struct xwl_output *xwl_output);
|
||||
|
||||
static Rotation
|
||||
wl_transform_to_xrandr(enum wl_output_transform transform)
|
||||
{
|
||||
switch (transform) {
|
||||
default:
|
||||
case WL_OUTPUT_TRANSFORM_NORMAL:
|
||||
return RR_Rotate_0;
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
return RR_Rotate_90;
|
||||
case WL_OUTPUT_TRANSFORM_180:
|
||||
return RR_Rotate_180;
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
return RR_Rotate_270;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
||||
return RR_Reflect_X | RR_Rotate_0;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
return RR_Reflect_X | RR_Rotate_90;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||
return RR_Reflect_X | RR_Rotate_180;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
return RR_Reflect_X | RR_Rotate_270;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
wl_subpixel_to_xrandr(int subpixel)
|
||||
{
|
||||
switch (subpixel) {
|
||||
default:
|
||||
case WL_OUTPUT_SUBPIXEL_UNKNOWN:
|
||||
return SubPixelUnknown;
|
||||
case WL_OUTPUT_SUBPIXEL_NONE:
|
||||
return SubPixelNone;
|
||||
case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
|
||||
return SubPixelHorizontalRGB;
|
||||
case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
|
||||
return SubPixelHorizontalBGR;
|
||||
case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
|
||||
return SubPixelVerticalRGB;
|
||||
case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
|
||||
return SubPixelVerticalBGR;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
|
||||
int physical_width, int physical_height, int subpixel,
|
||||
const char *make, const char *model, int transform)
|
||||
{
|
||||
struct xwl_output *xwl_output = data;
|
||||
|
||||
RROutputSetPhysicalSize(xwl_output->randr_output,
|
||||
physical_width, physical_height);
|
||||
RROutputSetSubpixelOrder(xwl_output->randr_output,
|
||||
wl_subpixel_to_xrandr(subpixel));
|
||||
|
||||
/* Apply the change from wl_output only if xdg-output is not supported */
|
||||
if (!xwl_output->xdg_output) {
|
||||
xwl_output->x = x;
|
||||
xwl_output->y = y;
|
||||
}
|
||||
xwl_output->rotation = wl_transform_to_xrandr(transform);
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
|
||||
int width, int height, int refresh)
|
||||
{
|
||||
struct xwl_output *xwl_output = data;
|
||||
|
||||
if (!(flags & WL_OUTPUT_MODE_CURRENT))
|
||||
return;
|
||||
|
||||
/* Apply the change from wl_output only if xdg-output is not supported */
|
||||
if (!xwl_output->xdg_output) {
|
||||
xwl_output->width = width;
|
||||
xwl_output->height = height;
|
||||
}
|
||||
xwl_output->refresh = refresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides on the maximum expanse of an output in logical space (i.e. in the
|
||||
* Wayland compositor plane) respective to some fix width and height values. The
|
||||
* function sets the provided values to these maxima on return.
|
||||
*/
|
||||
static inline void
|
||||
output_get_new_size(struct xwl_output *xwl_output, int *width, int *height)
|
||||
{
|
||||
int output_width, output_height;
|
||||
|
||||
/* When we have xdg-output support the stored size is already rotated. */
|
||||
if (xwl_output->xdg_output
|
||||
|| (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180))) {
|
||||
output_width = xwl_output->width;
|
||||
output_height = xwl_output->height;
|
||||
} else {
|
||||
output_width = xwl_output->height;
|
||||
output_height = xwl_output->width;
|
||||
}
|
||||
|
||||
if (*width < xwl_output->x + output_width)
|
||||
*width = xwl_output->x + output_width;
|
||||
|
||||
if (*height < xwl_output->y + output_height)
|
||||
*height = xwl_output->y + output_height;
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_set_pixmap_visit_window(WindowPtr window, void *data)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
|
||||
if (screen->GetWindowPixmap(window) == data) {
|
||||
screen->SetWindowPixmap(window, screen->GetScreenPixmap(screen));
|
||||
return WT_WALKCHILDREN;
|
||||
}
|
||||
|
||||
return WT_DONTWALKCHILDREN;
|
||||
}
|
||||
|
||||
static void
|
||||
update_backing_pixmaps(struct xwl_screen *xwl_screen, int width, int height)
|
||||
{
|
||||
ScreenPtr pScreen = xwl_screen->screen;
|
||||
WindowPtr pRoot = pScreen->root;
|
||||
PixmapPtr old_pixmap, new_pixmap;
|
||||
|
||||
old_pixmap = pScreen->GetScreenPixmap(pScreen);
|
||||
new_pixmap = pScreen->CreatePixmap(pScreen, width, height,
|
||||
pScreen->rootDepth,
|
||||
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
|
||||
pScreen->SetScreenPixmap(new_pixmap);
|
||||
|
||||
if (old_pixmap) {
|
||||
TraverseTree(pRoot, xwl_set_pixmap_visit_window, old_pixmap);
|
||||
pScreen->DestroyPixmap(old_pixmap);
|
||||
}
|
||||
|
||||
pScreen->ResizeWindow(pRoot, 0, 0, width, height, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
update_screen_size(struct xwl_output *xwl_output, int width, int height)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||
|
||||
if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL)
|
||||
SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE);
|
||||
|
||||
if (!xwl_screen->rootless && xwl_screen->screen->root)
|
||||
update_backing_pixmaps (xwl_screen, width, height);
|
||||
|
||||
xwl_screen->width = width;
|
||||
xwl_screen->height = height;
|
||||
xwl_screen->screen->width = width;
|
||||
xwl_screen->screen->height = height;
|
||||
xwl_screen->screen->mmWidth = (width * 25.4) / monitorResolution;
|
||||
xwl_screen->screen->mmHeight = (height * 25.4) / monitorResolution;
|
||||
|
||||
SetRootClip(xwl_screen->screen, xwl_screen->root_clip_mode);
|
||||
|
||||
if (xwl_screen->screen->root) {
|
||||
BoxRec box = { 0, 0, width, height };
|
||||
|
||||
xwl_screen->screen->root->drawable.width = width;
|
||||
xwl_screen->screen->root->drawable.height = height;
|
||||
RegionReset(&xwl_screen->screen->root->winSize, &box);
|
||||
RRScreenSizeNotify(xwl_screen->screen);
|
||||
}
|
||||
|
||||
update_desktop_dimensions();
|
||||
|
||||
RRTellChanged(xwl_screen->screen);
|
||||
}
|
||||
|
||||
struct xwl_emulated_mode *
|
||||
xwl_output_get_emulated_mode_for_client(struct xwl_output *xwl_output,
|
||||
ClientPtr client)
|
||||
{
|
||||
struct xwl_client *xwl_client = xwl_client_get(client);
|
||||
int i;
|
||||
|
||||
if (!xwl_output)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < XWL_CLIENT_MAX_EMULATED_MODES; i++) {
|
||||
if (xwl_client->emulated_modes[i].server_output_id ==
|
||||
xwl_output->server_output_id)
|
||||
return &xwl_client->emulated_modes[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_output_add_emulated_mode_for_client(struct xwl_output *xwl_output,
|
||||
ClientPtr client,
|
||||
RRModePtr mode,
|
||||
Bool from_vidmode)
|
||||
{
|
||||
struct xwl_client *xwl_client = xwl_client_get(client);
|
||||
struct xwl_emulated_mode *emulated_mode;
|
||||
int i;
|
||||
|
||||
emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
|
||||
if (!emulated_mode) {
|
||||
/* Find a free spot in the emulated modes array */
|
||||
for (i = 0; i < XWL_CLIENT_MAX_EMULATED_MODES; i++) {
|
||||
if (xwl_client->emulated_modes[i].server_output_id == 0) {
|
||||
emulated_mode = &xwl_client->emulated_modes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!emulated_mode) {
|
||||
static Bool warned;
|
||||
|
||||
if (!warned) {
|
||||
ErrorF("Ran out of space for emulated-modes, not adding mode");
|
||||
warned = TRUE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
emulated_mode->server_output_id = xwl_output->server_output_id;
|
||||
emulated_mode->width = mode->mode.width;
|
||||
emulated_mode->height = mode->mode.height;
|
||||
emulated_mode->from_vidmode = from_vidmode;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_output_remove_emulated_mode_for_client(struct xwl_output *xwl_output,
|
||||
ClientPtr client)
|
||||
{
|
||||
struct xwl_emulated_mode *emulated_mode;
|
||||
|
||||
emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
|
||||
if (emulated_mode) {
|
||||
DebugF("XWAYLAND: xwl_output_remove_emulated_mode: %dx%d\n",
|
||||
emulated_mode->width, emulated_mode->height);
|
||||
memset(emulated_mode, 0, sizeof(*emulated_mode));
|
||||
}
|
||||
}
|
||||
|
||||
/* From hw/xfree86/common/xf86DefModeSet.c with some obscure modes dropped */
|
||||
const int32_t xwl_output_fake_modes[][2] = {
|
||||
/* 4:3 (1.33) */
|
||||
{ 2048, 1536 },
|
||||
{ 1920, 1440 },
|
||||
{ 1600, 1200 },
|
||||
{ 1440, 1080 },
|
||||
{ 1400, 1050 },
|
||||
{ 1280, 1024 }, /* 5:4 (1.25) */
|
||||
{ 1280, 960 },
|
||||
{ 1152, 864 },
|
||||
{ 1024, 768 },
|
||||
{ 800, 600 },
|
||||
{ 640, 480 },
|
||||
{ 320, 240 },
|
||||
/* 16:10 (1.6) */
|
||||
{ 2560, 1600 },
|
||||
{ 1920, 1200 },
|
||||
{ 1680, 1050 },
|
||||
{ 1440, 900 },
|
||||
{ 1280, 800 },
|
||||
{ 720, 480 }, /* 3:2 (1.5) */
|
||||
{ 640, 400 },
|
||||
{ 320, 200 },
|
||||
/* 16:9 (1.77) */
|
||||
{ 5120, 2880 },
|
||||
{ 4096, 2304 },
|
||||
{ 3840, 2160 },
|
||||
{ 3200, 1800 },
|
||||
{ 2880, 1620 },
|
||||
{ 2560, 1440 },
|
||||
{ 2048, 1152 },
|
||||
{ 1920, 1080 },
|
||||
{ 1600, 900 },
|
||||
{ 1368, 768 },
|
||||
{ 1280, 720 },
|
||||
{ 1024, 576 },
|
||||
{ 864, 486 },
|
||||
{ 720, 400 },
|
||||
{ 640, 350 },
|
||||
};
|
||||
|
||||
/* Build an array with RRModes the first mode is the actual output mode, the
|
||||
* rest are fake modes from the xwl_output_fake_modes list. We do this for apps
|
||||
* which want to change resolution when they go fullscreen.
|
||||
* When an app requests a mode-change, we fake it using WPviewport.
|
||||
*/
|
||||
static RRModePtr *
|
||||
output_get_rr_modes(struct xwl_output *xwl_output,
|
||||
int32_t width, int32_t height,
|
||||
int *count)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||
RRModePtr *rr_modes;
|
||||
int i;
|
||||
|
||||
rr_modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 1, sizeof(RRModePtr));
|
||||
if (!rr_modes)
|
||||
goto err;
|
||||
|
||||
/* Add actual output mode */
|
||||
rr_modes[0] = xwayland_cvt(width, height, xwl_output->refresh / 1000.0, 0, 0);
|
||||
if (!rr_modes[0])
|
||||
goto err;
|
||||
|
||||
*count = 1;
|
||||
|
||||
if (!xwl_screen_has_resolution_change_emulation(xwl_screen))
|
||||
return rr_modes;
|
||||
|
||||
/* Add fake modes */
|
||||
for (i = 0; i < ARRAY_SIZE(xwl_output_fake_modes); i++) {
|
||||
/* Skip actual output mode, already added */
|
||||
if (xwl_output_fake_modes[i][0] == width &&
|
||||
xwl_output_fake_modes[i][1] == height)
|
||||
continue;
|
||||
|
||||
/* Skip modes which are too big, avoid downscaling */
|
||||
if (xwl_output_fake_modes[i][0] > width ||
|
||||
xwl_output_fake_modes[i][1] > height)
|
||||
continue;
|
||||
|
||||
rr_modes[*count] = xwayland_cvt(xwl_output_fake_modes[i][0],
|
||||
xwl_output_fake_modes[i][1],
|
||||
xwl_output->refresh / 1000.0, 0, 0);
|
||||
if (!rr_modes[*count])
|
||||
goto err;
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
return rr_modes;
|
||||
err:
|
||||
FatalError("Failed to allocate memory for list of RR modes");
|
||||
}
|
||||
|
||||
RRModePtr
|
||||
xwl_output_find_mode(struct xwl_output *xwl_output,
|
||||
int32_t width, int32_t height)
|
||||
{
|
||||
RROutputPtr output = xwl_output->randr_output;
|
||||
int i;
|
||||
|
||||
/* width & height -1 means we want the actual output mode, which is idx 0 */
|
||||
if (width == -1 && height == -1 && output->modes)
|
||||
return output->modes[0];
|
||||
|
||||
for (i = 0; i < output->numModes; i++) {
|
||||
if (output->modes[i]->mode.width == width && output->modes[i]->mode.height == height)
|
||||
return output->modes[i];
|
||||
}
|
||||
|
||||
ErrorF("XWAYLAND: mode %dx%d is not available\n", width, height);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct xwl_output_randr_emu_prop {
|
||||
Atom atom;
|
||||
uint32_t rects[XWL_CLIENT_MAX_EMULATED_MODES][4];
|
||||
int rect_count;
|
||||
};
|
||||
|
||||
static void
|
||||
xwl_output_randr_emu_prop(struct xwl_screen *xwl_screen, ClientPtr client,
|
||||
struct xwl_output_randr_emu_prop *prop)
|
||||
{
|
||||
static const char atom_name[] = "_XWAYLAND_RANDR_EMU_MONITOR_RECTS";
|
||||
struct xwl_emulated_mode *emulated_mode;
|
||||
struct xwl_output *xwl_output;
|
||||
int index = 0;
|
||||
|
||||
prop->atom = MakeAtom(atom_name, strlen(atom_name), TRUE);
|
||||
|
||||
xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
|
||||
emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
|
||||
if (!emulated_mode)
|
||||
continue;
|
||||
|
||||
prop->rects[index][0] = xwl_output->x;
|
||||
prop->rects[index][1] = xwl_output->y;
|
||||
prop->rects[index][2] = emulated_mode->width;
|
||||
prop->rects[index][3] = emulated_mode->height;
|
||||
index++;
|
||||
}
|
||||
|
||||
prop->rect_count = index;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_output_set_randr_emu_prop(WindowPtr window,
|
||||
struct xwl_output_randr_emu_prop *prop)
|
||||
{
|
||||
if (prop->rect_count) {
|
||||
dixChangeWindowProperty(serverClient, window, prop->atom,
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
prop->rect_count * 4, prop->rects, TRUE);
|
||||
} else {
|
||||
DeleteProperty(serverClient, window, prop->atom);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_output_set_randr_emu_prop_callback(void *resource, XID id, void *user_data)
|
||||
{
|
||||
if (xwl_window_is_toplevel(resource))
|
||||
xwl_output_set_randr_emu_prop(resource, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_output_set_randr_emu_props(struct xwl_screen *xwl_screen, ClientPtr client)
|
||||
{
|
||||
struct xwl_output_randr_emu_prop prop = {};
|
||||
|
||||
xwl_output_randr_emu_prop(xwl_screen, client, &prop);
|
||||
FindClientResourcesByType(client, RT_WINDOW,
|
||||
xwl_output_set_randr_emu_prop_callback, &prop);
|
||||
}
|
||||
|
||||
void
|
||||
xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
|
||||
WindowPtr window)
|
||||
{
|
||||
struct xwl_output_randr_emu_prop prop = {};
|
||||
|
||||
xwl_output_randr_emu_prop(xwl_screen, wClient(window), &prop);
|
||||
xwl_output_set_randr_emu_prop(window, &prop);
|
||||
}
|
||||
|
||||
void
|
||||
xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
|
||||
RRModePtr mode, Bool from_vidmode)
|
||||
{
|
||||
DebugF("XWAYLAND: xwl_output_set_emulated_mode from %s: %dx%d\n",
|
||||
from_vidmode ? "vidmode" : "randr",
|
||||
mode->mode.width, mode->mode.height);
|
||||
|
||||
/* modes[0] is the actual (not-emulated) output mode */
|
||||
if (mode == xwl_output->randr_output->modes[0])
|
||||
xwl_output_remove_emulated_mode_for_client(xwl_output, client);
|
||||
else
|
||||
xwl_output_add_emulated_mode_for_client(xwl_output, client, mode, from_vidmode);
|
||||
|
||||
xwl_screen_check_resolution_change_emulation(xwl_output->xwl_screen);
|
||||
|
||||
xwl_output_set_randr_emu_props(xwl_output->xwl_screen, client);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_output_change(struct xwl_output *xwl_output)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||
struct xwl_output *it;
|
||||
int mode_width, mode_height, count;
|
||||
int width = 0, height = 0, has_this_output = 0;
|
||||
RRModePtr *randr_modes;
|
||||
|
||||
/* Clear out the "done" received flags */
|
||||
xwl_output->wl_output_done = FALSE;
|
||||
xwl_output->xdg_output_done = FALSE;
|
||||
|
||||
/* When we have received an xdg-output for the mode size we might need to
|
||||
* rotate back the stored logical size it provided.
|
||||
*/
|
||||
if (xwl_output->xdg_output == NULL
|
||||
|| xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
|
||||
mode_width = xwl_output->width;
|
||||
mode_height = xwl_output->height;
|
||||
} else {
|
||||
mode_width = xwl_output->height;
|
||||
mode_height = xwl_output->width;
|
||||
}
|
||||
|
||||
/* Build a fresh modes array using the current refresh rate */
|
||||
randr_modes = output_get_rr_modes(xwl_output, mode_width, mode_height, &count);
|
||||
RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1);
|
||||
RRCrtcNotify(xwl_output->randr_crtc, randr_modes[0],
|
||||
xwl_output->x, xwl_output->y,
|
||||
xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
|
||||
/* RROutputSetModes takes ownership of the passed in modes, so we only
|
||||
* have to free the pointer array.
|
||||
*/
|
||||
free(randr_modes);
|
||||
|
||||
xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
|
||||
/* output done event is sent even when some property
|
||||
* of output is changed. That means that we may already
|
||||
* have this output. If it is true, we must not add it
|
||||
* into the output_list otherwise we'll corrupt it */
|
||||
if (it == xwl_output)
|
||||
has_this_output = 1;
|
||||
|
||||
output_get_new_size(it, &width, &height);
|
||||
}
|
||||
|
||||
if (!has_this_output) {
|
||||
xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
|
||||
|
||||
/* we did not check this output for new screen size, do it now */
|
||||
output_get_new_size(xwl_output, &width, &height);
|
||||
|
||||
--xwl_screen->expecting_event;
|
||||
}
|
||||
|
||||
update_screen_size(xwl_output, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_done(void *data, struct wl_output *wl_output)
|
||||
{
|
||||
struct xwl_output *xwl_output = data;
|
||||
|
||||
xwl_output->wl_output_done = TRUE;
|
||||
/* Apply the changes from wl_output only if both "done" events are received,
|
||||
* if xdg-output is not supported or if xdg-output version is high enough.
|
||||
*/
|
||||
if (xwl_output->xdg_output_done || !xwl_output->xdg_output ||
|
||||
zxdg_output_v1_get_version(xwl_output->xdg_output) >= 3)
|
||||
apply_output_change(xwl_output);
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_scale(void *data, struct wl_output *wl_output, int32_t factor)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_output_listener output_listener = {
|
||||
output_handle_geometry,
|
||||
output_handle_mode,
|
||||
output_handle_done,
|
||||
output_handle_scale
|
||||
};
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
int32_t x, int32_t y)
|
||||
{
|
||||
struct xwl_output *xwl_output = data;
|
||||
|
||||
xwl_output->x = x;
|
||||
xwl_output->y = y;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
int32_t width, int32_t height)
|
||||
{
|
||||
struct xwl_output *xwl_output = data;
|
||||
|
||||
xwl_output->width = width;
|
||||
xwl_output->height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output)
|
||||
{
|
||||
struct xwl_output *xwl_output = data;
|
||||
|
||||
xwl_output->xdg_output_done = TRUE;
|
||||
if (xwl_output->wl_output_done &&
|
||||
zxdg_output_v1_get_version(xdg_output) < 3)
|
||||
apply_output_change(xwl_output);
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
const char *name)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
const char *description)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct zxdg_output_v1_listener xdg_output_listener = {
|
||||
xdg_output_handle_logical_position,
|
||||
xdg_output_handle_logical_size,
|
||||
xdg_output_handle_done,
|
||||
xdg_output_handle_name,
|
||||
xdg_output_handle_description,
|
||||
};
|
||||
|
||||
struct xwl_output *
|
||||
xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
|
||||
{
|
||||
struct xwl_output *xwl_output;
|
||||
static int serial;
|
||||
char name[256];
|
||||
|
||||
xwl_output = calloc(1, sizeof *xwl_output);
|
||||
if (xwl_output == NULL) {
|
||||
ErrorF("%s ENOMEM\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xwl_output->output = wl_registry_bind(xwl_screen->registry, id,
|
||||
&wl_output_interface, 2);
|
||||
if (!xwl_output->output) {
|
||||
ErrorF("Failed binding wl_output\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
xwl_output->server_output_id = id;
|
||||
wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
|
||||
|
||||
snprintf(name, sizeof name, "XWAYLAND%d", serial++);
|
||||
|
||||
xwl_output->xwl_screen = xwl_screen;
|
||||
xwl_output->randr_crtc = RRCrtcCreate(xwl_screen->screen, xwl_output);
|
||||
if (!xwl_output->randr_crtc) {
|
||||
ErrorF("Failed creating RandR CRTC\n");
|
||||
goto err;
|
||||
}
|
||||
RRCrtcSetRotations (xwl_output->randr_crtc, ALL_ROTATIONS);
|
||||
|
||||
xwl_output->randr_output = RROutputCreate(xwl_screen->screen, name,
|
||||
strlen(name), xwl_output);
|
||||
if (!xwl_output->randr_output) {
|
||||
ErrorF("Failed creating RandR Output\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
RRCrtcGammaSetSize(xwl_output->randr_crtc, 256);
|
||||
RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1);
|
||||
RROutputSetConnection(xwl_output->randr_output, RR_Connected);
|
||||
RRTellChanged(xwl_screen->screen);
|
||||
|
||||
/* We want the output to be in the list as soon as created so we can
|
||||
* use it when binding to the xdg-output protocol...
|
||||
*/
|
||||
xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
|
||||
--xwl_screen->expecting_event;
|
||||
|
||||
if (xwl_screen->xdg_output_manager)
|
||||
xwl_output_get_xdg_output(xwl_output);
|
||||
|
||||
return xwl_output;
|
||||
|
||||
err:
|
||||
if (xwl_output->randr_crtc)
|
||||
RRCrtcDestroy(xwl_output->randr_crtc);
|
||||
if (xwl_output->output)
|
||||
wl_output_destroy(xwl_output->output);
|
||||
free(xwl_output);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
xwl_output_destroy(struct xwl_output *xwl_output)
|
||||
{
|
||||
if (xwl_output->xdg_output)
|
||||
zxdg_output_v1_destroy(xwl_output->xdg_output);
|
||||
wl_output_destroy(xwl_output->output);
|
||||
free(xwl_output);
|
||||
}
|
||||
|
||||
void
|
||||
xwl_output_remove(struct xwl_output *xwl_output)
|
||||
{
|
||||
struct xwl_output *it;
|
||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||
int width = 0, height = 0;
|
||||
|
||||
xorg_list_del(&xwl_output->link);
|
||||
|
||||
xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
|
||||
output_get_new_size(it, &width, &height);
|
||||
update_screen_size(xwl_output, width, height);
|
||||
|
||||
RRCrtcDestroy(xwl_output->randr_crtc);
|
||||
RROutputDestroy(xwl_output->randr_output);
|
||||
RRTellChanged(xwl_screen->screen);
|
||||
|
||||
xwl_output_destroy(xwl_output);
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_randr_get_info(ScreenPtr pScreen, Rotation * rotations)
|
||||
{
|
||||
*rotations = ALL_ROTATIONS;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef RANDR_10_INTERFACE
|
||||
static Bool
|
||||
xwl_randr_set_config(ScreenPtr pScreen,
|
||||
Rotation rotation, int rate, RRScreenSizePtr pSize)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RANDR_12_INTERFACE
|
||||
static Bool
|
||||
xwl_randr_screen_set_size(ScreenPtr pScreen,
|
||||
CARD16 width,
|
||||
CARD16 height,
|
||||
CARD32 mmWidth, CARD32 mmHeight)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_randr_crtc_set(ScreenPtr pScreen,
|
||||
RRCrtcPtr crtc,
|
||||
RRModePtr new_mode,
|
||||
int x,
|
||||
int y,
|
||||
Rotation rotation,
|
||||
int numOutputs, RROutputPtr * outputs)
|
||||
{
|
||||
struct xwl_output *xwl_output = crtc->devPrivate;
|
||||
RRModePtr mode;
|
||||
|
||||
if (new_mode) {
|
||||
mode = xwl_output_find_mode(xwl_output,
|
||||
new_mode->mode.width,
|
||||
new_mode->mode.height);
|
||||
} else {
|
||||
mode = xwl_output_find_mode(xwl_output, -1, -1);
|
||||
}
|
||||
if (!mode)
|
||||
return FALSE;
|
||||
|
||||
xwl_output_set_emulated_mode(xwl_output, GetCurrentClient(), mode, FALSE);
|
||||
|
||||
/* A real randr implementation would call:
|
||||
* RRCrtcNotify(xwl_output->randr_crtc, mode, xwl_output->x, xwl_output->y,
|
||||
* xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
|
||||
* here to update the mode reported to clients querying the randr settings
|
||||
* but that influences *all* clients and we do randr mode change emulation
|
||||
* on a per client basis. So we just return success here.
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_randr_crtc_set_gamma(ScreenPtr pScreen, RRCrtcPtr crtc)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_randr_crtc_get_gamma(ScreenPtr pScreen, RRCrtcPtr crtc)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_randr_output_set_property(ScreenPtr pScreen,
|
||||
RROutputPtr output,
|
||||
Atom property,
|
||||
RRPropertyValuePtr value)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_output_validate_mode(ScreenPtr pScreen,
|
||||
RROutputPtr output,
|
||||
RRModePtr mode)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_randr_mode_destroy(ScreenPtr pScreen, RRModePtr mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Bool
|
||||
xwl_screen_init_output(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
rrScrPrivPtr rp;
|
||||
|
||||
if (!RRScreenInit(xwl_screen->screen))
|
||||
return FALSE;
|
||||
|
||||
RRScreenSetSizeRange(xwl_screen->screen, 16, 16, 32767, 32767);
|
||||
|
||||
rp = rrGetScrPriv(xwl_screen->screen);
|
||||
rp->rrGetInfo = xwl_randr_get_info;
|
||||
|
||||
#if RANDR_10_INTERFACE
|
||||
rp->rrSetConfig = xwl_randr_set_config;
|
||||
#endif
|
||||
|
||||
#if RANDR_12_INTERFACE
|
||||
rp->rrScreenSetSize = xwl_randr_screen_set_size;
|
||||
rp->rrCrtcSet = xwl_randr_crtc_set;
|
||||
rp->rrCrtcSetGamma = xwl_randr_crtc_set_gamma;
|
||||
rp->rrCrtcGetGamma = xwl_randr_crtc_get_gamma;
|
||||
rp->rrOutputSetProperty = xwl_randr_output_set_property;
|
||||
rp->rrOutputValidateMode = xwl_output_validate_mode;
|
||||
rp->rrModeDestroy = xwl_randr_mode_destroy;
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_output_get_xdg_output(struct xwl_output *xwl_output)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||
|
||||
xwl_output->xdg_output =
|
||||
zxdg_output_manager_v1_get_xdg_output (xwl_screen->xdg_output_manager,
|
||||
xwl_output->output);
|
||||
|
||||
zxdg_output_v1_add_listener(xwl_output->xdg_output,
|
||||
&xdg_output_listener,
|
||||
xwl_output);
|
||||
}
|
||||
|
||||
void
|
||||
xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
struct xwl_output *it;
|
||||
|
||||
assert(xwl_screen->xdg_output_manager);
|
||||
|
||||
xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
|
||||
xwl_output_get_xdg_output(it);
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2011-2014 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XWAYLAND_OUTPUT_H
|
||||
#define XWAYLAND_OUTPUT_H
|
||||
|
||||
#include <xwayland-config.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include <dix.h>
|
||||
#include <input.h>
|
||||
#include <randrstr.h>
|
||||
|
||||
#include "xwayland-types.h"
|
||||
|
||||
struct xwl_output {
|
||||
struct xorg_list link;
|
||||
struct wl_output *output;
|
||||
struct zxdg_output_v1 *xdg_output;
|
||||
uint32_t server_output_id;
|
||||
struct xwl_screen *xwl_screen;
|
||||
RROutputPtr randr_output;
|
||||
RRCrtcPtr randr_crtc;
|
||||
int32_t x, y, width, height, refresh;
|
||||
Rotation rotation;
|
||||
Bool wl_output_done;
|
||||
Bool xdg_output_done;
|
||||
};
|
||||
|
||||
/* Per client per output emulated randr/vidmode resolution info. */
|
||||
struct xwl_emulated_mode {
|
||||
uint32_t server_output_id;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
Bool from_vidmode;
|
||||
};
|
||||
|
||||
Bool xwl_screen_init_output(struct xwl_screen *xwl_screen);
|
||||
|
||||
struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen,
|
||||
uint32_t id);
|
||||
|
||||
void xwl_output_destroy(struct xwl_output *xwl_output);
|
||||
|
||||
void xwl_output_remove(struct xwl_output *xwl_output);
|
||||
|
||||
struct xwl_emulated_mode *xwl_output_get_emulated_mode_for_client(
|
||||
struct xwl_output *xwl_output, ClientPtr client);
|
||||
|
||||
RRModePtr xwl_output_find_mode(struct xwl_output *xwl_output,
|
||||
int32_t width, int32_t height);
|
||||
void xwl_output_set_emulated_mode(struct xwl_output *xwl_output,
|
||||
ClientPtr client, RRModePtr mode,
|
||||
Bool from_vidmode);
|
||||
void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
|
||||
WindowPtr window);
|
||||
|
||||
void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
|
||||
|
||||
#endif /* XWAYLAND_OUTPUT_H */
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2014 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include <X11/X.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "privates.h"
|
||||
#include "dix.h"
|
||||
#include "fb.h"
|
||||
#include "pixmapstr.h"
|
||||
|
||||
#include "xwayland-types.h"
|
||||
#include "xwayland-pixmap.h"
|
||||
#include "xwayland-window-buffers.h"
|
||||
|
||||
static DevPrivateKeyRec xwl_pixmap_private_key;
|
||||
static DevPrivateKeyRec xwl_pixmap_cb_private_key;
|
||||
|
||||
struct xwl_pixmap_buffer_release_callback {
|
||||
xwl_buffer_release_cb callback;
|
||||
void *data;
|
||||
};
|
||||
|
||||
void
|
||||
xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap)
|
||||
{
|
||||
dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key, xwl_pixmap);
|
||||
}
|
||||
|
||||
struct xwl_pixmap *
|
||||
xwl_pixmap_get(PixmapPtr pixmap)
|
||||
{
|
||||
return dixLookupPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key);
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_pixmap_set_buffer_release_cb(PixmapPtr pixmap,
|
||||
xwl_buffer_release_cb func, void *data)
|
||||
{
|
||||
struct xwl_pixmap_buffer_release_callback *xwl_pixmap_buffer_release_callback;
|
||||
|
||||
xwl_pixmap_buffer_release_callback = dixLookupPrivate(&pixmap->devPrivates,
|
||||
&xwl_pixmap_cb_private_key);
|
||||
|
||||
if (xwl_pixmap_buffer_release_callback == NULL) {
|
||||
xwl_pixmap_buffer_release_callback =
|
||||
calloc(1, sizeof (struct xwl_pixmap_buffer_release_callback));
|
||||
|
||||
if (xwl_pixmap_buffer_release_callback == NULL) {
|
||||
ErrorF("Failed to allocate pixmap callback data\n");
|
||||
return FALSE;
|
||||
}
|
||||
dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_cb_private_key,
|
||||
xwl_pixmap_buffer_release_callback);
|
||||
}
|
||||
|
||||
xwl_pixmap_buffer_release_callback->callback = func;
|
||||
xwl_pixmap_buffer_release_callback->data = data;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
xwl_pixmap_del_buffer_release_cb(PixmapPtr pixmap)
|
||||
{
|
||||
struct xwl_pixmap_buffer_release_callback *xwl_pixmap_buffer_release_callback;
|
||||
|
||||
xwl_pixmap_buffer_release_callback = dixLookupPrivate(&pixmap->devPrivates,
|
||||
&xwl_pixmap_cb_private_key);
|
||||
if (xwl_pixmap_buffer_release_callback) {
|
||||
dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_cb_private_key, NULL);
|
||||
free(xwl_pixmap_buffer_release_callback);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xwl_pixmap_buffer_release_cb(void *data, struct wl_buffer *wl_buffer)
|
||||
{
|
||||
PixmapPtr pixmap = data;
|
||||
struct xwl_pixmap_buffer_release_callback *xwl_pixmap_buffer_release_callback;
|
||||
|
||||
xwl_pixmap_buffer_release_callback = dixLookupPrivate(&pixmap->devPrivates,
|
||||
&xwl_pixmap_cb_private_key);
|
||||
if (xwl_pixmap_buffer_release_callback)
|
||||
(*xwl_pixmap_buffer_release_callback->callback)
|
||||
(xwl_pixmap_buffer_release_callback->data);
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_pixmap_init(void)
|
||||
{
|
||||
if (!dixRegisterPrivateKey(&xwl_pixmap_private_key, PRIVATE_PIXMAP, 0))
|
||||
return FALSE;
|
||||
|
||||
if (!dixRegisterPrivateKey(&xwl_pixmap_cb_private_key, PRIVATE_PIXMAP, 0))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2014 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XWAYLAND_PIXMAP_H
|
||||
#define XWAYLAND_PIXMAP_H
|
||||
|
||||
#include <xwayland-config.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include "pixmapstr.h"
|
||||
|
||||
/* This is an opaque structure implemented in the different backends */
|
||||
struct xwl_pixmap;
|
||||
|
||||
typedef void (*xwl_buffer_release_cb) (void *data);
|
||||
|
||||
void xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap);
|
||||
struct xwl_pixmap *xwl_pixmap_get(PixmapPtr pixmap);
|
||||
Bool xwl_pixmap_set_buffer_release_cb(PixmapPtr pixmap,
|
||||
xwl_buffer_release_cb func, void *data);
|
||||
void xwl_pixmap_del_buffer_release_cb(PixmapPtr pixmap);
|
||||
void xwl_pixmap_buffer_release_cb(void *data, struct wl_buffer *wl_buffer);
|
||||
Bool xwl_pixmap_init(void);
|
||||
|
||||
#endif /* XWAYLAND_PIXMAP_H */
|
|
@ -1,965 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2018 Roman Gilg
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include <windowstr.h>
|
||||
#include <present.h>
|
||||
|
||||
#include "xwayland-present.h"
|
||||
#include "xwayland-screen.h"
|
||||
#include "xwayland-window.h"
|
||||
#include "xwayland-pixmap.h"
|
||||
#include "glamor.h"
|
||||
|
||||
|
||||
#define XWL_PRESENT_CAPS PresentCapabilityAsync
|
||||
|
||||
|
||||
/*
|
||||
* When not flipping let Present copy with 60fps.
|
||||
* When flipping wait on frame_callback, otherwise
|
||||
* the surface is not visible, in this case update
|
||||
* with long interval.
|
||||
*/
|
||||
#define TIMER_LEN_COPY 17 // ~60fps
|
||||
#define TIMER_LEN_FLIP 1000 // 1fps
|
||||
|
||||
static DevPrivateKeyRec xwl_present_window_private_key;
|
||||
|
||||
static struct xwl_present_window *
|
||||
xwl_present_window_priv(WindowPtr window)
|
||||
{
|
||||
return dixGetPrivate(&window->devPrivates,
|
||||
&xwl_present_window_private_key);
|
||||
}
|
||||
|
||||
static struct xwl_present_window *
|
||||
xwl_present_window_get_priv(WindowPtr window)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
|
||||
|
||||
if (xwl_present_window == NULL) {
|
||||
xwl_present_window = calloc (1, sizeof (struct xwl_present_window));
|
||||
if (!xwl_present_window)
|
||||
return NULL;
|
||||
|
||||
xwl_present_window->msc = 1;
|
||||
xwl_present_window->ust = GetTimeInMicros();
|
||||
|
||||
xorg_list_init(&xwl_present_window->frame_callback_list);
|
||||
xorg_list_init(&xwl_present_window->wait_list);
|
||||
xorg_list_init(&xwl_present_window->flip_queue);
|
||||
xorg_list_init(&xwl_present_window->idle_queue);
|
||||
|
||||
dixSetPrivate(&window->devPrivates,
|
||||
&xwl_present_window_private_key,
|
||||
xwl_present_window);
|
||||
}
|
||||
|
||||
return xwl_present_window;
|
||||
}
|
||||
|
||||
static struct xwl_present_event *
|
||||
xwl_present_event_from_id(uint64_t event_id)
|
||||
{
|
||||
return (struct xwl_present_event*)(uintptr_t)event_id;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_free_timer(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
TimerFree(xwl_present_window->frame_timer);
|
||||
xwl_present_window->frame_timer = NULL;
|
||||
}
|
||||
|
||||
static CARD32
|
||||
xwl_present_timer_callback(OsTimerPtr timer,
|
||||
CARD32 time,
|
||||
void *arg);
|
||||
|
||||
static present_vblank_ptr
|
||||
xwl_present_get_pending_flip(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
present_vblank_ptr flip_pending;
|
||||
|
||||
if (xorg_list_is_empty(&xwl_present_window->flip_queue))
|
||||
return NULL;
|
||||
|
||||
flip_pending = xorg_list_first_entry(&xwl_present_window->flip_queue, present_vblank_rec,
|
||||
event_queue);
|
||||
|
||||
if (flip_pending->queued)
|
||||
return NULL;
|
||||
|
||||
return flip_pending;
|
||||
}
|
||||
|
||||
static inline Bool
|
||||
xwl_present_has_pending_events(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
|
||||
|
||||
return (flip_pending && flip_pending->sync_flip) ||
|
||||
!xorg_list_is_empty(&xwl_present_window->wait_list);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
if (xwl_present_has_pending_events(xwl_present_window)) {
|
||||
CARD32 timeout;
|
||||
|
||||
if (!xorg_list_is_empty(&xwl_present_window->frame_callback_list))
|
||||
timeout = TIMER_LEN_FLIP;
|
||||
else
|
||||
timeout = TIMER_LEN_COPY;
|
||||
|
||||
xwl_present_window->frame_timer = TimerSet(xwl_present_window->frame_timer,
|
||||
0, timeout,
|
||||
&xwl_present_timer_callback,
|
||||
xwl_present_window);
|
||||
} else {
|
||||
xwl_present_free_timer(xwl_present_window);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
|
||||
|
||||
static uint32_t
|
||||
xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
|
||||
{
|
||||
return XWL_PRESENT_CAPS;
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_present_get_ust_msc(ScreenPtr screen,
|
||||
WindowPtr present_window,
|
||||
uint64_t *ust,
|
||||
uint64_t *msc)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
|
||||
if (!xwl_present_window)
|
||||
return BadAlloc;
|
||||
|
||||
*ust = xwl_present_window->ust;
|
||||
*msc = xwl_present_window->msc;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
/*
|
||||
* When the wait fence or previous flip is completed, it's time
|
||||
* to re-try the request
|
||||
*/
|
||||
static void
|
||||
xwl_present_re_execute(present_vblank_ptr vblank)
|
||||
{
|
||||
uint64_t ust = 0, crtc_msc = 0;
|
||||
|
||||
(void) xwl_present_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
|
||||
xwl_present_execute(vblank, ust, crtc_msc);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_flip_try_ready(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
present_vblank_ptr vblank;
|
||||
|
||||
xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
|
||||
if (vblank->queued) {
|
||||
xwl_present_re_execute(vblank);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_release_pixmap(struct xwl_present_event *event)
|
||||
{
|
||||
if (!event->pixmap)
|
||||
return;
|
||||
|
||||
xwl_pixmap_del_buffer_release_cb(event->pixmap);
|
||||
dixDestroyPixmap(event->pixmap, event->pixmap->drawable.id);
|
||||
event->pixmap = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_free_event(struct xwl_present_event *event)
|
||||
{
|
||||
xwl_present_release_pixmap(event);
|
||||
xorg_list_del(&event->vblank.event_queue);
|
||||
present_vblank_destroy(&event->vblank);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_free_idle_vblank(present_vblank_ptr vblank)
|
||||
{
|
||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
||||
xwl_present_free_event(xwl_present_event_from_id((uintptr_t)vblank));
|
||||
}
|
||||
|
||||
static WindowPtr
|
||||
xwl_present_toplvl_pixmap_window(WindowPtr window)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
PixmapPtr pixmap = (*screen->GetWindowPixmap)(window);
|
||||
WindowPtr w = window;
|
||||
WindowPtr next_w;
|
||||
|
||||
while(w->parent) {
|
||||
next_w = w->parent;
|
||||
if ( (*screen->GetWindowPixmap)(next_w) != pixmap) {
|
||||
break;
|
||||
}
|
||||
w = next_w;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_flips_stop(WindowPtr window)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
|
||||
present_vblank_ptr vblank, tmp;
|
||||
|
||||
/* Change back to the fast refresh rate */
|
||||
xwl_present_reset_timer(xwl_present_window);
|
||||
|
||||
/* Free any left over idle vblanks */
|
||||
xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->idle_queue, event_queue)
|
||||
xwl_present_free_idle_vblank(vblank);
|
||||
|
||||
if (xwl_present_window->flip_active) {
|
||||
xwl_present_free_idle_vblank(xwl_present_window->flip_active);
|
||||
xwl_present_window->flip_active = NULL;
|
||||
}
|
||||
|
||||
xwl_present_flip_try_ready(xwl_present_window);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
||||
{
|
||||
WindowPtr window = vblank->window;
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
|
||||
|
||||
DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 " %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||
vblank->event_id, vblank, vblank->exec_msc, vblank->target_msc,
|
||||
vblank->pixmap ? vblank->pixmap->drawable.id : 0,
|
||||
vblank->window ? vblank->window->drawable.id : 0));
|
||||
|
||||
assert (&vblank->event_queue == xwl_present_window->flip_queue.next);
|
||||
|
||||
xorg_list_del(&vblank->event_queue);
|
||||
|
||||
if (xwl_present_window->flip_active) {
|
||||
struct xwl_present_event *event =
|
||||
xwl_present_event_from_id((uintptr_t)xwl_present_window->flip_active);
|
||||
|
||||
if (!event->pixmap)
|
||||
xwl_present_free_event(event);
|
||||
else
|
||||
/* Put the previous flip in the idle_queue and wait for further notice from
|
||||
* the Wayland compositor
|
||||
*/
|
||||
xorg_list_append(&xwl_present_window->flip_active->event_queue, &xwl_present_window->idle_queue);
|
||||
}
|
||||
|
||||
xwl_present_window->flip_active = vblank;
|
||||
|
||||
present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
|
||||
|
||||
if (vblank->abort_flip)
|
||||
xwl_present_flips_stop(window);
|
||||
|
||||
xwl_present_flip_try_ready(xwl_present_window);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_update_window_crtc(present_window_priv_ptr window_priv, RRCrtcPtr crtc, uint64_t new_msc)
|
||||
{
|
||||
/* Crtc unchanged, no offset. */
|
||||
if (crtc == window_priv->crtc)
|
||||
return;
|
||||
|
||||
/* No crtc earlier to offset against, just set the crtc. */
|
||||
if (window_priv->crtc == PresentCrtcNeverSet) {
|
||||
window_priv->msc_offset = 0;
|
||||
window_priv->crtc = crtc;
|
||||
return;
|
||||
}
|
||||
|
||||
/* In window-mode the last correct msc-offset is always kept
|
||||
* in window-priv struct because msc is saved per window and
|
||||
* not per crtc as in screen-mode.
|
||||
*/
|
||||
window_priv->msc_offset += new_msc - window_priv->msc;
|
||||
window_priv->crtc = crtc;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xwl_present_cleanup(WindowPtr window)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
struct xwl_present_event *event, *tmp;
|
||||
|
||||
if (!xwl_present_window)
|
||||
return;
|
||||
|
||||
xorg_list_del(&xwl_present_window->frame_callback_list);
|
||||
|
||||
if (xwl_present_window->sync_callback) {
|
||||
wl_callback_destroy(xwl_present_window->sync_callback);
|
||||
xwl_present_window->sync_callback = NULL;
|
||||
}
|
||||
|
||||
/* Clear remaining events */
|
||||
xorg_list_for_each_entry_safe(event, tmp, &window_priv->vblank, vblank.window_list)
|
||||
xwl_present_free_event(event);
|
||||
|
||||
/* Clear timer */
|
||||
xwl_present_free_timer(xwl_present_window);
|
||||
|
||||
/* Remove from privates so we don't try to access it later */
|
||||
dixSetPrivate(&window->devPrivates,
|
||||
&xwl_present_window_private_key,
|
||||
NULL);
|
||||
|
||||
free(xwl_present_window);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_buffer_release(void *data)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window;
|
||||
struct xwl_present_event *event = data;
|
||||
present_vblank_ptr vblank;
|
||||
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
vblank = &event->vblank;
|
||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
||||
|
||||
xwl_present_window = xwl_present_window_priv(vblank->window);
|
||||
if (xwl_present_window->flip_active == vblank ||
|
||||
xwl_present_get_pending_flip(xwl_present_window) == vblank)
|
||||
xwl_present_release_pixmap(event);
|
||||
else
|
||||
xwl_present_free_event(event);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
|
||||
uint64_t msc = ++xwl_present_window->msc;
|
||||
present_vblank_ptr vblank, tmp;
|
||||
|
||||
xwl_present_window->ust = GetTimeInMicros();
|
||||
|
||||
if (flip_pending && flip_pending->sync_flip)
|
||||
xwl_present_flip_notify_vblank(flip_pending, xwl_present_window->ust, msc);
|
||||
|
||||
xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->wait_list, event_queue) {
|
||||
if (vblank->exec_msc <= msc) {
|
||||
DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n",
|
||||
vblank->event_id, xwl_present_window->ust, msc));
|
||||
|
||||
xwl_present_execute(vblank, xwl_present_window->ust, msc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static CARD32
|
||||
xwl_present_timer_callback(OsTimerPtr timer,
|
||||
CARD32 time,
|
||||
void *arg)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = arg;
|
||||
|
||||
/* If we were expecting a frame callback for this window, it didn't arrive
|
||||
* in a second. Stop listening to it to avoid double-bumping the MSC
|
||||
*/
|
||||
xorg_list_del(&xwl_present_window->frame_callback_list);
|
||||
|
||||
xwl_present_msc_bump(xwl_present_window);
|
||||
xwl_present_reset_timer(xwl_present_window);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
xwl_present_frame_callback(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
xorg_list_del(&xwl_present_window->frame_callback_list);
|
||||
|
||||
xwl_present_msc_bump(xwl_present_window);
|
||||
|
||||
/* we do not need the timer anymore for this frame,
|
||||
* reset it for potentially the next one
|
||||
*/
|
||||
xwl_present_reset_timer(xwl_present_window);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_sync_callback(void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
present_vblank_ptr vblank = data;
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(vblank->window);
|
||||
|
||||
wl_callback_destroy(xwl_present_window->sync_callback);
|
||||
xwl_present_window->sync_callback = NULL;
|
||||
|
||||
xwl_present_flip_notify_vblank(vblank, xwl_present_window->ust, xwl_present_window->msc);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener xwl_present_sync_listener = {
|
||||
xwl_present_sync_callback
|
||||
};
|
||||
|
||||
static RRCrtcPtr
|
||||
xwl_present_get_crtc(present_screen_priv_ptr screen_priv,
|
||||
WindowPtr present_window)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
|
||||
rrScrPrivPtr rr_private;
|
||||
|
||||
if (xwl_present_window == NULL)
|
||||
return NULL;
|
||||
|
||||
rr_private = rrGetScrPriv(present_window->drawable.pScreen);
|
||||
|
||||
if (rr_private->numCrtcs == 0)
|
||||
return NULL;
|
||||
|
||||
return rr_private->crtcs[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue an event to report back to the Present extension when the specified
|
||||
* MSC has passed
|
||||
*/
|
||||
static int
|
||||
xwl_present_queue_vblank(ScreenPtr screen,
|
||||
WindowPtr present_window,
|
||||
RRCrtcPtr crtc,
|
||||
uint64_t event_id,
|
||||
uint64_t msc)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
|
||||
struct xwl_window *xwl_window = xwl_window_from_window(present_window);
|
||||
struct xwl_present_event *event = xwl_present_event_from_id(event_id);
|
||||
|
||||
event->vblank.exec_msc = msc;
|
||||
|
||||
xorg_list_del(&event->vblank.event_queue);
|
||||
xorg_list_append(&event->vblank.event_queue, &xwl_present_window->wait_list);
|
||||
|
||||
/* If there's a pending frame callback, use that */
|
||||
if (xwl_window && xwl_window->frame_callback &&
|
||||
xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
|
||||
xorg_list_add(&xwl_present_window->frame_callback_list,
|
||||
&xwl_window->frame_callback_list);
|
||||
}
|
||||
|
||||
if ((xwl_window && xwl_window->frame_callback) ||
|
||||
!xwl_present_window->frame_timer)
|
||||
xwl_present_reset_timer(xwl_present_window);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a pending vblank event so that it is not reported
|
||||
* to the extension
|
||||
*/
|
||||
static void
|
||||
xwl_present_abort_vblank(ScreenPtr screen,
|
||||
WindowPtr present_window,
|
||||
RRCrtcPtr crtc,
|
||||
uint64_t event_id,
|
||||
uint64_t msc)
|
||||
{
|
||||
static Bool called;
|
||||
|
||||
if (called)
|
||||
return;
|
||||
|
||||
/* xwl_present_cleanup should have cleaned up everything,
|
||||
* present_free_window_vblank shouldn't need to call this.
|
||||
*/
|
||||
ErrorF("Unexpected call to %s:\n", __func__);
|
||||
xorg_backtrace();
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_flush(WindowPtr window)
|
||||
{
|
||||
glamor_block_handler(window->drawable.pScreen);
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_present_check_flip(RRCrtcPtr crtc,
|
||||
WindowPtr present_window,
|
||||
PixmapPtr pixmap,
|
||||
Bool sync_flip,
|
||||
RegionPtr valid,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
PresentFlipReason *reason)
|
||||
{
|
||||
WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(present_window);
|
||||
struct xwl_window *xwl_window = xwl_window_from_window(present_window);
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
|
||||
if (reason)
|
||||
*reason = PRESENT_FLIP_REASON_UNKNOWN;
|
||||
|
||||
if (!xwl_window)
|
||||
return FALSE;
|
||||
|
||||
if (!crtc)
|
||||
return FALSE;
|
||||
|
||||
/* Source pixmap must align with window exactly */
|
||||
if (x_off || y_off)
|
||||
return FALSE;
|
||||
|
||||
/* Valid area must contain window (for simplicity for now just never flip when one is set). */
|
||||
if (valid)
|
||||
return FALSE;
|
||||
|
||||
/* Flip pixmap must have same dimensions as window */
|
||||
if (present_window->drawable.width != pixmap->drawable.width ||
|
||||
present_window->drawable.height != pixmap->drawable.height)
|
||||
return FALSE;
|
||||
|
||||
/* Window must be same region as toplevel window */
|
||||
if ( !RegionEqual(&present_window->winSize, &toplvl_window->winSize) )
|
||||
return FALSE;
|
||||
|
||||
/* Can't flip if window clipped by children */
|
||||
if (!RegionEqual(&present_window->clipList, &present_window->winSize))
|
||||
return FALSE;
|
||||
|
||||
if (!xwl_glamor_check_flip(pixmap))
|
||||
return FALSE;
|
||||
|
||||
/* Can't flip if the window pixmap doesn't match the xwl_window parent
|
||||
* window's, e.g. because a client redirected this window or one of its
|
||||
* parents.
|
||||
*/
|
||||
if (screen->GetWindowPixmap(xwl_window->window) != screen->GetWindowPixmap(present_window))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* We currently only allow flips of windows, that have the same
|
||||
* dimensions as their xwl_window parent window. For the case of
|
||||
* different sizes subsurfaces are presumably the way forward.
|
||||
*/
|
||||
if (!RegionEqual(&xwl_window->window->winSize, &present_window->winSize))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* 'window' is being reconfigured. Check to see if it is involved
|
||||
* in flipping and clean up as necessary.
|
||||
*/
|
||||
static void
|
||||
xwl_present_check_flip_window (WindowPtr window)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_vblank_ptr flip_pending;
|
||||
present_vblank_ptr flip_active;
|
||||
present_vblank_ptr vblank;
|
||||
PresentFlipReason reason;
|
||||
|
||||
/* If this window hasn't ever been used with Present, it can't be
|
||||
* flipping
|
||||
*/
|
||||
if (!xwl_present_window || !window_priv)
|
||||
return;
|
||||
|
||||
flip_pending = xwl_present_get_pending_flip(xwl_present_window);
|
||||
flip_active = xwl_present_window->flip_active;
|
||||
|
||||
if (flip_pending) {
|
||||
if (!xwl_present_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap,
|
||||
flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL))
|
||||
flip_pending->abort_flip = TRUE;
|
||||
} else if (flip_active) {
|
||||
if (!xwl_present_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
|
||||
flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
|
||||
xwl_present_flips_stop(window);
|
||||
}
|
||||
|
||||
/* Now check any queued vblanks */
|
||||
xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
|
||||
if (vblank->queued && vblank->flip &&
|
||||
!xwl_present_check_flip(vblank->crtc, window, vblank->pixmap,
|
||||
vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
|
||||
vblank->flip = FALSE;
|
||||
vblank->reason = reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up any pending or current flips for this window
|
||||
*/
|
||||
static void
|
||||
xwl_present_clear_window_flip(WindowPtr window)
|
||||
{
|
||||
/* xwl_present_cleanup cleaned up everything */
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_present_flip(WindowPtr present_window,
|
||||
RRCrtcPtr crtc,
|
||||
uint64_t event_id,
|
||||
PixmapPtr pixmap,
|
||||
Bool sync_flip,
|
||||
RegionPtr damage)
|
||||
{
|
||||
struct xwl_window *xwl_window = xwl_window_from_window(present_window);
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window);
|
||||
BoxPtr damage_box;
|
||||
struct wl_buffer *buffer;
|
||||
struct xwl_present_event *event = xwl_present_event_from_id(event_id);
|
||||
|
||||
if (!xwl_window)
|
||||
return FALSE;
|
||||
|
||||
buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap);
|
||||
if (!buffer) {
|
||||
ErrorF("present: Error getting buffer\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
damage_box = RegionExtents(damage);
|
||||
|
||||
pixmap->refcnt++;
|
||||
|
||||
event->pixmap = pixmap;
|
||||
|
||||
xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event);
|
||||
|
||||
/* We can flip directly to the main surface (full screen window without clips) */
|
||||
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
|
||||
|
||||
if (!xwl_window->frame_callback)
|
||||
xwl_window_create_frame_callback(xwl_window);
|
||||
|
||||
if (xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
|
||||
xorg_list_add(&xwl_present_window->frame_callback_list,
|
||||
&xwl_window->frame_callback_list);
|
||||
}
|
||||
|
||||
/* Realign timer */
|
||||
xwl_present_reset_timer(xwl_present_window);
|
||||
|
||||
xwl_surface_damage(xwl_window->xwl_screen, xwl_window->surface,
|
||||
damage_box->x1 - present_window->drawable.x,
|
||||
damage_box->y1 - present_window->drawable.y,
|
||||
damage_box->x2 - damage_box->x1,
|
||||
damage_box->y2 - damage_box->y1);
|
||||
|
||||
wl_surface_commit(xwl_window->surface);
|
||||
|
||||
if (!sync_flip) {
|
||||
xwl_present_window->sync_callback =
|
||||
wl_display_sync(xwl_window->xwl_screen->display);
|
||||
wl_callback_add_listener(xwl_present_window->sync_callback,
|
||||
&xwl_present_sync_listener,
|
||||
&event->vblank);
|
||||
}
|
||||
|
||||
wl_display_flush(xwl_window->xwl_screen->display);
|
||||
xwl_window->present_flipped = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Once the required MSC has been reached, execute the pending request.
|
||||
*
|
||||
* For requests to actually present something, either blt contents to
|
||||
* the window pixmap or queue a window buffer swap on the backend.
|
||||
*
|
||||
* For requests to just get the current MSC/UST combo, skip that part and
|
||||
* go straight to event delivery.
|
||||
*/
|
||||
static void
|
||||
xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
||||
{
|
||||
WindowPtr window = vblank->window;
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
|
||||
present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
|
||||
|
||||
xorg_list_del(&vblank->event_queue);
|
||||
|
||||
if (present_execute_wait(vblank, crtc_msc))
|
||||
return;
|
||||
|
||||
if (flip_pending && vblank->flip && vblank->pixmap && vblank->window) {
|
||||
DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
|
||||
vblank->event_id, vblank, flip_pending));
|
||||
xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue);
|
||||
vblank->flip_ready = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
vblank->queued = FALSE;
|
||||
|
||||
if (vblank->pixmap && vblank->window) {
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
|
||||
if (vblank->flip) {
|
||||
RegionPtr damage;
|
||||
|
||||
DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||
vblank->event_id, vblank, crtc_msc,
|
||||
vblank->pixmap->drawable.id, vblank->window->drawable.id));
|
||||
|
||||
/* Set update region as damaged */
|
||||
if (vblank->update) {
|
||||
damage = RegionDuplicate(vblank->update);
|
||||
/* Translate update region to screen space */
|
||||
assert(vblank->x_off == 0 && vblank->y_off == 0);
|
||||
RegionTranslate(damage, window->drawable.x, window->drawable.y);
|
||||
RegionIntersect(damage, damage, &window->clipList);
|
||||
} else
|
||||
damage = RegionDuplicate(&window->clipList);
|
||||
|
||||
if (xwl_present_flip(vblank->window, vblank->crtc, vblank->event_id,
|
||||
vblank->pixmap, vblank->sync_flip, damage)) {
|
||||
WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
|
||||
PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
|
||||
|
||||
/* Replace window pixmap with flip pixmap */
|
||||
#ifdef COMPOSITE
|
||||
vblank->pixmap->screen_x = old_pixmap->screen_x;
|
||||
vblank->pixmap->screen_y = old_pixmap->screen_y;
|
||||
#endif
|
||||
present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap);
|
||||
vblank->pixmap->refcnt++;
|
||||
dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
|
||||
|
||||
/* Report damage */
|
||||
DamageDamageRegion(&vblank->window->drawable, damage);
|
||||
RegionDestroy(damage);
|
||||
|
||||
/* Put pending flip at the flip queue head */
|
||||
xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
|
||||
return;
|
||||
}
|
||||
|
||||
vblank->flip = FALSE;
|
||||
}
|
||||
DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||
vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
|
||||
|
||||
if (flip_pending)
|
||||
flip_pending->abort_flip = TRUE;
|
||||
else if (xwl_present_window->flip_active)
|
||||
xwl_present_flips_stop(window);
|
||||
|
||||
present_execute_copy(vblank, crtc_msc);
|
||||
assert(!vblank->queued);
|
||||
|
||||
if (xwl_present_queue_vblank(screen, window, vblank->crtc,
|
||||
vblank->event_id, crtc_msc + 1)
|
||||
== Success) {
|
||||
/* Clear the pixmap field, so this will fall through to present_execute_post next time */
|
||||
dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);
|
||||
vblank->pixmap = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
present_execute_post(vblank, ust, crtc_msc);
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_present_pixmap(WindowPtr window,
|
||||
PixmapPtr pixmap,
|
||||
CARD32 serial,
|
||||
RegionPtr valid,
|
||||
RegionPtr update,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
RRCrtcPtr target_crtc,
|
||||
SyncFence *wait_fence,
|
||||
SyncFence *idle_fence,
|
||||
uint32_t options,
|
||||
uint64_t target_window_msc,
|
||||
uint64_t divisor,
|
||||
uint64_t remainder,
|
||||
present_notify_ptr notifies,
|
||||
int num_notifies)
|
||||
{
|
||||
uint64_t ust = 0;
|
||||
uint64_t target_msc;
|
||||
uint64_t crtc_msc = 0;
|
||||
int ret;
|
||||
present_vblank_ptr vblank, tmp;
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
struct xwl_present_event *event;
|
||||
|
||||
if (!window_priv)
|
||||
return BadAlloc;
|
||||
|
||||
target_crtc = xwl_present_get_crtc(screen_priv, window);
|
||||
|
||||
ret = xwl_present_get_ust_msc(screen, window, &ust, &crtc_msc);
|
||||
|
||||
xwl_present_update_window_crtc(window_priv, target_crtc, crtc_msc);
|
||||
|
||||
if (ret == Success) {
|
||||
/* Stash the current MSC away in case we need it later
|
||||
*/
|
||||
window_priv->msc = crtc_msc;
|
||||
}
|
||||
|
||||
target_msc = present_get_target_msc(target_window_msc + window_priv->msc_offset,
|
||||
crtc_msc,
|
||||
divisor,
|
||||
remainder,
|
||||
options);
|
||||
|
||||
/*
|
||||
* Look for a matching presentation already on the list...
|
||||
*/
|
||||
|
||||
if (!update && pixmap) {
|
||||
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->vblank, window_list) {
|
||||
|
||||
if (!vblank->pixmap)
|
||||
continue;
|
||||
|
||||
if (!vblank->queued)
|
||||
continue;
|
||||
|
||||
if (vblank->target_msc != target_msc)
|
||||
continue;
|
||||
|
||||
present_vblank_scrap(vblank);
|
||||
if (vblank->flip_ready)
|
||||
xwl_present_re_execute(vblank);
|
||||
}
|
||||
}
|
||||
|
||||
event = calloc(1, sizeof(*event));
|
||||
if (!event)
|
||||
return BadAlloc;
|
||||
|
||||
vblank = &event->vblank;
|
||||
if (!present_vblank_init(vblank, window, pixmap, serial, valid, update, x_off, y_off,
|
||||
target_crtc, wait_fence, idle_fence, options, XWL_PRESENT_CAPS,
|
||||
notifies, num_notifies, target_msc, crtc_msc)) {
|
||||
present_vblank_destroy(vblank);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
vblank->event_id = (uintptr_t)event;
|
||||
|
||||
/* Xwayland presentations always complete (at least) one frame after they
|
||||
* are executed
|
||||
*/
|
||||
vblank->exec_msc = vblank->target_msc - 1;
|
||||
|
||||
vblank->queued = TRUE;
|
||||
if (crtc_msc < vblank->exec_msc) {
|
||||
if (xwl_present_queue_vblank(screen, window, target_crtc, vblank->event_id, vblank->exec_msc) == Success)
|
||||
return Success;
|
||||
|
||||
DebugPresent(("present_queue_vblank failed\n"));
|
||||
}
|
||||
|
||||
xwl_present_execute(vblank, ust, crtc_msc);
|
||||
return Success;
|
||||
}
|
||||
|
||||
void
|
||||
xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
/* The pending frame callback may never be called, so drop it and shorten
|
||||
* the frame timer interval.
|
||||
*/
|
||||
xorg_list_del(&xwl_present_window->frame_callback_list);
|
||||
xwl_present_reset_timer(xwl_present_window);
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_present_init(ScreenPtr screen)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
present_screen_priv_ptr screen_priv;
|
||||
|
||||
if (!xwl_screen->glamor || !xwl_screen->egl_backend)
|
||||
return FALSE;
|
||||
|
||||
if (!present_screen_register_priv_keys())
|
||||
return FALSE;
|
||||
|
||||
if (present_screen_priv(screen))
|
||||
return TRUE;
|
||||
|
||||
screen_priv = present_screen_priv_init(screen);
|
||||
if (!screen_priv)
|
||||
return FALSE;
|
||||
|
||||
if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
|
||||
return FALSE;
|
||||
|
||||
screen_priv->query_capabilities = xwl_present_query_capabilities;
|
||||
screen_priv->get_crtc = xwl_present_get_crtc;
|
||||
|
||||
screen_priv->check_flip = xwl_present_check_flip;
|
||||
screen_priv->check_flip_window = xwl_present_check_flip_window;
|
||||
screen_priv->clear_window_flip = xwl_present_clear_window_flip;
|
||||
|
||||
screen_priv->present_pixmap = xwl_present_pixmap;
|
||||
screen_priv->queue_vblank = xwl_present_queue_vblank;
|
||||
screen_priv->flush = xwl_present_flush;
|
||||
screen_priv->re_execute = xwl_present_re_execute;
|
||||
|
||||
screen_priv->abort_vblank = xwl_present_abort_vblank;
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2018 Roman Gilg
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of the
|
||||
* copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XWAYLAND_PRESENT_H
|
||||
#define XWAYLAND_PRESENT_H
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include <dix.h>
|
||||
#include <present_priv.h>
|
||||
|
||||
#include "xwayland-types.h"
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
struct xwl_present_window {
|
||||
struct xorg_list frame_callback_list;
|
||||
|
||||
uint64_t msc;
|
||||
uint64_t ust;
|
||||
|
||||
OsTimerPtr frame_timer;
|
||||
|
||||
struct wl_callback *sync_callback;
|
||||
|
||||
struct xorg_list wait_list;
|
||||
struct xorg_list flip_queue;
|
||||
struct xorg_list idle_queue;
|
||||
|
||||
present_vblank_ptr flip_active;
|
||||
};
|
||||
|
||||
struct xwl_present_event {
|
||||
present_vblank_rec vblank;
|
||||
|
||||
PixmapPtr pixmap;
|
||||
};
|
||||
|
||||
void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
|
||||
Bool xwl_present_init(ScreenPtr screen);
|
||||
void xwl_present_cleanup(WindowPtr window);
|
||||
void xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window);
|
||||
|
||||
#endif /* GLAMOR_HAS_GBM */
|
||||
|
||||
#endif /* XWAYLAND_PRESENT_H */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue