--- SDL_sysvideo.cc.org	2003-10-12 01:25:48.000000000 +0900
+++ SDL_sysvideo.cc	2003-10-26 00:44:07.000000000 +0900
@@ -31,20 +31,31 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
 
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <linux/fb.h>
+#include <sys/mman.h>
+#include <asm/page.h>	
 
 #include <qapplication.h>
 #include <qpe/qpeapplication.h>
 #include <qpe/qcopenvelope_qws.h>
+#include <qgfx_qws.h>
+#include <qwindowsystem_qws.h>
+#include <qwidget.h>
+#include <qwidgetlist.h>
+#include <qdirectpainter_qws.h>
 
 #include "SDL.h"
 #include "SDL_timer.h"
 
 #include "SDL_QWin.h"
+#include "SDL_sysvideo.h"
 
 extern "C" {
 
@@ -132,6 +143,17 @@
   static int QT_IconifyWindow(_THIS);
   static SDL_GrabMode QT_GrabInput(_THIS, SDL_GrabMode mode);
 
+  static int console_fd;
+  struct fb_var_screeninfo saved_vinfo;
+  static int fb_hwrot;
+ 
+#define W100FB_CONFIG          0x57415200 /* WAL\00 */
+#define W100INIT_ITEM          0
+#define W100INIT_ALL           1
+#define W100INIT_ITEM_WITH_VAL 2
+#define W100FB_CONFIG_EX       0x57415202 /* WAL\02 */
+
+
   /* FB driver bootstrap functions */
 
   static int QT_Available(void)
@@ -276,6 +298,9 @@
 
   int QT_VideoInit(_THIS, SDL_PixelFormat *vformat)
   {
+    const char *SDL_fbdev;
+    struct fb_var_screeninfo vinfo;
+
     /* Initialize the QPE Application  */
      /* Determine the screen depth */
     vformat->BitsPerPixel = QPixmap::defaultDepth();
@@ -283,6 +308,23 @@
     // For now we hardcode the current depth because anything else
     // might as well be emulated by SDL rather than by Qtopia.
 
+    SDL_fbdev = getenv("SDL_FBDEV");
+    if ( SDL_fbdev == NULL ) {
+    	SDL_fbdev = "/dev/fb0";
+    }
+    console_fd = open(SDL_fbdev, O_RDWR, 0);
+    if ( console_fd < 0 ) {
+    	SDL_SetError("Unable to open %s", SDL_fbdev);
+    	return(-1);
+    }
+
+    if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {
+    	SDL_SetError("Couldn't get console pixel format");
+    	QT_VideoQuit(_this);
+    	return(-1);
+    }
+    saved_vinfo = vinfo;
+
     QSize desktop_size = qApp->desktop()->size();
     QT_AddMode(_this, ((vformat->BitsPerPixel+7)/8)-1,
 	       desktop_size.width(), desktop_size.height());
@@ -328,6 +370,7 @@
 
   /* Various screen update functions available */
   static void QT_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
+  static void QT_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
 
 
   static int QT_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen)
@@ -425,6 +468,18 @@
     QSize qteSize = qApp->desktop()->size();
     QSize fbSize;
     QSize userSize;
+    int fb_xres;
+    int fb_yres;
+    struct fb_var_screeninfo vinfo;
+    struct fb_fix_screeninfo finfo;
+
+    int mapped_memlen;
+    int mapped_offset;
+    void *mapped_mem;
+    long mapped_iolen;
+    int fb_offset;
+    int fb_direct;
+    int tmp_ioctl_data;
 
     machine_t machine = QT_GetMachine(_this);
     machine_spec_t machineSpec = st_machine_spec[machine];
@@ -435,6 +490,55 @@
     // qte での回転角度を取得
     QT_GetQteServerSpec(_this, &qteRotation, &isQteQvga);
 
+
+    const char *envFb_HwRot = getenv("SDL_FB_HWROT");
+    fb_hwrot = envFb_HwRot ? atoi(envFb_HwRot) : -1;
+    if (fb_hwrot == 1) {
+	if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {
+		SDL_SetError("Couldn't get console pixel format");
+		QT_VideoQuit(_this);
+		return(NULL);
+	}
+
+	if ((vinfo.xres == 480) && (vinfo.yres == 640)) {
+		vinfo.xres = 640;
+		vinfo.xres_virtual = 640;
+		vinfo.yres = 480;
+		vinfo.yres_virtual = 480;
+
+		if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {
+			SDL_SetError("Couldn't set console screen info");
+			return(NULL);
+		}
+
+	} else if ((vinfo.xres == 320) && (vinfo.yres == 240)) {
+		tmp_ioctl_data=121;
+		ioctl(console_fd, W100FB_CONFIG_EX, &tmp_ioctl_data);	
+	}
+
+	qteSize.setWidth(vinfo.xres);
+	qteSize.setHeight(vinfo.yres);
+	qteRotation=0;
+	LOG("QT_FBVideoMode: argSize=%dx%d\n", vinfo.xres, vinfo.yres);
+
+    }
+
+    const char *envFb_Direct = getenv("SDL_FB_DIRECT");
+    fb_direct = envFb_Direct ? atoi(envFb_Direct) : -1;
+    if (fb_direct == 1){
+	if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
+		SDL_SetError("Couldn't get console hardware info");
+		QT_VideoQuit(_this);
+		return(NULL);
+    	}
+        if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {
+		SDL_SetError("Couldn't get console pixel format");
+		QT_VideoQuit(_this);
+                return(NULL);
+        }
+
+    }
+
     // hack for SL-5500
     if (machine == MACHINE_SHARP_SL5500)
       qteRotation = 3;
@@ -513,6 +617,10 @@
       return NULL;
     }
 
+    if (fb_hwrot == 1) 
+	sdlRotation = 0;
+
+
     if (getenv(SDL_QT_INVERT_ROTATION_ENV_NAME) != NULL) {
       sdlRotation = (sdlRotation + 2) & 3;
     }
@@ -549,6 +657,9 @@
     else if (machine == MACHINE_SHARP_SLB500)
       qteKeyRotation = 3;
 
+    if (isQteQvga && fb_hwrot == 1) 
+	qteKeyRotation = 1;
+
     sdlKeyRotation = sdlRotation;
 
     SDL_Win->setKeyRotation(sdlKeyRotation, qteKeyRotation);
@@ -570,10 +681,31 @@
       delete qimage;
       return(NULL);
     }
-    current->pitch = qimage->bytesPerLine();
-    current->pixels = (void *)qimage->bits();
+
+    if (fb_direct == 1) {
+	current->pitch = finfo.line_length;//qimage->bytesPerLine();
+        current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE);
+        mapped_offset = (((long)finfo.smem_start) -
+	                (((long)finfo.smem_start)&~(PAGE_SIZE-1)));
+	mapped_memlen = finfo.smem_len+mapped_offset;
+        if(console_fd >0 ) {
+		delete qimage;
+		mapped_mem = mmap(NULL, mapped_memlen,PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0);
+		fb_offset=(vinfo.xres-width)+(vinfo.yres-height)*vinfo.xres;
+		current->pixels = (void *)((int )mapped_mem+fb_offset);
+                _this->UpdateRects = QT_DirectUpdate;
+    	} else {
+    		current->pixels = (void *)qimage->bits();
+                _this->UpdateRects = QT_NormalUpdate;
+    	}
+    } else {
+	current->pitch = qimage->bytesPerLine();
+	current->pixels = (void *)qimage->bits();
+        _this->UpdateRects = QT_NormalUpdate;
+
+    }
+
     SDL_Win->setImage(qimage);
-    _this->UpdateRects = QT_NormalUpdate;
     SDL_Win->setFullscreen(true);
 
     //     fprintf(stderr,"QT_SetVideoMode() qImage:%dx%d %d\n",
@@ -629,6 +761,12 @@
       SDL_Win->unlockScreen();
     }
   }
+
+  static void QT_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+  {
+
+  }
+
   /* Is the system palette settable? */
   int QT_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
   {
@@ -644,6 +782,19 @@
     //    -- David Hedbor
     //    delete SDL_Win; 
     //    SDL_Win = 0;
+
+    if ( console_fd > 0 ) {
+    	/* Restore the original video mode and palette */
+	int tmp_ioctl_data=120;
+	ioctl(console_fd, W100FB_CONFIG_EX, &tmp_ioctl_data);
+
+    	ioctl(console_fd, FBIOPUT_VSCREENINFO, &saved_vinfo);
+
+    	/* We're all done with the framebuffer */
+    	close(console_fd);
+    	console_fd = -1;
+    }
+
     _this->screen->pixels = NULL;
     QT_GrabInput(_this, SDL_GRAB_OFF);
 
