gecko-dev/cmd/winfe/feorphan.cpp

856 lines
20 KiB
C++

/* -*- Mode: C++; tab-width: 4; 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 "stdafx.h"
#include "prefapi.h"
#include "netsdoc.h"
#include "template.h"
#ifdef MOZ_LDAP
#include "dirprefs.h"
#endif
#ifdef MOZ_MAIL_NEWS
#include "compfrm.h"
#endif
#ifdef EDITOR
//#include "edview.h"
#endif
#ifdef NSPR20
#include "private/prpriv.h"
#endif
// This is the NSPR priority of the main GUI thread (ie. mozilla)
#ifndef NSPR20
#ifdef XP_WIN32
#define MOZILLA_THREAD_PRIORITY 15
#else
#define MOZILLA_THREAD_PRIORITY 2
#endif
#else
#ifdef XP_WIN32
#define MOZILLA_THREAD_PRIORITY PR_PRIORITY_NORMAL
#else
#define MOZILLA_THREAD_PRIORITY PR_PRIORITY_LOW
#endif
#endif
#if defined(OJI) || defined(JAVA) || defined(MOCHA)
#ifndef XP_PC
#define XP_PC
#endif
#ifdef XP_WIN32
#ifndef HW_THREADS
#define HW_THREADS
#endif
#else
#ifndef SW_THREADS
#define SW_THREADS
#endif
#endif
#ifndef X386
#define X386
#endif
#include "nspr.h"
#include "plevent.h"
#endif /* OJI || JAVA || MOCHA */
#if defined(OJI)
#include "jvmmgr.h"
#elif defined(JAVA)
#include "java.h"
#endif
#if defined(XP_PC) && !defined(_WIN32)
#if defined(JAVA) || defined(OJI)
extern "C" PR_PUBLIC_API(void) SuspendAllJavaThreads(void);
#endif
#endif
// Shared event queue used to pass messages between the java threads and
// the main navigator thread...
extern "C" {
PREventQueue *mozilla_event_queue;
PRThread *mozilla_thread;
};
//
// Call layout with the red green and blue values of the current COLORREF
//
MODULE_PRIVATE void
wfe_SetLayoutColor(int type, COLORREF color)
{
#ifndef MOZ_NGLAYOUT
uint8 red = GetRValue(color);
uint8 green = GetGValue(color);
uint8 blue = GetBValue(color);
LO_SetDefaultColor(type, red, green, blue);
#endif /* MOZ_NGLAYOUT */
}
void OpenDraftExit (URL_Struct *url_struct, int/*status*/,MWContext *pContext)
{
XP_ASSERT (url_struct && pContext);
if (!url_struct) return;
NET_FreeURLStruct ( url_struct );
}
#ifdef MOZ_LDAP
// This function handles callbacks for all of the *bad* things which we
// are caching in netscape.h...In general, we should try to move these but
// the mnprefs.cpp & mnwizard.cpp are such a mess that I am punting for now
int PR_CALLBACK
DirServerListChanged(const char *pref, void *data)
{
theApp.m_directories = DIR_GetDirServers();
return TRUE;
}
#endif // MOZ_LDAP
// This function handles callbacks for all of the *bad* things which we
// are caching in netscape.h...In general, we should try to move these but
// the mnprefs.cpp & mnwizard.cpp are such a mess that I am punting for now
int PR_CALLBACK
WinFEPrefChangedFunc(const char *pref, void *data)
{
if (!strcmpi(pref,"browser.startup.homepage")) {
LPSTR lpszHomePage = NULL;
PREF_CopyCharPref("browser.startup.homepage", &lpszHomePage);
theApp.m_pHomePage = lpszHomePage;
if (lpszHomePage)
XP_FREE(lpszHomePage);
} else if (!strcmpi(pref,"browser.cache.directory")) {
LPSTR lpszCacheDir;
PREF_CopyCharPref("browser.cache.directory",&lpszCacheDir);
theApp.m_pCacheDir = lpszCacheDir;
if (lpszCacheDir)
XP_FREE(lpszCacheDir);
} else if (!strcmpi(pref,"browser.bookmark_location")) {
LPSTR lpszPref;
PREF_CopyCharPref("browser.bookmark_location",&lpszPref);
theApp.m_pBookmarkFile = lpszPref;
if (lpszPref)
XP_FREE(lpszPref);
}
else if (!strcmpi(pref,"mime.types.all_defined")) { //Begin CRN_MIME
fe_UpdateMControlMimeTypes();
}//End CRN_MIME
return PREF_NOERROR;
};
#ifdef XP_WIN16
/////////////////////////////////////////////////////////////////////////////
// 16-bit RTL helper functions
//
// These functions are used by NSPR to access RTL functions that are
// not available from 16-bit DLLs... They provide the necessary
// "mov DS, SS" entry prolog to fix "DS == SS" which is assumed
// by the MS RTL...
//
#ifdef DEBUG
extern "C" int _heapchk();
extern "C" {
extern unsigned long hcCount;
extern unsigned long hcMallocCount;
extern unsigned long hcFreeCount;
extern unsigned long hcLimit;
}
static void chk()
{
static unsigned long checkCount;
if (_heapchk() != _HEAPOK)
__asm { int 3 }
hcCount += 1;
if (hcCount >= hcLimit)
__asm { int 3 }
}
extern "C" static void aFchkstk(void)
{
}
#endif
#if defined(XP_WIN16)
// Only used when debug build on win16.
BOOL PR_CALLBACK DefaultBlockingHook(void) {
MSG msg;
BOOL ret = FALSE;
/*
* Only dispatch messages if the current thread is mozilla...
*/
if (mozilla_thread == PR_CurrentThread()) {
/* get the next message if any */
ret = (BOOL)PeekMessage(&msg,NULL,0,0,PM_NOREMOVE);
/* if we got one, process it */
if (ret) {
ret = theApp.NSPumpMessage();
}
}
/* TRUE if we got a message */
return ret;
}
#endif
#ifdef MOZ_USE_MS_MALLOC
/*--------------------------------------------------------------------------*/
/* 32-bit aligned memory management routines */
/*--------------------------------------------------------------------------*/
/* */
/* The strategy for aligning memory to 32-bit boundaries is to allocate an */
/* extra 32-bits for each allocation - A 16-bit header and a 16-bit padding */
/* */
/* If the memory returned from _fmalloc() is not 32-bit aligned, then the */
/* pointer is adjusted forward by 2 bytes to correctly align the memory. */
/* The resulting 2-byte header is initialized to PR_NON_ALIGNED_HEADER. */
/* There is also an "extra" 2 byte padding at the end of the block which */
/* are unused. */
/* */
/* If the memory returned from _fmalloc() is already 32-aligned, then the */
/* pointer is adjusted forward by 4 bytes to maintain alignment. The first */
/* 2 bytes are filled with a pad value in DEBUG mode and the next 2 bytes */
/* are initialized to PR_ALIGNED_HEADER */
/* */
/*--------------------------------------------------------------------------*/
#define PR_HEADER_SIZE 4
#define PR_ALIGNED_PAD 0xDEAD
#define PR_ALIGNED_HEADER 0xAD04
#define PR_NONALIGNED_HEADER 0xAD02
#define PR_IS_ALIGNED(p) ( !(OFFSETOF(p) & 0x03) )
#define PR_GET_HEADER_WORD(p) ( *((WORD*)(((char *)(p))-2)) )
#define PR_GET_HEADER_PAD(p) ( *((WORD*)(((char *)(p))-4)) )
#define PR_GET_ROOT(p) ( (void *)(((unsigned long)(p)) - (unsigned long)(PR_GET_HEADER_WORD(p) & 0x000F)) )
//
// This macro verifies that a memory block is 32-bit aligned and contains
// the proper header values...
//
#ifdef DEBUG
#define PR_VALIDATE_BLOCK(p) ASSERT( PR_IS_ALIGNED(p) ); \
if (p) { \
if (PR_GET_HEADER_WORD(p) == PR_ALIGNED_HEADER) { \
ASSERT( PR_GET_HEADER_PAD(p) == PR_ALIGNED_PAD ); \
} else { \
ASSERT( PR_GET_HEADER_WORD(p) == PR_NONALIGNED_HEADER ); \
} \
}
#else
#define PR_VALIDATE_BLOCK(p)
#endif
void * malloc(size_t size) {
char *p;
/* allocate a 16-bit aligned block of memory */
p = (char *)_fmalloc(size + PR_HEADER_SIZE);
/* Memory is already 32-bit aligned */
if ( PR_IS_ALIGNED(p) ) {
#ifdef DEBUG
*((WORD *)p) = PR_ALIGNED_PAD;
#endif
p = ((char *)p) + 2;
*((WORD *)p) = PR_ALIGNED_HEADER;
}
/* Align memory to 32-bit boundary */
else {
*((WORD *)p) = PR_NONALIGNED_HEADER;
}
p = ((char *)p) + 2;
PR_VALIDATE_BLOCK(p);
return (void *)p;
}
void free(void *p) {
void *h;
if (p) {
PR_VALIDATE_BLOCK(p);
h = PR_GET_ROOT(p);
ASSERT( (OFFSETOF(p) - OFFSETOF(h)) <= PR_HEADER_SIZE );
} else {
h = NULL;
}
_ffree(h);
}
void * realloc(void *p, size_t size) {
size_t old_size;
void *new_block;
void *h;
if (p) {
PR_VALIDATE_BLOCK(p);
h = PR_GET_ROOT(p);
old_size = _fmsize(h) - (PR_GET_HEADER_WORD(p) == PR_ALIGNED_HEADER ? 4 : 2);
ASSERT( (OFFSETOF(p) - OFFSETOF(h)) <= PR_HEADER_SIZE );
} else {
h = NULL;
old_size = 0;
}
/* allocate a 32-bit aligned block of memory */
new_block = malloc(size);
if (p && new_block) {
/* copy the original data into the new block of memory */
memcpy(new_block, p, (old_size < size ? old_size : size));
/* free the old block of memory */
_ffree(h);
}
p = new_block;
PR_VALIDATE_BLOCK(p);
return p;
}
void * calloc(size_t size, size_t number) {
void *p;
long bytes;
bytes = (long)size * (long)number;
ASSERT(bytes < 0xFFF0L);
/* allocate a 32-bit aligned block of memory */
p = malloc((size_t)bytes);
if (p) {
memset(p, 0x00, (size_t)bytes);
}
PR_VALIDATE_BLOCK(p);
return p;
}
#endif
/*--------------------------------------------------------------------------*/
void * PR_CALLBACK __ns_malloc(size_t size) {
return malloc(size);
}
void PR_CALLBACK __ns_free(void *p) {
free(p);
}
void* PR_CALLBACK __ns_realloc(void *p, size_t size) {
return realloc(p, size);
}
void* PR_CALLBACK __ns_calloc(size_t size, size_t number) {
return calloc(size, number);
}
int PR_CALLBACK __ns_gethostname(char * name, int namelen) {
return gethostname(name, namelen);
}
struct hostent * PR_CALLBACK __ns_gethostbyname(const char * name) {
return gethostbyname(name);
}
struct hostent * PR_CALLBACK __ns_gethostbyaddr(const char * addr, int len, int type) {
return gethostbyaddr(addr, len, type);
}
char* PR_CALLBACK __ns_getenv(const char *varname)
{
return getenv(varname);
}
int PR_CALLBACK __ns_putenv(const char *varname)
{
return putenv(varname);
}
int PR_CALLBACK __ns_auxOutput(const char *string)
{
#ifdef DEBUG
::OutputDebugString(string);
#endif
return 0;
}
void PR_CALLBACK __ns_exit(int exitCode)
{
ASSERT(0);
exit(exitCode);
}
size_t PR_CALLBACK __ns_strftime(char *s, size_t len, const char *fmt, const struct tm *p)
{
return strftime(s, len, fmt, p);
}
u_long PR_CALLBACK __ns_ntohl(u_long netlong)
{
return ntohl(netlong);
}
u_short PR_CALLBACK __ns_ntohs(u_short netshort)
{
return ntohs(netshort);
}
int PR_CALLBACK __ns_closesocket(SOCKET s)
{
return closesocket(s);
}
int PR_CALLBACK __ns_setsockopt(SOCKET s, int level, int optname, const char FAR * optval, int optlen)
{
return setsockopt(s, level, optname, optval, optlen);
}
SOCKET PR_CALLBACK __ns_socket(int af, int type, int protocol)
{
return socket(af, type, protocol);
}
int PR_CALLBACK __ns_getsockname(SOCKET s, struct sockaddr FAR *name, int FAR * namelen)
{
return getsockname(s, name, namelen);
}
u_long PR_CALLBACK __ns_htonl(u_long hostlong)
{
return htonl(hostlong);
}
u_short PR_CALLBACK __ns_htons(u_short hostshort)
{
return htons(hostshort);
}
unsigned long PR_CALLBACK __ns_inet_addr(const char FAR * cp)
{
return inet_addr(cp);
}
int PR_CALLBACK __ns_WSAGetLastError(void)
{
return WSAGetLastError();
}
int PR_CALLBACK __ns_connect(SOCKET s, const struct sockaddr FAR *name, int namelen)
{
return connect(s, name, namelen);
}
int PR_CALLBACK __ns_recv(SOCKET s, char FAR * buf, int len, int flags)
{
return recv(s, buf, len, flags);
}
int PR_CALLBACK __ns_ioctlsocket(SOCKET s, long cmd, u_long FAR *argp)
{
return ioctlsocket(s, cmd, argp);
}
int PR_CALLBACK __ns_recvfrom(SOCKET s, char FAR * buf, int len, int flags, struct sockaddr FAR *from, int FAR * fromlen)
{
return recvfrom(s, buf, len, flags, from, fromlen);
}
int PR_CALLBACK __ns_send(SOCKET s, const char FAR * buf, int len, int flags)
{
return send(s, buf, len, flags);
}
int PR_CALLBACK __ns_sendto(SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR *to, int tolen)
{
return sendto(s, buf, len, flags, to, tolen);
}
SOCKET PR_CALLBACK __ns_accept(SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen)
{
return accept(s, addr, addrlen);
}
int PR_CALLBACK __ns_listen(SOCKET s, int backlog)
{
return listen(s, backlog);
}
int PR_CALLBACK __ns_bind(SOCKET s, const struct sockaddr FAR *addr, int namelen)
{
return bind(s, addr, namelen);
}
int PR_CALLBACK __ns_select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout)
{
return select(nfds, readfds, writefds, exceptfds, timeout);
}
int PR_CALLBACK __ns_getsockopt(SOCKET s, int level, int optname, char FAR * optval, int FAR *optlen)
{
return getsockopt(s, level, optname, optval, optlen);
}
struct protoent * PR_CALLBACK __ns_getprotobyname(const char FAR * name)
{
return getprotobyname(name);
}
int PR_CALLBACK __ns_WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
long lEvent)
{
return WSAAsyncSelect(s, hWnd, wMsg, lEvent);
}
void PR_CALLBACK __ns_WSASetLastError(int iError)
{
WSASetLastError(iError);
}
int PR_CALLBACK MozillaNonblockingNetTicklerCallback(void)
{
// We need to tickle the network and the UI if we
// are stuck in java networking code.
MSG msg;
if (PR_CurrentThread() == mozilla_thread) {
/* get the next message if any */
if (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {
(void) theApp.NSPumpMessage();
return FALSE;
}
}
return TRUE;
}
#endif /* XP_WIN16 */
void fe_InitJava()
{
}
void fe_InitNSPR(void* stackBase)
{
#ifdef XP_WIN16
#if !defined(NSPR20)
//
// The 16-bit MS RTL prohibits 16-bit DLLs from calling some RTL functions.
// ie.
// malloc/free
// strftime
// sscanf
// etc...
// To fix this limitation, function pointers are passed to NSPR which
// route the RTL functions "into the EXE" where the actual RTL function
// is available. (Oh what a tangled web we weave :-( )
//
static struct PRMethodCallbackStr DLLCallbacks = {
__ns_malloc,
__ns_realloc,
__ns_calloc,
__ns_free,
__ns_gethostname,
__ns_gethostbyname,
__ns_gethostbyaddr,
__ns_getenv,
__ns_putenv,
__ns_auxOutput,
__ns_exit,
__ns_strftime,
__ns_ntohl,
__ns_ntohs,
__ns_closesocket,
__ns_setsockopt,
__ns_socket,
__ns_getsockname,
__ns_htonl,
__ns_htons,
__ns_inet_addr,
__ns_WSAGetLastError,
__ns_connect,
__ns_recv,
__ns_ioctlsocket,
__ns_recvfrom,
__ns_send,
__ns_sendto,
__ns_accept,
__ns_listen,
__ns_bind,
__ns_select,
__ns_getsockopt,
__ns_getprotobyname,
__ns_WSAAsyncSelect,
__ns_WSASetLastError
};
// Perform the 16-bit ONLY callback initialization...
PR_MDInit(&DLLCallbacks);
#endif /* NSPR20 */
#endif /* XP_WIN16 */
#if defined(OJI) || defined(JAVA) || defined(MOCHA)
#ifndef NSPR20
// Initialize the NSPR library
PR_Init( "mozilla", MOZILLA_THREAD_PRIORITY, 1, stackBase);
mozilla_thread = PR_CurrentThread();
#else
PR_STDIO_INIT()
mozilla_thread = PR_CurrentThread();
PR_SetThreadGCAble();
PR_SetThreadPriority(mozilla_thread, MOZILLA_THREAD_PRIORITY);
PL_InitializeEventsLib("mozilla");
#endif
#endif /* OJI || JAVA || MOCHA */
}
BOOL fe_ShutdownJava()
{
BOOL bRetval = TRUE;
#if defined(OJI)
nsJVMMgr* jvmMgr = JVM_GetJVMMgr();
if (jvmMgr == NULL)
return FALSE;
bRetval = (jvmMgr->ShutdownJVM() == nsJVMStatus_Enabled);
// XXX suspend all java threads
jvmMgr->Release();
#elif defined(JAVA)
bRetval = (LJ_ShutdownJava() == LJJavaStatus_Enabled);
#if defined(XP_PC) && !defined(_WIN32)
SuspendAllJavaThreads();
#endif
#endif
return(bRetval);
}
//
// Register our document icons
//
static const CString strMARKUP_KEY = "NetscapeMarkup";
BOOL fe_RegisterOLEIcon ( LPSTR szCLSIDObject, // Class ID of the Object
LPSTR szObjectName, // Human Readable Object Name
LPSTR szIconPath ) // Path and Index of Icon
{
HKEY hKey;
LONG lRes = 0L;
char lpszCLSID[] = "CLSID"; // OLE Class ID Section of eg DB
char lpszDefIcon[] = "\\DefaultIcon"; // Default Icon Subkey
char lpBuffer[64]; // Working buffer
// Open the reg db for the "CLSID" key, this top-level key
// is where OLE2 and other OLE aware apps will look for
// this information.
lRes = RegOpenKey(HKEY_CLASSES_ROOT, lpszCLSID, &hKey);
if (ERROR_SUCCESS != lRes)
{
TRACE("RegOpenKey failed.\n");
return FALSE;
}
// Register the Object
// Set the value of the CLSID Entry to the Human Readable
// name of the Object
lRes = RegSetValue( hKey,
szCLSIDObject,
REG_SZ,
szObjectName,
lstrlen(szObjectName)
);
if (ERROR_SUCCESS != lRes) // bail on failure
{
RegCloseKey(hKey);
return FALSE;
}
// Build "defaulticon" subkey string "{ <class id> }\\DefaultIcon"
lstrcpy (lpBuffer, szCLSIDObject);
lstrcat (lpBuffer, lpszDefIcon);
// Set Object's default icon entry to point to the
// default icon for the object
lRes = RegSetValue( hKey,
lpBuffer,
REG_SZ,
szIconPath,
lstrlen(szIconPath)
);
if (ERROR_SUCCESS != lRes) // bail on failure
{
RegCloseKey(hKey);
return FALSE;
}
// Close the reg db
RegCloseKey(hKey);
//
//
//
lRes = RegOpenKey(HKEY_CLASSES_ROOT, (const char*)strMARKUP_KEY, &hKey);
if (ERROR_SUCCESS != lRes)
{
TRACE("RegOpenKey failed.\n");
return FALSE;
}
// Set Object's default icon entry to point to the
// default icon for the object
lRes = RegSetValue( hKey,
lpszCLSID,
REG_SZ,
szCLSIDObject,
lstrlen(szCLSIDObject)
);
if (ERROR_SUCCESS != lRes) // bail on failure
{
RegCloseKey(hKey);
return FALSE;
}
// Set Object's default icon entry to point to the
// default icon for the object
lRes = RegSetValue( hKey,
"DefaultIcon",
REG_SZ,
szIconPath,
lstrlen(szIconPath)
);
if (ERROR_SUCCESS != lRes) // bail on failure
{
RegCloseKey(hKey);
return FALSE;
}
// Close the reg db
RegCloseKey(hKey);
return TRUE;
}
#if defined(XP_WIN16)
/****************************************************************************/
/* */
/* BEWARE! BEWARE! BEWARE! BEWARE! BEWARE! BEWARE! BEWARE! BEWARE! BEWARE! */
/* */
/* The following code is duplicated from ns\modules\applet\src\lj_embed.c */
/* It is ONLY required for 16-bit until JAVA becomes integrated into the */
/* build! */
/* */
/* BEWARE! BEWARE! BEWARE! BEWARE! BEWARE! BEWARE! BEWARE! BEWARE! BEWARE! */
/* */
/****************************************************************************/
#if defined(MOCHA) && !defined(JAVA)
#include "prevent.h"
#include "prlog.h"
PR_LOG_DEFINE(Event);
/*
* There is currently a race between which thread destroys synchronous
* events. See bug 32832 for a full description.
*/
void
LJ_ProcessEvent()
{
PREvent* event;
for (;;) {
PR_LOG_BEGIN(Event, debug, ("$$$ getting event\n"));
event = PR_GetEvent(mozilla_event_queue);
if (event == NULL) {
return;
}
if(event->synchronousResult) {
PR_HandleEvent(event);
PR_LOG_END(Event, debug, ("$$$ done with sync event\n"));
}
else {
PR_HandleEvent(event);
PR_LOG_END(Event, debug, ("$$$ done with async event\n"));
PR_DestroyEvent(event);
}
}
}
#endif // MOCHA && !JAVA
#endif // XP_WIN16
#ifdef XP_WIN16
#if defined(NSPR20)
#include "private\prpriv.h"
#endif
void fe_yield(void)
{
PR_Sleep(PR_INTERVAL_NO_WAIT);
}
#endif