[llnl.x] more on XmString problem

chapman@lll-crg.llnl.gov (Carol Chapman) (04/19/91)

I recently reported (complained) to the net about problems accessing
the contents of pushbutton labels using Motif.  Some of the labels
were created using UIL and some were set within my C program by a call
to XmStringCreateLtoR.  Masayoshi Habu replied and told me to try
using XmStringCreate rather than XmStringCreateLtoR.  That solved my
problem with labels that were set within my C program, but I am still
unable to access labels set within UIL code.  I'm using XmStringGetLtR
to try to look at the contents.  It always returns a null string.  I
therefore suspect that XmStringCreateLtoR is buggy, and UIL is buggy
too.  My work is all on DEC equipment, so I've reported the bug to
them.  Enclosed here are some small test cases I ran, if anyone is
interested. 

I'm using
C, VMS 5.3, and Motif 1.1 on a VAXstation 3100.  The enclosed files
are:  test.c, test.com, test.opt, test1.c, test1.uil, test1.com and
test1.opt.  Test.c creates a label and successfully accesses it.
Test1.c uses UIL to create a pushbutton containing a label.  I am not
able to access its label.

After running test and test1, I thought the problem must be related
to UIL, but I received a phone call from a guy named Sanjay
Agrawal who works for Oracle in Berkeley.  He claims to have the
same problem in that his small test case works, but on his larger
real program, a null label is always returned.  He is not using UIL.

carol    (chapman@llnl.gov)

--------------------------------------------------------------------

/*---------------------------------------------------------------------------*/
/*                             TEST.C                                        */
/*---------------------------------------------------------------------------*/

#define VMS

#include <stdio.h>
#ifdef VMS
#include <stdlib.h>
#endif
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Mrm/MrmPublic.h>

#define  MAX_ARGS        12
#define  MAX_LABEL_SIZE  128

Boolean       debug = True;
char*         get_label(Widget);

/*---------------------------------------------------------------------------*/


	main(int argc, char *argv[])
	{
	  Widget toplevel, msg;
	  Arg al[10];
	  int ac;
          char* label = NULL;

	  toplevel=XtInitialize(argv[0],"",NULL,0,&argc,argv);
	  ac=0;
	  XtSetArg(al[ac],XmNlabelString,
	   	 XmStringCreate("hello",XmSTRING_DEFAULT_CHARSET)); ac++;
	  msg=XtCreateManagedWidget("msg",xmLabelWidgetClass,toplevel,al,ac);
	  XtRealizeWidget(toplevel);
          label = (char*) XtCalloc(MAX_LABEL_SIZE, sizeof(char));
          label = get_label(msg);
          printf("label = %s\n", label);
	  XtMainLoop();
	}

/*---------------------------------------------------------------------------*/

char* get_label(Widget         id)
  
  /* Returns a label from within a Motif label string.                       */

{
  int              num               = 0;     /* number of arguments         */
  Arg              wargs[MAX_ARGS];           /* argument list               */
  char*            label             = NULL;  /* label to be returned        */
  XmString         label_str;                 /* Motif label string          */

  if (debug)
     printf("in get_label\n");
  /* Pull the label out of the widget */
  XtSetArg(wargs[num], XmNlabelString, &label_str); num++;
  XtGetValues(id, wargs, num);

  /* Pull the character string out of the XmString */
  XmStringGetLtoR(label_str, XmSTRING_DEFAULT_CHARSET, &label);

  /* Free string and make sure we free the pixmap (if there was one) */
  XmStringFree(label_str);
  
  if (debug)
     printf("leaving get_label\n");
  return(label);
}  /* of get_label */


/*--------------------------------------------------------------------------*/



!---------------------------------------------------------------------------!
!                              TEST.OPT                                     !
!---------------------------------------------------------------------------!

   sys$share:decw$motif$dxmshr/share,-
   sys$share:decw$motif$xmshr/share,-
   sys$share:decw$motif$xtshr/share,-
   sys$share:decw$xlibshr/share,-
   sys$share:vaxcrtl/share



!-----------------------------------------------------------------------------!
!                              TEST.COM                                       !
!-----------------------------------------------------------------------------!

$ link/debug test, test.opt/options
$ exit


/*--------------------------------------------------------------------------*/
/*                             TEST1.C                                      */
/*--------------------------------------------------------------------------*/

#define VMS

#include <stdio.h>
#ifdef VMS
#include <stdlib.h>
#endif
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Mrm/MrmPublic.h>

Display                *disp;                       /* the display           */
MrmHierarchy           s_MrmHierarchy;              /* our widget hierarchy  */
Widget                 toplevel = NULL;             /* top widget            */
XtAppContext           app_context;                 /* application context   */
Widget                 widgetlist[2];               /* array of most widgets */

#define MAX_ARGS       12
#define MAX_LABEL_SIZE 128


/*---------------------------------------------------------------------------*/

void create_cb(Widget              w,
	       int*                data_from_app,
               caddr_t             data_from_widget)

  /* A callback routine called when most widgets are first created.  This
     stores the id of the widget in an indexed array called widgetlist.      */

{
  int index = (int) *data_from_app;
  
  widgetlist[index] = w;
}  /* of create_cb */


/*---------------------------------------------------------------------------*/

char* get_label(Widget         id)
  
  /* Returns a label from within a Motif label string.                       */

{
  int              num               = 0;     /* number of arguments         */
  Arg              wargs[MAX_ARGS];           /* argument list               */
  char*            label             = NULL;  /* label to be returned        */
  XmString         label_str;                 /* Motif label string          */

  printf("in get_label\n");
  /* Pull the label out of the widget */
  XtSetArg(wargs[num], XmNlabelString, &label_str); num++;
  XtGetValues(id, wargs, num);

  /* Pull the character string out of the XmString */
  XmStringGetLtoR(label_str, XmSTRING_DEFAULT_CHARSET, &label);

  /* Free string and make sure we free the pixmap (if there was one) */
  XmStringFree(label_str);
  
  printf("leaving get_label\n");
  return(label);
}  /* of get_label */


/*--------------------------------------------------------------------------*/

void set_label(Widget         id, 
               char*          label)

  /* Sets a Motif label.                                                    */

{
  int          num              = 0;  /* number of arguments                */
  Arg          wargs[MAX_ARGS];       /* argument list                      */
  XmString     label_str;             /* Motif label string                 */

  printf("in set_label\n");
  /* specify the new label */
  label_str = XmStringCreateLtoR(label, XmSTRING_DEFAULT_CHARSET);

  XtSetArg(wargs[num], XmNlabelType, XmSTRING); num++;
  XtSetArg(wargs[num], XmNlabelString, label_str); num++;
  XtSetValues(id, wargs, num);

  /* Free string and make sure we free the pixmap (if there was one) */
  XmStringFree(label_str);
  printf("leaving set_label\n");
}  /* of set_label */


/*---------------------------------------------------------------------------*/

extern void the_test_cb(Widget      w,
                        caddr_t     data_from_app,
                        caddr_t     data_from_widget)

{
  char* label = NULL;

  printf("in the_test_cb\n");
  label = (char*) XtCalloc(MAX_LABEL_SIZE, sizeof(char));
  label = get_label(widgetlist[1]);
  if (label != NULL)
     printf("originally, label = %s\n", label);
  else
     printf("originally, label is perceived to be NULL\n");
  set_label(widgetlist[1], "new label");
  label = (char*) XtCalloc(MAX_LABEL_SIZE, sizeof(char));
  label = get_label(widgetlist[1]);
  if (label != NULL)
     printf("after set_label, label = %s\n", label);
  else
     printf("after set_label, label is NULL\n");
  printf("leaving the_test_cb\n");
}  /* of the_test_cb */


/*---------------------------------------------------------------------------*/

int main (argc,argv)
  unsigned int  argc;
  char          **argv;
  
{
  MrmRegisterArg  register_list[] = {
      {"create_cb", (caddr_t) create_cb},
      {"the_test_cb", (caddr_t) the_test_cb}
  };  /* of register_list */
  char*                   uid_files_array[] =
                          {  "test1.uid"
                          };  /* of uid_files_array */
  int                     i = 0;
  int register_list_num = (sizeof register_list / sizeof register_list[0]);
  MrmCode                 cwin_type;
  MrmType                 main_window_class;
  Widget                  main_window_id = NULL;
  Arg                     wargs[MAX_ARGS];

  MrmInitialize();  /* initialize Motif Resource Manager */

  /* initialize the X Toolkit */
  toplevel = XtAppInitialize(&app_context,
 		             "Test1", 
                             NULL, 
                             0,
                             &argc, 
                             argv,
                             NULL,
                             NULL,
                             0);

  /* open all UID files in the hierarchy and get hierarchy id */
  if (MrmOpenHierarchy((MrmCount) XtNumber(uid_files_array), 
                       uid_files_array, 
                       NULL, 
                       &s_MrmHierarchy) != MrmSUCCESS)
  {  /* something is wrong */
     printf("test1.c/main:  Error opening UID file(s)\n");
     exit(1);
  }  /* of if */
    
  /* register UIL names that will be used by this program */
  if (MrmRegisterNames (register_list, register_list_num) != MrmSUCCESS)
  {  /* something is wrong */
     printf("test1.c/main:  Error registering names\n");
     exit(1);
  }  /* of if */

  /* fetch the main window widget */
  if (MrmFetchWidget(s_MrmHierarchy,
                     "main_w",
                     toplevel,
                     &main_window_id,
                     &main_window_class) != MrmSUCCESS)
  {  /* unable to fetch widget */
     printf("test1.c/main:  Error fetching main window widget.\n");
     exit(1);  /* abort program */
  }  /* of if */
  widgetlist[0] = main_window_id;

  /* manage the main window widget and its children */
  XtManageChild(main_window_id);


  /* let the main window widget know that the label widget is the
     work window portion of the main window */
  XtSetArg(wargs[0], XmNworkWindow, widgetlist[1]);
  XtSetValues(widgetlist[0], wargs, 1);

  /* display toplevel widget and its managed children */
  XtRealizeWidget(toplevel);

  /* get display value for later use */
  disp = XtDisplay(toplevel);

  XSynchronize(disp, TRUE);  /* enable synchronization for debugging */

  XtAppMainLoop(app_context);  /* infinite loop for event handling */

}  /* of main */



!------------------------------------------------------------------------------!
!                              TEST1.UIL                                       !
!------------------------------------------------------------------------------!

module test1
    names = case_sensitive

object
    main_w: XmMainWindow 
        {
        arguments
            {
            XmNx = 75;
            XmNy = 113;
            XmNborderWidth = 1;
            };
        controls
            {
            XmPushButton pbutton;
            };
        };
    pbutton: XmPushButton 
        {
        arguments
            {
            XmNx = 16;
            XmNy = 4;
            XmNlabelString = 
            compound_string("hello world");
            };
        callbacks
            {
            MrmNcreateCallback = procedures
                {
                create_cb(1);
                };
            XmNactivateCallback = procedures
                {
                the_test_cb(0);
                };
            };
        };

procedure
    create_cb;
    the_test_cb;

end module;



!-----------------------------------------------------------------------!
!                          TEST1.OPT                                    !
!-----------------------------------------------------------------------!

   sys$share:decw$motif$dxmshr/share,-
   sys$share:decw$motif$xmshr/share,-
   sys$share:decw$motif$xtshr/share,-
   sys$share:decw$xlibshr/share,-
   sys$share:vaxcrtl/share



!-------------------------------------------------------------------------!
!                               TEST1.COM                                 !
!-------------------------------------------------------------------------!

$ link/debug test1, test1.opt/options
$ exit
Carol Chapman                                        Tel. (415) 423-7876
Livermore National Laboratory                NEW -->  chapman@.llnl.gov
P. O. Box 808, L-572            "Are you in charge here?"
Livermore, CA  94550            "No, but I'm full of ideas!"  -- Dr. Who