Logo Search packages:      
Sourcecode: bbmail version File versions  Download package

bbmail.cc

// bbmail.cc for bbmail - an tool for display the mail in X11.
//
//  Copyright (c) 1998-2000 by John Kennis, jkennis@chello.nl
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// (See the included file COPYING / GPL-2.0)
//

#include "bbmail.hh"
#include "version.h"
#include <utime.h>
#include <dirent.h>

Checkmail::Checkmail(ToolWindow *toolwindow)
{
      bbtool=toolwindow;
      timer=new BTimer(bbtool->getCurrentScreenInfo()->getBaseDisplay(),this) ;
      timer->setTimeout(bbtool->getResource()->report.check_delay*1000);
      timer->start();
      broken=False;
      last_totalmail=0;
      last_newmail=0;
      new_mailbox=0;
      spoolfile = new
                  LOCALSPOOLFILE[bbtool->getResource()->report.number_of_spoolfiles];
      memset(spoolfile,0,
             sizeof(LOCALSPOOLFILE)*bbtool->getResource()->report.number_of_spoolfiles);

      number_of_checks=bbtool->getResource()->report.force_check_delay;
}

Checkmail::~Checkmail()
{
      delete [] spoolfile;
}

void Checkmail::Reconfigure()
{
      delete [] spoolfile;
      spoolfile =
          new LOCALSPOOLFILE[bbtool->getResource()->report.number_of_spoolfiles];
      memset(spoolfile,0,
             sizeof(LOCALSPOOLFILE)*bbtool->getResource()->report.number_of_spoolfiles);
      number_of_checks=bbtool->getResource()->report.force_check_delay;
      timeout();
}

bool Checkmail::CheckMaildir(int spoolno)
{
      struct stat file_status, maildir_status;

      if (bbtool->getResource()->spoolfile[spoolno].filename==NULL) {
            fprintf(stderr,"No qmail maildir specified\n");
            return(false);
      }

      if (stat(bbtool->getResource()->spoolfile[spoolno].filename,
               &file_status)!=0) {
            fprintf(stderr,"Could not read status spool file %s\n",
                    bbtool->getResource()->spoolfile[spoolno].filename);
            return(false);
      }

      // check maildir new/

      if (stat(bbtool->getResource()->spoolfile[spoolno].new_maildir, &maildir_status)!=0) {
            fprintf(stderr,"Could not read status new maildir: %s\n",
                    bbtool->getResource()->spoolfile[spoolno].new_maildir);
            return(false);
      }
      if (maildir_status.st_mtime > file_status.st_mtime) {
            file_status.st_mtime = maildir_status.st_mtime;
      }

      if (stat(bbtool->getResource()->spoolfile[spoolno].cur_maildir, &maildir_status)!=0) {
            fprintf(stderr,"Could not read status current maildir: %s\n",
                    bbtool->getResource()->spoolfile[spoolno].cur_maildir);
            return(false);
      }
      if (maildir_status.st_mtime > file_status.st_mtime) {
            file_status.st_mtime = maildir_status.st_mtime;
      }

      if  (file_status.st_mtime != spoolfile[spoolno].last_mtime) {

            spoolfile[spoolno].last_mtime = file_status.st_mtime;
            spoolfile[spoolno].newmail=0;
            DIR *dir;

            if ((dir = opendir (bbtool->getResource()->spoolfile[spoolno].new_maildir)) == NULL) {
                  fprintf(stderr,"Could not open maildir %s\n",
                          bbtool->getResource()->spoolfile[spoolno].new_maildir);
                  return false;
            }

            while (readdir (dir))
                  spoolfile[spoolno].newmail++;
            /* -2 for . and .. */
            spoolfile[spoolno].newmail-=2;
            closedir(dir);

            if ((dir = opendir (bbtool->getResource()->spoolfile[spoolno].cur_maildir)) == NULL) {
                  fprintf(stderr,"Could not open maildir %s\n",
                          bbtool->getResource()->spoolfile[spoolno].new_maildir);
                  return false;
            }

            spoolfile[spoolno].totalmail=spoolfile[spoolno].newmail;

            while (readdir (dir))
                  spoolfile[spoolno].totalmail++;
            /* -2 for . and .. */
            spoolfile[spoolno].totalmail-=2;
            closedir(dir);
      }
      return(true);
}

bool Checkmail::CheckOther(int spoolno,bool force)
{
      struct stat file_status;
      FILE *fp;
      int num[2]={-1,-1};
      int number_of_values;


      if ((bbtool->getResource()->spoolfile[spoolno].proc==NULL)&
              (bbtool->getResource()->spoolfile[spoolno].proc==NULL)) {
            fprintf(stderr,"Nothing to do, no proc defined\n");
            return(false);
      }
      if (bbtool->getResource()->spoolfile[spoolno].filename!=NULL) {
            if (stat(bbtool->getResource()->spoolfile[spoolno].filename,
                     &file_status)!=0) {
                  fprintf(stderr,"Could not read status spool file %s\n",
                          bbtool->getResource()->spoolfile[spoolno].filename);
                  return(false);
            }
      }

      if  ((file_status.st_mtime != spoolfile[spoolno].last_mtime)&&
              (bbtool->getResource()->spoolfile[spoolno].filename!=NULL)||
              (force && bbtool->getResource()->spoolfile[spoolno].force_check)) {

            if (bbtool->getResource()->spoolfile[spoolno].second_ignore)
                  number_of_values=1;
            else
                  number_of_values=2;

            spoolfile[spoolno].last_mtime = file_status.st_mtime;
            int old_newmail=spoolfile[spoolno].newmail;
            spoolfile[spoolno].newmail=0;
            spoolfile[spoolno].totalmail=0;

            if (bbtool->getResource()->spoolfile[spoolno].proc!=NULL) {
                  if ((fp=(FILE*)popen(bbtool->getResource()->spoolfile[spoolno].proc,
                                       "r")) == NULL) {
                        fprintf(stderr,"Could not run command %s\n",
                                bbtool->getResource()->spoolfile[spoolno].proc);
                        return(false);
                  } else {
                        while (!(feof(fp))) {
                              if (ReadPipe(fp,num,number_of_values)!=0) {
                                    if (num[0]>old_newmail)
                                          new_mailbox=spoolno;
#ifdef DEBUG
                                    fprintf(stderr,"first int: %i, second int %i\n",num[0],num[1]);
#endif
                                    spoolfile[spoolno].newmail+=num[0];
                                    spoolfile[spoolno].totalmail+=num[1];
                              } else {
                                    if ((num[0]==-1)&(num[1]==-1)) {
                                          pclose(fp);
                                          return(false);
                                    }
                              }
                        }
                        pclose(fp);
                  }
            }
            if  (bbtool->getResource()->spoolfile[spoolno].reversedProc!=NULL) {
                  if ((fp=(FILE*)popen(
                              bbtool->getResource()->spoolfile[spoolno].reversedProc, "r"))
                          == NULL) {
                        fprintf(stderr,"Could not run command %s\n",
                                bbtool->getResource()->spoolfile[spoolno].reversedProc);
                        return(false);
                  } else {
                        while (!(feof(fp))) {
                              if (ReadPipe(fp,num,number_of_values)!=0) {
                                    if (num[1]>old_newmail) new_mailbox=spoolno;
                                    spoolfile[spoolno].newmail+=num[1];
                                    spoolfile[spoolno].totalmail+=num[0];
                              }
                        }
                        pclose(fp);
                  }
            }
            if (!bbtool->getResource()->spoolfile[spoolno].first_is_new)
                  spoolfile[spoolno].newmail=spoolfile[spoolno].totalmail-
                                             spoolfile[spoolno].newmail;
            if (!bbtool->getResource()->spoolfile[spoolno].second_is_total)
                  spoolfile[spoolno].totalmail=spoolfile[spoolno].newmail+
                                               spoolfile[spoolno].totalmail;

      }

      return(true);
}

void Checkmail::forceCheck()
{
      timeout();
}

bool Checkmail::getChar(char *string,int *index)
{
      bool special=false;
      if (string[*index]=='\\') {
            (*index)++;
      } else {
            if ((string[*index]=='[')|(string[*index]==']'))
                  special=true;
      }
      return(special);
}

bool Checkmail::checkStatusFlag(char *status_flag,int spoolno)
{
      int i,x,len;
      bool passed;

      len=strlen(bbtool->getResource()->spoolfile[spoolno].statusFlag);
      for (i=0,x=0;i<len;i++,x++) {
            if (getChar(bbtool->getResource()->spoolfile[spoolno].statusFlag,&i)) {
                  if ((bbtool->getResource()->spoolfile[spoolno].statusFlag[i]=='[')) {
                        passed=false;
                        while ((bbtool->getResource()->spoolfile[spoolno].statusFlag[i]!=']')
                                & (i<len)) {
                              i++;

                              if (!getChar(bbtool->getResource()->spoolfile[spoolno].statusFlag,
                                           &i))
                                    if (bbtool->getResource()->spoolfile[spoolno].statusFlag[i]==
                                            status_flag[x]) {
                                          passed=true;
                                    }
                        }
                        if (!passed) return false;
                  } else {
                        fprintf(stderr,"unexpected token in statusFlag\n");
                  }
            } else
                  if (bbtool->getResource()->spoolfile[spoolno].statusFlag[i]!=status_flag[x])
                        return(false);
      }
      return(true);
}

bool Checkmail::CheckMbox(int spoolno)
{
      int readmail=0;
      int mailcount=0;
      FILE *spool_id;
      bool read_status=True;
      char mailbuf[128];
      struct stat file_status;
      int len;
      struct utimbuf ut;

      if (bbtool->getResource()->spoolfile[spoolno].filename==NULL) {
            fprintf(stderr,"No mbox mailfile specified\n");
            return(false);
      }

      if (!(spool_id = fopen(bbtool->getResource()->spoolfile[spoolno].filename,
                             "r"))) {
            fprintf(stderr,"Could not open mail spool file %s\n",
                    bbtool->getResource()->spoolfile[spoolno].filename);
            return(false);
      }
      fstat(fileno(spool_id),&file_status);
      if(file_status.st_mtime != spoolfile[spoolno].last_mtime ||
              file_status.st_size != spoolfile[spoolno].last_size) {
            spoolfile[spoolno].last_mtime = file_status.st_mtime;
            spoolfile[spoolno].last_size = file_status.st_size;
            len = strlen(bbtool->getResource()->spoolfile[spoolno].statusFlag);
            while(fgets(mailbuf, 127, spool_id)) {
                  if(!strncmp(mailbuf, "From ", 5)) {
                        mailcount++;
                        read_status=False;
                  } else
                        if (checkStatusFlag(mailbuf,spoolno)) {
                              if(!read_status) {
                                    readmail++;
                                    read_status=True;
                              }
                        } else if (!strncmp(mailbuf,"Subject",7)) {
                              if (!strncmp(&mailbuf[9],
                                           "DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA",49)!=0) {
                                    mailcount--;
                                    read_status=True;
                              }
                        }

            }
            if ((mailcount-readmail)>spoolfile[spoolno].newmail)
                  new_mailbox=spoolno;
            spoolfile[spoolno].newmail=mailcount-readmail;
            spoolfile[spoolno].totalmail=mailcount;
#ifdef DEBUG
            fprintf(stderr,"mailcount=%d, readmail=%d, spoolno=%d\n",mailcount,
                    readmail,spoolno);
#endif
      }
      fclose(spool_id);
      ut.actime = file_status.st_atime;
      ut.modtime = file_status.st_mtime;
      utime(bbtool->getResource()->spoolfile[spoolno].filename, &ut);
      return(true);
}

void Checkmail::timeout()
{
      int totalmail=0;
      bool change_raise=False;
      bool force=False;
      int i,old_total,old_new;
      bool redraw=False;

      newmail=0;
      broken=False;
      if (bbtool->getResource()->report.force_check) {
            if (bbtool->getResource()->report.force_check_delay==number_of_checks) {
                  force=True;
                  number_of_checks=0;
            } else {
                  number_of_checks++;
#ifdef DEBUG
                  fprintf(stderr,"number_of_checks %i\n",number_of_checks);
#endif
            }
      }
      for (i=0;i<bbtool->getResource()->report.number_of_spoolfiles;i++) {
            old_new=spoolfile[i].newmail;
            old_total=spoolfile[i].totalmail;
            if (bbtool->getResource()->spoolfile[i].type==SpoolList::other) {
                  if (!(CheckOther(i,force))) {
                        broken=True;
                  } else {
                        newmail+=spoolfile[i].newmail;
                        totalmail+=spoolfile[i].totalmail;
                        if ((spoolfile[i].newmail!=old_new)|(spoolfile[i].totalmail!=old_total))
                              bbtool->mbmenu->UpdateNumbers(spoolfile[i].newmail,
                                                            spoolfile[i].totalmail,i);
                  }
            } else if (bbtool->getResource()->spoolfile[i].type==SpoolList::mbox) {
                  if (!(CheckMbox(i)))
                        broken=True;
                  else {
                        totalmail+=spoolfile[i].totalmail;
                        newmail+=spoolfile[i].newmail;
                        if ((spoolfile[i].newmail!=old_new)|(spoolfile[i].totalmail!=old_total))
                              bbtool->mbmenu->UpdateNumbers(spoolfile[i].newmail,
                                                            spoolfile[i].totalmail,i);
                  }
            } else if (bbtool->getResource()->spoolfile[i].type==SpoolList::maildir) {
                  if (!(CheckMaildir(i)))
                        broken=True;
                  else {
                        totalmail+=spoolfile[i].totalmail;
                        newmail+=spoolfile[i].newmail;
                        if ((spoolfile[i].newmail!=old_new)|(spoolfile[i].totalmail!=old_total))
                              bbtool->mbmenu->UpdateNumbers(spoolfile[i].newmail,
                                                            spoolfile[i].totalmail,i);
                  }
            }
      }
      if (bbtool->mbmenu->isVisible() && bbtool->mbmenu->WaitForUpdate())
            bbtool->mbmenu->Update();
      if (newmail>last_newmail)
            change_raise = True;
      else {
            /* are there  ny not empty mailboxes left */
            for (i=0;i<bbtool->getResource()->report.number_of_spoolfiles;i++) {
                  if (spoolfile[i].newmail!=0) {
                        new_mailbox=i;
                        //        change_raise = True;
                  }






            }
      }
      if ((newmail!=last_newmail)|(totalmail!=last_totalmail)|(broken) )
            redraw=True;
      last_newmail=newmail;
      last_totalmail=totalmail;
      if (redraw) bbtool->Redraw(change_raise);
}

int Checkmail::ReadPipe(FILE *fp,int num[2],int number_of_values)
{
      int i=0;
      bool found=False;
      bool newline=False;
      int x=0;
      char ch[6]={0,0,0,0,0,0};

      while (!(feof(fp))&(x!=number_of_values)&(ch[i]!='\n')&(!newline)) {
            fread(&ch[i],1,1,fp);
            while ((ch[i]>='0' && ch[i] <='9' && ch[1]!='\n')&(!feof(fp))) {
                  i++;
                  if (i==7) return(0);
                  fread(&ch[i],1,1,fp);
                  found=True;
            }
            if (ch[i]=='\n') newline=True;
            if (found) {
                  ch[i]='\0';
                  num[x]=atoi(ch);
                  i=0;
                  x++;
                  found=False;
            }
      }
      /* skip to next line */
      while (!(feof(fp))&(ch[0]!='\n')&(!newline))
            fread(&ch[0],1,1,fp);
      return(x);
}


ToolWindow::ToolWindow(int argc,char **argv,struct CMDOPTIONS *options):
            Basewindow(argc,argv,options)
{
      spooldir=options->spooldir;
      frame.x=0;
      frame.y=0;

      /* initialize image */
      envelopePushed=False;
      close_app=False;


      /* initialize xrm database */
      XrmInitialize();
      resource = new Resource(this);


      pixmaplist = new PIXMAPLIST[resource->report.number_of_spoolfiles];

      MakeWindow(False);
      checkmail=new Checkmail(this);
      Redraw(False);
      checkmail->forceCheck();
      eventLoop();
}

ToolWindow::~ToolWindow()
{
      int i;
      XUnmapWindow(getXDisplay(),framewin);

      /* destroy pixmaps */
      if (pixmap.frame) getImageControl()->removeImage(pixmap.frame);
      if (pixmap.label) getImageControl()->removeImage(pixmap.label);
      if (pixmap.envelope) getImageControl()->removeImage(pixmap.envelope);
      /* destroy windows */
      for (i=0;i<resource[i].report.number_of_spoolfiles;i++) {
            if (pixmaplist[i].envelope_newmail)
                  getImageControl()->removeImage(pixmaplist[i].envelope_newmail);
            if (pixmaplist[i].envelope_newmail_pressed)
                  getImageControl()->removeImage(pixmaplist[i].envelope_newmail_pressed);
      }


      if (frameGC) XFreeGC(getXDisplay(),frameGC);
      if (labelGC) XFreeGC(getXDisplay(),labelGC);
      if (menuGC) XFreeGC(getXDisplay(),menuGC);
      if (menuHiBGGC) XFreeGC(getXDisplay(),menuHiBGGC);
      if (menuHiGC) XFreeGC(getXDisplay(),menuHiGC);
      if (menuFrameGC)   XFreeGC(getXDisplay(),menuFrameGC);
      if (labelwin)     XDestroyWindow(getXDisplay(),labelwin);
      if (envelopewin) XDestroyWindow(getXDisplay(),envelopewin);
      XDestroyWindow(getXDisplay(),framewin);
      delete resource;
}


void ToolWindow::reconfigure(void)
{
      int i;

      /* destroy pixmaps */
      getImageControl()->removeImage(pixmap.frame);
      getImageControl()->removeImage(pixmap.label);
      getImageControl()->removeImage(pixmap.envelope);
      getImageControl()->removeImage(pixmap.envelope_pressed);
      for (i=0;i<resource->report.number_of_spoolfiles;i++) {
            getImageControl()->removeImage(pixmaplist[i].envelope_newmail);
            getImageControl()->removeImage(pixmaplist[i].envelope_newmail_pressed);
      }
      mbmenu->ClearMenu();
      delete [] pixmaplist;

      resource->Reload();
      mbmenu->Reconfigure();
      checkmail->Reconfigure();

      pixmaplist = new PIXMAPLIST[resource->report.number_of_spoolfiles];

      MakeWindow(True);

      if (resource->show.label) XClearWindow(getXDisplay(), labelwin);
      XClearWindow(getXDisplay(), envelopewin);
      XClearWindow(getXDisplay(), framewin);
      Redraw(False);
}


void ToolWindow::saveMenuSearch(Window window,Basemenu *menu)
{
      menuwin=window;
}

void ToolWindow::removeMenuSearch(Window window)
{
      menuwin= (Window )NULL;
}

Resource *ToolWindow::getResource()
{
      return resource;
}

void ToolWindow::MakeWindow(bool reconfigure)
{
      XSetWindowAttributes attrib;
      XWMHints wmhints;
      int i;
      max_value=1;
      for (i=0;i<resource->report.number_of_digits;i++)
            max_value*=10;

      max_value-=1;

      unsigned long create_mask = CWBackPixmap|CWCursor|CWEventMask;

      frame.height=resource->frame.font->ascent +
                   resource->frame.font->descent+4*resource->frame.bevelWidth;

      if (resource->show.envelope) {
            envelope.height=frame.height-2*resource->frame.bevelWidth -
                            2*resource->envelope.bevelHeight;
            envelope.width=(envelope.height*3)/2;

            if (!(fmod((double)envelope.width,2.0) > 0.0)) envelope.width++;
      } else
            envelope.width=0;

      label.width=label.width0=label.width1=label.width2=label.width3=0;
      int extra_space=0;

      if (resource->show.label) {

            label.width0 = XTextWidth(resource->label.font,"0",strlen("0"));
            if (resource->show.newmail_counter)
                  label.width1 = resource->report.number_of_digits*label.width0;
            if (resource->show.totalmail_counter)
                  label.width3 =  resource->report.number_of_digits*label.width0;
            if ((resource->show.totalmail_counter) & (resource->show.newmail_counter))
                  label.width2 = XTextWidth(resource->label.font,"/",strlen("/"));
            label.height=frame.height-2*resource->frame.bevelWidth;
            extra_space=resource->frame.bevelWidth;
            label.width=label.width1 + label.width2 + label.width3 +
                        2*resource->frame.bevelWidth;
      }

      frame.width =label.width + extra_space + envelope.width
                   + resource->frame.bevelWidth*2+resource->envelope.bevelWidth*2;

      if (resource->position.mask & XNegative)
            resource->position.x = getCurrentScreenInfo()->getWidth()+
                                   resource->position.x-frame.width;
      if (resource->position.mask & YNegative)
            resource->position.y = getCurrentScreenInfo()->getHeight()+
                                   resource->position.y-frame.height;

      if (!withdrawn) {
            frame.x=resource->position.x;
            frame.y=resource->position.y;
      }

      attrib.background_pixmap = ParentRelative;
      pixmap.frame = getImageControl()->renderImage(frame.width,
                     frame.height, &resource->frame.texture);

      if (withdrawn) {
            wmhints.initial_state = WithdrawnState;
      } else {
            wmhints.initial_state = NormalState;
      }

      attrib.cursor = getSessionCursor();
      attrib.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask |
                          FocusChangeMask | KeyPressMask | StructureNotifyMask;


      if    (!reconfigure) {
            framewin = XCreateWindow(getXDisplay(),
                                     getCurrentScreenInfo()->getRootWindow(), frame.x,
                                     frame.y, frame.width,
                                     frame.height, 0, getCurrentScreenInfo()->getDepth(),
                                     InputOutput,getCurrentScreenInfo()->getVisual(),
                                     create_mask, &attrib);
      } else if (!withdrawn) {
            XMoveResizeWindow(getXDisplay(),framewin,frame.x,
                              frame.y, frame.width,
                              frame.height);
      } else {
            XResizeWindow(getXDisplay(),framewin,frame.width,
                          frame.height);

      }
      wmhints.flags = IconWindowHint | StateHint;
      wmhints.icon_window = framewin;

      //  XSetStandardProperties(getXDisplay(),framewin,BBTOOL,
      //                 BBTOOL, None,getArgv(),getArgc(),NULL);
      XTextProperty windowname;
      XClassHint classhints;

      char *name=BBTOOL;
      XSizeHints sizehints;

      classhints.res_name=BBTOOL;
      classhints.res_class="bbtools";

      sizehints.x=getResource()->position.x;
      sizehints.y=getResource()->position.y;
      sizehints.max_width=sizehints.min_width=frame.width;
      sizehints.max_height=sizehints.min_height=frame.height;
      sizehints.flags=USPosition|PMinSize|PMaxSize;

      XStringListToTextProperty(&name,1,&windowname);
      XSetWMProperties(getXDisplay(),framewin,&windowname,NULL,getArgv(),getArgc(),
                       &sizehints,&wmhints,&classhints);
      Atom wmproto[2];
      wmproto[0]=wm_delete_window;
      wmproto[1]=getBlackboxStructureMessagesAtom();
      XSetWMProtocols(getXDisplay(), framewin,wmproto, 2);

      if (!decorated&&!withdrawn) {
            BlackboxHints bb_hints;
            bb_hints.decoration =DecorNone;
            bb_hints.attrib = AttribOmnipresent;
            bb_hints.flags = AttribDecoration|AttribOmnipresent;
            XChangeProperty(getXDisplay(), framewin, getBlackboxHintsAtom(),
                            getBlackboxHintsAtom(), 32, PropModeReplace,
                            (unsigned char *) &bb_hints,  PropBlackboxHintsElements);
      }


      if (!shape)
            XSetWindowBackgroundPixmap(getXDisplay(), framewin, pixmap.frame);

      if (resource->show.label) {
            if (!resource->label.transparent)
                  pixmap.label =
                      getImageControl()->renderImage(label.width, label.height,
                                                     &resource->label.texture);
            if (!reconfigure)
                  labelwin = XCreateWindow(getXDisplay(), framewin,
                                           2*resource->frame.bevelWidth
                                           +envelope.width+2*resource->envelope.bevelWidth,
                                           resource->frame.bevelWidth,
                                           label.width, label.height, 0,
                                           getCurrentScreenInfo()->getDepth(), InputOutput,
                                           getCurrentScreenInfo()->getVisual(),
                                           create_mask, &attrib);
            else
                  XMoveResizeWindow(getXDisplay(),labelwin,
                                    2*resource->frame.bevelWidth+
                                    envelope.width+2*resource->envelope.bevelWidth,
                                    resource->frame.bevelWidth, label.width, label.height);
            if (!resource->label.transparent)
                  XSetWindowBackgroundPixmap(getXDisplay(), labelwin, pixmap.label);
      }

      if (resource->show.envelope) {
            pixmap.envelope =
                getImageControl()->renderImage(envelope.width, envelope.height,
                                               &resource->envelope.texture);

            pixmap.envelope_pressed =
                getImageControl()->renderImage(envelope.width, envelope.height,
                                               &resource->envelope.texture_pressed);

            for (i=0;i<resource->report.number_of_spoolfiles;i++) {
                  pixmaplist[i].envelope_newmail =
                      getImageControl()->renderImage(envelope.width, envelope.height,
                                                     &resource->spoolfile[i].newmail_texture);

                  pixmaplist[i].envelope_newmail_pressed =
                      getImageControl()->renderImage(envelope.width, envelope.height,
                                                     &resource->spoolfile[i].newmail_pressed_texture);
            }

            if (!reconfigure)
                  envelopewin = XCreateWindow(getXDisplay(), framewin,
                                              resource->frame.bevelWidth+resource->envelope.bevelWidth,
                                              resource->frame.bevelWidth+resource->envelope.bevelWidth,
                                              envelope.width, envelope.height, 0,
                                              getCurrentScreenInfo()->getDepth(),
                                              InputOutput,getCurrentScreenInfo()->getVisual(),
                                              create_mask, &attrib);
            else
                  XMoveResizeWindow(getXDisplay(),envelopewin,
                                    resource->frame.bevelWidth+resource->envelope.bevelWidth,
                                    resource->frame.bevelWidth+resource->envelope.bevelWidth,
                                    envelope.width, envelope.height);


            points[0].x =  2;
            points[0].y =  2;
            points[1].x = envelope.width/2;
            points[1].y = (envelope.height*2)/3;
            points[2].x = envelope.width-3;
            points[2].y = 2;

            points[3].x=2;
            points[3].y=envelope.height-3;
            points[4].x=envelope.width/3;
            points[4].y=envelope.height/2-1;

            points[5].x=envelope.width-3;
            points[5].y=envelope.height-3;
            points[6].x=(envelope.width*2)/3;
            points[6].y=envelope.height/2;

            points[7].x=envelope.width/3;
            points[7].y=2;
            points[8].x=(envelope.width*2)/3-1;
            points[8].y=envelope.height/2;

            points[9].x=(envelope.width*2)/3-1;
            points[9].y=2;
            points[10].x=envelope.width/3;
            points[10].y=envelope.height/2;

      }




      if (!reconfigure) {

            if (resource->show.label) {
                  gcv.foreground = resource->label.newmail_textColor.getPixel();
                  gcv.font = resource->label.font->fid;
                  labelGC = XCreateGC(getXDisplay(), labelwin,GCFont, &gcv);
            }

            gcv.foreground = resource->envelope.textColor.getPixel();
            gcv.font = resource->frame.font->fid;
            frameGC = XCreateGC(getXDisplay(), framewin,GCFont, &gcv);

            gcv.font = resource->menu.font->fid;
            gcv.foreground = resource->menu.texture.getColor()->getPixel();
            menuGC = XCreateGC(getXDisplay(), framewin,GCFont|GCForeground, &gcv);

            gcv.foreground = resource->menu.highlightColor.getPixel();
            gcv.arc_mode = ArcChord;
            gcv.fill_style = FillSolid;
            menuHiBGGC = XCreateGC(getXDisplay(), framewin,GCForeground|
                                   GCFillStyle|GCArcMode, &gcv);

            gcv.foreground = resource->menu.hitextColor.getPixel();
            menuHiGC = XCreateGC(getXDisplay(), framewin,   GCFont|GCForeground, &gcv);

            gcv.foreground = resource->menu.textColor.getPixel();
            menuFrameGC = XCreateGC(getXDisplay(), framewin,GCFont|GCForeground, &gcv);

            mbmenu = new Mailboxmenu(this);
            mbmenu->Update();
      } else {
            if (resource->show.label) {
                  gcv.foreground = resource->label.newmail_textColor.getPixel();
                  gcv.font = resource->label.font->fid;
                  XChangeGC(getXDisplay(),labelGC,GCFont, &gcv);
            }

            gcv.foreground = resource->envelope.textColor.getPixel();
            gcv.font = resource->frame.font->fid;
            XChangeGC(getXDisplay(),frameGC,GCFont, &gcv);


            gcv.font = resource->menu.font->fid;
            gcv.foreground = resource->menu.texture.getColor()->getPixel();
            XChangeGC(getXDisplay(), menuGC,GCFont|GCForeground, &gcv);

            gcv.foreground = resource->menu.highlightColor.getPixel();
            XChangeGC(getXDisplay(), menuHiBGGC,GCFont|GCForeground, &gcv);

            gcv.foreground = resource->menu.hitextColor.getPixel();
            XChangeGC(getXDisplay(), menuHiGC, GCFont|GCForeground, &gcv);

            gcv.foreground = resource->menu.textColor.getPixel();
            XChangeGC(getXDisplay(), menuFrameGC,GCFont|GCForeground, &gcv);

      }

      if (!reconfigure) {
            XClearWindow(getXDisplay(), framewin);
            XMapWindow(getXDisplay(), framewin);
            XMapSubwindows(getXDisplay(), framewin);
            mapped=true;
            if (!decorated&&!withdrawn)
                  XMoveResizeWindow(getXDisplay(),framewin,frame.x,
                                    frame.y, frame.width,
                                    frame.height);
      }
}



void ToolWindow::Redraw(bool change_raise)
{
      if (resource->show.label) {
            char t[6];
            if (resource->show.label) XClearWindow(getXDisplay(),labelwin);
            if (resource->show.newmail_counter) {
                  if (checkmail->getNewmail()==0)
                        XSetForeground(getXDisplay(),labelGC,
                                       resource->label.newmail_boring_textColor.getPixel());
                  else
                        XSetForeground(getXDisplay(),labelGC,
                                       resource->label.newmail_textColor.getPixel());

                  if (checkmail->getNewmail()<max_value) {
                        sprintf(t, "%02d", checkmail->getNewmail());
                        int xposition=(resource->report.number_of_digits-strlen(t))
                                      *label.width0 + resource->frame.bevelWidth;
                        XDrawString(getXDisplay(), labelwin, labelGC, xposition,
                                    (label.height+resource->label.font->ascent-
                                     resource->label.font->descent) / 2,
                                    t, strlen(t));
                  } else {
                        sprintf(t, ">");
                        int xposition=(resource->report.number_of_digits-strlen(t))*
                                      label.width0 + resource->frame.bevelWidth;
                        XDrawString(getXDisplay(), labelwin, labelGC, xposition,
                                    (label.height+resource->label.font->ascent-
                                     resource->label.font->descent) / 2,
                                    t, strlen(t));
                  }
            }
            if (resource->show.totalmail_counter) {
                  int totalmail_xposition=label.width0;
                  if (resource->show.newmail_counter) {
                        if ((checkmail->getLastTotalmail()==0)|(checkmail->getNewmail()==0))
                              XSetForeground(getXDisplay(),labelGC,
                                             resource->label.seperator_boring_textColor.getPixel());
                        else
                              XSetForeground(getXDisplay(),labelGC,
                                             resource->label.seperator_textColor.getPixel());
                        sprintf(t, "/");

                        XDrawString(getXDisplay(), labelwin, labelGC, label.width1 +
                                    resource->frame.bevelWidth,
                                    (label.height+resource->label.font->ascent-
                                     resource->label.font->descent) / 2,t, strlen(t));
                        totalmail_xposition=label.width1+label.width2 +
                                            resource->frame.bevelWidth;
                  }
                  if (checkmail->getLastTotalmail()>max_value) {
                        sprintf(t, ">");
                        XDrawString(getXDisplay(), labelwin, labelGC, totalmail_xposition,
                                    (label.height+resource->label.font->ascent-
                                     resource->label.font->descent) / 2,t, strlen(t));
                  }     else {
                      if (checkmail->getLastTotalmail()==0)
                      XSetForeground(getXDisplay(),labelGC,
                                     resource->label.totalmail_boring_textColor.getPixel());
                      else
                            XSetForeground(getXDisplay(),labelGC,
                                           resource->label.totalmail_textColor.getPixel());

                            sprintf(t, "%02d", checkmail->getLastTotalmail());
                            if (!(resource->show.newmail_counter))
                                  totalmail_xposition-=label.width0/2-1;
                                  XDrawString(getXDisplay(), labelwin, labelGC, totalmail_xposition,
                                              (label.height+resource->label.font->ascent-
                                               resource->label.font->descent) / 2,t, strlen(t));
                              }
                        }
}

if (checkmail->getNewmail()==0) {
            mbmenu->setHighlight(-1);
            if (resource->show.envelope) {
                  if (envelopePushed)
                        XSetWindowBackgroundPixmap(getXDisplay(), envelopewin,
                                                   pixmap.envelope_pressed);
                  else
                        XSetWindowBackgroundPixmap(getXDisplay(), envelopewin,
                                                   pixmap.envelope);
                  XSetForeground(getXDisplay(),frameGC,
                                 resource->envelope.textColor.getPixel());
                  XClearWindow(getXDisplay(),envelopewin);
                  XDrawLines(getXDisplay(),envelopewin,frameGC,points,3,CoordModeOrigin);
                  XDrawLine(getXDisplay(), envelopewin, frameGC, points[3].x, points[3].y,
                            points[4].x, points[4].y);
                  XDrawLine(getXDisplay(), envelopewin, frameGC, points[5].x, points[5].y,
                            points[6].x, points[6].y);
                  if (checkmail->getBroken()) {
                        XSetForeground(getXDisplay(),frameGC,
                                       resource->envelope.error_textColor.getPixel());
                        XSetLineAttributes(getXDisplay(),frameGC,2,LineSolid,CapButt,JoinMiter);
                        XDrawLine(getXDisplay(), envelopewin, frameGC, points[7].x, points[7].y,
                                  points[8].x, points[8].y);
                        XDrawLine(getXDisplay(), envelopewin, frameGC, points[9].x, points[9].y,
                                  points[10].x, points[10].y);
                        XSetLineAttributes(getXDisplay(),frameGC,0,LineSolid,CapButt,JoinMiter);
                  }
            }

            if (resource->show.onlyAtNewMail&mapped) {
                  XUnmapSubwindows(getXDisplay(),framewin);
                  XUnmapWindow(getXDisplay(),framewin);
                  mapped=false;
            }
      } else {
            if (resource->show.envelope) {
                  mbmenu->setHighlight(checkmail->getNewMailbox());
                  if (envelopePushed)
                        XSetWindowBackgroundPixmap(getXDisplay(), envelopewin,
                                                   pixmaplist[checkmail->getNewMailbox()].envelope_newmail_pressed);
                  else
                        XSetWindowBackgroundPixmap(getXDisplay(), envelopewin,
                                                   pixmaplist[checkmail->getNewMailbox()].envelope_newmail);
                  XSetForeground(getXDisplay(),frameGC,
                                 resource->spoolfile[checkmail->getNewMailbox()].
                                 newmail_textColor.getPixel());

                  XClearWindow(getXDisplay(),envelopewin);
                  XDrawLines(getXDisplay(),envelopewin,frameGC,points,3,CoordModeOrigin);
                  XDrawLine(getXDisplay(), envelopewin, frameGC, points[3].x,
                            points[3].y, points[4].x, points[4].y);
                  XDrawLine(getXDisplay(), envelopewin, frameGC,points[5].x, points[5].y,
                            points[6].x, points[6].y);

                  if (checkmail->getBroken()) {
                        XSetForeground(getXDisplay(),frameGC,
                                       resource->spoolfile[checkmail->getNewMailbox()].
                                       newmail_error_textColor.getPixel());
                        XSetLineAttributes(getXDisplay(),frameGC,2,LineSolid,CapButt,JoinMiter);
                        XDrawLine(getXDisplay(), envelopewin, frameGC, points[7].x, points[7].y,
                                  points[8].x, points[8].y);
                        XDrawLine(getXDisplay(), envelopewin, frameGC, points[9].x, points[9].y,
                                  points[10].x, points[10].y);
                        XSetLineAttributes(getXDisplay(),frameGC,0,LineSolid,CapButt,JoinMiter);
                  }
            }
            if ((resource->show.onlyAtNewMail) & (!(mapped))) {
                  XMapSubwindows(getXDisplay(),framewin);
                  XMapWindow(getXDisplay(),framewin);
                  mapped=true;
            }
            if (change_raise) {
                  if (resource->spoolfile[checkmail->getNewMailbox()].bell)
                        XBell(getXDisplay(),100);
                  if ((resource->spoolfile[checkmail->getNewMailbox()].newmailProc!=NULL));
                  system(resource->spoolfile[checkmail->getNewMailbox()].newmailProc);
                  if ((resource->report.auto_raise)&(!(raised))) {
                        XRaiseWindow(getXDisplay(),framewin);
                        raised=True;
                  }
            }
      }
}

void ToolWindow::process_event(XEvent *Event)
{
      /* process events */
      switch (Event->type) {
      case ClientMessage:
            {
                  if ((unsigned)Event->xclient.data.l[0]==wm_delete_window) shutdown();
            }
            break;
      case Expose:
            {
                  if (Event->xexpose.window==menuwin)
                        mbmenu->exposeEvent(&Event->xexpose);
                  else
                        Redraw(False);
            }
            break;
      case ButtonPress:
            {
                  if (Event->xbutton.window == menuwin)
                        mbmenu->buttonPressEvent(&Event->xbutton);
                  else {
                        if (Event->xbutton.button == LEFT_BUTTON) {
                              if (!(raised)) {
                                    XRaiseWindow(getXDisplay(),framewin);
                                    raised=True;
                              }
                              if (Event->xbutton.window==envelopewin) {
                                    envelopePushed=True;
                                    Redraw(False);
                              }
                        } else if (Event->xbutton.button == MIDDLE_BUTTON) {
                              if (raised) {
                                    XLowerWindow(getXDisplay(),framewin);
                                    raised=False;
                              }
                        } else if (Event->xbutton.button == RIGHT_BUTTON) {
                              if (Event->xbutton.window==envelopewin) {
                                    if (!envelopePushed) {
                                          envelopePushed=True;
                                          Redraw(False);

                                          if (mbmenu->isVisible())
                                                mbmenu->hide();
                                          else {
                                                if (mbmenu->WaitForUpdate()) mbmenu->Update();
                                                mbmenu->Move(frame.x,frame.y,withdrawn);
                                                mbmenu->show();
                                          }
                                    } else {
                                          envelopePushed=False;
                                          Redraw(False);
                                          mbmenu->hide();
                                    }
                              }
                        }
                  }
            }
            break;
      case ButtonRelease:
            {
                  if (Event->xbutton.window == menuwin)
                        mbmenu->buttonReleaseEvent(&Event->xbutton);
                  else {
                        if (Event->xbutton.button == LEFT_BUTTON) {
                              if (Event->xbutton.window==envelopewin) {
                                    envelopePushed=False;
                                    Redraw(False);
                                    if (Event->xbutton.x > 0 && Event->xbutton.x < envelope.width &&
                                            Event->xbutton.y >0 && Event->xbutton.y < envelope.height ) {
                                          if (checkmail->getNewmail()!=0)
                                                system(resource->
                                                       spoolfile[checkmail->getNewMailbox()].runCommand);
                                          else
                                                system(resource->report.runCommand);
                                    }
                              }
                        }
                        /*            if (Event->xbutton.button == RIGHT_BUTTON) {
                                      if (Event->xbutton.window==envelopewin)
                                                                  {
                                                                  }
                                                            }*/
                  }
            }
            break;
      case MotionNotify:
            {
                  if (Event->xmotion.window==menuwin)
                        mbmenu->motionNotifyEvent(&Event->xmotion);
            }
            break;
      case EnterNotify:
            {
                  if (Event->xcrossing.window==menuwin)
                        mbmenu->enterNotifyEvent(&Event->xcrossing);
            }
            break;
      case LeaveNotify:
            {
                  if (Event->xcrossing.window==menuwin)
                        mbmenu->leaveNotifyEvent(&Event->xcrossing);
            }
            break;
      case ConfigureNotify:
            {
                  if (Event->xconfigure.window==framewin &&
                          Event->xconfigure.send_event) {
                        if (withdrawn) {
                              reconfigure();
                        }
                        int parent_x,parent_y;
                        Window parent_root;
                        unsigned int parent_width;
                        unsigned int parent_height;
                        unsigned int parent_border_width;
                        unsigned int parent_depth;
                        if (withdrawn) {
                              XGetGeometry(getXDisplay(),Event->xconfigure.above,&parent_root,
                                           &parent_x,&parent_y,&parent_width,&parent_height,
                                           &parent_border_width,&parent_depth);
                              frame.x=Event->xconfigure.x+parent_x;
                              frame.y=Event->xconfigure.y+parent_y;
                        } else {
                              frame.x=Event->xconfigure.x;
                              frame.y=Event->xconfigure.y;
                              if (decorated) {
                                    if (position==NULL) position= new char [13];
                                    sprintf(position,"+%i+%i",frame.x,frame.y);
                              }
                        }

                        if (mbmenu->isVisible())
                              mbmenu->show();
                  }
            }
      }  /* switch */
}

Generated by  Doxygen 1.6.0   Back to index