## 9.1 An Example

In this section, we implement a simple client/server pair to demonstrate the use of message passing. The server will answer requests about creating pixmaps from image files. For demonstration purpose, it displays the messages together with the pixmaps in a text window. The client consists of a directory list tree and a label. When the user double click on a file item in the list tree, it broadcasts a message out asking the server to create a pixmap from the file.

### The Server

    #include "EZ.h"

    Atom  PIXMAP_ATOM;

    void msgHandler(EZ_Message *msg, void *data)
    {
      /*
       * the default message handler for the server:
       * if message type is PXIMAP_ATOM, try to create
       * a pixmap from the file supplied, and send the
       * pixmap id and shape id back.
       */
      EZ_TextProperty         *tmpTp;
      char                    buf[1024], *ptr;
      EZ_Widget               *text = (EZ_Widget *)data;

      if(msg->messageType == PIXMAP_ATOM && msg->messageLength > 0)
        {
          char   reply[1024];
          Pixmap pixmap, shape;
          int    w, h;
          EZ_Pixmap *pptr;
          /* print the message */
          sprintf(buf, "\n+++From [%lx], Type=[%lx], Len=[%d] Id=[%d]+++\n   %s\n",
                  msg->sender, msg->messageType, msg->messageLength,
                  msg->replyId,  msg->message);
          EZ_TextInsertString(text, buf);

          /* allocate the pixmap */
          if((pptr = EZ_CreateLabelPixmapFromXpmFile(msg->message)) == NULL)
            pptr = EZ_CreateLabelPixmapFromImageFile(msg->message);
          if(pptr)
            {
              EZ_GetLabelPixmapInfo(pptr, &pixmap, &shape, &w, &h);
              /* reply */
              sprintf(reply, "%d %d %lx %lx", w, h, pixmap, shape);
              EZ_ReplyMessage(msg, reply, strlen(reply));

              /* display the pixmap */
              sprintf(buf, "   [pixmap=%lx shape=%lx]: replied\n", pixmap,shape);
              EZ_TextInsertString(text, buf);
              tmpTp =  EZ_GetTextProperty(EZ_LABEL_PIXMAP, pptr, NULL);
              EZ_TextInsertStringWithProperty(text, buf, tmpTp);
            }
          else
            {
              sprintf(buf, "  Couldn't create pixmap\n", pixmap,shape);
              EZ_TextInsertString(text, buf);
            }
        }
      else
        {
          sprintf(buf, "\n---From [%lx], Type=[%lx], Len=[%d] Id=[%d]----\n   %s\n",
                  msg->sender, msg->messageType, msg->messageLength,
                  msg->replyId,  msg->message);
          EZ_TextInsertString(text, buf);
        }
    }

    main(int ac, char **av)
    {
      EZ_Widget *frame, *text;

      EZ_Initialize(ac, av, 0);
      PIXMAP_ATOM =  EZ_GetAtom("PixmapTestAtom");

      frame  = EZ_CreateWidgetXrm(EZ_WIDGET_FRAME,    NULL,
                                  "server",           "Server",
                                  EZ_FILL_MODE,       EZ_FILL_BOTH,
                                  EZ_LABEL_STRING,    "Pixmap server",
                                  EZ_IPADX,           4,
                                  EZ_SIZE,            400, 400,
                                  0);
      text =  EZ_CreateWidgetXrm(EZ_WIDGET_TEXT,      frame,
                                 "text",              "Text",
                                  0);
      EZ_SetDefaultMessageHandler(msgHandler, text);

      EZ_DisplayWidget(frame);
      EZ_EventMainLoop();
    }

### The Client

    #include "EZ.h"

    Atom  PIXMAP_ATOM;

    void msgHandler(EZ_Message *msg, void *data)
    {
      EZ_Widget        *label = (EZ_Widget *)data;
      if(msg->messageLength > 0)
        {
          Pixmap pixmap, shape;
          int    w, h;
          if(sscanf(msg->message, "%d %d %lx %lx", &w, &h, &pixmap, &shape) == 4 && w > 0)
            {
              EZ_Pixmap *ptr = EZ_CreateLabelPixmapFromXPixmap(pixmap, shape, 0, 0, w,h, 1);
              if(ptr) EZ_ConfigureWidget((EZ_Widget *)data, EZ_LABEL_PIXMAP, ptr, 0);
              /* delete this handler */
              EZ_DeleteMessageHandler(msg->messageType, msg->messageId, data, msgHandler);
            }
        }
    }

    static void timeoutCb(void *notused, void *data)
    {
      printf("message handler timeout\n");
    }

    void ltreeCB(EZ_Widget *tree, void *data)
    {
      EZ_TreeNode  *node = EZ_GetListTreeWidgetSelection(tree);
      EZ_Item      *item;
      static       int  msgId = 1;

      if(node && (item = EZ_TreeNodeGetItem(node)))
        {
          char *path = EZ_GetDirTreeNodeFullPath(node);
          /* add a message handler */
          EZ_RegisterMessageHandler(PIXMAP_ATOM, /* type of msg it handles */
                                    msgId+1,     /* the msgId it handles   */
                                    data,        /* client data to be passed to handler */
                                    msgHandler,  /* the handler            */
                                    1,           /* expire in one second   */
                                    timeoutCb,   /* what to do when handler expires */
                                    data         /* client data to be passed to timeoutCb */
                                    );
          /* broadcast a message to find a server */
          EZ_BroadcastMessage(PIXMAP_ATOM,  /* msg type */
                              path,         /* the message */
                              strlen(path), /* length of message */
                              msgId,        /* this message Id   */
                              msgId+1       /* ask recipient to reply using this id */
                              );
          msgId += 2;
        }
    }

    main(int ac, char **av)
    {
      EZ_Widget *frame, *ltree, *label, *phandle;
      EZ_TreeNode *root;

      EZ_Initialize(ac, av, 0);
      PIXMAP_ATOM =  EZ_GetAtom("PixmapTestAtom");

      frame  = EZ_CreateWidgetXrm(EZ_WIDGET_FRAME,    NULL,
                                  "server",           "Server",
                                  EZ_FILL_MODE,       EZ_FILL_BOTH,
                                  EZ_LABEL_STRING,    "Pixmap client",
                                  EZ_IPADX,           4,
                                  EZ_SIZE,            800, 400,
                                  0);
      ltree =  EZ_CreateWidgetXrm(EZ_WIDGET_TREE,      frame,
                                  "tree",              "Tree",
                                  EZ_WIDTH,            300,
                                  0);
      phandle = EZ_CreateWidget(EZ_WIDGET_PANE_HANDLE, frame,
                                0);

      label = EZ_CreateWidgetXrm(EZ_WIDGET_LABEL,      frame,
                                 "label",              "Label",
                                 0);
      EZ_AddWidgetCallBack(ltree, EZ_CALLBACK, ltreeCB, label, 0);

      EZ_GlobHiddenFiles(True);
      root = EZ_CreateDirTree(NULL, "./*", NULL, 0);  /* */
      EZ_SetListTreeWidgetTree(ltree, root);

      EZ_DisplayWidget(frame);
      EZ_EventMainLoop();
    }

HTML Documentation Maintainance:`Arturo Espinosa <arturo@nuclecu.unam.mx>`