XWorkstation.st
changeset 6159 d4e463e0c56c
parent 6157 244e739e05e9
child 6160 3ea2f08308ae
equal deleted inserted replaced
6158:17d06f1e4ca6 6159:d4e463e0c56c
    13 
    13 
    14 DeviceWorkstation subclass:#XWorkstation
    14 DeviceWorkstation subclass:#XWorkstation
    15 	instanceVariableNames:'hasShapeExtension hasShmExtension hasDPSExtension
    15 	instanceVariableNames:'hasShapeExtension hasShmExtension hasDPSExtension
    16 		hasMbufExtension hasXVideoExtension hasSaveUnder hasPEXExtension
    16 		hasMbufExtension hasXVideoExtension hasSaveUnder hasPEXExtension
    17 		hasImageExtension hasInputExtension hasXineramaExtension
    17 		hasImageExtension hasInputExtension hasXineramaExtension
    18 		ignoreBackingStore blackpixel whitepixel atoms protocolsAtom
    18 		hasRenderExtension hasXftLibrary ignoreBackingStore blackpixel whitepixel atoms protocolsAtom
    19 		deleteWindowAtom saveYourselfAtom quitAppAtom primaryAtom
    19 		deleteWindowAtom saveYourselfAtom quitAppAtom primaryAtom
    20 		clipboardAtom stringAtom wmStateAtom motifWMHintsAtom
    20 		clipboardAtom stringAtom wmStateAtom motifWMHintsAtom
    21 		listOfXFonts buttonsPressed eventRootX eventRootY displayName
    21 		listOfXFonts buttonsPressed eventRootX eventRootY displayName
    22 		eventTrace dispatchingExpose rgbVisual rgbaVisual virtualRootId
    22 		eventTrace dispatchingExpose rgbVisual rgbaVisual virtualRootId
    23 		rootId altModifierMask metaModifierMask lastEventTime
    23 		rootId altModifierMask metaModifierMask lastEventTime
   165 # include <X11/extensions/XIE.h>
   165 # include <X11/extensions/XIE.h>
   166 #endif
   166 #endif
   167 
   167 
   168 #ifdef XINERAMA
   168 #ifdef XINERAMA
   169 # include <X11/extensions/Xinerama.h>
   169 # include <X11/extensions/Xinerama.h>
       
   170 #endif
       
   171 
       
   172 /*
       
   173  * xft library (based on RENDER extension) - if available
       
   174  */
       
   175 #ifdef XFT
       
   176 # include <X11/Xft/Xft.h>
   170 #endif
   177 #endif
   171 
   178 
   172 /*
   179 /*
   173  * when I have more time to check it out, I will support display-PS
   180  * when I have more time to check it out, I will support display-PS
   174  */
   181  */
  3201      argument is not integer."
  3208      argument is not integer."
  3202 
  3209 
  3203     <context: #return>
  3210     <context: #return>
  3204 
  3211 
  3205     operationsUntilFlush notNil ifTrue:[
  3212     operationsUntilFlush notNil ifTrue:[
  3206         operationsUntilFlush <= 0 ifTrue:[
  3213 	operationsUntilFlush <= 0 ifTrue:[
  3207             self flush.
  3214 	    self flush.
  3208         ] ifFalse:[
  3215 	] ifFalse:[
  3209             operationsUntilFlush := operationsUntilFlush - 1.
  3216 	    operationsUntilFlush := operationsUntilFlush - 1.
  3210         ].
  3217 	].
  3211     ].
  3218     ].
  3212 %{
  3219 %{
  3213 
  3220 
  3214     GC gc;
  3221     GC gc;
  3215     Drawable source, dest;
  3222     Drawable source, dest;
  3219      && __isExternalAddress(sourceId)
  3226      && __isExternalAddress(sourceId)
  3220      && __isExternalAddress(destId)
  3227      && __isExternalAddress(destId)
  3221      && __bothSmallInteger(w, h)
  3228      && __bothSmallInteger(w, h)
  3222      && __bothSmallInteger(srcX, srcY)
  3229      && __bothSmallInteger(srcX, srcY)
  3223      && __bothSmallInteger(dstX, dstY)) {
  3230      && __bothSmallInteger(dstX, dstY)) {
  3224         int _sX, _sY, _w, _h, _dX, _dY;
  3231 	int _sX, _sY, _w, _h, _dX, _dY;
  3225 
  3232 
  3226         _sX = __intVal(srcX);
  3233 	_sX = __intVal(srcX);
  3227         _sY = __intVal(srcY);
  3234 	_sY = __intVal(srcY);
  3228         _w = __intVal(w);
  3235 	_w = __intVal(w);
  3229         _h = __intVal(h);
  3236 	_h = __intVal(h);
  3230         _dX = __intVal(dstX);
  3237 	_dX = __intVal(dstX);
  3231         _dY = __intVal(dstY);
  3238 	_dY = __intVal(dstY);
  3232 
  3239 
  3233         gc = __GCVal(dstGCId);
  3240 	gc = __GCVal(dstGCId);
  3234         source = __DrawableVal(sourceId);
  3241 	source = __DrawableVal(sourceId);
  3235         dest =   __DrawableVal(destId);
  3242 	dest =   __DrawableVal(destId);
  3236         ENTER_XLIB();
  3243 	ENTER_XLIB();
  3237         XCopyArea(myDpy, source, dest, gc, _sX, _sY, _w, _h, _dX, _dY);
  3244 	XCopyArea(myDpy, source, dest, gc, _sX, _sY, _w, _h, _dX, _dY);
  3238         LEAVE_XLIB();
  3245 	LEAVE_XLIB();
  3239         RETURN ( self );
  3246 	RETURN ( self );
  3240     }
  3247     }
  3241 %}.
  3248 %}.
  3242     "badGC, bad sourceDrawableId or destDrawableID
  3249     "badGC, bad sourceDrawableId or destDrawableID
  3243      or any non integer coordinate"
  3250      or any non integer coordinate"
  3244 
  3251 
  3253      This is basically the same as copyFromId:..., but does not generate expose events."
  3260      This is basically the same as copyFromId:..., but does not generate expose events."
  3254 
  3261 
  3255     <context: #return>
  3262     <context: #return>
  3256 
  3263 
  3257     operationsUntilFlush notNil ifTrue:[
  3264     operationsUntilFlush notNil ifTrue:[
  3258         operationsUntilFlush <= 0 ifTrue:[
  3265 	operationsUntilFlush <= 0 ifTrue:[
  3259             self flush.
  3266 	    self flush.
  3260         ] ifFalse:[
  3267 	] ifFalse:[
  3261             operationsUntilFlush := operationsUntilFlush - 1.
  3268 	    operationsUntilFlush := operationsUntilFlush - 1.
  3262         ].
  3269 	].
  3263     ].
  3270     ].
  3264 %{
  3271 %{
  3265 
  3272 
  3266     GC gc;
  3273     GC gc;
  3267     Drawable source, dest;
  3274     Drawable source, dest;
  3271      && __isExternalAddress(sourceId)
  3278      && __isExternalAddress(sourceId)
  3272      && __isExternalAddress(destId)
  3279      && __isExternalAddress(destId)
  3273      && __bothSmallInteger(w, h)
  3280      && __bothSmallInteger(w, h)
  3274      && __bothSmallInteger(srcX, srcY)
  3281      && __bothSmallInteger(srcX, srcY)
  3275      && __bothSmallInteger(dstX, dstY)) {
  3282      && __bothSmallInteger(dstX, dstY)) {
  3276         Display *dpy = myDpy;
  3283 	Display *dpy = myDpy;
  3277 
  3284 
  3278         gc = __GCVal(dstGCId);
  3285 	gc = __GCVal(dstGCId);
  3279         source = __DrawableVal(sourceId);
  3286 	source = __DrawableVal(sourceId);
  3280         dest =   __DrawableVal(destId);
  3287 	dest =   __DrawableVal(destId);
  3281         ENTER_XLIB();
  3288 	ENTER_XLIB();
  3282         XSetGraphicsExposures(dpy, gc, 0);
  3289 	XSetGraphicsExposures(dpy, gc, 0);
  3283         XCopyArea(dpy, source, dest, gc,
  3290 	XCopyArea(dpy, source, dest, gc,
  3284                                 __intVal(srcX), __intVal(srcY),
  3291 				__intVal(srcX), __intVal(srcY),
  3285                                 __intVal(w), __intVal(h),
  3292 				__intVal(w), __intVal(h),
  3286                                 __intVal(dstX), __intVal(dstY));
  3293 				__intVal(dstX), __intVal(dstY));
  3287         XSetGraphicsExposures(dpy, gc, 1);
  3294 	XSetGraphicsExposures(dpy, gc, 1);
  3288         LEAVE_XLIB();
  3295 	LEAVE_XLIB();
  3289         RETURN ( self );
  3296 	RETURN ( self );
  3290     }
  3297     }
  3291 %}.
  3298 %}.
  3292     "badGC, bad sourceDrawableId or destDrawableID
  3299     "badGC, bad sourceDrawableId or destDrawableID
  3293      or any non integer coordinate"
  3300      or any non integer coordinate"
  3294 
  3301 
  3303      argument is not integer."
  3310      argument is not integer."
  3304 
  3311 
  3305     <context: #return>
  3312     <context: #return>
  3306 
  3313 
  3307     operationsUntilFlush notNil ifTrue:[
  3314     operationsUntilFlush notNil ifTrue:[
  3308         operationsUntilFlush <= 0 ifTrue:[
  3315 	operationsUntilFlush <= 0 ifTrue:[
  3309             self flush.
  3316 	    self flush.
  3310         ] ifFalse:[
  3317 	] ifFalse:[
  3311             operationsUntilFlush := operationsUntilFlush - 1.
  3318 	    operationsUntilFlush := operationsUntilFlush - 1.
  3312         ].
  3319 	].
  3313     ].
  3320     ].
  3314 %{
  3321 %{
  3315 
  3322 
  3316     GC gc;
  3323     GC gc;
  3317     Drawable source, dest;
  3324     Drawable source, dest;
  3321      && __isExternalAddress(sourceId)
  3328      && __isExternalAddress(sourceId)
  3322      && __isExternalAddress(destId)
  3329      && __isExternalAddress(destId)
  3323      && __bothSmallInteger(w, h)
  3330      && __bothSmallInteger(w, h)
  3324      && __bothSmallInteger(srcX, srcY)
  3331      && __bothSmallInteger(srcX, srcY)
  3325      && __bothSmallInteger(dstX, dstY)) {
  3332      && __bothSmallInteger(dstX, dstY)) {
  3326         gc = __GCVal(dstGCId);
  3333 	gc = __GCVal(dstGCId);
  3327         source = __DrawableVal(sourceId);
  3334 	source = __DrawableVal(sourceId);
  3328         dest =   __DrawableVal(destId);
  3335 	dest =   __DrawableVal(destId);
  3329         ENTER_XLIB();
  3336 	ENTER_XLIB();
  3330         XCopyPlane(myDpy, source, dest, gc,
  3337 	XCopyPlane(myDpy, source, dest, gc,
  3331                                  __intVal(srcX), __intVal(srcY),
  3338 				 __intVal(srcX), __intVal(srcY),
  3332                                  __intVal(w), __intVal(h),
  3339 				 __intVal(w), __intVal(h),
  3333                                  __intVal(dstX), __intVal(dstY), 1);
  3340 				 __intVal(dstX), __intVal(dstY), 1);
  3334         LEAVE_XLIB();
  3341 	LEAVE_XLIB();
  3335         RETURN ( self );
  3342 	RETURN ( self );
  3336     }
  3343     }
  3337 %}.
  3344 %}.
  3338     "badGC, bad sourceDrawableId or destDrawableID
  3345     "badGC, bad sourceDrawableId or destDrawableID
  3339      or any non integer coordinate"
  3346      or any non integer coordinate"
  3340 
  3347 
  3350      This is the same as copyPlaneFromId:..., but does not generate graphics exposes"
  3357      This is the same as copyPlaneFromId:..., but does not generate graphics exposes"
  3351 
  3358 
  3352     <context: #return>
  3359     <context: #return>
  3353 
  3360 
  3354     operationsUntilFlush notNil ifTrue:[
  3361     operationsUntilFlush notNil ifTrue:[
  3355         operationsUntilFlush <= 0 ifTrue:[
  3362 	operationsUntilFlush <= 0 ifTrue:[
  3356             self flush.
  3363 	    self flush.
  3357         ] ifFalse:[
  3364 	] ifFalse:[
  3358             operationsUntilFlush := operationsUntilFlush - 1.
  3365 	    operationsUntilFlush := operationsUntilFlush - 1.
  3359         ].
  3366 	].
  3360     ].
  3367     ].
  3361 %{
  3368 %{
  3362 
  3369 
  3363     GC gc;
  3370     GC gc;
  3364     Drawable source, dest;
  3371     Drawable source, dest;
  3368      && __isExternalAddress(sourceId)
  3375      && __isExternalAddress(sourceId)
  3369      && __isExternalAddress(destId)
  3376      && __isExternalAddress(destId)
  3370      && __bothSmallInteger(w, h)
  3377      && __bothSmallInteger(w, h)
  3371      && __bothSmallInteger(srcX, srcY)
  3378      && __bothSmallInteger(srcX, srcY)
  3372      && __bothSmallInteger(dstX, dstY)) {
  3379      && __bothSmallInteger(dstX, dstY)) {
  3373         Display *dpy = myDpy;
  3380 	Display *dpy = myDpy;
  3374 
  3381 
  3375         gc = __GCVal(dstGCId);
  3382 	gc = __GCVal(dstGCId);
  3376         source = __DrawableVal(sourceId);
  3383 	source = __DrawableVal(sourceId);
  3377         dest =   __DrawableVal(destId);
  3384 	dest =   __DrawableVal(destId);
  3378         ENTER_XLIB();
  3385 	ENTER_XLIB();
  3379         XSetGraphicsExposures(dpy, gc, 0);
  3386 	XSetGraphicsExposures(dpy, gc, 0);
  3380         XCopyPlane(dpy, source, dest, gc,
  3387 	XCopyPlane(dpy, source, dest, gc,
  3381                                  __intVal(srcX), __intVal(srcY),
  3388 				 __intVal(srcX), __intVal(srcY),
  3382                                  __intVal(w), __intVal(h),
  3389 				 __intVal(w), __intVal(h),
  3383                                  __intVal(dstX), __intVal(dstY), 1);
  3390 				 __intVal(dstX), __intVal(dstY), 1);
  3384         XSetGraphicsExposures(dpy, gc, 1);
  3391 	XSetGraphicsExposures(dpy, gc, 1);
  3385         LEAVE_XLIB();
  3392 	LEAVE_XLIB();
  3386         RETURN ( self );
  3393 	RETURN ( self );
  3387     }
  3394     }
  3388 %}.
  3395 %}.
  3389     "badGC, bad sourceDrawableId or destDrawableID
  3396     "badGC, bad sourceDrawableId or destDrawableID
  3390      or any non integer coordinate"
  3397      or any non integer coordinate"
  3391 
  3398 
  3397      The angles may be floats or integer - they are given in degrees."
  3404      The angles may be floats or integer - they are given in degrees."
  3398 
  3405 
  3399     <context: #return>
  3406     <context: #return>
  3400 
  3407 
  3401     operationsUntilFlush notNil ifTrue:[
  3408     operationsUntilFlush notNil ifTrue:[
  3402         operationsUntilFlush <= 0 ifTrue:[
  3409 	operationsUntilFlush <= 0 ifTrue:[
  3403             self flush.
  3410 	    self flush.
  3404         ] ifFalse:[
  3411 	] ifFalse:[
  3405             operationsUntilFlush := operationsUntilFlush - 1.
  3412 	    operationsUntilFlush := operationsUntilFlush - 1.
  3406         ].
  3413 	].
  3407     ].
  3414     ].
  3408 %{
  3415 %{
  3409 
  3416 
  3410     GC gc;
  3417     GC gc;
  3411     Window win;
  3418     Window win;
  3412     int w, h, angle1, angle2;
  3419     int w, h, angle1, angle2;
  3413     double f;
  3420     double f;
  3414 
  3421 
  3415     if (__isSmallInteger(startAngle))
  3422     if (__isSmallInteger(startAngle))
  3416         angle1 = __intVal(startAngle) * 64;
  3423 	angle1 = __intVal(startAngle) * 64;
  3417     else if (__isFloat(startAngle)) {
  3424     else if (__isFloat(startAngle)) {
  3418         f = __floatVal(startAngle);
  3425 	f = __floatVal(startAngle);
  3419         angle1 = f * 64;
  3426 	angle1 = f * 64;
  3420     } else if (__isShortFloat(startAngle)) {
  3427     } else if (__isShortFloat(startAngle)) {
  3421         f = __shortFloatVal(startAngle);
  3428 	f = __shortFloatVal(startAngle);
  3422         angle1 = f * 64;
  3429 	angle1 = f * 64;
  3423     } else goto bad;
  3430     } else goto bad;
  3424 
  3431 
  3425     if (__isSmallInteger(angle))
  3432     if (__isSmallInteger(angle))
  3426         angle2 = __intVal(angle) * 64;
  3433 	angle2 = __intVal(angle) * 64;
  3427     else if (__isFloat(angle)) {
  3434     else if (__isFloat(angle)) {
  3428         f = __floatVal(angle);
  3435 	f = __floatVal(angle);
  3429         angle2 = f * 64;
  3436 	angle2 = f * 64;
  3430     } else if (__isShortFloat(angle)) {
  3437     } else if (__isShortFloat(angle)) {
  3431         f = __shortFloatVal(angle);
  3438 	f = __shortFloatVal(angle);
  3432         angle2 = f * 64;
  3439 	angle2 = f * 64;
  3433     } else goto bad;
  3440     } else goto bad;
  3434 
  3441 
  3435     if (ISCONNECTED
  3442     if (ISCONNECTED
  3436      && __isExternalAddress(aGCId)
  3443      && __isExternalAddress(aGCId)
  3437      && __isExternalAddress(aDrawableId)
  3444      && __isExternalAddress(aDrawableId)
  3438      && __bothSmallInteger(x, y)
  3445      && __bothSmallInteger(x, y)
  3439      && __bothSmallInteger(width, height)) {
  3446      && __bothSmallInteger(width, height)) {
  3440         win = __WindowVal(aDrawableId);
  3447 	win = __WindowVal(aDrawableId);
  3441         gc = __GCVal(aGCId);
  3448 	gc = __GCVal(aGCId);
  3442         w = __intVal(width);
  3449 	w = __intVal(width);
  3443         h = __intVal(height);
  3450 	h = __intVal(height);
  3444         /*
  3451 	/*
  3445          * need this check here: some servers simply dump core with bad args
  3452 	 * need this check here: some servers simply dump core with bad args
  3446          */
  3453 	 */
  3447         if ((w >= 0) && (h >= 0) && (angle1 >= 0) && (angle2 >= 0)) {
  3454 	if ((w >= 0) && (h >= 0) && (angle1 >= 0) && (angle2 >= 0)) {
  3448             ENTER_XLIB();
  3455 	    ENTER_XLIB();
  3449             XDrawArc(myDpy, win, gc, __intVal(x), __intVal(y),
  3456 	    XDrawArc(myDpy, win, gc, __intVal(x), __intVal(y),
  3450                                    w, h, angle1, angle2);
  3457 				   w, h, angle1, angle2);
  3451             LEAVE_XLIB();
  3458 	    LEAVE_XLIB();
  3452         }
  3459 	}
  3453         RETURN ( self );
  3460 	RETURN ( self );
  3454     }
  3461     }
  3455     bad: ;
  3462     bad: ;
  3456 %}.
  3463 %}.
  3457     "badGC, badDrawable or coordinates not integer
  3464     "badGC, badDrawable or coordinates not integer
  3458      or angle(s) not integer or float."
  3465      or angle(s) not integer or float."
  3464     "draw a line. If the coordinates are not integers, an error is triggered."
  3471     "draw a line. If the coordinates are not integers, an error is triggered."
  3465 
  3472 
  3466     <context: #return>
  3473     <context: #return>
  3467 
  3474 
  3468     operationsUntilFlush notNil ifTrue:[
  3475     operationsUntilFlush notNil ifTrue:[
  3469         operationsUntilFlush <= 0 ifTrue:[
  3476 	operationsUntilFlush <= 0 ifTrue:[
  3470             self flush.
  3477 	    self flush.
  3471         ] ifFalse:[
  3478 	] ifFalse:[
  3472             operationsUntilFlush := operationsUntilFlush - 1.
  3479 	    operationsUntilFlush := operationsUntilFlush - 1.
  3473         ].
  3480 	].
  3474     ].
  3481     ].
  3475 %{
  3482 %{
  3476 
  3483 
  3477     GC gc;
  3484     GC gc;
  3478     Window win;
  3485     Window win;
  3480     if (ISCONNECTED
  3487     if (ISCONNECTED
  3481      && __isExternalAddress(aGCId)
  3488      && __isExternalAddress(aGCId)
  3482      && __isExternalAddress(aDrawableId)
  3489      && __isExternalAddress(aDrawableId)
  3483      && __bothSmallInteger(x0, y0)
  3490      && __bothSmallInteger(x0, y0)
  3484      && __bothSmallInteger(x1, y1)) {
  3491      && __bothSmallInteger(x1, y1)) {
  3485         Display *dpy = myDpy;
  3492 	Display *dpy = myDpy;
  3486         int ix0, iy0, ix1, iy1;
  3493 	int ix0, iy0, ix1, iy1;
  3487         gc = __GCVal(aGCId);
  3494 	gc = __GCVal(aGCId);
  3488         win = __WindowVal(aDrawableId);
  3495 	win = __WindowVal(aDrawableId);
  3489 
  3496 
  3490         ix0 = __intVal(x0);
  3497 	ix0 = __intVal(x0);
  3491         iy0 = __intVal(y0);
  3498 	iy0 = __intVal(y0);
  3492         ix1 = __intVal(x1);
  3499 	ix1 = __intVal(x1);
  3493         iy1 = __intVal(y1);
  3500 	iy1 = __intVal(y1);
  3494 
  3501 
  3495         /* attention: coordinates in X are shorts and wrap; clamp here. */
  3502 	/* attention: coordinates in X are shorts and wrap; clamp here. */
  3496         if (ix0 > 0x7FFF) ix0 = 0x7FFF;
  3503 	if (ix0 > 0x7FFF) ix0 = 0x7FFF;
  3497         else if (ix0 < -0x8000) ix0 = -0x8000;
  3504 	else if (ix0 < -0x8000) ix0 = -0x8000;
  3498         if (iy0 > 0x7FFF) iy0 = 0x7FFF;
  3505 	if (iy0 > 0x7FFF) iy0 = 0x7FFF;
  3499         else if (iy0 < -0x8000) iy0 = -0x8000;
  3506 	else if (iy0 < -0x8000) iy0 = -0x8000;
  3500         if (ix1 > 0x7FFF) ix1 = 0x7FFF;
  3507 	if (ix1 > 0x7FFF) ix1 = 0x7FFF;
  3501         else if (ix1 < -0x8000) ix1 = -0x8000;
  3508 	else if (ix1 < -0x8000) ix1 = -0x8000;
  3502         if (iy1 > 0x7FFF) iy1 = 0x7FFF;
  3509 	if (iy1 > 0x7FFF) iy1 = 0x7FFF;
  3503         else if (iy1 < -0x8000) iy1 = -0x8000;
  3510 	else if (iy1 < -0x8000) iy1 = -0x8000;
  3504 
  3511 
  3505         ENTER_XLIB();
  3512 	ENTER_XLIB();
  3506         if ((ix0 == ix1) && (iy0 == iy1)) {
  3513 	if ((ix0 == ix1) && (iy0 == iy1)) {
  3507             /* little bit shorter X-lib message (better with slow connections...) */
  3514 	    /* little bit shorter X-lib message (better with slow connections...) */
  3508             XDrawPoint(dpy, win, gc, ix0, iy0);
  3515 	    XDrawPoint(dpy, win, gc, ix0, iy0);
  3509         } else {
  3516 	} else {
  3510             XDrawLine(dpy, win, gc, ix0, iy0, ix1, iy1);
  3517 	    XDrawLine(dpy, win, gc, ix0, iy0, ix1, iy1);
  3511         }
  3518 	}
  3512         LEAVE_XLIB();
  3519 	LEAVE_XLIB();
  3513         RETURN ( self );
  3520 	RETURN ( self );
  3514     }
  3521     }
  3515 %}.
  3522 %}.
  3516     "badGC, badDrawable or coordinates not integer"
  3523     "badGC, badDrawable or coordinates not integer"
  3517     self primitiveFailedOrClosedConnection
  3524     self primitiveFailedOrClosedConnection
  3518 !
  3525 !
  3525     <context: #return>
  3532     <context: #return>
  3526 
  3533 
  3527     |noY|
  3534     |noY|
  3528 
  3535 
  3529     (noY := yValues size) < 2 ifTrue:[
  3536     (noY := yValues size) < 2 ifTrue:[
  3530         ^ self
  3537 	^ self
  3531     ].
  3538     ].
  3532 
  3539 
  3533     operationsUntilFlush notNil ifTrue:[
  3540     operationsUntilFlush notNil ifTrue:[
  3534         operationsUntilFlush <= 0 ifTrue:[
  3541 	operationsUntilFlush <= 0 ifTrue:[
  3535             self flush.
  3542 	    self flush.
  3536         ] ifFalse:[
  3543 	] ifFalse:[
  3537             operationsUntilFlush := operationsUntilFlush - 1.
  3544 	    operationsUntilFlush := operationsUntilFlush - 1.
  3538         ].
  3545 	].
  3539     ].
  3546     ].
  3540 %{
  3547 %{
  3541     OBJ      yA, t;
  3548     OBJ      yA, t;
  3542     int      i, num;
  3549     int      i, num;
  3543     float    y, x, sY, tY, step;
  3550     float    y, x, sY, tY, step;
  3549     Window win;
  3556     Window win;
  3550 
  3557 
  3551     if (ISCONNECTED
  3558     if (ISCONNECTED
  3552      && __isExternalAddress(aGCId)
  3559      && __isExternalAddress(aGCId)
  3553      && __isExternalAddress(aDrawableId) ) {
  3560      && __isExternalAddress(aDrawableId) ) {
  3554         gc = __GCVal(aGCId);
  3561 	gc = __GCVal(aGCId);
  3555         win = __WindowVal(aDrawableId);
  3562 	win = __WindowVal(aDrawableId);
  3556 
  3563 
  3557         if( __isSmallInteger(scaleY) )
  3564 	if( __isSmallInteger(scaleY) )
  3558             sY = (float) __intVal( scaleY );
  3565 	    sY = (float) __intVal( scaleY );
  3559         else if (__isFloat(scaleY))
  3566 	else if (__isFloat(scaleY))
  3560             sY = __floatVal( scaleY );
  3567 	    sY = __floatVal( scaleY );
  3561         else if (__isShortFloat(scaleY))
  3568 	else if (__isShortFloat(scaleY))
  3562             sY = __shortFloatVal( scaleY );
  3569 	    sY = __shortFloatVal( scaleY );
  3563         else {
  3570 	else {
  3564             t = __SSEND0(scaleY, @symbol(asFloat), 0);
  3571 	    t = __SSEND0(scaleY, @symbol(asFloat), 0);
  3565             if (! __isFloat(t)) goto fail;
  3572 	    if (! __isFloat(t)) goto fail;
  3566             sY = __floatVal( t );
  3573 	    sY = __floatVal( t );
  3567         }
  3574 	}
  3568 
  3575 
  3569         if( __isSmallInteger(transY) )
  3576 	if( __isSmallInteger(transY) )
  3570             tY = (float) __intVal( transY );
  3577 	    tY = (float) __intVal( transY );
  3571         else if (__isFloat(transY))
  3578 	else if (__isFloat(transY))
  3572             tY = __floatVal( transY );
  3579 	    tY = __floatVal( transY );
  3573         else if (__isShortFloat(transY))
  3580 	else if (__isShortFloat(transY))
  3574             tY = __shortFloatVal( transY );
  3581 	    tY = __shortFloatVal( transY );
  3575         else {
  3582 	else {
  3576             t = __SSEND0(transY, @symbol(asFloat), 0);
  3583 	    t = __SSEND0(transY, @symbol(asFloat), 0);
  3577             if (! __isFloat(t)) goto fail;
  3584 	    if (! __isFloat(t)) goto fail;
  3578             tY = __floatVal( t );
  3585 	    tY = __floatVal( t );
  3579         }
  3586 	}
  3580 
  3587 
  3581         if( __isSmallInteger(startX) )
  3588 	if( __isSmallInteger(startX) )
  3582             x = (float) __intVal( startX );
  3589 	    x = (float) __intVal( startX );
  3583         else if (__isFloat(startX))
  3590 	else if (__isFloat(startX))
  3584             x = __floatVal( startX );
  3591 	    x = __floatVal( startX );
  3585         else if (__isShortFloat(startX))
  3592 	else if (__isShortFloat(startX))
  3586             x = __shortFloatVal( startX );
  3593 	    x = __shortFloatVal( startX );
  3587         else {
  3594 	else {
  3588             t = __SSEND0(startX, @symbol(asFloat), 0);
  3595 	    t = __SSEND0(startX, @symbol(asFloat), 0);
  3589             if (! __isFloat(t)) goto fail;
  3596 	    if (! __isFloat(t)) goto fail;
  3590             x = __floatVal( t );
  3597 	    x = __floatVal( t );
  3591         }
  3598 	}
  3592 
  3599 
  3593         if( __isSmallInteger(stepX) )
  3600 	if( __isSmallInteger(stepX) )
  3594             step = (float) __intVal( stepX );
  3601 	    step = (float) __intVal( stepX );
  3595         else if (__isFloat(stepX))
  3602 	else if (__isFloat(stepX))
  3596             step = __floatVal( stepX );
  3603 	    step = __floatVal( stepX );
  3597         else if (__isShortFloat(stepX))
  3604 	else if (__isShortFloat(stepX))
  3598             step = __shortFloatVal( stepX );
  3605 	    step = __shortFloatVal( stepX );
  3599         else {
  3606 	else {
  3600             t = __SSEND0(stepX, @symbol(asFloat), 0);
  3607 	    t = __SSEND0(stepX, @symbol(asFloat), 0);
  3601             if (! __isFloat(t)) goto fail;
  3608 	    if (! __isFloat(t)) goto fail;
  3602             step = __floatVal( t );
  3609 	    step = __floatVal( t );
  3603         }
  3610 	}
  3604 
  3611 
  3605         num = __intVal( noY );
  3612 	num = __intVal( noY );
  3606 
  3613 
  3607         if( num > 200 ) {
  3614 	if( num > 200 ) {
  3608             if( ! (points = (XPoint *) malloc ( sizeof(XPoint) * num )) )
  3615 	    if( ! (points = (XPoint *) malloc ( sizeof(XPoint) * num )) )
  3609                 goto fail;
  3616 		goto fail;
  3610             mustFree = 1;
  3617 	    mustFree = 1;
  3611         } else {
  3618 	} else {
  3612             points = qPoints;
  3619 	    points = qPoints;
  3613         }
  3620 	}
  3614         for( i = 0; i < num; ++i ) {
  3621 	for( i = 0; i < num; ++i ) {
  3615             int px, py;
  3622 	    int px, py;
  3616 
  3623 
  3617             yA  = __AT_(yValues, __MKSMALLINT(i+1) );
  3624 	    yA  = __AT_(yValues, __MKSMALLINT(i+1) );
  3618 
  3625 
  3619             if( __isFloat(yA) )
  3626 	    if( __isFloat(yA) )
  3620                 y = __floatVal( yA );
  3627 		y = __floatVal( yA );
  3621             else if( __isSmallInteger(yA) )
  3628 	    else if( __isSmallInteger(yA) )
  3622                 y = (float) __intVal( yA );
  3629 		y = (float) __intVal( yA );
  3623             else if( __isShortFloat( yA) )
  3630 	    else if( __isShortFloat( yA) )
  3624                 y = __shortFloatVal( yA );
  3631 		y = __shortFloatVal( yA );
  3625             else {
  3632 	    else {
  3626                 t = __SSEND0(yA, @symbol(asFloat), 0);
  3633 		t = __SSEND0(yA, @symbol(asFloat), 0);
  3627                 if (! __isFloat(t)) goto fail;
  3634 		if (! __isFloat(t)) goto fail;
  3628                 y = __floatVal( t );
  3635 		y = __floatVal( t );
  3629             }
  3636 	    }
  3630 
  3637 
  3631             px = (int) (x + 0.5);
  3638 	    px = (int) (x + 0.5);
  3632             py = (int) ((y * sY) + tY + 0.5);
  3639 	    py = (int) ((y * sY) + tY + 0.5);
  3633 
  3640 
  3634             /* attention: coordinates in X are shorts and wrap; clamp here. */
  3641 	    /* attention: coordinates in X are shorts and wrap; clamp here. */
  3635             if (px > 0x7FFF) px = 0x7FFF;
  3642 	    if (px > 0x7FFF) px = 0x7FFF;
  3636             else if (px < -0x8000) px = -0x8000;
  3643 	    else if (px < -0x8000) px = -0x8000;
  3637             if (py > 0x7FFF) py = 0x7FFF;
  3644 	    if (py > 0x7FFF) py = 0x7FFF;
  3638             else if (py < -0x8000) py = -0x8000;
  3645 	    else if (py < -0x8000) py = -0x8000;
  3639 
  3646 
  3640             points[i].x = px;
  3647 	    points[i].x = px;
  3641             points[i].y = py;
  3648 	    points[i].y = py;
  3642             x = x + step;
  3649 	    x = x + step;
  3643         }
  3650 	}
  3644 
  3651 
  3645         ENTER_XLIB();
  3652 	ENTER_XLIB();
  3646         XDrawLines(myDpy, win, gc, points, num, CoordModeOrigin);
  3653 	XDrawLines(myDpy, win, gc, points, num, CoordModeOrigin);
  3647         LEAVE_XLIB();
  3654 	LEAVE_XLIB();
  3648 
  3655 
  3649         if( mustFree ) {
  3656 	if( mustFree ) {
  3650             free( points );
  3657 	    free( points );
  3651         }
  3658 	}
  3652         RETURN ( self );
  3659 	RETURN ( self );
  3653     }
  3660     }
  3654 
  3661 
  3655 fail:
  3662 fail:
  3656     if( mustFree )
  3663     if( mustFree )
  3657         free( points );
  3664 	free( points );
  3658 %}.
  3665 %}.
  3659     ^ super displayLinesFromX:startX step:stepX yValues:yValues scaleY:scaleY transY:transY in:aDrawableId with:aGCId
  3666     ^ super displayLinesFromX:startX step:stepX yValues:yValues scaleY:scaleY transY:transY in:aDrawableId with:aGCId
  3660 
  3667 
  3661     "Modified: / 13.6.1998 / 13:51:39 / cg"
  3668     "Modified: / 13.6.1998 / 13:51:39 / cg"
  3662 !
  3669 !
  3665     "draw a point. If x/y are not integers, an error is triggered."
  3672     "draw a point. If x/y are not integers, an error is triggered."
  3666 
  3673 
  3667     <context: #return>
  3674     <context: #return>
  3668 
  3675 
  3669     operationsUntilFlush notNil ifTrue:[
  3676     operationsUntilFlush notNil ifTrue:[
  3670         operationsUntilFlush <= 0 ifTrue:[
  3677 	operationsUntilFlush <= 0 ifTrue:[
  3671             self flush.
  3678 	    self flush.
  3672         ] ifFalse:[
  3679 	] ifFalse:[
  3673             operationsUntilFlush := operationsUntilFlush - 1.
  3680 	    operationsUntilFlush := operationsUntilFlush - 1.
  3674         ].
  3681 	].
  3675     ].
  3682     ].
  3676 %{
  3683 %{
  3677 
  3684 
  3678     GC gc;
  3685     GC gc;
  3679     Window win;
  3686     Window win;
  3680 
  3687 
  3681     if (ISCONNECTED
  3688     if (ISCONNECTED
  3682      && __isExternalAddress(aGCId)
  3689      && __isExternalAddress(aGCId)
  3683      && __isExternalAddress(aDrawableId)
  3690      && __isExternalAddress(aDrawableId)
  3684      && __bothSmallInteger(x, y)) {
  3691      && __bothSmallInteger(x, y)) {
  3685         int px, py;
  3692 	int px, py;
  3686 
  3693 
  3687         gc = __GCVal(aGCId);
  3694 	gc = __GCVal(aGCId);
  3688         win = __WindowVal(aDrawableId);
  3695 	win = __WindowVal(aDrawableId);
  3689 
  3696 
  3690         px = __intVal(x);
  3697 	px = __intVal(x);
  3691         py = __intVal(y);
  3698 	py = __intVal(y);
  3692         if (px > 0x7FFF) px = 0x7FFF;
  3699 	if (px > 0x7FFF) px = 0x7FFF;
  3693         else if (px < -0x8000) px = -0x8000;
  3700 	else if (px < -0x8000) px = -0x8000;
  3694         if (py > 0x7FFF) py = 0x7FFF;
  3701 	if (py > 0x7FFF) py = 0x7FFF;
  3695         else if (py < -0x8000) py = -0x8000;
  3702 	else if (py < -0x8000) py = -0x8000;
  3696 
  3703 
  3697         ENTER_XLIB();
  3704 	ENTER_XLIB();
  3698         XDrawPoint(myDpy, win, gc, px, py);
  3705 	XDrawPoint(myDpy, win, gc, px, py);
  3699         LEAVE_XLIB();
  3706 	LEAVE_XLIB();
  3700 
  3707 
  3701         RETURN ( self );
  3708 	RETURN ( self );
  3702     }
  3709     }
  3703 %}.
  3710 %}.
  3704     "badGC, badDrawable or x/y not integer"
  3711     "badGC, badDrawable or x/y not integer"
  3705     self primitiveFailedOrClosedConnection
  3712     self primitiveFailedOrClosedConnection
  3706 !
  3713 !
  3713     <context: #return>
  3720     <context: #return>
  3714 
  3721 
  3715     |numberOfPoints newPoints|
  3722     |numberOfPoints newPoints|
  3716 
  3723 
  3717     operationsUntilFlush notNil ifTrue:[
  3724     operationsUntilFlush notNil ifTrue:[
  3718         operationsUntilFlush <= 0 ifTrue:[
  3725 	operationsUntilFlush <= 0 ifTrue:[
  3719             self flush.
  3726 	    self flush.
  3720         ] ifFalse:[
  3727 	] ifFalse:[
  3721             operationsUntilFlush := operationsUntilFlush - 1.
  3728 	    operationsUntilFlush := operationsUntilFlush - 1.
  3722         ].
  3729 	].
  3723     ].
  3730     ].
  3724     numberOfPoints := aPolygon size.
  3731     numberOfPoints := aPolygon size.
  3725 %{
  3732 %{
  3726     GC gc;
  3733     GC gc;
  3727     Window win;
  3734     Window win;
  3733 
  3740 
  3734     if (ISCONNECTED
  3741     if (ISCONNECTED
  3735      && __isExternalAddress(aGCId)
  3742      && __isExternalAddress(aGCId)
  3736      && __isExternalAddress(aDrawableId)
  3743      && __isExternalAddress(aDrawableId)
  3737      && __isSmallInteger(numberOfPoints)) {
  3744      && __isSmallInteger(numberOfPoints)) {
  3738         gc = __GCVal(aGCId);
  3745 	gc = __GCVal(aGCId);
  3739         win = __WindowVal(aDrawableId);
  3746 	win = __WindowVal(aDrawableId);
  3740         num = __intVal(numberOfPoints);
  3747 	num = __intVal(numberOfPoints);
  3741         /*
  3748 	/*
  3742          * avoid a (slow) malloc, if the number of points is small
  3749 	 * avoid a (slow) malloc, if the number of points is small
  3743          */
  3750 	 */
  3744         if (num > 100) {
  3751 	if (num > 100) {
  3745             points = (XPoint *)malloc(sizeof(XPoint) * num);
  3752 	    points = (XPoint *)malloc(sizeof(XPoint) * num);
  3746             if (! points) goto fail;
  3753 	    if (! points) goto fail;
  3747             mustFree = 1;
  3754 	    mustFree = 1;
  3748         } else
  3755 	} else
  3749             points = qPoints;
  3756 	    points = qPoints;
  3750 
  3757 
  3751         for (i=0; i<num; i++) {
  3758 	for (i=0; i<num; i++) {
  3752             int px, py;
  3759 	    int px, py;
  3753 
  3760 
  3754             point = __AT_(aPolygon, __MKSMALLINT(i+1));
  3761 	    point = __AT_(aPolygon, __MKSMALLINT(i+1));
  3755             if (! __isPoint(point)) goto fail;
  3762 	    if (! __isPoint(point)) goto fail;
  3756             x = _point_X(point);
  3763 	    x = _point_X(point);
  3757             y = _point_Y(point);
  3764 	    y = _point_Y(point);
  3758             if (! __bothSmallInteger(x, y))
  3765 	    if (! __bothSmallInteger(x, y))
  3759                 goto fail;
  3766 		goto fail;
  3760 
  3767 
  3761             px = __intVal(x);
  3768 	    px = __intVal(x);
  3762             py = __intVal(y);
  3769 	    py = __intVal(y);
  3763 
  3770 
  3764             /* attention: coordinates in X are shorts and wrap; clamp here. */
  3771 	    /* attention: coordinates in X are shorts and wrap; clamp here. */
  3765             if (px > 0x7FFF) px = 0x7FFF;
  3772 	    if (px > 0x7FFF) px = 0x7FFF;
  3766             else if (px < -0x8000) px = -0x8000;
  3773 	    else if (px < -0x8000) px = -0x8000;
  3767             if (py > 0x7FFF) py = 0x7FFF;
  3774 	    if (py > 0x7FFF) py = 0x7FFF;
  3768             else if (py < -0x8000) py = -0x8000;
  3775 	    else if (py < -0x8000) py = -0x8000;
  3769 
  3776 
  3770             points[i].x = px;
  3777 	    points[i].x = px;
  3771             points[i].y = py;
  3778 	    points[i].y = py;
  3772         }
  3779 	}
  3773 
  3780 
  3774         ENTER_XLIB();
  3781 	ENTER_XLIB();
  3775         XDrawLines(myDpy, win, gc, points, num, CoordModeOrigin);
  3782 	XDrawLines(myDpy, win, gc, points, num, CoordModeOrigin);
  3776         LEAVE_XLIB();
  3783 	LEAVE_XLIB();
  3777 
  3784 
  3778         if (mustFree)
  3785 	if (mustFree)
  3779             free(points);
  3786 	    free(points);
  3780         RETURN ( self );
  3787 	RETURN ( self );
  3781     }
  3788     }
  3782 fail: ;
  3789 fail: ;
  3783     if (mustFree)
  3790     if (mustFree)
  3784         free(points);
  3791 	free(points);
  3785 %}.
  3792 %}.
  3786     "badGC, badDrawable or coordinates not integer"
  3793     "badGC, badDrawable or coordinates not integer"
  3787     self primitiveFailedOrClosedConnection
  3794     self primitiveFailedOrClosedConnection
  3788 !
  3795 !
  3789 
  3796 
  3791     "draw a rectangle. If the coordinates are not integers, an error is triggered."
  3798     "draw a rectangle. If the coordinates are not integers, an error is triggered."
  3792 
  3799 
  3793     <context: #return>
  3800     <context: #return>
  3794 
  3801 
  3795     operationsUntilFlush notNil ifTrue:[
  3802     operationsUntilFlush notNil ifTrue:[
  3796         operationsUntilFlush <= 0 ifTrue:[
  3803 	operationsUntilFlush <= 0 ifTrue:[
  3797             self flush.
  3804 	    self flush.
  3798         ] ifFalse:[
  3805 	] ifFalse:[
  3799             operationsUntilFlush := operationsUntilFlush - 1.
  3806 	    operationsUntilFlush := operationsUntilFlush - 1.
  3800         ].
  3807 	].
  3801     ].
  3808     ].
  3802 %{
  3809 %{
  3803 
  3810 
  3804     GC gc;
  3811     GC gc;
  3805     Window win;
  3812     Window win;
  3808     if (ISCONNECTED
  3815     if (ISCONNECTED
  3809      && __isExternalAddress(aGCId)
  3816      && __isExternalAddress(aGCId)
  3810      && __isExternalAddress(aDrawableId)
  3817      && __isExternalAddress(aDrawableId)
  3811      && __bothSmallInteger(x, y)
  3818      && __bothSmallInteger(x, y)
  3812      && __bothSmallInteger(width, height)) {
  3819      && __bothSmallInteger(width, height)) {
  3813         int px, py;
  3820 	int px, py;
  3814 
  3821 
  3815         gc = __GCVal(aGCId);
  3822 	gc = __GCVal(aGCId);
  3816         win = __WindowVal(aDrawableId);
  3823 	win = __WindowVal(aDrawableId);
  3817         w = __intVal(width);
  3824 	w = __intVal(width);
  3818         h = __intVal(height);
  3825 	h = __intVal(height);
  3819 
  3826 
  3820         /*
  3827 	/*
  3821          * need this check here: some servers simply dump core with bad args
  3828 	 * need this check here: some servers simply dump core with bad args
  3822          */
  3829 	 */
  3823         if ((w >= 0) && (h >= 0)) {
  3830 	if ((w >= 0) && (h >= 0)) {
  3824             px = __intVal(x);
  3831 	    px = __intVal(x);
  3825             py = __intVal(y);
  3832 	    py = __intVal(y);
  3826 
  3833 
  3827             /* attention: coordinates in X are shorts and wrap; clamp here. */
  3834 	    /* attention: coordinates in X are shorts and wrap; clamp here. */
  3828             if (px > 0x7FFF) px = 0x7FFF;
  3835 	    if (px > 0x7FFF) px = 0x7FFF;
  3829             else if (px < -0x8000) px = -0x8000;
  3836 	    else if (px < -0x8000) px = -0x8000;
  3830             if (py > 0x7FFF) py = 0x7FFF;
  3837 	    if (py > 0x7FFF) py = 0x7FFF;
  3831             else if (py < -0x8000) py = -0x8000;
  3838 	    else if (py < -0x8000) py = -0x8000;
  3832 
  3839 
  3833             ENTER_XLIB();
  3840 	    ENTER_XLIB();
  3834             XDrawRectangle(myDpy, win, gc, px, py, w, h);
  3841 	    XDrawRectangle(myDpy, win, gc, px, py, w, h);
  3835             LEAVE_XLIB();
  3842 	    LEAVE_XLIB();
  3836         }
  3843 	}
  3837         RETURN ( self );
  3844 	RETURN ( self );
  3838     }
  3845     }
  3839 %}.
  3846 %}.
  3840     "badGC, badDrawable or coordinates not integer"
  3847     "badGC, badDrawable or coordinates not integer"
  3841     self primitiveFailedOrClosedConnection
  3848     self primitiveFailedOrClosedConnection
  3842 !
  3849 !
  3847      If the coordinates are not integers, an error is triggered."
  3854      If the coordinates are not integers, an error is triggered."
  3848 
  3855 
  3849     <context: #return>
  3856     <context: #return>
  3850 
  3857 
  3851     operationsUntilFlush notNil ifTrue:[
  3858     operationsUntilFlush notNil ifTrue:[
  3852         operationsUntilFlush <= 0 ifTrue:[
  3859 	operationsUntilFlush <= 0 ifTrue:[
  3853             self flush.
  3860 	    self flush.
  3854         ] ifFalse:[
  3861 	] ifFalse:[
  3855             operationsUntilFlush := operationsUntilFlush - 1.
  3862 	    operationsUntilFlush := operationsUntilFlush - 1.
  3856         ].
  3863 	].
  3857     ].
  3864     ].
  3858 %{
  3865 %{
  3859 
  3866 
  3860     GC gc;
  3867     GC gc;
  3861     Window win;
  3868     Window win;
  3869      && __isExternalAddress(aGCId)
  3876      && __isExternalAddress(aGCId)
  3870      && __isExternalAddress(aDrawableId)
  3877      && __isExternalAddress(aDrawableId)
  3871      && __isNonNilObject(aString)
  3878      && __isNonNilObject(aString)
  3872      && __bothSmallInteger(index1, index2)
  3879      && __bothSmallInteger(index1, index2)
  3873      && __bothSmallInteger(x, y)) {
  3880      && __bothSmallInteger(x, y)) {
  3874         int lMax = __intVal(@global(MaxStringLength));
  3881 	int lMax = __intVal(@global(MaxStringLength));
  3875         Display *dpy = myDpy;
  3882 	Display *dpy = myDpy;
  3876         gc = __GCVal(aGCId);
  3883 	gc = __GCVal(aGCId);
  3877         win = __WindowVal(aDrawableId);
  3884 	win = __WindowVal(aDrawableId);
  3878 
  3885 
  3879         i1 = __intVal(index1) - 1;
  3886 	i1 = __intVal(index1) - 1;
  3880         if (i1 >= 0) {
  3887 	if (i1 >= 0) {
  3881             OBJ cls;
  3888 	    OBJ cls;
  3882 
  3889 
  3883             i2 = __intVal(index2) - 1;
  3890 	    i2 = __intVal(index2) - 1;
  3884             if (i2 < i1) {
  3891 	    if (i2 < i1) {
  3885                 RETURN (self);
  3892 		RETURN (self);
  3886             }
  3893 	    }
  3887 
  3894 
  3888             cp = (char *) __stringVal(aString);
  3895 	    cp = (char *) __stringVal(aString);
  3889             l = i2 - i1 + 1;
  3896 	    l = i2 - i1 + 1;
  3890 
  3897 
  3891             if (__isStringLike(aString)) {
  3898 	    if (__isStringLike(aString)) {
  3892                 n = __stringSize(aString);
  3899 		n = __stringSize(aString);
  3893                 if (i2 < n) {
  3900 		if (i2 < n) {
  3894                     cp += i1;
  3901 		    cp += i1;
  3895                     if (l > lMax) l = lMax;
  3902 		    if (l > lMax) l = lMax;
  3896                     ENTER_XLIB();
  3903 		    ENTER_XLIB();
  3897                     if (opaque == true)
  3904 		    if (opaque == true)
  3898                         XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
  3905 			XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
  3899                     else
  3906 		    else
  3900                         XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
  3907 			XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
  3901                     LEAVE_XLIB();
  3908 		    LEAVE_XLIB();
  3902                     RETURN ( self );
  3909 		    RETURN ( self );
  3903                 }
  3910 		}
  3904             }
  3911 	    }
  3905 
  3912 
  3906             cls = __qClass(aString);
  3913 	    cls = __qClass(aString);
  3907             nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  3914 	    nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  3908             cp += nInstBytes;
  3915 	    cp += nInstBytes;
  3909 
  3916 
  3910             if (__isBytes(aString)) {
  3917 	    if (__isBytes(aString)) {
  3911                 n = __byteArraySize(aString) - nInstBytes - 1;
  3918 		n = __byteArraySize(aString) - nInstBytes - 1;
  3912 
  3919 
  3913                 if (i2 < n) {
  3920 		if (i2 < n) {
  3914                     cp += i1;
  3921 		    cp += i1;
  3915                     if (l > lMax) l = lMax;
  3922 		    if (l > lMax) l = lMax;
  3916                     ENTER_XLIB();
  3923 		    ENTER_XLIB();
  3917                     if (opaque == true)
  3924 		    if (opaque == true)
  3918                         XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
  3925 			XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
  3919                     else
  3926 		    else
  3920                         XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
  3927 			XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, l);
  3921                     LEAVE_XLIB();
  3928 		    LEAVE_XLIB();
  3922                     RETURN ( self );
  3929 		    RETURN ( self );
  3923                 }
  3930 		}
  3924             }
  3931 	    }
  3925 
  3932 
  3926             /* TWOBYTESTRINGS */
  3933 	    /* TWOBYTESTRINGS */
  3927             if (__isWords(aString)) {
  3934 	    if (__isWords(aString)) {
  3928                 n = (__byteArraySize(aString) - nInstBytes) / 2;
  3935 		n = (__byteArraySize(aString) - nInstBytes) / 2;
  3929                 if (i2 < n) {
  3936 		if (i2 < n) {
  3930                     union {
  3937 		    union {
  3931                         char b[2];
  3938 			char b[2];
  3932                         unsigned short s;
  3939 			unsigned short s;
  3933                     } u;
  3940 		    } u;
  3934                     int i;
  3941 		    int i;
  3935                     XChar2b *cp2 = (XChar2b *)0;
  3942 		    XChar2b *cp2 = (XChar2b *)0;
  3936                     int mustFree = 0;
  3943 		    int mustFree = 0;
  3937 
  3944 
  3938                     cp += (i1 * 2);
  3945 		    cp += (i1 * 2);
  3939                     if (l > lMax) l = lMax;
  3946 		    if (l > lMax) l = lMax;
  3940 
  3947 
  3941 #if defined(MSBFIRST) || defined(__MSBFIRST)
  3948 #if defined(MSBFIRST) || defined(__MSBFIRST)
  3942                     /*
  3949 		    /*
  3943                      * chars already in correct order
  3950 		     * chars already in correct order
  3944                      */
  3951 		     */
  3945 #else
  3952 #else
  3946 # if ! (defined(LSBFIRST) || defined(__LSBFIRST))
  3953 # if ! (defined(LSBFIRST) || defined(__LSBFIRST))
  3947                     /*
  3954 		    /*
  3948                      * ST/X TwoByteStrings store the asciiValue in native byteOrder;
  3955 		     * ST/X TwoByteStrings store the asciiValue in native byteOrder;
  3949                      * X expects them MSB first
  3956 		     * X expects them MSB first
  3950                      * convert as required
  3957 		     * convert as required
  3951                      */
  3958 		     */
  3952                     u.s = 0x1234;
  3959 		    u.s = 0x1234;
  3953                     if (u.b[0] != 0x12)
  3960 		    if (u.b[0] != 0x12)
  3954 # endif
  3961 # endif
  3955                     {
  3962 		    {
  3956                         if (l <= NLOCALBUFFER) {
  3963 			if (l <= NLOCALBUFFER) {
  3957                             cp2 = xlatebuffer;
  3964 			    cp2 = xlatebuffer;
  3958                         } else {
  3965 			} else {
  3959                             cp2 = (XChar2b *)(malloc(l * 2));
  3966 			    cp2 = (XChar2b *)(malloc(l * 2));
  3960                             mustFree = 1;
  3967 			    mustFree = 1;
  3961                         }
  3968 			}
  3962                         for (i=0; i<l; i++) {
  3969 			for (i=0; i<l; i++) {
  3963                             cp2[i].byte1 = (((XChar2b *)cp)[i]).byte2;
  3970 			    cp2[i].byte1 = (((XChar2b *)cp)[i]).byte2;
  3964                             cp2[i].byte2 = (((XChar2b *)cp)[i]).byte1;
  3971 			    cp2[i].byte2 = (((XChar2b *)cp)[i]).byte1;
  3965                         }
  3972 			}
  3966                         cp = (char *) cp2;
  3973 			cp = (char *) cp2;
  3967                     }
  3974 		    }
  3968 #endif
  3975 #endif
  3969                     ENTER_XLIB();
  3976 		    ENTER_XLIB();
  3970                     if (opaque == true)
  3977 		    if (opaque == true)
  3971                         XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
  3978 			XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
  3972                     else
  3979 		    else
  3973                         XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
  3980 			XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
  3974                     LEAVE_XLIB();
  3981 		    LEAVE_XLIB();
  3975 
  3982 
  3976                     if (mustFree) {
  3983 		    if (mustFree) {
  3977                         free(cp2);
  3984 			free(cp2);
  3978                     }
  3985 		    }
  3979 
  3986 
  3980                     RETURN ( self );
  3987 		    RETURN ( self );
  3981                 }
  3988 		}
  3982             }
  3989 	    }
  3983 
  3990 
  3984             /* FOURBYTESTRINGS */
  3991 	    /* FOURBYTESTRINGS */
  3985             if (__isLongs(aString)) {
  3992 	    if (__isLongs(aString)) {
  3986                 n = (__byteArraySize(aString) - nInstBytes) / 4;
  3993 		n = (__byteArraySize(aString) - nInstBytes) / 4;
  3987                 if (i2 < n) {
  3994 		if (i2 < n) {
  3988                     union {
  3995 		    union {
  3989                         char b[2];
  3996 			char b[2];
  3990                         unsigned short s;
  3997 			unsigned short s;
  3991                     } u;
  3998 		    } u;
  3992                     int i;
  3999 		    int i;
  3993                     XChar2b *cp2 = (XChar2b *)0;
  4000 		    XChar2b *cp2 = (XChar2b *)0;
  3994                     int32 *ip;
  4001 		    int32 *ip;
  3995                     int mustFree = 0;
  4002 		    int mustFree = 0;
  3996 
  4003 
  3997                     cp += (i1 * 4);
  4004 		    cp += (i1 * 4);
  3998                     if (l > lMax) l = lMax;
  4005 		    if (l > lMax) l = lMax;
  3999 
  4006 
  4000                     /*
  4007 		    /*
  4001                      * all codePoints <= 16rFFFF are draw; above 16bit range are drawn as 16rFFFF.
  4008 		     * all codePoints <= 16rFFFF are draw; above 16bit range are drawn as 16rFFFF.
  4002                      */
  4009 		     */
  4003                     if (l <= NLOCALBUFFER) {
  4010 		    if (l <= NLOCALBUFFER) {
  4004                         cp2 = xlatebuffer;
  4011 			cp2 = xlatebuffer;
  4005                     } else {
  4012 		    } else {
  4006                         cp2 = (XChar2b *)(malloc(l * 2));
  4013 			cp2 = (XChar2b *)(malloc(l * 2));
  4007                         mustFree = 1;
  4014 			mustFree = 1;
  4008                     }
  4015 		    }
  4009                     for (i=0; i<l; i++) {
  4016 		    for (i=0; i<l; i++) {
  4010                         int32 codePoint = ((int32 *)cp)[i];
  4017 			int32 codePoint = ((int32 *)cp)[i];
  4011 
  4018 
  4012                         if (codePoint > 0xFFFF) {
  4019 			if (codePoint > 0xFFFF) {
  4013                             codePoint = 0xFFFF;
  4020 			    codePoint = 0xFFFF;
  4014                         }
  4021 			}
  4015                         cp2[i].byte1 = (codePoint >> 8) & 0xFF;
  4022 			cp2[i].byte1 = (codePoint >> 8) & 0xFF;
  4016                         cp2[i].byte2 = codePoint & 0xFF;
  4023 			cp2[i].byte2 = codePoint & 0xFF;
  4017                     }
  4024 		    }
  4018                     cp = (char *) cp2;
  4025 		    cp = (char *) cp2;
  4019 
  4026 
  4020                     ENTER_XLIB();
  4027 		    ENTER_XLIB();
  4021                     if (opaque == true)
  4028 		    if (opaque == true)
  4022                         XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
  4029 			XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
  4023                     else
  4030 		    else
  4024                         XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
  4031 			XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, l);
  4025                     LEAVE_XLIB();
  4032 		    LEAVE_XLIB();
  4026 
  4033 
  4027                     if (mustFree) {
  4034 		    if (mustFree) {
  4028                         free(cp2);
  4035 			free(cp2);
  4029                     }
  4036 		    }
  4030 
  4037 
  4031                     RETURN ( self );
  4038 		    RETURN ( self );
  4032                 }
  4039 		}
  4033             }
  4040 	    }
  4034         }
  4041 	}
  4035     }
  4042     }
  4036 #undef NLOCALBUFFER
  4043 #undef NLOCALBUFFER
  4037 %}.
  4044 %}.
  4038     (aString isString and:[aString bitsPerCharacter > 16]) ifTrue:[
  4045     (aString isString and:[aString bitsPerCharacter > 16]) ifTrue:[
  4039         self displayString:(TwoByteString new:aString size withAll:16rFFFF asCharacter)
  4046 	self displayString:(TwoByteString new:aString size withAll:16rFFFF asCharacter)
  4040              from:index1 to:index2 x:x y:y in:aDrawableId with:aGCId opaque:opaque.
  4047 	     from:index1 to:index2 x:x y:y in:aDrawableId with:aGCId opaque:opaque.
  4041         ^ self.
  4048 	^ self.
  4042     ].
  4049     ].
  4043 
  4050 
  4044     "x/y not integer, badGC or drawable, or not a string"
  4051     "x/y not integer, badGC or drawable, or not a string"
  4045     self primitiveFailedOrClosedConnection
  4052     self primitiveFailedOrClosedConnection
  4046 !
  4053 !
  4051      If the coordinates are not integers, an error is triggered."
  4058      If the coordinates are not integers, an error is triggered."
  4052 
  4059 
  4053     <context: #return>
  4060     <context: #return>
  4054 
  4061 
  4055     operationsUntilFlush notNil ifTrue:[
  4062     operationsUntilFlush notNil ifTrue:[
  4056         operationsUntilFlush <= 0 ifTrue:[
  4063 	operationsUntilFlush <= 0 ifTrue:[
  4057             self flush.
  4064 	    self flush.
  4058         ] ifFalse:[
  4065 	] ifFalse:[
  4059             operationsUntilFlush := operationsUntilFlush - 1.
  4066 	    operationsUntilFlush := operationsUntilFlush - 1.
  4060         ].
  4067 	].
  4061     ].
  4068     ].
  4062 %{
  4069 %{
  4063 
  4070 
  4064     GC gc;
  4071     GC gc;
  4065     Window win;
  4072     Window win;
  4073     if (ISCONNECTED
  4080     if (ISCONNECTED
  4074      && __isExternalAddress(aGCId)
  4081      && __isExternalAddress(aGCId)
  4075      && __isExternalAddress(aDrawableId)
  4082      && __isExternalAddress(aDrawableId)
  4076      && __isNonNilObject(aString)
  4083      && __isNonNilObject(aString)
  4077      && __bothSmallInteger(x, y)) {
  4084      && __bothSmallInteger(x, y)) {
  4078         int lMax = __intVal(@global(MaxStringLength));
  4085 	int lMax = __intVal(@global(MaxStringLength));
  4079         Display *dpy = myDpy;
  4086 	Display *dpy = myDpy;
  4080         gc = __GCVal(aGCId);
  4087 	gc = __GCVal(aGCId);
  4081         win = __WindowVal(aDrawableId);
  4088 	win = __WindowVal(aDrawableId);
  4082 
  4089 
  4083         cp = (char *) __stringVal(aString);
  4090 	cp = (char *) __stringVal(aString);
  4084 
  4091 
  4085         if (__isStringLike(aString)) {
  4092 	if (__isStringLike(aString)) {
  4086             n = __stringSize(aString);
  4093 	    n = __stringSize(aString);
  4087             if (n > lMax) n = lMax;
  4094 	    if (n > lMax) n = lMax;
  4088             ENTER_XLIB();
  4095 	    ENTER_XLIB();
  4089             if (opaque == true)
  4096 	    if (opaque == true)
  4090                 XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
  4097 		XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
  4091             else
  4098 	    else
  4092                 XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
  4099 		XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
  4093             LEAVE_XLIB();
  4100 	    LEAVE_XLIB();
  4094             RETURN ( self );
  4101 	    RETURN ( self );
  4095         }
  4102 	}
  4096 
  4103 
  4097         cls = __qClass(aString);
  4104 	cls = __qClass(aString);
  4098         nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  4105 	nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  4099         cp += nInstBytes;
  4106 	cp += nInstBytes;
  4100 
  4107 
  4101         if (__isBytes(aString)) {
  4108 	if (__isBytes(aString)) {
  4102             n = __byteArraySize(aString) - nInstBytes - 1;
  4109 	    n = __byteArraySize(aString) - nInstBytes - 1;
  4103 
  4110 
  4104             if (n > lMax) n = lMax;
  4111 	    if (n > lMax) n = lMax;
  4105             ENTER_XLIB();
  4112 	    ENTER_XLIB();
  4106             if (opaque == true)
  4113 	    if (opaque == true)
  4107                 XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
  4114 		XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
  4108             else
  4115 	    else
  4109                 XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
  4116 		XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
  4110             LEAVE_XLIB();
  4117 	    LEAVE_XLIB();
  4111             RETURN ( self );
  4118 	    RETURN ( self );
  4112         }
  4119 	}
  4113 
  4120 
  4114         /* TWOBYTESTRINGS */
  4121 	/* TWOBYTESTRINGS */
  4115         if (__isWords(aString)) {
  4122 	if (__isWords(aString)) {
  4116             union {
  4123 	    union {
  4117                 char b[2];
  4124 		char b[2];
  4118                 unsigned short s;
  4125 		unsigned short s;
  4119             } u;
  4126 	    } u;
  4120             int i;
  4127 	    int i;
  4121             XChar2b *cp2;
  4128 	    XChar2b *cp2;
  4122             int mustFree = 0;
  4129 	    int mustFree = 0;
  4123 
  4130 
  4124             n = (__byteArraySize(aString) - nInstBytes) / 2;
  4131 	    n = (__byteArraySize(aString) - nInstBytes) / 2;
  4125             if (n > lMax) n = lMax;
  4132 	    if (n > lMax) n = lMax;
  4126 
  4133 
  4127 #if defined(MSBFIRST) || defined(__MSBFIRST)
  4134 #if defined(MSBFIRST) || defined(__MSBFIRST)
  4128             /*
  4135 	    /*
  4129              * chars already in correct order
  4136 	     * chars already in correct order
  4130              */
  4137 	     */
  4131 #else
  4138 #else
  4132 # if ! (defined(LSBFIRST) || defined(__LSBFIRST))
  4139 # if ! (defined(LSBFIRST) || defined(__LSBFIRST))
  4133             /*
  4140 	    /*
  4134              * ST/X TwoByteStrings store the asciiValue in native byteOrder;
  4141 	     * ST/X TwoByteStrings store the asciiValue in native byteOrder;
  4135              * X expects them MSB first
  4142 	     * X expects them MSB first
  4136              * convert as required
  4143 	     * convert as required
  4137              */
  4144 	     */
  4138             u.s = 0x1234;
  4145 	    u.s = 0x1234;
  4139             if (u.b[0] != 0x12)
  4146 	    if (u.b[0] != 0x12)
  4140 # endif
  4147 # endif
  4141             {
  4148 	    {
  4142                 if (n <= NLOCALBUFFER) {
  4149 		if (n <= NLOCALBUFFER) {
  4143                     cp2 = xlatebuffer;
  4150 		    cp2 = xlatebuffer;
  4144                 } else {
  4151 		} else {
  4145                     cp2 = (XChar2b *)(malloc(n * 2));
  4152 		    cp2 = (XChar2b *)(malloc(n * 2));
  4146                     mustFree = 1;
  4153 		    mustFree = 1;
  4147                 }
  4154 		}
  4148 
  4155 
  4149                 for (i=0; i<n; i++) {
  4156 		for (i=0; i<n; i++) {
  4150                     cp2[i].byte1 = (((XChar2b *)cp)[i]).byte2;
  4157 		    cp2[i].byte1 = (((XChar2b *)cp)[i]).byte2;
  4151                     cp2[i].byte2 = (((XChar2b *)cp)[i]).byte1;
  4158 		    cp2[i].byte2 = (((XChar2b *)cp)[i]).byte1;
  4152                 }
  4159 		}
  4153                 cp = (char *) cp2;
  4160 		cp = (char *) cp2;
  4154             }
  4161 	    }
  4155 #endif
  4162 #endif
  4156             ENTER_XLIB();
  4163 	    ENTER_XLIB();
  4157             if (opaque == true)
  4164 	    if (opaque == true)
  4158                 XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, n);
  4165 		XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, n);
  4159             else
  4166 	    else
  4160                 XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, n);
  4167 		XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, n);
  4161             LEAVE_XLIB();
  4168 	    LEAVE_XLIB();
  4162 
  4169 
  4163 
  4170 
  4164             if (mustFree) {
  4171 	    if (mustFree) {
  4165                 free(cp2);
  4172 		free(cp2);
  4166             }
  4173 	    }
  4167 
  4174 
  4168             RETURN ( self );
  4175 	    RETURN ( self );
  4169         }
  4176 	}
  4170     }
  4177     }
  4171 #undef NLOCALBUFFER
  4178 #undef NLOCALBUFFER
  4172 %}.
  4179 %}.
  4173     ^ super displayString:aString x:x y:y in:aDrawableId with:aGCId opaque:opaque
  4180     ^ super displayString:aString x:x y:y in:aDrawableId with:aGCId opaque:opaque
  4174 !
  4181 !
  4175 
  4182 
  4176 drawBits:givenBits bitsPerPixel:bitsPerPixel depth:imageDepth padding:givenPadding
  4183 drawBits:givenBits bitsPerPixel:bitsPerPixel depth:imageDepth padding:givenPadding
  4177         width:imageWidth height:imageHeight
  4184 	width:imageWidth height:imageHeight
  4178         x:srcx y:srcy
  4185 	x:srcx y:srcy
  4179         into:aDrawableId
  4186 	into:aDrawableId
  4180         x:dstx y:dsty
  4187 	x:dstx y:dsty
  4181         width:w height:h
  4188 	width:w height:h
  4182         with:aGCId
  4189 	with:aGCId
  4183 
  4190 
  4184     "draw a bitImage which has depth id, width iw and height ih into
  4191     "draw a bitImage which has depth id, width iw and height ih into
  4185      the drawable. draw a region of w/h pixels from srcx/srcy to dstx/dsty.
  4192      the drawable. draw a region of w/h pixels from srcx/srcy to dstx/dsty.
  4186      Individual source pixels have bitsPerPixel bits, allowing to draw
  4193      Individual source pixels have bitsPerPixel bits, allowing to draw
  4187      depth and pixel-units to be different.
  4194      depth and pixel-units to be different.
  4199     "/ 8-bit padded image. (it wants it 32bit padded).
  4206     "/ 8-bit padded image. (it wants it 32bit padded).
  4200     "/ as a workaround, repad it here (although, the server and/or Xlib should
  4207     "/ as a workaround, repad it here (although, the server and/or Xlib should
  4201     "/ care for that.
  4208     "/ care for that.
  4202 
  4209 
  4203     ((imageDepth == 4) and:[depth == 4]) ifTrue:[
  4210     ((imageDepth == 4) and:[depth == 4]) ifTrue:[
  4204         fmt := self supportedImageFormatForDepth:4.
  4211 	fmt := self supportedImageFormatForDepth:4.
  4205         fmt isNil ifTrue:[
  4212 	fmt isNil ifTrue:[
  4206             self primitiveFailed. "/ cannot represent this image
  4213 	    self primitiveFailed. "/ cannot represent this image
  4207             ^ nil
  4214 	    ^ nil
  4208         ].
  4215 	].
  4209         wantedPadding := fmt at:#padding.
  4216 	wantedPadding := fmt at:#padding.
  4210         wantedPadding > givenPadding ifTrue:[
  4217 	wantedPadding > givenPadding ifTrue:[
  4211             bits := self
  4218 	    bits := self
  4212                             repadBits:givenBits
  4219 			    repadBits:givenBits
  4213                             width:imageWidth
  4220 			    width:imageWidth
  4214                             height:imageHeight
  4221 			    height:imageHeight
  4215                             depth:imageDepth
  4222 			    depth:imageDepth
  4216                             from:givenPadding
  4223 			    from:givenPadding
  4217                             to:wantedPadding.
  4224 			    to:wantedPadding.
  4218             padding := wantedPadding.
  4225 	    padding := wantedPadding.
  4219         ]
  4226 	]
  4220     ].
  4227     ].
  4221 
  4228 
  4222 
  4229 
  4223     operationsUntilFlush notNil ifTrue:[
  4230     operationsUntilFlush notNil ifTrue:[
  4224         operationsUntilFlush <= 0 ifTrue:[
  4231 	operationsUntilFlush <= 0 ifTrue:[
  4225             self flush.
  4232 	    self flush.
  4226         ] ifFalse:[
  4233 	] ifFalse:[
  4227             operationsUntilFlush := operationsUntilFlush - 1.
  4234 	    operationsUntilFlush := operationsUntilFlush - 1.
  4228         ].
  4235 	].
  4229     ].
  4236     ].
  4230     "
  4237     "
  4231      sorry; I had to separate it into 2 methods, since XPutImage needs
  4238      sorry; I had to separate it into 2 methods, since XPutImage needs
  4232      an unlimited stack, and thus cannot send primitiveFailed
  4239      an unlimited stack, and thus cannot send primitiveFailed
  4233     "
  4240     "
  4234     (self
  4241     (self
  4235         primDrawBits:bits
  4242 	primDrawBits:bits
  4236         bitsPerPixel:bitsPerPixel
  4243 	bitsPerPixel:bitsPerPixel
  4237         depth:imageDepth
  4244 	depth:imageDepth
  4238         msb:true
  4245 	msb:true
  4239         padding:padding
  4246 	padding:padding
  4240         width:imageWidth height:imageHeight
  4247 	width:imageWidth height:imageHeight
  4241         x:srcx y:srcy
  4248 	x:srcx y:srcy
  4242         into:aDrawableId
  4249 	into:aDrawableId
  4243         x:dstx y:dsty
  4250 	x:dstx y:dsty
  4244         width:w height:h
  4251 	width:w height:h
  4245         with:aGCId)
  4252 	with:aGCId)
  4246     ifFalse:[
  4253     ifFalse:[
  4247         "
  4254 	"
  4248          also happens, if a segmentation violation occurs in the
  4255 	 also happens, if a segmentation violation occurs in the
  4249          XPutImage ...
  4256 	 XPutImage ...
  4250         "
  4257 	"
  4251         self primitiveFailedOrClosedConnection
  4258 	self primitiveFailedOrClosedConnection
  4252     ].
  4259     ].
  4253 !
  4260 !
  4254 
  4261 
  4255 fillArcX:x y:y width:width height:height from:startAngle angle:angle
  4262 fillArcX:x y:y width:width height:height from:startAngle angle:angle
  4256                in:aDrawableId with:aGCId
  4263 	       in:aDrawableId with:aGCId
  4257     "fill an arc. If any coordinate is not integer, an error is triggered.
  4264     "fill an arc. If any coordinate is not integer, an error is triggered.
  4258      The angles may be floats or integer - they are given in degrees."
  4265      The angles may be floats or integer - they are given in degrees."
  4259 
  4266 
  4260     <context: #return>
  4267     <context: #return>
  4261 
  4268 
  4262     operationsUntilFlush notNil ifTrue:[
  4269     operationsUntilFlush notNil ifTrue:[
  4263         operationsUntilFlush <= 0 ifTrue:[
  4270 	operationsUntilFlush <= 0 ifTrue:[
  4264             self flush.
  4271 	    self flush.
  4265         ] ifFalse:[
  4272 	] ifFalse:[
  4266             operationsUntilFlush := operationsUntilFlush - 1.
  4273 	    operationsUntilFlush := operationsUntilFlush - 1.
  4267         ].
  4274 	].
  4268     ].
  4275     ].
  4269 %{
  4276 %{
  4270 
  4277 
  4271     GC gc;
  4278     GC gc;
  4272     Window win;
  4279     Window win;
  4273     int w, h, angle1, angle2;
  4280     int w, h, angle1, angle2;
  4274     double f;
  4281     double f;
  4275 
  4282 
  4276     if (__isSmallInteger(startAngle))
  4283     if (__isSmallInteger(startAngle))
  4277         angle1 = __intVal(startAngle) * 64;
  4284 	angle1 = __intVal(startAngle) * 64;
  4278     else if (__isFloat(startAngle)) {
  4285     else if (__isFloat(startAngle)) {
  4279         f = __floatVal(startAngle);
  4286 	f = __floatVal(startAngle);
  4280         angle1 = f * 64;
  4287 	angle1 = f * 64;
  4281     } else if (__isShortFloat(startAngle)) {
  4288     } else if (__isShortFloat(startAngle)) {
  4282         f = __shortFloatVal(startAngle);
  4289 	f = __shortFloatVal(startAngle);
  4283         angle1 = f * 64;
  4290 	angle1 = f * 64;
  4284     } else goto bad;
  4291     } else goto bad;
  4285 
  4292 
  4286     if (__isSmallInteger(angle))
  4293     if (__isSmallInteger(angle))
  4287         angle2 = __intVal(angle) * 64;
  4294 	angle2 = __intVal(angle) * 64;
  4288     else if (__isFloat(angle)) {
  4295     else if (__isFloat(angle)) {
  4289         f = __floatVal(angle);
  4296 	f = __floatVal(angle);
  4290         angle2 = f * 64;
  4297 	angle2 = f * 64;
  4291     } else if (__isShortFloat(angle)) {
  4298     } else if (__isShortFloat(angle)) {
  4292         f = __shortFloatVal(angle);
  4299 	f = __shortFloatVal(angle);
  4293         angle2 = f * 64;
  4300 	angle2 = f * 64;
  4294     } else goto bad;
  4301     } else goto bad;
  4295 
  4302 
  4296     if (ISCONNECTED
  4303     if (ISCONNECTED
  4297      && __isExternalAddress(aGCId)
  4304      && __isExternalAddress(aGCId)
  4298      && __isExternalAddress(aDrawableId)
  4305      && __isExternalAddress(aDrawableId)
  4299      && __bothSmallInteger(x, y)
  4306      && __bothSmallInteger(x, y)
  4300      && __bothSmallInteger(width, height)) {
  4307      && __bothSmallInteger(width, height)) {
  4301         gc = __GCVal(aGCId);
  4308 	gc = __GCVal(aGCId);
  4302         win = __WindowVal(aDrawableId);
  4309 	win = __WindowVal(aDrawableId);
  4303         w = __intVal(width);
  4310 	w = __intVal(width);
  4304         h = __intVal(height);
  4311 	h = __intVal(height);
  4305         /*
  4312 	/*
  4306          * need this check here: some servers simply dump core with bad args
  4313 	 * need this check here: some servers simply dump core with bad args
  4307          */
  4314 	 */
  4308         if ((w >= 0) && (h >= 0) && (angle1 >= 0) && (angle2 >= 0)) {
  4315 	if ((w >= 0) && (h >= 0) && (angle1 >= 0) && (angle2 >= 0)) {
  4309             ENTER_XLIB();
  4316 	    ENTER_XLIB();
  4310             XFillArc(myDpy, win, gc, __intVal(x), __intVal(y),
  4317 	    XFillArc(myDpy, win, gc, __intVal(x), __intVal(y),
  4311                                    w, h, angle1, angle2);
  4318 				   w, h, angle1, angle2);
  4312             LEAVE_XLIB();
  4319 	    LEAVE_XLIB();
  4313         }
  4320 	}
  4314         RETURN ( self );
  4321 	RETURN ( self );
  4315     }
  4322     }
  4316     bad: ;
  4323     bad: ;
  4317 %}.
  4324 %}.
  4318     "badGC, badDrawable or coordinates not integer
  4325     "badGC, badDrawable or coordinates not integer
  4319      or non float angle(s)"
  4326      or non float angle(s)"
  4328     <context: #return>
  4335     <context: #return>
  4329 
  4336 
  4330     |numberOfPoints|
  4337     |numberOfPoints|
  4331 
  4338 
  4332     operationsUntilFlush notNil ifTrue:[
  4339     operationsUntilFlush notNil ifTrue:[
  4333         operationsUntilFlush <= 0 ifTrue:[
  4340 	operationsUntilFlush <= 0 ifTrue:[
  4334             self flush.
  4341 	    self flush.
  4335         ] ifFalse:[
  4342 	] ifFalse:[
  4336             operationsUntilFlush := operationsUntilFlush - 1.
  4343 	    operationsUntilFlush := operationsUntilFlush - 1.
  4337         ].
  4344 	].
  4338     ].
  4345     ].
  4339     numberOfPoints := aPolygon size.
  4346     numberOfPoints := aPolygon size.
  4340 %{
  4347 %{
  4341     GC gc;
  4348     GC gc;
  4342     Window win;
  4349     Window win;
  4348 
  4355 
  4349     if (ISCONNECTED
  4356     if (ISCONNECTED
  4350      && __isExternalAddress(aGCId)
  4357      && __isExternalAddress(aGCId)
  4351      && __isExternalAddress(aDrawableId)
  4358      && __isExternalAddress(aDrawableId)
  4352      && __isSmallInteger(numberOfPoints)) {
  4359      && __isSmallInteger(numberOfPoints)) {
  4353         gc = __GCVal(aGCId);
  4360 	gc = __GCVal(aGCId);
  4354         win = __WindowVal(aDrawableId);
  4361 	win = __WindowVal(aDrawableId);
  4355         num = __intVal(numberOfPoints);
  4362 	num = __intVal(numberOfPoints);
  4356         if (num < 3) {
  4363 	if (num < 3) {
  4357             RETURN ( self );
  4364 	    RETURN ( self );
  4358         }
  4365 	}
  4359         /*
  4366 	/*
  4360          * avoid (slow) malloc, if not many points
  4367 	 * avoid (slow) malloc, if not many points
  4361          */
  4368 	 */
  4362         if (num > 100) {
  4369 	if (num > 100) {
  4363             points = (XPoint *) malloc(sizeof(XPoint) * num);
  4370 	    points = (XPoint *) malloc(sizeof(XPoint) * num);
  4364             if (! points) goto fail;
  4371 	    if (! points) goto fail;
  4365             mustFree = 1;
  4372 	    mustFree = 1;
  4366         } else
  4373 	} else
  4367             points = qPoints;
  4374 	    points = qPoints;
  4368         for (i=0; i<num; i++) {
  4375 	for (i=0; i<num; i++) {
  4369             point = __AT_(aPolygon, __MKSMALLINT(i+1));
  4376 	    point = __AT_(aPolygon, __MKSMALLINT(i+1));
  4370             if (! __isPoint(point)) goto fail;
  4377 	    if (! __isPoint(point)) goto fail;
  4371             x = _point_X(point);
  4378 	    x = _point_X(point);
  4372             y = _point_Y(point);
  4379 	    y = _point_Y(point);
  4373             if (! __bothSmallInteger(x, y))
  4380 	    if (! __bothSmallInteger(x, y))
  4374                 goto fail;
  4381 		goto fail;
  4375             points[i].x = __intVal(x);
  4382 	    points[i].x = __intVal(x);
  4376             points[i].y = __intVal(y);
  4383 	    points[i].y = __intVal(y);
  4377         }
  4384 	}
  4378         ENTER_XLIB();
  4385 	ENTER_XLIB();
  4379         XFillPolygon(myDpy, win, gc, points, num, Complex, CoordModeOrigin);
  4386 	XFillPolygon(myDpy, win, gc, points, num, Complex, CoordModeOrigin);
  4380         LEAVE_XLIB();
  4387 	LEAVE_XLIB();
  4381         if (mustFree)
  4388 	if (mustFree)
  4382             free(points);
  4389 	    free(points);
  4383         RETURN ( self );
  4390 	RETURN ( self );
  4384 
  4391 
  4385 fail: ;
  4392 fail: ;
  4386         if (mustFree)
  4393 	if (mustFree)
  4387             free(points);
  4394 	    free(points);
  4388     }
  4395     }
  4389 %}.
  4396 %}.
  4390     "badGC, badDrawable or coordinates not integer"
  4397     "badGC, badDrawable or coordinates not integer"
  4391     self primitiveFailedOrClosedConnection
  4398     self primitiveFailedOrClosedConnection
  4392 !
  4399 !
  4395     "fill a rectangle. If any coordinate is not integer, an error is triggered."
  4402     "fill a rectangle. If any coordinate is not integer, an error is triggered."
  4396 
  4403 
  4397     <context: #return>
  4404     <context: #return>
  4398 
  4405 
  4399     operationsUntilFlush notNil ifTrue:[
  4406     operationsUntilFlush notNil ifTrue:[
  4400         operationsUntilFlush <= 0 ifTrue:[
  4407 	operationsUntilFlush <= 0 ifTrue:[
  4401             self flush.
  4408 	    self flush.
  4402         ] ifFalse:[
  4409 	] ifFalse:[
  4403             operationsUntilFlush := operationsUntilFlush - 1.
  4410 	    operationsUntilFlush := operationsUntilFlush - 1.
  4404         ].
  4411 	].
  4405     ].
  4412     ].
  4406 %{
  4413 %{
  4407 
  4414 
  4408     int w, h;
  4415     int w, h;
  4409 
  4416 
  4410     if (ISCONNECTED
  4417     if (ISCONNECTED
  4411      && __isExternalAddress(aGCId)
  4418      && __isExternalAddress(aGCId)
  4412      && __isExternalAddress(aDrawableId)
  4419      && __isExternalAddress(aDrawableId)
  4413      && __bothSmallInteger(x, y)
  4420      && __bothSmallInteger(x, y)
  4414      && __bothSmallInteger(width, height)) {
  4421      && __bothSmallInteger(width, height)) {
  4415         w = __intVal(width);
  4422 	w = __intVal(width);
  4416         h = __intVal(height);
  4423 	h = __intVal(height);
  4417         /*
  4424 	/*
  4418          * need this check here: some servers simply dump core with bad args
  4425 	 * need this check here: some servers simply dump core with bad args
  4419          */
  4426 	 */
  4420         if ((w >= 0) && (h >= 0)) {
  4427 	if ((w >= 0) && (h >= 0)) {
  4421             ENTER_XLIB();
  4428 	    ENTER_XLIB();
  4422             XFillRectangle(myDpy,
  4429 	    XFillRectangle(myDpy,
  4423                            __DrawableVal(aDrawableId), __GCVal(aGCId),
  4430 			   __DrawableVal(aDrawableId), __GCVal(aGCId),
  4424                            __intVal(x), __intVal(y), w, h);
  4431 			   __intVal(x), __intVal(y), w, h);
  4425             LEAVE_XLIB();
  4432 	    LEAVE_XLIB();
  4426         }
  4433 	}
  4427         RETURN ( self );
  4434 	RETURN ( self );
  4428     }
  4435     }
  4429 %}.
  4436 %}.
  4430     "badGC, badDrawable or coordinates not integer"
  4437     "badGC, badDrawable or coordinates not integer"
  4431     self primitiveFailedOrClosedConnection
  4438     self primitiveFailedOrClosedConnection
  4432 !
  4439 !
  8596     hasMbufExtension := self queryMBUFExtension.
  8603     hasMbufExtension := self queryMBUFExtension.
  8597     hasPEXExtension := self queryPEXExtension.
  8604     hasPEXExtension := self queryPEXExtension.
  8598     hasImageExtension := self queryXIEExtension.
  8605     hasImageExtension := self queryXIEExtension.
  8599     hasInputExtension := self queryXIExtension.
  8606     hasInputExtension := self queryXIExtension.
  8600     hasXineramaExtension := self queryXineramaExtension.
  8607     hasXineramaExtension := self queryXineramaExtension.
       
  8608     hasRenderExtension := self queryRenderExtension.
       
  8609     hasXftLibrary := self queryXftLibrary.
  8601 
  8610 
  8602     primaryAtom := self atomIDOf:#PRIMARY.
  8611     primaryAtom := self atomIDOf:#PRIMARY.
  8603     stringAtom := self atomIDOf:#STRING.
  8612     stringAtom := self atomIDOf:#STRING.
  8604     clipboardAtom := self atomIDOf:#CLIPBOARD.
  8613     clipboardAtom := self atomIDOf:#CLIPBOARD.
  8605 
  8614 
  9003     "
  9012     "
  9004      Display queryRGBMasks
  9013      Display queryRGBMasks
  9005     "
  9014     "
  9006 !
  9015 !
  9007 
  9016 
       
  9017 queryXftLibrary
       
  9018 %{
       
  9019 #ifndef XFT
       
  9020     RETURN (false);
       
  9021 #endif
       
  9022 %}.
       
  9023     ^ self queryRenderExtension
       
  9024 !
       
  9025 
       
  9026 queryRenderExtension
       
  9027 %{  /* NOCONTEXT */
       
  9028 
       
  9029 #ifdef XRENDER
       
  9030     if (ISCONNECTED) {
       
  9031 	Display *dpy;
       
  9032 	int dummy;
       
  9033 
       
  9034 	dpy = myDpy;
       
  9035 
       
  9036 	if (XRenderQueryExtension (dpy, &dummy, &dummy)) {
       
  9037 	    RETURN ( true );
       
  9038 	}
       
  9039     }
       
  9040 #endif
       
  9041 %}.
       
  9042     ^ false
       
  9043 
       
  9044     "
       
  9045      Display queryRenderExtension
       
  9046     "
       
  9047 !
       
  9048 
  9008 querySHMExtension
  9049 querySHMExtension
  9009 %{  /* NOCONTEXT */
  9050 %{  /* NOCONTEXT */
  9010 
  9051 
  9011 #ifdef xxSHM
  9052 #ifdef xxSHM
  9012     if (ISCONNECTED) {
  9053     if (ISCONNECTED) {
  9519      See also #sync, which even waits until the request has been processed."
  9560      See also #sync, which even waits until the request has been processed."
  9520 
  9561 
  9521     <context: #return>
  9562     <context: #return>
  9522 %{
  9563 %{
  9523     if (ISCONNECTED) {
  9564     if (ISCONNECTED) {
  9524         ENTER_XLIB();
  9565 	ENTER_XLIB();
  9525         XFlush(myDpy);
  9566 	XFlush(myDpy);
  9526         LEAVE_XLIB();
  9567 	LEAVE_XLIB();
  9527     }
  9568     }
  9528 %}.
  9569 %}.
  9529 
  9570 
  9530     operationsUntilFlush := maxOperationsUntilFlush.
  9571     operationsUntilFlush := maxOperationsUntilFlush.
  9531 !
  9572 !
  9557     <context: #return>
  9598     <context: #return>
  9558 %{
  9599 %{
  9559 
  9600 
  9560     if (ISCONNECTED) {
  9601     if (ISCONNECTED) {
  9561 
  9602 
  9562         ENTER_XLIB();
  9603 	ENTER_XLIB();
  9563         XSync(myDpy, 0);
  9604 	XSync(myDpy, 0);
  9564         LEAVE_XLIB();
  9605 	LEAVE_XLIB();
  9565 
  9606 
  9566     }
  9607     }
  9567 %}.
  9608 %}.
  9568     operationsUntilFlush := maxOperationsUntilFlush.
  9609     operationsUntilFlush := maxOperationsUntilFlush.
  9569 !
  9610 !
 13003 ! !
 13044 ! !
 13004 
 13045 
 13005 !XWorkstation class methodsFor:'documentation'!
 13046 !XWorkstation class methodsFor:'documentation'!
 13006 
 13047 
 13007 version
 13048 version
 13008     ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.574 2013-11-20 19:08:19 stefan Exp $'
 13049     ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.575 2013-11-25 10:51:46 cg Exp $'
 13009 !
 13050 !
 13010 
 13051 
 13011 version_CVS
 13052 version_CVS
 13012     ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.574 2013-11-20 19:08:19 stefan Exp $'
 13053     ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.575 2013-11-25 10:51:46 cg Exp $'
 13013 !
 13054 !
 13014 
 13055 
 13015 version_SVN
 13056 version_SVN
 13016     ^ '$ Id $'
 13057     ^ '$ Id $'
 13017 ! !
 13058 ! !