From dc6a12357fff675508d3fd13934318dc9d9d5e5a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 19 May 2002 20:06:01 +0000 Subject: [PATCH] Added David Hedbor's Qtopia patches --- configure.in | 89 +++++-- include/SDL_main.h | 3 +- src/main/Makefile.am | 5 +- src/main/linux/SDL_Qtopia_main.cc | 24 ++ src/video/SDL_sysvideo.h | 3 + src/video/SDL_video.c | 3 + src/video/qtopia/.cvsignore | 6 + src/video/qtopia/Makefile.am | 20 ++ src/video/qtopia/SDL_QPEApp.cc | 62 +++++ src/video/qtopia/SDL_QPEApp.h | 37 +++ src/video/qtopia/SDL_QWin.cc | 333 +++++++++++++++++++++++++ src/video/qtopia/SDL_QWin.h | 128 ++++++++++ src/video/qtopia/SDL_lowvideo.h | 69 ++++++ src/video/qtopia/SDL_sysevents.cc | 273 +++++++++++++++++++++ src/video/qtopia/SDL_sysevents_c.h | 35 +++ src/video/qtopia/SDL_sysmouse.cc | 65 +++++ src/video/qtopia/SDL_sysmouse_c.h | 36 +++ src/video/qtopia/SDL_sysvideo.cc | 376 +++++++++++++++++++++++++++++ src/video/qtopia/SDL_syswm.cc | 39 +++ src/video/qtopia/SDL_syswm_c.h | 32 +++ 20 files changed, 1613 insertions(+), 25 deletions(-) create mode 100644 src/main/linux/SDL_Qtopia_main.cc create mode 100644 src/video/qtopia/.cvsignore create mode 100644 src/video/qtopia/Makefile.am create mode 100644 src/video/qtopia/SDL_QPEApp.cc create mode 100644 src/video/qtopia/SDL_QPEApp.h create mode 100644 src/video/qtopia/SDL_QWin.cc create mode 100644 src/video/qtopia/SDL_QWin.h create mode 100644 src/video/qtopia/SDL_lowvideo.h create mode 100644 src/video/qtopia/SDL_sysevents.cc create mode 100644 src/video/qtopia/SDL_sysevents_c.h create mode 100644 src/video/qtopia/SDL_sysmouse.cc create mode 100644 src/video/qtopia/SDL_sysmouse_c.h create mode 100644 src/video/qtopia/SDL_sysvideo.cc create mode 100644 src/video/qtopia/SDL_syswm.cc create mode 100644 src/video/qtopia/SDL_syswm_c.h diff --git a/configure.in b/configure.in index cfccac00d..13e67c608 100644 --- a/configure.in +++ b/configure.in @@ -322,15 +322,15 @@ CheckESD() [ --enable-esd support the Enlightened Sound Daemon [default=yes]], , enable_esd=yes) if test x$enable_audio = xyes -a x$enable_esd = xyes; then - use_esd=no + use_esd=no AM_PATH_ESD(0.2.8, use_esd=yes) - if test x$use_esd = xyes; then + if test x$use_esd = xyes; then AC_ARG_ENABLE(esd-shared, [ --enable-esd-shared dynamically load ESD audio support [default=no]], , enable_esd_shared=no) esd_lib_spec=`echo $ESD_LIBS | sed 's/.*-L\([[^ ]]*\).*/\1\/libesd.so.*/'` - esd_lib=`ls $esd_lib_spec | head -1 | sed 's/.*\/\(.*\)/\1/'` - echo "-- $esd_lib_spec -> $esd_lib" + esd_lib=`ls $esd_lib_spec | head -1 | sed 's/.*\/\(.*\)/\1/'` + echo "-- $esd_lib_spec -> $esd_lib" if test x$enable_dlopen != xyes && \ test x$enable_esd_shared = xyes; then AC_MSG_ERROR([You must have dlopen() support and use the --enable-dlopen option]) @@ -338,7 +338,7 @@ CheckESD() if test x$enable_dlopen = xyes && \ test x$enable_esd_shared = xyes && test x$esd_lib != x; then CFLAGS="$CFLAGS -DESD_SUPPORT -DESD_DYNAMIC=\$(esd_lib) $ESD_CFLAGS" - AC_SUBST(esd_lib) + AC_SUBST(esd_lib) else CFLAGS="$CFLAGS -DESD_SUPPORT $ESD_CFLAGS" SYSTEM_LIBS="$SYSTEM_LIBS $ESD_LIBS" @@ -379,8 +379,8 @@ CheckARTSC() [ --enable-arts-shared dynamically load aRts audio support [default=no]], , enable_arts_shared=no) arts_lib_spec=`echo $ARTSC_LIBS | sed 's/.*-L\([[^ ]]*\).*/\1\/libartsc.so.*/'` - arts_lib=`ls $arts_lib_spec | head -1 | sed 's/.*\/\(.*\)/\1/'` - echo "-- $arts_lib_spec -> $arts_lib" + arts_lib=`ls $arts_lib_spec | head -1 | sed 's/.*\/\(.*\)/\1/'` + echo "-- $arts_lib_spec -> $arts_lib" if test x$enable_dlopen != xyes && \ test x$enable_arts_shared = xyes; then AC_MSG_ERROR([You must have dlopen() support and use the --enable-dlopen option]) @@ -388,7 +388,7 @@ CheckARTSC() if test x$enable_dlopen = xyes && \ test x$enable_arts_shared = xyes && test x$arts_lib != x; then CFLAGS="$CFLAGS -DARTSC_SUPPORT -DARTSC_DYNAMIC=\$(arts_lib) $ARTSC_CFLAGS" - AC_SUBST(arts_lib) + AC_SUBST(arts_lib) else CFLAGS="$CFLAGS -DARTSC_SUPPORT $ARTSC_CFLAGS" SYSTEM_LIBS="$SYSTEM_LIBS $ARTSC_LIBS" @@ -1165,7 +1165,7 @@ CheckPTHREAD() #include ],[ pthread_mutexattr_t attr; - #ifdef linux + #if defined(linux) && !(defined(__arm__) && defined(QWS)) pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP); #else pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); @@ -1349,6 +1349,36 @@ CheckBWINDOW() VIDEO_DRIVERS="$VIDEO_DRIVERS bwindow/libvideo_bwindow.la" } +dnl Set up the QTopia video driver if enabled +CheckQtopia() +{ + AC_ARG_ENABLE(video-qtopia, +[ --enable-video-qtopia use Qtopia video driver [default=no]], + , enable_video_qtopia=no) + if test x$enable_video = xyes -a x$enable_video_qtopia = xyes; then + AC_MSG_CHECKING(for Qtopia support) + video_qtopia=no + AC_LANG_CPLUSPLUS + OLD_CXX="$CXXFLAGS" + CXXFLAGS="-DQT_QWS_EBX -fno-rtti -fno-exceptions -DQT_QWS_CUSTOM -DQWS -I${QPEDIR}/include -I${QTDIR}/include/ -DNO_DEBUG" + AC_TRY_COMPILE([ + #include + ],[ + ],[ + video_qtopia=yes + ]) + CXXFLAGS="$OLD_CXX" + AC_MSG_RESULT($video_qtopia) + if test x$video_qtopia = xyes; then + CFLAGS="$CFLAGS -DENABLE_QTOPIA -DQT_QWS_EBX -DQT_QWS_CUSTOM -DQWS -I${QPEDIR}/include -I${QTDIR}/include/ -DNO_DEBUG -fno-rtti -fno-exceptions" + SYSTEM_LIBS="$SYSTEM_LIBS -:${QPEDIR}/lib -L${QTDIR}/lib/ -lqpe -lqte" + VIDEO_SUBDIRS="$VIDEO_SUBDIRS qtopia" + VIDEO_DRIVERS="$VIDEO_DRIVERS qtopia/libvideo_qtopia.la" + fi + AC_LANG_C + fi +} + dnl Set up the Mac toolbox video driver for Mac OS 7-9 CheckTOOLBOX() { @@ -1420,7 +1450,7 @@ case "$target" in ARCH=linux CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckNASM CheckOSS CheckALSA @@ -1436,11 +1466,18 @@ case "$target" in CheckGGI CheckSVGA CheckAAlib + CheckQtopia CheckOpenGL CheckInputEvents CheckPTHREAD # Set up files for the main() stub - COPY_ARCH_SRC(src/main, linux, SDL_main.c) + if test "x$video_qtopia" = "xyes"; then + COPY_ARCH_SRC(src/main, linux, SDL_Qtopia_main.cc) + SDL_CFLAGS="$SDL_CFLAGS -Dmain=SDL_main" + SDL_LIBS="-lSDLmain $SDL_LIBS" + else + COPY_ARCH_SRC(src/main, linux, SDL_main.c) + fi # Set up files for the audio library # We use the OSS and ALSA API's, not the Sun audio API #if test x$enable_audio = xyes; then @@ -1479,7 +1516,11 @@ case "$target" in else COPY_ARCH_SRC(src/thread, linux, SDL_sysmutex.c) COPY_ARCH_SRC(src/thread, linux, SDL_sysmutex_c.h) - COPY_ARCH_SRC(src/thread, linux, SDL_syscond.c) + if test x$has_recursive_mutexes != xyes; then + COPY_ARCH_SRC(src/thread, generic, SDL_syscond.c) + else + COPY_ARCH_SRC(src/thread, linux, SDL_syscond.c) + fi COPY_ARCH_SRC(src/thread, generic, SDL_syscond_c.h) fi fi @@ -1492,7 +1533,7 @@ case "$target" in ARCH=bsdi CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckNASM CheckOSS CheckARTSC @@ -1544,7 +1585,7 @@ case "$target" in ARCH=freebsd CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckVGL CheckNASM CheckOSS @@ -1601,7 +1642,7 @@ case "$target" in ARCH=netbsd CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckNASM CheckOSS CheckARTSC @@ -1656,7 +1697,7 @@ case "$target" in ARCH=openbsd CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckNASM CheckOSS CheckARTSC @@ -1715,7 +1756,7 @@ case "$target" in ARCH=sysv5 CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckNASM CheckOSS CheckARTSC @@ -1765,7 +1806,7 @@ case "$target" in CFLAGS="$CFLAGS -D__ELF__" # Fix for nasm on Solaris x86 CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckNASM CheckOSS CheckARTSC @@ -1814,7 +1855,7 @@ case "$target" in ARCH=irix CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckDMEDIA CheckESD CheckNAS @@ -1877,7 +1918,7 @@ case "$target" in ARCH=hpux CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckOSS CheckNAS CheckX11 @@ -1925,7 +1966,7 @@ case "$target" in ARCH=aix CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckOSS CheckNAS CheckX11 @@ -1971,7 +2012,7 @@ case "$target" in ARCH=osf CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckNAS CheckX11 CheckGGI @@ -2018,7 +2059,7 @@ case "$target" in ARCH=qnx CheckDummyVideo CheckDiskAudio - CheckDLOPEN + CheckDLOPEN CheckNAS CheckPHOTON CheckX11 @@ -2330,6 +2371,7 @@ AC_SUBST(ARCH) # Set the conditional variables for this target AM_CONDITIONAL(TARGET_LINUX, test $ARCH = linux) +AM_CONDITIONAL(TARGET_QTOPIA, test "x$video_qtopia" = "xyes") AM_CONDITIONAL(TARGET_SOLARIS, test $ARCH = solaris) AM_CONDITIONAL(TARGET_IRIX, test $ARCH = irix) AM_CONDITIONAL(TARGET_BSDI, test $ARCH = bsdi) @@ -2486,6 +2528,7 @@ src/video/dummy/Makefile src/video/ataricommon/Makefile src/video/xbios/Makefile src/video/gem/Makefile +src/video/qtopia/Makefile src/events/Makefile src/joystick/Makefile src/joystick/amigaos/Makefile diff --git a/include/SDL_main.h b/include/SDL_main.h index 6cdad2475..a20f9ba1e 100644 --- a/include/SDL_main.h +++ b/include/SDL_main.h @@ -31,7 +31,8 @@ static char rcsid = /* Redefine main() on Win32 and MacOS so that it is called by winmain.c */ #if defined(WIN32) || (defined(__MWERKS__) && !defined(__BEOS__)) || \ - defined(macintosh) || defined(__APPLE__) || defined(__SYMBIAN32__) + defined(macintosh) || defined(__APPLE__) || defined(__SYMBIAN32__) || \ + defined(QWS) #ifdef __cplusplus #define C_LINKAGE "C" diff --git a/src/main/Makefile.am b/src/main/Makefile.am index 898ba62b1..5bc50790e 100644 --- a/src/main/Makefile.am +++ b/src/main/Makefile.am @@ -17,9 +17,12 @@ lib_LIBRARIES = libSDLmain.a if TARGET_MACOSX MAINLIB_ARCH_SRCS = SDLMain.m SDLMain.h else +if TARGET_QTOPIA +MAINLIB_ARCH_SRCS = SDL_Qtopia_main.cc +else MAINLIB_ARCH_SRCS = SDL_main.c endif - +endif libSDLmain_a_SOURCES = $(MAINLIB_ARCH_SRCS) # Build an internal library of any special app setup functions diff --git a/src/main/linux/SDL_Qtopia_main.cc b/src/main/linux/SDL_Qtopia_main.cc new file mode 100644 index 000000000..6dfdbb743 --- /dev/null +++ b/src/main/linux/SDL_Qtopia_main.cc @@ -0,0 +1,24 @@ + +/* Include the SDL main definition header */ +#include "SDL_main.h" +#ifdef main +#undef main +#endif +#ifdef QWS +#include +#include +#endif + +extern int SDL_main(int argc, char *argv[]); + +int main(int argc, char *argv[]) +{ +#ifdef QWS + // This initializes the Qtopia application. It needs to be done here + // because it parses command line options. + QPEApplication *app = new QPEApplication(argc, argv); + QWidget dummy; + app->showMainWidget(&dummy); +#endif + return(SDL_main(argc, argv)); +} diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 65b653d87..589ddab1e 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -398,6 +398,9 @@ extern VideoBootStrap XBIOS_bootstrap; #ifdef ENABLE_GEM extern VideoBootStrap GEM_bootstrap; #endif +#ifdef ENABLE_QTOPIA +extern VideoBootStrap Qtopia_bootstrap; +#endif /* This is the current video device */ extern SDL_VideoDevice *current_video; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index e7b27f5fe..2eefcd743 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -110,6 +110,9 @@ static VideoBootStrap *bootstrap[] = { #endif #ifdef ENABLE_GEM &GEM_bootstrap, +#endif +#ifdef ENABLE_QTOPIA + &Qtopia_bootstrap, #endif NULL }; diff --git a/src/video/qtopia/.cvsignore b/src/video/qtopia/.cvsignore new file mode 100644 index 000000000..899d53557 --- /dev/null +++ b/src/video/qtopia/.cvsignore @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.libs +*.o +*.lo +*.la diff --git a/src/video/qtopia/Makefile.am b/src/video/qtopia/Makefile.am new file mode 100644 index 000000000..f1cb8ca16 --- /dev/null +++ b/src/video/qtopia/Makefile.am @@ -0,0 +1,20 @@ + +## Makefile.am for SDL using the Qtopia backend + +noinst_LTLIBRARIES = libvideo_qtopia.la +libvideo_qtopia_la_SOURCES = $(QTOPIA_SRCS) + +# The SDL BWindow video driver sources +QTOPIA_SRCS = \ + SDL_QWin.h \ + SDL_QWin.cc \ + SDL_QPEApp.h \ + SDL_QPEApp.cc \ + SDL_lowvideo.h \ + SDL_sysmouse.cc \ + SDL_sysmouse_c.h \ + SDL_sysvideo.cc \ + SDL_syswm.cc \ + SDL_syswm_c.h \ + SDL_sysevents.cc \ + SDL_sysevents_c.h diff --git a/src/video/qtopia/SDL_QPEApp.cc b/src/video/qtopia/SDL_QPEApp.cc new file mode 100644 index 000000000..394c6f4e4 --- /dev/null +++ b/src/video/qtopia/SDL_QPEApp.cc @@ -0,0 +1,62 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#include +#include +#include + +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_error.h" + +/* Flag to tell whether or not the Be application is active or not */ +int SDL_QPEAppActive = 0; +static QPEApplication *app; + +int SDL_InitQPEApp() { + if(SDL_QPEAppActive <= 0) { + if(!qApp) { + int argc = 1; + char *argv[] = { { "SDLApp" } }; + app = new QPEApplication(argc, argv); + QWidget dummy; + app->showMainWidget(&dummy); + } else { + app = (QPEApplication*)qApp; + } + SDL_QPEAppActive++; + } + return 0; +} + +/* Quit the QPE Application, if there's nothing left to do */ +void SDL_QuitQPEApp(void) +{ + /* Decrement the application reference count */ + SDL_QPEAppActive--; + /* If the reference count reached zero, clean up the app */ + if ( SDL_QPEAppActive == 0 && app) { + delete app; + app = 0; + qApp = 0; + } +} diff --git a/src/video/qtopia/SDL_QPEApp.h b/src/video/qtopia/SDL_QPEApp.h new file mode 100644 index 000000000..5889f03f2 --- /dev/null +++ b/src/video/qtopia/SDL_QPEApp.h @@ -0,0 +1,37 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* Handle the QPE application loop */ + +/* Initialize the QPE Application, if it's not already started */ +extern int SDL_InitQPEApp(void); + +/* Quit the QPE Application, if there's nothing left to do */ +extern void SDL_QuitQPEApp(void); + +/* Flag to tell whether the app is active or not */ +extern int SDL_QPEAppActive; diff --git a/src/video/qtopia/SDL_QWin.cc b/src/video/qtopia/SDL_QWin.cc new file mode 100644 index 000000000..5b343f97a --- /dev/null +++ b/src/video/qtopia/SDL_QWin.cc @@ -0,0 +1,333 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include "SDL_QWin.h" +#include +#include +SDL_QWin::SDL_QWin(const QSize& size) + : QWidget(0, "SDL_main"), my_painter(0), my_image(0), + my_inhibit_resize(false), my_mouse_pos(-1,-1), my_flags(0), + my_has_fullscreen(false), my_locked(0) +{ + setBackgroundMode(NoBackground); +} + +SDL_QWin::~SDL_QWin() { + // Nothing to do yet. + if(my_image) { + delete my_image; + } +} + +void SDL_QWin::setImage(QImage *image) { + if ( my_image ) { + delete my_image; + } + my_image = image; + // setFixedSize(image->size()); +} + +void SDL_QWin::resizeEvent(QResizeEvent *e) { + if(size() != qApp->desktop()->size()) { + // Widget is not the correct size, so do the fullscreen magic + my_has_fullscreen = false; + enableFullscreen(); + } + if(my_inhibit_resize) { + my_inhibit_resize = false; + } else { + SDL_PrivateResize(e->size().width(), e->size().height()); + } +} + +void SDL_QWin::focusInEvent(QFocusEvent *) { + // Always do it here, no matter the size. + enableFullscreen(); + SDL_PrivateAppActive(true, SDL_APPINPUTFOCUS); +} + +void SDL_QWin::focusOutEvent(QFocusEvent *) { + my_has_fullscreen = false; + SDL_PrivateAppActive(false, SDL_APPINPUTFOCUS); +} + +void SDL_QWin::closeEvent(QCloseEvent *e) { + SDL_PrivateQuit(); + e->ignore(); +} + +void SDL_QWin::mouseMoveEvent(QMouseEvent *e) { + Qt::ButtonState button = e->button(); + int sdlstate = 0; + if( (button & Qt::LeftButton)) { + sdlstate |= SDL_BUTTON_LMASK; + } + if( (button & Qt::RightButton)) { + sdlstate |= SDL_BUTTON_RMASK; + } + if( (button & Qt::MidButton)) { + sdlstate |= SDL_BUTTON_MMASK; + } + SDL_PrivateMouseMotion(sdlstate, 0, e->pos().x(), e->pos().y()); +} + +void SDL_QWin::mousePressEvent(QMouseEvent *e) { + my_mouse_pos = e->pos(); + Qt::ButtonState button = e->button(); + SDL_PrivateMouseButton(SDL_PRESSED, + (button & Qt::LeftButton) ? 1 : + ((button & Qt::RightButton) ? 2 : 3), + e->x(), e->y()); +} + +void SDL_QWin::mouseReleaseEvent(QMouseEvent *e) { + my_mouse_pos = QPoint(-1, -1); + Qt::ButtonState button = e->button(); + SDL_PrivateMouseButton(SDL_RELEASED, + (button & Qt::LeftButton) ? 1 : + ((button & Qt::RightButton) ? 2 : 3), + e->x(), e->y()); +} + +#define USE_DIRECTPAINTER + + +#ifndef __i386__ +static inline void gs_fastRotateBlit_3 ( unsigned short *fb, + unsigned short *bits, + const QRect& rect ) +{ + int startx, starty; + int width, height; + + startx = rect.left() >> 1; + starty = rect.top() >> 1; + width = ((rect.right() - rect.left()) >> 1) + 2; + height = ((rect.bottom() - rect.top()) >> 1) + 2; + + if((startx+width) > 120) { + width = 120 - startx; // avoid horizontal overflow + } + if((starty+height) > 160) { + height = 160 - starty; // avoid vertical overflow + } + + ulong *sp1, *sp2, *dp1, *dp2; + ulong stop, sbot, dtop, dbot; + + sp1 = (ulong*)bits + startx + starty*240; + sp2 = sp1 + 120; + dp1 = (ulong *)fb + (159 - starty) + startx*320; + dp2 = dp1 + 160; + int rowadd = (-320*width) - 1; + int rowadd2 = 240 - width; + // transfer in cells of 2x2 pixels in words + for (int y=0; y>16) + (stop & 0xffff0000); + // write to framebuffer + *dp1 = dtop; + *dp2 = dbot; + // update source ptrs + sp1++; sp2++; + // update dest ptrs - 2 pix at a time + dp1 += 320; + dp2 += 320; + } + // adjust src ptrs - skip a row as we work in pairs + sp1 += rowadd2; + sp2 += rowadd2; + // adjust dest ptrs for rotation + dp1 += rowadd; + dp2 += rowadd; + } +} +#endif + +void SDL_QWin::repaintRect(const QRect& rect) { + if(!my_painter || !rect.width() || !rect.height()) { + return; + } +#ifndef __i386__ + + if(QPixmap::defaultDepth() == 16 && + my_painter->transformOrientation() == 3 && + my_painter->numRects() >= 0) { + if(my_image->width() == width()) { + ushort *fb = (ushort*)my_painter->frameBuffer(); + ushort *buf = (ushort*)my_image->bits(); + gs_fastRotateBlit_3(fb, buf, rect); + } else { + // landscape mode + uchar *fb = (uchar*)my_painter->frameBuffer(); + uchar *buf = (uchar*)my_image->bits(); + int h = rect.height(); + int wd = rect.width()<<1; + int fblineadd = my_painter->lineStep(); + int buflineadd = my_image->bytesPerLine(); + fb += (rect.left()<<1) + rect.top() * my_painter->lineStep(); + buf += (rect.left()<<1) + rect.top() * my_image->bytesPerLine(); + while(h--) { + memcpy(fb, buf, wd); + fb += fblineadd; + buf += buflineadd; + } + } + } else { +#endif + QPainter pp(this); + pp.drawImage(rect.topLeft(), *my_image, rect); + pp.end(); +#ifndef __i386__ + } +#endif +} + +// This paints the current buffer to the screen, when desired. +void SDL_QWin::paintEvent(QPaintEvent *ev) { + if(my_image && isVisible() && isActiveWindow()) { + lockScreen(); + repaintRect(ev->rect()); + unlockScreen(); + } +} + +/* Function to translate a keyboard transition and queue the key event */ +void SDL_QWin::QueueKey(QKeyEvent *e, int pressed) +{ + SDL_keysym keysym; + int scancode = e->key(); + /* Set the keysym information */ + if(scancode >= 'A' && scancode <= 'Z') { + // Qt sends uppercase, SDL wants lowercase + keysym.sym = static_cast(scancode + 32); + } else if(scancode >= 0x1000) { + // Special keys + switch(scancode) { + case Qt::Key_Escape: scancode = SDLK_ESCAPE; break; + case Qt::Key_Tab: scancode = SDLK_TAB; break; + case Qt::Key_Backspace: scancode = SDLK_BACKSPACE; break; + case Qt::Key_Return: scancode = SDLK_RETURN; break; + case Qt::Key_Enter: scancode = SDLK_KP_ENTER; break; + case Qt::Key_Insert: scancode = SDLK_INSERT; break; + case Qt::Key_Delete: scancode = SDLK_DELETE; break; + case Qt::Key_Pause: scancode = SDLK_PAUSE; break; + case Qt::Key_Print: scancode = SDLK_PRINT; break; + case Qt::Key_SysReq: scancode = SDLK_SYSREQ; break; + case Qt::Key_Home: scancode = SDLK_HOME; break; + case Qt::Key_End: scancode = SDLK_END; break; + case Qt::Key_Left: scancode = SDLK_LEFT; break; + case Qt::Key_Up: scancode = SDLK_UP; break; + case Qt::Key_Right: scancode = SDLK_RIGHT; break; + case Qt::Key_Down: scancode = SDLK_DOWN; break; + case Qt::Key_Prior: scancode = SDLK_PAGEUP; break; + case Qt::Key_Next: scancode = SDLK_PAGEDOWN; break; + case Qt::Key_Shift: scancode = SDLK_LSHIFT; break; + case Qt::Key_Control: scancode = SDLK_LCTRL; break; + case Qt::Key_Meta: scancode = SDLK_LMETA; break; + case Qt::Key_Alt: scancode = SDLK_LALT; break; + case Qt::Key_CapsLock: scancode = SDLK_CAPSLOCK; break; + case Qt::Key_NumLock: scancode = SDLK_NUMLOCK; break; + case Qt::Key_ScrollLock: scancode = SDLK_SCROLLOCK; break; + case Qt::Key_F1: scancode = SDLK_F1; break; + case Qt::Key_F2: scancode = SDLK_F2; break; + case Qt::Key_F3: scancode = SDLK_F3; break; + case Qt::Key_F4: scancode = SDLK_F4; break; + case Qt::Key_F5: scancode = SDLK_F5; break; + case Qt::Key_F6: scancode = SDLK_F6; break; + case Qt::Key_F7: scancode = SDLK_F7; break; + case Qt::Key_F8: scancode = SDLK_F8; break; + case Qt::Key_F9: scancode = SDLK_F9; break; + case Qt::Key_F10: scancode = SDLK_F10; break; + case Qt::Key_F11: scancode = SDLK_F11; break; + case Qt::Key_F12: scancode = SDLK_F12; break; + case Qt::Key_F13: scancode = SDLK_F13; break; + case Qt::Key_F14: scancode = SDLK_F14; break; + case Qt::Key_F15: scancode = SDLK_F15; break; + case Qt::Key_Super_L: scancode = SDLK_LSUPER; break; + case Qt::Key_Super_R: scancode = SDLK_RSUPER; break; + case Qt::Key_Menu: scancode = SDLK_MENU; break; + case Qt::Key_Help: scancode = SDLK_HELP; break; + default: + scancode = SDLK_UNKNOWN; + break; + } + keysym.sym = static_cast(scancode); + } else { + keysym.sym = static_cast(scancode); + } + keysym.scancode = scancode; + keysym.mod = KMOD_NONE; + ButtonState st = e->state(); + if( (st & ShiftButton) ) { keysym.mod = static_cast(keysym.mod | KMOD_LSHIFT); } + if( (st & ControlButton) ) { keysym.mod = static_cast(keysym.mod | KMOD_LCTRL); } + if( (st & AltButton) ) { keysym.mod = static_cast(keysym.mod | KMOD_LALT); } + if ( SDL_TranslateUNICODE ) { + QChar qchar = e->text()[0]; + keysym.unicode = qchar.unicode(); + } else { + keysym.unicode = 0; + } + + /* NUMLOCK and CAPSLOCK are implemented as double-presses in reality */ + // if ( (keysym.sym == SDLK_NUMLOCK) || (keysym.sym == SDLK_CAPSLOCK) ) { + // pressed = 1; + // } + + /* Queue the key event */ + if ( pressed ) { + SDL_PrivateKeyboard(SDL_PRESSED, &keysym); + } else { + SDL_PrivateKeyboard(SDL_RELEASED, &keysym); + } +} + +void SDL_QWin::setFullscreen(bool fs_on) { + my_has_fullscreen = false; + enableFullscreen(); +} + +void SDL_QWin::enableFullscreen() { + // Make sure size is correct + if(!my_has_fullscreen) { + setFixedSize(qApp->desktop()->size()); + // This call is needed because showFullScreen won't work + // correctly if the widget already considers itself to be fullscreen. + showNormal(); + // This is needed because showNormal() forcefully changes the window + // style to WSTyle_TopLevel. + setWFlags(WStyle_Customize | WStyle_NoBorder); + // Enable fullscreen. + showFullScreen(); + my_has_fullscreen = true; + } +} diff --git a/src/video/qtopia/SDL_QWin.h b/src/video/qtopia/SDL_QWin.h new file mode 100644 index 000000000..2d0058889 --- /dev/null +++ b/src/video/qtopia/SDL_QWin.h @@ -0,0 +1,128 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#ifndef _SDL_QWin_h +#define _SDL_QWin_h +#include + +#include +#include +#include +#include +#include + +#include "SDL_events.h" +//#include "SDL_BView.h" + +extern "C" { +#include "SDL_events_c.h" +}; + +class SDL_QWin : public QWidget +{ + void QueueKey(QKeyEvent *e, int pressed); + public: + SDL_QWin(const QSize& size); + virtual ~SDL_QWin(); + virtual bool shown(void) { + return isVisible(); + } + /* If called, the next resize event will not be forwarded to SDL. */ + virtual void inhibitResize(void) { + my_inhibit_resize = true; + } + void setImage(QImage *image); + void setOffset(int x, int y) { + my_offset = QPoint(x, y); + } + void GetXYOffset(int &x, int &y) { + x = my_offset.x(); + y = my_offset.y(); + } + bool beginDraw(void) { + return true; + } + void endDraw(void) { + } + QImage *image(void) { + return my_image; + } + + void setWFlags(WFlags flags) { + QWidget::setWFlags(flags); + my_flags = flags; + } + const QPoint& mousePos() const { return my_mouse_pos; } + void setMousePos(const QPoint& newpos) { my_mouse_pos = newpos; } + void setFullscreen(bool); + + void lockScreen() { + if(!my_painter) { + my_painter = new QDirectPainter(this); + } + my_locked++; // Increate lock refcount + } + void unlockScreen() { + if(my_locked > 0) { + my_locked--; // decrease lock refcount; + } + if(!my_locked && my_painter) { + my_painter->end(); + delete my_painter; + my_painter = 0; + } + } + void repaintRect(const QRect& rect); + protected: + /* Handle resizing of the window */ + virtual void resizeEvent(QResizeEvent *e); + void focusInEvent(QFocusEvent *); + void focusOutEvent(QFocusEvent *); + void closeEvent(QCloseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + void paintEvent(QPaintEvent *ev); + void keyPressEvent(QKeyEvent *e) { + QueueKey(e, 1); + } + void keyReleaseEvent(QKeyEvent *e) { + QueueKey(e, 0); + } + private: + void enableFullscreen(); + QDirectPainter *my_painter; + QImage *my_image; + bool my_inhibit_resize; + QPoint my_offset; + QPoint my_mouse_pos; + WFlags my_flags; + WFlags my_has_fullscreen; + unsigned int my_locked; +}; + +#endif /* _SDL_QWin_h */ diff --git a/src/video/qtopia/SDL_lowvideo.h b/src/video/qtopia/SDL_lowvideo.h new file mode 100644 index 000000000..62c815783 --- /dev/null +++ b/src/video/qtopia/SDL_lowvideo.h @@ -0,0 +1,69 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#ifndef _SDL_lowvideo_h +#define _SDL_lowvideo_h + +#include "SDL_mouse.h" +#include "SDL_sysvideo.h" + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_VideoDevice *_this + +/* Private display data */ +struct SDL_PrivateVideoData { + /* The main window */ + SDL_QWin *SDL_Win; + + /* The fullscreen mode list */ +#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ + int SDL_nummodes[NUM_MODELISTS]; + SDL_Rect **SDL_modelist[NUM_MODELISTS]; + + /* A completely clear cursor */ + WMcursor *BlankCursor; + + /* Mouse state variables */ + Uint32 last_buttons; + QPoint last_point; + + /* Keyboard state variables */ + int key_flip; + //struct key_info keyinfo[2]; +}; +/* Old variable names */ +#define SDL_Win (_this->hidden->SDL_Win) +#define saved_mode (_this->hidden->saved_mode) +#define SDL_nummodes (_this->hidden->SDL_nummodes) +#define SDL_modelist (_this->hidden->SDL_modelist) +#define SDL_BlankCursor (_this->hidden->BlankCursor) +#define last_buttons (_this->hidden->last_buttons) +#define last_point (_this->hidden->last_point) +#define key_flip (_this->hidden->key_flip) +#define keyinfo (_this->hidden->keyinfo) + +#endif /* _SDL_lowvideo_h */ diff --git a/src/video/qtopia/SDL_sysevents.cc b/src/video/qtopia/SDL_sysevents.cc new file mode 100644 index 000000000..0e1652250 --- /dev/null +++ b/src/video/qtopia/SDL_sysevents.cc @@ -0,0 +1,273 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include + +#include +#include +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_QWin.h" +#include "SDL_lowvideo.h" +#include "SDL_timer.h" + +extern "C" { +#include "SDL_events_c.h" +#include "SDL_sysevents.h" +#include "SDL_sysevents_c.h" + + // static SDLKey keymap[128]; +/* This is special because we know it will be run in a loop in a separate + thread. Normally this function should loop as long as there are input + states changing, i.e. new events arriving. +*/ +void QT_PumpEvents(_THIS) +{ + if(!qApp) { + return; + } + // printf("processing events: %p\n", qApp); + //qApp->processOneEvent(); // wait for a event + qApp->processEvents(); // and process all outstanding ones +#if 0 + BView *view; + BRect bounds; + BPoint point; + uint32 buttons; + const uint32 button_masks[3] = { + B_PRIMARY_MOUSE_BUTTON, + B_TERTIARY_MOUSE_BUTTON, + B_SECONDARY_MOUSE_BUTTON, + }; + unsigned int i, j; + + /* Check out the mouse buttons and position (slight race condition) */ + if ( SDL_Win->Lock() ) { + /* Don't do anything if we have no view */ + view = SDL_Win->View(); + if ( ! view ) { + SDL_Win->Unlock(); + return; + } + bounds = view->Bounds(); + /* Get new input state, if still active */ + if ( SDL_Win->IsActive() ) { + key_flip = !key_flip; + get_key_info(&keyinfo[key_flip]); + view->GetMouse(&point, &buttons, true); + } else { + key_flip = key_flip; + point = last_point; + buttons = last_buttons; + } + SDL_Win->Unlock(); + } else { + return; + } + + /* If our view is active, we'll find key changes here */ + if ( memcmp(keyinfo[0].key_states, keyinfo[1].key_states, 16) != 0 ) { + for ( i=0; i<16; ++i ) { + Uint8 new_state, transition; + + new_state = keyinfo[key_flip].key_states[i]; + transition = keyinfo[!key_flip].key_states[i] ^ + keyinfo[ key_flip].key_states[i]; + for ( j=0; j<8; ++j ) { + if ( transition&0x80 ) + QueueKey(i*8+j, new_state&0x80); + transition <<= 1; + new_state <<= 1; + } + } + } + + /* We check keyboard, but not mouse if mouse isn't in window */ + if ( ! bounds.Contains(point) ) { + /* Mouse moved outside our view? */ + if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { + SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); + be_app->SetCursor(B_HAND_CURSOR); + } + return; + } + /* Has the mouse moved back into our view? */ + if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { + /* Reset the B_HAND_CURSOR to our own */ + SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); + SDL_SetCursor(NULL); + } + + /* Check for mouse motion */ + if ( point != last_point ) { + int x, y; + + SDL_Win->GetXYOffset(x, y); + x = (int)point.x - x; + y = (int)point.y - y; + SDL_PrivateMouseMotion(0, 0, x, y); + } + last_point = point; + + /* Add any mouse button events */ + for ( i=0; i +#include + + +#include "SDL_error.h" +#include "SDL_QWin.h" + +extern "C" { + +#include "SDL_sysmouse_c.h" + +/* The implementation dependent data for the window manager cursor */ +struct WMcursor { + char *bits; +}; +WMcursor *QT_CreateWMCursor(_THIS, + Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) +{ + static WMcursor dummy; + dummy.bits = 0; + return &dummy; +} + +int QT_ShowWMCursor(_THIS, WMcursor *cursor) +{ + return 1; +} + +void QT_FreeWMCursor(_THIS, WMcursor *cursor) +{ +} + +void QT_WarpWMCursor(_THIS, Uint16 x, Uint16 y) +{ + SDL_Win->setMousePos(QPoint(x, y)); +} + +}; /* Extern C */ diff --git a/src/video/qtopia/SDL_sysmouse_c.h b/src/video/qtopia/SDL_sysmouse_c.h new file mode 100644 index 000000000..97b066ab3 --- /dev/null +++ b/src/video/qtopia/SDL_sysmouse_c.h @@ -0,0 +1,36 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include "SDL_lowvideo.h" + +/* Functions to be exported */ +extern void QT_FreeWMCursor(_THIS, WMcursor *cursor); +extern WMcursor *QT_CreateWMCursor(_THIS, + Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); +extern int QT_ShowWMCursor(_THIS, WMcursor *cursor); +extern void QT_WarpWMCursor(_THIS, Uint16 x, Uint16 y); + diff --git a/src/video/qtopia/SDL_sysvideo.cc b/src/video/qtopia/SDL_sysvideo.cc new file mode 100644 index 000000000..837952ca2 --- /dev/null +++ b/src/video/qtopia/SDL_sysvideo.cc @@ -0,0 +1,376 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* Qtopia based framebuffer implementation */ + +#include +#include + +#include +#include + +#include + +#include "SDL.h" +#include "SDL_timer.h" + +#include "SDL_QWin.h" +#include "SDL_QPEApp.h" + +extern "C" { + +#include "SDL_sysvideo.h" +#include "SDL_sysmouse_c.h" +#include "SDL_sysevents_c.h" +#include "SDL_events_c.h" +#include "SDL_syswm_c.h" +#include "SDL_lowvideo.h" + + //#define QTOPIA_DEBUG +#define QT_HIDDEN_SIZE 32 /* starting hidden window size */ + + /* Initialization/Query functions */ + static int QT_VideoInit(_THIS, SDL_PixelFormat *vformat); + static SDL_Rect **QT_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); + static SDL_Surface *QT_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); + static void QT_UpdateMouse(_THIS); + static int QT_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); + static void QT_VideoQuit(_THIS); + + /* Hardware surface functions */ + static int QT_AllocHWSurface(_THIS, SDL_Surface *surface); + static int QT_LockHWSurface(_THIS, SDL_Surface *surface); + static void QT_UnlockHWSurface(_THIS, SDL_Surface *surface); + static void QT_FreeHWSurface(_THIS, SDL_Surface *surface); + + static int QT_ToggleFullScreen(_THIS, int fullscreen); + + + /* FB driver bootstrap functions */ + + static int QT_Available(void) + { + return(1); + } + + static void QT_DeleteDevice(SDL_VideoDevice *device) + { + free(device->hidden); + free(device); + } + + static SDL_VideoDevice *QT_CreateDevice(int devindex) + { + SDL_VideoDevice *device; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); + if ( device ) { + memset(device, 0, (sizeof *device)); + device->hidden = (struct SDL_PrivateVideoData *) + malloc((sizeof *device->hidden)); + } + if ( (device == NULL) || (device->hidden == NULL) ) { + SDL_OutOfMemory(); + if ( device ) { + free(device); + } + return(0); + } + memset(device->hidden, 0, (sizeof *device->hidden)); + + /* Set the function pointers */ + device->VideoInit = QT_VideoInit; + device->ListModes = QT_ListModes; + device->SetVideoMode = QT_SetVideoMode; + device->UpdateMouse = QT_UpdateMouse; + device->SetColors = QT_SetColors; + device->UpdateRects = NULL; + device->VideoQuit = QT_VideoQuit; + device->AllocHWSurface = QT_AllocHWSurface; + device->CheckHWBlit = NULL; + device->FillHWRect = NULL; + device->SetHWColorKey = NULL; + device->SetHWAlpha = NULL; + device->LockHWSurface = QT_LockHWSurface; + device->UnlockHWSurface = QT_UnlockHWSurface; + device->FlipHWSurface = NULL; + device->FreeHWSurface = QT_FreeHWSurface; + device->SetIcon = NULL; + device->SetCaption = QT_SetWMCaption; + device->GetWMInfo = NULL; + device->FreeWMCursor = QT_FreeWMCursor; + device->CreateWMCursor = QT_CreateWMCursor; + device->ShowWMCursor = QT_ShowWMCursor; + device->WarpWMCursor = QT_WarpWMCursor; + device->InitOSKeymap = QT_InitOSKeymap; + device->PumpEvents = QT_PumpEvents; + + device->free = QT_DeleteDevice; + device->ToggleFullScreen = QT_ToggleFullScreen; + + /* Set the driver flags */ + device->handles_any_size = 0; + + return device; + } + + VideoBootStrap Qtopia_bootstrap = { + "qtopia", "Qtopia / QPE graphics", + QT_Available, QT_CreateDevice + }; + + /* Function to sort the display_list */ + static int CompareModes(const void *A, const void *B) + { +#if 0 + const display_mode *a = (display_mode *)A; + const display_mode *b = (display_mode *)B; + + if ( a->space == b->space ) { + return((b->virtual_width*b->virtual_height)- + (a->virtual_width*a->virtual_height)); + } else { + return(ColorSpaceToBitsPerPixel(b->space)- + ColorSpaceToBitsPerPixel(a->space)); + } +#endif + return 0; + } + + /* Yes, this isn't the fastest it could be, but it works nicely */ + static int QT_AddMode(_THIS, int index, unsigned int w, unsigned int h) + { + SDL_Rect *mode; + int i; + int next_mode; + + /* Check to see if we already have this mode */ + if ( SDL_nummodes[index] > 0 ) { + for ( i=SDL_nummodes[index]-1; i >= 0; --i ) { + mode = SDL_modelist[index][i]; + if ( (mode->w == w) && (mode->h == h) ) { + return(0); + } + } + } + + /* Set up the new video mode rectangle */ + mode = (SDL_Rect *)malloc(sizeof *mode); + if ( mode == NULL ) { + SDL_OutOfMemory(); + return(-1); + } + mode->x = 0; + mode->y = 0; + mode->w = w; + mode->h = h; +#ifdef QTOPIA_DEBUG + fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1); +#endif + + /* Allocate the new list of modes, and fill in the new mode */ + next_mode = SDL_nummodes[index]; + SDL_modelist[index] = (SDL_Rect **) + realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); + if ( SDL_modelist[index] == NULL ) { + SDL_OutOfMemory(); + SDL_nummodes[index] = 0; + free(mode); + return(-1); + } + SDL_modelist[index][next_mode] = mode; + SDL_modelist[index][next_mode+1] = NULL; + SDL_nummodes[index]++; + + return(0); + } + + int QT_VideoInit(_THIS, SDL_PixelFormat *vformat) + { + /* Initialize the QPE Application */ + if(SDL_InitQPEApp() == -1) { + return -1; + } + + /* Determine the screen depth */ + vformat->BitsPerPixel = QPixmap::defaultDepth(); + + // For now we hardcode the current depth because anything else + // might as well be emulated by SDL rather than by Qtopia. + + QSize desktop_size = qApp->desktop()->size(); + QT_AddMode(_this, ((vformat->BitsPerPixel+7)/8)-1, + desktop_size.width(), desktop_size.height()); + QT_AddMode(_this, ((vformat->BitsPerPixel+7)/8)-1, + desktop_size.height(), desktop_size.width()); + + /* Create the window / widget */ + SDL_Win = new SDL_QWin(QSize(QT_HIDDEN_SIZE, QT_HIDDEN_SIZE)); + qApp->setMainWidget(SDL_Win); + /* Fill in some window manager capabilities */ + _this->info.wm_available = 0; + + /* We're done! */ + return(0); + } + + /* We support any dimension at our bit-depth */ + SDL_Rect **QT_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) + { + SDL_Rect **modes; + + modes = ((SDL_Rect **)0); + if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { + modes = SDL_modelist[((format->BitsPerPixel+7)/8)-1]; + } else { + if ( format->BitsPerPixel == + _this->screen->format->BitsPerPixel ) { + modes = ((SDL_Rect **)-1); + } + } + return(modes); + } + + /* Various screen update functions available */ + static void QT_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); + + + static int QT_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen) + { + return -1; + } + + static int QT_ToggleFullScreen(_THIS, int fullscreen) + { + return -1; + } + + /* FIXME: check return values and cleanup here */ + SDL_Surface *QT_SetVideoMode(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags) + { + Qt::WFlags wflags = Qt::WType_TopLevel|Qt::WStyle_Customize; + QImage *qimage; + QSize desktop_size = qApp->desktop()->size(); + + + current->flags = SDL_FULLSCREEN; // We always run fullscreen. + + if(width <= desktop_size.width() && height <= desktop_size.height()) { + current->w = desktop_size.width(); + current->h = desktop_size.height(); + } else if(width <= desktop_size.height() + && height <= desktop_size.width()) { + // Landscape mode + current->h = desktop_size.width(); + current->w = desktop_size.height(); + } else { + SDL_SetError("Unsupported resolution, %dx%d\n", width, height); + } + if ( flags & SDL_OPENGL ) { + SDL_SetError("OpenGL not supported"); + return(NULL); + } + /* Create the QImage framebuffer */ + qimage = new QImage(current->w, current->h, bpp); + if (qimage->isNull()) { + SDL_SetError("Couldn't create screen bitmap"); + delete qimage; + return(NULL); + } + current->pitch = qimage->bytesPerLine(); + current->pixels = (void *)qimage->bits(); + SDL_Win->setImage(qimage); + _this->UpdateRects = QT_NormalUpdate; + SDL_Win->setFullscreen(true); + /* We're done */ + return(current); + } + + /* Update the current mouse state and position */ + void QT_UpdateMouse(_THIS) + { + QPoint point(-1, -1); + if ( SDL_Win->isActiveWindow() ) { + point = SDL_Win->mousePos(); + } + + if ( (point.x() >= 0) && (point.x() < SDL_VideoSurface->w) && + (point.y() >= 0) && (point.y() < SDL_VideoSurface->h) ) { + SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); + SDL_PrivateMouseMotion(0, 0, + (Sint16)point.x(), (Sint16)point.y()); + } else { + SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); + } + } + + /* We don't actually allow hardware surfaces other than the main one */ + static int QT_AllocHWSurface(_THIS, SDL_Surface *surface) + { + return(-1); + } + static void QT_FreeHWSurface(_THIS, SDL_Surface *surface) + { + return; + } + static int QT_LockHWSurface(_THIS, SDL_Surface *surface) + { + return(0); + } + static void QT_UnlockHWSurface(_THIS, SDL_Surface *surface) + { + return; + } + + static void QT_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) + { + int i; + SDL_Win->lockScreen(); + for ( i=0; irepaintRect(rect); + } + SDL_Win->unlockScreen(); + } + /* Is the system palette settable? */ + int QT_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) + { + return -1; + } + + void QT_VideoQuit(_THIS) + { + qApp->setMainWidget(0); + delete SDL_Win; + SDL_QuitQPEApp(); + _this->screen->pixels = NULL; + } + +}; /* Extern C */ diff --git a/src/video/qtopia/SDL_syswm.cc b/src/video/qtopia/SDL_syswm.cc new file mode 100644 index 000000000..1bb2b26e7 --- /dev/null +++ b/src/video/qtopia/SDL_syswm.cc @@ -0,0 +1,39 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include "SDL_QWin.h" + +extern "C" { + +#include "SDL_syswm_c.h" + +void QT_SetWMCaption(_THIS, const char *title, const char *icon) +{ + SDL_Win->setCaption(title); +} + +}; /* Extern C */ diff --git a/src/video/qtopia/SDL_syswm_c.h b/src/video/qtopia/SDL_syswm_c.h new file mode 100644 index 000000000..9ed01a93e --- /dev/null +++ b/src/video/qtopia/SDL_syswm_c.h @@ -0,0 +1,32 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include "SDL_lowvideo.h" + +/* Functions to be exported */ +extern void QT_SetWMCaption(_THIS, const char *title, const char *icon); +