📄 log.htm
字号:
</blockquote>
<P>All the workaround modes are saved in the SPEAKFRE.INI file
and apply to subsequent executions. The menu items are
disabled when a connection is active.
<P>As suggested by John Deters, I added the ability to
automatically open an iconised version of Speak Freely whenever
a new inbound connection is established. This lets you see the
site that's just started talking to you. Since some people
might find such an unsolicited pop-up irritating, this only
happens if you check the new Options menu item "Look Who's
Talking".
<P>Tested under Windows 95 final build. Works fine when using
the standard built-in WINSOCK, but doesn't resolve host names
when Sun PC-NFS is overloaded on top of Windows networking.
This appears to be a general problem of this configuration;
other programs fail on gethostbyname() in precisely the same
way. When you configure Windows 95, be sure to install the
TCP/IP driver; if you don't you'll get nowhere fast.
<P><B>12 September 1995</B>
<P>Sending a stereo .WAV file in ADPCM compression mode crashed
the Unix speaker program. The code in READWAVE.C which
calculates the number of bytes of .WAV file needed to fill a
packet was incorrectly assuming the nBlockAlign field was the
size of an individual sample, not the frame of samples for all
channels. Fixed.
<P>Closing a connection while a .WAV file was being sent
orphaned the MMIO handle used to read the file. Fixed in
CONNECT.C.
<P><B>13 September 1995</B>
<P>Added the ability to drop saved connection (.SFX) files in
the MDI frame window and thereby open (or activate, if already
open) connections to the hosts given in the files. You can
drop multiple connection files in a multiple selection and each
will be opened.
<P>CONNECT.C had its own implementation of DragAcceptFiles()
which directly twiddled WS_EX_ACCEPTFILES. It doesn't any
more.
<P>If a connection file is named on the command line when the
program is launched, it is opened once the application is
initialised. This permits making an association between the
.SFX extension and Speak Freely in the File Manager and
launching the program for a given connection by double clicking
the connection file. You can specify multiple connection files
on the command line, space separated. This allows making a
program item icon which opens a collection of connections, a
handy thing to put in your StartUp folder. (Suggested by John
Gilmore).
<P>John also pointed out that the program wasn't usable without
a mouse since the left mouse button was the only way to push to
talk. I added logic in CONNECT.C that permits the space bar to
be used to toggle push to talk, just as in the Unix mike
program. You can cycle between open connections with Ctrl+Tab
and use the space bar to select any set to which you wish to
transmit.
<P>Mouseless users who push to talk with the space bar don't
have the benefit of the cursor change to indicate which
connections are transmitting. I added a "Transmitting" status
indicator in the connection window which appears whenever live
audio is being sent to the window.
<P>If you make a .WAV sound file with the (nonstandard)
sampling rate of 8000 samples per second, it is now played
correctly by READWAVE.C, not forced to the closest standard
sampling rate of 11025 samples per second. Conversion of
stereo .WAV files into mono is still performed for 8000 sample
per second files. If the user has the ability to make 8000
sample/sec .WAVs, this reduces file size, improves sound
quality, and eliminates CPU overhead when sending such files.
.AU files remain the fastest, since they're already mu-law
encoded.
<P><B>14 September 1995</B>
<P>Update release 5.1c.
<P><B>20 September 1995</B>
<P>Began work on answering machine. Defined structure for data
in file, added a new ANSWER.C module with a function to save a
sound buffer in an answer file in that format.
<P><B>25 September 1995</B>
<P>Modified the new connection dialogue handler to allow
numeric IP addresses which can't be resolved into host names.
If the host name lookup fails, the dotted IP number from
inet_ntoa is used as the host name.
<P>Good ole' Trumpet Winsock returns an error status if
gethostname() is called with a buffer too small to hold the
entire name, as opposed to truncating it as Unix does. I
changed the two calls in CONNECT.C to get the host name in a
temporary buffer, then copy as much as will fit into the
sendinghost field of the sound buffer.
<P>Added the ability to set the multicast scope with a new item
in the Options/Connection dialogue. This item is enabled only
if the IP address is a valid multicast group number.
<P>Bad ole' Windows 95 WINSOCK returns a WSAEFAULT error if you
pass a single byte argument for the IP_MULTICAST_TTL
setsockopt() call. This is incompatible with all Unix
documentation I have seen. Trumpet works correctly with the
single byte argument, and accepts the 2 byte short required by
Windows 95. Given the likelihood there's some other WINSOCK
that requires a one byte argument, in goes another
Options/Workaround/Network item: "Multicast TTL Argument Is
char" which does it the Unix way, not as required by Windows
95.
<P><B>26 September 1995</B>
<P>Added a new Connection/Multicast Groups dialogue which
allows adding and dropping membership in multicast groups.
Groups can be specified by DNS-resolvable name or by IP
address. A check box controls multicast loop-back of locally
sent packets to groups in which this host has added
membership. The loopback box is disabled on systems (such as
Windows 95) which do not implement the IP_MULTICAST_LOOP
setsockopt() option.
<P><B>1 October 1995</B>
<P>Discovered the multicast tear-down code in the WM_DESTROY
message handler of FRAME.C wasn't testing for a NULL
multiName[], resulting in bad GlobalFree() calls when we failed
to initialise a multicast port. Fixed.
<P>FRAME.C wasn't killing the main timeout timer at
WM_DESTROY. Fixed.
<P>If the attempt to drop a multicast membership at WM_DESTROY
time failed, a message box was displayed as a child window of
the one frame being destroyed. This is apparently (yet another
of the billions and billgatesillions) undocumented no-no--in
any case, if you do it, you get an "err USER: Attempt to
activate destroyed window" at the time the WM_DESTROY returns.
I changed the parent of the message box in this case to be NULL
and it seems to be happy now. (In FRAME.C).
<P>Finished implementation of the answering machine, ANSWER.C.
I'll probably be back before long to make it more
message-oriented (select message from a list box of sites and
times, individually delete messages, etc.) but at least it now
has basic functionality.
<P><B>2 October 1995</B>
<P>Added keyboard accelerator (CTRL+T) for answering machine,
and a new connection menu item that lets you toggle whether
incoming messages are recorded without having to pop up the
answering machine dialogue. Fixed a bug in which checking or
unchecking the record incoming messages box in the answering
machine dialogue didn't take effect until you closed the
dialogue; now it takes effect immediately.
<P>Added code to overwrite the 16 byte session key exchanged
via PGP before closing the file on disc. Unfortunately, since
we can't transmit and receive the with a pipe, as we do on
Unix, there's still a window while PGP is running during which
the session key is visible, but at least this keeps it from
lying around in unallocated disc space for an indeterminate
time.
<P>If no answering machine message file was configured, the
answering machine dialogue in ANSWER.C called scanMessageFile
anyway. Unfortunately, that routine didn't test for answerFile
being NULL and proceeded to stomp all over memory. Fixed in
ANSWER.C scanMessageFile().
<P>Moved all translatable strings and formats from the .C
modules into the string table of the resource file, using the
rstring(), rfilter() functions and the Format() macro as
intermediaries. Strings that aren't to be translated,such as
fopen() mode strings, formats that contain only a field editing
code, etc. continue to appear as strings in the source code.
Banishing these strings to the resource file reclaimed almost
4K of data space, enough to give us some breathing room should
it prove necessary to introduce another static full-size sound
buffer for some reason.
<P><B>3 October 1995</B>
<P>The enabling and disabling of buttons in the answering
machine was befuddling Windows' dialogue box keyboard
accelerator logic. I added code at the end of a message replay
to restore the input focus to the button last pressed or its
logical successor if that button has become disabled as a
result of the message we just completed.
<P>Keyboard accelerators in the answering machine were less
than optimally chosen due to renaming of buttons during its
development. I rationalised them so the most commonly used
buttons have the most obvious keyboard shortcuts.
<P>Pressing the Close button in the answering machine gave a
debug kernel "err: window destroyed in window callback". Why,
I know not. It uses the standard code for modeless dialogues
right out of Petzold, which identical code works perfectly in
the propeller-head modeless dialogue. Changing the
DestroyWindow() to a PostMessage of WM_CLOSE to ourself made
the message go away. I changed the propeller-head dialogue in
DIALOGS.C to use the same logic.
<P>Several modal dialogues needlessly included the system menu
in their title bar. Eliminated. (The modal dialogues such as
the answering machine and propeller-head continue to display
the system menu.)
<P>Installed help buttons in all the dialogues, linked to the
topic in the help file which describes the dialogue.
<P>Moved the names of our help file and the base Windows help
file into the resource string table.
<P>I removed the "How to use help" menu item, which has fallen
out of fashion.
<P>Changed "Help/Search..." to "Help/Search for Help on..." as
used in current Microsoft applications.
<P><B>4 October 1995</B>
<P>Completed moving all section and item titles for the main
.INI file and saved connection files to the string table in the
resource file. Whether these should be translated isn't clear:
a normal user won't ever examine these files and translating
renders them incompatible between different language editions.
But the saving in data segment size by elminiating duplication
of the section titles alone justifies the work.
<P>Added two new string constants kS0[1] = "0" and kS1 = "1" to
FRAME.C and changed all references to the explicit constants in
profile file I/O to use them. This eliminates redundant string
constants in the data space.
<P>Found a few string constants I'd missed somehow in
READWAVE.C. Banished.
<P>Fixed the answering machine to update the host name when a
definitive name (one not displayed in parentheses) is seen,
replacing any previously displayed name.
<P>Added help butttons to all the file open dialogues, linked
to the appropriate topics in the help file.
<P>Added a pleasant default ring file. I haven't found a
suitable (well-recorded and public domain) telephone bell, so I
decided to pioneer non-irritating notification of an incoming
call with this wind chime derived sound. The original appeared
on the CD-ROM (N
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -