*work in progress*
authorEleni Maria Stea <elene.mst@gmail.com>
Wed, 13 Feb 2013 23:46:58 +0000 (01:46 +0200)
committerEleni Maria Stea <elene.mst@gmail.com>
Wed, 13 Feb 2013 23:46:58 +0000 (01:46 +0200)
added some stuff on the window manager and windows
set /dev/tty in raw mode disable echo etc
added todo lists everywhere :p

src/geom.h [new file with mode: 0644]
src/keyboard.cc [new file with mode: 0644]
src/keyboard.h [new file with mode: 0644]
src/mouse.cc [new file with mode: 0644]
src/mouse.h [new file with mode: 0644]
src/window.cc [new file with mode: 0644]
src/window.h [new file with mode: 0644]
src/wm.cc [new file with mode: 0644]
src/wm.h [new file with mode: 0644]

diff --git a/src/geom.h b/src/geom.h
new file mode 100644 (file)
index 0000000..c294b54
--- /dev/null
@@ -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 (file)
index 0000000..8933d42
--- /dev/null
@@ -0,0 +1,85 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#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 (file)
index 0000000..8996dd9
--- /dev/null
@@ -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 (file)
index 0000000..c461810
--- /dev/null
@@ -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 (file)
index 0000000..535f0d4
--- /dev/null
@@ -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 (file)
index 0000000..76c5177
--- /dev/null
@@ -0,0 +1,73 @@
+#include <string.h>
+#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 (file)
index 0000000..7bccd2c
--- /dev/null
@@ -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 (file)
index 0000000..0428a7c
--- /dev/null
+++ b/src/wm.cc
@@ -0,0 +1,37 @@
+#include <stdexcept>
+#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<Window*>::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 (file)
index 0000000..27ae316
--- /dev/null
+++ b/src/wm.h
@@ -0,0 +1,23 @@
+#ifndef WM_H_
+#define WM_H_
+
+#include <list>
+#include "geom.h"
+
+class Window;
+
+class WindowManager {
+private:
+       std::list<Window*> windows;
+       std::list<Rect> dirty_rects;
+
+public:
+       WindowManager();
+
+       void invalidate_region(const Rect &rect);
+       void process_windows();
+};
+
+extern WindowManager *wm;
+
+#endif // WM_H_