Back to index

im-sdk  12.3.91
IIIMPClientAuxSetValues.cpp
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 #if !defined(USE_FRAMEMGR_ALWAYS)
00043 #include <stddef.h>
00044 #include <string.h>
00045 #else /* USE_FRAMEMGR_ALWAYS */
00046 #include "FrameMgr.h"
00047 #endif /* USE_FRAMEMGR_ALWAYS */
00048 #include "IIIMProtocol.hh"
00049 #include "IIIMPClient.hh"
00050 #include "IMProtoHandler.hh"
00051 #include "IMProtocolStruct.h"
00052 #include "IMProtocolStructP.hh"
00053 
00054 #if !defined(USE_FRAMEMGR_ALWAYS)
00055 int
00056 IIIMPClient::string_list_count(char *p) {
00057   char *ptr;
00058   CARD32 str_list_size; 
00059   int num;
00060   CARD16 str_size;
00061 
00062   num = 0;
00063   ptr = p;
00064   if (False == need_swap) {
00065     req_get32(ptr, str_list_size);
00066     if (str_list_size & 0x03) {
00067       str_list_size &= (~0x03);
00068     }
00069 
00070     while (4 <= str_list_size) {
00071       req_get16(ptr, str_size);
00072       str_list_size -= 2;
00073       if ((str_size + 2) & 0x03) { /* padding */
00074        str_size = (((str_size + 2) & (~0x03)) + 2);
00075       }
00076       if (str_list_size < str_size) {
00077        str_size = str_list_size;
00078       }
00079 
00080       ptr += str_size;
00081       str_list_size -= str_size;
00082       num += 1;
00083     }
00084   } else {
00085     req_get32s(ptr, str_list_size);
00086     if (str_list_size & 0x03) {
00087       str_list_size &= (~0x03);
00088     }
00089 
00090     while (4 <= str_list_size) {
00091       req_get16s(ptr, str_size);
00092       str_list_size -= 2;
00093       if ((str_size + 2) & 0x03) { /* padding */
00094        str_size = (((str_size + 2) & (~0x03)) + 2);
00095       }
00096       if (str_list_size < str_size) {
00097        str_size = str_list_size;
00098       }
00099 
00100       ptr += str_size;
00101       str_list_size -= str_size;
00102       num += 1;
00103     }
00104   }
00105   return num;
00106 }
00107 #else /* USE_FRAMEMGR_ALWAYS */
00108 #endif /* USE_FRAMEMGR_ALWAYS */
00109 
00110 void
00111 IIIMPClient::aux_set_values(IMProtocolStruct *call_data,
00112                          unsigned char *p) {
00113 #if !defined(USE_FRAMEMGR_ALWAYS)
00114   char *ptr;
00115   int im_name_len;
00116   char *enginename;
00117   int i;
00118 #else /* USE_FRAMEMGR_ALWAYS */
00119   FrameMgr fm;
00120   FmStatus status;
00121   extern XimFrameRec im_aux_setvalues_fr[], im_aux_setvalues_reply_fr[];
00122   XimFrameRec *input_fr = im_aux_setvalues_fr;
00123 #endif /* USE_FRAMEMGR_ALWAYS */
00124   int class_index;
00125   CARD16 input_method_id, input_context_id;
00126   CARD32 byte_length = 0;
00127   int number;
00128 #if !defined(USE_FRAMEMGR_ALWAYS)
00129   int string_list_num;
00130 #else /* USE_FRAMEMGR_ALWAYS */
00131   int integer_list_num = IIIMPClient::MAX_ATTRNUM;
00132   int string_list_num = IIIMPClient::MAX_ATTRNUM;
00133 #endif /* USE_FRAMEMGR_ALWAYS */
00134   IMAuxDrawCallbackStruct aux_draw;
00135 
00136 #if !defined(USE_FRAMEMGR_ALWAYS)
00137   ptr = (char *)p;
00138   if (False == need_swap) {
00139     req_get16(ptr, input_method_id);
00140     req_get16(ptr, input_context_id);
00141     req_get32(ptr, class_index);
00142     req_get16(ptr, byte_length);
00143   } else {
00144     req_get16s(ptr, input_method_id);
00145     req_get16s(ptr, input_context_id);
00146     req_get32s(ptr, class_index);
00147     req_get16s(ptr, byte_length);
00148   }
00149   if (byte_length & 0x01) {
00150     byte_length += 1;
00151   }
00152   if (byte_length & 0x02) {
00153     im_name_len = byte_length;
00154   } else {
00155     im_name_len = (byte_length + 2);
00156   }
00157 
00158 #else /* USE_FRAMEMGR_ALWAYS */
00159   /* create FrameMgr */
00160   fm = FrameMgrInit(input_fr, (char *)p, need_swap);
00161 
00162   /* get data */
00163   FrameMgrGetToken(fm, input_method_id);
00164   FrameMgrGetToken(fm, input_context_id);
00165   FrameMgrGetToken(fm, class_index);
00166 
00167   /* engine_name */
00168   CompoundString enginename;
00169 
00170   FrameMgrGetToken(fm, byte_length);
00171 #endif /* USE_FRAMEMGR_ALWAYS */
00172   if (byte_length == 0) {
00173     /* something wrong */
00174     return;
00175   } else {
00176     CARD16 str;
00177     CARD8 byte_data;
00178     char *enginenamep;
00179 
00180 #if !defined(USE_FRAMEMGR_ALWAYS)
00181     enginename = new char[byte_length + 1];
00182 #else /* USE_FRAMEMGR_ALWAYS */
00183     enginename = CompoundString(byte_length);
00184     memset(enginename, 0, byte_length);
00185 #endif /* USE_FRAMEMGR_ALWAYS */
00186 
00187     int i;
00188     if (False == need_swap) {
00189       for (i = 0, enginenamep = enginename;
00190           i < byte_length; i += 2, enginenamep++) {
00191 #if !defined(USE_FRAMEMGR_ALWAYS)
00192        req_get16(ptr, *enginenamep);
00193 #else /* USE_FRAMEMGR_ALWAYS */
00194         FrameMgrGetToken(fm, byte_data);
00195        *(((unsigned char *)&str) + 1) = byte_data;
00196        FrameMgrGetToken(fm, byte_data);
00197        *(((unsigned char *)&str) + 0) = byte_data;
00198        *enginenamep = (char)str;
00199 #endif /* USE_FRAMEMGR_ALWAYS */
00200       }
00201     } else {
00202       for (i = 0, enginenamep = enginename;
00203           i < byte_length; i += 2, enginenamep++) {
00204 #if !defined(USE_FRAMEMGR_ALWAYS)
00205        req_get16s(ptr, *enginenamep);
00206 #else /* USE_FRAMEMGR_ALWAYS */
00207         FrameMgrGetToken(fm, byte_data);
00208        *(((unsigned char *)&str) + 0) = byte_data;
00209        FrameMgrGetToken(fm, byte_data);
00210        *(((unsigned char *)&str) + 1) = byte_data;
00211        *enginenamep = (char)str;
00212 #endif /* USE_FRAMEMGR_ALWAYS */
00213       }
00214     }
00215     *enginenamep = (char)0;
00216   }
00217 #if !defined(USE_FRAMEMGR_ALWAYS)
00218   if ((byte_length + 2) & 0x03) {
00219     ptr += (4 - ((byte_length + 2) & 0x03));
00220   }
00221 #else /* USE_FRAMEMGR_ALWAYS */
00222 #endif /* USE_FRAMEMGR_ALWAYS */
00223 
00224 
00225   aux_draw.aux_name = enginename;
00226   aux_draw.aux_index = class_index;
00227 
00228   /* integer value list */
00229 #if !defined(USE_FRAMEMGR_ALWAYS)
00230   int *integer_list = NULL;
00231 #else /* USE_FRAMEMGR_ALWAYS */
00232   int *integer_list = new int[integer_list_num];
00233 #endif /* USE_FRAMEMGR_ALWAYS */
00234 
00235   number = 0;
00236 #if !defined(USE_FRAMEMGR_ALWAYS)
00237   if (False == need_swap) {
00238     req_get32(ptr, byte_length);
00239   } else {
00240     req_get32s(ptr, byte_length);
00241   }
00242 #else /* USE_FRAMEMGR_ALWAYS */
00243   FrameMgrGetToken(fm, byte_length);
00244 #endif /* USE_FRAMEMGR_ALWAYS*/
00245   if (byte_length) {
00246 #if !defined(USE_FRAMEMGR_ALWAYS)
00247     integer_list = new int[byte_length / 4];
00248     if (False == need_swap) {
00249       for (number = 0; number < (byte_length / 4); number++) {
00250        req_get32(ptr, *(integer_list + number));
00251       }
00252     } else {
00253       for (number = 0; number < (byte_length / 4); number++) {
00254        req_get32s(ptr, *(integer_list + number));
00255       }
00256     }
00257 #else /* USE_FRAMEMGR_ALWAYS */
00258     while (FrameMgrIsIterLoopEnd(fm, &status) == False) {
00259       if (number == integer_list_num) {
00260        integer_list_num += IIIMPClient::MAX_ATTRNUM;
00261        int *temp = integer_list;
00262        integer_list = new int[integer_list_num];
00263        memmove(integer_list, temp, sizeof(int) * number);
00264        delete [] temp;
00265       }
00266       FrameMgrGetToken(fm, integer_list[number++]);
00267     }
00268 #endif /* USE_FRAMEMGR_ALWAYS */
00269   }
00270   aux_draw.count_integer_values = number;
00271   aux_draw.integer_values = integer_list;
00272 
00273 #if !defined(USE_FRAMEMGR_ALWAYS)
00274   /* string value list */
00275   string_list_num = string_list_count(ptr);
00276 #endif
00277 
00278   IMText *string_list = new IMText[string_list_num];
00279   if (!string_list) {
00280     delete [] integer_list;
00281     return;
00282   }
00283 
00284   number = 0;
00285 #if !defined(USE_FRAMEMGR_ALWAYS)
00286   if (False == need_swap) {
00287     req_get32(ptr, byte_length);
00288   } else {
00289     req_get32s(ptr, byte_length);
00290   }
00291 #else /* USE_FRAMEMGR_ALWAYS */
00292   FrameMgrGetToken(fm, byte_length);
00293 #endif /* USE_FRAMEMGR_ALWAYS */
00294   if (byte_length) {
00295 #if !defined(USE_FRAMEMGR_ALWAYS)
00296     if (False == need_swap) {
00297       while (4 <= byte_length) {
00298        CARD16 str_length = 0;
00299        req_get16(ptr, str_length);
00300        byte_length -= 2;
00301 
00302        if (str_length & 0x01) {    /* incorrect request */
00303          str_length += 1;
00304        }
00305        if (byte_length < str_length) {    /* incorrect request */
00306          str_length = byte_length;
00307        }
00308 
00309        if (65000 < str_length) {
00310          /* something wrong */
00311        } else {
00312          int len = (str_length / 2);
00313          UTFCHAR *utf_str = new UTFCHAR[len + 1];
00314 
00315          for (i = 0; i < len; i++) {
00316            req_get16(ptr, *(utf_str + i));
00317          }
00318          *(utf_str + len) = 0;
00319 
00320          if ((str_length + 2) & 0x03) {
00321            byte_length -= (((str_length + 2) & (~0x03)) + 2);
00322            ptr += 2;
00323          } else {
00324            byte_length -= str_length;
00325          }
00326 
00327          string_list[number].encoding = UTF16_CODESET;
00328          string_list[number].char_length = len;
00329          string_list[number].text.utf_chars = utf_str;
00330          number += 1;
00331        }
00332       }
00333     } else {
00334       while (4 <= byte_length) {
00335        CARD16 str_length = 0;
00336        req_get16s(ptr, str_length);
00337        byte_length -= 2;
00338 
00339        if (str_length & 0x01) {    /* incorrect request */
00340          str_length += 1;
00341        }
00342        if (byte_length < str_length) {    /* incorrect request */
00343          str_length = byte_length;
00344        }
00345 
00346        if (65000 < str_length) {
00347          /* something wrong */
00348        } else {
00349          int len = (str_length / 2);
00350          UTFCHAR *utf_str = new UTFCHAR[len + 1];
00351 
00352          for (i = 0; i < len; i++) {
00353            req_get16s(ptr, *(utf_str + i));
00354          }
00355          *(utf_str + len) = 0;
00356 
00357          if ((str_length + 2) & 0x03) {
00358            byte_length -= (((str_length + 2) & (~0x03)) + 2);
00359            ptr += 2;
00360          } else {
00361            byte_length -= str_length;
00362          }
00363 
00364          string_list[number].encoding = UTF16_CODESET;
00365          string_list[number].char_length = len;
00366          string_list[number].text.utf_chars = utf_str;
00367          number += 1;
00368        }
00369       }
00370     }
00371 #else /* USE_FRAMEMGR_ALWAYS */
00372     if (1 == (byte_length % 2)) {
00373       /*
00374        * byte_length must be even.
00375        * it should be safe to add 1 to byte_length when it is odd.
00376        */
00377       byte_length += 1;
00378     }
00379 
00380     while (byte_length > 0) {
00381       CARD16 str_length = 0;
00382       FrameMgrGetToken(fm, str_length);
00383       byte_length -= 2;
00384 
00385       if (1 == (str_length % 2)) {
00386        str_length += 1;
00387       }
00388       if (byte_length < str_length) {
00389        /* incorrect request */
00390        str_length = byte_length;
00391       }
00392 
00393       if (str_length > 65000) {
00394        /* something wrong */
00395       } else {
00396        CARD8 first_byte, second_byte;
00397        int len;
00398        char *utf_str = new char[str_length + 1];
00399        char *strp;
00400        int bl;
00401 
00402        for (strp = utf_str; strp < &utf_str[str_length];) {
00403          FrameMgrGetToken(fm, first_byte);
00404          byte_length--;
00405          FrameMgrGetToken(fm, second_byte);
00406          byte_length--;
00407          if (need_swap) {
00408            *strp++ = second_byte;
00409            *strp++ = first_byte;
00410          } else {
00411            *strp++ = first_byte;
00412            *strp++ = second_byte;
00413          }
00414        }
00415        /* decrease padding */
00416        byte_length -= ((str_length + 2) % 4);
00417 
00418        *strp = (char)0;
00419 
00420        if (number == string_list_num) {
00421          string_list_num += IIIMPClient::MAX_ATTRNUM;
00422          IMText *temp = string_list;
00423          string_list = new IMText[string_list_num];
00424          memmove(string_list, temp, sizeof(IMText) * number);
00425          delete [] temp;
00426        }
00427        const int one_unit = sizeof(UTFCHAR)/sizeof(char);
00428        string_list[number].encoding = UTF16_CODESET;
00429        string_list[number].char_length = str_length/one_unit;
00430        string_list[number++].text.utf_chars = (UTFCHAR*)utf_str;
00431       }
00432     }
00433 #endif /* USE_FRAMEMGR_ALWAYS */
00434   }
00435   aux_draw.count_string_values = number;
00436   aux_draw.string_values = string_list;
00437 
00438 #if !defined(USE_FRAMEMGR_ALWAYS)
00439 #else /* USE_FRAMEMGR_ALWAYS */
00440   /* free FrameMgr */
00441   FrameMgrFree(fm);
00442 #endif /* USE_FRAMEMGR_ALWAYS */
00443 
00444   InputContext *ic = &(input_context_list.getItem(input_context_id));
00445   if (ic) {
00446     IMAuxEvent aux_event;
00447     aux_event.type = IM_EventAux;
00448     aux_event.aux = &aux_draw;
00449     iiim_protocol->proto_handler->ForwardEvent((InputContext*)ic,
00450                                           (IMInputEvent*)&aux_event);
00451   } else { 
00452     // need to treate as an error
00453   }
00454 
00455   /* return AUX_SET_VALUES_REPLY */
00456 
00457 #if !defined(USE_FRAMEMGR_ALWAYS)
00458   const int total_size = (4 + 2 + 2 + 4 + 2 + im_name_len);
00459   char *reply = new char[total_size];
00460   memcpy(reply + 4, p, total_size - 4);
00461 
00462   send_message(IM_AUX_SETVALUES_REPLY, reply, total_size);
00463 
00464   delete [] reply;
00465 
00466 #else /* USE_FRAMEMGR_ALWAYS */
00467   /* create FrameMgr */
00468   fm = FrameMgrInit(im_aux_setvalues_reply_fr, NULL, need_swap);
00469 
00470   /* set iteration count of engine name */
00471   byte_length = strlen(enginename);
00472   FrameMgrSetIterCount(fm, byte_length);
00473 
00474   const int total_size = FrameMgrGetTotalSize(fm);
00475   CompoundString reply = CompoundString(total_size);
00476   memset(reply, 0, total_size);
00477   FrameMgrSetBuffer(fm, reply);
00478 
00479   FrameMgrPutToken(fm, input_method_id);
00480   FrameMgrPutToken(fm, input_context_id);
00481   FrameMgrPutToken(fm, class_index);
00482 
00483   for (char *enginenamep = enginename;
00484        enginenamep < &enginename[byte_length];enginenamep++) {
00485     CARD16 str = (CARD16)*enginenamep;
00486     CARD8 byte_data;
00487     byte_data = (str << 8) & 0xff00;
00488     FrameMgrPutToken(fm, byte_data);
00489     byte_data = str & 0x00ff;
00490     FrameMgrPutToken(fm, byte_data);
00491   }
00492   send_message(IM_AUX_SETVALUES_REPLY, reply, total_size);
00493 #endif /* USE_FRAMEMGR_ALWAYS */
00494 
00495 #if !defined(USE_FRAMEMGR_ALWAYS)
00496 #else /* USE_FRAMEMGR_ALWAYS */
00497   /* free FrameMgr */
00498   FrameMgrFree(fm);
00499 #endif /* USE_FRAMEMGR_ALWAYS */
00500 
00501   delete [] integer_list;
00502 
00503   for (IMText *textp = aux_draw.string_values;
00504        textp < &aux_draw.string_values[aux_draw.count_string_values];
00505        textp++) {
00506     if (textp->text.utf_chars) delete [] textp->text.utf_chars;
00507   }
00508   delete [] string_list;
00509 
00510   return;
00511 }