summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim Woelders <kim@woelders.dk>2008-11-01 18:11:10 +0000
committerKim Woelders <kim@woelders.dk>2008-11-01 18:11:10 +0000
commit06a53a073d1798a883e149635dc4fc7feab5a1b6 (patch)
tree7cde702d56bccbb347ec120fe3e0d71032937fbd
parent5b60182d96fa136366e1f5ae6329edcbc886d47f (diff)
downloadimlib2-06a53a073d1798a883e149635dc4fc7feab5a1b6.tar.gz
Refactor shm stuff.
SVN revision: 37378
-rw-r--r--src/lib/grab.c134
-rw-r--r--src/lib/ximage.c201
-rw-r--r--src/lib/ximage.h8
3 files changed, 126 insertions, 217 deletions
diff --git a/src/lib/grab.c b/src/lib/grab.c
index d38218f..39017dd 100644
--- a/src/lib/grab.c
+++ b/src/lib/grab.c
@@ -7,6 +7,7 @@
#include <sys/ipc.h>
#include <sys/shm.h>
#include "grab.h"
+#include "ximage.h"
static char _x_err = 0;
static DATA8 rtab[256], gtab[256], btab[256];
@@ -530,7 +531,7 @@ __imlib_GrabDrawableToRGBA(DATA32 * data, int ox, int oy, int ow, int oh,
int src_x, src_y, src_w, src_h, origw, origh;
int width, height, clipx, clipy;
XShmSegmentInfo shminfo, mshminfo;
- XImage *xim = NULL, *mxim = NULL;
+ XImage *xim, *mxim;
static signed char x_does_shm = -1;
XColor cols[256];
@@ -662,62 +663,15 @@ __imlib_GrabDrawableToRGBA(DATA32 * data, int ox, int oy, int ow, int oh,
/* Create an Ximage (shared or not) */
if (x_does_shm < 0)
- {
- if (XShmQueryExtension(d))
- x_does_shm = 1;
- else
- x_does_shm = 0;
- }
-
- prev_erh = XSetErrorHandler((XErrorHandler) Tmp_HandleXError);
+ __imlib_ShmCheck(d);
+ xim = NULL;
if (x_does_shm)
{
- _x_err = 0;
- xim = XShmCreateImage(d, v, xatt.depth, ZPixmap, NULL, &shminfo, w, h);
- if (xim)
- {
- XSync(d, False);
- if (_x_err)
- {
- XDestroyImage(xim);
- }
- else
- {
- shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line *
- xim->height, IPC_CREAT | 0666);
- if (shminfo.shmid < 0)
- {
- XDestroyImage(xim);
- }
- else
- {
- shminfo.shmaddr = xim->data = shmat(shminfo.shmid, 0, 0);
- if (xim->data != (char *)-1)
- {
- shminfo.readOnly = False;
- XShmAttach(d, &shminfo);
- is_shm = 1;
- XShmGetImage(d, p, xim, x, y, 0xffffffff);
- XSync(d, False);
- if (_x_err)
- {
- shmdt(shminfo.shmaddr);
- shmctl(shminfo.shmid, IPC_RMID, 0);
- XDestroyImage(xim);
- is_shm = 0;
- }
- }
- else
- {
- shmctl(shminfo.shmid, IPC_RMID, 0);
- XDestroyImage(xim);
- }
- }
- }
- }
+ xim = __imlib_ShmGetXImage(d, v, p, xatt.depth, x, y, w, h, &shminfo);
+ is_shm = xim != NULL;
}
- if (!is_shm)
+ if (!xim)
xim = XGetImage(d, p, x, y, w, h, 0xffffffff, ZPixmap);
if (!xim)
{
@@ -726,62 +680,15 @@ __imlib_GrabDrawableToRGBA(DATA32 * data, int ox, int oy, int ow, int oh,
return 0;
}
+ mxim = NULL;
if ((m) && (domask))
{
- _x_err = 0;
- if (x_does_shm)
- {
- mxim = XShmCreateImage(d, v, 1, ZPixmap, NULL, &mshminfo, w, h);
- if (mxim)
- {
- XSync(d, False);
- if (_x_err)
- {
- XDestroyImage(mxim);
- }
- else
- {
- mshminfo.shmid = shmget(IPC_PRIVATE,
- mxim->bytes_per_line *
- mxim->height, IPC_CREAT | 0666);
- if (mshminfo.shmid < 0)
- {
- XDestroyImage(mxim);
- }
- else
- {
- mshminfo.shmaddr = mxim->data =
- shmat(mshminfo.shmid, 0, 0);
- if (mxim->data != (char *)-1)
- {
- mshminfo.readOnly = False;
- XShmAttach(d, &mshminfo);
- is_mshm = 1;
- XShmGetImage(d, m, mxim, 0, 0, 0xffffffff);
- XSync(d, False);
- if (_x_err)
- {
- shmdt(mshminfo.shmaddr);
- shmctl(mshminfo.shmid, IPC_RMID, 0);
- XDestroyImage(mxim);
- is_mshm = 0;
- }
- }
- else
- {
- shmctl(mshminfo.shmid, IPC_RMID, 0);
- XDestroyImage(mxim);
- }
- }
- }
- }
- }
- if (!is_mshm)
+ mxim = __imlib_ShmGetXImage(d, v, m, 1, 0, 0, w, h, &mshminfo);
+ is_mshm = mxim != NULL;
+ if (!mxim)
mxim = XGetImage(d, m, 0, 0, w, h, 0xffffffff, ZPixmap);
}
- XSetErrorHandler((XErrorHandler) prev_erh);
-
if ((is_shm) || (is_mshm))
{
XSync(d, False);
@@ -835,23 +742,16 @@ __imlib_GrabDrawableToRGBA(DATA32 * data, int ox, int oy, int ow, int oh,
/* destroy the Ximage */
if (is_shm)
+ __imlib_ShmDetach(d, &shminfo);
+ XDestroyImage(xim);
+ if (mxim)
{
- XSync(d, False);
- XShmDetach(d, &shminfo);
- shmdt(shminfo.shmaddr);
- shmctl(shminfo.shmid, IPC_RMID, 0);
- }
- if ((is_mshm) && (mxim))
- {
- XShmDetach(d, &mshminfo);
- shmdt(mshminfo.shmaddr);
- shmctl(mshminfo.shmid, IPC_RMID, 0);
+ if (is_mshm)
+ __imlib_ShmDetach(d, &mshminfo);
+ XDestroyImage(mxim);
}
- XDestroyImage(xim);
if (created_mask)
XFreePixmap(d, m);
- if (mxim)
- XDestroyImage(mxim);
if (pdomask)
{
diff --git a/src/lib/ximage.c b/src/lib/ximage.c
index 230e5b0..daa3059 100644
--- a/src/lib/ximage.c
+++ b/src/lib/ximage.c
@@ -31,6 +31,87 @@ TmpXError(Display * d, XErrorEvent * ev)
ev = NULL;
}
+void
+__imlib_ShmCheck(Display * d)
+{
+ /* if its there set x_does_shm flag */
+ if (XShmQueryExtension(d))
+ x_does_shm = 1;
+ /* clear the flag - no shm at all */
+ else
+ x_does_shm = 0;
+}
+
+XImage *
+__imlib_ShmGetXImage(Display * d, Visual * v, Drawable draw, int depth,
+ int x, int y, int w, int h, XShmSegmentInfo * si)
+{
+ XImage *xim;
+
+ /* try create an shm image */
+ xim = XShmCreateImage(d, v, depth, ZPixmap, NULL, si, w, h);
+ if (!xim)
+ return NULL;
+
+ /* get an shm id of this image */
+ si->shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height,
+ IPC_CREAT | 0666);
+ /* if the get succeeds */
+ if (si->shmid != -1)
+ {
+ /* set the params for the shm segment */
+ si->readOnly = False;
+ si->shmaddr = xim->data = shmat(si->shmid, 0, 0);
+ /* get the shm addr for this data chunk */
+ if (xim->data != (char *)-1)
+ {
+ XErrorHandler ph;
+
+ /* setup a temporary error handler */
+ _x_err = 0;
+ ph = XSetErrorHandler((XErrorHandler) TmpXError);
+ /* ask X to attach to the shared mem segment */
+ XShmAttach(d, si);
+ if (draw != None)
+ XShmGetImage(d, draw, xim, x, y, 0xffffffff);
+ /* wait for X to reply and do this */
+ XSync(d, False);
+ /* reset the error handler */
+ XSetErrorHandler((XErrorHandler) ph);
+
+ /* if we attached without an error we're set */
+ if (_x_err == 0)
+ return xim;
+
+ /* attach by X failed... must be remote client */
+ /* flag shm forever to not work - remote */
+ x_does_shm = 0;
+
+ /* detach */
+ shmdt(si->shmaddr);
+ }
+
+ /* get failed - out of shm id's or shm segment too big ? */
+ /* remove the shm id we created */
+ shmctl(si->shmid, IPC_RMID, 0);
+ }
+
+ /* couldnt create SHM image ? */
+ /* destroy previous image */
+ XDestroyImage(xim);
+
+ return NULL;
+}
+
+void
+__imlib_ShmDetach(Display * d, XShmSegmentInfo * si)
+{
+ XSync(d, False);
+ XShmDetach(d, si);
+ shmdt(si->shmaddr);
+ shmctl(si->shmid, IPC_RMID, 0);
+}
+
/* "safe" realloc allowing handling of out-of-memory situations */
static void *
_safe_realloc(void *ptr, size_t size, int *err)
@@ -95,14 +176,11 @@ __imlib_FlushXImage(Display * d)
xim = list_xim[i];
list_mem_use -= xim->bytes_per_line * xim->height;
if (list_si[i])
- XShmDetach(d, list_si[i]);
- XDestroyImage(xim);
- if (list_si[i])
{
- shmdt(list_si[i]->shmaddr);
- shmctl(list_si[i]->shmid, IPC_RMID, 0);
+ __imlib_ShmDetach(d, list_si[i]);
free(list_si[i]);
}
+ XDestroyImage(xim);
list_num--;
for (j = i; j < list_num; j++)
{
@@ -175,14 +253,8 @@ __imlib_ProduceXImage(Display * d, Visual * v, int depth, int w, int h,
/* if we havent check the shm extension before - see if its there */
if (x_does_shm < 0)
- {
- /* if its there set dose_xhm flag */
- if (XShmQueryExtension(d))
- x_does_shm = 1;
- /* clear the flag - no shm at all */
- else
- x_does_shm = 0;
- }
+ __imlib_ShmCheck(d);
+
/* find a cached XImage (to avoid server to & fro) that is big enough */
/* for our needs and the right depth */
*shared = 0;
@@ -237,87 +309,15 @@ __imlib_ProduceXImage(Display * d, Visual * v, int depth, int w, int h,
/* if the server does shm */
if (x_does_shm)
{
- /* try create an shm image */
- xim = XShmCreateImage(d, v, depth, ZPixmap, NULL,
- list_si[list_num - 1], w, h);
- /* if it succeeds */
- if (xim)
- {
- /* add to list */
- list_xim[list_num - 1] = xim;
- /* get an shm id of this image */
- list_si[list_num - 1]->shmid =
- shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height,
- IPC_CREAT | 0777);
- /* if the get succeeds */
- if (list_si[list_num - 1]->shmid != -1)
- {
- /* set the params for the shm segment */
- list_si[list_num - 1]->readOnly = False;
- list_si[list_num - 1]->shmaddr = xim->data =
- shmat(list_si[list_num - 1]->shmid, 0, 0);
- /* get the shm addr for this data chunk */
- if (xim->data != (char *)-1)
- {
- XErrorHandler ph;
-
- /* setup a temporary error handler */
- _x_err = 0;
- ph = XSetErrorHandler((XErrorHandler) TmpXError);
- /* ask X to attach to the shared mem segment */
- XShmAttach(d, list_si[list_num - 1]);
- /* wait for X to reply and do this */
- XSync(d, False);
- /* reset the error handler */
- XSetErrorHandler((XErrorHandler) ph);
- /* if we attached without an error we're set */
- if (!_x_err)
- {
- /* mark the image as used */
- list_used[list_num - 1] = 1;
- /* incrument our memory count */
- list_mem_use += xim->bytes_per_line * xim->height;
- /* set shared flag */
- *shared = 1;
- }
- /* attach by X failed... must be remote client */
- else
- {
- /* flag shm foevere to not work - remote */
- x_does_shm = 0;
- /* destroy our previous image */
- XDestroyImage(xim);
- /* detach */
- shmdt(list_si[list_num - 1]->shmaddr);
- /* remove the shm id */
- shmctl(list_si[list_num - 1]->shmid, IPC_RMID, 0);
- /* flag out xim as NULL */
- xim = NULL;
- }
- }
- /* get failed - out of shm id's or shm segment too big ? */
- else
- {
- /* destroy previous image */
- XDestroyImage(xim);
- /* remove the shm id we created */
- shmctl(list_si[list_num - 1]->shmid, IPC_RMID, 0);
- /* flag xim as NULL */
- xim = NULL;
- }
- }
- /* couldnt create SHM image ? */
- else
- {
- /* destroy previous image */
- XDestroyImage(xim);
- /* flag xim as NULL */
- xim = NULL;
- }
- }
+ xim = __imlib_ShmGetXImage(d, v, None, depth, 0, 0, w, h,
+ list_si[list_num - 1]);
}
/* ok if xim == NULL it all failed - fall back to XImages */
- if (!xim)
+ if (xim)
+ {
+ *shared = 1;
+ }
+ else
{
/* get rid of out shm info struct */
free(list_si[list_num - 1]);
@@ -336,15 +336,16 @@ __imlib_ProduceXImage(Display * d, Visual * v, int depth, int w, int h,
list_num--;
return NULL;
}
- /* add xim to our list */
- list_xim[list_num - 1] = xim;
- /* incriment our memory count */
- list_mem_use += xim->bytes_per_line * xim->height;
- /* mark image as used */
- list_used[list_num - 1] = 1;
- /* remember what display that XImage was for */
- list_d[list_num - 1] = d;
}
+ /* add xim to our list */
+ list_xim[list_num - 1] = xim;
+ /* incriment our memory count */
+ list_mem_use += xim->bytes_per_line * xim->height;
+ /* mark image as used */
+ list_used[list_num - 1] = 1;
+ /* remember what display that XImage was for */
+ list_d[list_num - 1] = d;
+
/* flush unused images from the image list */
__imlib_FlushXImage(d);
diff --git a/src/lib/ximage.h b/src/lib/ximage.h
index c1fc7ef..a690f71 100644
--- a/src/lib/ximage.h
+++ b/src/lib/ximage.h
@@ -1,6 +1,9 @@
#ifndef __XIMAGE
#define __XIMAGE 1
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+
void __imlib_SetMaxXImageCount(Display * d, int num);
__hidden int __imlib_GetMaxXImageCount(Display * d);
__hidden void __imlib_SetMaxXImageTotalSize(Display * d, int num);
@@ -9,5 +12,10 @@ __hidden void __imlib_FlushXImage(Display * d);
__hidden void __imlib_ConsumeXImage(Display * d, XImage * xim);
__hidden XImage *__imlib_ProduceXImage(Display * d, Visual * v, int depth,
int w, int h, char *shared);
+__hidden void __imlib_ShmCheck(Display * d);
+__hidden XImage *__imlib_ShmGetXImage(Display * d, Visual * v, Drawable draw,
+ int depth, int x, int y, int w, int h,
+ XShmSegmentInfo * si);
+__hidden void __imlib_ShmDetach(Display * d, XShmSegmentInfo * si);
#endif