/**
\author Nicolas Plourde <nicolasplourde@gmail.com>
Copyright (c) Nicolas Plourde - April 2004
YUV support Copyright (C) 2004 Romain Dolbeau <romain@dolbeau.org>
\brief MPlayer Mac OSX Quartz video out module.
\todo: -screen overlay output
-fit osd in black bar when available
-fix RGB32
-(add sugestion here)
*/
//SYS
#include <stdio.h>
//OSX
#include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
//MPLAYER
#include "config.h"
#include "fastmemcpy.h"
#include "video_out.h"
#include "video_out_internal.h"
#include "aspect.h"
#include "mp_msg.h"
#include "m_option.h"
#include "mp_fifo.h"
#include "mpbswap.h"
#include "sub.h"
#include "input/input.h"
#include "input/mouse.h"
#include "vo_quartz.h"
static const vo_info_t info =
{
"Mac OSX (Quartz)",
"quartz",
"Nicolas Plourde <nicolasplourde@hotmail.com>, Romain Dolbeau <romain@dolbeau.org>",
""
};
const LIBVO_EXTERN(quartz)
static uint32_t image_depth;
static uint32_t image_format;
static uint32_t image_size;
static uint32_t image_buffer_size;
static char *image_data;
static ImageSequence seqId;
static CodecType image_qtcodec;
static PlanarPixmapInfoYUV420 *P = NULL;
static struct
{
ImageDescriptionHandle desc;
Handle extension_colr;
Handle extension_fiel;
Handle extension_clap;
Handle extension_pasp;
} yuv_qt_stuff;
static MatrixRecord matrix;
static int EnterMoviesDone = 0;
static int get_image_done = 0;
static int vo_quartz_fs; // we are in fullscreen
extern float monitor_aspect;
extern float movie_aspect;
static float old_movie_aspect;
static int winLevel = 1;
int levelList[] =
{
kCGDesktopWindowLevelKey,
kCGNormalWindowLevelKey,
kCGScreenSaverWindowLevelKey
};
static int int_pause = 0;
static float winAlpha = 1;
static int mouseHide = FALSE;
static int device_id = 0;
static short fs_res_x = 0;
static short fs_res_y = 0;
static WindowRef theWindow = NULL;
static WindowGroupRef winGroup = NULL;
static CGRect bounds;
static CGDirectDisplayID displayId = 0;
static CFDictionaryRef originalMode = NULL;
static CGDataProviderRef dataProviderRef = NULL;
static CGImageRef image = NULL;
static Rect imgRect; // size of the original image (unscaled)
static Rect dstRect; // size of the displayed image (after scaling)
static Rect winRect; // size of the window containg the displayed image (include padding)
static Rect oldWinRect; // size of the window containg the displayed image (include padding) when NOT in FS mode
static CGRect displayRect; // size of the display device
static Rect oldWinBounds;
static MenuRef windMenu;
static MenuRef movMenu;
static MenuRef aspectMenu;
static int lastScreensaverUpdate = 0;
static int lastMouseHide = 0;
enum
{
kQuitCmd = 1,
kHalfScreenCmd = 2,
kNormalScreenCmd = 3,
kDoubleScreenCmd = 4,
kFullScreenCmd = 5,
kKeepAspectCmd = 6,
kAspectOrgCmd = 7,
kAspectFullCmd = 8,
kAspectWideCmd = 9,
kPanScanCmd = 10
};
#include "osdep/keycodes.h"
//PROTOTYPE/////////////////////////////////////////////////////////////////
static OSStatus KeyEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
static OSStatus MouseEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
static OSStatus WindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
void window_resized();
void window_ontop();
void window_fullscreen();
void window_panscan();
static inline int convert_key(UInt32 key, UInt32 charcode)
{
switch (key)
{
case QZ_IBOOK_ENTER:
case QZ_RETURN: return KEY_ENTER;
case QZ_ESCAPE: return KEY_ESC;
case QZ_BACKSPACE: return KEY_BACKSPACE;
case QZ_LALT: return KEY_BACKSPACE;
case QZ_LCTRL: return KEY_BACKSPACE;
case QZ_LSHIFT: return KEY_BACKSPACE;
case QZ_F1: return KEY_F + 1;
case QZ_F2: return KEY_F + 2;
case QZ_F3: return KEY_F + 3;
case QZ_F4: return KEY_F + 4;
case QZ_F5: return KEY_F + 5;
case QZ_F6: return KEY_F + 6;
case QZ_F7: return KEY_F + 7;
case QZ_F8: return KEY_F + 8;
case QZ_F9: return KEY_F + 9;
case QZ_F10: return KEY_F + 10;
case QZ_F11: return KEY_F + 11;
case QZ_F12: return KEY_F + 12;
case QZ_INSERT: return KEY_INSERT;
case QZ_DELETE: return KEY_DELETE;
case QZ_HOME: return KEY_HOME;
case QZ_END: return KEY_END;
case QZ_KP_PLUS: return '+';
case QZ_KP_MINUS: return '-';
case QZ_TAB: return KEY_TAB;
case QZ_PAGEUP: return KEY_PAGE_UP;
case QZ_PAGEDOWN: return KEY_PAGE_DOWN;
case QZ_UP: return KEY_UP;
case QZ_DOWN: return KEY_DOWN;
case QZ_LEFT: return KEY_LEFT;
case QZ_RIGHT: return KEY_RIGHT;
case QZ_KP_MULTIPLY: return '*';
case QZ_KP_DIVIDE: return '/';
case QZ_KP_ENTER: return KEY_KPENTER;
case QZ_KP_PERIOD: return KEY_KPDEC;
case QZ_KP0: return KEY_KP0;
case QZ_KP1: return KEY_KP1;
case QZ_KP2: return KEY_KP2;
case QZ_KP3: return KEY_KP3;
case QZ_KP4: return KEY_KP4;
case QZ_KP5: return KEY_KP5;
case QZ_KP6: return KEY_KP6;
case QZ_KP7: return KEY_KP7;
case QZ_KP8: return KEY_KP8;
case QZ_KP9: return KEY_KP9;
default: return charcode;
}
}
static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride)
{
switch (image_format)
{
case IMGFMT_RGB32:
vo_draw_alpha_rgb32(w, h, src, srca, stride, image_data + 4 * (y0 * imgRect.right + x0), 4 * imgRect.right);
break;
case IMGFMT_YV12:
case IMGFMT_IYUV:
case IMGFMT_I420:
vo_draw_alpha_yv12(w, h, src, srca, stride, ((char *)P) + be2me_32(P->componentInfoY.offset) + x0 + y0 * imgRect.right, imgRect.right);
break;
case IMGFMT_UYVY:
vo_draw_alpha_uyvy(w, h, src, srca, stride, ((char *)P) + (x0 + y0 * imgRect.right) * 2, imgRect.right * 2);
break;
case IMGFMT_YUY2:
vo_draw_alpha_yuy2(w, h, src, srca, stride, ((char *)P) + (x0 + y0 * imgRect.right) * 2, imgRect.right * 2);
break;
}
}
//default keyboard event handler
static OSStatus KeyEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData)
{
OSStatus result = noErr;
UInt32 class = GetEventClass(event);
UInt32 kind = GetEventKind(event);
result = CallNextEventHandler(nextHandler, event);
if (class == kEventClassKeyboard)
{
char macCharCodes;
UInt32 macKeyCode;
UInt32 macKeyModifiers;
GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(macCharCodes), NULL, &macCharCodes);
GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(macKeyCode), NULL, &macKeyCode);
GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(macKeyModifiers), NULL, &macKeyModifiers);
if (macKeyModifiers != 256)
{
if (kind == kEventRawKeyRepeat || kind == kEventRawKeyDown)
{
int key = convert_key(macKeyCode, macCharCodes);
if (key != -1)
mplayer_put_key(key);
}
}
else if (macKeyModifiers == 256)
{
switch (macCharCodes)
{
case '[': SetWindowAlpha(theWindow, winAlpha -= 0.05); break;
case ']': SetWindowAlpha(theWindow, winAlpha += 0.05); break;
}
}
else
result = eventNotHandledErr;
}
return result;
}
//default mouse event handler
static OSStatus MouseEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData)
{
OSStatus result = noErr;
UInt32 class = GetEventClass(event);
UInt32 kind = GetEventKind(event);
result = CallNextEventHandler(nextHandler, event);
if (class == kEventClassMouse)
{
WindowPtr tmpWin;
Point mousePos;
Point winMousePos;
Ge
|