meson: use gnu_symbol_visibility argument
[mesa.git] / src / glx / drisw_glx.c
index b3e00f9a4e010b47cca0e6b8a762efba830006ee..985e258663e5af79362626defb7ad26e107ec387 100644 (file)
 #include <X11/extensions/shmproto.h>
 #include <assert.h>
 
-static Bool
-driswCreateGCs(struct drisw_drawable * pdp,
-               Display * dpy, XID drawable, int visualid)
-{
-   long visMask;
-   XVisualInfo visTemp;
-   int num_visuals;
-
-   pdp->gc = XCreateGC(dpy, drawable, 0, NULL);
-
-   /* visual */
-   visTemp.visualid = visualid;
-   visMask = VisualIDMask;
-   pdp->visinfo = XGetVisualInfo(dpy, visMask, &visTemp, &num_visuals);
-
-   if (!pdp->visinfo || num_visuals == 0)
-      return False;
-
-   return True;
-}
-
 static int xshm_error = 0;
 static int xshm_opcode = -1;
 
@@ -77,13 +56,15 @@ XCreateDrawable(struct drisw_drawable * pdp, int shmid, Display * dpy)
    if (pdp->ximage) {
       XDestroyImage(pdp->ximage);
       pdp->ximage = NULL;
+      if ((pdp->shminfo.shmid > 0) && (shmid != pdp->shminfo.shmid))
+         XShmDetach(dpy, &pdp->shminfo);
    }
 
    if (!xshm_error && shmid >= 0) {
       pdp->shminfo.shmid = shmid;
       pdp->ximage = XShmCreateImage(dpy,
-                                    pdp->visinfo->visual,
-                                    pdp->visinfo->depth,
+                                    NULL,
+                                    pdp->xDepth,
                                     ZPixmap,              /* format */
                                     NULL,                 /* data */
                                     &pdp->shminfo,        /* shminfo */
@@ -112,8 +93,8 @@ XCreateDrawable(struct drisw_drawable * pdp, int shmid, Display * dpy)
    if (pdp->ximage == NULL) {
       pdp->shminfo.shmid = -1;
       pdp->ximage = XCreateImage(dpy,
-                                 pdp->visinfo->visual,
-                                 pdp->visinfo->depth,
+                                 NULL,
+                                 pdp->xDepth,
                                  ZPixmap, 0,             /* format, offset */
                                  NULL,                   /* data */
                                  0, 0,                   /* width, height */
@@ -140,8 +121,6 @@ XDestroyDrawable(struct drisw_drawable * pdp, Display * dpy, XID drawable)
    if (pdp->shminfo.shmid > 0)
       XShmDetach(dpy, &pdp->shminfo);
 
-   free(pdp->visinfo);
-
    XFreeGC(dpy, pdp->gc);
 }
 
@@ -214,14 +193,13 @@ swrastXPutImage(__DRIdrawable * draw, int op,
    ximage->bytes_per_line = stride ? stride : bytes_per_line(w * ximage->bits_per_pixel, 32);
    ximage->data = data;
 
+   ximage->width = ximage->bytes_per_line / ((ximage->bits_per_pixel + 7)/ 8);
+   ximage->height = h;
+
    if (pdp->shminfo.shmid >= 0) {
-      ximage->width = ximage->bytes_per_line / ((ximage->bits_per_pixel + 7)/ 8);
-      ximage->height = h;
       XShmPutImage(dpy, drawable, gc, ximage, srcx, srcy, x, y, w, h, False);
       XSync(dpy, False);
    } else {
-      ximage->width = w;
-      ximage->height = h;
       XPutImage(dpy, drawable, gc, ximage, srcx, srcy, x, y, w, h);
    }
    ximage->data = NULL;
@@ -309,10 +287,10 @@ swrastGetImage(__DRIdrawable * read,
    swrastGetImage2(read, x, y, w, h, 0, data, loaderPrivate);
 }
 
-static void
-swrastGetImageShm(__DRIdrawable * read,
-                  int x, int y, int w, int h,
-                  int shmid, void *loaderPrivate)
+static GLboolean
+swrastGetImageShm2(__DRIdrawable * read,
+                   int x, int y, int w, int h,
+                   int shmid, void *loaderPrivate)
 {
    struct drisw_drawable *prp = loaderPrivate;
    __GLXDRIdrawable *pread = &(prp->base);
@@ -322,8 +300,11 @@ swrastGetImageShm(__DRIdrawable * read,
 
    if (!prp->ximage || shmid != prp->shminfo.shmid) {
       if (!XCreateDrawable(prp, shmid, dpy))
-         return;
+         return GL_FALSE;
    }
+
+   if (prp->shminfo.shmid == -1)
+      return GL_FALSE;
    readable = pread->xDrawable;
 
    ximage = prp->ximage;
@@ -333,10 +314,19 @@ swrastGetImageShm(__DRIdrawable * read,
    ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32);
 
    XShmGetImage(dpy, readable, ximage, x, y, ~0L);
+   return GL_TRUE;
+}
+
+static void
+swrastGetImageShm(__DRIdrawable * read,
+                  int x, int y, int w, int h,
+                  int shmid, void *loaderPrivate)
+{
+   swrastGetImageShm2(read, x, y, w, h, shmid, loaderPrivate);
 }
 
 static const __DRIswrastLoaderExtension swrastLoaderExtension_shm = {
-   .base = {__DRI_SWRAST_LOADER, 5 },
+   .base = {__DRI_SWRAST_LOADER, 6 },
 
    .getDrawableInfo     = swrastGetDrawableInfo,
    .putImage            = swrastPutImage,
@@ -346,6 +336,7 @@ static const __DRIswrastLoaderExtension swrastLoaderExtension_shm = {
    .putImageShm         = swrastPutImageShm,
    .getImageShm         = swrastGetImageShm,
    .putImageShm2        = swrastPutImageShm2,
+   .getImageShm2        = swrastGetImageShm2,
 };
 
 static const __DRIextension *loader_extensions_shm[] = {
@@ -667,8 +658,8 @@ driswCreateDrawable(struct glx_screen *base, XID xDrawable,
    struct drisw_drawable *pdp;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
    struct drisw_screen *psc = (struct drisw_screen *) base;
-   Bool ret;
    const __DRIswrastExtension *swrast = psc->swrast;
+   Display *dpy = psc->base.dpy;
 
    pdp = calloc(1, sizeof(*pdp));
    if (!pdp)
@@ -677,11 +668,34 @@ driswCreateDrawable(struct glx_screen *base, XID xDrawable,
    pdp->base.xDrawable = xDrawable;
    pdp->base.drawable = drawable;
    pdp->base.psc = &psc->base;
+   pdp->config = modes;
+   pdp->gc = XCreateGC(dpy, xDrawable, 0, NULL);
+   pdp->xDepth = 0;
+
+   /* Use the visual depth, if this fbconfig corresponds to a visual */
+   if (pdp->config->visualID != 0) {
+      int matches = 0;
+      XVisualInfo *visinfo, template;
+
+      template.visualid = pdp->config->visualID;
+      template.screen = pdp->config->screen;
+      visinfo = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask,
+                               &template, &matches);
+
+      if (visinfo && matches) {
+         pdp->xDepth = visinfo->depth;
+         XFree(visinfo);
+      }
+   }
 
-   ret = driswCreateGCs(pdp, psc->base.dpy, xDrawable, modes->visualID);
-   if (!ret) {
-      free(pdp);
-      return NULL;
+   /* Otherwise, or if XGetVisualInfo failed, ask the server */
+   if (pdp->xDepth == 0) {
+      Window root;
+      int x, y;
+      unsigned uw, uh, bw, depth;
+
+      XGetGeometry(dpy, xDrawable, &root, &x, &y, &uw, &uh, &bw, &depth);
+      pdp->xDepth = depth;
    }
 
    /* Create a new drawable */