Changes for OS/2. Patch provided by Eric Olson (eric.olson@sympatico.ca)

This commit is contained in:
mcafee%netscape.com 1999-06-28 23:39:35 +00:00
Родитель d922249feb
Коммит 78235616b4
112 изменённых файлов: 18764 добавлений и 0 удалений

75
gfx/src/os2/Makefile.in Normal file
Просмотреть файл

@ -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

445
gfx/src/os2/libprint.c Normal file
Просмотреть файл

@ -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);
}

98
gfx/src/os2/libprint.h Normal file
Просмотреть файл

@ -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
gfx/src/os2/libprint.ico Normal file
Просмотреть файл

0
gfx/src/os2/libprint.rc Normal file
Просмотреть файл

0
gfx/src/os2/libprres.h Normal file
Просмотреть файл

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

@ -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

86
gfx/src/os2/nsGfxDefs.h Normal file
Просмотреть файл

@ -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

356
gfx/src/os2/nsImageOS2.cpp Normal file
Просмотреть файл

@ -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;
}
}

88
gfx/src/os2/nsImageOS2.h Normal file
Просмотреть файл

@ -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

356
gfx/src/os2/nsRegionOS2.cpp Normal file
Просмотреть файл

@ -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;
}

78
gfx/src/os2/nsRegionOS2.h Normal file
Просмотреть файл

@ -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
gfx/src/os2/nsTimerOS2.h Normal file
Просмотреть файл

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

@ -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;
}

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

256
widget/src/os2/nsCanvas.cpp Normal file
Просмотреть файл

@ -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 = &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 = &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;
}

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

@ -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);
}

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

921
widget/src/os2/nsFSTree.cpp Normal file
Просмотреть файл

@ -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,
&paramPacket, paramSize, &paramSize,
&dataPacket, dataSize, &dataSize);
/* drive is available if (a) there is media (b) drive not locked */
*yesno = !rc && (dataPacket & 0x4) && ((dataPacket & 3) != 1);
}
return rc;
}

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

@ -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
widget/src/os2/nsLabel.h Normal file
Просмотреть файл

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

@ -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

141
widget/src/os2/nsMenu.cpp Normal file
Просмотреть файл

@ -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;
}

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

@ -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;
}

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

@ -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

416
widget/src/os2/nsModule.cpp Normal file
Просмотреть файл

@ -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

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

@ -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;
}

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

@ -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

2019
widget/src/os2/nsWindow.cpp Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -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

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

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше