JWM Source Documentation
clock.c
Go to the documentation of this file.
1 
10 #include "jwm.h"
11 #include "clock.h"
12 #include "tray.h"
13 #include "color.h"
14 #include "font.h"
15 #include "timing.h"
16 #include "main.h"
17 #include "command.h"
18 #include "cursor.h"
19 #include "popup.h"
20 #include "misc.h"
21 #include "settings.h"
22 #include "event.h"
23 #include "action.h"
24 
26 typedef struct ClockType {
27 
30  char *format;
31  char *zone;
32  struct ActionType *actions;
35  /* The following are used to control popups. */
36  int mousex;
37  int mousey;
40  int userWidth;
42  struct ClockType *next;
44 } ClockType;
45 
47 static const char *DEFAULT_FORMAT = "%I:%M %p";
48 
49 static ClockType *clocks;
50 
51 static void Create(TrayComponentType *cp);
52 static void Resize(TrayComponentType *cp);
53 static void Destroy(TrayComponentType *cp);
55  int x, int y, int button);
57  int x, int y, int button);
59  int x, int y, int mask);
60 
61 static void DrawClock(ClockType *clk, const TimeType *now);
62 
63 static void SignalClock(const struct TimeType *now, int x, int y, Window w,
64  void *data);
65 
66 
68 void InitializeClock(void)
69 {
70  clocks = NULL;
71 }
72 
74 void StartupClock(void)
75 {
76  ClockType *clk;
77  for(clk = clocks; clk; clk = clk->next) {
78  if(clk->cp->requestedWidth == 0) {
79  clk->cp->requestedWidth = 1;
80  }
81  if(clk->cp->requestedHeight == 0) {
83  }
84  }
85 }
86 
88 void DestroyClock(void)
89 {
90  while(clocks) {
91  ClockType *cp = clocks->next;
92 
93  if(clocks->format) {
94  Release(clocks->format);
95  }
96  if(clocks->zone) {
97  Release(clocks->zone);
98  }
99  DestroyActions(clocks->actions);
101 
102  Release(clocks);
103  clocks = cp;
104  }
105 }
106 
108 TrayComponentType *CreateClock(const char *format, const char *zone,
109  int width, int height)
110 {
111 
113  ClockType *clk;
114 
115  clk = Allocate(sizeof(ClockType));
116  clk->next = clocks;
117  clocks = clk;
118 
121  clk->mouseTime.seconds = 0;
122  clk->mouseTime.ms = 0;
123  clk->userWidth = 0;
124 
125  if(!format) {
126  format = DEFAULT_FORMAT;
127  }
128  clk->format = CopyString(format);
129  clk->zone = CopyString(zone);
130  clk->actions = NULL;
131  memset(&clk->lastTime, 0, sizeof(clk->lastTime));
132 
133  cp = CreateTrayComponent();
134  cp->object = clk;
135  clk->cp = cp;
136  if(width > 0) {
137  cp->requestedWidth = width;
138  clk->userWidth = 1;
139  } else {
140  cp->requestedWidth = 0;
141  clk->userWidth = 0;
142  }
143  cp->requestedHeight = height;
144 
145  cp->Create = Create;
146  cp->Resize = Resize;
147  cp->Destroy = Destroy;
151 
153 
154  return cp;
155 }
156 
159  const char *action,
160  int mask)
161 {
162  ClockType *clock = (ClockType*)cp->object;
163  AddAction(&clock->actions, action, mask);
164 }
165 
168 {
170  rootDepth);
171 }
172 
175 {
176 
177  ClockType *clk;
178  TimeType now;
179 
180  Assert(cp);
181 
182  clk = (ClockType*)cp->object;
183 
184  Assert(clk);
185 
186  if(cp->pixmap != None) {
188  }
189 
191  rootDepth);
192 
193  memset(&clk->lastTime, 0, sizeof(clk->lastTime));
194 
195  GetCurrentTime(&now);
196  DrawClock(clk, &now);
197 
198 }
199 
202 {
203  Assert(cp);
204  if(cp->pixmap != None) {
206  }
207 }
208 
210 void ProcessClockButtonPress(TrayComponentType *cp, int x, int y, int button)
211 {
212  const ClockType *clk = (ClockType*)cp->object;
213  ProcessActionPress(clk->actions, cp, x, y, button);
214 }
215 
216 void ProcessClockButtonRelease(TrayComponentType *cp, int x, int y, int button)
217 {
218  const ClockType *clk = (ClockType*)cp->object;
219  ProcessActionRelease(clk->actions, cp, x, y, button);
220 }
221 
224  int x, int y, int mask)
225 {
226  ClockType *clk = (ClockType*)cp->object;
227  clk->mousex = cp->screenx + x;
228  clk->mousey = cp->screeny + y;
229  GetCurrentTime(&clk->mouseTime);
230 }
231 
233 void SignalClock(const TimeType *now, int x, int y, Window w, void *data)
234 {
235 
236  ClockType *cp = (ClockType*)data;
237  const char *longTime;
238 
239  DrawClock(cp, now);
240  if(cp->cp->tray->window == w &&
241  abs(cp->mousex - x) < settings.doubleClickDelta &&
242  abs(cp->mousey - y) < settings.doubleClickDelta) {
243  if(GetTimeDifference(now, &cp->mouseTime) >= settings.popupDelay) {
244  longTime = GetTimeString("%c", cp->zone);
245  ShowPopup(x, y, longTime, POPUP_CLOCK);
246  }
247  }
248 
249 }
250 
252 void DrawClock(ClockType *clk, const TimeType *now)
253 {
254 
256  const char *timeString;
257  int width;
258  int rwidth;
259 
260  /* Only draw if the time changed. */
261  if(now->seconds == clk->lastTime.seconds) {
262  return;
263  }
264 
265  /* Clear the area. */
266  cp = clk->cp;
269  JXFillRectangle(display, cp->pixmap, rootGC, 0, 0,
270  cp->width, cp->height);
271  } else {
273  colors[COLOR_CLOCK_BG1], colors[COLOR_CLOCK_BG2],
274  0, 0, cp->width, cp->height);
275  }
276 
277  /* Determine if the clock is the right size. */
278  timeString = GetTimeString(clk->format, clk->zone);
279  width = GetStringWidth(FONT_CLOCK, timeString);
280  rwidth = width + 4;
281  if(rwidth == clk->cp->requestedWidth || clk->userWidth) {
282 
283  /* Draw the clock. */
285  (cp->width - width) / 2,
286  (cp->height - GetStringHeight(FONT_CLOCK)) / 2,
287  cp->width, timeString);
288 
289  UpdateSpecificTray(clk->cp->tray, clk->cp);
290 
291  } else {
292 
293  /* Wrong size. Resize. */
294  clk->cp->requestedWidth = rwidth;
295  ResizeTray(clk->cp->tray);
296 
297  }
298 
299 }

joewing.net / Projects / JWM