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   uint seltags;
29   uint sellt;
30   uint[2] tagset;
31   bool showbar;
32   bool topbar;
33   Client *clients;
34   Client *sel;
35   Client *stack;
36   Monitor *next;
37   Window barwin;
38   const(Layout)*[2] lt;
39 
40     struct MonitorRange 
41     {
42         Monitor* monitor;
43 
44         @property empty() 
45         {
46             return monitor is null;
47         }
48 
49         @property auto front() 
50         {
51             return monitor;
52         }
53 
54         auto popFront() 
55         {
56             monitor = monitor.next;
57         }
58 
59         int opApply(int delegate(Monitor*) dg)
60         {
61             int result = 0;
62             while(!this.empty)
63             {
64                 result = dg(this.front);
65                 if(result)
66                 {
67                     break;
68                 }
69                 this.popFront;
70             }
71             return result;
72         }
73 
74         int opApply(int delegate(size_t, Monitor*) dg) 
75         {
76             int result = 0;
77             size_t ii = 0;
78             while(!this.empty)
79             {
80                 result = dg(ii++, this.front);
81                 if(result)
82                 {
83                     break;
84                 }
85                 this.popFront;
86             }
87             return result;
88         }
89     }
90 }
91 
92 Monitor* recttomon(int x, int y, int w, int h) 
93 {
94     auto r = selmon;
95     int a, area = 0;
96 
97     foreach(m; mons.range) {
98         a = INTERSECT(x, y, w, h, m);
99         if(a > area) {
100             area = a;
101             r = m;
102         }
103     }
104     return r;
105 }
106 
107 Monitor* wintomon(Window w) 
108 {
109     int x, y;
110 
111     if(w == rootWin && getrootptr(&x, &y)) {
112         return recttomon(x, y, 1, 1);
113     }
114     auto m = mons.range.find!(mon => mon.barwin == w).front;
115     if(m) {
116         return m;
117     }
118 
119     auto c = wintoclient(w);
120     if(c) {
121         return c.mon;
122     }
123     return selmon;
124 }
125 
126 Monitor* dirtomon(int dir) 
127 {
128     Monitor *m = null;
129 
130     if(dir > 0) {
131         m = selmon.next;
132         if(m is null) {
133             m = mons;
134         }
135     } else if(selmon == mons) {
136         m = mons.range.find!"a.next is null".front;
137     } else {
138         m = mons.range.find!(a => a.next == selmon).front;
139     }
140     return m;
141 }
142 
143 Monitor* createmon() 
144 {
145     Monitor* m = new Monitor();
146 
147     if(m is null) {
148         die("fatal: could not malloc() %s bytes\n", Monitor.sizeof);
149     }
150 
151     m.tagset[0] = m.tagset[1] = 1;
152     m.mfact = mfact;
153     m.nmaster = nmaster;
154     m.showbar = showbar;
155     m.topbar = topbar;
156     m.lt[0] = &layouts[0];
157     m.lt[1] = &layouts[1 % LENGTH(layouts)];
158     m.ltsymbol = layouts[0].symbol;
159 
160     return m;
161 }