1 module monitor;
2 
3 import std.stdio;
4 import std.string;
5 import std.algorithm;
6 
7 import deimos.X11.X;
8 
9 import cboxapp;
10 import window;
11 import theme.layout;
12 import config;
13 import types;
14 import kernel;
15 import theme.manager;
16 import old;
17 import utils;
18 
19 struct Monitor 
20 {
21   string ltsymbol;
22   float mfact;
23   int nmaster;
24   int num;
25   int by;               /* bar geometry */
26   int mx, my, mw, mh;   /* screen size */
27   int wx, wy, ww, wh;   /* window area  */
28 
29   uint seltags;
30   uint sellt;
31   uint[2] tagset;
32   bool showbar;
33   bool topbar;
34   Client *clients;
35   Client *sel;
36   Client *stack;
37   Monitor *next;
38   Window barwin;
39   const(Layout)*[2] lt;
40 
41     struct MonitorRange 
42     {
43         Monitor* monitor;
44 
45         @property empty() 
46         {
47             return monitor is null;
48         }
49 
50         @property auto front() 
51         {
52             return monitor;
53         }
54 
55         auto popFront() 
56         {
57             monitor = monitor.next;
58         }
59 
60         int opApply(int delegate(Monitor*) dg)
61         {
62             int result = 0;
63             while(!this.empty)
64             {
65                 result = dg(this.front);
66                 if(result)
67                 {
68                     break;
69                 }
70                 this.popFront;
71             }
72             return result;
73         }
74 
75         int opApply(int delegate(size_t, Monitor*) dg) 
76         {
77             int result = 0;
78             size_t ii = 0;
79             while(!this.empty)
80             {
81                 result = dg(ii++, this.front);
82                 if(result)
83                 {
84                     break;
85                 }
86                 this.popFront;
87             }
88             return result;
89         }
90     }
91 }
92 
93 Monitor* recttomon(int x, int y, int w, int h) 
94 {
95     auto r = selmon;
96     int a, area = 0;
97 
98     foreach(m; mons.range) {
99         a = INTERSECT(x, y, w, h, m);
100         if(a > area) {
101             area = a;
102             r = m;
103         }
104     }
105     return r;
106 }
107 
108 Monitor* wintomon(Window w) 
109 {
110     int x, y;
111 
112     if(w == rootWin && getrootptr(&x, &y)) {
113         return recttomon(x, y, 1, 1);
114     }
115     auto m = mons.range.find!(mon => mon.barwin == w).front;
116     if(m) {
117         return m;
118     }
119 
120     auto c = wintoclient(w);
121     if(c) {
122         return c.mon;
123     }
124     return selmon;
125 }
126 
127 Monitor* dirtomon(int dir) 
128 {
129     Monitor *m = null;
130 
131     if(dir > 0) {
132         m = selmon.next;
133         if(m is null) {
134             m = mons;
135         }
136     } else if(selmon == mons) {
137         m = mons.range.find!"a.next is null".front;
138     } else {
139         m = mons.range.find!(a => a.next == selmon).front;
140     }
141     return m;
142 }
143 
144 Monitor* createmon() 
145 {
146     Monitor* m = new Monitor();
147 
148     if(m is null) {
149         die("fatal: could not malloc() %s bytes\n", Monitor.sizeof);
150     }
151 
152     m.tagset[0] = m.tagset[1] = 1;
153     m.mfact = mfact;
154     m.nmaster = nmaster;
155     m.showbar = showbar;
156     m.topbar = topbar;
157     m.lt[0] = &layouts[0];
158     m.lt[1] = &layouts[1 % LENGTH(layouts)];
159     m.ltsymbol = layouts[0].symbol;
160 
161     return m;
162 }
163 
164 void arrange(Monitor *m) 
165 {
166     if(m) {
167         windowManager.showhide(m.stack);
168     } else foreach(m; mons.range) {
169         windowManager.showhide(m.stack);
170     }
171     if(m) {
172         arrangemon(m);
173         restack(m);
174     } else foreach(m; mons.range) {
175         arrangemon(m);
176     }
177 }
178 
179 void arrangemon(Monitor *m) {
180     
181     m.ltsymbol = m.lt[m.sellt].symbol;
182 
183     if(m.lt[m.sellt].arrange)
184         m.lt[m.sellt].arrange(m);
185 }
186 
187 void attach(Client *c) {
188     
189     c.next = c.mon.clients;
190     c.mon.clients = c;
191 }
192 
193 void attachstack(Client *c) {
194     
195     c.snext = c.mon.stack;
196     c.mon.stack = c;
197 }