├── .bzrignore ├── clock ├── Makefile ├── README └── src │ └── main.cc ├── libwinnie ├── Makefile ├── README └── src │ ├── event.h │ ├── fbdev │ ├── event.cc │ ├── gfx.cc │ ├── keyboard.cc │ └── mouse.cc │ ├── geom.cc │ ├── geom.h │ ├── gfx.cc │ ├── gfx.h │ ├── keyboard.h │ ├── mouse.h │ ├── mouse_cursor.h │ ├── pixmap.cc │ ├── pixmap.h │ ├── sdl │ ├── event.cc │ ├── gfx.cc │ ├── keyboard.cc │ └── mouse.cc │ ├── semaphore.cc │ ├── semaphore.h │ ├── shalloc.cc │ ├── shalloc.h │ ├── text.cc │ ├── text.h │ ├── window.cc │ ├── window.h │ ├── winnie.cc │ ├── winnie.h │ ├── wm.cc │ └── wm.h └── winnie ├── Makefile ├── README └── src └── main.cc /.bzrignore: -------------------------------------------------------------------------------- 1 | *.d 2 | -------------------------------------------------------------------------------- /clock/Makefile: -------------------------------------------------------------------------------- 1 | src = $(wildcard src/*.cc) $(wildcard src/fbdev/*.cc) $(wildcard src/sdl/*.cc) 2 | obj = $(src:.cc=.o) 3 | dep = $(obj:.o=.d) 4 | bin = clock 5 | 6 | dbg = -g 7 | opt = -O0 8 | inc = -Isrc -I../libwinnie/src 9 | 10 | backend = SDL 11 | 12 | ifeq ($(backend), SDL) 13 | def = -DWINNIE_SDL 14 | libs = -lSDL 15 | else 16 | def = -DWINNIE_FBDEV 17 | endif 18 | 19 | CXX = g++ 20 | CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc) $(def) `freetype-config --cflags` 21 | LDFLAGS = -L../libwinnie/ $(libs) `freetype-config --libs` -lrt -lwinnie 22 | 23 | $(bin): $(obj) 24 | $(CXX) -o $@ $(obj) $(LDFLAGS) -Wl,-rpath=../libwinnie 25 | 26 | -include $(dep) 27 | 28 | %.d: %.cc 29 | @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@ 30 | 31 | .PHONY: clean 32 | clean: 33 | rm -f $(obj) $(bin) $(dep) 34 | 35 | -------------------------------------------------------------------------------- /clock/README: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | A clock winnie client. 23 | -------------------------------------------------------------------------------- /clock/src/main.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "winnie.h" 27 | 28 | static void display(Window *win); 29 | static void keyboard(Window *win, int key, bool pressed); 30 | static void button(Window *win, int bn, bool pressed, int x, int y); 31 | static void motion(Window *win, int x, int y); 32 | 33 | Subsys* subsys; 34 | 35 | int main() 36 | { 37 | if(!winnie_open()) { 38 | exit(1); 39 | } 40 | 41 | Window *clock_win = new Window; 42 | clock_win->set_title("Clipping the win title"); 43 | clock_win->move(200, 100); 44 | clock_win->resize(200, 300); 45 | clock_win->set_display_callback(display); 46 | clock_win->set_keyboard_callback(keyboard); 47 | clock_win->set_mouse_button_callback(button); 48 | clock_win->set_mouse_motion_callback(motion); 49 | 50 | wm->add_window(clock_win); 51 | 52 | winnie_close(); 53 | } 54 | 55 | static void display(Window *win) 56 | { 57 | fill_rect(win->get_absolute_rect(), 128, 128, 128); 58 | } 59 | 60 | static void keyboard(Window *win, int key, bool pressed) 61 | { 62 | switch(key) { 63 | case 'q': 64 | exit(0); 65 | } 66 | } 67 | 68 | static void button(Window *win, int bn, bool pressed, int x, int y) 69 | { 70 | printf("WINDOW(%p) button %d %s\n", (void*)win, bn, pressed ? "press" : "release"); 71 | } 72 | 73 | static void motion(Window *win, int x, int y) 74 | { 75 | printf("WINDOW(%p) motion %d %d\n", (void*)win, x, y); 76 | } 77 | -------------------------------------------------------------------------------- /libwinnie/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=/usr/local 2 | src = $(wildcard src/*.cc) $(wildcard src/fbdev/*.cc) $(wildcard src/sdl/*.cc) 3 | obj = $(src:.cc=.o) 4 | #dep = $(obj:.o=.d) 5 | lib_so = libwinnie.so 6 | 7 | dbg = -g 8 | opt = -O0 9 | inc = -Isrc 10 | 11 | backend = SDL 12 | 13 | ifeq ($(backend), SDL) 14 | def = -DWINNIE_SDL 15 | libs = -lSDL 16 | else 17 | def = -DWINNIE_FBDEV 18 | endif 19 | 20 | CXX = g++ 21 | CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc) $(def) `freetype-config --cflags` 22 | LDFLAGS = $(libs) `freetype-config --libs` -lrt 23 | 24 | $(lib_so): $(obj) 25 | $(CXX) -o $@ -shared $(obj) $(LDFLAGS) 26 | 27 | .PHONY: clean 28 | clean: 29 | rm -f $(obj) $(lib_so) 30 | 31 | .PHONY: install 32 | install: $(lib_so) 33 | mkdir -p $(PREFIX)/lib 34 | mkdir -p $(PREFIX)/bin 35 | cp $(lib_so) $(PREFIX)/lib/$(lib_so) 36 | ldconfig 37 | 38 | .PHONY: uninstall 39 | uninstall: 40 | rm -f $(PREFIX)/lib/$(lib_so) 41 | -------------------------------------------------------------------------------- /libwinnie/README: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | The winnie library. 23 | -------------------------------------------------------------------------------- /libwinnie/src/event.h: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef EVENT_H_ 23 | #define EVENT_H_ 24 | 25 | class Window; 26 | 27 | typedef void (*DisplayFuncType)(Window* win); 28 | typedef void (*KeyboardFuncType)(Window* win, int key, bool pressed); 29 | typedef void (*MouseButtonFuncType)(Window *win, int bn, bool pressed, int x, int y); 30 | typedef void (*MouseMotionFuncType)(Window *win, int x, int y); 31 | 32 | struct Callbacks { 33 | DisplayFuncType display; 34 | KeyboardFuncType keyboard; 35 | MouseButtonFuncType button; 36 | MouseMotionFuncType motion; 37 | }; 38 | 39 | void process_events(); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /libwinnie/src/fbdev/event.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifdef WINNIE_FBDEV 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "event.h" 30 | #include "wm.h" 31 | #include "keyboard.h" 32 | #include "mouse.h" 33 | 34 | void process_events() 35 | { 36 | int keyb_fd = get_keyboard_fd(); 37 | int mouse_fd = get_mouse_fd(); 38 | 39 | for(;;) { 40 | wm->process_windows(); 41 | 42 | fd_set read_set; 43 | 44 | FD_ZERO(&read_set); 45 | FD_SET(keyb_fd, &read_set); 46 | FD_SET(mouse_fd, &read_set); 47 | 48 | int maxfd = keyb_fd > mouse_fd ? keyb_fd : mouse_fd; 49 | 50 | while(select(maxfd + 1, &read_set, 0, 0, 0) == -1 && errno == EINTR); 51 | 52 | if(FD_ISSET(keyb_fd, &read_set)) { 53 | process_keyboard_event(); 54 | } 55 | if(FD_ISSET(mouse_fd, &read_set)) { 56 | process_mouse_event(); 57 | } 58 | } 59 | } 60 | #endif // WINNIE_FBDEV 61 | -------------------------------------------------------------------------------- /libwinnie/src/fbdev/gfx.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifdef WINNIE_FBDEV 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #include "gfx.h" 38 | #include "shalloc.h" 39 | #include "winnie.h" 40 | 41 | #define FRAMEBUFFER_SIZE(xsz, ysz, bpp) ((xsz) * (ysz) * (bpp) / CHAR_BIT) 42 | 43 | static unsigned char *framebuffer; 44 | static int dev_fd; 45 | static int rgb_order[3]; 46 | 47 | struct Graphics { 48 | Rect screen_rect; 49 | Rect clipping_rect; 50 | int color_depth; 51 | Pixmap *pixmap; 52 | }; 53 | 54 | static Graphics *gfx; 55 | 56 | bool init_gfx() 57 | { 58 | if(!(gfx = (Graphics*)sh_malloc(sizeof *gfx))) { 59 | return false; 60 | } 61 | 62 | get_subsys()->graphics_offset = (int)((char*)gfx - (char*)get_pool()); 63 | 64 | dev_fd = -1; 65 | 66 | if((dev_fd = open("/dev/fb0", O_RDWR)) == -1) { 67 | fprintf(stderr, "Cannot open /dev/fb0 : %s\n", strerror(errno)); 68 | return false; 69 | } 70 | 71 | fb_var_screeninfo sinfo; 72 | if(ioctl(dev_fd, FBIOGET_VSCREENINFO, &sinfo) == -1) { 73 | close(dev_fd); 74 | dev_fd = -1; 75 | fprintf(stderr, "Unable to get screen info : %s\n", strerror(errno)); 76 | return false; 77 | } 78 | 79 | printf("width : %d height : %d\n : bpp : %d\n", sinfo.xres, sinfo.yres, sinfo.bits_per_pixel); 80 | printf("virtual w: %d virtual h: %d\n", sinfo.xres_virtual, sinfo.yres_virtual); 81 | 82 | gfx->screen_rect.x = gfx->screen_rect.y = 0; 83 | gfx->screen_rect.width = sinfo.xres_virtual; 84 | gfx->screen_rect.height = sinfo.yres_virtual; 85 | gfx->color_depth = sinfo.bits_per_pixel; 86 | 87 | rgb_order[0] = sinfo.red.offset / 8; 88 | rgb_order[1] = sinfo.green.offset / 8; 89 | rgb_order[2] = sinfo.blue.offset / 8; 90 | 91 | set_clipping_rect(gfx->screen_rect); 92 | 93 | int sz = FRAMEBUFFER_SIZE(gfx->screen_rect.width, gfx->screen_rect.height, gfx->color_depth); 94 | framebuffer = (unsigned char*)mmap(0, sz, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0); 95 | 96 | if(framebuffer == (void*)-1) { 97 | close(dev_fd); 98 | dev_fd = -1; 99 | fprintf(stderr, "Cannot map the framebuffer to memory : %s\n", strerror(errno)); 100 | return false; 101 | } 102 | 103 | // TODO: uncomment when I find how to use intelfb instead of i915 GRRRR.- 104 | fb_vblank vblank; 105 | if(ioctl(dev_fd, FBIOGET_VBLANK, &vblank) == -1) { 106 | // fprintf(stderr, "FBIOGET_VBLANK error: %s\n", strerror(errno)); 107 | } 108 | /* 109 | else { 110 | printf("flags: %x\n", vblank.flags); 111 | printf("count: %d\n", vblank.count); 112 | printf("beam position: %d, %d\n", vblank.hcount, vblank.vcount); 113 | } 114 | */ 115 | 116 | if(!(gfx->pixmap = (Pixmap*)sh_malloc(sizeof(Pixmap)))) { 117 | fprintf(stderr, "Failed to allocate pixmap.\n"); 118 | return false; 119 | } 120 | 121 | gfx->pixmap->width = gfx->screen_rect.width; 122 | gfx->pixmap->height = gfx->screen_rect.height; 123 | 124 | int fbsize = gfx->pixmap->width * gfx->pixmap->height * gfx->color_depth / 8; 125 | if(!(gfx->pixmap->pixels = (unsigned char*)sh_malloc(fbsize))) { 126 | fprintf(stderr, "failed to allocate the pixmap framebuffer.\n"); 127 | return false; 128 | } 129 | 130 | return true; 131 | } 132 | 133 | void destroy_gfx() 134 | { 135 | clear_screen(0, 0, 0); 136 | gfx_update(gfx->screen_rect); 137 | 138 | if(dev_fd != -1) { 139 | close(dev_fd); 140 | } 141 | 142 | dev_fd = -1; 143 | 144 | munmap(framebuffer, FRAMEBUFFER_SIZE(gfx->screen_rect.width, gfx->screen_rect.height, gfx->color_depth)); 145 | framebuffer = 0; 146 | 147 | sh_free(gfx->pixmap->pixels); 148 | gfx->pixmap->pixels = 0; 149 | sh_free(gfx->pixmap); 150 | sh_free(gfx); 151 | } 152 | 153 | bool client_open_gfx(void *smem_start, int offset) 154 | { 155 | gfx = (Graphics*)((unsigned char*)smem_start + offset); 156 | return true; 157 | } 158 | 159 | void client_close_gfx() 160 | { 161 | } 162 | 163 | unsigned char *get_framebuffer() 164 | { 165 | return gfx->pixmap->pixels; 166 | } 167 | 168 | Pixmap *get_framebuffer_pixmap() 169 | { 170 | return gfx->pixmap; 171 | } 172 | 173 | Rect get_screen_size() 174 | { 175 | return gfx->screen_rect; 176 | } 177 | 178 | int get_color_depth() 179 | { 180 | return gfx->color_depth; 181 | } 182 | 183 | void set_clipping_rect(const Rect &rect) 184 | { 185 | gfx->clipping_rect = rect_intersection(rect, get_screen_size()); 186 | } 187 | 188 | const Rect &get_clipping_rect() 189 | { 190 | return gfx->clipping_rect; 191 | } 192 | 193 | void set_cursor_visibility(bool visible) 194 | { 195 | fb_cursor curs; 196 | curs.enable = visible ? 1 : 0; 197 | 198 | if(ioctl(dev_fd, FBIO_CURSOR, &curs) == -1) { 199 | fprintf(stderr, "Cannot toggle cursor visibility : %s\n", strerror(errno)); 200 | } 201 | } 202 | 203 | void gfx_update(const Rect &upd_rect) 204 | { 205 | Rect rect = rect_intersection(upd_rect, gfx->screen_rect); 206 | unsigned char *sptr = gfx->pixmap->pixels + (rect.y * gfx->screen_rect.width + rect.x) * 4; 207 | unsigned char *dptr = framebuffer + (rect.y * gfx->screen_rect.width + rect.x) * 4; 208 | 209 | for(int i=0; iscreen_rect.width * 4; 212 | dptr += gfx->screen_rect.width * 4; 213 | } 214 | } 215 | 216 | void wait_vsync() 217 | { 218 | unsigned long arg = 0; 219 | if(ioctl(dev_fd, FBIO_WAITFORVSYNC, &arg) == -1) { 220 | // printf("ioctl error %s\n", strerror(errno)); 221 | } 222 | } 223 | 224 | void get_rgb_order(int *r, int *g, int *b) 225 | { 226 | *r = rgb_order[0]; 227 | *g = rgb_order[1]; 228 | *b = rgb_order[2]; 229 | } 230 | 231 | #endif // WINNIE_FBDEV 232 | -------------------------------------------------------------------------------- /libwinnie/src/fbdev/keyboard.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifdef WINNIE_FBDEV 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "keyboard.h" 34 | #include "shalloc.h" 35 | #include "window.h" 36 | #include "winnie.h" 37 | #include "wm.h" 38 | 39 | struct Keyboard { 40 | int dev_fd; 41 | enum {RAW, CANONICAL} ttystate; 42 | }; 43 | 44 | static Keyboard *keyboard; 45 | 46 | bool init_keyboard() 47 | { 48 | if(!(keyboard = (Keyboard*)sh_malloc(sizeof *keyboard))) { 49 | return false; 50 | } 51 | 52 | get_subsys()->keyboard_offset = (int)((char*)keyboard - (char*)get_pool()); 53 | 54 | keyboard->ttystate = keyboard->CANONICAL; 55 | keyboard->dev_fd = -1; 56 | 57 | if((keyboard->dev_fd = open("/dev/tty", O_RDWR)) == -1) { 58 | fprintf(stderr, "Cannot open /dev/tty : %s\n", strerror(errno)); 59 | return false; 60 | } 61 | 62 | struct termios buf; 63 | 64 | if(tcgetattr(keyboard->dev_fd, &buf) < 0) { 65 | fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno)); 66 | return false; 67 | } 68 | 69 | buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); 70 | buf.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); 71 | buf.c_cflag &= ~(CSIZE | PARENB); 72 | buf.c_cflag |= CS8; 73 | buf.c_oflag &= ~(OPOST); 74 | 75 | if(tcsetattr(keyboard->dev_fd, TCSAFLUSH, &buf) < 0) { 76 | return false; 77 | } 78 | 79 | keyboard->ttystate = keyboard->RAW; 80 | return true; 81 | } 82 | 83 | void destroy_keyboard() 84 | { 85 | struct termios buf; 86 | 87 | if(tcgetattr(keyboard->dev_fd, &buf) < 0) { 88 | fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno)); 89 | } 90 | 91 | buf.c_lflag |= (ECHO | ICANON | IEXTEN | ISIG); 92 | buf.c_iflag |= (BRKINT | ICRNL | INPCK | ISTRIP | IXON); 93 | buf.c_cflag |= (CSIZE | PARENB); 94 | buf.c_cflag &= CS8; 95 | buf.c_oflag |= (OPOST); 96 | 97 | if(tcsetattr(keyboard->dev_fd, TCSAFLUSH, &buf) < 0) { 98 | fprintf(stderr, "Cannot set the tty parameters : %s\n", strerror(errno)); 99 | } 100 | 101 | keyboard->ttystate = keyboard->CANONICAL; 102 | 103 | if(keyboard->dev_fd != -1) { 104 | close(keyboard->dev_fd); 105 | keyboard->dev_fd = -1; 106 | } 107 | 108 | sh_free(keyboard); 109 | } 110 | 111 | bool client_open_keyboard(void *smem_start, int offset) 112 | { 113 | keyboard = (Keyboard*)((unsigned char*)smem_start + offset); 114 | return true; 115 | } 116 | 117 | void client_close_keyboard() 118 | { 119 | } 120 | 121 | int get_keyboard_fd() 122 | { 123 | return keyboard->dev_fd; 124 | } 125 | 126 | void process_keyboard_event() 127 | { 128 | char key; 129 | if(read(keyboard->dev_fd, &key, 1) < 1) { 130 | return; 131 | } 132 | 133 | if(key == 'q') { 134 | exit(0); 135 | } 136 | 137 | Window *focused_win = wm->get_focused_window(); 138 | if(focused_win) { 139 | KeyboardFuncType keyb_callback = focused_win->get_keyboard_callback(); 140 | if(keyb_callback) { 141 | keyb_callback(focused_win, key, true); //TODO: true?? 142 | } 143 | } 144 | 145 | /* TODO: 146 | * - handle system-wide key combinations (alt-tab?) 147 | * - otherwise send keypress/release to focused window 148 | */ 149 | } 150 | #endif // WINNIE_FBDEV 151 | -------------------------------------------------------------------------------- /libwinnie/src/fbdev/mouse.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifdef WINNIE_FBDEV 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "geom.h" 35 | #include "gfx.h" 36 | #include "mouse.h" 37 | #include "shalloc.h" 38 | #include "window.h" 39 | #include "winnie.h" 40 | #include "wm.h" 41 | 42 | #define BN_LEFT 1 43 | #define BN_RIGHT 2 44 | #define BN_MIDDLE 4 45 | 46 | static int read_mouse(); 47 | 48 | struct Mouse { 49 | int dev_fd; 50 | Rect bounds; 51 | int pointer_x; 52 | int pointer_y; 53 | int bnstate; 54 | }; 55 | 56 | static Mouse *mouse; 57 | 58 | bool init_mouse() 59 | { 60 | if(!(mouse = (Mouse*)sh_malloc(sizeof *mouse))) { 61 | return false; 62 | } 63 | get_subsys()->mouse_offset = (int)((char*)mouse - (char*)get_pool()); 64 | memset(mouse, 0, sizeof *mouse); 65 | 66 | mouse->dev_fd = -1; 67 | 68 | if((mouse->dev_fd = open("/dev/psaux", O_RDONLY | O_NONBLOCK)) == -1) { 69 | fprintf(stderr, "Cannot open /dev/psaux : %s\n", strerror(errno)); 70 | return false; 71 | } 72 | 73 | set_mouse_bounds(get_screen_size()); 74 | return true; 75 | } 76 | 77 | void destroy_mouse() 78 | { 79 | if(mouse->dev_fd != -1) { 80 | close(mouse->dev_fd); 81 | mouse->dev_fd = -1; 82 | } 83 | sh_free(mouse); 84 | } 85 | 86 | bool client_open_mouse(void *smem_start, int offset) 87 | { 88 | mouse = (Mouse*)((unsigned char*)smem_start + offset); 89 | return true; 90 | } 91 | 92 | void client_close_mouse() 93 | { 94 | } 95 | 96 | void set_mouse_bounds(const Rect &rect) 97 | { 98 | mouse->bounds = rect; 99 | } 100 | 101 | int get_mouse_fd() 102 | { 103 | return mouse->dev_fd; 104 | } 105 | 106 | void process_mouse_event() 107 | { 108 | /* TODO: 109 | * - read all pending events from mouse fd (use O_NONBLOCK so that 110 | * read will return -1 when there are no more events instead of blocking). 111 | */ 112 | 113 | int prev_state = mouse->bnstate; 114 | int prev_x = mouse->pointer_x; 115 | int prev_y = mouse->pointer_y; 116 | 117 | if(read_mouse() == -1) { 118 | return; 119 | } 120 | 121 | Window *top; 122 | if(!(top = wm->get_grab_window())) { 123 | top = wm->get_window_at_pos(mouse->pointer_x, mouse->pointer_y); 124 | if(top) { 125 | wm->set_focused_window(top); 126 | } 127 | else { 128 | wm->set_focused_window(0); 129 | } 130 | } 131 | 132 | /* - send each pointer move and button press/release to the topmost window 133 | * with the pointer on it. 134 | */ 135 | 136 | int dx = mouse->pointer_x - prev_x; 137 | int dy = mouse->pointer_y - prev_y; 138 | 139 | if((dx || dy) && top) { 140 | MouseMotionFuncType motion_callback = top->get_mouse_motion_callback(); 141 | if(motion_callback) { 142 | Rect rect = top->get_absolute_rect(); 143 | motion_callback(top, mouse->pointer_x - rect.x, mouse->pointer_y - rect.y); 144 | } 145 | } 146 | 147 | MouseButtonFuncType button_callback; 148 | if((mouse->bnstate != prev_state) && top && (button_callback = top->get_mouse_button_callback())) { 149 | int num_bits = sizeof mouse->bnstate * CHAR_BIT; 150 | for(int i=0; ibnstate >> i) & 1; 152 | int prev_s = (prev_state >> i) & 1; 153 | if(s != prev_s) { 154 | Rect rect = top->get_absolute_rect(); 155 | button_callback(top, i, s, mouse->pointer_x - rect.x, mouse->pointer_y - rect.y); 156 | } 157 | } 158 | } 159 | } 160 | 161 | void get_pointer_pos(int *x, int *y) 162 | { 163 | *x = mouse->pointer_x; 164 | *y = mouse->pointer_y; 165 | } 166 | 167 | int get_button_state() 168 | { 169 | return mouse->bnstate; 170 | } 171 | 172 | int get_button(int bn) 173 | { 174 | if(bn < 0 || bn >= 3) { 175 | return 0; 176 | } 177 | return (mouse->bnstate & (1 << bn)) != 0; 178 | } 179 | 180 | static int read_mouse() 181 | { 182 | int rd; 183 | signed char state[3] = {0, 0, 0}; 184 | 185 | if((rd = read(mouse->dev_fd, state, 3)) == -1) { 186 | fprintf(stderr, "Unable to get mouse state : %s\n", strerror(errno)); 187 | return -1; 188 | } 189 | 190 | mouse->bnstate = state[0] & 7; 191 | mouse->pointer_x += state[1]; 192 | mouse->pointer_y -= state[2]; 193 | 194 | if(mouse->pointer_x < mouse->bounds.x) { 195 | mouse->pointer_x = mouse->bounds.x; 196 | } 197 | 198 | if(mouse->pointer_y < mouse->bounds.y) { 199 | mouse->pointer_y = mouse->bounds.y; 200 | } 201 | 202 | if(mouse->pointer_x > mouse->bounds.x + mouse->bounds.width - 1) { 203 | mouse->pointer_x = mouse->bounds.x + mouse->bounds.width - 1; 204 | } 205 | 206 | if(mouse->pointer_y > mouse->bounds.y + mouse->bounds.height - 1) { 207 | mouse->pointer_y = mouse->bounds.y + mouse->bounds.height - 1; 208 | } 209 | 210 | return 0; 211 | } 212 | #endif // WINNIE_FBDEV 213 | -------------------------------------------------------------------------------- /libwinnie/src/geom.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include "geom.h" 23 | 24 | Rect::Rect() 25 | { 26 | x = y = width = height = 0; 27 | } 28 | 29 | Rect::Rect(int x, int y, int w, int h) 30 | { 31 | this->x = x; 32 | this->y = y; 33 | width = w; 34 | height = h; 35 | } 36 | 37 | static inline int min(int x, int y) 38 | { 39 | return x < y ? x : y; 40 | } 41 | 42 | static inline int max(int x, int y) 43 | { 44 | return x > y ? x : y; 45 | } 46 | 47 | Rect rect_union(const Rect &a, const Rect &b) 48 | { 49 | Rect uni; 50 | uni.x = min(a.x, b.x); 51 | uni.y = min(a.y, b.y); 52 | uni.width = max(a.x + a.width, b.x + b.width) - uni.x; 53 | uni.height = max(a.y + a.height, b.y + b.height) - uni.y; 54 | 55 | return uni; 56 | } 57 | 58 | Rect rect_intersection(const Rect &a, const Rect &b) 59 | { 60 | Rect intersect; 61 | intersect.x = max(a.x, b.x); 62 | intersect.y = max(a.y, b.y); 63 | intersect.width = max(min(a.x + a.width, b.x + b.width) - intersect.x, 0); 64 | intersect.height = max(min(a.y + a.height, b.y + b.height) - intersect.y, 0); 65 | 66 | return intersect; 67 | } 68 | -------------------------------------------------------------------------------- /libwinnie/src/geom.h: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef GEOM_H_ 23 | #define GEOM_H_ 24 | 25 | struct Rect { 26 | int x, y; 27 | int width, height; 28 | 29 | Rect(); 30 | Rect(int x, int y, int w, int h); 31 | }; 32 | 33 | Rect rect_union(const Rect &a, const Rect &b); 34 | Rect rect_intersection(const Rect &a, const Rect &b); 35 | 36 | #endif // GEOM_H_ 37 | -------------------------------------------------------------------------------- /libwinnie/src/gfx.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include 23 | 24 | #include "geom.h" 25 | #include "gfx.h" 26 | 27 | void clear_screen(int r, int g, int b) 28 | { 29 | Rect screen_rect = get_screen_size(); 30 | fill_rect(screen_rect, r, g, b); 31 | } 32 | 33 | void fill_rect(const Rect &rect, int r, int g, int b) 34 | { 35 | Rect drect = rect; 36 | Rect screen_rect = get_screen_size(); 37 | Rect clipping_rect = get_clipping_rect(); 38 | 39 | if(drect.x < clipping_rect.x) { 40 | drect.width -= clipping_rect.x - drect.x; 41 | drect.x = clipping_rect.x; 42 | } 43 | 44 | if(drect.y < clipping_rect.y) { 45 | drect.height -= clipping_rect.y - drect.y; 46 | drect.y = clipping_rect.y; 47 | } 48 | 49 | if(drect.x + drect.width >= clipping_rect.x + clipping_rect.width) { 50 | drect.width = clipping_rect.width + clipping_rect.x - drect.x; 51 | } 52 | 53 | if(drect.y + drect.height >= clipping_rect.y + clipping_rect.height) { 54 | drect.height = clipping_rect.height + clipping_rect.y - drect.y; 55 | } 56 | 57 | unsigned char *fb = get_framebuffer() + (drect.x + screen_rect.width * drect.y) * 4; 58 | for(int i=0; i= irect.width) { 93 | width -= xend - irect.width; 94 | } 95 | 96 | int yend = dest_y + height; 97 | if(yend >= irect.height) { 98 | height -= yend - irect.height; 99 | } 100 | 101 | if(width <= 0 || height <= 0) { 102 | return; 103 | } 104 | 105 | unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4; 106 | unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4; 107 | 108 | for(int i=0; i= irect.width) { 144 | width -= xend - irect.width; 145 | } 146 | 147 | int yend = dest_y + height; 148 | if(yend >= irect.height) { 149 | height -= yend - irect.height; 150 | } 151 | 152 | if(width <= 0 || height <= 0) { 153 | return; 154 | } 155 | 156 | unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4; 157 | unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4; 158 | 159 | for(int i=0; i. 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef GFX_H_ 23 | #define GFX_H_ 24 | 25 | #include "geom.h" 26 | #include "pixmap.h" 27 | 28 | bool init_gfx(); 29 | void destroy_gfx(); 30 | 31 | bool client_open_gfx(void *smem_start, int offset); 32 | void client_close_gfx(); 33 | 34 | unsigned char *get_framebuffer(); 35 | Pixmap *get_framebuffer_pixmap(); 36 | 37 | Rect get_screen_size(); 38 | int get_color_depth(); 39 | 40 | void set_clipping_rect(const Rect &clip_rect); 41 | const Rect &get_clipping_rect(); 42 | 43 | void clear_screen(int r, int g, int b); 44 | void fill_rect(const Rect &rect, int r, int g, int b); 45 | 46 | void set_cursor_visibility(bool visible); 47 | 48 | void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img, 49 | const Rect &dest_rect, int dest_x, int dest_y); 50 | 51 | void blit_key(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img, 52 | const Rect &dest_rect, int dest_x, int dest_y, int key_r, int key_g, int key_b); 53 | 54 | void gfx_update(const Rect &rect); 55 | 56 | void wait_vsync(); // vertical synchronization 57 | 58 | void get_rgb_order(int *r, int *g, int *b); 59 | 60 | #endif //GFX_H_ 61 | -------------------------------------------------------------------------------- /libwinnie/src/keyboard.h: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef KEYBOARD_H_ 23 | #define KEYBOARD_H_ 24 | 25 | bool init_keyboard(); 26 | void destroy_keyboard(); 27 | 28 | bool client_open_keyboard(void *smem_start, int offset); 29 | void client_close_keyboard(); 30 | 31 | int get_keyboard_fd(); 32 | void process_keyboard_event(); 33 | 34 | #endif // KEYBOARD_H_ 35 | -------------------------------------------------------------------------------- /libwinnie/src/mouse.h: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef MOUSE_H_ 23 | #define MOUSE_H_ 24 | 25 | struct Rect; 26 | 27 | bool init_mouse(); 28 | void destroy_mouse(); 29 | 30 | bool client_open_mouse(void *smem_start, int offset); 31 | void client_close_mouse(); 32 | 33 | void set_mouse_bounds(const Rect &rect); 34 | 35 | int get_mouse_fd(); 36 | void process_mouse_event(); 37 | 38 | void get_pointer_pos(int *x, int *y); 39 | int get_button_state(); 40 | int get_button(int bn); 41 | 42 | #endif // MOUSE_H_ 43 | -------------------------------------------------------------------------------- /libwinnie/src/mouse_cursor.h: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef MOUSE_CURSOR_H_ 23 | #define MOUSE_CURSOR_H_ 24 | 25 | const int mouse_cursor_width = 8; 26 | const int mouse_cursor_height = 16; 27 | 28 | const int mouse_cursor_bw[] = { 29 | 128, 128, 0, 0, 0, 0, 0, 0, 30 | 128, 255, 128, 0, 0, 0, 0, 0, 31 | 128, 255, 255, 128, 0, 0, 0, 0, 32 | 128, 255, 255, 255, 128, 0, 0, 0, 33 | 128, 255, 255, 255, 255, 128, 0, 0, 34 | 128, 255, 255, 255, 255, 255, 128, 0, 35 | 128, 255, 255, 255, 255, 255, 255, 128, 36 | 128, 255, 255, 255, 255, 255, 128, 0, 37 | 128, 255, 255, 255, 255, 128, 0, 0, 38 | 128, 255, 255, 255, 255, 128, 0, 0, 39 | 128, 255, 255, 255, 255, 255, 128, 0, 40 | 128, 255, 255, 255, 255, 255, 128, 0, 41 | 128, 255, 128, 128, 255, 255, 255, 128, 42 | 128, 128, 0, 128, 255, 255, 255, 128, 43 | 128, 0, 0, 0, 128, 255, 255, 128, 44 | 0, 0, 0, 0, 0, 128, 128, 128 45 | }; 46 | 47 | 48 | 49 | #endif // MOUSE_CURSOR_H_ 50 | -------------------------------------------------------------------------------- /libwinnie/src/pixmap.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include "pixmap.h" 26 | 27 | Pixmap::Pixmap() 28 | { 29 | width = height = 0; 30 | pixels = 0; 31 | } 32 | 33 | Pixmap::Pixmap(const Pixmap &pixmap) 34 | { 35 | width = height = 0; 36 | pixels = 0; 37 | set_image(pixmap.width, pixmap.height, pixmap.pixels); 38 | } 39 | 40 | Pixmap &Pixmap::operator=(const Pixmap &pixmap) 41 | { 42 | if(this != &pixmap) { 43 | set_image(pixmap.width, pixmap.height, pixmap.pixels); 44 | } 45 | 46 | return *this; 47 | } 48 | 49 | Pixmap::~Pixmap() 50 | { 51 | if(pixels) { 52 | delete [] pixels; 53 | } 54 | } 55 | 56 | int Pixmap::get_width() const 57 | { 58 | return width; 59 | } 60 | 61 | int Pixmap::get_height() const 62 | { 63 | return height; 64 | } 65 | 66 | Rect Pixmap::get_rect() const 67 | { 68 | Rect rect(0, 0, width, height); 69 | return rect; 70 | } 71 | 72 | bool Pixmap::set_image(int x, int y, unsigned char *pix) 73 | { 74 | delete [] pixels; 75 | 76 | pixels = new unsigned char[x * y * 4]; 77 | width = x; 78 | height = y; 79 | 80 | if(pix) { 81 | memcpy(pixels, pix, x * y * 4); 82 | } 83 | return true; 84 | } 85 | 86 | const unsigned char *Pixmap::get_image() const 87 | { 88 | return pixels; 89 | } 90 | 91 | unsigned char *Pixmap::get_image() 92 | { 93 | return pixels; 94 | } 95 | 96 | bool Pixmap::load(const char *fname) 97 | { 98 | FILE *fp; 99 | int hdrline = 0; 100 | 101 | if(!(fp = fopen(fname, "rb"))) { 102 | fprintf(stderr, "failed to open pixmap: %s: %s\n", fname, strerror(errno)); 103 | return false; 104 | } 105 | 106 | /* read ppm header */ 107 | while(hdrline < 3) { 108 | char buf[64]; 109 | 110 | if(!fgets(buf, sizeof buf, fp)) 111 | goto err; 112 | 113 | /* skip comments */ 114 | if(buf[0] == '#') 115 | continue; 116 | 117 | switch(hdrline++) { 118 | case 0: 119 | /* first header line should be P6 */ 120 | if(strcmp(buf, "P6\n") != 0) 121 | goto err; 122 | break; 123 | 124 | case 1: 125 | /* second header line contains the pixmap dimensions */ 126 | if(sscanf(buf, "%d %d", &width, &height) != 2) 127 | goto err; 128 | break; 129 | } 130 | } 131 | 132 | set_image(width, height, 0); 133 | 134 | for(int i=0; i. 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef PIXMAP_H_ 23 | #define PIXMAP_H_ 24 | 25 | #include "geom.h" 26 | 27 | class Pixmap { 28 | public: 29 | int width, height; 30 | unsigned char *pixels; 31 | 32 | Pixmap(); 33 | 34 | Pixmap(const Pixmap &pixmap); 35 | Pixmap &operator=(const Pixmap& pixmap); 36 | 37 | ~Pixmap(); 38 | 39 | int get_width() const; 40 | int get_height() const; 41 | Rect get_rect() const; 42 | 43 | bool set_image(int x, int y, unsigned char *pix = 0); 44 | const unsigned char *get_image() const; 45 | unsigned char *get_image(); 46 | 47 | bool load(const char *fname); 48 | bool save(const char *fname) const; 49 | }; 50 | 51 | #endif // PIXMAP_H_ 52 | -------------------------------------------------------------------------------- /libwinnie/src/sdl/event.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifdef WINNIE_SDL 23 | #include 24 | #include 25 | 26 | #include "event.h" 27 | #include "keyboard.h" 28 | #include "mouse.h" 29 | #include "wm.h" 30 | 31 | SDL_Event sdl_event; 32 | void process_events() 33 | { 34 | wm->process_windows(); 35 | if(!SDL_WaitEvent(&sdl_event)) { 36 | return; 37 | } 38 | 39 | switch(sdl_event.type) { 40 | case SDL_KEYDOWN: 41 | case SDL_KEYUP: 42 | process_keyboard_event(); 43 | break; 44 | case SDL_MOUSEMOTION: 45 | case SDL_MOUSEBUTTONDOWN: 46 | case SDL_MOUSEBUTTONUP: 47 | process_mouse_event(); 48 | break; 49 | case SDL_QUIT: 50 | exit(0); 51 | default: 52 | break; 53 | } 54 | } 55 | 56 | #endif // WINNIE_SDL 57 | -------------------------------------------------------------------------------- /libwinnie/src/sdl/gfx.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifdef WINNIE_SDL 23 | #include 24 | #include 25 | #include 26 | 27 | #include "gfx.h" 28 | #include "shalloc.h" 29 | #include "winnie.h" 30 | 31 | static SDL_Surface *fbsurf; 32 | 33 | struct Graphics { 34 | Rect screen_rect; 35 | Rect clipping_rect; 36 | int color_depth; // bits per pixel 37 | Pixmap *pixmap; 38 | }; 39 | 40 | static Graphics *gfx; 41 | 42 | bool init_gfx() 43 | { 44 | if(SDL_Init(SDL_INIT_VIDEO) == -1) { 45 | fprintf(stderr, "failed to initialize SDL\n"); 46 | return false; 47 | } 48 | 49 | if(!(gfx = (Graphics*)sh_malloc(sizeof *gfx))) { 50 | return false; 51 | } 52 | 53 | get_subsys()->graphics_offset = (int)((char*)gfx - (char*)get_pool()); 54 | 55 | Rect scr_rect(0, 0, 1024, 768); 56 | gfx->screen_rect = scr_rect; 57 | gfx->color_depth = 32; 58 | 59 | if(!(fbsurf = SDL_SetVideoMode(gfx->screen_rect.width, gfx->screen_rect.height, gfx->color_depth, 0))) { 60 | fprintf(stderr, "Failed to set video mode\n"); 61 | return false; 62 | } 63 | SDL_ShowCursor(0); 64 | 65 | if(!(gfx->pixmap = (Pixmap*)sh_malloc(sizeof(Pixmap)))) { 66 | fprintf(stderr, "Failed to allocate pixmap.\n"); 67 | return false; 68 | } 69 | 70 | gfx->pixmap->width = gfx->screen_rect.width; 71 | gfx->pixmap->height = gfx->screen_rect.height; 72 | 73 | int fbsize = gfx->pixmap->width * gfx->pixmap->height * gfx->color_depth / 8; 74 | if(!(gfx->pixmap->pixels = (unsigned char*)sh_malloc(fbsize))) { 75 | fprintf(stderr, "failed to allocate the pixmap framebuffer.\n"); 76 | return false; 77 | } 78 | 79 | set_clipping_rect(gfx->screen_rect); 80 | 81 | return true; 82 | } 83 | 84 | void destroy_gfx() 85 | { 86 | sh_free(gfx->pixmap->pixels); 87 | gfx->pixmap->pixels = 0; 88 | sh_free(gfx->pixmap); 89 | sh_free(gfx); 90 | SDL_Quit(); 91 | } 92 | 93 | bool client_open_gfx(void *smem_start, int offset) 94 | { 95 | gfx = (Graphics*)((unsigned char*)smem_start + offset); 96 | return true; 97 | } 98 | 99 | void client_close_gfx() 100 | { 101 | } 102 | 103 | unsigned char *get_framebuffer() 104 | { 105 | return gfx->pixmap->pixels; 106 | } 107 | 108 | Pixmap *get_framebuffer_pixmap() 109 | { 110 | return gfx->pixmap; 111 | } 112 | 113 | Rect get_screen_size() 114 | { 115 | return gfx->screen_rect; 116 | } 117 | 118 | int get_color_depth() 119 | { 120 | return gfx->color_depth; 121 | } 122 | 123 | void set_clipping_rect(const Rect &rect) 124 | { 125 | gfx->clipping_rect = rect_intersection(rect, get_screen_size()); 126 | } 127 | 128 | const Rect &get_clipping_rect() 129 | { 130 | return gfx->clipping_rect; 131 | } 132 | 133 | 134 | void set_cursor_visibility(bool visible) 135 | { 136 | } 137 | 138 | void gfx_update(const Rect &upd_rect) 139 | { 140 | if(SDL_MUSTLOCK(fbsurf)) { 141 | SDL_LockSurface(fbsurf); 142 | } 143 | 144 | Rect rect = rect_intersection(upd_rect, gfx->screen_rect); 145 | 146 | unsigned char *sptr = gfx->pixmap->pixels + (rect.y * gfx->screen_rect.width + rect.x) * 4; 147 | unsigned char *dptr = (unsigned char*)fbsurf->pixels + (rect.y * gfx->screen_rect.width + rect.x) * 4; 148 | 149 | for(int i=0; iscreen_rect.width * 4; 152 | dptr += gfx->screen_rect.width * 4; 153 | } 154 | 155 | if(SDL_MUSTLOCK(fbsurf)) { 156 | SDL_UnlockSurface(fbsurf); 157 | } 158 | SDL_UpdateRect(fbsurf, rect.x, rect.y, rect.width, rect.height); 159 | } 160 | 161 | void wait_vsync() 162 | { 163 | } 164 | 165 | void get_rgb_order(int *r, int *g, int *b) 166 | { 167 | *r = fbsurf->format->Rshift / 8; 168 | *g = fbsurf->format->Gshift / 8; 169 | *b = fbsurf->format->Bshift / 8; 170 | } 171 | 172 | #endif // WINNIE_SDL 173 | -------------------------------------------------------------------------------- /libwinnie/src/sdl/keyboard.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifdef WINNIE_SDL 23 | #include 24 | 25 | #include "keyboard.h" 26 | #include "window.h" 27 | #include "wm.h" 28 | 29 | extern SDL_Event sdl_event; 30 | 31 | bool init_keyboard() 32 | { 33 | return true; 34 | } 35 | 36 | void destroy_keyboard() 37 | { 38 | } 39 | 40 | bool client_open_keyboard(void *smem_start, int offset) 41 | { 42 | return true; 43 | } 44 | 45 | void client_close_keyboard() 46 | { 47 | } 48 | 49 | int get_keyboard_fd() 50 | { 51 | return -1; 52 | } 53 | 54 | void process_keyboard_event() 55 | { 56 | int key = sdl_event.key.keysym.sym; 57 | 58 | Window *focused_win = wm->get_focused_window(); 59 | if(focused_win) { 60 | KeyboardFuncType keyb_callback = focused_win->get_keyboard_callback(); 61 | if(keyb_callback) { 62 | bool pressed = sdl_event.key.state == SDL_PRESSED; 63 | keyb_callback(focused_win, key, pressed); 64 | } 65 | } 66 | } 67 | #endif // WINNIE_SDL 68 | -------------------------------------------------------------------------------- /libwinnie/src/sdl/mouse.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifdef WINNIE_SDL 23 | #include 24 | 25 | #include "mouse.h" 26 | #include "shalloc.h" 27 | #include "wm.h" 28 | #include "window.h" 29 | #include "winnie.h" 30 | 31 | extern SDL_Event sdl_event; 32 | 33 | struct Mouse { 34 | int pointer_x; 35 | int pointer_y; 36 | int bnstate; 37 | }; 38 | 39 | static Mouse *mouse; 40 | 41 | bool init_mouse() 42 | { 43 | if(!(mouse = (Mouse*)sh_malloc(sizeof *mouse))) { 44 | return false; 45 | } 46 | get_subsys()->mouse_offset = (int)((char*)mouse - (char*)get_pool()); 47 | 48 | memset(mouse, 0, sizeof *mouse); 49 | return true; 50 | } 51 | 52 | void destroy_mouse() 53 | { 54 | sh_free(mouse); 55 | } 56 | 57 | bool client_open_mouse(void *smem_start, int offset) 58 | { 59 | mouse = (Mouse*)((unsigned char*)smem_start + offset); 60 | return true; 61 | } 62 | 63 | void client_close_mouse() 64 | { 65 | } 66 | 67 | void set_mouse_bounds(const Rect &rect) 68 | { 69 | } 70 | 71 | int get_mouse_fd() 72 | { 73 | return -1; 74 | } 75 | 76 | void process_mouse_event() 77 | { 78 | int bn; 79 | MouseMotionFuncType motion_callback = 0; 80 | MouseButtonFuncType button_callback = 0; 81 | 82 | Window *win; 83 | if(!(win = wm->get_grab_window())) { 84 | win = wm->get_window_at_pos(mouse->pointer_x, mouse->pointer_y); 85 | if(win) { 86 | wm->set_focused_window(win); 87 | } 88 | else { 89 | wm->set_focused_window(0); 90 | } 91 | } 92 | 93 | switch(sdl_event.type) { 94 | case SDL_MOUSEMOTION: 95 | mouse->pointer_x = sdl_event.motion.x; 96 | mouse->pointer_y = sdl_event.motion.y; 97 | if(win && (motion_callback = win->get_mouse_motion_callback())) { 98 | Rect rect = win->get_absolute_rect(); 99 | motion_callback(win, mouse->pointer_x - rect.x, mouse->pointer_y - rect.y); 100 | } 101 | break; 102 | 103 | case SDL_MOUSEBUTTONUP: 104 | case SDL_MOUSEBUTTONDOWN: 105 | bn = sdl_event.button.button - SDL_BUTTON_LEFT; 106 | if(sdl_event.button.state == SDL_PRESSED) { 107 | mouse->bnstate |= 1 << bn; 108 | } 109 | else { 110 | mouse->bnstate &= ~(1 << bn); 111 | } 112 | if(win && (button_callback = win->get_mouse_button_callback())) { 113 | Rect rect = win->get_absolute_rect(); 114 | button_callback(win, bn, sdl_event.button.state, mouse->pointer_x - rect.x, mouse->pointer_y - rect.y); 115 | } 116 | } 117 | } 118 | 119 | void get_pointer_pos(int *x, int *y) 120 | { 121 | *x = mouse->pointer_x; 122 | *y = mouse->pointer_y; 123 | } 124 | 125 | int get_button_state() 126 | { 127 | return mouse->bnstate; 128 | } 129 | 130 | int get_button(int bn) 131 | { 132 | if(bn < 0 || bn >= 3) { 133 | return 0; 134 | } 135 | return (mouse->bnstate & (1 << bn)) != 0; 136 | } 137 | #endif // WINNIE_SDL 138 | -------------------------------------------------------------------------------- /libwinnie/src/semaphore.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include "semaphore.h" 23 | -------------------------------------------------------------------------------- /libwinnie/src/semaphore.h: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef SEMAPHORE_H_ 23 | #define SEMAPHORE_H_ 24 | 25 | bool init_semaphore(); 26 | void destroy_semaphore(); 27 | 28 | #endif // SEMAPHORE_H_ 29 | -------------------------------------------------------------------------------- /libwinnie/src/shalloc.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #include "shalloc.h" 37 | 38 | #define BLOCK_SIZE 512 39 | 40 | #define NUM_BLOCKS (POOL_SIZE / BLOCK_SIZE) 41 | #define BITMAP_SIZE (NUM_BLOCKS / 32) 42 | 43 | static bool is_allocated(int block_number); 44 | static int addr_to_block(unsigned char *addr); 45 | static unsigned char *block_to_addr(int block_number); 46 | static void alloc_blocks(int block_pos, int num_blocks); 47 | static void free_blocks(int block_pos, int num_blocks); 48 | 49 | static void print_stats(); 50 | static int fd; 51 | 52 | static unsigned char *pool; 53 | static std::map alloc_sizes; //starting block -> number of blocks 54 | 55 | // 0 means not allocated 1 means allocated 56 | static uint32_t bitmap[BITMAP_SIZE]; 57 | 58 | struct Statistics { 59 | int alloc_num; 60 | int free_num; 61 | int alloc_memsize; 62 | int free_memsize; 63 | }; 64 | 65 | static Statistics stats; 66 | 67 | bool init_shared_memory() 68 | { 69 | if(((fd = shm_open(SHMNAME, O_RDWR | O_CREAT, S_IRWXU)) == -1)) { 70 | fprintf(stderr, "Failed to open shared memory: %s\n", strerror(errno)); 71 | return false; 72 | } 73 | ftruncate(fd, POOL_SIZE); 74 | 75 | if((pool = (unsigned char*)mmap(0, POOL_SIZE, PROT_READ | PROT_WRITE, 76 | MAP_SHARED, fd, 0)) == (void*)-1) { 77 | fprintf(stderr, "Failed to map shared memory: %s\n", strerror(errno)); 78 | } 79 | 80 | for(int i=0; i::iterator it; 133 | if((it = alloc_sizes.find(block)) != alloc_sizes.end()) { 134 | int num_blocks = it->second; 135 | free_blocks(block, num_blocks); 136 | alloc_sizes.erase(it); 137 | } 138 | else { 139 | fprintf(stderr, "Attempt to free non-existent blocks from: %d\n", block); 140 | } 141 | } 142 | 143 | void *get_pool() 144 | { 145 | return (void*)pool; 146 | } 147 | 148 | static bool is_allocated(int block_number) 149 | { 150 | int idx = block_number / 32; 151 | int bit_num = block_number % 32; 152 | 153 | if((bitmap[idx] >> bit_num) & 1) { 154 | return true; 155 | } 156 | 157 | return false; 158 | } 159 | 160 | static int addr_to_block(unsigned char *addr) 161 | { 162 | assert(addr >= pool); 163 | assert(addr < pool + POOL_SIZE); 164 | 165 | return (addr - pool) / BLOCK_SIZE; 166 | } 167 | 168 | static unsigned char *block_to_addr(int block_number) 169 | { 170 | assert(block_number >= 0); 171 | assert(block_number < NUM_BLOCKS); 172 | 173 | return pool + block_number * BLOCK_SIZE; 174 | } 175 | 176 | static void alloc_blocks(int block_pos, int num_blocks) 177 | { 178 | for(int i=0; i. 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef SHALLOC_H_ 23 | #define SHALLOC_H_ 24 | 25 | #include 26 | 27 | #define POOL_SIZE 16777216 28 | #define SHMNAME "/winnie.shm" 29 | 30 | bool init_shared_memory(); 31 | void destroy_shared_memory(); 32 | 33 | void *sh_malloc(size_t bytes); 34 | void sh_free(void *ptr); 35 | 36 | void *get_pool(); 37 | 38 | #endif // SHALLOC_H_ 39 | -------------------------------------------------------------------------------- /libwinnie/src/text.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "gfx.h" 26 | #include "shalloc.h" 27 | #include "text.h" 28 | #include "winnie.h" 29 | 30 | #define DPI 72 31 | #define FONT_PATH "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf" 32 | #define FONT_SIZE 16 33 | 34 | static int draw_glyph(Pixmap *pixmap, int x, int y, char c); 35 | 36 | struct Text { 37 | FT_Library ft_lib; 38 | FT_Face ft_face; 39 | int text_x, text_y; 40 | int text_color[3]; 41 | }; 42 | 43 | static Text *text; 44 | 45 | bool init_text() 46 | { 47 | if(!(text = (Text*)sh_malloc(sizeof *text))) { 48 | return false; 49 | } 50 | 51 | get_subsys()->text_offset = (int)((char*)text - (char*)get_pool()); 52 | 53 | if(FT_Init_FreeType(&text->ft_lib)) { 54 | fprintf(stderr, "Failed to initialize the FreeType library!\n"); 55 | return false; 56 | } 57 | 58 | if(FT_New_Face(text->ft_lib, FONT_PATH, 0, &text->ft_face)) { 59 | fprintf(stderr, "Failed to load font: %s\n", FONT_PATH); 60 | return false; 61 | } 62 | 63 | if(FT_Set_Char_Size(text->ft_face, 0, FONT_SIZE * 64, DPI, DPI)) { 64 | fprintf(stderr, "Failed to set font size\n"); 65 | return false; 66 | } 67 | 68 | set_text_color(255, 255, 255); 69 | 70 | return true; 71 | } 72 | 73 | void destroy_text() 74 | { 75 | sh_free(text); 76 | } 77 | 78 | bool client_open_text(void *smem_start, int offset) 79 | { 80 | text = (Text*)((unsigned char*)smem_start + offset); 81 | return true; 82 | } 83 | 84 | void client_close_text() 85 | { 86 | } 87 | 88 | void draw_text(const char *txt, Pixmap *pixmap) 89 | { 90 | if(!pixmap) { 91 | pixmap = get_framebuffer_pixmap(); 92 | } 93 | 94 | while(*txt != 0) { 95 | text->text_x += draw_glyph(pixmap, text->text_x, text->text_y, *txt); 96 | txt++; 97 | } 98 | } 99 | 100 | void set_text_position(int x, int y) 101 | { 102 | text->text_x = x; 103 | text->text_y = y; 104 | 105 | } 106 | 107 | void set_text_color(int r, int g, int b) 108 | { 109 | text->text_color[0] = r; 110 | text->text_color[1] = g; 111 | text->text_color[2] = b; 112 | } 113 | 114 | static int draw_glyph(Pixmap *pixmap, int x, int y, char c) 115 | { 116 | if(FT_Load_Char(text->ft_face, c, FT_LOAD_RENDER)) { 117 | return 0; 118 | } 119 | 120 | x += text->ft_face->glyph->bitmap_left; 121 | y -= text->ft_face->glyph->bitmap_top; 122 | 123 | FT_Bitmap *ft_bmp = &text->ft_face->glyph->bitmap; 124 | unsigned char *bmp_ptr = ft_bmp->buffer; 125 | unsigned char *pxm_ptr = pixmap->get_image() + (pixmap->get_width() * y + x) * 4; 126 | 127 | Rect clipping_rect = get_clipping_rect(); 128 | 129 | for(int i=0; irows; i++) { 130 | int dest_y = i + y; 131 | if(dest_y >= clipping_rect.y + clipping_rect.height) { 132 | break; 133 | } 134 | 135 | if(dest_y >= clipping_rect.y) { 136 | for(int j=0; jwidth; j++) { 137 | int dest_x = j + x; 138 | 139 | if(dest_x >= clipping_rect.x + clipping_rect.width) { 140 | break; 141 | } 142 | 143 | if(bmp_ptr[j] && dest_x >= clipping_rect.x) { 144 | int a = (int)bmp_ptr[j]; 145 | pxm_ptr[4 * j] = (a * text->text_color[0] + pxm_ptr[4 * j] * (255 - a)) / 255; 146 | pxm_ptr[4 * j + 1] = (a * text->text_color[1] + pxm_ptr[4 * j + 1] * (255 - a)) / 255; 147 | pxm_ptr[4 * j + 2] = (a * text->text_color[2] + pxm_ptr[4 * j + 2] * (255 - a)) / 255; 148 | } 149 | } 150 | } 151 | 152 | pxm_ptr += 4 * pixmap->get_width(); 153 | bmp_ptr += ft_bmp->pitch; 154 | } 155 | 156 | return text->ft_face->glyph->advance.x >> 6; 157 | } 158 | -------------------------------------------------------------------------------- /libwinnie/src/text.h: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef TEXT_H_ 23 | #define TEXT_H_ 24 | 25 | bool init_text(); 26 | void destroy_text(); 27 | 28 | bool client_open_text(void *smem_start, int offset); 29 | void client_close_text(); 30 | 31 | void draw_text(const char *txt, Pixmap *pixmap = 0); 32 | void set_text_position(int x, int y); 33 | void set_text_color(int r, int g, int b); 34 | 35 | #endif // TEXT_H_ 36 | -------------------------------------------------------------------------------- /libwinnie/src/window.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include 23 | #include //TODO 24 | #include 25 | 26 | #include "gfx.h" 27 | #include "window.h" 28 | #include "wm.h" 29 | 30 | Window::Window() 31 | { 32 | parent = 0; 33 | title = 0; 34 | rect.x = rect.y = 0; 35 | rect.width = rect.height = 128; 36 | memset(&callbacks, 0, sizeof callbacks); 37 | dirty = true; 38 | managed = true; 39 | focusable = true; 40 | state = STATE_NORMAL; 41 | } 42 | 43 | Window::~Window() 44 | { 45 | for(size_t i=0; iremove_window(children[i]); 47 | delete children[i]; 48 | } 49 | 50 | delete [] title; 51 | } 52 | 53 | const Rect &Window::get_rect() const 54 | { 55 | return rect; 56 | } 57 | 58 | Rect Window::get_absolute_rect() const 59 | { 60 | if(!parent) { 61 | return rect; 62 | } 63 | 64 | Rect absolute_rect; 65 | absolute_rect = parent->get_absolute_rect(); 66 | 67 | absolute_rect.x += rect.x; 68 | absolute_rect.y += rect.y; 69 | absolute_rect.width = rect.width; 70 | absolute_rect.height = rect.height; 71 | 72 | return absolute_rect; 73 | } 74 | 75 | bool Window::contains_point(int ptr_x, int ptr_y) 76 | { 77 | Rect abs_rect = get_absolute_rect(); 78 | return ptr_x >= abs_rect.x && ptr_x < abs_rect.x + abs_rect.width && 79 | ptr_y >= abs_rect.y && ptr_y < abs_rect.y + abs_rect.height; 80 | } 81 | 82 | void Window::move(int x, int y) 83 | { 84 | invalidate(); // moved, should redraw, MUST BE CALLED FIRST 85 | rect.x = x; 86 | rect.y = y; 87 | } 88 | 89 | void Window::resize(int x, int y) 90 | { 91 | invalidate(); // resized, should redraw, MUST BE CALLED FIRST 92 | rect.width = x; 93 | rect.height = y; 94 | } 95 | 96 | void Window::set_title(const char *s) 97 | { 98 | delete [] title; 99 | 100 | title = new char[strlen(s) + 1]; 101 | strcpy(title, s); 102 | } 103 | 104 | const char *Window::get_title() const 105 | { 106 | return title; 107 | } 108 | 109 | void Window::invalidate() 110 | { 111 | dirty = true; 112 | Rect abs_rect = get_absolute_rect(); 113 | wm->invalidate_region(abs_rect); 114 | } 115 | 116 | void Window::draw(Rect *dirty_region) 117 | { 118 | Rect abs_rect = get_absolute_rect(); 119 | Rect intersect = rect_intersection(abs_rect, *dirty_region); 120 | if(intersect.width && intersect.height) { 121 | Rect prev_clip = get_clipping_rect(); 122 | set_clipping_rect(abs_rect); 123 | 124 | if(callbacks.display) { 125 | callbacks.display(this); 126 | } 127 | dirty = false; 128 | 129 | draw_children(abs_rect); 130 | 131 | *dirty_region = rect_union(*dirty_region, abs_rect); 132 | set_clipping_rect(prev_clip); 133 | } 134 | } 135 | 136 | void Window::draw_children(const Rect &dirty_region) 137 | { 138 | Rect drect = dirty_region; 139 | for(size_t i=0; idraw(&drect); 141 | } 142 | } 143 | 144 | unsigned char *Window::get_win_start_on_fb() 145 | { 146 | unsigned char *fb = get_framebuffer(); 147 | Rect abs_rect = get_absolute_rect(); 148 | return fb + get_color_depth() * (get_screen_size().x * abs_rect.y + abs_rect.x) / 8; 149 | } 150 | 151 | int Window::get_scanline_width() 152 | { 153 | return get_screen_size().x; 154 | } 155 | 156 | void Window::set_managed(bool managed) 157 | { 158 | this->managed = managed; 159 | } 160 | 161 | bool Window::get_managed() const 162 | { 163 | return managed; 164 | } 165 | 166 | void Window::set_focusable(bool focusable) 167 | { 168 | this->focusable = focusable; 169 | } 170 | 171 | bool Window::get_focusable() const 172 | { 173 | return focusable; 174 | } 175 | 176 | bool Window::get_dirty() const 177 | { 178 | return dirty; 179 | } 180 | 181 | void Window::set_display_callback(DisplayFuncType func) 182 | { 183 | callbacks.display = func; 184 | } 185 | 186 | void Window::set_keyboard_callback(KeyboardFuncType func) 187 | { 188 | callbacks.keyboard = func; 189 | } 190 | 191 | void Window::set_mouse_button_callback(MouseButtonFuncType func) 192 | { 193 | callbacks.button = func; 194 | } 195 | 196 | void Window::set_mouse_motion_callback(MouseMotionFuncType func) 197 | { 198 | callbacks.motion = func; 199 | } 200 | 201 | const DisplayFuncType Window::get_display_callback() const 202 | { 203 | return callbacks.display; 204 | } 205 | 206 | const KeyboardFuncType Window::get_keyboard_callback() const 207 | { 208 | return callbacks.keyboard; 209 | } 210 | 211 | const MouseButtonFuncType Window::get_mouse_button_callback() const 212 | { 213 | return callbacks.button; 214 | } 215 | 216 | const MouseMotionFuncType Window::get_mouse_motion_callback() const 217 | { 218 | return callbacks.motion; 219 | } 220 | 221 | void Window::add_child(Window *win) 222 | { 223 | children.push_back(win); 224 | if(win->parent) { 225 | win->parent->remove_child(win); 226 | } 227 | win->parent = this; 228 | } 229 | 230 | void Window::remove_child(Window *win) 231 | { 232 | std::vector::iterator it; 233 | it = std::find(children.begin(), children.end(), win); 234 | if(it != children.end()) { 235 | children.erase(it); 236 | win->parent = 0; 237 | } 238 | } 239 | 240 | Window **Window::get_children() 241 | { 242 | if(children.empty()) { 243 | return 0; 244 | } 245 | return &children[0]; 246 | } 247 | 248 | int Window::get_children_count() const 249 | { 250 | return (int)children.size(); 251 | } 252 | 253 | const Window *Window::get_parent() const 254 | { 255 | return parent; 256 | } 257 | 258 | Window *Window::get_parent() 259 | { 260 | return parent; 261 | } 262 | 263 | void Window::set_state(State state) 264 | { 265 | this->state = state; 266 | } 267 | 268 | Window::State Window::get_state() const 269 | { 270 | return state; 271 | } 272 | -------------------------------------------------------------------------------- /libwinnie/src/window.h: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef WINDOW_H_ 23 | #define WINDOW_H_ 24 | 25 | #include 26 | 27 | #include "geom.h" 28 | #include "event.h" 29 | 30 | class Window { 31 | public: 32 | enum State {STATE_NORMAL, STATE_MINIMIZED, STATE_MAXIMIZED, STATE_SHADED}; 33 | 34 | private: 35 | char *title; 36 | State state; 37 | 38 | Rect rect; 39 | Rect normal_rect; // normal state rectangle managed by the wm 40 | 41 | Callbacks callbacks; 42 | 43 | std::vector children; 44 | Window* parent; 45 | 46 | bool dirty; 47 | bool managed; // whether the wm manages (+decorates) this win 48 | bool focusable; 49 | 50 | public: 51 | Window(); 52 | ~Window(); 53 | 54 | const Rect &get_rect() const; 55 | Rect get_absolute_rect() const; 56 | bool contains_point(int ptr_x, int ptr_y); 57 | 58 | void move(int x, int y); 59 | void resize(int x, int y); 60 | 61 | void set_title(const char *s); 62 | const char *get_title() const; 63 | 64 | /* mark this window as dirty, and notify the window manager 65 | * to repaint it, and anything it used to cover. 66 | */ 67 | void invalidate(); 68 | 69 | void draw(Rect *dirty_region); 70 | void draw_children(const Rect &dirty_region); 71 | 72 | unsigned char *get_win_start_on_fb(); 73 | int get_scanline_width(); 74 | 75 | void set_managed(bool managed); 76 | bool get_managed() const; 77 | 78 | void set_focusable(bool focusable); 79 | bool get_focusable() const; 80 | 81 | bool get_dirty() const; 82 | 83 | void set_display_callback(DisplayFuncType func); 84 | void set_keyboard_callback(KeyboardFuncType func); 85 | void set_mouse_button_callback(MouseButtonFuncType func); 86 | void set_mouse_motion_callback(MouseMotionFuncType func); 87 | 88 | const DisplayFuncType get_display_callback() const; 89 | const KeyboardFuncType get_keyboard_callback() const; 90 | const MouseButtonFuncType get_mouse_button_callback() const; 91 | const MouseMotionFuncType get_mouse_motion_callback() const; 92 | 93 | // win hierarchy 94 | void add_child(Window *win); 95 | void remove_child(Window *win); 96 | 97 | Window **get_children(); 98 | int get_children_count() const; 99 | 100 | const Window *get_parent() const; 101 | Window *get_parent(); 102 | 103 | void set_state(State state); 104 | State get_state() const; 105 | 106 | // XXX remove if not needed 107 | friend class WindowManager; 108 | }; 109 | 110 | #endif // WINDOW_H_ 111 | -------------------------------------------------------------------------------- /libwinnie/src/winnie.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "keyboard.h" 32 | #include "mouse.h" 33 | #include "shalloc.h" 34 | #include "winnie.h" 35 | 36 | static Subsys *subsys; 37 | 38 | bool winnie_init() 39 | { 40 | if(!init_shared_memory()) { 41 | return false; 42 | } 43 | 44 | if(!(subsys = (Subsys*)sh_malloc(sizeof *subsys))) { 45 | return false; 46 | } 47 | 48 | if(!init_gfx()) { 49 | return false; 50 | } 51 | 52 | if(!init_window_manager()) { 53 | return false; 54 | } 55 | 56 | if(!init_keyboard()) { 57 | return false; 58 | } 59 | 60 | if(!init_mouse()) { 61 | return false; 62 | } 63 | 64 | if(!init_text()) { 65 | return false; 66 | } 67 | 68 | wm->invalidate_region(get_screen_size()); 69 | return true; 70 | } 71 | 72 | void winnie_shutdown() 73 | { 74 | destroy_gfx(); 75 | destroy_keyboard(); 76 | destroy_mouse(); 77 | destroy_text(); 78 | destroy_window_manager(); 79 | 80 | sh_free(subsys); 81 | 82 | destroy_shared_memory(); 83 | } 84 | 85 | static int fd; 86 | static void *pool; 87 | 88 | bool winnie_open() 89 | { 90 | if(((fd = shm_open(SHMNAME, O_RDWR, S_IRWXU)) == -1)) { 91 | fprintf(stderr, "Failed to open shared memory: %s\n", strerror(errno)); 92 | return false; 93 | } 94 | 95 | if((pool = mmap(0, POOL_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == (void*)-1) { 96 | fprintf(stderr, "Failed to map shared memory: %s\n", strerror(errno)); 97 | return false; 98 | } 99 | 100 | subsys = (Subsys*)pool; 101 | 102 | if(!client_open_gfx(pool, subsys->graphics_offset)) { 103 | fprintf(stderr, "Failed to open graphics.\n"); 104 | return false; 105 | } 106 | 107 | if(!client_open_keyboard(pool, subsys->keyboard_offset)) { 108 | fprintf(stderr, "Failed to open keyboard.\n"); 109 | return false; 110 | } 111 | 112 | if(!client_open_mouse(pool, subsys->mouse_offset)) { 113 | fprintf(stderr, "Failed to open mouse.\n"); 114 | return false; 115 | } 116 | 117 | if(!client_open_text(pool, subsys->text_offset)) { 118 | fprintf(stderr, "Failed to open text.\n"); 119 | return false; 120 | } 121 | 122 | if(!client_open_wm(pool, subsys->wm_offset)) { 123 | fprintf(stderr, "Failed to open the window manager.\n"); 124 | return false; 125 | } 126 | 127 | return true; 128 | } 129 | 130 | void winnie_close() 131 | { 132 | client_close_gfx(); 133 | client_close_keyboard(); 134 | client_close_mouse(); 135 | client_close_text(); 136 | client_close_wm(); 137 | 138 | if(munmap(pool, POOL_SIZE) == -1) { 139 | fprintf(stderr, "Failed to unmap shared memory: %s\n", strerror(errno)); 140 | } 141 | } 142 | 143 | long winnie_get_time() 144 | { 145 | static struct timeval init_tv; 146 | struct timeval tv; 147 | 148 | gettimeofday(&tv, 0); 149 | 150 | if(!tv.tv_sec && !tv.tv_usec) { 151 | init_tv = tv; 152 | return 0; 153 | } 154 | 155 | return (tv.tv_usec - init_tv.tv_usec) / 1000 + (tv.tv_sec - init_tv.tv_sec) * 1000; 156 | } 157 | 158 | Subsys *get_subsys() 159 | { 160 | return subsys; 161 | } 162 | -------------------------------------------------------------------------------- /libwinnie/src/winnie.h: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef WINNIE_H_ 23 | #define WINNIE_H_ 24 | 25 | #include "event.h" 26 | #include "geom.h" 27 | #include "gfx.h" 28 | #include "keyboard.h" 29 | #include "mouse.h" 30 | #include "text.h" 31 | #include "window.h" 32 | #include "wm.h" 33 | 34 | struct Subsys { 35 | int graphics_offset; 36 | int keyboard_offset; 37 | int mouse_offset; 38 | int text_offset; 39 | int wm_offset; 40 | }; 41 | 42 | bool winnie_init(); 43 | void winnie_shutdown(); 44 | 45 | bool winnie_open(); 46 | void winnie_close(); 47 | 48 | long winnie_get_time(); 49 | 50 | Subsys *get_subsys(); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /libwinnie/src/wm.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include // TODO 26 | 27 | #include "gfx.h" 28 | #include "mouse.h" 29 | #include "mouse_cursor.h" 30 | #include "shalloc.h" 31 | #include "text.h" 32 | #include "window.h" 33 | #include "winnie.h" 34 | #include "wm.h" 35 | 36 | #define DCLICK_INTERVAL 400 37 | 38 | WindowManager *wm; 39 | 40 | static void display(Window *win); 41 | static void mouse(Window *win, int bn, bool pressed, int x, int y); 42 | static void motion(Window *win, int x, int y); 43 | 44 | bool init_window_manager() 45 | { 46 | void *wm_mem; 47 | if(!(wm_mem = sh_malloc(sizeof *wm))) { 48 | return false; 49 | } 50 | 51 | wm = new (wm_mem) WindowManager; 52 | 53 | get_subsys()->wm_offset = (int)((char*)wm - (char*)get_pool()); 54 | 55 | return true; 56 | } 57 | 58 | void destroy_window_manager() 59 | { 60 | wm->~WindowManager(); 61 | sh_free(wm); 62 | } 63 | 64 | 65 | bool client_open_wm(void *smem_start, int offset) 66 | { 67 | wm = (WindowManager*) ((unsigned char*)smem_start + offset); 68 | return true; 69 | } 70 | 71 | void client_close_wm() 72 | { 73 | } 74 | 75 | void WindowManager::create_frame(Window *win) 76 | { 77 | Window *frame = new Window; 78 | Window *parent = win->get_parent(); 79 | 80 | frame->set_display_callback(display); 81 | frame->set_mouse_button_callback(mouse); 82 | frame->set_mouse_motion_callback(motion); 83 | frame->set_focusable(false); 84 | frame->add_child(win); 85 | 86 | windows.push_back(frame); 87 | 88 | Rect win_rect = win->get_rect(); 89 | frame->move(win_rect.x - frame_thickness, 90 | win_rect.y - frame_thickness - titlebar_thickness); 91 | frame->resize(win_rect.width + frame_thickness * 2, 92 | win_rect.height + frame_thickness * 2 + titlebar_thickness); 93 | 94 | win->move(frame_thickness, frame_thickness + titlebar_thickness); 95 | parent->add_child(frame); 96 | } 97 | 98 | void WindowManager::destroy_frame(Window *win) 99 | { 100 | Window *frame = win->parent; 101 | if(!frame) { 102 | return; 103 | } 104 | 105 | if(grab_win == win) { 106 | release_mouse(); 107 | } 108 | 109 | std::list::iterator it; 110 | it = std::find(windows.begin(), windows.end(), frame); 111 | if(it != windows.end()) { 112 | root_win->add_child(win); 113 | windows.erase(it); 114 | delete frame; 115 | } 116 | } 117 | 118 | WindowManager::WindowManager() 119 | { 120 | if(!wm) { 121 | wm = this; 122 | } else { 123 | throw std::runtime_error("Trying to create a second instance of WindowManager!\n"); 124 | } 125 | 126 | root_win = new Window; 127 | root_win->resize(get_screen_size().width, get_screen_size().height); 128 | root_win->move(0, 0); 129 | root_win->set_managed(false); 130 | 131 | grab_win = 0; 132 | focused_win = 0; 133 | background = 0; 134 | 135 | bg_color[0] = 210; 136 | bg_color[1] = 106; 137 | bg_color[2] = 106; 138 | 139 | frame_thickness = 8; 140 | titlebar_thickness = 16; 141 | 142 | set_focused_frame_color(0, 0, 0); 143 | set_unfocused_frame_color(200, 200, 200); 144 | 145 | mouse_cursor.set_image(mouse_cursor_width, mouse_cursor_height); 146 | unsigned char *pixels = mouse_cursor.get_image(); 147 | 148 | for(int i=0; i::iterator drit = dirty_rects.begin(); 176 | Rect uni = *drit++; 177 | while(drit != dirty_rects.end()) { 178 | uni = rect_union(uni, *drit++); 179 | } 180 | dirty_rects.clear(); 181 | 182 | wait_vsync(); 183 | 184 | if(!background) { 185 | fill_rect(uni, bg_color[0], bg_color[1], bg_color[2]); 186 | } 187 | else { 188 | blit(background->pixels, Rect(0, 0, background->width, background->height), 189 | get_framebuffer(), get_screen_size(), 0, 0); 190 | } 191 | 192 | root_win->draw_children(uni); 193 | 194 | // draw mouse cursor 195 | int mouse_x, mouse_y; 196 | get_pointer_pos(&mouse_x, &mouse_y); 197 | 198 | blit_key(mouse_cursor.get_image(), mouse_cursor.get_rect(), 199 | get_framebuffer(), get_screen_size(), mouse_x, mouse_y, 200 | 0, 0, 0); 201 | 202 | Rect mouse_rect(mouse_x, mouse_y, mouse_cursor.get_width(), mouse_cursor.get_height()); 203 | invalidate_region(mouse_rect); 204 | 205 | gfx_update(uni); 206 | } 207 | 208 | void WindowManager::add_window(Window *win) 209 | { 210 | if(!win || win == root_win) { 211 | return; 212 | } 213 | 214 | root_win->add_child(win); 215 | 216 | if(windows.empty()) { 217 | focused_win = win; 218 | } 219 | 220 | if(win->get_managed()) { 221 | create_frame(win); 222 | } 223 | 224 | windows.push_back(win); 225 | } 226 | 227 | void WindowManager::remove_window(Window *win) 228 | { 229 | std::list::iterator it; 230 | it = std::find(windows.begin(), windows.end(), win); 231 | 232 | if(it != windows.end()) { 233 | windows.erase(it); 234 | } 235 | } 236 | 237 | void WindowManager::set_focused_window(Window *win) 238 | { 239 | if(win && win == focused_win) { 240 | return; 241 | } 242 | 243 | Window *parent; 244 | if(focused_win) { 245 | // invalidate the frame (if any) 246 | parent = focused_win->get_parent(); 247 | if(parent && parent != root_win) { 248 | parent->invalidate(); 249 | fill_rect(parent->get_absolute_rect(), frame_ucolor[0], frame_ucolor[1], frame_ucolor[2]); 250 | } 251 | } 252 | 253 | if(!win) { 254 | focused_win = 0; 255 | return; 256 | } 257 | 258 | if(win->get_focusable()) { 259 | focused_win = win; 260 | parent = focused_win->get_parent(); 261 | fill_rect(parent->get_absolute_rect(), frame_fcolor[0], frame_fcolor[1], frame_fcolor[2]); 262 | return; 263 | } 264 | 265 | Window **children = win->get_children(); 266 | for(int i=0; iget_children_count(); i++) { 267 | if(children[0]->get_focusable()) { 268 | set_focused_window(children[0]); 269 | fill_rect(win->get_absolute_rect(), frame_fcolor[0], frame_fcolor[1], frame_fcolor[2]); 270 | return; 271 | } 272 | } 273 | 274 | focused_win = 0; 275 | } 276 | 277 | const Window *WindowManager::get_focused_window() const 278 | { 279 | return focused_win; 280 | } 281 | 282 | Window *WindowManager::get_focused_window() 283 | { 284 | return focused_win; 285 | } 286 | 287 | Window *WindowManager::get_window_at_pos(int pointer_x, int pointer_y) 288 | { 289 | Window *root_win = wm->get_root_window(); 290 | Window **children = root_win->get_children(); 291 | for(int i=root_win->get_children_count() - 1; i>=0; i--) { 292 | if(children[i]->contains_point(pointer_x, pointer_y)) { 293 | return children[i]; 294 | } 295 | } 296 | 297 | return 0; 298 | } 299 | 300 | Window *WindowManager::get_root_window() const 301 | { 302 | return root_win; 303 | } 304 | 305 | void WindowManager::set_focused_frame_color(int r, int g, int b) 306 | { 307 | frame_fcolor[0] = r; 308 | frame_fcolor[1] = g; 309 | frame_fcolor[2] = b; 310 | } 311 | 312 | void WindowManager::get_focused_frame_color(int *r, int *g, int *b) const 313 | { 314 | *r = frame_fcolor[0]; 315 | *g = frame_fcolor[1]; 316 | *b = frame_fcolor[2]; 317 | } 318 | 319 | void WindowManager::set_unfocused_frame_color(int r, int g, int b) 320 | { 321 | frame_ucolor[0] = r; 322 | frame_ucolor[1] = g; 323 | frame_ucolor[2] = b; 324 | } 325 | 326 | void WindowManager::get_unfocused_frame_color(int *r, int *g, int *b) const 327 | { 328 | *r = frame_ucolor[0]; 329 | *g = frame_ucolor[1]; 330 | *b = frame_ucolor[2]; 331 | } 332 | 333 | void WindowManager::set_background(const Pixmap *pixmap) 334 | { 335 | if(background) { 336 | delete background; 337 | } 338 | 339 | if(pixmap) { 340 | background = new Pixmap(*pixmap); 341 | } 342 | else { 343 | background = 0; 344 | } 345 | } 346 | 347 | const Pixmap *WindowManager::get_background() const 348 | { 349 | return background; 350 | } 351 | 352 | Window *WindowManager::get_grab_window() const 353 | { 354 | return grab_win; 355 | } 356 | 357 | void WindowManager::grab_mouse(Window *win) 358 | { 359 | grab_win = win; 360 | } 361 | 362 | void WindowManager::release_mouse() 363 | { 364 | grab_win = 0; 365 | } 366 | 367 | void WindowManager::raise_window(Window *win) 368 | { 369 | if(!win) { 370 | return; 371 | } 372 | 373 | Window *parent = win->get_parent(); 374 | if(parent != root_win) { 375 | if(parent->get_parent() == root_win) { 376 | win = parent; 377 | } 378 | else { 379 | return; 380 | } 381 | } 382 | 383 | root_win->remove_child(win); 384 | root_win->add_child(win); 385 | } 386 | 387 | void WindowManager::sink_window(Window *win) 388 | { 389 | if(!win) { 390 | return; 391 | } 392 | 393 | std::list::iterator it; 394 | it = std::find(windows.begin(), windows.end(), win); 395 | if(it != windows.end()) { 396 | windows.erase(it); 397 | windows.push_front(win); 398 | } 399 | } 400 | 401 | void WindowManager::maximize_window(Window *win) 402 | { 403 | win->normal_rect = win->rect; 404 | 405 | Rect rect = get_screen_size(); 406 | 407 | Window *frame; 408 | if((frame = win->get_parent())) { 409 | frame->normal_rect = frame->rect; 410 | frame->resize(rect.width, rect.height); 411 | frame->move(rect.x, rect.y); 412 | 413 | rect.width -= frame_thickness * 2; 414 | rect.height -= frame_thickness * 2 + titlebar_thickness; 415 | } 416 | else { 417 | win->move(0, 0); 418 | } 419 | 420 | win->resize(rect.width, rect.height); 421 | win->set_state(Window::STATE_MAXIMIZED); 422 | } 423 | 424 | void WindowManager::unmaximize_window(Window *win) 425 | { 426 | win->resize(win->normal_rect.width, win->normal_rect.height); 427 | win->move(win->normal_rect.x, win->normal_rect.y); 428 | 429 | Window *frame; 430 | if((frame = win->get_parent())) { 431 | frame->resize(frame->normal_rect.width, frame->normal_rect.height); 432 | frame->move(frame->normal_rect.x, frame->normal_rect.y); 433 | } 434 | 435 | win->set_state(Window::STATE_NORMAL); 436 | } 437 | 438 | static void display(Window *win) 439 | { 440 | //frame display: 441 | Window *child = win->get_children()[0]; 442 | int r, g, b; 443 | Rect abs_rect = win->get_absolute_rect(); 444 | 445 | //TODO 5 not hardcoded 446 | set_text_position(abs_rect.x + 5, abs_rect.y + 15); 447 | set_text_color(255, 255, 255); 448 | 449 | if(child == wm->get_focused_window()) { 450 | wm->get_focused_frame_color(&r, &g, &b); 451 | fill_rect(abs_rect, r, g, b); 452 | } 453 | else { 454 | wm->get_unfocused_frame_color(&r, &g, &b); 455 | fill_rect(win->get_absolute_rect(), r, g, b); 456 | } 457 | 458 | draw_text(child->get_title()); 459 | } 460 | 461 | static int prev_x, prev_y; 462 | 463 | static void mouse(Window *win, int bn, bool pressed, int x, int y) 464 | { 465 | static long last_click = 0; 466 | 467 | if(bn == 0) { 468 | if(pressed) { 469 | wm->grab_mouse(win); 470 | wm->raise_window(win); 471 | prev_x = x; 472 | prev_y = y; 473 | } 474 | else { 475 | long time = winnie_get_time(); 476 | if((time - last_click) < DCLICK_INTERVAL) { 477 | Window *child = win->get_children()[0]; 478 | Window::State state = child->get_state(); 479 | if(state == Window::STATE_MAXIMIZED) { 480 | wm->unmaximize_window(child); 481 | } 482 | else if(state == Window::STATE_NORMAL) { 483 | wm->maximize_window(child); 484 | } 485 | } 486 | last_click = time; 487 | 488 | wm->release_mouse(); 489 | } 490 | } 491 | } 492 | 493 | static void motion(Window *win, int x, int y) 494 | { 495 | int left_bn = get_button(0); 496 | 497 | if(left_bn) { 498 | int dx = x - prev_x; 499 | int dy = y - prev_y; 500 | prev_x = x - dx; 501 | prev_y = y - dy; 502 | 503 | if(win->get_children()[0]->get_state() != Window::STATE_MAXIMIZED) { 504 | Rect rect = win->get_rect(); 505 | win->move(rect.x + dx, rect.y + dy); 506 | } 507 | } 508 | } 509 | -------------------------------------------------------------------------------- /libwinnie/src/wm.h: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #ifndef WM_H_ 23 | #define WM_H_ 24 | 25 | #include 26 | 27 | #include "geom.h" 28 | #include "pixmap.h" 29 | #include "winnie.h" 30 | 31 | class Window; 32 | 33 | bool init_window_manager(); 34 | void destroy_window_manager(); 35 | 36 | bool client_open_wm(void *smem_start, int offset); 37 | void client_close_wm(); 38 | 39 | class WindowManager { 40 | private: 41 | std::list windows; 42 | 43 | std::list dirty_rects; 44 | 45 | int bg_color[3]; 46 | int frame_thickness; 47 | int titlebar_thickness; 48 | int frame_fcolor[3]; 49 | int frame_ucolor[3]; 50 | 51 | Window *root_win; 52 | Window *focused_win; 53 | Window *grab_win; 54 | 55 | Pixmap mouse_cursor; 56 | Pixmap *background; 57 | 58 | void create_frame(Window *win); 59 | void destroy_frame(Window *win); 60 | 61 | public: 62 | WindowManager(); 63 | ~WindowManager(); 64 | 65 | void invalidate_region(const Rect &rect); 66 | void process_windows(); 67 | 68 | void add_window(Window *win); 69 | void remove_window(Window *win); 70 | 71 | void set_focused_window(Window *win); 72 | const Window *get_focused_window() const; 73 | Window *get_focused_window(); 74 | 75 | Window *get_window_at_pos(int pointer_x, int pointer_y); 76 | Window *get_root_window() const; 77 | 78 | void set_focused_frame_color(int r, int g, int b); 79 | void get_focused_frame_color(int *r, int *g, int *b) const; 80 | 81 | void set_unfocused_frame_color(int r, int g, int b); 82 | void get_unfocused_frame_color(int *r, int *g, int *b) const; 83 | 84 | void set_background(const Pixmap *pixmap); 85 | const Pixmap *get_background() const; 86 | 87 | Window *get_grab_window() const; 88 | 89 | void grab_mouse(Window *win); 90 | void release_mouse(); 91 | 92 | void raise_window(Window *win); 93 | void sink_window(Window *win); 94 | 95 | void maximize_window(Window *win); 96 | void unmaximize_window(Window *win); 97 | }; 98 | 99 | extern WindowManager *wm; 100 | 101 | #endif // WM_H_ 102 | -------------------------------------------------------------------------------- /winnie/Makefile: -------------------------------------------------------------------------------- 1 | src = $(wildcard src/*.cc) $(wildcard src/fbdev/*.cc) $(wildcard src/sdl/*.cc) 2 | obj = $(src:.cc=.o) 3 | dep = $(obj:.o=.d) 4 | bin = wserver 5 | 6 | dbg = -g 7 | opt = -O0 8 | inc = -Isrc -I../libwinnie/src 9 | 10 | backend = SDL 11 | 12 | ifeq ($(backend), SDL) 13 | def = -DWINNIE_SDL 14 | libs = -lSDL 15 | else 16 | def = -DWINNIE_FBDEV 17 | endif 18 | 19 | CXX = g++ 20 | CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc) $(def) `freetype-config --cflags` 21 | LDFLAGS = -L../libwinnie $(libs) `freetype-config --libs` -lrt -lwinnie 22 | 23 | $(bin): $(obj) ../libwinnie/libwinnie.so 24 | $(CXX) -o $@ $(obj) $(LDFLAGS) -Wl,-rpath=../libwinnie 25 | 26 | -include $(dep) 27 | 28 | %.d: %.cc 29 | @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@ 30 | 31 | .PHONY: clean 32 | clean: 33 | rm -f $(obj) $(bin) $(dep) 34 | 35 | -------------------------------------------------------------------------------- /winnie/README: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | The winnie server application. 23 | -------------------------------------------------------------------------------- /winnie/src/main.cc: -------------------------------------------------------------------------------- 1 | /* 2 | winnie - an experimental window system 3 | 4 | Copyright (C) 2013 Eleni Maria Stea 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | Author: Eleni Maria Stea 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "winnie.h" 27 | 28 | static void cleanup(); 29 | 30 | int main() 31 | { 32 | if(!winnie_init()) { 33 | exit(1); 34 | } 35 | 36 | atexit(cleanup); 37 | 38 | Pixmap bg; 39 | if(!(bg.load("data/bg.ppm"))) { 40 | fprintf(stderr, "failed to load pixmap\n"); 41 | } 42 | 43 | wm->set_background(&bg); 44 | 45 | while(1) { 46 | process_events(); 47 | } 48 | } 49 | 50 | static void cleanup() 51 | { 52 | winnie_shutdown(); 53 | } 54 | --------------------------------------------------------------------------------