#include <stdio.h>
#include <stdlib.h>
#include <Xatom.h>
#include <Xos.h>
#include <Intrinsic.h>
#include <StringDefs.h>
#include <Xaw/Command.h>
#include <Xaw/Label.h>
#include <Xaw/Form.h>
#include <Xaw/Box.h>
#include <Xaw/AsciiText.h>
#include <Xaw/Paned.h> /* See comment around MakeSpecialForms */
#include "defs.h"
#include "externs.h"
#include "game.h"
#include "grades.h"
#include "options.h"
#include "search.h"
#include "searchwidgets.h"
#include "strokesearch.h"
#include "learn.h"
#include "utils.h"
#include "multikanji.h"
#include "init.h"
#include "log.h"
#include "timeout.h"
Widget toplevel,mainform;
XFontStruct *largekfont;
XFontStruct *smallkfont;
XFontStruct *englishfont;
XFontStruct *defaultfont;
Widget kanjiform,englishform,buttonform;
Widget statusline;
Widget currentkanjiForm;
Widget currentkanjiGrade,currentkanjiFreq,currentkanjiNum;
Widget kanjiMissed;
Widget choicesWidgets[NUMBEROFCHOICES],questionWidget;
Widget ONWidget;
static char * jumpAccel =
" <Key>Return: jump-to-kanji()";
/* setstatus:
* sets label for main status bar widget.
* ( the long one at the bottom)
* and also the same message at the bottom of the search popup window
*/
void setstatus(char *s)
{
if((statusline==NULL) || (searchstatusline==NULL)){
/* Some kind of warning message, before program has fullyh
* come up. Print to stdout instead
*/
printf("%s\n", s);
return;
}
XtVaSetValues(statusline,
XtNlabel,s,
NULL);
XtVaSetValues(searchstatusline,
XtNlabel,s,
NULL);
}
/* handle_button
* exists for the sole purpose of getting Button2 events
*/
void
handle_button(Widget w,XtPointer closure,XEvent *e,Boolean *cont)
{
XButtonEvent *event = (XButtonEvent *) e;
int buttoncount=0;
if(e->type == ClientMessage)
puts("CLIENT MESSAGE FROM BUTTONH");
if((event->button != Button2) &&
(event->button != Button3))
return;
#ifdef DEBUG
puts("Got button2/3 click?");
#endif
do {
if(w == choicesWidgets[buttoncount]){
break;
}
buttoncount++;
} while(buttoncount <NUMBEROFCHOICES);
if(buttoncount == NUMBEROFCHOICES){
puts("huh? how we get a click on a nonexistant button?");
quit(NULL, NULL, NULL);
}
printsearch(values[buttoncount]);
}
/* JumpToKanji
* callback when Return is pressed in Frequency or #index window
*/
int getclosestindex(int target){
int closestindex = lowestkanji;
int counter = lowestkanji-1;
while(counter <=highestkanji){
while(!UseThisKanji(counter)){
counter++;
if(counter >highestkanji){
setstatus("Using closest index available");
Beep();
return closestindex;
}
}
if(abs(target - closestindex) > abs(target - counter)){
closestindex = counter;
if(closestindex == target)
break;
}
counter++;
}
if(target != closestindex){
setstatus("Using closest index available");
Beep();
}
return closestindex;
}
/* given a frequency rating,
* will find the closest usable kanji
*/
int getindexfromfreq(int freq){
int closestindex = lowestkanji;
int closestfreq = translations[lowestkanji]->frequency;
int counter = lowestkanji-1;
while(counter <=highestkanji){
while(!UseThisKanji(counter)){
counter++;
if(counter >highestkanji)
return closestindex;
}
if(abs(closestfreq - freq) >
abs((translations[counter]->frequency) - freq) )
{
closestindex = counter;
closestfreq = translations[counter]->frequency;
if(closestfreq == freq)
break;
}
counter++;
}
return closestindex;
}
/* DescribeCurrent()
* Sets labels in MAIN window to display difficulty of
* reading displayed on the top
*/
void DescribeCurrent(TRANSLATION kanji)
{
int kindex;
if(kanji->kanji == NULL) {
kindex = 0;
} else {
kindex = kanji->kanji[0].byte1;
kindex = kindex <<8;
kindex |= kanji->kanji[0].byte2;
}
if(kindex == NOKANJI) {
kindex = 0;
}
SetWidgetNumberval(currentkanjiGrade,(int)kanji->grade_level);
SetWidgetNumberval(currentkanjiFreq,(int)kanji->frequency);
SetWidgetHexval(currentkanjiNum,kindex);
}
/* JumpToKanji
* This is the MAIN WINDOW "jump to kanji" routine.
* The search window has its own.
* This handles jump for either direct index, Or Frequency.
*/
void JumpToKanji(Widget w,XEvent *event,String *params,Cardinal *num_parags)
{
int kindex;
kindex = GetWidgetNumberval(w);
/* kindex is actually EITHER index, or
* frequency rating
*/
if(w == currentkanjiNum){
if((kindex <lowestkanji) || (kindex> highestkanji)){
SetWidgetHexval(w,kindex);
return;
}
kindex = getclosestindex(kindex);
} else {
if(kindex <1){
setstatus("negative frequencies do not occur");
/* SetWidgetNumberval(w,values[truevalue]);*/
return;
}
kindex = getindexfromfreq(kindex);
}
lastpicked = values[truevalue];
values[truevalue] = translations[kindex];
DescribeCurrent(translations[kindex]);
printallchoices();
printquestion();
return;
}
/* This is a special hack to attempt to force all the widgets to be the
* same size.
* It has the unfortunate side-effect of killing initial auto-size-width
* for the top-level main window.
* So if you use this, remember to do a good layout of the top-level window
* as well. SIGH.
*
* The standard creation methods like MakeQuestionWidget are set up to
* create the forms if they have not already been made here.
*/
void MakeSpecialForms(Widget parent){
/* We try to set resource so that we will be happy with EITHER
* a Paned parent, or a Form parent.
*
* Note that if the parent is PanedWidget, these forms will
* all be forcibly resized and stretched, ignoring
* XawChainXXX
*/
kanjiform = XtVaCreateManagedWidget("kanjiform",formWidgetClass, mainform,
XtNshowGrip, False,
XtNright, XawChainRight,
XtNleft, XawChainLeft,
XtNtop,XawChainBottom,
XtNbottom,XawChainBottom,
NULL);
englishform = XtVaCreateManagedWidget("englishform",formWidgetClass,
mainform,
XtNfromVert,kanjiform,
XtNvertDistance,10,
XtNshowGrip, False,
XtNright, XawChainRight,
XtNleft, XawChainLeft,
XtNtop,XawChainBottom,
XtNbottom,XawChainBottom,
NULL);
buttonform = XtVaCreateManagedWidget(
"buttonform",formWidgetClass,mainform,
XtNfromVert,englishform,
XtNvertDistance,15,
XtNshowGrip, False,
XtNskipAdjust, True,
XtNright, XawChainLeft,
XtNleft, XawChainLeft,
XtNtop,XawChainBottom,
XtNbottom,XawChainBottom,
NULL);
}
/* MakeCurrent;
* Makes window that describes current widget.
* Has current kanji grade, frequency, and index listed
* (It is now also editable, to enable jumping to a kanji)
*/
Widget MakeCurrent(Widget parent,Widget fromvert){
Widget gradelabel,freqlabel,numlabel;
XtAccelerators Accel;
currentkanjiForm = XtVaCreateManagedWidget(
"curkanjiForm",boxWidgetClass,parent,
/*XtNright,XawChainRight,XtNleft,XawChainRight,*/
XtNtop,XawChainTop, XtNbottom,XawChainTop,
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNfromVert,fromvert,
XtNorientation,XtEhorizontal,
NULL);
gradelabel = XtVaCreateManagedWidget(
"currgradelabel",labelWidgetClass,currentkanjiForm,
XtNlabel,"G:",
XtNtop,XawChainTop,
XtNbottom,XawChainTop,
XtNborderWidth,0,
NULL);
currentkanjiGrade = XtVaCreateManagedWidget(
"curkanjiGrade",asciiTextWidgetClass,currentkanjiForm,
XtNwidth,30, /* match search window */
XtNstring," ",
XtNdisplayCaret,False,
NULL);
freqlabel = XtVaCreateManagedWidget(
"currfreqlabel",labelWidgetClass,currentkanjiForm,
XtNlabel,"F:",
XtNborderWidth,0,
NULL);
currentkanjiFreq = XtVaCreateManagedWidget(
"curkanjiFreq",asciiTextWidgetClass,currentkanjiForm,
XtNeditType,XawtextEdit,
XtNstring," ",
XtNwidth,INPUTWIDTH,
NULL);
numlabel = XtVaCreateManagedWidget(
"curNumlabel",labelWidgetClass,currentkanjiForm,
XtNlabel,"#x:",
XtNborderWidth,0,
NULL);
currentkanjiNum = XtVaCreateManagedWidget(
"curkanjiNum",asciiTextWidgetClass,currentkanjiForm,
XtNeditType,XawtextEdit,
XtNstring," ",
XtNwidth,INPUTWIDTH,
NULL);
/* NOTE ! ! we do NOT add a callback, because that is
* taken care of by the accelerators.
* callback is JumpToKanji
*/
Accel = XtParseAcceleratorTable(jumpAccel);
XtOverrideTranslations(currentkanjiFreq,Accel);
XtOverrideTranslations(currentkanjiNum,Accel);
return currentkanjiForm;
}
static char *missedAccel = " \
<Key>BackSpace: Accelerator(x)\n \
<Key>Delete: Accelerator(x)\n \
";
/* MakeQuestionWidget()
* set up widgets for top section of main window
*/
void MakeQuestionWidget(){
Widget tmplabel, qthrowaway;
XtAccelerators Accel;
if(kanjiform == NULL){
/* normally made in MakeSpecialForms() */
kanjiform = XtVaCreateManagedWidget(
"kanjiform",formWidgetClass, mainform,
XtNright, XawChainRight,
XtNleft, XawChainLeft,
XtNtop,XawChainBottom,
XtNbottom,XawChainBottom,
NULL);
}
questionWidget = XtVaCreateManagedWidget("questionlarge",
commandWidgetClass,
kanjiform,
XtNshapeStyle,XawShapeRoundedRectangle,
XtNcornerRoundPercent,50,
XtNlabel,"",
XtNwidth,FULLWIDTH,
XtNencoding,XawTextEncodingChar2b,
XtNfont,largekfont,
XtNtop,XawChainTop,
XtNbottom,XawChainTop,
XtNleft, XawChainLeft, XtNright,XawChainRight,
NULL);
#ifdef USE_OKU
ONWidget = XtVaCreateManagedWidget(
"ONreading",labelWidgetClass,kanjiform,
XtNlabel," ",
XtNencoding,XawTextEncodingChar2b,
XtNfont,smallkfont,
XtNtop,XawChainTop,
XtNbottom,XawChainTop,
XtNjustify,XtJustifyLeft,
XtNwidth,KANJIWIDTH * NUMBEROFCHOICES +
(NUMBEROFCHOICES *5),
XtNfromVert,questionWidget,
NULL);
#endif
/* now describe current kanji */
MakeCurrent(kanjiform,questionWidget);
tmplabel=XtVaCreateManagedWidget(
"missedlabel",labelWidgetClass,kanjiform,
XtNfromVert, questionWidget,
XtNfromHoriz, currentkanjiForm,
XtNtop,XawChainTop,
XtNbottom,XawChainTop,
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNlabel,"missed",
XtNborderWidth,0,
/* nasty hardcode.. */
XtNvertDistance, 10,
NULL);
kanjiMissed=XtVaCreateManagedWidget(
"missedkanji",asciiTextWidgetClass,kanjiform,
XtNfromVert, questionWidget,
XtNfromHoriz, tmplabel,
XtNtop,XawChainTop,
XtNbottom,XawChainTop,
XtNleft, XawChainLeft, XtNright,XawChainLeft,
/*XtNlabel,"00/00/00",*/
/* hardcode numbers, becuase ascitxtwidget is wierd*/
XtNwidth, (int)(INPUTWIDTH *1.5) ,
XtNdisplayCaret,False,
XtNvertDistance, 10,
NULL);
/* Xaw layout is a black art. This is solely for spacing */
/*
qthrowaway=XtVaCreateManagedWidget(
"qthrowaway",asciiTextWidgetClass,kanjiform,
XtNfromVert, questionWidget,
XtNfromHoriz, kanjiMissed,
XtNtop,XawChainTop,
XtNbottom,XawChainTop,
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNlabel,"0",
XtNdisplayCaret,False,
NULL);
*/
Accel = XtParseAcceleratorTable(missedAccel);
XtOverrideTranslations(kanjiMissed,Accel);
}
/* MakeEnglishButtons:
* Just that. initialize the english buttons that display the possible
* guesses.
*/
void MakeChoicesButtons(){
int i;
if(englishform==NULL) {
/* See also MakeSpecialWidgets() */
englishform = XtVaCreateManagedWidget(
"englishform",formWidgetClass, mainform,
XtNfromVert,kanjiform,
XtNvertDistance,5,
XtNright, XawChainRight,
XtNleft, XawChainLeft,
XtNtop,XawChainBottom,
XtNbottom,XawChainBottom,
NULL);
}
for(i=0;i<NUMBEROFCHOICES;i++){
char labl[20];
sprintf(labl,"english%d",i);
if(i==0){
choicesWidgets[0]=XtVaCreateWidget(
labl,commandWidgetClass,englishform,
XtNwidth,FULLWIDTH,
XtNright,XawChainRight,
XtNleft,XawChainLeft,
XtNtop,XawChainTop,
XtNbottom,XawChainTop,
XtNfont,largekfont,
XtNvertDistance,10,
XtNshapeStyle,XawShapeRoundedRectangle,
XtNcornerRoundPercent,50,
NULL);
} else {
choicesWidgets[i]=XtVaCreateWidget(
labl,commandWidgetClass,englishform,
XtNwidth,FULLWIDTH,
XtNright,XawChainRight, XtNleft,XawChainLeft,
XtNtop,XawChainTop, XtNbottom,XawChainTop,
XtNfont,largekfont,
XtNfromVert,choicesWidgets[i-1],
XtNshapeStyle,XawShapeRoundedRectangle,
XtNcornerRoundPercent,50,
NULL);
}
XtAddEventHandler(choicesWidgets[i],ButtonPressMask,False,
handle_button,NULL);
XtAddCallback(choicesWidgets[i],
XtNcallback,choicescallback,(XtPointer) i);
}
XtManageChildren(choicesWidgets,NUMBEROFCHOICES);
}
void MakeButtons(){
Widget w[7];
if(buttonform==NULL){
/* See also MakeSpecialForms(). sigh */
buttonform = XtVaCreateManagedWidget(
"buttonform",formWidgetClass,mainform,
XtNfromVert,englishform,
XtNvertDistance,15,
XtNright, XawChainLeft, XtNleft, XawChainLeft,
XtNtop,XawChainBottom, XtNbottom,XawChainBottom,
NULL);
}
w[0] = XtVaCreateWidget("quit",commandWidgetClass,buttonform,
XtNlabel,"quit",
XtNshapeStyle,XawShapeEllipse,
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNtop,XawChainBottom, XtNbottom,XawChainBottom,
NULL);
w[1] = XtVaCreateWidget("cheat",commandWidgetClass,buttonform,
XtNfromHoriz,w[0],
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNtop,XawChainBottom, XtNbottom,XawChainBottom,
NULL);
w[2]= XtVaCreateManagedWidget("back",commandWidgetClass,
buttonform,
XtNlabel,"prev. char",
XtNfromHoriz,w[1],
/*XtNshapeStyle,XawShapeEllipse,*/
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNtop,XawChainBottom, XtNbottom,XawChainBottom,
NULL);
w[3]= XtVaCreateManagedWidget("log",commandWidgetClass,
buttonform,
XtNlabel,"Log",
XtNfromHoriz,w[2],
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNtop,XawChainBottom, XtNbottom,XawChainBottom,
/*XtNshapeStyle,XawShapeEllipse,*/
NULL);
w[4] = XtVaCreateWidget("options",commandWidgetClass,
buttonform,
XtNlabel,"options",
XtNfromHoriz,w[3],
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNtop,XawChainBottom, XtNbottom,XawChainBottom,
XtNshapeStyle,XawShapeEllipse,
NULL);
w[5]= XtVaCreateManagedWidget("search",commandWidgetClass,
buttonform,
XtNlabel,"Search",
XtNfromHoriz,w[4],
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNtop,XawChainBottom, XtNbottom,XawChainBottom,
XtNshapeStyle,XawShapeEllipse,
NULL);
w[6]= XtVaCreateManagedWidget("learn",commandWidgetClass,
buttonform,
XtNlabel,"Learn",
XtNfromHoriz,w[5],
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNtop,XawChainBottom, XtNbottom,XawChainBottom,
XtNshapeStyle,XawShapeEllipse,
NULL);
statusline = XtVaCreateManagedWidget("status",labelWidgetClass,
buttonform,
XtNlabel," Welcome to kanjidrill ",
XtNborderWidth,2,
XtNvertDistance,STATUSDISTANCE,
XtNfromVert,w[0],
XtNleft, XawChainLeft, XtNright,XawChainLeft,
XtNtop,XawChainBottom, XtNbottom,XawChainBottom,
NULL);
XtAddCallback(w[0],XtNcallback,quit,NULL);
XtAddCallback(w[1],XtNcallback,cheatcallback,NULL);
XtAddCallback(w[2],XtNcallback,BackCallback,NULL);
XtAddCallback(w[3],XtNcallback,MakeLog,NULL);
XtAddCallback(w[4],XtNcallback,OptionsCallback,NULL);
XtAddCallback(w[5],XtNcallback,SearchCallback,NULL);
XtAddCallback(w[6],XtNcallback,LearnCallback,NULL);
XtManageChildren(w,7);
}
void initfonts(){
char LargeKname[100],SmallKname[100],Efontname[100];
/* Widget tmplabel;*/
/* String tmpstring;*/
/* Sigh, okay this is ugly, tell me a better way...*/
/* Hell, tell me a way that WORKS, dammit... */
/*
tmplabel=XtVaCreateManagedWidget("tmplabel", labelWidgetClass,toplevel,
NULL);
XtVaGetValues(tmplabel, "XtNfont", &defaultfont, NULL);
if(defaultfont==NULL){
puts("ERROR: cannot find default font?!!");
exit(0);
}
XtDestroyWidget(tmplabel);
*/
GetXtrmString("kanjifont","Kanjifont",LargeKname);
GetXtrmString("smallkanji","Smallkanji",SmallKname);
GetXtrmString("englishfont","Englishfont",Efontname);
/* GetXtrmString("font", "Font", tmpstring);*/
#ifdef DEBUG
printf("kanjifont from resources is \"%s\"\n",LargeKname);
printf("smallkanjifont from resources is \"%s\"\n",SmallKname);
printf("regular font from resources is \"%s\"\n",Efontname);
#endif
largekfont = XLoadQueryFont(display,LargeKname);
smallkfont = XLoadQueryFont(display,SmallKname);
englishfont = XLoadQueryFont(display,Efontname);
/* defaultfont = XLoadQueryFont(display,tmpstring);*/
if(largekfont == NULL){
fprintf(stderr,"could not load large kanji font\n");
exit(0);
}
if(smallkfont == NULL){
fprintf(stderr,"could not load small kanji font\n");
exit(0);
}
if(englishfont == NULL){
fprintf(stderr,"could not load english font??\n");
exit(0);
}
}
static char *guessAccel = " \
Ctrl<Key>q: quit()\n \
<Key>1: guess-meaning(0)\n \
<Key>2: guess-meaning(1)\n \
<Key>3: guess-meaning(2)\n \
<Key>4: guess-meaning(3)\n \
<Key>5: guess-meaning(4)\n \
<Key>6: guess-meaning(5)\n \
<Key>7: guess-meaning(6)\n \
<Key>8: guess-meaning(7)\n \
<Key>9: guess-meaning(8)\n \
Shift<Key>c: Accelerator(C)\n \
<Key>c: Accelerator(c)\n \
Shift<Key>e: Accelerator(E)\n \
<Key>e: Accelerator(e)\n \
Shift<Key>k: Accelerator(K)\n \
<Key>k: Accelerator(k)\n \
Any<Key>l: Accelerator(l)\n \
Shift<Key>m: Accelerator(M)\n \
<Key>m: Accelerator(m)\n \
<Key>n: Accelerator(n)\n \
Shift<Key>o: Accelerator(O)\n \
<Key>F13: Accelerator(O)\n \
<Key>o: Accelerator(o)\n \
<Key>p: Accelerator(b)\n \
Any<Key>s: Accelerator(s)\n \
Shift<Key>t: Accelerator(T)\n \
<Key>u: Accelerator(u)\n \
<Key>F19: Accelerator(s)\n \
Shift<Key>a: Accelerator(S0)\n \
Shift<Key>1: Accelerator(S1)\n \
Shift<Key>2: Accelerator(S2)\n \
Shift<Key>3: Accelerator(S3)\n \
Shift<Key>4: Accelerator(S4)\n \
Shift<Key>5: Accelerator(S5)\n \
Shift<Key>6: Accelerator(S6)\n \
Shift<Key>7: Accelerator(S7)\n \
Shift<Key>=: Accelerator(S7)\n \
Shift<Key>+: Accelerator(S7)\n \
Shift<Key>KP_Add: Accelerator(S7)\n \
<Message>WM_PROTOCOLS: delete-window()\n \
<Message>WM_DELETE_WINDOW: delete-window()\n \
";
/* The 'Shift=' thing is a hack, because usually the '+' is actually
* the '=' key plus shift
*/
/* Accelerator()
* A jumping-off point for keyboard accelerators, as set above.
* This handles multiple widgets, so it can get messy.
* WARNING: It seems you can only have a single accelerator table
* for the ENTIRE PROGRAM. Not on a window-by-window basis.
* We check 'w' for pointer to the window involved, if needed
*
* Adding a new key in here also needs a line added in an Accel list,
* like guessAccel, above.
*/
void Accelerator(Widget w, XEvent *event,String *params,Cardinal *num_params){
int int_store;
char *param = *params;
if(*num_params <1){
puts("Warning: Accelerator function must have one argument!");
return;
}
if(*num_params >1){
printf("Warning: Accelerator functions take one argument, and one only\n");
}
switch(param[0]){
case 'b':
BackCallback(NULL,NULL,NULL);
break;
case 'c':
cheatcallback(NULL,NULL,NULL);
break;
case 'C':
supercheat();
break;
case 'e':
ChangeMode(NULL,(XtPointer) GUESS_ENGLISH,NULL);
break;
case 'E':
ChangeQuestion(NULL,(XtPointer) GUESS_ENGLISH,NULL);
break;
case 'k':
ChangeMode(NULL,(XtPointer) GUESS_KANJI,NULL);
break;
case 'K':
ChangeQuestion(NULL,(XtPointer) GUESS_KANJI,NULL);
break;
case 'l':
LearnCallback(NULL,(XtPointer) NULL,NULL);
break;
case 'm':
ChangeMode(NULL,(XtPointer) GUESS_KANA,NULL);
break;
case 'n':
if(w==learn_popup){
LearnNewChar(w, (XtPointer)True,NULL);
}
break;
case 'N':
if(w==learn_popup){
LearnNewChar(w, False,NULL);
}
break;
case 'M':
ChangeQuestion(NULL,(XtPointer) GUESS_KANA,NULL);
break;
case 'o':
ordercallback(orderbutton,NULL,NULL);
break;
case 'O':
OptionsCallback(NULL,NULL,NULL);
break;
case 'u':
UsefileCallback(usefilebutton,NULL,NULL);
break;
case 's':
SearchCallback(NULL,NULL,NULL);
break;
/* handle two-digit accelerator code.
* This is actually S[123456+]
*/
case 'S':
param+=1;
int_store = (*param)-'0';
GradeCallback(gradeButtons[int_store],
(XtPointer) int_store,NULL);
break;
case 'T':
TimerCallback(NULL,NULL,NULL);
break;
case 'x':
if(w== kanjiMissed){
ClearMissed();
break;
}
break;
default:
printf("DEBUG: unrecognized Accelerator '%c'\n",
param[0]);
}
}
/* delete_calback
* sole purpose is to handle window deletion. (like)<Message>WM_PROTOCOLS
* still technically selected, via Actions.? bizzare, and irritating that we
* have to use TWO METHODS to deal with this insanity. sigh.
*
* EXCEPT... This one seems to be to simply notify us.
* If we don't register this, the client dies. But now that
* we register this via XtAugmentTranslations... we dont actually
* have to do anything. Mindbogglingly stupid, really.
*/
void
delete_callback(Widget w, XEvent *event,String *params,Cardinal *num_params)
{
if(event->xclient.data.l[0] == delete_message){
/*
handle_delete(w, NULL, event, NULL);
*/
return;
}
puts("Got NON-delete event, in delete_callback?");
}
void quitaction(Widget w, XEvent * e, String *p, Cardinal *c)
{
quit(NULL, NULL, NULL);
}
/* deliberately a "nop". used primarily to make the RETURN key
* do nothing, when we want to disable it.
*/
void do_nothing(Widget w, XEvent * e, String *p, Cardinal *c)
{
return;
}
/* Different widgets may have different "Accelerator" tables,
* parsed by
* but all of them have to hook through this shared Actions list
*/
static XtActionsRec kdrillActionList[] = {
{ "quit", quitaction},
{ "update-frequency", UpdateFrequency},
{ "update-timeout", UpdateTimeout},
{ "do-find", DoFind},
{ "stroke-search", DoStrokeSearch}, /* ignore warning*/
{ "jump-to-kanji", JumpToKanji},
{ "guess-meaning", Guessvalue},
{ "Accelerator", Accelerator},
{ "delete-window", delete_callback},
{ "do-nothing", do_nothing},
};
XtAccelerators AllAccel;
void handle_delete(Widget,XtPointer,XEvent *,Boolean *);
/* MakeWidgets()
* Highest level routine for making ALL the widgets.
* This is THE starting point for making widgets
* (even the popup stuff actually gets created through here)
*/
void MakeWidgets(){
#ifdef DEBUG
puts("Starting MakeWidgets");
#endif
/* I suppose I shouldn't hard-code window-width and height..
but it makes things easier for now.
*/
#ifdef USEFORMFORTOP /* not currently used */
mainform = XtVaCreateManagedWidget("kdrill",formWidgetClass,
toplevel,
XtNvSpace,16,
XtNhSpace,10,
NULL);
#else
/* Note: This automatically stretches out the widgets to be
* the full width of the window
*/
mainform = XtVaCreateManagedWidget("kdrill",panedWidgetClass,
toplevel,
NULL);
#endif
initfonts();
XtAppAddActions(Context,kdrillActionList,XtNumber(kdrillActionList) );
AllAccel = XtParseAcceleratorTable(guessAccel);
/*XtOverrideTranslations(mainform,AllAccel);*/
XtAugmentTranslations(mainform,AllAccel);
MakeSpecialForms(mainform);
MakeQuestionWidget();
MakeChoicesButtons();
MakeOptionsPopup();
MakeSearchPopup();
MakeLearnPopup();
MakeMulti();
MakeButtons();
#ifdef DEBUG
puts("Ending MakeWidgets");
#endif
}