From: Eleni Maria Stea Date: Fri, 22 Feb 2013 23:22:10 +0000 (+0200) Subject: added SDL backend for easier testing X-Git-Url: https://eleni.mutantstargoat.com/git/?p=winnie;a=commitdiff_plain;h=6dc42c0e7292d6d94de640ddd7de3ee5c808e9c2 added SDL backend for easier testing --- diff --git a/Makefile b/Makefile index c6b749a..a894e52 100644 --- 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 index a54fe7a..0000000 --- a/src/event.cc +++ /dev/null @@ -1,37 +0,0 @@ -#include - -#include -#include -#include - -#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 index 0000000..611ec3c --- /dev/null +++ b/src/fbdev/event.cc @@ -0,0 +1,39 @@ +#ifdef WINNIE_FBDEV +#include + +#include +#include +#include + +#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 index 0000000..00e1881 --- /dev/null +++ b/src/fbdev/gfx.cc @@ -0,0 +1,226 @@ +#ifdef WINNIE_FBDEV +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#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= 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= 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 +#include +#include +#include + +#include +#include +#include +#include + +#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 index 0000000..5fd080b --- /dev/null +++ b/src/fbdev/mouse.cc @@ -0,0 +1,161 @@ +#ifdef WINNIE_FBDEV +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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> 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 index 7d3595c..0000000 --- a/src/gfx.cc +++ /dev/null @@ -1,219 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#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= 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= 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 -#include -#include -#include - -#include -#include -#include -#include - -#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 - */ -} diff --git a/src/main.cc b/src/main.cc index 6697506..8b36449 100644 --- a/src/main.cc +++ b/src/main.cc @@ -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 index b3f329b..0000000 --- a/src/mouse.cc +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#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> 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; -} diff --git a/src/mouse.h b/src/mouse.h index 271ee83..1770d7a 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -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 index 0000000..97c9b1e --- /dev/null +++ b/src/sdl/event.cc @@ -0,0 +1,33 @@ +#ifdef WINNIE_SDL +#include +#include + +#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 index 0000000..b757688 --- /dev/null +++ b/src/sdl/gfx.cc @@ -0,0 +1,170 @@ +#ifdef WINNIE_SDL +#include +#include +#include +#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= 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 + +#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 index 0000000..5531707 --- /dev/null +++ b/src/sdl/mouse.cc @@ -0,0 +1,89 @@ +#ifdef WINNIE_SDL +#include + +#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 diff --git a/src/window.cc b/src/window.cc index 2a8b6f5..46528b7 100644 --- a/src/window.cc +++ b/src/window.cc @@ -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 && diff --git a/src/window.h b/src/window.h index 1eebed0..3db8ec8 100644 --- a/src/window.h +++ b/src/window.h @@ -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); diff --git a/src/wm.cc b/src/wm.cc index 6577a67..89b709f 100644 --- 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;