mirror of
https://github.com/gnustep/libs-back.git
synced 2025-05-31 01:11:00 +00:00
2004-11-10 18:41 Alexander Malmberg <alexander@malmberg.org>
* Source/x11/XWindowBuffer.m (test_xshm): New function. (test_xshm_error_handler): New function. (+windowBufferForWindow:depthInfo:): Move XShm detection code to test_xshm and use it to decide whether to use XShm or not. (+initialize): Move use_xshm setting code to test_xshm. (+_gotShmCompletion:): Don't warn if we can't find an XWindowBuffer for the event. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@20338 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
c158657a9d
commit
af541a19a0
2 changed files with 143 additions and 26 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2004-11-10 18:41 Alexander Malmberg <alexander@malmberg.org>
|
||||||
|
|
||||||
|
* Source/x11/XWindowBuffer.m (test_xshm): New function.
|
||||||
|
(test_xshm_error_handler): New function.
|
||||||
|
(+windowBufferForWindow:depthInfo:): Move XShm detection code
|
||||||
|
to test_xshm and use it to decide whether to use XShm or not.
|
||||||
|
(+initialize): Move use_xshm setting code to test_xshm.
|
||||||
|
(+_gotShmCompletion:): Don't warn if we can't find an XWindowBuffer
|
||||||
|
for the event.
|
||||||
|
|
||||||
2004-11-10 Matt Rice <ratmice@yahoo.com>
|
2004-11-10 Matt Rice <ratmice@yahoo.com>
|
||||||
|
|
||||||
* Source/x11/XGServerWindow.m (-iconSize): Implement new method.
|
* Source/x11/XGServerWindow.m (-iconSize): Implement new method.
|
||||||
|
|
|
@ -41,8 +41,121 @@ static int num_window_buffers;
|
||||||
|
|
||||||
static int use_shape_hack = 0; /* this is an ugly hack :) */
|
static int use_shape_hack = 0; /* this is an ugly hack :) */
|
||||||
|
|
||||||
static int use_xshm = 1;
|
|
||||||
|
|
||||||
|
static int did_test_xshm = 0;
|
||||||
|
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).";
|
||||||
|
|
||||||
|
static int test_xshm_error_handler(Display *d, XErrorEvent *ev)
|
||||||
|
{
|
||||||
|
num_xshm_test_errors++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_xshm(Display *display, int drawing_depth)
|
||||||
|
{
|
||||||
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||||
|
|
||||||
|
did_test_xshm = 1;
|
||||||
|
|
||||||
|
if ([ud objectForKey: @"XWindowBufferUseXShm"])
|
||||||
|
use_xshm = [ud boolForKey: @"XWindowBufferUseXShm"];
|
||||||
|
|
||||||
|
/* If the user doesn't want XShm, there's no point in doing any further
|
||||||
|
testing. */
|
||||||
|
if (!use_xshm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* This seems to return success if the X server understands the XShm
|
||||||
|
protocol, regardless of whether XShm can actually be used or not... */
|
||||||
|
if (!XShmQueryExtension(display))
|
||||||
|
{
|
||||||
|
NSLog(@"XShm not supported by X server.");
|
||||||
|
NSLog(xshm_warning);
|
||||||
|
use_xshm = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ... so we check that it actually works here. To do this, we need to
|
||||||
|
set up our own error handler (because the xlib calls never fail, they
|
||||||
|
just cause error events to be sent to us), explicitly synchronize
|
||||||
|
(or we wouldn't get to handle, and thus detect, the errors until much
|
||||||
|
later), and try actually creating a XShm image. Yuck. */
|
||||||
|
{
|
||||||
|
XImage *ximage;
|
||||||
|
XShmSegmentInfo shminfo;
|
||||||
|
int (*old_error_handler)();
|
||||||
|
|
||||||
|
old_error_handler = XSetErrorHandler(test_xshm_error_handler);
|
||||||
|
|
||||||
|
ximage = XShmCreateImage(display,
|
||||||
|
DefaultVisual(display, DefaultScreen(display)),
|
||||||
|
drawing_depth, ZPixmap, NULL, &shminfo,
|
||||||
|
1, 1);
|
||||||
|
if (!ximage || num_xshm_test_errors)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (shminfo.shmid == -1 || num_xshm_test_errors)
|
||||||
|
{
|
||||||
|
NSLog(@"XShm not supported, shmget() failed: %m.");
|
||||||
|
XDestroyImage(ximage);
|
||||||
|
goto no_xshm;
|
||||||
|
}
|
||||||
|
|
||||||
|
shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
|
||||||
|
if ((int)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;
|
||||||
|
}
|
||||||
|
|
||||||
|
shminfo.readOnly = 0;
|
||||||
|
if (!XShmAttach(display, &shminfo) || num_xshm_test_errors)
|
||||||
|
{
|
||||||
|
NSLog(@"XShm not supported, XShmAttach() failed.");
|
||||||
|
XDestroyImage(ximage);
|
||||||
|
shmdt(shminfo.shmaddr);
|
||||||
|
shmctl(shminfo.shmid, IPC_RMID, 0);
|
||||||
|
goto no_xshm;
|
||||||
|
}
|
||||||
|
|
||||||
|
XShmDetach(display, &shminfo);
|
||||||
|
XDestroyImage(ximage);
|
||||||
|
shmdt(shminfo.shmaddr);
|
||||||
|
|
||||||
|
/* Most of the time, all the above calls will return success despite
|
||||||
|
actually failing. To catch all errors generated by the calls before
|
||||||
|
returning, we synchronize here. */
|
||||||
|
XSync(display, False);
|
||||||
|
|
||||||
|
shmctl(shminfo.shmid, IPC_RMID, 0);
|
||||||
|
|
||||||
|
if (num_xshm_test_errors)
|
||||||
|
{
|
||||||
|
NSLog(@"XShm not supported.");
|
||||||
|
no_xshm:
|
||||||
|
NSLog(xshm_warning);
|
||||||
|
use_xshm = 0;
|
||||||
|
}
|
||||||
|
XSetErrorHandler(old_error_handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@implementation XWindowBuffer
|
@implementation XWindowBuffer
|
||||||
|
@ -149,20 +262,13 @@ static int use_xshm = 1;
|
||||||
if (wi->window->xframe.size.width * wi->window->xframe.size.height < 4096)
|
if (wi->window->xframe.size.width * wi->window->xframe.size.height < 4096)
|
||||||
goto no_xshm;
|
goto no_xshm;
|
||||||
|
|
||||||
#define WARN @" Falling back to normal XImage:s (will be slower)."
|
if (!did_test_xshm)
|
||||||
|
test_xshm(wi->display, aDI->drawing_depth);
|
||||||
|
|
||||||
if (!use_xshm)
|
if (!use_xshm)
|
||||||
goto no_xshm;
|
goto no_xshm;
|
||||||
|
|
||||||
/* Use XShm if possible, else fall back to normal XImage:s */
|
/* Use XShm if possible, else fall back to normal XImage:s */
|
||||||
if (!XShmQueryExtension(wi->display))
|
|
||||||
{
|
|
||||||
static BOOL xshm_warned = NO;
|
|
||||||
if (!xshm_warned)
|
|
||||||
NSLog(@"XShm not supported." WARN);
|
|
||||||
xshm_warned = YES;
|
|
||||||
goto no_xshm;
|
|
||||||
}
|
|
||||||
|
|
||||||
wi->use_shm = 1;
|
wi->use_shm = 1;
|
||||||
wi->ximage = XShmCreateImage(wi->display,
|
wi->ximage = XShmCreateImage(wi->display,
|
||||||
DefaultVisual(wi->display, DefaultScreen(wi->display)),
|
DefaultVisual(wi->display, DefaultScreen(wi->display)),
|
||||||
|
@ -171,7 +277,8 @@ static BOOL xshm_warned = NO;
|
||||||
wi->window->xframe.size.height);
|
wi->window->xframe.size.height);
|
||||||
if (!wi->ximage)
|
if (!wi->ximage)
|
||||||
{
|
{
|
||||||
NSLog(@"Warning: XShmCreateImage failed!" WARN);
|
NSLog(@"Warning: XShmCreateImage failed!");
|
||||||
|
NSLog(xshm_warning);
|
||||||
goto no_xshm;
|
goto no_xshm;
|
||||||
}
|
}
|
||||||
wi->shminfo.shmid = shmget(IPC_PRIVATE,
|
wi->shminfo.shmid = shmget(IPC_PRIVATE,
|
||||||
|
@ -180,7 +287,8 @@ static BOOL xshm_warned = NO;
|
||||||
|
|
||||||
if (wi->shminfo.shmid == -1)
|
if (wi->shminfo.shmid == -1)
|
||||||
{
|
{
|
||||||
NSLog(@"Warning: shmget() failed: %m." WARN);
|
NSLog(@"Warning: shmget() failed: %m.");
|
||||||
|
NSLog(xshm_warning);
|
||||||
XDestroyImage(wi->ximage);
|
XDestroyImage(wi->ximage);
|
||||||
goto no_xshm;
|
goto no_xshm;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +296,8 @@ static BOOL xshm_warned = NO;
|
||||||
wi->shminfo.shmaddr = wi->ximage->data = shmat(wi->shminfo.shmid, 0, 0);
|
wi->shminfo.shmaddr = wi->ximage->data = shmat(wi->shminfo.shmid, 0, 0);
|
||||||
if ((int)wi->shminfo.shmaddr == -1)
|
if ((int)wi->shminfo.shmaddr == -1)
|
||||||
{
|
{
|
||||||
NSLog(@"Warning: shmat() failed: %m." WARN);
|
NSLog(@"Warning: shmat() failed: %m.");
|
||||||
|
NSLog(xshm_warning);
|
||||||
XDestroyImage(wi->ximage);
|
XDestroyImage(wi->ximage);
|
||||||
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
||||||
goto no_xshm;
|
goto no_xshm;
|
||||||
|
@ -197,7 +306,8 @@ static BOOL xshm_warned = NO;
|
||||||
wi->shminfo.readOnly = 0;
|
wi->shminfo.readOnly = 0;
|
||||||
if (!XShmAttach(wi->display, &wi->shminfo))
|
if (!XShmAttach(wi->display, &wi->shminfo))
|
||||||
{
|
{
|
||||||
NSLog(@"Warning: XShmAttach() failed." WARN);
|
NSLog(@"Warning: XShmAttach() failed.");
|
||||||
|
NSLog(xshm_warning);
|
||||||
XDestroyImage(wi->ximage);
|
XDestroyImage(wi->ximage);
|
||||||
shmdt(wi->shminfo.shmaddr);
|
shmdt(wi->shminfo.shmaddr);
|
||||||
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
||||||
|
@ -210,20 +320,21 @@ static BOOL xshm_warned = NO;
|
||||||
dragged across a window. */
|
dragged across a window. */
|
||||||
/* TODO: we still get and handle expose events, although we don't
|
/* TODO: we still get and handle expose events, although we don't
|
||||||
need to. */
|
need to. */
|
||||||
wi->pixmap=XShmCreatePixmap(wi->display,wi->drawable,
|
wi->pixmap = XShmCreatePixmap(wi->display, wi->drawable,
|
||||||
wi->ximage->data,&wi->shminfo,
|
wi->ximage->data, &wi->shminfo,
|
||||||
wi->window->xframe.size.width,
|
wi->window->xframe.size.width,
|
||||||
wi->window->xframe.size.height,
|
wi->window->xframe.size.height,
|
||||||
aDI->drawing_depth);
|
aDI->drawing_depth);
|
||||||
if (wi->pixmap) /* TODO: this doesn't work */
|
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
|
/* 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
|
if it's marked for destruction, so we make sure it's attached before
|
||||||
marking it. */
|
marking it. */
|
||||||
XSync(wi->display,False);
|
XSync(wi->display, False);
|
||||||
|
|
||||||
/* Mark the segment as destroyed now. Since we're attached, it won't
|
/* Mark the segment as destroyed now. Since we're attached, it won't
|
||||||
actually be destroyed, but if we crashed before doing this, it wouldn't
|
actually be destroyed, but if we crashed before doing this, it wouldn't
|
||||||
|
@ -541,9 +652,6 @@ static int warn = 0;
|
||||||
{
|
{
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||||
use_shape_hack = [ud boolForKey: @"XWindowBuffer-shape-hack"];
|
use_shape_hack = [ud boolForKey: @"XWindowBuffer-shape-hack"];
|
||||||
|
|
||||||
if ([ud objectForKey: @"XWindowBufferUseXShm"])
|
|
||||||
use_xshm = [ud boolForKey: @"XWindowBufferUseXShm"];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -558,7 +666,6 @@ static int warn = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NSLog(@"Warning: gotShmCompletion: couldn't find XWindowBuffer for drawable");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue