mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
r=blizzard, sr=kin@netscape.com, a=asa for drivers XLIB only - Checkin for timecop@network.email.ne.jp - adding gc-cache to xlib port
This commit is contained in:
parent
6ecd046893
commit
2fe8c52474
@ -45,8 +45,17 @@ CPPSRCS = \
|
||||
nsScreenXlib.cpp \
|
||||
nsScreenManagerXlib.cpp \
|
||||
nsPrintOptionsXlib.cpp \
|
||||
nsGCCache.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef HAVE_XIE
|
||||
CSRCS += XIE.c
|
||||
endif
|
||||
|
||||
CSRCS += scale.c
|
||||
|
||||
EXPORTS = nsGCCache.h
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifndef MOZ_MONOLITHIC_TOOLKIT
|
||||
@ -57,10 +66,16 @@ EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
CXXFLAGS += $(TK_CFLAGS)
|
||||
endif
|
||||
|
||||
ifdef HAVE_XIE
|
||||
DEFINES += -DHAVE_XIE
|
||||
GFX_XIE_LIBS += $(MOZ_XIE_LIBS)
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(NSPR_LIBS) \
|
||||
-lxpcom \
|
||||
-lgkgfx \
|
||||
$(GFX_XIE_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -D_IMPL_NS_GFXNONXP
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "nsFontMetricsXlib.h"
|
||||
|
||||
#include "xlibrgb.h"
|
||||
#include "X11/Xatom.h"
|
||||
|
||||
#include "nsDeviceContextSpecXlib.h"
|
||||
|
||||
@ -49,8 +50,14 @@
|
||||
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
|
||||
static NS_DEFINE_IID(kDeviceContextIID, NS_IDEVICE_CONTEXT_IID);
|
||||
|
||||
#define XLIB_DEFAULT_FONT1 "-*-helvetica-medium-r-*-*-*-140-*-*-*-*-iso8859-1"
|
||||
#define XLIB_DEFAULT_FONT2 "-*-fixed-medium-r-*-*-*-120-*-*-*-*-*-*"
|
||||
|
||||
static PRLogModuleInfo *DeviceContextXlibLM = PR_NewLogModule("DeviceContextXlib");
|
||||
|
||||
/* global default font handle */
|
||||
static XFontStruct *mDefaultFont = nsnull;
|
||||
|
||||
nsDeviceContextXlib::nsDeviceContextXlib()
|
||||
: DeviceContextImpl()
|
||||
{
|
||||
@ -93,6 +100,11 @@ NS_IMETHODIMP nsDeviceContextXlib::Init(nsNativeWidget aNativeWidget)
|
||||
mVisual = xlib_rgb_get_visual();
|
||||
mDepth = xlib_rgb_get_depth();
|
||||
|
||||
if (!mDefaultFont)
|
||||
mDefaultFont = XLoadQueryFont(mDisplay, XLIB_DEFAULT_FONT1);
|
||||
|
||||
if (!mDefaultFont)
|
||||
mDefaultFont = XLoadQueryFont(mDisplay, XLIB_DEFAULT_FONT2);
|
||||
|
||||
#ifdef DEBUG
|
||||
static PRBool once = PR_TRUE;
|
||||
@ -171,12 +183,7 @@ NS_IMETHODIMP nsDeviceContextXlib::CreateRenderingContext(nsIRenderingContext *&
|
||||
NS_ADDREF(context);
|
||||
surface = new nsDrawingSurfaceXlib();
|
||||
if (nsnull != surface) {
|
||||
|
||||
GC gc = XCreateGC(mDisplay,
|
||||
(Drawable) mWidget,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
xGC *gc = new xGC(mDisplay,(Drawable) mWidget, 0, NULL);
|
||||
rv = surface->Init(mDisplay,
|
||||
mScreen,
|
||||
mVisual,
|
||||
@ -292,15 +299,65 @@ NS_IMETHODIMP nsDeviceContextXlib::GetSystemAttribute(nsSystemAttrID anID, Syste
|
||||
//---------
|
||||
// Fonts
|
||||
//---------
|
||||
case eSystemAttr_Font_Caption:
|
||||
case eSystemAttr_Font_Caption: // css2
|
||||
case eSystemAttr_Font_Icon:
|
||||
case eSystemAttr_Font_Menu:
|
||||
case eSystemAttr_Font_MessageBox:
|
||||
case eSystemAttr_Font_SmallCaption:
|
||||
case eSystemAttr_Font_StatusBar:
|
||||
case eSystemAttr_Font_Tooltips:
|
||||
case eSystemAttr_Font_Window: // css3
|
||||
case eSystemAttr_Font_Document:
|
||||
case eSystemAttr_Font_Workspace:
|
||||
case eSystemAttr_Font_Desktop:
|
||||
case eSystemAttr_Font_Info:
|
||||
case eSystemAttr_Font_Dialog:
|
||||
case eSystemAttr_Font_Button:
|
||||
case eSystemAttr_Font_PullDownMenu:
|
||||
case eSystemAttr_Font_List:
|
||||
case eSystemAttr_Font_Field:
|
||||
case eSystemAttr_Font_Tooltips: // moz
|
||||
case eSystemAttr_Font_Widget:
|
||||
status = NS_ERROR_FAILURE;
|
||||
aInfo->mFont->style = NS_FONT_STYLE_NORMAL;
|
||||
aInfo->mFont->weight = NS_FONT_WEIGHT_NORMAL;
|
||||
aInfo->mFont->decorations = NS_FONT_DECORATION_NONE;
|
||||
|
||||
|
||||
if (!mDefaultFont)
|
||||
return NS_ERROR_FAILURE;
|
||||
else
|
||||
{
|
||||
char *fontName = (char *)NULL;
|
||||
unsigned long pr = 0;
|
||||
|
||||
::XGetFontProperty(mDefaultFont, XA_FULL_NAME, &pr);
|
||||
if(pr)
|
||||
{
|
||||
fontName = XGetAtomName(mDisplay, pr);
|
||||
aInfo->mFont->name.AssignWithConversion(fontName);
|
||||
::XFree(fontName);
|
||||
}
|
||||
|
||||
pr = 0;
|
||||
::XGetFontProperty(mDefaultFont, XA_WEIGHT, &pr);
|
||||
if ( pr > 10 )
|
||||
aInfo->mFont->weight = NS_FONT_WEIGHT_BOLD;
|
||||
|
||||
pr = 0;
|
||||
Atom pixelSizeAtom = ::XInternAtom(mDisplay, "PIXEL_SIZE", 0);
|
||||
::XGetFontProperty(mDefaultFont, pixelSizeAtom, &pr);
|
||||
if( pr )
|
||||
aInfo->mFont->size = NSIntPixelsToTwips(pr, mPixelsToTwips);
|
||||
|
||||
pr = 0;
|
||||
::XGetFontProperty(mDefaultFont, XA_ITALIC_ANGLE, &pr );
|
||||
if( pr )
|
||||
aInfo->mFont->style = NS_FONT_STYLE_ITALIC;
|
||||
|
||||
pr = 0;
|
||||
::XGetFontProperty(mDefaultFont, XA_UNDERLINE_THICKNESS, &pr);
|
||||
if( pr )
|
||||
aInfo->mFont->decorations = NS_FONT_DECORATION_UNDERLINE;
|
||||
}
|
||||
break;
|
||||
} // switch
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "nsDrawingSurfaceXlib.h"
|
||||
#include "prlog.h"
|
||||
#include "nsGCCache.h"
|
||||
|
||||
#include "xlibrgb.h" // for xlib_rgb_get_visual_info
|
||||
#include <X11/Xutil.h> // for XVisualInfo.
|
||||
@ -42,7 +43,7 @@ nsDrawingSurfaceXlib::nsDrawingSurfaceXlib()
|
||||
mScreen = nsnull;
|
||||
mVisual = nsnull;
|
||||
mDepth = 0;
|
||||
mGC = 0;
|
||||
mGC = nsnull;
|
||||
// set up lock info
|
||||
mLocked = PR_FALSE;
|
||||
mLockX = 0;
|
||||
@ -91,8 +92,10 @@ nsDrawingSurfaceXlib::~nsDrawingSurfaceXlib()
|
||||
}
|
||||
|
||||
// We are freeing the GC here now [See nsWidget::CreateGC()]
|
||||
if (mGC)
|
||||
XFreeGC(mDisplay, mGC);
|
||||
if(mGC) {
|
||||
mGC->Release();
|
||||
mGC = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE(nsDrawingSurfaceXlib, kIDrawingSurfaceIID)
|
||||
@ -105,7 +108,7 @@ nsDrawingSurfaceXlib::Init(Display * aDisplay,
|
||||
Visual * aVisual,
|
||||
int aDepth,
|
||||
Drawable aDrawable,
|
||||
GC aGC)
|
||||
xGC *aGC)
|
||||
{
|
||||
PR_LOG(DrawingSurfaceXlibLM, PR_LOG_DEBUG, ("nsDrawingSurfaceXlib::Init()\n"));
|
||||
|
||||
@ -113,14 +116,12 @@ nsDrawingSurfaceXlib::Init(Display * aDisplay,
|
||||
mScreen = aScreen;
|
||||
mVisual = aVisual;
|
||||
mDepth = aDepth;
|
||||
// We Ignore the GC we are given, cos it is bad. [See nsWidget::CreateGC()]
|
||||
#if 0
|
||||
mGC = aGC;
|
||||
#endif
|
||||
mDrawable = aDrawable;
|
||||
|
||||
// Create a new GC
|
||||
mGC = XCreateGC(mDisplay, mDrawable, 0, NULL);
|
||||
if (mGC)
|
||||
mGC->Release();
|
||||
mGC = aGC;
|
||||
mGC->AddRef();
|
||||
|
||||
mIsOffscreen = PR_FALSE;
|
||||
return NS_OK;
|
||||
@ -131,7 +132,7 @@ nsDrawingSurfaceXlib::Init (Display * aDisplay,
|
||||
Screen * aScreen,
|
||||
Visual * aVisual,
|
||||
int aDepth,
|
||||
GC aGC,
|
||||
xGC * aGC,
|
||||
PRUint32 aWidth,
|
||||
PRUint32 aHeight,
|
||||
PRUint32 aFlags)
|
||||
@ -140,15 +141,15 @@ nsDrawingSurfaceXlib::Init (Display * aDisplay,
|
||||
mScreen = aScreen;
|
||||
mVisual = aVisual;
|
||||
mDepth = aDepth;
|
||||
// We Ignore the GC we are given, cos it is bad. [See nsWidget::Create()]
|
||||
#if 0
|
||||
mGC = aGC;
|
||||
#endif
|
||||
|
||||
mWidth = aWidth;
|
||||
mHeight = aHeight;
|
||||
mLockFlags = aFlags;
|
||||
|
||||
if(mGC)
|
||||
mGC->Release();
|
||||
mGC = aGC;
|
||||
mGC->AddRef();
|
||||
|
||||
mIsOffscreen = PR_TRUE;
|
||||
|
||||
mDrawable = XCreatePixmap(mDisplay,
|
||||
@ -156,9 +157,6 @@ nsDrawingSurfaceXlib::Init (Display * aDisplay,
|
||||
mWidth,
|
||||
mHeight,
|
||||
mDepth);
|
||||
// Create a new GC
|
||||
mGC = XCreateGC(mDisplay, mDrawable, 0, NULL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -213,7 +211,7 @@ nsDrawingSurfaceXlib::Unlock(void)
|
||||
|
||||
// If the lock was not read only, put the bits back on the pixmap
|
||||
if (!(mLockFlags & NS_LOCK_SURFACE_READ_ONLY)) {
|
||||
XPutImage(mDisplay, mDrawable, mGC, mImage,
|
||||
XPutImage(mDisplay, mDrawable, *mGC, mImage,
|
||||
0, 0, mLockX, mLockY,
|
||||
mLockWidth, mLockHeight);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define nsDrawingSurfaceXlib_h__
|
||||
|
||||
#include "nsIDrawingSurface.h"
|
||||
#include "nsGCCache.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xos.h>
|
||||
@ -50,31 +51,31 @@ public:
|
||||
Visual * aVisual,
|
||||
int aDepth,
|
||||
Drawable aDrawable,
|
||||
GC aGC);
|
||||
xGC * aGC);
|
||||
|
||||
NS_IMETHOD Init (Display * aDisplay,
|
||||
Screen * aScreen,
|
||||
Visual * aVisual,
|
||||
int aDepth,
|
||||
GC aGC,
|
||||
xGC * aGC,
|
||||
PRUint32 aWidth,
|
||||
PRUint32 aHeight,
|
||||
PRUint32 aFlags);
|
||||
|
||||
GC GetGC(void) { return mGC; }
|
||||
Drawable GetDrawable(void) { return (mDrawable); }
|
||||
Display * GetDisplay() { return mDisplay; }
|
||||
Screen * GetScreen() { return mScreen; }
|
||||
Visual * GetVisual() { return mVisual; }
|
||||
int GetDepth() { return mDepth; }
|
||||
int GetScreenNumber() { return XScreenNumberOfScreen(mScreen); }
|
||||
xGC * GetGC() { mGC->AddRef(); return mGC; }
|
||||
|
||||
private:
|
||||
Display * mDisplay;
|
||||
Screen * mScreen;
|
||||
Visual * mVisual;
|
||||
int mDepth;
|
||||
GC mGC;
|
||||
xGC * mGC;
|
||||
Drawable mDrawable;
|
||||
XImage * mImage;
|
||||
nsPixelFormat mPixFormat;
|
||||
|
@ -49,7 +49,7 @@
|
||||
|
||||
#undef USER_DEFINED
|
||||
#define USER_DEFINED "x-user-def"
|
||||
#define NOISY_FONTS 1
|
||||
// #define NOISY_FONTS 1
|
||||
|
||||
|
||||
// these are in the widget set
|
||||
@ -1477,6 +1477,7 @@ SetUpFontCharSetInfo(nsFontCharSetInfo* aSelf)
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef NOISY_FONTS
|
||||
else
|
||||
fprintf(stderr, "=== nsICharRepresentable %s failed\n", aSelf->mCharSet);
|
||||
}
|
||||
@ -1485,6 +1486,10 @@ SetUpFontCharSetInfo(nsFontCharSetInfo* aSelf)
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "=== GetCharsetAtom2 %s failed\n", aSelf->mCharSet);
|
||||
#else
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef DEBUG_DUMP_TREE
|
||||
@ -1723,7 +1728,7 @@ nsFontXlibNormal::GetWidth(const PRUnichar* aString, PRUint32 aLength)
|
||||
if ((mFont->min_byte1 == 0) && (mFont->max_byte1 == 0))
|
||||
return XTextWidth(mFont, (char*) buf, len);
|
||||
else
|
||||
return XTextWidth16(mFont, buf, len);
|
||||
return XTextWidth16(mFont, buf, len / 2);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1743,23 +1748,39 @@ nsFontXlibNormal::DrawString(nsRenderingContextXlib* aContext,
|
||||
int len = mCharSetInfo->Convert(mCharSetInfo, mFont, aString, aLength,
|
||||
(char*) buf, sizeof(buf));
|
||||
|
||||
xGC *gc = aContext->GetGC();
|
||||
if ((mFont->min_byte1 == 0) && (mFont->max_byte1 == 0))
|
||||
{
|
||||
XDrawString(aSurface->GetDisplay(),
|
||||
aSurface->GetDrawable(),
|
||||
aSurface->GetGC(),
|
||||
*gc,
|
||||
aX, aY + mBaselineAdjust, (char *)buf, len);
|
||||
|
||||
gc->Release();
|
||||
return XTextWidth(mFont, (char*) buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* XXX is this the right way to do it? Can I get GCCache to give me a
|
||||
* new GC? */
|
||||
GC copyGC;
|
||||
XGCValues values;
|
||||
memset(&values, 0, sizeof(XGCValues));
|
||||
|
||||
XGetGCValues(aSurface->GetDisplay(), *gc,
|
||||
GCForeground | GCBackground, &values);
|
||||
values.font = mFont->fid;
|
||||
copyGC = XCreateGC(aSurface->GetDisplay(), aSurface->GetDrawable(),
|
||||
GCForeground | GCBackground | GCFont, &values);
|
||||
|
||||
/* note the length must be divided by 2 for X*16 functions */
|
||||
XDrawString16(aSurface->GetDisplay(),
|
||||
aSurface->GetDrawable(),
|
||||
aSurface->GetGC(),
|
||||
aX, aY + mBaselineAdjust, buf, len);
|
||||
|
||||
return XTextWidth16(mFont, buf, len);
|
||||
copyGC,
|
||||
aX, aY + mBaselineAdjust, buf, len / 2);
|
||||
XFreeGC(aSurface->GetDisplay(), copyGC);
|
||||
gc->Release();
|
||||
return XTextWidth16(mFont, buf, len / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2016,11 +2037,13 @@ nsFontXlibUserDefined::DrawString(nsRenderingContextXlib* aContext,
|
||||
char buf[1024];
|
||||
PRUint32 len = Convert(aString, aLength, buf, sizeof(buf));
|
||||
|
||||
xGC *gc = aContext->GetGC();
|
||||
XDrawString(aSurface->GetDisplay(),
|
||||
aSurface->GetDrawable(),
|
||||
aSurface->GetGC(),
|
||||
*gc,
|
||||
aX, aY + mBaselineAdjust, (char *)buf, len);
|
||||
|
||||
gc->Release();
|
||||
return XTextWidth(mFont, buf, len);
|
||||
}
|
||||
|
||||
@ -2104,7 +2127,7 @@ nsFontMetricsXlib::PickASizeAndLoad(nsFontStretch* aStretch,
|
||||
{
|
||||
PRInt32 i;
|
||||
PRInt32 n = aStretch->mScaledFonts.Count();
|
||||
nsFontXlib* p;
|
||||
nsFontXlib* p = nsnull;
|
||||
|
||||
for (i=0; i < n; i++)
|
||||
{
|
||||
@ -3061,7 +3084,7 @@ nsFontMetricsXlib::FindLocalFont(PRUnichar aChar)
|
||||
if (mFontIsGeneric[mFontsIndex])
|
||||
return nsnull;
|
||||
|
||||
nsCString* familyName = mFonts.CStringAt(mFontsIndex++);
|
||||
nsCString* familyName = mFonts.CStringAt(mFontsIndex);
|
||||
|
||||
/*
|
||||
* Count Hyphens
|
||||
@ -3102,6 +3125,7 @@ nsFontMetricsXlib::FindLocalFont(PRUnichar aChar)
|
||||
if (font && font->SupportsChar(aChar))
|
||||
return font;
|
||||
}
|
||||
mFontsIndex++;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
|
@ -64,7 +64,7 @@ static nsresult nsScriptableRegionConstructor(nsISupports *aOuter, REFNSIID aIID
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsIScriptableRegion *inst;
|
||||
nsIScriptableRegion *inst = nsnull;
|
||||
|
||||
if ( NULL == aResult )
|
||||
{
|
||||
@ -190,5 +190,10 @@ static nsModuleComponentInfo components[] =
|
||||
nsScreenManagerXlibConstructor }
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(nsGfxXlibModule, components)
|
||||
PR_STATIC_CALLBACK(void)
|
||||
nsGfxXlibModuleDtor(nsIModule *self)
|
||||
{
|
||||
nsRenderingContextXlib::Shutdown();
|
||||
}
|
||||
|
||||
NS_IMPL_NSGETMODULE_WITH_DTOR("nsGfxXlibModule", components, nsGfxXlibModuleDtor)
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim:ts=2:sw=2:et
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
@ -23,13 +24,25 @@
|
||||
|
||||
#include "nsImageXlib.h"
|
||||
#include "nsDrawingSurfaceXlib.h"
|
||||
#include "nsDeviceContextXlib.h"
|
||||
#include "nsRenderingContextXlib.h"
|
||||
#include "xlibrgb.h"
|
||||
#include "prlog.h"
|
||||
#include "drawers.h"
|
||||
|
||||
#define IsFlagSet(a,b) ((a) & (b))
|
||||
|
||||
static PRLogModuleInfo *ImageXlibLM = PR_NewLogModule("ImageXlib");
|
||||
|
||||
/* XXX we are simply creating a GC and setting its function to Copy.
|
||||
we shouldn't be doing this every time this method is called. this creates
|
||||
way more trips to the server than we should be doing so we are creating a
|
||||
static one.
|
||||
*/
|
||||
static GC s1bitGC = 0;
|
||||
static GC sXbitGC = 0;
|
||||
|
||||
|
||||
nsImageXlib::nsImageXlib()
|
||||
{
|
||||
PR_LOG(ImageXlibLM, PR_LOG_DEBUG, ("nsImageXlib::nsImageXlib()\n"));
|
||||
@ -48,10 +61,9 @@ nsImageXlib::nsImageXlib()
|
||||
mAlphaRowBytes = 0;
|
||||
mAlphaWidth = 0;
|
||||
mAlphaHeight = 0;
|
||||
mLocation.x = 0;
|
||||
mLocation.y = 0;
|
||||
mAlphaValid = PR_FALSE;
|
||||
mDisplay = nsnull;
|
||||
mConvertedBits = nsnull;
|
||||
mGC = nsnull;
|
||||
mNaturalWidth = 0;
|
||||
mNaturalHeight = 0;
|
||||
|
||||
@ -94,17 +106,38 @@ nsImageXlib::~nsImageXlib()
|
||||
|
||||
XFreePixmap(mDisplay, mImagePixmap);
|
||||
}
|
||||
|
||||
if(mGC)
|
||||
{
|
||||
XFreeGC(mDisplay, mGC);
|
||||
mGC=nsnull;
|
||||
}
|
||||
if(sXbitGC && mDisplay) // Sometimes mDisplay is null, let orhers free
|
||||
{
|
||||
XFreeGC(mDisplay, sXbitGC);
|
||||
sXbitGC=nsnull;
|
||||
}
|
||||
if(s1bitGC && mDisplay) // Sometimes mDisplay is null, let orhers free
|
||||
{
|
||||
XFreeGC(mDisplay, s1bitGC);
|
||||
s1bitGC=nsnull;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsImageXlib, nsIImage)
|
||||
NS_IMPL_ISUPPORTS1(nsImageXlib, nsIImage);
|
||||
|
||||
nsresult nsImageXlib::Init(PRInt32 aWidth, PRInt32 aHeight,
|
||||
PRInt32 aDepth, nsMaskRequirements aMaskRequirements)
|
||||
{
|
||||
if ((aWidth == 0) || (aHeight == 0))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (nsnull != mImageBits) {
|
||||
delete[] mImageBits;
|
||||
mImageBits = nsnull;
|
||||
}
|
||||
|
||||
if (nsnull != mAlphaBits) {
|
||||
delete[] mAlphaBits;
|
||||
mAlphaBits = nsnull;;
|
||||
@ -123,8 +156,7 @@ nsresult nsImageXlib::Init(PRInt32 aWidth, PRInt32 aHeight,
|
||||
mImagePixmap = nsnull;
|
||||
}
|
||||
|
||||
if (24 == aDepth)
|
||||
{
|
||||
if (24 == aDepth) {
|
||||
mNumBytesPixel = 3;
|
||||
} else {
|
||||
NS_ASSERTION(PR_FALSE, "unexpected image depth");
|
||||
@ -141,8 +173,7 @@ nsresult nsImageXlib::Init(PRInt32 aWidth, PRInt32 aHeight,
|
||||
|
||||
mImageBits = (PRUint8*)new PRUint8[mSizeImage];
|
||||
|
||||
switch(aMaskRequirements)
|
||||
{
|
||||
switch(aMaskRequirements) {
|
||||
case nsMaskRequirements_kNoMask:
|
||||
mAlphaBits = nsnull;
|
||||
mAlphaWidth = 0;
|
||||
@ -257,17 +288,137 @@ void nsImageXlib::ImageUpdated(nsIDeviceContext *aContext,
|
||||
PRUint8 aFlags,
|
||||
nsRect *aUpdateRect)
|
||||
{
|
||||
if (nsImageUpdateFlags_kBitsChanged & aFlags) {
|
||||
if (mAlphaPixmap != nsnull) {
|
||||
XFreePixmap(mDisplay, mAlphaPixmap);
|
||||
mAlphaPixmap = nsnull;
|
||||
/* this does not do what I think it should do, so comment out for now */
|
||||
|
||||
// check if the image has an all-opaque 8-bit alpha mask
|
||||
if ((mAlphaDepth==8) && !mAlphaValid) {
|
||||
unsigned bottom, left, right;
|
||||
bottom = aUpdateRect->y + aUpdateRect->height;
|
||||
left = aUpdateRect->x;
|
||||
right = left + aUpdateRect->width;
|
||||
for (unsigned y=aUpdateRect->y; (y<bottom) && !mAlphaValid; y++) {
|
||||
unsigned char *alpha = mAlphaBits + mAlphaRowBytes*y + left;
|
||||
for (unsigned x=left; x<right; x++) {
|
||||
if (*(alpha++)!=255) {
|
||||
mAlphaValid=PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if (mImagePixmap != nsnull) {
|
||||
XFreePixmap(mDisplay, mImagePixmap);
|
||||
mImagePixmap = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
mFlags = aFlags;
|
||||
|
||||
if (mAlphaValid && mImagePixmap) {
|
||||
XFreePixmap(mDisplay, mImagePixmap);
|
||||
mImagePixmap = 0;
|
||||
}
|
||||
|
||||
if (!mAlphaValid) {
|
||||
CreateOffscreenPixmap(mWidth, mHeight);
|
||||
|
||||
if (!sXbitGC) {
|
||||
XGCValues gcv;
|
||||
memset(&gcv, 0, sizeof(XGCValues));
|
||||
gcv.function = GXcopy;
|
||||
sXbitGC = XCreateGC(mDisplay, mImagePixmap, GCFunction, &gcv);
|
||||
}
|
||||
xlib_draw_rgb_image_dithalign(mImagePixmap, sXbitGC,
|
||||
aUpdateRect->x, aUpdateRect->y,
|
||||
aUpdateRect->width, aUpdateRect->height,
|
||||
XLIB_RGB_DITHER_MAX,
|
||||
mImageBits + mRowBytes * aUpdateRect->y + 3 * aUpdateRect->x,
|
||||
mRowBytes,
|
||||
aUpdateRect->x, aUpdateRect->y);
|
||||
}
|
||||
mFlags = aFlags; // this should be 0'd out by Draw()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageXlib::DrawScaled(nsIRenderingContext &aContext,
|
||||
nsDrawingSurface aSurface,
|
||||
PRInt32 aSX, PRInt32 aSY,
|
||||
PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY,
|
||||
PRInt32 aDWidth, PRInt32 aDHeight)
|
||||
{
|
||||
|
||||
PRInt32 origSHeight = aSHeight, origDHeight = aDHeight;
|
||||
PRInt32 origSWidth = aSWidth, origDWidth = aDWidth;
|
||||
|
||||
if (aSWidth < 0 || aDWidth < 0 || aSHeight < 0 || aDHeight < 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (0 == aSWidth || 0 == aDWidth || 0 == aSHeight || 0 == aDHeight)
|
||||
return NS_OK;
|
||||
|
||||
// limit the size of the blit to the amount of the image read in
|
||||
if (aSX + aSWidth > mDecodedX2) {
|
||||
aDWidth -= ((aSX + aSWidth - mDecodedX2)*origDWidth)/origSWidth;
|
||||
aSWidth -= (aSX + aSWidth) - mDecodedX2;
|
||||
}
|
||||
if (aSX < mDecodedX1) {
|
||||
aDX += ((mDecodedX1 - aSX)*origDWidth)/origSWidth;
|
||||
aSX = mDecodedX1;
|
||||
}
|
||||
|
||||
if (aSY + aSHeight > mDecodedY2) {
|
||||
aDHeight -= ((aSY + aSHeight - mDecodedY2)*origDHeight)/origSHeight;
|
||||
aSHeight -= (aSY + aSHeight) - mDecodedY2;
|
||||
}
|
||||
if (aSY < mDecodedY1) {
|
||||
aDY += ((mDecodedY1 - aSY)*origDHeight)/origSHeight;
|
||||
aSY = mDecodedY1;
|
||||
}
|
||||
|
||||
if ((aDWidth <= 0 || aDHeight <= 0) || (aSWidth <= 0 || aSHeight <= 0))
|
||||
return NS_OK;
|
||||
|
||||
nsDrawingSurfaceXlib *drawing = (nsDrawingSurfaceXlib*)aSurface;
|
||||
xGC *gc = ((nsRenderingContextXlib&)aContext).GetGC();
|
||||
|
||||
if (mAlphaDepth == 1)
|
||||
CreateAlphaBitmap(mWidth, mHeight);
|
||||
|
||||
if ((mAlphaDepth == 8) && mAlphaValid) {
|
||||
NS_WARNING("can't do 8bit alpha stretched images currently\n");
|
||||
/* TODO: stretch alpha, stretch source, composite */
|
||||
/* DrawComposited(aContext, aSurface, aSX, aSY, aDX, aDY, aSWidth, aSHeight); */
|
||||
gc->Release();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool succeeded = PR_FALSE;
|
||||
|
||||
#ifdef HAVE_XIE
|
||||
/* Draw with XIE */
|
||||
succeeded = DrawScaledImageXIE(mDisplay, drawing->GetDrawable(),
|
||||
*gc,
|
||||
mImagePixmap,
|
||||
mAlphaPixmap,
|
||||
mWidth, mHeight,
|
||||
aSX, aSY,
|
||||
aSWidth, aSHeight,
|
||||
aDX, aDY,
|
||||
aDWidth, aDHeight);
|
||||
#endif
|
||||
|
||||
if (!succeeded) {
|
||||
/* the last resort */
|
||||
succeeded = DrawScaledImageNN(mDisplay,
|
||||
drawing->GetDrawable(),
|
||||
*gc,
|
||||
mImagePixmap,
|
||||
mAlphaPixmap,
|
||||
mWidth, mHeight,
|
||||
aSX, aSY,
|
||||
aSWidth, aSHeight,
|
||||
aDX, aDY,
|
||||
aDWidth, aDHeight);
|
||||
}
|
||||
|
||||
gc->Release();
|
||||
|
||||
mFlags = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Draw the bitmap, this method has a source and destination coordinates
|
||||
@ -279,18 +430,86 @@ nsImageXlib::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||
if (aSurface == nsnull)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsDrawingSurfaceXlib *drawing = (nsDrawingSurfaceXlib*)aSurface;
|
||||
if (aSWidth != aDWidth || aSHeight != aDHeight) {
|
||||
return DrawScaled(aContext, aSurface, aSX, aSY, aSWidth, aSHeight,
|
||||
aDX, aDY, aDWidth, aDHeight);
|
||||
}
|
||||
|
||||
if (aSWidth <= 0 || aDWidth <= 0 || aSHeight <= 0 || aDHeight <= 0) {
|
||||
NS_ASSERTION(aSWidth > 0 && aDWidth > 0 && aSHeight > 0 && aDHeight > 0,
|
||||
"You can't draw an image with a 0 width or height!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// limit the size of the blit to the amount of the image read in
|
||||
PRInt32 j = aSX + aSWidth;
|
||||
PRInt32 z;
|
||||
if (j > mDecodedX2) {
|
||||
z = j - mDecodedX2;
|
||||
aDWidth -= z;
|
||||
aSWidth -= z;
|
||||
}
|
||||
if (aSX < mDecodedX1) {
|
||||
aDX += mDecodedX1 - aSX;
|
||||
aSX = mDecodedX1;
|
||||
}
|
||||
|
||||
j = aSY + aSHeight;
|
||||
if (j > mDecodedY2) {
|
||||
z = j - mDecodedY2;
|
||||
aDHeight -= z;
|
||||
aSHeight -= z;
|
||||
}
|
||||
if (aSY < mDecodedY1) {
|
||||
aDY += mDecodedY1 - aSY;
|
||||
aSY = mDecodedY1;
|
||||
}
|
||||
|
||||
if (aDWidth <= 0 || aDHeight <= 0 || aSWidth <= 0 || aSHeight <= 0)
|
||||
return NS_OK;
|
||||
|
||||
if ((mAlphaDepth == 8) && mAlphaValid) {
|
||||
DrawComposited(aContext, aSurface, aSX, aSY, aDX, aDY, aSWidth, aSHeight);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsDrawingSurfaceXlib *drawing = (nsDrawingSurfaceXlib*)aSurface;
|
||||
if (mDisplay == nsnull)
|
||||
mDisplay = drawing->GetDisplay();
|
||||
|
||||
xlib_draw_rgb_image(drawing->GetDrawable(),
|
||||
drawing->GetGC(),
|
||||
aDX, aDY, aDWidth, aDHeight,
|
||||
XLIB_RGB_DITHER_MAX,
|
||||
mImageBits + mRowBytes * aSY + 3 * aDX,
|
||||
mRowBytes);
|
||||
|
||||
if (mAlphaDepth == 1)
|
||||
CreateAlphaBitmap(mWidth, mHeight);
|
||||
|
||||
GC copyGC;
|
||||
xGC *gc = ((nsRenderingContextXlib&)aContext).GetGC();
|
||||
|
||||
if (mAlphaPixmap) {
|
||||
if (mGC) { /* reuse GC */
|
||||
copyGC = mGC;
|
||||
SetupGCForAlpha(copyGC, aDX - aSX, aDY - aSY);
|
||||
} else { /* make a new one */
|
||||
/* this repeats things done in SetupGCForAlpha */
|
||||
XGCValues xvalues;
|
||||
memset(&xvalues, 0, sizeof(XGCValues));
|
||||
unsigned long xvalues_mask = 0;
|
||||
xvalues.clip_x_origin = aDX - aSX;
|
||||
xvalues.clip_y_origin = aDY - aSY;
|
||||
if (IsFlagSet(nsImageUpdateFlags_kBitsChanged, mFlags)) {
|
||||
xvalues_mask = GCClipXOrigin | GCClipYOrigin | GCClipMask;
|
||||
xvalues.clip_mask = mAlphaPixmap;
|
||||
}
|
||||
mGC = XCreateGC(mDisplay, drawing->GetDrawable(), xvalues_mask , &xvalues);
|
||||
copyGC = mGC;
|
||||
}
|
||||
} else { /* !mAlphaPixmap */
|
||||
copyGC = *gc;
|
||||
}
|
||||
|
||||
XCopyArea(mDisplay, mImagePixmap, drawing->GetDrawable(),
|
||||
copyGC, aSX, aSY, aSWidth, aDWidth, aDX, aDY);
|
||||
|
||||
gc->Release();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -470,7 +689,6 @@ nsImageXlib::DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes,
|
||||
XImage *ximage, unsigned char *readData)
|
||||
{
|
||||
Visual *visual = xlib_rgb_get_visual();
|
||||
Colormap colormap = xlib_rgb_get_cmap();
|
||||
|
||||
unsigned char *target = readData;
|
||||
|
||||
@ -533,7 +751,7 @@ nsImageXlib::DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned char *ptr =
|
||||
(unsigned char *)ximage->data + row*ximage->bytes_per_line;
|
||||
for (int col=0; col<ximage->width; col++) {
|
||||
unsigned pix;
|
||||
unsigned pix = 0;
|
||||
switch (ximage->bits_per_pixel) {
|
||||
case 1:
|
||||
pix = (*ptr>>(col%8))&1;
|
||||
@ -591,14 +809,12 @@ nsImageXlib::DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes,
|
||||
void
|
||||
nsImageXlib::DrawComposited(nsIRenderingContext &aContext,
|
||||
nsDrawingSurface aSurface,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aSX, PRInt32 aSY,
|
||||
PRInt32 aDX, PRInt32 aDY,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
if ((aWidth != mWidth) || (aHeight != mHeight))
|
||||
{
|
||||
aWidth = mWidth;
|
||||
aHeight = mHeight;
|
||||
}
|
||||
if ((aWidth==0) || (aHeight==0))
|
||||
return;
|
||||
|
||||
nsDrawingSurfaceXlib *drawing = (nsDrawingSurfaceXlib*)aSurface;
|
||||
Visual *visual = xlib_rgb_get_visual();
|
||||
@ -606,35 +822,30 @@ nsImageXlib::DrawComposited(nsIRenderingContext &aContext,
|
||||
Display *dpy = drawing->GetDisplay();
|
||||
Drawable drawable = drawing->GetDrawable();
|
||||
|
||||
// I hate clipping too :)
|
||||
// I hate clipping... too!
|
||||
PRUint32 surfaceWidth, surfaceHeight;
|
||||
drawing->GetDimensions(&surfaceWidth, &surfaceHeight);
|
||||
|
||||
int readX, readY;
|
||||
unsigned readWidth, readHeight, destX, destY;
|
||||
|
||||
readX = aX; readY = aY;
|
||||
destX = 0; destY = 0;
|
||||
if ((aY>=(int)surfaceHeight) || (aX>=(int)surfaceWidth) ||
|
||||
(aY+aHeight<=0) || (aX+aWidth<=0))
|
||||
{
|
||||
// this should never happen if the layout engine is sane,
|
||||
// as it means we are trying to draw an image which is outside
|
||||
// the drawing surface.
|
||||
|
||||
if ((aDY >= (int)surfaceHeight) || (aDX >= (int)surfaceWidth) ||
|
||||
(aDY + aHeight <= 0) || (aDX + aWidth <= 0)) {
|
||||
// This should never happen if the layout engine is sane,
|
||||
// as it means we're trying to draw an image which is outside
|
||||
// the drawing surface. Bulletproof gfx for now...
|
||||
return;
|
||||
}
|
||||
|
||||
if (aX<0) {
|
||||
readX = 0; readWidth = aWidth+aX; destX = -aX;
|
||||
if (aDX < 0) {
|
||||
readX = 0; readWidth = aWidth + aDX; destX = aSX - aDX;
|
||||
} else {
|
||||
readX = aX; readWidth = aWidth; destX = 0;
|
||||
readX = aDX; readWidth = aWidth; destX = aSX;
|
||||
}
|
||||
|
||||
if (aY<0) {
|
||||
readY = 0; readHeight = aHeight+aY; destY = -aY;
|
||||
if (aDY < 0) {
|
||||
readY = 0; readHeight = aHeight + aDY; destY = aSY - aDY;
|
||||
} else {
|
||||
readY = aY; readHeight = aHeight; destY = 0;
|
||||
readY = aDY; readHeight = aHeight; destY = aSY;
|
||||
}
|
||||
|
||||
if (readX+readWidth > surfaceWidth)
|
||||
@ -642,13 +853,26 @@ nsImageXlib::DrawComposited(nsIRenderingContext &aContext,
|
||||
if (readY+readHeight > surfaceHeight)
|
||||
readHeight = surfaceHeight-readY;
|
||||
|
||||
if ((readHeight <= 0) || (readWidth <= 0))
|
||||
return;
|
||||
|
||||
// fprintf(stderr, "aX=%d aY=%d, aWidth=%u aHeight=%u\n", aX, aY, aWidth, aHeight);
|
||||
// fprintf(stderr, "surfaceWidth=%u surfaceHeight=%u\n", surfaceWidth, surfaceHeight);
|
||||
// fprintf(stderr, "readX=%u readY=%u readWidth=%u readHeight=%u destX=%u destY=%u\n\n",
|
||||
// readX, readY, readWidth, readHeight, destX, destY);
|
||||
|
||||
XImage *ximage = XGetImage(dpy, drawable,
|
||||
readX, readY, readWidth, readHeight,
|
||||
AllPlanes, ZPixmap);
|
||||
|
||||
NS_ASSERTION((ximage != NULL), "XGetImage() failed");
|
||||
if (!ximage)
|
||||
return;
|
||||
|
||||
unsigned char *readData = new unsigned char[3*readWidth*readHeight];
|
||||
|
||||
PRBool isLSB;
|
||||
unsigned test = 1;
|
||||
unsigned int test = 1;
|
||||
isLSB = (((char *)&test)[0]) ? 1 : 0;
|
||||
|
||||
PRBool flipBytes =
|
||||
@ -668,107 +892,117 @@ nsImageXlib::DrawComposited(nsIRenderingContext &aContext,
|
||||
DrawComposited24(isLSB, flipBytes, destX, destY, readWidth, readHeight,
|
||||
ximage, readData);
|
||||
else if ((ximage->bits_per_pixel==16) &&
|
||||
(xlib_get_prec_from_mask(visual->red_mask) == 6) &&
|
||||
(xlib_get_prec_from_mask(visual->green_mask) == 6) &&
|
||||
(xlib_get_prec_from_mask(visual->blue_mask) == 6))
|
||||
((xlib_get_prec_from_mask(visual->red_mask) == 5) || (xlib_get_prec_from_mask(visual->red_mask) == 6)) &&
|
||||
((xlib_get_prec_from_mask(visual->green_mask) == 5) || (xlib_get_prec_from_mask(visual->green_mask) == 6)) &&
|
||||
((xlib_get_prec_from_mask(visual->blue_mask) == 5) || (xlib_get_prec_from_mask(visual->blue_mask) == 6)))
|
||||
DrawComposited16(isLSB, flipBytes, destX, destY, readWidth, readHeight,
|
||||
ximage, readData);
|
||||
else
|
||||
DrawCompositedGeneral(isLSB, flipBytes, destX, destY, readWidth, readHeight,
|
||||
ximage, readData);
|
||||
|
||||
GC imageGC;
|
||||
imageGC = XCreateGC(dpy, drawing->GetDrawable(), 0, NULL);
|
||||
xlib_draw_rgb_image(drawing->GetDrawable(),
|
||||
imageGC,
|
||||
xGC *imageGC = ((nsRenderingContextXlib&)aContext).GetGC();
|
||||
xlib_draw_rgb_image(drawing->GetDrawable(), *imageGC,
|
||||
readX, readY, readWidth, readHeight,
|
||||
XLIB_RGB_DITHER_MAX,
|
||||
readData, 3*readWidth);
|
||||
XFreeGC(dpy, imageGC);
|
||||
XDestroyImage(ximage);
|
||||
imageGC->Release();
|
||||
delete[] readData;
|
||||
mFlags = 0;
|
||||
}
|
||||
|
||||
void nsImageXlib::CreateAlphaBitmap(PRInt32 aWidth, PRInt32 aHeight,
|
||||
nsDrawingSurface aSurface)
|
||||
void nsImageXlib::CreateAlphaBitmap(PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
XImage *x_image = nsnull;
|
||||
Display *dpy = nsnull;
|
||||
Visual *visual = nsnull;
|
||||
GC gc;
|
||||
XGCValues gcv;
|
||||
|
||||
nsDrawingSurfaceXlib *drawing = (nsDrawingSurfaceXlib*)aSurface;
|
||||
|
||||
if (mDisplay == nsnull)
|
||||
mDisplay = drawing->GetDisplay();
|
||||
mDisplay = xlib_rgb_get_display();
|
||||
|
||||
// Create gc clip-mask on demand
|
||||
if (mAlphaBits != nsnull)
|
||||
{
|
||||
if (mAlphaPixmap == nsnull)
|
||||
{
|
||||
mAlphaPixmap = XCreatePixmap(mDisplay,
|
||||
RootWindow(mDisplay, drawing->GetScreenNumber()),
|
||||
aWidth, aHeight, 1);
|
||||
}
|
||||
/* Create gc clip-mask on demand */
|
||||
if (mAlphaBits && IsFlagSet(nsImageUpdateFlags_kBitsChanged, mFlags)) {
|
||||
|
||||
dpy = mDisplay;
|
||||
visual = drawing->GetVisual();
|
||||
if (!mAlphaPixmap)
|
||||
mAlphaPixmap = XCreatePixmap(mDisplay, DefaultRootWindow(mDisplay),
|
||||
aWidth, aHeight, 1);
|
||||
|
||||
x_image = XCreateImage(dpy, visual, 1, XYPixmap, 0, (char *)mAlphaBits,
|
||||
aWidth, aHeight, 32, mAlphaRowBytes);
|
||||
// Make an image out of the alpha-bits created by the image library
|
||||
x_image = XCreateImage(mDisplay, xlib_rgb_get_visual(),
|
||||
1, /* visual depth...1 for bitmaps */
|
||||
XYPixmap,
|
||||
0, /* x offset, XXX fix this */
|
||||
(char *)mAlphaBits, /* cast away our sign. */
|
||||
aWidth,
|
||||
aHeight,
|
||||
32, /* bitmap pad */
|
||||
mAlphaRowBytes); /* bytes per line */
|
||||
|
||||
x_image->bits_per_pixel=1;
|
||||
x_image->bitmap_bit_order = MSBFirst;
|
||||
x_image->byte_order = MSBFirst;
|
||||
|
||||
/* Image library always places pixels left-to-right MSB to LSB */
|
||||
x_image->bitmap_bit_order = MSBFirst;
|
||||
|
||||
/* This definition doesn't depend on client byte ordering
|
||||
because the image library ensures that the bytes in
|
||||
bitmask data are arranged left to right on the screen,
|
||||
low to high address in memory. */
|
||||
x_image->byte_order = MSBFirst;
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
// no, it's still MSB XXX check on this!!
|
||||
// x_image->byte_order = LSBFirst;
|
||||
#elif defined (IS_BIG_ENDIAN)
|
||||
x_image->byte_order = MSBFirst;
|
||||
#else
|
||||
#error ERROR! Endianness is unknown;
|
||||
#endif
|
||||
|
||||
/* Copy the XImage to mAlphaPixmap */
|
||||
if (!s1bitGC) {
|
||||
memset(&gcv, 0, sizeof(XGCValues));
|
||||
gcv.function = GXcopy;
|
||||
gc = XCreateGC(dpy, mAlphaPixmap, GCFunction, &gcv);
|
||||
XPutImage(dpy, mAlphaPixmap,
|
||||
gc,
|
||||
x_image,
|
||||
0,0,0,0,
|
||||
aWidth, aHeight);
|
||||
XFreeGC(dpy, gc);
|
||||
s1bitGC = XCreateGC(mDisplay, mAlphaPixmap, GCFunction, &gcv);
|
||||
}
|
||||
|
||||
// done with the temp image
|
||||
x_image->data = 0; //Don't free the IL_Pixmap's bits
|
||||
XPutImage(mDisplay, mAlphaPixmap, s1bitGC, x_image, 0, 0, 0, 0,
|
||||
aWidth, aHeight);
|
||||
|
||||
/* Now we are done with the temporary image */
|
||||
x_image->data = 0; /* Don't free the IL_Pixmap's bits. */
|
||||
XDestroyImage(x_image);
|
||||
}
|
||||
}
|
||||
|
||||
void nsImageXlib::CreateOffscreenPixmap(PRInt32 aWidth, PRInt32 aHeight,
|
||||
nsDrawingSurface aDrawing)
|
||||
void nsImageXlib::CreateOffscreenPixmap(PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
if (mImagePixmap == nsnull)
|
||||
{
|
||||
nsDrawingSurfaceXlib *drawing = (nsDrawingSurfaceXlib*)aDrawing;
|
||||
if (mImagePixmap == nsnull) {
|
||||
if (mDisplay == nsnull)
|
||||
mDisplay = drawing->GetDisplay();
|
||||
mDisplay = xlib_rgb_get_display();
|
||||
|
||||
mImagePixmap = XCreatePixmap(mDisplay,
|
||||
RootWindow(mDisplay, drawing->GetScreenNumber()),
|
||||
aWidth,
|
||||
aHeight,
|
||||
drawing->GetDepth());
|
||||
XSetClipOrigin(mDisplay, drawing->GetGC(), 0, 0);
|
||||
XSetClipMask(mDisplay, drawing->GetGC(), None);
|
||||
mImagePixmap = XCreatePixmap(mDisplay, DefaultRootWindow(mDisplay),
|
||||
aWidth, aHeight,
|
||||
xlib_rgb_get_depth());
|
||||
}
|
||||
}
|
||||
|
||||
void nsImageXlib::DrawImageOffscreen(PRInt32 validX, PRInt32 validY,
|
||||
PRInt32 validWidth, PRInt32 validHeight,
|
||||
nsDrawingSurface aDrawing)
|
||||
void nsImageXlib::DrawImageOffscreen(PRInt32 aSX, PRInt32 aSY,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
nsDrawingSurfaceXlib *drawing = (nsDrawingSurfaceXlib*)aDrawing;
|
||||
|
||||
xlib_draw_rgb_image(mImagePixmap,
|
||||
drawing->GetGC(),
|
||||
validX, validY, validWidth, validHeight,
|
||||
if (IsFlagSet(nsImageUpdateFlags_kBitsChanged, mFlags)) {
|
||||
printf("draw_image_off_screen: %p\n", this);
|
||||
if (!sXbitGC) {
|
||||
printf("no sXbit gc\n");
|
||||
XGCValues gcv;
|
||||
gcv.function = GXcopy;
|
||||
sXbitGC = XCreateGC(mDisplay, DefaultRootWindow(mDisplay),
|
||||
GCFunction, &gcv);
|
||||
}
|
||||
xlib_draw_rgb_image(mImagePixmap, sXbitGC,
|
||||
aSX, aSY, aWidth, aHeight,
|
||||
XLIB_RGB_DITHER_MAX,
|
||||
mImageBits, mRowBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void nsImageXlib::SetupGCForAlpha(GC aGC, PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
@ -779,9 +1013,13 @@ void nsImageXlib::SetupGCForAlpha(GC aGC, PRInt32 aX, PRInt32 aY)
|
||||
unsigned long xvalues_mask = 0;
|
||||
xvalues.clip_x_origin = aX;
|
||||
xvalues.clip_y_origin = aY;
|
||||
xvalues.clip_mask = mAlphaPixmap;
|
||||
xvalues_mask = GCClipXOrigin | GCClipYOrigin | GCClipMask;
|
||||
xvalues_mask = GCClipXOrigin | GCClipYOrigin;
|
||||
xvalues.function = GXcopy;
|
||||
|
||||
if (IsFlagSet(nsImageUpdateFlags_kBitsChanged, mFlags)) {
|
||||
xvalues.clip_mask = mAlphaPixmap;
|
||||
xvalues_mask |= GCClipMask;
|
||||
}
|
||||
XChangeGC(mDisplay, aGC, xvalues_mask, &xvalues);
|
||||
}
|
||||
}
|
||||
@ -796,14 +1034,13 @@ nsImageXlib::Draw(nsIRenderingContext &aContext,
|
||||
if (aSurface == nsnull)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (mAlphaDepth == 8)
|
||||
{
|
||||
DrawComposited(aContext, aSurface, aX, aY, aWidth, aHeight);
|
||||
if ((mAlphaDepth == 8) && mAlphaValid) {
|
||||
DrawComposited(aContext, aSurface, 0, 0, aX, aY, aWidth, aHeight);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if ((aWidth != mWidth) || (aHeight != mHeight))
|
||||
{
|
||||
// XXX it is said that this is temporary code
|
||||
if ((aWidth != mWidth) || (aHeight != mHeight)) {
|
||||
aWidth = mWidth;
|
||||
aHeight = mHeight;
|
||||
}
|
||||
@ -834,29 +1071,40 @@ nsImageXlib::Draw(nsIRenderingContext &aContext,
|
||||
validX = mDecodedX1;
|
||||
}
|
||||
|
||||
CreateAlphaBitmap(validWidth, validHeight, aSurface);
|
||||
|
||||
CreateOffscreenPixmap(validWidth, validHeight, aSurface);
|
||||
DrawImageOffscreen(validX, validY, validWidth, validHeight, aSurface);
|
||||
CreateAlphaBitmap(aWidth, aHeight);
|
||||
|
||||
GC copyGC;
|
||||
if (mAlphaPixmap)
|
||||
{
|
||||
copyGC = XCreateGC(mDisplay, drawing->GetDrawable(), 0, NULL);
|
||||
XCopyGC(mDisplay, drawing->GetGC(), 0xffffffff, copyGC);
|
||||
xGC *gc = ((nsRenderingContextXlib&)aContext).GetGC();
|
||||
|
||||
if (mAlphaPixmap) {
|
||||
if (mGC) { /* reuse GC */
|
||||
copyGC = mGC;
|
||||
SetupGCForAlpha(copyGC, aX, aY);
|
||||
} else
|
||||
{
|
||||
copyGC = drawing->GetGC();
|
||||
} else { /* make a new one */
|
||||
/* this repeats things done in SetupGCForAlpha */
|
||||
XGCValues xvalues;
|
||||
memset(&xvalues, 0, sizeof(XGCValues));
|
||||
unsigned long xvalues_mask = 0;
|
||||
xvalues.clip_x_origin = aX;
|
||||
xvalues.clip_y_origin = aY;
|
||||
if (IsFlagSet(nsImageUpdateFlags_kBitsChanged, mFlags)) {
|
||||
xvalues_mask = GCClipXOrigin | GCClipYOrigin | GCClipMask;
|
||||
xvalues.clip_mask = mAlphaPixmap;
|
||||
}
|
||||
mGC = XCreateGC(mDisplay, drawing->GetDrawable(), xvalues_mask , &xvalues);
|
||||
copyGC = mGC;
|
||||
}
|
||||
} else { /* !mAlphaPixmap */
|
||||
copyGC = *gc;
|
||||
}
|
||||
|
||||
XCopyArea(mDisplay, mImagePixmap, drawing->GetDrawable(),
|
||||
copyGC, validX, validY,
|
||||
validWidth, validHeight,
|
||||
aX, aY);
|
||||
validX + aX, validY + aY);
|
||||
|
||||
gc->Release();
|
||||
|
||||
if (mAlphaPixmap)
|
||||
XFreeGC(mDisplay, copyGC);
|
||||
mFlags = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -876,9 +1124,13 @@ void nsImageXlib::TilePixmap(Pixmap src, Pixmap dest, PRInt32 aSXOffset,
|
||||
valuesMask = GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle;
|
||||
gc = XCreateGC(mDisplay, src, valuesMask, &values);
|
||||
|
||||
if (useClip)
|
||||
{
|
||||
// FIXME: set the clipping area here
|
||||
if (useClip) {
|
||||
XRectangle xrectangle;
|
||||
xrectangle.x = clipRect.x;
|
||||
xrectangle.y = clipRect.y;
|
||||
xrectangle.width = clipRect.width;
|
||||
xrectangle.height = clipRect.height;
|
||||
XSetClipRectangles(mDisplay, gc, 0, 0, &xrectangle, 1, Unsorted);
|
||||
}
|
||||
|
||||
XFillRectangle(mDisplay, dest, gc, destRect.x, destRect.y,
|
||||
@ -892,15 +1144,109 @@ NS_IMETHODIMP nsImageXlib::DrawTile(nsIRenderingContext &aContext,
|
||||
nsRect &aSrcRect,
|
||||
nsRect &aTileRect)
|
||||
{
|
||||
nsDrawingSurfaceXlib *drawing = (nsDrawingSurfaceXlib*)aSurface;
|
||||
PRBool partial = PR_FALSE;
|
||||
|
||||
PRInt32
|
||||
aY0 = aTileRect.y,
|
||||
validX = 0,
|
||||
validY = 0,
|
||||
validWidth = mWidth,
|
||||
validHeight = mHeight;
|
||||
|
||||
// limit the image rectangle to the size of the image data which
|
||||
// has been validated.
|
||||
if (mDecodedY2 < mHeight) {
|
||||
validHeight = mDecodedY2 - mDecodedY1;
|
||||
partial = PR_TRUE;
|
||||
}
|
||||
if (mDecodedX2 < mWidth) {
|
||||
validWidth = mDecodedX2 - mDecodedX1;
|
||||
partial = PR_TRUE;
|
||||
}
|
||||
if (mDecodedY1 > 0) {
|
||||
validHeight -= mDecodedY1;
|
||||
validY = mDecodedY1;
|
||||
partial = PR_TRUE;
|
||||
}
|
||||
if (mDecodedX1 > 0) {
|
||||
validWidth -= mDecodedX1;
|
||||
validX = mDecodedX1;
|
||||
partial = PR_TRUE;
|
||||
}
|
||||
|
||||
if (partial ||
|
||||
(drawing->GetDepth() == 8) ||
|
||||
((mAlphaDepth == 8) && mAlphaValid)) {
|
||||
#ifdef DEBUG_TILING
|
||||
printf("Warning: using slow tiling\n");
|
||||
#endif
|
||||
PRInt32 aY0 = aTileRect.y,
|
||||
aX0 = aTileRect.x,
|
||||
aY1 = aTileRect.y + aTileRect.height,
|
||||
aX1 = aTileRect.x + aTileRect.width;
|
||||
|
||||
for (PRInt32 y = aY0; y < aY1; y+=aSrcRect.height)
|
||||
for (PRInt32 x = aX0; x < aX1; x+=aSrcRect.width)
|
||||
Draw(aContext, aSurface, x, y, aSrcRect.width, aSrcRect.height);
|
||||
Draw(aContext,aSurface,x,y,
|
||||
PR_MIN(aSrcRect.width, aX1-x),
|
||||
PR_MIN(aSrcRect.height, aY1-y));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* draw the tile offscreen */
|
||||
CreateOffscreenPixmap(mWidth, mHeight);
|
||||
/* XXX Why? DrawImageOffscreen(0, 0, validWidth, validHeight); */
|
||||
|
||||
if (mAlphaDepth == 1) {
|
||||
Pixmap tileImg;
|
||||
Pixmap tileMask;
|
||||
|
||||
CreateAlphaBitmap(validWidth, validHeight);
|
||||
|
||||
nsRect tmpRect(0,0,aTileRect.width, aTileRect.height);
|
||||
|
||||
tileImg = XCreatePixmap(mDisplay, mImagePixmap,
|
||||
aTileRect.width, aTileRect.height,
|
||||
mDepth);
|
||||
|
||||
TilePixmap(mImagePixmap, tileImg, 0, 0, tmpRect, tmpRect, PR_FALSE);
|
||||
|
||||
// tile alpha mask
|
||||
tileMask = XCreatePixmap(mDisplay, mAlphaPixmap,
|
||||
aTileRect.width, aTileRect.height, mAlphaDepth);
|
||||
|
||||
TilePixmap(mAlphaPixmap, tileMask, 0, 0, tmpRect, tmpRect, PR_FALSE);
|
||||
|
||||
GC fgc;
|
||||
XGCValues values;
|
||||
unsigned long valuesMask;
|
||||
|
||||
memset(&values, 0, sizeof(XGCValues));
|
||||
values.clip_mask = tileMask;
|
||||
values.clip_x_origin = aTileRect.x;
|
||||
values.clip_y_origin = aTileRect.y;
|
||||
valuesMask = GCClipXOrigin | GCClipYOrigin | GCClipMask;
|
||||
fgc = XCreateGC(mDisplay, drawing->GetDrawable(), valuesMask, &values);
|
||||
|
||||
// and copy it back
|
||||
XCopyArea(mDisplay, tileImg, drawing->GetDrawable(),
|
||||
fgc, 0,0,
|
||||
aTileRect.width, aTileRect.height,
|
||||
aTileRect.x, aTileRect.y);
|
||||
|
||||
XFreePixmap(mDisplay, tileImg);
|
||||
XFreePixmap(mDisplay, tileMask);
|
||||
XFreeGC(mDisplay, fgc);
|
||||
|
||||
} else {
|
||||
// In the non-alpha case, ??? can tile for us
|
||||
|
||||
nsRect clipRect;
|
||||
PRBool isValid;
|
||||
aContext.GetClipRect(clipRect, isValid);
|
||||
TilePixmap(mImagePixmap, drawing->GetDrawable(), aTileRect.x, aTileRect.y, aTileRect, clipRect, PR_TRUE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -910,10 +1256,11 @@ NS_IMETHODIMP nsImageXlib::DrawTile(nsIRenderingContext &aContext,
|
||||
const nsRect &aTileRect)
|
||||
{
|
||||
nsDrawingSurfaceXlib *drawing = (nsDrawingSurfaceXlib*)aSurface;
|
||||
|
||||
if (mDisplay == nsnull)
|
||||
mDisplay = drawing->GetDisplay();
|
||||
|
||||
PRBool partial = PR_FALSE;
|
||||
|
||||
PRInt32
|
||||
validX = 0,
|
||||
validY = 0,
|
||||
@ -921,23 +1268,26 @@ NS_IMETHODIMP nsImageXlib::DrawTile(nsIRenderingContext &aContext,
|
||||
validHeight = mHeight;
|
||||
|
||||
// limit the image rectangle to the size of the image data which
|
||||
// has been validated.
|
||||
if ((mDecodedY2 < mHeight)) {
|
||||
if (mDecodedY2 < mHeight) {
|
||||
validHeight = mDecodedY2 - mDecodedY1;
|
||||
partial = PR_TRUE;
|
||||
}
|
||||
if ((mDecodedX2 < mWidth)) {
|
||||
if (mDecodedX2 < mWidth) {
|
||||
validWidth = mDecodedX2 - mDecodedX1;
|
||||
partial = PR_TRUE;
|
||||
}
|
||||
if ((mDecodedY1 > 0)) {
|
||||
if (mDecodedY1 > 0) {
|
||||
validHeight -= mDecodedY1;
|
||||
validY = mDecodedY1;
|
||||
partial = PR_TRUE;
|
||||
}
|
||||
if ((mDecodedX1 > 0)) {
|
||||
if (mDecodedX1 > 0) {
|
||||
validWidth -= mDecodedX1;
|
||||
validX = mDecodedX1;
|
||||
partial = PR_TRUE;
|
||||
}
|
||||
|
||||
if (mAlphaDepth == 8) {
|
||||
if (partial || ((mAlphaDepth == 8) && mAlphaValid)) {
|
||||
PRInt32 aY0 = aTileRect.y - aSYOffset,
|
||||
aX0 = aTileRect.x - aSXOffset,
|
||||
aY1 = aTileRect.y + aTileRect.height,
|
||||
@ -958,15 +1308,15 @@ NS_IMETHODIMP nsImageXlib::DrawTile(nsIRenderingContext &aContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
CreateOffscreenPixmap(validWidth, validHeight, aSurface);
|
||||
DrawImageOffscreen(validX, validY, validWidth, validHeight, aSurface);
|
||||
CreateOffscreenPixmap(mWidth, mHeight);
|
||||
/* XXX Why? DrawImageOffscreen(validX, validY, validWidth, validHeight); */
|
||||
|
||||
if (mAlphaDepth == 1)
|
||||
{
|
||||
Pixmap tileImg;
|
||||
Pixmap tileMask;
|
||||
|
||||
CreateAlphaBitmap(validWidth, validHeight, aSurface);
|
||||
CreateAlphaBitmap(validWidth, validHeight);
|
||||
|
||||
nsRect tmpRect(0,0,aTileRect.width, aTileRect.height);
|
||||
|
||||
@ -1001,8 +1351,9 @@ NS_IMETHODIMP nsImageXlib::DrawTile(nsIRenderingContext &aContext,
|
||||
XFreePixmap(mDisplay, tileImg);
|
||||
XFreePixmap(mDisplay, tileMask);
|
||||
XFreeGC(mDisplay, fgc);
|
||||
} else
|
||||
{
|
||||
|
||||
} else {
|
||||
|
||||
nsRect clipRect;
|
||||
PRBool isValid;
|
||||
|
||||
@ -1048,6 +1399,17 @@ nsImageXlib::SetDecodedRect(PRInt32 x1, PRInt32 y1, PRInt32 x2, PRInt32 y2)
|
||||
mDecodedY1 = y1;
|
||||
mDecodedX2 = x2;
|
||||
mDecodedY2 = y2;
|
||||
|
||||
// check if the image has an all-opaque 8-bit alpha mask
|
||||
if ((mAlphaDepth==8) && !mAlphaValid) {
|
||||
for (int y=mDecodedY1; y<mDecodedY2; y++) {
|
||||
unsigned char *alpha = mAlphaBits + mAlphaRowBytes*y + mDecodedX1;
|
||||
for (int x=mDecodedX1; x<mDecodedX2; x++)
|
||||
if (*(alpha++)!=255) {
|
||||
mAlphaValid=PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1056,32 +1418,26 @@ NS_IMETHODIMP nsImageXlib::DrawToImage(nsIImage* aDstImage,
|
||||
nscoord aDX, nscoord aDY,
|
||||
nscoord aDWidth, nscoord aDHeight)
|
||||
{
|
||||
#if 0
|
||||
// XXX This is a copy of the GTK version, partially converted for
|
||||
// the xlib port. I can't figure out how to finish it.
|
||||
nsImageXlib *dest = NS_STATIC_CAST(nsImageXlib *, aDstImage);
|
||||
if (!dest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsDrawingSurfaceXlib *drawing = /* XXX What should this be!?!?! */ nsnull;
|
||||
NS_ENSURE_TRUE(drawing, NS_ERROR_FAILURE);
|
||||
|
||||
if (!dest->mImagePixmap)
|
||||
dest->CreateOffscreenPixmap(dest->mWidth, dest->mHeight, drawing);
|
||||
dest->CreateOffscreenPixmap(dest->mWidth, dest->mHeight);
|
||||
|
||||
if (!dest->mImagePixmap || !mImagePixmap)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mDisplay)
|
||||
mDisplay = drawing->GetDisplay();
|
||||
mDisplay = xlib_rgb_get_display();
|
||||
|
||||
GC gc = XCreateGC(mDisplay, dest->mImagePixmap, 0, NULL);
|
||||
|
||||
if (mAlphaDepth == 1)
|
||||
CreateAlphaBitmap(mWidth, mHeight, drawing);
|
||||
CreateAlphaBitmap(mWidth, mHeight);
|
||||
|
||||
if (mAlphaPixmap) {
|
||||
if (mAlphaPixmap)
|
||||
SetupGCForAlpha(gc, 0, 0);
|
||||
}
|
||||
|
||||
XCopyArea(dest->mDisplay, mImagePixmap, dest->mImagePixmap, gc,
|
||||
0, 0, mWidth, mHeight, aDX, aDY);
|
||||
@ -1089,9 +1445,5 @@ NS_IMETHODIMP nsImageXlib::DrawToImage(nsIImage* aDstImage,
|
||||
XFreeGC(mDisplay, gc);
|
||||
|
||||
return NS_OK;
|
||||
#else
|
||||
NS_NOTREACHED("nsImageXlib::DrawToImage not yet implemented");
|
||||
return NS_ERROR_FAILURE;
|
||||
#endif
|
||||
}
|
||||
#endif // USE_IMG2
|
||||
|
@ -25,11 +25,12 @@
|
||||
#define nsImageXlib_h__
|
||||
|
||||
#include "nsIImage.h"
|
||||
#include "nsGCCache.h"
|
||||
|
||||
#include "X11/Xlib.h"
|
||||
#include "X11/Xutil.h"
|
||||
#include "X11/Xos.h"
|
||||
class nsDrawingSurfaceXlib;
|
||||
// class nsDrawingSurfaceXlib;
|
||||
|
||||
class nsImageXlib : public nsIImage {
|
||||
public:
|
||||
@ -122,6 +123,10 @@ private:
|
||||
void ComputePaletteSize(PRIntn nBitCount);
|
||||
|
||||
private:
|
||||
NS_IMETHODIMP DrawScaled(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
|
||||
|
||||
static unsigned scaled6[1<<6];
|
||||
static unsigned scaled5[1<<5];
|
||||
|
||||
@ -143,18 +148,16 @@ private:
|
||||
XImage *ximage, unsigned char *readData);
|
||||
inline void DrawComposited(nsIRenderingContext &aContext,
|
||||
nsDrawingSurface aSurface,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aSX, PRInt32 aSY,
|
||||
PRInt32 aDX, PRInt32 aDY,
|
||||
PRInt32 aWidth, PRInt32 aHeight);
|
||||
|
||||
inline void TilePixmap(Pixmap src, Pixmap dest, PRInt32 aSXOffset, PRInt32 aSYOffset,
|
||||
const nsRect &destRect, const nsRect &clipRect, PRBool useClip);
|
||||
inline void CreateAlphaBitmap(PRInt32 aWidth, PRInt32 aHeight,
|
||||
nsDrawingSurface aSurface);
|
||||
inline void CreateOffscreenPixmap(PRInt32 aWidth, PRInt32 aHeight,
|
||||
nsDrawingSurface aSurface);
|
||||
inline void DrawImageOffscreen(PRInt32 validX, PRInt32 validY,
|
||||
PRInt32 validWidth, PRInt32 validHeight,
|
||||
nsDrawingSurface aSurface);
|
||||
inline void CreateAlphaBitmap(PRInt32 aWidth, PRInt32 aHeight);
|
||||
inline void CreateOffscreenPixmap(PRInt32 aWidth, PRInt32 aHeight);
|
||||
inline void DrawImageOffscreen(PRInt32 aSX, PRInt32 aSY,
|
||||
PRInt32 aWidth, PRInt32 aHeight);
|
||||
inline void SetupGCForAlpha(GC aGC, PRInt32 aX, PRInt32 aY);
|
||||
|
||||
PRInt32 mWidth;
|
||||
@ -162,7 +165,9 @@ private:
|
||||
PRInt32 mDepth; // bits per pixel
|
||||
PRInt32 mRowBytes;
|
||||
PRUint8 *mImageBits;
|
||||
PRUint8 *mConvertedBits;
|
||||
GC mGC;
|
||||
|
||||
//PRUint8 *mConvertedBits;
|
||||
PRInt32 mSizeImage;
|
||||
PRBool mIsTopToBottom;
|
||||
|
||||
@ -183,7 +188,7 @@ private:
|
||||
PRInt16 mAlphaRowBytes; // alpha bytes per row
|
||||
PRInt16 mAlphaWidth; // alpha layer width
|
||||
PRInt16 mAlphaHeight; // alpha layer height
|
||||
nsPoint mLocation; // alpha mask location
|
||||
PRPackedBool mAlphaValid;
|
||||
Pixmap mImagePixmap;
|
||||
Display *mDisplay;
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
* Peter Hartshorn <peter@igelaus.com.au>
|
||||
* Ken Faulkner <faulkner@igelaus.com.au>
|
||||
* Tony Tsui <tony@igelaus.com.au>
|
||||
* Tomi Leppikangas <tomi.leppikangas@oulu.fi>
|
||||
*/
|
||||
|
||||
#include "nsRenderingContextXlib.h"
|
||||
@ -29,11 +30,14 @@
|
||||
#include "xlibrgb.h"
|
||||
#include "prprf.h"
|
||||
#include "prmem.h"
|
||||
#include "nsGCCache.h"
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsRenderingContextXlib, nsIRenderingContext)
|
||||
|
||||
static PRLogModuleInfo * RenderingContextXlibLM = PR_NewLogModule("RenderingContextXlib");
|
||||
|
||||
static nsGCCache *gcCache = nsnull;
|
||||
|
||||
class GraphicsState
|
||||
{
|
||||
public:
|
||||
@ -83,6 +87,9 @@ nsRenderingContextXlib::nsRenderingContextXlib()
|
||||
mScreen = nsnull;
|
||||
mVisual = nsnull;
|
||||
mDepth = 0;
|
||||
mGC = nsnull;
|
||||
|
||||
mFunction = GXcopy;
|
||||
|
||||
PushState();
|
||||
}
|
||||
@ -102,11 +109,15 @@ nsRenderingContextXlib::~nsRenderingContextXlib()
|
||||
delete mStateCache;
|
||||
mStateCache = nsnull;
|
||||
}
|
||||
|
||||
if (mTranMatrix)
|
||||
delete mTranMatrix;
|
||||
NS_IF_RELEASE(mOffscreenSurface);
|
||||
NS_IF_RELEASE(mFontMetrics);
|
||||
NS_IF_RELEASE(mContext);
|
||||
|
||||
if(nsnull != mGC)
|
||||
mGC->Release();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -126,14 +137,15 @@ nsRenderingContextXlib::Init(nsIDeviceContext* aContext, nsIWidget *aWindow)
|
||||
mRenderingSurface = (nsDrawingSurfaceXlib *)new nsDrawingSurfaceXlib();
|
||||
|
||||
if (mRenderingSurface) {
|
||||
|
||||
Drawable win = (Drawable)aWindow->GetNativeData(NS_NATIVE_WINDOW);
|
||||
GC gc = (GC)aWindow->GetNativeData(NS_NATIVE_GRAPHIC);
|
||||
xGC *gc = (xGC*)aWindow->GetNativeData(NS_NATIVE_GRAPHIC);
|
||||
|
||||
mRenderingSurface->Init(mDisplay,
|
||||
mScreen,
|
||||
mVisual,
|
||||
mDepth,
|
||||
win,
|
||||
(PRUint32)win,
|
||||
gc);
|
||||
|
||||
mOffscreenSurface = mRenderingSurface;
|
||||
@ -142,6 +154,13 @@ nsRenderingContextXlib::Init(nsIDeviceContext* aContext, nsIWidget *aWindow)
|
||||
return (CommonInit());
|
||||
}
|
||||
|
||||
/*static*/ nsresult
|
||||
nsRenderingContextXlib::Shutdown()
|
||||
{
|
||||
delete gcCache;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRenderingContextXlib::Init(nsIDeviceContext* aContext, nsDrawingSurface aSurface)
|
||||
{
|
||||
@ -330,12 +349,6 @@ nsRenderingContextXlib::PopState(PRBool &aClipState)
|
||||
if (mFontMetrics != state->mFontMetrics)
|
||||
SetFont(state->mFontMetrics);
|
||||
|
||||
if (mRenderingSurface && mClipRegion) {
|
||||
Region region;
|
||||
mClipRegion->GetNativeRegion((void *&)region);
|
||||
XSetRegion(mDisplay, mRenderingSurface->GetGC(), region);
|
||||
}
|
||||
|
||||
if (state->mColor != mCurrentColor)
|
||||
SetColor(state->mColor);
|
||||
if (state->mLineStyle != mCurrentLineStyle)
|
||||
@ -351,6 +364,50 @@ nsRenderingContextXlib::PopState(PRBool &aClipState)
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
void nsRenderingContextXlib::UpdateGC()
|
||||
{
|
||||
XGCValues values;
|
||||
unsigned long valuesMask;
|
||||
|
||||
if (mGC)
|
||||
mGC->Release();
|
||||
|
||||
memset(&values, 0, sizeof(XGCValues));
|
||||
|
||||
unsigned long color;
|
||||
|
||||
color = xlib_rgb_xpixel_from_rgb (NS_RGB(NS_GET_B(mCurrentColor),
|
||||
NS_GET_G(mCurrentColor),
|
||||
NS_GET_R(mCurrentColor)));
|
||||
|
||||
values.foreground =color;
|
||||
valuesMask = GCForeground;
|
||||
|
||||
if (mCurrentFont) {
|
||||
valuesMask |= GCFont;
|
||||
values.font = mCurrentFont->fid;
|
||||
}
|
||||
|
||||
values.line_style = mLineStyle;
|
||||
valuesMask |= GCLineStyle;
|
||||
|
||||
values.function = mFunction;
|
||||
valuesMask |= GCFunction;
|
||||
|
||||
Region rgn = 0;
|
||||
if (mClipRegion) {
|
||||
mClipRegion->GetNativeRegion((void*&)rgn);
|
||||
}
|
||||
|
||||
if (!gcCache) {
|
||||
gcCache = new nsGCCache();
|
||||
if (!gcCache) return;
|
||||
}
|
||||
|
||||
mGC = gcCache->GetGC(mDisplay, mRenderingSurface->GetDrawable(),
|
||||
valuesMask, &values,
|
||||
rgn);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRenderingContextXlib::IsVisibleRect(const nsRect& aRect, PRBool &aVisible)
|
||||
@ -384,9 +441,6 @@ nsRenderingContextXlib::SetClipRect(const nsRect& aRect, nsClipCombine aCombine,
|
||||
}
|
||||
aClipState = mClipRegion->IsEmpty();
|
||||
|
||||
mClipRegion->GetNativeRegion((void*&)rgn);
|
||||
XSetRegion(mDisplay, mRenderingSurface->GetGC(), rgn);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -428,8 +482,6 @@ nsRenderingContextXlib::SetClipRegion(const nsIRegion& aRegion, nsClipCombine aC
|
||||
}
|
||||
|
||||
aClipState = mClipRegion->IsEmpty();
|
||||
mClipRegion->GetNativeRegion((void*&)rgn);
|
||||
XSetRegion(mDisplay, mRenderingSurface->GetGC(),rgn);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -461,36 +513,28 @@ nsRenderingContextXlib::SetLineStyle(nsLineStyle aLineStyle)
|
||||
{
|
||||
PR_LOG(RenderingContextXlibLM, PR_LOG_DEBUG, ("nsRenderingContextXlib::SetLineStyle()\n"));
|
||||
if (aLineStyle != mCurrentLineStyle) {
|
||||
/* XXX this isnt done in gtk, copy from there when ready
|
||||
switch(aLineStyle)
|
||||
{
|
||||
case nsLineStyle_kSolid:
|
||||
XSetLineAttributes(mDisplay, mRenderingSurface->GetGC(),
|
||||
1, // width
|
||||
LineSolid, // line style
|
||||
CapNotLast,// cap style
|
||||
JoinMiter);// join style
|
||||
mLineStyle = LineSolid;
|
||||
mDashes = 0;
|
||||
break;
|
||||
case nsLineStyle_kDashed:
|
||||
{
|
||||
static char dashed[2] = {4,4};
|
||||
XSetDashes(mDisplay, mRenderingSurface->GetGC(),
|
||||
0, dashed, 2);
|
||||
}
|
||||
mDashList = dashed;
|
||||
mDashes = 2;
|
||||
break;
|
||||
|
||||
case nsLineStyle_kDotted:
|
||||
{
|
||||
static char dotted[2] = {3,1};
|
||||
XSetDashes(mDisplay, mRenderingSurface->GetGC(),
|
||||
0, dotted, 2);
|
||||
}
|
||||
mDashList = dotted;
|
||||
mDashes = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
mCurrentLineStyle = aLineStyle ;
|
||||
}
|
||||
return NS_OK;
|
||||
@ -512,9 +556,7 @@ nsRenderingContextXlib::SetColor(nscolor aColor)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mCurrentColor = aColor;
|
||||
xlib_rgb_gc_set_foreground(mRenderingSurface->GetGC(), NS_RGB(NS_GET_B(aColor),
|
||||
NS_GET_G(aColor),
|
||||
NS_GET_R(aColor)));
|
||||
|
||||
PR_LOG(RenderingContextXlibLM, PR_LOG_DEBUG, ("Setting color to %d %d %d\n", NS_GET_R(aColor), NS_GET_G(aColor), NS_GET_B(aColor)));
|
||||
return NS_OK;
|
||||
}
|
||||
@ -550,7 +592,6 @@ nsRenderingContextXlib::SetFont(nsIFontMetrics *aFontMetrics)
|
||||
nsFontHandle fontHandle;
|
||||
mFontMetrics->GetFontHandle(fontHandle);
|
||||
mCurrentFont = (XFontStruct *)fontHandle;
|
||||
XSetFont(mDisplay, mRenderingSurface->GetGC(), mCurrentFont->fid);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -601,12 +642,13 @@ nsRenderingContextXlib::CreateDrawingSurface(nsRect *aBounds, PRUint32 aSurfFlag
|
||||
|
||||
if (surf) {
|
||||
NS_ADDREF(surf);
|
||||
|
||||
if (!mGC)
|
||||
UpdateGC();
|
||||
surf->Init(mDisplay,
|
||||
mScreen,
|
||||
mVisual,
|
||||
mDepth,
|
||||
mRenderingSurface->GetGC(),
|
||||
mGC,
|
||||
aBounds->width,
|
||||
aBounds->height,
|
||||
aSurfFlags);
|
||||
@ -650,8 +692,10 @@ nsRenderingContextXlib::DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord
|
||||
diffY = (diffY>0?1:-1);
|
||||
}
|
||||
|
||||
UpdateGC();
|
||||
|
||||
::XDrawLine(mDisplay, mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(), aX0, aY0, aX1 - diffX, aY1 - diffY);
|
||||
*mGC, aX0, aY0, aX1 - diffX, aY1 - diffY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -678,8 +722,9 @@ nsRenderingContextXlib::DrawStdLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoo
|
||||
diffY = (diffY>0?1:-1);
|
||||
}
|
||||
|
||||
UpdateGC();
|
||||
::XDrawLine(mDisplay, mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(), aX0, aY0, aX1 - diffX, aY1 - diffY);
|
||||
*mGC, aX0, aY0, aX1 - diffX, aY1 - diffY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -704,9 +749,10 @@ nsRenderingContextXlib::DrawPolyline(const nsPoint aPoints[], PRInt32 aNumPoints
|
||||
mTranMatrix->TransformCoord((PRInt32*)&thispoint->x,(PRInt32*)&thispoint->y);
|
||||
}
|
||||
|
||||
UpdateGC();
|
||||
::XDrawLines(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
xpoints, aNumPoints, CoordModeOrigin);
|
||||
|
||||
PR_Free((void *)xpoints);
|
||||
@ -738,13 +784,19 @@ nsRenderingContextXlib::DrawRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord
|
||||
|
||||
mTranMatrix->TransformCoord(&x,&y,&w,&h);
|
||||
|
||||
// After the transform, if the numbers are huge, chop them, because
|
||||
// they're going to be converted from 32 bit to 16 bit.
|
||||
// It's all way off the screen anyway.
|
||||
ConditionRect(x,y,w,h);
|
||||
|
||||
// Don't draw empty rectangles; also, w/h are adjusted down by one
|
||||
// so that the right number of pixels are drawn.
|
||||
if (w && h)
|
||||
{
|
||||
UpdateGC();
|
||||
::XDrawRectangle(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
x,
|
||||
y,
|
||||
w - 1,
|
||||
@ -775,11 +827,18 @@ nsRenderingContextXlib::FillRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord
|
||||
h = aHeight;
|
||||
|
||||
mTranMatrix->TransformCoord(&x,&y,&w,&h);
|
||||
|
||||
// After the transform, if the numbers are huge, chop them, because
|
||||
// they're going to be converted from 32 bit to 16 bit.
|
||||
// It's all way off the screen anyway.
|
||||
ConditionRect(x,y,w,h);
|
||||
|
||||
PR_LOG(RenderingContextXlibLM, PR_LOG_DEBUG, ("About to fill window 0x%lxd with rect %d %d %d %d\n",
|
||||
mRenderingSurface->GetDrawable(), x, y, w, h));
|
||||
UpdateGC();
|
||||
::XFillRectangle(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
x,y,w,h);
|
||||
|
||||
return NS_OK;
|
||||
@ -806,23 +865,24 @@ nsRenderingContextXlib :: InvertRect(nscoord aX, nscoord aY, nscoord aWidth, nsc
|
||||
|
||||
mTranMatrix->TransformCoord(&x,&y,&w,&h);
|
||||
|
||||
// Set XOR drawing mode
|
||||
::XSetFunction(mDisplay,
|
||||
mRenderingSurface->GetGC(),
|
||||
GXxor);
|
||||
// After the transform, if the numbers are huge, chop them, because
|
||||
// they're going to be converted from 32 bit to 16 bit.
|
||||
// It's all way off the screen anyway.
|
||||
ConditionRect(x,y,w,h);
|
||||
|
||||
mFunction = GXxor;
|
||||
|
||||
UpdateGC();
|
||||
|
||||
::XFillRectangle(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h);
|
||||
|
||||
// Back to normal copy drawing mode
|
||||
::XSetFunction(mDisplay,
|
||||
mRenderingSurface->GetGC(),
|
||||
GXcopy);
|
||||
mFunction = GXcopy;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -847,9 +907,10 @@ nsRenderingContextXlib::DrawPolygon(const nsPoint aPoints[], PRInt32 aNumPoints)
|
||||
mTranMatrix->TransformCoord((PRInt32*)&thispoint->x,(PRInt32*)&thispoint->y);
|
||||
}
|
||||
|
||||
UpdateGC();
|
||||
::XDrawLines(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
xpoints, aNumPoints, CoordModeOrigin);
|
||||
|
||||
PR_Free((void *)xpoints);
|
||||
@ -880,9 +941,10 @@ nsRenderingContextXlib::FillPolygon(const nsPoint aPoints[], PRInt32 aNumPoints)
|
||||
thispoint->y = y;
|
||||
}
|
||||
|
||||
UpdateGC();
|
||||
::XFillPolygon(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
xpoints, aNumPoints, Convex, CoordModeOrigin);
|
||||
|
||||
PR_Free((void *)xpoints);
|
||||
@ -913,9 +975,10 @@ nsRenderingContextXlib::DrawEllipse(nscoord aX, nscoord aY, nscoord aWidth, nsco
|
||||
|
||||
mTranMatrix->TransformCoord(&x,&y,&w,&h);
|
||||
|
||||
UpdateGC();
|
||||
::XDrawArc(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
x,y,w,h, 0, 360 * 64);
|
||||
|
||||
return NS_OK;
|
||||
@ -944,9 +1007,11 @@ nsRenderingContextXlib::FillEllipse(nscoord aX, nscoord aY, nscoord aWidth, nsco
|
||||
|
||||
mTranMatrix->TransformCoord(&x,&y,&w,&h);
|
||||
|
||||
UpdateGC();
|
||||
|
||||
::XFillArc(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
x,y,w,h, 0, 360 * 64);
|
||||
|
||||
return NS_OK;
|
||||
@ -977,9 +1042,10 @@ nsRenderingContextXlib::DrawArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord
|
||||
|
||||
mTranMatrix->TransformCoord(&x,&y,&w,&h);
|
||||
|
||||
UpdateGC();
|
||||
::XDrawArc(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
x,y,w,h, NSToIntRound(aStartAngle * 64.0f),
|
||||
NSToIntRound(aEndAngle * 64.0f));
|
||||
|
||||
@ -1011,9 +1077,10 @@ nsRenderingContextXlib::FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord
|
||||
|
||||
mTranMatrix->TransformCoord(&x,&y,&w,&h);
|
||||
|
||||
UpdateGC();
|
||||
::XFillArc(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
x,y,w,h, NSToIntRound(aStartAngle * 64.0f),
|
||||
NSToIntRound(aEndAngle * 64.0f));
|
||||
|
||||
@ -1156,6 +1223,8 @@ nsRenderingContextXlib::DrawString(const char *aString, PRUint32 aLength,
|
||||
y += aY;
|
||||
}
|
||||
|
||||
UpdateGC();
|
||||
|
||||
if (nsnull != aSpacing) {
|
||||
// Render the string, one character at a time...
|
||||
const char* end = aString + aLength;
|
||||
@ -1164,9 +1233,9 @@ nsRenderingContextXlib::DrawString(const char *aString, PRUint32 aLength,
|
||||
nscoord xx = x;
|
||||
nscoord yy = y;
|
||||
mTranMatrix->TransformCoord(&xx, &yy);
|
||||
XDrawString(mDisplay,
|
||||
::XDrawString(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
xx, yy, &ch, 1);
|
||||
x += *aSpacing++;
|
||||
}
|
||||
@ -1175,7 +1244,7 @@ nsRenderingContextXlib::DrawString(const char *aString, PRUint32 aLength,
|
||||
mTranMatrix->TransformCoord(&x, &y);
|
||||
XDrawString(mDisplay,
|
||||
mRenderingSurface->GetDrawable(),
|
||||
mRenderingSurface->GetGC(),
|
||||
*mGC,
|
||||
x, y, aString, aLength);
|
||||
}
|
||||
}
|
||||
@ -1267,6 +1336,7 @@ FoundFont:
|
||||
if (aSpacing) {
|
||||
const PRUnichar* str = &aString[start];
|
||||
const PRUnichar* end = &aString[i];
|
||||
UpdateGC();
|
||||
while (str < end) {
|
||||
x = aX;
|
||||
y = aY;
|
||||
@ -1277,6 +1347,7 @@ FoundFont:
|
||||
}
|
||||
}
|
||||
else {
|
||||
UpdateGC();
|
||||
prevFont->DrawString(this, mRenderingSurface, x, y, &aString[start], i - start);
|
||||
x += prevFont->GetWidth(&aString[start], i -start);
|
||||
|
||||
@ -1292,6 +1363,7 @@ FoundFont:
|
||||
}
|
||||
|
||||
if (prevFont) {
|
||||
UpdateGC();
|
||||
if (aSpacing) {
|
||||
const PRUnichar* str = &aString[start];
|
||||
const PRUnichar* end = &aString[i];
|
||||
@ -1358,6 +1430,7 @@ nsRenderingContextXlib::DrawImage(nsIImage *aImage, const nsRect& aRect)
|
||||
nsRect tr;
|
||||
tr = aRect;
|
||||
mTranMatrix->TransformCoord(&tr.x, &tr.y, &tr.width, &tr.height);
|
||||
UpdateGC();
|
||||
return aImage->Draw(*this, mRenderingSurface, tr.x, tr.y, tr.width, tr.height);
|
||||
}
|
||||
|
||||
@ -1377,6 +1450,7 @@ nsRenderingContextXlib::DrawImage(nsIImage *aImage, const nsRect& aSRect, const
|
||||
dr = aDRect;
|
||||
mTranMatrix->TransformCoord(&dr.x, &dr.y,
|
||||
&dr.width, &dr.height);
|
||||
UpdateGC();
|
||||
|
||||
return aImage->Draw(*this, mRenderingSurface,
|
||||
sr.x, sr.y,
|
||||
@ -1454,10 +1528,12 @@ nsRenderingContextXlib::CopyOffScreenBits(nsDrawingSurface aSrcSurf, PRInt32 aSr
|
||||
//XXX flags are unused. that would seem to mean that there is
|
||||
//inefficiency somewhere... MMP
|
||||
|
||||
UpdateGC();
|
||||
|
||||
XCopyArea(mDisplay,
|
||||
((nsDrawingSurfaceXlib *)aSrcSurf)->GetDrawable(),
|
||||
destsurf->GetDrawable(),
|
||||
((nsDrawingSurfaceXlib *)aSrcSurf)->GetGC(),
|
||||
*mGC,
|
||||
srcX, srcY,
|
||||
drect.width, drect.height,
|
||||
drect.x, drect.y);
|
||||
|
@ -41,6 +41,9 @@
|
||||
#include "nsDrawingSurfaceXlib.h"
|
||||
#include "nsRegionXlib.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsGCCache.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
class GraphicsState;
|
||||
|
||||
@ -49,6 +52,7 @@ class nsRenderingContextXlib : public nsRenderingContextImpl
|
||||
public:
|
||||
nsRenderingContextXlib();
|
||||
virtual ~nsRenderingContextXlib();
|
||||
static nsresult Shutdown(); // release statics
|
||||
|
||||
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
||||
|
||||
@ -197,7 +201,10 @@ class nsRenderingContextXlib : public nsRenderingContextImpl
|
||||
// this is a common init function for both of the init functions.
|
||||
nsresult CommonInit(void);
|
||||
|
||||
xGC *GetGC() { mGC->AddRef(); return mGC; }
|
||||
|
||||
private:
|
||||
void UpdateGC();
|
||||
nsDrawingSurfaceXlib *mOffscreenSurface;
|
||||
nsDrawingSurfaceXlib *mRenderingSurface;
|
||||
nsIDeviceContext *mContext;
|
||||
@ -214,6 +221,32 @@ private:
|
||||
nsVoidArray *mStateCache;
|
||||
XFontStruct *mCurrentFont;
|
||||
nsLineStyle mCurrentLineStyle;
|
||||
xGC *mGC;
|
||||
int mFunction;
|
||||
int mLineStyle;
|
||||
char *mDashList;
|
||||
int mDashes;
|
||||
|
||||
// ConditionRect is used to fix coordinate overflow problems for
|
||||
// rectangles after they are transformed to screen coordinates
|
||||
void ConditionRect(nscoord &x, nscoord &y, nscoord &w, nscoord &h) {
|
||||
if ( y < -32766 ) {
|
||||
y = -32766;
|
||||
}
|
||||
|
||||
if ( y + h > 32766 ) {
|
||||
h = 32766 - y;
|
||||
}
|
||||
|
||||
if ( x < -32766 ) {
|
||||
x = -32766;
|
||||
}
|
||||
|
||||
if ( x + w > 32766 ) {
|
||||
w = 32766 - x;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*-
|
||||
* vim:ts=2:et:sw=2
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
@ -31,6 +32,7 @@
|
||||
#include <errno.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/keysymdef.h>
|
||||
#include <X11/Xlocale.h>
|
||||
|
||||
#include "nsWindow.h"
|
||||
#include "nsWidget.h"
|
||||
@ -295,6 +297,18 @@ NS_METHOD nsAppShell::Create(int* bac, char ** bav)
|
||||
break;
|
||||
}
|
||||
|
||||
/* setup locale */
|
||||
if (!setlocale (LC_ALL,""))
|
||||
NS_WARNING("locale not supported by C library");
|
||||
|
||||
if (!XSupportsLocale ()) {
|
||||
NS_WARNING("locale not supported by Xlib, locale set to C");
|
||||
setlocale (LC_ALL, "C");
|
||||
}
|
||||
|
||||
if (!XSetLocaleModifiers (""))
|
||||
NS_WARNING("can not set locale modifiers");
|
||||
|
||||
// Open the display
|
||||
if (mDisplay == nsnull) {
|
||||
mDisplay = XOpenDisplay(displayName);
|
||||
@ -304,12 +318,10 @@ NS_METHOD nsAppShell::Create(int* bac, char ** bav)
|
||||
// Requires XSynchronize(mDisplay, True); To stop X buffering. Use this
|
||||
// to make debugging easier. KenF
|
||||
|
||||
if (mDisplay == NULL)
|
||||
{
|
||||
if (mDisplay == NULL) {
|
||||
fprintf(stderr, "%s: Cannot connect to X server %s\n",
|
||||
argv[0],
|
||||
XDisplayName(displayName));
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -728,7 +740,9 @@ nsAppShell::HandleButtonEvent(XEvent *event, nsWidget *aWidget)
|
||||
eventType = NS_MOUSE_MIDDLE_BUTTON_DOWN;
|
||||
break;
|
||||
case 3:
|
||||
eventType = NS_MOUSE_RIGHT_BUTTON_DOWN;
|
||||
/* look back into this in case anything actually needs a
|
||||
* NS_MOUSE_RIGHT_BUTTON_DOWN */
|
||||
eventType = NS_CONTEXTMENU;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
@ -797,9 +811,8 @@ nsAppShell::HandleButtonEvent(XEvent *event, nsWidget *aWidget)
|
||||
}
|
||||
}
|
||||
|
||||
if (currentlyDragging && !mDragging) {
|
||||
if (currentlyDragging && !mDragging)
|
||||
HandleDragDropEvent(event, aWidget);
|
||||
}
|
||||
|
||||
mevent.message = eventType;
|
||||
mevent.eventStructType = NS_MOUSE_EVENT;
|
||||
@ -812,7 +825,6 @@ nsAppShell::HandleButtonEvent(XEvent *event, nsWidget *aWidget)
|
||||
void
|
||||
nsAppShell::HandleExposeEvent(XEvent *event, nsWidget *aWidget)
|
||||
{
|
||||
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Expose event for window 0x%lx %d %d %d %d\n", event->xany.window,
|
||||
event->xexpose.x, event->xexpose.y, event->xexpose.width, event->xexpose.height));
|
||||
|
||||
@ -830,23 +842,17 @@ nsAppShell::HandleExposeEvent(XEvent *event, nsWidget *aWidget)
|
||||
} while (txe.xexpose.count>0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsPaintEvent pevent;
|
||||
pevent.message = NS_PAINT;
|
||||
pevent.widget = aWidget;
|
||||
pevent.eventStructType = NS_PAINT_EVENT;
|
||||
pevent.rect = dirtyRect;
|
||||
|
||||
// XXX fix this
|
||||
pevent.time = 0;
|
||||
//pevent.time = PR_Now();
|
||||
//pevent.region = nsnull;
|
||||
NS_ADDREF(aWidget);
|
||||
aWidget->OnPaint(pevent);
|
||||
NS_RELEASE(aWidget);
|
||||
delete pevent.rect;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim:ts=2:et:sw=2:
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
@ -18,15 +19,20 @@
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* tim copperfield <timecop@japan.co.jp>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsScrollBar.h"
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
#include "xlibrgb.h"
|
||||
|
||||
NS_IMPL_ADDREF(nsScrollbar)
|
||||
NS_IMPL_RELEASE(nsScrollbar)
|
||||
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
||||
#define NS_SCROLLBAR_MIN 8
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsScrollbar, nsWidget)
|
||||
NS_IMPL_RELEASE_INHERITED(nsScrollbar, nsWidget)
|
||||
NS_IMPL_QUERY_INTERFACE2(nsScrollbar, nsIScrollbar, nsIWidget)
|
||||
|
||||
PRLogModuleInfo *XlibScrollbarLM = PR_NewLogModule("XlibScrollbar");
|
||||
|
||||
@ -36,6 +42,8 @@ nsScrollbar::nsScrollbar(PRBool aIsVertical) : nsWidget(), nsIScrollbar()
|
||||
mMaxRange = 0;
|
||||
mPosition = 0;
|
||||
mThumbSize = 0;
|
||||
mXScale = 0.0;
|
||||
mYScale = 0.0;
|
||||
mLineIncrement = 1;
|
||||
mIsVertical = aIsVertical;
|
||||
mBackground = NS_RGB(100,100,100);
|
||||
@ -49,9 +57,65 @@ nsScrollbar::~nsScrollbar()
|
||||
{
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsScrollbar)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollbar)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsWidget)
|
||||
/* Create scrollbar widget */
|
||||
void nsScrollbar::CreateNative(Window aParent, nsRect aRect)
|
||||
{
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long attr_mask;
|
||||
|
||||
// on a window resize, we don't want to window contents to
|
||||
// be discarded...
|
||||
attr.bit_gravity = NorthWestGravity;
|
||||
// make sure that we listen for events
|
||||
attr.event_mask = StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | VisibilityChangeMask;
|
||||
// set the default background color and border to that awful gray
|
||||
attr.background_pixel = mBackgroundPixel;
|
||||
attr.border_pixel = mBorderPixel;
|
||||
// set the colormap
|
||||
attr.colormap = xlib_rgb_get_cmap();
|
||||
// here's what's in the struct
|
||||
attr_mask = CWBitGravity | CWEventMask | CWBackPixel | CWBorderPixel;
|
||||
// check to see if there was actually a colormap.
|
||||
if (attr.colormap)
|
||||
attr_mask |= CWColormap;
|
||||
|
||||
CreateNativeWindow(aParent, mBounds, attr, attr_mask);
|
||||
// set up the scrolling bar.
|
||||
attr.event_mask = Button1MotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | VisibilityChangeMask;
|
||||
attr.background_pixel = xlib_rgb_xpixel_from_rgb(NS_RGB(192,192,192));
|
||||
attr.border_pixel = xlib_rgb_xpixel_from_rgb(NS_RGB(100,100,100));
|
||||
// set up the size
|
||||
CalcBarBounds();
|
||||
mBar = XCreateWindow(mDisplay,
|
||||
mBaseWindow,
|
||||
mBarBounds.x, mBarBounds.y,
|
||||
mBarBounds.width, mBarBounds.height,
|
||||
2, // border width
|
||||
mDepth,
|
||||
InputOutput,
|
||||
mVisual,
|
||||
attr_mask,
|
||||
&attr);
|
||||
AddWindowCallback(mBar, this);
|
||||
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::CreateNative created window 0x%lx with bar 0x%lx\n",
|
||||
mBaseWindow, mBar));
|
||||
}
|
||||
|
||||
void nsScrollbar::DestroyNative(void)
|
||||
{
|
||||
// override since we have two native widgets
|
||||
if (mBar) {
|
||||
DestroyNativeChildren(mDisplay, mBar);
|
||||
|
||||
XDestroyWindow(mDisplay, mBar);
|
||||
DeleteWindowCallback(mBar);
|
||||
mBar = 0;
|
||||
}
|
||||
if (mBaseWindow) {
|
||||
nsWidget::DestroyNative();
|
||||
mBaseWindow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD nsScrollbar::SetMaxRange(PRUint32 aEndRange)
|
||||
{
|
||||
@ -74,8 +138,7 @@ NS_METHOD nsScrollbar::SetPosition(PRUint32 aPos)
|
||||
{
|
||||
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::SetPosition()\n"));
|
||||
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("Scroll to %d\n", aPos));
|
||||
// mPosition = (PRUint32)((float)aPos / (float)mRequestedSize.height * (float)mMaxRange);
|
||||
mPosition = aPos;
|
||||
mPosition = CLAMP(aPos, 0, mMaxRange);
|
||||
CalcBarBounds();
|
||||
LayoutBar();
|
||||
return NS_OK;
|
||||
@ -155,6 +218,9 @@ PRBool nsScrollbar::OnScroll(PRUint32 scrollCode, int cPos)
|
||||
result = PrevPage();
|
||||
break;
|
||||
case NS_SCROLLBAR_POS:
|
||||
if (mIsVertical == PR_TRUE)
|
||||
result = SetPosition(cPos);
|
||||
else
|
||||
result = SetPosition(cPos);
|
||||
break;
|
||||
default:
|
||||
@ -178,105 +244,40 @@ PRBool nsScrollbar::OnResize(nsSizeEvent &event)
|
||||
|
||||
PRBool nsScrollbar::DispatchMouseEvent(nsMouseEvent &aEvent)
|
||||
{
|
||||
PRBool result;
|
||||
PRInt32 real;
|
||||
|
||||
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::DispatchMouseEvent\n"));
|
||||
|
||||
// check to see if this was on the main window.
|
||||
/* that calculation is kind of screwed, but better than the original */
|
||||
switch (aEvent.message) {
|
||||
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
||||
if (mIsVertical == PR_TRUE) {
|
||||
OnScroll(NS_SCROLLBAR_POS, aEvent.point.y);
|
||||
real = (PRInt32)((float)(PR_MAX(0, aEvent.point.y - ((PRInt32)PR_MAX((mThumbSize * mYScale), NS_SCROLLBAR_MIN) / 2))) / mYScale);
|
||||
OnScroll(NS_SCROLLBAR_POS, real);
|
||||
} else {
|
||||
real = (PRInt32)((float)(PR_MAX(0, aEvent.point.x - ((PRInt32)PR_MAX((mThumbSize * mXScale), NS_SCROLLBAR_MIN) / 2))) / mXScale);
|
||||
OnScroll(NS_SCROLLBAR_POS, real);
|
||||
}
|
||||
else {
|
||||
OnScroll(NS_SCROLLBAR_POS, aEvent.point.x);
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
||||
if (mIsVertical == PR_TRUE) {
|
||||
if (aEvent.point.y < mBarBounds.y) {
|
||||
if (aEvent.point.y < mBarBounds.y)
|
||||
OnScroll(NS_SCROLLBAR_PAGE_PREV, 0);
|
||||
}
|
||||
else if (aEvent.point.y > mBarBounds.height) {
|
||||
else if (aEvent.point.y > (mBarBounds.y + mBarBounds.height))
|
||||
OnScroll(NS_SCROLLBAR_PAGE_NEXT, 0);
|
||||
} else { /* !vertical */
|
||||
if (aEvent.point.x < mBarBounds.x)
|
||||
OnScroll(NS_SCROLLBAR_PAGE_PREV, 0);
|
||||
else if (aEvent.point.x > (mBarBounds.x + mBarBounds.width))
|
||||
OnScroll(NS_SCROLLBAR_PAGE_NEXT, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (aEvent.point.x < mBarBounds.x) {
|
||||
OnScroll(NS_SCROLLBAR_PAGE_PREV, 0);
|
||||
}
|
||||
else if (aEvent.point.x > mBarBounds.width) {
|
||||
OnScroll(NS_SCROLLBAR_PAGE_NEXT, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
result = PR_FALSE;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void nsScrollbar::CreateNative(Window aParent, nsRect aRect)
|
||||
{
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long attr_mask;
|
||||
|
||||
// on a window resize, we don't want to window contents to
|
||||
// be discarded...
|
||||
attr.bit_gravity = SouthEastGravity;
|
||||
// make sure that we listen for events
|
||||
attr.event_mask = StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | VisibilityChangeMask;
|
||||
// set the default background color and border to that awful gray
|
||||
attr.background_pixel = mBackgroundPixel;
|
||||
attr.border_pixel = mBorderPixel;
|
||||
// set the colormap
|
||||
attr.colormap = xlib_rgb_get_cmap();
|
||||
// here's what's in the struct
|
||||
attr_mask = CWBitGravity | CWEventMask | CWBackPixel | CWBorderPixel;
|
||||
// check to see if there was actually a colormap.
|
||||
if (attr.colormap)
|
||||
attr_mask |= CWColormap;
|
||||
|
||||
CreateNativeWindow(aParent, mBounds, attr, attr_mask);
|
||||
CreateGC();
|
||||
// set up the scrolling bar.
|
||||
attr.event_mask = Button1MotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | VisibilityChangeMask;
|
||||
attr.background_pixel = xlib_rgb_xpixel_from_rgb(NS_RGB(192,192,192));
|
||||
attr.border_pixel = xlib_rgb_xpixel_from_rgb(NS_RGB(100,100,100));
|
||||
// set up the size
|
||||
CalcBarBounds();
|
||||
mBar = XCreateWindow(mDisplay,
|
||||
mBaseWindow,
|
||||
mBarBounds.x, mBarBounds.y,
|
||||
mBarBounds.width, mBarBounds.height,
|
||||
2, // border width
|
||||
mDepth,
|
||||
InputOutput,
|
||||
mVisual,
|
||||
attr_mask,
|
||||
&attr);
|
||||
AddWindowCallback(mBar, this);
|
||||
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::CreateNative created window 0x%lx with bar 0x%lx\n",
|
||||
mBaseWindow, mBar));
|
||||
}
|
||||
|
||||
void nsScrollbar::DestroyNative()
|
||||
{
|
||||
// override since we have two native widgets
|
||||
if (mBar) {
|
||||
DestroyNativeChildren(mDisplay, mBar);
|
||||
|
||||
XDestroyWindow(mDisplay, mBar);
|
||||
DeleteWindowCallback(mBar);
|
||||
mBar = 0;
|
||||
return SendEvent(NS_SCROLLBAR_POS);
|
||||
}
|
||||
if (mBaseWindow) {
|
||||
nsWidget::DestroyNative();
|
||||
mBaseWindow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollbar::Show(PRBool bState)
|
||||
{
|
||||
@ -329,21 +330,7 @@ nsresult nsScrollbar::NextPage(void)
|
||||
mPosition = max;
|
||||
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::NextPage(): new position is %d\n", mPosition));
|
||||
|
||||
// send the event
|
||||
if (mEventCallback) {
|
||||
nsScrollbarEvent sevent;
|
||||
sevent.message = NS_SCROLLBAR_POS;
|
||||
sevent.widget = (nsWidget *)this;
|
||||
sevent.eventStructType = NS_SCROLLBAR_EVENT;
|
||||
sevent.position = (mPosition);
|
||||
sevent.point.x = 0;
|
||||
sevent.point.y = 0;
|
||||
// send the event
|
||||
result = ConvertStatus((*mEventCallback) (&sevent));
|
||||
// the gtk code indicates that the callback can
|
||||
// modify the position. how odd.
|
||||
mPosition = sevent.position;
|
||||
}
|
||||
result = SendEvent(NS_SCROLLBAR_POS);
|
||||
CalcBarBounds();
|
||||
LayoutBar();
|
||||
return result;
|
||||
@ -352,27 +339,14 @@ nsresult nsScrollbar::NextPage(void)
|
||||
nsresult nsScrollbar::PrevPage(void)
|
||||
{
|
||||
nsresult result = PR_FALSE;
|
||||
|
||||
// check to make sure we don't go backwards
|
||||
if (mThumbSize > mPosition) {
|
||||
mPosition = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mPosition -= mThumbSize;
|
||||
}
|
||||
|
||||
// send the event
|
||||
if (mEventCallback) {
|
||||
nsScrollbarEvent sevent;
|
||||
sevent.message = NS_SCROLLBAR_POS;
|
||||
sevent.widget = (nsWidget *)this;
|
||||
sevent.eventStructType = NS_SCROLLBAR_EVENT;
|
||||
sevent.position = (mPosition);
|
||||
// send the event
|
||||
result = ConvertStatus((*mEventCallback) (&sevent));
|
||||
// the gtk code indicates that the callback can
|
||||
// modify the position. how odd.
|
||||
mPosition = sevent.position;
|
||||
}
|
||||
result = SendEvent(NS_SCROLLBAR_POS);
|
||||
CalcBarBounds();
|
||||
LayoutBar();
|
||||
return result;
|
||||
@ -380,47 +354,46 @@ nsresult nsScrollbar::PrevPage(void)
|
||||
|
||||
void nsScrollbar::CalcBarBounds(void)
|
||||
{
|
||||
float bar_start;
|
||||
float bar_end;
|
||||
PRUint32 bar_start;
|
||||
PRUint32 bar_end;
|
||||
|
||||
if (mMaxRange == 0) {
|
||||
bar_start = 0;
|
||||
bar_end = 0;
|
||||
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("CalcBarBounds: max range is zero.\n"));
|
||||
|
||||
mXScale = 0.0;
|
||||
mYScale = 0.0;
|
||||
} else {
|
||||
if (mIsVertical == PR_TRUE) {
|
||||
mYScale = (float)mRequestedSize.height / (float)mMaxRange;
|
||||
bar_start = (PRUint32)((float)mPosition * mYScale);
|
||||
bar_end = (PRUint32)((float)mThumbSize * mYScale);
|
||||
bar_start = CLAMP(bar_start, 0, (PRUint32)(mRequestedSize.height));
|
||||
} else {
|
||||
mXScale = (float)mRequestedSize.width / (float)mMaxRange;
|
||||
bar_start = (PRUint32)((float)mPosition * mXScale);
|
||||
bar_end = (PRUint32)((float)mThumbSize * mXScale);
|
||||
bar_start = CLAMP(bar_start, 0, (PRUint32)(mRequestedSize.width));
|
||||
}
|
||||
else {
|
||||
|
||||
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("CalcBarBounds: position: %d max: %d thumb: %d\n",
|
||||
mPosition, mMaxRange, mThumbSize));
|
||||
bar_start = (float)mPosition / (float)mMaxRange;
|
||||
bar_end = (float)mThumbSize / (float)mMaxRange;
|
||||
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("CalcBarBounds: start: %f end: %f\n", bar_start, bar_end));
|
||||
|
||||
}
|
||||
bar_end = PR_MAX(bar_end, NS_SCROLLBAR_MIN);
|
||||
|
||||
if (mIsVertical == PR_TRUE) {
|
||||
mBarBounds.x = 0;
|
||||
mBarBounds.y = (int)(bar_start * mRequestedSize.height);
|
||||
mBarBounds.width = mRequestedSize.width;
|
||||
mBarBounds.height = (int)(bar_end * mRequestedSize.height);
|
||||
}
|
||||
else {
|
||||
mBarBounds.x = (int)(bar_start * mRequestedSize.width);
|
||||
mBarBounds.y = bar_start;
|
||||
mBarBounds.width = mRequestedSize.width - 4;
|
||||
mBarBounds.height = bar_end;
|
||||
} else {
|
||||
mBarBounds.x = bar_start;
|
||||
mBarBounds.y = 0;
|
||||
mBarBounds.width = (int)(bar_end * mRequestedSize.width);
|
||||
mBarBounds.height = mRequestedSize.height;
|
||||
mBarBounds.width = bar_end;
|
||||
mBarBounds.height = mRequestedSize.height - 4;
|
||||
}
|
||||
if (mBarBounds.height == 0) {
|
||||
|
||||
if (mBarBounds.height == 0)
|
||||
mBarBounds.height = 1;
|
||||
}
|
||||
if (mBarBounds.width == 0) {
|
||||
mBarBounds.width = 1;
|
||||
}
|
||||
|
||||
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("CalcBarBounds: bar is (%s) %d %d %d %d\n",
|
||||
((mIsVertical == PR_TRUE) ? "vertical" : "horizontal" ),
|
||||
mBarBounds.x, mBarBounds.y, mBarBounds.width, mBarBounds.height));
|
||||
if (mBarBounds.width == 0)
|
||||
mBarBounds.width = 1;
|
||||
}
|
||||
|
||||
void nsScrollbar::LayoutBar(void)
|
||||
@ -434,3 +407,22 @@ NS_IMETHODIMP nsScrollbar::Move(PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
return nsWidget::Move(aX, aY);
|
||||
}
|
||||
|
||||
PRBool nsScrollbar::SendEvent(PRUint32 message)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
// send the event
|
||||
if (mEventCallback) {
|
||||
nsScrollbarEvent sevent;
|
||||
sevent.message = message;
|
||||
sevent.widget = (nsWidget *)this;
|
||||
sevent.eventStructType = NS_SCROLLBAR_EVENT;
|
||||
sevent.position = (mPosition);
|
||||
// send the event
|
||||
result = ConvertStatus((*mEventCallback) (&sevent));
|
||||
// the gtk code indicates that the callback can
|
||||
// modify the position. how odd.
|
||||
mPosition = sevent.position;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim:ts=2:et:sw=2
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
@ -68,6 +69,7 @@ public:
|
||||
|
||||
PRBool OnScroll(PRUint32 scrollCode, int cPos);
|
||||
void CreateNative(Window aParent, nsRect aRect);
|
||||
PRBool SendEvent(PRUint32 message);
|
||||
|
||||
private:
|
||||
void CalcBarBounds(void);
|
||||
@ -77,6 +79,8 @@ private:
|
||||
PRUint32 mMaxRange;
|
||||
PRUint32 mPosition;
|
||||
PRUint32 mThumbSize;
|
||||
float mXScale;
|
||||
float mYScale;
|
||||
PRUint32 mLineIncrement;
|
||||
PRBool mIsVertical;
|
||||
nsIRenderingContext *mRenderingContext;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "nsToolkit.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "plevent.h"
|
||||
#include "nsGCCache.h"
|
||||
|
||||
// Static Thread Local Storage index of the toolkit object associated with
|
||||
// a given thread...
|
||||
@ -32,15 +33,34 @@ static PRUintn gToolkitTLSIndex = 0;
|
||||
nsToolkit::nsToolkit()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mGC = NULL;
|
||||
}
|
||||
|
||||
nsToolkit::~nsToolkit()
|
||||
{
|
||||
if(mGC)
|
||||
mGC->Release();
|
||||
}
|
||||
|
||||
NS_DEFINE_IID(kIToolkitIID, NS_ITOOLKIT_IID);
|
||||
NS_IMPL_ISUPPORTS(nsToolkit,kIToolkitIID);
|
||||
|
||||
void nsToolkit::CreateSharedGC(Display *display, Drawable d)
|
||||
{
|
||||
if (mGC)
|
||||
return;
|
||||
mGC = new xGC(display, d, 0, NULL);
|
||||
mGC->AddRef(); // this is for us
|
||||
}
|
||||
|
||||
xGC *nsToolkit::GetSharedGC(Display *display, Drawable d)
|
||||
{
|
||||
if(!mGC)
|
||||
CreateSharedGC(display, d);
|
||||
|
||||
return mGC;
|
||||
}
|
||||
|
||||
NS_METHOD nsToolkit::Init(PRThread *aThread)
|
||||
{
|
||||
return NS_OK;
|
||||
@ -66,14 +86,27 @@ NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult)
|
||||
{
|
||||
toolkit = (nsIToolkit*)PR_GetThreadPrivate(gToolkitTLSIndex);
|
||||
|
||||
// Create a new toolkit for this thread
|
||||
if (!toolkit)
|
||||
{
|
||||
fprintf(stderr, "Creating a new nsIToolkit!\n");
|
||||
//
|
||||
// Create a new toolkit for this thread...
|
||||
//
|
||||
if (!toolkit) {
|
||||
toolkit = new nsToolkit();
|
||||
|
||||
if (!toolkit) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
} else {
|
||||
NS_ADDREF(toolkit);
|
||||
toolkit->Init(PR_GetCurrentThread());
|
||||
//
|
||||
// The reference stored in the TLS is weak. It is removed in the
|
||||
// nsToolkit destructor...
|
||||
//
|
||||
PR_SetThreadPrivate(gToolkitTLSIndex, (void*)toolkit);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "No need to create a new nsIToolkit!\n");
|
||||
} else {
|
||||
NS_ADDREF(toolkit);
|
||||
}
|
||||
*aResult = toolkit;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define nsToolkit_h__
|
||||
|
||||
#include "nsIToolkit.h"
|
||||
#include "nsGCCache.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
@ -38,6 +39,9 @@ struct MethodInfo;
|
||||
|
||||
class nsToolkit : public nsIToolkit
|
||||
{
|
||||
private:
|
||||
void CreateSharedGC(Display *display, Drawable d);
|
||||
xGC *mGC;
|
||||
|
||||
public:
|
||||
nsToolkit();
|
||||
@ -45,6 +49,7 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_IMETHOD Init(PRThread *aThread);
|
||||
xGC *GetSharedGC(Display *display, Drawable d);
|
||||
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim:ts=2:et:sw=2
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
@ -37,8 +38,10 @@
|
||||
#include "nsIEventListener.h"
|
||||
#include "nsIMenuListener.h"
|
||||
#include "nsIMouseListener.h"
|
||||
#include "nsIRollupListener.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsIMenuRollup.h"
|
||||
#include "nsToolkit.h"
|
||||
|
||||
#include "xlibrgb.h"
|
||||
|
||||
@ -73,8 +76,7 @@ Window nsWidget::mFocusWindow = 0;
|
||||
|
||||
// For popup handling
|
||||
nsCOMPtr<nsIRollupListener> nsWidget::gRollupListener;
|
||||
//nsWeakPtr nsWidget::gRollupWidget;
|
||||
nsCOMPtr<nsIWidget> nsWidget::gRollupWidget;
|
||||
nsWeakPtr nsWidget::gRollupWidget;
|
||||
PRBool nsWidget::gRollupConsumeRollupEvent = PR_FALSE;
|
||||
|
||||
class nsWindowKey : public nsHashKey {
|
||||
@ -116,7 +118,6 @@ nsWidget::nsWidget() // : nsBaseWidget()
|
||||
mBackgroundPixel = xlib_rgb_xpixel_from_rgb(mBackground);
|
||||
mBackground = NS_RGB(192, 192, 192);
|
||||
mBorderPixel = xlib_rgb_xpixel_from_rgb(mBorderRGB);
|
||||
mGC = 0;
|
||||
mParentWidget = nsnull;
|
||||
mName.AssignWithConversion("unnamed");
|
||||
mIsShown = PR_FALSE;
|
||||
@ -189,12 +190,6 @@ nsWidget::DestroyNative()
|
||||
// with dangling references.
|
||||
DestroyNativeChildren(mDisplay, mBaseWindow);
|
||||
|
||||
// This is handled in nsDrawingSurfaceXlib for now
|
||||
#if 0
|
||||
if (mGC)
|
||||
XFreeGC(mDisplay, mGC);
|
||||
#endif
|
||||
|
||||
XDestroyWindow(mDisplay, mBaseWindow);
|
||||
DeleteWindowCallback(mBaseWindow);
|
||||
}
|
||||
@ -217,9 +212,9 @@ NS_IMETHODIMP nsWidget::Create(nsIWidget *aParent,
|
||||
//mParentWidget = aParent;
|
||||
//NS_IF_ADDREF(mParentWidget); // KenF FIXME
|
||||
|
||||
return(StandardWidgetCreate(aParent, aRect, aHandleEventFunction,
|
||||
return StandardWidgetCreate(aParent, aRect, aHandleEventFunction,
|
||||
aContext, aAppShell, aToolkit, aInitData,
|
||||
nsnull));
|
||||
nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsWidget::Create(nsNativeWidget aParent,
|
||||
@ -291,11 +286,9 @@ nsWidget::StandardWidgetCreate(nsIWidget *aParent,
|
||||
|
||||
attr.bit_gravity = NorthWestGravity;
|
||||
attr.event_mask = GetEventMask();
|
||||
attr.background_pixel = mBackgroundPixel;
|
||||
attr.border_pixel = mBorderPixel;
|
||||
attr.colormap = xlib_rgb_get_cmap();
|
||||
|
||||
attr_mask = CWBitGravity | CWEventMask | CWBackPixel | CWBorderPixel;
|
||||
attr_mask = CWBitGravity | CWEventMask;
|
||||
|
||||
if (attr.colormap)
|
||||
attr_mask |= CWColormap;
|
||||
@ -386,10 +379,16 @@ NS_IMETHODIMP nsWidget::ConstrainPosition(PRInt32 *aX, PRInt32 *aY)
|
||||
|
||||
NS_IMETHODIMP nsWidget::Move(PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
|
||||
//printf("nsWidget::Move aX=%i, aY=%i\n", aX, aY);
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("nsWidget::Move(x, y)\n"));
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Moving window 0x%lx to %d, %d\n", mBaseWindow, aX, aY));
|
||||
|
||||
if((aX == mBounds.x) && (aY == mBounds.y) && !mIsToplevel) {
|
||||
//printf("discard this move\n");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
mBounds.x = aX;
|
||||
mBounds.y = aY;
|
||||
|
||||
@ -433,6 +432,7 @@ NS_IMETHODIMP nsWidget::Resize(PRInt32 aWidth,
|
||||
PRInt32 aHeight,
|
||||
PRBool aRepaint)
|
||||
{
|
||||
//printf("nsWidget::Resize aWidth=%i, Height=%i\n",aWidth, aHeight);
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("nsWidget::Resize(width, height)\n"));
|
||||
|
||||
if (aWidth <= 0) {
|
||||
@ -444,6 +444,7 @@ NS_IMETHODIMP nsWidget::Resize(PRInt32 aWidth,
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("*** height is %d, fixing.\n", aHeight));
|
||||
aHeight = 1;
|
||||
}
|
||||
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Resizing window 0x%lx to %d, %d\n", mBaseWindow, aWidth, aHeight));
|
||||
mRequestedSize.width = mBounds.width = aWidth;
|
||||
mRequestedSize.height = mBounds.height = aHeight;
|
||||
@ -477,6 +478,7 @@ NS_IMETHODIMP nsWidget::Resize(PRInt32 aX,
|
||||
PRInt32 aHeight,
|
||||
PRBool aRepaint)
|
||||
{
|
||||
//printf("nsWidget::Resize aX=%i, aY=%i, aWidth=%i, aHeight=%i\n", aX, aY, aWidth, aHeight);
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("nsWidget::Resize(x, y, width, height)\n"));
|
||||
|
||||
if (aWidth <= 0) {
|
||||
@ -584,7 +586,8 @@ void * nsWidget::GetNativeData(PRUint32 aDataType)
|
||||
break;
|
||||
case NS_NATIVE_GRAPHIC:
|
||||
// XXX implement this...
|
||||
return (void *)mGC;
|
||||
NS_ASSERTION(nsnull != mToolkit, "NULL toolkit, unable to get a GC");
|
||||
return (void *)NS_STATIC_CAST(nsToolkit*,mToolkit)->GetSharedGC(mDisplay, mBaseWindow);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "nsWidget::GetNativeData(%d) called with crap value.\n",
|
||||
@ -636,29 +639,10 @@ NS_IMETHODIMP nsWidget::Show(PRBool bState)
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("state is %d\n", bState));
|
||||
|
||||
if (bState) {
|
||||
if (mIsToplevel) {
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Someone just used the show method on the toplevel window.\n"));
|
||||
}
|
||||
if (mParentWidget) {
|
||||
((nsWidget *)mParentWidget)->WidgetShow(this);
|
||||
// Fix Popups appearing behind mozilla window. TonyT
|
||||
XRaiseWindow(mDisplay, mBaseWindow);
|
||||
}
|
||||
else {
|
||||
if (mBaseWindow) {
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Mapping window 0x%lx...\n", mBaseWindow));
|
||||
Map();
|
||||
}
|
||||
}
|
||||
mIsShown = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
if (mBaseWindow) {
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Unmapping window 0x%lx...\n", mBaseWindow));
|
||||
} else {
|
||||
Unmap();
|
||||
}
|
||||
mIsShown = PR_FALSE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -702,6 +686,8 @@ NS_IMETHODIMP nsWidget::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsWidget, nsBaseWidget, nsISupportsWeakReference)
|
||||
|
||||
NS_IMETHODIMP nsWidget::WidgetToScreen(const nsRect& aOldRect,
|
||||
nsRect& aNewRect)
|
||||
{
|
||||
@ -815,11 +801,9 @@ void nsWidget::CreateNative(Window aParent, nsRect aRect)
|
||||
|
||||
attr.bit_gravity = NorthWestGravity;
|
||||
attr.event_mask = GetEventMask();
|
||||
attr.background_pixel = mBackgroundPixel;
|
||||
attr.border_pixel = mBorderPixel;
|
||||
attr.colormap = xlib_rgb_get_cmap();
|
||||
|
||||
attr_mask = CWBitGravity | CWEventMask | CWBackPixel | CWBorderPixel ;
|
||||
attr_mask = CWBitGravity | CWEventMask;
|
||||
|
||||
if (attr.colormap)
|
||||
attr_mask |= CWColormap;
|
||||
@ -986,13 +970,16 @@ nsWidget::OnPaint(nsPaintEvent &event)
|
||||
return result;
|
||||
}
|
||||
|
||||
PRBool nsWidget::IsMouseInWindow(nsIWidget* inWidget, PRInt32 inMouseX, PRInt32 inMouseY){
|
||||
PRBool nsWidget::IsMouseInWindow(Window window, PRInt32 inMouseX, PRInt32 inMouseY){
|
||||
|
||||
XWindowAttributes inWindowAttributes;
|
||||
|
||||
/* sometimes we get NULL window */
|
||||
if (!window)
|
||||
return PR_FALSE;
|
||||
|
||||
// Get the origin (top left corner) coordinate and size
|
||||
Window currentPopupWindow = (Window)inWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
if (XGetWindowAttributes(mDisplay, currentPopupWindow, &inWindowAttributes) == 0){
|
||||
if (XGetWindowAttributes(mDisplay, window, &inWindowAttributes) == 0) {
|
||||
fprintf(stderr, "Failed calling XGetWindowAttributes in nsWidget::IsMouseInWindow");
|
||||
return PR_FALSE;
|
||||
}
|
||||
@ -1033,21 +1020,20 @@ PRBool nsWidget::IsMouseInWindow(nsIWidget* inWidget, PRInt32 inMouseX, PRInt32
|
||||
//
|
||||
// Deal with rollup of popups (xpmenus, etc)
|
||||
//
|
||||
PRBool nsWidget::HandlePopup ( PRInt32 inMouseX, PRInt32 inMouseY ){
|
||||
PRBool nsWidget::HandlePopup ( PRInt32 inMouseX, PRInt32 inMouseY )
|
||||
{
|
||||
PRBool retVal = PR_FALSE;
|
||||
PRBool rollup = PR_FALSE;
|
||||
|
||||
// The gRollupListener and gRollupWidget are both set to nsnull when a popup is no
|
||||
// longer visible
|
||||
|
||||
// Use non weak reference until implemented
|
||||
//nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWidget);
|
||||
//nsCOMPtr<nsIWidget> rollupWidget = gRollupWidget;
|
||||
nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWidget);
|
||||
|
||||
|
||||
if (gRollupWidget && gRollupListener){
|
||||
if (rollupWidget && gRollupListener) {
|
||||
Window currentPopup = (Window)rollupWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
|
||||
if (!IsMouseInWindow(gRollupWidget, inMouseX, inMouseY)){
|
||||
if (!IsMouseInWindow(currentPopup, inMouseX, inMouseY)) {
|
||||
rollup = PR_TRUE;
|
||||
nsCOMPtr<nsIMenuRollup> menuRollup ( do_QueryInterface(gRollupListener) );
|
||||
if ( menuRollup ) {
|
||||
@ -1061,7 +1047,8 @@ PRBool nsWidget::HandlePopup ( PRInt32 inMouseX, PRInt32 inMouseY ){
|
||||
widgetChain->GetElementAt ( i, getter_AddRefs(genericWidget) );
|
||||
nsCOMPtr<nsIWidget> widget ( do_QueryInterface(genericWidget) );
|
||||
if ( widget ) {
|
||||
if ( IsMouseInWindow(widget, inMouseX, inMouseY) ) {
|
||||
Window currWindow = (Window)widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
if ( IsMouseInWindow(currWindow, inMouseX, inMouseY) ) {
|
||||
rollup = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
@ -1070,11 +1057,9 @@ PRBool nsWidget::HandlePopup ( PRInt32 inMouseX, PRInt32 inMouseY ){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (rollup){
|
||||
//fprintf(stderr, "Calling gRollupListener->Rollup()\n");
|
||||
gRollupListener->Rollup();
|
||||
retVal = PR_TRUE;
|
||||
}
|
||||
@ -1212,6 +1197,7 @@ PRBool nsWidget::DispatchKeyEvent(nsKeyEvent & aKeyEvent)
|
||||
#undef TRACE_EVENTS_MOTION
|
||||
#undef TRACE_EVENTS_PAINT
|
||||
#undef TRACE_EVENTS_CROSSING
|
||||
#undef DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
@ -1302,14 +1288,6 @@ PRBool nsWidget::ConvertStatus(nsEventStatus aStatus)
|
||||
return(PR_FALSE);
|
||||
}
|
||||
|
||||
void nsWidget::CreateGC(void)
|
||||
{
|
||||
// This is handled in nsDrawingSurfaceXlib, for now
|
||||
#if 0
|
||||
mGC = XCreateGC(mDisplay, mBaseWindow, 0, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void nsWidget::WidgetPut(nsWidget *aWidget)
|
||||
{
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <X11/Xos.h>
|
||||
|
||||
#include "nsBaseWidget.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIRegion.h"
|
||||
@ -41,12 +42,14 @@
|
||||
#define XLIB_WIDGET_NOISY
|
||||
#endif
|
||||
|
||||
class nsWidget : public nsBaseWidget
|
||||
class nsWidget : public nsBaseWidget, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
nsWidget();
|
||||
virtual ~nsWidget();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_IMETHOD Create(nsIWidget *aParent,
|
||||
const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
@ -156,9 +159,10 @@ public:
|
||||
void *CheckParent(long ThisWindow);
|
||||
|
||||
// Deal with rollup for popups
|
||||
PRBool IsMouseInWindow(nsIWidget* inWidget, PRInt32 inMouseX, PRInt32 inMouseY);
|
||||
PRBool IsMouseInWindow(Window window, PRInt32 inMouseX, PRInt32 inMouseY);
|
||||
PRBool HandlePopup( PRInt32 inMouseX, PRInt32 inMouseY);
|
||||
|
||||
void WidgetShow (nsWidget *aWidget);
|
||||
protected:
|
||||
|
||||
nsCOMPtr<nsIRegion> mUpdateArea;
|
||||
@ -171,7 +175,6 @@ protected:
|
||||
virtual void CreateNative(Window aParent, nsRect aRect);
|
||||
virtual void DestroyNative();
|
||||
static void DestroyNativeChildren(Display *aDisplay, Window aWindow);
|
||||
void CreateGC(void);
|
||||
void Map(void);
|
||||
void Unmap(void);
|
||||
|
||||
@ -192,11 +195,11 @@ protected:
|
||||
void WidgetMove (nsWidget *aWidget);
|
||||
void WidgetMoveResize (nsWidget *aWidget);
|
||||
void WidgetResize (nsWidget *aWidget);
|
||||
void WidgetShow (nsWidget *aWidget);
|
||||
// check to see whether or not a rect will intersect with the current scrolled area
|
||||
PRBool WidgetVisible (nsRect &aBounds);
|
||||
|
||||
PRBool mIsShown;
|
||||
PRBool mShown;
|
||||
int mVisibility; // this is an int because that's the way X likes it
|
||||
PRUint32 mPreferredWidth;
|
||||
PRUint32 mPreferredHeight;
|
||||
@ -213,11 +216,12 @@ protected:
|
||||
unsigned long mBackgroundPixel;
|
||||
PRUint32 mBorderRGB;
|
||||
unsigned long mBorderPixel;
|
||||
GC mGC; // until we get gc pooling working...
|
||||
// GC mGC; // until we get gc pooling working...
|
||||
nsString mName; // name of the type of widget
|
||||
PRBool mIsToplevel;
|
||||
nsRect mRequestedSize;
|
||||
PRBool mMapped;
|
||||
PRBool mLastGrabFailed;
|
||||
|
||||
static Window mFocusWindow;
|
||||
|
||||
@ -232,8 +236,7 @@ protected:
|
||||
|
||||
// Variables for infomation about the current popup window and its listener
|
||||
static nsCOMPtr<nsIRollupListener> gRollupListener;
|
||||
static nsCOMPtr<nsIWidget> gRollupWidget;
|
||||
//static nsWeakPtr gRollupWidget;
|
||||
static nsWeakPtr gRollupWidget;
|
||||
static PRBool gRollupConsumeRollupEvent;
|
||||
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim:ts=2:et:sw=2
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
@ -28,6 +29,11 @@
|
||||
|
||||
#include "xlibrgb.h"
|
||||
|
||||
/* for window title unicode->locale conversion */
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsFileSpec.h" // for nsAutoCString
|
||||
|
||||
#define ABS(i) ( i<0 ? 0-i : i )
|
||||
@ -176,6 +182,7 @@ nsWindow::UnqueueDraw ()
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsWindow, nsWidget)
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
nsWindow::nsWindow() : nsWidget()
|
||||
@ -190,6 +197,8 @@ nsWindow::nsWindow() : nsWidget()
|
||||
// FIXME KenF
|
||||
mIsUpdating = PR_FALSE;
|
||||
mBlockFocusEvents = PR_FALSE;
|
||||
mLastGrabFailed = PR_TRUE;
|
||||
mIsTooSmall = PR_FALSE;
|
||||
|
||||
// FIXME New on M17 merge.
|
||||
mWindowType = eWindowType_child;
|
||||
@ -234,10 +243,49 @@ PRBool nsWindow::OnExpose(nsPaintEvent &event)
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsWindow::Show(PRBool bState)
|
||||
{
|
||||
// don't show if we are too small
|
||||
if (mIsTooSmall)
|
||||
return NS_OK;
|
||||
|
||||
if (bState) {
|
||||
if (mIsToplevel) {
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Someone just used the show method on the toplevel window.\n"));
|
||||
}
|
||||
|
||||
if (mParentWidget) {
|
||||
((nsWidget *)mParentWidget)->WidgetShow(this);
|
||||
// Fix Popups appearing behind mozilla window. TonyT
|
||||
XRaiseWindow(mDisplay, mBaseWindow);
|
||||
} else {
|
||||
if (mBaseWindow) {
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Mapping window 0x%lx...\n", mBaseWindow));
|
||||
Map();
|
||||
}
|
||||
}
|
||||
|
||||
mIsShown = PR_TRUE;
|
||||
if (sGrabWindow == this && mLastGrabFailed) {
|
||||
/* re-grab things like popup menus - the window isn't mapped when
|
||||
* the first grab occurs */
|
||||
NativeGrab(PR_TRUE);
|
||||
}
|
||||
} else {
|
||||
if (mBaseWindow) {
|
||||
PR_LOG(XlibWidgetsLM, PR_LOG_DEBUG, ("Unmapping window 0x%lx...\n", mBaseWindow));
|
||||
Unmap();
|
||||
}
|
||||
mIsShown = PR_FALSE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Function that does native grab.
|
||||
void nsWindow::NativeGrab(PRBool aGrab)
|
||||
{
|
||||
Cursor newCursor = XCreateFontCursor(mDisplay, XC_right_ptr);
|
||||
mLastGrabFailed = PR_FALSE;
|
||||
|
||||
if (aGrab)
|
||||
{
|
||||
@ -249,17 +297,15 @@ void nsWindow::NativeGrab(PRBool aGrab)
|
||||
(Window)0, newCursor, CurrentTime);
|
||||
|
||||
if (retval != GrabSuccess)
|
||||
fprintf(stderr, "Grab pointer failed!\n");
|
||||
mLastGrabFailed = PR_TRUE;
|
||||
|
||||
retval = XGrabKeyboard(mDisplay, mBaseWindow, PR_TRUE, GrabModeAsync,
|
||||
GrabModeAsync, CurrentTime);
|
||||
|
||||
if (retval != GrabSuccess)
|
||||
fprintf(stderr, "Grab keyboard failed!\n");
|
||||
mLastGrabFailed = PR_TRUE;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
XUngrabPointer(mDisplay, CurrentTime);
|
||||
XUngrabKeyboard(mDisplay, CurrentTime);
|
||||
}
|
||||
@ -272,29 +318,17 @@ void nsWindow::NativeGrab(PRBool aGrab)
|
||||
NS_IMETHODIMP nsWindow::CaptureRollupEvents(nsIRollupListener * aListener,
|
||||
PRBool aDoCapture,
|
||||
PRBool aConsumeRollupEvent)
|
||||
{
|
||||
if (aDoCapture)
|
||||
{
|
||||
if (aDoCapture) {
|
||||
NativeGrab(PR_TRUE);
|
||||
|
||||
sIsGrabbing = PR_TRUE;
|
||||
sGrabWindow = this;
|
||||
|
||||
//fprintf(stderr, "Received listener from generated popup\n");
|
||||
gRollupListener = aListener;
|
||||
|
||||
// Get assertion error:
|
||||
// ###!!! ASSERTION: Did you know you were calling |NS_GetWeakReference()| on
|
||||
// something that doesn't support weak references?: 'factoryPtr', file
|
||||
// nsWeakReference.cpp, line 55
|
||||
//gRollupWidget = getter_AddRefs(NS_GetWeakReference(NS_STATIC_CAST(nsIWidget*,this)));
|
||||
gRollupWidget = NS_STATIC_CAST(nsIWidget*,this);
|
||||
|
||||
// GTK does not seem to use this but other window toolkits do
|
||||
gRollupConsumeRollupEvent = PR_TRUE;
|
||||
//}
|
||||
gRollupListener = aListener;
|
||||
gRollupWidget = getter_AddRefs(NS_GetWeakReference(NS_STATIC_CAST(nsIWidget*, this)));
|
||||
}else{
|
||||
|
||||
// Release Grab
|
||||
if (sGrabWindow == this)
|
||||
sGrabWindow = NULL;
|
||||
@ -377,6 +411,34 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aWidth,
|
||||
PRInt32 aHeight,
|
||||
PRBool aRepaint)
|
||||
{
|
||||
//printf("nsWindow::Resize aWidth=%i aHeight=%i\n", aWidth,aHeight);
|
||||
PRBool NeedToShow = PR_FALSE;
|
||||
/* PRInt32 sizeHeight = aHeight;
|
||||
PRInt32 sizeWidth = aWidth; */
|
||||
|
||||
mBounds.width = aWidth;
|
||||
mBounds.height = aHeight;
|
||||
|
||||
// code to keep the window from showing before it has been moved or resized
|
||||
|
||||
// if we are resized to 1x1 or less, we will hide the window. Show(TRUE) will be ignored until a
|
||||
// larger resize has happened
|
||||
if (aWidth <= 1 || aHeight <= 1)
|
||||
{
|
||||
aWidth = 1;
|
||||
aHeight = 1;
|
||||
mIsTooSmall = PR_TRUE;
|
||||
Show(PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mIsTooSmall)
|
||||
{
|
||||
// if we are not shown, we don't want to force a show here, so check and see if Show(TRUE) has been called
|
||||
NeedToShow = mShown;
|
||||
mIsTooSmall = PR_FALSE;
|
||||
}
|
||||
}
|
||||
nsWidget::Resize(aWidth, aHeight, aRepaint);
|
||||
|
||||
nsSizeEvent sevent;
|
||||
@ -393,6 +455,13 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aWidth,
|
||||
OnResize(sevent);
|
||||
Release();
|
||||
delete sevent.windowSize;
|
||||
|
||||
if (NeedToShow)
|
||||
Show(PR_TRUE);
|
||||
|
||||
if (aRepaint)
|
||||
Invalidate(PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -407,6 +476,7 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aX,
|
||||
PRInt32 aHeight,
|
||||
PRBool aRepaint)
|
||||
{
|
||||
//printf("nsWindow::Resize aX=%i, aY=%i, aWidth=%i, aHeight=%i\n", aX,aY,aWidth,aHeight);
|
||||
|
||||
nsWidget::Resize(aX, aY, aWidth, aHeight, aRepaint);
|
||||
|
||||
@ -427,43 +497,6 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aX,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
void nsWindow::CreateNative(Window aParent, nsRect aRect)
|
||||
{
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long attr_mask;
|
||||
|
||||
// on a window resize, we don't want to window contents to
|
||||
// be discarded...
|
||||
attr.bit_gravity = NorthWestGravity;
|
||||
// make sure that we listen for events
|
||||
attr.event_mask = StructureNotifyMask |
|
||||
ExposureMask |
|
||||
ButtonPressMask |
|
||||
ButtonReleaseMask |
|
||||
PointerMotionMask |
|
||||
KeyPressMask |
|
||||
KeyReleaseMask |
|
||||
VisibilityChangeMask;
|
||||
// set the default background color and border to that awful gray
|
||||
attr.background_pixel = mBackgroundPixel;
|
||||
attr.border_pixel = mBorderPixel;
|
||||
// set the colormap
|
||||
attr.colormap = xlib_rgb_get_cmap();
|
||||
// here's what's in the struct
|
||||
attr_mask = CWBitGravity | CWEventMask | CWBackPixel | CWBorderPixel;
|
||||
// check to see if there was actually a colormap.
|
||||
if (attr.colormap)
|
||||
attr_mask |= CWColormap;
|
||||
|
||||
CreateNativeWindow(aParent, mBounds, attr, attr_mask);
|
||||
CreateGC();
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* virtual */ long
|
||||
nsWindow::GetEventMask()
|
||||
{
|
||||
@ -587,7 +620,7 @@ NS_IMETHODIMP nsWindow::Update()
|
||||
nsISupports* child;
|
||||
if (NS_SUCCEEDED(children->CurrentItem(&child)))
|
||||
{
|
||||
nsWindow* childWindow = NS_STATIC_CAST(nsWindow*,child);
|
||||
nsWindow *childWindow = NS_STATIC_CAST(nsWindow*, NS_STATIC_CAST(nsIWidget*, child));
|
||||
NS_RELEASE(child);
|
||||
|
||||
childWindow->Update();
|
||||
@ -604,10 +637,9 @@ NS_IMETHODIMP nsWindow::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
|
||||
if (mIsUpdating)
|
||||
UnqueueDraw();
|
||||
|
||||
PRInt32 srcX, srcY, destX, destY, width, height;
|
||||
PRInt32 srcX = 0, srcY = 0, destX = 0, destY = 0, width = 0, height = 0;
|
||||
nsRect aRect;
|
||||
GC gc;
|
||||
|
||||
gc = XCreateGC(mDisplay, mBaseWindow, 0, NULL);
|
||||
|
||||
if (aDx < 0 || aDy < 0)
|
||||
@ -669,7 +701,7 @@ NS_IMETHODIMP nsWindow::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
|
||||
nsISupports* child;
|
||||
if (NS_SUCCEEDED(children->CurrentItem(&child)))
|
||||
{
|
||||
nsWindow* childWindow = NS_STATIC_CAST(nsWindow*,child);
|
||||
nsWindow *childWindow = NS_STATIC_CAST(nsWindow*, NS_STATIC_CAST(nsIWidget*, child));
|
||||
NS_RELEASE(child);
|
||||
|
||||
nsRect bounds;
|
||||
@ -724,6 +756,61 @@ NS_IMETHODIMP nsWindow::SetTitle(const nsString& aTitle)
|
||||
if(!mBaseWindow)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
char *platformText;
|
||||
PRInt32 platformLen;
|
||||
|
||||
nsCOMPtr<nsIUnicodeEncoder> encoder;
|
||||
/* get the charset */
|
||||
nsAutoString platformCharset;
|
||||
nsCOMPtr <nsIPlatformCharset> platformCharsetService = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = platformCharsetService->GetCharset(kPlatformCharsetSel_Menu, platformCharset);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
platformCharset.AssignWithConversion("ISO-8859-1");
|
||||
|
||||
/* get the encoder */
|
||||
NS_WITH_SERVICE(nsICharsetConverterManager, ccm, NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
rv = ccm->GetUnicodeEncoder(&platformCharset, getter_AddRefs(encoder));
|
||||
|
||||
/* Estimate out length and allocate the buffer based on a worst-case estimate, then do
|
||||
the conversion. */
|
||||
PRInt32 len = (PRInt32)aTitle.Length();
|
||||
encoder->GetMaxLength(aTitle.GetUnicode(), len, &platformLen);
|
||||
if (platformLen) {
|
||||
platformText = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(platformLen + sizeof(char)));
|
||||
if (platformText) {
|
||||
rv = encoder->Convert(aTitle.GetUnicode(), &len, platformText, &platformLen);
|
||||
(platformText)[platformLen] = '\0'; // null terminate. Convert() doesn't do it for us
|
||||
}
|
||||
} // if valid length
|
||||
|
||||
if (platformLen > 0) {
|
||||
int status = 0;
|
||||
XTextProperty prop;
|
||||
|
||||
/* Use XStdICCTextStyle for 41786(a.k.a TWM sucks) and 43108(JA text title) */
|
||||
prop.value = 0;
|
||||
status = XmbTextListToTextProperty(mDisplay, &platformText, 1,
|
||||
XStdICCTextStyle, &prop);
|
||||
|
||||
if (status == Success) {
|
||||
XSetWMProperties(mDisplay, mBaseWindow,
|
||||
&prop, &prop, NULL, 0, NULL, NULL, NULL);
|
||||
if (prop.value)
|
||||
XFree(prop.value);
|
||||
|
||||
nsMemory::Free(platformText);
|
||||
return NS_OK;
|
||||
} else { // status != Success
|
||||
if (prop.value)
|
||||
XFree(prop.value);
|
||||
nsMemory::Free(platformText);
|
||||
}
|
||||
}
|
||||
|
||||
/* if the stuff above failed, replace multibyte with .... */
|
||||
XStoreName(mDisplay, mBaseWindow, (const char *) nsAutoCString(aTitle));
|
||||
|
||||
return NS_OK;
|
||||
|
@ -70,6 +70,9 @@ class nsWindow : public nsWidget
|
||||
public:
|
||||
nsWindow();
|
||||
~nsWindow();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
static void UpdateIdle (void *data);
|
||||
NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener,
|
||||
PRBool aDoCapture,
|
||||
@ -83,6 +86,7 @@ class nsWindow : public nsWidget
|
||||
NS_IMETHOD ScrollRect(nsRect &aSrcRect, PRInt32 aDx, PRInt32 aDy);
|
||||
|
||||
NS_IMETHOD SetTitle(const nsString& aTitle);
|
||||
NS_IMETHOD Show(PRBool aShow);
|
||||
|
||||
NS_IMETHOD Resize(PRInt32 aWidth,
|
||||
PRInt32 aHeight,
|
||||
@ -108,6 +112,7 @@ protected:
|
||||
void UnqueueDraw();
|
||||
PRBool mIsUpdating;
|
||||
PRBool mBlockFocusEvents;
|
||||
PRBool mIsTooSmall;
|
||||
|
||||
static PRBool sIsGrabbing;
|
||||
static nsWindow *sGrabWindow;
|
||||
|
Loading…
Reference in New Issue
Block a user