Rename ARTWindowBuffer to XWindowBuffer and move it to x11/.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@14426 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
alexm 2002-09-10 19:37:47 +00:00
parent 3211edd61e
commit 7a94e951c2
10 changed files with 114 additions and 266 deletions

View file

@ -1,3 +1,10 @@
2002-09-10 21:36 Alexander Malmberg <alexander@malmberg.org>
* 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 <alexander@malmberg.org>
* Source/art/composite.m: Implement handling of tranformations and

View file

@ -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 <X11/extensions/XShm.h>
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

View file

@ -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

View file

@ -37,7 +37,7 @@
#include <libart_lgpl/art_vpath_dash.h>
@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;

View file

@ -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

View file

@ -26,7 +26,7 @@
#include "ARTGState.h"
#include "ARTWindowBuffer.h"
#include "x11/XWindowBuffer.h"
#include "blit.h"

View file

@ -31,7 +31,7 @@ Image drawing. DPSimage and helpers.
#include "ARTGState.h"
#include "ARTWindowBuffer.h"
#include "x11/XWindowBuffer.h"
#include "blit.h"

View file

@ -31,7 +31,7 @@ Path handling.
#include "ARTGState.h"
#include "ARTWindowBuffer.h"
#include "x11/XWindowBuffer.h"
#include "blit.h"

View file

@ -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

View file

@ -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 <sys/ipc.h>
#include <sys/shm.h>
#ifndef RDS
#include <X11/extensions/shape.h>
#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; i<num_art_window_buffers; i++)
for (i = 0; i < num_window_buffers; i++)
{
if (art_window_buffers[i]->window == 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 (*a<CUTOFF)
if (*a < CUTOFF)
{
*dst = *dst & ~(1<<bofs);
*dst = *dst & ~(1 << bofs);
}
bofs++;
if (bofs == 8)
@ -415,9 +406,8 @@ static int warn = 0;
alpha = NULL;
has_alpha = 1;
/* fill the alpha channel */
/* TODO: is +=4 correct? yes, but only because the only modes
with inline alpha are 32 bit */
for (i = 0, s = data + DI.inline_alpha_ofs; i<sx * sy; i++, s += 4)
for (i = 0, s = data + DI.inline_alpha_ofs; i < sx * sy;
i++, s += DI.bytes_per_pixel)
*s = 0xff;
return;
}
@ -439,13 +429,13 @@ static int warn = 0;
{
int i;
for (i = 0; i<num_art_window_buffers; i++)
if (art_window_buffers[i] == self) break;
if (i<num_art_window_buffers)
for (i = 0; i < num_window_buffers; i++)
if (window_buffers[i] == self) break;
if (i < num_window_buffers)
{
num_art_window_buffers--;
for (; i<num_art_window_buffers; i++)
art_window_buffers[i] = art_window_buffers[i + 1];
num_window_buffers--;
for (; i < num_window_buffers; i++)
window_buffers[i] = window_buffers[i + 1];
}
if (ximage)
@ -465,161 +455,26 @@ static int warn = 0;
}
+(void) initializeBackendWithDrawInfo: (draw_info_t *)d
+(void) initialize
{
use_shape_hack = [[NSUserDefaults standardUserDefaults]
boolForKey: @"back-art-shape-hack"];
DI = *d;
boolForKey: @"XWindowBuffer-shape-hack"];
}
+(void) _gotShmCompletion: (Drawable)d
{
int i;
for (i=0;i<num_art_window_buffers;i++)
for (i = 0; i < num_window_buffers; i++)
{
if (art_window_buffers[i]->drawable==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; i<num_art_window_buffers; i++)
{
if (art_window_buffers[i]->window == 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<sx * sy; i++, s += 4)
*s = 0xff;
return;
}
alpha = malloc(sx * sy);
if (!alpha)
return;
// NSLog(@"got buffer at %p", alpha);
has_alpha = 1;
memset(alpha, 0xff, sx * sy);
}
-(void) _gotShmCompletion
{
}
-(void) _exposeRect: (NSRect)r
{
}
@end
#endif