summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2009-03-14 23:52:45 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2009-03-14 23:52:45 +0200
commitae2faad6669c313b7a5dd318baeee0bffdd47031 (patch)
tree0b383b5dde56d54be4b144e7e23e96bd8bdd43cf /libvo
parentb93f4b7bba0e31d157b74685d3166f74a6c244d7 (diff)
parent642162c07460e439d1d81cda4643dc028ed238e0 (diff)
downloadmpv-ae2faad6669c313b7a5dd318baeee0bffdd47031.tar.bz2
mpv-ae2faad6669c313b7a5dd318baeee0bffdd47031.tar.xz
Merge svn changes up to r28951
Diffstat (limited to 'libvo')
-rw-r--r--libvo/fastmemcpy.h11
-rw-r--r--libvo/font_load_ft.c4
-rw-r--r--libvo/video_out.c4
-rw-r--r--libvo/vo_aa.c8
-rw-r--r--libvo/vo_directfb2.c2
-rw-r--r--libvo/vo_gif89a.c2
-rw-r--r--libvo/vo_gl.c2
-rw-r--r--libvo/vo_gl2.c2
-rw-r--r--libvo/vo_ivtv.c2
-rw-r--r--libvo/vo_jpeg.c2
-rw-r--r--libvo/vo_kva.c1075
-rw-r--r--libvo/vo_macosx.m25
-rw-r--r--libvo/vo_md5sum.c2
-rw-r--r--libvo/vo_png.c2
-rw-r--r--libvo/vo_pnm.c2
-rw-r--r--libvo/vo_sdl.c2
-rw-r--r--libvo/vo_v4l2.c2
-rw-r--r--libvo/vo_vdpau.c3
-rw-r--r--libvo/vo_xv.c4
-rw-r--r--libvo/vo_xvmc.c4
-rw-r--r--libvo/vo_yuv4mpeg.c2
-rw-r--r--libvo/vo_zr2.c2
22 files changed, 1114 insertions, 50 deletions
diff --git a/libvo/fastmemcpy.h b/libvo/fastmemcpy.h
index fa736b62f0..16767d9842 100644
--- a/libvo/fastmemcpy.h
+++ b/libvo/fastmemcpy.h
@@ -23,20 +23,13 @@
#include <inttypes.h>
#include <string.h>
-#ifdef CONFIG_FASTMEMCPY
-#if HAVE_MMX || HAVE_MMX2 || HAVE_AMD3DNOW \
-/* || HAVE_SSE || HAVE_SSE2 */
+#if defined(CONFIG_FASTMEMCPY) && (HAVE_MMX || HAVE_MMX2 || HAVE_AMD3DNOW /* || HAVE_SSE || HAVE_SSE2 */)
#include <stddef.h>
void * fast_memcpy(void * to, const void * from, size_t len);
void * mem2agpcpy(void * to, const void * from, size_t len);
-#else /* HAVE_MMX/MMX2/3DNOW/SSE/SSE2 */
-#define mem2agpcpy(a,b,c) memcpy(a,b,c)
-#define fast_memcpy(a,b,c) memcpy(a,b,c)
-#endif
-
-#else /* CONFIG_FASTMEMCPY */
+#else
#define mem2agpcpy(a,b,c) memcpy(a,b,c)
#define fast_memcpy(a,b,c) memcpy(a,b,c)
#endif
diff --git a/libvo/font_load_ft.c b/libvo/font_load_ft.c
index ac9bcbfa75..38b6178e5c 100644
--- a/libvo/font_load_ft.c
+++ b/libvo/font_load_ft.c
@@ -56,8 +56,8 @@
#endif
char *subtitle_font_encoding = NULL;
-float text_font_scale_factor = 5.0;
-float osd_font_scale_factor = 6.0;
+float text_font_scale_factor = 3.5;
+float osd_font_scale_factor = 4.0;
float subtitle_font_radius = 2.0;
float subtitle_font_thickness = 2.0;
// 0 = no autoscale
diff --git a/libvo/video_out.c b/libvo/video_out.c
index 2791ba54b3..eb348dd086 100644
--- a/libvo/video_out.c
+++ b/libvo/video_out.c
@@ -100,6 +100,7 @@ extern struct vo_driver video_out_mpegpes;
extern struct vo_driver video_out_yuv4mpeg;
extern struct vo_driver video_out_direct3d;
extern struct vo_driver video_out_directx;
+extern struct vo_driver video_out_kva;
extern struct vo_driver video_out_dxr2;
extern struct vo_driver video_out_dxr3;
extern struct vo_driver video_out_ivtv;
@@ -134,6 +135,9 @@ const struct vo_driver *video_out_drivers[] =
#ifdef CONFIG_DIRECT3D
&video_out_direct3d,
#endif
+#ifdef CONFIG_KVA
+ &video_out_kva,
+#endif
#ifdef CONFIG_COREVIDEO
&video_out_macosx,
#endif
diff --git a/libvo/vo_aa.c b/libvo/vo_aa.c
index d0807dc132..48b9f2f2ad 100644
--- a/libvo/vo_aa.c
+++ b/libvo/vo_aa.c
@@ -575,19 +575,19 @@ static int parse_suboptions(const char *arg) {
char *pseudoargv[4], *osdcolor = NULL, *subcolor = NULL, **strings,
*helpmsg = NULL;
int pseudoargc, displayhelp = 0, *booleans;
- opt_t extra_opts[] = {
+ const opt_t extra_opts[] = {
{"osdcolor", OPT_ARG_MSTRZ, &osdcolor, NULL, 0},
{"subcolor", OPT_ARG_MSTRZ, &subcolor, NULL, 0},
{"help", OPT_ARG_BOOL, &displayhelp, NULL, 0} };
opt_t *subopts = NULL, *p;
- char *strings_list[] = {"-driver", "-kbddriver", "-mousedriver", "-font",
+ char * const strings_list[] = {"-driver", "-kbddriver", "-mousedriver", "-font",
"-width", "-height", "-minwidth", "-minheight", "-maxwidth",
"-maxheight", "-recwidth", "-recheight", "-bright", "-contrast",
"-gamma", "-dimmul", "-boldmul", "-random" };
- char *booleans_list[] = {"-dim", "-bold", "-reverse", "-normal",
+ char * const booleans_list[] = {"-dim", "-bold", "-reverse", "-normal",
"-boldfont", "-inverse", "-extended", "-eight", "-dither",
"-floyd_steinberg", "-error_distribution"};
- char *nobooleans_list[] = {"-nodim", "-nobold", "-noreverse", "-nonormal",
+ char * const nobooleans_list[] = {"-nodim", "-nobold", "-noreverse", "-nonormal",
"-noboldfont", "-noinverse", "-noextended", "-noeight", "-nodither",
"-nofloyd_steinberg", "-noerror_distribution"};
const int nstrings = sizeof(strings_list) / sizeof(char*);
diff --git a/libvo/vo_directfb2.c b/libvo/vo_directfb2.c
index 9124ad5dd0..caff687d02 100644
--- a/libvo/vo_directfb2.c
+++ b/libvo/vo_directfb2.c
@@ -175,7 +175,7 @@ static int preinit(const char *arg)
strarg_t mode_str = {0, NULL};
strarg_t par_str = {0, NULL};
strarg_t dfb_params = {0, NULL};
- opt_t subopts[] = {
+ const opt_t subopts[] = {
{"input", OPT_ARG_BOOL, &use_input, NULL},
{"buffermode", OPT_ARG_STR, &mode_str, check_mode},
{"fieldparity", OPT_ARG_STR, &par_str, check_parity},
diff --git a/libvo/vo_gif89a.c b/libvo/vo_gif89a.c
index c51e303a7b..78dd5249fd 100644
--- a/libvo/vo_gif89a.c
+++ b/libvo/vo_gif89a.c
@@ -104,7 +104,7 @@ static char *gif_filename = NULL;
// the default output filename
#define DEFAULT_FILE "out.gif"
-static opt_t subopts[] = {
+static const opt_t subopts[] = {
{"output", OPT_ARG_MSTRZ, &gif_filename, NULL, 0},
{"fps", OPT_ARG_FLOAT, &target_fps, NULL, 0},
{NULL, 0, NULL, NULL, 0}
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 2c9f48d0e1..2e85163833 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -973,7 +973,7 @@ uninit(void)
vo_uninit();
}
-static opt_t subopts[] = {
+static const opt_t subopts[] = {
{"manyfmts", OPT_ARG_BOOL, &many_fmts, NULL},
{"osd", OPT_ARG_BOOL, &use_osd, NULL},
{"scaled-osd", OPT_ARG_BOOL, &scaled_osd, NULL},
diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c
index 66099e16d0..382994e318 100644
--- a/libvo/vo_gl2.c
+++ b/libvo/vo_gl2.c
@@ -844,7 +844,7 @@ uninit(void)
vo_uninit();
}
-static opt_t subopts[] = {
+static const opt_t subopts[] = {
{"yuv", OPT_ARG_INT, &use_yuv, (opt_test_f)int_non_neg},
{"glfinish", OPT_ARG_BOOL, &use_glFinish, NULL},
{NULL}
diff --git a/libvo/vo_ivtv.c b/libvo/vo_ivtv.c
index 38b9ee7f4e..94daaa577b 100644
--- a/libvo/vo_ivtv.c
+++ b/libvo/vo_ivtv.c
@@ -59,7 +59,7 @@ static vo_mpegpes_t *pes;
static int output = -1;
static char *device = NULL;
-static opt_t subopts[] = {
+static const opt_t subopts[] = {
{"output", OPT_ARG_INT, &output, (opt_test_f)int_non_neg},
{"device", OPT_ARG_MSTRZ, &device, NULL},
{NULL}
diff --git a/libvo/vo_jpeg.c b/libvo/vo_jpeg.c
index 3d8fcc77f0..cd6a83a938 100644
--- a/libvo/vo_jpeg.c
+++ b/libvo/vo_jpeg.c
@@ -339,7 +339,7 @@ static int int_zero_hundred(int *val)
static int preinit(const char *arg)
{
- opt_t subopts[] = {
+ const opt_t subopts[] = {
{"progressive", OPT_ARG_BOOL, &jpeg_progressive_mode, NULL, 0},
{"baseline", OPT_ARG_BOOL, &jpeg_baseline, NULL, 0},
{"optimize", OPT_ARG_INT, &jpeg_optimize,
diff --git a/libvo/vo_kva.c b/libvo/vo_kva.c
new file mode 100644
index 0000000000..6b126ed592
--- /dev/null
+++ b/libvo/vo_kva.c
@@ -0,0 +1,1075 @@
+/*
+ * OS/2 video output driver
+ *
+ * Copyright (c) 2007-2009 by KO Myung-Hun (komh@chollian.net)
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define INCL_WIN
+#define INCL_GPI
+#define INCL_DOS
+#include <os2.h>
+
+#include <mmioos2.h>
+#include <fourcc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+
+#include <kva.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+#include "video_out.h"
+#include "video_out_internal.h"
+#include "aspect.h"
+
+#include "fastmemcpy.h"
+#include "mp_fifo.h"
+#include "osdep/keycodes.h"
+#include "input/input.h"
+#include "input/mouse.h"
+#include "subopt-helper.h"
+#include "sub.h"
+
+#include "cpudetect.h"
+#include "libswscale/swscale.h"
+#include "libmpcodecs/vf_scale.h"
+
+static const vo_info_t info = {
+ "SNAP/WarpOverlay!/DIVE video output",
+ "kva",
+ "KO Myung-Hun <komh@chollian.net>",
+ ""
+};
+
+LIBVO_EXTERN(kva)
+
+#define WC_MPLAYER "WC_MPLAYER"
+
+#define SRC_WIDTH m_int.kvas.szlSrcSize.cx
+#define SRC_HEIGHT m_int.kvas.szlSrcSize.cy
+
+#define HWNDFROMWINID(wid) ((wid) + 0x80000000UL)
+
+static const struct keymap m_vk_map[] = {
+ {VK_NEWLINE, KEY_ENTER}, {VK_TAB, KEY_TAB}, {VK_SPACE, ' '},
+
+ // control keys
+ {VK_CTRL, KEY_CTRL}, {VK_BACKSPACE, KEY_BS},
+ {VK_DELETE, KEY_DELETE}, {VK_INSERT, KEY_INSERT},
+ {VK_HOME, KEY_HOME}, {VK_END, KEY_END},
+ {VK_PAGEUP, KEY_PAGE_UP}, {VK_PAGEDOWN, KEY_PAGE_DOWN},
+ {VK_ESC, KEY_ESC},
+
+ // cursor keys
+ {VK_RIGHT, KEY_RIGHT}, {VK_LEFT, KEY_LEFT},
+ {VK_DOWN, KEY_DOWN}, {VK_UP, KEY_UP},
+
+ // function keys
+ {VK_F1, KEY_F+1}, {VK_F2, KEY_F+2}, {VK_F3, KEY_F+3}, {VK_F4, KEY_F+4},
+ {VK_F5, KEY_F+5}, {VK_F6, KEY_F+6}, {VK_F7, KEY_F+7}, {VK_F8, KEY_F+8},
+ {VK_F9, KEY_F+9}, {VK_F10, KEY_F+10}, {VK_F11, KEY_F+11}, {VK_F12, KEY_F+12},
+
+ {0, 0}
+};
+
+static const struct keymap m_keypad_map[] = {
+ // keypad keys
+ {0x52, KEY_KP0}, {0x4F, KEY_KP1}, {0x50, KEY_KP2}, {0x51, KEY_KP3},
+ {0x4B, KEY_KP4}, {0x4C, KEY_KP5}, {0x4D, KEY_KP6}, {0x47, KEY_KP7},
+ {0x48, KEY_KP8}, {0x49, KEY_KP9}, {0x53, KEY_KPDEC}, {0x5A, KEY_KPENTER},
+
+ {0, 0}
+};
+
+static const struct keymap m_mouse_map[] = {
+ {WM_BUTTON1DOWN, MOUSE_BTN0},
+ {WM_BUTTON3DOWN, MOUSE_BTN1},
+ {WM_BUTTON2DOWN, MOUSE_BTN2},
+ {WM_BUTTON1DBLCLK, MOUSE_BTN0_DBL},
+ {WM_BUTTON3DBLCLK, MOUSE_BTN1_DBL},
+ {WM_BUTTON2DBLCLK, MOUSE_BTN2_DBL},
+
+ {0, 0}
+};
+
+struct {
+ HAB hab;
+ HMQ hmq;
+ HWND hwndFrame;
+ HWND hwndClient;
+ HWND hwndSysMenu;
+ HWND hwndTitleBar;
+ HWND hwndMinMax;
+ FOURCC fcc;
+ int iImageFormat;
+ int nChromaShift;
+ KVASETUP kvas;
+ KVACAPS kvac;
+ RECTL rclDst;
+ int bpp;
+ LONG lStride;
+ PBYTE pbImage;
+ BOOL fFixT23;
+ PFNWP pfnwpOldFrame;
+ uint8_t *planes[3]; // y = 0, u = 1, v = 2
+ int stride[3];
+ BOOL fHWAccel;
+ RECTL rclParent;
+ struct SwsContext *sws;
+} m_int;
+
+static inline void setAspectRatio(ULONG ulRatio)
+{
+ m_int.kvas.ulRatio = ulRatio;
+ kvaSetup(&m_int.kvas);
+}
+
+static int query_format_info(int format, PBOOL pfHWAccel, PFOURCC pfcc,
+ int *pbpp, int *pnChromaShift)
+{
+ BOOL fHWAccel;
+ FOURCC fcc;
+ INT bpp;
+ INT nChromaShift;
+
+ switch (format) {
+ case IMGFMT_YV12:
+ fHWAccel = m_int.kvac.ulInputFormatFlags & KVAF_YV12;
+ fcc = FOURCC_YV12;
+ bpp = 1;
+ nChromaShift = 1;
+ break;
+
+ case IMGFMT_YUY2:
+ fHWAccel = m_int.kvac.ulInputFormatFlags & KVAF_YUY2;
+ fcc = FOURCC_Y422;
+ bpp = 2;
+ nChromaShift = 0;
+ break;
+
+ case IMGFMT_YVU9:
+ fHWAccel = m_int.kvac.ulInputFormatFlags & KVAF_YVU9;
+ fcc = FOURCC_YVU9;
+ bpp = 1;
+ nChromaShift = 2;
+ break;
+
+ case IMGFMT_BGR24:
+ fHWAccel = m_int.kvac.ulInputFormatFlags & KVAF_BGR24;
+ fcc = FOURCC_BGR3;
+ bpp = 3;
+ nChromaShift = 0;
+ break;
+
+ case IMGFMT_BGR16:
+ fHWAccel = m_int.kvac.ulInputFormatFlags & KVAF_BGR16;
+ fcc = FOURCC_R565;
+ bpp = 2;
+ nChromaShift = 0;
+ break;
+
+ case IMGFMT_BGR15:
+ fHWAccel = m_int.kvac.ulInputFormatFlags & KVAF_BGR15;
+ fcc = FOURCC_R555;
+ bpp = 2;
+ nChromaShift = 0;
+ break;
+
+ default:
+ return 1;
+ }
+
+ if (pfHWAccel)
+ *pfHWAccel = fHWAccel;
+
+ if (pfcc)
+ *pfcc = fcc;
+
+ if (pbpp)
+ *pbpp = bpp;
+
+ if (pnChromaShift)
+ *pnChromaShift = nChromaShift;
+
+ return 0;
+}
+
+static void imgCreate(void)
+{
+ int size = SRC_HEIGHT * m_int.lStride;;
+
+ switch (m_int.iImageFormat) {
+ case IMGFMT_YV12:
+ size += size / 2;
+ break;
+
+ case IMGFMT_YVU9:
+ size += size / 8;
+ break;
+ }
+
+ m_int.pbImage = malloc(size);
+
+ m_int.planes[0] = m_int.pbImage;
+ m_int.stride[0] = m_int.lStride;
+
+ // YV12 or YVU9 ?
+ if (m_int.nChromaShift) {
+ m_int.planes[1] = m_int.planes[0] + SRC_HEIGHT * m_int.stride[0];
+ m_int.stride[1] = m_int.stride[0] >> m_int.nChromaShift;
+
+ m_int.planes[2] = m_int.planes[1] +
+ (SRC_HEIGHT >> m_int.nChromaShift) * m_int.stride[1];
+ m_int.stride[2] = m_int.stride[1];
+ }
+}
+
+static void imgFree(void)
+{
+ free(m_int.pbImage);
+
+ m_int.pbImage = NULL;
+}
+
+static void imgDisplay(void)
+{
+ PVOID pBuffer;
+ ULONG ulBPL;
+
+ if (!kvaLockBuffer(&pBuffer, &ulBPL)) {
+ uint8_t *dst[3];
+ int dstStride[3];
+
+ // Get packed or Y
+ dst[0] = pBuffer;
+ dstStride[0] = ulBPL;
+
+ // YV12 or YVU9 ?
+ if (m_int.nChromaShift) {
+ // Get V
+ dst[2] = dst[0] + SRC_HEIGHT * dstStride[0];
+ dstStride[2] = dstStride[0] >> m_int.nChromaShift;
+
+ // Get U
+ dst[1] = dst[2] +
+ (SRC_HEIGHT >> m_int.nChromaShift ) * dstStride[2];
+ dstStride[1] = dstStride[2];
+ }
+
+ if (m_int.fHWAccel) {
+ int w, h;
+
+ w = m_int.stride[0];
+ h = SRC_HEIGHT;
+
+ // Copy packed or Y
+ mem2agpcpy_pic(dst[0], m_int.planes[0], w, h,
+ dstStride[0], m_int.stride[0]);
+
+ // YV12 or YVU9 ?
+ if (m_int.nChromaShift) {
+ w >>= m_int.nChromaShift; h >>= m_int.nChromaShift;
+
+ // Copy U
+ mem2agpcpy_pic(dst[1], m_int.planes[1], w, h,
+ dstStride[1], m_int.stride[1]);
+
+ // Copy V
+ mem2agpcpy_pic(dst[2], m_int.planes[2], w, h,
+ dstStride[2], m_int.stride[2]);
+ }
+ } else {
+ sws_scale(m_int.sws, m_int.planes, m_int.stride, 0, SRC_HEIGHT,
+ dst, dstStride);
+ }
+
+ kvaUnlockBuffer();
+ }
+}
+
+// Frame window procedure to work around T23 laptop with S3 video card,
+// which supports upscaling only.
+static MRESULT EXPENTRY NewFrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
+ MPARAM mp2)
+{
+ switch (msg) {
+ case WM_QUERYTRACKINFO:
+ {
+ PTRACKINFO pti = (PTRACKINFO)mp2;
+ RECTL rcl;
+
+ if (vo_fs)
+ break;
+
+ m_int.pfnwpOldFrame(hwnd, msg, mp1, mp2);
+
+ rcl.xLeft = 0;
+ rcl.yBottom = 0;
+ rcl.xRight = SRC_WIDTH + 1;
+ rcl.yTop = SRC_HEIGHT + 1;
+
+ WinCalcFrameRect(hwnd, &rcl, FALSE);
+
+ pti->ptlMinTrackSize.x = rcl.xRight - rcl.xLeft;
+ pti->ptlMinTrackSize.y = rcl.yTop - rcl.yBottom;
+
+ pti->ptlMaxTrackSize.x = vo_screenwidth;
+ pti->ptlMaxTrackSize.y = vo_screenheight;
+
+ return (MRESULT)TRUE;
+ }
+
+ case WM_ADJUSTWINDOWPOS:
+ {
+ PSWP pswp = (PSWP)mp1;
+ RECTL rcl;
+
+ if (vo_fs)
+ break;
+
+ if (pswp->fl & SWP_SIZE) {
+ rcl.xLeft = pswp->x;
+ rcl.yBottom = pswp->y;
+ rcl.xRight = rcl.xLeft + pswp->cx;
+ rcl.yTop = rcl.yBottom + pswp->cy;
+
+ WinCalcFrameRect(hwnd, &rcl, TRUE);
+
+ if (rcl.xRight - rcl.xLeft <= SRC_WIDTH)
+ rcl.xRight = rcl.xLeft + (SRC_WIDTH + 1);
+
+ if (rcl.yTop - rcl.yBottom <= SRC_HEIGHT)
+ rcl.yTop = rcl.yBottom + (SRC_HEIGHT + 1);
+
+ WinCalcFrameRect(hwnd, &rcl, FALSE);
+
+ if (rcl.xRight - rcl.xLeft > vo_screenwidth) {
+ rcl.xLeft = 0;
+ rcl.xRight = vo_screenwidth;
+ }
+
+ if (rcl.yTop - rcl.yBottom > vo_screenheight) {
+ rcl.yBottom = 0;
+ rcl.yTop = vo_screenheight;
+ }
+
+ pswp->fl |= SWP_MOVE;
+ pswp->x = rcl.xLeft;
+ pswp->y = rcl.yBottom;
+ pswp->cx = rcl.xRight - rcl.xLeft;
+ pswp->cy = rcl.yTop - rcl.yBottom;
+ }
+ break;
+ }
+ }
+
+ return m_int.pfnwpOldFrame(hwnd, msg, mp1, mp2);
+}
+
+static MRESULT EXPENTRY WndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+ // if slave mode, ignore mouse events and deliver them to a parent window
+ if (WinID != -1 &&
+ ((msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST) ||
+ (msg >= WM_EXTMOUSEFIRST && msg <= WM_EXTMOUSELAST))) {
+ WinPostMsg(HWNDFROMWINID(WinID), msg, mp1, mp2);
+
+ return (MRESULT)TRUE;
+ }
+
+ switch (msg) {
+ case WM_CLOSE:
+ mplayer_put_key(KEY_CLOSE_WIN);
+
+ return 0;
+
+ case WM_CHAR:
+ {
+ USHORT fsFlags = SHORT1FROMMP(mp1);
+ UCHAR uchScan = CHAR4FROMMP(mp1);
+ USHORT usCh = SHORT1FROMMP(mp2);
+ USHORT usVk = SHORT2FROMMP(mp2);
+ int mpkey;
+
+ if (fsFlags & KC_KEYUP)
+ break;
+
+ if (fsFlags & KC_SCANCODE) {
+ mpkey = lookup_keymap_table(m_keypad_map, uchScan);
+ if (mpkey) {
+ // distinguish KEY_KP0 and KEY_KPINS
+ if (mpkey == KEY_KP0 && usCh != '0')
+ mpkey = KEY_KPINS;
+
+ // distinguish KEY_KPDEC and KEY_KPDEL
+ if (mpkey == KEY_KPDEC && usCh != '.')
+ mpkey = KEY_KPDEL;
+
+ mplayer_put_key(mpkey);
+
+ return (MRESULT)TRUE;
+ }
+ }
+
+ if (fsFlags & KC_VIRTUALKEY) {
+ mpkey = lookup_keymap_table(m_vk_map, usVk);
+ if (mpkey) {
+ mplayer_put_key(mpkey);
+
+ return (MRESULT)TRUE;
+ }
+ }
+
+ if ((fsFlags & KC_CHAR) && !HIBYTE(usCh))
+ mplayer_put_key(usCh);
+
+ return (MRESULT)TRUE;
+ }
+
+ case WM_BUTTON1DOWN:
+ case WM_BUTTON3DOWN:
+ case WM_BUTTON2DOWN:
+ case WM_BUTTON1DBLCLK:
+ case WM_BUTTON3DBLCLK:
+ case WM_BUTTON2DBLCLK:
+ if (WinQueryFocus(HWND_DESKTOP) != hwnd)
+ WinSetFocus(HWND_DESKTOP, hwnd);
+ else if (!vo_nomouse_input)
+ mplayer_put_key(lookup_keymap_table(m_mouse_map, msg));
+
+ return (MRESULT)TRUE;
+
+ case WM_PAINT:
+ {
+ HPS hps;
+ RECTL rcl, rclDst;
+ PRECTL prcl = NULL;
+ HRGN hrgn, hrgnDst;
+ RGNRECT rgnCtl;
+
+ // get a current movie area
+ kvaAdjustDstRect(&m_int.kvas.rclSrcRect, &rclDst);
+
+ // get a current invalidated area
+ hps = WinBeginPaint(hwnd, NULLHANDLE, &rcl);
+
+ // create a region for an invalidated area
+ hrgn = GpiCreateRegion(hps, 1, &rcl);
+ // create a region for a movie area
+ hrgnDst = GpiCreateRegion(hps, 1, &rclDst);
+
+ // exclude a movie area from an invalidated area
+ GpiCombineRegion(hps, hrgn, hrgn, hrgnDst, CRGN_DIFF);
+
+ // get rectangles from the region
+ rgnCtl.ircStart = 1;
+ rgnCtl.ulDirection = RECTDIR_LFRT_TOPBOT;
+ GpiQueryRegionRects(hps, hrgn, NULL, &rgnCtl, NULL);
+
+ if (rgnCtl.crcReturned > 0) {
+ rgnCtl.crc = rgnCtl.crcReturned;
+ prcl = malloc(sizeof(RECTL) * rgnCtl.crcReturned);
+ }
+
+ // draw black bar if needed
+ if (prcl && GpiQueryRegionRects(hps, hrgn, NULL, &rgnCtl, prcl)) {
+ int i;
+
+ for (i = 0; i < rgnCtl.crcReturned; i++)
+ WinFillRect(hps, &prcl[i], CLR_BLACK);
+ }
+
+ free(prcl);
+
+ GpiDestroyRegion(hps, hrgnDst);
+ GpiDestroyRegion(hps, hrgn);
+
+ WinEndPaint(hps);
+
+ return 0;
+ }
+ }
+
+ return WinDefWindowProc(hwnd, msg, mp1, mp2);
+}
+
+// Change process type from VIO to PM to use PM APIs.
+static void morphToPM(void)
+{
+ PPIB pib;
+
+ DosGetInfoBlocks(NULL, &pib);
+
+ // Change flag from VIO to PM:
+ if (pib->pib_ultype == 2)
+ pib->pib_ultype = 3;
+}
+
+static int preinit(const char *arg)
+{
+ HWND hwndParent;
+ ULONG flFrameFlags;
+ ULONG kvaMode = 0;
+
+ int fUseSnap = 0;
+ int fUseWO = 0;
+ int fUseDive = 0;
+ int fFixT23 = 0;
+
+ const opt_t subopts[] = {
+ {"snap", OPT_ARG_BOOL, &fUseSnap, NULL},
+ {"wo", OPT_ARG_BOOL, &fUseWO, NULL},
+ {"dive", OPT_ARG_BOOL, &fUseDive, NULL},
+ {"t23", OPT_ARG_BOOL, &fFixT23, NULL},
+ {NULL, 0, NULL, NULL}
+ };
+
+ PCSZ pcszVideoModeStr[3] = {"DIVE", "WarpOverlay!", "SNAP"};
+
+ if (subopt_parse(arg, subopts) != 0)
+ return -1;
+
+ morphToPM();
+
+ memset(&m_int, 0, sizeof(m_int));
+
+ m_int.hab = WinInitialize(0);
+ m_int.hmq = WinCreateMsgQueue(m_int.hab, 0);
+
+ WinRegisterClass(m_int.hab,
+ WC_MPLAYER,
+ WndProc,
+ CS_SIZEREDRAW | CS_MOVENOTIFY,
+ sizeof(PVOID));
+
+ if (WinID == -1) {
+ hwndParent = HWND_DESKTOP;
+ flFrameFlags = FCF_SYSMENU | FCF_TITLEBAR | FCF_MINMAX |
+ FCF_SIZEBORDER | FCF_TASKLIST;
+ } else {
+ hwndParent = HWNDFROMWINID(WinID);
+ flFrameFlags = 0;
+ }
+
+ m_int.hwndFrame =
+ WinCreateStdWindow(hwndParent, // parent window handle
+ WS_VISIBLE, // frame window style
+ &flFrameFlags, // window style
+ WC_MPLAYER, // class name
+ "", // window title
+ 0L, // default client style
+ NULLHANDLE, // resource in exe file
+ 1, // frame window id
+ &m_int.hwndClient); // client window handle
+
+ if (m_int.hwndFrame == NULLHANDLE)
+ return -1;
+
+ m_int.hwndSysMenu = WinWindowFromID(m_int.hwndFrame, FID_SYSMENU);
+ m_int.hwndTitleBar = WinWindowFromID(m_int.hwndFrame, FID_TITLEBAR);
+ m_int.hwndMinMax = WinWindowFromID(m_int.hwndFrame, FID_MINMAX);
+
+ m_int.fFixT23 = fFixT23;
+
+ if (m_int.fFixT23)
+ m_int.pfnwpOldFrame = WinSubclassWindow(m_int.hwndFrame,
+ NewFrameWndProc);
+
+ if (!!fUseSnap + !!fUseWO + !!fUseDive > 1)
+ mp_msg(MSGT_VO, MSGL_WARN,"KVA: Multiple mode specified!!!\n");
+
+ if (fUseSnap)
+ kvaMode = KVAM_SNAP;
+ else if (fUseWO)
+ kvaMode = KVAM_WO;
+ else if (fUseDive)
+ kvaMode = KVAM_DIVE;
+ else
+ kvaMode = KVAM_AUTO;
+
+ if (kvaInit(kvaMode, m_int.hwndClient, vo_colorkey)) {
+ mp_msg(MSGT_VO, MSGL_ERR, "KVA: Init failed!!!\n");
+
+ return -1;
+ }
+
+ kvaCaps(&m_int.kvac);
+
+ mp_msg(MSGT_VO, MSGL_V, "KVA: Selected video mode = %s\n",
+ pcszVideoModeStr[m_int.kvac.ulMode - 1]);
+
+ kvaDisableScreenSaver();
+
+ // Might cause PM DLLs to be loaded which incorrectly enable SIG_FPE,
+ // so mask off all floating-point exceptions.
+ _control87(MCW_EM, MCW_EM);
+
+ return 0;
+}
+
+static void uninit(void)
+{
+ kvaEnableScreenSaver();
+
+ imgFree();
+
+ sws_freeContext(m_int.sws);
+
+ if (m_int.hwndFrame != NULLHANDLE) {
+ kvaResetAttr();
+ kvaDone();
+
+ if (m_int.fFixT23)
+ WinSubclassWindow(m_int.hwndFrame, m_int.pfnwpOldFrame);
+
+ WinDestroyWindow(m_int.hwndFrame);
+ }
+
+ WinDestroyMsgQueue(m_int.hmq);
+ WinTerminate(m_int.hab);
+}
+
+static int config(uint32_t width, uint32_t height,
+ uint32_t d_width, uint32_t d_height,
+ uint32_t flags, char *title, uint32_t format)
+{
+ RECTL rcl;
+
+ mp_msg(MSGT_VO, MSGL_V,
+ "KVA: Using 0x%X (%s) image format, vo_config_count = %d\n",
+ format, vo_format_name(format), vo_config_count);
+
+ imgFree();
+
+ if (query_format_info(format, &m_int.fHWAccel, &m_int.fcc, &m_int.bpp,
+ &m_int.nChromaShift))
+ return 1;
+
+ m_int.iImageFormat = format;
+
+ // if there is no hw accel for given format,
+ // try any format supported by hw accel
+ if (!m_int.fHWAccel) {
+ int dstFormat = 0;
+
+ sws_freeContext(m_int.sws);
+
+ if (m_int.kvac.ulInputFormatFlags & KVAF_YV12)
+ dstFormat = IMGFMT_YV12;
+ else if (m_int.kvac.ulInputFormatFlags & KVAF_YUY2)
+ dstFormat = IMGFMT_YUY2;
+ else if (m_int.kvac.ulInputFormatFlags & KVAF_YVU9)
+ dstFormat = IMGFMT_YVU9;
+ else if (m_int.kvac.ulInputFormatFlags & KVAF_BGR24)
+ dstFormat = IMGFMT_BGR24;
+ else if (m_int.kvac.ulInputFormatFlags & KVAF_BGR16)
+ dstFormat = IMGFMT_BGR16;
+ else if (m_int.kvac.ulInputFormatFlags & KVAF_BGR15)
+ dstFormat = IMGFMT_BGR15;
+
+ if (query_format_info(dstFormat, NULL, &m_int.fcc, NULL, NULL))
+ return 1;
+
+ m_int.sws = sws_getContextFromCmdLine(width, height, format,
+ width, height, dstFormat);
+ }
+
+ mp_msg(MSGT_VO, MSGL_V, "KVA: Selected FOURCC = %.4s\n", (char *)&m_int.fcc);
+
+ m_int.kvas.ulLength = sizeof(KVASETUP);
+ m_int.kvas.szlSrcSize.cx = width;
+ m_int.kvas.szlSrcSize.cy = height;
+ m_int.kvas.rclSrcRect.xLeft = 0;
+ m_int.kvas.rclSrcRect.yTop = 0;
+ m_int.kvas.rclSrcRect.xRight = width;
+ m_int.kvas.rclSrcRect.yBottom = height;
+ m_int.kvas.ulRatio = vo_keepaspect ? KVAR_FORCEANY : KVAR_NONE;
+ m_int.kvas.ulAspectWidth = d_width;
+ m_int.kvas.ulAspectHeight = d_height;
+ m_int.kvas.fccSrcColor = m_int.fcc;
+ m_int.kvas.fDither = TRUE;
+
+ if (kvaSetup(&m_int.kvas)) {
+ mp_msg(MSGT_VO, MSGL_ERR, "KVA: Setup failed!!!\n");
+
+ return 1;
+ }
+
+ m_int.lStride = width * m_int.bpp;
+
+ imgCreate();
+
+ if (WinID == -1) {
+ WinSetWindowText(m_int.hwndFrame, title);
+
+ // initialize 'vo_fs' only once at first config() call
+ if (vo_config_count == 0)
+ vo_fs = flags & VOFLAG_FULLSCREEN;
+
+ // workaround for T23 laptop w