From: Peter Stewart <peterfs74@gmail.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] cocoa.m using openGL
Date: Tue, 24 May 2005 01:29:18 +0200 [thread overview]
Message-ID: <16d65796e962fc2648b2bd8804a62afc@gmail.com> (raw)
Hi,
Sorry, kind of new at this...
Here is the diff -u version of cocoa.m, I guess you got the
Makefile.target fix :-)
diff -u cocoa.m.orig cocoa.m > cocoa.m.diff
enjoy,
peter.
--- cocoa.m.orig Sat May 21 17:19:45 2005
+++ cocoa.m Mon May 23 19:24:00 2005
@@ -37,16 +37,23 @@
#import <Cocoa/Cocoa.h>
+#include <OpenGL/CGLCurrent.h>
+#include <OpenGL/CGLContext.h>
+
#include "vl.h"
-NSWindow *window = NULL;
-NSQuickDrawView *qd_view = NULL;
+static NSWindow *window = NULL;
+static NSOpenGLView *ogl_view = NULL;
+#define SCREEN_BPP 32
int gArgc;
char **gArgv;
DisplayState current_ds;
+GLint screen_tex = 0;
+GLuint display_list_tex = 0;
+
/* main defined in qemu/vl.c */
int qemu_main(int argc, char **argv);
@@ -62,6 +69,7 @@
------------------------------------------------------
*/
+
/*
------------------------------------------------------
cocoa_update
@@ -70,22 +78,22 @@
static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
{
//printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
+
+ // Make this context current
+ [[ogl_view openGLContext] makeCurrentContext];
+
+ // Bind, update and draw new image
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);
+
+ // glTexSubImage2D is faster when not using a texture range
+ glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,
(GLint)ds->width, (GLint)ds->height, 0, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);
+
+ // Use the compiled display list
+ glCallList(display_list_tex);
+
+ // Swap buffer to screen
+ [[ogl_view openGLContext] flushBuffer];
- /* Use QDFlushPortBuffer() to flush content to display */
- RgnHandle dirty = NewRgn ();
- RgnHandle temp = NewRgn ();
-
- SetEmptyRgn (dirty);
-
- /* Build the region of dirty rectangles */
- MacSetRectRgn (temp, x, y,
- x + w, y + h);
- MacUnionRgn (dirty, temp, dirty);
-
- /* Flush the dirty region */
- QDFlushPortBuffer ( [ qd_view qdPort ], dirty );
- DisposeRgn (dirty);
- DisposeRgn (temp);
}
/*
@@ -95,74 +103,96 @@
*/
static void cocoa_resize(DisplayState *ds, int w, int h)
{
- const int device_bpp = 32;
- static void *screen_pixels;
- static int screen_pitch;
+
NSRect contentRect;
+
+ // printf("resizing to %d %d\n", w, h);
- //printf("resizing to %d %d\n", w, h);
-
- contentRect = NSMakeRect (0, 0, w, h);
- if(window)
- {
- [window close];
- [window release];
- }
- window = [ [ QemuWindow alloc ] initWithContentRect:contentRect
-
styleMask:
NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
- backing:NSBackingStoreBuffered
defer:NO];
- if(!window)
- {
- fprintf(stderr, "(cocoa) can't create window\n");
- exit(1);
- }
-
- if(qd_view)
- [qd_view release];
-
- qd_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
-
- if(!qd_view)
- {
- fprintf(stderr, "(cocoa) can't create qd_view\n");
- exit(1);
- }
-
- [ window setAcceptsMouseMovedEvents:YES ];
- [ window setTitle:@"Qemu" ];
- [ window setReleasedWhenClosed:NO ];
-
- /* Set screen to black */
- [ window setBackgroundColor: [NSColor blackColor] ];
-
- /* set window position */
- [ window center ];
-
- [ qd_view setAutoresizingMask: NSViewWidthSizable |
NSViewHeightSizable ];
- [ [ window contentView ] addSubview:qd_view ];
- [ qd_view release ];
- [ window makeKeyAndOrderFront:nil ];
-
- /* Careful here, the window seems to have to be onscreen to do
that */
- LockPortBits ( [ qd_view qdPort ] );
- screen_pixels = GetPixBaseAddr ( GetPortPixMap ( [ qd_view qdPort
] ) );
- screen_pitch = GetPixRowBytes ( GetPortPixMap ( [ qd_view qdPort
] ) );
- UnlockPortBits ( [ qd_view qdPort ] );
- {
- int vOffset = [ window frame ].size.height -
- [ qd_view frame ].size.height - [ qd_view frame
].origin.y;
-
- int hOffset = [ qd_view frame ].origin.x;
-
- screen_pixels += (vOffset * screen_pitch) + hOffset *
(device_bpp/8);
- }
- ds->data = screen_pixels;
- ds->linesize = screen_pitch;
- ds->depth = device_bpp;
+ contentRect = NSMakeRect (0, 0, w, h);
+
+ [window setContentSize:contentRect.size];
+ [window update];
+
+ [[ogl_view openGLContext] makeCurrentContext];
+ [[ogl_view openGLContext] update];
+
+ glViewport(0, 0, (int) contentRect.size.width, (int)
contentRect.size.height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ // This is used as a init'd flag as well...
+ if(screen_tex != 0) {
+ glDeleteTextures(1, &screen_tex);
+ glDeleteLists(display_list_tex, 1);
+ }
+
+ screen_tex = 1;
+
+ if(ds->data != NULL) free(ds->data);
+ ds->data = (GLubyte *) malloc(w * h * (SCREEN_BPP >> 3));
+ assert(ds->data != NULL);
+ ds->linesize = w * (SCREEN_BPP >> 3);
+ ds->depth = SCREEN_BPP;
ds->width = w;
ds->height = h;
-
- current_ds = *ds;
+
+ // Setup some basic OpenGL stuff as from Apple
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+ glEnable(GL_TEXTURE_RECTANGLE_EXT);
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);
+
+ glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, w * h *
(SCREEN_BPP >> 3), ds->data);
+
+ // Use CACHED for VRAM+reused tex Use SHARED for AGP+used once
tex
+ // Note the texture is always changing so use SHARED
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,
GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
+ glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+ glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, w, h, 0,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);
+
+ glFlush();
+
+ // Setup a display list to save all the operations below
+
+ display_list_tex = glGenLists(1);
+ glNewList(display_list_tex, GL_COMPILE);
+
+ glBegin(GL_QUADS);
+
+ glTexCoord2f(0.0f, 0.0f);
+ glVertex2f(-1.0f, 1.0f);
+
+ glTexCoord2f(0.0f, (GLfloat)h);
+ glVertex2f(-1.0f, -1.0f);
+
+ glTexCoord2f((GLfloat)w, (GLfloat)h);
+ glVertex2f(1.0f, -1.0f);
+
+ glTexCoord2f((GLfloat)w, 0.0f);
+ glVertex2f(1.0f, 1.0f);
+
+ glEnd();
+
+ glEndList();
+
+
+ // Swap buffer to screen
+ [[ogl_view openGLContext] flushBuffer];
+
+ memcpy(¤t_ds, ds, sizeof(DisplayState));
}
/*
@@ -243,19 +273,16 @@
static void cocoa_refresh(DisplayState *ds)
{
//printf("cocoa_refresh \n");
- NSDate *distantPast;
NSEvent *event;
- NSAutoreleasePool *pool;
int grab = 1;
-
- pool = [ [ NSAutoreleasePool alloc ] init ];
- distantPast = [ NSDate distantPast ];
-
+ NSDate *distantPast = [ NSDate distantPast ];;
+
if (is_active_console(vga_console))
vga_update_display();
+
do {
- event = [ NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:distantPast
- inMode: NSDefaultRunLoopMode dequeue:YES ];
+ event = [ window nextEventMatchingMask:NSAnyEventMask
untilDate:distantPast inMode: NSDefaultRunLoopMode dequeue:YES ];
+
if (event != nil) {
switch ([event type]) {
case NSKeyDown:
@@ -278,26 +305,74 @@
kbd_put_keycode(keycode | 0x80);
}
break;
+
+
case NSScrollWheel:
-
- case NSLeftMouseDown:
- case NSLeftMouseUp:
-
- case NSOtherMouseDown:
- case NSRightMouseDown:
-
- case NSOtherMouseUp:
- case NSRightMouseUp:
-
+ if(grab)
+ {
+ int dz = [event deltaZ];
+
+ kbd_mouse_event(0, 0,
dz, 0);
+ }
+ break;
+
+
case NSMouseMoved:
+ if(grab)
+ {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+
+ kbd_mouse_event(dx, dy,
0, 0);
+ }
+ break;
+
+
+ case NSOtherMouseDown:
+ case NSOtherMouseUp:
case NSOtherMouseDragged:
+ if(grab)
+ {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+
+ kbd_mouse_event(dx, dy,
dz, MOUSE_EVENT_MBUTTON);
+ }
+ break;
+
+ case NSRightMouseDown:
+ case NSRightMouseUp:
case NSRightMouseDragged:
+ if(grab)
+ {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+
+ kbd_mouse_event(dx, dy,
dz, MOUSE_EVENT_RBUTTON);
+ }
+ break;
+
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
case NSLeftMouseDragged:
-
- default: [NSApp sendEvent:event];
+ if(grab)
+ {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+
+ kbd_mouse_event(dx, dy,
dz, MOUSE_EVENT_LBUTTON);
+ }
+ break;
+
+ default:
+ [NSApp sendEvent:event];
}
}
} while(event != nil);
+
}
/*
@@ -319,12 +394,72 @@
void cocoa_display_init(DisplayState *ds, int full_screen)
{
- ds->dpy_update = cocoa_update;
- ds->dpy_resize = cocoa_resize;
- ds->dpy_refresh = cocoa_refresh;
+ //printf("resizing to %d %d\n", w, h);
+
+ const int w = 640;
+ const int h = 400;
+
+ if(window == nil)
+ {
+ // Init pixel format attribs
+ NSOpenGLPixelFormatAttribute attrs[] =
+ {
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFANoRecovery,
+ NSOpenGLPFADoubleBuffer,
+ 0
+ };
+
+ NSRect contentRect = NSMakeRect (0, 0, w, h);
+
+ // Get pixel format from OpenGL
+ NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat
alloc] initWithAttributes:attrs];
+ if (!pixFmt)
+ {
+ fprintf(stderr, "No pixel format -- exiting");
+ exit(1);
+ }
+
+ window = [ [ QemuWindow alloc ]
initWithContentRect:contentRect
+
styleMask:
NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
+
backing:NSBackingStoreBuffered defer:NO];
+ if(!window)
+ {
+ fprintf(stderr, "(cocoa) can't create
window\n");
+ exit(1);
+ }
+
+ ogl_view = [ [ NSOpenGLView alloc ]
initWithFrame:contentRect pixelFormat:pixFmt ];
+
+ if(!ogl_view)
+ {
+ fprintf(stderr, "(cocoa) can't create
ogl_view\n");
+ exit(1);
+ }
+
+ [ window setAcceptsMouseMovedEvents:YES ];
+ [ window setTitle:@"Qemu" ];
+ [ window setReleasedWhenClosed:NO ];
+
+ /* set window position */
+ [ window center ];
+ [ window makeKeyAndOrderFront:nil ];
+
+ [ ogl_view setAutoresizingMask: NSViewWidthSizable |
NSViewHeightSizable ];
+ [ window setContentView:ogl_view ];
+ [ ogl_view release ];
+ }
+
+ ds->dpy_update = cocoa_update;
+ ds->dpy_resize = cocoa_resize;
+ ds->dpy_refresh = cocoa_refresh;
cocoa_resize(ds, 640, 400);
-
+
+ [ window display ];
+ [ window makeMainWindow ];
+ [ window makeKeyWindow ];
+
atexit(cocoa_cleanup);
}
@@ -341,30 +476,13 @@
Some trick from SDL to use miniwindow
------------------------------------------------------
*/
-static void QZ_SetPortAlphaOpaque ()
-{
- /* Assume 32 bit if( bpp == 32 )*/
- if ( 1 ) {
-
- uint32_t *pixels = (uint32_t*) current_ds.data;
- uint32_t rowPixels = current_ds.linesize / 4;
- uint32_t i, j;
-
- for (i = 0; i < current_ds.height; i++)
- for (j = 0; j < current_ds.width; j++) {
-
- pixels[ (i * rowPixels) + j ] |= 0xFF000000;
- }
- }
-}
+
@implementation QemuWindow
- (void)miniaturize:(id)sender
{
- /* make the alpha channel opaque so anim won't have holes in it */
- QZ_SetPortAlphaOpaque ();
-
+ /* make the alpha channel opaque so anim won't have holes in it */
[ super miniaturize:sender ];
}
@@ -377,12 +495,10 @@
UI elements, and restore the SDL surface. This way, no expose
event
is required, and the deminiaturize works perfectly.
*/
-
- /* make sure pixels are fully opaque */
- QZ_SetPortAlphaOpaque ();
+
/* save current visible SDL surface */
- [ self cacheImageInRect:[ qd_view frame ] ];
+ [ self cacheImageInRect:[ ogl_view frame ] ];
/* let the window manager redraw controls, border, etc */
[ super display ];
@@ -424,8 +540,8 @@
{
NSOpenPanel *op = [[NSOpenPanel alloc] init];
- cocoa_resize(¤t_ds, 640, 400);
-
+ cocoa_display_init(¤t_ds, 0);
+
[op setPrompt:@"Boot image"];
[op setMessage:@"Select the disk image you want to
boot.\n\nHit the \"Cancel\" button to quit"];
@@ -449,9 +565,16 @@
exit(0);
}
+
+
+
+
+
- (void)openPanelDidEnd:(NSOpenPanel *)sheet
returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
- if(returnCode == NSCancelButton)
+ [sheet close];
+
+ if(returnCode == NSCancelButton)
{
exit(0);
}
next reply other threads:[~2005-05-23 23:42 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-05-23 23:29 Peter Stewart [this message]
-- strict thread matches above, loose matches on Subject: below --
2005-05-23 23:58 [Qemu-devel] cocoa.m using openGL Peter Stewart
2005-05-23 23:31 Peter Stewart
2005-05-24 0:20 ` Mike Kronenberg
2005-05-23 17:31 Peter Stewart
2005-05-23 19:17 ` Mike Kronenberg
2005-05-23 21:54 ` Hetz Ben Hamo
2005-05-23 7:47 Peter Stewart
2005-05-23 8:38 ` Mike Kronenberg
2005-05-22 13:00 Peter Stewart
2005-05-22 13:45 ` Hetz Ben Hamo
2005-05-23 7:20 ` Mike Kronenberg
2005-05-24 15:11 ` Mike Kronenberg
2005-05-26 15:09 ` Pierre d'Herbemont
2005-05-27 14:57 ` Pierre d'Herbemont
2005-05-28 18:39 ` Mike Kronenberg
2005-05-29 14:47 ` Pierre d'Herbemont
2005-05-26 14:52 ` Pierre d'Herbemont
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=16d65796e962fc2648b2bd8804a62afc@gmail.com \
--to=peterfs74@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.