diff -urN microwindows-0.90.orig/src/demos/mwin/Makefile microwindows-0.90/src/demos/mwin/Makefile
--- microwindows-0.90.orig/src/demos/mwin/Makefile	2001-06-21 10:32:39.000000000 +0400
+++ microwindows-0.90/src/demos/mwin/Makefile	2003-09-18 16:26:01.000000000 +0400
@@ -37,7 +37,8 @@
 	$(TOP)/bin/malpha\
 	$(TOP)/bin/mtest\
 	$(TOP)/bin/mtest2\
-	$(TOP)/bin/mine
+	$(TOP)/bin/mine\
+	$(TOP)/bin/mstretch
 
 ifneq ($(ARCH), ELKS)
 DEMOS += $(TOP)/bin/muserfd
@@ -66,6 +67,9 @@
 $(TOP)/bin/mtest: mtest.o $(MWINLIBS) $(TOP)/config
 	$(CC) $(CFLAGS) $(LDFLAGS) mtest.o -o $@ $(CCMWINLIBS)
 
+$(TOP)/bin/mstretch: mstretch.o $(MWINLIBS) $(TOP)/config
+	$(CC) $(CFLAGS) $(LDFLAGS) mstretch.o -o $@ $(CCMWINLIBS)
+
 $(TOP)/bin/mtest2: mtest2.o $(MWINLIBS) $(TOP)/config
 	$(CC) $(CFLAGS) $(LDFLAGS) mtest2.o -o $@ $(CCMWINLIBS)
 
diff -urN microwindows-0.90.orig/src/drivers/fb.h microwindows-0.90/src/drivers/fb.h
--- microwindows-0.90.orig/src/drivers/fb.h	2003-02-25 11:59:52.000000000 +0300
+++ microwindows-0.90/src/drivers/fb.h	2003-09-18 15:35:04.000000000 +0400
@@ -26,6 +26,16 @@
 typedef unsigned short *	ADDR16;
 typedef unsigned long *		ADDR32;
 
+#ifndef RESTRICT
+#define RESTRICT
+#endif
+#ifndef SIGN
+#define SIGN(x) (((x) > 0) ? 1 : (((x) == 0) ? 0 : -1))
+#endif
+#ifndef ABS
+#define ABS(x) (((x) >= 0) ? (x) : -(x))
+#endif
+
 /* Note that the following ROP macro implements the
  * Porter-Duff rules assuming that source and destination
  * both have an alpha of 1.0.  Drivers that support alpha
diff -urN microwindows-0.90.orig/src/drivers/fblin16.c microwindows-0.90/src/drivers/fblin16.c
--- microwindows-0.90.orig/src/drivers/fblin16.c	2003-05-11 22:18:11.000000000 +0400
+++ microwindows-0.90/src/drivers/fblin16.c	2003-09-19 11:50:40.000000000 +0400
@@ -318,17 +318,8 @@
  * could "#define RESTRICT restrict" or put
  * "CFLAGS += -DRESTRICT=restrict" in the makefile).
  *
- * Compatibility definitions:
+ * Compatibility definitions (see fb.h)
  */
-#ifndef RESTRICT
-#define RESTRICT
-#endif
-#ifndef SIGN
-#define SIGN(x) (((x) > 0) ? 1 : (((x) == 0) ? 0 : -1))
-#endif
-#ifndef ABS
-#define ABS(x) (((x) >= 0) ? (x) : -(x))
-#endif
 
 /* Blit a 16-bit image.
  * Can stretch the image by any X and/or Y scale factor.
diff -urN microwindows-0.90.orig/src/drivers/fblin1.c microwindows-0.90/src/drivers/fblin1.c
--- microwindows-0.90.orig/src/drivers/fblin1.c	2003-02-26 07:01:25.000000000 +0300
+++ microwindows-0.90/src/drivers/fblin1.c	2003-09-19 11:50:19.000000000 +0400
@@ -167,6 +167,202 @@
 	DRAWOFF;
 }
 
+#define GETSHIFT(x) (0x7 - (x))
+#define GETB(v, vx) (((v) >> GETSHIFT(vx)) & 0x1)
+
+DEFINE_applyOpR
+
+static void
+linear1_stretchblitex(PSD dstpsd,
+			 PSD srcpsd,
+			 MWCOORD dest_x_start,
+			 MWCOORD dest_y_start,
+			 MWCOORD width,
+			 MWCOORD height,
+			 int x_denominator,
+			 int y_denominator,
+			 int src_x_fraction,
+			 int src_y_fraction,
+			 int x_step_fraction,
+			 int y_step_fraction,
+			 long op)
+{
+	ADDR8 src_ptr;
+	ADDR8 next_src_ptr;
+	int sx;
+	int next_sx;
+	ADDR8 dest_ptr;
+	ADDR8 next_dest_ptr;
+	int dx;
+	int next_dx;
+
+	/* Keep track of error in the source co-ordinates */
+	int x_error;
+	int y_error;
+
+	/* 1-unit steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int src_x_step_one;
+	int src_y_step_one;
+
+	/* normal steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int src_x_step_normal;
+	int src_y_step_normal;
+
+	/* 1-unit steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int x_error_step_normal;
+	int y_error_step_normal;
+
+	/* Countdown to the end of the destination image */
+	int x_count;
+	int y_count;
+
+	/* Start position in source, in whole pixels */
+	int src_x_start;
+	int src_y_start;
+
+	/* Error values for start X position in source */
+	int x_error_start;
+
+	/* 1-unit step down dest, in bytes. */
+	int dest_y_step;
+
+	/*DPRINTF("Nano-X: linear32_stretchflipblit( dest=(%d,%d) %dx%d )\n",
+	       dest_x_start, dest_y_start, width, height);*/
+
+	/* We add half a dest pixel here so we're sampling from the middle of
+	 * the dest pixel, not the top left corner.
+	 */
+	src_x_fraction += (x_step_fraction >> 1);
+	src_y_fraction += (y_step_fraction >> 1);
+
+	/* Seperate the whole part from the fractions.
+	 *
+	 * Also, We need to do lots of comparisons to see if error values are
+	 * >= x_denominator.  So subtract an extra x_denominator for speed - then
+	 * we can just check if it's >= 0.
+	 */
+	src_x_start = src_x_fraction / x_denominator;
+	src_y_start = src_y_fraction / y_denominator;
+	x_error_start = src_x_fraction - (src_x_start + 1) * x_denominator;
+	y_error = src_y_fraction - (src_y_start + 1) * y_denominator;
+
+	/* precalculate various deltas (in bits) */
+
+	src_x_step_normal = (x_step_fraction / x_denominator);
+	src_x_step_one = SIGN(x_step_fraction);
+	x_error_step_normal =
+		ABS(x_step_fraction) - ABS(src_x_step_normal) * x_denominator;
+	
+	src_y_step_normal = y_step_fraction / y_denominator;
+	src_y_step_one = SIGN(y_step_fraction) * srcpsd->linelen;
+	y_error_step_normal =
+		ABS(y_step_fraction) - ABS(src_y_step_normal) * y_denominator;
+	src_y_step_normal *= srcpsd->linelen;
+
+	/* Pointer to the first source pixel */
+	next_src_ptr = (ADDR8)srcpsd->addr +
+		src_y_start * srcpsd->linelen +
+		(src_x_start >> 3);
+
+	next_sx = src_x_start & 0x7;
+
+	/* Cache the width of a scanline in dest */
+	dest_y_step = dstpsd->linelen;
+
+	/* Pointer to the first dest pixel */
+	next_dest_ptr = (ADDR8)dstpsd->addr +
+		dest_y_start * dest_y_step +
+		(dest_x_start >> 3);
+	
+	next_dx = dest_x_start & 0x7;
+
+	/*
+	 * The MWROP_CLEAR case could be removed.  But it is a large
+	 * speed increase for a small quantity of code.
+	 */
+	switch (op & MWROP_EXTENSION) {
+	case MWROP_CLEAR:
+		y_count = height;
+		while (y_count-- > 0) {
+			dest_ptr = next_dest_ptr;
+			dx = next_dx;
+			x_count = width;
+			while (x_count-- > 0) {
+				if (dx == 0 && x_count > 7) {
+					/* Etre rapid loin des frontieres */
+					*dest_ptr++ = 0;
+					x_count -= 7;
+				}
+				else {
+					*dest_ptr &= notmask[dx];
+					++dx;
+					if ((dx &= 0x7) == 0)
+						dest_ptr++;
+				}
+			}
+			next_dest_ptr += dest_y_step;
+		}
+		break;
+	default:
+		y_count = height;
+		while (y_count-- > 0) {
+			src_ptr = next_src_ptr;
+			sx = next_sx;
+			dest_ptr = next_dest_ptr;
+			dx = next_dx;
+
+			x_error = x_error_start;
+
+			x_count = width;
+			while (x_count-- > 0) {
+				*dest_ptr = (*dest_ptr & notmask[dx]) |
+					(applyOpR(MWROP_TO_MODE(op),
+						GETB(*src_ptr, sx),
+						GETB(*dest_ptr, dx)) << GETSHIFT(dx));
+						
+				++dx;
+				if ((dx &= 0x7) == 0)
+					dest_ptr++;
+
+				sx += src_x_step_normal;
+				x_error += x_error_step_normal;
+
+				if (x_error >= 0) {
+					sx += src_x_step_one;
+					x_error -= x_denominator;
+				}
+
+				while (sx >= 8) {
+					sx -= 8;
+					src_ptr++;
+				}
+				while (sx < 0) {
+					sx += 8;
+					src_ptr--;
+				}
+			}
+
+			next_dest_ptr += dest_y_step;
+
+			next_src_ptr += src_y_step_normal;
+			y_error += y_error_step_normal;
+
+			if (y_error >= 0) {
+				next_src_ptr += src_y_step_one;
+				y_error -= y_denominator;
+			}
+		}
+		break;
+
+	}
+}
+
 SUBDRIVER fblinear1 = {
 	linear1_init,
 	linear1_drawpixel,
@@ -174,5 +370,9 @@
 	linear1_drawhorzline,
 	linear1_drawvertline,
 	gen_fillrect,
-	linear1_blit
+	linear1_blit,
+	NULL,
+	NULL,
+	linear1_stretchblitex
 };
+
diff -urN microwindows-0.90.orig/src/drivers/fblin24.c microwindows-0.90/src/drivers/fblin24.c
--- microwindows-0.90.orig/src/drivers/fblin24.c	2003-05-11 22:18:23.000000000 +0400
+++ microwindows-0.90/src/drivers/fblin24.c	2003-09-19 11:50:48.000000000 +0400
@@ -302,17 +302,8 @@
  * could "#define RESTRICT restrict" or put
  * "CFLAGS += -DRESTRICT=restrict" in the makefile).
  *
- * Compatibility definitions:
+ * Compatibility definitions (see fb.h)
  */
-#ifndef RESTRICT
-#define RESTRICT
-#endif
-#ifndef SIGN
-#define SIGN(x) (((x) > 0) ? 1 : (((x) == 0) ? 0 : -1))
-#endif
-#ifndef ABS
-#define ABS(x) (((x) >= 0) ? (x) : -(x))
-#endif
 
 /* Blit a 24-bit image.
  * Can stretch the image by any X and/or Y scale factor.
diff -urN microwindows-0.90.orig/src/drivers/fblin2.c microwindows-0.90/src/drivers/fblin2.c
--- microwindows-0.90.orig/src/drivers/fblin2.c	2003-02-26 07:01:25.000000000 +0300
+++ microwindows-0.90/src/drivers/fblin2.c	2003-09-19 11:49:31.000000000 +0400
@@ -164,6 +164,207 @@
 	DRAWOFF;
 }
 
+#define GETSHIFT(x) ((0x3 - (x)) << 1)
+#define GETB(v, vx) (((v) >> GETSHIFT(vx)) & 0x3)
+
+DEFINE_applyOpR
+
+static void
+linear2_stretchblitex(PSD dstpsd,
+			 PSD srcpsd,
+			 MWCOORD dest_x_start,
+			 MWCOORD dest_y_start,
+			 MWCOORD width,
+			 MWCOORD height,
+			 int x_denominator,
+			 int y_denominator,
+			 int src_x_fraction,
+			 int src_y_fraction,
+			 int x_step_fraction,
+			 int y_step_fraction,
+			 long op)
+{
+	ADDR8 src_ptr;
+	ADDR8 next_src_ptr;
+	int sx;
+	int next_sx;
+	ADDR8 dest_ptr;
+	ADDR8 next_dest_ptr;
+	int dx;
+	int next_dx;
+
+	/* Keep track of error in the source co-ordinates */
+	int x_error;
+	int y_error;
+
+	/* 1-unit steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int src_x_step_one;
+	int src_y_step_one;
+
+	/* normal steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int src_x_step_normal;
+	int src_y_step_normal;
+
+	/* 1-unit steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int x_error_step_normal;
+	int y_error_step_normal;
+
+	/* Countdown to the end of the destination image */
+	int x_count;
+	int y_count;
+
+	/* Start position in source, in whole pixels */
+	int src_x_start;
+	int src_y_start;
+
+	/* Error values for start X position in source */
+	int x_error_start;
+
+	/* 1-unit step down dest, in bytes. */
+	int dest_y_step;
+
+	/*DPRINTF("Nano-X: linear32_stretchflipblit( dest=(%d,%d) %dx%d )\n",
+	       dest_x_start, dest_y_start, width, height);*/
+
+	/* We add half a dest pixel here so we're sampling from the middle of
+	 * the dest pixel, not the top left corner.
+	 */
+	src_x_fraction += (x_step_fraction >> 1);
+	src_y_fraction += (y_step_fraction >> 1);
+
+	/* Seperate the whole part from the fractions.
+	 *
+	 * Also, We need to do lots of comparisons to see if error values are
+	 * >= x_denominator.  So subtract an extra x_denominator for speed - then
+	 * we can just check if it's >= 0.
+	 */
+	src_x_start = src_x_fraction / x_denominator;
+	src_y_start = src_y_fraction / y_denominator;
+	x_error_start = src_x_fraction - (src_x_start + 1) * x_denominator;
+	y_error = src_y_fraction - (src_y_start + 1) * y_denominator;
+
+	/* precalculate various deltas (in bits) */
+
+	src_x_step_normal = (x_step_fraction / x_denominator);
+	src_x_step_one = SIGN(x_step_fraction);
+	x_error_step_normal =
+		ABS(x_step_fraction) - ABS(src_x_step_normal) * x_denominator;
+	
+	src_y_step_normal = y_step_fraction / y_denominator;
+	src_y_step_one = SIGN(y_step_fraction) * srcpsd->linelen;
+	y_error_step_normal =
+		ABS(y_step_fraction) - ABS(src_y_step_normal) * y_denominator;
+	src_y_step_normal *= srcpsd->linelen;
+
+	/* Pointer to the first source pixel */
+	next_src_ptr = (ADDR8)srcpsd->addr +
+		src_y_start * srcpsd->linelen +
+		(src_x_start >> 2);
+
+	next_sx = src_x_start & 0x3;
+
+	/* Cache the width of a scanline in dest */
+	dest_y_step = dstpsd->linelen;
+
+	/* Pointer to the first dest pixel */
+	next_dest_ptr = (ADDR8)dstpsd->addr +
+		dest_y_start * dest_y_step +
+		(dest_x_start >> 2);
+	
+	next_dx = dest_x_start & 0x3;
+
+	/*
+	 * Note: The MWROP_SRC case below is a simple expansion of the
+	 * default case.  It can be removed without significant speed
+	 * penalty if you need to reduce code size.
+	 *
+	 * The MWROP_CLEAR case could be removed.  But it is a large
+	 * speed increase for a small quantity of code.
+	 */
+	switch (op & MWROP_EXTENSION) {
+	case MWROP_CLEAR:
+		y_count = height;
+		while (y_count-- > 0) {
+			dest_ptr = next_dest_ptr;
+			dx = next_dx;
+			x_count = width;
+			while (x_count-- > 0) {
+				if (dx == 0 && x_count > 0x3) {
+					/* Etre rapid loin des frontieres */
+					*dest_ptr++ = 0;
+					x_count -= 0x3;
+				}
+				else {
+					*dest_ptr &= notmask[dx];
+					++dx;
+					if ((dx &= 0x3) == 0)
+						dest_ptr++;
+				}
+			}
+			next_dest_ptr += dest_y_step;
+		}
+		break;
+	default:
+		y_count = height;
+		while (y_count-- > 0) {
+			src_ptr = next_src_ptr;
+			sx = next_sx;
+			dest_ptr = next_dest_ptr;
+			dx = next_dx;
+
+			x_error = x_error_start;
+
+			x_count = width;
+			while (x_count-- > 0) {
+				*dest_ptr = (*dest_ptr & notmask[dx]) |
+					(applyOpR(MWROP_TO_MODE(op),
+						GETB(*src_ptr, sx),
+						GETB(*dest_ptr, dx)) << GETSHIFT(dx));
+						
+				++dx;
+				if ((dx &= 0x3) == 0)
+					dest_ptr++;
+
+				sx += src_x_step_normal;
+				x_error += x_error_step_normal;
+
+				if (x_error >= 0) {
+					sx += src_x_step_one;
+					x_error -= x_denominator;
+				}
+
+				while (sx >= 4) {
+					sx -= 4;
+					src_ptr++;
+				}
+				while (sx < 0) {
+					sx += 4;
+					src_ptr--;
+				}
+			}
+
+			next_dest_ptr += dest_y_step;
+
+			next_src_ptr += src_y_step_normal;
+			y_error += y_error_step_normal;
+
+			if (y_error >= 0) {
+				next_src_ptr += src_y_step_one;
+				y_error -= y_denominator;
+			}
+		}
+		break;
+
+	}
+}
+
+
 SUBDRIVER fblinear2 = {
 	linear2_init,
 	linear2_drawpixel,
@@ -171,5 +372,8 @@
 	linear2_drawhorzline,
 	linear2_drawvertline,
 	gen_fillrect,
-	linear2_blit
+	linear2_blit,
+	NULL,
+	NULL,
+	linear2_stretchblitex
 };
diff -urN microwindows-0.90.orig/src/drivers/fblin32alpha.c microwindows-0.90/src/drivers/fblin32alpha.c
--- microwindows-0.90.orig/src/drivers/fblin32alpha.c	2003-05-11 22:18:41.000000000 +0400
+++ microwindows-0.90/src/drivers/fblin32alpha.c	2003-09-19 11:51:09.000000000 +0400
@@ -656,17 +656,8 @@
  * could "#define RESTRICT restrict" or put
  * "CFLAGS += -DRESTRICT=restrict" in the makefile).
  *
- * Compatibility definitions:
+ * Compatibility definitions (see fb.h)
  */
-#ifndef RESTRICT
-#define RESTRICT
-#endif
-#ifndef SIGN
-#define SIGN(x) (((x) > 0) ? 1 : (((x) == 0) ? 0 : -1))
-#endif
-#ifndef ABS
-#define ABS(x) (((x) >= 0) ? (x) : -(x))
-#endif
 
 /* Blit a 32-bit image.
  * Can stretch the image by any X and/or Y scale factor.
diff -urN microwindows-0.90.orig/src/drivers/fblin32.c microwindows-0.90/src/drivers/fblin32.c
--- microwindows-0.90.orig/src/drivers/fblin32.c	2003-05-11 22:18:08.000000000 +0400
+++ microwindows-0.90/src/drivers/fblin32.c	2003-09-19 11:50:58.000000000 +0400
@@ -284,17 +284,8 @@
  * could "#define RESTRICT restrict" or put
  * "CFLAGS += -DRESTRICT=restrict" in the makefile).
  *
- * Compatibility definitions:
+ * Compatibility definitions (see fb.h)
  */
-#ifndef RESTRICT
-#define RESTRICT
-#endif
-#ifndef SIGN
-#define SIGN(x) (((x) > 0) ? 1 : (((x) == 0) ? 0 : -1))
-#endif
-#ifndef ABS
-#define ABS(x) (((x) >= 0) ? (x) : -(x))
-#endif
 
 /* Blit a 32-bit image.
  * Can stretch the image by any X and/or Y scale factor.
diff -urN microwindows-0.90.orig/src/drivers/fblin4.c microwindows-0.90/src/drivers/fblin4.c
--- microwindows-0.90.orig/src/drivers/fblin4.c	2003-02-25 22:52:25.000000000 +0300
+++ microwindows-0.90/src/drivers/fblin4.c	2003-09-19 11:49:37.000000000 +0400
@@ -187,6 +187,207 @@
 	DRAWOFF;
 }
 
+#define GETSHIFT(x) ((0x1 - (x)) << 2)
+#define GETB(v, vx) (((v) >> GETSHIFT(vx)) & 0xf)
+
+DEFINE_applyOpR
+
+static void
+linear4_stretchblitex(PSD dstpsd,
+			 PSD srcpsd,
+			 MWCOORD dest_x_start,
+			 MWCOORD dest_y_start,
+			 MWCOORD width,
+			 MWCOORD height,
+			 int x_denominator,
+			 int y_denominator,
+			 int src_x_fraction,
+			 int src_y_fraction,
+			 int x_step_fraction,
+			 int y_step_fraction,
+			 long op)
+{
+	ADDR8 src_ptr;
+	ADDR8 next_src_ptr;
+	int sx;
+	int next_sx;
+	ADDR8 dest_ptr;
+	ADDR8 next_dest_ptr;
+	int dx;
+	int next_dx;
+
+	/* Keep track of error in the source co-ordinates */
+	int x_error;
+	int y_error;
+
+	/* 1-unit steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int src_x_step_one;
+	int src_y_step_one;
+
+	/* normal steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int src_x_step_normal;
+	int src_y_step_normal;
+
+	/* 1-unit steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int x_error_step_normal;
+	int y_error_step_normal;
+
+	/* Countdown to the end of the destination image */
+	int x_count;
+	int y_count;
+
+	/* Start position in source, in whole pixels */
+	int src_x_start;
+	int src_y_start;
+
+	/* Error values for start X position in source */
+	int x_error_start;
+
+	/* 1-unit step down dest, in bytes. */
+	int dest_y_step;
+
+	/*DPRINTF("Nano-X: linear32_stretchflipblit( dest=(%d,%d) %dx%d )\n",
+	       dest_x_start, dest_y_start, width, height);*/
+
+	/* We add half a dest pixel here so we're sampling from the middle of
+	 * the dest pixel, not the top left corner.
+	 */
+	src_x_fraction += (x_step_fraction >> 1);
+	src_y_fraction += (y_step_fraction >> 1);
+
+	/* Seperate the whole part from the fractions.
+	 *
+	 * Also, We need to do lots of comparisons to see if error values are
+	 * >= x_denominator.  So subtract an extra x_denominator for speed - then
+	 * we can just check if it's >= 0.
+	 */
+	src_x_start = src_x_fraction / x_denominator;
+	src_y_start = src_y_fraction / y_denominator;
+	x_error_start = src_x_fraction - (src_x_start + 1) * x_denominator;
+	y_error = src_y_fraction - (src_y_start + 1) * y_denominator;
+
+	/* precalculate various deltas (in bits) */
+
+	src_x_step_normal = (x_step_fraction / x_denominator);
+	src_x_step_one = SIGN(x_step_fraction);
+	x_error_step_normal =
+		ABS(x_step_fraction) - ABS(src_x_step_normal) * x_denominator;
+	
+	src_y_step_normal = y_step_fraction / y_denominator;
+	src_y_step_one = SIGN(y_step_fraction) * srcpsd->linelen;
+	y_error_step_normal =
+		ABS(y_step_fraction) - ABS(src_y_step_normal) * y_denominator;
+	src_y_step_normal *= srcpsd->linelen;
+
+	/* Pointer to the first source pixel */
+	next_src_ptr = (ADDR8)srcpsd->addr +
+		src_y_start * srcpsd->linelen +
+		(src_x_start >> 1);
+
+	next_sx = src_x_start & 0x1;
+
+	/* Cache the width of a scanline in dest */
+	dest_y_step = dstpsd->linelen;
+
+	/* Pointer to the first dest pixel */
+	next_dest_ptr = (ADDR8)dstpsd->addr +
+		dest_y_start * dest_y_step +
+		(dest_x_start >> 1);
+	
+	next_dx = dest_x_start & 0x1;
+
+	/*
+	 * Note: The MWROP_SRC case below is a simple expansion of the
+	 * default case.  It can be removed without significant speed
+	 * penalty if you need to reduce code size.
+	 *
+	 * The MWROP_CLEAR case could be removed.  But it is a large
+	 * speed increase for a small quantity of code.
+	 */
+	switch (op & MWROP_EXTENSION) {
+	case MWROP_CLEAR:
+		y_count = height;
+		while (y_count-- > 0) {
+			dest_ptr = next_dest_ptr;
+			dx = next_dx;
+			x_count = width;
+			while (x_count-- > 0) {
+				if (dx == 0 && x_count > 0x1) {
+					/* Etre rapid loin des frontieres */
+					*dest_ptr++ = 0;
+					x_count--;
+				}
+				else {
+					*dest_ptr &= notmask[dx];
+					++dx;
+					if ((dx &= 0x1) == 0)
+						dest_ptr++;
+				}
+			}
+			next_dest_ptr += dest_y_step;
+		}
+		break;
+	default:
+		y_count = height;
+		while (y_count-- > 0) {
+			src_ptr = next_src_ptr;
+			sx = next_sx;
+			dest_ptr = next_dest_ptr;
+			dx = next_dx;
+
+			x_error = x_error_start;
+
+			x_count = width;
+			while (x_count-- > 0) {
+				*dest_ptr = (*dest_ptr & notmask[dx]) |
+					(applyOpR(MWROP_TO_MODE(op),
+						GETB(*src_ptr, sx),
+						GETB(*dest_ptr, dx)) << GETSHIFT(dx));
+						
+				++dx;
+				if ((dx &= 0x1) == 0)
+					dest_ptr++;
+
+				sx += src_x_step_normal;
+				x_error += x_error_step_normal;
+
+				if (x_error >= 0) {
+					sx += src_x_step_one;
+					x_error -= x_denominator;
+				}
+
+				while (sx >= 2) {
+					sx -= 2;
+					src_ptr++;
+				}
+				while (sx < 0) {
+					sx += 2;
+					src_ptr--;
+				}
+			}
+
+			next_dest_ptr += dest_y_step;
+
+			next_src_ptr += src_y_step_normal;
+			y_error += y_error_step_normal;
+
+			if (y_error >= 0) {
+				next_src_ptr += src_y_step_one;
+				y_error -= y_denominator;
+			}
+		}
+		break;
+
+	}
+}
+
+
 SUBDRIVER fblinear4 = {
 	linear4_init,
 	linear4_drawpixel,
@@ -194,5 +395,8 @@
 	linear4_drawhorzline,
 	linear4_drawvertline,
 	gen_fillrect,
-	linear4_blit
+	linear4_blit,
+	NULL,
+	NULL,
+	linear4_stretchblitex
 };
diff -urN microwindows-0.90.orig/src/drivers/fblin8.c microwindows-0.90/src/drivers/fblin8.c
--- microwindows-0.90.orig/src/drivers/fblin8.c	2003-02-25 22:52:25.000000000 +0300
+++ microwindows-0.90/src/drivers/fblin8.c	2003-09-19 11:50:26.000000000 +0400
@@ -838,6 +838,164 @@
 	}
 }
 
+static void
+linear8_stretchblitex(PSD dstpsd,
+			 PSD srcpsd,
+			 MWCOORD dest_x_start,
+			 MWCOORD dest_y_start,
+			 MWCOORD width,
+			 MWCOORD height,
+			 int x_denominator,
+			 int y_denominator,
+			 int src_x_fraction,
+			 int src_y_fraction,
+			 int x_step_fraction,
+			 int y_step_fraction,
+			 long op)
+{
+	ADDR8 src_ptr;
+	ADDR8 next_src_ptr;
+	ADDR8 dest_ptr;
+	ADDR8 next_dest_ptr;
+
+	/* Keep track of error in the source co-ordinates */
+	int x_error;
+	int y_error;
+
+	/* 1-unit steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int src_x_step_one;
+	int src_y_step_one;
+
+	/* normal steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int src_x_step_normal;
+	int src_y_step_normal;
+
+	/* 1-unit steps "forward" through the source image, as steps in the image
+	 * byte array.
+	 */
+	int x_error_step_normal;
+	int y_error_step_normal;
+
+	/* Countdown to the end of the destination image */
+	int x_count;
+	int y_count;
+
+	/* Start position in source, in whole pixels */
+	int src_x_start;
+	int src_y_start;
+
+	/* Error values for start X position in source */
+	int x_error_start;
+
+	/* 1-unit step down dest, in bytes. */
+	int dest_y_step;
+
+	/*DPRINTF("Nano-X: linear32_stretchflipblit( dest=(%d,%d) %dx%d )\n",
+	       dest_x_start, dest_y_start, width, height);*/
+
+	/* We add half a dest pixel here so we're sampling from the middle of
+	 * the dest pixel, not the top left corner.
+	 */
+	src_x_fraction += (x_step_fraction >> 1);
+	src_y_fraction += (y_step_fraction >> 1);
+
+	/* Seperate the whole part from the fractions.
+	 *
+	 * Also, We need to do lots of comparisons to see if error values are
+	 * >= x_denominator.  So subtract an extra x_denominator for speed - then
+	 * we can just check if it's >= 0.
+	 */
+	src_x_start = src_x_fraction / x_denominator;
+	src_y_start = src_y_fraction / y_denominator;
+	x_error_start = src_x_fraction - (src_x_start + 1) * x_denominator;
+	y_error = src_y_fraction - (src_y_start + 1) * y_denominator;
+
+	/* precalculate various deltas (in bits) */
+
+	src_x_step_normal = (x_step_fraction / x_denominator);
+	src_x_step_one = SIGN(x_step_fraction);
+	x_error_step_normal =
+		ABS(x_step_fraction) - ABS(src_x_step_normal) * x_denominator;
+	
+	src_y_step_normal = y_step_fraction / y_denominator;
+	src_y_step_one = SIGN(y_step_fraction) * srcpsd->linelen;
+	y_error_step_normal =
+		ABS(y_step_fraction) - ABS(src_y_step_normal) * y_denominator;
+	src_y_step_normal *= srcpsd->linelen;
+
+	/* Pointer to the first source pixel */
+	next_src_ptr = (ADDR8)srcpsd->addr +
+		src_y_start * srcpsd->linelen +
+		src_x_start;
+
+	/* Cache the width of a scanline in dest */
+	dest_y_step = dstpsd->linelen;
+
+	/* Pointer to the first dest pixel */
+	next_dest_ptr = (ADDR8)dstpsd->addr +
+		dest_y_start * dest_y_step +
+		dest_x_start;
+	
+	/*
+	 * Note: The MWROP_SRC case below is a simple expansion of the
+	 * default case.  It can be removed without significant speed
+	 * penalty if you need to reduce code size.
+	 *
+	 * The MWROP_CLEAR case could be removed.  But it is a large
+	 * speed increase for a small quantity of code.
+	 */
+	switch (op & MWROP_EXTENSION) {
+	case MWROP_CLEAR:
+		y_count = height;
+		while (y_count-- > 0) {
+			dest_ptr = next_dest_ptr;
+			x_count = width;
+			while (x_count-- > 0) {
+				*dest_ptr++ = 0;
+			}
+			next_dest_ptr += dest_y_step;
+		}
+		break;
+	default:
+		y_count = height;
+		while (y_count-- > 0) {
+			src_ptr = next_src_ptr;
+			dest_ptr = next_dest_ptr;
+
+			x_error = x_error_start;
+
+			x_count = width;
+			while (x_count-- > 0) {
+				applyOp(MWROP_TO_MODE(op), *src_ptr, dest_ptr, ADDR8);
+				dest_ptr++;
+
+				src_ptr += src_x_step_normal;
+				x_error += x_error_step_normal;
+
+				if (x_error >= 0) {
+					src_ptr += src_x_step_one;
+					x_error -= x_denominator;
+				}
+			}
+
+			next_dest_ptr += dest_y_step;
+
+			next_src_ptr += src_y_step_normal;
+			y_error += y_error_step_normal;
+
+			if (y_error >= 0) {
+				next_src_ptr += src_y_step_one;
+				y_error -= y_denominator;
+			}
+		}
+		break;
+
+	}
+}
 
 SUBDRIVER fblinear8 = {
 	linear8_init,
@@ -848,5 +1006,6 @@
 	gen_fillrect,
 	linear8_blit,
 	linear8_drawarea,
-	linear8_stretchblit
+	linear8_stretchblit,
+	linear8_stretchblitex
 };
