comparison src/video/qtopia/SDL_QWin.cc @ 567:969fbd4dcd4e

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).
author Sam Lantinga <slouken@libsdl.org>
date Mon, 20 Jan 2003 01:08:20 +0000
parents c96e2137f9eb
children b8d311d90021
comparison
equal deleted inserted replaced
566:d6e7d7006062 567:969fbd4dcd4e
127 ((button & Qt::RightButton) ? 2 : 3), 127 ((button & Qt::RightButton) ? 2 : 3),
128 my_mouse_pos.x(), my_mouse_pos.y()); 128 my_mouse_pos.x(), my_mouse_pos.y());
129 my_mouse_pos = QPoint(-1, -1); 129 my_mouse_pos = QPoint(-1, -1);
130 } 130 }
131 131
132 #define USE_DIRECTPAINTER 132 static inline void
133 133 gs_fastRotateBlit_3 ( unsigned short *fb,
134 134 unsigned short *bits,
135 #ifndef __i386__ 135 const QRect& rect )
136 static inline void gs_fastRotateBlit_3 ( unsigned short *fb,
137 unsigned short *bits,
138 const QRect& rect )
139 { 136 {
137 // FIXME: this only works correctly for 240x320 displays
140 int startx, starty; 138 int startx, starty;
141 int width, height; 139 int width, height;
142 140
143 startx = rect.left() >> 1; 141 startx = rect.left() >> 1;
144 starty = rect.top() >> 1; 142 starty = rect.top() >> 1;
185 // adjust dest ptrs for rotation 183 // adjust dest ptrs for rotation
186 dp1 += rowadd; 184 dp1 += rowadd;
187 dp2 += rowadd; 185 dp2 += rowadd;
188 } 186 }
189 } 187 }
188
189 static inline void
190 gs_fastRotateBlit_1 ( unsigned short *fb,
191 unsigned short *bits,
192 const QRect& rect ) {
193 // FIXME: this only works correctly for 240x320 displays
194 int startx, starty;
195 int width, height;
196
197 startx = rect.left() >> 1;
198 starty = rect.top() >> 1;
199 width = ((rect.right() - rect.left()) >> 1) + 2;
200 height = ((rect.bottom() - rect.top()) >> 1) + 2;
201
202 if((startx+width) > 120) {
203 width = 120 - startx; // avoid horizontal overflow
204 }
205 if((starty+height) > 160) {
206 height = 160 - starty; // avoid vertical overflow
207 }
208
209 ulong *sp1, *sp2, *dp1, *dp2;
210 ulong stop, sbot, dtop, dbot;
211 fb += 320*239; // Move "fb" to top left corner
212 sp1 = (ulong*)bits + startx + starty*240;
213 sp2 = sp1 + 120;
214 dp1 = (ulong*)fb - startx * 320 - starty;
215 dp2 = dp1 - 160;
216 int rowadd = (320*width) + 1;
217 int rowadd2 = 240 - width;
218 // transfer in cells of 2x2 pixels in words
219 for (int y=0; y<height; y++) {
220 for (int x=0; x<width; x++) {
221 // read
222 stop = *sp1;
223 sbot = *sp2;
224 // rotate
225 dtop = (stop & 0xffff) + ((sbot & 0xffff)<<16);
226 dbot = ((stop & 0xffff0000)>>16) + (sbot & 0xffff0000);
227 // write
228 *dp1 = dtop;
229 *dp2 = dbot;
230 // update source ptrs
231 sp1++; sp2++;
232 // update dest ptrs - 2 pix at a time
233 dp1 -= 320;
234 dp2 -= 320;
235 }
236 // adjust src ptrs - skip a row as we work in pairs
237 sp1 += rowadd2;
238 sp2 += rowadd2;
239 // adjust dest ptrs for rotation
240 dp1 += rowadd;
241 dp2 += rowadd;
242 }
243 }
244
245 // desktop, SL-A300 etc
246 bool SDL_QWin::repaintRotation0(const QRect& rect) {
247 if(my_image->width() == width()) {
248 uchar *fb = (uchar*)my_painter->frameBuffer();
249 uchar *buf = (uchar*)my_image->bits();
250 if(rect == my_image->rect()) {
251 memcpy(fb, buf, width()*height()*2);
252 } else {
253 int h = rect.height();
254 int wd = rect.width()<<1;
255 int fblineadd = my_painter->lineStep();
256 int buflineadd = my_image->bytesPerLine();
257 fb += (rect.left()<<1) + rect.top() * my_painter->lineStep();
258 buf += (rect.left()<<1) + rect.top() * my_image->bytesPerLine();
259 while(h--) {
260 memcpy(fb, buf, wd);
261 fb += fblineadd;
262 buf += buflineadd;
263 }
264 }
265 } else {
266 return false; // FIXME: Landscape
267 }
268 #ifdef __i386__
269 my_painter->fillRect( rect, QBrush( Qt::NoBrush ) );
190 #endif 270 #endif
271 return true;
272 }
273
274
275 // Sharp Zaurus SL-5500 etc
276 bool SDL_QWin::repaintRotation3(const QRect& rect) {
277 if(my_image->width() == width()) {
278 ushort *fb = (ushort*)my_painter->frameBuffer();
279 ushort *buf = (ushort*)my_image->bits();
280 gs_fastRotateBlit_3(fb, buf, rect);
281 } else {
282 // landscape mode
283 if (screenRotation == SDL_QT_ROTATION_90) {
284 uchar *fb = (uchar*)my_painter->frameBuffer();
285 uchar *buf = (uchar*)my_image->bits();
286 if(rect == my_image->rect()) {
287 memcpy(fb, buf, width()*height()*2);
288 } else {
289 int h = rect.height();
290 int wd = rect.width()<<1;
291 int fblineadd = my_painter->lineStep();
292 int buflineadd = my_image->bytesPerLine();
293 fb += (rect.left()<<1) + rect.top() * my_painter->lineStep();
294 buf += (rect.left()<<1) + rect.top() * my_image->bytesPerLine();
295 while(h--) {
296 memcpy(fb, buf, wd);
297 fb += fblineadd;
298 buf += buflineadd;
299 }
300 }
301 } else if (screenRotation == SDL_QT_ROTATION_270) {
302 int h = rect.height();
303 int wd = rect.width();
304 int fblineadd = my_painter->lineStep() - (rect.width() << 1);
305 int buflineadd = my_image->bytesPerLine() - (rect.width() << 1);
306 int w;
307
308 uchar *fb = (uchar*)my_painter->frameBuffer();
309 uchar *buf = (uchar*)my_image->bits();
310
311 fb += ((my_painter->width() - (rect.top() + rect.height())) *
312 my_painter->lineStep()) + ((my_painter->height() - ((rect.left() +
313 rect.width()))) << 1);
314
315 buf += my_image->bytesPerLine() * (rect.top() + rect.height()) -
316 (((my_image->width() - (rect.left() + rect.width())) << 1) + 2);
317
318 while(h--) {
319 w = wd;
320 while(w--) *((unsigned short*)fb)++ = *((unsigned short*)buf)--;
321 fb += fblineadd;
322 buf -= buflineadd;
323 }
324 }
325 }
326 return true;
327 }
328
329 // ipaq 3800...
330 bool SDL_QWin::repaintRotation1(const QRect& rect) {
331 if(my_image->width() == width()) {
332 ushort *fb = (ushort*)my_painter->frameBuffer();
333 ushort *buf = (ushort*)my_image->bits();
334 gs_fastRotateBlit_1(fb, buf, rect);
335 } else {
336 return false; // FIXME: landscape mode
337 }
338 return true;
339 }
191 340
192 void SDL_QWin::repaintRect(const QRect& rect) { 341 void SDL_QWin::repaintRect(const QRect& rect) {
193 if(!my_painter || !rect.width() || !rect.height()) { 342 if(!my_painter || !rect.width() || !rect.height()) {
194 return; 343 return;
195 } 344 }
196 #ifndef __i386__ 345
197 346 if(QPixmap::defaultDepth() == 16) {
198 if(QPixmap::defaultDepth() == 16 && 347 switch(my_painter->transformOrientation()) {
199 my_painter->transformOrientation() == 3 && 348 case 3:
200 my_painter->numRects() >= 0) { 349 if(repaintRotation3(rect)) { return; }
201 if(my_image->width() == width()) { 350 break;
202 ushort *fb = (ushort*)my_painter->frameBuffer(); 351 case 1:
203 ushort *buf = (ushort*)my_image->bits(); 352 if(repaintRotation1(rect)) { return; }
204 gs_fastRotateBlit_3(fb, buf, rect); 353 break;
205 } else { 354 case 0:
206 // landscape mode 355 if(repaintRotation0(rect)) { return; }
207 if (screenRotation == SDL_QT_ROTATION_90) { 356 break;
208 uchar *fb = (uchar*)my_painter->frameBuffer(); 357 }
209 uchar *buf = (uchar*)my_image->bits(); 358 }
210 if(rect == my_image->rect()) { 359 my_painter->drawImage(rect.topLeft(), *my_image, rect);
211 memcpy(fb, buf, width()*height()*2);
212 } else {
213 int h = rect.height();
214 int wd = rect.width()<<1;
215 int fblineadd = my_painter->lineStep();
216 int buflineadd = my_image->bytesPerLine();
217 fb += (rect.left()<<1) + rect.top() * my_painter->lineStep();
218 buf += (rect.left()<<1) + rect.top() * my_image->bytesPerLine();
219 while(h--) {
220 memcpy(fb, buf, wd);
221 fb += fblineadd;
222 buf += buflineadd;
223 }
224 }
225 }
226 else if (screenRotation == SDL_QT_ROTATION_270) {
227 int h = rect.height();
228 int wd = rect.width();
229 int fblineadd = my_painter->lineStep() - (rect.width() << 1);
230 int buflineadd = my_image->bytesPerLine() - (rect.width() << 1);
231 int w;
232
233 uchar *fb = (uchar*)my_painter->frameBuffer();
234 uchar *buf = (uchar*)my_image->bits();
235
236 fb += ((my_painter->width() - (rect.top() + rect.height())) *
237 my_painter->lineStep()) + ((my_painter->height() - ((rect.left() +
238 rect.width()))) << 1);
239
240 buf += my_image->bytesPerLine() * (rect.top() + rect.height()) -
241 (((my_image->width() - (rect.left() + rect.width())) << 1) + 2);
242
243 while(h--) {
244 w = wd;
245 while(w--) *((unsigned short*)fb)++ = *((unsigned short*)buf)--;
246 fb += fblineadd;
247 buf -= buflineadd;
248 }
249 }
250 }
251 } else {
252 #endif
253 QPainter pp(this);
254 pp.drawImage(rect.topLeft(), *my_image, rect);
255 pp.end();
256 #ifndef __i386__
257 }
258 #endif
259 } 360 }
260 361
261 // This paints the current buffer to the screen, when desired. 362 // This paints the current buffer to the screen, when desired.
262 void SDL_QWin::paintEvent(QPaintEvent *ev) { 363 void SDL_QWin::paintEvent(QPaintEvent *ev) {
263 if(my_image && isVisible() && isActiveWindow()) { 364 if(my_image) {
264 lockScreen(); 365 lockScreen(true);
265 repaintRect(ev->rect()); 366 repaintRect(ev->rect());
266 unlockScreen(); 367 unlockScreen();
267 } 368 }
268 } 369 }
269 370
270 /* Function to translate a keyboard transition and queue the key event */ 371 /* Function to translate a keyboard transition and queue the key event
372 * This should probably be a table although this method isn't exactly
373 * slow.
374 */
271 void SDL_QWin::QueueKey(QKeyEvent *e, int pressed) 375 void SDL_QWin::QueueKey(QKeyEvent *e, int pressed)
272 { 376 {
273 SDL_keysym keysym; 377 SDL_keysym keysym;
274 int scancode = e->key(); 378 int scancode = e->key();
275 /* Set the keysym information */ 379 /* Set the keysym information */
338 case Qt::Key_F15: scancode = SDLK_F15; break; 442 case Qt::Key_F15: scancode = SDLK_F15; break;
339 case Qt::Key_Super_L: scancode = SDLK_LSUPER; break; 443 case Qt::Key_Super_L: scancode = SDLK_LSUPER; break;
340 case Qt::Key_Super_R: scancode = SDLK_RSUPER; break; 444 case Qt::Key_Super_R: scancode = SDLK_RSUPER; break;
341 case Qt::Key_Menu: scancode = SDLK_MENU; break; 445 case Qt::Key_Menu: scancode = SDLK_MENU; break;
342 case Qt::Key_Help: scancode = SDLK_HELP; break; 446 case Qt::Key_Help: scancode = SDLK_HELP; break;
447
448 case Qt::Key_F33:
449 // FIXME: This is a hack to enable the OK key on
450 // Zaurii devices. SDLK_RETURN is a suitable key to use
451 // since it often is used as such.
452 // david@hedbor.org
453 scancode = SDLK_RETURN;
454 break;
343 default: 455 default:
344 scancode = SDLK_UNKNOWN; 456 scancode = SDLK_UNKNOWN;
345 break; 457 break;
346 } 458 }
347 keysym.sym = static_cast<SDLKey>(scancode); 459 keysym.sym = static_cast<SDLKey>(scancode);
392 // Enable fullscreen. 504 // Enable fullscreen.
393 showFullScreen(); 505 showFullScreen();
394 my_has_fullscreen = true; 506 my_has_fullscreen = true;
395 } 507 }
396 } 508 }
509
510 bool SDL_QWin::lockScreen(bool force) {
511 if(!my_painter) {
512 if(force || (isVisible() && isActiveWindow())) {
513 my_painter = new QDirectPainter(this);
514 } else {
515 return false;
516 }
517 }
518 my_locked++; // Increate lock refcount
519 return true;
520 }
521
522 void SDL_QWin::unlockScreen() {
523 if(my_locked > 0) {
524 my_locked--; // decrease lock refcount;
525 }
526 if(!my_locked && my_painter) {
527 my_painter->end();
528 delete my_painter;
529 my_painter = 0;
530 }
531 }