upload tizen2.0 source
[framework/uifw/xorg/lib/libice.git] / src / misc.c
1 /******************************************************************************
2
3
4 Copyright 1993, 1998  The Open Group
5
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of The Open Group shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from The Open Group.
25
26 Author: Ralph Mor, X Consortium
27 ******************************************************************************/
28
29 #ifdef WIN32
30 #define _WILLWINSOCK_
31 #endif
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35 #include <X11/ICE/ICElib.h>
36 #include "ICElibint.h"
37 #include <X11/Xtrans/Xtrans.h>
38 #include <stdio.h>
39 #ifdef WIN32
40 #include <X11/Xwinsock.h>
41 #include <X11/Xw32defs.h>
42 #endif
43
44 \f
45 /*
46  * scratch buffer
47  */
48
49 char *
50 IceAllocScratch (
51         IceConn         iceConn,
52         unsigned long   size
53 )
54 {
55     if (!iceConn->scratch || size > iceConn->scratch_size)
56     {
57         if (iceConn->scratch)
58             free (iceConn->scratch);
59
60         iceConn->scratch = (char *) malloc ((unsigned) size);
61         iceConn->scratch_size = size;
62     }
63
64     return (iceConn->scratch);
65 }
66
67
68 \f
69 /*
70  * Output/Input buffer functions
71  */
72
73 int
74 IceFlush (
75         IceConn iceConn
76 )
77 {
78     _IceWrite (iceConn,
79         (unsigned long) (iceConn->outbufptr - iceConn->outbuf),
80         iceConn->outbuf);
81
82     iceConn->outbufptr = iceConn->outbuf;
83     return 1;
84 }
85
86
87 int
88 IceGetOutBufSize (
89         IceConn iceConn
90 )
91 {
92     return (iceConn->outbufmax - iceConn->outbuf);
93 }
94
95
96 int
97 IceGetInBufSize (
98         IceConn iceConn
99 )
100 {
101     return (iceConn->inbufmax - iceConn->inbuf);
102 }
103
104
105 \f
106 /*
107  * informational functions
108  */
109
110 IceConnectStatus
111 IceConnectionStatus (
112         IceConn iceConn
113 )
114 {
115     return (iceConn->connection_status);
116 }
117
118
119 char *
120 IceVendor (
121         IceConn iceConn
122 )
123 {
124     return strdup(iceConn->vendor);
125 }
126
127
128 char *
129 IceRelease (
130         IceConn iceConn
131 )
132 {
133     return strdup(iceConn->release);
134 }
135
136
137 int
138 IceProtocolVersion (
139         IceConn iceConn
140 )
141 {
142     return (_IceVersions[iceConn->my_ice_version_index].major_version);
143 }
144
145
146 int
147 IceProtocolRevision (
148         IceConn iceConn
149 )
150 {
151     return (_IceVersions[iceConn->my_ice_version_index].minor_version);
152 }
153
154
155 int
156 IceConnectionNumber (
157         IceConn iceConn
158 )
159 {
160     return (_IceTransGetConnectionNumber (iceConn->trans_conn));
161 }
162
163
164 char *
165 IceConnectionString (
166         IceConn iceConn
167 )
168 {
169     if (iceConn->connection_string)
170     {
171         return strdup(iceConn->connection_string);
172     }
173     else
174         return (NULL);
175 }
176
177
178 unsigned long
179 IceLastSentSequenceNumber (
180         IceConn iceConn
181 )
182 {
183     return (iceConn->send_sequence);
184 }
185
186
187 unsigned long
188 IceLastReceivedSequenceNumber (
189         IceConn iceConn
190 )
191 {
192     return (iceConn->receive_sequence);
193 }
194
195
196 Bool
197 IceSwapping (
198         IceConn iceConn
199 )
200 {
201     return (iceConn->swap);
202 }
203
204
205 \f
206 /*
207  * Read "n" bytes from a connection.
208  *
209  * Return Status 0 if we detected an EXPECTED closed connection.
210  *
211  */
212
213 Status
214 _IceRead (
215         register IceConn iceConn,
216         unsigned long    nbytes,
217         register char    *ptr
218 )
219 {
220     register unsigned long nleft;
221
222     nleft = nbytes;
223     while (nleft > 0)
224     {
225         int nread;
226
227         if (iceConn->io_ok)
228             nread = _IceTransRead (iceConn->trans_conn, ptr, (int) nleft);
229         else
230             return (1);
231
232         if (nread <= 0)
233         {
234 #ifdef WIN32
235             errno = WSAGetLastError();
236 #endif
237             if (iceConn->want_to_close)
238             {
239                 /*
240                  * We sent a WantToClose message and now we detected that
241                  * the other side closed the connection.
242                  */
243
244                 _IceConnectionClosed (iceConn);     /* invoke watch procs */
245                 _IceFreeConnection (iceConn);
246
247                 return (0);
248             }
249             else
250             {
251                 /*
252                  * Fatal IO error.  First notify each protocol's IceIOErrorProc
253                  * callback, then invoke the application IO error handler.
254                  */
255
256                 iceConn->io_ok = False;
257
258                 if (iceConn->connection_status == IceConnectPending)
259                 {
260                     /*
261                      * Don't invoke IO error handler if we are in the
262                      * middle of a connection setup.
263                      */
264
265                     return (1);
266                 }
267
268                 if (iceConn->process_msg_info)
269                 {
270                     int i;
271
272                     for (i = iceConn->his_min_opcode;
273                         i <= iceConn->his_max_opcode; i++)
274                     {
275                         _IceProcessMsgInfo *process;
276
277                         process = &iceConn->process_msg_info[
278                             i - iceConn->his_min_opcode];
279
280                         if ((process != NULL) && process->in_use)
281                         {
282                             IceIOErrorProc IOErrProc = process->accept_flag ?
283                               process->protocol->accept_client->io_error_proc :
284                               process->protocol->orig_client->io_error_proc;
285
286                             if (IOErrProc)
287                                 (*IOErrProc) (iceConn);
288                         }
289                     }
290                 }
291
292                 (*_IceIOErrorHandler) (iceConn);
293                 return (1);
294             }
295         }
296
297         nleft -= nread;
298         ptr   += nread;
299     }
300
301     return (1);
302 }
303
304
305 \f
306 /*
307  * If we read a message header with a bad major or minor opcode,
308  * we need to advance to the end of the message.  This way, the next
309  * message can be processed correctly.
310  */
311
312 void
313 _IceReadSkip (
314         register IceConn        iceConn,
315         register unsigned long  nbytes
316 )
317 {
318     char temp[512];
319
320     while (nbytes > 0)
321     {
322         unsigned long rbytes = nbytes > 512 ? 512 : nbytes;
323
324         _IceRead (iceConn, rbytes, temp);
325         nbytes -= rbytes;
326     }
327 }
328
329
330 \f
331 /*
332  * Write "n" bytes to a connection.
333  */
334
335 void
336 _IceWrite (
337         register IceConn iceConn,
338         unsigned long    nbytes,
339         register char    *ptr
340 )
341 {
342     register unsigned long nleft;
343
344     nleft = nbytes;
345     while (nleft > 0)
346     {
347         int nwritten;
348
349         if (iceConn->io_ok)
350             nwritten = _IceTransWrite (iceConn->trans_conn, ptr, (int) nleft);
351         else
352             return;
353
354         if (nwritten <= 0)
355         {
356 #ifdef WIN32
357             errno = WSAGetLastError();
358 #endif
359             /*
360              * Fatal IO error.  First notify each protocol's IceIOErrorProc
361              * callback, then invoke the application IO error handler.
362              */
363
364             iceConn->io_ok = False;
365
366             if (iceConn->connection_status == IceConnectPending)
367             {
368                 /*
369                  * Don't invoke IO error handler if we are in the
370                  * middle of a connection setup.
371                  */
372
373                 return;
374             }
375
376             if (iceConn->process_msg_info)
377             {
378                 int i;
379
380                 for (i = iceConn->his_min_opcode;
381                      i <= iceConn->his_max_opcode; i++)
382                 {
383                     _IceProcessMsgInfo *process;
384
385                     process = &iceConn->process_msg_info[
386                         i - iceConn->his_min_opcode];
387
388                     if (process->in_use)
389                     {
390                         IceIOErrorProc IOErrProc = process->accept_flag ?
391                             process->protocol->accept_client->io_error_proc :
392                             process->protocol->orig_client->io_error_proc;
393
394                         if (IOErrProc)
395                             (*IOErrProc) (iceConn);
396                     }
397                 }
398             }
399
400             (*_IceIOErrorHandler) (iceConn);
401             return;
402         }
403
404         nleft -= nwritten;
405         ptr   += nwritten;
406     }
407 }
408
409 #ifdef WORD64
410
411 IceWriteData16 (
412         IceConn         iceConn,
413         unsigned long   nbytes,
414         short           *data
415 )
416 {
417     int numShorts = nbytes / 2;
418     int index = 0;
419
420     while (index < numShorts)
421     {
422         int spaceLeft, count, i;
423         int shortsLeft = numShorts - index;
424
425         spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
426
427         if (spaceLeft < 2)
428         {
429             IceFlush (iceConn);
430             spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
431         }
432
433         count = (shortsLeft < spaceLeft / 2) ? shortsLeft : spaceLeft / 2;
434
435         for (i = 0; i < count; i++)
436             STORE_CARD16 (iceConn->outbufptr, data[index++]);
437     }
438 }
439
440
441 IceWriteData32 (
442         IceConn         iceConn,
443         unsigned long   nbytes,
444         int             *data
445 )
446 {
447     int numLongs = nbytes / 4;
448     int index = 0;
449
450     while (index < numLongs)
451     {
452         int spaceLeft, count, i;
453         int longsLeft = numLongs - index;
454
455         spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
456
457         if (spaceLeft < 4)
458         {
459             IceFlush (iceConn);
460             spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
461         }
462
463         count = (longsLeft < spaceLeft / 4) ? longsLeft : spaceLeft / 4;
464
465         for (i = 0; i < count; i++)
466             STORE_CARD32 (iceConn->outbufptr, data[index++]);
467     }
468 }
469
470
471 IceReadData16 (
472         IceConn         iceConn,
473         Bool            swap,
474         unsigned long   nbytes,
475         short           *data
476 )
477 {
478     /* NOT IMPLEMENTED YET */
479 }
480
481
482 IceReadData32 (
483         IceConn         iceConn,
484         Bool            swap,
485         unsigned long   nbytes,
486         int             *data
487 )
488 {
489     /* NOT IMPLEMENTED YET */
490 }
491
492 #endif  /* WORD64 */
493
494
495 \f
496 void
497 _IceAddOpcodeMapping (
498         IceConn iceConn,
499         int     hisOpcode,
500         int     myOpcode
501 )
502 {
503     if (hisOpcode <= 0 || hisOpcode > 255)
504     {
505         return;
506     }
507     else if (iceConn->process_msg_info == NULL)
508     {
509         iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc (
510             sizeof (_IceProcessMsgInfo));
511         iceConn->his_min_opcode = iceConn->his_max_opcode = hisOpcode;
512     }
513     else if (hisOpcode < iceConn->his_min_opcode)
514     {
515         _IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
516         int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
517         int newsize = iceConn->his_max_opcode - hisOpcode + 1;
518         int i;
519
520         iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc (
521             newsize * sizeof (_IceProcessMsgInfo));
522
523         memcpy (&iceConn->process_msg_info[
524             iceConn->his_min_opcode - hisOpcode], oldVec,
525             oldsize * sizeof (_IceProcessMsgInfo));
526
527         free ((char *) oldVec);
528
529         for (i = hisOpcode + 1; i < iceConn->his_min_opcode; i++)
530         {
531             iceConn->process_msg_info[i -
532                 iceConn->his_min_opcode].in_use = False;
533
534             iceConn->process_msg_info[i -
535                 iceConn->his_min_opcode].protocol = NULL;
536         }
537
538         iceConn->his_min_opcode = hisOpcode;
539     }
540     else if (hisOpcode > iceConn->his_max_opcode)
541     {
542         _IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
543         int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
544         int newsize = hisOpcode - iceConn->his_min_opcode + 1;
545         int i;
546
547         iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc (
548             newsize * sizeof (_IceProcessMsgInfo));
549
550         memcpy (iceConn->process_msg_info, oldVec,
551             oldsize * sizeof (_IceProcessMsgInfo));
552
553         free ((char *) oldVec);
554
555         for (i = iceConn->his_max_opcode + 1; i < hisOpcode; i++)
556         {
557             iceConn->process_msg_info[i -
558                 iceConn->his_min_opcode].in_use = False;
559
560             iceConn->process_msg_info[i -
561                 iceConn->his_min_opcode].protocol = NULL;
562         }
563
564         iceConn->his_max_opcode = hisOpcode;
565     }
566
567     iceConn->process_msg_info[hisOpcode -
568         iceConn->his_min_opcode].in_use = True;
569
570     iceConn->process_msg_info[hisOpcode -
571         iceConn->his_min_opcode].my_opcode = myOpcode;
572
573     iceConn->process_msg_info[hisOpcode -
574         iceConn->his_min_opcode].protocol = &_IceProtocols[myOpcode - 1];
575 }
576
577
578 \f
579 char *
580 IceGetPeerName (IceConn iceConn)
581 {
582     return (_IceTransGetPeerNetworkId (iceConn->trans_conn));
583 }
584
585 \f
586 char *
587 _IceGetPeerName (IceConn iceConn)
588 {
589     return (IceGetPeerName(iceConn));
590 }