From 5e5a48ff8cd08f123601cd0625ca62a86675aac9 Mon Sep 17 00:00:00 2001 From: marha Date: Sun, 4 Jan 2015 16:25:32 +0100 Subject: fontconfig libX11 mesa xserver git update 4 Jan 2015 xserver commit dc777c346d5d452a53b13b917c45f6a1bad2f20b libX11 commit 446f5f7f41317a85a0cd0efa5e6a1b37bc99fba2 fontconfig commit 4420b27c074821a1d1f9d6ebe822a610176a417d mesa commit 48094d0e6554a9df36bf00fc2793ade46cf92406 --- xorg-server/Xext/xcmisc.c | 1 + xorg-server/Xext/xvdisp.c | 20 ++ xorg-server/Xi/chgdctl.c | 8 +- xorg-server/Xi/chgfctl.c | 2 + xorg-server/Xi/sendexev.c | 3 + xorg-server/Xi/xiallowev.c | 2 + xorg-server/Xi/xichangecursor.c | 2 +- xorg-server/Xi/xichangehierarchy.c | 35 ++- xorg-server/Xi/xigetclientpointer.c | 1 + xorg-server/Xi/xigrabdev.c | 9 +- xorg-server/Xi/xipassivegrab.c | 12 +- xorg-server/Xi/xiproperty.c | 14 +- xorg-server/Xi/xiquerydevice.c | 1 + xorg-server/Xi/xiquerypointer.c | 2 + xorg-server/Xi/xiselectev.c | 8 + xorg-server/Xi/xisetclientpointer.c | 3 +- xorg-server/Xi/xisetdevfocus.c | 4 + xorg-server/Xi/xiwarppointer.c | 2 + xorg-server/config/udev.c | 7 +- xorg-server/configure.ac | 1 + xorg-server/dbe/dbe.c | 17 +- xorg-server/dix/dispatch.c | 3 + xorg-server/dix/region.c | 20 +- xorg-server/dri3/dri3_request.c | 6 + xorg-server/glamor/glamor.c | 34 +-- xorg-server/glamor/glamor.h | 4 + xorg-server/glamor/glamor_egl.c | 89 +++--- xorg-server/glamor/glamor_egl_stubs.c | 2 +- xorg-server/glamor/glamor_fbo.c | 4 +- xorg-server/glamor/glamor_priv.h | 2 - xorg-server/glamor/glamor_xv.c | 26 +- xorg-server/glx/clientinfo.c | 20 +- xorg-server/glx/glxcmds.c | 96 +++--- xorg-server/glx/glxcmdsswap.c | 4 + xorg-server/glx/glxext.c | 8 +- xorg-server/glx/glxext.h | 1 - xorg-server/glx/glxserver.h | 43 ++- xorg-server/glx/indirect_program.c | 2 + xorg-server/glx/indirect_reqsize.c | 142 +++++---- xorg-server/glx/indirect_reqsize.h | 181 ++++++----- xorg-server/glx/indirect_texture_compression.c | 4 + xorg-server/glx/indirect_util.c | 9 +- xorg-server/glx/rensize.c | 114 ++++--- xorg-server/glx/single2.c | 23 +- xorg-server/glx/single2swap.c | 19 +- xorg-server/glx/singlepix.c | 60 ++-- xorg-server/glx/singlepixswap.c | 50 ++- xorg-server/glx/swap_interval.c | 2 + xorg-server/glx/unpack.h | 3 +- xorg-server/hw/kdrive/ephyr/ephyr.c | 2 +- xorg-server/hw/kdrive/ephyr/ephyr.h | 1 + xorg-server/hw/kdrive/ephyr/hostx.c | 11 +- xorg-server/hw/kdrive/ephyr/hostx.h | 2 +- xorg-server/hw/xfree86/common/xf86AutoConfig.c | 1 - xorg-server/hw/xfree86/dri2/dri2ext.c | 3 + .../hw/xfree86/drivers/modesetting/Makefile.am | 3 + xorg-server/hw/xfree86/drivers/modesetting/dri2.c | 2 - .../hw/xfree86/drivers/modesetting/driver.c | 104 ++++--- .../hw/xfree86/drivers/modesetting/driver.h | 15 +- .../xfree86/drivers/modesetting/drmmode_display.c | 337 ++++++++++----------- .../xfree86/drivers/modesetting/drmmode_display.h | 33 +- .../hw/xfree86/drivers/modesetting/dumb_bo.c | 134 ++++++++ .../hw/xfree86/drivers/modesetting/dumb_bo.h | 45 +++ .../hw/xfree86/drivers/modesetting/present.c | 228 ++++++++++++++ .../hw/xfree86/drivers/modesetting/vblank.c | 28 +- .../hw/xfree86/os-support/solaris/sun_init.c | 33 -- xorg-server/hw/xfree86/os-support/xf86_OSlib.h | 5 + xorg-server/hw/xwayland/xwayland-glamor.c | 3 +- xorg-server/hw/xwayland/xwayland-input.c | 7 +- xorg-server/hw/xwin/InitOutput.c | 4 + xorg-server/hw/xwin/XWin.rc | 1 + xorg-server/hw/xwin/man/XWin.man | 6 +- xorg-server/hw/xwin/winclipboard/internal.h | 14 +- xorg-server/hw/xwin/winclipboard/thread.c | 56 ++-- xorg-server/hw/xwin/winclipboard/winclipboard.h | 2 + xorg-server/hw/xwin/winclipboard/wndproc.c | 227 +++++++++----- xorg-server/hw/xwin/winclipboard/xevents.c | 175 +++++------ xorg-server/hw/xwin/winclipboard/xwinclip.c | 7 + xorg-server/hw/xwin/winclipboard/xwinclip.man | 3 + xorg-server/hw/xwin/winclipboardwrappers.c | 6 - xorg-server/hw/xwin/winprocarg.c | 27 +- xorg-server/hw/xwin/winresource.h | 1 + xorg-server/hw/xwin/wintrayicon.c | 19 ++ xorg-server/hw/xwin/winwndproc.c | 6 + xorg-server/include/dix.h | 7 +- xorg-server/include/regionstr.h | 10 +- xorg-server/man/Xserver.man | 10 + xorg-server/os/access.c | 6 + xorg-server/os/io.c | 7 +- xorg-server/os/log.c | 7 +- xorg-server/os/osinit.c | 6 +- xorg-server/os/rpcauth.c | 4 + xorg-server/os/xsha1.c | 25 ++ xorg-server/present/present.c | 28 +- xorg-server/present/present_request.c | 6 + xorg-server/randr/rrsdispatch.c | 4 + xorg-server/render/picture.c | 45 ++- xorg-server/render/render.c | 20 +- xorg-server/test/Makefile.am | 2 +- xorg-server/test/misc.c | 37 +++ xorg-server/test/xi1/Makefile.am | 34 +++ .../test/xi1/protocol-xchangedevicecontrol.c | 122 ++++++++ xorg-server/test/xi2/protocol-xigetclientpointer.c | 5 + .../test/xi2/protocol-xipassivegrabdevice.c | 8 + xorg-server/test/xi2/protocol-xiquerypointer.c | 4 + xorg-server/test/xi2/protocol-xiwarppointer.c | 3 + xorg-server/xfixes/select.c | 1 + .../xkeyboard-config/rules/base.extras.xml.in | 10 + xorg-server/xkeyboard-config/rules/base.xml.in | 4 +- xorg-server/xkeyboard-config/symbols/de | 34 +++ xorg-server/xkeyboard-config/symbols/fi | 1 - .../xkeyboard-config/symbols/fujitsu_vndr/jp | 2 +- .../xkeyboard-config/symbols/fujitsu_vndr/us | 2 +- xorg-server/xkeyboard-config/symbols/il | 2 +- xorg-server/xkeyboard-config/symbols/ru | 9 +- 115 files changed, 2203 insertions(+), 938 deletions(-) create mode 100644 xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c create mode 100644 xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.h create mode 100644 xorg-server/hw/xfree86/drivers/modesetting/present.c create mode 100644 xorg-server/test/xi1/Makefile.am create mode 100644 xorg-server/test/xi1/protocol-xchangedevicecontrol.c (limited to 'xorg-server') 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 #include +#ifdef GLAMOR +#define GLAMOR_FOR_XORG 1 +#include "glamor.h" +#ifdef GLAMOR_HAS_GBM +#include +#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 #include #include +#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,45 +416,43 @@ 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 + * + */ + +#include "dumb_bo.h" + +#include +#include +#include +#include +#include +#include +#include + +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 + * + */ +#ifndef DUMB_BO_H +#define DUMB_BO_H + +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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); @@ -322,6 +330,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 /* @@ -370,15 +346,6 @@ xf86ProcessArgument(int argc, char **argv, int i) return 1; } - /* - * 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. */ 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 #include + +extern _X_HIDDEN void xf86VTAcquire(int); +extern _X_HIDDEN void xf86VTRelease(int); #endif #if defined(sun) #include +extern _X_HIDDEN char xf86SolarisFbDev[PATH_MAX]; + #include #include 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 #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 #include +#include #include @@ -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 +#include #include #include #include +#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 @@ -43,12 +43,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 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 #endif + #include "win.h" #include #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 #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 #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 +#endif + +/* + * Protocol testing for ChangeDeviceControl request. + */ +#include +#include +#include +#include +#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 @@ -118,6 +118,16 @@ + + + pl + <_description>Polish (Germany, eliminate dead keys) + + ger + pol + + + sun_type6 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 <_description>Uyghur - ug + uig @@ -6628,7 +6628,7 @@