зеркало из https://github.com/mozilla/pjs.git
Changes for OS/2. Patch provided by Eric Olson (eric.olson@sympatico.ca)
This commit is contained in:
Родитель
d922249feb
Коммит
78235616b4
|
@ -0,0 +1,75 @@
|
|||
#
|
||||
# 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/
|
||||
#
|
||||
# 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 the Mozilla OS/2 libraries.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Makefile for gfx/src/os2
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
OS2_IMPLIB = 1
|
||||
OS2_LIBRARYNAME = gfxos2
|
||||
|
||||
MODULE = raptor
|
||||
|
||||
REQUIRES = util img xpcom raptor dom netlib java dbm js
|
||||
|
||||
DEFINES += -D_IMPL_NS_GFXONXP
|
||||
|
||||
OS2_LIBS = nggfx img mozjs mozutil netlib xpcom
|
||||
OS_LIBS += $(NSPR_LIBS) -luconv
|
||||
|
||||
CPPSRCS = \
|
||||
nsDeviceContextOS2.cpp \
|
||||
nsRenderingContextOS2.cpp \
|
||||
nsFontMetricsOS2.cpp \
|
||||
nsImageOS2.cpp \
|
||||
nsPaletteOS2.cpp \
|
||||
nsRegionOS2.cpp \
|
||||
nsDeviceContextSpecFactoryO.cpp \
|
||||
nsDeviceContextSpecOS2.cpp \
|
||||
nsDrawingSurfaceOS2.cpp \
|
||||
nsGfxFactoryOS2.cpp \
|
||||
nsTimerOS2.cpp \
|
||||
$(NULL)
|
||||
|
||||
CSRCS = libprint.c
|
||||
|
||||
RES_FILE = $(srcdir)/libprint.res
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += -I$(topsrcdir)/gfx/src
|
||||
|
||||
# This adds the resources for the print dialog to the gfxos2 dll.
|
||||
# I guess eventually we ought to use an xml dialog...
|
||||
# XXX Have to copy files because rc is too stupid for an objdir build
|
||||
|
||||
$(SHARED_LIBRARY): $(OBJS) $(RES_FILE)
|
||||
|
||||
$(RES_FILE): $(srcdir)/libprint.rc
|
||||
cp $(srcdir)/libprint.ico ./libprint.ico
|
||||
cp $(srcdir)/libprres.h ./libprres.h
|
||||
rc -r $(srcdir)/libprint.rc
|
||||
|
|
@ -0,0 +1,445 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
/* Simple printing API. I've not done this before, so bear with me... */
|
||||
|
||||
#define INCL_PM
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_SPLDOSPRINT
|
||||
#include <os2.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libprint.h"
|
||||
#include "libprres.h"
|
||||
|
||||
/* print-queue structure, opaque so I can change it. */
|
||||
struct _PRTQUEUE
|
||||
{
|
||||
PRQINFO3 q;
|
||||
};
|
||||
|
||||
/* local functions */
|
||||
static PRTQUEUE *prnGetDefaultPrinter( void);
|
||||
static PRQINFO3 *prnGetAllQueues( PULONG pNumQueues);
|
||||
static BOOL prnEscape( HDC hdc, long lEscape);
|
||||
static PRTQUEUE *prnCreatePRTQUEUE( PRQINFO3 *pInfo);
|
||||
|
||||
MRESULT EXPENTRY prnDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
|
||||
|
||||
/****************************************************************************/
|
||||
/* Library-level data and functions */
|
||||
/****************************************************************************/
|
||||
|
||||
static HMODULE hmodRes;
|
||||
|
||||
BOOL PrnInitialize( HMODULE hmodResources)
|
||||
{
|
||||
hmodRes = hmodResources;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL PrnTerminate()
|
||||
{
|
||||
/* nop for now, may do something eventually */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Printer Selection */
|
||||
/****************************************************************************/
|
||||
|
||||
/* Main work function - run a dialog to pick a printer */
|
||||
PRTQUEUE *PrnSelectPrinter( HWND hwndOwner, BOOL bQuiet)
|
||||
{
|
||||
PRTQUEUE *pQueue = 0;
|
||||
|
||||
if( bQuiet)
|
||||
pQueue = prnGetDefaultPrinter();
|
||||
else
|
||||
{
|
||||
ULONG rc = WinDlgBox( HWND_DESKTOP, hwndOwner,
|
||||
prnDlgProc,
|
||||
hmodRes, IDD_PICKPRINTER,
|
||||
&pQueue);
|
||||
if( rc == DID_CANCEL)
|
||||
pQueue = 0;
|
||||
}
|
||||
|
||||
return pQueue;
|
||||
}
|
||||
|
||||
BOOL PrnClosePrinter( PRTQUEUE *pPrintQueue)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
|
||||
if( pPrintQueue)
|
||||
{
|
||||
free( pPrintQueue);
|
||||
rc = TRUE;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
PRTQUEUE *prnGetDefaultPrinter()
|
||||
{
|
||||
ULONG ulQueues = 0;
|
||||
PRQINFO3 *pInfo = prnGetAllQueues( &ulQueues);
|
||||
PRTQUEUE *pq = 0;
|
||||
|
||||
if( ulQueues > 0)
|
||||
{
|
||||
/* find the default one */
|
||||
ULONG i;
|
||||
for( i = 0; i < ulQueues; i++)
|
||||
if( pInfo[ i].fsType & PRQ3_TYPE_APPDEFAULT)
|
||||
break;
|
||||
|
||||
/* must have a default printer... */
|
||||
if( i == ulQueues)
|
||||
i = 0;
|
||||
|
||||
pq = prnCreatePRTQUEUE( pInfo + i);
|
||||
|
||||
free( pInfo);
|
||||
}
|
||||
|
||||
return pq;
|
||||
}
|
||||
|
||||
PRTQUEUE *prnCreatePRTQUEUE( PRQINFO3 *pInfo)
|
||||
{
|
||||
PRTQUEUE *pq = (PRTQUEUE *) malloc( sizeof( PRTQUEUE));
|
||||
memcpy( &pq->q, pInfo, sizeof( PRQINFO3));
|
||||
return pq;
|
||||
}
|
||||
|
||||
PRQINFO3 *prnGetAllQueues( PULONG pNumQueues)
|
||||
{
|
||||
ULONG ulReturned = 0, ulNeeded = 0, ulTotal = 0;
|
||||
PBYTE pBuffer = NULL;
|
||||
SPLERR rc = 0;
|
||||
|
||||
/* first work out how much space we need */
|
||||
rc = SplEnumQueue( NULL, 3, pBuffer, 0, &ulReturned,
|
||||
&ulTotal, &ulNeeded, NULL);
|
||||
|
||||
pBuffer = (PBYTE) malloc( ulNeeded);
|
||||
|
||||
/* now get the queue-infos */
|
||||
rc = SplEnumQueue( NULL, 3, pBuffer, ulNeeded, &ulReturned,
|
||||
&ulTotal, &ulNeeded, NULL);
|
||||
|
||||
*pNumQueues = ulReturned;
|
||||
|
||||
return (PRQINFO3 *) pBuffer;
|
||||
}
|
||||
|
||||
BOOL PrnDoJobProperties( PRTQUEUE *pInfo)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
|
||||
if( pInfo)
|
||||
{
|
||||
char *pszPrinter = strdup( pInfo->q.pszPrinters);
|
||||
char *pszDriverName = strdup( pInfo->q.pszDriverName);
|
||||
char *pszDeviceName = 0;
|
||||
char *c;
|
||||
long lRC;
|
||||
|
||||
if( 0 != (c = strchr( pszPrinter, ',')))
|
||||
*c = '\0';
|
||||
|
||||
if( 0 != (c = strchr( pszDriverName, '.')))
|
||||
{
|
||||
*c = '\0';
|
||||
pszDeviceName = c + 1;
|
||||
}
|
||||
|
||||
lRC = DevPostDeviceModes( 0 /*hab*/,
|
||||
pInfo->q.pDriverData,
|
||||
pszDriverName,
|
||||
pszDeviceName,
|
||||
pszPrinter,
|
||||
DPDM_POSTJOBPROP);
|
||||
free( pszPrinter);
|
||||
free( pszDriverName);
|
||||
|
||||
rc = (lRC != DPDM_ERROR);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Job management */
|
||||
/****************************************************************************/
|
||||
|
||||
HDC PrnOpenDC( PRTQUEUE *pInfo, PSZ pszApplicationName)
|
||||
{
|
||||
HDC hdc = 0;
|
||||
|
||||
if( pInfo && pszApplicationName)
|
||||
{
|
||||
char *pszDriverName = strdup( pInfo->q.pszDriverName), *c;
|
||||
DEVOPENSTRUC dop = { pInfo->q.pszName,
|
||||
pszDriverName,
|
||||
pInfo->q.pDriverData,
|
||||
"PM_Q_STD",
|
||||
pszApplicationName,
|
||||
pInfo->q.pszPrProc,
|
||||
0, 0, 0 };
|
||||
|
||||
if( 0 != (c = strchr( pszDriverName, '.')))
|
||||
*c = '\0';
|
||||
|
||||
hdc = DevOpenDC( 0 /*hab*/,
|
||||
OD_QUEUED,
|
||||
"*",
|
||||
6,
|
||||
(PDEVOPENDATA) &dop,
|
||||
NULLHANDLE);
|
||||
|
||||
free( pszDriverName);
|
||||
}
|
||||
|
||||
return hdc;
|
||||
}
|
||||
|
||||
BOOL PrnCloseDC( HDC hdc)
|
||||
{
|
||||
return (hdc != 0 && DEV_OK == DevCloseDC( hdc));
|
||||
}
|
||||
|
||||
BOOL PrnStartJob( HDC hdc, PSZ pszJobName)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
|
||||
if( hdc && pszJobName)
|
||||
{
|
||||
long lDummy = 0;
|
||||
long lResult = DevEscape( hdc, DEVESC_STARTDOC,
|
||||
(long) strlen( pszJobName) + 1, pszJobName,
|
||||
&lDummy, NULL);
|
||||
rc = (lResult == DEV_OK);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL PrnNewPage( HDC hdc)
|
||||
{
|
||||
return prnEscape( hdc, DEVESC_NEWFRAME);
|
||||
}
|
||||
|
||||
BOOL prnEscape( HDC hdc, long lEscape)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
|
||||
if( hdc)
|
||||
{
|
||||
long lDummy = 0;
|
||||
long lResult = DevEscape( hdc, lEscape,
|
||||
0, NULL, &lDummy, NULL);
|
||||
rc = (lResult == DEV_OK);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL PrnAbortJob( HDC hdc)
|
||||
{
|
||||
return prnEscape( hdc, DEVESC_ABORTDOC);
|
||||
}
|
||||
|
||||
BOOL PrnEndJob( HDC hdc)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
|
||||
if( hdc)
|
||||
{
|
||||
long lOutCount = 2;
|
||||
USHORT usJobID = 0;
|
||||
long lResult = DevEscape( hdc, DEVESC_ENDDOC,
|
||||
0, NULL, &lOutCount, (PBYTE) &usJobID);
|
||||
rc = (lResult == DEV_OK);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* find the selected form */
|
||||
BOOL PrnQueryHardcopyCaps( HDC hdc, PHCINFO pHCInfo)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
|
||||
if( hdc && pHCInfo)
|
||||
{
|
||||
PHCINFO pBuffer;
|
||||
long lAvail, i;
|
||||
|
||||
/* query how many forms are available */
|
||||
lAvail = DevQueryHardcopyCaps( hdc, 0, 0, NULL);
|
||||
|
||||
pBuffer = (PHCINFO) malloc( lAvail * sizeof(HCINFO));
|
||||
|
||||
DevQueryHardcopyCaps( hdc, 0, lAvail, pBuffer);
|
||||
|
||||
for( i = 0; i < lAvail; i++)
|
||||
if( pBuffer[ i].flAttributes & HCAPS_CURRENT)
|
||||
{
|
||||
memcpy( pHCInfo, pBuffer + i, sizeof(HCINFO));
|
||||
rc = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
free( pBuffer);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Print dialog stuff */
|
||||
/****************************************************************************/
|
||||
|
||||
typedef struct _PRNDLG
|
||||
{
|
||||
HWND hwndLbox;
|
||||
PRQINFO3 *pQueues;
|
||||
ULONG ulQueues;
|
||||
HPOINTER hPointer;
|
||||
PRTQUEUE **ppQueue;
|
||||
} PRNDLG, *PPRNDLG;
|
||||
|
||||
#define PRM_QUERYQUEUE (WM_USER) /* returns PRQINFO3* */
|
||||
#define PRM_JOBPROPERTIES (WM_USER + 1)
|
||||
|
||||
MRESULT EXPENTRY prnDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
PPRNDLG pData = (PPRNDLG) WinQueryWindowPtr( hwnd, 0);
|
||||
|
||||
switch( msg)
|
||||
{
|
||||
case WM_INITDLG:
|
||||
/* set up our data structure */
|
||||
pData = (PPRNDLG) malloc( sizeof( PRNDLG));
|
||||
pData->pQueues = prnGetAllQueues( &pData->ulQueues);
|
||||
pData->hwndLbox = WinWindowFromID( hwnd, IDLB_QUEUES);
|
||||
pData->hPointer = WinLoadPointer( HWND_DESKTOP, hmodRes, IDICO_PRINTER);
|
||||
pData->ppQueue = (PRTQUEUE**) mp2;
|
||||
WinSetWindowPtr( hwnd, 0, pData);
|
||||
|
||||
/* set up the dialog */
|
||||
WinSetPresParam( hwnd, PP_FONTNAMESIZE, 7, "8.Helv");
|
||||
WinEnableWindow( WinWindowFromID( hwnd, IDB_HELP), FALSE);
|
||||
WinSendMsg( hwnd, WM_SETICON, MPFROMLONG(pData->hPointer), 0);
|
||||
|
||||
/* populate listbox */
|
||||
if( pData->ulQueues == 0)
|
||||
{
|
||||
WinEnableWindow( WinWindowFromID( hwnd, DID_OK), FALSE);
|
||||
WinSendMsg( pData->hwndLbox, LM_INSERTITEM, MPFROMSHORT(0),
|
||||
MPFROMP("(no printers available)"));
|
||||
WinEnableWindow( pData->hwndLbox, FALSE);
|
||||
WinEnableWindow( WinWindowFromID( hwnd, IDB_JOBPROPERTIES), FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for( i = 0; i < pData->ulQueues; i++)
|
||||
{
|
||||
WinSendMsg( pData->hwndLbox, LM_INSERTITEM, MPFROMSHORT(i),
|
||||
MPFROMP( pData->pQueues[i].pszComment));
|
||||
WinSendMsg( pData->hwndLbox, LM_SETITEMHANDLE, MPFROMSHORT(i),
|
||||
MPFROMP( pData->pQueues + i));
|
||||
if( pData->pQueues[i].fsType & PRQ3_TYPE_APPDEFAULT)
|
||||
WinSendMsg( pData->hwndLbox, LM_SELECTITEM,
|
||||
MPFROMSHORT(i), MPFROMSHORT(TRUE));
|
||||
}
|
||||
}
|
||||
// Center over owner
|
||||
{
|
||||
RECTL rclMe, rclOwner;
|
||||
LONG lX, lY;
|
||||
BOOL rc;
|
||||
WinQueryWindowRect( WinQueryWindow( hwnd, QW_PARENT), &rclOwner);
|
||||
WinQueryWindowRect( hwnd, &rclMe);
|
||||
lX = (rclOwner.xRight - rclMe.xRight) / 2;
|
||||
lY = (rclOwner.yTop - rclMe.yTop) / 2;
|
||||
rc = WinSetWindowPos( hwnd, 0, lX, lY, 0, 0, SWP_MOVE);
|
||||
}
|
||||
break;
|
||||
|
||||
case PRM_QUERYQUEUE:
|
||||
{
|
||||
/* find which lbox item is selected & return its handle */
|
||||
MRESULT sel;
|
||||
sel = WinSendMsg( pData->hwndLbox, LM_QUERYSELECTION, 0, 0);
|
||||
return WinSendMsg( pData->hwndLbox, LM_QUERYITEMHANDLE, sel, 0);
|
||||
}
|
||||
|
||||
case PRM_JOBPROPERTIES:
|
||||
{
|
||||
/* do job properties dialog for selected printer */
|
||||
PPRQINFO3 pInfo;
|
||||
pInfo = (PPRQINFO3) WinSendMsg( hwnd, PRM_QUERYQUEUE, 0, 0);
|
||||
PrnDoJobProperties( (PRTQUEUE*) pInfo); /* !! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_CONTROL:
|
||||
if( SHORT2FROMMP(mp1) == LN_ENTER)
|
||||
return WinSendMsg( hwnd, PRM_JOBPROPERTIES, 0, 0);
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch( SHORT1FROMMP(mp1))
|
||||
{
|
||||
case IDB_JOBPROPERTIES:
|
||||
WinSendMsg( hwnd, PRM_JOBPROPERTIES, 0, 0);
|
||||
return 0;
|
||||
|
||||
case DID_OK:
|
||||
{
|
||||
/* set return value */
|
||||
PPRQINFO3 pInfo;
|
||||
pInfo = (PPRQINFO3) WinSendMsg( hwnd, PRM_QUERYQUEUE, 0, 0);
|
||||
*(pData->ppQueue) = prnCreatePRTQUEUE( pInfo);
|
||||
break; /* dismiss dialog normally */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
if( pData->pQueues)
|
||||
free( pData->pQueues);
|
||||
free( pData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return WinDefDlgProc( hwnd, msg, mp1, mp2);
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
/* (Over?) Simple printing API */
|
||||
|
||||
/****************************************************************************/
|
||||
/* Example usage: */
|
||||
/* */
|
||||
/* PRTQUEUE *pq = PrnSelectPrinter(...) */
|
||||
/* HDC dcPrint = PrnOpenDC( pq, ...) */
|
||||
/* */
|
||||
/* GpiAssociate( hps, dcPrint) */
|
||||
/* */
|
||||
/* PrnStartJob( dcPrint, ...) */
|
||||
/* . */
|
||||
/* . */
|
||||
/* Gpi calls to `hps' */
|
||||
/* . */
|
||||
/* . */
|
||||
/* PrnEndJob( dcPrint) */
|
||||
/* */
|
||||
/* GpiAssociate( hps, NULLHANDLE) */
|
||||
/* */
|
||||
/* PrnCloseDC( dcPrint) */
|
||||
/* PrnClosePrinter( pq) */
|
||||
/****************************************************************************/
|
||||
|
||||
#ifndef _libprint_h
|
||||
#define _libprint_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Library init and term; job properties per queue are cached during run. */
|
||||
BOOL PrnInitialize( HMODULE hmodResources);
|
||||
BOOL PrnTerminate( void);
|
||||
|
||||
/* opaque type to describe a print queue (printer) */
|
||||
typedef struct _PRTQUEUE PRTQUEUE;
|
||||
|
||||
/* Select a printer. If bQuiet is set, the default one is used; otherwise, */
|
||||
/* a dialog is popped up to allow the user to choose. Job properties */
|
||||
/* configuration can be done at this stage, from the dialog. */
|
||||
/* Returns null if use cancels. */
|
||||
PRTQUEUE *PrnSelectPrinter( HWND hwndOwner, BOOL bQuiet);
|
||||
|
||||
/* Release app. resources associated with a printer */
|
||||
BOOL PrnClosePrinter( PRTQUEUE *pPrintQueue);
|
||||
|
||||
/* Display job-properties dialog. Returns success. */
|
||||
BOOL PrnDoJobProperties( PRTQUEUE *pPrintQueue);
|
||||
|
||||
/* Get a DC for the selected printer. Must supply the application name. */
|
||||
HDC PrnOpenDC( PRTQUEUE *pPrintQueue, PSZ pszApplicationName);
|
||||
|
||||
/* Close the print DC; your PS should have been disassociated. */
|
||||
BOOL PrnCloseDC( HDC hdc);
|
||||
|
||||
/* Get the hardcopy caps for the selected form */
|
||||
BOOL PrnQueryHardcopyCaps( HDC hdc, PHCINFO pHCInfo);
|
||||
|
||||
/* Begin a print job. A PS should have been associated with the dc */
|
||||
/* (returned from PrnOpenDC()), a job name is required. */
|
||||
BOOL PrnStartJob( HDC hdc, PSZ pszJobName);
|
||||
|
||||
/* End a print job previously started with PrnStartJob(). */
|
||||
BOOL PrnEndJob( HDC hdc);
|
||||
|
||||
/* Abort the current job started with PrnStartJob(). */
|
||||
BOOL PrnAbortJob( HDC hdc);
|
||||
|
||||
/* Make a page-break. */
|
||||
BOOL PrnNewPage( HDC hdc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,648 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// ToDo:
|
||||
#include "nsGfxDefs.h"
|
||||
#include "libprint.h"
|
||||
|
||||
#include "nsDeviceContextSpecOS2.h"
|
||||
#include "nsDeviceContextOS2.h"
|
||||
#include "nsDrawingSurfaceOS2.h"
|
||||
#include "nsPaletteOS2.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsFont.h"
|
||||
#include "il_util.h"
|
||||
|
||||
// nsDeviceContextOS2 - The graphics state associated with a window.
|
||||
// Keep the colour palette for all rendering contexts here; they share
|
||||
// it and the widget can do palette-y things.
|
||||
//
|
||||
// Remember that this thing can be fairly long-lived, linked to a window.
|
||||
//
|
||||
// It's a bit schizophrenic - really there should be a nsIPrintDC <: nsIDC ...
|
||||
|
||||
// Init/Term -----------------------------------------------------------------
|
||||
|
||||
nsDeviceContextOS2::nsDeviceContextOS2() : DeviceContextImpl()
|
||||
{
|
||||
// Default for now
|
||||
mSurface = nsnull;
|
||||
mDepth = 0;
|
||||
mPaletteInfo.isPaletteDevice = PR_FALSE;
|
||||
mPaletteInfo.sizePalette = 0;
|
||||
mPaletteInfo.numReserved = 0;
|
||||
mPaletteInfo.palette = nsnull;
|
||||
mPalette = nsnull;
|
||||
mPixelsToTwips = 0;
|
||||
mTwipsToPixels = 0;
|
||||
mPixelScale = 1.0f;
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mDC = 0;
|
||||
mPrintState = nsPrintState_ePreBeginDoc;
|
||||
|
||||
// Init module if necessary (XXX find a better way of doing this!)
|
||||
if( !gModuleData.lDisplayDepth)
|
||||
gModuleData.Init();
|
||||
}
|
||||
|
||||
nsDeviceContextOS2::~nsDeviceContextOS2()
|
||||
{
|
||||
NS_IF_RELEASE( mSurface);
|
||||
NS_IF_RELEASE( mPalette);
|
||||
|
||||
if( mDC)
|
||||
{
|
||||
GpiAssociate( mPS, 0);
|
||||
GpiDestroyPS( mPS);
|
||||
PrnCloseDC( mDC);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::Init( nsNativeWidget aWidget)
|
||||
{
|
||||
HWND hwnd = aWidget ? (HWND)aWidget : HWND_DESKTOP;
|
||||
HDC hdc = WinOpenWindowDC( hwnd);
|
||||
|
||||
CommonInit( hdc);
|
||||
|
||||
// Get size - don't know if this is needed for non-print DCs
|
||||
long lCaps[2];
|
||||
DevQueryCaps( hdc, CAPS_WIDTH, 2, lCaps);
|
||||
mWidth = lCaps[0]; // these are in device units...
|
||||
mHeight = lCaps[1];
|
||||
|
||||
// Don't need to close HDCs obtained from WinOpenWindowDC
|
||||
|
||||
return DeviceContextImpl::Init( aWidget);
|
||||
}
|
||||
|
||||
// This version of Init() is called when creating a print DC
|
||||
nsresult nsDeviceContextOS2::Init( nsNativeDeviceContext aContext,
|
||||
nsIDeviceContext *aOrigContext)
|
||||
{
|
||||
// These calcs are from the windows version & I'm not 100%
|
||||
// sure what's going on...
|
||||
|
||||
float origscale, newscale;
|
||||
float t2d, a2d;
|
||||
|
||||
mDC = (HDC)aContext; // we are print dc...
|
||||
|
||||
// Create a print PS now. This is necessary 'cos we need it from
|
||||
// odd places to do font-y things, where the only common reference
|
||||
// point is this DC. We can't just create a new PS because only one
|
||||
// PS can be associated with a given DC, and we can't get that PS from
|
||||
// the DC (really?). And it would be slow :-)
|
||||
SIZEL sizel = { 0 , 0 };
|
||||
mPS = GpiCreatePS( 0/*hab*/, mDC, &sizel,
|
||||
PU_PELS | GPIT_MICRO | GPIA_ASSOC);
|
||||
|
||||
CommonInit( mDC);
|
||||
// yech: we can't call nsDeviceContextImpl::Init() 'cos no widget.
|
||||
DeviceContextImpl::CommonInit();
|
||||
|
||||
GetTwipsToDevUnits( newscale);
|
||||
aOrigContext->GetTwipsToDevUnits( origscale);
|
||||
|
||||
mPixelScale = newscale / origscale;
|
||||
|
||||
aOrigContext->GetTwipsToDevUnits( t2d);
|
||||
aOrigContext->GetAppUnitsToDevUnits( a2d);
|
||||
|
||||
mAppUnitsToDevUnits = (a2d / t2d) * mTwipsToPixels;
|
||||
mDevUnitsToAppUnits = 1.0f / mAppUnitsToDevUnits;
|
||||
|
||||
HCINFO hcinfo;
|
||||
PrnQueryHardcopyCaps( mDC, &hcinfo);
|
||||
mWidth = hcinfo.xPels;
|
||||
mHeight = hcinfo.yPels;
|
||||
// XXX hsb says there are margin problems, must be from here...
|
||||
printf( "Got surface of size %d x %d pixels\n", mWidth, mHeight);
|
||||
printf( "mPixelScale = %f\n", mPixelScale);
|
||||
|
||||
// We need to begin a document now, because the client is entitled at
|
||||
// this point to do stuff like create fonts, which required the PS to
|
||||
// be associated with a DC which has been DEVESC_STARTDOC'd.
|
||||
BeginDocument();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsDeviceContextOS2::CommonInit( HDC aDC)
|
||||
{
|
||||
// Record palette-potential of device even if it is >8bpp
|
||||
long lCap = 0;
|
||||
DevQueryCaps( aDC, CAPS_ADDITIONAL_GRAPHICS, 1, &lCap);
|
||||
mPaletteInfo.isPaletteDevice = !!(lCap & CAPS_PALETTE_MANAGER);
|
||||
|
||||
// Work out the pels-to-twips conversion
|
||||
DevQueryCaps( aDC, CAPS_VERTICAL_FONT_RES, 1, &lCap);
|
||||
mTwipsToPixels = ((float) lCap) / (float)NSIntPointsToTwips(72);
|
||||
mPixelsToTwips = 1.0f / mTwipsToPixels;
|
||||
|
||||
// max palette size: level out at COLOR_CUBE_SIZE
|
||||
// (or CAPS_COLORS ?)
|
||||
DevQueryCaps( aDC, CAPS_PHYS_COLORS, 1, &lCap);
|
||||
mPaletteInfo.sizePalette = (PRUint8) (min( lCap, COLOR_CUBE_SIZE));
|
||||
|
||||
// erm?
|
||||
mPaletteInfo.numReserved = 0;
|
||||
|
||||
DevQueryCaps( aDC, CAPS_COLOR_BITCOUNT, 1, &lCap);
|
||||
mDepth = lCap;
|
||||
}
|
||||
|
||||
// Creation of other gfx objects malarky -------------------------------------
|
||||
|
||||
nsresult nsDeviceContextOS2::GetDrawingSurface( nsIRenderingContext &aContext, nsDrawingSurface &aSurface)
|
||||
{
|
||||
if( !mSurface)
|
||||
{
|
||||
nsDrawingSurface tSurface;
|
||||
aContext.CreateDrawingSurface( nsnull, 0, tSurface);
|
||||
mSurface = (nsDrawingSurfaceOS2 *) tSurface;
|
||||
NS_ADDREF(mSurface);
|
||||
}
|
||||
|
||||
printf("Dodgy nsDeviceContext::GetDrawingContext() called\n");
|
||||
|
||||
aSurface = mSurface;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::GetDeviceContextFor( nsIDeviceContextSpec *aDevice,
|
||||
nsIDeviceContext *&aContext)
|
||||
{
|
||||
// Prolly want to clean this up xpCom-wise...
|
||||
nsDeviceContextOS2 *newCX = new nsDeviceContextOS2;
|
||||
nsDeviceContextSpecOS2 *spec = (nsDeviceContextSpecOS2*) aDevice;
|
||||
|
||||
aContext = newCX;
|
||||
NS_ADDREF(aContext);
|
||||
|
||||
PRTQUEUE *pq;
|
||||
spec->GetPRTQUEUE( pq);
|
||||
|
||||
HDC hdcPrint = PrnOpenDC( pq, "Mozilla");
|
||||
|
||||
return newCX->Init( (nsNativeDeviceContext) hdcPrint, this);
|
||||
}
|
||||
|
||||
// Create a rendering context against our hdc for a printer
|
||||
nsresult nsDeviceContextOS2::CreateRenderingContext( nsIRenderingContext *&aContext)
|
||||
{
|
||||
NS_ASSERTION( mDC, "CreateRenderingContext for non-print DC");
|
||||
|
||||
nsIRenderingContext *pContext = new nsRenderingContextOS2;
|
||||
NS_ADDREF(pContext);
|
||||
|
||||
nsPrintSurface *surf = new nsPrintSurface;
|
||||
NS_ADDREF(surf);
|
||||
|
||||
surf->Init( mPS, mWidth, mHeight);
|
||||
|
||||
nsresult rc = pContext->Init( this, (void*)((nsDrawingSurfaceOS2 *) surf));
|
||||
|
||||
if( NS_OK != rc)
|
||||
{
|
||||
NS_IF_RELEASE(surf);
|
||||
NS_IF_RELEASE(pContext);
|
||||
}
|
||||
|
||||
aContext = pContext;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
HPS nsDeviceContextOS2::GetRepresentativePS() const
|
||||
{
|
||||
HPS hps;
|
||||
|
||||
if( mDC == 0)
|
||||
{
|
||||
HWND hwnd = mWidget ? (HWND)mWidget : HWND_DESKTOP;
|
||||
hps = WinGetPS( hwnd);
|
||||
}
|
||||
else
|
||||
hps = mPS;
|
||||
|
||||
return hps;
|
||||
}
|
||||
|
||||
void nsDeviceContextOS2::ReleaseRepresentativePS( HPS aPS)
|
||||
{
|
||||
if( mDC == 0)
|
||||
if( !WinReleasePS( aPS))
|
||||
PMERROR( "WinReleasePS (DC)");
|
||||
else
|
||||
/* nop */ ;
|
||||
}
|
||||
|
||||
// Metrics -------------------------------------------------------------------
|
||||
|
||||
// Note that this returns values in app units, as opposed to GetSystemAttr(),
|
||||
// which uses device units.
|
||||
nsresult nsDeviceContextOS2::GetScrollBarDimensions( float &aWidth, float &aHeight) const
|
||||
{
|
||||
aWidth = (float) WinQuerySysValue( HWND_DESKTOP, SV_CXVSCROLL) *
|
||||
mDevUnitsToAppUnits;
|
||||
aHeight = (float) WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL) *
|
||||
mDevUnitsToAppUnits;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Utility function to query a logical font, from the ini file if possible
|
||||
// but with os-dependent defaults. If there's no appropriate inikey, just
|
||||
// supply a null for that parameter.
|
||||
static void FindSystemFont( nsFont *aFont, const char *aIniKey,
|
||||
const char *aWarp3Default,
|
||||
const char *aWarp4Default)
|
||||
{
|
||||
static int bIsWarp4 = -1; // XXX MT
|
||||
char fontNameSize[100];
|
||||
|
||||
NS_ASSERTION( aWarp3Default && aWarp4Default, "Bad params to FindSystemFont");
|
||||
if( !aWarp3Default || !aWarp4Default) return;
|
||||
|
||||
if( bIsWarp4 == -1)
|
||||
{
|
||||
ULONG ulValues[2];
|
||||
DosQuerySysInfo( QSV_VERSION_MAJOR, QSV_VERSION_MINOR,
|
||||
ulValues, sizeof ulValues);
|
||||
bIsWarp4 = (ulValues[0] >= 20) && (ulValues[1] >= 40);
|
||||
}
|
||||
|
||||
if( aIniKey)
|
||||
PrfQueryProfileString( HINI_USERPROFILE, "PM_SystemFonts", aIniKey,
|
||||
bIsWarp4 ? aWarp4Default : aWarp3Default,
|
||||
fontNameSize, 100);
|
||||
else
|
||||
strcpy( fontNameSize, bIsWarp4 ? aWarp4Default : aWarp3Default);
|
||||
|
||||
// Parse font description into face and pointage
|
||||
int iPoints = 0;
|
||||
char facename[ 100];
|
||||
if( 2 == sscanf( fontNameSize, "%d.%s", &iPoints, facename))
|
||||
{
|
||||
// XXX This isn't quite `right', but I can't be bothered to go
|
||||
// XXX through the rigamarole of working out precisely what's going
|
||||
// XXX on. Just ensure that the right thing happens when this font
|
||||
// XXX gets passed to nsFontMetricsOS2 or nsWindow.
|
||||
aFont->name = facename;
|
||||
aFont->style = NS_FONT_STYLE_NORMAL;
|
||||
aFont->variant = NS_FONT_VARIANT_NORMAL;
|
||||
aFont->weight = NS_FONT_WEIGHT_NORMAL;
|
||||
aFont->decorations = NS_FONT_DECORATION_NONE;
|
||||
|
||||
// XXX Windows sets the size in points...
|
||||
#if 1
|
||||
aFont->size = iPoints;
|
||||
#else
|
||||
// XXX ..but it should probably be in app units
|
||||
float twip2dev, twip2app;
|
||||
nscoord nsTwips = NSIntPointsToTwips( iPoints);
|
||||
GetDevUnitsToAppUnits( twip2app);
|
||||
GetTwipsToDevUnits( twip2dev);
|
||||
twip2app *= twip2dev;
|
||||
|
||||
aFont->size = NSToCoordFloor( nsTwips * twip2app);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
NS_ASSERTION( 0, "Malformed fontnamesize string");
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::GetSystemAttribute( nsSystemAttrID anID,
|
||||
SystemAttrStruct *aInfo) const
|
||||
{
|
||||
int sysclr = 0, sysval = 0;
|
||||
|
||||
switch( anID)
|
||||
{
|
||||
// Colors
|
||||
// !! Any of these could be wrong...
|
||||
case eSystemAttr_Color_WindowBackground:
|
||||
sysclr = SYSCLR_BACKGROUND;
|
||||
break;
|
||||
case eSystemAttr_Color_WindowForeground:
|
||||
sysclr = SYSCLR_WINDOWTEXT;
|
||||
break;
|
||||
case eSystemAttr_Color_WidgetBackground:
|
||||
sysclr = SYSCLR_BUTTONMIDDLE;
|
||||
break;
|
||||
case eSystemAttr_Color_WidgetForeground:
|
||||
sysclr = SYSCLR_WINDOWTEXT;
|
||||
break;
|
||||
case eSystemAttr_Color_WidgetSelectBackground:
|
||||
sysclr = SYSCLR_HILITEBACKGROUND;
|
||||
break;
|
||||
case eSystemAttr_Color_WidgetSelectForeground:
|
||||
sysclr = SYSCLR_HILITEFOREGROUND;
|
||||
break;
|
||||
case eSystemAttr_Color_Widget3DHighlight:
|
||||
sysclr = SYSCLR_BUTTONLIGHT;
|
||||
break;
|
||||
case eSystemAttr_Color_Widget3DShadow:
|
||||
sysclr = SYSCLR_BUTTONDARK;
|
||||
break;
|
||||
case eSystemAttr_Color_TextBackground:
|
||||
sysclr = SYSCLR_ENTRYFIELD;
|
||||
break;
|
||||
case eSystemAttr_Color_TextForeground:
|
||||
sysclr = SYSCLR_WINDOWTEXT;
|
||||
break;
|
||||
case eSystemAttr_Color_TextSelectBackground:
|
||||
sysclr = SYSCLR_HILITEBACKGROUND;
|
||||
break;
|
||||
case eSystemAttr_Color_TextSelectForeground:
|
||||
sysclr = SYSCLR_HILITEFOREGROUND;
|
||||
break;
|
||||
// Size (these seem to be required in device units)
|
||||
// !! These could well be wrong & need to be arbitrarily changed...
|
||||
case eSystemAttr_Size_WindowTitleHeight:
|
||||
sysval = SV_CYTITLEBAR;
|
||||
break;
|
||||
case eSystemAttr_Size_WindowBorderWidth:
|
||||
sysval = SV_CXSIZEBORDER;
|
||||
break;
|
||||
case eSystemAttr_Size_WindowBorderHeight:
|
||||
sysval = SV_CYSIZEBORDER;
|
||||
break;
|
||||
case eSystemAttr_Size_Widget3DBorder:
|
||||
sysval = SV_CXBORDER;
|
||||
break;
|
||||
case eSystemAttr_Size_ScrollbarHeight:
|
||||
sysval = SV_CYHSCROLL;
|
||||
break;
|
||||
case eSystemAttr_Size_ScrollbarWidth:
|
||||
sysval = SV_CXVSCROLL;
|
||||
break;
|
||||
// Fonts
|
||||
//
|
||||
// !! Again, these are up for grabs & spec-less.
|
||||
// !! If it looks crazy, change it here.
|
||||
//
|
||||
case eSystemAttr_Font_Caption:
|
||||
case eSystemAttr_Font_SmallCaption:
|
||||
FindSystemFont( aInfo->mFont, "WindowTitles",
|
||||
"10.Helv", "9.WarpSans Bold");
|
||||
break;
|
||||
case eSystemAttr_Font_Icon:
|
||||
FindSystemFont( aInfo->mFont, "IconText",
|
||||
"8.Helv", "9.WarpSans");
|
||||
break;
|
||||
case eSystemAttr_Font_Menu:
|
||||
FindSystemFont( aInfo->mFont, "Menus",
|
||||
"10.Helv", "9.WarpSans Bold");
|
||||
break;
|
||||
case eSystemAttr_Font_MessageBox:
|
||||
case eSystemAttr_Font_StatusBar:
|
||||
case eSystemAttr_Font_Tooltips:
|
||||
case eSystemAttr_Font_Widget:
|
||||
FindSystemFont( aInfo->mFont, "WindowText",
|
||||
"8.Helv", "9.Warpsans");
|
||||
break;
|
||||
// don't want to be here
|
||||
default:
|
||||
NS_ASSERTION(0,"Bad eSystemAttr value");
|
||||
break;
|
||||
}
|
||||
|
||||
// Load colour if appropriate
|
||||
if( sysclr != 0)
|
||||
{
|
||||
long lColor = WinQuerySysColor( HWND_DESKTOP, sysclr, 0);
|
||||
|
||||
RGB2 *pRGB2 = (RGB2*) &lColor;
|
||||
|
||||
*(aInfo->mColor) = NS_RGB( pRGB2->bRed, pRGB2->bGreen, pRGB2->bBlue);
|
||||
}
|
||||
else if( sysval != 0)
|
||||
{
|
||||
aInfo->mSize = WinQuerySysValue( HWND_DESKTOP, sysval);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// (XXX) the screen object thinks these are in pels, duh.
|
||||
//
|
||||
nsresult nsDeviceContextOS2::GetDeviceSurfaceDimensions( PRInt32 &aWidth, PRInt32 &aHeight)
|
||||
{
|
||||
aWidth = NSToIntRound( mWidth * mDevUnitsToAppUnits);
|
||||
aHeight = NSToIntRound( mHeight * mDevUnitsToAppUnits);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::GetDepth( PRUint32& aDepth)
|
||||
{
|
||||
aDepth = mDepth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Yuck...
|
||||
nsresult nsDeviceContextOS2::SupportsNativeWidgets( PRBool &aSupportsWidgets)
|
||||
{
|
||||
aSupportsWidgets = (mDC == 0) ? PR_TRUE : PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::GetCanonicalPixelScale( float &aScale) const
|
||||
{
|
||||
aScale = mPixelScale;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Fonts ---------------------------------------------------------------------
|
||||
|
||||
// Rather unfortunate place for this method...
|
||||
nsresult nsDeviceContextOS2::CheckFontExistence( const nsString &aFontName)
|
||||
{
|
||||
HPS hps = GetRepresentativePS();
|
||||
|
||||
char fontName[ FACESIZE];
|
||||
aFontName.ToCString( fontName, FACESIZE);
|
||||
|
||||
long lWant = 0;
|
||||
long lFonts = GpiQueryFonts( hps, QF_PUBLIC | QF_PRIVATE,
|
||||
fontName, &lWant, 0, 0);
|
||||
|
||||
ReleaseRepresentativePS( hps);
|
||||
|
||||
return lFonts > 0 ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Font setup - defaults aren't terribly helpful; this may be no better!
|
||||
nsresult nsDeviceContextOS2::CreateFontAliasTable()
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
if( !mFontAliasTable)
|
||||
{
|
||||
mFontAliasTable = new nsHashtable;
|
||||
|
||||
AliasFont( "Times", "Tms Rmn", "Times New Roman", PR_FALSE);
|
||||
AliasFont( "Times Roman", "Tms Rmn", "Times New Roman", PR_FALSE);
|
||||
AliasFont( "Arial", "Helv", "Helvetica", PR_FALSE);
|
||||
AliasFont( "Helvetica", "Helv", "Arial", PR_FALSE);
|
||||
AliasFont( "Courier", "Courier New", "", PR_FALSE); // why does base force this alias?
|
||||
AliasFont( "Courier New", "Courier", "", PR_FALSE);
|
||||
AliasFont( "Sans", "Helv", "Arial", PR_FALSE);
|
||||
// Is this right?
|
||||
AliasFont( "Unicode", "Times New Roman MT 30", "", PR_FALSE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Colourspaces and palettes -------------------------------------------------
|
||||
|
||||
// Override these so we can use palette manager
|
||||
nsresult nsDeviceContextOS2::GetILColorSpace( IL_ColorSpace *&aColorSpace)
|
||||
{
|
||||
if( !mColorSpace)
|
||||
{
|
||||
// !! Might want to do something funky for 4bpp displays
|
||||
|
||||
// See if we're dealing with an 8-bit palette device
|
||||
if( (8 == mDepth) && mPaletteInfo.isPaletteDevice)
|
||||
{
|
||||
IL_ColorMap *cMap = IL_NewCubeColorMap( 0, 0, COLOR_CUBE_SIZE);
|
||||
if( !cMap)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Create a pseudo color space
|
||||
mColorSpace = IL_CreatePseudoColorSpace( cMap, 8, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
IL_RGBBits colorRGBBits;
|
||||
|
||||
// Create a 24-bit color space
|
||||
colorRGBBits.red_shift = 16;
|
||||
colorRGBBits.red_bits = 8;
|
||||
colorRGBBits.green_shift = 8;
|
||||
colorRGBBits.green_bits = 8;
|
||||
colorRGBBits.blue_shift = 0;
|
||||
colorRGBBits.blue_bits = 8;
|
||||
|
||||
mColorSpace = IL_CreateTrueColorSpace(&colorRGBBits, 24);
|
||||
}
|
||||
|
||||
if( !mColorSpace)
|
||||
{
|
||||
aColorSpace = nsnull;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the color space
|
||||
aColorSpace = mColorSpace;
|
||||
IL_AddRefToColorSpace( aColorSpace);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::GetPaletteInfo( nsPaletteInfo& aPaletteInfo)
|
||||
{
|
||||
aPaletteInfo.isPaletteDevice = mPaletteInfo.isPaletteDevice;
|
||||
aPaletteInfo.sizePalette = mPaletteInfo.sizePalette;
|
||||
aPaletteInfo.numReserved = mPaletteInfo.numReserved;
|
||||
|
||||
nsresult rc = NS_OK;
|
||||
|
||||
SetupColorMaps();
|
||||
|
||||
aPaletteInfo.palette = mPaletteInfo.palette;
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::GetPalette( nsIPaletteOS2 *&aPalette)
|
||||
{
|
||||
nsresult rc = SetupColorMaps();
|
||||
aPalette = mPalette;
|
||||
NS_ADDREF( aPalette);
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::SetupColorMaps()
|
||||
{
|
||||
nsresult rc = NS_OK;
|
||||
if( !mPalette)
|
||||
{
|
||||
// Share a single palette between all screen instances; printers need
|
||||
// a separate palette for compatability reasons.
|
||||
if( mDC) rc = NS_CreatePalette( this, mPalette);
|
||||
else mPalette = gModuleData.GetUIPalette( this);
|
||||
|
||||
if( rc == NS_OK)
|
||||
rc = mPalette->GetNSPalette( mPaletteInfo.palette);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDeviceContextOS2::ConvertPixel(nscolor aColor, PRUint32 & aPixel)
|
||||
{
|
||||
printf( "Alert: nsDeviceContext::ConvertPixel called\n");
|
||||
aPixel = aColor;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Printing ------------------------------------------------------------------
|
||||
nsresult nsDeviceContextOS2::BeginDocument()
|
||||
{
|
||||
NS_ASSERTION(mDC, "BeginDocument for non-print DC");
|
||||
if( mPrintState == nsPrintState_ePreBeginDoc)
|
||||
{
|
||||
PrnStartJob( mDC, "Warpzilla NGLayout job");
|
||||
printf( "BeginDoc\n");
|
||||
mPrintState = nsPrintState_eBegunDoc;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::EndDocument()
|
||||
{
|
||||
PrnEndJob( mDC);
|
||||
mPrintState = nsPrintState_ePreBeginDoc;
|
||||
printf("EndDoc\n");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::BeginPage()
|
||||
{
|
||||
if( mPrintState == nsPrintState_eBegunDoc)
|
||||
mPrintState = nsPrintState_eBegunFirstPage;
|
||||
else
|
||||
{
|
||||
PrnNewPage( mDC);
|
||||
printf("NewPage");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextOS2::EndPage()
|
||||
{
|
||||
/* nop */
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsDeviceContextOS2_h
|
||||
#define _nsDeviceContextOS2_h
|
||||
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsRenderingContextOS2.h"
|
||||
|
||||
// Device contexts are either for windows or for printers.
|
||||
// If the former, the DeviceContextImpl member mWidget is set.
|
||||
// If the latter, the mDC member here is set.
|
||||
// (yes, I know: eventually want to split these guys up)
|
||||
|
||||
class nsIPaletteOS2;
|
||||
class nsDrawingSurfaceOS2;
|
||||
|
||||
class nsDeviceContextOS2 : public DeviceContextImpl
|
||||
{
|
||||
public:
|
||||
nsDeviceContextOS2();
|
||||
|
||||
NS_IMETHOD Init( nsNativeWidget aWidget);
|
||||
|
||||
// what a bizarre method. These floats are app units.
|
||||
NS_IMETHOD GetScrollBarDimensions( float &aWidth, float &aHeight) const;
|
||||
|
||||
NS_IMETHOD GetSystemAttribute( nsSystemAttrID anID, SystemAttrStruct *aInfo) const;
|
||||
|
||||
// get a low level drawing surface for rendering. the rendering context
|
||||
// that is passed in is used to create the drawing surface if there isn't
|
||||
// already one in the device context. the drawing surface is then cached
|
||||
// in the device context for re-use.
|
||||
NS_IMETHOD GetDrawingSurface( nsIRenderingContext &aContext,
|
||||
nsDrawingSurface &aSurface);
|
||||
NS_IMETHOD CheckFontExistence( const nsString &aFontName);
|
||||
NS_IMETHOD GetDepth( PRUint32 &aDepth);
|
||||
NS_IMETHOD GetILColorSpace( IL_ColorSpace*& aColorSpace);
|
||||
NS_IMETHOD GetPaletteInfo( nsPaletteInfo &);
|
||||
NS_IMETHOD ConvertPixel( nscolor aColor, PRUint32 & aPixel);
|
||||
NS_IMETHOD GetDeviceSurfaceDimensions( PRInt32 &aWidth, PRInt32 &aHeight);
|
||||
NS_IMETHOD SupportsNativeWidgets( PRBool &aSupportsWidgets);
|
||||
NS_IMETHOD GetCanonicalPixelScale( float &aScale) const;
|
||||
NS_IMETHOD GetDeviceContextFor( nsIDeviceContextSpec *aDevice,
|
||||
nsIDeviceContext *&aContext);
|
||||
NS_IMETHOD CreateRenderingContext( nsIRenderingContext *&aContext);
|
||||
NS_IMETHOD BeginDocument();
|
||||
NS_IMETHOD EndDocument();
|
||||
NS_IMETHOD BeginPage();
|
||||
NS_IMETHOD EndPage();
|
||||
|
||||
// OS2 specific methods
|
||||
public:
|
||||
// Call to ensure colour table/palette is loaded and ready.
|
||||
nsresult SetupColorMaps();
|
||||
// Get the palette object for the device, used to pick colours.
|
||||
// Release when done.
|
||||
nsresult GetPalette( nsIPaletteOS2 *&apalette);
|
||||
// Init from a HDC for printing purposes
|
||||
nsresult Init( nsNativeDeviceContext aContext,
|
||||
nsIDeviceContext *aOrigContext);
|
||||
void CommonInit( HDC aDC);
|
||||
|
||||
// Needed by the fontmetrics - can't rely on having a widget.
|
||||
HPS GetRepresentativePS() const;
|
||||
void ReleaseRepresentativePS( HPS aPS);
|
||||
|
||||
protected:
|
||||
virtual ~nsDeviceContextOS2();
|
||||
|
||||
virtual nsresult CreateFontAliasTable();
|
||||
|
||||
nsDrawingSurfaceOS2 *mSurface;
|
||||
PRUint32 mDepth; // bit depth of device
|
||||
nsPaletteInfo mPaletteInfo;
|
||||
nsIPaletteOS2 *mPalette;
|
||||
float mPixelScale;
|
||||
PRInt32 mWidth;
|
||||
PRInt32 mHeight;
|
||||
HDC mDC; // PrintDC. Owned by libprint.
|
||||
HPS mPS; // PrintPS.
|
||||
enum nsPrintState
|
||||
{
|
||||
nsPrintState_ePreBeginDoc,
|
||||
nsPrintState_eBegunDoc,
|
||||
nsPrintState_eBegunFirstPage,
|
||||
nsPrintState_eEndedDoc
|
||||
} mPrintState;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// This class is part of the strange printing `architecture'.
|
||||
// The `CreateDeviceContextSpec' method basically selects a print queue,
|
||||
// known here as an `nsIDeviceContextSpec'. This is given to a method
|
||||
// in nsIDeviceContext which creates a fresh device context for that
|
||||
// printer.
|
||||
|
||||
#include "nsGfxDefs.h"
|
||||
#include "libprint.h"
|
||||
|
||||
#include "nsDeviceContextSpecFactoryO.h"
|
||||
#include "nsDeviceContextSpecOS2.h"
|
||||
#include "nsRegionOS2.h"
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
nsDeviceContextSpecFactoryOS2::nsDeviceContextSpecFactoryOS2()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsDeviceContextSpecFactoryOS2, nsIDeviceContextSpecFactory::GetIID())
|
||||
|
||||
NS_IMETHODIMP nsDeviceContextSpecFactoryOS2::Init()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDeviceContextSpecFactoryOS2::CreateDeviceContextSpec(
|
||||
nsIDeviceContextSpec *aOldSpec,
|
||||
nsIDeviceContextSpec *&aNewSpec,
|
||||
PRBool aQuiet)
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
// This currently ignores aOldSpec. This may be of no consequence...
|
||||
PRTQUEUE *pq = PrnSelectPrinter( HWND_DESKTOP, aQuiet ? TRUE : FALSE);
|
||||
|
||||
if( pq)
|
||||
{
|
||||
nsDeviceContextSpecOS2 *spec = new nsDeviceContextSpecOS2;
|
||||
NS_ADDREF(spec);
|
||||
spec->Init( pq);
|
||||
aNewSpec = spec;
|
||||
rc = NS_OK;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// This class is part of the strange printing `architecture'.
|
||||
// The `CreateDeviceContextSpec' method basically selects a print queue,
|
||||
// known here as an `nsIDeviceContextSpec'. This is given to a method
|
||||
// in nsIDeviceContext which creates a fresh device context for that
|
||||
// printer.
|
||||
|
||||
#ifndef _nsDeviceContextSpecFactoryOS2_h
|
||||
#define _nsDeviceContextSpecFactoryOS2_h
|
||||
|
||||
#include "nsIDeviceContextSpecFactory.h"
|
||||
#include "nsIDeviceContextSpec.h"
|
||||
|
||||
class nsDeviceContextSpecFactoryOS2 : public nsIDeviceContextSpecFactory
|
||||
{
|
||||
public:
|
||||
nsDeviceContextSpecFactoryOS2();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init();
|
||||
NS_IMETHOD CreateDeviceContextSpec( nsIDeviceContextSpec *aOldSpec,
|
||||
nsIDeviceContextSpec *&aNewSpec,
|
||||
PRBool aQuiet);
|
||||
protected:
|
||||
virtual ~nsDeviceContextSpecFactoryOS2() {}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsGfxDefs.h"
|
||||
#include "libprint.h"
|
||||
|
||||
#include "nsDeviceContextSpecOS2.h"
|
||||
|
||||
nsDeviceContextSpecOS2::nsDeviceContextSpecOS2()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mQueue = nsnull;
|
||||
}
|
||||
|
||||
nsDeviceContextSpecOS2::~nsDeviceContextSpecOS2()
|
||||
{
|
||||
if( mQueue)
|
||||
PrnClosePrinter( mQueue);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsDeviceContextSpecOS2, nsIDeviceContextSpec::GetIID())
|
||||
|
||||
nsresult nsDeviceContextSpecOS2::Init( PRTQUEUE *pq)
|
||||
{
|
||||
mQueue = pq;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextSpecOS2::GetPRTQUEUE( PRTQUEUE *&p)
|
||||
{
|
||||
p = mQueue;
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsDeviceContextSpecOS2_h
|
||||
#define _nsDeviceContextSpecOS2_h
|
||||
|
||||
#include "nsIDeviceContextSpec.h"
|
||||
|
||||
class nsDeviceContextSpecOS2 : public nsIDeviceContextSpec
|
||||
{
|
||||
public:
|
||||
nsDeviceContextSpecOS2();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init( PRTQUEUE *pq);
|
||||
NS_IMETHOD GetPRTQUEUE( PRTQUEUE *&p);
|
||||
|
||||
protected:
|
||||
virtual ~nsDeviceContextSpecOS2();
|
||||
|
||||
PRTQUEUE *mQueue;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,556 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsGfxDefs.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsDrawingSurfaceOS2.h"
|
||||
#include "nsFontMetricsOS2.h"
|
||||
#include "nsPaletteOS2.h"
|
||||
|
||||
// Base class -- fonts, palette and xpcom -----------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsDrawingSurfaceOS2,nsIDrawingSurface::GetIID())
|
||||
|
||||
// We start allocated lCIDs at 2. This leaves #1 for nsFontMetricsOS2 to
|
||||
// do testing with, and 0 is, of course, LCID_DEFAULT.
|
||||
|
||||
nsDrawingSurfaceOS2::nsDrawingSurfaceOS2()
|
||||
: mNextID(2), mTopID(1), mPalette(0), mPS(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mHTFonts = new nsHashtable;
|
||||
}
|
||||
|
||||
nsDrawingSurfaceOS2::~nsDrawingSurfaceOS2()
|
||||
{
|
||||
// release palette; no harm if it's already been done by a subclass
|
||||
DeselectPalette();
|
||||
DisposeFonts();
|
||||
}
|
||||
|
||||
void nsDrawingSurfaceOS2::DisposeFonts()
|
||||
{
|
||||
if( mHTFonts)
|
||||
{
|
||||
// free font things
|
||||
GpiSetCharSet( mPS, LCID_DEFAULT);
|
||||
for( int i = 2; i <= mTopID; i++)
|
||||
{
|
||||
if( !GpiDeleteSetId( mPS, i))
|
||||
PMERROR( "GpiDeleteSetId");
|
||||
}
|
||||
delete mHTFonts;
|
||||
mHTFonts = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Key for the hashtable
|
||||
typedef nsVoidKey FontHandleKey;
|
||||
|
||||
void nsDrawingSurfaceOS2::SelectFont( nsIFontMetrics *metrics)
|
||||
{
|
||||
nsFontHandle fh = nsnull;
|
||||
metrics->GetFontHandle( fh);
|
||||
|
||||
nsFontHandleOS2 *pHandle = (nsFontHandleOS2 *) fh;
|
||||
FontHandleKey key( pHandle);
|
||||
|
||||
if( !mHTFonts->Get( &key))
|
||||
{
|
||||
if( mNextID == 255)
|
||||
// ids used up, need to empty table and start again.
|
||||
FlushFontCache();
|
||||
|
||||
GpiCreateLogFont( mPS, 0, mNextID, &pHandle->fattrs);
|
||||
mHTFonts->Put( &key, (void *) mNextID);
|
||||
mNextID++;
|
||||
if( mTopID < 254)
|
||||
mTopID++;
|
||||
}
|
||||
|
||||
long lcid = (long) mHTFonts->Get( &key);
|
||||
pHandle->SelectIntoPS( mPS, lcid);
|
||||
}
|
||||
|
||||
void nsDrawingSurfaceOS2::FlushFontCache()
|
||||
{
|
||||
mHTFonts->Reset();
|
||||
mNextID = 2;
|
||||
// leave mTopID where it is.
|
||||
}
|
||||
|
||||
// Palette
|
||||
void nsDrawingSurfaceOS2::SetPalette( nsIPaletteOS2 *aPalette)
|
||||
{
|
||||
NS_IF_RELEASE(mPalette);
|
||||
mPalette = aPalette;
|
||||
NS_ADDREF(mPalette);
|
||||
}
|
||||
|
||||
void nsDrawingSurfaceOS2::DeselectPalette()
|
||||
{
|
||||
if( mPalette)
|
||||
{
|
||||
mPalette->Deselect( mPS);
|
||||
NS_RELEASE(mPalette); // this nulls out mPalette
|
||||
}
|
||||
}
|
||||
|
||||
// yuck.
|
||||
nsresult nsDrawingSurfaceOS2::GetBitmap( HBITMAP &aBitmap)
|
||||
{
|
||||
aBitmap = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDrawingSurfaceOS2::RequiresInvertedMask( PRBool *aBool)
|
||||
{
|
||||
*aBool = (PRBool) (gModuleData.lDisplayDepth <= 8);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Offscreen surface --------------------------------------------------------
|
||||
|
||||
nsOffscreenSurface::nsOffscreenSurface() : mDC(0), mBitmap(0),
|
||||
mHeight(0), mWidth(0),
|
||||
mInfoHeader(0), mBits(0),
|
||||
mYPels(0), mScans(0)
|
||||
{}
|
||||
|
||||
// Setup a new offscreen surface which is to be compatible with the
|
||||
// passed-in presentation space.
|
||||
nsresult nsOffscreenSurface::Init( HPS aCompatiblePS,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
// Find the compatible device context and create a memory one
|
||||
HDC hdcCompat = GpiQueryDevice( aCompatiblePS);
|
||||
DEVOPENSTRUC dop = { 0, 0, 0, 0, 0 };
|
||||
mDC = DevOpenDC( 0/*hab*/, OD_MEMORY, "*", 5,
|
||||
(PDEVOPENDATA) &dop, hdcCompat);
|
||||
|
||||
if( DEV_ERROR != mDC)
|
||||
{
|
||||
// create the PS
|
||||
SIZEL sizel = { 0, 0 };
|
||||
mPS = GpiCreatePS( 0/*hab*/, mDC, &sizel,
|
||||
PU_PELS | GPIT_MICRO | GPIA_ASSOC);
|
||||
|
||||
if( GPI_ERROR != mPS)
|
||||
{
|
||||
// now create a bitmap of the right size
|
||||
BITMAPINFOHEADER2 hdr = { 0 };
|
||||
|
||||
hdr.cbFix = sizeof( BITMAPINFOHEADER2);
|
||||
hdr.cx = aWidth;
|
||||
hdr.cy = aHeight;
|
||||
hdr.cPlanes = 1;
|
||||
|
||||
// find bitdepth
|
||||
LONG lBitCount = 0;
|
||||
DevQueryCaps( hdcCompat, CAPS_COLOR_BITCOUNT, 1, &lBitCount);
|
||||
hdr.cBitCount = (USHORT) lBitCount;
|
||||
|
||||
mBitmap = GpiCreateBitmap( mPS, &hdr, 0, 0, 0);
|
||||
|
||||
if( GPI_ERROR != mBitmap)
|
||||
{
|
||||
// set final stats & select bitmap into ps
|
||||
mHeight = aHeight;
|
||||
mWidth = aWidth;
|
||||
GpiSetBitmap( mPS, mBitmap);
|
||||
rc = NS_OK;
|
||||
}
|
||||
else
|
||||
PMERROR( "GpiCreateBitmap");
|
||||
}
|
||||
else
|
||||
PMERROR( "GpiCreatePS");
|
||||
}
|
||||
else
|
||||
PMERROR( "DevOpenDC");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsOffscreenSurface::~nsOffscreenSurface()
|
||||
{
|
||||
if( mPS)
|
||||
{
|
||||
DisposeFonts();
|
||||
if( HBM_ERROR == GpiSetBitmap( mPS, 0))
|
||||
PMERROR( "GpiSetBitmap");
|
||||
if( !GpiDeleteBitmap( mBitmap))
|
||||
PMERROR( "GpiDeleteBitmap");
|
||||
DeselectPalette();
|
||||
//
|
||||
// Don't need to do this because the PS is a micro-one.
|
||||
//
|
||||
// if( !GpiAssociate( mPS, 0))
|
||||
// PMERROR( "GpiAssociate");
|
||||
//
|
||||
if( !GpiDestroyPS( mPS))
|
||||
PMERROR( "GpiDestroyPS");
|
||||
if( DEV_ERROR == DevCloseDC( mDC))
|
||||
PMERROR( "DevCloseDC");
|
||||
mPS = 0;
|
||||
}
|
||||
if( mInfoHeader)
|
||||
free( mInfoHeader);
|
||||
delete [] mBits;
|
||||
}
|
||||
|
||||
nsresult nsOffscreenSurface::GetBitmap( HBITMAP &aBitmap)
|
||||
{
|
||||
aBitmap = mBitmap;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Okay; plan here is to get the bits and hope that the fact that we're
|
||||
// returning an upside-down rectangle doesn't matter.
|
||||
//
|
||||
// If it does, then the following needs to be done:
|
||||
//
|
||||
// * undefine the USD flag in libimg
|
||||
// * alter the draw code in nsImageOS2 to draw right-way-up
|
||||
// * fix the printing case (probably involving an ugly xform)
|
||||
//
|
||||
nsresult nsOffscreenSurface::Lock( PRInt32 aX, PRInt32 aY,
|
||||
PRUint32 aWidth, PRUint32 aHeight,
|
||||
void **aBits, PRInt32 *aStride,
|
||||
PRInt32 *aWidthBytes,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
// Trust other platforms to ensure that we don't get nested!
|
||||
PRInt32 lStride = 0;
|
||||
ULONG rc = 0;
|
||||
|
||||
// Allocate buffers first time we get called.
|
||||
//
|
||||
// Need to look at the way in which this functionality is exercised:
|
||||
// may actually be more efficient to only grab the section of bitmap
|
||||
// required on each call, and to free up memory afterwards.
|
||||
//
|
||||
// Currently: * allocate once enough space for the entire bitmap
|
||||
// * only grab & set the required scanlines
|
||||
//
|
||||
if( !mBits)
|
||||
{
|
||||
BITMAPINFOHEADER bih = { sizeof( BITMAPINFOHEADER), 0, 0, 0, 0 };
|
||||
|
||||
rc = GpiQueryBitmapInfoHeader( mBitmap, (PBITMAPINFOHEADER2) &bih);
|
||||
if( !rc) PMERROR( "GpiQueryInfoHeader");
|
||||
|
||||
// alloc space to query pel data into...
|
||||
lStride = RASWIDTH( bih.cx, bih.cBitCount);
|
||||
mBits = new PRUint8 [ lStride * bih.cy ];
|
||||
|
||||
// ..and colour table too
|
||||
int cols = -1;
|
||||
if( bih.cBitCount >= 24) cols = 0;
|
||||
else cols = 1 << bih.cBitCount;
|
||||
|
||||
int szStruct = sizeof( BITMAPINFOHEADER2) + cols * sizeof( RGB2);
|
||||
|
||||
mInfoHeader = (PBITMAPINFOHEADER2) calloc( szStruct, 1);
|
||||
mInfoHeader->cbFix = sizeof( BITMAPINFOHEADER2);
|
||||
mInfoHeader->cx = bih.cx;
|
||||
mInfoHeader->cy = bih.cy;
|
||||
mInfoHeader->cPlanes = 1;
|
||||
mInfoHeader->cBitCount = (USHORT) bih.cBitCount;
|
||||
// GPI-Ref says these have to be set too...
|
||||
mInfoHeader->ulCompression = BCA_UNCOMP;
|
||||
mInfoHeader->usRecording = BRA_BOTTOMUP;
|
||||
mInfoHeader->usRendering = BRH_NOTHALFTONED; // ...hmm...
|
||||
mInfoHeader->ulColorEncoding = BCE_RGB;
|
||||
}
|
||||
else
|
||||
lStride = RASWIDTH( mInfoHeader->cx, mInfoHeader->cBitCount);
|
||||
|
||||
// record starting scanline (bottom is 0)
|
||||
mYPels = mInfoHeader->cy - aY - aHeight;
|
||||
mScans = aHeight;
|
||||
|
||||
rc = GpiQueryBitmapBits( mPS, mYPels, mScans, (char*) mBits,
|
||||
(PBITMAPINFO2) mInfoHeader);
|
||||
if( rc != mInfoHeader->cy) PMERROR( "GpiQueryBitmapBits");
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "Lock, requested %d x %d and got %d x %d\n",
|
||||
aWidth, aHeight, (int) mInfoHeader->cx, aHeight);
|
||||
#endif
|
||||
|
||||
// Okay. Now have current state of bitmap in mBits.
|
||||
*aStride = lStride;
|
||||
*aBits = (void*) (mBits + (aX * (mInfoHeader->cBitCount >> 3)));
|
||||
*aWidthBytes = aWidth * (mInfoHeader->cBitCount >> 3);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsOffscreenSurface::Unlock()
|
||||
{
|
||||
long rc = GpiSetBitmapBits( mPS, mYPels, mScans, (char*) mBits,
|
||||
(PBITMAPINFO2) mInfoHeader);
|
||||
if( rc == GPI_ALTERROR) PMERROR( "GpiSetBitmapBits");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsOffscreenSurface::GetDimensions( PRUint32 *aWidth, PRUint32 *aHeight)
|
||||
{
|
||||
if( !aWidth || !aHeight)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aWidth = mWidth;
|
||||
*aHeight = mHeight;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsOffscreenSurface::IsOffscreen( PRBool *aOffScreen)
|
||||
{
|
||||
if( !aOffScreen)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aOffScreen = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsOffscreenSurface::IsPixelAddressable( PRBool *aAddressable)
|
||||
{
|
||||
if( !aAddressable)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aAddressable = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsOffscreenSurface::GetPixelFormat( nsPixelFormat *aFormat)
|
||||
{
|
||||
if( !aFormat)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Okay. Who knows what's going on here - we (as wz) currently support
|
||||
// only 8 and 24 bpp bitmaps; dunno what should be done for 32 bpp,
|
||||
// even if os/2 supports them.
|
||||
//
|
||||
// (prob'ly need to get the FOURCC stuff into the act for 16bpp?)
|
||||
//
|
||||
BITMAPINFOHEADER bih = { sizeof( BITMAPINFOHEADER), 0, 0, 0, 0 };
|
||||
long rc = GpiQueryBitmapInfoHeader( mBitmap, (PBITMAPINFOHEADER2) &bih);
|
||||
|
||||
switch( bih.cBitCount)
|
||||
{
|
||||
case 8:
|
||||
memset( aFormat, 0, sizeof(nsPixelFormat));
|
||||
break;
|
||||
|
||||
case 24:
|
||||
aFormat->mRedZeroMask = 0xff;
|
||||
aFormat->mGreenZeroMask = 0xff;
|
||||
aFormat->mBlueZeroMask = 0xff;
|
||||
aFormat->mAlphaZeroMask = 0;
|
||||
aFormat->mRedMask = 0xff;
|
||||
aFormat->mGreenMask = 0xff00;
|
||||
aFormat->mBlueMask = 0xff0000;
|
||||
aFormat->mAlphaMask = 0;
|
||||
aFormat->mRedCount = 8;
|
||||
aFormat->mGreenCount = 8;
|
||||
aFormat->mBlueCount = 8;
|
||||
aFormat->mAlphaCount = 0;
|
||||
aFormat->mRedShift = 0;
|
||||
aFormat->mGreenShift = 8;
|
||||
aFormat->mBlueShift = 16;
|
||||
aFormat->mAlphaShift = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf( "Bad bit-depth for GetPixelFormat (%d)\n", bih.cBitCount);
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Non-offscreen surfaces, base for window & print --------------------------
|
||||
nsOnscreenSurface::nsOnscreenSurface() : mProxySurface(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
nsOnscreenSurface::~nsOnscreenSurface()
|
||||
{
|
||||
NS_IF_RELEASE(mProxySurface);
|
||||
}
|
||||
|
||||
void nsOnscreenSurface::EnsureProxy()
|
||||
{
|
||||
if( !mProxySurface)
|
||||
{
|
||||
PRUint32 width, height;
|
||||
GetDimensions( &width, &height);
|
||||
|
||||
mProxySurface = new nsOffscreenSurface;
|
||||
if( NS_SUCCEEDED(mProxySurface->Init( mPS, width, height)))
|
||||
{
|
||||
NS_ADDREF(mProxySurface);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete mProxySurface;
|
||||
mProxySurface = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsOnscreenSurface::Lock( PRInt32 aX, PRInt32 aY,
|
||||
PRUint32 aWidth, PRUint32 aHeight,
|
||||
void **aBits, PRInt32 *aStride,
|
||||
PRInt32 *aWidthBytes,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
EnsureProxy();
|
||||
|
||||
printf( "Locking through a proxy\n");
|
||||
|
||||
// blit our 'real' bitmap to the proxy surface
|
||||
PRUint32 width, height;
|
||||
GetDimensions( &width, &height);
|
||||
POINTL pts[3] = { { 0, 0 }, { width, height }, { 0, 0 } };
|
||||
long lHits = GpiBitBlt( mProxySurface->mPS, mPS, 3, pts,
|
||||
ROP_SRCCOPY, BBO_OR);
|
||||
if( GPI_ERROR == lHits) PMERROR( "GpiBitBlt/DSL");
|
||||
|
||||
return mProxySurface->Lock( aX, aY, aWidth, aHeight,
|
||||
aBits, aStride, aWidthBytes, aFlags);
|
||||
}
|
||||
|
||||
nsresult nsOnscreenSurface::Unlock()
|
||||
{
|
||||
nsresult rc = mProxySurface->Unlock();
|
||||
|
||||
// blit proxy bitmap back to ours
|
||||
PRUint32 width, height;
|
||||
GetDimensions( &width, &height);
|
||||
POINTL pts[3] = { { 0, 0 }, { width, height }, { 0, 0 } };
|
||||
long lHits = GpiBitBlt( mPS, mProxySurface->mPS, 3, pts,
|
||||
ROP_SRCCOPY, BBO_OR);
|
||||
if( GPI_ERROR == lHits) PMERROR( "GpiBitBlt/DSUL");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsOnscreenSurface::GetPixelFormat( nsPixelFormat *aFormat)
|
||||
{
|
||||
EnsureProxy();
|
||||
return mProxySurface->GetPixelFormat( aFormat);
|
||||
}
|
||||
|
||||
nsresult nsOnscreenSurface::IsOffscreen( PRBool *aOffScreen)
|
||||
{
|
||||
if( !aOffScreen)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aOffScreen = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsOnscreenSurface::IsPixelAddressable( PRBool *aAddressable)
|
||||
{
|
||||
if( !aAddressable)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aAddressable = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Surface for a PM window --------------------------------------------------
|
||||
nsWindowSurface::nsWindowSurface() : mWidget(nsnull)
|
||||
{}
|
||||
|
||||
nsWindowSurface::~nsWindowSurface()
|
||||
{
|
||||
// palette will be deselected in superclass dtor
|
||||
|
||||
// need to do this now because hps is invalid after subsequent free
|
||||
DisposeFonts();
|
||||
// release hps
|
||||
mWidget->FreeNativeData( (void*) mPS, NS_NATIVE_GRAPHIC);
|
||||
mPS = 0; // just for safety
|
||||
}
|
||||
|
||||
nsresult nsWindowSurface::Init( nsIWidget *aOwner)
|
||||
{
|
||||
mWidget = aOwner;
|
||||
mPS = (HPS) mWidget->GetNativeData( NS_NATIVE_GRAPHIC);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsWindowSurface::GetDimensions( PRUint32 *aWidth, PRUint32 *aHeight)
|
||||
{
|
||||
// I don't think we can be more efficient than this, except perhaps by
|
||||
// doing some kind of `push' of height from the window to us.
|
||||
nsRect rect;
|
||||
mWidget->GetClientBounds( rect);
|
||||
*aHeight = rect.height;
|
||||
*aWidth = rect.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Printer surface. A few minor differences, like the page size is fixed ---
|
||||
nsPrintSurface::nsPrintSurface() : mHeight(0), mWidth(0)
|
||||
{}
|
||||
|
||||
nsresult nsPrintSurface::Init( HPS aPS, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
mPS = aPS;
|
||||
mHeight = aHeight;
|
||||
mWidth = aWidth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsPrintSurface::~nsPrintSurface()
|
||||
{
|
||||
// PS is owned by the DC; superclass dtor will deselect palette.
|
||||
}
|
||||
|
||||
nsresult nsPrintSurface::GetDimensions( PRUint32 *aWidth, PRUint32 *aHeight)
|
||||
{
|
||||
if( !aWidth || !aHeight)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aWidth = mWidth;
|
||||
*aHeight = mHeight;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPrintSurface::RequiresInvertedMask( PRBool *aBool)
|
||||
{
|
||||
*aBool = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsDrawingSurfaceOS2_h
|
||||
#define _nsDrawingSurfaceOS2_h
|
||||
|
||||
#include "nsIDrawingSurface.h"
|
||||
|
||||
class nsHashtable;
|
||||
class nsIWidget;
|
||||
class nsIPaletteOS2;
|
||||
|
||||
// These were called `drawables' in os2fe.
|
||||
//
|
||||
// Note that each surface has a ref to the palette of the device context
|
||||
// from which it was spun off. This is because drawing surfaces have
|
||||
// lifetimes which extend further than the rendering context which
|
||||
// created them. The creating object must select the palette into the
|
||||
// surface's presentation space; all the drawing surface does is deselect
|
||||
// the palette when it's dying.
|
||||
//
|
||||
// This is rather unwieldy...
|
||||
//
|
||||
// Note: |nsDrawingSurface| == (void*)(nsDrawingSurfaceOS2*)surf
|
||||
|
||||
class nsDrawingSurfaceOS2 : public nsIDrawingSurface
|
||||
{
|
||||
nsHashtable *mHTFonts; // cache of fonthandle to lcid
|
||||
long mNextID; // next lcid to allocate
|
||||
long mTopID; // highest used lcid
|
||||
nsIPaletteOS2 *mPalette; // palette
|
||||
|
||||
protected:
|
||||
void DeselectPalette();
|
||||
void DisposeFonts(); // MUST be called before disposing of PS
|
||||
|
||||
public:
|
||||
nsDrawingSurfaceOS2();
|
||||
virtual ~nsDrawingSurfaceOS2();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIDrawingSurface actually implemented in subclasses
|
||||
|
||||
HPS mPS; // presentation space for this surface
|
||||
|
||||
void SelectFont( nsIFontMetrics *metrics);
|
||||
void FlushFontCache();
|
||||
|
||||
void SetPalette( nsIPaletteOS2 *aPalette);
|
||||
|
||||
NS_IMETHOD GetBitmap( HBITMAP &aBitmap); // yuck (for blender, may go)
|
||||
NS_IMETHOD RequiresInvertedMask( PRBool *aBool); // double yuck (images)
|
||||
};
|
||||
|
||||
// Offscreen surface. Others depend on this.
|
||||
class nsOffscreenSurface : public nsDrawingSurfaceOS2
|
||||
{
|
||||
HDC mDC;
|
||||
HBITMAP mBitmap;
|
||||
PRInt32 mHeight;
|
||||
PRInt32 mWidth;
|
||||
|
||||
PBITMAPINFOHEADER2 mInfoHeader;
|
||||
PRUint8 *mBits;
|
||||
|
||||
PRInt32 mYPels;
|
||||
PRUint32 mScans;
|
||||
|
||||
public:
|
||||
nsOffscreenSurface();
|
||||
virtual ~nsOffscreenSurface();
|
||||
|
||||
// os/2 methods
|
||||
NS_IMETHOD Init( HPS aCompatiblePS, PRInt32 aWidth, PRInt32 aHeight);
|
||||
NS_IMETHOD GetBitmap( HBITMAP &aBitmap);
|
||||
|
||||
// nsIDrawingSurface methods
|
||||
NS_IMETHOD Lock( PRInt32 aX, PRInt32 aY, PRUint32 aWidth, PRUint32 aHeight,
|
||||
void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes,
|
||||
PRUint32 aFlags);
|
||||
NS_IMETHOD Unlock();
|
||||
NS_IMETHOD GetDimensions( PRUint32 *aWidth, PRUint32 *aHeight);
|
||||
NS_IMETHOD IsOffscreen( PRBool *aOffScreen);
|
||||
NS_IMETHOD IsPixelAddressable( PRBool *aAddressable);
|
||||
NS_IMETHOD GetPixelFormat( nsPixelFormat *aFormat);
|
||||
};
|
||||
|
||||
// Onscreen surface - uses an offscreen to implement bitlevel access
|
||||
class nsOnscreenSurface : public nsDrawingSurfaceOS2
|
||||
{
|
||||
nsOffscreenSurface *mProxySurface;
|
||||
void EnsureProxy();
|
||||
|
||||
public:
|
||||
nsOnscreenSurface();
|
||||
virtual ~nsOnscreenSurface();
|
||||
|
||||
// nsIDrawingSurface methods
|
||||
NS_IMETHOD Lock( PRInt32 aX, PRInt32 aY, PRUint32 aWidth, PRUint32 aHeight,
|
||||
void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes,
|
||||
PRUint32 aFlags);
|
||||
NS_IMETHOD Unlock();
|
||||
NS_IMETHOD IsOffscreen( PRBool *aOffScreen);
|
||||
NS_IMETHOD IsPixelAddressable( PRBool *aAddressable);
|
||||
NS_IMETHOD GetPixelFormat( nsPixelFormat *aFormat);
|
||||
};
|
||||
|
||||
// Surface for an onscreen window
|
||||
class nsWindowSurface : public nsOnscreenSurface
|
||||
{
|
||||
nsIWidget *mWidget; // window who owns the surface
|
||||
|
||||
public:
|
||||
nsWindowSurface();
|
||||
virtual ~nsWindowSurface();
|
||||
|
||||
NS_IMETHOD Init( nsIWidget *aOwner);
|
||||
NS_IMETHOD GetDimensions( PRUint32 *aWidth, PRUint32 *aHeight);
|
||||
};
|
||||
|
||||
// Surface for a printer-page
|
||||
class nsPrintSurface : public nsOnscreenSurface
|
||||
{
|
||||
PRInt32 mHeight;
|
||||
PRInt32 mWidth;
|
||||
|
||||
public:
|
||||
nsPrintSurface();
|
||||
virtual ~nsPrintSurface();
|
||||
|
||||
NS_IMETHOD Init( HPS aPS, PRInt32 aWidth, PRInt32 aHeight);
|
||||
NS_IMETHOD RequiresInvertedMask( PRBool *aNeedsIMask);
|
||||
NS_IMETHOD GetDimensions( PRUint32 *aWidth, PRUint32 *aHeight);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,429 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// ToDo: Unicode, encoding.
|
||||
// Revision by someone who *really* understands OS/2 fonts.
|
||||
|
||||
#include "nsGfxDefs.h"
|
||||
#include "nsDeviceContextOS2.h"
|
||||
#include "nsFontMetricsOS2.h"
|
||||
#include "nsString.h"
|
||||
#include "nsFont.h"
|
||||
|
||||
// font handle
|
||||
nsFontHandleOS2::nsFontHandleOS2()
|
||||
{
|
||||
memset( &fattrs, 0, sizeof fattrs);
|
||||
fattrs.usRecordLength = sizeof fattrs;
|
||||
charbox.cx = charbox.cy = 0;
|
||||
}
|
||||
|
||||
void nsFontHandleOS2::SelectIntoPS( HPS hps, long lcid)
|
||||
{
|
||||
if( !GpiSetCharBox( hps, &charbox))
|
||||
PMERROR("GpiSetCharBox");
|
||||
if( !GpiSetCharSet( hps, lcid))
|
||||
PMERROR("GpiSetCharSet");
|
||||
}
|
||||
|
||||
nsFontMetricsOS2::nsFontMetricsOS2()
|
||||
{
|
||||
// members are zeroed by new operator (hmm)
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsFontMetricsOS2::~nsFontMetricsOS2()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
delete mFont;
|
||||
delete mFontHandle;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS( nsFontMetricsOS2, nsIFontMetrics::GetIID())
|
||||
|
||||
nsresult nsFontMetricsOS2::Init( const nsFont &aFont, nsIDeviceContext *aContext)
|
||||
{
|
||||
mFont = new nsFont( aFont);
|
||||
mContext = (nsDeviceContextOS2 *) aContext;
|
||||
RealizeFont();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFontMetricsOS2::Destroy()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Map CSS font names to something we can understand locally.
|
||||
// Some conversions are a bit dodgy (fantasy) but there's little option, I
|
||||
// guess.
|
||||
// Surely this should be in XP code somewhere?
|
||||
static void MapGenericFamilyToFont( const nsString &aGenericFamily,
|
||||
nsIDeviceContext *aDC,
|
||||
nsString &aFontFace)
|
||||
{
|
||||
// the CSS generic names (conversions from Nav for now)
|
||||
// XXX this need to check availability with the dc
|
||||
PRBool aliased;
|
||||
if( aGenericFamily.EqualsIgnoreCase( "serif"))
|
||||
aDC->GetLocalFontName( nsString( "Tms Rmn"), aFontFace, aliased);
|
||||
else if( aGenericFamily.EqualsIgnoreCase( "sans-serif"))
|
||||
aDC->GetLocalFontName( nsString( "Helv"), aFontFace, aliased);
|
||||
else if( aGenericFamily.EqualsIgnoreCase( "Helv")) // !!
|
||||
aDC->GetLocalFontName( nsString( "Script"), aFontFace, aliased);
|
||||
else if( aGenericFamily.EqualsIgnoreCase( "fantasy")) // !!
|
||||
aDC->GetLocalFontName(nsString( "Arial"), aFontFace, aliased);
|
||||
else if( aGenericFamily.EqualsIgnoreCase( "monospace"))
|
||||
aDC->GetLocalFontName( nsString( "Courier"), aFontFace, aliased);
|
||||
else
|
||||
aFontFace.Truncate();
|
||||
}
|
||||
|
||||
struct FontEnumData
|
||||
{
|
||||
FontEnumData( nsIDeviceContext* aContext, char* aFaceName)
|
||||
: mContext( aContext), mFaceName( aFaceName)
|
||||
{}
|
||||
|
||||
nsIDeviceContext *mContext;
|
||||
char *mFaceName;
|
||||
};
|
||||
|
||||
// callback for each of the faces in the nsFont (use the first we can match)
|
||||
static PRBool FontEnumCallback( const nsString& aFamily, PRBool aGeneric, void *aData)
|
||||
{
|
||||
FontEnumData *data = (FontEnumData*)aData;
|
||||
PRBool rc = PR_TRUE;
|
||||
|
||||
if( aGeneric)
|
||||
{
|
||||
nsAutoString realFace;
|
||||
MapGenericFamilyToFont( aFamily, data->mContext, realFace);
|
||||
realFace.ToCString( data->mFaceName, FACESIZE);
|
||||
rc = PR_FALSE; // stop
|
||||
}
|
||||
else
|
||||
{
|
||||
nsAutoString realFace;
|
||||
PRBool aliased;
|
||||
data->mContext->GetLocalFontName( aFamily, realFace, aliased);
|
||||
if( aliased || (NS_OK == data->mContext->CheckFontExistence( realFace)))
|
||||
{
|
||||
realFace.ToCString(data->mFaceName, FACESIZE);
|
||||
rc = PR_FALSE; // stop
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Current strategy wrt. image/outline fonts:
|
||||
// If image face requested is available in the point size requested,
|
||||
// use it. If not, use the corresponding outline font. The reason
|
||||
// why we deal with this here instead of letting GpiCreateLogFont() do
|
||||
// something sensible is because it doesn't do the right thing with
|
||||
// bold/italic effects: if we ask for bold Tms Rmn in 35 pt, we don't
|
||||
// get Times New Roman Bold in 35 pt, but Times New Roman 35pt with a
|
||||
// fake bold effect courtesy of gpi, which looks ugly.
|
||||
//
|
||||
// Yes, it would be easier & quite plausable to ignore image fonts altogether
|
||||
// and just use outlines, but I reckon image fonts look better at lower
|
||||
// point sizes.
|
||||
//
|
||||
// Candidate for butchery!
|
||||
|
||||
// Utility; delete [] when done.
|
||||
static PFONTMETRICS getMetrics( long &lFonts, PCSZ facename, HPS hps)
|
||||
{
|
||||
LONG lWant = 0;
|
||||
lFonts = GpiQueryFonts( hps, QF_PUBLIC | QF_PRIVATE,
|
||||
facename, &lWant, 0, 0);
|
||||
PFONTMETRICS pMetrics = new FONTMETRICS [ lFonts];
|
||||
|
||||
GpiQueryFonts( hps, QF_PUBLIC | QF_PRIVATE, facename, &lFonts,
|
||||
sizeof( FONTMETRICS), pMetrics);
|
||||
|
||||
return pMetrics;
|
||||
}
|
||||
|
||||
void nsFontMetricsOS2::RealizeFont()
|
||||
{
|
||||
nsFontHandleOS2 *fh = new nsFontHandleOS2;
|
||||
|
||||
// 1) Find family name
|
||||
char szFamily[ FACESIZE] = "";
|
||||
FontEnumData data( mContext, szFamily);
|
||||
mFont->EnumerateFamilies( FontEnumCallback, &data);
|
||||
|
||||
// sanity check - no way of telling whether we want a fixed or prop font..
|
||||
if( !szFamily[0])
|
||||
strcpy( szFamily, "System Proportional");
|
||||
|
||||
// 2) Get a representative PS for doing font queries into
|
||||
HPS hps = mContext->GetRepresentativePS();
|
||||
|
||||
// 3) Work out what our options are wrt. image/outline, prefer image.
|
||||
BOOL bOutline = FALSE, bImage = FALSE;
|
||||
long lFonts = 0; int i;
|
||||
PFONTMETRICS pMetrics = getMetrics( lFonts, szFamily, hps);
|
||||
|
||||
for( i = 0; i < lFonts && !(bImage && bOutline); i++)
|
||||
if( pMetrics[ i].fsDefn & FM_DEFN_OUTLINE) bOutline = TRUE;
|
||||
else bImage = TRUE;
|
||||
delete [] pMetrics;
|
||||
|
||||
if( !bImage) fh->fattrs.fsFontUse = FATTR_FONTUSE_OUTLINE |
|
||||
FATTR_FONTUSE_TRANSFORMABLE;
|
||||
|
||||
// 4) Try to munge the face for italic & bold effects (could do better)
|
||||
BOOL bBold = mFont->weight > NS_FONT_WEIGHT_NORMAL;
|
||||
BOOL bItalic = !!(mFont->style & NS_FONT_STYLE_ITALIC);
|
||||
FACENAMEDESC fnd = { sizeof( FACENAMEDESC),
|
||||
bBold ? FWEIGHT_BOLD : FWEIGHT_DONT_CARE,
|
||||
FWIDTH_DONT_CARE,
|
||||
0,
|
||||
bItalic ? FTYPE_ITALIC : 0 };
|
||||
|
||||
ULONG rc = GpiQueryFaceString( hps, szFamily, &fnd,
|
||||
FACESIZE, fh->fattrs.szFacename);
|
||||
if( rc == GPI_ERROR)
|
||||
{ // no real font, fake it
|
||||
strcpy( fh->fattrs.szFacename, szFamily);
|
||||
if( bBold) fh->fattrs.fsSelection |= FATTR_SEL_BOLD;
|
||||
if( bItalic) fh->fattrs.fsSelection |= FATTR_SEL_ITALIC;
|
||||
}
|
||||
|
||||
// 5) Add misc effects
|
||||
if( mFont->decorations & NS_FONT_DECORATION_UNDERLINE)
|
||||
fh->fattrs.fsSelection |= FATTR_SEL_UNDERSCORE;
|
||||
if( mFont->decorations & NS_FONT_DECORATION_LINE_THROUGH)
|
||||
fh->fattrs.fsSelection |= FATTR_SEL_STRIKEOUT;
|
||||
|
||||
// 6) Encoding
|
||||
// There doesn't seem to be any encoding stuff yet, so guess.
|
||||
// (XXX unicode hack; use same codepage as converter!)
|
||||
fh->fattrs.usCodePage = gModuleData.ulCodepage;
|
||||
|
||||
// 7) Find the point size for the font, and set up the charbox too
|
||||
float app2dev, app2twip, twip2dev;
|
||||
mContext->GetAppUnitsToDevUnits( app2dev);
|
||||
mContext->GetDevUnitsToTwips( app2twip);
|
||||
mContext->GetTwipsToDevUnits( twip2dev);
|
||||
|
||||
// !! Windows wants to mply up here. I don't think I do. If fonts
|
||||
// !! ever begin to look `squished', try enabling the following code
|
||||
#if 0
|
||||
float scale;
|
||||
mContext->GetCanonicalPixelScale(scale);
|
||||
app2twip *= app2dev * scale;
|
||||
#else
|
||||
app2twip *= app2dev;
|
||||
#endif
|
||||
|
||||
// Note: are you confused by the block above, and thinking that app2twip
|
||||
// must be 1? Well, there's *no* guarantee that app units are
|
||||
// twips, despite whatever nscoord.h says!
|
||||
int points = NSTwipsToFloorIntPoints( nscoord( mFont->size * app2twip));
|
||||
fh->charbox.cx = MAKEFIXED( points * 20 * twip2dev, 0);
|
||||
fh->charbox.cy = fh->charbox.cx;
|
||||
|
||||
// 8) If we're using an image font, check it's available in the size
|
||||
// required, substituting an outline if necessary.
|
||||
if( bImage)
|
||||
{
|
||||
HDC hdc = GpiQueryDevice( hps);
|
||||
long res[ 2];
|
||||
DevQueryCaps( hdc, CAPS_HORIZONTAL_FONT_RES, 2, res);
|
||||
pMetrics = getMetrics( lFonts, szFamily, hps);
|
||||
|
||||
for( i = 0; i < lFonts; i++)
|
||||
if( !stricmp( szFamily, pMetrics[ i].szFamilyname) &&
|
||||
pMetrics[ i].sNominalPointSize / 10 == points &&
|
||||
pMetrics[ i].sXDeviceRes == res[0] &&
|
||||
pMetrics[ i].sYDeviceRes == res[1]) break;
|
||||
|
||||
if( i == lFonts)
|
||||
{
|
||||
// Couldn't find an appropriate font, need to use an outline.
|
||||
// If there was an outline originally, fine. If not...
|
||||
if( !bOutline)
|
||||
{
|
||||
// Can't have the requested font in requested size; fake.
|
||||
if( !stricmp( szFamily, "Helv"))
|
||||
strcpy( szFamily, "Helvetica");
|
||||
else if( !stricmp( szFamily, "Courier"))
|
||||
strcpy( szFamily, "Courier New");
|
||||
else
|
||||
strcpy( szFamily, "Times New Roman"); // hmm
|
||||
fh->fattrs.fsSelection &= ~(FATTR_SEL_BOLD | FATTR_SEL_ITALIC);
|
||||
rc = GpiQueryFaceString( hps, szFamily, &fnd,
|
||||
FACESIZE, fh->fattrs.szFacename);
|
||||
if( rc == GPI_ERROR)
|
||||
{
|
||||
strcpy( fh->fattrs.szFacename, szFamily);
|
||||
if( bBold) fh->fattrs.fsSelection |= FATTR_SEL_BOLD;
|
||||
if( bItalic) fh->fattrs.fsSelection |= FATTR_SEL_ITALIC;
|
||||
}
|
||||
}
|
||||
fh->fattrs.fsFontUse = FATTR_FONTUSE_OUTLINE |
|
||||
FATTR_FONTUSE_TRANSFORMABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// image face found fine, set required size in fattrs.
|
||||
fh->fattrs.lMaxBaselineExt = pMetrics[ i].lMaxBaselineExt;
|
||||
fh->fattrs.lAveCharWidth = pMetrics[ i].lAveCharWidth;
|
||||
}
|
||||
delete [] pMetrics;
|
||||
}
|
||||
|
||||
// 9) Record font handle & record various font metrics to cache
|
||||
mFontHandle = fh;
|
||||
if( GPI_ERROR == GpiCreateLogFont( hps, 0, 1, &fh->fattrs))
|
||||
PMERROR( "GpiCreateLogFont");
|
||||
fh->SelectIntoPS( hps, 1);
|
||||
|
||||
FONTMETRICS fm;
|
||||
GpiQueryFontMetrics( hps, sizeof fm, &fm);
|
||||
|
||||
float dev2app;
|
||||
mContext->GetDevUnitsToAppUnits( dev2app);
|
||||
|
||||
// PM includes the internal leading in the max ascender. So the max
|
||||
// ascender we tell raptor about should be lMaxAscent - lInternalLeading.
|
||||
//
|
||||
// This is probably all moot 'cos lInternalLeading is usually zero.
|
||||
// More so 'cos layout doesn't look at the leading we give it.
|
||||
//
|
||||
// So let's leave it as zero to avoid confusion & change it if necessary.
|
||||
|
||||
mHeight = NSToCoordRound( fm.lMaxBaselineExt * dev2app);
|
||||
mMaxAscent = NSToCoordRound( fm.lMaxAscender * dev2app);
|
||||
mMaxDescent = NSToCoordRound( fm.lMaxDescender * dev2app);
|
||||
mMaxAdvance = NSToCoordRound( fm.lMaxCharInc * dev2app);
|
||||
|
||||
mLeading = NSToCoordRound( fm.lInternalLeading * dev2app);
|
||||
mXHeight = NSToCoordRound( fm.lXHeight * dev2app);
|
||||
|
||||
mSuperscriptYOffset = NSToCoordRound( fm.lSuperscriptYOffset * dev2app);
|
||||
mSubscriptYOffset = NSToCoordRound( fm.lSubscriptYOffset * dev2app); // !! check this
|
||||
mStrikeoutPosition = NSToCoordRound( fm.lStrikeoutPosition * dev2app);
|
||||
mStrikeoutSize = NSToCoordRound( fm.lStrikeoutSize * dev2app);
|
||||
mUnderlinePosition = NSToCoordRound( -fm.lUnderscorePosition * dev2app);
|
||||
mUnderlineSize = NSToCoordRound( fm.lUnderscoreSize * dev2app);
|
||||
|
||||
// OS/2 field (needs to be kept in sync with mMaxAscent)
|
||||
mDevMaxAscent = fm.lMaxAscender;
|
||||
|
||||
// 10) Clean up
|
||||
GpiSetCharSet( hps, LCID_DEFAULT);
|
||||
if( !GpiDeleteSetId( hps, 1))
|
||||
PMERROR( "GpiDeleteSetID (FM)");
|
||||
mContext->ReleaseRepresentativePS( hps);
|
||||
}
|
||||
|
||||
nscoord nsFontMetricsOS2::GetSpaceWidth( nsIRenderingContext *aRContext)
|
||||
{
|
||||
if( !mSpaceWidth)
|
||||
{
|
||||
char buf[1];
|
||||
buf[0] = ' ';
|
||||
aRContext->GetWidth( buf, 1, mSpaceWidth);
|
||||
}
|
||||
|
||||
return mSpaceWidth;
|
||||
}
|
||||
|
||||
// Other metrics
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetXHeight( nscoord &aResult)
|
||||
{
|
||||
aResult = mXHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetSuperscriptOffset(nscoord& aResult)
|
||||
{
|
||||
aResult = mSuperscriptYOffset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetSubscriptOffset(nscoord& aResult)
|
||||
{
|
||||
aResult = mSubscriptYOffset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetStrikeout(nscoord& aOffset, nscoord& aSize)
|
||||
{
|
||||
aOffset = mStrikeoutPosition;
|
||||
aSize = mStrikeoutSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetUnderline(nscoord& aOffset, nscoord& aSize)
|
||||
{
|
||||
aOffset = mUnderlinePosition;
|
||||
aSize = mUnderlineSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetHeight( nscoord &aHeight)
|
||||
{
|
||||
aHeight = mHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetLeading( nscoord &aLeading)
|
||||
{
|
||||
aLeading = mLeading;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetMaxAscent( nscoord &aAscent)
|
||||
{
|
||||
aAscent = mMaxAscent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetMaxDescent( nscoord &aDescent)
|
||||
{
|
||||
aDescent = mMaxDescent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetMaxAdvance( nscoord &aAdvance)
|
||||
{
|
||||
aAdvance = mMaxAdvance;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetFont( const nsFont *&aFont)
|
||||
{
|
||||
aFont = mFont;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsOS2::GetFontHandle( nsFontHandle &aHandle)
|
||||
{
|
||||
aHandle = mFontHandle;
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsFontMetricsOS2_h
|
||||
#define _nsFontMetricsOS2_h
|
||||
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
class nsIRenderingContext;
|
||||
class nsDeviceContextOS2;
|
||||
class nsString;
|
||||
class nsFont;
|
||||
|
||||
// An nsFontHandle is actually a pointer to one of these.
|
||||
// It knows how to select itself into a ps.
|
||||
struct nsFontHandleOS2
|
||||
{
|
||||
FATTRS fattrs;
|
||||
SIZEF charbox;
|
||||
|
||||
nsFontHandleOS2();
|
||||
void SelectIntoPS( HPS hps, long lcid);
|
||||
};
|
||||
|
||||
class nsFontMetricsOS2 : public nsIFontMetrics
|
||||
{
|
||||
public:
|
||||
nsFontMetricsOS2();
|
||||
virtual ~nsFontMetricsOS2();
|
||||
|
||||
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init( const nsFont& aFont, nsIDeviceContext *aContext);
|
||||
NS_IMETHOD Destroy();
|
||||
|
||||
// Metrics
|
||||
NS_IMETHOD GetXHeight( nscoord &aResult);
|
||||
NS_IMETHOD GetSuperscriptOffset( nscoord &aResult);
|
||||
NS_IMETHOD GetSubscriptOffset( nscoord &aResult);
|
||||
NS_IMETHOD GetStrikeout( nscoord &aOffset, nscoord &aSize);
|
||||
NS_IMETHOD GetUnderline( nscoord &aOffset, nscoord &aSize);
|
||||
NS_IMETHOD GetHeight( nscoord &aHeight);
|
||||
NS_IMETHOD GetLeading( nscoord &aLeading);
|
||||
NS_IMETHOD GetMaxAscent( nscoord &aAscent);
|
||||
NS_IMETHOD GetMaxDescent( nscoord &aDescent);
|
||||
NS_IMETHOD GetMaxAdvance( nscoord &aAdvance);
|
||||
|
||||
NS_IMETHOD GetFont( const nsFont *&aFont);
|
||||
NS_IMETHOD GetFontHandle( nsFontHandle &aHandle);
|
||||
|
||||
// for drawing text
|
||||
PRUint32 GetDevMaxAscender() const { return mDevMaxAscent; }
|
||||
nscoord GetSpaceWidth( nsIRenderingContext *aRContext);
|
||||
|
||||
protected:
|
||||
void RealizeFont();
|
||||
|
||||
nsFont *mFont;
|
||||
|
||||
nscoord mXHeight;
|
||||
nscoord mSuperscriptYOffset;
|
||||
nscoord mSubscriptYOffset;
|
||||
nscoord mStrikeoutPosition;
|
||||
nscoord mStrikeoutSize;
|
||||
nscoord mUnderlinePosition;
|
||||
nscoord mUnderlineSize;
|
||||
nscoord mHeight;
|
||||
nscoord mLeading;
|
||||
nscoord mMaxAscent;
|
||||
nscoord mMaxDescent;
|
||||
nscoord mMaxAdvance;
|
||||
|
||||
PRUint32 mDevMaxAscent;
|
||||
nscoord mSpaceWidth;
|
||||
|
||||
nsFontHandleOS2 *mFontHandle;
|
||||
nsDeviceContextOS2 *mContext; // sigh.. broken broken broken XP interfaces...
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsgfxdefs_h
|
||||
#define _nsgfxdefs_h
|
||||
|
||||
// nsGfxDefs.h - common includes etc. for gfx library
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
#define INCL_PM
|
||||
#define INCL_DOS
|
||||
#include <os2.h>
|
||||
|
||||
#include <uconv.h> // XXX hack XXX
|
||||
|
||||
#define COLOR_CUBE_SIZE 216
|
||||
|
||||
void PMERROR(const char *str);
|
||||
|
||||
class nsString;
|
||||
class nsIPaletteOS2;
|
||||
class nsIDeviceContext;
|
||||
|
||||
// Module data
|
||||
struct nsGfxModuleData
|
||||
{
|
||||
HMODULE hModResources;
|
||||
HPS hpsScreen;
|
||||
LONG lDisplayDepth;
|
||||
|
||||
nsGfxModuleData();
|
||||
~nsGfxModuleData();
|
||||
|
||||
// XXX XXX XXX this is a hack copied from the widget library (where it's
|
||||
// not a hack but perfectly valid) until font-switching comes
|
||||
// on-line.
|
||||
// Unicode->local cp. conversions
|
||||
char *ConvertFromUcs( const PRUnichar *pText, ULONG ulLength, char *szBuffer, ULONG ulSize);
|
||||
char *ConvertFromUcs( const nsString &aStr, char *szBuffer, ULONG ulSize);
|
||||
// these methods use a single static buffer
|
||||
const char *ConvertFromUcs( const PRUnichar *pText, ULONG ulLength);
|
||||
const char *ConvertFromUcs( const nsString &aStr);
|
||||
|
||||
UconvObject converter;
|
||||
BOOL supplantConverter;
|
||||
PRUint32 renderingHints;
|
||||
ULONG ulCodepage;
|
||||
// XXX XXX XXX end hack
|
||||
|
||||
void Init();
|
||||
|
||||
// This addref's
|
||||
nsIPaletteOS2 *GetUIPalette( nsIDeviceContext *aContext);
|
||||
|
||||
protected:
|
||||
nsIPaletteOS2 *uiPalette;
|
||||
};
|
||||
|
||||
extern nsGfxModuleData gModuleData;
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define MK_RGB(r,g,b) ((r) * 65536) + ((g) * 256) + (b)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// ToDo: nowt (except get rid of unicode hack)
|
||||
#define INCL_DOS
|
||||
#include "nsGfxDefs.h"
|
||||
#include "libprint.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsFontMetricsOS2.h"
|
||||
#include "nsRenderingContextOS2.h"
|
||||
#include "nsImageOS2.h"
|
||||
#include "nsDeviceContextOS2.h"
|
||||
#include "nsRegionOS2.h"
|
||||
#include "nsBlender.h"
|
||||
#include "nsPaletteOS2.h"
|
||||
#include "nsDeviceContextSpecOS2.h"
|
||||
#include "nsDeviceContextSpecFactoryO.h"
|
||||
|
||||
// nsGfxFactory.cpp - factory for creating os/2 graphics objects.
|
||||
|
||||
static NS_DEFINE_IID(kCFontMetrics, NS_FONT_METRICS_CID);
|
||||
static NS_DEFINE_IID(kCRenderingContext, NS_RENDERING_CONTEXT_CID);
|
||||
static NS_DEFINE_IID(kCImage, NS_IMAGE_CID);
|
||||
static NS_DEFINE_IID(kCDeviceContext, NS_DEVICE_CONTEXT_CID);
|
||||
static NS_DEFINE_IID(kCRegion, NS_REGION_CID);
|
||||
static NS_DEFINE_IID(kCBlender, NS_BLENDER_CID);
|
||||
static NS_DEFINE_IID(kCDeviceContextSpec, NS_DEVICE_CONTEXT_SPEC_CID);
|
||||
static NS_DEFINE_IID(kCDeviceContextSpecFactory, NS_DEVICE_CONTEXT_SPEC_FACTORY_CID);
|
||||
|
||||
class nsGfxFactoryOS2 : public nsIFactory
|
||||
{
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIFactory methods
|
||||
NS_IMETHOD CreateInstance( nsISupports *aOuter,
|
||||
const nsIID &aIID,
|
||||
void **aResult);
|
||||
|
||||
NS_IMETHOD LockFactory( PRBool aLock) { return NS_OK; }
|
||||
|
||||
nsGfxFactoryOS2( const nsCID &aClass);
|
||||
virtual ~nsGfxFactoryOS2();
|
||||
|
||||
private:
|
||||
nsCID mClassID;
|
||||
};
|
||||
|
||||
nsGfxFactoryOS2::nsGfxFactoryOS2( const nsCID &aClass)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mClassID = aClass;
|
||||
}
|
||||
|
||||
nsGfxFactoryOS2::~nsGfxFactoryOS2()
|
||||
{
|
||||
NS_ASSERTION( mRefCnt == 0, "non-zero refcnt at destruction");
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsGfxFactoryOS2,nsIFactory::GetIID())
|
||||
|
||||
nsresult nsGfxFactoryOS2::CreateInstance( nsISupports *aOuter,
|
||||
const nsIID &aIID,
|
||||
void **aResult)
|
||||
{
|
||||
if( !aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aResult = 0;
|
||||
|
||||
nsISupports *inst = nsnull;
|
||||
|
||||
if( mClassID.Equals( kCFontMetrics)) {
|
||||
inst = new nsFontMetricsOS2;
|
||||
}
|
||||
else if( mClassID.Equals( kCDeviceContext)) {
|
||||
inst = new nsDeviceContextOS2;
|
||||
}
|
||||
else if( mClassID.Equals( kCRenderingContext)) {
|
||||
inst = (nsISupports *)((nsIRenderingContext*)new nsRenderingContextOS2);
|
||||
}
|
||||
else if( mClassID.Equals( kCImage)) {
|
||||
inst = new nsImageOS2;
|
||||
}
|
||||
else if( mClassID.Equals( kCRegion)) {
|
||||
inst = new nsRegionOS2;
|
||||
}
|
||||
else if( mClassID.Equals( kCBlender)) {
|
||||
inst = new nsBlender;
|
||||
}
|
||||
else if( mClassID.Equals( kCDeviceContextSpec)) {
|
||||
inst = new nsDeviceContextSpecOS2;
|
||||
}
|
||||
else if( mClassID.Equals( kCDeviceContextSpecFactory)) {
|
||||
inst = new nsDeviceContextSpecFactoryOS2;
|
||||
}
|
||||
|
||||
if( !inst)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult res = inst->QueryInterface(aIID, aResult);
|
||||
|
||||
if( NS_FAILED(res))
|
||||
// We didn't get the right interface, so clean up
|
||||
delete inst;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// This is a factory-factory: create a factory for the desired type.
|
||||
extern "C" NS_GFXNONXP nsresult NSGetFactory(nsISupports* servMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory)
|
||||
{
|
||||
if( !aFactory)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aFactory = new nsGfxFactoryOS2( aClass);
|
||||
|
||||
if( !*aFactory)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return (*aFactory)->QueryInterface( nsIFactory::GetIID(), (void**) aFactory);
|
||||
}
|
||||
|
||||
// Module-level data ---------------------------------------------------------
|
||||
void PMERROR( const char *api)
|
||||
{
|
||||
ERRORID eid = WinGetLastError(0);
|
||||
USHORT usError = ERRORIDERROR(eid);
|
||||
printf( "%s failed, error = 0x%X\n", api, usError);
|
||||
}
|
||||
|
||||
nsGfxModuleData::nsGfxModuleData() : hModResources(0), hpsScreen(0),
|
||||
lDisplayDepth(0), uiPalette(0)
|
||||
{}
|
||||
|
||||
void nsGfxModuleData::Init()
|
||||
{
|
||||
char buffer[CCHMAXPATH];
|
||||
APIRET rc;
|
||||
|
||||
rc = DosLoadModule( buffer, CCHMAXPATH, "GFXOS2", &hModResources);
|
||||
|
||||
if( rc)
|
||||
{
|
||||
printf( "Gfx failed to load self. rc = %d, cause = %s\n", (int)rc, buffer);
|
||||
// rats. Can't load ourselves. Oh well. Try to be harmless...
|
||||
hModResources = 0;
|
||||
}
|
||||
PrnInitialize( hModResources);
|
||||
|
||||
// get screen bit-depth
|
||||
hpsScreen = WinGetScreenPS( HWND_DESKTOP);
|
||||
HDC hdc = GpiQueryDevice( hpsScreen);
|
||||
DevQueryCaps( hdc, CAPS_COLOR_BITCOUNT, 1, &lDisplayDepth);
|
||||
|
||||
// XXX XXX temp hack XXX XXX XXX
|
||||
converter = 0;
|
||||
supplantConverter = FALSE;
|
||||
if( !getenv( "MOZ_DONT_DRAW_UNICODE"))
|
||||
{
|
||||
ULONG ulDummy = 0;
|
||||
renderingHints = 0;
|
||||
DosQueryCp( 4, &ulCodepage, &ulDummy);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderingHints = NS_RENDERING_HINT_FAST_8BIT_TEXT;
|
||||
ulCodepage = 1004;
|
||||
}
|
||||
// XXX XXX end temp hack XXX XXX XXX
|
||||
}
|
||||
|
||||
nsGfxModuleData::~nsGfxModuleData()
|
||||
{
|
||||
// XXX XXX temp hack XXX XXX XXX
|
||||
if( converter)
|
||||
UniFreeUconvObject( converter);
|
||||
// XXX XXX end temp hack XXX XXX XXX
|
||||
|
||||
PrnTerminate();
|
||||
if( hModResources)
|
||||
DosFreeModule( hModResources);
|
||||
WinReleasePS( hpsScreen);
|
||||
|
||||
NS_IF_RELEASE(uiPalette);
|
||||
}
|
||||
|
||||
nsIPaletteOS2 *nsGfxModuleData::GetUIPalette( nsIDeviceContext *aContext)
|
||||
{
|
||||
if( !uiPalette)
|
||||
NS_CreatePalette( aContext, uiPalette);
|
||||
|
||||
NS_ADDREF(uiPalette);
|
||||
|
||||
return uiPalette;
|
||||
}
|
||||
|
||||
nsGfxModuleData gModuleData;
|
||||
|
||||
// XXX XXX XXX XXX Temp hack until font-switching comes on-line XXX XXX XXX XXX
|
||||
|
||||
// Conversion from unicode to appropriate codepage
|
||||
char *nsGfxModuleData::ConvertFromUcs( const PRUnichar *pText, ULONG ulLength,
|
||||
char *szBuffer, ULONG ulSize)
|
||||
{
|
||||
if( supplantConverter)
|
||||
{
|
||||
// We couldn't create a converter for some reason, so do this 'by hand'.
|
||||
// Note this algorithm is fine for most of most western charsets, but
|
||||
// fails dismally for various glyphs, baltic, points east...
|
||||
ULONG ulCount = 0;
|
||||
char *szSave = szBuffer;
|
||||
while( *pText && ulCount < ulSize - 1) // (one for terminator)
|
||||
{
|
||||
*szBuffer = (char) *pText;
|
||||
szBuffer++;
|
||||
pText++;
|
||||
ulCount++;
|
||||
}
|
||||
|
||||
// terminate string
|
||||
*szBuffer = '\0';
|
||||
|
||||
return szSave;
|
||||
}
|
||||
|
||||
if( !converter)
|
||||
{
|
||||
// Create a converter from unicode to a codepage which PM can display.
|
||||
UniChar codepage[20];
|
||||
int unirc = UniMapCpToUcsCp( 0, codepage, 20);
|
||||
if( unirc == ULS_SUCCESS)
|
||||
{
|
||||
unirc = UniCreateUconvObject( codepage, &converter);
|
||||
// XXX do we need to set substitution options here?
|
||||
}
|
||||
if( unirc != ULS_SUCCESS)
|
||||
{
|
||||
supplantConverter = TRUE;
|
||||
renderingHints = NS_RENDERING_HINT_FAST_8BIT_TEXT;
|
||||
ulCodepage = 1004;
|
||||
printf( "Couldn't create gfx unicode converter.\n");
|
||||
return ConvertFromUcs( pText, szBuffer, ulSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Have converter, now get it to work...
|
||||
|
||||
UniChar *ucsString = (UniChar*) pText;
|
||||
size_t ucsLen = ulLength;
|
||||
size_t cplen = ulSize;
|
||||
size_t cSubs = 0;
|
||||
|
||||
char *tmp = szBuffer; // function alters the out pointer
|
||||
|
||||
int unirc = UniUconvFromUcs( converter, &ucsString, &ucsLen,
|
||||
(void**) &tmp, &cplen, &cSubs);
|
||||
|
||||
if( unirc == UCONV_E2BIG) // k3w1
|
||||
{
|
||||
// terminate output string (truncating)
|
||||
*(szBuffer + ulSize - 1) = '\0';
|
||||
}
|
||||
else if( unirc != ULS_SUCCESS)
|
||||
{
|
||||
printf( "UniUconvFromUcs failed, rc %X\n", unirc);
|
||||
supplantConverter = TRUE;
|
||||
szBuffer = ConvertFromUcs( pText, szBuffer, ulSize);
|
||||
supplantConverter = FALSE;
|
||||
}
|
||||
|
||||
return szBuffer;
|
||||
}
|
||||
|
||||
char *nsGfxModuleData::ConvertFromUcs( const nsString &aString,
|
||||
char *szBuffer, ULONG ulSize)
|
||||
{
|
||||
char *szRet = 0;
|
||||
const PRUnichar *pUnicode = aString.GetUnicode();
|
||||
|
||||
if( pUnicode)
|
||||
szRet = ConvertFromUcs( pUnicode, aString.Length() + 1, szBuffer, ulSize);
|
||||
else
|
||||
szRet = aString.ToCString( szBuffer, ulSize);
|
||||
|
||||
return szRet;
|
||||
}
|
||||
|
||||
const char *nsGfxModuleData::ConvertFromUcs( const PRUnichar *pText, ULONG ulLength)
|
||||
{
|
||||
// This is probably okay; longer strings will be truncated but istr there's
|
||||
// a PM limit on things like windowtext
|
||||
// (which these routines are usually used for)
|
||||
|
||||
static char buffer[1024]; // XXX (multithread)
|
||||
*buffer = '\0';
|
||||
return ConvertFromUcs( pText, ulLength, buffer, 1024);
|
||||
}
|
||||
|
||||
const char *nsGfxModuleData::ConvertFromUcs( const nsString &aString)
|
||||
{
|
||||
const char *szRet = 0;
|
||||
const PRUnichar *pUnicode = aString.GetUnicode();
|
||||
|
||||
if( pUnicode)
|
||||
szRet = ConvertFromUcs( pUnicode, aString.Length() + 1);
|
||||
else
|
||||
szRet = aString.GetBuffer(); // hrm.
|
||||
|
||||
return szRet;
|
||||
}
|
||||
|
||||
// XXX XXX XXX XXX End Temp hack until font-switching comes on-line XXX XXX XXX
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsGfxDefs.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nsImageOS2.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsRenderingContextOS2.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsImageOS2,nsIImage::GetIID());
|
||||
|
||||
//------------------------------------------------------------
|
||||
nsImageOS2::nsImageOS2()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
mInfo = 0;
|
||||
mStride = 0;
|
||||
mImageBits = 0;
|
||||
mBitmap = 0;
|
||||
|
||||
mAStride = 0;
|
||||
mAImageBits = 0;
|
||||
mABitmap = 0;
|
||||
mAlphaDepth = 0;
|
||||
|
||||
mColorMap = 0;
|
||||
|
||||
mOptimized = PR_FALSE;
|
||||
|
||||
mDeviceDepth = 0;
|
||||
}
|
||||
|
||||
nsImageOS2::~nsImageOS2()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
nsresult nsImageOS2::Init( PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,
|
||||
nsMaskRequirements aMaskRequirements)
|
||||
{
|
||||
// Guard against memory leak in multiple init
|
||||
Cleanup();
|
||||
|
||||
// (copying windows code - what about monochrome? Oh well.)
|
||||
NS_ASSERTION( aDepth == 24 || aDepth == 8, "Bad image depth");
|
||||
|
||||
// Work out size of bitmap to allocate
|
||||
mStride = RASWIDTH(aWidth,aDepth);
|
||||
|
||||
// mStride = aWidth * aDepth;
|
||||
// if( aDepth < 8)
|
||||
// mStride += 7;
|
||||
// mStride /= 8;
|
||||
//
|
||||
// // Make sure image width is 4byte aligned
|
||||
// mStride = (mStride + 3) & ~0x3;
|
||||
|
||||
mImageBits = new PRUint8 [ aHeight * mStride ];
|
||||
|
||||
// Set up bitmapinfo header
|
||||
int cols = -1;
|
||||
if( aDepth == 8) cols = COLOR_CUBE_SIZE;
|
||||
else if( aDepth <= 32) cols = 0;
|
||||
|
||||
int szStruct = sizeof( BITMAPINFOHEADER2) + cols * sizeof( RGB2);
|
||||
|
||||
mInfo = (PBITMAPINFO2) calloc( szStruct, 1);
|
||||
mInfo->cbFix = sizeof( BITMAPINFOHEADER2);
|
||||
mInfo->cx = aWidth;
|
||||
mInfo->cy = aHeight;
|
||||
mInfo->cPlanes = 1;
|
||||
mInfo->cBitCount = (USHORT) aDepth;
|
||||
|
||||
// We can't set up the bitmap colour table yet.
|
||||
|
||||
// init color map.
|
||||
// XP will update the color map & then call ImageUpdated(), at which
|
||||
// point we can change the color table in the bitmapinfo.
|
||||
if( aDepth == 8)
|
||||
{
|
||||
mColorMap = new nsColorMap;
|
||||
mColorMap->NumColors = COLOR_CUBE_SIZE;
|
||||
mColorMap->Index = new PRUint8[3 * mColorMap->NumColors];
|
||||
}
|
||||
|
||||
// Allocate stuff for mask bitmap
|
||||
if( aMaskRequirements != nsMaskRequirements_kNoMask)
|
||||
{
|
||||
if( aMaskRequirements == nsMaskRequirements_kNeeds1Bit)
|
||||
{
|
||||
mAStride = (aWidth + 7) / 8;
|
||||
mAlphaDepth = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERTION( nsMaskRequirements_kNeeds8Bit == aMaskRequirements,
|
||||
"unexpected mask depth");
|
||||
mAStride = aWidth;
|
||||
mAlphaDepth = 8;
|
||||
}
|
||||
|
||||
// 32-bit align each row
|
||||
mAStride = (mAStride + 3) & ~0x3;
|
||||
|
||||
mAImageBits = new PRUint8 [ aHeight * mAStride];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsImageOS2::Cleanup()
|
||||
{
|
||||
if( mImageBits) {
|
||||
delete [] mImageBits; mImageBits = 0;
|
||||
}
|
||||
if( mInfo) {
|
||||
free( mInfo); mInfo = 0;
|
||||
}
|
||||
if( mColorMap) {
|
||||
if( mColorMap->Index)
|
||||
delete [] mColorMap->Index;
|
||||
delete mColorMap;
|
||||
mColorMap = 0;
|
||||
}
|
||||
if( mAImageBits) {
|
||||
delete [] mAImageBits; mAImageBits = 0;
|
||||
}
|
||||
if( mBitmap) {
|
||||
GpiDeleteBitmap( mBitmap);
|
||||
mBitmap = 0;
|
||||
}
|
||||
if( mABitmap) {
|
||||
GpiDeleteBitmap( mABitmap);
|
||||
mABitmap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void nsImageOS2::ImageUpdated( nsIDeviceContext *aContext,
|
||||
PRUint8 aFlags, nsRect *aUpdateRect)
|
||||
{
|
||||
// This is where we can set the bitmap colour table, as the XP code
|
||||
// has filled in the colour map. It would be cute to be able to alias
|
||||
// the bitmap colour table as the mColorMap->Index thing, but the formats
|
||||
// are unfortunately different. Rats.
|
||||
|
||||
if( aFlags & nsImageUpdateFlags_kColorMapChanged && mInfo->cBitCount == 8)
|
||||
{
|
||||
PRGB2 pBmpEntry = mInfo->argbColor;
|
||||
PRUint8 *pMapByte = mColorMap->Index;
|
||||
|
||||
for( PRInt32 i = 0; i < mColorMap->NumColors; i++, pBmpEntry++)
|
||||
{
|
||||
pBmpEntry->bRed = *pMapByte++;
|
||||
pBmpEntry->bGreen = *pMapByte++;
|
||||
pBmpEntry->bBlue = *pMapByte++;
|
||||
}
|
||||
|
||||
aContext->GetDepth( mDeviceDepth);
|
||||
}
|
||||
else if( aFlags & nsImageUpdateFlags_kBitsChanged)
|
||||
{
|
||||
// jolly good...
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsImageOS2::Draw( nsIRenderingContext &aContext,
|
||||
nsDrawingSurface aSurface,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
return Draw( aContext, aSurface,
|
||||
0, 0, mInfo->cx, mInfo->cy,
|
||||
aX, aY, aWidth, aHeight);
|
||||
}
|
||||
|
||||
nsresult nsImageOS2::Draw( nsIRenderingContext &aContext,
|
||||
nsDrawingSurface aSurface,
|
||||
PRInt32 aSX, PRInt32 aSY, PRInt32 aSW, PRInt32 aSH,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDW, PRInt32 aDH)
|
||||
{
|
||||
// Find target rect in OS/2 coords.
|
||||
nsRect trect( aDX, aDY, aDW, aDH);
|
||||
RECTL rcl;
|
||||
((nsRenderingContextOS2 &)aContext).NS2PM_ININ( trect, rcl); // !! !! !!
|
||||
|
||||
nsDrawingSurfaceOS2 *surf = (nsDrawingSurfaceOS2*) aSurface;
|
||||
|
||||
// Set up blit coord array
|
||||
POINTL aptl[ 4] = { { rcl.xLeft, rcl.yBottom },
|
||||
{ rcl.xRight, rcl.yTop },
|
||||
{ aSX, mInfo->cy - aSY - aSH},
|
||||
{ aSX + aSW, mInfo->cy - aSY } };
|
||||
|
||||
// Don't bother creating HBITMAPs, just use the pel data to GpiDrawBits
|
||||
// at all times. This (a) makes printing work 'cos bitmaps are
|
||||
// device-independent.
|
||||
// (b) is allegedly more efficient...
|
||||
//
|
||||
#if 0
|
||||
if( mBitmap == 0 && mOptimized)
|
||||
{
|
||||
// moz has asked us to optimize this image, but we haven't got
|
||||
// round to actually doing it yet. So do it now.
|
||||
CreateBitmaps( surf);
|
||||
}
|
||||
#endif
|
||||
|
||||
if( mAlphaDepth == 0)
|
||||
{
|
||||
// no transparency, just blit it
|
||||
DrawBitmap( surf->mPS, 4, aptl, ROP_SRCCOPY, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// from os2fe/cxdc1.cpp:
|
||||
// > the transparent areas of the pixmap are coloured black.
|
||||
// > Note this does *not* mean that all black pels are transparent!
|
||||
// >
|
||||
// > Thus all we need to do is AND the mask onto the target, taking
|
||||
// > out pels that are not transparent, and then OR the image onto
|
||||
// > the target.
|
||||
// >
|
||||
// > Note that GPI *ignores* the colour in monochrome bitmaps when
|
||||
// > blitting, but uses the actual pel values (indices into cmap)
|
||||
// > to do things with. For 8bpp palette surface, the XP mask is
|
||||
// > backwards, so we need a custom ROP.
|
||||
// >
|
||||
// > There's probably a really good reason why ROP_SRCAND does the
|
||||
// > right thing in true colour...
|
||||
|
||||
#define ROP_NOTSRCAND 0x22 // NOT(SRC) AND DST
|
||||
|
||||
PRBool aBool;
|
||||
surf->RequiresInvertedMask( &aBool);
|
||||
|
||||
long lRop = aBool ? ROP_NOTSRCAND : ROP_SRCAND;
|
||||
|
||||
// Apply mask to target, clear pels we will fill in from the image
|
||||
DrawBitmap( surf->mPS, 4, aptl, lRop, PR_TRUE);
|
||||
// Now combine image with target
|
||||
DrawBitmap( surf->mPS, 4, aptl, ROP_SRCPAINT, PR_FALSE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsImageOS2::Optimize( nsIDeviceContext* aContext)
|
||||
{
|
||||
// Defer this until we have a PS...
|
||||
mOptimized = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// From os2fe/cxdc1.cpp
|
||||
|
||||
static RGB2 rgb2White = { 0xff, 0xff, 0xff, 0 };
|
||||
static RGB2 rgb2Black = { 0, 0, 0, 0 };
|
||||
|
||||
struct MASKBMPINFO
|
||||
{
|
||||
BITMAPINFOHEADER2 bmpInfo;
|
||||
RGB2 rgbZero;
|
||||
RGB2 rgbOne;
|
||||
|
||||
operator PBITMAPINFO2 () { return (PBITMAPINFO2) &bmpInfo; }
|
||||
operator PBITMAPINFOHEADER2 () { return &bmpInfo; }
|
||||
|
||||
MASKBMPINFO( PBITMAPINFO2 pBI)
|
||||
{
|
||||
memcpy( &bmpInfo, pBI, sizeof( BITMAPINFOHEADER2));
|
||||
bmpInfo.cBitCount = 1;
|
||||
rgbZero = rgb2Black;
|
||||
rgbOne = rgb2White;
|
||||
}
|
||||
};
|
||||
|
||||
void nsImageOS2::CreateBitmaps( nsDrawingSurfaceOS2 *surf)
|
||||
{
|
||||
mBitmap = GpiCreateBitmap( surf->mPS,
|
||||
(PBITMAPINFOHEADER2) mInfo,
|
||||
CBM_INIT,
|
||||
(PBYTE) mImageBits,
|
||||
mInfo);
|
||||
if( mBitmap == GPI_ERROR)
|
||||
PMERROR("GpiCreateBitmap");
|
||||
|
||||
if( mAImageBits)
|
||||
{
|
||||
if( mAlphaDepth == 1)
|
||||
{
|
||||
MASKBMPINFO maskInfo( mInfo);
|
||||
mABitmap = GpiCreateBitmap( surf->mPS,
|
||||
maskInfo,
|
||||
CBM_INIT,
|
||||
(PBYTE) mAImageBits,
|
||||
maskInfo);
|
||||
if( mABitmap == GPI_ERROR)
|
||||
PMERROR( "GpiCreateBitmap (mask)");
|
||||
}
|
||||
else
|
||||
printf( "8 bit alpha mask, no chance...\n");
|
||||
}
|
||||
}
|
||||
|
||||
void nsImageOS2::DrawBitmap( HPS hps, LONG lCount, PPOINTL pPoints,
|
||||
LONG lRop, PRBool bIsMask)
|
||||
{
|
||||
HBITMAP hBmp = bIsMask ? mABitmap : mBitmap;
|
||||
|
||||
#if 0
|
||||
if( hBmp)
|
||||
{
|
||||
if( GPI_ERROR == GpiWCBitBlt( hps, hBmp, lCount, pPoints, lRop, BBO_OR))
|
||||
PMERROR( "GpiWCBitBlt");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
MASKBMPINFO *pMaskInfo = 0;
|
||||
PBITMAPINFO2 pBmp2 = mInfo;
|
||||
|
||||
if( PR_TRUE == bIsMask)
|
||||
{
|
||||
pMaskInfo = new MASKBMPINFO( pBmp2);
|
||||
pBmp2 = *pMaskInfo;
|
||||
}
|
||||
|
||||
void *pBits = bIsMask ? mAImageBits : mImageBits;
|
||||
|
||||
if( GPI_ERROR == GpiDrawBits( hps, pBits, pBmp2,
|
||||
lCount, pPoints, lRop, BBO_OR))
|
||||
PMERROR( "GpiDrawBits");
|
||||
|
||||
delete pMaskInfo;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsImageOS2_h_
|
||||
#define _nsImageOS2_h_
|
||||
|
||||
#include "nsIImage.h"
|
||||
|
||||
struct nsDrawingSurfaceOS2;
|
||||
|
||||
class nsImageOS2 : public nsIImage
|
||||
{
|
||||
public:
|
||||
nsImageOS2();
|
||||
virtual ~nsImageOS2();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsresult Init( PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,
|
||||
nsMaskRequirements aMaskRequirements);
|
||||
PRInt32 GetWidth() { return mInfo ? mInfo->cx : 0; }
|
||||
PRInt32 GetHeight() { return mInfo ? mInfo->cy : 0; }
|
||||
PRInt32 GetLineStride() { return mStride; }
|
||||
PRUint8 *GetBits() { return mImageBits; }
|
||||
void *GetBitInfo() { return mInfo; }
|
||||
nsColorMap *GetColorMap() { return mColorMap; }
|
||||
PRInt32 GetBytesPix() { return mInfo ? mInfo->cBitCount : 0; }
|
||||
|
||||
PRBool GetIsRowOrderTopToBottom() { return PR_FALSE; }
|
||||
|
||||
// These may require more sensible returns...
|
||||
PRInt32 GetAlphaWidth() { return mInfo ? mInfo->cx : 0; }
|
||||
PRInt32 GetAlphaHeight() { return mInfo ? mInfo->cy : 0; }
|
||||
PRInt32 GetAlphaLineStride() { return mAStride; }
|
||||
PRUint8 *GetAlphaBits() { return mAImageBits; }
|
||||
|
||||
void SetAlphaLevel(PRInt32 aAlphaLevel) {}
|
||||
PRInt32 GetAlphaLevel() { return 0; }
|
||||
|
||||
nsresult Optimize( nsIDeviceContext* aContext);
|
||||
PRBool IsOptimized() { return mOptimized; }
|
||||
|
||||
NS_IMETHOD Draw( nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||
PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
NS_IMETHOD Draw( nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
|
||||
|
||||
void ImageUpdated( nsIDeviceContext *aContext,
|
||||
PRUint8 aFlags, nsRect *aUpdateRect);
|
||||
|
||||
private:
|
||||
BITMAPINFO2 *mInfo;
|
||||
PRInt32 mStride;
|
||||
PRInt32 mAStride;
|
||||
PRUint8 *mImageBits;
|
||||
PRUint8 *mAImageBits;
|
||||
nsColorMap *mColorMap;
|
||||
HBITMAP mBitmap;
|
||||
HBITMAP mABitmap;
|
||||
PRBool mOptimized;
|
||||
PRInt32 mAlphaDepth;
|
||||
PRUint32 mDeviceDepth;
|
||||
|
||||
void Cleanup();
|
||||
void CreateBitmaps( nsDrawingSurfaceOS2 *surf);
|
||||
void DrawBitmap( HPS hps, LONG cPts, PPOINTL pPts, LONG lRop, PRBool bMsk);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// ToDo: nothing
|
||||
#include "nsGfxDefs.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nsDeviceContextOS2.h" // sigh...
|
||||
#include "nsPaletteOS2.h"
|
||||
#include "il_util.h"
|
||||
|
||||
// os2fe/palette.cpp lives! Sort of.
|
||||
//
|
||||
// There's just the one palette, which is shared by all the windows,
|
||||
// DC's and whatever that get created.
|
||||
//
|
||||
// This makes apprunner vaguely usable!
|
||||
//
|
||||
// Printing might need some work.
|
||||
|
||||
// Common base
|
||||
class nsPaletteOS2 : public nsIPaletteOS2
|
||||
{
|
||||
protected:
|
||||
nsIDeviceContext *mContext; // don't hold a ref to avoid circularity
|
||||
PRUint8 *mGammaTable;
|
||||
|
||||
public:
|
||||
virtual nsresult Init( nsIDeviceContext *aContext,
|
||||
ULONG * = 0, ULONG = 0)
|
||||
{
|
||||
mContext = aContext;
|
||||
mContext->GetGammaTable( mGammaTable);
|
||||
return mContext == nsnull ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
long GetGPIColor( HPS hps, nscolor rgb)
|
||||
{
|
||||
long gcolor = MK_RGB( mGammaTable[NS_GET_R(rgb)],
|
||||
mGammaTable[NS_GET_G(rgb)],
|
||||
mGammaTable[NS_GET_B(rgb)]);
|
||||
return GpiQueryColorIndex( hps, 0, gcolor);
|
||||
}
|
||||
|
||||
virtual nsresult GetNSPalette( nsPalette &aPalette) const
|
||||
{
|
||||
aPalette = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsPaletteOS2()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mContext = nsnull;
|
||||
mGammaTable = 0;
|
||||
}
|
||||
|
||||
virtual ~nsPaletteOS2()
|
||||
{}
|
||||
};
|
||||
|
||||
// this isn't really an xpcom object, so don't allow anyone to get anything
|
||||
nsresult nsPaletteOS2::QueryInterface( const nsIID&, void**)
|
||||
{
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsPaletteOS2)
|
||||
NS_IMPL_RELEASE(nsPaletteOS2)
|
||||
|
||||
// Logical colour table, for 8bpp with no palette manager or explicit choice
|
||||
class nsLCOLPaletteOS2 : public nsPaletteOS2
|
||||
{
|
||||
ULONG *mTable;
|
||||
ULONG mSize;
|
||||
|
||||
public:
|
||||
nsresult Init( nsIDeviceContext *aContext,
|
||||
ULONG *pEntries, ULONG cEntries)
|
||||
{
|
||||
mTable = pEntries;
|
||||
mSize = cEntries;
|
||||
return nsPaletteOS2::Init( aContext);
|
||||
}
|
||||
|
||||
nsresult Select( HPS hps, nsIDeviceContext *)
|
||||
{
|
||||
BOOL rc = GpiCreateLogColorTable( hps, LCOL_RESET | LCOL_PURECOLOR,
|
||||
LCOLF_CONSECRGB, 0,
|
||||
mSize, (PLONG) mTable);
|
||||
if( !rc)
|
||||
PMERROR( "GpiCreateLogColorTable");
|
||||
return rc ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult Deselect( HPS hps)
|
||||
{
|
||||
BOOL rc = GpiCreateLogColorTable( hps, LCOL_RESET, 0, 0, 0, 0);
|
||||
return rc ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsLCOLPaletteOS2()
|
||||
{
|
||||
mTable = 0;
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
~nsLCOLPaletteOS2()
|
||||
{
|
||||
if( mTable) free( mTable);
|
||||
}
|
||||
};
|
||||
|
||||
// Palette manager palette, for 8bpp with palette manager
|
||||
class nsHPALPaletteOS2 : public nsPaletteOS2
|
||||
{
|
||||
HPAL mHPal;
|
||||
|
||||
public:
|
||||
nsresult Init( nsIDeviceContext *aContext,
|
||||
ULONG *pEntries, ULONG cEntries)
|
||||
{
|
||||
mHPal = GpiCreatePalette( 0/*hab*/, LCOL_PURECOLOR, LCOLF_CONSECRGB,
|
||||
cEntries, pEntries);
|
||||
free( pEntries);
|
||||
|
||||
return nsPaletteOS2::Init( aContext);
|
||||
}
|
||||
|
||||
nsresult GetNSPalette( nsPalette &aPalette) const
|
||||
{
|
||||
aPalette = (nsPalette) mHPal;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Select( HPS hps, nsIDeviceContext *aContext)
|
||||
{
|
||||
HPAL rc = GpiSelectPalette( hps, mHPal);
|
||||
if( rc == (HPAL) PAL_ERROR)
|
||||
{
|
||||
PMERROR( "GpiSelectPalette");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// okay, we could do with a window here. Unfortunately there's
|
||||
// no guarantee that this is going to return anything sensible.
|
||||
nsNativeWidget wdg = ((nsDeviceContextOS2 *) aContext)->mWidget;
|
||||
if( wdg)
|
||||
{
|
||||
ULONG ulDummy = 0;
|
||||
WinRealizePalette( (HWND)wdg, hps, &ulDummy);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Deselect( HPS hps)
|
||||
{
|
||||
HPAL rc = GpiSelectPalette( hps, 0);
|
||||
return rc == ((HPAL)PAL_ERROR) ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
nsHPALPaletteOS2()
|
||||
{
|
||||
mHPal = 0;
|
||||
}
|
||||
|
||||
~nsHPALPaletteOS2()
|
||||
{
|
||||
if( mHPal)
|
||||
GpiDeletePalette( mHPal);
|
||||
}
|
||||
};
|
||||
|
||||
// RGB colour table, for >8bpp
|
||||
class nsRGBPaletteOS2 : public nsPaletteOS2
|
||||
{
|
||||
public:
|
||||
nsresult Select( HPS hps, nsIDeviceContext *)
|
||||
{
|
||||
BOOL rc = GpiCreateLogColorTable( hps, LCOL_PURECOLOR,
|
||||
LCOLF_RGB, 0, 0, 0);
|
||||
if( !rc)
|
||||
PMERROR( "GpiCreateLogColorTable #2");
|
||||
return rc ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult Deselect( HPS hps)
|
||||
{
|
||||
BOOL rc = GpiCreateLogColorTable( hps, LCOL_RESET, 0, 0, 0, 0);
|
||||
return rc ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRGBPaletteOS2() {}
|
||||
~nsRGBPaletteOS2() {}
|
||||
};
|
||||
|
||||
nsresult NS_CreatePalette( nsIDeviceContext *aContext, nsIPaletteOS2 *&aPalette)
|
||||
{
|
||||
nsresult rc = NS_OK;
|
||||
IL_ColorSpace *colorSpace = 0;
|
||||
|
||||
nsPaletteOS2 *newPalette = 0;
|
||||
|
||||
rc = aContext->GetILColorSpace( colorSpace);
|
||||
if( NS_SUCCEEDED(rc))
|
||||
{
|
||||
if( NI_PseudoColor == colorSpace->type)
|
||||
{
|
||||
PULONG pPalette = (PULONG) calloc( COLOR_CUBE_SIZE, sizeof( ULONG));
|
||||
|
||||
// Now set the color cube entries.
|
||||
for( PRInt32 i = 0; i < COLOR_CUBE_SIZE; i++)
|
||||
{
|
||||
IL_RGB *map = colorSpace->cmap.map + i;
|
||||
pPalette[ i] = MK_RGB( map->red, map->green, map->blue);
|
||||
}
|
||||
|
||||
// this works, sorta. Should probably tell users,
|
||||
// or activate via a pref, or something.
|
||||
if( getenv( "MOZ_USE_LCOL"))
|
||||
newPalette = new nsLCOLPaletteOS2;
|
||||
else
|
||||
newPalette = new nsHPALPaletteOS2;
|
||||
rc = newPalette->Init( aContext, pPalette, COLOR_CUBE_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
newPalette = new nsRGBPaletteOS2;
|
||||
rc = newPalette->Init( aContext);
|
||||
}
|
||||
|
||||
IL_ReleaseColorSpace( colorSpace);
|
||||
}
|
||||
|
||||
if( NS_SUCCEEDED(rc))
|
||||
{
|
||||
NS_ADDREF(newPalette);
|
||||
aPalette = newPalette;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// Manage picking of colours via various GPI methods.
|
||||
// Created & (hopefully) destroyed by nsDeviceContextOS2; each rendering
|
||||
// context spun off from that dc holds a ref to it, and uses it to get things
|
||||
// right. Gamma correction done here too using the dc's table, so don't
|
||||
// go through gamma before GetGPIColor()'ing.
|
||||
//
|
||||
// !! What to do about A-channel ?
|
||||
|
||||
#ifndef _nspaletteos2_h
|
||||
#define _nspaletteos2_h
|
||||
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nscolor.h"
|
||||
|
||||
class nsIDeviceContext;
|
||||
|
||||
class nsIPaletteOS2 : public nsISupports
|
||||
{
|
||||
public:
|
||||
virtual long GetGPIColor( HPS hps, nscolor rgb) = 0;
|
||||
virtual nsresult Select( HPS hps, nsIDeviceContext *aContext) = 0;
|
||||
virtual nsresult Deselect( HPS hps) = 0;
|
||||
virtual nsresult GetNSPalette( nsPalette &aPalette) const = 0;
|
||||
};
|
||||
|
||||
// So yes, this could be an nsDeviceContextOS2 method, but this way is better
|
||||
// for modularisation. Oh yes.
|
||||
// Release when done.
|
||||
nsresult NS_CreatePalette( nsIDeviceContext *aContext,
|
||||
nsIPaletteOS2 *&aPalette);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// ToDo: nothing
|
||||
#include "nsGfxDefs.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nsRegionOS2.h"
|
||||
|
||||
// Crazy Region Space
|
||||
//
|
||||
// In OS/2, windows & presentation spaces have coord. systems with the
|
||||
// origin in the bottom left & positive going up.
|
||||
//
|
||||
// The rest of mozilla assumes a coord. system with the origin in the
|
||||
// top left & positive going down.
|
||||
//
|
||||
// Thus we have a host of methods to convert between the two when
|
||||
// drawing into a window, and so on.
|
||||
//
|
||||
// Regions are different: when they're defined and operations done on
|
||||
// them, there's no clue to the intended target. So we need another
|
||||
// way of defining regions. Do this using something which is very close
|
||||
// to XP space (actually much closer now we use nsRects instead of XP_Rects)
|
||||
// which can be envisaged as a reflection in the (XP space) line y = 0
|
||||
//
|
||||
// Hmm, perhaps it would cause less confusion not to mention this at all!
|
||||
|
||||
#define nsRgnPS (gModuleData.hpsScreen)
|
||||
|
||||
nsRegionOS2::nsRegionOS2()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
mRegion = 0;
|
||||
mRegionType = RGN_NULL;
|
||||
}
|
||||
|
||||
nsRegionOS2::~nsRegionOS2()
|
||||
{
|
||||
if( mRegion)
|
||||
if( !GpiDestroyRegion( nsRgnPS, mRegion))
|
||||
PMERROR( "GpiDestroyRegion (nsR)");
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsRegionOS2, nsIRegion::GetIID())
|
||||
|
||||
// Create empty region
|
||||
nsresult nsRegionOS2::Init()
|
||||
{
|
||||
mRegion = GpiCreateRegion( nsRgnPS, 0, 0);
|
||||
if( mRegion == RGN_ERROR)
|
||||
PMERROR("GpiCreateRegion");
|
||||
mRegionType = RGN_NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// assignment
|
||||
void nsRegionOS2::SetTo( const nsIRegion &aRegion)
|
||||
{
|
||||
nsRegionOS2 *pRegion = (nsRegionOS2 *) &aRegion;
|
||||
|
||||
mRegionType = GpiCombineRegion( nsRgnPS, mRegion, pRegion->mRegion,
|
||||
0, CRGN_COPY);
|
||||
}
|
||||
|
||||
void nsRegionOS2::SetTo( PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
if( 0 == mRegion)
|
||||
Init();
|
||||
|
||||
RECTL rcl = { aX, aY, aX + aWidth, aY + aHeight }; // in-ex
|
||||
|
||||
GpiSetRegion( nsRgnPS, mRegion, 1, &rcl);
|
||||
|
||||
mRegionType = (aWidth && aHeight) ? RGN_RECT : RGN_NULL;
|
||||
}
|
||||
|
||||
// Combine region with something; generic helpers
|
||||
void nsRegionOS2::combine( long lOp, PRInt32 aX, PRInt32 aY, PRInt32 aW, PRInt32 aH)
|
||||
{
|
||||
RECTL rcl = { aX, aY, aX + aW, aY + aH }; // in-ex
|
||||
HRGN rgn = GpiCreateRegion( nsRgnPS, 1, &rcl);
|
||||
if( rgn == RGN_ERROR)
|
||||
{
|
||||
PMERROR( "GpiCreateRegion #2 ");
|
||||
printf( "X Y W H is %d %d %d %d\n", aX, aY, aW, aH);
|
||||
}
|
||||
mRegionType = GpiCombineRegion( nsRgnPS, mRegion, mRegion, rgn, lOp);
|
||||
if( mRegionType == RGN_ERROR)
|
||||
PMERROR( "GpiCombineRegion #2 ");
|
||||
if( !GpiDestroyRegion( nsRgnPS, rgn))
|
||||
PMERROR( "GpiDestroyRegion (nsR::c)");
|
||||
}
|
||||
|
||||
void nsRegionOS2::combine( long lOp, const nsIRegion &aRegion)
|
||||
{
|
||||
nsRegionOS2 *pRegion = (nsRegionOS2 *)&aRegion;
|
||||
mRegionType = GpiCombineRegion( nsRgnPS, mRegion, mRegion,
|
||||
pRegion->mRegion, lOp);
|
||||
if( mRegionType == RGN_ERROR)
|
||||
PMERROR( "GpiCombineRegion");
|
||||
}
|
||||
|
||||
#define DECL_COMBINE(name,token) \
|
||||
void nsRegionOS2::name(const nsIRegion &aRegion) \
|
||||
{ combine( token, aRegion); } \
|
||||
\
|
||||
void nsRegionOS2::name( PRInt32 aX, PRInt32 aY, \
|
||||
PRInt32 aWidth, PRInt32 aHeight) \
|
||||
{ combine( token, aX, aY, aWidth, aHeight); }
|
||||
|
||||
DECL_COMBINE(Intersect,CRGN_AND)
|
||||
DECL_COMBINE(Union,CRGN_OR)
|
||||
DECL_COMBINE(Subtract,CRGN_DIFF)
|
||||
|
||||
// misc
|
||||
PRBool nsRegionOS2::IsEmpty()
|
||||
{
|
||||
return (mRegionType == RGN_NULL) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsRegionOS2::IsEqual( const nsIRegion &aRegion)
|
||||
{
|
||||
nsRegionOS2 *pRegion = (nsRegionOS2 *)&aRegion;
|
||||
|
||||
long lrc = GpiEqualRegion( nsRgnPS, mRegion, pRegion->mRegion);
|
||||
|
||||
return lrc == EQRGN_EQUAL ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
|
||||
void nsRegionOS2::GetBoundingBox( PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight)
|
||||
{
|
||||
if( mRegionType != RGN_NULL)
|
||||
{
|
||||
RECTL rcl;
|
||||
if( RGN_ERROR == GpiQueryRegionBox( nsRgnPS, mRegion, &rcl))
|
||||
PMERROR( "GpiQueryRegionBox");
|
||||
|
||||
*aX = rcl.xLeft;
|
||||
*aY = rcl.yBottom;
|
||||
*aWidth = rcl.xRight - rcl.xLeft; // in-ex, okay.
|
||||
*aHeight = rcl.yTop - rcl.yBottom;
|
||||
}
|
||||
else
|
||||
*aX = *aY = *aWidth = *aHeight = 0;
|
||||
}
|
||||
|
||||
// translate
|
||||
void nsRegionOS2::Offset( PRInt32 aXOffset, PRInt32 aYOffset)
|
||||
{
|
||||
POINTL ptl = { aXOffset, aYOffset };
|
||||
GpiOffsetRegion( nsRgnPS, mRegion, &ptl);
|
||||
}
|
||||
|
||||
// hittest - precise spec, rect must be completely contained.
|
||||
PRBool nsRegionOS2::ContainsRect( PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
RECTL rcl = { aX, aY, aX + aWidth, aY + aHeight }; // in-ex
|
||||
long lRC = GpiRectInRegion( nsRgnPS, mRegion, &rcl);
|
||||
return lRC == RRGN_INSIDE ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
|
||||
// Accessor for the CRS region
|
||||
nsresult nsRegionOS2::GetNativeRegion( void *&aRegion) const
|
||||
{
|
||||
aRegion = (void*) mRegion;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the complexity of the region
|
||||
nsresult nsRegionOS2::GetRegionComplexity( nsRegionComplexity &aComplexity) const
|
||||
{
|
||||
NS_ASSERTION( mRegionType != RGN_ERROR, "Bad region complexity");
|
||||
|
||||
switch( mRegionType)
|
||||
{
|
||||
case RGN_NULL: aComplexity = eRegionComplexity_empty; break;
|
||||
case RGN_RECT: aComplexity = eRegionComplexity_rect; break;
|
||||
default:
|
||||
case RGN_COMPLEX: aComplexity = eRegionComplexity_complex; break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Code recycled from os2fe/drawable.cpp (the good old days...)
|
||||
// The beautiful thing about this is that it works both ways: os/2
|
||||
// space in, Crazy Region Space out, and vice-versa.
|
||||
struct CGetRects
|
||||
{
|
||||
PRECTL pRects;
|
||||
ULONG ulUsed;
|
||||
ULONG ulGot;
|
||||
ULONG ulHeight;
|
||||
|
||||
CGetRects( ULONG h) : ulUsed( 0), ulGot( 10), ulHeight( h)
|
||||
{
|
||||
pRects = (PRECTL) malloc( 10 * sizeof( RECTL));
|
||||
}
|
||||
|
||||
~CGetRects() { free( pRects); }
|
||||
|
||||
inline void add( RECTL &rectl) // sneaky; might work...
|
||||
{
|
||||
if( ulUsed == ulGot)
|
||||
{
|
||||
ulGot += 10;
|
||||
pRects = (PRECTL) realloc( pRects, ulGot * sizeof( RECTL));
|
||||
}
|
||||
pRects[ ulUsed].xLeft = rectl.xLeft;
|
||||
pRects[ ulUsed].yBottom = ulHeight - rectl.yTop; // This is right.
|
||||
pRects[ ulUsed].xRight = rectl.xRight; // Trust me.
|
||||
pRects[ ulUsed].yTop = ulHeight - rectl.yBottom;
|
||||
ulUsed++;
|
||||
}
|
||||
};
|
||||
|
||||
// Big ugly function to accumulate lists of rectangles.
|
||||
// All logic is in parameters (as opposed to making a callback per rect) for
|
||||
// speed reasons (maybe spurious, but...)
|
||||
static void RealQueryRects( HRGN hrgn,
|
||||
HPS hps,
|
||||
nsRegionRectSet **aRects,
|
||||
CGetRects *aGetRects)
|
||||
{
|
||||
BOOL isRECTL = aRects ? FALSE : TRUE;
|
||||
|
||||
// right, this is far too complicated. What we want is a function to
|
||||
// query how many rectangles we need before we start...
|
||||
RECTL rects[ 10];
|
||||
RGNRECT rgnRect = { 1, 10, 0, RECTDIR_LFRT_TOPBOT };
|
||||
|
||||
for( ;;)
|
||||
{
|
||||
// get a batch of rectangles
|
||||
GpiQueryRegionRects( hps, hrgn, 0, &rgnRect, rects);
|
||||
// call them out
|
||||
for( PRUint32 i = 0; i < rgnRect.crcReturned; i++)
|
||||
{
|
||||
if( isRECTL)
|
||||
{
|
||||
aGetRects->add( rects[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// accumulate nsRects in the nsRegionRectSet structure
|
||||
|
||||
// first check for space
|
||||
if( (*aRects)->mNumRects == (*aRects)->mRectsLen)
|
||||
{
|
||||
*aRects = (nsRegionRectSet *)
|
||||
realloc( *aRects, sizeof( nsRegionRectSet) +
|
||||
((*aRects)->mNumRects + 9) * sizeof(nsRegionRect));
|
||||
(*aRects)->mRectsLen += 10;
|
||||
#ifdef DEBUG
|
||||
// !! If this happens lots, bump up initial allocation
|
||||
printf( "Allocating more regionrect space...\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
nsRegionRect *theRect = (*aRects)->mRects + (*aRects)->mNumRects;
|
||||
|
||||
theRect->x = rects[i].xLeft;
|
||||
theRect->y = rects[i].yBottom;
|
||||
theRect->width = rects[i].xRight - rects[i].xLeft; // in-ex
|
||||
theRect->height = rects[i].yTop - rects[i].yBottom;
|
||||
|
||||
(*aRects)->mNumRects++;
|
||||
}
|
||||
}
|
||||
// are we done ?
|
||||
if( rgnRect.crcReturned < rgnRect.crc) break;
|
||||
|
||||
// set up for the next batch
|
||||
rgnRect.ircStart += 10;
|
||||
}
|
||||
}
|
||||
|
||||
#define GetRects_Native(r,p,a) RealQueryRects( r, p, nsnull, a)
|
||||
#define GetRects_NS(r,p,a) RealQueryRects( r, p, a, nsnull)
|
||||
|
||||
HRGN nsRegionOS2::GetHRGN( PRUint32 ulHeight, HPS hps)
|
||||
{
|
||||
CGetRects getRects( ulHeight);
|
||||
|
||||
GetRects_Native( mRegion, nsRgnPS, &getRects);
|
||||
|
||||
return GpiCreateRegion( hps, getRects.ulUsed, getRects.pRects);
|
||||
}
|
||||
|
||||
// For copying from an existing region who has height & possibly diff. hdc
|
||||
nsresult nsRegionOS2::Init( HRGN copy, PRUint32 ulHeight, HPS hps)
|
||||
{
|
||||
CGetRects getRects( ulHeight);
|
||||
|
||||
GetRects_Native( copy, hps, &getRects);
|
||||
|
||||
Init();
|
||||
|
||||
mRegionType = GpiSetRegion( nsRgnPS, mRegion,
|
||||
getRects.ulUsed, getRects.pRects);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the region as an array of rects for the new compositor
|
||||
nsresult nsRegionOS2::GetRects( nsRegionRectSet **aRects)
|
||||
{
|
||||
if( !aRects)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if( *aRects == nsnull)
|
||||
{
|
||||
*aRects = (nsRegionRectSet *) malloc( sizeof( nsRegionRectSet) +
|
||||
9 * sizeof( nsRegionRect));
|
||||
(*aRects)->mNumRects = 0;
|
||||
(*aRects)->mRectsLen = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can reuse the structures (says the header).
|
||||
// That's quite sensible, actually.
|
||||
(*aRects)->mNumRects = 0;
|
||||
}
|
||||
|
||||
GetRects_NS( mRegion, nsRgnPS, aRects);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsRegionOS2::FreeRects( nsRegionRectSet *aRects)
|
||||
{
|
||||
if( !aRects)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
free( aRects);
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// Region object. From os2fe\regions.cpp.
|
||||
// Regions are defined in Crazy Region Space - see nsRegionOS2.cpp.
|
||||
|
||||
#ifndef _nsRegionOS2_h
|
||||
#define _nsRegionOS2_h
|
||||
|
||||
#include "nsIRegion.h"
|
||||
|
||||
typedef void (*nsRECTLInRegionFunc)(void *closure, RECTL &rectl);
|
||||
|
||||
class nsRegionOS2 : public nsIRegion
|
||||
{
|
||||
public:
|
||||
nsRegionOS2();
|
||||
virtual ~nsRegionOS2();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init();
|
||||
|
||||
virtual void SetTo( const nsIRegion &aRegion);
|
||||
virtual void SetTo( PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
virtual void Intersect( const nsIRegion &aRegion);
|
||||
virtual void Intersect( PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
virtual void Union( const nsIRegion &aRegion);
|
||||
virtual void Union( PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
virtual void Subtract( const nsIRegion &aRegion);
|
||||
virtual void Subtract( PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
virtual PRBool IsEmpty();
|
||||
virtual PRBool IsEqual( const nsIRegion &aRegion);
|
||||
virtual void GetBoundingBox( PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight);
|
||||
virtual void Offset( PRInt32 aXOffset, PRInt32 aYOffset);
|
||||
virtual PRBool ContainsRect( PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
|
||||
NS_IMETHOD GetRects( nsRegionRectSet **aRects);
|
||||
NS_IMETHOD FreeRects( nsRegionRectSet *aRects);
|
||||
|
||||
// Don't use this -- it returns a region defined in CRS.
|
||||
NS_IMETHOD GetNativeRegion( void *&aRegion) const;
|
||||
NS_IMETHOD GetRegionComplexity( nsRegionComplexity &aComplexity) const;
|
||||
|
||||
// OS/2 specific
|
||||
// get region in widget's coord space for given device
|
||||
HRGN GetHRGN( PRUint32 ulHeight, HPS hps);
|
||||
|
||||
// copy from another region defined in aWidget's space for a given device
|
||||
nsresult Init( HRGN copy, PRUint32 ulHeight, HPS hps);
|
||||
|
||||
private:
|
||||
void combine( long lOp, PRInt32 aX, PRInt32 aY, PRInt32 aW, PRInt32 aH);
|
||||
void combine( long lOp, const nsIRegion &aRegion);
|
||||
|
||||
HRGN mRegion;
|
||||
long mRegionType;
|
||||
};
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsRenderingContextOS2_h
|
||||
#define _nsRenderingContextOS2_h
|
||||
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIScriptObjectOwner.h"
|
||||
#include "nsIDOMRenderingContext.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nscoord.h"
|
||||
#include "nscolor.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
class nsIDeviceContext;
|
||||
class nsIFontMetrics;
|
||||
class nsIPaletteOS2;
|
||||
class nsString;
|
||||
class nsIWidget;
|
||||
class nsPoint;
|
||||
class nsFont;
|
||||
class nsRect;
|
||||
|
||||
struct GraphicsState;
|
||||
|
||||
#include "nsDrawingSurfaceOS2.h"
|
||||
|
||||
class nsRenderingContextOS2 : public nsIRenderingContext,
|
||||
public nsIDOMRenderingContext,
|
||||
public nsIScriptObjectOwner
|
||||
{
|
||||
public:
|
||||
nsRenderingContextOS2();
|
||||
virtual ~nsRenderingContextOS2();
|
||||
|
||||
void *operator new( size_t sz) {
|
||||
void *rv = new char[ sz];
|
||||
nsCRT::zero( rv, sz);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init( nsIDeviceContext* aContext, nsIWidget *aWindow);
|
||||
NS_IMETHOD Init( nsIDeviceContext* aContext, nsDrawingSurface aSurface);
|
||||
|
||||
NS_IMETHOD Reset();
|
||||
|
||||
NS_IMETHOD GetDeviceContext( nsIDeviceContext *&aDeviceContext);
|
||||
|
||||
NS_IMETHOD LockDrawingSurface( PRInt32 aX, PRInt32 aY,
|
||||
PRUint32 aWidth, PRUint32 aHeight,
|
||||
void **aBits,
|
||||
PRInt32 *aStride, PRInt32 *aWidthBytes,
|
||||
PRUint32 aFlags);
|
||||
NS_IMETHOD UnlockDrawingSurface();
|
||||
|
||||
NS_IMETHOD SelectOffScreenDrawingSurface( nsDrawingSurface aSurface);
|
||||
NS_IMETHOD GetDrawingSurface( nsDrawingSurface *aSurface);
|
||||
|
||||
NS_IMETHOD PushState();
|
||||
NS_IMETHOD PopState( PRBool &aClipEmpty);
|
||||
|
||||
NS_IMETHOD IsVisibleRect( const nsRect& aRect, PRBool &aIsVisible);
|
||||
|
||||
NS_IMETHOD SetClipRect( const nsRect& aRect, nsClipCombine aCombine, PRBool &aClipEmpty);
|
||||
NS_IMETHOD GetClipRect( nsRect &aRect, PRBool &aHasLocalClip);
|
||||
NS_IMETHOD SetClipRegion( const nsIRegion& aRegion, nsClipCombine aCombine, PRBool &aClipEmpty);
|
||||
NS_IMETHOD GetClipRegion( nsIRegion **aRegion);
|
||||
|
||||
NS_IMETHOD SetColor( nscolor aColor);
|
||||
NS_IMETHOD GetColor( nscolor &aColor) const;
|
||||
|
||||
NS_IMETHOD SetFont( const nsFont& aFont);
|
||||
NS_IMETHOD SetFont( nsIFontMetrics *aFontMetrics);
|
||||
|
||||
NS_IMETHOD GetFontMetrics( nsIFontMetrics*& aFontMetrics);
|
||||
|
||||
NS_IMETHOD Translate( nscoord aX, nscoord aY);
|
||||
NS_IMETHOD Scale( float aSx, float aSy);
|
||||
NS_IMETHOD GetCurrentTransform( nsTransform2D *&aTransform);
|
||||
|
||||
NS_IMETHOD SetLineStyle( nsLineStyle aLineStyle);
|
||||
NS_IMETHOD GetLineStyle( nsLineStyle &aLineStyle);
|
||||
|
||||
NS_IMETHOD CreateDrawingSurface( nsRect *aBounds, PRUint32 aSurfFlags, nsDrawingSurface &aSurface);
|
||||
NS_IMETHOD DestroyDrawingSurface( nsDrawingSurface aDS);
|
||||
|
||||
NS_IMETHOD DrawLine( nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1);
|
||||
NS_IMETHOD DrawPolyline( const nsPoint aPoints[], PRInt32 aNumPoints);
|
||||
|
||||
NS_IMETHOD DrawRect( const nsRect& aRect);
|
||||
NS_IMETHOD DrawRect( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
||||
NS_IMETHOD FillRect( const nsRect& aRect);
|
||||
NS_IMETHOD FillRect( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
||||
|
||||
NS_IMETHOD DrawPolygon( const nsPoint aPoints[], PRInt32 aNumPoints);
|
||||
NS_IMETHOD FillPolygon( const nsPoint aPoints[], PRInt32 aNumPoints);
|
||||
|
||||
NS_IMETHOD DrawEllipse( const nsRect& aRect);
|
||||
NS_IMETHOD DrawEllipse( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
||||
NS_IMETHOD FillEllipse( const nsRect& aRect);
|
||||
NS_IMETHOD FillEllipse( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
||||
|
||||
NS_IMETHOD DrawArc( const nsRect& aRect,
|
||||
float aStartAngle, float aEndAngle);
|
||||
NS_IMETHOD DrawArc( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
|
||||
float aStartAngle, float aEndAngle);
|
||||
NS_IMETHOD FillArc( const nsRect& aRect,
|
||||
float aStartAngle, float aEndAngle);
|
||||
NS_IMETHOD FillArc( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
|
||||
float aStartAngle, float aEndAngle);
|
||||
// String widths
|
||||
NS_IMETHOD GetWidth( char aC, nscoord &aWidth);
|
||||
NS_IMETHOD GetWidth( PRUnichar aC, nscoord &aWidth,
|
||||
PRInt32 *aFontID = nsnull);
|
||||
NS_IMETHOD GetWidth( const nsString &aString, nscoord &aWidth,
|
||||
PRInt32 *aFontID = nsnull);
|
||||
NS_IMETHOD GetWidth( const char* aString, nscoord &aWidth);
|
||||
NS_IMETHOD GetWidth( const char* aString, PRUint32 aLength,
|
||||
nscoord &aWidth);
|
||||
NS_IMETHOD GetWidth( const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord &aWidth, PRInt32 *aFontID = nsnull);
|
||||
|
||||
NS_IMETHOD DrawString( const char *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
const nscoord* aSpacing = nsnull);
|
||||
NS_IMETHOD DrawString( const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
PRInt32 aFontID = -1,
|
||||
const nscoord* aSpacing = nsnull);
|
||||
NS_IMETHOD DrawString( const nsString& aString,
|
||||
nscoord aX, nscoord aY,
|
||||
PRInt32 aFontID = -1,
|
||||
const nscoord* aSpacing = nsnull);
|
||||
|
||||
NS_IMETHOD DrawImage( nsIImage *aImage, nscoord aX, nscoord aY);
|
||||
NS_IMETHOD DrawImage( nsIImage *aImage, nscoord aX, nscoord aY,
|
||||
nscoord aWidth, nscoord aHeight);
|
||||
NS_IMETHOD DrawImage( nsIImage *aImage, const nsRect& aRect);
|
||||
NS_IMETHOD DrawImage( nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect);
|
||||
|
||||
NS_IMETHOD CopyOffScreenBits( nsDrawingSurface aSrcSurf,
|
||||
PRInt32 aSrcX, PRInt32 aSrcY,
|
||||
const nsRect &aDestBounds,
|
||||
PRUint32 aCopyFlags);
|
||||
|
||||
NS_IMETHOD GetHints( PRUint32 &aResult);
|
||||
|
||||
// nsIScriptObjectOwner
|
||||
NS_IMETHOD GetScriptObject( nsIScriptContext *aContext, void** aScriptObject);
|
||||
NS_IMETHOD SetScriptObject( void* aScriptObject);
|
||||
|
||||
// nsIDOMRenderingContext
|
||||
NS_DECL_IDOMRENDERINGCONTEXT
|
||||
|
||||
// Convert XP-rects to OS/2 space.
|
||||
// World coordinates given & required, double inclusive rcl wanted.
|
||||
void NS2PM_ININ( const nsRect &in, RECTL &rcl);
|
||||
// World coordinates given & required, inclusive-exclusive rcl wanted.
|
||||
void NS2PM_INEX( const nsRect &in, RECTL &rcl);
|
||||
|
||||
// Convert OS/2 rects to XP space.
|
||||
// World coords given & required, double-inclusive rcl wanted
|
||||
void PM2NS_ININ( const RECTL &in, nsRect &out);
|
||||
|
||||
// Convert XP points to OS/2 space.
|
||||
void NS2PM( PPOINTL aPointl, ULONG cPointls);
|
||||
|
||||
private:
|
||||
nsresult CommonInit();
|
||||
nsresult SetupPS( HPS oldPS, HPS newPS);
|
||||
void GetTargetHeight( PRUint32 &ht);
|
||||
|
||||
// Colour/font setting; call before drawing things.
|
||||
void SetupDrawingColor( BOOL bForce = FALSE);
|
||||
void SetupFontAndColor( BOOL bForce = FALSE);
|
||||
|
||||
// Primitive draw-ers
|
||||
void PMDrawRect( nsRect &rect, BOOL fill);
|
||||
void PMDrawPoly( const nsPoint aPoints[], PRInt32 aNumPoints, PRBool bFilled);
|
||||
void PMDrawArc( nsRect &rect, PRBool bFilled, PRBool bFull, PRInt32 start=0, PRInt32 end=0);
|
||||
|
||||
protected:
|
||||
nsIDeviceContext *mContext; // device context
|
||||
nsIPaletteOS2 *mPalette; // palette from the dc
|
||||
nsDrawingSurfaceOS2 *mSurface; // draw things here
|
||||
nsDrawingSurfaceOS2 *mFrontSurface; // if offscreen, this is onscreen
|
||||
nscolor mColor; // current colour
|
||||
nsLineStyle mLineStyle; // current line style
|
||||
nsTransform2D mTMatrix; // current xform matrix
|
||||
float mP2T; // cache pix-2-app factor from DC
|
||||
GraphicsState *mStateStack; // stack of graphics states
|
||||
nsIFontMetrics *mFontMetrics; // current font
|
||||
nsIFontMetrics *mCurrFontMetrics; // currently selected font
|
||||
nscolor mCurrDrawingColor;// currently selected drawing color
|
||||
nscolor mCurrTextColor; // currently selected text color
|
||||
nsLineStyle mCurrLineStyle; // currently selected line style
|
||||
void *mScriptObject; // crazy script object thing.
|
||||
};
|
||||
|
||||
inline void nsRenderingContextOS2::GetTargetHeight( PRUint32 &ht)
|
||||
{
|
||||
PRUint32 on, dummy, off;
|
||||
mSurface->GetDimensions( &dummy, &on);
|
||||
if( mSurface != mFrontSurface)
|
||||
{
|
||||
mFrontSurface->GetDimensions( &dummy, &off);
|
||||
if( off < on) on = off;
|
||||
}
|
||||
ht = on;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsAppShell.h"
|
||||
#include "nsHashtable.h"
|
||||
|
||||
// Appshell manager. Same threads must get the same appshell object,
|
||||
// or else the message queue will be taken over by the second (nested)
|
||||
// appshell and subsequently killed when it does. This is bad because
|
||||
// the main (first) appshell should still be running.
|
||||
|
||||
TID QueryCurrentTID();
|
||||
|
||||
class nsAppshellManager
|
||||
{
|
||||
HMTX mLock;
|
||||
nsHashtable *mTable;
|
||||
|
||||
struct ThreadKey : public nsVoidKey
|
||||
{
|
||||
ThreadKey() : nsVoidKey( (void*) QueryCurrentTID()) {}
|
||||
};
|
||||
|
||||
public:
|
||||
nsAppshellManager()
|
||||
{
|
||||
mTable = new nsHashtable;
|
||||
DosCreateMutexSem( 0, &mLock, 0, FALSE /*unowned*/);
|
||||
}
|
||||
|
||||
~nsAppshellManager()
|
||||
{
|
||||
DosCloseMutexSem( mLock);
|
||||
delete mTable;
|
||||
}
|
||||
|
||||
nsIAppShell *GetAppshell()
|
||||
{
|
||||
ThreadKey key;
|
||||
|
||||
DosRequestMutexSem( mLock, SEM_INDEFINITE_WAIT);
|
||||
|
||||
nsIAppShell *pShell = (nsIAppShell*) mTable->Get( &key);
|
||||
|
||||
if( nsnull == pShell)
|
||||
{
|
||||
pShell = new nsAppShell;
|
||||
mTable->Put( &key, (void*) pShell);
|
||||
}
|
||||
|
||||
DosReleaseMutexSem( mLock);
|
||||
|
||||
return pShell;
|
||||
}
|
||||
|
||||
void RemoveAppshell( nsIAppShell *aShell)
|
||||
{
|
||||
ThreadKey key;
|
||||
|
||||
DosRequestMutexSem( mLock, SEM_INDEFINITE_WAIT);
|
||||
|
||||
nsIAppShell *pShell = (nsIAppShell*) mTable->Get( &key);
|
||||
|
||||
if( pShell != aShell)
|
||||
printf( "Appshell object dying in a foreign thread\n");
|
||||
else
|
||||
mTable->Remove( &key);
|
||||
|
||||
DosReleaseMutexSem( mLock);
|
||||
}
|
||||
};
|
||||
|
||||
static nsAppshellManager *pManager = nsnull;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAppShell, nsIAppShell::GetIID())
|
||||
|
||||
// nsAppShell constructor
|
||||
nsAppShell::nsAppShell()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mDispatchListener = 0;
|
||||
mHab = 0; mHmq = 0;
|
||||
mQuitNow = FALSE;
|
||||
memset( &mQmsg, 0, sizeof mQmsg);
|
||||
}
|
||||
|
||||
nsresult nsAppShell::SetDispatchListener( nsDispatchListener *aDispatchListener)
|
||||
{
|
||||
mDispatchListener = aDispatchListener;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Create the application shell
|
||||
nsresult nsAppShell::Create( int */*argc*/, char **/*argv*/)
|
||||
{
|
||||
// It is possible that there already is a HAB/HMQ for this thread.
|
||||
// This condition arises when an event queue (underlying, PLEvent) is
|
||||
// created before the appshell.
|
||||
// When this happens, we must take over ownership of these existing
|
||||
// objects (and so destroy them when we go, too).
|
||||
|
||||
if( FALSE == WinQueryQueueInfo( HMQ_CURRENT, 0, 0))
|
||||
{
|
||||
mHab = WinInitialize( 0);
|
||||
mHmq = WinCreateMsgQueue( mHab, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
mHab = 0; // HABs don't actually seem to be checked, ever.
|
||||
// But 0 == (current pid,current tid)
|
||||
mHmq = HMQ_CURRENT;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Enter a message handler loop
|
||||
nsresult nsAppShell::Run()
|
||||
{
|
||||
if( !mHmq) return NS_ERROR_FAILURE; // (mHab = 0 is okay)
|
||||
|
||||
// Add a reference to deal with async. shutdown
|
||||
NS_ADDREF_THIS();
|
||||
|
||||
// XXX if we're HMQ_CURRENT, peek the first message & get the right one ?
|
||||
|
||||
// Process messages
|
||||
for( ;;)
|
||||
{
|
||||
if( TRUE == WinGetMsg( mHab, &mQmsg, 0, 0, 0))
|
||||
{
|
||||
WinDispatchMsg( mHab, &mQmsg);
|
||||
}
|
||||
else
|
||||
{ // WM_QUIT
|
||||
if( mQmsg.hwnd)
|
||||
// send WM_SYSCOMMAND, SC_CLOSE to window (tasklist close)
|
||||
WinSendMsg( mQmsg.hwnd, WM_SYSCOMMAND, MPFROMSHORT(SC_CLOSE), 0);
|
||||
else
|
||||
{
|
||||
if( mQuitNow) // Don't want to close the app when a window is
|
||||
break; // closed, just when our `Exit' is called.
|
||||
}
|
||||
}
|
||||
|
||||
if( mDispatchListener)
|
||||
mDispatchListener->AfterDispatch();
|
||||
}
|
||||
|
||||
// reset mQuitNow flag for re-entrant appshells
|
||||
mQuitNow = FALSE;
|
||||
|
||||
// Release the reference we added earlier
|
||||
Release();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// GetNativeData - return the HMQ for NS_NATIVE_SHELL
|
||||
void *nsAppShell::GetNativeData( PRUint32 aDataType)
|
||||
{
|
||||
void *rc = 0;
|
||||
|
||||
switch( aDataType)
|
||||
{
|
||||
case NS_NATIVE_SHELL: rc = (void*) mHmq; break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Exit a message handler loop
|
||||
nsresult nsAppShell::Exit()
|
||||
{
|
||||
NS_ASSERTION( mQuitNow == FALSE, "Double AppShell::Exit");
|
||||
mQuitNow = TRUE;
|
||||
WinPostQueueMsg( mHmq, WM_QUIT, 0, 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsAppShell destructor
|
||||
nsAppShell::~nsAppShell()
|
||||
{
|
||||
WinDestroyMsgQueue( mHmq);
|
||||
WinTerminate( mHab);
|
||||
}
|
||||
|
||||
// These are for modal dialogs and also tres weird.
|
||||
//
|
||||
// XXX must handle WM_QUIT sensibly (close window)
|
||||
// -- dependency on xptoolkit dialogs being close by other means.
|
||||
//
|
||||
nsresult nsAppShell::GetNativeEvent( PRBool &aRealEvent, void *&aEvent)
|
||||
{
|
||||
BOOL isNotQuit = WinGetMsg( mHab, &mQmsg, 0, 0, 0);
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
if( isNotQuit)
|
||||
{
|
||||
aRealEvent = PR_TRUE;
|
||||
rc = NS_OK;
|
||||
aEvent = &mQmsg;
|
||||
}
|
||||
else
|
||||
aRealEvent = PR_FALSE;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsAppShell::DispatchNativeEvent( PRBool /*aRealEvent*/, void */*aEvent*/)
|
||||
{
|
||||
WinDispatchMsg( mHab, &mQmsg);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsAppShell::EventIsForModalWindow( PRBool aRealEvent,
|
||||
void */*aEvent*/,
|
||||
nsIWidget *aWidget,
|
||||
PRBool *aForWindow)
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
if( PR_FALSE == aRealEvent)
|
||||
{
|
||||
*aForWindow = PR_FALSE;
|
||||
rc = NS_OK;
|
||||
}
|
||||
else if( nsnull != aWidget)
|
||||
{
|
||||
// Set aForWindow if either:
|
||||
// * the message is for a descendent of the given window
|
||||
// * the message is for another window, but is a message which
|
||||
// should be allowed for a disabled window.
|
||||
|
||||
PRBool isMouseEvent = PR_FALSE;
|
||||
PRBool isInWindow = PR_FALSE;
|
||||
|
||||
// Examine the target window & find the frame
|
||||
// XXX should GetNativeData() use GetMainWindow() ?
|
||||
HWND hwnd = (HWND)aWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
hwnd = WinQueryWindow(hwnd, QW_PARENT);
|
||||
|
||||
if( hwnd == mQmsg.hwnd || WinIsChild( mQmsg.hwnd, hwnd))
|
||||
isInWindow = PR_TRUE;
|
||||
|
||||
// XXX really ought to do something about focus here
|
||||
|
||||
if( !isInWindow)
|
||||
{
|
||||
// Block mouse messages for non-modal windows
|
||||
if( mQmsg.msg >= WM_MOUSEFIRST && mQmsg.msg <= WM_MOUSELAST)
|
||||
isMouseEvent = PR_TRUE;
|
||||
else if( mQmsg.msg >= WM_MOUSETRANSLATEFIRST &&
|
||||
mQmsg.msg <= WM_MOUSETRANSLATELAST)
|
||||
isMouseEvent = PR_TRUE;
|
||||
else if( mQmsg.msg == WMU_MOUSEENTER || mQmsg.msg == WMU_MOUSELEAVE)
|
||||
isMouseEvent = PR_TRUE;
|
||||
}
|
||||
|
||||
// set dispatch indicator
|
||||
*aForWindow = isInWindow || !isMouseEvent;
|
||||
|
||||
rc = NS_OK;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
extern "C" nsresult NS_CreateAppshell( nsIAppShell **aAppShell)
|
||||
{
|
||||
if( !aAppShell)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
BOOL bFirstTime = FALSE;
|
||||
|
||||
if( !pManager)
|
||||
{
|
||||
bFirstTime = TRUE;
|
||||
pManager = new nsAppshellManager;
|
||||
}
|
||||
|
||||
*aAppShell = pManager->GetAppshell();
|
||||
|
||||
if( bFirstTime)
|
||||
gModuleData.Init( *aAppShell);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the current TID [vacpp doesn't have gettid()]
|
||||
TID QueryCurrentTID()
|
||||
{
|
||||
PTIB pTib = 0;
|
||||
PPIB pPib = 0;
|
||||
DosGetInfoBlocks( &pTib, &pPib);
|
||||
return pTib->tib_ptib2->tib2_ultid;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsAppShell_h
|
||||
#define _nsAppShell_h
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsIAppShell.h"
|
||||
|
||||
// Native PM Application shell wrapper.
|
||||
class nsAppShell : public nsIAppShell
|
||||
{
|
||||
public:
|
||||
nsAppShell();
|
||||
virtual ~nsAppShell();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIAppShell
|
||||
NS_IMETHOD Create( int *argc, char **argv);
|
||||
NS_IMETHOD SetDispatchListener( nsDispatchListener *aDispatchListener);
|
||||
NS_IMETHOD Spinup() { return NS_OK; }
|
||||
NS_IMETHOD Run();
|
||||
NS_IMETHOD Spindown() { return NS_OK; }
|
||||
NS_IMETHOD Exit();
|
||||
|
||||
NS_IMETHOD GetNativeEvent( PRBool &aRealEvent, void *&aEvent);
|
||||
NS_IMETHOD EventIsForModalWindow( PRBool aRealEvent, void *aEvent,
|
||||
nsIWidget *aWidget, PRBool *aForWindow);
|
||||
NS_IMETHOD DispatchNativeEvent( PRBool aRealEvent, void *aEvent);
|
||||
|
||||
// return the HMQ for NS_NATIVE_SHELL, fwiw
|
||||
virtual void *GetNativeData( PRUint32 aDataType);
|
||||
|
||||
private:
|
||||
nsDispatchListener *mDispatchListener;
|
||||
HAB mHab;
|
||||
HMQ mHmq;
|
||||
BOOL mQuitNow;
|
||||
QMSG mQmsg;
|
||||
};
|
||||
|
||||
// obtain an appropriate appshell object
|
||||
extern "C" nsresult NS_CreateAppshell( nsIAppShell **aAppShell);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsBaseList.h"
|
||||
#include "nsStringUtil.h"
|
||||
|
||||
// Basic things for talking to listboxen.
|
||||
// Code shared by listbox & combobox controls.
|
||||
//
|
||||
// Very straight-forward; potential DBCS/Unicode problems as ever.
|
||||
|
||||
// return false if index is silly
|
||||
PRBool nsBaseList::CheckIndex( PRInt32 &index)
|
||||
{
|
||||
short sItems = GetItemCount();
|
||||
if( index == -1)
|
||||
index = sItems - 1;
|
||||
|
||||
return index >= sItems ? PR_FALSE : PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult nsBaseList::AddItemAt( nsString &aItem, PRInt32 aPosition)
|
||||
{
|
||||
NS_ALLOC_STR_BUF(buf, aItem, 256);
|
||||
|
||||
short iPos = aPosition;
|
||||
if( iPos == -1)
|
||||
iPos = LIT_END;
|
||||
|
||||
SendMsg( LM_INSERTITEM, MPFROMSHORT(iPos), MPFROMP(buf));
|
||||
|
||||
NS_FREE_STR_BUF(buf);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Despite what the comment says, return the found index.
|
||||
PRInt32 nsBaseList::FindItem( nsString &aItem, PRInt32 aStartPos)
|
||||
{
|
||||
PRInt32 ret = -1;
|
||||
|
||||
if( PR_TRUE == CheckIndex( aStartPos))
|
||||
{
|
||||
NS_ALLOC_STR_BUF(buf, aItem, 256);
|
||||
|
||||
short sStart = aStartPos;
|
||||
if( sStart == 0)
|
||||
sStart = LIT_FIRST;
|
||||
|
||||
MRESULT rc = SendMsg( LM_SEARCHSTRING,
|
||||
MPFROM2SHORT(LSS_CASESENSITIVE,sStart),
|
||||
MPFROMP(buf));
|
||||
ret = SHORT1FROMMR(rc);
|
||||
|
||||
if( ret == LIT_NONE)
|
||||
ret = -1;
|
||||
|
||||
NS_FREE_STR_BUF(buf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
PRInt32 nsBaseList::GetItemCount()
|
||||
{
|
||||
return SHORT1FROMMR( SendMsg( LM_QUERYITEMCOUNT));
|
||||
}
|
||||
|
||||
PRBool nsBaseList::RemoveItemAt( PRInt32 aPosition)
|
||||
{
|
||||
PRBool rc = CheckIndex( aPosition);
|
||||
|
||||
if( rc == PR_TRUE)
|
||||
SendMsg( LM_DELETEITEM, MPFROMSHORT(aPosition));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
PRBool nsBaseList::GetItemAt( nsString& anItem, PRInt32 aPosition)
|
||||
{
|
||||
PRBool rc = CheckIndex( aPosition);
|
||||
|
||||
if( rc == PR_TRUE)
|
||||
{
|
||||
// first get text length
|
||||
short len = SHORT1FROMMR( SendMsg( LM_QUERYITEMTEXTLENGTH,
|
||||
MPFROMSHORT(aPosition)));
|
||||
|
||||
NS_ALLOC_CHAR_BUF(buf,256,len+1);
|
||||
|
||||
// now get text & fill in string
|
||||
SendMsg( LM_QUERYITEMTEXT, MPFROM2SHORT(aPosition,len+1), MPFROMP(buf));
|
||||
anItem.SetString(buf);
|
||||
|
||||
NS_FREE_CHAR_BUF(buf);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsBaseList::GetSelectedItem( nsString &aItem)
|
||||
{
|
||||
PRInt32 sel = GetSelectedIndex();
|
||||
if( sel != -1)
|
||||
GetItemAt( aItem, sel);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 nsBaseList::GetSelectedIndex()
|
||||
{
|
||||
short sel = SHORT1FROMMR( SendMsg( LM_QUERYSELECTION,
|
||||
MPFROMSHORT(LIT_FIRST)));
|
||||
if( sel == LIT_NONE)
|
||||
sel = -1;
|
||||
|
||||
return sel;
|
||||
}
|
||||
|
||||
nsresult nsBaseList::SelectItem( PRInt32 aPosition)
|
||||
{
|
||||
if( PR_TRUE == CheckIndex( aPosition))
|
||||
SendMsg( LM_SELECTITEM, MPFROMSHORT(aPosition), MPFROMLONG(TRUE));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsBaseList::Deselect()
|
||||
{
|
||||
SendMsg( LM_SELECTITEM, MPFROMSHORT(LIT_NONE));
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// nscanvas - basic window class that dispatches paint events.
|
||||
|
||||
#include "nscanvas.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include <stdio.h>
|
||||
|
||||
nsCanvas::nsCanvas() : mIsTLB(FALSE)
|
||||
{}
|
||||
|
||||
|
||||
// Called in the PM thread.
|
||||
void nsCanvas::RealDoCreate( HWND hwndP, nsWindow *aParent, const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext, nsIAppShell *aAppShell,
|
||||
nsWidgetInitData *aInitData, HWND hwndO)
|
||||
{
|
||||
if( aInitData && aInitData->mBorderStyle == eBorderStyle_BorderlessTopLevel)
|
||||
{
|
||||
// Untested hackery for (eg.) drop-downs on gfx-drawn comboboxes
|
||||
//
|
||||
// * Examine the window-type field in any init data.
|
||||
// * If this is set to 'borderless top-level' then
|
||||
// * Parent window to desktop
|
||||
// * Owner window to the frame of the xptoolkit parent
|
||||
// * Record xptoolkit parent because coordinates are relative to it.
|
||||
// * Pray that gecko will close the popup before trying to scroll content!
|
||||
|
||||
mIsTLB = TRUE;
|
||||
|
||||
// Find the frame.
|
||||
HWND hwndFrame = hwndP;
|
||||
while( !(FI_FRAME & (ULONG)WinSendMsg( hwndFrame, WM_QUERYFRAMEINFO, 0, 0)))
|
||||
hwndFrame = WinQueryWindow( hwndFrame, QW_PARENT);
|
||||
|
||||
// Create the window. Parent to desktop, owner to the frame (moving works),
|
||||
// maintain the xptoolkit parent, which handles coordinate resolution.
|
||||
nsWindow::RealDoCreate( HWND_DESKTOP, aParent, aRect,
|
||||
aHandleEventFunction, aContext,
|
||||
aAppShell, aInitData, hwndFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just pass thru'
|
||||
nsWindow::RealDoCreate( hwndP, aParent, aRect, aHandleEventFunction,
|
||||
aContext, aAppShell, aInitData, hwndO);
|
||||
}
|
||||
}
|
||||
|
||||
// Need to override this because the coords passed in are in OS/2 space but
|
||||
// relative to the xptoolkit parent.
|
||||
|
||||
BOOL nsCanvas::SetWindowPos( HWND ib, long x, long y,
|
||||
long cx, long cy, ULONG flags)
|
||||
{
|
||||
POINTL ptl = { x, y };
|
||||
if( mIsTLB)
|
||||
WinMapWindowPoints( (HWND) mParent->GetNativeData(NS_NATIVE_WIDGET),
|
||||
HWND_DESKTOP, &ptl, 1);
|
||||
return nsWindow::SetWindowPos( ib, ptl.x, ptl.y, cx, cy, flags);
|
||||
}
|
||||
|
||||
PRBool nsCanvas::OnReposition( PSWP pSwp)
|
||||
{
|
||||
PRBool rc = PR_FALSE;
|
||||
|
||||
if( mIsTLB)
|
||||
{
|
||||
if( pSwp->fl & SWP_MOVE && !(pSwp->fl & SWP_MINIMIZE))
|
||||
rc = OnMove( pSwp->x, gModuleData.szScreen.cy - pSwp->y - pSwp->cy);
|
||||
if( pSwp->fl & SWP_SIZE && !(pSwp->fl & SWP_MINIMIZE))
|
||||
rc = OnResize( pSwp->cx, pSwp->cy);
|
||||
}
|
||||
else
|
||||
rc = nsWindow::OnReposition( pSwp);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
PRBool nsCanvas::OnPaint()
|
||||
{
|
||||
PRBool rc = PR_FALSE;
|
||||
|
||||
if( mContext && (mEventCallback || mEventListener))
|
||||
{
|
||||
// Get rect to redraw and validate window
|
||||
#if 0
|
||||
RECTL rcl;
|
||||
WinQueryUpdateRect( mWnd, &rcl);
|
||||
WinValidateRect( mWnd, &rcl, TRUE);
|
||||
|
||||
if( rcl.xLeft || rcl.xRight || rcl.yBottom || rcl.yTop)
|
||||
{
|
||||
// build XP rect from in-ex window rect
|
||||
nsRect rect;
|
||||
rect.x = rcl.xLeft;
|
||||
rect.y = GetClientHeight() - rcl.yTop;
|
||||
rect.width = rcl.xRight - rcl.xLeft;
|
||||
rect.height = rcl.yTop - rcl.yBottom;
|
||||
|
||||
// build & dispatch paint event
|
||||
nsPaintEvent event;
|
||||
InitEvent( event, NS_PAINT);
|
||||
event.rect = ▭
|
||||
event.eventStructType = NS_PAINT_EVENT;
|
||||
event.renderingContext = GetRenderingContext();
|
||||
rc = DispatchEventInternal( &event);
|
||||
|
||||
NS_RELEASE( event.renderingContext);
|
||||
}
|
||||
#else
|
||||
RECTL rcl = { 0 };
|
||||
HPS thePS = (HPS) GetNativeData( NS_NATIVE_GRAPHIC);
|
||||
thePS = WinBeginPaint( mWnd, thePS, &rcl);
|
||||
|
||||
if( rcl.xLeft || rcl.xRight || rcl.yBottom || rcl.yTop)
|
||||
{
|
||||
// build XP rect from in-ex window rect
|
||||
nsRect rect;
|
||||
rect.x = rcl.xLeft;
|
||||
rect.y = GetClientHeight() - rcl.yTop;
|
||||
rect.width = rcl.xRight - rcl.xLeft;
|
||||
rect.height = rcl.yTop - rcl.yBottom;
|
||||
|
||||
// build & dispatch paint event
|
||||
nsPaintEvent event;
|
||||
InitEvent( event, NS_PAINT);
|
||||
event.rect = ▭
|
||||
event.eventStructType = NS_PAINT_EVENT;
|
||||
event.renderingContext = GetRenderingContext();
|
||||
rc = DispatchEventInternal( &event);
|
||||
|
||||
NS_RELEASE( event.renderingContext);
|
||||
}
|
||||
|
||||
WinEndPaint( thePS);
|
||||
FreeNativeData( (void*)thePS, NS_NATIVE_GRAPHIC);
|
||||
#endif
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Realize-palette. I reckon only top-level windows get the message, so
|
||||
// there's code in frame to broadcast it to children.
|
||||
PRBool nsCanvas::OnRealizePalette()
|
||||
{
|
||||
PRBool rc = PR_FALSE;
|
||||
|
||||
// Get palette info from device
|
||||
nsPaletteInfo palInfo;
|
||||
mContext->GetPaletteInfo( palInfo);
|
||||
|
||||
if( mPS && palInfo.isPaletteDevice && palInfo.palette)
|
||||
{
|
||||
// An onscreen nsDrawingSurface has been created for the window,
|
||||
// and we have a palette. So realize it.
|
||||
ULONG cclr;
|
||||
long palrc = WinRealizePalette( mWnd, mPS, &cclr);
|
||||
if( palrc && palrc != PAL_ERROR)
|
||||
// Colours have changed, redraw.
|
||||
WinInvalidateRect( mWnd, 0, FALSE);
|
||||
|
||||
rc = PR_TRUE;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
PRBool nsCanvas::OnKey( MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
nsWindow::OnKey( mp1, mp2);
|
||||
return PR_TRUE; // Gecko doesn't expect unhandled events to propagate
|
||||
}
|
||||
|
||||
extern BOOL g_bHandlingMouseClick;
|
||||
|
||||
PRBool nsCanvas::DispatchMouseEvent( PRUint32 msg, int clickcount,
|
||||
MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
PRBool rc = PR_FALSE;
|
||||
|
||||
// Stop multiple messages for the same PM action
|
||||
if( g_bHandlingMouseClick)
|
||||
return rc;
|
||||
|
||||
// Don't capture mb2 so that drag'n'drop works.
|
||||
|
||||
if( mEventCallback || mMouseListener)
|
||||
{
|
||||
switch( msg)
|
||||
{
|
||||
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
||||
WinSetCapture( HWND_DESKTOP, mWnd);
|
||||
break;
|
||||
|
||||
case NS_MOUSE_LEFT_BUTTON_UP:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
||||
WinSetCapture( HWND_DESKTOP, 0); // release
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rc = nsWindow::DispatchMouseEvent( msg, clickcount, mp1, mp2);
|
||||
}
|
||||
|
||||
// Mousemove messages mustn't propagate to get cursors working. Try commenting
|
||||
// this block out & then move the mouse over a link.
|
||||
|
||||
if( msg == NS_MOUSE_MOVE)
|
||||
rc = PR_TRUE;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Creation hooks
|
||||
static BOOL bRegistered;
|
||||
PCSZ nsCanvas::WindowClass()
|
||||
{
|
||||
if( !bRegistered)
|
||||
{
|
||||
BOOL rc = WinRegisterClass( 0 /*hab*/, NSCANVASCLASS,
|
||||
WinDefWindowProc, 0, 4);
|
||||
NS_ASSERTION(rc, "Couldn't register canvas class");
|
||||
bRegistered = TRUE;
|
||||
}
|
||||
|
||||
return (PCSZ) NSCANVASCLASS;
|
||||
}
|
||||
|
||||
ULONG nsCanvas::WindowStyle()
|
||||
{
|
||||
return BASE_CONTROL_STYLE | WS_CLIPCHILDREN;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nscanvas_h
|
||||
#define _nscanvas_h
|
||||
|
||||
// nscanvas - this is the NS_CHILD_CID class which contains content.
|
||||
// The main code added in here is to do painting.
|
||||
|
||||
#include "nswindow.h"
|
||||
|
||||
class nsCanvas : public nsWindow
|
||||
{
|
||||
public:
|
||||
nsCanvas();
|
||||
|
||||
protected:
|
||||
// So we can do the right thing for 'top-level borderless' widgets (popups)
|
||||
virtual void RealDoCreate( HWND hwndP, nsWindow *aParent,
|
||||
const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext,
|
||||
nsIAppShell *aAppShell,
|
||||
nsWidgetInitData *aInitData,
|
||||
HWND hwndOwner);
|
||||
|
||||
virtual BOOL SetWindowPos( HWND hwndInsertBehind, long x, long y,
|
||||
long cx, long cy, unsigned long flags);
|
||||
|
||||
virtual PRBool OnReposition( PSWP pSwp);
|
||||
virtual PRBool OnPaint();
|
||||
virtual PRBool OnKey( MPARAM mp1, MPARAM mp2);
|
||||
virtual PRBool OnRealizePalette();
|
||||
virtual PRBool DispatchMouseEvent( PRUint32 msg, int clickcount,
|
||||
MPARAM mp1, MPARAM mp2);
|
||||
virtual PCSZ WindowClass();
|
||||
virtual ULONG WindowStyle();
|
||||
|
||||
BOOL mIsTLB;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// Check button control
|
||||
|
||||
#include "nsCheckButton.h"
|
||||
|
||||
// XP-com
|
||||
NS_IMPL_ADDREF(nsCheckButton)
|
||||
NS_IMPL_RELEASE(nsCheckButton)
|
||||
|
||||
nsresult nsCheckButton::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
nsresult result = nsWindow::QueryInterface( aIID, aInstancePtr);
|
||||
|
||||
if( result == NS_NOINTERFACE && aIID.Equals( nsICheckButton::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsICheckButton*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMPL_LABEL(nsCheckButton)
|
||||
|
||||
// checked-ness
|
||||
nsresult nsCheckButton::GetState( PRBool &aState)
|
||||
{
|
||||
MRESULT rc = mOS2Toolkit->SendMsg( mWnd, BM_QUERYCHECK);
|
||||
aState = SHORT1FROMMR(rc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsCheckButton::SetState( const PRBool aState)
|
||||
{
|
||||
mOS2Toolkit->SendMsg( mWnd, BM_SETCHECK, MPFROMLONG(aState));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Creation hooks
|
||||
PCSZ nsCheckButton::WindowClass()
|
||||
{
|
||||
return WC_BUTTON;
|
||||
}
|
||||
|
||||
ULONG nsCheckButton::WindowStyle()
|
||||
{
|
||||
return BASE_CONTROL_STYLE | BS_CHECKBOX;
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsClipboard.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
#include <unidef.h> // for UniStrlen
|
||||
|
||||
// The relation between mozilla's mime formats and those understood by the
|
||||
// clipboard is a little hazy, mostly in the areas of images.
|
||||
//
|
||||
// Could be a lot cleverer & use delayed rendering or something to provide
|
||||
// a consumer with text when what we've got is unicode, or whatever.
|
||||
|
||||
// Okay, I'm not entirely sure why I did this in this way; it just sortof grew
|
||||
// like this...
|
||||
|
||||
typedef PRUint32 (*ImportDataFn)( void *pData, void **pDataOut);
|
||||
typedef PRUint32 (*ExportDataFn)( void *pDataIn, PRUint32 cData, void *pBuffer);
|
||||
|
||||
struct FormatRecord
|
||||
{
|
||||
const char *szMimeType;
|
||||
ULONG ulClipboardFmt;
|
||||
const char *szFmtName;
|
||||
ImportDataFn pfnImport;
|
||||
ExportDataFn pfnExport;
|
||||
};
|
||||
|
||||
// scaffolding
|
||||
nsClipboard::nsClipboard()
|
||||
{}
|
||||
|
||||
nsClipboard::~nsClipboard()
|
||||
{}
|
||||
|
||||
nsresult nsClipboard::SetNativeClipboardData()
|
||||
{
|
||||
return DoClipboardAction( nsClipboard::Write);
|
||||
}
|
||||
|
||||
nsresult nsClipboard::GetNativeClipboardData( nsITransferable *aTransferable)
|
||||
{
|
||||
nsITransferable *tmp = mTransferable;
|
||||
mTransferable = aTransferable;
|
||||
nsresult rc = DoClipboardAction( nsClipboard::Read);
|
||||
mTransferable = tmp;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Native clipboard.
|
||||
//
|
||||
// We do slightly odd things in order to store the length of the data
|
||||
// in the object: for non textual data, the first 4 bytes is an ULONG
|
||||
// containing the length of the REST of the data. May change this.
|
||||
//
|
||||
|
||||
|
||||
// Get some data from the clipboard
|
||||
void nsClipboard::GetClipboardData( nsString *aFlavour)
|
||||
{
|
||||
FormatRecord *pRecord;
|
||||
ULONG ulFmt = GetFormatID( aFlavour, &pRecord);
|
||||
PULONG pData = (PULONG) WinQueryClipbrdData( 0/*hab*/, ulFmt);
|
||||
|
||||
if( pData)
|
||||
{
|
||||
PRUint32 cbData = pRecord->pfnImport( pData, (void**) &pData);
|
||||
|
||||
// XXX any guesses how we could decode a HBITMAP into gif/png/jpeg data??
|
||||
//
|
||||
// We have libpng ready to use, which is well documented & configurable.
|
||||
// It should be easy to write a routine to convert a bitmap directly to
|
||||
// an in-memory buffer as required here.
|
||||
//
|
||||
// http://www.physik.fu-berlin.de/edv_docu/documentation/libpng/libpng.txt
|
||||
|
||||
// unfortunately we need to copy the data because the transferable
|
||||
// needs to be able to delete [] it.
|
||||
PRUint8 *pMozData = new PRUint8 [ cbData ];
|
||||
memcpy( pMozData, pData, cbData);
|
||||
mTransferable->SetTransferData( aFlavour, pMozData, cbData);
|
||||
}
|
||||
}
|
||||
|
||||
// Set some data onto the clipboard
|
||||
void nsClipboard::SetClipboardData( nsString *aFlavour)
|
||||
{
|
||||
void *pMozData = nsnull, *pData = nsnull;
|
||||
PRUint32 cbMozData = 0, cbData = 0;
|
||||
|
||||
// Get the data from the transferable
|
||||
mTransferable->GetTransferData( aFlavour, &pMozData, &cbMozData);
|
||||
|
||||
// Figure out how much memory we need to store the native version
|
||||
FormatRecord *pRecord;
|
||||
GetFormatID( aFlavour, &pRecord);
|
||||
cbData = pRecord->pfnExport( pMozData, cbMozData, 0);
|
||||
|
||||
// allocatate some memory to put the data in
|
||||
APIRET rc = DosAllocSharedMem( &pData, nsnull, cbData,
|
||||
PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE);
|
||||
if( !rc)
|
||||
{
|
||||
// copy across & pin up.
|
||||
pRecord->pfnExport( pMozData, cbMozData, pData);
|
||||
WinSetClipbrdData( 0/*hab*/, (ULONG) pData,
|
||||
pRecord->ulClipboardFmt, CFI_POINTER);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else
|
||||
printf( "DosAllocSharedMem failed, rc %d\n", (int)rc);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Go through the flavors in the transferable and either get or set them
|
||||
nsresult nsClipboard::DoClipboardAction( nsClipboard::ClipboardAction aAction)
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
if( WinOpenClipbrd( 0/*hab*/))
|
||||
{
|
||||
if( aAction == nsClipboard::Write)
|
||||
WinEmptyClipbrd( 0/*hab*/);
|
||||
|
||||
// Get the list of formats the transferable can handle
|
||||
nsVoidArray *pFormats = nsnull;
|
||||
if( aAction == nsClipboard::Read)
|
||||
mTransferable->FlavorsTransferableCanImport( &pFormats);
|
||||
else
|
||||
mTransferable->FlavorsTransferableCanExport( &pFormats);
|
||||
|
||||
PRUint32 cFormats = pFormats->Count();
|
||||
|
||||
for( PRUint32 i = 0; i < cFormats; i++)
|
||||
{
|
||||
nsString *pFlavour = (nsString*) pFormats->ElementAt( i);
|
||||
if( pFlavour) // just in case
|
||||
{
|
||||
if( aAction == nsClipboard::Read) GetClipboardData( pFlavour);
|
||||
else SetClipboardData( pFlavour);
|
||||
}
|
||||
}
|
||||
|
||||
WinCloseClipbrd( 0/*hab*/);
|
||||
rc = NS_OK;
|
||||
delete pFormats;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Converters for various types of data
|
||||
|
||||
static PRUint32 Import8Bit( void *pString, void **pOut)
|
||||
{
|
||||
*pOut = pString;
|
||||
return strlen( (char*) pString);
|
||||
}
|
||||
|
||||
static PRUint32 Export8Bit( void *pDataIn, PRUint32 cData, void *pBuffer)
|
||||
{
|
||||
if( pBuffer)
|
||||
{
|
||||
memcpy( pBuffer, pDataIn, cData);
|
||||
*(((char*)pBuffer) + cData) = '\0';
|
||||
}
|
||||
return cData + 1;
|
||||
}
|
||||
|
||||
static PRUint32 Import16Bit( void *pString, void **pOut)
|
||||
{
|
||||
*pOut = pString;
|
||||
return UniStrlen( (UniChar*) pString) * 2;
|
||||
}
|
||||
|
||||
static PRUint32 Export16Bit( void *pDataIn, PRUint32 cData, void *pBuffer)
|
||||
{
|
||||
if( pBuffer)
|
||||
{
|
||||
memcpy( pBuffer, pDataIn, cData);
|
||||
*((UniChar*)pBuffer + (cData>>1)) = 0;
|
||||
}
|
||||
return cData + sizeof(UniChar);
|
||||
}
|
||||
|
||||
static PRUint32 ImportBin( void *pData, void **pOut)
|
||||
{
|
||||
*pOut = ((PRUint32*)pData) + 1;
|
||||
return *(PRUint32*)pData;
|
||||
}
|
||||
|
||||
static PRUint32 ExportBin( void *pDataIn, PRUint32 cData, void *pBuffer)
|
||||
{
|
||||
if( pBuffer)
|
||||
{
|
||||
*((PRUint32*)pBuffer) = cData;
|
||||
memcpy( (PRUint32*)pBuffer + 1, pDataIn, cData);
|
||||
}
|
||||
return cData + sizeof(PRUint32);
|
||||
}
|
||||
|
||||
static FormatRecord records[] =
|
||||
{
|
||||
{ kTextMime, CF_TEXT, 0, Import8Bit, Export8Bit },
|
||||
{ kUnicodeMime, 0, "CF_UNICODE", Import16Bit, Export16Bit },
|
||||
{ kHTMLMime, 0, "CF_HTML", Import8Bit, Export8Bit },
|
||||
{ kXIFMime, 0, "CF_XIF", Import8Bit, Export8Bit },
|
||||
{ kPNGImageMime, 0, "CF_PNG", ImportBin, ExportBin },
|
||||
{ kGIFImageMime, 0, "CF_GIF", ImportBin, ExportBin },
|
||||
{ kJPEGImageMime, 0, "CF_JPEG", ImportBin, ExportBin },
|
||||
{ kAOLMailMime, 0, "CF_AOLMAIL", Import8Bit, Export8Bit },
|
||||
{ 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
// get the format ID for a given mimetype
|
||||
ULONG nsClipboard::GetFormatID( nsString *aMimeStr, FormatRecord **pFmtRec)
|
||||
{
|
||||
ULONG ulFormat = 0;
|
||||
|
||||
const char *pszFmt = gModuleData.ConvertFromUcs( *aMimeStr);
|
||||
|
||||
for( FormatRecord *pRecord = records; pRecord->szMimeType; pRecord++)
|
||||
if( !strcmp( pRecord->szMimeType, pszFmt))
|
||||
{
|
||||
if( !pRecord->ulClipboardFmt)
|
||||
// create an atom for the format
|
||||
pRecord->ulClipboardFmt = gModuleData.GetAtom( pRecord->szFmtName);
|
||||
ulFormat = pRecord->ulClipboardFmt;
|
||||
*pFmtRec = pRecord;
|
||||
break;
|
||||
}
|
||||
|
||||
NS_ASSERTION(ulFormat, "Clipboard beseiged by unknown mimetype");
|
||||
|
||||
return ulFormat;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsClipboard_h
|
||||
#define _nsClipboard_h
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsBaseClipboard.h"
|
||||
|
||||
// Clipboard service.
|
||||
|
||||
struct FormatRecord;
|
||||
|
||||
class nsClipboard : public nsBaseClipboard
|
||||
{
|
||||
public:
|
||||
nsClipboard();
|
||||
virtual ~nsClipboard();
|
||||
|
||||
protected:
|
||||
// nsBaseClipboard
|
||||
NS_IMETHOD SetNativeClipboardData();
|
||||
NS_IMETHOD GetNativeClipboardData( nsITransferable *aTransferable);
|
||||
|
||||
enum ClipboardAction
|
||||
{
|
||||
Read,
|
||||
Write
|
||||
};
|
||||
|
||||
ULONG GetFormatID( nsString *aMimeStr, FormatRecord **ppRecord);
|
||||
void GetClipboardData( nsString *aFlavour);
|
||||
void SetClipboardData( nsString *aFlavour);
|
||||
nsresult DoClipboardAction( ClipboardAction aAction);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nscombobox.h"
|
||||
|
||||
// WC_COMBOBOX wrapper. Hackery present in nsWindow to enable user to just
|
||||
// talk about the height of the entryfield portion. This may well not work
|
||||
// because the combobox will size it on its own. Oh well, can be worked on.
|
||||
|
||||
NS_IMPL_ADDREF(nsComboBox)
|
||||
NS_IMPL_RELEASE(nsComboBox)
|
||||
|
||||
nsresult nsComboBox::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
if( aIID.Equals( nsIComboBox::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIComboBox*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
else if( aIID.Equals( nsIListWidget::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIListWidget*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsWindow::QueryInterface( aIID,aInstancePtr);
|
||||
}
|
||||
|
||||
nsComboBox::nsComboBox() : mDropdown(60), mEntry(gModuleData.lHtEntryfield)
|
||||
{}
|
||||
|
||||
nsresult nsComboBox::PreCreateWidget( nsWidgetInitData *aInitData)
|
||||
{
|
||||
if( aInitData != nsnull)
|
||||
{
|
||||
// remember the dropdown height
|
||||
nsComboBoxInitData *comboData = (nsComboBoxInitData*) aInitData;
|
||||
mDropdown = comboData->mDropDownHeight;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsComboBox::OnPresParamChanged( MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
if( LONGFROMMP(mp1) == PP_FONTNAMESIZE)
|
||||
{
|
||||
// reget height of entryfield
|
||||
SWP swp;
|
||||
WinQueryWindowPos( WinWindowFromID( mWnd, CBID_EDIT), &swp);
|
||||
mEntry = swp.cy + 6; // another magic number...
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRInt32 nsComboBox::GetHeight( PRInt32 aProposedHeight)
|
||||
{
|
||||
// See layout/html/forms/src/nsSelectControlFrame.cpp
|
||||
// return aProposedHeight + mDropdown;
|
||||
return mDropdown + mEntry;
|
||||
}
|
||||
|
||||
nsresult nsComboBox::GetBounds( nsRect &aRect)
|
||||
{
|
||||
aRect.x = mBounds.x;
|
||||
aRect.y = mBounds.y;
|
||||
aRect.width = mBounds.width;
|
||||
aRect.height = mEntry;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsComboBox::GetClientBounds( nsRect &aRect)
|
||||
{
|
||||
aRect.x = 0;
|
||||
aRect.y = 0;
|
||||
aRect.width = mBounds.width;
|
||||
aRect.height = mEntry;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PCSZ nsComboBox::WindowClass()
|
||||
{
|
||||
return WC_COMBOBOX;
|
||||
}
|
||||
|
||||
ULONG nsComboBox::WindowStyle()
|
||||
{
|
||||
return CBS_DROPDOWNLIST | BASE_CONTROL_STYLE;
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// popup context menu
|
||||
|
||||
#include "nsContextMenu.h"
|
||||
#include "nsWindow.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
// Can't WinQueryWindowRect() on menu before popping up...
|
||||
static void CalcMenuSize( HWND hwnd, PSIZEL szl);
|
||||
|
||||
NS_IMPL_ADDREF(nsContextMenu)
|
||||
NS_IMPL_RELEASE(nsContextMenu)
|
||||
|
||||
nsresult nsContextMenu::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if( !aInstancePtr)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aInstancePtr = 0;
|
||||
|
||||
if( aIID.Equals(nsIContextMenu::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIContextMenu*) this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if( aIID.Equals(nsIMenuListener::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIMenuListener*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if( aIID.Equals(((nsISupports*)(nsIContextMenu*)this)->GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsISupports*) ((nsIContextMenu*)this));
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
nsContextMenu::nsContextMenu() : mOwner(nsnull), mX(0), mY(0), mShowing(PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsContextMenu::~nsContextMenu()
|
||||
{
|
||||
}
|
||||
|
||||
// Well, not real sure what kind of window we've got here.
|
||||
nsresult nsContextMenu::Create( nsISupports *aParent,
|
||||
const nsString &str1, const nsString &str2)
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIWidget> pWidget = do_QueryInterface(aParent);
|
||||
|
||||
if( pWidget)
|
||||
{
|
||||
HWND wnd = (HWND) pWidget->GetNativeData( NS_NATIVE_WIDGET);
|
||||
mOwner = NS_HWNDToWindow(wnd);
|
||||
|
||||
if( !mOwner)
|
||||
rc = NS_ERROR_NULL_POINTER;
|
||||
else
|
||||
{
|
||||
nsToolkit *pToolkit = (nsToolkit*) pWidget->GetToolkit();
|
||||
|
||||
nsMenuBase::Create( wnd, pToolkit);
|
||||
NS_RELEASE(pToolkit);
|
||||
|
||||
rc = NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
mAlignment = str1;
|
||||
mAnchor = str2;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsContextMenu::GetParent( nsISupports *&aParent)
|
||||
{
|
||||
NS_IF_RELEASE(aParent);
|
||||
aParent = mOwner;
|
||||
NS_IF_ADDREF(mOwner);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsContextMenu::SetLocation( PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
mX = aX;
|
||||
mY = aY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIMenuListener specialization for
|
||||
|
||||
// Called to display the menu: update the DOM tree & then pop up the menu
|
||||
nsEventStatus nsContextMenu::MenuSelected( const nsMenuEvent &aMenuEvent)
|
||||
{
|
||||
// Bail if we're already up. This happens for complicated reasons.
|
||||
if( mShowing) return nsEventStatus_eIgnore;
|
||||
|
||||
// Call superclass method to build the menu
|
||||
nsDynamicMenu::MenuSelected( aMenuEvent);
|
||||
|
||||
// The coords we have are relative to the desktop. Convert to PM.
|
||||
POINTL ptl = { mX, mY };
|
||||
ptl.y = gModuleData.szScreen.cy - ptl.y - 1;
|
||||
|
||||
// Now look at the "popupalign" attribute to see what corner of the popup
|
||||
// should go at this location.
|
||||
// (see http://www.mozilla.org/xpfe/xptoolkit/popups.html)
|
||||
SIZEL szMenu;
|
||||
CalcMenuSize( mWnd, &szMenu);
|
||||
|
||||
if( mAlignment == "topleft") // most common case
|
||||
ptl.y -= szMenu.cy;
|
||||
else if( mAlignment == "bottomright")
|
||||
ptl.x -= szMenu.cx;
|
||||
else if( mAlignment == "topright")
|
||||
{
|
||||
ptl.x -= szMenu.cx;
|
||||
ptl.y -= szMenu.cy;
|
||||
}
|
||||
|
||||
mShowing = TRUE;
|
||||
|
||||
// Tell owner we're up so it can dispatch our commands.
|
||||
mOwner->SetContextMenu( this);
|
||||
|
||||
WinPopupMenu( HWND_DESKTOP,
|
||||
(HWND) mOwner->GetNativeData( NS_NATIVE_WIDGET),
|
||||
mWnd,
|
||||
ptl.x, ptl.y,
|
||||
0,
|
||||
PU_HCONSTRAIN | PU_VCONSTRAIN | PU_NONE |
|
||||
PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2);
|
||||
|
||||
// Because XPFE is Really Great, this is meant to be synchronous. Oh yes.
|
||||
//
|
||||
// XXX this loop is WRONG if there is a ``modal dialog'' showing.
|
||||
|
||||
#if 0
|
||||
nsIAppShell *pAppShell;
|
||||
NS_CreateAppShell( &pAppShell);
|
||||
#endif
|
||||
|
||||
// Guess we ought to get appshell in on the act -- we can get
|
||||
// the current appshell using NS_GetAppShell() or something, and it
|
||||
// knows if there's a modal loop 'cos it's smart :-).
|
||||
// Add a method to the appshell to 'process contextmenu' or something.
|
||||
//
|
||||
QMSG qmsg;
|
||||
BOOL rc;
|
||||
|
||||
while( mShowing)
|
||||
{
|
||||
rc = WinGetMsg( 0, &qmsg, 0, 0, 0);
|
||||
if( qmsg.msg == WM_USER) break; // menu is done, leave loop.
|
||||
WinDispatchMsg( 0, &qmsg);
|
||||
}
|
||||
|
||||
mOwner->SetContextMenu(0);
|
||||
|
||||
mShowing = PR_FALSE;
|
||||
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
nsEventStatus nsContextMenu::MenuDeselected( const nsMenuEvent &aMenuEvent)
|
||||
{
|
||||
// terminate modal loop from popup method
|
||||
if( mShowing)
|
||||
{
|
||||
WinPostQueueMsg( HMQ_CURRENT, WM_USER, 0, 0);
|
||||
}
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
// Can't WinQueryWindowRect() on menu before popping up...
|
||||
void CalcMenuSize( HWND hwnd, PSIZEL szl)
|
||||
{
|
||||
SHORT sItems = (SHORT) WinSendMsg( hwnd, MM_QUERYITEMCOUNT, 0, 0);
|
||||
|
||||
memset( szl, 0, sizeof(SIZEL));
|
||||
|
||||
for( SHORT i = 0; i < sItems; i++)
|
||||
{
|
||||
SHORT sID = (SHORT) WinSendMsg( hwnd, MM_ITEMIDFROMPOSITION,
|
||||
MPFROMSHORT(i), 0);
|
||||
RECTL rclItem;
|
||||
|
||||
WinSendMsg( hwnd, MM_QUERYITEMRECT, MPFROM2SHORT(sID,0), MPFROMP(&rclItem));
|
||||
LONG lWidth = rclItem.xRight - rclItem.xLeft;
|
||||
if( lWidth > szl->cx) szl->cx = lWidth;
|
||||
szl->cy += (rclItem.yTop - rclItem.yBottom);
|
||||
}
|
||||
|
||||
// Fudge-factor
|
||||
szl->cy += WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER);
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nscontextmenu_h
|
||||
#define _nscontextmenu_h
|
||||
|
||||
#include "nsIContextMenu.h"
|
||||
#include "nsMenuBase.h"
|
||||
|
||||
class nsWindow;
|
||||
|
||||
// Pop-up menu
|
||||
|
||||
class nsContextMenu : public nsIContextMenu, public nsDynamicMenu
|
||||
{
|
||||
public:
|
||||
nsContextMenu();
|
||||
virtual ~nsContextMenu();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIContextMenu extras
|
||||
NS_IMETHOD Create( nsISupports *aParent,
|
||||
const nsString &str1, const nsString &str2);
|
||||
NS_IMETHOD GetParent( nsISupports *&aParent);
|
||||
NS_IMETHOD SetLocation( PRInt32 aX, PRInt32 aY);
|
||||
|
||||
// nsIMenuListener overrides
|
||||
nsEventStatus MenuSelected( const nsMenuEvent &aMenuEvent);
|
||||
nsEventStatus MenuDeselected( const nsMenuEvent &aMenuEvent);
|
||||
|
||||
// Common methods
|
||||
DECL_DYNAMIC_MENU_METHODS
|
||||
|
||||
protected:
|
||||
nsWindow *mOwner;
|
||||
PRInt32 mX, mY;
|
||||
PRBool mShowing;
|
||||
nsString mAnchor;
|
||||
nsString mAlignment;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// This class is part of the strange printing `architecture'.
|
||||
// The `CreateDeviceContextSpec' method basically selects a print queue,
|
||||
// known here as an `nsIDeviceContextSpec'. This is given to a method
|
||||
// in nsIDeviceContext which creates a fresh device context for that
|
||||
// printer.
|
||||
|
||||
#include "nsGfxDefs.h"
|
||||
#include "libprint.h"
|
||||
|
||||
#include "nsDeviceContextSpecFactoryO.h"
|
||||
#include "nsDeviceContextSpecOS2.h"
|
||||
#include "nsRegionOS2.h"
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
nsDeviceContextSpecFactoryOS2::nsDeviceContextSpecFactoryOS2()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsDeviceContextSpecFactoryOS2, nsIDeviceContextSpecFactory::GetIID())
|
||||
|
||||
NS_IMETHODIMP nsDeviceContextSpecFactoryOS2::Init()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDeviceContextSpecFactoryOS2::CreateDeviceContextSpec(
|
||||
nsIDeviceContextSpec *aOldSpec,
|
||||
nsIDeviceContextSpec *&aNewSpec,
|
||||
PRBool aQuiet)
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
// This currently ignores aOldSpec. This may be of no consequence...
|
||||
PRTQUEUE *pq = PrnSelectPrinter( HWND_DESKTOP, aQuiet ? TRUE : FALSE);
|
||||
|
||||
if( pq)
|
||||
{
|
||||
nsDeviceContextSpecOS2 *spec = new nsDeviceContextSpecOS2;
|
||||
NS_ADDREF(spec);
|
||||
spec->Init( pq);
|
||||
aNewSpec = spec;
|
||||
rc = NS_OK;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// This class is part of the strange printing `architecture'.
|
||||
// The `CreateDeviceContextSpec' method basically selects a print queue,
|
||||
// known here as an `nsIDeviceContextSpec'. This is given to a method
|
||||
// in nsIDeviceContext which creates a fresh device context for that
|
||||
// printer.
|
||||
|
||||
#ifndef _nsDeviceContextSpecFactoryOS2_h
|
||||
#define _nsDeviceContextSpecFactoryOS2_h
|
||||
|
||||
#include "nsIDeviceContextSpecFactory.h"
|
||||
#include "nsIDeviceContextSpec.h"
|
||||
|
||||
class nsDeviceContextSpecFactoryOS2 : public nsIDeviceContextSpecFactory
|
||||
{
|
||||
public:
|
||||
nsDeviceContextSpecFactoryOS2();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init();
|
||||
NS_IMETHOD CreateDeviceContextSpec( nsIDeviceContextSpec *aOldSpec,
|
||||
nsIDeviceContextSpec *&aNewSpec,
|
||||
PRBool aQuiet);
|
||||
protected:
|
||||
virtual ~nsDeviceContextSpecFactoryOS2() {}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsGfxDefs.h"
|
||||
#include "libprint.h"
|
||||
|
||||
#include "nsDeviceContextSpecOS2.h"
|
||||
|
||||
nsDeviceContextSpecOS2::nsDeviceContextSpecOS2()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mQueue = nsnull;
|
||||
}
|
||||
|
||||
nsDeviceContextSpecOS2::~nsDeviceContextSpecOS2()
|
||||
{
|
||||
if( mQueue)
|
||||
PrnClosePrinter( mQueue);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsDeviceContextSpecOS2, nsIDeviceContextSpec::GetIID())
|
||||
|
||||
nsresult nsDeviceContextSpecOS2::Init( PRTQUEUE *pq)
|
||||
{
|
||||
mQueue = pq;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextSpecOS2::GetPRTQUEUE( PRTQUEUE *&p)
|
||||
{
|
||||
p = mQueue;
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsDeviceContextSpecOS2_h
|
||||
#define _nsDeviceContextSpecOS2_h
|
||||
|
||||
#include "nsIDeviceContextSpec.h"
|
||||
|
||||
class nsDeviceContextSpecOS2 : public nsIDeviceContextSpec
|
||||
{
|
||||
public:
|
||||
nsDeviceContextSpecOS2();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init( PRTQUEUE *pq);
|
||||
NS_IMETHOD GetPRTQUEUE( PRTQUEUE *&p);
|
||||
|
||||
protected:
|
||||
virtual ~nsDeviceContextSpecOS2();
|
||||
|
||||
PRTQUEUE *mQueue;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,540 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.0 (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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// To do
|
||||
// * Use the correct icons on drives
|
||||
// This requires beefing up DosIsRemovable() from FSTree.cpp to a
|
||||
// general 'DosQueryDriveType', and providing a handy array of icons
|
||||
// in the resource module, OR doing something funky with the WPS.
|
||||
//
|
||||
// * Helptext
|
||||
//
|
||||
// (dialog is usable at this point; those below are just for bonus points)
|
||||
//
|
||||
// * Make dialog resizable
|
||||
// Just requires coding.
|
||||
//
|
||||
// * Add a 1-pixel bevel-in border around the container
|
||||
//
|
||||
// * When user supplies a pathname in their DIRPICKER, hilight it in
|
||||
// the tree. This is a bit hard 'cos of asynchronous FSTree. Maybe
|
||||
// should fix that to allow "synchronous calls", so Expand() and Trash()
|
||||
// would have completed by the time they return (easy).
|
||||
//
|
||||
// * Save preferences (cnr colour, dialog position & size) somewhere
|
||||
//
|
||||
// * Directory history (replace typein at bottom with an entryfield)
|
||||
//
|
||||
// * More options? Subclassing?
|
||||
|
||||
#define INCL_WIN
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSERRORS
|
||||
#include <os2.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "nsFSTree.h"
|
||||
#include "resid.h"
|
||||
#include "nsDirPicker.h"
|
||||
|
||||
// XXX kludges
|
||||
static HMODULE res_handle;
|
||||
|
||||
// Container records
|
||||
|
||||
struct TREENODE
|
||||
{
|
||||
MINIRECORDCORE m;
|
||||
FS::IDir *pDir;
|
||||
};
|
||||
|
||||
typedef TREENODE *PTREENODE;
|
||||
|
||||
#define DIR2REC(dir) ((PTREENODE)dir->GetFileInfo()->GetUserData())
|
||||
|
||||
static void insertTree( HWND hwndCnr, PTREENODE pParent, PTREENODE pRecord,
|
||||
PRECORDINSERT pRI);
|
||||
|
||||
APIRET DosReallyCreateDir( PSZ dirpath);
|
||||
|
||||
void CenterWindow( HWND hwnd, HWND hwndOver);
|
||||
|
||||
// Window-word data for the dialog; implement fs callbacks to dynamically
|
||||
// build the tree (and stuff)
|
||||
|
||||
struct DirPicker : public FS::ICallbacks
|
||||
{
|
||||
HWND hwndDlg;
|
||||
HWND hwndCnr;
|
||||
HWND hwndCBox;
|
||||
HWND hwndEf;
|
||||
FS::ITreeBuilder *fsTree;
|
||||
FS::IDir *pMetaNode;
|
||||
BOOL initted;
|
||||
PTREENODE pCurrRoot;
|
||||
PDIRPICKER pDirPicker;
|
||||
HPOINTER icoFolder;
|
||||
|
||||
DirPicker( HWND dlg, PDIRPICKER aPicker) : hwndDlg(dlg), pMetaNode(0),
|
||||
initted(FALSE), pCurrRoot(0),
|
||||
pDirPicker(aPicker)
|
||||
{
|
||||
hwndCnr = WinWindowFromID( hwndDlg, IDD_TREECNR);
|
||||
hwndCBox = WinWindowFromID( hwndDlg, IDD_CBDRIVES);
|
||||
hwndEf = WinWindowFromID( hwndDlg, IDD_EFPATH);
|
||||
fsTree = FS::CreateTreeBuilder();
|
||||
fsTree->Init( this);
|
||||
fsTree->RequiresPM( TRUE);
|
||||
icoFolder = WinLoadPointer( HWND_DESKTOP, res_handle, ID_ICO_FOLDER);
|
||||
}
|
||||
|
||||
virtual ~DirPicker()
|
||||
{
|
||||
WinDestroyPointer( icoFolder);
|
||||
}
|
||||
|
||||
void CreateRoot( FS::IDir *aRootNode)
|
||||
{
|
||||
pMetaNode = aRootNode;
|
||||
}
|
||||
|
||||
void CreateDir( FS::IDir *aNewNode)
|
||||
{
|
||||
// Create a new node
|
||||
PTREENODE pRec = (PTREENODE) WinSendMsg( hwndCnr, CM_ALLOCRECORD,
|
||||
MPFROMLONG(4), MPFROMLONG(1));
|
||||
// find some strings; note that fstree owns them
|
||||
pRec->m.pszIcon = (char*) aNewNode->GetFileInfo()->GetLeafName();
|
||||
if( aNewNode->AsDrive())
|
||||
{
|
||||
// Now add the drive to the combobox
|
||||
char listitem[40];
|
||||
strcpy( listitem, pRec->m.pszIcon);
|
||||
PCSZ vollbl = aNewNode->AsDrive()->GetVolumeLabel();
|
||||
if( vollbl && *vollbl)
|
||||
{
|
||||
strcat( listitem, " [");
|
||||
strcat( listitem, vollbl);
|
||||
strcat( listitem, "]");
|
||||
}
|
||||
MRESULT index = WinSendMsg( hwndCBox, LM_INSERTITEM,
|
||||
MPFROMSHORT(LIT_END), MPFROMP(listitem));
|
||||
WinSendMsg( hwndCBox, LM_SETITEMHANDLE, index, MPFROMP(pRec));
|
||||
|
||||
// display the current drive first; if the user gave us a seed, we'll
|
||||
// do that in InitialScanComplete().
|
||||
ULONG ulDriveNum, ulDriveMap;
|
||||
DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap);
|
||||
char buffer[] = "A:";
|
||||
buffer[0] += ulDriveNum - 1;
|
||||
|
||||
// Filter out all but the root of this drive
|
||||
if( stricmp( pRec->m.pszIcon, buffer))
|
||||
pRec->m.flRecordAttr = CRA_FILTERED;
|
||||
else
|
||||
{
|
||||
pCurrRoot = pRec;
|
||||
WinSendMsg( hwndCBox, LM_SELECTITEM, index, MPFROMSHORT(TRUE));
|
||||
}
|
||||
|
||||
// XXX use the right icon
|
||||
pRec->m.hptrIcon = icoFolder;
|
||||
}
|
||||
else
|
||||
{
|
||||
PCSZ pcszPathname = aNewNode->GetFileInfo()->GetPathName();
|
||||
// don't need to doserror protect this call 'cos we'll only get
|
||||
// callbacks if the directory has been seen.
|
||||
pRec->m.hptrIcon = WinLoadFileIcon( pcszPathname, FALSE);
|
||||
|
||||
// once we start getting straight directories, toplevel is done
|
||||
if( !initted)
|
||||
{
|
||||
initted = TRUE;
|
||||
WinPostMsg( hwndCnr, CM_EXPANDTREE, MPFROMP(pCurrRoot), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Tie up both ways
|
||||
pRec->pDir = aNewNode;
|
||||
aNewNode->GetFileInfo()->SetUserData( pRec);
|
||||
|
||||
// Now insert the record into the container
|
||||
RECORDINSERT rI = { sizeof(RECORDINSERT), (PRECORDCORE) CMA_END, 0,
|
||||
TRUE, CMA_TOP, 1 };
|
||||
// Set parent if appropriate
|
||||
if( aNewNode->GetParent()->GetParent())
|
||||
{
|
||||
rI.pRecordParent = (PRECORDCORE) DIR2REC(aNewNode->GetParent());
|
||||
}
|
||||
|
||||
WinSendMsg( hwndCnr, CM_INSERTRECORD, MPFROMP(pRec), MPFROMP(&rI));
|
||||
}
|
||||
|
||||
void DestroyDir( FS::IDir *aNode)
|
||||
{
|
||||
if( aNode != pMetaNode)
|
||||
{
|
||||
PTREENODE pNode = DIR2REC(aNode);
|
||||
if( pNode == pCurrRoot)
|
||||
WinSendMsg( hwndCnr, CM_REMOVERECORD,
|
||||
MPFROMP(&pNode), MPFROM2SHORT(1, 0));
|
||||
WinSendMsg( hwndCnr, CM_FREERECORD, MPFROMP(&pNode), MPFROMSHORT(1));
|
||||
}
|
||||
}
|
||||
|
||||
void InitialScanComplete()
|
||||
{
|
||||
// Mismatch between our gui requirements and the way that FSTree provides
|
||||
// us with data. Really ought to alter FSTree to build drives selectively;
|
||||
// this would be done
|
||||
//
|
||||
// Anyhow, now we know that the initial scan has completed, we can take
|
||||
// out of the container those drives which have been filtered away.
|
||||
// They needed to be in the container in order to build the tree.
|
||||
|
||||
FS::IDir *pNode = pMetaNode->GetFirstChild();
|
||||
while( pNode)
|
||||
{
|
||||
if( pNode != pCurrRoot->pDir)
|
||||
{
|
||||
PTREENODE pRecord = DIR2REC(pNode);
|
||||
WinSendMsg( hwndCnr, CM_REMOVERECORD,
|
||||
MPFROMP(&pRecord), MPFROM2SHORT(1, 0));
|
||||
pRecord->m.flRecordAttr &= ~CRA_FILTERED;
|
||||
}
|
||||
|
||||
pNode = pNode->GetNextSibling();
|
||||
}
|
||||
|
||||
// Now we know where we are.
|
||||
// If the user has given a seed directory, try & find it (!)
|
||||
if( pDirPicker->szFullFile[0])
|
||||
{
|
||||
// XXX write me
|
||||
}
|
||||
}
|
||||
|
||||
void CreateFile( FS::IFile *aNewLeaf) {}
|
||||
void DestroyFile( FS::IFile *aLeaf) {}
|
||||
};
|
||||
|
||||
MRESULT EXPENTRY fndpDirPicker( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
DirPicker *pData = (DirPicker *) WinQueryWindowPtr( hwnd, QWL_USER);
|
||||
|
||||
switch( msg)
|
||||
{
|
||||
case WM_INITDLG:
|
||||
{
|
||||
PDIRPICKER pPicker = (PDIRPICKER) mp2;
|
||||
// create data area & save it away
|
||||
pData = new DirPicker( hwnd, pPicker);
|
||||
WinSetWindowPtr( hwnd, QWL_USER, pData);
|
||||
|
||||
// prep window
|
||||
CenterWindow( hwnd, WinQueryWindow( hwnd, QW_OWNER));
|
||||
|
||||
// XXX make dynamic, save fontnamesize
|
||||
WinSetPresParam( hwnd, PP_FONTNAMESIZE, 11, "9.WarpSans");
|
||||
// XXX colour for container bg?
|
||||
// XXX Do help later
|
||||
WinEnableControl( hwnd, IDD_HELPBUTTON, FALSE);
|
||||
|
||||
// sort out container
|
||||
CNRINFO cnrInfo = { sizeof(CNRINFO), 0 };
|
||||
cnrInfo.flWindowAttr = CV_TREE | CV_ICON | CV_MINI | CA_TREELINE;
|
||||
WinSendMsg( pData->hwndCnr, CM_SETCNRINFO,
|
||||
MPFROMP( &cnrInfo), MPFROMLONG( CMA_FLWINDOWATTR));
|
||||
WinSetWindowBits( pData->hwndCnr, QWL_STYLE, 0, WS_CLIPSIBLINGS);
|
||||
|
||||
// allow entryfield to be long enough to display a full pathname
|
||||
WinSendMsg( pData->hwndEf, EM_SETTEXTLIMIT, MPFROMSHORT(CCHMAXPATH), 0);
|
||||
if( *pPicker->szFullFile)
|
||||
WinSetWindowText( pData->hwndEf, pPicker->szFullFile);
|
||||
|
||||
if( pPicker->pszTitle)
|
||||
WinSetWindowText( hwnd, pPicker->pszTitle);
|
||||
WinShowWindow( hwnd, TRUE);
|
||||
|
||||
// begin scan (returns immediately)
|
||||
pData->fsTree->Build( FS::Lazy);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_CONTROL:
|
||||
switch( SHORT1FROMMP(mp1))
|
||||
{
|
||||
case IDD_TREECNR:
|
||||
switch( SHORT2FROMMP(mp1))
|
||||
{
|
||||
case CN_EXPANDTREE:
|
||||
{
|
||||
PTREENODE pNode = (PTREENODE) mp2;
|
||||
pNode->pDir->Expand();
|
||||
return 0;
|
||||
}
|
||||
case CN_ENTER:
|
||||
{
|
||||
// Trigger an expand
|
||||
PNOTIFYRECORDENTER pThing = (PNOTIFYRECORDENTER) mp2;
|
||||
if( pThing->pRecord) // trap double-click on background
|
||||
WinPostMsg( pData->hwndCnr, CM_EXPANDTREE,
|
||||
MPFROMP(pThing->pRecord), 0);
|
||||
return 0;
|
||||
}
|
||||
case CN_EMPHASIS:
|
||||
{
|
||||
PNOTIFYRECORDEMPHASIS pThing = (PNOTIFYRECORDEMPHASIS) mp2;
|
||||
if( pThing->fEmphasisMask & CRA_SELECTED)
|
||||
{
|
||||
PTREENODE pNode = (PTREENODE) pThing->pRecord;
|
||||
// check this node has GAINED not LOST selection
|
||||
if( pNode->m.flRecordAttr & CRA_SELECTED)
|
||||
{
|
||||
// set path into entryfield, specialcase root dirs
|
||||
// to get the backslash
|
||||
char buffer[4] = "A:\\";
|
||||
char *pname =
|
||||
(char*) pNode->pDir->GetFileInfo()->GetPathName();
|
||||
if( pNode->pDir->AsDrive())
|
||||
{
|
||||
buffer[0] = pname[0];
|
||||
pname = buffer;
|
||||
}
|
||||
WinSetWindowText( pData->hwndEf, pname);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDD_CBDRIVES:
|
||||
switch( SHORT2FROMMP(mp1))
|
||||
{
|
||||
case CBN_EFCHANGE:
|
||||
{
|
||||
// change drives (potentially)
|
||||
MRESULT index;
|
||||
index = WinSendMsg( pData->hwndCBox, LM_QUERYSELECTION,
|
||||
MPFROMSHORT(LIT_FIRST),0);
|
||||
PTREENODE pNode = (PTREENODE)
|
||||
WinSendMsg( pData->hwndCBox, LM_QUERYITEMHANDLE, index, 0);
|
||||
|
||||
// actually a change?
|
||||
if( pNode != pData->pCurrRoot)
|
||||
{
|
||||
// remove old drive tree
|
||||
WinSendMsg( pData->hwndCnr, CM_REMOVERECORD,
|
||||
MPFROMP(&pData->pCurrRoot), MPFROM2SHORT(1,0));
|
||||
|
||||
// insert new one
|
||||
//
|
||||
// I could have *sworn* that you could insert an entire
|
||||
// tree just by inserting the root. Unfortunately this
|
||||
// isn't so :-(
|
||||
|
||||
// Single RI on the stack
|
||||
RECORDINSERT rI = { sizeof(RECORDINSERT),
|
||||
(PRECORDCORE) CMA_END,
|
||||
0, TRUE, CMA_TOP, 1 };
|
||||
|
||||
// if the new drive is removable, generate a fresh tree
|
||||
FS::IDrive *pDrive = pNode->pDir->AsDrive();
|
||||
if( pDrive->IsRemovable())
|
||||
{
|
||||
WinSendMsg( pData->hwndCnr, CM_INSERTRECORD,
|
||||
MPFROMP(pNode), MPFROMP(&rI));
|
||||
pNode->pDir->Trash();
|
||||
}
|
||||
else
|
||||
insertTree( pData->hwndCnr, 0, pNode, &rI);
|
||||
|
||||
pData->pCurrRoot = pNode;
|
||||
WinPostMsg( pData->hwndCnr, CM_EXPANDTREE,
|
||||
MPFROMP(pData->pCurrRoot), 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
pData->fsTree->DeleteInstance();
|
||||
delete pData;
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
switch( SHORT1FROMMP(mp1))
|
||||
{
|
||||
case DID_CANCEL:
|
||||
case DID_OK:
|
||||
{
|
||||
WinQueryWindowText( pData->hwndEf, CCHMAXPATH,
|
||||
pData->pDirPicker->szFullFile);
|
||||
pData->pDirPicker->lReturn = SHORT1FROMMP(mp1);
|
||||
|
||||
if( SHORT1FROMMP(mp1) == DID_OK)
|
||||
{
|
||||
// Check if directory exists etc.
|
||||
FILESTATUS3 fs3;
|
||||
APIRET rc = DosQueryPathInfo( pData->pDirPicker->szFullFile,
|
||||
FIL_STANDARD, &fs3, sizeof fs3);
|
||||
if( rc)
|
||||
{
|
||||
char msg1[256], buffer[500];
|
||||
WinLoadString( 0, res_handle, ID_STR_HMMDIR, 256, msg1);
|
||||
sprintf( buffer, msg1, pData->pDirPicker->szFullFile);
|
||||
ULONG ret = WinMessageBox( HWND_DESKTOP, hwnd, buffer,
|
||||
0, 0, MB_YESNO | MB_QUERY |
|
||||
MB_APPLMODAL);
|
||||
if( ret != MBID_YES) return 0;
|
||||
else
|
||||
{
|
||||
rc = DosReallyCreateDir( pData->pDirPicker->szFullFile);
|
||||
if( rc)
|
||||
{
|
||||
WinLoadString( 0, res_handle, ID_STR_NOCDIR, 256, msg1);
|
||||
WinMessageBox( HWND_DESKTOP, hwnd, msg1, 0, 0,
|
||||
MB_OK | MB_ERROR | MB_APPLMODAL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// break out, defdlgproc will close the window.
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
WinPostMsg( hwnd, WM_COMMAND, MPFROM2SHORT(DID_CANCEL,0), 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return WinDefDlgProc( hwnd, msg, mp1, mp2);
|
||||
}
|
||||
|
||||
// Insert an FSTree tree (DFS, recursive; ought to do iterative magic, or
|
||||
// at least optimize the 'insert children' case to insert them all at once)
|
||||
static void insertTree( HWND hwndCnr, PTREENODE pParent, PTREENODE pRecord,
|
||||
PRECORDINSERT pRI)
|
||||
{
|
||||
// insert this node
|
||||
pRI->pRecordParent = (PRECORDCORE) pParent;
|
||||
WinSendMsg( hwndCnr, CM_INSERTRECORD, MPFROMP(pRecord), MPFROMP(pRI));
|
||||
|
||||
// do each child
|
||||
FS::IDir *pDir = pRecord->pDir->GetFirstChild();
|
||||
while( pDir)
|
||||
{
|
||||
insertTree( hwndCnr, pRecord, DIR2REC(pDir), pRI);
|
||||
pDir = pDir->GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
// Entrypoint
|
||||
HWND APIENTRY FS_PickDirectory( HWND hwndParent,
|
||||
HWND hwndOwner,
|
||||
HMODULE hModResources,
|
||||
PDIRPICKER pDirPicker)
|
||||
{
|
||||
HWND hwndRet = 0;
|
||||
|
||||
if( pDirPicker)
|
||||
{
|
||||
// XXX fix this somehow; FS_SetResourceHandle(), or move whole lot
|
||||
// XXX into a dll (not for mozilla, tho')
|
||||
res_handle = hModResources;
|
||||
|
||||
if( pDirPicker->bModal)
|
||||
{
|
||||
ULONG rc = WinDlgBox( hwndParent, hwndOwner,
|
||||
fndpDirPicker, hModResources,
|
||||
DID_DIRPICKER, pDirPicker);
|
||||
hwndRet = (rc == DID_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
hwndRet = WinLoadDlg( hwndParent, hwndOwner,
|
||||
fndpDirPicker, hModResources,
|
||||
DID_DIRPICKER, pDirPicker);
|
||||
}
|
||||
}
|
||||
|
||||
return hwndRet;
|
||||
}
|
||||
|
||||
// create all segments in the path
|
||||
APIRET DosReallyCreateDir( PSZ dirpath)
|
||||
{
|
||||
APIRET rc = 0;
|
||||
int depth = 0;
|
||||
char *c;
|
||||
char buff[CCHMAXPATH];
|
||||
|
||||
strcpy( buff, dirpath);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
rc = DosCreateDir( dirpath, 0);
|
||||
if( (rc == NO_ERROR && depth == 0) ||
|
||||
(rc && rc != ERROR_PATH_NOT_FOUND)) break;
|
||||
// if rc = 0 go down a level, else go up a level
|
||||
if( rc == ERROR_PATH_NOT_FOUND)
|
||||
{
|
||||
c = strrchr( buff, '\\');
|
||||
if( !c) break;
|
||||
depth++;
|
||||
*c = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
depth--;
|
||||
buff[ strlen( buff)] = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Center hwnd over hwndOver
|
||||
void CenterWindow( HWND hwnd, HWND hwndOver)
|
||||
{
|
||||
SWP swp1, swp2;
|
||||
if( !hwndOver) hwndOver = HWND_DESKTOP;
|
||||
|
||||
WinQueryWindowPos( hwnd, &swp1);
|
||||
WinQueryWindowPos( hwndOver, &swp2);
|
||||
swp1.x = (swp2.cx - swp1.cx) / 2;
|
||||
swp1.y = (swp2.cy - swp1.cy) / 2;
|
||||
WinSetWindowPos( hwnd, 0, swp1.x, swp1.y, 0, 0, SWP_MOVE);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.0 (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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _dirpicker_h
|
||||
#define _dirpicker_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This is an interface to a 'choose directory' dialog which uses the FSTree */
|
||||
/* code as a back-end. */
|
||||
/* */
|
||||
/* It could be expanded to give a 'choose file' dialog along the same lines as */
|
||||
/* the one from win32 very easily -- add another container for files, a */
|
||||
/* vertical (draggable) split bar to separate the two, add something for file */
|
||||
/* types, a little WPS integration and there you go. */
|
||||
|
||||
typedef struct _DIRPICKER
|
||||
{
|
||||
CHAR szFullFile[CCHMAXPATH]; /* directory picked; may be set on init */
|
||||
LONG lReturn; /* button pressed, DID_CANCEL or DID_OK */
|
||||
BOOL bModal; /* should the dialog be shown modally */
|
||||
PSZ pszTitle; /* title for the dialog */
|
||||
} DIRPICKER, *PDIRPICKER;
|
||||
|
||||
/* return: if bModal then return hwnd of dialog or 0 on error */
|
||||
/* else TRUE if successful, FALSE on error. */
|
||||
|
||||
HWND APIENTRY FS_PickDirectory( HWND hwndParent, /* parent for dialog */
|
||||
HWND hwndOwner, /* owner for dialog */
|
||||
HMODULE hModResources, /* resource module */
|
||||
PDIRPICKER pDirPicker); /* running data */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,997 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// Drag'n'drop manager
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsDragService.h"
|
||||
#include "nsITransferable.h"
|
||||
#include "nsIFileListTransferable.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
#include "nsFileSpec.h"
|
||||
#include "nsFileStream.h"
|
||||
#include "nsSpecialSystemDirectory.h"
|
||||
|
||||
#include "resid.h"
|
||||
|
||||
#include <stdio.h> // for sscanf
|
||||
#include <stdlib.h> // realloc/free
|
||||
|
||||
//
|
||||
// There are three major cases to consider:
|
||||
//
|
||||
// 1. Drag from xptoolkit to non-xptoolkit
|
||||
//
|
||||
// Use DRM_OS2FILE. Source render to get right rf used.
|
||||
//
|
||||
// 2. Drag from xptoolkit to xptoolkit
|
||||
//
|
||||
// Use a custom shared-memory RM; special-case same process
|
||||
//
|
||||
// 3. Drag from non-xptoolkit to xptoolkit
|
||||
//
|
||||
// Use DRM_OS2FILE and create nsFileListTransferable's
|
||||
// Problem: we need to copy the file because we have no way of knowing
|
||||
// when client has done with it & we can DM_ENDCONVERSATION
|
||||
//
|
||||
// Plus: xptoolkit will eventually acquire text/URL (or text/URI or something)
|
||||
// which we can handle.
|
||||
//
|
||||
// Apart from this, the major thing not implemented is the initiation of
|
||||
// post-drop conversations for DRM_OS2FILE. This is because of various reasons,
|
||||
// see comment in nsDragService::DoPushedOS2FILE() below.
|
||||
//
|
||||
|
||||
// Quick utility class to clean up files we create at some later point...
|
||||
class nsGCFileSpec : public nsFileSpec
|
||||
{
|
||||
public:
|
||||
nsGCFileSpec(nsFileSpec &fs) : nsFileSpec(fs) {}
|
||||
~nsGCFileSpec()
|
||||
{
|
||||
Delete( FALSE);
|
||||
}
|
||||
};
|
||||
|
||||
static char *DecodeStrHandle( HSTR hstr);
|
||||
static const char *MimeTypeToRF( const char *pcsz);
|
||||
static const char *RFToMimeType( const char *pcsz);
|
||||
static BOOL FindFile( PDRAGITEM pItem, nsFileSpec &aFileSpec);
|
||||
static void GetTempFile( nsFileSpec &tempfile);
|
||||
|
||||
// convert between pm & xptoolkit drag operation types
|
||||
#define DragOperation(at) \
|
||||
(at == nsIDragService::DRAGDROP_ACTION_NONE ? DO_DEFAULT : \
|
||||
(at == nsIDragService::DRAGDROP_ACTION_COPY ? DO_COPY : \
|
||||
(at == nsIDragService::DRAGDROP_ACTION_MOVE ? DO_MOVE : DO_LINK)))
|
||||
|
||||
#define DragDropAction(do) \
|
||||
(do == DO_LINK ? nsIDragService::DRAGDROP_ACTION_LINK : \
|
||||
(do == DO_COPY ? nsIDragService::DRAGDROP_ACTION_COPY : \
|
||||
nsIDragService::DRAGDROP_ACTION_MOVE))
|
||||
|
||||
nsDragService::nsDragService() : mDragInfo(0), mDragItems(0)
|
||||
{
|
||||
// XXX temporary icon until xptoolkit realises it needs to give us one
|
||||
mIcon = WinLoadPointer( HWND_DESKTOP, gModuleData.hModResources,
|
||||
ID_ICO_DRAGITEM);
|
||||
|
||||
// Window for doing things
|
||||
mDragWnd = WinCreateWindow( HWND_DESKTOP, WC_STATIC, 0, 0, 0, 0, 0, 0,
|
||||
HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0);
|
||||
mWndProc = WinSubclassWindow( mDragWnd, fnwpDragSource);
|
||||
}
|
||||
|
||||
nsDragService::~nsDragService()
|
||||
{
|
||||
WinDestroyPointer( mIcon);
|
||||
WinDestroyWindow( mDragWnd);
|
||||
}
|
||||
|
||||
nsresult nsDragService::InvokeDragSession( nsISupportsArray *aTransArray,
|
||||
nsIRegion *aRegion,
|
||||
PRUint32 aActionType)
|
||||
{
|
||||
// This is horribly multidimensional -- we have an array of dragitems, fine.
|
||||
// But -- each dragitem may be a file list, which itself is several dragitems.
|
||||
PDRAGITEM pDragItems = 0;
|
||||
ULONG cDragItems = 0;
|
||||
|
||||
PRUint32 cItems;
|
||||
aTransArray->Count( &cItems);
|
||||
for( PRUint32 i = 0; i < cItems; i++)
|
||||
{
|
||||
nsCOMPtr<nsISupports> pThing;
|
||||
pThing = dont_AddRef( aTransArray->ElementAt(i)); // XXX check this doesn't leak
|
||||
if( pThing)
|
||||
{
|
||||
// Get dragitems for this array element
|
||||
nsCOMPtr<nsITransferable> pXfer = do_QueryInterface(pThing);
|
||||
PDRAGITEM pDItems = 0;
|
||||
ULONG cDItems = 0;
|
||||
|
||||
CreateDragItems( &cDItems, &pDItems, pXfer);
|
||||
|
||||
// Now extend & copy up into the local array
|
||||
pDragItems = (PDRAGITEM)
|
||||
realloc( pDragItems, cDragItems + cDItems * sizeof(DRAGITEM));
|
||||
memcpy( pDragItems + cDragItems, pDItems, cDItems * sizeof(DRAGITEM));
|
||||
cDragItems += cDItems;
|
||||
|
||||
// free local data
|
||||
delete [] pDItems;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
if( cDragItems)
|
||||
{
|
||||
rc = InvokeDrag( pDragItems, cDragItems, aActionType);
|
||||
free( pDragItems);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Even though it says single, it may well be multiple 'cos of the files thing.
|
||||
nsresult nsDragService::InvokeDragSessionSingle( nsITransferable *aTransferable,
|
||||
nsIRegion *aRegion,
|
||||
PRUint32 aActionType)
|
||||
{
|
||||
PDRAGITEM pDragItems = 0;
|
||||
ULONG cDragItems = 0;
|
||||
|
||||
CreateDragItems( &cDragItems, &pDragItems, aTransferable);
|
||||
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
if( cDragItems)
|
||||
{
|
||||
rc = InvokeDrag( pDragItems, cDragItems, aActionType);
|
||||
delete [] pDragItems;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsDragService::GetData( nsITransferable *aTransferable,
|
||||
PRUint32 aItemIndex)
|
||||
{
|
||||
// Fill the transferable with data from the given dragitem.
|
||||
if( !aTransferable || aItemIndex >= mDragInfo->cditem)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PDRAGITEM pItem = DrgQueryDragitemPtr( mDragInfo, aItemIndex);
|
||||
|
||||
// Problem here. Unless we're xptoolkit<->xptoolkit we can only
|
||||
// get data in *one* flavour.
|
||||
//
|
||||
// Oh well; do our best.
|
||||
|
||||
nsVoidArray *pFormats = nsnull;
|
||||
aTransferable->FlavorsTransferableCanImport( &pFormats);
|
||||
PRUint32 cFormats = pFormats->Count();
|
||||
|
||||
for( PRUint32 i = 0; i < cFormats; i++)
|
||||
{
|
||||
nsString *pFlavour = (nsString*) pFormats->ElementAt( i);
|
||||
char buff[40];
|
||||
gModuleData.ConvertFromUcs( *pFlavour, buff, 40);
|
||||
const char *rf = MimeTypeToRF( buff);
|
||||
if( rf && DrgVerifyRMF( pItem, 0, rf))
|
||||
{
|
||||
// Okay, have something to do. Now pick a rendering mechanism:
|
||||
void *pData = 0;
|
||||
PRUint32 cData = 0;
|
||||
|
||||
BOOL source_dry_p = FALSE; // can only get single flavour
|
||||
|
||||
// 1. Some xptoolkit - use DRM_MOZILLA
|
||||
if( DrgVerifyRMF( pItem, "DRM_MOZILLA", 0))
|
||||
{
|
||||
DoMozillaXfer( pItem, buff, &pData, &cData);
|
||||
}
|
||||
// 2. Some random process - use DRM_OS2FILE
|
||||
else if( DrgVerifyRMF( pItem, "DRM_OS2FILE", 0))
|
||||
{
|
||||
// 2a. `normal' rendering - load it, break out
|
||||
if( pItem->hstrSourceName && pItem->hstrContainerName)
|
||||
{
|
||||
nsFileSpec file;
|
||||
|
||||
if( !FindFile( pItem, file))
|
||||
printf( "Can't find dropped file\n");
|
||||
else
|
||||
{
|
||||
cData = file.GetFileSize();
|
||||
pData = new char [ cData ];
|
||||
nsInputFileStream istream( file);
|
||||
istream.read( pData, (PRInt32) cData);
|
||||
istream.close();
|
||||
|
||||
source_dry_p = TRUE;
|
||||
}
|
||||
}
|
||||
// 2b. DRM_OS2FILE push - faff around endlessly, break out
|
||||
// This is a bit tricky 'cos this method needs to be synchronous.
|
||||
else
|
||||
{
|
||||
DoPushedOS2FILE( pItem, rf, &pData, &cData);
|
||||
source_dry_p = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *rmf = DecodeStrHandle( pItem->hstrRMF);
|
||||
printf( "Incomprehensible DRM (%s)\n", rmf);
|
||||
}
|
||||
|
||||
if( pData && cData)
|
||||
aTransferable->SetTransferData( pFlavour, pData, cData);
|
||||
|
||||
if( source_dry_p)
|
||||
break;
|
||||
}
|
||||
else if( pFlavour->Equals( kDropFilesMime))
|
||||
{
|
||||
// Moan if this isn't a filelisttransferable.
|
||||
nsCOMPtr<nsIFileListTransferable> pFileList = do_QueryInterface(aTransferable);
|
||||
|
||||
if( !pFileList)
|
||||
printf( "kDropFilesMime requested but no filelisttransferable!\n");
|
||||
else
|
||||
{
|
||||
// Need a file.
|
||||
nsFileSpec *pFileSpec = 0;
|
||||
|
||||
if( DrgVerifyRMF( pItem, "DRM_MOZILLA", 0))
|
||||
{
|
||||
void *pData = 0;
|
||||
PRUint32 cData;
|
||||
DoMozillaXfer( pItem, buff, &pData, &cData);
|
||||
|
||||
if( pData)
|
||||
{
|
||||
nsFileSpec tempfile;
|
||||
GetTempFile( tempfile);
|
||||
|
||||
nsOutputFileStream stream(tempfile);
|
||||
stream.write( pData, (PRInt32)cData);
|
||||
stream.close();
|
||||
|
||||
// Make sure this temp file is erased eventually.
|
||||
pFileSpec = new nsGCFileSpec( tempfile);
|
||||
}
|
||||
}
|
||||
// 2. Some random process - use DRM_OS2FILE
|
||||
else if( DrgVerifyRMF( pItem, "DRM_OS2FILE", 0))
|
||||
{
|
||||
if( pItem->hstrSourceName && pItem->hstrContainerName)
|
||||
{
|
||||
nsFileSpec file;
|
||||
|
||||
if( !FindFile( pItem, file))
|
||||
printf( "Can't find dropped file\n");
|
||||
else
|
||||
pFileSpec = new nsFileSpec(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
// (can't actually do source rendering yet)
|
||||
DoPushedOS2FILE(0,0,0,0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *rmf = DecodeStrHandle( pItem->hstrRMF);
|
||||
printf( "Incomprehensible DRM -> file (%s)\n", rmf);
|
||||
}
|
||||
|
||||
// Did we get one?
|
||||
if( pFileSpec)
|
||||
{
|
||||
nsVoidArray array;
|
||||
array.AppendElement(pFileSpec);
|
||||
pFileList->SetFileList(&array);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDragService::GetNumDropItems( PRUint32 *aNumItems)
|
||||
{
|
||||
if( !aNumItems)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aNumItems = mDragInfo->cditem;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDragService::IsDataFlavorSupported( nsString *aDataFlavour)
|
||||
{
|
||||
// The idea here is to return NS_OK if any of the dragitems supports
|
||||
// this flavour (yeah, hmm...)
|
||||
//
|
||||
// Maybe we should change it so they all have to be (which is what CUA
|
||||
// says we should do...)
|
||||
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
char buff[40];
|
||||
gModuleData.ConvertFromUcs( *aDataFlavour, buff, 40);
|
||||
|
||||
const char *rf = MimeTypeToRF( buff);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "IsDataFlavorSupported %s\n", buff);
|
||||
printf( "RF for that is %s\n", rf);
|
||||
#endif
|
||||
|
||||
if( rf)
|
||||
{
|
||||
for( PRUint32 i = 0; i < mDragInfo->cditem; i++)
|
||||
{
|
||||
PDRAGITEM pItem = DrgQueryDragitemPtr( mDragInfo, i);
|
||||
// this checks for ANY rm, which is a bit dubious.
|
||||
if( DrgVerifyRMF( pItem, 0, rf))
|
||||
{
|
||||
rc = NS_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "Flavor is %ssupported.\n", rc == NS_OK ? "" : "not ");
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Starting drag-over event block.
|
||||
void nsDragService::InitDragOver( PDRAGINFO aDragInfo)
|
||||
{
|
||||
// If the drag's from another process, grab it
|
||||
if( !mDragInfo)
|
||||
{
|
||||
DrgAccessDraginfo( aDragInfo);
|
||||
mDragInfo = aDragInfo;
|
||||
}
|
||||
|
||||
// Set xp flags
|
||||
SetCanDrop( PR_FALSE);
|
||||
SetDragAction( DragDropAction(mDragInfo->usOperation));
|
||||
StartDragSession();
|
||||
}
|
||||
|
||||
// end of drag-over event block; get xp settings & convert.
|
||||
MRESULT nsDragService::TermDragOver()
|
||||
{
|
||||
MRESULT rc;
|
||||
PRBool bCanDrop;
|
||||
PRUint32 action;
|
||||
|
||||
EndDragSession();
|
||||
GetCanDrop( &bCanDrop);
|
||||
GetDragAction( &action);
|
||||
|
||||
rc = MPFROM2SHORT( bCanDrop ? DOR_DROP : DOR_NODROP, DragOperation(action));
|
||||
|
||||
// ...factor code...
|
||||
TermDragExit();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void nsDragService::InitDragExit( PDRAGINFO aDragInfo)
|
||||
{
|
||||
// Nothing else to do
|
||||
InitDragOver( aDragInfo);
|
||||
}
|
||||
|
||||
void nsDragService::TermDragExit()
|
||||
{
|
||||
// release draginfo if appropriate. Note we use the slightly icky way
|
||||
// of looking at the value of mDragItems to see if we started the drag.
|
||||
if( !mDragItems)
|
||||
{
|
||||
DrgFreeDraginfo( mDragInfo);
|
||||
mDragInfo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void nsDragService::InitDrop( PDRAGINFO aDragInfo)
|
||||
{
|
||||
// again, doesn't look like there's anything else to do
|
||||
InitDragOver( aDragInfo);
|
||||
}
|
||||
|
||||
void nsDragService::TermDrop()
|
||||
{
|
||||
// do an end-conversation for each dragitem.
|
||||
// Any actual rendering is done in response to the GetData method above.
|
||||
for( PRUint32 i = 0; i < mDragInfo->cditem; i++)
|
||||
{
|
||||
PDRAGITEM pItem = DrgQueryDragitemPtr( mDragInfo, i);
|
||||
DrgSendTransferMsg( pItem->hwndItem,
|
||||
DM_ENDCONVERSATION,
|
||||
MPFROMLONG(pItem->ulItemID),
|
||||
MPFROMSHORT(DMFL_TARGETSUCCESSFUL)); // I suppose
|
||||
}
|
||||
|
||||
TermDragExit();
|
||||
}
|
||||
|
||||
// access the singleton
|
||||
nsresult NS_GetDragService( nsISupports **aDragService)
|
||||
{
|
||||
if( !aDragService)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aDragService = (nsIDragService*)gModuleData.dragService;
|
||||
NS_ADDREF(*aDragService);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Examine a transferable and allocate & fill in appropriate DRAGITEMs
|
||||
void nsDragService::CreateDragItems( PULONG pCount, PDRAGITEM *ppItems,
|
||||
nsITransferable *aTransferable)
|
||||
{
|
||||
nsCOMPtr<nsIFileListTransferable> pFileList = do_QueryInterface(aTransferable);
|
||||
|
||||
if( pFileList)
|
||||
{
|
||||
nsVoidArray aFiles;
|
||||
pFileList->GetFileList( &aFiles);
|
||||
*pCount = aFiles.Count();
|
||||
if( *pCount)
|
||||
{
|
||||
// Create a dragitem for each filespec
|
||||
*ppItems = new DRAGITEM [*pCount];
|
||||
for( PRUint32 i = 0; i < *pCount; i++)
|
||||
{
|
||||
nsFileSpec *pFile = (nsFileSpec*) aFiles.ElementAt(i);
|
||||
FillDragItem( *ppItems + i, pFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppItems = new DRAGITEM [1]; // alloc w' new [] for uniform deletion
|
||||
*pCount = 1;
|
||||
FillDragItem( *ppItems, aTransferable);
|
||||
}
|
||||
}
|
||||
|
||||
void nsDragService::FillDragItem( PDRAGITEM aItem, nsFileSpec *aFilespec)
|
||||
{
|
||||
// We don't have to source-render these, 'cos they're unique files which
|
||||
// already exist (we hope).
|
||||
//
|
||||
// On the down side, I have to trust nsFileSpec...
|
||||
//
|
||||
|
||||
aItem->hwndItem = mDragWnd; // just for completeness
|
||||
aItem->ulItemID = 0;
|
||||
aItem->hstrType = DrgAddStrHandle( DRT_UNKNOWN);
|
||||
// XXX print & discard to come ? Maybe not, actually.
|
||||
aItem->hstrRMF = DrgAddStrHandle( "<DRM_OS2FILE,DRF_UNKNOWN>");
|
||||
|
||||
// (this is a really messy, unwieldy api)
|
||||
nsFileSpec parentDir;
|
||||
aFilespec->GetParent( parentDir);
|
||||
aItem->hstrContainerName = DrgAddStrHandle( nsNSPRPath(parentDir));
|
||||
char *pszLeaf = aFilespec->GetLeafName();
|
||||
aItem->hstrSourceName = DrgAddStrHandle( pszLeaf);
|
||||
aItem->hstrTargetName = DrgAddStrHandle( pszLeaf);
|
||||
nsCRT::free( pszLeaf);
|
||||
|
||||
aItem->cxOffset = aItem->cyOffset = 0;
|
||||
aItem->fsControl = 0;
|
||||
aItem->fsSupportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE;
|
||||
}
|
||||
|
||||
// Transferables passed in here are guaranteed not to be nsIFileListTransferables
|
||||
//
|
||||
void nsDragService::FillDragItem( PDRAGITEM aItem, nsITransferable *aTransferable)
|
||||
{
|
||||
aItem->hwndItem = mDragWnd;
|
||||
|
||||
// ref the transferable to write out the data when we know which is needed
|
||||
aItem->ulItemID = (ULONG) aTransferable;
|
||||
NS_ADDREF(aTransferable);
|
||||
|
||||
// Now go through transferable building things
|
||||
nsVoidArray *pFormats = nsnull;
|
||||
aTransferable->FlavorsTransferableCanExport( &pFormats);
|
||||
|
||||
// XXX DRM_DISCARD and DRM_PRINTFILE to come when xptoolkit decides how
|
||||
// (whether...) to handle them
|
||||
|
||||
char rmf[200] = "(DRM_OS2FILE,DRM_MOZILLA) X (DRF_UNKNOWN";
|
||||
char buff[40];
|
||||
|
||||
PRUint32 cFormats = pFormats->Count();
|
||||
|
||||
for( PRUint32 i = 0; i < cFormats; i++)
|
||||
{
|
||||
nsString *pFlavour = (nsString*) pFormats->ElementAt( i);
|
||||
gModuleData.ConvertFromUcs( *pFlavour, buff, 40);
|
||||
const char *rf = MimeTypeToRF( buff);
|
||||
if( rf)
|
||||
{
|
||||
strcat( rmf, ",");
|
||||
strcat( rmf, rf);
|
||||
}
|
||||
#if 0
|
||||
else if( pFlavour->Equals( kURLMime))
|
||||
{
|
||||
// Abort any processing already done; the idea here is to provide
|
||||
// the URL format so the WPS can do the Right Thing; we also need to
|
||||
// provide some kind of text format for insertion into a program.
|
||||
aItem->hstrType = DrgAddStrHandle( DRT_URL","DRT_TEXT);
|
||||
aItem->hstrRMF = DrgAddStrHandle( "<DRM_OS2FILE,DRF_TEXT>,<DRM_STRHANDLES,DRF_URL>");
|
||||
aItem->hstrContainerName = 0;
|
||||
aItem->hstrSourceName = DrgAddStrHandle( full url );
|
||||
aItem->hstrTargetName = DrgAddStrHandle( title for object );
|
||||
aItem->cxOffset = aItem->cyOffset = 0;
|
||||
aItem->fsControl = 0;
|
||||
aItem->fsSupportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE;
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// Not sure what to do about 'Type'. Setting everything is wrong,
|
||||
// but picking an arbitary one is also bad.
|
||||
//
|
||||
// So leave it as unknown for now.
|
||||
}
|
||||
|
||||
delete pFormats;
|
||||
|
||||
strcat( rmf, ")");
|
||||
|
||||
aItem->hstrType = DrgAddStrHandle( DRT_UNKNOWN);
|
||||
aItem->hstrRMF = DrgAddStrHandle( rmf);
|
||||
|
||||
// For source-rendering, don't supply `source name'
|
||||
nsSpecialSystemDirectory tmpDir(nsSpecialSystemDirectory::OS_TemporaryDirectory);
|
||||
aItem->hstrContainerName = DrgAddStrHandle( nsNSPRPath(tmpDir));
|
||||
aItem->hstrSourceName = 0;
|
||||
aItem->hstrTargetName = DrgAddStrHandle( "ATempFile");
|
||||
aItem->cxOffset = aItem->cyOffset = 0; // DrgDrag() sets these
|
||||
aItem->fsControl = 0;
|
||||
aItem->fsSupportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE;
|
||||
}
|
||||
|
||||
|
||||
// Actually do the drag
|
||||
nsresult nsDragService::InvokeDrag( PDRAGITEM aItems, ULONG aCItems,
|
||||
PRUint32 aActionType)
|
||||
{
|
||||
// keep track of allocated draginfos
|
||||
NS_ASSERTION(!mDragInfo,"Drag info leaked");
|
||||
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
PDRAGINFO pDragInfo = DrgAllocDraginfo( aCItems);
|
||||
|
||||
if( pDragInfo)
|
||||
{
|
||||
pDragInfo->usOperation = DragOperation(aActionType);
|
||||
pDragInfo->hwndSource = mDragWnd;
|
||||
for( PRUint32 i = 0; i < aCItems; i++)
|
||||
DrgSetDragitem( pDragInfo, aItems + i, sizeof(DRAGITEM), i);
|
||||
|
||||
// XXX Need to make a dragimage from somewhere. There ought to be an
|
||||
// nsIImage passed in here, but let's just make something up for now.
|
||||
//
|
||||
// XXX also need to handle the multiple-dragitem case correctly
|
||||
//
|
||||
DRAGIMAGE dimage = { sizeof(DRAGIMAGE), 0, mIcon,
|
||||
{ 0, 0 }, DRG_ICON, 0, 0 };
|
||||
|
||||
// Set draginfo pointer for reentrancy
|
||||
mDragInfo = pDragInfo;
|
||||
mDragItems = aCItems;
|
||||
|
||||
HWND hwndDest = DrgDrag( mDragWnd, pDragInfo, &dimage, 1, VK_ENDDRAG,
|
||||
#ifdef DEBUG
|
||||
(void*) 0x80000000L // makes IPMD happier
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
rc = NS_OK; // hwndDest == 0 may be error or just cancelled; shrug.
|
||||
|
||||
if( !hwndDest)
|
||||
{
|
||||
// Clean up everything here; no async. case to consider.
|
||||
DrgDeleteDraginfoStrHandles( pDragInfo);
|
||||
DrgFreeDraginfo( pDragInfo);
|
||||
mDragInfo = 0;
|
||||
mDragItems = 0;
|
||||
}
|
||||
|
||||
// We don't DrgFreeDragInfo() here if there is a transfer of some sort;
|
||||
// instead this is done when we get the appropriate DM_ENDCONVERSATION.
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Window-proc. for the drag-source window
|
||||
MRESULT EXPENTRY fnwpDragSource( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
MRESULT mr;
|
||||
|
||||
if( gModuleData.dragService)
|
||||
mr = gModuleData.dragService->HandleMessage( msg, mp1, mp2);
|
||||
else
|
||||
mr = WinDefWindowProc( hwnd, msg, mp1, mp2);
|
||||
|
||||
return mr;
|
||||
}
|
||||
|
||||
MRESULT nsDragService::HandleMessage( ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case DM_RENDER:
|
||||
{
|
||||
NS_ASSERTION(mDragItems && mDragInfo, "Spurious DM_RENDER");
|
||||
|
||||
// The target wants us to put some data somewhere.
|
||||
PDRAGTRANSFER pXFer = (PDRAGTRANSFER) mp1;
|
||||
BOOL rc = FALSE;
|
||||
|
||||
// This is vitally important, apparently.
|
||||
pXFer->pditem->hstrSourceName = DrgAddStrHandle( "Dummy.fil");
|
||||
|
||||
if( !pXFer->pditem->ulItemID)
|
||||
{
|
||||
// the target (silly boy) has asked us to source-render something
|
||||
// it's completely capable of rendering all by itself.
|
||||
pXFer->fsReply = DMFL_NATIVERENDER;
|
||||
DrgFreeDragtransfer( pXFer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Need to actually return from this call before we can render the
|
||||
// thing...
|
||||
WinPostMsg( mDragWnd, WM_USER, mp1, mp2);
|
||||
rc = TRUE;
|
||||
}
|
||||
|
||||
return MRFROMLONG(rc);
|
||||
}
|
||||
|
||||
//
|
||||
// Very possibly this should be in a fresh thread.
|
||||
//
|
||||
// This rather large block is the source-side of the source-render
|
||||
// protocol; the target picks which format (from those provided by
|
||||
// the transferable) it would like & where we should put it.
|
||||
//
|
||||
case WM_USER:
|
||||
{
|
||||
// Posted to ourselves in order to carry out a target's desired
|
||||
// rendering.
|
||||
PDRAGTRANSFER pXFer = (PDRAGTRANSFER) mp1;
|
||||
nsITransferable *pTrans = (nsITransferable*) pXFer->pditem->ulItemID;
|
||||
USHORT usFlags = DMFL_RENDERFAIL;
|
||||
|
||||
NS_ASSERTION(pTrans, "No transferable to source-render");
|
||||
|
||||
#ifdef DEBUG
|
||||
char *target = DecodeStrHandle( pXFer->hstrRenderToName);
|
||||
printf( "Source-rendering to %s\n", target);
|
||||
nsFileSpec dest( target);
|
||||
#else
|
||||
nsFileSpec dest( DecodeStrHandle( pXFer->hstrRenderToName));
|
||||
#endif
|
||||
// Now, the fun bit is working out what format to use.
|
||||
char *rmf = DecodeStrHandle( pXFer->hstrSelectedRMF);
|
||||
char rm[50], rf[50];
|
||||
int tokens = sscanf( rmf, "<%s,%s>", rm, rf);
|
||||
|
||||
NS_ASSERTION(tokens == 2, "Couldn't parse hstrSelectedRMF");
|
||||
#ifdef DEBUG
|
||||
printf( "%d - %s %s\n", tokens, rm, rf);
|
||||
#endif
|
||||
if( !strcmp( rm, "DRM_OS2FILE"))
|
||||
{
|
||||
// Go through the transferable's flavours looking for one which
|
||||
// matches the requested rf.
|
||||
nsVoidArray *pFormats = nsnull;
|
||||
char buff[40];
|
||||
pTrans->FlavorsTransferableCanExport( &pFormats);
|
||||
PRUint32 cFormats = pFormats->Count(), i;
|
||||
|
||||
for( i = 0; i < cFormats; i++)
|
||||
{
|
||||
nsString *pFlavour = (nsString*) pFormats->ElementAt( i);
|
||||
gModuleData.ConvertFromUcs( *pFlavour, buff, 40);
|
||||
const char *this_rf = MimeTypeToRF( buff);
|
||||
if( this_rf && !strcmp( this_rf, rf))
|
||||
{
|
||||
// Found it!
|
||||
void *pData;
|
||||
PRUint32 cData;
|
||||
pTrans->GetTransferData( pFlavour, &pData, &cData);
|
||||
|
||||
// (uh-oh)
|
||||
nsOutputFileStream stream(dest);
|
||||
stream.write( pData, (PRInt32)cData);
|
||||
stream.close();
|
||||
usFlags = DMFL_RENDEROK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete pFormats;
|
||||
if( i == cFormats)
|
||||
#ifdef DEBUG
|
||||
printf( "Target asked for format %s which we can't do.\n", rf);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Unexpected rendering mechanism\n");
|
||||
}
|
||||
|
||||
// Tell the target we're done.
|
||||
DrgPostTransferMsg( pXFer->hwndClient,
|
||||
DM_RENDERCOMPLETE,
|
||||
pXFer,
|
||||
usFlags,
|
||||
0,
|
||||
TRUE);
|
||||
|
||||
DrgFreeDragtransfer( pXFer);
|
||||
|
||||
// Note that the transferable we have here will be release'd in
|
||||
// the DM_ENDCONVERSATION for the dragitem in question.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// DRM_MOZILLA messages; see nsWidgetDefs.h for details
|
||||
case WMU_GETFLAVOURLEN:
|
||||
case WMU_GETFLAVOURDATA:
|
||||
{
|
||||
char buffer[40] = "";
|
||||
PRUint32 cData = 0;
|
||||
void *pData;
|
||||
|
||||
nsITransferable *pTrans = (nsITransferable*) mp1;
|
||||
|
||||
if( pTrans)
|
||||
{
|
||||
PWZDROPXFER pXFer = (PWZDROPXFER) mp2;
|
||||
ATOM atom;
|
||||
|
||||
if( msg == WMU_GETFLAVOURLEN) atom = LONGFROMMP(mp2);
|
||||
else atom = pXFer->hAtomFlavour;
|
||||
|
||||
WinQueryAtomName( WinQuerySystemAtomTable(), atom, buffer, 40);
|
||||
nsAutoString str(buffer);
|
||||
if( NS_SUCCEEDED(pTrans->GetTransferData( &str, &pData, &cData)))
|
||||
{
|
||||
if( msg == WMU_GETFLAVOURDATA)
|
||||
{
|
||||
memcpy( &pXFer->data[0], pData, cData);
|
||||
DosFreeMem( pXFer);
|
||||
return MPFROMLONG(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MRFROMLONG(cData);
|
||||
}
|
||||
|
||||
case DM_ENDCONVERSATION:
|
||||
{
|
||||
NS_ASSERTION(mDragItems && mDragInfo, "Unexpected DM_ENDCONVERSATION");
|
||||
|
||||
// If it was necessary (for source-rendering), we kept a reference
|
||||
// to the transferable in the dragitem. Now it's safe to release.
|
||||
nsITransferable *pTransferable = (nsITransferable*) mp1;
|
||||
NS_IF_RELEASE(pTransferable);
|
||||
|
||||
mDragItems--;
|
||||
if( mDragItems == 0)
|
||||
{
|
||||
// the last of the dragitems has been ack'ed, so free the draginfo
|
||||
DrgFreeDraginfo( mDragInfo);
|
||||
mDragInfo = 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf( "DM_ENDCONVERSATION, mDragItems = %d\n", (int)mDragItems);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (*mWndProc)( mDragWnd, msg, mp1, mp2);
|
||||
}
|
||||
|
||||
// Various forms of source-rendering, DRM_MOZILLA and "pushed-file" -------------
|
||||
//
|
||||
// Custom shared-memory rendering mechanism
|
||||
//
|
||||
// Probably ought to just get creative with DRAGTRANSFER as is, but that (a)
|
||||
// confuses the DRM_OS2FILE source-rendering & (b) imposes unhelpful constraints
|
||||
|
||||
void nsDragService::DoMozillaXfer( PDRAGITEM pItem, char *szFlavour,
|
||||
void **ppData, PRUint32 *cData)
|
||||
{
|
||||
// First check if this is an intra-process transfer!
|
||||
if( mDragItems)
|
||||
{
|
||||
// Yes.
|
||||
nsITransferable *pSource = (nsITransferable*) pItem->ulItemID;
|
||||
if( !pSource)
|
||||
printf( "intra-process xfer fails due to null ulItemID\n");
|
||||
else
|
||||
{
|
||||
nsAutoString flavour(szFlavour);
|
||||
if( NS_SUCCEEDED(pSource->GetTransferData( &flavour, ppData, cData)))
|
||||
{
|
||||
// need to make a copy...
|
||||
char *tmp = new char [ *cData ];
|
||||
memcpy( tmp, *ppData, *cData);
|
||||
*ppData = tmp;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
HATOMTBL hAtomTbl = WinQuerySystemAtomTable();
|
||||
ATOM hAtom = WinAddAtom( hAtomTbl, szFlavour);
|
||||
|
||||
ULONG ulLen = (ULONG) WinSendMsg( pItem->hwndItem, WMU_GETFLAVOURLEN,
|
||||
MPFROMLONG(pItem->ulItemID),
|
||||
MPFROMLONG(hAtom));
|
||||
if( ulLen)
|
||||
{
|
||||
void *shmem = 0;
|
||||
if( !DosAllocSharedMem( &shmem, 0, ulLen + sizeof(ATOM),
|
||||
PAG_COMMIT | OBJ_GIVEABLE | PAG_WRITE))
|
||||
{
|
||||
// Find the tid of the source so we can give it the memory
|
||||
PID pid;
|
||||
TID tid;
|
||||
WinQueryWindowProcess( pItem->hwndItem, &pid, &tid);
|
||||
DosGiveSharedMem( shmem, pid, PAG_WRITE);
|
||||
|
||||
PWZDROPXFER pWzData = (PWZDROPXFER) shmem;
|
||||
pWzData->hAtomFlavour = hAtom;
|
||||
|
||||
BOOL ok = (BOOL) WinSendMsg( pItem->hwndItem, WMU_GETFLAVOURDATA,
|
||||
MPFROMLONG(pItem->ulItemID),
|
||||
MPFROMP(pWzData));
|
||||
if( ok)
|
||||
{
|
||||
// now allocate (too many copies I know, but transferable has
|
||||
// restrictions...)
|
||||
char *buf = new char [ ulLen ];
|
||||
memcpy( buf, &pWzData->data[0], ulLen);
|
||||
*cData = ulLen;
|
||||
*ppData = buf;
|
||||
}
|
||||
|
||||
// free shared memory
|
||||
DosFreeMem( shmem);
|
||||
}
|
||||
}
|
||||
|
||||
WinDeleteAtom( hAtomTbl, hAtom);
|
||||
}
|
||||
|
||||
void nsDragService::DoPushedOS2FILE( PDRAGITEM pItem, const char *szRf,
|
||||
void **pData, PRUint32 *cData)
|
||||
{
|
||||
// Unfortunately there's no way we can do this: we must return from DM_DROP
|
||||
// before having a "post-drop conversation" involving DM_RENDER.
|
||||
//
|
||||
// BUT we need to fill the transferable NOW, before we return from DM_DROP
|
||||
// so that gecko (or whoever's underneath us).
|
||||
//
|
||||
// So we're stuck until there's some asynch. way of proceeding.
|
||||
//
|
||||
// But it's not all bad: not many people use source rendering; mozilla
|
||||
// does, but we can use DRM_MOZILLA to do that.
|
||||
|
||||
printf( "\n\nSorry, source-rendering of DRM_OS2FILE not working.\n");
|
||||
printf( "(see mozilla/widget/src/os2/nsDragService::DoPushedOS2FILE)\n\n");
|
||||
}
|
||||
|
||||
// Quick utility functions ------------------------------------------------------
|
||||
|
||||
static char *DecodeStrHandle( HSTR hstr)
|
||||
{
|
||||
static char buf[CCHMAXPATH];
|
||||
DrgQueryStrName( hstr, CCHMAXPATH, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Table to map mozilla "mimetypes" to PM "rendering formats"
|
||||
// Could optimize I guess, but not really important.
|
||||
|
||||
static const char *gFormatMap[][2] =
|
||||
{
|
||||
{ "DRF_TEXT", kTextMime },
|
||||
{ "DRF_UNICODE", kUnicodeMime },
|
||||
{ "DRF_HTML", kHTMLMime },
|
||||
{ "DRF_XIF", kXIFMime },
|
||||
{ "DRF_PNG", kPNGImageMime },
|
||||
{ "DRF_GIF", kGIFImageMime },
|
||||
{ "DRF_JPEG", kJPEGImageMime },
|
||||
{ "DRF_AOLMAIL", kAOLMailMime },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static const char *MimeTypeToRF( const char *pcsz)
|
||||
{
|
||||
int i = 0;
|
||||
while( gFormatMap[i][0])
|
||||
if( !strcmp( pcsz, gFormatMap[i][1])) break;
|
||||
return gFormatMap[i][0];
|
||||
}
|
||||
|
||||
static const char *RFToMimeType( const char *pcsz)
|
||||
{
|
||||
int i = 0;
|
||||
while( gFormatMap[i][0])
|
||||
if( !strcmp( pcsz, gFormatMap[i][0])) break;
|
||||
return gFormatMap[i][1];
|
||||
}
|
||||
|
||||
static BOOL FindFile( PDRAGITEM pItem, nsFileSpec &aFileSpec)
|
||||
{
|
||||
const char *str = DecodeStrHandle( pItem->hstrContainerName);
|
||||
#ifdef DEBUG
|
||||
printf( "Getting drag data from `%s'", str);
|
||||
#endif
|
||||
aFileSpec = str;
|
||||
str = DecodeStrHandle( pItem->hstrSourceName);
|
||||
#ifdef DEBUG
|
||||
printf( "`%s'\n", str);
|
||||
#endif
|
||||
aFileSpec += str;
|
||||
|
||||
return aFileSpec.Exists();
|
||||
}
|
||||
|
||||
static void GetTempFile( nsFileSpec &tempfile)
|
||||
{
|
||||
nsSpecialSystemDirectory tmpDir(nsSpecialSystemDirectory::OS_TemporaryDirectory);
|
||||
tmpDir += "tmpfile";
|
||||
tmpDir.MakeUnique();
|
||||
tempfile = tmpDir;
|
||||
}
|
|
@ -0,0 +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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsdragservice_h
|
||||
#define _nsdragservice_h
|
||||
|
||||
// Drag service. Manages drag & drop events, converts between OS/2 and
|
||||
// mozilla-style databuffers.
|
||||
//
|
||||
// This exists as a singleton in the nsModule; it's created at creation of the
|
||||
// primaeval appshell and destroyed at DLL unload-time.
|
||||
//
|
||||
|
||||
#include "nsBaseDragService.h"
|
||||
|
||||
class nsFileSpec;
|
||||
|
||||
// This implements nsIDragSession and nsIDragService.
|
||||
|
||||
class nsDragService : public nsBaseDragService
|
||||
{
|
||||
public:
|
||||
nsDragService();
|
||||
virtual ~nsDragService();
|
||||
|
||||
// nsIDragService
|
||||
NS_IMETHOD InvokeDragSession( nsISupportsArray *anArrayTransferables,
|
||||
nsIRegion *aRegion, PRUint32 aActionType);
|
||||
NS_IMETHOD InvokeDragSessionSingle( nsITransferable *aTransferable,
|
||||
nsIRegion *aRegion, PRUint32 aActionType);
|
||||
|
||||
// nsIDragSession
|
||||
NS_IMETHOD GetData( nsITransferable *aTransferable, PRUint32 aItemIndex);
|
||||
NS_IMETHOD GetNumDropItems( PRUint32 *aNumItems);
|
||||
NS_IMETHOD IsDataFlavorSupported( nsString *aDataFlavour);
|
||||
|
||||
// platform methods, called from nsWindow
|
||||
void InitDragOver( PDRAGINFO aDragInfo);
|
||||
MRESULT TermDragOver();
|
||||
|
||||
void InitDragExit( PDRAGINFO aDragInfo);
|
||||
void TermDragExit();
|
||||
|
||||
void InitDrop( PDRAGINFO aDragInfo);
|
||||
void TermDrop();
|
||||
|
||||
protected:
|
||||
// Natives
|
||||
void CreateDragItems( PULONG pCount, PDRAGITEM *ppItems,
|
||||
nsITransferable *aTransferable);
|
||||
void FillDragItem( PDRAGITEM aItem, nsITransferable *aTransferable);
|
||||
void FillDragItem( PDRAGITEM aItem, nsFileSpec *aFilespec);
|
||||
nsresult InvokeDrag( PDRAGITEM aItems, ULONG aCItems, PRUint32 aActionType);
|
||||
MRESULT HandleMessage( ULONG msg, MPARAM mp1, MPARAM mp2);
|
||||
void DoPushedOS2FILE( PDRAGITEM pItem, const char *szRf,
|
||||
void **pData, PRUint32 *cData);
|
||||
void DoMozillaXfer( PDRAGITEM pItem, char *szFlavour,
|
||||
void **ppData, PRUint32 *cData);
|
||||
|
||||
HWND mDragWnd;
|
||||
HPOINTER mIcon;
|
||||
|
||||
// State; allocated draginfo & outstanding items
|
||||
PDRAGINFO mDragInfo;
|
||||
PFNWP mWndProc;
|
||||
ULONG mDragItems;
|
||||
|
||||
friend MRESULT EXPENTRY fnwpDragSource(HWND,ULONG,MPARAM,MPARAM);
|
||||
};
|
||||
|
||||
nsresult NS_GetDragService( nsISupports **aDragService);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsEntryField.h"
|
||||
|
||||
NS_IMPL_ADDREF(nsEntryField)
|
||||
NS_IMPL_RELEASE(nsEntryField)
|
||||
|
||||
nsresult nsEntryField::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
nsresult result = nsWindow::QueryInterface( aIID, aInstancePtr);
|
||||
|
||||
if( result == NS_NOINTERFACE && aIID.Equals( nsITextWidget::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsITextWidget*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Textfield messages; all very straight-forward to translate into PM.
|
||||
|
||||
nsresult nsEntryField::GetText( nsString &aTextBuffer, PRUint32 aBufferSize, PRUint32 &size)
|
||||
{
|
||||
nsWindow::GetWindowText( aTextBuffer, &size);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEntryField::SetText( const nsString &aText, PRUint32 &len)
|
||||
{
|
||||
SetTitle( aText);
|
||||
mText = aText;
|
||||
len = aText.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEntryField::InsertText( const nsString &aText, PRUint32 aStartPos,
|
||||
PRUint32 aEndPos, PRUint32 &rc)
|
||||
{
|
||||
PRUint32 dummy;
|
||||
nsString currentText;
|
||||
GetText( currentText, 256, dummy);
|
||||
nsString newText( aText);
|
||||
currentText.Insert( newText, aStartPos, aText.Length());
|
||||
SetText( currentText, dummy);
|
||||
rc = aText.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEntryField::RemoveText()
|
||||
{
|
||||
PRUint32 dummy;
|
||||
SetText( nsString(), dummy);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEntryField::SetPassword( PRBool aIsPassword)
|
||||
{
|
||||
if( mWnd)
|
||||
{
|
||||
if( aIsPassword)
|
||||
AddToStyle( ES_UNREADABLE);
|
||||
else
|
||||
RemoveFromStyle( ES_UNREADABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aIsPassword)
|
||||
mStyle |= ES_UNREADABLE;
|
||||
else
|
||||
mStyle &= ~ES_UNREADABLE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEntryField::SetMaxTextLength( PRUint32 aChars)
|
||||
{
|
||||
short sLength = aChars ? (short) aChars : 500; // !! hmm
|
||||
mOS2Toolkit->SendMsg( mWnd, EM_SETTEXTLIMIT, MPFROMSHORT(sLength));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEntryField::SetReadOnly( PRBool aReadOnlyFlag, PRBool &old)
|
||||
{
|
||||
BOOL bOldState;
|
||||
|
||||
if( mWnd)
|
||||
{
|
||||
bOldState = (BOOL) mOS2Toolkit->SendMsg( mWnd, EM_QUERYREADONLY);
|
||||
mOS2Toolkit->SendMsg( mWnd, EM_SETREADONLY, MPFROMLONG(aReadOnlyFlag));
|
||||
}
|
||||
else
|
||||
{
|
||||
bOldState = mStyle & ES_READONLY;
|
||||
if( aReadOnlyFlag)
|
||||
mStyle |= ES_READONLY;
|
||||
else
|
||||
mStyle &= ~ES_READONLY;
|
||||
}
|
||||
|
||||
old = bOldState ? PR_TRUE : PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEntryField::SelectAll()
|
||||
{
|
||||
SetSelection( 0, 32000);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Maybe off-by-one errors here, test & see
|
||||
nsresult nsEntryField::SetSelection( PRUint32 aStartSel, PRUint32 aEndSel)
|
||||
{
|
||||
mOS2Toolkit->SendMsg( mWnd, EM_SETSEL,
|
||||
MPFROM2SHORT( (short)aStartSel, (short)aEndSel));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEntryField::GetSelection( PRUint32 *aStartSel, PRUint32 *aEndSel)
|
||||
{
|
||||
MRESULT rc = mOS2Toolkit->SendMsg( mWnd, EM_QUERYSEL);
|
||||
if( aStartSel)
|
||||
*aStartSel = SHORT1FROMMR( rc);
|
||||
if( aEndSel)
|
||||
*aEndSel = SHORT2FROMMR( rc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEntryField::SetCaretPosition( PRUint32 aPosition)
|
||||
{
|
||||
SetSelection( aPosition, aPosition);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We're in a bit of trouble here 'cos we can't find out where the cursor
|
||||
// is if there's a selection. Oh well, do what windows does...
|
||||
nsresult nsEntryField::GetCaretPosition( PRUint32 &rc)
|
||||
{
|
||||
PRUint32 selStart, selEnd;
|
||||
GetSelection( &selStart, &selEnd);
|
||||
if( selStart == selEnd)
|
||||
rc = selStart;
|
||||
else
|
||||
rc = (PRUint32) -1;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// platform hooks
|
||||
PCSZ nsEntryField::WindowClass()
|
||||
{
|
||||
return WC_ENTRYFIELD;
|
||||
}
|
||||
|
||||
ULONG nsEntryField::WindowStyle()
|
||||
{
|
||||
return mStyle | ES_MARGIN | ES_LEFT | ES_AUTOSCROLL | BASE_CONTROL_STYLE;
|
||||
}
|
||||
|
||||
nsresult nsEntryField::PreCreateWidget( nsWidgetInitData *aInitData)
|
||||
{
|
||||
if( nsnull != aInitData)
|
||||
{
|
||||
nsTextWidgetInitData *data = (nsTextWidgetInitData *) aInitData;
|
||||
if( data->mIsPassword)
|
||||
mStyle |= ES_UNREADABLE;
|
||||
if( data->mIsReadOnly)
|
||||
mStyle |= ES_READONLY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ULONG nsEntryField::GetSWPFlags( ULONG flags)
|
||||
{
|
||||
// add SWP_NOADJUST to stop ever-increasing entryfields
|
||||
return flags | SWP_NOADJUST;
|
||||
}
|
||||
|
||||
void nsEntryField::PostCreateWidget()
|
||||
{
|
||||
SetMaxTextLength( 0);
|
||||
}
|
|
@ -0,0 +1,921 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.0 (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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// FSTree.cpp - asynchronous directory scanner
|
||||
//
|
||||
// mjf Sunday 06 June 1999
|
||||
//
|
||||
// TODO
|
||||
// * (maybe) Abstract away filing system from scanner ('datasource' idea)
|
||||
//
|
||||
// * Break out Dos* functions to some central useful place
|
||||
//
|
||||
// * Add more fine-grained synchronous-ness (see DirPicker.cpp)
|
||||
//
|
||||
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_DOSDEVIOCTL
|
||||
#define INCL_WIN
|
||||
#include <os2.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
// disable asserts
|
||||
#define NDEBUG
|
||||
#include <assert.h>
|
||||
#include "nsFSTree.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
# define TRACE(x) printf x
|
||||
#else
|
||||
# define TRACE(x)
|
||||
#endif
|
||||
|
||||
// helper Dos* style functions
|
||||
APIRET DosQueryNumDrives( PULONG cDrives);
|
||||
APIRET DosIsDriveRemovable( USHORT drive, PBOOL rem);
|
||||
APIRET DosIsDriveAvailable( USHORT dirve, PBOOL yesno);
|
||||
|
||||
// Simple pipe-based queue class, templated to make some attempt at type-safety
|
||||
template<class T>
|
||||
class Queue
|
||||
{
|
||||
HFILE mRead;
|
||||
HFILE mWrite;
|
||||
|
||||
public:
|
||||
Queue() : mRead(0), mWrite(0) {}
|
||||
~Queue() { Close(); }
|
||||
|
||||
void Create()
|
||||
{
|
||||
DosCreatePipe( &mRead, &mWrite, 1024);
|
||||
}
|
||||
|
||||
APIRET Write( T *aThing)
|
||||
{
|
||||
ULONG ulActual = 0;
|
||||
APIRET rc = DosWrite( mWrite, aThing, sizeof(T), &ulActual);
|
||||
assert( rc || ulActual == sizeof(T));
|
||||
return rc;
|
||||
}
|
||||
|
||||
APIRET Read( T *aThing)
|
||||
{
|
||||
ULONG ulActual = 0;
|
||||
APIRET rc = DosRead( mRead, aThing, sizeof(T), &ulActual);
|
||||
assert( rc || ulActual == sizeof(T));
|
||||
return rc;
|
||||
}
|
||||
|
||||
void Close()
|
||||
{
|
||||
DosClose( mRead);
|
||||
DosClose( mWrite);
|
||||
}
|
||||
};
|
||||
|
||||
class fsFile;
|
||||
class fsDir;
|
||||
|
||||
// messages sent from client to scanning thread
|
||||
struct RQPacket
|
||||
{
|
||||
enum Cmd
|
||||
{
|
||||
Expand,
|
||||
Trash,
|
||||
Foliate,
|
||||
Defoliate
|
||||
};
|
||||
|
||||
Cmd mCmd;
|
||||
fsDir *mDir;
|
||||
|
||||
RQPacket( fsDir *aDir, RQPacket::Cmd aCmd) : mCmd(aCmd), mDir(aDir) {}
|
||||
RQPacket() {}
|
||||
};
|
||||
|
||||
// messages sent from scanner to callback thread
|
||||
struct CBPacket
|
||||
{
|
||||
enum Cmd
|
||||
{
|
||||
CreateRoot,
|
||||
CreateNode,
|
||||
DestroyNode,
|
||||
CreateLeaf,
|
||||
DestroyLeaf,
|
||||
ScanComplete
|
||||
};
|
||||
|
||||
Cmd mCmd;
|
||||
union
|
||||
{
|
||||
fsDir *mDir;
|
||||
fsFile *mFile;
|
||||
} mData;
|
||||
|
||||
CBPacket( fsDir *aDir, CBPacket::Cmd aCmd) : mCmd(aCmd)
|
||||
{ mData.mDir = aDir; }
|
||||
CBPacket( fsFile *aFile, CBPacket::Cmd aCmd) : mCmd(aCmd)
|
||||
{ mData.mFile = aFile; }
|
||||
CBPacket() : mCmd(CBPacket::ScanComplete)
|
||||
{}
|
||||
};
|
||||
|
||||
// fsTree, implementation of main treebuilder class
|
||||
class fsTree : public FS::ITreeBuilder
|
||||
{
|
||||
FS::ICallbacks *mCallbacks;
|
||||
FS::BuildMode mBuildMode;
|
||||
Queue<RQPacket> mRQQueue;
|
||||
Queue<CBPacket> mCBQueue;
|
||||
fsDir *mRoot;
|
||||
HEV mHEV;
|
||||
BOOL mDestructing;
|
||||
HMTX mMutex;
|
||||
BOOL mNeedsPM;
|
||||
|
||||
void SendMsg( fsDir *aDir, RQPacket::Cmd aCmd);
|
||||
void SendMsg( fsDir *aDir, CBPacket::Cmd aCmd);
|
||||
void SendMsg( fsFile *aFile, CBPacket::Cmd aCmd);
|
||||
void SendCompleteMsg();
|
||||
void Scan();
|
||||
void Notify();
|
||||
void CreateRootNode();
|
||||
void CreateDrives();
|
||||
void ScanForChildren( fsDir *aDir);
|
||||
void DestroyNode( fsDir *aDir);
|
||||
void Defoliate( fsDir *aDir);
|
||||
void Foliate( fsDir *aDir);
|
||||
|
||||
friend void _Optlink scannerThread( void *arg)
|
||||
{ ((fsTree*)arg)->Scan(); }
|
||||
|
||||
friend void _Optlink notifyThread( void *arg)
|
||||
{ ((fsTree*)arg)->Notify(); }
|
||||
|
||||
public:
|
||||
fsTree() : mCallbacks(0), mRoot(0), mDestructing(0), mMutex(0), mNeedsPM(0) {}
|
||||
virtual ~fsTree();
|
||||
|
||||
// ITreeBuilder
|
||||
BOOL Init( FS::ICallbacks *aCallbacks);
|
||||
BOOL RequiresPM( BOOL bSet) { mNeedsPM = bSet; return TRUE; }
|
||||
BOOL Build( FS::BuildMode aBuildMode);
|
||||
BOOL Lock();
|
||||
BOOL Unlock();
|
||||
BOOL DeleteInstance();
|
||||
|
||||
// Called by fsDirs in response to user requests
|
||||
void ExpandNode( fsDir *aDir)
|
||||
{ SendMsg( aDir, RQPacket::Expand); }
|
||||
void TrashNode( fsDir *aDir)
|
||||
{ SendMsg( aDir, RQPacket::Trash); }
|
||||
void FoliateNode( fsDir *aDir)
|
||||
{ SendMsg( aDir, RQPacket::Foliate); }
|
||||
void DefoliateNode( fsDir *aDir)
|
||||
{ SendMsg( aDir, RQPacket::Defoliate); }
|
||||
};
|
||||
|
||||
|
||||
// Base fs entity class
|
||||
class fsBase : public FS::IFileInfo
|
||||
{
|
||||
void *mUserData;
|
||||
FILEFINDBUF3 mFindBuf;
|
||||
PSZ mPathname;
|
||||
|
||||
protected:
|
||||
FS::IDir *mParent;
|
||||
|
||||
public:
|
||||
fsBase( FILEFINDBUF3 *aBuf, FS::IDir *aParent) : mUserData(0), mPathname(0),
|
||||
mParent(aParent)
|
||||
{
|
||||
assert(aBuf);
|
||||
memcpy( &mFindBuf, aBuf, sizeof mFindBuf);
|
||||
}
|
||||
|
||||
virtual ~fsBase()
|
||||
{
|
||||
delete [] mPathname;
|
||||
}
|
||||
|
||||
PCSZ GetLeafName() { return mFindBuf.achName; }
|
||||
ULONG GetAttributes() { return mFindBuf.attrFile; }
|
||||
ULONG GetSize() { return mFindBuf.cbFile; }
|
||||
FDATE GetCreationDate() { return mFindBuf.fdateCreation; }
|
||||
FTIME GetCreationTime() { return mFindBuf.ftimeCreation; }
|
||||
FDATE GetLastAccessDate() { return mFindBuf.fdateLastAccess; }
|
||||
FTIME GetLastAccessTime() { return mFindBuf.ftimeLastAccess; }
|
||||
FDATE GetLastWriteDate() { return mFindBuf.fdateLastWrite; }
|
||||
FTIME GetLastWriteTime() { return mFindBuf.ftimeLastWrite; }
|
||||
void *GetUserData() { return mUserData; }
|
||||
void SetUserData( void *aData) { mUserData = aData; }
|
||||
|
||||
PCSZ GetPathName()
|
||||
{
|
||||
if( !mPathname && mParent)
|
||||
{
|
||||
mPathname = new char [ CCHMAXPATH ];
|
||||
PCSZ pszParentPath = mParent->GetFileInfo()->GetPathName();
|
||||
if( pszParentPath)
|
||||
{
|
||||
strcpy( mPathname, pszParentPath);
|
||||
strcat( mPathname, "\\");
|
||||
}
|
||||
else
|
||||
*mPathname = 0;
|
||||
strcat( mPathname, GetLeafName());
|
||||
}
|
||||
return mPathname;
|
||||
}
|
||||
};
|
||||
|
||||
// Files
|
||||
class fsFile : public FS::IFile, public fsBase
|
||||
{
|
||||
fsFile *mNext;
|
||||
|
||||
public:
|
||||
fsFile( FILEFINDBUF3 *aBuf, FS::IDir *aParent) : fsBase(aBuf, aParent),
|
||||
mNext(0)
|
||||
{}
|
||||
|
||||
virtual ~fsFile()
|
||||
{}
|
||||
|
||||
fsFile *GetNext() { return mNext; }
|
||||
FS::IDir *GetParent() { return mParent; } // XXX move into fsBase?
|
||||
FS::IFileInfo *GetFileInfo() { return this; }
|
||||
|
||||
void SetNext( fsFile *aNext) { mNext = aNext; }
|
||||
};
|
||||
|
||||
// Directories
|
||||
class fsDir : public FS::IDir, public fsBase
|
||||
{
|
||||
fsFile *mFiles;
|
||||
fsDir *mChild;
|
||||
fsDir *mSibling;
|
||||
fsTree *mTree;
|
||||
|
||||
#define FSDIR_FOLIATED 1
|
||||
#define FSDIR_EXPANDED 2
|
||||
|
||||
ULONG mFlags;
|
||||
|
||||
public:
|
||||
fsDir( fsTree *aTree, FILEFINDBUF3 *aBuf, FS::IDir *aParent)
|
||||
: fsBase(aBuf, aParent),
|
||||
mFiles(0), mChild(0), mSibling(0), mTree(aTree), mFlags(0)
|
||||
{}
|
||||
|
||||
virtual ~fsDir()
|
||||
{}
|
||||
|
||||
FS::IDir *GetParent() { return mParent; } // XXX move into fsBase?
|
||||
fsDir *GetFirstChild() { return mChild; }
|
||||
fsDir *GetNextSibling() { return mSibling; }
|
||||
void Expand();
|
||||
void Trash();
|
||||
|
||||
fsFile *GetFirstLeaf() { return mFiles; }
|
||||
void Foliate( BOOL aForce);
|
||||
|
||||
fsBase *GetFileInfo() { return this; }
|
||||
|
||||
void SetFiles( fsFile *aFile) { mFiles = aFile; }
|
||||
void SetChild( fsDir *aDir) { mChild = aDir; }
|
||||
void SetSibling( fsDir *aDir) { mSibling = aDir; }
|
||||
|
||||
virtual FS::IDrive *AsDrive() { return 0; }
|
||||
};
|
||||
|
||||
void fsDir::Expand()
|
||||
{
|
||||
if( !(mFlags & FSDIR_EXPANDED))
|
||||
{
|
||||
mTree->ExpandNode( this);
|
||||
mFlags |= FSDIR_EXPANDED;
|
||||
}
|
||||
}
|
||||
|
||||
void fsDir::Trash()
|
||||
{
|
||||
if( mFlags & FSDIR_FOLIATED)
|
||||
mTree->DefoliateNode( this);
|
||||
mTree->TrashNode( this);
|
||||
mFlags = 0;
|
||||
}
|
||||
|
||||
void fsDir::Foliate( BOOL aForce)
|
||||
{
|
||||
if( !(mFlags & FSDIR_FOLIATED) || aForce)
|
||||
{
|
||||
if( aForce)
|
||||
mTree->DefoliateNode( this);
|
||||
mTree->FoliateNode( this);
|
||||
mFlags |= FSDIR_FOLIATED;
|
||||
}
|
||||
}
|
||||
|
||||
// Drives
|
||||
class fsDrive : public FS::IDrive, public fsDir
|
||||
{
|
||||
BOOL mIsRemovable;
|
||||
FSINFO mFSInfo;
|
||||
|
||||
public:
|
||||
fsDrive( fsTree *aTree, FILEFINDBUF3 *aBuf, FS::IDir *aParent)
|
||||
: fsDir( aTree, aBuf, aParent),
|
||||
mIsRemovable((BOOL)-1)
|
||||
{}
|
||||
|
||||
virtual ~fsDrive()
|
||||
{}
|
||||
|
||||
BOOL IsRemovable()
|
||||
{
|
||||
if( mIsRemovable == (BOOL)-1)
|
||||
DosIsDriveRemovable( *GetLeafName() - 'A', &mIsRemovable);
|
||||
return mIsRemovable;
|
||||
}
|
||||
|
||||
PCSZ GetVolumeLabel()
|
||||
{
|
||||
PCSZ pcszLabel = 0;
|
||||
USHORT usDrive = *GetLeafName() - 'A';
|
||||
BOOL bAvail = FALSE;
|
||||
|
||||
// bit of a race here, but it's not critical.
|
||||
|
||||
DosIsDriveAvailable( usDrive, &bAvail);
|
||||
|
||||
if( bAvail)
|
||||
{
|
||||
APIRET rc = DosQueryFSInfo( usDrive + 1, FSIL_VOLSER,
|
||||
&mFSInfo, sizeof mFSInfo);
|
||||
|
||||
if( !rc) pcszLabel = mFSInfo.vol.szVolLabel;
|
||||
}
|
||||
return pcszLabel;
|
||||
}
|
||||
|
||||
fsDrive *AsDrive() { return this; }
|
||||
};
|
||||
|
||||
// fsTree -----------------------------------------------------------------------
|
||||
|
||||
BOOL fsTree::DeleteInstance()
|
||||
{
|
||||
delete this;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
fsTree::~fsTree()
|
||||
{
|
||||
// Execute synchronously to prevent leaky pain
|
||||
mDestructing = TRUE;
|
||||
if( mRoot)
|
||||
DestroyNode( mRoot);
|
||||
|
||||
mRQQueue.Close();
|
||||
mCBQueue.Close();
|
||||
|
||||
if( mHEV)
|
||||
DosCloseEventSem( mHEV);
|
||||
|
||||
if( mMutex)
|
||||
DosCloseMutexSem( mMutex);
|
||||
}
|
||||
|
||||
|
||||
BOOL fsTree::Init( FS::ICallbacks *aCallbacks)
|
||||
{
|
||||
assert(!mCallbacks); // double-init is bad
|
||||
|
||||
mCallbacks = aCallbacks;
|
||||
|
||||
DosCreateMutexSem( 0, &mMutex, 0, 0);
|
||||
DosCreateEventSem( 0, &mHEV, 0, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL fsTree::Build( FS::BuildMode aBuildMode)
|
||||
{
|
||||
assert( mCallbacks); // must have callbacks
|
||||
assert( !mRoot); // can't call twice
|
||||
|
||||
BOOL rc = FALSE;
|
||||
if( mCallbacks && !mRoot)
|
||||
{
|
||||
mBuildMode = aBuildMode;
|
||||
|
||||
mRQQueue.Create();
|
||||
|
||||
_beginthread( scannerThread, 0, 32768, this);
|
||||
|
||||
if( mBuildMode == FS::Synchronous)
|
||||
DosWaitEventSem( mHEV, SEM_INDEFINITE_WAIT);
|
||||
|
||||
rc = TRUE;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL fsTree::Lock()
|
||||
{
|
||||
DosRequestMutexSem( mMutex, SEM_INDEFINITE_WAIT);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL fsTree::Unlock()
|
||||
{
|
||||
DosReleaseMutexSem( mMutex);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void fsTree::SendMsg( fsDir *aDir, RQPacket::Cmd aCmd)
|
||||
{
|
||||
RQPacket packet( aDir, aCmd);
|
||||
APIRET rc = mRQQueue.Write( &packet);
|
||||
|
||||
if( rc)
|
||||
TRACE(( "ERROR: fsTree::SendMsg (RQ) rc = %d\n", (int)rc));
|
||||
}
|
||||
|
||||
void fsTree::SendMsg( fsDir *aDir, CBPacket::Cmd aCmd)
|
||||
{
|
||||
CBPacket packet( aDir, aCmd);
|
||||
APIRET rc = mCBQueue.Write( &packet);
|
||||
|
||||
if( rc)
|
||||
TRACE(( "ERROR: fsTree::SendMsg (CB 1) rc = %d\n", (int)rc));
|
||||
}
|
||||
|
||||
void fsTree::SendMsg( fsFile *aFile, CBPacket::Cmd aCmd)
|
||||
{
|
||||
CBPacket packet( aFile, aCmd);
|
||||
APIRET rc = mCBQueue.Write( &packet);
|
||||
|
||||
if( rc)
|
||||
TRACE(( "ERROR: fsTree::SendMsg (CB 2) rc = %d\n", (int)rc));
|
||||
}
|
||||
|
||||
void fsTree::SendCompleteMsg()
|
||||
{
|
||||
CBPacket packet;
|
||||
APIRET rc = mCBQueue.Write( &packet);
|
||||
|
||||
if( rc)
|
||||
TRACE(( "ERROR: fsTree::SendMsg (CB 3) rc = %d\n", (int)rc));
|
||||
}
|
||||
|
||||
// Scanner thread ---------------------------------------------------------------
|
||||
void fsTree::Scan()
|
||||
{
|
||||
// Set up the notify thread
|
||||
mCBQueue.Create();
|
||||
_beginthread( notifyThread, 0, 32768, this);
|
||||
|
||||
// Do root node
|
||||
CreateRootNode();
|
||||
|
||||
// Do drives -- root dir for each drive
|
||||
// This will do *everything* if we're not in Lazy mode.
|
||||
CreateDrives();
|
||||
|
||||
// Signal that we've done the initial scan.
|
||||
// This lets the user thread go if we're synchronous.
|
||||
SendCompleteMsg();
|
||||
|
||||
// Process commands
|
||||
for(;;)
|
||||
{
|
||||
RQPacket pkt;
|
||||
APIRET rc = mRQQueue.Read( &pkt);
|
||||
if( rc)
|
||||
{
|
||||
TRACE(( "scanThread got rc %d, quitting\n", (int)rc));
|
||||
break;
|
||||
}
|
||||
|
||||
switch( pkt.mCmd)
|
||||
{
|
||||
case RQPacket::Expand:
|
||||
{
|
||||
// scan on each child of pkt.mDir
|
||||
fsDir *pDir = pkt.mDir->GetFirstChild();
|
||||
while( pDir)
|
||||
{
|
||||
ScanForChildren( pDir);
|
||||
pDir = pDir->GetNextSibling();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case RQPacket::Trash:
|
||||
{
|
||||
// Refresh a node - destroy tree below & rescan at top level.
|
||||
fsDir *pDir = pkt.mDir->GetFirstChild();
|
||||
pkt.mDir->SetChild(0);
|
||||
while( pDir)
|
||||
{
|
||||
fsDir *pTemp = pDir->GetNextSibling();
|
||||
Lock();
|
||||
DestroyNode( pDir); // pDir no longer valid
|
||||
Unlock();
|
||||
pDir = pTemp;
|
||||
}
|
||||
ScanForChildren( pkt.mDir);
|
||||
break;
|
||||
}
|
||||
|
||||
case RQPacket::Foliate:
|
||||
// scan for files in pkt.mDir
|
||||
Foliate( pkt.mDir);
|
||||
break;
|
||||
|
||||
case RQPacket::Defoliate:
|
||||
// remove all leaves from pkt.mDir
|
||||
Defoliate( pkt.mDir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fsTree::CreateRootNode()
|
||||
{
|
||||
FILEFINDBUF3 buf = { 0 };
|
||||
strcpy( buf.achName, "$ROOT");
|
||||
buf.cchName = 5;
|
||||
mRoot = new fsDir( this, &buf, 0);
|
||||
SendMsg( mRoot, CBPacket::CreateRoot);
|
||||
}
|
||||
|
||||
void fsTree::CreateDrives()
|
||||
{
|
||||
ULONG ulDrives = 0;
|
||||
DosQueryNumDrives( &ulDrives);
|
||||
|
||||
fsDrive *pPrev = 0;
|
||||
|
||||
// go through the drives one by one
|
||||
for( UINT i = 0; i < ulDrives; i++)
|
||||
{
|
||||
APIRET rc;
|
||||
FILESTATUS3 fs3 = { { 0, 0, 0 } };
|
||||
FILEFINDBUF3 ffb3 = { 0 };
|
||||
|
||||
strcpy( ffb3.achName, "A:\\");
|
||||
ffb3.achName[0] += i;
|
||||
|
||||
// create drive node from disk data
|
||||
DosError(0);
|
||||
rc = DosQueryPathInfo( ffb3.achName, FIL_STANDARD, &fs3, sizeof fs3);
|
||||
DosError(1);
|
||||
|
||||
ffb3.achName[2] = 0;
|
||||
memcpy( &ffb3.fdateCreation, &fs3, sizeof fs3);
|
||||
|
||||
// Insert drive node into tree
|
||||
fsDrive *pDrive = new fsDrive( this, &ffb3, mRoot);
|
||||
Lock();
|
||||
if( !pPrev) mRoot->SetChild( pDrive);
|
||||
else pPrev->SetSibling( pDrive);
|
||||
pPrev = pDrive;
|
||||
Unlock();
|
||||
|
||||
SendMsg( pDrive, CBPacket::CreateNode);
|
||||
}
|
||||
|
||||
// now scan for children. Splitting the task up this way makes UIs more
|
||||
// responsive, as they can wap up the roots first before going digging.
|
||||
fsDir *pDir = mRoot->GetFirstChild();
|
||||
while( pDir)
|
||||
{
|
||||
ScanForChildren( pDir);
|
||||
pDir = pDir->GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
void fsTree::ScanForChildren( fsDir *aParent)
|
||||
{
|
||||
// Look through the directory indicated for child directories and
|
||||
// insert them into the tree.
|
||||
char buffer[CCHMAXPATH] = "";
|
||||
APIRET rc;
|
||||
HDIR hDir = HDIR_CREATE;
|
||||
ULONG ulCount = 1;
|
||||
FILEFINDBUF3 fb;
|
||||
|
||||
fsDir *pPrev = 0;
|
||||
|
||||
strcpy( buffer, aParent->GetPathName());
|
||||
strcat( buffer, "\\*");
|
||||
|
||||
// Scan for directories & build node-list
|
||||
|
||||
DosError(0);
|
||||
rc = DosFindFirst( buffer, &hDir,
|
||||
MUST_HAVE_DIRECTORY | FILE_ARCHIVED | FILE_SYSTEM |
|
||||
FILE_HIDDEN | FILE_READONLY | FILE_DIRECTORY,
|
||||
&fb, sizeof fb,
|
||||
&ulCount, FIL_STANDARD);
|
||||
DosError(1);
|
||||
|
||||
while( !rc)
|
||||
{
|
||||
if( strcmp( fb.achName, ".") && strcmp( fb.achName, ".."))
|
||||
{
|
||||
Lock();
|
||||
fsDir *pDir = new fsDir( this, &fb, aParent);
|
||||
if( !pPrev) aParent->SetChild( pDir);
|
||||
else pPrev->SetSibling( pDir);
|
||||
pPrev = pDir;
|
||||
Unlock();
|
||||
|
||||
SendMsg( pDir, CBPacket::CreateNode);
|
||||
|
||||
// If we're not in lazy mode, recurse (ahem!)
|
||||
if( mBuildMode != FS::Lazy)
|
||||
ScanForChildren( pDir);
|
||||
|
||||
}
|
||||
rc = DosFindNext( hDir, &fb, sizeof fb, &ulCount);
|
||||
}
|
||||
|
||||
DosFindClose( hDir);
|
||||
}
|
||||
|
||||
// Destroy a node (recursively)
|
||||
void fsTree::DestroyNode( fsDir *aDir)
|
||||
{
|
||||
fsDir *aNotherDir = aDir->GetNextSibling();
|
||||
if( aNotherDir)
|
||||
{
|
||||
DestroyNode( aNotherDir);
|
||||
aDir->SetSibling( 0);
|
||||
}
|
||||
|
||||
aNotherDir = aDir->GetFirstChild();
|
||||
if( aNotherDir)
|
||||
{
|
||||
DestroyNode( aNotherDir);
|
||||
aDir->SetChild( 0);
|
||||
}
|
||||
|
||||
if( mDestructing)
|
||||
{
|
||||
Defoliate( aDir);
|
||||
mCallbacks->DestroyDir( aDir);
|
||||
delete aDir;
|
||||
}
|
||||
else
|
||||
SendMsg( aDir, CBPacket::DestroyNode);
|
||||
}
|
||||
|
||||
// Destroy a node's leaves
|
||||
void fsTree::Defoliate( fsDir *aDir)
|
||||
{
|
||||
Lock();
|
||||
|
||||
fsFile *pFile = aDir->GetFirstLeaf();
|
||||
|
||||
while( pFile)
|
||||
{
|
||||
fsFile *pTemp = pFile->GetNext();
|
||||
pFile->SetNext(0);
|
||||
|
||||
if( mDestructing)
|
||||
{
|
||||
mCallbacks->DestroyFile( pFile);
|
||||
delete pFile;
|
||||
}
|
||||
else
|
||||
SendMsg( pFile, CBPacket::DestroyLeaf);
|
||||
|
||||
pFile = pTemp;
|
||||
}
|
||||
|
||||
aDir->SetFiles( 0);
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
// Examine directory and add files to tree
|
||||
void fsTree::Foliate( fsDir *aDir)
|
||||
{
|
||||
FILEFINDBUF3 fb = { 0 };
|
||||
APIRET rc = 0;
|
||||
ULONG ulCount = 1;
|
||||
HDIR hDir = HDIR_CREATE;
|
||||
char path[ CCHMAXPATH];
|
||||
|
||||
strcpy( path, aDir->GetPathName());
|
||||
strcat( path, "\\*");
|
||||
|
||||
// Scan for files
|
||||
|
||||
DosError(0);
|
||||
rc = DosFindFirst( path, &hDir,
|
||||
FILE_ARCHIVED | FILE_SYSTEM |
|
||||
FILE_HIDDEN | FILE_READONLY,
|
||||
&fb, sizeof fb,
|
||||
&ulCount,
|
||||
FIL_STANDARD);
|
||||
DosError(1);
|
||||
fsFile *pLast = 0;
|
||||
|
||||
while( !rc)
|
||||
{
|
||||
Lock();
|
||||
fsFile *pFile = new fsFile( &fb, aDir);
|
||||
if( !pLast) aDir->SetFiles( pFile);
|
||||
else pLast->SetNext( pFile);
|
||||
pLast = pFile;
|
||||
Unlock();
|
||||
|
||||
SendMsg( pFile, CBPacket::CreateLeaf);
|
||||
|
||||
rc = DosFindNext( hDir, &fb, sizeof fb, &ulCount);
|
||||
}
|
||||
|
||||
DosFindClose( hDir);
|
||||
}
|
||||
|
||||
// Notify thread ----------------------------------------------------------------
|
||||
void fsTree::Notify()
|
||||
{
|
||||
// Create PM if necessary (hackish, sorry)
|
||||
HAB hab;
|
||||
HMQ hmq;
|
||||
|
||||
if( mNeedsPM)
|
||||
{
|
||||
hab = WinInitialize( 0);
|
||||
hmq = WinCreateMsgQueue( hab, 0);
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
CBPacket pkt;
|
||||
APIRET rc = mCBQueue.Read( &pkt);
|
||||
if( rc)
|
||||
{
|
||||
TRACE(( "notifyThread got rc %d, quitting\n", (int)rc));
|
||||
break;
|
||||
}
|
||||
|
||||
switch( pkt.mCmd)
|
||||
{
|
||||
case CBPacket::CreateRoot:
|
||||
mCallbacks->CreateRoot( pkt.mData.mDir);
|
||||
break;
|
||||
|
||||
case CBPacket::CreateNode:
|
||||
mCallbacks->CreateDir( pkt.mData.mDir);
|
||||
break;
|
||||
|
||||
case CBPacket::DestroyNode:
|
||||
mCallbacks->DestroyDir( pkt.mData.mDir);
|
||||
delete pkt.mData.mDir;
|
||||
break;
|
||||
|
||||
case CBPacket::CreateLeaf:
|
||||
mCallbacks->CreateFile( pkt.mData.mFile);
|
||||
break;
|
||||
|
||||
case CBPacket::DestroyLeaf:
|
||||
mCallbacks->DestroyFile( pkt.mData.mFile);
|
||||
delete pkt.mData.mFile;
|
||||
break;
|
||||
|
||||
case CBPacket::ScanComplete:
|
||||
mCallbacks->InitialScanComplete();
|
||||
if( mBuildMode == FS::Synchronous)
|
||||
DosPostEventSem( mHEV);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( mNeedsPM)
|
||||
{
|
||||
WinDestroyMsgQueue( hmq);
|
||||
WinTerminate( hab);
|
||||
}
|
||||
}
|
||||
|
||||
// Bootstrap --------------------------------------------------------------------
|
||||
FS::ITreeBuilder *FS::CreateTreeBuilder()
|
||||
{
|
||||
return new fsTree;
|
||||
}
|
||||
|
||||
// Dos-functions ----------------------------------------------------------------
|
||||
APIRET DosQueryNumDrives( PULONG cDrives)
|
||||
{
|
||||
int i;
|
||||
BOOL dummy;
|
||||
for( i = 0; i < 26; i++)
|
||||
if( DosIsDriveRemovable( i, &dummy)) break;
|
||||
*cDrives = i;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
APIRET DosIsDriveRemovable( USHORT drive, PBOOL rem)
|
||||
{
|
||||
struct {
|
||||
BYTE commandInformation;
|
||||
BYTE driveUnit;
|
||||
} driveRequest;
|
||||
ULONG parmSize;
|
||||
BIOSPARAMETERBLOCK driveInfo;
|
||||
ULONG dataSize;
|
||||
APIRET rc;
|
||||
|
||||
driveRequest.commandInformation = 0;
|
||||
driveRequest.driveUnit = drive;
|
||||
parmSize = sizeof driveRequest;
|
||||
dataSize = sizeof driveInfo;
|
||||
memset( &driveInfo, 0, dataSize);
|
||||
DosError(0);
|
||||
rc = DosDevIOCtl( (HFILE)-1, IOCTL_DISK, DSK_GETDEVICEPARAMS,
|
||||
&driveRequest, parmSize, &parmSize,
|
||||
&driveInfo, dataSize, &dataSize);
|
||||
DosError(1);
|
||||
|
||||
if( !rc && !driveInfo.bDeviceType) rc = ERROR_INVALID_DRIVE;
|
||||
else *rem = !(driveInfo.fsDeviceAttr & 1);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
APIRET DosIsDriveAvailable( USHORT drive, PBOOL yesno)
|
||||
{
|
||||
APIRET rc = 1;//DosIsDriveRemovable( drive, yesno);
|
||||
|
||||
if( !rc && !*yesno)
|
||||
{
|
||||
*yesno = TRUE; // bad assumption ?
|
||||
}
|
||||
else
|
||||
{
|
||||
#pragma pack(1)
|
||||
|
||||
struct {
|
||||
UCHAR commandInformation;
|
||||
USHORT driveunit;
|
||||
} paramPacket;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
ULONG paramSize;
|
||||
USHORT dataPacket;
|
||||
ULONG dataSize;
|
||||
|
||||
paramPacket.commandInformation = 0;
|
||||
paramPacket.driveunit = drive;
|
||||
paramSize = sizeof paramPacket;
|
||||
dataPacket = 0;
|
||||
dataSize = sizeof dataPacket;
|
||||
|
||||
rc = DosDevIOCtl( (HFILE)-1, IOCTL_DISK, DSK_GETLOCKSTATUS,
|
||||
¶mPacket, paramSize, ¶mSize,
|
||||
&dataPacket, dataSize, &dataSize);
|
||||
|
||||
/* drive is available if (a) there is media (b) drive not locked */
|
||||
*yesno = !rc && (dataPacket & 0x4) && ((dataPacket & 3) != 1);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.0 (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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// FSTree -- filing-system-tree-builder
|
||||
//
|
||||
// This is in mozilla to provide an adaquate 'choose directory' dialog.
|
||||
// It could be used to provide a nice 'choose file' dialog as well.
|
||||
//
|
||||
// * Lazy or eager
|
||||
// * Synchronous or asynchronous
|
||||
// * UI-free
|
||||
//
|
||||
// mjf Sunday 06 June 1999, rehashing various versions of this code written for
|
||||
// various purposes written over the past few years into one beauteous whole.
|
||||
//
|
||||
// The interface scheme is something of an experiment.
|
||||
//
|
||||
|
||||
#ifndef _fstree_h
|
||||
#define _fstree_h
|
||||
|
||||
// Name-space for interfaces
|
||||
struct FS
|
||||
{
|
||||
// Base class for filing-system entities
|
||||
class IFileInfo
|
||||
{
|
||||
public:
|
||||
virtual PCSZ GetLeafName() = 0;
|
||||
virtual PCSZ GetPathName() = 0;
|
||||
virtual ULONG GetAttributes() = 0;
|
||||
virtual ULONG GetSize() = 0;
|
||||
virtual FDATE GetCreationDate() = 0;
|
||||
virtual FTIME GetCreationTime() = 0;
|
||||
virtual FDATE GetLastAccessDate() = 0;
|
||||
virtual FTIME GetLastAccessTime() = 0;
|
||||
virtual FDATE GetLastWriteDate() = 0;
|
||||
virtual FTIME GetLastWriteTime() = 0;
|
||||
|
||||
virtual void *GetUserData() = 0;
|
||||
virtual void SetUserData( void *aUserData) = 0;
|
||||
};
|
||||
|
||||
class IDir;
|
||||
|
||||
// Files
|
||||
class IFile
|
||||
{
|
||||
public:
|
||||
virtual IFile *GetNext() = 0;
|
||||
virtual IDir *GetParent() = 0;
|
||||
virtual IFileInfo *GetFileInfo() = 0;
|
||||
};
|
||||
|
||||
class IDrive;
|
||||
|
||||
// Directories
|
||||
class IDir
|
||||
{
|
||||
public:
|
||||
virtual IDir *GetParent() = 0;
|
||||
virtual IDir *GetFirstChild() = 0;
|
||||
virtual IDir *GetNextSibling() = 0;
|
||||
virtual void Expand() = 0;
|
||||
virtual void Trash() = 0;
|
||||
|
||||
virtual IFile *GetFirstLeaf() = 0;
|
||||
virtual void Foliate( BOOL bForceRefresh) = 0;
|
||||
|
||||
virtual IFileInfo *GetFileInfo() = 0;
|
||||
|
||||
virtual IDrive *AsDrive() = 0;
|
||||
};
|
||||
|
||||
// Drives
|
||||
class IDrive
|
||||
{
|
||||
public:
|
||||
virtual BOOL IsRemovable() = 0;
|
||||
virtual PCSZ GetVolumeLabel() = 0;
|
||||
};
|
||||
|
||||
// Callbacks (clients implement this interface)
|
||||
class ICallbacks
|
||||
{
|
||||
public:
|
||||
// The meta node, parent of all drives
|
||||
virtual void CreateRoot( IDir *aRootNode) = 0;
|
||||
// Callback to notify completion of initial scan
|
||||
virtual void InitialScanComplete() = 0;
|
||||
// All directories named here have parents
|
||||
virtual void CreateDir( IDir *aNewNode) = 0;
|
||||
// Clean up user data if necessary
|
||||
virtual void DestroyDir( IDir *aNode) = 0;
|
||||
virtual void CreateFile( IFile *aNewLeaf) = 0;
|
||||
// Clean up user data if necessary
|
||||
virtual void DestroyFile( IFile *aLeaf) = 0;
|
||||
};
|
||||
|
||||
enum BuildMode // ways in which tree can be built
|
||||
{
|
||||
Lazy, // keep 1 level ahead of expand requests
|
||||
Eager, // expand until there's nothing left to do
|
||||
Synchronous // do everything (as for Eager) before Build() returns
|
||||
};
|
||||
|
||||
// Tree builder
|
||||
class ITreeBuilder
|
||||
{
|
||||
public:
|
||||
virtual BOOL Init( ICallbacks *aCallbacks) = 0;
|
||||
virtual BOOL RequiresPM( BOOL bSet) = 0;
|
||||
virtual BOOL Build( BuildMode aBuildMode) = 0;
|
||||
virtual BOOL Lock() = 0;
|
||||
virtual BOOL Unlock() = 0;
|
||||
virtual BOOL DeleteInstance() = 0;
|
||||
};
|
||||
|
||||
// Bootstrap (use DeleteInstance() to destroy)
|
||||
static ITreeBuilder *CreateTreeBuilder();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsIToolkit.h"
|
||||
#include "nsFileDialog.h"
|
||||
#include "nsDirPicker.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// File dialog.
|
||||
//
|
||||
// ToDo: types array
|
||||
|
||||
nsFileDialog::nsFileDialog() : mWndOwner( 0), mCFilters(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
memset( &mFileDlg, 0, sizeof mFileDlg);
|
||||
mFileDlg.cbSize = sizeof mFileDlg;
|
||||
mFileDlg.fl = FDS_CENTER | FDS_ENABLEFILELB;
|
||||
strcpy( mFileDlg.szFullFile, "*.*");
|
||||
}
|
||||
|
||||
nsFileDialog::~nsFileDialog()
|
||||
{
|
||||
if( mFileDlg.pszTitle)
|
||||
free( mFileDlg.pszTitle);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsFileDialog,nsIFileWidget::GetIID())
|
||||
|
||||
nsresult nsFileDialog::Create( nsIWidget *aParent,
|
||||
const nsString &aTitle,
|
||||
nsFileDlgMode aMode,
|
||||
nsIDeviceContext *aContext,
|
||||
nsIAppShell *aAppShell,
|
||||
nsIToolkit *aToolkit,
|
||||
void *aInitData)
|
||||
{
|
||||
// set owner
|
||||
if( aParent)
|
||||
mWndOwner = (HWND) aParent->GetNativeData( NS_NATIVE_WIDGET);
|
||||
else
|
||||
mWndOwner = HWND_DESKTOP;
|
||||
|
||||
if( mFileDlg.pszTitle)
|
||||
{
|
||||
free( mFileDlg.pszTitle);
|
||||
mFileDlg.pszTitle = 0;
|
||||
}
|
||||
if( aTitle.Length() > 0)
|
||||
mFileDlg.pszTitle = strdup( gModuleData.ConvertFromUcs( aTitle));
|
||||
|
||||
if( aMode == eMode_load)
|
||||
mFileDlg.fl |= FDS_OPEN_DIALOG;
|
||||
else if( aMode == eMode_save)
|
||||
mFileDlg.fl |= FDS_SAVEAS_DIALOG;
|
||||
else
|
||||
NS_ASSERTION(0, "Dodgy file dialog type");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// FQ Filename (I suspect this method will vanish)
|
||||
nsresult nsFileDialog::SetDefaultString( const nsString &aString)
|
||||
{
|
||||
gModuleData.ConvertFromUcs( aString, mFileDlg.szFullFile, CCHMAXPATH);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFileDialog::SetDisplayDirectory( const nsFileSpec &aDirectory)
|
||||
{
|
||||
// first copy the file part of whatever we have into 'buff'
|
||||
char buff[CCHMAXPATH] = "";
|
||||
char *lastslash = strrchr( mFileDlg.szFullFile, '\\');
|
||||
|
||||
strcpy( buff, lastslash ? lastslash + 1 : mFileDlg.szFullFile);
|
||||
|
||||
// Now copy directory from filespec into filedlg
|
||||
strcpy( mFileDlg.szFullFile, nsNSPRPath(aDirectory));
|
||||
|
||||
// Ensure there's a trailing backslash...
|
||||
if( '\\' != lastchar( mFileDlg.szFullFile))
|
||||
strcat( mFileDlg.szFullFile, "\\");
|
||||
|
||||
// ...and stick the file back on.
|
||||
strcat( mFileDlg.szFullFile, buff);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "SetDisplayDir, szFullFile = %s\n", mFileDlg.szFullFile);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFileDialog::GetDisplayDirectory( nsFileSpec &aDirectory)
|
||||
{
|
||||
char buff[CCHMAXPATH] = "";
|
||||
strcpy( buff, mFileDlg.szFullFile);
|
||||
printf( "mFileDlg.szFullFile = %s\n", buff);
|
||||
char *lastslash = strrchr( buff, '\\');
|
||||
|
||||
if( lastslash && '\0' != *lastslash)
|
||||
*lastslash = '\0';
|
||||
else
|
||||
// no directory set
|
||||
*buff = '\0';
|
||||
|
||||
aDirectory = (const char*) buff;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFileDialog::SetFilterList( PRUint32 aNumberOfFilters,
|
||||
const nsString aTitles[],
|
||||
const nsString aFilters[])
|
||||
{
|
||||
//
|
||||
// XXX really need a subclassed file dialog for this.
|
||||
// Just using the papszITypeList doesn't work because that's meant to
|
||||
// be .TYPE eas.
|
||||
//
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFileDialog::GetSelectedType( PRInt16 &theType)
|
||||
{
|
||||
theType = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// return false if cancel happens.
|
||||
PRBool nsFileDialog::Show()
|
||||
{
|
||||
PRBool rc = PR_TRUE;
|
||||
|
||||
WinFileDlg( HWND_DESKTOP, mWndOwner, &mFileDlg);
|
||||
if( mFileDlg.lReturn == DID_CANCEL)
|
||||
rc = PR_FALSE;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsFileDialog::GetFile( nsFileSpec &aSpec)
|
||||
{
|
||||
aSpec = mFileDlg.szFullFile;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Methods for folks who can't be bothered to call Create() & Show()
|
||||
nsFileDlgResults nsFileDialog::GetFile( nsIWidget *aParent,
|
||||
const nsString &promptString,
|
||||
nsFileSpec &theFileSpec)
|
||||
{
|
||||
nsFileDlgResults rc = nsFileDlgResults_Cancel;
|
||||
|
||||
Create( aParent, promptString, eMode_load);
|
||||
|
||||
if( Show())
|
||||
{
|
||||
rc = nsFileDlgResults_OK;
|
||||
GetFile( theFileSpec);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsFileDlgResults nsFileDialog::PutFile( nsIWidget *aParent,
|
||||
const nsString &promptString,
|
||||
nsFileSpec &theFileSpec)
|
||||
{
|
||||
nsFileDlgResults rc = nsFileDlgResults_Cancel;
|
||||
|
||||
Create( aParent, promptString, eMode_save);
|
||||
|
||||
if( Show())
|
||||
{
|
||||
rc = nsFileDlgResults_OK;
|
||||
GetFile( theFileSpec);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsFileDlgResults nsFileDialog::GetFolder( nsIWidget *aParent,
|
||||
const nsString &promptString,
|
||||
nsFileSpec &theFileSpec)
|
||||
{
|
||||
nsFileDlgResults rc = nsFileDlgResults_Cancel;
|
||||
|
||||
HWND hwndOwner = HWND_DESKTOP;
|
||||
if( aParent)
|
||||
hwndOwner = (HWND) aParent->GetNativeData( NS_NATIVE_WIDGET);
|
||||
|
||||
DIRPICKER dp = { { 0 }, 0, TRUE, 0 }; // modal dialog
|
||||
|
||||
gModuleData.ConvertFromUcs( promptString, dp.szFullFile, CCHMAXPATH);
|
||||
|
||||
HWND ret = FS_PickDirectory( HWND_DESKTOP, hwndOwner,
|
||||
gModuleData.hModResources, &dp);
|
||||
|
||||
if( ret && dp.lReturn == DID_OK)
|
||||
{
|
||||
theFileSpec = dp.szFullFile;
|
||||
strcpy( mFileDlg.szFullFile, dp.szFullFile); // just in case...
|
||||
rc = nsFileDlgResults_OK;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsFontServices.h"
|
||||
#include "nsIFontNameIterator.h"
|
||||
#include "nsIFontSizeIterator.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// FONTMETRICS are obtained and stored in a datastructure which is optimized
|
||||
// towards the enumeration-style purpose for which they are required in this
|
||||
// toolkit (primarily to populate combobox widgets, I guess)
|
||||
|
||||
class FaceInstance
|
||||
{
|
||||
PFONTMETRICS mFontMetrics;
|
||||
FaceInstance *mNext;
|
||||
|
||||
public:
|
||||
FaceInstance( PFONTMETRICS aMetrics) : mFontMetrics(aMetrics), mNext(0)
|
||||
{}
|
||||
|
||||
~FaceInstance()
|
||||
{
|
||||
delete mNext;
|
||||
}
|
||||
|
||||
PRBool IsScalable()
|
||||
{
|
||||
return mFontMetrics->fsDefn & FM_DEFN_OUTLINE;
|
||||
}
|
||||
|
||||
double GetPointSize()
|
||||
{
|
||||
return ((double)mFontMetrics->sNominalPointSize) / 10.0;
|
||||
}
|
||||
|
||||
void Append( FaceInstance *aInstance)
|
||||
{
|
||||
if( IsScalable() || GetPointSize() == aInstance->GetPointSize())
|
||||
delete aInstance;
|
||||
else
|
||||
{
|
||||
if( !mNext) mNext = aInstance;
|
||||
else mNext->Append( aInstance);
|
||||
}
|
||||
}
|
||||
|
||||
FaceInstance *GetNext() { return mNext; }
|
||||
};
|
||||
|
||||
|
||||
class FontFamily
|
||||
{
|
||||
char *mFamName;
|
||||
FaceInstance *mInstances;
|
||||
FontFamily *mNext;
|
||||
|
||||
public:
|
||||
FontFamily( PFONTMETRICS aMetrics) : mFamName(0), mInstances(0), mNext(0)
|
||||
{
|
||||
mFamName = strdup( aMetrics->szFamilyname);
|
||||
mInstances = new FaceInstance( aMetrics);
|
||||
}
|
||||
|
||||
~FontFamily()
|
||||
{
|
||||
if( mFamName) free( mFamName);
|
||||
delete mInstances;
|
||||
delete mNext;
|
||||
}
|
||||
|
||||
void Append( FontFamily *aFamily)
|
||||
{
|
||||
if( !mNext) mNext = aFamily;
|
||||
else mNext->Append( aFamily);
|
||||
}
|
||||
|
||||
FontFamily *GetNext() { return mNext; }
|
||||
|
||||
FaceInstance *GetInstances() { return mInstances; }
|
||||
const char *GetName() const { return mFamName; }
|
||||
// XXX maybe have a method here to do the system atom-table thing
|
||||
// ("good grief", I know...)
|
||||
};
|
||||
|
||||
class FontLister
|
||||
{
|
||||
FontFamily *mFamilies;
|
||||
FontFamily *mCache;
|
||||
PFONTMETRICS mMetrics;
|
||||
|
||||
public:
|
||||
// XXX ought to take a DC or PS or something...
|
||||
FontLister() : mFamilies(0), mCache(0), mMetrics(0)
|
||||
{
|
||||
HPS hps = WinGetScreenPS( HWND_DESKTOP);
|
||||
|
||||
// Get fontmetrics for the display
|
||||
LONG lWant = 0, lFonts;
|
||||
lFonts = GpiQueryFonts( hps, QF_PUBLIC | QF_PRIVATE,
|
||||
0, &lWant, 0, 0);
|
||||
mMetrics = new FONTMETRICS [ lFonts ];
|
||||
|
||||
GpiQueryFonts( hps, QF_PUBLIC | QF_PRIVATE, 0, &lFonts,
|
||||
sizeof( FONTMETRICS), mMetrics);
|
||||
|
||||
// now stick 'em in our datastructures
|
||||
for( LONG l = 0; l < lFonts; l++)
|
||||
{
|
||||
FontFamily *pFamily = FindFamily( mMetrics[l].szFamilyname);
|
||||
if( pFamily)
|
||||
{
|
||||
FaceInstance *pInstance = new FaceInstance( mMetrics + l);
|
||||
pFamily->GetInstances()->Append( pInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
pFamily = new FontFamily( mMetrics + l);
|
||||
if( !mFamilies) mFamilies = pFamily;
|
||||
else mFamilies->Append( pFamily);
|
||||
}
|
||||
}
|
||||
|
||||
WinReleasePS( hps);
|
||||
}
|
||||
|
||||
~FontLister()
|
||||
{
|
||||
delete mFamilies;
|
||||
delete [] mMetrics;
|
||||
}
|
||||
|
||||
FontFamily *FindFamily( const char *aName)
|
||||
{
|
||||
if( !mCache || stricmp( mCache->GetName(), aName))
|
||||
{
|
||||
FontFamily *pFamily = mFamilies;
|
||||
while( pFamily)
|
||||
{
|
||||
if( !stricmp( pFamily->GetName(), aName))
|
||||
break;
|
||||
pFamily = pFamily->GetNext();
|
||||
}
|
||||
mCache = pFamily;
|
||||
}
|
||||
return mCache;
|
||||
}
|
||||
|
||||
FontFamily *GetFamilies() { return mFamilies; }
|
||||
};
|
||||
|
||||
// Now declare a couple of iterators for font size and name.
|
||||
// Could maybe share code somehow (base template class?)
|
||||
|
||||
// Font-size iterator (xpcom)
|
||||
class nsFontSizeIterator : public nsIFontSizeIterator
|
||||
{
|
||||
FaceInstance *mFirst;
|
||||
FaceInstance *mCurrent;
|
||||
|
||||
public:
|
||||
nsFontSizeIterator( FaceInstance *aFace)
|
||||
: mFirst(aFace), mCurrent(aFace)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
virtual ~nsFontSizeIterator() {}
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIFontSizeIterator
|
||||
NS_IMETHOD Reset()
|
||||
{
|
||||
mCurrent = mFirst;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD Get( double *aFontSize)
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
if( mCurrent)
|
||||
{
|
||||
*aFontSize = mCurrent->GetPointSize();
|
||||
rc = NS_OK;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
NS_IMETHOD Advance()
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
if( mCurrent)
|
||||
{
|
||||
mCurrent = mCurrent->GetNext();
|
||||
if( mCurrent) rc = NS_OK;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsFontSizeIterator, nsIFontSizeIterator::GetIID())
|
||||
|
||||
// Font-name iterator (xpcom)
|
||||
class nsFontNameIterator : public nsIFontNameIterator
|
||||
{
|
||||
FontFamily *mFirst;
|
||||
FontFamily *mCurrent;
|
||||
|
||||
public:
|
||||
nsFontNameIterator( FontFamily *aFamily)
|
||||
: mFirst(aFamily), mCurrent(aFamily)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIFontNameIterator
|
||||
NS_IMETHOD Reset()
|
||||
{
|
||||
mCurrent = mFirst;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD Get( nsString *aString)
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
if( mCurrent)
|
||||
{
|
||||
aString->SetString( mCurrent->GetName());
|
||||
rc = NS_OK;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
NS_IMETHOD Advance()
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
if( mCurrent)
|
||||
{
|
||||
mCurrent = mCurrent->GetNext();
|
||||
if( mCurrent) rc = NS_OK;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsFontNameIterator, nsIFontNameIterator::GetIID())
|
||||
|
||||
// font retriever service
|
||||
NS_IMPL_ISUPPORTS(nsFontRetrieverService, nsIFontRetrieverService::GetIID())
|
||||
|
||||
nsFontRetrieverService::nsFontRetrieverService()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mFontLister = new FontLister;
|
||||
}
|
||||
|
||||
nsFontRetrieverService::~nsFontRetrieverService()
|
||||
{
|
||||
delete mFontLister;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFontRetrieverService::CreateFontNameIterator( nsIFontNameIterator **aIterator)
|
||||
{
|
||||
if( !aIterator)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aIterator = new nsFontNameIterator( mFontLister->GetFamilies());
|
||||
NS_ADDREF(*aIterator);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFontRetrieverService::CreateFontSizeIterator( const nsString &aFontName,
|
||||
nsIFontSizeIterator **aIterator)
|
||||
{
|
||||
if( !aIterator)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
char buffer[100];
|
||||
gModuleData.ConvertFromUcs( aFontName, buffer, 100);
|
||||
|
||||
FontFamily *pFamily = mFontLister->FindFamily( buffer);
|
||||
if( !pFamily)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aIterator = new nsFontSizeIterator( pFamily->GetInstances());
|
||||
NS_ADDREF(*aIterator);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFontRetrieverService::IsFontScalable( const nsString &aFontName,
|
||||
PRBool *aResult)
|
||||
{
|
||||
if( !aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
char buffer[100];
|
||||
gModuleData.ConvertFromUcs( aFontName, buffer, 100);
|
||||
|
||||
FontFamily *pFamily = mFontLister->FindFamily( buffer);
|
||||
if( !pFamily)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aResult = pFamily->GetInstances()->IsScalable();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// singleton behaviour -- don't trust xpcom so do it ourselves
|
||||
nsresult NS_GetFontService( nsISupports **aResult)
|
||||
{
|
||||
if( !aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if( !gModuleData.fontService)
|
||||
{
|
||||
gModuleData.fontService = new nsFontRetrieverService;
|
||||
NS_ADDREF(gModuleData.fontService);
|
||||
}
|
||||
|
||||
*aResult = gModuleData.fontService;
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// Frame window - produced when NS_WINDOW_CID is required.
|
||||
|
||||
#include "nsFrameWindow.h"
|
||||
|
||||
nsFrameWindow::nsFrameWindow() : nsCanvas()
|
||||
{
|
||||
hwndFrame = 0;
|
||||
fnwpDefFrame = 0;
|
||||
}
|
||||
|
||||
nsFrameWindow::~nsFrameWindow()
|
||||
{
|
||||
}
|
||||
|
||||
// Called in the PM thread.
|
||||
void nsFrameWindow::RealDoCreate( HWND hwndP, nsWindow *aParent,
|
||||
const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext,
|
||||
nsIAppShell *aAppShell,
|
||||
nsWidgetInitData *aInitData, HWND hwndO)
|
||||
{
|
||||
NS_ASSERTION( hwndP == HWND_DESKTOP && aParent == nsnull,
|
||||
"Attempt to create non-top-level frame");
|
||||
|
||||
// Create the frame window.
|
||||
FRAMECDATA fcd = { sizeof( FRAMECDATA), 0, 0, 0 };
|
||||
fcd.flCreateFlags = GetFCFlags();
|
||||
|
||||
// Assume frames are toplevel. Breaks if anyone tries to do MDI, which
|
||||
// is an extra bonus feature :-)
|
||||
hwndFrame = WinCreateWindow( HWND_DESKTOP,
|
||||
WC_FRAME,
|
||||
0, 0, // text, style
|
||||
0, 0, 0, 0, // position
|
||||
HWND_DESKTOP,
|
||||
HWND_TOP,
|
||||
0, // ID
|
||||
&fcd, 0);
|
||||
|
||||
// This is a bit weird; without an icon, we get WM_PAINT messages
|
||||
// when minimized. They don't stop, giving maxed cpu. Go figure.
|
||||
|
||||
NS_ASSERTION( hwndFrame, "Couldn't create frame");
|
||||
|
||||
// Now create the client as a child of us, triggers resize and sets
|
||||
// up the client size (with any luck...)
|
||||
nsCanvas::RealDoCreate( hwndFrame, nsnull, aRect, aHandleEventFunction,
|
||||
aContext, aAppShell, aInitData, hwndO);
|
||||
|
||||
// Subclass frame
|
||||
fnwpDefFrame = WinSubclassWindow( hwndFrame, fnwpFrame);
|
||||
WinSetWindowPtr( hwndFrame, QWL_USER, this);
|
||||
BOOL brc = (BOOL) WinSendMsg( hwndFrame, WM_SETICON,
|
||||
MPFROMLONG( gModuleData.GetFrameIcon()), 0);
|
||||
|
||||
// make the client the client.
|
||||
WinSetWindowUShort( mWnd, QWS_ID, FID_CLIENT);
|
||||
WinSendMsg( hwndFrame, WM_UPDATEFRAME, 0, 0); // possibly superfluous
|
||||
|
||||
// Set up initial client size
|
||||
UpdateClientSize();
|
||||
|
||||
// Record frame hwnd somewhere that the window object can see during dtor
|
||||
mHackDestroyWnd = hwndFrame;
|
||||
}
|
||||
|
||||
ULONG nsFrameWindow::GetFCFlags()
|
||||
{
|
||||
return FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER |
|
||||
FCF_MINMAX | FCF_TASKLIST | FCF_NOBYTEALIGN |
|
||||
(gModuleData.bIsDBCS ? FCF_DBE_APPSTAT : 0);
|
||||
}
|
||||
|
||||
void nsFrameWindow::UpdateClientSize()
|
||||
{
|
||||
RECTL rcl = { 0, 0, mBounds.width, mBounds.height };
|
||||
WinCalcFrameRect( hwndFrame, &rcl, TRUE); // provided == frame rect
|
||||
mSizeClient.width = rcl.xRight - rcl.xLeft;
|
||||
mSizeClient.height = rcl.yTop - rcl.yBottom;
|
||||
mSizeBorder.width = (mBounds.width - mSizeClient.width) / 2;
|
||||
mSizeBorder.height = (mBounds.height - mSizeClient.height) / 2;
|
||||
}
|
||||
|
||||
nsresult nsFrameWindow::GetClientBounds( nsRect &aRect)
|
||||
{
|
||||
aRect.x = 0;
|
||||
aRect.y = 0;
|
||||
aRect.width = mSizeClient.width;
|
||||
aRect.height = mSizeClient.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFrameWindow::GetBorderSize( PRInt32 &aWidth, PRInt32 &aHeight)
|
||||
{
|
||||
aWidth = mSizeBorder.width;
|
||||
aHeight = mSizeBorder.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Just ignore this callback; the correct stuff is done in the frame wp.
|
||||
PRBool nsFrameWindow::OnReposition( PSWP pSwp)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// For frame windows, 'Show' is equivalent to 'Show & Activate'
|
||||
nsresult nsFrameWindow::Show( PRBool bState)
|
||||
{
|
||||
if( mWnd)
|
||||
{
|
||||
nsWindow::Show( bState);
|
||||
if( bState)
|
||||
WinSetWindowPos( GetMainWindow(), 0, 0, 0, 0, 0, SWP_ACTIVATE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Subclass for frame window
|
||||
MRESULT EXPENTRY fnwpFrame( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
nsFrameWindow *pFrame = (nsFrameWindow*) WinQueryWindowPtr( hwnd, QWL_USER);
|
||||
return pFrame->FrameMessage( msg, mp1, mp2);
|
||||
}
|
||||
|
||||
// Process messages from the frame
|
||||
MRESULT nsFrameWindow::FrameMessage( ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
MRESULT mRC = 0;
|
||||
BOOL bDone = FALSE;
|
||||
|
||||
switch( msg)
|
||||
{
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
PSWP pSwp = (PSWP) mp1;
|
||||
|
||||
// Note that client windows never get 'move' messages (well, they won't here anyway)
|
||||
if( pSwp->fl & SWP_MOVE && !(pSwp->fl & SWP_MINIMIZE))
|
||||
{
|
||||
// These commented-out `-1's cancel each other out.
|
||||
POINTL ptl = { pSwp->x, pSwp->y + pSwp->cy /* - 1 */ };
|
||||
ptl.y = gModuleData.szScreen.cy - ptl.y /* - 1*/ ;
|
||||
mBounds.x = ptl.x;
|
||||
mBounds.y = ptl.y;
|
||||
OnMove( ptl.x, ptl.y);
|
||||
}
|
||||
|
||||
// When the frame is sized, do stuff to recalculate client size.
|
||||
if( pSwp->fl & SWP_SIZE && !(pSwp->fl & SWP_MINIMIZE))
|
||||
{
|
||||
mRC = (*fnwpDefFrame)( hwndFrame, msg, mp1, mp2);
|
||||
bDone = TRUE;
|
||||
|
||||
mBounds.width = pSwp->cx;
|
||||
mBounds.height = pSwp->cy;
|
||||
|
||||
UpdateClientSize();
|
||||
DispatchResizeEvent( mSizeClient.width, mSizeClient.height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
WinSubclassWindow( hwndFrame, fnwpDefFrame);
|
||||
WinSetWindowPtr( hwndFrame, QWL_USER, 0);
|
||||
break;
|
||||
|
||||
// adjust client size when menu appears or disappears.
|
||||
case WM_UPDATEFRAME:
|
||||
if( LONGFROMMP(mp1) & FCF_MENU)
|
||||
UpdateClientSize();
|
||||
break;
|
||||
}
|
||||
|
||||
if( !bDone)
|
||||
mRC = (*fnwpDefFrame)( hwndFrame, msg, mp1, mp2);
|
||||
|
||||
return mRC;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsframewindow_h
|
||||
#define _nsframewindow_h
|
||||
|
||||
// Widget needs to treat the frame/client as one window - it's only really
|
||||
// interested in the client.
|
||||
//
|
||||
// mWnd is the client window; mBounds holds the frame rectangle relative to
|
||||
// the desktop.
|
||||
//
|
||||
// The frame itself is subclassed so OnMove events for the client happen.
|
||||
|
||||
#include "nscanvas.h"
|
||||
#include "nssize.h"
|
||||
|
||||
class nsFrameWindow : public nsCanvas
|
||||
{
|
||||
public:
|
||||
nsFrameWindow();
|
||||
virtual ~nsFrameWindow();
|
||||
|
||||
protected:
|
||||
HWND hwndFrame;
|
||||
PFNWP fnwpDefFrame;
|
||||
nsSize mSizeClient;
|
||||
nsSize mSizeBorder;
|
||||
|
||||
// So we can create the frame, parent the client & position it right
|
||||
virtual void RealDoCreate( HWND hwndP, nsWindow *aParent,
|
||||
const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext,
|
||||
nsIAppShell *aAppShell,
|
||||
nsWidgetInitData *aInitData, HWND hwndO);
|
||||
|
||||
// hook so dialog can be created looking like a dialog
|
||||
virtual ULONG GetFCFlags();
|
||||
|
||||
// So Destroy, Show, SetWindowPos, SetTitle, etc. work
|
||||
HWND GetMainWindow() const { return hwndFrame; }
|
||||
|
||||
// So correct sizing behaviour happens
|
||||
PRBool OnReposition( PSWP pSwp);
|
||||
|
||||
// Set up client sizes from frame dimensions
|
||||
void UpdateClientSize();
|
||||
PRInt32 GetClientHeight() { return mSizeClient.height; }
|
||||
|
||||
// So we can catch move messages
|
||||
MRESULT FrameMessage( ULONG msg, MPARAM mp1, MPARAM mp2);
|
||||
|
||||
NS_IMETHOD Show( PRBool bState);
|
||||
|
||||
// We have client
|
||||
NS_IMETHOD GetBorderSize( PRInt32 &aWidth, PRInt32 &aHeight);
|
||||
NS_IMETHOD GetClientBounds( nsRect &aRect);
|
||||
|
||||
friend MRESULT EXPENTRY fnwpFrame( HWND, ULONG, MPARAM, MPARAM);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsLabel.h"
|
||||
|
||||
// XP-com
|
||||
NS_IMPL_ADDREF(nsLabel)
|
||||
NS_IMPL_RELEASE(nsLabel)
|
||||
|
||||
nsresult nsLabel::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
nsresult result = nsWindow::QueryInterface( aIID, aInstancePtr);
|
||||
|
||||
if( result == NS_NOINTERFACE && aIID.Equals( nsILabel::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsILabel*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// nsLabel constructor
|
||||
nsLabel::nsLabel()
|
||||
{
|
||||
mAlignment = eAlign_Left;
|
||||
}
|
||||
|
||||
// Creation hook to create with correct aligment
|
||||
nsresult nsLabel::PreCreateWidget( nsWidgetInitData *aInitData)
|
||||
{
|
||||
if( nsnull != aInitData)
|
||||
{
|
||||
nsLabelInitData* data = (nsLabelInitData *) aInitData;
|
||||
mAlignment = data->mAlignment;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ULONG nsLabel::GetPMStyle( nsLabelAlignment aAlignment)
|
||||
{
|
||||
ULONG rc = 0;
|
||||
|
||||
switch( aAlignment)
|
||||
{
|
||||
case eAlign_Right : rc = DT_RIGHT; break;
|
||||
case eAlign_Left : rc = DT_LEFT; break;
|
||||
case eAlign_Center: rc = DT_CENTER; break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Label style
|
||||
nsresult nsLabel::SetAlignment( nsLabelAlignment aAlignment)
|
||||
{
|
||||
if( mWnd && aAlignment != mAlignment)
|
||||
{
|
||||
// already created a PM window; remove current aligment & add new
|
||||
RemoveFromStyle( GetPMStyle( mAlignment));
|
||||
AddToStyle( GetPMStyle( aAlignment));
|
||||
}
|
||||
|
||||
mAlignment = aAlignment;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Label text
|
||||
NS_IMPL_LABEL(nsLabel)
|
||||
|
||||
// Creation hooks
|
||||
PCSZ nsLabel::WindowClass()
|
||||
{
|
||||
return WC_STATIC;
|
||||
}
|
||||
|
||||
ULONG nsLabel::WindowStyle()
|
||||
{
|
||||
return BASE_CONTROL_STYLE | SS_TEXT | GetPMStyle( mAlignment);
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsListBox.h"
|
||||
|
||||
// listbox; need more code here to allow multiple selections.
|
||||
|
||||
NS_IMPL_ADDREF(nsListBox)
|
||||
NS_IMPL_RELEASE(nsListBox)
|
||||
|
||||
nsresult nsListBox::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
nsresult result = nsWindow::QueryInterface( aIID, aInstancePtr);
|
||||
|
||||
if( result == NS_NOINTERFACE)
|
||||
{
|
||||
if( aIID.Equals( nsIListBox::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIListBox*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
else if( aIID.Equals( nsIListWidget::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIListWidget*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define LS_U_MULTISEL (LS_MULTIPLESEL | LS_EXTENDEDSEL)
|
||||
|
||||
nsresult nsListBox::SetMultipleSelection( PRBool aMultipleSelections)
|
||||
{
|
||||
if( mWnd)
|
||||
{
|
||||
if( aMultipleSelections)
|
||||
AddToStyle( LS_U_MULTISEL);
|
||||
else
|
||||
RemoveFromStyle( LS_U_MULTISEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aMultipleSelections)
|
||||
mStyle |= LS_U_MULTISEL;
|
||||
else
|
||||
mStyle &= ~LS_U_MULTISEL;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Helper
|
||||
PRInt32 nsListBox::GetSelections( PRInt32 *aIndices, PRInt32 aSize)
|
||||
{
|
||||
PRInt32 cItems = 0;
|
||||
short sItemStart = LIT_FIRST;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
sItemStart = SHORT1FROMMR( SendMsg( LM_QUERYSELECTION,
|
||||
MPFROMSHORT(sItemStart)));
|
||||
if( sItemStart == LIT_NONE)
|
||||
break;
|
||||
|
||||
if( aIndices && cItems < aSize)
|
||||
aIndices[cItems] = sItemStart;
|
||||
cItems++;
|
||||
}
|
||||
|
||||
return cItems;
|
||||
}
|
||||
|
||||
PRInt32 nsListBox::GetSelectedCount()
|
||||
{
|
||||
return GetSelections( 0, 0);
|
||||
}
|
||||
|
||||
nsresult nsListBox::GetSelectedIndices( PRInt32 aIndices[], PRInt32 aSize)
|
||||
{
|
||||
GetSelections( aIndices, aSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsListBox::SetSelectedIndices( PRInt32 aIndices[], PRInt32 aSize)
|
||||
{
|
||||
// clear selection
|
||||
Deselect();
|
||||
|
||||
for( int i = 0; i < aSize; i++)
|
||||
SendMsg( LM_SELECTITEM, MPFROMSHORT( aIndices[i]), MPFROMLONG( TRUE));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Platform hooks
|
||||
nsresult nsListBox::PreCreateWidget( nsWidgetInitData *aInitData)
|
||||
{
|
||||
if( nsnull != aInitData)
|
||||
{
|
||||
nsListBoxInitData *data = (nsListBoxInitData *) aInitData;
|
||||
if( data->mMultiSelect)
|
||||
mStyle |= LS_U_MULTISEL;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PCSZ nsListBox::WindowClass()
|
||||
{
|
||||
return WC_LISTBOX;
|
||||
}
|
||||
|
||||
ULONG nsListBox::WindowStyle()
|
||||
{
|
||||
return mStyle | LS_NOADJUSTPOS | BASE_CONTROL_STYLE;
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsLookAndFeel.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsWidgetDefs.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// XPCom scaffolding
|
||||
NS_IMPL_ISUPPORTS(nsLookAndFeel, nsILookAndFeel::GetIID())
|
||||
|
||||
nsLookAndFeel::nsLookAndFeel()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
// Colours
|
||||
NS_IMETHODIMP nsLookAndFeel::GetColor(const nsColorID aID, nscolor &aColor)
|
||||
{
|
||||
int idx = 0;
|
||||
switch (aID)
|
||||
{
|
||||
case eColor_WindowBackground: idx = SYSCLR_BACKGROUND; break;
|
||||
case eColor_WindowForeground: idx = SYSCLR_WINDOWTEXT; break;
|
||||
case eColor_WidgetBackground: idx = SYSCLR_BUTTONMIDDLE; break;
|
||||
case eColor_WidgetForeground: idx = SYSCLR_WINDOWTEXT; break;
|
||||
case eColor_WidgetSelectBackground: idx = SYSCLR_HILITEBACKGROUND; break;
|
||||
case eColor_WidgetSelectForeground: idx = SYSCLR_HILITEFOREGROUND; break;
|
||||
case eColor_Widget3DHighlight: idx = SYSCLR_BUTTONLIGHT; break;
|
||||
case eColor_Widget3DShadow: idx = SYSCLR_BUTTONDARK; break;
|
||||
case eColor_TextBackground: idx = SYSCLR_ENTRYFIELD; break;
|
||||
case eColor_TextForeground: idx = SYSCLR_WINDOWTEXT; break;
|
||||
case eColor_TextSelectBackground: idx = SYSCLR_HILITEBACKGROUND; break;
|
||||
case eColor_TextSelectForeground: idx = SYSCLR_HILITEFOREGROUND; break;
|
||||
|
||||
default:
|
||||
NS_ASSERTION(0, "Bad system colour");
|
||||
break;
|
||||
}
|
||||
|
||||
long lColor = WinQuerySysColor( HWND_DESKTOP, idx, 0);
|
||||
|
||||
RGB2 *pRGB2 = (RGB2*) &lColor;
|
||||
|
||||
aColor = NS_RGB( pRGB2->bRed, pRGB2->bGreen, pRGB2->bBlue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// metrics
|
||||
NS_IMETHODIMP nsLookAndFeel::GetMetric(const nsMetricID aID, PRInt32 & aMetric)
|
||||
{
|
||||
long svalue = 0;
|
||||
aMetric = 0;
|
||||
|
||||
switch( aID)
|
||||
{
|
||||
case eMetric_WindowTitleHeight: svalue = SV_CYTITLEBAR; break;
|
||||
case eMetric_WindowBorderWidth: svalue = SV_CXSIZEBORDER; break;
|
||||
case eMetric_WindowBorderHeight: svalue = SV_CYSIZEBORDER; break;
|
||||
case eMetric_Widget3DBorder: svalue = SV_CXBORDER; break;
|
||||
case eMetric_TextFieldHeight: aMetric = gModuleData.lHtEntryfield; break;
|
||||
|
||||
//
|
||||
// These are copied from the Win32 version; changes welcome
|
||||
//
|
||||
case eMetric_TextVerticalInsidePadding:
|
||||
aMetric = 0;
|
||||
break;
|
||||
case eMetric_TextShouldUseVerticalInsidePadding:
|
||||
aMetric = 0;
|
||||
break;
|
||||
case eMetric_TextHorizontalInsideMinimumPadding:
|
||||
aMetric = 3;
|
||||
break;
|
||||
case eMetric_TextShouldUseHorizontalInsideMinimumPadding:
|
||||
aMetric = 1;
|
||||
break;
|
||||
|
||||
case eMetric_ButtonHorizontalInsidePaddingNavQuirks:
|
||||
aMetric = 10;
|
||||
break;
|
||||
case eMetric_ButtonHorizontalInsidePaddingOffsetNavQuirks:
|
||||
aMetric = 8;
|
||||
break;
|
||||
|
||||
case eMetric_CheckboxSize:
|
||||
aMetric = 12;
|
||||
break;
|
||||
case eMetric_RadioboxSize:
|
||||
aMetric = 12;
|
||||
break;
|
||||
|
||||
case eMetric_ListHorizontalInsideMinimumPadding:
|
||||
aMetric = 3;
|
||||
break;
|
||||
case eMetric_ListShouldUseHorizontalInsideMinimumPadding:
|
||||
aMetric = 0;
|
||||
break;
|
||||
case eMetric_ListVerticalInsidePadding:
|
||||
aMetric = 0;
|
||||
break;
|
||||
case eMetric_ListShouldUseVerticalInsidePadding:
|
||||
aMetric = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ASSERTION( 0, "Bad metric");
|
||||
break;
|
||||
}
|
||||
|
||||
if( svalue != 0)
|
||||
aMetric = WinQuerySysValue( HWND_DESKTOP, svalue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// These are copied from the Win32 version; changes welcome
|
||||
//
|
||||
// float metrics
|
||||
NS_IMETHODIMP nsLookAndFeel::GetMetric( const nsMetricFloatID aID,
|
||||
float &aMetric)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
switch( aID)
|
||||
{
|
||||
case eMetricFloat_TextFieldVerticalInsidePadding:
|
||||
aMetric = 0.25f;
|
||||
break;
|
||||
case eMetricFloat_TextFieldHorizontalInsidePadding:
|
||||
aMetric = 0.95f;
|
||||
break;
|
||||
case eMetricFloat_TextAreaVerticalInsidePadding:
|
||||
aMetric = 0.40f;
|
||||
break;
|
||||
case eMetricFloat_TextAreaHorizontalInsidePadding:
|
||||
aMetric = 0.40f;
|
||||
break;
|
||||
case eMetricFloat_ListVerticalInsidePadding:
|
||||
aMetric = 0.10f;
|
||||
break;
|
||||
case eMetricFloat_ListHorizontalInsidePadding:
|
||||
aMetric = 0.40f;
|
||||
break;
|
||||
case eMetricFloat_ButtonVerticalInsidePadding:
|
||||
aMetric = 0.25f;
|
||||
break;
|
||||
case eMetricFloat_ButtonHorizontalInsidePadding:
|
||||
aMetric = 0.25f;
|
||||
break;
|
||||
default:
|
||||
aMetric = -1.0;
|
||||
res = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsLookAndFeel_h
|
||||
#define _nsLookAndFeel_h
|
||||
|
||||
#include "nsILookAndFeel.h"
|
||||
|
||||
class nsLookAndFeel: public nsILookAndFeel
|
||||
{
|
||||
public:
|
||||
nsLookAndFeel();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD GetColor( const nsColorID aID, nscolor &aColor);
|
||||
NS_IMETHOD GetMetric( const nsMetricID aID, PRInt32 &aMetric);
|
||||
NS_IMETHOD GetMetric( const nsMetricFloatID aID, float &aMetric);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// normal menu
|
||||
|
||||
#include "nsMenu.h"
|
||||
#include "nsIMenuBar.h"
|
||||
#include "nsMenuItem.h"
|
||||
#include "nsIContextMenu.h"
|
||||
|
||||
#include "nsIWebShell.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
NS_IMPL_ADDREF(nsMenu)
|
||||
NS_IMPL_RELEASE(nsMenu)
|
||||
|
||||
nsresult nsMenu::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if( !aInstancePtr)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aInstancePtr = 0;
|
||||
|
||||
if( aIID.Equals(nsIMenu::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIMenu*) this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if( aIID.Equals(nsIMenuListener::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIMenuListener*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if( aIID.Equals(((nsISupports*)(nsIMenu*)this)->GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsISupports*) ((nsIMenu*)this));
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
nsMenu::nsMenu() : mParent(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsMenu::~nsMenu()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult nsMenu::Create( nsISupports *aThing, const nsString &aLabel)
|
||||
{
|
||||
if( !aThing)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
void *pvHwnd = 0;
|
||||
nsIMenu *aMenu = nsnull;
|
||||
nsIContextMenu *aPopup = nsnull;
|
||||
nsIMenuBar *aBar = nsnull;
|
||||
|
||||
if( NS_SUCCEEDED( aThing->QueryInterface( nsIMenuBar::GetIID(),
|
||||
(void**) &aBar)))
|
||||
{
|
||||
aBar->GetNativeData( pvHwnd);
|
||||
NS_RELEASE(aBar);
|
||||
}
|
||||
else if( NS_SUCCEEDED( aThing->QueryInterface( nsIMenu::GetIID(),
|
||||
(void**) &aMenu)))
|
||||
{
|
||||
aMenu->GetNativeData( &pvHwnd);
|
||||
NS_RELEASE(aMenu);
|
||||
}
|
||||
else if( NS_SUCCEEDED( aThing->QueryInterface( nsIContextMenu::GetIID(),
|
||||
(void**) &aPopup)))
|
||||
{
|
||||
aPopup->GetNativeData( &pvHwnd);
|
||||
NS_RELEASE(aPopup);
|
||||
}
|
||||
|
||||
// This is a bit dubious, as there's no guarantee that this menu
|
||||
// is being created in the same thread as the parent was. But this
|
||||
// is probably moot...
|
||||
|
||||
nsMenuBase *pPBase = (nsMenuBase*) WinQueryWindowPtr( (HWND) pvHwnd, QWL_USER);
|
||||
|
||||
nsMenuBase::Create( HWND_DESKTOP, pPBase->GetTK());
|
||||
|
||||
// Connect up to parent menu component
|
||||
WinSetOwner( mWnd, (HWND) pvHwnd);
|
||||
mParent = aThing;
|
||||
|
||||
// record text
|
||||
mLabel = aLabel;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenu::GetParent( nsISupports * &aParent)
|
||||
{
|
||||
NS_IF_RELEASE(aParent);
|
||||
aParent = mParent;
|
||||
NS_IF_ADDREF(aParent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenu::GetLabel( nsString &aText)
|
||||
{
|
||||
aText = mLabel;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenu::SetLabel( const nsString &aText)
|
||||
{
|
||||
mLabel = aText;
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsMenu_h
|
||||
#define _nsMenu_h
|
||||
|
||||
// A submenu which reflects a DOM content model
|
||||
|
||||
#include "nsIMenu.h"
|
||||
#include "nsMenuBase.h"
|
||||
|
||||
class nsMenu : public nsIMenu, public nsDynamicMenu
|
||||
{
|
||||
public:
|
||||
nsMenu();
|
||||
~nsMenu();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIMenu extras
|
||||
NS_IMETHOD Create( nsISupports *aParent, const nsString &aLabel);
|
||||
NS_IMETHOD GetParent( nsISupports *&aParent);
|
||||
NS_IMETHOD GetLabel( nsString &aText);
|
||||
NS_IMETHOD SetLabel( const nsString &aText);
|
||||
|
||||
// Common methods
|
||||
DECL_DYNAMIC_MENU_METHODS
|
||||
|
||||
protected:
|
||||
nsString mLabel;
|
||||
nsISupports *mParent;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// menu bar
|
||||
|
||||
#include "nsWindow.h"
|
||||
#include "nsMenuBar.h"
|
||||
#include "nsMenu.h"
|
||||
|
||||
#include "nsIWebShell.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
// XPCom
|
||||
NS_IMPL_ADDREF(nsMenuBar)
|
||||
NS_IMPL_RELEASE(nsMenuBar)
|
||||
|
||||
nsresult nsMenuBar::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if( !aInstancePtr)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aInstancePtr = 0;
|
||||
|
||||
if( aIID.Equals(nsIMenuBar::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIMenuBar*) this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if( aIID.Equals(nsIMenuListener::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIMenuListener*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if( aIID.Equals(((nsISupports*)(nsIMenuBar*)this)->GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsISupports*)((nsIMenuBar*)this));
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
nsMenuBar::nsMenuBar() : mWndFrame(nsnull), mParent(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsMenuBar::~nsMenuBar()
|
||||
{
|
||||
}
|
||||
|
||||
// Creation
|
||||
nsresult nsMenuBar::Create( nsIWidget *aParent)
|
||||
{
|
||||
NS_ASSERTION(aParent,"Menu must have a parent");
|
||||
|
||||
nsToolkit *aToolkit = (nsToolkit*) aParent->GetToolkit();
|
||||
|
||||
mWndFrame = (HWND) aParent->GetNativeData( NS_NATIVE_WINDOW);
|
||||
//
|
||||
// Who knows what kind of window the client's given to us here.
|
||||
// Search up the window hierarchy until we find a frame.
|
||||
//
|
||||
while( !((ULONG)aToolkit->SendMsg( mWndFrame, WM_QUERYFRAMEINFO) & FI_FRAME))
|
||||
mWndFrame = WinQueryWindow( mWndFrame, QW_PARENT);
|
||||
|
||||
nsMenuBase::Create( mWndFrame, aToolkit);
|
||||
NS_RELEASE(aToolkit); // add-ref'd by above call
|
||||
|
||||
// must have id FID_MENU
|
||||
WinSetWindowUShort( mWnd, QWS_ID, FID_MENU);
|
||||
// tell the frame about us
|
||||
UpdateFrame();
|
||||
|
||||
// remember parent
|
||||
mParent = aParent;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ULONG nsMenuBar::WindowStyle()
|
||||
{
|
||||
return MS_ACTIONBAR;
|
||||
}
|
||||
|
||||
nsresult nsMenuBar::GetParent( nsIWidget *&aParent)
|
||||
{
|
||||
NS_IF_RELEASE(aParent);
|
||||
aParent = mParent;
|
||||
NS_ADDREF(aParent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuBar::SetParent( nsIWidget *aParent)
|
||||
{
|
||||
// XXX oh dear. I don't really want to implement this.
|
||||
// I guess we could work out what new frame window this
|
||||
// is & then reparent ourselves, but ewwww.
|
||||
printf( "nsMenuBar::SetParent() - tell someone\n");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsMenuBar::UpdateFrame()
|
||||
{
|
||||
if( mToolkit)
|
||||
mToolkit->SendMsg( mWndFrame, WM_UPDATEFRAME, MPFROMLONG(FCF_MENU));
|
||||
}
|
||||
|
||||
// Need to override these so we can tell the frame about the new entries
|
||||
nsresult nsMenuBar::AddMenu( nsIMenu *aMenu)
|
||||
{
|
||||
nsresult rc = nsMenuBase::InsertItemAt( aMenu);
|
||||
UpdateFrame();
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsMenuBar::InsertMenuAt( const PRUint32 aCount, nsIMenu *&aMenu)
|
||||
{
|
||||
nsresult rc = nsMenuBase::InsertItemAt( aMenu, aCount);
|
||||
UpdateFrame();
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsMenuBar::RemoveMenu( const PRUint32 aCount)
|
||||
{
|
||||
nsresult rc = nsMenuBase::RemoveItemAt( aCount);
|
||||
UpdateFrame();
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsMenuBar::RemoveAll()
|
||||
{
|
||||
nsresult rc = nsMenuBase::RemoveAll();
|
||||
UpdateFrame();
|
||||
return rc;
|
||||
}
|
||||
|
||||
// accessor
|
||||
nsresult nsMenuBar::GetMenuAt( const PRUint32 aCount, nsIMenu *&aMenu)
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
NS_IF_RELEASE(aMenu);
|
||||
|
||||
if( VerifyIndex( aCount))
|
||||
{
|
||||
MENUITEM mI;
|
||||
nsMenuBase::GetItemAt( aCount, &mI);
|
||||
|
||||
nsISupports *aThing = (nsISupports*) mI.hItem;
|
||||
rc = aThing->QueryInterface( nsIMenu::GetIID(), (void**) &aMenu);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// hmm
|
||||
nsresult nsMenuBar::Paint()
|
||||
{
|
||||
UpdateFrame();
|
||||
mParent->Invalidate( PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIMenuListener interface - used to update menu dynamically and build it
|
||||
// from a dom content model
|
||||
|
||||
// nsWebShellWindow currently fakes a call into here to kick us off
|
||||
nsEventStatus nsMenuBar::MenuConstruct( const nsMenuEvent &aMenuEvent,
|
||||
nsIWidget *aParentWindow,
|
||||
void *aMenubarNode,
|
||||
void *aWebShell)
|
||||
{
|
||||
nsIWebShell *pWebShell = (nsIWebShell*) aWebShell;
|
||||
nsIDOMNode *pMenubarNode = (nsIDOMNode*) aMenubarNode;
|
||||
|
||||
// Create the menubar, register for notifications with the window
|
||||
Create( aParentWindow);
|
||||
aParentWindow->AddMenuListener( this);
|
||||
aParentWindow->SetMenuBar( this);
|
||||
|
||||
// Now iterate through the DOM children creating submenus.
|
||||
nsCOMPtr<nsIDOMNode> pMenuNode;
|
||||
pMenubarNode->GetFirstChild( getter_AddRefs(pMenuNode));
|
||||
while( pMenuNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> pMenuElement( do_QueryInterface(pMenuNode));
|
||||
if( pMenuElement)
|
||||
{
|
||||
nsString nodeType, menuName;
|
||||
pMenuElement->GetNodeName( nodeType);
|
||||
if( nodeType.Equals( "menu"))
|
||||
{
|
||||
// new submenu
|
||||
pMenuElement->GetAttribute( nsAutoString( "name"), menuName);
|
||||
nsIMenu *pMenu = new nsMenu;
|
||||
NS_ADDREF(pMenu);
|
||||
pMenu->Create( (nsIMenuBar*)this, menuName);
|
||||
pMenu->SetDOMNode( pMenuNode);
|
||||
pMenu->SetDOMElement( pMenuElement);
|
||||
pMenu->SetWebShell( pWebShell);
|
||||
|
||||
// insert into menubar; nsMenuBase takes ownership
|
||||
AddMenu( pMenu);
|
||||
NS_RELEASE(pMenu);
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> pOldNode( pMenuNode);
|
||||
pOldNode->GetNextSibling( getter_AddRefs(pMenuNode));
|
||||
}
|
||||
|
||||
// Hackish -- nsWebShellWindow doesn't cut its ref, so leave the frame
|
||||
// window with ownership.
|
||||
Release(); // can't call NS_RELEASE 'cos |this| is not an lvalue...
|
||||
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsMenuBase.h"
|
||||
#include "nsMenuItem.h"
|
||||
#include "nsMenu.h"
|
||||
#include "nsToolkit.h"
|
||||
#include "nsISupportsArray.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
// Common code used by menu classes
|
||||
|
||||
nsMenuBase::nsMenuBase() : mToolkit(0), mWnd(0), mElements(nsnull)
|
||||
{}
|
||||
|
||||
void nsMenuBase::Create( HWND hwndParent, nsToolkit *aToolkit)
|
||||
{
|
||||
NS_ASSERTION( aToolkit, "Missing toolkit in menucreation");
|
||||
|
||||
mToolkit = aToolkit;
|
||||
NS_ADDREF(mToolkit);
|
||||
|
||||
// thread-switch if necessary
|
||||
if( !mToolkit->IsPMThread())
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED( "Threaded menus");
|
||||
}
|
||||
else
|
||||
{
|
||||
mWnd = WinCreateWindow( hwndParent,
|
||||
WC_MENU,
|
||||
0, // text
|
||||
WindowStyle(),
|
||||
0, 0, 0, 0, // pos/size
|
||||
hwndParent, // owner
|
||||
HWND_TOP,
|
||||
0, // window ID
|
||||
0, 0); // ctldata, presparams
|
||||
NS_ASSERTION( mWnd, "No menu window");
|
||||
|
||||
// store nsMenuBase * in QWL_USER
|
||||
WinSetWindowPtr( mWnd, QWL_USER, this);
|
||||
|
||||
// nice font (hmm)
|
||||
WinSetPresParam( mWnd, PP_FONTNAMESIZE,
|
||||
strlen( gModuleData.pszFontNameSize) + 1,
|
||||
gModuleData.pszFontNameSize);
|
||||
|
||||
NS_NewISupportsArray( &mElements);
|
||||
}
|
||||
}
|
||||
|
||||
ULONG nsMenuBase::WindowStyle()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nsMenuBase::Destroy()
|
||||
{
|
||||
if( mToolkit)
|
||||
if( !mToolkit->IsPMThread())
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED( "Threaded menus");
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX Not sure about this -- need to think more.
|
||||
// Shouldn't it be dealt with by the normal parent-death process?
|
||||
WinDestroyWindow( mWnd);
|
||||
mWnd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// dumb helper
|
||||
MRESULT nsMenuBase::SendMsg( ULONG m, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
MRESULT mrc = 0;
|
||||
if( mToolkit)
|
||||
mrc = mToolkit->SendMsg( mWnd, m, mp1, mp2);
|
||||
return mrc;
|
||||
}
|
||||
|
||||
nsMenuBase::~nsMenuBase()
|
||||
{
|
||||
if( mWnd) Destroy();
|
||||
NS_IF_RELEASE(mToolkit);
|
||||
NS_IF_RELEASE(mElements);
|
||||
}
|
||||
|
||||
nsresult nsMenuBase::GetItemCount( PRUint32 &aCount)
|
||||
{
|
||||
MRESULT rc = SendMsg( MM_QUERYITEMCOUNT);
|
||||
aCount = SHORT1FROMMP( rc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuBase::GetNativeData( void **aNative)
|
||||
{
|
||||
*aNative = (void*) mWnd;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// New all-singing, all-dancing insert routine.
|
||||
//
|
||||
// The 'aThing' may be an nsIMenu or an nsIMenuItem, joy.
|
||||
// If it is null, then we're talking about a separator, though this ought
|
||||
// not to be used.
|
||||
nsresult nsMenuBase::InsertItemAt( nsISupports *aThing, PRUint32 aPos)
|
||||
{
|
||||
nsIMenu *pMenu = nsnull;
|
||||
nsIMenuItem *pItem = nsnull;
|
||||
MENUITEM mI = { aPos, 0, 0, 0, 0, (ULONG) aThing };
|
||||
char *pStr = nsnull;
|
||||
|
||||
// XXX needs to use unicode converter to get right text
|
||||
// This is very much an issue now that menus are constructed
|
||||
// from XUL and so can have an arbitrary encoding.
|
||||
//
|
||||
// Whether PM will know what to do with non-western characters
|
||||
// is another issue! Probably okay if it's in the process'
|
||||
// codepage (font set via presparams, which take that cp)
|
||||
|
||||
// set up menitem depending on what we have...
|
||||
if( nsnull == aThing)
|
||||
{
|
||||
mI.afStyle |= MIS_SEPARATOR;
|
||||
}
|
||||
else if( NS_SUCCEEDED( aThing->QueryInterface( nsIMenu::GetIID(),
|
||||
(void**) &pMenu)))
|
||||
{
|
||||
void *hwnd = nsnull;
|
||||
|
||||
nsString aString;
|
||||
pMenu->GetLabel( aString);
|
||||
pStr = gModuleData.ConvertFromUcs( aString);
|
||||
|
||||
mI.afStyle |= MIS_SUBMENU | MIS_TEXT;
|
||||
|
||||
pMenu->GetNativeData( &hwnd);
|
||||
mI.hwndSubMenu = (HWND) hwnd;
|
||||
|
||||
NS_RELEASE(pMenu);
|
||||
}
|
||||
else if( NS_SUCCEEDED( aThing->QueryInterface( nsIMenuItem::GetIID(),
|
||||
(void**) &pItem)))
|
||||
{
|
||||
nsMenuItem *pPMItem = (nsMenuItem*) pItem; // XXX
|
||||
nsString aString;
|
||||
PRBool bIsSep = PR_FALSE;
|
||||
|
||||
mI.id = pPMItem->GetPMID();
|
||||
|
||||
pPMItem->IsSeparator( bIsSep);
|
||||
if( bIsSep)
|
||||
{
|
||||
mI.afStyle |= MIS_SEPARATOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
mI.afStyle |= MIS_TEXT;
|
||||
pPMItem->GetLabel( aString);
|
||||
pStr = gModuleData.ConvertFromUcs( aString);
|
||||
}
|
||||
NS_RELEASE(pItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf( "Erk, strange menu thing being added\n");
|
||||
#endif
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// add menu item to gui
|
||||
SendMsg( MM_INSERTITEM, MPFROMP(&mI), MPFROMP(pStr));
|
||||
// ..and take ownership of it (separators don't have it)
|
||||
if( aThing)
|
||||
mElements->InsertElementAt( aThing, 0);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Pull items off of a menu
|
||||
nsresult nsMenuBase::GetItemID( USHORT usID, PMENUITEM pItem)
|
||||
{
|
||||
SendMsg( MM_QUERYITEM, MPFROM2SHORT(usID, FALSE), MPFROMP(pItem));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuBase::GetItemAt( const PRUint32 &pos, PMENUITEM pItem)
|
||||
{
|
||||
nsresult rc = NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
if( VerifyIndex( pos))
|
||||
{
|
||||
// find the ID
|
||||
MRESULT mrc = SendMsg( MM_ITEMIDFROMPOSITION, MPFROMLONG(pos));
|
||||
rc = GetItemID( SHORT1FROMMR(mrc), pItem);
|
||||
rc = NS_OK;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsMenuBase::GetItemAt( const PRUint32 &aPos, nsISupports *&aThing)
|
||||
{
|
||||
MENUITEM mI = { 0 };
|
||||
nsresult rc = GetItemAt( aPos, &mI);
|
||||
|
||||
if( NS_SUCCEEDED(rc))
|
||||
{
|
||||
NS_IF_RELEASE(aThing); // XP-COM correct, but probably bad, sigh.
|
||||
|
||||
// This is either an nsIMenu or an nsIMenuItem
|
||||
aThing = (nsISupports*) mI.hItem;
|
||||
NS_ADDREF(aThing);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Update an item (grey, tick)
|
||||
nsresult nsMenuBase::UpdateItem( PMENUITEM aItem)
|
||||
{
|
||||
SendMsg( MM_SETITEM, 0, MPFROMP(aItem));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuBase::RemoveItemAt( const PRUint32 index)
|
||||
{
|
||||
MENUITEM mI = { 0 };
|
||||
nsresult rc = GetItemAt( index, &mI);
|
||||
|
||||
if( NS_SUCCEEDED(rc))
|
||||
{
|
||||
// remove item from gui
|
||||
SendMsg( MM_REMOVEITEM, MPFROM2SHORT( mI.id, FALSE));
|
||||
|
||||
// remove item from our list if we have it (& hence delete the window)
|
||||
nsISupports *pThing = (nsISupports*) mI.hItem;
|
||||
PRInt32 lIndex = 0;
|
||||
if( pThing && NS_SUCCEEDED( mElements->GetIndexOf( pThing, &lIndex)))
|
||||
rc = mElements->DeleteElementAt( lIndex);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsMenuBase::RemoveAll()
|
||||
{
|
||||
PRUint32 count;
|
||||
GetItemCount( count);
|
||||
|
||||
for( PRUint32 i = 0; i < count; i++)
|
||||
RemoveItemAt( 0);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
BOOL nsMenuBase::VerifyIndex( PRUint32 index)
|
||||
{
|
||||
PRUint32 count;
|
||||
GetItemCount( count);
|
||||
return index == NS_MIT_END || index < count;
|
||||
}
|
||||
|
||||
// Dummy nsIMenuListener implementation
|
||||
|
||||
nsEventStatus nsMenuBase::MenuItemSelected( const nsMenuEvent &aMenuEvent)
|
||||
{
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
nsEventStatus nsMenuBase::MenuSelected(const nsMenuEvent & aMenuEvent)
|
||||
{
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
nsEventStatus nsMenuBase::MenuDeselected(const nsMenuEvent & aMenuEvent)
|
||||
{
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
nsEventStatus nsMenuBase::MenuDestruct( const nsMenuEvent &aMenuEvent)
|
||||
{
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
nsEventStatus nsMenuBase::MenuConstruct( const nsMenuEvent &aMenuEvent,
|
||||
nsIWidget *aParentWindow,
|
||||
void *menubarNode,
|
||||
void *aWebShell)
|
||||
{
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
// nsDynamicMenu, common base class for context & 'normal' menus
|
||||
//
|
||||
nsDynamicMenu::nsDynamicMenu() : mListener(0), mWebShell(0),
|
||||
mDOMNode(0), mDOMElement(0)
|
||||
{}
|
||||
|
||||
nsDynamicMenu::~nsDynamicMenu()
|
||||
{
|
||||
NS_IF_RELEASE(mListener);
|
||||
}
|
||||
|
||||
nsresult nsDynamicMenu::AddMenuListener( nsIMenuListener *aMenuListener)
|
||||
{
|
||||
if( !aMenuListener)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_IF_RELEASE(mListener);
|
||||
mListener = aMenuListener;
|
||||
NS_ADDREF(mListener);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDynamicMenu::RemoveMenuListener( nsIMenuListener *aMenuListener)
|
||||
{
|
||||
if( aMenuListener == mListener)
|
||||
NS_IF_RELEASE(mListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDynamicMenu::SetDOMNode( nsIDOMNode *aMenuNode)
|
||||
{
|
||||
mDOMNode = aMenuNode;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDynamicMenu::SetDOMElement( nsIDOMElement *aMenuElement)
|
||||
{
|
||||
mDOMElement = aMenuElement;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDynamicMenu::SetWebShell( nsIWebShell *aWebShell)
|
||||
{
|
||||
mWebShell = aWebShell;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// build the menu from the DOM content model.
|
||||
//
|
||||
// Note that the tear-down from the previous display is done in the init for
|
||||
// the next menu so that the MENUITEMs are valid for WM_COMMAND dispatching
|
||||
//
|
||||
nsEventStatus nsDynamicMenu::MenuSelected( const nsMenuEvent &aMenuEvent)
|
||||
{
|
||||
RemoveAll();
|
||||
|
||||
// Go through children of menu node and populate menu
|
||||
nsCOMPtr<nsIDOMNode> pItemNode;
|
||||
mDOMNode->GetFirstChild( getter_AddRefs(pItemNode));
|
||||
|
||||
while( pItemNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> pItemElement( do_QueryInterface(pItemNode));
|
||||
if( pItemElement)
|
||||
{
|
||||
nsString nodeType;
|
||||
pItemElement->GetNodeName( nodeType);
|
||||
if( nodeType.Equals( "menuitem"))
|
||||
{
|
||||
// find attributes of menu item & create gui peer
|
||||
nsString itemName;
|
||||
nsIMenuItem *pItem = new nsMenuItem;
|
||||
NS_ADDREF(pItem);
|
||||
pItemElement->GetAttribute( nsAutoString("name"), itemName);
|
||||
pItem->Create( (nsIMenu*)this, itemName, PR_FALSE);
|
||||
InsertItemAt( pItem);
|
||||
|
||||
nsString itemCmd, disabled, checked;
|
||||
pItemElement->GetAttribute( nsAutoString("onclick"), itemCmd);
|
||||
pItemElement->GetAttribute( nsAutoString("disabled"), disabled);
|
||||
pItemElement->GetAttribute( nsAutoString("checked"), checked);
|
||||
pItem->SetCommand( itemCmd);
|
||||
pItem->SetWebShell( mWebShell);
|
||||
pItem->SetDOMElement( pItemElement);
|
||||
pItem->SetEnabled( !disabled.Equals( nsAutoString("true")));
|
||||
pItem->SetChecked( checked.Equals( nsAutoString("true")));
|
||||
NS_RELEASE(pItem); // ownership of the item has passed to nsMenuBase
|
||||
}
|
||||
else if( nodeType.Equals( "separator"))
|
||||
InsertItemAt( 0);
|
||||
else if( nodeType.Equals( "menu"))
|
||||
{
|
||||
// new submenu
|
||||
nsString menuName;
|
||||
nsIMenu *pMenu = new nsMenu;
|
||||
NS_ADDREF(pMenu);
|
||||
pItemElement->GetAttribute( nsAutoString("name"), menuName);
|
||||
pMenu->Create( (nsIMenu*)this, menuName);
|
||||
pMenu->SetDOMNode( pItemNode);
|
||||
pMenu->SetDOMElement( pItemElement);
|
||||
pMenu->SetWebShell( mWebShell);
|
||||
|
||||
// insert into menubar
|
||||
InsertItemAt( pMenu);
|
||||
NS_RELEASE(pMenu); // owned in nsMenuBase
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> pOldNode( pItemNode);
|
||||
pOldNode->GetNextSibling( getter_AddRefs(pItemNode));
|
||||
}
|
||||
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsmenubase_h
|
||||
#define _nsmenubase_h
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsIMenuListener.h"
|
||||
|
||||
class nsString;
|
||||
class nsIWebShell;
|
||||
class nsIDOMElement;
|
||||
class nsIDOMNode;
|
||||
class nsISupportsArray;
|
||||
|
||||
// Base class for the various menu widgets to share code.
|
||||
|
||||
class nsToolkit;
|
||||
|
||||
class nsMenuBase : public nsIMenuListener
|
||||
{
|
||||
public:
|
||||
nsMenuBase();
|
||||
virtual ~nsMenuBase();
|
||||
|
||||
// common menu methods
|
||||
NS_IMETHOD GetItemCount( PRUint32 &aCount);
|
||||
NS_IMETHOD InsertItemAt( nsISupports *aThing, PRUint32 aPos = NS_MIT_END);
|
||||
NS_IMETHOD GetItemID( USHORT usID, PMENUITEM pItem);
|
||||
NS_IMETHOD GetItemAt( const PRUint32 &pos, PMENUITEM pItem);
|
||||
NS_IMETHOD GetItemAt( const PRUint32 &pos, nsISupports *&aThing);
|
||||
NS_IMETHOD UpdateItem( PMENUITEM pItem);
|
||||
NS_IMETHOD RemoveItemAt( const PRUint32 index);
|
||||
NS_IMETHOD RemoveAll();
|
||||
NS_IMETHOD GetNativeData( void **aNative);
|
||||
|
||||
// dummy nsIMenuListener implementation
|
||||
virtual nsEventStatus MenuSelected( const nsMenuEvent &aMenuEvent);
|
||||
virtual nsEventStatus MenuItemSelected( const nsMenuEvent &aMenuEvent);
|
||||
virtual nsEventStatus MenuDeselected( const nsMenuEvent &aMenuEvent);
|
||||
virtual nsEventStatus MenuConstruct( const nsMenuEvent &aMenuEvent,
|
||||
nsIWidget *aParentWindow,
|
||||
void *menubarNode,
|
||||
void *aWebShell);
|
||||
virtual nsEventStatus MenuDestruct( const nsMenuEvent &aMenuEvent);
|
||||
|
||||
// helpers
|
||||
MRESULT SendMsg( ULONG m, MPARAM mp1=0, MPARAM mp2=0);
|
||||
nsToolkit *GetTK() { return mToolkit; }
|
||||
|
||||
protected:
|
||||
virtual BOOL VerifyIndex( PRUint32 index);
|
||||
|
||||
void Create( HWND hwndParent, nsToolkit *aToolkit);
|
||||
void Destroy();
|
||||
|
||||
// Subclasses should supply extra style bits here if required.
|
||||
virtual ULONG WindowStyle();
|
||||
|
||||
nsToolkit *mToolkit;
|
||||
HWND mWnd;
|
||||
nsISupportsArray *mElements; // we now own the menu elements
|
||||
};
|
||||
|
||||
#define DECL_MENU_BASE_METHODS \
|
||||
NS_IMETHOD AddItem( nsISupports *aThing) \
|
||||
{ return nsMenuBase::InsertItemAt( aThing); } \
|
||||
NS_IMETHOD AddSeparator() \
|
||||
{ return nsMenuBase::InsertItemAt( nsnull); } \
|
||||
NS_IMETHOD GetItemCount( PRUint32 &aCount) \
|
||||
{ return nsMenuBase::GetItemCount( aCount); } \
|
||||
NS_IMETHOD GetItemAt( const PRUint32 aCount, nsISupports *&aThing) \
|
||||
{ return nsMenuBase::GetItemAt( aCount, aThing); } \
|
||||
NS_IMETHOD InsertItemAt( const PRUint32 aCount, nsISupports *aThing) \
|
||||
{ return nsMenuBase::InsertItemAt( aThing, aCount); } \
|
||||
NS_IMETHOD InsertSeparator( const PRUint32 aCount) \
|
||||
{ return nsMenuBase::InsertItemAt( nsnull, aCount); } \
|
||||
NS_IMETHOD RemoveItem( const PRUint32 aCount) \
|
||||
{ return nsMenuBase::RemoveItemAt( aCount); } \
|
||||
NS_IMETHOD RemoveAll() \
|
||||
{ return nsMenuBase::RemoveAll(); } \
|
||||
NS_IMETHOD GetNativeData( void **aNative) \
|
||||
{ return nsMenuBase::GetNativeData( aNative); }
|
||||
|
||||
// Base class for nsMenu & nsContextMenu, menus whose contents are build afresh
|
||||
// from the DOM content model on each activation.
|
||||
class nsDynamicMenu : public nsMenuBase
|
||||
{
|
||||
public:
|
||||
nsDynamicMenu();
|
||||
virtual ~nsDynamicMenu();
|
||||
|
||||
// Common methods
|
||||
NS_IMETHOD AddMenuListener( nsIMenuListener *aMenuListener);
|
||||
NS_IMETHOD RemoveMenuListener( nsIMenuListener *aMenuListener);
|
||||
NS_IMETHOD SetDOMNode( nsIDOMNode *aMenuNode);
|
||||
NS_IMETHOD SetDOMElement( nsIDOMElement *aMenuElement);
|
||||
NS_IMETHOD SetWebShell( nsIWebShell *aWebShell);
|
||||
|
||||
// nsIMenuListener override to build/tear down the menu
|
||||
virtual nsEventStatus MenuSelected( const nsMenuEvent &aMenuEvent);
|
||||
|
||||
protected:
|
||||
nsIMenuListener *mListener;
|
||||
nsIWebShell *mWebShell;
|
||||
nsIDOMNode *mDOMNode;
|
||||
nsIDOMElement *mDOMElement;
|
||||
};
|
||||
|
||||
#define DECL_DYNAMIC_MENU_METHODS \
|
||||
DECL_MENU_BASE_METHODS \
|
||||
NS_IMETHOD AddMenuListener( nsIMenuListener *aMenuListener) \
|
||||
{ return nsDynamicMenu::AddMenuListener( aMenuListener); } \
|
||||
NS_IMETHOD RemoveMenuListener( nsIMenuListener *aMenuListener) \
|
||||
{ return nsDynamicMenu::RemoveMenuListener( aMenuListener); } \
|
||||
NS_IMETHOD SetDOMNode( nsIDOMNode *aMenuNode) \
|
||||
{ return nsDynamicMenu::SetDOMNode( aMenuNode); } \
|
||||
NS_IMETHOD SetDOMElement( nsIDOMElement *aMenuElement) \
|
||||
{ return nsDynamicMenu::SetDOMElement( aMenuElement); } \
|
||||
NS_IMETHOD SetWebShell( nsIWebShell *aWebShell) \
|
||||
{ return nsDynamicMenu::SetWebShell( aWebShell); }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,387 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// menu item
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsMenuItem.h"
|
||||
#include "nsMenuBase.h"
|
||||
#include "nsIMenu.h"
|
||||
#include "nsIContextMenu.h"
|
||||
#include "nsIMenuBar.h"
|
||||
#include "nsWindow.h"
|
||||
|
||||
#include "nsIDocumentViewer.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIWebShell.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
// XP-Com
|
||||
NS_IMPL_ADDREF(nsMenuItem)
|
||||
NS_IMPL_RELEASE(nsMenuItem)
|
||||
|
||||
nsresult nsMenuItem::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if( nsnull == aInstancePtr)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aInstancePtr = nsnull;
|
||||
|
||||
if( aIID.Equals(nsIMenuItem::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIMenuItem*) this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if( aIID.Equals(nsIMenuListener::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIMenuListener*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if( aIID.Equals(((nsISupports*)(nsIMenuItem*)this)->GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsISupports*)((nsIMenuItem*)this));
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
nsMenuItem::nsMenuItem() : mMenuBase(nsnull), mIsSeparator(PR_FALSE),
|
||||
mTarget(nsnull), mPMID(0), mMenuListener(nsnull),
|
||||
mDOMElement(nsnull), mWebShell(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsMenuItem::~nsMenuItem()
|
||||
{
|
||||
NS_IF_RELEASE(mMenuListener);
|
||||
}
|
||||
|
||||
// Helper function to find the widget at the root of the menu tree.
|
||||
//
|
||||
// This may have to traverse an arbitrary number of cascaded menus.
|
||||
|
||||
static nsIWidget *FindWidget( nsISupports *aParent)
|
||||
{
|
||||
nsIWidget *widget = nsnull;
|
||||
nsIMenu *menu = nsnull;
|
||||
nsIMenuBar *menuBar = nsnull;
|
||||
nsIContextMenu *popup = nsnull;
|
||||
nsISupports *parent = aParent;
|
||||
|
||||
// Bump the ref count on the parent, since it gets released unconditionally..
|
||||
NS_ADDREF(parent);
|
||||
for( ;;)
|
||||
{
|
||||
if( NS_OK == parent->QueryInterface( nsIMenu::GetIID(), (void**) &menu))
|
||||
{
|
||||
NS_RELEASE(parent);
|
||||
if( NS_OK != menu->GetParent(parent))
|
||||
{
|
||||
NS_RELEASE(menu);
|
||||
return nsnull;
|
||||
}
|
||||
NS_RELEASE(menu);
|
||||
}
|
||||
else if( NS_OK == parent->QueryInterface( nsIContextMenu::GetIID(),
|
||||
(void**) &popup))
|
||||
{
|
||||
nsISupports *pThing = 0;
|
||||
if( NS_OK != popup->GetParent( pThing))
|
||||
{
|
||||
widget = nsnull;
|
||||
}
|
||||
pThing->QueryInterface( nsIWidget::GetIID(), (void**) &widget);
|
||||
NS_RELEASE(parent);
|
||||
NS_RELEASE(popup);
|
||||
return widget;
|
||||
}
|
||||
else if( NS_OK == parent->QueryInterface( nsIMenuBar::GetIID(),
|
||||
(void**) &menuBar))
|
||||
{
|
||||
if( NS_OK != menuBar->GetParent(widget))
|
||||
{
|
||||
widget = nsnull;
|
||||
}
|
||||
NS_RELEASE(parent);
|
||||
NS_RELEASE(menuBar);
|
||||
return widget;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_RELEASE(parent);
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::Create( nsISupports *aParent, const nsString &aLabel,
|
||||
PRBool aIsSeparator)
|
||||
{
|
||||
nsIContextMenu *pPopup = nsnull;
|
||||
nsIMenu *pMenu = nsnull;
|
||||
|
||||
void *pvWnd = 0;
|
||||
|
||||
if( NS_SUCCEEDED( aParent->QueryInterface( nsIMenu::GetIID(),
|
||||
(void**) &pMenu)))
|
||||
{
|
||||
pMenu->GetNativeData( &pvWnd);
|
||||
NS_RELEASE(pMenu);
|
||||
}
|
||||
else if( NS_SUCCEEDED( aParent->QueryInterface( nsIContextMenu::GetIID(),
|
||||
(void**) &pPopup)))
|
||||
{
|
||||
pPopup->GetNativeData( &pvWnd);
|
||||
NS_RELEASE(pPopup);
|
||||
}
|
||||
|
||||
mMenuBase = (nsMenuBase*) WinQueryWindowPtr( (HWND) pvWnd, QWL_USER);
|
||||
mLabel = aLabel;
|
||||
|
||||
mTarget = FindWidget( aParent);
|
||||
NS_ASSERTION(mTarget,"Can't find window to target menuitem to");
|
||||
if( mTarget)
|
||||
{
|
||||
mIsSeparator = aIsSeparator;
|
||||
|
||||
HWND hwnd = (HWND) mTarget->GetNativeData( NS_NATIVE_WINDOW);
|
||||
nsWindow *wnd = NS_HWNDToWindow( hwnd); // doesn't addref
|
||||
mPMID = wnd->GetNextCmdID();
|
||||
mTarget->Release(); // don't want to hold a ref to the window
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::GetLabel( nsString &aText)
|
||||
{
|
||||
aText = mLabel;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::SetLabel( nsString &aText)
|
||||
{
|
||||
mLabel = aText;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// menuitem style
|
||||
nsresult nsMenuItem::SetEnabled( PRBool aIsEnabled)
|
||||
{
|
||||
MENUITEM mI;
|
||||
mMenuBase->GetItemID( mPMID, &mI);
|
||||
if( PR_TRUE == aIsEnabled)
|
||||
mI.afAttribute &= ~MIA_DISABLED;
|
||||
else
|
||||
mI.afAttribute |= MIA_DISABLED;
|
||||
mMenuBase->UpdateItem( &mI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::GetEnabled( PRBool *aIsEnabled)
|
||||
{
|
||||
if( nsnull == aIsEnabled)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
MENUITEM mI;
|
||||
mMenuBase->GetItemID( mPMID, &mI);
|
||||
|
||||
*aIsEnabled = ((mI.afAttribute & MIA_DISABLED) ? PR_FALSE : PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::SetChecked( PRBool aIsChecked)
|
||||
{
|
||||
MENUITEM mI;
|
||||
mMenuBase->GetItemID( mPMID, &mI);
|
||||
if( PR_TRUE == aIsChecked)
|
||||
mI.afAttribute |= MIA_CHECKED;
|
||||
else
|
||||
mI.afAttribute &= ~MIA_CHECKED;
|
||||
mMenuBase->UpdateItem( &mI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::GetChecked( PRBool *aIsChecked)
|
||||
{
|
||||
if( nsnull == aIsChecked)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
MENUITEM mI;
|
||||
mMenuBase->GetItemID( mPMID, &mI);
|
||||
|
||||
*aIsChecked = ((mI.afAttribute & MIA_CHECKED) ? PR_TRUE : PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::GetCommand( PRUint32 &aCommand)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::GetTarget( nsIWidget *&aTarget)
|
||||
{
|
||||
NS_IF_RELEASE(aTarget);
|
||||
aTarget = mTarget;
|
||||
NS_IF_ADDREF(aTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::GetNativeData( void *&aData)
|
||||
{
|
||||
return mMenuBase->GetNativeData( &aData);
|
||||
}
|
||||
|
||||
NS_METHOD nsMenuItem::AddMenuListener( nsIMenuListener *aMenuListener)
|
||||
{
|
||||
NS_IF_RELEASE(mMenuListener);
|
||||
mMenuListener = aMenuListener;
|
||||
NS_ADDREF(mMenuListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsMenuItem::RemoveMenuListener( nsIMenuListener *aMenuListener)
|
||||
{
|
||||
if( mMenuListener == aMenuListener)
|
||||
NS_IF_RELEASE(mMenuListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::IsSeparator( PRBool &aIsSep)
|
||||
{
|
||||
aIsSep = mIsSeparator;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::SetCommand( const nsString &aStrCmd)
|
||||
{
|
||||
mCmdString = aStrCmd;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::DoCommand()
|
||||
{
|
||||
// code copied from windows
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIContentViewerContainer> contentViewerContainer;
|
||||
contentViewerContainer = do_QueryInterface(mWebShell);
|
||||
if (!contentViewerContainer) {
|
||||
NS_ERROR("Webshell doesn't support the content viewer container interface");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContentViewer> contentViewer;
|
||||
if (NS_FAILED(rv = contentViewerContainer->GetContentViewer(getter_AddRefs(contentViewer)))) {
|
||||
NS_ERROR("Unable to retrieve content viewer.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocumentViewer> docViewer;
|
||||
docViewer = do_QueryInterface(contentViewer);
|
||||
if (!docViewer) {
|
||||
NS_ERROR("Document viewer interface not supported by the content viewer.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
if (NS_FAILED(rv = docViewer->GetPresContext(*getter_AddRefs(presContext)))) {
|
||||
NS_ERROR("Unable to retrieve the doc viewer's presentation context.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_MOUSE_EVENT;
|
||||
event.message = NS_MOUSE_LEFT_CLICK;
|
||||
|
||||
nsCOMPtr<nsIContent> contentNode;
|
||||
contentNode = do_QueryInterface(mDOMElement);
|
||||
if (!contentNode) {
|
||||
NS_ERROR("DOM Node doesn't support the nsIContent interface required to handle DOM events.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = contentNode->HandleDOMEvent(*presContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::SetDOMElement( nsIDOMElement *aDOMElement)
|
||||
{
|
||||
mDOMElement = aDOMElement;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::GetDOMElement( nsIDOMElement **aDOMElement)
|
||||
{
|
||||
if( !aDOMElement)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_IF_RELEASE(*aDOMElement);
|
||||
*aDOMElement = mDOMElement;
|
||||
NS_IF_ADDREF(mDOMElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMenuItem::SetWebShell( nsIWebShell *aWebShell)
|
||||
{
|
||||
mWebShell = aWebShell;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIMenuListener interface
|
||||
nsEventStatus nsMenuItem::MenuItemSelected( const nsMenuEvent &aMenuEvent)
|
||||
{
|
||||
DoCommand();
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
nsEventStatus nsMenuItem::MenuConstruct( const nsMenuEvent &aMenuEvent,
|
||||
nsIWidget *aParentWindow,
|
||||
void *menubarNode,
|
||||
void *aWebShell)
|
||||
{
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
nsEventStatus nsMenuItem::MenuSelected( const nsMenuEvent &aMenuEvent)
|
||||
{
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
nsEventStatus nsMenuItem::MenuDeselected(const nsMenuEvent & aMenuEvent)
|
||||
{
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
nsEventStatus nsMenuItem::MenuDestruct( const nsMenuEvent &aMenuEvent)
|
||||
{
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// nsMenuItem - interface to things which live in menus.
|
||||
//
|
||||
// This is rather complicated, not least because it contains about 2 1/2
|
||||
// versions of the API rolled up into 1.
|
||||
|
||||
#ifndef _nsmenuitem_h
|
||||
#define _nsmenuitem_h
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIMenuItem.h"
|
||||
#include "nsIMenuListener.h"
|
||||
|
||||
class nsMenuBase;
|
||||
class nsIDOMElement;
|
||||
class nsIWebShell;
|
||||
|
||||
class nsMenuItem : public nsIMenuItem, public nsIMenuListener
|
||||
{
|
||||
public:
|
||||
nsMenuItem();
|
||||
virtual ~nsMenuItem();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIMenuItem
|
||||
NS_IMETHOD Create( nsISupports *aParent, const nsString &aLabel, PRBool isSep);
|
||||
NS_IMETHOD GetLabel( nsString &aText);
|
||||
NS_IMETHOD SetLabel( nsString &aText);
|
||||
NS_IMETHOD SetEnabled( PRBool aIsEnabled);
|
||||
NS_IMETHOD GetEnabled( PRBool *aIsEnabled);
|
||||
NS_IMETHOD SetChecked( PRBool aIsEnabled);
|
||||
NS_IMETHOD GetChecked( PRBool *aIsEnabled);
|
||||
NS_IMETHOD GetCommand( PRUint32 &aCommand);
|
||||
NS_IMETHOD GetTarget( nsIWidget *&aTarget);
|
||||
NS_IMETHOD GetNativeData( void *&aData);
|
||||
NS_IMETHOD AddMenuListener( nsIMenuListener *aMenuListener);
|
||||
NS_IMETHOD RemoveMenuListener( nsIMenuListener *aMenuListener);
|
||||
NS_IMETHOD IsSeparator( PRBool &aIsSep);
|
||||
NS_IMETHOD SetCommand( const nsString &aStrCmd);
|
||||
NS_IMETHOD DoCommand();
|
||||
NS_IMETHOD SetDOMElement( nsIDOMElement *aDOMElement);
|
||||
NS_IMETHOD GetDOMElement( nsIDOMElement **aDOMElement);
|
||||
NS_IMETHOD SetWebShell( nsIWebShell *aWebShell);
|
||||
|
||||
// nsIMenuListener interface
|
||||
nsEventStatus MenuSelected( const nsMenuEvent &aMenuEvent);
|
||||
nsEventStatus MenuItemSelected( const nsMenuEvent &aMenuEvent);
|
||||
nsEventStatus MenuDeselected( const nsMenuEvent &aMenuEvent);
|
||||
nsEventStatus MenuConstruct( const nsMenuEvent &aMenuEvent,
|
||||
nsIWidget *aParentWindow,
|
||||
void *menubarNode,
|
||||
void *aWebShell);
|
||||
nsEventStatus MenuDestruct( const nsMenuEvent &aMenuEvent);
|
||||
|
||||
// nsMenuItem
|
||||
USHORT GetPMID() { return mPMID; }
|
||||
|
||||
protected:
|
||||
nsMenuBase *mMenuBase; // Menu we are attached to
|
||||
nsString mLabel;
|
||||
PRBool mIsSeparator;
|
||||
nsIWidget *mTarget; // window we dispatch to
|
||||
USHORT mPMID; // PM command ID
|
||||
nsIMenuListener *mMenuListener;
|
||||
nsString mCmdString; // JS command
|
||||
nsIDOMElement *mDOMElement; // dom element for item
|
||||
nsIWebShell *mWebShell;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,416 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#define INCL_DOSDEVIOCTL // for keyboard layout
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "resid.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Module-level data & utility functions:
|
||||
// * unicode keycode & string conversion
|
||||
// * atom management
|
||||
// * printing bits & pieces (though not really any more)
|
||||
|
||||
#include "nsIFontRetrieverService.h"
|
||||
#include "nsDragService.h"
|
||||
#include "nsAppShell.h"
|
||||
|
||||
#include <unidef.h>
|
||||
|
||||
#define WARPZILLA_PRESPARAM "PP_WARPZILLA"
|
||||
|
||||
static void GetKeyboardName( char *buff);
|
||||
|
||||
nsWidgetModuleData::nsWidgetModuleData()
|
||||
{}
|
||||
|
||||
// This is called when the first appshell is created.
|
||||
void nsWidgetModuleData::Init( nsIAppShell *aPrimaevalAppShell)
|
||||
{
|
||||
if( 0 != hModResources) return;
|
||||
|
||||
char buffer[CCHMAXPATH];
|
||||
APIRET rc;
|
||||
|
||||
rc = DosLoadModule( buffer, CCHMAXPATH, "WDGTRES", &hModResources);
|
||||
|
||||
if( rc)
|
||||
{
|
||||
printf( "Widget failed to load resource DLL. rc = %d, cause = %s\n",
|
||||
(int)rc, buffer);
|
||||
hModResources = 0;
|
||||
}
|
||||
|
||||
szScreen.cx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN);
|
||||
szScreen.cy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN);
|
||||
|
||||
bMouseSwitched = WinQuerySysValue( HWND_DESKTOP, SV_SWAPBUTTON);
|
||||
|
||||
// Magic number -- height of normal text fields in pixels.
|
||||
// Both combobox and (atm) nsBrowserWindow depend on this.
|
||||
lHtEntryfield = 26;
|
||||
|
||||
rc = WinLoadString( 0/*hab*/, hModResources, ID_STR_FONT, 256, buffer);
|
||||
if( !rc) strcpy( buffer, "8.Helv");
|
||||
pszFontNameSize = strdup( buffer);
|
||||
|
||||
hptrSelect = hptrFrameIcon = 0;
|
||||
|
||||
// Work out if the system is DBCS
|
||||
COUNTRYCODE cc = { 0 };
|
||||
DosQueryDBCSEnv( CCHMAXPATH, &cc, buffer);
|
||||
bIsDBCS = buffer[0] || buffer[1];
|
||||
|
||||
ppMozilla = GetAtom( WARPZILLA_PRESPARAM);
|
||||
|
||||
fontService = nsnull;
|
||||
|
||||
dragService = new nsDragService;
|
||||
NS_ADDREF(dragService);
|
||||
|
||||
// keep a ref beyond the client app so we shut ourselves down properly.
|
||||
appshell = aPrimaevalAppShell;
|
||||
NS_ADDREF(appshell);
|
||||
|
||||
converter = 0;
|
||||
supplantConverter = FALSE;
|
||||
|
||||
// create unicode keyboard object
|
||||
char kbdname[8];
|
||||
UniChar unikbdname[8];
|
||||
GetKeyboardName( kbdname);
|
||||
for( int i = 0; i < 8; i++)
|
||||
unikbdname[i] = kbdname[i];
|
||||
|
||||
if( UniCreateKeyboard( &hKeyboard, unikbdname, 0) != ULS_SUCCESS)
|
||||
hKeyboard = 0;
|
||||
#ifdef DEBUG
|
||||
else
|
||||
printf( "Widget library loaded keyboard table for %s\n", kbdname);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
mWindows = nsnull;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsWidgetModuleData::~nsWidgetModuleData()
|
||||
{
|
||||
if( hKeyboard)
|
||||
UniDestroyKeyboard( hKeyboard);
|
||||
|
||||
if( converter)
|
||||
UniFreeUconvObject( converter);
|
||||
|
||||
NS_IF_RELEASE(dragService);
|
||||
|
||||
NS_IF_RELEASE(fontService);
|
||||
|
||||
PRInt32 cAtoms = atoms.Count();
|
||||
HATOMTBL systbl = WinQuerySystemAtomTable();
|
||||
for( PRInt32 i = 0; i < cAtoms; i++)
|
||||
WinDeleteAtom( systbl, (ATOM) atoms.ElementAt(i));
|
||||
|
||||
if( hptrSelect)
|
||||
WinDestroyPointer( hptrSelect);
|
||||
if( hptrFrameIcon)
|
||||
WinDestroyPointer( hptrFrameIcon);
|
||||
if( hModResources)
|
||||
DosFreeModule( hModResources);
|
||||
free( pszFontNameSize);
|
||||
#if 0
|
||||
delete mWindows;
|
||||
#endif
|
||||
|
||||
// finally shut down the appshell. No more PM.
|
||||
// (hope that gfxos2 has gone first!)
|
||||
NS_IF_RELEASE(appshell);
|
||||
}
|
||||
|
||||
HPOINTER nsWidgetModuleData::GetPointer( nsCursor aCursor)
|
||||
{
|
||||
if( aCursor != eCursor_hyperlink)
|
||||
printf( "\n*** Need to implement cursor type %d (see widget/os2/nsModule.cpp)\n\n", (int) aCursor);
|
||||
|
||||
// Use an array and indices here when we have all the pointers in place.
|
||||
if( !hptrSelect)
|
||||
hptrSelect = WinLoadPointer( HWND_DESKTOP,
|
||||
hModResources, ID_PTR_SELECTURL);
|
||||
return hptrSelect;
|
||||
}
|
||||
|
||||
HPOINTER nsWidgetModuleData::GetFrameIcon()
|
||||
{
|
||||
if( !hptrFrameIcon)
|
||||
hptrFrameIcon = WinLoadPointer( HWND_DESKTOP,
|
||||
hModResources, ID_ICO_FRAME);
|
||||
return hptrFrameIcon;
|
||||
}
|
||||
|
||||
// Conversion from unicode to appropriate codepage
|
||||
char *nsWidgetModuleData::ConvertFromUcs( const PRUnichar *pText,
|
||||
char *szBuffer, ULONG ulSize)
|
||||
{
|
||||
if( supplantConverter)
|
||||
{
|
||||
// We couldn't create a converter for some reason, so do this 'by hand'.
|
||||
// Note this algorithm is fine for most of most western charsets, but
|
||||
// fails dismally for various glyphs, baltic, points east...
|
||||
ULONG ulCount = 0;
|
||||
char *szSave = szBuffer;
|
||||
while( *pText && ulCount < ulSize - 1) // (one for terminator)
|
||||
{
|
||||
*szBuffer = (char) *pText;
|
||||
szBuffer++;
|
||||
pText++;
|
||||
ulCount++;
|
||||
}
|
||||
|
||||
// terminate string
|
||||
*szBuffer = '\0';
|
||||
|
||||
return szSave;
|
||||
}
|
||||
|
||||
if( !converter)
|
||||
{
|
||||
// Create a converter from unicode to a codepage which PM can display.
|
||||
UniChar codepage[20];
|
||||
int unirc = UniMapCpToUcsCp( 0, codepage, 20);
|
||||
if( unirc == ULS_SUCCESS)
|
||||
{
|
||||
unirc = UniCreateUconvObject( codepage, &converter);
|
||||
// XXX do we need to set substitution options here?
|
||||
#ifdef DEBUG
|
||||
if( unirc == ULS_SUCCESS)
|
||||
{
|
||||
printf( "Widget library created unicode converter for cp %s\n",
|
||||
ConvertFromUcs( (PRUnichar *) codepage));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if( unirc != ULS_SUCCESS)
|
||||
{
|
||||
supplantConverter = TRUE;
|
||||
printf( "Couldn't create widget unicode converter.\n");
|
||||
return ConvertFromUcs( pText, szBuffer, ulSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Have converter, now get it to work...
|
||||
|
||||
UniChar *ucsString = (UniChar*) pText;
|
||||
size_t ucsLen = UniStrlen( ucsString) + 1;
|
||||
size_t cplen = ulSize;
|
||||
size_t cSubs = 0;
|
||||
|
||||
char *tmp = szBuffer; // function alters the out pointer
|
||||
|
||||
int unirc = UniUconvFromUcs( converter, &ucsString, &ucsLen,
|
||||
(void**) &tmp, &cplen, &cSubs);
|
||||
|
||||
if( unirc == UCONV_E2BIG) // k3w1
|
||||
{
|
||||
// terminate output string (truncating)
|
||||
*(szBuffer + ulSize - 1) = '\0';
|
||||
}
|
||||
else if( unirc != ULS_SUCCESS)
|
||||
{
|
||||
printf( "UniUconvFromUcs failed, rc %X\n", unirc);
|
||||
supplantConverter = TRUE;
|
||||
szBuffer = ConvertFromUcs( pText, szBuffer, ulSize);
|
||||
supplantConverter = FALSE;
|
||||
}
|
||||
|
||||
return szBuffer;
|
||||
}
|
||||
|
||||
char *nsWidgetModuleData::ConvertFromUcs( const nsString &aString,
|
||||
char *szBuffer, ULONG ulSize)
|
||||
{
|
||||
char *szRet = 0;
|
||||
const PRUnichar *pUnicode = aString.GetUnicode();
|
||||
|
||||
if( pUnicode)
|
||||
szRet = ConvertFromUcs( pUnicode, szBuffer, ulSize);
|
||||
else
|
||||
szRet = aString.ToCString( szBuffer, ulSize);
|
||||
|
||||
return szRet;
|
||||
}
|
||||
|
||||
const char *nsWidgetModuleData::ConvertFromUcs( const PRUnichar *pText)
|
||||
{
|
||||
// This is probably okay; longer strings will be truncated but istr there's
|
||||
// a PM limit on things like windowtext
|
||||
// (which these routines are usually used for)
|
||||
|
||||
static char buffer[1024]; // XXX (multithread)
|
||||
*buffer = '\0';
|
||||
return ConvertFromUcs( pText, buffer, 1024);
|
||||
}
|
||||
|
||||
const char *nsWidgetModuleData::ConvertFromUcs( const nsString &aString)
|
||||
{
|
||||
const char *szRet = 0;
|
||||
const PRUnichar *pUnicode = aString.GetUnicode();
|
||||
|
||||
if( pUnicode)
|
||||
szRet = ConvertFromUcs( pUnicode);
|
||||
else
|
||||
szRet = aString.GetBuffer(); // hrm.
|
||||
|
||||
return szRet;
|
||||
}
|
||||
|
||||
// Wrapper around UniTranslateKey to deal with shift-state etc.
|
||||
int nsWidgetModuleData::TranslateKey( VSCAN scan, UniChar *pChar, VDKEY *vdkey)
|
||||
{
|
||||
int unirc = 1;
|
||||
|
||||
// bail if we've not got a keyboard
|
||||
if( !hKeyboard) return unirc;
|
||||
|
||||
// XXX Right, this seems madly wrong, but I'm not sure what else to do.
|
||||
// We need to work out the 'effective shift state' before calling
|
||||
// UniTranslateKey(). This is derived from the state of the keyboard
|
||||
// and the current scancode. Unfortunately, the only way I can find
|
||||
// the current state of the various keys is by doing this on each
|
||||
// keypress!
|
||||
//
|
||||
// XXX Anything else to test? Layers? Or are they just deadkey applications?
|
||||
// Are deadkeys meant to go in here?
|
||||
|
||||
ULONG sstate = 0;
|
||||
|
||||
if( WinIsKeyDown(VK_SHIFT)) sstate |= KBD_SHIFT;
|
||||
if( WinIsKeyDown(VK_CTRL)) sstate |= KBD_CTRL;
|
||||
// if( WinIsKeyDown(VK_ALT)) sstate |= KBD_ALT;
|
||||
// if( WinIsKeyDown(VK_ALTGRAF)) sstate |= KBD_ALTGR;
|
||||
|
||||
#define TOGGLED(vk) (WinGetKeyState(HWND_DESKTOP,vk) & 1)
|
||||
|
||||
if( TOGGLED(VK_CAPSLOCK)) sstate |= KBD_CAPSLOCK;
|
||||
if( TOGGLED(VK_NUMLOCK)) sstate |= KBD_NUMLOCK;
|
||||
if( TOGGLED(VK_SCRLLOCK)) sstate |= KBD_SCROLLLOCK;
|
||||
|
||||
USHIFTSTATE uss = { sstate, 0, 0 };
|
||||
|
||||
unirc = UniUpdateShiftState( hKeyboard, &uss, scan, 0);
|
||||
if( unirc == ULS_SUCCESS)
|
||||
{
|
||||
BYTE bBiosScancode;
|
||||
unirc = UniTranslateKey( hKeyboard,
|
||||
uss.Effective,
|
||||
scan,
|
||||
pChar,
|
||||
vdkey,
|
||||
&bBiosScancode);
|
||||
}
|
||||
|
||||
return unirc;
|
||||
}
|
||||
|
||||
static void GetKeyboardName( char *buff)
|
||||
{
|
||||
HFILE hKeyboard = 0;
|
||||
ULONG ulAction;
|
||||
|
||||
strcpy( buff, "UK");
|
||||
|
||||
if( !DosOpen( "KBD$", &hKeyboard, &ulAction, 0, FILE_NORMAL, FILE_OPEN,
|
||||
OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE, NULL))
|
||||
{
|
||||
ULONG ulDataLen;
|
||||
#pragma pack(2)
|
||||
struct { USHORT usLength; USHORT usCp; CHAR ach[8];} kcp;
|
||||
#pragma pack()
|
||||
|
||||
kcp.usLength = ulDataLen = sizeof kcp;
|
||||
|
||||
if( !DosDevIOCtl( hKeyboard, IOCTL_KEYBOARD, KBD_QUERYKBDCODEPAGESUPPORT,
|
||||
0, 0, 0,
|
||||
&kcp, ulDataLen, &ulDataLen))
|
||||
strcpy( buff, kcp.ach);
|
||||
|
||||
DosClose( hKeyboard);
|
||||
}
|
||||
}
|
||||
|
||||
ATOM nsWidgetModuleData::GetAtom( const char *atomname)
|
||||
{
|
||||
ATOM atom = WinAddAtom( WinQuerySystemAtomTable(), atomname);
|
||||
atoms.AppendElement( (void*) atom);
|
||||
return atom;
|
||||
}
|
||||
|
||||
ATOM nsWidgetModuleData::GetAtom( const nsString &atomname)
|
||||
{
|
||||
return GetAtom( ConvertFromUcs( atomname));
|
||||
}
|
||||
|
||||
// Printing stuff -- need to be able to generate a window of a given
|
||||
// flavour and then do stuff to it in nsWindow::Paint()
|
||||
|
||||
#if 0
|
||||
|
||||
class nsWndClassKey : public nsHashKey
|
||||
{
|
||||
PCSZ pszClassname;
|
||||
|
||||
public:
|
||||
nsWndClassKey( PCSZ pszName) : pszClassname( pszName)
|
||||
{}
|
||||
PRUint32 HashValue() const
|
||||
{ return (PRUint32) pszClassname; }
|
||||
PRBool Equals( const nsHashKey *aKey) const
|
||||
{ return HashValue() == aKey->HashValue(); }
|
||||
nsHashKey *Clone() const
|
||||
{ return new nsWndClassKey( pszClassname); }
|
||||
};
|
||||
|
||||
|
||||
// Get a window to render its state
|
||||
HWND nsWidgetModuleData::GetWindowForPrinting( PCSZ pszClass, ULONG ulStyle)
|
||||
{
|
||||
if( mWindows == nsnull)
|
||||
mWindows = new nsHashtable;
|
||||
|
||||
nsWndClassKey aKey( pszClass);
|
||||
|
||||
if( mWindows->Get( &aKey) == nsnull)
|
||||
{
|
||||
HWND hwnd = WinCreateWindow( HWND_DESKTOP, pszClass, "", ulStyle,
|
||||
0, -4096, 0, 0, HWND_DESKTOP,
|
||||
HWND_TOP, 0, 0, 0);
|
||||
NS_ASSERTION( hwnd, "WinCreateWindow for printing failed");
|
||||
mWindows->Put( &aKey, (void*) hwnd);
|
||||
}
|
||||
|
||||
return (HWND) mWindows->Get( &aKey);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
nsWidgetModuleData gModuleData;
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// popup menu
|
||||
|
||||
#include "nsPopupMenu.h"
|
||||
#include "nsWindow.h"
|
||||
|
||||
// XPCom
|
||||
NS_IMPL_ADDREF(nsPopupMenu)
|
||||
NS_IMPL_RELEASE(nsPopupMenu)
|
||||
|
||||
nsresult nsPopupMenu::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if( !aInstancePtr)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aInstancePtr = 0;
|
||||
|
||||
if( aIID.Equals(nsIPopupMenu::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIPopUpMenu*) this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if( aIID.Equals(((nsISupports*)(nsIPopUpMenu*)this)->GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsISupports*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
||||
nsPopupMenu::nsPopupMenu() : mParent(0), nsMenuBase()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsPopupMenu::~nsPopupMenu()
|
||||
{
|
||||
NS_IF_RELEASE(mParent);
|
||||
}
|
||||
|
||||
// Creation: parent to the desktop, owner to the `parent'
|
||||
nsresult nsPopupMenu::Create( nsIWidget *aParent)
|
||||
{
|
||||
// find the owner hwnd & nsWindow (for the toolkit)
|
||||
HWND hwndOwner = (HWND) aParent->GetNativeData( NS_NATIVE_WINDOW);
|
||||
mParent = NS_HWNDToWindow( hwndOwner);
|
||||
NS_ADDREF(mParent);
|
||||
|
||||
nsIToolkit *aToolkit = mParent->GetToolkit();
|
||||
|
||||
nsMenuBase::Create( HWND_DESKTOP, (nsToolkit*) aToolkit);
|
||||
NS_RELEASE(aToolkit);
|
||||
|
||||
WinSetOwner( mWnd, hwndOwner);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPopupMenu::GetParent( nsIWidget *&aParent)
|
||||
{
|
||||
NS_IF_RELEASE(aParent);
|
||||
aParent = mParent;
|
||||
NS_IF_ADDREF(aParent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ULONG nsPopupMenu::WindowStyle()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult nsPopupMenu::ShowMenu( PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
POINTL pos = { aX, aY };
|
||||
mParent->NS2PM(pos);
|
||||
|
||||
WinPopupMenu( HWND_DESKTOP,
|
||||
(HWND) mParent->GetNativeData( NS_NATIVE_WIDGET),
|
||||
mWnd, pos.x, pos.y, 0,
|
||||
PU_HCONSTRAIN | PU_VCONSTRAIN | PU_NONE |
|
||||
PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2);
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsPopupMenu_h
|
||||
#define _nsPopupMenu_h
|
||||
|
||||
// A menu for popping up.
|
||||
|
||||
#include "nsIPopupMenu.h"
|
||||
#include "nsMenuBase.h"
|
||||
|
||||
class nsWindow;
|
||||
class nsIMenuItem;
|
||||
|
||||
class nsPopupMenu : public nsIPopUpMenu, public nsMenuBase
|
||||
{
|
||||
public:
|
||||
nsPopupMenu();
|
||||
~nsPopupMenu();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIPopupMenu
|
||||
NS_IMETHOD Create( nsIWidget *aParent);
|
||||
NS_IMETHOD GetParent( nsIWidget *&aParent);
|
||||
NS_IMETHOD ShowMenu( PRInt32 aX, PRInt32 aY);
|
||||
|
||||
// Common methods with nsMenu
|
||||
DECL_MENU_BASE_METHODS
|
||||
|
||||
// nsIPopUpMenu hasn't been revamped along with the other menu classes
|
||||
// in the `dynamic menu' effort, so don't try too hard getting these
|
||||
// old-style methods implemented -- it'll change soon. (ask saari if
|
||||
// concerned).
|
||||
NS_IMETHOD AddItem( nsIMenuItem *aMenuItem)
|
||||
{ return nsMenuBase::InsertItemAt( aMenuItem); }
|
||||
NS_IMETHOD GetItemAt( const PRUint32 aCount, nsIMenuItem *&aThing)
|
||||
{ return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD InsertItemAt( const PRUint32 aCount, nsIMenuItem *&aMenuItem)
|
||||
{ return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD InsertItemAt( const PRUint32 aCount, const nsString &aMenuItemName)
|
||||
{ return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD GetNativeData( void *&aData)
|
||||
{ return nsMenuBase::GetNativeData( &aData); }
|
||||
|
||||
protected:
|
||||
ULONG WindowStyle();
|
||||
|
||||
nsWindow *mParent;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// Push button control; don't really come any simpler than this...
|
||||
|
||||
#include "nsPushButton.h"
|
||||
|
||||
// XP-com
|
||||
NS_IMPL_ADDREF(nsPushButton)
|
||||
NS_IMPL_RELEASE(nsPushButton)
|
||||
|
||||
nsresult nsPushButton::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
nsresult result = nsWindow::QueryInterface( aIID, aInstancePtr);
|
||||
|
||||
if( result == NS_NOINTERFACE && aIID.Equals( nsIButton::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIButton*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Text
|
||||
NS_IMPL_LABEL(nsPushButton)
|
||||
|
||||
// Creation hooks
|
||||
PCSZ nsPushButton::WindowClass()
|
||||
{
|
||||
return WC_BUTTON;
|
||||
}
|
||||
|
||||
ULONG nsPushButton::WindowStyle()
|
||||
{
|
||||
return BASE_CONTROL_STYLE | BS_PUSHBUTTON;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// Radio button control
|
||||
|
||||
#include "nsRadioButton.h"
|
||||
|
||||
// XP-com
|
||||
NS_IMPL_ADDREF(nsRadioButton)
|
||||
NS_IMPL_RELEASE(nsRadioButton)
|
||||
|
||||
nsresult nsRadioButton::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
nsresult result = nsWindow::QueryInterface( aIID, aInstancePtr);
|
||||
|
||||
if( result == NS_NOINTERFACE && aIID.Equals( nsIRadioButton::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIRadioButton*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Text
|
||||
NS_IMPL_LABEL(nsRadioButton)
|
||||
|
||||
// checked-ness
|
||||
nsresult nsRadioButton::GetState( PRBool &aState)
|
||||
{
|
||||
MRESULT rc = mOS2Toolkit->SendMsg( mWnd, BM_QUERYCHECK);
|
||||
aState = SHORT1FROMMR(rc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsRadioButton::SetState( const PRBool aState)
|
||||
{
|
||||
mOS2Toolkit->SendMsg( mWnd, BM_SETCHECK, MPFROMLONG(aState));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Creation hooks
|
||||
PCSZ nsRadioButton::WindowClass()
|
||||
{
|
||||
return WC_BUTTON;
|
||||
}
|
||||
|
||||
ULONG nsRadioButton::WindowStyle()
|
||||
{
|
||||
return BASE_CONTROL_STYLE | BS_RADIOBUTTON;
|
||||
}
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsScrollbar.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsUnitConversion.h"
|
||||
|
||||
NS_IMPL_ADDREF(nsScrollbar)
|
||||
NS_IMPL_RELEASE(nsScrollbar)
|
||||
|
||||
nsresult nsScrollbar::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
nsresult result = nsWindow::QueryInterface( aIID, aInstancePtr);
|
||||
|
||||
if( result == NS_NOINTERFACE && aIID.Equals( nsIScrollbar::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsIScrollbar*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Init; window creation
|
||||
nsScrollbar::nsScrollbar( PRBool aIsVertical) : nsWindow()
|
||||
{
|
||||
mOrientation = aIsVertical ? SBS_VERT : SBS_HORZ;
|
||||
mScaleFactor = 1.0f;
|
||||
mLineIncrement = 0;
|
||||
mThumbSize = 0;
|
||||
mMaxRange = 0;
|
||||
}
|
||||
|
||||
// nsWindow overrides to create the right kind of window
|
||||
PCSZ nsScrollbar::WindowClass()
|
||||
{
|
||||
return WC_SCROLLBAR;
|
||||
}
|
||||
|
||||
ULONG nsScrollbar::WindowStyle()
|
||||
{
|
||||
return mOrientation | SBS_THUMBSIZE | SBS_AUTOTRACK | BASE_CONTROL_STYLE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Metrics set/get ----------------------------------------------------------
|
||||
|
||||
// Note carefully that the widget concepts of "thumb size" & "range" are not
|
||||
// the same as the corresponding PM ones; they're much more like (?identical)
|
||||
// Java's. Basically the thumb size is not just cosmetic.
|
||||
//
|
||||
// This means that changing the thumb size or the max range means the other
|
||||
// must be changed too. This code may need some work.
|
||||
|
||||
#define ROUND_D(u) NSToIntRound( (u) / mScaleFactor)
|
||||
#define ROUND_U(u) (PRUint32) NSToIntRound( (u) * mScaleFactor)
|
||||
|
||||
void nsScrollbar::SetThumbRange( PRUint32 aEndRange, PRUint32 aSize)
|
||||
{
|
||||
// get current position
|
||||
|
||||
PRUint32 pos;
|
||||
GetPosition( pos);
|
||||
|
||||
// set scale factor dependent on max range
|
||||
if( aEndRange > 32000)
|
||||
mScaleFactor = aEndRange / 32000.0f;
|
||||
|
||||
// set new sizes
|
||||
mMaxRange = aEndRange;
|
||||
mThumbSize = aSize;
|
||||
|
||||
// set range & pos
|
||||
mOS2Toolkit->SendMsg( mWnd, SBM_SETSCROLLBAR,
|
||||
MPFROMSHORT( ROUND_D(pos)),
|
||||
MPFROM2SHORT( 0, ROUND_D(mMaxRange-mThumbSize)));
|
||||
|
||||
// set thumb
|
||||
mOS2Toolkit->SendMsg( mWnd, SBM_SETTHUMBSIZE,
|
||||
MPFROM2SHORT( ROUND_D(mThumbSize),
|
||||
ROUND_D(mMaxRange)));
|
||||
}
|
||||
|
||||
// Range - 0 to max range
|
||||
nsresult nsScrollbar::SetMaxRange( PRUint32 aEndRange)
|
||||
{
|
||||
SetThumbRange( aEndRange, mThumbSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Thumb size
|
||||
nsresult nsScrollbar::SetThumbSize( PRUint32 aSize)
|
||||
{
|
||||
SetThumbRange( mMaxRange, aSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Thumb position
|
||||
nsresult nsScrollbar::SetPosition( PRUint32 aPos)
|
||||
{
|
||||
mOS2Toolkit->SendMsg( mWnd, SBM_SETPOS, MPFROMSHORT(ROUND_D( aPos)));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollbar::GetPosition( PRUint32 &pos)
|
||||
{
|
||||
MRESULT rc = mOS2Toolkit->SendMsg( mWnd, SBM_QUERYPOS);
|
||||
pos = ROUND_U( SHORT1FROMMR(rc));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// All the above
|
||||
nsresult nsScrollbar::SetParameters( PRUint32 aMaxRange, PRUint32 aThumbSize,
|
||||
PRUint32 aPosition, PRUint32 aLineIncrement)
|
||||
{
|
||||
SetThumbRange( aMaxRange, aThumbSize);
|
||||
SetPosition( aPosition);
|
||||
SetLineIncrement( aLineIncrement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Deal with scrollbar messages -------------------------------------------
|
||||
|
||||
PRBool nsScrollbar::OnScroll( MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
PRBool rc = PR_TRUE;
|
||||
|
||||
USHORT usCmd = SHORT2FROMMP(mp2);
|
||||
int msg = 0;
|
||||
|
||||
BOOL hasEvent = mEventListener != nsnull || mEventCallback != nsnull;
|
||||
|
||||
PRUint32 newpos, li, ts;
|
||||
|
||||
GetPosition( newpos);
|
||||
GetLineIncrement( li);
|
||||
GetThumbSize( ts);
|
||||
|
||||
switch( usCmd)
|
||||
{
|
||||
case SB_LINERIGHT: // == SB_LINEDOWN
|
||||
{
|
||||
newpos += li;
|
||||
msg = NS_SCROLLBAR_LINE_NEXT;
|
||||
break;
|
||||
}
|
||||
|
||||
case SB_LINELEFT: // == SB_LINEUP
|
||||
{
|
||||
if( newpos > li) newpos -= li;
|
||||
else newpos = 0;
|
||||
msg = NS_SCROLLBAR_LINE_PREV;
|
||||
break;
|
||||
}
|
||||
|
||||
case SB_PAGERIGHT: // == SB_PAGEDOWN
|
||||
{
|
||||
newpos += (ts - li);
|
||||
msg = NS_SCROLLBAR_PAGE_NEXT;
|
||||
break;
|
||||
}
|
||||
|
||||
case SB_PAGELEFT: // == SB_PAGEUP
|
||||
{
|
||||
PRUint32 delta;
|
||||
delta = ts - li;
|
||||
if( newpos > delta) newpos -= delta;
|
||||
else newpos = 0;
|
||||
msg = NS_SCROLLBAR_PAGE_PREV;
|
||||
break;
|
||||
}
|
||||
|
||||
case SB_SLIDERTRACK:
|
||||
newpos = ROUND_U( SHORT1FROMMP(mp2));
|
||||
msg = NS_SCROLLBAR_POS;
|
||||
break;
|
||||
}
|
||||
|
||||
if( msg != 0)
|
||||
{
|
||||
// Ensure newpos is sensible
|
||||
if( newpos > (mMaxRange - mThumbSize))
|
||||
newpos = mMaxRange - mThumbSize;
|
||||
|
||||
// if there are listeners, give them a chance to alter newpos
|
||||
if( mEventListener != nsnull || mEventCallback != nsnull)
|
||||
{
|
||||
nsScrollbarEvent event;
|
||||
InitEvent( event, msg);
|
||||
event.eventStructType = NS_SCROLLBAR_EVENT;
|
||||
event.position = newpos;
|
||||
DispatchEventInternal( &event);
|
||||
|
||||
// Ensure position is still sensible
|
||||
newpos = event.position;
|
||||
if( newpos > (mMaxRange - mThumbSize))
|
||||
newpos = mMaxRange - mThumbSize;
|
||||
}
|
||||
|
||||
// Now move the scrollbar
|
||||
SetPosition( newpos);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nsscrollbar_h
|
||||
#define _nsscrollbar_h
|
||||
|
||||
#include "nsWindow.h"
|
||||
|
||||
#include "nsIScrollbar.h"
|
||||
|
||||
// WC_SCROLLBAR wrapper, for NS_HORZSCROLLBAR_CID & NS_VERTSCROLLBAR_CID
|
||||
|
||||
class nsScrollbar : public nsWindow, public nsIScrollbar
|
||||
{
|
||||
public:
|
||||
nsScrollbar( PRBool aIsVertical);
|
||||
|
||||
// nsISupports
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
|
||||
// nsIScrollbar part
|
||||
NS_IMETHOD SetMaxRange( PRUint32 aEndRange);
|
||||
NS_IMETHOD GetMaxRange( PRUint32 &mr) { mr = mMaxRange; return NS_OK; }
|
||||
NS_IMETHOD SetPosition( PRUint32 aPos);
|
||||
NS_IMETHOD GetPosition( PRUint32 &pos);
|
||||
NS_IMETHOD SetThumbSize( PRUint32 aSize);
|
||||
NS_IMETHOD GetThumbSize( PRUint32 &ts) { ts = mThumbSize; return NS_OK; }
|
||||
NS_IMETHOD SetLineIncrement( PRUint32 aSize) { mLineIncrement = aSize; return NS_OK; }
|
||||
NS_IMETHOD GetLineIncrement( PRUint32 &li) { li = mLineIncrement; return NS_OK; }
|
||||
NS_IMETHOD SetParameters( PRUint32 aMaxRange, PRUint32 aThumbSize,
|
||||
PRUint32 aPosition, PRUint32 aLineInc);
|
||||
|
||||
// Manage scroll events we generate
|
||||
virtual PRBool OnScroll( MPARAM mp1, MPARAM mp2);
|
||||
|
||||
protected:
|
||||
// Creation hooks
|
||||
virtual PCSZ WindowClass();
|
||||
virtual ULONG WindowStyle();
|
||||
|
||||
private:
|
||||
void SetThumbRange( PRUint32 aEndRange, PRUint32 aSize);
|
||||
ULONG mOrientation; // horz/vert
|
||||
int mLineIncrement; // inc. for line-scrolls
|
||||
float mScaleFactor; // to allow for >32k sizes
|
||||
PRUint32 mThumbSize; // cache XP thumbsize
|
||||
PRUint32 mMaxRange; // cache XP maxrange
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsSound.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsSound,nsISound::GetIID())
|
||||
|
||||
nsSound::nsSound()
|
||||
{}
|
||||
|
||||
nsSound::~nsSound()
|
||||
{}
|
||||
|
||||
nsresult nsSound::Beep()
|
||||
{
|
||||
WinAlarm( HWND_DESKTOP, WA_WARNING);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This function should NOT exist -- how do people expect to componentize
|
||||
// widget & gfx if they keep introducing static functions.
|
||||
|
||||
#if 0
|
||||
nsresult NS_NewSound( nsISound** aSound)
|
||||
{
|
||||
if( !aSound)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsSound *pSound = new nsSound;
|
||||
return pSound->QueryInterface( nsISound::GetIID(), (void**) aSound);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nssound_h
|
||||
#define _nssound_h
|
||||
|
||||
#include "nsISound.h"
|
||||
|
||||
// This is rather lame!
|
||||
|
||||
class nsSound : public nsISound
|
||||
{
|
||||
public:
|
||||
nsSound();
|
||||
virtual ~nsSound();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Beep();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
// C++ interface
|
||||
#include "nsTabWidget.h"
|
||||
|
||||
// C interface
|
||||
#include "tabapi.h" // !! TAB-FIX
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// XP-com
|
||||
NS_IMPL_ADDREF(nsTabWidget)
|
||||
NS_IMPL_RELEASE(nsTabWidget)
|
||||
|
||||
nsresult nsTabWidget::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
nsresult result = nsWindow::QueryInterface( aIID, aInstancePtr);
|
||||
|
||||
if( result == NS_NOINTERFACE && aIID.Equals( nsITabWidget::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsITabWidget*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// tab methods
|
||||
nsresult nsTabWidget::SetTabs( PRUint32 aNumberOfTabs,
|
||||
const nsString aTabLabels[])
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
if( mToolkit && mWnd)
|
||||
{
|
||||
// first remove current tabs...
|
||||
// !! oops, can't do this yet :-) // !! TAB-FIX
|
||||
// mOS2Toolkit->SendMsg( mWnd, TABM_REMOVEALLTABS);
|
||||
|
||||
PRUint32 i;
|
||||
char **strings = new char * [aNumberOfTabs];
|
||||
|
||||
for( i = 0; i < aNumberOfTabs; i++)
|
||||
strings[i] = strdup( gModuleData.ConvertFromUcs( aTabLabels[i]));
|
||||
|
||||
BOOL bOk = (BOOL) mOS2Toolkit->SendMsg( mWnd, TABM_INSERTMULTTABS,
|
||||
MPFROMSHORT(aNumberOfTabs),
|
||||
MPFROMP(strings));
|
||||
for( i = 0; i < aNumberOfTabs; i++)
|
||||
free( strings[i]);
|
||||
delete [] strings;
|
||||
|
||||
if( bOk)
|
||||
rc = NS_OK;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsresult nsTabWidget::GetSelectedTab( PRUint32 &aTab)
|
||||
{
|
||||
nsresult rc = NS_ERROR_FAILURE;
|
||||
|
||||
if( mWnd && mToolkit)
|
||||
{
|
||||
MRESULT mrc = mOS2Toolkit->SendMsg( mWnd, TABM_QUERYHILITTAB);
|
||||
aTab = SHORT1FROMMR( mrc);
|
||||
if( aTab != TABC_FAILURE)
|
||||
rc = NS_OK;
|
||||
aTab--; // !! TAB-INDEX
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Generate mozilla events when appropriate...
|
||||
PRBool nsTabWidget::OnControl( MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
switch( SHORT2FROMMP(mp1))
|
||||
{
|
||||
case TTN_TABCHANGE:
|
||||
DispatchStandardEvent( NS_TABCHANGE);
|
||||
break;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Creation hooks...
|
||||
PCSZ nsTabWidget::WindowClass()
|
||||
{
|
||||
return (PCSZ) TabGetTabControlName();
|
||||
}
|
||||
|
||||
ULONG nsTabWidget::WindowStyle()
|
||||
{
|
||||
return BASE_CONTROL_STYLE;
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsTextArea.h"
|
||||
|
||||
NS_IMPL_ADDREF(nsTextArea)
|
||||
NS_IMPL_RELEASE(nsTextArea)
|
||||
nsresult nsTextArea::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
nsresult result = nsWindow::QueryInterface( aIID, aInstancePtr);
|
||||
|
||||
if( result == NS_NOINTERFACE && aIID.Equals( nsITextAreaWidget::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsITextAreaWidget*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// MLE notes: in Warp 4 (and I guess Warp3 fp 28-ish) MLE's *do* respond
|
||||
// correctly to colour-changes via presparams.
|
||||
//
|
||||
// Should really add code to deal with text lengths > 64k.
|
||||
//
|
||||
// No DBCS support.
|
||||
//
|
||||
// Format is currently left as MLFIE_CFTEXT; need to wait & see what it
|
||||
// should be. MLFIE_WINFMT could well be the right thing to do; set this
|
||||
// using the PostCreateWidget() hook.
|
||||
//
|
||||
// May also need strategic MLM_DISABLEREFRESH
|
||||
|
||||
nsresult nsTextArea::GetText( nsString &aTextBuffer, PRUint32 aBufferSize, PRUint32 &len)
|
||||
{
|
||||
if( mToolkit != nsnull)
|
||||
{
|
||||
IPT clength = (IPT) mOS2Toolkit->SendMsg( mWnd, MLM_QUERYTEXTLENGTH);
|
||||
// now get bytes
|
||||
long length = (long) mOS2Toolkit->SendMsg( mWnd, MLM_QUERYFORMATTEXTLENGTH,
|
||||
0, MPFROMLONG(length));
|
||||
// ..buffer..
|
||||
NS_ALLOC_CHAR_BUF(buf,256,length+1)
|
||||
|
||||
mOS2Toolkit->SendMsg( mWnd, MLM_SETIMPORTEXPORT,
|
||||
MPFROMP(buf), MPFROMLONG(length+1));
|
||||
IPT start = 0;
|
||||
mOS2Toolkit->SendMsg( mWnd, MLM_EXPORT, MPFROMP(&start), MPFROMP(&length));
|
||||
|
||||
aTextBuffer.SetLength(0);
|
||||
aTextBuffer.Append(buf);
|
||||
|
||||
NS_FREE_CHAR_BUF(buf)
|
||||
|
||||
len = clength;
|
||||
}
|
||||
else
|
||||
{
|
||||
aTextBuffer = mText;
|
||||
len = aTextBuffer.Length();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::SetText( const nsString &aText, PRUint32 &len)
|
||||
{
|
||||
if( mOS2Toolkit != nsnull)
|
||||
{
|
||||
RemoveText();
|
||||
|
||||
NS_ALLOC_STR_BUF(buf,aText,512)
|
||||
|
||||
mOS2Toolkit->SendMsg( mWnd, MLM_SETIMPORTEXPORT,
|
||||
MPFROMP(buf), MPFROMLONG(aText.Length() + 1));
|
||||
IPT ipt = 0;
|
||||
mOS2Toolkit->SendMsg( mWnd, MLM_IMPORT,
|
||||
MPFROMP(&ipt), MPFROMLONG(aText.Length()));
|
||||
|
||||
NS_FREE_STR_BUF(buf)
|
||||
}
|
||||
|
||||
len = aText.Length();
|
||||
mText = aText;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::InsertText( const nsString &aText, PRUint32 aStartPos, PRUint32 aEndPos, PRUint32 &len)
|
||||
{
|
||||
PRUint32 dummy;
|
||||
nsString currentText;
|
||||
GetText( currentText, 256, dummy);
|
||||
nsString newText( aText);
|
||||
currentText.Insert( newText, aStartPos, aText.Length());
|
||||
SetText( currentText, dummy);
|
||||
len = aText.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::RemoveText()
|
||||
{
|
||||
if( mOS2Toolkit != nsnull)
|
||||
{
|
||||
IPT length = (IPT) mOS2Toolkit->SendMsg( mWnd, MLM_QUERYTEXTLENGTH);
|
||||
mOS2Toolkit->SendMsg( mWnd, MLM_DELETE, MPFROMLONG(0), MPFROMLONG(length));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::SetPassword( PRBool aIsPassword)
|
||||
{
|
||||
// no...
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::SetMaxTextLength( PRUint32 aChars)
|
||||
{
|
||||
if( mToolkit != nsnull)
|
||||
{
|
||||
long lSize = aChars ? (long)aChars : -1;
|
||||
mOS2Toolkit->SendMsg( mWnd, MLM_SETTEXTLIMIT, MPFROMLONG(lSize));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::SetReadOnly( PRBool aReadOnlyFlag, PRBool &bOld)
|
||||
{
|
||||
BOOL bOldState;
|
||||
if( mWnd)
|
||||
{
|
||||
bOldState = (BOOL) mOS2Toolkit->SendMsg( mWnd, MLM_QUERYREADONLY);
|
||||
mOS2Toolkit->SendMsg( mWnd, MLM_SETREADONLY, MPFROMSHORT(aReadOnlyFlag));
|
||||
}
|
||||
else
|
||||
{
|
||||
bOldState = mStyle & MLS_READONLY;
|
||||
if( aReadOnlyFlag)
|
||||
mStyle |= MLS_READONLY;
|
||||
else
|
||||
mStyle &= ~MLS_READONLY;
|
||||
}
|
||||
bOld = bOldState ? PR_TRUE : PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::SelectAll()
|
||||
{
|
||||
if( mToolkit != nsnull)
|
||||
{
|
||||
IPT length = (IPT) mOS2Toolkit->SendMsg( mWnd, MLM_QUERYTEXTLENGTH);
|
||||
SetSelection( 0, length);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::SetSelection( PRUint32 aStartSel, PRUint32 aEndSel)
|
||||
{
|
||||
if( mToolkit != nsnull)
|
||||
mOS2Toolkit->SendMsg( mWnd, MLM_SETSEL,
|
||||
MPFROMLONG(aStartSel), MPFROMLONG(aEndSel));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::GetSelection( PRUint32 *aStartSel, PRUint32 *aEndSel)
|
||||
{
|
||||
if( mToolkit != nsnull)
|
||||
{
|
||||
MRESULT rc = mOS2Toolkit->SendMsg( mWnd, MLM_QUERYSEL,
|
||||
MPFROMLONG(MLFQS_MINMAXSEL));
|
||||
if( aStartSel)
|
||||
*aStartSel = SHORT1FROMMR(rc);
|
||||
if( aEndSel)
|
||||
*aEndSel = SHORT2FROMMR(rc);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::SetCaretPosition( PRUint32 aPosition)
|
||||
{
|
||||
if( mToolkit != nsnull)
|
||||
mOS2Toolkit->SendMsg( mWnd, MLM_SETSEL,
|
||||
MPFROMLONG(aPosition), MPFROMLONG(aPosition));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::GetCaretPosition( PRUint32 &ret)
|
||||
{
|
||||
if( mToolkit != nsnull)
|
||||
{
|
||||
MRESULT rc = mOS2Toolkit->SendMsg( mWnd, MLM_QUERYSEL,
|
||||
MPFROMLONG(MLFQS_CURSORSEL));
|
||||
ret = (PRUint32) rc;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// platform hooks
|
||||
PCSZ nsTextArea::WindowClass()
|
||||
{
|
||||
return WC_MLE;
|
||||
}
|
||||
|
||||
ULONG nsTextArea::WindowStyle()
|
||||
{ // no wordwrap, intentional; should be in interface...
|
||||
return mStyle | MLS_BORDER | MLS_HSCROLL | MLS_VSCROLL | BASE_CONTROL_STYLE;
|
||||
}
|
||||
|
||||
nsresult nsTextArea::PreCreateWidget( nsWidgetInitData *aInitData)
|
||||
{
|
||||
if( nsnull != aInitData)
|
||||
{
|
||||
nsTextWidgetInitData *data = (nsTextWidgetInitData *) aInitData;
|
||||
if( data->mIsReadOnly)
|
||||
mStyle |= MLS_READONLY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsToolkit.h"
|
||||
|
||||
#include "nsIAppShell.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
// 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,
|
||||
nsIAppShell::GetIID(),
|
||||
(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, nsIToolkit::GetIID())
|
||||
|
||||
static MRESULT EXPENTRY fnwpDispatch( HWND, ULONG, MPARAM, MPARAM);
|
||||
#define UWC_DISPATCH "DispatchWndClass"
|
||||
|
||||
// Create the internal window - also sets the pm thread 'formally'
|
||||
void nsToolkit::CreateInternalWindow( PRThread *aThread)
|
||||
{
|
||||
NS_PRECONDITION(aThread, "null thread");
|
||||
mPMThread = aThread;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
// 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)
|
||||
{}
|
||||
};
|
||||
|
||||
nsresult nsToolkit::CallMethod( MethodInfo *pInfo)
|
||||
{
|
||||
PR_EnterMonitor( mMonitor);
|
||||
|
||||
RealMethodInfo rminfo( pInfo, mMonitor);
|
||||
|
||||
// post the message to the window
|
||||
WinPostMsg( mDispatchWnd, WMU_CALLMETHOD, MPFROMP(&rminfo), 0);
|
||||
|
||||
// wait for it to complete...
|
||||
PR_Wait( mMonitor, PR_INTERVAL_NO_TIMEOUT);
|
||||
PR_ExitMonitor( mMonitor);
|
||||
|
||||
// cleanup & return
|
||||
return rminfo.rc;
|
||||
}
|
||||
|
||||
struct SendMsgStruct
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
MRESULT EXPENTRY fnwpDispatch( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
MRESULT mRC = 0;
|
||||
|
||||
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);
|
||||
|
||||
return mRC;
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _toolkit_h
|
||||
#define _toolkit_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;
|
||||
|
||||
class nsToolkit : public nsIToolkit
|
||||
{
|
||||
public:
|
||||
nsToolkit();
|
||||
virtual ~nsToolkit();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init( PRThread *aThread);
|
||||
|
||||
nsresult CallMethod( MethodInfo *info);
|
||||
MRESULT SendMsg( HWND hwnd, ULONG msg, MPARAM mp1 = 0, MPARAM mp2 = 0);
|
||||
|
||||
// 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; }
|
||||
|
||||
void CreateInternalWindow( PRThread *aThread);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
// Interface to derive things from
|
||||
class nsSwitchToPMThread
|
||||
{
|
||||
public:
|
||||
// No return code: if this is a problem then
|
||||
virtual nsresult CallMethod( MethodInfo *info) = 0;
|
||||
};
|
||||
|
||||
// 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
|
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsTooltipManager.h"
|
||||
#include "nswindow.h"
|
||||
|
||||
// Created 25-9-98 mjf, improvising furiously...
|
||||
|
||||
// --> Bank on TTData->cRcls being smallish.
|
||||
//
|
||||
// This is probably a bad bet, seeing as the main use will be on a child
|
||||
// window rendering content with many separate areas of interest (eg. 1
|
||||
// per image with alt text).
|
||||
//
|
||||
// So it may turn out to be a good idea to make this data structure more
|
||||
// sophisticated -- hash on the coordinates.
|
||||
|
||||
// Hashtable defs; key is HWND, element is TTData*
|
||||
class HWNDHashKey : public nsHashKey
|
||||
{
|
||||
HWND hwnd;
|
||||
|
||||
public:
|
||||
HWNDHashKey( HWND h) : hwnd(h) {}
|
||||
|
||||
virtual PRUint32 HashValue() const { return hwnd; }
|
||||
virtual PRBool Equals( const nsHashKey *aKey) const
|
||||
{ return (((HWNDHashKey*)aKey)->hwnd == hwnd) ? PR_TRUE : PR_FALSE; }
|
||||
virtual nsHashKey *Clone() const
|
||||
{ return new HWNDHashKey( hwnd); }
|
||||
};
|
||||
|
||||
#define ID_TT_TIMER (TID_USERMAX-1)
|
||||
|
||||
struct TTData
|
||||
{
|
||||
HWND hwnd;
|
||||
RECTL *aRcls; // could use a region to hold rects, but need to know
|
||||
ULONG cRcls; // index of rectangle for notifications.
|
||||
// [see large comment above]
|
||||
|
||||
|
||||
LONG lIndex; // Index of last rectangle hit. -1 is none.
|
||||
LONG lIndexShowing;
|
||||
PFNWP oldFnWp;
|
||||
BOOL bTimerSet;
|
||||
POINTL ptStart;
|
||||
|
||||
TTData( HWND h) : hwnd(h), aRcls(0), cRcls(0), lIndex(-1),
|
||||
lIndexShowing(-1), oldFnWp(0), bTimerSet(0)
|
||||
{ ptStart.x = 0; ptStart.y = 0; }
|
||||
|
||||
~TTData()
|
||||
{ delete [] aRcls; }
|
||||
|
||||
// if cRects is 0, same number as we already have.
|
||||
void UpdateTooltips( nsWindow *w, nsRect *rects[], PRUint32 cRects = 0)
|
||||
{
|
||||
if( cRects > 0)
|
||||
{
|
||||
delete [] aRcls;
|
||||
aRcls = new RECTL [cRects];
|
||||
cRcls = cRects;
|
||||
}
|
||||
|
||||
// Get bounds once..
|
||||
nsRect bounds;
|
||||
w->GetBounds( bounds);
|
||||
|
||||
for( ULONG i = 0; i < cRects; i++)
|
||||
{
|
||||
// convert the ith nsrect to the ith in-ex rectl
|
||||
aRcls[i].yTop = bounds.height - rects[i]->y;
|
||||
aRcls[i].xLeft = rects[i]->x;
|
||||
aRcls[i].xRight = aRcls[i].xLeft + rects[i]->width;
|
||||
aRcls[i].yBottom = aRcls[i].yTop - rects[i]->height;
|
||||
}
|
||||
}
|
||||
|
||||
void StopTimer()
|
||||
{
|
||||
if( bTimerSet)
|
||||
{
|
||||
WinStopTimer( 0/*hab*/, hwnd, ID_TT_TIMER);
|
||||
bTimerSet = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void StartTimer()
|
||||
{
|
||||
if( !bTimerSet)
|
||||
{
|
||||
WinStartTimer( 0/*hab*/, hwnd, ID_TT_TIMER, 1000); // 1 second?
|
||||
bTimerSet = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
long Test( PPOINTL pt)
|
||||
{
|
||||
lIndex = -1;
|
||||
for( ULONG i = 0; lIndex == -1 && i < cRcls; i++)
|
||||
if( WinPtInRect( 0/*hab*/, aRcls + i, pt))
|
||||
lIndex = i;
|
||||
return lIndex;
|
||||
}
|
||||
|
||||
void ShowTooltip()
|
||||
{
|
||||
NS_ASSERTION( lIndex >= 0, "Invalid tt index");
|
||||
if( lIndex != lIndexShowing)
|
||||
{
|
||||
WinSendMsg( hwnd, WMU_SHOW_TOOLTIP, MPFROMLONG(lIndex), 0);
|
||||
lIndexShowing = lIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void HideTooltip()
|
||||
{
|
||||
if( lIndexShowing != -1)
|
||||
{
|
||||
WinSendMsg( hwnd, WMU_HIDE_TOOLTIP, 0, 0);
|
||||
lIndexShowing = -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// subclass to watch for mouse messages
|
||||
MRESULT EXPENTRY HandleMsg( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
return nsTooltipManager::GetManager()->HandleMsg( hwnd, msg, mp1, mp2);
|
||||
}
|
||||
|
||||
#define HOVER_DIST_SQR 100
|
||||
|
||||
// Message handler ---------------------------------------------------------
|
||||
MRESULT nsTooltipManager::HandleMsg( HWND hwnd, ULONG msg,
|
||||
MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
MRESULT mRC = 0;
|
||||
|
||||
// find data area
|
||||
TTData *pData = GetEntry( hwnd);
|
||||
|
||||
if( pData)
|
||||
{
|
||||
BOOL bSet = FALSE;
|
||||
|
||||
switch( msg)
|
||||
{
|
||||
case WMU_MOUSEENTER:
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
// Is point in rectl list?
|
||||
// Yes: Is tooltip mode on?
|
||||
// Yes: Show tooltip
|
||||
// No: Is timer set?
|
||||
// Yes: Is point < HOVER_DIST from startpoint ?
|
||||
// Yes: run away
|
||||
// No: Stop timer
|
||||
// No: nop
|
||||
// Record startpoint
|
||||
// Start timer
|
||||
// No: No tooltip here: Stop timer, run away
|
||||
pData->StopTimer();
|
||||
POINTL pt = { SHORT1FROMMP(mp1), SHORT2FROMMP(mp1) };
|
||||
if( pData->Test( &pt) >= 0)
|
||||
{
|
||||
if( mTTMode == PR_TRUE)
|
||||
{
|
||||
pData->ShowTooltip();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pData->bTimerSet)
|
||||
{
|
||||
// ..approx..
|
||||
long lX = pt.x - pData->ptStart.x;
|
||||
long lY = pt.y - pData->ptStart.y;
|
||||
|
||||
if( lX * lX + lY * lY < HOVER_DIST_SQR)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->StopTimer();
|
||||
}
|
||||
}
|
||||
memcpy( &pData->ptStart, &pt, sizeof pt);
|
||||
pData->StartTimer();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->StopTimer();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_TIMER:
|
||||
// Is it our timer?
|
||||
// Yes: Set tooltip mode; cancel timer; show tooltip
|
||||
// No: Run away
|
||||
if( SHORT1FROMMP( mp1) == ID_TT_TIMER)
|
||||
{
|
||||
mTTMode = PR_TRUE;
|
||||
pData->StopTimer();
|
||||
pData->ShowTooltip();
|
||||
bSet = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WMU_MOUSELEAVE:
|
||||
// Is tooltip mode on?
|
||||
// Yes: hide tooltip; Is next window one of ours?
|
||||
// Yes: do nothing
|
||||
// No: unset tooltip mode
|
||||
// No: stop timer
|
||||
if( mTTMode)
|
||||
{
|
||||
pData->HideTooltip();
|
||||
if( 0 == GetEntry( HWNDFROMMP(mp2)))
|
||||
{
|
||||
mTTMode = PR_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->StopTimer();
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_BUTTON1DOWN:
|
||||
case WM_BUTTON2DOWN:
|
||||
case WM_BUTTON3DOWN:
|
||||
// Is tooltip mode on?
|
||||
// Yes: hide tooltip; unset tooltip mode
|
||||
// No: Stop timer
|
||||
if( mTTMode)
|
||||
{
|
||||
pData->HideTooltip();
|
||||
mTTMode = PR_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->StopTimer();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( !bSet && pData->oldFnWp)
|
||||
mRC = (*pData->oldFnWp)( hwnd, msg, mp1, mp2);
|
||||
}
|
||||
else // ..oops..
|
||||
mRC = WinDefWindowProc( hwnd, msg, mp1, mp2);
|
||||
return mRC;
|
||||
}
|
||||
|
||||
// Manager methods ---------------------------------------------------------
|
||||
TTData *nsTooltipManager::GetEntry( nsWindow *w)
|
||||
{
|
||||
HWND hwnd = (HWND) w->GetNativeData( NS_NATIVE_WINDOW);
|
||||
return GetEntry( hwnd);
|
||||
}
|
||||
|
||||
TTData *nsTooltipManager::GetEntry( HWND hwnd)
|
||||
{
|
||||
HWNDHashKey key( hwnd);
|
||||
return (TTData*) mManaged.Get( &key);
|
||||
}
|
||||
|
||||
void nsTooltipManager::SetTooltips( nsWindow *window,
|
||||
PRUint32 cTips, nsRect *rects[])
|
||||
{
|
||||
TTData *pData = GetEntry( window);
|
||||
|
||||
if( !pData)
|
||||
{
|
||||
HWND hwnd = (HWND) window->GetNativeData( NS_NATIVE_WINDOW);
|
||||
pData = new TTData( hwnd);
|
||||
pData->oldFnWp = WinSubclassWindow( hwnd, ::HandleMsg);
|
||||
HWNDHashKey key(hwnd);
|
||||
mManaged.Put( &key, pData);
|
||||
mElements++;
|
||||
}
|
||||
pData->UpdateTooltips( window, rects, cTips);
|
||||
}
|
||||
|
||||
void nsTooltipManager::UpdateTooltips( nsWindow *window, nsRect *rects[])
|
||||
{
|
||||
TTData *pData = GetEntry( window);
|
||||
|
||||
NS_ASSERTION( pData, "Update tt for bad window");
|
||||
|
||||
pData->UpdateTooltips( window, rects);
|
||||
}
|
||||
|
||||
void nsTooltipManager::RemoveTooltips( nsWindow *window)
|
||||
{
|
||||
HWND hwnd = (HWND) window->GetNativeData( NS_NATIVE_WINDOW);
|
||||
|
||||
HWNDHashKey key( hwnd);
|
||||
TTData *pData = (TTData*) mManaged.Remove( &key);
|
||||
|
||||
if( pData)
|
||||
{
|
||||
pData->StopTimer(); // just for safety
|
||||
WinSubclassWindow( hwnd, pData->oldFnWp);
|
||||
|
||||
delete pData;
|
||||
mElements--;
|
||||
}
|
||||
|
||||
if( 0 == mElements) // no clients, go away
|
||||
{
|
||||
delete this;
|
||||
nsTooltipManager::sMgr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Ctor/dtor stuff ---------------------------------------------------------
|
||||
nsTooltipManager::nsTooltipManager() : mElements(0), mTTMode( PR_FALSE)
|
||||
{}
|
||||
|
||||
PRBool emptyHashtableFunc( nsHashKey *aKey, void *aData, void *pClosure)
|
||||
{
|
||||
delete (TTData*) aData;
|
||||
return PR_TRUE; // keep going
|
||||
}
|
||||
|
||||
nsTooltipManager::~nsTooltipManager()
|
||||
{
|
||||
// shouldn't be any elements...
|
||||
// NS_ASSERTION( mElements == 0, "Non-deregistered tts");
|
||||
mManaged.Enumerate( emptyHashtableFunc);
|
||||
}
|
||||
|
||||
nsTooltipManager *nsTooltipManager::GetManager()
|
||||
{
|
||||
if( !sMgr)
|
||||
sMgr = new nsTooltipManager;
|
||||
|
||||
return sMgr;
|
||||
}
|
||||
|
||||
nsTooltipManager *nsTooltipManager::sMgr;
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsTooltipWidget.h"
|
||||
|
||||
// Tooltip class; just a custom canvas-like class to put things on.
|
||||
|
||||
NS_IMPL_ADDREF(nsTooltipWidget)
|
||||
NS_IMPL_RELEASE(nsTooltipWidget)
|
||||
|
||||
nsresult nsTooltipWidget::QueryInterface( const nsIID &aIID, void **aInstancePtr)
|
||||
{
|
||||
nsresult result = nsWindow::QueryInterface(aIID, aInstancePtr);
|
||||
|
||||
if( result == NS_NOINTERFACE && aIID.Equals( nsITooltipWidget::GetIID()))
|
||||
{
|
||||
*aInstancePtr = (void*) ((nsITooltipWidget*)this);
|
||||
NS_ADDREF_THIS();
|
||||
result = NS_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL bRegistered;
|
||||
#define NSTOOLTIPCLASS (PCSZ)"WarpzillaTooltip"
|
||||
|
||||
PCSZ nsTooltipWidget::WindowClass()
|
||||
{
|
||||
if( !bRegistered)
|
||||
{
|
||||
BOOL rc = WinRegisterClass( 0 /*hab*/, NSTOOLTIPCLASS,
|
||||
WinDefWindowProc, 0, 4);
|
||||
NS_ASSERTION( rc, "Couldn't register tooltip class");
|
||||
bRegistered = TRUE;
|
||||
}
|
||||
|
||||
return NSTOOLTIPCLASS;
|
||||
}
|
||||
|
||||
ULONG nsTooltipWidget::WindowStyle()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// background for tooltips
|
||||
#define MK_RGB(r,g,b) ((r) * 65536) + ((g) * 256) + (b)
|
||||
|
||||
|
||||
PRBool nsTooltipWidget::OnPaint()
|
||||
{
|
||||
// Draw tooltip - black border, off-white interior
|
||||
RECTL rcl;
|
||||
HPS hps = WinBeginPaint( mWnd, 0, &rcl);
|
||||
WinQueryWindowRect( mWnd, &rcl);
|
||||
GpiCreateLogColorTable( hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, 0);
|
||||
long lColor = 0; // black
|
||||
GpiSetAttrs( hps, PRIM_LINE, LBB_COLOR, 0, &lColor);
|
||||
lColor = MK_RGB(255,255,185); // off-white
|
||||
GpiSetAttrs( hps, PRIM_AREA, ABB_COLOR, 0, &lColor);
|
||||
rcl.yTop--;
|
||||
rcl.xRight--;
|
||||
PPOINTL pts = (PPOINTL) &rcl;
|
||||
GpiMove( hps, pts);
|
||||
GpiBox( hps, DRO_OUTLINEFILL, pts + 1, 0, 0);
|
||||
WinEndPaint( hps);
|
||||
return PR_TRUE;
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nswidgetdefs_h
|
||||
#define _nswidgetdefs_h
|
||||
|
||||
// OS/2 defines; for user messages & warp4 stuff, plus module-global data
|
||||
|
||||
#include "nsIWidget.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
#define INCL_PM
|
||||
#define INCL_NLS
|
||||
#define INCL_DOS
|
||||
#include <os2.h>
|
||||
#include <uconv.h> // Rather not have to include these two, but need types...
|
||||
#include <unikbd.h> //
|
||||
|
||||
#define SUPPORT_NON_XPFE /* support for viewer.exe */
|
||||
|
||||
class nsIFontRetrieverService;
|
||||
class nsDragService;
|
||||
class nsIAppShell;
|
||||
|
||||
// Module data -- anything that would be static, should be module-visible,
|
||||
// or any magic constants.
|
||||
class nsWidgetModuleData
|
||||
{
|
||||
public:
|
||||
HMODULE hModResources; // resource module
|
||||
SIZEL szScreen; // size of screen in pixels
|
||||
BOOL bMouseSwitched; // true if MB1 is the RH mouse button
|
||||
LONG lHtEntryfield; // ideal height of an entryfield
|
||||
char *pszFontNameSize; // fns for default widget font
|
||||
BOOL bIsDBCS; // true if system is dbcs
|
||||
ULONG ppMozilla; // pres-param for hwnd <-> nsWindow*
|
||||
|
||||
// xptoolkit services we look after, & the primaeval appshell too.
|
||||
nsIFontRetrieverService *fontService;
|
||||
nsDragService *dragService;
|
||||
nsIAppShell *appshell;
|
||||
|
||||
// We're caching resource-loaded things here too. This may be
|
||||
// better-suited elsewhere, but there shouldn't be very many of them.
|
||||
HPOINTER GetPointer( nsCursor aCursor);
|
||||
HPOINTER GetFrameIcon();
|
||||
|
||||
// Unicode->local cp. conversions
|
||||
char *ConvertFromUcs( const PRUnichar *pText, char *szBuffer, ULONG ulSize);
|
||||
char *ConvertFromUcs( const nsString &aStr, char *szBuffer, ULONG ulSize);
|
||||
// these methods use a single static buffer
|
||||
const char *ConvertFromUcs( const PRUnichar *pText);
|
||||
const char *ConvertFromUcs( const nsString &aStr);
|
||||
|
||||
// Unicode keyboard utility stuff
|
||||
KHAND hKeyboard;
|
||||
int TranslateKey( VSCAN scan, UniChar *aChar, VDKEY *vdkey);
|
||||
|
||||
// Atom service; clients don't need to bother about freeing them.
|
||||
ATOM GetAtom( const char *atomname);
|
||||
ATOM GetAtom( const nsString &atomname);
|
||||
|
||||
#if 0
|
||||
HWND GetWindowForPrinting( PCSZ pszClass, ULONG ulStyle);
|
||||
#endif
|
||||
|
||||
nsWidgetModuleData();
|
||||
~nsWidgetModuleData();
|
||||
|
||||
void Init( nsIAppShell *aPrimaevalAppShell);
|
||||
|
||||
private:
|
||||
HPOINTER hptrSelect; // !! be more sensible about this...
|
||||
HPOINTER hptrFrameIcon;
|
||||
#if 0
|
||||
nsHashtable *mWindows;
|
||||
#endif
|
||||
|
||||
UconvObject converter;
|
||||
BOOL supplantConverter;
|
||||
|
||||
nsVoidArray atoms;
|
||||
};
|
||||
|
||||
extern nsWidgetModuleData gModuleData;
|
||||
|
||||
// messages - here to avoid duplication
|
||||
#define WMU_CALLMETHOD (WM_USER + 1)
|
||||
#define WMU_SENDMSG (WM_USER + 2)
|
||||
|
||||
// MP1 is "LONG lIndex", MP2 is reserved
|
||||
#define WMU_SHOW_TOOLTIP (WM_USER + 3)
|
||||
|
||||
// MP1 & MP2 both reserved
|
||||
#define WMU_HIDE_TOOLTIP (WM_USER + 4)
|
||||
|
||||
// DRM_MOZILLA messages
|
||||
|
||||
// WMU_GETFLAVOURLEN
|
||||
//
|
||||
// mp1 - ULONG ulItemID Item ID from DRAGITEM
|
||||
// mp2 - HATOM hAtomFlavour Atom in the system table for the data flavour
|
||||
//
|
||||
// returns - ULONG ulSize Size in bytes of transfer data, 0 for error
|
||||
//
|
||||
#define WMU_GETFLAVOURLEN (WM_USER + 5)
|
||||
|
||||
typedef struct _WZDROPXFER
|
||||
{
|
||||
ATOM hAtomFlavour;
|
||||
CHAR data[1];
|
||||
} WZDROPXFER, *PWZDROPXFER;
|
||||
|
||||
// WMU_GETFLAVOURDATA
|
||||
//
|
||||
// mp1 - ULONG ulItemID Item ID from DRAGITEM
|
||||
// mp2 - PWZDROPXFER pvData Pointer to buffer to put data.
|
||||
// Must DosFreeMem().
|
||||
//
|
||||
// returns - BOOL bSuccess TRUE ok, FALSE error occurred.
|
||||
|
||||
#define WMU_GETFLAVOURDATA (WM_USER + 6)
|
||||
|
||||
#define WinIsKeyDown(vk) ((WinGetKeyState(HWND_DESKTOP,vk) & 0x8000) ? PR_TRUE : PR_FALSE)
|
||||
|
||||
// Tab control uses messages from TABM_BASE, which is currently (WM_USER+50).
|
||||
// See tabapi.h for details.
|
||||
|
||||
// WMU'd to avoid potential clash with offical names.
|
||||
// MP2 is the other window.
|
||||
#define WMU_MOUSEENTER 0x041e
|
||||
#define WMU_MOUSELEAVE 0x041f
|
||||
|
||||
#ifndef FCF_CLOSEBUTTON // defined in the Merlin toolkit
|
||||
#define FCF_CLOSEBUTTON 0x04000000L
|
||||
#endif
|
||||
|
||||
#ifndef DRT_URL
|
||||
#define DRT_URL "UniformResourceLocator"
|
||||
#endif
|
||||
|
||||
#define BASE_CONTROL_STYLE WS_TABSTOP
|
||||
|
||||
#define NS_MIT_END ((const PRUint32) MIT_END)
|
||||
|
||||
// A common pattern in widget is the 'Get/SetLabel' methods. These macros
|
||||
// can be used to fill in implementations who derive from nsWindow and just
|
||||
// want to call WinSet/QueryWindowText.
|
||||
|
||||
#define NS_DECL_LABEL \
|
||||
NS_IMETHOD SetLabel( const nsString &aText); \
|
||||
NS_IMETHOD GetLabel( nsString &aBuffer);
|
||||
|
||||
#define NS_IMPL_LABEL(_clsname) \
|
||||
nsresult _clsname::SetLabel( const nsString &aText) \
|
||||
{ \
|
||||
SetTitle( aText); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
\
|
||||
nsresult _clsname::GetLabel( nsString &aBuffer) \
|
||||
{ \
|
||||
PRUint32 dummy; \
|
||||
GetWindowText( aBuffer, &dummy); \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
// can be used as an lvalue too.
|
||||
#define lastchar(s) *((s) + strlen((s)) - 1)
|
||||
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
* 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 the Mozilla OS/2 libraries.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _nswindow_h
|
||||
#define _nswindow_h
|
||||
|
||||
#include "nsWidgetDefs.h"
|
||||
#include "nsBaseWidget.h"
|
||||
#include "nsToolkit.h"
|
||||
|
||||
class nsIMenuBar;
|
||||
class nsContextMenu;
|
||||
|
||||
// Base widget class.
|
||||
// This is abstract. Controls (labels, radio buttons, listboxen) derive
|
||||
// from here. A thing called a child window derives from here, and the
|
||||
// frame window class derives from the child. The content-displaying
|
||||
// classes are off on their own branch to avoid creating a palette for
|
||||
// every window we create. This may turn out to be what's required, in
|
||||
// which case the paint & palette code from nsChildWindow needs to be
|
||||
// munged in here. nsFrameWindow is separate because work needs to be done
|
||||
// there to decide whether methods apply to frame or client.
|
||||
|
||||
class nsWindow : public nsBaseWidget,
|
||||
public nsSwitchToPMThread
|
||||
{
|
||||
public:
|
||||
// Scaffolding
|
||||
nsWindow();
|
||||
virtual ~nsWindow();
|
||||
|
||||
// nsIWidget
|
||||
|
||||
// Creation from native (eh?) or widget parent, destroy
|
||||
NS_IMETHOD Create( nsIWidget *aParent,
|
||||
const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext,
|
||||
nsIAppShell *aAppShell = nsnull,
|
||||
nsIToolkit *aToolkit = nsnull,
|
||||
nsWidgetInitData *aInitData = nsnull);
|
||||
NS_IMETHOD Create( nsNativeWidget aParent,
|
||||
const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext,
|
||||
nsIAppShell *aAppShell = nsnull,
|
||||
nsIToolkit *aToolkit = nsnull,
|
||||
nsWidgetInitData *aInitData = nsnull);
|
||||
NS_IMETHOD Destroy(); // call before releasing
|
||||
|
||||
// Hierarchy: only interested in widget children (it seems)
|
||||
virtual nsIWidget *GetParent();
|
||||
|
||||
// Strangely misplaced menubar methods
|
||||
NS_IMETHOD SetMenuBar( nsIMenuBar *aMenuBar);
|
||||
NS_IMETHOD ShowMenuBar( PRBool bShow);
|
||||
NS_IMETHOD IsMenuBarVisible( PRBool *aVisible);
|
||||
|
||||
// Physical properties
|
||||
NS_IMETHOD Show( PRBool bState);
|
||||
NS_IMETHOD Move( PRUint32 aX, PRUint32 aY);
|
||||
NS_IMETHOD Resize( PRUint32 aWidth,
|
||||
PRUint32 aHeight,
|
||||
PRBool aRepaint);
|
||||
NS_IMETHOD Resize( PRUint32 aX,
|
||||
PRUint32 aY,
|
||||
PRUint32 aWidth,
|
||||
PRUint32 aHeight,
|
||||
PRBool aRepaint);
|
||||
NS_IMETHOD GetClientBounds( nsRect &aRect);
|
||||
NS_IMETHOD GetBorderSize( PRInt32 &aWidth, PRInt32 &aHeight);
|
||||
NS_IMETHOD Enable( PRBool bState);
|
||||
NS_IMETHOD SetFocus();
|
||||
NS_IMETHOD IsVisible( PRBool &aState);
|
||||
|
||||
NS_IMETHOD GetPreferredSize( PRInt32 &aWidth, PRInt32 &aHeight);
|
||||
NS_IMETHOD SetPreferredSize( PRInt32 aWidth, PRInt32 aHeight);
|
||||
|
||||
NS_IMETHOD BeginResizingChildren();
|
||||
NS_IMETHOD EndResizingChildren();
|
||||
NS_IMETHOD WidgetToScreen( const nsRect &aOldRect, nsRect &aNewRect);
|
||||
NS_IMETHOD ScreenToWidget( const nsRect &aOldRect, nsRect &aNewRect);
|
||||
NS_IMETHOD DispatchEvent( struct nsGUIEvent *event, nsEventStatus &aStatus);
|
||||
|
||||
// Widget appearance
|
||||
virtual nscolor GetForegroundColor();
|
||||
NS_IMETHOD SetForegroundColor( const nscolor &aColor);
|
||||
virtual nscolor GetBackgroundColor();
|
||||
NS_IMETHOD SetBackgroundColor( const nscolor &aColor);
|
||||
virtual nsIFontMetrics *GetFont();
|
||||
NS_IMETHOD SetFont( const nsFont &aFont);
|
||||
NS_IMETHOD SetColorMap( nsColorMap *aColorMap);
|
||||
NS_IMETHOD SetCursor( nsCursor aCursor);
|
||||
NS_IMETHOD SetTitle( const nsString& aTitle);
|
||||
NS_IMETHOD Invalidate( PRBool aIsSynchronous);
|
||||
NS_IMETHOD Invalidate( const nsRect & aRect, PRBool aIsSynchronous);
|
||||
NS_IMETHOD Update();
|
||||
NS_IMETHOD Scroll( PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect);
|
||||
NS_IMETHOD Paint( nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
|
||||
// Tooltips
|
||||
NS_IMETHOD SetTooltips( PRUint32 aNumberOfTips, nsRect *aTooltipAreas[]);
|
||||
NS_IMETHOD RemoveTooltips();
|
||||
NS_IMETHOD UpdateTooltips( nsRect* aNewTips[]);
|
||||
|
||||
// Get a HWND or a HPS.
|
||||
virtual void *GetNativeData( PRUint32 aDataType);
|
||||
virtual void FreeNativeData( void *aDatum, PRUint32 aDataType);
|
||||
|
||||
// nsSwitchToPMThread interface
|
||||
NS_IMETHOD CallMethod( MethodInfo *info);
|
||||
|
||||
// PM methods which need to be public (menus, etc)
|
||||
ULONG GetNextID() { return mNextID++; }
|
||||
USHORT GetNextCmdID() { return mNextCmdID++; }
|
||||
void NS2PM_PARENT( POINTL &ptl);
|
||||
void NS2PM( POINTL &ptl);
|
||||
void SetContextMenu( nsContextMenu *aMenu);
|
||||
|
||||
protected:
|
||||
// nsWindow methods subclasses must provide for creation to work
|
||||
virtual PCSZ WindowClass() = 0;
|
||||
virtual ULONG WindowStyle() = 0;
|
||||
|
||||
// hooks subclasses may wish to override!
|
||||
virtual void PostCreateWidget() {}
|
||||
virtual PRInt32 GetHeight( PRInt32 aHeight) { return aHeight; }
|
||||
virtual PRInt32 GetClientHeight() { return mBounds.height; }
|
||||
virtual ULONG GetSWPFlags( ULONG flags) { return flags; }
|
||||
virtual HWND GetMainWindow() const { return mWnd; }
|
||||
virtual void SetupForPrint( HWND /*hwnd*/) {}
|
||||
|
||||
// Useful functions for subclasses to use, threaded as necessary.
|
||||
virtual nsresult GetWindowText( nsString &str, PRUint32 *rc);
|
||||
virtual void AddToStyle( ULONG style);
|
||||
virtual void RemoveFromStyle( ULONG style);
|
||||
virtual void GetStyle( ULONG &out);
|
||||
virtual nscolor QueryPresParam( ULONG ppID);
|
||||
virtual void SetPresParam( ULONG ppID, const nscolor &c);
|
||||
// return true if deferred
|
||||
virtual BOOL SetWindowPos( HWND hwndInsertBehind, long x, long y,
|
||||
long cx, long cy, unsigned long flags);
|
||||
|
||||
// Message handlers - may wish to override. Default implementation for
|
||||
// palette, control, paint & scroll is to do nothing.
|
||||
|
||||
// Return whether message has been processed.
|
||||
virtual PRBool ProcessMessage( ULONG m, MPARAM p1, MPARAM p2, MRESULT &r);
|
||||
virtual PRBool OnPaint();
|
||||
virtual void OnDestroy();
|
||||
virtual PRBool OnReposition( PSWP pNewSwp);
|
||||
virtual PRBool OnResize( PRInt32 aX, PRInt32 aY);
|
||||
virtual PRBool OnMove( PRInt32 aX, PRInt32 aY);
|
||||
virtual PRBool OnKey( MPARAM mp1, MPARAM mp2);
|
||||
virtual PRBool OnRealizePalette();
|
||||
virtual PRBool OnScroll( MPARAM mp1, MPARAM mp2);
|
||||
virtual PRBool OnControl( MPARAM mp1, MPARAM mp2);
|
||||
virtual PRBool OnMenuClick( USHORT aCmd);
|
||||
virtual PRBool OnActivateMenu( HWND aMenu, BOOL aActivate);
|
||||
// called after param has been set...
|
||||
virtual PRBool OnPresParamChanged( MPARAM mp1, MPARAM mp2);
|
||||
virtual PRBool OnDragOver( MPARAM mp1, MPARAM mp2, MRESULT &mr);
|
||||
virtual PRBool OnDragLeave( MPARAM mp1, MPARAM mp2);
|
||||
virtual PRBool OnDrop( MPARAM mp1, MPARAM mp2);
|
||||
|
||||
// PM data members
|
||||
HWND mWnd; // window handle
|
||||
PFNWP mFnWP; // previous window procedure
|
||||
nsWindow *mParent; // parent widget
|
||||
ULONG mNextID; // next child window id
|
||||
USHORT mNextCmdID; // next WM_COMMAND id for menus
|
||||
PSWP mSWPs; // SWPs for deferred window positioning
|
||||
ULONG mlHave, mlUsed; // description of mSWPs array
|
||||
HPOINTER mPointer; // current PM pointer
|
||||
HPS mPS; // cache PS for window
|
||||
ULONG mPSRefs; // number of refs to cache ps
|
||||
BOOL mDragInside; // track draginside state
|
||||
VDKEY mDeadKey; // dead key from previous keyevent
|
||||
BOOL mHaveDeadKey; // is mDeadKey valid [0 may be a valid dead key, for all I know]
|
||||
HWND mHackDestroyWnd; // access GetMainWindow() window from destructor
|
||||
|
||||
HWND GetParentHWND() const;
|
||||
HWND GetHWND() const { return mWnd; }
|
||||
PFNWP GetPrevWP() const { return mFnWP; }
|
||||
|
||||
// nglayout data members
|
||||
PRInt32 mPreferredHeight;
|
||||
PRInt32 mPreferredWidth;
|
||||
nsToolkit *mOS2Toolkit;
|
||||
nsFont *mFont;
|
||||
nsIMenuBar *mMenuBar;
|
||||
nsContextMenu *mActiveMenu; // record this so we can send it events
|
||||
|
||||
// State of the window, used to emulate windows better...
|
||||
enum nsWindowState
|
||||
{
|
||||
nsWindowState_ePrecreate, // default state; Create() not called
|
||||
nsWindowState_eInCreate, // processing Create() method
|
||||
nsWindowState_eLive, // active, existing window
|
||||
nsWindowState_eDoingDelete, // object destructor running
|
||||
nsWindowState_eDead // window destroyed
|
||||
} mWindowState;
|
||||
|
||||
// Implementation ------------------------------
|
||||
void DoCreate( HWND hwndP, nsWindow *wndP, const nsRect &rect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext, nsIAppShell *aAppShell,
|
||||
nsIToolkit *aToolkit, nsWidgetInitData *aInitData);
|
||||
|
||||
virtual void RealDoCreate( HWND hwndP, nsWindow *aParent,
|
||||
const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext,
|
||||
nsIAppShell *aAppShell,
|
||||
nsWidgetInitData *aInitData,
|
||||
HWND hwndOwner = 0);
|
||||
|
||||
virtual void SubclassWindow( PRBool bState);
|
||||
|
||||
PRBool ConvertStatus( nsEventStatus aStatus);
|
||||
void InitEvent( nsGUIEvent &event, PRUint32 aEventType, nsPoint *pt = 0);
|
||||
PRBool DispatchEventInternal( struct nsGUIEvent *event);
|
||||
PRBool DispatchStandardEvent( PRUint32 aMsg, PRUint8 aStructType = NS_GUI_EVENT);
|
||||
virtual PRBool DispatchMouseEvent( PRUint32 msg, int clickcount,
|
||||
MPARAM mp1, MPARAM mp2);
|
||||
virtual PRBool DispatchResizeEvent( PRInt32 aClientX, PRInt32 aClientY);
|
||||
void DeferPosition( HWND, HWND, long, long, long, long, ULONG);
|
||||
|
||||
// Enumeration of the methods which are accessable on the PM thread
|
||||
enum {
|
||||
W_CREATE,
|
||||
W_DESTROY,
|
||||
W_SET_FOCUS,
|
||||
W_UPDATE_WINDOW,
|
||||
W_SET_TITLE,
|
||||
W_GET_TITLE
|
||||
};
|
||||
friend MRESULT EXPENTRY fnwpNSWindow( HWND, ULONG, MPARAM, MPARAM);
|
||||
friend MRESULT EXPENTRY fnwpFrame( HWND, ULONG, MPARAM, MPARAM);
|
||||
};
|
||||
|
||||
#define PM2NS_PARENT NS2PM_PARENT
|
||||
#define PM2NS NS2PM
|
||||
|
||||
extern PRUint32 WMChar2KeyCode( MPARAM mp1, MPARAM mp2);
|
||||
|
||||
extern nsWindow *NS_HWNDToWindow( HWND hwnd);
|
||||
|
||||
#define NSCANVASCLASS "WarpzillaCanvas"
|
||||
|
||||
#if 0
|
||||
|
||||
// Need to do this because the cross-platform widgets (toolbars) assume
|
||||
// that the name of the NS_CHILD_CID is ChildWindow and that it gets
|
||||
// defined in "nsWindow.h".
|
||||
//
|
||||
// However, if we've included this header *from nsCanvas.h*, then we
|
||||
// get a lovely circular dependency, and so special-case this.
|
||||
//
|
||||
// Yes, I suppose I'm just being perverse by having three separate classes
|
||||
// here, but I just baulk at naming a class 'ChildWindow'.
|
||||
//
|
||||
// (and don't tell me there's a JLib class called JMother. Believe me,
|
||||
// I know, and I regret it at least twice a week...)
|
||||
//
|
||||
#ifndef _nscanvas_h
|
||||
#include "nsCanvas.h"
|
||||
typedef nsCanvas ChildWindow;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,59 @@
|
|||
# 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/
|
||||
#
|
||||
# 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 the Mozilla OS/2 libraries.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Makefile for widget\src\os2\res
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
DLL = wdgtres.dll
|
||||
OS2_LIBRARYNAME = wdgtres
|
||||
export:
|
||||
|
||||
libs: $(DLL)
|
||||
|
||||
install:
|
||||
$(INSTALL) -m 444 $(DLL) $(DIST)/bin
|
||||
|
||||
RCOPTS = -n -x2 -i . $(RCDEFS)
|
||||
|
||||
# XXX Have to copy files because rc and link386 are too stupid for a mirror tree build
|
||||
|
||||
$(DLL): wdgtres.obj wdgtres.rc
|
||||
cp $(topsrcdir)/widget/src/os2/resID.h ./resID.h
|
||||
cp $(srcdir)/frame.ico ./frame.ico
|
||||
cp $(srcdir)/folder.ico ./folder.ico
|
||||
cp $(srcdir)/dragitem.ico ./dragitem.ico
|
||||
cp $(srcdir)/select.ptr ./select.ptr
|
||||
cp $(srcdir)/wdgtres.def ./wdgtres.def
|
||||
link386 /nol wdgtres,$@,nul,,wdgtres.def
|
||||
rc $(RCOPTS) $(srcdir)/wdgtres.rc $@
|
||||
|
||||
ifneq ($(MOZ_OS2_TOOLS),VACPP)
|
||||
OMF_FLAG = -Zomf
|
||||
endif
|
||||
|
||||
wdgtres.obj: wdgtres.C
|
||||
$(CC) -o $@ -s -c $(CFLAGS) $(OMF_FLAG) $<
|
||||
|
||||
realclean clean:
|
||||
rm -rf $(DLL) *.res *.obj
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче