微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将小部件作为 client_data 传递给 Xt/Motif 信号处理程序?

如何解决如何将小部件作为 client_data 传递给 Xt/Motif 信号处理程序?

我想要一个 Motif 应用程序在接收到 SIGUSR1 信号时重绘绘图区小部件。

我已经使用 X11R6 中的 Xt 功能配置了信号:

/* 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);

其中 signal_usr1_handler 是 OS Unix 处理程序,read_data 是 Xt 信号处理程序。

对于 Xt 信号处理程序,我试图传递小部件 chart_area,它是一个绘图区小部件。

这些是处理程序:

/* SIGNAL HANDLER */
void signal_usr1_handler() {
    printf("SIGUSR1 RECEIVED\n");
    XtNoticeSignal(signal_id);
}
    
/* READ DATA XT SIGNAL HANDLER */
void read_data(XtPointer client_data,XtSignalId *id) {

    posx += 5;
    printf("XT HANDLES SIGUSR1\n"); 
    
    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) &da_struct);
    
}

应用程序在执行 Segmentation fault (core dumped) 函数时正好引发一个 XtCallCallbacks

这是完整的源代码

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
 
#include <Xm/Xm.h>
#include <Xm/DrawingA.h>
#include <Xm/Label.h>

/* 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( 
        &app,argv[0],&argc,argv,sessionShellWidgetClass,XmNwidth,400,XmNheight,300,NULL
    );
    
    /* CREATE AND MANAGE DRAWING CANVAS WIDGET */
    ac=0; 
    chart_area = XmCreateDrawingArea(toplevel,"chart_area",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),&gcv);

    /* ASSIGN GRAPHICS CONTEXT */   
    XtVaSetValues(chart_area,XmNuserData,gc,NULL);   
    
    /* ASSIGN CALLBACKS AND MANAGE WIDGET */
    XtAddCallback(chart_area,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,(XtPointer)chart_area);
        
    /* REALIZE TOPLEVEL WINDOW AND LAUNCH APPLICATION LOOP */
    XtRealizeWidget(toplevel);  
    XtAppMainLoop(app);
    
    return 0;

}

void draw_chart(Widget widget,XtPointer call_data) {

    XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *) call_data;
    XEvent *event = cbs->event;
    display *dpy = event->xany.display;
    GC gc;
    
    /* DRAW LINE */
    if(cbs->reason == XmCR_EXPOSE || cbs->reason == XmCR_ACTIVATE) {

        XtVaGetValues(widget,&gc,NULL);
        XDrawLine(dpy,cbs->window,10,posx,200);

    }
}
    
/* SIGNAL HANDLER */
void signal_usr1_handler() {
    printf("SIGUSR1 RECEIVED\n");
    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("XT HANDLES SIGUSR1\n"); 
    
    XmDrawingAreaCallbackStruct da_struct;

    da_struct.reason = XmCR_EXPOSE;
    da_struct.event = (XEvent *) NULL;
    da_struct.window = Xtwindow((Widget)client_data);

    /* XtCallCallbacks((Widget)client_data,(XtPointer) &da_struct); */
    
}

解决方法

以下原因导致崩溃:

Display *dpy = event->xany.display;

因为事件被设置为 NULL。

此外,您可能需要通过传递其地址并接收 XmUserData 作为来处理 gc

GC *gc;

然后使用 *gc,

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。