From be9279836d090eeb1196c31583fe2a5b596c2473 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Wed, 16 Apr 2003 10:11:38 +0000 Subject: *** empty log message *** --- win/WinPort.c | 1011 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ win/makefile.vc | 178 ++++++++++ 2 files changed, 1189 insertions(+) create mode 100644 win/WinPort.c create mode 100644 win/makefile.vc (limited to 'win') diff --git a/win/WinPort.c b/win/WinPort.c new file mode 100644 index 0000000..9187c57 --- /dev/null +++ b/win/WinPort.c @@ -0,0 +1,1011 @@ +/* + * WinPort.c -- Compatibility layer for Windows 2k + * + * Authors : Patrick Lecoanet. + * Creation date : + * + * $Id$ + */ + +/* + * Copyright (c) 2003 - CENA, Patrick Lecoanet -- + * + * This code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this code; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef _WIN32 + +#include "Geo.h" +#include +#include +#include "Types.h" + +static const char rcsid[] = "$Id"; +static const char compile_id[]="$Compile$"; + +/* + *---------------------------------------------------------------------- + * + * ZnUnionRegion -- + * + * Compute the union of two regions. + * + * Results: + * Returns the result in the dr_return region. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +void +ZnUnionRegion(TkRegion sra, + TkRegion srb, + TkRegion dr_return) +{ + CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_OR); +} + +/* + *---------------------------------------------------------------------- + * + * ZnOffsetRegion -- + * + * Offset a region by the specified pixel offsets. + * + * Results: + * Returns the result in the dr_return region. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +void +ZnOffsetRegion(TkRegion reg, + int dx, + int dy) +{ + OffsetRgn((HRGN) reg, dx, dy); +} + +/* + *---------------------------------------------------------------------- + * + * ZnPolygonRegion -- + * + * Compute a region from a polygon. + * + * Results: + * Returns the result in the dr_return region. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +TkRegion +ZnPolygonRegion(XPoint *points, + int n, + int fill_rule) +{ + POINT *pts; + HRGN reg; + int i; + char msg[256]; + + pts = ZnMalloc(n*sizeof(POINT)); + for (i = 0; i < n; i++, points++) { + pts[i].x = points->x; + pts[i].y = points->y; + } + + reg = CreatePolygonRgn(pts, n, + fill_rule==EvenOddRule?ALTERNATE:WINDING); + if (!reg) { + sprintf(msg, "Polygon region failed: %ld, n: %d\n", GetLastError(), n); + OutputDebugString(msg); + } + ZnFree(pts); + return (TkRegion) reg; +} + +#define PI 3.14159265358979 +#define XAngleToRadians(a) ((double)(a) / 64 * PI / 180); + +/* + * Translation table between X gc functions and Win32 raster op modes. + */ + +int tkpWinRopModes[] = { + R2_BLACK, /* GXclear */ + R2_MASKPEN, /* GXand */ + R2_MASKPENNOT, /* GXandReverse */ + R2_COPYPEN, /* GXcopy */ + R2_MASKNOTPEN, /* GXandInverted */ + R2_NOT, /* GXnoop */ + R2_XORPEN, /* GXxor */ + R2_MERGEPEN, /* GXor */ + R2_NOTMERGEPEN, /* GXnor */ + R2_NOTXORPEN, /* GXequiv */ + R2_NOT, /* GXinvert */ + R2_MERGEPENNOT, /* GXorReverse */ + R2_NOTCOPYPEN, /* GXcopyInverted */ + R2_MERGENOTPEN, /* GXorInverted */ + R2_NOTMASKPEN, /* GXnand */ + R2_WHITE /* GXset */ +}; + +/* + * The following two raster ops are used to copy the foreground and background + * bits of a source pattern as defined by a stipple used as the pattern. + */ + +#define COPYFG 0x00CA0749 /* dest = (pat & src) | (!pat & dst) */ +#define COPYBG 0x00AC0744 /* dest = (!pat & src) | (pat & dst) */ + +/* + * The followng typedef is used to pass Windows GDI drawing functions. + */ + +typedef BOOL (CALLBACK *WinDrawFunc) _ANSI_ARGS_((HDC dc, + CONST POINT* points, int npoints)); + +typedef struct ThreadSpecificData { + POINT *winPoints; /* Array of points that is reused. */ + int nWinPoints; /* Current size of point array. */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + +/* + *---------------------------------------------------------------------- + * + * SetUpGraphicsPort -- + * + * Set up the graphics port from the given GC. + * + * Results: + * None. + * + * Side effects: + * The current port is adjusted. + * + *---------------------------------------------------------------------- + */ + +static HPEN +SetUpGraphicsPort(gc) + GC gc; +{ + DWORD style; + + if (gc->line_style == LineOnOffDash) { + unsigned char *p = (unsigned char *) &(gc->dashes); + /* pointer to the dash-list */ + + /* + * Below is a simple translation of serveral dash patterns + * to valid windows pen types. Far from complete, + * but I don't know how to do it better. + * Any ideas: + */ + + if (p[1] && p[2]) { + if (!p[3] || p[4]) { + style = PS_DASHDOTDOT; /* -.. */ + } else { + style = PS_DASHDOT; /* -. */ + } + } else { + if (p[0] > (4 * gc->line_width)) { + style = PS_DASH; /* - */ + } else { + style = PS_DOT; /* . */ + } + } + } else { + style = PS_SOLID; + } + if (gc->line_width < 2) { + return CreatePen(style, gc->line_width, gc->foreground); + } else { + LOGBRUSH lb; + + lb.lbStyle = BS_SOLID; + lb.lbColor = gc->foreground; + lb.lbHatch = 0; + + style |= PS_GEOMETRIC; + switch (gc->cap_style) { + case CapNotLast: + case CapButt: + style |= PS_ENDCAP_FLAT; + break; + case CapRound: + style |= PS_ENDCAP_ROUND; + break; + default: + style |= PS_ENDCAP_SQUARE; + break; + } + switch (gc->join_style) { + case JoinMiter: + style |= PS_JOIN_MITER; + break; + case JoinRound: + style |= PS_JOIN_ROUND; + break; + default: + style |= PS_JOIN_BEVEL; + break; + } + return ExtCreatePen(style, gc->line_width, &lb, 0, NULL); + } +} + +/* + *---------------------------------------------------------------------- + * + * ConvertPoints -- + * + * Convert an array of X points to an array of Win32 points. + * + * Results: + * Returns the converted array of POINTs. + * + * Side effects: + * Allocates a block of memory in thread local storage that + * should not be freed. + * + *---------------------------------------------------------------------- + */ + +static POINT * +ConvertPoints(points, npoints, mode, bbox) + XPoint *points; + int npoints; + int mode; /* CoordModeOrigin or CoordModePrevious. */ + RECT *bbox; /* Bounding box of points. */ +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + int i; + + /* + * To avoid paying the cost of a malloc on every drawing routine, + * we reuse the last array if it is large enough. + */ + + if (npoints > tsdPtr->nWinPoints) { + if (tsdPtr->winPoints != NULL) { + ckfree((char *) tsdPtr->winPoints); + } + tsdPtr->winPoints = (POINT *) ckalloc(sizeof(POINT) * npoints); + if (tsdPtr->winPoints == NULL) { + tsdPtr->nWinPoints = -1; + return NULL; + } + tsdPtr->nWinPoints = npoints; + } + + bbox->left = bbox->right = points[0].x; + bbox->top = bbox->bottom = points[0].y; + + if (mode == CoordModeOrigin) { + for (i = 0; i < npoints; i++) { + tsdPtr->winPoints[i].x = points[i].x; + tsdPtr->winPoints[i].y = points[i].y; + bbox->left = MIN(bbox->left, tsdPtr->winPoints[i].x); + bbox->right = MAX(bbox->right, tsdPtr->winPoints[i].x); + bbox->top = MIN(bbox->top, tsdPtr->winPoints[i].y); + bbox->bottom = MAX(bbox->bottom, tsdPtr->winPoints[i].y); + } + } else { + tsdPtr->winPoints[0].x = points[0].x; + tsdPtr->winPoints[0].y = points[0].y; + for (i = 1; i < npoints; i++) { + tsdPtr->winPoints[i].x = tsdPtr->winPoints[i-1].x + points[i].x; + tsdPtr->winPoints[i].y = tsdPtr->winPoints[i-1].y + points[i].y; + bbox->left = MIN(bbox->left, tsdPtr->winPoints[i].x); + bbox->right = MAX(bbox->right, tsdPtr->winPoints[i].x); + bbox->top = MIN(bbox->top, tsdPtr->winPoints[i].y); + bbox->bottom = MAX(bbox->bottom, tsdPtr->winPoints[i].y); + } + } + return tsdPtr->winPoints; +} + +/* + *---------------------------------------------------------------------- + * + * XFillRectangles -- + * + * Fill multiple rectangular areas in the given drawable. + * + * Results: + * None. + * + * Side effects: + * Draws onto the specified drawable. + * + *---------------------------------------------------------------------- + */ +void +XFillRectangles(display, d, gc, rectangles, nrectangles) + Display* display; + Drawable d; + GC gc; + XRectangle* rectangles; + int nrectangles; +{ + HDC dc; + int i; + RECT rect; + TkWinDCState state; + HBRUSH brush; + TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask; + + if (d == None) { + return; + } + + dc = TkWinGetDrawableDC(display, d, &state); + SetROP2(dc, tkpWinRopModes[gc->function]); + brush = CreateSolidBrush(gc->foreground); + + if (clipPtr && clipPtr->type == TKP_CLIP_REGION) { + SelectClipRgn(dc, (HRGN) clipPtr->value.region); + OffsetClipRgn(dc, gc->clip_x_origin, gc->clip_y_origin); + } + if ((gc->fill_style == FillStippled + || gc->fill_style == FillOpaqueStippled) + && gc->stipple != None) { + TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; + HBRUSH oldBrush, stipple; + HBITMAP oldBitmap, bitmap; + HDC dcMem; + HBRUSH bgBrush = CreateSolidBrush(gc->background); + + if (twdPtr->type != TWD_BITMAP) { + panic("unexpected drawable type in stipple"); + } + + /* + * Select stipple pattern into destination dc. + */ + + stipple = CreatePatternBrush(twdPtr->bitmap.handle); + SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL); + oldBrush = SelectObject(dc, stipple); + dcMem = CreateCompatibleDC(dc); + + /* + * For each rectangle, create a drawing surface which is the size of + * the rectangle and fill it with the background color. Then merge the + * result with the stipple pattern. + */ + + for (i = 0; i < nrectangles; i++) { + bitmap = CreateCompatibleBitmap(dc, rectangles[i].width, + rectangles[i].height); + oldBitmap = SelectObject(dcMem, bitmap); + rect.left = 0; + rect.top = 0; + rect.right = rectangles[i].width; + rect.bottom = rectangles[i].height; + FillRect(dcMem, &rect, brush); + BitBlt(dc, rectangles[i].x, rectangles[i].y, rectangles[i].width, + rectangles[i].height, dcMem, 0, 0, COPYFG); + if (gc->fill_style == FillOpaqueStippled) { + FillRect(dcMem, &rect, bgBrush); + BitBlt(dc, rectangles[i].x, rectangles[i].y, + rectangles[i].width, rectangles[i].height, dcMem, + 0, 0, COPYBG); + } + SelectObject(dcMem, oldBitmap); + DeleteObject(bitmap); + } + + DeleteDC(dcMem); + SelectObject(dc, oldBrush); + DeleteObject(stipple); + DeleteObject(bgBrush); + } else { + for (i = 0; i < nrectangles; i++) { + TkWinFillRect(dc, rectangles[i].x, rectangles[i].y, + rectangles[i].width, rectangles[i].height, gc->foreground); + } + } + DeleteObject(brush); + TkWinReleaseDrawableDC(d, dc, &state); +} + + +/* + *---------------------------------------------------------------------- + * + * XFillRectangle -- + * + * Fills a rectangular area in the given drawable. This procedure + * is implemented as a call to XFillRectangles. + * + * Results: + * None + * + * Side effects: + * Fills the specified rectangle. + * + *---------------------------------------------------------------------- + */ + +void +XFillRectangle(display, d, gc, x, y, width, height) + Display* display; + Drawable d; + GC gc; + int x; + int y; + unsigned int width; + unsigned int height; +{ + XRectangle rectangle; + rectangle.x = x; + rectangle.y = y; + rectangle.width = width; + rectangle.height = height; + XFillRectangles(display, d, gc, &rectangle, 1); +} + +/* + *---------------------------------------------------------------------- + * + * RenderObject -- + * + * This function draws a shape using a list of points, a + * stipple pattern, and the specified drawing function. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +RenderObject(dc, gc, points, npoints, mode, pen, func) + HDC dc; + GC gc; + XPoint* points; + int npoints; + int mode; + HPEN pen; + WinDrawFunc func; +{ + RECT rect; + HPEN oldPen; + HBRUSH oldBrush; + POINT *winPoints = ConvertPoints(points, npoints, mode, &rect); + TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask; + + if (clipPtr && clipPtr->type == TKP_CLIP_REGION) { + SelectClipRgn(dc, (HRGN) clipPtr->value.region); + OffsetClipRgn(dc, gc->clip_x_origin, gc->clip_y_origin); + } + if ((gc->fill_style == FillStippled + || gc->fill_style == FillOpaqueStippled) + && gc->stipple != None) { + + TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; + HDC dcMem; + LONG width, height; + HBITMAP oldBitmap; + int i; + HBRUSH oldMemBrush; + + if (twdPtr->type != TWD_BITMAP) { + panic("unexpected drawable type in stipple"); + } + + /* + * Grow the bounding box enough to account for line width. + */ + + rect.left -= gc->line_width; + rect.top -= gc->line_width; + rect.right += gc->line_width; + rect.bottom += gc->line_width; + + width = rect.right - rect.left; + height = rect.bottom - rect.top; + + /* + * Select stipple pattern into destination dc. + */ + + SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL); + oldBrush = SelectObject(dc, CreatePatternBrush(twdPtr->bitmap.handle)); + + /* + * Create temporary drawing surface containing a copy of the + * destination equal in size to the bounding box of the object. + */ + + dcMem = CreateCompatibleDC(dc); + oldBitmap = SelectObject(dcMem, CreateCompatibleBitmap(dc, width, + height)); + oldPen = SelectObject(dcMem, pen); + BitBlt(dcMem, 0, 0, width, height, dc, rect.left, rect.top, SRCCOPY); + + /* + * Translate the object for rendering in the temporary drawing + * surface. + */ + + for (i = 0; i < npoints; i++) { + winPoints[i].x -= rect.left; + winPoints[i].y -= rect.top; + } + + /* + * Draw the object in the foreground color and copy it to the + * destination wherever the pattern is set. + */ + + SetPolyFillMode(dcMem, (gc->fill_rule == EvenOddRule) ? ALTERNATE + : WINDING); + oldMemBrush = SelectObject(dcMem, CreateSolidBrush(gc->foreground)); + (*func)(dcMem, winPoints, npoints); + BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, COPYFG); + + /* + * If we are rendering an opaque stipple, then draw the polygon in the + * background color and copy it to the destination wherever the pattern + * is clear. + */ + + if (gc->fill_style == FillOpaqueStippled) { + DeleteObject(SelectObject(dcMem, + CreateSolidBrush(gc->background))); + (*func)(dcMem, winPoints, npoints); + BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, + COPYBG); + } + + SelectObject(dcMem, oldPen); + DeleteObject(SelectObject(dcMem, oldMemBrush)); + DeleteObject(SelectObject(dcMem, oldBitmap)); + DeleteDC(dcMem); + } else { + oldPen = SelectObject(dc, pen); + oldBrush = SelectObject(dc, CreateSolidBrush(gc->foreground)); + SetROP2(dc, tkpWinRopModes[gc->function]); + + SetPolyFillMode(dc, (gc->fill_rule == EvenOddRule) ? ALTERNATE + : WINDING); + + (*func)(dc, winPoints, npoints); + + SelectObject(dc, oldPen); + } + DeleteObject(SelectObject(dc, oldBrush)); +} + +/* + *---------------------------------------------------------------------- + * + * XDrawLines -- + * + * Draw connected lines. + * + * Results: + * None. + * + * Side effects: + * Renders a series of connected lines. + * + *---------------------------------------------------------------------- + */ + +void +XDrawLines(display, d, gc, points, npoints, mode) + Display* display; + Drawable d; + GC gc; + XPoint* points; + int npoints; + int mode; +{ + HPEN pen; + TkWinDCState state; + HDC dc; + TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask; + + if (d == None) { + return; + } + + dc = TkWinGetDrawableDC(display, d, &state); + + if (clipPtr && clipPtr->type == TKP_CLIP_REGION) { + SelectClipRgn(dc, (HRGN) clipPtr->value.region); + OffsetClipRgn(dc, gc->clip_x_origin, gc->clip_y_origin); + } + pen = SetUpGraphicsPort(gc); + SetBkMode(dc, TRANSPARENT); + RenderObject(dc, gc, points, npoints, mode, pen, Polyline); + DeleteObject(pen); + + TkWinReleaseDrawableDC(d, dc, &state); +} + +/* + *---------------------------------------------------------------------- + * + * XDrawLine -- + * + * Draw a single line between two points in a given drawable. + * + * Results: + * None. + * + * Side effects: + * Draws a single line segment. + * + *---------------------------------------------------------------------- + */ + +void +XDrawLine(display, d, gc, x1, y1, x2, y2) + Display* display; + Drawable d; + GC gc; + int x1, y1, x2, y2; /* Coordinates of line segment. */ +{ + XPoint points[2]; + + points[0].x = x1; + points[0].y = y1; + points[1].x = x2; + points[1].y = y2; + XDrawLines(display, d, gc, points, 2, CoordModeOrigin); +} + +/* + *---------------------------------------------------------------------- + * + * XFillPolygon -- + * + * Draws a filled polygon. + * + * Results: + * None. + * + * Side effects: + * Draws a filled polygon on the specified drawable. + * + *---------------------------------------------------------------------- + */ + +void +XFillPolygon(display, d, gc, points, npoints, shape, mode) + Display* display; + Drawable d; + GC gc; + XPoint* points; + int npoints; + int shape; + int mode; +{ + HPEN pen; + TkWinDCState state; + HDC dc; + + if (d == None) { + return; + } + + dc = TkWinGetDrawableDC(display, d, &state); + + pen = GetStockObject(NULL_PEN); + RenderObject(dc, gc, points, npoints, mode, pen, Polygon); + + TkWinReleaseDrawableDC(d, dc, &state); +} + +/* + *---------------------------------------------------------------------- + * + * XDrawRectangle -- + * + * Draws a rectangle. + * + * Results: + * None. + * + * Side effects: + * Draws a rectangle on the specified drawable. + * + *---------------------------------------------------------------------- + */ + +void +XDrawRectangle(display, d, gc, x, y, width, height) + Display* display; + Drawable d; + GC gc; + int x; + int y; + unsigned int width; + unsigned int height; +{ + HPEN pen, oldPen; + TkWinDCState state; + HBRUSH oldBrush; + HDC dc; + TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask; + + if (d == None) { + return; + } + + dc = TkWinGetDrawableDC(display, d, &state); + + if (clipPtr && clipPtr->type == TKP_CLIP_REGION) { + SelectClipRgn(dc, (HRGN) clipPtr->value.region); + OffsetClipRgn(dc, gc->clip_x_origin, gc->clip_y_origin); + } + pen = SetUpGraphicsPort(gc); + SetBkMode(dc, TRANSPARENT); + oldPen = SelectObject(dc, pen); + oldBrush = SelectObject(dc, GetStockObject(NULL_BRUSH)); + SetROP2(dc, tkpWinRopModes[gc->function]); + + Rectangle(dc, x, y, x+width+1, y+height+1); + + DeleteObject(SelectObject(dc, oldPen)); + SelectObject(dc, oldBrush); + TkWinReleaseDrawableDC(d, dc, &state); +} + +/* + *---------------------------------------------------------------------- + * + * DrawOrFillArc -- + * + * This procedure handles the rendering of drawn or filled + * arcs and chords. + * + * Results: + * None. + * + * Side effects: + * Renders the requested arc. + * + *---------------------------------------------------------------------- + */ + +static void +DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, fill) + Display *display; + Drawable d; + GC gc; + int x, y; /* left top */ + unsigned int width, height; + int start; /* start: three-o'clock (deg*64) */ + int extent; /* extent: relative (deg*64) */ + int fill; /* ==0 draw, !=0 fill */ +{ + HDC dc; + HBRUSH brush, oldBrush; + HPEN pen, oldPen; + TkWinDCState state; + int clockwise = (extent < 0); /* non-zero if clockwise */ + int xstart, ystart, xend, yend; + double radian_start, radian_end, xr, yr; + TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask; + + if (d == None) { + return; + } + + dc = TkWinGetDrawableDC(display, d, &state); + + if (clipPtr && clipPtr->type == TKP_CLIP_REGION) { + SelectClipRgn(dc, (HRGN) clipPtr->value.region); + OffsetClipRgn(dc, gc->clip_x_origin, gc->clip_y_origin); + } + SetROP2(dc, tkpWinRopModes[gc->function]); + + /* + * Compute the absolute starting and ending angles in normalized radians. + * Swap the start and end if drawing clockwise. + */ + + start = start % (64*360); + if (start < 0) { + start += (64*360); + } + extent = (start+extent) % (64*360); + if (extent < 0) { + extent += (64*360); + } + if (clockwise) { + int tmp = start; + start = extent; + extent = tmp; + } + radian_start = XAngleToRadians(start); + radian_end = XAngleToRadians(extent); + + /* + * Now compute points on the radial lines that define the starting and + * ending angles. Be sure to take into account that the y-coordinate + * system is inverted. + */ + + if (gc->fill_style == FillStippled && gc->stipple != None) { + xr = width / 2.0; + yr = height / 2.0; + } + else { + xr = x + width / 2.0; + yr = y + height / 2.0; + } + xstart = (int)((xr + cos(radian_start)*width/2.0) + 0.5); + ystart = (int)((yr + sin(-radian_start)*height/2.0) + 0.5); + xend = (int)((xr + cos(radian_end)*width/2.0) + 0.5); + yend = (int)((yr + sin(-radian_end)*height/2.0) + 0.5); + + /* + * Now draw a filled or open figure. Note that we have to + * increase the size of the bounding box by one to account for the + * difference in pixel definitions between X and Windows. + */ + + pen = SetUpGraphicsPort(gc); + oldPen = SelectObject(dc, pen); + if (!fill) { + /* + * Note that this call will leave a gap of one pixel at the + * end of the arc for thin arcs. We can't use ArcTo because + * it's only supported under Windows NT. + */ + + SetBkMode(dc, TRANSPARENT); + Arc(dc, x, y, x+width+1, y+height+1, xstart, ystart, xend, yend); + } else { + brush = CreateSolidBrush(gc->foreground); + + if (gc->fill_style == FillStippled && gc->stipple != None) { + TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; + HBITMAP oldBitmap; + HDC dcMem; + HBRUSH oldMemBrush; + + if (twdPtr->type != TWD_BITMAP) { + panic("unexpected drawable type in stipple"); + } + + /* + * Select stipple pattern into destination dc. + */ + SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL); + oldBrush = SelectObject(dc, + CreatePatternBrush(twdPtr->bitmap.handle)); + + /* + * Create temporary drawing surface containing a copy of the + * destination equal in size to the bounding box of the object. + */ + dcMem = CreateCompatibleDC(dc); + oldBitmap = SelectObject(dcMem, + CreateCompatibleBitmap(dc, width, height)); + BitBlt(dcMem, 0, 0, width, height, dc, x, y, SRCCOPY); + oldMemBrush = SelectObject(dcMem, brush); + if (gc->arc_mode == ArcChord) { + Chord(dcMem, 0, 0, width+1, height+1, xstart, ystart, xend, yend); + } else if ( gc->arc_mode == ArcPieSlice ) { + Pie(dcMem, 0, 0, width+1, height+1, xstart, ystart, xend, yend); + } + + BitBlt(dc, x, y, width, height, dcMem, 0, 0, COPYFG); + DeleteObject(SelectObject(dcMem, oldBitmap)); + DeleteObject(SelectObject(dcMem, oldMemBrush)); + DeleteObject(SelectObject(dc, oldBrush)); + DeleteDC(dcMem); + } else { + oldBrush = SelectObject(dc, brush); + if (gc->arc_mode == ArcChord) { + Chord(dc, x, y, x+width+1, y+height+1, xstart, ystart, xend, yend); + } else if ( gc->arc_mode == ArcPieSlice ) { + Pie(dc, x, y, x+width+1, y+height+1, xstart, ystart, xend, yend); + } + DeleteObject(SelectObject(dc, oldBrush)); + } + } + DeleteObject(SelectObject(dc, oldPen)); + TkWinReleaseDrawableDC(d, dc, &state); +} + +/* + *---------------------------------------------------------------------- + * + * XDrawArc -- + * + * Draw an arc. + * + * Results: + * None. + * + * Side effects: + * Draws an arc on the specified drawable. + * + *---------------------------------------------------------------------- + */ + +void +XDrawArc(display, d, gc, x, y, width, height, start, extent) + Display* display; + Drawable d; + GC gc; + int x; + int y; + unsigned int width; + unsigned int height; + int start; + int extent; +{ + display->request++; + + DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 0); +} + +/* + *---------------------------------------------------------------------- + * + * XFillArc -- + * + * Draw a filled arc. + * + * Results: + * None. + * + * Side effects: + * Draws a filled arc on the specified drawable. + * + *---------------------------------------------------------------------- + */ + +void +XFillArc(display, d, gc, x, y, width, height, start, extent) + Display* display; + Drawable d; + GC gc; + int x; + int y; + unsigned int width; + unsigned int height; + int start; + int extent; +{ + display->request++; + + DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 1); +} + +#endif /* _WIN32 */ diff --git a/win/makefile.vc b/win/makefile.vc new file mode 100644 index 0000000..2d21adc --- /dev/null +++ b/win/makefile.vc @@ -0,0 +1,178 @@ +# Generated automatically from Makefile.in by configure. +# Copyright (c) 1993 - 2002 CENA, Patrick Lecoanet -- +# +# This code is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this code; if not, write to the Free +# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# $Revision$ +# +srcdir = . + +SHELL = /bin/sh + +# Visual Studio 6 default +TOOLS32 = C:\Progra~1\Microsoft Visual Studio\VC98 +CC = "$(TOOLS32)\bin\cl.exe" +LD = "$(TOOLS32)\bin\link.exe" -link50compat +libpath32 = /LIBPATH:"$(TOOLS32)\lib" +include32 = /I"$(TOOLS32)\include" +CP = copy +RM = del + +PERLCONFIG = INSTALLDIRS=perl + +INSTALL_PERL = install_perl + +prefix = c:\lecoanet +exec_prefix = $(prefix) + +bindir = $(exec_prefix)\bin +libdir = $(exec_prefix)\lib +incdir = $(prefix)\include +mandir = $(prefix)\man\man3 + +windir = $(srcdir)\win +genericdir = $(srcdir) +tktmpdir = $(srcdir)\tkwin +ptktmpdir = $(srcdir)\ptkwin + +tcl_inc_dir = $(prefix)\tcl8.4.1 +tk_inc_dir = $(prefix)\tk8.4.1 +INCLUDES = /I$(srcdir) $(include32) + +TCL_TK_VER = 84 +# Assume that WISH is already INSTALLED +TCLSH = $(bindir)\tclsh$(TCL_TK_VER) +WISH = $(bindir)\wish$(TCL_TK_VER) +WIN_LIBS = glu32.lib user32.lib gdi32.lib ws2_32.lib +#GL_LIBS = +GL_LIBS = opengl32.lib +PTKROOT = c:\perl\site\lib +TKLIBS = $(libdir)\tcl$(TCL_TK_VER).lib \ + $(libdir)\tk$(TCL_TK_VER).lib \ + $(GL_LIBS) $(WIN_LIBS) +PTKLIBS = $(PTKROOT)\auto\Tk\Tk.lib $(GL_LIBS) $(WIN_LIBS) + +ZINC_VER = 3 +ZINC_MAJOR = 2 + +# +# Recognized compilation time flags are : +# +# PROFILE ask for profile support +# OM include code for internal overlap manager +# GL include code that need GL support. +# GL_PRINT_CONFIG display the detected hardware capabilities +# GL_DAMAGE redraw only modified areas +# SHAPE include code for reshaping windows. +# +DFLAGS= /DOM /DGL /DGL_DAMAGE /DGL_PRINT_CONFIG +#DFLAGS= /DOM +#DFLAGS = /DTCL_MEM_DEBUG + +# Max speed +#CDEBUG = -O2 -Gs +# Debug +CDEBUG = -Z7 -Od +CFLAGS = /c /W3 /nologo /YX $(CDEBUG) /DWIN /DDLL_BUILD /DBUILD_Tkzinc $(DFLAGS) +TKCPPFLAGS = /Fp$(tktmpdir)\ $(INCLUDES) /I"$(incdir)" /I$(tk_inc_dir)\generic /I$(tk_inc_dir)\win /I$(tcl_inc_dir)\generic /I$(tcl_inc_dir)\win +PTKCPPFLAGS = /DPTK /Fp$(ptktmpdir)\ $(INCLUDES) /I$(PTKROOT)\Tk\pTk /I$(PTKROOT)\Tk + +LFLAGS = /nologo /machine:IX86 /warn:3 $(libpath32) +DLLENTRY = @12 +DLLLFLAGS = $(LFLAGS) /entry:_DllMainCRTStartup$(DLLENTRY) /dll + +TKDLLOBJS = $(tktmpdir)\Track.obj \ + $(tktmpdir)\Tabular.obj \ + $(tktmpdir)\Reticle.obj \ + $(tktmpdir)\Map.obj \ + $(tktmpdir)\Rectangle.obj \ + $(tktmpdir)\Arc.obj \ + $(tktmpdir)\Curve.obj \ + $(tktmpdir)\Item.obj \ +# $(tktmpdir)\PostScript.obj \ + $(tktmpdir)\MapInfo.obj \ + $(tktmpdir)\Attrs.obj \ + $(tktmpdir)\Draw.obj \ + $(tktmpdir)\Geo.obj \ + $(tktmpdir)\List.obj \ +# $(tktmpdir)\perfos.obj \ + $(tktmpdir)\version.obj \ + $(tktmpdir)\Transfo.obj \ + $(tktmpdir)\Group.obj \ + $(tktmpdir)\Icon.obj \ + $(tktmpdir)\Text.obj \ + $(tktmpdir)\Color.obj \ + $(tktmpdir)\Field.obj \ + $(tktmpdir)\Triangles.obj \ + $(tktmpdir)\Window.obj \ + $(tktmpdir)\tkZinc.obj \ + $(tktmpdir)\OverlapMan.obj \ + $(tktmpdir)\WinPort.obj \ + $(tktmpdir)\Image.obj + +PTKDLLOBJS = $(ptktmpdir)\Track.obj \ + $(ptktmpdir)\Tabular.obj \ + $(ptktmpdir)\Reticle.obj \ + $(ptktmpdir)\Map.obj \ + $(ptktmpdir)\Rectangle.obj \ + $(ptktmpdir)\Arc.obj \ + $(ptktmpdir)\Curve.obj \ + $(ptktmpdir)\Item.obj \ +# $(ptktmpdir)\PostScript.obj \ + $(ptktmpdir)\MapInfo.obj \ + $(ptktmpdir)\Attrs.obj \ + $(ptktmpdir)\Draw.obj \ + $(ptktmpdir)\Geo.obj \ + $(ptktmpdir)\List.obj \ +# $(ptktmpdir)\perfos.obj \ + $(ptktmpdir)\version.obj \ + $(ptktmpdir)\Transfo.obj \ + $(ptktmpdir)\Group.obj \ + $(ptktmpdir)\Icon.obj \ + $(ptktmpdir)\Text.obj \ + $(ptktmpdir)\Color.obj \ + $(ptktmpdir)\Field.obj \ + $(ptktmpdir)\Triangles.obj \ + $(ptktmpdir)\Window.obj \ + $(ptktmpdir)\tkZinc.obj \ + $(ptktmpdir)\OverlapMan.obj \ + $(ptktmpdir)\WinPort.obj \ + $(ptktmpdir)\Image.obj + +DLL=Tkzinc.dll +PTKAR=ptkzinc.lib + +$(DLL): $(TKDLLOBJS) + $(LD) $(DLLLFLAGS) $(TKLIBS) -out:$@ $(TKDLLOBJS) + +$(PTKAR): $(PTKDLLOBJS) + LIB $(PTKDLLOBJS) /OUT:$@ + +{$(windir)}.c{$(tktmpdir)}.obj: + $(CC) $(TKCPPFLAGS) $(CFLAGS) -Fo$(tktmpdir)\ $< + +{$(genericdir)}.c{$(tktmpdir)}.obj: + $(CC) $(TKCPPFLAGS) $(CFLAGS) -Fo$(tktmpdir)\ $< + +{$(windir)}.c{$(ptktmpdir)}.obj: + $(CC) $(PTKCPPFLAGS) $(CFLAGS) -Fo$(ptktmpdir)\ $< + +{$(genericdir)}.c{$(ptktmpdir)}.obj: + $(CC) $(PTKCPPFLAGS) $(CFLAGS) -Fo$(ptktmpdir)\ $< + +mostlyclean: + $(RM) *.bak *~ $(tmpdir)\*.obj +clean: + $(RM) *.bak *~ $(tmpdir)\*.obj *.dll -- cgit v1.1