XWorkstation.st
changeset 6567 803364ec1f7d
parent 6551 eff1347ac76f
child 6569 844102405f89
equal deleted inserted replaced
6565:a3955bc42356 6567:803364ec1f7d
    25 		deviceIOTimeoutErrorSignal activateOnClick rawKeySymTranslation
    25 		deviceIOTimeoutErrorSignal activateOnClick rawKeySymTranslation
    26 		selectionOwner clipboardSelectionTime primarySelectionTime
    26 		selectionOwner clipboardSelectionTime primarySelectionTime
    27 		selectionFetchers selectionHandlers preWaitAction xlibTimeout
    27 		selectionFetchers selectionHandlers preWaitAction xlibTimeout
    28 		xlibTimeoutForWindowCreation hasConnectionBroken uniqueDeviceID
    28 		xlibTimeoutForWindowCreation hasConnectionBroken uniqueDeviceID
    29 		stxDeviceAtom uuidAtom primaryBuffer windowGroupWindow
    29 		stxDeviceAtom uuidAtom primaryBuffer windowGroupWindow
    30 		maxOperationsUntilFlush operationsUntilFlush'
    30 		maxOperationsUntilFlush operationsUntilFlush lastError'
    31 	classVariableNames:'RawKeySymTranslation ConservativeSync MaxStringLength
    31 	classVariableNames:'RawKeySymTranslation ConservativeSync MaxStringLength
    32 		DefaultXLibTimeout DefaultXLibTimeoutForWindowCreation
    32 		DefaultXLibTimeout DefaultXLibTimeoutForWindowCreation
    33 		ErrorDBCache'
    33 		ErrorDBCache'
    34 	poolDictionaries:''
    34 	poolDictionaries:''
    35 	category:'Interface-Graphics'
    35 	category:'Interface-Graphics'
   562 ! !
   562 ! !
   563 
   563 
   564 !XWorkstation class methodsFor:'initialization'!
   564 !XWorkstation class methodsFor:'initialization'!
   565 
   565 
   566 initialize
   566 initialize
       
   567     "/ ConservativeSync is required for some Xlib implementation,
       
   568     "/ where eventPending returns wrong if we do not flush the buffer.
       
   569     "/ (especially Win32 & Xlib)
   567     ConservativeSync := OperatingSystem isMSWINDOWSlike.
   570     ConservativeSync := OperatingSystem isMSWINDOWSlike.
   568 
   571 
   569     "/ some XServers crash, when given too long strings in XDrawString/XDrawInageString.
   572     "/ some XServers crash, when given too long strings in XDrawString/XDrawInageString.
   570     "/ the following is an adjustable soft-limit.
   573     "/ the following is an adjustable soft-limit.
   571     MaxStringLength := 4096.
   574     MaxStringLength := 4096.
  4996 
  4999 
  4997 expose:view x:x y:y width:w height:h count:count
  5000 expose:view x:x y:y width:w height:h count:count
  4998     "forward an expose event for some view"
  5001     "forward an expose event for some view"
  4999 
  5002 
  5000     self exposeX:x y:y width:w height:h view:view.
  5003     self exposeX:x y:y width:w height:h view:view.
  5001 
       
  5002 
       
  5003 
       
  5004 
       
  5005 !
  5004 !
  5006 
  5005 
  5007 focusIn:view mode:mode detail:detail
  5006 focusIn:view mode:mode detail:detail
  5008     "a view got the keyboard focus"
  5007     "a view got the keyboard focus"
  5009 
  5008 
  5024 
  5023 
  5025 graphicsExpose:view x:x y:y width:w height:h count:count
  5024 graphicsExpose:view x:x y:y width:w height:h count:count
  5026     "forward a graphics-expose event for some view"
  5025     "forward a graphics-expose event for some view"
  5027 
  5026 
  5028     self graphicsExposeX:x y:y width:w height:h final:(count==0) view:view
  5027     self graphicsExposeX:x y:y width:w height:h final:(count==0) view:view
  5029 
       
  5030 
       
  5031 
       
  5032 
       
  5033 !
  5028 !
  5034 
  5029 
  5035 keyPress:view key:key code:keyCode state:state x:x y:y rootX:rX rootY:rY time:time
  5030 keyPress:view key:key code:keyCode state:state x:x y:y rootX:rX rootY:rY time:time
  5036     "forward a key-press event for some view"
  5031     "forward a key-press event for some view"
  5037 
  5032 
  5051     eventRootY := rY.
  5046     eventRootY := rY.
  5052 
  5047 
  5053     "very low-level mapping of X11 event symbols to common ST/X event symbols"
  5048     "very low-level mapping of X11 event symbols to common ST/X event symbols"
  5054     commonKey := rawKeySymTranslation at:key ifAbsent:key.
  5049     commonKey := rawKeySymTranslation at:key ifAbsent:key.
  5055 
  5050 
       
  5051 view errorPrint. ' key:' errorPrint. commonKey errorPrintCR.
  5056     self keyPress:commonKey x:x y:y view:view.
  5052     self keyPress:commonKey x:x y:y view:view.
  5057 !
  5053 !
  5058 
  5054 
  5059 keyRelease:view key:key code:keyCode state:state x:x y:y rootX:rX rootY:rY time:time
  5055 keyRelease:view key:key code:keyCode state:state x:x y:y rootX:rX rootY:rY time:time
  5060     "forward a key-release event for some view"
  5056     "forward a key-release event for some view"
  5350 			 PropertyChangeMask ));
  5346 			 PropertyChangeMask ));
  5351 %}
  5347 %}
  5352 !
  5348 !
  5353 
  5349 
  5354 dispatchEvent:evArray
  5350 dispatchEvent:evArray
       
  5351     "a raw event array as coming from the low level C code is converted
       
  5352      to a message send here.
       
  5353      Also, the windowID from the event array is mapped to a view object."
       
  5354 
  5355     |viewId view evType arguments|
  5355     |viewId view evType arguments|
  5356 
  5356 
  5357     viewId := evArray at:1.
  5357     viewId := evArray at:1.
  5358     viewId notNil ifTrue:[
  5358     viewId notNil ifTrue:[
  5359 	viewId = lastId ifTrue:[
  5359 	viewId = lastId ifTrue:[
  5370 	arguments at:1 put:view.
  5370 	arguments at:1 put:view.
  5371 
  5371 
  5372 	self perform:evType withArguments:arguments.
  5372 	self perform:evType withArguments:arguments.
  5373 	^ true.
  5373 	^ true.
  5374     ].
  5374     ].
  5375 '********** unhandled event:' errorPrintCR.
  5375 
  5376 evType errorPrintCR. (evArray at:2) errorPrintCR.
  5376     '********** unhandled event:' errorPrintCR.
  5377 '********** see dispatchEvent' errorPrintCR.
  5377     evType errorPrintCR. (evArray at:2) errorPrintCR.
       
  5378     '********** see dispatchEvent' errorPrintCR.
  5378     ^ false
  5379     ^ false
  5379 !
  5380 !
  5380 
  5381 
  5381 dispatchEventFor:aViewIdOrNil withMask:eventMask
  5382 dispatchEventFor:aViewIdOrNil withMask:eventMask
  5382     "central event handling method:
  5383     "central event handling method:
  5679     RETURN ( rslt );
  5680     RETURN ( rslt );
  5680 %}
  5681 %}
  5681 !
  5682 !
  5682 
  5683 
  5683 getEventFor:aViewIdOrNil withMask:eventMask into:anEventArray
  5684 getEventFor:aViewIdOrNil withMask:eventMask into:anEventArray
  5684     "read next event if there is one and put events data into anEventArray.
  5685     "read next event if there is one and put event's data into anEventArray.
  5685      If aViewIdOrNil is nil, events for any view are fetched;
  5686      If aViewIdOrNil is nil, events for any view are fetched;
  5686      otherwise only events for that specific view will be fetched.
  5687      otherwise only events for that specific view will be fetched.
  5687      Returns true, if there was an event, false otherwise.
  5688      Returns true, if there was an event, false otherwise.
  5688      This method may block - so you better check for pending events
  5689      This method may block - so you better check for pending events
  5689      before calling for it.
  5690      before calling for it.
  5690 
  5691 
  5691      The event fields are placed them into anEventArray (must be at least size 13):
  5692      The event fields are placed into anEventArray (must be at least size 13):
  5692      the fields are:
  5693      the fields are:
  5693 	1:      windowID
  5694 	1:      windowID
  5694 	2:      eventType-ID
  5695 	2:      eventType-ID
  5695 	3:      eventTypeSymbol
  5696 	3:      eventTypeSymbol
  5696 
  5697 
  6419 %{
  6420 %{
  6420     int type;
  6421     int type;
  6421     int state;
  6422     int state;
  6422 
  6423 
  6423     if (__isSmallInteger(stateMask)) {
  6424     if (__isSmallInteger(stateMask)) {
  6424         state = __intVal(stateMask);
  6425 	state = __intVal(stateMask);
  6425     } else {
  6426     } else {
  6426         state = 0;
  6427 	state = 0;
  6427     }
  6428     }
  6428 
  6429 
  6429     if (ISCONNECTED
  6430     if (ISCONNECTED
  6430      && __isSmallInteger(xPos) && __isSmallInteger(yPos)
  6431      && __isSmallInteger(xPos) && __isSmallInteger(yPos)
  6431      && (__isSmallInteger(keySymCodeOrButtonNr) || __isStringLike(keySymCodeOrButtonNr))
  6432      && (__isSmallInteger(keySymCodeOrButtonNr) || __isStringLike(keySymCodeOrButtonNr))
  6432      && (__isExternalAddress(targetId) || __isInteger(targetId))) {
  6433      && (__isExternalAddress(targetId) || __isInteger(targetId))) {
  6433         Display *dpy = myDpy;
  6434 	Display *dpy = myDpy;
  6434 
  6435 
  6435         XEvent ev;
  6436 	XEvent ev;
  6436         Window target;
  6437 	Window target;
  6437         Status result;
  6438 	Status result;
  6438         KeySym keySym, *syms;
  6439 	KeySym keySym, *syms;
  6439         int screen = __intVal(__INST(screen));
  6440 	int screen = __intVal(__INST(screen));
  6440         char s[2];
  6441 	int nSyms;
  6441         int nSyms;
  6442 
  6442 
  6443 	if ((typeSymbol == @symbol(keyPress))
  6443         if ((typeSymbol == @symbol(keyPress))
  6444 	 || (typeSymbol == @symbol(keyRelease))) {
  6444          || (typeSymbol == @symbol(keyRelease))) {
  6445 	    if (__isStringLike(keySymCodeOrButtonNr)) {
  6445             if (__isStringLike(keySymCodeOrButtonNr)) {
  6446 		keySym = XStringToKeysym(__stringVal(keySymCodeOrButtonNr));
  6446                 keySym = XStringToKeysym(__stringVal(keySymCodeOrButtonNr));
  6447 	    } else {
  6447             } else {
  6448 		if (__isCharacter(keySymCodeOrButtonNr)) {
  6448                 if (__isCharacter(keySymCodeOrButtonNr)) {
  6449 		    char s[2];
  6449                     s[0] = __intVal(__characterVal(keySymCodeOrButtonNr));
  6450 		    s[0] = __intVal(__characterVal(keySymCodeOrButtonNr));
  6450                     s[1] = '\0';
  6451 		    s[1] = '\0';
  6451                     keySym = XStringToKeysym(s);
  6452 		    keySym = XStringToKeysym(s);
  6452                 } else {
  6453 		} else {
  6453                     keySym = (KeySym) __intVal(keySymCodeOrButtonNr);
  6454 		    if (__isSmallInteger(keySymCodeOrButtonNr)) {
  6454                 }
  6455 			keySym = (KeySym) __intVal(keySymCodeOrButtonNr);
  6455             }
  6456 		    } else {
  6456             ev.xkey.keycode = XKeysymToKeycode(dpy, keySym);
  6457 			goto notOk;
  6457 
  6458 		    }
  6458             if (stateMask == nil) {
  6459 		}
  6459                 /*
  6460 	    }
  6460                  * get the modifier from the keySym
  6461 	    ev.xkey.keycode = XKeysymToKeycode(dpy, keySym);
  6461                  */
  6462 
  6462                 nSyms = 0;
  6463 	    if (stateMask == nil) {
  6463                 syms = XGetKeyboardMapping(dpy, ev.xkey.keycode, 1, &nSyms);
  6464 		/*
  6464                 if (syms) {
  6465 		 * get the modifier from the keySym
  6465                     int i;
  6466 		 */
  6466 
  6467 		nSyms = 0;
  6467                     for (i=0; i<nSyms; i++) {
  6468 		syms = XGetKeyboardMapping(dpy, ev.xkey.keycode, 1, &nSyms);
  6468                         if (syms[i] == keySym) {
  6469 		if (syms) {
       
  6470 		    int i;
       
  6471 
       
  6472 		    for (i=0; i<nSyms; i++) {
       
  6473 			if (syms[i] == keySym) {
  6469 #ifdef MODIFIERDEBUG
  6474 #ifdef MODIFIERDEBUG
  6470                             console_printf("modifier-index is %d\n", i);
  6475 			    console_printf("modifier-index is %d\n", i);
  6471 #endif
  6476 #endif
  6472                             if (i) state = (1 << (i-1));
  6477 			    if (i) state = (1 << (i-1));
  6473                             break;
  6478 			    break;
  6474                         }
  6479 			}
  6475                     }
  6480 		    }
  6476                     XFree(syms);
  6481 		    XFree(syms);
  6477                 }
  6482 		}
  6478             }
  6483 	    }
  6479         } else {
  6484 	} else {
  6480             if ((typeSymbol == @symbol(buttonPress))
  6485 	    if ((typeSymbol == @symbol(buttonPress))
  6481              || (typeSymbol == @symbol(buttonRelease))) {
  6486 	     || (typeSymbol == @symbol(buttonRelease))) {
  6482                 if (__isSmallInteger(keySymCodeOrButtonNr)) {
  6487 		if (__isSmallInteger(keySymCodeOrButtonNr)) {
  6483                     ev.xbutton.button = __intVal(keySymCodeOrButtonNr);
  6488 		    ev.xbutton.button = __intVal(keySymCodeOrButtonNr);
  6484                 } else {
  6489 		} else {
  6485                     ev.xbutton.button = 1;
  6490 		    ev.xbutton.button = 1;
  6486                 }
  6491 		}
  6487             } else {
  6492 	    } else {
  6488                 DPRINTF(("invalid sendEvent typeSymbol\n"));
  6493 		DPRINTF(("invalid sendEvent typeSymbol\n"));
  6489                 RETURN (false);
  6494 		RETURN (false);
  6490             }
  6495 	    }
  6491         }
  6496 	}
  6492 
  6497 
  6493         if (typeSymbol == @symbol(keyPress))
  6498 	if (typeSymbol == @symbol(keyPress))
  6494             ev.xany.type = KeyPress;
  6499 	    ev.xany.type = KeyPress;
  6495         else if (typeSymbol == @symbol(keyRelease))
  6500 	else if (typeSymbol == @symbol(keyRelease))
  6496             ev.xany.type = KeyRelease;
  6501 	    ev.xany.type = KeyRelease;
  6497         else if (typeSymbol == @symbol(buttonPress))
  6502 	else if (typeSymbol == @symbol(buttonPress))
  6498             ev.xany.type = ButtonPress;
  6503 	    ev.xany.type = ButtonPress;
  6499         else if (typeSymbol == @symbol(buttonRelease))
  6504 	else if (typeSymbol == @symbol(buttonRelease))
  6500             ev.xany.type = ButtonRelease;
  6505 	    ev.xany.type = ButtonRelease;
  6501 
  6506 
  6502         if (__isExternalAddress(targetId)) {
  6507 	if (__isExternalAddress(targetId)) {
  6503             target = __WindowVal(targetId);
  6508 	    target = __WindowVal(targetId);
  6504         } else {
  6509 	} else {
  6505             target = (Window) __longIntVal(targetId);
  6510 	    target = (Window) __longIntVal(targetId);
  6506         }
  6511 	}
  6507         ev.xkey.window = target;
  6512 	ev.xkey.window = target;
  6508         ev.xkey.same_screen = 1;
  6513 	ev.xkey.same_screen = 1;
  6509         ev.xkey.subwindow = 0;
  6514 	ev.xkey.subwindow = 0;
  6510         ev.xkey.root = RootWindow(dpy, screen);
  6515 	ev.xkey.root = RootWindow(dpy, screen);
  6511         ev.xkey.x = __intVal(xPos);
  6516 	ev.xkey.x = __intVal(xPos);
  6512         ev.xkey.y = __intVal(yPos);
  6517 	ev.xkey.y = __intVal(yPos);
  6513         ev.xkey.state = state;
  6518 	ev.xkey.state = state;
  6514         ev.xkey.time = CurrentTime;
  6519 	ev.xkey.time = CurrentTime;
  6515 
  6520 
  6516         ENTER_XLIB();
  6521 	ENTER_XLIB();
  6517         result = XSendEvent(dpy, target, False, 0 , &ev);
  6522 	result = XSendEvent(dpy, target, False, 0 , &ev);
  6518         LEAVE_XLIB();
  6523 	LEAVE_XLIB();
  6519         if ((result == BadValue) || (result == BadWindow)) {
  6524 	if ((result == BadValue) || (result == BadWindow)) {
  6520             DPRINTF(("bad status\n"));
  6525 	    DPRINTF(("bad status\n"));
  6521             RETURN ( false )
  6526 	    RETURN ( false )
  6522         }
  6527 	}
  6523         RETURN (true)
  6528 	RETURN (true)
  6524     }
  6529     }
       
  6530   notOk: ;
  6525 %}.
  6531 %}.
  6526     self primitiveFailedOrClosedConnection.
  6532     self primitiveFailedOrClosedConnection.
  6527     ^ false
  6533     ^ false
  6528 
  6534 
  6529     "<<END
  6535     "<<END
  6533      v contents:'Hello world'.
  6539      v contents:'Hello world'.
  6534      v openAndWait.
  6540      v openAndWait.
  6535      v selectFromCharacterPosition:1 to:5.
  6541      v selectFromCharacterPosition:1 to:5.
  6536 
  6542 
  6537      "/ CTRL-c
  6543      "/ CTRL-c
  6538      v device 
  6544      v device
  6539          sendKeyOrButtonEvent:#keyPress
  6545 	 sendKeyOrButtonEvent:#keyPress
  6540          x:10 y:10
  6546 	 x:10 y:10
  6541          keyOrButton:#'Control'
  6547 	 keyOrButton:#'Control'
  6542          state:(v device ctrlModifierMask)
  6548 	 state:(v device ctrlModifierMask)
  6543          toViewId: v id.
  6549 	 toViewId: v id.
  6544 
  6550 
  6545      v device 
  6551      v device
  6546          sendKeyOrButtonEvent:#keyPress
  6552 	 sendKeyOrButtonEvent:#keyPress
  6547          x:10 y:10
  6553 	 x:10 y:10
  6548          keyOrButton:'c'
  6554 	 keyOrButton:'c'
  6549          state:(v device ctrlModifierMask)
  6555 	 state:(v device ctrlModifierMask)
  6550          toViewId: v id.
  6556 	 toViewId: v id.
  6551 
  6557 
  6552      v device 
  6558      v device
  6553          sendKeyOrButtonEvent:#keyRelease
  6559 	 sendKeyOrButtonEvent:#keyRelease
  6554          x:10 y:10
  6560 	 x:10 y:10
  6555          keyOrButton:'c'
  6561 	 keyOrButton:'c'
  6556          state:(v device ctrlModifierMask)
  6562 	 state:(v device ctrlModifierMask)
  6557          toViewId: v id.
  6563 	 toViewId: v id.
  6558 
  6564 
  6559      v device 
  6565      v device
  6560          sendKeyOrButtonEvent:#keyRelease
  6566 	 sendKeyOrButtonEvent:#keyRelease
  6561          x:10 y:10
  6567 	 x:10 y:10
  6562          keyOrButton:#'Control'
  6568 	 keyOrButton:#'Control'
  6563          state:0
  6569 	 state:0
  6564          toViewId: v id.
  6570 	 toViewId: v id.
  6565 
  6571 
  6566      "/ CTRL-v
  6572      "/ CTRL-v
  6567 
  6573 
  6568      v device 
  6574      v device
  6569          sendKeyOrButtonEvent:#keyPress
  6575 	 sendKeyOrButtonEvent:#keyPress
  6570          x:10 y:10
  6576 	 x:10 y:10
  6571          keyOrButton:#'Control'
  6577 	 keyOrButton:#'Control'
  6572          state:(v device ctrlModifierMask)
  6578 	 state:(v device ctrlModifierMask)
  6573          toViewId: v id.
  6579 	 toViewId: v id.
  6574 
  6580 
  6575      v device 
  6581      v device
  6576          sendKeyOrButtonEvent:#keyPress
  6582 	 sendKeyOrButtonEvent:#keyPress
  6577          x:10 y:10
  6583 	 x:10 y:10
  6578          keyOrButton:'v'
  6584 	 keyOrButton:'v'
  6579          state:(v device ctrlModifierMask)
  6585 	 state:(v device ctrlModifierMask)
  6580          toViewId: v id.
  6586 	 toViewId: v id.
  6581 
  6587 
  6582      v device 
  6588      v device
  6583          sendKeyOrButtonEvent:#keyRelease
  6589 	 sendKeyOrButtonEvent:#keyRelease
  6584          x:10 y:10
  6590 	 x:10 y:10
  6585          keyOrButton:'v'
  6591 	 keyOrButton:'v'
  6586          state:(v device ctrlModifierMask)
  6592 	 state:(v device ctrlModifierMask)
  6587          toViewId: v id.
  6593 	 toViewId: v id.
  6588 
  6594 
  6589      v device 
  6595      v device
  6590          sendKeyOrButtonEvent:#keyRelease
  6596 	 sendKeyOrButtonEvent:#keyRelease
  6591          x:10 y:10
  6597 	 x:10 y:10
  6592          keyOrButton:#'Control'
  6598 	 keyOrButton:#'Control'
  6593          state:0
  6599 	 state:0
  6594          toViewId: v id.
  6600 	 toViewId: v id.
  6595 END"
  6601 END"
  6596 ! !
  6602 ! !
  6597 
  6603 
  6598 !XWorkstation methodsFor:'font stuff'!
  6604 !XWorkstation methodsFor:'font stuff'!
  6599 
  6605 
  7546      FontDescription."
  7552      FontDescription."
  7547 
  7553 
  7548     |names|
  7554     |names|
  7549 
  7555 
  7550     listOfXFonts isNil ifTrue:[
  7556     listOfXFonts isNil ifTrue:[
  7551         names := self getAvailableFontsMatching:'*'.
  7557 	names := self getAvailableFontsMatching:'*'.
  7552         names isNil ifTrue:[
  7558 	names isNil ifTrue:[
  7553             "no names returned ..."
  7559 	    "no names returned ..."
  7554             ^ nil
  7560 	    ^ nil
  7555         ].
  7561 	].
  7556         listOfXFonts := names collect:[:aName | self fontDescriptionFromXFontName:aName].
  7562 	listOfXFonts := names collect:[:aName | self fontDescriptionFromXFontName:aName].
  7557         listOfXFonts := FontDescription genericFonts, listOfXFonts.
  7563 	listOfXFonts := FontDescription genericFonts, listOfXFonts.
  7558     ].
  7564     ].
  7559 
  7565 
  7560     (XftFontDescription notNil
  7566     (XftFontDescription notNil
  7561             and:[ XftFontDescription isLoaded
  7567 	    and:[ XftFontDescription isLoaded
  7562             and:[ self supportsXFTFonts ]]
  7568 	    and:[ self supportsXFTFonts ]]
  7563     ) ifTrue:[
  7569     ) ifTrue:[
  7564         UserPreferences current useXftFontsOnly ifTrue:[
  7570 	UserPreferences current useXftFontsOnly ifTrue:[
  7565             ^ (XftFontDescription listOfAvailableFonts)
  7571 	    ^ (XftFontDescription listOfAvailableFonts)
  7566         ].
  7572 	].
  7567         ^ listOfXFonts , (XftFontDescription listOfAvailableFonts).
  7573 	^ listOfXFonts , (XftFontDescription listOfAvailableFonts).
  7568     ].
  7574     ].
  7569     ^ listOfXFonts
  7575     ^ listOfXFonts
  7570 
  7576 
  7571     "
  7577     "
  7572      Display flushListOfAvailableFonts.
  7578      Display flushListOfAvailableFonts.
  7856 #undef NLOCALBUFFER
  7862 #undef NLOCALBUFFER
  7857 fail: ;
  7863 fail: ;
  7858 %}.
  7864 %}.
  7859     self primitiveFailedOrClosedConnection.
  7865     self primitiveFailedOrClosedConnection.
  7860     ^ 0
  7866     ^ 0
       
  7867 ! !
       
  7868 
       
  7869 !XWorkstation methodsFor:'grabbing-keys'!
       
  7870 
       
  7871 grabKey:keySymCodeOrChar modifier:modifierMaskOrNil window:aWindowIdOrNil
       
  7872     "grab a single key either for an individual window
       
  7873      or the whole screen (if aWindowIdOrNil is nil).
       
  7874      The keySymCodeOrChar argument may be a keySym (name of a key) or an integer (the keySymCode)
       
  7875      or a character.
       
  7876      The modifierMaskOrNil is as mask as returned by altModifierMask, ctrlModifierMask, etc.
       
  7877      if nil, the key is grabbed with AnyModifier.
       
  7878      Only the key is passed to myself - no permanent grab is installed.
       
  7879      (GrabModeAsync)"
       
  7880 
       
  7881     ^ sekf
       
  7882 	grabKey:keySymCodeOrChar
       
  7883 	modifier:modifierMaskOrNil
       
  7884 	grabModeKeyboard:#GrabModeAsync
       
  7885 	grabModePointer:#GrabModeAsync
       
  7886 	window:aWindowIdOrNil
       
  7887 !
       
  7888 
       
  7889 grabKey:keySymCodeOrChar modifier:modifierMaskOrNil grabModeKeyboard:modeKbd grabModePointer:modePtr window:aWindowIdOrNil
       
  7890     "internal basic entry to grab a single key either for an individual window
       
  7891      or the whole screen (if aWindowIdOrNil is nil).
       
  7892      The keySymCodeOrChar argument may be a keySym (name of a key) or an integer (the keySymCode)
       
  7893      or a character.
       
  7894      The modifierMaskOrNil is as mask as returned by altModifierMask, ctrlModifierMask, etc.
       
  7895      if nil, the key is grabbed with AnyModifier.
       
  7896      ModeKbd and modePtr are symbols GrabModeAsync or GrabModeSync.
       
  7897 
       
  7898      After that, this key-event will no longer be sent to the window/screen.
       
  7899 
       
  7900      Use with care: the only useful application is to define a special hotKey
       
  7901      to start/stop event recorders without a need for a click or focus change.
       
  7902      Once grabbed, those key events will be exclusively reported to me.
       
  7903 
       
  7904      Use GrabModeSync with big care - you can easily lock up your Xserver,
       
  7905      and have to kill ST/X or force an ungrab from a remote login if you have.
       
  7906     "
       
  7907 
       
  7908 %{
       
  7909     int modifierMask = AnyModifier;
       
  7910     KeySym keySym, *syms;
       
  7911 
       
  7912     if (__isStringLike(keySymCodeOrChar)) {
       
  7913 	keySym = XStringToKeysym(__stringVal(keySymCodeOrChar));
       
  7914     } else {
       
  7915 	if (__isCharacter(keySymCodeOrChar)) {
       
  7916 	    char s[2];
       
  7917 
       
  7918 	    s[0] = __intVal(__characterVal(keySymCodeOrChar));
       
  7919 	    s[1] = '\0';
       
  7920 	    keySym = XStringToKeysym(s);
       
  7921 	} else {
       
  7922 	    if (__isSmallInteger(keySymCodeOrChar)) {
       
  7923 		keySym = (KeySym) __intVal(keySymCodeOrChar);
       
  7924 	    } else {
       
  7925 		goto notOK;
       
  7926 	    }
       
  7927 	}
       
  7928     }
       
  7929 
       
  7930     if (modifierMaskOrNil != nil) {
       
  7931 	if (__isSmallInteger(modifierMaskOrNil)) {
       
  7932 	    modifierMask = __intVal(modifierMaskOrNil);
       
  7933 	} else {
       
  7934 	    goto notOK;
       
  7935 	}
       
  7936     }
       
  7937 
       
  7938     if (ISCONNECTED) {
       
  7939 	Display *dpy;
       
  7940 	Window window;
       
  7941 	int keyCode;
       
  7942 	int result;
       
  7943 	int mKbd, mPtr;
       
  7944 
       
  7945 	mKbd = modeKbd == @symbol(GrabModeAsync) ? GrabModeAsync :GrabModeSync;
       
  7946 	mPtr = modePtr == @symbol(GrabModeAsync) ? GrabModeAsync :GrabModeSync;
       
  7947 
       
  7948 	dpy = myDpy;
       
  7949 	keyCode = XKeysymToKeycode(dpy, keySym);
       
  7950 	if (__isExternalAddress(aWindowIdOrNil)) {
       
  7951 	    window = __WindowVal(aWindowIdOrNil);
       
  7952 	} else {
       
  7953 	    int screen;
       
  7954 
       
  7955 	    screen = DefaultScreen(dpy);
       
  7956 	    window = RootWindow(dpy, screen);
       
  7957 	}
       
  7958 	ENTER_XLIB();
       
  7959 
       
  7960 	result = XGrabKey (dpy,
       
  7961 	    keyCode, modifierMask, window,
       
  7962 	    False, mKbd, mPtr );
       
  7963 
       
  7964 	XSync(dpy, True);
       
  7965 	XFlush(dpy);
       
  7966 
       
  7967 	LEAVE_XLIB();
       
  7968 
       
  7969 	if (result != Success) {
       
  7970 	    if (result == BadAccess) {
       
  7971 		__INST(lastError) = @symbol(badAccess);
       
  7972 	    } else {
       
  7973 		__INST(lastError) = @symbol(other);
       
  7974 	    }
       
  7975 	    RETURN (false);
       
  7976 	}
       
  7977 	RETURN (true);
       
  7978     }
       
  7979   notOK: ;
       
  7980 %}.
       
  7981     self primitiveFailedOrClosedConnection
       
  7982 !
       
  7983 
       
  7984 ungrabKey:keySymCodeOrChar modifier:modifierMaskOrNil window:aWindowIdOrNil
       
  7985     "ungrab a single key as previously grabbed via grabKey:
       
  7986      Read the comment there."
       
  7987 
       
  7988 %{
       
  7989     int modifierMask = AnyModifier;
       
  7990     KeySym keySym, *syms;
       
  7991 
       
  7992     if (__isStringLike(keySymCodeOrChar)) {
       
  7993 	keySym = XStringToKeysym(__stringVal(keySymCodeOrChar));
       
  7994     } else {
       
  7995 	if (__isCharacter(keySymCodeOrChar)) {
       
  7996 	    char s[2];
       
  7997 
       
  7998 	    s[0] = __intVal(__characterVal(keySymCodeOrChar));
       
  7999 	    s[1] = '\0';
       
  8000 	    keySym = XStringToKeysym(s);
       
  8001 	} else {
       
  8002 	    if (__isSmallInteger(keySymCodeOrChar)) {
       
  8003 		keySym = (KeySym) __intVal(keySymCodeOrChar);
       
  8004 	    } else {
       
  8005 		goto notOK;
       
  8006 	    }
       
  8007 	}
       
  8008     }
       
  8009 
       
  8010     if (modifierMaskOrNil != nil) {
       
  8011 	if (__isSmallInteger(modifierMaskOrNil)) {
       
  8012 	    modifierMask = __intVal(modifierMaskOrNil);
       
  8013 	} else {
       
  8014 	    goto notOK;
       
  8015 	}
       
  8016     }
       
  8017 
       
  8018     if (ISCONNECTED) {
       
  8019 	Display *dpy;
       
  8020 	Window window;
       
  8021 	int keyCode;
       
  8022 	int result;
       
  8023 
       
  8024 	dpy = myDpy;
       
  8025 	if (__isExternalAddress(aWindowIdOrNil)) {
       
  8026 	    window = __WindowVal(aWindowIdOrNil);
       
  8027 	} else {
       
  8028 	    int screen;
       
  8029 
       
  8030 	    screen = DefaultScreen(dpy);
       
  8031 	    window = RootWindow(dpy, screen);
       
  8032 	}
       
  8033 	keyCode = XKeysymToKeycode(dpy, keySym);
       
  8034 
       
  8035 	ENTER_XLIB();
       
  8036 
       
  8037 	result = XUngrabKey (dpy, keyCode, modifierMask, window);
       
  8038 
       
  8039 	XSync(dpy, True);
       
  8040 	XFlush(dpy);
       
  8041 
       
  8042 	LEAVE_XLIB();
       
  8043 
       
  8044 	if (result != Success) {
       
  8045 	    if (result == BadAccess) {
       
  8046 		__INST(lastError) = @symbol(badAccess);
       
  8047 	    } else {
       
  8048 		__INST(lastError) = @symbol(other);
       
  8049 	    }
       
  8050 	    RETURN (false);
       
  8051 	}
       
  8052 	RETURN (true);
       
  8053     }
       
  8054   notOK: ;
       
  8055 %}.
       
  8056     self primitiveFailedOrClosedConnection
  7861 ! !
  8057 ! !
  7862 
  8058 
  7863 !XWorkstation methodsFor:'grabbing'!
  8059 !XWorkstation methodsFor:'grabbing'!
  7864 
  8060 
  7865 allowEvents:mode
  8061 allowEvents:mode
 13360 ! !
 13556 ! !
 13361 
 13557 
 13362 !XWorkstation class methodsFor:'documentation'!
 13558 !XWorkstation class methodsFor:'documentation'!
 13363 
 13559 
 13364 version
 13560 version
 13365     ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.596 2014-07-22 10:49:13 cg Exp $'
 13561     ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.597 2014-09-20 13:30:53 cg Exp $'
 13366 !
 13562 !
 13367 
 13563 
 13368 version_CVS
 13564 version_CVS
 13369     ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.596 2014-07-22 10:49:13 cg Exp $'
 13565     ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.597 2014-09-20 13:30:53 cg Exp $'
 13370 !
 13566 !
 13371 
 13567 
 13372 version_SVN
 13568 version_SVN
 13373     ^ '$ Id $'
 13569     ^ '$ Id $'
 13374 ! !
 13570 ! !