mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-23 11:51:27 +00:00
In XwindowBuffer get the default visual and depth from the XGServer.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@26961 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
c6c8160a30
commit
1802f35b22
4 changed files with 312 additions and 283 deletions
|
@ -1,3 +1,11 @@
|
|||
2008-10-24 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/x11/XGServer.m (-visualForScreen:, -depthForScreen:):
|
||||
New methods that hide RContext details.
|
||||
* Headers/x11/XGServer.h: Declare these new methods.
|
||||
* Source/x11/XWindowBuffer.m: Get the default visual and depth
|
||||
from the XGServer.
|
||||
|
||||
2008-10-22 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/x11/XGServerWindow.m (-_checkStyle:): Correct code
|
||||
|
|
|
@ -63,6 +63,9 @@ typedef enum {
|
|||
- (Window) xAppRootWindow;
|
||||
|
||||
- (void *) xrContextForScreen: (int)screen_number;
|
||||
- (Visual *) visualForScreen: (int)screen_number;
|
||||
- (int) depthForScreen: (int)screen_number;
|
||||
|
||||
- (XGDrawMechanism) drawMechanismForScreen: (int)screen_number;
|
||||
- (void) getForScreen: (int)screen_number pixelFormat: (int *)bpp_number
|
||||
masks: (int *)red_mask : (int *)green_mask : (int *)blue_mask;
|
||||
|
|
|
@ -518,6 +518,16 @@ _parse_display_name(NSString *name, int *dn, int *sn)
|
|||
return [[self _screenContextForScreen: screen_number] context];
|
||||
}
|
||||
|
||||
- (Visual *) visualForScreen: (int)screen_number
|
||||
{
|
||||
return [[self _screenContextForScreen: screen_number] context]->visual;
|
||||
}
|
||||
|
||||
- (int) depthForScreen: (int)screen_number
|
||||
{
|
||||
return [[self _screenContextForScreen: screen_number] context]->depth;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the XGDrawMechanism, which roughly describes the depth of
|
||||
the screen and how pixels should be drawn to the screen for maximum
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
|
@ -49,7 +49,7 @@ static int use_xshm = 1;
|
|||
static int num_xshm_test_errors = 0;
|
||||
|
||||
static NSString *xshm_warning
|
||||
= @"Falling back to normal XImage: s (will be slower).";
|
||||
= @"Falling back to normal XImage: s (will be slower).";
|
||||
|
||||
static int test_xshm_error_handler(Display *d, XErrorEvent *ev)
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ static int test_xshm_error_handler(Display *d, XErrorEvent *ev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void test_xshm(Display *display, int drawing_depth)
|
||||
static void test_xshm(Display *display, Visual *visual, int drawing_depth)
|
||||
{
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
|
@ -93,39 +93,38 @@ static void test_xshm(Display *display, int drawing_depth)
|
|||
|
||||
old_error_handler = XSetErrorHandler(test_xshm_error_handler);
|
||||
|
||||
ximage = XShmCreateImage(display,
|
||||
DefaultVisual(display, DefaultScreen(display)),
|
||||
drawing_depth, ZPixmap, NULL, &shminfo,
|
||||
1, 1);
|
||||
ximage = XShmCreateImage(display, visual,
|
||||
drawing_depth, ZPixmap, NULL, &shminfo,
|
||||
1, 1);
|
||||
XSync(display, False);
|
||||
if (!ximage || num_xshm_test_errors)
|
||||
{
|
||||
NSLog(@"XShm not supported, XShmCreateImage failed.");
|
||||
goto no_xshm;
|
||||
NSLog(@"XShm not supported, XShmCreateImage failed.");
|
||||
goto no_xshm;
|
||||
}
|
||||
|
||||
shminfo.shmid = shmget(IPC_PRIVATE,
|
||||
64, /* We don't have exact bytes per row values here, but this
|
||||
should be safe, and we'll probably get a full page anyway.
|
||||
(And if it turns out not to be enough, the X server will notice
|
||||
and give us errors, causing us to think that XShm isn't
|
||||
supported.) */
|
||||
IPC_CREAT | 0700);
|
||||
64, /* We don't have exact bytes per row values here, but this
|
||||
should be safe, and we'll probably get a full page anyway.
|
||||
(And if it turns out not to be enough, the X server will notice
|
||||
and give us errors, causing us to think that XShm isn't
|
||||
supported.) */
|
||||
IPC_CREAT | 0700);
|
||||
|
||||
if (shminfo.shmid == -1 || num_xshm_test_errors)
|
||||
{
|
||||
NSLog(@"XShm not supported, shmget() failed: %m.");
|
||||
XDestroyImage(ximage);
|
||||
goto no_xshm;
|
||||
NSLog(@"XShm not supported, shmget() failed: %m.");
|
||||
XDestroyImage(ximage);
|
||||
goto no_xshm;
|
||||
}
|
||||
|
||||
shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
|
||||
if ((intptr_t)shminfo.shmaddr == -1 || num_xshm_test_errors)
|
||||
{
|
||||
NSLog(@"XShm not supported, shmat() failed: %m.");
|
||||
XDestroyImage(ximage);
|
||||
shmctl(shminfo.shmid, IPC_RMID, 0);
|
||||
goto no_xshm;
|
||||
NSLog(@"XShm not supported, shmat() failed: %m.");
|
||||
XDestroyImage(ximage);
|
||||
shmctl(shminfo.shmid, IPC_RMID, 0);
|
||||
goto no_xshm;
|
||||
}
|
||||
|
||||
shminfo.readOnly = 0;
|
||||
|
@ -134,11 +133,11 @@ static void test_xshm(Display *display, int drawing_depth)
|
|||
XSync(display, False);
|
||||
if (num_xshm_test_errors)
|
||||
{
|
||||
NSLog(@"XShm not supported, XShmAttach() failed.");
|
||||
XDestroyImage(ximage);
|
||||
shmdt(shminfo.shmaddr);
|
||||
shmctl(shminfo.shmid, IPC_RMID, 0);
|
||||
goto no_xshm;
|
||||
NSLog(@"XShm not supported, XShmAttach() failed.");
|
||||
XDestroyImage(ximage);
|
||||
shmdt(shminfo.shmaddr);
|
||||
shmctl(shminfo.shmid, IPC_RMID, 0);
|
||||
goto no_xshm;
|
||||
}
|
||||
|
||||
XShmDetach(display, &shminfo);
|
||||
|
@ -154,10 +153,10 @@ static void test_xshm(Display *display, int drawing_depth)
|
|||
|
||||
if (num_xshm_test_errors)
|
||||
{
|
||||
NSLog(@"XShm not supported.");
|
||||
NSLog(@"XShm not supported.");
|
||||
no_xshm:
|
||||
NSLog(xshm_warning);
|
||||
use_xshm = 0;
|
||||
NSLog(xshm_warning);
|
||||
use_xshm = 0;
|
||||
}
|
||||
XSetErrorHandler(old_error_handler);
|
||||
}
|
||||
|
@ -166,16 +165,24 @@ no_xshm:
|
|||
|
||||
@implementation XWindowBuffer
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
use_shape_hack = [ud boolForKey: @"XWindowBuffer-shape-hack"];
|
||||
}
|
||||
|
||||
+ windowBufferForWindow: (gswindow_device_t *)awindow
|
||||
depthInfo: (struct XWindowBuffer_depth_info_s *)aDI
|
||||
{
|
||||
int i;
|
||||
XWindowBuffer *wi;
|
||||
int drawing_depth;
|
||||
Visual *visual;
|
||||
|
||||
for (i = 0; i < num_window_buffers; i++)
|
||||
{
|
||||
if (window_buffers[i]->window == awindow)
|
||||
break;
|
||||
break;
|
||||
}
|
||||
if (i == num_window_buffers)
|
||||
{
|
||||
|
@ -184,11 +191,11 @@ no_xshm:
|
|||
window_buffers = realloc(window_buffers,
|
||||
sizeof(XWindowBuffer *) * (num_window_buffers + 1));
|
||||
if (!window_buffers)
|
||||
{
|
||||
NSLog(@"Out of memory (failed to allocate %i bytes)",
|
||||
sizeof(XWindowBuffer *) * (num_window_buffers + 1));
|
||||
exit(1);
|
||||
}
|
||||
{
|
||||
NSLog(@"Out of memory (failed to allocate %i bytes)",
|
||||
sizeof(XWindowBuffer *) * (num_window_buffers + 1));
|
||||
exit(1);
|
||||
}
|
||||
window_buffers[num_window_buffers++] = wi;
|
||||
}
|
||||
else
|
||||
|
@ -205,6 +212,15 @@ no_xshm:
|
|||
wi->window->gdriverProtocol = GDriverHandlesExpose | GDriverHandlesBacking;
|
||||
wi->window->gdriver = wi;
|
||||
|
||||
#if 0
|
||||
drawing_depth = aDI->drawing_depth;
|
||||
visual = DefaultVisual(wi->display, DefaultScreen(wi->display));
|
||||
#else
|
||||
// Better to get the used visual from the XGServer.
|
||||
visual = [(XGServer*)GSCurrentServer() visualForScreen: awindow->screen];
|
||||
drawing_depth = [(XGServer*)GSCurrentServer() depthForScreen: awindow->screen];
|
||||
#endif
|
||||
|
||||
/* TODO: resolve properly.
|
||||
-x11 is creating buffers before I have a chance to tell it not to, so
|
||||
I'm freeing them here to reduce memory consumption (and prevent
|
||||
|
@ -225,33 +241,32 @@ no_xshm:
|
|||
wi->sx != awindow->xframe.size.width ||
|
||||
wi->sy != awindow->xframe.size.height)
|
||||
{
|
||||
wi->sx = wi->window->xframe.size.width;
|
||||
/* printf("%@ updating image for %p (%gx%g)\n", wi, wi->window,
|
||||
wi->window->xframe.size.width, wi->window->xframe.size.height);*/
|
||||
/* printf("%@ updating image for %p (%gx%g)\n", wi, wi->window,
|
||||
wi->window->xframe.size.width, wi->window->xframe.size.height);*/
|
||||
if (wi->ximage)
|
||||
{
|
||||
if (wi->use_shm)
|
||||
{
|
||||
XShmDetach(wi->display, &wi->shminfo);
|
||||
XDestroyImage(wi->ximage);
|
||||
shmdt(wi->shminfo.shmaddr);
|
||||
}
|
||||
else
|
||||
XDestroyImage(wi->ximage);
|
||||
}
|
||||
{
|
||||
if (wi->use_shm)
|
||||
{
|
||||
XShmDetach(wi->display, &wi->shminfo);
|
||||
XDestroyImage(wi->ximage);
|
||||
shmdt(wi->shminfo.shmaddr);
|
||||
}
|
||||
else
|
||||
XDestroyImage(wi->ximage);
|
||||
}
|
||||
if (wi->pixmap)
|
||||
{
|
||||
XFreePixmap(wi->display,wi->pixmap);
|
||||
XSetWindowBackground(wi->display,wi->window->ident,None);
|
||||
wi->pixmap=0;
|
||||
}
|
||||
{
|
||||
XFreePixmap(wi->display,wi->pixmap);
|
||||
XSetWindowBackground(wi->display,wi->window->ident,None);
|
||||
wi->pixmap=0;
|
||||
}
|
||||
|
||||
wi->has_alpha = 0;
|
||||
if (wi->alpha)
|
||||
{
|
||||
free(wi->alpha);
|
||||
wi->alpha = NULL;
|
||||
}
|
||||
{
|
||||
free(wi->alpha);
|
||||
wi->alpha = NULL;
|
||||
}
|
||||
|
||||
wi->pending_put = wi->pending_event = 0;
|
||||
|
||||
|
@ -269,73 +284,72 @@ no_xshm:
|
|||
goto no_xshm;
|
||||
|
||||
if (!did_test_xshm)
|
||||
test_xshm(wi->display, aDI->drawing_depth);
|
||||
test_xshm(wi->display, visual, drawing_depth);
|
||||
|
||||
if (!use_xshm)
|
||||
goto no_xshm;
|
||||
|
||||
/* Use XShm if possible, else fall back to normal XImage: s */
|
||||
wi->use_shm = 1;
|
||||
wi->ximage = XShmCreateImage(wi->display,
|
||||
DefaultVisual(wi->display, DefaultScreen(wi->display)),
|
||||
aDI->drawing_depth, ZPixmap, NULL, &wi->shminfo,
|
||||
wi->window->xframe.size.width,
|
||||
wi->window->xframe.size.height);
|
||||
wi->ximage = XShmCreateImage(wi->display, visual,
|
||||
drawing_depth, ZPixmap, NULL, &wi->shminfo,
|
||||
wi->window->xframe.size.width,
|
||||
wi->window->xframe.size.height);
|
||||
if (!wi->ximage)
|
||||
{
|
||||
NSLog(@"Warning: XShmCreateImage failed!");
|
||||
NSLog(xshm_warning);
|
||||
goto no_xshm;
|
||||
}
|
||||
{
|
||||
NSLog(@"Warning: XShmCreateImage failed!");
|
||||
NSLog(xshm_warning);
|
||||
goto no_xshm;
|
||||
}
|
||||
wi->shminfo.shmid = shmget(IPC_PRIVATE,
|
||||
wi->ximage->bytes_per_line * wi->ximage->height,
|
||||
IPC_CREAT | 0700);
|
||||
wi->ximage->bytes_per_line * wi->ximage->height,
|
||||
IPC_CREAT | 0700);
|
||||
|
||||
if (wi->shminfo.shmid == -1)
|
||||
{
|
||||
NSLog(@"Warning: shmget() failed: %m.");
|
||||
NSLog(xshm_warning);
|
||||
XDestroyImage(wi->ximage);
|
||||
goto no_xshm;
|
||||
}
|
||||
{
|
||||
NSLog(@"Warning: shmget() failed: %m.");
|
||||
NSLog(xshm_warning);
|
||||
XDestroyImage(wi->ximage);
|
||||
goto no_xshm;
|
||||
}
|
||||
|
||||
wi->shminfo.shmaddr = wi->ximage->data = shmat(wi->shminfo.shmid, 0, 0);
|
||||
if ((intptr_t)wi->shminfo.shmaddr == -1)
|
||||
{
|
||||
NSLog(@"Warning: shmat() failed: %m.");
|
||||
NSLog(xshm_warning);
|
||||
XDestroyImage(wi->ximage);
|
||||
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
||||
goto no_xshm;
|
||||
}
|
||||
{
|
||||
NSLog(@"Warning: shmat() failed: %m.");
|
||||
NSLog(xshm_warning);
|
||||
XDestroyImage(wi->ximage);
|
||||
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
||||
goto no_xshm;
|
||||
}
|
||||
|
||||
wi->shminfo.readOnly = 0;
|
||||
if (!XShmAttach(wi->display, &wi->shminfo))
|
||||
{
|
||||
NSLog(@"Warning: XShmAttach() failed.");
|
||||
NSLog(xshm_warning);
|
||||
XDestroyImage(wi->ximage);
|
||||
shmdt(wi->shminfo.shmaddr);
|
||||
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
||||
goto no_xshm;
|
||||
}
|
||||
{
|
||||
NSLog(@"Warning: XShmAttach() failed.");
|
||||
NSLog(xshm_warning);
|
||||
XDestroyImage(wi->ximage);
|
||||
shmdt(wi->shminfo.shmaddr);
|
||||
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
||||
goto no_xshm;
|
||||
}
|
||||
|
||||
/* We try to create a shared pixmap using the same buffer, and set
|
||||
it as the background of the window. This allows X to handle expose
|
||||
events all by itself, which avoids white flashing when things are
|
||||
dragged across a window. */
|
||||
it as the background of the window. This allows X to handle expose
|
||||
events all by itself, which avoids white flashing when things are
|
||||
dragged across a window. */
|
||||
/* TODO: we still get and handle expose events, although we don't
|
||||
need to. */
|
||||
need to. */
|
||||
wi->pixmap = XShmCreatePixmap(wi->display, wi->drawable,
|
||||
wi->ximage->data, &wi->shminfo,
|
||||
wi->window->xframe.size.width,
|
||||
wi->window->xframe.size.height,
|
||||
aDI->drawing_depth);
|
||||
wi->ximage->data, &wi->shminfo,
|
||||
wi->window->xframe.size.width,
|
||||
wi->window->xframe.size.height,
|
||||
drawing_depth);
|
||||
if (wi->pixmap) /* TODO: this doesn't work */
|
||||
{
|
||||
XSetWindowBackgroundPixmap(wi->display, wi->window->ident,
|
||||
wi->pixmap);
|
||||
}
|
||||
{
|
||||
XSetWindowBackgroundPixmap(wi->display, wi->window->ident,
|
||||
wi->pixmap);
|
||||
}
|
||||
|
||||
/* On some systems (eg. freebsd), X can't attach to the shared segment
|
||||
if it's marked for destruction, so we make sure it's attached before
|
||||
|
@ -348,24 +362,25 @@ no_xshm:
|
|||
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
||||
|
||||
if (!wi->ximage)
|
||||
{
|
||||
{
|
||||
no_xshm:
|
||||
wi->use_shm = 0;
|
||||
wi->ximage = XCreateImage(wi->display, DefaultVisual(wi->display,
|
||||
DefaultScreen(wi->display)), aDI->drawing_depth, ZPixmap, 0, NULL,
|
||||
wi->window->xframe.size.width, wi->window->xframe.size.height,
|
||||
8, 0);
|
||||
wi->use_shm = 0;
|
||||
wi->ximage = XCreateImage(wi->display, visual, drawing_depth,
|
||||
ZPixmap, 0, NULL,
|
||||
wi->window->xframe.size.width,
|
||||
wi->window->xframe.size.height,
|
||||
8, 0);
|
||||
|
||||
wi->ximage->data = malloc(wi->ximage->height * wi->ximage->bytes_per_line);
|
||||
if (!wi->ximage->data)
|
||||
{
|
||||
XDestroyImage(wi->ximage);
|
||||
wi->ximage = NULL;
|
||||
}
|
||||
/*TODO? wi->ximage = XGetImage(wi->display, wi->drawable,
|
||||
0, 0, wi->window->xframe.size.width, wi->window->xframe.size.height,
|
||||
-1, ZPixmap);*/
|
||||
}
|
||||
wi->ximage->data = malloc(wi->ximage->height * wi->ximage->bytes_per_line);
|
||||
if (!wi->ximage->data)
|
||||
{
|
||||
XDestroyImage(wi->ximage);
|
||||
wi->ximage = NULL;
|
||||
}
|
||||
/*TODO? wi->ximage = XGetImage(wi->display, wi->drawable,
|
||||
0, 0, wi->window->xframe.size.width, wi->window->xframe.size.height,
|
||||
-1, ZPixmap);*/
|
||||
}
|
||||
}
|
||||
|
||||
if (wi->ximage)
|
||||
|
@ -376,7 +391,7 @@ no_xshm:
|
|||
wi->bytes_per_line = wi->ximage->bytes_per_line;
|
||||
wi->bits_per_pixel = wi->ximage->bits_per_pixel;
|
||||
wi->bytes_per_pixel = wi->bits_per_pixel / 8;
|
||||
// NSLog(@"%@ ximage=%p data=%p\n", wi->ximage, wi->data);
|
||||
// NSLog(@"%@ ximage=%p data=%p\n", wi->ximage, wi->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -400,31 +415,31 @@ extern int XShmGetEventBase(Display *d);
|
|||
{
|
||||
pending_put = 0;
|
||||
if (pending_rect.x + pending_rect.w > window->xframe.size.width)
|
||||
{
|
||||
pending_rect.w = window->xframe.size.width - pending_rect.x;
|
||||
if (pending_rect.w <= 0)
|
||||
return;
|
||||
}
|
||||
{
|
||||
pending_rect.w = window->xframe.size.width - pending_rect.x;
|
||||
if (pending_rect.w <= 0)
|
||||
return;
|
||||
}
|
||||
if (pending_rect.y + pending_rect.h > window->xframe.size.height)
|
||||
{
|
||||
pending_rect.h = window->xframe.size.height - pending_rect.y;
|
||||
if (pending_rect.h <= 0)
|
||||
return;
|
||||
}
|
||||
{
|
||||
pending_rect.h = window->xframe.size.height - pending_rect.y;
|
||||
if (pending_rect.h <= 0)
|
||||
return;
|
||||
}
|
||||
if (!XShmPutImage(display, drawable, gc, ximage,
|
||||
pending_rect.x, pending_rect.y,
|
||||
pending_rect.x, pending_rect.y,
|
||||
pending_rect.w, pending_rect.h,
|
||||
1))
|
||||
{
|
||||
NSLog(@"XShmPutImage failed?");
|
||||
}
|
||||
pending_rect.x, pending_rect.y,
|
||||
pending_rect.x, pending_rect.y,
|
||||
pending_rect.w, pending_rect.h,
|
||||
1))
|
||||
{
|
||||
NSLog(@"XShmPutImage failed?");
|
||||
}
|
||||
else
|
||||
{
|
||||
pending_event = 1;
|
||||
}
|
||||
{
|
||||
pending_event = 1;
|
||||
}
|
||||
}
|
||||
// XFlush(window->display);
|
||||
// XFlush(window->display);
|
||||
}
|
||||
|
||||
- (void) _exposeRect: (NSRect)rect
|
||||
|
@ -476,138 +491,138 @@ accuracy, we do the test using int: s.
|
|||
{
|
||||
|
||||
/* HACK: lets try to use shaped windows to get some use out of
|
||||
destination alpha */
|
||||
destination alpha */
|
||||
if (has_alpha && use_shape_hack)
|
||||
{
|
||||
{
|
||||
static int warn = 0;
|
||||
Pixmap p;
|
||||
int dsize = ((sx + 7) / 8) * sy;
|
||||
unsigned char *buf = malloc(dsize);
|
||||
unsigned char *dst;
|
||||
int bofs;
|
||||
unsigned char *a;
|
||||
int as;
|
||||
int i, x;
|
||||
Pixmap p;
|
||||
int dsize = ((sx + 7) / 8) * sy;
|
||||
unsigned char *buf = malloc(dsize);
|
||||
unsigned char *dst;
|
||||
int bofs;
|
||||
unsigned char *a;
|
||||
int as;
|
||||
int i, x;
|
||||
|
||||
if (!warn)
|
||||
NSLog(@"Warning: activating shaped windows");
|
||||
warn = 1;
|
||||
if (!warn)
|
||||
NSLog(@"Warning: activating shaped windows");
|
||||
warn = 1;
|
||||
|
||||
memset(buf, 0xff, dsize);
|
||||
memset(buf, 0xff, dsize);
|
||||
|
||||
#define CUTOFF 128
|
||||
|
||||
if (DI.inline_alpha)
|
||||
{
|
||||
a = data + DI.inline_alpha_ofs;
|
||||
as = DI.bytes_per_pixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = alpha;
|
||||
as = 1;
|
||||
}
|
||||
if (DI.inline_alpha)
|
||||
{
|
||||
a = data + DI.inline_alpha_ofs;
|
||||
as = DI.bytes_per_pixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = alpha;
|
||||
as = 1;
|
||||
}
|
||||
|
||||
for (bofs = 0, i = sx * sy, x = sx, dst = buf; i; i--, a += as)
|
||||
{
|
||||
if (*a < CUTOFF)
|
||||
{
|
||||
*dst = *dst & ~(1 << bofs);
|
||||
}
|
||||
bofs++;
|
||||
if (bofs == 8)
|
||||
{
|
||||
dst++;
|
||||
bofs = 0;
|
||||
}
|
||||
x--;
|
||||
if (!x)
|
||||
{
|
||||
if (bofs)
|
||||
{
|
||||
bofs = 0;
|
||||
dst++;
|
||||
}
|
||||
x = sx;
|
||||
}
|
||||
}
|
||||
for (bofs = 0, i = sx * sy, x = sx, dst = buf; i; i--, a += as)
|
||||
{
|
||||
if (*a < CUTOFF)
|
||||
{
|
||||
*dst = *dst & ~(1 << bofs);
|
||||
}
|
||||
bofs++;
|
||||
if (bofs == 8)
|
||||
{
|
||||
dst++;
|
||||
bofs = 0;
|
||||
}
|
||||
x--;
|
||||
if (!x)
|
||||
{
|
||||
if (bofs)
|
||||
{
|
||||
bofs = 0;
|
||||
dst++;
|
||||
}
|
||||
x = sx;
|
||||
}
|
||||
}
|
||||
#undef CUTOFF
|
||||
//NSLog(@"check shape");
|
||||
if (old_shape_size == dsize && !memcmp(old_shape, buf, dsize))
|
||||
{
|
||||
free(buf);
|
||||
// NSLog(@" same shape");
|
||||
}
|
||||
else
|
||||
{
|
||||
// NSLog(@" updating");
|
||||
p = XCreatePixmapFromBitmapData(display, window->ident,
|
||||
(char *)buf, sx, sy, 1, 0, 1);
|
||||
free(old_shape);
|
||||
old_shape = buf;
|
||||
old_shape_size = dsize;
|
||||
XShapeCombineMask(display, window->ident,
|
||||
ShapeBounding, 0, 0, p, ShapeSet);
|
||||
XFreePixmap(display, p);
|
||||
}
|
||||
}
|
||||
if (old_shape_size == dsize && !memcmp(old_shape, buf, dsize))
|
||||
{
|
||||
free(buf);
|
||||
// NSLog(@" same shape");
|
||||
}
|
||||
else
|
||||
{
|
||||
// NSLog(@" updating");
|
||||
p = XCreatePixmapFromBitmapData(display, window->ident,
|
||||
(char *)buf, sx, sy, 1, 0, 1);
|
||||
free(old_shape);
|
||||
old_shape = buf;
|
||||
old_shape_size = dsize;
|
||||
XShapeCombineMask(display, window->ident,
|
||||
ShapeBounding, 0, 0, p, ShapeSet);
|
||||
XFreePixmap(display, p);
|
||||
}
|
||||
}
|
||||
|
||||
if (pending_event)
|
||||
{
|
||||
if (!pending_put)
|
||||
{
|
||||
pending_put = 1;
|
||||
pending_rect.x = x;
|
||||
pending_rect.y = y;
|
||||
pending_rect.w = w;
|
||||
pending_rect.h = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x < pending_rect.x)
|
||||
{
|
||||
pending_rect.w += pending_rect.x - x;
|
||||
pending_rect.x = x;
|
||||
}
|
||||
if (x + w > pending_rect.x + pending_rect.w)
|
||||
{
|
||||
pending_rect.w = x + w - pending_rect.x;
|
||||
}
|
||||
if (y < pending_rect.y)
|
||||
{
|
||||
pending_rect.h += pending_rect.y - y;
|
||||
pending_rect.y = y;
|
||||
}
|
||||
if (y + h > pending_rect.y + pending_rect.h)
|
||||
{
|
||||
pending_rect.h = y + h - pending_rect.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
if (!pending_put)
|
||||
{
|
||||
pending_put = 1;
|
||||
pending_rect.x = x;
|
||||
pending_rect.y = y;
|
||||
pending_rect.w = w;
|
||||
pending_rect.h = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x < pending_rect.x)
|
||||
{
|
||||
pending_rect.w += pending_rect.x - x;
|
||||
pending_rect.x = x;
|
||||
}
|
||||
if (x + w > pending_rect.x + pending_rect.w)
|
||||
{
|
||||
pending_rect.w = x + w - pending_rect.x;
|
||||
}
|
||||
if (y < pending_rect.y)
|
||||
{
|
||||
pending_rect.h += pending_rect.y - y;
|
||||
pending_rect.y = y;
|
||||
}
|
||||
if (y + h > pending_rect.y + pending_rect.h)
|
||||
{
|
||||
pending_rect.h = y + h - pending_rect.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pending_put = 0;
|
||||
if (!XShmPutImage(display, drawable, gc, ximage,
|
||||
x, y, x, y, w, h, 1))
|
||||
{
|
||||
NSLog(@"XShmPutImage failed?");
|
||||
}
|
||||
else
|
||||
{
|
||||
pending_event = 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
pending_put = 0;
|
||||
if (!XShmPutImage(display, drawable, gc, ximage,
|
||||
x, y, x, y, w, h, 1))
|
||||
{
|
||||
NSLog(@"XShmPutImage failed?");
|
||||
}
|
||||
else
|
||||
{
|
||||
pending_event = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Performance hack. Check right away for ShmCompletion
|
||||
events. */
|
||||
events. */
|
||||
{
|
||||
XEvent e;
|
||||
XEvent e;
|
||||
|
||||
while (XCheckTypedEvent(window->display,
|
||||
XShmGetEventBase(window->display) + ShmCompletion, &e))
|
||||
{
|
||||
[isa _gotShmCompletion: ((XShmCompletionEvent *)&e)->drawable];
|
||||
}
|
||||
while (XCheckTypedEvent(window->display,
|
||||
XShmGetEventBase(window->display) + ShmCompletion, &e))
|
||||
{
|
||||
[isa _gotShmCompletion: ((XShmCompletionEvent *)&e)->drawable];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ximage)
|
||||
|
@ -624,7 +639,7 @@ static int warn = 0;
|
|||
if (!data)
|
||||
return;
|
||||
|
||||
// NSLog(@"needs alpha for %p: %ix%i", self, sx, sy);
|
||||
// NSLog(@"needs alpha for %p: %ix%i", self, sx, sy);
|
||||
|
||||
if (DI.inline_alpha)
|
||||
{
|
||||
|
@ -634,8 +649,8 @@ static int warn = 0;
|
|||
has_alpha = 1;
|
||||
/* fill the alpha channel */
|
||||
for (i = 0, s = data + DI.inline_alpha_ofs; i < sx * sy;
|
||||
i++, s += DI.bytes_per_pixel)
|
||||
*s = 0xff;
|
||||
i++, s += DI.bytes_per_pixel)
|
||||
*s = 0xff;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -646,7 +661,7 @@ static int warn = 0;
|
|||
return;
|
||||
}
|
||||
|
||||
// NSLog(@"got buffer at %p", alpha);
|
||||
// NSLog(@"got buffer at %p", alpha);
|
||||
|
||||
has_alpha = 1;
|
||||
memset(alpha, 0xff, sx * sy);
|
||||
|
@ -662,25 +677,25 @@ static int warn = 0;
|
|||
{
|
||||
num_window_buffers--;
|
||||
for (; i < num_window_buffers; i++)
|
||||
window_buffers[i] = window_buffers[i + 1];
|
||||
window_buffers[i] = window_buffers[i + 1];
|
||||
}
|
||||
|
||||
if (ximage)
|
||||
{
|
||||
if (pixmap)
|
||||
{
|
||||
XFreePixmap(display,pixmap);
|
||||
pixmap=0;
|
||||
}
|
||||
{
|
||||
XFreePixmap(display,pixmap);
|
||||
pixmap=0;
|
||||
}
|
||||
|
||||
if (use_shm)
|
||||
{
|
||||
XShmDetach(display, &shminfo);
|
||||
XDestroyImage(ximage);
|
||||
shmdt(shminfo.shmaddr);
|
||||
}
|
||||
{
|
||||
XShmDetach(display, &shminfo);
|
||||
XDestroyImage(ximage);
|
||||
shmdt(shminfo.shmaddr);
|
||||
}
|
||||
else
|
||||
XDestroyImage(ximage);
|
||||
XDestroyImage(ximage);
|
||||
}
|
||||
if (alpha)
|
||||
free(alpha);
|
||||
|
@ -688,23 +703,16 @@ static int warn = 0;
|
|||
}
|
||||
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
use_shape_hack = [ud boolForKey: @"XWindowBuffer-shape-hack"];
|
||||
}
|
||||
|
||||
|
||||
+ (void) _gotShmCompletion: (Drawable)d
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < num_window_buffers; i++)
|
||||
{
|
||||
if (window_buffers[i]->drawable == d)
|
||||
{
|
||||
[window_buffers[i] _gotShmCompletion];
|
||||
return;
|
||||
}
|
||||
{
|
||||
[window_buffers[i] _gotShmCompletion];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue