Chinaunix首页 | 论坛 | 博客
  • 博客访问: 277910
  • 博文数量: 65
  • 博客积分: 3091
  • 博客等级: 中校
  • 技术积分: 705
  • 用 户 组: 普通用户
  • 注册时间: 2005-01-25 09:44
文章存档

2013年(2)

2012年(11)

2011年(12)

2010年(13)

2009年(15)

2008年(12)

分类: LINUX

2009-04-07 11:15:18

  在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) < (b) ? (a) : (b))
#define XawAbs(a)    ((a) < 0 ? -(a) : (a))

#define XawStackAlloc(size, stk_buffer)  \
((size) <= sizeof(stk_buffer)   \
 ? (XtPointer)(stk_buffer)   \
 : XtMalloc((unsigned)(size)))

#define XawStackFree(pointer, stk_buffer) \
do {      \
  if ((pointer) != (XtPointer)(stk_buffer)) \
    XtFree((char *)pointer);   \
} while (0)

#ifndef XtX
#define XtX(w)            (((RectObj)w)->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 < 400; pos += 8)
    {
        XDrawLine(dpy, win, gc, pos, 0, pos, 400);
        XDrawLine(dpy, win, gc, 0, pos, 400, pos);
    }
    */

    *strBuf = '\0';
    sprintf(strBuf, "count: %d", num);
    xtext.chars = strBuf;
    xtext.nchars = strlen(strBuf);
    xtext.delta = 0;
    xtext.font = None;

    XClearArea(dpy, win, x, y-12, 32*8, 16, False); /* y-8 <-> 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;
}

阅读(1227) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~