Back to index

im-sdk  12.3.91
xaux_ext_common.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2003 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 
00043 #pragma ident "$Id$"
00044 
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <limits.h>
00048 #include <unistd.h>
00049 #include <stdarg.h>
00050 #include <poll.h>
00051 
00052 #include <X11/Intrinsic.h>
00053 #include <X11/Xatom.h>
00054 
00055 #include "trace_message.h"
00056 
00057 #include "iiimpAux.h"
00058 #include "xaux_common.h"
00059 #include "xaux_ext_common.h"
00060 #include "xaux_ext_common_priv.h"
00061 
00062 static unsigned int  xs_seqno = 0;
00063 static unsigned int  maxpropsz = XAUX_MAXPROPSZ;
00064 
00065 static Bool
00066 xaux_ext_get_sowin(
00067        xaux_ext_class_t     *xc,
00068        Display              *display)
00069 {
00070        xc->sowin = XGetSelectionOwner(display, xc->atom_sowin);
00071 
00072        if (xc->sowin == None) {
00073 #if defined(DEBUG_XAUX)
00074               fprintf(stderr, "%s: cannot find sowin.[%s]\n", xc->classname);
00075 #endif /* defined(DEBUG_XAUX) */
00076               return (False);
00077        } else {
00078               XSelectInput(display, xc->sowin, PropertyChangeMask);
00079               return (True);
00080        }
00081 }
00082 
00083 static Bool
00084 xaux_xs_flushq(
00085        Display *            dpy,
00086        xaux_ext_class_t *   xc)
00087 {
00088        Bool          rv = True;
00089        unsigned char *p;
00090        int           len;
00091        Atom          atom;
00092 
00093        while (xaux_propq_check(xc->propq) > 0) {
00094               atom = xaux_atommng_get_atom(xc->atommng_data, xc->sowin);
00095               if (atom == (Atom)None) {
00096                      rv = False;
00097                      break;
00098               }
00099               if (xaux_propq_get(xc->propq, &p, &len) >= 0) {
00100                      XSetSelectionOwner(dpy, atom, xc->extwin, CurrentTime);
00101                      XFlush(dpy);
00102                      XChangeProperty(dpy, xc->sowin, atom,
00103                             XA_STRING, 8, PropModeReplace,
00104                             p, len);
00105                      XFlush(dpy);
00106 #if defined(DEBUG_XAUX)
00107 fprintf(stderr, "(%s) send property atom=%d\n", xc->shortname, atom);
00108 #endif /* defined(DEBUG_XAUX) */
00109                      free(p);
00110               } else {
00111                      rv = False;
00112                      break;
00113               }
00114        }
00115 
00116        return (rv);
00117 }
00118 
00119 static Bool
00120 xaux_xs_send_property(
00121        Display *            dpy,
00122        xaux_ext_class_t *   xc,
00123        const unsigned char *       p,     /* data to send */
00124        int                  len)   /* length of data (bytes) */
00125 {
00126        Atom   atom;
00127        int    i;
00128        int    qcount;
00129 
00130        if ((xc->sowin == None) &&
00131               (xaux_ext_get_sowin(xc, dpy) == False)) {
00132               return (False);
00133        }
00134 
00135        if ((qcount = xaux_propq_add(xc->propq, (unsigned char *)p, len))
00136                      == -1) {
00137 fprintf(stderr, "(%s) SETVALUE: cannot add to send buffer (mem)\n",
00138               xc->shortname);
00139               free((char *)p);
00140               return (False);
00141        } else if (qcount == -2) {
00142 fprintf(stderr, "(%s) SETVALUE: cannot add to send buffer (size)\n",
00143               xc->shortname);
00144               free((char *)p);
00145               return (False);
00146        }
00147 
00148        xaux_xs_flushq(dpy, xc);
00149 
00150        return (True);
00151 }
00152 
00153 static Bool
00154 xaux_xs_send_property_setv(
00155        Display                     *dpy,
00156        xaux_ext_class_t     *xc,
00157        char                 *prop)
00158 {
00159        char          *setv = XS_DATA_TOP(prop);
00160        Bool          rv;
00161 
00162 #if defined(DEBUG_XAUX)
00163        if (BO_SEGNO(prop) == 0) {
00164               if (BO_SETV_INT_COUNT(setv) > 0) {
00165                      fprintf(stderr, "(%s) SETV: im=0x%x ic=0x%x "
00166                             "i[0]=0x%x in=%d sn=%d "
00167                             "segno=%d segsize=0x%x\n",
00168                             xc->shortname,
00169                             BO_IMID(prop), BO_ICID(prop),
00170                             *(BO_SETV_INT_LIST(setv)),
00171                             BO_SETV_INT_COUNT(setv),
00172                             BO_SETV_STR_COUNT(setv),
00173                             BO_SEGNO(prop), SX_SEGSIZE(prop));
00174               } else {
00175                      fprintf(stderr, "(%s) SETV: im=0x%x ic=0x%x "
00176                             "in=%d sn=%d "
00177                             "segno=%d segsize=0x%x\n",
00178                             xc->shortname,
00179                             BO_IMID(prop), BO_ICID(prop),
00180                             BO_SETV_INT_COUNT(setv),
00181                             BO_SETV_STR_COUNT(setv),
00182                             BO_SEGNO(prop), BO_SEGSIZE(prop));
00183               }
00184        } else {
00185               fprintf(stderr, "(%s) SETV: im=0x%x ic=0x%x "
00186                             "segno=%d segsize=0x%x\n",
00187                      xc->shortname,
00188                      BO_IMID(prop), BO_ICID(prop),
00189                      BO_SEGNO(prop), BO_SEGSIZE(prop));
00190        }
00191 #endif /* defined(DEBUG_XAUX) */
00192 
00193        rv = xaux_xs_send_property(dpy, xc, (unsigned char *)prop,
00194               XS_SIZE_HEADER + XS_SEGSIZE(prop));
00195 
00196        return (rv);
00197 }
00198 
00199 typedef struct _xaux_ext_draw_state {
00200        Bool          stored;
00201        int           seqno;
00202        aux_ext_data_t       aux_ext_data_;
00203        aux_ext_data_t       *aux_ext_data;
00204        int           segno;
00205        int           int_next;
00206        int           str_next;
00207        int           str_yet;
00208        int           outbufsz;
00209        char          *outbuf_;
00210        char          *outbuf;
00211        int           maxnprops;
00212        int           nprops;
00213        unsigned char **props;
00214 } xaux_ext_draw_state_t;
00215 
00216 static xaux_ext_draw_state_t       _pending_draw[XAUX_EXT_MAXDEPTH];
00217 static xaux_ext_draw_state_t       *pending_draw_array = NULL;
00218 
00219 static Bool
00220 xaux_ext_clean_draw_state(xaux_ext_draw_state_t *state, Bool initial)
00221 {
00222        int           maxnprops_sv;
00223        unsigned char **props_sv;
00224        aux_ext_data_t *data;
00225        int           i;
00226 
00227        if (!initial) {
00228               if (state->aux_ext_data != NULL) {
00229                      free(state->aux_ext_data->integer_list);
00230                      data = state->aux_ext_data;
00231                      if (NULL != data->string_list) {
00232                             for (i = 0; i < data->string_count; i++) {
00233                                    free((data->string_list + i)->ptr);
00234                             }
00235                      }
00236                      free(state->aux_ext_data->string_list);
00237               }
00238               free(state->outbuf_);
00239 
00240               for (i = 0; i < state->nprops; i++) {
00241                      if (state->props[i] != NULL) {
00242                             XFree(state->props[i]);
00243                      }
00244               }
00245 
00246               maxnprops_sv = state->maxnprops;
00247               props_sv = state->props;
00248        }
00249 
00250        memset(state, 0, sizeof (xaux_ext_draw_state_t));
00251 
00252        if (initial) {
00253               state->maxnprops = XAUX_MAXNPROPS_INIT;
00254               if ((state->props = (unsigned char **)malloc(
00255                             sizeof (unsigned char *)
00256                             * state->maxnprops)) == NULL) {
00257                      return (False);
00258               }
00259        } else {
00260               state->maxnprops = maxnprops_sv;
00261               state->props = props_sv;
00262        }
00263 
00264        state->nprops = 0;
00265        state->stored = False;
00266        state->aux_ext_data = &(state->aux_ext_data_);
00267 
00268        return (True);
00269 }
00270 
00271 static Bool
00272 xaux_ext_add_prop_to_draw_state(
00273        xaux_ext_draw_state_t       *state,
00274        unsigned char        *prop)
00275 {
00276        int           maxnprops = state->maxnprops;
00277        int           nprops = state->nprops;
00278        unsigned char **props = state->props;
00279 
00280        if ((state->nprops) >= state->maxnprops) {
00281               maxnprops += XAUX_MAXNPROPS_INIT;
00282               props = (unsigned char **)realloc(props,
00283                      sizeof (unsigned char *) * maxnprops);
00284               if (props == NULL) {
00285                      return (False);
00286               }
00287               state->maxnprops = maxnprops;
00288               state->props = props;
00289        }
00290 
00291        state->props[state->nprops] = prop;
00292        state->nprops++;
00293        return (True);
00294 }
00295 
00296 static Bool
00297 xaux_ext_init_draw_state(
00298        xaux_ext_draw_state_t       *state,
00299        xaux_ext_priv_t             *priv,
00300        xaux_ext_class_t     *xc,
00301        unsigned char        *prop)
00302 {
00303        aux_ext_data_t       *aux_ext_data;
00304        unsigned char *draw;
00305 
00306        if (xaux_ext_clean_draw_state(state, False) == False) {
00307               return (False);
00308        }
00309 
00310        draw = SX_DATA_TOP(prop);
00311 
00312        state->seqno = BO_SEQNO(prop);
00313 
00314        aux_ext_data = state->aux_ext_data;
00315        aux_ext_data->type = AUX_EXT_DATA_DRAW;
00316        aux_ext_data->im = BO_IMID(prop);
00317        aux_ext_data->ic = BO_ICID(prop);
00318        aux_ext_data->aux_index = BO_INDEX(prop);
00319        aux_ext_data->aux_name = (unsigned char *)xc->classname;
00320        aux_ext_data->aux_name_length =
00321               strlen((const char *)aux_ext_data->aux_name);
00322        aux_ext_data->integer_count = BO_DRAW_INT_COUNT(prop);
00323        aux_ext_data->string_count = BO_DRAW_STR_COUNT(prop);
00324        aux_ext_data->clientwin = BO_DRAW_CLIENTWIN(prop);
00325        aux_ext_data->focuswin = BO_DRAW_FOCUSWIN(prop);
00326        aux_ext_data->point.x = BO_DRAW_POSX(prop);
00327        aux_ext_data->point.y = BO_DRAW_POSY(prop);
00328 
00329        state->segno = BO_SEGNO(prop);
00330 
00331        state->str_yet = 0;
00332 
00333        if (aux_ext_data->integer_count > 0) {
00334               if ((aux_ext_data->integer_list = (int *)malloc(sizeof (int)
00335                             * aux_ext_data->integer_count)) == NULL) {
00336                      (void)xaux_ext_clean_draw_state(state, False);
00337                      return (False);
00338               }
00339        } else {
00340               aux_ext_data->integer_list = NULL;
00341        }
00342 
00343        if (aux_ext_data->string_count > 0) {
00344 
00345               if ((aux_ext_data->string_list = (aux_ext_string_t *)malloc(
00346                             sizeof (aux_ext_string_t) *
00347                             aux_ext_data->string_count)) == NULL) {
00348                      (void)xaux_ext_clean_draw_state(state, False);
00349                      return (False);
00350               }
00351 
00352               /*
00353                * when conversion to locale codeset is needed,
00354                * allocate buffer for conversion output.
00355                */
00356               if (priv->do_mbconv) {
00357                      size_t c;
00358 
00359                      /* total length (in bytes) of strings */
00360                      c  = BO_DRAW_TOTAL_STR_LEN(prop); 
00361                      /* converting to number of chars */
00362                      c /= sizeof (CARD16);
00363                      /* multiply with MB_CUR_MAX */
00364                      c *= MB_CUR_MAX;
00365                      /* for null termination of each string */
00366                      c += aux_ext_data->string_count;
00367 
00368                      state->outbufsz = c;
00369                      /* allocate outbuf_ */
00370                      if ((state->outbuf_ = (char *)malloc(state->outbufsz))
00371                                    == NULL) {
00372                             (void)xaux_ext_clean_draw_state(state, False);
00373                             return (False);
00374                      }
00375                      state->outbuf = state->outbuf_;
00376               }
00377        }
00378 
00379        return (True);
00380 }
00381 
00382 static Bool
00383 xaux_ext_process_property_update(
00384        xaux_ext_priv_t *    priv,
00385        Window               window,
00386        Atom                 atom)
00387 {
00388        xaux_ext_draw_state_t       *state;
00389        aux_ext_data_t              *aux_ext_data;
00390        Display       *      dpy = priv->dpy;
00391        Atom          actual_type_return;
00392        int           actual_format_return;
00393        unsigned long nitem_return;
00394        unsigned long bytes_after_return;
00395        unsigned char *      prop;
00396        unsigned char *      proptail;
00397        unsigned char *      draw;
00398        int           r;
00399        int           imid;
00400        unsigned char *      p;
00401        int           i;
00402        int           n=0;
00403        xaux_ext_class_t     *xc = &(priv->class);
00404        XPoint        point;
00405        Bool          rv = True;
00406        int           type;
00407        int           *ip;
00408        unsigned char *sp;
00409        xaux_ext_draw_state_t       *pending_draw;
00410 
00411        r = XGetWindowProperty(dpy, window,
00412                             atom, 0, INT_MAX, True,
00413                             XA_STRING, &actual_type_return,
00414                             &actual_format_return, &nitem_return,
00415                             &bytes_after_return, &prop);
00416 
00417        if ((r != Success) || (actual_type_return != XA_STRING)) {
00418               return False;
00419        }
00420 
00421        type = BO_AUXTYPE(prop);
00422 
00423        proptail = prop + SX_SIZE_HEADER + BO_SEGSIZE(prop);
00424 
00425        if (type == AUX_DATA_START || type == AUX_DATA_DONE) {
00426               aux_ext_data_t       aux_ext_data_;
00427 
00428               aux_ext_data = &(aux_ext_data_);
00429 
00430               if (BO_ATOM_AUX_NAME(prop) != xc->atom_classname) {
00431                      rv = False;
00432                      goto cleanup_return;
00433               }
00434 
00435               aux_ext_data->im = BO_IMID(prop);
00436               aux_ext_data->ic = BO_ICID(prop);
00437               aux_ext_data->aux_index = BO_INDEX(prop);
00438 
00439               switch (type) {
00440               case AUX_EXT_DATA_START:
00441 #if defined(DEBUG_XAUX)
00442                      fprintf(stderr, "(%s) START%s: im=0x%x ic=0x%x\n",
00443                             xc->shortname,
00444                             ((window == xc->sowin) ? "(sowin)" : ""),
00445                             aux_ext_data->im, aux_ext_data->ic);
00446 #endif /* defined(DEBUG_XAUX) */
00447                      if (priv->cb_start != NULL) {
00448                             rv = (*priv->cb_start)(xc,
00449                                    aux_ext_data, priv->cb_start_data);
00450                      } else {
00451 #if defined(DEBUG_XAUX)
00452        fprintf(stderr, "(%s) START callback not registered\n", xc->shortname);
00453 #endif /* defined(DEBUG_XAUX) */
00454                             rv = False;
00455                      }
00456                      break;
00457               case AUX_EXT_DATA_DONE:
00458 #if defined(DEBUG_XAUX)
00459                      fprintf(stderr, "(%s) DONE%s: im=0x%x ic=0x%x\n",
00460                             xc->shortname,
00461                             ((window == xc->sowin) ? "(sowin)" : ""),
00462                             aux_ext_data->im, aux_ext_data->ic);
00463 #endif /* defined(DEBUG_XAUX) */
00464                      if (priv->cb_done != NULL) {
00465                             rv = (*priv->cb_done)(xc,
00466                                    aux_ext_data, priv->cb_done_data);
00467                      } else {
00468 #if defined(DEBUG_XAUX)
00469        fprintf(stderr, "(%s) DONE callback not registered\n", xc->shortname);
00470 #endif /* defined(DEBUG_XAUX) */
00471                             rv = False;
00472                      }
00473                      break;
00474               }
00475 
00476               rv = True;
00477               goto cleanup_return;
00478        }
00479 
00480        draw = SX_DATA_TOP(prop);
00481 
00482        if (pending_draw_array == NULL) {
00483               int    i;
00484               pending_draw_array = &(_pending_draw[0]);
00485 
00486               for (i = 0; i < XAUX_EXT_MAXDEPTH; i++) {
00487                      xaux_ext_clean_draw_state(
00488                             &(pending_draw_array[i]), True);
00489               }
00490        }
00491 
00492 #if defined(DEBUG_XAUX)
00493 fprintf(stderr, "(%s) DRAW: using depth=%d pending_draw\n",
00494               xc->shortname, xc->depth);
00495 #endif /* defined(DEBUG_XAUX) */
00496        pending_draw = &(pending_draw_array[xc->depth]);
00497 
00498        if (BO_SEGNO(prop) > 0) {
00499               if (pending_draw->stored == True) {
00500                      if (BO_SEGNO(prop) == (pending_draw->segno + 1)) {
00501 #if defined(DEBUG_XAUX)
00502 fprintf(stderr, "(%s) DRAW: segno=%d, continue with stored segno=%d\n",
00503               xc->shortname, BO_SEGNO(prop), pending_draw->segno);
00504 #endif /* defined(DEBUG_XAUX) */
00505                             state = pending_draw;
00506                             ip = (int *)draw;
00507                      } else {
00508 #if defined(DEBUG_XAUX)
00509 fprintf(stderr, "(%s) DRAW: stored segno mismatch (%d expected %d actual)\n",
00510               xc->shortname, pending_draw->segno + 1, BO_SEGNO(prop));
00511 #endif /* defined(DEBUG_XAUX) */
00512                             xaux_ext_clean_draw_state(pending_draw, False);
00513                             rv = False;
00514                             goto cleanup_return;
00515                      }
00516               } else {
00517 #if defined(DEBUG_XAUX)
00518 fprintf(stderr, "(%s) DRAW: received segno=%d but no stored segs\n",
00519               xc->shortname, BO_SEGNO(prop));
00520 #endif /* defined(DEBUG_XAUX) */
00521                      rv = False;
00522                      goto cleanup_return;
00523               }
00524        } else {
00525               if (pending_draw->stored == True) {
00526 #if defined(DEBUG_XAUX)
00527 fprintf(stderr, "(%s) DRAW: stored but received segno=0 (%d expected)\n",
00528                             xc->shortname, pending_draw->segno + 1);
00529 #endif /* defined(DEBUG_XAUX) */
00530                      xaux_ext_init_draw_state(pending_draw, priv, xc, prop);
00531               } else {
00532                      xaux_ext_init_draw_state(pending_draw, priv, xc, prop);
00533               }
00534               state = pending_draw;
00535               ip = (int *)BO_DRAW_INT_LIST(draw);
00536        }
00537 
00538        aux_ext_data = state->aux_ext_data;
00539 
00540        for (i = state->int_next; i < aux_ext_data->integer_count; i++) {
00541               if ((unsigned char *)ip >= proptail) {
00542                      state->int_next = i;
00543                      state->segno = BO_SEGNO(prop);
00544                      xaux_ext_add_prop_to_draw_state(state, prop);
00545                      state->stored = True;
00546 #if defined(DEBUG_XAUX)
00547 fprintf(stderr, "(%s) DRAW: received up to int[%d]\n", xc->shortname, i - 1);
00548 #endif /* defined(DEBUG_XAUX) */
00549                      return (True);
00550               }
00551               aux_ext_data->integer_list[i] = BO_CARD32(prop, ip);
00552               ip++;
00553        }
00554 
00555        state->int_next = i;
00556 
00557        sp = (unsigned char *)ip;
00558 
00559        for(i = state->str_next; i < aux_ext_data->string_count; i++) {
00560               char *        ib;
00561               size_t        ibl;
00562               size_t        obl = state->outbufsz;
00563 
00564               if (sp >= proptail) {
00565                      state->str_next = i;
00566                      state->segno = BO_SEGNO(prop);
00567                      xaux_ext_add_prop_to_draw_state(state, prop);
00568                      state->stored = True;
00569 #if defined(DEBUG_XAUX)
00570 fprintf(stderr, "(%s) DRAW: received up to str[%d]\n", xc->shortname, i - 1);
00571 #endif /* defined(DEBUG_XAUX) */
00572                      return (True);
00573               }
00574 
00575               /* assign length of a string to ibl */
00576               ibl = BO_CARD16(prop, sp);
00577               /* move sp to head of the string */
00578               sp += sizeof(CARD16);
00579               /* assign head of the string to ib */
00580               ib = (char *)sp;
00581               /* move sp to point length of next string */
00582               sp += (ibl + sizeof (unsigned char) * 2 +
00583                      padding[(sizeof(CARD16)
00584                      + ibl + sizeof (unsigned char) * 2) % 4]);
00585 
00586               if (priv->do_mbconv) { /* convert to locale codeset */
00587                      char *        ob;
00588                      size_t        obl_save;
00589 
00590                      ob = state->outbuf;
00591                      obl_save = obl;
00592                      aux_ext_data->string_list[i].ptr = (unsigned char *)ob;
00593                      utf16_mb((const char **)&ib, &ibl, &ob, &obl);
00594                      aux_ext_data->string_list[i].length = obl_save - obl;
00595                      state->outbuf =
00596                             ob + aux_ext_data->string_list[i].length;
00597                      /* null termination */
00598                      *(state->outbuf++) = '\0';
00599                      *(state->outbuf++) = '\0';
00600               } else { /* pass as UTF-16 string */
00601                      aux_ext_data->string_list[i].ptr =
00602                             (unsigned char *)malloc((sizeof (CARD16)) * ibl);
00603                      if (1 == (*((CARD16 *)(prop)))) {
00604                             memcpy((char *)(aux_ext_data->string_list[i].ptr),
00605                                    ib,
00606                                    (sizeof (CARD16)) * ibl);
00607                      } else {
00608                             swab(ib,
00609                                  (char *)(aux_ext_data->string_list[i].ptr),
00610                                  (sizeof (CARD16)) * ibl);
00611                      }
00612                      aux_ext_data->string_list[i].length = ibl;
00613               }
00614        }
00615 
00616 #if defined(DEBUG_XAUX)
00617        if (aux_ext_data->integer_count > 0) {
00618               fprintf(stderr, "(%s) DRAW%s: im=0x%x ic=0x%x "
00619                             "i[0]=0x%x in=%d sn=%d\n",
00620                      xc->shortname,
00621                      ((window == xc->sowin) ? "(sowin)" : ""),
00622                      aux_ext_data->im, aux_ext_data->ic,
00623                      aux_ext_data->integer_list[0],
00624                      aux_ext_data->integer_count,
00625                      aux_ext_data->string_count);
00626        } else {
00627               fprintf(stderr, "(%s) DRAW%s: im=0x%x ic=0x%x in=%d sn=%d\n",
00628                      xc->shortname,
00629                      ((window == xc->sowin) ? "(sowin)" : ""),
00630                      aux_ext_data->im, aux_ext_data->ic,
00631                      aux_ext_data->integer_count,
00632                      aux_ext_data->string_count);
00633        }
00634 #endif /* defined(DEBUG_XAUX) */
00635        if (priv->cb_draw != NULL) {
00636               rv = (*priv->cb_draw)(xc, aux_ext_data, priv->cb_draw_data);
00637        } else {
00638 #if defined(DEBUG_XAUX)
00639        fprintf(stderr, "(%s) DRAW callback not registered\n", xc->shortname);
00640 #endif /* defined(DEBUG_XAUX) */
00641               rv = False;
00642        }
00643 
00644        xaux_ext_clean_draw_state(state, False);
00645 
00646 cleanup_return:
00647        if (prop != NULL) {
00648               XFree(prop);
00649        }
00650 
00651        return (rv);
00652 }
00653 
00654 static Bool
00655 xaux_ext_increment_depth(
00656        xaux_ext_class_t     *xc
00657 )
00658 {
00659        xc->depth++;
00660 
00661        if (xc->depth > XAUX_EXT_MAXDEPTH) {
00662               fprintf(stderr,
00663                      "(%s) depth exceeded (%d)\n", xc->shortname, xc->depth);
00664               xc->depth--;
00665               return (False);
00666        } else {
00667 #if defined(DEBUG_XAUX)
00668               fprintf(stderr, "(%s) depth=%d\n", xc->shortname, xc->depth);
00669 #endif /* defined(DEBUG_XAUX) */
00670               return (True);
00671        }
00672 }
00673 
00674 static Bool
00675 xaux_ext_decrement_depth(
00676        xaux_ext_class_t     *xc
00677 )
00678 {
00679        xc->depth--;
00680 #if defined(DEBUG_XAUX)
00681        fprintf(stderr, "(%s) depth=%d\n", xc->shortname, xc->depth);
00682 #endif /* defined(DEBUG_XAUX) */
00683        return (True);
00684 }
00685 
00686 static Bool
00687 xaux_ext_process_property_notify(
00688        xaux_ext_priv_t *    priv,
00689        Window               win,
00690        Atom                 atom)
00691 {
00692        Display       *      dpy = priv->dpy;
00693        xaux_ext_class_t     *xc = &(priv->class);
00694        Atom          *atoms;
00695        int           r;            /* return of Xlib functions */
00696        Bool          rv;           /* return of xaux functions */
00697        int           i;
00698 
00699        if (win == (Window)None) {
00700               return (False);
00701        }
00702 
00703        if (xaux_ext_increment_depth(xc) == False) {
00704               return (False);
00705        }
00706        
00707 #if defined(DEBUG_XAUX)
00708 fprintf(stderr, "(%s) process new atom=%d at depth=%d\n",
00709                      xc->shortname, atom, xc->depth);
00710 #endif /* defined(DEBUG_XAUX) */
00711        rv = xaux_ext_process_property_update(priv, win, atom);
00712 
00713        xaux_ext_decrement_depth(xc);
00714 
00715        return (True);
00716 }
00717 
00718 static Bool
00719 xaux_ext_dispatch_propnot_extwin(
00720        xaux_ext_priv_t             *priv,
00721        Window               win,
00722        XPropertyEvent              *pev)
00723 {
00724        Bool                 rv = False;
00725        xaux_ext_class_t *   xc = &(priv->class);
00726 
00727        if (xaux_atommng_check_atom(xc->atommng_data, False, pev->atom)
00728                      == True) {
00729               /* sx */
00730               if (pev->state == PropertyNewValue) {
00731                      rv = xaux_ext_process_property_notify(priv,
00732                             (win == (Window)None) ?
00733                             pev->window : win, pev->atom);
00734               }
00735               rv = True;
00736        }
00737 
00738        return (rv);
00739 }
00740 
00741 static Bool
00742 xaux_ext_dispatch_propnot_sowin(
00743        xaux_ext_priv_t             *priv,
00744        Window               win,
00745        XPropertyEvent              *pev)
00746 {
00747        Bool                 rv = False;
00748        xaux_ext_class_t *   xc = &(priv->class);
00749 
00750        if (xaux_atommng_check_atom(xc->atommng_data, True, pev->atom)
00751                      == True) {
00752               /* xs */
00753               if (pev->state == PropertyDelete) {
00754                      if (xaux_atommng_process_delete(xc->atommng_data, pev)
00755                                    == True) {
00756                             xaux_xs_flushq(priv->dpy, xc);
00757                      }
00758               }
00759               rv = True;
00760        }
00761 
00762        return (rv);
00763 }
00764 
00765 static Bool
00766 xaux_ext_event_handler(
00767        xaux_ext_handle_t    hdl,   /* handle */
00768        Window               win,   /* window */
00769        XEvent *             ev,    /* event */
00770        void *               sodata)       /* so's data */
00771 {
00772        xaux_ext_priv_t *    priv = (xaux_ext_priv_t *)sodata;
00773        Bool                 rv = False;
00774        xaux_ext_class_t *   xc = &(priv->class);
00775 
00776        TRACE_MESSAGE('E', ("aux_ext:AuxEventHandler: %d\n", event->type));
00777 
00778        switch (ev->type) {
00779        case PropertyNotify:
00780               if (ev->xproperty.window == xc->extwin) {
00781                      rv = xaux_ext_dispatch_propnot_extwin(priv, win,
00782                             (XPropertyEvent *)(&(ev->xproperty)));
00783               }
00784               break;
00785        case SelectionClear:
00786               if ((rv = xaux_atommng_process_selclr(xc->atommng_data,
00787                             (XSelectionClearEvent *)ev)) == True) {
00788                      xaux_xs_flushq(priv->dpy, xc);
00789               }
00790               break;
00791        default:
00792 #if defined(DEBUG_XAUX)
00793        fprintf(stderr, "(%s) ignore event type=%d\n", xc->shortname, ev->type);
00794 #endif /* defined(DEBUG_XAUX) */
00795               break;
00796        }
00797 
00798        return (rv);
00799 }
00800 
00801 static void
00802 xaux_ext_notify_extwin(
00803        xaux_ext_class_t *   xc,
00804        Display *            dpy)
00805 {
00806        if (xc->sowin == (Window)None) {
00807               return;
00808        }
00809 
00810 
00811        XChangeProperty(dpy, xc->sowin, xc->atom_extwin, XA_WINDOW,
00812               32, PropModeReplace, (unsigned char *)&(xc->extwin), 1);
00813 #if defined(DEBUG_XAUX)
00814 fprintf(stderr, "ext: notify_extwin: extwin 0x%x to sowin 0x%0x\n",
00815        xc->extwin, xc->sowin);
00816 #endif /* defined(DEBUG_XAUX) */
00817 
00818        XFlush(dpy);
00819 }
00820 
00821 /* xaux_ext_open: start to use xaux_ext */
00822 
00823 static xaux_ext_handle_t           /* handle */
00824 xaux_ext_open(
00825        const char *  classname,    /* classname (ASCII) */
00826        Display *     dpy,          /* display */
00827        Window        extwin,              /* window */
00828        ...)                        /* optional values */
00829 {
00830        va_list              ap;
00831        int           ptr_no = 0;
00832 
00833        xaux_ext_priv_t *    priv;
00834        xaux_ext_class_t *   xc;
00835        char                 buf[PATH_MAX];
00836 
00837        if (dpy == NULL || classname == NULL) {
00838               return (NULL);
00839        }
00840 
00841        priv = (xaux_ext_priv_t *)malloc(sizeof (xaux_ext_priv_t));
00842 
00843        bzero((void *)priv, sizeof (xaux_ext_priv_t));
00844 
00845        priv->dpy = dpy;
00846        priv->do_mbconv = False;
00847 
00848        xc = &(priv->class);
00849 
00850        bzero((void *)xc, sizeof (xaux_ext_class_t));
00851 
00852        xc->classname = (const char *)strdup(classname);
00853 
00854        if (xc->classname == NULL) {
00855               free(priv);
00856               return (NULL);
00857        }
00858 
00859        xc->shortname = strrchr(xc->classname, '.');
00860        if (xc->shortname == NULL) {
00861               xc->shortname = (char *)xc->classname;
00862        } else {
00863               xc->shortname++;
00864        }
00865        xc->shortname = strdup(xc->shortname);
00866        if (xc->shortname == NULL) {
00867               xc->shortname = "";
00868        } else {
00869               if (strlen(xc->shortname) > 4) {
00870                      xc->shortname[4] = '\0';
00871               }
00872        }
00873 
00874        xc->atom_classname = XInternAtom(dpy, xc->classname, False);
00875 
00876        sprintf(buf, "%s%s", xc->classname, XAUX_SOWIN_SUFFIX);
00877        xc->atom_sowin = XInternAtom(dpy, buf, False);
00878 
00879        sprintf(buf, "%s%s", xc->classname, XAUX_EXTWIN_SUFFIX);
00880        xc->atom_extwin = XInternAtom(dpy, buf, False);
00881 
00882        sprintf(buf, "%s_sx", xc->classname);
00883        xc->atom_sx = XInternAtom(dpy, buf, False);
00884 
00885        sprintf(buf, "%s_xs", xc->classname);
00886        xc->atom_xs = XInternAtom(dpy, buf, False);
00887 
00888        xc->atommng_data = xaux_atommng_alloc_data(
00889               xc->classname, True /* means "xs" */, dpy);
00890        
00891        if (xc->atommng_data == NULL) {
00892               free((void *)xc->classname);
00893               free(priv);
00894               return (NULL);
00895        }
00896 
00897        xc->propq = xaux_propq_alloc(XAUX_EXT_MAXPROPQDATASZ);
00898 
00899        if (xc->propq == NULL) {
00900               xaux_atommng_free_data(xc->atommng_data);
00901               free((void *)xc->classname);
00902               free(priv);
00903               return (NULL);
00904        }
00905 
00906        xc->sowin = (Window)0;
00907 
00908        xc->extwin = extwin;
00909 
00910        if (xc->extwin == (Window)0) {
00911               xaux_atommng_free_data(xc->atommng_data);
00912               free((void *)xc->classname);
00913               free(priv);
00914               return (NULL);
00915        }
00916               
00917        va_start(ap, 128);
00918 
00919        /* optional values can be set here */
00920 
00921        va_end(ap);
00922 
00923        if (XGetSelectionOwner(dpy, xc->atom_extwin) != None) {
00924 #if defined(DEBUG_XAUX)
00925               fprintf(stderr, "%s: %s already exists.[%s](1)\n",
00926                      ME_EXT, ME_EXT, xc->classname);
00927 #endif /* defined(DEBUG_XAUX) */
00928               xaux_atommng_free_data(xc->atommng_data);
00929               free((void *)xc->classname);
00930               free(priv);
00931               return (NULL);
00932        }
00933 
00934        XSetSelectionOwner(dpy, xc->atom_extwin, xc->extwin, CurrentTime);
00935 
00936        if (XGetSelectionOwner(dpy, xc->atom_extwin) != xc->extwin) {
00937 #if defined(DEBUG_XAUX)
00938               fprintf(stderr, "%s: %s already exists.[%s](2)\n",
00939                      ME_EXT, ME_EXT, xc->classname);
00940 #endif /* defined(DEBUG_XAUX) */
00941               xaux_atommng_free_data(xc->atommng_data);
00942               free((void *)xc->classname);
00943               free(priv);
00944               return (NULL);
00945        }
00946 
00947 #if defined(DEBUG_XAUX)
00948               fprintf(stderr, "(%s) extwin created: 0x%0x\n", 
00949                      xc->shortname, xc->extwin);
00950 #endif /* defined(DEBUG_XAUX) */
00951 
00952        if (xaux_ext_get_sowin(xc, dpy) == True) {
00953               /* notify extwin */
00954               xaux_ext_notify_extwin(xc, dpy);
00955        }
00956 
00957        xc->depth = 0;
00958 
00959        xc->maxnprops = XAUX_EXT_MAXNPROPS;
00960 
00961        if ((xc->props = (Atom *)malloc(sizeof (Atom) * xc->maxnprops))
00962                      == NULL) {
00963               free((void *)xc->classname);
00964               free(priv);
00965               return (NULL);
00966        } else {
00967               int    i;
00968               for (i = 0; i < xc->maxnprops; i++) {
00969                      xc->props[i] = (Atom)None;
00970               }
00971        }
00972 
00973        return ((xaux_ext_handle_t)priv);
00974 }
00975 
00976 /* xaux_ext_close: finish to use xaux_ext */
00977 
00978 static void
00979 xaux_ext_close(
00980        xaux_ext_handle_t    hdl)          /* handle */
00981 {
00982        xaux_ext_priv_t             *priv = (xaux_ext_priv_t *)hdl;
00983 
00984        if (priv != NULL) {
00985               xaux_ext_class_t * xc = (xaux_ext_class_t *)&(priv->class);
00986               xaux_atommng_free_data(xc->atommng_data);
00987               xaux_propq_free(xc->propq);
00988               free((void *)xc->classname);
00989               free(xc->props);
00990               free(priv);
00991        }
00992 
00993        return;
00994 }
00995 
00996 /*
00997  * xaux_ext_registercb_addevhandler:
00998  * register callback to add event handler
00999  */
01000 
01001 static Bool
01002 xaux_ext_registercb_addevhandler(
01003        xaux_ext_handle_t           hdl,   /* handle */
01004        xaux_ext_cb_addevhandler_t  cb,    /* callback */
01005        void *                      data)  /* ext's data */
01006 {
01007        xaux_ext_priv_t             *priv = (xaux_ext_priv_t *)hdl;
01008 
01009        if (priv != NULL && cb != NULL) {
01010 #if defined(DEBUG_XAUX)
01011        fprintf(stderr, "(%s) cb_addevhandler registered\n",
01012               priv->class.shortname);
01013 #endif /* defined(DEBUG_XAUX) */
01014               priv->cb_addevhandler = cb;
01015               priv->cb_addevhandler_data = data;
01016               /* execution of callback maybe moved to somewhere else */
01017               (*priv->cb_addevhandler)(hdl,
01018                      PropertyChangeMask, True,
01019                      xaux_ext_event_handler, hdl,
01020                      priv->cb_addevhandler_data);
01021               /* process data arrived before evhandler registered (if any) */
01022 #if defined(DEBUG_XAUX)
01023        fprintf(stderr,
01024        "(%s) process data arrived before evhanlder registered (if any)\n",
01025               priv->class.shortname);
01026 #endif /* defined(DEBUG_XAUX) */
01027               (void)xaux_ext_process_property_notify(priv,
01028                      priv->class.extwin,
01029                      xaux_atommng_know_atom(priv->class.atommng_data, False)
01030                      );
01031               return (True);
01032        } else {
01033               return (False);
01034        }
01035 }
01036 
01037 static Bool
01038 xaux_ext_process_detoured_properties(
01039        xaux_ext_handle_t    hdl)
01040 {
01041        xaux_ext_priv_t             *priv = (xaux_ext_priv_t *)hdl;
01042        xaux_ext_class_t     *xc = &(priv->class);
01043 
01044        if (xc->sowin != None) {
01045               if ((priv->cb_start == NULL) ||
01046                             (priv->cb_draw == NULL) ||
01047                             (priv->cb_done == NULL)) {
01048                      return (False);
01049               }
01050               /* process sx properties which has been put on sowin */
01051 #if defined(DEBUG_XAUX)
01052        fprintf(stderr, "(%s) check detoured properties\n",
01053                             priv->class.shortname);
01054 #endif /* defined(DEBUG_XAUX) */
01055               xaux_ext_process_property_notify(priv, xc->sowin,
01056                      xaux_atommng_know_atom(priv->class.atommng_data, False)
01057                      );
01058        }
01059 }
01060 
01061 /*
01062  * xaux_ext_registercb_evhandler:
01063  * register callback to remove event handler
01064  */
01065 
01066 static Bool
01067 xaux_ext_registercb_rmevhandler(
01068        xaux_ext_handle_t           hdl,   /* handle */
01069        xaux_ext_cb_addevhandler_t  cb,    /* callback */
01070        void *                      data)  /* ext's data */
01071 {
01072        xaux_ext_priv_t             *priv = (xaux_ext_priv_t *)hdl;
01073 
01074        if (priv != NULL && cb != NULL) {
01075 #if defined(DEBUG_XAUX)
01076        fprintf(stderr, "(%s) cb_rmevhandler registered\n",
01077               priv->class.shortname);
01078 #endif /* defined(DEBUG_XAUX) */
01079               priv->cb_rmevhandler = cb;
01080               priv->cb_rmevhandler_data = data;
01081               return (True);
01082        } else {
01083               return (False);
01084        }
01085 }
01086 
01087 /* xaux_ext_registercb_start: register callback for AUX_START */
01088 
01089 static Bool
01090 xaux_ext_registercb_start(
01091        xaux_ext_handle_t    hdl,   /* handle */
01092        xaux_ext_cb_start_t  cb,    /* callback */
01093        void *               data)  /* client data */
01094 {
01095        xaux_ext_priv_t             *priv = (xaux_ext_priv_t *)hdl;
01096 
01097        if (priv != NULL && cb!= NULL) {
01098               priv->cb_start = cb;
01099               xaux_ext_process_detoured_properties(hdl);
01100               return (True);
01101        } else {
01102               return (False);
01103        }
01104 }
01105 
01106 /* xaux_ext_registercb_draw: register callback for AUX_DRAW */
01107 
01108 static Bool
01109 xaux_ext_registercb_draw(
01110        xaux_ext_handle_t    hdl,   /* handle */
01111        xaux_ext_cb_draw_t   cb,    /* callback */
01112        void *               data)  /* client data */
01113 {
01114        xaux_ext_priv_t             *priv = (xaux_ext_priv_t *)hdl;
01115 
01116        if (priv != NULL && cb != NULL) {
01117               priv->cb_draw = cb;
01118               xaux_ext_process_detoured_properties(hdl);
01119               return (True);
01120        } else {
01121               return (False);
01122        }
01123 }
01124 
01125 /* xaux_ext_registercb_done: register callback for AUX_DONE */
01126 
01127 static Bool
01128 xaux_ext_registercb_done(
01129        xaux_ext_handle_t    hdl,   /* handle */
01130        xaux_ext_cb_done_t   cb,    /* callback */
01131        void *               data)  /* client data */
01132 {
01133        xaux_ext_priv_t             *priv = (xaux_ext_priv_t *)hdl;
01134 
01135        if (priv != NULL && cb != NULL) {
01136               priv->cb_done = cb;
01137               xaux_ext_process_detoured_properties(hdl);
01138               return (True);
01139        } else {
01140               return (False);
01141        }
01142 }
01143 
01144 /* xaux_ext_setvalue: send AUX_SETVALUE to server */
01145 
01146 static Bool
01147 xaux_ext_setvalue(
01148        xaux_ext_handle_t    hdl,          /* handle */
01149        aux_ext_data_t              *aux_ext_data)       /* callback */
01150 {
01151        xaux_ext_priv_t             *priv = (xaux_ext_priv_t *)hdl;
01152        xaux_ext_class_t     *xc = (xaux_ext_class_t *)&(priv->class);
01153        Display              *dpy = priv->dpy;
01154        static char   *string_buf = NULL;
01155        char          *setv;
01156        static size_t bufsize = 0;
01157        size_t        i;
01158        int           *ip;
01159        char          *sp;
01160        Bool          rv = True;
01161        int           int_next;
01162        int           str_next;
01163        int           total_str_len;
01164        int           segno = 0;
01165        char          *propbuf = NULL;
01166        char          *propbuftail = NULL;
01167        int           allocsz;
01168 
01169        if (aux_ext_data == NULL) {
01170               /* reset; free string_buf */
01171               if (string_buf != NULL) {
01172                      free(string_buf);
01173                      string_buf = NULL;
01174               }
01175               bufsize = 0;
01176               return True;
01177        }
01178 
01179        if (aux_ext_data->string_count > 0) {
01180               size_t maxlen = 0;
01181               size_t newbufsize;
01182 
01183               for (i = 0, total_str_len = 0;
01184                             i < aux_ext_data->string_count; i++) {
01185                      if (priv->do_mbconv == True) {
01186                             total_str_len +=
01187                                    ((aux_ext_data->string_list[i].length 
01188                                           + 1) * sizeof (CARD16));
01189                             if (aux_ext_data->string_list[i].length
01190                                           > maxlen) {
01191                                    maxlen =
01192                                    aux_ext_data->string_list[i].length;
01193                             }
01194                      } else {
01195                             total_str_len +=
01196                                    aux_ext_data->string_list[i].length;
01197                      }
01198               }
01199 
01200               if (priv->do_mbconv == True) {
01201                      newbufsize = maxlen * sizeof (CARD16);
01202                      /*
01203                       * "+1" is required by mb_utf16() method.
01204                       * The method uses the area for BOM.
01205                       */
01206                      newbufsize += sizeof (CARD16);
01207 
01208                      if (newbufsize > bufsize) {
01209                             char   *new_string_buf;
01210                             new_string_buf =
01211                                    realloc(string_buf, newbufsize);
01212                             if (new_string_buf == NULL) {
01213                                    free(string_buf);
01214                                    bufsize = 0;
01215                                    return (False);
01216                             } else {
01217                                    bufsize = newbufsize;
01218                                    string_buf = new_string_buf;
01219                             }
01220                      }
01221               }
01222        }
01223 
01224        allocsz = XS_SIZE_HEADER + XS_SIZE_SETV_HEADER /* header */
01225               + (sizeof (CARD32) * aux_ext_data->integer_count) /* int */
01226               + total_str_len /* str */
01227               + (sizeof (CARD16) * aux_ext_data->string_count) /* strlen */
01228               + (3 * aux_ext_data->string_count); /* pad */
01229        
01230        if (allocsz > maxpropsz) {
01231               allocsz = maxpropsz;
01232        }
01233 
01234        for (segno = 0; ; segno++) {
01235               if (segno > 0) {
01236                      allocsz = maxpropsz;
01237               }
01238               if ((propbuf = (char *)malloc(allocsz)) == NULL) {
01239                      goto discard;
01240               }
01241               propbuftail = propbuf + allocsz;
01242 
01243               XS_PROTOVERS_MAJOR(propbuf) = XAUX_PROTOVERS_MAJOR;
01244               XS_PROTOVERS_MINOR(propbuf) = XAUX_PROTOVERS_MINOR;
01245               XS_SEQNO(propbuf) = xs_seqno;
01246               XS_ATOM_AUX_NAME(propbuf) = xc->atom_classname;
01247               XS_INDEX(propbuf) = xc->index;
01248               XS_PRIVTYPE(propbuf) = (CARD8)XAUX_PRIVTYPE_PUBLIC;
01249               XS_AUXTYPE(propbuf) = (CARD8)AUX_DATA_SETVALUE;
01250               XS_IMID(propbuf) = aux_ext_data->im;
01251               XS_ICID(propbuf) = aux_ext_data->ic;
01252               XS_MORESEGS(propbuf) = 0;
01253               XS_SEGNO(propbuf) = segno;
01254 
01255               setv = (char *)XS_DATA_TOP(propbuf);
01256 
01257               if (segno == 0) {
01258                      XS_SETV_INT_COUNT(setv) = aux_ext_data->integer_count;
01259                      XS_SETV_STR_COUNT(setv) = aux_ext_data->string_count;
01260                      int_next = 0;
01261                      str_next = 0;
01262                      ip = (int *)XS_SETV_INT_LIST(setv);
01263               } else {
01264                      ip = (int *)setv;
01265               }
01266 
01267               for (i = int_next; i < aux_ext_data->integer_count; i++) {
01268                      if ((char *)(ip + 1) > propbuftail) {
01269                             /* avoid to exceed tail of buffer */
01270                             XS_MORESEGS(propbuf) = 1;
01271                             XS_SEGSIZE(propbuf) = (char *)ip - setv;
01272                             rv = xaux_xs_send_property_setv(
01273                                    dpy, xc, propbuf);
01274                             if (rv == False) {
01275                                    goto discard;
01276                             }
01277 #if defined(DEBUG_XAUX)
01278 fprintf(stderr, "(%s) SETV: sent up to integer[%d]\n", xc->shortname, i - 1);
01279 #endif /* defined(DEBUG_XAUX) */
01280                             int_next = i;
01281                             break;
01282                      }
01283                      *ip++ = aux_ext_data->integer_list[i];
01284               }
01285 
01286               if (i < aux_ext_data->integer_count) {
01287                      continue;
01288               }
01289 
01290               int_next = i;        /* no more int */
01291               sp = (char *)ip;     /* int array tail is str array head */
01292 
01293               for (i = str_next; i < aux_ext_data->string_count; i++) {
01294                      size_t        len;
01295                      int           pn;
01296                      unsigned char *p;
01297                      size_t        j;
01298                      char *        ib;
01299                      size_t        ibl;
01300 
01301                      ib = (char *)(aux_ext_data->string_list[i].ptr);
01302                      ibl = (size_t)aux_ext_data->string_list[i].length;
01303 
01304                      if (priv->do_mbconv) {
01305                             char *        ob;
01306                             size_t        obl;
01307 
01308                             ob = string_buf;
01309                             obl = bufsize;
01310                             mb_utf16((const char **)&ib, &ibl, &ob, &obl);
01311                             len = bufsize - obl;
01312                             p = (unsigned char *)string_buf;
01313                      } else {
01314                             len = ibl;
01315                             p = (unsigned char *)ib;
01316                      }
01317 
01318                      pn = padding[(sizeof (CARD16) + len) % 4];
01319 
01320                      if ((sp + sizeof (CARD16) + len + pn) > propbuftail) {
01321                             /* avoid to exceed tail of buffer */
01322                             if (i == str_next) {
01323                                    /* single string too long */
01324                                    goto discard;
01325                             }
01326                             XS_MORESEGS(propbuf) = 1;
01327                             XS_SEGSIZE(propbuf) = (char *)sp - setv;
01328                             rv = xaux_xs_send_property_setv(
01329                                    dpy, xc, propbuf);
01330                             if (rv == False) {
01331                                    goto discard;
01332                             }
01333 #if defined(DEBUG_XAUX)
01334 fprintf(stderr, "(%s) SETV: sent up to string[%d]\n", xc->shortname, i - 1);
01335 #endif /* defined(DEBUG_XAUX) */
01336                             str_next = i;
01337                             break;
01338                      } else {
01339                             /* put length */
01340                             *(CARD16 *)sp = len;
01341                             sp += sizeof (CARD16);
01342                             /* put string */
01343                             for (j = 0; j < len; j++) {
01344                                    *sp++ = *p++;
01345                             }
01346                             /* put padding */
01347                             for (j = 0; j < pn; j++) {
01348                                    *sp++ = 0U;
01349                             }
01350                      }
01351               }
01352 
01353               if (i < aux_ext_data->string_count) {
01354                      continue;
01355               }
01356 
01357               XS_MORESEGS(propbuf) = 0;
01358               XS_SEGSIZE(propbuf) = (int)(sp - setv);
01359               rv = xaux_xs_send_property_setv(dpy, xc, propbuf);
01360               if (rv == False) {
01361                      goto discard;
01362               }
01363               break;
01364               /* NOTREACHED */
01365        }
01366 
01367 discard:
01368        xs_seqno++;
01369 
01370        return (rv);
01371 }
01372 
01373 xaux_ext_methods_t   xaux_ext_methods = {
01374        xaux_ext_open,
01375        xaux_ext_close,
01376        xaux_ext_registercb_start,
01377        xaux_ext_registercb_draw,
01378        xaux_ext_registercb_done,
01379        xaux_ext_setvalue,
01380        xaux_ext_registercb_addevhandler,
01381        xaux_ext_registercb_rmevhandler,
01382        NULL,
01383        NULL
01384 };