From: CJSENFT@lexmark.com
Newsgroups: comp.windows.x.motif
Subject: Core Dump when deleting from a List widget
Date: 4 Jan 93 18:49:48 GMT
Organization: Lexmark International, Lexington, KY
X-Disclaimer: These views are the poster's and not necessarily those of Lexmark

******> WARNING Long (but necessary) Code Section Attached <******
 
     I have been trying to use a list widget in XmEXTENDED_SELECT mode.
I wish to create create a list and have the user select items and then
a push button which will delete the selected items.  Since the items in
my actual application are not necessarily unique, I prefer to use the
position list widget functions to perform the delete.  My problem is that
the program core dumps.  I have written what I consider a simple test
program (which follows) that also exhibits this problem.  I am using
Motif v1.1 on a RISC/6000 (AIX v3.2) but I am not sure what patch level
my version is at.
 
     The code includes alterations to the translations so that selections
are always done in "add mode" (I am unsure of my terminology).  The code
still core dumps if this alteration is removed and the user makes his
selections manually using "add mode".  The crash occurs when a deletion
has already been performed at least once and the user attempts to make
another selection in the list.  The crash occurs in some internal
function (AddItem) before my XmNextendedSelectionCallback is called.
Although the crash is quite unpredictable it seems to occur more
frequently when items are deleted from the end of the list.
 
     Thanks Warren A. Bullock
     (via Cathy J. Senft :: Lexmark International, Inc. :: cjsenft@lexmark.com)
 
 
# ========================================================================
# BEGINNING OF SOURCE CODE
# ========================================================================
 
 
/************************************************************************/
/* Name: list_test.c                                                    */
/*                                                                      */
/* Description: test list widget delete behavior                        */
/*                                                                      */
/* History:  Dec 21 1992  Warren A. Bullock                             */
/************************************************************************/
 
/*****************/
/* include files */
/*****************/
#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/List.h>
#include <Xm/PushB.h>
#include <Xm/Form.h>
 
/******************/
/* local literals */
/******************/
#define LIST_LENGTH 100
 
/***********************/
/* function prototypes */
/***********************/
void select_callback(Widget, XtPointer, XmListCallbackStruct *);
void delete_callback(Widget, XtPointer, XtPointer);
void quit_callback(Widget, XtPointer, XtPointer);
 
/********************/
/* global variables */
/********************/
int list_num, selections[LIST_LENGTH];
Widget list_w;
 
/*****************/
/* main function */
/*****************/
main (int argc, char **argv)
  {
    XtAppContext app;
    XtTranslations trans_parsed;
    Widget toplevel_w, form_w, delete_button_w, quit_button_w;
    XmString list_data[LIST_LENGTH], temp_xmstr;
    char trans_str[] = "#replace \n\
            <Btn1Down>:    ListBeginToggle()  \n\
            <Btn1Motion>:  ListButtonMotion() \n\
            <Btn1Up>:      ListEndToggle()    \n",
         temp_str[80];
    Arg args[10];
    int num_args, i;
 
    /*************************************************/
    /* initialize the toolkit; Create toplevel shell */
    /*************************************************/
    toplevel_w = XtVaAppInitialize(&app, "LT", NULL, 0, &argc, argv, NULL,
        XmNtitle, "ListTest", NULL);
 
    /*************************************************************/
    /* create a form widget which will contain all other widgets */
    /*************************************************************/
    form_w = XtVaCreateManagedWidget("form",
        xmFormWidgetClass, toplevel_w, NULL);
 
    /***************************************/
    /* initialize list widget translations */
    /***************************************/
    trans_parsed = XtParseTranslationTable(trans_str);
 
    /*******************************/
    /* initialize list widget data */
    /*******************************/
    for (i = 0; i < LIST_LENGTH; i++)
      {
        sprintf(temp_str, "%d Item    ", i + 1);
        list_data[i] = XmStringCreateLtoR(temp_str, XmSTRING_DEFAULT_CHARSET);
        selections[i] = FALSE;
      }
    list_num = LIST_LENGTH;
 
    /**********************/
    /* create list widget */
    /**********************/
    num_args = 0;
    XtSetArg(args[num_args], XmNselectionPolicy, XmEXTENDED_SELECT);
        num_args++;
    XtSetArg(args[num_args], XmNitems, list_data); num_args++;
    XtSetArg(args[num_args], XmNitemCount, list_num); num_args++;
    XtSetArg(args[num_args], XmNvisibleItemCount, 10); num_args++;
    XtSetArg(args[num_args], XmNleftAttachment, XmATTACH_FORM); num_args++;
    XtSetArg(args[num_args], XmNtopAttachment, XmATTACH_FORM); num_args++;
    list_w = XmCreateScrolledList(form_w, "list", args, num_args);
    XtManageChild(list_w);
 
    /*******************************/
    /* change list widget behavior */
    /*******************************/
    num_args = 0;
    XtSetArg(args[num_args], XmNtranslations, trans_parsed); num_args++;
    XtSetValues(list_w, args, num_args);
    XtAddCallback(list_w, XmNextendedSelectionCallback,
      select_callback, NULL);
 
    /************************/
    /* create delete button */
    /************************/
    temp_xmstr = XmStringCreateLtoR("Delete", XmSTRING_DEFAULT_CHARSET);
    delete_button_w = XtVaCreateManagedWidget("delete_button",
        xmPushButtonWidgetClass, form_w,
        XmNleftAttachment, XmATTACH_FORM,
        XmNtopAttachment, XmATTACH_WIDGET,
        XmNtopWidget, list_w,
        XmNmultiClick, XmMULTICLICK_DISCARD,
        XmNlabelString, temp_xmstr, NULL);
    XtAddCallback(delete_button_w, XmNactivateCallback,
      delete_callback, NULL);
    XmStringFree(temp_xmstr);
 
    /**********************/
    /* create quit button */
    /**********************/
    temp_xmstr = XmStringCreateLtoR("Quit", XmSTRING_DEFAULT_CHARSET);
    quit_button_w = XtVaCreateManagedWidget("quit_button",
        xmPushButtonWidgetClass, form_w,
        XmNleftAttachment, XmATTACH_WIDGET,
        XmNleftWidget, delete_button_w,
        XmNtopAttachment, XmATTACH_WIDGET,
        XmNtopWidget, list_w,
        XmNmultiClick, XmMULTICLICK_DISCARD,
        XmNlabelString, temp_xmstr, NULL);
    XtAddCallback(quit_button_w, XmNactivateCallback,
      quit_callback, NULL);
    XmStringFree(temp_xmstr);
 
    /*******************************/
    /* realize application widgets */
    /*******************************/
    XtRealizeWidget(toplevel_w);
 
    /********************/
    /* start event loop */
    /********************/
    XtAppMainLoop(app);
  }
 
/*********************************/
/* callback to select list items */
/*********************************/
void select_callback(Widget w, XtPointer client_data,
    XmListCallbackStruct *list_data)
  {
    int i, j;
 
#ifdef DEBUG
      {
        int num;
        XmString *items;
 
        XtVaGetValues(list_w, XmNitemCount, &num, XmNitems, &items, NULL);
        fprintf(stderr, "BEFORE SELECTION NUMBER IN LIST (%d)\n", num);
        if (num > 0)
          {
            for(i = 0; i < num; i++)
              {
                char *str;
 
                XmStringGetLtoR(items[i], XmSTRING_DEFAULT_CHARSET, &str);
                fprintf(stderr, "  ITEM (%s)\n", str);
              }
          }
      }
#endif
 
    /*******************************************/
    /* mark selected items in selections array */
    /*******************************************/
    for (i = 0, j = 0; i < list_num; i++)
      {
 
        /***********************************/
        /* while there are more selections */
        /***********************************/
        if (j < list_data->selected_item_count)
          {
            if (list_data->selected_item_positions[j] == i + 1)
              {
                selections[i] = TRUE;
                j++;
              }
            else
              selections[i] = FALSE;
          }
        else
          selections[i] = FALSE;
      }
 
    /*******************/
    /* show selections */
    /*******************/
    fprintf(stderr, "SELECTIONS\n");
    for (i = 0; i < list_num; i++)
      {
        if (selections[i] == TRUE)
          fprintf(stderr, "  %d\n", i+1);
      }
    fprintf(stderr, "\n");
  }
 
/*********************************/
/* callback to delete list items */
/*********************************/
void delete_callback(Widget w, XtPointer client_data, XtPointer call_data)
  {
    int i;
 
    /*********************************/
    /* delete all current selections */
    /*********************************/
    fprintf(stderr, "DELETIONS\n");
    for (i = list_num - 1; i >= 0; i--)
      {
        if (selections[i] == TRUE)
          {
            XmListDeletePos(list_w, i + 1);
            list_num--;
            fprintf(stderr, "  %d\n", i + 1);
          }
      }
    fprintf(stderr, "\n");
 
    /***********************************/
    /* set all selections to all false */
    /***********************************/
    for (i = 0; i < list_num; i++)
      selections[i] = FALSE;
 
#ifdef DEBUG
      {
        int num;
        XmString *items;
 
        XtVaGetValues(list_w, XmNitemCount, &num, XmNitems, &items, NULL);
        fprintf(stderr, "AFTER DELETE NUMBER IN LIST (%d)\n", num);
        if (num > 0)
          {
            for(i = 0; i < num; i++)
              {
                char *str;
 
                XmStringGetLtoR(items[i], XmSTRING_DEFAULT_CHARSET, &str);
                fprintf(stderr, "  ITEM (%s)\n", str);
              }
          }
      }
#endif
 
  }
 
/****************************/
/* callback to exit program */
/****************************/
void quit_callback(Widget w, XtPointer client_data, XtPointer call_data)
  {
    XtCloseDisplay(XtDisplay(w));
    exit(0);
  }
 
# ========================================================================
# END OF SOURCE CODE
# ========================================================================
 
 
# ========================================================================
# BEGINNING OF MAKEFILE
# ========================================================================
 
list_test: list_test.o
    cc -g -o list_test list_test.o -lXm -lXt -lX11
 
list_test.o: list_test.c
    cc -g -c list_test.c
 
 
# ========================================================================
# END OF MAKEFILE
# ========================================================================
 
 
Thanks again.
(Cathy J. Senft :: Lexmark International, Inc. :: cjsenft@lexmark.com)
Newsgroups: comp.windows.x.motif