You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
466 lines
13 KiB
466 lines
13 KiB
/*****************************************************************************
|
|
* os2_factory.cpp
|
|
*****************************************************************************
|
|
* Copyright (C) 2003, 2013 the VideoLAN team
|
|
*
|
|
* Authors: Cyril Deguet <asmax@via.ecp.fr>
|
|
* Olivier Teulière <ipkiss@via.ecp.fr>
|
|
* KO Myung-Hun <komh@chollian.net>
|
|
*
|
|
* This program 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.
|
|
*
|
|
* This program 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 this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
|
*****************************************************************************/
|
|
|
|
#ifdef OS2_SKINS
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <io.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <cfloat>
|
|
|
|
#include "os2_factory.hpp"
|
|
#include "os2_graphics.hpp"
|
|
#include "os2_timer.hpp"
|
|
#include "os2_window.hpp"
|
|
#include "os2_tooltip.hpp"
|
|
#include "os2_popup.hpp"
|
|
#include "os2_loop.hpp"
|
|
#include "../src/theme.hpp"
|
|
#include "../src/window_manager.hpp"
|
|
#include "../src/generic_window.hpp"
|
|
#include "../commands/cmd_dialogs.hpp"
|
|
#include "../commands/cmd_minimize.hpp"
|
|
|
|
|
|
static void MorphToPM( void )
|
|
{
|
|
PPIB pib;
|
|
PTIB tib;
|
|
|
|
DosGetInfoBlocks(&tib, &pib);
|
|
|
|
// Change flag from VIO to PM
|
|
if (pib->pib_ultype==2) pib->pib_ultype = 3;
|
|
}
|
|
|
|
|
|
MRESULT EXPENTRY OS2Factory::OS2FrameProc( HWND hwnd, ULONG msg,
|
|
MPARAM mp1, MPARAM mp2 )
|
|
{
|
|
// Get pointer to thread info: should only work with the parent window
|
|
intf_thread_t *p_intf = (intf_thread_t *)WinQueryWindowPtr( hwnd, 0 );
|
|
|
|
OS2Factory *pFactory = (OS2Factory*)OS2Factory::instance( p_intf );
|
|
|
|
if( msg == WM_ADJUSTWINDOWPOS )
|
|
{
|
|
PSWP pswp = ( PSWP )PVOIDFROMMP( mp1 );
|
|
if( pswp->fl & ( SWP_MINIMIZE | SWP_RESTORE ))
|
|
{
|
|
// propagate to all the owned windows
|
|
HENUM henum = WinBeginEnumWindows( HWND_DESKTOP );
|
|
HWND hwndNext;
|
|
while(( hwndNext = WinGetNextWindow( henum )) != NULLHANDLE )
|
|
{
|
|
if( WinQueryWindow( hwndNext, QW_OWNER ) ==
|
|
pFactory->m_hParentClientWindow )
|
|
WinSetWindowPos( hwndNext, 0, 0, 0, 0, 0,
|
|
pswp->fl &
|
|
( SWP_MINIMIZE | SWP_RESTORE ));
|
|
}
|
|
}
|
|
}
|
|
else if( msg == WM_SYSCOMMAND )
|
|
{
|
|
// If closing parent window
|
|
if( SHORT1FROMMP(mp1) == SC_CLOSE )
|
|
{
|
|
libvlc_Quit( vlc_object_instance(p_intf) );
|
|
|
|
return 0;
|
|
}
|
|
else if( SHORT1FROMMP(mp1) == SC_MINIMIZE )
|
|
{
|
|
pFactory->minimize();
|
|
|
|
return 0;
|
|
}
|
|
else if( SHORT1FROMMP(mp1) == SC_RESTORE )
|
|
{
|
|
pFactory->restore();
|
|
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
msg_Dbg( p_intf, "WM_SYSCOMMAND %i", (SHORT1FROMMP(mp1)));
|
|
}
|
|
}
|
|
|
|
return pFactory->m_pfnwpOldFrameProc( hwnd, msg, mp1, mp2 );
|
|
}
|
|
|
|
MRESULT EXPENTRY OS2Factory::OS2Proc( HWND hwnd, ULONG msg,
|
|
MPARAM mp1, MPARAM mp2 )
|
|
{
|
|
// Get pointer to thread info: should only work with the parent window
|
|
intf_thread_t *p_intf = (intf_thread_t *)WinQueryWindowPtr( hwnd, 0 );
|
|
|
|
// If doesn't exist, treat windows message normally
|
|
if( p_intf == NULL || p_intf->p_sys->p_osFactory == NULL )
|
|
{
|
|
return WinDefWindowProc( hwnd, msg, mp1, mp2 );
|
|
}
|
|
|
|
OS2Factory *pFactory = (OS2Factory*)OS2Factory::instance( p_intf );
|
|
GenericWindow *pWin = pFactory->m_windowMap[hwnd];
|
|
|
|
// Subclass a frame window
|
|
if( !pFactory->m_pfnwpOldFrameProc )
|
|
{
|
|
// Store with it a pointer to the interface thread
|
|
WinSetWindowPtr( pFactory->m_hParentWindow, 0, p_intf );
|
|
|
|
pFactory->m_pfnwpOldFrameProc =
|
|
WinSubclassWindow( pFactory->m_hParentWindow, OS2FrameProc );
|
|
}
|
|
|
|
if( hwnd != pFactory->getParentWindow() && pWin )
|
|
{
|
|
OS2Loop* pLoop =
|
|
(OS2Loop*) OSFactory::instance( p_intf )->getOSLoop();
|
|
if( pLoop )
|
|
return pLoop->processEvent( hwnd, msg, mp1, mp2 );
|
|
}
|
|
|
|
// If hwnd does not match any window or message not processed
|
|
return WinDefWindowProc( hwnd, msg, mp1, mp2 );
|
|
}
|
|
|
|
|
|
OS2Factory::OS2Factory( intf_thread_t *pIntf ):
|
|
OSFactory( pIntf ), m_hParentWindow( 0 ),
|
|
m_pfnwpOldFrameProc( 0 ), m_dirSep( "\\" )
|
|
{
|
|
// see init()
|
|
}
|
|
|
|
|
|
bool OS2Factory::init()
|
|
{
|
|
PCSZ vlc_name = "VLC Media Player";
|
|
PCSZ vlc_icon = "VLC_ICON";
|
|
PCSZ vlc_class = "SkinWindowClass";
|
|
|
|
MorphToPM();
|
|
|
|
m_hab = WinInitialize( 0 );
|
|
|
|
// save FPU CW
|
|
unsigned saved_cw = _control87( 0, 0 );
|
|
|
|
// WinCreateMsgQueue() changes FPU CW but does not restore it
|
|
m_hmq = WinCreateMsgQueue( m_hab, 0 );
|
|
|
|
// restore FPU CW
|
|
_control87( saved_cw, MCW_EM | MCW_IC | MCW_RC | MCW_PC );
|
|
|
|
if( !WinRegisterClass( m_hab, vlc_class, OS2Factory::OS2Proc,
|
|
CS_SIZEREDRAW, sizeof( PVOID )))
|
|
{
|
|
msg_Err( getIntf(), "cannot register window class" );
|
|
return false;
|
|
}
|
|
|
|
ULONG flFrame = FCF_SYSMENU | FCF_MINBUTTON | FCF_TASKLIST
|
|
/* | FCF_ICON */;
|
|
|
|
m_hParentWindow = WinCreateStdWindow( HWND_DESKTOP,
|
|
0,
|
|
&flFrame,
|
|
vlc_class,
|
|
vlc_name,
|
|
0,
|
|
NULLHANDLE,
|
|
0/* ID_VLC_ICON */,
|
|
&m_hParentClientWindow );
|
|
|
|
if( !m_hParentWindow )
|
|
{
|
|
msg_Err( getIntf(), "cannot create parent window" );
|
|
return false;
|
|
}
|
|
|
|
// Store with it a pointer to the interface thread
|
|
WinSetWindowPtr( m_hParentClientWindow, 0, getIntf());
|
|
|
|
WinSetWindowPos( m_hParentWindow, HWND_TOP, 0, 0, 0, 0,
|
|
SWP_ACTIVATE | SWP_ZORDER | SWP_MOVE | SWP_SIZE |
|
|
SWP_SHOW );
|
|
|
|
// Set the mouse pointer to a default arrow
|
|
changeCursor( kDefaultArrow );
|
|
|
|
// Initialize the resource path
|
|
char *datadir = config_GetUserDir( VLC_USERDATA_DIR );
|
|
m_resourcePath.push_back( (std::string)datadir + "\\skins" );
|
|
free( datadir );
|
|
datadir = config_GetSysPath(VLC_PKG_DATA_DIR, NULL);
|
|
m_resourcePath.push_back( (std::string)datadir + "\\skins" );
|
|
m_resourcePath.push_back( (std::string)datadir + "\\skins2" );
|
|
m_resourcePath.push_back( (std::string)datadir + "\\share\\skins" );
|
|
m_resourcePath.push_back( (std::string)datadir + "\\share\\skins2" );
|
|
m_resourcePath.push_back( (std::string)datadir + "\\vlc\\skins" );
|
|
m_resourcePath.push_back( (std::string)datadir + "\\vlc\\skins2" );
|
|
free( datadir );
|
|
|
|
// All went well
|
|
return true;
|
|
}
|
|
|
|
|
|
OS2Factory::~OS2Factory()
|
|
{
|
|
if( m_hParentWindow ) WinDestroyWindow( m_hParentWindow );
|
|
|
|
WinDestroyMsgQueue( m_hmq );
|
|
WinTerminate( m_hab );
|
|
}
|
|
|
|
|
|
OSGraphics *OS2Factory::createOSGraphics( int width, int height )
|
|
{
|
|
return new OS2Graphics( getIntf(), width, height );
|
|
}
|
|
|
|
|
|
OSLoop *OS2Factory::getOSLoop()
|
|
{
|
|
return OS2Loop::instance( getIntf() );
|
|
}
|
|
|
|
|
|
void OS2Factory::destroyOSLoop()
|
|
{
|
|
OS2Loop::destroy( getIntf() );
|
|
}
|
|
|
|
void OS2Factory::minimize()
|
|
{
|
|
/* Make sure no tooltip is visible first */
|
|
getIntf()->p_sys->p_theme->getWindowManager().hideTooltip();
|
|
|
|
WinSetWindowPos( m_hParentWindow, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE );
|
|
}
|
|
|
|
void OS2Factory::restore()
|
|
{
|
|
WinSetWindowPos( m_hParentWindow, NULLHANDLE, 0, 0, 0, 0, SWP_RESTORE );
|
|
}
|
|
|
|
void OS2Factory::addInTray()
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
void OS2Factory::removeFromTray()
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
void OS2Factory::addInTaskBar()
|
|
{
|
|
WinSetWindowPos( m_hParentWindow, NULLHANDLE, 0, 0, 0, 0, SWP_HIDE );
|
|
|
|
HSWITCH hswitch = WinQuerySwitchHandle( m_hParentWindow, 0 );
|
|
|
|
SWCNTRL swctl;
|
|
WinQuerySwitchEntry( hswitch, &swctl );
|
|
swctl.uchVisibility = SWL_VISIBLE;
|
|
WinChangeSwitchEntry( hswitch, &swctl );
|
|
|
|
WinSetWindowPos( m_hParentWindow, NULLHANDLE, 0, 0, 0, 0,
|
|
SWP_ACTIVATE | SWP_SHOW );
|
|
}
|
|
|
|
void OS2Factory::removeFromTaskBar()
|
|
{
|
|
WinSetWindowPos( m_hParentWindow, NULLHANDLE, 0, 0, 0, 0, SWP_HIDE );
|
|
|
|
HSWITCH hswitch = WinQuerySwitchHandle( m_hParentWindow, 0 );
|
|
|
|
SWCNTRL swctl;
|
|
WinQuerySwitchEntry( hswitch, &swctl );
|
|
swctl.uchVisibility = SWL_INVISIBLE;
|
|
WinChangeSwitchEntry( hswitch, &swctl );
|
|
|
|
WinSetWindowPos( m_hParentWindow, NULLHANDLE, 0, 0, 0, 0,
|
|
SWP_ACTIVATE | SWP_SHOW );
|
|
}
|
|
|
|
OSTimer *OS2Factory::createOSTimer( CmdGeneric &rCmd )
|
|
{
|
|
return new OS2Timer( getIntf(), rCmd, m_hParentClientWindow );
|
|
}
|
|
|
|
|
|
OSWindow *OS2Factory::createOSWindow( GenericWindow &rWindow, bool dragDrop,
|
|
bool playOnDrop, OSWindow *pParent,
|
|
GenericWindow::WindowType_t type )
|
|
{
|
|
return new OS2Window( getIntf(), rWindow, m_hInst, m_hParentClientWindow,
|
|
dragDrop, playOnDrop, (OS2Window*)pParent, type );
|
|
}
|
|
|
|
|
|
OSTooltip *OS2Factory::createOSTooltip()
|
|
{
|
|
return new OS2Tooltip( getIntf(), m_hInst, m_hParentClientWindow );
|
|
}
|
|
|
|
|
|
OSPopup *OS2Factory::createOSPopup()
|
|
{
|
|
// XXX FIXME: this way of getting the handle really sucks!
|
|
// In fact, the clean way would be to have in Builder::addPopup() a call
|
|
// to pPopup->associateToWindow() (to be written)... but the problem is
|
|
// that there is no way to access the OS-dependent window handle from a
|
|
// GenericWindow (we cannot even access the OSWindow).
|
|
if( m_windowMap.begin() == m_windowMap.end() )
|
|
{
|
|
msg_Err( getIntf(), "no window has been created before the popup!" );
|
|
return NULL;
|
|
}
|
|
|
|
return new OS2Popup( getIntf(), m_windowMap.begin()->first );
|
|
}
|
|
|
|
|
|
int OS2Factory::getScreenWidth() const
|
|
{
|
|
return WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
|
|
}
|
|
|
|
|
|
int OS2Factory::getScreenHeight() const
|
|
{
|
|
return WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
|
|
}
|
|
|
|
|
|
void OS2Factory::getMonitorInfo( OSWindow* pWindow,
|
|
int* p_x, int* p_y,
|
|
int* p_width, int* p_height ) const
|
|
{
|
|
*p_x = 0;
|
|
*p_y = 0;
|
|
*p_width = getScreenWidth();
|
|
*p_height = getScreenHeight();
|
|
}
|
|
|
|
|
|
void OS2Factory::getMonitorInfo( int numScreen, int* p_x, int* p_y,
|
|
int* p_width, int* p_height ) const
|
|
{
|
|
*p_x = 0;
|
|
*p_y = 0;
|
|
*p_width = getScreenWidth();
|
|
*p_height = getScreenHeight();
|
|
}
|
|
|
|
|
|
SkinsRect OS2Factory::getWorkArea() const
|
|
{
|
|
// TODO : calculate Desktop Workarea excluding WarpCenter
|
|
|
|
// Fill a Rect object
|
|
return SkinsRect( 0, 0, getScreenWidth(), getScreenHeight());
|
|
}
|
|
|
|
|
|
void OS2Factory::getMousePos( int &rXPos, int &rYPos ) const
|
|
{
|
|
POINTL ptl;
|
|
|
|
WinQueryPointerPos( HWND_DESKTOP, &ptl );
|
|
|
|
rXPos = ptl.x;
|
|
rYPos = ( getScreenHeight() - 1 ) - ptl.y; // Invert Y
|
|
}
|
|
|
|
|
|
void OS2Factory::changeCursor( CursorType_t type ) const
|
|
{
|
|
LONG id;
|
|
switch( type )
|
|
{
|
|
default:
|
|
case kDefaultArrow: id = SPTR_ARROW; break;
|
|
case kResizeNWSE: id = SPTR_SIZENWSE; break;
|
|
case kResizeNS: id = SPTR_SIZENS; break;
|
|
case kResizeWE: id = SPTR_SIZEWE; break;
|
|
case kResizeNESW: id = SPTR_SIZENESW; break;
|
|
}
|
|
|
|
HPOINTER hptr = WinQuerySysPointer( HWND_DESKTOP, id, FALSE );
|
|
WinSetPointer( HWND_DESKTOP, hptr );
|
|
|
|
m_cursorType = type;
|
|
}
|
|
|
|
|
|
void OS2Factory::rmDir( const std::string &rPath )
|
|
{
|
|
struct dirent *file;
|
|
DIR *dir;
|
|
|
|
dir = opendir( rPath.c_str() );
|
|
if( !dir ) return;
|
|
|
|
// Parse the directory and remove everything it contains
|
|
while( (file = readdir( dir )) )
|
|
{
|
|
struct stat statbuf;
|
|
std::string filename = file->d_name;
|
|
|
|
// Skip "." and ".."
|
|
if( filename == "." || filename == ".." )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
filename = rPath + "\\" + filename;
|
|
|
|
if( !stat( filename.c_str(), &statbuf ) && statbuf.st_mode & S_IFDIR )
|
|
{
|
|
rmDir( filename );
|
|
}
|
|
else
|
|
{
|
|
unlink( filename.c_str() );
|
|
}
|
|
}
|
|
|
|
// Close the directory
|
|
closedir( dir );
|
|
|
|
// And delete it
|
|
rmdir( rPath.c_str() );
|
|
}
|
|
|
|
#endif
|
|
|