/[dtapublic]/projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkimage.c
ViewVC logotype

Annotation of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkimage.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (hide annotations) (download)
Fri Oct 14 01:50:00 2016 UTC (7 years, 6 months ago) by dashley
Original Path: projs/trunk/shared_source/tk_base/tkimage.c
File MIME type: text/plain
File size: 29957 byte(s)
Move shared source code to commonize.
1 dashley 25 /* $Header: /cvsroot/esrg/sfesrg/esrgpcpj/shared/tk_base/tkimage.c,v 1.1.1.1 2001/06/13 05:02:12 dtashley Exp $ */
2    
3     /*
4     * tkImage.c --
5     *
6     * This module implements the image protocol, which allows lots
7     * of different kinds of images to be used in lots of different
8     * widgets.
9     *
10     * Copyright (c) 1994 The Regents of the University of California.
11     * Copyright (c) 1994-1997 Sun Microsystems, Inc.
12     *
13     * See the file "license.terms" for information on usage and redistribution
14     * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15     *
16     * RCS: @(#) $Id: tkimage.c,v 1.1.1.1 2001/06/13 05:02:12 dtashley Exp $
17     */
18    
19     #include "tkInt.h"
20     #include "tkPort.h"
21    
22     /*
23     * Each call to Tk_GetImage returns a pointer to one of the following
24     * structures, which is used as a token by clients (widgets) that
25     * display images.
26     */
27    
28     typedef struct Image {
29     Tk_Window tkwin; /* Window passed to Tk_GetImage (needed to
30     * "re-get" the image later if the manager
31     * changes). */
32     Display *display; /* Display for tkwin. Needed because when
33     * the image is eventually freed tkwin may
34     * not exist anymore. */
35     struct ImageMaster *masterPtr;
36     /* Master for this image (identifiers image
37     * manager, for example). */
38     ClientData instanceData;
39     /* One word argument to pass to image manager
40     * when dealing with this image instance. */
41     Tk_ImageChangedProc *changeProc;
42     /* Code in widget to call when image changes
43     * in a way that affects redisplay. */
44     ClientData widgetClientData;
45     /* Argument to pass to changeProc. */
46     struct Image *nextPtr; /* Next in list of all image instances
47     * associated with the same name. */
48    
49     } Image;
50    
51     /*
52     * For each image master there is one of the following structures,
53     * which represents a name in the image table and all of the images
54     * instantiated from it. Entries in mainPtr->imageTable point to
55     * these structures.
56     */
57    
58     typedef struct ImageMaster {
59     Tk_ImageType *typePtr; /* Information about image type. NULL means
60     * that no image manager owns this image: the
61     * image was deleted. */
62     ClientData masterData; /* One-word argument to pass to image mgr
63     * when dealing with the master, as opposed
64     * to instances. */
65     int width, height; /* Last known dimensions for image. */
66     Tcl_HashTable *tablePtr; /* Pointer to hash table containing image
67     * (the imageTable field in some TkMainInfo
68     * structure). */
69     Tcl_HashEntry *hPtr; /* Hash entry in mainPtr->imageTable for
70     * this structure (used to delete the hash
71     * entry). */
72     Image *instancePtr; /* Pointer to first in list of instances
73     * derived from this name. */
74     } ImageMaster;
75    
76     typedef struct ThreadSpecificData {
77     Tk_ImageType *imageTypeList;/* First in a list of all known image
78     * types. */
79     Tk_ImageType *oldImageTypeList;/* First in a list of all known old-style image
80     * types. */
81     } ThreadSpecificData;
82     static Tcl_ThreadDataKey dataKey;
83    
84     /*
85     * Prototypes for local procedures:
86     */
87    
88     static void DeleteImage _ANSI_ARGS_((ImageMaster *masterPtr));
89    
90     /*
91     *----------------------------------------------------------------------
92     *
93     * Tk_CreateOldImageType, Tk_CreateImageType --
94     *
95     * This procedure is invoked by an image manager to tell Tk about
96     * a new kind of image and the procedures that manage the new type.
97     * The procedure is typically invoked during Tcl_AppInit.
98     *
99     * Results:
100     * None.
101     *
102     * Side effects:
103     * The new image type is entered into a table used in the "image
104     * create" command.
105     *
106     *----------------------------------------------------------------------
107     */
108    
109     void
110     Tk_CreateOldImageType(typePtr)
111     Tk_ImageType *typePtr; /* Structure describing the type. All of
112     * the fields except "nextPtr" must be filled
113     * in by caller. Must not have been passed
114     * to Tk_CreateImageType previously. */
115     {
116     ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
117     Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
118    
119     typePtr->nextPtr = tsdPtr->oldImageTypeList;
120     tsdPtr->oldImageTypeList = typePtr;
121     }
122    
123     void
124     Tk_CreateImageType(typePtr)
125     Tk_ImageType *typePtr; /* Structure describing the type. All of
126     * the fields except "nextPtr" must be filled
127     * in by caller. Must not have been passed
128     * to Tk_CreateImageType previously. */
129     {
130     ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
131     Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
132    
133     typePtr->nextPtr = tsdPtr->imageTypeList;
134     tsdPtr->imageTypeList = typePtr;
135     }
136    
137     /*
138     *----------------------------------------------------------------------
139     *
140     * Tk_ImageObjCmd --
141     *
142     * This procedure is invoked to process the "image" Tcl command.
143     * See the user documentation for details on what it does.
144     *
145     * Results:
146     * A standard Tcl result.
147     *
148     * Side effects:
149     * See the user documentation.
150     *
151     *----------------------------------------------------------------------
152     */
153    
154     int
155     Tk_ImageObjCmd(clientData, interp, objc, objv)
156     ClientData clientData; /* Main window associated with interpreter. */
157     Tcl_Interp *interp; /* Current interpreter. */
158     int objc; /* Number of arguments. */
159     Tcl_Obj *CONST objv[]; /* Argument strings. */
160     {
161     static char *imageOptions[] = {
162     "create", "delete", "height", "names", "type", "types", "width",
163     (char *) NULL
164     };
165     enum options {
166     IMAGE_CREATE, IMAGE_DELETE, IMAGE_HEIGHT, IMAGE_NAMES,
167     IMAGE_TYPE, IMAGE_TYPES, IMAGE_WIDTH
168     };
169     TkWindow *winPtr = (TkWindow *) clientData;
170     int i, new, firstOption, index;
171     Tk_ImageType *typePtr;
172     ImageMaster *masterPtr;
173     Image *imagePtr;
174     Tcl_HashEntry *hPtr;
175     Tcl_HashSearch search;
176     char idString[16 + TCL_INTEGER_SPACE], *name;
177     TkDisplay *dispPtr = winPtr->dispPtr;
178     ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
179     Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
180    
181     if (objc < 2) {
182     Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
183     return TCL_ERROR;
184     }
185    
186     if (Tcl_GetIndexFromObj(interp, objv[1], imageOptions, "option", 0,
187     &index) != TCL_OK) {
188     return TCL_ERROR;
189     }
190     switch ((enum options) index) {
191     case IMAGE_CREATE: {
192     char *arg;
193     Tcl_Obj **args;
194     int oldimage = 0;
195     if (objc < 3) {
196     Tcl_WrongNumArgs(interp, 2, objv, "type ?name? ?options?");
197     return TCL_ERROR;
198     }
199    
200     /*
201     * Look up the image type.
202     */
203    
204     arg = Tcl_GetString(objv[2]);
205     for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
206     typePtr = typePtr->nextPtr) {
207     if ((*arg == typePtr->name[0])
208     && (strcmp(arg, typePtr->name) == 0)) {
209     break;
210     }
211     }
212     if (typePtr == NULL) {
213     oldimage = 1;
214     for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
215     typePtr = typePtr->nextPtr) {
216     if ((*arg == typePtr->name[0])
217     && (strcmp(arg, typePtr->name) == 0)) {
218     break;
219     }
220     }
221     }
222     if (typePtr == NULL) {
223     Tcl_AppendResult(interp, "image type \"", arg,
224     "\" doesn't exist", (char *) NULL);
225     return TCL_ERROR;
226     }
227    
228     /*
229     * Figure out a name to use for the new image.
230     */
231    
232     if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) {
233     dispPtr->imageId++;
234     sprintf(idString, "image%d", dispPtr->imageId);
235     name = idString;
236     firstOption = 3;
237     } else {
238     name = arg;
239     firstOption = 4;
240     }
241    
242     /*
243     * Create the data structure for the new image.
244     */
245    
246     hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable,
247     name, &new);
248     if (new) {
249     masterPtr = (ImageMaster *) ckalloc(sizeof(ImageMaster));
250     masterPtr->typePtr = NULL;
251     masterPtr->masterData = NULL;
252     masterPtr->width = masterPtr->height = 1;
253     masterPtr->tablePtr = &winPtr->mainPtr->imageTable;
254     masterPtr->hPtr = hPtr;
255     masterPtr->instancePtr = NULL;
256     Tcl_SetHashValue(hPtr, masterPtr);
257     } else {
258     /*
259     * An image already exists by this name. Disconnect the
260     * instances from the master.
261     */
262    
263     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
264     if (masterPtr->typePtr != NULL) {
265     for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
266     imagePtr = imagePtr->nextPtr) {
267     (*masterPtr->typePtr->freeProc)(
268     imagePtr->instanceData, imagePtr->display);
269     (*imagePtr->changeProc)(imagePtr->widgetClientData,
270     0, 0, masterPtr->width, masterPtr->height,
271     masterPtr->width, masterPtr->height);
272     }
273     (*masterPtr->typePtr->deleteProc)(masterPtr->masterData);
274     masterPtr->typePtr = NULL;
275     }
276     }
277    
278     /*
279     * Call the image type manager so that it can perform its own
280     * initialization, then re-"get" for any existing instances of
281     * the image.
282     */
283    
284     objv += firstOption;
285     objc -= firstOption;
286     args = (Tcl_Obj **) objv;
287     if (oldimage) {
288     int i;
289     args = (Tcl_Obj **) ckalloc((objc+1) * sizeof(char *));
290     for (i = 0; i < objc; i++) {
291     args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]);
292     }
293     args[objc] = NULL;
294     }
295     if ((*typePtr->createProc)(interp, name, objc,
296     args, typePtr, (Tk_ImageMaster) masterPtr,
297     &masterPtr->masterData) != TCL_OK) {
298     DeleteImage(masterPtr);
299     if (oldimage) {
300     ckfree((char *) args);
301     }
302     return TCL_ERROR;
303     }
304     if (oldimage) {
305     ckfree((char *) args);
306     }
307     masterPtr->typePtr = typePtr;
308     for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
309     imagePtr = imagePtr->nextPtr) {
310     imagePtr->instanceData = (*typePtr->getProc)(
311     imagePtr->tkwin, masterPtr->masterData);
312     }
313     Tcl_SetResult(interp,
314     Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr),
315     TCL_STATIC);
316     break;
317     }
318     case IMAGE_DELETE: {
319     for (i = 2; i < objc; i++) {
320     char *arg = Tcl_GetString(objv[i]);
321     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
322     if (hPtr == NULL) {
323     Tcl_AppendResult(interp, "image \"", arg,
324     "\" doesn't exist", (char *) NULL);
325     return TCL_ERROR;
326     }
327     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
328     DeleteImage(masterPtr);
329     }
330     break;
331     }
332     case IMAGE_HEIGHT: {
333     char *arg;
334     if (objc != 3) {
335     Tcl_WrongNumArgs(interp, 2, objv, "name");
336     return TCL_ERROR;
337     }
338     arg = Tcl_GetString(objv[2]);
339     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
340     if (hPtr == NULL) {
341     Tcl_AppendResult(interp, "image \"", arg,
342     "\" doesn't exist", (char *) NULL);
343     return TCL_ERROR;
344     }
345     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
346     Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->height);
347     break;
348     }
349     case IMAGE_NAMES: {
350     if (objc != 2) {
351     Tcl_WrongNumArgs(interp, 2, objv, NULL);
352     return TCL_ERROR;
353     }
354     for (hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
355     hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
356     Tcl_AppendElement(interp, Tcl_GetHashKey(
357     &winPtr->mainPtr->imageTable, hPtr));
358     }
359     break;
360     }
361     case IMAGE_TYPE: {
362     char *arg;
363     if (objc != 3) {
364     Tcl_WrongNumArgs(interp, 2, objv, "name");
365     return TCL_ERROR;
366     }
367     arg = Tcl_GetString(objv[2]);
368     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
369     if (hPtr == NULL) {
370     Tcl_AppendResult(interp, "image \"", arg,
371     "\" doesn't exist", (char *) NULL);
372     return TCL_ERROR;
373     }
374     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
375     if (masterPtr->typePtr != NULL) {
376     Tcl_SetResult(interp, masterPtr->typePtr->name, TCL_STATIC);
377     }
378     break;
379     }
380     case IMAGE_TYPES: {
381     if (objc != 2) {
382     Tcl_WrongNumArgs(interp, 2, objv, NULL);
383     return TCL_ERROR;
384     }
385     for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
386     typePtr = typePtr->nextPtr) {
387     Tcl_AppendElement(interp, typePtr->name);
388     }
389     for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
390     typePtr = typePtr->nextPtr) {
391     Tcl_AppendElement(interp, typePtr->name);
392     }
393     break;
394     }
395     case IMAGE_WIDTH: {
396     char *arg;
397     if (objc != 3) {
398     Tcl_WrongNumArgs(interp, 2, objv, "name");
399     return TCL_ERROR;
400     }
401     arg = Tcl_GetString(objv[2]);
402     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
403     if (hPtr == NULL) {
404     Tcl_AppendResult(interp, "image \"", arg,
405     "\" doesn't exist", (char *) NULL);
406     return TCL_ERROR;
407     }
408     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
409     Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->width);
410     break;
411     }
412     }
413     return TCL_OK;
414     }
415    
416     /*
417     *----------------------------------------------------------------------
418     *
419     * Tk_ImageChanged --
420     *
421     * This procedure is called by an image manager whenever something
422     * has happened that requires the image to be redrawn (some of its
423     * pixels have changed, or its size has changed).
424     *
425     * Results:
426     * None.
427     *
428     * Side effects:
429     * Any widgets that display the image are notified so that they
430     * can redisplay themselves as appropriate.
431     *
432     *----------------------------------------------------------------------
433     */
434    
435     void
436     Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth,
437     imageHeight)
438     Tk_ImageMaster imageMaster; /* Image that needs redisplay. */
439     int x, y; /* Coordinates of upper-left pixel of
440     * region of image that needs to be
441     * redrawn. */
442     int width, height; /* Dimensions (in pixels) of region of
443     * image to redraw. If either dimension
444     * is zero then the image doesn't need to
445     * be redrawn (perhaps all that happened is
446     * that its size changed). */
447     int imageWidth, imageHeight;/* New dimensions of image. */
448     {
449     ImageMaster *masterPtr = (ImageMaster *) imageMaster;
450     Image *imagePtr;
451    
452     masterPtr->width = imageWidth;
453     masterPtr->height = imageHeight;
454     for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
455     imagePtr = imagePtr->nextPtr) {
456     (*imagePtr->changeProc)(imagePtr->widgetClientData, x, y,
457     width, height, imageWidth, imageHeight);
458     }
459     }
460    
461     /*
462     *----------------------------------------------------------------------
463     *
464     * Tk_NameOfImage --
465     *
466     * Given a token for an image master, this procedure returns
467     * the name of the image.
468     *
469     * Results:
470     * The return value is the string name for imageMaster.
471     *
472     * Side effects:
473     * None.
474     *
475     *----------------------------------------------------------------------
476     */
477    
478     char *
479     Tk_NameOfImage(imageMaster)
480     Tk_ImageMaster imageMaster; /* Token for image. */
481     {
482     ImageMaster *masterPtr = (ImageMaster *) imageMaster;
483    
484     return Tcl_GetHashKey(masterPtr->tablePtr, masterPtr->hPtr);
485     }
486    
487     /*
488     *----------------------------------------------------------------------
489     *
490     * Tk_GetImage --
491     *
492     * This procedure is invoked by a widget when it wants to use
493     * a particular image in a particular window.
494     *
495     * Results:
496     * The return value is a token for the image. If there is no image
497     * by the given name, then NULL is returned and an error message is
498     * left in the interp's result.
499     *
500     * Side effects:
501     * Tk records the fact that the widget is using the image, and
502     * it will invoke changeProc later if the widget needs redisplay
503     * (i.e. its size changes or some of its pixels change). The
504     * caller must eventually invoke Tk_FreeImage when it no longer
505     * needs the image.
506     *
507     *----------------------------------------------------------------------
508     */
509    
510     Tk_Image
511     Tk_GetImage(interp, tkwin, name, changeProc, clientData)
512     Tcl_Interp *interp; /* Place to leave error message if image
513     * can't be found. */
514     Tk_Window tkwin; /* Token for window in which image will
515     * be used. */
516     char *name; /* Name of desired image. */
517     Tk_ImageChangedProc *changeProc;
518     /* Procedure to invoke when redisplay is
519     * needed because image's pixels or size
520     * changed. */
521     ClientData clientData; /* One-word argument to pass to damageProc. */
522     {
523     Tcl_HashEntry *hPtr;
524     ImageMaster *masterPtr;
525     Image *imagePtr;
526    
527     hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->imageTable, name);
528     if (hPtr == NULL) {
529     goto noSuchImage;
530     }
531     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
532     if (masterPtr->typePtr == NULL) {
533     goto noSuchImage;
534     }
535     imagePtr = (Image *) ckalloc(sizeof(Image));
536     imagePtr->tkwin = tkwin;
537     imagePtr->display = Tk_Display(tkwin);
538     imagePtr->masterPtr = masterPtr;
539     imagePtr->instanceData =
540     (*masterPtr->typePtr->getProc)(tkwin, masterPtr->masterData);
541     imagePtr->changeProc = changeProc;
542     imagePtr->widgetClientData = clientData;
543     imagePtr->nextPtr = masterPtr->instancePtr;
544     masterPtr->instancePtr = imagePtr;
545     return (Tk_Image) imagePtr;
546    
547     noSuchImage:
548     Tcl_AppendResult(interp, "image \"", name, "\" doesn't exist",
549     (char *) NULL);
550     return NULL;
551     }
552    
553     /*
554     *----------------------------------------------------------------------
555     *
556     * Tk_FreeImage --
557     *
558     * This procedure is invoked by a widget when it no longer needs
559     * an image acquired by a previous call to Tk_GetImage. For each
560     * call to Tk_GetImage there must be exactly one call to Tk_FreeImage.
561     *
562     * Results:
563     * None.
564     *
565     * Side effects:
566     * The association between the image and the widget is removed.
567     *
568     *----------------------------------------------------------------------
569     */
570    
571     void
572     Tk_FreeImage(image)
573     Tk_Image image; /* Token for image that is no longer
574     * needed by a widget. */
575     {
576     Image *imagePtr = (Image *) image;
577     ImageMaster *masterPtr = imagePtr->masterPtr;
578     Image *prevPtr;
579    
580     /*
581     * Clean up the particular instance.
582     */
583    
584     if (masterPtr->typePtr != NULL) {
585     (*masterPtr->typePtr->freeProc)(imagePtr->instanceData,
586     imagePtr->display);
587     }
588     prevPtr = masterPtr->instancePtr;
589     if (prevPtr == imagePtr) {
590     masterPtr->instancePtr = imagePtr->nextPtr;
591     } else {
592     while (prevPtr->nextPtr != imagePtr) {
593     prevPtr = prevPtr->nextPtr;
594     }
595     prevPtr->nextPtr = imagePtr->nextPtr;
596     }
597     ckfree((char *) imagePtr);
598    
599     /*
600     * If there are no more instances left for the master, and if the
601     * master image has been deleted, then delete the master too.
602     */
603    
604     if ((masterPtr->typePtr == NULL) && (masterPtr->instancePtr == NULL)) {
605     Tcl_DeleteHashEntry(masterPtr->hPtr);
606     ckfree((char *) masterPtr);
607     }
608     }
609    
610     /*
611     *----------------------------------------------------------------------
612     *
613     * Tk_PostscriptImage --
614     *
615     * This procedure is called by widgets that contain images in order
616     * to redisplay an image on the screen or an off-screen pixmap.
617     *
618     * Results:
619     * None.
620     *
621     * Side effects:
622     * The image's manager is notified, and it redraws the desired
623     * portion of the image before returning.
624     *
625     *----------------------------------------------------------------------
626     */
627    
628     int
629     Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass)
630     Tk_Image image; /* Token for image to redisplay. */
631     Tcl_Interp *interp;
632     Tk_Window tkwin;
633     Tk_PostscriptInfo psinfo; /* postscript info */
634     int x, y; /* Upper-left pixel of region in image that
635     * needs to be redisplayed. */
636     int width, height; /* Dimensions of region to redraw. */
637     int prepass;
638     {
639     Image *imagePtr = (Image *) image;
640     int result;
641     XImage *ximage;
642     Pixmap pmap;
643     GC newGC;
644     XGCValues gcValues;
645    
646     if (imagePtr->masterPtr->typePtr == NULL) {
647     /*
648     * No master for image, so nothing to display on postscript.
649     */
650     return TCL_OK;
651     }
652    
653     /*
654     * Check if an image specific postscript-generation function
655     * exists; otherwise go on with generic code.
656     */
657    
658     if (imagePtr->masterPtr->typePtr->postscriptProc != NULL) {
659     return (*imagePtr->masterPtr->typePtr->postscriptProc)(
660     imagePtr->masterPtr->masterData, interp, tkwin, psinfo,
661     x, y, width, height, prepass);
662     }
663    
664     if (prepass) {
665     return TCL_OK;
666     }
667    
668     /*
669     * Create a Pixmap, tell the image to redraw itself there, and then
670     * generate an XImage from the Pixmap. We can then read pixel
671     * values out of the XImage.
672     */
673    
674     pmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
675     width, height, Tk_Depth(tkwin));
676    
677     gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
678     newGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
679     if (newGC != None) {
680     XFillRectangle(Tk_Display(tkwin), pmap, newGC,
681     0, 0, (unsigned int)width, (unsigned int)height);
682     Tk_FreeGC(Tk_Display(tkwin), newGC);
683     }
684    
685     Tk_RedrawImage(image, x, y, width, height, pmap, 0, 0);
686    
687     ximage = XGetImage(Tk_Display(tkwin), pmap, 0, 0,
688     (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap);
689    
690     Tk_FreePixmap(Tk_Display(tkwin), pmap);
691    
692     if (ximage == NULL) {
693     /* The XGetImage() function is apparently not
694     * implemented on this system. Just ignore it.
695     */
696     return TCL_OK;
697     }
698     result = TkPostscriptImage(interp, tkwin, psinfo, ximage, x, y,
699     width, height);
700    
701     XDestroyImage(ximage);
702     return result;
703     }
704    
705     /*
706     *----------------------------------------------------------------------
707     *
708     * Tk_RedrawImage --
709     *
710     * This procedure is called by widgets that contain images in order
711     * to redisplay an image on the screen or an off-screen pixmap.
712     *
713     * Results:
714     * None.
715     *
716     * Side effects:
717     * The image's manager is notified, and it redraws the desired
718     * portion of the image before returning.
719     *
720     *----------------------------------------------------------------------
721     */
722    
723     void
724     Tk_RedrawImage(image, imageX, imageY, width, height, drawable,
725     drawableX, drawableY)
726     Tk_Image image; /* Token for image to redisplay. */
727     int imageX, imageY; /* Upper-left pixel of region in image that
728     * needs to be redisplayed. */
729     int width, height; /* Dimensions of region to redraw. */
730     Drawable drawable; /* Drawable in which to display image
731     * (window or pixmap). If this is a pixmap,
732     * it must have the same depth as the window
733     * used in the Tk_GetImage call for the
734     * image. */
735     int drawableX, drawableY; /* Coordinates in drawable that correspond
736     * to imageX and imageY. */
737     {
738     Image *imagePtr = (Image *) image;
739    
740     if (imagePtr->masterPtr->typePtr == NULL) {
741     /*
742     * No master for image, so nothing to display.
743     */
744    
745     return;
746     }
747    
748     /*
749     * Clip the redraw area to the area of the image.
750     */
751    
752     if (imageX < 0) {
753     width += imageX;
754     drawableX -= imageX;
755     imageX = 0;
756     }
757     if (imageY < 0) {
758     height += imageY;
759     drawableY -= imageY;
760     imageY = 0;
761     }
762     if ((imageX + width) > imagePtr->masterPtr->width) {
763     width = imagePtr->masterPtr->width - imageX;
764     }
765     if ((imageY + height) > imagePtr->masterPtr->height) {
766     height = imagePtr->masterPtr->height - imageY;
767     }
768     (*imagePtr->masterPtr->typePtr->displayProc)(
769     imagePtr->instanceData, imagePtr->display, drawable,
770     imageX, imageY, width, height, drawableX, drawableY);
771     }
772    
773     /*
774     *----------------------------------------------------------------------
775     *
776     * Tk_SizeOfImage --
777     *
778     * This procedure returns the current dimensions of an image.
779     *
780     * Results:
781     * The width and height of the image are returned in *widthPtr
782     * and *heightPtr.
783     *
784     * Side effects:
785     * None.
786     *
787     *----------------------------------------------------------------------
788     */
789    
790     void
791     Tk_SizeOfImage(image, widthPtr, heightPtr)
792     Tk_Image image; /* Token for image whose size is wanted. */
793     int *widthPtr; /* Return width of image here. */
794     int *heightPtr; /* Return height of image here. */
795     {
796     Image *imagePtr = (Image *) image;
797    
798     *widthPtr = imagePtr->masterPtr->width;
799     *heightPtr = imagePtr->masterPtr->height;
800     }
801    
802     /*
803     *----------------------------------------------------------------------
804     *
805     * Tk_DeleteImage --
806     *
807     * Given the name of an image, this procedure destroys the
808     * image.
809     *
810     * Results:
811     * None.
812     *
813     * Side effects:
814     * The image is destroyed; existing instances will display as
815     * blank areas. If no such image exists then the procedure does
816     * nothing.
817     *
818     *----------------------------------------------------------------------
819     */
820    
821     void
822     Tk_DeleteImage(interp, name)
823     Tcl_Interp *interp; /* Interpreter in which the image was
824     * created. */
825     char *name; /* Name of image. */
826     {
827     Tcl_HashEntry *hPtr;
828     TkWindow *winPtr;
829    
830     winPtr = (TkWindow *) Tk_MainWindow(interp);
831     if (winPtr == NULL) {
832     return;
833     }
834     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
835     if (hPtr == NULL) {
836     return;
837     }
838     DeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr));
839     }
840    
841     /*
842     *----------------------------------------------------------------------
843     *
844     * DeleteImage --
845     *
846     * This procedure is responsible for deleting an image.
847     *
848     * Results:
849     * None.
850     *
851     * Side effects:
852     * The connection is dropped between instances of this image and
853     * an image master. Image instances will redisplay themselves
854     * as empty areas, but existing instances will not be deleted.
855     *
856     *----------------------------------------------------------------------
857     */
858    
859     static void
860     DeleteImage(masterPtr)
861     ImageMaster *masterPtr; /* Pointer to main data structure for image. */
862     {
863     Image *imagePtr;
864     Tk_ImageType *typePtr;
865    
866     typePtr = masterPtr->typePtr;
867     masterPtr->typePtr = NULL;
868     if (typePtr != NULL) {
869     for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
870     imagePtr = imagePtr->nextPtr) {
871     (*typePtr->freeProc)(imagePtr->instanceData,
872     imagePtr->display);
873     (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0,
874     masterPtr->width, masterPtr->height, masterPtr->width,
875     masterPtr->height);
876     }
877     (*typePtr->deleteProc)(masterPtr->masterData);
878     }
879     if (masterPtr->instancePtr == NULL) {
880     Tcl_DeleteHashEntry(masterPtr->hPtr);
881     ckfree((char *) masterPtr);
882     }
883     }
884    
885     /*
886     *----------------------------------------------------------------------
887     *
888     * TkDeleteAllImages --
889     *
890     * This procedure is called when an application is deleted. It
891     * calls back all of the managers for all images so that they
892     * can cleanup, then it deletes all of Tk's internal information
893     * about images.
894     *
895     * Results:
896     * None.
897     *
898     * Side effects:
899     * All information for all images gets deleted.
900     *
901     *----------------------------------------------------------------------
902     */
903    
904     void
905     TkDeleteAllImages(mainPtr)
906     TkMainInfo *mainPtr; /* Structure describing application that is
907     * going away. */
908     {
909     Tcl_HashSearch search;
910     Tcl_HashEntry *hPtr;
911     ImageMaster *masterPtr;
912    
913     for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search);
914     hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
915     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
916     DeleteImage(masterPtr);
917     }
918     Tcl_DeleteHashTable(&mainPtr->imageTable);
919     }
920    
921     /*
922     *----------------------------------------------------------------------
923     *
924     * Tk_GetImageMasterData --
925     *
926     * Given the name of an image, this procedure returns the type
927     * of the image and the clientData associated with its master.
928     *
929     * Results:
930     * If there is no image by the given name, then NULL is returned
931     * and a NULL value is stored at *typePtrPtr. Otherwise the return
932     * value is the clientData returned by the createProc when the
933     * image was created and a pointer to the type structure for the
934     * image is stored at *typePtrPtr.
935     *
936     * Side effects:
937     * None.
938     *
939     *----------------------------------------------------------------------
940     */
941    
942     ClientData
943     Tk_GetImageMasterData(interp, name, typePtrPtr)
944     Tcl_Interp *interp; /* Interpreter in which the image was
945     * created. */
946     char *name; /* Name of image. */
947     Tk_ImageType **typePtrPtr; /* Points to location to fill in with
948     * pointer to type information for image. */
949     {
950     Tcl_HashEntry *hPtr;
951     TkWindow *winPtr;
952     ImageMaster *masterPtr;
953    
954     winPtr = (TkWindow *) Tk_MainWindow(interp);
955     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
956     if (hPtr == NULL) {
957     *typePtrPtr = NULL;
958     return NULL;
959     }
960     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
961     *typePtrPtr = masterPtr->typePtr;
962     return masterPtr->masterData;
963     }
964    
965     /*
966     *----------------------------------------------------------------------
967     *
968     * Tk_SetTSOrigin --
969     *
970     * Set the pattern origin of the tile to a common point (i.e. the
971     * origin (0,0) of the top level window) so that tiles from two
972     * different widgets will match up. This done by setting the
973     * GCTileStipOrigin field is set to the translated origin of the
974     * toplevel window in the hierarchy.
975     *
976     * Results:
977     * None.
978     *
979     * Side Effects:
980     * The GCTileStipOrigin is reset in the GC. This will cause the
981     * tile origin to change when the GC is used for drawing.
982     *
983     *----------------------------------------------------------------------
984     */
985     /*ARGSUSED*/
986     void
987     Tk_SetTSOrigin(tkwin, gc, x, y)
988     Tk_Window tkwin;
989     GC gc;
990     int x, y;
991     {
992     while (!Tk_IsTopLevel(tkwin)) {
993     x -= Tk_X(tkwin) + Tk_Changes(tkwin)->border_width;
994     y -= Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
995     tkwin = Tk_Parent(tkwin);
996     }
997     XSetTSOrigin(Tk_Display(tkwin), gc, x, y);
998     }
999    
1000    
1001     /* $History: tkImage.c $
1002     *
1003     * ***************** Version 1 *****************
1004     * User: Dtashley Date: 1/02/01 Time: 2:55a
1005     * Created in $/IjuScripter, IjuConsole/Source/Tk Base
1006     * Initial check-in.
1007     */
1008    
1009     /* End of TKIMAGE.C */

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25