123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964 |
- #include <windows.h>
- #include <ddraw.h>
- #include "main.h"
- #include "video.h"
- #include "subtitles.h"
- #include "resource.h"
- #undef GetSystemMetrics
- #define OSD_ENABLED 1
- #define INIT_DIRECTDRAW_STRUCT(x) (ZeroMemory(&x, sizeof(x)), x.dwSize=sizeof(x))
- #define OV_COL_R 16
- #define OV_COL_G 0
- #define OV_COL_B 16
- #define OSD_TEXT_SIZE 28
- #define OSD_TEXT_R 192
- #define OSD_TEXT_G 192
- #define OSD_TEXT_B 192
- #define OSD_TEXT_R_HILITE 255
- #define OSD_TEXT_G_HILITE 255
- #define OSD_TEXT_B_HILITE 255
- #define OSD_VOL_COL_R 0
- #define OSD_VOL_COL_G 0
- #define OSD_VOL_COL_B 192
- #define OSD_VOL_BKCOL_R 0
- #define OSD_VOL_BKCOL_G 0
- #define OSD_VOL_BKCOL_B 64
- #define TIMER_OSD_ID 1234
- #define CTRLTYPE_SYMBOL 0
- #define CTRLTYPE_TEXT 1
- #define CTRLTYPE_PROGRESS 2
- #define CTRLTYPE_SPACER 3
- #define CTRL_PROGRESSTEXT 0
- #define CTRL_PROGRESS 1
- #define CTRL_PROGRESSSPACER 2
- #define CTRL_REW 3
- #define CTRL_PLAY 4
- #define CTRL_PAUSE 5
- #define CTRL_STOP 6
- #define CTRL_FFWD 7
- #define CTRL_VOLSPACER 8
- #define CTRL_VOLTEXT 9
- #define CTRL_VOL 10
- int g_ctrl_type[NUM_WIDGETS] = {
- CTRLTYPE_TEXT,
- CTRLTYPE_PROGRESS,
- CTRLTYPE_SPACER,
- CTRLTYPE_SYMBOL,
- CTRLTYPE_SYMBOL,
- CTRLTYPE_SYMBOL,
- CTRLTYPE_SYMBOL,
- CTRLTYPE_SYMBOL,
- CTRLTYPE_SPACER,
- CTRLTYPE_TEXT,
- CTRLTYPE_PROGRESS
- };
- const char *g_ctrl_text[NUM_WIDGETS] = {
- "Progress ",
- "",
- "",
- "7", // rew
- "4", // play
- ";", // pause
- "<", // stop
- "8", // ffwd
- "",
- "Volume ",
- ""
- };
- int g_ctrl_force_width[NUM_WIDGETS] = {
- 0,
- 96, // progress bar width
- 32, // spacer width
- 0, // rew
- 0, // play
- 0, // pause
- 0, // stop
- 0, // ffwd
- 32, // spacer width
- 0,
- 64 // volume bar width
- };
- extern HINSTANCE g_hInstance;
- extern int g_bitmap_id;
- static BOOL WINAPI DDEnumCallbackEx(GUID FAR *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext, HMONITOR hm) {
- VideoOutputChild *ovo=(VideoOutputChild *)lpContext;
- if(ovo->m_found_devguid) return 1;
- if(hm==ovo->m_monitor_to_find) {
- ovo->m_devguid=*lpGUID;
- ovo->m_found_devguid=1;
- }
- return 1;
- }
- void VideoOutputChild::update_monitor_coords(VideoOutput *parent)
- {
- //find the correct monitor if multiple monitor support is present
- HWND hwnd=parent->getHwnd();
- m_found_devguid=0;
- m_mon_x=0;
- m_mon_y=0;
- HINSTANCE h=LoadLibrary("user32.dll");
- if (h) {
- HMONITOR (WINAPI *Mfp)(POINT pt, DWORD dwFlags) = (HMONITOR (WINAPI *)(POINT,DWORD)) GetProcAddress(h,"MonitorFromPoint");
- HMONITOR (WINAPI *Mfr)(LPCRECT lpcr, DWORD dwFlags) = (HMONITOR (WINAPI *)(LPCRECT, DWORD)) GetProcAddress(h, "MonitorFromRect");
- HMONITOR (WINAPI *Mfw)(HWND wnd, DWORD dwFlags)=(HMONITOR (WINAPI *)(HWND, DWORD)) GetProcAddress(h, "MonitorFromWindow");
- BOOL (WINAPI *Gmi)(HMONITOR mon, LPMONITORINFO lpmi) = (BOOL (WINAPI *)(HMONITOR,LPMONITORINFO)) GetProcAddress(h,"GetMonitorInfoA");
- if (Mfp && Mfr && Mfw && Gmi) {
- RECT r;
- GetWindowRect(hwnd,&r);
- HMONITOR hm=Mfr(&r,NULL);
- if(hm) {
- HINSTANCE hdd = LoadLibrary("ddraw.dll");
- if(hdd) {
- typedef BOOL (FAR PASCAL * LPDDENUMCALLBACKEXA)(GUID FAR *, LPSTR, LPSTR, LPVOID, HMONITOR);
- typedef HRESULT (WINAPI * LPDIRECTDRAWENUMERATEEX)( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
- LPDIRECTDRAWENUMERATEEX lpDDEnumEx;
- lpDDEnumEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(hdd,"DirectDrawEnumerateExA");
- if (lpDDEnumEx) {
- m_monitor_to_find=hm;
- lpDDEnumEx(&DDEnumCallbackEx, this, DDENUM_ATTACHEDSECONDARYDEVICES|DDENUM_NONDISPLAYDEVICES);
- if(m_found_devguid) {
- MONITORINFOEX mi;
- memset(&mi,0,sizeof(mi));
- mi.cbSize=sizeof(mi);
- if (Gmi(hm,&mi)) {
- m_mon_x=mi.rcMonitor.left;
- m_mon_y=mi.rcMonitor.top;
- }
- }
- }
- FreeLibrary(hdd);
- }
- }
- }
- FreeLibrary(h);
- }
- }
- int VideoOutput::get_latency()
- {
- return vid_vsync?15:0;
- }
- #undef GetSystemMetrics
- int VideoOutput::class_refcnt=0;
- void VideoOutput::adjustAspect(RECT &rd)
- {
- if (vid_aspectadj)
- {
- int outh=rd.bottom-rd.top;
- int outw=rd.right-rd.left;
- int newh=(int)((aspect*height*outw)/(double)width);
- int neww=(int)((width*outh)/(height*aspect));
- if (outh > newh) // black bars on top and bottom
- {
- int d=outh - newh;
- rd.top+=d/2;
- rd.bottom-=d-d/2;
- }
- else if (outw > neww) // black bars on left and right
- {
- int d=outw - neww;
- rd.left+=d/2;
- rd.right-=d-d/2;
- }
- }
- }
- LRESULT CALLBACK VideoOutput::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- if (uMsg == WM_CREATE)
- {
- SetWindowLong(hwnd,GWL_USERDATA,(long)((CREATESTRUCT *)lParam)->lpCreateParams);
- ShowWindow(hwnd,SW_SHOW);
- if (GetParent(hwnd))
- {
- RECT r;
- GetClientRect(GetParent(hwnd),&r);
- SetWindowPos(hwnd,NULL,0,0,
- r.right,
- r.bottom,
- SWP_NOACTIVATE|SWP_NOZORDER);
- }
- return 0;
- }
- VideoOutput *_This=(VideoOutput*)GetWindowLong(hwnd,GWL_USERDATA);
- if (_This) return _This->WindowProc(hwnd,uMsg,wParam,lParam);
- else return DefWindowProc(hwnd,uMsg,wParam,lParam);
- }
- void VideoOutput::notifyBufferState(int bufferstate) /* 0-255*/
- {
- m_bufferstate=bufferstate;
- #ifdef ACTIVEX_CONTROL
- PostMessage( video_hwnd, STATUS_MSG, STATUS_PREBUFFER, bufferstate );
- #endif
- if (!m_video_output) {
- if(GetTickCount()-m_lastbufinvalid>500) {
- InvalidateRect(video_hwnd,NULL,FALSE);
- m_lastbufinvalid=GetTickCount();
- }
- }
- }
- LRESULT VideoOutput::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_TIMER:
- case WM_WINDOWPOSCHANGING:
- case WM_WINDOWPOSCHANGED:
- case WM_SIZE:
- case WM_MOVE:
- case WM_MOVING:
- if (uMsg == WM_TIMER && wParam == TIMER_OSD_ID) {
- hideOSD();
- return 0;
- }
- EnterCriticalSection(&m_cs);
- if(m_video_output) m_video_output->timerCallback();
- LeaveCriticalSection(&m_cs);
- if (uMsg == WM_TIMER) return 0;
- break;
- case WM_LBUTTONDOWN:
- if(is_fs)
- osdHitTest(LOWORD(lParam),HIWORD(lParam),0);
- #ifdef ACTIVEX_CONTROL
- SendMessage( video_hwnd, STATUS_MSG, STATUS_MOUSEPRESS, 1 );
- #endif
- break;
-
- case WM_PAINT:
- {
- if (m_video_output && m_video_output->onPaint(hwnd,(HDC)wParam)) return 0;
- if (m_logo && !m_video_output)
- {
- PAINTSTRUCT p;
- BeginPaint(hwnd,&p);
- RECT r;
- GetClientRect(hwnd,&r);
-
- HDC out=p.hdc;
- HDC dc=CreateCompatibleDC(NULL);
- SelectObject(dc,m_logo);
- int xp=(r.right-r.left-m_logo_w)/2;
- int yp=(r.bottom-r.top-m_logo_h)/2;
- BitBlt(out,xp,yp,m_logo_w,m_logo_h,dc,0,0,SRCCOPY);
- int bs=m_bufferstate;
- if (bs < 16) bs=16;
- HGDIOBJ oldobj1=SelectObject(out,CreateSolidBrush(RGB(0,0,0)));
- HGDIOBJ oldobj2=SelectObject(out,CreatePen(PS_SOLID,0,RGB(0,0,0)));
- Rectangle(out,r.left,r.top,r.right,yp);
- if (m_statusmsg)
- Rectangle(out,r.left,yp+m_logo_h,r.right,r.bottom);
- else
- {
- Rectangle(out,r.left,yp+m_logo_h+2+9,r.right,r.bottom);
- Rectangle(out,xp + ((bs * (m_logo_w+2))>>8),yp+m_logo_h+2,r.right, yp+9+m_logo_h+2);
- }
- Rectangle(out,r.left,yp,xp-1,yp+m_logo_h+9+2);
- Rectangle(out,xp+m_logo_w+1,yp,r.right,yp+m_logo_h+2);
- DeleteObject(SelectObject(out,oldobj2));
- DeleteObject(SelectObject(out,oldobj1));
- if (m_statusmsg)
- {
- RECT subr={0,yp+m_logo_h+2,r.right,r.bottom};
- SetTextColor(out,RGB(255,255,255));
- SetBkMode(out,TRANSPARENT);
- DrawText(out,m_statusmsg,-1,&subr,DT_TOP|DT_CENTER|DT_NOCLIP|DT_NOPREFIX);
- }
- else
- {
- yp+=m_logo_h+2;
- if (bs)
- {
- HGDIOBJ oldobj1=SelectObject(out,CreateSolidBrush(RGB(128,128,128)));
- HGDIOBJ oldobj2=SelectObject(out,CreatePen(PS_SOLID,0,RGB(255,255,255)));
- Rectangle(out,xp-1,yp,xp + ((bs * (m_logo_w+2))>>8), yp+9);
- DeleteObject(SelectObject(out,oldobj2));
- DeleteObject(SelectObject(out,oldobj1));
- }
- }
- DeleteDC(dc);
- EndPaint(hwnd,&p);
- return 0;
- }
- }
- break;
- case WM_USER+0x1:
- m_need_change=1;
- break;
- #ifdef ACTIVEX_CONTROL
- case STATUS_MSG:
- SendStatus( wParam, lParam );
- break;
- #endif
- case WM_KEYDOWN:
- if(wParam==27 && is_fs) remove_fullscreen();
- break;
- case WM_MOUSEMOVE:
- if(is_fs) {
- if (ignore_mousemove_count>0) {
- ignore_mousemove_count--;
- }
- else if (abs(osdLastMouseX - LOWORD(lParam)) + abs(osdLastMouseY - HIWORD(lParam)) > 1) {
- KillTimer(hwnd, TIMER_OSD_ID);
- showOSD();
- SetTimer(hwnd, TIMER_OSD_ID, 2000, NULL);
- if (wParam & MK_LBUTTON)
- osdHitTest(LOWORD(lParam),HIWORD(lParam),1);
- else
- osdHitTest(LOWORD(lParam),HIWORD(lParam),-1);
- }
- osdLastMouseX = LOWORD(lParam);
- osdLastMouseY = HIWORD(lParam);
- }
- break;
- }
- if (m_msgcallback)
- {
- return m_msgcallback(m_msgcallback_tok,hwnd, uMsg, wParam, lParam);
- }
-
- return (DefWindowProc(hwnd, uMsg, wParam, lParam));
- }
- VideoOutput::VideoOutput(HWND parent_hwnd, int initxpos, int initypos)
- {
- curSubtitle=NULL;
- m_statusmsg=0;
- m_bufferstate=0;
- m_msgcallback=0;
- m_msgcallback_tok=0;
- video_hwnd=video_parent_hwnd=0;
- decoder=0;
- vid_aspectadj=true;
- vid_overlays=true;
- vid_ddraw=true;
- vid_vsync=true;
- aspect=1.0;
- m_need_change=false;
- width=height=flip=uyvy_output=yuy2_output=is_fs=ignore_mousemove_count=show_osd=0;
- oldfsparent=0;
- memset(&oldfsrect,0,sizeof(oldfsrect));
- memset(&lastfsrect,0,sizeof(lastfsrect));
- oldfsstyle=0;
- m_video_output=NULL;
- osdFontText=NULL;
- osdFontSymbol=NULL;
- osdProgressBrushBg=NULL;
- osdProgressBrushFg=NULL;
- osdProgressPenBg=NULL;
- osdProgressPenFg=NULL;
- osdProgressPenBgHilite=NULL;
- osdBlackBrush=NULL;
- osdMemDC=NULL;
- osdMemBM=NULL;
- osdOldBM=NULL;
- osdMemBMW=0;
- osdMemBMH=0;
- osdLastMouseX=-1;
- osdLastMouseY=-1;
- for (int i=0; i<NUM_WIDGETS; i++)
- SetRect(&ctrlrect[i], 0, 0, 0, 0);
- ctrlrects_ready = 0;
- resetSubtitle();
- WNDCLASS wc={0,};
- wc.hCursor=LoadCursor(NULL,IDC_ARROW);
- wc.lpfnWndProc = WndProc;
- wc.hInstance = GetModuleHandle(NULL);
- wc.lpszClassName = "NSVplay";
- LOGBRUSH lb={BS_SOLID,RGB(OV_COL_R,OV_COL_G,OV_COL_B),};
- wc.hbrBackground=CreateBrushIndirect(&lb);
- if (!class_refcnt) RegisterClass(&wc);
- class_refcnt++;
- m_logo=(HBITMAP)LoadImage(g_hInstance,MAKEINTRESOURCE(g_bitmap_id),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
- BITMAP bm;
- GetObject(m_logo, sizeof(BITMAP), &bm);
- m_logo_w=bm.bmWidth;
- m_logo_h=bm.bmHeight;
- if(m_logo_h<0) m_logo_h=-m_logo_h;
- InitializeCriticalSection(&m_cs);
- video_hwnd=CreateWindowEx(0,wc.lpszClassName, "NSV Player",parent_hwnd?WS_CHILD:(WS_OVERLAPPEDWINDOW&(~WS_MAXIMIZEBOX)),
- initxpos,initypos,320,200,
- parent_hwnd, NULL,wc.hInstance,(void*)this);
- video_parent_hwnd=parent_hwnd;
- m_lastbufinvalid=0;
-
- #ifdef ACTIVEX_CONTROL
- m_firstframe = 1;
- #endif
- }
- VideoOutputChild *VideoOutput::createVideoOutput(int n) {
- if(!vid_overlays && !vid_ddraw) vid_overlays=true;
- if(!vid_overlays) n++;
- if(n==0) return new OverlayVideoOutput();
- if(!vid_ddraw) n++;
- if(n==1) return new DDrawVideoOutput();
- return 0;
- }
- int VideoOutput::open(int w, int h, int vflip, double aspectratio, unsigned int fmt)
- {
- EnterCriticalSection(&m_cs);
- delete(m_video_output);
- m_video_output=NULL;
- if (!w) w=320;
- if (!h) h=240;
- width=w;
- height=h;
- flip=vflip;
- type=fmt;
- is_fs=0;
- ignore_mousemove_count=0;
- show_osd=0;
- aspect=aspectratio;
- for(int i=0;m_video_output=createVideoOutput(i);i++) {
- if(m_video_output->create(this,w,h,fmt,vflip,aspectratio)) {
- LeaveCriticalSection(&m_cs);
- if (!GetParent(video_hwnd)) {
- RECT r,r2;
- int ow=width,oh=height;
- if (aspect > 0.001)
- {
- if (aspect < 1.0) ow=(int)(ow/aspect);
- else oh=(int)(oh*aspect);
- }
- GetWindowRect(video_hwnd,&r);
- GetClientRect(video_hwnd,&r2);
- SetWindowPos(video_hwnd,NULL,0,0,
- ow+(r.right-r.left)-(r2.right-r2.left),
- oh+(r.bottom-r.top)-(r2.bottom-r2.top),
- SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
- }
- return 0;
- }
- delete(m_video_output);
- }
- LeaveCriticalSection(&m_cs);
- return 1;
- }
- void VideoOutput::draw(void *frame)
- {
- if (!m_video_output || !frame) return;
- if ((m_video_output && m_video_output->needChange()) || m_need_change) {
- open(width,height,flip,aspect,type);
- m_need_change=0;
- }
- #ifdef ACTIVEX_CONTROL
- if ( m_firstframe ) {
- m_firstframe = 0;
- PostMessage( video_hwnd, STATUS_MSG, STATUS_FIRSTFRAME, 1 );
- }
- #endif
- if (m_video_output) m_video_output->displayFrame((const char *)frame,0,0);
- }
- VideoOutput::~VideoOutput()
- {
- free(m_statusmsg);
- delete(m_video_output);
- DestroyWindow(video_hwnd);
- if (!--class_refcnt) UnregisterClass("NSVplay",GetModuleHandle(NULL));
- if(osdFontText) DeleteObject(osdFontText);
- if(osdFontSymbol) DeleteObject(osdFontSymbol);
- if(osdProgressBrushBg) DeleteObject(osdProgressBrushBg);
- if(osdProgressBrushFg) DeleteObject(osdProgressBrushFg);
- if(osdBlackBrush ) DeleteObject(osdBlackBrush );
- if(osdProgressPenBg ) DeleteObject(osdProgressPenBg );
- if(osdProgressPenFg ) DeleteObject(osdProgressPenFg );
- if(osdProgressPenBgHilite) DeleteObject(osdProgressPenBgHilite);
- if(osdMemDC) {
- SelectObject(osdMemDC,osdOldBM); // delete our doublebuffer
- DeleteDC(osdMemDC);
- }
- if(osdMemBM) DeleteObject(osdMemBM);
- DeleteCriticalSection(&m_cs);
- }
- void VideoOutput::close()
- {
- delete(m_video_output);
- m_video_output=NULL;
- }
- void VideoOutput::getViewport(RECT *r, HWND wnd, int full) {
- POINT *p=NULL;
- RECT *sr=NULL;
- if (p || sr || wnd) {
- HINSTANCE h=LoadLibrary("user32.dll");
- if (h) {
- HMONITOR (WINAPI *Mfp)(POINT pt, DWORD dwFlags) = (HMONITOR (WINAPI *)(POINT,DWORD)) GetProcAddress(h,"MonitorFromPoint");
- HMONITOR (WINAPI *Mfr)(LPCRECT lpcr, DWORD dwFlags) = (HMONITOR (WINAPI *)(LPCRECT, DWORD)) GetProcAddress(h, "MonitorFromRect");
- HMONITOR (WINAPI *Mfw)(HWND wnd, DWORD dwFlags)=(HMONITOR (WINAPI *)(HWND, DWORD)) GetProcAddress(h, "MonitorFromWindow");
- BOOL (WINAPI *Gmi)(HMONITOR mon, LPMONITORINFO lpmi) = (BOOL (WINAPI *)(HMONITOR,LPMONITORINFO)) GetProcAddress(h,"GetMonitorInfoA");
- if (Mfp && Mfr && Mfw && Gmi) {
- HMONITOR hm = NULL;
- if (p)
- hm=Mfp(*p,MONITOR_DEFAULTTONULL);
- else if (sr)
- hm=Mfr(sr,MONITOR_DEFAULTTONULL);
- else if (wnd)
- hm=Mfw(wnd,MONITOR_DEFAULTTONULL);
- if (hm) {
- MONITORINFOEX mi;
- memset(&mi,0,sizeof(mi));
- mi.cbSize=sizeof(mi);
- if (Gmi(hm,&mi)) {
- if(!full) *r=mi.rcWork;
- else *r=mi.rcMonitor;
- FreeLibrary(h);
- return;
- }
- }
- }
- FreeLibrary(h);
- }
- }
- if (full)
- { // this might be borked =)
- r->top=r->left=0;
- r->right=::GetSystemMetrics(SM_CXSCREEN);
- r->bottom=::GetSystemMetrics(SM_CYSCREEN);
- }
- else
- {
- SystemParametersInfo(SPI_GETWORKAREA,0,r,0);
- }
- }
- void VideoOutput::fullscreen()
- {
- if (is_fs) return;
- if(!m_video_output) return;
- is_fs=1;
- ignore_mousemove_count=2;
- oldfsparent=GetParent(video_hwnd);
- oldfsstyle=GetWindowLong(video_hwnd,GWL_STYLE);
- if (!oldfsparent) GetWindowRect(video_hwnd,&oldfsrect);
- else GetClientRect(video_hwnd,&oldfsrect);
- getViewport(&lastfsrect,video_hwnd,1);
- SetParent(video_hwnd,NULL);
- SetWindowLong(video_hwnd,GWL_STYLE,WS_POPUP|WS_VISIBLE);
- SetWindowPos(video_hwnd, HWND_TOPMOST, lastfsrect.left, lastfsrect.top, lastfsrect.right-lastfsrect.left, lastfsrect.bottom-lastfsrect.top, SWP_DRAWFRAME);
- SetFocus(video_hwnd);
- resetSubtitle();
- //showOSD();
- //SetCursor(NULL);
- }
- void VideoOutput::getOutputSize(int *w, int *h)
- {
- RECT r2;
- GetClientRect(video_hwnd,&r2);
- *w=r2.right-r2.left;
- *h=r2.bottom-r2.top;
- }
- void VideoOutput::setOutputSize(int w, int h)
- {
- RECT r,r2;
- GetWindowRect(video_hwnd,&r);
- GetClientRect(video_hwnd,&r2);
- SetWindowPos(video_hwnd, 0, 0,0,
- w+(r.right-r.left)-(r2.right-r2.left),
- h+(r.bottom-r.top)-(r2.bottom-r2.top),
- SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
- }
- void VideoOutput::remove_fullscreen()
- {
- if(!is_fs) return;
- SetParent(video_hwnd,oldfsparent);
- SetWindowLong(video_hwnd,GWL_STYLE,oldfsstyle);
- // note: when returning from fullscreen *on a secondary monitor*,
- // be careful how you set the new window Z order.
- // nsvplay.exe: only HWND_NOTOPMOST works
- // nsvplayX.exe: only HWND_TOP works
- SetWindowPos(video_hwnd, oldfsparent ? HWND_TOP : HWND_NOTOPMOST, oldfsrect.left, oldfsrect.top, oldfsrect.right-oldfsrect.left, oldfsrect.bottom-oldfsrect.top, SWP_FRAMECHANGED);
- SetFocus(oldfsparent ? oldfsparent : video_hwnd);
- is_fs=0;
- show_osd=0;
- ctrlrects_ready=0;
- resetSubtitle();
- hideOSD();
- }
- int VideoOutput::is_fullscreen()
- {
- return is_fs;
- }
- void VideoOutput::showStatusMsg(const char *text)
- {
- m_statusmsg=_strdup(text);
- InvalidateRect(video_hwnd,NULL,TRUE);
- }
- void VideoOutput::drawSubtitle(SubsItem *item)
- {
- if(!item) {
- if(curSubtitle) {
- m_video_output->drawSubtitle(NULL);
- curSubtitle=NULL;
- }
- return;
- }
- if(curSubtitle==item) return;
- curSubtitle=item;
- m_video_output->drawSubtitle(curSubtitle);
- }
- void VideoOutput::resetSubtitle()
- {
- curSubtitle=NULL;
- if(m_video_output) m_video_output->resetSubtitle();
- }
- void VideoOutput::showOSD() {
- if(OSD_ENABLED && m_video_output) {
- KillTimer(video_hwnd, TIMER_OSD_ID);
- if (!show_osd)
- m_video_output->showOSD();
- SetTimer(video_hwnd, TIMER_OSD_ID, 2000, NULL);
- show_osd = 1;
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- }
- }
- void VideoOutput::hideOSD() {
- if(OSD_ENABLED && m_video_output) {
- KillTimer(video_hwnd, TIMER_OSD_ID);
- m_video_output->hideOSD();
- show_osd = 0;
- SetCursor(NULL);
- }
- }
- void VideoOutput::drawOSD(HDC hdc, RECT *rg) {
- if(m_video_output && show_osd) {
- if (!osdMemDC ) osdMemDC = CreateCompatibleDC(hdc);
- if (!osdFontText) osdFontText=CreateFont(OSD_TEXT_SIZE,0,0,0,FW_SEMIBOLD,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Arial");
- if (!osdFontSymbol) osdFontSymbol=CreateFont(OSD_TEXT_SIZE,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,SYMBOL_CHARSET,OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH,"Webdings");
- if (!osdProgressBrushBg) osdProgressBrushBg = CreateSolidBrush(RGB(OSD_VOL_BKCOL_R,OSD_VOL_BKCOL_G,OSD_VOL_BKCOL_B));
- if (!osdProgressBrushFg) osdProgressBrushFg = CreateSolidBrush(RGB(OSD_VOL_COL_R,OSD_VOL_COL_G,OSD_VOL_COL_B));
- if (!osdBlackBrush ) osdBlackBrush = CreateSolidBrush(RGB(0,0,0));//OV_COL_R,OV_COL_G,OV_COL_B));
- if (!osdProgressPenBg ) osdProgressPenBg = CreatePen(PS_SOLID,0,RGB(OSD_TEXT_R,OSD_TEXT_G,OSD_TEXT_B));
- if (!osdProgressPenFg ) osdProgressPenFg = CreatePen(PS_NULL,0,RGB(0,0,0));
- if (!osdProgressPenBgHilite) osdProgressPenBgHilite = CreatePen(PS_SOLID,0,RGB(OSD_TEXT_R_HILITE,OSD_TEXT_G_HILITE,OSD_TEXT_B_HILITE));
-
- COLORREF fg = GetTextColor(osdMemDC);
- COLORREF bg = GetBkColor(osdMemDC);
- SetTextColor(osdMemDC, RGB(OSD_TEXT_R,OSD_TEXT_G,OSD_TEXT_B));
- SetBkColor(osdMemDC, RGB(0,0,0));//OV_COL_R,OV_COL_G,OV_COL_B));
-
- HGDIOBJ oldfont = SelectObject(osdMemDC, osdFontText);
- HGDIOBJ oldbrush = SelectObject(osdMemDC, osdProgressBrushBg);
- HGDIOBJ oldpen = SelectObject(osdMemDC, osdProgressPenBg);
- RECT fullr;
- GetClientRect(video_hwnd,&fullr);
- ClientToScreen(video_hwnd,(LPPOINT)&fullr);
- ClientToScreen(video_hwnd,((LPPOINT)&fullr) + 1);
- // transform coords from windows desktop coords (where 0,0==upper-left corner of the primary monitor)
- // to the coords for the monitor we're displaying on:
- fullr.top -= m_video_output->m_mon_y;
- fullr.left -= m_video_output->m_mon_x;
- fullr.right -= m_video_output->m_mon_x;
- fullr.bottom -= m_video_output->m_mon_y;
- if (!ctrlrects_ready) {
- ctrlrects_ready = 1;
- int net_width = 0;
- int max_height = 0;
- int streaming = (decoder && decoder->getlen()==-1) ? 1 : 0;
-
- for (int i=0; i<NUM_WIDGETS; i++) {
- if (streaming && (i==CTRL_PROGRESS || i==CTRL_PROGRESSTEXT || i==CTRL_PROGRESSSPACER || i==CTRL_FFWD || i==CTRL_REW)) {
- // disable progress bar + seek arrows when the NSV is a stream
- ctrlrect[i].right = -1;
- continue;
- }
- else if (g_ctrl_force_width[i] != 0) {
- SetRect(&ctrlrect[i], 0, 0, g_ctrl_force_width[i], 0);
- }
- else {
- SelectObject(osdMemDC, (g_ctrl_type[i] == CTRLTYPE_SYMBOL) ? osdFontSymbol : osdFontText);
- SetRect(&ctrlrect[i], 0, 0, 256, 256);
- ctrlrect[i].bottom = DrawText(osdMemDC, g_ctrl_text[i], -1, &ctrlrect[i], DT_SINGLELINE|DT_CALCRECT);
- }
- net_width += ctrlrect[i].right - ctrlrect[i].left;
- max_height = max(max_height, ctrlrect[i].bottom - ctrlrect[i].top);
- }
- // now we know the size of all the controls; now place them.
- int x = (fullr.right + fullr.left)/2 - net_width/2;
- SetRect(&ctrlrect_all, 0, 0, 0, 0);
- for (i=0; i<NUM_WIDGETS; i++)
- {
- if (ctrlrect[i].right >= 0) // if control is not disabled...
- {
- int this_width = ctrlrect[i].right - ctrlrect[i].left;
- int this_height = ctrlrect[i].bottom - ctrlrect[i].top ;
- if (this_height==0) this_height = max_height*2/3;// progress bars
- ctrlrect[i].top = max_height/2 - this_height/2;
- ctrlrect[i].bottom = max_height/2 + this_height/2;
- ctrlrect[i].left = x;
- ctrlrect[i].right = x + this_width;
- if (ctrlrect_all.bottom==0) {
- ctrlrect_all.top = ctrlrect[i].top ;
- ctrlrect_all.bottom = ctrlrect[i].bottom;
- }
- else {
- ctrlrect_all.top = min(ctrlrect_all.top , ctrlrect[i].top );
- ctrlrect_all.bottom = max(ctrlrect_all.bottom, ctrlrect[i].bottom);
- }
- x += this_width;
- }
- }
- }
- int w = fullr.right - fullr.left;
- int h = ctrlrect_all.bottom - ctrlrect_all.top;
- if (!osdMemBM || osdMemBMW != w || osdMemBMH != h) {
- if (osdMemBM) {
- SelectObject(osdMemDC,osdOldBM);
- DeleteObject(osdMemBM);
- }
- osdMemBM = CreateCompatibleBitmap(hdc,w,h);
- osdOldBM = (HBITMAP)SelectObject(osdMemDC, osdMemBM);
- osdMemBMW = w;
- osdMemBMH = h;
- }
- RECT temp;
- SetRect(&temp, 0, 0, w, h);
- FillRect(osdMemDC, &temp, (HBRUSH)osdBlackBrush);
- for (int i=0; i<NUM_WIDGETS; i++) {
- if (g_ctrl_type[i] == CTRLTYPE_PROGRESS)
- {
- int progress = 0;
- int max_progress = ctrlrect[i].right - ctrlrect[i].left;
- switch(i)
- {
- case CTRL_VOL:
- if (decoder)
- progress = decoder->getvolume()*max_progress/255;
- break;
- case CTRL_PROGRESS:
- if (decoder)
- {
- int len = decoder->getlen();
- if (len>0)
- progress = decoder->getpos()*max_progress/len;
- }
- break;
- }
- SelectObject(osdMemDC, osdProgressBrushBg);
- SelectObject(osdMemDC, (i==osdLastClickItem) ? osdProgressPenBgHilite : osdProgressPenBg);
- RoundRect(osdMemDC, ctrlrect[i].left, ctrlrect[i].top, ctrlrect[i].right, ctrlrect[i].bottom, 3, 3);
- SelectObject(osdMemDC, osdProgressBrushFg);
- SelectObject(osdMemDC, osdProgressPenFg);
- Rectangle(osdMemDC, ctrlrect[i].left+1, ctrlrect[i].top+1, ctrlrect[i].left + progress, ctrlrect[i].bottom);
- }
- else if (g_ctrl_type[i] == CTRLTYPE_SYMBOL ||
- g_ctrl_type[i] == CTRLTYPE_TEXT)
- {
- SelectObject(osdMemDC, (g_ctrl_type[i] == CTRLTYPE_SYMBOL) ? osdFontSymbol : osdFontText);
- SetTextColor(osdMemDC, (i==osdLastClickItem) ? RGB(OSD_TEXT_R_HILITE,OSD_TEXT_G_HILITE,OSD_TEXT_B_HILITE) : RGB(OSD_TEXT_R,OSD_TEXT_G,OSD_TEXT_B));
- DrawText(osdMemDC, g_ctrl_text[i], -1, &ctrlrect[i], DT_SINGLELINE);
- }
- }
- int x0 = fullr.left;
- int y0 = fullr.bottom - (ctrlrect_all.bottom - ctrlrect_all.top);
- BitBlt(hdc,x0,y0,w,h,osdMemDC,0,0,SRCCOPY);
- // display stream title @ the top:
- #if (SHOW_STREAM_TITLE_AT_TOP)
- if (decoder)
- {
- RECT temp;
- SetRect(&temp, 0, 0, w, h);
- FillRect(osdMemDC, &temp, (HBRUSH)osdBlackBrush);
- SelectObject(osdMemDC, osdFontText);
- SetTextColor(osdMemDC, RGB(OSD_TEXT_R,OSD_TEXT_G,OSD_TEXT_B));
- char *t=decoder->getTitle();
- char *buf=(char*)malloc(32+(t?strlen(t):0));
- wsprintf(buf, "%s (%d kbps)", t?t:"", decoder->getBitrate()/1000);
- char *p=buf;
- while (*p)
- {
- if (*p == '_') *p=' ';
- p++;
- }
- DrawText(osdMemDC, buf, -1, &temp, DT_SINGLELINE|DT_CENTER);
- free(buf);
- SelectObject(osdMemDC, osdFontSymbol);
- DrawText(osdMemDC, "2r", -1, &temp, DT_SINGLELINE|DT_RIGHT);
- int x0 = fullr.left;
- int y0 = fullr.top;
- BitBlt(hdc,x0,y0,w,h,osdMemDC,0,0,SRCCOPY);
- }
- SelectObject(osdMemDC, oldpen);
- SelectObject(osdMemDC, oldbrush);
- SelectObject(osdMemDC, oldfont);
- SetTextColor(osdMemDC, fg);
- SetBkColor(osdMemDC, bg);
- }
- #endif
- }
- void VideoOutput::osdHitTest(int x, int y, int dragging)
- {
- // dragging == -1: just a mousemove (no clicking)
- // dragging == 0: user clicked
- // dragging == 1: user clicked before, and is now dragging/moving mouse
- if (dragging<1)
- osdLastClickItem = -1;
- // transform (x,y) from screen coords into coords relative to the memDC
- y = y - ((lastfsrect.bottom - lastfsrect.top) - (ctrlrect_all.bottom - ctrlrect_all.top));
- int i0 = 0;
- int i1 = NUM_WIDGETS;
- if (dragging==1) {
- i0 = osdLastClickItem;
- i1 = osdLastClickItem+1;
- }
- for (int i=i0; i<i1; i++)
- {
- if (dragging==1 || (x >= ctrlrect[i].left && x <= ctrlrect[i].right && y >= ctrlrect[i].top && y <= ctrlrect[i].bottom))
- {
- float t = (x - ctrlrect[i].left) / (float)(ctrlrect[i].right - ctrlrect[i].left);
- if (t<0) t=0;
- if (t>1) t=1;
- if (dragging<1)
- osdLastClickItem = i;
-
- switch(i)
- {
- case CTRL_VOL:
- if (decoder && dragging>=0) decoder->setvolume((int)(t*255));
- return;
- case CTRL_PROGRESS:
- if (decoder && dragging>=0)
- {
- int len = decoder->getlen();
- if (len > 0)
- decoder->seek((int)(t*len));
- }
- return;
- case CTRL_PAUSE:
- if (decoder && dragging>=0) decoder->pause(1);
- return;
- case CTRL_PLAY:
- if (decoder && dragging>=0) decoder->pause(0);
- return;
- case CTRL_STOP:
- if (decoder && dragging>=0) {
- decoder->pause(1);
- remove_fullscreen();
- }
- return;
- case CTRL_REW:
- case CTRL_FFWD:
- if (decoder && dragging>=0)
- {
- int pos = decoder->getpos();
- int len = decoder->getlen();
- if (len > 0)
- {
- if (i==CTRL_REW)
- pos = max(0, pos-15000); // milliseconds to rewind
- else
- pos = min(len, pos+30000); // milliseconds to skip ahead
- decoder->seek(pos);
- }
- }
- return;
- default:
- if (dragging<1)
- osdLastClickItem = -1;
- break;
- }
- }
- }
- if (dragging==0)
- remove_fullscreen();
- }
|