gecko-dev/cmd/xfe/XfeWidgets/Xfe/PixmapUtil.c

387 строки
9.3 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*----------------------------------------------------------------------*/
/* */
/* Name: <Xfe/PixmapUtil.c> */
/* Description: Xfe widgets pixmap utilities. */
/* Author: Ramiro Estrugo <ramiro@netscape.com> */
/* */
/*----------------------------------------------------------------------*/
#include <Xfe/XfeP.h>
#define MESSAGE1 "The pixmap needs to have the same depth as the widget."
#define MESSAGE2 "Cannot obtain geometry for pixmap."
/*----------------------------------------------------------------------*/
/* */
/* Double buffer global variables */
/* */
/*----------------------------------------------------------------------*/
static Pixmap _pixmap_buffer = XmUNSPECIFIED_PIXMAP;
static Cardinal _pixmap_buffer_depth = 0;
static Dimension _pixmap_buffer_width = 0;
static Dimension _pixmap_buffer_height = 0;
/*----------------------------------------------------------------------*/
static Pixmap BufferCreate (Widget,Dimension,Dimension);
static void BufferUpdate (Widget,Pixmap,
Dimension,Dimension);
static Boolean BufferCheck (Widget);
static void BufferFree (Widget);
/*----------------------------------------------------------------------*/
/* */
/* Double buffer utilities */
/* */
/*----------------------------------------------------------------------*/
Pixmap
_XfePixmapBufferAllocate(Widget w)
{
Pixmap buffer = XmUNSPECIFIED_PIXMAP;
assert( w != NULL );
/* Check whether a buffer already exists */
if (_XfePixmapGood(_pixmap_buffer))
{
assert( _pixmap_buffer_depth == _XfeDepth(w));
/* Check whether this widget can use the buffer */
if (BufferCheck(w))
{
buffer = _pixmap_buffer;
}
else
{
Dimension new_width = XfeMax(_XfeWidth(w),_pixmap_buffer_width);
Dimension new_height = XfeMax(_XfeHeight(w),_pixmap_buffer_height);
BufferFree(w);
buffer = BufferCreate(w,new_width,new_height);
assert( _XfePixmapGood(buffer) );
BufferUpdate(w,buffer,new_width,new_height);
}
}
/* Create a buffer pixmap for the first time */
else
{
buffer = BufferCreate(w,_XfeWidth(w),_XfeHeight(w));
assert( _XfePixmapGood(buffer) );
BufferUpdate(w,buffer,_XfeWidth(w),_XfeHeight(w));
}
return buffer;
}
/*----------------------------------------------------------------------*/
void
_XfePixmapBufferRelease(Widget w,Pixmap buffer)
{
}
/*----------------------------------------------------------------------*/
Pixmap
_XfePixmapBufferAccess()
{
return _pixmap_buffer;
}
/*----------------------------------------------------------------------*/
static void
BufferFree(Widget w)
{
assert( _XfePixmapGood(_pixmap_buffer) );
/* Free the buffer pixmap */
XFreePixmap(XtDisplay(w),_pixmap_buffer);
}
/*----------------------------------------------------------------------*/
static Pixmap
BufferCreate(Widget w,Dimension width,Dimension height)
{
assert( w != NULL );
return XCreatePixmap(XtDisplay(w),
DefaultRootWindow(XtDisplay(w)),
width,
height,
_XfeDepth(w));
}
/*----------------------------------------------------------------------*/
static void
BufferUpdate(Widget w,Pixmap buffer,Dimension width,Dimension height)
{
assert( _XfePixmapGood(buffer) );
_pixmap_buffer = buffer;
_pixmap_buffer_depth = _XfeDepth(w);
_pixmap_buffer_width = width;
_pixmap_buffer_height = height;
}
/*----------------------------------------------------------------------*/
static Boolean
BufferCheck(Widget w)
{
assert( w != NULL );
return ((_XfeWidth(w) <= _pixmap_buffer_width) &&
(_XfeHeight(w) <= _pixmap_buffer_height) &&
(_XfeDepth(w) == _pixmap_buffer_depth));
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Pixmap */
/* */
/*----------------------------------------------------------------------*/
Boolean
XfePixmapExtent(Display * dpy,
Pixmap pixmap,
Dimension * width,
Dimension * height,
Cardinal * depth)
{
Boolean result = False;
assert( dpy != NULL );
if (_XfePixmapGood(pixmap))
{
unsigned int borderWidth;
Window rootWindow;
int x;
int y;
unsigned int pixmap_width;
unsigned int pixmap_height;
unsigned int pixmap_depth;
/* Query Server for Pixmap info */
result = XGetGeometry(dpy,pixmap,&rootWindow,&x,&y,
&pixmap_width,&pixmap_height,
&borderWidth,&pixmap_depth);
/* Verify that the pixmap extent was obtained */
if(result)
{
/* Assign the required components */
if (width)
{
*width = pixmap_width;
}
if (height)
{
*height = pixmap_height;
}
if (depth)
{
*depth = pixmap_depth;
}
}
else
{
/* Make them NULL as an extra warning */
if (width)
{
*width = 0;
}
if (height)
{
*height = 0;
}
if (depth)
{
*depth = 0;
}
}
}
return result;
}
/*----------------------------------------------------------------------*/
Boolean
XfePixmapGood(Pixmap pixmap)
{
return _XfePixmapGood(pixmap);
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Stipple / Tile functions */
/* */
/*----------------------------------------------------------------------*/
Pixmap
XfeInsensitiveTile(Screen * screen,int depth,Pixel fg,Pixel bg)
{
return XmGetPixmapByDepth(screen,"50_foreground",fg,bg,depth);
}
/*----------------------------------------------------------------------*/
Pixmap
XfeInsensitiveStipple(Screen * screen,int depth,Pixel fg,Pixel bg)
{
return XmGetPixmapByDepth(screen,"50_foreground",fg,bg,depth);
}
/*----------------------------------------------------------------------*/
void
XfePixmapClear(Display * dpy,
Pixmap pixmap,
GC gc,
Dimension width,
Dimension height)
{
assert( dpy != NULL );
assert( _XfePixmapGood(pixmap) );
assert( gc != None );
assert( width > 0 );
assert( height > 0 );
XFillRectangle(dpy,pixmap,gc,0,0,width,height);
}
/*----------------------------------------------------------------------*/
Pixmap
XfePixmapCheck(Widget w,
Pixmap pixmap,
Dimension * width_out,
Dimension * height_out)
{
Pixmap result = XmUNSPECIFIED_PIXMAP;
Dimension width = 0;
Dimension height = 0;
/* Check the pixmap only if it is good */
if (_XfePixmapGood(pixmap))
{
Cardinal depth;
if (XfePixmapExtent(XtDisplay(w),
pixmap,
&width,
&height,
&depth))
{
/* Make sure the pixmap's depth matches the widget */
if (_XfeDepth(w) == depth)
{
result = pixmap;
}
else
{
_XfeWarning(w,MESSAGE1);
}
}
else
{
_XfeWarning(w,MESSAGE2);
}
}
if (width_out)
{
*width_out = width;
}
if (height_out)
{
*height_out = height;
}
return pixmap;
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Preparation utlities */
/* */
/*----------------------------------------------------------------------*/
/* extern */ void
_XfePixmapPrepare(Widget w,
Pixmap * pixmap_in_out,
Dimension * width_out,
Dimension * height_out,
String name)
{
Dimension width = 0;
Dimension height = 0;
/* assert( width_out != NULL ); */
/* assert( height_out != NULL ); */
assert( pixmap_in_out != NULL );
assert( _XfeIsAlive(w) );
/* Obtain geometry info for the pixmap if its good */
if (_XfePixmapGood(*pixmap_in_out))
{
Cardinal depth;
if (XfePixmapExtent(XtDisplay(w),
*pixmap_in_out,
&width,
&height,
&depth))
{
/* Make sure the pixmap's depth matches the widget */
if (_XfeDepth(w) != depth)
{
width = 0;
height = 0;
*pixmap_in_out = XmUNSPECIFIED_PIXMAP;
_XfeArgWarning(w,MESSAGE1,name);
}
}
/* Could not get geometry for the pixmap */
else
{
*pixmap_in_out = XmUNSPECIFIED_PIXMAP;
_XfeArgWarning(w,MESSAGE2,name);
}
}
/* Assign the dimensions if needed */
if (width_out)
{
*width_out = width;
}
if (height_out)
{
*height_out = height;
}
}
/*----------------------------------------------------------------------*/