Commit cfca6d1c authored by Sam Lantinga's avatar Sam Lantinga

From: David Hedbor

Subject: Qtopia patches (input grabbing and iconify)

Ok, here's a patch that adds support for SDL_WM_GrabInput (default
state is "ungrabbed") and SDL_WM_IconifyWindow. Also has some other
tweaks such as taking additional steps to clean up when exiting
(bypassing certain bugs in some versions of Qtopia and/or OPIE) and it
also maps Key_F33 to Key_Return (this is the Zaurus 'ok' key).

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40568
parent 879224b6
...@@ -1459,8 +1459,13 @@ CheckQtopia() ...@@ -1459,8 +1459,13 @@ CheckQtopia()
if test x$video_qtopia = xyes; then 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" CFLAGS="$CFLAGS -DENABLE_QTOPIA -DQT_QWS_EBX -DQT_QWS_CUSTOM -DQWS -I${QPEDIR}/include -I${QTDIR}/include/ -DNO_DEBUG -fno-rtti -fno-exceptions"
SDL_LIBS="$SDL_LIBS -L${QPEDIR}/lib -L${QTDIR}/lib/ -lqpe -lqte" SDL_LIBS="$SDL_LIBS -L${QPEDIR}/lib -L${QTDIR}/lib/ -lqpe -lqte"
SDL_CFLAGS="$SDL_CFLAGS -DQWS"
VIDEO_SUBDIRS="$VIDEO_SUBDIRS qtopia" VIDEO_SUBDIRS="$VIDEO_SUBDIRS qtopia"
VIDEO_DRIVERS="$VIDEO_DRIVERS qtopia/libvideo_qtopia.la" VIDEO_DRIVERS="$VIDEO_DRIVERS qtopia/libvideo_qtopia.la"
else
AC_MSG_ERROR([
*** Failed to find Qtopia includes. Make sure that the QTDIR and QPEDIR
*** environment variables are set correctly.])
fi fi
AC_LANG_C AC_LANG_C
fi fi
......
/* Include the SDL main definition header */ /* Include the SDL main definition header */
#include "SDL_main.h" #include "SDL_main.h"
#include <stdlib.h>
#include <unistd.h>
#ifdef main #ifdef main
#undef main #undef main
#endif #endif
#ifdef QWS #ifdef QWS
#include <qpe/qpeapplication.h> #include <qpe/qpeapplication.h>
#include <qapplication.h>
#include <qpe/qpeapplication.h>
#include <stdlib.h>
// Workaround for OPIE to remove taskbar icon. Also fixes
// some issues in Qtopia where there are left-over qcop files in /tmp/.
// I'm guessing this will also clean up the taskbar in the Sharp version
// of Qtopia.
static inline void cleanupQCop() {
QString appname(qApp->argv()[0]);
int slash = appname.findRev("/");
if(slash != -1) { appname = appname.mid(slash+1); }
QString cmd = QPEApplication::qpeDir() + "bin/qcop QPE/System 'closing(QString)' '"+appname+"'";
system(cmd.latin1());
cmd = "/tmp/qcop-msg-"+appname;
unlink(cmd.latin1());
}
static QPEApplication *app;
#endif #endif
extern int SDL_main(int argc, char *argv[]); extern int SDL_main(int argc, char *argv[]);
...@@ -15,9 +36,10 @@ int main(int argc, char *argv[]) ...@@ -15,9 +36,10 @@ int main(int argc, char *argv[])
#ifdef QWS #ifdef QWS
// This initializes the Qtopia application. It needs to be done here // This initializes the Qtopia application. It needs to be done here
// because it parses command line options. // because it parses command line options.
QPEApplication app(argc, argv);
QWidget dummy; QWidget dummy;
app.showMainWidget(&dummy); app = new QPEApplication(argc, argv);
app->showMainWidget(&dummy);
atexit(cleanupQCop);
#endif #endif
// Exit here because if return is used, the application // Exit here because if return is used, the application
// doesn't seem to quit correctly. // doesn't seem to quit correctly.
......
...@@ -54,6 +54,9 @@ static VideoBootStrap *bootstrap[] = { ...@@ -54,6 +54,9 @@ static VideoBootStrap *bootstrap[] = {
#ifdef ENABLE_NANOX #ifdef ENABLE_NANOX
&NX_bootstrap, &NX_bootstrap,
#endif #endif
#ifdef ENABLE_QTOPIA
&Qtopia_bootstrap,
#endif
#ifdef ENABLE_FBCON #ifdef ENABLE_FBCON
&FBCON_bootstrap, &FBCON_bootstrap,
#endif #endif
...@@ -111,9 +114,6 @@ static VideoBootStrap *bootstrap[] = { ...@@ -111,9 +114,6 @@ static VideoBootStrap *bootstrap[] = {
#ifdef ENABLE_GEM #ifdef ENABLE_GEM
&GEM_bootstrap, &GEM_bootstrap,
#endif #endif
#ifdef ENABLE_QTOPIA
&Qtopia_bootstrap,
#endif
#ifdef ENABLE_PICOGUI #ifdef ENABLE_PICOGUI
&PG_bootstrap, &PG_bootstrap,
#endif #endif
......
...@@ -129,14 +129,12 @@ void SDL_QWin::mouseReleaseEvent(QMouseEvent *e) { ...@@ -129,14 +129,12 @@ void SDL_QWin::mouseReleaseEvent(QMouseEvent *e) {
my_mouse_pos = QPoint(-1, -1); my_mouse_pos = QPoint(-1, -1);
} }
#define USE_DIRECTPAINTER static inline void
gs_fastRotateBlit_3 ( unsigned short *fb,
#ifndef __i386__
static inline void gs_fastRotateBlit_3 ( unsigned short *fb,
unsigned short *bits, unsigned short *bits,
const QRect& rect ) const QRect& rect )
{ {
// FIXME: this only works correctly for 240x320 displays
int startx, starty; int startx, starty;
int width, height; int width, height;
...@@ -187,17 +185,95 @@ static inline void gs_fastRotateBlit_3 ( unsigned short *fb, ...@@ -187,17 +185,95 @@ static inline void gs_fastRotateBlit_3 ( unsigned short *fb,
dp2 += rowadd; dp2 += rowadd;
} }
} }
#endif
void SDL_QWin::repaintRect(const QRect& rect) { static inline void
if(!my_painter || !rect.width() || !rect.height()) { gs_fastRotateBlit_1 ( unsigned short *fb,
return; unsigned short *bits,
const QRect& rect ) {
// FIXME: this only works correctly for 240x320 displays
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
} }
#ifndef __i386__
if(QPixmap::defaultDepth() == 16 && ulong *sp1, *sp2, *dp1, *dp2;
my_painter->transformOrientation() == 3 && ulong stop, sbot, dtop, dbot;
my_painter->numRects() >= 0) { fb += 320*239; // Move "fb" to top left corner
sp1 = (ulong*)bits + startx + starty*240;
sp2 = sp1 + 120;
dp1 = (ulong*)fb - startx * 320 - starty;
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<height; y++) {
for (int x=0; x<width; x++) {
// read
stop = *sp1;
sbot = *sp2;
// rotate
dtop = (stop & 0xffff) + ((sbot & 0xffff)<<16);
dbot = ((stop & 0xffff0000)>>16) + (sbot & 0xffff0000);
// write
*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;
}
}
// desktop, SL-A300 etc
bool SDL_QWin::repaintRotation0(const QRect& rect) {
if(my_image->width() == width()) {
uchar *fb = (uchar*)my_painter->frameBuffer();
uchar *buf = (uchar*)my_image->bits();
if(rect == my_image->rect()) {
memcpy(fb, buf, width()*height()*2);
} else {
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 {
return false; // FIXME: Landscape
}
#ifdef __i386__
my_painter->fillRect( rect, QBrush( Qt::NoBrush ) );
#endif
return true;
}
// Sharp Zaurus SL-5500 etc
bool SDL_QWin::repaintRotation3(const QRect& rect) {
if(my_image->width() == width()) { if(my_image->width() == width()) {
ushort *fb = (ushort*)my_painter->frameBuffer(); ushort *fb = (ushort*)my_painter->frameBuffer();
ushort *buf = (ushort*)my_image->bits(); ushort *buf = (ushort*)my_image->bits();
...@@ -222,8 +298,7 @@ void SDL_QWin::repaintRect(const QRect& rect) { ...@@ -222,8 +298,7 @@ void SDL_QWin::repaintRect(const QRect& rect) {
buf += buflineadd; buf += buflineadd;
} }
} }
} } else if (screenRotation == SDL_QT_ROTATION_270) {
else if (screenRotation == SDL_QT_ROTATION_270) {
int h = rect.height(); int h = rect.height();
int wd = rect.width(); int wd = rect.width();
int fblineadd = my_painter->lineStep() - (rect.width() << 1); int fblineadd = my_painter->lineStep() - (rect.width() << 1);
...@@ -248,26 +323,55 @@ void SDL_QWin::repaintRect(const QRect& rect) { ...@@ -248,26 +323,55 @@ void SDL_QWin::repaintRect(const QRect& rect) {
} }
} }
} }
return true;
}
// ipaq 3800...
bool SDL_QWin::repaintRotation1(const QRect& rect) {
if(my_image->width() == width()) {
ushort *fb = (ushort*)my_painter->frameBuffer();
ushort *buf = (ushort*)my_image->bits();
gs_fastRotateBlit_1(fb, buf, rect);
} else { } else {
#endif return false; // FIXME: landscape mode
QPainter pp(this);
pp.drawImage(rect.topLeft(), *my_image, rect);
pp.end();
#ifndef __i386__
} }
#endif return true;
}
void SDL_QWin::repaintRect(const QRect& rect) {
if(!my_painter || !rect.width() || !rect.height()) {
return;
}
if(QPixmap::defaultDepth() == 16) {
switch(my_painter->transformOrientation()) {
case 3:
if(repaintRotation3(rect)) { return; }
break;
case 1:
if(repaintRotation1(rect)) { return; }
break;
case 0:
if(repaintRotation0(rect)) { return; }
break;
}
}
my_painter->drawImage(rect.topLeft(), *my_image, rect);
} }
// This paints the current buffer to the screen, when desired. // This paints the current buffer to the screen, when desired.
void SDL_QWin::paintEvent(QPaintEvent *ev) { void SDL_QWin::paintEvent(QPaintEvent *ev) {
if(my_image && isVisible() && isActiveWindow()) { if(my_image) {
lockScreen(); lockScreen(true);
repaintRect(ev->rect()); repaintRect(ev->rect());
unlockScreen(); unlockScreen();
} }
} }
/* Function to translate a keyboard transition and queue the key event */ /* Function to translate a keyboard transition and queue the key event
* This should probably be a table although this method isn't exactly
* slow.
*/
void SDL_QWin::QueueKey(QKeyEvent *e, int pressed) void SDL_QWin::QueueKey(QKeyEvent *e, int pressed)
{ {
SDL_keysym keysym; SDL_keysym keysym;
...@@ -340,6 +444,14 @@ void SDL_QWin::QueueKey(QKeyEvent *e, int pressed) ...@@ -340,6 +444,14 @@ void SDL_QWin::QueueKey(QKeyEvent *e, int pressed)
case Qt::Key_Super_R: scancode = SDLK_RSUPER; break; case Qt::Key_Super_R: scancode = SDLK_RSUPER; break;
case Qt::Key_Menu: scancode = SDLK_MENU; break; case Qt::Key_Menu: scancode = SDLK_MENU; break;
case Qt::Key_Help: scancode = SDLK_HELP; break; case Qt::Key_Help: scancode = SDLK_HELP; break;
case Qt::Key_F33:
// FIXME: This is a hack to enable the OK key on
// Zaurii devices. SDLK_RETURN is a suitable key to use
// since it often is used as such.
// david@hedbor.org
scancode = SDLK_RETURN;
break;
default: default:
scancode = SDLK_UNKNOWN; scancode = SDLK_UNKNOWN;
break; break;
...@@ -394,3 +506,26 @@ void SDL_QWin::enableFullscreen() { ...@@ -394,3 +506,26 @@ void SDL_QWin::enableFullscreen() {
my_has_fullscreen = true; my_has_fullscreen = true;
} }
} }
bool SDL_QWin::lockScreen(bool force) {
if(!my_painter) {
if(force || (isVisible() && isActiveWindow())) {
my_painter = new QDirectPainter(this);
} else {
return false;
}
}
my_locked++; // Increate lock refcount
return true;
}
void SDL_QWin::unlockScreen() {
if(my_locked > 0) {
my_locked--; // decrease lock refcount;
}
if(!my_locked && my_painter) {
my_painter->end();
delete my_painter;
my_painter = 0;
}
}
...@@ -70,14 +70,7 @@ class SDL_QWin : public QWidget ...@@ -70,14 +70,7 @@ class SDL_QWin : public QWidget
x = my_offset.x(); x = my_offset.x();
y = my_offset.y(); y = my_offset.y();
} }
bool beginDraw(void) { QImage *image(void) { return my_image; }
return true;
}
void endDraw(void) {
}
QImage *image(void) {
return my_image;
}
void setWFlags(WFlags flags) { void setWFlags(WFlags flags) {
QWidget::setWFlags(flags); QWidget::setWFlags(flags);
...@@ -87,22 +80,8 @@ class SDL_QWin : public QWidget ...@@ -87,22 +80,8 @@ class SDL_QWin : public QWidget
void setMousePos(const QPoint& newpos); void setMousePos(const QPoint& newpos);
void setFullscreen(bool); void setFullscreen(bool);
void lockScreen() { bool lockScreen(bool force=false);
if(!my_painter) { void unlockScreen();
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); void repaintRect(const QRect& rect);
protected: protected:
/* Handle resizing of the window */ /* Handle resizing of the window */
...@@ -114,13 +93,12 @@ class SDL_QWin : public QWidget ...@@ -114,13 +93,12 @@ class SDL_QWin : public QWidget
void mousePressEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e);
void paintEvent(QPaintEvent *ev); void paintEvent(QPaintEvent *ev);
void keyPressEvent(QKeyEvent *e) { void keyPressEvent(QKeyEvent *e) { QueueKey(e, 1); }
QueueKey(e, 1); void keyReleaseEvent(QKeyEvent *e) { QueueKey(e, 0); }
}
void keyReleaseEvent(QKeyEvent *e) {
QueueKey(e, 0);
}
private: private:
bool repaintRotation0(const QRect& rect);
bool repaintRotation1(const QRect& rect);
bool repaintRotation3(const QRect& rect);
void enableFullscreen(); void enableFullscreen();
QDirectPainter *my_painter; QDirectPainter *my_painter;
QImage *my_image; QImage *my_image;
......
...@@ -53,7 +53,7 @@ extern "C" { ...@@ -53,7 +53,7 @@ extern "C" {
//#define QTOPIA_DEBUG //#define QTOPIA_DEBUG
#define QT_HIDDEN_SIZE 32 /* starting hidden window size */ #define QT_HIDDEN_SIZE 32 /* starting hidden window size */
/* Name of the environment variable used to invert the screen rotation or not: /* Name of the environment variable used to invert the screen rotation or not:
Possible values: Possible values:
!=0 : Screen is 270 rotated !=0 : Screen is 270 rotated
0: Screen is 90 rotated*/ 0: Screen is 90 rotated*/
...@@ -75,6 +75,8 @@ extern "C" { ...@@ -75,6 +75,8 @@ extern "C" {
static int QT_ToggleFullScreen(_THIS, int fullscreen); static int QT_ToggleFullScreen(_THIS, int fullscreen);
static int QT_IconifyWindow(_THIS);
static SDL_GrabMode QT_GrabInput(_THIS, SDL_GrabMode mode);
/* FB driver bootstrap functions */ /* FB driver bootstrap functions */
...@@ -128,6 +130,8 @@ extern "C" { ...@@ -128,6 +130,8 @@ extern "C" {
device->FreeHWSurface = QT_FreeHWSurface; device->FreeHWSurface = QT_FreeHWSurface;
device->SetIcon = NULL; device->SetIcon = NULL;
device->SetCaption = QT_SetWMCaption; device->SetCaption = QT_SetWMCaption;
device->IconifyWindow = QT_IconifyWindow;
device->GrabInput = QT_GrabInput;
device->GetWMInfo = NULL; device->GetWMInfo = NULL;
device->FreeWMCursor = QT_FreeWMCursor; device->FreeWMCursor = QT_FreeWMCursor;
device->CreateWMCursor = QT_CreateWMCursor; device->CreateWMCursor = QT_CreateWMCursor;
...@@ -281,7 +285,7 @@ extern "C" { ...@@ -281,7 +285,7 @@ extern "C" {
QSize desktop_size = qApp->desktop()->size(); QSize desktop_size = qApp->desktop()->size();
current->flags = SDL_FULLSCREEN; // We always run fullscreen. current->flags = 0; //SDL_FULLSCREEN; // We always run fullscreen.
if(width <= desktop_size.width() if(width <= desktop_size.width()
&& height <= desktop_size.height()) { && height <= desktop_size.height()) {
...@@ -355,15 +359,15 @@ extern "C" { ...@@ -355,15 +359,15 @@ extern "C" {
static void QT_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) static void QT_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
{ {
int i; if(SDL_Win->lockScreen()) {
SDL_Win->lockScreen(); for(int i=0; i<numrects; ++i ) {
for ( i=0; i<numrects; ++i ) {
QRect rect(rects[i].x, rects[i].y, QRect rect(rects[i].x, rects[i].y,
rects[i].w, rects[i].h); rects[i].w, rects[i].h);
SDL_Win->repaintRect(rect); SDL_Win->repaintRect(rect);
} }
SDL_Win->unlockScreen(); SDL_Win->unlockScreen();
} }
}
/* Is the system palette settable? */ /* Is the system palette settable? */
int QT_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) int QT_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{ {
...@@ -380,6 +384,25 @@ extern "C" { ...@@ -380,6 +384,25 @@ extern "C" {
// delete SDL_Win; // delete SDL_Win;
// SDL_Win = 0; // SDL_Win = 0;
_this->screen->pixels = NULL; _this->screen->pixels = NULL;
QT_GrabInput(_this, SDL_GRAB_OFF);
}
static int QT_IconifyWindow(_THIS) {
SDL_Win->hide();
return true;
}
static SDL_GrabMode QT_GrabInput(_THIS, SDL_GrabMode mode) {
if(mode == SDL_GRAB_OFF) {
QPEApplication::grabKeyboard();
qApp->processEvents();
QPEApplication::ungrabKeyboard();
} else {
QPEApplication::grabKeyboard();
}
qApp->processEvents();
return mode;
} }
}; /* Extern C */ }; /* Extern C */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment