414 lines
11 KiB
C
414 lines
11 KiB
C
/*
|
||
* tixWinDraw.c --
|
||
*
|
||
* Implement the Windows specific function calls for drawing.
|
||
*
|
||
* Copyright (c) 1993-1999 Ioi Kim Lam.
|
||
* Copyright (c) 2000 Tix Project Group.
|
||
*
|
||
* See the file "license.terms" for information on usage and redistribution
|
||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||
*
|
||
* $Id: tixWinDraw.c,v 1.5 2004/03/28 02:44:57 hobbs Exp $
|
||
*/
|
||
|
||
#include <tkWinInt.h>
|
||
#include <tixInt.h>
|
||
#include <tixPort.h>
|
||
|
||
|
||
/*----------------------------------------------------------------------
|
||
*
|
||
* TixpDrawTmpLine --
|
||
*
|
||
* Draws a "temporarily" line on the desktop window with XOR
|
||
* drawing mode. This function is used by the PanedWindow and
|
||
* ResizeHandler to draw the rubberband lines. Calling the
|
||
* function again with the same parameters cancels the temporary
|
||
* lines without affecting what was originally on the screen.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* None
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TixpDrawTmpLine(x1, y1, x2, y2, tkwin)
|
||
int x1;
|
||
int y1;
|
||
int x2;
|
||
int y2;
|
||
Tk_Window tkwin;
|
||
{
|
||
HWND desktop;
|
||
HDC hdc;
|
||
HPEN hpen;
|
||
HGDIOBJ old;
|
||
|
||
desktop = GetDesktopWindow();
|
||
hdc = GetWindowDC(desktop);
|
||
hpen = CreatePen(PS_SOLID, 0, RGB(255,255,255));
|
||
|
||
old = SelectObject(hdc, hpen);
|
||
SetROP2(hdc, R2_XORPEN);
|
||
|
||
MoveToEx(hdc, x1, y1, NULL);
|
||
LineTo(hdc, x2, y2);
|
||
|
||
SelectObject(hdc, old);
|
||
DeleteObject(hpen);
|
||
ReleaseDC(desktop, hdc);
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TixpDrawAnchorLines --
|
||
*
|
||
* See comments near Tix_DrawAnchorLines in tixUtils.c.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* None
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TixpDrawAnchorLines(display, drawable, gc, x, y, w, h)
|
||
Display *display;
|
||
Drawable drawable;
|
||
GC gc;
|
||
int x;
|
||
int y;
|
||
int w;
|
||
int h;
|
||
{
|
||
HDC hdc;
|
||
TkWinDCState state;
|
||
RECT rect;
|
||
|
||
if (w < 2 || h < 2) {
|
||
/*
|
||
* Area too small to show effect. Don't bother
|
||
*/
|
||
return;
|
||
}
|
||
|
||
hdc = TkWinGetDrawableDC(display, drawable, &state);
|
||
rect.left = x;
|
||
rect.top = y;
|
||
rect.right = x+w;
|
||
rect.bottom = y+h;
|
||
DrawFocusRect(hdc, &rect);
|
||
TkWinReleaseDrawableDC(drawable, hdc, &state);
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TixpStartSubRegionDraw --
|
||
*
|
||
* This function is used by the Tix DItem code to implement
|
||
* clipped rendering -- if a DItem is larger than the region
|
||
* where the DItem is displayed (with the Tix_DItemDisplay
|
||
* function), we clip the DItem so that all the rendering
|
||
* happens inside the region.
|
||
*
|
||
* This Win32 implementation is tricky (which explains why the
|
||
* TixpSubRegDrawXXX API looks so arcane.) Tk does not support
|
||
* a portable API for setting the clip region of a GC. We could
|
||
* hack into Tk's Win32 implementation of GC to get the clipping
|
||
* to work, but that may run into future incompatibilities.
|
||
*
|
||
* For a clean and (almost) portable, albeit a bit slow,
|
||
* implemetation of clipping, we allocate a pixmap when clipping
|
||
* is required. All subsequent drawing goes into this
|
||
* pixmap. When TixpEndSubRegionDraw is called we then copy from
|
||
* the pixmap back to the destination drawable.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* A Tk pixmap may be created and saved into subRegPtr->pixmap in
|
||
* for the clipped drawing operations.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TixpStartSubRegionDraw(display, drawable, gc, subRegPtr, origX, origY,
|
||
x, y, width, height, needWidth, needHeight)
|
||
Display *display;
|
||
Drawable drawable;
|
||
GC gc;
|
||
TixpSubRegion * subRegPtr;
|
||
int origX;
|
||
int origY;
|
||
int x;
|
||
int y;
|
||
int width;
|
||
int height;
|
||
int needWidth;
|
||
int needHeight;
|
||
{
|
||
TkWinDrawable * wdrPtr;
|
||
int depth;
|
||
|
||
if ((width < needWidth) || (height < needHeight)) {
|
||
subRegPtr->origX = origX;
|
||
subRegPtr->origY = origY;
|
||
subRegPtr->x = x;
|
||
subRegPtr->y = y;
|
||
subRegPtr->width = width;
|
||
subRegPtr->height = height;
|
||
|
||
/*
|
||
* Find out the depth of the drawable and create a pixmap of
|
||
* the same depth.
|
||
*/
|
||
|
||
wdrPtr = (TkWinDrawable *)drawable;
|
||
if (wdrPtr->type == TWD_BITMAP) {
|
||
depth = wdrPtr->bitmap.depth;
|
||
} else {
|
||
depth = wdrPtr->window.winPtr->depth;
|
||
}
|
||
|
||
subRegPtr->pixmap = Tk_GetPixmap(display, drawable, width, height,
|
||
depth);
|
||
|
||
if (subRegPtr->pixmap != None) {
|
||
/*
|
||
* It could be None if we have somehow exhausted the Windows
|
||
* GDI resources.
|
||
*/
|
||
XCopyArea(display, drawable, subRegPtr->pixmap, gc, x, y,
|
||
(unsigned) width, (unsigned) height, 0, 0);
|
||
}
|
||
} else {
|
||
subRegPtr->pixmap = None;
|
||
}
|
||
}
|
||
|
||
/*----------------------------------------------------------------------
|
||
* TixpEndSubRegionDraw --
|
||
*
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TixpEndSubRegionDraw(display, drawable, gc, subRegPtr)
|
||
Display *display;
|
||
Drawable drawable;
|
||
GC gc;
|
||
TixpSubRegion * subRegPtr;
|
||
{
|
||
if (subRegPtr->pixmap != None) {
|
||
XCopyArea(display, subRegPtr->pixmap, drawable, gc, 0, 0,
|
||
(unsigned) subRegPtr->width, (unsigned) subRegPtr->height,
|
||
subRegPtr->x, subRegPtr->y);
|
||
Tk_FreePixmap(display, subRegPtr->pixmap);
|
||
subRegPtr->pixmap = None;
|
||
}
|
||
}
|
||
|
||
void
|
||
TixpSubRegSetClip(display, subRegPtr, gc)
|
||
Display *display;
|
||
TixpSubRegion * subRegPtr;
|
||
GC gc;
|
||
{
|
||
/* Do nothing */
|
||
}
|
||
|
||
void
|
||
TixpSubRegUnsetClip(display, subRegPtr, gc)
|
||
Display *display;
|
||
TixpSubRegion * subRegPtr;
|
||
GC gc;
|
||
{
|
||
/* Do nothing */
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TixpSubRegDisplayText --
|
||
*
|
||
* Display a text string on one or more lines in a sub region.
|
||
*
|
||
* Results:
|
||
* See TkDisplayText
|
||
*
|
||
* Side effects:
|
||
* See TkDisplayText
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TixpSubRegDisplayText(display, drawable, gc, subRegPtr, font, string,
|
||
numChars, x, y, length, justify, underline)
|
||
Display *display; /* X display to use for drawing text. */
|
||
Drawable drawable; /* Window or pixmap in which to draw the
|
||
* text. */
|
||
GC gc; /* Graphics context to use for drawing text. */
|
||
TixpSubRegion * subRegPtr; /* Information about the subregion */
|
||
TixFont font; /* Font that determines geometry of text
|
||
* (should be same as font in gc). */
|
||
CONST84 char *string; /* String to display; may contain embedded
|
||
* newlines. */
|
||
int numChars; /* Number of characters to use from string. */
|
||
int x, y; /* Pixel coordinates within drawable of
|
||
* upper left corner of display area. */
|
||
int length; /* Line length in pixels; used to compute
|
||
* word wrap points and also for
|
||
* justification. Must be > 0. */
|
||
Tk_Justify justify; /* How to justify lines. */
|
||
int underline; /* Index of character to underline, or < 0
|
||
* for no underlining. */
|
||
{
|
||
if (subRegPtr->pixmap != None) {
|
||
TixDisplayText(display, subRegPtr->pixmap, font, string,
|
||
numChars, x - subRegPtr->x, y - subRegPtr->y,
|
||
length, justify, underline, gc);
|
||
} else {
|
||
TixDisplayText(display, drawable, font, string,
|
||
numChars, x, y, length, justify, underline, gc);
|
||
}
|
||
}
|
||
|
||
/*----------------------------------------------------------------------
|
||
* TixpSubRegFillRectangle --
|
||
*
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TixpSubRegFillRectangle(display, drawable, gc, subRegPtr, x, y, width, height)
|
||
Display *display; /* X display to use for drawing rectangle. */
|
||
Drawable drawable; /* Window or pixmap in which to draw the
|
||
* rectangle. */
|
||
GC gc; /* Graphics context to use for drawing. */
|
||
TixpSubRegion * subRegPtr; /* Information about the subregion */
|
||
int x, y; /* Pixel coordinates within drawable of
|
||
* upper left corner of display area. */
|
||
int width, height; /* Size of the rectangle. */
|
||
{
|
||
if (subRegPtr->pixmap != None) {
|
||
XFillRectangle(display, subRegPtr->pixmap, gc,
|
||
x - subRegPtr->x, y - subRegPtr->y, width, height);
|
||
} else {
|
||
XFillRectangle(display, drawable, gc, x, y, width, height);
|
||
}
|
||
}
|
||
|
||
/*----------------------------------------------------------------------
|
||
* TixpSubRegDrawImage --
|
||
*
|
||
* Draws a Tk image in a subregion.
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TixpSubRegDrawImage(subRegPtr, image, imageX, imageY, width, height,
|
||
drawable, drawableX, drawableY)
|
||
TixpSubRegion * subRegPtr;
|
||
Tk_Image image;
|
||
int imageX;
|
||
int imageY;
|
||
int width;
|
||
int height;
|
||
Drawable drawable;
|
||
int drawableX;
|
||
int drawableY;
|
||
{
|
||
Drawable dest;
|
||
|
||
if (subRegPtr->pixmap != None) {
|
||
dest = subRegPtr->pixmap;
|
||
drawableX -= subRegPtr->x;
|
||
drawableY -= subRegPtr->y;
|
||
} else {
|
||
dest = drawable;
|
||
}
|
||
|
||
Tk_RedrawImage(image, imageX, imageY, width, height, dest,
|
||
drawableX, drawableY);
|
||
}
|
||
|
||
void
|
||
TixpSubRegDrawBitmap(display, drawable, gc, subRegPtr, bitmap, src_x, src_y,
|
||
width, height, dest_x, dest_y, plane)
|
||
Display *display;
|
||
Drawable drawable;
|
||
GC gc;
|
||
TixpSubRegion * subRegPtr;
|
||
Pixmap bitmap;
|
||
int src_x, src_y;
|
||
int width, height;
|
||
int dest_x, dest_y;
|
||
unsigned long plane;
|
||
{
|
||
XSetClipOrigin(display, gc, dest_x, dest_y);
|
||
if (subRegPtr->pixmap != None) {
|
||
XCopyPlane(display, bitmap, subRegPtr->pixmap, gc, src_x, src_y,
|
||
width, height, dest_x - subRegPtr->x, dest_y - subRegPtr->y,
|
||
plane);
|
||
} else {
|
||
XCopyPlane(display, bitmap, drawable, gc, src_x, src_y, width, height,
|
||
dest_x, dest_y, plane);
|
||
}
|
||
XSetClipOrigin(display, gc, 0, 0);
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TixpSubRegDrawAnchorLines --
|
||
*
|
||
* Draw anchor lines inside the given sub region.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* None
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TixpSubRegDrawAnchorLines(display, drawable, gc, subRegPtr, x, y, w, h)
|
||
Display *display; /* Display to draw on. */
|
||
Drawable drawable; /* Drawable to draw on. */
|
||
GC gc; /* Use the foreground color of this GC. */
|
||
TixpSubRegion * subRegPtr; /* Describes the subregion. */
|
||
int x; /* x pos of top-left corner of anchor rect */
|
||
int y; /* y pos of top-left corner of anchor rect */
|
||
int w; /* width of anchor rect */
|
||
int h; /* height of anchor rect */
|
||
{
|
||
Drawable dest;
|
||
|
||
if (subRegPtr->pixmap != None) {
|
||
dest = subRegPtr->pixmap;
|
||
x -= subRegPtr->x;
|
||
y -= subRegPtr->y;
|
||
} else {
|
||
dest = drawable;
|
||
}
|
||
|
||
TixpDrawAnchorLines(display, dest, gc, x, y, w, h);
|
||
}
|