]> andersk Git - moira.git/blob - clients/mmoira/stubs.c
missed a shifted mouse translation
[moira.git] / clients / mmoira / stubs.c
1 /*
2 ** Stub functions
3 */
4
5 #include        <X11/StringDefs.h>
6 #include        <X11/Intrinsic.h>
7 #include        <X11/IntrinsicP.h>
8 #include        <X11/Core.h>
9 #include        <X11/CoreP.h>
10 #include        <X11/CompositeP.h>
11 #include        <X11/cursorfont.h>
12 #include        <Xm/Text.h>
13 #include        "mmoira.h"
14 #include        <sys/file.h>
15
16 static char rcsid[] = "$Header$";
17
18 void    extra_help_callback();
19 extern EntryForm *MoiraForms[];
20
21 static Widget   logwidget = NULL;
22
23
24 /* No-op action to mask built-in actions */
25
26 void noopACT(w, event, p, n)
27 Widget w;
28 XEvent *event;
29 String *p;
30 Cardinal *n;
31 {
32 }
33
34
35 /* Action to do a moira retrieve on what was clicked at */
36
37 void moiraRetrieveACT(w, event, p, n)
38 Widget w;
39 XEvent *event;
40 String *p;
41 Cardinal *n;
42 {
43     XmTextPosition pos;
44     XButtonEvent *be;
45
46     be = (XButtonEvent *)event;
47
48     pos = XmTextXYToPos(w, be->x, be->y);
49     DoMoiraSelect(pos, w, 0);
50 }
51
52
53 /* Action to modify the moira object that was clicked on */
54
55 void moiraModifyACT(w, event, p, n)
56 Widget w;
57 XEvent *event;
58 String *p;
59 Cardinal *n;
60 {
61     XmTextPosition pos;
62     XButtonEvent *be;
63
64     be = (XButtonEvent *)event;
65
66     pos = XmTextXYToPos(w, be->x, be->y);
67     DoMoiraSelect(pos, w, 1);
68 }
69
70
71 static XtActionsRec myactions[] = {
72     { "moiraRetrieve", moiraRetrieveACT },
73     { "moiraModify", moiraModifyACT },
74     { "noop", noopACT },
75 };
76
77
78 /* These are the additional translations added to the Motif text widget
79  * for the log window.  The two noop translations are here to avoid
80  * nasty interactions with the selection mechanism.  They match the
81  * existing translations that involve shifted mouse buttons.
82  */
83
84 #define newtrans "~Ctrl  Shift ~Meta ~Alt<Btn1Down>: moiraRetrieve()\n\
85         ~Ctrl ~Meta ~Alt<Btn1Up>: noop()\n\
86         ~Ctrl Shift ~Meta ~Alt<Btn1Motion>: noop()\n\
87         ~Ctrl  Shift ~Meta ~Alt<Btn2Down>: moiraModify()"
88
89
90 /* Create the log window, and setup the translation table to taking
91  * mouse clicks in it.
92  */
93
94 Widget
95 SetupLogWidget(parent)
96 Widget  parent;
97 {
98         Arg             wargs[10];
99         int             n;
100         XtTranslations  trans;
101
102         if (logwidget)
103                 return (logwidget);
104         
105         n = 0;
106         XtSetArg(wargs[n], XmNeditMode, XmMULTI_LINE_EDIT);     n++;
107         XtSetArg(wargs[n], XmNeditable, False);                 n++;
108
109         logwidget = XmCreateScrolledText(       parent,
110                                                 "logwidget", 
111                                                 wargs, n);
112         XtManageChild(logwidget);
113
114         XtAppAddActions(XtWidgetToApplicationContext(logwidget),
115                         myactions, XtNumber(myactions));
116         trans = XtParseTranslationTable(newtrans);
117         XtOverrideTranslations(logwidget, trans);
118         return (logwidget);
119 }
120
121
122 /* This actually does all of the work for handling mouse clicks.  It
123  * finds the surrounding text and decides what to do with the click,
124  * the actually starts the moira query or pops up the form.
125  */
126
127 static DoMoiraSelect(pos, w, modify)
128 XmTextPosition pos;
129 Widget w;
130 int modify;    
131 {
132     char *log, *p, *p1, *p2;
133     char name[256], type[256], type2[256];
134
135     log = XmTextGetString(w);
136     for (p = &log[pos]; p > log; p--)
137       if (isspace(*p) || *p == ':') break;
138
139     /* p now points to the beginning of the word on which the mouse was
140      * clicked.  Begin gross hacking to find the name and type of object.
141      */
142     /* get name */
143     p1 = p + 1;
144     p2 = name;
145     while (*p1 && !isspace(*p1)) *p2++ = *p1++;
146     *p2 = 0;
147     /* backup two words before for type2 */
148     while (p >= log && isspace(*p) || *p == ':') p--;
149     while (p >= log && !isspace(*p)) p--;
150     while (p >= log && isspace(*p)) p--;
151     while (p >= log && !isspace(*p)) p--;
152     p++;
153     p2 = type2;
154     /* new get type2 */
155     if (p > log) {
156         while (!isspace(*p)) *p2++ = *p++;
157         *p2++ = *p++;
158         /* skip additional whitespace */
159         while (isspace(*p)) p++;
160     }
161     /* get type & rest of type2 */
162     p1 = type;
163     while (*p && *p != ':' && !isspace(*p)) *p2++ = *p1++ = *p++;
164     *p2 = *p1 = 0;
165     /* Done! */
166 #ifdef DEBUG
167     printf("name \"%s\", type \"%s\" type2 \"%s\"\n", name, type, type2);
168 #endif /* DEBUG */
169     if (!strcasecmp(type, "USER") ||
170         !strcmp(type, "name") ||
171         !strcmp(type2, "Modified by") ||
172         !strcmp(type2, "User Ownership") ||
173         !strcmp(type2, "Login name") ||
174         !strcmp(type, "login")) {
175         DoReference(name, "select_user", MM_MOD_USER, MM_SHOW_USER,
176                     "get_user_account_by_login", modify);
177     } else if (!strcasecmp(type, "LIST") ||
178                !strcmp(type2, "Group Ownership")) {
179         DoReference(name, "select_list", MM_MOD_LIST, MM_SHOW_LIST,
180                     "get_list_info", modify);
181     } else if (!strcasecmp(type, "MACHINE") ||
182                !strcmp(type, "host") ||
183                !strcmp(type, "Server") ||
184                !strcmp(type, "on") ||
185                !strcmp(type, "Box")) {
186         DoReference(name, "select_machine", MM_MOD_MACH, MM_SHOW_MACH,
187                     "get_machine", modify);
188     } else if (!strcasecmp(type, "CLUSTER")) {
189         DoReference(name, "select_cluster", MM_MOD_CLUSTER, MM_SHOW_CLUSTER,
190                     "get_cluster", modify);
191     } else if (!strcasecmp(type, "FILESYSTEM") ||
192                !strcmp(type, "FILESYS") ||
193                !strcmp(type2, "syslib Data")) {
194         DoReference(name, "select_filsys", MM_MOD_FILSYS, MM_SHOW_FILSYS,
195                     "get_filesys_by_label", modify);
196     } else if (!strcmp(type, "Printer") ||
197                !strcmp(type2, "lpr Data")) {
198         DoReference(name, "select_printer", MM_MOD_PCAP, MM_SHOW_PCAP,
199                     "get_printcap_entry", modify);
200     } else {
201         XBell(XtDisplay(w), 100);
202     }
203     XtFree(log);
204 }
205
206
207 /* This is the heart of handling the reference once we have found out
208  * what type of reference it is.
209  */
210
211 static DoReference(name, formname, modop, showop, query, modify)
212 char *name;
213 char *formname;
214 int modop;
215 int showop;
216 char *query;
217 int modify;
218 {
219     EntryForm *form, f;
220     MenuItem m;
221     char *argv[2], **aargv;
222     int status;
223
224     if (modify) {
225         form = GetAndClearForm(formname);
226         StoreField(form, 0, name);
227         form->menu = &m;
228         m.operation = modop;
229         m.query = query;
230         m.argc = 1;
231         MoiraFormApply(0, form);
232     } else {
233         f.menu = &m;
234         if (showop == MM_SHOW_FILSYS) f.extrastuff = (caddr_t) sq_create();
235         argv[0] = name;
236         m.operation = showop;
237         status = MoiraQuery(query, 1, argv, DisplayCallback, &f);
238         if (showop == MM_SHOW_FILSYS) {
239             while (sq_get_data(f.extrastuff, &aargv)) {
240                 ShowFilsys(aargv);
241             }
242             sq_destroy(f.extrastuff);
243         }
244         if (status)
245           com_err(program_name, status, " while looking up data");
246         else
247           AppendToLog("\n");
248     }
249 }
250
251
252 /*
253 ** PopupErrorMessage(text)
254 **
255 ** Given a char* pointing to an error message, possibly with imbedded
256 ** newlines, display the text in a popup window and put two buttons
257 ** at the bottom of the window, labelled "OK" and "Cancel."  Pop down
258 ** when one of the buttons is pressed.
259 **
260 ** Return 0 if "OK" is pressed, 1 for "Cancel."
261 */
262
263 Boolean
264 PopupErrorMessage(text, extrahelp)
265 char    *text;
266 char    *extrahelp;
267 {
268         static Widget           child;
269         Arg             wargs[10];
270         int             n;
271         static XmString        label;
272
273         if (label) {
274                 XtFree(label);
275                 XtDestroyWidget(child);
276         }
277
278
279         label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
280
281         n = 0;
282         XtSetArg(wargs[n], XmNmessageString, label);            n++;
283
284         child = (Widget) XmCreateErrorDialog(logwidget, "errormessage", wargs, n);
285         if (extrahelp) 
286                 XtAddCallback (child, XmNhelpCallback, extra_help_callback, extrahelp);
287         else
288                 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
289         XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_CANCEL_BUTTON));
290         XtManageChild(child);
291 }
292
293 /*
294 ** PopupHelpWindow(text)
295 **
296 ** Given a char* pointing to an help message, possibly with imbedded
297 ** newlines, display the text in a popup window and put a single button
298 ** at the bottom of the window, labelled "OK."  Pop down when the
299 ** the buttons is pressed.
300 */
301
302 void
303 PopupHelpWindow(text)
304 char    *text;
305 {
306         static Widget           child;
307         Arg             wargs[10];
308         int             n;
309
310         static XmString        label;
311         if (label) {
312                 XtFree(label);
313                 XtDestroyWidget(child);
314         }
315
316         label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
317
318         n = 0;
319         XtSetArg(wargs[n], XmNmessageString, label);            n++;
320
321         child = (Widget) XmCreateMessageDialog(logwidget, "helpmessage", wargs, n);
322         XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_CANCEL_BUTTON));
323         XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
324
325         XtManageChild(child);
326 }
327
328 /*
329 ** Given a char* to a single line of text, append this line at the bottom
330 ** of the log window.  Return 0 of the append was sucessful, non-zero
331 ** for an error condition.
332 */
333
334 int
335 AppendToLog(text)
336 char    *text;
337 {
338         XmTextPosition  pos;
339         char            *string, *p;
340
341         string = XmTextGetString(logwidget);
342         pos = strlen(string);
343         XtFree(string);
344
345         XmTextReplace(logwidget, pos, pos, text);
346         XmTextSetCursorPosition(logwidget, pos + strlen(text));
347         if (pos > MAXLOGSIZE) {
348             for (p = &string[pos - MAXLOGSIZE]; *p && *p != '\n'; p++);
349             if (*p)
350               pos = p - string;
351             XmTextReplace(logwidget, 0, pos, "");
352         }
353 }
354
355 void
356 MakeWatchCursor(topW)
357 Widget  topW;
358 {
359     static Cursor mycursor = NULL;
360     EntryForm **fp;
361
362     if (!topW)
363       return;
364
365     if (!mycursor)
366       mycursor = XCreateFontCursor (XtDisplay(topW), XC_watch);
367
368     XDefineCursor(XtDisplay(topW), XtWindow(topW), mycursor);
369     for (fp = MoiraForms; *fp; fp++)
370       if ((*fp)->formpointer && XtIsManaged((*fp)->formpointer))
371         XDefineCursor(XtDisplay(topW), XtWindow((*fp)->formpointer), mycursor);
372 }
373
374 void
375 MakeNormalCursor(topW)
376 Widget  topW;
377 {
378     EntryForm **fp;
379
380     if (!topW)
381       return;
382
383     XUndefineCursor(XtDisplay(topW), XtWindow(topW));
384     for (fp = MoiraForms; *fp; fp++)
385       if ((*fp)->formpointer && XtIsManaged((*fp)->formpointer))
386         XUndefineCursor(XtDisplay(topW), XtWindow((*fp)->formpointer));
387 }
388
389 /*
390 ** Move through the fields of the spec and make certain that the
391 ** form's widgets actually reflect the current values.
392 */
393
394 void
395 UpdateForm(spec)
396 EntryForm       *spec;
397 {
398         UserPrompt      **myinputlines = spec->inputlines;
399         UserPrompt      *current;
400         Arg             wargs[10];
401         int             n, kidcount;
402         Widget          kid;
403
404         if (spec->formpointer == NULL) return;
405
406         for (   current = (*myinputlines);
407                 current; 
408                 myinputlines++, current = (*myinputlines)) {
409
410                 if (current->changed) {
411                     n = 0;
412                     XtSetArg(wargs[n], XmNsensitive,
413                              current->insensitive ? False : True); n++;
414                     XtSetValues(current->mywidget, wargs, n);
415                     current->changed = False;
416                 }
417
418                 switch (current->type) {
419                 case FT_STRING:
420                         if (current->returnvalue.stringvalue) {
421                                 XmTextSetString (current->mywidget, current->returnvalue.stringvalue);
422                         }
423                         break;
424
425                 case FT_BOOLEAN:
426                         n = 0;
427                         XtSetArg(wargs[n], XmNset,
428                                  current->returnvalue.booleanvalue ? True : False);     n++;
429                         XtSetValues (current->mywidget, wargs, n);
430                         break;
431
432                 case FT_KEYWORD:
433                         kidcount = ((CompositeRec *)(current->mywidget))->
434                                         composite.num_children;
435
436                         while(kidcount--) {
437                                 n = 0;
438                                 kid = ((CompositeRec *)(current->mywidget))->
439                                         composite.children[kidcount];
440                                 if (current->returnvalue.stringvalue &&
441                                         (!strcmp (XtName(kid), current->returnvalue.stringvalue))) {
442                                         XtSetArg(wargs[n], XmNset, True);
443                                         n++;
444                                 }
445                                 else {
446                                         XtSetArg(wargs[n], XmNset, False);
447                                         n++;
448                                 }
449                                 XtSetValues (kid, wargs, n);
450                         }
451                         break;
452
453                 case FT_NUMBER:
454                         break;
455                 }
456                 n = 0;
457                 XtSetArg(wargs[n], XtNsensitive, !(current->insensitive));              n++;
458                 XtSetValues (current->mywidget, wargs, n);
459         }
460 }
461
462 void
463 extra_help_callback(w, client_data, call_data)
464 Widget  w;
465 char    *client_data;
466 XmAnyCallbackStruct     *call_data;
467 {
468     help(client_data);
469 }
470
471
472 int write_log_to_file(fn)
473 char *fn;
474 {
475     char *string, buf[256];
476     int fd, i;
477     extern int errno;
478
479     string = XmTextGetString(logwidget);
480     fd = open(fn, O_WRONLY|O_CREAT, 0666);
481     if (fd < 0) {
482         sprintf(buf, "opening output file \"%s\"", fn);
483         com_err(program_name, errno, buf);
484         return(1);
485     }
486     if ((i = write(fd, string, strlen(string))) < 0) {
487         sprintf(buf, "writing output file \"%s\"", fn);
488         com_err(program_name, errno, buf);
489         return(1);
490     }
491     if ((i = close(fd)) < 0) {
492         sprintf(buf, "closing output file \"%s\"", fn);
493         com_err(program_name, errno, buf);
494         return(1);
495     }
496     return(0);
497 }
498
499
500 void yesCallback(w, ret, dummy)
501 Widget w;
502 XtPointer ret;
503 XtPointer dummy;
504 {
505     int *ip = (int *)ret;
506     *ret = 1;
507 }
508
509 void noCallback(w, ret, dummy)
510 Widget w;
511 XtPointer ret;
512 XtPointer dummy;
513 {
514     int *ip = (int *)ret;
515     *ret = -1;
516 }
517
518
519 static int value;
520 static XtCallbackRec yescb[] = { { yesCallback, (XtPointer) &value },
521                                  { NULL, NULL} };
522 static XtCallbackRec nocb[]  = { { noCallback, (XtPointer) &value },
523                                  {NULL, NULL} };
524
525 Boolean AskQuestion(text, helpname)
526 char *text, *helpname;
527 {
528         static Widget           child;
529         Arg             wargs[10];
530         int             n;
531         static XmString        label, yes = NULL, no;
532         XEvent  event;
533
534         if (!yes) {
535             yes = XmStringCreate("Yes", XmSTRING_DEFAULT_CHARSET);
536             no = XmStringCreate("No", XmSTRING_DEFAULT_CHARSET);
537         }
538         if (label) {
539                 XtFree(label);
540                 XtDestroyWidget(child);
541         }
542
543         label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
544
545         n = 0;
546         XtSetArg(wargs[n], XmNmessageString, label);            n++;
547         XtSetArg(wargs[n], XmNokLabelString, yes);              n++;
548         XtSetArg(wargs[n], XmNcancelLabelString, no);           n++;
549         XtSetArg(wargs[n], XmNokCallback, yescb);               n++;
550         XtSetArg(wargs[n], XmNcancelCallback, nocb);            n++;
551
552         child = (Widget) XmCreateQuestionDialog(logwidget, "question", wargs, n);
553         if (helpname) 
554                 XtAddCallback (child, XmNhelpCallback, extra_help_callback, helpname);
555         else
556                 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
557
558         XtManageChild(child);
559         value = 0;
560         while (value == 0) {
561             XtAppNextEvent(_XtDefaultAppContext(), &event);
562             XtDispatchEvent(&event);
563         }
564         if (value > 0)
565           return(1);
566         else
567           return(0);
568 }
569
570
571
572 /******* temporary ********/
573 display_error(msg)
574 char *msg;
575 {
576     PopupErrorMessage(msg, "no_more_help");
577 }
This page took 0.192747 seconds and 5 git commands to generate.