diff options
Diffstat (limited to 'src/misc.c')
-rw-r--r-- | src/misc.c | 621 |
1 files changed, 621 insertions, 0 deletions
diff --git a/src/misc.c b/src/misc.c new file mode 100644 index 0000000..0ed98b0 --- /dev/null +++ b/src/misc.c @@ -0,0 +1,621 @@ +/* $Xorg: misc.c,v 1.4 2001/02/09 02:03:26 xorgcvs Exp $ */ +/****************************************************************************** + + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Author: Ralph Mor, X Consortium +******************************************************************************/ + +#ifdef WIN32 +#define _WILLWINSOCK_ +#endif +#include <X11/ICE/ICElib.h> +#include "ICElibint.h" +#include <X11/Xtrans.h> +#include <stdio.h> +#ifdef WIN32 +#include <X11/Xwinsock.h> +#include <X11/Xw32defs.h> +#endif + + +/* + * scratch buffer + */ + +char * +IceAllocScratch (iceConn, size) + +IceConn iceConn; +unsigned long size; + +{ + if (!iceConn->scratch || size > iceConn->scratch_size) + { + if (iceConn->scratch) + free (iceConn->scratch); + + iceConn->scratch = (char *) malloc ((unsigned) size); + iceConn->scratch_size = size; + } + + return (iceConn->scratch); +} + + + +/* + * Output/Input buffer functions + */ + +IceFlush (iceConn) + +IceConn iceConn; + +{ + _IceWrite (iceConn, + (unsigned long) (iceConn->outbufptr - iceConn->outbuf), + iceConn->outbuf); + + iceConn->outbufptr = iceConn->outbuf; + return 1; +} + + +int +IceGetOutBufSize (iceConn) + +IceConn iceConn; + +{ + return (iceConn->outbufmax - iceConn->outbuf); +} + + +int +IceGetInBufSize (iceConn) + +IceConn iceConn; + +{ + return (iceConn->inbufmax - iceConn->inbuf); +} + + + +/* + * informational functions + */ + +IceConnectStatus +IceConnectionStatus (iceConn) + +IceConn iceConn; + +{ + return (iceConn->connection_status); +} + + +char * +IceVendor (iceConn) + +IceConn iceConn; + +{ + char *string = (char *) malloc (strlen (iceConn->vendor) + 1); + + if (string) + strcpy (string, iceConn->vendor); + + return (string); +} + + +char * +IceRelease (iceConn) + +IceConn iceConn; + +{ + char *string = (char *) malloc (strlen (iceConn->release) + 1); + + if (string) + strcpy (string, iceConn->release); + + return (string); +} + + +int +IceProtocolVersion (iceConn) + +IceConn iceConn; + +{ + return (_IceVersions[iceConn->my_ice_version_index].major_version); +} + + +int +IceProtocolRevision (iceConn) + +IceConn iceConn; + +{ + return (_IceVersions[iceConn->my_ice_version_index].minor_version); +} + + +int +IceConnectionNumber (iceConn) + +IceConn iceConn; + +{ + return (_IceTransGetConnectionNumber (iceConn->trans_conn)); +} + + +char * +IceConnectionString (iceConn) + +IceConn iceConn; + +{ + if (iceConn->connection_string) + { + char *string = (char *) malloc ( + strlen (iceConn->connection_string) + 1); + + if (string) + strcpy (string, iceConn->connection_string); + + return (string); + } + else + return (NULL); +} + + +unsigned long +IceLastSentSequenceNumber (iceConn) + +IceConn iceConn; + +{ + return (iceConn->send_sequence); +} + + +unsigned long +IceLastReceivedSequenceNumber (iceConn) + +IceConn iceConn; + +{ + return (iceConn->receive_sequence); +} + + +Bool +IceSwapping (iceConn) + +IceConn iceConn; + +{ + return (iceConn->swap); +} + + + +/* + * Read "n" bytes from a connection. + * + * Return Status 0 if we detected an EXPECTED closed connection. + * + */ + +Status +_IceRead (iceConn, nbytes, ptr) + +register IceConn iceConn; +unsigned long nbytes; +register char *ptr; + +{ + register unsigned long nleft; + + nleft = nbytes; + while (nleft > 0) + { + int nread; + + if (iceConn->io_ok) + nread = _IceTransRead (iceConn->trans_conn, ptr, (int) nleft); + else + return (1); + + if (nread <= 0) + { +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + if (iceConn->want_to_close) + { + /* + * We sent a WantToClose message and now we detected that + * the other side closed the connection. + */ + + _IceConnectionClosed (iceConn); /* invoke watch procs */ + _IceFreeConnection (iceConn); + + return (0); + } + else + { + /* + * Fatal IO error. First notify each protocol's IceIOErrorProc + * callback, then invoke the application IO error handler. + */ + + iceConn->io_ok = False; + + if (iceConn->connection_status == IceConnectPending) + { + /* + * Don't invoke IO error handler if we are in the + * middle of a connection setup. + */ + + return (1); + } + + if (iceConn->process_msg_info) + { + int i; + + for (i = iceConn->his_min_opcode; + i <= iceConn->his_max_opcode; i++) + { + _IceProcessMsgInfo *process; + + process = &iceConn->process_msg_info[ + i - iceConn->his_min_opcode]; + + if (process->in_use) + { + IceIOErrorProc IOErrProc = process->accept_flag ? + process->protocol->accept_client->io_error_proc : + process->protocol->orig_client->io_error_proc; + + if (IOErrProc) + (*IOErrProc) (iceConn); + } + } + } + + (*_IceIOErrorHandler) (iceConn); + return (1); + } + } + + nleft -= nread; + ptr += nread; + } + + return (1); +} + + + +/* + * If we read a message header with a bad major or minor opcode, + * we need to advance to the end of the message. This way, the next + * message can be processed correctly. + */ + +void +_IceReadSkip (iceConn, nbytes) + +register IceConn iceConn; +register unsigned long nbytes; + +{ + char temp[512]; + + while (nbytes > 0) + { + unsigned long rbytes = nbytes > 512 ? 512 : nbytes; + + _IceRead (iceConn, rbytes, temp); + nbytes -= rbytes; + } +} + + + +/* + * Write "n" bytes to a connection. + */ + +void +_IceWrite (iceConn, nbytes, ptr) + +register IceConn iceConn; +unsigned long nbytes; +register char *ptr; + +{ + register unsigned long nleft; + + nleft = nbytes; + while (nleft > 0) + { + int nwritten; + + if (iceConn->io_ok) + nwritten = _IceTransWrite (iceConn->trans_conn, ptr, (int) nleft); + else + return; + + if (nwritten <= 0) + { +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + /* + * Fatal IO error. First notify each protocol's IceIOErrorProc + * callback, then invoke the application IO error handler. + */ + + iceConn->io_ok = False; + + if (iceConn->connection_status == IceConnectPending) + { + /* + * Don't invoke IO error handler if we are in the + * middle of a connection setup. + */ + + return; + } + + if (iceConn->process_msg_info) + { + int i; + + for (i = iceConn->his_min_opcode; + i <= iceConn->his_max_opcode; i++) + { + _IceProcessMsgInfo *process; + + process = &iceConn->process_msg_info[ + i - iceConn->his_min_opcode]; + + if (process->in_use) + { + IceIOErrorProc IOErrProc = process->accept_flag ? + process->protocol->accept_client->io_error_proc : + process->protocol->orig_client->io_error_proc; + + if (IOErrProc) + (*IOErrProc) (iceConn); + } + } + } + + (*_IceIOErrorHandler) (iceConn); + return; + } + + nleft -= nwritten; + ptr += nwritten; + } +} + +#ifdef WORD64 + +IceWriteData16 (iceConn, nbytes, data) + +IceConn iceConn; +unsigned long nbytes; +short *data; + +{ + int numShorts = nbytes / 2; + int index = 0; + + while (index < numShorts) + { + int spaceLeft, count, i; + int shortsLeft = numShorts - index; + + spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; + + if (spaceLeft < 2) + { + IceFlush (iceConn); + spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; + } + + count = (shortsLeft < spaceLeft / 2) ? shortsLeft : spaceLeft / 2; + + for (i = 0; i < count; i++) + STORE_CARD16 (iceConn->outbufptr, data[index++]); + } +} + + +IceWriteData32 (iceConn, nbytes, data) + +IceConn iceConn; +unsigned long nbytes; +int *data; + +{ + int numLongs = nbytes / 4; + int index = 0; + + while (index < numLongs) + { + int spaceLeft, count, i; + int longsLeft = numLongs - index; + + spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; + + if (spaceLeft < 4) + { + IceFlush (iceConn); + spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; + } + + count = (longsLeft < spaceLeft / 4) ? longsLeft : spaceLeft / 4; + + for (i = 0; i < count; i++) + STORE_CARD32 (iceConn->outbufptr, data[index++]); + } +} + + +IceReadData16 (iceConn, swap, nbytes, data) + +IceConn iceConn; +Bool swap; +unsigned long nbytes; +short *data; + +{ + /* NOT IMPLEMENTED YET */ +} + + +IceReadData32 (iceConn, swap, nbytes, data) + +IceConn iceConn; +Bool swap; +unsigned long nbytes; +int *data; + +{ + /* NOT IMPLEMENTED YET */ +} + +#endif /* WORD64 */ + + + +void +_IceAddOpcodeMapping (iceConn, hisOpcode, myOpcode) + +IceConn iceConn; +int hisOpcode; +int myOpcode; + +{ + if (hisOpcode <= 0 || hisOpcode > 255) + { + return; + } + else if (iceConn->process_msg_info == NULL) + { + iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc ( + sizeof (_IceProcessMsgInfo)); + iceConn->his_min_opcode = iceConn->his_max_opcode = hisOpcode; + } + else if (hisOpcode < iceConn->his_min_opcode) + { + _IceProcessMsgInfo *oldVec = iceConn->process_msg_info; + int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1; + int newsize = iceConn->his_max_opcode - hisOpcode + 1; + int i; + + iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc ( + newsize * sizeof (_IceProcessMsgInfo)); + + memcpy (&iceConn->process_msg_info[ + iceConn->his_min_opcode - hisOpcode], oldVec, + oldsize * sizeof (_IceProcessMsgInfo)); + + free ((char *) oldVec); + + for (i = hisOpcode + 1; i < iceConn->his_min_opcode; i++) + { + iceConn->process_msg_info[i - + iceConn->his_min_opcode].in_use = False; + + iceConn->process_msg_info[i - + iceConn->his_min_opcode].protocol = NULL; + } + + iceConn->his_min_opcode = hisOpcode; + } + else if (hisOpcode > iceConn->his_max_opcode) + { + _IceProcessMsgInfo *oldVec = iceConn->process_msg_info; + int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1; + int newsize = hisOpcode - iceConn->his_min_opcode + 1; + int i; + + iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc ( + newsize * sizeof (_IceProcessMsgInfo)); + + memcpy (iceConn->process_msg_info, oldVec, + oldsize * sizeof (_IceProcessMsgInfo)); + + free ((char *) oldVec); + + for (i = iceConn->his_max_opcode + 1; i < hisOpcode; i++) + { + iceConn->process_msg_info[i - + iceConn->his_min_opcode].in_use = False; + + iceConn->process_msg_info[i - + iceConn->his_min_opcode].protocol = NULL; + } + + iceConn->his_max_opcode = hisOpcode; + } + + iceConn->process_msg_info[hisOpcode - + iceConn->his_min_opcode].in_use = True; + + iceConn->process_msg_info[hisOpcode - + iceConn->his_min_opcode].my_opcode = myOpcode; + + iceConn->process_msg_info[hisOpcode - + iceConn->his_min_opcode].protocol = &_IceProtocols[myOpcode - 1]; +} + + + +char * +_IceGetPeerName (iceConn) + +IceConn iceConn; + +{ + return (_IceTransGetPeerNetworkId (iceConn->trans_conn)); +} |