r=mkaply, a=brendan
Bring nsToolkit up to par with the Windows code
This commit is contained in:
mkaply%us.ibm.com 2000-08-07 20:51:47 +00:00
Родитель 5fa2999ab4
Коммит 428b8d9862
6 изменённых файлов: 414 добавлений и 335 удалений

Просмотреть файл

@ -0,0 +1,62 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef SWITCHTOUITHREAD_H
#define SWITCHTOUITHREAD_H
// foreward declaration
struct MethodInfo;
/**
* Switch thread to match the thread the widget was created in so messages will be dispatched.
*/
class nsSwitchToUIThread {
public:
virtual BOOL CallMethod(MethodInfo *info) = 0;
};
//
// Structure used for passing the information necessary for synchronously
// invoking a method on the GUI thread...
//
struct MethodInfo {
nsSwitchToUIThread* target;
UINT methodId;
int nArgs;
ULONG* args;
MethodInfo(nsSwitchToUIThread *obj, UINT id, int numArgs=0, ULONG *arguments = 0) {
target = obj;
methodId = id;
nArgs = numArgs;
args = arguments;
}
BOOL Invoke() { return target->CallMethod(this); }
};
#endif // TOUITHRD_H

Просмотреть файл

@ -1,257 +1,220 @@
/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* The Original Code is the Mozilla OS/2 libraries.
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Initial Developer of the Original Code is John Fairhurst,
* <john_fairhurst@iname.com>. Portions created by John Fairhurst are
* Copyright (C) 1999 John Fairhurst. All Rights Reserved.
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* John Fairhurst <john_fairhurst@iname.com>
* Pierre Phaneuf <pp@ludusdesign.com>
* IBM Corp.
*/
#include "nsToolkit.h"
#include "nsSwitchToUIThread.h"
#include "nsIAppShell.h"
#include "nsGUIEvent.h"
#include "nsWidgetsCID.h"
#include "nsIComponentManager.h"
static PRUintn gToolkitTLSIndex = 0;
// Bits to deal with the case where a new toolkit is initted with a null ----
// thread. In this case it has to create a new thread to be the PM thread.
// Hopefully this will never happen!
// struct passed to new thread
struct ThreadInitInfo
{
PRMonitor *pMonitor;
nsToolkit *toolkit;
ThreadInitInfo( nsToolkit *tk, PRMonitor *pMon)
: pMonitor( pMon), toolkit( tk)
{}
};
// main for the message pump thread
extern "C" void RunPump( void *arg)
{
ThreadInitInfo *info = (ThreadInitInfo *) arg;
nsIAppShell *pShell = nsnull;
nsresult res;
static NS_DEFINE_IID(kAppShellCID, NS_APPSHELL_CID);
res = nsComponentManager::CreateInstance( kAppShellCID, nsnull,
NS_GET_IID(nsIAppShell),
(void **) &pShell);
NS_ASSERTION( res == NS_OK, "Couldn't create new shell");
pShell->Create( 0, 0);
// do registration and creation in this thread
info->toolkit->CreateInternalWindow( PR_GetCurrentThread());
// let the main thread continue
PR_EnterMonitor( info->pMonitor);
PR_Notify( info->pMonitor);
PR_ExitMonitor( info->pMonitor);
pShell->Run();
NS_RELEASE( pShell);
}
// toolkit method to create a new thread and process the msgq there
void nsToolkit::CreatePMThread()
{
PR_EnterMonitor( mMonitor);
ThreadInitInfo ti( this, mMonitor);
// create a pm thread
mPMThread = ::PR_CreateThread( PR_SYSTEM_THREAD,
RunPump,
&ti,
PR_PRIORITY_NORMAL,
PR_LOCAL_THREAD,
PR_UNJOINABLE_THREAD,
0);
// wait for it to start
PR_Wait( mMonitor, PR_INTERVAL_NO_TIMEOUT);
PR_ExitMonitor( mMonitor);
}
// 'Normal use' toolkit methods ---------------------------------------------
nsToolkit::nsToolkit() : mDispatchWnd( 0), mPMThread( 0)
{
NS_INIT_REFCNT();
mMonitor = PR_NewMonitor();
}
nsToolkit::~nsToolkit()
{
// Destroy the Dispatch Window
WinDestroyWindow( mDispatchWnd);
// Destroy monitor
PR_DestroyMonitor( mMonitor);
}
// nsISupports implementation macro
NS_IMPL_ISUPPORTS(nsToolkit, NS_GET_IID(nsIToolkit))
static MRESULT EXPENTRY fnwpDispatch( HWND, ULONG, MPARAM, MPARAM);
#define UWC_DISPATCH "DispatchWndClass"
//
// Static thread local storage index of the Toolkit
// object associated with a given thread...
//
static PRUintn gToolkitTLSIndex = 0;
// Create the internal window - also sets the pm thread 'formally'
void nsToolkit::CreateInternalWindow( PRThread *aThread)
{
NS_PRECONDITION(aThread, "null thread");
mPMThread = aThread;
//
// main for the message pump thread
//
PRBool gThreadState = PR_FALSE;
BOOL rc = WinRegisterClass( 0/*hab*/, UWC_DISPATCH, fnwpDispatch, 0, 0);
NS_ASSERTION( rc, "Couldn't register class");
// create the internal window - just use a static
mDispatchWnd = WinCreateWindow( HWND_DESKTOP,
UWC_DISPATCH,
0, 0,
0, 0, 0, 0,
HWND_DESKTOP,
HWND_BOTTOM,
0, 0, 0);
NS_ASSERTION( mDispatchWnd, "Couldn't create toolkit internal window");
#if DEBUG_sobotka
printf("\n+++++++++++nsToolkit created dispatch window 0x%lx\n", mDispatchWnd);
#endif
}
// Set up the toolkit - create window, check for thread.
nsresult nsToolkit::Init( PRThread *aThread)
{
// Store the thread ID of the thread with the message queue.
// If no thread is provided create one (!!)
if( aThread)
CreateInternalWindow( aThread);
else
// create a thread where the message pump will run
CreatePMThread();
return NS_OK;
}
// Bits to reflect events into the pm thread --------------------------------
// additional structure to provide synchronization & returncode
// Unlike Windows, we cannot use WinSendMsg()
struct RealMethodInfo
{
MethodInfo *pInfo;
PRMonitor *pMonitor;
nsresult rc;
RealMethodInfo( MethodInfo *info, PRMonitor *pMon)
: pInfo( info), pMonitor( pMon), rc( NS_ERROR_FAILURE)
{}
struct ThreadInitInfo {
PRMonitor *monitor;
nsToolkit *toolkit;
};
nsresult nsToolkit::CallMethod( MethodInfo *pInfo)
void PR_CALLBACK RunPump(void* arg)
{
PR_EnterMonitor( mMonitor);
ThreadInitInfo *info = (ThreadInitInfo*)arg;
::PR_EnterMonitor(info->monitor);
RealMethodInfo rminfo( pInfo, mMonitor);
// do registration and creation in this thread
info->toolkit->CreateInternalWindow(PR_GetCurrentThread());
// post the message to the window
WinPostMsg( mDispatchWnd, WMU_CALLMETHOD, MPFROMP(&rminfo), 0);
gThreadState = PR_TRUE;
// wait for it to complete...
PR_Wait( mMonitor, PR_INTERVAL_NO_TIMEOUT);
PR_ExitMonitor( mMonitor);
::PR_Notify(info->monitor);
::PR_ExitMonitor(info->monitor);
// cleanup & return
return rminfo.rc;
delete info;
// Process messages
QMSG qmsg;
while (WinGetMsg((HAB)0, &qmsg, 0, 0, 0)) {
WinDispatchMsg((HAB)0, &qmsg);
}
}
struct SendMsgStruct
//-------------------------------------------------------------------------
//
// constructor
//
//-------------------------------------------------------------------------
nsToolkit::nsToolkit()
{
HWND hwnd;
ULONG msg;
MPARAM mp1, mp2;
MRESULT rc;
PRMonitor *pMonitor;
SendMsgStruct( HWND h, ULONG m, MPARAM p1, MPARAM p2, PRMonitor *pMon)
: hwnd( h), msg( m), mp1( p1), mp2( p2), rc( 0), pMonitor( pMon)
{}
};
MRESULT nsToolkit::SendMsg( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
MRESULT rc = 0;
if( hwnd && IsPMThread())
rc = WinSendMsg( hwnd, msg, mp1, mp2);
else if( hwnd)
{
PR_EnterMonitor( mMonitor);
SendMsgStruct data( hwnd, msg, mp1, mp2, mMonitor);
// post a message to the window
WinPostMsg( mDispatchWnd, WMU_SENDMSG, MPFROMP(&data), 0);
// wait for it to complete...
PR_Wait( mMonitor, PR_INTERVAL_NO_TIMEOUT);
PR_ExitMonitor( mMonitor);
rc = data.rc;
}
return rc;
NS_INIT_REFCNT();
mGuiThread = NULL;
mDispatchWnd = 0;
mMonitor = PR_NewMonitor();
}
MRESULT EXPENTRY fnwpDispatch( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
//-------------------------------------------------------------------------
//
// destructor
//
//-------------------------------------------------------------------------
nsToolkit::~nsToolkit()
{
MRESULT mRC = 0;
NS_PRECONDITION(::WinIsWindow((HAB)0, mDispatchWnd), "Invalid window handle");
if( msg == WMU_CALLMETHOD)
{
RealMethodInfo *pInfo = (RealMethodInfo*) mp1;
// call the method (indirection-fest :-)
pInfo->rc = pInfo->pInfo->target->CallMethod( pInfo->pInfo);
// signal the monitor to let the caller continue
PR_EnterMonitor( pInfo->pMonitor);
PR_Notify( pInfo->pMonitor);
PR_ExitMonitor( pInfo->pMonitor);
}
else if( msg == WMU_SENDMSG)
{
SendMsgStruct *pData = (SendMsgStruct*) mp1;
// send the message
pData->rc = WinSendMsg( pData->hwnd, pData->msg, pData->mp1, pData->mp2);
// signal the monitor to let the caller continue
PR_EnterMonitor( pData->pMonitor);
PR_Notify( pData->pMonitor);
PR_ExitMonitor( pData->pMonitor);
}
else
mRC = WinDefWindowProc( hwnd, msg, mp1, mp2);
// Destroy the Dispatch Window
::WinDestroyWindow(mDispatchWnd);
mDispatchWnd = NULL;
return mRC;
// Remove the TLS reference to the toolkit...
PR_SetThreadPrivate(gToolkitTLSIndex, nsnull);
PR_DestroyMonitor( mMonitor);
}
//-------------------------------------------------------------------------
//
// Register the window class for the internal window and create the window
//
//-------------------------------------------------------------------------
void nsToolkit::CreateInternalWindow(PRThread *aThread)
{
NS_PRECONDITION(aThread, "null thread");
mGuiThread = aThread;
//
// create the internal window
//
WinRegisterClass((HAB)0, "nsToolkitClass", nsToolkitWindowProc, NULL, 0);
mDispatchWnd = ::WinCreateWindow(HWND_DESKTOP,
"nsToolkitClass",
"NetscapeDispatchWnd",
WS_DISABLED,
-50, -50,
10, 10,
HWND_DESKTOP,
HWND_BOTTOM,
0, 0, 0);
VERIFY(mDispatchWnd);
}
//-------------------------------------------------------------------------
//
// Create a new thread and run the message pump in there
//
//-------------------------------------------------------------------------
void nsToolkit::CreateUIThread()
{
PRMonitor *monitor = ::PR_NewMonitor();
::PR_EnterMonitor(monitor);
ThreadInitInfo *ti = new ThreadInitInfo();
ti->monitor = monitor;
ti->toolkit = this;
// create a gui thread
mGuiThread = ::PR_CreateThread(PR_SYSTEM_THREAD,
RunPump,
(void*)ti,
PR_PRIORITY_NORMAL,
PR_LOCAL_THREAD,
PR_UNJOINABLE_THREAD,
0);
// wait for the gui thread to start
while(gThreadState == PR_FALSE) {
::PR_Wait(monitor, PR_INTERVAL_NO_TIMEOUT);
}
// at this point the thread is running
::PR_ExitMonitor(monitor);
::PR_DestroyMonitor(monitor);
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
NS_METHOD nsToolkit::Init(PRThread *aThread)
{
// Store the thread ID of the thread containing the message pump.
// If no thread is provided create one
if (NULL != aThread) {
CreateInternalWindow(aThread);
} else {
// create a thread where the message pump will run
CreateUIThread();
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// nsToolkit WindowProc. Used to call methods on the "main GUI thread"...
//
//-------------------------------------------------------------------------
MRESULT EXPENTRY nsToolkitWindowProc(HWND hWnd, ULONG msg, MPARAM mp1,
MPARAM mp2)
{
switch (msg) {
case WM_CALLMETHOD:
{
MethodInfo *info = (MethodInfo *)mp2;
PRMonitor *monitor = (PRMonitor *)mp1;
info->Invoke();
PR_EnterMonitor(monitor);
PR_Notify(monitor);
PR_ExitMonitor(monitor);
}
case WM_SENDMSG:
{
SendMsgStruct *pData = (SendMsgStruct*) mp1;
// send the message
pData->rc = WinSendMsg( pData->hwnd, pData->msg, pData->mp1, pData->mp2);
// signal the monitor to let the caller continue
PR_EnterMonitor( pData->pMonitor);
PR_Notify( pData->pMonitor);
PR_ExitMonitor( pData->pMonitor);
}
default:
return ::WinDefWindowProc(hWnd, msg, mp1, mp2);
}
}
//-------------------------------------------------------------------------
//
// Return the nsIToolkit for the current thread. If a toolkit does not
@ -300,3 +263,38 @@ NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult)
return rv;
}
void nsToolkit::CallMethod(MethodInfo *info)
{
PR_EnterMonitor(mMonitor);
::WinPostMsg(mDispatchWnd, WM_CALLMETHOD, MPFROMP(mMonitor), MPFROMP(info));
PR_Wait(mMonitor, PR_INTERVAL_NO_TIMEOUT);
PR_ExitMonitor( mMonitor);
}
MRESULT nsToolkit::SendMsg( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
MRESULT rc = 0;
if( hwnd && IsGuiThread())
rc = WinSendMsg( hwnd, msg, mp1, mp2);
else if( hwnd)
{
PR_EnterMonitor( mMonitor);
SendMsgStruct data( hwnd, msg, mp1, mp2, mMonitor);
// post a message to the window
WinPostMsg( mDispatchWnd, WM_SENDMSG, MPFROMP(&data), 0);
// wait for it to complete...
PR_Wait( mMonitor, PR_INTERVAL_NO_TIMEOUT);
PR_ExitMonitor( mMonitor);
rc = data.rc;
}
return rc;
}

Просмотреть файл

@ -1,117 +1,91 @@
/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* The Original Code is the Mozilla OS/2 libraries.
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Initial Developer of the Original Code is John Fairhurst,
* <john_fairhurst@iname.com>. Portions created by John Fairhurst are
* Copyright (C) 1999 John Fairhurst. All Rights Reserved.
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* John Fairhurst <john_fairhurst@iname.com>
* IBM Corp.
*/
#ifndef _toolkit_h
#define _toolkit_h
#ifndef TOOLKIT_H
#define TOOLKIT_H
#include "nsdefs.h"
#include "nsIToolkit.h"
#include "nsWidgetDefs.h"
#include "prmon.h"
// This is a wrapper around the 'pm thread' which runs the message queue.
// Need to do this to 1) ensure windows are always created/destroyed etc.
// in the same thread, 2) because there's no guarantee that a calling
// thread will have a message queue.
//
// In normal operation, a top level window will be created with a null
// toolkit. This creates a new toolkit & init's with the current thread.
// There is an assumption that there is an nsAppShell for that thread,
// which becomes the 'PM thread'. A null thread can be passed in, in
// which case a new thread is created & set to be the PM thread - this
// shouldn't really happen because there's no condition for thread#1 to
// exit!
//
// To allow non-pm threads to call pm functions, a slightly contorted
// mechanism is used.
//
// The object which wishes to do tasks in the pm thread (eg. nsWindow) must
// derive from the nsSwitchToPMThread class.
// At task-time, create an instance of MethodInfo and call the 'CallMethod'
// method in the widget's toolkit. This will call back into the object's
// 'CallMethod' in the pm thread, and not return until it does.
//
// The good news is that you probably don't need to worry about this!
//
// What you may need to 'worry about' is the 'SendMsg' method. When you
// want to call WinSendMsg & you're not certain you're in the PM thread,
// use this one, and the right thing will happen.
struct MethodInfo;
/**
* Wrapper around the thread running the message pump.
* The toolkit abstraction is necessary because the message pump must
* execute within the same thread that created the widget under Win32.
*/
class nsToolkit : public nsIToolkit
{
public:
nsToolkit();
virtual ~nsToolkit();
NS_DECL_ISUPPORTS
public:
NS_IMETHOD Init( PRThread *aThread);
NS_DECL_ISUPPORTS
nsresult CallMethod( MethodInfo *info);
MRESULT SendMsg( HWND hwnd, ULONG msg, MPARAM mp1 = 0, MPARAM mp2 = 0);
nsToolkit();
NS_IMETHOD Init(PRThread *aThread);
void CallMethod(MethodInfo *info);
MRESULT SendMsg(HWND hwnd, ULONG msg, MPARAM mp1 = 0, MPARAM mp2 = 0);
// Return whether the current thread is the application's Gui thread.
PRBool IsGuiThread(void) { return (PRBool)(mGuiThread == PR_GetCurrentThread());}
PRThread* GetGuiThread(void) { return mGuiThread; }
HWND GetDispatchWindow(void) { return mDispatchWnd; }
void CreateInternalWindow(PRThread *aThread);
// Return whether the current thread is the application's PM thread.
PRBool IsPMThread() { return (PRBool)(mPMThread == PR_GetCurrentThread());}
PRThread *GetPMThread() { return mPMThread; }
HWND GetDispatchWindow() { return mDispatchWnd; }
private:
~nsToolkit();
void CreateUIThread(void);
void CreateInternalWindow( PRThread *aThread);
public:
private:
void CreatePMThread();
protected:
// Handle of the window used to receive dispatch messages.
HWND mDispatchWnd;
// Thread Id of the PM thread.
PRThread *mPMThread;
// Monitor used to coordinate dispatch
PRMonitor *mMonitor;
protected:
// Handle of the window used to receive dispatch messages.
HWND mDispatchWnd;
// Thread Id of the "main" Gui thread.
PRThread *mGuiThread;
// Monitor used to coordinate dispatch
PRMonitor *mMonitor;
};
// Interface to derive things from
class nsSwitchToPMThread
// Window procedure for the internal window
static MRESULT EXPENTRY nsToolkitWindowProc(HWND, ULONG, MPARAM, MPARAM);
#define WM_CALLMETHOD (WM_USER+1)
#define WM_SENDMSG (WM_USER+2)
struct SendMsgStruct
{
public:
// No return code: if this is a problem then
virtual nsresult CallMethod( MethodInfo *info) = 0;
HWND hwnd;
ULONG msg;
MPARAM mp1, mp2;
MRESULT rc;
PRMonitor *pMonitor;
SendMsgStruct( HWND h, ULONG m, MPARAM p1, MPARAM p2, PRMonitor *pMon)
: hwnd( h), msg( m), mp1( p1), mp2( p2), rc( 0), pMonitor( pMon)
{}
};
// Structure used for passing the information
struct MethodInfo
{
nsSwitchToPMThread *target;
UINT methodId;
int nArgs;
ULONG *args;
MethodInfo( nsSwitchToPMThread *obj, UINT id,
int numArgs = 0, ULONG *arguments = 0)
{
target = obj;
methodId = id;
nArgs = numArgs;
args = arguments;
}
};
#endif
#endif // TOOLKIT_H

Просмотреть файл

@ -223,7 +223,7 @@ void nsWindow::DoCreate( HWND hwndP, nsWindow *aParent, const nsRect &aRect,
}
// Switch to the PM thread if necessary...
if( !mOS2Toolkit->IsPMThread())
if( !mOS2Toolkit->IsGuiThread())
{
ULONG args[7] = { hwndP, (ULONG) aParent, (ULONG) &aRect,
(ULONG) aHandleEventFunction,
@ -394,7 +394,7 @@ nsWindow::~nsWindow()
nsresult nsWindow::Destroy()
{
// Switch to the PM thread if necessary...
if( mToolkit && !mOS2Toolkit->IsPMThread())
if( mToolkit && !mOS2Toolkit->IsGuiThread())
{
MethodInfo info( this, nsWindow::W_DESTROY);
mOS2Toolkit->CallMethod( &info);
@ -1657,7 +1657,7 @@ nsresult nsWindow::Enable( PRBool bState)
nsresult nsWindow::SetFocus()
{
// Switch to the PM thread if necessary...
if( !mOS2Toolkit->IsPMThread())
if( !mOS2Toolkit->IsGuiThread())
{
MethodInfo info(this, nsWindow::W_SET_FOCUS);
mOS2Toolkit->CallMethod(&info);
@ -2106,7 +2106,7 @@ nsresult nsWindow::InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchron
nsresult nsWindow::Update()
{
// Switch to the PM thread if necessary...
if( !mOS2Toolkit->IsPMThread())
if( !mOS2Toolkit->IsGuiThread())
{
MethodInfo info(this, nsWindow::W_UPDATE_WINDOW);
mOS2Toolkit->CallMethod(&info);
@ -2119,7 +2119,7 @@ nsresult nsWindow::Update()
nsresult nsWindow::SetTitle( const nsString &aTitle)
{
// Switch to the PM thread if necessary...
if( mOS2Toolkit && !mOS2Toolkit->IsPMThread())
if( mOS2Toolkit && !mOS2Toolkit->IsGuiThread())
{
ULONG ulong = (ULONG) &aTitle;
MethodInfo info( this, nsWindow::W_SET_TITLE, 1, &ulong);
@ -2136,7 +2136,7 @@ nsresult nsWindow::SetTitle( const nsString &aTitle)
nsresult nsWindow::GetWindowText( nsString &aStr, PRUint32 *rc)
{
// Switch to the PM thread if necessary...
if( !mOS2Toolkit->IsPMThread())
if( !mOS2Toolkit->IsGuiThread())
{
ULONG args[] = { (ULONG) &aStr, (ULONG) rc };
MethodInfo info( this, nsWindow::W_GET_TITLE, 2, args);
@ -2359,9 +2359,9 @@ void nsWindow::FreeNativeData( void *aDatum, PRUint32 aDataType)
}
// Thread switch callback
nsresult nsWindow::CallMethod(MethodInfo *info)
BOOL nsWindow::CallMethod(MethodInfo *info)
{
nsresult rc = NS_ERROR_FAILURE;
BOOL bRet = TRUE;
switch( info->methodId)
{
@ -2376,7 +2376,7 @@ nsresult nsWindow::CallMethod(MethodInfo *info)
(nsIAppShell*) (info->args[5]),
nsnull, /* toolkit */
(nsWidgetInitData*) (info->args[6]));
rc = NS_OK;
bRet = TRUE;
break;
#if 0
case nsWindow::W_CREATE:
@ -2387,7 +2387,7 @@ nsresult nsWindow::CallMethod(MethodInfo *info)
(nsIAppShell *)(info->args[4]),
(nsIToolkit*)(info->args[5]),
(nsWidgetInitData*)(info->args[6]));
rc = NS_OK;
bRet = TRUE;
break;
case nsWindow::W_CREATE_NATIVE:
@ -2398,44 +2398,46 @@ nsresult nsWindow::CallMethod(MethodInfo *info)
(nsIAppShell *)(info->args[4]),
(nsIToolkit*)(info->args[5]),
(nsWidgetInitData*)(info->args[6]));
rc = NS_OK;
bRet = TRUE;
break;
#endif
case nsWindow::W_DESTROY:
NS_ASSERTION(info->nArgs == 0, "Bad args to Destroy");
Destroy();
rc = NS_OK;
bRet = TRUE;
break;
case nsWindow::W_SET_FOCUS:
NS_ASSERTION(info->nArgs == 0, "Bad args to SetFocus");
SetFocus();
rc = NS_OK;
bRet = TRUE;
break;
case nsWindow::W_UPDATE_WINDOW:
NS_ASSERTION(info->nArgs == 0, "Bad args to UpdateWindow");
Update();
rc = NS_OK;
bRet = TRUE;
break;
case nsWindow::W_SET_TITLE:
NS_ASSERTION(info->nArgs == 1, "Bad args to SetTitle");
SetTitle( (const nsString &) info->args[0]);
rc = NS_OK;
bRet = TRUE;
break;
case nsWindow::W_GET_TITLE:
NS_ASSERTION(info->nArgs == 2, "Bad args to GetTitle");
rc = GetWindowText( *((nsString*) info->args[0]),
(PRUint32*)info->args[1]);
GetWindowText( *((nsString*) info->args[0]),
(PRUint32*)info->args[1]);
bRet = TRUE;
break;
default:
bRet = FALSE;
break;
}
return rc;
return bRet;
}
// function to translate from a WM_CHAR to an NS VK_ constant ---------------

Просмотреть файл

@ -39,6 +39,7 @@
#include "nsWidgetDefs.h"
#include "nsBaseWidget.h"
#include "nsToolkit.h"
#include "nsSwitchToUIThread.h"
class nsIMenuBar;
//class nsContextMenu;
@ -54,7 +55,7 @@ class nsIMenuBar;
// there to decide whether methods apply to frame or client.
class nsWindow : public nsBaseWidget,
public nsSwitchToPMThread
public nsSwitchToUIThread
{
public:
// Scaffolding
@ -148,7 +149,7 @@ class nsWindow : public nsBaseWidget,
virtual void FreeNativeData( void *aDatum, PRUint32 aDataType);
// nsSwitchToPMThread interface
NS_IMETHOD CallMethod( MethodInfo *info);
virtual BOOL CallMethod(MethodInfo *info);
// PM methods which need to be public (menus, etc)
ULONG GetNextID() { return mNextID++; }

42
widget/src/os2/nsdefs.h Normal file
Просмотреть файл

@ -0,0 +1,42 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef NSDEFS_H
#define NSDEFS_H
#include <os2.h>
#ifdef _DEBUG
#define BREAK_TO_DEBUGGER DebugBreak()
#else
#define BREAK_TO_DEBUGGER
#endif
#ifdef _DEBUG
#define VERIFY(exp) ((exp) ? 0: (WinGetLastError((HAB)0), BREAK_TO_DEBUGGER))
#else // !_DEBUG
#define VERIFY(exp) (exp)
#endif // !_DEBUG
#endif // NSDEFS_H