# HG changeset patch # User nplourde # Date 1082981846 0 # Node ID 1da74cbaf32423f2dde6cbb6a857e02751a2943c # Parent 0dce76a37a16500b6312854e0274966e199981fc Add Fullscreen, Ontop and OSD support diff -r 0dce76a37a16 -r 1da74cbaf324 libvo/vo_quartz.c --- 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 + + 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 -#include -#include -#include -#include //OSX #include -#include //MPLAYER #include "config.h" @@ -38,492 +34,510 @@ #include "vo_quartz.h" -static vo_info_t info = { - "MacOS X (Quartz)", - "quartz", - "Nicolas Plourde ", - "" +static vo_info_t info = +{ + "Mac OSX (Quartz)", + "quartz", + "Nicolas Plourde ", + "" }; -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; -}