}
}
-void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img, int dest_x, int dest_y)
+void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+ const Rect &dest_rect, int dest_x, int dest_y)
{
- Rect dest_rect;
+ int width = src_rect.width;
+ int height = src_rect.height;
- if(dest_x < screen_rect.x) {
- dest_rect.x = screen_rect.x;
+ int xoffs = dest_x - dest_rect.x;
+ if(xoffs < 0) {
+ dest_x = dest_rect.x;
+ width += xoffs;
}
- if(dest_y < screen_rect.y) {
- dest_rect.y = screen_rect.y;
+ int yoffs = dest_y - dest_rect.y;
+ if(yoffs < 0) {
+ dest_y = dest_rect.y;
+ height += yoffs;
}
- //TODO :p zzz
+ int xend = dest_x + width;
+ if(xend >= dest_rect.width) {
+ width -= xend - dest_rect.width;
+ }
+
+ int yend = dest_y + height;
+ if(yend >= dest_rect.height) {
+ height -= yend - dest_rect.height;
+ }
+
+ if(width <= 0 || height <= 0) {
+ return;
+ }
+
+ unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4;
+ unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
+
+ for(int i=0; i<height; i++) {
+ memcpy(dptr, sptr, width * 4);
+ sptr += src_rect.width * 4;
+ dptr += dest_rect.width * 4;
+ }
+}
+
+void blit_key(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+ const Rect &dest_rect, int dest_x, int dest_y, int key_r, int key_g, int key_b)
+{
+ int width = src_rect.width;
+ int height = src_rect.height;
+
+ int xoffs = dest_x - dest_rect.x;
+ if(xoffs < 0) {
+ dest_x = dest_rect.x;
+ width += xoffs;
+ }
+
+ int yoffs = dest_y - dest_rect.y;
+ if(yoffs < 0) {
+ dest_y = dest_rect.y;
+ height += yoffs;
+ }
+
+ int xend = dest_x + width;
+ if(xend >= dest_rect.width) {
+ width -= xend - dest_rect.width;
+ }
+
+ int yend = dest_y + height;
+ if(yend >= dest_rect.height) {
+ height -= yend - dest_rect.height;
+ }
+
+ if(width <= 0 || height <= 0) {
+ return;
+ }
+
+ unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4;
+ unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
+
+ for(int i=0; i<height; i++) {
+ for(int j=0; j<width; j++) {
+ int r = sptr[j * 4];
+ int g = sptr[j * 4 + 1];
+ int b = sptr[j * 4 + 2];
+
+ if(r != key_r || g != key_g || b != key_b) {
+ dptr[j * 4] = r;
+ dptr[j * 4 + 1] = g;
+ dptr[j * 4 + 2] = b;
+ }
+ }
+
+ sptr += src_rect.width * 4;
+ dptr += dest_rect.width * 4;
+ }
}
void set_cursor_visibility(bool visible);
-void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img, int dest_x, int dest_y);
+void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+ const Rect &dest_rect, int dest_x, int dest_y);
+
+void blit_key(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+ const Rect &dest_rect, int dest_x, int dest_y, int key_r, int key_g, int key_b);
#endif //GFX_H_
return;
}
- unsigned char *fb = get_framebuffer();
+ /*unsigned char *fb = get_framebuffer();
fb += (bounds.width * pointer_y + pointer_x) * 4;
fb[0] = 0;
fb[1] = 0;
- fb[2] = 0;
+ fb[2] = 0;*/
//printf("pointer (x, y) = (%d, %d)\r\n", pointer_x, pointer_y);
--- /dev/null
+#ifndef MOUSE_CURSOR_H_
+#define MOUSE_CURSOR_H_
+
+const int mouse_cursor_width = 8;
+const int mouse_cursor_height = 16;
+
+const int mouse_cursor_bw[] = {
+ 128, 128, 0, 0, 0, 0, 0, 0,
+ 128, 255, 128, 0, 0, 0, 0, 0,
+ 128, 255, 255, 128, 0, 0, 0, 0,
+ 128, 255, 255, 255, 128, 0, 0, 0,
+ 128, 255, 255, 255, 255, 128, 0, 0,
+ 128, 255, 255, 255, 255, 255, 128, 0,
+ 128, 255, 255, 255, 255, 255, 255, 128,
+ 128, 255, 255, 255, 255, 255, 128, 0,
+ 128, 255, 255, 255, 255, 128, 0, 0,
+ 128, 255, 255, 255, 255, 128, 0, 0,
+ 128, 255, 255, 255, 255, 255, 128, 0,
+ 128, 255, 255, 255, 255, 255, 128, 0,
+ 128, 255, 128, 128, 255, 255, 255, 128,
+ 128, 128, 0, 128, 255, 255, 255, 128,
+ 128, 0, 0, 0, 128, 255, 255, 128,
+ 0, 0, 0, 0, 0, 128, 128, 128
+};
+
+
+
+#endif // MOUSE_CURSOR_H_
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "pixmap.h"
+
+Pixmap::Pixmap()
+{
+ width = height = 0;
+ pixels = 0;
+}
+
+Pixmap::~Pixmap()
+{
+ if(pixels) {
+ delete [] pixels;
+ }
+}
+
+int Pixmap::get_width() const
+{
+ return width;
+}
+
+int Pixmap::get_height() const
+{
+ return height;
+}
+
+Rect Pixmap::get_rect() const
+{
+ Rect rect = {0, 0, width, height};
+ return rect;
+}
+
+bool Pixmap::set_image(int x, int y, unsigned char *pix)
+{
+ delete [] pixels;
+
+ pixels = new unsigned char[x * y * 4];
+ width = x;
+ height = y;
+
+ if(pix) {
+ memcpy(pixels, pix, x * y * 4);
+ }
+ return true;
+}
+
+const unsigned char *Pixmap::get_image() const
+{
+ return pixels;
+}
+
+unsigned char *Pixmap::get_image()
+{
+ return pixels;
+}
+
+bool Pixmap::load(const char *fname)
+{
+ return false; // TODO
+}
+
+bool Pixmap::save(const char *fname) const
+{
+ if(!pixels) {
+ return false;
+ }
+
+ FILE *fp = fopen(fname, "wb");
+ if(!fp) {
+ fprintf(stderr, "failed to save pixmap: %s: %s\n", fname, strerror(errno));
+ return false;
+ }
+
+ fprintf(fp, "P6\n%d %d\n255\n", width, height);
+
+ for(int i=0; i<width * height; i++) {
+ fputc(pixels[i * 4], fp);
+ fputc(pixels[i * 4 + 1], fp);
+ fputc(pixels[i * 4 + 2], fp);
+ }
+
+ fclose(fp);
+ return true;
+}
--- /dev/null
+#ifndef PIXMAP_H_
+#define PIXMAP_H_
+
+#include "geom.h"
+
+class Pixmap {
+private:
+ int width, height;
+ unsigned char *pixels;
+
+public:
+ Pixmap();
+ ~Pixmap();
+
+ int get_width() const;
+ int get_height() const;
+ Rect get_rect() const;
+
+ bool set_image(int x, int y, unsigned char *pix = 0);
+ const unsigned char *get_image() const;
+ unsigned char *get_image();
+
+ bool load(const char *fname);
+ bool save(const char *fname) const;
+};
+
+#endif // PIXMAP_H_
bool Window::contains_point(int ptr_x, int ptr_y)
{
- if((rect.x <= ptr_x) && ((rect.x + rect.width) >= ptr_x)) {
- if((rect.y <= ptr_y) && (ptr_y <= (rect.y + rect.height))) {
- return true;
- }
- }
-
- return false;
+ return ptr_x >= rect.x && ptr_x < rect.x + rect.width &&
+ ptr_y >= rect.y && ptr_y < rect.y + rect.height;
}
void Window::move(int x, int y)
#include "gfx.h"
#include "wm.h"
#include "window.h"
+#include "mouse.h"
+#include "mouse_cursor.h"
WindowManager *wm;
static WindowManager wminst;
bg_color[0] = 210;
bg_color[1] = 106;
bg_color[2] = 106;
+
+ mouse_cursor.set_image(mouse_cursor_width, mouse_cursor_height);
+ unsigned char *pixels = mouse_cursor.get_image();
+
+ for(int i=0; i<mouse_cursor_height; i++) {
+ for(int j=0; j<mouse_cursor_width; j++) {
+ int val = mouse_cursor_bw[i * mouse_cursor_width + j];
+ *pixels++ = val;
+ *pixels++ = val;
+ *pixels++ = val;
+ *pixels++ = 255;
+ }
+ }
}
void WindowManager::invalidate_region(const Rect &rect)
}
it++;
}
+
+ // draw mouse cursor
+ int mouse_x, mouse_y;
+ get_pointer_pos(&mouse_x, &mouse_y);
+
+ blit_key(mouse_cursor.get_image(), mouse_cursor.get_rect(),
+ get_framebuffer(), get_screen_size(), mouse_x, mouse_y,
+ 0, 0, 0);
+
+ Rect mouse_rect = {mouse_x, mouse_y, mouse_cursor.get_width(), mouse_cursor.get_height()};
+ invalidate_region(mouse_rect);
}
void WindowManager::add_window(Window *win)
#include <list>
#include "geom.h"
+#include "pixmap.h"
class Window;
int bg_color[3];
Window *focused_win;
+ Pixmap mouse_cursor;
+
public:
WindowManager();