1 // bbmail.cpp for bbmail - an tool for display the mail in X11.
2 //
3 // Copyright (c) 1998-2005 by John Kennis, jkennis@chello.nl
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 //
19 // (See the included file COPYING / GPL-2.0)
20 //
21
22 #include "bbmail.h"
23 #include "config.h"
24 #include <string>
25 #include <cstdio> // for fprintf popen stderr etc
26 #include <cstring> // for strncmp
27 #include <cstdlib>
28 #include <cmath>
29
30 extern "C" {
31 #include <utime.h>
32 #include <dirent.h>
33 #include <X11/cursorfont.h>
34 #include <sys/stat.h>
35 }
36
37 #include "EWMH.hh"
38
39 #define SEPERATOR "/"
40
Checkmail(ToolWindow * toolwindow)41 Checkmail::Checkmail(ToolWindow *toolwindow):
42 m_pBbtool(toolwindow)
43 {
44 timer = new bt::Timer(m_pBbtool, this) ;
45 timer->setTimeout(m_pBbtool->getResource()->report.check_delay * 1000);
46 timer->recurring(true);
47
48 timer->start();
49 broken = false;
50 last_totalmail = 0;
51 last_newmail = 0;
52 new_mailbox = 0;
53 newmail = 0;
54 spoolfile = new
55 LocalSpoolfile[m_pBbtool->getResource()->report.number_of_spoolfiles];
56 number_of_checks = m_pBbtool->getResource()->report.force_check_delay;
57 }
58
~Checkmail()59 Checkmail::~Checkmail()
60 {
61 delete [] spoolfile;
62 delete timer;
63 }
64
reconfigure()65 void Checkmail::reconfigure()
66 {
67 delete [] spoolfile;
68 spoolfile = new LocalSpoolfile[
69 m_pBbtool->getResource()->report.number_of_spoolfiles];
70 number_of_checks = m_pBbtool->getResource()->report.force_check_delay;
71 timer->fireTimeout();
72 }
73
CheckMaildir(int spoolno)74 bool Checkmail::CheckMaildir(int spoolno)
75 {
76 struct stat file_status, maildir_status;
77
78 if (m_pBbtool->getResource()->spoolfile[spoolno].filename.empty())
79 {
80 fprintf(stderr,"No qmail maildir specified\n");
81 return(false);
82 }
83
84 if (stat(m_pBbtool->getResource()->spoolfile[spoolno].filename.c_str(),
85 &file_status)!=0)
86 {
87 fprintf(stderr,"Could not read status spool file %s\n",
88 m_pBbtool->getResource()->spoolfile[spoolno].filename.c_str());
89 return(false);
90 }
91
92 // check maildir new/
93
94 if (stat(m_pBbtool->getResource()->spoolfile[spoolno].new_maildir.c_str(),
95 &maildir_status) != 0)
96 {
97 fprintf(stderr,"Could not read status new maildir: %s\n",
98 m_pBbtool->getResource()->spoolfile[spoolno].new_maildir.c_str());
99 return(false);
100 }
101 if (maildir_status.st_mtime > file_status.st_mtime)
102 {
103 file_status.st_mtime = maildir_status.st_mtime;
104 }
105
106 if (stat(m_pBbtool->getResource()->spoolfile[spoolno].cur_maildir.c_str(),
107 &maildir_status) != 0)
108 {
109 fprintf(stderr,"Could not read status current maildir: %s\n",
110 m_pBbtool->getResource()->spoolfile[spoolno].cur_maildir.c_str());
111 return(false);
112 }
113 if (maildir_status.st_mtime > file_status.st_mtime)
114 {
115 file_status.st_mtime = maildir_status.st_mtime;
116 }
117
118 if (file_status.st_mtime != spoolfile[spoolno].last_mtime)
119 {
120 spoolfile[spoolno].last_mtime = file_status.st_mtime;
121 spoolfile[spoolno].newmail=0;
122 DIR *dir;
123
124 if ((dir = opendir(
125 m_pBbtool->getResource()->spoolfile[spoolno].new_maildir.c_str())
126 ) == NULL)
127 {
128 fprintf(stderr,"Could not open maildir %s\n",
129 m_pBbtool->getResource()->spoolfile[spoolno].new_maildir.c_str());
130 return false;
131 }
132
133 while (readdir (dir))
134 {
135 spoolfile[spoolno].newmail++;
136 }
137 /* -2 for . and .. */
138 spoolfile[spoolno].newmail -= 2;
139 closedir(dir);
140
141 if ((dir = opendir(
142 m_pBbtool->getResource()->spoolfile[spoolno].cur_maildir.c_str())
143 ) == NULL)
144 {
145 fprintf(stderr,"Could not open maildir %s\n",
146 m_pBbtool->getResource()->spoolfile[spoolno].new_maildir.c_str());
147 return false;
148 }
149
150 spoolfile[spoolno].totalmail=spoolfile[spoolno].newmail;
151
152 while (readdir (dir))
153 {
154 spoolfile[spoolno].totalmail++;
155 }
156 /* -2 for . and .. */
157 spoolfile[spoolno].totalmail-=2;
158 closedir(dir);
159 }
160 return(true);
161 }
162
CheckOther(int spoolno,bool force)163 bool Checkmail::CheckOther(int spoolno,bool force)
164 {
165 struct stat file_status;
166 FILE *fp;
167 int num[2]={-1,-1};
168 int number_of_values;
169
170
171 if ((m_pBbtool->getResource()->spoolfile[spoolno].proc.empty())&
172 (m_pBbtool->getResource()->spoolfile[spoolno].proc.empty()))
173 {
174 fprintf(stderr,"Nothing to do, no proc defined\n");
175 return(false);
176 }
177 if (!m_pBbtool->getResource()->spoolfile[spoolno].filename.empty())
178 {
179 if (stat(m_pBbtool->getResource()->spoolfile[spoolno].filename.c_str(),
180 &file_status)!=0)
181 {
182 fprintf(stderr,"Could not read status spool file %s\n",
183 m_pBbtool->getResource()->spoolfile[spoolno].filename.c_str());
184 return(false);
185 }
186 }
187
188 if ((file_status.st_mtime != spoolfile[spoolno].last_mtime)&&
189 (m_pBbtool->getResource()->spoolfile[spoolno].filename.empty())||
190 (force && m_pBbtool->getResource()->spoolfile[spoolno].force_check))
191 {
192
193 if (m_pBbtool->getResource()->spoolfile[spoolno].second_ignore)
194 {
195 number_of_values = 1;
196 }
197 else
198 {
199 number_of_values = 2;
200 }
201
202 spoolfile[spoolno].last_mtime = file_status.st_mtime;
203 int old_newmail = spoolfile[spoolno].newmail;
204 spoolfile[spoolno].newmail = 0;
205 spoolfile[spoolno].totalmail = 0;
206
207 if (!m_pBbtool->getResource()->spoolfile[spoolno].proc.empty())
208 {
209 if ((fp = (FILE*)popen(
210 m_pBbtool->getResource()->spoolfile[spoolno].proc.c_str(),
211 "r")) == NULL)
212 {
213 fprintf(stderr,"Could not run command %s\n",
214 m_pBbtool->getResource()->spoolfile[spoolno].proc.c_str());
215 return(false);
216 }
217 else
218 {
219 while (!(feof(fp)))
220 {
221 if (ReadPipe(fp,num,number_of_values) != 0)
222 {
223 if (num[0] > old_newmail)
224 {
225 new_mailbox = spoolno;
226 }
227 #ifdef DEBUG
228 fprintf(stderr,"first int: %i, second int %i\n",num[0],num[1]);
229 #endif
230 spoolfile[spoolno].newmail += num[0];
231 spoolfile[spoolno].totalmail += num[1];
232 }
233 else
234 {
235 if ((num[0] == -1) & (num[1] == -1))
236 {
237 pclose(fp);
238 return(false);
239 }
240 }
241 }
242 pclose(fp);
243 }
244 }
245 if (!m_pBbtool->getResource()->spoolfile[spoolno].reversedProc.empty())
246 {
247 if ((fp=(FILE*)popen(
248 m_pBbtool->getResource()->spoolfile[spoolno].reversedProc.c_str(),
249 "r")) == NULL)
250 {
251 fprintf(stderr,"Could not run command %s\n",
252 m_pBbtool->getResource()->spoolfile[spoolno].reversedProc.c_str());
253 return(false);
254 }
255 else
256 {
257 while (!(feof(fp)))
258 {
259 if (ReadPipe(fp,num,number_of_values)!=0)
260 {
261 if (num[1]>old_newmail) new_mailbox = spoolno;
262 spoolfile[spoolno].newmail+=num[1];
263 spoolfile[spoolno].totalmail+=num[0];
264 }
265 }
266 pclose(fp);
267 }
268 }
269 if (!m_pBbtool->getResource()->spoolfile[spoolno].first_is_new)
270 spoolfile[spoolno].newmail=spoolfile[spoolno].totalmail-
271 spoolfile[spoolno].newmail;
272 if (!m_pBbtool->getResource()->spoolfile[spoolno].second_is_total)
273 spoolfile[spoolno].totalmail=spoolfile[spoolno].newmail+
274 spoolfile[spoolno].totalmail;
275
276 }
277
278 return(true);
279 }
280
forceCheck()281 void Checkmail::forceCheck()
282 {
283 timer->fireTimeout();
284 }
285
getChar(const char * string,int * index)286 bool Checkmail::getChar(const char *string,int *index)
287 {
288 bool special = false;
289 if (string[*index] == '\\') {
290 (*index)++;
291 } else {
292 if ((string[*index] == '[')|(string[*index] == ']'))
293 special = true;
294 }
295 return(special);
296 }
297
checkStatusFlag(char * status_flag,int spoolno)298 bool Checkmail::checkStatusFlag(char *status_flag,int spoolno)
299 {
300 int i, x, len;
301 bool passed;
302
303 len = m_pBbtool->getResource()->spoolfile[spoolno].statusflag.length();
304 for (i = 0, x = 0; i < len; i++, x++) {
305 if (getChar(m_pBbtool->getResource()->spoolfile[spoolno].statusflag.c_str(), &i)) {
306 if ((m_pBbtool->getResource()->spoolfile[spoolno].statusflag[i]=='[')) {
307 passed=false;
308 while ((m_pBbtool->getResource()->spoolfile[spoolno].statusflag[i]!=']')
309 & (i<len)) {
310 i++;
311
312 if (!getChar(m_pBbtool->getResource()->spoolfile[spoolno].statusflag.c_str(),
313 &i))
314 if (m_pBbtool->getResource()->spoolfile[spoolno].statusflag[i]==
315 status_flag[x]) {
316 passed=true;
317 }
318 }
319 if (!passed) return false;
320 } else {
321 fprintf(stderr,"unexpected token in statusFlag\n");
322 }
323 } else
324 if (m_pBbtool->getResource()->spoolfile[spoolno].statusflag[i]!=status_flag[x])
325 return(false);
326 }
327 return(true);
328 }
329
CheckMbox(int spoolno)330 bool Checkmail::CheckMbox(int spoolno)
331 {
332 int readmail = 0;
333 int mailcount = 0;
334 FILE *spool_id;
335 bool read_status = true;
336 char mailbuf[128];
337 struct stat file_status;
338 struct utimbuf ut;
339
340 if (m_pBbtool->getResource()->spoolfile[spoolno].filename.empty()) {
341 fprintf(stderr,"No mbox mailfile specified\n");
342 return(false);
343 }
344
345 if (!(spool_id = fopen(m_pBbtool->getResource()->spoolfile[spoolno].filename.c_str(),
346 "r"))) {
347 fprintf(stderr,"Could not open mail spool file %s\n",
348 m_pBbtool->getResource()->spoolfile[spoolno].filename.c_str());
349 return(false);
350 }
351 fstat(fileno(spool_id), &file_status);
352 if(file_status.st_mtime != spoolfile[spoolno].last_mtime ||
353 file_status.st_size != spoolfile[spoolno].last_size) {
354 spoolfile[spoolno].last_mtime = file_status.st_mtime;
355 spoolfile[spoolno].last_size = file_status.st_size;
356 while(fgets(mailbuf, 127, spool_id)) {
357 if(!strncmp(mailbuf, "From ", 5)) {
358 mailcount++;
359 read_status=False;
360 } else
361 if (checkStatusFlag(mailbuf,spoolno)) {
362 if(!read_status) {
363 readmail++;
364 read_status=True;
365 }
366 } else if (!strncmp(mailbuf,"Subject",7)) {
367 if (!strncmp(&mailbuf[9],
368 "DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA",49)!=0) {
369 mailcount--;
370 read_status=True;
371 }
372 }
373
374 }
375 if ((mailcount - readmail) > spoolfile[spoolno].newmail)
376 new_mailbox = spoolno;
377 spoolfile[spoolno].newmail = mailcount - readmail;
378 spoolfile[spoolno].totalmail = mailcount;
379 #ifdef DEBUG
380 fprintf(stderr,"mailcount=%d, readmail=%d, spoolno=%d\n",mailcount,
381 readmail,spoolno);
382 #endif
383 }
384 fclose(spool_id);
385 ut.actime = file_status.st_atime;
386 ut.modtime = file_status.st_mtime;
387 utime(m_pBbtool->getResource()->spoolfile[spoolno].filename.c_str(), &ut);
388 return(true);
389 }
390
timeout(bt::Timer * timer)391 void Checkmail::timeout(bt::Timer *timer)
392 {
393 int totalmail=0;
394 bool change_raise=False;
395 bool force=False;
396 int i,old_total,old_new;
397 bool redraw=False;
398 newmail=0;
399 broken=False;
400 if (m_pBbtool->getResource()->report.force_check) {
401 if (m_pBbtool->getResource()->report.force_check_delay==number_of_checks) {
402 force=True;
403 number_of_checks=0;
404 } else {
405 number_of_checks++;
406 #ifdef DEBUG
407 fprintf(stderr,"number_of_checks %i\n",number_of_checks);
408 #endif
409 }
410 }
411 for (i = 0; i < (int)m_pBbtool->getResource()->report.number_of_spoolfiles; i++) {
412 old_new=spoolfile[i].newmail;
413 old_total=spoolfile[i].totalmail;
414
415 if (m_pBbtool->getResource()->spoolfile[i].type==SpoolList::other) {
416 if (!(CheckOther(i,force))) {
417 broken=True;
418 } else {
419 newmail+=spoolfile[i].newmail;
420 totalmail+=spoolfile[i].totalmail;
421 if ((spoolfile[i].newmail!=old_new)|(spoolfile[i].totalmail!=old_total))
422 {
423 m_pBbtool->mbMenu()->UpdateNumbers(spoolfile[i].newmail,
424 spoolfile[i].totalmail,i);
425 }
426 }
427 } else if (m_pBbtool->getResource()->spoolfile[i].type==SpoolList::mbox) {
428 if (!(CheckMbox(i)))
429 broken=True;
430 else {
431 totalmail+=spoolfile[i].totalmail;
432 newmail+=spoolfile[i].newmail;
433 if ((spoolfile[i].newmail != old_new) | (spoolfile[i].totalmail != old_total))
434 m_pBbtool->mbMenu()->UpdateNumbers(spoolfile[i].newmail,
435 spoolfile[i].totalmail,i);
436 }
437 } else if (m_pBbtool->getResource()->spoolfile[i].type == SpoolList::maildir) {
438 if (!(CheckMaildir(i)))
439 broken=True;
440 else {
441 totalmail+=spoolfile[i].totalmail;
442 newmail+=spoolfile[i].newmail;
443 if ((spoolfile[i].newmail!=old_new)|(spoolfile[i].totalmail!=old_total))
444 m_pBbtool->mbMenu()->UpdateNumbers(spoolfile[i].newmail,
445 spoolfile[i].totalmail,i);
446 }
447 }
448 }
449 if (newmail>last_newmail)
450 change_raise = True;
451 else {
452 /* are there ny not empty mailboxes left */
453 for (i = 0; i < (int)m_pBbtool->getResource()->report.number_of_spoolfiles; i++) {
454 if (spoolfile[i].newmail!=0) {
455 new_mailbox=i;
456 // change_raise = True;
457 }
458 }
459 }
460 if ((newmail!=last_newmail)|(totalmail!=last_totalmail)|(broken) )
461 {
462 redraw=True;
463 }
464 last_newmail=newmail;
465 last_totalmail=totalmail;
466 if (redraw) m_pBbtool->redraw(change_raise);
467 }
468
ReadPipe(FILE * fp,int num[2],int number_of_values)469 int Checkmail::ReadPipe(FILE *fp,int num[2],int number_of_values)
470 {
471 int i=0;
472 bool found=False;
473 bool newline=False;
474 int x=0;
475 char ch[6]={0,0,0,0,0,0};
476
477 while (!(feof(fp))&(x!=number_of_values)&(ch[i]!='\n')&(!newline)) {
478 fread(&ch[i],1,1,fp);
479 while ((ch[i]>='0' && ch[i] <='9' && ch[1]!='\n')&(!feof(fp))) {
480 i++;
481 if (i==7) return(0);
482 fread(&ch[i],1,1,fp);
483 found=True;
484 }
485 if (ch[i]=='\n') newline=True;
486 if (found) {
487 ch[i]='\0';
488 num[x]=atoi(ch);
489 i=0;
490 x++;
491 found=False;
492 }
493 }
494 /* skip to next line */
495 while (!(feof(fp))&(ch[0]!='\n')&(!newline))
496 fread(&ch[0],1,1,fp);
497 return(x);
498 }
499
500
ToolWindow(Configuration cml_options)501 ToolWindow::ToolWindow(Configuration cml_options):
502 bt::Application(cml_options.appName(), cml_options.displayName().c_str(), false),
503 current_screen_info(display().screenInfo(DefaultScreen(XDisplay()))),
504 _config(cml_options)
505 {
506
507 checkmail = NULL;
508 mbmenu = NULL;
509 current_screen = DefaultScreen(XDisplay());
510 wm_delete_window = XInternAtom (XDisplay(), "WM_DELETE_WINDOW",False);
511
512 /* initialize xrm database */
513 XrmInitialize();
514 resource = new Resource(this, _config.rcFilename());
515 frame_window = new FrameWindow(this);
516 label_window = new LabelWindow(this);
517 envelope_window = new EnvelopeWindow(this);
518
519 if (resource->validMailbox()) {
520 checkmail = new Checkmail(this);
521 makeWindow(false);
522 redraw(False);
523 checkmail->forceCheck();
524 } else {
525 throw -1;
526 }
527
528 }
529
~ToolWindow()530 ToolWindow::~ToolWindow()
531 {
532 delete envelope_window;
533 delete label_window;
534 delete mbmenu;
535 delete resource;
536 delete checkmail;
537 delete frame_window;
538 }
539
540
reconfigure(void)541 void ToolWindow::reconfigure(void)
542 {
543 delete resource;
544 resource = new Resource(this, _config.rcFilename());
545 mbmenu->reconfigure();
546 checkmail->reconfigure();
547
548 makeWindow(true);
549
550 // if (resource->show.label) XClearWindow(XDisplay(), label_window->window());
551 // XClearWindow(XDisplay(), envelope_window->window());
552 // XClearWindow(XDisplay(), frame_window->window());
553 redraw(False);
554 }
555
makeWindow(bool reconfigure)556 void ToolWindow::makeWindow(bool reconfigure)
557 {
558 frame_window->setHeight(textHeight(getCurrentScreen(), resource->frame.font) + 4 * resource->frame.bevelWidth);
559
560 if (resource->show.envelope) {
561 envelope_window->setHeight(frame_window->height() - 2 * resource->frame.bevelWidth -
562 2 * resource->envelope.bevelHeight);
563 envelope_window->setWidth((envelope_window->height() * 3) / 2);
564
565 if (!(fmod((double)envelope_window->width(), 2.0) > 0.0))
566 envelope_window->setWidth(envelope_window->width() + 1);
567 } else
568 envelope_window->setWidth(0);
569
570
571 if (resource->show.label) {
572 label_window->calcSize();
573 label_window->setHeight(frame_window->height() - 2 * resource->frame.bevelWidth);
574 }
575
576 frame_window->setWidth(label_window->width() + envelope_window->width()
577 + resource->frame.bevelWidth * 3 + resource->envelope.bevelWidth * 2);
578
579 if (resource->position.mask & XNegative)
580 resource->position.x = getCurrentScreenInfo()->width() +
581 resource->position.x - frame_window->width();
582 if (resource->position.mask & YNegative)
583 resource->position.y = getCurrentScreenInfo()->height() +
584 resource->position.y - frame_window->height();
585
586 if (!config().isWithdrawn()) {
587 frame_window->setX(resource->position.x);
588 frame_window->setY(resource->position.y);
589 }
590
591 if (!reconfigure) {
592 frame_window->createWindow();
593 } else {
594 frame_window->reconfigure();
595 }
596 if (resource->show.label) {
597 label_window->setX(2 * resource->frame.bevelWidth +
598 envelope_window->width() + 2 * resource->envelope.bevelWidth);
599 label_window->setY(resource->frame.bevelWidth);
600 if (!reconfigure)
601 label_window->createWindow();
602 else
603 label_window->reconfigure();
604 }
605 if (resource->show.envelope) {
606 envelope_window->setX(resource->frame.bevelWidth + resource->envelope.bevelWidth);
607 envelope_window->setY(resource->frame.bevelWidth + resource->envelope.bevelWidth);
608 if (!reconfigure)
609 envelope_window->createWindow();
610 else
611 envelope_window->reconfigure();
612 }
613
614 if (!reconfigure) {
615 mbmenu = new MailboxMenu(this);
616 XClearWindow(XDisplay(), frame_window->window());
617 XMapSubwindows(XDisplay(), frame_window->window());
618 mapped=true;
619 if (!config().isDecorated() && !config().isWithdrawn())
620 {
621 XMoveResizeWindow(XDisplay(),frame_window->window(),frame_window->x(),
622 frame_window->y(), frame_window->width(),
623 frame_window->height());
624 }
625 }
626 }
627
628
629
redraw(bool change_raise)630 void ToolWindow::redraw(bool change_raise)
631 {
632 if (checkmail->getNewmail()==0) {
633 if (resource->show.onlyAtNewMail&mapped) {
634 XUnmapSubwindows(XDisplay(), frame_window->window());
635 XUnmapWindow(XDisplay(), frame_window->window());
636 mapped=false;
637 }
638 else if (resource->show.envelope) {
639 envelope_window->redraw();
640 }
641 } else {
642 if ((resource->show.onlyAtNewMail) & (!(mapped))) {
643 XMapSubwindows(XDisplay(), frame_window->window());
644 XMapWindow(XDisplay(),frame_window->window());
645 mapped=true;
646 }
647 if (change_raise) {
648 if (resource->spoolfile[checkmail->getNewMailbox()].bell)
649 XBell(XDisplay(),100);
650 if (!resource->spoolfile[checkmail->getNewMailbox()].newmailProc.empty());
651 system(resource->spoolfile[checkmail->getNewMailbox()].newmailProc.c_str());
652 if ((resource->report.auto_raise)&(!(raised))) {
653 XRaiseWindow(XDisplay(), frame_window->window());
654 raised = true;
655 }
656 }
657 if (resource->show.envelope) {
658 envelope_window->redraw();
659 }
660 }
661 if (resource->show.label) {
662 label_window->redraw();
663 }
664
665 }
666
667
FrameWindow(ToolWindow * toolwindow)668 FrameWindow::FrameWindow(ToolWindow *toolwindow) :
669 bt::EventHandler() ,
670 m_pBbtool(toolwindow),
671 fwindow(0),
672 fx(0),
673 fy(0),
674 m_pixmap(0),
675 fposition(NULL),
676 m_screen(toolwindow->getCurrentScreen()),
677 display(toolwindow->XDisplay())
678 {
679 }
680
~FrameWindow(void)681 FrameWindow::~FrameWindow(void)
682 {
683 if (m_pixmap) bt::PixmapCache::release(m_pixmap);
684 if (fposition) delete fposition;
685
686 if (fwindow) XDestroyWindow(display, fwindow);
687
688 }
689
createWindow(void)690 void FrameWindow::createWindow(void)
691 {
692 XSetWindowAttributes attrib;
693 XWMHints wmhints;
694 unsigned long create_mask = CWBackPixmap | CWCursor | CWEventMask | CWOverrideRedirect;
695
696 attrib.background_pixmap = ParentRelative;
697 m_pixmap = bt::PixmapCache::find(m_screen,
698 m_pBbtool->getResource()->frame.texture, fwidth, fheight);
699 if (m_pBbtool->config().isWithdrawn()) {
700 wmhints.initial_state = WithdrawnState;
701 } else {
702 wmhints.initial_state = NormalState;
703 }
704
705 attrib.cursor = XCreateFontCursor(display, XC_left_ptr);
706 attrib.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask |
707 FocusChangeMask | KeyPressMask | StructureNotifyMask;
708 attrib.override_redirect = False;
709
710 bt::EWMH ewmh(m_pBbtool->display());
711 bool wm_window_type_dock = false;
712
713 if (!m_pBbtool->config().isDecorated() && !m_pBbtool->config().isWithdrawn()) {
714 bt::EWMH::AtomList supported_atoms;
715 if (ewmh.readSupported(m_pBbtool->getCurrentScreenInfo()->rootWindow(), supported_atoms)) {
716
717 bt::EWMH::AtomList::iterator it = supported_atoms.begin();
718 for (; it != supported_atoms.end(); ++it) {
719 if ( (*it) == ewmh.wmWindowTypeDock()) {
720 wm_window_type_dock = true;
721 }
722 }
723 } else {
724 attrib.override_redirect = True;
725 }
726 }
727
728 fwindow = XCreateWindow(display,
729 m_pBbtool->getCurrentScreenInfo()->rootWindow(),
730 fx, fy, fwidth, fheight, 0,
731 m_pBbtool->getCurrentScreenInfo()->depth(),
732 InputOutput, m_pBbtool->getCurrentScreenInfo()->visual(),
733 create_mask, &attrib);
734
735 wmhints.flags = IconWindowHint | StateHint;
736 wmhints.icon_window = fwindow;
737 XTextProperty windowname;
738 XClassHint classhints;
739
740 char *name = (char *)PACKAGE;
741 XSizeHints sizehints;
742
743 classhints.res_name = (char *)PACKAGE;
744 classhints.res_class = (char *)"m_pBbtools";
745
746 sizehints.x = m_pBbtool->getResource()->position.x;
747 sizehints.y = m_pBbtool->getResource()->position.y;
748 sizehints.max_width = sizehints.min_width = fwidth;
749 sizehints.max_height = sizehints.min_height = fheight;
750 sizehints.flags = USPosition | PMinSize | PMaxSize;
751
752 XStringListToTextProperty(&name, 1, &windowname);
753 XSetWMProperties(display, fwindow, &windowname, NULL, m_pBbtool->config().argv(), m_pBbtool->config().argc(),
754 &sizehints, &wmhints, &classhints);
755 XFree(windowname.value);
756 Atom wmproto[2];
757 wmproto[0] = m_pBbtool->wmDeleteWindowAtom();
758 XSetWMProtocols(display, fwindow, wmproto, 1);
759 bt::EWMH::AtomList window_type_atom;
760 window_type_atom.push_back(ewmh.wmWindowTypeDock());
761 if (!m_pBbtool->config().isDecorated() && !m_pBbtool->config().isWithdrawn()) {
762 if (wm_window_type_dock) {
763 XChangeProperty(display, fwindow, ewmh.wmWindowType(), XA_ATOM,
764 32, PropModeReplace,
765 reinterpret_cast<unsigned char*>(&(window_type_atom[0])), window_type_atom.size());
766 } else {
767 //attrib.override_redirect set
768 fprintf(stderr, "Cannot dock\n");
769 }
770 }
771 bt::EWMH::AtomList state_atom;
772 state_atom.push_back(ewmh.wmStateSticky());
773 state_atom.push_back(ewmh.wmStateSkipTaskbar());
774 state_atom.push_back(ewmh.wmStateSkipPager());
775 ewmh.setWMState(fwindow, state_atom);
776
777 //XSetWindowBackgroundPixmap(display, fwindow, m_pixmap);
778 redraw();
779
780 m_pBbtool->insertEventHandler(fwindow, this);
781 }
782
redraw(void)783 void FrameWindow::redraw(void)
784 {
785 bt::Rect u(0, 0, fwidth, fheight);
786 bt::drawTexture(m_screen,
787 m_pBbtool->getResource()->frame.texture,
788 fwindow,
789 u, u, m_pixmap);
790 }
791
reconfigure(void)792 void FrameWindow::reconfigure(void)
793 {
794 bt::PixmapCache::release(m_pixmap);
795 m_pixmap = bt::PixmapCache::find(m_screen,
796 m_pBbtool->getResource()->frame.texture, fwidth, fheight);
797
798 if (!m_pBbtool->config().isWithdrawn()) {
799 XMoveResizeWindow(display, fwindow, fx, fy, fwidth, fheight);
800 } else {
801 XResizeWindow(display, fwindow, fwidth, fheight);
802 }
803 redraw();
804 }
805
clientMessageEvent(const XClientMessageEvent * xclient_event)806 void FrameWindow::clientMessageEvent(const XClientMessageEvent *xclient_event)
807 {
808 if ((unsigned)xclient_event->data.l[0] == m_pBbtool->wmDeleteWindowAtom())
809 m_pBbtool->shutdown();
810 }
811
exposeEvent(const XExposeEvent *)812 void FrameWindow::exposeEvent(const XExposeEvent *)
813 {
814 redraw();
815 }
816
buttonPressEvent(const XButtonEvent * xbutton_event)817 void FrameWindow::buttonPressEvent(const XButtonEvent *xbutton_event)
818 {
819 if (xbutton_event->button == LEFT_BUTTON) {
820 if (!m_pBbtool->isRaised()) {
821 XRaiseWindow(display, fwindow);
822 m_pBbtool->setRaised(true);
823 }
824 } else if (xbutton_event->button == MIDDLE_BUTTON) {
825 if (m_pBbtool->isRaised()) {
826 XLowerWindow(display, fwindow);
827 m_pBbtool->setRaised(false);
828 }
829 }
830 }
831
LabelWindow(ToolWindow * toolwindow)832 LabelWindow::LabelWindow(ToolWindow *toolwindow) :
833 bt::EventHandler() ,
834 m_pBbtool(toolwindow),
835 m_pDisplay(toolwindow->XDisplay()),
836 m_window(0),
837 m_pixmap(0),
838 m_x(0),
839 m_y(0),
840 m_widthNewMail(0),
841 m_widthTotalMail(0),
842 m_widthSeperator(0),
843 m_screen(toolwindow->getCurrentScreen())
844
845 {
846 }
847
~LabelWindow(void)848 LabelWindow::~LabelWindow(void)
849 {
850 if (m_pixmap) bt::PixmapCache::release(m_pixmap);
851 if (m_window) XDestroyWindow(m_pDisplay, m_window);
852 delete m_pPen;
853 }
854
createWindow(void)855 void LabelWindow::createWindow(void)
856 {
857 XSetWindowAttributes attrib;
858 unsigned long create_mask = CWBackPixmap | CWEventMask;
859
860 int i;
861 m_maxValue = 1;
862 for (i = 0; i < m_pBbtool->getResource()->report.number_of_digits; i++)
863 m_maxValue *= 10;
864
865 m_maxValue -= 1;
866
867
868 attrib.background_pixmap = ParentRelative;
869 attrib.cursor = XCreateFontCursor(m_pDisplay, XC_left_ptr);
870 attrib.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask |
871 FocusChangeMask | KeyPressMask | StructureNotifyMask;
872
873 if (!m_pBbtool->getResource()->label.transparent)
874 m_pixmap = bt::PixmapCache::find(m_screen,
875 m_pBbtool->getResource()->label.texture, m_width, m_height);
876 m_window = XCreateWindow(m_pDisplay, m_pBbtool->frameWindow()->window(), m_x, m_y,
877 m_width, m_height, 0,
878 m_pBbtool->getCurrentScreenInfo()->depth(), InputOutput,
879 m_pBbtool->getCurrentScreenInfo()->visual(),
880 create_mask, &attrib);
881
882 m_pPen = new bt::Pen(m_screen,
883 m_pBbtool->getResource()->label.newmail_textColor);
884 // lpen->setFont(m_pBbtool->getResource()->label.font);
885
886 redraw();
887 m_pBbtool->insertEventHandler(m_window, this);
888 XClearWindow(m_pDisplay, m_pBbtool->frameWindow()->window());
889 XMapWindow(m_pDisplay, m_pBbtool->frameWindow()->window());
890 XMapSubwindows(m_pDisplay, m_pBbtool->frameWindow()->window());
891
892
893 }
894
reconfigure(void)895 void LabelWindow::reconfigure(void)
896 {
897 if (!m_pBbtool->getResource()->label.transparent) {
898 bt::PixmapCache::release(m_pixmap);
899 m_pixmap = bt::PixmapCache::find(m_screen,
900 m_pBbtool->getResource()->label.texture, m_width, m_height);
901 }
902 XMoveResizeWindow(m_pDisplay, m_window, m_x, m_y, m_width, m_height);
903 delete m_pPen;
904 m_pPen = new bt::Pen(m_screen,
905 m_pBbtool->getResource()->label.newmail_textColor);
906
907 redraw();
908 }
909
calcSize()910 void LabelWindow::calcSize()
911 {
912 bt::ustring str;
913 char *t;
914 t = new char [m_pBbtool->getResource()->report.number_of_digits + m_pBbtool->getResource()->report.number_of_digits + 1 + 1];
915 if (m_pBbtool->getResource()->show.newmail_counter && m_pBbtool->getResource()->show.newmail_counter)
916 {
917 sprintf(t, "%0*d/%0*d", m_pBbtool->getResource()->report.number_of_digits, 0, m_pBbtool->getResource()->report.number_of_digits, 0);
918 str = bt::toUnicode(t);
919 unsigned int text_width = bt::textRect(m_pBbtool->getCurrentScreen(), m_pBbtool->getResource()->label.font, str).width();
920 m_width = text_width + 3 * m_pBbtool->getResource()->frame.bevelWidth;
921 sprintf(t, "%0*d", m_pBbtool->getResource()->report.number_of_digits, 0);
922 str = bt::toUnicode(t);
923 m_widthNewMail = bt::textRect(m_pBbtool->getCurrentScreen(), m_pBbtool->getResource()->label.font, str).width();
924 sprintf(t, "%0*d", m_pBbtool->getResource()->report.number_of_digits, 0);
925 str = bt::toUnicode(t);
926 m_widthTotalMail = bt::textRect(m_pBbtool->getCurrentScreen(), m_pBbtool->getResource()->label.font, str).width();
927 m_widthSeperator = text_width - m_widthNewMail - m_widthTotalMail;
928 }
929 else if (m_pBbtool->getResource()->show.newmail_counter) // split these up now, so we can use different number_of_digits later
930 {
931 sprintf(t, "%0*d", m_pBbtool->getResource()->report.number_of_digits, 0);
932 str = bt::toUnicode(t);
933 m_width = bt::textRect(m_pBbtool->getCurrentScreen(), m_pBbtool->getResource()->label.font, str).width() +
934 2 * m_pBbtool->getResource()->frame.bevelWidth;
935 }
936 else if (m_pBbtool->getResource()->show.totalmail_counter)
937 {
938 sprintf(t, "%0*d", m_pBbtool->getResource()->report.number_of_digits, 0);
939 str = bt::toUnicode(t);
940 m_width = bt::textRect(m_pBbtool->getCurrentScreen(), m_pBbtool->getResource()->label.font, str).width() +
941 2 * m_pBbtool->getResource()->frame.bevelWidth;
942 }
943 delete [] t;
944 }
945
946
redraw(void)947 void LabelWindow::redraw(void)
948 {
949 // redraw windows
950 if (m_pixmap == ParentRelative || m_pBbtool->getResource()->label.transparent) // we can remove the transparent option in the future
951 {
952 bt::Rect u(0, 0, width(), height());
953 bt::Rect t(-x(), -y(), m_pBbtool->frameWindow()->width(), m_pBbtool->frameWindow()->height());
954 bt::drawTexture(m_screen,
955 m_pBbtool->getResource()->frame.texture,
956 m_window,
957 t, u, m_pBbtool->frameWindow()->pixmap());
958 }
959 else
960 {
961 bt::Rect u(0, 0, width(), height());
962 bt::drawTexture(m_screen,
963 m_pBbtool->getResource()->label.texture,
964 m_window,
965 u, u, m_pixmap);
966 }
967
968 // redraw text
969 char t[6];
970 bt::ustring txt;
971 // if (m_pBbtool->getResource()->show.label)
972 // XClearWindow(m_pDisplay, m_window);
973 if (m_pBbtool->getResource()->show.newmail_counter) {
974 if (m_pBbtool->checkMail()->getNewmail() == 0)
975 XSetForeground(m_pDisplay, m_pPen->gc(),
976 m_pBbtool->getResource()->label.newmail_boring_textColor.pixel(m_screen));
977 else
978 XSetForeground(m_pDisplay, m_pPen->gc(),
979 m_pBbtool->getResource()->label.newmail_textColor.pixel(m_screen));
980
981 if (m_pBbtool->checkMail()->getNewmail() < m_maxValue) {
982 sprintf(t, "%0*d",m_pBbtool->getResource()->report.number_of_digits, m_pBbtool->checkMail()->getNewmail());
983 txt = bt::toUnicode(t);
984 bt::Rect text_rect = bt::textRect(m_screen, m_pBbtool->getResource()->label.font, txt);
985 text_rect.setX(m_pBbtool->getResource()->frame.bevelWidth);
986 text_rect.setY(text_rect.y() + m_pBbtool->getResource()->frame.bevelWidth);
987 text_rect.setWidth(m_widthNewMail);
988 drawText(m_pBbtool->getResource()->label.font, *m_pPen, m_window,
989 text_rect, bt::AlignCenter, txt);
990 } else {
991 sprintf(t, ">");
992 txt = bt::toUnicode(t);
993 bt::Rect text_rect = bt::textRect(m_screen, m_pBbtool->getResource()->label.font, txt);
994 text_rect.setX(m_pBbtool->getResource()->frame.bevelWidth);
995 text_rect.setY(text_rect.y() + m_pBbtool->getResource()->frame.bevelWidth);
996 text_rect.setWidth(m_widthNewMail);
997 drawText(m_pBbtool->getResource()->label.font, *m_pPen, m_window,
998 text_rect, bt::AlignCenter, txt);
999 }
1000 }
1001 if (m_pBbtool->getResource()->show.totalmail_counter) {
1002 if (m_pBbtool->getResource()->show.newmail_counter) {
1003 if ((m_pBbtool->checkMail()->getLastTotalmail() == 0) | (m_pBbtool->checkMail()->getNewmail() == 0))
1004 XSetForeground(m_pDisplay, m_pPen->gc(),
1005 m_pBbtool->getResource()->label.seperator_boring_textColor.pixel(m_screen));
1006 else
1007 XSetForeground(m_pDisplay, m_pPen->gc(),
1008 m_pBbtool->getResource()->label.seperator_textColor.pixel(m_screen));
1009 sprintf(t, SEPERATOR);
1010 txt = bt::toUnicode(t);
1011 bt::Rect text_rect = bt::textRect(m_screen, m_pBbtool->getResource()->label.font, txt);
1012 text_rect.setX(m_widthNewMail + m_pBbtool->getResource()->frame.bevelWidth);
1013 text_rect.setY(text_rect.y() + m_pBbtool->getResource()->frame.bevelWidth);
1014 text_rect.setWidth(m_widthSeperator);
1015 drawText(m_pBbtool->getResource()->label.font, *m_pPen, m_window,
1016 text_rect, bt::AlignCenter, txt);
1017 }
1018 if (m_pBbtool->checkMail()->getLastTotalmail() > m_maxValue) {
1019 sprintf(t, ">");
1020 txt = bt::toUnicode(t);
1021 bt::Rect text_rect = bt::textRect(m_screen, m_pBbtool->getResource()->label.font, txt);
1022 text_rect.setX(m_widthNewMail + m_widthSeperator + m_pBbtool->getResource()->frame.bevelWidth);
1023 text_rect.setY(text_rect.y() + m_pBbtool->getResource()->frame.bevelWidth);
1024 text_rect.setWidth(m_widthTotalMail);
1025 drawText(m_pBbtool->getResource()->label.font, *m_pPen, m_window,
1026 text_rect, bt::AlignCenter, txt);
1027 } else {
1028 if (m_pBbtool->checkMail()->getLastTotalmail() == 0) {
1029 XSetForeground(m_pDisplay, m_pPen->gc(),
1030 m_pBbtool->getResource()->label.totalmail_boring_textColor.pixel(m_screen));
1031 } else {
1032 XSetForeground(m_pDisplay, m_pPen->gc(),
1033 m_pBbtool->getResource()->label.totalmail_textColor.pixel(m_screen));
1034 }
1035
1036 sprintf(t, "%0*d", m_pBbtool->getResource()->report.number_of_digits, m_pBbtool->checkMail()->getLastTotalmail());
1037 txt = bt::toUnicode(t);
1038 bt::Rect text_rect = bt::textRect(m_screen, m_pBbtool->getResource()->label.font, txt);
1039 text_rect.setX( m_widthNewMail + m_widthSeperator + m_pBbtool->getResource()->frame.bevelWidth);
1040 text_rect.setY(text_rect.y() + m_pBbtool->getResource()->frame.bevelWidth);
1041 text_rect.setWidth(m_widthTotalMail);
1042 drawText(m_pBbtool->getResource()->label.font, *m_pPen, m_window,
1043 text_rect, bt::AlignCenter, txt);
1044 }
1045 }
1046 }
1047
buttonPressEvent(const XButtonEvent * xbutton_event)1048 void LabelWindow::buttonPressEvent(const XButtonEvent *xbutton_event)
1049 {
1050 if (xbutton_event->button == LEFT_BUTTON) {
1051 if (!m_pBbtool->isRaised()) {
1052 XRaiseWindow(m_pDisplay, m_pBbtool->frameWindow()->window());
1053 m_pBbtool->setRaised(true);
1054 }
1055 } else if (xbutton_event->button == MIDDLE_BUTTON) {
1056 if (m_pBbtool->isRaised()) {
1057 XLowerWindow(m_pDisplay, m_pBbtool->frameWindow()->window());
1058 m_pBbtool->setRaised(false);
1059 }
1060 }
1061 }
1062
exposeEvent(const XExposeEvent *)1063 void LabelWindow::exposeEvent(const XExposeEvent *)
1064 {
1065 redraw();
1066 }
1067
EnvelopeWindow(ToolWindow * toolwindow)1068 EnvelopeWindow::EnvelopeWindow(ToolWindow *toolwindow) :
1069 bt::EventHandler() ,
1070 display(toolwindow->XDisplay()),
1071 m_pBbtool(toolwindow),
1072 m_screen(toolwindow->getCurrentScreen()),
1073 m_window(0),
1074 ex(0),
1075 ey(0),
1076 pixmap(0),
1077 pixmap_pressed(0),
1078 envelope_pushed(false)
1079 {
1080 }
1081
~EnvelopeWindow(void)1082 EnvelopeWindow::~EnvelopeWindow(void)
1083 {
1084 if (pixmap) bt::PixmapCache::release(pixmap);
1085 if (pixmap_pressed) bt::PixmapCache::release(pixmap_pressed);
1086 int i;
1087 for (i = 0; i < num_of_pixmaps; i++) {
1088 bt::PixmapCache::release(pixmap_new[i]);
1089 bt::PixmapCache::release(pixmap_new_pressed[i]);
1090 }
1091
1092 delete [] pixmap_new;
1093 delete [] pixmap_new_pressed;
1094 delete epen;
1095
1096 if (m_window) XDestroyWindow(display, m_window);
1097 }
1098
createWindow(void)1099 void EnvelopeWindow::createWindow(void)
1100 {
1101 XSetWindowAttributes attrib;
1102 unsigned long create_mask = CWBackPixmap | CWCursor | CWEventMask;
1103 attrib.background_pixmap = ParentRelative;
1104 attrib.cursor = XCreateFontCursor(display, XC_left_ptr);
1105 attrib.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask |
1106 FocusChangeMask | KeyPressMask | StructureNotifyMask;
1107
1108
1109 pixmap = bt::PixmapCache::find(m_screen,
1110 m_pBbtool->getResource()->envelope.texture, ewidth, eheight);
1111
1112 pixmap_pressed = bt::PixmapCache::find(m_screen,
1113 m_pBbtool->getResource()->envelope.texture_pressed,
1114 ewidth, eheight);
1115
1116 num_of_pixmaps = m_pBbtool->getResource()->report.number_of_spoolfiles;
1117 pixmap_new = new Pixmap [num_of_pixmaps];
1118 pixmap_new_pressed = new Pixmap [num_of_pixmaps];
1119
1120 int i;
1121 for (i = 0; i < num_of_pixmaps; i++) {
1122 pixmap_new[i] = bt::PixmapCache::find(m_screen,
1123 m_pBbtool->getResource()->spoolfile[i].newmail_texture,
1124 ewidth, eheight);
1125
1126 pixmap_new_pressed[i] = bt::PixmapCache::find(m_screen,
1127 m_pBbtool->getResource()->spoolfile[i].newmail_pressed_texture,
1128 ewidth, eheight);
1129 }
1130
1131 m_window = XCreateWindow(display, m_pBbtool->frameWindow()->window(),
1132 ex, ey, ewidth, eheight, 0,
1133 m_pBbtool->getCurrentScreenInfo()->depth(),
1134 InputOutput, m_pBbtool->getCurrentScreenInfo()->visual(),
1135 create_mask, &attrib);
1136
1137 epen = new bt::Pen(m_screen, m_pBbtool->getResource()->envelope.textColor);
1138 //epen->setFont(m_pBbtool->getResource()->frame.font);
1139
1140 calcPoints();
1141
1142 m_pBbtool->insertEventHandler(m_window, this);
1143
1144 }
1145
reconfigure(void)1146 void EnvelopeWindow::reconfigure(void)
1147 {
1148 bt::PixmapCache::release(pixmap);
1149 bt::PixmapCache::release(pixmap_pressed);
1150
1151 int i;
1152 for (i = 0; i < num_of_pixmaps; i++) {
1153 bt::PixmapCache::release(pixmap_new[i]);
1154 bt::PixmapCache::release(pixmap_new_pressed[i]);
1155 }
1156
1157 delete [] pixmap_new;
1158 delete [] pixmap_new_pressed;
1159
1160 pixmap = bt::PixmapCache::find(m_screen,
1161 m_pBbtool->getResource()->envelope.texture, ewidth, eheight);
1162
1163 pixmap_pressed = bt::PixmapCache::find(m_screen,
1164 m_pBbtool->getResource()->envelope.texture_pressed,
1165 ewidth, eheight);
1166
1167 num_of_pixmaps = m_pBbtool->getResource()->report.number_of_spoolfiles;
1168 pixmap_new = new Pixmap [num_of_pixmaps];
1169 pixmap_new_pressed = new Pixmap [num_of_pixmaps];
1170
1171
1172 for (i = 0; i < num_of_pixmaps; i++) {
1173 pixmap_new[i] = bt::PixmapCache::find(m_screen,
1174 m_pBbtool->getResource()->spoolfile[i].newmail_texture,
1175 ewidth, eheight);
1176
1177 pixmap_new_pressed[i] = bt::PixmapCache::find(m_screen,
1178 m_pBbtool->getResource()->spoolfile[i].newmail_pressed_texture,
1179 ewidth, eheight);
1180 }
1181 delete epen;
1182 epen = new bt::Pen(m_screen, m_pBbtool->getResource()->envelope.textColor);
1183 calcPoints();
1184
1185 XMoveResizeWindow(display, m_window, ex, ey, ewidth, eheight);
1186 redraw();
1187 }
1188
release(void)1189 void EnvelopeWindow::release(void)
1190 {
1191 if (envelope_pushed) {
1192 envelope_pushed = false;
1193 m_pBbtool->redraw(false);
1194 }
1195 }
1196
buttonPressEvent(const XButtonEvent * xbutton_event)1197 void EnvelopeWindow::buttonPressEvent(const XButtonEvent *xbutton_event)
1198 {
1199 if (xbutton_event->button == LEFT_BUTTON) {
1200 if (!m_pBbtool->isRaised()) {
1201 XRaiseWindow(display, m_pBbtool->frameWindow()->window());
1202 m_pBbtool->setRaised(true);
1203 }
1204 envelope_pushed = true;
1205 m_pBbtool->redraw(false);
1206 } else if (xbutton_event->button == MIDDLE_BUTTON) {
1207 if (m_pBbtool->isRaised()) {
1208 XLowerWindow(display, m_pBbtool->frameWindow()->window());
1209 m_pBbtool->setRaised(false);
1210 }
1211 } else if (xbutton_event->button == RIGHT_BUTTON) {
1212 if (!envelope_pushed) {
1213 envelope_pushed = true;
1214 m_pBbtool->redraw(false);
1215 if (!m_pBbtool->mbMenu()->isVisible()) {
1216 m_pBbtool->mbMenu()->popup(m_pBbtool->frameWindow()->x(), m_pBbtool->frameWindow()->y(),
1217 m_pBbtool->config().isWithdrawn());
1218 }
1219 }
1220 }
1221 }
1222
buttonReleaseEvent(const XButtonEvent * xbutton_event)1223 void EnvelopeWindow::buttonReleaseEvent(const XButtonEvent *xbutton_event)
1224 {
1225 if (xbutton_event->button == LEFT_BUTTON) {
1226 envelope_pushed = false;
1227 m_pBbtool->redraw(false);
1228 if (xbutton_event->x > 0 && xbutton_event->x < (int)ewidth &&
1229 xbutton_event->y > 0 && xbutton_event->y < (int)eheight ) {
1230 if (m_pBbtool->checkMail()->getNewmail() != 0) {
1231 if (!m_pBbtool->getResource()->spoolfile[m_pBbtool->checkMail()->getNewMailbox()].runCommand.empty()) {
1232 system(m_pBbtool->getResource()->spoolfile[m_pBbtool->checkMail()->getNewMailbox()].runCommand.c_str());
1233 }
1234 else {
1235 if (!m_pBbtool->getResource()->report.runCommand.empty()) {
1236 system(m_pBbtool->getResource()->report.runCommand.c_str());
1237 }
1238 }
1239 } else {
1240 if (!m_pBbtool->getResource()->report.runCommand.empty()) {
1241 system(m_pBbtool->getResource()->report.runCommand.c_str());
1242 }
1243 }
1244 }
1245 }
1246 }
1247
exposeEvent(const XExposeEvent *)1248 void EnvelopeWindow::exposeEvent(const XExposeEvent *)
1249 {
1250 redraw();
1251 }
1252
calcPoints(void)1253 void EnvelopeWindow::calcPoints(void) {
1254 points[0].x = 2;
1255 points[0].y = 2;
1256 points[1].x = ewidth / 2;
1257 points[1].y = (eheight * 2) / 3;
1258 points[2].x = ewidth - 3;
1259 points[2].y = 2;
1260
1261 points[3].x = 2;
1262 points[3].y = eheight - 3;
1263 points[4].x = ewidth / 3;
1264 points[4].y = eheight / 2 - 1;
1265
1266 points[5].x = ewidth - 3;
1267 points[5].y = eheight - 3;
1268 points[6].x = (ewidth * 2) / 3;
1269 points[6].y = eheight / 2;
1270
1271 points[7].x = ewidth / 3;
1272 points[7].y = 2;
1273 points[8].x = (ewidth * 2) / 3 - 1;
1274 points[8].y = eheight / 2;
1275
1276 points[9].x = (ewidth * 2) / 3 - 1;
1277 points[9].y = 2;
1278 points[10].x = ewidth / 3;
1279 points[10].y = eheight / 2;
1280 }
1281
redraw(void)1282 void EnvelopeWindow::redraw(void)
1283 {
1284 if (m_pBbtool->checkMail()->getNewmail() == 0)
1285 {
1286
1287 if (envelope_pushed)
1288 {
1289 // XSetWindowBackgroundPixmap(display, m_window, pixmap_pressed);
1290 if (pixmap_pressed == ParentRelative)
1291 {
1292 bt::Rect u(0, 0, width(), height());
1293 bt::Rect t(-x(), -y(), m_pBbtool->frameWindow()->width(), m_pBbtool->frameWindow()->height());
1294 bt::drawTexture(m_screen,
1295 m_pBbtool->getResource()->frame.texture,
1296 m_window,
1297 t, u, m_pBbtool->frameWindow()->pixmap());
1298 }
1299 else
1300 {
1301 bt::Rect u(0, 0, width(), height());
1302 bt::drawTexture(m_screen,
1303 m_pBbtool->getResource()->envelope.texture_pressed,
1304 m_window,
1305 u, u, pixmap_pressed);
1306 }
1307 }
1308 else
1309 {
1310 // XSetWindowBackgroundPixmap(display, m_window, pixmap);
1311 if (pixmap == ParentRelative)
1312 {
1313 bt::Rect u(0, 0, width(), height());
1314 bt::Rect t(-x(), -y(), m_pBbtool->frameWindow()->width(), m_pBbtool->frameWindow()->height());
1315 bt::drawTexture(m_screen,
1316 m_pBbtool->getResource()->frame.texture,
1317 m_window,
1318 t, u, m_pBbtool->frameWindow()->pixmap());
1319 }
1320 else
1321 {
1322 bt::Rect u(0, 0, width(), height());
1323 bt::drawTexture(m_screen,
1324 m_pBbtool->getResource()->envelope.texture,
1325 m_window,
1326 u, u, pixmap);
1327 }
1328 }
1329
1330 XSetForeground(display, epen->gc(),
1331 m_pBbtool->getResource()->envelope.textColor.pixel(m_screen));
1332 XClearWindow(display, m_window);
1333 XDrawLines(display, m_window, epen->gc(), points, 3, CoordModeOrigin);
1334 XDrawLine(display, m_window, epen->gc(), points[3].x, points[3].y,
1335 points[4].x, points[4].y);
1336 XDrawLine(display, m_window, epen->gc(), points[5].x, points[5].y,
1337 points[6].x, points[6].y);
1338 if (m_pBbtool->checkMail()->getBroken()) {
1339 XSetForeground(display, epen->gc(),
1340 m_pBbtool->getResource()->envelope.error_textColor.pixel(m_screen));
1341 XSetLineAttributes(display, epen->gc() , 2, LineSolid, CapButt, JoinMiter);
1342 XDrawLine(display, m_window, epen->gc(), points[7].x, points[7].y,
1343 points[8].x, points[8].y);
1344 XDrawLine(display, m_window, epen->gc(), points[9].x, points[9].y,
1345 points[10].x, points[10].y);
1346 XSetLineAttributes(display, epen->gc(), 0, LineSolid,CapButt,JoinMiter);
1347 }
1348 } else {
1349 if (envelope_pushed)
1350 {
1351 if (pixmap_pressed == ParentRelative)
1352 {
1353 bt::Rect u(0, 0, width(), height());
1354 bt::Rect t(-x(), -y(), m_pBbtool->frameWindow()->width(), m_pBbtool->frameWindow()->height());
1355 bt::drawTexture(m_screen,
1356 m_pBbtool->getResource()->frame.texture,
1357 m_window,
1358 t, u, m_pBbtool->frameWindow()->pixmap());
1359 }
1360 else
1361 {
1362 bt::Rect u(0, 0, width(), height());
1363 bt::drawTexture(m_screen,
1364 m_pBbtool->getResource()->spoolfile[m_pBbtool->checkMail()->getNewMailbox()].newmail_pressed_texture,
1365 m_window,
1366 u, u, pixmap_new_pressed[m_pBbtool->checkMail()->getNewMailbox()]);
1367 }
1368
1369 // XSetWindowBackgroundPixmap(display, m_window,
1370 // pixmap_new_pressed[m_pBbtool->checkMail()->getNewMailbox()]);
1371 }
1372 else
1373 {
1374 if (pixmap_pressed == ParentRelative)
1375 {
1376 bt::Rect u(0, 0, width(), height());
1377 bt::Rect t(-x(), -y(), m_pBbtool->frameWindow()->width(), m_pBbtool->frameWindow()->height());
1378 bt::drawTexture(m_screen,
1379 m_pBbtool->getResource()->frame.texture,
1380 m_window,
1381 t, u, m_pBbtool->frameWindow()->pixmap());
1382 }
1383 else
1384 {
1385 bt::Rect u(0, 0, width(), height());
1386 bt::drawTexture(m_screen,
1387 m_pBbtool->getResource()->spoolfile[m_pBbtool->checkMail()->getNewMailbox()].newmail_texture,
1388 m_window,
1389 u, u, pixmap_new[m_pBbtool->checkMail()->getNewMailbox()]);
1390 }
1391 // XSetWindowBackgroundPixmap(display, m_window,
1392 // pixmap_new[m_pBbtool->checkMail()->getNewMailbox()]);
1393 }
1394 XSetForeground(display, epen->gc(),
1395 m_pBbtool->getResource()->spoolfile[m_pBbtool->checkMail()->getNewMailbox()].
1396 newmail_textColor.pixel(m_screen));
1397
1398 XClearWindow(display, m_window);
1399 XDrawLines(display, m_window, epen->gc(), points, 3, CoordModeOrigin);
1400 XDrawLine(display, m_window, epen->gc(), points[3].x,
1401 points[3].y, points[4].x, points[4].y);
1402 XDrawLine(display, m_window, epen->gc(), points[5].x, points[5].y,
1403 points[6].x, points[6].y);
1404
1405 if (m_pBbtool->checkMail()->getBroken()) {
1406 XSetForeground(display, epen->gc(),
1407 m_pBbtool->getResource()->spoolfile[m_pBbtool->checkMail()->getNewMailbox()].
1408 newmail_error_textColor.pixel(m_screen));
1409 XSetLineAttributes(display, epen->gc(), 2, LineSolid,CapButt,JoinMiter);
1410 XDrawLine(display, m_window, epen->gc(), points[7].x, points[7].y,
1411 points[8].x, points[8].y);
1412 XDrawLine(display, m_window, epen->gc(), points[9].x, points[9].y,
1413 points[10].x, points[10].y);
1414 XSetLineAttributes(display, epen->gc(), 0, LineSolid, CapButt, JoinMiter);
1415 }
1416 }
1417 }
1418
configureNotifyEvent(const XConfigureEvent * xconfigure_event)1419 void FrameWindow::configureNotifyEvent(const XConfigureEvent *xconfigure_event)
1420 {
1421 if (xconfigure_event->send_event) {
1422 if (m_pBbtool->config().isWithdrawn()) {
1423 m_pBbtool->reconfigure();
1424 }
1425 int parent_x,parent_y;
1426 Window parent_root;
1427 unsigned int parent_width;
1428 unsigned int parent_height;
1429 unsigned int parent_border_width;
1430 unsigned int parent_depth;
1431 if (m_pBbtool->config().isWithdrawn()) {
1432 XGetGeometry(display, xconfigure_event->above, &parent_root,
1433 &parent_x, &parent_y, &parent_width, &parent_height,
1434 &parent_border_width, &parent_depth);
1435 fx = xconfigure_event->x + parent_x;
1436 fy = xconfigure_event->y + parent_y;
1437 } else {
1438 fx = xconfigure_event->x;
1439 fy = xconfigure_event->y;
1440 if (m_pBbtool->config().isDecorated()) {
1441 char position[13];
1442 sprintf(position,"+%i+%i", fx, fy);
1443 m_pBbtool->config().setGeometry(position);
1444 }
1445 }
1446 if (m_pBbtool->mbMenu()->isVisible())
1447 m_pBbtool->mbMenu()->show();
1448 }
1449 }
1450