summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
authoralex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-04-05 21:20:19 +0000
committeralex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-04-05 21:20:19 +0000
commitfac2bcf4f9c9a399e323478ec4303b03bd1ce9d9 (patch)
tree9cdfaaa7ec6c1a3a1af2b9accab5b4c7080f14ad /libvo
parentbfcc5b3160482db90fa24d02dbf11540e8d5384f (diff)
downloadmpv-fac2bcf4f9c9a399e323478ec4303b03bd1ce9d9.tar.bz2
mpv-fac2bcf4f9c9a399e323478ec4303b03bd1ce9d9.tar.xz
Quartz/MacOSX video output module by Nicolas Plourde
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12121 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libvo')
-rw-r--r--libvo/video_out.c6
-rw-r--r--libvo/vo_quartz.c529
-rw-r--r--libvo/vo_quartz.h129
3 files changed, 664 insertions, 0 deletions
diff --git a/libvo/video_out.c b/libvo/video_out.c
index c05c84b86f..df26b6fcc6 100644
--- a/libvo/video_out.c
+++ b/libvo/video_out.c
@@ -118,6 +118,9 @@ extern vo_functions_t video_out_tdfx_vid;
#ifdef HAVE_TGA
extern vo_functions_t video_out_tga;
#endif
+#ifdef MACOSX
+extern vo_functions_t video_out_quartz;
+#endif
vo_functions_t* video_out_drivers[] =
{
@@ -228,6 +231,9 @@ vo_functions_t* video_out_drivers[] =
#ifdef HAVE_TGA
&video_out_tga,
#endif
+#ifdef MACOSX
+ &video_out_quartz,
+#endif
NULL
};
diff --git a/libvo/vo_quartz.c b/libvo/vo_quartz.c
new file mode 100644
index 0000000000..bf59ced483
--- /dev/null
+++ b/libvo/vo_quartz.c
@@ -0,0 +1,529 @@
+/*
+ * 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.
+ */
+
+//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"
+#include "video_out.h"
+#include "video_out_internal.h"
+#include "aspect.h"
+
+#include "../input/input.h"
+#include "../input/mouse.h"
+
+#include "vo_quartz.h"
+
+static vo_info_t info = {
+ "MacOS X (Quartz)",
+ "quartz",
+ "Nicolas Plourde <nicolasplourde@hotmail.com>",
+ ""
+};
+
+LIBVO_EXTERN (quartz)
+static unsigned char *ImageData = NULL;
+
+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;
+
+static int int_pause = 0;
+
+int screen_width, screen_height;
+
+WindowRef theWindow;
+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);
+
+//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);
+
+
+//default window event handler
+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:
+
+ 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;
+ }
+
+ return err;
+}
+
+//keyboard event handler
+static OSStatus
+MainKeyEventHandler (EventHandlerCallRef nextHandler, EventRef event,
+ void *userData)
+{
+ 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:
+ 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;
+ }
+
+ 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;
+
+ screen_width = deviceRect.right;
+ screen_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;
+
+ aspect_save_orig (width, height);
+ aspect_save_prescale (d_width, d_height);
+ aspect_save_screenres (screen_width, screen_height);
+
+ 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;
+
+ 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}
+ };
+
+ const EventTypeSpec keyEvents[] =
+ { {kEventClassKeyboard, kEventRawKeyDown} };
+ InstallWindowEventHandler (theWindow,
+ NewEventHandlerUPP (MainWindowEventHandler),
+ GetEventTypeCount (winEvents), winEvents,
+ theWindow, NULL);
+ InstallWindowEventHandler (theWindow,
+ NewEventHandlerUPP (MainKeyEventHandler),
+ GetEventTypeCount (keyEvents), keyEvents,
+ theWindow, NULL);
+
+ RepositionWindow (theWindow, NULL, kWindowCascadeOnMainScreen);
+ ShowWindow (theWindow);
+
+ //Setup Quartz context
+ CreateCGContextForPort (GetWindowPort (theWindow), &context);
+
+ //set size and aspect for current window
+ resize_window (d_width, d_height);
+
+ return 0;
+}
+
+//resize drawing context to fit window
+void
+resize_window (uint32_t width, uint32_t height)
+{
+ //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);
+}
+
+static void
+check_events (void)
+{
+ EventRef theEvent;
+ EventTargetRef theTarget;
+
+ theTarget = GetEventDispatcherTarget ();
+
+ ReceiveNextEvent (0, NULL, kEventDurationNoWait, true, &theEvent);
+ SendEventToEventTarget (theEvent, theTarget);
+ ReleaseEvent (theEvent);
+
+ //if(VO_EVENT_RESIZE) resize_window(vo_dwidth,vo_dheight);
+ if (VO_EVENT_EXPOSE && int_pause)
+ flip_page ();
+}
+
+static void
+draw_osd (void)
+{
+}
+
+static void
+flip_page (void)
+{
+ CGContextFlush (context);
+}
+
+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[])
+{
+ //this is very slow. I have to find another way.
+ CGImageAlphaInfo alphaInfo;
+
+ dataProviderRef =
+ CGDataProviderCreateWithData (0, src[0],
+ image_width * image_height * image_bytes,
+ 0);
+
+ if (image_format == IMGFMT_RGB24)
+ alphaInfo = kCGImageAlphaNone;
+ else if (image_format == IMGFMT_RGB32)
+ alphaInfo = kCGImageAlphaNoneSkipFirst;
+
+ image = CGImageCreate (image_width,
+ image_height,
+ 8,
+ image_depth,
+ ((image_width * image_depth) + 7) / 8,
+ CGColorSpaceCreateDeviceRGB (),
+ alphaInfo,
+ dataProviderRef, 0, 0, kCGRenderingIntentDefault);
+
+ CGContextDrawImage (context, bounds, image);
+
+ return 0;
+}
+
+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;
+}
diff --git a/libvo/vo_quartz.h b/libvo/vo_quartz.h
new file mode 100644
index 0000000000..8b4a5883d2
--- /dev/null
+++ b/libvo/vo_quartz.h
@@ -0,0 +1,129 @@
+/*
+ * vo_quartz.h
+ * Mac keyboard def taken from SDL
+ */
+
+#ifndef VO_QUARTZ_H
+#define VO_QUARTZ_H 1
+
+/* These are the Macintosh key scancode constants -- from Inside Macintosh */
+#define QZ_ESCAPE 0x35
+#define QZ_F1 0x7A
+#define QZ_F2 0x78
+#define QZ_F3 0x63
+#define QZ_F4 0x76
+#define QZ_F5 0x60
+#define QZ_F6 0x61
+#define QZ_F7 0x62
+#define QZ_F8 0x64
+#define QZ_F9 0x65
+#define QZ_F10 0x6D
+#define QZ_F11 0x67
+#define QZ_F12 0x6F
+#define QZ_PRINT 0x69
+#define QZ_SCROLLOCK 0x6B
+#define QZ_PAUSE 0x71
+#define QZ_POWER 0x7F
+#define QZ_BACKQUOTE 0x32
+#define QZ_1 0x12
+#define QZ_2 0x13
+#define QZ_3 0x14
+#define QZ_4 0x15
+#define QZ_5 0x17
+#define QZ_6 0x16
+#define QZ_7 0x1A
+#define QZ_8 0x1C
+#define QZ_9 0x19
+#define QZ_0 0x1D
+#define QZ_MINUS 0x1B
+#define QZ_EQUALS 0x18
+#define QZ_BACKSPACE 0x33
+#define QZ_INSERT 0x72
+#define QZ_HOME 0x73
+#define QZ_PAGEUP 0x74
+#define QZ_NUMLOCK 0x47
+#define QZ_KP_EQUALS 0x51
+#define QZ_KP_DIVIDE 0x4B
+#define QZ_KP_MULTIPLY 0x43
+#define QZ_TAB 0x30
+#define QZ_q 0x0C
+#define QZ_w 0x0D
+#define QZ_e 0x0E
+#define QZ_r 0x0F
+#define QZ_t 0x11
+#define QZ_y 0x10
+#define QZ_u 0x20
+#define QZ_i 0x22
+#define QZ_o 0x1F
+#define QZ_p 0x23
+#define QZ_LEFTBRACKET 0x21
+#define QZ_RIGHTBRACKET 0x1E
+#define QZ_BACKSLASH 0x2A
+#define QZ_DELETE 0x75
+#define QZ_END 0x77
+#define QZ_PAGEDOWN 0x79
+#define QZ_KP7 0x59
+#define QZ_KP8 0x5B
+#define QZ_KP9 0x5C
+#define QZ_KP_MINUS 0x4E
+#define QZ_CAPSLOCK 0x39
+#define QZ_a 0x00
+#define QZ_s 0x01
+#define QZ_d 0x02
+#define QZ_f 0x03
+#define QZ_g 0x05
+#define QZ_h 0x04
+#define QZ_j 0x26
+#define QZ_k 0x28
+#define QZ_l 0x25
+#define QZ_SEMICOLON 0x29
+#define QZ_QUOTE 0x27
+#define QZ_RETURN 0x24
+#define QZ_KP4 0x56
+#define QZ_KP5 0x57
+#define QZ_KP6 0x58
+#define QZ_KP_PLUS 0x45
+#define QZ_LSHIFT 0x38
+#define QZ_z 0x06
+#define QZ_x 0x07
+#define QZ_c 0x08
+#define QZ_v 0x09
+#define QZ_b 0x0B
+#define QZ_n 0x2D
+#define QZ_m 0x2E
+#define QZ_COMMA 0x2B
+#define QZ_PERIOD 0x2F
+#define QZ_SLASH 0x2C
+/* These are the same as the left versions - use left by default */
+#if 0
+#define QZ_RSHIFT 0x38
+#endif
+#define QZ_UP 0x7E
+#define QZ_KP1 0x53
+#define QZ_KP2 0x54
+#define QZ_KP3 0x55
+#define QZ_KP_ENTER 0x4C
+#define QZ_LCTRL 0x3B
+#define QZ_LALT 0x3A
+#define QZ_LMETA 0x37
+#define QZ_SPACE 0x31
+/* These are the same as the left versions - use left by default */
+#if 0
+#define QZ_RMETA 0x37
+#define QZ_RALT 0x3A
+#define QZ_RCTRL 0x3B
+#endif
+#define QZ_LEFT 0x7B
+#define QZ_DOWN 0x7D
+#define QZ_RIGHT 0x7C
+#define QZ_KP0 0x52
+#define QZ_KP_PERIOD 0x41
+
+/* Wierd, these keys are on my iBook under MacOS X */
+#define QZ_IBOOK_ENTER 0x34
+#define QZ_IBOOK_LEFT 0x3B
+#define QZ_IBOOK_RIGHT 0x3C
+#define QZ_IBOOK_DOWN 0x3D
+#define QZ_IBOOK_UP 0x3E
+
+#endif /* VO_QUARTZ_H */