diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..a6ddb5c --- /dev/null +++ b/ChangeLog @@ -0,0 +1,29 @@ +2000-09-13 Donal K. Fellows + + * configure.in: Fixed a blooper that assumed that Tcl and Tk were + installed in the same directory. + +2000-09-11 Donal K. Fellows + + * configure.in: Changed to build correctly on Solaris (at least on + my workstation...) Also altered mechanism for guessing whether to + support photo image shapes to use configure instead of testing + what was defined in tkInt.h... + +2000-09-10 Donal K. Fellows + + * license.txt: Pulled this out into a single file. Made all + source files reference this one for license. + + * shape.test: Started work on writing a test suite. Will need to + continue on a Unix system so results - particularly of get + operations - can be used to help write the suite... + +2000-09-09 Donal K. Fellows + + * shape.h: Altered KIND_* definitions to have a SHAPE_ prefix. + + * shapeInt.h: Created this file. Shape_RenderTextAsRectangles now + defined throuth this header and made "private" to the extension by + changing its name, as its applicability to other domains is really + small. Other files updated to take account of this... diff --git a/README b/README new file mode 100644 index 0000000..619ab9b --- /dev/null +++ b/README @@ -0,0 +1,24 @@ +Shaped Window Extension 0.4 for Tcl/Tk, Source Code Distribution +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This distribution is made under the terms described in the +"license.txt" file. + +It allows a system that uses the Tk toolkit over the Tcl interpreter +(of at least version 8.0) to work with windows whose shapes are +described by other than a simple rectangle. + +There is some documentation (both as NROFF source, with the tmac.an +macro package loaded, and PostScript as generated from that source +with GROFF) in the shape0.4/doc directory. + +There are some demonstrations in the shape0.4/demos directory. + +Any bug reports or feature suggestions are welcome; please send them +to the author at fellowsd@cs.man.ac.uk The author does not (at the +time of writing) provide commercial-level support for this software. + +Note that this software should be considered to be of no better than +beta quality on Unix and alpha quality on Windows. It is likely that +there will be a fair number more interim distributions like this one +before a full release. diff --git a/demos/dragger.tcl b/demos/dragger.tcl new file mode 100644 index 0000000..9646177 --- /dev/null +++ b/demos/dragger.tcl @@ -0,0 +1,106 @@ +#!/bin/sh + +# dragger.tcl --- +# +# Quick demo using the shape library to provide a coloured cursor +# +# Copyright (c) 1997 by Donal K. Fellows +# +# The author hereby grants permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# +# $Id: demo.tcl,v 1.1 1997/09/17 21:10:23 donal Exp donal $ + +# Now we make cunning use of the backslash/shell trick \ +[ -x `dirname $0`/../shapewish ] && exec `dirname $0`/../shapewish $0 ${1+"$@"} || exec wish8.0 $0 ${1+"$@"} || { echo "`basename $0`: couldn't start wish" >&2 ; exit 1; } + +set dir [file join [pwd] [file dirname [info script]] ..] +lappend auto_path [file join $dir ..] +package require Shape + +set images [file join $dir images] + +set none [list @[file join $images none.cur] blue] + +image create photo redptr -file [file join $images ptr-red.gif] +image create photo greenptr -file [file join $images ptr-green.gif] +image create photo doc -file [file join $images doc-img.gif] +set ptrxbm @[file join $images ptr-mask.xbm] +set docxbm @[file join $images doc-mask.xbm] + +pack [label .l -justify l -text "Drag off this window to see a coloured\ + cursor\n(implemented using a canvas and the non-rectangular\nwindow\ + extension) in action.\n\nNow it is your turn to take this away and\ + build a full\ndrag-and-drop system around this.\n\nOther things you\ + could try include animated cursors,\nXEyes and OClock clones, etc."] + +toplevel .cursor +wm withdraw .cursor +wm overrideredirect .cursor 1 +pack [canvas .cursor.workarea -bd 0 -highlightthick 0] +set image(status) [.cursor.workarea create image 0 0 \ + -anchor nw -image greenptr] +set image(doc) [.cursor.workarea create image 3 4 \ + -anchor nw -image doc] +#pack [label .cursor.ptr -bd 0 -image greenptr] +update idletasks +shape set .cursor.workarea -offset 0 0 bitmap $ptrxbm +shape upd .cursor.workarea + -offset 3 4 bitmap $docxbm +shape set .cursor window .cursor.workarea + +proc movecursor {x y} { + global image + wm geometry .cursor +$x+$y + update idletasks + set w [winfo containing $x $y] + if {[string length $w] && [winfo toplevel $w] == "."} { + .cursor.workarea itemconf $image(status) -image greenptr + } else { + .cursor.workarea itemconf $image(status) -image redptr + } +} +proc showcursor {w x y} { + global savedcursor none + set savedcursor [list $w conf -cursor [$w cget -cursor]] + $w conf -cursor $none + movecursor $x $y + wm deiconify .cursor + raise .cursor + after 250 raisewin .cursor +} +proc raisewin w { + if {[winfo exists $w] && [winfo ismapped $w]} { + raise $w + after 250 raisewin $w + } +} + +proc hidecursor {} { + global savedcursor + wm withdraw .cursor + eval $savedcursor +} + +bind . <1> {showcursor %W %X %Y} +bind . {movecursor %X %Y} +bind . {hidecursor} diff --git a/demos/fancytext.tcl b/demos/fancytext.tcl new file mode 100644 index 0000000..a0bee3b --- /dev/null +++ b/demos/fancytext.tcl @@ -0,0 +1,87 @@ +#!/bin/sh + +# dragger.tcl --- +# +# Quick demo using the shape library to provide a coloured cursor +# +# Copyright (c) 1997 by Donal K. Fellows +# +# The author hereby grants permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# +# $Id: demo.tcl,v 1.1 1997/09/17 21:10:23 donal Exp donal $ + +# Now we make cunning use of the backslash/shell trick \ +[ -x `dirname $0`/../shapewish ] && exec `dirname $0`/../shapewish $0 ${1+"$@"} || exec wish8.0 $0 ${1+"$@"} || { echo "`basename $0`: couldn't start wish" >&2 ; exit 1; } + +set dir [file join [pwd] [file dirname [info script]] ..] +lappend auto_path [file join $dir ..] +package require Shape + +set font {Helvetica 72 bold} +. conf -bg black +pack [canvas .c -bg black -bd 0 -highlightthick 0] -fill both -expand 1 +shape set .c text "Some Text" $font +set bb [shape bound .c] +set offmax [lindex $bb 3] +proc moveLine {idx} { + global count line inc + .c move $idx 0 $inc($idx) + incr count($idx) $inc($idx) +} +proc moveFwds {idx} { + global count offmax delay inc + if {$count($idx)<$offmax} { + moveLine $idx + after $delay($idx) moveFwds $idx + } else { + set inc($idx) [expr -$inc($idx)] + moveBack $idx + } +} +proc moveBack {idx} { + global count offmax delay inc bb + if {$count($idx)>[lindex $bb 1]} { + moveLine $idx + after $delay($idx) moveBack $idx + } else { + set inc($idx) [expr -$inc($idx)] + moveFwds $idx + } +} +proc move {line delayVal incVal} { + global count delay inc + set count($line) 0 + set delay($line) $delayVal + set inc($line) $incVal + moveFwds $line +} +set width [expr [lindex $bb 0]+[lindex $bb 2]] +set height [expr [lindex $bb 1]+[lindex $bb 3]] +wm geometry . ${width}x${height} +wm sizefrom . user +update +move [.c create line 0 0 [lindex $bb 2] 0 -fill blue] 50 2 +move [.c create line 0 0 [lindex $bb 2] 0 -fill green] 50 3 +move [.c create line 0 0 [lindex $bb 2] 0 -fill red] 50 5 +move [.c create line 0 0 [lindex $bb 2] 0 -fill yellow] 50 7 diff --git a/demos/fingerprint.tcl b/demos/fingerprint.tcl new file mode 100644 index 0000000..84151ac --- /dev/null +++ b/demos/fingerprint.tcl @@ -0,0 +1,29 @@ +#!/bin/sh + +# This little demo (in the splendid tradition of xteddy and xbomb :^) +# is due to John LoVerso and I have adapted it +# a little in order to increase its effectiveness. + +# Now we make cunning use of the backslash/shell trick \ +[ -x `dirname $0`/../shapewish ] && exec `dirname $0`/../shapewish $0 ${1+"$@"} || exec wish8.0 $0 ${1+"$@"} || { echo "`basename $0`: couldn't start wish" >&2 ; exit 1; } + +set dir [file join [pwd] [file dirname [info script]] ..] +lappend auto_path [file join $dir ..] +package require Shape + +set images [file join $dir images] + +. config -bg tan -cursor dotbox +wm overrideredirect . 1 +wm withdraw . +update idle +shape set . -bound bitmap @[file join $images fingerprint.xbm] +wm deiconify . +bind . <1> { + regexp {\+(-?[0-9]+)\+(-?[0-9]+)} [winfo geometry .] dummy x y + set x [expr $x-%X] + set y [expr $y-%Y] +} +bind . { + wm geometry . +[expr %X+$x]+[expr %Y+$y] +} diff --git a/demos/images/doc-img.gif b/demos/images/doc-img.gif new file mode 100644 index 0000000..0d61b38 Binary files /dev/null and b/demos/images/doc-img.gif differ diff --git a/demos/images/doc-mask.xbm b/demos/images/doc-mask.xbm new file mode 100644 index 0000000..db06e16 --- /dev/null +++ b/demos/images/doc-mask.xbm @@ -0,0 +1,14 @@ +#define doc-mask_width 32 +#define doc-mask_height 32 +static unsigned char doc-mask_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, + 0xfe, 0x3f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, + 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, + 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, + 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, + 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, + 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, + 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, + 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/demos/images/fingerprint.xbm b/demos/images/fingerprint.xbm new file mode 100644 index 0000000..84e95bf --- /dev/null +++ b/demos/images/fingerprint.xbm @@ -0,0 +1,32 @@ +#define fingerprint_width 48 +#define fingerprint_height 56 +static char fingerprint_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x18, 0xff, 0x04, 0x00, 0x00, 0x00, 0xe4, 0x81, 0x1f, 0x00, + 0x00, 0x00, 0xb6, 0x1f, 0x1c, 0x00, 0x00, 0x00, 0xfd, 0xf0, 0x38, 0x00, + 0x00, 0x80, 0x14, 0x80, 0x53, 0x00, 0x00, 0xc0, 0x12, 0x3f, 0x76, 0x00, + 0x00, 0x60, 0xcb, 0x60, 0xac, 0x00, 0x00, 0x20, 0x6d, 0x98, 0xb9, 0x01, + 0x00, 0xa0, 0x35, 0x34, 0x53, 0x01, 0x00, 0xb0, 0x12, 0x6b, 0xb6, 0x01, + 0x00, 0xd0, 0xb2, 0x51, 0xa4, 0x06, 0x00, 0x50, 0xaf, 0x90, 0x2c, 0x05, + 0x00, 0x58, 0xab, 0xa0, 0x28, 0x05, 0x00, 0x68, 0xeb, 0x20, 0x69, 0x05, + 0x00, 0xe8, 0x6a, 0x20, 0x4b, 0x0d, 0x00, 0xa8, 0x77, 0x4e, 0x52, 0x09, + 0x00, 0xd8, 0x35, 0x53, 0x4a, 0x0a, 0x00, 0xb4, 0xb5, 0x51, 0x4a, 0x1a, + 0x00, 0x64, 0xb5, 0x56, 0x56, 0x12, 0x00, 0x74, 0xbd, 0x56, 0x50, 0x14, + 0x00, 0xdc, 0xaf, 0x56, 0x96, 0x14, 0x00, 0xec, 0xaa, 0x5a, 0x9e, 0x1d, + 0x00, 0xa4, 0x9e, 0x4a, 0x1a, 0x11, 0x00, 0x74, 0x57, 0x6b, 0x2a, 0x11, + 0x00, 0x5c, 0x55, 0x2d, 0x52, 0x13, 0x00, 0x24, 0x4b, 0x24, 0x52, 0x24, + 0x00, 0xb8, 0x6b, 0x24, 0xb1, 0x24, 0x00, 0x98, 0x2b, 0x92, 0x24, 0x29, + 0x00, 0x44, 0x2d, 0x92, 0x26, 0x03, 0x00, 0x30, 0x36, 0x9a, 0x4e, 0x04, + 0x00, 0x0c, 0x1b, 0x8b, 0x4a, 0x28, 0x00, 0xc4, 0x06, 0x25, 0xca, 0x21, + 0x00, 0x64, 0xc3, 0x25, 0x1a, 0x27, 0x00, 0x18, 0x78, 0x12, 0x23, 0x2c, + 0x00, 0x08, 0x8f, 0xcb, 0xd9, 0x2f, 0x00, 0xf8, 0xe1, 0x60, 0x38, 0x26, + 0x00, 0x88, 0x3d, 0x18, 0xe6, 0x09, 0x00, 0x18, 0x07, 0x86, 0x01, 0x37, + 0x00, 0x68, 0xf9, 0x73, 0xfe, 0x11, 0x00, 0x90, 0x05, 0x9e, 0x03, 0x0b, + 0x00, 0x10, 0x8f, 0x79, 0xfc, 0x00, 0x00, 0x20, 0xf0, 0x0f, 0x03, 0x04, + 0x00, 0xe0, 0x07, 0x80, 0x7f, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x80, 0x04, + 0x00, 0x80, 0x07, 0x80, 0x3e, 0x02, 0x00, 0x00, 0x84, 0x7f, 0x00, 0x01, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x85, 0x83, 0x00, + 0x00, 0x00, 0x00, 0x34, 0x34, 0x00, 0x00, 0x00, 0x00, 0x90, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; diff --git a/demos/images/none.cur b/demos/images/none.cur new file mode 100644 index 0000000..78a1c6d --- /dev/null +++ b/demos/images/none.cur @@ -0,0 +1,6 @@ +#define none_width 1 +#define none_height 1 +#define none_x_hot 0 +#define none_y_hot 0 +static unsigned char none_bits[] = { + 0x00}; diff --git a/demos/images/ptr-green.gif b/demos/images/ptr-green.gif new file mode 100644 index 0000000..f4e4500 Binary files /dev/null and b/demos/images/ptr-green.gif differ diff --git a/demos/images/ptr-mask.xbm b/demos/images/ptr-mask.xbm new file mode 100644 index 0000000..5ef4fc3 --- /dev/null +++ b/demos/images/ptr-mask.xbm @@ -0,0 +1,4 @@ +#define ptr-mask_width 8 +#define ptr-mask_height 8 +static unsigned char ptr-mask_bits[] = { + 0x00, 0x07, 0x1e, 0x7e, 0x06, 0x06, 0x04, 0x04, }; diff --git a/demos/images/ptr-red.gif b/demos/images/ptr-red.gif new file mode 100644 index 0000000..b8924c1 Binary files /dev/null and b/demos/images/ptr-red.gif differ diff --git a/doc/CombShape.3 b/doc/CombShape.3 new file mode 100644 index 0000000..1eb2bcc --- /dev/null +++ b/doc/CombShape.3 @@ -0,0 +1,186 @@ +'\" -*- nroff -*- +'\" Copyright (c) 2000 Donal K. Fellows +'\" +'\" The author hereby grants permission to use, copy, modify, distribute, +'\" and license this software and its documentation for any purpose, provided +'\" that existing copyright notices are retained in all copies and that this +'\" notice is included verbatim in any distributions. No written agreement, +'\" license, or royalty fee is required for any of the authorized uses. +'\" Modifications to this software may be copyrighted by their authors +'\" and need not follow the licensing terms described here, provided that +'\" the new terms are clearly indicated on the first page of each file where +'\" they apply. +'\" +'\" IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY +'\" FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +'\" ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +'\" DERIVATIVES THEREOF, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE +'\" POSSIBILITY OF SUCH DAMAGE. +'\" +'\" THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +'\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +'\" FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +'\" IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE +'\" NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +'\" MODIFICATIONS. +'\" +'\" $Id$ +'\" +.so man.macros +.TH Shape_MoveShape 3 0.4 Shape "Non-rectangular Window Extension" + +.BS +.SH "NAME" +Shape_CombineBitmap, Shape_CombineRectangles, +Shape_CombineRectanglesOrdered, Shape_CombineRegion, +Shape_CombineWindow, Shape_MoveShape \- apply a shaping to a window +.SH "SYNOPSIS" +.nf +\fB#include \fR +\fB#include \fR +.sp +int +\fBShape_CombineBitmap(\fIinterp, tkwin, kind, op, x, y, bitmap\fB)\fR +.sp +int +\fBShape_CombineRectangles(\fIinterp, tkwin, kind, op, rectc, rectv\fB)\fR +.sp +int +\fBShape_CombineRectanglesOrdered(\fIinterp, tkwin, kind, op, rectc, rectv\fB)\fR +.sp +int +\fBShape_CombineRegion(\fIinterp, tkwin, kind, op, x, y, region\fB)\fR +.sp +int +\fBShape_CombineWindow(\fIinterp, tkwin, kind, op, x, y, srcwin\fB)\fR +.sp +int +\fBShape_MoveShape(\fIinterp, tkwin, kind, x, y\fB)\fR +.SH "ARGUMENTS" +.AS "Tk_Window" "*interp" +.AP Tcl_Interp *interp in +Interpreter to use for error reporting. +.AP Tk_Window tkwin in +Token for window to apply the shaping operation to. +.AP int kind in +Which shape should the operation be applied to; must be a boolean +combination of SHAPE_BOUNDING, SHAPE_CLIP, and SHAPE_TOPLEVEL. +.AP int op in +What kind of operation to apply; should be SHAPE_OP_SET, +SHAPE_OP_UNION, SHAPE_OP_INTERSECT, SHAPE_OP_SUBTRACT, or +SHAPE_OP_INVERT. +.AP int x in +Offset (along X axis) to apply to shape. +.AP int y in +Offset (along Y axis) to apply to shape. +.AP Pixmap bitmap in +Identifier for a bitmap that defines a shape to apply. +.AP int rectc in +Number of rectangles in array. +.AP XRectangle *rectv in +Array of rectangles that define a shape to apply. +.AP TkRegion region in +Token for region defining the shape to apply. +.AP Tk_Window srcwin in +Token for window whose shape is to be used to apply. +.BE + +.SH "DESCRIPTION" +.PP +These functions let you set and modify the shape of a given window, +\fItkwin\fR. Each \fIShape_Combine*\fR function operates almost the +same, supporting the same options as to what parts of the window to +apply the shaping operation to (\fIkind\fR,) and the same kinds of +ways of applying a shape (\fIop\fR.) Most also support the +application of an offset \fI(x,y)\fR to the shape to be applied before +application to the window, making it easier to support resizing +windows. Each function returns TCL_OK on success, and TCL_ERROR on +failure (when it leaves a description of the problem in \fIinterp\fR +suitable for passing back to calling code.) + +.PP +.B Shape_CombineBitmap +applies the shape defined by the given bitmap, \fIbitmap\fR, to the +window. + +.PP +.B Shape_CombineRegion +applies the shape defined by the given region, \fIregion\fR, to the +window. + +.PP +.B Shape_CombineWindow +applies the shape already defined on another window, \fIsrcwin\fR, to +a window (useful for propagating shapes up window hierarchies.) + +.PP +.B Shape_CombineRectangles +applies the shape defined by an array of \fRrectc\fR rectangles, +\fIrectv\fR, to the window. No overall transformation for the +rectangles is supported, since that is easily applied in the calling +code. + +.PP +.B Shape_CombineRectanglesOrdered +applies the shape defined by an array of \fIrectc\fR rectangles, +\fIrectv\fR, to the window. The rectangles must be arranged so that +they are non-overlapping and proceed in strict scanline order. \fINot +all platforms make use of this extra information.\fR No overall +transformation for the rectangles is supported, since that is easily +applied in the calling code. + +.PP +.B Shape_MoveShape +applies a translation (defined by \fI(x,y)\fR in the coordinate system +of the root window) to the specified shape of the window. + +.SH "OPERATIONS" + +Five operations are supported: +.TP 25 +SHAPE_OP_SET +This sets the shape of the window to be that specified by the source. +.TP 25 +SHAPE_OP_UNION +This updates the shape of the window to include that specified by the +source. +.TP 25 +SHAPE_OP_INTERSECT +This updates the shape of the window to be the overlap between the +current shape of the window and the shape of the source. +.TP 25 +SHAPE_OP_SUBTRACT +This updates the shape of the window to \fIexclude\fR the shape of the +source. +.TP 25 +SHAPE_OP_INVERT +This sets the shape of the window to be wherever was not previously in +the shape of the window. The source is ignored. +.LP + +.SH "MODIFICATION TARGETS" + +Under X, each window has two different shapes; the bounding shape and +the clipping shape. The \fIbounding\fR shape specifies which parts of +the window obscure things which are in underlying windows, and the +\fIclipping\fR shape specifies which parts of the window are actually +drawn upon by the application. The space between is the border of the +window. Note that parts of windows that can be drawn upon but which +do not obscure the underlying matter cannot actually be seen anyway. + +Tk manages its own borders, so these two shapes should normally be +made identical (by passing KIND_BOTH to the \fIkind\fR parameter.) +These functions support individual modification though. + +To make things more complex (\fIi.e.\fR to help the implementation of +menubars and embedded windows,) Tk implements toplevel windows using +several X windows. This means that to alter the shape of a toplevel, +it is also necessary to modify the shape of the containing window. +This operation is performed automatically if the KIND_TOPLEVEL flag is +set in the \fIkind\fR parameter. + +.SH "AUTHOR" +Donal K. Fellows \fC\fR + +.SH "SEE ALSO" +shape(n), Shape_GetBbox(3), Shape_RenderTextAsRectangles(3) diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..1a32775 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,8 @@ +doc: CombShape.ps QuryShape.ps shape.ps + +MANTOPS=groff -man + +%.ps: %.3 + $(MANTOPS) $< >$@ +%.ps: %.n + $(MANTOPS) $< >$@ diff --git a/doc/QuryShape.3 b/doc/QuryShape.3 new file mode 100644 index 0000000..ae72324 --- /dev/null +++ b/doc/QuryShape.3 @@ -0,0 +1,121 @@ +'\" -*- nroff -*- +'\" Copyright (c) 2000 Donal K. Fellows +'\" +'\" The author hereby grants permission to use, copy, modify, distribute, +'\" and license this software and its documentation for any purpose, provided +'\" that existing copyright notices are retained in all copies and that this +'\" notice is included verbatim in any distributions. No written agreement, +'\" license, or royalty fee is required for any of the authorized uses. +'\" Modifications to this software may be copyrighted by their authors +'\" and need not follow the licensing terms described here, provided that +'\" the new terms are clearly indicated on the first page of each file where +'\" they apply. +'\" +'\" IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY +'\" FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +'\" ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +'\" DERIVATIVES THEREOF, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE +'\" POSSIBILITY OF SUCH DAMAGE. +'\" +'\" THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +'\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +'\" FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +'\" IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE +'\" NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +'\" MODIFICATIONS. +'\" +'\" $Id$ +'\" +.so man.macros +.TH Shape_QueryVersion 3 0.4 Shape "Non-rectangular Window Extension" + +.BS +.SH "NAME" +Shape_GetBbox, Shape_GetShapeRectanglesObj, Shape_QueryVersion, +Shape_ExtensionPresent \- get info about a shaping or the shaping +subsystem +.SH "SYNOPSIS" +.nf +\fB#include \fR +.sp +int +\fBShape_GetBbox(\fIinterp, tkwin, getClip, valid, x1, y1, x2, y2\fB)\fR +.sp +int +\fBShape_GetShapeRectanglesObj(\fIinterp, tkwin, getClip\fB)\fR +.sp +int +\fBShape_QueryVersion(\fItkwin, majorPtr, minorPtr\fB)\fR +.sp +int +\fBShape_ExtensionPresent(\fItkwin\fB)\fR +.SH "ARGUMENTS" +.AS "Tk_Window" "*majorPtr" +.AP Tcl_Interp *interp in +Interpreter to use for error reporting and providing the result from +\fBShape_GetShapeRectanglesObj\fR. +.AP Tk_Window tkwin in +Token for window to query the shaping of. +.AP int getClip in +Whether to use the clipping shape of the window (see MODIFICATION +TARGETS in the Shape_MoveShape(3) manual page for a discussion.) +.AP int *valid out +Whether a valid bounding box is present for the shape of the window. +.AP int *x1 out +The x-coordinate of the left side of the bounding box. +.AP int *y1 out +The y-coordinate of the top side of the bounding box. +.AP int *x2 out +The x-coordinate of the right side of the bounding box. +.AP int *y2 out +The y-coordinate of the bottom side of the bounding box. +.AP int *majorPtr out +The major version of the X Shaped Window extension installed on the +XServer. +.AP int *minorPtr out +The minor version of the X Shaped Window extension installed on the +XServer. +.BE + +.SH "DESCRIPTION" +.B Shape_GetBbox +queries the bounding box of the bounding shape (or the clipping shape +if \IgetClip\fR is set) of the given window (specified by +\fItkwin\fR.) If a shape is defined for the window, the flag +indicated by \fIvalid\fR is set and the bounds are passed in \fIx1\fR, +\fIy1\fR, \fIx2\fR and \fIy2\fR. If no shape is defined for the +window, the flag is reset instead. In both cases, TCL_OK is returned +from the function. If an error occurs, a message is left in the +specified interpreter and TCL_ERROR is returned; \fIvalid\fR is not +modified in this case. + +.B Shape_GetShapeRectanglesObj +queries the bounding shape (or the clipping shape if \IgetClip\fR is +set) of the given window (specified by \fItkwin\fR.) If the shape is +successfully queried, a description of the shape in terms of a list of +rectangles (each rectangle being represented by a list of four +elements identifying the coordinates of that rectangle) is placed in +the interpreter, \fIinterp\fR, and TCL_OK is returned. If an error +occurs, a suitable message is placed in the interpreter, and TCL_ERROR +is returned. + +.B Shape_QueryVersion +queries the version of the XShape extension installed on the (display +of the) XServer which window \fItkwin\fR exists on. The result is +non-zero (true) if the query was successful (in which case the +variables identified by \fImajorVersion\fR and \fIminorVersion\fR are +updated to contain the version number details) and zero (false) if the +query failed. \fIDummy values are returned under Windows.\fR + +.B Shape_ExtensionPresent +queries whether the XShape extension is installed on the XServer which +window \fItkwin\fR exists on, returning a non-zero (true) value if +this is the case. \fIThis function always succeeds on Windows due to +the way the linking works.\fR This function is normally only called +during the initialisation of the extension. + +.SH "AUTHOR" +Donal K. Fellows \fC\fR + +.SH "SEE ALSO" +shape(n), Shape_MoveShape(3), Shape_RenderTextAsRectangles(3) diff --git a/doc/man.macros b/doc/man.macros new file mode 100644 index 0000000..67e6012 --- /dev/null +++ b/doc/man.macros @@ -0,0 +1,234 @@ +'\" The definitions below are for supplemental macros used in Tcl/Tk +'\" manual entries. +'\" +'\" .AP type name in/out ?indent? +'\" Start paragraph describing an argument to a library procedure. +'\" type is type of argument (int, etc.), in/out is either "in", "out", +'\" or "in/out" to describe whether procedure reads or modifies arg, +'\" and indent is equivalent to second arg of .IP (shouldn't ever be +'\" needed; use .AS below instead) +'\" +'\" .AS ?type? ?name? +'\" Give maximum sizes of arguments for setting tab stops. Type and +'\" name are examples of largest possible arguments that will be passed +'\" to .AP later. If args are omitted, default tab stops are used. +'\" +'\" .BS +'\" Start box enclosure. From here until next .BE, everything will be +'\" enclosed in one large box. +'\" +'\" .BE +'\" End of box enclosure. +'\" +'\" .CS +'\" Begin code excerpt. +'\" +'\" .CE +'\" End code excerpt. +'\" +'\" .VS ?br? +'\" Begin vertical sidebar, for use in marking newly-changed parts +'\" of man pages. If an argument is present, then a line break is +'\" forced before starting the sidebar. +'\" +'\" .VE +'\" End of vertical sidebar. +'\" +'\" .DS +'\" Begin an indented unfilled display. +'\" +'\" .DE +'\" End of indented unfilled display. +'\" +'\" .SO +'\" Start of list of standard options for a Tk widget. The +'\" options follow on successive lines, in four columns separated +'\" by tabs. +'\" +'\" .SE +'\" End of list of standard options for a Tk widget. +'\" +'\" .OP cmdName dbName dbClass +'\" Start of description of a specific option. cmdName gives the +'\" option's name as specified in the class command, dbName gives +'\" the option's name in the option database, and dbClass gives +'\" the option's class in the option database. +'\" +'\" .UL arg1 arg2 +'\" Print arg1 underlined, then print arg2 normally. +'\" +'\" SCCS: @(#) man.macros 1.8 96/02/15 20:02:24 +'\" +'\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +'\" # Start an argument description +.de AP +.ie !"\\$4"" .TP \\$4 +.el \{\ +. ie !"\\$2"" .TP \\n()Cu +. el .TP 15 +.\} +.ie !"\\$3"" \{\ +.ta \\n()Au \\n()Bu +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !"\\$2"" \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +'\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !"\\$1"" .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +'\" # BS - start boxed text +'\" # ^y = starting y location +'\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +'\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +'\" # VS - start vertical sidebar +'\" # ^Y = starting y location +'\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !"\\$1"" .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +'\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +'\" # Special macro to handle page bottom: finish off current +'\" # box/sidebar if in box/sidebar mode, then invoked standard +'\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +'\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +'\" # DE - end display +.de DE +.fi +.RE +.sp +.. +'\" # SO - start of list of standard options +.de SO +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 4c 8c 12c +.ft B +.. +'\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\fBoptions\\fR manual entry for details on the standard options. +.. +'\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +'\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +'\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.de UL +\\$1\l'|0\(ul'\\$2 +.. diff --git a/doc/shape.n b/doc/shape.n new file mode 100644 index 0000000..3df7f5e --- /dev/null +++ b/doc/shape.n @@ -0,0 +1,333 @@ +'\" -*- nroff -*- +'\" Copyright (c) 1997-2000 Donal K. Fellows +'\" +'\" The author hereby grants permission to use, copy, modify, distribute, +'\" and license this software and its documentation for any purpose, provided +'\" that existing copyright notices are retained in all copies and that this +'\" notice is included verbatim in any distributions. No written agreement, +'\" license, or royalty fee is required for any of the authorized uses. +'\" Modifications to this software may be copyrighted by their authors +'\" and need not follow the licensing terms described here, provided that +'\" the new terms are clearly indicated on the first page of each file where +'\" they apply. +'\" +'\" IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY +'\" FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +'\" ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +'\" DERIVATIVES THEREOF, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE +'\" POSSIBILITY OF SUCH DAMAGE. +'\" +'\" THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +'\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +'\" FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +'\" IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE +'\" NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +'\" MODIFICATIONS. +'\" +'\" $Id$ +'\" +.so man.macros +.TH shape n 0.4 Shape "Non-rectangular Window Extension" +.BS + +.SH NAME +shape \- Set/update/query shaped window information + +.SH SYNOPSIS +\fBpackage require shape 0.4\fR + +\fBshape \fIoption window \fR?\fIarg ...\fR? +.BE + +.SH DESCRIPTION +.PP +The \fBshape\fR command is used to manipulate windows so as to make +them have non-rectangular shapes. It also permits the querying of the +current status of windows to see what shape they have. The +\fBshape\fR can have any of several forms, depending on the +\fIoption\fR argument: + +.TP +\fBshape bounds \fIwindow \fR?\fIkind\fR? +Returns the bounding box of the shape of \fIwindow\fR, or an empty +string if the window does not currently have a shape set for it +(i.e. it is rectangular.) The \fIkind\fR option allows the selection +of which shape to retrieve the bounding box of. The \fB-bounding\fR +option indicates that the bounding shape of the window is to be +queried (the default.) The \fB-clip\fR option indicates that the +clipping shape of the window is to be queried. + +.TP +\fBshape get \fIwindow \fR?\fIkind\fR? +Returns a list of rectangles describing the shape of \fIwindow\fR. If +\fIwindow\fR currently has no shape set for it, this command returns +the Xserver's current idea of the rectangular shape of \fIwindow\fR +which might or might not be ``sensible''. The \fIkind\fR option +allows the selection of which shape to retrieve the shape of. The +\fB-bounding\fR option indicates that the bounding shape of the window +is to be queried (the default.) The \fB-clip\fR option indicates that +the clipping shape of the window is to be queried. + +.TP +\fBshape offset \fIwindow \fR?\fIkind\fR? \fIxOffset yOffset\fR +Moves the shape of \fIwindow\fR by \fIxOffset\fR pixels right and +\fIyOffset\fR pixels down, relative to the overall position of +\fIwindow\fR. The contents of \fIwindow\fR do not move. + +The \fIkind\fR option allows the selection of which shape to move. +The \fB-bounding\fR option indicates that the bounding shape of +\fIwindow\fR is to be moved. The \fB-clip\fR option indicates that +the clipping shape of \fIwindow\fR is to be moved. The \fB-both\fR +option (the default) moves both the bounding and the clipping shapes +of \fIwindow\fR. + +.TP +\fBshape set \fIwindow \fR?\fIkind\fR? ?\fI-offset xOffset yOffset\fR? \fIsourcekind \fR?\fIarg ...\fR? +Sets the shape of \fIwindow\fR to the shape specified by the source +described by \fIsourcekind ...\fR, possibly pre-offset by +(\fIxOffset\fR,\fIyOffset\fR), much as in the \fBshape offset\fR +command. Shape sources are described in ``SHAPE SOURCES'' below. + +The \fIkind\fR option allows the selection of which shape to set. The +\fB-bounding\fR option indicates that the bounding shape of +\fIwindow\fR is to be set. The \fB-clip\fR option indicates that the +clipping shape of \fIwindow\fR is to be set. The \fB-both\fR option +(the default) sets both the bounding and the clipping shapes of +\fIwindow\fR. + +.TP +\fBshape update \fIwindow operation \fR?\fIkind\fR? ?\fI-offset xOffset yOffset\fR? \fIsourcekind \fR?\fIarg ...\fR? +Updates the shape of \fIwindow\fR, applying a shape using set +operation \fIoperation\fR. The shape applied is specified by the +source described by \fIsourcekind ...\fR and is possibly pre-offset by +(\fIxOffset\fR,\fIyOffset\fR), much as in the \fBshape offset\fR +command. Shape sources are described in ``SHAPE SOURCES'' below. + +The \fIkind\fR option allows the selection of which shape to set. The +\fB-bounding\fR option indicates that the bounding shape of +\fIwindow\fR is to be set. The \fB-clip\fR option indicates that the +clipping shape of \fIwindow\fR is to be set. The \fB-both\fR option +(the default) sets both the bounding and the clipping shapes of +\fIwindow\fR. + +The following set operations (and unique abbreviations of them) are +supported: +.RS + +.TP +\fBset\fR (aliases: \fB:=\fR, \fB=\fR) +The shape specified by the source becomes the shape of \fIwindow\fR. + +.TP +\fBunion\fR (aliases: \fB+=\fR, \fB||\fR) +The new shape of \fIwindow\fR consists of all areas specified in +either the old shape of \fIwindow\fR, or by the source. + +.TP +\fBintersect\fR (aliases: \fB*=\fR, \fB&&\fR) +The new shape of \fIwindow\fR consists of all areas specified in both +the old shape of \fIwindow\fR, and by the source. + +.TP +\fBsubtract\fR (aliases: \fB-=\fR) +The new shape of \fIwindow\fR consists of all areas specified by the +old shape of \fIwindow\fR that are not specified by the source. + +.TP +\fBinvert\fR (no aliases) +The new shape of \fIwindow\fR consists of all areas specified by the +source that are not specified by the old shape of \fIwindow\fR. +.RE + +.TP +\fBshape version\fR +Return the version number of the non-rectangular window extension +installed on the X server that serves the screen that \fB.\fR is on. +Note that this is \fInot\fR the version number of the Tcl/Tk +extension, which is reported in the (global) variables +\fBshape_version\fR and \fBshape_patchLevel\fR. + +.VS +\fBThis returns a dummy value on Windows.\fR +.VE + +.SH "SHAPE SOURCES" + +.VS +There are six types of shape sources, though they are not universally +supported: +.VE + +.TP +\fBbitmap \fIbitmap\fR +This uses the outline of \fIbitmap\fR (which may be any string +acceptable to \fBTk_GetBitmap\fR) as a shape source. The same +information is supplied to operations involving bounding and clipping +shapes. + +.VS +\fBThis operation is not supported on Windows.\fR + +.TP +\fBphoto \fIphotoImageName\fR +This uses (with a suitably patched Tk core) the transparency +information from the given photo image (specified using any string +acceptable to \fBTk_GetPhoto\fR). The same information is supplied to +operations involving bounding and clipping shapes. +.VE + +.TP +\fBrectangles \fIrectangleList\fR +This uses the union of the rectangles in \fIrectangleList\fR as a +source of shape information (the same information is supplied to +operations involving bounding and clipping shapes). Each rectangle is +described a list of four numbers \fIx1\fR, \fIy1\fR, \fIx2\fR and +\fIy2\fR where (\fIx1\fR,\fIy1\fR) is the top-left corner of the +rectangle, and (\fIx2\fR,\fIy2\fR) is the bottom-right corner of the +rectangle. + +.TP +\fBreset\fR +This resets the shape of the window the operation is being applied to +to a rectangle with the dimensions of the window (or at least, the +dimensions that the Xserver thinks that the window has.) This +operation is only valid as part of the \fBshape set\fR command. It +ought to mark the window as not being shaped at all, but there is no +protocol for this in version 1.0 of the X non-rectangular window +extension, making it an impossible operation. + +.TP +\fBtext \fIstring font\fR +This uses an image of \fIstring\fR drawn in \fIfont\fR as a source of +shape information (the same information is supplied to operations +involving bounding and clipping shapes) where \fIfont\fR is any string +acceptable to \fBTk_GetFont\fR. Note that only spaces are supported +as whitespace characters in \fIstring\fR, and that the effects of +using newline and tab characters is undefined. + +.VS +\fBThis operation is not supported on Windows.\fR +.VE + +.TP +\fBwindow \fIwindow\fR +This uses \fIwindow\fR as a source of shape information, with the +bounding shape of \fIwindow\fR being used to supply bounding +information, and the clipping shape of \fIwindow\fR being used to +supply clipping information. + +.SH "KINDS OF SHAPE" + +Every window has two kinds of shape; their \fBbounding\fR and their +\fBclipping\fR shapes. The \fBbounding\fR shape of a window describes +the area covered by that window, and the \fBclipping\fR shape of a +window describes the part of the window occupied by the contents of +that window. The area of the window contained in the bounding area of +the window but not in the clipping area of the window is (X) border of +the window. This border is not useful under Tk (which manages all +widget borders internally,) so the default kinds that the various +operations work on are such that read-only operations work by default +on the bounding shape (via the \fB-bounding\fR option) and read-write +operations work by default on both the clip and the bounding shapes +(via the \fB-both\fR option.) The \fB-clip\fR option is unlikely to +be useful in normal operation. + +.VS +\fIWindows only supports one kind of shape, so the difference between +clipping and bounding regions is ignored.\fR +.VE + +.SH CAVEATS + +When setting the shape of a toplevel window, make sure that you +perform an \fBupdate idletasks\fR between the creation of the toplevel +and applying a \fBshape set\fR or \fBshape update\fR operation to it. +This is because Tk works by reparenting toplevel windows into a +(user-invisible) container, so allowing the introduction of a menubar +to windows without having to alter the internal dimensions of the +toplevel. Because this is done on an idle handler, you must wait +until after that idle handler has executed before applying a reshape +operation to a toplevel. Failure to do this will result in the +reshaped toplevel being apparently encased in a toplevel window that +is unresponsive to all events (like Expose events). While no harm is +done to the application, this an undesirable effect that you probably +do not want in your application. Sometime, I will have a go at fixing +this. + +This extension can only handle applications that use a single screen, +or at least, it can only handle those that only attempt to use shaped +windows on the same screen as \fB.\fR Since this is the vast majority +of all applications, this should not prove too onerous a restriction +for the present. +.VS +\fIThis might have been fixed. Need to test...\fR +.VE + +Updating window shapes can be a very expensive operation, so you are +advised to avoid doing it as much as possible (do not use it as a way +of doing animation \- it does not work well.) Of course, if you need +to change the shape, then do so, but you should try to find ways that +do it as little as possible due to it being an expensive operation. + +Some other X clients can run far slower if they have to interact with +shaped windows. The troublemakers are not always the clients that you +would expect to cause problems. + +.SH "DEMO PROGRAMS" + +All these programs are located in \fCshape0.4/demos\fR. + +.TP +\fBdragger.tcl\fR +This creates a window that when Mouse Button 1 is depressed in, brings +up a coloured cursor that (partially) changes colour depending on +whether the cursor is over the source window or not. + +.TP +\fBfancytext.tcl\fR +A fairly simple, but effective, demonstration of how to make a simple +piece of text look far more effective using moving lines clipped to +the text to suggest the letters without showing them all at once. + +.TP +\fBfingerprint.tcl\fR +This puts a grubby-looking fingerprint on the screen. The fingerprint +can be dragged about the screen (the cursor changes when it is +possible to drag the fingerprint). Thanks to John LoVerso +\fC\fR for this little demo! + +.SH TO-DO + +I need fix the caveat relating to toplevels and check for and resolve +any conflicts with some of the other capabilities of toplevels +(especially the \fB-menu\fR and \fB-use\fR options). + +I want to write some code to install the extension. + +.VS +I \fIneed\fR to test the code for Windows, but I have no compiler that +can target the platform. Also, anyone who can supply code to convert +bitmaps or text to regions is welcome to contribute! + +I would like input about using non-rectangular windows on other Tk +platforms (notably the Mac.) +.VE + +It would be rather nice to be able to anchor cutouts to corners/edges +of a window and have them handle window resizes correctly. Possibly +also a scaling operation could be added. + +.VS +At some point, I ought to look into more complex alpha blending, which +some people report that is supported in a few places. It does have +the disadvantage of only being able to work on systems with at least +15 or 16 bits per pixel; 8-bpp displays (like the ones I use) simply +do not have the hardware to cope with this... +.VE + +There are probably loads of other things that need doing, but I can't +think of them right now. +.SH AUTHOR +Donal K. Fellows \fC\fR +.SH KEYWORDS +shape, window diff --git a/generic/shape.c b/generic/shape.c new file mode 100644 index 0000000..fcb5c66 --- /dev/null +++ b/generic/shape.c @@ -0,0 +1,599 @@ +/* + * shape.c -- + * + * The Tcl-level interface to non-rectangular windows. + * + * Copyright (c) 1997-2000 by Donal K. Fellows + * + * See "license.txt" for details of the license this file is made + * available under. + * + * $Id$ + */ + +#include "shapeInt.h" + +#ifdef __WIN32__ +#define SUPPORTS_PHOTO_REGION +#else +#if (SHAPE_PHOTO == 1) +#define SUPPORTS_PHOTO_REGION +#endif +#endif + +#ifdef SUPPORTS_PHOTO_REGION +#include +#endif +#include +#include "panic.h" + +#define min(x,y) ((x)<(y)?(x):(y)) +#define max(x,y) ((x)<(y)?(y):(x)) +#define encodeKind(idx,flag) ((idx)|(flag?SHAPE_KIND_TOPLEVEL:0)) + +typedef int (*shapeCommandHandler) + _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int opnum, + int objc, Tcl_Obj *CONST objv[])); +typedef int (*shapeApplicator) + _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int x, int y, int op, + int kind, int objc, Tcl_Obj *CONST objv[])); + +static int +shapeBoundClipOps _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int opnum, + int objc, Tcl_Obj *CONST objv[])); +static int +shapeOffsetOp _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int opnum, + int objc, Tcl_Obj *CONST objv[])); +static int +shapeSetUpdateOps _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int opnum, + int objc, Tcl_Obj *CONST objv[])); +static int +shapeBitmap _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int x, int y, + int op, int kind, int objc, Tcl_Obj *CONST objv[])); +static int +shapeRects _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int x, int y, + int op, int kind, int objc, Tcl_Obj *CONST objv[])); +static int +shapeReset _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int x, int y, + int op, int kind, int objc, Tcl_Obj *CONST objv[])); +static int +shapeText _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int x, int y, + int op, int kind, int objc, Tcl_Obj *CONST objv[])); +static int +shapeWindow _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int x, int y, + int op, int kind, int objc, Tcl_Obj *CONST objv[])); +#ifdef SUPPORTS_PHOTO_REGION +static int +shapePhoto _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, int x, int y, + int op, int kind, int objc, Tcl_Obj *CONST objv[])); +#endif + +static int +shapeCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); + + +enum { + boundsCmd, getCmd, offsetCmd, setCmd, updateCmd, versionCmd +}; +static char *subcommands[] = { + "bounds", "get", "offset", "set", "update", "version", NULL +}; +static shapeCommandHandler shapeCommandHandlers[] = { + shapeBoundClipOps, shapeBoundClipOps, + shapeOffsetOp, shapeSetUpdateOps, shapeSetUpdateOps, + NULL +}; + + +/* + * Minor design note; I use K&R style function definition headers + * despite being very keen on ANSI-C everywhere else. This is because + * it is far easier to write and document function headers in the K&R + * style... + */ + +static Tk_Window +getWindow(apptkwin, interp, pathName, isToplevel) + Tk_Window apptkwin; + Tcl_Interp *interp; + Tcl_Obj *pathName; + int *isToplevel; +{ + char *winName = Tcl_GetStringFromObj(pathName, NULL); + Tk_Window tkwin = Tk_NameToWindow(interp, winName, apptkwin); + + if (!tkwin) { + return NULL; + } + if (Tk_Display(tkwin) != Tk_Display(apptkwin)) { + Tcl_AppendResult(interp, "can only apply shape operations to windows" + " on the same display as the main window of the" + " application", NULL); + return NULL; + } + if (Tk_WindowId(tkwin) == None) { + Tk_MakeWindowExist(tkwin); + if (Tk_WindowId(tkwin) == None) { + Tcl_AppendResult(interp, "failed to create window ", + Tk_PathName(tkwin), NULL); + return NULL; + } + } + *isToplevel = Tk_IsTopLevel(tkwin); + return tkwin; +} + + + +static int +shapeBoundClipOps(tkwin0, interp, opnum, objc, objv) + Tk_Window tkwin0; + Tcl_Interp *interp; + int opnum, objc; + Tcl_Obj *CONST objv[]; +{ + static char *options[] = { + "-bounding", "-clip", NULL + }; + int idx = 0,toplevel; + Tk_Window tkwin; + + if (objc<3||objc>4) { + Tcl_WrongNumArgs(interp, 2, objv, "pathName ?-bounding/-clip?"); + return TCL_ERROR; + } else if (objc==4 && + Tcl_GetIndexFromObj(interp, objv[3], options, "option", 0, + &idx) != TCL_OK) { + return TCL_ERROR; + } + tkwin = getWindow(tkwin0, interp, objv[2], &toplevel); + if (tkwin == NULL) { + return TCL_ERROR; + } + + switch (opnum) { + case boundsCmd: { + int x1, y1, x2, y2, valid; + + if (Shape_GetBbox(interp,tkwin,idx,&valid,&x1,&y1,&x2,&y2) != TCL_OK) { + return TCL_ERROR; + } + if (valid) { + Tcl_Obj *r, *result[4]; + + result[0] = Tcl_NewIntObj(x1); + result[1] = Tcl_NewIntObj(y1); + result[2] = Tcl_NewIntObj(x2); + result[3] = Tcl_NewIntObj(y2); + Tcl_SetObjResult(interp, Tcl_NewListObj(4, result)); + } + return TCL_OK; + } + case getCmd: + /* Would have to hard-code the fact that freeing is done with + * XFree() or something equally grotty in order to not push + * Objs into *this* interface... */ + return Shape_GetShapeRectanglesObj(interp, tkwin, idx); + default: /* should be impossible to get here! */ + panic("unexpected operation number %d", opnum); + } +} + +static int +shapeOffsetOp(tkwin0, interp, opnum, objc, objv) + Tk_Window tkwin0; + Tcl_Interp *interp; + int opnum, objc; + Tcl_Obj *CONST objv[]; +{ + static char *opts[] = { + "-bounding", "-clip", "-both", NULL + }; + int x,y,toplevel, i = SHAPE_KIND_BOTH-1; + Tk_Window tkwin; + + /* Argument parsing */ + switch (objc) { + default: + Tcl_WrongNumArgs(interp, 2, objv, + "pathName ?-bounding/-clip/-both? x y"); + return TCL_ERROR; + case 6: + if (Tcl_GetIndexFromObj(interp, objv[3], opts, "option", 0, + &i) != TCL_OK) { + return TCL_ERROR; + } + case 5: + tkwin = getWindow(tkwin0, interp, objv[2], &toplevel); + if (tkwin == NULL || + Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK || + Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK) { + return TCL_ERROR; + } + return Shape_MoveShape(interp, tkwin, encodeKind(i+1, toplevel), x, y); + } +} + +static int +shapeBitmap(tkwin, interp, x, y, op, kind, objc, objv) + Tk_Window tkwin; + Tcl_Interp *interp; + int x, y, op, kind, objc; + Tcl_Obj *CONST objv[]; +{ + char *bmap_name; + Pixmap bmap; + int result; + + if (objc != 1) { + Tcl_AppendResult(interp, "bitmap requires one argument; a bitmap " + "name", NULL); + return TCL_ERROR; + } + + bmap_name = Tcl_GetStringFromObj(objv[0], NULL); + bmap = Tk_GetBitmap(interp, tkwin, Tk_GetUid(bmap_name)); + + if (bmap == None) { + return TCL_ERROR; + } + + result = Shape_CombineBitmap(interp, tkwin, kind, op, x, y, bmap); + + Tk_FreeBitmap(Tk_Display(tkwin), bmap); + return result; +} + +static int +shapeRects(tkwin, interp, x, y, op, kind, objc, objv) + Tk_Window tkwin; + Tcl_Interp *interp; + int x, y, op, kind, objc; + Tcl_Obj *CONST objv[]; +{ + Tcl_Obj **ovec; + XRectangle *rects; + int count,i,result; + + if (objc != 1) { + Tcl_AppendResult(interp, "rectangles requires one argument; " + "a list of rectangles", NULL); + return TCL_ERROR; + } + + if (Tcl_ListObjGetElements(interp, objv[0], &count, &ovec) != TCL_OK) { + return TCL_ERROR; + } else if (count<1) { + Tcl_AppendResult(interp, "need at least one rectangle", NULL); + return TCL_ERROR; + } + + rects = (XRectangle *)Tcl_Alloc(sizeof(XRectangle)*count); + for (i=0 ; i= objc) { + Tcl_AppendResult(interp, "-offset reqires two args; x and y", + NULL); + return TCL_ERROR; + } else if (Tcl_GetIntFromObj(interp, objv[idx+1], &x) != TCL_OK || + Tcl_GetIntFromObj(interp, objv[idx+2], &y) != TCL_OK) { + return TCL_ERROR; + } + idx += 2; + break; + case sourceargs: { + shapeApplicator app = applicators[opidx]; + if (app != NULL) { + objc -= idx+1; + objv += idx+1; + return app(tkwin, interp, x, y, operation, kind, objc, objv); + } + Tcl_AppendResult(interp, "not supported", NULL); + return TCL_ERROR; + } + } + } + Tcl_AppendResult(interp, "no source to take shape from", NULL); + return TCL_ERROR; +} + +static int +shapeCmd(clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + int subcmdidx; + + if (objc<2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?window arg ...?"); + return TCL_ERROR; + } else if (Tcl_GetIndexFromObj(interp, objv[1], subcommands, "subcommand", + 0, &subcmdidx) != TCL_OK) { + return TCL_ERROR; + } + + if (shapeCommandHandlers[subcmdidx]) { + /* Farm out the more complex operations */ + return shapeCommandHandlers[subcmdidx](clientData, interp, subcmdidx, + objc, objv); + } else switch (subcmdidx) { + case versionCmd: + /* shape version */ + if (objc!=2) { + Tcl_WrongNumArgs(interp, 1, objv, "version"); + return TCL_ERROR; + } else { + int major=-1, minor=-1; + char buffer[64]; + + if (Shape_QueryVersion((Tk_Window)clientData, &major, &minor)) { + sprintf(buffer, "%d.%d", major, minor); + Tcl_AppendResult(interp, buffer, NULL); + } + return TCL_OK; + } + + default: /* should be impossible to get here! */ + panic("switch fallthrough"); + } +} + +int +Shape_Init(interp) + Tcl_Interp *interp; +{ + Tk_Window tkwin = Tk_MainWindow(interp); + + if (Tcl_PkgRequire(interp, "Tk", "8", 0) == NULL) { + return TCL_ERROR; + } + if (!Shape_ExtensionPresent(tkwin)) { + Tcl_AppendResult(interp, "shaped window extension not supported on " + "this X server", NULL); + return TCL_ERROR; + } + + Tcl_CreateObjCommand(interp, "shape", shapeCmd, tkwin, NULL); + /* See the head of the shape.h file for the definitions of these macros */ + Tcl_SetVar(interp, "shape_version", SHAPE_VERSION, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "shape_patchLevel", SHAPE_PATCHLEVEL, TCL_GLOBAL_ONLY); + return Tcl_PkgProvide(interp, "shape", SHAPE_VERSION); +} + +/* + * $Log$ + */ diff --git a/generic/shapeInt.h b/generic/shapeInt.h new file mode 100644 index 0000000..75047ac --- /dev/null +++ b/generic/shapeInt.h @@ -0,0 +1,29 @@ +/* + * shapeInt.h -- + * + * The private C interface between modules of the non-rectangular + * window extension. + * + * Copyright (c) 2000 by Donal K. Fellows + * + * See "license.txt" for details of the license this file is made + * available under. + * + * $Id$ + */ + +#ifndef SHAPE_SHAPEINT_H +#define SHAPE_SHAPEINT_H + +#include + +#define ShapeApplyToBounding(kind) ((kind) & SHAPE_KIND_BOUNDING) +#define ShapeApplyToClip(kind) ((kind) & SHAPE_KIND_CLIP) +#define ShapeApplyToParent(kind) ((kind) & SHAPE_KIND_TOPLEVEL) + +EXTERN XRectangle * +ShapeRenderTextAsRectangles _ANSI_ARGS_((Tk_Window tkwin, Tcl_Interp *interp, + Tcl_Obj *string, Tcl_Obj *font, + int *numRects)); + +#endif diff --git a/generic/tkAppInit.c b/generic/tkAppInit.c new file mode 100644 index 0000000..ba03df0 --- /dev/null +++ b/generic/tkAppInit.c @@ -0,0 +1,124 @@ +/* + * tkAppInit.c -- + * + * Provides a default version of the Tcl_AppInit procedure for + * use in wish and similar Tk-based applications. + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tkAppInit.c 1.22 96/05/29 09:47:08 + */ + +#include "tk.h" + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ + +extern int matherr(); +int *tclDummyMathPtr = (int *) matherr; + +#ifdef TK_TEST +EXTERN int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +#endif /* TK_TEST */ + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tk_Main never returns here, so this procedure never + * returns either. + * + * Side effects: + * Whatever the application does. + * + *---------------------------------------------------------------------- + */ + +int +main(argc, argv) + int argc; /* Number of command-line arguments. */ + char **argv; /* Values of command-line arguments. */ +{ + Tk_Main(argc, argv, Tcl_AppInit); + return 0; /* Needed only to prevent compiler warning. */ +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ +EXTERN int Shape_Init _ANSI_ARGS_((Tcl_Interp *interp)); + +int +Tcl_AppInit(interp) + Tcl_Interp *interp; /* Interpreter for application. */ +{ + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (Tk_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit); +#ifdef TK_TEST + if (Tktest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "Tktest", Tktest_Init, + (Tcl_PackageInitProc *) NULL); +#endif /* TK_TEST */ + if (Shape_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + + Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY); + return TCL_OK; +} diff --git a/include/panic.h b/include/panic.h new file mode 100644 index 0000000..e172907 --- /dev/null +++ b/include/panic.h @@ -0,0 +1,13 @@ +#ifndef PANIC_H +#define PANIC_H + +#ifdef __GNUC__ +EXTERN void +panic _ANSI_ARGS_((char *message, ...) + __attribute__ ((__noreturn__ , + __format__(printf,1,2) )) ); +#else +EXTERN void panic _ANSI_ARGS_((char *message, ...)); +#endif + +#endif diff --git a/include/shape.h b/include/shape.h new file mode 100644 index 0000000..0dbdd05 --- /dev/null +++ b/include/shape.h @@ -0,0 +1,88 @@ +/* + * shape.h -- + * + * The public platform-independent C interface to the + * non-rectangular window extension. + * + * Copyright (c) 1997-2000 by Donal K. Fellows + * + * See "license.txt" for details of the license this file is made + * available under. + * + * $Id$ + */ + +#ifndef SHAPE_SHAPE_H +#define SHAPE_SHAPE_H + +#include +#include +#include /* For Region declaration. */ + +#define SHAPE_VERSION_MAJOR 0 +#define SHAPE_VERSION_MINOR 4 +#define SHAPE_VERSION_PATCH 4 +#define SHAPE_VERSION STRINGIFY(SHAPE_VERSION_MAJOR) "." STRINGIFY(SHAPE_VERSION_MINOR) +#define SHAPE_PATCHLEVEL SHAPE_VERSION "." STRINGIFY(SHAPE_VERSION_PATCH) + +#define SHAPE_KIND_BOUNDING (1<<0) +#define SHAPE_KIND_CLIP (1<<1) +#define SHAPE_KIND_BOTH (SHAPE_KIND_BOUNDING | SHAPE_KIND_CLIP) +#define SHAPE_KIND_TOPLEVEL (1<<8) +#define SHAPE_KIND_ALL (SHAPE_KIND_BOTH | SHAPE_KIND_TOPLEVEL) +#define SHAPE_BOUND_MASK (SHAPE_KIND_BOUNDING | SHAPE_KIND_TOPLEVEL) +#define SHAPE_CLIP_MASK (SHAPE_KIND_CLIP | SHAPE_KIND_TOPLEVEL) + +#ifndef ShapeSet +/* Taken from /usr/include/X11/extensions/shape.h */ +#define ShapeSet 0 +#define ShapeUnion 1 +#define ShapeIntersect 2 +#define ShapeSubtract 3 +#define ShapeInvert 4 +#endif /* ShapeSet */ + +#define SHAPE_OP_SET ShapeSet +#define SHAPE_OP_UNION ShapeUnion +#define SHAPE_OP_INTERSECT ShapeIntersect +#define SHAPE_OP_SUBTRACT ShapeSubtract +#define SHAPE_OP_INVERT ShapeInvert + +EXTERN int +Shape_GetBbox _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, int getClip, + int *valid, int *x1, int *y1, int *x2, int *y2)); +EXTERN int +Shape_GetShapeRectanglesObj _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, + int getClip)); +EXTERN int +Shape_MoveShape _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, + int kind, int x, int y)); +EXTERN int +Shape_CombineBitmap _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, + int kind, int op, int x, int y, + Pixmap bitmap)); +EXTERN int +Shape_CombineRectangles _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, + int kind, int op, + int rectc, XRectangle *rectv)); +EXTERN int +Shape_CombineRectanglesOrdered _ANSI_ARGS_((Tcl_Interp *interp,Tk_Window tkwin, + int kind, int op, + int rectc, XRectangle *rectv)); +EXTERN int +Shape_CombineWindow _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, + int kind, int op, int x, int y, + Tk_Window srcwin)); +EXTERN int +Shape_CombineRegion _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, + int kind, int op, int x, int y, + Region region)); +EXTERN int +Shape_Reset _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, int kind)); +EXTERN int +Shape_QueryVersion _ANSI_ARGS_((Tk_Window tkwin, + int *majorPtr, int *minorPtr)); +EXTERN int +Shape_ExtensionPresent _ANSI_ARGS_((Tk_Window tkwin)); + +#endif /* SHAPE_SHAPE_H */ diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..f176326 --- /dev/null +++ b/license.txt @@ -0,0 +1,38 @@ +This software is copyrighted by Donal K. Fellows, and other parties. +The following terms apply to all files associated with the software +unless explicitly disclaimed in individual files. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, +provided that existing copyright notices are retained in all copies +and that this notice is included verbatim in any distributions. No +written agreement, license, or royalty fee is required for any of the +authorized uses. Modifications to this software may be copyrighted by +their authors and need not follow the licensing terms described here, +provided that the new terms are clearly indicated on the first page of +each file where they apply. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND +THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE +MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" in +the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. diff --git a/tests/README b/tests/README new file mode 100644 index 0000000..982e6a3 --- /dev/null +++ b/tests/README @@ -0,0 +1 @@ +This stuff is under development, and needs far more work... diff --git a/tests/all.tcl b/tests/all.tcl new file mode 100644 index 0000000..6c6ec8e --- /dev/null +++ b/tests/all.tcl @@ -0,0 +1,57 @@ +# all.tcl -- +# +# This file contains a top-level script to run all of the Tcl +# tests. Execute it by invoking "source all.test" when running tcltest +# in this directory. +# +# Copyright (c) 1998-2000 by Scriptics Corporation. +# All rights reserved. +# +# RCS: @(#) $Id: all.tcl,v 1.1 2000/02/03 21:20:51 wart Exp $ + +# DKF - copied from "sampleextension/tests/all.tcl" + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest + namespace import ::tcltest::* +} + +set ::tcltest::testSingleFile false +set ::tcltest::testsDirectory [file dir [info script]] + +# We need to ensure that the testsDirectory is absolute +::tcltest::normalizePath ::tcltest::testsDirectory + +puts stdout "Tests running in interp: [info nameofexecutable]" +puts stdout "Tests running in working dir: $::tcltest::testsDirectory" +if {[llength $::tcltest::skip] > 0} { + puts stdout "Skipping tests that match: $::tcltest::skip" +} +if {[llength $::tcltest::match] > 0} { + puts stdout "Only running tests that match: $::tcltest::match" +} + +if {[llength $::tcltest::skipFiles] > 0} { + puts stdout "Skipping test files that match: $::tcltest::skipFiles" +} +if {[llength $::tcltest::matchFiles] > 0} { + puts stdout "Only sourcing test files that match: $::tcltest::matchFiles" +} + +set timeCmd {clock format [clock seconds]} +puts stdout "Tests began at [eval $timeCmd]" + +# source each of the specified tests +foreach file [lsort [::tcltest::getMatchingFiles]] { + set tail [file tail $file] + puts stdout $tail + if {[catch {source $file} msg]} { + puts stdout $msg + } +} + +# cleanup +puts stdout "\nTests ended at [eval $timeCmd]" +::tcltest::cleanupTests 1 +return + diff --git a/tests/semantics.test b/tests/semantics.test new file mode 100644 index 0000000..3ef10e4 --- /dev/null +++ b/tests/semantics.test @@ -0,0 +1,28 @@ +# Commands covered: shape +# +# This file contains a collection of tests for one or more of the +# Shape extension's command(s) semantics. Sourcing this file into Tcl +# runs the tests and generates output for errors. No output means no +# errors were found. +# +# Copyright (c) 2000 by Donal K. Fellows +# +# See the file "license.terms" for information on usage and +# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest + namespace import ::tcltest::* +} + +package require shape + +### WRITE THE TESTS HERE ### + +# cleanup +::tcltest::cleanupTests +return + +# Local Variables: +# mode: tcl +# End: diff --git a/tests/shape.test b/tests/shape.test new file mode 100644 index 0000000..8421d92 --- /dev/null +++ b/tests/shape.test @@ -0,0 +1,89 @@ +## -*- tcl -*- + +# top-level error messages +test shape-1.1 {Shape needs subcommand} { + list [catch { + shape + } msg] $msg +} {1 "wrong # args: should be \"shape subcommand ?window arg ...?\""} +test shape-1.2 {Shape subcommand list} { + list [catch { + shape Dummy + } msg] $msg +} {1 "bad subcommand \"Dummy\": must be\ + bounds, get, offset, set, update, or version"} + +# version subcommand +test shape-2.1 {Shape version: command format} { + list [catch { + shape version Dummy + } msg] $msg +} {1 " wrong # args: should be \"shape version\""} +test shape-2.2 {Shape version: result format} { + string is double -strict [shape version] +} {1} + +# set subcommand +test shape-3.1 {Shape set: command format} { + list [catch { + shape set + } msg] $msg +} {1 "wrong # args: should be \"shape set pathName ?options?\""} + +# get subcommand +test shape-4.1 {Shape get: command format} { + list [catch { + shape get + } msg] $msg +} {1 "wrong # args: should be \"shape get pathName ?-bounding/-clip?\""} +test shape-4.2 {Shape get: command format} { + list [catch { + shape get ? ? ? + } msg] $msg +} {1 "wrong # args: should be \"shape get pathName ?-bounding/-clip?\""} + +# update subcommand +test shape-5.1 {Shape update: command format} { + list [catch { + shape update + } msg] $msg +} {1 "wrong # args: should be \"shape update pathName operation ?options?\""} + +# offset subcommand +test shape-6.1 {Shape offset: command format} { + list [catch { + shape offset + } msg] $msg +} {1 "wrong # args: should be\ + \"shape offset pathName ?-bounding/-clip/-both? x y\""} +test shape-6.2 {Shape offset: command format} { + list [catch { + shape offset ? + } msg] $msg +} {1 "wrong # args: should be\ + \"shape offset pathName ?-bounding/-clip/-both? x y\""} +test shape-6.3 {Shape offset: command format} { + list [catch { + shape offset ? ? + } msg] $msg +} {1 "wrong # args: should be\ + \"shape offset pathName ?-bounding/-clip/-both? x y\""} +test shape-6.4 {Shape offset: command format} { + list [catch { + shape offset ? ? ? ? ? + } msg] $msg +} {1 "wrong # args: should be\ + \"shape offset pathName ?-bounding/-clip/-both? x y\""} + +# bounds subcommand +test shape-7.1 {Shape bounds: command format} { + list [catch { + shape bounds + } msg] $msg +} {1 "wrong # args: should be \"shape bounds pathName ?-bounding/-clip?\""} +test shape-7.2 {Shape bounds: command format} { + list [catch { + shape bounds ? ? ? + } msg] $msg +} {1 "wrong # args: should be \"shape bounds pathName ?-bounding/-clip?\""} + diff --git a/tests/syntax.test b/tests/syntax.test new file mode 100644 index 0000000..4960446 --- /dev/null +++ b/tests/syntax.test @@ -0,0 +1,136 @@ +# Commands covered: shape +# +# This file contains a collection of tests for one or more of the +# Shape extension's command(s) syntax. Sourcing this file into Tcl +# runs the tests and generates output for errors. No output means no +# errors were found. +# +# Copyright (c) 2000 by Donal K. Fellows +# +# See the file "license.terms" for information on usage and +# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest + namespace import ::tcltest::* +} + +package require shape + +# top-level error messages +test syntax-1.1 {Shape needs subcommand} { + list [catch { + shape + } msg] $msg +} {1 "wrong # args: should be \"shape subcommand ?window arg ...?\""} +test syntax-1.2 {Shape subcommand list} { + list [catch { + shape Dummy + } msg] $msg +} {1 "bad subcommand \"Dummy\": must be\ + bounds, get, offset, set, update, or version"} +test syntax-1.3 {Variables were created} { + list [info exist shape_version] [info exist shape_patchLevel] +} {1 1} + +# version subcommand +test syntax-2.1 {Shape version: command format} { + list [catch { + shape version Dummy + } msg] $msg +} {1 " wrong # args: should be \"shape version\""} +test syntax-2.2 {Shape version: result format} { + string is double -strict [shape version] +} {1} + +# set subcommand +test syntax-3.1 {Shape set: command format} { + list [catch { + shape set + } msg] $msg +} {1 "wrong # args: should be \"shape set pathName ?options?\""} +test syntax-3.2 {Shape set: needs window pathname} { + list [catch { + shape set not-a-window + } msg] $msg +} {1 "bad window path name \"not-a-window\""} + +# get subcommand +test syntax-4.1 {Shape get: command format} { + list [catch { + shape get + } msg] $msg +} {1 "wrong # args: should be \"shape get pathName ?-bounding/-clip?\""} +test syntax-4.2 {Shape get: command format} { + list [catch { + shape get ? ? ? + } msg] $msg +} {1 "wrong # args: should be \"shape get pathName ?-bounding/-clip?\""} +test syntax-4.3 {Shape get: needs window pathname} { + list [catch { + shape get not-a-window + } msg] $msg +} {1 "bad window path name \"not-a-window\""} + +# update subcommand +test syntax-5.1 {Shape update: command format} { + list [catch { + shape update + } msg] $msg +} {1 "wrong # args: should be \"shape update pathName operation ?options?\""} + +# offset subcommand +test syntax-6.1 {Shape offset: command format} { + list [catch { + shape offset + } msg] $msg +} {1 "wrong # args: should be\ + \"shape offset pathName ?-bounding/-clip/-both? x y\""} +test syntax-6.2 {Shape offset: command format} { + list [catch { + shape offset ? + } msg] $msg +} {1 "wrong # args: should be\ + \"shape offset pathName ?-bounding/-clip/-both? x y\""} +test syntax-6.3 {Shape offset: command format} { + list [catch { + shape offset ? ? + } msg] $msg +} {1 "wrong # args: should be\ + \"shape offset pathName ?-bounding/-clip/-both? x y\""} +test syntax-6.4 {Shape offset: command format} { + list [catch { + shape offset ? ? ? ? ? + } msg] $msg +} {1 "wrong # args: should be\ + \"shape offset pathName ?-bounding/-clip/-both? x y\""} +test syntax-6.5 {Shape offset: needs window pathname} { + list [catch { + shape offset not-a-window 0 0 + } msg] $msg +} {1 "bad window path name \"not-a-window\""} + +# bounds subcommand +test syntax-7.1 {Shape bounds: command format} { + list [catch { + shape bounds + } msg] $msg +} {1 "wrong # args: should be \"shape bounds pathName ?-bounding/-clip?\""} +test syntax-7.2 {Shape bounds: command format} { + list [catch { + shape bounds ? ? ? + } msg] $msg +} {1 "wrong # args: should be \"shape bounds pathName ?-bounding/-clip?\""} +test syntax-7.3 {Shape bounds: needs window pathname} { + list [catch { + shape bounds not-a-window + } msg] $msg +} {1 "bad window path name \"not-a-window\""} + +# cleanup +::tcltest::cleanupTests +return + +# Local Variables: +# mode: tcl +# End: diff --git a/unix/Makefile.in b/unix/Makefile.in new file mode 100644 index 0000000..4b4e278 --- /dev/null +++ b/unix/Makefile.in @@ -0,0 +1,86 @@ +# This Makefile is used to create the example loadable module. +# It also illustrates how to take advantage of configuration +# exported by Tcl to set up Makefiles for shared libraries. +# +# SCCS: @(#) Makefile.in 1.5 97/08/14 19:01:21 + +SOFILE = libshape04.so.1.0 +EXEFILE = shapewish +UNIX_OBJS = shapeUnixImpl.o shapeUnixText.o +GENERIC_OBJS = shape.o + +GENERIC_SRCS = $(GENERIC_DIR)/shape.c +UNIX_SRCS = \ + $(UNIX_DIR)/shapeUnixImpl.c \ + $(UNIX_DIR)/shapeUnixText.c + +OBJS = $(GENERIC_OBJS) $(UNIX_OBJS) +SRCS = $(GENERIC_SRCS) $(UNIX_SRCS) + +# The directory containing the Tcl library archive file appropriate +# for this version of Tk: +TCL_BIN_DIR = @TCL_BIN_DIR@ + +# Libraries to use when linking: +LIBS = @TCL_LIB_SPEC@ @TCL_LIBS@ -lc + +#---------------------------------------------------------------- +# The information below is modified by the configure script when +# Makefile is generated from Makefile.in. You shouldn't normally +# modify any of this stuff by hand. +#---------------------------------------------------------------- + +CC = @CC@ +SHLIB_CFLAGS = @SHLIB_CFLAGS@ +SHLIB_LD = @SHLIB_LD@ +SHLIB_SUFFIX = @SHLIB_SUFFIX@ +TCL_INCLUDE_DIR = @TCL_INCLUDE@ +TK_INCLUDE_DIR = @TK_INCLUDE@ +TK_XINCLUDES = @TK_XINCLUDES@ +VPATH = @srcdir@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TK_LIBS = @TK_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TK_SRC_DIR = @TK_SRC_DIR@ + +SRC_DIR = @srcdir@ +TOP_DIR = @srcdir@/.. +GENERIC_DIR = $(TOP_DIR)/generic +UNIX_DIR = $(TOP_DIR)/unix +INCLUDE_DIR = $(TOP_DIR)/include +# ---------------------------------------------------------------------- +CFLAGS = -g -DSHAPE_PHOTO=@SHAPE_PHOTO@ +CC_SWITCHES = $(CFLAGS) ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \ + -I${INCLUDE_DIR} -I${GENERIC_DIR} -I${UNIX_DIR} \ + -I${TK_INCLUDE_DIR} ${TK_XINCLUDES} -I${TCL_INCLUDE_DIR} \ + -I${TCL_SRC_DIR}/generic -I${TCL_SRC_DIR}/unix \ + -I${TK_SRC_DIR}/generic -I${TK_SRC_DIR}/unix +# ---------------------------------------------------------------------- +all: @PRIMARY_TARGET@ + +$(OBJS): $(INCLUDE_DIR)/shape.h $(INCLUDE_DIR)/panic.h $(GENERIC_DIR)/shapeInt.h + +shape.o: $(GENERIC_DIR)/shape.c + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/shape.c +tkAppInit.o: $(GENERIC_DIR)/tkAppInit.c + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkAppInit.c +shapeUnixImpl.o: $(UNIX_DIR)/shapeUnixImpl.c + $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/shapeUnixImpl.c +shapeUnixText.o: $(UNIX_DIR)/shapeUnixText.c + $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/shapeUnixText.c +# ---------------------------------------------------------------------- +$(SOFILE): $(OBJS) + ${SHLIB_LD} -o $@ $^ @SHLIB_LD_LIBS@ +$(EXEFILE): $(OBJS) tkAppInit.o + $(CC) -o $@ $^ @SHLIB_LD_LIBS@ ${TK_LIB_SPEC} ${TCL_LIB_SPEC} ${TK_LIBS} +# ---------------------------------------------------------------------- +clean: + rm -f *.o *.a $(SOFILE) $(EXEFILE) core +distclean: clean + rm -f Makefile config.cache config.log config.status +# ---------------------------------------------------------------------- +Makefile: Makefile.in config.status + ./config.status +depend: + makedepend -- $(DEPEND_SWITCHES) -- $(SRCS) diff --git a/unix/configure b/unix/configure new file mode 100755 index 0000000..d21154f --- /dev/null +++ b/unix/configure @@ -0,0 +1,764 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.3 +# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-tclconf=DIR use Tcl 8.0 configuration file from DIR" +ac_help="$ac_help + --with-tkconf=DIR use Tk 8.0 configuration file from DIR" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE + +# Initialize some other variables. +subdirs= + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -build | --build | --buil | --bui | --bu | --b) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=PREFIX install architecture-dependent files in PREFIX + [same as prefix] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +--enable and --with options recognized:$ac_help +EOF + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.3" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=shapeUnixImpl.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5' + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + +# SCCS: @(#) configure.in 1.9 96/04/15 09:50:20 + +VERSION=0.4 + +#-------------------------------------------------------------------- +# See if there was a command-line option for where Tcl is; if +# not, assume that its top-level directory is a sibling of ours. +#-------------------------------------------------------------------- + +# Check whether --with-tclconf or --without-tclconf was given. +withval="$with_tclconf" +if test -n "$withval"; then + TCL_CONF_DIR=$withval +else + TCL_CONF_DIR=/usr/local/lib +fi + +if test ! -r $TCL_CONF_DIR/tclConfig.sh; then + { echo "configure: error: Tcl configuration file $TCL_CONF_DIR/tclConfig.sh does not exist" 1>&2; exit 1; } +fi +# Check whether --with-tkconf or --without-tkconf was given. +withval="$with_tkconf" +if test -n "$withval"; then + TK_CONF_DIR=$withval +else + TK_CONF_DIR=$TCL_CONF_DIR +fi + +if test ! -r $TK_CONF_DIR/tkConfig.sh; then + { echo "configure: error: Tcl configuration file $TK_CONF_DIR/tkConfig.sh does not exist" 1>&2; exit 1; } +fi + +#-------------------------------------------------------------------- +# Read in configuration information generated by Tcl for shared +# libraries, and arrange for it to be substituted into our +# Makefile. +#-------------------------------------------------------------------- + +file=$TCL_CONF_DIR/tclConfig.sh +. $file +file=$TK_CONF_DIR/tkConfig.sh +. $file + +CC=$TCL_CC +SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS +SHLIB_LD=$TCL_SHLIB_LD +SHLIB_LD_LIBS="-lXext $TCL_SHLIB_LD_LIBS" +SHLIB_SUFFIX=$TCL_SHLIB_SUFFIX +SHLIB_VERSION=$TCL_SHLIB_VERSION +TCL_LIBS=$TCL_LIBS +TCL_VERSION=$TCL_VERSION +TCL_INCLUDE=$TCL_PREFIX/include +TK_INCLUDE=$TK_PREFIX/include +TCL_BIN_DIR=$TK_EXEC_PREFIX/bin + +echo $ac_n "checking for -lXext""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_lib_Xext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXext $TK_XLIBSW $LIBS" +cat > conftest.$ac_ext <&6 + : +else + echo "$ac_t""no" 1>&6 +{ echo "configure: error: X extension library not available" 1>&2; exit 1; } +fi + + +echo $ac_n "checking for TkPhotoGetValidRegion""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_func_TkPhotoGetValidRegion'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +char TkPhotoGetValidRegion(); + +int main() { return 0; } +int t() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_TkPhotoGetValidRegion) || defined (__stub___TkPhotoGetValidRegion) +choke me +#else +TkPhotoGetValidRegion(); +#endif + +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_func_TkPhotoGetValidRegion=yes" +else + rm -rf conftest* + eval "ac_cv_func_TkPhotoGetValidRegion=no" +fi +rm -f conftest* + +fi +if eval "test \"`echo '$ac_cv_func_'TkPhotoGetValidRegion`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SHAPE_PHOTO=1 +else + echo "$ac_t""no" 1>&6 +SHAPE_PHOTO=0 +fi + + + +if test $TCL_SHARED_BUILD -eq 1; then + PRIMARY_TARGET='$(SOFILE)' +else + PRIMARY_TARGET='$(EXEFILE)' +fi + + + + + + + + + + + + + + + + + + + + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ + >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.3" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF +$ac_vpsub +$extrasub +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@SHAPE_PHOTO@%$SHAPE_PHOTO%g +s%@CC@%$CC%g +s%@PRIMARY_TARGET@%$PRIMARY_TARGET%g +s%@SHLIB_CFLAGS@%$SHLIB_CFLAGS%g +s%@SHLIB_LD@%$SHLIB_LD%g +s%@SHLIB_LD_LIBS@%$SHLIB_LD_LIBS%g +s%@SHLIB_SUFFIX@%$SHLIB_SUFFIX%g +s%@SHLIB_VERSION@%$SHLIB_VERSION%g +s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g +s%@TCL_LIBS@%$TCL_LIBS%g +s%@TCL_VERSION@%$TCL_VERSION%g +s%@TCL_BIN_DIR@%$TCL_BIN_DIR%g +s%@TCL_INCLUDE@%$TCL_INCLUDE%g +s%@TCL_SRC_DIR@%$TCL_SRC_DIR%g +s%@TK_INCLUDE@%$TK_INCLUDE%g +s%@TK_XINCLUDES@%$TK_XINCLUDES%g +s%@TK_LIB_SPEC@%$TK_LIB_SPEC%g +s%@TK_LIBS@%$TK_LIBS%g +s%@TK_SRC_DIR@%$TK_SRC_DIR%g + +CEOF +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust relative srcdir, etc. for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file +fi; done +rm -f conftest.subs + + + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/unix/configure.in b/unix/configure.in new file mode 100644 index 0000000..5d39794 --- /dev/null +++ b/unix/configure.in @@ -0,0 +1,97 @@ +dnl This is really a -*- shell-script -*- with bells on. +dnl ------------------------------------------------------------ +dnl +dnl configure.in -- +dnl +dnl Autoconf input script for producing the configure script +dnl to build the non-rectangular window extension on Unix. +dnl +dnl Copyright (c) 1997-2000 by Donal K. Fellows +dnl +dnl See "license.txt" for details of the license this file is made +dnl available under. +dnl +dnl $Id$ +dnl +dnl ------------------------------------------------------------ +dnl This file is an input file used by the GNU "autoconf" program to +dnl generate the file "configure", which is run to configure the +dnl Makefile in this directory. +AC_INIT(shapeUnixImpl.c) +# SCCS: @(#) configure.in 1.9 96/04/15 09:50:20 + +VERSION=0.4 + +#-------------------------------------------------------------------- +# See if there was a command-line option for where Tcl is; if +# not, assume that its top-level directory is a sibling of ours. +#-------------------------------------------------------------------- + +AC_ARG_WITH(tclconf, + [ --with-tclconf=DIR use Tcl 8.0 configuration file from DIR], + TCL_CONF_DIR=$withval, TCL_CONF_DIR=/usr/local/lib) +if test ! -r $TCL_CONF_DIR/tclConfig.sh; then + AC_MSG_ERROR(Tcl configuration file $TCL_CONF_DIR/tclConfig.sh does not exist) +fi +AC_ARG_WITH(tkconf, + [ --with-tkconf=DIR use Tk 8.0 configuration file from DIR], + TK_CONF_DIR=$withval, TK_CONF_DIR=$TCL_CONF_DIR) +if test ! -r $TK_CONF_DIR/tkConfig.sh; then + AC_MSG_ERROR(Tcl configuration file $TK_CONF_DIR/tkConfig.sh does not exist) +fi + +#-------------------------------------------------------------------- +# Read in configuration information generated by Tcl for shared +# libraries, and arrange for it to be substituted into our +# Makefile. +#-------------------------------------------------------------------- + +file=$TCL_CONF_DIR/tclConfig.sh +. $file +file=$TK_CONF_DIR/tkConfig.sh +. $file + +CC=$TCL_CC +SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS +SHLIB_LD=$TCL_SHLIB_LD +SHLIB_LD_LIBS="-lXext $TCL_SHLIB_LD_LIBS" +SHLIB_SUFFIX=$TCL_SHLIB_SUFFIX +SHLIB_VERSION=$TCL_SHLIB_VERSION +TCL_LIBS=$TCL_LIBS +TCL_VERSION=$TCL_VERSION +TCL_INCLUDE=$TCL_PREFIX/include +TK_INCLUDE=$TK_PREFIX/include +TCL_BIN_DIR=$TK_EXEC_PREFIX/bin + +AC_CHECK_LIB(Xext, XShapeQueryVersion, :, AC_MSG_ERROR(X extension library not available), $TK_XLIBSW) + +AC_CHECK_FUNC(TkPhotoGetValidRegion, SHAPE_PHOTO=1, SHAPE_PHOTO=0) +AC_SUBST(SHAPE_PHOTO) + +if test $TCL_SHARED_BUILD -eq 1; then + PRIMARY_TARGET='$(SOFILE)' +else + PRIMARY_TARGET='$(EXEFILE)' +fi + +AC_SUBST(CC) +AC_SUBST(PRIMARY_TARGET) +AC_SUBST(SHLIB_CFLAGS) +AC_SUBST(SHLIB_LD) +AC_SUBST(SHLIB_LD_LIBS) +AC_SUBST(SHLIB_SUFFIX) +AC_SUBST(SHLIB_VERSION) +AC_SUBST(TCL_LIB_SPEC) +AC_SUBST(TCL_LIBS) +AC_SUBST(TCL_VERSION) +AC_SUBST(TCL_BIN_DIR) +AC_SUBST(TCL_INCLUDE) +AC_SUBST(TCL_SRC_DIR) +AC_SUBST(TK_INCLUDE) +AC_SUBST(TK_XINCLUDES) +AC_SUBST(TK_LIB_SPEC) +AC_SUBST(TK_LIBS) +AC_SUBST(TK_SRC_DIR) +AC_SUBST(TCL_LIB_SPEC) + +AC_OUTPUT(Makefile) diff --git a/unix/pkgIndex.tcl b/unix/pkgIndex.tcl new file mode 100644 index 0000000..94e274a --- /dev/null +++ b/unix/pkgIndex.tcl @@ -0,0 +1,8 @@ +# Tcl package index file, version 1.0 + +# This is hand-rolled code. The name of the shared library is odd, but +# it needs to be mangled like this to get the names working happily on +# broken OSes like SunOS4. If you have a problem with this, tough! + +package ifneeded Shape 0.4 "package require Tk 8\n\ + [list tclPkgSetup $dir Shape 0.4 {{libshape04.so.1.0 load shape}}]" diff --git a/unix/shapeUnixImpl.c b/unix/shapeUnixImpl.c new file mode 100644 index 0000000..1ff3cfc --- /dev/null +++ b/unix/shapeUnixImpl.c @@ -0,0 +1,510 @@ +/* + * shapeUnixImpl.c -- + * + * This module implements raw access to the X Shaped-Window extension. + * + * Copyright (c) 2000 by Donal K. Fellows + * + * See "license.txt" for details of the license this file is made + * available under. + * + * $Id$ + */ + +#include +#include /* Includes conventional X stuff. */ +#include /* For Region declaration. */ +#include +#include "shape.h" + +#ifdef DKF_SHAPE_DEBUGGING +static int +applyOperationToToplevelParent = 1; +#else +#define applyOperationToToplevelParent 1 +#endif + +/* + * ---------------------------------------------------------------------- + * + * getXParent - + * Return the X window token for the given window on the given + * display. + * + * Returns: + * A window token, or None if an error occurred or the parent + * is the root window of the display. + * + * Side effects: + * None + * + * ---------------------------------------------------------------------- + */ + +static Window +getXParent(dpy, win) + Display *dpy; + Window win; +{ + Window root, parent, *kids; + unsigned int nkids; + + kids = (Window *)NULL; + if (XQueryTree(dpy, win, &root, &parent, &kids, &nkids) != False) { + if (kids != NULL) { + XFree(kids); + } + if (parent != root) { + return parent; + } + } + return None; +} + +/* + * ---------------------------------------------------------------------- + * + * Shape_GetBbox - + * Get the bounding box of the window shape. The getClip parameter + * specifies whether to get the clip region of the window, otherwise + * the bounding region of the window is got. + * + * Result: + * A standard Tcl result value. The variable pointed to by valid + * indicates whether the variables pointed to by x1...y2 + * represent a valid bounding box, or whether none has been + * designated for the window. + * + * Side effects: + * None other than as described above. + * + * ---------------------------------------------------------------------- + */ + +int +Shape_GetBbox(interp, tkwin, getClip, valid, x1, y1, x2, y2) + Tcl_Interp *interp; + Tk_Window tkwin; + int getClip, *valid, *x1, *y1, *x2, *y2; +{ + Display *dpy = Tk_Display(tkwin); + Window win = Tk_WindowId(tkwin); + Tcl_Obj *result[4]; + Status s; + int bShaped, xbs, ybs, cShaped, xcs, ycs; + unsigned int wbs, hbs, wcs, hcs; + + if (win == None) { + Tcl_AppendResult(interp, "window ", Tk_PathName(tkwin), + " doesn't fully exist", NULL); + return TCL_ERROR; + } + + s = XShapeQueryExtents(dpy, win, + &bShaped, &xbs, &ybs, &wbs, &hbs, + &cShaped, &xcs, &ycs, &wcs, &hcs); + + if (!s) { + Tcl_AppendResult(interp, "extents query failed", NULL); + return TCL_ERROR; + } else if (bShaped && !getClip) { + /* Bounding box of window. */ + *valid = 1; + *x1 = xbs; + *y1 = ybs; + *x2 = xbs+wbs-1; + *y2 = ybs+hbs-1; + } else if (cShaped && getClip) { + /* Bounding box of drawable area. */ + *valid = 1; + *x1 = xcs; + *y1 = ycs; + *x2 = xcs+wcs-1; + *y2 = ycs+hcs-1; + } else { + *valid = 0; + } + return TCL_OK; +} + +/* + * ---------------------------------------------------------------------- + * + * Shape_GetShapeRectanglesObj - + * Get a list of rectangles that describe the window shape. The + * getClip parameter specifies whether to get the clip region of the + * window, otherwise the bounding region of the window is got. + * + * Result: + * A standard Tcl result value. The actual result value or an + * error message is left in the interpreter's result. + * + * Side effects: + * None other than as described above. + * + * ---------------------------------------------------------------------- + */ + +int +Shape_GetShapeRectanglesObj(interp, tkwin, getClip) + Tcl_Interp *interp; + Tk_Window tkwin; + int getClip; +{ + Display *dpy = Tk_Display(tkwin); + Window win = Tk_WindowId(tkwin); + XRectangle *rects = NULL; + int count = 0; + int order,i; + Tcl_Obj *rect[4], **retvals; + + if (win == None) { + Tcl_AppendResult(interp, "window ", Tk_PathName(tkwin), + " doesn't fully exist", NULL); + return TCL_ERROR; + } + + rects = XShapeGetRectangles(dpy, win, (getClip?ShapeClip:ShapeBounding), + &count, &order); + + if (count) { + /* alloca() would be more efficient */ + retvals = (Tcl_Obj **)Tcl_Alloc(sizeof(Tcl_Obj *)*count); + for (i=0 ; i +#include /* Includes conventional X stuff. */ +#include "shapeInt.h" + +/* + * ---------------------------------------------------------------------- + * + * ShapeRenderTextAsRectangles -- + * + * Convert a string and font into an array of rectangles that + * describe the shape of the rendered string. + * + * Returns: + * An array of XRectangles (allocated with Tcl_Alloc()) or NULL if + * an error occurred (when an error message will be left in the + * interpreter.) + * + * Notes: + * You are warned that the operation of this code is _highly_ + * arcane, requiring the drawing of the text first on a pixmap, + * then the conversion of that pixmap to an image, and then that + * image to a (sorted) rectangle list which can then be combined + * with the shape region. AAARGH! + * + * In other words, this code is awful and slow, but it works. + * Modify at your own risk... + * + * (Of course, if you can make it go faster, please be my guest!) + * + * ---------------------------------------------------------------------- + */ + +XRectangle * +ShapeRenderTextAsRectangles(tkwin, interp, stringObj, font, numRects) + Tk_Window tkwin; /*in*/ + Tcl_Interp *interp; /*in*/ + Tcl_Obj *stringObj; /*in*/ + Tcl_Obj *font; /*in*/ + int *numRects; /*out*/ +{ + Tk_FontMetrics metrics; + Pixmap pixmap; + int width,length,i,j,k; + XGCValues gcValues; + GC gc; + XImage *xi; + XRectangle *rects; + + Display *dpy = Tk_Display(tkwin); + Window win = Tk_WindowId(tkwin); + char *string = Tcl_GetStringFromObj(stringObj, &length); + char *fontname = Tcl_GetStringFromObj(font, NULL); + unsigned long black = BlackPixel(dpy, Tk_ScreenNumber(tkwin)); + unsigned long white = WhitePixel(dpy, Tk_ScreenNumber(tkwin)); + Tk_Font tkfont = Tk_GetFont(interp, tkwin, fontname); + + if (!tkfont) { + return NULL; + } + Tk_GetFontMetrics(tkfont, &metrics); + width = Tk_TextWidth(tkfont, string, length); + + /* Draw the text */ + pixmap = Tk_GetPixmap(dpy,win, width, metrics.linespace, Tk_Depth(tkwin)); + + /* Start by clearing the background; life is amusing if you don't! */ + gcValues.foreground = white; + gcValues.graphics_exposures = False; + gc = Tk_GetGC(tkwin, GCForeground | GCGraphicsExposures, &gcValues); + XFillRectangle(dpy, pixmap, gc, 0,0, width, metrics.linespace); + Tk_FreeGC(dpy, gc); + + /* Now paint the string in the given font. */ + gcValues.font = Tk_FontId(tkfont); + gcValues.foreground = black; + gcValues.background = white; + gc = Tk_GetGC(tkwin, GCForeground | GCBackground | GCFont | + GCGraphicsExposures, &gcValues); + Tk_DrawChars(dpy, pixmap, gc, tkfont, string, length, 0, metrics.ascent); + Tk_FreeGC(dpy, gc); + Tk_FreeFont(tkfont); + + /* Convert to rectangles using an image. YUCK! */ + xi = XGetImage(dpy, pixmap, 0, 0, width, metrics.linespace, + AllPlanes, ZPixmap); + Tk_FreePixmap(dpy, pixmap); + + /* Note that this allocates far, far too much memory */ + rects = (XRectangle *) + Tcl_Alloc(sizeof(XRectangle) * width * metrics.linespace); + for (j=1,k=0 ; j +#include +#include +#include "shapeInt.h" + +#ifdef DKF_SHAPE_DEBUGGING +static int +applyOperationToToplevelParent = 1; +#else +#define applyOperationToToplevelParent 1 +#endif + +#define CLASSSIZE 23 +#define RECTCOUNT 64 + +static int getHWNDs _ANSI_ARGS_((Tcl_Interp*, Tk_Window, int, HWND*, HWND*)); +static int setHRGN _ANSI_ARGS_((Tcl_Interp*, char*, HWND, HWND, int, int, + HRGN)); +static int invertHRGN _ANSI_ARGS_((Tcl_Interp*, char*, HWND, HWND, int, int, + int, int)); +static int mixHRGN _ANSI_ARGS_((Tcl_Interp*, char*, HWND, HWND, int, int, int, + HRGN)); + +static int +getHWNDs(interp, tkwin, kind, window, parent) + Tcl_Interp *interp; + Tk_Window tkwin; + int kind; + HWND *window, *parent; +{ + Window w = Tk_WindowId(tkwin); + HWND hwnd; + + if (w == None) { + Tcl_AppendResult(interp, "window \"", Tk_PathName(tkwin), + "\" does not properly exist", NULL); + return TCL_ERROR; + } + *window = hwnd = Tk_GetHWND(w); + if (parent == NULL) { + /* Stop right here! */ + return TCL_OK; + } + if (ShapeApplyToParent(kind) && applyOperationToToplevelParent) { + int returnval; + TCHAR myname[CLASSSIZE+1]; + + while ((returnval = GetClassName(hwnd, myname, CLASSSIZE)) != 0 && + strcmp(myname, "TkTopLevel") != 0) { + hwnd = GetParent(hwnd); + if (hwnd == NULL) { + TclWinConvertError(GetLastError()); + Tcl_AppendResult(interp, "parental window search for " + "window \"", Tk_PathName(tkwin), "\" failed", + NULL); + return TCL_ERROR; + } + } + + if (returnval == 0) { + TclWinConvertError(GetLastError()); + Tcl_AppendResult(interp, "parental classname determinisation ", + "for window \"", Tk_PathName(tkwin), "\" failed", + NULL); + return TCL_ERROR; + } + + *parent = hwnd; + } else { + *parent = NULL; + } + + return TCL_OK; +} + +/* Note that this code assumes that we *own* the region; no other code + * must reference it after this function returns! */ +int +setHRGN(interp, pathname, window, parent, x, y, region) + Tcl_Interp *interp; + char *pathname; + HWND window, parent; + int x, y; + HRGN region; +{ + HRGN tmp; + if ((x!=0 || y!=0) && OffsetRgn(region, x, y) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(region); + Tcl_AppendResult(interp, "could not apply offset to region", + NULL); + return TCL_ERROR; + } + if (SetWindowRgn(window, region, TRUE) == 0) { + TclWinConvertError(GetLastError()); + DeleteObject(region); + Tcl_AppendResult(interp, "set region failed for \"", pathname, "\"", + NULL); + return TCL_ERROR; + } + if (parent == NULL) { + return TCL_OK; + } + tmp = (HRGN)TkCreateRegion(); + if (CombineRgn(tmp, region, tmp, RGN_COPY) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + Tcl_AppendResult(interp, "could not duplicate region", NULL); + return TCL_ERROR; + } + if (SetWindowRgn(parent, tmp, TRUE) == 0) { + TclWinConvertError(GetLastError()); + Tcl_AppendResult(interp, "set region failed for outer shell of \"", + pathname, "\"", NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +static int +invertHRGN(interp, pathname, window, parent, w, h, x, y) + Tcl_Interp *interp; + char *pathname; + HWND window, parent; + int w, h, x, y; +{ + HRGN region = (HRGN)TkCreateRegion(); + HRGN tmp; + + if (GetWindowRgn(window, region) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(region); + Tcl_AppendResult(interp, "could not read existing region of \"", + pathname, "\"", NULL); + return TCL_ERROR; + } + tmp = CreateRectRgn(0, 0, w-1, h-1); /* assume *this* works... */ + if (CombineRgn(tmp, region, tmp, RGN_XOR) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + DeleteObject(region); + Tcl_AppendResult(interp, "could not invert region", NULL); + return TCL_ERROR; + } + DeleteObject(region); + if ((x!=0 || y!=0) && OffsetRgn(tmp, x, y)==ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + Tcl_AppendResult(interp, "could not apply offset to region", + NULL); + return TCL_ERROR; + } + if (SetWindowRgn(window, tmp, TRUE) == 0) { + TclWinConvertError(GetLastError()); + Tcl_AppendResult(interp, "set region failed for \"", pathname, "\"", + NULL); + return TCL_ERROR; + } + if (parent == NULL) { + return TCL_OK; + } + + region = (HRGN)TkCreateRegion(); + if (GetWindowRgn(parent, region) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(region); + Tcl_AppendResult(interp, "could not read existing region of " + "outer shell of \"", pathname, "\"", NULL); + return TCL_ERROR; + } + tmp = CreateRectRgn(0, 0, w-1, h-1); /* assume *this* works... */ + if (CombineRgn(tmp, region, tmp, RGN_XOR) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + DeleteObject(region); + Tcl_AppendResult(interp, "could not invert region", NULL); + return TCL_ERROR; + } + DeleteObject(region); + if ((x!=0 || y!=0) && OffsetRgn(tmp, x, y)==ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + Tcl_AppendResult(interp, "could not apply offset to region", + NULL); + return TCL_ERROR; + } + if (SetWindowRgn(w, tmp, TRUE) == 0) { + TclWinConvertError(GetLastError()); + Tcl_AppendResult(interp, "set region failed for outer shell of \"", + pathname, "\"", NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +static int +mixHRGN(interp, pathname, window, parent, op, x, y, region) + Tcl_Interp *interp; + char *pathname; + HWND window, parent; + int op, x, y; + HRGN region; +{ + HRGN tmp; + if ((x!=0 || y!=0) && OffsetRgn(region, x, y)==ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(region); + Tcl_AppendResult(interp, "could not apply offset to region", + NULL); + return TCL_ERROR; + } + + tmp = (HRGN)TkCreateRegion(); + if (GetWindowRgn(window, tmp) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + DeleteObject(region); + Tcl_AppendResult(interp, "could not read existing region of " + "outer shell of \"", pathname, "\"", NULL); + return TCL_ERROR; + } + if (CombineRgn(tmp, region, tmp, op) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + DeleteObject(region); + Tcl_AppendResult(interp, "could not apply operation to region", NULL); + return TCL_ERROR; + } + if (SetWindowRgn(window, tmp, TRUE) == 0) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + DeleteObject(region); + Tcl_AppendResult(interp, "set region failed for \"", pathname, "\"", + NULL); + return TCL_ERROR; + } + + if (parent == NULL) { + DeleteObject(region); + return TCL_OK; + } + + tmp = (HRGN)TkCreateRegion(); + if (GetWindowRgn(parent, tmp) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + DeleteObject(region); + Tcl_AppendResult(interp, "could not read existing region of " + "outer shell of \"", pathname, "\"", NULL); + return TCL_ERROR; + } + if (CombineRgn(tmp, region, tmp, op) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + DeleteObject(region); + Tcl_AppendResult(interp, "could not apply operation to region", NULL); + return TCL_ERROR; + } + DeleteObject(region); + if (SetWindowRgn(parent, tmp, TRUE) == 0) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + Tcl_AppendResult(interp, "set region failed for outer shell of \"", + pathname, "\"", NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +/* Assume that we can deallocate region. Callers must duplicate if + * necessary! */ +int +ShapeCombineHRGN(interp, tkwin, kind, op, x, y, region) + Tcl_Interp *interp; + Tk_Window tkwin; + int kind, op; + int x, y; /* Ignored, for now... */ + HRGN region; +{ + HWND w, parent; + + if (getHWNDs(interp, tkwin, kind, &w, &parent) != TCL_OK) { + return TCL_ERROR; + } + + switch (op) { + case ShapeInvert: + /* region ignored, so delete! */ + DeleteObject(region); + return invertHRGN(interp, Tk_PathName(tkwin), w, parent, + Tk_Width(tkwin), Tk_Height(tkwin), x, y); + + case ShapeSet: + return setHRGN(interp, Tk_PathName(tkwin), w, parent, x, y, region); + + case ShapeUnion: + return mixHRGN(interp, Tk_PathName(tkwin), w, parent, RGN_OR, x, y, + region); + case ShapeIntersect: + return mixHRGN(interp, Tk_PathName(tkwin), w, parent, RGN_AND, x, y, + region); + case ShapeSubtract: + return mixHRGN(interp, Tk_PathName(tkwin), w, parent, RGN_DIFF, x, y, + region); + default: + Tcl_AppendResult(interp, "unknown operation code", NULL); + /* region ignored, so delete! */ + DeleteObject(region); + return TCL_ERROR; + } +} + +HRGN +ShapeAddDataToRegion(interp, region, data, size) + Tcl_Interp *interp; + HRGN region; + LPRGNDATA data; + int size; +{ + HRGN tmp; + + data->rdh.nCount = size; + tmp = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER)+size*sizeof(RECT), data); + if (region == NULL) return tmp; + if (CombineRgn(tmp, tmp, region, RGN_OR) == ERROR) { + TclWinConvertError(GetLastError()); + DeleteObject(tmp); + DeleteObject(region); + Tcl_AppendResult(interp, "combination operation failed", NULL); + return NULL; + } + DeleteObject(region); + return tmp; +} + +int +Shape_CombineRectangles(interp, tkwin, kind, op, rectc, rectv) + Tcl_Interp *interp; + Tk_Window tkwin; + int kind, op, rectc; + XRectangle *rectv; +{ + int i, j; + HRGN region = NULL, tmprgn; + int size = sizeof(RGNDATAHEADER)+RECTCOUNT*sizeof(RECT); + LPRGNDATA data = (LPRGNDATA)Tcl_Alloc(size); + LPRECT rects = (RECT *)(data->Buffer); + + data->rdh.dwSize = sizeof(data->rdh); + data->rdh.nRgnSize = 0; + data->rdh.rcBound.left = 0; + data->rdh.rcBound.top = 0; + data->rdh.rcBound.right = Tk_Width(tkwin)-1; + data->rdh.rcBound.bottom = Tk_Height(tkwin)-1; + + for (i=j=0 ; iBuffer); + CloseRegion(region); + + /*** GET THE TCL_OBJ FOR THE RECTANGLES ***/ + result = Tcl_NewObj(); + for (i=0 ; irdh.nCount ; i++) { + /* reusing these objects between rectangles is impractical */ + vec[0] = Tcl_NewIntObj(rects[i].left); + vec[1] = Tcl_NewIntObj(rects[i].top); + vec[2] = Tcl_NewIntObj(rects[i].right); + vec[3] = Tcl_NewIntObj(rects[i].bottom); + /* assume this op will not fail, since object is under our control */ + Tcl_ListObjAppendElement(interp, result, Tcl_NewListObj(4, vec)); + } + Tcl_Free((char *)buffer); + Tcl_SetObjResult(interp, result); + + return TCL_OK; +} + +int +Shape_ExtensionPresent(tkwin) + Tk_Window tkwin; +{ + /* Test Windows version here? No, since we're already loaded, and + * the DLL won't make it that far without support for the + * functions we need... */ + return 1; +} + +int +Shape_QueryVersion(tkwin, majorPtr, minorPtr) + Tk_Window tkwin; + int *majorPtr, *minorPtr; +{ + *majorPtr = -1; /* Or maybe 0 instead? */ + *minorPtr = 0; + return 1; +} + +/* Placeholders for stuff not yet done... */ + +int +Shape_CombineBitmap(interp, tkwin, kind, op, x, y, bitmap) + Tcl_Interp *interp; + Tk_Window tkwin; + int kind, op, x, y; + Pixmap bitmap; +{ + Tcl_AppendResult(interp, "operation not supported yet", NULL); + return TCL_ERROR; +} + +XRectangle * +ShapeRenderTextAsRectangles(tkwin, interp, string, font, numRects) + Tk_Window tkwin; + Tcl_Interp *interp; + Tcl_Obj *string, *font; + int *numRects; +{ + Tcl_AppendResult(interp, "operation not supported yet", NULL); + return NULL; +}