Back to index

im-sdk  12.3.91
xaux_object_common.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <limits.h>
00003 #include <unistd.h>
00004 #include <wait.h>
00005 
00006 #include <X11/Xlib.h>
00007 #include <X11/Xatom.h>
00008 
00009 #include "config.h"
00010 #include "xaux_object.h"
00011 
00012 /* workaround for "stored reference to aux_t is corrupred" problem */
00013 static void (*aux_setvalue)(aux_t *, const unsigned char *, int);
00014 static unsigned char *(*compose)(const aux_data_t *, int *);
00015 static aux_t aux_tmp;
00016 
00017 static Bool xaux_object_event_filter(Display *display, Window window, XEvent *event, XPointer pointer);
00018 static Bool xaux_object_get_extwin(xaux_class_t *xc, Display *display);
00019 static Bool xaux_object_launch_ext(xaux_class_t *xc, Display *display);
00020 
00021 static Bool xaux_object_init_class(Display *display, Window window, xaux_class_t *xc);
00022 void xaux_object_print(xaux_object_t *xaux_object);
00023 
00024 extern xaux_class_t xaux_classes[];
00025 
00026 xaux_object_t *xaux_object_new()
00027 {
00028        xaux_object_t *xaux_object;
00029 
00030        xaux_object = (xaux_object_t *)calloc(1, sizeof(xaux_object_t));
00031        if (xaux_object == NULL)
00032               return NULL;
00033 
00034        return xaux_object;
00035 }
00036 
00037 Bool xaux_object_init(xaux_object_t *xaux_object, aux_t *aux, char *classname, xaux_class_t *xaux_classes)
00038 {
00039        Display *display;
00040        xaux_class_t *p;
00041 
00042        if (!aux)
00043               return False;
00044 
00045        if (!classname || !*classname)
00046               return False;
00047 
00048        if (!xaux_classes)
00049               return False;
00050 
00051        /* workaround for "stored reference to aux_t is corrupred" problem */
00052        aux_tmp.ic = aux->ic;
00053        aux_setvalue = aux->service->aux_setvalue;
00054        compose = aux->service->compose;
00055 
00056        display = aux->service->display(aux);
00057 
00058        xaux_object->display = display;
00059 
00060        xaux_object->classname = classname;
00061        xaux_object->atom_classname = XInternAtom(display, classname, False);
00062 
00063        xaux_object->window = XCreateSimpleWindow(display, RootWindow(display, 0),
00064                    0, 0, 1, 1, 0, 0, 0);
00065 
00066        if (xaux_object->window == None) {
00067               DEBUG_printf("xaux_object_new: creating window failed.\n");
00068               return False;
00069        }
00070 
00071        XSetSelectionOwner(display,
00072               xaux_object->atom_classname, xaux_object->window, CurrentTime);
00073 
00074         XSelectInput(display, xaux_object->window, PropertyChangeMask);
00075 
00076         aux->service->register_X_filter(display, xaux_object->window,
00077               ClientMessage, ClientMessage,
00078               xaux_object_event_filter, NULL);
00079 
00080        xaux_object->xaux_classes = xaux_classes;
00081        p = xaux_classes;
00082        while(p->classname != NULL) {
00083               xaux_object_init_class(display, xaux_object->window, p);
00084               p++;
00085        }
00086 
00087        xaux_object_print(xaux_object);
00088 
00089        return (True);
00090 }
00091 
00092 void xaux_object_destroy(xaux_object_t *xaux_object)
00093 {
00094        if (xaux_object == NULL ||
00095            xaux_object->display ||
00096            xaux_object->window == None)
00097               return;
00098 
00099        XDestroyWindow(xaux_object->display, xaux_object->window);
00100 
00101        return;
00102 }
00103 
00104 void xaux_object_print(xaux_object_t *xaux_object)
00105 {
00106 #ifdef DEBUG
00107        xaux_class_t *p;
00108 
00109        if (xaux_object == NULL ||
00110            xaux_object->display ||
00111            xaux_object->window == None)
00112               return;
00113 
00114        printf("xaux_object: %p\n", xaux_object);
00115        printf("  classname: %s\n", xaux_object->classname);
00116        printf("  window: %d\n", xaux_object->window);
00117 
00118        p = xaux_object->xaux_classes;
00119        while(p->classname != NULL) {
00120               printf(" class: %s\n", p->classname);
00121               p++;
00122        }
00123 #endif
00124        return;
00125 }
00126 
00127 /************************************************************
00128     functions to process xaux_class_t and aux messages
00129 ************************************************************/
00130 static Bool xaux_object_init_class(Display *display, Window window, xaux_class_t *xc)
00131 {
00132        char          buf[XAUX_MAXCLASSNAMELEN + XAUX_MAXSUFFIXLEN + 1];
00133        int           i;
00134 
00135        if (xc == NULL)
00136               return False;
00137 
00138        DEBUG_printf("xaux_object_init_class ===\n");
00139        if (access(xc->extexec, X_OK) != 0) {
00140               DEBUG_printf("executable \"%s\" not found\n", xc->extexec);
00141               return False;
00142        }
00143 
00144        if (xc->classname == NULL) {
00145               return False;
00146        }
00147 
00148        xc->atom_classname = XInternAtom(display, xc->classname, False);
00149 
00150        sprintf(buf, "%s%s", xc->classname, XAUX_SOWIN_SUFFIX);
00151        xc->atom_sowin = XInternAtom(display, buf, False);
00152 
00153        sprintf(buf, "%s%s", xc->classname, XAUX_EXTWIN_SUFFIX);
00154        xc->atom_extwin = XInternAtom(display, buf, False);
00155 
00156        for (i = 0; i < XAUX_SX_NATOMS; i++) {
00157               sprintf(buf, "%s%s_%d",
00158                      xc->classname, XAUX_SX_SUFFIX, i);
00159               xc->atom_sx[i] = XInternAtom(display, buf, False);
00160        }
00161        xc->atom_sx_idx = 1;
00162 
00163        for (i = 0; i < XAUX_XS_NATOMS; i++) {
00164               sprintf(buf, "%s%s_%d",
00165                      xc->classname, XAUX_XS_SUFFIX, i);
00166               xc->atom_xs[i] = XInternAtom(display, buf, False);
00167        }
00168        xc->atom_xs_idx = 1;
00169 
00170        xc->extwin = (Window)0;
00171 
00172        if (xaux_object_launch_ext(xc, display) == False)
00173               return (False);
00174 
00175        i = 0;
00176        while (xaux_object_get_extwin(xc, display) == False) {
00177               DEBUG_printf("classname: %s, retry number: %d, sleep: %d um\n", xc->classname, i, XAUX_RETRYINT_EXTWIN);
00178               if (i++ > XAUX_MAXRETRY_EXTWIN)
00179                      break;
00180               usleep(XAUX_RETRYINT_EXTWIN);
00181        }
00182 
00183        return True;
00184 }
00185 
00186 char *xaux_object_get_classname_from_utfname(CARD16 *utf_name, int utf_name_len)
00187 {
00188        int i;
00189        char *classname = NULL;
00190 
00191        if (!utf_name || !*utf_name)
00192               return (NULL);
00193 
00194        classname = (char *)calloc(utf_name_len + 1, sizeof(char));
00195        if (classname == NULL) return (NULL);
00196 
00197        for (i = 0; i < utf_name_len; i++) {
00198               classname[i] = utf_name[i] & 0xff;
00199        }
00200 
00201        return (classname);
00202 }
00203 
00204 static xaux_class_t *xaux_object_get_class_from_name(xaux_object_t *xaux_object, char *classname)
00205 {
00206        xaux_class_t *aux_class;
00207        Display *display;
00208        Window owner;
00209 
00210        Atom atom_classname = (Atom)None;
00211 
00212        if (xaux_object == NULL || classname == NULL)
00213               return (NULL);
00214 
00215        display = xaux_object->display;
00216        atom_classname = XInternAtom(display, classname, True);
00217 
00218        /* check whether the classname is registered by the owner */
00219        DEBUG_printf("classname: %s, atom_classname: %p\n", classname, atom_classname);
00220        if (atom_classname == (Atom)None)
00221               return (NULL);
00222 
00223        /* check whether the classname is for the binary aux module */
00224        for (aux_class = xaux_object->xaux_classes; aux_class->classname; aux_class++) {
00225               if (!strcasecmp(classname, aux_class->classname))
00226                      return (aux_class);
00227        }
00228 
00229        /* check whether the classname is launched by an aux manager */
00230        owner = XGetSelectionOwner(display, atom_classname);
00231        if (owner == (Window)None)
00232               return (NULL);
00233 
00234        for (aux_class = xaux_object->xaux_classes; aux_class->classname; aux_class++) {
00235               if (aux_class->extwin == owner)
00236                      return (aux_class);
00237        }
00238 
00239        return (NULL);
00240 }
00241 
00242 static Bool xaux_object_get_extwin(xaux_class_t *xc, Display *display)
00243 {
00244        if (xc->atom_extwin == (Atom)None)
00245               return False;
00246 
00247        xc->extwin = XGetSelectionOwner(display, xc->atom_extwin);
00248        if (xc->extwin == None) {
00249               return False;
00250        }
00251        return True;
00252 }
00253 
00254 static void xaux_object_signal_child_handler(int sig, siginfo_t * info, void * ucontext)
00255 {
00256     pid_t   pid;
00257     int     status;
00258 
00259     while ((pid = waitpid(info->si_pid, &status, WNOHANG|WUNTRACED)) > 0) {
00260         printf("pid %d: die\n", pid);
00261     }
00262 }
00263 
00264 static void xaux_object_register_signal_child_handler()
00265 {
00266     struct sigaction act;
00267 
00268     act.sa_handler = NULL;
00269     act.sa_sigaction = xaux_object_signal_child_handler;
00270     sigfillset(&act.sa_mask);
00271     act.sa_flags = SA_SIGINFO;
00272 
00273     sigaction(SIGCHLD, &act, NULL);
00274 }
00275 
00276 static Bool xaux_object_launch_ext(xaux_class_t *xc, Display *display)
00277 {
00278        pid_t         pid;
00279 
00280        if (xc->atom_extwin == (Atom)None)
00281               return False;
00282 
00283        if (xaux_object_get_extwin(xc, display) == True) {
00284               return True;
00285        }
00286 
00287        xaux_object_register_signal_child_handler();
00288 
00289 #ifdef sun
00290        pid = fork1();
00291 #else
00292        pid = fork();
00293 #endif
00294 
00295        if (pid == (pid_t)(-1)) { /* fork failed */
00296               return False;
00297        } else if (0 == pid) { /* child */
00298 #ifdef DEBUG_XAUX
00299               chdir("/tmp");
00300 #endif
00301               execl(xc->extexec, xc->classname, NULL);
00302               _exit(1);
00303        }
00304        
00305        /* parent */
00306        return True;
00307 }
00308 
00309 static char *xaux_object_compose_aux_data(aux_t *aux, xaux_class_t *xc, aux_data_t *aux_data, int type, int *string_len)
00310 {
00311        XPoint        point;
00312        char *        string_buf;
00313        size_t        i;
00314        int           *ip;
00315        char          *sp;
00316        size_t        total;
00317        size_t        len;
00318 
00319        /* estimate enough size for string_buf */
00320 
00321        /* size for header */
00322        total = SX_SIZE_PROP_HEADER_DRAW;
00323 
00324        /* add size for integer_values */
00325        total += (sizeof (CARD32) * aux_data->integer_count);
00326 
00327        /* add size for string_values */
00328        if (aux_data->string_count > 0) {
00329               for (i = 0; i < aux_data->string_count; i++) {
00330                      /* number of bytes */
00331                      len = aux_data->string_list[i].length;
00332 
00333                      /* consider padding */
00334                      total +=
00335                      ((sizeof (CARD16) + len + 3) / 4) * 4;
00336               }
00337        }
00338 
00339        if ((string_buf = (char *)malloc(total)) == NULL) {
00340               return NULL;
00341        }
00342 
00343        SX_PROP_ATOM_AUX_NAME(string_buf) = xc->atom_classname;
00344        SX_PROP_TYPE(string_buf) = type;
00345        SX_PROP_INDEX(string_buf) = xc->index;
00346        SX_PROP_IMID(string_buf) = aux_data->im;
00347        SX_PROP_ICID(string_buf) = aux_data->ic;
00348        SX_PROP_SOWIN(string_buf) = xc->sowin;
00349 
00350        SX_PROP_CLIENTWIN(string_buf) = aux->service->client_window(aux);
00351 
00352        aux->service->point(aux, &point);
00353        SX_PROP_POSX(string_buf) = point.x;
00354        SX_PROP_POSY(string_buf) = point.y;
00355 
00356        SX_PROP_FOCUSWIN(string_buf) = aux->service->window(aux);
00357 
00358        SX_PROP_INT_COUNT(string_buf) = aux_data->integer_count;
00359        SX_PROP_STR_COUNT(string_buf) = aux_data->string_count;
00360 
00361        ip = (int *)SX_PROP_INT_LIST(string_buf);
00362 
00363        if (aux_data->integer_count > 0) {
00364               for (i = 0; i < aux_data->integer_count; i++) {
00365                      *ip++ = aux_data->integer_list[i];
00366               }
00367        }
00368 
00369        sp = (char *)SX_PROP_STR_LIST(string_buf);
00370 
00371        if (aux_data->string_count > 0) {
00372               char *        ob;
00373               size_t        obl;
00374 
00375               ob = sp;
00376 
00377               for (i = 0; i < aux_data->string_count; i++) {
00378                      int           pn;
00379                      unsigned char *p;
00380                      size_t        j;
00381 
00382                      len = aux_data->string_list[i].length;
00383                      p = aux_data->string_list[i].ptr;
00384 
00385                      *(CARD16 *)ob = len;
00386                      ob += sizeof (CARD16);
00387 
00388                      for (j = 0; j < len; j++) {
00389                             *ob++ = *p++;
00390                      }
00391                             
00392                      pn = padding[(sizeof (CARD16) + len) % 4];
00393 
00394                      /* padding */
00395                      for (j = 0; j < pn; j++) {
00396                             *ob++ = 0U;
00397                      }
00398                      sp = ob;
00399               }
00400        }
00401 
00402        *string_len = sp - &(string_buf[0]);
00403        return (string_buf);
00404 }
00405 
00406 aux_data_t *xaux_object_decompose_from_string(xaux_class_t *xc, unsigned char *string_buf)
00407 {
00408        aux_data_t *  aux_data;
00409        int           i;
00410 
00411        aux_data = (aux_data_t *)calloc(1, sizeof(aux_data_t));
00412        if (aux_data == NULL)
00413               return (NULL);
00414 
00415        /* header */
00416        aux_data->type = AUX_DATA_SETVALUE;
00417        aux_data->im = XS_PROP_IMID(string_buf);
00418        aux_data->ic = XS_PROP_ICID(string_buf);
00419        aux_data->aux_index = xc->index;
00420        aux_data->aux_name = (unsigned char *)xc->utfname;
00421        aux_data->aux_name_length = strlen(xc->classname)*sizeof(CARD16);
00422 
00423        /* int values */
00424        aux_data->integer_count = XS_PROP_INT_COUNT(string_buf);
00425 
00426        if (aux_data->integer_count > 0) {
00427               aux_data->integer_list = (int *)XS_PROP_INT_LIST(string_buf);
00428        } else {
00429               aux_data->integer_list = NULL;
00430        }
00431 
00432        /* string values */
00433        aux_data->string_count = XS_PROP_STR_COUNT(string_buf);
00434        if (aux_data->string_count > 0) {
00435               unsigned char * prop_str = XS_PROP_STR_LIST(string_buf);
00436 
00437               if ((aux_data->string_list = (aux_string_t *)malloc(sizeof (aux_string_t) * 
00438                                           aux_data->string_count)) == NULL) {
00439                      free ((char *)aux_data);
00440                      return NULL;
00441               }
00442 
00443               for (i = 0; i < aux_data->string_count; i++) {
00444                      int    j;
00445                      int    pn;
00446                      size_t len;
00447 
00448                      len = *((CARD16 *)(prop_str));
00449                      prop_str += sizeof (CARD16);
00450                      aux_data->string_list[i].ptr = prop_str;
00451                      aux_data->string_list[i].length = len;
00452                      prop_str += len;
00453                      pn = padding[(sizeof(CARD16) + len) % 4];
00454                      for (j = 0; j < pn; j++) {
00455                             *prop_str++ = 0U;
00456                      }
00457               }
00458        } else {
00459               aux_data->string_list = NULL;
00460        }
00461 
00462        aux_data->string_ptr = NULL;
00463 
00464        return aux_data;
00465 }
00466 
00467 /************************************************************
00468     Send messages to aux modules
00469 ************************************************************/
00470 Bool xaux_object_send_message(
00471        aux_t *              aux,
00472        xaux_class_t *       xc,
00473        int           im_id,
00474        int           ic_id,
00475        aux_data_type_t      type,
00476        Atom          atom_client,
00477        Atom          atom_data)
00478 {
00479        Display *            display;
00480        XClientMessageEvent  event;
00481 
00482        display = aux->service->display(aux);
00483 
00484        if (xaux_object_get_extwin(xc, display) == False)
00485               return False;
00486 
00487        event.type = ClientMessage;
00488        event.serial = 0;
00489        event.send_event = True;
00490        event.display = display;
00491        event.window = xc->extwin;
00492        event.message_type = atom_client;
00493        event.format = 32;
00494 
00495        event.data.l[0] = xc->atom_classname;
00496        event.data.l[1] = ((CARD32)im_id << 16) | ((CARD32)ic_id & 0xffff);
00497        event.data.l[2] = xc->index;
00498        event.data.l[3] = type; /* CREATE, DONE, ... */
00499        event.data.l[4] = atom_data;
00500 
00501        XSendEvent(display, xc->extwin, True, 0, (XEvent *)(&event));
00502 
00503        /* needed in en_US.UTF-8 */
00504         XFlush(display);
00505 
00506        return True;
00507 }
00508 
00509 Bool xaux_object_send_property(
00510        aux_t *                     aux,
00511        xaux_class_t *              xc,
00512        const unsigned char *       p,
00513        int                  len,
00514        Atom                 atom_client)
00515 {
00516        Display *     display;
00517        int           i = 1;
00518        Bool          rv;
00519        Window        win;
00520 
00521        display = aux->service->display(aux);
00522 
00523        if (xaux_object_get_extwin(xc, display) == False)
00524               return False;
00525 
00526        win = xc->extwin;
00527 
00528        XChangeProperty(display, win,
00529               xc->atom_sx[xc->atom_sx_idx], XA_STRING,
00530               8, PropModeReplace, (unsigned char *)p, len);
00531 
00532        if (xaux_object_send_message(aux, xc,
00533               aux->service->im_id(aux), aux->service->ic_id(aux),
00534               AUX_DATA_DRAW, atom_client, xc->atom_sx[xc->atom_sx_idx]) == False) {
00535                      return False;
00536        }
00537 
00538        /* XFlush() has been called in xaux_object_send_message() */
00539        
00540        if (++xc->atom_sx_idx == XAUX_SX_NATOMS)
00541               xc->atom_sx_idx = 1;
00542        
00543        return True;
00544 }
00545 
00546 Bool xaux_object_draw_aux_module(xaux_object_t *xaux_object, aux_t *aux, 
00547 char *classname, aux_data_t *aux_data, int type)
00548 {
00549        char *        string_buf;
00550        int           string_len;
00551        Bool          rv = True;
00552        Display *     display;
00553        Atom          atom_client;
00554 
00555        xaux_class_t *       xc;
00556 
00557        DEBUG_printf("aux_tmp: %p, aux_setvalue: %p, compose: %p\n", &aux_tmp, aux_setvalue, compose);
00558 
00559        display = aux->service->display(aux);
00560 
00561        /* make the aux_object as the current focused aux object */
00562        XSetSelectionOwner(display,
00563               xaux_object->atom_classname, xaux_object->window, CurrentTime);
00564 
00565        xc = xaux_object_get_class_from_name(xaux_object, classname);
00566        DEBUG_printf("xaux_object_get_class_from_name, return: xc: %p\n", xc);
00567        if (xc == NULL)
00568               return False;
00569 
00570        if (xaux_object_get_extwin(xc, display) == False)
00571               return False;
00572 
00573        /* workaround for "stored reference to aux_t is corrupred" problem */
00574        aux_tmp.ic = aux->ic;
00575 
00576        atom_client = XInternAtom(display, classname, True);
00577 
00578        if (type == AUX_DATA_START || type == AUX_DATA_DONE) {
00579               rv = xaux_object_send_message(aux, xc, aux_data->im, aux_data->ic, type, atom_client, (Atom)None);
00580        } else if (type == AUX_DATA_DRAW) {
00581               string_buf = (char *)xaux_object_compose_aux_data(aux, xc, aux_data, type, &string_len);
00582 
00583               DEBUG_printf("so_Draw[%s] im:0x%x ic:0x%x in=%d sn=%d\n",
00584                      xc->classname, aux_data->im, aux_data->ic,
00585                      aux_data->integer_count, aux_data->string_count);
00586               DEBUG_printf("total = %d\n", string_len);
00587 
00588               if (string_buf != NULL) {
00589                      rv = xaux_object_send_property(aux, xc,
00590                             (unsigned char *)string_buf, string_len, atom_client);
00591                      free(string_buf);
00592               }
00593        }
00594 
00595        return (rv);
00596 }
00597 
00598 /************************************************************
00599     Receive messages from aux modules
00600 ************************************************************/
00601 static Bool
00602 xaux_object_process_property_update(
00603        Display       *             display,
00604        Window               window,
00605        Atom                 atom,
00606        xaux_class_t *              xc)
00607 {
00608        Atom          actual_type_return;
00609        int           actual_format_return;
00610        unsigned long nitem_return;
00611        unsigned long bytes_after_return;
00612        unsigned char *prop_return;
00613        int           r;
00614        char          *atom_name;
00615        aux_data_t    *aux_data;
00616        int           size;
00617        unsigned char   *p;
00618 
00619        atom_name = XGetAtomName (display, atom);
00620        DEBUG_printf("xaux_object_process_property_update: atom_name: %s\n", atom_name);
00621        DEBUG_printf("aux_tmp: %p, aux_setvalue: %p, compose: %p\n", &aux_tmp, aux_setvalue, compose);
00622 
00623        r = XGetWindowProperty(display, window,
00624                             atom, 0, INT_MAX, False,
00625                             AnyPropertyType, &actual_type_return,
00626                             &actual_format_return, &nitem_return,
00627                             &bytes_after_return, &prop_return);
00628 
00629        if (r != Success) {
00630               return False;
00631        }
00632 
00633        aux_data = xaux_object_decompose_from_string(xc, prop_return);
00634        if (aux_data == NULL) {
00635               XFree(prop_return);
00636               return False;
00637        }
00638 
00639        /* compose and send message to engine */
00640 
00641        /* workaround for "stored reference to aux_t is corrupred" problem */
00642        if ((p = /*ic->aux->service->*/compose(aux_data, &size)) == NULL) {
00643               free(aux_data->string_list);
00644               free(aux_data);
00645               XFree(prop_return);
00646               return False;
00647        }
00648 
00649        DEBUG_printf("so_SetValue[%s] im:0x%x ic:0x%x in=%d sn=%d\n",
00650                      xc->classname, aux_data->im, aux_data->ic,
00651                      aux_data->integer_count, aux_data->string_count);
00652 
00653        /* workaround for "stored reference to aux_t is corrupred" problem */
00654        /*ic->aux->service->*/aux_setvalue(/*ic->aux*/&aux_tmp, p, size);
00655 
00656        free(p);
00657        free(aux_data->string_list);
00658        free(aux_data);
00659 
00660        XFree(prop_return);
00661 
00662        return True;
00663 }
00664 
00665 static Bool xaux_object_process_client_message(Display *display, Window window, XClientMessageEvent *event)
00666 {
00667        aux_data_t    aux_data_;
00668        aux_data_t    *aux_data = &(aux_data_);
00669        aux_data_type_t      type;
00670        xaux_class_t  *xc;
00671 
00672        xc = &xaux_classes[0];
00673 
00674        aux_data->im = ((CARD32)(event->data.l[1])) >> 16;
00675        aux_data->ic = ((CARD32)(event->data.l[1])) & 0xffff;
00676        aux_data->aux_index = (CARD32)(event->data.l[2]);
00677 
00678        type = (CARD32)(event->data.l[3]);
00679 
00680        switch (type) {
00681        case AUX_DATA_SETVALUE:
00682               return xaux_object_process_property_update(display, window,
00683                             (Atom)(event->data.l[4]), xc);
00684        default:
00685               return False;
00686        }
00687 }
00688 
00689 static Bool xaux_object_event_filter(Display *display, Window window, XEvent *event, XPointer pointer)
00690 {
00691        switch (event->type) {
00692        case ClientMessage:
00693               return (xaux_object_process_client_message(display, window,
00694                      (XClientMessageEvent *)event));
00695        }
00696        return False;
00697 }