nanogui: Thread: Panning and double buffering


[<<] [<] Page 1 of 2 [>] [>>]
Subject: Panning and double buffering
From: llandre ####@####.####
Date: 21 Apr 2006 11:49:35 +0100
Message-Id: <4448B95D.9010303@dave-tech.it>

Hi all,

I'm running Microwindows on a ARM9-based embedded system running Linux 
2.6. The framebuffer driver supports the ioctl required to handle panning.
I use microwindows to show some full-screen bitmaps and to handle user 
input. When changing from one bitmap to another the LCD flickers because 
it takes a while to paint the new image in memory. I'd like to exploit 
panning ioctl to avoid this. In other words the new bitmap should be put 
on a second buffer and, after this opearation has completed, application 
code should change framebuffer pointer with the aforementioned ioctl (I 
have already tested this technique with a simple non-microwindows 
application and it works fine because the graphics controller 
automatically makes the pointer change effective at the beginning of 
next frame).

Does microwindows already support this feature? If not, anybody can 
provide some help about how to add it?



TIA,
llandre

DAVE Electronics System House - R&D Department
web:   http://www.dave-tech.it
email: ####@####.####
Subject: Re: [nanogui] Panning and double buffering
From: "Greg Haerr" ####@####.####
Date: 21 Apr 2006 17:52:45 +0100
Message-Id: <05dd01c66563$fa2fc480$0300a8c0@RDP>

: When changing from one bitmap to another the LCD flickers because 
: it takes a while to paint the new image in memory. I'd like to exploit 
: panning ioctl to avoid this. In other words the new bitmap should be put 
: on a second buffer and, after this opearation has completed, application 
: code should change framebuffer pointer with the aforementioned ioctl 

Microwindows doesn't support any low-level hardware control
except framebuffer r/w and ioctls for palette loading, so you'll
have to add this "framebuffer switch" capability yourself.

It's a little tricky exactly how to handle this, since you'll effectively
have two hw framebuffers, but Microwindows normally clips all
output to the displayed framebuffer.  One way might be to add
two new GrXXX API calls, one that sets the hw framebuffer
currently displayed, and another that changes the the low level
memory-mapped address for the Microwindows drawing
framebuffer, scrdev.addr.  Perhaps both these values are
set in one call.  In this way, you could display from one
fb while drawing in another, and then swap.

Regards,

Greg
Subject: Re: Panning and double buffering
From: "Aaron J. Grier" ####@####.####
Date: 21 Apr 2006 19:14:47 +0100
Message-Id: <20060421181412.GJ4095@mordor.unix.fryenet>

On Fri, Apr 21, 2006 at 10:52:29AM -0600, Greg Haerr wrote:
> It's a little tricky exactly how to handle this, since you'll
> effectively have two hw framebuffers, but Microwindows normally clips
> all output to the displayed framebuffer.

perhaps model this after xfree's "viewport" where the physical screen
only shows one section of framebuffer memory?

-- 
  Aaron J. Grier  |   Frye Electronics, Tigard, OR   |  ####@####.####
Subject: Re: Panning and double buffering
From: "Jordan Crouse" ####@####.####
Date: 24 Apr 2006 05:26:39 +0100
Message-Id: <20060424042851.GC12016@cosmic.amd.com>

On 21/04/06 10:52 -0600, Greg Haerr wrote:
> It's a little tricky exactly how to handle this, since you'll effectively
> have two hw framebuffers, but Microwindows normally clips all
> output to the displayed framebuffer.  One way might be to add
> two new GrXXX API calls, one that sets the hw framebuffer
> currently displayed, and another that changes the the low level
> memory-mapped address for the Microwindows drawing
> framebuffer, scrdev.addr.  Perhaps both these values are
> set in one call.  In this way, you could display from one
> fb while drawing in another, and then swap.

You don't have to change the framebuffer address - when you set up a
framebuffer for panning, you establish the memory area for the entire 
virtual space, and then tell the framebuffer driver the only display
the physical view area.

So as far as Nano-X is concerned, the entire space is there so you can
draw on the non-visible area without changing anything around.  All you
will need is the Gr call to change the window viewpoint, and you're golden.

I have some patches I wrote about a year ago to test our Geode framebuffer.
They're old, but they should be useful.  I'll send it forward tomorrow.

Jordan

-- 
Jordan Crouse
Senior Linux Engineer
AMD - Personal Connectivity Solutions Group
<www.amd.com/embeddedprocessors>

Subject: Re: Panning and double buffering
From: "Jordan Crouse" ####@####.####
Date: 24 Apr 2006 20:50:31 +0100
Message-Id: <20060424195418.GE25101@cosmic.amd.com>

Ok - as promised, here is the patch.  It was written and tested on 0.90, and
it compiles with config.fb on most recent CVS, but thats about all I can 
promise you.  Your mileage will vary, consult your doctor before taking 
internally, and don't kill me if it makes your system die a horrible death.

Jordan

-- 
Jordan Crouse
Senior Linux Engineer
AMD - Personal Connectivity Solutions Group
<www.amd.com/embeddedprocessors>

Subject: Re: Panning and double buffering
From: "Jordan Crouse" ####@####.####
Date: 24 Apr 2006 23:18:03 +0100
Message-Id: <20060424222150.GH25101@cosmic.amd.com>

On 24/04/06 13:54 -0600, Jordan Crouse wrote:
> Ok - as promised, here is the patch.  

I've been informed that I hit send a little bit too quickly.  Lets try 
that again, shall we?

Jordan

Index: microwin/src/drivers/scr_bios.c
===================================================================
--- microwin.orig/src/drivers/scr_bios.c
+++ microwin/src/drivers/scr_bios.c
@@ -235,8 +235,8 @@ VGA_close(PSD psd)
 static void
 VGA_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_debug.c
===================================================================
--- microwin.orig/src/drivers/scr_debug.c
+++ microwin/src/drivers/scr_debug.c
@@ -76,8 +76,8 @@ DBG_close(PSD psd)
 static void
 DBG_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_djgr.c
===================================================================
--- microwin.orig/src/drivers/scr_djgr.c
+++ microwin/src/drivers/scr_djgr.c
@@ -107,8 +107,8 @@ DJGR_close(PSD psd)
 static void
 DJGR_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_ecos.c
===================================================================
--- microwin.orig/src/drivers/scr_ecos.c
+++ microwin/src/drivers/scr_ecos.c
@@ -357,8 +357,8 @@ setfadelevel(PSD psd, int f)
 static void
 gen_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-    psi->rows = psd->yvirtres;
-    psi->cols = psd->xvirtres;
+    psi->visrows = psi->rows = psd->yvirtres;
+    psi->viscols = psi->cols = psd->xvirtres;
     psi->planes = psd->planes;
     psi->bpp = psd->bpp;
     psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_em84xx.c
===================================================================
--- microwin.orig/src/drivers/scr_em84xx.c
+++ microwin/src/drivers/scr_em84xx.c
@@ -247,8 +247,8 @@ EM8400_close(PSD psd)
 static void
 EM8400_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_fb.c
===================================================================
--- microwin.orig/src/drivers/scr_fb.c
+++ microwin/src/drivers/scr_fb.c
@@ -43,10 +43,10 @@ static void fb_close(PSD psd);
 static void fb_setportrait(PSD psd, int portraitmode);
 static void fb_setpalette(PSD psd,int first, int count, MWPALENTRY *palette);
 static void gen_getscreeninfo(PSD psd,PMWSCREENINFO psi);
-
+static void fb_panscreen(PSD psd, int, int);
 
 SCREENDEVICE	scrdev = {
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
 	fb_open,
 	fb_close,
 	gen_getscreeninfo,
@@ -64,8 +64,10 @@ SCREENDEVICE	scrdev = {
 	gen_allocatememgc,
 	fb_mapmemgc,
 	gen_freememgc,
+	fb_panscreen,
 	NULL,			/* StretchBlit subdriver*/
 	fb_setportrait		/* SetPortrait*/
+
 };
 
 /* static variables*/
@@ -144,9 +146,25 @@ fb_open(PSD psd)
 	psd->xres = psd->xvirtres = fb_var.xres_virtual;
 	psd->yres = psd->yvirtres = fb_var.yres_virtual;
 #else
-	psd->xres = psd->xvirtres = fb_var.xres;
-	psd->yres = psd->yvirtres = fb_var.yres;
+	/* The entire xvirtres is available for us to draw on */
+
+	psd->xres = psd->xvirtres = fb_var.xres_virtual;
+	psd->yres = psd->yvirtres = fb_var.yres_virtual;
+
+	/* But we want to know how much of the screen is visible so we can
+	   know when to pan */
+
+	psd->xvisible = fb_var.xres;
+	psd->yvisible = fb_var.yres;
+
+	printf("FB:  total (%d,%d) visible (%d,%d)\n",
+	       psd->xvirtres, psd->yvirtres, psd->xvisible, psd->yvisible);
+
 #endif
+	/* Offset into the screen for panning purposes */
+	
+	psd->xoffset = 0;
+	psd->yoffset = 0;
 
 	/* set planes from fb type*/
 	if (type == FB_TYPE_VGA_PLANES)
@@ -472,6 +490,9 @@ gen_getscreeninfo(PSD psd,PMWSCREENINFO 
 {
 	psi->rows = psd->yvirtres;
 	psi->cols = psd->xvirtres;
+	psi->viscols = 	psd->xvisible;
+	psi->visrows = psd->yvisible;
+
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
@@ -529,3 +550,21 @@ gen_getscreeninfo(PSD psd,PMWSCREENINFO 
 		psi->ydpcm = 19;	/* assumes screen height of 18 cm*/
 	}
 }
+
+static void
+fb_panscreen(PSD psd, int xoffset, int yoffset) {
+  struct fb_var_screeninfo fb_var;
+  
+  if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1) 
+    return;
+
+  /* Don't bother doing the operation if we don't have to */
+
+  //if (fb_var.xoffset == xoffset && fb_var.yoffset == yoffset)
+  // return;
+
+  fb_var.xoffset = xoffset;
+  fb_var.yoffset = yoffset;
+
+  ioctl(fb, FBIOPAN_DISPLAY, &fb_var);
+}
Index: microwin/src/drivers/scr_fbsd.c
===================================================================
--- microwin.orig/src/drivers/scr_fbsd.c
+++ microwin/src/drivers/scr_fbsd.c
@@ -201,8 +201,8 @@ static PSD FBSD_open(PSD psd)
 
 static void FBSD_getscreeninfo(PSD psd, PMWSCREENINFO psi)
 {
-    psi->rows = psd->yvirtres;
-    psi->cols = psd->xvirtres;
+    psi->visrows = psi->rows = psd->yvirtres;
+    psi->viscols = psi->cols = psd->xvirtres;
     psi->planes = psd->planes;
     psi->bpp = psd->bpp;
     psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_herc.c
===================================================================
--- microwin.orig/src/drivers/scr_herc.c
+++ microwin/src/drivers/scr_herc.c
@@ -144,8 +144,8 @@ HERC_close(PSD psd)
 static void
 HERC_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_prsm.c
===================================================================
--- microwin.orig/src/drivers/scr_prsm.c
+++ microwin/src/drivers/scr_prsm.c
@@ -126,8 +126,8 @@ VB_close(PSD psd)
 static void
 VB_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	pis->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_rtems.c
===================================================================
--- microwin.orig/src/drivers/scr_rtems.c
+++ microwin/src/drivers/scr_rtems.c
@@ -311,8 +311,8 @@ ioctl_setpalette(int start, int len, sho
 static void
 gen_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_svga.c
===================================================================
--- microwin.orig/src/drivers/scr_svga.c
+++ microwin/src/drivers/scr_svga.c
@@ -109,8 +109,8 @@ SVGA_close(PSD psd)
 static void
 SVGA_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_x11.c
===================================================================
--- microwin.orig/src/drivers/scr_x11.c
+++ microwin/src/drivers/scr_x11.c
@@ -841,8 +841,8 @@ X11_close(PSD psd)
 static void
 X11_getscreeninfo(PSD psd, PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/engine/devmouse.c
===================================================================
--- microwin.orig/src/engine/devmouse.c
+++ microwin/src/engine/devmouse.c
@@ -183,6 +183,8 @@ GdSetAccelMouse(int newthresh, int newsc
 void
 GdMoveMouse(MWCOORD newx, MWCOORD newy)
 {
+        int xo = scrdev.xoffset, yo = scrdev.yoffset;
+	
 	if (!(mousedev.flags & MOUSE_RAW)) {
 		if (newx < minx)
 			newx = minx;
@@ -197,6 +199,30 @@ GdMoveMouse(MWCOORD newx, MWCOORD newy)
 	if (newx == xpos && newy == ypos)
 		return;
 
+#ifdef NOTUSED
+	/* Pan the display if possible - we want to do this smoothly */
+
+	if (newx < scrdev.xoffset)
+ 	  xo = newx - 5;
+	else if (newx > scrdev.xoffset + scrdev.xvisible)
+	  xo = (newx + 5) - scrdev.xvisible;
+	
+	if (newy < scrdev.yoffset)
+	  yo = newy - 5;
+	else if (newy > scrdev.yoffset + scrdev.yvisible)
+	  yo = (newy + 5) - scrdev.yvisible;
+	
+	if (xo < 0) xo = 0;
+	if (xo > scrdev.xres) xo = scrdev.xres - scrdev.xvisible;
+	
+	if (yo < 0) yo = 0;
+	if (yo > scrdev.yres) yo = scrdev.yres - scrdev.yvisible;
+
+	/* Move the screen accordingly */
+	if (xo != scrdev.xoffset || yo != scrdev.yoffset)
+	  GdPanScreen(&scrdev, xo, yo);
+#endif
+
 	changed = TRUE;
 
 	xpos = newx;
Index: microwin/src/engine/devopen.c
===================================================================
--- microwin.orig/src/engine/devopen.c
+++ microwin/src/engine/devopen.c
@@ -408,6 +408,41 @@ GdGetColorRGB(PSD psd, MWPIXELVAL pixel)
 	}
 }
 
+void
+GdPanScreen(PSD psd, int xoffset, int yoffset) {
+		
+	if (!psd->PanScreen) return;
+
+	if ((psd->xvisible != psd->xvirtres)) {
+
+		/* Bound it */
+
+		if (xoffset < 0) xoffset = 0;		
+		if (xoffset + psd->xvisible > psd->xvirtres)
+			xoffset = psd->xvirtres - psd->xvisible;
+	}
+	else 
+		xoffset = 0;
+
+	if ((psd->yvisible != psd->yvirtres)) {
+		
+		/* Bound it */
+
+		if (yoffset < 0) yoffset = 0;		
+		if (yoffset + psd->yvisible > psd->yvirtres)
+			yoffset = psd->yvirtres - psd->yvisible;
+	}
+	else 
+		yoffset = 0;
+
+	if (xoffset != psd->xoffset || yoffset != psd->yoffset) {
+		psd->yoffset = yoffset;
+		psd->xoffset = xoffset;
+
+		psd->PanScreen(psd, psd->xoffset, psd->yoffset);
+	}
+}
+
 #if !VXWORKS
 #if defined(HAVE_FILEIO)
 #include <unistd.h>
@@ -637,3 +672,5 @@ GdCaptureScreen(char *path)
 	return 0;
 }
 #endif /* !VXWORKS*/
+
+
Index: microwin/src/include/device.h
===================================================================
--- microwin.orig/src/include/device.h
+++ microwin/src/include/device.h
@@ -338,6 +338,10 @@ typedef struct _mwscreendevice {
 	MWCOORD	yres;		/* Y screen res (real) */
 	MWCOORD	xvirtres;	/* X drawing res (will be flipped in portrait mode) */
 	MWCOORD	yvirtres;	/* Y drawing res (will be flipped in portrait mode) */
+	int     xvisible;       /* Actual x real estate that is visible */
+	int     yvisible;       /* Ditto */
+	int     xoffset;        /* X offset for panning */
+	int     yoffset;        /* Y offset for panning */
 	int	planes;		/* # planes*/
 	int	bpp;		/* # bpp*/
 	int	linelen;	/* line length in bytes for bpp 1,2,4,8*/
@@ -374,6 +378,7 @@ typedef struct _mwscreendevice {
 	MWBOOL	(*MapMemGC)(PSD mempsd,MWCOORD w,MWCOORD h,int planes,int bpp,
 			int linelen,int size,void *addr);
 	void	(*FreeMemGC)(PSD mempsd);
+	void    (*PanScreen)(PSD, int, int);
 	void	(*StretchBlit)(PSD destpsd,MWCOORD destx,MWCOORD desty,
 			MWCOORD destw,MWCOORD desth,PSD srcpsd,MWCOORD srcx,
 			MWCOORD srcy,MWCOORD srcw,MWCOORD srch,long op);
@@ -794,6 +799,8 @@ void	drawbitmap(PSD psd, MWCOORD x, MWCO
 		const MWIMAGEBITS *imagebits);
 void	drawpoint(PSD psd, MWCOORD x, MWCOORD y);
 void	drawrow(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y);
+void    GdPanScreen(PSD psd, int, int);
+
 extern SCREENDEVICE scrdev;
 
 
Index: microwin/src/include/mwtypes.h
===================================================================
--- microwin.orig/src/include/mwtypes.h
+++ microwin/src/include/mwtypes.h
@@ -314,6 +314,8 @@ typedef unsigned int	MWKEYMOD;
 typedef struct {
 	MWCOORD  rows;		/* number of rows on screen */
 	MWCOORD  cols;		/* number of columns on screen */
+	MWCOORD  visrows;       /* number of visible rows */
+	MWCOORD  viscols;       /* number of visible columns */
 	int 	 xdpcm;		/* dots/centimeter in x direction */
 	int 	 ydpcm;		/* dots/centimeter in y direction */
 	int	 planes;	/* hw # planes*/
Index: microwin/src/include/nano-X.h
===================================================================
--- microwin.orig/src/include/nano-X.h
+++ microwin/src/include/nano-X.h
@@ -559,6 +559,12 @@ typedef union {
 
 typedef void (*GR_FNCALLBACKEVENT)(GR_EVENT *);
 
+typedef struct {
+   GR_WINDOW_ID buf[2];
+   int active;
+   int size;
+} GR_DOUBLE_BUFFER;
+	
 /* GR_BITMAP macros*/
 /* size of GR_BITMAP image in words*/
 #define	GR_BITMAP_SIZE(width, height)	MWIMAGE_SIZE(width, height)
@@ -925,6 +931,7 @@ void            GrSetTransform(GR_TRANSF
 int             GrCalcTransform(GR_CAL_DATA *, GR_TRANSFORM *);
 int             GrLoadTransformData(char *filename, GR_TRANSFORM *);
 int             GrSaveTransformData(GR_TRANSFORM *, char *filename);
+void            GrPanDisplay(int, int);
 
 /* nxutil.c - utility routines*/
 GR_WINDOW_ID	GrNewWindowEx(GR_WM_PROPS props, GR_CHAR *title,
@@ -944,6 +951,12 @@ GR_BITMAP *	GrNewBitmapFromPixmap(GR_WIN
 GR_REGION_ID	GrNewRegionFromPixmap(GR_WINDOW_ID src, MWCOORD x, MWCOORD y,
 			GR_SIZE width, GR_SIZE height);
 
+/* nxdblbuf.c */
+
+GR_DOUBLE_BUFFER *GrInitDoubleBuffer(void);
+void GrCloseDoubleBuffer(GR_DOUBLE_BUFFER *);
+void GrFlipBuffers(GR_DOUBLE_BUFFER *);
+
 /* direct client-side framebuffer mapping routines*/
 unsigned char * GrOpenClientFramebuffer(void);
 void		GrCloseClientFramebuffer(void);
Index: microwin/src/nanox/Makefile
===================================================================
--- microwin.orig/src/nanox/Makefile
+++ microwin/src/nanox/Makefile
@@ -38,7 +38,8 @@ NANOXFILES := \
 OBJS := \
 	$(MW_DIR_OBJ)/nanox/nxdraw.o \
 	$(MW_DIR_OBJ)/nanox/nxutil.o \
-	$(MW_DIR_OBJ)/nanox/nxtransform.o
+	$(MW_DIR_OBJ)/nanox/nxtransform.o \
+	$(MW_DIR_OBJ)/nanox/nxdblbuf.o
 
 ifeq ($(LINK_APP_INTO_SERVER), Y)
 OBJS += $(NANOXFILES)
Index: microwin/src/nanox/client.c
===================================================================
--- microwin.orig/src/nanox/client.c
+++ microwin/src/nanox/client.c
@@ -4761,5 +4761,19 @@ GrCopyFont(GR_FONT_ID fontid, GR_COORD h
 }
 #endif /*HAVE_FREETYPE_2_SUPPORT*/
 
+/* Used to pan the display for those devices that have such support */
 
+void
+GrPanDisplay(int xoffset, int yoffset) {
+
+  nxPanDisplayReq *req;
+
+  LOCK(&nxGlobalLock);
+
+  req = AllocReq(PanDisplay);
+  req->xoffset = xoffset;
+  req->yoffset = yoffset;
+
+  UNLOCK(&nxGlobalLock);
+}
 
Index: microwin/src/nanox/nxdblbuf.c
===================================================================
--- /dev/null
+++ microwin/src/nanox/nxdblbuf.c
@@ -0,0 +1,49 @@
+#include "nano-X.h"
+#include "device.h"
+
+/* Initalize two windows that act as double buffers */
+
+GR_DOUBLE_BUFFER *GrInitDoubleBuffer(void) {
+  
+  GR_SCREEN_INFO si;
+  GR_DOUBLE_BUFFER *s = 0;
+
+  GrGetScreenInfo(&si);
+
+  if (si.rows < si.visrows * 2) return 0;
+  
+  s = malloc(sizeof(GR_DOUBLE_BUFFER));
+  if (!s) return 0;
+
+  printf("VISROWS=%d\n", si.visrows);
+
+  s->buf[0] = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, si.cols, 
+			  si.visrows, 0, 0, 0);
+  
+  s->buf[1] = GrNewWindow(GR_ROOT_WINDOW_ID, 0, si.visrows, 
+			  si.cols, si.visrows, 0, 0, 0);
+
+  s->active = 0;
+  s->size = si.visrows;
+
+  return s;
+}
+
+void GrCloseDoubleBuffer(GR_DOUBLE_BUFFER *buf) {
+  GrDestroyWindow(buf->buf[0]);
+  GrDestroyWindow(buf->buf[1]);
+
+  free(buf);
+}
+
+/* Flip the screen betwee nteh two buffers */
+
+void GrFlipBuffers(GR_DOUBLE_BUFFER *buf) {
+
+  if (!buf) return;
+
+  buf->active = !buf->active;
+  GrPanDisplay(0, buf->size * buf->active);
+}
+
+  
Index: microwin/src/nanox/nxproto.h
===================================================================
--- microwin.orig/src/nanox/nxproto.h
+++ microwin/src/nanox/nxproto.h
@@ -1366,4 +1366,13 @@ typedef struct {
 	INT16 height;
 } nxCopyFontReq;
 
-#define GrTotalNumCalls         125
+#define GrNumPanDisplay         125
+typedef struct 	{
+	BYTE8 reqType;
+	BYTE8 hilength;
+	UINT16 length;
+	INT16 xoffset;
+	INT16 yoffset;
+} nxPanDisplayReq;
+	
+#define GrTotalNumCalls         126
Index: microwin/src/nanox/srvfunc.c
===================================================================
--- microwin.orig/src/nanox/srvfunc.c
+++ microwin/src/nanox/srvfunc.c
@@ -4314,3 +4314,15 @@ GrUngrabKey(GR_WINDOW_ID id, GR_KEY key)
 
 	SERVER_UNLOCK();
 }
+
+/**
+ * Pan the display 
+ *
+ * @param xoffset New xoffset of the display
+ * @param yoffset New yoffset of the display
+ */
+
+void
+GrPanDisplay(int xoffset, int yoffset) {  
+  GdPanScreen(rootwp->psd, xoffset, yoffset);
+}
Index: microwin/src/nanox/srvmain.c
===================================================================
--- microwin.orig/src/nanox/srvmain.c
+++ microwin/src/nanox/srvmain.c
@@ -1169,7 +1169,15 @@ GsInitialize(void)
 	 * Tell the mouse driver some things.
 	 */
 	curbuttons = 0;
-	GdRestrictMouse(0, 0, psd->xvirtres - 1, psd->yvirtres - 1);
+
+	/* If panning is indicated, we now allow the mouse the full range
+	   of motion */
+	
+	if (psd->PanScreen)
+	  GdRestrictMouse(0, 0, psd->xres - 1, psd->yres - 1);
+	else
+	  GdRestrictMouse(0, 0, psd->xvirtres - 1, psd->yvirtres - 1);
+
 	GdMoveMouse(psd->xvirtres / 2, psd->yvirtres / 2);
 
 	/* Force root window screen paint*/
Index: microwin/src/nanox/srvnet.c
===================================================================
--- microwin.orig/src/nanox/srvnet.c
+++ microwin/src/nanox/srvnet.c
@@ -1593,6 +1593,11 @@ GrCopyFontWrapper(void *r)
 #endif /*HAVE_FREETYPE_2_SUPPORT*/
 }
 
+static void
+GrPanDisplayWrapper(void *r) {
+	nxPanDisplayReq *req = r;
+	GrPanDisplay(req->xoffset, req->yoffset);
+}
 
 void GrShmCmdsFlushWrapper(void *r);
 
@@ -1729,6 +1734,7 @@ static const struct GrFunction GrFunctio
 	/* 122 */ {GrSetTransformWrapper, "GrSetTransform" },
 	/* 123 */ {GrCreateFontFromBufferWrapper, "GrCreateFontFromBuffer"},
 	/* 124 */ {GrCopyFontWrapper, "GrCopyFont"},
+	/* 125 */ {GrPanDisplayWrapper, "GrPanDisplay" }
 };
 
 void
Subject: Re: [nanogui] Panning and double buffering
From: llandre ####@####.####
Date: 25 Apr 2006 10:16:43 +0100
Message-Id: <444DE997.20909@dave-tech.it>

Hello,

> I have to admit that I cant help you with your problem. But I read that
> you run Microwindows under Linux on a ARM9 processor. How did you
> compile it ? I am curious because I am also using an ARM9 processor
> (ATMEL AT91SAM9261) and Microwindows does not seem to work for me. I can
> (cross) compile it, but when running Microwindows apps on the ARM under
> Linux nothing happens. 
>  
> I compiled for iPaq(used the predifined script). What switches/tools did
> you use ? 

we are used to build it natively on the target with the GCC 3.3.3 
provided by Denx ELDK (www.denx.de).
Before runnning make we disabled JPEG support and Freetype fonts support:

HAVE_JPEG_SUPPORT = N
HAVE_FREETYPE_SUPPORT = N



HTH,
llandre

DAVE Electronics System House - R&D Department
web:   http://www.dave-tech.it
email: ####@####.####
Subject: Re: [nanogui] Re: Panning and double buffering
From: llandre ####@####.####
Date: 25 Apr 2006 10:27:18 +0100
Message-Id: <444DEC14.5090702@dave-tech.it>

Jordan, Gregg and Aaron,

thanks a lot for your help.

I think we are going to try Jordan's patch on our emebedded platform.



Cheers,
llandre

DAVE Electronics System House - R&D Department
web:   http://www.dave-tech.it
email: ####@####.####
Subject: Re: [nanogui] Re: Panning and double buffering
From: Steven Scholz ####@####.####
Date: 27 Apr 2006 16:46:30 +0100
Message-Id: <4450E750.4060404@imc-berlin.de>

Hi all,

> I have some patches I wrote about a year ago to test our Geode framebuffer.
> They're old, but they should be useful.  I'll send it forward tomorrow.

Does anyone know how this could then be used with FLTK?

I think for now when using Fl_Double_Window it draws offscreen and then does
a memcpy() ...

Anyone tried?

--
Steven
Subject: Panning and double buffering
From: mohanreddy.b ####@####.####
Date: 27 Jun 2008 04:00:05 -0000
Message-Id: <4d8f9b866b30646af6feec4856f4caa5@localhost>

Is any one tested the following code. i got this code from list for double
buffering.i am getting segmentation fault while running on Embedded board.

Index: microwin/src/drivers/scr_bios.c
===================================================================
--- microwin.orig/src/drivers/scr_bios.c
+++ microwin/src/drivers/scr_bios.c
@@ -235,8 +235,8 @@ VGA_close(PSD psd)
 static void
 VGA_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_debug.c
===================================================================
--- microwin.orig/src/drivers/scr_debug.c
+++ microwin/src/drivers/scr_debug.c
@@ -76,8 +76,8 @@ DBG_close(PSD psd)
 static void
 DBG_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_djgr.c
===================================================================
--- microwin.orig/src/drivers/scr_djgr.c
+++ microwin/src/drivers/scr_djgr.c
@@ -107,8 +107,8 @@ DJGR_close(PSD psd)
 static void
 DJGR_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_ecos.c
===================================================================
--- microwin.orig/src/drivers/scr_ecos.c
+++ microwin/src/drivers/scr_ecos.c
@@ -357,8 +357,8 @@ setfadelevel(PSD psd, int f)
 static void
 gen_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-    psi->rows = psd->yvirtres;
-    psi->cols = psd->xvirtres;
+    psi->visrows = psi->rows = psd->yvirtres;
+    psi->viscols = psi->cols = psd->xvirtres;
     psi->planes = psd->planes;
     psi->bpp = psd->bpp;
     psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_em84xx.c
===================================================================
--- microwin.orig/src/drivers/scr_em84xx.c
+++ microwin/src/drivers/scr_em84xx.c
@@ -247,8 +247,8 @@ EM8400_close(PSD psd)
 static void
 EM8400_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_fb.c
===================================================================
--- microwin.orig/src/drivers/scr_fb.c
+++ microwin/src/drivers/scr_fb.c
@@ -43,10 +43,10 @@ static void fb_close(PSD psd);
 static void fb_setportrait(PSD psd, int portraitmode);
 static void fb_setpalette(PSD psd,int first, int count, MWPALENTRY
*palette);
 static void gen_getscreeninfo(PSD psd,PMWSCREENINFO psi);
-
+static void fb_panscreen(PSD psd, int, int);
 
 SCREENDEVICE	scrdev = {
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
 	fb_open,
 	fb_close,
 	gen_getscreeninfo,
@@ -64,8 +64,10 @@ SCREENDEVICE	scrdev = {
 	gen_allocatememgc,
 	fb_mapmemgc,
 	gen_freememgc,
+	fb_panscreen,
 	NULL,			/* StretchBlit subdriver*/
 	fb_setportrait		/* SetPortrait*/
+
 };
 
 /* static variables*/
@@ -144,9 +146,25 @@ fb_open(PSD psd)
 	psd->xres = psd->xvirtres = fb_var.xres_virtual;
 	psd->yres = psd->yvirtres = fb_var.yres_virtual;
 #else
-	psd->xres = psd->xvirtres = fb_var.xres;
-	psd->yres = psd->yvirtres = fb_var.yres;
+	/* The entire xvirtres is available for us to draw on */
+
+	psd->xres = psd->xvirtres = fb_var.xres_virtual;
+	psd->yres = psd->yvirtres = fb_var.yres_virtual;
+
+	/* But we want to know how much of the screen is visible so we can
+	   know when to pan */
+
+	psd->xvisible = fb_var.xres;
+	psd->yvisible = fb_var.yres;
+
+	printf("FB:  total (%d,%d) visible (%d,%d)\n",
+	       psd->xvirtres, psd->yvirtres, psd->xvisible, psd->yvisible);
+
 #endif
+	/* Offset into the screen for panning purposes */
+	
+	psd->xoffset = 0;
+	psd->yoffset = 0;
 
 	/* set planes from fb type*/
 	if (type == FB_TYPE_VGA_PLANES)
@@ -472,6 +490,9 @@ gen_getscreeninfo(PSD psd,PMWSCREENINFO 
 {
 	psi->rows = psd->yvirtres;
 	psi->cols = psd->xvirtres;
+	psi->viscols = 	psd->xvisible;
+	psi->visrows = psd->yvisible;
+
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
@@ -529,3 +550,21 @@ gen_getscreeninfo(PSD psd,PMWSCREENINFO 
 		psi->ydpcm = 19;	/* assumes screen height of 18 cm*/
 	}
 }
+
+static void
+fb_panscreen(PSD psd, int xoffset, int yoffset) {
+  struct fb_var_screeninfo fb_var;
+  
+  if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1) 
+    return;
+
+  /* Don't bother doing the operation if we don't have to */
+
+  //if (fb_var.xoffset == xoffset && fb_var.yoffset == yoffset)
+  // return;
+
+  fb_var.xoffset = xoffset;
+  fb_var.yoffset = yoffset;
+
+  ioctl(fb, FBIOPAN_DISPLAY, &fb_var);
+}
Index: microwin/src/drivers/scr_fbsd.c
===================================================================
--- microwin.orig/src/drivers/scr_fbsd.c
+++ microwin/src/drivers/scr_fbsd.c
@@ -201,8 +201,8 @@ static PSD FBSD_open(PSD psd)
 
 static void FBSD_getscreeninfo(PSD psd, PMWSCREENINFO psi)
 {
-    psi->rows = psd->yvirtres;
-    psi->cols = psd->xvirtres;
+    psi->visrows = psi->rows = psd->yvirtres;
+    psi->viscols = psi->cols = psd->xvirtres;
     psi->planes = psd->planes;
     psi->bpp = psd->bpp;
     psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_herc.c
===================================================================
--- microwin.orig/src/drivers/scr_herc.c
+++ microwin/src/drivers/scr_herc.c
@@ -144,8 +144,8 @@ HERC_close(PSD psd)
 static void
 HERC_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_prsm.c
===================================================================
--- microwin.orig/src/drivers/scr_prsm.c
+++ microwin/src/drivers/scr_prsm.c
@@ -126,8 +126,8 @@ VB_close(PSD psd)
 static void
 VB_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	pis->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_rtems.c
===================================================================
--- microwin.orig/src/drivers/scr_rtems.c
+++ microwin/src/drivers/scr_rtems.c
@@ -311,8 +311,8 @@ ioctl_setpalette(int start, int len, sho
 static void
 gen_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_svga.c
===================================================================
--- microwin.orig/src/drivers/scr_svga.c
+++ microwin/src/drivers/scr_svga.c
@@ -109,8 +109,8 @@ SVGA_close(PSD psd)
 static void
 SVGA_getscreeninfo(PSD psd,PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/drivers/scr_x11.c
===================================================================
--- microwin.orig/src/drivers/scr_x11.c
+++ microwin/src/drivers/scr_x11.c
@@ -841,8 +841,8 @@ X11_close(PSD psd)
 static void
 X11_getscreeninfo(PSD psd, PMWSCREENINFO psi)
 {
-	psi->rows = psd->yvirtres;
-	psi->cols = psd->xvirtres;
+	psi->visrows = psi->rows = psd->yvirtres;
+	psi->viscols = psi->cols = psd->xvirtres;
 	psi->planes = psd->planes;
 	psi->bpp = psd->bpp;
 	psi->ncolors = psd->ncolors;
Index: microwin/src/engine/devmouse.c
===================================================================
--- microwin.orig/src/engine/devmouse.c
+++ microwin/src/engine/devmouse.c
@@ -183,6 +183,8 @@ GdSetAccelMouse(int newthresh, int newsc
 void
 GdMoveMouse(MWCOORD newx, MWCOORD newy)
 {
+        int xo = scrdev.xoffset, yo = scrdev.yoffset;
+	
 	if (!(mousedev.flags & MOUSE_RAW)) {
 		if (newx < minx)
 			newx = minx;
@@ -197,6 +199,30 @@ GdMoveMouse(MWCOORD newx, MWCOORD newy)
 	if (newx == xpos && newy == ypos)
 		return;
 
+#ifdef NOTUSED
+	/* Pan the display if possible - we want to do this smoothly */
+
+	if (newx < scrdev.xoffset)
+ 	  xo = newx - 5;
+	else if (newx > scrdev.xoffset + scrdev.xvisible)
+	  xo = (newx + 5) - scrdev.xvisible;
+	
+	if (newy < scrdev.yoffset)
+	  yo = newy - 5;
+	else if (newy > scrdev.yoffset + scrdev.yvisible)
+	  yo = (newy + 5) - scrdev.yvisible;
+	
+	if (xo < 0) xo = 0;
+	if (xo > scrdev.xres) xo = scrdev.xres - scrdev.xvisible;
+	
+	if (yo < 0) yo = 0;
+	if (yo > scrdev.yres) yo = scrdev.yres - scrdev.yvisible;
+
+	/* Move the screen accordingly */
+	if (xo != scrdev.xoffset || yo != scrdev.yoffset)
+	  GdPanScreen(&scrdev, xo, yo);
+#endif
+
 	changed = TRUE;
 
 	xpos = newx;
Index: microwin/src/engine/devopen.c
===================================================================
--- microwin.orig/src/engine/devopen.c
+++ microwin/src/engine/devopen.c
@@ -408,6 +408,41 @@ GdGetColorRGB(PSD psd, MWPIXELVAL pixel)
 	}
 }
 
+void
+GdPanScreen(PSD psd, int xoffset, int yoffset) {
+		
+	if (!psd->PanScreen) return;
+
+	if ((psd->xvisible != psd->xvirtres)) {
+
+		/* Bound it */
+
+		if (xoffset < 0) xoffset = 0;		
+		if (xoffset + psd->xvisible > psd->xvirtres)
+			xoffset = psd->xvirtres - psd->xvisible;
+	}
+	else 
+		xoffset = 0;
+
+	if ((psd->yvisible != psd->yvirtres)) {
+		
+		/* Bound it */
+
+		if (yoffset < 0) yoffset = 0;		
+		if (yoffset + psd->yvisible > psd->yvirtres)
+			yoffset = psd->yvirtres - psd->yvisible;
+	}
+	else 
+		yoffset = 0;
+
+	if (xoffset != psd->xoffset || yoffset != psd->yoffset) {
+		psd->yoffset = yoffset;
+		psd->xoffset = xoffset;
+
+		psd->PanScreen(psd, psd->xoffset, psd->yoffset);
+	}
+}
+
 #if !VXWORKS
 #if defined(HAVE_FILEIO)
 #include <unistd.h>
@@ -637,3 +672,5 @@ GdCaptureScreen(char *path)
 	return 0;
 }
 #endif /* !VXWORKS*/
+
+
Index: microwin/src/include/device.h
===================================================================
--- microwin.orig/src/include/device.h
+++ microwin/src/include/device.h
@@ -338,6 +338,10 @@ typedef struct _mwscreendevice {
 	MWCOORD	yres;		/* Y screen res (real) */
 	MWCOORD	xvirtres;	/* X drawing res (will be flipped in portrait mode) */
 	MWCOORD	yvirtres;	/* Y drawing res (will be flipped in portrait mode) */
+	int     xvisible;       /* Actual x real estate that is visible */
+	int     yvisible;       /* Ditto */
+	int     xoffset;        /* X offset for panning */
+	int     yoffset;        /* Y offset for panning */
 	int	planes;		/* # planes*/
 	int	bpp;		/* # bpp*/
 	int	linelen;	/* line length in bytes for bpp 1,2,4,8*/
@@ -374,6 +378,7 @@ typedef struct _mwscreendevice {
 	MWBOOL	(*MapMemGC)(PSD mempsd,MWCOORD w,MWCOORD h,int planes,int bpp,
 			int linelen,int size,void *addr);
 	void	(*FreeMemGC)(PSD mempsd);
+	void    (*PanScreen)(PSD, int, int);
 	void	(*StretchBlit)(PSD destpsd,MWCOORD destx,MWCOORD desty,
 			MWCOORD destw,MWCOORD desth,PSD srcpsd,MWCOORD srcx,
 			MWCOORD srcy,MWCOORD srcw,MWCOORD srch,long op);
@@ -794,6 +799,8 @@ void	drawbitmap(PSD psd, MWCOORD x, MWCO
 		const MWIMAGEBITS *imagebits);
 void	drawpoint(PSD psd, MWCOORD x, MWCOORD y);
 void	drawrow(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y);
+void    GdPanScreen(PSD psd, int, int);
+
 extern SCREENDEVICE scrdev;
 
 
Index: microwin/src/include/mwtypes.h
===================================================================
--- microwin.orig/src/include/mwtypes.h
+++ microwin/src/include/mwtypes.h
@@ -314,6 +314,8 @@ typedef unsigned int	MWKEYMOD;
 typedef struct {
 	MWCOORD  rows;		/* number of rows on screen */
 	MWCOORD  cols;		/* number of columns on screen */
+	MWCOORD  visrows;       /* number of visible rows */
+	MWCOORD  viscols;       /* number of visible columns */
 	int 	 xdpcm;		/* dots/centimeter in x direction */
 	int 	 ydpcm;		/* dots/centimeter in y direction */
 	int	 planes;	/* hw # planes*/
Index: microwin/src/include/nano-X.h
===================================================================
--- microwin.orig/src/include/nano-X.h
+++ microwin/src/include/nano-X.h
@@ -559,6 +559,12 @@ typedef union {
 
 typedef void (*GR_FNCALLBACKEVENT)(GR_EVENT *);
 
+typedef struct {
+   GR_WINDOW_ID buf[2];
+   int active;
+   int size;
+} GR_DOUBLE_BUFFER;
+	
 /* GR_BITMAP macros*/
 /* size of GR_BITMAP image in words*/
 #define	GR_BITMAP_SIZE(width, height)	MWIMAGE_SIZE(width, height)
@@ -925,6 +931,7 @@ void            GrSetTransform(GR_TRANSF
 int             GrCalcTransform(GR_CAL_DATA *, GR_TRANSFORM *);
 int             GrLoadTransformData(char *filename, GR_TRANSFORM *);
 int             GrSaveTransformData(GR_TRANSFORM *, char *filename);
+void            GrPanDisplay(int, int);
 
 /* nxutil.c - utility routines*/
 GR_WINDOW_ID	GrNewWindowEx(GR_WM_PROPS props, GR_CHAR *title,
@@ -944,6 +951,12 @@ GR_BITMAP *	GrNewBitmapFromPixmap(GR_WIN
 GR_REGION_ID	GrNewRegionFromPixmap(GR_WINDOW_ID src, MWCOORD x, MWCOORD y,
 			GR_SIZE width, GR_SIZE height);
 
+/* nxdblbuf.c */
+
+GR_DOUBLE_BUFFER *GrInitDoubleBuffer(void);
+void GrCloseDoubleBuffer(GR_DOUBLE_BUFFER *);
+void GrFlipBuffers(GR_DOUBLE_BUFFER *);
+
 /* direct client-side framebuffer mapping routines*/
 unsigned char * GrOpenClientFramebuffer(void);
 void		GrCloseClientFramebuffer(void);
Index: microwin/src/nanox/Makefile
===================================================================
--- microwin.orig/src/nanox/Makefile
+++ microwin/src/nanox/Makefile
@@ -38,7 +38,8 @@ NANOXFILES := \
 OBJS := \
 	$(MW_DIR_OBJ)/nanox/nxdraw.o \
 	$(MW_DIR_OBJ)/nanox/nxutil.o \
-	$(MW_DIR_OBJ)/nanox/nxtransform.o
+	$(MW_DIR_OBJ)/nanox/nxtransform.o \
+	$(MW_DIR_OBJ)/nanox/nxdblbuf.o
 
 ifeq ($(LINK_APP_INTO_SERVER), Y)
 OBJS += $(NANOXFILES)
Index: microwin/src/nanox/client.c
===================================================================
--- microwin.orig/src/nanox/client.c
+++ microwin/src/nanox/client.c
@@ -4761,5 +4761,19 @@ GrCopyFont(GR_FONT_ID fontid, GR_COORD h
 }
 #endif /*HAVE_FREETYPE_2_SUPPORT*/
 
+/* Used to pan the display for those devices that have such support */
 
+void
+GrPanDisplay(int xoffset, int yoffset) {
+
+  nxPanDisplayReq *req;
+
+  LOCK(&nxGlobalLock);
+
+  req = AllocReq(PanDisplay);
+  req->xoffset = xoffset;
+  req->yoffset = yoffset;
+
+  UNLOCK(&nxGlobalLock);
+}
 
Index: microwin/src/nanox/nxdblbuf.c
===================================================================
--- /dev/null
+++ microwin/src/nanox/nxdblbuf.c
@@ -0,0 +1,49 @@
+#include "nano-X.h"
+#include "device.h"
+
+/* Initalize two windows that act as double buffers */
+
+GR_DOUBLE_BUFFER *GrInitDoubleBuffer(void) {
+  
+  GR_SCREEN_INFO si;
+  GR_DOUBLE_BUFFER *s = 0;
+
+  GrGetScreenInfo(&si);
+
+  if (si.rows < si.visrows * 2) return 0;
+  
+  s = malloc(sizeof(GR_DOUBLE_BUFFER));
+  if (!s) return 0;
+
+  printf("VISROWS=%d\n", si.visrows);
+
+  s->buf[0] = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, si.cols, 
+			  si.visrows, 0, 0, 0);
+  
+  s->buf[1] = GrNewWindow(GR_ROOT_WINDOW_ID, 0, si.visrows, 
+			  si.cols, si.visrows, 0, 0, 0);
+
+  s->active = 0;
+  s->size = si.visrows;
+
+  return s;
+}
+
+void GrCloseDoubleBuffer(GR_DOUBLE_BUFFER *buf) {
+  GrDestroyWindow(buf->buf[0]);
+  GrDestroyWindow(buf->buf[1]);
+
+  free(buf);
+}
+
+/* Flip the screen betwee nteh two buffers */
+
+void GrFlipBuffers(GR_DOUBLE_BUFFER *buf) {
+
+  if (!buf) return;
+
+  buf->active = !buf->active;
+  GrPanDisplay(0, buf->size * buf->active);
+}
+
+  
Index: microwin/src/nanox/nxproto.h
===================================================================
--- microwin.orig/src/nanox/nxproto.h
+++ microwin/src/nanox/nxproto.h
@@ -1366,4 +1366,13 @@ typedef struct {
 	INT16 height;
 } nxCopyFontReq;
 
-#define GrTotalNumCalls         125
+#define GrNumPanDisplay         125
+typedef struct 	{
+	BYTE8 reqType;
+	BYTE8 hilength;
+	UINT16 length;
+	INT16 xoffset;
+	INT16 yoffset;
+} nxPanDisplayReq;
+	
+#define GrTotalNumCalls         126
Index: microwin/src/nanox/srvfunc.c
===================================================================
--- microwin.orig/src/nanox/srvfunc.c
+++ microwin/src/nanox/srvfunc.c
@@ -4314,3 +4314,15 @@ GrUngrabKey(GR_WINDOW_ID id, GR_KEY key)
 
 	SERVER_UNLOCK();
 }
+
+/**
+ * Pan the display 
+ *
+ * @param xoffset New xoffset of the display
+ * @param yoffset New yoffset of the display
+ */
+
+void
+GrPanDisplay(int xoffset, int yoffset) {  
+  GdPanScreen(rootwp->psd, xoffset, yoffset);
+}
Index: microwin/src/nanox/srvmain.c
===================================================================
--- microwin.orig/src/nanox/srvmain.c
+++ microwin/src/nanox/srvmain.c
@@ -1169,7 +1169,15 @@ GsInitialize(void)
 	 * Tell the mouse driver some things.
 	 */
 	curbuttons = 0;
-	GdRestrictMouse(0, 0, psd->xvirtres - 1, psd->yvirtres - 1);
+
+	/* If panning is indicated, we now allow the mouse the full range
+	   of motion */
+	
+	if (psd->PanScreen)
+	  GdRestrictMouse(0, 0, psd->xres - 1, psd->yres - 1);
+	else
+	  GdRestrictMouse(0, 0, psd->xvirtres - 1, psd->yvirtres - 1);
+
 	GdMoveMouse(psd->xvirtres / 2, psd->yvirtres / 2);
 
 	/* Force root window screen paint*/
Index: microwin/src/nanox/srvnet.c
===================================================================
--- microwin.orig/src/nanox/srvnet.c
+++ microwin/src/nanox/srvnet.c
@@ -1593,6 +1593,11 @@ GrCopyFontWrapper(void *r)
 #endif /*HAVE_FREETYPE_2_SUPPORT*/
 }
 
+static void
+GrPanDisplayWrapper(void *r) {
+	nxPanDisplayReq *req = r;
+	GrPanDisplay(req->xoffset, req->yoffset);
+}
 
 void GrShmCmdsFlushWrapper(void *r);
 
@@ -1729,6 +1734,7 @@ static const struct GrFunction GrFunctio
 	/* 122 */ {GrSetTransformWrapper, "GrSetTransform" },
 	/* 123 */ {GrCreateFontFromBufferWrapper, "GrCreateFontFromBuffer"},
 	/* 124 */ {GrCopyFontWrapper, "GrCopyFont"},
+	/* 125 */ {GrPanDisplayWrapper, "GrPanDisplay" }
 };
 
 void


[<<] [<] Page 1 of 2 [>] [>>]


Powered by ezmlm-browse 0.20.