📄 event.c
字号:
if (event->object != NULL) *str = GetWin(event->object)->name; else *str = ""; return(YES); } /* Objname variable */ if (!strcmp("objname",name)) { if (event->object != NULL) *str = GetNameGObject(event->object); else *str = ""; return(YES); } /* Type variable */ if (!strcmp("type",name)) { switch(event->type) { case KeyDown1: *str = "keyDown"; break; case KeyUp: *str = "keyUp"; break; case ButtonUp: *str = "buttonUp"; break; case ButtonDown: *str = "buttonDown"; break; case Enter: *str = "enter"; break; case Leave: *str = "leave"; break; case MouseMotion: *str = "mouseMotion"; break; case Draw: *str = "draw"; break; case Del: *str = "delete"; break; case ErrorEvent: *str = "errorEvent"; break; default : Errorf("GetEventVariable2() : event type %d unknown",event->type); } return(YES); } /* Button variable */ if (!strcmp("button",name)) { switch(event->type) { case ButtonDown : case ButtonUp: case MouseMotion : *str = ButtonCode2Str(event->button); break; default : Errorf("GetEventVariable2() : bad button"); } return(YES); } /* i, j, m and n variables (mouse global coordinates) */ if (!strncmp("i",name,1)) {*f = event->i; return(YES);} if (!strncmp("j",name,1)) {*f = event->j; return(YES);} if (!strncmp("m",name,1)) {*f = event->m; return(YES);} if (!strncmp("n",name,1)) {*f = event->n; return(YES);} /* x,y,w and h variables (mouse local coordinates) */ if (!strncmp("x",name,1)) {*f = event->x; return(YES);} if (!strncmp("y",name,1)) {*f = event->y; return(YES);} if (!strncmp("w",name,1)) {*f = event->w; return(YES);} if (!strncmp("h",name,1)) {*f = event->h; return(YES);} return(NO);} /************************************************************************ * * Main Function that process bindings * * - It process any binding script attached to 'event' * - It returns either NULL or sequence of key code that must be printed on the terminal * - If it is waiting for a key sequence to be completed it changes * 'event' so that its type corresponds to NoEvent * ************************************************************************/ static void Add1Event(void){ /* Here we just count the number of received events */ if (toplevelCur->nEvents < ULONG_MAX) toplevelCur->nEvents++; else toplevelCur->nEvents = 1;} static unsigned long *DoBinding(EVENT event) { EVENT event1; BINDING b,b1; BINDING *theBindings; int c,i,i1,j; char flagFirst; GCLASS classCur = NULL; /* The following variables are used for buffering key events for binded KeyDown1 sequences */ static unsigned long bKeys[MaxLengthKeySeq]; static unsigned long termKeys[MaxLengthKeySeq]; unsigned long *result = NULL; static GOBJECT object = NULL; static int nKeys = 0; static int nKeysToPull = 0; static char flagKeyIsOk; if (event->type == NoEvent) return(NULL); /* No Event */ if (event->type & DelayEvent || event->type & TimeEvent) { event->object = NULL; } /* * We should empty the buffer if an event happened in another object or an event different from a key event * or a mouse motion event happened in the object */ if (nKeys != 0 && (event->object != object || !(event->type & (KeyUp | KeyDown1 | MouseMotion)))) { if (object == NULL) { /* Case of the terminal */ memcpy(termKeys,bKeys,sizeof(unsigned long)*nKeys); termKeys[nKeys] = 0; result = termKeys; } nKeys = 0; nKeysToPull = 0; } /* If the buffer is empty then we should not pull any keys out of it */ if (nKeys == 0) nKeysToPull = 0; if (event->object != NULL) classCur = event->object->classCur; /* * If we are dealing with GObject bindings then we need to put the event->key in the buffer if * keyDown event moreover we have to set te flag that will tell us if we have a chance to * match a binding */ if (event->type == KeyDown1 && (event->object == NULL || classCur == theGObjectClass)) { bKeys[nKeys] = event->key; nKeys++; flagKeyIsOk = NO; object = event->object; } /* We get the corresponding bindings (and set back the current class of the object to its original class) */ if (event->object == NULL) theBindings = theTerminalBindings; else { theBindings = event->object->classCur->theBindings; event->object->classCur = event->object->gclass; } /* The index in the "theBindings" list */ c = GetBindingCategory(event->type); /* We store the event */ event1 = toplevelCur->lastEvent; toplevelCur->lastEvent = event; /* Loop on the bindings */ b = theBindings[c]; if (b != NULL) b->state = BindingOff; flagFirst = YES; while(1) { /* Case the first binding is NULL */ if (b == NULL) break; /* Should we delete the binding whose script was just executed ? */ if (b->state == Binding2BeDeleted) { b1 = b->next; DeleteBinding(b); b = b1; } /* If it is not the first time the loop is being executed, we must get the next binding */ else if (!flagFirst) { b->state = BindingOff; b = b->next; } /* If no binding then leave the loop */ if (b == NULL) break; /* Next time in the loop will not be the first time */ flagFirst = NO; /* Init the state */ b->state = BindingOff; /* Go to next binding if binding is not active */ if (b->group != NULL && b->group->flagActive == NO) continue; /* Go to next binding if binding does not match the eventtype */ if ((b->eventType & event->type) == 0) continue; /* * Buttons */ if (event->type & (ButtonUp + ButtonDown)) { /* Go to next binding if binding does not match the right button */ if ((b->button & ModMask) != ModAny && (b->button & ModMask) != (event->button & ModMask)) continue; if (!(b->button & ButtonMask & event->button)) continue; b->state = BindingOn; EvalScript(b->script,NO); Add1Event(); InitResult(); } /* * Motion */ else if (event->type & MouseMotion) { /* Go to next binding if binding does not match the right button */ if ((b->button & ModMask) != ModAny && (b->button & ModMask) != (event->button & ModMask)) continue; if (!(b->button & ButtonMask & event->button)) continue; b->state = BindingOn; EvalScript(b->script,NO); InitResult(""); Add1Event(); } /* * Enter/Leave */ else if (event->type & (Enter + Leave)) { b->state = BindingOn; EvalScript(b->script,NO); Add1Event(); InitResult(); } /* * KeyUp */ else if (event->type & KeyUp) { /* Go to next binding if binding does not match the right key */ if (event->key != b->keys[0] && (b->keys[0] != AnyKC || event->key == EscapeKC) && ((event->key & ModMask) != ModAny || (event->key & KeyMask) != b->keys[0])) continue; b->state = BindingOn; EvalScript(b->script,NO); Add1Event(); InitResult(); } /* * KeyDown1 */ else if (event->type & KeyDown1) { i = b->nKeys; while (1) { /* * Look for the next character (reverse order) in the binding sequence that matches the character * that was just typed */ i--; for (;i>=0;i--) if (bKeys[nKeys-1] == b->keys[i] || (b->keys[i] == AnyKC && event->key != EscapeKC)) break; /* If there is none then it's over */ if (i == -1) break; /* Otherwise we try to match the buffered keys */ for (i1 = i-1,j = nKeys-2;i1>=0 && j >= 0;i1--,j--) if (bKeys[j] != b->keys[i1] && (b->keys[i1] != AnyKC || bKeys[j] == EscapeKC)) break; /* If we could not match all the first binded keys (up to the ith) then we go on */ if (i1 != -1) continue; /* If we haven't match all the binding sequence then we should wait */ if (i != b->nKeys-1) { flagKeyIsOk = YES; continue; } /* * We need to remember how many keys * have to be pulled out from the buffer. */ nKeysToPull = MAX(nKeysToPull,i+1); b->state = BindingOn; EvalScript(b->script,NO); Add1Event(); InitResult(); break; } } /* * Draw or Delete Graph event */ else if (event->type & (Draw + Del)) { b->state = BindingOn; EvalScript(b->script,NO); Add1Event(); InitResult(); } /* * Error event */ else if (event->type & ErrorEvent) { b->state = BindingOn; EvalScript(b->script,NO); Add1Event(); InitResult(); } /* * Time events */ else if ((event->type & TimeEvent) && b->eventType == TimeEvent) { if (event->timer == b->timer) { b->timer = event->timer = NULL; b->state = BindingOn; EvalScript(b->script,NO); InitResult(); b->state = Binding2BeDeleted; } } /* * Delay event */ else if ((event->type & DelayEvent) && b->eventType == DelayEvent) { if (event->timer == b->timer) { b->state = BindingOn; EvalScript(b->script,NO); InitResult(); } } } /* * We are dealing (in a loop) first at the bindings of the GObjects * then the bindings of the class below it and so on * down to the class of the object. * If this is the case and the event->type is a keyDown, then we need * to pull out some keys from the buffer. * If there is none we have to check the flagKeyIsOk. */ if (event->type == KeyDown1 && (event->object == NULL || classCur == event->object->gclass)) { if (nKeysToPull == 0) { if (!flagKeyIsOk) { /* We empty te buffer */ if (object == NULL) { /* case of the terminal */ memcpy(termKeys,bKeys,sizeof(unsigned long)*nKeys); termKeys[nKeys] = 0; result = termKeys; } nKeys = 0; } else event->type = NoEvent; } else { if (nKeysToPull > nKeys) Errorf("DoBindings() : Weird error"); /* We pull the keys */ for (i=0,j=nKeysToPull;j<nKeys;i++,j++) bKeys[i] = bKeys[j]; bKeys[i] = 0; nKeys = i; nKeysToPull = 0; event->type = NoEvent; } } /* We restore the event */ toplevelCur->lastEvent = event1; return(result);}/************************************************************************** * * This function is just for debugging * **************************************************************************/// #define DEBUGEVENT 1 static void PrintEvent(EVENT event){ if (event->object == NULL) return; switch(event->type) { case ButtonDown: Printf("ButtonDown : GObject %s (%s), x = %g, y = %g [%d %d], button = %d mod = %d\n", event->object->name,event->object->classCur->name,event->x,event->y,event->i,event->j,event->button & ButtonMask, event->button & ModMask); break; case ButtonUp: Printf("ButtonUp : GObject %s (%s), x = %g, y = %g [%d %d], button = %d mod = %d\n", event->object->name,event->object->classCur->name,event->x,event->y,event->i,event->j,event->button & ButtonMask, event->button & ModMask); break; case Resize: Printf("Resize : GObject %s (%s), x = %g, y = %g, w = %g, h = %g [%d %d %d %d]\n", event->object->name,event->object->classCur->name,event->x,event->y,event->w,event->h,event->i,event->j,event->m,event->n); break; case Enter: Printf("Enter : GObject %s (%s) x= %g y = %g\n", event->object->name,event->object->classCur->name,event->x,event->y); break; case Leave: Printf("Leave : GObject %s (%s)\n", event->object->name,event->object->classCur->name); break; case KeyDown1: Printf("KeyDown1 : GObject %s (%s), x = %g, y = %g [%d %d] key = %d, (%c)\n", event->object->name,event->object->classCur->name,event->x,event->y,event->i,event->j,event->key,event->key); break; case KeyUp: Printf("KeyUp : GObject %s (%s), x = %g, y = %g [%d %d] key = %d, (%c)\n", event->object->name,event->object->classCur->name,event->x,event->y,event->i,event->j,event->key,event->key); break; case MouseMotion: Printf("MouseMotion : GObject %s (%s), button = %d, x = %g, y = %g [%d %d] mod = %d\n", event->object->name,event->object->classCur->name,event->button & ButtonMask,event->x,event->y,event->i,event->j,event->button & ModMask); break; case Draw: Printf("Draw : GObject %s (%s) x = %g, y = %g, w = %g, h = %g [%d %d %d %d]\n", event->object->name,event->object->classCur->name,event->x,event->y,event->w,event->h,event->i,event->j,event->m,event->n); break; case Del: Printf("Delete : GObject %s (%s)\n", event->object->name,event->object->classCur->name); break; }} /************************************************************************ * * Main Function for processing the next event * ************************************************************************//* * Static variables for remembering the last object that was visited by the mouse * and the object the user has pushed the mouse button in (if any) */static GOBJECT objButton = NULL;static GOBJECT objLast = NULL;static int depthLast = 0;static LWFLOAT xLast,yLast;static int iLast, jLast;/* * Subroutine called by 'Process1Event_' and 'SendEvent' only that processes the event 'event' */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -