From: Eleni Maria Stea Date: Mon, 11 Mar 2013 21:19:03 +0000 (+0200) Subject: bug fixes, added background image X-Git-Url: http://git.mutantstargoat.com?p=winnie;a=commitdiff_plain;h=32869d8ffb64be82541f48166c5e73a6c4336135 bug fixes, added background image --- diff --git a/Makefile b/Makefile index a132c3f..4242187 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ dbg = -g opt = -O0 inc = -Isrc -#backend = SDL +backend = SDL ifeq ($(backend), SDL) def = -DWINNIE_SDL diff --git a/src/fbdev/gfx.cc b/src/fbdev/gfx.cc index 74dec0c..e3677d4 100644 --- a/src/fbdev/gfx.cc +++ b/src/fbdev/gfx.cc @@ -20,6 +20,7 @@ static unsigned char *framebuffer; static int dev_fd; +static int rgb_order[3]; struct Graphics { Rect screen_rect; @@ -59,6 +60,10 @@ bool init_gfx() gfx->screen_rect.height = sinfo.yres_virtual; gfx->color_depth = sinfo.bits_per_pixel; + rgb_order[0] = sinfo.red.offset / 8; + rgb_order[1] = sinfo.green.offset / 8; + rgb_order[2] = sinfo.blue.offset / 8; + set_clipping_rect(gfx->screen_rect); int sz = FRAMEBUFFER_SIZE(gfx->screen_rect.width, gfx->screen_rect.height, gfx->color_depth); @@ -104,7 +109,7 @@ bool init_gfx() void destroy_gfx() { clear_screen(0, 0, 0); - gfx_update(); + gfx_update(gfx->screen_rect); if(dev_fd != -1) { close(dev_fd); @@ -161,9 +166,17 @@ void set_cursor_visibility(bool visible) } } -void gfx_update() +void gfx_update(const Rect &upd_rect) { - memcpy(framebuffer, gfx->pixmap->pixels, gfx->pixmap->width * gfx->pixmap->height * (gfx->color_depth / 8)); + Rect rect = rect_intersection(upd_rect, gfx->screen_rect); + unsigned char *sptr = gfx->pixmap->pixels + (rect.y * gfx->screen_rect.width + rect.x) * 4; + unsigned char *dptr = framebuffer + (rect.y * gfx->screen_rect.width + rect.x) * 4; + + for(int i=0; iscreen_rect.width * 4; + dptr += gfx->screen_rect.width * 4; + } } void wait_vsync() @@ -174,4 +187,11 @@ void wait_vsync() } } +void get_rgb_order(int *r, int *g, int *b) +{ + *r = rgb_order[0]; + *g = rgb_order[1]; + *b = rgb_order[2]; +} + #endif // WINNIE_FBDEV diff --git a/src/fbdev/mouse.cc b/src/fbdev/mouse.cc index dae9b98..cb383de 100644 --- a/src/fbdev/mouse.cc +++ b/src/fbdev/mouse.cc @@ -38,6 +38,7 @@ bool init_mouse() if(!(mouse = (Mouse*)sh_malloc(sizeof *mouse))) { return false; } + memset(mouse, 0, sizeof *mouse); mouse->dev_fd = -1; diff --git a/src/geom.cc b/src/geom.cc index c9d5c51..7561397 100644 --- a/src/geom.cc +++ b/src/geom.cc @@ -1,5 +1,18 @@ #include "geom.h" +Rect::Rect() +{ + x = y = width = height = 0; +} + +Rect::Rect(int x, int y, int w, int h) +{ + this->x = x; + this->y = y; + width = w; + height = h; +} + static inline int min(int x, int y) { return x < y ? x : y; diff --git a/src/geom.h b/src/geom.h index 9c00b41..203914a 100644 --- a/src/geom.h +++ b/src/geom.h @@ -4,6 +4,9 @@ struct Rect { int x, y; int width, height; + + Rect(); + Rect(int x, int y, int w, int h); }; Rect rect_union(const Rect &a, const Rect &b); diff --git a/src/gfx.cc b/src/gfx.cc index f0be460..c517b39 100644 --- a/src/gfx.cc +++ b/src/gfx.cc @@ -47,6 +47,9 @@ void fill_rect(const Rect &rect, int r, int g, int b) 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 red_offs, green_offs, blue_offs; + get_rgb_order(&red_offs, &green_offs, &blue_offs); + Rect irect = rect_intersection(get_clipping_rect(), dest_rect); int width = src_rect.width; @@ -82,7 +85,11 @@ void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img, unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4; for(int i=0; iadd_window(win1); wm->add_window(win2); + Pixmap bg; + if(!(bg.load("data/bg.ppm"))) { + fprintf(stderr, "failed to load pixmap\n"); + } + + wm->set_background(&bg); + while(1) { process_events(); } diff --git a/src/pixmap.cc b/src/pixmap.cc index 5c9b242..ada337d 100644 --- a/src/pixmap.cc +++ b/src/pixmap.cc @@ -9,6 +9,22 @@ Pixmap::Pixmap() pixels = 0; } +Pixmap::Pixmap(const Pixmap &pixmap) +{ + width = height = 0; + pixels = 0; + set_image(pixmap.width, pixmap.height, pixmap.pixels); +} + +Pixmap &Pixmap::operator=(const Pixmap &pixmap) +{ + if(this != &pixmap) { + set_image(pixmap.width, pixmap.height, pixmap.pixels); + } + + return *this; +} + Pixmap::~Pixmap() { if(pixels) { @@ -28,7 +44,7 @@ int Pixmap::get_height() const Rect Pixmap::get_rect() const { - Rect rect = {0, 0, width, height}; + Rect rect(0, 0, width, height); return rect; } @@ -58,7 +74,61 @@ unsigned char *Pixmap::get_image() bool Pixmap::load(const char *fname) { - return false; // TODO + FILE *fp; + int hdrline = 0; + + if(!(fp = fopen(fname, "rb"))) { + fprintf(stderr, "failed to open pixmap: %s: %s\n", fname, strerror(errno)); + return false; + } + + /* read ppm header */ + while(hdrline < 3) { + char buf[64]; + + if(!fgets(buf, sizeof buf, fp)) + goto err; + + /* skip comments */ + if(buf[0] == '#') + continue; + + switch(hdrline++) { + case 0: + /* first header line should be P6 */ + if(strcmp(buf, "P6\n") != 0) + goto err; + break; + + case 1: + /* second header line contains the pixmap dimensions */ + if(sscanf(buf, "%d %d", &width, &height) != 2) + goto err; + break; + } + } + + set_image(width, height, 0); + + for(int i=0; iscreen_rect = scr_rect; gfx->color_depth = 32; @@ -86,75 +86,6 @@ int get_color_depth() return gfx->color_depth; } -/*void set_clipping_rect(const Rect &rect) -{ - gfx->clipping_rect = rect_intersection(rect, gfx->screen_rect); - - SDL_Rect sdl_rect; - sdl_rect.x = gfx->clipping_rect.x; - sdl_rect.y = gfx->clipping_rect.y; - sdl_rect.w = gfx->clipping_recvoid fill_rect(const Rect &rect, int r, int g, int b) -{ - Rect drect = rect; - Rect screen_rect = get_screen_size(); - - if(drect.x < clipping_rect.x) { - drect.width -= clipping_rect.x - drect.x; - drect.x = clipping_rect.x; - } - - if(drect.y < clipping_rect.y) { - drect.height -= clipping_rect.y - drect.y; - drect.y = clipping_rect.y; - } - - if(drect.x + drect.width >= clipping_rect.x + clipping_rect.width) { - drect.width = clipping_rect.width + clipping_rect.x - drect.x; - } - - if(drect.y + drect.height >= clipping_rect.y + clipping_rect.height) { - drect.height = clipping_rect.height + clipping_rect.y - drect.y; - } - - unsigned char *fb = get_framebuffer() + (drect.x + screen_rect.width * drect.y) * 4; - for(int i=0; iclipping_rect.height; - - SDL_SetClipRect(fbsurf, &sdl_rect); -} - -const Rect &get_clipping_rect() -{ - return gfx->clipping_rect; -} - -void clear_screen(int r, int g, int b) -{ - fill_rect(gfx->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_clipping_rect(const Rect &rect) { gfx->clipping_rect = rect_intersection(rect, get_screen_size()); @@ -170,20 +101,38 @@ void set_cursor_visibility(bool visible) { } -void gfx_update() +void gfx_update(const Rect &upd_rect) { if(SDL_MUSTLOCK(fbsurf)) { SDL_LockSurface(fbsurf); } - memcpy(fbsurf->pixels, gfx->pixmap->pixels, gfx->pixmap->width * gfx->pixmap->height * (gfx->color_depth / 8)); + + Rect rect = rect_intersection(upd_rect, gfx->screen_rect); + + unsigned char *sptr = gfx->pixmap->pixels + (rect.y * gfx->screen_rect.width + rect.x) * 4; + unsigned char *dptr = (unsigned char*)fbsurf->pixels + (rect.y * gfx->screen_rect.width + rect.x) * 4; + + for(int i=0; iscreen_rect.width * 4; + dptr += gfx->screen_rect.width * 4; + } + if(SDL_MUSTLOCK(fbsurf)) { SDL_UnlockSurface(fbsurf); } - SDL_UpdateRect(fbsurf, 0, 0, 0, 0); + SDL_UpdateRect(fbsurf, rect.x, rect.y, rect.width, rect.height); } void wait_vsync() { } +void get_rgb_order(int *r, int *g, int *b) +{ + *r = fbsurf->format->Rshift / 8; + *g = fbsurf->format->Gshift / 8; + *b = fbsurf->format->Bshift / 8; +} + #endif // WINNIE_SDL diff --git a/src/sdl/mouse.cc b/src/sdl/mouse.cc index 546f3bf..86e9cce 100644 --- a/src/sdl/mouse.cc +++ b/src/sdl/mouse.cc @@ -21,6 +21,7 @@ bool init_mouse() if(!(mouse = (Mouse*)sh_malloc(sizeof *mouse))) { return false; } + memset(mouse, 0, sizeof *mouse); return true; } diff --git a/src/wm.cc b/src/wm.cc index 7791e79..dd47d30 100644 --- a/src/wm.cc +++ b/src/wm.cc @@ -91,6 +91,7 @@ WindowManager::WindowManager() grab_win = 0; focused_win = 0; + background = 0; bg_color[0] = 210; bg_color[1] = 106; @@ -141,7 +142,13 @@ void WindowManager::process_windows() wait_vsync(); - fill_rect(uni, bg_color[0], bg_color[1], bg_color[2]); + if(!background) { + fill_rect(uni, bg_color[0], bg_color[1], bg_color[2]); + } + else { + blit(background->pixels, Rect(0, 0, background->width, background->height), + get_framebuffer(), get_screen_size(), 0, 0); + } root_win->draw_children(uni); @@ -153,10 +160,10 @@ void WindowManager::process_windows() 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()}; + Rect mouse_rect(mouse_x, mouse_y, mouse_cursor.get_width(), mouse_cursor.get_height()); invalidate_region(mouse_rect); - gfx_update(); + gfx_update(uni); } void WindowManager::add_window(Window *win) @@ -284,6 +291,25 @@ void WindowManager::get_unfocused_frame_color(int *r, int *g, int *b) const *b = frame_ucolor[2]; } +void WindowManager::set_background(const Pixmap *pixmap) +{ + if(background) { + delete background; + } + + if(pixmap) { + background = new Pixmap(*pixmap); + } + else { + background = 0; + } +} + +const Pixmap *WindowManager::get_background() const +{ + return background; +} + Window *WindowManager::get_grab_window() const { return grab_win; @@ -349,9 +375,7 @@ void WindowManager::maximize_window(Window *win) rect.height -= frame_thickness * 2 + titlebar_thickness; } else { - rect.x = 0; - rect.y = 0; - win->move(rect.x, rect.y); + win->move(0, 0); } win->resize(rect.width, rect.height); @@ -402,28 +426,26 @@ static void mouse(Window *win, int bn, bool pressed, int x, int y) static long last_click = 0; if(bn == 0) { - if(pressed) { + if(pressed) { + wm->grab_mouse(win); + wm->raise_window(win); + prev_x = x; + prev_y = y; + } + else { long time = winnie_get_time(); if((time - last_click) < DCLICK_INTERVAL) { Window *child = win->get_children()[0]; Window::State state = child->get_state(); if(state == Window::STATE_MAXIMIZED) { - child->set_state(Window::STATE_NORMAL); wm->unmaximize_window(child); } else if(state == Window::STATE_NORMAL) { wm->maximize_window(child); } } - - wm->grab_mouse(win); - wm->raise_window(win); - prev_x = x; - prev_y = y; - last_click = time; - } - else { + wm->release_mouse(); } } @@ -439,7 +461,9 @@ static void motion(Window *win, int x, int y) prev_x = x - dx; prev_y = y - dy; - Rect rect = win->get_rect(); - win->move(rect.x + dx, rect.y + dy); + if(win->get_children()[0]->get_state() != Window::STATE_MAXIMIZED) { + Rect rect = win->get_rect(); + win->move(rect.x + dx, rect.y + dy); + } } } diff --git a/src/wm.h b/src/wm.h index 140a3b0..0ba8a04 100644 --- a/src/wm.h +++ b/src/wm.h @@ -28,6 +28,7 @@ private: Window *grab_win; Pixmap mouse_cursor; + Pixmap *background; void create_frame(Window *win); void destroy_frame(Window *win); @@ -55,6 +56,9 @@ public: void set_unfocused_frame_color(int r, int g, int b); void get_unfocused_frame_color(int *r, int *g, int *b) const; + void set_background(const Pixmap *pixmap); + const Pixmap *get_background() const; + Window *get_grab_window() const; void grab_mouse(Window *win);