changeset 12296:1da74cbaf324

Add Fullscreen, Ontop and OSD support
author nplourde
date Mon, 26 Apr 2004 12:17:26 +0000
parents 0dce76a37a16
children a6b64a263ca2
files libvo/vo_quartz.c
diffstat 1 files changed, 467 insertions(+), 453 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/vo_quartz.c	Mon Apr 26 12:14:46 2004 +0000
+++ b/libvo/vo_quartz.c	Mon Apr 26 12:17:26 2004 +0000
@@ -1,31 +1,27 @@
-/* 
- * vo_quartz.c
- *
- * Copyright (c) Nicolas Plourde - January 2004
- *
- * MPlayer Mac OSX Quartz video out module.
- *
- * TODO: -Fullscreen
- *       -Better event handling
- *
- * Note on performance:
- *  Right now i can play fullsize dvd video with -framedrop on my 
- *  iBook G4 800mhz. YUV to RGB converstion will speed up thing alot.
- *  Another thing is the slow fps when you maximize the window, I was
- *  not expecting that. I will fix this a.s.a.p. Im new to Mac 
- *  programming so help is welcome.
+/*
+	vo_quartz.c
+	
+	by Nicolas Plourde <nicolasplourde@hotmail.com>
+	
+	Copyright (c) Nicolas Plourde - April 2004
+	
+	MPlayer Mac OSX Quartz video out module.
+	
+	todo:   -YUV support.
+			-Redo event handling.
+			-Choose fullscreen display device.
+			-Fullscreen antialiasing.
+			-resize black bar without CGContext
+			-rootwin
+			-non-blocking event
+			-(add sugestion here)
  */
 
 //SYS
 #include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <errno.h>
 
 //OSX
 #include <Carbon/Carbon.h>
-#include <QuickTime/QuickTime.h>
 
 //MPLAYER
 #include "config.h"
@@ -38,492 +34,510 @@
 
 #include "vo_quartz.h"
 
-static vo_info_t info = {
-  "MacOS X (Quartz)",
-  "quartz",
-  "Nicolas Plourde <nicolasplourde@hotmail.com>",
-  ""
+static vo_info_t info = 
+{
+	"Mac OSX (Quartz)",
+	"quartz",
+	"Nicolas Plourde <nicolasplourde@hotmail.com>",
+	""
 };
 
-LIBVO_EXTERN (quartz)
-static unsigned char *ImageData = NULL;
+LIBVO_EXTERN(quartz)
 
-static uint32_t image_width;
-static uint32_t image_height;
-static uint32_t image_depth;
-static uint32_t image_bytes;
-static uint32_t image_format;
+uint32_t image_width;
+uint32_t image_height;
+uint32_t image_depth;
+uint32_t image_bytes;
+uint32_t image_format;
+char *image_data;
 
-static int int_pause = 0;
+extern int vo_ontop;
+extern int vo_fs;
 
-int screen_width, screen_height;
+int int_pause = 0;
+float winAlpha = 1;
+
+int device_width, device_height;
 
 WindowRef theWindow;
+
+GWorldPtr imgGWorld;
+
+Rect imgRect;
+Rect dstRect;
+Rect winRect;
+
 CGContextRef context;
-CGRect bounds;
-CGRect winBounds;
-Rect contentRect;
-CGImageRef image;
-CGDataProviderRef dataProviderRef;
-Ptr oldscreenstate;
-RGBColor black = { 0, 0, 0 };
-float winAlpha = 1;
 
 #include "../osdep/keycodes.h"
-extern void mplayer_put_key (int code);
+extern void mplayer_put_key(int code);
+
+extern void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 
 //PROTOTYPE/////////////////////////////////////////////////////////////////
-void resize_window (uint32_t width, uint32_t height);
-static OSStatus MainWindowEventHandler (EventHandlerCallRef nextHandler,
-					EventRef event, void *userData);
-static OSStatus MainKeyEventHandler (EventHandlerCallRef nextHandler,
-				     EventRef event, void *userData);
+void window_resized();
+void window_ontop();
+void window_fullscreen();
 
+static OSStatus MainWindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
+static OSStatus MainKeyboardEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
+static OSStatus MainMouseEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
+
+static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride)
+{
+	vo_draw_alpha_rgb32(w,h,src,srca,stride,image_data+4*(y0*imgRect.right+x0),4*imgRect.right);
+}
 
 //default window event handler
-static OSStatus
-MainWindowEventHandler (EventHandlerCallRef nextHandler, EventRef event,
-			void *userData)
+static OSStatus MainWindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData)
 {
-  OSStatus err = noErr;
-  WindowRef window;
-  Rect rectPort = { 0, 0, 0, 0 };
-  OSStatus result = eventNotHandledErr;
-  UInt32 class = GetEventClass (event);
-  UInt32 kind = GetEventKind (event);
-
-  GetEventParameter (event, kEventParamDirectObject, typeWindowRef, NULL,
-		     sizeof (WindowRef), NULL, &window);
-  if (window)
-    {
-      GetWindowPortBounds (window, &rectPort);
-    }
-
-  switch (kind)
-    {
-    case kEventWindowActivated:
+    OSStatus err = noErr;
+	WindowRef     window;
+	Rect          rectPort = {0,0,0,0};
+	OSStatus      result = eventNotHandledErr;
+	UInt32        class = GetEventClass (event);
+	UInt32        kind = GetEventKind (event);
 
-    case kEventWindowDrawContent:
-      break;
-
-    case kEventWindowClosed:
-      HideWindow (window);
-      mplayer_put_key (KEY_ESC);
-      break;
-
-    case kEventWindowShown:
-      InvalWindowRect (window, &rectPort);
-      break;
-
-    case kEventWindowBoundsChanged:
-      resize_window (rectPort.right, rectPort.bottom);
-      break;
-
-    case kEventWindowZoomed:
-      resize_window (rectPort.right, rectPort.bottom);
-      break;
-
-    default:
-      err = eventNotHandledErr;
-      break;
+	GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window);
+	if(window)
+	{
+		GetWindowPortBounds (window, &rectPort);
+	}
+  
+    switch (kind)
+    {
+		//close window
+        case kEventWindowClosed:
+			HideWindow(window);
+			mplayer_put_key(KEY_ESC);
+		break;
+		
+		//resize window
+		case kEventWindowBoundsChanged:
+			window_resized();
+			flip_page();
+		break;
+			
+        default:
+            err = eventNotHandledErr;
+            break;
     }
-
-  return err;
+    
+    return err;
 }
 
 //keyboard event handler
-static OSStatus
-MainKeyEventHandler (EventHandlerCallRef nextHandler, EventRef event,
-		     void *userData)
+static OSStatus MainKeyboardEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData)
 {
-  OSStatus err = noErr;
-  UInt32 macKeyCode;
+    OSStatus err = noErr;
+	UInt32 macKeyCode;
+	
+	GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(macKeyCode), NULL, &macKeyCode);
+	
+    switch (GetEventKind (event))
+    {
+        case kEventRawKeyDown: 
+		{
+			switch(macKeyCode)
+			{
+				case QZ_RETURN: mplayer_put_key(KEY_ENTER);break;
+				case QZ_ESCAPE: mplayer_put_key(KEY_ESC);break;
+				case QZ_q: mplayer_put_key('q');break;
+ 				case QZ_F1: mplayer_put_key(KEY_F+1);break;
+ 				case QZ_F2: mplayer_put_key(KEY_F+2);break;
+ 				case QZ_F3: mplayer_put_key(KEY_F+3);break;
+ 				case QZ_F4: mplayer_put_key(KEY_F+4);break;
+ 				case QZ_F5: mplayer_put_key(KEY_F+5);break;
+ 				case QZ_F6: mplayer_put_key(KEY_F+6);break;
+ 				case QZ_F7: mplayer_put_key(KEY_F+7);break;
+ 				case QZ_F8: mplayer_put_key(KEY_F+8);break;
+ 				case QZ_F9: mplayer_put_key(KEY_F+9);break;
+ 				case QZ_F10: mplayer_put_key(KEY_F+10);break;
+ 				case QZ_F11: mplayer_put_key(KEY_F+11);break;
+ 				case QZ_F12: mplayer_put_key(KEY_F+12);break;
+				case QZ_o: mplayer_put_key('o');break;
+				case QZ_SPACE: mplayer_put_key(' ');break;
+                case QZ_p: mplayer_put_key('p');break;
+				//case QZ_7: mplayer_put_key(shift_key?'/':'7');
+                //case QZ_PLUS: mplayer_put_key(shift_key?'*':'+');
+				case QZ_KP_PLUS: mplayer_put_key('+');break;
+				case QZ_MINUS:
+				case QZ_KP_MINUS: mplayer_put_key('-');break;
+				case QZ_TAB: mplayer_put_key('\t');break;
+				case QZ_PAGEUP: mplayer_put_key(KEY_PAGE_UP);break;
+				case QZ_PAGEDOWN: mplayer_put_key(KEY_PAGE_DOWN);break;  
+				case QZ_UP: mplayer_put_key(KEY_UP);break;
+				case QZ_DOWN: mplayer_put_key(KEY_DOWN);break;
+                case QZ_LEFT: mplayer_put_key(KEY_LEFT);break;
+				case QZ_RIGHT: mplayer_put_key(KEY_RIGHT);break;
+				//case QZ_LESS: mplayer_put_key(shift_key?'>':'<'); break;
+				//case QZ_GREATER: mplayer_put_key('>'); break;
+				//case QZ_ASTERISK:
+				case QZ_KP_MULTIPLY: mplayer_put_key('*'); break;
+				case QZ_SLASH:
+				case QZ_KP_DIVIDE: mplayer_put_key('/'); break;
+				case QZ_KP0: mplayer_put_key(KEY_KP0); break;
+				case QZ_KP1: mplayer_put_key(KEY_KP1); break;
+				case QZ_KP2: mplayer_put_key(KEY_KP2); break;
+				case QZ_KP3: mplayer_put_key(KEY_KP3); break;
+				case QZ_KP4: mplayer_put_key(KEY_KP4); break;
+				case QZ_KP5: mplayer_put_key(KEY_KP5); break;
+				case QZ_KP6: mplayer_put_key(KEY_KP6); break;
+				case QZ_KP7: mplayer_put_key(KEY_KP7); break;
+				case QZ_KP8: mplayer_put_key(KEY_KP8); break;
+				case QZ_KP9: mplayer_put_key(KEY_KP9); break;
+				case QZ_KP_PERIOD: mplayer_put_key(KEY_KPDEC); break;
+				case QZ_KP_ENTER: mplayer_put_key(KEY_KPENTER); break;
+				case QZ_LEFTBRACKET: SetWindowAlpha(theWindow, winAlpha-=0.05);break;
+				case QZ_RIGHTBRACKET: SetWindowAlpha(theWindow, winAlpha+=0.05);break;
+				case QZ_f: mplayer_put_key('f'); break;
+				case QZ_t: mplayer_put_key('T'); break;
+				default:
+					break;
+			}
+		}		
+		break;
+        default:
+            err = eventNotHandledErr;
+            break;
+    }
+    
+    return err;
+}
 
-  GetEventParameter (event, kEventParamKeyCode, typeUInt32, NULL,
-		     sizeof (macKeyCode), NULL, &macKeyCode);
+//Mouse event handler
+static OSStatus MainMouseEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData)
+{
+    OSStatus err = noErr;
+	WindowPtr tmpWin;
+	Point mousePos;
+	
+	GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0, sizeof(Point), 0, &mousePos);
 
-  switch (GetEventKind (event))
+    switch (GetEventKind (event))
     {
-    case kEventRawKeyDown:
-      {
-	switch (macKeyCode)
-	  {
-	  case QZ_RETURN:
-	    mplayer_put_key (KEY_ENTER);
-	    break;
-	  case QZ_ESCAPE:
-	    EndFullScreen (oldscreenstate, 0);
-	    QuitApplicationEventLoop ();
-	    mplayer_put_key (KEY_ESC);
-	    break;
-	  case QZ_q:
-	    mplayer_put_key ('q');
-	    break;
-	  case QZ_F1:
-	    mplayer_put_key (KEY_F + 1);
-	    break;
-	  case QZ_F2:
-	    mplayer_put_key (KEY_F + 2);
-	    break;
-	  case QZ_F3:
-	    mplayer_put_key (KEY_F + 3);
-	    break;
-	  case QZ_F4:
-	    mplayer_put_key (KEY_F + 4);
-	    break;
-	  case QZ_F5:
-	    mplayer_put_key (KEY_F + 5);
-	    break;
-	  case QZ_F6:
-	    mplayer_put_key (KEY_F + 6);
-	    break;
-	  case QZ_F7:
-	    mplayer_put_key (KEY_F + 7);
-	    break;
-	  case QZ_F8:
-	    mplayer_put_key (KEY_F + 8);
-	    break;
-	  case QZ_F9:
-	    mplayer_put_key (KEY_F + 9);
-	    break;
-	  case QZ_F10:
-	    mplayer_put_key (KEY_F + 10);
-	    break;
-	  case QZ_F11:
-	    mplayer_put_key (KEY_F + 11);
-	    break;
-	  case QZ_F12:
-	    mplayer_put_key (KEY_F + 12);
-	    break;
-	  case QZ_o:
-	    mplayer_put_key ('o');
-	    break;
-	  case QZ_SPACE:
-	    mplayer_put_key (' ');
-	    break;
-	  case QZ_p:
-	    mplayer_put_key ('p');
-	    break;
-	    //case QZ_7: mplayer_put_key(shift_key?'/':'7');
-	    //case QZ_PLUS: mplayer_put_key(shift_key?'*':'+');
-	  case QZ_KP_PLUS:
-	    mplayer_put_key ('+');
-	    break;
-	  case QZ_MINUS:
-	  case QZ_KP_MINUS:
-	    mplayer_put_key ('-');
-	    break;
-	  case QZ_TAB:
-	    mplayer_put_key ('\t');
-	    break;
-	  case QZ_PAGEUP:
-	    mplayer_put_key (KEY_PAGE_UP);
-	    break;
-	  case QZ_PAGEDOWN:
-	    mplayer_put_key (KEY_PAGE_DOWN);
-	    break;
-	  case QZ_UP:
-	    mplayer_put_key (KEY_UP);
-	    break;
-	  case QZ_DOWN:
-	    mplayer_put_key (KEY_DOWN);
-	    break;
-	  case QZ_LEFT:
-	    mplayer_put_key (KEY_LEFT);
-	    break;
-	  case QZ_RIGHT:
-	    mplayer_put_key (KEY_RIGHT);
-	    break;
-	    //case QZ_LESS: mplayer_put_key(shift_key?'>':'<'); break;
-	    //case QZ_GREATER: mplayer_put_key('>'); break;
-	    //case QZ_ASTERISK:
-	  case QZ_KP_MULTIPLY:
-	    mplayer_put_key ('*');
-	    break;
-	  case QZ_SLASH:
-	  case QZ_KP_DIVIDE:
-	    mplayer_put_key ('/');
-	    break;
-	  case QZ_KP0:
-	    mplayer_put_key (KEY_KP0);
-	    break;
-	  case QZ_KP1:
-	    mplayer_put_key (KEY_KP1);
-	    break;
-	  case QZ_KP2:
-	    mplayer_put_key (KEY_KP2);
-	    break;
-	  case QZ_KP3:
-	    mplayer_put_key (KEY_KP3);
-	    break;
-	  case QZ_KP4:
-	    mplayer_put_key (KEY_KP4);
-	    break;
-	  case QZ_KP5:
-	    mplayer_put_key (KEY_KP5);
-	    break;
-	  case QZ_KP6:
-	    mplayer_put_key (KEY_KP6);
-	    break;
-	  case QZ_KP7:
-	    mplayer_put_key (KEY_KP7);
-	    break;
-	  case QZ_KP8:
-	    mplayer_put_key (KEY_KP8);
-	    break;
-	  case QZ_KP9:
-	    mplayer_put_key (KEY_KP9);
-	    break;
-	  case QZ_KP_PERIOD:
-	    mplayer_put_key (KEY_KPDEC);
-	    break;
-	  case QZ_KP_ENTER:
-	    mplayer_put_key (KEY_KPENTER);
-	    break;
-	  case QZ_LEFTBRACKET:
-	    SetWindowAlpha (theWindow, winAlpha -= 0.05);
-	    break;
-	  case QZ_RIGHTBRACKET:
-	    SetWindowAlpha (theWindow, winAlpha += 0.05);
-	    break;
-	  case QZ_f:
-	    break;
-	  default:
-	    break;
-	  }
-      }
-      break;
-    default:
-      err = eventNotHandledErr;
-      break;
+        case kEventMouseDown: 
+		{
+				short part = FindWindow(mousePos,&tmpWin);
+				
+				if(part == inMenuBar)
+				{
+					MenuSelect(mousePos);
+				}
+		}		
+		break;
+        default:
+            err = eventNotHandledErr;
+            break;
     }
+    
+	HiliteMenu(0);
+    return err;
+}
 
-  return err;
+static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format)
+{
+	WindowAttributes	windowAttrs;
+	CFStringRef			titleKey;
+	CFStringRef			windowTitle; 
+	OSStatus			result;
+	GDHandle			deviceHdl;
+	Rect				deviceRect;
+	
+	//Get Main device info///////////////////////////////////////////////////
+	deviceHdl = GetMainDevice();
+	deviceRect = (*deviceHdl)->gdRect;
+	
+	device_width = deviceRect.right;
+	device_height = deviceRect.bottom;
+	
+	//misc mplayer setup/////////////////////////////////////////////////////
+	image_width = width;
+	image_height = height;
+	image_depth = IMGFMT_RGB_DEPTH(format);
+	image_bytes = (IMGFMT_RGB_DEPTH(format)+7)/8;
+	image_data = malloc(image_width*image_height*4);
+
+	vo_fs = flags & VOFLAG_FULLSCREEN;
+	
+	//get movie aspect
+	aspect_save_orig(width,height);
+	aspect_save_prescale(d_width,d_height);
+	aspect_save_screenres(device_width, device_height);
+
+	aspect(&d_width,&d_height,A_NOZOOM);
+
+	//Create player window//////////////////////////////////////////////////
+	windowAttrs =   kWindowStandardDocumentAttributes
+					| kWindowStandardHandlerAttribute
+					| kWindowLiveResizeAttribute;
+
+	SetRect(&winRect, 0, 0, d_width, d_height);
+	SetRect(&dstRect, 0, 0, d_width, d_height);
+	SetRect(&imgRect, 0, 0, image_width, image_height);
+	
+	CreateNewWindow(kDocumentWindowClass, windowAttrs, &winRect, &theWindow);
+
+	//Set window title
+	titleKey	= CFSTR("MPlayer");
+	windowTitle = CFCopyLocalizedString(titleKey, NULL);
+	result		= SetWindowTitleWithCFString(theWindow, windowTitle);
+	CFRelease(titleKey);
+	CFRelease(windowTitle);
+
+	//Install event handler
+	const EventTypeSpec winEvents[] = { { kEventClassWindow, kEventWindowClosed }, { kEventClassWindow, kEventWindowBoundsChanged } };
+	const EventTypeSpec keyEvents[] = { { kEventClassKeyboard, kEventRawKeyDown } };
+	const EventTypeSpec mouseEvents[] = { { kEventClassMouse, kEventMouseDown } };
+	
+    InstallWindowEventHandler (theWindow, NewEventHandlerUPP (MainWindowEventHandler), GetEventTypeCount(winEvents), winEvents, theWindow, NULL);	
+	InstallWindowEventHandler (theWindow, NewEventHandlerUPP (MainKeyboardEventHandler), GetEventTypeCount(keyEvents), keyEvents, theWindow, NULL);
+	InstallApplicationEventHandler (NewEventHandlerUPP (MainMouseEventHandler), GetEventTypeCount(mouseEvents), mouseEvents, 0, NULL);
+
+	//Show window
+	RepositionWindow(theWindow, NULL, kWindowCascadeOnMainScreen);
+	ShowWindow (theWindow);
+	
+	if(vo_fs)
+		window_fullscreen();
+		
+	if(vo_ontop)
+		window_ontop();
+	
+	return 0;
 }
 
-static uint32_t
-config (uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height,
-	uint32_t flags, char *title, uint32_t format)
+static void check_events(void)
 {
-  WindowAttributes windowAttrs;
-  CFStringRef titleKey;
-  CFStringRef windowTitle;
-  OSStatus result;
-  GDHandle deviceHdl;
-  Rect deviceRect;
-
-  //Get Main device info///////////////////////////////////////////////////
-  deviceHdl = GetMainDevice ();
-  deviceRect = (*deviceHdl)->gdRect;
-
-  screen_width = deviceRect.right;
-  screen_height = deviceRect.bottom;
+	EventRef theEvent;
+	EventTargetRef theTarget;
+	OSStatus	theErr;
+	
+	//Get event
+	theTarget = GetEventDispatcherTarget();
+    theErr = ReceiveNextEvent(0, 0, kEventDurationNoWait,true, &theEvent);
+    if(theErr == noErr && theEvent != NULL)
+	{
+		SendEventToEventTarget (theEvent, theTarget);
+		ReleaseEvent(theEvent);
+	}
 
-  //misc mplayer setup/////////////////////////////////////////////////////
-  image_width = width;
-  image_height = height;
-  image_depth = IMGFMT_RGB_DEPTH (format);
-  image_bytes = (IMGFMT_RGB_DEPTH (format) + 7) / 8;
-
-  aspect_save_orig (width, height);
-  aspect_save_prescale (d_width, d_height);
-  aspect_save_screenres (screen_width, screen_height);
+	//update activity every 30 seconds to prevent
+	//screensaver from starting up.
+	DateTimeRec d;
+	unsigned long curTime;
+	static unsigned long lastTime = 0;
+	
+	GetTime(&d);
+	DateToSeconds( &d, &curTime);
+	
+	if( ( (curTime - lastTime) >= 30) || (lastTime == 0))
+	{
+		UpdateSystemActivity(UsrActivity);
+		lastTime = curTime;
+	}
+}
 
-  aspect (&d_width, &d_height, A_NOZOOM);
-
-  if (ImageData)
-    free (ImageData);
-  ImageData = malloc (image_width * image_height * image_bytes);
-
-  //Create player window//////////////////////////////////////////////////
-  windowAttrs = kWindowStandardDocumentAttributes
-    | kWindowMetalAttribute
-    | kWindowStandardHandlerAttribute
-    | kWindowInWindowMenuAttribute
-    | kWindowLiveResizeAttribute | kWindowCompositingAttribute;
+static void draw_osd(void)
+{
+	vo_draw_text(image_width,image_height,draw_alpha);
+}
 
-  SetRect (&contentRect, 0, 0, d_width, d_height);
-  CreateNewWindow (kDocumentWindowClass, windowAttrs, &contentRect,
-		   &theWindow);
-
-  titleKey = CFSTR ("MPlayer");
-  windowTitle = CFCopyLocalizedString (titleKey, NULL);
-  result = SetWindowTitleWithCFString (theWindow, windowTitle);
-  CFRelease (titleKey);
-  CFRelease (windowTitle);
-
-  const EventTypeSpec winEvents[] = {
-    {kEventClassWindow, kEventWindowActivated},
-    {kEventClassWindow, kEventWindowDrawContent},
-    {kEventClassWindow, kEventWindowClosed},
-    {kEventClassWindow, kEventWindowShown},
-    {kEventClassWindow, kEventWindowBoundsChanged},
-    {kEventClassWindow, kEventWindowZoomed}
-  };
+static void flip_page(void)
+{
+	OSStatus error;
+	CGrafPtr oldPort,deskPort;
+	GDHandle oldGDevice;
+	OSStatus lockPixelsError;
+	Boolean canLockPixels;
+	
+	GetGWorld (&oldPort, &oldGDevice);
+	SetGWorld(GetWindowPort(theWindow), GetMainDevice());
+	
+	CGrafPtr windowPort = GetWindowPort(theWindow);
+	
+	lockPixelsError = LockPortBits(windowPort);
+	
+	if (lockPixelsError == noErr)
+		canLockPixels = true;
+	else 
+		canLockPixels = false;
+	
+	if (canLockPixels)
+	{
+		CopyBits( GetPortBitMapForCopyBits (imgGWorld), GetPortBitMapForCopyBits (windowPort), &imgRect, &dstRect, srcCopy, 0 );
+		lockPixelsError = UnlockPortBits(windowPort);
+	}
+	
+	RgnHandle theVisibleRegion; 
+	
+	if (QDIsPortBuffered(windowPort))
+	{
+		theVisibleRegion = NewRgn();
+		GetPortVisibleRegion(windowPort, theVisibleRegion);
+		QDFlushPortBuffer(windowPort, theVisibleRegion); 
+		DisposeRgn(theVisibleRegion);
+	} 
 
-  const EventTypeSpec keyEvents[] =
-    { {kEventClassKeyboard, kEventRawKeyDown} };
-  InstallWindowEventHandler (theWindow,
-			     NewEventHandlerUPP (MainWindowEventHandler),
-			     GetEventTypeCount (winEvents), winEvents,
-			     theWindow, NULL);
-  InstallWindowEventHandler (theWindow,
-			     NewEventHandlerUPP (MainKeyEventHandler),
-			     GetEventTypeCount (keyEvents), keyEvents,
-			     theWindow, NULL);
+	SetGWorld(oldPort, oldGDevice); 
+}
+
+static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
+{
+	return -1;
+}
+
+static uint32_t draw_frame(uint8_t *src[])
+{
+	image_data = src[0];
+
+	DisposeGWorld(imgGWorld);
+	NewGWorldFromPtr (&imgGWorld, k32ARGBPixelFormat, &imgRect, 0, 0, 0, image_data, image_width * 4);
+
+	return 0; 
+}
 
-  RepositionWindow (theWindow, NULL, kWindowCascadeOnMainScreen);
-  ShowWindow (theWindow);
+static uint32_t query_format(uint32_t format)
+{
+	image_format = format;
+	
+	//Curently supporting only rgb32 format.
+    if ((format == IMGFMT_RGB32))
+        return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;
+    return 0;
+}
 
-  //Setup Quartz context
-  CreateCGContextForPort (GetWindowPort (theWindow), &context);
+static void uninit(void)
+{
+	ShowMenuBar();
+}
 
-  //set size and aspect for current window
-  resize_window (d_width, d_height);
-
-  return 0;
+static uint32_t preinit(const char *arg)
+{
+    return 0;
 }
 
-//resize drawing context to fit window
-void
-resize_window (uint32_t width, uint32_t height)
+static uint32_t control(uint32_t request, void *data, ...)
 {
-  //this is a "wow it work". Need some improvement.
-  uint32_t d_width;
-  uint32_t d_height;
-  uint32_t size;
-  Rect tmpRect;
-
-  float aspectX;
-  float aspectY;
-
-  aspect (&d_width, &d_height, A_NOZOOM);
-
-  aspectX = (float) ((float) d_width * (width / (float) d_width));
-  aspectY = (float) ((float) d_height * (width / (float) d_width));
-
-  if (aspectY > height)
-    {
-      aspectX = (float) ((float) d_width * (height / (float) d_height));
-      aspectY = (float) ((float) d_height * (height / (float) d_height));
-
-      bounds = CGRectMake ((width - aspectX) / 2, 0, aspectX, aspectY);
-    }
-  else
-    {
-      bounds = CGRectMake (0, (height - aspectY) / 2, aspectX, aspectY);
-    }
-
-  //create a graphic context for the window
-  GetWindowPortBounds (theWindow, &tmpRect);
-  SetPortBounds (GetWindowPort (theWindow), &tmpRect);
-  CreateCGContextForPort (GetWindowPort (theWindow), &context);
-
-  //fill background with black
-  winBounds =
-    CGRectMake (tmpRect.top, tmpRect.left, tmpRect.right, tmpRect.bottom);
-  CGContextSetRGBFillColor (context, 0.0, 0.0, 0.0, 1.0);
-  CGContextFillRect (context, winBounds);
+  switch (request)
+  {
+	case VOCTRL_PAUSE: return (int_pause=1);
+	case VOCTRL_RESUME: return (int_pause=0);
+	case VOCTRL_FULLSCREEN: window_fullscreen(); return VO_TRUE;
+	case VOCTRL_ONTOP: window_ontop(); return VO_TRUE;
+	case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data));
+  }
+  return VO_NOTIMPL;
 }
 
-static void
-check_events (void)
+void window_resized()
 {
-  EventRef theEvent;
-  EventTargetRef theTarget;
-
-  theTarget = GetEventDispatcherTarget ();
+	float aspectX;
+	float aspectY;
+	
+	int padding;
+	
+	uint32_t d_width;
+	uint32_t d_height;
+	
+	GetWindowPortBounds(theWindow, &winRect);
 
-  ReceiveNextEvent (0, NULL, kEventDurationNoWait, true, &theEvent);
-  SendEventToEventTarget (theEvent, theTarget);
-  ReleaseEvent (theEvent);
+	aspect( &d_width, &d_height, A_NOZOOM);
+	
+	aspectX = (float)((float)winRect.right/(float)d_width);
+	aspectY = (float)((float)winRect.bottom/(float)d_height);
+	
+	if((d_height*aspectX)>winRect.bottom)
+	{
+		padding = (winRect.right - d_width*aspectY)/2;
+		SetRect(&dstRect, padding, 0, d_width*aspectY+padding, d_height*aspectY);
+	}
+	else
+	{
+		padding = (winRect.bottom - d_height*aspectX)/2;
+		SetRect(&dstRect, 0, padding, (d_width*aspectX), d_height*aspectX+padding);
+	}
 
-  //if(VO_EVENT_RESIZE) resize_window(vo_dwidth,vo_dheight);
-  if (VO_EVENT_EXPOSE && int_pause)
-    flip_page ();
+	//create a graphic context for the window
+	SetPortBounds(GetWindowPort(theWindow), &winRect);
+	CreateCGContextForPort(GetWindowPort(theWindow),&context);
+
+	//fill background with black
+	CGRect winBounds = CGRectMake( winRect.top, winRect.left, winRect.right, winRect.bottom);
+	CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
+	CGContextFillRect(context, winBounds);
+	CGContextFlush(context);
 }
 
-static void
-draw_osd (void)
-{
-}
-
-static void
-flip_page (void)
-{
-  CGContextFlush (context);
+void window_ontop()
+{	
+	if(!vo_ontop)
+		SetWindowClass( theWindow, kUtilityWindowClass);
+	else
+		SetWindowClass( theWindow, kDocumentWindowClass);
+		
+	vo_ontop = (!(vo_ontop));
 }
 
-static uint32_t
-draw_slice (uint8_t * src[], int stride[], int w, int h, int x, int y)
+void window_fullscreen()
 {
-  return -1;
-}
+	static Rect oldRect;
+	static Ptr *restoreState = nil;
+	short width=640;
+	short height=480;
+	RGBColor black={0,0,0};
+	GDHandle deviceHdl;
+	Rect deviceRect;
 
-static uint32_t
-draw_frame (uint8_t * src[])
-{
-  //this is very slow. I have to find another way.
-  CGImageAlphaInfo alphaInfo;
+	//go fullscreen
+	if(!vo_fs)
+	{
+		//BeginFullScreen( &restoreState,nil,&width,&height,nil,&black,nil);
+		HideMenuBar();
 
-  dataProviderRef =
-    CGDataProviderCreateWithData (0, src[0],
-				  image_width * image_height * image_bytes,
-				  0);
+		//Get Main device info///////////////////////////////////////////////////
+		deviceHdl = GetMainDevice();
+		deviceRect = (*deviceHdl)->gdRect;
+	
+		device_width = deviceRect.right;
+		device_height = deviceRect.bottom;
 
-  if (image_format == IMGFMT_RGB24)
-    alphaInfo = kCGImageAlphaNone;
-  else if (image_format == IMGFMT_RGB32)
-    alphaInfo = kCGImageAlphaNoneSkipFirst;
+		//save old window size
+		GetWindowPortBounds(theWindow, &oldRect);
+		
+		//hide mouse cursor
+		HideCursor();
+		
+		//go fullscreen
+		ChangeWindowAttributes(theWindow, 0, kWindowResizableAttribute);
+		MoveWindow (theWindow, 0, 0, 1);		
+		SizeWindow(theWindow, device_width, device_height,1);
 
-  image = CGImageCreate (image_width,
-			 image_height,
-			 8,
-			 image_depth,
-			 ((image_width * image_depth) + 7) / 8,
-			 CGColorSpaceCreateDeviceRGB (),
-			 alphaInfo,
-			 dataProviderRef, 0, 0, kCGRenderingIntentDefault);
+		vo_fs = 1;
+	}
+	else //go back to windowed mode
+	{
+		//EndFullScreen( restoreState,0);
+		ShowMenuBar();
+		
+		//Get Main device info///////////////////////////////////////////////////
+		deviceHdl = GetMainDevice();
+		deviceRect = (*deviceHdl)->gdRect;
+	
+		device_width = deviceRect.right;
+		device_height = deviceRect.bottom;
 
-  CGContextDrawImage (context, bounds, image);
-
-  return 0;
+		//show mouse cursor
+		ShowCursor();
+		
+		//revert window to previous setting
+		ChangeWindowAttributes(theWindow, kWindowResizableAttribute, 0);
+		SizeWindow(theWindow, oldRect.right, oldRect.bottom,1);
+		RepositionWindow(theWindow, NULL, kWindowCascadeOnMainScreen);
+		
+		vo_fs = 0;
+	}
+	
+	window_resized();
 }
 
-static uint32_t
-query_format (uint32_t format)
-{
-  image_format = format;
-
-  //Curently supporting only rgb format.
-  if ((format == IMGFMT_RGB24) || (format == IMGFMT_RGB32))
-    return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;
-  return 0;
-}
-
-
-static void
-uninit (void)
-{
-}
-
-static uint32_t
-preinit (const char *arg)
-{
-  return 0;
-}
-
-static uint32_t
-control (uint32_t request, void *data, ...)
-{
-  switch (request)
-    {
-    case VOCTRL_PAUSE:
-      return (int_pause = 1);
-    case VOCTRL_RESUME:
-      return (int_pause = 0);
-    case VOCTRL_QUERY_FORMAT:
-      return query_format (*((uint32_t *) data));
-    }
-  return VO_NOTIMPL;
-}