📄 frame.c
字号:
/*
MDI Frame window handler
*/
#include "netfone.h"
// Variables exported
HWAVEOUT hWaveOut = NULL; // Wave output handle
HWAVEIN hWaveIn = NULL; // Wave input handle
int isWaveSound = FALSE; // Input from wave file ?
int outputActive = FALSE; // Is wave output open ?
int inputActive = FALSE; // Is wave input open ?
int inputPaused = FALSE; // Is input paused for output ?
int openConnections = 0; // Number of open connections
int listeners = 0; // Current wantsInput windows
int broadcasting = FALSE; // Broadcasting to all connections ?
int bConferencing = FALSE; //In conference mode? -BCW 11/30/1997
int bEchoPackets = FALSE; // In Echo Mode? -BCW 10/03/1998
static int outputTimeout = 0; // Output release timeout
long outputPending = 0; // Output buffers in queue
int halfDuplexTransition = FALSE; // Transitioning from output to input ?
int outputInShutdown = FALSE; // Close output when last buffer returned
gsm gsmh = NULL; // GSM handle
rate_t xrate; // Transmit 2X compression context
HCURSOR phoneCursor = NULL,
boltCursor = NULL,
earCursor = NULL; // Cursors
int voxmode = IDM_VOX_NONE; // VOX mode
int breakinput = FALSE; // break input audio stream for output
int compression = FALSE; // 2X compression mode
int gsmcompress = TRUE; // GSM compression mode
int adpcmcompress = FALSE; // ADPCM compression mode
int lpccompress = FALSE; // LPC compression mode
int lpc10compress = FALSE; // LPC-10 compression mode
int robust = 1; // Robust mode for LPC-10
int voxcompress = FALSE; // VOXGSM compression mode
int protocolXmit = PROTOCOL_SPEAKFREE; // Default protocol to send (!protocolAuto or new connection)
int protocolSent = PROTOCOL_SPEAKFREE; // Protocol we're currently sending
int protocolAuto = TRUE; // Send same protocol as received from connection
#ifdef MODEM
int modemEnable = FALSE; // Modem connections enabled ?
char modemInitString[128] = // Modem initialisation string
"ATQ0V1E1S0=1";
char baudrate[12] = "19200"; // Baud rate
char commport[12] = "COM1"; // Communications port
int modemShowRant = TRUE; // Show rant about Windows serial I/O support
int modemSessions = 0; // Open sessions on modem
#endif
int alwaysBindSocket = FALSE; // Bind output socket (WINSOCK bug work-around)
int useSendNotSendto = FALSE; // Use send() to socket, not sendto()
int waNetNoConnect = FALSE; // Don't connect(), use sendto()
int waNetUseSend = FALSE; // Use send(), not sendto() always
int waNetMultiTTLisChar = FALSE; // Argument to IP_MULTICAST_TTL setsockopt is char
int waNetNoOutOverflow = FALSE; // Disable output overflow detection and recovery
int waNetNoMsgLoopIns = FALSE; // Disable message loop insurance
int waNetSynchronousGetHostname = 2; // Use gethostbyaddr(), not WASAsync variant
int waNetSynchronousGetHostnameAction = FALSE; // Action set by above variable
int waProtNoHeartbeat = FALSE; // No heartbeat in Speak Freely protocol
int waProtUseLargerRTCPackets = FALSE; // Use large packets with RTP protocol
int waProtNoVAT = FALSE; // Disable auto-sensing of VAT protocol
int waProtNoRTP = FALSE; // Disable auto-sensing of RTP protocol
int waProtNoRTCPCrypt = FALSE; // Don't encrypt RTCP packets
int waAudioHalf = FALSE; // Assume audio half-duplex; don't test
int waAudio11025 = FALSE; // Assume audio 11025 samples/sec
int waAudioRingMaxVolume = FALSE; // Force maximum output volume for remote ring
static UINT waAudioInDevice = (UINT) WAVE_MAPPER; // Default audio input device
static UINT waAudioOutDevice = (UINT) WAVE_MAPPER; // Default audio output device
int halfDuplex = FALSE; // Audio hardware is half-duplex
static int audioIs8Bit = FALSE; // Nonzero if audio is 8 bit only
static int audioUse8Bit = FALSE; // Use 8 bit audio
int netMaxSamples; // Maximum samples network can send
static int currentInputLength; // Current expected input buffer length
int currentInputSamples; // Samples desired in current input buffers
int holped = FALSE; // Help was invoked somewhere
static char ringFileName[MAX_PATH] = "";// Ring file name
static int lookWho_sTalking = FALSE; // Restore from icon on new connection
char lwl_s_server[MAX_PATH]; // Look Who's Listening server name
char lwl_s_email[80]; // E-mail address
char lwl_s_fullname[80]; // Full name
char lwl_s_phone[80]; // Telephone number
char lwl_s_location[80]; // Location name
int lwl_s_publish; // Publish in directory ?
int lwl_s_exact; // Exact match only ?
char lwl_a_server[MAX_PATH]; // Look Who's Listening query server
int lwl_a_exact; // Exact matches only
int lwl_t_published = FALSE; // Directory listing published
int lwl_t_resend = 0; // Time to update directory listing ?
static int lwl_t_diactive = FALSE; // LWL dialogue up
int lwl_t_pending = FALSE; // LWL server update pending ?
static int lwl_t_tock = 0; // Mushy timer for LWL socket handling
unsigned long ssrc; // RTP synchronisation source identifier
unsigned long timestamp; // RTP packet timestamp
unsigned short seq; // RTP packet sequence number
unsigned long rtpdesrand; // RTP DES random RTCP prefix
char *sdes = NULL; // LWL SDES packet
int sdesl; // LWL SDES packet length
int spurt = TRUE; // Start of talk spurt flag
char *vatid = NULL; // VAT ID packet
int vatidl; // VAT ID packet length
char *rtpsdes = NULL; // RTP SDES packet
int rtpsdesl; // RTP SDES packet length
HINSTANCE hInst; // The current instance handle
HACCEL hAccel; // Accelerator table handle
HWND hwndMDIFrame; // MDI frame window handle
HWND hwndMDIClient; // MDI client window handle
HWND hDlgPropeller = NULL; // Propeller head modeless dialogue
HWND hDlgChat = NULL; // Chat modeless dialogue
HWND hDlgSpectral = NULL; // Spectral display modeless dialogue
LPSTR commandLine = NULL; // Command line from invocation
HWND hDlgAnswer = NULL; // Answering machine modeless dialogue
LPSTR pszAppName; // Application name
INT tmAveCharWidth; // TEXTMETRIC.tmAveCharWidth
INT tmHeight; // TEXTMETRIC.tmHeight
int rememberedConnections = 0; // Number of remembered connections
LPSTR rememberedConnection[REMEMBER_CONNECTIONS]; // Remembered connections
UINT fileOpenHelpButton; // File open help button message value
char *fileHelpKey = NULL; // Help key for file open/save in progress
int multiMemberships = 0; // Number of multicast group memberships
#ifdef IP_MAX_MEMBERSHIPS
struct in_addr multiAddr[IP_MAX_MEMBERSHIPS]; // Multicast group IP numbers
LPSTR multiName[IP_MAX_MEMBERSHIPS]; // Multicast group names
#endif
int multiLoop = FALSE; // Multicast loop-back mode
int multiBrainDead = FALSE; // Multicast loop-back option not supported
static UINT jitterBuf = 1000; // Milliseconds to anti-jitter output
BOOL jitterPause = FALSE; // Queueing packets for anti-jitter ?
static UINT jitterTimer = 0; // Jitter timer
#define JITTER_TIMER_ID 6 // Timer ID for anti-jitter
// Local variables
#define nWaveHeaders 4
static SOCKET sCommand = INVALID_SOCKET; // Command socket
static SOCKET sControl = INVALID_SOCKET; // RTP/VAT control port socket
static SOCKET lwlsock = INVALID_SOCKET; // Look Who's Listening periodic update socket
struct auxSocket FAR *asList = NULL; // Auxiliary socket list
static LPWAVEHDR inWaveHeader[nWaveHeaders];// Pointers to wave input buffers
static int waveHeadersAllocated = 0; // Number of allocated wave headers
static int createSuccessful = FALSE; // Set once we've loaded .INI parameters
static int inputTerm = FALSE; // Input terminating
static soundbuf receivedSoundBuffer; // Sound buffer from network
#ifdef MODEM
static LPSTR modemSb = NULL; // Modem sound buffer assembly area
#endif
static UINT bombTimer = 0; // Timer for close bomb
static int closeBomb = FALSE; // Trigger close when audio active
#define BOMB_TIMER_ID 7 // Close timebomb ID
u_long Lazarus = 0; // Lazarus host ID
int LazarusLong = 0; // If nonzero, anti-reincarnation timeout
// Audio hardware configuration
static int audioChannels = 1; // Audio input channels
//#define HIGH_QUALITY
#ifdef HIGH_QUALITY
static int samplesPerSecond = 22050; // Sound sampling rate
#else
static int samplesPerSecond = 8000; // Sound sampling rate
#endif
static int bytesPerSecond = 16000; // Sample bytes per second
static int sampleAlignment = 2; // Sample frame size
static int bitsPerSample = 16; // Bits per sample
static char kS0[] = "0", kS1[] = "1"; // Frequently used string constants
// Export current audio settings to About dialogue
int aboutInSamples = 0; // Input samples per second
int aboutInBits; // Input bits per sample
int aboutOutSamples = 0; // Output samples per second
int aboutOutBits; // Output bits per sample
// Export various status information to Propeller Head dialogue
long packetsReceived = 0, // Network packet traffic counters
packetsSent = 0,
inputPacketsLost = 0, // Input packets lost due to half-duplex
outputPacketsLost = 0, // Output packets lost due to net traffic
messageChecks = 0; // Anti-lockup calls on DefaultMessageLoop
int messageQueueSize = 120; // Inbound message queue size
// Network properties
int aboutUDPmax = 0; // Maximum UDP packet size
// Private constants
#define DESIRED_WINSOCK_VERSION 0x0101 // we'd like winsock ver 1.1...
#define MINIMUM_WINSOCK_VERSION 0x0001 // ...but we'll take ver 1.0
#define MODEM_INPUT_EVENT 9999 // Modem input socket status
// MDI message forwarder
static LRESULT Frame_MDIMessageForwarder(HWND hwnd, UINT nMessage,
WPARAM wParam, LPARAM lParam)
{
return DefFrameProc(hwnd, hwndMDIClient, nMessage, wParam, lParam);
}
// PROPELLER -- Update propeller head dialogue if it's displayed.
void propeller(int control, DWORD value)
{
if (hDlgPropeller != NULL) {
char s[80];
wsprintf(s, Format(0), value);
SetDlgItemText(hDlgPropeller, control, s);
}
}
/* FINDCLIENTBYHOST -- Find the connection window for a given
host address. */
static HWND findClientByHost(LPSOCKADDR_IN paddr)
{
HWND hwnd;
hwnd = GetWindow(hwndMDIClient, GW_CHILD);
while (hwnd != NULL) {
if ((WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC) == ((WNDPROC) connectWndProc)) {
LPCLIENT_DATA pClientData = CLIENTPTR(hwnd);
if ((pClientData != NULL) &&
(pClientData->inetSock.sin_addr.s_addr == paddr->sin_addr.s_addr) &&
(pClientData->port == ntohs(paddr->sin_port))) {
return hwnd;
}
}
hwnd = GetWindow(hwnd, GW_HWNDNEXT);
}
return NULL;
}
/* GETACTIVECONNECTION -- Get the active connection window. If no
connection is active, NULL is returned.
A connection will not be returned unless
it has a valid client data structure. */
static HWND getActiveConnection(void)
{
LRESULT mdiActive;
HWND hwnd;
if (hwndMDIClient != NULL) {
mdiActive = SendMessage(hwndMDIClient, WM_MDIGETACTIVE,
0, 0L);
hwnd = (HWND) LOWORD(mdiActive);
if (hwnd != NULL &&
((WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC) == ((WNDPROC) connectWndProc)) &&
CLIENTPTR(hwnd) != NULL) {
return hwnd;
}
}
return NULL;
}
#ifdef IP_MAX_MEMBERSHIPS
/* MULTICASTJOIN -- Join or drop multicast groups given in
the multicast table. */
void multicastJoin(HWND hwnd, int join)
{
int i, what;
struct ip_mreq mreq;
struct auxSocket FAR *s;
static int recursed = 0;
if (recursed > 0) {
return;
}
recursed++;
if (join) {
int sstat;
if (waNetMultiTTLisChar) {
u_char loop;
loop = (u_char) multiLoop;
sstat = setsockopt(sCommand, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &loop,
sizeof loop);
if (sstat != -1) {
sstat = setsockopt(sControl, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &loop,
sizeof loop);
}
} else {
int loop;
loop = (int) multiLoop;
sstat = setsockopt(sCommand, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &loop,
sizeof loop);
if (sstat != -1) {
sstat = setsockopt(sControl, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &loop,
sizeof loop);
}
}
if (sstat == -1) {
int serr = WSAGetLastError();
if (serr == WSAENOPROTOOPT) {
// Windows 95 and NT don't support IP_MULTICAST_LOOP
multiBrainDead = TRUE;
} else {
/* Since many Winsock implementations don't support multicast,
disable the warning to prevent a natter every time we start
up. */
#ifdef MULTICAST_WARNING
MsgBox(hwnd, MB_ICONSTOP | MB_OK,
Format(8),
serr, SockerrToString(serr));
#endif
}
}
// Now set the TTL for any auxiliary sockets
s = asList;
while (s != NULL) {
if (s->asrefc > 0) {
if (waNetMultiTTLisChar) {
u_char loop;
loop = (u_char) multiLoop;
sstat = setsockopt(s->asdata, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &loop,
sizeof loop);
if (sstat != -1) {
sstat = setsockopt(s->asctrl, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &loop,
sizeof loop);
}
} else {
int loop;
loop = (int) multiLoop;
sstat = setsockopt(s->asdata, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &loop,
sizeof loop);
if (sstat != -1) {
sstat = setsockopt(s->asctrl, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &loop,
sizeof loop);
}
}
if (sstat != -1) {
what = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
for (i = 0; i < multiMemberships; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -