add: if (textEvent) { WMNotification *notif = WMCreateNotification(textEvent, tPtr, data);  if (tPtr->delegate) { if (textEvent==WMTextDidBeginEditingNotification && tPtr->delegate->didBeginEditing) (*tPtr->delegate->didBeginEditing)(tPtr->delegate, notif); else if (textEvent==WMTextDidEndEditingNotification && tPtr->delegate->didEndEditing) (*tPtr->delegate->didEndEditing)(tPtr->delegate, notif); else if (textEvent==WMTextDidChangeNotification && tPtr->delegate->didChange) (*tPtr->delegate->didChange)(tPtr->delegate, notif); }  WMPostNotification(notif); WMReleaseNotification(notif); }
context: handleTextFieldKeyPress(TextField *tPtr, XEvent *event){    char buffer[64];    KeySym ksym;    int count, refresh = 0;    int control_pressed = 0;    int cancelSelection = 1;    /*printf("(%d,%d) -> ", tPtr->selection.position, tPtr->selection.count);*/    if (((XKeyEvent *) event)->state & WM_EMACSKEYMASK)	control_pressed = 1;    count = XLookupString(&event->xkey, buffer, 63, &ksym, NULL);    buffer[count] = '\0';    /* Be careful in any case in this switch statement, never to call     * to more than a function that can generate text change notifications.     * Only one text change notification should be sent in any case.     * Else hazardous things can happen.     * Maybe we need a better solution than the function wrapper to inform     * functions that change text in text fields, if they need to send a     * change notification or not. -Dan     */    switch (ksym) {     case XK_Tab:#ifdef XK_ISO_Left_Tab     case XK_ISO_Left_Tab:#endif	if (event->xkey.state & ShiftMask) {	    if (tPtr->view->prevFocusChain) {		W_SetFocusOfTopLevel(W_TopLevelOfView(tPtr->view),				     tPtr->view->prevFocusChain);		tPtr->flags.notIllegalMovement = 1;	    }	    NOTIFY(tPtr, didEndEditing, WMTextDidEndEditingNotification,		   (void*)WMBacktabTextMovement);	} else {	    if (tPtr->view->nextFocusChain) {		W_SetFocusOfTopLevel(W_TopLevelOfView(tPtr->view),				     tPtr->view->nextFocusChain);		tPtr->flags.notIllegalMovement = 1;	    }	    NOTIFY(tPtr, didEndEditing, WMTextDidEndEditingNotification,		   (void*)WMTabTextMovement);	}	break;     case XK_Return:	NOTIFY(tPtr, didEndEditing, WMTextDidEndEditingNotification,	       (void*)WMReturnTextMovement);	break;     case WM_EMACSKEY_LEFT:	if (!control_pressed) {	    goto normal_key;	}#ifdef XK_KP_Left     case XK_KP_Left:#endif     case XK_Left:	if (tPtr->cursorPosition > 0) {	    paintCursor(tPtr);            if (event->xkey.state & ControlMask) {    	    	int i = tPtr->cursorPosition - 1;						while (i > 0 && tPtr->text[i] != ' ') i--;		while (i > 0 && tPtr->text[i] == ' ') i--;		tPtr->cursorPosition = (i > 0) ? i + 1 : 0;            } else		tPtr->cursorPosition--;	    if (tPtr->cursorPosition < tPtr->viewPosition) {		tPtr->viewPosition = tPtr->cursorPosition;		refresh = 1;	    } else		paintCursor(tPtr);	}	if (event->xkey.state & ShiftMask)	    cancelSelection = 0;	break;    case WM_EMACSKEY_RIGHT:        if (!control_pressed) {            goto normal_key;        }#ifdef XK_KP_Right    case XK_KP_Right:#endif    case XK_Right:	if (tPtr->cursorPosition < tPtr->textLen) {	    paintCursor(tPtr);            if (event->xkey.state & ControlMask) {    	    	int i = tPtr->cursorPosition;				    	    	while (tPtr->text[i] && tPtr->text[i] != ' ') i++;    	    	while (tPtr->text[i] == ' ') i++;    	    	tPtr->cursorPosition = i;            } else {               tPtr->cursorPosition++;            }	    while (WMWidthOfString(tPtr->font,				&(tPtr->text[tPtr->viewPosition]),				tPtr->cursorPosition-tPtr->viewPosition)		   > tPtr->usableWidth) {		tPtr->viewPosition++;		refresh = 1;	    }	    if (!refresh)		paintCursor(tPtr);	}	if (event->xkey.state & ShiftMask)	    cancelSelection = 0;	break;	    case WM_EMACSKEY_HOME:        if (!control_pressed) {            goto normal_key;        }#ifdef XK_KP_Home    case XK_KP_Home:#endif    case XK_Home:	if (tPtr->cursorPosition > 0) {	    paintCursor(tPtr);	    tPtr->cursorPosition = 0;	    if (tPtr->viewPosition > 0) {		tPtr->viewPosition = 0;		refresh = 1;	    } else		paintCursor(tPtr);	}	if (event->xkey.state & ShiftMask)	    cancelSelection = 0;	break;	    case WM_EMACSKEY_END:        if (!control_pressed) {            goto normal_key;        }#ifdef XK_KP_End    case XK_KP_End:#endif    case XK_End:	if (tPtr->cursorPosition < tPtr->textLen) {	    paintCursor(tPtr);	    tPtr->cursorPosition = tPtr->textLen;	    tPtr->viewPosition = 0;	    while (WMWidthOfString(tPtr->font,				   &(tPtr->text[tPtr->viewPosition]),				   tPtr->textLen-tPtr->viewPosition)		   > tPtr->usableWidth) {		tPtr->viewPosition++;		refresh = 1;	    }	    if (!refresh)		paintCursor(tPtr);	}	if (event->xkey.state & ShiftMask)	    cancelSelection = 0;	break;	     case WM_EMACSKEY_BS:         if (!control_pressed) {             goto normal_key;         }     case XK_BackSpace:     	if (tPtr->selection.count) {	    WMDeleteTextFieldRange(tPtr, tPtr->selection);            NOTIFY(tPtr, didChange, WMTextDidChangeNotification,                   (void*)WMDeleteTextEvent);	} else if (tPtr->cursorPosition > 0) {            WMRange range;            range.position = tPtr->cursorPosition - 1;            range.count = 1;	    WMDeleteTextFieldRange(tPtr, range);            NOTIFY(tPtr, didChange, WMTextDidChangeNotification,                   (void*)WMDeleteTextEvent);	}	break;	    case WM_EMACSKEY_DEL:        if (!control_pressed) {            goto normal_key;        }#ifdef XK_KP_Delete    case XK_KP_Delete:#endif    case XK_Delete:     	if (tPtr->selection.count) {	    WMDeleteTextFieldRange(tPtr, tPtr->selection);            NOTIFY(tPtr, didChange, WMTextDidChangeNotification,                   (void*)WMDeleteTextEvent);	} else if (tPtr->cursorPosition < tPtr->textLen) {            WMRange range;            range.position = tPtr->cursorPosition;            range.count = 1;	    WMDeleteTextFieldRange(tPtr, range);            NOTIFY(tPtr, didChange, WMTextDidChangeNotification,                   (void*)WMDeleteTextEvent);	}	break;    normal_key:     default:	if (count > 0 && !iscntrl(buffer[0])) {            if (tPtr->selection.count) {                WMDeleteTextFieldRange(tPtr, tPtr->selection);                tPtr->selection.count = 0;                refresh = 1;            }            /* TODO: check if this is correct. */            cancelSelection = 0;	    WMInsertTextFieldText(tPtr, buffer, tPtr->cursorPosition);            tPtr->selection.position = tPtr->cursorPosition;            NOTIFY(tPtr, didChange, WMTextDidChangeNotification,                   (void*)WMInsertTextEvent);	} else	    return;	break;    }    if (!cancelSelection) {    	if (tPtr->selection.count != tPtr->cursorPosition - tPtr->selection.position) {	    WMNotification *notif;	                tPtr->selection.count = tPtr->cursorPosition - tPtr->selection.position;            XSetSelectionOwner(tPtr->view->screen->display,                    	       XA_PRIMARY, tPtr->view->window,			       event->xbutton.time);            notif = WMCreateNotification("_lostOwnership", NULL,tPtr);            WMPostNotification(notif);            WMReleaseNotification(notif);            refresh = 1;        }    } else {    	if (tPtr->selection.count) {    	    tPtr->selection.count = 0;            refresh = 1;	}    	tPtr->selection.position = tPtr->cursorPosition;    }    if (refresh)	paintTextField(tPtr);    /*printf("(%d,%d)\n", tPtr->selection.position, tPtr->selection.count);*/}