From 0bc04d1ae8a133d83ab7887f13cbe49aa4079ee7 Mon Sep 17 00:00:00 2001 From: Christopher Chavez Date: Mon, 13 Nov 2023 04:44:03 -0600 Subject: [PATCH 1/4] shape.c: fix compilation shape.c:404:47: error: cannot take the address of an rvalue of type 'void *' 404 | imageName = Tcl_GetStringFromObj(objv[0], &NULL); | ^~~~~ --- generic/shape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/shape.c b/generic/shape.c index 908cd31..1cfb175 100644 --- a/generic/shape.c +++ b/generic/shape.c @@ -401,7 +401,7 @@ shapePhoto( return TCL_ERROR; } - imageName = Tcl_GetStringFromObj(objv[0], &NULL); + imageName = Tcl_GetString(objv[0]); handle = Tk_FindPhoto(interp, imageName); if (handle == NULL) { return TCL_ERROR; From 6d401cc41e7e6d9f6c55690ee9d7ce6d306f3565 Mon Sep 17 00:00:00 2001 From: Christopher Chavez Date: Mon, 13 Nov 2023 04:54:47 -0600 Subject: [PATCH 2/4] Revise `shapePhoto()` to not use `TkPhotoGetValidRegion()` --- generic/shape.c | 67 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/generic/shape.c b/generic/shape.c index 1cfb175..b027e67 100644 --- a/generic/shape.c +++ b/generic/shape.c @@ -393,7 +393,13 @@ shapePhoto( { char *imageName; Tk_PhotoHandle handle; - Region region; + XImage *maskXImage; + GC maskGC; + Pixmap maskDrawable; + Tk_PhotoImageBlock block; + int result, i, j; + Display *dpy = Tk_Display(tkwin); + Window window = Tk_WindowId(tkwin); if (objc != 1) { Tcl_AppendResult(interp, "photo requires one argument; " @@ -407,20 +413,61 @@ shapePhoto( return TCL_ERROR; } - /* - * Deep implementation magic! Relies on knowing a TkRegion is - * implemented as a Region under X... - */ + Tk_PhotoGetImage(handle, &block); + maskDrawable = Tk_GetPixmap(dpy, window, block.width, block.height, 1); + if (maskDrawable == None) { + Tcl_AppendResult(interp, "Tk_GetPixmap failed for image ", + imageName, (char *)NULL); + return TCL_ERROR; + } - region = (Region) TkPhotoGetValidRegion(handle); + maskGC = XCreateGC(dpy, maskDrawable, 0ul, NULL); + if (maskGC == NULL) { + Tk_FreePixmap(dpy, maskDrawable); + Tcl_AppendResult(interp, "XCreateGC failed for image ", + imageName, (char *)NULL); + return TCL_ERROR; + } - if (region == None) { - Tcl_AppendResult(interp, "bad transparency info in photo image ", - imageName, NULL); + maskXImage = XCreateImage(dpy, Tk_Visual(tkwin), 1u, + XYBitmap, 0, NULL, 1, 1, 32, 0); + if (maskXImage == NULL) { + XFreeGC(dpy, maskGC); + Tk_FreePixmap(dpy, maskDrawable); + Tcl_AppendResult(interp, "XCreateImage failed for image ", + imageName, (char *)NULL); return TCL_ERROR; } - return Shape_CombineRegion(interp, tkwin, kind, op, x, y, region); + maskXImage->width = block.width; + maskXImage->height = block.height; + maskXImage->bytes_per_line = ((block.width + 31) >> 3) & ~3; + maskXImage->data = Tcl_Alloc(block.height * maskXImage->bytes_per_line); + if (maskXImage->data == NULL) { + XDestroyImage(maskXImage); + XFreeGC(dpy, maskGC); + Tk_FreePixmap(dpy, maskDrawable); + Tcl_AppendResult(interp, "failed to allocate mask XImage buffer for image ", + imageName, (char *)NULL); + return TCL_ERROR; + } + + for (i = 0; i < block.height; i++) { + unsigned char *row = block.pixelPtr + i*block.pitch; + for (j = 0; j < block.width; j++) { + unsigned char *pixel = row + j*block.pixelSize; + XPutPixel(maskXImage, j, i, pixel[block.offset[3]] == 0); + } + } + + XPutImage(dpy, maskDrawable, maskGC, maskXImage, 0, 0, 0, 0, block.width, block.height); + Tcl_Free(maskXImage->data); + maskXImage->data = NULL; + XDestroyImage(maskXImage); + XFreeGC(dpy, maskGC); + result = Shape_CombineBitmap(interp, tkwin, kind, op, x, y, maskDrawable); + Tk_FreePixmap(dpy, maskDrawable); + return result; } #endif From 4e1b95747e191939d34f4f7efbe41763b3ba974d Mon Sep 17 00:00:00 2001 From: Christopher Chavez Date: Mon, 13 Nov 2023 05:10:45 -0600 Subject: [PATCH 3/4] Always enable photo shape source functionality Remove unneeded includes, macros, and configure checks --- generic/shape.c | 22 ---------------------- unix/Makefile.in | 2 +- unix/configure | 47 ----------------------------------------------- unix/configure.in | 3 --- 4 files changed, 1 insertion(+), 73 deletions(-) diff --git a/generic/shape.c b/generic/shape.c index b027e67..0595abc 100644 --- a/generic/shape.c +++ b/generic/shape.c @@ -11,17 +11,6 @@ #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 #define min(x,y) ((x)<(y) ? (x) : (y)) @@ -55,12 +44,9 @@ static int shapeText(Tk_Window tkwin, Tcl_Interp *interp, static int shapeWindow(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(Tk_Window tkwin, Tcl_Interp *interp, int x, int y, int op, int kind, int objc, Tcl_Obj *const objv[]); -#endif - static int shapeCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -379,7 +365,6 @@ shapeWindow( return Shape_CombineWindow(interp, tkwin, kind, op, x, y, srcwin); } -#ifdef SUPPORTS_PHOTO_REGION static int shapePhoto( Tk_Window tkwin, @@ -469,7 +454,6 @@ shapePhoto( Tk_FreePixmap(dpy, maskDrawable); return result; } -#endif static int shapeSetUpdateOps( @@ -486,25 +470,19 @@ shapeSetUpdateOps( "-offset", "-bounding", "-clip", "-both", "bitmap", "rectangles", "reset", "text", "window", -#ifdef SUPPORTS_PHOTO_REGION "photo", -#endif NULL }; static enum optkind optk[] = { offsetargs, shapekind, shapekind, shapekind, sourceargs, sourceargs, sourceargs, sourceargs, sourceargs -#ifdef SUPPORTS_PHOTO_REGION , sourceargs -#endif }; static shapeApplicator applicators[] = { NULL, NULL, NULL, NULL, shapeBitmap, shapeRects, shapeReset, shapeText, shapeWindow, -#ifdef SUPPORTS_PHOTO_REGION shapePhoto, -#endif NULL }; diff --git a/unix/Makefile.in b/unix/Makefile.in index a06fb08..eed224b 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -50,7 +50,7 @@ GENERIC_DIR = $(TOP_DIR)/generic UNIX_DIR = $(TOP_DIR)/unix INCLUDE_DIR = $(TOP_DIR)/include # ---------------------------------------------------------------------- -CFLAGS = -g -DSHAPE_PHOTO=@SHAPE_PHOTO@ +CFLAGS = -g 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} \ diff --git a/unix/configure b/unix/configure index d21154f..fa64000 100755 --- a/unix/configure +++ b/unix/configure @@ -492,52 +492,6 @@ else 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)' @@ -679,7 +633,6 @@ 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 diff --git a/unix/configure.in b/unix/configure.in index 5d39794..de38de5 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -65,9 +65,6 @@ 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 From 5be84f91249a8e34346ca779a5f4e6c716e1287e Mon Sep 17 00:00:00 2001 From: Christopher Chavez Date: Mon, 13 Nov 2023 05:43:33 -0600 Subject: [PATCH 4/4] Revise dragger.tcl demo to use photo shape source --- demos/dragger.tcl | 3 +-- demos/images/doc-img.gif | Bin 177 -> 197 bytes demos/images/doc-mask.xbm | 14 -------------- 3 files changed, 1 insertion(+), 16 deletions(-) delete mode 100644 demos/images/doc-mask.xbm diff --git a/demos/dragger.tcl b/demos/dragger.tcl index 1563660..e672ab4 100755 --- a/demos/dragger.tcl +++ b/demos/dragger.tcl @@ -48,7 +48,6 @@ 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\ @@ -67,7 +66,7 @@ set image(doc) [.cursor.workarea create image 3 4 \ #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 upd .cursor.workarea + -offset 3 4 photo doc shape set .cursor window .cursor.workarea proc movecursor {x y} { diff --git a/demos/images/doc-img.gif b/demos/images/doc-img.gif index 0d61b38c28a6611830bbc7670605df9558851b00..c1ab737a5f24b18cd99bb6423c016ef0cb6b17d1 100644 GIT binary patch literal 197 zcmZ?wbhEHbRA5kG_{0DO#l^)xL>z2>m;?m;*uQ`O|Ns9Lf3om`By~UpNG$_%7sswU z|8!4yGVjrub9U#E8P`f16C3+2@@92fz0%tCUa0?SQyofTvNL