mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-23 16:10:52 +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
e71ab02698
commit
34d406f5d9
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>
|
||||
|
||||
* 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_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
|
||||
|
@ -149,20 +262,13 @@ static int use_xshm = 1;
|
|||
if (wi->window->xframe.size.width * wi->window->xframe.size.height < 4096)
|
||||
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)
|
||||
goto no_xshm;
|
||||
|
||||
/* 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->ximage = XShmCreateImage(wi->display,
|
||||
DefaultVisual(wi->display, DefaultScreen(wi->display)),
|
||||
|
@ -171,7 +277,8 @@ static BOOL xshm_warned = NO;
|
|||
wi->window->xframe.size.height);
|
||||
if (!wi->ximage)
|
||||
{
|
||||
NSLog(@"Warning: XShmCreateImage failed!" WARN);
|
||||
NSLog(@"Warning: XShmCreateImage failed!");
|
||||
NSLog(xshm_warning);
|
||||
goto no_xshm;
|
||||
}
|
||||
wi->shminfo.shmid = shmget(IPC_PRIVATE,
|
||||
|
@ -180,7 +287,8 @@ static BOOL xshm_warned = NO;
|
|||
|
||||
if (wi->shminfo.shmid == -1)
|
||||
{
|
||||
NSLog(@"Warning: shmget() failed: %m." WARN);
|
||||
NSLog(@"Warning: shmget() failed: %m.");
|
||||
NSLog(xshm_warning);
|
||||
XDestroyImage(wi->ximage);
|
||||
goto no_xshm;
|
||||
}
|
||||
|
@ -188,7 +296,8 @@ static BOOL xshm_warned = NO;
|
|||
wi->shminfo.shmaddr = wi->ximage->data = shmat(wi->shminfo.shmid, 0, 0);
|
||||
if ((int)wi->shminfo.shmaddr == -1)
|
||||
{
|
||||
NSLog(@"Warning: shmat() failed: %m." WARN);
|
||||
NSLog(@"Warning: shmat() failed: %m.");
|
||||
NSLog(xshm_warning);
|
||||
XDestroyImage(wi->ximage);
|
||||
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
||||
goto no_xshm;
|
||||
|
@ -197,7 +306,8 @@ static BOOL xshm_warned = NO;
|
|||
wi->shminfo.readOnly = 0;
|
||||
if (!XShmAttach(wi->display, &wi->shminfo))
|
||||
{
|
||||
NSLog(@"Warning: XShmAttach() failed." WARN);
|
||||
NSLog(@"Warning: XShmAttach() failed.");
|
||||
NSLog(xshm_warning);
|
||||
XDestroyImage(wi->ximage);
|
||||
shmdt(wi->shminfo.shmaddr);
|
||||
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
|
||||
|
@ -210,20 +320,21 @@ static BOOL xshm_warned = NO;
|
|||
dragged across a window. */
|
||||
/* TODO: we still get and handle expose events, although we don't
|
||||
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->pixmap = XShmCreatePixmap(wi->display, wi->drawable,
|
||||
wi->ximage->data, &wi->shminfo,
|
||||
wi->window->xframe.size.width,
|
||||
wi->window->xframe.size.height,
|
||||
aDI->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
|
||||
marking it. */
|
||||
XSync(wi->display,False);
|
||||
XSync(wi->display, False);
|
||||
|
||||
/* 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
|
||||
|
@ -541,9 +652,6 @@ static int warn = 0;
|
|||
{
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
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;
|
||||
}
|
||||
}
|
||||
NSLog(@"Warning: gotShmCompletion: couldn't find XWindowBuffer for drawable");
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue