免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1113 | 回复: 0
打印 上一主题 下一主题

在Xlib程序中使用select方法并行处理X事件和网络通信 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-07 11:15 |只看该作者 |倒序浏览

                  在Xlib程序中无阻塞的并行处理X事件和网络通信的方法可以使用select函数的基本思想来实现。Xlib库提供了一个在很多系统平台中都通用的接口函数(XtAppAddInput)来实现该功能;当然,我们也可采用自己的代码来实现。
示例程序:
/*
* Demo.c
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
/* $XFree86: xc/lib/Xaw/SimpleP.h,v 1.12 2001/12/14 19:54:43 dawes Exp $ */
#ifndef _SimpleP_h
#define _SimpleP_h
#include
//#include
/* $XFree86: xc/lib/Xaw/Simple.h,v 1.8 2001/01/17 19:42:30 dawes Exp $ */
#ifndef _Simple_h
#define _Simple_h
#include
/* Resources:
Name       Class  RepType  Default Value
----       -----  -------  -------------
background      Background  Pixel  XtDefaultBackground
border       BorderColor Pixel  XtDefaultForeground
borderWidth      BorderWidth Dimension 1
cursor       Cursor  Cursor  None
cursorName      Cursor  String  NULL
destroyCallback     Callback  Pointer  NULL
displayList      DisplayList XawDisplayList* NULL
height       Height  Dimension 0
insensitiveBorder   Insensitive Pixmap  Gray
mappedWhenManaged   MappedWhenManaged Boolean  True
pointerColor        Foreground         Pixel           XtDefaultForeground
pointerColorBackground Background      Pixel           XtDefaultBackground
sensitive      Sensitive  Boolean  True
tip       Tip  String  NULL
width       Width  Dimension 0
x       Position  Position 0
y       Position  Position 0
*/
#define XtNcursor "cursor"
#define XtNcursorName "cursorName"
#define XtNinsensitiveBorder "insensitiveBorder"
#define XtCInsensitive "Insensitive"
#ifndef XtCInternational
#define XtCInternational "International"
#endif
#ifndef XtNinternational
#define XtNinternational "international"
#endif
typedef struct _SimpleClassRec *SimpleWidgetClass;
typedef struct _SimpleRec *SimpleWidget;
//extern WidgetClass simpleWidgetClass;
#endif /* _Simple_h */
_XFUNCPROTOBEGIN
//#include
/* $XdotOrg: xc/lib/Xaw/XawInit.h,v 1.2 2004/04/23 18:43:38 eich Exp $ */
#ifndef _XawInit_h
#define _XawInit_h
#define XawVendor XVENDORNAMESHORT
#define XawVersion 6700002L
#include
_XFUNCPROTOBEGIN
void XawInitializeWidgetSet(void);
extern Widget XawOpenApplication(
        XtAppContext *app_context_return,
        Display      *dpy,
        Screen       *screen,
        String        application_name,
        String        application_class,
        WidgetClass   widget_class,
        int          *argc,
        String       *argv
    );
_XFUNCPROTOEND
#endif /* _XawInit_h */
typedef struct
{
    Bool (*change_sensitive)(Widget);
} SimpleClassPart;
#define XtInheritChangeSensitive ((Bool (*)(Widget))_XtInherit)
typedef struct _SimpleClassRec
{
    CoreClassPart core_class;
    SimpleClassPart simple_class;
} SimpleClassRec;
//extern SimpleClassRec simpleClassRec;
typedef struct
{
    /* resources */
    Cursor cursor;
    Pixmap insensitive_border;
    String cursor_name;   /* cursor specified by name */
    Pixel pointer_fg, pointer_bg; /* Pointer colors */
    Boolean international;
    XtCallbackList callbacks;
    /* private */
} SimplePart;
typedef struct _SimpleRec
{
    CorePart core;
    SimplePart simple;
} SimpleRec;
_XFUNCPROTOEND
#endif /* _SimpleP_h */
//#include
//#include "Private.h"
/* $XFree86: xc/lib/Xaw/Private.h,v 3.9 1999/05/16 10:12:48 dawes Exp $ */
#ifndef _XawPrivate_h
#define _XawPrivate_h
#define XawMax(a, b) ((a) > (b) ? (a) : (b))
#define XawMin(a, b) ((a) rectangle.x)
#endif
#ifndef XtY
#define XtY(w)            (((RectObj)w)->rectangle.y)
#endif
#ifndef XtWidth
#define XtWidth(w)        (((RectObj)w)->rectangle.width)
#endif
#ifndef XtHeight
#define XtHeight(w)       (((RectObj)w)->rectangle.height)
#endif
#ifndef XtBorderWidth
#define XtBorderWidth(w)  (((RectObj)w)->rectangle.border_width)
#endif
/* misc */
void XawTypeToStringWarning(Display*, String);
/* OS.c */
int _XawGetPageSize(void);
#endif /* _XawPrivate_h */
/*
* Class Methods
*/
static Bool ChangeSensitive(Widget);
static void XawSimpleClassInitialize(void);
static void XawSimpleClassPartInitialize(WidgetClass);
static void XawSimpleRealize(Widget, Mask*, XSetWindowAttributes*);
static Boolean XawSimpleSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
/*
* Prototypes
*/
static void ConvertCursor(Widget);
/*
* Initialization
*/
#define offset(field) XtOffsetOf(SimpleRec, simple.field)
static XtResource resources[] =
{
    {
        XtNcursor,
        XtCCursor,
        XtRCursor,
        sizeof(Cursor),
        offset(cursor),
        XtRImmediate,
        (XtPointer)None
    },
    {
        XtNinsensitiveBorder,
        XtCInsensitive,
        XtRPixmap,
        sizeof(Pixmap),
        offset(insensitive_border),
        XtRImmediate,
        NULL
    },
    {
        XtNpointerColor,
        XtCForeground,
        XtRPixel,
        sizeof(Pixel),
        offset(pointer_fg),
        XtRString,
        XtDefaultForeground
    },
    {
        XtNpointerColorBackground,
        XtCBackground,
        XtRPixel,
        sizeof(Pixel),
        offset(pointer_bg),
        XtRString,
        XtDefaultBackground
    },
    {
        XtNcursorName,
        XtCCursor,
        XtRString,
        sizeof(String),
        offset(cursor_name),
        XtRString,
        NULL
    },
    {
        XtNinternational,
        XtCInternational,
        XtRBoolean,
        sizeof(Boolean),
        offset(international),
        XtRImmediate,
        (XtPointer)False
    },
    {
        XtNcallback,
        XtCCallback,
        XtRCallback,
        sizeof(XtPointer),
        offset(callbacks),
        XtRCallback,
        NULL
    },
#undef offset
};
SimpleClassRec simpleClassRec =
{
    /* core */
    {
        (WidgetClass)&widgetClassRec, /* superclass */
        "Simple",    /* class_name */
        sizeof(SimpleRec),   /* widget_size */
        XawSimpleClassInitialize,  /* class_initialize */
        XawSimpleClassPartInitialize, /* class_part_initialize */
        False,    /* class_inited */
        NULL,    /* initialize */
        NULL,    /* initialize_hook */
        XawSimpleRealize,   /* realize */
        NULL,    /* actions */
        0,     /* num_actions */
        resources,    /* resources */
        XtNumber(resources),  /* num_resources */
        NULLQUARK,    /* xrm_class */
        True,    /* compress_motion */
        True,    /* compress_exposure */
        True,    /* compress_enterleave */
        False,    /* visible_interest */
        NULL,    /* destroy */
        NULL,    /* resize */
        NULL,    /* expose */
        XawSimpleSetValues, /* set_values */
        NULL,               /* set_values_hook */
        XtInheritSetValuesAlmost,  /* set_values_almost */
        NULL,    /* get_values_hook */
        NULL,    /* accept_focus */
        XtVersion,    /* version */
        NULL,    /* callback_private */
        NULL,    /* tm_table */
        XtInheritQueryGeometry,  /* query_geometry */
        XtInheritDisplayAccelerator, /* display_accelerator */
        NULL,    /* extension */
    },
    /* simple */
    {
        ChangeSensitive,   /* change_sensitive */
    },
};
WidgetClass simpleWidgetClass = (WidgetClass)&simpleClassRec;
static void
XawSimpleClassInitialize(void)
{
    static XtConvertArgRec convertArg[] =
    {
        {
            XtWidgetBaseOffset,
            (XtPointer)XtOffsetOf(WidgetRec, core.screen),
            sizeof(Screen *)
        },
        {
            XtResourceString,
            (XtPointer)XtNpointerColor,
            sizeof(Pixel)
        },
        {
            XtResourceString,
            (XtPointer)XtNpointerColorBackground,
            sizeof(Pixel)
        },
        {
            XtWidgetBaseOffset,
            (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
            sizeof(Colormap)
        },
    };
    XawInitializeWidgetSet();
    XtSetTypeConverter(XtRString, XtRColorCursor, XmuCvtStringToColorCursor,
                       convertArg, XtNumber(convertArg), XtCacheByDisplay, NULL);
}
static void
XawSimpleClassPartInitialize(WidgetClass cclass)
{
    SimpleWidgetClass c = (SimpleWidgetClass)cclass;
    SimpleWidgetClass super = (SimpleWidgetClass)c->core_class.superclass;
    if (c->simple_class.change_sensitive == NULL)
    {
        char buf[BUFSIZ];
        (void)XmuSnprintf(buf, sizeof(buf),
                          "%s Widget: The Simple Widget class method "
                          "'change_sensitive' is undefined.\nA function "
                          "must be defined or inherited.",
                          c->core_class.class_name);
        XtWarning(buf);
        c->simple_class.change_sensitive = ChangeSensitive;
    }
    if (c->simple_class.change_sensitive == XtInheritChangeSensitive)
        c->simple_class.change_sensitive = super->simple_class.change_sensitive;
}
static void
XawSimpleRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
{
    Pixmap border_pixmap = CopyFromParent;
    if (!XtIsSensitive(w))
    {
        /* change border to gray; have to remember the old one,
         * so XtDestroyWidget deletes the proper one */
        if (((SimpleWidget)w)->simple.insensitive_border == None)
            ((SimpleWidget)w)->simple.insensitive_border =
                XmuCreateStippledPixmap(XtScreen(w),
                                        w->core.border_pixel,
                                        w->core.background_pixel,
                                        w->core.depth);
        border_pixmap = w->core.border_pixmap;
        attributes->border_pixmap =
            w->core.border_pixmap = ((SimpleWidget)w)->simple.insensitive_border;
        *valueMask |= CWBorderPixmap;
        *valueMask &= ~CWBorderPixel;
    }
    ConvertCursor(w);
    if ((attributes->cursor = ((SimpleWidget)w)->simple.cursor) != None)
        *valueMask |= CWCursor;
    XtCreateWindow(w, InputOutput, (Visual *)CopyFromParent,
                   *valueMask, attributes);
    if (!XtIsSensitive(w))
        w->core.border_pixmap = border_pixmap;
}
/*
* Function:
* ConvertCursor
*
* Parameters:
* w - simple widget
*
* Description:
* Converts a name to a new cursor.
*/
static void
ConvertCursor(Widget w)
{
    SimpleWidget simple = (SimpleWidget) w;
    XrmValue from, to;
    Cursor cursor = None;
    if (simple->simple.cursor_name == NULL)
        return;
    from.addr = (XPointer)simple->simple.cursor_name;
    from.size = strlen((char *)from.addr) + 1;
    to.size = sizeof(Cursor);
    to.addr = (XPointer)&cursor;
    if (XtConvertAndStore(w, XtRString, &from, XtRColorCursor, &to))
        simple->simple.cursor = cursor;
    else
        XtAppErrorMsg(XtWidgetToApplicationContext(w),
                      "convertFailed","ConvertCursor","XawError",
                      "Simple: ConvertCursor failed.",
                      NULL, NULL);
}
/*ARGSUSED*/
static Boolean
XawSimpleSetValues(Widget current, Widget request, Widget cnew,
                   ArgList args, Cardinal *num_args)
{
    SimpleWidget s_old = (SimpleWidget)current;
    SimpleWidget s_new = (SimpleWidget)cnew;
    Bool new_cursor = False;
    /* this disables user changes after creation */
    s_new->simple.international = s_old->simple.international;
    if (XtIsSensitive(current) != XtIsSensitive(cnew))
        (*((SimpleWidgetClass)XtClass(cnew))->simple_class.change_sensitive)
        (cnew);
    if (s_old->simple.cursor != s_new->simple.cursor)
        new_cursor = True;
    /*
     * We are not handling the string cursor_name correctly here
     */
    if (s_old->simple.pointer_fg != s_new->simple.pointer_fg ||
            s_old->simple.pointer_bg != s_new->simple.pointer_bg ||
            s_old->simple.cursor_name != s_new->simple.cursor_name)
    {
        ConvertCursor(cnew);
        new_cursor = True;
    }
    if (new_cursor && XtIsRealized(cnew))
    {
        if (s_new->simple.cursor != None)
            XDefineCursor(XtDisplay(cnew), XtWindow(cnew), s_new->simple.cursor);
        else
            XUndefineCursor(XtDisplay(cnew), XtWindow(cnew));
    }
    return (False);
}
static Bool
ChangeSensitive(Widget w)
{
    if (XtIsRealized(w))
    {
        if (XtIsSensitive(w))
            if (w->core.border_pixmap != XtUnspecifiedPixmap)
                XSetWindowBorderPixmap(XtDisplay(w), XtWindow(w),
                                       w->core.border_pixmap);
            else
                XSetWindowBorder(XtDisplay(w), XtWindow(w),
                                 w->core.border_pixel);
        else
        {
            if (((SimpleWidget)w)->simple.insensitive_border == None)
                ((SimpleWidget)w)->simple.insensitive_border =
                    XmuCreateStippledPixmap(XtScreen(w),
                                            w->core.border_pixel,
                                            w->core.background_pixel,
                                            w->core.depth);
            XSetWindowBorderPixmap(XtDisplay(w), XtWindow(w),
                                   ((SimpleWidget)w)->simple.insensitive_border);
        }
    }
    return (False);
}
/*****************************************/
void XawInitializeWidgetSet(void)
{
    static Boolean firsttime = True;
    if (firsttime)
    {
        firsttime = False;
        XtInitializeWidgetClass(vendorShellWidgetClass);
    }
}
/*****************************************/
static void
usr_callback(Widget w, XtPointer client_data, XtPointer call_data)
{
    static int num = 0;
    int pos;
    int sock;
    Display *dpy;
    Screen  *screen;
    Window   win;
    GC gc;
    XTextItem xtext;
    static int x, y;
    int blackColor, whiteColor;
    char strBuf[64];
    dpy = XtDisplay(w);
    screen = XtScreen(w);
    win = XtWindow(w);
    blackColor = BlackPixel(dpy, DefaultScreen(dpy));
    whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
    gc = XCreateGC(dpy, win, 0, NULL);
    XSetForeground(dpy, gc, blackColor);
    //XClearWindow(dpy, win);
    /*
    for(pos = 0; pos  8 */
    x = XtWidth(w) / 2;
    y = XtHeight(w) / 2;
    XDrawText(dpy, win, gc, x, y, &xtext, 1);
    sock = *(int *)call_data; // not client_data
    //printf("usr_callback 0x%x: data = %d\n", call_data, sock);
    sprintf(strBuf, "%s %d", (char *)client_data, num);
    if (send(sock, (const void *)strBuf, strlen(strBuf)+1, 0) == -1)
    {
        perror("send");
    }
    ++num;
    return;
}
/*****************************************/
static void
usr_hndlr(Widget w, XtPointer client_data, XEvent *event, Boolean *bContinue)
{
    XtCallCallbacks(w, XtNcallback, client_data);
    return;
}
/*****************************************/
/* Hard-code a portnumber and name of the server machine, for when wecreate
* our own socket to ourselves running as a server. */
#define PORT_NUM    3141
/* #define SERVER_NAME    "hgwells.omnia.de" */
#define SERVER_NAME    "localhost"
/* Define this so that the MainLoop implementation uses select(). */
#define USE_SELECT
void server_main(void);
void client_main(int argc, char **argv);
void process_client(int sock);
//void pushed(Widget w, XtPointer client, XtPointer call);
void read_sock(int sock);
void admin_server_input(XtPointer client, int *fd, XtInputId *id);
void MainLoop(XtAppContext app_cntxt, Widget toplevel, int sock);
void process_events(XtAppContext app_cntxt);
/***************************************************************************
**
* FUNCTION:    main * DESCRIPTION:
****************************************************************************
*/
int main(int argc, char *argv[])
{
    if (argc == 1)
        server_main();
    else
        client_main(argc, argv);
    return 0;
}
/***************************************************************************
**
* FUNCTION:    server_main
* DESCRIPTION:    Create a TCP/IP socket, waiting for incomingconnections.
****************************************************************************
*/
void server_main(void)
{
    int       rc, len, sock, newsock;
    struct sockaddr_in    addr;
    struct hostent    *host;
    (void)fprintf(stderr, "Server Listener on %s...\n", SERVER_NAME);
    host = gethostbyname(SERVER_NAME);
    if (host == (struct hostent *)NULL)
    {
        perror("gethostbyname");
        exit(1);
    }
    (void)fprintf(stderr, "creating socket\n");
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1)
    {
        perror("socket");
        exit(1);
    }
    (void)memset((void *)&addr, '\0', sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port   = htons(PORT_NUM);
    (void)memcpy((void *)&addr.sin_addr, (void *)host->h_addr,
                 (size_t)host->h_length);
    (void)fprintf(stderr, "binding...\n");
    rc = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
    if (rc == -1)
    {
        perror("bind");
        exit(1);
    }
    (void)fprintf(stderr, "listening...\n");
    rc = listen(sock, 10);
    if (rc == -1)
    {
        perror("listen");
        exit(1);
    }
    for ( ; ; )
    {
        len = sizeof(addr);
        (void)fprintf(stderr, "accepting...\n");
        newsock = accept(sock, (struct sockaddr *)&addr, (unsigned int
                         *)&len);
        (void)fprintf(stderr, "new socket = %d...\n", newsock);
        process_client(newsock);
    }
    return;
}
/***************************************************************************
**
* FUNCTION:    process_client
* DESCRIPTION:    Read messages from the socket, sending back a simpleack.
****************************************************************************
*/
void process_client(int sock)
{
    int        rc;
    char    buf[BUFSIZ];
    for ( ; ; )
    {
        rc = recv(sock, buf, sizeof(buf), 0);
        if (rc == -1)
            perror("recv");
        buf[rc] = '\0';
        (void)fprintf(stderr, "Recving '%s'\n", buf);
        if (strcmp(buf, "bye") == 0)
            break;
        (void)fprintf(stderr, "Sending '+OK'\n", buf);
        if (send(sock, (const void *)"+OK", 4, 0) == -1)
            perror("send");
    }
    return;
}
/***************************************************************************
**
* FUNCTION:    client_main
* DESCRIPTION:    Create a socket, connecting on a hardcoded portnumber to
*        a hardcoded server, and then create a simple Motif screen.
****************************************************************************
*/
void client_main(int argc, char **argv)
{
    int       rc, len, sock, newsock;
    struct sockaddr_in    addr;
    struct hostent    *host;
    Display     *dpy;
    GC gc;
    Window      win;
    XEvent      xevt;
    Widget      toplevel, w;
    XtInputId        input_id;
    XtAppContext    app_cntxt;
    Arg  args[10];
    Font fid;
    XTextItem xtext;
    int ac;
    int blackColor, whiteColor;
    int posx, posy, width, height;
    char strBuf[32];
    (void)fprintf(stderr, "Client to %s...\n", SERVER_NAME);
    host = gethostbyname(SERVER_NAME);
    if (host == (struct hostent*)NULL)
    {
        perror("gethostbyname");
        exit(1);
    }
    (void)fprintf(stderr, "creating socket...\n");
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1)
    {
        perror("socket");
        exit(1);
    }
    (void)memset((void *)&addr, '\0', sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port   = htons(PORT_NUM);
    (void)memcpy((void *)&addr.sin_addr, (void *)host->h_addr,
                 (size_t)host->h_length);
    (void)fprintf(stderr, "connecting...\n");
    rc = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
    if (rc == -1)
    {
        perror("connect");
        exit(1);
    }
    toplevel = XtVaAppInitialize(
                   &app_cntxt,       /* Application context */
                   "XHello",         /* Application class */
                   NULL, 0,            /* command line option list */
                   &argc, argv,        /* command line args */
                   NULL,               /* for missing app-defaults file */
                   NULL);              /* terminate varargs list */
    ac = 0;
    XtSetArg(args[ac], XtNheight, 50);
    ac++;
    XtSetArg(args[ac], XtNwidth, 100);
    ac++;
    XtSetValues(toplevel, args, ac);
    w = XtVaCreateManagedWidget(
                "hello",   /* arbitrary widget name */
                simpleWidgetClass, /* widget class from Label.h */
                toplevel,   /* parent widget */
                NULL);              /* terminate varargs list */
    XtAddCallback(w, XtNcallback, usr_callback, "Test");
    XtAddEventHandler(w, ButtonPressMask, FALSE, usr_hndlr, &sock);
    /*
     *  Create windows for widgets and map them.
     */
    XtRealizeWidget(toplevel);
    /*
     *  Loop for events.
     */
    /* This is the code that should work - it works fine on all variants of
     * UNIX - solaris, OSF/1, HP-UX, Linux, AIX, ULTRIX etc
     */
    input_id = XtAppAddInput(app_cntxt, sock,
                (XtPointer)(XtInputReadMask|XtInputExceptMask),
                (XtInputCallbackProc)admin_server_input,
                NULL);
    XtAppMainLoop(app_cntxt);
    /* The second parameter of XtAppAddInput pecifies the source file
     * descriptor on a UNIX-based system
     * or other operating system dependent device specification.
     * If above code can`t work, following code can be a solution.
     */
    //MainLoop(app_cntxt, toplevel, sock);
    return;
}
/***************************************************************************
**
* FUNCTION:    MainLoop
* DESCRIPTION:    Implementation of an X mainloop function.
*        It attempts to select on the server socket and the X socket,
*        processing whichever has input.
****************************************************************************
*/
void MainLoop(XtAppContext app_cntxt, Widget toplevel, int sock)
{
    int            xfd, rc;
    fd_set        readfds;
    Display     *dsply;
    dsply = XtDisplay(toplevel);
    xfd = ConnectionNumber(dsply);
#ifdef USE_SELECT
    for (;;)
    {
        /* In desperation, force all buffered X events out. */
        XFlush(dsply);
        fsync(xfd);
        XSync(dsply, False);
        /* Now try select'ing for any input on the client/server socket and
         * on the connection to the X-server.     */
        FD_ZERO(&readfds);
        FD_SET (sock, &readfds);
        FD_SET (xfd,  &readfds);
        (void)fprintf(stderr, "selecting on %d and %d\n", sock, xfd);
        rc = select(FD_SETSIZE, &readfds, NULL, NULL, (struct timeval *)NULL);
        if (rc == -1)
        {
            perror("select");
            exit(1);
        }
        /* If there's something on the X-socket, process it. */
        if (FD_ISSET(xfd, &readfds) != 0)
        {
            process_events(app_cntxt);
            continue;
        }
        /* If there's something on the from our socket, process it. */
        if (FD_ISSET(sock, &readfds) != 0)
        {
            read_sock(sock);
            continue;
        }
    }
#else    /* Don't worry about the socket - just process X-requests. */
    for (;;)
    {
        process_events(app_cntxt);
    }
#endif /* USE_SELECT */
    return;
}
/***************************************************************************
**
* FUNCTION:    process_events
* DESCRIPTION:    Loop, getting all events and dispatching them.
*        This uses AppPending, as a way of seeing if there is any
*        AlternateInput events coming in...
****************************************************************************
*/
void process_events(XtAppContext app_cntxt)
{
    XtInputMask input_mask;
    XEvent        event;
    while ((input_mask = XtAppPending(app_cntxt)) != 0)
    {
        if (input_mask == XtIMXEvent)
            (void)fprintf(stderr, "XEvent\n");
        if (input_mask == XtIMAlternateInput)
            (void)fprintf(stderr, "AlternateInput\n");
        XtAppNextEvent(app_cntxt, &event);
        XtDispatchEvent(&event);
    }
    return;
}
/***************************************************************************
**
* FUNCTION:    admin_server_input
* DESCRIPTION:    XtInput callback - not used here unless XtAddInput is used.
****************************************************************************
*/
void admin_server_input(XtPointer client, int *fd, XtInputId *id)
{
    (void)fprintf(stderr, "Read from socket ...\n");
    read_sock(*fd);
    return;
}
/***************************************************************************
**
* FUNCTION:    read_sock
* DESCRIPTION:    Receive a message from the server
****************************************************************************
*/
void read_sock(int sock)
{
    int        rc;
    char    buf[BUFSIZ];
    rc = recv(sock, buf, sizeof(buf), 0);
    if (rc == -1)
        perror("recv");
    buf[rc] = '\0';
    (void)fprintf(stderr, "Recving '%s'\n", buf);
    return;
}
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/3771/showart_1891901.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP