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

init.c

#include <stdlib.h>     /* for srand48() */
#include <unistd.h>     /* for "access()" */
#include <stdio.h>

#include <limits.h>     /* for POSIX_PATH_MAX */

#include <Xatom.h>
#include <Xfuncs.h>     /* handles bzero redefine stuff */
#include <Xos.h>
#include <Intrinsic.h>
#include <StringDefs.h>
#include <Shell.h>
#include <Xaw/Command.h>
#include <Xaw/Label.h>
#include <Xaw/Form.h>
#include <Composite.h>


#include "defs.h"
#include "externs.h"
#include "game.h"
#include "grades.h"
#include "options.h"
#include "searchwidgets.h"
#include "widgets.h"
#include "timeout.h"

#include "icon_xbm"

int lowfrequency=0,highfrequency=0;

char *usefile=NULL;     /* global pointer that indicates if usefile is
                   * AVAILABLE, not neccessarily that it is used
                   */
char usefilename[100];

Atom wm_message,delete_message;


/*
 * This array has "fallback resources", in case
 * the normal "KDrill" resource file is not present.
 * Note that it is an either/or situation.
 * If there is a KDrill app-resources file on the system,
 * these fallback resources WILL NOT BE LOOKED AT !!!
 *
 *  If you add something to this list, consider adding it to
 *  SaveConfig() as well!!
 *  And dont forget that you have to use SetXtrmXXXX() routines
 *  to have the values available for SaveConfig() also!!
 *
 */
static char *fallback[] = {
      "KDrill.options_popupx:       0",
      "KDrill.options_popupy:       -200",
      "KDrill.search_popupx:        400", /* should really be precise,
                                    but... */
      "KDrill.search_popupy:        0",
      "KDrill.notallT:  0",
      "KDrill.noBell:         0",
      "KDrill.nousefile:      1",
      "KDrill.usefile:  .kanjiusefile", 
      DICTLOCATION,     /* change this value in Imakefile !!*/
      EDICTLOCATION,    /* change this value in Imakefile !!*/
      RADLOCATION,      /* change this value in Imakefile !!*/
      "KDrill.kanjifont:      -jis-*--24*jisx0208*",
      "KDrill.smallkanji:     -jis-*--16*jisx0208*",
      "KDrill.englishfont:    fixed",
      "KDrill.gradelevel:     0",
      "KDrill.guessmode:      english",
      "KDrill.questionmode:   kanji",
      "KDrill.romajiswitch:   0",
      "KDrill.lowfrequency:   0",
      "KDrill.highfrequency:  0",
      "KDrill.timersec: 7",
      "KDrill.logfile:  kdrill.log",
      NULL
};

/* command line arguments should set the appropriate resources.. so we can
 * pull them out when wanted
 */
static XrmOptionDescRec optionDescList[] = {
      {"-notallT",      ".notallT",XrmoptionNoArg,"1"},
      {"-usefile",      ".usefile", XrmoptionSepArg,(caddr_t) NULL},
      {"-nousefile",  ".nousefile", XrmoptionNoArg, "1"},
      {"-kdictfile",    ".kdictfile",     XrmoptionSepArg,(caddr_t) NULL},
      {"-edictfile",    ".edictfile",     XrmoptionSepArg,(caddr_t) NULL},
      {"-radkfile",     ".radkfile",      XrmoptionSepArg,(caddr_t) NULL},
      {"-englishfont",".englishfont",     XrmoptionSepArg,(caddr_t) NULL},
      {"-kanjifont",    ".kanjifont",     XrmoptionSepArg,(caddr_t) NULL},
      {"-smallkanji",   ".smallkanji",    XrmoptionSepArg,(caddr_t) NULL},
      {"-noBell",     ".noBell",    XrmoptionNoArg, "1"},
      {"-guessmode",    ".guessmode",     XrmoptionSepArg,(caddr_t) NULL},
      {"-questionmode",".questionmode",XrmoptionSepArg,(caddr_t) NULL},
      {"-romajiswitch",   ".romajiswitch",    XrmoptionNoArg,"1"},
      {"-showinorder",   ".showinorder",    XrmoptionNoArg,"1"},
      {"-gradelevel", ".gradelevel",  XrmoptionSepArg,(caddr_t) NULL},
      {"-lowfrequency", ".lowfrequency",XrmoptionSepArg,(caddr_t) NULL},
      {"-highfrequency",      ".highfrequency",XrmoptionSepArg,(caddr_t) NULL},
      {"-logfile",      ".logfile", XrmoptionSepArg,(caddr_t) NULL},
      
      
};



/* handle_delete
 *    Its sole purpose is to handle WM_DELETE messages.
 *    These days, we want to only CLOSE windows that aren't the
 *    main one.
 *
 */
void
handle_delete(Widget w,XtPointer closure,XEvent *event,Boolean *cont)
{
      XClientMessageEvent *cevent = (XClientMessageEvent *) event;
      puts("DEBUG: handle_delete called !!\n");

      if(cevent->type != ClientMessage) return;
      if(cevent->message_type != wm_message) return;
      if(cevent->data.l[0] != delete_message)  return;

      if(w == toplevel){
            quit(NULL, NULL, NULL);
      }

#ifdef DEBUG
      puts("In handle_delete...");
      if(XtIsTopLevelShell(w)){
            puts("   IS a top level shell");
      }
      if(XtIsShell(w)){
            puts("   IS a  shell");
      }
      if(XtIsTransientShell(w)){
            puts("   IS a 'transient' shell");
      }


      if(XtIsTopLevelShell(XtParent(w))){
            puts("   PARENT is a top level shell");
      }
      if(XtIsShell(XtParent(w))){
            puts("   PARENT is a  shell");
      }
      if(XtIsTransientShell(XtParent(w))){
            puts("   PARENT is a 'transient' shell");
      }

      
#endif /* DEBUG */


      /* Problem here: there are three types of windows we have
         to deal with:
         "Option window" type  (shell, transient)
         multi-match window  (toplevel, shell)
         seach window (toplevel, shell: but DIFFERENT from multi somehow)
         XtPopdown works for the first two, but only UnmapWidget works
         for last kind.
         The only difference I can see, is that the search window
         has "toplevel" as its parent, which is not strictly
         speaking just a window. It is what XtVaAppInitialize() returns.
         It CONTAINS a window, but is not merely a window.
         searchwindow is made that way, to remain open, when
         the main window is iconified.
         I *could* just special-case it. But i hate special cases.
      */
      XtPopdown(w);
      if(isMapped(w)){
            /* if it is still showing.. try harder! */
            XtUnmapWidget(w);
      }

}

/* initgc:
 *    Initialises global gc values.
 *      We don't really need this any more. But
 *    GC's are good to have, I suppose.
 */
void initgc(){

      gc =  XCreateGC(display,mainwindow,0,NULL);
      cleargc = XCreateGC(display,mainwindow,0,NULL);

      XSetForeground(display,gc,black);
      XSetBackground(display,gc,white);
      XSetForeground(display,cleargc,white);
      XSetBackground(display,cleargc,black);

}

/* GetOptions
 *    get resource and command line options.
 *    (The nice thing is that thanks to Xt, commandline options
 *     get auto-translated to resources already
 */

void GetOptions(){
      int tmpnumber;
      char tmpstr[100];


      /* set grade bits appropriately */
      GetXtrmString("gradelevel","Gradelevel",tmpstr);
      parsegrades(tmpstr);

      switchKanaEnglish = !GetXtrmBoolean("notallT","NotallT");
      /* default of nousefile is FALSE. which means
       * useUsefile defaults to TRUE
       */
      useUsefile = !GetXtrmBoolean("nousefile","Nousefile");

      doBell = !GetXtrmBoolean("noBell","NoBell");
      showinorder = GetXtrmBoolean("showinorder","Showinorder");

      lowfrequency = GetXtrmNumber("lowfrequency","Lowfrequency");
      if((lowfrequency <0) || (lowfrequency >=MAXTRANSLATIONSALLOWED))
            lowfrequency = 0;
      highfrequency = GetXtrmNumber("highfrequency","Highfrequency");
      if((highfrequency <0) || (highfrequency >=MAXTRANSLATIONSALLOWED))
            highfrequency = 0;

      tmpnumber = GetXtrmNumber("timersec","Timersec");
      setTimeoutLen(tmpnumber);
      

      GetXtrmString("guessmode", "Guessmode", tmpstr);
      if(strcmp(tmpstr, "english")==0){
            choicesmode = GUESS_ENGLISH;
      }else if(strcmp(tmpstr, "kanji")==0){
            choicesmode = GUESS_KANJI;
      } else{
            choicesmode = GUESS_KANA;
      }
      GetXtrmString("questionmode", "Questionmode", tmpstr);
      if(strcmp(tmpstr, "english")==0){
            questionmode=GUESS_ENGLISH;
      } else if (strcmp(tmpstr, "kanji")==0){
            questionmode=GUESS_KANJI;
      } else{
            questionmode=GUESS_KANA;
      }

      if( GetXtrmBoolean("romajiswitch","Romajiswitch"))
            romajiswitch = 1;

}


/* this routine is solely for internalizing various
 *  "Atoms" neccessary to handle the stupid WM_DELETE_WINDOW
 *  message
 */
void setup_deletewindow(Widget winwidget)
{

      /* Must wait for the window to actually appear. sigh.*/
      XFlush(display);
      XSync(display,False); /* This should be redundant, but... */

      if(wm_message==(Atom)NULL){
            wm_message=XInternAtom(display,"WM_PROTOCOLS",False);
            delete_message=XInternAtom(display,"WM_DELETE_WINDOW",False);
            if (wm_message == (Atom) NULL) {
                  perror("unable to create wm_message property");
                  exit(1);
            }
            if (delete_message == (Atom) NULL) {
                  perror("unable to create delete property");
                  exit(1);
            }
      }
      XtAddEventHandler(winwidget, NoEventMask, True,
                       handle_delete, (XtPointer)NULL);

      XtAugmentTranslations(winwidget, AllAccel);

      /* I haven't figured out why we would be called when this is 0.
       * Seems to be a strange bug in X. sigh.
       */ 
      if(XtWindow(winwidget)==0){
            /*printf("XtWindow is %d\n",XtWindow(winwidget));*/
            return;
      }

        XChangeProperty(display, XtWindow(winwidget),
                  wm_message, XA_ATOM, 32, PropModeReplace, 
                        (unsigned char *) &delete_message, 1);


}

#ifndef _POSIX_PATH_MAX
#define _POSIX_PATH_MAX 1024
#endif

/* If we have the appropriate functions (X11R6?)
 * load up our own special user-specific xresources file
 * We need the global 'display' set
 */
void init_xdb()
{
      char XFileName[_POSIX_PATH_MAX];
      XrmDatabase globaldb;

      sprintf(XFileName,"%s/.kdrill", homedir);
      globaldb=XrmGetDatabase(display);

      /* override "global" prefs with user specific ones */
      /* That way, we try to keep working, even if prefs file
       * is screwed up
       */
      XrmCombineFileDatabase(XFileName, &globaldb, True);
}

/* initstuffs:
 *    calls the various init routines to setup
 *    GCs, fonts, dictionaries, and widgets
 *    (But initializing the translations is done later)
 */

static Pixmap iconpixmap;

void initstuffs(int *argc,char *argv[])
{
      srand48 (time(NULL));

      bzero(translations, sizeof(struct translationstruct *) * MAXTRANSLATIONSALLOWED);
      lowestkanji = highestkanji = 0;

      homedir = (char *) getenv("HOME");
      if(homedir == NULL){
            puts("WARNING: no 'HOME' environment variable");
            puts("Faking with '.' instead");
            homedir=".";
      }

      toplevel = XtVaAppInitialize(&Context,"KDrill",
                           optionDescList,XtNumber(optionDescList),
                           argc,argv,fallback,
                           NULL,NULL);

      if(*argc >1){
            usage();
      }

      display = XtDisplay(toplevel);

      if(display == NULL) perror("NULL DISPLAY");

#ifndef NOXRMSAVE
      init_xdb();
#endif /*NOXRMSAVE*/


      /* Get command line options... yeah, we should do this in a
       *  struct, in one go... but some things need to be initalized
       * later
       */

      white = XWhitePixel(display,0);
      black = XBlackPixel(display,0);

      GetOptions();

      MakeWidgets();

      XtRealizeWidget(toplevel);

      mainwindow = XtWindow(toplevel);
      if(mainwindow == 0) perror("NULL WINDOW");
      
      setup_deletewindow(toplevel);

      iconpixmap = XCreateBitmapFromData(display,mainwindow,
                     (char *)icon_xbm_bits,
                     icon_xbm_width,icon_xbm_height);

      XtVaSetValues(toplevel,XtNiconName,"kdrill",
                  XtNiconPixmap,iconpixmap,NULL);

      /* Why doesnt this work? It should... ? */
      XtVaSetValues(search_popup,XtNiconName,"kdrill_search",
                  XtNiconPixmap,iconpixmap,NULL);


      initgc();

}


Generated by  Doxygen 1.6.0   Back to index