Newsgroups: comp.windows.x Path: utzoo!utgpu!watserv1!watdragon!watsol.waterloo.edu!tbray From: tbray@watsol.waterloo.edu (Tim Bray) Subject: Flaw in Xt init sequence (but with simple fix) Message-ID: <1991Feb28.005057.24723@watdragon.waterloo.edu> Sender: daemon@watdragon.waterloo.edu (Owner of Many System Processes) Organization: University of Waterloo Date: Thu, 28 Feb 1991 00:50:57 GMT Lines: 84 Suppose I have a widget set called Xn. Suppose I need some general-purpose initialization done. This is generally done by having a file called Vendor.c, and in it declaring a global variable called applicationShellWidgetClass which is a complicated Xt structure containing, among other things, pointers to several initialization routines. Then, in XtAppInitialize, the following call gets my Xn code involved in the initialization logic, and it all works hunky-dory... root = XtAppCreateShell(NULL, application_class, applicationShellWidgetClass,dpy, merged_args, num); The the programmer builds her application, and eventually something like the following happens: cc -o app app.o -lXn -lXt -lX11 But wait! Suppose the widget set doesn't need any particular initialization, and hasn't bothered to define the applicationShellWidgetClass global? No problem, because libXt has its own Vendor.c, which has its own applicationShellWidgetClass, which has pointers to some routines that do something or other, and that'll get linked in if one hasn't already been provided. GENERAL CLAIM: this kind of dependence of on the semantics of the unix linker is unclean, unportable, and downright icky. SAMPLE PROBLEM: IBM's AIX on the RS/6000 supports shared libraries. Shared libraries are a Good Thing; in fact with software as bloated as Xlib, Xt and Xn, it verges on criminal negligence not to use them if they're there. However, the shared-lib builder on AIX handily pre-resolves all the unresolved pointers. So if you execute the cc command line above, and Xt has been built shared, the applicationShellWidgetClass is already pointing at the Xt version, and the first time you try to XtCreate an Xn widget, you go up ingloriously in smoke. Am currently looking at various solutions involving different hacks and kludges. And in the interim, running N applications that each carries its own copy of Xt, Xn, and X11 around. PROPOSED SOLUTION: We need two new function calls. Require an entry point in each widget set with a nice standard name; in this case void * XnGetApplicationShell(); (void *) because I think those are Xt data structures that application code doesn't want to know about. If the widget set doesn't need to initialize, the entry point just returns NULL. No args necessary, I think. Then you have another call, a carbon copy of XtAppInitialize() with 1 more argument, as follows: Widget XtAppInitializeW(app_context_return, application_class, options, num_options, argc_in_out, argv_in_out, fallback_resources, args_in, num_args_in, application_shell) XtAppContext * app_context_return; String application_class; XrmOptionDescRec *options; Cardinal num_options, *argc_in_out, num_args_in; String *argv_in_out, * fallback_resources; ArgList args_in; void *application_shell; Then, down its guts, it says: if (application_shell) root = XtAppCreateShell(NULL, application_class, application_shell, dpy, merged_args, num); else root = XtAppCreateShell(NULL, application_class, applicationShellWidgetClass, dpy, merged_args, num); If it isn't obvious, you use the return from XnGetApplicationShell() as the last argument to XtAppInitializeW(). Of course, you'd want to have an analogous form of XtInitialize() and maybe some of those other init calls. Or am I missing some terribly obvious point? Cheers, Tim Bray, University of Waterloo