mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 07:21:02 +00:00
opal: Implementation of a lot of drawing and matrix methods. Work on getting backing store support to work.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@36893 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
333059a5d8
commit
a73c2e0fc5
8 changed files with 470 additions and 60 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2013-07-15 Ivan Vucica <ivan@vucica.net>
|
||||
|
||||
* Source/opal/OpalFontEnumerator.m:
|
||||
* Source/opal/OpalFontInfo.m:
|
||||
More dummy font code, trying to get wider menu items et al.
|
||||
|
||||
* Source/opal/OpalSurface.m:
|
||||
* Source/opal/OpalContext.m:
|
||||
* Headers/opal/OpalSurface.h:
|
||||
Work on getting backing store support to work.
|
||||
|
||||
* Source/opal/OpalGState.m:
|
||||
* Headers/opal/OpalGState.h:
|
||||
Implementation of a lot of drawing and matrix methods.
|
||||
|
||||
2013-07-11 Ivan Vucica <ivan@vucica.net>
|
||||
|
||||
* Source/opal/OpalContext.m:
|
||||
|
|
|
@ -60,3 +60,7 @@
|
|||
: (int)x
|
||||
: (int)y;
|
||||
@end
|
||||
|
||||
@interface OpalGState (Accessors)
|
||||
- (CGContextRef) cgContext;
|
||||
@end
|
||||
|
|
|
@ -31,10 +31,18 @@
|
|||
@interface OpalSurface : NSObject
|
||||
{
|
||||
struct _gswindow_device_t * _gsWindowDevice;
|
||||
CGContextRef _cgContext;
|
||||
CGContextRef _backingCGContext;
|
||||
CGContextRef _x11CGContext;
|
||||
}
|
||||
|
||||
- (id) initWithDevice: (void *)device;
|
||||
- (struct _gswindow_device_t *) device;
|
||||
- (CGContextRef) cgContext;
|
||||
|
||||
@end
|
||||
|
||||
@interface OpalSurface (DebugExtensions)
|
||||
|
||||
- (void) dummyDraw;
|
||||
|
||||
@end
|
||||
|
|
|
@ -62,5 +62,40 @@
|
|||
|
||||
[surface release];
|
||||
}
|
||||
|
||||
- (BOOL) isDrawingToScreen
|
||||
{
|
||||
OpalSurface *surface = nil;
|
||||
[OGSTATE GSCurrentSurface: &surface : NULL : NULL];
|
||||
return [surface isDrawingToScreen];
|
||||
}
|
||||
|
||||
/**
|
||||
This handles 'expose' event notifications that arrive from
|
||||
X11.
|
||||
*/
|
||||
+ (void) handleExposeRect: (NSRect)rect forDriver: (void *)driver
|
||||
{
|
||||
if ([(id)driver isKindOfClass: [OpalSurface class]])
|
||||
{
|
||||
[(OpalSurface *)driver handleExposeRect: rect];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if BUILD_SERVER == SERVER_x11
|
||||
#ifdef XSHM
|
||||
+ (void) _gotShmCompletion: (Drawable)d
|
||||
{
|
||||
[XWindowBuffer _gotShmCompletion: d];
|
||||
}
|
||||
|
||||
- (void) gotShmCompletion: (Drawable)d
|
||||
{
|
||||
[XWindowBuffer _gotShmCompletion: d];
|
||||
}
|
||||
#endif // XSHM
|
||||
#endif // BUILD_SERVER = SERVER_x11
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -27,11 +27,88 @@
|
|||
|
||||
#import "opal/OpalFontEnumerator.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface OpalFaceInfo : NSObject
|
||||
/* DUMMY interface */
|
||||
{
|
||||
NSString * _familyName;
|
||||
int _weight;
|
||||
unsigned int _traits;
|
||||
}
|
||||
- (id) initWithFamilyName: (NSString *)familyName
|
||||
weight: (int)weight
|
||||
traits: (unsigned int)traits;
|
||||
|
||||
- (unsigned int) cacheSize;
|
||||
|
||||
- (int) weight;
|
||||
- (void) setWeight: (int)weight;
|
||||
- (unsigned int) traits;
|
||||
- (void) setTraits: (unsigned int)traits;
|
||||
|
||||
- (NSString *) familyName;
|
||||
- (void) setFamilyName: (NSString *)name;
|
||||
|
||||
- (NSCharacterSet*)characterSet;
|
||||
@end
|
||||
@implementation OpalFaceInfo
|
||||
/* DUMMY implementation */
|
||||
- (id) initWithFamilyName: (NSString *)familyName
|
||||
weight: (int)weight
|
||||
traits: (unsigned int)traits
|
||||
{
|
||||
self = [super init];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
_familyName = [familyName retain];
|
||||
_weight = weight;
|
||||
_traits = traits;
|
||||
|
||||
return self;
|
||||
}
|
||||
- (int) weight { return _weight; }
|
||||
- (void) setWeight: (int)weight { _weight = weight; }
|
||||
- (unsigned int) traits { return _traits; }
|
||||
- (void) setTraits: (unsigned int)traits { _traits = traits; }
|
||||
- (NSString *)familyName { return _familyName; }
|
||||
- (void) setFamilyName: (NSString *)name { [_familyName release]; _familyName = [name retain]; }
|
||||
|
||||
- (NSCharacterSet *) characterSet { return nil; }
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation OpalFontEnumerator
|
||||
|
||||
+ (OpalFaceInfo *) fontWithName: (NSString *) name
|
||||
{
|
||||
return [[[OpalFaceInfo alloc] initWithFamilyName:name weight:1 traits:0] autorelease];
|
||||
}
|
||||
|
||||
- (void) enumerateFontsAndFamilies
|
||||
{
|
||||
allFontNames = [[NSArray arrayWithObjects: @"FreeSans",
|
||||
@"FreeSans-Bold", @"FreeMono", nil] retain];
|
||||
allFontFamilies = [[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"FreeSans", @"FreeSans",
|
||||
@"FreeMono", @"FreeMono",
|
||||
nil] retain];
|
||||
|
||||
}
|
||||
|
||||
- (NSString *) defaultSystemFontName
|
||||
{
|
||||
return @"FreeSans";
|
||||
}
|
||||
- (NSString *) defaultBoldSystemFontName
|
||||
{
|
||||
return @"FreeSans-Bold";
|
||||
}
|
||||
- (NSString *) defaultFixedPitchFontName
|
||||
{
|
||||
return @"FreeMono";
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
|
@ -35,5 +35,13 @@
|
|||
{
|
||||
return [super init];
|
||||
}
|
||||
|
||||
- (NSRect) boundingRectForGlyph: (NSGlyph)glyph
|
||||
{
|
||||
return NSMakeRect(0, 0, 10, 10);
|
||||
}
|
||||
- (CGFloat) widthOfString: (NSString *)string
|
||||
{
|
||||
NSLog(@"WIDTH OF %@", string);
|
||||
return [string length] * 10;
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#import "opal/OpalSurface.h"
|
||||
#import "x11/XGServerWindow.h"
|
||||
|
||||
#define CGCTX [self cgContext]
|
||||
|
||||
@implementation OpalGState
|
||||
|
||||
// MARK: Minimum required methods
|
||||
|
@ -38,20 +40,23 @@
|
|||
|
||||
- (void) DPSinitclip
|
||||
{
|
||||
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
OPContextResetClip(CGCTX);
|
||||
}
|
||||
|
||||
- (void) DPSclip
|
||||
{
|
||||
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
CGContextClip(CGCTX);
|
||||
}
|
||||
|
||||
- (void) DPSfill
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
[_opalSurface dummyDraw];
|
||||
|
||||
//CGContextFillPath(CGCTX);
|
||||
}
|
||||
|
||||
- (void) DPSimage: (NSAffineTransform *)matrix
|
||||
|
@ -76,15 +81,33 @@
|
|||
op: (NSCompositingOperation)op
|
||||
fraction: (CGFloat)delta
|
||||
{
|
||||
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
- (void) compositerect: (NSRect)aRect
|
||||
op: (NSCompositingOperation)op
|
||||
{
|
||||
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
CGContextSaveGState(CGCTX);
|
||||
CGContextFillRect(CGCTX, CGRectMake(aRect.origin.x, aRect.origin.y,
|
||||
aRect.size.width, aRect.size.height));
|
||||
CGContextRestoreGState(CGCTX);
|
||||
}
|
||||
|
||||
- (void) DPSsetdash: (const CGFloat*)pat
|
||||
: (NSInteger)size
|
||||
: (CGFloat)offset
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
// TODO: stub
|
||||
}
|
||||
- (void) DPSstroke
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
CGContextStrokePath(CGCTX);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -126,11 +149,15 @@
|
|||
_opalSurface = [opalSurface retain];
|
||||
|
||||
// TODO: apply offset using [self setOffset:]
|
||||
|
||||
[_opalSurface dummyDraw];
|
||||
|
||||
}
|
||||
- (id) GSCurrentSurface: (OpalSurface **)surface
|
||||
: (int *)x
|
||||
: (int *)y
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
return _opalSurface;
|
||||
}
|
||||
/**
|
||||
Sets up a new CG*Context() for drawing content.
|
||||
|
||||
|
@ -148,6 +175,124 @@
|
|||
|
||||
@end
|
||||
|
||||
// MARK: Accessors
|
||||
// MARK: -
|
||||
|
||||
@implementation OpalGState (Accessors)
|
||||
|
||||
- (CGContextRef) cgContext
|
||||
{
|
||||
return [_opalSurface cgContext];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// MARK: Non-required methods
|
||||
// MARK: -
|
||||
static CGFloat theAlpha = 1.; // TODO: removeme
|
||||
@implementation OpalGState (NonrequiredMethods)
|
||||
|
||||
- (void) DPSsetrgbcolor: (CGFloat)r : (CGFloat)g : (CGFloat)b
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
const CGFloat alpha = 1; // TODO: is this correct?
|
||||
CGContextSetRGBFillColor(CGCTX, r, g, b, alpha);
|
||||
}
|
||||
- (void) DPSrectfill: (CGFloat)x : (CGFloat)y : (CGFloat)w : (CGFloat)h
|
||||
{
|
||||
NSLog(@"%p (%@): %s - rect %g %g %g %g", self, [self class], __PRETTY_FUNCTION__, x, y, w, h);
|
||||
|
||||
if (theAlpha == 0)
|
||||
return;
|
||||
CGContextFillRect(CGCTX, CGRectMake(x, y, w, h));
|
||||
}
|
||||
- (void) DPSrectclip: (CGFloat)x : (CGFloat)y : (CGFloat)w : (CGFloat)h
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
CGContextClipToRect(CGCTX, CGRectMake(x, y, w, h));
|
||||
}
|
||||
- (void) DPSsetgray: (CGFloat)gray
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
const CGFloat alpha = 1; // TODO: is this correct?
|
||||
CGContextSetGrayFillColor(CGCTX, gray, alpha);
|
||||
}
|
||||
- (void) DPSsetalpha: (CGFloat)a
|
||||
{
|
||||
NSLog(@"%p (%@): %s - alpha %g", self, [self class], __PRETTY_FUNCTION__, a);
|
||||
|
||||
CGContextSetAlpha(CGCTX, a);
|
||||
theAlpha = a;
|
||||
}
|
||||
- (void)DPSinitmatrix
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
OPContextSetIdentityCTM(CGCTX);
|
||||
}
|
||||
- (void)DPSconcat: (const CGFloat *)m
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
CGContextConcatCTM(CGCTX, CGAffineTransformMake(
|
||||
m[0], m[1], m[2],
|
||||
m[3], m[4], m[5]));
|
||||
}
|
||||
- (void)DPSscale: (CGFloat)x
|
||||
: (CGFloat)y
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
CGContextScaleCTM(CGCTX, x, y);
|
||||
}
|
||||
- (void)DPStranslate: (CGFloat)x
|
||||
: (CGFloat)y
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
CGContextTranslateCTM(CGCTX, x, y);
|
||||
}
|
||||
- (void) DPSmoveto: (CGFloat) x
|
||||
: (CGFloat) y
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
CGContextMoveToPoint(CGCTX, x, y);
|
||||
}
|
||||
- (void) DPSlineto: (CGFloat) x
|
||||
: (CGFloat) y
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
CGContextAddLineToPoint(CGCTX, x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
- (void) setColor: (device_color_t *)color state: (color_state_t)cState
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
|
||||
[super setColor: color
|
||||
state: cState];
|
||||
|
||||
switch (color->space)
|
||||
{
|
||||
case rgb_colorspace:
|
||||
if (cState & COLOR_STROKE)
|
||||
CGContextSetRGBStrokeColor(CGCTX, color->field[0],
|
||||
color->field[1], color->field[2], color->field[3]);
|
||||
if (cState & COLOR_FILL)
|
||||
CGContextSetRGBFillColor(CGCTX, color->field[0],
|
||||
color->field[1], color->field[2], color->field[3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
@end
|
||||
|
||||
// MARK: Non-required unimplemented methods
|
||||
// MARK: -
|
||||
|
||||
|
@ -167,43 +312,6 @@
|
|||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
- (void) setColor: (device_color_t *)color state: (color_state_t)cState
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
- (void)DPSinitmatrix
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
- (void)DPSconcat: (const CGFloat *)m
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
- (void) DPSsetalpha: (CGFloat)a
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
- (void) DPSrectfill: (CGFloat)x : (CGFloat)y : (CGFloat)w : (CGFloat)h
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
[_opalSurface dummyDraw];
|
||||
}
|
||||
- (void) DPSrectclip: (CGFloat)x : (CGFloat)y : (CGFloat)w : (CGFloat)h
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
- (void) DPSsetrgbcolor: (CGFloat)r : (CGFloat)g : (CGFloat)b
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
- (void) GSSetCTM: (NSAffineTransform *)newctm
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
- (void) DPSsetgray: (CGFloat)gray
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
/*
|
||||
- (NSAffineTransform *) GSCurrentCTM
|
||||
{
|
||||
|
@ -211,13 +319,50 @@
|
|||
return nil;
|
||||
}
|
||||
*/
|
||||
- (void)DPSscale: (CGFloat)x : (CGFloat)y
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
- (void)DPStranslate: (CGFloat)x : (CGFloat)y
|
||||
{
|
||||
NSLog(@"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation OpalGState (Unused)
|
||||
|
||||
- (void) _setPath
|
||||
{
|
||||
#if 0
|
||||
NSInteger count = [path elementCount];
|
||||
NSInteger i;
|
||||
SEL elmsel = @selector(elementAtIndex:associatedPoints:);
|
||||
NSBezierPathElement (*elmidx)(id, SEL, NSInteger, NSPoint*) =
|
||||
(NSBezierPathElement (*)(id, SEL, NSInteger, NSPoint*))[path methodForSelector: elmsel];
|
||||
|
||||
// reset current cairo path
|
||||
cairo_new_path(_ct);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
NSBezierPathElement type;
|
||||
NSPoint points[3];
|
||||
|
||||
type = (NSBezierPathElement)(*elmidx)(path, elmsel, i, points);
|
||||
switch(type)
|
||||
{
|
||||
case NSMoveToBezierPathElement:
|
||||
cairo_move_to(_ct, points[0].x, points[0].y);
|
||||
break;
|
||||
case NSLineToBezierPathElement:
|
||||
cairo_line_to(_ct, points[0].x, points[0].y);
|
||||
break;
|
||||
case NSCurveToBezierPathElement:
|
||||
cairo_curve_to(_ct, points[0].x, points[0].y,
|
||||
points[1].x, points[1].y,
|
||||
points[2].x, points[2].y);
|
||||
break;
|
||||
case NSClosePathBezierPathElement:
|
||||
cairo_close_path(_ct);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -32,6 +32,66 @@
|
|||
extern CGContextRef OPX11ContextCreate(Display *display, Drawable drawable);
|
||||
extern void OPContextSetSize(CGContextRef ctx, CGSize s);
|
||||
|
||||
/* Taken from GSQuartzCore's CABackingStore */
|
||||
static CGContextRef createCGBitmapContext (int pixelsWide,
|
||||
int pixelsHigh)
|
||||
{
|
||||
CGContextRef context = NULL;
|
||||
CGColorSpaceRef colorSpace;
|
||||
void * bitmapData;
|
||||
int bitmapByteCount;
|
||||
int bitmapBytesPerRow;
|
||||
|
||||
bitmapBytesPerRow = (pixelsWide * 4);
|
||||
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
|
||||
|
||||
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);// 2
|
||||
|
||||
// Let CGBitmapContextCreate() allocate the memory.
|
||||
// This should be good under Cocoa too.
|
||||
bitmapData = NULL;
|
||||
|
||||
context = CGBitmapContextCreate (bitmapData,
|
||||
pixelsWide,
|
||||
pixelsHigh,
|
||||
8, // bits per component
|
||||
bitmapBytesPerRow,
|
||||
colorSpace,
|
||||
#if !GNUSTEP
|
||||
kCGImageAlphaPremultipliedLast);
|
||||
#else
|
||||
// Opal only supports kCGImageAlphaPremultipliedFirst.
|
||||
// However, this is incorrect since it implies ARGB.
|
||||
kCGImageAlphaPremultipliedFirst);
|
||||
#endif
|
||||
|
||||
// Note: our use of premultiplied alpha means that we need to
|
||||
// do alpha blending using:
|
||||
// GL_SRC_ALPHA, GL_ONE
|
||||
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
if (context== NULL)
|
||||
{
|
||||
free (bitmapData);// 5
|
||||
fprintf (stderr, "Context not created!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if GNUSTEP
|
||||
#warning Opal bug: context should be cleared automatically
|
||||
|
||||
#if 0
|
||||
CGContextClearRect (context, CGRectInfinite);
|
||||
#else
|
||||
#warning Opal bug: CGContextClearRect() permanently whacks the context
|
||||
memset (CGBitmapContextGetData (context),
|
||||
0, bitmapBytesPerRow * pixelsHigh);
|
||||
#endif
|
||||
#endif
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
@implementation OpalSurface
|
||||
|
||||
- (id) initWithDevice: (void *)device
|
||||
|
@ -46,8 +106,31 @@ extern void OPContextSetSize(CGContextRef ctx, CGSize s);
|
|||
|
||||
Display * display = _gsWindowDevice->display;
|
||||
Window window = _gsWindowDevice->ident;
|
||||
_x11CGContext = OPX11ContextCreate(display, window);
|
||||
|
||||
if (_gsWindowDevice->type == NSBackingStoreNonretained)
|
||||
{
|
||||
// Don't double-buffer:
|
||||
// use the window surface as the drawing destination.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do double-buffer:
|
||||
// Create a similar surface to the window which supports alpha
|
||||
|
||||
_cgContext = OPX11ContextCreate(display, window);
|
||||
// Ask XGServerWindow to call +[OpalContext handleExposeRect:forDriver:]
|
||||
// to let us handle the back buffer -> front buffer copy using Opal.
|
||||
_gsWindowDevice->gdriverProtocol |= GDriverHandlesExpose | GDriverHandlesBacking;
|
||||
_gsWindowDevice->gdriver = self;
|
||||
|
||||
#if 0
|
||||
// Disabled because when the content is blitted onto the screen,
|
||||
// we get just yellow blots instead of actual content.
|
||||
_backingCGContext = createCGBitmapContext(
|
||||
_gsWindowDevice->buffer_width,
|
||||
_gsWindowDevice->buffer_height);
|
||||
#endif
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -57,18 +140,53 @@ extern void OPContextSetSize(CGContextRef ctx, CGSize s);
|
|||
return _gsWindowDevice;
|
||||
}
|
||||
|
||||
- (CGContextRef) cgContext
|
||||
{
|
||||
return _backingCGContext ? _backingCGContext : _x11CGContext;
|
||||
}
|
||||
|
||||
- (void) handleExposeRect: (NSRect)rect
|
||||
{
|
||||
CGRect cgRect = CGRectMake(rect.origin.x, rect.origin.y,
|
||||
rect.size.width, rect.size.height);
|
||||
|
||||
CGImageRef backingImage = CGBitmapContextCreateImage(_backingCGContext);
|
||||
if (!backingImage) // FIXME: writing a nil image fails with Opal
|
||||
return;
|
||||
|
||||
CGContextDrawImage(_x11CGContext, cgRect, backingImage);
|
||||
|
||||
// FIXME: Opal tries to access -path from CFURLRef
|
||||
//CFURLRef fileUrl = CFURLCreateWithFileSystemPath(NULL, @"/tmp/opalback.jpg", kCFURLPOSIXPathStyle, NO);
|
||||
CFURLRef fileUrl = (CFURLRef)[[NSURL fileURLWithPath: @"/tmp/opalback.jpg"] retain];
|
||||
CGImageDestinationRef outfile = CGImageDestinationCreateWithURL(fileUrl, @"public.jpeg"/*kUTTypeJPEG*/, 1, NULL);
|
||||
CGImageDestinationAddImage(outfile, backingImage, NULL);
|
||||
CGImageDestinationFinalize(outfile);
|
||||
CFRelease(fileUrl);
|
||||
CFRelease(outfile);
|
||||
|
||||
|
||||
CGImageRelease(backingImage);
|
||||
}
|
||||
|
||||
- (BOOL) isDrawingToScreen
|
||||
{
|
||||
// TODO: stub
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) dummyDraw
|
||||
{
|
||||
|
||||
NSLog(@"performing dummy draw");
|
||||
|
||||
CGContextSaveGState(_cgContext);
|
||||
CGContextSaveGState([self cgContext]);
|
||||
|
||||
CGRect r = CGRectMake(0, 0, 1024, 1024);
|
||||
CGContextSetRGBFillColor(_cgContext, 1, 0, 0, 1);
|
||||
CGContextFillRect(_cgContext, r);
|
||||
CGContextSetRGBFillColor([self cgContext], 1, 0, 0, 1);
|
||||
CGContextFillRect([self cgContext], r);
|
||||
|
||||
CGContextRestoreGState(_cgContext);
|
||||
CGContextRestoreGState([self cgContext]);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue