introducing H1x0 style grayscale support in the X11 sim


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7137 a1c6a512-1295-4272-9138-f99709370657
diff --git a/uisimulator/common/lcd-playersim.h b/uisimulator/common/lcd-playersim.h
index ef3b142..10267de 100644
--- a/uisimulator/common/lcd-playersim.h
+++ b/uisimulator/common/lcd-playersim.h
@@ -30,7 +30,10 @@
 
 void drawdots(int color, struct coordinate *coord, int count);
 void drawdot(int color, int x, int y);
-void drawline(int color, int x1, int y1, int x2, int y2);
 void drawrect(int color, int x1, int y1, int x2, int y2);
 void drawrectangles(int color, struct rectangle *rects, int count);
 
+
+void dots(int *colors, struct coordinate *points, int count);
+
+
diff --git a/uisimulator/x11/lcd-x11.c b/uisimulator/x11/lcd-x11.c
index d538cee..3ad5a79 100644
--- a/uisimulator/x11/lcd-x11.c
+++ b/uisimulator/x11/lcd-x11.c
@@ -43,9 +43,11 @@
 #if LCD_DEPTH == 2
 #define YBLOCK 4
 #define BITOFFS 1  /* take the MSB of each pixel */
+#define ANDBIT 3 /* AND with this to get the color number */
 #else
 #define YBLOCK 8
 #define BITOFFS 0
+#define ANDBIT 1
 #endif
 
 extern void screen_resized(int width, int height);
@@ -56,48 +58,8 @@
 
 void lcd_update (void)
 {
-    int x, y;
-    int p=0;
-    int bit;
-    struct coordinate points[LCD_WIDTH * LCD_HEIGHT];
-    int cp=0;
-    struct coordinate clearpoints[LCD_WIDTH * LCD_HEIGHT];
-
-    for(y=0; y<LCD_HEIGHT; y+=YBLOCK) {
-        for(x=0; x<LCD_WIDTH; x++) {
-            if(lcd_framebuffer[y/YBLOCK][x] || lcd_framebuffer_copy[y/YBLOCK][x]) {
-                /* one or more bits/pixels are changed */
-                unsigned char diff =
-                    lcd_framebuffer[y/YBLOCK][x] ^ lcd_framebuffer_copy[y/YBLOCK][x];
-
-                for(bit=0; bit<YBLOCK; bit++) {
-                    if(lcd_framebuffer[y/YBLOCK][x]&(1<<(bit*LCD_DEPTH+BITOFFS))) {
-                        /* set a dot */
-                        points[p].x = x + MARGIN_X;
-                        points[p].y = y+bit + MARGIN_Y;
-                        p++; /* increase the point counter */
-                    }
-                    else if(diff &(1<<(bit*LCD_DEPTH+BITOFFS))) {
-                        /* clear a dot */
-                        clearpoints[cp].x = x + MARGIN_X;
-                        clearpoints[cp].y = y+bit + MARGIN_Y;
-                        cp++; /* increase the point counter */
-                    }
-                }
-            }
-        }
-    }
-
-    /* copy a huge block */
-    memcpy(lcd_framebuffer_copy, lcd_framebuffer, sizeof(lcd_framebuffer));
-
-    drawdots(0, &clearpoints[0], cp);
-    drawdots(1, &points[0], p);
-    /* printf("lcd_update: Draws %d pixels, clears %d pixels (max %d/%d)\n",
-       p, cp, p+cp, LCD_HEIGHT*LCD_WIDTH); */
-    XtAppLock(app);
-    XSync(dpy,False);
-    XtAppUnlock(app);
+    /* update a full screen rect */
+    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
 }
 
 void lcd_update_rect(int x_start, int y_start,
@@ -108,11 +70,10 @@
     int y;
     int p=0;
     int bit;
-    int cp=0;
     int xmax;
     int ymax;
+    int colors[LCD_WIDTH * LCD_HEIGHT];
     struct coordinate points[LCD_WIDTH * LCD_HEIGHT];
-    struct coordinate clearpoints[LCD_WIDTH * LCD_HEIGHT];
 
 #if 0
     fprintf(stderr, "%04d: lcd_update_rect(%d, %d, %d, %d)\n",
@@ -132,24 +93,25 @@
     for(; yline<=ymax; yline++) {
         y = yline * YBLOCK;
         for(x=x_start; x<xmax; x++) {
-            if(lcd_framebuffer[yline][x] || lcd_framebuffer_copy[yline][x]) {
+            if(lcd_framebuffer[yline][x] != lcd_framebuffer_copy[yline][x]) {
                 /* one or more bits/pixels are changed */
-                unsigned char diff =
-                  lcd_framebuffer[yline][x] ^ lcd_framebuffer_copy[yline][x];
 
                 for(bit=0; bit<YBLOCK; bit++) {
-                    if(lcd_framebuffer[yline][x]&(1<<(bit*LCD_DEPTH+BITOFFS))) {
-                        /* set a dot */
-                        points[p].x = x + MARGIN_X;
-                        points[p].y = y+bit + MARGIN_Y;
-                        p++; /* increase the point counter */
-                    }
-                    else if(diff &(1<<(bit*LCD_DEPTH+BITOFFS))) {
-                        /* clear a dot */
-                        clearpoints[cp].x = x + MARGIN_X;
-                        clearpoints[cp].y = y+bit + MARGIN_Y;
-                        cp++; /* increase the point counter */
-                    }
+                    unsigned int col;
+                    col = lcd_framebuffer[yline][x]&(ANDBIT<<(bit*LCD_DEPTH));
+
+#if LCD_DEPTH == 2
+                    /* shift down the value to the lower bits */
+                    col >>= (bit * LCD_DEPTH);
+
+                    /* set a dot */
+                    colors[p] = col;
+#else
+                    colors[p] = col?3:0;
+#endif
+                    points[p].x = x + MARGIN_X;
+                    points[p].y = y+bit + MARGIN_Y;
+                    p++; /* increase the point counter */
                 }
 
                 /* update the copy */
@@ -158,8 +120,7 @@
         }
     }
 
-    drawdots(0, &clearpoints[0], cp);
-    drawdots(1, &points[0], p);
+    dots(colors, &points[0], p);
     /* printf("lcd_update_rect: Draws %d pixels, clears %d pixels\n", p, cp);*/
     XtAppLock(app);
     XSync(dpy,False);
@@ -175,51 +136,7 @@
 
 void lcd_remote_update (void)
 {
-    int x, y;
-    int p=0;
-    int bit;
-    struct coordinate points[LCD_REMOTE_WIDTH * LCD_REMOTE_HEIGHT];
-    int cp=0;
-    struct coordinate clearpoints[LCD_REMOTE_WIDTH * LCD_REMOTE_HEIGHT];
-
-    for(y=0; y<LCD_REMOTE_HEIGHT; y+=8) {
-        for(x=0; x<LCD_REMOTE_WIDTH; x++) {
-            if(lcd_remote_framebuffer[y/8][x] ||
-               lcd_remote_framebuffer_copy[y/8][x]) {
-                /* one or more bits/pixels are changed */
-                unsigned char diff =
-                    lcd_remote_framebuffer[y/8][x] ^
-                    lcd_remote_framebuffer_copy[y/8][x];
-
-                for(bit=0; bit<8; bit++) {
-                    if(lcd_remote_framebuffer[y/8][x]&(1<<bit)) {
-                        /* set a dot */
-                        points[p].x = x + REMOTE_MARGIN_X;
-                        points[p].y = y+bit + REMOTE_MARGIN_Y;
-                        p++; /* increase the point counter */
-                    }
-                    else if(diff &(1<<bit)) {
-                        /* clear a dot */
-                        clearpoints[cp].x = x + REMOTE_MARGIN_X;
-                        clearpoints[cp].y = y+bit + REMOTE_MARGIN_Y;
-                        cp++; /* increase the point counter */
-                    }
-                }
-            }
-        }
-    }
-
-    /* copy a huge block */
-    memcpy(lcd_remote_framebuffer_copy, lcd_remote_framebuffer,
-           sizeof(lcd_remote_framebuffer));
-
-    drawdots(0, &clearpoints[0], cp);
-    drawdots(1, &points[0], p);
-    /* printf("lcd_update: Draws %d pixels, clears %d pixels (max %d/%d)\n",
-       p, cp, p+cp, LCD_HEIGHT*LCD_WIDTH); */
-    XtAppLock(app);
-    XSync(dpy,False);
-    XtAppUnlock(app);
+    lcd_remote_update_rect(0, 0, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT);
 }
 
 void lcd_remote_update_rect(int x_start, int y_start,
@@ -230,11 +147,10 @@
     int y;
     int p=0;
     int bit;
-    int cp=0;
     int xmax;
     int ymax;
     struct coordinate points[LCD_WIDTH * LCD_HEIGHT];
-    struct coordinate clearpoints[LCD_WIDTH * LCD_HEIGHT];
+    int colors[LCD_WIDTH * LCD_HEIGHT];
 
 #if 0
     fprintf(stderr, "%04d: lcd_update_rect(%d, %d, %d, %d)\n",
@@ -264,18 +180,20 @@
                 for(bit=0; bit<8; bit++) {
                     if(lcd_remote_framebuffer[yline][x]&(1<<bit)) {
                         /* set a dot */
+                        colors[p]=3;
                         points[p].x = x + REMOTE_MARGIN_X;
                         points[p].y = y+bit + REMOTE_MARGIN_Y;
                         p++; /* increase the point counter */
                     }
                     else if(diff &(1<<bit)) {
                         /* clear a dot */
-                        clearpoints[cp].x = x + REMOTE_MARGIN_X;
-                        clearpoints[cp].y = y+bit + REMOTE_MARGIN_Y;
-                        cp++; /* increase the point counter */
+                        colors[p]=0;
+                        points[p].x = x + REMOTE_MARGIN_X;
+                        points[p].y = y+bit + REMOTE_MARGIN_Y;
+                        p++; /* increase the point counter */
                     }
                 }
-
+                
                 /* update the copy */
                 lcd_remote_framebuffer_copy[yline][x] =
                     lcd_remote_framebuffer[yline][x];
@@ -283,8 +201,7 @@
         }
     }
 
-    drawdots(0, &clearpoints[0], cp);
-    drawdots(1, &points[0], p);
+    dots(colors, &points[0], p);
     /* printf("lcd_update_rect: Draws %d pixels, clears %d pixels\n", p, cp);*/
     XtAppLock(app);
     XSync(dpy,False);
diff --git a/uisimulator/x11/lcd-x11.h b/uisimulator/x11/lcd-x11.h
index b95374c..07911b2 100644
--- a/uisimulator/x11/lcd-x11.h
+++ b/uisimulator/x11/lcd-x11.h
@@ -22,3 +22,5 @@
 
 /* include the "real" lcd.h file here */
 #include <lcd.h>
+
+
diff --git a/uisimulator/x11/resources.c b/uisimulator/x11/resources.c
index e0925d0..feaf3b8 100644
--- a/uisimulator/x11/resources.c
+++ b/uisimulator/x11/resources.c
@@ -21,9 +21,6 @@
 extern char *progclass;
 extern XrmDatabase db;
 
-static unsigned int get_time_resource (char *res_name, char *res_class,
-				       Bool sec_p);
-
 #ifndef isupper
 # define isupper(c)  ((c) >= 'A' && (c) <= 'Z')
 #endif
@@ -79,57 +76,6 @@
   return 0;
 }
 
-int 
-get_integer_resource (char *res_name, char *res_class)
-{
-  int val;
-  char c, *s = get_string_resource (res_name, res_class);
-  char *ss = s;
-  if (!s) return 0;
-
-  while (*ss && *ss <= ' ') ss++;			/* skip whitespace */
-
-  if (ss[0] == '0' && (ss[1] == 'x' || ss[1] == 'X'))	/* 0x: parse as hex */
-    {
-      if (1 == sscanf (ss+2, "%x %c", &val, &c))
-	{
-	  free (s);
-	  return val;
-	}
-    }
-  else							/* else parse as dec */
-    {
-      if (1 == sscanf (ss, "%d %c", &val, &c))
-	{
-	  free (s);
-	  return val;
-	}
-    }
-
-  fprintf (stderr, "%s: %s must be an integer, not %s.\n",
-	   progname, res_name, s);
-  free (s);
-  return 0;
-}
-
-double
-get_float_resource (char *res_name, char *res_class)
-{
-  double val;
-  char c, *s = get_string_resource (res_name, res_class);
-  if (! s) return 0.0;
-  if (1 == sscanf (s, " %lf %c", &val, &c))
-    {
-      free (s);
-      return val;
-    }
-  fprintf (stderr, "%s: %s must be a float, not %s.\n",
-	   progname, res_name, s);
-  free (s);
-  return 0.0;
-}
-
-
 unsigned int
 get_pixel_resource (char *res_name, char *res_class,
 		    Display *dpy, Colormap cmap)
@@ -165,67 +111,3 @@
 	  : WhitePixel (dpy, DefaultScreen (dpy)));
 }
 
-
-int
-parse_time (const char *string, Bool seconds_default_p, Bool silent_p)
-{
-  unsigned int h, m, s;
-  char c;
-  if (3 == sscanf (string,   " %u : %2u : %2u %c", &h, &m, &s, &c))
-    ;
-  else if (2 == sscanf (string, " : %2u : %2u %c", &m, &s, &c) ||
-	   2 == sscanf (string,    " %u : %2u %c", &m, &s, &c))
-    h = 0;
-  else if (1 == sscanf (string,       " : %2u %c", &s, &c))
-    h = m = 0;
-  else if (1 == sscanf (string,          " %u %c",
-			(seconds_default_p ? &s : &m), &c))
-    {
-      h = 0;
-      if (seconds_default_p) m = 0;
-      else s = 0;
-    }
-  else
-    {
-      if (! silent_p)
-	fprintf (stderr, "%s: invalid time interval specification \"%s\".\n",
-		 progname, string);
-      return -1;
-    }
-  if (s >= 60 && (h != 0 || m != 0))
-    {
-      if (! silent_p)
-	fprintf (stderr, "%s: seconds > 59 in \"%s\".\n", progname, string);
-      return -1;
-    }
-  if (m >= 60 && h > 0)
-    {
-      if (! silent_p)
-	fprintf (stderr, "%s: minutes > 59 in \"%s\".\n", progname, string);
-      return -1;
-    }
-  return ((h * 60 * 60) + (m * 60) + s);
-}
-
-static unsigned int 
-get_time_resource (char *res_name, char *res_class, Bool sec_p)
-{
-  int val;
-  char *s = get_string_resource (res_name, res_class);
-  if (!s) return 0;
-  val = parse_time (s, sec_p, False);
-  free (s);
-  return (val < 0 ? 0 : val);
-}
-
-unsigned int 
-get_seconds_resource (char *res_name, char *res_class)
-{
-  return get_time_resource (res_name, res_class, True);
-}
-
-unsigned int 
-get_minutes_resource (char *res_name, char *res_class)
-{
-  return get_time_resource (res_name, res_class, False);
-}
diff --git a/uisimulator/x11/uibasic.c b/uisimulator/x11/uibasic.c
index 3e7f46c..05eb3ff 100644
--- a/uisimulator/x11/uibasic.c
+++ b/uisimulator/x11/uibasic.c
@@ -58,30 +58,75 @@
 };
 char *progclass = "rockboxui";
 
-char *defaults [] = {
 #ifdef IRIVER_H100_SERIES
-    ".background: lightblue",
+#define BGCOLOR "lightblue"
 #elif defined ARCHOS_GMINI120
-    ".background: royalblue",
+#define BGCOLOR "royalblue"
 #else
-    ".background: lightgreen",
+#define BGCOLOR "lightgreen"
 #endif
+
+
+char *defaults [] = {
+    ".background: " BGCOLOR,
     ".foreground: black",
     "*help:       false",
     0
 };
 
+static XColor getcolor[4];
+
+/* set a range of bitmap indices to a gradient from startcolour to endcolour
+   inherited from the win32 sim code by Jens Arnold */
+static void lcdcolors(int index, int count, XColor *start, XColor *end)
+{
+    int i;
+    count--;
+    for (i = 0; i <= count; i++)
+    {
+        getcolor[i+index].red = start->red
+            + (end->red - start->red) * i / count;
+        getcolor[i+index].green = start->green
+            + (end->green - start->green) * i / count;
+        getcolor[i+index].blue = start->blue
+            + (end->blue - start->blue) * i / count;
+        XAllocColor (dpy, cmap, &getcolor[i+index]);
+    }
+}
+
+
 void init_window ()
 {
     XGCValues gcv;
     XWindowAttributes xgwa;
 
     XGetWindowAttributes (dpy, window, &xgwa);
+    XColor bg;
+    XColor fg;
 
     cmap = xgwa.colormap;
 
+    XParseColor (dpy, cmap, BGCOLOR, &bg);
+    XParseColor (dpy, cmap, "black", &fg);
+    getcolor[0] = bg;
+    getcolor[1] = bg;
+    getcolor[2] = bg;
+    getcolor[3] = bg;
+
+    lcdcolors(0, 4, &bg, &fg);
+
+#if 0
+    for(i=0; i<4; i++) {
+        printf("color %d: %d %d %d\n",
+               i,
+               getcolor[i].red,
+               getcolor[i].green,
+               getcolor[i].blue);
+    }
+#endif
+    
     gcv.function = GXxor;
-    gcv.foreground = get_pixel_resource("foreground", "Foreground", dpy, cmap);
+    gcv.foreground = getcolor[3].pixel;
     draw_gc = XCreateGC (dpy, window, GCForeground, &gcv);
 
     screen_resized(LCD_WIDTH, LCD_HEIGHT);
@@ -94,8 +139,8 @@
     maxy = height;
 
     XtAppLock(app);
-    XSetForeground(dpy, draw_gc,
-                   get_pixel_resource("background", "Background", dpy, cmap));
+    XSetForeground(dpy, draw_gc, getcolor[0].pixel);
+
     XFillRectangle(dpy, window, draw_gc, 0, 0, width*display_zoom,
                    height*display_zoom);
     XtAppUnlock(app);
@@ -106,13 +151,7 @@
 void drawrect(int color, int x1, int y1, int x2, int y2)
 {
     XtAppLock(app);
-    if (color==0)
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("background", "Background", dpy, cmap));
-    else
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("foreground", "Foreground", dpy, cmap));
-
+    XSetForeground(dpy, draw_gc, getcolor[color].pixel);
     XFillRectangle(dpy, window, draw_gc, x1*display_zoom, y1*display_zoom,
                    x2*display_zoom, y2*display_zoom);
     XtAppUnlock(app);
@@ -124,15 +163,10 @@
            "usage: " PROGNAME "\n");
 }
 
-void drawline(int color, int x1, int y1, int x2, int y2)
+static void drawline(int color, int x1, int y1, int x2, int y2)
 {
     XtAppLock(app);
-    if (color==0)
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("background", "Background", dpy, cmap));
-    else
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("foreground", "Foreground", dpy, cmap));
+    XSetForeground(dpy, draw_gc, getcolor[color].pixel);
 
     XDrawLine(dpy, window, draw_gc,
               (int)(x1*display_zoom),
@@ -142,32 +176,14 @@
     XtAppUnlock(app);
 }
 
-void drawdot(int color, int x, int y)
+void dots(int *colors, struct coordinate *points, int count)
 {
+    int color;
     XtAppLock(app);
-    if (color==0)
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("background", "Background", dpy, cmap));
-    else
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("foreground", "Foreground", dpy, cmap));
-
-    XFillRectangle(dpy, window, draw_gc, x*display_zoom, y*display_zoom,
-                   display_zoom, display_zoom);
-    XtAppUnlock(app);
-}
-
-void drawdots(int color, struct coordinate *points, int count)
-{
-    XtAppLock(app);
-    if (color==0)
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("background", "Background", dpy, cmap));
-    else
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("foreground", "Foreground", dpy, cmap));
 
     while (count--) {
+        color = colors[count];
+        XSetForeground(dpy, draw_gc, getcolor[color].pixel);
         XFillRectangle(dpy, window, draw_gc,
                        points[count].x*display_zoom,
                        points[count].y*display_zoom,
@@ -177,41 +193,6 @@
     XtAppUnlock(app);
 }
 
-void drawrectangles(int color, struct rectangle *points, int count)
-{
-    XtAppLock(app);
-    if (color==0)
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("background", "Background", dpy, cmap));
-    else
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("foreground", "Foreground", dpy, cmap));
-
-    while (count--) {
-        XFillRectangle(dpy, window, draw_gc,
-                       points[count].x*display_zoom,
-                       points[count].y*display_zoom,
-                       points[count].width*display_zoom,
-                       points[count].height*display_zoom);
-    }
-    XtAppUnlock(app);
-}
-
-void drawtext(int color, int x, int y, char *text)
-{
-    XtAppLock(app);
-    if (color==0)
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("background", "Background", dpy, cmap));
-    else
-        XSetForeground(dpy, draw_gc,
-                       get_pixel_resource("foreground", "Foreground", dpy, cmap));
-
-    XDrawString(dpy, window, draw_gc, x*display_zoom, y*display_zoom, text,
-                strlen(text));
-    XtAppUnlock(app);
-}
-
 /* this is where the applicaton starts */
 extern void app_main(void);