#include <X11/ICE/ICElib.h>
#include "ICElibint.h"
#include <X11/Xtrans.h>
Status
IceProtocolShutdown (iceConn, majorOpcode)
IceConn iceConn;
int majorOpcode;
{
if (iceConn->proto_ref_count == 0 || iceConn->process_msg_info == NULL ||
majorOpcode < 1 || majorOpcode > _IceLastMajorOpcode)
{
return (0);
}
else
{
int i;
for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++)
{
if (iceConn->process_msg_info[
i - iceConn->his_min_opcode].in_use &&
iceConn->process_msg_info[
i - iceConn->his_min_opcode].my_opcode == majorOpcode)
break;
}
if (i > iceConn->his_max_opcode)
{
return (0);
}
else
{
iceConn->process_msg_info[
i - iceConn->his_min_opcode].in_use = False;
iceConn->proto_ref_count--;
return (1);
}
}
}
void
IceSetShutdownNegotiation (iceConn, negotiate)
IceConn iceConn;
Bool negotiate;
{
iceConn->skip_want_to_close = negotiate ? False : True;
}
Bool
IceCheckShutdownNegotiation (iceConn)
IceConn iceConn;
{
return (iceConn->skip_want_to_close ? False : True);
}
IceCloseStatus
IceCloseConnection (iceConn)
IceConn iceConn;
{
int refCountReachedZero;
IceCloseStatus status;
if (iceConn->listen_obj &&
iceConn->connection_status != IceConnectAccepted)
{
_IceConnectionClosed (iceConn);
_IceFreeConnection (iceConn);
return (IceClosedNow);
}
if (iceConn->open_ref_count > 0)
iceConn->open_ref_count--;
refCountReachedZero = iceConn->open_ref_count == 0 &&
iceConn->proto_ref_count == 0;
status = IceConnectionInUse;
if (!iceConn->free_asap && (!iceConn->io_ok ||
(iceConn->io_ok && refCountReachedZero &&
iceConn->skip_want_to_close)))
{
_IceConnectionClosed (iceConn);
status = IceClosedNow;
}
if (!iceConn->free_asap && iceConn->dispatch_level != 0 &&
(!iceConn->io_ok ||
(iceConn->io_ok && refCountReachedZero &&
iceConn->skip_want_to_close)))
{
iceConn->free_asap = True;
status = IceClosedASAP;
}
if (iceConn->io_ok && iceConn->dispatch_level == 0 &&
!iceConn->skip_want_to_close && refCountReachedZero)
{
IceSimpleMessage (iceConn, 0, ICE_WantToClose);
IceFlush (iceConn);
iceConn->want_to_close = 1;
status = IceStartedShutdownNegotiation;
}
else if (iceConn->dispatch_level == 0 &&
(!iceConn->io_ok || (iceConn->io_ok && iceConn->skip_want_to_close &&
(iceConn->free_asap || (!iceConn->free_asap && refCountReachedZero)))))
{
_IceFreeConnection (iceConn);
status = IceClosedNow;
}
return (status);
}
void
_IceFreeConnection (iceConn)
IceConn iceConn;
{
if (iceConn->listen_obj == NULL)
{
int i;
for (i = 0; i < _IceConnectionCount; i++)
if (_IceConnectionObjs[i] == iceConn)
break;
if (i < _IceConnectionCount)
{
if (i < _IceConnectionCount - 1)
{
_IceConnectionObjs[i] =
_IceConnectionObjs[_IceConnectionCount - 1];
_IceConnectionStrings[i] =
_IceConnectionStrings[_IceConnectionCount - 1];
}
_IceConnectionCount--;
}
}
if (iceConn->trans_conn)
_IceTransClose (iceConn->trans_conn);
if (iceConn->connection_string)
free (iceConn->connection_string);
if (iceConn->vendor)
free (iceConn->vendor);
if (iceConn->release)
free (iceConn->release);
if (iceConn->inbuf)
free (iceConn->inbuf);
if (iceConn->outbuf)
free (iceConn->outbuf);
if (iceConn->scratch)
free (iceConn->scratch);
if (iceConn->process_msg_info)
free ((char *) iceConn->process_msg_info);
if (iceConn->connect_to_you)
free ((char *) iceConn->connect_to_you);
if (iceConn->protosetup_to_you)
free ((char *) iceConn->protosetup_to_you);
if (iceConn->connect_to_me)
free ((char *) iceConn->connect_to_me);
if (iceConn->protosetup_to_me)
free ((char *) iceConn->protosetup_to_me);
free ((char *) iceConn);
}