* in progress *
authorEleni Maria Stea <elene.mst@gmail.com>
Tue, 19 Feb 2013 23:44:03 +0000 (01:44 +0200)
committerEleni Maria Stea <elene.mst@gmail.com>
Tue, 19 Feb 2013 23:44:03 +0000 (01:44 +0200)
added blit and blit_key functions to the graphics code
added mouse cursor drawing

src/gfx.cc
src/gfx.h
src/mouse.cc
src/mouse_cursor.h [new file with mode: 0644]
src/pixmap.cc [new file with mode: 0644]
src/pixmap.h [new file with mode: 0644]
src/window.cc
src/wm.cc
src/wm.h

index 226d269..5c04d1e 100644 (file)
@@ -113,17 +113,97 @@ void set_cursor_visibility(bool visible)
        }
 }
 
-void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img, int dest_x, int dest_y)
+void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+               const Rect &dest_rect, int dest_x, int dest_y)
 {
-       Rect dest_rect;
+       int width = src_rect.width;
+       int height = src_rect.height;
 
-       if(dest_x < screen_rect.x) {
-               dest_rect.x = screen_rect.x;
+       int xoffs = dest_x - dest_rect.x;
+       if(xoffs < 0) {
+               dest_x = dest_rect.x;
+               width += xoffs;
        }
 
-       if(dest_y < screen_rect.y) {
-               dest_rect.y = screen_rect.y;
+       int yoffs = dest_y - dest_rect.y;
+       if(yoffs < 0) {
+               dest_y = dest_rect.y;
+               height += yoffs;
        }
 
-       //TODO :p zzz
+       int xend = dest_x + width;
+       if(xend >= dest_rect.width) {
+               width -= xend - dest_rect.width;
+       }
+
+       int yend = dest_y + height;
+       if(yend >= dest_rect.height) {
+               height -= yend - dest_rect.height;
+       }
+
+       if(width <= 0 || height <= 0) {
+               return;
+       }
+
+       unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4;
+       unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
+
+       for(int i=0; i<height; i++) {
+               memcpy(dptr, sptr, width * 4);
+               sptr += src_rect.width * 4;
+               dptr += dest_rect.width * 4;
+       }
+}
+
+void blit_key(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+               const Rect &dest_rect, int dest_x, int dest_y, int key_r, int key_g, int key_b)
+{
+       int width = src_rect.width;
+       int height = src_rect.height;
+
+       int xoffs = dest_x - dest_rect.x;
+       if(xoffs < 0) {
+               dest_x = dest_rect.x;
+               width += xoffs;
+       }
+
+       int yoffs = dest_y - dest_rect.y;
+       if(yoffs < 0) {
+               dest_y = dest_rect.y;
+               height += yoffs;
+       }
+
+       int xend = dest_x + width;
+       if(xend >= dest_rect.width) {
+               width -= xend - dest_rect.width;
+       }
+
+       int yend = dest_y + height;
+       if(yend >= dest_rect.height) {
+               height -= yend - dest_rect.height;
+       }
+
+       if(width <= 0 || height <= 0) {
+               return;
+       }
+
+       unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4;
+       unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
+
+       for(int i=0; i<height; i++) {
+               for(int j=0; j<width; j++) {
+                       int r = sptr[j * 4];
+                       int g = sptr[j * 4 + 1];
+                       int b = sptr[j * 4 + 2];
+
+                       if(r != key_r || g != key_g || b != key_b) {
+                               dptr[j * 4] = r;
+                               dptr[j * 4 + 1] = g;
+                               dptr[j * 4 + 2] = b;
+                       }
+               }
+
+               sptr += src_rect.width * 4;
+               dptr += dest_rect.width * 4;
+       }
 }
index e03be2a..623e2e2 100644 (file)
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -15,6 +15,10 @@ void fill_rect(const Rect &rect, int r, int g, int b);
 
 void set_cursor_visibility(bool visible);
 
-void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img, int dest_x, int dest_y);
+void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+               const Rect &dest_rect, int dest_x, int dest_y);
+
+void blit_key(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+               const Rect &dest_rect, int dest_x, int dest_y, int key_r, int key_g, int key_b);
 
 #endif //GFX_H_
index 861b597..1fed5d1 100644 (file)
@@ -69,11 +69,11 @@ void process_mouse_event()
                return;
        }
 
-       unsigned char *fb = get_framebuffer();
+       /*unsigned char *fb = get_framebuffer();
        fb += (bounds.width * pointer_y + pointer_x) * 4;
        fb[0] = 0;
        fb[1] = 0;
-       fb[2] = 0;
+       fb[2] = 0;*/
 
        //printf("pointer (x, y) = (%d, %d)\r\n", pointer_x, pointer_y);
 
diff --git a/src/mouse_cursor.h b/src/mouse_cursor.h
new file mode 100644 (file)
index 0000000..af9e3ce
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef MOUSE_CURSOR_H_
+#define MOUSE_CURSOR_H_
+
+const int mouse_cursor_width = 8;
+const int mouse_cursor_height = 16;
+
+const int mouse_cursor_bw[] = {
+       128, 128,   0,   0,   0,   0,   0,   0,
+       128, 255, 128,   0,   0,   0,   0,   0,
+       128, 255, 255, 128,   0,   0,   0,   0,
+       128, 255, 255, 255, 128,   0,   0,   0,
+       128, 255, 255, 255, 255, 128,   0,   0,
+       128, 255, 255, 255, 255, 255, 128,   0,
+       128, 255, 255, 255, 255, 255, 255, 128,
+       128, 255, 255, 255, 255, 255, 128,   0,
+       128, 255, 255, 255, 255, 128,   0,   0,
+       128, 255, 255, 255, 255, 128,   0,   0,
+       128, 255, 255, 255, 255, 255, 128,   0,
+       128, 255, 255, 255, 255, 255, 128,   0,
+       128, 255, 128, 128, 255, 255, 255, 128,
+       128, 128,   0, 128, 255, 255, 255, 128,
+       128,   0,   0,   0, 128, 255, 255, 128,
+         0,   0,   0,   0,   0, 128, 128, 128
+};
+
+
+
+#endif // MOUSE_CURSOR_H_
diff --git a/src/pixmap.cc b/src/pixmap.cc
new file mode 100644 (file)
index 0000000..5c9b242
--- /dev/null
@@ -0,0 +1,86 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "pixmap.h"
+
+Pixmap::Pixmap()
+{
+       width = height = 0;
+       pixels = 0;
+}
+
+Pixmap::~Pixmap()
+{
+       if(pixels) {
+               delete [] pixels;
+       }
+}
+
+int Pixmap::get_width() const
+{
+       return width;
+}
+
+int Pixmap::get_height() const
+{
+       return height;
+}
+
+Rect Pixmap::get_rect() const
+{
+       Rect rect = {0, 0, width, height};
+       return rect;
+}
+
+bool Pixmap::set_image(int x, int y, unsigned char *pix)
+{
+       delete [] pixels;
+
+       pixels = new unsigned char[x * y * 4];
+       width = x;
+       height = y;
+
+       if(pix) {
+               memcpy(pixels, pix, x * y * 4);
+       }
+       return true;
+}
+
+const unsigned char *Pixmap::get_image() const
+{
+       return pixels;
+}
+
+unsigned char *Pixmap::get_image()
+{
+       return pixels;
+}
+
+bool Pixmap::load(const char *fname)
+{
+       return false;   // TODO
+}
+
+bool Pixmap::save(const char *fname) const
+{
+       if(!pixels) {
+               return false;
+       }
+
+       FILE *fp = fopen(fname, "wb");
+       if(!fp) {
+               fprintf(stderr, "failed to save pixmap: %s: %s\n", fname, strerror(errno));
+               return false;
+       }
+
+       fprintf(fp, "P6\n%d %d\n255\n", width, height);
+
+       for(int i=0; i<width * height; i++) {
+               fputc(pixels[i * 4], fp);
+               fputc(pixels[i * 4 + 1], fp);
+               fputc(pixels[i * 4 + 2], fp);
+       }
+
+       fclose(fp);
+       return true;
+}
diff --git a/src/pixmap.h b/src/pixmap.h
new file mode 100644 (file)
index 0000000..02a848b
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef PIXMAP_H_
+#define PIXMAP_H_
+
+#include "geom.h"
+
+class Pixmap {
+private:
+       int width, height;
+       unsigned char *pixels;
+
+public:
+       Pixmap();
+       ~Pixmap();
+
+       int get_width() const;
+       int get_height() const;
+       Rect get_rect() const;
+
+       bool set_image(int x, int y, unsigned char *pix = 0);
+       const unsigned char *get_image() const;
+       unsigned char *get_image();
+
+       bool load(const char *fname);
+       bool save(const char *fname) const;
+};
+
+#endif // PIXMAP_H_
index 84d1004..608d93b 100644 (file)
@@ -24,13 +24,8 @@ const Rect &Window::get_rect() const
 
 bool Window::contains_point(int ptr_x, int ptr_y)
 {
-       if((rect.x <= ptr_x) && ((rect.x + rect.width) >= ptr_x)) {
-               if((rect.y <= ptr_y) && (ptr_y <= (rect.y + rect.height))) {
-                       return true;
-               }
-       }
-
-       return false;
+       return ptr_x >= rect.x && ptr_x < rect.x + rect.width &&
+                       ptr_y >= rect.y && ptr_y < rect.y + rect.height;
 }
 
 void Window::move(int x, int y)
index f65c9c2..b661234 100644 (file)
--- a/src/wm.cc
+++ b/src/wm.cc
@@ -2,6 +2,8 @@
 #include "gfx.h"
 #include "wm.h"
 #include "window.h"
+#include "mouse.h"
+#include "mouse_cursor.h"
 
 WindowManager *wm;
 static WindowManager wminst;
@@ -19,6 +21,19 @@ WindowManager::WindowManager()
        bg_color[0] = 210;
        bg_color[1] = 106;
        bg_color[2] = 106;
+
+       mouse_cursor.set_image(mouse_cursor_width, mouse_cursor_height);
+       unsigned char *pixels = mouse_cursor.get_image();
+
+       for(int i=0; i<mouse_cursor_height; i++) {
+               for(int j=0; j<mouse_cursor_width; j++) {
+                       int val = mouse_cursor_bw[i * mouse_cursor_width + j];
+                       *pixels++ = val;
+                       *pixels++ = val;
+                       *pixels++ = val;
+                       *pixels++ = 255;
+               }
+       }
 }
 
 void WindowManager::invalidate_region(const Rect &rect)
@@ -49,6 +64,17 @@ void WindowManager::process_windows()
                }
                it++;
        }
+
+       // draw mouse cursor
+       int mouse_x, mouse_y;
+       get_pointer_pos(&mouse_x, &mouse_y);
+
+       blit_key(mouse_cursor.get_image(), mouse_cursor.get_rect(),
+                       get_framebuffer(), get_screen_size(), mouse_x, mouse_y,
+                       0, 0, 0);
+
+       Rect mouse_rect = {mouse_x, mouse_y, mouse_cursor.get_width(), mouse_cursor.get_height()};
+       invalidate_region(mouse_rect);
 }
 
 void WindowManager::add_window(Window *win)
index fc10953..e3f4040 100644 (file)
--- a/src/wm.h
+++ b/src/wm.h
@@ -3,6 +3,7 @@
 
 #include <list>
 #include "geom.h"
+#include "pixmap.h"
 
 class Window;
 
@@ -14,6 +15,8 @@ private:
        int bg_color[3];
        Window *focused_win;
 
+       Pixmap mouse_cursor;
+
 public:
        WindowManager();