b661234302cea8781325a987bc90eda6b5dfccaf
[winnie] / src / wm.cc
1 #include <stdexcept>
2 #include "gfx.h"
3 #include "wm.h"
4 #include "window.h"
5 #include "mouse.h"
6 #include "mouse_cursor.h"
7
8 WindowManager *wm;
9 static WindowManager wminst;
10
11 WindowManager::WindowManager()
12 {
13         if(!wm) {
14                 wm = this;
15         } else {
16                 throw std::runtime_error("Trying to create a second instance of WindowManager!\n");
17         }
18
19         focused_win = 0;
20
21         bg_color[0] = 210;
22         bg_color[1] = 106;
23         bg_color[2] = 106;
24
25         mouse_cursor.set_image(mouse_cursor_width, mouse_cursor_height);
26         unsigned char *pixels = mouse_cursor.get_image();
27
28         for(int i=0; i<mouse_cursor_height; i++) {
29                 for(int j=0; j<mouse_cursor_width; j++) {
30                         int val = mouse_cursor_bw[i * mouse_cursor_width + j];
31                         *pixels++ = val;
32                         *pixels++ = val;
33                         *pixels++ = val;
34                         *pixels++ = 255;
35                 }
36         }
37 }
38
39 void WindowManager::invalidate_region(const Rect &rect)
40 {
41         dirty_rects.push_back(rect);
42 }
43
44 void WindowManager::process_windows()
45 {
46         if(dirty_rects.empty()) {
47                 return;
48         }
49
50         std::list<Rect>::iterator drit = dirty_rects.begin();
51         Rect uni = *drit++;
52         while(drit != dirty_rects.end()) {
53                 uni = rect_union(uni, *drit++);
54         }
55         dirty_rects.clear();
56
57         fill_rect(uni, bg_color[0], bg_color[1], bg_color[2]);
58         
59         std::list<Window*>::iterator it = windows.begin();
60         while(it != windows.end()) {
61                 Rect intersect = rect_intersection((*it)->rect, uni); 
62                 if(intersect.width && intersect.height) {
63                         (*it)->draw();
64                 }
65                 it++;
66         }
67
68         // draw mouse cursor
69         int mouse_x, mouse_y;
70         get_pointer_pos(&mouse_x, &mouse_y);
71
72         blit_key(mouse_cursor.get_image(), mouse_cursor.get_rect(),
73                         get_framebuffer(), get_screen_size(), mouse_x, mouse_y,
74                         0, 0, 0);
75
76         Rect mouse_rect = {mouse_x, mouse_y, mouse_cursor.get_width(), mouse_cursor.get_height()};
77         invalidate_region(mouse_rect);
78 }
79
80 void WindowManager::add_window(Window *win)
81 {
82         if(windows.empty()) {
83                 focused_win = win;
84         }
85
86         windows.push_back(win);
87 }
88
89 void WindowManager::set_focused_window(Window *win)
90 {
91         focused_win = win;
92 }
93
94 const Window *WindowManager::get_focused_window() const
95 {
96         return focused_win;
97 }
98
99 Window *WindowManager::get_focused_window()
100 {
101         return focused_win;
102 }
103
104 Window *WindowManager::get_window_at_pos(int pointer_x, int pointer_y)
105 {
106         Window *win = 0;
107         std::list<Window*>::reverse_iterator rit = windows.rbegin();
108         while(rit != windows.rend()) {
109                 if((*rit)->contains_point(pointer_x, pointer_y)) {
110                         win = *rit;
111                         break;
112                 }
113                 rit++;
114         }
115
116         return win;
117 }