diff --git a/ChangeLog b/ChangeLog index d6d1c26..316ddc3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2002-09-10 21:36 Alexander Malmberg + + * Source/art/ARTWindowBuffer.h, Source/art/ARTWindowBuffer.m, + Source/x11/XWindowBuffer.m, Headers/x11/XWindowBuffer.h: Rename + ARTWindowBuffer to XWindowBuffer and move it to x11/ so other + backends can use it. Update many files in Source/art/. + 2002-09-10 17:35 Alexander Malmberg * Source/art/composite.m: Implement handling of tranformations and diff --git a/Source/art/ARTWindowBuffer.h b/Headers/x11/XWindowBuffer.h similarity index 67% rename from Source/art/ARTWindowBuffer.h rename to Headers/x11/XWindowBuffer.h index a273f4e..4367dc5 100644 --- a/Source/art/ARTWindowBuffer.h +++ b/Headers/x11/XWindowBuffer.h @@ -20,32 +20,33 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef ARTWindowBuffer_h -#define ARTWindowBuffer_h +#ifndef XWindowBuffer_h +#define XWindowBuffer_h #include + +struct XWindowBuffer_depth_info_s +{ + int drawing_depth; + int bytes_per_pixel; + BOOL inline_alpha; + int inline_alpha_ofs; +}; + /* -ARTWindowBuffer maintains an XImage for a window. Each ARTGState that -renders to that window uses the same WinImage (and thus the same buffer, -etc.). +XWindowBuffer maintains an XImage for a window. Each ARTGState that +renders to that window uses the same XWindowBuffer (and thus the same +buffer, etc.). Many states might render to the same window, so we need to make sure -that there's only one WinImage for each window. */ -@interface ARTWindowBuffer : NSObject +that there's only one XWindowBuffer for each window. */ +@interface XWindowBuffer : NSObject { @public -#ifdef RDS - int window; - RDSClient *remote; - - struct - { - int shmid; - char *shmaddr; - } shminfo; -#else gswindow_device_t *window; + +@private GC gc; Drawable drawable; XImage *ximage; @@ -53,7 +54,9 @@ that there's only one WinImage for each window. */ int use_shm; XShmSegmentInfo shminfo; -#endif + + + struct XWindowBuffer_depth_info_s DI; /* While a XShmPutImage is in progress we don't try to call it @@ -65,6 +68,11 @@ that there's only one WinImage for each window. */ int pending_event; /* We're waiting for the ShmCompletion event. */ + /* This is for the ugly shape-hack */ + unsigned char *old_shape; + int old_shape_size; + +@public unsigned char *data; int sx, sy; int bytes_per_line, bits_per_pixel, bytes_per_pixel; @@ -74,28 +82,25 @@ that there's only one WinImage for each window. */ it. */ unsigned char *alpha; int has_alpha; - - - unsigned char *old_shape; - int old_shape_size; } -#ifdef RDS -+ artWindowBufferForWindow: (int)awindow remote: (RDSClient *)remote; -#else -+ artWindowBufferForWindow: (gswindow_device_t *)awindow; -#endif +/* this returns a _retained_ object */ ++ windowBufferForWindow: (gswindow_device_t *)awindow + depthInfo: (struct XWindowBuffer_depth_info_s *)aDI; +/* +Note that alpha is _not_ guaranteed to exist after this has been called; +you still need to check has_alpha. If the call fails, a message will be +logged. + +(In ARTGState, I handle failures by simply ignoring the operation that +required alpha.) +*/ -(void) needsAlpha; -(void) _gotShmCompletion; -(void) _exposeRect: (NSRect)r; - -+(void) initializeBackendWithDrawInfo: (struct draw_info_s *)d; - -#ifndef RDS +(void) _gotShmCompletion: (Drawable)d; -#endif @end diff --git a/Source/art/ARTContext.m b/Source/art/ARTContext.m index a9d9038..d018a19 100644 --- a/Source/art/ARTContext.m +++ b/Source/art/ARTContext.m @@ -28,7 +28,7 @@ #include "ARTGState.h" -#include "ARTWindowBuffer.h" +#include "x11/XWindowBuffer.h" #include "blit.h" #include "ftfont.h" @@ -469,12 +469,8 @@ very expensive @interface ARTGState (internal_stuff) -#ifdef RDS --(void) _setup_stuff: (int)window : (RDSClient *)remote; -#else -(void) _setup_stuff: (gswindow_device_t *)win : (int)x : (int)y; -(void) GSCurrentDevice: (void **)device : (int *)x : (int *)y; -#endif @end @implementation ARTGState (internal_stuff) @@ -549,19 +545,27 @@ very expensive return self; } -#ifdef RDS --(void) _setup_stuff: (int)window : (RDSClient *)remote -{ - NSLog(@"_setup_stuff: %i : %p",window,remote); - DESTROY(wi); - wi=[ARTWindowBuffer artWindowBufferForWindow: window remote: remote]; -} -#else -(void) _setup_stuff: (gswindow_device_t *)window : (int)x : (int)y { + struct XWindowBuffer_depth_info_s di; + + XWindowBuffer *new_wi; [self setOffset: NSMakePoint(x, y)]; - DESTROY(wi); - wi=[ARTWindowBuffer artWindowBufferForWindow: window]; + + di.drawing_depth = DI.drawing_depth; + di.bytes_per_pixel = DI.bytes_per_pixel; + di.inline_alpha = DI.inline_alpha; + di.inline_alpha_ofs = DI.inline_alpha_ofs; + new_wi=[XWindowBuffer windowBufferForWindow: window depthInfo: &di]; + if (new_wi != wi) + { + DESTROY(wi); + wi=new_wi; + } + else + { + DESTROY(new_wi); + } } -(void) GSCurrentDevice: (void **)device : (int *)x : (int *)y @@ -579,8 +583,6 @@ very expensive } } -#endif - @end @@ -616,9 +618,6 @@ very expensive [gstate DPSsetalpha: 1.0]; [gstate DPSsetlinewidth: 1.0]; -#ifdef RDS - artcontext_setup_draw_info(&DI,0x000000ff,0x0000ff00,0x00ff0000,32); -#else { Display *d=[(XGServer *)server xDisplay]; Visual *v=DefaultVisual(d,DefaultScreen(d)); @@ -629,8 +628,6 @@ very expensive artcontext_setup_draw_info(&DI,v->red_mask,v->green_mask,v->blue_mask,bpp); } -#endif - [ARTWindowBuffer initializeBackendWithDrawInfo: &DI]; return self; } @@ -638,9 +635,7 @@ very expensive - (void) flushGraphics { /* TODO: _really_ flush? (ie. force updates and wait for shm completion?) */ -#ifndef RDS XFlush([(XGServer *)server xDisplay]); -#endif } +(void) waitAllContexts @@ -648,17 +643,15 @@ very expensive } -#ifndef RDS +(void) _gotShmCompletion: (Drawable)d { - [ARTWindowBuffer _gotShmCompletion: d]; + [XWindowBuffer _gotShmCompletion: d]; } -(void) gotShmCompletion: (Drawable)d { - [ARTWindowBuffer _gotShmCompletion: d]; + [XWindowBuffer _gotShmCompletion: d]; } -#endif // // Read the Color at a Screen Position @@ -671,29 +664,18 @@ very expensive - (void) beep { -#ifndef RDS XBell([(XGServer *)server xDisplay], 50); -#else -#warning TODO beep -#endif } /* Private backend methods */ +(void) handleExposeRect: (NSRect)rect forDriver: (void *)driver { - [(ARTWindowBuffer *)driver _exposeRect: rect]; + [(XWindowBuffer *)driver _exposeRect: rect]; } @end @implementation ARTContext (ops) -#ifdef RDS --(void) _rds_set_device: (int)window remote: (RDSClient *)remote -{ - NSLog(@"_rds_set_device: %i remote: %@",window,remote); - [(ARTGState *)gstate _setup_stuff: window : remote]; -} -#else - (void) GSSetDevice: (void*)device : (int)x : (int)y { [(ARTGState *)gstate _setup_stuff: device : x : y]; @@ -703,8 +685,5 @@ very expensive { [(ARTGState *)gstate GSCurrentDevice: device : x : y]; } - -#endif - @end diff --git a/Source/art/ARTGState.h b/Source/art/ARTGState.h index 8e62c5e..8073f52 100644 --- a/Source/art/ARTGState.h +++ b/Source/art/ARTGState.h @@ -37,7 +37,7 @@ #include -@class ARTWindowBuffer; +@class XWindowBuffer; @interface ARTGState : GSGState @@ -52,7 +52,7 @@ int do_dash; - ARTWindowBuffer *wi; + XWindowBuffer *wi; int clip_x0,clip_y0,clip_x1,clip_y1; BOOL all_clipped; diff --git a/Source/art/GNUmakefile b/Source/art/GNUmakefile index c21a4ab..d71863a 100644 --- a/Source/art/GNUmakefile +++ b/Source/art/GNUmakefile @@ -39,8 +39,9 @@ SUBPROJECT_NAME=art # The Objective-C source files to be compiled art_OBJC_FILES = \ - ARTContext.m blit.m ftfont.m \ - ARTWindowBuffer.m \ + ARTContext.m \ + blit.m \ + ftfont.m \ image.m \ composite.m \ path.m diff --git a/Source/art/composite.m b/Source/art/composite.m index cb8afcc..cda7adb 100644 --- a/Source/art/composite.m +++ b/Source/art/composite.m @@ -26,7 +26,7 @@ #include "ARTGState.h" -#include "ARTWindowBuffer.h" +#include "x11/XWindowBuffer.h" #include "blit.h" diff --git a/Source/art/image.m b/Source/art/image.m index b15d70e..23b70e5 100644 --- a/Source/art/image.m +++ b/Source/art/image.m @@ -31,7 +31,7 @@ Image drawing. DPSimage and helpers. #include "ARTGState.h" -#include "ARTWindowBuffer.h" +#include "x11/XWindowBuffer.h" #include "blit.h" diff --git a/Source/art/path.m b/Source/art/path.m index 69c67c1..bbdbaa6 100644 --- a/Source/art/path.m +++ b/Source/art/path.m @@ -31,7 +31,7 @@ Path handling. #include "ARTGState.h" -#include "ARTWindowBuffer.h" +#include "x11/XWindowBuffer.h" #include "blit.h" diff --git a/Source/x11/GNUmakefile b/Source/x11/GNUmakefile index 03850ab..9e267ab 100644 --- a/Source/x11/GNUmakefile +++ b/Source/x11/GNUmakefile @@ -61,7 +61,8 @@ XGServerWindow.m \ XGDragView.m \ XGSlideView.m \ XIMInputServer.m \ -XGBitmapImageRep.m +XGBitmapImageRep.m \ +XWindowBuffer.m x11_HEADER_FILES_DIR = ../../Headers/x11 x11_HEADER_FILES_INSTALL_DIR = gnustep/x11 diff --git a/Source/art/ARTWindowBuffer.m b/Source/x11/XWindowBuffer.m similarity index 67% rename from Source/art/ARTWindowBuffer.m rename to Source/x11/XWindowBuffer.m index 287dde4..af2f81f 100644 --- a/Source/art/ARTWindowBuffer.m +++ b/Source/x11/XWindowBuffer.m @@ -25,66 +25,57 @@ #include "x11/XGServer.h" #include "x11/XGServerWindow.h" -#include "gsc/GSContext.h" -#include "art/ARTContext.h" -#include "blit.h" - -#include "ARTWindowBuffer.h" +#include "x11/XWindowBuffer.h" #include #include -#ifndef RDS #include -#endif -static ARTWindowBuffer **art_window_buffers; -static int num_art_window_buffers; +static XWindowBuffer **window_buffers; +static int num_window_buffers; -static draw_info_t DI; - - -#ifndef RDS - static int use_shape_hack = 0; /* this is an ugly hack :) */ -@implementation ARTWindowBuffer +@implementation XWindowBuffer -+ artWindowBufferForWindow: (gswindow_device_t *)awindow ++ windowBufferForWindow: (gswindow_device_t *)awindow + depthInfo: (struct XWindowBuffer_depth_info_s *)aDI { int i; - ARTWindowBuffer *wi; + XWindowBuffer *wi; - for (i = 0; iwindow == awindow) + if (window_buffers[i]->window == awindow) break; } - if (i == num_art_window_buffers) + if (i == num_window_buffers) { - wi = [[ARTWindowBuffer alloc] init]; + wi = [[XWindowBuffer alloc] init]; wi->window = awindow; - art_window_buffers = realloc(art_window_buffers, - sizeof(ARTWindowBuffer *) * (num_art_window_buffers + 1)); - if (!art_window_buffers) + window_buffers = realloc(window_buffers, + sizeof(XWindowBuffer *) * (num_window_buffers + 1)); + if (!window_buffers) { NSLog(@"Out of memory (failed to allocate %i bytes)", - sizeof(ARTWindowBuffer *) * (num_art_window_buffers + 1)); + sizeof(XWindowBuffer *) * (num_window_buffers + 1)); exit(1); } - art_window_buffers[num_art_window_buffers++] = wi; + window_buffers[num_window_buffers++] = wi; } else { - wi = art_window_buffers[i]; + wi = window_buffers[i]; wi = RETAIN(wi); } + wi->DI = *aDI; wi->gc = awindow->gc; wi->drawable = awindow->ident; wi->display = awindow->display; @@ -143,7 +134,7 @@ static int use_shape_hack = 0; /* this is an ugly hack :) */ wi->use_shm = 1; wi->ximage = XShmCreateImage(wi->display, DefaultVisual(wi->display, DefaultScreen(wi->display)), - DI.drawing_depth, ZPixmap, NULL, &wi->shminfo, + aDI->drawing_depth, ZPixmap, NULL, &wi->shminfo, wi->window->xframe.size.width, wi->window->xframe.size.height); } @@ -179,7 +170,7 @@ static int use_shape_hack = 0; /* this is an ugly hack :) */ NSLog(@"failed to create shared memory image, using normal XImage:s"); wi->use_shm = 0; wi->ximage = XCreateImage(wi->display, DefaultVisual(wi->display, - DefaultScreen(wi->display)), DI.drawing_depth, ZPixmap, 0, NULL, + DefaultScreen(wi->display)), aDI->drawing_depth, ZPixmap, 0, NULL, wi->window->xframe.size.width, wi->window->xframe.size.height, 8, 0); @@ -189,7 +180,7 @@ static int use_shape_hack = 0; /* this is an ugly hack :) */ XDestroyImage(wi->ximage); wi->ximage = NULL; } -/*TODO? wi->ximage=XGetImage(wi->display, wi->drawable, +/*TODO? wi->ximage = XGetImage(wi->display, wi->drawable, 0, 0, wi->window->xframe.size.width, wi->window->xframe.size.height, -1, ZPixmap);*/ } @@ -302,7 +293,7 @@ static int warn = 0; if (DI.inline_alpha) { a = data + DI.inline_alpha_ofs; - as = 4; + as = DI.bytes_per_pixel; } else { @@ -312,9 +303,9 @@ static int warn = 0; for (bofs = 0, i = sx * sy, x = sx, dst = buf; i; i--, a += as) { - if (*adrawable==d) + if (window_buffers[i]->drawable == d) { - [art_window_buffers[i] _gotShmCompletion]; + [window_buffers[i] _gotShmCompletion]; return; } } - NSLog(@"Warning: gotShmCompletion: couldn't find ARTWindowBuffer for drawable"); + NSLog(@"Warning: gotShmCompletion: couldn't find XWindowBuffer for drawable"); } @end -#else - -@implementation ARTWindowBuffer - -+ artWindowBufferForWindow: (int)awindow remote: (RDSClient *)aremote; -{ - int i; - ARTWindowBuffer *wi; - - int x, y; - - for (i = 0; iwindow == awindow) - break; - } - if (i == num_art_window_buffers) - { - wi = [[ARTWindowBuffer alloc] init]; - wi->window = awindow; - wi->remote = aremote; - art_window_buffers = realloc(art_window_buffers, - sizeof(ARTWindowBuffer *) * (num_art_window_buffers + 1)); - if (!art_window_buffers) - { - NSLog(@"Out of memory (failed to allocate %i bytes)", - sizeof(ARTWindowBuffer *) * (num_art_window_buffers + 1)); - exit(1); - } - art_window_buffers[num_art_window_buffers++] = wi; - } - else - { - wi = art_window_buffers[i]; - wi = RETAIN(wi); - } - - [aremote setupGetWindowSize: awindow : &x : &y]; - if (x == wi->sx && y == wi->sy && wi->data) - return wi; - - { - if (wi->alpha) - { - free(wi->alpha); - wi->alpha = NULL; - wi->has_alpha = 0; - } - if (wi->data) - { - shmdt(wi->shminfo.shmaddr); - wi->data = NULL; - } - -// wi->pending_put = wi->pending_event = 0; - - /* TODO: only use shared memory for 'real' on-screen windows */ - wi->shminfo.shmid = shmget(IPC_PRIVATE, DI.bytes_per_pixel * x * y, - IPC_CREAT | 0700); - if (!wi->shminfo.shmid == -1) - NSLog(@"shmget() failed"); -/* printf("shminfo.shmid=%08x %i bytes (%ix%i)\n", - wi->shminfo.shmid, wi->ximage->bytes_per_line * wi->ximage->height, - wi->ximage->width, wi->ximage->height);*/ - wi->shminfo.shmaddr = wi->data = shmat(wi->shminfo.shmid, 0, 0); - shmctl(wi->shminfo.shmid, IPC_RMID, 0); -// printf("addr=%p\n", wi->shminfo.shmaddr); - } - - if (wi->data) - { - wi->sx = x; - wi->sy = y; - wi->bytes_per_line = DI.bytes_per_pixel * x; -// wi->bits_per_pixel = DI.bits_per_pixel; - wi->bytes_per_pixel = DI.bytes_per_pixel; -// NSLog(@"%@ ximage=%p data=%p\n", wi->ximage, wi->data); - - [wi needsAlpha]; - [aremote setupWindow: wi->window : wi->shminfo.shmid - : wi->sx : wi->sy : wi->bytes_per_line]; - } - else - { - NSLog(@"Warning: failed to create shm buffer for window"); - wi->data = NULL; - } - - return wi; -} - --(void) needsAlpha -{ - if (has_alpha) - return; - -// NSLog(@"needs alpha for %p: %ix%i", self, sx, sy); - - if (DI.inline_alpha) - { - int i; - unsigned char *s; - alpha = NULL; - has_alpha = 1; - /* fill the alpha channel */ - /* TODO: is +=4 correct? but only because the only modes - with inline alpha are 32 bit */ - for (i = 0, s = data + DI.inline_alpha_ofs; i