Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtinfo / dtinfo / src / Agents / HelpAgent.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * $XConsortium: HelpAgent.C /main/16 1996/11/26 12:49:50 cde-hal $
25  *
26  * Copyright (c) 1993 HAL Computer Systems International, Ltd.
27  * All rights reserved.  Unpublished -- rights reserved under
28  * the Copyright Laws of the United States.  USE OF A COPYRIGHT
29  * NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
30  * OR DISCLOSURE.
31  * 
32  * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE
33  * SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.  USE,
34  * DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE
35  * PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS
36  * INTERNATIONAL, LTD.
37  * 
38  *                         RESTRICTED RIGHTS LEGEND
39  * Use, duplication, or disclosure by the Government is subject
40  * to the restrictions as set forth in subparagraph (c)(l)(ii)
41  * of the Rights in Technical Data and Computer Software clause
42  * at DFARS 252.227-7013.
43  *
44  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.
45  *                  1315 Dell Avenue
46  *                  Campbell, CA  95008
47  * 
48  */
49
50 #define C_TOC_Element
51 #define L_Basic
52
53 #define C_WindowSystem
54 #define L_Other
55
56 #define C_HelpAgent
57 #define L_Agents
58
59 #define C_MessageMgr
60 #define C_EnvMgr
61 #define C_LibraryMgr
62 #define L_Managers
63
64 #include "Prelude.h"
65
66 #include "Other/XmStringLocalized.hh"
67 #include "Managers/CatMgr.hh"
68
69 #include "Registration.hh"
70
71 // HGL Help include file: 
72 // #include "Help/Help.h"
73
74 #include "WWL/WXmPrimitive.h"
75 #include "WWL/WXmManager.h"
76 #include "WWL/WXmPushButton.h"
77 #include "WWL/WXmPushButtonGadget.h"
78 #include <X11/cursorfont.h>
79
80 //#include <Dt/HelpQuickD.h>
81 #include <Dt/Help.h>
82 #include <Dt/HelpDialog.h>
83 #include <stdio.h>
84 #include <iostream.h>
85
86 #define CLASS HelpAgent
87 #include "create_macros.hh"
88
89 #include "external-api/olias.h"
90
91 /******** The onitem cursor (32x32, xbm format) ********/
92 #define onitem32_width 32
93 #define onitem32_height 32
94 #define onitem32_x_hot 0
95 #define onitem32_y_hot 0
96 static unsigned char onitem32_bits[] = {
97    0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x1f, 0xfc, 0xf9, 0xff, 0xe7, 0xf3,
98    0xf1, 0xff, 0xfb, 0xef, 0xe1, 0xff, 0xfd, 0xdf, 0xc1, 0xff, 0xfd, 0xdf,
99    0x83, 0xff, 0xfe, 0xbf, 0x03, 0xff, 0x7e, 0x7e, 0x03, 0xfe, 0xbe, 0x7d,
100    0x03, 0xfc, 0xbe, 0x7d, 0x03, 0xf0, 0xc1, 0x7d, 0x03, 0xe0, 0xff, 0x7e,
101    0x07, 0xc0, 0x7f, 0xbf, 0x07, 0x80, 0xbf, 0xbf, 0x07, 0x00, 0xde, 0xdf,
102    0x07, 0x00, 0xdc, 0xef, 0x07, 0x00, 0xdf, 0xf7, 0x07, 0x80, 0xdf, 0xfb,
103    0x0f, 0xc0, 0xdf, 0xfb, 0x0f, 0xc0, 0xdf, 0xfb, 0x0f, 0x81, 0xdf, 0xfb,
104    0xcf, 0x83, 0x3f, 0xfc, 0xef, 0x07, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff,
105    0xff, 0x0f, 0x3e, 0xfc, 0xff, 0x0f, 0xde, 0xfb, 0xff, 0x1f, 0xdc, 0xfb,
106    0xff, 0x1f, 0xdc, 0xfb, 0xff, 0x3f, 0xd8, 0xfb, 0xff, 0x3f, 0x3c, 0xfc,
107    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
108
109 #define onitem32_m_width 32
110 #define onitem32_m_height 32
111 #define onitem32_m_x_hot 0
112 #define onitem32_m_y_hot 0
113 static unsigned char onitem32_m_bits[] = {
114    0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0xe0, 0x03, 0x0f, 0x00, 0xf8, 0x0f,
115    0x1f, 0x00, 0xfc, 0x1f, 0x3f, 0x00, 0xfe, 0x3f, 0x7f, 0x00, 0xfe, 0x3f,
116    0xfe, 0x00, 0xff, 0x7f, 0xfe, 0x01, 0xff, 0xff, 0xfe, 0x03, 0x7f, 0xfe,
117    0xfe, 0x0f, 0x7f, 0xfe, 0xfe, 0x1f, 0x3e, 0xfe, 0xfe, 0x3f, 0x00, 0xff,
118    0xfc, 0x7f, 0x80, 0x7f, 0xfc, 0xff, 0xc1, 0x7f, 0xfc, 0xff, 0xe3, 0x3f,
119    0xfc, 0xff, 0xe7, 0x1f, 0xfc, 0xff, 0xe3, 0x0f, 0xfc, 0xff, 0xe0, 0x07,
120    0xf8, 0x7f, 0xe0, 0x07, 0xf8, 0x7f, 0xe0, 0x07, 0xf8, 0xff, 0xe0, 0x07,
121    0xf8, 0xfe, 0xc0, 0x03, 0x38, 0xfc, 0x01, 0x00, 0x18, 0xfc, 0x01, 0x00,
122    0x00, 0xf8, 0xc3, 0x03, 0x00, 0xf8, 0xe3, 0x07, 0x00, 0xf0, 0xe7, 0x07,
123    0x00, 0xf0, 0xe7, 0x07, 0x00, 0xe0, 0xef, 0x07, 0x00, 0xe0, 0xc7, 0x03,
124    0x00, 0xc0, 0x03, 0x00, 0x00, 0x80, 0x00, 0x00};
125
126 #define NULL_LOCATORID "__HaL__DefaultLocatorId__"
127
128 HelpAgent *HelpAgent::g_help_agent;
129
130 // /////////////////////////////////////////////////////////////////
131 // class constructor
132 // /////////////////////////////////////////////////////////////////
133
134 HelpAgent::HelpAgent()
135 : f_helper (NULL)
136 {
137   Widget app_shell = window_system().toplevel();
138   f_cursor = create_help_cursor(app_shell);
139 }
140
141
142 // /////////////////////////////////////////////////////////////////
143 // class destructor
144 // /////////////////////////////////////////////////////////////////
145
146 HelpAgent::~HelpAgent()
147 {
148   g_help_agent = NULL;
149 }
150
151
152 // /////////////////////////////////////////////////////////////////
153 // create_ui
154 // /////////////////////////////////////////////////////////////////
155
156 void
157 HelpAgent::create_ui()
158 {
159   Arg args[2];
160   int n;
161   Widget app_shell = window_system().toplevel();
162   f_appXrmDb = XrmGetDatabase (XtDisplay (app_shell));
163
164   n = 0;
165   XtSetArg(args[n], XmNtitle, "Dtinfo Help"); n++;
166   f_helper = DtCreateHelpDialog(app_shell,
167                                 "helpdialog",
168                                 args, n);
169 }
170
171
172 // /////////////////////////////////////////////////////////////////
173 // display_help
174 // /////////////////////////////////////////////////////////////////
175 void
176 HelpAgent::display_help (Widget w)
177 {
178   char* locator_id=get_locator_id(w);
179   if(locator_id == NULL)
180   {
181     message_mgr().error_dialog ((char*)UAS_String(
182                   CATGETS(Set_Messages, 3, "No help available")));
183     return;
184   }
185
186   Wait_Cursor bob;
187
188   if (f_helper == NULL)
189     create_ui();
190   XtVaSetValues(f_helper,
191                 DtNhelpType, DtHELP_TYPE_TOPIC,
192                 DtNhelpVolume, "Infomgr",
193                 DtNlocationId, locator_id,
194                 XmNdialogStyle, XmDIALOG_MODELESS,
195                 NULL);
196
197   XtManageChild(f_helper);
198   Popup();
199 }
200
201 void
202 HelpAgent::display_help (const String locatoridResourceString)
203 {
204   Wait_Cursor bob;
205
206   if (f_helper == NULL)
207     create_ui();
208
209   if (f_appXrmDb)
210   {
211     char* type;
212     XrmValue value;
213
214     if(env().debug())
215       cerr << "Resource string: " << locatoridResourceString << endl;
216     if(XrmGetResource(f_appXrmDb, locatoridResourceString,
217                         locatoridResourceString, &type, &value ))
218     {
219       if(env().debug())
220         cerr << "Value: " << value.addr << endl;
221       XtVaSetValues(f_helper,
222                     DtNhelpType, DtHELP_TYPE_TOPIC,
223                     DtNhelpVolume, "Infomgr",
224                     DtNlocationId, value.addr,
225                     XmNdialogStyle, XmDIALOG_MODELESS,
226                     NULL);
227       XtManageChild(f_helper);
228       Popup();
229     }
230     else
231     {
232       message_mgr().error_dialog (UAS_String(
233                     CATGETS(Set_Messages, 3, "No help available")));
234     }
235   }
236 }
237
238 void
239 HelpAgent::Popup()
240 {
241   Widget app_shell = window_system().toplevel();
242   Widget parent = XtParent(f_helper);
243   //XRaiseWindow(XtDisplay(parent), XtWindow(parent));
244   UAS_List<UAS_String> env_infolibs(env().infolibs());
245   library_mgr().init(env_infolibs);
246
247   XMapRaised(XtDisplay(app_shell), XtWindow(app_shell));
248   XMapRaised(XtDisplay(parent), XtWindow(parent));
249 }
250
251
252 // /////////////////////////////////////////////////////////////////
253 // Help Callback Functions
254 // /////////////////////////////////////////////////////////////////
255 // This provides F1 help support
256
257 static void
258 helpCB(Widget w, XtPointer, XtPointer)
259 {
260   help_agent().help_cb(w);
261 }
262
263 void
264 HelpAgent::add_help_cb (Widget w)
265 {
266   XtAddCallback(w, XmNhelpCallback, helpCB, NULL);
267 }
268
269 void
270 HelpAgent::help_cb (Widget w)
271 {
272   display_help (w);
273 }
274
275
276 // /////////////////////////////////////////////////////////////////
277 // Context Help functions
278 // /////////////////////////////////////////////////////////////////
279 // This provides context-sensitive help
280
281 static void
282 contextHelpCB(Widget w, XtPointer, XtPointer)
283 {
284   help_agent().context_help(w);
285 }
286
287 void
288 HelpAgent::add_context_help (Widget w)
289 {
290   XtAddCallback(w, XmNactivateCallback, contextHelpCB, NULL);
291 }
292
293 void
294 HelpAgent::context_help(Widget widget)
295 {
296   while(!XtIsSubclass(widget, topLevelShellWidgetClass))
297     widget = XtParent(widget);
298
299   if (widget != NULL)
300   {
301     XEvent event;
302     Widget sel_widget = XmTrackingEvent(widget, f_cursor, False, &event);
303     if (sel_widget != NULL)
304       display_help(sel_widget);
305   }
306 }
307
308 // /////////////////////////////////////////////////////////////////
309 // Activate Help functions
310 // /////////////////////////////////////////////////////////////////
311 // This provides help for help buttons and help menu items.
312 // Widgets that register an activate callback also need a help
313 // callback.
314
315 static void
316 activateHelpCB(Widget w, XtPointer client_data, XtPointer)
317 {
318   help_agent().activate_help(w, (String)client_data);
319 }
320
321 void
322 HelpAgent::add_activate_help (Widget w, const String locator_id)
323 {
324   XtAddCallback(w, XmNactivateCallback, activateHelpCB, (XtPointer)locator_id);
325   add_help_cb(w);
326 }
327
328 void
329 HelpAgent::add_activate_help (WXmPushButton& w, const String locator_id)
330 {
331   XtAddCallback((Widget)w, XmNactivateCallback, activateHelpCB, (XtPointer)locator_id);
332 }
333
334 void
335 HelpAgent::add_activate_help (WXmPushButtonGadget& w, const String locator_id)
336 {
337   XtAddCallback((Widget)w, XmNactivateCallback, activateHelpCB, (XtPointer)locator_id);
338 }
339
340 void
341 HelpAgent::activate_help (Widget w, String locator_id)
342 {
343   if (locator_id != NULL)
344     display_help(locator_id);
345   else
346     display_help (w);
347 }
348
349 #if 0
350 void HelpAgent::add_context_help (WXmPrimitive &w)
351 {
352   w.SetHelpCallback (this, (WWL_FUN) &HelpAgent::context_help_cb);
353 }
354
355 void HelpAgent::add_context_help (WXmManager &w)
356 {
357   w.SetHelpCallback (this, (WWL_FUN) &HelpAgent::context_help_cb);
358 }
359
360 void
361 HelpAgent::add_context_help(WXmPushButton &pb, int context)
362 {
363   pb.SetHelpCallback (this, (WWL_FUN) &HelpAgent::context_help_cb);
364   //pb.SetActivateCallback (this, (WWL_FUN) &HelpAgent::context_help_cb,
365 //                        (XtPointer) context);
366 }
367
368 void
369 HelpAgent::add_context_help(WXmPushButtonGadget &pb, int context)
370 {
371   pb.SetActivateCallback (this, (WWL_FUN) &HelpAgent::context_help_cb,
372                           (XtPointer) context);
373 }
374
375 void
376 HelpAgent::add_activate_help (WXmPushButton &pb, const String card_id)
377 {
378   pb.SetActivateCallback (this, (WWL_FUN) &HelpAgent::help_cb,
379                           (void *) card_id);
380 }
381
382 void
383 HelpAgent::add_activate_help (WXmPushButtonGadget &pbg, const String card_id)
384 {
385   pbg.SetActivateCallback (this, (WWL_FUN) &HelpAgent::help_cb,
386                            (void *) card_id);
387 }
388
389 void
390 HelpAgent::add_activate_help (Widget w, const String card_id)
391 {
392   pbg.SetActivateCallback (this, (WWL_FUN) &HelpAgent::help_cb,
393                            (void *) card_id);
394 }
395
396 #endif
397 char*
398 HelpAgent::get_locator_id(const Widget w)
399 {
400    XtResource   res;
401    //res.resource_name   = (resourceName ? (String)resourceName : "helpcard");
402    res.resource_name   = "helpcard";
403    res.resource_class  = XtCString;
404    res.resource_type   = XtRString;
405    res.resource_size   = sizeof(String);
406    res.resource_offset = 0;
407    res.default_type    = XtRString;
408    res.default_addr    = NULL_LOCATORID;
409
410    char         *wname = XtName(w);     // Just for gdb
411    String       string;
412    XtGetApplicationResources(w, &string, &res, 1, NULL, 0);
413
414    if(env().debug())
415    {
416       UAS_String wname = XtName(w);
417       UAS_String dot(".");
418       Widget parent = XtParent(w);
419       while(parent != NULL)
420       {
421          UAS_String Parent(XtName(parent));
422          wname = Parent + dot + wname;   
423          parent = XtParent(parent);
424       }
425       cerr << "Widget: " << (char*)wname << endl;
426    }
427
428    if ( strcmp(string, NULL_LOCATORID)==0 )
429    {  
430       // Locator id not found, look for it in a parent
431       //cerr << "Locator id not found, searching parent" << endl;
432       Widget parent = XtParent(w);
433       while(parent != NULL)
434       {
435         XtGetApplicationResources(parent, &string, &res, 1, NULL, 0);
436         if ( strcmp(string, NULL_LOCATORID)==0 )     // Not found
437           parent = XtParent(parent);
438         else
439         {
440           if(env().debug())
441             cerr << "Parent Locator is: " << string << endl;
442           return string;
443         }
444       }
445       return NULL;
446     }
447
448    if(env().debug())
449      cerr << "Locator is: " << string << endl;
450    return string;
451 }
452
453 Cursor
454 HelpAgent::create_help_cursor(Widget parent)
455 {
456   Display     *display = XtDisplay(parent);
457   Screen      *retScr = XtScreen(parent);
458   int          screen = XScreenNumberOfScreen(retScr);
459   char        *bits;
460   char        *maskBits;
461   unsigned int width;
462   unsigned int height;
463   unsigned int xHotspot;
464   unsigned int yHotspot;
465   Pixmap       pixmap;
466   Pixmap       maskPixmap;
467   XColor       xcolors[2];
468   Cursor      cursor;
469
470   width    = onitem32_width;
471   height   = onitem32_height;
472   bits     = (char *) onitem32_bits;
473   maskBits = (char *) onitem32_m_bits;
474   xHotspot = onitem32_x_hot;
475   yHotspot = onitem32_y_hot;
476
477   pixmap = XCreateBitmapFromData (display,
478              RootWindowOfScreen(XtScreen(parent)), bits,
479              width, height);
480
481
482   maskPixmap = XCreateBitmapFromData (display,
483                  RootWindowOfScreen(XtScreen(parent)), maskBits,
484                  width, height);
485
486   xcolors[0].pixel = BlackPixelOfScreen(ScreenOfDisplay(display, screen));
487   xcolors[1].pixel = WhitePixelOfScreen(ScreenOfDisplay(display, screen));
488
489   XQueryColors (display,
490     DefaultColormapOfScreen(ScreenOfDisplay(display, screen)), xcolors, 2);
491
492   cursor = XCreatePixmapCursor (display, pixmap, maskPixmap,
493                        &(xcolors[0]), &(xcolors[1]),
494                        xHotspot, yHotspot);
495   XFreePixmap (display, pixmap);
496   XFreePixmap (display, maskPixmap);
497
498   return cursor;
499
500 }