aboutsummaryrefslogtreecommitdiff
path: root/xorg-server
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server')
-rw-r--r--xorg-server/Xext/xcmisc.c1
-rw-r--r--xorg-server/Xext/xvdisp.c20
-rw-r--r--xorg-server/Xi/chgdctl.c8
-rw-r--r--xorg-server/Xi/chgfctl.c2
-rw-r--r--xorg-server/Xi/sendexev.c3
-rw-r--r--xorg-server/Xi/xiallowev.c2
-rw-r--r--xorg-server/Xi/xichangecursor.c2
-rw-r--r--xorg-server/Xi/xichangehierarchy.c35
-rw-r--r--xorg-server/Xi/xigetclientpointer.c1
-rw-r--r--xorg-server/Xi/xigrabdev.c9
-rw-r--r--xorg-server/Xi/xipassivegrab.c12
-rw-r--r--xorg-server/Xi/xiproperty.c14
-rw-r--r--xorg-server/Xi/xiquerydevice.c1
-rw-r--r--xorg-server/Xi/xiquerypointer.c2
-rw-r--r--xorg-server/Xi/xiselectev.c8
-rw-r--r--xorg-server/Xi/xisetclientpointer.c3
-rw-r--r--xorg-server/Xi/xisetdevfocus.c4
-rw-r--r--xorg-server/Xi/xiwarppointer.c2
-rw-r--r--xorg-server/config/udev.c7
-rw-r--r--xorg-server/configure.ac1
-rw-r--r--xorg-server/dbe/dbe.c17
-rw-r--r--xorg-server/dix/dispatch.c3
-rw-r--r--xorg-server/dix/region.c20
-rw-r--r--xorg-server/dri3/dri3_request.c6
-rw-r--r--xorg-server/glamor/glamor.c34
-rw-r--r--xorg-server/glamor/glamor.h4
-rw-r--r--xorg-server/glamor/glamor_egl.c89
-rw-r--r--xorg-server/glamor/glamor_egl_stubs.c2
-rw-r--r--xorg-server/glamor/glamor_fbo.c4
-rw-r--r--xorg-server/glamor/glamor_priv.h2
-rw-r--r--xorg-server/glamor/glamor_xv.c26
-rw-r--r--xorg-server/glx/clientinfo.c20
-rw-r--r--xorg-server/glx/glxcmds.c96
-rw-r--r--xorg-server/glx/glxcmdsswap.c4
-rw-r--r--xorg-server/glx/glxext.c8
-rw-r--r--xorg-server/glx/glxext.h1
-rw-r--r--xorg-server/glx/glxserver.h43
-rw-r--r--xorg-server/glx/indirect_program.c2
-rw-r--r--xorg-server/glx/indirect_reqsize.c142
-rw-r--r--xorg-server/glx/indirect_reqsize.h181
-rw-r--r--xorg-server/glx/indirect_texture_compression.c4
-rw-r--r--xorg-server/glx/indirect_util.c9
-rw-r--r--xorg-server/glx/rensize.c114
-rw-r--r--xorg-server/glx/single2.c23
-rw-r--r--xorg-server/glx/single2swap.c19
-rw-r--r--xorg-server/glx/singlepix.c60
-rw-r--r--xorg-server/glx/singlepixswap.c50
-rw-r--r--xorg-server/glx/swap_interval.c2
-rw-r--r--xorg-server/glx/unpack.h3
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.c2
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.h1
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.c11
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.h2
-rw-r--r--xorg-server/hw/xfree86/common/xf86AutoConfig.c1
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2ext.c3
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/Makefile.am3
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/dri2.c2
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/driver.c104
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/driver.h15
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c337
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h33
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c134
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.h45
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/present.c228
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/vblank.c28
-rw-r--r--xorg-server/hw/xfree86/os-support/solaris/sun_init.c33
-rw-r--r--xorg-server/hw/xfree86/os-support/xf86_OSlib.h5
-rw-r--r--xorg-server/hw/xwayland/xwayland-glamor.c3
-rw-r--r--xorg-server/hw/xwayland/xwayland-input.c7
-rw-r--r--xorg-server/hw/xwin/InitOutput.c4
-rw-r--r--xorg-server/hw/xwin/XWin.rc1
-rw-r--r--xorg-server/hw/xwin/man/XWin.man6
-rw-r--r--xorg-server/hw/xwin/winclipboard/internal.h14
-rw-r--r--xorg-server/hw/xwin/winclipboard/thread.c56
-rw-r--r--xorg-server/hw/xwin/winclipboard/winclipboard.h2
-rw-r--r--xorg-server/hw/xwin/winclipboard/wndproc.c227
-rw-r--r--xorg-server/hw/xwin/winclipboard/xevents.c175
-rw-r--r--xorg-server/hw/xwin/winclipboard/xwinclip.c7
-rw-r--r--xorg-server/hw/xwin/winclipboard/xwinclip.man3
-rw-r--r--xorg-server/hw/xwin/winclipboardwrappers.c6
-rw-r--r--xorg-server/hw/xwin/winprocarg.c27
-rw-r--r--xorg-server/hw/xwin/winresource.h1
-rw-r--r--xorg-server/hw/xwin/wintrayicon.c19
-rw-r--r--xorg-server/hw/xwin/winwndproc.c6
-rw-r--r--xorg-server/include/dix.h7
-rw-r--r--xorg-server/include/regionstr.h10
-rw-r--r--xorg-server/man/Xserver.man10
-rw-r--r--xorg-server/os/access.c6
-rw-r--r--xorg-server/os/io.c7
-rw-r--r--xorg-server/os/log.c7
-rw-r--r--xorg-server/os/osinit.c6
-rw-r--r--xorg-server/os/rpcauth.c4
-rw-r--r--xorg-server/os/xsha1.c25
-rw-r--r--xorg-server/present/present.c28
-rw-r--r--xorg-server/present/present_request.c6
-rw-r--r--xorg-server/randr/rrsdispatch.c4
-rw-r--r--xorg-server/render/picture.c45
-rw-r--r--xorg-server/render/render.c20
-rw-r--r--xorg-server/test/Makefile.am2
-rw-r--r--xorg-server/test/misc.c37
-rw-r--r--xorg-server/test/xi1/Makefile.am34
-rw-r--r--xorg-server/test/xi1/protocol-xchangedevicecontrol.c122
-rw-r--r--xorg-server/test/xi2/protocol-xigetclientpointer.c5
-rw-r--r--xorg-server/test/xi2/protocol-xipassivegrabdevice.c8
-rw-r--r--xorg-server/test/xi2/protocol-xiquerypointer.c4
-rw-r--r--xorg-server/test/xi2/protocol-xiwarppointer.c3
-rw-r--r--xorg-server/xfixes/select.c1
-rw-r--r--xorg-server/xkeyboard-config/rules/base.extras.xml.in10
-rw-r--r--xorg-server/xkeyboard-config/rules/base.xml.in4
-rw-r--r--xorg-server/xkeyboard-config/symbols/de34
-rw-r--r--xorg-server/xkeyboard-config/symbols/fi1
-rw-r--r--xorg-server/xkeyboard-config/symbols/fujitsu_vndr/jp2
-rw-r--r--xorg-server/xkeyboard-config/symbols/fujitsu_vndr/us2
-rw-r--r--xorg-server/xkeyboard-config/symbols/il2
-rw-r--r--xorg-server/xkeyboard-config/symbols/ru9
115 files changed, 2203 insertions, 938 deletions
diff --git a/xorg-server/Xext/xcmisc.c b/xorg-server/Xext/xcmisc.c
index 034bfb63b..1e9101059 100644
--- a/xorg-server/Xext/xcmisc.c
+++ b/xorg-server/Xext/xcmisc.c
@@ -167,6 +167,7 @@ static int
SProcXCMiscGetXIDList(ClientPtr client)
{
REQUEST(xXCMiscGetXIDListReq);
+ REQUEST_SIZE_MATCH(xXCMiscGetXIDListReq);
swaps(&stuff->length);
swapl(&stuff->count);
diff --git a/xorg-server/Xext/xvdisp.c b/xorg-server/Xext/xvdisp.c
index 86f982ae2..c2d0fc9c1 100644
--- a/xorg-server/Xext/xvdisp.c
+++ b/xorg-server/Xext/xvdisp.c
@@ -1121,6 +1121,7 @@ static int
SProcXvQueryExtension(ClientPtr client)
{
REQUEST(xvQueryExtensionReq);
+ REQUEST_SIZE_MATCH(xvQueryExtensionReq);
swaps(&stuff->length);
return XvProcVector[xv_QueryExtension] (client);
}
@@ -1129,6 +1130,7 @@ static int
SProcXvQueryAdaptors(ClientPtr client)
{
REQUEST(xvQueryAdaptorsReq);
+ REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
swaps(&stuff->length);
swapl(&stuff->window);
return XvProcVector[xv_QueryAdaptors] (client);
@@ -1138,6 +1140,7 @@ static int
SProcXvQueryEncodings(ClientPtr client)
{
REQUEST(xvQueryEncodingsReq);
+ REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
swaps(&stuff->length);
swapl(&stuff->port);
return XvProcVector[xv_QueryEncodings] (client);
@@ -1147,6 +1150,7 @@ static int
SProcXvGrabPort(ClientPtr client)
{
REQUEST(xvGrabPortReq);
+ REQUEST_SIZE_MATCH(xvGrabPortReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->time);
@@ -1157,6 +1161,7 @@ static int
SProcXvUngrabPort(ClientPtr client)
{
REQUEST(xvUngrabPortReq);
+ REQUEST_SIZE_MATCH(xvUngrabPortReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->time);
@@ -1167,6 +1172,7 @@ static int
SProcXvPutVideo(ClientPtr client)
{
REQUEST(xvPutVideoReq);
+ REQUEST_SIZE_MATCH(xvPutVideoReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->drawable);
@@ -1186,6 +1192,7 @@ static int
SProcXvPutStill(ClientPtr client)
{
REQUEST(xvPutStillReq);
+ REQUEST_SIZE_MATCH(xvPutStillReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->drawable);
@@ -1205,6 +1212,7 @@ static int
SProcXvGetVideo(ClientPtr client)
{
REQUEST(xvGetVideoReq);
+ REQUEST_SIZE_MATCH(xvGetVideoReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->drawable);
@@ -1224,6 +1232,7 @@ static int
SProcXvGetStill(ClientPtr client)
{
REQUEST(xvGetStillReq);
+ REQUEST_SIZE_MATCH(xvGetStillReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->drawable);
@@ -1243,6 +1252,7 @@ static int
SProcXvPutImage(ClientPtr client)
{
REQUEST(xvPutImageReq);
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->drawable);
@@ -1266,6 +1276,7 @@ static int
SProcXvShmPutImage(ClientPtr client)
{
REQUEST(xvShmPutImageReq);
+ REQUEST_SIZE_MATCH(xvShmPutImageReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->drawable);
@@ -1293,6 +1304,7 @@ static int
SProcXvSelectVideoNotify(ClientPtr client)
{
REQUEST(xvSelectVideoNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
swaps(&stuff->length);
swapl(&stuff->drawable);
return XvProcVector[xv_SelectVideoNotify] (client);
@@ -1302,6 +1314,7 @@ static int
SProcXvSelectPortNotify(ClientPtr client)
{
REQUEST(xvSelectPortNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
swaps(&stuff->length);
swapl(&stuff->port);
return XvProcVector[xv_SelectPortNotify] (client);
@@ -1311,6 +1324,7 @@ static int
SProcXvStopVideo(ClientPtr client)
{
REQUEST(xvStopVideoReq);
+ REQUEST_SIZE_MATCH(xvStopVideoReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->drawable);
@@ -1321,6 +1335,7 @@ static int
SProcXvSetPortAttribute(ClientPtr client)
{
REQUEST(xvSetPortAttributeReq);
+ REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->attribute);
@@ -1332,6 +1347,7 @@ static int
SProcXvGetPortAttribute(ClientPtr client)
{
REQUEST(xvGetPortAttributeReq);
+ REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->attribute);
@@ -1342,6 +1358,7 @@ static int
SProcXvQueryBestSize(ClientPtr client)
{
REQUEST(xvQueryBestSizeReq);
+ REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
swaps(&stuff->length);
swapl(&stuff->port);
swaps(&stuff->vid_w);
@@ -1355,6 +1372,7 @@ static int
SProcXvQueryPortAttributes(ClientPtr client)
{
REQUEST(xvQueryPortAttributesReq);
+ REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
swaps(&stuff->length);
swapl(&stuff->port);
return XvProcVector[xv_QueryPortAttributes] (client);
@@ -1364,6 +1382,7 @@ static int
SProcXvQueryImageAttributes(ClientPtr client)
{
REQUEST(xvQueryImageAttributesReq);
+ REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
swaps(&stuff->length);
swapl(&stuff->port);
swapl(&stuff->id);
@@ -1376,6 +1395,7 @@ static int
SProcXvListImageFormats(ClientPtr client)
{
REQUEST(xvListImageFormatsReq);
+ REQUEST_SIZE_MATCH(xvListImageFormatsReq);
swaps(&stuff->length);
swapl(&stuff->port);
return XvProcVector[xv_ListImageFormats] (client);
diff --git a/xorg-server/Xi/chgdctl.c b/xorg-server/Xi/chgdctl.c
index d078aa248..b3ee867f0 100644
--- a/xorg-server/Xi/chgdctl.c
+++ b/xorg-server/Xi/chgdctl.c
@@ -78,7 +78,7 @@ SProcXChangeDeviceControl(ClientPtr client)
REQUEST(xChangeDeviceControlReq);
swaps(&stuff->length);
- REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
+ REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
swaps(&stuff->control);
ctl = (xDeviceCtl *) &stuff[1];
swaps(&ctl->control);
@@ -115,7 +115,7 @@ ProcXChangeDeviceControl(ClientPtr client)
xDeviceEnableCtl *e;
REQUEST(xChangeDeviceControlReq);
- REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
+ REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceControlReq));
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
@@ -192,6 +192,10 @@ ProcXChangeDeviceControl(ClientPtr client)
break;
case DEVICE_ENABLE:
e = (xDeviceEnableCtl *) &stuff[1];
+ if ((len != bytes_to_int32(sizeof(xDeviceEnableCtl)))) {
+ ret = BadLength;
+ goto out;
+ }
if (IsXTestDevice(dev, NULL))
status = !Success;
diff --git a/xorg-server/Xi/chgfctl.c b/xorg-server/Xi/chgfctl.c
index 6dcf60c66..224c2ba0a 100644
--- a/xorg-server/Xi/chgfctl.c
+++ b/xorg-server/Xi/chgfctl.c
@@ -467,6 +467,8 @@ ProcXChangeFeedbackControl(ClientPtr client)
xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]);
if (client->swapped) {
+ if (len < bytes_to_int32(sizeof(xStringFeedbackCtl)))
+ return BadLength;
swaps(&f->num_keysyms);
}
if (len !=
diff --git a/xorg-server/Xi/sendexev.c b/xorg-server/Xi/sendexev.c
index 3c213864b..183f88dae 100644
--- a/xorg-server/Xi/sendexev.c
+++ b/xorg-server/Xi/sendexev.c
@@ -135,6 +135,9 @@ ProcXSendExtensionEvent(ClientPtr client)
if (ret != Success)
return ret;
+ if (stuff->num_events == 0)
+ return ret;
+
/* The client's event type must be one defined by an extension. */
first = ((xEvent *) &stuff[1]);
diff --git a/xorg-server/Xi/xiallowev.c b/xorg-server/Xi/xiallowev.c
index ebef23344..ca263ef1f 100644
--- a/xorg-server/Xi/xiallowev.c
+++ b/xorg-server/Xi/xiallowev.c
@@ -48,6 +48,7 @@ int
SProcXIAllowEvents(ClientPtr client)
{
REQUEST(xXIAllowEventsReq);
+ REQUEST_AT_LEAST_SIZE(xXIAllowEventsReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
@@ -55,6 +56,7 @@ SProcXIAllowEvents(ClientPtr client)
if (stuff->length > 3) {
xXI2_2AllowEventsReq *req_xi22 = (xXI2_2AllowEventsReq *) stuff;
+ REQUEST_AT_LEAST_SIZE(xXI2_2AllowEventsReq);
swapl(&req_xi22->touchid);
swapl(&req_xi22->grab_window);
}
diff --git a/xorg-server/Xi/xichangecursor.c b/xorg-server/Xi/xichangecursor.c
index 7a1bb7a0d..8e6255b6e 100644
--- a/xorg-server/Xi/xichangecursor.c
+++ b/xorg-server/Xi/xichangecursor.c
@@ -57,11 +57,11 @@ int
SProcXIChangeCursor(ClientPtr client)
{
REQUEST(xXIChangeCursorReq);
+ REQUEST_SIZE_MATCH(xXIChangeCursorReq);
swaps(&stuff->length);
swapl(&stuff->win);
swapl(&stuff->cursor);
swaps(&stuff->deviceid);
- REQUEST_SIZE_MATCH(xXIChangeCursorReq);
return (ProcXIChangeCursor(client));
}
diff --git a/xorg-server/Xi/xichangehierarchy.c b/xorg-server/Xi/xichangehierarchy.c
index 9e36354d1..27324452d 100644
--- a/xorg-server/Xi/xichangehierarchy.c
+++ b/xorg-server/Xi/xichangehierarchy.c
@@ -411,7 +411,7 @@ int
ProcXIChangeHierarchy(ClientPtr client)
{
xXIAnyHierarchyChangeInfo *any;
- int required_len = sizeof(xXIChangeHierarchyReq);
+ size_t len; /* length of data remaining in request */
int rc = Success;
int flags[MAXDEVICES] = { 0 };
@@ -421,21 +421,46 @@ ProcXIChangeHierarchy(ClientPtr client)
if (!stuff->num_changes)
return rc;
+ if (stuff->length > (INT_MAX >> 2))
+ return BadAlloc;
+ len = (stuff->length << 2) - sizeof(xXIAnyHierarchyChangeInfo);
+
any = (xXIAnyHierarchyChangeInfo *) &stuff[1];
while (stuff->num_changes--) {
+ if (len < sizeof(xXIAnyHierarchyChangeInfo)) {
+ rc = BadLength;
+ goto unwind;
+ }
+
SWAPIF(swaps(&any->type));
SWAPIF(swaps(&any->length));
- required_len += any->length;
- if ((stuff->length * 4) < required_len)
+ if ((any->length > (INT_MAX >> 2)) || (len < (any->length << 2)))
return BadLength;
+#define CHANGE_SIZE_MATCH(type) \
+ do { \
+ if ((len < sizeof(type)) || (any->length != (sizeof(type) >> 2))) { \
+ rc = BadLength; \
+ goto unwind; \
+ } \
+ } while(0)
+
switch (any->type) {
case XIAddMaster:
{
xXIAddMasterInfo *c = (xXIAddMasterInfo *) any;
+ /* Variable length, due to appended name string */
+ if (len < sizeof(xXIAddMasterInfo)) {
+ rc = BadLength;
+ goto unwind;
+ }
SWAPIF(swaps(&c->name_len));
+ if (c->name_len > (len - sizeof(xXIAddMasterInfo))) {
+ rc = BadLength;
+ goto unwind;
+ }
rc = add_master(client, c, flags);
if (rc != Success)
@@ -446,6 +471,7 @@ ProcXIChangeHierarchy(ClientPtr client)
{
xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
+ CHANGE_SIZE_MATCH(xXIRemoveMasterInfo);
rc = remove_master(client, r, flags);
if (rc != Success)
goto unwind;
@@ -455,6 +481,7 @@ ProcXIChangeHierarchy(ClientPtr client)
{
xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
+ CHANGE_SIZE_MATCH(xXIDetachSlaveInfo);
rc = detach_slave(client, c, flags);
if (rc != Success)
goto unwind;
@@ -464,6 +491,7 @@ ProcXIChangeHierarchy(ClientPtr client)
{
xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
+ CHANGE_SIZE_MATCH(xXIAttachSlaveInfo);
rc = attach_slave(client, c, flags);
if (rc != Success)
goto unwind;
@@ -471,6 +499,7 @@ ProcXIChangeHierarchy(ClientPtr client)
break;
}
+ len -= any->length * 4;
any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4);
}
diff --git a/xorg-server/Xi/xigetclientpointer.c b/xorg-server/Xi/xigetclientpointer.c
index 3c90d588d..306dd396b 100644
--- a/xorg-server/Xi/xigetclientpointer.c
+++ b/xorg-server/Xi/xigetclientpointer.c
@@ -50,6 +50,7 @@ int
SProcXIGetClientPointer(ClientPtr client)
{
REQUEST(xXIGetClientPointerReq);
+ REQUEST_SIZE_MATCH(xXIGetClientPointerReq);
swaps(&stuff->length);
swapl(&stuff->win);
diff --git a/xorg-server/Xi/xigrabdev.c b/xorg-server/Xi/xigrabdev.c
index 63d95bc1c..e2a2ae333 100644
--- a/xorg-server/Xi/xigrabdev.c
+++ b/xorg-server/Xi/xigrabdev.c
@@ -47,6 +47,11 @@ int
SProcXIGrabDevice(ClientPtr client)
{
REQUEST(xXIGrabDeviceReq);
+ /*
+ * Check here for at least the length of the struct we swap, then
+ * let ProcXIGrabDevice check the full size after we swap mask_len.
+ */
+ REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
@@ -71,7 +76,7 @@ ProcXIGrabDevice(ClientPtr client)
unsigned int pointer_mode;
REQUEST(xXIGrabDeviceReq);
- REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
+ REQUEST_FIXED_SIZE(xXIGrabDeviceReq, ((size_t) stuff->mask_len) * 4);
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
if (ret != Success)
@@ -131,6 +136,7 @@ int
SProcXIUngrabDevice(ClientPtr client)
{
REQUEST(xXIUngrabDeviceReq);
+ REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
@@ -148,6 +154,7 @@ ProcXIUngrabDevice(ClientPtr client)
TimeStamp time;
REQUEST(xXIUngrabDeviceReq);
+ REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
if (ret != Success)
diff --git a/xorg-server/Xi/xipassivegrab.c b/xorg-server/Xi/xipassivegrab.c
index 700622d38..9241ffdea 100644
--- a/xorg-server/Xi/xipassivegrab.c
+++ b/xorg-server/Xi/xipassivegrab.c
@@ -53,6 +53,7 @@ SProcXIPassiveGrabDevice(ClientPtr client)
uint32_t *mods;
REQUEST(xXIPassiveGrabDeviceReq);
+ REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
@@ -63,6 +64,8 @@ SProcXIPassiveGrabDevice(ClientPtr client)
swaps(&stuff->mask_len);
swaps(&stuff->num_modifiers);
+ REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
+ ((uint32_t) stuff->mask_len + stuff->num_modifiers) *4);
mods = (uint32_t *) &stuff[1] + stuff->mask_len;
for (i = 0; i < stuff->num_modifiers; i++, mods++) {
@@ -92,7 +95,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
int mask_len;
REQUEST(xXIPassiveGrabDeviceReq);
- REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
+ REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
+ ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4);
if (stuff->deviceid == XIAllDevices)
dev = inputInfo.all_devices;
@@ -252,6 +256,7 @@ SProcXIPassiveUngrabDevice(ClientPtr client)
uint32_t *modifiers;
REQUEST(xXIPassiveUngrabDeviceReq);
+ REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
swaps(&stuff->length);
swapl(&stuff->grab_window);
@@ -259,6 +264,8 @@ SProcXIPassiveUngrabDevice(ClientPtr client)
swapl(&stuff->detail);
swaps(&stuff->num_modifiers);
+ REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
+ ((uint32_t) stuff->num_modifiers) << 2);
modifiers = (uint32_t *) &stuff[1];
for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
@@ -277,7 +284,8 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
int i, rc;
REQUEST(xXIPassiveUngrabDeviceReq);
- REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
+ REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
+ ((uint32_t) stuff->num_modifiers) << 2);
if (stuff->deviceid == XIAllDevices)
dev = inputInfo.all_devices;
diff --git a/xorg-server/Xi/xiproperty.c b/xorg-server/Xi/xiproperty.c
index 463607d33..8e8e4b061 100644
--- a/xorg-server/Xi/xiproperty.c
+++ b/xorg-server/Xi/xiproperty.c
@@ -1013,10 +1013,9 @@ int
SProcXListDeviceProperties(ClientPtr client)
{
REQUEST(xListDevicePropertiesReq);
+ REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
swaps(&stuff->length);
-
- REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
return (ProcXListDeviceProperties(client));
}
@@ -1037,10 +1036,10 @@ int
SProcXDeleteDeviceProperty(ClientPtr client)
{
REQUEST(xDeleteDevicePropertyReq);
+ REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
swaps(&stuff->length);
swapl(&stuff->property);
- REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
return (ProcXDeleteDeviceProperty(client));
}
@@ -1048,13 +1047,13 @@ int
SProcXGetDeviceProperty(ClientPtr client)
{
REQUEST(xGetDevicePropertyReq);
+ REQUEST_SIZE_MATCH(xGetDevicePropertyReq);
swaps(&stuff->length);
swapl(&stuff->property);
swapl(&stuff->type);
swapl(&stuff->longOffset);
swapl(&stuff->longLength);
- REQUEST_SIZE_MATCH(xGetDevicePropertyReq);
return (ProcXGetDeviceProperty(client));
}
@@ -1253,11 +1252,10 @@ int
SProcXIListProperties(ClientPtr client)
{
REQUEST(xXIListPropertiesReq);
+ REQUEST_SIZE_MATCH(xXIListPropertiesReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
-
- REQUEST_SIZE_MATCH(xXIListPropertiesReq);
return (ProcXIListProperties(client));
}
@@ -1279,11 +1277,11 @@ int
SProcXIDeleteProperty(ClientPtr client)
{
REQUEST(xXIDeletePropertyReq);
+ REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
swapl(&stuff->property);
- REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
return (ProcXIDeleteProperty(client));
}
@@ -1291,6 +1289,7 @@ int
SProcXIGetProperty(ClientPtr client)
{
REQUEST(xXIGetPropertyReq);
+ REQUEST_SIZE_MATCH(xXIGetPropertyReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
@@ -1298,7 +1297,6 @@ SProcXIGetProperty(ClientPtr client)
swapl(&stuff->type);
swapl(&stuff->offset);
swapl(&stuff->len);
- REQUEST_SIZE_MATCH(xXIGetPropertyReq);
return (ProcXIGetProperty(client));
}
diff --git a/xorg-server/Xi/xiquerydevice.c b/xorg-server/Xi/xiquerydevice.c
index 4e544f0f5..67a9a4f3f 100644
--- a/xorg-server/Xi/xiquerydevice.c
+++ b/xorg-server/Xi/xiquerydevice.c
@@ -54,6 +54,7 @@ int
SProcXIQueryDevice(ClientPtr client)
{
REQUEST(xXIQueryDeviceReq);
+ REQUEST_SIZE_MATCH(xXIQueryDeviceReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
diff --git a/xorg-server/Xi/xiquerypointer.c b/xorg-server/Xi/xiquerypointer.c
index e9bdd428d..7ec0c851d 100644
--- a/xorg-server/Xi/xiquerypointer.c
+++ b/xorg-server/Xi/xiquerypointer.c
@@ -63,6 +63,8 @@ int
SProcXIQueryPointer(ClientPtr client)
{
REQUEST(xXIQueryPointerReq);
+ REQUEST_SIZE_MATCH(xXIQueryPointerReq);
+
swaps(&stuff->length);
swaps(&stuff->deviceid);
swapl(&stuff->win);
diff --git a/xorg-server/Xi/xiselectev.c b/xorg-server/Xi/xiselectev.c
index 45a996e4c..168579f5b 100644
--- a/xorg-server/Xi/xiselectev.c
+++ b/xorg-server/Xi/xiselectev.c
@@ -114,6 +114,7 @@ int
SProcXISelectEvents(ClientPtr client)
{
int i;
+ int len;
xXIEventMask *evmask;
REQUEST(xXISelectEventsReq);
@@ -122,10 +123,17 @@ SProcXISelectEvents(ClientPtr client)
swapl(&stuff->win);
swaps(&stuff->num_masks);
+ len = stuff->length - bytes_to_int32(sizeof(xXISelectEventsReq));
evmask = (xXIEventMask *) &stuff[1];
for (i = 0; i < stuff->num_masks; i++) {
+ if (len < bytes_to_int32(sizeof(xXIEventMask)))
+ return BadLength;
+ len -= bytes_to_int32(sizeof(xXIEventMask));
swaps(&evmask->deviceid);
swaps(&evmask->mask_len);
+ if (len < evmask->mask_len)
+ return BadLength;
+ len -= evmask->mask_len;
evmask =
(xXIEventMask *) (((char *) &evmask[1]) + evmask->mask_len * 4);
}
diff --git a/xorg-server/Xi/xisetclientpointer.c b/xorg-server/Xi/xisetclientpointer.c
index 38ff51e86..24d4a5379 100644
--- a/xorg-server/Xi/xisetclientpointer.c
+++ b/xorg-server/Xi/xisetclientpointer.c
@@ -51,10 +51,11 @@ int
SProcXISetClientPointer(ClientPtr client)
{
REQUEST(xXISetClientPointerReq);
+ REQUEST_SIZE_MATCH(xXISetClientPointerReq);
+
swaps(&stuff->length);
swapl(&stuff->win);
swaps(&stuff->deviceid);
- REQUEST_SIZE_MATCH(xXISetClientPointerReq);
return (ProcXISetClientPointer(client));
}
diff --git a/xorg-server/Xi/xisetdevfocus.c b/xorg-server/Xi/xisetdevfocus.c
index 372ec248a..96a9a16e4 100644
--- a/xorg-server/Xi/xisetdevfocus.c
+++ b/xorg-server/Xi/xisetdevfocus.c
@@ -44,6 +44,8 @@ int
SProcXISetFocus(ClientPtr client)
{
REQUEST(xXISetFocusReq);
+ REQUEST_AT_LEAST_SIZE(xXISetFocusReq);
+
swaps(&stuff->length);
swaps(&stuff->deviceid);
swapl(&stuff->focus);
@@ -56,6 +58,8 @@ int
SProcXIGetFocus(ClientPtr client)
{
REQUEST(xXIGetFocusReq);
+ REQUEST_AT_LEAST_SIZE(xXIGetFocusReq);
+
swaps(&stuff->length);
swaps(&stuff->deviceid);
diff --git a/xorg-server/Xi/xiwarppointer.c b/xorg-server/Xi/xiwarppointer.c
index 3f051f759..780758a9e 100644
--- a/xorg-server/Xi/xiwarppointer.c
+++ b/xorg-server/Xi/xiwarppointer.c
@@ -56,6 +56,8 @@ int
SProcXIWarpPointer(ClientPtr client)
{
REQUEST(xXIWarpPointerReq);
+ REQUEST_SIZE_MATCH(xXIWarpPointerReq);
+
swaps(&stuff->length);
swapl(&stuff->src_win);
swapl(&stuff->dst_win);
diff --git a/xorg-server/config/udev.c b/xorg-server/config/udev.c
index 1e4a9d7a6..1d2140afd 100644
--- a/xorg-server/config/udev.c
+++ b/xorg-server/config/udev.c
@@ -300,12 +300,11 @@ device_removed(struct udev_device *device)
const char *path = udev_device_get_devnode(device);
dev_t devnum = udev_device_get_devnum(device);
- if (strncmp(sysname,"card", 4) != 0)
- return;
- ErrorF("removing GPU device %s %s\n", syspath, path);
- if (!path)
+ if ((strncmp(sysname,"card", 4) != 0) || (path == NULL))
return;
+ LogMessage(X_INFO, "config/udev: removing GPU device %s %s\n",
+ syspath, path);
config_udev_odev_setup_attribs(path, syspath, major(devnum),
minor(devnum), DeleteGPUDeviceRequest);
/* Retry vtenter after a drm node removal */
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index 140e33e45..96524c58b 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -2621,6 +2621,7 @@ hw/kdrive/linux/Makefile
hw/kdrive/src/Makefile
hw/xwayland/Makefile
test/Makefile
+test/xi1/Makefile
test/xi2/Makefile
xserver.ent
xorg-server.pc
diff --git a/xorg-server/dbe/dbe.c b/xorg-server/dbe/dbe.c
index 527588c3c..e5d928d7b 100644
--- a/xorg-server/dbe/dbe.c
+++ b/xorg-server/dbe/dbe.c
@@ -450,18 +450,21 @@ ProcDbeSwapBuffers(ClientPtr client)
DbeSwapInfoPtr swapInfo;
xDbeSwapInfo *dbeSwapInfo;
int error;
- register int i, j;
- int nStuff;
+ unsigned int i, j;
+ unsigned int nStuff;
+ int nStuff_i; /* DDX API requires int for nStuff */
REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
nStuff = stuff->n; /* use local variable for performance. */
if (nStuff == 0) {
+ REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
return Success;
}
if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
return BadAlloc;
+ REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
/* Get to the swap info appended to the end of the request. */
dbeSwapInfo = (xDbeSwapInfo *) &stuff[1];
@@ -525,9 +528,10 @@ ProcDbeSwapBuffers(ClientPtr client)
* could deal with cross-screen synchronization.
*/
- while (nStuff > 0) {
+ nStuff_i = nStuff;
+ while (nStuff_i > 0) {
pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
- error = (*pDbeScreenPriv->SwapBuffers) (client, &nStuff, swapInfo);
+ error = (*pDbeScreenPriv->SwapBuffers) (client, &nStuff_i, swapInfo);
if (error != Success) {
free(swapInfo);
return error;
@@ -914,13 +918,16 @@ static int
SProcDbeSwapBuffers(ClientPtr client)
{
REQUEST(xDbeSwapBuffersReq);
- register int i;
+ unsigned int i;
xDbeSwapInfo *pSwapInfo;
swaps(&stuff->length);
REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
swapl(&stuff->n);
+ if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
+ return BadAlloc;
+ REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
if (stuff->n != 0) {
pSwapInfo = (xDbeSwapInfo *) stuff + 1;
diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c
index d844a0942..9044ac786 100644
--- a/xorg-server/dix/dispatch.c
+++ b/xorg-server/dix/dispatch.c
@@ -2000,6 +2000,9 @@ ProcPutImage(ClientPtr client)
tmpImage = (char *) &stuff[1];
lengthProto = length;
+ if (stuff->height != 0 && lengthProto >= (INT32_MAX / stuff->height))
+ return BadLength;
+
if ((bytes_to_int32(lengthProto * stuff->height) +
bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
return BadLength;
diff --git a/xorg-server/dix/region.c b/xorg-server/dix/region.c
index ce1014ef8..04e590170 100644
--- a/xorg-server/dix/region.c
+++ b/xorg-server/dix/region.c
@@ -169,7 +169,6 @@ Equipment Corporation.
((r1)->y1 <= (r2)->y1) && \
((r1)->y2 >= (r2)->y2) )
-#define xallocData(n) malloc(RegionSizeof(n))
#define xfreeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
#define RECTALLOC_BAIL(pReg,n,bail) \
@@ -205,8 +204,9 @@ if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
#define DOWNSIZE(reg,numRects) \
if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
{ \
- RegDataPtr NewData; \
- NewData = (RegDataPtr)realloc((reg)->data, RegionSizeof(numRects)); \
+ size_t NewSize = RegionSizeof(numRects); \
+ RegDataPtr NewData = \
+ (NewSize > 0) ? realloc((reg)->data, NewSize) : NULL ; \
if (NewData) \
{ \
NewData->size = (numRects); \
@@ -345,17 +345,20 @@ Bool
RegionRectAlloc(RegionPtr pRgn, int n)
{
RegDataPtr data;
+ size_t rgnSize;
if (!pRgn->data) {
n++;
- pRgn->data = xallocData(n);
+ rgnSize = RegionSizeof(n);
+ pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
if (!pRgn->data)
return RegionBreak(pRgn);
pRgn->data->numRects = 1;
*RegionBoxptr(pRgn) = pRgn->extents;
}
else if (!pRgn->data->size) {
- pRgn->data = xallocData(n);
+ rgnSize = RegionSizeof(n);
+ pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
if (!pRgn->data)
return RegionBreak(pRgn);
pRgn->data->numRects = 0;
@@ -367,7 +370,8 @@ RegionRectAlloc(RegionPtr pRgn, int n)
n = 250;
}
n += pRgn->data->numRects;
- data = (RegDataPtr) realloc(pRgn->data, RegionSizeof(n));
+ rgnSize = RegionSizeof(n);
+ data = (rgnSize > 0) ? realloc(pRgn->data, rgnSize) : NULL;
if (!data)
return RegionBreak(pRgn);
pRgn->data = data;
@@ -1312,6 +1316,7 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype)
{
RegionPtr pRgn;
+ size_t rgnSize;
RegDataPtr pData;
BoxPtr pBox;
int i;
@@ -1338,7 +1343,8 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype)
}
return pRgn;
}
- pData = xallocData(nrects);
+ rgnSize = RegionSizeof(nrects);
+ pData = (rgnSize > 0) ? malloc(rgnSize) : NULL;
if (!pData) {
RegionBreak(pRgn);
return pRgn;
diff --git a/xorg-server/dri3/dri3_request.c b/xorg-server/dri3/dri3_request.c
index fe45620c9..2d7558863 100644
--- a/xorg-server/dri3/dri3_request.c
+++ b/xorg-server/dri3/dri3_request.c
@@ -321,6 +321,7 @@ static int
sproc_dri3_query_version(ClientPtr client)
{
REQUEST(xDRI3QueryVersionReq);
+ REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
swaps(&stuff->length);
swapl(&stuff->majorVersion);
@@ -332,6 +333,7 @@ static int
sproc_dri3_open(ClientPtr client)
{
REQUEST(xDRI3OpenReq);
+ REQUEST_SIZE_MATCH(xDRI3OpenReq);
swaps(&stuff->length);
swapl(&stuff->drawable);
@@ -343,6 +345,7 @@ static int
sproc_dri3_pixmap_from_buffer(ClientPtr client)
{
REQUEST(xDRI3PixmapFromBufferReq);
+ REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
swaps(&stuff->length);
swapl(&stuff->pixmap);
@@ -358,6 +361,7 @@ static int
sproc_dri3_buffer_from_pixmap(ClientPtr client)
{
REQUEST(xDRI3BufferFromPixmapReq);
+ REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
swaps(&stuff->length);
swapl(&stuff->pixmap);
@@ -368,6 +372,7 @@ static int
sproc_dri3_fence_from_fd(ClientPtr client)
{
REQUEST(xDRI3FenceFromFDReq);
+ REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
swaps(&stuff->length);
swapl(&stuff->drawable);
@@ -379,6 +384,7 @@ static int
sproc_dri3_fd_from_fence(ClientPtr client)
{
REQUEST(xDRI3FDFromFenceReq);
+ REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq);
swaps(&stuff->length);
swapl(&stuff->drawable);
diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c
index d228e35ad..78e827809 100644
--- a/xorg-server/glamor/glamor.c
+++ b/xorg-server/glamor/glamor.c
@@ -123,8 +123,6 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
pixmap_priv->base.fbo->width = screen_pixmap->drawable.width;
pixmap_priv->base.fbo->height = screen_pixmap->drawable.height;
-
- glamor_priv->back_pixmap = back_pixmap;
}
uint32_t
@@ -222,23 +220,20 @@ void
glamor_destroy_textured_pixmap(PixmapPtr pixmap)
{
if (pixmap->refcnt == 1) {
- glamor_pixmap_private *pixmap_priv;
-
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (pixmap_priv != NULL)
- glamor_pixmap_destroy_fbo(pixmap_priv);
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (pixmap_priv != NULL) {
+#if GLAMOR_HAS_GBM
+ glamor_egl_destroy_pixmap_image(pixmap);
+#endif
+ glamor_set_pixmap_private(pixmap, NULL);
+ }
}
}
Bool
glamor_destroy_pixmap(PixmapPtr pixmap)
{
- glamor_screen_private
- *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
- if (glamor_priv->dri3_enabled)
- glamor_egl_destroy_textured_pixmap(pixmap);
- else
- glamor_destroy_textured_pixmap(pixmap);
+ glamor_destroy_textured_pixmap(pixmap);
return fbDestroyPixmap(pixmap);
}
@@ -428,6 +423,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_set_debug_level(&glamor_debug_level);
+ glamor_priv->saved_procs.close_screen = screen->CloseScreen;
+ screen->CloseScreen = glamor_close_screen;
+
/* If we are using egl screen, call egl screen init to
* register correct close screen function. */
if (flags & GLAMOR_USE_EGL_SCREEN) {
@@ -437,9 +435,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
goto fail;
}
- glamor_priv->saved_procs.close_screen = screen->CloseScreen;
- screen->CloseScreen = glamor_close_screen;
-
glamor_priv->saved_procs.create_screen_resources =
screen->CreateScreenResources;
screen->CreateScreenResources = glamor_create_screen_resources;
@@ -558,7 +553,6 @@ _X_EXPORT void
glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
{
glamor_pixmap_private *old_priv;
- glamor_pixmap_fbo *fbo;
old_priv = dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
@@ -568,8 +562,8 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
else {
if (old_priv == NULL)
return;
- fbo = glamor_pixmap_detach_fbo(old_priv);
- glamor_purge_fbo(fbo);
+
+ glamor_pixmap_destroy_fbo(old_priv);
free(old_priv);
}
@@ -619,8 +613,6 @@ glamor_close_screen(ScreenPtr screen)
#endif
screen_pixmap = screen->GetScreenPixmap(screen);
glamor_set_pixmap_private(screen_pixmap, NULL);
- if (glamor_priv->back_pixmap && *glamor_priv->back_pixmap)
- glamor_set_pixmap_private(*glamor_priv->back_pixmap, NULL);
glamor_release_screen_priv(screen);
diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h
index 405dbe8ed..206158c02 100644
--- a/xorg-server/glamor/glamor.h
+++ b/xorg-server/glamor/glamor.h
@@ -170,6 +170,10 @@ extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
unsigned int, Bool,
CARD16 *, CARD32 *);
+extern void glamor_egl_destroy_pixmap_image(PixmapPtr pixmap);
+
+extern _X_EXPORT void *glamor_egl_get_gbm_device(ScreenPtr screen);
+
/* @glamor_supports_pixmap_import_export: Returns whether
* glamor_fd_from_pixmap(), glamor_name_from_pixmap(), and
* glamor_pixmap_from_fd() are supported.
diff --git a/xorg-server/glamor/glamor_egl.c b/xorg-server/glamor/glamor_egl.c
index 182e2e8c9..113450c8d 100644
--- a/xorg-server/glamor/glamor_egl.c
+++ b/xorg-server/glamor/glamor_egl.c
@@ -69,8 +69,6 @@ struct glamor_egl_screen_private {
CreateScreenResourcesProcPtr CreateScreenResources;
CloseScreenProcPtr CloseScreen;
int fd;
- EGLImageKHR front_image;
- PixmapPtr *back_pixmap;
int cpp;
#ifdef GLAMOR_HAS_GBM
struct gbm_device *gbm;
@@ -176,6 +174,18 @@ glamor_create_texture_from_image(ScreenPtr screen,
return TRUE;
}
+void *
+glamor_egl_get_gbm_device(ScreenPtr screen)
+{
+#ifdef GLAMOR_HAS_GBM
+ struct glamor_egl_screen_private *glamor_egl =
+ glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+ return glamor_egl->gbm;
+#else
+ return NULL;
+#endif
+}
+
unsigned int
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
{
@@ -220,13 +230,9 @@ Bool
glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
- struct glamor_pixmap_private *pixmap_priv;
- struct glamor_egl_screen_private *glamor_egl;
PixmapPtr screen_pixmap;
- glamor_egl = glamor_egl_get_screen_private(scrn);
screen_pixmap = screen->GetScreenPixmap(screen);
- pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -234,8 +240,7 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
return FALSE;
}
- glamor_egl->front_image = pixmap_priv->base.image;
- glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap);
+ glamor_set_screen_pixmap(screen_pixmap, NULL);
return TRUE;
}
@@ -244,15 +249,7 @@ glamor_egl_create_textured_screen_ext(ScreenPtr screen,
int handle,
int stride, PixmapPtr *back_pixmap)
{
- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
- struct glamor_egl_screen_private *glamor_egl;
-
- glamor_egl = glamor_egl_get_screen_private(scrn);
-
- glamor_egl->back_pixmap = back_pixmap;
- if (!glamor_egl_create_textured_screen(screen, handle, stride))
- return FALSE;
- return TRUE;
+ return glamor_egl_create_textured_screen(screen, handle, stride);
}
static Bool
@@ -268,6 +265,24 @@ glamor_egl_check_has_gem(int fd)
return FALSE;
}
+static void
+glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image)
+{
+ struct glamor_pixmap_private *pixmap_priv =
+ glamor_get_pixmap_private(pixmap);
+ EGLImageKHR old;
+
+ old = pixmap_priv->base.image;
+ if (old) {
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn);
+
+ eglDestroyImageKHR(glamor_egl->display, old);
+ }
+ pixmap_priv->base.image = image;
+}
+
Bool
glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
{
@@ -275,8 +290,6 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
- struct glamor_pixmap_private *pixmap_priv =
- glamor_get_pixmap_private(pixmap);
struct glamor_egl_screen_private *glamor_egl;
EGLImageKHR image;
GLuint texture;
@@ -311,7 +324,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
glamor_create_texture_from_image(screen, image, &texture);
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_texture(pixmap, texture);
- pixmap_priv->base.image = image;
+ glamor_egl_set_pixmap_image(pixmap, image);
ret = TRUE;
done:
@@ -325,8 +338,6 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
- struct glamor_pixmap_private *pixmap_priv =
- glamor_get_pixmap_private(pixmap);
struct glamor_egl_screen_private *glamor_egl;
EGLImageKHR image;
GLuint texture;
@@ -346,7 +357,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
glamor_create_texture_from_image(screen, image, &texture);
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_texture(pixmap, texture);
- pixmap_priv->base.image = image;
+ glamor_egl_set_pixmap_image(pixmap, image);
ret = TRUE;
done:
@@ -419,8 +430,8 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
if (image == EGL_NO_IMAGE_KHR)
goto failure;
- pixmap_priv->base.image = image;
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
+ glamor_egl_set_pixmap_image(pixmap, image);
}
bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
@@ -519,16 +530,17 @@ glamor_pixmap_from_fd(ScreenPtr screen,
#endif
}
-static void
-_glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
+void
+glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
{
- ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
- struct glamor_egl_screen_private *glamor_egl =
- glamor_egl_get_screen_private(scrn);
struct glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
- if (pixmap_priv->base.image) {
+ if (pixmap_priv && pixmap_priv->base.image) {
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
+ struct glamor_egl_screen_private *glamor_egl =
+ glamor_egl_get_screen_private(scrn);
+
/* Before destroy an image which was attached to
* a texture. we must call glFlush to make sure the
* operation on that texture has been done.*/
@@ -541,9 +553,6 @@ _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
_X_EXPORT void
glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
{
- ScrnInfoPtr scrn = xf86ScreenToScrn(front->drawable.pScreen);
- struct glamor_egl_screen_private *glamor_egl =
- glamor_egl_get_screen_private(scrn);
EGLImageKHR temp;
struct glamor_pixmap_private *front_priv =
glamor_get_pixmap_private(front);
@@ -558,15 +567,12 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
- glamor_egl->front_image = front_priv->base.image;
}
void
glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
{
- if (pixmap->refcnt == 1)
- _glamor_egl_destroy_pixmap_image(pixmap);
glamor_destroy_textured_pixmap(pixmap);
}
@@ -583,17 +589,8 @@ glamor_egl_close_screen(ScreenPtr screen)
screen_pixmap = screen->GetScreenPixmap(screen);
pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
- eglDestroyImageKHR(glamor_egl->display, glamor_egl->front_image);
+ eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
pixmap_priv->base.image = NULL;
- glamor_egl->front_image = NULL;
-
- if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) {
- pixmap_priv = glamor_get_pixmap_private(*glamor_egl->back_pixmap);
- if (pixmap_priv->base.image) {
- eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
- pixmap_priv->base.image = NULL;
- }
- }
screen->CloseScreen = glamor_egl->saved_close_screen;
diff --git a/xorg-server/glamor/glamor_egl_stubs.c b/xorg-server/glamor/glamor_egl_stubs.c
index 028d1cc05..a93f62dcb 100644
--- a/xorg-server/glamor/glamor_egl_stubs.c
+++ b/xorg-server/glamor/glamor_egl_stubs.c
@@ -36,7 +36,7 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
}
void
-glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
{
}
diff --git a/xorg-server/glamor/glamor_fbo.c b/xorg-server/glamor/glamor_fbo.c
index 42738268c..8d73e4765 100644
--- a/xorg-server/glamor/glamor_fbo.c
+++ b/xorg-server/glamor/glamor_fbo.c
@@ -126,7 +126,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
#endif
}
-void
+static void
glamor_purge_fbo(glamor_pixmap_fbo *fbo)
{
glamor_make_current(fbo->glamor_priv);
@@ -540,8 +540,6 @@ glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
if (fbo)
glamor_destroy_fbo(fbo);
}
-
- free(priv);
}
Bool
diff --git a/xorg-server/glamor/glamor_priv.h b/xorg-server/glamor/glamor_priv.h
index 885f12a6d..f69949790 100644
--- a/xorg-server/glamor/glamor_priv.h
+++ b/xorg-server/glamor/glamor_priv.h
@@ -306,7 +306,6 @@ typedef struct glamor_screen_private {
int linear_max_nstops;
int radial_max_nstops;
- PixmapPtr *back_pixmap;
int screen_fbo;
struct glamor_saved_procs saved_procs;
char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
@@ -654,7 +653,6 @@ glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private *glamor_priv, int w,
int h, GLenum format, int flag);
void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv);
-void glamor_purge_fbo(glamor_pixmap_fbo *fbo);
void glamor_init_pixmap_fbo(ScreenPtr screen);
void glamor_fini_pixmap_fbo(ScreenPtr screen);
diff --git a/xorg-server/glamor/glamor_xv.c b/xorg-server/glamor/glamor_xv.c
index 26bdef66b..83e24adb2 100644
--- a/xorg-server/glamor/glamor_xv.c
+++ b/xorg-server/glamor/glamor_xv.c
@@ -208,15 +208,14 @@ glamor_xv_query_image_attributes(int id,
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
- *h = *h;
- *w = *w;
- size = *w;
+ *h = ALIGN(*h, 2);
+ size = ALIGN(*w, 4);
if (pitches)
pitches[0] = size;
size *= *h;
if (offsets)
offsets[1] = size;
- tmp = *w >> 1;
+ tmp = ALIGN(*w >> 1, 4);
if (pitches)
pitches[1] = pitches[2] = tmp;
tmp *= (*h >> 1);
@@ -413,9 +412,6 @@ glamor_xv_put_image(glamor_port_private *port_priv,
s2offset = s3offset = srcPitch2 = 0;
- srcPitch = width;
- srcPitch2 = width >> 1;
-
if (!port_priv->src_pix[0] ||
(width != port_priv->src_pix_w || height != port_priv->src_pix_h)) {
int i;
@@ -439,11 +435,13 @@ glamor_xv_put_image(glamor_port_private *port_priv,
}
top = (src_y) & ~1;
- nlines = (src_y + height) - top;
+ nlines = (src_y + src_h) - top;
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
+ srcPitch = ALIGN(width, 4);
+ srcPitch2 = ALIGN(width >> 1, 4);
s2offset = srcPitch * height;
s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1));
s2offset += ((top >> 1) * srcPitch2);
@@ -454,18 +452,18 @@ glamor_xv_put_image(glamor_port_private *port_priv,
s3offset = tmp;
}
glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0],
- 0, 0, srcPitch, nlines,
- port_priv->src_pix[0]->devKind,
+ 0, 0, width, nlines,
+ srcPitch,
buf + (top * srcPitch), 0);
glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1],
- 0, 0, srcPitch2, (nlines + 1) >> 1,
- port_priv->src_pix[1]->devKind,
+ 0, 0, width >> 1, (nlines + 1) >> 1,
+ srcPitch2,
buf + s2offset, 0);
glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2],
- 0, 0, srcPitch2, (nlines + 1) >> 1,
- port_priv->src_pix[2]->devKind,
+ 0, 0, width >> 1, (nlines + 1) >> 1,
+ srcPitch2,
buf + s3offset, 0);
break;
default:
diff --git a/xorg-server/glx/clientinfo.c b/xorg-server/glx/clientinfo.c
index 4aaa4c967..74ad91991 100644
--- a/xorg-server/glx/clientinfo.c
+++ b/xorg-server/glx/clientinfo.c
@@ -33,18 +33,22 @@ static int
set_client_info(__GLXclientState * cl, xGLXSetClientInfoARBReq * req,
unsigned bytes_per_version)
{
+ ClientPtr client = cl->client;
char *gl_extensions;
char *glx_extensions;
+ int size;
+
+ REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq);
/* Verify that the size of the packet matches the size inferred from the
* sizes specified for the various fields.
*/
- const unsigned expected_size = sz_xGLXSetClientInfoARBReq
- + (req->numVersions * bytes_per_version)
- + __GLX_PAD(req->numGLExtensionBytes)
- + __GLX_PAD(req->numGLXExtensionBytes);
+ size = sz_xGLXSetClientInfoARBReq;
+ size = safe_add(size, safe_mul(req->numVersions, bytes_per_version));
+ size = safe_add(size, safe_pad(req->numGLExtensionBytes));
+ size = safe_add(size, safe_pad(req->numGLXExtensionBytes));
- if (req->length != (expected_size / 4))
+ if (size < 0 || req->length != (size / 4))
return BadLength;
/* Verify that the actual length of the GL extension string matches what's
@@ -80,8 +84,11 @@ __glXDisp_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
int
__glXDispSwap_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc;
+ REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq);
+
req->length = bswap_16(req->length);
req->numVersions = bswap_32(req->numVersions);
req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes);
@@ -99,8 +106,11 @@ __glXDisp_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc)
int
__glXDispSwap_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc;
+ REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq);
+
req->length = bswap_16(req->length);
req->numVersions = bswap_32(req->numVersions);
req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes);
diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c
index 8d3fa9ff7..e836af8d5 100644
--- a/xorg-server/glx/glxcmds.c
+++ b/xorg-server/glx/glxcmds.c
@@ -198,6 +198,12 @@ __glXdirectContextDestroy(__GLXcontext * context)
free(context);
}
+static int
+__glXdirectContextLoseCurrent(__GLXcontext * context)
+{
+ return GL_TRUE;
+}
+
_X_HIDDEN __GLXcontext *
__glXdirectContextCreate(__GLXscreen * screen,
__GLXconfig * modes, __GLXcontext * shareContext)
@@ -209,6 +215,7 @@ __glXdirectContextCreate(__GLXscreen * screen,
return NULL;
context->destroy = __glXdirectContextDestroy;
+ context->loseCurrent = __glXdirectContextLoseCurrent;
return context;
}
@@ -413,7 +420,9 @@ __glXDisp_DestroyContext(__GLXclientState * cl, GLbyte * pc)
&glxc, &err))
return err;
- FreeResourceByType(req->context, __glXContextRes, FALSE);
+ glxc->idExists = GL_FALSE;
+ if (!glxc->currentClient)
+ FreeResourceByType(req->context, __glXContextRes, FALSE);
return Success;
}
@@ -2023,7 +2032,7 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
left = (req->length << 2) - sz_xGLXRenderReq;
while (left > 0) {
__GLXrenderSizeData entry;
- int extra;
+ int extra = 0;
__GLXdispatchRenderProcPtr proc;
int err;
@@ -2042,6 +2051,9 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
cmdlen = hdr->length;
opcode = hdr->opcode;
+ if (left < cmdlen)
+ return BadLength;
+
/*
** Check for core opcodes and grab entry data.
*/
@@ -2055,24 +2067,21 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
return __glXError(GLXBadRenderRequest);
}
+ if (cmdlen < entry.bytes) {
+ return BadLength;
+ }
+
if (entry.varsize) {
/* variable size command */
extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE,
- client->swapped);
+ client->swapped,
+ left - __GLX_RENDER_HDR_SIZE);
if (extra < 0) {
- extra = 0;
- }
- if (cmdlen != __GLX_PAD(entry.bytes + extra)) {
return BadLength;
}
}
- else {
- /* constant size command */
- if (cmdlen != __GLX_PAD(entry.bytes)) {
- return BadLength;
- }
- }
- if (left < cmdlen) {
+
+ if (cmdlen != safe_pad(safe_add(entry.bytes, extra))) {
return BadLength;
}
@@ -2108,6 +2117,8 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
__GLX_DECLARE_SWAP_VARIABLES;
+ REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq);
+
req = (xGLXRenderLargeReq *) pc;
if (client->swapped) {
__GLX_SWAP_SHORT(&req->length);
@@ -2123,12 +2134,14 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
__glXResetLargeCommandStatus(cl);
return error;
}
+ if (safe_pad(req->dataBytes) < 0)
+ return BadLength;
dataBytes = req->dataBytes;
/*
** Check the request length.
*/
- if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) {
+ if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) {
client->errorValue = req->length;
/* Reset in case this isn't 1st request. */
__glXResetLargeCommandStatus(cl);
@@ -2138,7 +2151,8 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
if (cl->largeCmdRequestsSoFar == 0) {
__GLXrenderSizeData entry;
- int extra;
+ int extra = 0;
+ int left = (req->length << 2) - sz_xGLXRenderLargeReq;
size_t cmdlen;
int err;
@@ -2151,13 +2165,17 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
return __glXError(GLXBadLargeRequest);
}
+ if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE)
+ return BadLength;
+
hdr = (__GLXrenderLargeHeader *) pc;
if (client->swapped) {
__GLX_SWAP_INT(&hdr->length);
__GLX_SWAP_INT(&hdr->opcode);
}
- cmdlen = hdr->length;
opcode = hdr->opcode;
+ if ((cmdlen = safe_pad(hdr->length)) < 0)
+ return BadLength;
/*
** Check for core opcodes and grab entry data.
@@ -2175,21 +2193,18 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
** will be in the 1st request, so it's okay to do this.
*/
extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE,
- client->swapped);
+ client->swapped,
+ left - __GLX_RENDER_LARGE_HDR_SIZE);
if (extra < 0) {
- extra = 0;
- }
- /* large command's header is 4 bytes longer, so add 4 */
- if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) {
return BadLength;
}
}
- else {
- /* constant size command */
- if (cmdlen != __GLX_PAD(entry.bytes + 4)) {
- return BadLength;
- }
+
+ /* the +4 is safe because we know entry.bytes is small */
+ if (cmdlen != safe_pad(safe_add(entry.bytes + 4, extra))) {
+ return BadLength;
}
+
/*
** Make enough space in the buffer, then copy the entire request.
*/
@@ -2216,6 +2231,7 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
** We are receiving subsequent (i.e. not the first) requests of a
** multi request command.
*/
+ int bytesSoFar; /* including this packet */
/*
** Check the request number and the total request count.
@@ -2234,11 +2250,18 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
/*
** Check that we didn't get too much data.
*/
- if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) {
+ if ((bytesSoFar = safe_add(cl->largeCmdBytesSoFar, dataBytes)) < 0) {
+ client->errorValue = dataBytes;
+ __glXResetLargeCommandStatus(cl);
+ return __glXError(GLXBadLargeRequest);
+ }
+
+ if (bytesSoFar > cl->largeCmdBytesTotal) {
client->errorValue = dataBytes;
__glXResetLargeCommandStatus(cl);
return __glXError(GLXBadLargeRequest);
}
+
memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes);
cl->largeCmdBytesSoFar += dataBytes;
cl->largeCmdRequestsSoFar++;
@@ -2250,17 +2273,16 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
** This is the last request; it must have enough bytes to complete
** the command.
*/
- /* NOTE: the two pad macros have been added below; they are needed
- ** because the client library pads the total byte count, but not
- ** the per-request byte counts. The Protocol Encoding says the
- ** total byte count should not be padded, so a proposal will be
- ** made to the ARB to relax the padding constraint on the total
- ** byte count, thus preserving backward compatibility. Meanwhile,
- ** the padding done below fixes a bug that did not allow
- ** large commands of odd sizes to be accepted by the server.
+ /* NOTE: the pad macro below is needed because the client library
+ ** pads the total byte count, but not the per-request byte counts.
+ ** The Protocol Encoding says the total byte count should not be
+ ** padded, so a proposal will be made to the ARB to relax the
+ ** padding constraint on the total byte count, thus preserving
+ ** backward compatibility. Meanwhile, the padding done below
+ ** fixes a bug that did not allow large commands of odd sizes to
+ ** be accepted by the server.
*/
- if (__GLX_PAD(cl->largeCmdBytesSoFar) !=
- __GLX_PAD(cl->largeCmdBytesTotal)) {
+ if (safe_pad(cl->largeCmdBytesSoFar) != cl->largeCmdBytesTotal) {
client->errorValue = dataBytes;
__glXResetLargeCommandStatus(cl);
return __glXError(GLXBadLargeRequest);
diff --git a/xorg-server/glx/glxcmdsswap.c b/xorg-server/glx/glxcmdsswap.c
index 5d179f317..9ec1222f8 100644
--- a/xorg-server/glx/glxcmdsswap.c
+++ b/xorg-server/glx/glxcmdsswap.c
@@ -958,11 +958,13 @@ __glXDispSwap_RenderLarge(__GLXclientState * cl, GLbyte * pc)
int
__glXDispSwap_VendorPrivate(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
xGLXVendorPrivateReq *req;
GLint vendorcode;
__GLXdispatchVendorPrivProcPtr proc;
__GLX_DECLARE_SWAP_VARIABLES;
+ REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
req = (xGLXVendorPrivateReq *) pc;
__GLX_SWAP_SHORT(&req->length);
@@ -985,11 +987,13 @@ __glXDispSwap_VendorPrivate(__GLXclientState * cl, GLbyte * pc)
int
__glXDispSwap_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
xGLXVendorPrivateWithReplyReq *req;
GLint vendorcode;
__GLXdispatchVendorPrivProcPtr proc;
__GLX_DECLARE_SWAP_VARIABLES;
+ REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateWithReplyReq);
req = (xGLXVendorPrivateWithReplyReq *) pc;
__GLX_SWAP_SHORT(&req->length);
diff --git a/xorg-server/glx/glxext.c b/xorg-server/glx/glxext.c
index c2de3cedd..e41b881f2 100644
--- a/xorg-server/glx/glxext.c
+++ b/xorg-server/glx/glxext.c
@@ -66,6 +66,7 @@ static DevPrivateKeyRec glxClientPrivateKeyRec;
** Forward declarations.
*/
static int __glXDispatch(ClientPtr);
+static GLboolean __glXFreeContext(__GLXcontext * cx);
/*
** Called when the extension is reset.
@@ -133,6 +134,9 @@ DrawableGone(__GLXdrawable * glxPriv, XID xid)
next = c->next;
if (c->currentClient &&
(c->drawPriv == glxPriv || c->readPriv == glxPriv)) {
+ /* flush the context */
+ glFlush();
+ c->hasUnflushedCommands = GL_FALSE;
/* just force a re-bind the next time through */
(*c->loseCurrent) (c);
lastGLContext = NULL;
@@ -186,7 +190,7 @@ __glXRemoveFromContextList(__GLXcontext * cx)
/*
** Free a context.
*/
-GLboolean
+static GLboolean
__glXFreeContext(__GLXcontext * cx)
{
if (cx->idExists || cx->currentClient)
@@ -291,7 +295,7 @@ glxClientCallback(CallbackListPtr *list, void *closure, void *data)
c->loseCurrent(c);
lastGLContext = NULL;
c->currentClient = NULL;
- __glXFreeContext(c);
+ FreeResourceByType(c->id, __glXContextRes, FALSE);
}
}
diff --git a/xorg-server/glx/glxext.h b/xorg-server/glx/glxext.h
index 3f2dee696..cde0e1519 100644
--- a/xorg-server/glx/glxext.h
+++ b/xorg-server/glx/glxext.h
@@ -51,7 +51,6 @@
#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
#endif
-extern GLboolean __glXFreeContext(__GLXcontext * glxc);
extern void __glXFlushContextCache(void);
extern Bool __glXAddContext(__GLXcontext * cx);
diff --git a/xorg-server/glx/glxserver.h b/xorg-server/glx/glxserver.h
index a324b290f..9088ec478 100644
--- a/xorg-server/glx/glxserver.h
+++ b/xorg-server/glx/glxserver.h
@@ -177,7 +177,7 @@ typedef int (*__GLXprocPtr) (__GLXclientState *, char *pc);
/*
* Tables for computing the size of each rendering command.
*/
-typedef int (*gl_proto_size_func) (const GLbyte *, Bool);
+typedef int (*gl_proto_size_func) (const GLbyte *, Bool, int);
typedef struct {
int bytes;
@@ -228,6 +228,47 @@ extern void glxSwapQueryServerStringReply(ClientPtr client,
* Routines for computing the size of variably-sized rendering commands.
*/
+static _X_INLINE int
+safe_add(int a, int b)
+{
+ if (a < 0 || b < 0)
+ return -1;
+
+ if (INT_MAX - a < b)
+ return -1;
+
+ return a + b;
+}
+
+static _X_INLINE int
+safe_mul(int a, int b)
+{
+ if (a < 0 || b < 0)
+ return -1;
+
+ if (a == 0 || b == 0)
+ return 0;
+
+ if (a > INT_MAX / b)
+ return -1;
+
+ return a * b;
+}
+
+static _X_INLINE int
+safe_pad(int a)
+{
+ int ret;
+
+ if (a < 0)
+ return -1;
+
+ if ((ret = safe_add(a, 3)) < 0)
+ return -1;
+
+ return ret & (GLuint)~3;
+}
+
extern int __glXTypeSize(GLenum enm);
extern int __glXImageSize(GLenum format, GLenum type,
GLenum target, GLsizei w, GLsizei h, GLsizei d,
diff --git a/xorg-server/glx/indirect_program.c b/xorg-server/glx/indirect_program.c
index cda139ee6..5caee7b2a 100644
--- a/xorg-server/glx/indirect_program.c
+++ b/xorg-server/glx/indirect_program.c
@@ -56,6 +56,8 @@ DoGetProgramString(struct __GLXclientStateRec *cl, GLbyte * pc,
__GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error);
ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateWithReplyReq, 8);
+
pc += __GLX_VENDPRIV_HDR_SIZE;
if (cx != NULL) {
GLenum target;
diff --git a/xorg-server/glx/indirect_reqsize.c b/xorg-server/glx/indirect_reqsize.c
index abd076604..020aae2fe 100644
--- a/xorg-server/glx/indirect_reqsize.c
+++ b/xorg-server/glx/indirect_reqsize.c
@@ -31,24 +31,22 @@
#include "indirect_size.h"
#include "indirect_reqsize.h"
-#define __GLX_PAD(x) (((x) + 3) & ~3)
-
#if defined(__CYGWIN__) || defined(__MINGW32__)
#undef HAVE_ALIAS
#endif
#ifdef HAVE_ALIAS
#define ALIAS2(from,to) \
- GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \
+ GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \
__attribute__ ((alias( # to )));
#define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize )
#else
#define ALIAS(from,to) \
- GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \
- { return __glX ## to ## ReqSize( pc, swap ); }
+ GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \
+ { return __glX ## to ## ReqSize( pc, swap, reqlen ); }
#endif
int
-__glXCallListsReqSize(const GLbyte * pc, Bool swap)
+__glXCallListsReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei n = *(GLsizei *) (pc + 0);
GLenum type = *(GLenum *) (pc + 4);
@@ -60,11 +58,11 @@ __glXCallListsReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glCallLists_size(type);
- return __GLX_PAD((compsize * n));
+ return safe_pad(safe_mul(compsize, n));
}
int
-__glXBitmapReqSize(const GLbyte * pc, Bool swap)
+__glXBitmapReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -88,7 +86,7 @@ __glXBitmapReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXFogfvReqSize(const GLbyte * pc, Bool swap)
+__glXFogfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 0);
GLsizei compsize;
@@ -98,11 +96,11 @@ __glXFogfvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glFogfv_size(pname);
- return __GLX_PAD((compsize * 4));
+ return safe_pad(safe_mul(compsize, 4));
}
int
-__glXLightfvReqSize(const GLbyte * pc, Bool swap)
+__glXLightfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 4);
GLsizei compsize;
@@ -112,11 +110,11 @@ __glXLightfvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glLightfv_size(pname);
- return __GLX_PAD((compsize * 4));
+ return safe_pad(safe_mul(compsize, 4));
}
int
-__glXLightModelfvReqSize(const GLbyte * pc, Bool swap)
+__glXLightModelfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 0);
GLsizei compsize;
@@ -126,11 +124,11 @@ __glXLightModelfvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glLightModelfv_size(pname);
- return __GLX_PAD((compsize * 4));
+ return safe_pad(safe_mul(compsize, 4));
}
int
-__glXMaterialfvReqSize(const GLbyte * pc, Bool swap)
+__glXMaterialfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 4);
GLsizei compsize;
@@ -140,11 +138,11 @@ __glXMaterialfvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glMaterialfv_size(pname);
- return __GLX_PAD((compsize * 4));
+ return safe_pad(safe_mul(compsize, 4));
}
int
-__glXPolygonStippleReqSize(const GLbyte * pc, Bool swap)
+__glXPolygonStippleReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -164,7 +162,7 @@ __glXPolygonStippleReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXTexParameterfvReqSize(const GLbyte * pc, Bool swap)
+__glXTexParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 4);
GLsizei compsize;
@@ -174,11 +172,11 @@ __glXTexParameterfvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glTexParameterfv_size(pname);
- return __GLX_PAD((compsize * 4));
+ return safe_pad(safe_mul(compsize, 4));
}
int
-__glXTexImage1DReqSize(const GLbyte * pc, Bool swap)
+__glXTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -206,7 +204,7 @@ __glXTexImage1DReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXTexImage2DReqSize(const GLbyte * pc, Bool swap)
+__glXTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -236,7 +234,7 @@ __glXTexImage2DReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXTexEnvfvReqSize(const GLbyte * pc, Bool swap)
+__glXTexEnvfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 4);
GLsizei compsize;
@@ -246,11 +244,11 @@ __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glTexEnvfv_size(pname);
- return __GLX_PAD((compsize * 4));
+ return safe_pad(safe_mul(compsize, 4));
}
int
-__glXTexGendvReqSize(const GLbyte * pc, Bool swap)
+__glXTexGendvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 4);
GLsizei compsize;
@@ -260,11 +258,11 @@ __glXTexGendvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glTexGendv_size(pname);
- return __GLX_PAD((compsize * 8));
+ return safe_pad(safe_mul(compsize, 8));
}
int
-__glXTexGenfvReqSize(const GLbyte * pc, Bool swap)
+__glXTexGenfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 4);
GLsizei compsize;
@@ -274,11 +272,11 @@ __glXTexGenfvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glTexGenfv_size(pname);
- return __GLX_PAD((compsize * 4));
+ return safe_pad(safe_mul(compsize, 4));
}
int
-__glXPixelMapfvReqSize(const GLbyte * pc, Bool swap)
+__glXPixelMapfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei mapsize = *(GLsizei *) (pc + 4);
@@ -286,11 +284,11 @@ __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap)
mapsize = bswap_32(mapsize);
}
- return __GLX_PAD((mapsize * 4));
+ return safe_pad(safe_mul(mapsize, 4));
}
int
-__glXPixelMapusvReqSize(const GLbyte * pc, Bool swap)
+__glXPixelMapusvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei mapsize = *(GLsizei *) (pc + 4);
@@ -298,11 +296,11 @@ __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap)
mapsize = bswap_32(mapsize);
}
- return __GLX_PAD((mapsize * 2));
+ return safe_pad(safe_mul(mapsize, 2));
}
int
-__glXDrawPixelsReqSize(const GLbyte * pc, Bool swap)
+__glXDrawPixelsReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -330,7 +328,7 @@ __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap)
+__glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei n = *(GLsizei *) (pc + 0);
@@ -338,11 +336,11 @@ __glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap)
n = bswap_32(n);
}
- return __GLX_PAD((n * 4) + (n * 4));
+ return safe_pad(safe_add(safe_mul(n, 4), safe_mul(n, 4)));
}
int
-__glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap)
+__glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -370,7 +368,7 @@ __glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap)
+__glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -400,7 +398,7 @@ __glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXColorTableReqSize(const GLbyte * pc, Bool swap)
+__glXColorTableReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -428,7 +426,7 @@ __glXColorTableReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap)
+__glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 4);
GLsizei compsize;
@@ -438,11 +436,11 @@ __glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glColorTableParameterfv_size(pname);
- return __GLX_PAD((compsize * 4));
+ return safe_pad(safe_mul(compsize, 4));
}
int
-__glXColorSubTableReqSize(const GLbyte * pc, Bool swap)
+__glXColorSubTableReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -470,7 +468,7 @@ __glXColorSubTableReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap)
+__glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -498,7 +496,7 @@ __glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap)
+__glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = 0;
@@ -528,7 +526,7 @@ __glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap)
+__glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 4);
GLsizei compsize;
@@ -538,11 +536,11 @@ __glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glConvolutionParameterfv_size(pname);
- return __GLX_PAD((compsize * 4));
+ return safe_pad(safe_mul(compsize, 4));
}
int
-__glXTexImage3DReqSize(const GLbyte * pc, Bool swap)
+__glXTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = *(GLint *) (pc + 8);
@@ -579,7 +577,7 @@ __glXTexImage3DReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap)
+__glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLint row_length = *(GLint *) (pc + 4);
GLint image_height = *(GLint *) (pc + 8);
@@ -613,7 +611,7 @@ __glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap)
}
int
-__glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap)
+__glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei imageSize = *(GLsizei *) (pc + 20);
@@ -621,11 +619,11 @@ __glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap)
imageSize = bswap_32(imageSize);
}
- return __GLX_PAD(imageSize);
+ return safe_pad(imageSize);
}
int
-__glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap)
+__glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei imageSize = *(GLsizei *) (pc + 24);
@@ -633,11 +631,11 @@ __glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap)
imageSize = bswap_32(imageSize);
}
- return __GLX_PAD(imageSize);
+ return safe_pad(imageSize);
}
int
-__glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap)
+__glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei imageSize = *(GLsizei *) (pc + 28);
@@ -645,11 +643,11 @@ __glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap)
imageSize = bswap_32(imageSize);
}
- return __GLX_PAD(imageSize);
+ return safe_pad(imageSize);
}
int
-__glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap)
+__glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei imageSize = *(GLsizei *) (pc + 36);
@@ -657,11 +655,11 @@ __glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap)
imageSize = bswap_32(imageSize);
}
- return __GLX_PAD(imageSize);
+ return safe_pad(imageSize);
}
int
-__glXPointParameterfvReqSize(const GLbyte * pc, Bool swap)
+__glXPointParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum pname = *(GLenum *) (pc + 0);
GLsizei compsize;
@@ -671,11 +669,11 @@ __glXPointParameterfvReqSize(const GLbyte * pc, Bool swap)
}
compsize = __glPointParameterfv_size(pname);
- return __GLX_PAD((compsize * 4));
+ return safe_pad(safe_mul(compsize, 4));
}
int
-__glXDrawBuffersReqSize(const GLbyte * pc, Bool swap)
+__glXDrawBuffersReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei n = *(GLsizei *) (pc + 0);
@@ -683,11 +681,11 @@ __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap)
n = bswap_32(n);
}
- return __GLX_PAD((n * 4));
+ return safe_pad(safe_mul(n, 4));
}
int
-__glXProgramStringARBReqSize(const GLbyte * pc, Bool swap)
+__glXProgramStringARBReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei len = *(GLsizei *) (pc + 8);
@@ -695,11 +693,11 @@ __glXProgramStringARBReqSize(const GLbyte * pc, Bool swap)
len = bswap_32(len);
}
- return __GLX_PAD(len);
+ return safe_pad(len);
}
int
-__glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei n = *(GLsizei *) (pc + 4);
@@ -707,11 +705,11 @@ __glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap)
n = bswap_32(n);
}
- return __GLX_PAD((n * 8));
+ return safe_pad(safe_mul(n, 8));
}
int
-__glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei n = *(GLsizei *) (pc + 4);
@@ -719,11 +717,11 @@ __glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap)
n = bswap_32(n);
}
- return __GLX_PAD((n * 16));
+ return safe_pad(safe_mul(n, 16));
}
int
-__glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei n = *(GLsizei *) (pc + 4);
@@ -731,11 +729,11 @@ __glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap)
n = bswap_32(n);
}
- return __GLX_PAD((n * 24));
+ return safe_pad(safe_mul(n, 24));
}
int
-__glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei n = *(GLsizei *) (pc + 4);
@@ -743,11 +741,11 @@ __glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap)
n = bswap_32(n);
}
- return __GLX_PAD((n * 12));
+ return safe_pad(safe_mul(n, 12));
}
int
-__glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei n = *(GLsizei *) (pc + 4);
@@ -755,11 +753,11 @@ __glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap)
n = bswap_32(n);
}
- return __GLX_PAD((n * 6));
+ return safe_pad(safe_mul(n, 6));
}
int
-__glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLsizei n = *(GLsizei *) (pc + 4);
@@ -767,7 +765,7 @@ __glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap)
n = bswap_32(n);
}
- return __GLX_PAD((n * 32));
+ return safe_pad(safe_mul(n, 32));
}
ALIAS(Fogiv, Fogfv)
diff --git a/xorg-server/glx/indirect_reqsize.h b/xorg-server/glx/indirect_reqsize.h
index 49d400c45..632a85b1c 100644
--- a/xorg-server/glx/indirect_reqsize.h
+++ b/xorg-server/glx/indirect_reqsize.h
@@ -36,115 +36,156 @@
#define PURE
#endif
-extern PURE _X_HIDDEN int __glXCallListsReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXBitmapReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXFogfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXFogivReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXLightfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXLightivReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXLightModelfvReqSize(const GLbyte * pc,
- Bool swap);
-extern PURE _X_HIDDEN int __glXLightModelivReqSize(const GLbyte * pc,
- Bool swap);
-extern PURE _X_HIDDEN int __glXMaterialfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXMaterialivReqSize(const GLbyte * pc, Bool swap);
+extern PURE _X_HIDDEN int __glXCallListsReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXBitmapReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXFogfvReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXFogivReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXLightfvReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXLightivReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXLightModelfvReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXLightModelivReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXMaterialfvReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXMaterialivReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXPolygonStippleReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXTexParameterfvReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXTexParameterivReqSize(const GLbyte * pc,
- Bool swap);
-extern PURE _X_HIDDEN int __glXTexImage1DReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexImage2DReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexEnvivReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexGendvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexGenfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexGenivReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXMap1dReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXMap1fReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXMap2dReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXMap2fReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXPixelMapuivReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap);
+ Bool swap, int reqlen);
+extern PURE _X_HIDDEN int __glXTexImage1DReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXTexImage2DReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXTexEnvivReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXTexGendvReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXTexGenfvReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXTexGenivReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXMap1dReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXMap1fReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXMap2dReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXMap2fReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXPixelMapuivReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
+extern PURE _X_HIDDEN int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXPrioritizeTexturesReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXTexSubImage1DReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXTexSubImage2DReqSize(const GLbyte * pc,
- Bool swap);
-extern PURE _X_HIDDEN int __glXColorTableReqSize(const GLbyte * pc, Bool swap);
+ Bool swap, int reqlen);
+extern PURE _X_HIDDEN int __glXColorTableReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXColorTableParameterfvReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXColorTableParameterivReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXColorSubTableReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXConvolutionFilter1DReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXConvolutionFilter2DReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXConvolutionParameterfvReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXConvolutionParameterivReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXSeparableFilter2DReqSize(const GLbyte * pc,
- Bool swap);
-extern PURE _X_HIDDEN int __glXTexImage3DReqSize(const GLbyte * pc, Bool swap);
+ Bool swap, int reqlen);
+extern PURE _X_HIDDEN int __glXTexImage3DReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXTexSubImage3DReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXCompressedTexImage1DReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXCompressedTexImage2DReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXCompressedTexImage3DReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXCompressedTexSubImage1DReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXCompressedTexSubImage2DReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXCompressedTexSubImage3DReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXPointParameterfvReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXPointParameterivReqSize(const GLbyte * pc,
- Bool swap);
-extern PURE _X_HIDDEN int __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap);
+ Bool swap, int reqlen);
+extern PURE _X_HIDDEN int __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXProgramStringARBReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXDeleteFramebuffersReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXDeleteRenderbuffersReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs1dvNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs1fvNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs1svNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs2dvNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs2fvNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs2svNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs3dvNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs3fvNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs3svNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs4dvNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs4fvNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs4svNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap, int reqlen);
extern PURE _X_HIDDEN int __glXVertexAttribs4ubvNVReqSize(const GLbyte * pc,
- Bool swap);
+ Bool swap,
+ int reqlen);
#undef PURE
diff --git a/xorg-server/glx/indirect_texture_compression.c b/xorg-server/glx/indirect_texture_compression.c
index cda765698..1ebf7f3a2 100644
--- a/xorg-server/glx/indirect_texture_compression.c
+++ b/xorg-server/glx/indirect_texture_compression.c
@@ -43,6 +43,8 @@ __glXDisp_GetCompressedTexImage(struct __GLXclientStateRec *cl, GLbyte * pc)
__GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error);
ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
+
pc += __GLX_SINGLE_HDR_SIZE;
if (cx != NULL) {
const GLenum target = *(GLenum *) (pc + 0);
@@ -87,6 +89,8 @@ __glXDispSwap_GetCompressedTexImage(struct __GLXclientStateRec *cl, GLbyte * pc)
__glXForceCurrent(cl, bswap_32(req->contextTag), &error);
ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
+
pc += __GLX_SINGLE_HDR_SIZE;
if (cx != NULL) {
const GLenum target = (GLenum) bswap_32(*(int *) (pc + 0));
diff --git a/xorg-server/glx/indirect_util.c b/xorg-server/glx/indirect_util.c
index 926e57c78..9ba28157c 100644
--- a/xorg-server/glx/indirect_util.c
+++ b/xorg-server/glx/indirect_util.c
@@ -73,12 +73,17 @@ __glXGetAnswerBuffer(__GLXclientState * cl, size_t required_size,
void *local_buffer, size_t local_size, unsigned alignment)
{
void *buffer = local_buffer;
- const unsigned mask = alignment - 1;
+ const intptr_t mask = alignment - 1;
if (local_size < required_size) {
- const size_t worst_case_size = required_size + alignment;
+ size_t worst_case_size;
intptr_t temp_buf;
+ if (required_size < SIZE_MAX - alignment)
+ worst_case_size = required_size + alignment;
+ else
+ return NULL;
+
if (cl->returnBufSize < worst_case_size) {
void *temp = realloc(cl->returnBuf, worst_case_size);
diff --git a/xorg-server/glx/rensize.c b/xorg-server/glx/rensize.c
index ba22d1067..6bfe99b2a 100644
--- a/xorg-server/glx/rensize.c
+++ b/xorg-server/glx/rensize.c
@@ -43,19 +43,11 @@
(((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \
((a & 0xff00U)<<8) | ((a & 0xffU)<<24))
-static int
-Map1Size(GLint k, GLint order)
-{
- if (order <= 0 || k < 0)
- return -1;
- return k * order;
-}
-
int
-__glXMap1dReqSize(const GLbyte * pc, Bool swap)
+__glXMap1dReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum target;
- GLint order, k;
+ GLint order;
target = *(GLenum *) (pc + 16);
order = *(GLint *) (pc + 20);
@@ -63,15 +55,16 @@ __glXMap1dReqSize(const GLbyte * pc, Bool swap)
target = SWAPL(target);
order = SWAPL(order);
}
- k = __glMap1d_size(target);
- return 8 * Map1Size(k, order);
+ if (order < 1)
+ return -1;
+ return safe_mul(8, safe_mul(__glMap1d_size(target), order));
}
int
-__glXMap1fReqSize(const GLbyte * pc, Bool swap)
+__glXMap1fReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum target;
- GLint order, k;
+ GLint order;
target = *(GLenum *) (pc + 0);
order = *(GLint *) (pc + 12);
@@ -79,23 +72,24 @@ __glXMap1fReqSize(const GLbyte * pc, Bool swap)
target = SWAPL(target);
order = SWAPL(order);
}
- k = __glMap1f_size(target);
- return 4 * Map1Size(k, order);
+ if (order < 1)
+ return -1;
+ return safe_mul(4, safe_mul(__glMap1f_size(target), order));
}
static int
Map2Size(int k, int majorOrder, int minorOrder)
{
- if (majorOrder <= 0 || minorOrder <= 0 || k < 0)
+ if (majorOrder < 1 || minorOrder < 1)
return -1;
- return k * majorOrder * minorOrder;
+ return safe_mul(k, safe_mul(majorOrder, minorOrder));
}
int
-__glXMap2dReqSize(const GLbyte * pc, Bool swap)
+__glXMap2dReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum target;
- GLint uorder, vorder, k;
+ GLint uorder, vorder;
target = *(GLenum *) (pc + 32);
uorder = *(GLint *) (pc + 36);
@@ -105,15 +99,14 @@ __glXMap2dReqSize(const GLbyte * pc, Bool swap)
uorder = SWAPL(uorder);
vorder = SWAPL(vorder);
}
- k = __glMap2d_size(target);
- return 8 * Map2Size(k, uorder, vorder);
+ return safe_mul(8, Map2Size(__glMap2d_size(target), uorder, vorder));
}
int
-__glXMap2fReqSize(const GLbyte * pc, Bool swap)
+__glXMap2fReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
GLenum target;
- GLint uorder, vorder, k;
+ GLint uorder, vorder;
target = *(GLenum *) (pc + 0);
uorder = *(GLint *) (pc + 12);
@@ -123,8 +116,7 @@ __glXMap2fReqSize(const GLbyte * pc, Bool swap)
uorder = SWAPL(uorder);
vorder = SWAPL(vorder);
}
- k = __glMap2f_size(target);
- return 4 * Map2Size(k, uorder, vorder);
+ return safe_mul(4, Map2Size(__glMap2f_size(target), uorder, vorder));
}
/**
@@ -175,14 +167,16 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
GLint bytesPerElement, elementsPerGroup, groupsPerRow;
GLint groupSize, rowSize, padding, imageSize;
+ if (w == 0 || h == 0 || d == 0)
+ return 0;
+
if (w < 0 || h < 0 || d < 0 ||
(type == GL_BITMAP &&
(format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) {
return -1;
}
- if (w == 0 || h == 0 || d == 0)
- return 0;
+ /* proxy targets have no data */
switch (target) {
case GL_PROXY_TEXTURE_1D:
case GL_PROXY_TEXTURE_2D:
@@ -199,6 +193,12 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
return 0;
}
+ /* real data has to have real sizes */
+ if (imageHeight < 0 || rowLength < 0 || skipImages < 0 || skipRows < 0)
+ return -1;
+ if (alignment != 1 && alignment != 2 && alignment != 4 && alignment != 8)
+ return -1;
+
if (type == GL_BITMAP) {
if (rowLength > 0) {
groupsPerRow = rowLength;
@@ -207,11 +207,14 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
groupsPerRow = w;
}
rowSize = bits_to_bytes(groupsPerRow);
+ if (rowSize < 0)
+ return -1;
padding = (rowSize % alignment);
if (padding) {
rowSize += alignment - padding;
}
- return ((h + skipRows) * rowSize);
+
+ return safe_mul(safe_add(h, skipRows), rowSize);
}
else {
switch (format) {
@@ -224,6 +227,11 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
case GL_ALPHA:
case GL_LUMINANCE:
case GL_INTENSITY:
+ case GL_RED_INTEGER_EXT:
+ case GL_GREEN_INTEGER_EXT:
+ case GL_BLUE_INTEGER_EXT:
+ case GL_ALPHA_INTEGER_EXT:
+ case GL_LUMINANCE_INTEGER_EXT:
elementsPerGroup = 1;
break;
case GL_422_EXT:
@@ -234,14 +242,19 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
case GL_DEPTH_STENCIL_MESA:
case GL_YCBCR_MESA:
case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE_ALPHA_INTEGER_EXT:
elementsPerGroup = 2;
break;
case GL_RGB:
case GL_BGR:
+ case GL_RGB_INTEGER_EXT:
+ case GL_BGR_INTEGER_EXT:
elementsPerGroup = 3;
break;
case GL_RGBA:
case GL_BGRA:
+ case GL_RGBA_INTEGER_EXT:
+ case GL_BGRA_INTEGER_EXT:
case GL_ABGR_EXT:
elementsPerGroup = 4;
break;
@@ -293,6 +306,7 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
default:
return -1;
}
+ /* known safe by the switches above, not checked */
groupSize = bytesPerElement * elementsPerGroup;
if (rowLength > 0) {
groupsPerRow = rowLength;
@@ -300,18 +314,21 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
else {
groupsPerRow = w;
}
- rowSize = groupsPerRow * groupSize;
+
+ if ((rowSize = safe_mul(groupsPerRow, groupSize)) < 0)
+ return -1;
padding = (rowSize % alignment);
if (padding) {
rowSize += alignment - padding;
}
- if (imageHeight > 0) {
- imageSize = (imageHeight + skipRows) * rowSize;
- }
- else {
- imageSize = (h + skipRows) * rowSize;
- }
- return ((d + skipImages) * imageSize);
+
+ if (imageHeight > 0)
+ h = imageHeight;
+ h = safe_add(h, skipRows);
+
+ imageSize = safe_mul(h, rowSize);
+
+ return safe_mul(safe_add(d, skipImages), imageSize);
}
}
@@ -342,13 +359,14 @@ __glXTypeSize(GLenum enm)
}
int
-__glXDrawArraysReqSize(const GLbyte * pc, Bool swap)
+__glXDrawArraysReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
__GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc;
__GLXdispatchDrawArraysComponentHeader *compHeader;
GLint numVertexes = hdr->numVertexes;
GLint numComponents = hdr->numComponents;
GLint arrayElementSize = 0;
+ GLint x, size;
int i;
if (swap) {
@@ -357,6 +375,13 @@ __glXDrawArraysReqSize(const GLbyte * pc, Bool swap)
}
pc += sizeof(__GLXdispatchDrawArraysHeader);
+ reqlen -= sizeof(__GLXdispatchDrawArraysHeader);
+
+ size = safe_mul(sizeof(__GLXdispatchDrawArraysComponentHeader),
+ numComponents);
+ if (size < 0 || reqlen < 0 || reqlen < size)
+ return -1;
+
compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc;
for (i = 0; i < numComponents; i++) {
@@ -400,17 +425,18 @@ __glXDrawArraysReqSize(const GLbyte * pc, Bool swap)
return -1;
}
- arrayElementSize += __GLX_PAD(numVals * __glXTypeSize(datatype));
+ x = safe_pad(safe_mul(numVals, __glXTypeSize(datatype)));
+ if ((arrayElementSize = safe_add(arrayElementSize, x)) < 0)
+ return -1;
pc += sizeof(__GLXdispatchDrawArraysComponentHeader);
}
- return ((numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader)) +
- (numVertexes * arrayElementSize));
+ return safe_add(size, safe_mul(numVertexes, arrayElementSize));
}
int
-__glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap)
+__glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
{
__GLXdispatchConvolutionFilterHeader *hdr =
(__GLXdispatchConvolutionFilterHeader *) pc;
@@ -435,9 +461,7 @@ __glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap)
/* XXX Should rowLength be used for either or both image? */
image1size = __glXImageSize(format, type, 0, w, 1, 1,
0, rowLength, 0, 0, alignment);
- image1size = __GLX_PAD(image1size);
image2size = __glXImageSize(format, type, 0, h, 1, 1,
0, rowLength, 0, 0, alignment);
- return image1size + image2size;
-
+ return safe_add(safe_pad(image1size), image2size);
}
diff --git a/xorg-server/glx/single2.c b/xorg-server/glx/single2.c
index 53b661d20..a6ea614fd 100644
--- a/xorg-server/glx/single2.c
+++ b/xorg-server/glx/single2.c
@@ -45,11 +45,14 @@
int
__glXDisp_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
GLsizei size;
GLenum type;
__GLXcontext *cx;
int error;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
+
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
return error;
@@ -76,10 +79,13 @@ __glXDisp_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
int
__glXDisp_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
__GLXcontext *cx;
GLsizei size;
int error;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
return error;
@@ -104,7 +110,7 @@ __glXDisp_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
int
__glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc)
{
- ClientPtr client;
+ ClientPtr client = cl->client;
xGLXRenderModeReply reply;
__GLXcontext *cx;
GLint nitems = 0, retBytes = 0, retval, newModeCheck;
@@ -112,6 +118,8 @@ __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc)
GLenum newMode;
int error;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
return error;
@@ -188,7 +196,6 @@ __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc)
** selection array, as per the API for glRenderMode itself.
*/
noChangeAllowed:;
- client = cl->client;
reply = (xGLXRenderModeReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
@@ -207,9 +214,12 @@ __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc)
int
__glXDisp_Flush(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
__GLXcontext *cx;
int error;
+ REQUEST_SIZE_MATCH(xGLXSingleReq);
+
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
return error;
@@ -223,10 +233,12 @@ __glXDisp_Flush(__GLXclientState * cl, GLbyte * pc)
int
__glXDisp_Finish(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
__GLXcontext *cx;
- ClientPtr client;
int error;
+ REQUEST_SIZE_MATCH(xGLXSingleReq);
+
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
return error;
@@ -317,7 +329,7 @@ __glXcombine_strings(const char *cext_string, const char *sext_string)
int
DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap)
{
- ClientPtr client;
+ ClientPtr client = cl->client;
__GLXcontext *cx;
GLenum name;
const char *string;
@@ -327,6 +339,8 @@ DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap)
char *buf = NULL, *buf1 = NULL;
GLint length = 0;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
/* If the client has the opposite byte order, swap the contextTag and
* the name.
*/
@@ -343,7 +357,6 @@ DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap)
pc += __GLX_SINGLE_HDR_SIZE;
name = *(GLenum *) (pc + 0);
string = (const char *) glGetString(name);
- client = cl->client;
if (string == NULL)
string = "";
diff --git a/xorg-server/glx/single2swap.c b/xorg-server/glx/single2swap.c
index 764501f59..53490694b 100644
--- a/xorg-server/glx/single2swap.c
+++ b/xorg-server/glx/single2swap.c
@@ -41,6 +41,7 @@
int
__glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
GLsizei size;
GLenum type;
@@ -48,6 +49,8 @@ __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
__GLXcontext *cx;
int error;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
+
__GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
@@ -77,12 +80,15 @@ __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
int
__glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
__GLXcontext *cx;
GLsizei size;
__GLX_DECLARE_SWAP_VARIABLES;
int error;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
__GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
@@ -109,7 +115,7 @@ __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
int
__glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
{
- ClientPtr client;
+ ClientPtr client = cl->client;
__GLXcontext *cx;
xGLXRenderModeReply reply;
GLint nitems = 0, retBytes = 0, retval, newModeCheck;
@@ -120,6 +126,8 @@ __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
__GLX_DECLARE_SWAP_ARRAY_VARIABLES;
int error;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
__GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
@@ -200,7 +208,6 @@ __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
** selection array, as per the API for glRenderMode itself.
*/
noChangeAllowed:;
- client = cl->client;
reply = (xGLXRenderModeReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
@@ -224,11 +231,14 @@ __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
int
__glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
__GLXcontext *cx;
int error;
__GLX_DECLARE_SWAP_VARIABLES;
+ REQUEST_SIZE_MATCH(xGLXSingleReq);
+
__GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
@@ -243,12 +253,14 @@ __glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc)
int
__glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc)
{
+ ClientPtr client = cl->client;
__GLXcontext *cx;
- ClientPtr client;
int error;
__GLX_DECLARE_SWAP_VARIABLES;
+ REQUEST_SIZE_MATCH(xGLXSingleReq);
+
__GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
@@ -260,7 +272,6 @@ __glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc)
cx->hasUnflushedCommands = GL_FALSE;
/* Send empty reply packet to indicate finish is finished */
- client = cl->client;
__GLX_BEGIN_REPLY(0);
__GLX_PUT_RETVAL(0);
__GLX_SWAP_REPLY_HEADER();
diff --git a/xorg-server/glx/singlepix.c b/xorg-server/glx/singlepix.c
index 506fdaad5..54ed7fd21 100644
--- a/xorg-server/glx/singlepix.c
+++ b/xorg-server/glx/singlepix.c
@@ -51,6 +51,8 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc)
int error;
char *answer, answerBuffer[200];
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 28);
+
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
return error;
@@ -65,7 +67,7 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc)
lsbFirst = *(GLboolean *) (pc + 25);
compsize = __glReadPixels_size(format, type, width, height);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
@@ -100,6 +102,8 @@ __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc)
char *answer, answerBuffer[200];
GLint width = 0, height = 0, depth = 1;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 20);
+
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
return error;
@@ -124,7 +128,7 @@ __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc)
compsize =
__glGetTexImage_size(target, level, format, type, width, height, depth);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
__GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -157,6 +161,8 @@ __glXDisp_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc)
GLubyte answerBuffer[200];
char *answer;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
return error;
@@ -217,15 +223,13 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1);
- if (compsize < 0)
- compsize = 0;
- if (compsize2 < 0)
- compsize2 = 0;
- compsize = __GLX_PAD(compsize);
- compsize2 = __GLX_PAD(compsize2);
+ if ((compsize = safe_pad(compsize)) < 0)
+ return BadLength;
+ if ((compsize2 = safe_pad(compsize2)) < 0)
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
- __GLX_GET_ANSWER_BUFFER(answer, cl, compsize + compsize2, 1);
+ __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1);
__glXClearErrorOccured();
glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4),
*(GLenum *) (pc + 8), answer, answer + compsize, NULL);
@@ -249,7 +253,8 @@ int
__glXDisp_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
-
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
}
@@ -257,7 +262,8 @@ int
__glXDisp_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
-
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
}
@@ -296,7 +302,7 @@ GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
*/
compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
__GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -323,7 +329,8 @@ int
__glXDisp_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
-
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
}
@@ -331,7 +338,8 @@ int
__glXDisp_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
-
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
}
@@ -365,7 +373,7 @@ GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
*/
compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
__GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -390,7 +398,8 @@ int
__glXDisp_GetHistogram(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
-
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
}
@@ -398,7 +407,8 @@ int
__glXDisp_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
-
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
}
@@ -426,7 +436,7 @@ GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
__GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -450,7 +460,8 @@ int
__glXDisp_GetMinmax(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
-
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
}
@@ -458,7 +469,8 @@ int
__glXDisp_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
-
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
}
@@ -491,7 +503,7 @@ GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
*/
compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
__GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -517,7 +529,8 @@ int
__glXDisp_GetColorTable(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
-
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
}
@@ -525,6 +538,7 @@ int
__glXDisp_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
-
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
}
diff --git a/xorg-server/glx/singlepixswap.c b/xorg-server/glx/singlepixswap.c
index 846910153..9eff5923d 100644
--- a/xorg-server/glx/singlepixswap.c
+++ b/xorg-server/glx/singlepixswap.c
@@ -53,6 +53,8 @@ __glXDispSwap_ReadPixels(__GLXclientState * cl, GLbyte * pc)
int error;
char *answer, answerBuffer[200];
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 28);
+
__GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
@@ -75,7 +77,7 @@ __glXDispSwap_ReadPixels(__GLXclientState * cl, GLbyte * pc)
lsbFirst = *(GLboolean *) (pc + 25);
compsize = __glReadPixels_size(format, type, width, height);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
@@ -114,6 +116,8 @@ __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc)
char *answer, answerBuffer[200];
GLint width = 0, height = 0, depth = 1;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 20);
+
__GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
@@ -144,7 +148,7 @@ __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc)
compsize =
__glGetTexImage_size(target, level, format, type, width, height, depth);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
__GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -184,6 +188,8 @@ __glXDispSwap_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc)
__GLX_DECLARE_SWAP_VARIABLES;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
__GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
if (!cx) {
@@ -251,15 +257,13 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1);
- if (compsize < 0)
- compsize = 0;
- if (compsize2 < 0)
- compsize2 = 0;
- compsize = __GLX_PAD(compsize);
- compsize2 = __GLX_PAD(compsize2);
+ if ((compsize = safe_pad(compsize)) < 0)
+ return BadLength;
+ if ((compsize2 = safe_pad(compsize2)) < 0)
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
- __GLX_GET_ANSWER_BUFFER(answer, cl, compsize + compsize2, 1);
+ __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1);
__glXClearErrorOccured();
glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4),
*(GLenum *) (pc + 8), answer, answer + compsize, NULL);
@@ -285,7 +289,9 @@ int
__glXDispSwap_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
}
@@ -293,7 +299,9 @@ int
__glXDispSwap_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
}
@@ -338,7 +346,7 @@ GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
*/
compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
__GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -367,7 +375,9 @@ int
__glXDispSwap_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
}
@@ -375,7 +385,9 @@ int
__glXDispSwap_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
}
@@ -415,7 +427,7 @@ GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
*/
compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
__GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -441,7 +453,9 @@ int
__glXDispSwap_GetHistogram(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
}
@@ -449,7 +463,9 @@ int
__glXDispSwap_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
}
@@ -483,7 +499,7 @@ GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
__GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -507,7 +523,9 @@ int
__glXDispSwap_GetMinmax(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
}
@@ -515,7 +533,9 @@ int
__glXDispSwap_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
}
@@ -554,7 +574,7 @@ GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
*/
compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
if (compsize < 0)
- compsize = 0;
+ return BadLength;
glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
__GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -581,7 +601,9 @@ int
__glXDispSwap_GetColorTable(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
}
@@ -589,6 +611,8 @@ int
__glXDispSwap_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc)
{
const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
+ ClientPtr client = cl->client;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
}
diff --git a/xorg-server/glx/swap_interval.c b/xorg-server/glx/swap_interval.c
index 17bc99207..232055080 100644
--- a/xorg-server/glx/swap_interval.c
+++ b/xorg-server/glx/swap_interval.c
@@ -46,6 +46,8 @@ DoSwapInterval(__GLXclientState * cl, GLbyte * pc, int do_swap)
__GLXcontext *cx;
GLint interval;
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 4);
+
cx = __glXLookupContextByTag(cl, tag);
if ((cx == NULL) || (cx->pGlxScreen == NULL)) {
diff --git a/xorg-server/glx/unpack.h b/xorg-server/glx/unpack.h
index 52fba74e1..2b1ebcf02 100644
--- a/xorg-server/glx/unpack.h
+++ b/xorg-server/glx/unpack.h
@@ -83,7 +83,8 @@ extern xGLXSingleReply __glXReply;
** pointer.
*/
#define __GLX_GET_ANSWER_BUFFER(res,cl,size,align) \
- if ((size) > sizeof(answerBuffer)) { \
+ if (size < 0) return BadLength; \
+ else if ((size) > sizeof(answerBuffer)) { \
int bump; \
if ((cl)->returnBufSize < (size)+(align)) { \
(cl)->returnBuf = (GLbyte*)realloc((cl)->returnBuf, \
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c
index 93a48a9cd..907bbebae 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.c
@@ -1292,7 +1292,7 @@ ephyrPutColors(ScreenPtr pScreen, int n, xColorItem * pdefs)
if (p > max)
max = p;
- hostx_set_cmap_entry(p,
+ hostx_set_cmap_entry(pScreen, p,
pdefs->red >> 8,
pdefs->green >> 8, pdefs->blue >> 8);
pdefs++;
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.h b/xorg-server/hw/kdrive/ephyr/ephyr.h
index 2395a7f7e..18bfe11ff 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr.h
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.h
@@ -83,6 +83,7 @@ typedef struct _ephyrScrPriv {
KdScreenInfo *screen;
int mynum; /* Screen number */
+ unsigned long cmap[256];
/**
* Per-screen Xlib-using state for glamor (private to
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c
index 8d6d5e83b..f64861b50 100644
--- a/xorg-server/hw/kdrive/ephyr/hostx.c
+++ b/xorg-server/hw/kdrive/ephyr/hostx.c
@@ -82,8 +82,6 @@ struct EphyrHostXVars {
KdScreenInfo **screens;
long damage_debug_msec;
-
- unsigned long cmap[256];
};
/* memset ( missing> ) instead of below */
@@ -751,9 +749,12 @@ hostx_calculate_color_shift(unsigned long mask)
}
void
-hostx_set_cmap_entry(unsigned char idx,
+hostx_set_cmap_entry(ScreenPtr pScreen, unsigned char idx,
unsigned char r, unsigned char g, unsigned char b)
{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
/* need to calculate the shifts for RGB because server could be BGR. */
/* XXX Not sure if this is correct for 8 on 16, but this works for 8 on 24.*/
static int rshift, bshift, gshift = 0;
@@ -765,7 +766,7 @@ hostx_set_cmap_entry(unsigned char idx,
gshift = hostx_calculate_color_shift(HostX.visual->green_mask);
bshift = hostx_calculate_color_shift(HostX.visual->blue_mask);
}
- HostX.cmap[idx] = ((r << rshift) & HostX.visual->red_mask) |
+ scrpriv->cmap[idx] = ((r << rshift) & HostX.visual->red_mask) |
((g << gshift) & HostX.visual->green_mask) |
((b << bshift) & HostX.visual->blue_mask);
}
@@ -1017,7 +1018,7 @@ hostx_paint_rect(KdScreenInfo *screen,
unsigned char pixel =
*(unsigned char *) (scrpriv->fb_data + idx);
xcb_image_put_pixel(scrpriv->ximg, x, y,
- HostX.cmap[pixel]);
+ scrpriv->cmap[pixel]);
break;
}
default:
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.h b/xorg-server/hw/kdrive/ephyr/hostx.h
index 87acd5a50..93aaa509c 100644
--- a/xorg-server/hw/kdrive/ephyr/hostx.h
+++ b/xorg-server/hw/kdrive/ephyr/hostx.h
@@ -141,7 +141,7 @@ hostx_get_visual_masks(KdScreenInfo *screen,
CARD32 *rmsk, CARD32 *gmsk, CARD32 *bmsk);
void
-hostx_set_cmap_entry(unsigned char idx,
+hostx_set_cmap_entry(ScreenPtr pScreen, unsigned char idx,
unsigned char r, unsigned char g, unsigned char b);
void *hostx_screen_init(KdScreenInfo *screen,
diff --git a/xorg-server/hw/xfree86/common/xf86AutoConfig.c b/xorg-server/hw/xfree86/common/xf86AutoConfig.c
index 03dad150a..1450afbfc 100644
--- a/xorg-server/hw/xfree86/common/xf86AutoConfig.c
+++ b/xorg-server/hw/xfree86/common/xf86AutoConfig.c
@@ -208,7 +208,6 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
if (xf86Info.consoleFd >= 0 && (i < (nmatches - 1))) {
struct vis_identifier visid;
const char *cp;
- extern char xf86SolarisFbDev[PATH_MAX];
int iret;
SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid));
diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c
index ffd66fad6..221ec530b 100644
--- a/xorg-server/hw/xfree86/dri2/dri2ext.c
+++ b/xorg-server/hw/xfree86/dri2/dri2ext.c
@@ -270,6 +270,9 @@ ProcDRI2GetBuffers(ClientPtr client)
unsigned int *attachments;
REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
+ if (stuff->count > (INT_MAX / 4))
+ return BadLength;
+
if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess,
&pDrawable, &status))
return status;
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/Makefile.am b/xorg-server/hw/xfree86/drivers/modesetting/Makefile.am
index 5b08600c1..82c4f2f32 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/Makefile.am
+++ b/xorg-server/hw/xfree86/drivers/modesetting/Makefile.am
@@ -48,6 +48,9 @@ modesetting_drv_la_SOURCES = \
driver.h \
drmmode_display.c \
drmmode_display.h \
+ dumb_bo.c \
+ dumb_bo.h \
+ present.c \
vblank.c \
$(NULL)
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/dri2.c b/xorg-server/hw/xfree86/drivers/modesetting/dri2.c
index 6c88060b0..63cb0659d 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/dri2.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/dri2.c
@@ -43,8 +43,6 @@
#include "dri2.h"
#ifdef GLAMOR
-#define GLAMOR_FOR_XORG 1
-#include "glamor.h"
enum ms_dri2_frame_event_type {
MS_DRI2_QUEUE_SWAP,
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/driver.c b/xorg-server/hw/xfree86/drivers/modesetting/driver.c
index 592f2469b..1ebf807e5 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/driver.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/driver.c
@@ -61,11 +61,6 @@
#include "driver.h"
-#ifdef GLAMOR
-#define GLAMOR_FOR_XORG 1
-#include "glamor.h"
-#endif
-
static void AdjustFrame(ScrnInfoPtr pScrn, int x, int y);
static Bool CloseScreen(ScreenPtr pScreen);
static Bool EnterVT(ScrnInfoPtr pScrn);
@@ -453,11 +448,12 @@ dispatch_dirty_region(ScrnInfoPtr scrn,
modesettingPtr ms = modesettingPTR(scrn);
RegionPtr dirty = DamageRegion(damage);
unsigned num_cliprects = REGION_NUM_RECTS(dirty);
+ int ret = 0;
if (num_cliprects) {
drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip));
BoxPtr rect = REGION_RECTS(dirty);
- int i, ret;
+ int i;
if (!clip)
return -ENOMEM;
@@ -474,12 +470,8 @@ dispatch_dirty_region(ScrnInfoPtr scrn,
ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects);
free(clip);
DamageEmpty(damage);
- if (ret) {
- if (ret == -EINVAL)
- return ret;
- }
}
- return 0;
+ return ret;
}
static void
@@ -593,7 +585,7 @@ try_enable_glamor(ScrnInfoPtr pScrn)
Bool do_glamor = (!accel_method_str ||
strcmp(accel_method_str, "glamor") == 0);
- ms->glamor = FALSE;
+ ms->drmmode.glamor = FALSE;
#ifdef GLAMOR
if (!do_glamor) {
@@ -604,7 +596,7 @@ try_enable_glamor(ScrnInfoPtr pScrn)
if (xf86LoadSubModule(pScrn, GLAMOR_EGL_MODULE_NAME)) {
if (glamor_egl_init(pScrn, ms->fd)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "glamor initialized\n");
- ms->glamor = TRUE;
+ ms->drmmode.glamor = TRUE;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"glamor initialization failed\n");
@@ -788,7 +780,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
try_enable_glamor(pScrn);
- if (ms->glamor) {
+ if (ms->drmmode.glamor) {
xf86LoadSubModule(pScrn, "dri2");
} else {
Bool prefer_shadow = TRUE;
@@ -861,7 +853,7 @@ msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
*size = stride;
- return ((uint8_t *) ms->drmmode.front_bo->ptr + row * stride + offset);
+ return ((uint8_t *) ms->drmmode.front_bo.dumb->ptr + row * stride + offset);
}
static void
@@ -877,7 +869,8 @@ CreateScreenResources(ScreenPtr pScreen)
modesettingPtr ms = modesettingPTR(pScrn);
PixmapPtr rootPixmap;
Bool ret;
- void *pixels;
+ void *pixels = NULL;
+ int err;
pScreen->CreateScreenResources = ms->createScreenResources;
ret = pScreen->CreateScreenResources(pScreen);
@@ -886,27 +879,19 @@ CreateScreenResources(ScreenPtr pScreen)
if (!drmmode_set_desired_modes(pScrn, &ms->drmmode))
return FALSE;
-#ifdef GLAMOR
- if (ms->glamor) {
- if (!glamor_egl_create_textured_screen_ext(pScreen,
- ms->drmmode.front_bo->handle,
- pScrn->displayWidth *
- pScrn->bitsPerPixel / 8,
- NULL)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "glamor_egl_create_textured_screen_ext() failed\n");
- return FALSE;
- }
- }
-#endif
+ if (!drmmode_glamor_handle_new_screen_pixmap(&ms->drmmode))
+ return FALSE;
drmmode_uevent_init(pScrn, &ms->drmmode);
if (!ms->drmmode.sw_cursor)
drmmode_map_cursor_bos(pScrn, &ms->drmmode);
- pixels = drmmode_map_front_bo(&ms->drmmode);
- if (!pixels)
- return FALSE;
+
+ if (!ms->drmmode.gbm) {
+ pixels = drmmode_map_front_bo(&ms->drmmode);
+ if (!pixels)
+ return FALSE;
+ }
rootPixmap = pScreen->GetScreenPixmap(pScreen);
@@ -922,18 +907,22 @@ CreateScreenResources(ScreenPtr pScreen)
return FALSE;
}
- ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
- pScreen, rootPixmap);
+ err = drmModeDirtyFB(ms->fd, ms->drmmode.fb_id, NULL, 0);
- if (ms->damage) {
- DamageRegister(&rootPixmap->drawable, ms->damage);
- ms->dirty_enabled = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
- }
- else {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to create screen damage record\n");
- return FALSE;
+ if (err != -EINVAL && err != -ENOSYS) {
+ ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+ pScreen, rootPixmap);
+
+ if (ms->damage) {
+ DamageRegister(&rootPixmap->drawable, ms->damage);
+ ms->dirty_enabled = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to create screen damage record\n");
+ return FALSE;
+ }
}
return ret;
}
@@ -996,6 +985,11 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
if (!SetMaster(pScrn))
return FALSE;
+#ifdef GLAMOR_HAS_GBM
+ if (ms->drmmode.glamor)
+ ms->drmmode.gbm = glamor_egl_get_gbm_device(pScreen);
+#endif
+
/* HW dependent - FIXME */
pScrn->displayWidth = pScrn->virtualX;
if (!drmmode_create_initial_bos(pScrn, &ms->drmmode))
@@ -1053,7 +1047,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
fbPictureInit(pScreen, NULL, 0);
#ifdef GLAMOR
- if (ms->glamor) {
+ if (ms->drmmode.glamor) {
if (!glamor_init(pScreen,
GLAMOR_USE_EGL_SCREEN |
GLAMOR_USE_SCREEN |
@@ -1106,6 +1100,19 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
xf86DPMSInit(pScreen, xf86DPMSSet, 0);
+#ifdef GLAMOR
+ if (ms->drmmode.glamor) {
+ XF86VideoAdaptorPtr glamor_adaptor;
+
+ glamor_adaptor = glamor_xv_init(pScreen, 16);
+ if (glamor_adaptor != NULL)
+ xf86XVScreenInit(pScreen, &glamor_adaptor, 1);
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to initialize XV support.\n");
+ }
+#endif
+
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@@ -1116,11 +1123,16 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
}
#ifdef GLAMOR
- if (ms->glamor) {
+ if (ms->drmmode.glamor) {
if (!ms_dri2_screen_init(pScreen)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize the DRI2 extension.\n");
}
+
+ if (!ms_present_screen_init(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to initialize the Present extension.\n");
+ }
}
#endif
@@ -1190,7 +1202,7 @@ CloseScreen(ScreenPtr pScreen)
modesettingPtr ms = modesettingPTR(pScrn);
#ifdef GLAMOR
- if (ms->glamor) {
+ if (ms->drmmode.glamor) {
ms_dri2_close_screen(pScreen);
}
#endif
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/driver.h b/xorg-server/hw/xfree86/drivers/modesetting/driver.h
index 9eda1c4da..3decc3eea 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/driver.h
+++ b/xorg-server/hw/xfree86/drivers/modesetting/driver.h
@@ -33,6 +33,14 @@
#include <xf86Crtc.h>
#include <damage.h>
+#ifdef GLAMOR
+#define GLAMOR_FOR_XORG 1
+#include "glamor.h"
+#ifdef GLAMOR_HAS_GBM
+#include <gbm.h>
+#endif
+#endif
+
#include "drmmode_display.h"
#define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
@@ -97,7 +105,6 @@ typedef struct _modesettingRec {
Bool dirty_enabled;
uint32_t cursor_width, cursor_height;
- Bool glamor;
} modesettingRec, *modesettingPtr;
#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
@@ -107,6 +114,10 @@ uint32_t ms_drm_queue_alloc(xf86CrtcPtr crtc,
ms_drm_handler_proc handler,
ms_drm_abort_proc abort);
+void ms_drm_abort(ScrnInfoPtr scrn,
+ Bool (*match)(void *data, void *match_data),
+ void *match_data);
+
xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
xf86CrtcPtr ms_covering_crtc(ScrnInfoPtr scrn, BoxPtr box,
xf86CrtcPtr desired, BoxPtr crtc_box_ret);
@@ -122,3 +133,5 @@ void ms_dri2_close_screen(ScreenPtr screen);
Bool ms_vblank_screen_init(ScreenPtr screen);
void ms_vblank_close_screen(ScreenPtr screen);
+
+Bool ms_present_screen_init(ScreenPtr screen);
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c
index ef9009e98..824500bae 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -33,6 +33,7 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
+#include "dumb_bo.h"
#include "xf86str.h"
#include "X11/Xatom.h"
#include "micmap.h"
@@ -49,112 +50,64 @@
#include "driver.h"
-static struct dumb_bo *
-dumb_bo_create(int fd,
- const unsigned width, const unsigned height, const unsigned bpp)
-{
- struct drm_mode_create_dumb arg;
- struct dumb_bo *bo;
- int ret;
-
- bo = calloc(1, sizeof(*bo));
- if (!bo)
- return NULL;
-
- memset(&arg, 0, sizeof(arg));
- arg.width = width;
- arg.height = height;
- arg.bpp = bpp;
-
- ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
- if (ret)
- goto err_free;
-
- bo->handle = arg.handle;
- bo->size = arg.size;
- bo->pitch = arg.pitch;
-
- return bo;
- err_free:
- free(bo);
- return NULL;
-}
-
static int
-dumb_bo_map(int fd, struct dumb_bo *bo)
+drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
{
- struct drm_mode_map_dumb arg;
int ret;
- void *map;
- if (bo->ptr) {
- bo->map_count++;
- return 0;
+#ifdef GLAMOR_HAS_GBM
+ if (bo->gbm) {
+ gbm_bo_destroy(bo->gbm);
+ bo->gbm = NULL;
}
+#endif
- memset(&arg, 0, sizeof(arg));
- arg.handle = bo->handle;
-
- ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
- if (ret)
- return ret;
-
- map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, arg.offset);
- if (map == MAP_FAILED)
- return -errno;
+ if (bo->dumb) {
+ ret = dumb_bo_destroy(drmmode->fd, bo->dumb);
+ if (ret == 0)
+ bo->dumb = NULL;
+ }
- bo->ptr = map;
return 0;
}
-#if 0
-static int
-dumb_bo_unmap(int fd, struct dumb_bo *bo)
+static uint32_t
+drmmode_bo_get_pitch(drmmode_bo *bo)
{
- bo->map_count--;
- return 0;
-}
+#ifdef GLAMOR_HAS_GBM
+ if (bo->gbm)
+ return gbm_bo_get_stride(bo->gbm);
#endif
-int
-dumb_bo_destroy(int fd, struct dumb_bo *bo)
-{
- struct drm_mode_destroy_dumb arg;
- int ret;
-
- if (bo->ptr) {
- munmap(bo->ptr, bo->size);
- bo->ptr = NULL;
- }
-
- memset(&arg, 0, sizeof(arg));
- arg.handle = bo->handle;
- ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
- if (ret)
- return -errno;
-
- free(bo);
- return 0;
+ return bo->dumb->pitch;
}
-struct dumb_bo *
-dumb_get_bo_from_fd(int fd, int handle, int pitch, int size)
+uint32_t
+drmmode_bo_get_handle(drmmode_bo *bo)
{
- struct dumb_bo *bo;
- int ret;
+#ifdef GLAMOR_HAS_GBM
+ if (bo->gbm)
+ return gbm_bo_get_handle(bo->gbm).u32;
+#endif
- bo = calloc(1, sizeof(*bo));
- if (!bo)
- return NULL;
+ return bo->dumb->handle;
+}
- ret = drmPrimeFDToHandle(fd, handle, &bo->handle);
- if (ret) {
- free(bo);
- return NULL;
+static Bool
+drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
+ unsigned width, unsigned height, unsigned bpp)
+{
+#ifdef GLAMOR_HAS_GBM
+ if (drmmode->glamor) {
+ bo->gbm = gbm_bo_create(drmmode->gbm, width, height,
+ GBM_FORMAT_ARGB8888,
+ GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+ return bo->gbm != NULL;
}
- bo->pitch = pitch;
- bo->size = size;
- return bo;
+#endif
+
+ bo->dumb = dumb_bo_create(drmmode->fd, width, height, bpp);
+ return bo->dumb != NULL;
}
Bool
@@ -232,18 +185,8 @@ drmmode_ConvertToKMode(ScrnInfoPtr scrn,
static void
drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
{
-#if 0
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
-
-// drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-// drmmode_ptr drmmode = drmmode_crtc->drmmode;
-
- /* bonghits in the randr 1.2 - uses dpms to disable crtc - bad buzz */
- if (mode == DPMSModeOff) {
-// drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-// 0, 0, 0, NULL, 0, NULL);
- }
-#endif
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_crtc->dpms_mode = mode;
}
#if 0
@@ -315,8 +258,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
ret = drmModeAddFB(drmmode->fd,
pScrn->virtualX, height,
pScrn->depth, pScrn->bitsPerPixel,
- drmmode->front_bo->pitch,
- drmmode->front_bo->handle, &drmmode->fb_id);
+ drmmode_bo_get_pitch(&drmmode->front_bo),
+ drmmode_bo_get_handle(&drmmode->front_bo),
+ &drmmode->fb_id);
if (ret < 0) {
ErrorF("failed to add fb %d\n", ret);
return FALSE;
@@ -385,6 +329,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
if (crtc->scrn->pScreen)
xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
+
+ crtc->funcs->dpms(crtc, DPMSModeOn);
+
/* go through all the outputs and force DPMS them back on? */
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
@@ -432,25 +379,32 @@ drmmode_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
}
static void
-drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
+drmmode_set_cursor(xf86CrtcPtr crtc)
{
- modesettingPtr ms = modesettingPTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
- int i;
- uint32_t *ptr;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
uint32_t handle = drmmode_crtc->cursor_bo->handle;
+ modesettingPtr ms = modesettingPTR(crtc->scrn);
+ static Bool use_set_cursor2 = TRUE;
int ret;
- /* cursor should be mapped already */
- ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr);
+ if (use_set_cursor2) {
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+ CursorPtr cursor = xf86_config->cursor;
- for (i = 0; i < ms->cursor_width * ms->cursor_height; i++)
- ptr[i] = image[i]; // cpu_to_le32(image[i]);
+ ret =
+ drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+ handle, ms->cursor_width, ms->cursor_height,
+ cursor->bits->xhot, cursor->bits->yhot);
+ if (ret == -EINVAL)
+ use_set_cursor2 = FALSE;
+ else
+ return;
+ }
+
+ ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle,
+ ms->cursor_width, ms->cursor_height);
- ret =
- drmModeSetCursor(drmmode_crtc->drmmode->fd,
- drmmode_crtc->mode_crtc->crtc_id, handle,
- ms->cursor_width, ms->cursor_height);
if (ret) {
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
@@ -462,46 +416,44 @@ drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
}
static void
-drmmode_hide_cursor(xf86CrtcPtr crtc)
+drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
- drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ int i;
+ uint32_t *ptr;
- drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0,
- ms->cursor_width, ms->cursor_height);
+ /* cursor should be mapped already */
+ ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr);
+
+ for (i = 0; i < ms->cursor_width * ms->cursor_height; i++)
+ ptr[i] = image[i]; // cpu_to_le32(image[i]);
+ if (drmmode_crtc->cursor_up)
+ drmmode_set_cursor(crtc);
}
static void
-drmmode_show_cursor(xf86CrtcPtr crtc)
+drmmode_hide_cursor(xf86CrtcPtr crtc)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
- uint32_t handle = drmmode_crtc->cursor_bo->handle;
- static Bool use_set_cursor2 = TRUE;
-
- if (use_set_cursor2) {
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
- CursorPtr cursor = xf86_config->cursor;
- int ret;
-
- ret =
- drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
- handle, ms->cursor_width, ms->cursor_height,
- cursor->bits->xhot, cursor->bits->yhot);
- if (ret == -EINVAL)
- use_set_cursor2 = FALSE;
- else
- return;
- }
- drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle,
+ drmmode_crtc->cursor_up = FALSE;
+ drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0,
ms->cursor_width, ms->cursor_height);
}
static void
+drmmode_show_cursor(xf86CrtcPtr crtc)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_crtc->cursor_up = TRUE;
+ drmmode_set_cursor(crtc);
+}
+
+static void
drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t * red, uint16_t * green,
uint16_t * blue, int size)
{
@@ -1019,8 +971,7 @@ static const char *const output_names[] = {
};
static void
-drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num,
- int *num_dvi, int *num_hdmi)
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
{
xf86OutputPtr output;
drmModeConnectorPtr koutput;
@@ -1172,6 +1123,42 @@ drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
}
}
+Bool
+drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
+{
+#ifdef GLAMOR
+ ScrnInfoPtr scrn = drmmode->scrn;
+ ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn);
+ PixmapPtr screen_pixmap;
+ void *gbm_bo;
+
+ if (!drmmode->glamor)
+ return TRUE;
+
+#ifdef GLAMOR_HAS_GBM
+ gbm_bo = drmmode->front_bo.gbm;
+ screen_pixmap = screen->GetScreenPixmap(screen);
+
+ if (!glamor_egl_create_textured_pixmap_from_gbm_bo(screen_pixmap, gbm_bo)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
+ return FALSE;
+ }
+ glamor_set_screen_pixmap(screen_pixmap, NULL);
+#else
+ if (!glamor_egl_create_textured_screen(screen,
+ drmmode_bo_get_handle(&drmmode->front_bo),
+ scrn->displayWidth *
+ scrn->bitsPerPixel / 8)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "glamor_egl_create_textured_screen() failed\n");
+ return FALSE;
+ }
+#endif
+#endif
+
+ return TRUE;
+}
+
static Bool
drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
{
@@ -1180,14 +1167,14 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
drmmode_crtc_private_ptr
drmmode_crtc = xf86_config->crtc[0]->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
- struct dumb_bo *old_front = NULL;
+ drmmode_bo old_front;
Bool ret;
ScreenPtr screen = xf86ScrnToScreen(scrn);
uint32_t old_fb_id;
int i, pitch, old_width, old_height, old_pitch;
int cpp = (scrn->bitsPerPixel + 7) / 8;
PixmapPtr ppix = screen->GetScreenPixmap(screen);
- void *new_pixels;
+ void *new_pixels = NULL;
if (scrn->virtualX == width && scrn->virtualY == height)
return TRUE;
@@ -1202,16 +1189,15 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
old_width = scrn->virtualX;
old_height = scrn->virtualY;
- old_pitch = drmmode->front_bo->pitch;
+ old_pitch = drmmode_bo_get_pitch(&drmmode->front_bo);
old_fb_id = drmmode->fb_id;
old_front = drmmode->front_bo;
- drmmode->front_bo =
- dumb_bo_create(drmmode->fd, width, height, scrn->bitsPerPixel);
- if (!drmmode->front_bo)
+ if (!drmmode_create_bo(drmmode, &drmmode->front_bo,
+ width, height, scrn->bitsPerPixel))
goto fail;
- pitch = drmmode->front_bo->pitch;
+ pitch = drmmode_bo_get_pitch(&drmmode->front_bo);
scrn->virtualX = width;
scrn->virtualY = height;
@@ -1219,30 +1205,32 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
scrn->bitsPerPixel, pitch,
- drmmode->front_bo->handle, &drmmode->fb_id);
+ drmmode_bo_get_handle(&drmmode->front_bo),
+ &drmmode->fb_id);
if (ret)
goto fail;
- new_pixels = drmmode_map_front_bo(drmmode);
- if (!new_pixels)
- goto fail;
+ if (!drmmode->gbm) {
+ new_pixels = drmmode_map_front_bo(drmmode);
+ if (!new_pixels)
+ goto fail;
+ }
- if (!drmmode->shadow_enable)
- screen->ModifyPixmapHeader(ppix, width, height, -1, -1,
- pitch, new_pixels);
- else {
- void *new_shadow;
+ if (drmmode->shadow_enable) {
uint32_t size = scrn->displayWidth * scrn->virtualY *
((scrn->bitsPerPixel + 7) >> 3);
- new_shadow = calloc(1, size);
- if (new_shadow == NULL)
+ new_pixels = calloc(1, size);
+ if (new_pixels == NULL)
goto fail;
free(drmmode->shadow_fb);
- drmmode->shadow_fb = new_shadow;
- screen->ModifyPixmapHeader(ppix, width, height, -1, -1,
- pitch, drmmode->shadow_fb);
+ drmmode->shadow_fb = new_pixels;
}
+ screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch, new_pixels);
+
+ if (!drmmode_glamor_handle_new_screen_pixmap(drmmode))
+ goto fail;
+
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
@@ -1255,14 +1243,13 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
if (old_fb_id) {
drmModeRmFB(drmmode->fd, old_fb_id);
- dumb_bo_destroy(drmmode->fd, old_front);
+ drmmode_bo_destroy(drmmode, &old_front);
}
return TRUE;
fail:
- if (drmmode->front_bo)
- dumb_bo_destroy(drmmode->fd, drmmode->front_bo);
+ drmmode_bo_destroy(drmmode, &drmmode->front_bo);
drmmode->front_bo = old_front;
scrn->virtualX = old_width;
scrn->virtualY = old_height;
@@ -1279,7 +1266,7 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
Bool
drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
{
- int i, num_dvi = 0, num_hdmi = 0;
+ int i;
int ret;
uint64_t value = 0;
@@ -1307,7 +1294,7 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
drmmode_crtc_init(pScrn, drmmode, i);
for (i = 0; i < drmmode->mode_res->count_connectors; i++)
- drmmode_output_init(pScrn, drmmode, i, &num_dvi, &num_hdmi);
+ drmmode_output_init(pScrn, drmmode, i);
/* workout clones */
drmmode_clones_init(pScrn, drmmode);
@@ -1468,7 +1455,7 @@ drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
return TRUE;
}
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
static void
drmmode_handle_uevents(int fd, void *closure)
{
@@ -1488,7 +1475,7 @@ drmmode_handle_uevents(int fd, void *closure)
void
drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
{
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
struct udev *u;
struct udev_monitor *mon;
@@ -1521,7 +1508,7 @@ drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
void
drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
{
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
if (drmmode->uevent_handler) {
struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor);
@@ -1548,10 +1535,9 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
width = pScrn->virtualX;
height = pScrn->virtualY;
- drmmode->front_bo = dumb_bo_create(drmmode->fd, width, height, bpp);
- if (!drmmode->front_bo)
+ if (!drmmode_create_bo(drmmode, &drmmode->front_bo, width, height, bpp))
return FALSE;
- pScrn->displayWidth = drmmode->front_bo->pitch / cpp;
+ pScrn->displayWidth = drmmode_bo_get_pitch(&drmmode->front_bo) / cpp;
width = ms->cursor_width;
height = ms->cursor_height;
@@ -1571,14 +1557,14 @@ drmmode_map_front_bo(drmmode_ptr drmmode)
{
int ret;
- if (drmmode->front_bo->ptr)
- return drmmode->front_bo->ptr;
+ if (drmmode->front_bo.dumb->ptr)
+ return drmmode->front_bo.dumb->ptr;
- ret = dumb_bo_map(drmmode->fd, drmmode->front_bo);
+ ret = dumb_bo_map(drmmode->fd, drmmode->front_bo.dumb);
if (ret)
return NULL;
- return drmmode->front_bo->ptr;
+ return drmmode->front_bo.dumb->ptr;
}
@@ -1625,8 +1611,7 @@ drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
drmmode->fb_id = 0;
}
- dumb_bo_destroy(drmmode->fd, drmmode->front_bo);
- drmmode->front_bo = NULL;
+ drmmode_bo_destroy(drmmode, &drmmode->front_bo);
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h
index 987608c55..66d0ca260 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -28,17 +28,20 @@
#define DRMMODE_DISPLAY_H
#include "xf86drmMode.h"
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
#include "libudev.h"
#endif
-struct dumb_bo {
- uint32_t handle;
- uint32_t size;
- void *ptr;
- int map_count;
- uint32_t pitch;
-};
+#include "dumb_bo.h"
+
+struct gbm_device;
+
+typedef struct {
+ struct dumb_bo *dumb;
+#ifdef GLAMOR_HAS_GBM
+ struct gbm_bo *gbm;
+#endif
+} drmmode_bo;
typedef struct {
int fd;
@@ -48,14 +51,18 @@ typedef struct {
drmModeFBPtr mode_fb;
int cpp;
ScrnInfoPtr scrn;
-#ifdef HAVE_UDEV
+
+ struct gbm_device *gbm;
+
+#ifdef CONFIG_UDEV_KMS
struct udev_monitor *uevent_monitor;
InputHandlerProc uevent_handler;
#endif
drmEventContext event_context;
- struct dumb_bo *front_bo;
+ drmmode_bo front_bo;
Bool sw_cursor;
+ Bool glamor;
Bool shadow_enable;
void *shadow_fb;
@@ -79,7 +86,9 @@ typedef struct {
drmmode_ptr drmmode;
drmModeCrtcPtr mode_crtc;
uint32_t vblank_pipe;
+ int dpms_mode;
struct dumb_bo *cursor_bo;
+ Bool cursor_up;
unsigned rotate_fb_id;
uint16_t lut_r[256], lut_g[256], lut_b[256];
DamagePtr slave_damage;
@@ -128,6 +137,8 @@ extern DevPrivateKeyRec msPixmapPrivateKeyRec;
#define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec))
+uint32_t drmmode_bo_get_handle(drmmode_bo *bo);
+Bool drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode);
void *drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv);
Bool drmmode_SetSlaveBO(PixmapPtr ppix,
drmmode_ptr drmmode,
@@ -147,8 +158,6 @@ Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode,
int *depth, int *bpp);
-struct dumb_bo *dumb_get_bo_from_fd(int drm_fd, int fd, int pitch, int size);
-int dumb_bo_destroy(int fd, struct dumb_bo *bo);
#ifndef DRM_CAP_DUMB_PREFERRED_DEPTH
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c b/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c
new file mode 100644
index 000000000..58d420e07
--- /dev/null
+++ b/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright © 2007 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:
+ * Dave Airlie <airlied@redhat.com>
+ *
+ */
+
+#include "dumb_bo.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <xf86drm.h>
+
+struct dumb_bo *
+dumb_bo_create(int fd,
+ const unsigned width, const unsigned height, const unsigned bpp)
+{
+ struct drm_mode_create_dumb arg;
+ struct dumb_bo *bo;
+ int ret;
+
+ bo = calloc(1, sizeof(*bo));
+ if (!bo)
+ return NULL;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.width = width;
+ arg.height = height;
+ arg.bpp = bpp;
+
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
+ if (ret)
+ goto err_free;
+
+ bo->handle = arg.handle;
+ bo->size = arg.size;
+ bo->pitch = arg.pitch;
+
+ return bo;
+ err_free:
+ free(bo);
+ return NULL;
+}
+
+int
+dumb_bo_map(int fd, struct dumb_bo *bo)
+{
+ struct drm_mode_map_dumb arg;
+ int ret;
+ void *map;
+
+ if (bo->ptr) {
+ return 0;
+ }
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = bo->handle;
+
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
+ if (ret)
+ return ret;
+
+ map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, arg.offset);
+ if (map == MAP_FAILED)
+ return -errno;
+
+ bo->ptr = map;
+ return 0;
+}
+
+int
+dumb_bo_destroy(int fd, struct dumb_bo *bo)
+{
+ struct drm_mode_destroy_dumb arg;
+ int ret;
+
+ if (bo->ptr) {
+ munmap(bo->ptr, bo->size);
+ bo->ptr = NULL;
+ }
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = bo->handle;
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
+ if (ret)
+ return -errno;
+
+ free(bo);
+ return 0;
+}
+
+struct dumb_bo *
+dumb_get_bo_from_fd(int fd, int handle, int pitch, int size)
+{
+ struct dumb_bo *bo;
+ int ret;
+
+ bo = calloc(1, sizeof(*bo));
+ if (!bo)
+ return NULL;
+
+ ret = drmPrimeFDToHandle(fd, handle, &bo->handle);
+ if (ret) {
+ free(bo);
+ return NULL;
+ }
+ bo->pitch = pitch;
+ bo->size = size;
+ return bo;
+}
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.h b/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.h
new file mode 100644
index 000000000..9235e61e2
--- /dev/null
+++ b/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2007 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:
+ * Dave Airlie <airlied@redhat.com>
+ *
+ */
+#ifndef DUMB_BO_H
+#define DUMB_BO_H
+
+#include <stdint.h>
+
+struct dumb_bo {
+ uint32_t handle;
+ uint32_t size;
+ void *ptr;
+ uint32_t pitch;
+};
+
+struct dumb_bo *dumb_bo_create(int fd, const unsigned width,
+ const unsigned height, const unsigned bpp);
+int dumb_bo_map(int fd, struct dumb_bo *bo);
+int dumb_bo_destroy(int fd, struct dumb_bo *bo);
+struct dumb_bo *dumb_get_bo_from_fd(int fd, int handle, int pitch, int size);
+
+#endif
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/present.c b/xorg-server/hw/xfree86/drivers/modesetting/present.c
new file mode 100644
index 000000000..359e11316
--- /dev/null
+++ b/xorg-server/hw/xfree86/drivers/modesetting/present.c
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include "dix-config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <xf86.h>
+#include <xf86Crtc.h>
+#include <xf86drm.h>
+#include <xf86str.h>
+#include <present.h>
+
+#include "driver.h"
+
+#if 0
+#define DebugPresent(x) ErrorF x
+#else
+#define DebugPresent(x)
+#endif
+
+struct ms_present_vblank_event {
+ uint64_t event_id;
+};
+
+static RRCrtcPtr
+ms_present_get_crtc(WindowPtr window)
+{
+ xf86CrtcPtr xf86_crtc = ms_dri2_crtc_covering_drawable(&window->drawable);
+ return xf86_crtc ? xf86_crtc->randr_crtc : NULL;
+}
+
+static int
+ms_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc)
+{
+ xf86CrtcPtr xf86_crtc = crtc->devPrivate;
+
+ return ms_get_crtc_ust_msc(xf86_crtc, ust, msc);
+}
+
+/*
+ * Flush the DRM event queue when full; makes space for new events.
+ */
+static Bool
+ms_flush_drm_events(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ modesettingPtr ms = modesettingPTR(scrn);
+
+ struct pollfd p = { .fd = ms->fd, .events = POLLIN };
+ int r;
+
+ do {
+ r = poll(&p, 1, 0);
+ } while (r == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (r <= 0)
+ return TRUE;
+
+ return drmHandleEvent(ms->fd, &ms->event_context) >= 0;
+}
+
+/*
+ * Called when the queued vblank event has occurred
+ */
+static void
+ms_present_vblank_handler(uint64_t msc, uint64_t usec, void *data)
+{
+ struct ms_present_vblank_event *event = data;
+
+ DebugPresent(("\t\tmh %lld msc %llu\n",
+ (long long) event->event_id, (long long) msc));
+
+ present_event_notify(event->event_id, usec, msc);
+ free(event);
+}
+
+/*
+ * Called when the queued vblank is aborted
+ */
+static void
+ms_present_vblank_abort(void *data)
+{
+ struct ms_present_vblank_event *event = data;
+
+ DebugPresent(("\t\tma %lld\n", (long long) event->event_id));
+
+ free(event);
+}
+
+/*
+ * Queue an event to report back to the Present extension when the specified
+ * MSC has past
+ */
+static int
+ms_present_queue_vblank(RRCrtcPtr crtc,
+ uint64_t event_id,
+ uint64_t msc)
+{
+ xf86CrtcPtr xf86_crtc = crtc->devPrivate;
+ ScreenPtr screen = crtc->pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ modesettingPtr ms = modesettingPTR(scrn);
+ drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
+ struct ms_present_vblank_event *event;
+ drmVBlank vbl;
+ int ret;
+ uint32_t seq;
+
+ event = calloc(sizeof(struct ms_present_vblank_event), 1);
+ if (!event)
+ return BadAlloc;
+ event->event_id = event_id;
+ seq = ms_drm_queue_alloc(xf86_crtc, event,
+ ms_present_vblank_handler,
+ ms_present_vblank_abort);
+ if (!seq) {
+ free(event);
+ return BadAlloc;
+ }
+
+ vbl.request.type =
+ DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | drmmode_crtc->vblank_pipe;
+ vbl.request.sequence = ms_crtc_msc_to_kernel_msc(xf86_crtc, msc);
+ vbl.request.signal = seq;
+ for (;;) {
+ ret = drmWaitVBlank(ms->fd, &vbl);
+ if (!ret)
+ break;
+ if (errno != EBUSY || !ms_flush_drm_events(screen))
+ return BadAlloc;
+ }
+ DebugPresent(("\t\tmq %lld seq %u msc %llu (hw msc %u)\n",
+ (long long) event_id, seq, (long long) msc,
+ vbl.request.sequence));
+ return Success;
+}
+
+static Bool
+ms_present_event_match(void *data, void *match_data)
+{
+ struct ms_present_vblank_event *event = data;
+ uint64_t *match = match_data;
+
+ return *match == event->event_id;
+}
+
+/*
+ * Remove a pending vblank event from the DRM queue so that it is not reported
+ * to the extension
+ */
+static void
+ms_present_abort_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
+{
+ ScreenPtr screen = crtc->pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+
+ ms_drm_abort(scrn, ms_present_event_match, &event_id);
+}
+
+/*
+ * Flush our batch buffer when requested by the Present extension.
+ */
+static void
+ms_present_flush(WindowPtr window)
+{
+#ifdef GLAMOR
+ ScreenPtr screen = window->drawable.pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ modesettingPtr ms = modesettingPTR(scrn);
+
+ if (ms->drmmode.glamor)
+ glamor_block_handler(screen);
+#endif
+}
+
+static present_screen_info_rec ms_present_screen_info = {
+ .version = PRESENT_SCREEN_INFO_VERSION,
+
+ .get_crtc = ms_present_get_crtc,
+ .get_ust_msc = ms_present_get_ust_msc,
+ .queue_vblank = ms_present_queue_vblank,
+ .abort_vblank = ms_present_abort_vblank,
+ .flush = ms_present_flush,
+
+ .capabilities = PresentCapabilityNone,
+ .check_flip = 0,
+ .flip = 0,
+ .unflip = 0,
+};
+
+Bool
+ms_present_screen_init(ScreenPtr screen)
+{
+ return present_screen_init(screen, &ms_present_screen_info);
+}
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/vblank.c b/xorg-server/hw/xfree86/drivers/modesetting/vblank.c
index 5031ef8ff..711f6edb3 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/vblank.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/vblank.c
@@ -88,6 +88,14 @@ static int ms_box_area(BoxPtr box)
return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1);
}
+static Bool
+ms_crtc_on(xf86CrtcPtr crtc)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+ return crtc->enabled && drmmode_crtc->dpms_mode == DPMSModeOn;
+}
+
/*
* Return the crtc covering 'box'. If two crtcs cover a portion of
* 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
@@ -114,7 +122,7 @@ ms_covering_crtc(ScrnInfoPtr scrn,
crtc = xf86_config->crtc[c];
/* If the CRTC is off, treat it as not covering */
- if (!crtc->enabled)
+ if (!ms_crtc_on(crtc))
continue;
ms_crtc_box(crtc, &crtc_box);
@@ -323,6 +331,24 @@ ms_drm_abort_scrn(ScrnInfoPtr scrn)
}
/*
+ * Externally usable abort function that uses a callback to match a single
+ * queued entry to abort
+ */
+void
+ms_drm_abort(ScrnInfoPtr scrn, Bool (*match)(void *data, void *match_data),
+ void *match_data)
+{
+ struct ms_drm_queue *q;
+
+ xorg_list_for_each_entry(q, &ms_drm_queue, list) {
+ if (match(q->data, match_data)) {
+ ms_drm_abort_one(q);
+ break;
+ }
+ }
+}
+
+/*
* General DRM kernel handler. Looks for the matching sequence number in the
* drm event queue and calls the handler for it.
*/
diff --git a/xorg-server/hw/xfree86/os-support/solaris/sun_init.c b/xorg-server/hw/xfree86/os-support/solaris/sun_init.c
index 16fc1b739..cc50f36c4 100644
--- a/xorg-server/hw/xfree86/os-support/solaris/sun_init.c
+++ b/xorg-server/hw/xfree86/os-support/solaris/sun_init.c
@@ -46,15 +46,12 @@
#define SOL_CONSOLE_DEV "/dev/console"
static Bool KeepTty = FALSE;
-static Bool Protect0 = FALSE;
static Bool UseConsole = FALSE;
#ifdef HAS_USL_VTS
static int VTnum = -1;
static int xf86StartVT = -1;
static int vtEnabled = 0;
-extern void xf86VTAcquire(int);
-extern void xf86VTRelease(int);
#endif
/* Device to open as xf86Info.consoleFd */
@@ -97,27 +94,6 @@ xf86OpenConsole(void)
if (geteuid() != 0)
FatalError("xf86OpenConsole: Server must be suid root\n");
- /* Protect page 0 to help find NULL dereferencing */
- /* mprotect() doesn't seem to work */
- if (Protect0) {
- int fd = -1;
-
- if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0) {
- xf86Msg(X_WARNING,
- "xf86OpenConsole: cannot open /dev/zero (%s)\n",
- strerror(errno));
- }
- else {
- if (mmap(0, 0x1000, PROT_NONE,
- MAP_FIXED | MAP_SHARED, fd, 0) == MAP_FAILED)
- xf86Msg(X_WARNING,
- "xf86OpenConsole: failed to protect page 0 (%s)\n",
- strerror(errno));
-
- close(fd);
- }
- }
-
#ifdef HAS_USL_VTS
/*
@@ -371,15 +347,6 @@ xf86ProcessArgument(int argc, char **argv, int i)
}
/*
- * Undocumented flag to protect page 0 from read/write to help catch NULL
- * pointer dereferences. This is purely a debugging flag.
- */
- if (!strcmp(argv[i], "-protect0")) {
- Protect0 = TRUE;
- return 1;
- }
-
- /*
* Use /dev/console as the console device.
*/
if (!strcmp(argv[i], "-C")) {
diff --git a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h
index 3a83f348f..6190fe6a0 100644
--- a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h
+++ b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h
@@ -134,10 +134,15 @@
#endif
#include <sys/kd.h>
#include <sys/vt.h>
+
+extern _X_HIDDEN void xf86VTAcquire(int);
+extern _X_HIDDEN void xf86VTRelease(int);
#endif
#if defined(sun)
#include <sys/fbio.h>
+extern _X_HIDDEN char xf86SolarisFbDev[PATH_MAX];
+
#include <sys/kbd.h>
#include <sys/kbio.h>
diff --git a/xorg-server/hw/xwayland/xwayland-glamor.c b/xorg-server/hw/xwayland/xwayland-glamor.c
index 4be883fa3..09b454f8a 100644
--- a/xorg-server/hw/xwayland/xwayland-glamor.c
+++ b/xorg-server/hw/xwayland/xwayland-glamor.c
@@ -398,9 +398,8 @@ xwl_screen_init_glamor(struct xwl_screen *xwl_screen,
}
void
-glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
{
- glamor_destroy_textured_pixmap(pixmap);
}
int
diff --git a/xorg-server/hw/xwayland/xwayland-input.c b/xorg-server/hw/xwayland/xwayland-input.c
index b8c543ce4..5e204189f 100644
--- a/xorg-server/hw/xwayland/xwayland-input.c
+++ b/xorg-server/hw/xwayland/xwayland-input.c
@@ -233,6 +233,9 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
xwl_seat->xwl_screen->serial = serial;
switch (button) {
+ case BTN_LEFT:
+ index = 1;
+ break;
case BTN_MIDDLE:
index = 2;
break;
@@ -240,7 +243,9 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
index = 3;
break;
default:
- index = button - BTN_LEFT + 1;
+ /* Skip indexes 4-7: they are used for vertical and horizontal scroll.
+ The rest of the buttons go in order: BTN_SIDE becomes 8, etc. */
+ index = 8 + button - BTN_SIDE;
break;
}
diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c
index fef46a94f..654c58c14 100644
--- a/xorg-server/hw/xwin/InitOutput.c
+++ b/xorg-server/hw/xwin/InitOutput.c
@@ -793,6 +793,10 @@ winUseMsg(void)
#ifdef XWIN_CLIPBOARD
ErrorF("-nounicodeclipboard\n"
"\tDo not use Unicode clipboard even if on a NT-based platform.\n");
+
+ ErrorF("-[no]primary\n"
+ "\tWhen clipboard integration is enabled, map the X11 PRIMARY selection\n"
+ "\tto the Windows clipboard. Default is enabled.\n");
#endif
ErrorF("-refresh rate_in_Hz\n"
diff --git a/xorg-server/hw/xwin/XWin.rc b/xorg-server/hw/xwin/XWin.rc
index a142f3070..a54e0fdbb 100644
--- a/xorg-server/hw/xwin/XWin.rc
+++ b/xorg-server/hw/xwin/XWin.rc
@@ -93,6 +93,7 @@ BEGIN
POPUP "TRAYICON_MENU"
BEGIN
MENUITEM "&Hide Root Window", ID_APP_HIDE_ROOT
+ MENUITEM "Clipboard may use &PRIMARY selection", ID_APP_MONITOR_PRIMARY
MENUITEM "&About...", ID_APP_ABOUT
MENUITEM SEPARATOR
MENUITEM "E&xit...", ID_APP_EXIT
diff --git a/xorg-server/hw/xwin/man/XWin.man b/xorg-server/hw/xwin/man/XWin.man
index a043ac281..15a57db02 100644
--- a/xorg-server/hw/xwin/man/XWin.man
+++ b/xorg-server/hw/xwin/man/XWin.man
@@ -174,7 +174,7 @@ on remote hosts, when that information is available and it's useful to do so.
.SH OPTIONS CONTROLLING WINDOWS INTEGRATION
.TP 8
.B \-[no]clipboard
-Enables [disables] the integration between the Cygwin/X clipboard and
+Enables [disables] the integration between the X11 clipboard and
\fIWindows\fP clipboard. The default is enabled.
.TP 8
.B "\-emulate3buttons [\fItimeout\fP]"
@@ -200,6 +200,10 @@ prevents the \fIWindows\fP mouse cursor from being drawn on top of the X
cursor.
This parameter has no effect unless \fB-swcursor\fP is also specified.
.TP 8
+.B \-[no]primary
+Clipboard integration may [will not] use the PRIMARY selection.
+The default is enabled.
+.TP 8
.B \-swcursor
Disable the usage of the \fIWindows\fP cursor and use the X11 software cursor instead.
.TP 8
diff --git a/xorg-server/hw/xwin/winclipboard/internal.h b/xorg-server/hw/xwin/winclipboard/internal.h
index 94956f80d..c6bde84af 100644
--- a/xorg-server/hw/xwin/winclipboard/internal.h
+++ b/xorg-server/hw/xwin/winclipboard/internal.h
@@ -39,10 +39,12 @@
#include <X11/Xwindows.h>
#define WIN_XEVENTS_SUCCESS 0
-#define WIN_XEVENTS_CONVERT 2
-#define WIN_XEVENTS_NOTIFY 3
+#define WIN_XEVENTS_FAILED 1
+#define WIN_XEVENTS_NOTIFY_DATA 3
+#define WIN_XEVENTS_NOTIFY_TARGETS 4
#define WM_WM_REINIT (WM_USER + 1)
+#define WM_WM_QUIT (WM_USER + 2)
/*
* References to external symbols
@@ -95,9 +97,15 @@ typedef struct
* winclipboardxevents.c
*/
+typedef struct
+{
+ Bool fUseUnicode;
+ Atom *targetList;
+} ClipboardConversionData;
+
int
winClipboardFlushXEvents(HWND hwnd,
- Window iWindow, Display * pDisplay, Bool fUnicodeSupport, ClipboardAtoms *atom);
+ Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atom);
Atom
diff --git a/xorg-server/hw/xwin/winclipboard/thread.c b/xorg-server/hw/xwin/winclipboard/thread.c
index c179e3f83..50e1e8cb5 100644
--- a/xorg-server/hw/xwin/winclipboard/thread.c
+++ b/xorg-server/hw/xwin/winclipboard/thread.c
@@ -123,6 +123,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
int iSelectError;
Bool fShutdown = FALSE;
static Bool fErrorHandlerSet = FALSE;
+ ClipboardConversionData data;
winDebug("winClipboardProc - Hello\n");
@@ -254,21 +255,25 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
}
}
- /* Pre-flush X events */
- /*
- * NOTE: Apparently you'll freeze if you don't do this,
- * because there may be events in local data structures
- * already.
- */
- winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
-
- /* Pre-flush Windows messages */
- if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
- ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n");
- }
+ data.fUseUnicode = fUseUnicode;
- /* Loop for X events */
+ /* Loop for events */
while (1) {
+
+ /* Process X events */
+ winClipboardFlushXEvents(hwnd,
+ iWindow, pDisplay, &data, &atoms);
+
+ /* Process Windows messages */
+ if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
+ ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue trapped "
+ "WM_QUIT message, exiting main loop.\n");
+ break;
+ }
+
+ /* We need to ensure that all pending requests are sent */
+ XFlush(pDisplay);
+
/* Setup the file descriptor set */
/*
* NOTE: You have to do this before every call to select
@@ -315,10 +320,9 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
break;
}
- /* Branch on which descriptor became active */
if (FD_ISSET(iConnectionNumber, &fdsRead)) {
- /* Process X events */
- winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
+ winDebug
+ ("winClipboardProc - X connection ready, pumping X event queue\n");
}
#ifdef HAS_DEVWINDOWS
@@ -328,14 +332,16 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
if (1)
#endif
{
- /* Process Windows messages */
- if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
- ErrorF("winClipboardProc - "
- "winClipboardFlushWindowsMessageQueue trapped "
- "WM_QUIT message, exiting main loop.\n");
- break;
- }
+ winDebug
+ ("winClipboardProc - /dev/windows ready, pumping Windows message queue\n");
}
+
+#ifdef HAS_DEVWINDOWS
+ if (!(FD_ISSET(iConnectionNumber, &fdsRead)) &&
+ !(FD_ISSET(fdMessageQueue, &fdsRead))) {
+ winDebug("winClipboardProc - Spurious wake, select() returned %d\n", iReturn);
+ }
+#endif
}
winClipboardProc_Exit:
@@ -345,7 +351,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
winClipboardProc_Done:
/* Close our Windows window */
if (g_hwndClipboard) {
- winClipboardWindowDestroy();
+ DestroyWindow(g_hwndClipboard);
}
/* Close our X window */
@@ -485,7 +491,7 @@ void
winClipboardWindowDestroy(void)
{
if (g_hwndClipboard) {
- SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0);
+ SendMessage(g_hwndClipboard, WM_WM_QUIT, 0, 0);
}
}
diff --git a/xorg-server/hw/xwin/winclipboard/winclipboard.h b/xorg-server/hw/xwin/winclipboard/winclipboard.h
index 52481301b..9c5c568a7 100644
--- a/xorg-server/hw/xwin/winclipboard/winclipboard.h
+++ b/xorg-server/hw/xwin/winclipboard/winclipboard.h
@@ -33,4 +33,6 @@ void winFixClipboardChain(void);
void winClipboardWindowDestroy(void);
+extern Bool fPrimarySelection;
+
#endif
diff --git a/xorg-server/hw/xwin/winclipboard/wndproc.c b/xorg-server/hw/xwin/winclipboard/wndproc.c
index 165ff558a..1ea5bc6b7 100644
--- a/xorg-server/hw/xwin/winclipboard/wndproc.c
+++ b/xorg-server/hw/xwin/winclipboard/wndproc.c
@@ -45,6 +45,7 @@
#include <sys/types.h>
#include <sys/time.h>
+#include <limits.h>
#include <X11/Xatom.h>
@@ -64,7 +65,7 @@
static int
winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
- Bool fUseUnicode, ClipboardAtoms *atoms, int iTimeoutSec)
+ ClipboardConversionData *data, ClipboardAtoms *atoms, int iTimeoutSec)
{
int iConnNumber;
struct timeval tv;
@@ -82,8 +83,18 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
fd_set fdsRead;
long remainingTime;
- /* We need to ensure that all pending events are processed */
- XSync(pDisplay, FALSE);
+ /* Process X events */
+ iReturn = winClipboardFlushXEvents(hwnd, iWindow, pDisplay, data, atoms);
+
+ winDebug("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n", iReturn);
+
+ if ((WIN_XEVENTS_NOTIFY_DATA == iReturn) || (WIN_XEVENTS_NOTIFY_TARGETS == iReturn) || (WIN_XEVENTS_FAILED == iReturn)) {
+ /* Bail out */
+ return iReturn;
+ }
+
+ /* We need to ensure that all pending requests are sent */
+ XFlush(pDisplay);
/* Setup the file descriptor set */
FD_ZERO(&fdsRead);
@@ -112,24 +123,8 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
break;
}
- /* Branch on which descriptor became active */
- if (FD_ISSET(iConnNumber, &fdsRead)) {
- /* Process X events */
- /* Exit when we see that server is shutting down */
- iReturn = winClipboardFlushXEvents(hwnd,
- iWindow, pDisplay, fUseUnicode, atoms);
-
- winDebug
- ("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
- iReturn);
-
- if (WIN_XEVENTS_NOTIFY == iReturn) {
- /* Bail out if notify processed */
- return iReturn;
- }
- }
- else {
- winDebug("winProcessXEventsTimeout - Spurious wake\n");
+ if (!FD_ISSET(iConnNumber, &fdsRead)) {
+ winDebug("winProcessXEventsTimeout - Spurious wake, select() returned %d\n", iReturn);
}
}
@@ -148,6 +143,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
static Display *pDisplay;
static Window iWindow;
static ClipboardAtoms *atoms;
+ static Bool fRunning;
/* Branch on message type */
switch (message) {
@@ -159,7 +155,13 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
ChangeClipboardChain(hwnd, s_hwndNextViewer);
s_hwndNextViewer = NULL;
+ }
+ return 0;
+ case WM_WM_QUIT:
+ {
+ winDebug("winClipboardWindowProc - WM_WM_QUIT\n");
+ fRunning = FALSE;
PostQuitMessage(0);
}
return 0;
@@ -175,6 +177,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
pDisplay = cwcp->pClipboardDisplay;
iWindow = cwcp->iClipboardWindow;
atoms = cwcp->atoms;
+ fRunning = TRUE;
first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
if (first == hwnd)
@@ -307,6 +310,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
}
+ /* Bail when shutting down */
+ if (!fRunning)
+ return 0;
+
/*
* Do not take ownership of the X11 selections when something
* other than CF_TEXT or CF_UNICODETEXT has been copied
@@ -410,93 +417,151 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winDebug("winClipboardWindowProc - WM_DESTROYCLIPBOARD - Ignored.\n");
return 0;
- case WM_RENDERFORMAT:
case WM_RENDERALLFORMATS:
+ winDebug("winClipboardWindowProc - WM_RENDERALLFORMATS - Hello.\n");
+
+ /*
+ WM_RENDERALLFORMATS is sent as we are shutting down, to render the
+ clipboard so it's contents remains available to other applications.
+
+ Unfortunately, this can't work without major changes. The server is
+ already waiting for us to stop, so we can't ask for the rendering of
+ clipboard text now.
+ */
+
+ return 0;
+
+ case WM_RENDERFORMAT:
{
int iReturn;
Bool fConvertToUnicode;
+ Bool pasted = FALSE;
+ Atom selection;
+ ClipboardConversionData data;
+ int best_target = 0;
- winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n");
+ winDebug("winClipboardWindowProc - WM_RENDERFORMAT %d - Hello.\n",
+ wParam);
/* Flag whether to convert to Unicode or not */
- if (message == WM_RENDERALLFORMATS)
- fConvertToUnicode = FALSE;
- else
- fConvertToUnicode = (CF_UNICODETEXT == wParam);
+ fConvertToUnicode = (CF_UNICODETEXT == wParam);
- /* Request the selection contents */
- iReturn = XConvertSelection(pDisplay,
- winClipboardGetLastOwnedSelectionAtom(atoms),
- atoms->atomCompoundText,
- atoms->atomLocalProperty,
- iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow) {
- ErrorF("winClipboardWindowProc - WM_RENDER*FORMAT - "
- "XConvertSelection () failed\n");
- break;
+ selection = winClipboardGetLastOwnedSelectionAtom(atoms);
+ if (selection == None) {
+ ErrorF("winClipboardWindowProc - no monitored selection is owned\n");
+ goto fake_paste;
}
- /* Special handling for WM_RENDERALLFORMATS */
- if (message == WM_RENDERALLFORMATS) {
- /* We must open and empty the clipboard */
+ winDebug("winClipboardWindowProc - requesting targets for selection from owner\n");
- /* Close clipboard if we have it open already */
- if (GetOpenClipboardWindow() == hwnd) {
- CloseClipboard();
- }
+ /* Request the selection's supported conversion targets */
+ XConvertSelection(pDisplay,
+ selection,
+ atoms->atomTargets,
+ atoms->atomLocalProperty,
+ iWindow, CurrentTime);
- if (!OpenClipboard(hwnd)) {
- ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
- "OpenClipboard () failed: %08x\n",
- GetLastError());
- break;
- }
+ /* Process X events */
+ data.fUseUnicode = fConvertToUnicode;
+ iReturn = winProcessXEventsTimeout(hwnd,
+ iWindow,
+ pDisplay,
+ &data,
+ atoms,
+ WIN_POLL_TIMEOUT);
- if (!EmptyClipboard()) {
- ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
- "EmptyClipboard () failed: %08x\n",
- GetLastError());
- break;
- }
+ if (WIN_XEVENTS_NOTIFY_TARGETS != iReturn) {
+ ErrorF
+ ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY_TARGETS\n");
+ goto fake_paste;
}
- /* Process the SelectionNotify event */
+ /* Choose the most preferred target */
+ {
+ struct target_priority
+ {
+ Atom target;
+ unsigned int priority;
+ };
+
+ struct target_priority target_priority_table[] =
+ {
+ { atoms->atomCompoundText, 0 },
+#ifdef X_HAVE_UTF8_STRING
+ { atoms->atomUTF8String, 1 },
+#endif
+ { XA_STRING, 2 },
+ };
+
+ int best_priority = INT_MAX;
+
+ int i,j;
+ for (i = 0 ; data.targetList[i] != 0; i++)
+ {
+ for (j = 0; j < sizeof(target_priority_table)/sizeof(struct target_priority); j ++)
+ {
+ if ((data.targetList[i] == target_priority_table[j].target) &&
+ (target_priority_table[j].priority < best_priority))
+ {
+ best_target = target_priority_table[j].target;
+ best_priority = target_priority_table[j].priority;
+ }
+ }
+ }
+ }
+
+ free(data.targetList);
+ data.targetList = 0;
+
+ winDebug("winClipboardWindowProc - best target is %d\n", best_target);
+
+ /* No useful targets found */
+ if (best_target == 0)
+ goto fake_paste;
+
+ winDebug("winClipboardWindowProc - requesting selection from owner\n");
+
+ /* Request the selection contents */
+ XConvertSelection(pDisplay,
+ selection,
+ best_target,
+ atoms->atomLocalProperty,
+ iWindow, CurrentTime);
+
+ /* Process X events */
iReturn = winProcessXEventsTimeout(hwnd,
iWindow,
pDisplay,
- fConvertToUnicode,
+ &data,
atoms,
WIN_POLL_TIMEOUT);
/*
- * The last call to winProcessXEventsTimeout
- * from above had better have seen a notify event, or else we
- * are dealing with a buggy or old X11 app. In these cases we
- * have to paste some fake data to the Win32 clipboard to
- * satisfy the requirement that we write something to it.
+ * winProcessXEventsTimeout had better have seen a notify event,
+ * or else we are dealing with a buggy or old X11 app.
*/
- if (WIN_XEVENTS_NOTIFY != iReturn) {
- /* Paste no data, to satisfy required call to SetClipboardData */
- SetClipboardData(CF_UNICODETEXT, NULL);
- SetClipboardData(CF_TEXT, NULL);
-
+ if (WIN_XEVENTS_NOTIFY_DATA != iReturn) {
ErrorF
- ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY\n");
+ ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY_DATA\n");
}
-
- /* Special handling for WM_RENDERALLFORMATS */
- if (message == WM_RENDERALLFORMATS) {
- /* We must close the clipboard */
-
- if (!CloseClipboard()) {
- ErrorF("winClipboardWindowProc - WM_RENDERALLFORMATS - "
- "CloseClipboard () failed: %08x\n",
- GetLastError());
- break;
- }
+ else {
+ pasted = TRUE;
}
- winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Returning.\n");
+ /*
+ * If we couldn't get the data from the X clipboard, we
+ * have to paste some fake data to the Win32 clipboard to
+ * satisfy the requirement that we write something to it.
+ */
+ fake_paste:
+ if (!pasted)
+ {
+ /* Paste no data, to satisfy required call to SetClipboardData */
+ SetClipboardData(CF_UNICODETEXT, NULL);
+ SetClipboardData(CF_TEXT, NULL);
+ }
+
+ winDebug("winClipboardWindowProc - WM_RENDERFORMAT - Returning.\n");
return 0;
}
}
diff --git a/xorg-server/hw/xwin/winclipboard/xevents.c b/xorg-server/hw/xwin/winclipboard/xevents.c
index 33d52aafd..835195b52 100644
--- a/xorg-server/hw/xwin/winclipboard/xevents.c
+++ b/xorg-server/hw/xwin/winclipboard/xevents.c
@@ -43,11 +43,15 @@
#undef _XSERVER64
#endif
-#include "internal.h"
+#include <limits.h>
+#include <wchar.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xfixes.h>
+#include "winclipboard.h"
+#include "internal.h"
+
/*
* Constants
*/
@@ -62,6 +66,7 @@
*/
extern int xfixes_event_base;
+Bool fPrimarySelection = TRUE;
/*
* Local variables
@@ -133,13 +138,59 @@ winClipboardInitMonitoredSelections(void)
lastOwnedSelectionIndex = CLIP_OWN_NONE;
}
+static int
+winClipboardSelectionNotifyTargets(HWND hwnd, Window iWindow, Display *pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
+{
+ Atom type;
+ int format;
+ unsigned long nitems;
+ unsigned long after;
+ Atom *prop;
+
+ /* Retrieve the selection data and delete the property */
+ int iReturn = XGetWindowProperty(pDisplay,
+ iWindow,
+ atoms->atomLocalProperty,
+ 0,
+ INT_MAX,
+ True,
+ AnyPropertyType,
+ &type,
+ &format,
+ &nitems,
+ &after,
+ (unsigned char **)&prop);
+ if (iReturn != Success) {
+ ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+ "XGetWindowProperty () failed, aborting: %d\n", iReturn);
+ } else {
+ int i;
+ data->targetList = malloc((nitems+1)*sizeof(Atom));
+
+ for (i = 0; i < nitems; i++)
+ {
+ Atom atom = prop[i];
+ char *pszAtomName = XGetAtomName(pDisplay, atom);
+ data->targetList[i] = atom;
+ winDebug("winClipboardFlushXEvents - SelectionNotify - target[%d] %d = %s\n", i, atom, pszAtomName);
+ XFree(pszAtomName);
+ }
+
+ data->targetList[nitems] = 0;
+
+ XFree(prop);
+ }
+
+ return WIN_XEVENTS_NOTIFY_TARGETS;
+}
+
/*
* Process any pending X events
*/
int
winClipboardFlushXEvents(HWND hwnd,
- Window iWindow, Display * pDisplay, Bool fUseUnicode, ClipboardAtoms *atoms)
+ Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
{
Atom atomClipboard = atoms->atomClipboard;
Atom atomLocalProperty = atoms->atomLocalProperty;
@@ -158,14 +209,11 @@ winClipboardFlushXEvents(HWND hwnd,
int iReturn;
HGLOBAL hGlobal = NULL;
XICCEncodingStyle xiccesStyle;
- int iConvertDataLen = 0;
char *pszConvertData = NULL;
char *pszTextList[2] = { NULL };
int iCount;
char **ppszTextList = NULL;
wchar_t *pwszUnicodeStr = NULL;
- int iUnicodeLen = 0;
- int iReturnDataLen = 0;
Bool fAbort = FALSE;
Bool fCloseClipboard = FALSE;
Bool fSetClipboardData = TRUE;
@@ -272,7 +320,7 @@ winClipboardFlushXEvents(HWND hwnd,
fCloseClipboard = TRUE;
/* Check that clipboard format is available */
- if (fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+ if (data->fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
static int count; /* Hack to stop acroread spamming the log */
static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */
@@ -289,7 +337,7 @@ winClipboardFlushXEvents(HWND hwnd,
fAbort = TRUE;
goto winClipboardFlushXEvents_SelectionRequest_Done;
}
- else if (!fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) {
+ else if (!data->fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) {
ErrorF("winClipboardFlushXEvents - CF_TEXT is not "
"available from Win32 clipboard. Aborting.\n");
@@ -311,7 +359,7 @@ winClipboardFlushXEvents(HWND hwnd,
xiccesStyle = XStringStyle;
/* Get a pointer to the clipboard text, in desired format */
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
/* Retrieve clipboard data */
hGlobal = GetClipboardData(CF_UNICODETEXT);
}
@@ -330,8 +378,8 @@ winClipboardFlushXEvents(HWND hwnd,
pszGlobalData = (char *) GlobalLock(hGlobal);
/* Convert the Unicode string to UTF8 (MBCS) */
- if (fUseUnicode) {
- iConvertDataLen = WideCharToMultiByte(CP_UTF8,
+ if (data->fUseUnicode) {
+ int iConvertDataLen = WideCharToMultiByte(CP_UTF8,
0,
(LPCWSTR) pszGlobalData,
-1, NULL, 0, NULL, NULL);
@@ -346,7 +394,6 @@ winClipboardFlushXEvents(HWND hwnd,
}
else {
pszConvertData = strdup(pszGlobalData);
- iConvertDataLen = strlen(pszConvertData) + 1;
}
/* Convert DOS string to UNIX string */
@@ -361,7 +408,7 @@ winClipboardFlushXEvents(HWND hwnd,
xtpText.nitems = 0;
/* Create the text property from the text list */
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
#ifdef X_HAVE_UTF8_STRING
iReturn = Xutf8TextListToTextProperty(pDisplay,
pszTextList,
@@ -491,7 +538,6 @@ winClipboardFlushXEvents(HWND hwnd,
*/
case SelectionNotify:
-
winDebug("winClipboardFlushXEvents - SelectionNotify\n");
{
char *pszAtomName;
@@ -506,75 +552,31 @@ winClipboardFlushXEvents(HWND hwnd,
}
/*
- * Request conversion of UTF8 and CompoundText targets.
- */
- if (event.xselection.property == None) {
- if (event.xselection.target == XA_STRING) {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "XA_STRING\n");
+ SelectionNotify with property of None indicates either:
- return WIN_XEVENTS_CONVERT;
- }
- else if (event.xselection.target == atomUTF8String) {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "Requesting conversion of UTF8 target.\n");
-
- XConvertSelection(pDisplay,
- event.xselection.selection,
- XA_STRING,
- atomLocalProperty, iWindow, CurrentTime);
-
- /* Process the ConvertSelection event */
- XFlush(pDisplay);
- return WIN_XEVENTS_CONVERT;
- }
-#ifdef X_HAVE_UTF8_STRING
- else if (event.xselection.target == atomCompoundText) {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "Requesting conversion of CompoundText target.\n");
-
- XConvertSelection(pDisplay,
- event.xselection.selection,
- atomUTF8String,
- atomLocalProperty, iWindow, CurrentTime);
-
- /* Process the ConvertSelection event */
- XFlush(pDisplay);
- return WIN_XEVENTS_CONVERT;
- }
-#endif
- else {
+ (i) Generated by the X server if no owner for the specified selection exists
+ (perhaps it's disappeared on us mid-transaction), or
+ (ii) Sent by the selection owner when the requested selection conversion could
+ not be performed or server errors prevented the conversion data being returned
+ */
+ if (event.xselection.property == None) {
ErrorF("winClipboardFlushXEvents - SelectionNotify - "
- "Unknown format. Cannot request conversion, "
- "aborting.\n");
- break;
+ "Conversion to format %d refused.\n",
+ event.xselection.target);
+ return WIN_XEVENTS_FAILED;
}
- }
- /* Retrieve the size of the stored data */
- iReturn = XGetWindowProperty(pDisplay, iWindow, atomLocalProperty, 0, 0, /* Don't get data, just size */
- False,
- AnyPropertyType,
- &xtpText.encoding,
- &xtpText.format,
- &xtpText.nitems,
- &ulReturnBytesLeft, &xtpText.value);
- if (iReturn != Success) {
- ErrorF("winClipboardFlushXEvents - SelectionNotify - "
- "XGetWindowProperty () failed, aborting: %d\n", iReturn);
- break;
+ if (event.xselection.target == atomTargets) {
+ return winClipboardSelectionNotifyTargets(hwnd, iWindow, pDisplay, data, atoms);
}
- winDebug("SelectionNotify - returned data %d left %d\n",
- xtpText.nitems, ulReturnBytesLeft);
-
- /* Request the selection data */
+ /* Retrieve the selection data and delete the property */
iReturn = XGetWindowProperty(pDisplay,
iWindow,
atomLocalProperty,
0,
- ulReturnBytesLeft,
- False,
+ INT_MAX,
+ True,
AnyPropertyType,
&xtpText.encoding,
&xtpText.format,
@@ -583,7 +585,7 @@ winClipboardFlushXEvents(HWND hwnd,
if (iReturn != Success) {
ErrorF("winClipboardFlushXEvents - SelectionNotify - "
"XGetWindowProperty () failed, aborting: %d\n", iReturn);
- break;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
}
{
@@ -597,7 +599,7 @@ winClipboardFlushXEvents(HWND hwnd,
pszAtomName = NULL;
}
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
#ifdef X_HAVE_UTF8_STRING
/* Convert the text property to a text list */
iReturn = Xutf8TextPropertyToTextList(pDisplay,
@@ -614,8 +616,7 @@ winClipboardFlushXEvents(HWND hwnd,
/* Conversion succeeded or some unconvertible characters */
if (ppszTextList != NULL) {
int i;
-
- iReturnDataLen = 0;
+ int iReturnDataLen = 0;
for (i = 0; i < iCount; i++) {
iReturnDataLen += strlen(ppszTextList[i]);
}
@@ -664,14 +665,14 @@ winClipboardFlushXEvents(HWND hwnd,
/* Convert the X clipboard string to DOS format */
winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData));
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
/* Find out how much space needed to convert MBCS to Unicode */
- iUnicodeLen = MultiByteToWideChar(CP_UTF8,
+ int iUnicodeLen = MultiByteToWideChar(CP_UTF8,
0,
pszReturnData, -1, NULL, 0);
- /* Allocate memory for the Unicode string */
- pwszUnicodeStr = malloc(sizeof(wchar_t) * (iUnicodeLen + 1));
+ /* NOTE: iUnicodeLen includes space for null terminator */
+ pwszUnicodeStr = malloc(sizeof(wchar_t) * iUnicodeLen);
if (!pwszUnicodeStr) {
ErrorF("winClipboardFlushXEvents - SelectionNotify "
"malloc failed for pwszUnicodeStr, aborting.\n");
@@ -689,9 +690,10 @@ winClipboardFlushXEvents(HWND hwnd,
/* Allocate global memory for the X clipboard data */
hGlobal = GlobalAlloc(GMEM_MOVEABLE,
- sizeof(wchar_t) * (iUnicodeLen + 1));
+ sizeof(wchar_t) * iUnicodeLen);
}
else {
+ int iConvertDataLen = 0;
pszConvertData = strdup(pszReturnData);
iConvertDataLen = strlen(pszConvertData) + 1;
@@ -723,9 +725,8 @@ winClipboardFlushXEvents(HWND hwnd,
}
/* Copy the returned string into the global memory */
- if (fUseUnicode) {
- memcpy(pszGlobalData,
- pwszUnicodeStr, sizeof(wchar_t) * (iUnicodeLen + 1));
+ if (data->fUseUnicode) {
+ wcscpy((wchar_t *)pszGlobalData, pwszUnicodeStr);
free(pwszUnicodeStr);
pwszUnicodeStr = NULL;
}
@@ -740,7 +741,7 @@ winClipboardFlushXEvents(HWND hwnd,
pszGlobalData = NULL;
/* Push the selection data to the Windows clipboard */
- if (fUseUnicode)
+ if (data->fUseUnicode)
SetClipboardData(CF_UNICODETEXT, hGlobal);
else
SetClipboardData(CF_TEXT, hGlobal);
@@ -770,7 +771,7 @@ winClipboardFlushXEvents(HWND hwnd,
SetClipboardData(CF_UNICODETEXT, NULL);
SetClipboardData(CF_TEXT, NULL);
}
- return WIN_XEVENTS_NOTIFY;
+ return WIN_XEVENTS_NOTIFY_DATA;
case SelectionClear:
winDebug("SelectionClear - doing nothing\n");
@@ -790,7 +791,7 @@ winClipboardFlushXEvents(HWND hwnd,
winDebug("winClipboardFlushXEvents - XFixesSetSelectionOwnerNotify\n");
/* Save selection owners for monitored selections, ignore other selections */
- if (e->selection == XA_PRIMARY) {
+ if ((e->selection == XA_PRIMARY) && fPrimarySelection) {
MonitorSelection(e, CLIP_OWN_PRIMARY);
}
else if (e->selection == atomClipboard) {
diff --git a/xorg-server/hw/xwin/winclipboard/xwinclip.c b/xorg-server/hw/xwin/winclipboard/xwinclip.c
index 3677974c4..856c4dd54 100644
--- a/xorg-server/hw/xwin/winclipboard/xwinclip.c
+++ b/xorg-server/hw/xwin/winclipboard/xwinclip.c
@@ -92,6 +92,13 @@ main (int argc, char *argv[])
continue;
}
+ /* Look for -noprimary */
+ if (!strcmp (argv[i], "-noprimary"))
+ {
+ fPrimarySelection = False;
+ continue;
+ }
+
/* Yack when we find a parameter that we don't know about */
printf ("Unknown parameter: %s\nExiting.\n", argv[i]);
exit (1);
diff --git a/xorg-server/hw/xwin/winclipboard/xwinclip.man b/xorg-server/hw/xwin/winclipboard/xwinclip.man
index 822db91d4..a53dc3029 100644
--- a/xorg-server/hw/xwin/winclipboard/xwinclip.man
+++ b/xorg-server/hw/xwin/winclipboard/xwinclip.man
@@ -29,6 +29,9 @@ Specifies the X server display to connect to.
.TP 8
.B \-nounicodeclipboard
Do not use unicode text on the clipboard.
+.TP 8
+.B \-noprimary
+Do not monitor the PRIMARY selection.
.SH "SEE ALSO"
XWin(1)
diff --git a/xorg-server/hw/xwin/winclipboardwrappers.c b/xorg-server/hw/xwin/winclipboardwrappers.c
index 2679f4f98..2e6b63287 100644
--- a/xorg-server/hw/xwin/winclipboardwrappers.c
+++ b/xorg-server/hw/xwin/winclipboardwrappers.c
@@ -44,12 +44,6 @@
DISPATCH_PROC(winProcEstablishConnection);
/*
- * References to external symbols
- */
-
-extern Bool g_fClipboard;
-
-/*
* Wrapper for internal EstablishConnection function.
* Initializes internal clients that must not be started until
* an external client has connected.
diff --git a/xorg-server/hw/xwin/winprocarg.c b/xorg-server/hw/xwin/winprocarg.c
index f2bf05bad..e8cccb4c2 100644
--- a/xorg-server/hw/xwin/winprocarg.c
+++ b/xorg-server/hw/xwin/winprocarg.c
@@ -37,13 +37,8 @@ from The Open Group.
#include "winmsg.h"
#include "winmonitors.h"
-/*
- * References to external symbols
- */
-
#ifdef XWIN_CLIPBOARD
-extern Bool g_fUnicodeClipboard;
-extern Bool g_fClipboard;
+#include "winclipboard/winclipboard.h"
#endif
/*
@@ -716,6 +711,26 @@ ddxProcessArgument(int argc, char *argv[], int i)
/* Indicate that we have processed this argument */
return 1;
}
+
+ /*
+ * Look for the '-primary' argument
+ */
+ if (IS_OPTION("-primary")) {
+ fPrimarySelection = TRUE;
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-noprimary' argument
+ */
+ if (IS_OPTION("-noprimary")) {
+ fPrimarySelection = FALSE;
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
#endif
/*
diff --git a/xorg-server/hw/xwin/winresource.h b/xorg-server/hw/xwin/winresource.h
index afbf9f28d..37e92ce61 100644
--- a/xorg-server/hw/xwin/winresource.h
+++ b/xorg-server/hw/xwin/winresource.h
@@ -43,6 +43,7 @@
#define ID_APP_HIDE_ROOT 201
#define ID_APP_ALWAYS_ON_TOP 202
#define ID_APP_ABOUT 203
+#define ID_APP_MONITOR_PRIMARY 204
#define ID_ABOUT_WEBSITE 303
diff --git a/xorg-server/hw/xwin/wintrayicon.c b/xorg-server/hw/xwin/wintrayicon.c
index e0aa7e5ab..6acc0d712 100644
--- a/xorg-server/hw/xwin/wintrayicon.c
+++ b/xorg-server/hw/xwin/wintrayicon.c
@@ -32,9 +32,13 @@
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
+
#include "win.h"
#include <shellapi.h>
#include "winprefs.h"
+#ifdef XWIN_CLIPBOARD
+#include "winclipboard/winclipboard.h"
+#endif
/*
* Initialize the tray icon
@@ -170,6 +174,21 @@ winHandleIconMessage(HWND hwnd, UINT message,
RemoveMenu(hmenuTray, ID_APP_HIDE_ROOT, MF_BYCOMMAND);
}
+#ifdef XWIN_CLIPBOARD
+ if (g_fClipboard) {
+ /* Set menu state to indicate if 'Monitor Primary' is enabled or not */
+ MENUITEMINFO mii = { 0 };
+ mii.cbSize = sizeof(MENUITEMINFO);
+ mii.fMask = MIIM_STATE;
+ mii.fState = fPrimarySelection ? MFS_CHECKED : MFS_UNCHECKED;
+ SetMenuItemInfo(hmenuTray, ID_APP_MONITOR_PRIMARY, FALSE, &mii);
+ }
+ else {
+ /* Remove 'Monitor Primary' menu item */
+ RemoveMenu(hmenuTray, ID_APP_MONITOR_PRIMARY, MF_BYCOMMAND);
+ }
+#endif
+
SetupRootMenu(hmenuTray);
/*
diff --git a/xorg-server/hw/xwin/winwndproc.c b/xorg-server/hw/xwin/winwndproc.c
index 0c434c927..1bf3f5cde 100644
--- a/xorg-server/hw/xwin/winwndproc.c
+++ b/xorg-server/hw/xwin/winwndproc.c
@@ -1218,6 +1218,12 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
#endif
+#ifdef XWIN_CLIPBOARD
+ case ID_APP_MONITOR_PRIMARY:
+ fPrimarySelection = !fPrimarySelection;
+ return 0;
+#endif
+
case ID_APP_ABOUT:
/* Display the About box */
winDisplayAboutDialog(s_pScreenPriv);
diff --git a/xorg-server/include/dix.h b/xorg-server/include/dix.h
index 991a3ce88..921156b4c 100644
--- a/xorg-server/include/dix.h
+++ b/xorg-server/include/dix.h
@@ -74,9 +74,14 @@ SOFTWARE.
if ((sizeof(req) >> 2) > client->req_len )\
return(BadLength)
+#define REQUEST_AT_LEAST_EXTRA_SIZE(req, extra) \
+ if (((sizeof(req) + ((uint64_t) extra)) >> 2) > client->req_len ) \
+ return(BadLength)
+
#define REQUEST_FIXED_SIZE(req, n)\
if (((sizeof(req) >> 2) > client->req_len) || \
- (((sizeof(req) + (n) + 3) >> 2) != client->req_len)) \
+ (((n) >> 2) >= client->req_len) || \
+ ((((uint64_t) sizeof(req) + (n) + 3) >> 2) != (uint64_t) client->req_len)) \
return(BadLength)
#define LEGAL_NEW_RESOURCE(id,client)\
diff --git a/xorg-server/include/regionstr.h b/xorg-server/include/regionstr.h
index 515e93ffa..079375d33 100644
--- a/xorg-server/include/regionstr.h
+++ b/xorg-server/include/regionstr.h
@@ -127,7 +127,10 @@ RegionEnd(RegionPtr reg)
static inline size_t
RegionSizeof(size_t n)
{
- return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
+ if (n < ((INT_MAX - sizeof(RegDataRec)) / sizeof(BoxRec)))
+ return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
+ else
+ return 0;
}
static inline void
@@ -138,9 +141,10 @@ RegionInit(RegionPtr _pReg, BoxPtr _rect, int _size)
(_pReg)->data = (RegDataPtr) NULL;
}
else {
+ size_t rgnSize;
(_pReg)->extents = RegionEmptyBox;
- if (((_size) > 1) && ((_pReg)->data =
- (RegDataPtr) malloc(RegionSizeof(_size)))) {
+ if (((_size) > 1) && ((rgnSize = RegionSizeof(_size)) > 0) &&
+ (((_pReg)->data = malloc(rgnSize)) != NULL)) {
(_pReg)->data->size = (_size);
(_pReg)->data->numRects = 0;
}
diff --git a/xorg-server/man/Xserver.man b/xorg-server/man/Xserver.man
index c03830c15..3bf844f98 100644
--- a/xorg-server/man/Xserver.man
+++ b/xorg-server/man/Xserver.man
@@ -181,6 +181,16 @@ prints a usage message.
.B \-I
causes all remaining command line arguments to be ignored.
.TP 8
+.B \-iglx
+Prohibit creating indirect GLX contexts. Indirect GLX is of limited use,
+since it lacks support for many modern OpenGL features and extensions;
+it's slower than direct contexts; and it opens a large attack surface for
+protocol parsing errors.
+This is the default unless +iglx is specified.
+.TP 8
+.B +iglx
+Allow creating indirect GLX contexts.
+.TP 8
.B \-maxbigreqsize \fIsize\fP
sets the maximum big request to
.I size
diff --git a/xorg-server/os/access.c b/xorg-server/os/access.c
index 5c510ded2..28f2d3213 100644
--- a/xorg-server/os/access.c
+++ b/xorg-server/os/access.c
@@ -1296,6 +1296,10 @@ GetHosts(void **data, int *pnHosts, int *pLen, BOOL * pEnabled)
for (host = validhosts; host; host = host->next) {
nHosts++;
n += pad_to_int32(host->len) + sizeof(xHostEntry);
+ /* Could check for INT_MAX, but in reality having more than 1mb of
+ hostnames in the access list is ridiculous */
+ if (n >= 1048576)
+ break;
}
if (n) {
*data = ptr = malloc(n);
@@ -1304,6 +1308,8 @@ GetHosts(void **data, int *pnHosts, int *pLen, BOOL * pEnabled)
}
for (host = validhosts; host; host = host->next) {
len = host->len;
+ if ((ptr + sizeof(xHostEntry) + len) > ((unsigned char *) *data + n))
+ break;
((xHostEntry *) ptr)->family = host->family;
((xHostEntry *) ptr)->length = len;
ptr += sizeof(xHostEntry);
diff --git a/xorg-server/os/io.c b/xorg-server/os/io.c
index bb273bb0c..96a243d8c 100644
--- a/xorg-server/os/io.c
+++ b/xorg-server/os/io.c
@@ -971,10 +971,11 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
}
if (notWritten > oco->size) {
- unsigned char *obuf;
+ unsigned char *obuf = NULL;
- obuf = (unsigned char *) realloc(oco->buf,
- notWritten + BUFSIZE);
+ if (notWritten + BUFSIZE <= INT_MAX) {
+ obuf = realloc(oco->buf, notWritten + BUFSIZE);
+ }
if (!obuf) {
_XSERVTransDisconnect(oc->trans_conn);
_XSERVTransClose(oc->trans_conn);
diff --git a/xorg-server/os/log.c b/xorg-server/os/log.c
index 2e3b3f61f..0532c2eb7 100644
--- a/xorg-server/os/log.c
+++ b/xorg-server/os/log.c
@@ -257,8 +257,11 @@ void
LogClose(enum ExitCode error)
{
if (logFile) {
- ErrorFSigSafe("Server terminated %s (%d). Closing log file.\n",
- (error == EXIT_NO_ERROR) ? "successfully" : "with error", error);
+ int msgtype = (error == EXIT_NO_ERROR) ? X_INFO : X_ERROR;
+ LogMessageVerbSigSafe(msgtype, -1,
+ "Server terminated %s (%d). Closing log file.\n",
+ (error == EXIT_NO_ERROR) ? "successfully" : "with error",
+ error);
fclose(logFile);
logFile = NULL;
logFileFd = -1;
diff --git a/xorg-server/os/osinit.c b/xorg-server/os/osinit.c
index ff0979ac8..91e3e068c 100644
--- a/xorg-server/os/osinit.c
+++ b/xorg-server/os/osinit.c
@@ -208,9 +208,11 @@ OsInit(void)
* for failures to load libraries/modules at runtime so we can clean up
* after ourselves.
*/
- int failure_signal = SIGQUIT;
+ {
+ int failure_signal = SIGQUIT;
- dlinfo(RTLD_SELF, RTLD_DI_SETSIGNAL, &failure_signal);
+ dlinfo(RTLD_SELF, RTLD_DI_SETSIGNAL, &failure_signal);
+ }
#endif
#if !defined(XQUARTZ) /* STDIN is already /dev/null and STDOUT/STDERR is managed by console_redirect.c */
diff --git a/xorg-server/os/rpcauth.c b/xorg-server/os/rpcauth.c
index d60ea3518..413cc6118 100644
--- a/xorg-server/os/rpcauth.c
+++ b/xorg-server/os/rpcauth.c
@@ -66,6 +66,10 @@ authdes_ezdecode(const char *inmsg, int len)
SVCXPRT xprt;
temp_inmsg = malloc(len);
+ if (temp_inmsg == NULL) {
+ why = AUTH_FAILED; /* generic error, since there is no AUTH_BADALLOC */
+ return NULL;
+ }
memmove(temp_inmsg, inmsg, len);
memset((char *) &msg, 0, sizeof(msg));
diff --git a/xorg-server/os/xsha1.c b/xorg-server/os/xsha1.c
index 24c0aa284..c54e68c83 100644
--- a/xorg-server/os/xsha1.c
+++ b/xorg-server/os/xsha1.c
@@ -1,3 +1,28 @@
+/* Copyright © 2007 Carl Worth
+ * Copyright © 2009 Jeremy Huddleston, Julien Cristau, and Matthieu Herrb
+ * Copyright © 2009-2010 Mikhail Gusarov
+ * Copyright © 2012 Yaakov Selkowitz and Keith Packard
+ *
+ * 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.
+ */
+
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
diff --git a/xorg-server/present/present.c b/xorg-server/present/present.c
index ac9047edb..2a705a968 100644
--- a/xorg-server/present/present.c
+++ b/xorg-server/present/present.c
@@ -440,7 +440,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
DebugPresent(("\tn %lld %p %8lld: %08lx -> %08lx\n",
vblank->event_id, vblank, vblank->target_msc,
vblank->pixmap ? vblank->pixmap->drawable.id : 0,
- vblank->window->drawable.id));
+ vblank->window ? vblank->window->drawable.id : 0));
assert (vblank == screen_priv->flip_pending);
@@ -834,10 +834,13 @@ present_pixmap(WindowPtr window,
vblank->notifies = notifies;
vblank->num_notifies = num_notifies;
- if (!screen_priv->info || !(screen_priv->info->capabilities & PresentCapabilityAsync))
+ if (!(options & PresentOptionAsync))
vblank->sync_flip = TRUE;
if (!(options & PresentOptionCopy) &&
+ !((options & PresentOptionAsync) &&
+ (!screen_priv->info ||
+ !(screen_priv->info->capabilities & PresentCapabilityAsync))) &&
pixmap != NULL &&
present_check_flip (target_crtc, window, pixmap, vblank->sync_flip, valid, x_off, y_off))
{
@@ -859,28 +862,27 @@ present_pixmap(WindowPtr window,
}
if (pixmap)
- DebugPresent(("q %lld %p %8lld: %08lx -> %08lx (crtc %p)\n",
+ DebugPresent(("q %lld %p %8lld: %08lx -> %08lx (crtc %p) flip %d vsync %d serial %d\n",
vblank->event_id, vblank, target_msc,
vblank->pixmap->drawable.id, vblank->window->drawable.id,
- target_crtc));
+ target_crtc, vblank->flip, vblank->sync_flip, vblank->serial));
xorg_list_add(&vblank->event_queue, &present_exec_queue);
vblank->queued = TRUE;
if ((pixmap && target_msc >= crtc_msc) || (!pixmap && target_msc > crtc_msc)) {
ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc);
- if (ret != Success) {
- xorg_list_del(&vblank->event_queue);
- vblank->queued = FALSE;
- goto failure;
- }
- } else
- present_execute(vblank, ust, crtc_msc);
+ if (ret == Success)
+ return Success;
+
+ DebugPresent(("present_queue_vblank failed\n"));
+ }
+
+ present_execute(vblank, ust, crtc_msc);
return Success;
no_mem:
ret = BadAlloc;
-failure:
vblank->notifies = NULL;
present_vblank_destroy(vblank);
return ret;
@@ -955,7 +957,7 @@ present_vblank_destroy(present_vblank_ptr vblank)
DebugPresent(("\td %lld %p %8lld: %08lx -> %08lx\n",
vblank->event_id, vblank, vblank->target_msc,
vblank->pixmap ? vblank->pixmap->drawable.id : 0,
- vblank->window->drawable.id));
+ vblank->window ? vblank->window->drawable.id : 0));
/* Drop pixmap reference */
if (vblank->pixmap)
diff --git a/xorg-server/present/present_request.c b/xorg-server/present/present_request.c
index 835890d28..7c53e7262 100644
--- a/xorg-server/present/present_request.c
+++ b/xorg-server/present/present_request.c
@@ -210,6 +210,7 @@ proc_present_query_capabilities (ClientPtr client)
RRCrtcPtr crtc = NULL;
int r;
+ REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq);
r = dixLookupWindow(&window, stuff->target, client, DixGetAttrAccess);
switch (r) {
case Success:
@@ -254,6 +255,7 @@ static int
sproc_present_query_version(ClientPtr client)
{
REQUEST(xPresentQueryVersionReq);
+ REQUEST_SIZE_MATCH(xPresentQueryVersionReq);
swaps(&stuff->length);
swapl(&stuff->majorVersion);
@@ -265,6 +267,7 @@ static int
sproc_present_pixmap(ClientPtr client)
{
REQUEST(xPresentPixmapReq);
+ REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
swaps(&stuff->length);
swapl(&stuff->window);
@@ -284,6 +287,7 @@ static int
sproc_present_notify_msc(ClientPtr client)
{
REQUEST(xPresentNotifyMSCReq);
+ REQUEST_SIZE_MATCH(xPresentNotifyMSCReq);
swaps(&stuff->length);
swapl(&stuff->window);
@@ -297,6 +301,7 @@ static int
sproc_present_select_input (ClientPtr client)
{
REQUEST(xPresentSelectInputReq);
+ REQUEST_SIZE_MATCH(xPresentSelectInputReq);
swaps(&stuff->length);
swapl(&stuff->window);
@@ -308,6 +313,7 @@ static int
sproc_present_query_capabilities (ClientPtr client)
{
REQUEST(xPresentQueryCapabilitiesReq);
+ REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq);
swaps(&stuff->length);
swapl(&stuff->target);
return (*proc_present_vector[stuff->presentReqType]) (client);
diff --git a/xorg-server/randr/rrsdispatch.c b/xorg-server/randr/rrsdispatch.c
index 08c3b6abe..47558cf75 100644
--- a/xorg-server/randr/rrsdispatch.c
+++ b/xorg-server/randr/rrsdispatch.c
@@ -27,6 +27,7 @@ SProcRRQueryVersion(ClientPtr client)
{
REQUEST(xRRQueryVersionReq);
+ REQUEST_SIZE_MATCH(xRRQueryVersionReq);
swaps(&stuff->length);
swapl(&stuff->majorVersion);
swapl(&stuff->minorVersion);
@@ -38,6 +39,7 @@ SProcRRGetScreenInfo(ClientPtr client)
{
REQUEST(xRRGetScreenInfoReq);
+ REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
swaps(&stuff->length);
swapl(&stuff->window);
return (*ProcRandrVector[stuff->randrReqType]) (client);
@@ -69,6 +71,7 @@ SProcRRSelectInput(ClientPtr client)
{
REQUEST(xRRSelectInputReq);
+ REQUEST_SIZE_MATCH(xRRSelectInputReq);
swaps(&stuff->length);
swapl(&stuff->window);
swaps(&stuff->enable);
@@ -152,6 +155,7 @@ SProcRRConfigureOutputProperty(ClientPtr client)
{
REQUEST(xRRConfigureOutputPropertyReq);
+ REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq);
swaps(&stuff->length);
swapl(&stuff->output);
swapl(&stuff->property);
diff --git a/xorg-server/render/picture.c b/xorg-server/render/picture.c
index 711cbc7bb..6ff31ba02 100644
--- a/xorg-server/render/picture.c
+++ b/xorg-server/render/picture.c
@@ -41,6 +41,9 @@
#include "servermd.h"
#include "picturestr.h"
#include "xace.h"
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
DevPrivateKeyRec PictureScreenPrivateKeyRec;
DevPrivateKeyRec PictureWindowPrivateKeyRec;
@@ -1007,6 +1010,38 @@ CreateConicalGradientPicture(Picture pid, xPointFixed * center, xFixed angle,
return pPicture;
}
+static int
+cpAlphaMap(void **result, XID id, ScreenPtr screen, ClientPtr client, Mask mode)
+{
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ PanoramiXRes *res;
+ int err = dixLookupResourceByType((void **)&res, id, XRT_PICTURE,
+ client, mode);
+ if (err != Success)
+ return err;
+ id = res->info[screen->myNum].id;
+ }
+#endif
+ return dixLookupResourceByType(result, id, PictureType, client, mode);
+}
+
+static int
+cpClipMask(void **result, XID id, ScreenPtr screen, ClientPtr client, Mask mode)
+{
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ PanoramiXRes *res;
+ int err = dixLookupResourceByType((void **)&res, id, XRT_PIXMAP,
+ client, mode);
+ if (err != Success)
+ return err;
+ id = res->info[screen->myNum].id;
+ }
+#endif
+ return dixLookupResourceByType(result, id, RT_PIXMAP, client, mode);
+}
+
#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
#define NEXT_PTR(_type) ((_type) ulist++->ptr)
@@ -1053,9 +1088,8 @@ ChangePicture(PicturePtr pPicture,
if (pid == None)
pAlpha = 0;
else {
- error = dixLookupResourceByType((void **) &pAlpha, pid,
- PictureType, client,
- DixReadAccess);
+ error = cpAlphaMap((void **) &pAlpha, pid, pScreen,
+ client, DixReadAccess);
if (error != Success) {
client->errorValue = pid;
break;
@@ -1112,9 +1146,8 @@ ChangePicture(PicturePtr pPicture,
}
else {
clipType = CT_PIXMAP;
- error = dixLookupResourceByType((void **) &pPixmap, pid,
- RT_PIXMAP, client,
- DixReadAccess);
+ error = cpClipMask((void **) &pPixmap, pid, pScreen,
+ client, DixReadAccess);
if (error != Success) {
client->errorValue = pid;
break;
diff --git a/xorg-server/render/render.c b/xorg-server/render/render.c
index e3031da25..723f380c2 100644
--- a/xorg-server/render/render.c
+++ b/xorg-server/render/render.c
@@ -276,11 +276,11 @@ ProcRenderQueryVersion(ClientPtr client)
REQUEST(xRenderQueryVersionReq);
+ REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+
pRenderClient->major_version = stuff->majorVersion;
pRenderClient->minor_version = stuff->minorVersion;
- REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
-
if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
(SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) {
rep.majorVersion = stuff->majorVersion;
@@ -1995,7 +1995,7 @@ static int
SProcRenderQueryVersion(ClientPtr client)
{
REQUEST(xRenderQueryVersionReq);
-
+ REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
swaps(&stuff->length);
swapl(&stuff->majorVersion);
swapl(&stuff->minorVersion);
@@ -2006,6 +2006,7 @@ static int
SProcRenderQueryPictFormats(ClientPtr client)
{
REQUEST(xRenderQueryPictFormatsReq);
+ REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
swaps(&stuff->length);
return (*ProcRenderVector[stuff->renderReqType]) (client);
}
@@ -2014,6 +2015,7 @@ static int
SProcRenderQueryPictIndexValues(ClientPtr client)
{
REQUEST(xRenderQueryPictIndexValuesReq);
+ REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
swaps(&stuff->length);
swapl(&stuff->format);
return (*ProcRenderVector[stuff->renderReqType]) (client);
@@ -2029,6 +2031,7 @@ static int
SProcRenderCreatePicture(ClientPtr client)
{
REQUEST(xRenderCreatePictureReq);
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
swaps(&stuff->length);
swapl(&stuff->pid);
swapl(&stuff->drawable);
@@ -2042,6 +2045,7 @@ static int
SProcRenderChangePicture(ClientPtr client)
{
REQUEST(xRenderChangePictureReq);
+ REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
swaps(&stuff->length);
swapl(&stuff->picture);
swapl(&stuff->mask);
@@ -2053,6 +2057,7 @@ static int
SProcRenderSetPictureClipRectangles(ClientPtr client)
{
REQUEST(xRenderSetPictureClipRectanglesReq);
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
swaps(&stuff->length);
swapl(&stuff->picture);
swaps(&stuff->xOrigin);
@@ -2065,6 +2070,7 @@ static int
SProcRenderFreePicture(ClientPtr client)
{
REQUEST(xRenderFreePictureReq);
+ REQUEST_SIZE_MATCH(xRenderFreePictureReq);
swaps(&stuff->length);
swapl(&stuff->picture);
return (*ProcRenderVector[stuff->renderReqType]) (client);
@@ -2074,6 +2080,7 @@ static int
SProcRenderComposite(ClientPtr client)
{
REQUEST(xRenderCompositeReq);
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
swaps(&stuff->length);
swapl(&stuff->src);
swapl(&stuff->mask);
@@ -2093,6 +2100,7 @@ static int
SProcRenderScale(ClientPtr client)
{
REQUEST(xRenderScaleReq);
+ REQUEST_SIZE_MATCH(xRenderScaleReq);
swaps(&stuff->length);
swapl(&stuff->src);
swapl(&stuff->dst);
@@ -2193,6 +2201,7 @@ static int
SProcRenderCreateGlyphSet(ClientPtr client)
{
REQUEST(xRenderCreateGlyphSetReq);
+ REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
swaps(&stuff->length);
swapl(&stuff->gsid);
swapl(&stuff->format);
@@ -2203,6 +2212,7 @@ static int
SProcRenderReferenceGlyphSet(ClientPtr client)
{
REQUEST(xRenderReferenceGlyphSetReq);
+ REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
swaps(&stuff->length);
swapl(&stuff->gsid);
swapl(&stuff->existing);
@@ -2213,6 +2223,7 @@ static int
SProcRenderFreeGlyphSet(ClientPtr client)
{
REQUEST(xRenderFreeGlyphSetReq);
+ REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
swaps(&stuff->length);
swapl(&stuff->glyphset);
return (*ProcRenderVector[stuff->renderReqType]) (client);
@@ -2227,6 +2238,7 @@ SProcRenderAddGlyphs(ClientPtr client)
xGlyphInfo *gi;
REQUEST(xRenderAddGlyphsReq);
+ REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
swaps(&stuff->length);
swapl(&stuff->glyphset);
swapl(&stuff->nglyphs);
@@ -2261,6 +2273,7 @@ static int
SProcRenderFreeGlyphs(ClientPtr client)
{
REQUEST(xRenderFreeGlyphsReq);
+ REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
swaps(&stuff->length);
swapl(&stuff->glyphset);
SwapRestL(stuff);
@@ -2278,6 +2291,7 @@ SProcRenderCompositeGlyphs(ClientPtr client)
int size;
REQUEST(xRenderCompositeGlyphsReq);
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
switch (stuff->renderReqType) {
default:
diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am
index 83442767a..82578d977 100644
--- a/xorg-server/test/Makefile.am
+++ b/xorg-server/test/Makefile.am
@@ -4,7 +4,7 @@ noinst_PROGRAMS = list string
if XORG
# Tests that require at least some DDX functions in order to fully link
# For now, requires xf86 ddx, could be adjusted to use another
-SUBDIRS += xi2
+SUBDIRS += xi1 xi2
noinst_PROGRAMS += xkb input xtest misc fixes xfree86 os signal-logging touch
if RES
noinst_PROGRAMS += hashtabletest
diff --git a/xorg-server/test/misc.c b/xorg-server/test/misc.c
index dd792e692..66330a140 100644
--- a/xorg-server/test/misc.c
+++ b/xorg-server/test/misc.c
@@ -28,6 +28,8 @@
#include <stdint.h>
#include "misc.h"
#include "scrnintstr.h"
+#include "dix.h"
+#include "dixstruct.h"
ScreenInfo screenInfo;
@@ -155,11 +157,46 @@ dix_update_desktop_dimensions(void)
assert_dimensions(-w2, -h2, w2, h2);
}
+static int
+dix_request_fixed_size_overflow(ClientRec *client)
+{
+ xReq req = { 0 };
+
+ client->req_len = req.length = 1;
+ REQUEST_FIXED_SIZE(req, SIZE_MAX);
+ return Success;
+}
+
+static int
+dix_request_fixed_size_match(ClientRec *client)
+{
+ xReq req = { 0 };
+
+ client->req_len = req.length = 9;
+ REQUEST_FIXED_SIZE(req, 30);
+ return Success;
+}
+
+static void
+dix_request_size_checks(void)
+{
+ ClientRec client = { 0 };
+ int rc;
+
+ rc = dix_request_fixed_size_overflow(&client);
+ assert(rc == BadLength);
+
+ rc = dix_request_fixed_size_match(&client);
+ assert(rc == Success);
+}
+
+
int
main(int argc, char **argv)
{
dix_version_compare();
dix_update_desktop_dimensions();
+ dix_request_size_checks();
return 0;
}
diff --git a/xorg-server/test/xi1/Makefile.am b/xorg-server/test/xi1/Makefile.am
new file mode 100644
index 000000000..907fa7aea
--- /dev/null
+++ b/xorg-server/test/xi1/Makefile.am
@@ -0,0 +1,34 @@
+if ENABLE_UNIT_TESTS
+if HAVE_LD_WRAP
+noinst_PROGRAMS = \
+ protocol-xchangedevicecontrol
+
+TESTS=$(noinst_PROGRAMS)
+TESTS_ENVIRONMENT = $(XORG_MALLOC_DEBUG_ENV)
+
+AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
+AM_CPPFLAGS = @XORG_INCS@ -I$(srcdir)/../xi2
+TEST_LDADD=../libxservertest.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) $(GLX_SYS_LIBS)
+COMMON_SOURCES=$(srcdir)/../xi2/protocol-common.c
+
+if SPECIAL_DTRACE_OBJECTS
+TEST_LDADD += $(OS_LIB) $(DIX_LIB)
+endif
+
+protocol_xchangedevicecontrol_LDADD=$(TEST_LDADD)
+
+protocol_xchangedevicecontrol_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient
+
+protocol_xchangedevicecontrol_SOURCES=$(COMMON_SOURCES) protocol-xchangedevicecontrol.c
+
+else
+# Print that xi1-tests were skipped (exit code 77 for automake test harness)
+TESTS = xi1-tests
+CLEANFILES = $(TESTS)
+
+xi1-tests:
+ @echo 'echo "ld -wrap support required for xi1 unit tests, skipping"' > $@
+ @echo 'exit 77' >> $@
+ $(AM_V_GEN)chmod +x $@
+endif
+endif
diff --git a/xorg-server/test/xi1/protocol-xchangedevicecontrol.c b/xorg-server/test/xi1/protocol-xchangedevicecontrol.c
new file mode 100644
index 000000000..8e638b218
--- /dev/null
+++ b/xorg-server/test/xi1/protocol-xchangedevicecontrol.c
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+/*
+ * Protocol testing for ChangeDeviceControl request.
+ */
+#include <stdint.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/XIproto.h>
+#include "inputstr.h"
+#include "chgdctl.h"
+
+#include "protocol-common.h"
+
+static ClientRec client_request;
+
+static void
+reply_ChangeDeviceControl(ClientPtr client, int len, char *data, void *userdata)
+{
+ xChangeDeviceControlReply *rep = (xChangeDeviceControlReply *) data;
+
+ if (client->swapped) {
+ swapl(&rep->length);
+ swaps(&rep->sequenceNumber);
+ }
+
+ reply_check_defaults(rep, len, ChangeDeviceControl);
+
+ /* XXX: check status code in reply */
+}
+
+static void
+request_ChangeDeviceControl(ClientPtr client, xChangeDeviceControlReq * req,
+ xDeviceCtl *ctl, int error)
+{
+ int rc;
+
+ client_request.req_len = req->length;
+ rc = ProcXChangeDeviceControl(&client_request);
+ assert(rc == error);
+
+ /* XXX: ChangeDeviceControl doesn't seem to fill in errorValue to check */
+
+ client_request.swapped = TRUE;
+ swaps(&req->length);
+ swaps(&req->control);
+ swaps(&ctl->length);
+ swaps(&ctl->control);
+ /* XXX: swap other contents of ctl, depending on type */
+ rc = SProcXChangeDeviceControl(&client_request);
+ assert(rc == error);
+}
+
+static unsigned char *data[4096]; /* the request buffer */
+
+static void
+test_ChangeDeviceControl(void)
+{
+ xChangeDeviceControlReq *request = (xChangeDeviceControlReq *) data;
+ xDeviceCtl *control = (xDeviceCtl *) (&request[1]);
+
+ request_init(request, ChangeDeviceControl);
+
+ reply_handler = reply_ChangeDeviceControl;
+
+ client_request = init_client(request->length, request);
+
+ printf("Testing invalid lengths:\n");
+ printf(" -- no control struct\n");
+ request_ChangeDeviceControl(&client_request, request, control, BadLength);
+
+ printf(" -- xDeviceResolutionCtl\n");
+ request_init(request, ChangeDeviceControl);
+ request->control = DEVICE_RESOLUTION;
+ control->length = (sizeof(xDeviceResolutionCtl) >> 2);
+ request->length += control->length - 2;
+ request_ChangeDeviceControl(&client_request, request, control, BadLength);
+
+ printf(" -- xDeviceEnableCtl\n");
+ request_init(request, ChangeDeviceControl);
+ request->control = DEVICE_ENABLE;
+ control->length = (sizeof(xDeviceEnableCtl) >> 2);
+ request->length += control->length - 2;
+ request_ChangeDeviceControl(&client_request, request, control, BadLength);
+
+ /* XXX: Test functionality! */
+}
+
+int
+main(int argc, char **argv)
+{
+ init_simple();
+
+ test_ChangeDeviceControl();
+
+ return 0;
+}
diff --git a/xorg-server/test/xi2/protocol-xigetclientpointer.c b/xorg-server/test/xi2/protocol-xigetclientpointer.c
index 28eb8d32a..570c53e06 100644
--- a/xorg-server/test/xi2/protocol-xigetclientpointer.c
+++ b/xorg-server/test/xi2/protocol-xigetclientpointer.c
@@ -124,6 +124,11 @@ test_XIGetClientPointer(void)
request.win = INVALID_WINDOW_ID;
request_XIGetClientPointer(&client_request, &request, BadWindow);
+ printf("Testing invalid length\n");
+ client_request.req_len -= 4;
+ request_XIGetClientPointer(&client_request, &request, BadLength);
+ client_request.req_len += 4;
+
test_data.cp_is_set = FALSE;
printf("Testing window None, unset ClientPointer.\n");
diff --git a/xorg-server/test/xi2/protocol-xipassivegrabdevice.c b/xorg-server/test/xi2/protocol-xipassivegrabdevice.c
index c747ddf03..95d8ebf2b 100644
--- a/xorg-server/test/xi2/protocol-xipassivegrabdevice.c
+++ b/xorg-server/test/xi2/protocol-xipassivegrabdevice.c
@@ -139,6 +139,7 @@ request_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req,
int local_modifiers;
int mask_len;
+ client_request.req_len = req->length;
rc = ProcXIPassiveGrabDevice(&client_request);
assert(rc == error);
@@ -190,6 +191,13 @@ test_XIPassiveGrabDevice(void)
request_XIPassiveGrabDevice(&client_request, request, BadDevice,
request->deviceid);
+ printf("Testing invalid length\n");
+ request->length -= 2;
+ request_XIPassiveGrabDevice(&client_request, request, BadLength,
+ client_request.errorValue);
+ /* re-init request since swapped length test leaves some values swapped */
+ request_init(request, XIPassiveGrabDevice);
+ request->grab_window = CLIENT_WINDOW_ID;
request->deviceid = XIAllMasterDevices;
printf("Testing invalid grab types\n");
diff --git a/xorg-server/test/xi2/protocol-xiquerypointer.c b/xorg-server/test/xi2/protocol-xiquerypointer.c
index fc66b6429..c0421f6dd 100644
--- a/xorg-server/test/xi2/protocol-xiquerypointer.c
+++ b/xorg-server/test/xi2/protocol-xiquerypointer.c
@@ -201,6 +201,10 @@ test_XIQueryPointer(void)
test_data.dev = devices.mouse;
request.deviceid = devices.mouse->id;
request_XIQueryPointer(&client_request, &request, Success);
+
+ /* test REQUEST_SIZE_MATCH */
+ client_request.req_len -= 4;
+ request_XIQueryPointer(&client_request, &request, BadLength);
}
int
diff --git a/xorg-server/test/xi2/protocol-xiwarppointer.c b/xorg-server/test/xi2/protocol-xiwarppointer.c
index f7986c1eb..3aaaae6f9 100644
--- a/xorg-server/test/xi2/protocol-xiwarppointer.c
+++ b/xorg-server/test/xi2/protocol-xiwarppointer.c
@@ -198,6 +198,9 @@ test_XIWarpPointer(void)
request_XIWarpPointer(&client_request, &request, Success);
/* FIXME: src_x/y checks */
+
+ client_request.req_len -= 2; /* invalid length */
+ request_XIWarpPointer(&client_request, &request, BadLength);
}
int
diff --git a/xorg-server/xfixes/select.c b/xorg-server/xfixes/select.c
index c088ed3de..e964d588c 100644
--- a/xorg-server/xfixes/select.c
+++ b/xorg-server/xfixes/select.c
@@ -201,6 +201,7 @@ SProcXFixesSelectSelectionInput(ClientPtr client)
{
REQUEST(xXFixesSelectSelectionInputReq);
+ REQUEST_SIZE_MATCH(xXFixesSelectSelectionInputReq);
swaps(&stuff->length);
swapl(&stuff->window);
swapl(&stuff->selection);
diff --git a/xorg-server/xkeyboard-config/rules/base.extras.xml.in b/xorg-server/xkeyboard-config/rules/base.extras.xml.in
index 2e1e89d6b..749fc7225 100644
--- a/xorg-server/xkeyboard-config/rules/base.extras.xml.in
+++ b/xorg-server/xkeyboard-config/rules/base.extras.xml.in
@@ -120,6 +120,16 @@
</variant>
<variant>
<configItem>
+ <name>pl</name>
+ <_description>Polish (Germany, eliminate dead keys)</_description>
+ <languageList>
+ <iso639Id>ger</iso639Id>
+ <iso639Id>pol</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
<name>sun_type6</name>
<_description>German (Sun Type 6/7)</_description>
</configItem>
diff --git a/xorg-server/xkeyboard-config/rules/base.xml.in b/xorg-server/xkeyboard-config/rules/base.xml.in
index 682f8c9f9..5f12801f9 100644
--- a/xorg-server/xkeyboard-config/rules/base.xml.in
+++ b/xorg-server/xkeyboard-config/rules/base.xml.in
@@ -2568,7 +2568,7 @@
<_shortDescription>ug</_shortDescription>
<_description>Uyghur</_description>
<languageList>
- <iso639Id>ug</iso639Id>
+ <iso639Id>uig</iso639Id>
</languageList>
</configItem>
</variant>
@@ -6628,7 +6628,7 @@
<option>
<configItem>
<name>numpad:microsoft</name>
- <_description>Shift with numeric keypad keys works as in MS Windows</_description>
+ <_description>NumLock on: digits, Shift switches to arrow keys, Numlock off: always arrow keys (as in MS Windows)</_description>
</configItem>
</option>
<option>
diff --git a/xorg-server/xkeyboard-config/symbols/de b/xorg-server/xkeyboard-config/symbols/de
index 944732e51..fa3c7ec97 100644
--- a/xorg-server/xkeyboard-config/symbols/de
+++ b/xorg-server/xkeyboard-config/symbols/de
@@ -637,6 +637,40 @@ xkb_symbols "ru" {
};
partial alphanumeric_keys
+xkb_symbols "pl" {
+
+ // Combined layout for entering both German and Polish symbols on a German physical
+ // keyboard. Based on German (eliminate dead keys) and Polish (basic). Polish diacritics
+ // on AltGr+"acelnosxz". EuroSign moved to AE04 (AltGr+dollar key) to avoid conflict
+ // with Polish eogonek.
+ //
+ // https://github.com/kontextify/xkeyboard-config
+
+ include "latin(type4)"
+
+ name[Group1]= "Polish (Germany, eliminate dead keys)";
+
+ include "de(nodeadkeys)"
+ key <AE04> { [ 4, dollar, EuroSign, currency ] };
+
+ key <AD01> { [ q, Q ] };
+ key <AD02> { [ w, W ] };
+ key <AD03> { [ e, E, eogonek, Eogonek ] };
+ key <AD09> { [ o, O, oacute, Oacute ] };
+ key <AC01> { [ a, A, aogonek, Aogonek ] };
+ key <AC02> { [ s, S, sacute, Sacute ] };
+ key <AC04> { [ f, F ] };
+ key <AD06> { [ z, Z, zabovedot, Zabovedot ] };
+ key <AB02> { [ x, X, zacute, Zacute ] };
+ key <AB03> { [ c, C, cacute, Cacute ] };
+ key <AB06> { [ n, N, nacute, Nacute ] };
+
+ include "kpdl(comma)"
+
+ include "level3(ralt_switch)"
+};
+
+partial alphanumeric_keys
xkb_symbols "htcdream" {
include "inet(htcdream)"
diff --git a/xorg-server/xkeyboard-config/symbols/fi b/xorg-server/xkeyboard-config/symbols/fi
index 6afed2106..47bc24f13 100644
--- a/xorg-server/xkeyboard-config/symbols/fi
+++ b/xorg-server/xkeyboard-config/symbols/fi
@@ -79,7 +79,6 @@ xkb_symbols "kotoistus" {
include "nbsp(level3)"
include "kpdl(comma)"
include "level3(ralt_switch)"
- include "compose(rwin)"
};
partial alphanumeric_keys
diff --git a/xorg-server/xkeyboard-config/symbols/fujitsu_vndr/jp b/xorg-server/xkeyboard-config/symbols/fujitsu_vndr/jp
index 63bf56aca..26ae26768 100644
--- a/xorg-server/xkeyboard-config/symbols/fujitsu_vndr/jp
+++ b/xorg-server/xkeyboard-config/symbols/fujitsu_vndr/jp
@@ -25,7 +25,7 @@
//
// Japanese layout for a Fujitsu 140 key keyboard
-xkb_symbols {
+xkb_symbols "basic" {
override "fujitsu_vndr/us"
augment key <AE01> { [], [ kana_NU ] };
key <AE02> { [ 2, quotedbl ], [ kana_FU ] };
diff --git a/xorg-server/xkeyboard-config/symbols/fujitsu_vndr/us b/xorg-server/xkeyboard-config/symbols/fujitsu_vndr/us
index 30661dbb2..f62b5c832 100644
--- a/xorg-server/xkeyboard-config/symbols/fujitsu_vndr/us
+++ b/xorg-server/xkeyboard-config/symbols/fujitsu_vndr/us
@@ -24,7 +24,7 @@
//from The Open Group.
//
// US/ASCII layout for a Fujitsu 138 key keyboard
-xkb_symbols {
+xkb_symbols "basic" {
include "us(basic)"
// A few alphanumeric keys are different
diff --git a/xorg-server/xkeyboard-config/symbols/il b/xorg-server/xkeyboard-config/symbols/il
index 48452d620..67487c111 100644
--- a/xorg-server/xkeyboard-config/symbols/il
+++ b/xorg-server/xkeyboard-config/symbols/il
@@ -205,7 +205,7 @@ xkb_symbols "biblical" {
key <AE02> { [ 2, U0599, VoidSymbol, at ] };
key <AE03> { [ 3, U0592, VoidSymbol, numbersign ] };
key <AE04> { [ 4, U05AF, NewSheqelSign, dollar ] };
- key <AE05> { [ 5, VoidSymbol, U200D, percent ] };
+ key <AE05> { [ 5, U05BA, U200D, percent ] };
key <AE06> { [ 6, U05B9, U200C, asciicircum ] };
key <AE07> { [ 7, U05BF, U034F, ampersand ] };
key <AE08> { [ 8, U05C2, U200E, asterisk ] };
diff --git a/xorg-server/xkeyboard-config/symbols/ru b/xorg-server/xkeyboard-config/symbols/ru
index 37b61a7dc..0ba987067 100644
--- a/xorg-server/xkeyboard-config/symbols/ru
+++ b/xorg-server/xkeyboard-config/symbols/ru
@@ -478,11 +478,12 @@ xkb_symbols "srp" {
};
// Mari language layout
-// http://www.marlamuter.ru/
+// http://www.marlamuter.com/
+// Last edit by Viatcheslav Kileev (slavakileev@yandex.ru)
partial alphanumeric_keys
xkb_symbols "chm" {
- include "ru(common)"
+ include "ru(winkeys)"
name[Group1]= "Mari";
key.type[group1]="FOUR_LEVEL_ALPHABETIC";
@@ -491,9 +492,7 @@ xkb_symbols "chm" {
key <AD03> { [ Cyrillic_u, Cyrillic_U, U04F1, U04F0 ] };
key <AC02> { [ Cyrillic_yeru, Cyrillic_YERU, U04F9, U04F8 ] };
key <AD06> { [ Cyrillic_en, Cyrillic_EN, U04A5, U04A4 ] };
- key <AC11> { [ Cyrillic_e, Cyrillic_E, U04E9, U04E8 ] };
- key <AC10> { [ Cyrillic_zhe, Cyrillic_ZHE, U04EB, U04EA ] };
- key <AC01> { [ Cyrillic_ef, Cyrillic_EF, UF537, UF536 ] };
+ key <AC07> { [ Cyrillic_o, Cyrillic_O, U04E7, U04E6 ] };
include "level3(ralt_switch)"
};