From 7d9a457bbf39696590d678b4b694406f4b5a3524 Mon Sep 17 00:00:00 2001
From: rods <rods>
Date: Mon, 8 Jun 1998 21:31:33 +0000
Subject: [PATCH] added more functionality

---
 widget/src/motif/nsTextHelper.cpp     | 131 ++++++++------
 widget/src/motif/nsTextWidget.cpp     | 241 ++++++++++++++++++++++++++
 widget/src/motif/nsTextWidget.h       | 117 +++++++++++++
 widget/src/motif/nsXtEventHandler.cpp |  40 +++++
 widget/src/motif/nsXtEventHandler.h   |   2 +
 5 files changed, 477 insertions(+), 54 deletions(-)
 create mode 100644 widget/src/motif/nsTextWidget.cpp
 create mode 100644 widget/src/motif/nsTextWidget.h

diff --git a/widget/src/motif/nsTextHelper.cpp b/widget/src/motif/nsTextHelper.cpp
index 9af17cd9bc7d..04b5b69b1b2b 100644
--- a/widget/src/motif/nsTextHelper.cpp
+++ b/widget/src/motif/nsTextHelper.cpp
@@ -23,93 +23,121 @@
 #include "nsString.h"
 #include "nsStringUtil.h"
 
+#include <Xm/Text.h>
 
-void nsTextHelper::PreCreateWidget(nsWidgetInitData *aInitData)
+#define DBG 0
+
+
+//-------------------------------------------------------------------------
+void nsTextHelper::SetMaxTextLength(PRUint32 aChars)
 {
-  if (nsnull != aInitData) {
-    nsTextWidgetInitData* data = (nsTextWidgetInitData *) aInitData;
-    mIsPassword = data->mIsPassword;
+  XmTextSetMaxLength(mWidget, (int)aChars);
+}
+
+//-------------------------------------------------------------------------
+PRUint32  nsTextHelper::GetText(nsString& aTextBuffer, PRUint32 aBufferSize) 
+{
+  char * str = XmTextGetString(mWidget);
+  aTextBuffer.SetLength(0);
+  aTextBuffer.Append(str);
+  PRUint32 len = (PRUint32)strlen(str);
+  XtFree(str);
+  return len;
+}
+
+//-------------------------------------------------------------------------
+PRUint32  nsTextHelper::SetText(const nsString& aText)
+{ 
+  if (!mIsReadOnly) {
+    NS_ALLOC_STR_BUF(buf, aText, 512);
+    XmTextSetString(mWidget, buf);
+    NS_FREE_STR_BUF(buf);
+    return(aText.Length());
+  }
+
+  return 0;
+}
+
+//-------------------------------------------------------------------------
+PRUint32  nsTextHelper::InsertText(const nsString &aText, PRUint32 aStartPos, PRUint32 aEndPos)
+{ 
+  if (!mIsReadOnly) {
+    NS_ALLOC_STR_BUF(buf, aText, 512);
+    XmTextInsert(mWidget, aStartPosbuf);
+    NS_FREE_STR_BUF(buf);
+  }
+  return(0);
+}
+
+//-------------------------------------------------------------------------
+void  nsTextHelper::RemoveText()
+{
+  char blank[2];
+  blank[0] = 0;
+
+  if (!mIsReadOnly) {
+    XmTextSetString(mWidget, buf);
   }
 }
 
-void nsTextHelper::SetMaxTextLength(PRUint32 aChars)
-{
-  //::SendMessage(mWnd, EM_SETLIMITTEXT, (WPARAM) (INT)aChars, 0);
-}
-
-PRUint32  nsTextHelper::GetText(nsString& aTextBuffer, PRUint32 aBufferSize) {
-
-  /*int length = GetWindowTextLength(mWnd);
-  int bufLength = length + 1;
-  NS_ALLOC_CHAR_BUF(buf, 512, bufLength);
-  int charsCopied = GetWindowText(mWnd, buf, bufLength);
-  aTextBuffer.SetLength(0);
-  aTextBuffer.Append(buf);
-  NS_FREE_CHAR_BUF(buf);
-  */
-
-  return(0);
-}
-
-PRUint32  nsTextHelper::SetText(const nsString& aText)
-{ 
-/*
-  NS_ALLOC_STR_BUF(buf, aText, 512);
-  SetWindowText(mWnd, buf);
-  NS_FREE_STR_BUF(buf);
-  return(aText.Length());
-*/
-return 0;
-}
-
-PRUint32  nsTextHelper::InsertText(const nsString &aText, PRUint32 aStartPos, PRUint32 aEndPos)
-{ 
-   // NOT IMPLEMENTED
-  return(0);
-}
-
-void  nsTextHelper::RemoveText()
-{
-  //SetWindowText(mWnd, "");
-}
-
+//-------------------------------------------------------------------------
 void  nsTextHelper::SetPassword(PRBool aIsPassword)
 {
   mIsPassword = aIsPassword;
 }
 
+//-------------------------------------------------------------------------
 PRBool  nsTextHelper::SetReadOnly(PRBool aReadOnlyFlag)
 {
   PRBool oldSetting = mIsReadOnly;
   mIsReadOnly = aReadOnlyFlag;
+  XmTextSetEditable(mWidget, aReadOnlyFlag);
   return(oldSetting);
 }
 
   
+//-------------------------------------------------------------------------
 void nsTextHelper::SelectAll()
 {
-  //::SendMessage(mWnd, EM_SETSEL, (WPARAM) 0, (LPARAM)-1);
+  nsString text;
+  PRUint32 numChars = GetText(text, 0);
+  SetSelection(0, numChars);
 }
 
 
+//-------------------------------------------------------------------------
 void  nsTextHelper::SetSelection(PRUint32 aStartSel, PRUint32 aEndSel)
 {
-  //::SendMessage(mWnd, EM_SETSEL, (WPARAM) (INT)aStartSel, (INT) (LPDWORD)aEndSel); 
+  XmTextPosition left  = (XmTextPosition)aStartSel;
+  XmTextPosition right = (XmTextPosition)aEndSel;
+
+  Time time;
+
+  XmTextSetSelection(mWidget, left, right, time);
 }
 
 
+//-------------------------------------------------------------------------
 void  nsTextHelper::GetSelection(PRUint32 *aStartSel, PRUint32 *aEndSel)
 {
-  //::SendMessage(mWnd, EM_GETSEL, (WPARAM) (LPDWORD)aStartSel, (LPARAM) (LPDWORD)aEndSel); 
+  XmTextPosition left;
+  XmTextPosition right;
+
+  XmTextGetSelectionPosition(mWidget, &left, &right);
+  *aStartSel = left;
+  *aEndSel   = right;
 }
 
+//-------------------------------------------------------------------------
 void  nsTextHelper::SetCaretPosition(PRUint32 aPosition)
 {
+  XmTextSetInsertionPosition(mWidget, (XmTextPosition)aPosition);
 }
 
+//-------------------------------------------------------------------------
 PRUint32  nsTextHelper::GetCaretPosition()
 {
-  return(0);
+  return (PRUin32)XmTextGetInsertionPosition(mWidget);
 }
 
 //-------------------------------------------------------------------------
@@ -134,11 +162,6 @@ nsTextHelper::~nsTextHelper()
 }
 
 //-------------------------------------------------------------------------
-//
-// Clear window before paint
-//
-//-------------------------------------------------------------------------
-
 PRBool nsTextHelper::AutoErase()
 {
   return(PR_TRUE);
diff --git a/widget/src/motif/nsTextWidget.cpp b/widget/src/motif/nsTextWidget.cpp
new file mode 100644
index 000000000000..e727f0ba01ef
--- /dev/null
+++ b/widget/src/motif/nsTextWidget.cpp
@@ -0,0 +1,241 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#include "nsTextWidget.h"
+#include "nsToolkit.h"
+#include "nsColor.h"
+#include "nsGUIEvent.h"
+#include "nsString.h"
+
+#include <Xm/Text.h>
+
+#define DBG 0
+
+//-------------------------------------------------------------------------
+//
+// nsTextWidget constructor
+//
+//-------------------------------------------------------------------------
+nsTextWidget::nsTextWidget(nsISupports *aOuter) : nsTextHelper(aOuter),
+  mIsPasswordCallBacksInstalled(PR_FALSE)
+{
+  //mBackground = NS_RGB(124, 124, 124);
+}
+
+//-------------------------------------------------------------------------
+//
+// nsTextWidget destructor
+//
+//-------------------------------------------------------------------------
+nsTextWidget::~nsTextWidget()
+{
+}
+
+//-------------------------------------------------------------------------
+void nsButton::Create(nsIWidget *aParent,
+                      const nsRect &aRect,
+                      EVENT_CALLBACK aHandleEventFunction,
+                      nsIDeviceContext *aContext,
+                      nsIToolkit *aToolkit,
+                      nsWidgetInitData *aInitData) 
+{
+  Widget parentWidget = nsnull;
+
+  if (DBG) fprintf(stderr, "aParent 0x%x\n", aParent);
+
+  if (aParent) {
+    parentWidget = (Widget) aParent->GetNativeData(NS_NATIVE_WIDGET);
+  } else {
+    parentWidget = (Widget) aInitData ;
+  }
+
+  if (DBG) fprintf(stderr, "Parent 0x%x\n", parentWidget);
+
+  mWidget = ::XtVaCreateManagedWidget("button",
+                                    xmTextWidgetClass, 
+                                    parentWidget,
+                                    XmNwidth, aRect.width,
+                                    XmNheight, aRect.height,
+                                    XmNrecomputeSize, False,
+                                    XmNhighlightOnEnter, False,
+		                                XmNx, aRect.x,
+		                                XmNy, aRect.y, 
+                                    nsnull);
+
+  if (DBG) fprintf(stderr, "Button 0x%x  this 0x%x\n", mWidget, this);
+
+  // save the event callback function
+  mEventCallback = aHandleEventFunction;
+
+  InitCallbacks();
+
+}
+
+//-------------------------------------------------------------------------
+void nsButton::Create(nsNativeWindow aParent,
+                      const nsRect &aRect,
+                      EVENT_CALLBACK aHandleEventFunction,
+                      nsIDeviceContext *aContext,
+                      nsIToolkit *aToolkit,
+                      nsWidgetInitData *aInitData)
+{
+}
+
+
+//-------------------------------------------------------------------------
+//
+// Query interface implementation
+//
+//-------------------------------------------------------------------------
+nsresult nsTextWidget::QueryInterface(REFNSIID aIID, void** aInstancePtr)
+{
+  static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
+
+  if (aIID.Equals(kITextWidgetIID)) {
+    AddRef();
+    *aInstancePtr = (void**) &mAggWidget;
+    return NS_OK;
+  }
+  return nsWindow::QueryInterface(aIID, aInstancePtr);
+}
+
+
+//-------------------------------------------------------------------------
+//
+// move, paint, resizes message - ignore
+//
+//-------------------------------------------------------------------------
+PRBool nsTextWidget::OnMove(PRInt32, PRInt32)
+{
+  return PR_FALSE;
+}
+
+//--------------------------------------------------------------
+PRBool nsTextWidget::OnPaint()
+{
+  return PR_FALSE;
+}
+
+
+//--------------------------------------------------------------
+PRBool nsTextWidget::OnResize(nsRect &aWindowRect)
+{
+  return PR_FALSE;
+}
+
+
+//--------------------------------------------------------------
+#define GET_OUTER() ((nsButton*) ((char*)this - nsButton::GetOuterOffset()))
+
+
+//--------------------------------------------------------------
+void TextWidget::AggTextWidget::SetMaxTextLength(PRUint32 aChars)
+{
+  GET_OUTER()->SetMaxTextLength(aChars);
+}
+
+//--------------------------------------------------------------
+PRUint32  TextWidget::AggTextWidget::GetText(nsString& aTextBuffer, PRUint32 aBufferSize) {
+  return GET_OUTER()->GetText(aTextBuffer, aBufferSize);
+}
+
+//--------------------------------------------------------------
+PRUint32  TextWidget::AggTextWidget::SetText(const nsString& aText)
+{ 
+  return GET_OUTER()->SetText(aText);
+}
+
+//--------------------------------------------------------------
+PRUint32  TextWidget::AggTextWidget::InsertText(const nsString &aText, PRUint32 aStartPos, PRUint32 aEndPos)
+{ 
+  return GET_OUTER()->InsertText(aText, aStartPos, aEndPos);
+}
+
+//--------------------------------------------------------------
+void  TextWidget::AggTextWidget::RemoveText()
+{
+  GET_OUTER()->RemoveText();
+}
+
+//--------------------------------------------------------------
+void  TextWidget::AggTextWidget::SetPassword(PRBool aIsPassword)
+{
+  GET_OUTER()->SetPassword(aIsPassword);
+  if (aIsPassword) {
+    if (!mIsPasswordCallBacksInstalled) {
+      XtAddCallback(mWidget, XmNmodifyVerifyCallback, nsXtWidget_Text_Callback, NULL);
+      XtAddCallback(mWidget, XmNactivateCallback,     nsXtWidget_Text_Callback, NULL);
+      mIsPasswordCallBacksInstalled = PR_TRUE;
+    }
+  } else {
+    if (mIsPasswordCallBacksInstalled) {
+      XtRemoveCallback(mWidget, XmNmodifyVerifyCallback, nsXtWidget_Text_Callback, NULL);
+      XtRemoveCallback(mWidget, XmNactivateCallback,     nsXtWidget_Text_Callback, NULL);
+      mIsPasswordCallBacksInstalled = PR_FALSE;
+    }
+  }
+}
+
+//--------------------------------------------------------------
+PRBool  TextWidget::AggTextWidget::SetReadOnly(PRBool aReadOnlyFlag)
+{
+  GET_OUTER()->SetReadOnly(aReadOnlyFlag);
+}
+
+//--------------------------------------------------------------
+void TextWidget::AggTextWidget::SelectAll()
+{
+  GET_OUTER()->SelectAll();
+}
+
+
+//--------------------------------------------------------------
+void  TextWidget::AggTextWidget::SetSelection(PRUint32 aStartSel, PRUint32 aEndSel)
+{
+  GET_OUTER()->SetSelection(aStartSel, aEndSel);
+}
+
+
+//--------------------------------------------------------------
+void  TextWidget::AggTextWidget::GetSelection(PRUint32 *aStartSel, PRUint32 *aEndSel)
+{
+  GET_OUTER()->GetSelection(aStartSel, aEndSel);
+}
+
+//--------------------------------------------------------------
+void  TextWidget::AggTextWidget::SetCaretPosition(PRUint32 aPosition)
+{
+  GET_OUTER()->SetCaretPosition(aPosition);
+}
+
+//--------------------------------------------------------------
+PRUint32  TextWidget::AggTextWidget::GetCaretPosition()
+{
+  return GET_OUTER()->GetCaretPosition();
+}
+
+PRBool TextWidget::AggTextWidget::AutoErase()
+{
+  return GET_OUTER()->AutoErase();
+}
+
+
+//----------------------------------------------------------------------
+
+BASE_IWIDGET_IMPL(nsTextWidget, AggTextWidget);
+
diff --git a/widget/src/motif/nsTextWidget.h b/widget/src/motif/nsTextWidget.h
new file mode 100644
index 000000000000..eee8a58ae0a0
--- /dev/null
+++ b/widget/src/motif/nsTextWidget.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#ifndef nsTextWidget_h__
+#define nsTextWidget_h__
+
+#include "nsWindow.h"
+#include "nsTextHelper.h"
+
+#include "nsITextWidget.h"
+
+/**
+ * Native Motif single line edit control wrapper. 
+ */
+
+class nsTextWidget : public nsTextHelper
+{
+
+public:
+  nsTextWidget(nsISupports *aOuter);
+  virtual ~nsTextWidget();
+
+  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
+
+  void Create(nsIWidget *aParent,
+              const nsRect &aRect,
+              EVENT_CALLBACK aHandleEventFunction,
+              nsIDeviceContext *aContext = nsnull,
+              nsIToolkit *aToolkit = nsnull,
+              nsWidgetInitData *aInitData = nsnull);
+
+  void Create(nsNativeWindow aParent,
+              const nsRect &aRect,
+              EVENT_CALLBACK aHandleEventFunction,
+              nsIDeviceContext *aContext = nsnull,
+              nsIToolkit *aToolkit = nsnull,
+              nsWidgetInitData *aInitData = nsnull);
+
+
+  virtual PRBool  OnPaint();
+  virtual PRBool  OnMove(PRInt32 aX, PRInt32 aY);
+  virtual PRBool  OnResize(nsRect &aWindowRect);
+
+  // nsTextHelper Interface
+  virtual void      SelectAll();
+  virtual void      SetMaxTextLength(PRUint32 aChars);
+  virtual PRUint32  GetText(nsString& aTextBuffer, PRUint32 aBufferSize);
+  virtual PRUint32  SetText(const nsString& aText);
+  virtual PRUint32  InsertText(const nsString &aText, PRUint32 aStartPos, PRUint32 aEndPos);
+  virtual void      RemoveText();
+  virtual void      SetPassword(PRBool aIsPassword);
+  virtual PRBool    SetReadOnly(PRBool aReadOnlyFlag);
+  virtual void      SetSelection(PRUint32 aStartSel, PRUint32 aEndSel);
+  virtual void      GetSelection(PRUint32 *aStartSel, PRUint32 *aEndSel);
+  virtual void      SetCaretPosition(PRUint32 aPosition);
+  virtual PRUint32  GetCaretPosition();
+  virtual void      PreCreateWidget(nsWidgetInitData *aInitData);
+  virtual PRBool    AutoErase();
+
+protected:
+    PRBool  mIsPasswordCallBacksInstalled;
+
+private:
+
+  // this should not be public
+  static PRInt32 GetOuterOffset() {
+    return offsetof(nsTextWidget,mAggWidget);
+  }
+
+
+  // Aggregator class and instance variable used to aggregate in the
+  // nsIText interface to nsText w/o using multiple
+  // inheritance.
+  class AggTextWidget : public nsITextWidget {
+  public:
+    AggTextWidget();
+    virtual ~AggTextWidget();
+
+    AGGRRGATE_METHOD_DEF
+
+    virtual void      SelectAll();
+    virtual void      SetMaxTextLength(PRUint32 aChars);
+    virtual PRUint32  GetText(nsString& aTextBuffer, PRUint32 aBufferSize);
+    virtual PRUint32  SetText(const nsString& aText);
+    virtual PRUint32  InsertText(const nsString &aText, PRUint32 aStartPos, PRUint32 aEndPos);
+    virtual void      RemoveText();
+    virtual void      SetPassword(PRBool aIsPassword);
+    virtual PRBool    SetReadOnly(PRBool aReadOnlyFlag);
+    virtual void      SetSelection(PRUint32 aStartSel, PRUint32 aEndSel);
+    virtual void      GetSelection(PRUint32 *aStartSel, PRUint32 *aEndSel);
+    virtual void      SetCaretPosition(PRUint32 aPosition);
+    virtual PRUint32  GetCaretPosition();
+    virtual void      PreCreateWidget(nsWidgetInitData *aInitData);
+    virtual PRBool    AutoErase();
+
+  };
+  AggTextWidget mAggWidget;
+
+
+};
+
+#endif // nsTextWidget_h__
diff --git a/widget/src/motif/nsXtEventHandler.cpp b/widget/src/motif/nsXtEventHandler.cpp
index 11775f350078..05a8de13d4be 100644
--- a/widget/src/motif/nsXtEventHandler.cpp
+++ b/widget/src/motif/nsXtEventHandler.cpp
@@ -231,3 +231,43 @@ void nsXtWidget_Scrollbar_Callback(Widget w, XtPointer p, XtPointer call_data)
 
 
 
+//==============================================================
+void nsXtWidget_Text_Callback(Widget w, XtPointer p, XtPointer call_data)
+{
+  nsWindow * widgetWindow = (nsWindow *) p ;
+
+  char * newStr;
+  int len;
+
+  XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *) call_data;
+
+  if (cbs->reason == XmCR_ACTIVATE) {
+      printf ("Password: %s0, passwd);
+      return;
+  }
+
+  if (cbs->startPos < cbs->currInsert) {   /* backspace */
+      cbs->endPos = strlen (passwd);       /* delete from here to end */
+      passwd[cbs->startPos] = 0;           /* backspace--terminate */
+      return;
+  }
+
+  if (cbs->text->length > 1) {
+      cbs->doit = False;  /* don't allow "paste" operations */
+      return;             /* make the user *type* the password! */
+  }
+
+  newStr = XtMalloc (cbs->endPos + 2); /* new char + NULL terminator */
+  if (passwd) {
+      strcpy (newStr, passwd);
+      XtFree (passwd);
+  } else
+      newStr[0] = NULL;
+  passwd = newStr;
+  strncat (passwd, cbs->text->ptr, cbs->text->length);
+  passwd[cbs->endPos + cbs->text->length] = 0;
+
+  for (len = 0; len < cbs->text->length; len++)
+      cbs->text->ptr[len] = '*';
+}
+
diff --git a/widget/src/motif/nsXtEventHandler.h b/widget/src/motif/nsXtEventHandler.h
index 21ee494879b1..1f06d8b89efe 100644
--- a/widget/src/motif/nsXtEventHandler.h
+++ b/widget/src/motif/nsXtEventHandler.h
@@ -37,6 +37,8 @@ void nsXtWidget_Toggle_Callback(Widget w, XtPointer p, XtPointer call_data);
 void nsXtWidget_Toggle_ArmCallback(Widget w, XtPointer p, XtPointer call_data);
 void nsXtWidget_Toggle_DisArmCallback(Widget w, XtPointer p, XtPointer call_data);
 
+void nsXtWidget_Text_Callback(Widget w, XtPointer p, XtPointer call_data);
+
 #endif  // __nsXtEventHandler.h