From: Eleni Maria Stea Date: Wed, 13 Feb 2013 23:46:58 +0000 (+0200) Subject: *work in progress* X-Git-Url: https://eleni.mutantstargoat.com/git/?p=winnie;a=commitdiff_plain;h=8a92836b3af157fd47c657cfe546887e5f5683a8 *work in progress* added some stuff on the window manager and windows set /dev/tty in raw mode disable echo etc added todo lists everywhere :p --- diff --git a/src/geom.h b/src/geom.h new file mode 100644 index 0000000..c294b54 --- /dev/null +++ b/src/geom.h @@ -0,0 +1,15 @@ +#ifndef GEOM_H_ +#define GEOM_H_ + +struct Rect { + int x, y; + int width, height; +}; + +// TODO probably need to implement something like this: +/* +Rect rect_union(const Rect &a, const Rect &b); +Rect rect_intersection(const Rect &a, const Rect &b); +*/ + +#endif // GEOM_H_ diff --git a/src/keyboard.cc b/src/keyboard.cc new file mode 100644 index 0000000..8933d42 --- /dev/null +++ b/src/keyboard.cc @@ -0,0 +1,85 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "keyboard.h" + +static int tty_fd = -1; +static enum {RAW, CANONICAL} ttystate = CANONICAL; + +static int keyb_fd = -1; + +bool init_keyboard() +{ + if((tty_fd = open("/dev/tty", O_RDWR)) == -1) { + fprintf(stderr, "Cannot open /dev/tty : %s\n", strerror(errno)); + return false; + } + + struct termios buf; + + if(tcgetattr(tty_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); + buf.c_cc[VMIN] = 1; + buf.c_cc[VTIME] = 0; + + if(tcsetattr(tty_fd, TCSAFLUSH, &buf) < 0) { + return false; + } + + ttystate = RAW; + return true; +} + +void destroy_keyboard() +{ + struct termios buf; + + 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); + buf.c_cc[VMIN] = 1; + buf.c_cc[VTIME] = 0; + + ttystate = CANONICAL; + close(tty_fd); + + tty_fd = -1; +} + +int get_keyboard_fd() +{ + return tty_fd; +} + +void process_keyboard_event() +{ + char key; + if(read(tty_fd, &key, 1) < 1) { + return; + } + + if(key == 'q') { + exit(0); + } + /* TODO: + * - handle system-wide key combinations (alt-tab?) + * - otherwise send keypress/release to focused window + */ +} diff --git a/src/keyboard.h b/src/keyboard.h new file mode 100644 index 0000000..8996dd9 --- /dev/null +++ b/src/keyboard.h @@ -0,0 +1,10 @@ +#ifndef KEYBOARD_H_ +#define KEYBOARD_H_ + +bool init_keyboard(); +void destroy_keyboard(); + +int get_keyboard_fd(); +void process_keyboard_event(); + +#endif // KEYBOARD_H_ diff --git a/src/mouse.cc b/src/mouse.cc new file mode 100644 index 0000000..c461810 --- /dev/null +++ b/src/mouse.cc @@ -0,0 +1,50 @@ +#include "mouse.h" +#include "geom.h" + +static int dev_fd = -1; // file descriptor for /dev/psaux +static Rect bounds; +static int pointer_x, pointer_y; + +bool init_mouse() +{ + // TODO open /dev/psaux (see O_NONBLOCK comment below) + return true; +} + +void destroy_mouse() +{ + // TODO close /dev/psaux +} + +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). + * - process each event and update the pointer and button state + * - send each pointer move and button press/release to the tompost window + * with the pointer on it. + */ +} + +void get_pointer_pos(int *x, int *y) +{ + *x = pointer_x; + *y = pointer_y; +} + +int get_button_state(int bn) +{ + // TODO + return 0; +} diff --git a/src/mouse.h b/src/mouse.h new file mode 100644 index 0000000..535f0d4 --- /dev/null +++ b/src/mouse.h @@ -0,0 +1,17 @@ +#ifndef MOUSE_H_ +#define MOUSE_H_ + +struct Rect; + +bool init_mouse(); +void destroy_mouse(); + +void set_mouse_bounds(const Rect &rect); + +int get_mouse_fd(); +void process_mouse_event(); + +void get_pointer_pos(int *x, int *y); +int get_button_state(int bn); + +#endif // MOUSE_H_ diff --git a/src/window.cc b/src/window.cc new file mode 100644 index 0000000..76c5177 --- /dev/null +++ b/src/window.cc @@ -0,0 +1,73 @@ +#include +#include "gfx.h" +#include "window.h" +#include "wm.h" + +Window::Window() +{ + title = 0; + rect.x = rect.y = 0; + rect.width = rect.height = 128; + memset(&callbacks, 0, sizeof callbacks); + dirty = true; +} + +Window::~Window() +{ + delete [] title; +} + +const Rect &Window::get_rect() const +{ + return rect; +} + +void Window::move(int x, int y) +{ + invalidate(); // moved, should redraw, MUST BE CALLED FIRST + rect.x = x; + rect.y = y; +} + +void Window::resize(int x, int y) +{ + invalidate(); // resized, should redraw, MUST BE CALLED FIRST + rect.width = x; + rect.height = y; +} + +void Window::set_title(const char *s) +{ + delete [] title; + + title = new char[strlen(s) + 1]; + strcpy(title, s); +} + +const char *Window::get_title() const +{ + return title; +} + +void Window::invalidate() +{ + dirty = true; + wm->invalidate_region(rect); +} + +void Window::draw() +{ + callbacks.display(this); + dirty = false; +} + +unsigned char *Window::get_win_start_on_fb() +{ + unsigned char *fb = get_framebuffer(); + return fb + get_color_depth() * (get_screen_size().x * rect.y + rect.x) / 8; +} + +int Window::get_scanline_width() +{ + return get_screen_size().x; +} diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..7bccd2c --- /dev/null +++ b/src/window.h @@ -0,0 +1,46 @@ +#ifndef WINDOW_H_ +#define WINDOW_H_ + +#include "geom.h" +#include "event.h" + +class Window { +private: + char *title; + Rect rect; + Callbacks callbacks; + + bool dirty; + +public: + Window(); + ~Window(); + + const Rect &get_rect() const; + + void move(int x, int y); + void resize(int x, int y); + + void set_title(const char *s); + const char *get_title() const; + + /* mark this window as dirty, and notify the window manager + * to repaint it, and anything it used to cover. + */ + void invalidate(); + + void draw(); + + unsigned char *get_win_start_on_fb(); + int get_scanline_width(); + + void set_display_callback(DisplayFuncType func); + void set_keyboard_callback(KeyboardFuncType func); + void set_mouse_button_callback(MouseButtonFuncType func); + void set_mouse_motion_callback(MouseMotionFuncType func); + + // XXX remove if not needed + friend class WindowManager; +}; + +#endif // WINDOW_H_ diff --git a/src/wm.cc b/src/wm.cc new file mode 100644 index 0000000..0428a7c --- /dev/null +++ b/src/wm.cc @@ -0,0 +1,37 @@ +#include +#include "wm.h" +#include "window.h" + + +WindowManager *wm; +static WindowManager wminst; + +WindowManager::WindowManager() +{ + if(!wm) { + wm = this; + } else { + throw std::runtime_error("Trying to create a second instance of WindowManager!\n"); + } +} + +void WindowManager::invalidate_region(const Rect &rect) +{ + dirty_rects.push_back(rect); +} + +void WindowManager::process_windows() +{ + //TODO: + //sta dirty rectangles na brw to union + //na eleg3w poia einai sto dirty area k na ta kanw dirty + //na ka8arizw ta dirty areas + //prwta render to bg + //meta ola ta dirty: + std::list::iterator it = windows.begin(); + while(it != windows.end()) { + if((*it)->dirty) { + (*it)->draw(); + } + } +} diff --git a/src/wm.h b/src/wm.h new file mode 100644 index 0000000..27ae316 --- /dev/null +++ b/src/wm.h @@ -0,0 +1,23 @@ +#ifndef WM_H_ +#define WM_H_ + +#include +#include "geom.h" + +class Window; + +class WindowManager { +private: + std::list windows; + std::list dirty_rects; + +public: + WindowManager(); + + void invalidate_region(const Rect &rect); + void process_windows(); +}; + +extern WindowManager *wm; + +#endif // WM_H_