# HG changeset patch # User Stefan Vogel # Date 970158267 -7200 # Node ID e3b21cba1c5963d70c99e1b8b90a281ddda57557 # Parent 2ba64af7dfc61c668a11b9d4e67b612e7491230b Fix mappingNotifyEvents with new dispatcher. diff -r 2ba64af7dfc6 -r e3b21cba1c59 XWorkstation.st --- a/XWorkstation.st Thu Sep 28 14:51:05 2000 +0200 +++ b/XWorkstation.st Thu Sep 28 18:24:27 2000 +0200 @@ -5069,11 +5069,11 @@ decomposeEventBuffer:aByteArray into:eventArr "extracet event fields and place them into an array: the fields are: - 1: windowID - 2: eventType-ID - 3: eventTypeSymbol - - 4.. args + 1: windowID + 2: eventType-ID + 3: eventTypeSymbol + + 4.. args " %{ # define ANYBUTTON (Button1MotionMask | Button2MotionMask | Button3MotionMask) @@ -5113,378 +5113,382 @@ eB = aByteArray; if (__isByteArray(eB)) { - ev = (XEvent *)(__ByteArrayInstPtr(eB)->ba_element); + ev = (XEvent *)(__ByteArrayInstPtr(eB)->ba_element); } else { - printf("DISPLAY: no eventBuffer\n"); - RETURN (false); + printf("DISPLAY: no eventBuffer\n"); + RETURN (false); } if (!__isArray(eventArr)) { - printf("DISPLAY: bad argument\n"); - RETURN (false); + printf("DISPLAY: bad argument\n"); + RETURN (false); } if (__arraySize(eventArr) < 11) { - printf("DISPLAY: bad argument\n"); - RETURN (false); + printf("DISPLAY: bad argument\n"); + RETURN (false); } if (((t = __INST(lastId)) != nil) && __isExternalAddress(t) && (_WindowVal(t) == ae->window)) { - windowID = t; + windowID = t; } else { - windowID = __MKEXTERNALADDRESS(ae->window); + windowID = __MKEXTERNALADDRESS(ae->window); } __ArrayInstPtr(eventArr)->a_element[0] = windowID; __STORE(eventArr, windowID); __ArrayInstPtr(eventArr)->a_element[1] = __MKSMALLINT(ev->type); switch (ev->type) { - case KeyRelease: - sym = @symbol(keyRelease:key:code:state:x:y:rootX:rootY:time:); - goto keyPressAndRelease; - - case KeyPress: - sym = @symbol(keyPress:key:code:state:x:y:rootX:rootY:time:); - /* FALL INTO */ - - keyPressAndRelease: - arg = nil; - nchars = XLookupString(ke, (char *)buffer, sizeof(buffer), &keySym, NULL); - if (nchars - && (((buffer[0] >= ' ') && (buffer[0] <= '~')) - || (buffer[0] >= 0x80))) { - arg = _MKCHARACTER(buffer[0])/* *_CharacterTable[buffer[0]] */; - keySymString = NULL; - } else { - keySymString = XKeysymToString(keySym); - if (keySymString) { - arg = __MKSTRING(keySymString); - } - } - - if (arg == nil) { - /* happens sometimes (alt-graph on sun has no keysym) */ - RETURN (false); - } - - __ArrayInstPtr(eventArr)->a_element[2] = sym; - - __ArrayInstPtr(eventArr)->a_element[3] = arg; __STORE(eventArr, arg); - __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(ke->keycode); __STORE(eventArr, t); - __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(ke->state); - __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(ke->x); - __ArrayInstPtr(eventArr)->a_element[7] = __mkSmallInteger(ke->y); - __ArrayInstPtr(eventArr)->a_element[8] = __mkSmallInteger(ke->x_root); - __ArrayInstPtr(eventArr)->a_element[9] = __mkSmallInteger(ke->y_root); - __ArrayInstPtr(eventArr)->a_element[10] = t = __MKUINT(ke->time); __STORE(eventArr, t); - RETURN (true); - - case ButtonPress: - sym = @symbol(buttonPress:button:state:x:y:rootX:rootY:time:); - goto buttonPressAndRelease; - - case ButtonRelease: - sym = @symbol(buttonRelease:button:state:x:y:rootX:rootY:time:); - /* fall into */ - - buttonPressAndRelease: - __ArrayInstPtr(eventArr)->a_element[2] = sym; - __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(be->button); - __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(ke->state); - __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(be->x); - __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(be->y); - __ArrayInstPtr(eventArr)->a_element[7] = __mkSmallInteger(be->x_root); - __ArrayInstPtr(eventArr)->a_element[8] = __mkSmallInteger(be->y_root); - __ArrayInstPtr(eventArr)->a_element[9] = t = __MKUINT(be->time); __STORE(eventArr, t); - RETURN (true); - - case MotionNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(buttonMotion:state:x:y:rootX:rootY:time:); - - __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(me->state); - __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(me->x); - __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(me->y); - __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(me->x_root); - __ArrayInstPtr(eventArr)->a_element[7] = __mkSmallInteger(me->y_root); - __ArrayInstPtr(eventArr)->a_element[8] = t = __MKUINT(me->time); __STORE(eventArr, t); - RETURN (true); - - case FocusIn: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(focusIn:mode:detail:); - goto focusInOut; - - case FocusOut: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(focusOut:mode:detail:); - /* fall into */ - - focusInOut: - __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(fe->mode); - __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(fe->detail); - RETURN (true); - - - case EnterNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(pointerEnter:x:y:rootX:rootY:state:mode:detail:time:); - goto enterLeave; - - case LeaveNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(pointerLeave:x:y:rootX:rootY:state:mode:detail:time:); - /* fall into */ - - enterLeave: - __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(ele->x); - __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(ele->y); - __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(ele->x_root); - __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(ele->y_root); - __ArrayInstPtr(eventArr)->a_element[7] = __mkSmallInteger(ele->state); - __ArrayInstPtr(eventArr)->a_element[8] = __mkSmallInteger(ele->mode); - __ArrayInstPtr(eventArr)->a_element[9] = __mkSmallInteger(ele->detail); - __ArrayInstPtr(eventArr)->a_element[10] = t = __MKUINT(ele->time); __STORE(eventArr, t); - RETURN (true); - - case Expose: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(expose:x:y:width:height:count:); - goto expose; - - case GraphicsExpose: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(graphicsExpose:x:y:width:height:count:); - /* fall into */ - - expose: - __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(ee->x); - __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(ee->y); - __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(ee->width); - __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(ee->height); - __ArrayInstPtr(eventArr)->a_element[7] = __mkSmallInteger(ee->count); - RETURN (true); - - case NoExpose: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(noExposeView:); - RETURN (true); - - case VisibilityNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(visibilityNotify:state:); - switch (ve->state) { - case VisibilityUnobscured: - __ArrayInstPtr(eventArr)->a_element[3] = @symbol(unobscured); - break; - case VisibilityPartiallyObscured: - __ArrayInstPtr(eventArr)->a_element[3] = @symbol(partiallyObscured); - break; - case VisibilityFullyObscured: - __ArrayInstPtr(eventArr)->a_element[3] = @symbol(fullyObscured); - break; - } - RETURN (true); - - case CreateNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(createWindow:x:y:width:height:); - __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(cre->x); - __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(cre->y); - __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(cre->width); - __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(cre->height); - RETURN (true); - - case DestroyNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(destroyedView:); - RETURN (true); - - case UnmapNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(unmappedView:); - RETURN (true); - - case MapNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(mappedView:); - RETURN (true); - - case ConfigureNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(configure:x:y:width:height:above:); - __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(ce->x); - __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(ce->y); - __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(ce->width); - __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(ce->height); - __ArrayInstPtr(eventArr)->a_element[7] = nil; - if (ce->above != None) { - __ArrayInstPtr(eventArr)->a_element[7] = t = __MKEXTERNALADDRESS(ce->above); __STORE(eventArr, t); - } - RETURN (true); - - case GravityNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(gravityNotify:x:y:); - __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(gre->x); - __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(gre->y); - RETURN (true); - break; - - case ResizeRequest: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(resizeRequest:width:height:); - __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(rr->width); - __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(rr->height); - RETURN (true); - break; - - case ConfigureRequest: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(configureRequest:x:y:width:height:above:detail:); - __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(cr->x); - __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(cr->y); - __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(cr->width); - __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(cr->height); - __ArrayInstPtr(eventArr)->a_element[7] = nil; - if (cr->above != None) { - __ArrayInstPtr(eventArr)->a_element[7] = t = __MKEXTERNALADDRESS(cr->above); __STORE(eventArr, t); - } - switch (cr->detail) { - case Above: - __ArrayInstPtr(eventArr)->a_element[8] = @symbol(above); - break; - case Below: - __ArrayInstPtr(eventArr)->a_element[8] = @symbol(below); - break; - case TopIf: - __ArrayInstPtr(eventArr)->a_element[8] = @symbol(topIf); - break; - case BottomIf: - __ArrayInstPtr(eventArr)->a_element[8] = @symbol(bottomIf); - break; - case Opposite: - __ArrayInstPtr(eventArr)->a_element[8] = @symbol(opposite); - break; - default: - __ArrayInstPtr(eventArr)->a_element[8] = nil; - break; - } - RETURN (true); - break; - - case CirculateNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(circulateNotify:place:); - goto circulate; - - case CirculateRequest: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(circulateRequest:place:); - /* fall into */ - circulate: - switch (cie->place) { - case PlaceOnTop: - __ArrayInstPtr(eventArr)->a_element[3] = @symbol(placeOnTop); - break; - case PlaceOnBottom: - __ArrayInstPtr(eventArr)->a_element[3] = @symbol(placeOnBottom); - break; - default: - __ArrayInstPtr(eventArr)->a_element[3] = nil; - break; - } - RETURN (true); - break; - - case PropertyNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(propertyChange:atom:state:time:); - __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(pe->atom); __STORE(eventArr, t); - switch (pe->state) { - case PropertyNewValue: - __ArrayInstPtr(eventArr)->a_element[4] = @symbol(newValue); - break; - case PropertyDelete: - __ArrayInstPtr(eventArr)->a_element[4] = @symbol(deleted); - break; - default: - __ArrayInstPtr(eventArr)->a_element[4] = nil; - break; - } - __ArrayInstPtr(eventArr)->a_element[5] = t = __MKUINT(pe->time); __STORE(eventArr, t); - RETURN (true); - break; - - case SelectionClear: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(selectionClear:atom:time:); - __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(sce->selection); __STORE(eventArr, t); - __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(sce->time); __STORE(eventArr, t); - RETURN (true); - break; - - case SelectionRequest: - /* - * someone wants the selection - */ - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(selectionRequest:requestor:selection:target:property:time:); - __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(ev->xselectionrequest.requestor); __STORE(eventArr, t); - __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(ev->xselectionrequest.selection); __STORE(eventArr, t); - __ArrayInstPtr(eventArr)->a_element[5] = t = __MKUINT(ev->xselectionrequest.target); __STORE(eventArr, t); - __ArrayInstPtr(eventArr)->a_element[6] = t = __MKUINT(ev->xselectionrequest.property); __STORE(eventArr, t); - __ArrayInstPtr(eventArr)->a_element[7] = t = __MKUINT(ev->xselectionrequest.time); __STORE(eventArr, t); - RETURN (true); - - case SelectionNotify: - /* - * returned selection value (answer from SelectionRequest) - */ - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(selectionNotify:selection:target:property:requestor:time:); - __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(ev->xselection.selection); __STORE(eventArr, t); - __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(ev->xselection.target); __STORE(eventArr, t); - __ArrayInstPtr(eventArr)->a_element[5] = t = __MKUINT(ev->xselection.property); __STORE(eventArr, t); - __ArrayInstPtr(eventArr)->a_element[6] = t = __MKEXTERNALADDRESS(ev->xselection.requestor); __STORE(eventArr, t); - __ArrayInstPtr(eventArr)->a_element[7] = t = __MKUINT(ev->xselection.time); __STORE(eventArr, t); - - RETURN (true); - - case ColormapNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(colormapNotify:state:); - __ArrayInstPtr(eventArr)->a_element[3] = cme->state == ColormapInstalled ? true : false; - RETURN (true); - break; - - case ClientMessage: - if (ev->xclient.message_type == (int) _AtomVal(__INST(protocolsAtom))) { - if ((ev->xclient.data.l[0] == (int) _AtomVal(__INST(quitAppAtom))) - || (ev->xclient.data.l[0] == (int) _AtomVal(__INST(deleteWindowAtom)))) { - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(terminateView:); - RETURN (true); - } - if (ev->xclient.data.l[0] == (int) _AtomVal(__INST(saveYourselfAtom))) { - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(saveAndTerminateView:); - RETURN (true); - } - } - /* - * any other client message - */ - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(clientMessage:type:format:data:); - __ArrayInstPtr(eventArr)->a_element[3] = __MKSMALLINT(ev->xclient.message_type); - __ArrayInstPtr(eventArr)->a_element[4] = __MKSMALLINT(ev->xclient.format); - __ArrayInstPtr(eventArr)->a_element[5] = t = __MKBYTEARRAY(ev->xclient.data, sizeof(ev->xclient.data)); __STORE(eventArr, t); - RETURN (true); - break; - - case MappingNotify: - switch(mape->request) { - case MappingModifier: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(mappingModifier:); - break; - case MappingKeyboard: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(mappingKeyboard:); - break; - case MappingPointer: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(mappingPointer:); - break; - default: - arg = nil; - break; - } - RETURN (true); - - case KeymapNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(keymapNotify:); - RETURN (true); - break; - - case MapRequest: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(mapRequest:); - RETURN (true); - - case ReparentNotify: - __ArrayInstPtr(eventArr)->a_element[2] = @symbol(reparentedView:); - break; + case KeyRelease: + sym = @symbol(keyRelease:key:code:state:x:y:rootX:rootY:time:); + goto keyPressAndRelease; + + case KeyPress: + sym = @symbol(keyPress:key:code:state:x:y:rootX:rootY:time:); + /* FALL INTO */ + + keyPressAndRelease: + arg = nil; + nchars = XLookupString(ke, (char *)buffer, sizeof(buffer), &keySym, NULL); + if (nchars + && (((buffer[0] >= ' ') && (buffer[0] <= '~')) + || (buffer[0] >= 0x80))) { + arg = _MKCHARACTER(buffer[0])/* *_CharacterTable[buffer[0]] */; + keySymString = NULL; + } else { + keySymString = XKeysymToString(keySym); + if (keySymString) { + arg = __MKSTRING(keySymString); + } + } + + if (arg == nil) { + /* happens sometimes (alt-graph on sun has no keysym) */ + RETURN (false); + } + + __ArrayInstPtr(eventArr)->a_element[2] = sym; + + __ArrayInstPtr(eventArr)->a_element[3] = arg; __STORE(eventArr, arg); + __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(ke->keycode); __STORE(eventArr, t); + __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(ke->state); + __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(ke->x); + __ArrayInstPtr(eventArr)->a_element[7] = __mkSmallInteger(ke->y); + __ArrayInstPtr(eventArr)->a_element[8] = __mkSmallInteger(ke->x_root); + __ArrayInstPtr(eventArr)->a_element[9] = __mkSmallInteger(ke->y_root); + __ArrayInstPtr(eventArr)->a_element[10] = t = __MKUINT(ke->time); __STORE(eventArr, t); + RETURN (true); + + case ButtonPress: + sym = @symbol(buttonPress:button:state:x:y:rootX:rootY:time:); + goto buttonPressAndRelease; + + case ButtonRelease: + sym = @symbol(buttonRelease:button:state:x:y:rootX:rootY:time:); + /* fall into */ + + buttonPressAndRelease: + __ArrayInstPtr(eventArr)->a_element[2] = sym; + __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(be->button); + __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(ke->state); + __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(be->x); + __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(be->y); + __ArrayInstPtr(eventArr)->a_element[7] = __mkSmallInteger(be->x_root); + __ArrayInstPtr(eventArr)->a_element[8] = __mkSmallInteger(be->y_root); + __ArrayInstPtr(eventArr)->a_element[9] = t = __MKUINT(be->time); __STORE(eventArr, t); + RETURN (true); + + case MotionNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(buttonMotion:state:x:y:rootX:rootY:time:); + + __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(me->state); + __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(me->x); + __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(me->y); + __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(me->x_root); + __ArrayInstPtr(eventArr)->a_element[7] = __mkSmallInteger(me->y_root); + __ArrayInstPtr(eventArr)->a_element[8] = t = __MKUINT(me->time); __STORE(eventArr, t); + RETURN (true); + + case FocusIn: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(focusIn:mode:detail:); + goto focusInOut; + + case FocusOut: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(focusOut:mode:detail:); + /* fall into */ + + focusInOut: + __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(fe->mode); + __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(fe->detail); + RETURN (true); + + + case EnterNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(pointerEnter:x:y:rootX:rootY:state:mode:detail:time:); + goto enterLeave; + + case LeaveNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(pointerLeave:x:y:rootX:rootY:state:mode:detail:time:); + /* fall into */ + + enterLeave: + __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(ele->x); + __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(ele->y); + __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(ele->x_root); + __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(ele->y_root); + __ArrayInstPtr(eventArr)->a_element[7] = __mkSmallInteger(ele->state); + __ArrayInstPtr(eventArr)->a_element[8] = __mkSmallInteger(ele->mode); + __ArrayInstPtr(eventArr)->a_element[9] = __mkSmallInteger(ele->detail); + __ArrayInstPtr(eventArr)->a_element[10] = t = __MKUINT(ele->time); __STORE(eventArr, t); + RETURN (true); + + case Expose: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(expose:x:y:width:height:count:); + goto expose; + + case GraphicsExpose: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(graphicsExpose:x:y:width:height:count:); + /* fall into */ + + expose: + __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(ee->x); + __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(ee->y); + __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(ee->width); + __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(ee->height); + __ArrayInstPtr(eventArr)->a_element[7] = __mkSmallInteger(ee->count); + RETURN (true); + + case NoExpose: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(noExposeView:); + RETURN (true); + + case VisibilityNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(visibilityNotify:state:); + switch (ve->state) { + case VisibilityUnobscured: + __ArrayInstPtr(eventArr)->a_element[3] = @symbol(unobscured); + break; + case VisibilityPartiallyObscured: + __ArrayInstPtr(eventArr)->a_element[3] = @symbol(partiallyObscured); + break; + case VisibilityFullyObscured: + __ArrayInstPtr(eventArr)->a_element[3] = @symbol(fullyObscured); + break; + } + RETURN (true); + + case CreateNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(createWindow:x:y:width:height:); + __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(cre->x); + __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(cre->y); + __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(cre->width); + __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(cre->height); + RETURN (true); + + case DestroyNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(destroyedView:); + RETURN (true); + + case UnmapNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(unmappedView:); + RETURN (true); + + case MapNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(mappedView:); + RETURN (true); + + case ConfigureNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(configure:x:y:width:height:above:); + __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(ce->x); + __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(ce->y); + __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(ce->width); + __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(ce->height); + __ArrayInstPtr(eventArr)->a_element[7] = nil; + if (ce->above != None) { + __ArrayInstPtr(eventArr)->a_element[7] = t = __MKEXTERNALADDRESS(ce->above); __STORE(eventArr, t); + } + RETURN (true); + + case GravityNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(gravityNotify:x:y:); + __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(gre->x); + __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(gre->y); + RETURN (true); + break; + + case ResizeRequest: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(resizeRequest:width:height:); + __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(rr->width); + __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(rr->height); + RETURN (true); + break; + + case ConfigureRequest: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(configureRequest:x:y:width:height:above:detail:); + __ArrayInstPtr(eventArr)->a_element[3] = __mkSmallInteger(cr->x); + __ArrayInstPtr(eventArr)->a_element[4] = __mkSmallInteger(cr->y); + __ArrayInstPtr(eventArr)->a_element[5] = __mkSmallInteger(cr->width); + __ArrayInstPtr(eventArr)->a_element[6] = __mkSmallInteger(cr->height); + __ArrayInstPtr(eventArr)->a_element[7] = nil; + if (cr->above != None) { + __ArrayInstPtr(eventArr)->a_element[7] = t = __MKEXTERNALADDRESS(cr->above); __STORE(eventArr, t); + } + switch (cr->detail) { + case Above: + __ArrayInstPtr(eventArr)->a_element[8] = @symbol(above); + break; + case Below: + __ArrayInstPtr(eventArr)->a_element[8] = @symbol(below); + break; + case TopIf: + __ArrayInstPtr(eventArr)->a_element[8] = @symbol(topIf); + break; + case BottomIf: + __ArrayInstPtr(eventArr)->a_element[8] = @symbol(bottomIf); + break; + case Opposite: + __ArrayInstPtr(eventArr)->a_element[8] = @symbol(opposite); + break; + default: + __ArrayInstPtr(eventArr)->a_element[8] = nil; + break; + } + RETURN (true); + break; + + case CirculateNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(circulateNotify:place:); + goto circulate; + + case CirculateRequest: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(circulateRequest:place:); + /* fall into */ + circulate: + switch (cie->place) { + case PlaceOnTop: + __ArrayInstPtr(eventArr)->a_element[3] = @symbol(placeOnTop); + break; + case PlaceOnBottom: + __ArrayInstPtr(eventArr)->a_element[3] = @symbol(placeOnBottom); + break; + default: + __ArrayInstPtr(eventArr)->a_element[3] = nil; + break; + } + RETURN (true); + break; + + case PropertyNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(propertyChange:atom:state:time:); + __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(pe->atom); __STORE(eventArr, t); + switch (pe->state) { + case PropertyNewValue: + __ArrayInstPtr(eventArr)->a_element[4] = @symbol(newValue); + break; + case PropertyDelete: + __ArrayInstPtr(eventArr)->a_element[4] = @symbol(deleted); + break; + default: + __ArrayInstPtr(eventArr)->a_element[4] = nil; + break; + } + __ArrayInstPtr(eventArr)->a_element[5] = t = __MKUINT(pe->time); __STORE(eventArr, t); + RETURN (true); + break; + + case SelectionClear: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(selectionClear:atom:time:); + __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(sce->selection); __STORE(eventArr, t); + __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(sce->time); __STORE(eventArr, t); + RETURN (true); + break; + + case SelectionRequest: + /* + * someone wants the selection + */ + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(selectionRequest:requestor:selection:target:property:time:); + __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(ev->xselectionrequest.requestor); __STORE(eventArr, t); + __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(ev->xselectionrequest.selection); __STORE(eventArr, t); + __ArrayInstPtr(eventArr)->a_element[5] = t = __MKUINT(ev->xselectionrequest.target); __STORE(eventArr, t); + __ArrayInstPtr(eventArr)->a_element[6] = t = __MKUINT(ev->xselectionrequest.property); __STORE(eventArr, t); + __ArrayInstPtr(eventArr)->a_element[7] = t = __MKUINT(ev->xselectionrequest.time); __STORE(eventArr, t); + RETURN (true); + + case SelectionNotify: + /* + * returned selection value (answer from SelectionRequest) + */ + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(selectionNotify:selection:target:property:requestor:time:); + __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(ev->xselection.selection); __STORE(eventArr, t); + __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(ev->xselection.target); __STORE(eventArr, t); + __ArrayInstPtr(eventArr)->a_element[5] = t = __MKUINT(ev->xselection.property); __STORE(eventArr, t); + __ArrayInstPtr(eventArr)->a_element[6] = t = __MKEXTERNALADDRESS(ev->xselection.requestor); __STORE(eventArr, t); + __ArrayInstPtr(eventArr)->a_element[7] = t = __MKUINT(ev->xselection.time); __STORE(eventArr, t); + + RETURN (true); + + case ColormapNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(colormapNotify:state:); + __ArrayInstPtr(eventArr)->a_element[3] = cme->state == ColormapInstalled ? true : false; + RETURN (true); + break; + + case ClientMessage: + if (ev->xclient.message_type == (int) _AtomVal(__INST(protocolsAtom))) { + if ((ev->xclient.data.l[0] == (int) _AtomVal(__INST(quitAppAtom))) + || (ev->xclient.data.l[0] == (int) _AtomVal(__INST(deleteWindowAtom)))) { + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(terminateView:); + RETURN (true); + } + if (ev->xclient.data.l[0] == (int) _AtomVal(__INST(saveYourselfAtom))) { + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(saveAndTerminateView:); + RETURN (true); + } + } + /* + * any other client message + */ + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(clientMessage:type:format:data:); + __ArrayInstPtr(eventArr)->a_element[3] = __MKSMALLINT(ev->xclient.message_type); + __ArrayInstPtr(eventArr)->a_element[4] = __MKSMALLINT(ev->xclient.format); + __ArrayInstPtr(eventArr)->a_element[5] = t = __MKBYTEARRAY(ev->xclient.data, sizeof(ev->xclient.data)); __STORE(eventArr, t); + RETURN (true); + break; + + case MappingNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(mappingNotify:request:event:); + switch(mape->request) { + case MappingModifier: + arg = @symbol(mappingModifier); + break; + case MappingKeyboard: + arg = @symbol(mappingKeyboard); + break; + case MappingPointer: + arg = @symbol(mappingPointer); + break; + default: + arg = __MKSMALLINT(mape->request); + break; + } + __ArrayInstPtr(eventArr)->a_element[3] = arg; + __ArrayInstPtr(eventArr)->a_element[4] = t = __MKBYTEARRAY(ev, sizeof(*mape)); + __STORE(eventArr, t); + RETURN (true); + + case KeymapNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(keymapNotify:); + RETURN (true); + break; + + case MapRequest: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(mapRequest:); + RETURN (true); + + case ReparentNotify: + __ArrayInstPtr(eventArr)->a_element[2] = @symbol(reparentedView:); + break; } @@ -5558,6 +5562,429 @@ "Modified: 19.8.1997 / 17:10:26 / cg" ! +dispatchLastEvent:evArray + |viewId view evTypeNr evType arguments| + + evArray size < 3 ifTrue:[ +'********** bad event:' errorPrintCR. +evArray errorPrintCR. +'********** see newDispatchLastEvent' errorPrintCR. + ^ self. + ]. + + viewId := evArray at:1. + viewId notNil ifTrue:[ + viewId = lastId ifTrue:[ + view := lastView + ] ifFalse:[ + view := self viewFromId:viewId + ]. + ]. + + evType := evArray at:3. + + (self respondsTo:evType) ifTrue:[ + arguments := evArray copyFrom:3 to:(3 + evType numArgs - 1). + arguments at:1 put:view. + + self perform:evType withArguments:arguments. + ^ true. + ]. +'********** unhandled event:' errorPrintCR. +evType errorPrintCR. +'********** see newDispatchLastEvent' errorPrintCR. + ^ false +! + +dispatchPendingEvents + "central event handling method for modal operation. + (i.e. this is now only used in the modal debugger) + Dispatch any pending events; return when no more are pending. + This code is somewhat special, since X has a concept of graphic + expose events (which are sent after a bitblt). After such a bitblt, + we only handle exposes until the graphicsExpose arrives. + Other systems may not need such a kludge" + + "interested in exposes only ?" + dispatchingExpose notNil ifTrue:[ + [self exposeEventPendingFor:dispatchingExpose withSync:false] whileTrue:[ + self dispatchExposeEventFor:dispatchingExpose + ]. + ^ self + ]. + + [self eventPendingWithSync:false] whileTrue:[ + (self getEventFor:nil withMask:nil) ifTrue:[ + AbortSignal handle:[:ex | + ex return + ] do:[ + self newDispatchLastEvent + ] + ]. + ] + + "Modified: 19.8.1997 / 17:11:18 / cg" +! + +disposeEventsWithMask:aMask for:aWindowIdOrNil + "dispose (throw away) specific events. If aWindowId is nil, + events matching the mask are thrown away regardless of which + view they are for. Otherwise, only matching events for that + view are flushed." + + +%{ + + XEvent ev; + Window win; + + if (ISCONNECTED + && __isSmallInteger(aMask)) { + Display *dpy = myDpy; + + ENTER_XLIB(); + if (__isExternalAddress(aWindowIdOrNil)) { + win = _WindowVal(aWindowIdOrNil); + while (XCheckWindowEvent(dpy, win, __intVal(aMask), &ev)) ;; + } else { + while (XCheckMaskEvent(dpy, __intVal(aMask), &ev)) ;; + } + LEAVE_XLIB(); + RETURN ( self ); + } +%}. + self primitiveFailedOrClosedConnection +! + +eventMaskFor:anEventSymbol + "return the eventMask bit-constant corresponding to an event symbol" + +%{ /* NOCONTEXT */ + + int m = 0; + + if (anEventSymbol == @symbol(keyPress)) m = KeyPressMask; + else if (anEventSymbol == @symbol(keyRelease)) m = KeyReleaseMask; + else if (anEventSymbol == @symbol(buttonPress)) m = ButtonPressMask; + else if (anEventSymbol == @symbol(buttonRelease)) m = ButtonReleaseMask; + else if (anEventSymbol == @symbol(buttonMotion)) m = ButtonMotionMask; + else if (anEventSymbol == @symbol(pointerMotion)) m = PointerMotionMask; + else if (anEventSymbol == @symbol(expose)) m = ExposureMask; + else if (anEventSymbol == @symbol(focusChange)) m = FocusChangeMask; + else if (anEventSymbol == @symbol(enter)) m = EnterWindowMask; + else if (anEventSymbol == @symbol(leave)) m = LeaveWindowMask; + else if (anEventSymbol == @symbol(keymapState)) m = KeymapStateMask; + else if (anEventSymbol == @symbol(visibilityChange)) m = VisibilityChangeMask; + else if (anEventSymbol == @symbol(structureNotify)) m = StructureNotifyMask; + else if (anEventSymbol == @symbol(resizeRedirect)) m = ResizeRedirectMask; + else if (anEventSymbol == @symbol(propertyChange)) m = PropertyChangeMask; + else if (anEventSymbol == @symbol(colormapChange)) m = ColormapChangeMask; + RETURN (__MKSMALLINT(m)); +%} +! + +eventPending + "return true, if any event is pending. + This looks for both the internal queue and the display connection." + + "/ ConservativeSync is required for some Xlib implementation, + "/ where eventPending returns wrong if we do not flush the buffer. + "/ (especially Win32 & Xlib) + + ConservativeSync == true ifTrue:[self sync]. + + dispatchingExpose notNil ifTrue:[ + ^ self exposeEventPendingFor:dispatchingExpose withSync:false + ]. + ^ self eventPendingWithSync:false + + "Modified: / 28.4.1999 / 11:08:12 / cg" +! + +eventPending:anEventSymbol for:aWindowIdOrNil + "return true, if a specific event is pending" + + ^ self eventsPending:(self eventMaskFor:anEventSymbol) for:aWindowIdOrNil withSync:false +! + +eventPending:anEventMask for:aWindowIdOrNil withSync:doSync + "return true, if any of the masked events is pending" + + +%{ /* UNLIMITEDSTACK */ + + XEvent ev; + Window win; + int thereIsOne; + OBJ rslt = false; + + if (ISCONNECTED && __isSmallInteger(anEventMask)) { + Display *dpy = myDpy; + + ENTER_XLIB(); + if (doSync == true) { + XSync(dpy, 0); /* make certain everything is flushed */ + } + if (__isExternalAddress(aWindowIdOrNil)) { + win = _WindowVal(aWindowIdOrNil); + thereIsOne = XCheckWindowEvent(dpy, win, __intVal(anEventMask), &ev); + } else { + thereIsOne = XCheckMaskEvent(dpy, __intVal(anEventMask), &ev); + } + if (thereIsOne) { + XPutBackEvent(dpy, &ev); + rslt = true; + } + LEAVE_XLIB(); + } + RETURN ( rslt ); +%} +! + +eventPendingWithSync:doSync + "return true, if any event is pending. + If doSync is true, do a sync output buffer (i.e. send all to the display and wait until its processed) + before checking." + + +%{ /* UNLIMITEDSTACK */ + OBJ rslt = false; + + if (ISCONNECTED) { + Display *dpy = myDpy; + + if (XEventsQueued(dpy, QueuedAlready)) { + RETURN (true); + } + + ENTER_XLIB(); + if (doSync == true) { + XSync(dpy, 0); /* make certain everything is flushed */ + } + if (XPending(dpy)) { + rslt = true; + } + LEAVE_XLIB(); + } + RETURN ( rslt ); +%} +! + +eventQueued + "return true, if any event is queued" + + dispatchingExpose notNil ifTrue:[ + ^ self exposeEventPendingFor:dispatchingExpose withSync:false + ]. + ^ self eventQueuedAlready + + "Created: 12.12.1995 / 21:43:00 / stefan" +! + +eventQueuedAlready + "return true, if any event is queued internally. + (i.e. in X's internal event queue, which is both filled by explicit + nextEvent calls AND whenever drawing is done and events are pending on + the display connection)." + +%{ /* UNLIMITEDSTACK */ + OBJ rslt = false; + + if (ISCONNECTED) { + /* ENTER ... LEAVE not needed; XEventsQueued will not block */ + /* ENTER_XLIB(); */ + if (XEventsQueued(myDpy, QueuedAlready)) { + rslt = true; + } + /* LEAVE_XLIB(); */ + } + RETURN ( rslt ); +%} +! + +exposeEventPendingFor:aWindowIdOrNil withSync:doSync + "return true, if any expose event is pending for a specific view, + or any view (if the arg is nil). + This is an X specific, only required after a scroll operation." + + + +%{ /* UNLIMITEDSTACK */ + + XEvent ev; + Window win; + int thereIsOne; + OBJ rslt = false; + + if (ISCONNECTED) { + Display *dpy = myDpy; + + ENTER_XLIB(); + if (doSync == true) { + XSync(dpy, 0); /* make certain everything is flushed */ + } + if (__isExternalAddress(aWindowIdOrNil)) { + win = _WindowVal(aWindowIdOrNil); + thereIsOne = XCheckWindowEvent(dpy, win, ExposureMask, &ev); + } else { + thereIsOne = XCheckMaskEvent(dpy, ExposureMask, &ev); + } + if (thereIsOne) { + XPutBackEvent(dpy, &ev); + rslt = true; + } + LEAVE_XLIB(); + } + RETURN ( rslt ); +%} +! + +getEventFor:aViewIdOrNil withMask:eventMask + "read next event - put into local eventBuffer. + If aViewIdOrNil is nil, events for any view are fetched; + otherwise only events for that specific view will be fetched. + Returns true, if there was an event, false otherwise. + This method may block - so you better check for pending events + before calling for it." + + ^ self getEventFor:aViewIdOrNil withMask:eventMask into:eventBuffer +! + +getEventFor:aViewIdOrNil withMask:eventMask into:anEventBuffer + "read next event - put into anEventBuffer. + If aViewIdOrNil is nil, events for any view are fetched; + otherwise only events for that specific view will be fetched. + Returns true, if there was an event, false otherwise. + This method may block - so you better check for pending events + before calling for it. + + Sorry I had to split dispatch into this fetch method and an extra + handle method to allow unlimitedstack here. + (some Xlibs do a big alloca there ...) which cannot be done in + dispatchLastEvent, since it dispatches out into ST-methods. + " + +%{ /* UNLIMITEDSTACK */ + + Display *dpy; + Window win, wWanted; + int evMask; + XEvent *ev; + + if (! ISCONNECTED) { + RETURN (false); + } + + dpy = myDpy; + + if (__isByteArray(anEventBuffer)) { + ev = (XEvent *)(__ByteArrayInstPtr(anEventBuffer)->ba_element); + } else { + printf("DISPLAY: bad eventBuffer\n"); + RETURN (false); + } + ev->type = 0; + + if (__isSmallInteger(eventMask)) { + evMask = __intVal(eventMask); + } else { + evMask = ~0; + } + + if (__isExternalAddress(aViewIdOrNil)) { + wWanted = _WindowVal(aViewIdOrNil); + if (XCheckWindowEvent(dpy, wWanted, evMask, ev)) { + RETURN ( true ); + } + } else { + if (evMask == ~0) { + XNextEvent(dpy, ev); + RETURN (true); + } + if (XCheckMaskEvent(dpy, evMask, ev)) { + RETURN (true); + } + } + RETURN (false); +%}. + ^ self primitiveFailed +! + +handleAllEvents + "from now on, handle any kind of event" + + dispatchingExpose := nil +! + +handleExposeOnlyFor:aView + "from now on, handle expose events only" + + dispatchingExpose := aView id +! + +mappingNotify:view request:what event:eB + "One of Keyboard-, Modifier- or PointerMap has changed, probably by xmodmap. + Tell xlib about the fact." + + (what == #mappingKeyboard or:[what == #mappingModifier]) ifTrue:[ + self refreshKeyboardMapping:eB. + "Maybe some of our modifiers have been changed" + self initializeModifierMappings. + ]. + +! + +newDispatchLastEvent + |arr| + + arr := Array new:13. + self decomposeEventBuffer:eventBuffer into:arr. + (self dispatchLastEvent:arr) ifFalse:[ + self dispatchLastEvent + ] +! + +setEventMask:aMask in:aWindowId + "tell X that we are only interested in events from aMask, which + is the bitwise or of the eventMask bits (see 'eventMaskFor:')" + + +%{ + + int mask; + + if (ISCONNECTED + && __isExternalAddress(aWindowId) + && __isSmallInteger(aMask)) { + mask = __intVal(aMask); + +#ifdef OLD + /* these may not be disabled */ + mask |= ExposureMask | StructureNotifyMask | + KeyPressMask | KeyReleaseMask | + EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonMotionMask | ButtonReleaseMask; +#endif + + ENTER_XLIB(); + XSelectInput(myDpy, _WindowVal(aWindowId), mask); + LEAVE_XLIB(); + RETURN ( self ); + } +%}. + self primitiveFailedOrClosedConnection +! + +startDispatch + "redefined to clear dispatchingExpose, which is a special X feature" + + dispatching ifTrue:[^ self]. + dispatchingExpose := nil. + super startDispatch +! ! + +!XWorkstation methodsFor:'event handling - old dispatch'! + dispatchLastEvent |theView symS arg butt sibling windowID siblingID propertyID selectionID targetID requestorID @@ -6226,426 +6653,18 @@ ^ true ! -dispatchLastEvent:evArray - |viewId view evTypeNr evType arguments| - - evArray size < 3 ifTrue:[ -'********** bad event:' errorPrintCR. -evArray errorPrintCR. -'********** see newDispatchLastEvent' errorPrintCR. - ^ self. - ]. - - viewId := evArray at:1. - viewId notNil ifTrue:[ - viewId = lastId ifTrue:[ - view := lastView - ] ifFalse:[ - view := self viewFromId:viewId - ]. - ]. - - evType := evArray at:3. - - (self respondsTo:evType) ifTrue:[ - arguments := evArray copyFrom:3 to:(3 + evType numArgs - 1). - arguments at:1 put:view. - - self perform:evType withArguments:arguments. - ^ true. - ]. -'********** unhandled event:' errorPrintCR. -evType errorPrintCR. -'********** see newDispatchLastEvent' errorPrintCR. - ^ false -! - -dispatchPendingEvents - "central event handling method for modal operation. - (i.e. this is now only used in the modal debugger) - Dispatch any pending events; return when no more are pending. - This code is somewhat special, since X has a concept of graphic - expose events (which are sent after a bitblt). After such a bitblt, - we only handle exposes until the graphicsExpose arrives. - Other systems may not need such a kludge" - - "interested in exposes only ?" - dispatchingExpose notNil ifTrue:[ - [self exposeEventPendingFor:dispatchingExpose withSync:false] whileTrue:[ - self dispatchExposeEventFor:dispatchingExpose - ]. - ^ self - ]. - - [self eventPendingWithSync:false] whileTrue:[ - (self getEventFor:nil withMask:nil) ifTrue:[ - AbortSignal handle:[:ex | - ex return - ] do:[ - self newDispatchLastEvent - ] - ]. - ] - - "Modified: 19.8.1997 / 17:11:18 / cg" -! - -disposeEventsWithMask:aMask for:aWindowIdOrNil - "dispose (throw away) specific events. If aWindowId is nil, - events matching the mask are thrown away regardless of which - view they are for. Otherwise, only matching events for that - view are flushed." - - -%{ - - XEvent ev; - Window win; - - if (ISCONNECTED - && __isSmallInteger(aMask)) { - Display *dpy = myDpy; - - ENTER_XLIB(); - if (__isExternalAddress(aWindowIdOrNil)) { - win = _WindowVal(aWindowIdOrNil); - while (XCheckWindowEvent(dpy, win, __intVal(aMask), &ev)) ;; - } else { - while (XCheckMaskEvent(dpy, __intVal(aMask), &ev)) ;; - } - LEAVE_XLIB(); - RETURN ( self ); - } -%}. - self primitiveFailedOrClosedConnection -! - -eventMaskFor:anEventSymbol - "return the eventMask bit-constant corresponding to an event symbol" - -%{ /* NOCONTEXT */ - - int m = 0; - - if (anEventSymbol == @symbol(keyPress)) m = KeyPressMask; - else if (anEventSymbol == @symbol(keyRelease)) m = KeyReleaseMask; - else if (anEventSymbol == @symbol(buttonPress)) m = ButtonPressMask; - else if (anEventSymbol == @symbol(buttonRelease)) m = ButtonReleaseMask; - else if (anEventSymbol == @symbol(buttonMotion)) m = ButtonMotionMask; - else if (anEventSymbol == @symbol(pointerMotion)) m = PointerMotionMask; - else if (anEventSymbol == @symbol(expose)) m = ExposureMask; - else if (anEventSymbol == @symbol(focusChange)) m = FocusChangeMask; - else if (anEventSymbol == @symbol(enter)) m = EnterWindowMask; - else if (anEventSymbol == @symbol(leave)) m = LeaveWindowMask; - else if (anEventSymbol == @symbol(keymapState)) m = KeymapStateMask; - else if (anEventSymbol == @symbol(visibilityChange)) m = VisibilityChangeMask; - else if (anEventSymbol == @symbol(structureNotify)) m = StructureNotifyMask; - else if (anEventSymbol == @symbol(resizeRedirect)) m = ResizeRedirectMask; - else if (anEventSymbol == @symbol(propertyChange)) m = PropertyChangeMask; - else if (anEventSymbol == @symbol(colormapChange)) m = ColormapChangeMask; - RETURN (__MKSMALLINT(m)); -%} -! - -eventPending - "return true, if any event is pending. - This looks for both the internal queue and the display connection." - - "/ ConservativeSync is required for some Xlib implementation, - "/ where eventPending returns wrong if we do not flush the buffer. - "/ (especially Win32 & Xlib) - - ConservativeSync == true ifTrue:[self sync]. - - dispatchingExpose notNil ifTrue:[ - ^ self exposeEventPendingFor:dispatchingExpose withSync:false - ]. - ^ self eventPendingWithSync:false - - "Modified: / 28.4.1999 / 11:08:12 / cg" -! - -eventPending:anEventSymbol for:aWindowIdOrNil - "return true, if a specific event is pending" - - ^ self eventsPending:(self eventMaskFor:anEventSymbol) for:aWindowIdOrNil withSync:false -! - -eventPending:anEventMask for:aWindowIdOrNil withSync:doSync - "return true, if any of the masked events is pending" - - -%{ /* UNLIMITEDSTACK */ - - XEvent ev; - Window win; - int thereIsOne; - OBJ rslt = false; - - if (ISCONNECTED && __isSmallInteger(anEventMask)) { - Display *dpy = myDpy; - - ENTER_XLIB(); - if (doSync == true) { - XSync(dpy, 0); /* make certain everything is flushed */ - } - if (__isExternalAddress(aWindowIdOrNil)) { - win = _WindowVal(aWindowIdOrNil); - thereIsOne = XCheckWindowEvent(dpy, win, __intVal(anEventMask), &ev); - } else { - thereIsOne = XCheckMaskEvent(dpy, __intVal(anEventMask), &ev); - } - if (thereIsOne) { - XPutBackEvent(dpy, &ev); - rslt = true; - } - LEAVE_XLIB(); - } - RETURN ( rslt ); -%} -! - -eventPendingWithSync:doSync - "return true, if any event is pending. - If doSync is true, do a sync output buffer (i.e. send all to the display and wait until its processed) - before checking." - - -%{ /* UNLIMITEDSTACK */ - OBJ rslt = false; - - if (ISCONNECTED) { - Display *dpy = myDpy; - - if (XEventsQueued(dpy, QueuedAlready)) { - RETURN (true); - } - - ENTER_XLIB(); - if (doSync == true) { - XSync(dpy, 0); /* make certain everything is flushed */ - } - if (XPending(dpy)) { - rslt = true; - } - LEAVE_XLIB(); - } - RETURN ( rslt ); -%} -! - -eventQueued - "return true, if any event is queued" - - dispatchingExpose notNil ifTrue:[ - ^ self exposeEventPendingFor:dispatchingExpose withSync:false - ]. - ^ self eventQueuedAlready - - "Created: 12.12.1995 / 21:43:00 / stefan" -! - -eventQueuedAlready - "return true, if any event is queued internally. - (i.e. in X's internal event queue, which is both filled by explicit - nextEvent calls AND whenever drawing is done and events are pending on - the display connection)." - -%{ /* UNLIMITEDSTACK */ - OBJ rslt = false; - - if (ISCONNECTED) { - /* ENTER ... LEAVE not needed; XEventsQueued will not block */ - /* ENTER_XLIB(); */ - if (XEventsQueued(myDpy, QueuedAlready)) { - rslt = true; - } - /* LEAVE_XLIB(); */ - } - RETURN ( rslt ); -%} -! - -exposeEventPendingFor:aWindowIdOrNil withSync:doSync - "return true, if any expose event is pending for a specific view, - or any view (if the arg is nil). - This is an X specific, only required after a scroll operation." - - - -%{ /* UNLIMITEDSTACK */ - - XEvent ev; - Window win; - int thereIsOne; - OBJ rslt = false; - - if (ISCONNECTED) { - Display *dpy = myDpy; - - ENTER_XLIB(); - if (doSync == true) { - XSync(dpy, 0); /* make certain everything is flushed */ - } - if (__isExternalAddress(aWindowIdOrNil)) { - win = _WindowVal(aWindowIdOrNil); - thereIsOne = XCheckWindowEvent(dpy, win, ExposureMask, &ev); - } else { - thereIsOne = XCheckMaskEvent(dpy, ExposureMask, &ev); - } - if (thereIsOne) { - XPutBackEvent(dpy, &ev); - rslt = true; - } - LEAVE_XLIB(); - } - RETURN ( rslt ); -%} -! - -getEventFor:aViewIdOrNil withMask:eventMask - "read next event - put into local eventBuffer. - If aViewIdOrNil is nil, events for any view are fetched; - otherwise only events for that specific view will be fetched. - Returns true, if there was an event, false otherwise. - This method may block - so you better check for pending events - before calling for it." - - ^ self getEventFor:aViewIdOrNil withMask:eventMask into:eventBuffer -! - -getEventFor:aViewIdOrNil withMask:eventMask into:anEventBuffer - "read next event - put into anEventBuffer. - If aViewIdOrNil is nil, events for any view are fetched; - otherwise only events for that specific view will be fetched. - Returns true, if there was an event, false otherwise. - This method may block - so you better check for pending events - before calling for it. - - Sorry I had to split dispatch into this fetch method and an extra - handle method to allow unlimitedstack here. - (some Xlibs do a big alloca there ...) which cannot be done in - dispatchLastEvent, since it dispatches out into ST-methods. - " - -%{ /* UNLIMITEDSTACK */ - - Display *dpy; - Window win, wWanted; - int evMask; - XEvent *ev; - - if (! ISCONNECTED) { - RETURN (false); - } - - dpy = myDpy; - - if (__isByteArray(anEventBuffer)) { - ev = (XEvent *)(__ByteArrayInstPtr(anEventBuffer)->ba_element); - } else { - printf("DISPLAY: bad eventBuffer\n"); - RETURN (false); - } - ev->type = 0; - - if (__isSmallInteger(eventMask)) { - evMask = __intVal(eventMask); - } else { - evMask = ~0; - } - - if (__isExternalAddress(aViewIdOrNil)) { - wWanted = _WindowVal(aViewIdOrNil); - if (XCheckWindowEvent(dpy, wWanted, evMask, ev)) { - RETURN ( true ); - } - } else { - if (evMask == ~0) { - XNextEvent(dpy, ev); - RETURN (true); - } - if (XCheckMaskEvent(dpy, evMask, ev)) { - RETURN (true); - } - } - RETURN (false); -%}. - ^ self primitiveFailed -! - -handleAllEvents - "from now on, handle any kind of event" - - dispatchingExpose := nil -! - -handleExposeOnlyFor:aView - "from now on, handle expose events only" - - dispatchingExpose := aView id -! - mappingChanged:what event:eB - "One of Keyboard-, Modifier- or PointerMap has change, probably by xmodmap. + "OBSOLETE with newDispatchLastEvent!! + One of Keyboard-, Modifier- or PointerMap has change, probably by xmodmap. Tell xlib about the fact." (what == #mappingKeyboard or:[what == #mappingModifier]) ifTrue:[ - self refreshKeyboardMapping:eB. - "Maybe some of our modifiers have been changed" - self initializeModifierMappings. + self refreshKeyboardMapping:eB. + "Maybe some of our modifiers have been changed" + self initializeModifierMappings. ]. "Created: 1.12.1995 / 16:28:23 / stefan" -! - -newDispatchLastEvent - |arr| - - arr := Array new:13. - self decomposeEventBuffer:eventBuffer into:arr. - (self dispatchLastEvent:arr) ifFalse:[ - self dispatchLastEvent - ] -! - -setEventMask:aMask in:aWindowId - "tell X that we are only interested in events from aMask, which - is the bitwise or of the eventMask bits (see 'eventMaskFor:')" - - -%{ - - int mask; - - if (ISCONNECTED - && __isExternalAddress(aWindowId) - && __isSmallInteger(aMask)) { - mask = __intVal(aMask); - -#ifdef OLD - /* these may not be disabled */ - mask |= ExposureMask | StructureNotifyMask | - KeyPressMask | KeyReleaseMask | - EnterWindowMask | LeaveWindowMask | - ButtonPressMask | ButtonMotionMask | ButtonReleaseMask; -#endif - - ENTER_XLIB(); - XSelectInput(myDpy, _WindowVal(aWindowId), mask); - LEAVE_XLIB(); - RETURN ( self ); - } -%}. - self primitiveFailedOrClosedConnection -! - -startDispatch - "redefined to clear dispatchingExpose, which is a special X feature" - - dispatching ifTrue:[^ self]. - dispatchingExpose := nil. - super startDispatch ! ! !XWorkstation methodsFor:'event sending'! @@ -11633,6 +11652,6 @@ !XWorkstation class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.373 2000-09-26 15:15:56 cg Exp $' + ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.374 2000-09-28 16:24:27 stefan Exp $' ! ! XWorkstation initialize!