title: How do I pass a widget as client_data to a Xt/Motif signal handler?
body: <p>I want a Motif application to redraw a Drawing Area widget on reception of SIGUSR1 signal.</p>
  <p>I have configured the signal using the Xt functionalities in X11R6:</p>
  <pre><code>/* CONFIGURE READ SIGNAL, TRAPS SIGUSR1 TO FORCE APPLICATION READ DATA FILE */
  signal(SIGUSR1, signal_usr1_handler);
  signal_id = XtAppAddSignal (app, read_data, (XtPointer)chart_area);
  </code></pre>
  <p>Where <code>signal_usr1_handler</code> is the OS Unix handler and <code>read_data</code> is the Xt signal handler.</p>
  <p>For the Xt signal handler I am trying to pass the widget <code>chart_area</code> which is a Drawing Area Widget.</p>
  <p>These are the handlers:</p>
  <pre><code>/* SIGNAL HANDLER */
  void signal_usr1_handler() {
      printf(&quot;SIGUSR1 RECEIVED\n&quot;);
      XtNoticeSignal(signal_id);
  }
      
  /* READ DATA XT SIGNAL HANDLER */
  void read_data(XtPointer client_data, XtSignalId *id) {
  
      posx += 5;
      printf(&quot;XT HANDLES SIGUSR1\n&quot;); 
      
      XmDrawingAreaCallbackStruct da_struct;
  
      da_struct.reason = XmCR_EXPOSE;
      da_struct.event = (XEvent *) NULL;
      da_struct.window = XtWindow((Widget)client_data);
  
      XtCallCallbacks((Widget)client_data, XmNexposeCallback, (XtPointer) &amp;da_struct);
      
  }
  </code></pre>
  <p>The application raises a <code>Segmentation fault (core dumped)</code> exactly when executing the <code>XtCallCallbacks</code> function.</p>
  <p>This is the complete source code:</p>
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;signal.h&gt;
  #include &lt;sys/wait.h&gt;
   
  #include &lt;Xm/Xm.h&gt;
  #include &lt;Xm/DrawingA.h&gt;
  #include &lt;Xm/Label.h&gt;
  
  /* FUNCTION DECLARATIONS */
  void draw_chart(Widget widget, XtPointer client_data, XtPointer call_data);
  void signal_usr1_handler();
  void read_data(XtPointer client_data, XtSignalId *id);
  
  /* XT SIGNAL ID */
  XtSignalId  signal_id;      /* Signal ID used to receive data read via SIGUSR1 */
       
  int main(int argc, char *argv[]) {
  
      /* WIDGETS */
      XtAppContext    app;            /* Application Context */
      Widget      toplevel;       /* Top Level Button */
      Widget      chart_area;     /* Drawing Area Widget to draw the chart */
          
      /* DRAWING AREA RELATED */
      XGCValues   gcv;
      GC      gc;
      
      /* RESOURCE VALUE ARRAYS/COUNT */
      Arg al[10];
      int ac;
      
      /* INITIALIZE TOP LEVEL WINDOW */
      XtSetLanguageProc(NULL, NULL, NULL);
      toplevel = XtVaOpenApplication( 
          &amp;app, argv[0], NULL, 0, &amp;argc, argv, NULL, sessionShellWidgetClass,
          XmNwidth, 400, XmNheight, 300, NULL
      );
      
      /* CREATE AND MANAGE DRAWING CANVAS WIDGET */
      ac=0; 
      chart_area = XmCreateDrawingArea(toplevel, &quot;chart_area&quot;, al, ac);
                  
      /* CREATE GRAPHICS CONTEXT */
      gcv.foreground = WhitePixelOfScreen(XtScreen(chart_area));
      gcv.background = BlackPixelOfScreen(XtScreen(chart_area));  
      gc = XCreateGC (
          XtDisplay(chart_area),
          RootWindowOfScreen(XtScreen(chart_area)), 
          (GCForeground | GCBackground), 
          &amp;gcv);
  
      /* ASSIGN GRAPHICS CONTEXT */   
      XtVaSetValues(chart_area, XmNuserData, gc, NULL);   
      
      /* ASSIGN CALLBACKS AND MANAGE WIDGET */
      XtAddCallback(chart_area, XmNexposeCallback, draw_chart, NULL);
      XtManageChild(chart_area);  
                      
      /* CONFIGURE READ SIGNAL, TRAPS SIGUSR1 TO FORCE APPLICATION READ DATA FILE */
      signal(SIGUSR1, signal_usr1_handler);
      signal_id = XtAppAddSignal (app, read_data, (XtPointer)chart_area);
          
      /* REALIZE TOPLEVEL WINDOW AND LAUNCH APPLICATION LOOP */
      XtRealizeWidget(toplevel);  
      XtAppMainLoop(app);
      
      return 0;
  
  }
  
  void draw_chart(Widget widget, XtPointer client_data, XtPointer call_data) {
  
      XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *) call_data;
      XEvent *event = cbs-&gt;event;
      Display *dpy = event-&gt;xany.display;
      GC gc;
      
      /* DRAW LINE */
      if(cbs-&gt;reason == XmCR_EXPOSE || cbs-&gt;reason == XmCR_ACTIVATE) {
  
          XtVaGetValues(widget, XmNuserData, &amp;gc, NULL);
          XDrawLine(dpy, cbs-&gt;window, gc, 10, 10, posx, 200);
  
      }
  }
      
  /* SIGNAL HANDLER */
  void signal_usr1_handler() {
      printf(&quot;SIGUSR1 RECEIVED\n&quot;);
      XtNoticeSignal(signal_id);
  }
      
  /* READ DATA XT SIGNAL HANDLER */
  void read_data(XtPointer client_data, XtSignalId *id) {
  
      /* ... READ DATA AND PROCESSING GOES HERE ... */
  
      posx += 5;
      printf(&quot;XT HANDLES SIGUSR1\n&quot;); 
      
      XmDrawingAreaCallbackStruct da_struct;
  
      da_struct.reason = XmCR_EXPOSE;
      da_struct.event = (XEvent *) NULL;
      da_struct.window = XtWindow((Widget)client_data);
  
      /* XtCallCallbacks((Widget)client_data, XmNexposeCallback, (XtPointer) &amp;da_struct); */
      
  }
  </code></pre>