Back to index

im-sdk  12.3.91
xaux_ext_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 #pragma ident "@(#)xaux_ext_common.c 1.21 99/12/08"
00043 
00044 #include <locale.h>
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <limits.h>
00048 
00049 #include <X11/X.h>
00050 #include <X11/Xatom.h>
00051 
00052 #include "trace_message.h"
00053 
00054 #include "iiimpAux.h"
00055 #include "xaux_common.h"
00056 #include "xaux_ext_common.h"
00057 
00058 /* from iiimpAux.c */
00059 size_t
00060 utf16_mb(
00061         const char **   inbuf,
00062         size_t *        inbytesleft,
00063         char **         outbuf,
00064         size_t *        outbytesleft)
00065 {
00066         int     r;
00067 
00068         r = IIimpConvertFromUTF16((char *)(*inbuf), *inbytesleft,
00069                                   outbuf, outbytesleft);
00070         return (size_t)r;
00071 }
00072 
00073 size_t
00074 mb_utf16(
00075         const char **   inbuf,
00076         size_t *        inbytesleft,
00077         char **         outbuf,
00078         size_t *        outbytesleft)
00079 {
00080         int     r;
00081 
00082         r = IIimpConvertToUTF16((char *)(*inbuf), *inbytesleft,
00083                                   outbuf, outbytesleft);
00084         return (size_t)r;
00085 }
00086 
00087 
00088 static Bool
00089 xaux_xs_get_sowin(
00090        xaux_class_t  *xc,
00091        Display              *display)
00092 {
00093        size_t        i;
00094 
00095 
00096        xc->sowin = XGetSelectionOwner(display, xc->atom_sowin);
00097 
00098        if (xc->sowin == None)
00099               return False;
00100        else
00101               return True;
00102 }
00103 
00104 static Bool
00105 xaux_xs_send_property(
00106        Display *            display,
00107        xaux_class_t *              xc,
00108        int                  im_id,
00109        int                  ic_id,
00110        const unsigned char *       p,
00111        int                  len)
00112 {
00113        if ((xc->sowin == None) &&
00114               (xaux_xs_get_sowin(xc, display) == False)) {
00115               return False;
00116        }
00117 
00118        XChangeProperty(display, xc->sowin,
00119               xc->atom_xs[xc->atom_xs_idx], XA_STRING,
00120               8, PropModeReplace, (unsigned char *)p, len);
00121 
00122        if (xaux_xs_send_message(display, xc, im_id, ic_id,
00123               AUX_EXT_DATA_SETVALUE, xc->atom_xs[xc->atom_xs_idx]) == False) {
00124                      return False;
00125        }
00126 
00127        /* XFlush() has been called in xaux_xs_send_message() */
00128 
00129        if (++xc->atom_xs_idx == XAUX_XS_NATOMS)
00130               xc->atom_xs_idx = 1;
00131        
00132        return True;
00133 }
00134 
00135 Bool
00136 xaux_xs_send_message(
00137        Display *     display,
00138        xaux_class_t *       xc,
00139        int           im_id,
00140        int           ic_id,
00141        aux_ext_data_type_t  type,
00142        Atom          atom)
00143 {
00144        XClientMessageEvent  event;
00145 
00146        if ((xc->sowin == None) &&
00147               (xaux_xs_get_sowin(xc, display) == False)) {
00148               return False;
00149        }
00150               
00151        event.type = ClientMessage;
00152        event.serial = 0;
00153        event.send_event = True;
00154        event.display = display;
00155        event.window = xc->sowin;
00156        event.message_type = xc->atom_xs[0];
00157        event.format = 32;
00158 
00159        event.data.l[0] = xc->atom_classname;
00160        event.data.l[1] = ((CARD16)im_id << 8) | ((CARD16)ic_id & 0xffff);
00161        event.data.l[2] = xc->index;
00162        event.data.l[3] = type;
00163        if (type == AUX_EXT_DATA_SETVALUE) {
00164               event.data.l[4] = atom;
00165        } else {
00166               event.data.l[4] = 0; /* unused */
00167        }
00168 
00169        XSendEvent(display, xc->sowin, True, 0, (XEvent *)(&event));
00170 
00171        XFlush(display);
00172 
00173        return True;
00174 }
00175 
00176 static Bool
00177 xaux_ext_process_property_update(
00178        Display       *             display,
00179        Window               window,
00180        Atom                 atom)
00181 {
00182        Atom          actual_type_return;
00183        int           actual_format_return;
00184        unsigned long nitem_return;
00185        unsigned long bytes_after_return;
00186        unsigned char *      prop_return;
00187        int           r;
00188        int           imid;
00189        int           size;
00190        aux_ext_data_t       aux_ext_data_;
00191        aux_ext_data_t *     aux_ext_data = &(aux_ext_data_);
00192        unsigned char *      p;
00193        int           i;
00194        int           n=0;
00195        xaux_class_t  *xc = &xaux_class;
00196        XPoint        point;
00197        Bool          rv;
00198        int           type;
00199        char *        outbuf_ = NULL;
00200 
00201        if (window != xc->extwin && window != xc->sowin) {
00202               return False;
00203        }
00204 
00205        r = XGetWindowProperty(display, window,
00206                             atom, 0, INT_MAX, False,
00207                             AnyPropertyType, &actual_type_return,
00208                             &actual_format_return, &nitem_return,
00209                             &bytes_after_return, &prop_return);
00210 
00211        if (r != Success || actual_type_return == 0) {
00212               return False;
00213        }
00214 
00215        type = SX_PROP_TYPE(prop_return);
00216 
00217        /* ClientMessage detoured to property, due to extwin not
00218           available yet */
00219        if (type == AUX_DATA_START || type == AUX_DATA_DONE) {
00220               aux_ext_data_t       aux_ext_data_;
00221               aux_ext_data_t       *aux_ext_data = &(aux_ext_data_);
00222               xaux_class_t  *xc = &xaux_class;
00223 
00224               if (SX_PROP_ATOM_AUX_NAME(prop_return) != xc->atom_classname) {
00225                      return False;
00226               }
00227 
00228               aux_ext_data->im = SX_PROP_IMID(prop_return);
00229               aux_ext_data->ic = SX_PROP_ICID(prop_return);
00230               aux_ext_data->aux_index = SX_PROP_INDEX(prop_return);
00231 
00232               switch (type) {
00233               case AUX_EXT_DATA_START:
00234 #if defined(DEBUG_XAUX)
00235                      fprintf(stderr, "[%s] received START via property\n",
00236                             xc->classname);
00237 #endif /* defined(DEBUG_XAUX) */
00238                      return xaux_ext_Start(xc, aux_ext_data);
00239                      break;
00240               case AUX_EXT_DATA_DONE:
00241 #if defined(DEBUG_XAUX)
00242                      fprintf(stderr, "[%s] received DONE via property\n",
00243                             xc->classname);
00244 #endif /* defined(DEBUG_XAUX) */
00245                      return xaux_ext_Done(xc, aux_ext_data);
00246                      break;
00247               default:
00248                      return False;
00249               }
00250        }
00251 
00252        /* header */
00253 
00254        aux_ext_data->type = AUX_EXT_DATA_DRAW;
00255        aux_ext_data->im = SX_PROP_IMID(prop_return);
00256        aux_ext_data->ic = SX_PROP_ICID(prop_return);
00257        aux_ext_data->aux_index = xc->index;
00258        aux_ext_data->aux_name = (unsigned char *)xc->classname;
00259        aux_ext_data->aux_name_length =
00260               strlen((const char *)aux_ext_data->aux_name);
00261 
00262        /* int values */
00263 
00264        aux_ext_data->integer_count = SX_PROP_INT_COUNT(prop_return);
00265 
00266        if (aux_ext_data->integer_count > 0) {
00267               aux_ext_data->integer_list =
00268                      (int *)SX_PROP_INT_LIST(prop_return);
00269        } else {
00270               aux_ext_data->integer_list = NULL;
00271        }
00272 
00273        /* string values */
00274 
00275        aux_ext_data->string_count = SX_PROP_STR_COUNT(prop_return);
00276 
00277        if (aux_ext_data->string_count > 0) {
00278               unsigned char * prop_str = SX_PROP_STR_LIST(prop_return);
00279               char *        outbuf;
00280               size_t        outbufsiz, c;
00281 
00282               if ((aux_ext_data->string_list =
00283                      (aux_ext_string_t *)malloc(sizeof (aux_ext_string_t) *
00284                             aux_ext_data->string_count)) == NULL) {
00285                             XFree(prop_return);
00286                             return False;
00287               }
00288 
00289               /*
00290                * to make calcuration easier, assume no padding
00291                * so allocated area can be larger than needed
00292                */
00293               /* total bytes of the property */
00294               c  = nitem_return; 
00295               /* total bytes used for string_values in the property  */
00296               c -= SX_PROP_STR_LIST(prop_return) - prop_return;
00297               /* eliminate area for length values */
00298               c -= aux_ext_data->string_count * sizeof(CARD16);
00299               /* if all of the area is filled with UTF-16.... */
00300               c /= sizeof (CARD16);
00301               /* multiply with MB_CUR_MAX */
00302               c *= MB_CUR_MAX;
00303               /* for null termination of each string */
00304               c += aux_ext_data->string_count;
00305               outbufsiz = c;
00306 
00307               /* allocate outbuf_ */
00308               if ((outbuf_ = (char *)malloc(outbufsiz)) == NULL) {
00309                      free(aux_ext_data->string_list);
00310                      XFree(prop_return);
00311                      return False;
00312               }
00313 
00314               outbuf = &(outbuf_[0]);
00315 
00316               for(i = 0; i < aux_ext_data->string_count; i++) {
00317                      char *        ib;
00318                      char *        ob;
00319                      size_t        ibl;
00320                      size_t        obl = outbufsiz;
00321                      size_t        obl_save;
00322 
00323                      /* assign length of a string to ibl */
00324                      ibl = (size_t)*((CARD16 *)(prop_str));
00325                      /* move prop_str to point head of the string */
00326                      prop_str += sizeof(CARD16);
00327                      /* assign head of the string to ib */
00328                      ib = (char *)prop_str;
00329                      /* move prop_str to point lenght of next string */
00330                      prop_str += (ibl + padding[(sizeof(CARD16) + ibl) % 4]);
00331 
00332                      ob = outbuf;
00333                      obl_save = obl;
00334 
00335                      aux_ext_data->string_list[i].ptr = (unsigned char *)ob;
00336 
00337                      utf16_mb((const char **)&ib, &ibl, &ob, &obl);
00338 
00339                      aux_ext_data->string_list[i].length = obl_save - obl;
00340                      outbuf = ob + aux_ext_data->string_list[i].length;
00341 
00342                      /* null termination */
00343                      *(outbuf++) = '\0';
00344               }
00345        } else {
00346               aux_ext_data->string_list = NULL;
00347        }
00348 
00349        aux_ext_data->string_ptr = NULL;
00350 
00351        aux_ext_data->clientwin = SX_PROP_CLIENTWIN(prop_return);
00352        aux_ext_data->point.x = SX_PROP_POSX(prop_return);
00353        aux_ext_data->point.y = SX_PROP_POSY(prop_return);
00354        aux_ext_data->focuswin = SX_PROP_FOCUSWIN(prop_return);
00355 
00356 #if defined(DEBUG_XAUX)
00357        fprintf(stderr, "[%s] received DRAW via property\n",
00358               xc->classname);
00359 #endif /* defined(DEBUG_XAUX) */
00360        rv = xaux_ext_Draw(xc, aux_ext_data);
00361 
00362        free(aux_ext_data->string_list);
00363        if (outbuf_ != NULL) {
00364               free(outbuf_);
00365        }
00366        XFree(prop_return);
00367 
00368        return rv;
00369 }
00370 
00371 Bool
00372 xaux_ext_process_client_message(
00373        Display       *             display,
00374        XClientMessageEvent *       event)
00375 {
00376        aux_ext_data_t       aux_ext_data_;
00377        aux_ext_data_t       *aux_ext_data = &(aux_ext_data_);
00378        aux_ext_data_type_t  type;
00379        xaux_class_t  *xc = &xaux_class;
00380 
00381        if (event->data.l[0] != xc->atom_classname) {
00382               return False;
00383        }
00384 
00385        if (event->message_type != xc->atom_sx[0]) {
00386               return False;
00387        }
00388 
00389        if (event->window != xc->extwin) {
00390               return False;
00391        }
00392 
00393        aux_ext_data->im = ((CARD32)(event->data.l[1])) >> 16;
00394        aux_ext_data->ic = ((CARD32)(event->data.l[1])) & 0xffff;
00395        aux_ext_data->aux_index = (CARD32)(event->data.l[2]);
00396 
00397        type = (CARD32)(event->data.l[3]);
00398 
00399        switch (type) {
00400        case AUX_EXT_DATA_START:
00401 #if defined(DEBUG_XAUX)
00402               fprintf(stderr, "[%s] received START via ClientMessage\n",
00403                      xc->classname);
00404 #endif /* defined(DEBUG_XAUX) */
00405               return xaux_ext_Start(xc, aux_ext_data);
00406               break;
00407        case AUX_EXT_DATA_DRAW:
00408 #if defined(DEBUG_XAUX)
00409               fprintf(stderr, "[%s] notified DRAW via ClientMessage\n",
00410                      xc->classname);
00411 #endif /* defined(DEBUG_XAUX) */
00412               return xaux_ext_process_property_update(
00413                      display, xc->extwin, (Atom)(CARD32)(event->data.l[4]));
00414        case AUX_EXT_DATA_DONE:
00415 #if defined(DEBUG_XAUX)
00416               fprintf(stderr, "[%s] received DONE via ClientMessage\n",
00417                      xc->classname);
00418 #endif /* defined(DEBUG_XAUX) */
00419               return xaux_ext_Done(xc, aux_ext_data);
00420               break;
00421        default:
00422               return False;
00423        }
00424 }
00425 
00426 Bool
00427 xaux_ext_init_classes(
00428        Display              *display,
00429        xaux_class_t  *p,
00430        Window        extwin)
00431 {
00432        char          buf[1024];
00433        int           i;
00434 
00435        p->atom_classname = XInternAtom(display, p->classname, False);
00436 
00437        sprintf(buf, "%s%s", p->classname, XAUX_SOWIN_SUFFIX);
00438        p->atom_sowin = XInternAtom(display, buf, False);
00439 
00440        sprintf(buf, "%s%s", p->classname, XAUX_EXTWIN_SUFFIX);
00441        p->atom_extwin = XInternAtom(display, buf, False);
00442 
00443        for (i = 0; i < XAUX_SX_NATOMS; i++) {
00444               sprintf(buf, "%s%s_%d", p->classname, XAUX_SX_SUFFIX, i);
00445               p->atom_sx[i] = XInternAtom(display, buf, False);
00446        }
00447 
00448        p->atom_sx_idx = 1;
00449 
00450        for (i = 0; i < XAUX_XS_NATOMS; i++) {
00451               sprintf(buf, "%s%s_%d", p->classname, XAUX_XS_SUFFIX, i);
00452               p->atom_xs[i] = XInternAtom(display, buf, False);
00453        }
00454 
00455        p->atom_xs_idx = 1;
00456 
00457        p->sowin = (Window)0;
00458 
00459        p->extwin = extwin;
00460 
00461        if (XGetSelectionOwner(display, p->atom_extwin) != None) {
00462 #if defined(DEBUG_XAUX)
00463               fprintf(stderr, "%s: %s already exists.[%s](1)\n",
00464                      ME_EXT, ME_EXT, p->classname);
00465 #endif /* defined(DEBUG_XAUX) */
00466               return False;
00467        }
00468 
00469        XSetSelectionOwner(display, p->atom_extwin, p->extwin, CurrentTime);
00470 
00471        if (XGetSelectionOwner(display, p->atom_extwin) != p->extwin) {
00472 #if defined(DEBUG_XAUX)
00473               fprintf(stderr, "%s: %s already exists.[%s](2)\n",
00474                      ME_EXT, ME_EXT, p->classname);
00475 #endif /* defined(DEBUG_XAUX) */
00476               XDestroyWindow(display, p->extwin);
00477               p->extwin = (Window)0;
00478               return False;
00479        }
00480 
00481        /* process sx properties which has been put on sowin before
00482           extwin is prepared */
00483        if (xaux_xs_get_sowin(p, display) == True) {
00484               for (i = p->atom_sx_idx; i < XAUX_SX_NATOMS; i++) {
00485                      if (xaux_ext_process_property_update(
00486                             display, p->sowin, p->atom_sx[i]) == False) {
00487                             break;
00488                      }
00489               }
00490        }
00491        return True;
00492 }
00493 
00494 Bool
00495 xaux_ext_SetValue(
00496        Display              *display,
00497        xaux_class_t  *xc,
00498        aux_ext_data_t       *aux_ext_data)
00499 {
00500        static char   *string_buf = NULL;
00501        static size_t bufsize = 0;
00502        size_t        i;
00503        size_t        total = 0;
00504        int           *ip;
00505        char          *sp;
00506        Bool          rv = True;
00507 
00508        if (aux_ext_data == NULL) {
00509               /* reset; free string_buf */
00510               if (string_buf != NULL) {
00511                      free(string_buf);
00512                      string_buf = NULL;
00513               }
00514               bufsize = 0;
00515               return True;
00516        }
00517 
00518        total = XS_SIZE_PROP_HEADER_SETVALUE
00519               + (sizeof (CARD32) * aux_ext_data->integer_count);
00520 
00521        if (aux_ext_data->string_count > 0) {
00522               for (i = 0; i < aux_ext_data->string_count; i++) {
00523                      size_t len;
00524 
00525                      len = aux_ext_data->string_list[i].length
00526                             * sizeof (CARD16);
00527                      total += ((sizeof (CARD16) + len + 3) / 4) * 4;
00528               }
00529 
00530               /*
00531                * "+1" is required by mb_utf16() method.
00532                * The method uses the area for BOM.
00533                */
00534               total += sizeof (CARD16);
00535        }
00536 
00537        /* tentatively use realloc(); may replace with malloc() later */
00538        /* othewise, cleanup (freeing) routine should be provided */
00539        if (total > bufsize) {
00540               string_buf = realloc(string_buf, total);
00541               if (string_buf == NULL) {
00542                      bufsize = 0;
00543                      return False;
00544               }
00545               bufsize = total;
00546        }
00547 
00548        XS_PROP_ATOM_AUX_NAME(string_buf) = xc->atom_classname;
00549        XS_PROP_IMID(string_buf) = aux_ext_data->im;
00550        XS_PROP_ICID(string_buf) = aux_ext_data->ic;
00551 
00552        XS_PROP_INT_COUNT(string_buf) = aux_ext_data->integer_count;
00553        XS_PROP_STR_COUNT(string_buf) = aux_ext_data->string_count;
00554 
00555 
00556        ip = (int *)XS_PROP_INT_LIST(string_buf);
00557 
00558        if (aux_ext_data->integer_count > 0) {
00559 
00560               for (i = 0; i < aux_ext_data->integer_count; i++) {
00561                      *ip++ = aux_ext_data->integer_list[i];
00562               }
00563        }
00564 
00565        sp = (char *)XS_PROP_STR_LIST(string_buf);
00566 
00567        if (aux_ext_data->string_count > 0) {
00568               char * ob;
00569               size_t obl;
00570 
00571               ob = sp;
00572               obl = total - XS_SIZE_PROP_HEADER_SETVALUE
00573                      - (sizeof (CARD16) * aux_ext_data->integer_count);
00574 
00575               for (i = 0; i < aux_ext_data->string_count; i++) {
00576                      char *        ib;
00577                      size_t        ibl;
00578                      size_t        obl_save;
00579                      int           pn;
00580                      CARD16 *      plen;
00581                      int           j;
00582 
00583                      ib = (char *)(aux_ext_data->string_list[i].ptr);
00584                      ibl = (size_t)aux_ext_data->string_list[i].length;
00585 
00586                      /* remember area for length, then skip the area */
00587                      plen = (CARD16 *)ob;
00588                      ob += sizeof (CARD16);
00589                      obl -= sizeof (CARD16);
00590 
00591                      obl_save = obl;
00592 
00593                      mb_utf16((const char **)&ib, &ibl, &ob, &obl);
00594 
00595                      /* store length */
00596                      *plen = obl_save - obl;
00597 
00598                      /* move ob to tail of the string */
00599                      ob += *plen;
00600 
00601                      /* padding */
00602                      pn = padding[(sizeof(CARD16) + *plen) % 4];
00603                      for (j = 0; j < pn; j++) {
00604                             *ob++ = 0;
00605                      }
00606                      sp = ob;
00607               }
00608        }
00609 
00610 #if defined(DEBUG_XAUX)
00611        fprintf(stderr, "ext_SetValue[%s] im:0x%x ic:0x%x in=%d sn=%d\n",
00612               xc->classname, aux_ext_data->im, aux_ext_data->ic,
00613               aux_ext_data->integer_count, aux_ext_data->string_count);
00614 #endif /* defined(DEBUG_XAUX) */
00615 
00616        if (aux_ext_data->integer_count != 0 ||
00617               aux_ext_data->string_count != 0) {
00618               rv = xaux_xs_send_property(display, xc,
00619                      aux_ext_data->im, aux_ext_data->ic,
00620                      (unsigned char *)string_buf, (sp - &(string_buf[0])));
00621        }
00622 
00623        return (rv);
00624 }
00625 
00626 #ifdef  USE_CDE_HELP
00627 
00628 #if defined(USE_DTACTIONINVOKE)
00629 #include <Dt/Dt.h>
00630 #include <Dt/Action.h>
00631 
00632 static void DbReloadProc(XtPointer cd);
00633 
00634 #else /* defined(USE_DTACTIONINVOKE) */
00635 
00636 #define DTACTION_CMD    "/usr/dt/bin/dtaction"
00637 
00638 static int help_available = 0;
00639 static char tmp_file[256];
00640 
00641 void
00642 HelpCleanup()
00643 {
00644     if (help_available) {
00645         unlink(tmp_file);
00646     }
00647 }
00648 
00649 void
00650 HelpSinalHandler(int unused)
00651 {
00652     HelpCleanup();
00653     exit(1);
00654 }
00655 
00656 int
00657 HelpXIOErrorHandler(Display * dpy)
00658 {
00659     HelpCleanup();
00660     return 0;
00661 }
00662 #endif /* defined(USE_DTACTIONINVOKE) */
00663 
00664 typedef struct _RmDatabase {
00665     char *help_basepath;
00666 } RmDatabase;
00667 
00668 static RmDatabase rdb;
00669 
00670 static XtResource rdb_items[] = {
00671   {"helpBasepath", "HelpBasepath", XtRString, sizeof(char*),
00672    offsetof(RmDatabase, help_basepath), XtRString,
00673    (XPointer)DEFAULT_HELP_PATH
00674    },
00675 };
00676 
00677 void
00678 HelpInit(
00679        Widget shell,
00680         char *ApplicationClass,
00681        int argc,
00682        char **argv
00683 )
00684 {
00685 #if defined(USE_DTACTIONINVOKE)
00686     if (DtInitialize(XtDisplay(shell), shell, argv[0], ApplicationClass)==False) {
00687         /* DtInitialize() has already logged an appropriate error msg */
00688         exit(-1);
00689     }
00690 
00691     /* Load the filetype/action databases */
00692     DtDbLoad();
00693 
00694     /* Notice changes to the database without needing to restart application */
00695     DtDbReloadNotify(DbReloadProc, NULL);
00696 #else /* defined(USE_DTACTIONINVOKE) */
00697     int i;
00698     char *tmp_dir;
00699     char tmp_tmp_file[256];
00700 
00701     if (help_available) {
00702         return;
00703     }
00704     XtGetApplicationResources(shell,
00705                               &rdb, rdb_items, 1,
00706                               NULL, 0);
00707 
00708     if (access(DTACTION_CMD, X_OK) != 0) {
00709         return;
00710     }
00711     tmp_dir = getenv("HOME");
00712     if (!tmp_dir) {
00713         return;
00714     }
00715 
00716     /* check tmp file exists or not */
00717     for(i=0;i<10;i++){
00718         sprintf(tmp_tmp_file, "%s/.dt/tmp/%s.%s", tmp_dir,
00719             strrchr(ApplicationClass, '.') + 1, "XXXXXX");
00720         mktemp(tmp_tmp_file);
00721         if (access(tmp_tmp_file, F_OK) != 0) {
00722             strcpy(tmp_file, tmp_tmp_file);
00723            help_available = 1;
00724             break;
00725         }
00726     }
00727 
00728     if(!help_available){
00729        return;
00730     }
00731 
00732     /* At shoutdown of user session */
00733     XSetIOErrorHandler(HelpXIOErrorHandler);
00734 
00735     signal(SIGKILL, HelpSinalHandler);
00736     signal(SIGTERM, HelpSinalHandler);
00737     signal(SIGHUP, HelpSinalHandler);
00738 #endif /* defined(USE_DTACTIONINVOKE) */
00739 
00740     XtGetApplicationResources(shell,
00741                                 &rdb, rdb_items, 1,
00742                                 NULL, 0);
00743 
00744 #if defined(DEBUG_XAUX)
00745    printf("basepath = %s\n", rdb.help_basepath);
00746 #endif /* defined(DEBUG_XAUX) */
00747 }
00748 
00749 #if defined(USE_DTACTIONINVOKE)
00750 static void DbReloadProc(XtPointer cd)
00751 {
00752     /* Pick up any dynamic changes to the database files */
00753     DtDbLoad();
00754 }
00755 #endif /* defined(USE_DTACTIONINVOKE) */
00756 
00757 void
00758 HelpInvoke(
00759        Widget toplevel,
00760        char *path_
00761 )
00762 {
00763 #if defined(USE_DTACTIONINVOKE)
00764     DtActionArg *ap = NULL;
00765     int nap = 0;
00766     DtActionInvocationID actionId;
00767     char path[256];
00768 
00769     sprintf(path, "%s%s", rdb.help_basepath, path_);
00770 
00771 #if defined(DEBUG_XAUX)
00772     printf("actual path = %s\n", path);
00773 #endif /* defined(DEBUG_XAUX) */
00774 
00775     if (path != NULL){
00776         ap = (DtActionArg*) XtCalloc(1, sizeof(DtActionArg));
00777 
00778         ap[0].argClass = DtACTION_BUFFER;
00779         ap[0].u.buffer.bp = (void*)path;
00780         ap[0].u.buffer.size = strlen(path);
00781         ap[0].u.buffer.type = NULL;
00782         ap[0].u.buffer.name = NULL;
00783         ap[0].u.buffer.writable = False;
00784 
00785         nap = 1;
00786     }
00787 
00788     /* Invoke the specified action */
00789     actionId = DtActionInvoke(toplevel,"SDtWebClient",ap,nap,NULL,NULL,NULL,True,NULL,NULL);
00790 #else /* defined(USE_DTACTIONINVOKE) */
00791     FILE *fp;
00792     pid_t pid;
00793 
00794     if (!help_available) {
00795         return;
00796     }
00797     if (!path_) {
00798         return;
00799     }
00800     if ((fp = fopen(tmp_file, "w")) == NULL) {
00801         return;
00802     }
00803     fprintf(fp, "%s%s\n", rdb.help_basepath, path_);
00804     fclose(fp);
00805 
00806     pid = fork1();
00807 
00808     if (pid == (pid_t) (-1)) {
00809         return;
00810     } else if (0 == pid) {
00811         execl(DTACTION_CMD, "dtaction",
00812               "SDtWebClient", tmp_file, NULL);
00813         _exit(1);
00814     }
00815     return;
00816 #endif /* defined(USE_DTACTIONINVOKE) */
00817 }
00818 
00819 #else /* USE_CDE_HELP */
00820 
00821 void
00822 HelpInvoke(
00823         char *path
00824 )
00825 {
00826     char *browser;
00827     char *basepath;
00828 
00829     pid_t pid, pid2;
00830 
00831     if (!path) {
00832       return;
00833     }
00834 
00835 #ifdef linux
00836     pid = fork();
00837 #else
00838     pid = fork1();
00839 #endif
00840 
00841     if (getenv("HTT_HELP_BROWSER")){
00842       browser = getenv("HTT_HELP_BROWSER");
00843     } else {
00844       browser = "/usr/bin/netscape";
00845     }
00846 
00847     if (getenv("HTT_HELP_PATH")){
00848       basepath = getenv("HTT_HELP_PATH");
00849     } else {
00850       basepath = DEFAULT_HELP_PATH;
00851     }
00852 
00853     if (pid == (pid_t) (-1)) {
00854         return;
00855     } else if (0 == pid) {
00856         pid2 = fork();
00857         if(pid2 == -1) {
00858             _exit(1);
00859         } else if(pid2 == 0) {
00860            char *help = (char*)malloc(strlen(basepath) + strlen(path) +1 );
00861            sprintf(help, "%s%s", basepath, path);
00862            execl(browser, browser, help, NULL);
00863            free(help);
00864             _exit(1);
00865         } else {
00866             _exit(0);
00867         }
00868     } else {
00869         waitpid(pid, NULL, 0);
00870     }
00871     return;
00872 }
00873 
00874 #endif /* USE_CDE_HELP */
00875 
00876 #if !defined(USE_ICONV) && !defined(USE_CSCONV)
00877 #if defined(sun)
00878 #define USE_ICONV
00879 #else
00880 #define USE_CSCONV
00881 #endif
00882 #endif
00883 
00884 #ifdef USE_ICONV
00885 #include <iconv.h> 
00886 #endif
00887 
00888 #include <locale.h>
00889 #include <langinfo.h>
00890 #include <strings.h>
00891 #if !defined(USE_CSCONV)
00892 #include <errno.h>
00893 #endif /* !USE_CSCONV */
00894 #if 0
00895 #include "iiimpIM.h"
00896 #include "iiimp.h"
00897 #include "iiimpReq.h"
00898 #endif
00899 
00900 #define UTF16_STRLEN 4096
00901 
00902 #ifdef USE_CSCONV
00903 #include <dlfcn.h>
00904 #include "csconv.h"
00905 #define CSC_OPEN_LOCALE     "csconv_open_locale"
00906 #define CSC_OPEN     "csconv_open"
00907 #define CSC_CONV     "csconv"
00908 #define CSC_CLOSE    "csconv_close"
00909 
00910 typedef csconv_t     (* csc_open_locale_t)(const char *,
00911                                          const char *, const char *);
00912 typedef csconv_t     (* csc_open_t)(const char *, const char *);
00913 typedef size_t              (* csc_conv_t)(csconv_t, const char **, size_t *,
00914                                    char **, size_t *);
00915 typedef int          (* csc_close_t)(csconv_t);
00916 
00917 static void *               csc_handle;   
00918 static csc_open_locale_t    csc_open_locale;
00919 static csc_open_t           csc_open;
00920 static csc_conv_t           csc_conv;
00921 static csc_close_t          csc_close;
00922 
00923 static char *current_locale = 0;
00924 #endif
00925 
00926 #ifdef USE_ICONV
00927 static iconv_t i_conv1 = NULL;
00928 static iconv_t i_conv2 = NULL;
00929 static Bool skip_native_to_utf8_conv = False;
00930 #endif
00931 
00932 #ifdef USE_CSCONV
00933 static void
00934 dlopen_csconv()
00935 {
00936       csc_handle = dlopen(CSC_PATH, RTLD_LAZY);
00937       if (NULL == csc_handle) {
00938         csc_handle = (void *)(-1);
00939        return;
00940       }
00941 
00942       csc_open_locale = (csc_open_locale_t)dlsym(csc_handle, CSC_OPEN_LOCALE);
00943       csc_open = (csc_open_t)dlsym(csc_handle, CSC_OPEN);
00944       csc_conv = (csc_conv_t)dlsym(csc_handle, CSC_CONV);
00945       csc_close = (csc_close_t)dlsym(csc_handle, CSC_CLOSE);
00946 
00947       if ((NULL == csc_open_locale) || (NULL == csc_open) ||
00948          (NULL == csc_conv) || (NULL == csc_close)) {
00949         dlclose(csc_handle);
00950        csc_handle = (void *)(-1);
00951        return;
00952       }
00953 }
00954 #endif
00955 
00956 int
00957 IIimpConvertToUTF16(char *from_buf, size_t from_left,
00958                   char **to_buf, size_t *to_left) {
00959   size_t src_len, dst_len;
00960   char *src, *dst;
00961 #ifndef USE_CSCONV
00962   const char *ip;
00963   size_t ileft;
00964   char *op;
00965   size_t oleft;
00966   char buffer[UTF16_STRLEN];              /* Fix me! */
00967 #endif /* !USE_CSCONV */
00968   const size_t buf_len = UTF16_STRLEN;
00969   size_t ret = 0;
00970 #ifdef USE_CSCONV
00971   static csconv_t csconv_cd = NULL;
00972 
00973 #endif
00974 
00975 #ifdef USE_CSCONV
00976   if (current_locale == NULL){
00977     current_locale = (char*)strdup(setlocale(LC_CTYPE, NULL));
00978   }
00979 
00980   do {
00981     if (((void *)(-1) == csc_handle) ||
00982        ((csconv_t)(-1) == csconv_cd)) {
00983       continue;
00984     }
00985     if (NULL == csc_handle) {
00986       dlopen_csconv();
00987       if ((void *)(-1) == csc_handle) {
00988        continue;
00989       }
00990     }
00991     if (NULL == csconv_cd) {
00992 
00993       csconv_cd = (csc_open_locale)(current_locale, "UTF-16", "MultiByte");
00994       
00995       if ((csconv_t)(-1) == csconv_cd) {
00996        continue;
00997       }
00998     }
00999 
01000     dst = *((char **)to_buf);
01001 
01002     ret = csc_conv(csconv_cd,
01003                  (const char **)&from_buf, &from_left,
01004                  &dst, to_left);
01005     return ret;
01006   } while (0);
01007 #endif
01008 
01009 #ifdef USE_ICONV
01010   if (i_conv1 == (iconv_t)-1 || i_conv2 == (iconv_t)-1){
01011     goto done;
01012   }
01013 
01014   if (i_conv1 == NULL && !skip_native_to_utf8_conv) {
01015     char *encoding = nl_langinfo(CODESET);
01016     if (!strcmp(encoding, "UTF-8")) {
01017       skip_native_to_utf8_conv = True;
01018     } else {
01019       if ((i_conv1 = iconv_open("UTF-8", encoding))
01020          == (iconv_t)-1) {
01021        goto done;
01022       }
01023     }
01024   }
01025 
01026   if (i_conv2 == NULL){
01027     if ((i_conv2 = iconv_open("UCS-2",
01028                            "UTF-8")) == (iconv_t)-1)
01029       goto done;
01030   }
01031 
01032   if (!skip_native_to_utf8_conv) {
01033     ip = (const char *)from_buf;
01034     ileft = from_left;
01035 
01036     op = *((char **)to_buf);
01037     oleft = *to_left;
01038 
01039     while ((0 < ileft) && (0 < oleft)) {
01040       dst = buffer;
01041       dst_len = buf_len;
01042       ret = iconv(i_conv1, &ip, &ileft, (char**)&dst, &dst_len);
01043       if ((ret != 0) && (E2BIG != errno)) {
01044        goto done;
01045       }
01046 
01047       src = buffer;
01048       src_len = buf_len - dst_len;
01049 
01050       ret = iconv(i_conv2, (const char**)&src, &src_len, &op, &oleft);
01051       if (ret != 0) goto done;
01052     }
01053 
01054     dst_len = oleft;
01055 
01056   } else {
01057     src = from_buf;
01058     src_len = from_left;
01059     dst = *to_buf;
01060     dst_len = *to_left;
01061 
01062     ret = iconv(i_conv2, (const char**)&src, &src_len, (char**)&dst, &dst_len);
01063   }
01064 
01065   if (0xFEFF == **((CARD16 **)to_buf)) {
01066     memmove(*to_buf, *to_buf + 2, *to_left - dst_len - 2);
01067     *to_left = (dst_len + 2);
01068   } else {
01069     *to_left = dst_len;
01070   }
01071 done:
01072 #endif /* USE_ICONV */
01073   return(ret);
01074 }
01075 
01076 #ifdef USE_ICONV
01077 static iconv_t i_conv1_FromUTF16 = NULL;
01078 static iconv_t i_conv2_FromUTF16 = NULL;
01079 #endif
01080 
01081 /* Used when transfering data from AUX to IM,
01082    do data conversion from UCS2 to EUC */
01083 int
01084 IIimpConvertFromUTF16(char *from_buf, size_t from_left,
01085                     char **to_buf, size_t * to_left) {
01086   size_t src_len, dst_len;
01087   char *src, *dst;
01088 #ifndef USE_CSCONV
01089   const char *ip;
01090   size_t ileft;
01091   char *op;
01092   size_t oleft;
01093   char buffer[UTF16_STRLEN];       /* Fix me! */
01094 #endif /* !USE_CSCONV */
01095   const size_t buf_len = UTF16_STRLEN;
01096   size_t ret = 0;
01097 
01098 #ifdef USE_CSCONV
01099   static csconv_t csconv_cd = NULL;
01100 #endif
01101 
01102 #ifdef USE_CSCONV
01103   if (current_locale == NULL){
01104     current_locale = (char*)strdup(setlocale(LC_CTYPE, NULL));
01105   }
01106   do {
01107     if (((void *)(-1) == csc_handle) ||
01108        ((csconv_t)(-1) == csconv_cd)) {
01109       continue;
01110     }
01111     if (NULL == csc_handle) {
01112       dlopen_csconv();
01113       if ((void *)(-1) == csc_handle) {
01114        continue;
01115       }
01116     }
01117     if (NULL == csconv_cd) {
01118 
01119       csconv_cd = (csc_open_locale)(current_locale, "MultiByte", "UTF-16");
01120       
01121       if ((csconv_t)(-1) == csconv_cd) {
01122        continue;
01123       }
01124     }
01125 
01126     dst = *((char **)to_buf);
01127 
01128     ret = csc_conv(csconv_cd,
01129                  (const char **)&from_buf, &from_left, &dst, to_left);
01130     return ret;
01131   } while (0);
01132 #endif
01133 
01134 #ifdef USE_ICONV
01135   if (i_conv1_FromUTF16 == (iconv_t)-1 ||
01136       i_conv2_FromUTF16 == (iconv_t)-1) {
01137     goto done;
01138   }
01139 
01140   if (i_conv2_FromUTF16 == NULL && !skip_native_to_utf8_conv) {
01141     char *encoding = nl_langinfo(CODESET);
01142     if (!strcmp(encoding, "UTF-8")) {
01143       skip_native_to_utf8_conv = True;
01144     } else {
01145       if ((i_conv2_FromUTF16 = iconv_open(encoding, "UTF-8"))
01146          == (iconv_t) - 1) {
01147        goto done;
01148       }
01149     }
01150   }
01151   if (i_conv1_FromUTF16 == NULL) {
01152     if ((i_conv1_FromUTF16 = iconv_open("UTF-8", "UCS-2"))
01153        == (iconv_t) - 1) {
01154       goto done;
01155     }
01156   }
01157 
01158   if (skip_native_to_utf8_conv) {
01159     src = from_buf;
01160     src_len = from_left;    /* don't stop at '\0' in case of ascii */
01161     dst = *((char **) to_buf);
01162 
01163     ret = iconv(i_conv1_FromUTF16, (const char**)&src, &src_len,
01164               (char**)&dst, to_left);
01165   } else {
01166     ip = (const char *)from_buf;
01167     ileft = from_left;
01168 
01169     op = *((char **)to_buf);
01170     oleft = *to_left;
01171 
01172     while ((0 < ileft) && (0 < oleft)) {
01173       dst = buffer;
01174       dst_len = buf_len;
01175       ret = iconv(i_conv1_FromUTF16, &ip, &ileft, (char**)&dst, &dst_len);
01176       if ((ret != 0) && (E2BIG != errno)) {
01177        goto done;
01178       }
01179 
01180       src = buffer;
01181       src_len = buf_len - dst_len;
01182 
01183       ret = iconv(i_conv2_FromUTF16, (const char**)&src, &src_len,
01184                 &op, &oleft);
01185       if (ret != 0) goto done;
01186     }
01187 
01188     *to_left = oleft;
01189   }
01190 done:
01191 #endif /* USE_ICONV */
01192   return(ret);
01193 }