Back to index

im-sdk  12.3.91
xaux_so_common.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 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 "@(#)xaux_so_common.c 1.37 99/12/20"
00044 
00045 #include <stddef.h>
00046 #include <stdlib.h>
00047 #include <stdio.h>
00048 #include <sys/types.h>
00049 #include <unistd.h>
00050 #include <limits.h>
00051 #include <libgen.h>
00052 #include <sys/param.h>
00053 
00054 #include <X11/Xlib.h>
00055 #include <X11/Xatom.h>
00056 
00057 #include "iiimpAux.h"
00058 
00059 #include "xaux_common.h"
00060 #include "xaux_so_common.h"
00061 
00062 extern xaux_class_t xaux_classes[];
00063 
00064 static void          aux_icid_init(void);
00065 static void          aux_icid_finish(void);
00066 static aux_icid_t *  aux_icid_get(int, Bool);
00067 static void          aux_icid_delete(int);
00068 
00069 static int           aux_initialized = 0;
00070 
00071 #define HASH_SIZE 137
00072 static aux_icid_t    aux_icid[HASH_SIZE];
00073 
00074 /* workaround for "stored reference to aux_t is corrupred" problem */
00075 static void (*aux_setvalue)(aux_t *, const unsigned char *, int);
00076 static size_t (* mb_utf16)(const char **, size_t *, char **, size_t *);
00077 static unsigned char * (* compose)(const aux_data_t *, int *);
00078 static aux_t aux_tmp;
00079 
00080 static Bool xaux_so_Create(aux_t *);
00081 static Bool xaux_so_Start(aux_t *, const unsigned char *, int size);
00082 static Bool xaux_so_Draw(aux_t *, const unsigned char *, int size);
00083 static Bool xaux_so_Done(aux_t *, const unsigned char *, int size);
00084 static Bool xaux_so_Switched(aux_t *, int im_id, int on_off);
00085 static Bool xaux_so_Destroy(aux_t *);
00086 
00087 /* workaround_slowdtlogin */
00088 static Atom   atom_xbe = None;
00089 static Bool   is_server = False;
00090 /* workaround_slowdtlogin_end */
00091 
00092 aux_method_t xaux_so_methods = {
00093        xaux_so_Create,
00094        xaux_so_Start,
00095        xaux_so_Draw,
00096        xaux_so_Done,
00097        xaux_so_Switched,
00098        xaux_so_Destroy
00099 };
00100 
00101 static xaux_class_t *
00102 xaux_getclass_byatomxs(Atom atom)
00103 {
00104        xaux_class_t  *p = xaux_classes;
00105 
00106        while (p->classname != NULL) {
00107               if (p->atom_xs[0] == atom)
00108                      return (p);
00109               p++;
00110        }
00111 
00112        return (NULL);
00113 }
00114 
00115 static xaux_class_t *
00116 xaux_getclass_byutfname(
00117        const CARD16 *       utfname,
00118        size_t        len)
00119 {
00120        xaux_class_t  *p = xaux_classes;
00121 
00122        while (p->classname != NULL) {
00123               if (memcmp(p->utfname, utfname, len) == 0) {
00124                      return p;
00125               }
00126               p++;
00127        }
00128 
00129        return NULL;
00130 }
00131 
00132 static Bool
00133 xaux_so_get_extwin(
00134        xaux_class_t  *xc,
00135        Display              *display)
00136 {
00137        size_t        i;
00138 
00139        if (xc->atom_extwin == (Atom)None) {
00140               return False;
00141        }
00142 
00143        xc->extwin = XGetSelectionOwner(display, xc->atom_extwin);
00144        if (xc->extwin == None) {
00145 
00146               if (XAUX_MAXRETRY_EXTWIN <= 0) {
00147                      return False;
00148               }
00149 
00150               /* workaround_slowdtlogin */
00151               if (is_server == False) {
00152                      Window w;
00153 
00154                      if (atom_xbe == None) {
00155                             xc->atom_extwin = (Atom)None;
00156                             return False;
00157                      }
00158                      w = XGetSelectionOwner(display, atom_xbe);
00159                      if (w == None) {
00160                             xc->atom_extwin = (Atom)None;
00161                             return False;
00162                      }
00163               }
00164               /* workaround_slowdtlogin_end */
00165 
00166               sleep(XAUX_RETRYINT_EXTWIN);
00167 
00168               xc->extwin = XGetSelectionOwner(display, xc->atom_extwin);
00169               if (xc->extwin != None)
00170                      return True;
00171 
00172               return False;
00173        }
00174        return True;
00175 }
00176 
00177 static Bool
00178 xaux_so_launch_ext(
00179        xaux_class_t  *xc,
00180        aux_t         *aux
00181 )
00182 {
00183        pid_t         pid;
00184        const char    *ext = xc->extexec;
00185 
00186        if (xc->atom_extwin == (Atom)0) {
00187               return False;
00188        }
00189 
00190        if (xaux_so_get_extwin(xc, aux->service->display(aux)) == True) {
00191               /*
00192                * succeeded in communicating
00193                * with already running external program
00194                * no need to launch external program
00195                */
00196               return True;
00197        }
00198 
00199        if (aux->service->server(aux) == False) {
00200               /*
00201                * do not launch external program
00202                * if not loaded by server (htt_xbe) program
00203                */
00204               return False;
00205        }
00206 
00207        if (access(ext, X_OK) != 0) {
00208 #if defined(DEBUG_XAUX)
00209               fprintf(stderr, "executable \"%s\" not found\n", ext);
00210 #endif /* defined(DEBUG_XAUX) */
00211               /* no use to try to get extwin */
00212               xc->atom_extwin = (Atom)0;
00213               return False;
00214        }
00215                      
00216 #ifdef sun
00217        pid = fork1();
00218 #else
00219        pid = fork();
00220 #endif
00221 
00222        if (pid == (pid_t)(-1)) { /* fork failed */
00223               return False;
00224        } else if (0 == pid) { /* child */
00225 #if defined(DEBUG_XAUX)
00226               chdir("/tmp");
00227 #endif /* defined(DEBUG_XAUX) */
00228               execl(ext, xc->classname, NULL);
00229               _exit(1);
00230        }
00231        
00232        /* parent */
00233        return True;
00234 }
00235 
00236 static Bool
00237 xaux_so_send_message_detour_to_prop(
00238        aux_t *                     aux,
00239        xaux_class_t *              xc,
00240        int                  im_id,
00241        int                  ic_id,
00242        aux_data_type_t             type)
00243 {
00244        Display *            display;
00245        char                 string_buf[1024];
00246 
00247        display = aux->service->display(aux);
00248 
00249        SX_PROP_ATOM_AUX_NAME(string_buf) = xc->atom_classname;
00250        SX_PROP_TYPE(string_buf) = type;
00251        SX_PROP_INDEX(string_buf) = xc->index;
00252        SX_PROP_IMID(string_buf) = im_id;
00253        SX_PROP_ICID(string_buf) = ic_id;
00254 
00255        XChangeProperty(display, xc->sowin,
00256               xc->atom_sx[xc->atom_sx_idx], XA_STRING,
00257               8, PropModeReplace, (unsigned char *)(&string_buf),
00258               SX_SIZE_PROP_STARTDONE);
00259 
00260        /* needed in en_US.UTF-8 */
00261         XFlush(display);
00262 
00263        if (++xc->atom_sx_idx == XAUX_SX_NATOMS)
00264               xc->atom_sx_idx = 1;
00265        
00266        return True;
00267 }
00268 
00269 static Bool
00270 xaux_so_send_message(
00271        aux_t *              aux,
00272        xaux_class_t *       xc,
00273        int           im_id,
00274        int           ic_id,
00275        aux_data_type_t      type,
00276        Atom          atom)
00277 {
00278        Display *            display;
00279        XClientMessageEvent  event;
00280 
00281        display = aux->service->display(aux);
00282 
00283        if ((xc->extwin == None) &&
00284               (xaux_so_get_extwin(xc, display) == False)) {
00285               /* cannot get extwin */
00286               if (xc->atom_extwin == (Atom)None) {
00287                      return False;
00288               } else {
00289                      if (type == AUX_DATA_DRAW) {
00290                             return True;
00291                      } else {
00292                             return xaux_so_send_message_detour_to_prop(
00293                                    aux, xc, im_id, ic_id, type);
00294                      }
00295               }
00296        }
00297               
00298        event.type = ClientMessage;
00299        event.serial = 0;
00300        event.send_event = True;
00301        event.display = display;
00302        event.window = xc->extwin;
00303        event.message_type = xc->atom_sx[0];
00304        event.format = 32;
00305 
00306        event.data.l[0] = xc->atom_classname;
00307        event.data.l[1] = ((CARD32)im_id << 16) | ((CARD32)ic_id & 0xffff);
00308        event.data.l[2] = xc->index;
00309        event.data.l[3] = type; /* CREATE, DONE, ... */
00310        if (type == AUX_DATA_DRAW) {
00311               event.data.l[4] = atom;
00312        } else {
00313               event.data.l[4] = 0; /* unused */
00314        }
00315 
00316        XSendEvent(display, xc->extwin, True, 0, (XEvent *)(&event));
00317 
00318        /* needed in en_US.UTF-8 */
00319         XFlush(display);
00320 
00321        return True;
00322 }
00323 
00324 static Bool
00325 xaux_so_send_property(
00326        aux_t *                     aux,
00327        xaux_class_t *              xc,
00328        const unsigned char *       p,
00329        int                  len)
00330 {
00331        Display *     display;
00332        int           i = 1;
00333        Bool          rv;
00334        Window        win;
00335 
00336        display = aux->service->display(aux);
00337 
00338        if ((xc->extwin == None) &&
00339               (xaux_so_get_extwin(xc, display) == False) &&
00340               (xc->atom_extwin == (Atom)None)) {
00341               return False;
00342        }
00343 
00344        win = (xc->extwin != (Window)None) ? xc->extwin : xc->sowin;
00345 
00346        XChangeProperty(display, win,
00347               xc->atom_sx[xc->atom_sx_idx], XA_STRING,
00348               8, PropModeReplace, (unsigned char *)p, len);
00349 
00350        if (xaux_so_send_message(aux, xc,
00351               aux->service->im_id(aux), aux->service->ic_id(aux),
00352               AUX_DATA_DRAW, xc->atom_sx[xc->atom_sx_idx]) == False) {
00353                      return False;
00354        }
00355 
00356        /* XFlush() has been called in xaux_so_send_message() */
00357        
00358        if (++xc->atom_sx_idx == XAUX_SX_NATOMS)
00359               xc->atom_sx_idx = 1;
00360        
00361        return True;
00362 }
00363 
00364 static Bool
00365 xaux_so_process_property_update(
00366        Display       *             display,
00367        Window               window,
00368        Atom                 atom,
00369        xaux_class_t *              xc)
00370 {
00371        Atom          actual_type_return;
00372        int           actual_format_return;
00373        unsigned long nitem_return;
00374        unsigned long bytes_after_return;
00375        unsigned char *      prop_return;
00376        int           r;
00377 /*
00378        aux_icid_t *  ic;
00379 */
00380        int           size;
00381        aux_data_t    aux_data_;
00382        aux_data_t *  aux_data = &(aux_data_);
00383        unsigned char *      p;
00384        int           i;
00385        int           n=0;
00386 
00387        r = XGetWindowProperty(display, window,
00388                             atom, 0, INT_MAX, False,
00389                             AnyPropertyType, &actual_type_return,
00390                             &actual_format_return, &nitem_return,
00391                             &bytes_after_return, &prop_return);
00392 
00393        if (r != Success) {
00394               return False;
00395        }
00396 
00397 /*
00398        if ((ic = aux_icid_get(XS_PROP_ICID(prop_return), False)) == NULL) {
00399               XFree(prop_return);
00400               return False;
00401        }
00402 */
00403 
00404        /* header */
00405 
00406        aux_data->type = AUX_DATA_SETVALUE;
00407        aux_data->im = XS_PROP_IMID(prop_return);
00408        aux_data->ic = XS_PROP_ICID(prop_return);
00409        aux_data->aux_index = xc->index;
00410        aux_data->aux_name = (unsigned char *)xc->utfname;
00411        aux_data->aux_name_length = strlen(xc->classname)*sizeof(CARD16);
00412 
00413        /* int values */
00414 
00415        aux_data->integer_count = XS_PROP_INT_COUNT(prop_return);
00416 
00417        if (aux_data->integer_count > 0) {
00418               aux_data->integer_list = (int *)XS_PROP_INT_LIST(prop_return);
00419        } else {
00420               aux_data->integer_list = NULL;
00421        }
00422 
00423        /* string values */
00424 
00425        aux_data->string_count = XS_PROP_STR_COUNT(prop_return);
00426 
00427        if (aux_data->string_count > 0) {
00428               unsigned char * prop_str = XS_PROP_STR_LIST(prop_return);
00429               char *        outbuf;
00430               size_t        outbufsiz;
00431 
00432               if ((aux_data->string_list =
00433                      (aux_string_t *)malloc(sizeof (aux_string_t) *
00434                             aux_data->string_count)) == NULL) {
00435                             XFree(prop_return);
00436                             return False;
00437               }
00438 
00439               for (i = 0; i < aux_data->string_count; i++) {
00440                      int    j;
00441                      int    pn;
00442                      size_t len;
00443 
00444                      len = *((CARD16 *)(prop_str));
00445                      prop_str += sizeof (CARD16);
00446                      aux_data->string_list[i].ptr = prop_str;
00447                      aux_data->string_list[i].length = len;
00448                      prop_str += len;
00449                      pn = padding[(sizeof(CARD16) + len) % 4];
00450                      for (j = 0; j < pn; j++) {
00451                             *prop_str++ = 0U;
00452                      }
00453               }
00454        } else {
00455               aux_data->string_list = NULL;
00456        }
00457 
00458        aux_data->string_ptr = NULL;
00459 
00460        /* compose and send message to engine */
00461 
00462 /* workaround for "stored reference to aux_t is corrupred" problem */
00463        if ((p = /*ic->aux->service->*/compose(aux_data, &size)) == NULL) {
00464               free(aux_data->string_list);
00465               XFree(prop_return);
00466               return False;
00467        }
00468 
00469 #if defined(DEBUG_XAUX)
00470        fprintf(stderr, "so_SetValue[%s] im:0x%x ic:0x%x in=%d sn=%d\n",
00471               xc->classname, aux_data->im, aux_data->ic,
00472               aux_data->integer_count, aux_data->string_count);
00473 #endif /* defined(DEBUG_XAUX) */
00474 
00475 /* workaround for "stored reference to aux_t is corrupred" problem */
00476        /*ic->aux->service->*/aux_setvalue(/*ic->aux*/&aux_tmp, p, size);
00477 
00478        free(p);
00479        free(aux_data->string_list);
00480        XFree(prop_return);
00481 
00482        return True;
00483 }
00484 
00485 static Bool
00486 xaux_so_process_client_message(
00487        Display       *             display,
00488        Window               window,
00489        XClientMessageEvent *       event)
00490 {
00491        aux_data_t    aux_data_;
00492        aux_data_t    *aux_data = &(aux_data_);
00493        aux_data_type_t      type;
00494        xaux_class_t  *xc;
00495 
00496        if ((xc = xaux_getclass_byatomxs(event->message_type)) == NULL) {
00497               return False;
00498        }
00499 
00500        aux_data->im = ((CARD32)(event->data.l[1])) >> 16;
00501        aux_data->ic = ((CARD32)(event->data.l[1])) & 0xffff;
00502        aux_data->aux_index = (CARD32)(event->data.l[2]);
00503 
00504        type = (CARD32)(event->data.l[3]);
00505 
00506        switch (type) {
00507        case AUX_DATA_SETVALUE:
00508               return xaux_so_process_property_update(display, window,
00509                             (Atom)(event->data.l[4]), xc);
00510        default:
00511               return False;
00512        }
00513 }
00514 
00515 static Bool
00516 xaux_so_event_filter(
00517        Display *     display,
00518        Window        window,
00519        XEvent *      event,
00520        XPointer      pointer)
00521 {
00522        switch (event->type) {
00523        case ClientMessage:
00524               return (xaux_so_process_client_message(display, window,
00525                      (XClientMessageEvent *)event));
00526        }
00527        return False;
00528 }
00529 
00530 static void
00531 aux_icid_init(void)
00532 {
00533        int    i;
00534 
00535        for (i = 0; i < HASH_SIZE; i++) {
00536               aux_icid[i].icid = (-1);
00537        }
00538 }
00539 
00540 static void
00541 aux_icid_finish(void)
00542 {
00543        int           i;
00544        aux_icid_t *  p0;
00545        aux_icid_t *  p1;
00546 
00547        for (i = 0; i < HASH_SIZE; i++) {
00548               p0 = aux_icid[i].next;
00549 
00550               for (; p0 != NULL; p0 = p1) {
00551                      p1 = p0->next;
00552                      free(p0);
00553               }
00554        }
00555 }
00556 
00557 static aux_icid_t *
00558 aux_icid_get(
00559        int    icID,
00560        Bool   createit)
00561 {
00562        int           hash_value;
00563        aux_icid_t *  p;
00564 
00565        p = &(aux_icid[icID % HASH_SIZE]);
00566 
00567        if (p->icid == -1) {
00568               if (!createit)
00569                      return NULL;
00570               p->icid = icID;
00571               return (p);
00572        }
00573 
00574        for (; ; p = p->next) {
00575               if (icID == p->icid) {
00576                      return p;
00577               }
00578               if (p->next == NULL) {
00579                      if (!createit)
00580                             return NULL;
00581                      p->next = malloc(sizeof (aux_icid_t));
00582                      if (p->next == NULL) {
00583                             return NULL;
00584                      }
00585                      memset(p->next, 0, (sizeof (aux_icid_t)));
00586                      p->next->prev = p;
00587                      p->next->next = NULL;
00588                      p->next->icid = icID;
00589                      return (p->next);
00590               }
00591        }
00592 }
00593 
00594 static void
00595 aux_icid_delete(int icID)
00596 {
00597        aux_icid_t *  p;
00598 
00599        p = aux_icid_get(icID, False);
00600 
00601        if (NULL == p) {
00602               return;
00603        }
00604 
00605        p->icid = -1;
00606 
00607        if (p->next != NULL) {
00608               p->next->prev = p->prev;
00609        }
00610        if (p->prev != NULL) {
00611               p->prev->next = p->next;
00612               free(p);
00613        }
00614 }
00615 
00616 static Bool
00617 xaux_so_init_classes(aux_t * aux)
00618 {
00619        Display *     display;
00620        char          buf[XAUX_MAXCLASSNAMELEN + XAUX_MAXSUFFIXLEN + 1];
00621        int           i;
00622 
00623        xaux_class_t *p = xaux_classes;
00624 
00625        display = aux->service->display(aux);
00626 
00627        /* workaround_slowdtlogin */
00628        atom_xbe = XInternAtom(display, "xaux_xbe", False);
00629 
00630        is_server = aux->service->server(aux);
00631 
00632        if (is_server == True && atom_xbe != None) {
00633               XSetSelectionOwner(display, atom_xbe,
00634                             DefaultRootWindow(display), CurrentTime);
00635        }
00636        /* workaround_slowdtlogin_end */
00637 
00638        while (p->classname != NULL) {
00639               p->atom_classname = XInternAtom(display, p->classname, False);
00640 
00641               sprintf(buf, "%s%s", p->classname, XAUX_SOWIN_SUFFIX);
00642               p->atom_sowin = XInternAtom(display, buf, False);
00643 
00644               sprintf(buf, "%s%s", p->classname, XAUX_EXTWIN_SUFFIX);
00645               p->atom_extwin = XInternAtom(display, buf, False);
00646 
00647               for (i = 0; i < XAUX_SX_NATOMS; i++) {
00648                      sprintf(buf, "%s%s_%d",
00649                             p->classname, XAUX_SX_SUFFIX, i);
00650                      p->atom_sx[i] = XInternAtom(display, buf, False);
00651               }
00652               p->atom_sx_idx = 1;
00653 
00654               for (i = 0; i < XAUX_XS_NATOMS; i++) {
00655                      sprintf(buf, "%s%s_%d",
00656                             p->classname, XAUX_XS_SUFFIX, i);
00657                      p->atom_xs[i] = XInternAtom(display, buf, False);
00658               }
00659               p->atom_xs_idx = 1;
00660 
00661               if (XGetSelectionOwner(display, p->atom_sowin) != None) {
00662 #if defined(DEBUG_XAUX)
00663                      fprintf(stderr, "%s: %s already exists. [%s](1)\n",
00664                             ME_SO, ME_SO, p->classname);
00665 #endif /* defined(DEBUG_XAUX) */
00666                      goto done_sowin;
00667               }
00668 
00669               p->sowin = XCreateSimpleWindow(display, RootWindow(display, 0),
00670                           0, 0, 1, 1, 0, 0, 0);
00671 
00672               if (p->sowin == None) {
00673                      fprintf(stderr,
00674                             "%s: creating window for \"%s\" failed.\n",
00675                             ME_SO, p->classname);
00676                      goto done_sowin;
00677               }
00678 
00679                XSelectInput(display, p->sowin, PropertyChangeMask);
00680 
00681                aux->service->register_X_filter(display, p->sowin,
00682                      ClientMessage, ClientMessage,
00683                      xaux_so_event_filter, NULL);
00684 
00685               XSetSelectionOwner(display,
00686                      p->atom_sowin, p->sowin, CurrentTime);
00687 
00688               if (XGetSelectionOwner(display, p->atom_sowin) != p->sowin) {
00689                      fprintf(stderr, "%s: %s already exists.[%s](2)\n",
00690                             ME_SO, ME_SO, p->classname);
00691                      XDestroyWindow(display, p->sowin);
00692                      p->sowin = (Window)0;
00693                      goto done_sowin;
00694               }
00695 
00696 done_sowin:
00697               p->extwin = (Window)0;
00698 
00699               p++;
00700        }
00701 
00702        return True;
00703 }
00704 
00705 static Bool
00706 xaux_so_Create(aux_t * aux)
00707 {
00708        int           i;
00709        pid_t         pid;
00710        aux_icid_t *  aux_icid;
00711 
00712        if (0 == aux_initialized) {
00713               aux_icid_init();
00714        }
00715 
00716        if (NULL == (aux_icid = aux_icid_get(aux->service->ic_id(aux), True))) {
00717               return False;
00718        }
00719 
00720        aux_icid->aux = aux;
00721 
00722 /* workaround for "stored reference to aux_t is corrupred" problem */
00723 aux_tmp.ic = aux->ic;
00724 aux_setvalue = aux_icid->aux->service->aux_setvalue;
00725 mb_utf16 = aux_icid->aux->service->mb_utf16;
00726 compose = aux_icid->aux->service->compose;
00727 
00728        if (aux_initialized == 0) {
00729               xaux_so_init_classes(aux);
00730               aux_initialized = 1;
00731        }
00732 
00733        return True;
00734 }
00735 
00736 static Bool
00737 xaux_so_Start(aux_t * aux, const unsigned char * p, int size)
00738 {
00739        aux_data_t *  aux_data;
00740        xaux_class_t *       xc;
00741        Bool          rv;
00742 
00743        aux_data = aux->service->decompose(AUX_DATA_START, p);
00744 
00745        if ((xc = xaux_getclass_byutfname(
00746               (const CARD16 *)aux_data->aux_name,
00747               aux_data->aux_name_length)) == NULL) {
00748               aux->service->decompose_free(aux_data);
00749               return False;
00750        }
00751 
00752        if (xc->extwin == (Window)None
00753               && xaux_so_launch_ext(xc, aux) == False) {
00754               fprintf(stderr,
00755                      "cannot communicatie with external program [%s]",
00756                      xc->classname);
00757               aux->service->decompose_free(aux_data);
00758               return False;
00759        }
00760 
00761 #if defined(DEBUG_XAUX)
00762        fprintf(stderr, "so_Start[%s] im:0x%x ic:0x%x\n",
00763               xc->classname, aux_data->im, aux_data->ic);
00764 #endif /* defined(DEBUG_XAUX) */
00765 
00766        rv = xaux_so_send_message(aux, xc, aux_data->im, aux_data->ic,
00767               AUX_DATA_START, (Atom)0);
00768 
00769        aux->service->decompose_free(aux_data);
00770 
00771        return (rv);
00772 }
00773 
00774 static Bool
00775 xaux_so_Draw(aux_t * aux, const unsigned char * p, int size)
00776 {
00777        aux_data_t *  aux_data;
00778        XPoint        point;
00779        char *        string_buf;
00780        xaux_class_t *       xc;
00781        size_t        i;
00782        int           *ip;
00783        char          *sp;
00784        Bool          rv = True;
00785        size_t        total;
00786 
00787 
00788        aux_data = aux->service->decompose(AUX_DATA_DRAW, p);
00789 
00790        if ((xc = xaux_getclass_byutfname(
00791               (const CARD16 *)aux_data->aux_name,
00792               aux_data->aux_name_length)) == NULL) {
00793               aux->service->decompose_free(aux_data);
00794               return False;
00795        }
00796 
00797        /* estimate enough size for string_buf */
00798 
00799        /* size for header */
00800        total = SX_SIZE_PROP_HEADER_DRAW;
00801 
00802        /* add size for integer_values */
00803        total += (sizeof (CARD32) * aux_data->integer_count);
00804 
00805        /* add size for string_values */
00806        if (aux_data->string_count > 0) {
00807               for (i = 0; i < aux_data->string_count; i++) {
00808                      size_t len;
00809 
00810                      /* number of bytes */
00811                      len = aux_data->string_list[i].length;
00812 
00813                      /* consider padding */
00814                      total +=
00815                      ((sizeof (CARD16) + len + 3) / 4) * 4;
00816               }
00817        }
00818 
00819        if ((string_buf = (char *)malloc(total)) == NULL) {
00820               aux->service->decompose_free(aux_data);
00821 
00822               return False;
00823        }
00824 
00825        SX_PROP_ATOM_AUX_NAME(string_buf) = xc->atom_classname;
00826        SX_PROP_TYPE(string_buf) = AUX_DATA_DRAW;
00827        SX_PROP_INDEX(string_buf) = xc->index;
00828        SX_PROP_IMID(string_buf) = aux_data->im;
00829        SX_PROP_ICID(string_buf) = aux_data->ic;
00830        SX_PROP_SOWIN(string_buf) = xc->sowin;
00831 
00832        SX_PROP_CLIENTWIN(string_buf) = aux->service->client_window(aux);
00833 
00834        aux->service->point(aux, &point);
00835        SX_PROP_POSX(string_buf) = point.x;
00836        SX_PROP_POSY(string_buf) = point.y;
00837 
00838        SX_PROP_FOCUSWIN(string_buf) = aux->service->window(aux);
00839 
00840        SX_PROP_INT_COUNT(string_buf) = aux_data->integer_count;
00841        SX_PROP_STR_COUNT(string_buf) = aux_data->string_count;
00842 
00843        ip = (int *)SX_PROP_INT_LIST(string_buf);
00844 
00845        if (aux_data->integer_count > 0) {
00846 
00847               for (i = 0; i < aux_data->integer_count; i++) {
00848                      *ip++ = aux_data->integer_list[i];
00849               }
00850        }
00851 
00852        sp = (char *)SX_PROP_STR_LIST(string_buf);
00853 
00854        if (aux_data->string_count > 0) {
00855               char *        ob;
00856               size_t        obl;
00857 
00858               ob = sp;
00859 
00860               for (i = 0; i < aux_data->string_count; i++) {
00861                      size_t        len;
00862                      int           pn;
00863                      unsigned char *p;
00864                      size_t        j;
00865 
00866                      len = aux_data->string_list[i].length;
00867                      p = aux_data->string_list[i].ptr;
00868 
00869                      *(CARD16 *)ob = len;
00870                      ob += sizeof (CARD16);
00871 
00872                      for (j = 0; j < len; j++) {
00873                             *ob++ = *p++;
00874                      }
00875                             
00876                      pn = padding[(sizeof (CARD16) + len) % 4];
00877 
00878                      /* padding */
00879                      for (j = 0; j < pn; j++) {
00880                             *ob++ = 0U;
00881                      }
00882                      sp = ob;
00883               }
00884        }
00885 
00886 #if defined(DEBUG_XAUX)
00887        fprintf(stderr, "so_Draw[%s] im:0x%x ic:0x%x in=%d sn=%d\n",
00888               xc->classname, aux_data->im, aux_data->ic,
00889               aux_data->integer_count, aux_data->string_count);
00890        fprintf(stderr, "total = %d\n", total);
00891 #endif /* defined(DEBUG_XAUX) */
00892 
00893        if (aux_data->integer_count != 0 || aux_data->string_count != 0) {
00894               rv = xaux_so_send_property(aux, xc,
00895                      (unsigned char *)string_buf, (sp - &(string_buf[0])));
00896        }
00897 
00898        aux->service->decompose_free(aux_data);
00899        free(string_buf);
00900 
00901        return (rv);
00902 }
00903 
00904 static Bool
00905 xaux_so_Done(aux_t * aux, const unsigned char * p, int size)
00906 {
00907        aux_data_t    * aux_data;
00908        xaux_class_t *       xc;
00909        Bool          rv;
00910 
00911        aux_data = aux->service->decompose(AUX_DATA_DONE, p);
00912 
00913        if ((xc = xaux_getclass_byutfname(
00914               (const CARD16 *)aux_data->aux_name,
00915               aux_data->aux_name_length)) == NULL) {
00916               aux->service->decompose_free(aux_data);
00917               return False;
00918        }
00919 
00920 #if defined(DEBUG_XAUX)
00921        fprintf(stderr, "so_Done[%s] im:0x%x ic:0x%x\n",
00922               xc->classname, aux_data->im, aux_data->ic);
00923 #endif /* defined(DEBUG_XAUX) */
00924 
00925        rv = xaux_so_send_message(aux, xc, aux_data->im, aux_data->ic,
00926               AUX_DATA_DONE, (Atom)0);
00927 
00928        aux->service->decompose_free(aux_data);
00929 
00930        return (rv);
00931 
00932 }
00933 
00934 static Bool
00935 xaux_so_Switched(aux_t * aux, int im_id, int on_off)
00936 {
00937        return True;
00938 }
00939 
00940 static Bool
00941 xaux_so_Destroy(aux_t * aux)
00942 {
00943        return True;
00944 }