+ // First, do some stuff if it's a password control.
+ // (What does this do exactly?)
+
+ if (tw->GetWindowStyleFlag() & wxTE_PASSWORD)
+ {
+ /* _sm_
+ * At least on my system (SunOS 4.1.3 + Motif 1.2), you need to think of
+ * every event as a replace event. cbs->text->ptr gives the replacement
+ * text, cbs->startPos gives the index of the first char affected by the
+ * replace, and cbs->endPos gives the index one more than the last char
+ * affected by the replace (startPos == endPos implies an empty range).
+ * Hence, a deletion is represented by replacing all input text with a
+ * blank string ("", *not* NULL!). A simple insertion that does not
+ * overwrite any text has startPos == endPos.
+ */
+
+ if (tw->m_value.IsNull())
+ {
+ tw->m_value = cbs->text->ptr;
+ }
+ else
+ {
+ char * passwd = (char*) (const char*) tw->m_value; // Set up a more convenient alias.
+
+ int len = passwd ? strlen(passwd) : 0; // Enough room for old text
+ len += strlen(cbs->text->ptr) + 1; // + new text (if any) + NUL
+ len -= cbs->endPos - cbs->startPos; // - text from affected region.
+
+ char * newS = new char [len];
+ char * p = passwd, * dest = newS, * insert = cbs->text->ptr;
+
+ // Copy (old) text from passwd, up to the start posn of the change.
+ int i;
+ for (i = 0; i < cbs->startPos; ++i)
+ *dest++ = *p++;
+
+ // Copy the text to be inserted).
+ while (*insert)
+ *dest++ = *insert++;
+
+ // Finally, copy into newS any remaining text from passwd[endPos] on.
+ for (p = passwd + cbs->endPos; *p; )
+ *dest++ = *p++;
+ *dest = 0;
+
+ tw->m_value = newS;
+
+ delete[] newS;
+ }
+
+ if (cbs->text->length>0)
+ {
+ int i;
+ for (i = 0; i < cbs->text->length; ++i)
+ cbs->text->ptr[i] = '*';
+ cbs->text->ptr[i] = 0;
+ }
+ }
+
+ // If we're already within an OnChar, return: probably
+ // a programmatic insertion.
+ if (tw->m_tempCallbackStruct)
+ return;
+
+ // Check for a backspace
+ if (cbs->startPos == (cbs->currInsert - 1))
+ {
+ tw->m_tempCallbackStruct = (void*) cbs;
+
+ wxKeyEvent event (wxEVT_CHAR);
+ event.SetId(tw->GetId());
+ event.m_keyCode = WXK_DELETE;
+ event.SetEventObject(tw);
+
+ // Only if wxTextCtrl::OnChar is called
+ // will this be set to True (and the character
+ // passed through)
+ cbs->doit = False;
+
+ tw->GetEventHandler()->ProcessEvent(event);
+
+ tw->m_tempCallbackStruct = NULL;
+
+ if (tw->m_inSetValue)
+ return;
+
+ if (tw->m_processedDefault)
+ {
+ // Can generate a command
+ wxCommandEvent commandEvent(wxEVT_COMMAND_TEXT_UPDATED, tw->GetId());
+ commandEvent.SetEventObject(tw);
+ tw->ProcessCommand(commandEvent);
+ }
+
+ return;
+ }
+
+ // Pasting operation: let it through without
+ // calling OnChar
+ if (cbs->text->length > 1)
+ return;
+
+ // Something other than text
+ if (cbs->text->ptr == NULL)
+ return;