diff options
| author | Eleni Maria Stea <elene.mst@gmail.com> | 2013-03-11 23:19:03 +0200 |
|---|---|---|
| committer | Eleni Maria Stea <elene.mst@gmail.com> | 2013-03-11 23:19:03 +0200 |
| commit | 32869d8ffb64be82541f48166c5e73a6c4336135 (patch) | |
| tree | 027244aeafb756c3578d787cd632746943f6746b /src | |
| parent | 2985bfa49497805b4760c066a6288c4b3752d145 (diff) | |
bug fixes, added background image
Diffstat (limited to 'src')
| -rw-r--r-- | src/fbdev/gfx.cc | 26 | ||||
| -rw-r--r-- | src/fbdev/mouse.cc | 1 | ||||
| -rw-r--r-- | src/geom.cc | 13 | ||||
| -rw-r--r-- | src/geom.h | 3 | ||||
| -rw-r--r-- | src/gfx.cc | 18 | ||||
| -rw-r--r-- | src/gfx.h | 4 | ||||
| -rw-r--r-- | src/main.cc | 7 | ||||
| -rw-r--r-- | src/pixmap.cc | 74 | ||||
| -rw-r--r-- | src/pixmap.h | 4 | ||||
| -rw-r--r-- | src/sdl/gfx.cc | 95 | ||||
| -rw-r--r-- | src/sdl/mouse.cc | 1 | ||||
| -rw-r--r-- | src/wm.cc | 60 | ||||
| -rw-r--r-- | src/wm.h | 4 |
13 files changed, 209 insertions, 101 deletions
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; i<rect.height; i++) { + memcpy(dptr, sptr, rect.width * 4); + sptr += gfx->screen_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; @@ -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); @@ -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; i<height; i++) { - memcpy(dptr, sptr, width * 4); + for(int j=0; j<width; j++) { + dptr[j * 4 + red_offs] = sptr[j * 4]; + dptr[j * 4 + green_offs] = sptr[j * 4 + 1]; + dptr[j * 4 + blue_offs] = sptr[j * 4 + 2]; + } sptr += src_rect.width * 4; dptr += dest_rect.width * 4; } @@ -91,6 +98,9 @@ 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) { + 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; @@ -132,9 +142,9 @@ void blit_key(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_ 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; + dptr[j * 4 + red_offs] = r; + dptr[j * 4 + green_offs] = g; + dptr[j * 4 + blue_offs] = b; } } @@ -27,8 +27,10 @@ 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(); +void gfx_update(const Rect &rect); void wait_vsync(); // vertical synchronization +void get_rgb_order(int *r, int *g, int *b); + #endif //GFX_H_ diff --git a/src/main.cc b/src/main.cc index ae88575..f49f686 100644 --- a/src/main.cc +++ b/src/main.cc @@ -39,6 +39,13 @@ int main() wm->add_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; i<width * height * 4; i++) { + int c; + if(i % 4 != 3) { + c = fgetc(fp); + if(c < 0) + goto err; + } + else { + c = 255; + } + pixels[i] = c; + } + fclose(fp); + return true; + +err: + fprintf(stderr, "failed to load pixmap: %s\n", fname); + fclose(fp); + return false; } bool Pixmap::save(const char *fname) const diff --git a/src/pixmap.h b/src/pixmap.h index 9e5d5fb..aebec70 100644 --- a/src/pixmap.h +++ b/src/pixmap.h @@ -9,6 +9,10 @@ public: unsigned char *pixels; Pixmap(); + + Pixmap(const Pixmap &pixmap); + Pixmap &operator=(const Pixmap& pixmap); + ~Pixmap(); int get_width() const; diff --git a/src/sdl/gfx.cc b/src/sdl/gfx.cc index cd1a4a6..11c6e79 100644 --- a/src/sdl/gfx.cc +++ b/src/sdl/gfx.cc @@ -28,7 +28,7 @@ bool init_gfx() return false; } - Rect scr_rect = {0, 0, 1024, 768}; + Rect scr_rect(0, 0, 1024, 768); gfx->screen_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; 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; - } -} -t.width; - sdl_rect.h = gfx->clipping_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; i<rect.height; i++) { + memcpy(dptr, sptr, rect.width * 4); + sptr += gfx->screen_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; } @@ -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); + } } } @@ -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); |
