------------------------------------------------------------------------------- Application Defaults To allow for easy customization, programmers should write app-defaults files that do not use the name or class of the allpication, except in certain critical resources that the user should not be able to trivially or accidentally overirde. The standard R5 clients have app-defaults files written in this way. extract from p458 of O'rielly's R5 Xlib Prog Manual ------------------------------------------------------------------------------- X Toolkit and Athena Widget Font Defaults The following resources is used if and when (or not set) a font is not provided by resource for a widget to use. In order xtDefaultFont resource XtDefaultFont resource "-*-*-*-R-*-*-*-120-*-*-*-*-ISO8859-1" ------------------------------------------------------------------------------- Default icon To set a Default icon for an Xt program but still allow the user to override this icon setting. /* application icon */ #include "icon.xbm" main() { toplevel = XtVaAppInitialize(...); ... /* If no icon is set by the user -- set a default one */ { Pixmap icon; XtVaGetValues(toplevel, XtNiconPixmap, &icon, NULL); if ( icon == None ) { icon = XCreateBitmapFromData( XtDisplay(toplevel), RootWindowOfScreen(XtScreen(toplevel)), (char *)icon_bits, icon_width, icon_height); XtVaSetValues(toplevel, XtNiconPixmap, icon, NULL); } } ... } ------------------------------------------------------------------------------- Allow Event to happen for a short period This is to allow -- + dialog widget to popup announcing that the application is processing + to let redraw events occur + get a changes label to redraw before continuing. To do this I suggest (not the most ideal) ctx = XtWidgetToApplicationContext(dialog); for (i=0;i<30;i++) XtAppProcessEvent(ctx,XtIMAll); NOTE: processing events until XtAppPending says nothing is left DOES NOT WORK. --- Dan Peduzzi peduzzi@aer.com ------------------------------------------------------------------------------- XtAppMainLoop What is it void XtAppMainLoop(app) XtAppContext app; { XEvent event; for (;;) { XtAppNextEvent(app, &event); XtDispatchEvent(&event); } } Actually the two internal functions are in another Function XtAppProcessEvent(app, XtIMAll); ------------------------------------------------------------------------------- Enable `Delete Window' Function /* Set the window to call quit() action if `deleted' */ { Atom wm_delete_window; XtOverrideTranslations(toplevel, XtParseTranslationTable("WM_PROTOCOLS:quit()") ); wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); (void) XSetWMProtocols(display, XtWindow(toplevel), &wm_delete_window, 1); } ------------------------------------------------------------------------------- Xt Memory routines XtMalloc(), XtCalloc(), XtNew(), XtNewString() and XtRealloc() which all use the standard C language functions malloc(), calloc() and realloc() but execute XtErrorMsg() if a NULL value is returned. Xt error handlers are not supposed to return so this effectively exits. In addition, if XtRealloc() is called with a NULL pointer, it uses XtMalloc() to get the initial space. This allows code like: if (!ptr) ptr = (type *) malloc (sizeof (type)); else ptr = (type *) realloc (ptr, sizeof (type) * (count + 1)); ++count; to be written as: ptr = XtRealloc (ptr, sizeof (ptr) * ++count); Also, XtFree() accepts a NULL pointer as an argument. Generally, I've found the Xt functions conveniant to use. However, anytime I'm allocating anything potentially large I use the standard functions so I can fully recover from not enough memory errors. XtNew() and XtNewString() are conveniant macros for allocating a structure or copying a string: struct abc *xyzzy; char *ptr; char *str = "abcdef"; xyzzy = XtNew (struct abc); /* takes care of type casting */ ptr = XtNewString (str); Just to emphasize this, the Xt memory allocators are required to be compatible and so interchangeable with the standard C library memory allocators. ------------------------------------------------------------------------------- Warp cursour to widget /* Warps the cursor to the bottom right corner of the passed widget, where the cursor probably won't occlude what the user is looking at. Author: Sheeran Frank -- sheeran@ndg.co.jp */ void WarpToWidgetBR( Widget target ) { Dimension nx, ny; Arg arg[2]; XtSetArg( arg[0], XtNwidth, &nx ); XtSetArg( arg[1], XtNheight, &ny ); XtGetValues( target, arg, 2 ); XWarpPointer( XtDisplay( target ), NULL, XtWindow( target ), 0, 0, 0, 0, (Position) (nx-2), (Position) (ny-2) ); ... } NOTE: It is not good programming practice to warp the cursour unexpectedly as the user may be doing something else. If you do however provide cursour warping. PROVIDE A RESOURCE TO TURN THE WARPING OFF! ------------------------------------------------------------------------------- AsciiText widget width in characters (regardlees of font) This is how I do it in aXe. Seems to work OK. static void RowsColumnsToWidthHeight(rows, cols, widget, width, height) Dimension rows, cols, *width, *height; Widget widget; { AsciiTextWidget atw = (AsciiTextWidget) widget; XFontStruct *font; Position lm, rm, tm, bm; XtVaGetValues(widget, XtNfont, &font, XtNleftMargin, &lm, XtNrightMargin, &rm, XtNtopMargin, &tm, XtNbottomMargin, &bm, NULL); *width = cols * font->max_bounds.width + lm + rm; *height = rows * (font->max_bounds.ascent + font->max_bounds.descent) + tm + bm); } RowsColumnsToWidthHeight(rows, cols, ascii, &width, &height); XtVaSetValues(ascii, XtNwidth, width, XtNheight, height, NULL); J.K.Wight@newcastle.ac.uk ADDED NOTE: Proportional fonts will not work with this method. The result will be a large width with all the text on the left. Example -- Set an xterm's font to a proportional font like Helvetica. ------------------------------------------------------------------------------- Text/Dialog widget -- call function on return Method 1: add the translation *Dialog.value.translations: #override Return: dialog_finish() OR hardcoding char trans[] = "Return: Ok() \n\ CtrlM: Ok() "; ... dialog = XtVaCreateManagedWidget( "dialog", dialogWidgetClass, .... ); XtOverrideTranslations(XtNameToWidget(dialog, "value"), XtParseTranslationTable(trans)); NOTE: You have to add the \n\ between traslations. Read Xaw manual in "mit/hardcopy/Xaw" ------------------------------------------------------------------------------- Label and Pixmaps The problem is that the label widget checks to see if it has a bitmap or a pixmap in this resource by looking at that resources depth. if depth > 1 draw a pixmap which already has the colors filled in else draw bitmap filling in the Foreground and Background colors. This is fine for color displays or when using bitmaps. But as soon as you try to use a color pixmap (with the colors already assigned) on a black and white monocrome display, you have a 50-50 chance of that the image being inverted! IE: Using a Pixmap directly in a Label Widget is not 100% correct! A number of solutions exists. 1/ A simple one is to check for this condition and invert the pixmap before giving it to the label widget. if ( display depth == 1 && Black Pixel == 0 ) pre-invert your pixmap so label gets it right 2/ Draw the pixmap youself -- you know it is a pixmap 3/ Avoid using then in label or command widgets. 4/ Write your own version of label. ------------------------------------------------------------------------------- Other info and problems. * Text widgets with a multi line string in a expandable form only seem to appear with the first two lines visable initially. * You can't change the width of a widget boarder after its creation. However you can change its color. * Their seems to be no easy way to assign a pointer in a widget to point to extra information the widget is representing. `callback data' can be used but this mens changing this when the callback itself doesn't change. This method is not possible for action (translation) routines that the user may require. The best solution would be a general `pointer' type resource on all widgets. * Any string assigned to a widget via Xt(Va)SetValues is copied before actually being assigned. This means that only strings can actually be assigned as a label. A pointer coverted to Text could be set as a label. -------------------------------------------------------------------------------