[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] OpenGL for OS X
From: |
Mike Kronenberg |
Subject: |
[Qemu-devel] [PATCH] OpenGL for OS X |
Date: |
Fri, 1 Feb 2008 17:45:29 +0100 |
After a little discussion on the list, I made this patch for cocoa.m,
to replace CoreGraphic by OpenGL.
It's way faster than CG, but it requires a Mac with OpenGL capable
Graphics Card and at least 8mb of VRAM.
I think starting with G4 and Highend G3, this requirements are met.
features:
[new] draws dirty lines of the window as needed, implemented with
OpenGL (used the extensions as proposed by Pierre)
[new] window can be resized
[fix] conditional builds for Leopard, without linking to a specific sdk
[fix] lineflicker in fullscreen mode
The Question is, where to draw the line - or - if it needs a switch
for CG/OpenGL support for cocoa.
Please test and comment.
Mike
[1] http://www.kberg.ch/qemu/091patches/cocoa_m_OpenGL.diff.gz
--- /Users/mike/Documents/Qemu091gcc4/qemu/cocoa.m_original.m
2008-01-21 17:11:30.000000000 +0100
+++ /Users/mike/Documents/Qemu091gcc4/qemu/cocoa.m 2008-02-01
17:11:41.000000000 +0100
@@ -22,12 +22,17 @@
* THE SOFTWARE.
*/
+#include <AvailabilityMacros.h>
+
#import <Cocoa/Cocoa.h>
+#import <OpenGL/gl.h>
+
#include "qemu-common.h"
#include "console.h"
#include "sysemu.h"
+#define titleBarHeight 21.0
//#define DEBUG
@@ -54,6 +59,16 @@
int bitsPerPixel;
} QEMUScreen;
+typedef struct {
+ float x;
+ float y;
+ float width;
+ float height;
+ float dx;
+ float dy;
+ float zoom;
+} COCOADisplayProperties;
+
int qemu_main(int argc, char **argv); // main defined in qemu/vl.c
NSWindow *normalWindow;
id cocoaView;
@@ -246,18 +261,19 @@
QemuCocoaView
------------------------------------------------------
*/
address@hidden QemuCocoaView : NSView
address@hidden QemuCocoaView : NSOpenGLView
{
QEMUScreen screen;
+ COCOADisplayProperties displayProperties;
NSWindow *fullScreenWindow;
- float cx,cy,cw,ch,cdx,cdy;
- CGDataProviderRef dataProviderRef;
+ GLuint screen_tex;
int modifiers_state[256];
BOOL isMouseGrabed;
BOOL isFullscreen;
BOOL isAbsoluteEnabled;
BOOL isTabletEnabled;
}
+- (void) setContentDimensionsForFrame:(NSRect)rect;
- (void) resizeContentToWidth:(int)w height:(int)h displayState:
(DisplayState *)ds;
- (void) grabMouse;
- (void) ungrabMouse;
@@ -266,17 +282,16 @@
- (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled;
- (BOOL) isMouseGrabed;
- (BOOL) isAbsoluteEnabled;
-- (float) cdx;
-- (float) cdy;
- (QEMUScreen) gscreen;
+- (COCOADisplayProperties) displayProperties;
@end
@implementation QemuCocoaView
-- (id)initWithFrame:(NSRect)frameRect
+- (id)initWithFrame:(NSRect)frameRect pixelFormat:
(NSOpenGLPixelFormat *)format
{
- COCOA_DEBUG("QemuCocoaView: initWithFrame\n");
+ COCOA_DEBUG("QemuCocoaView: initWithFrame:pixelFormat\n");
- self = [super initWithFrame:frameRect];
+ self = [super initWithFrame:frameRect pixelFormat:format];
if (self) {
screen.bitsPerComponent = 8;
@@ -284,6 +299,8 @@
screen.width = frameRect.size.width;
screen.height = frameRect.size.height;
+ displayProperties.zoom = 1.0;
+
}
return self;
}
@@ -295,110 +312,118 @@
if (screenBuffer)
free(screenBuffer);
- if (dataProviderRef)
- CGDataProviderRelease(dataProviderRef);
-
[super dealloc];
}
- (void) drawRect:(NSRect) rect
{
- COCOA_DEBUG("QemuCocoaView: drawRect\n");
+ COCOA_DEBUG("QemuCocoaView: drawRect: NSRect(%f, %f, %f, %f)\n",
rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
if ((int)screenBuffer == -1)
return;
- // get CoreGraphic context
- CGContextRef viewContextRef = [[NSGraphicsContext currentContext]
graphicsPort];
- CGContextSetInterpolationQuality (viewContextRef,
kCGInterpolationNone);
- CGContextSetShouldAntialias (viewContextRef, NO);
-
- // draw screen bitmap directly to Core Graphics context
- if (dataProviderRef) {
- CGImageRef imageRef = CGImageCreate(
- screen.width, //width
- screen.height, //height
- screen.bitsPerComponent, //bitsPerComponent
- screen.bitsPerPixel, //bitsPerPixel
- (screen.width * 4), //bytesPerRow
+ // remove old texture
+ if( screen_tex != 0) {
+ glDeleteTextures(1, &screen_tex);
+ }
+
+ screen_tex = 1;
+ float onePixel[2];
+ onePixel[0] = 2.0 / displayProperties.width;
+ onePixel[1] = 2.0 / displayProperties.height;
+
+ //calculate the texure rect
+ NSRect clipRect;
+ clipRect = NSMakeRect(
+ 0.0, // we update the whole width, as QEMU in vga is always
updating whole memory pages)
+ floor((float)screen.height - (rect.origin.y +
rect.size.height) / displayProperties.dy),
+ (float)screen.width,
+ ceil(rect.size.height / displayProperties.dy));
+ int start = (int)clipRect.origin.y * screen.width * 4;
+ unsigned char *startPointer = screenBuffer;
+
+ //adapt the drawRect to the textureRect
+ rect = NSMakeRect(
+ 0.0, // we update the whole width, as QEMU in vga is always
updating whole memory pages)
+ (screen.height - (clipRect.origin.y + clipRect.size.height))
* displayProperties.dy,
+ displayProperties.width,
+ clipRect.size.height * displayProperties.dy);
+
+ glEnable(GL_TEXTURE_RECTANGLE_ARB); // enable rectangle textures
+
+ // bind screenBuffer to texture
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, screen.width); // Sets the
appropriate unpacking row length for the bitmap.
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Sets the byte-aligned
unpacking that's needed for bitmaps that are 3 bytes per pixel.
+
+ glBindTexture (GL_TEXTURE_RECTANGLE_ARB, screen_tex); // Binds
the texture name to the texture target.
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
GL_LINEAR); // Sets filtering so that it does not use a mipmap, which
would be redundant for the texture rectangle extension
+
+ // optimize loading of texture
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE); //
+ glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); // bypass
OpenGL framework
+ glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT,
(int)clipRect.size.height * screen.width * 4,
&startPointer[start]); // bypass OpenGL driver
+
+ glTexImage2D(
+ GL_TEXTURE_RECTANGLE_ARB,
+ 0,
+ GL_RGBA,
+ screen.width,
+ (int)clipRect.size.height,
+ 0,
#if __LITTLE_ENDIAN__
- CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), //
colorspace for OS X >= 10.4
- kCGImageAlphaNoneSkipLast,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
#else
- CGColorSpaceCreateDeviceRGB(), //colorspace for OS X <
10.4 (actually ppc)
- kCGImageAlphaNoneSkipFirst, //bitmapInfo
-#endif
- dataProviderRef, //provider
- NULL, //decode
- 0, //interpolate
- kCGRenderingIntentDefault //intent
- );
-// test if host support "CGImageCreateWithImageInRect" at compiletime
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
- if (CGImageCreateWithImageInRect == NULL) { // test if
"CGImageCreateWithImageInRect" is supported on host at runtime
+ GL_BGRA,
+ GL_UNSIGNED_INT_8_8_8_8_REV,
#endif
- // compatibility drawing code (draws everything) (OS X <
10.4)
- CGContextDrawImage (viewContextRef, CGRectMake(0, 0,
[self bounds].size.width, [self bounds].size.height), imageRef);
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
- } else {
- // selective drawing code (draws only dirty rectangles)
(OS X >= 10.4)
- const NSRect *rectList;
- int rectCount;
- int i;
- CGImageRef clipImageRef;
- CGRect clipRect;
-
- [self getRectsBeingDrawn:&rectList count:&rectCount];
- for (i = 0; i < rectCount; i++) {
- clipRect.origin.x = rectList[i].origin.x / cdx;
- clipRect.origin.y = (float)screen.height -
(rectList[i].origin.y + rectList[i].size.height) / cdy;
- clipRect.size.width = rectList[i].size.width / cdx;
- clipRect.size.height = rectList[i].size.height / cdy;
- clipImageRef = CGImageCreateWithImageInRect(
- imageRef,
- clipRect
- );
- CGContextDrawImage (viewContextRef,
cgrect(rectList[i]), clipImageRef);
- CGImageRelease (clipImageRef);
- }
- }
-#endif
- CGImageRelease (imageRef);
+ &startPointer[start]);
+
+ glBegin(GL_QUADS);
+ {
+ glTexCoord2f(0.0f, 0.0f);
+ glVertex2f(-1.0f, (GLfloat)(onePixel[1] * (rect.origin.y +
rect.size.height) - 1.0));
+
+ glTexCoord2f(0.0f, (GLfloat)clipRect.size.height);
+ glVertex2f(-1.0f, (GLfloat)(onePixel[1] * rect.origin.y - 1.0));
+
+ glTexCoord2f((GLfloat)clipRect.size.width,
(GLfloat)clipRect.size.height);
+ glVertex2f(1.0f, (GLfloat)(onePixel[1] * rect.origin.y - 1.0));
+
+ glTexCoord2f((GLfloat)clipRect.size.width, 0.0f);
+ glVertex2f(1.0f, (GLfloat)(onePixel[1] * (rect.origin.y +
rect.size.height) - 1.0));
}
+ glEnd();
+
+ glFlush();
}
-- (void) setContentDimensions
+- (void) setContentDimensionsForFrame:(NSRect)rect
{
- COCOA_DEBUG("QemuCocoaView: setContentDimensions\n");
+ COCOA_DEBUG("QemuCocoaView: setContentDimensionsForFrame:
NSRect(%f, %f, %f, %f)\n", rect.origin.x, rect.origin.y,
rect.size.width, rect.size.height);
- if (isFullscreen) {
- cdx = [[NSScreen mainScreen] frame].size.width /
(float)screen.width;
- cdy = [[NSScreen mainScreen] frame].size.height /
(float)screen.height;
- cw = screen.width * cdx;
- ch = screen.height * cdy;
- cx = ([[NSScreen mainScreen] frame].size.width - cw) / 2.0;
- cy = ([[NSScreen mainScreen] frame].size.height - ch) / 2.0;
- } else {
- cx = 0;
- cy = 0;
- cw = screen.width;
- ch = screen.height;
- cdx = 1.0;
- cdy = 1.0;
- }
+ displayProperties.dx = rect.size.width / (float)screen.width;
+ displayProperties.dy = rect.size.height / (float)screen.height;
+ displayProperties.width = rect.size.width;
+ displayProperties.height = rect.size.height;
+ displayProperties.x = 0.0;//([self bounds].size.width - cw) / 2.0;
+ displayProperties.y = 0.0;//([self bounds].size.height - ch) / 2.0;
+
+ [[self openGLContext] makeCurrentContext];
+ glViewport(displayProperties.x, displayProperties.y,
displayProperties.width, displayProperties.height);
+ [self update];
}
- (void) resizeContentToWidth:(int)w height:(int)h displayState:
(DisplayState *)ds
{
- COCOA_DEBUG("QemuCocoaView: resizeContent\n");
+ COCOA_DEBUG("QemuCocoaView: resizeContentToWidth:%i height:%i\n",
w, h);
// update screenBuffer
- if (dataProviderRef)
- CGDataProviderRelease(dataProviderRef);
if (screenBuffer)
free(screenBuffer);
screenBuffer = malloc( w * 4 * h );
+ // update display state
ds->data = screenBuffer;
ds->linesize = (w * 4);
ds->depth = 32;
@@ -410,21 +435,31 @@
ds->bgr = 0;
#endif
- dataProviderRef = CGDataProviderCreateWithData(NULL,
screenBuffer, w * 4 * h, NULL);
+ // update screen state
+ screen.width = w;
+ screen.height = h;
+
+ NSSize normalWindowSize;
+ normalWindowSize = NSMakeSize(
+ (float)w * displayProperties.zoom,
+ (float)h * displayProperties.zoom + titleBarHeight
+ );
+
+ // keep Window in correct aspect ratio
+ [normalWindow setMaxSize:NSMakeSize(normalWindowSize.width,
normalWindowSize.height)];
+ [normalWindow setAspectRatio:NSMakeSize(normalWindowSize.width,
normalWindowSize.height)];
// update windows
if (isFullscreen) {
- [[fullScreenWindow contentView] setFrame:[[NSScreen
mainScreen] frame]];
- [normalWindow setFrame:NSMakeRect([normalWindow
frame].origin.x, [normalWindow frame].origin.y - h + screen.height, w,
h + [normalWindow frame].size.height - screen.height) display:NO
animate:NO];
+ [self setContentDimensionsForFrame:[[NSScreen mainScreen]
frame]];
+ [normalWindow setFrame:NSMakeRect([normalWindow
frame].origin.x, [normalWindow frame].origin.y + [normalWindow
frame].size.height - normalWindowSize.height, normalWindowSize.width,
normalWindowSize.height) display:NO animate:NO];
} else {
if (qemu_name)
[normalWindow setTitle:[NSString stringWithFormat:@"QEMU
%s", qemu_name]];
- [normalWindow setFrame:NSMakeRect([normalWindow
frame].origin.x, [normalWindow frame].origin.y - h + screen.height, w,
h + [normalWindow frame].size.height - screen.height) display:YES
animate:YES];
+ [self setContentDimensionsForFrame:NSMakeRect(0, 0, w *
displayProperties.zoom, h * displayProperties.zoom)];
+ [self setFrame:NSMakeRect(0, 0, w * displayProperties.zoom, h
* displayProperties.zoom)];
+ [normalWindow setFrame:NSMakeRect([normalWindow
frame].origin.x, [normalWindow frame].origin.y + [normalWindow
frame].size.height - normalWindowSize.height, normalWindowSize.width,
normalWindowSize.height) display:YES animate:YES];
}
- screen.width = w;
- screen.height = h;
- [self setContentDimensions];
- [self setFrame:NSMakeRect(cx, cy, cw, ch)];
}
- (void) toggleFullScreen:(id)sender
@@ -434,9 +469,8 @@
if (isFullscreen) { // switch from fullscreen to desktop
isFullscreen = FALSE;
[self ungrabMouse];
- [self setContentDimensions];
// test if host support "enterFullScreenMode:withOptions" at
compiletime
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+#ifdef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
if ([NSView
respondsToSelector:@selector(exitFullScreenModeWithOptions:)]) { //
test if "exitFullScreenModeWithOptions" is supported on host at runtime
[self exitFullScreenModeWithOptions:nil];
} else {
@@ -445,15 +479,16 @@
[normalWindow setContentView: self];
[normalWindow makeKeyAndOrderFront: self];
[NSMenu setMenuBarVisible:YES];
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+#ifdef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
}
#endif
+ [self setContentDimensionsForFrame:NSMakeRect(0.0, 0.0,
screen.width * displayProperties.zoom, screen.height *
displayProperties.zoom)];
} else { // switch from desktop to fullscreen
isFullscreen = TRUE;
[self grabMouse];
- [self setContentDimensions];
+ [self setContentDimensionsForFrame:NSMakeRect(0.0, 0.0,
[[NSScreen mainScreen] frame].size.width, [[NSScreen mainScreen]
frame].size.height)];
// test if host support "enterFullScreenMode:withOptions" at
compiletime
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+#ifdef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
if ([NSView
respondsToSelector:@selector(enterFullScreenMode:withOptions:)]) { //
test if "enterFullScreenMode:withOptions" is supported on host at
runtime
[self enterFullScreenMode:[NSScreen mainScreen]
withOptions:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO],
NSFullScreenModeAllScreens,
@@ -469,7 +504,7 @@
[fullScreenWindow setHasShadow:NO];
[fullScreenWindow setContentView:self];
[fullScreenWindow makeKeyAndOrderFront:self];
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+#ifdef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
}
#endif
}
@@ -581,7 +616,7 @@
break;
case NSMouseMoved:
if (isAbsoluteEnabled) {
- if (p.x < 0 || p.x > screen.width || p.y < 0 || p.y >
screen.height || ![[self window] isKeyWindow]) {
+ if (p.x < 0 || p.x > (screen.width *
displayProperties.zoom) || p.y < 0 || p.y > (screen.height *
displayProperties.zoom) || ![[self window] isKeyWindow]) {
if (isTabletEnabled) { // if we leave the
window, deactivate the tablet
[NSCursor unhide];
isTabletEnabled = FALSE;
@@ -688,12 +723,42 @@
isMouseGrabed = FALSE;
}
+- (NSSize)windowWillResize:(NSWindow *)window toSize:
(NSSize)proposedFrameSize
+{
+ COCOA_DEBUG("QemuCocoaView: windowWillResize: toSize: NSSize(%f,
%f)\n", proposedFrameSize.width, proposedFrameSize.height);
+
+ // update zoom
+ displayProperties.zoom = proposedFrameSize.width /
(float)screen.width;
+
+ // Update the content to new size before window is resized, if
the new size is bigger
+ if (proposedFrameSize.width > [window frame].size.width ||
proposedFrameSize.height > [window frame].size.height) {
+ [self setContentDimensionsForFrame:NSMakeRect(0, 0,
proposedFrameSize.width, proposedFrameSize.height - titleBarHeight)];
+ [self setFrame:NSMakeRect(displayProperties.x,
displayProperties.y, displayProperties.width, displayProperties.height
- titleBarHeight)];
+ }
+
+ return proposedFrameSize;
+}
+
+- (void)windowDidResize:(NSNotification *)notification
+{
+ COCOA_DEBUG("QemuCocoaView: windowDidResize\n");
+
+ // update the content, if the size has changed
+ if (displayProperties.width != [[self window] frame].size.width
|| displayProperties.height != [[self window] frame].size.height -
titleBarHeight) {
+ if (isFullscreen) {
+ [self setContentDimensionsForFrame:NSMakeRect(0, 0,
[[self window] frame].size.width, [[self window] frame].size.height)];
+ } else {
+ [self setContentDimensionsForFrame:NSMakeRect(0, 0,
[[self window] frame].size.width, [[self window] frame].size.height -
titleBarHeight)];
+ }
+ [self setFrame:NSMakeRect(displayProperties.x,
displayProperties.y, displayProperties.width,
displayProperties.height)];
+ }
+}
+
- (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled
{isAbsoluteEnabled = tIsAbsoluteEnabled;}
- (BOOL) isMouseGrabed {return isMouseGrabed;}
- (BOOL) isAbsoluteEnabled {return isAbsoluteEnabled;}
-- (float) cdx {return cdx;}
-- (float) cdy {return cdy;}
- (QEMUScreen) gscreen {return screen;}
+- (COCOADisplayProperties) displayProperties {return
displayProperties;}
@end
@@ -722,7 +787,7 @@
if (self) {
// create a view and add it to the window
- cocoaView = [[QemuCocoaView alloc]
initWithFrame:NSMakeRect(0.0, 0.0, 640.0, 480.0)];
+ cocoaView = [[QemuCocoaView alloc]
initWithFrame:NSMakeRect(0.0, 0.0, 640.0, 480.0) pixelFormat:
[NSOpenGLView defaultPixelFormat]];
if(!cocoaView) {
fprintf(stderr, "(cocoa) can't create a view\n");
exit(1);
@@ -730,7 +795,7 @@
// create a window
normalWindow = [[NSWindow alloc] initWithContentRect:
[cocoaView frame]
- styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|
NSClosableWindowMask
+ styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|
NSClosableWindowMask|NSResizableWindowMask
backing:NSBackingStoreBuffered defer:NO];
if(!normalWindow) {
fprintf(stderr, "(cocoa) can't create window\n");
@@ -740,6 +805,7 @@
[normalWindow setTitle:[NSString stringWithFormat:@"QEMU"]];
[normalWindow setContentView:cocoaView];
[normalWindow makeKeyAndOrderFront:self];
+ [normalWindow setDelegate:cocoaView];
}
return self;
@@ -927,15 +993,12 @@
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
NSRect rect;
- if ([cocoaView cdx] == 1.0) {
- rect = NSMakeRect(x, [cocoaView gscreen].height - y - h, w, h);
- } else {
- rect = NSMakeRect(
- x * [cocoaView cdx],
- ([cocoaView gscreen].height - y - h) * [cocoaView cdy],
- w * [cocoaView cdx],
- h * [cocoaView cdy]);
- }
+ rect = NSMakeRect(
+ x * [cocoaView displayProperties].dx,
+ ([cocoaView gscreen].height - y - h) * [cocoaView
displayProperties].dy,
+ w * [cocoaView displayProperties].dx,
+ h * [cocoaView displayProperties].dy);
+
[cocoaView displayRect:rect];
}
--- /Users/mike/Documents/Qemu091gcc4/qemu/configure_original
2008-02-01 09:27:49.000000000 +0100
+++ /Users/mike/Documents/Qemu091gcc4/qemu/configure 2008-02-01
09:33:37.000000000 +0100
@@ -154,7 +154,7 @@
cocoa="yes"
coreaudio="yes"
OS_CFLAGS="-mdynamic-no-pic"
-OS_LDFLAGS="-framework CoreFoundation -framework IOKit"
+OS_LDFLAGS="-framework CoreFoundation -framework IOKit -framework
OpenGL"
;;
SunOS)
solaris="yes"
--- /Users/mike/Documents/Qemu091gcc4/qemu/Makefile.target_original
2008-02-01 09:38:48.000000000 +0100
+++ /Users/mike/Documents/Qemu091gcc4/qemu/Makefile.target 2008-02-01
09:38:32.000000000 +0100
@@ -525,7 +525,7 @@
VL_OBJS+=gdbstub.o
endif
ifdef CONFIG_COCOA
-COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework
IOKit
+COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework
IOKit -framework OpenGL
ifdef CONFIG_COREAUDIO
COCOA_LIBS+=-framework CoreAudio
endif
smime.p7s
Description: S/MIME cryptographic signature
- [Qemu-devel] [PATCH] OpenGL for OS X,
Mike Kronenberg <=
- Re: [Qemu-devel] [PATCH] OpenGL for OS X, Alexander Graf, 2008/02/05
- Re: [Qemu-devel] [PATCH] OpenGL for OS X, Anthony Liguori, 2008/02/05
- Re: [Qemu-devel] [PATCH] OpenGL for OS X, Johannes Schindelin, 2008/02/05
- Re: [Qemu-devel] [PATCH] OpenGL for OS X, Anthony Liguori, 2008/02/05
- Re: [Qemu-devel] [PATCH] OpenGL for OS X, Fabrice Bellard, 2008/02/05
- Re: [Qemu-devel] [PATCH] OpenGL for OS X, Gwenole Beauchesne, 2008/02/06
- Re: [Qemu-devel] [PATCH] OpenGL for OS X, Philip Boulain, 2008/02/06
Re: [Qemu-devel] [PATCH] OpenGL for OS X, Mike Kronenberg, 2008/02/16