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

window.c

/**************************************************
 window.c -- Copyright(c) 1999 Jiro Sekiba <jir@hello.to>
 **************************************************/
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<wchar.h>
#include<signal.h>

#include "cal.h"
#include "config.h"
#include "window.h"

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/keysymdef.h>
#include <X11/cursorfont.h>

#ifdef X_LOCALE
#include <X11/Xlocale.h>
#else
#include <locale.h>
#endif

#ifdef HAVE_LIBXEXT
#include <X11/extensions/shape.h>
#endif

static Display *dpy;
static Window Root;
static Window win;
static int screen_num;
static Pixmap pix;

static GC gc;

#ifdef HAVE_LIBXEXT
static Pixmap mask;
static GC mask_gc;
static int shape = 0;
#endif

static XFontSet fontset = NULL;
static int fontset_height;
static int max_text_width;
static int cell_width,cell_height;
static int window_width, window_height;
static int window_x,window_y;
static int rows,columns=7;
static int pad, num_week;

int target_year = 0;
int target_month = 0;

static int draw_month = -1;
static int draw_week = -1;

static struct Colors colors = {0L,0L,0L,0L,0L};
static enum Style style;

int init_display(char *display_name)
{
  XGCValues gcv;
  
  if((dpy = XOpenDisplay(display_name)) == NULL)
  {
    fprintf(stderr,"can't open display: %s\n",display_name);
    return 1;
  }
  Root = DefaultRootWindow(dpy);
  
  screen_num = DefaultScreen(dpy);
  gc = XCreateGC(dpy,Root,GCForeground|GCBackground,&gcv);

  return 0;
}

int load_fontset(char *fonts)
{
  XFontSet set = NULL;
  XFontSetExtents *extents;

  char **missingfonts;
  int count,i;
  char *defonts;

  if(!strlen(fonts))
    return 1;

  set = XCreateFontSet(dpy,fonts,&missingfonts,&count,&defonts);

  if(set)
  {
      if(fontset)
        XFreeFontSet(dpy,fontset);
      fontset = XCreateFontSet(dpy,fonts,&missingfonts,&count,&defonts);
      XFreeFontSet(dpy,set);
  }
  
  for(i=0;i<count;i++)
  {
      printf("missing: %s for Window\n",&*missingfonts[i]);
  }
  extents = XExtentsOfFontSet(fontset); 
  fontset_height = extents->max_logical_extent.height;
  return 0;
}

void calc_max_text_width()
{
  int i;
  int width;
  int max_width = 0;
  char str[8];
  XRectangle ink,logical;

  for(i=0;i<7;i++)
  {
    XwcTextExtents(fontset,weeks_name[i],wcslen(weeks_name[i]),&ink,&logical);
    width = ink.width;

    if(width > max_width)
      max_width = width;
  }

  for(i=10;i<32;i++)
  {
    sprintf(str,"%i",i);
    XmbTextExtents(fontset,str,strlen(str),&ink,&logical);
    width = ink.width;
    
    if(width > max_width)
      max_width = width;
  }
  max_text_width = max_width;
}

void init_style(enum Style style)
{
  switch(style)
  {
    case NORMAL_STYLE:
      rows = calc_rows(target_year,target_month, SUN);
      columns = 7;
      break;
    case MONDAY_STYLE:
      rows = calc_rows(target_year,target_month, MON);
      columns = 7;
      break;
    case LINE_STYLE:
      rows = 1;
      columns = calc_lastday(target_year,target_month); 
      break;
  }
#ifdef DEBUG
  printf("rows = %i\n",rows);
  printf("columns = %i\n",columns);
#endif
  
}


void calc_window_size()
{

  if(draw_month)
    rows++;
  if(draw_week)
    rows++;
  calc_max_text_width();
    
  cell_width = max_text_width + pad*2;
  cell_height = fontset_height + pad*2;
  window_width = cell_width * columns;
  window_height = cell_height * rows;

#ifdef DEBUG
  printf("max_text_width = %i\n",max_text_width);
  printf("cell_width = %i\n",cell_width);
  printf("cell_height = %i\n",cell_height);
  printf("window_width = %i\n",window_width);
  printf("window_height = %i\n",window_height);
#endif
}

void init_window()
{
  XSetWindowAttributes attributes;
  XWindowChanges changes;

  calc_window_size();
    
  win = XCreateSimpleWindow(dpy,Root,window_x,window_y,
                            window_width,window_height,0,0,0);
  attributes.override_redirect = True; /* independent from WindowManager */
  attributes.backing_store = Always; /* to save background pixmap */
  attributes.event_mask = StructureNotifyMask;
  XChangeWindowAttributes(dpy,win,
                          CWOverrideRedirect|CWBackingStore|CWEventMask,
                          &attributes);
  XSetWindowBackgroundPixmap( dpy, win, ParentRelative );
    
  changes.stack_mode = Below; /* alway below every window */
  XConfigureWindow(dpy,win,CWStackMode,&changes);

  pix = XCreatePixmap(dpy,win,window_width,window_height,
                      DefaultDepth(dpy,screen_num));

#ifdef HAVE_LIBXEXT
      {
        XGCValues gcv;

        mask = XCreatePixmap(dpy,Root,window_width,window_height,1);
        mask_gc = XCreateGC(dpy,mask,GCForeground|GCBackground,&gcv);
            /*create mask*/
        XSetForeground(dpy,mask_gc,0);
        XFillRectangle(dpy,mask,mask_gc,0,0,window_width,window_height);
        
        XSetForeground(dpy,mask_gc,1);
      }
#endif    
  
  
      XMapWindow(dpy,win);
}

static unsigned long getColor(char *colorName)
{
  XColor Color;
  XWindowAttributes Attributes;
    
  XGetWindowAttributes(dpy, Root, &Attributes);
  Color.pixel = 0;
    
  XParseColor (dpy, Attributes.colormap, colorName, &Color);
  Color.flags=DoRed | DoGreen | DoBlue;
  XAllocColor (dpy, Attributes.colormap, &Color);
    
  return Color.pixel;
}

static void wcDrawString(int x,int y,wchar_t *wstr,int len)
{
  XwcDrawString(dpy,pix,fontset,gc,x,y,wstr,len);
#ifdef HAVE_LIBXEXT
  XwcDrawString(dpy,mask,fontset,mask_gc,x,y,wstr,len);
#endif

}

static void drawCell(int column,int row,wchar_t *wstr)
{
  int len;
  int x,y;
  int text_width;
  XRectangle ink,logical;

  x = column * cell_width;
  y=  row * cell_height;

  len = wcslen(wstr);
  XwcTextExtents(fontset,wstr,len,&ink,&logical);
  text_width = logical.width;

  wcDrawString(x+(cell_width - text_width)/2,
             (y+fontset_height*3/4),wstr,len);
}

static void drawRow(int row,wchar_t *wstr)
{
  int len = 0;
  int text_width;

  XRectangle ink,logical;

  len = wcslen(wstr);
  XwcTextExtents(fontset,wstr,len,&ink,&logical);
  text_width = logical.width;
  wcDrawString((window_width-text_width)/2,
               row*cell_height+(pad+fontset_height*3/4),wstr,len);
}

void set_foreground(unsigned long color)
{
  XSetForeground(dpy,gc,color);

}

void write_cal(struct Colors *colors, enum Style style)
{
  char tmp[16];
  wchar_t wtmp[16];
  int mday;
  int row;
  int len,i,j,day,lastday,i_start;
  int loop;
  int offset;

  switch (style) {
    case NORMAL_STYLE:
    case LINE_STYLE:
      offset = calc_offset(target_year,target_month, SUN);
      break;
    case MONDAY_STYLE:
      offset = calc_offset(target_year,target_month, MON);
      break;
  }
  lastday = calc_lastday(target_year,target_month);
  row = 0;

      /*draw month*/
  if(draw_month)
  {
    set_foreground(colors->header);
    drawRow(row,month_name);
    row++;

  }
  
      /*draw day of week*/
  if(draw_week)
  {
    switch(style)
    {
      case NORMAL_STYLE:
        loop = columns;
        i_start = 0;
        break;
      case MONDAY_STYLE:
        loop = columns + 1;
        i_start = 1;
        break;
      case LINE_STYLE:
        loop = columns + offset;
        i_start = offset;
        break;
    }
    
    for(i=i_start;i<loop;i++)
    {
      if(i%7 == 0)
        set_foreground(colors->holiday);
      else if(i%7 == 6)
        set_foreground(colors->saturday);
      else
        set_foreground(colors->weekday);
      
      drawCell(i-i_start,row,weeks_name[i%7]);
    }
    row++;
  }

      /* draw days */
  for(j=row;j<rows;j++)
  {
    for(i=0;i<columns;i++)
    {
      day = (j-row)*columns+i+1;
      switch(style)
      {
        case MONDAY_STYLE:
          day = day-offset;
          mday = (day+offset)%7;
          break;
        case NORMAL_STYLE:
          day = day-offset;
        case LINE_STYLE:
          mday = (day+offset-1)%7;
          break;
      }

      if(lastday < day)
        break;
      else if(day < 1 )
        continue;

      if (day == today && target_month ==  this_month &&
          target_year == this_year)
        set_foreground(colors->today);
      else if(mday == 0 || is_holiday(target_year,target_month,day))
        set_foreground(colors->holiday);
      else if(mday == 6)
        set_foreground(colors->saturday);
      else
        set_foreground(colors->weekday);
        
      sprintf(tmp,"%i",day);
      len = strlen(tmp);
      mbstowcs(wtmp,tmp,len);
      wtmp[len] = 0L;
      drawCell(i,j,wtmp);
    }
  }
}

int destroy_data()
{
  XFreeFontSet(dpy,fontset);
  XFreePixmap(dpy,pix);
  XDestroyWindow(dpy,win);
  XCloseDisplay(dpy);
  return 0;
}

void set_background(Pixmap back)
{
  XSetWindowBackgroundPixmap( dpy, win, back);
  XClearWindow(dpy,win);
  XFlush(dpy);
}

int repaint()
{
  init_today();

  init_locale_data(target_year,target_month,num_week);

#ifdef HAVE_LIBXEXT
  if(shape)
    XShapeCombineMask(dpy,win,ShapeBounding,0,0,mask,ShapeSet);
  else
    set_background(ParentRelative);
#else  
  set_background(ParentRelative);
#endif  
  XCopyArea(dpy,win,pix,gc,0,0,window_width,window_height,0,0);
  write_cal(&colors,style);
  set_background(pix);
  return 0;
}

static void hup_handler(int signum)
{
  init_today();

  target_year = this_year;
  target_month = this_month;

  repaint();
}

int xdkcal(int year, int month,
           int win_x, int win_y,
           char *fonts, 
           char *default_col,
           char *holiday_col,
           char *saturday_col,
           char *today_col,
           char *header_col,
#ifdef HAVE_LIBXEXT
           int toshape,
#endif
           int padding,
           enum Style stl,
           int draw_mon,
           int draw_w,
           int num_w
           )
{
  XEvent event;
  struct sigaction act;

  target_year = year;
  target_month = month;
  window_x = win_x;
  window_y = win_y;
  pad = padding;
#ifdef HAVE_LIBXEXT
  shape = toshape;
#endif

  draw_month = draw_mon;
  draw_week = draw_w;
  
  num_week = num_w;

  init_display(NULL);
  load_fontset(fonts);
    
  colors.weekday = getColor(default_col);
  colors.holiday = getColor(holiday_col);
  colors.saturday = getColor(saturday_col);
  colors.today = getColor(today_col);
  colors.header = getColor(header_col);
  style = stl;

  act.sa_handler = hup_handler;
  act.sa_flags = SA_NODEFER;
  sigaction(SIGHUP,&act,NULL);

  init_style(style);
  init_window();

  init_today();

  do
  {
    XNextEvent(dpy,&event);
  }while(event.type!= ConfigureNotify);

  repaint();

  return 0;
}

Generated by  Doxygen 1.6.0   Back to index