added SDL backend for easier testing
authorEleni Maria Stea <elene.mst@gmail.com>
Fri, 22 Feb 2013 23:22:10 +0000 (01:22 +0200)
committerEleni Maria Stea <elene.mst@gmail.com>
Fri, 22 Feb 2013 23:22:10 +0000 (01:22 +0200)
19 files changed:
Makefile
src/event.cc [deleted file]
src/fbdev/event.cc [new file with mode: 0644]
src/fbdev/gfx.cc [new file with mode: 0644]
src/fbdev/keyboard.cc [new file with mode: 0644]
src/fbdev/mouse.cc [new file with mode: 0644]
src/gfx.cc [deleted file]
src/gfx.h
src/keyboard.cc [deleted file]
src/main.cc
src/mouse.cc [deleted file]
src/mouse.h
src/sdl/event.cc [new file with mode: 0644]
src/sdl/gfx.cc [new file with mode: 0644]
src/sdl/keyboard.cc [new file with mode: 0644]
src/sdl/mouse.cc [new file with mode: 0644]
src/window.cc
src/window.h
src/wm.cc

index c6b749a..a894e52 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,24 @@
-src = $(wildcard src/*.cc)
+src = $(wildcard src/*.cc) $(wildcard src/fbdev/*.cc) $(wildcard src/sdl/*.cc)
 obj = $(src:.cc=.o)
 dep = $(obj:.o=.d)
 bin = winnie
 
-
 dbg = -g
 opt = -O0
-#inc =
+inc = -Isrc
+
+backend = SDL
+
+ifeq ($(backend), SDL)
+       def = -DWINNIE_SDL
+       libs = -lSDL
+else
+       def = -DWINNIE_FBDEV
+endif
 
 CXX = g++
-CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc)
-#LDFLAGS = 
+CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc) $(def)
+LDFLAGS = $(libs)
 
 $(bin): $(obj)
        $(CXX) -o $@ $(obj) $(LDFLAGS)
diff --git a/src/event.cc b/src/event.cc
deleted file mode 100644 (file)
index a54fe7a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <stdio.h>
-
-#include <errno.h>
-#include <unistd.h>
-#include <sys/select.h>
-
-#include "event.h"
-#include "wm.h"
-#include "keyboard.h"
-#include "mouse.h"
-
-void process_events()
-{
-       int keyb_fd = get_keyboard_fd();
-       int mouse_fd = get_mouse_fd();
-
-       for(;;) {
-               wm->process_windows();
-
-               fd_set read_set;
-
-               FD_ZERO(&read_set);
-               FD_SET(keyb_fd, &read_set);
-               FD_SET(mouse_fd, &read_set);
-
-               int maxfd = keyb_fd > mouse_fd ? keyb_fd : mouse_fd;
-
-               while(select(maxfd + 1, &read_set, 0, 0, 0) == -1 && errno == EINTR);
-
-               if(FD_ISSET(keyb_fd, &read_set)) {
-                       process_keyboard_event();
-               }
-               if(FD_ISSET(mouse_fd, &read_set)) {
-                       process_mouse_event();
-               }
-       }
-}
diff --git a/src/fbdev/event.cc b/src/fbdev/event.cc
new file mode 100644 (file)
index 0000000..611ec3c
--- /dev/null
@@ -0,0 +1,39 @@
+#ifdef WINNIE_FBDEV
+#include <stdio.h>
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/select.h>
+
+#include "event.h"
+#include "wm.h"
+#include "keyboard.h"
+#include "mouse.h"
+
+void process_events()
+{
+       int keyb_fd = get_keyboard_fd();
+       int mouse_fd = get_mouse_fd();
+
+       for(;;) {
+               wm->process_windows();
+
+               fd_set read_set;
+
+               FD_ZERO(&read_set);
+               FD_SET(keyb_fd, &read_set);
+               FD_SET(mouse_fd, &read_set);
+
+               int maxfd = keyb_fd > mouse_fd ? keyb_fd : mouse_fd;
+
+               while(select(maxfd + 1, &read_set, 0, 0, 0) == -1 && errno == EINTR);
+
+               if(FD_ISSET(keyb_fd, &read_set)) {
+                       process_keyboard_event();
+               }
+               if(FD_ISSET(mouse_fd, &read_set)) {
+                       process_mouse_event();
+               }
+       }
+}
+#endif // WINNIE_FBDEV
diff --git a/src/fbdev/gfx.cc b/src/fbdev/gfx.cc
new file mode 100644 (file)
index 0000000..00e1881
--- /dev/null
@@ -0,0 +1,226 @@
+#ifdef WINNIE_FBDEV
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <linux/fb.h>
+
+#include "gfx.h"
+
+#define FRAMEBUFFER_SIZE(xsz, ysz, bpp) ((xsz) * (ysz) * (bpp) / CHAR_BIT)
+
+static unsigned char *framebuffer;
+static int dev_fd = -1;
+
+static Rect screen_rect;
+static int color_depth; // bits per pixel
+
+bool init_gfx()
+{
+       if((dev_fd = open("/dev/fb0", O_RDWR)) == -1) {
+               fprintf(stderr, "Cannot open /dev/fb0 : %s\n", strerror(errno));
+               return false;
+       }
+
+       fb_var_screeninfo sinfo;
+       if(ioctl(dev_fd, FBIOGET_VSCREENINFO, &sinfo) == -1) {
+               close(dev_fd);
+               dev_fd = -1;
+               fprintf(stderr, "Unable to get screen info : %s\n", strerror(errno));
+               return false;
+       }
+
+       printf("width : %d height : %d\n : bpp : %d\n", sinfo.xres, sinfo.yres, sinfo.bits_per_pixel);
+       printf("virtual w: %d virtual h: %d\n", sinfo.xres_virtual, sinfo.yres_virtual);
+
+       screen_rect.x = screen_rect.y = 0;
+       screen_rect.width = sinfo.xres_virtual;
+       screen_rect.height = sinfo.yres_virtual;
+       color_depth = sinfo.bits_per_pixel;
+
+       int sz = FRAMEBUFFER_SIZE(screen_rect.width, screen_rect.height, color_depth);
+       framebuffer = (unsigned char*)mmap(0, sz, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0);
+
+       if(framebuffer == (void*)-1) {
+               close(dev_fd);
+               dev_fd = -1;
+               fprintf(stderr, "Cannot map the framebuffer to memory : %s\n", strerror(errno));
+               return false;
+       }
+
+       return true;
+}
+
+void destroy_gfx()
+{
+       clear_screen(0, 0, 0);
+
+       if(dev_fd != -1) {
+               close(dev_fd);
+       }
+
+       dev_fd = -1;
+
+       munmap(framebuffer, FRAMEBUFFER_SIZE(screen_rect.width, screen_rect.height, color_depth));
+       framebuffer = 0;
+}
+
+unsigned char *get_framebuffer()
+{
+       return framebuffer;
+}
+
+Rect get_screen_size()
+{
+       return screen_rect;
+}
+
+int get_color_depth()
+{
+       return color_depth;
+}
+
+void clear_screen(int r, int g, int b)
+{
+       fill_rect(screen_rect, r, g, b);
+}
+
+void fill_rect(const Rect &rect, int r, int g, int b)
+{
+       Rect drect = rect;
+
+       if(drect.x < 0) {
+               drect.x = 0;
+       }
+
+       if(drect.y < 0) {
+               drect.y = 0;
+       }
+
+       unsigned char *fb = framebuffer + (drect.x + screen_rect.width * drect.y) * 4;
+       for(int i=0; i<drect.height; i++) {
+               for(int j=0; j<drect.width; j++) {
+                       fb[j * 4] = b;
+                       fb[j * 4 + 1] = g;
+                       fb[j * 4 + 2] = r;
+               }
+               fb += screen_rect.width * 4;
+       }
+}
+
+void set_cursor_visibility(bool visible)
+{
+       fb_cursor curs;
+       curs.enable = visible ? 1 : 0;
+
+       if(ioctl(dev_fd, FBIO_CURSOR, &curs) == -1) {
+               fprintf(stderr, "Cannot toggle cursor visibility : %s\n", strerror(errno));
+       }
+}
+
+void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+               const Rect &dest_rect, int dest_x, int dest_y)
+{
+       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++) {
+               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] = b;
+                               dptr[j * 4 + 1] = g;
+                               dptr[j * 4 + 2] = r;
+                       }
+               }
+
+               sptr += src_rect.width * 4;
+               dptr += dest_rect.width * 4;
+       }
+}
+
+void gfx_update()
+{
+}
+
+#endif // WINNIE_FBDEV
diff --git a/src/fbdev/keyboard.cc b/src/fbdev/keyboard.cc
new file mode 100644 (file)
index 0000000..77f0bdd
--- /dev/null
@@ -0,0 +1,102 @@
+#ifdef WINNIE_FBDEV
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "keyboard.h"
+#include "window.h"
+#include "wm.h"
+
+static int dev_fd = -1;
+static enum {RAW, CANONICAL} ttystate = CANONICAL;
+
+bool init_keyboard()
+{
+       if((dev_fd = open("/dev/tty", O_RDWR)) == -1) {
+               fprintf(stderr, "Cannot open /dev/tty : %s\n", strerror(errno));
+               return false;
+       }
+
+       struct termios buf;
+
+       if(tcgetattr(dev_fd, &buf) < 0) {
+               fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno));
+               return false;
+       }
+
+       buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+       buf.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+       buf.c_cflag &= ~(CSIZE | PARENB);
+       buf.c_cflag |= CS8;
+       buf.c_oflag &= ~(OPOST);
+
+       if(tcsetattr(dev_fd, TCSAFLUSH, &buf) < 0) {
+               return false;
+       }
+
+       ttystate = RAW;
+       return true;
+}
+
+void destroy_keyboard()
+{
+       struct termios buf;
+
+       if(tcgetattr(dev_fd, &buf) < 0) {
+               fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno));
+       }
+
+       buf.c_lflag |= (ECHO | ICANON | IEXTEN | ISIG);
+       buf.c_iflag |= (BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+       buf.c_cflag |= (CSIZE | PARENB);
+       buf.c_cflag &= CS8;
+       buf.c_oflag |= (OPOST);
+
+       if(tcsetattr(dev_fd, TCSAFLUSH, &buf) < 0) {
+               fprintf(stderr, "Cannot set the tty parameters : %s\n", strerror(errno));
+       }
+
+       ttystate = CANONICAL;
+
+       if(dev_fd != -1) {
+               close(dev_fd);
+               dev_fd = -1;
+       }
+}
+
+int get_keyboard_fd()
+{
+       return dev_fd;
+}
+
+void process_keyboard_event()
+{
+       char key;
+       if(read(dev_fd, &key, 1) < 1) {
+               return;
+       }
+
+       if(key == 'q') {
+               exit(0);
+       }
+
+       Window *focused_win = wm->get_focused_window();
+       if(focused_win) {
+               KeyboardFuncType keyb_callback = focused_win->get_keyboard_callback();
+               if(keyb_callback) {
+                       keyb_callback(focused_win, key, true); //TODO: true??
+               }
+       }
+
+       /* TODO:
+        * - handle system-wide key combinations (alt-tab?)
+        * - otherwise send keypress/release to focused window
+        */
+}
+#endif // WINNIE_FBDEV
diff --git a/src/fbdev/mouse.cc b/src/fbdev/mouse.cc
new file mode 100644 (file)
index 0000000..5fd080b
--- /dev/null
@@ -0,0 +1,161 @@
+#ifdef WINNIE_FBDEV
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "geom.h"
+#include "gfx.h"
+#include "mouse.h"
+#include "window.h"
+#include "wm.h"
+
+#define BN_LEFT                1
+#define BN_RIGHT       2
+#define BN_MIDDLE      4
+
+static int read_mouse();
+
+static int dev_fd = -1;        // file descriptor for /dev/psaux
+static Rect bounds;
+static int pointer_x, pointer_y;
+static int bnstate;
+
+bool init_mouse()
+{
+       if((dev_fd = open("/dev/psaux", O_RDONLY | O_NONBLOCK)) == -1) {
+               fprintf(stderr, "Cannot open /dev/psaux : %s\n", strerror(errno));
+               return false;
+       }
+
+       set_mouse_bounds(get_screen_size());
+       return true;
+}
+
+void destroy_mouse()
+{
+       if(dev_fd != -1) {
+               close(dev_fd);
+               dev_fd = -1;
+       }
+}
+
+void set_mouse_bounds(const Rect &rect)
+{
+       bounds = rect;
+}
+
+int get_mouse_fd()
+{
+       return dev_fd;
+}
+
+void process_mouse_event()
+{
+       /* TODO:
+        * - read all pending events from mouse fd (use O_NONBLOCK so that
+        *   read will return -1 when there are no more events instead of blocking).
+        */
+
+       int prev_state = bnstate;
+       int prev_x = pointer_x;
+       int prev_y = pointer_y;
+
+       if(read_mouse() == -1) {
+               return;
+       }
+
+       Window *top = wm->get_window_at_pos(pointer_x, pointer_y);
+       if(top) {
+               wm->set_focused_window(top);
+       }
+       else {
+               wm->set_focused_window(0);
+       }
+
+        /* - send each pointer move and button press/release to the topmost window
+        *   with the pointer on it.
+        */
+
+       int dx = pointer_x - prev_x;
+       int dy = pointer_y - prev_y;
+
+       if((dx || dy) && top) {
+               MouseMotionFuncType motion_callback = top->get_mouse_motion_callback();
+               if(motion_callback) {
+                       Rect rect = top->get_absolute_rect();
+                       motion_callback(top, pointer_x - rect.x, pointer_y - rect.y);
+               }
+       }
+
+       MouseButtonFuncType button_callback;
+       if((bnstate != prev_state) && top && (button_callback = top->get_mouse_button_callback())) {
+               int num_bits = sizeof bnstate * CHAR_BIT;
+               for(int i=0; i<num_bits; i++) {
+                       int s = (bnstate >> i) & 1;
+                       int prev_s = (prev_state >> i) & 1;
+                       if(s != prev_s) {
+                               button_callback(top, i, s);
+                       }
+               }
+       }
+}
+
+void get_pointer_pos(int *x, int *y)
+{
+       *x = pointer_x;
+       *y = pointer_y;
+}
+
+int get_button_state()
+{
+       return bnstate;
+}
+
+int get_button(int bn)
+{
+       if(bn < 0 || bn >= 3) {
+               return 0;
+       }
+       return (bnstate & (1 << bn)) != 0;
+}
+
+static int read_mouse()
+{
+       int rd;
+       signed char state[3] = {0, 0, 0};
+
+       if((rd = read(dev_fd, state, 3)) == -1) {
+               fprintf(stderr, "Unable to get mouse state : %s\n", strerror(errno));
+               return -1;
+       }
+
+       bnstate = state[0] & 7;
+       pointer_x += state[1];
+       pointer_y -= state[2];
+
+       if(pointer_x < bounds.x) {
+               pointer_x = bounds.x;
+       }
+
+       if(pointer_y < bounds.y) {
+               pointer_y = bounds.y;
+       }
+
+       if(pointer_x > bounds.x + bounds.width - 1) {
+               pointer_x = bounds.x + bounds.width - 1;
+       }
+
+       if(pointer_y > bounds.y + bounds.height - 1) {
+               pointer_y = bounds.y + bounds.height - 1;
+       }
+
+       return 0;
+}
+#endif // WINNIE_FBDEV
diff --git a/src/gfx.cc b/src/gfx.cc
deleted file mode 100644 (file)
index 7d3595c..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include <linux/fb.h>
-
-#include "gfx.h"
-
-#define FRAMEBUFFER_SIZE(xsz, ysz, bpp) ((xsz) * (ysz) * (bpp) / CHAR_BIT)
-
-static unsigned char *framebuffer;
-static int dev_fd = -1;
-
-static Rect screen_rect;
-static int color_depth; //bits per pixel
-
-bool init_gfx()
-{
-       if((dev_fd = open("/dev/fb0", O_RDWR)) == -1) {
-               fprintf(stderr, "Cannot open /dev/fb0 : %s\n", strerror(errno));
-               return false;
-       }
-
-       fb_var_screeninfo sinfo;
-       if(ioctl(dev_fd, FBIOGET_VSCREENINFO, &sinfo) == -1) {
-               close(dev_fd);
-               dev_fd = -1;
-               fprintf(stderr, "Unable to get screen info : %s\n", strerror(errno));
-               return false;
-       }
-
-       printf("width : %d height : %d\n : bpp : %d\n", sinfo.xres, sinfo.yres, sinfo.bits_per_pixel);
-       printf("virtual w: %d virtual h: %d\n", sinfo.xres_virtual, sinfo.yres_virtual);
-
-       screen_rect.x = screen_rect.y = 0;
-       screen_rect.width = sinfo.xres_virtual;
-       screen_rect.height = sinfo.yres_virtual;
-       color_depth = sinfo.bits_per_pixel;
-
-       int sz = FRAMEBUFFER_SIZE(screen_rect.width, screen_rect.height, color_depth);
-       framebuffer = (unsigned char*)mmap(0, sz, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0);
-
-       if(framebuffer == (void*)-1) {
-               close(dev_fd);
-               dev_fd = -1;
-               fprintf(stderr, "Cannot map the framebuffer to memory : %s\n", strerror(errno));
-               return false;
-       }
-
-       return true;
-}
-
-void destroy_gfx()
-{
-       clear_screen(0, 0, 0);
-
-       if(dev_fd != -1) {
-               close(dev_fd);
-       }
-
-       dev_fd = -1;
-
-       munmap(framebuffer, FRAMEBUFFER_SIZE(screen_rect.width, screen_rect.height, color_depth));
-       framebuffer = 0;
-}
-
-unsigned char *get_framebuffer()
-{
-       return framebuffer;
-}
-
-Rect get_screen_size()
-{
-       return screen_rect;
-}
-
-int get_color_depth()
-{
-       return color_depth;
-}
-
-void clear_screen(int r, int g, int b)
-{
-       fill_rect(screen_rect, r, g, b);
-}
-
-void fill_rect(const Rect &rect, int r, int g, int b)
-{
-       Rect drect = rect;
-
-       if(drect.x < 0) {
-               drect.x = 0;
-       }
-
-       if(drect.y < 0) {
-               drect.y = 0;
-       }
-
-       unsigned char *fb = framebuffer + (drect.x + screen_rect.width * drect.y) * 4;
-       for(int i=0; i<drect.height; i++) {
-               for(int j=0; j<drect.width; j++) {
-                       fb[j * 4] = b;
-                       fb[j * 4 + 1] = g;
-                       fb[j * 4 + 2] = r;
-               }
-               fb += screen_rect.width * 4;
-       }
-}
-
-void set_cursor_visibility(bool visible)
-{
-       fb_cursor curs;
-       curs.enable = visible ? 1 : 0;
-
-       if(ioctl(dev_fd, FBIO_CURSOR, &curs) == -1) {
-               fprintf(stderr, "Cannot toggle cursor visibility : %s\n", strerror(errno));
-       }
-}
-
-void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
-               const Rect &dest_rect, int dest_x, int dest_y)
-{
-       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++) {
-               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 623e2e2..c866d78 100644 (file)
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -21,4 +21,6 @@ void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
 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);
 
+void gfx_update();
+
 #endif //GFX_H_
diff --git a/src/keyboard.cc b/src/keyboard.cc
deleted file mode 100644 (file)
index 1b23e12..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "keyboard.h"
-#include "window.h"
-#include "wm.h"
-
-static int dev_fd = -1;
-static enum {RAW, CANONICAL} ttystate = CANONICAL;
-
-bool init_keyboard()
-{
-       if((dev_fd = open("/dev/tty", O_RDWR)) == -1) {
-               fprintf(stderr, "Cannot open /dev/tty : %s\n", strerror(errno));
-               return false;
-       }
-
-       struct termios buf;
-
-       if(tcgetattr(dev_fd, &buf) < 0) {
-               fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno));
-               return false;
-       }
-
-       buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
-       buf.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
-       buf.c_cflag &= ~(CSIZE | PARENB);
-       buf.c_cflag |= CS8;
-       buf.c_oflag &= ~(OPOST);
-
-       if(tcsetattr(dev_fd, TCSAFLUSH, &buf) < 0) {
-               return false;
-       }
-
-       ttystate = RAW;
-       return true;
-}
-
-void destroy_keyboard()
-{
-       struct termios buf;
-
-       if(tcgetattr(dev_fd, &buf) < 0) {
-               fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno));
-       }
-
-       buf.c_lflag |= (ECHO | ICANON | IEXTEN | ISIG);
-       buf.c_iflag |= (BRKINT | ICRNL | INPCK | ISTRIP | IXON);
-       buf.c_cflag |= (CSIZE | PARENB);
-       buf.c_cflag &= CS8;
-       buf.c_oflag |= (OPOST);
-
-       if(tcsetattr(dev_fd, TCSAFLUSH, &buf) < 0) {
-               fprintf(stderr, "Cannot set the tty parameters : %s\n", strerror(errno));
-       }
-
-       ttystate = CANONICAL;
-
-       if(dev_fd != -1) {
-               close(dev_fd);
-               dev_fd = -1;
-       }
-}
-
-int get_keyboard_fd()
-{
-       return dev_fd;
-}
-
-void process_keyboard_event()
-{
-       char key;
-       if(read(dev_fd, &key, 1) < 1) {
-               return;
-       }
-
-       if(key == 'q') {
-               exit(0);
-       }
-
-       Window *focused_win = wm->get_focused_window();
-       if(focused_win) {
-               KeyboardFuncType keyb_callback = focused_win->get_keyboard_callback();
-               if(keyb_callback) {
-                       keyb_callback(focused_win, key, true);
-               }
-       }
-
-       /* TODO:
-        * - handle system-wide key combinations (alt-tab?)
-        * - otherwise send keypress/release to focused window
-        */
-}
index 6697506..8b36449 100644 (file)
@@ -30,9 +30,11 @@ static void display(Window *win)
 {
        if(wm->get_focused_window() != win) {
                fill_rect(win->get_rect(), 106, 106, 250);
+               printf("drawing unfocused\n");
        }
        else {
                fill_rect(win->get_rect(), 0, 0, 255);
+               printf("drawing FOCUSED\n");
        }
 }
 
diff --git a/src/mouse.cc b/src/mouse.cc
deleted file mode 100644 (file)
index b3f329b..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "geom.h"
-#include "gfx.h"
-#include "mouse.h"
-#include "window.h"
-#include "wm.h"
-
-#define BN_LEFT                1
-#define BN_RIGHT       2
-#define BN_MIDDLE      4
-
-
-static int dev_fd = -1;        // file descriptor for /dev/psaux
-static Rect bounds;
-static int pointer_x, pointer_y;
-static int bnstate;
-
-bool init_mouse()
-{
-       if((dev_fd = open("/dev/psaux", O_RDONLY | O_NONBLOCK)) == -1) {
-               fprintf(stderr, "Cannot open /dev/psaux : %s\n", strerror(errno));
-               return false;
-       }
-
-       set_mouse_bounds(get_screen_size());
-       return true;
-}
-
-void destroy_mouse()
-{
-       if(dev_fd != -1) {
-               close(dev_fd);
-               dev_fd = -1;
-       }
-}
-
-void set_mouse_bounds(const Rect &rect)
-{
-       bounds = rect;
-}
-
-int get_mouse_fd()
-{
-       return dev_fd;
-}
-
-void process_mouse_event()
-{
-       /* TODO:
-        * - read all pending events from mouse fd (use O_NONBLOCK so that
-        *   read will return -1 when there are no more events instead of blocking).
-        */
-
-       int prev_state = bnstate;
-       int prev_x = pointer_x;
-       int prev_y = pointer_y;
-
-       if(read_mouse() == -1) {
-               return;
-       }
-
-       Window *top = wm->get_window_at_pos(pointer_x, pointer_y);
-       if(top) {
-               wm->set_focused_window(top);
-       }
-       else {
-               wm->set_focused_window(0);
-               return;
-       }
-
-        /* - send each pointer move and button press/release to the topmost window
-        *   with the pointer on it.
-        */
-
-       int dx = pointer_x - prev_x;
-       int dy = pointer_y - prev_y;
-
-       if(dx || dy) {
-               MouseMotionFuncType motion_callback = top->get_mouse_motion_callback();
-               if(motion_callback) {
-                       Rect rect = top->get_rect();
-                       motion_callback(top, pointer_x - rect.x, pointer_y - rect.y);
-               }
-       }
-
-       MouseButtonFuncType button_callback = top->get_mouse_button_callback();
-       if(button_callback && (bnstate != prev_state)) {
-               int num_bits = sizeof bnstate * CHAR_BIT;
-               for(int i=0; i<num_bits; i++) {
-                       int s = (bnstate >> i) & 1;
-                       int prev_s = (prev_state >> i) & 1;
-                       if(s != prev_s) {
-                               button_callback(top, i, s);
-                       }
-               }
-       }
-}
-
-void get_pointer_pos(int *x, int *y)
-{
-       *x = pointer_x;
-       *y = pointer_y;
-}
-
-int get_button_state(int bn)
-{
-       return bnstate;
-}
-
-int get_button(int bn)
-{
-       if(bn < 0 || bn >= 3) {
-               return 0;
-       }
-       return (bnstate & (1 << bn)) != 0;
-}
-
-
-int read_mouse()
-{
-       int rd;
-       signed char state[3] = {0, 0, 0};
-
-       if((rd = read(dev_fd, state, 3)) == -1) {
-               fprintf(stderr, "Unable to get mouse state : %s\n", strerror(errno));
-               return -1;
-       }
-
-       bnstate = state[0] & 7;
-       pointer_x += state[1];
-       pointer_y -= state[2];
-
-       if(pointer_x < bounds.x) {
-               pointer_x = bounds.x;
-       }
-
-       if(pointer_y < bounds.y) {
-               pointer_y = bounds.y;
-       }
-
-       if(pointer_x > bounds.x + bounds.width - 1) {
-               pointer_x = bounds.x + bounds.width - 1;
-       }
-
-       if(pointer_y > bounds.y + bounds.height - 1) {
-               pointer_y = bounds.y + bounds.height - 1;
-       }
-
-       return 0;
-}
index 271ee83..1770d7a 100644 (file)
@@ -12,9 +12,7 @@ int get_mouse_fd();
 void process_mouse_event();
 
 void get_pointer_pos(int *x, int *y);
-int get_button_state(int bn);
+int get_button_state();
 int get_button(int bn);
 
-int read_mouse();
-
 #endif // MOUSE_H_
diff --git a/src/sdl/event.cc b/src/sdl/event.cc
new file mode 100644 (file)
index 0000000..97c9b1e
--- /dev/null
@@ -0,0 +1,33 @@
+#ifdef WINNIE_SDL
+#include <stdlib.h>
+#include <SDL/SDL.h>
+
+#include "event.h"
+#include "keyboard.h"
+#include "mouse.h"
+#include "wm.h"
+
+SDL_Event sdl_event;
+void process_events()
+{
+       wm->process_windows();
+       if(!SDL_WaitEvent(&sdl_event)) {
+               return;
+       }
+
+       switch(sdl_event.type) {
+       case SDL_KEYDOWN:
+       case SDL_KEYUP:
+               process_keyboard_event();
+               break;
+       case SDL_MOUSEMOTION:
+       case SDL_MOUSEBUTTONDOWN:
+       case SDL_MOUSEBUTTONUP:
+               process_mouse_event();
+               break;
+       case SDL_QUIT:
+               exit(0);
+       }
+}
+
+#endif // WINNIE_SDL
diff --git a/src/sdl/gfx.cc b/src/sdl/gfx.cc
new file mode 100644 (file)
index 0000000..b757688
--- /dev/null
@@ -0,0 +1,170 @@
+#ifdef WINNIE_SDL
+#include <stdio.h>
+#include <stdlib.h>
+#include <SDL/SDL.h>
+#include "gfx.h"
+
+static SDL_Surface *fbsurf;
+
+static Rect screen_rect = {0, 0, 1024, 768};
+static int color_depth = 32; // bits per pixel
+
+bool init_gfx()
+{
+       if(SDL_Init(SDL_INIT_VIDEO) == -1) {
+               fprintf(stderr, "failed to initialize SDL\n");
+               return false;
+       }
+
+       if(!(fbsurf = SDL_SetVideoMode(screen_rect.width, screen_rect.height, color_depth, 0))) {
+               fprintf(stderr, "failed to set video mode\n");
+               return false;
+       }
+       SDL_ShowCursor(0);
+
+       return true;
+}
+
+void destroy_gfx()
+{
+       SDL_Quit();
+}
+
+unsigned char *get_framebuffer()
+{
+       return (unsigned char*)fbsurf->pixels;
+}
+
+Rect get_screen_size()
+{
+       return screen_rect;
+}
+
+int get_color_depth()
+{
+       return color_depth;
+}
+
+void clear_screen(int r, int g, int b)
+{
+       fill_rect(screen_rect, r, g, b);
+}
+
+void fill_rect(const Rect &rect, int r, int g, int b)
+{
+       uint32_t color = ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
+       
+       SDL_Rect sdl_rect;
+       sdl_rect.x = rect.x;
+       sdl_rect.y = rect.y;
+       sdl_rect.w = rect.width;
+       sdl_rect.h = rect.height;
+
+       SDL_FillRect(fbsurf, &sdl_rect, color);
+}
+
+void set_cursor_visibility(bool visible)
+{
+}
+
+void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+               const Rect &dest_rect, int dest_x, int dest_y)
+{
+       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++) {
+               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;
+       }
+}
+
+void gfx_update()
+{
+       SDL_UpdateRect(fbsurf, 0, 0, 0, 0);
+}
+
+#endif // WINNIE_SDL
diff --git a/src/sdl/keyboard.cc b/src/sdl/keyboard.cc
new file mode 100644 (file)
index 0000000..d7f549d
--- /dev/null
@@ -0,0 +1,37 @@
+#ifdef WINNIE_SDL
+#include <SDL/SDL.h>
+
+#include "keyboard.h"
+#include "window.h"
+#include "wm.h"
+
+extern SDL_Event sdl_event;
+
+bool init_keyboard()
+{
+       return true;
+}
+
+void destroy_keyboard()
+{
+}
+
+int get_keyboard_fd()
+{
+       return -1;
+}
+
+void process_keyboard_event()
+{
+       int key = sdl_event.key.keysym.sym;
+
+       Window *focused_win = wm->get_focused_window();
+       if(focused_win) {
+               KeyboardFuncType keyb_callback = focused_win->get_keyboard_callback();
+               if(keyb_callback) {
+                       bool pressed = sdl_event.key.state == SDL_PRESSED;
+                       keyb_callback(focused_win, key, pressed);
+               }
+       }
+}
+#endif // WINNIE_SDL
diff --git a/src/sdl/mouse.cc b/src/sdl/mouse.cc
new file mode 100644 (file)
index 0000000..5531707
--- /dev/null
@@ -0,0 +1,89 @@
+#ifdef WINNIE_SDL
+#include <SDL/SDL.h>
+
+#include "mouse.h"
+#include "window.h"
+#include "wm.h"
+
+extern SDL_Event sdl_event;
+
+static int pointer_x, pointer_y;
+static int bnstate;
+
+bool init_mouse()
+{
+       return true;
+}
+
+void destroy_mouse()
+{
+}
+
+void set_mouse_bounds(const Rect &rect)
+{
+}
+
+int get_mouse_fd()
+{
+       return -1;
+}
+
+void process_mouse_event()
+{
+       int bn;
+       MouseMotionFuncType motion_callback = 0;
+       MouseButtonFuncType button_callback = 0;
+
+       Window *top = wm->get_window_at_pos(pointer_x, pointer_y);
+
+       if(top) {
+               wm->set_focused_window(top);
+       }
+       else {
+               wm->set_focused_window(0);
+       }
+
+       switch(sdl_event.type) {
+       case SDL_MOUSEMOTION:
+               pointer_x = sdl_event.motion.x;
+               pointer_y = sdl_event.motion.y;
+               if(top && (motion_callback = top->get_mouse_motion_callback())) {
+                       Rect rect = top->get_absolute_rect();
+                       motion_callback(top, pointer_x - rect.x, pointer_y - rect.y);
+               }
+               break;
+
+       case SDL_MOUSEBUTTONUP:
+       case SDL_MOUSEBUTTONDOWN:
+               bn = sdl_event.button.button - SDL_BUTTON_LEFT;
+               if(sdl_event.button.state == SDL_PRESSED) {
+                       bnstate |= 1 << bn;
+               }
+               else {
+                       bnstate &= ~(1 << bn);
+               }
+               if(top && (button_callback = top->get_mouse_button_callback())) {
+                       button_callback(top, bn, sdl_event.button.state);
+               }
+       }
+}
+
+void get_pointer_pos(int *x, int *y)
+{
+       *x = pointer_x;
+       *y = pointer_y;
+}
+
+int get_button_state()
+{
+       return bnstate;
+}
+
+int get_button(int bn)
+{
+       if(bn < 0 || bn >= 3) {
+               return 0;
+       }
+       return (bnstate & (1 << bn)) != 0;
+}
+#endif // WINNIE_SDL
index 2a8b6f5..46528b7 100644 (file)
@@ -7,6 +7,7 @@
 
 Window::Window()
 {
+       parent = 0;
        title = 0;
        rect.x = rect.y = 0;
        rect.width = rect.height = 128;
@@ -31,6 +32,11 @@ const Rect &Window::get_rect() const
        return rect;
 }
 
+const Rect &Window::get_absolute_rect() const
+{
+       return rect;    // TODO implement absolute rectangle thingy
+}
+
 bool Window::contains_point(int ptr_x, int ptr_y)
 {
        return ptr_x >= rect.x && ptr_x < rect.x + rect.width &&
index 1eebed0..3db8ec8 100644 (file)
@@ -24,6 +24,7 @@ public:
        ~Window();
 
        const Rect &get_rect() const;
+       const Rect &get_absolute_rect() const;
        bool contains_point(int ptr_x, int ptr_y);
 
        void move(int x, int y);
index 6577a67..89b709f 100644 (file)
--- a/src/wm.cc
+++ b/src/wm.cc
@@ -130,6 +130,8 @@ void WindowManager::process_windows()
 
        Rect mouse_rect = {mouse_x, mouse_y, mouse_cursor.get_width(), mouse_cursor.get_height()};
        invalidate_region(mouse_rect);
+
+       gfx_update();
 }
 
 void WindowManager::add_window(Window *win)
@@ -163,6 +165,18 @@ void WindowManager::remove_window(Window *win)
 
 void WindowManager::set_focused_window(Window *win)
 {
+       if(win == focused_win) {
+               return;
+       }
+
+       if(focused_win) {
+               // invalidate the frame (if any)
+               Window *parent = focused_win->get_parent();
+               if(parent && parent != root_win) {
+                       parent->invalidate();
+               }
+       }
+
        if(!win) {
                focused_win = 0;
                return;
@@ -211,10 +225,7 @@ Window *WindowManager::get_window_at_pos(int pointer_x, int pointer_y)
 
 static void display(Window *win)
 {
-       if(win->get_managed()) {
-               fill_rect(win->get_rect(), 255, 211, 5);
-               win->draw(win->get_parent()->get_rect());
-       }
+       fill_rect(win->get_rect(), 255, 211, 5);
 }
 
 static int prev_x = -1, prev_y;