XWorkstation.st
changeset 7509 d18f375ac80d
parent 7507 cb7c25da60d0
child 7542 9e125aa140f9
child 7591 bce664b396f0
equal deleted inserted replaced
7508:f581795812b9 7509:d18f375ac80d
   124 #endif
   124 #endif
   125 
   125 
   126 extern OBJ __GLOBAL_GET_BY_NAME(char *);
   126 extern OBJ __GLOBAL_GET_BY_NAME(char *);
   127 
   127 
   128 # define __HANDLE_VAL(type, externalAddress) \
   128 # define __HANDLE_VAL(type, externalAddress) \
   129         ((type)__externalAddressVal(externalAddress))
   129 	((type)__externalAddressVal(externalAddress))
   130 
   130 
   131 # define __HANDLE_NEW(ptr, __cls)                    \
   131 # define __HANDLE_NEW(ptr, __cls)                    \
   132         ({                                           \
   132 	({                                           \
   133             OBJ handle = __MKEXTERNALADDRESS(ptr);   \
   133 	    OBJ handle = __MKEXTERNALADDRESS(ptr);   \
   134             OBJ clsObj = __GLOBAL_GET_BY_NAME(__cls);\
   134 	    OBJ clsObj = __GLOBAL_GET_BY_NAME(__cls);\
   135             __InstPtr(handle)->o_class = clsObj;     \
   135 	    __InstPtr(handle)->o_class = clsObj;     \
   136             __STORE(handle, clsObj);                 \
   136 	    __STORE(handle, clsObj);                 \
   137             handle;                                  \
   137 	    handle;                                  \
   138         })
   138 	})
   139 
   139 
   140 /*
   140 /*
   141  * this define suppresses XAllocColor/XFreeColor on
   141  * this define suppresses XAllocColor/XFreeColor on
   142  * TrueColor systems - I am not certain, if this is
   142  * TrueColor systems - I am not certain, if this is
   143  * always legal to do (it works with XFree servers).
   143  * always legal to do (it works with XFree servers).
   293  * This exception will shutDown the connection.
   293  * This exception will shutDown the connection.
   294  * Q: is this a good idea for the local display ?
   294  * Q: is this a good idea for the local display ?
   295  */
   295  */
   296 #define __ENTER_XLIB(whichTimeout)   \
   296 #define __ENTER_XLIB(whichTimeout)   \
   297     { \
   297     { \
   298         __blockingPrimitiveTimoutHandler__ = (VOIDFUNC)__XTimeoutErrorHandler; \
   298 	__blockingPrimitiveTimoutHandler__ = (voidFUNC)__XTimeoutErrorHandler; \
   299         __blockingPrimitiveTimeoutArg__ = self; \
   299 	__blockingPrimitiveTimeoutArg__ = self; \
   300         __blockingPrimitiveTimeout__ = whichTimeout; \
   300 	__blockingPrimitiveTimeout__ = whichTimeout; \
   301     } {
   301     } {
   302 
   302 
   303 #define LEAVE_XLIB()   \
   303 #define LEAVE_XLIB()   \
   304     { \
   304     { \
   305         __blockingPrimitiveTimoutHandler__ = (VOIDFUNC)0; \
   305 	__blockingPrimitiveTimoutHandler__ = (voidFUNC)0; \
   306         __blockingPrimitiveTimeoutArg__ = nil; \
   306 	__blockingPrimitiveTimeoutArg__ = nil; \
   307         __blockingPrimitiveTimeout__ = 0; \
   307 	__blockingPrimitiveTimeout__ = 0; \
   308     } }
   308     } }
   309 
   309 
   310 #define ENTER_XLIB()   __ENTER_XLIB(__intVal(__INST(xlibTimeout)) * 1000)
   310 #define ENTER_XLIB()   __ENTER_XLIB(__intVal(__INST(xlibTimeout)) * 1000)
   311 #define ENTER_XLIB2()  __ENTER_XLIB(__intVal(__INST(xlibTimeoutForWindowCreation)) * 1000)
   311 #define ENTER_XLIB2()  __ENTER_XLIB(__intVal(__INST(xlibTimeoutForWindowCreation)) * 1000)
   312 
   312 
   395 # ifdef __GNUC__
   395 # ifdef __GNUC__
   396 VOLATILE
   396 VOLATILE
   397 # endif
   397 # endif
   398 static void
   398 static void
   399 dummyToForceLoading() {
   399 dummyToForceLoading() {
   400         XCreateSimpleWindow(0, 0, 0, 0, 0, 0, 0, 0, 0);
   400 	XCreateSimpleWindow(0, 0, 0, 0, 0, 0, 0, 0, 0);
   401         XCloseDisplay(0);
   401 	XCloseDisplay(0);
   402         XCreateImage(0, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0);
   402 	XCreateImage(0, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0);
   403         XSetWindowColormap(0, 0, 0);
   403 	XSetWindowColormap(0, 0, 0);
   404         XQueryColors(0,0,0,0);
   404 	XQueryColors(0,0,0,0);
   405 # ifdef SHM
   405 # ifdef SHM
   406         XShmAttach(0, 0);
   406 	XShmAttach(0, 0);
   407         XShmCreateImage(0, 0, 0, 0, 0, 0, 0 ,0);
   407 	XShmCreateImage(0, 0, 0, 0, 0, 0, 0 ,0);
   408         XShmDetach(0, 0);
   408 	XShmDetach(0, 0);
   409         XShmPutImage(0, 0, 0, 0 , 0,0,0,0,0,0,0);
   409 	XShmPutImage(0, 0, 0, 0 , 0,0,0,0,0,0,0);
   410         shmctl(0,0,0);
   410 	shmctl(0,0,0);
   411         fgetc(0);
   411 	fgetc(0);
   412 # endif  // SHM
   412 # endif  // SHM
   413 }
   413 }
   414 #endif // !ELF
   414 #endif // !ELF
   415 
   415 
   416 static char* requestNames[] = {
   416 static char* requestNames[] = {
   553 {
   553 {
   554     XGetErrorText(dpy, event->error_code, lastErrorMsg, 127);
   554     XGetErrorText(dpy, event->error_code, lastErrorMsg, 127);
   555     lastErrorMsg[127] = '\0';
   555     lastErrorMsg[127] = '\0';
   556 
   556 
   557     if (lastErrorMsg[0] == '\0') {
   557     if (lastErrorMsg[0] == '\0') {
   558         sprintf(lastErrorMsg, "code: %d", event->error_code);
   558 	sprintf(lastErrorMsg, "code: %d", event->error_code);
   559     }
   559     }
   560     lastRequestCode = event->request_code;
   560     lastRequestCode = event->request_code;
   561     lastMinorCode = event->minor_code;
   561     lastMinorCode = event->minor_code;
   562     lastResource = event->resourceid;
   562     lastResource = event->resourceid;
   563     if ((event->error_code == BadWindow) && (lastRequestCode == 4) && (lastMinorCode == 0)) {
   563     if ((event->error_code == BadWindow) && (lastRequestCode == 4) && (lastMinorCode == 0)) {
   564         /*
   564 	/*
   565          * this is a BadWindow error for X_DestroyWindow.
   565 	 * this is a BadWindow error for X_DestroyWindow.
   566          * ignore it here, since it results from the GC freeing windows
   566 	 * ignore it here, since it results from the GC freeing windows
   567          * in non bottom-up window order.
   567 	 * in non bottom-up window order.
   568          */
   568 	 */
   569         return 0;
   569 	return 0;
   570     }
   570     }
   571 
   571 
   572     if (@global(DeviceWorkstation:ErrorPrinting) == true) {
   572     if (@global(DeviceWorkstation:ErrorPrinting) == true) {
   573         char *requestName = "?";
   573 	char *requestName = "?";
   574 
   574 
   575         if (event->request_code < (sizeof(requestNames)/sizeof(char *))) {
   575 	if (event->request_code < (sizeof(requestNames)/sizeof(char *))) {
   576             requestName = requestNames[event->request_code];
   576 	    requestName = requestNames[event->request_code];
   577         }
   577 	}
   578         console_fprintf(stderr, "XWorkstation [error]: x-error caught maj=%d (0x%x) \"%s\", min=%d (0x%x), resource=%"_lx_"\n",
   578 	console_fprintf(stderr, "XWorkstation [error]: x-error caught maj=%d (0x%x) \"%s\", min=%d (0x%x), resource=%"_lx_"\n",
   579                         event->request_code, event->request_code, requestName,
   579 			event->request_code, event->request_code, requestName,
   580                         event->minor_code, event->minor_code, (INT)(event->resourceid));
   580 			event->minor_code, event->minor_code, (INT)(event->resourceid));
   581         console_fprintf(stderr, "XWorkstation [error]: x-error message is [%d] '%s'\n",
   581 	console_fprintf(stderr, "XWorkstation [error]: x-error message is [%d] '%s'\n",
   582                         event->error_code, lastErrorMsg);
   582 			event->error_code, lastErrorMsg);
   583     }
   583     }
   584 #if 0
   584 #if 0
   585     // cg: should no longer be needed - librun no longer sends an errorInterrupt while running on C-stack
   585     // cg: should no longer be needed - librun no longer sends an errorInterrupt while running on C-stack
   586 #ifdef XFT
   586 #ifdef XFT
   587     if ((strncmp(lastErrorMsg, "RenderBadPicture", 16) == 0)) {
   587     if ((strncmp(lastErrorMsg, "RenderBadPicture", 16) == 0)) {
   588         /*
   588 	/*
   589          * this is a RenderBadPicture error from XFT drawing.
   589 	 * this is a RenderBadPicture error from XFT drawing.
   590          * ignore it for now, as this is due to an incomplete implementation
   590 	 * ignore it for now, as this is due to an incomplete implementation
   591          */
   591 	 */
   592         console_fprintf(stderr, "XWorkstation [info]: x-error ignored\n");
   592 	console_fprintf(stderr, "XWorkstation [info]: x-error ignored\n");
   593         return 0;
   593 	return 0;
   594     }
   594     }
   595 #endif
   595 #endif
   596 #endif
   596 #endif
   597     __errorInterruptWithIDAndParameter__(@symbol(DisplayError), __MKEXTERNALADDRESS(dpy));
   597     __errorInterruptWithIDAndParameter__(@symbol(DisplayError), __MKEXTERNALADDRESS(dpy));
   598     return 0;
   598     return 0;
   608  */
   608  */
   609 int
   609 int
   610 __XIOErrorHandler__(Display *dpy)
   610 __XIOErrorHandler__(Display *dpy)
   611 {
   611 {
   612     if (@global(DeviceWorkstation:ErrorPrinting) == true) {
   612     if (@global(DeviceWorkstation:ErrorPrinting) == true) {
   613         console_fprintf(stderr, "XWorkstation [error]: I/O error\n");
   613 	console_fprintf(stderr, "XWorkstation [error]: I/O error\n");
   614     }
   614     }
   615     __immediateErrorInterruptWithIDAndParameter__(@symbol(DisplayIOError),
   615     __immediateErrorInterruptWithIDAndParameter__(@symbol(DisplayIOError),
   616                                                   __MKEXTERNALADDRESS(dpy));
   616 						  __MKEXTERNALADDRESS(dpy));
   617 
   617 
   618 #if 0
   618 #if 0
   619     /*
   619     /*
   620      * don't do this.
   620      * don't do this.
   621      * This error is called asynchronously, and the wrong process may be terminated
   621      * This error is called asynchronously, and the wrong process may be terminated
   642  */
   642  */
   643 void
   643 void
   644 __XTimeoutErrorHandler(OBJ displayDeviceInst)
   644 __XTimeoutErrorHandler(OBJ displayDeviceInst)
   645 {
   645 {
   646     if ((displayDeviceInst == @global(MainDisplay))
   646     if ((displayDeviceInst == @global(MainDisplay))
   647         || (displayDeviceInst == @global(DeviceWorkstation:DefaultScreen))) {
   647 	|| (displayDeviceInst == @global(DeviceWorkstation:DefaultScreen))) {
   648         console_fprintf(stderr, "XWorkstation [error]: keep display connection for master display after X11 timeout (no shutdown)\n");
   648 	console_fprintf(stderr, "XWorkstation [error]: keep display connection for master display after X11 timeout (no shutdown)\n");
   649         return;
   649 	return;
   650     }
   650     }
   651     if (@global(DeviceWorkstation:ErrorPrinting) == true) {
   651     if (@global(DeviceWorkstation:ErrorPrinting) == true) {
   652         console_fprintf(stderr, "XWorkstation [error]: X11 request timeout dpy=%"_lx_"\n", (INT)displayDeviceInst);
   652 	console_fprintf(stderr, "XWorkstation [error]: X11 request timeout dpy=%"_lx_"\n", (INT)displayDeviceInst);
   653     }
   653     }
   654     __OINST(displayDeviceInst, hasConnectionBroken) = true;
   654     __OINST(displayDeviceInst, hasConnectionBroken) = true;
   655 
   655 
   656     __PROTECT__(displayDeviceInst);
   656     __PROTECT__(displayDeviceInst);
   657     __immediateErrorInterruptWithIDAndParameter__(@symbol(DisplayIOTimeoutError), displayDeviceInst);
   657     __immediateErrorInterruptWithIDAndParameter__(@symbol(DisplayIOTimeoutError), displayDeviceInst);
   659 
   659 
   660     /*
   660     /*
   661      * if we return from the error interrupt ...
   661      * if we return from the error interrupt ...
   662      */
   662      */
   663     if (__OINST(displayDeviceInst, displayId) != nil) {
   663     if (__OINST(displayDeviceInst, displayId) != nil) {
   664         __internalError("unhandled X11 display timeout error");
   664 	__internalError("unhandled X11 display timeout error");
   665 
   665 
   666         /*
   666 	/*
   667          * the current process failed to do an X11 request.
   667 	 * the current process failed to do an X11 request.
   668          * Terminate it!
   668 	 * Terminate it!
   669          */
   669 	 */
   670         __terminateProcess(0);      /* soft terminate */
   670 	__terminateProcess(0);      /* soft terminate */
   671         __terminateProcess(1);      /* hard terminate */
   671 	__terminateProcess(1);      /* hard terminate */
   672     }
   672     }
   673 }
   673 }
   674 #endif // __INCREMENTAL_COMPILE__
   674 #endif // __INCREMENTAL_COMPILE__
   675 
   675 
   676 %}
   676 %}
   705     the other device to the currentScreen query.
   705     the other device to the currentScreen query.
   706     Therefore, 'normal' applications do not have to care for all of this, as the currentScreen
   706     Therefore, 'normal' applications do not have to care for all of this, as the currentScreen
   707     query is answered by the launcher when opening its applications.
   707     query is answered by the launcher when opening its applications.
   708 
   708 
   709     Timeouts:
   709     Timeouts:
   710         sometimes, X-connections are lost and, as the Xlib is blocking and synchronous by
   710 	sometimes, X-connections are lost and, as the Xlib is blocking and synchronous by
   711         default, this would lead to a locked ST/X system.
   711 	default, this would lead to a locked ST/X system.
   712         Therefore, this class defines a timeOut, whenever doing an Xlib call.
   712 	Therefore, this class defines a timeOut, whenever doing an Xlib call.
   713         The default for this timeout is 30seconds.
   713 	The default for this timeout is 30seconds.
   714         This may be a problem with windowmanagers which show a rubber-band rectangle
   714 	This may be a problem with windowmanagers which show a rubber-band rectangle
   715         when creating windows.
   715 	when creating windows.
   716         If the user does not specify the rectangle within 30 seconds, the device assumes
   716 	If the user does not specify the rectangle within 30 seconds, the device assumes
   717         a timeout and closes the connection.
   717 	a timeout and closes the connection.
   718         As a (kludgy) workaround, a second timeout value is used for window-creation.
   718 	As a (kludgy) workaround, a second timeout value is used for window-creation.
   719         This secondary timeout value defaults to 60*5 seconds (5 minutes).
   719 	This secondary timeout value defaults to 60*5 seconds (5 minutes).
   720 
   720 
   721     See more documentation in my superclass, DeviceWorkstation.
   721     See more documentation in my superclass, DeviceWorkstation.
   722 
   722 
   723     [author:]
   723     [author:]
   724         Claus Gittinger
   724 	Claus Gittinger
   725 "
   725 "
   726 ! !
   726 ! !
   727 
   727 
   728 !XWorkstation class methodsFor:'initialization'!
   728 !XWorkstation class methodsFor:'initialization'!
   729 
   729 
  2012 %{
  2012 %{
  2013     int screen = __intVal(__INST(screen));
  2013     int screen = __intVal(__INST(screen));
  2014     Pixmap newBitmap;
  2014     Pixmap newBitmap;
  2015 
  2015 
  2016     if (__bothSmallInteger(w, h) && ISCONNECTED) {
  2016     if (__bothSmallInteger(w, h) && ISCONNECTED) {
  2017         Display *dpy = myDpy;
  2017 	Display *dpy = myDpy;
  2018 
  2018 
  2019 
  2019 
  2020         ENTER_XLIB();
  2020 	ENTER_XLIB();
  2021         newBitmap = XCreatePixmap(dpy, RootWindow(dpy, screen),
  2021 	newBitmap = XCreatePixmap(dpy, RootWindow(dpy, screen),
  2022                                        __intVal(w), __intVal(h), 1);
  2022 				       __intVal(w), __intVal(h), 1);
  2023         LEAVE_XLIB();
  2023 	LEAVE_XLIB();
  2024 #ifdef COUNT_RESOURCES
  2024 #ifdef COUNT_RESOURCES
  2025         if (newBitmap)
  2025 	if (newBitmap)
  2026             __cnt_bitmap++;
  2026 	    __cnt_bitmap++;
  2027 #endif
  2027 #endif
  2028 
  2028 
  2029         RETURN ( (newBitmap != (Pixmap)0) ? __MKEXTERNALADDRESS(newBitmap) : nil );
  2029 	RETURN ( (newBitmap != (Pixmap)0) ? __MKEXTERNALADDRESS(newBitmap) : nil );
  2030     }
  2030     }
  2031 %}.
  2031 %}.
  2032     self primitiveFailedOrClosedConnection.
  2032     self primitiveFailedOrClosedConnection.
  2033     ^ nil
  2033     ^ nil
  2034 !
  2034 !
  2628     unsigned char fastBits[10000];
  2628     unsigned char fastBits[10000];
  2629     OBJ num, *op;
  2629     OBJ num, *op;
  2630     int bytesPerRow;
  2630     int bytesPerRow;
  2631 
  2631 
  2632     if (! ISCONNECTED) {
  2632     if (! ISCONNECTED) {
  2633         RETURN (nil);
  2633 	RETURN (nil);
  2634     }
  2634     }
  2635 
  2635 
  2636     dpy = myDpy;
  2636     dpy = myDpy;
  2637     if (firstCall) {
  2637     if (firstCall) {
  2638         for (index=0; index < 256; index++) {
  2638 	for (index=0; index < 256; index++) {
  2639             int t = 0;
  2639 	    int t = 0;
  2640 
  2640 
  2641             if (index & 128) t |=   1;
  2641 	    if (index & 128) t |=   1;
  2642             if (index &  64) t |=   2;
  2642 	    if (index &  64) t |=   2;
  2643             if (index &  32) t |=   4;
  2643 	    if (index &  32) t |=   4;
  2644             if (index &  16) t |=   8;
  2644 	    if (index &  16) t |=   8;
  2645             if (index &   8) t |=  16;
  2645 	    if (index &   8) t |=  16;
  2646             if (index &   4) t |=  32;
  2646 	    if (index &   4) t |=  32;
  2647             if (index &   2) t |=  64;
  2647 	    if (index &   2) t |=  64;
  2648             if (index &   1) t |= 128;
  2648 	    if (index &   1) t |= 128;
  2649 
  2649 
  2650             reverseBitTable[index] = t;
  2650 	    reverseBitTable[index] = t;
  2651         }
  2651 	}
  2652         firstCall = 0;
  2652 	firstCall = 0;
  2653     }
  2653     }
  2654 
  2654 
  2655     if (__bothSmallInteger(w, h) && _isNonNilObject(anArray)) {
  2655     if (__bothSmallInteger(w, h) && _isNonNilObject(anArray)) {
  2656         newBitmap = (Pixmap)0;
  2656 	newBitmap = (Pixmap)0;
  2657         b_width = __intVal(w);
  2657 	b_width = __intVal(w);
  2658         b_height = __intVal(h);
  2658 	b_height = __intVal(h);
  2659         bytesPerRow = (b_width + 7) / 8;
  2659 	bytesPerRow = (b_width + 7) / 8;
  2660         nBytes = b_height * bytesPerRow;
  2660 	nBytes = b_height * bytesPerRow;
  2661         if (nBytes < sizeof(fastBits)) {
  2661 	if (nBytes < sizeof(fastBits)) {
  2662             cp = b_bits = fastBits;
  2662 	    cp = b_bits = fastBits;
  2663             allocatedBits = 0;
  2663 	    allocatedBits = 0;
  2664         } else {
  2664 	} else {
  2665             cp = b_bits = allocatedBits = (unsigned char *) malloc(nBytes);
  2665 	    cp = b_bits = allocatedBits = (unsigned char *) malloc(nBytes);
  2666             if (! cp) goto fail;
  2666 	    if (! cp) goto fail;
  2667         }
  2667 	}
  2668 
  2668 
  2669         if (__isArrayLike(anArray)) {
  2669 	if (__isArrayLike(anArray)) {
  2670             index = 1;
  2670 	    index = 1;
  2671             op = &(__ArrayInstPtr(anArray)->a_element[index - 1]);
  2671 	    op = &(__ArrayInstPtr(anArray)->a_element[index - 1]);
  2672             for (row = b_height; row; row--) {
  2672 	    for (row = b_height; row; row--) {
  2673                 for (col = bytesPerRow; col; col--) {
  2673 		for (col = bytesPerRow; col; col--) {
  2674                     num = *op++;
  2674 		    num = *op++;
  2675                     if (__isSmallInteger(num)) {
  2675 		    if (__isSmallInteger(num)) {
  2676                         bits = __intVal(num);
  2676 			bits = __intVal(num);
  2677                     } else {
  2677 		    } else {
  2678                         bits = __longIntVal(num);
  2678 			bits = __longIntVal(num);
  2679                         if (bits == 0) {
  2679 			if (bits == 0) {
  2680                             goto fail;
  2680 			    goto fail;
  2681                         }
  2681 			}
  2682                     }
  2682 		    }
  2683                     *cp++ = reverseBitTable[bits & 0xFF];
  2683 		    *cp++ = reverseBitTable[bits & 0xFF];
  2684                 }
  2684 		}
  2685             }
  2685 	    }
  2686         } else {
  2686 	} else {
  2687             if (__isByteArrayLike(anArray)) {
  2687 	    if (__isByteArrayLike(anArray)) {
  2688                 pBits = __ByteArrayInstPtr(anArray)->ba_element;
  2688 		pBits = __ByteArrayInstPtr(anArray)->ba_element;
  2689                 for (col = b_height*bytesPerRow; col; col--) {
  2689 		for (col = b_height*bytesPerRow; col; col--) {
  2690                     *cp++ = reverseBitTable[*pBits++];
  2690 		    *cp++ = reverseBitTable[*pBits++];
  2691                 }
  2691 		}
  2692             } else {
  2692 	    } else {
  2693                 goto fail;
  2693 		goto fail;
  2694             }
  2694 	    }
  2695         }
  2695 	}
  2696 
  2696 
  2697 
  2697 
  2698         ENTER_XLIB();
  2698 	ENTER_XLIB();
  2699         newBitmap = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  2699 	newBitmap = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  2700                                                (char *)b_bits,
  2700 					       (char *)b_bits,
  2701                                                b_width, b_height);
  2701 					       b_width, b_height);
  2702         LEAVE_XLIB();
  2702 	LEAVE_XLIB();
  2703 #ifdef COUNT_RESOURCES
  2703 #ifdef COUNT_RESOURCES
  2704         if (newBitmap)
  2704 	if (newBitmap)
  2705             __cnt_bitmap++;
  2705 	    __cnt_bitmap++;
  2706 #endif
  2706 #endif
  2707 
  2707 
  2708 
  2708 
  2709 fail: ;
  2709 fail: ;
  2710         if (allocatedBits)
  2710 	if (allocatedBits)
  2711             free(allocatedBits);
  2711 	    free(allocatedBits);
  2712         RETURN ( newBitmap ? __MKEXTERNALADDRESS(newBitmap) : nil );
  2712 	RETURN ( newBitmap ? __MKEXTERNALADDRESS(newBitmap) : nil );
  2713     }
  2713     }
  2714 %}.
  2714 %}.
  2715     ^ nil
  2715     ^ nil
  2716 !
  2716 !
  2717 
  2717 
  3411     |msgType dropColl dropCollSize anyFile anyDir anyText anyOther
  3411     |msgType dropColl dropCollSize anyFile anyDir anyText anyOther
  3412      dropType dropTypeCode strings sz idx val|
  3412      dropType dropTypeCode strings sz idx val|
  3413 
  3413 
  3414     (msgType := self atomIDOf:#DndProtocol) notNil ifTrue:[
  3414     (msgType := self atomIDOf:#DndProtocol) notNil ifTrue:[
  3415 
  3415 
  3416         "/ DND can drop files, file, dir, links, dirLink and text
  3416 	"/ DND can drop files, file, dir, links, dirLink and text
  3417         "/ check for this.
  3417 	"/ check for this.
  3418 
  3418 
  3419         dropObjects isCollection ifFalse:[
  3419 	dropObjects isCollection ifFalse:[
  3420             dropColl := Array with:dropObjects
  3420 	    dropColl := Array with:dropObjects
  3421         ] ifTrue:[
  3421 	] ifTrue:[
  3422             dropColl := dropObjects
  3422 	    dropColl := dropObjects
  3423         ].
  3423 	].
  3424         anyFile := anyDir := anyText := anyOther := false.
  3424 	anyFile := anyDir := anyText := anyOther := false.
  3425         dropColl do:[:aDropObject |
  3425 	dropColl do:[:aDropObject |
  3426             aDropObject isFileObject ifTrue:[
  3426 	    aDropObject isFileObject ifTrue:[
  3427                 aDropObject theObject isDirectory ifTrue:[
  3427 		aDropObject theObject isDirectory ifTrue:[
  3428                     anyDir := true
  3428 		    anyDir := true
  3429                 ] ifFalse:[
  3429 		] ifFalse:[
  3430                     anyFile := true
  3430 		    anyFile := true
  3431                 ]
  3431 		]
  3432             ] ifFalse:[
  3432 	    ] ifFalse:[
  3433                 aDropObject isTextObject ifTrue:[
  3433 		aDropObject isTextObject ifTrue:[
  3434                     anyText := true
  3434 		    anyText := true
  3435                 ] ifFalse:[
  3435 		] ifFalse:[
  3436                     anyOther := true
  3436 		    anyOther := true
  3437                 ]
  3437 		]
  3438             ]
  3438 	    ]
  3439         ].
  3439 	].
  3440 
  3440 
  3441         anyOther ifTrue:[
  3441 	anyOther ifTrue:[
  3442             "/ DND does not support this ...
  3442 	    "/ DND does not support this ...
  3443             Logger info:'DND can only drop files or text'.
  3443 	    Logger info:'DND can only drop files or text'.
  3444             ^ false
  3444 	    ^ false
  3445         ].
  3445 	].
  3446         anyText ifTrue:[
  3446 	anyText ifTrue:[
  3447             (anyFile or:[anyDir]) ifTrue:[
  3447 	    (anyFile or:[anyDir]) ifTrue:[
  3448                 "/ DND does not support mixed types
  3448 		"/ DND does not support mixed types
  3449                 Logger info:'DND cannot drop both files and text'.
  3449 		Logger info:'DND cannot drop both files and text'.
  3450                 ^ false
  3450 		^ false
  3451             ]
  3451 	    ]
  3452         ].
  3452 	].
  3453 
  3453 
  3454         dropCollSize := dropColl size.
  3454 	dropCollSize := dropColl size.
  3455         anyFile ifTrue:[
  3455 	anyFile ifTrue:[
  3456             dropType := #DndFiles.
  3456 	    dropType := #DndFiles.
  3457             dropCollSize == 1 ifTrue:[
  3457 	    dropCollSize == 1 ifTrue:[
  3458                 dropType := #DndFile
  3458 		dropType := #DndFile
  3459             ]
  3459 	    ]
  3460         ] ifFalse:[
  3460 	] ifFalse:[
  3461             anyDir ifTrue:[
  3461 	    anyDir ifTrue:[
  3462                 dropType := #DndFiles.
  3462 		dropType := #DndFiles.
  3463                 dropCollSize == 1 ifTrue:[
  3463 		dropCollSize == 1 ifTrue:[
  3464                     dropType := #DndDir
  3464 		    dropType := #DndDir
  3465                 ]
  3465 		]
  3466             ] ifFalse:[
  3466 	    ] ifFalse:[
  3467                 anyText ifTrue:[
  3467 		anyText ifTrue:[
  3468                     dropCollSize == 1 ifTrue:[
  3468 		    dropCollSize == 1 ifTrue:[
  3469                         dropType := #DndText
  3469 			dropType := #DndText
  3470                     ] ifFalse:[
  3470 		    ] ifFalse:[
  3471                         "/ can only drop a single text object
  3471 			"/ can only drop a single text object
  3472                         Logger info:'DND can only drop a single text'.
  3472 			Logger info:'DND can only drop a single text'.
  3473                         ^ false
  3473 			^ false
  3474                     ]
  3474 		    ]
  3475                 ] ifFalse:[
  3475 		] ifFalse:[
  3476                     "/ mhmh ...
  3476 		    "/ mhmh ...
  3477                     Logger info:'DND cannot drop this'.
  3477 		    Logger info:'DND cannot drop this'.
  3478                     ^ false
  3478 		    ^ false
  3479                 ]
  3479 		]
  3480             ]
  3480 	    ]
  3481         ].
  3481 	].
  3482 
  3482 
  3483         dropTypeCode := self dndDropTypes indexOf:dropType.
  3483 	dropTypeCode := self dndDropTypes indexOf:dropType.
  3484         dropTypeCode == 0 ifTrue:[
  3484 	dropTypeCode == 0 ifTrue:[
  3485             Logger info:'DND cannot drop this'.
  3485 	    Logger info:'DND cannot drop this'.
  3486             ^ false
  3486 	    ^ false
  3487         ].
  3487 	].
  3488         dropTypeCode := dropTypeCode - 1.
  3488 	dropTypeCode := dropTypeCode - 1.
  3489 
  3489 
  3490 
  3490 
  3491         "/ place the selection inTo the DndSelection property
  3491 	"/ place the selection inTo the DndSelection property
  3492         "/ of the rootView ...
  3492 	"/ of the rootView ...
  3493         "/ ... need a single string, with 0-terminated parts.
  3493 	"/ ... need a single string, with 0-terminated parts.
  3494 
  3494 
  3495         strings := OrderedCollection new.
  3495 	strings := OrderedCollection new.
  3496         sz := 0.
  3496 	sz := 0.
  3497         dropColl do:[:anObject |
  3497 	dropColl do:[:anObject |
  3498             |s o|
  3498 	    |s o|
  3499 
  3499 
  3500             o := anObject theObject.
  3500 	    o := anObject theObject.
  3501             anObject isFileObject ifTrue:[
  3501 	    anObject isFileObject ifTrue:[
  3502                 o := o pathName
  3502 		o := o pathName
  3503             ].
  3503 	    ].
  3504             s := o asString.
  3504 	    s := o asString.
  3505             strings add:s.
  3505 	    strings add:s.
  3506             sz := sz + (s size) + 1.
  3506 	    sz := sz + (s size) + 1.
  3507         ].
  3507 	].
  3508         val := String new:sz.
  3508 	val := String new:sz.
  3509         idx := 1.
  3509 	idx := 1.
  3510         strings do:[:aString |
  3510 	strings do:[:aString |
  3511             |sz|
  3511 	    |sz|
  3512 
  3512 
  3513             sz := aString size.
  3513 	    sz := aString size.
  3514             val replaceFrom:idx to:(idx + sz - 1) with:aString startingAt:1.
  3514 	    val replaceFrom:idx to:(idx + sz - 1) with:aString startingAt:1.
  3515             idx := idx + sz.
  3515 	    idx := idx + sz.
  3516             val at:idx put:(Character value:0).
  3516 	    val at:idx put:(Character value:0).
  3517             idx := idx + 1
  3517 	    idx := idx + 1
  3518         ].
  3518 	].
  3519 
  3519 
  3520         self
  3520 	self
  3521             setProperty:(self atomIDOf:#DndSelection)
  3521 	    setProperty:(self atomIDOf:#DndSelection)
  3522             type:(self atomIDOf:#STRING)
  3522 	    type:(self atomIDOf:#STRING)
  3523             value:val
  3523 	    value:val
  3524             for:rootId.
  3524 	    for:rootId.
  3525 
  3525 
  3526         ^ self
  3526 	^ self
  3527             sendClientEvent:msgType
  3527 	    sendClientEvent:msgType
  3528             format:32
  3528 	    format:32
  3529             to:destinationId
  3529 	    to:destinationId
  3530             propagate:true
  3530 	    propagate:true
  3531             eventMask:nil
  3531 	    eventMask:nil
  3532             window:destinationId
  3532 	    window:destinationId
  3533             data1:dropTypeCode
  3533 	    data1:dropTypeCode
  3534             data2:0
  3534 	    data2:0
  3535             data3:destinationId
  3535 	    data3:destinationId
  3536             data4:nil
  3536 	    data4:nil
  3537             data5:nil.
  3537 	    data5:nil.
  3538     ].
  3538     ].
  3539 
  3539 
  3540     ^ false
  3540     ^ false
  3541 
  3541 
  3542     "Created: 6.4.1997 / 13:39:37 / cg"
  3542     "Created: 6.4.1997 / 13:39:37 / cg"
  3589     "clear (fill with background) a rectangle. If any coordinate is not integer, an error is triggered."
  3589     "clear (fill with background) a rectangle. If any coordinate is not integer, an error is triggered."
  3590 
  3590 
  3591     <context: #return>
  3591     <context: #return>
  3592 
  3592 
  3593     operationsUntilFlush notNil ifTrue:[
  3593     operationsUntilFlush notNil ifTrue:[
  3594         operationsUntilFlush <= 0 ifTrue:[
  3594 	operationsUntilFlush <= 0 ifTrue:[
  3595             self flush.
  3595 	    self flush.
  3596         ] ifFalse:[
  3596 	] ifFalse:[
  3597             operationsUntilFlush := operationsUntilFlush - 1.
  3597 	    operationsUntilFlush := operationsUntilFlush - 1.
  3598         ].
  3598 	].
  3599     ].
  3599     ].
  3600 %{
  3600 %{
  3601 
  3601 
  3602     int w, h;
  3602     int w, h;
  3603 
  3603 
  3604     if (ISCONNECTED
  3604     if (ISCONNECTED
  3605      && __isExternalAddress(aDrawableId)
  3605      && __isExternalAddress(aDrawableId)
  3606      && __bothSmallInteger(x, y)
  3606      && __bothSmallInteger(x, y)
  3607      && __bothSmallInteger(width, height)) {
  3607      && __bothSmallInteger(width, height)) {
  3608         w = __intVal(width);
  3608 	w = __intVal(width);
  3609         h = __intVal(height);
  3609 	h = __intVal(height);
  3610         /*
  3610 	/*
  3611          * need this check here: some servers simply dump core with bad args
  3611 	 * need this check here: some servers simply dump core with bad args
  3612          */
  3612 	 */
  3613         if ((w >= 0) && (h >= 0)) {
  3613 	if ((w >= 0) && (h >= 0)) {
  3614             ENTER_XLIB();
  3614 	    ENTER_XLIB();
  3615             XClearArea(myDpy,
  3615 	    XClearArea(myDpy,
  3616                            __DrawableVal(aDrawableId),
  3616 			   __DrawableVal(aDrawableId),
  3617                            __intVal(x), __intVal(y), w, h, 0);
  3617 			   __intVal(x), __intVal(y), w, h, 0);
  3618             LEAVE_XLIB();
  3618 	    LEAVE_XLIB();
  3619         }
  3619 	}
  3620         RETURN ( self );
  3620 	RETURN ( self );
  3621     }
  3621     }
  3622 %}.
  3622 %}.
  3623     "badGC, badDrawable or coordinates not integer"
  3623     "badGC, badDrawable or coordinates not integer"
  3624     self primitiveFailedOrClosedConnection
  3624     self primitiveFailedOrClosedConnection
  3625 !
  3625 !
  5241 
  5241 
  5242     "/ see def's in DragAndDropTypes.h
  5242     "/ see def's in DragAndDropTypes.h
  5243     dropType := (self dndDropTypes) at:dropType+1 ifAbsent:#DndNotDnd.
  5243     dropType := (self dndDropTypes) at:dropType+1 ifAbsent:#DndNotDnd.
  5244 
  5244 
  5245     property := self
  5245     property := self
  5246         getProperty:(self atomIDOf:#DndSelection)
  5246 	getProperty:(self atomIDOf:#DndSelection)
  5247         from:rootId
  5247 	from:rootId
  5248         delete:false.
  5248 	delete:false.
  5249 
  5249 
  5250     propertyType := property key.
  5250     propertyType := property key.
  5251     dropValue := property value.
  5251     dropValue := property value.
  5252 
  5252 
  5253     "/ preconvert into a collection
  5253     "/ preconvert into a collection
  5257     "/ redefined dropMessage methods in applications.
  5257     "/ redefined dropMessage methods in applications.
  5258     "/ Conversion is done for some well known types
  5258     "/ Conversion is done for some well known types
  5259     "/ in the default dropMessage handling of SimpleView.
  5259     "/ in the default dropMessage handling of SimpleView.
  5260 
  5260 
  5261     dropType == #DndFiles ifTrue:[
  5261     dropType == #DndFiles ifTrue:[
  5262         "/ actually, a list of fileNames
  5262 	"/ actually, a list of fileNames
  5263         propertyType ~~ stringAtom ifTrue:[
  5263 	propertyType ~~ stringAtom ifTrue:[
  5264             Logger info:'expected a string propertyValue in drop'.
  5264 	    Logger info:'expected a string propertyValue in drop'.
  5265             ^ self
  5265 	    ^ self
  5266         ].
  5266 	].
  5267 
  5267 
  5268         names := OrderedCollection new.
  5268 	names := OrderedCollection new.
  5269         i1 := 1.
  5269 	i1 := 1.
  5270         [i1 ~~ 0] whileTrue:[
  5270 	[i1 ~~ 0] whileTrue:[
  5271             i2 := dropValue indexOf:(Character value:0) startingAt:i1.
  5271 	    i2 := dropValue indexOf:(Character value:0) startingAt:i1.
  5272             i2 ~~ 0 ifTrue:[
  5272 	    i2 ~~ 0 ifTrue:[
  5273                 names add:(dropValue copyFrom:i1 to:(i2-1)).
  5273 		names add:(dropValue copyFrom:i1 to:(i2-1)).
  5274                 i1 := i2 + 1.
  5274 		i1 := i2 + 1.
  5275             ] ifFalse:[
  5275 	    ] ifFalse:[
  5276                 i1 := i2
  5276 		i1 := i2
  5277             ].
  5277 	    ].
  5278         ].
  5278 	].
  5279         dropValue := names.
  5279 	dropValue := names.
  5280         dropValue := dropValue collect:[:nm | nm asFilename].
  5280 	dropValue := dropValue collect:[:nm | nm asFilename].
  5281         dropType := #files.
  5281 	dropType := #files.
  5282     ] ifFalse:[ (dropType == #DndFile) ifTrue:[
  5282     ] ifFalse:[ (dropType == #DndFile) ifTrue:[
  5283         propertyType ~~ stringAtom ifTrue:[
  5283 	propertyType ~~ stringAtom ifTrue:[
  5284             Logger info:'expected a string propertyValue in drop'.
  5284 	    Logger info:'expected a string propertyValue in drop'.
  5285             ^ self
  5285 	    ^ self
  5286         ].
  5286 	].
  5287         dropValue := dropValue asFilename.
  5287 	dropValue := dropValue asFilename.
  5288         dropType := #file.
  5288 	dropType := #file.
  5289     ] ifFalse:[ (dropType == #DndDir) ifTrue:[
  5289     ] ifFalse:[ (dropType == #DndDir) ifTrue:[
  5290         propertyType ~~ stringAtom ifTrue:[
  5290 	propertyType ~~ stringAtom ifTrue:[
  5291             Logger info:'expected a string propertyValue in drop'.
  5291 	    Logger info:'expected a string propertyValue in drop'.
  5292             ^ self
  5292 	    ^ self
  5293         ].
  5293 	].
  5294         dropValue := dropValue asFilename.
  5294 	dropValue := dropValue asFilename.
  5295         dropType := #directory.
  5295 	dropType := #directory.
  5296     ] ifFalse:[ (dropType == #DndText) ifTrue:[
  5296     ] ifFalse:[ (dropType == #DndText) ifTrue:[
  5297         propertyType ~~ stringAtom ifTrue:[
  5297 	propertyType ~~ stringAtom ifTrue:[
  5298             Logger info:'expected a string propertyValue in drop'.
  5298 	    Logger info:'expected a string propertyValue in drop'.
  5299             ^ self
  5299 	    ^ self
  5300         ].
  5300 	].
  5301         dropType := #text.
  5301 	dropType := #text.
  5302     ] ifFalse:[ (dropType == #DndExe) ifTrue:[
  5302     ] ifFalse:[ (dropType == #DndExe) ifTrue:[
  5303         propertyType ~~ stringAtom ifTrue:[
  5303 	propertyType ~~ stringAtom ifTrue:[
  5304             Logger info:'expected a string propertyValue in drop'.
  5304 	    Logger info:'expected a string propertyValue in drop'.
  5305             ^ self
  5305 	    ^ self
  5306         ].
  5306 	].
  5307         dropType := #executable.
  5307 	dropType := #executable.
  5308     ] ifFalse:[ (dropType == #DndLink) ifTrue:[
  5308     ] ifFalse:[ (dropType == #DndLink) ifTrue:[
  5309         propertyType ~~ stringAtom ifTrue:[
  5309 	propertyType ~~ stringAtom ifTrue:[
  5310             Logger info:'expected a string propertyValue in drop'.
  5310 	    Logger info:'expected a string propertyValue in drop'.
  5311             ^ self
  5311 	    ^ self
  5312         ].
  5312 	].
  5313         dropType := #link.
  5313 	dropType := #link.
  5314     ] ifFalse:[ (dropType == #DndRawData) ifTrue:[
  5314     ] ifFalse:[ (dropType == #DndRawData) ifTrue:[
  5315         dropType := #rawData.
  5315 	dropType := #rawData.
  5316     ] ifFalse:[
  5316     ] ifFalse:[
  5317         Logger info:'unsupported dropType: %1 data: %2 ' with:dropType with:dropValue.
  5317 	Logger info:'unsupported dropType: %1 data: %2 ' with:dropType with:dropValue.
  5318         dropType := #unknown.
  5318 	dropType := #unknown.
  5319     ]]]]]]].
  5319     ]]]]]]].
  5320 
  5320 
  5321     sensor := targetView sensor.
  5321     sensor := targetView sensor.
  5322     "not posted, if there is no sensor ..."
  5322     "not posted, if there is no sensor ..."
  5323     sensor notNil ifTrue:[
  5323     sensor notNil ifTrue:[
  5324         sensor dropMessage:dropType data:dropValue view:targetView position:nil handle:nil
  5324 	sensor dropMessage:dropType data:dropValue view:targetView position:nil handle:nil
  5325     ].
  5325     ].
  5326 
  5326 
  5327     "Created: 4.4.1997 / 17:59:37 / cg"
  5327     "Created: 4.4.1997 / 17:59:37 / cg"
  5328 !
  5328 !
  5329 
  5329 
 11292      in advance, since the X-server is free to return whatever it thinks is a good padding."
 11292      in advance, since the X-server is free to return whatever it thinks is a good padding."
 11293 
 11293 
 11294     |rawInfo info|
 11294     |rawInfo info|
 11295 
 11295 
 11296     ((w <= 0) or:[h <= 0]) ifTrue:[
 11296     ((w <= 0) or:[h <= 0]) ifTrue:[
 11297         self primitiveFailed.
 11297 	self primitiveFailed.
 11298         ^ nil
 11298 	^ nil
 11299     ].
 11299     ].
 11300 
 11300 
 11301     rawInfo := Array new:8.
 11301     rawInfo := Array new:8.
 11302                   "1 -> bit order"
 11302 		  "1 -> bit order"
 11303                   "2 -> depth"
 11303 		  "2 -> depth"
 11304                   "3 -> bytes_per_line"
 11304 		  "3 -> bytes_per_line"
 11305                   "4 -> byte_order"
 11305 		  "4 -> byte_order"
 11306                   "5 -> format"
 11306 		  "5 -> format"
 11307                   "6 -> bitmap_unit"
 11307 		  "6 -> bitmap_unit"
 11308                   "7 -> bitmap_pad"
 11308 		  "7 -> bitmap_pad"
 11309                   "8 -> bits_per_pixel"
 11309 		  "8 -> bits_per_pixel"
 11310 
 11310 
 11311     "/ had to extract the getPixel call into a separate method, to specify
 11311     "/ had to extract the getPixel call into a separate method, to specify
 11312     "/ unlimitedStack (some implementations use alloca and require huge amounts
 11312     "/ unlimitedStack (some implementations use alloca and require huge amounts
 11313     "/ of temporary stack space
 11313     "/ of temporary stack space
 11314 
 11314 
 11315     (self primGetBitsFrom:aDrawableId x:srcx y:srcy width:w height:h into:imageBits infoInto:rawInfo) ifTrue:[
 11315     (self primGetBitsFrom:aDrawableId x:srcx y:srcy width:w height:h into:imageBits infoInto:rawInfo) ifTrue:[
 11316         info := IdentityDictionary new.
 11316 	info := IdentityDictionary new.
 11317         info at:#bitOrder put:(rawInfo at:1).
 11317 	info at:#bitOrder put:(rawInfo at:1).
 11318         info at:#depth put:(rawInfo at:2).
 11318 	info at:#depth put:(rawInfo at:2).
 11319         info at:#bytesPerLine put:(rawInfo at:3).
 11319 	info at:#bytesPerLine put:(rawInfo at:3).
 11320         info at:#byteOrder put:(rawInfo at:4).
 11320 	info at:#byteOrder put:(rawInfo at:4).
 11321         info at:#format put:(rawInfo at:5).
 11321 	info at:#format put:(rawInfo at:5).
 11322         info at:#bitmapUnit put:(rawInfo at:6).
 11322 	info at:#bitmapUnit put:(rawInfo at:6).
 11323         info at:#bitmapPad put:(rawInfo at:7).
 11323 	info at:#bitmapPad put:(rawInfo at:7).
 11324         info at:#bitsPerPixel put:(rawInfo at:8).
 11324 	info at:#bitsPerPixel put:(rawInfo at:8).
 11325         ^ info
 11325 	^ info
 11326     ].
 11326     ].
 11327     "
 11327     "
 11328      some error occurred - either args are not smallintegers, imageBits is not a ByteArray
 11328      some error occurred - either args are not smallintegers, imageBits is not a ByteArray
 11329      or is too small to hold the bits
 11329      or is too small to hold the bits
 11330     "
 11330     "
 11586     |buffer bufferAsString|
 11586     |buffer bufferAsString|
 11587 
 11587 
 11588     buffer := self perform:bufferGetSelector.
 11588     buffer := self perform:bufferGetSelector.
 11589 
 11589 
 11590     (aTargetAtomID == (self atomIDOf:#'ST_OBJECT')) ifTrue:[
 11590     (aTargetAtomID == (self atomIDOf:#'ST_OBJECT')) ifTrue:[
 11591         "/ 'st-object' printCR.
 11591 	"/ 'st-object' printCR.
 11592         "send the selection in binaryStore format"
 11592 	"send the selection in binaryStore format"
 11593         "require libboss to be loaded"
 11593 	"require libboss to be loaded"
 11594         (Smalltalk isClassLibraryLoaded:'libstx_libboss') ifFalse:[
 11594 	(Smalltalk isClassLibraryLoaded:'libstx_libboss') ifFalse:[
 11595             Logger error:'cannot use binary store for copy buffer (libboss missing)'.
 11595 	    Logger error:'cannot use binary store for copy buffer (libboss missing)'.
 11596             ^ nil -> nil.
 11596 	    ^ nil -> nil.
 11597         ].
 11597 	].
 11598 
 11598 
 11599         [
 11599 	[
 11600             ^ aTargetAtomID -> (buffer binaryStoreBytes).
 11600 	    ^ aTargetAtomID -> (buffer binaryStoreBytes).
 11601         ] on:Error do:[:ex|
 11601 	] on:Error do:[:ex|
 11602             Logger info:'error on binary store of copy buffer: %1' with: ex description.
 11602 	    Logger info:'error on binary store of copy buffer: %1' with: ex description.
 11603             ^ nil -> nil.
 11603 	    ^ nil -> nil.
 11604         ].
 11604 	].
 11605     ].
 11605     ].
 11606 
 11606 
 11607     bufferAsString := self class bufferAsString:buffer.
 11607     bufferAsString := self class bufferAsString:buffer.
 11608 
 11608 
 11609     (aTargetAtomID == (self atomIDOf:#STRING)
 11609     (aTargetAtomID == (self atomIDOf:#STRING)
 11610      or:[aTargetAtomID == (self atomIDOf:#'text/plain')]
 11610      or:[aTargetAtomID == (self atomIDOf:#'text/plain')]
 11611     ) ifTrue:[
 11611     ) ifTrue:[
 11612         "/ 'string' printCR.
 11612 	"/ 'string' printCR.
 11613         "the other view wants the selection as string"
 11613 	"the other view wants the selection as string"
 11614         ^ aTargetAtomID -> (bufferAsString asSingleByteStringReplaceInvalidWith:$#).
 11614 	^ aTargetAtomID -> (bufferAsString asSingleByteStringReplaceInvalidWith:$#).
 11615     ].
 11615     ].
 11616 
 11616 
 11617     (aTargetAtomID == (self atomIDOf:#UTF8_STRING)
 11617     (aTargetAtomID == (self atomIDOf:#UTF8_STRING)
 11618      or:[aTargetAtomID == (self atomIDOf:#'text/plain;codeset=utf-8')]
 11618      or:[aTargetAtomID == (self atomIDOf:#'text/plain;codeset=utf-8')]
 11619     ) ifTrue:[
 11619     ) ifTrue:[
 11620         "/ 'utf string' printCR.
 11620 	"/ 'utf string' printCR.
 11621         "the other view wants the selection as utf8 string"
 11621 	"the other view wants the selection as utf8 string"
 11622         ^ aTargetAtomID -> (bufferAsString utf8Encoded).
 11622 	^ aTargetAtomID -> (bufferAsString utf8Encoded).
 11623     ].
 11623     ].
 11624 
 11624 
 11625     aTargetAtomID == (self atomIDOf:#LENGTH) ifTrue:[
 11625     aTargetAtomID == (self atomIDOf:#LENGTH) ifTrue:[
 11626         "the other one wants to know the size of our selection.
 11626 	"the other one wants to know the size of our selection.
 11627          LENGTH is deprecated, since we do not know how the selection is
 11627 	 LENGTH is deprecated, since we do not know how the selection is
 11628          going to be converted. The client must not rely on the length returned"
 11628 	 going to be converted. The client must not rely on the length returned"
 11629 
 11629 
 11630         ^ (self atomIDOf:#INTEGER) -> (bufferAsString size).
 11630 	^ (self atomIDOf:#INTEGER) -> (bufferAsString size).
 11631     ].
 11631     ].
 11632 
 11632 
 11633     "we do not support the requestet target type"
 11633     "we do not support the requestet target type"
 11634     ^ nil -> nil.
 11634     ^ nil -> nil.
 11635 
 11635 
 13810     id := xftDrawId.
 13810     id := xftDrawId.
 13811     xftDrawId := nil.
 13811     xftDrawId := nil.
 13812 %{
 13812 %{
 13813 #ifdef XFT
 13813 #ifdef XFT
 13814     if (__isExternalAddress(id)) {
 13814     if (__isExternalAddress(id)) {
 13815         XftDraw *address = (XftDraw *)__externalAddressVal(id);
 13815 	XftDraw *address = (XftDraw *)__externalAddressVal(id);
 13816         if (address) {
 13816 	if (address) {
 13817             XftDrawDestroy(address);
 13817 	    XftDrawDestroy(address);
 13818             __externalAddressVal(id) = 0;
 13818 	    __externalAddressVal(id) = 0;
 13819         }
 13819 	}
 13820     }
 13820     }
 13821 #endif
 13821 #endif
 13822 %}.
 13822 %}.
 13823 ! !
 13823 ! !
 13824 
 13824 
 13832     <context: #return>
 13832     <context: #return>
 13833 
 13833 
 13834     |displayId|
 13834     |displayId|
 13835 
 13835 
 13836     font isXftFont ifTrue:[
 13836     font isXftFont ifTrue:[
 13837         self displayDeviceXftString:aString from:index1 to:index2 x:x y:y opaque:opaque.
 13837 	self displayDeviceXftString:aString from:index1 to:index2 x:x y:y opaque:opaque.
 13838         ^ self.
 13838 	^ self.
 13839     ].
 13839     ].
 13840 
 13840 
 13841     device flushIfAppropriate.
 13841     device flushIfAppropriate.
 13842     displayId := device displayIdOrErrorIfBroken.
 13842     displayId := device displayIdOrErrorIfBroken.
 13843 
 13843 
 13854      && __isExternalAddress(__INST(gcId))
 13854      && __isExternalAddress(__INST(gcId))
 13855      && __isExternalAddress(__INST(drawableId))
 13855      && __isExternalAddress(__INST(drawableId))
 13856      && __isNonNilObject(aString)
 13856      && __isNonNilObject(aString)
 13857      && __bothSmallInteger(index1, index2)
 13857      && __bothSmallInteger(index1, index2)
 13858      && __bothSmallInteger(x, y)) {
 13858      && __bothSmallInteger(x, y)) {
 13859         int lMax = __intVal(@global(XWorkstation:MaxStringLength));
 13859 	int lMax = __intVal(@global(XWorkstation:MaxStringLength));
 13860         Display *dpy = __DisplayVal(displayId);
 13860 	Display *dpy = __DisplayVal(displayId);
 13861         gc = __GCVal(__INST(gcId));
 13861 	gc = __GCVal(__INST(gcId));
 13862         win = __WindowVal(__INST(drawableId));
 13862 	win = __WindowVal(__INST(drawableId));
 13863 
 13863 
 13864         i1 = __intVal(index1) - 1;
 13864 	i1 = __intVal(index1) - 1;
 13865         if (i1 >= 0) {
 13865 	if (i1 >= 0) {
 13866             OBJ cls;
 13866 	    OBJ cls;
 13867 
 13867 
 13868             i2 = __intVal(index2) - 1;
 13868 	    i2 = __intVal(index2) - 1;
 13869             if (i2 < i1) {
 13869 	    if (i2 < i1) {
 13870                 RETURN (self);
 13870 		RETURN (self);
 13871             }
 13871 	    }
 13872             cp = (char *) __stringVal(aString);
 13872 	    cp = (char *) __stringVal(aString);
 13873             l = i2 - i1 + 1;
 13873 	    l = i2 - i1 + 1;
 13874 
 13874 
 13875             if (__isStringLike(aString)) {
 13875 	    if (__isStringLike(aString)) {
 13876                 n = __stringSize(aString);
 13876 		n = __stringSize(aString);
 13877                 if (i2 < n) {
 13877 		if (i2 < n) {
 13878                     cp += i1;
 13878 		    cp += i1;
 13879                     if (l > lMax) l = lMax;
 13879 		    if (l > lMax) l = lMax;
 13880                     __ENTER_XLIB(1000 * __intVal(@global(XWorkstation:DefaultXLibTimeout)));
 13880 		    __ENTER_XLIB(1000 * __intVal(@global(XWorkstation:DefaultXLibTimeout)));
 13881                     if (opaque == true)
 13881 		    if (opaque == true)
 13882                         XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
 13882 			XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
 13883                     else
 13883 		    else
 13884                         XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
 13884 			XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
 13885                     LEAVE_XLIB();
 13885 		    LEAVE_XLIB();
 13886                     RETURN ( self );
 13886 		    RETURN ( self );
 13887                 }
 13887 		}
 13888             }
 13888 	    }
 13889 
 13889 
 13890             cls = __qClass(aString);
 13890 	    cls = __qClass(aString);
 13891             nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
 13891 	    nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
 13892             cp += nInstBytes;
 13892 	    cp += nInstBytes;
 13893 
 13893 
 13894             if (__isBytes(aString)) {
 13894 	    if (__isBytes(aString)) {
 13895                 n = __byteArraySize(aString) - nInstBytes - 1;
 13895 		n = __byteArraySize(aString) - nInstBytes - 1;
 13896 
 13896 
 13897                 if (i2 < n) {
 13897 		if (i2 < n) {
 13898                     cp += i1;
 13898 		    cp += i1;
 13899                     if (l > lMax) l = lMax;
 13899 		    if (l > lMax) l = lMax;
 13900                     __ENTER_XLIB(1000 * __intVal(@global(XWorkstation:DefaultXLibTimeout)));
 13900 		    __ENTER_XLIB(1000 * __intVal(@global(XWorkstation:DefaultXLibTimeout)));
 13901                     if (opaque == true)
 13901 		    if (opaque == true)
 13902                         XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
 13902 			XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
 13903                     else
 13903 		    else
 13904                         XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
 13904 			XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
 13905                     LEAVE_XLIB();
 13905 		    LEAVE_XLIB();
 13906                     RETURN ( self );
 13906 		    RETURN ( self );
 13907                 }
 13907 		}
 13908             }
 13908 	    }
 13909 
 13909 
 13910             /* TWOBYTESTRINGS */
 13910 	    /* TWOBYTESTRINGS */
 13911             if (__isWords(aString)) {
 13911 	    if (__isWords(aString)) {
 13912                 n = (__byteArraySize(aString) - nInstBytes) / 2;
 13912 		n = (__byteArraySize(aString) - nInstBytes) / 2;
 13913                 if (i2 < n) {
 13913 		if (i2 < n) {
 13914                     union {
 13914 		    union {
 13915                         char b[2];
 13915 			char b[2];
 13916                         unsigned short s;
 13916 			unsigned short s;
 13917                     } u;
 13917 		    } u;
 13918                     int i;
 13918 		    int i;
 13919                     XChar2b *cp2 = (XChar2b *)0;
 13919 		    XChar2b *cp2 = (XChar2b *)0;
 13920                     int mustFree = 0;
 13920 		    int mustFree = 0;
 13921 
 13921 
 13922                     cp += (i1 * 2);
 13922 		    cp += (i1 * 2);
 13923                     if (l > lMax) l = lMax;
 13923 		    if (l > lMax) l = lMax;
 13924 
 13924 
 13925 #if defined(MSBFIRST) || defined(__MSBFIRST)
 13925 #if defined(MSBFIRST) || defined(__MSBFIRST)
 13926                     /*
 13926 		    /*
 13927                      * chars already in correct order
 13927 		     * chars already in correct order
 13928                      */
 13928 		     */
 13929 #else
 13929 #else
 13930 # if ! (defined(LSBFIRST) || defined(__LSBFIRST))
 13930 # if ! (defined(LSBFIRST) || defined(__LSBFIRST))
 13931                     /*
 13931 		    /*
 13932                      * ST/X TwoByteStrings store the asciiValue in native byteOrder;
 13932 		     * ST/X TwoByteStrings store the asciiValue in native byteOrder;
 13933                      * X expects them MSB first
 13933 		     * X expects them MSB first
 13934                      * convert as required
 13934 		     * convert as required
 13935                      */
 13935 		     */
 13936                     u.s = 0x1234;
 13936 		    u.s = 0x1234;
 13937                     if (u.b[0] != 0x12)
 13937 		    if (u.b[0] != 0x12)
 13938 # endif  // ! (defined(LSBFIRST) || defined(__LSBFIRST)) 
 13938 # endif  // ! (defined(LSBFIRST) || defined(__LSBFIRST))
 13939                     {
 13939 		    {
 13940                         if (l <= NLOCALBUFFER) {
 13940 			if (l <= NLOCALBUFFER) {
 13941                             cp2 = xlatebuffer;
 13941 			    cp2 = xlatebuffer;
 13942                         } else {
 13942 			} else {
 13943                             cp2 = (XChar2b *)(malloc(l * 2));
 13943 			    cp2 = (XChar2b *)(malloc(l * 2));
 13944                             mustFree = 1;
 13944 			    mustFree = 1;
 13945                         }
 13945 			}
 13946                         for (i=0; i<l; i++) {
 13946 			for (i=0; i<l; i++) {
 13947                             cp2[i].byte1 = (((XChar2b *)cp)[i]).byte2;
 13947 			    cp2[i].byte1 = (((XChar2b *)cp)[i]).byte2;
 13948                             cp2[i].byte2 = (((XChar2b *)cp)[i]).byte1;
 13948 			    cp2[i].byte2 = (((XChar2b *)cp)[i]).byte1;
 13949                         }
 13949 			}
 13950                         cp = (char *) cp2;
 13950 			cp = (char *) cp2;
 13951                     }
 13951 		    }
 13952 #endif  // ! (defined(MSBFIRST) || defined(__MSBFIRST)) 
 13952 #endif  // ! (defined(MSBFIRST) || defined(__MSBFIRST))
 13953                     __ENTER_XLIB(1000 * __intVal(@global(XWorkstation:DefaultXLibTimeout)));
 13953 		    __ENTER_XLIB(1000 * __intVal(@global(XWorkstation:DefaultXLibTimeout)));
 13954                     if (opaque == true)
 13954 		    if (opaque == true)
 13955                         XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
 13955 			XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
 13956                     else
 13956 		    else
 13957                         XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
 13957 			XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
 13958                     LEAVE_XLIB();
 13958 		    LEAVE_XLIB();
 13959 
 13959 
 13960                     if (mustFree) {
 13960 		    if (mustFree) {
 13961                         free(cp2);
 13961 			free(cp2);
 13962                     }
 13962 		    }
 13963 
 13963 
 13964                     RETURN ( self );
 13964 		    RETURN ( self );
 13965                 }
 13965 		}
 13966             }
 13966 	    }
 13967 
 13967 
 13968             /* FOURBYTESTRINGS */
 13968 	    /* FOURBYTESTRINGS */
 13969             if (__isLongs(aString)) {
 13969 	    if (__isLongs(aString)) {
 13970                 n = (__byteArraySize(aString) - nInstBytes) / 4;
 13970 		n = (__byteArraySize(aString) - nInstBytes) / 4;
 13971                 if (i2 < n) {
 13971 		if (i2 < n) {
 13972                     union {
 13972 		    union {
 13973                         char b[2];
 13973 			char b[2];
 13974                         unsigned short s;
 13974 			unsigned short s;
 13975                     } u;
 13975 		    } u;
 13976                     int i;
 13976 		    int i;
 13977                     XChar2b *cp2 = (XChar2b *)0;
 13977 		    XChar2b *cp2 = (XChar2b *)0;
 13978                     int32 *ip;
 13978 		    int32 *ip;
 13979                     int mustFree = 0;
 13979 		    int mustFree = 0;
 13980 
 13980 
 13981                     cp += (i1 * 4);
 13981 		    cp += (i1 * 4);
 13982                     if (l > lMax) l = lMax;
 13982 		    if (l > lMax) l = lMax;
 13983 
 13983 
 13984                     /*
 13984 		    /*
 13985                      * all codePoints <= 16rFFFF are draw; above 16bit range are drawn as 16rFFFF.
 13985 		     * all codePoints <= 16rFFFF are draw; above 16bit range are drawn as 16rFFFF.
 13986                      */
 13986 		     */
 13987                     if (l <= NLOCALBUFFER) {
 13987 		    if (l <= NLOCALBUFFER) {
 13988                         cp2 = xlatebuffer;
 13988 			cp2 = xlatebuffer;
 13989                     } else {
 13989 		    } else {
 13990                         cp2 = (XChar2b *)(malloc(l * 2));
 13990 			cp2 = (XChar2b *)(malloc(l * 2));
 13991                         mustFree = 1;
 13991 			mustFree = 1;
 13992                     }
 13992 		    }
 13993                     for (i=0; i<l; i++) {
 13993 		    for (i=0; i<l; i++) {
 13994                         int32 codePoint = ((int32 *)cp)[i];
 13994 			int32 codePoint = ((int32 *)cp)[i];
 13995 
 13995 
 13996                         if (codePoint > 0xFFFF) {
 13996 			if (codePoint > 0xFFFF) {
 13997                             codePoint = 0xFFFF;
 13997 			    codePoint = 0xFFFF;
 13998                         }
 13998 			}
 13999                         cp2[i].byte1 = (codePoint >> 8) & 0xFF;
 13999 			cp2[i].byte1 = (codePoint >> 8) & 0xFF;
 14000                         cp2[i].byte2 = codePoint & 0xFF;
 14000 			cp2[i].byte2 = codePoint & 0xFF;
 14001                     }
 14001 		    }
 14002 
 14002 
 14003                     __ENTER_XLIB(1000 * __intVal(@global(XWorkstation:DefaultXLibTimeout)));
 14003 		    __ENTER_XLIB(1000 * __intVal(@global(XWorkstation:DefaultXLibTimeout)));
 14004                     if (opaque == true)
 14004 		    if (opaque == true)
 14005                         XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp2, l);
 14005 			XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp2, l);
 14006                     else
 14006 		    else
 14007                         XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp2, l);
 14007 			XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp2, l);
 14008                     LEAVE_XLIB();
 14008 		    LEAVE_XLIB();
 14009 
 14009 
 14010                     if (mustFree) {
 14010 		    if (mustFree) {
 14011                         free(cp2);
 14011 			free(cp2);
 14012                     }
 14012 		    }
 14013 
 14013 
 14014                     RETURN ( self );
 14014 		    RETURN ( self );
 14015                 }
 14015 		}
 14016             }
 14016 	    }
 14017         }
 14017 	}
 14018     }
 14018     }
 14019 #undef NLOCALBUFFER
 14019 #undef NLOCALBUFFER
 14020 %}.
 14020 %}.
 14021 
 14021 
 14022     "x/y not integer, badGC or drawable, or not a string"
 14022     "x/y not integer, badGC or drawable, or not a string"
 14040     displayId := device displayIdOrErrorIfBroken.
 14040     displayId := device displayIdOrErrorIfBroken.
 14041 
 14041 
 14042     "limit the string len, otherwise bad output is generated"
 14042     "limit the string len, otherwise bad output is generated"
 14043     stringLen := index2Arg - index1 + 1.
 14043     stringLen := index2Arg - index1 + 1.
 14044     stringLen > 1000 "8000" ifTrue:[
 14044     stringLen > 1000 "8000" ifTrue:[
 14045         index2 := index1 + 1000 "8000" - 1.
 14045 	index2 := index1 + 1000 "8000" - 1.
 14046     ]  ifFalse:[
 14046     ]  ifFalse:[
 14047         stringLen <= 0 ifTrue:[^ self].
 14047 	stringLen <= 0 ifTrue:[^ self].
 14048         index2 := index2Arg.
 14048 	index2 := index2Arg.
 14049     ].
 14049     ].
 14050     bytesPerCharacter := aString bytesPerCharacter.
 14050     bytesPerCharacter := aString bytesPerCharacter.
 14051 
 14051 
 14052     clipRect notNil ifTrue:[
 14052     clipRect notNil ifTrue:[
 14053         clipX := clipRect left.
 14053 	clipX := clipRect left.
 14054         clipY := clipRect top.
 14054 	clipY := clipRect top.
 14055         clipW := clipRect width.
 14055 	clipW := clipRect width.
 14056         clipH := clipRect height.
 14056 	clipH := clipRect height.
 14057 "/clipW > 32767 ifTrue:['clipW > 32767: ' errorPrint. clipW errorPrintCR. clipW := 32767].
 14057 "/clipW > 32767 ifTrue:['clipW > 32767: ' errorPrint. clipW errorPrintCR. clipW := 32767].
 14058 "/(clipX > 16384 or:[clipX < -16384]) ifTrue:['clipX > 16384: ' errorPrint. clipX errorPrintCR.].
 14058 "/(clipX > 16384 or:[clipX < -16384]) ifTrue:['clipX > 16384: ' errorPrint. clipX errorPrintCR.].
 14059         "/ YES YES YES: this MUST be transformed!!
 14059 	"/ YES YES YES: this MUST be transformed!!
 14060         "/ (see htmlView) fix the notebook, please.
 14060 	"/ (see htmlView) fix the notebook, please.
 14061     ].
 14061     ].
 14062 
 14062 
 14063     fgR := paint scaledRed.
 14063     fgR := paint scaledRed.
 14064     fgR notNil ifTrue:[
 14064     fgR notNil ifTrue:[
 14065         fgG := paint scaledGreen.
 14065 	fgG := paint scaledGreen.
 14066         fgB := paint scaledBlue.
 14066 	fgB := paint scaledBlue.
 14067         fgA := paint scaledAlpha.
 14067 	fgA := paint scaledAlpha.
 14068     ] ifFalse:[
 14068     ] ifFalse:[
 14069         "/ when drawing into a pixmap...
 14069 	"/ when drawing into a pixmap...
 14070         fgPixel := paint colorId.
 14070 	fgPixel := paint colorId.
 14071         fgPixel == 0 ifTrue:[
 14071 	fgPixel == 0 ifTrue:[
 14072             fgR := fgG := fgB := 0.
 14072 	    fgR := fgG := fgB := 0.
 14073         ] ifFalse:[
 14073 	] ifFalse:[
 14074             fgR := fgG := fgB := 16rFFFF.
 14074 	    fgR := fgG := fgB := 16rFFFF.
 14075         ].
 14075 	].
 14076         fgA := 16rFFFF.
 14076 	fgA := 16rFFFF.
 14077     ].
 14077     ].
 14078 
 14078 
 14079     opaque ifTrue:[
 14079     opaque ifTrue:[
 14080         bgPaint isColor ifTrue:[
 14080 	bgPaint isColor ifTrue:[
 14081             bgR := bgPaint scaledRed.
 14081 	    bgR := bgPaint scaledRed.
 14082             bgR notNil ifTrue:[
 14082 	    bgR notNil ifTrue:[
 14083                 bgG := bgPaint scaledGreen.
 14083 		bgG := bgPaint scaledGreen.
 14084                 bgB := bgPaint scaledBlue.
 14084 		bgB := bgPaint scaledBlue.
 14085                 bgA := bgPaint scaledAlpha.
 14085 		bgA := bgPaint scaledAlpha.
 14086             ] ifFalse:[
 14086 	    ] ifFalse:[
 14087                 "/ when drawing into a pixmap...
 14087 		"/ when drawing into a pixmap...
 14088                 bgPixel := bgPaint colorId.
 14088 		bgPixel := bgPaint colorId.
 14089                 bgPixel == 0 ifTrue:[
 14089 		bgPixel == 0 ifTrue:[
 14090                     bgR := bgG := bgB := 0.
 14090 		    bgR := bgG := bgB := 0.
 14091                 ] ifFalse:[
 14091 		] ifFalse:[
 14092                     bgR := bgG := bgB := 16rFFFF.
 14092 		    bgR := bgG := bgB := 16rFFFF.
 14093                 ].
 14093 		].
 14094                 bgA := 16rFFFF.
 14094 		bgA := 16rFFFF.
 14095             ].
 14095 	    ].
 14096         ] ifFalse:[
 14096 	] ifFalse:[
 14097             "images as background are not yet implemented"
 14097 	    "images as background are not yet implemented"
 14098             "/ #todo: fill background rectangle
 14098 	    "/ #todo: fill background rectangle
 14099             bgR := bgG := bgB := bgA := 16rFFFF.
 14099 	    bgR := bgG := bgB := bgA := 16rFFFF.
 14100         ].
 14100 	].
 14101     ].
 14101     ].
 14102 
 14102 
 14103     screen := device screen.
 14103     screen := device screen.
 14104     self isPixmap ifTrue:[
 14104     self isPixmap ifTrue:[
 14105         pixmapDepth := depth.
 14105 	pixmapDepth := depth.
 14106     ].
 14106     ].
 14107     fontId := font getXftFontId.
 14107     fontId := font getXftFontId.
 14108 
 14108 
 14109 %{ /* STACK: 64000 */
 14109 %{ /* STACK: 64000 */
 14110 #ifdef XFT
 14110 #ifdef XFT
 14116     int __bytesPerCharacter;
 14116     int __bytesPerCharacter;
 14117     XftDraw *__xftDrawId;
 14117     XftDraw *__xftDrawId;
 14118     XftFont *__xftFont;
 14118     XftFont *__xftFont;
 14119 
 14119 
 14120     if (!(__bothSmallInteger(drawX, drawY)
 14120     if (!(__bothSmallInteger(drawX, drawY)
 14121           && __bothSmallInteger(index1, index2)
 14121 	  && __bothSmallInteger(index1, index2)
 14122           && __isSmallInteger(bytesPerCharacter)
 14122 	  && __isSmallInteger(bytesPerCharacter)
 14123           && (__isSmallInteger(fgPixel) || (__bothSmallInteger(fgR, fgG) && __bothSmallInteger(fgB, fgA)))
 14123 	  && (__isSmallInteger(fgPixel) || (__bothSmallInteger(fgR, fgG) && __bothSmallInteger(fgB, fgA)))
 14124           && (opaque == false || __isSmallInteger(bgPixel) || (__bothSmallInteger(bgR, bgG) && __bothSmallInteger(bgB, bgA)))
 14124 	  && (opaque == false || __isSmallInteger(bgPixel) || (__bothSmallInteger(bgR, bgG) && __bothSmallInteger(bgB, bgA)))
 14125           && __isNonNilObject(aString)
 14125 	  && __isNonNilObject(aString)
 14126           && __isExternalAddress(displayId)
 14126 	  && __isExternalAddress(displayId)
 14127           && __isExternalAddressLike(fontId)
 14127 	  && __isExternalAddressLike(fontId)
 14128     )) {
 14128     )) {
 14129         error = @symbol(badArgument);
 14129 	error = @symbol(badArgument);
 14130         goto out;
 14130 	goto out;
 14131     }
 14131     }
 14132 
 14132 
 14133     __xftFont = XFT_FONT(fontId);
 14133     __xftFont = XFT_FONT(fontId);
 14134     __bytesPerCharacter = __intVal(bytesPerCharacter);
 14134     __bytesPerCharacter = __intVal(bytesPerCharacter);
 14135 
 14135 
 14136     if (__INST(xftDrawId) != nil) {
 14136     if (__INST(xftDrawId) != nil) {
 14137         __xftDrawId = __externalAddressVal(__INST(xftDrawId));
 14137 	__xftDrawId = __externalAddressVal(__INST(xftDrawId));
 14138     } else {
 14138     } else {
 14139         if (pixmapDepth != nil) {
 14139 	if (pixmapDepth != nil) {
 14140             int __pixmapDepth = __intVal(pixmapDepth);
 14140 	    int __pixmapDepth = __intVal(pixmapDepth);
 14141 
 14141 
 14142             if (__pixmapDepth == 1) {
 14142 	    if (__pixmapDepth == 1) {
 14143                 __xftDrawId = XftDrawCreateBitmap(DISPLAY(displayId), DRAWABLE(__INST(drawableId)));
 14143 		__xftDrawId = XftDrawCreateBitmap(DISPLAY(displayId), DRAWABLE(__INST(drawableId)));
 14144             } else {
 14144 	    } else {
 14145                 __xftDrawId = XftDrawCreateAlpha(DISPLAY(displayId), DRAWABLE(__INST(drawableId)), __pixmapDepth);
 14145 		__xftDrawId = XftDrawCreateAlpha(DISPLAY(displayId), DRAWABLE(__INST(drawableId)), __pixmapDepth);
 14146             }
 14146 	    }
 14147         } else {
 14147 	} else {
 14148             __xftDrawId = XftDrawCreate(DISPLAY(displayId),
 14148 	    __xftDrawId = XftDrawCreate(DISPLAY(displayId),
 14149                                            DRAWABLE(__INST(drawableId)),
 14149 					   DRAWABLE(__INST(drawableId)),
 14150                                            DefaultVisual(DISPLAY(displayId), SCREEN(screen)),
 14150 					   DefaultVisual(DISPLAY(displayId), SCREEN(screen)),
 14151                                            DefaultColormap(DISPLAY(displayId), SCREEN(screen)));
 14151 					   DefaultColormap(DISPLAY(displayId), SCREEN(screen)));
 14152         }
 14152 	}
 14153         __INST(xftDrawId) = newXftDrawId = XFT_DRAW_HANDLE_NEW(__xftDrawId);
 14153 	__INST(xftDrawId) = newXftDrawId = XFT_DRAW_HANDLE_NEW(__xftDrawId);
 14154         __STORE(self, newXftDrawId);
 14154 	__STORE(self, newXftDrawId);
 14155     }
 14155     }
 14156 
 14156 
 14157     string = __stringVal(aString) + ((__intVal(index1) - 1 ) * __bytesPerCharacter);
 14157     string = __stringVal(aString) + ((__intVal(index1) - 1 ) * __bytesPerCharacter);
 14158     len = __intVal(index2) - __intVal(index1) + 1;
 14158     len = __intVal(index2) - __intVal(index1) + 1;
 14159 
 14159 
 14160     if (clipX != nil) {
 14160     if (clipX != nil) {
 14161         clipRX.x = __intVal(clipX);
 14161 	clipRX.x = __intVal(clipX);
 14162         clipRX.y = __intVal(clipY);
 14162 	clipRX.y = __intVal(clipY);
 14163         clipRX.width = __intVal(clipW);
 14163 	clipRX.width = __intVal(clipW);
 14164         clipRX.height = __intVal(clipH);
 14164 	clipRX.height = __intVal(clipH);
 14165         XftDrawSetClipRectangles(__xftDrawId, 0, 0, &clipRX, 1);
 14165 	XftDrawSetClipRectangles(__xftDrawId, 0, 0, &clipRX, 1);
 14166     } else {
 14166     } else {
 14167         XftDrawSetClip(__xftDrawId, 0);
 14167 	XftDrawSetClip(__xftDrawId, 0);
 14168     }
 14168     }
 14169 
 14169 
 14170     if (opaque == true) {
 14170     if (opaque == true) {
 14171         if (bgPixel != nil) {
 14171 	if (bgPixel != nil) {
 14172             color.pixel = (unsigned long)__intVal(bgPixel);
 14172 	    color.pixel = (unsigned long)__intVal(bgPixel);
 14173         }
 14173 	}
 14174         color.color.red = __intVal(bgR);
 14174 	color.color.red = __intVal(bgR);
 14175         color.color.green = __intVal(bgG);
 14175 	color.color.green = __intVal(bgG);
 14176         color.color.blue = __intVal(bgB);
 14176 	color.color.blue = __intVal(bgB);
 14177         color.color.alpha = __intVal(bgA);
 14177 	color.color.alpha = __intVal(bgA);
 14178 
 14178 
 14179         switch (__bytesPerCharacter) {
 14179 	switch (__bytesPerCharacter) {
 14180         case 1:
 14180 	case 1:
 14181             XftTextExtents8(DISPLAY(displayId), __xftFont, (FcChar8*)string, len, &extents);
 14181 	    XftTextExtents8(DISPLAY(displayId), __xftFont, (FcChar8*)string, len, &extents);
 14182             break;
 14182 	    break;
 14183         case 2:
 14183 	case 2:
 14184             XftTextExtents16(DISPLAY(displayId), __xftFont, (FcChar16*)string, len, &extents);
 14184 	    XftTextExtents16(DISPLAY(displayId), __xftFont, (FcChar16*)string, len, &extents);
 14185             break;
 14185 	    break;
 14186         case 4:
 14186 	case 4:
 14187             XftTextExtents32(DISPLAY(displayId), __xftFont, (FcChar32*)string, len, &extents);
 14187 	    XftTextExtents32(DISPLAY(displayId), __xftFont, (FcChar32*)string, len, &extents);
 14188             break;
 14188 	    break;
 14189         }
 14189 	}
 14190 if (extents.width < 0) printf("width: %d  < 0\n", extents.width);
 14190 if (extents.width < 0) printf("width: %d  < 0\n", extents.width);
 14191 
 14191 
 14192         XftDrawRect(__xftDrawId, &color, __intVal(drawX) - extents.x, __intVal(drawY) - __xftFont->ascent, extents.width, __xftFont->height);
 14192 	XftDrawRect(__xftDrawId, &color, __intVal(drawX) - extents.x, __intVal(drawY) - __xftFont->ascent, extents.width, __xftFont->height);
 14193     }
 14193     }
 14194     if (__isSmallInteger(fgPixel)) {
 14194     if (__isSmallInteger(fgPixel)) {
 14195         color.pixel = (unsigned long)__intVal(fgPixel);
 14195 	color.pixel = (unsigned long)__intVal(fgPixel);
 14196     }
 14196     }
 14197     color.color.red = __intVal(fgR);
 14197     color.color.red = __intVal(fgR);
 14198     color.color.green = __intVal(fgG);
 14198     color.color.green = __intVal(fgG);
 14199     color.color.blue = __intVal(fgB);
 14199     color.color.blue = __intVal(fgB);
 14200     color.color.alpha = __intVal(fgA);
 14200     color.color.alpha = __intVal(fgA);
 14201 
 14201 
 14202     switch (__bytesPerCharacter) {
 14202     switch (__bytesPerCharacter) {
 14203     case 1:
 14203     case 1:
 14204         XftDrawString8(__xftDrawId, &color,__xftFont,
 14204 	XftDrawString8(__xftDrawId, &color,__xftFont,
 14205                         __intVal(drawX),
 14205 			__intVal(drawX),
 14206                         __intVal(drawY),
 14206 			__intVal(drawY),
 14207                         (FcChar8*)string,
 14207 			(FcChar8*)string,
 14208                         len);
 14208 			len);
 14209         break;
 14209 	break;
 14210 
 14210 
 14211     case 2:
 14211     case 2:
 14212         XftDrawString16(__xftDrawId, &color, __xftFont,
 14212 	XftDrawString16(__xftDrawId, &color, __xftFont,
 14213                         __intVal(drawX),
 14213 			__intVal(drawX),
 14214                         __intVal(drawY),
 14214 			__intVal(drawY),
 14215                         (FcChar16*)string,
 14215 			(FcChar16*)string,
 14216                         len);
 14216 			len);
 14217         break;
 14217 	break;
 14218 
 14218 
 14219     case 4:
 14219     case 4:
 14220         XftDrawString32(__xftDrawId, &color, __xftFont,
 14220 	XftDrawString32(__xftDrawId, &color, __xftFont,
 14221                         __intVal(drawX),
 14221 			__intVal(drawX),
 14222                         __intVal(drawY),
 14222 			__intVal(drawY),
 14223                         (FcChar32*)string,
 14223 			(FcChar32*)string,
 14224                         len);
 14224 			len);
 14225         break;
 14225 	break;
 14226 
 14226 
 14227     default:
 14227     default:
 14228         error = @symbol(invalidStringSize);
 14228 	error = @symbol(invalidStringSize);
 14229         goto out;
 14229 	goto out;
 14230     }
 14230     }
 14231 
 14231 
 14232 out:;
 14232 out:;
 14233 #endif
 14233 #endif
 14234 %}.
 14234 %}.
 14235     error notNil ifTrue:[
 14235     error notNil ifTrue:[
 14236         self primitiveFailed: error.
 14236 	self primitiveFailed: error.
 14237     ].
 14237     ].
 14238 ! !
 14238 ! !
 14239 
 14239 
 14240 !XWorkstation::X11GraphicsContext methodsFor:'drawing'!
 14240 !XWorkstation::X11GraphicsContext methodsFor:'drawing'!
 14241 
 14241 
 14247     "draw a filled rectangle; apply transformation if nonNil"
 14247     "draw a filled rectangle; apply transformation if nonNil"
 14248 
 14248 
 14249     |pX pY nW nH pO pC|
 14249     |pX pY nW nH pO pC|
 14250 
 14250 
 14251     gcId isNil ifTrue:[
 14251     gcId isNil ifTrue:[
 14252         self initGC
 14252 	self initGC
 14253     ].
 14253     ].
 14254     transformation notNil ifTrue:[
 14254     transformation notNil ifTrue:[
 14255         pO := transformation transformPoint:x@y.
 14255 	pO := transformation transformPoint:x@y.
 14256         pC := transformation transformPoint:(x+w-1)@(y+h-1).
 14256 	pC := transformation transformPoint:(x+w-1)@(y+h-1).
 14257         pX := pO x.
 14257 	pX := pO x.
 14258         pY := pO y.
 14258 	pY := pO y.
 14259         nW := pC x - pX + 1.
 14259 	nW := pC x - pX + 1.
 14260         nH := pC y - pY + 1.
 14260 	nH := pC y - pY + 1.
 14261 
 14261 
 14262         nW < 0 ifTrue:[
 14262 	nW < 0 ifTrue:[
 14263               nW := nW abs.
 14263 	      nW := nW abs.
 14264               pX := pX - nW.
 14264 	      pX := pX - nW.
 14265         ].
 14265 	].
 14266         nH < 0 ifTrue:[
 14266 	nH < 0 ifTrue:[
 14267               nH := nH abs.
 14267 	      nH := nH abs.
 14268               pY := pY - nH.
 14268 	      pY := pY - nH.
 14269         ].
 14269 	].
 14270     ] ifFalse:[
 14270     ] ifFalse:[
 14271         pX := x.
 14271 	pX := x.
 14272         pY := y.
 14272 	pY := y.
 14273         nW := w.
 14273 	nW := w.
 14274         nH := h.
 14274 	nH := h.
 14275     ].
 14275     ].
 14276     pX := pX rounded.
 14276     pX := pX rounded.
 14277     pY := pY rounded.
 14277     pY := pY rounded.
 14278     nW := nW rounded.
 14278     nW := nW rounded.
 14279     nH := nH rounded.
 14279     nH := nH rounded.
 14280 
 14280 
 14281     device
 14281     device
 14282         clearRectangleX:pX
 14282 	clearRectangleX:pX
 14283                      y:pY
 14283 		     y:pY
 14284                  width:nW
 14284 		 width:nW
 14285                 height:nH
 14285 		height:nH
 14286                     in:drawableId with:gcId
 14286 		    in:drawableId with:gcId
 14287 ! !
 14287 ! !
 14288 
 14288 
 14289 !XWorkstation::X11GraphicsContext methodsFor:'view creation'!
 14289 !XWorkstation::X11GraphicsContext methodsFor:'view creation'!
 14290 
 14290 
 14291 createBitmapFromArray:data width:width height:height
 14291 createBitmapFromArray:data width:width height:height