~ubuntu-branches/ubuntu/raring/sunpinyin/raring

« back to all changes in this revision

Viewing changes to wrapper/xim/IMdkit/i18nX.c

  • Committer: Package Import Robot
  • Author(s): YunQiang Su
  • Date: 2012-03-30 15:31:55 UTC
  • mfrom: (1.1.3) (1.2.7 sid)
  • Revision ID: package-import@ubuntu.com-20120330153155-qgls77sogzgtg9zp
Tags: 2.0.3+git20120222-1
* Team upload: git snapshot 20120222.
   - fix breaks if LDFLAGS in environment contains
       multiple words (Closese #646001).
   - rm patches merged to upstream:
       append-os-environ-toenv.patch
       fix-ftbfs-on-sh.patch
       remove-10-candidate-words-limitation.patch
   - refresh disable-lm-dict-compile.patch.
* Bump stardard version to 3.9.3: no modify needed.
* add libsunpinyin3-dbg and python-sunpinyin packages.
* debian/compat to 9, multiarch it.
* rewrite debian/rules with dh 7 format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************
 
2
 
 
3
         Copyright 1994, 1995 by Sun Microsystems, Inc.
 
4
         Copyright 1993, 1994 by Hewlett-Packard Company
 
5
 
 
6
Permission to use, copy, modify, distribute, and sell this software
 
7
and its documentation for any purpose is hereby granted without fee,
 
8
provided that the above copyright notice appear in all copies and
 
9
that both that copyright notice and this permission notice appear
 
10
in supporting documentation, and that the name of Sun Microsystems, Inc.
 
11
and Hewlett-Packard not be used in advertising or publicity pertaining to
 
12
distribution of the software without specific, written prior permission.
 
13
Sun Microsystems, Inc. and Hewlett-Packard make no representations about
 
14
the suitability of this software for any purpose.  It is provided "as is"
 
15
without express or implied warranty.
 
16
 
 
17
SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
 
18
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
 
19
WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
20
SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
 
21
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 
22
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
 
23
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 
24
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
25
 
 
26
  Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
 
27
 
 
28
    This version tidied and debugged by Steve Underwood May 1999
 
29
 
 
30
******************************************************************/
 
31
 
 
32
#include <limits.h>
 
33
#include <X11/Xlib.h>
 
34
#include <X11/Xatom.h>
 
35
#include "FrameMgr.h"
 
36
#include "IMdkit.h"
 
37
#include "Xi18n.h"
 
38
#include "Xi18nX.h"
 
39
#include "XimFunc.h"
 
40
 
 
41
extern Xi18nClient *_Xi18nFindClient(Xi18n, CARD16);
 
42
extern Xi18nClient *_Xi18nNewClient(Xi18n);
 
43
extern void _Xi18nDeleteClient(Xi18n, CARD16);
 
44
static Bool WaitXConnectMessage(Display*, Window,
 
45
                                XEvent*, XPointer);
 
46
static Bool WaitXIMProtocol(Display*, Window, XEvent*, XPointer);
 
47
 
 
48
static XClient *NewXClient (Xi18n i18n_core, Window new_client)
 
49
{
 
50
    Display *dpy = i18n_core->address.dpy;
 
51
    Xi18nClient *client = _Xi18nNewClient (i18n_core);
 
52
    XClient *x_client;
 
53
 
 
54
    x_client = (XClient *) malloc (sizeof (XClient));
 
55
    x_client->client_win = new_client;
 
56
    x_client->accept_win = XCreateSimpleWindow (dpy,
 
57
                                                DefaultRootWindow(dpy),
 
58
                                                0,
 
59
                                                0,
 
60
                                                1,
 
61
                                                1,
 
62
                                                1,
 
63
                                                0,
 
64
                                                0);
 
65
    client->trans_rec = x_client;
 
66
    return ((XClient *) x_client);
 
67
}
 
68
 
 
69
static unsigned char *ReadXIMMessage (XIMS ims,
 
70
                                      XClientMessageEvent *ev,
 
71
                                      int *connect_id)
 
72
{
 
73
    Xi18n i18n_core = ims->protocol;
 
74
    Xi18nClient *client = i18n_core->address.clients;
 
75
    XClient *x_client = NULL;
 
76
    FrameMgr fm;
 
77
    extern XimFrameRec packet_header_fr[];
 
78
    unsigned char *p = NULL;
 
79
    unsigned char *p1;
 
80
 
 
81
    while (client != NULL) {
 
82
        x_client = (XClient *) client->trans_rec;
 
83
        if (x_client->accept_win == ev->window) {
 
84
            *connect_id = client->connect_id;
 
85
            break;
 
86
        }
 
87
        client = client->next;
 
88
    }
 
89
 
 
90
    if (ev->format == 8) {
 
91
        /* ClientMessage only */
 
92
        XimProtoHdr *hdr = (XimProtoHdr *) ev->data.b;
 
93
        unsigned char *rec = (unsigned char *) (hdr + 1);
 
94
        register int total_size;
 
95
        CARD8 major_opcode;
 
96
        CARD8 minor_opcode;
 
97
        CARD16 length;
 
98
        extern int _Xi18nNeedSwap (Xi18n, CARD16);
 
99
 
 
100
        if (client->byte_order == '?')
 
101
        {
 
102
            if (hdr->major_opcode != XIM_CONNECT)
 
103
                return (unsigned char *) NULL; /* can do nothing */
 
104
            client->byte_order = (CARD8) rec[0];
 
105
        }
 
106
 
 
107
        fm = FrameMgrInit (packet_header_fr,
 
108
                           (char *) hdr,
 
109
                           _Xi18nNeedSwap (i18n_core, *connect_id));
 
110
        total_size = FrameMgrGetTotalSize (fm);
 
111
        /* get data */
 
112
        FrameMgrGetToken (fm, major_opcode);
 
113
        FrameMgrGetToken (fm, minor_opcode);
 
114
        FrameMgrGetToken (fm, length);
 
115
        FrameMgrFree (fm);
 
116
 
 
117
        if ((p = (unsigned char *) malloc (total_size + length * 4)) == NULL)
 
118
            return (unsigned char *) NULL;
 
119
 
 
120
        p1 = p;
 
121
        memmove (p1, &major_opcode, sizeof (CARD8));
 
122
        p1 += sizeof (CARD8);
 
123
        memmove (p1, &minor_opcode, sizeof (CARD8));
 
124
        p1 += sizeof (CARD8);
 
125
        memmove (p1, &length, sizeof (CARD16));
 
126
        p1 += sizeof (CARD16);
 
127
        memmove (p1, rec, length * 4);
 
128
    }
 
129
    else if (ev->format == 32) {
 
130
        /* ClientMessage and WindowProperty */
 
131
        unsigned long length = (unsigned long) ev->data.l[0];
 
132
        unsigned long get_length;
 
133
        Atom atom = (Atom) ev->data.l[1];
 
134
        int return_code;
 
135
        Atom actual_type_ret;
 
136
        int actual_format_ret;
 
137
        unsigned long bytes_after_ret;
 
138
        unsigned char *prop;
 
139
        unsigned long nitems;
 
140
 
 
141
        /* Round up length to next 4 byte value. */
 
142
        get_length = length + 3;
 
143
        if (get_length > LONG_MAX)
 
144
            get_length = LONG_MAX;
 
145
        get_length /= 4;
 
146
        if (get_length == 0) {
 
147
            fprintf(stderr, "%s: invalid length 0\n", __func__);
 
148
            return NULL;
 
149
        }
 
150
        return_code = XGetWindowProperty (i18n_core->address.dpy,
 
151
                                          x_client->accept_win,
 
152
                                          atom,
 
153
                                          client->property_offset / 4,
 
154
                                          get_length,
 
155
                                          True,
 
156
                                          AnyPropertyType,
 
157
                                          &actual_type_ret,
 
158
                                          &actual_format_ret,
 
159
                                          &nitems,
 
160
                                          &bytes_after_ret,
 
161
                                          &prop);
 
162
        if (return_code != Success || actual_format_ret == 0 || nitems == 0) {
 
163
            if (return_code == Success)
 
164
                XFree (prop);
 
165
            client->property_offset = 0;
 
166
            return (unsigned char *) NULL;
 
167
        }
 
168
        /* Update the offset to read next time as needed */
 
169
        if (bytes_after_ret > 0)
 
170
            client->property_offset += length;
 
171
        else
 
172
            client->property_offset = 0;
 
173
        switch (actual_format_ret) {
 
174
        case 8:
 
175
        case 16:
 
176
        case 32:
 
177
            length = nitems * actual_format_ret / 8;
 
178
            break;
 
179
        default:
 
180
            fprintf(stderr, "%s: unknown property return format: %d\n",
 
181
                        __func__, actual_format_ret);
 
182
            XFree(prop);
 
183
            client->property_offset = 0;
 
184
            return NULL;
 
185
        }
 
186
        /* if hit, it might be an error */
 
187
        if ((p = (unsigned char *) malloc (length)) == NULL)
 
188
            return (unsigned char *) NULL;
 
189
 
 
190
        memmove (p, prop, length);
 
191
        XFree (prop);
 
192
    }
 
193
    return (unsigned char *) p;
 
194
}
 
195
 
 
196
static void ReadXConnectMessage (XIMS ims, XClientMessageEvent *ev)
 
197
{
 
198
    Xi18n i18n_core = ims->protocol;
 
199
    XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
 
200
    XEvent event;
 
201
    Display *dpy = i18n_core->address.dpy;
 
202
    Window new_client = ev->data.l[0];
 
203
    CARD32 major_version = ev->data.l[1];
 
204
    CARD32 minor_version = ev->data.l[2];
 
205
    XClient *x_client = NewXClient (i18n_core, new_client);
 
206
 
 
207
    if (ev->window != i18n_core->address.im_window)
 
208
        return; /* incorrect connection request */
 
209
    /*endif*/
 
210
    if (major_version != 0  ||  minor_version != 0)
 
211
    {
 
212
        major_version =
 
213
        minor_version = 0;
 
214
        /* Only supporting only-CM & Property-with-CM method */
 
215
    }
 
216
    /*endif*/
 
217
    _XRegisterFilterByType (dpy,
 
218
                            x_client->accept_win,
 
219
                            ClientMessage,
 
220
                            ClientMessage,
 
221
                            WaitXIMProtocol,
 
222
                            (XPointer)ims);
 
223
    event.xclient.type = ClientMessage;
 
224
    event.xclient.display = dpy;
 
225
    event.xclient.window = new_client;
 
226
    event.xclient.message_type = spec->connect_request;
 
227
    event.xclient.format = 32;
 
228
    event.xclient.data.l[0] = x_client->accept_win;
 
229
    event.xclient.data.l[1] = major_version;
 
230
    event.xclient.data.l[2] = minor_version;
 
231
    event.xclient.data.l[3] = XCM_DATA_LIMIT;
 
232
 
 
233
    XSendEvent (dpy,
 
234
                new_client,
 
235
                False,
 
236
                NoEventMask,
 
237
                &event);
 
238
    XFlush (dpy);
 
239
}
 
240
 
 
241
static Bool Xi18nXBegin (XIMS ims)
 
242
{
 
243
    Xi18n i18n_core = ims->protocol;
 
244
    Display *dpy = i18n_core->address.dpy;
 
245
    XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
 
246
 
 
247
    spec->xim_request = XInternAtom (i18n_core->address.dpy,
 
248
                                     _XIM_PROTOCOL,
 
249
                                     False);
 
250
    spec->connect_request = XInternAtom (i18n_core->address.dpy,
 
251
                                         _XIM_XCONNECT,
 
252
                                         False);
 
253
 
 
254
    _XRegisterFilterByType (dpy,
 
255
                            i18n_core->address.im_window,
 
256
                            ClientMessage,
 
257
                            ClientMessage,
 
258
                            WaitXConnectMessage,
 
259
                            (XPointer)ims);
 
260
    return True;
 
261
}
 
262
 
 
263
static Bool Xi18nXEnd(XIMS ims)
 
264
{
 
265
    Xi18n i18n_core = ims->protocol;
 
266
    Display *dpy = i18n_core->address.dpy;
 
267
 
 
268
    _XUnregisterFilter (dpy,
 
269
                        i18n_core->address.im_window,
 
270
                        WaitXConnectMessage,
 
271
                        (XPointer)ims);
 
272
    return True;
 
273
}
 
274
 
 
275
static char *MakeNewAtom (CARD16 connect_id, char *atomName)
 
276
{
 
277
    static int sequence = 0;
 
278
 
 
279
    sprintf (atomName,
 
280
             "_server%d_%d",
 
281
             connect_id,
 
282
             ((sequence > 20)  ?  (sequence = 0)  :  sequence++));
 
283
    return atomName;
 
284
}
 
285
 
 
286
static Bool Xi18nXSend (XIMS ims,
 
287
                        CARD16 connect_id,
 
288
                        unsigned char *reply,
 
289
                        long length)
 
290
{
 
291
    Xi18n i18n_core = ims->protocol;
 
292
    Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id);
 
293
    XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
 
294
    XClient *x_client = (XClient *) client->trans_rec;
 
295
    XEvent event;
 
296
 
 
297
    memset(&event, 0, sizeof(XEvent));
 
298
    event.type = ClientMessage;
 
299
    event.xclient.serial = 0;
 
300
    event.xclient.send_event = True;
 
301
    event.xclient.display = i18n_core->address.dpy;
 
302
    event.xclient.window = x_client->client_win;
 
303
    event.xclient.message_type = spec->xim_request;
 
304
 
 
305
    if (length > XCM_DATA_LIMIT)
 
306
    {
 
307
        Atom atom;
 
308
        char atomName[16];
 
309
        Atom actual_type_ret;
 
310
        int actual_format_ret;
 
311
        int return_code;
 
312
        unsigned long nitems_ret;
 
313
        unsigned long bytes_after_ret;
 
314
        unsigned char *win_data;
 
315
 
 
316
        event.xclient.format = 32;
 
317
        atom = XInternAtom (i18n_core->address.dpy,
 
318
                            MakeNewAtom (connect_id, atomName),
 
319
                            False);
 
320
        return_code = XGetWindowProperty (i18n_core->address.dpy,
 
321
                                          x_client->client_win,
 
322
                                          atom,
 
323
                                          0L,
 
324
                                          10000L,
 
325
                                          False,
 
326
                                          XA_STRING,
 
327
                                          &actual_type_ret,
 
328
                                          &actual_format_ret,
 
329
                                          &nitems_ret,
 
330
                                          &bytes_after_ret,
 
331
                                          &win_data);
 
332
        if (return_code != Success)
 
333
            return False;
 
334
        /*endif*/
 
335
        if (win_data)
 
336
            XFree ((char *) win_data);
 
337
        /*endif*/
 
338
        XChangeProperty (i18n_core->address.dpy,
 
339
                         x_client->client_win,
 
340
                         atom,
 
341
                         XA_STRING,
 
342
                         8,
 
343
                         PropModeAppend,
 
344
                         (unsigned char *) reply,
 
345
                         length);
 
346
        event.xclient.data.l[0] = length;
 
347
        event.xclient.data.l[1] = atom;
 
348
    }
 
349
    else
 
350
    {
 
351
        unsigned char buffer[XCM_DATA_LIMIT];
 
352
        int i;
 
353
 
 
354
        event.xclient.format = 8;
 
355
 
 
356
        /* Clear unused field with NULL */
 
357
        memmove(buffer, reply, length);
 
358
        for (i = length; i < XCM_DATA_LIMIT; i++)
 
359
            buffer[i] = (char) 0;
 
360
        /*endfor*/
 
361
        length = XCM_DATA_LIMIT;
 
362
        memmove (event.xclient.data.b, buffer, length);
 
363
    }
 
364
    XSendEvent (i18n_core->address.dpy,
 
365
                x_client->client_win,
 
366
                False,
 
367
                NoEventMask,
 
368
                &event);
 
369
    XFlush (i18n_core->address.dpy);
 
370
    return True;
 
371
}
 
372
 
 
373
static Bool CheckCMEvent (Display *display, XEvent *event, XPointer xi18n_core)
 
374
{
 
375
    Xi18n i18n_core = (Xi18n) ((void *) xi18n_core);
 
376
    XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
 
377
 
 
378
    if ((event->type == ClientMessage)
 
379
        &&
 
380
        (event->xclient.message_type == spec->xim_request))
 
381
    {
 
382
        return  True;
 
383
    }
 
384
    /*endif*/
 
385
    return  False;
 
386
}
 
387
 
 
388
static Bool Xi18nXWait (XIMS ims,
 
389
                        CARD16 connect_id,
 
390
                        CARD8 major_opcode,
 
391
                        CARD8 minor_opcode)
 
392
{
 
393
    Xi18n i18n_core = ims->protocol;
 
394
    XEvent event;
 
395
    Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id);
 
396
    XClient *x_client = (XClient *) client->trans_rec;
 
397
 
 
398
    for (;;)
 
399
    {
 
400
        unsigned char *packet;
 
401
        XimProtoHdr *hdr;
 
402
        int connect_id_ret;
 
403
 
 
404
        XIfEvent (i18n_core->address.dpy,
 
405
                  &event,
 
406
                  CheckCMEvent,
 
407
                  (XPointer) i18n_core);
 
408
        if (event.xclient.window == x_client->accept_win)
 
409
        {
 
410
            if ((packet = ReadXIMMessage (ims,
 
411
                                          (XClientMessageEvent *) & event,
 
412
                                          &connect_id_ret))
 
413
                == (unsigned char*) NULL)
 
414
            {
 
415
                return False;
 
416
            }
 
417
            /*endif*/
 
418
            hdr = (XimProtoHdr *)packet;
 
419
 
 
420
            if ((hdr->major_opcode == major_opcode)
 
421
                &&
 
422
                (hdr->minor_opcode == minor_opcode))
 
423
            {
 
424
                return True;
 
425
            }
 
426
            else if (hdr->major_opcode == XIM_ERROR)
 
427
            {
 
428
                return False;
 
429
            }
 
430
            /*endif*/
 
431
        }
 
432
        /*endif*/
 
433
    }
 
434
    /*endfor*/
 
435
}
 
436
 
 
437
static Bool Xi18nXDisconnect (XIMS ims, CARD16 connect_id)
 
438
{
 
439
    Xi18n i18n_core = ims->protocol;
 
440
    Display *dpy = i18n_core->address.dpy;
 
441
    Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id);
 
442
    XClient *x_client = (XClient *) client->trans_rec;
 
443
 
 
444
    XDestroyWindow (dpy, x_client->accept_win);
 
445
    _XUnregisterFilter (dpy,
 
446
                        x_client->accept_win,
 
447
                        WaitXIMProtocol,
 
448
                        (XPointer)ims);
 
449
    XFree (x_client);
 
450
    _Xi18nDeleteClient (i18n_core, connect_id);
 
451
    return True;
 
452
}
 
453
 
 
454
Bool _Xi18nCheckXAddress (Xi18n i18n_core,
 
455
                          TransportSW *transSW,
 
456
                          char *address)
 
457
{
 
458
    XSpecRec *spec;
 
459
 
 
460
    if (!(spec = (XSpecRec *) malloc (sizeof (XSpecRec))))
 
461
        return False;
 
462
    /*endif*/
 
463
 
 
464
    i18n_core->address.connect_addr = (XSpecRec *) spec;
 
465
    i18n_core->methods.begin = Xi18nXBegin;
 
466
    i18n_core->methods.end = Xi18nXEnd;
 
467
    i18n_core->methods.send = Xi18nXSend;
 
468
    i18n_core->methods.wait = Xi18nXWait;
 
469
    i18n_core->methods.disconnect = Xi18nXDisconnect;
 
470
    return True;
 
471
}
 
472
 
 
473
static Bool WaitXConnectMessage (Display *dpy,
 
474
                                 Window win,
 
475
                                 XEvent *ev,
 
476
                                 XPointer client_data)
 
477
{
 
478
    XIMS ims = (XIMS)client_data;
 
479
    Xi18n i18n_core = ims->protocol;
 
480
    XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
 
481
 
 
482
    if (((XClientMessageEvent *) ev)->message_type
 
483
        == spec->connect_request)
 
484
    {
 
485
        ReadXConnectMessage (ims, (XClientMessageEvent *) ev);
 
486
        return True;
 
487
    }
 
488
    /*endif*/
 
489
    return False;
 
490
}
 
491
 
 
492
static Bool WaitXIMProtocol (Display *dpy,
 
493
                             Window win,
 
494
                             XEvent *ev,
 
495
                             XPointer client_data)
 
496
{
 
497
    extern void _Xi18nMessageHandler (XIMS, CARD16, unsigned char *, Bool *);
 
498
    XIMS ims = (XIMS) client_data;
 
499
    Xi18n i18n_core = ims->protocol;
 
500
    XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
 
501
    Bool delete = True;
 
502
    unsigned char *packet;
 
503
    int connect_id;
 
504
 
 
505
    if (((XClientMessageEvent *) ev)->message_type
 
506
        == spec->xim_request)
 
507
    {
 
508
        if ((packet = ReadXIMMessage (ims,
 
509
                                      (XClientMessageEvent *) ev,
 
510
                                      &connect_id))
 
511
            == (unsigned char *)  NULL)
 
512
        {
 
513
            return False;
 
514
        }
 
515
        /*endif*/
 
516
        _Xi18nMessageHandler (ims, connect_id, packet, &delete);
 
517
        if (delete == True)
 
518
            XFree (packet);
 
519
        /*endif*/
 
520
        return True;
 
521
    }
 
522
    /*endif*/
 
523
    return False;
 
524
}