void rfbSendInteractionCaps(rfbClientPtr cl)
{
  rfbInteractionCapsMsg intr_caps;
  rfbCapabilityInfo enc_list[N_ENC_CAPS];
  int i;

  /* Fill in the header structure sent prior to capability lists. */
  intr_caps.nServerMessageTypes = Swap16IfLE(N_SMSG_CAPS);
  intr_caps.nClientMessageTypes = Swap16IfLE(N_CMSG_CAPS);
  intr_caps.nEncodingTypes = Swap16IfLE(N_ENC_CAPS);
  intr_caps.pad = 0;

  /* Supported server->client message types. */
  /* For future file transfer support:
  i = 0;
  SetCapInfo(&smsg_list[i++], rfbFileListData,           rfbTightVncVendor);
  SetCapInfo(&smsg_list[i++], rfbFileDownloadData,       rfbTightVncVendor);
  SetCapInfo(&smsg_list[i++], rfbFileUploadCancel,       rfbTightVncVendor);
  SetCapInfo(&smsg_list[i++], rfbFileDownloadFailed,     rfbTightVncVendor);
  if (i != N_SMSG_CAPS) {
    rfbLog("rfbSendInteractionCaps: assertion failed, i != N_SMSG_CAPS\n");
    rfbCloseClient(cl);
    return;
  }
  */

  /* Supported client->server message types. */
  /* For future file transfer support:
  i = 0;
  SetCapInfo(&cmsg_list[i++], rfbFileListRequest,        rfbTightVncVendor);
  SetCapInfo(&cmsg_list[i++], rfbFileDownloadRequest,    rfbTightVncVendor);
  SetCapInfo(&cmsg_list[i++], rfbFileUploadRequest,      rfbTightVncVendor);
  SetCapInfo(&cmsg_list[i++], rfbFileUploadData,         rfbTightVncVendor);
  SetCapInfo(&cmsg_list[i++], rfbFileDownloadCancel,     rfbTightVncVendor);
  SetCapInfo(&cmsg_list[i++], rfbFileUploadFailed,       rfbTightVncVendor);
  if (i != N_CMSG_CAPS) {
    rfbLog("rfbSendInteractionCaps: assertion failed, i != N_CMSG_CAPS\n");
    rfbCloseClient(cl);
    return;
  }
  */

  /* Encoding types. */
  i = 0;
  SetCapInfo(&enc_list[i++],  rfbEncodingCopyRect,       rfbStandardVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingRRE,            rfbStandardVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingCoRRE,          rfbStandardVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingHextile,        rfbStandardVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingZlib,           rfbTridiaVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingZRLE,           rfbTridiaVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingZYWRLE,         rfbTridiaVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingTight,          rfbTightVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingCompressLevel0, rfbTightVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingQualityLevel0,  rfbTightVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingFineQualityLevel0, rfbTurboVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingSubsamp1X,         rfbTurboVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingXCursor,        rfbTightVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingRichCursor,     rfbTightVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingPointerPos,     rfbTightVncVendor);
  SetCapInfo(&enc_list[i++],  rfbEncodingLastRect,       rfbTightVncVendor);
  SetCapInfo(&enc_list[i++],  rfbGIIServer,              rfbGIIVendor);
  if (i != N_ENC_CAPS) {
    rfbLog("rfbSendInteractionCaps: assertion failed, i != N_ENC_CAPS\n");
    rfbCloseClient(cl);
    return;
  }

  /* Send header and capability lists */
  if (WriteExact(cl, (char *)&intr_caps,
                 sz_rfbInteractionCapsMsg) < 0 ||
      WriteExact(cl, (char *)&enc_list[0],
                 sz_rfbCapabilityInfo * N_ENC_CAPS) < 0) {
    rfbLogPerror("rfbSendInteractionCaps: write");
    rfbCloseClient(cl);
    return;
  }

  /* Dispatch client input to rfbProcessClientNormalMessage(). */
  cl->state = RFB_NORMAL;
}