问题描述
#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/List.h>
/* FUNCTION DECLaraTION */
void add_printers();
void add_printer(char *printer_name);
void add_command_groups(char *printer_name);
void read_printer_file(char *printer_name);
Widget make_menu_item(char *item_name,Widget menu);
void select_printer(Widget w,XtPointer client_data,XmpushButtonCallbackStruct *call_data);
/* XT/XM RELATED VARIABLES */
XtAppContext context;
xmstringCharSet char_set = xmsTRING_DEFAULT_CHARSET;
/* WIDGETS */
Widget toplevel;
Widget form;
Widget printer_pulldown_menu;
Widget printer_option_menu;
Widget printer_option_item[100];
int printer_menu_items = 0;
Widget command_group_list;
Widget command_list;
int main(int argc,char *argv[]) {
Arg al[10];
int ac;
/* CREATE TOP SHELL WIDGET */
toplevel = XtAppInitialize(&context,"",NULL,&argc,argv,0);
/* RESIZE TOP LEVEL*/
ac = 0;
XtSetArg(al[ac],XmNheight,900); ac++;
XtSetArg(al[ac],XmNwidth,600); ac++;
XtSetValues(toplevel,al,ac);
/* CREATE FORM MANAGER WIDGET */
form = XmCreateForm(toplevel,"form",ac);
XtManageChild(form);
/* SELECT PRINTER PULLDOWN */
ac = 0;
XtSetArg(al[ac],XmNleftAttachment,XmATTACH_FORM); ac++;
XtSetArg(al[ac],XmNrightAttachment,XmATTACH_FORM); ac++;
printer_pulldown_menu= XmCreatePulldownMenu(form,"printer_pulldown_menu",ac);
ac = 0;
XtSetArg(al[ac],XmNsubMenuId,printer_pulldown_menu); ac++;
XtSetArg(al[ac],XmNlabelString,xmstringCreate("Printer",char_set)); ac++;
/* SELECT PRINTER OPTIONS */
printer_option_menu = XmCreateOptionMenu(form,"printer_option_menu",ac);
add_printers();
XtManageChild(printer_option_menu);
/* COMMAND GROUP LIST */
ac = 0;
XtSetArg(al[ac],XmNselectionPolicy,xmsINGLE_SELECT); ac++;
XtSetArg(al[ac],XmNtopAttachment,XmATTACH_WIDGET); ac++;
XtSetArg(al[ac],XmNtopWidget,printer_option_menu); ac++;
XtSetArg(al[ac],XmNbottomAttachment,XmATTACH_POSITION); ac++;
XtSetArg(al[ac],XmNbottomPosition,50); ac++;
command_group_list = XmCreateScrolledList(form,"command_group_list",ac);
XtManageChild(command_group_list);
/* COMMAND LIST */
ac = 0;
XtSetArg(al[ac],command_group_list); ac++;
XtSetArg(al[ac],XmATTACH_FORM); ac++;
command_list = XmCreateScrolledList(form,"command_list",ac);
XtManageChild(command_list);
/* REALIZE TOPLEVEL */
XtRealizeWidget(toplevel);
XtAppMainLoop(context);
return 0;
}
/* THIS FUNCTION READS FILES UNDER /etc/xcmdprinter AND ADDS EACH PRINTER TO THE MENU */
void add_printers() {
DIR *dd;
struct dirent *entry;
dd = opendir("/etc/xcmdprinter");
while((entry = readdir(dd))!=NULL) {
/* PROCESS ONLY FILES AND SYMBOLIC LINKS */
int i = 0;
if(entry->d_type == DT_REG || entry->d_type == DT_LNK) {
/* OPEN FILE AND READ LINE BY LINE */
add_printer(entry->d_name);
}
}
closedir(dd);
}
void read_printer_file(char *printer_name) {
}
void add_printer(char *printer_name) {
if(printer_menu_items==100) {
fprintf(stderr,"ERROR: Maximum number of available printers is 100\n");
exit(1);
}
printer_option_item[printer_menu_items] = make_menu_item(printer_name,printer_pulldown_menu);
printer_menu_items++;
}
Widget make_menu_item(char *item_name,Widget menu) {
int ac;
Arg al[10];
Widget item;
ac = 0;
XtSetArg(al[ac],xmstringCreateLtoR(item_name,char_set)); ac++;
item = XmCreatePushButton(menu,item_name,ac);
XtManageChild(item);
XtAddCallback(item,XmNactivateCallback,select_printer,NULL);
XtSetSensitive(item,True);
return(item);
}
void select_printer(Widget w,XmpushButtonCallbackStruct *call_data) {
printf("BUTTON SELECTED\n");
}
void add_command_groups(char *printer_name) {
}
xcmdprinter: xcmdprinter.o
cc -std=c89 xcmdprinter.o -o xcmdprinter -L/usr/local/lib -I/usr/local/include -lXm -lXt -lX11
xcmdprinter.o: xcmdprinter.c
cc -g -std=c89 -c xcmdprinter.c -o xcmdprinter.o -I/usr/local/include
clean:
rm */*.o
rm xcmdprinter
rm *.core
但是,在实现选项菜单项选择的回调时,我收到以下警告,我很难理解为什么会生成此警告以及如何修复它。
cc -g -std=c89 -c xcmdprinter.c -o xcmdprinter.o -I/usr/local/include
xcmdprinter.c:154:43: warning: incompatible pointer types passing 'void (Widget,XtPointer,XmpushButtonCallbackStruct *)' (aka 'void (struct _WidgetRec *,void *,XmpushButtonCallbackStruct *)') to parameter of
type 'XtCallbackProc' (aka 'void (*)(struct _WidgetRec *,void *)') [-Wincompatible-pointer-types]
XtAddCallback(item,NULL);
^~~~~~~~~~~~~~
/usr/local/include/X11/Intrinsic.h:1247:35: note: passing argument to parameter here
XtCallbackProc /* callback */,^
1 warning generated.
解决方法
select_printer
的最后一个参数的类型与其回调预期的 XtAddCallback
不匹配。
select_printer
函数有一个 XmPushButtonCallbackStruct *
参数,而回调应该有一个 void *
参数。
我建议的解决方法是将 select_printer
的最后一个参数更改为 void *
,然后在 select_printer
中将参数转换为正确的类型。喜欢:
// Prototype declaration
void select_printer(Widget w,XtPointer client_data,XtPointer *call_data);
// ...
// Function definition
void select_printer(Widget w,XtPointer *call_data_voidp)
{
XmPushButtonCallbackStruct *call_data = (XmPushButtonCallbackStruct *) call_data_voidp;
// ...
}