Esempio n. 1
0
static void handle_focus_out(const XFocusChangeEvent *ev)
{
	WWindow *wwin;
	WScreen *scr;

	/*if(ev->window==SCREEN->root.win){
		SCREEN->active=FALSE;
		wwin=wglobal.current_wswindow;
		if(wwin!=NULL)
			redraw_wwin(wwin);
		return;
	}*/

	if(ev->mode==NotifyGrab || ev->mode==NotifyUngrab || ev->detail>NotifyNonlinearVirtual)
		return;

	wwin=FIND_WINDOW_T(ev->window, WWindow);
	
	if(wwin==NULL)
		return;
	
	scr=SCREEN_OF(wwin);
	if(ev->window==scr->root.win)
		return;

	if(wwin->xic!=NULL)
		XUnsetICFocus(wwin->xic);
}
void
CXWindowsPrimaryScreen::onPreEnter()
{
	assert(m_window != None);

	if (m_ic != NULL) {
		XUnsetICFocus(m_ic);
	}
}
Esempio n. 3
0
/*
 * Sets or unsets the focus to the given XIC.
 */
static void
setXICFocus(XIC ic, unsigned short req)
{
    if (ic == NULL) {
        (void)fprintf(stderr, "Couldn't find X Input Context\n");
        return;
    }
    if (req == 1)
        XSetICFocus(ic);
    else
        XUnsetICFocus(ic);
}
Esempio n. 4
0
/* this function should be called within AWT_LOCK() */
static void
destroyX11InputMethodData(JNIEnv *env, X11InputMethodData *pX11IMData)
{
    /*
     * Destroy XICs
     */
    if (pX11IMData->ic_active != (XIC)0) {
        XUnsetICFocus(pX11IMData->ic_active);
	XDestroyIC(pX11IMData->ic_active);
	if (pX11IMData->ic_active != pX11IMData->ic_passive) {
	    if (pX11IMData->ic_passive != (XIC)0) {
		XUnsetICFocus(pX11IMData->ic_passive);
		XDestroyIC(pX11IMData->ic_passive);
	    }
	    pX11IMData->ic_passive = (XIC)0;
	    pX11IMData->current_ic = (XIC)0;
	}
    }

    freeX11InputMethodData(env, pX11IMData);
}
Esempio n. 5
0
static void
X11_DispatchFocusOut(SDL_WindowData *data)
{
#ifdef DEBUG_XEVENTS
    printf("window %p: Dispatching FocusOut\n", data);
#endif
    SDL_SetKeyboardFocus(NULL);
#ifdef X_HAVE_UTF8_STRING
    if (data->ic) {
        XUnsetICFocus(data->ic);
    }
#endif
}
Esempio n. 6
0
/**********************************************************************
 *              EVENT_FocusOut
 *
 * Note: only top-level windows get FocusOut events.
 */
static void EVENT_FocusOut( HWND hwnd, XEvent *xev )
{
    XFocusChangeEvent *event = &xev->xfocus;
    HWND hwnd_tmp;
    Window focus_win;
    int revert;
    XIC xic;

    if (!hwnd) return;

    TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] );

    if (event->detail == NotifyPointer) return;
    if (ximInComposeMode) return;

    x11drv_thread_data()->last_focus = hwnd;
    if ((xic = X11DRV_get_ic( hwnd )))
    {
        wine_tsx11_lock();
        XUnsetICFocus( xic );
        wine_tsx11_unlock();
    }
    if (hwnd != GetForegroundWindow()) return;
    SendMessageW( hwnd, WM_CANCELMODE, 0, 0 );

    /* don't reset the foreground window, if the window which is
       getting the focus is a Wine window */

    wine_tsx11_lock();
    XGetInputFocus( thread_display(), &focus_win, &revert );
    if (focus_win)
    {
        if (XFindContext( thread_display(), focus_win, winContext, (char **)&hwnd_tmp ) != 0)
            focus_win = 0;
    }
    wine_tsx11_unlock();

    if (!focus_win)
    {
        /* Abey : 6-Oct-99. Check again if the focus out window is the
           Foreground window, because in most cases the messages sent
           above must have already changed the foreground window, in which
           case we don't have to change the foreground window to 0 */
        if (hwnd == GetForegroundWindow())
        {
            TRACE( "lost focus, setting fg to 0\n" );
            SetForegroundWindow( 0 );
        }
    }
}
Esempio n. 7
0
static void
UnsetICFocus(Widget w, XawVendorShellExtPart *ve)
{
    XawIcTableList	p, pp;

    if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) ||
	(p->xic == NULL)) return;

    if (IsSharedIC(ve) && (pp = CurrentSharedIcTable(ve))) {
	if (pp->widget != w) {
	    return;
	}
	SharedICChangeFocusWindow(NULL, ve, p);
    }
    if (p->ic_focused == TRUE) {
	XUnsetICFocus(p->xic);
	p->ic_focused = FALSE;
    }
}
Esempio n. 8
0
static void
_ecore_imf_context_xim_focus_out(Ecore_IMF_Context *ctx)
{
   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
   XIC ic;

   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);

   if (imf_context_data->has_focus == EINA_TRUE)
     {
        imf_context_data->has_focus = EINA_FALSE;
        ic = imf_context_data->ic;
        if (ic)
          XUnsetICFocus(ic);

        if (ecore_imf_context_input_panel_enabled_get(ctx))
          ecore_imf_context_input_panel_hide(ctx);
     }
}
Esempio n. 9
0
static void
_ecore_imf_context_xim_focus_out(Ecore_IMF_Context *ctx)
{
   EINA_LOG_DBG("%s in", __FUNCTION__);
#ifdef ENABLE_XIM
   XIC ic;
   Ecore_IMF_Context_Data *imf_context_data;
   imf_context_data = ecore_imf_context_data_get(ctx);
   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);

   if (imf_context_data->has_focus == EINA_TRUE)
     {
        imf_context_data->has_focus = EINA_FALSE;
        ic = imf_context_data->ic;
        if (ic)
          XUnsetICFocus(ic);

        if (ecore_imf_context_input_panel_enabled_get(ctx))
          ecore_imf_context_input_panel_hide(ctx);
     }
#else
   (void)ctx;
#endif
}
Esempio n. 10
0
int main_loop(int argc, char *argv[])
{
    setup_language();
    se_env* env = se_env_init();
    se_text_xviewer* viewer = se_text_xviewer_create( env );
    
    long im_event_mask;
    XGetICValues( viewer->xic, XNFilterEvents, &im_event_mask, NULL );

    int mask = ExposureMask | ButtonPressMask | ButtonReleaseMask
        | KeyPressMask | KeyReleaseMask | SubstructureNotifyMask
        | FocusChangeMask
        | im_event_mask;
    XSelectInput( env->display, viewer->view, mask );
    XSetICFocus( viewer->xic );
    
    viewer->repaint( viewer );    
    viewer->show( viewer );
    
    while ( 1 ) { // sync the first expose event
        XEvent ev;
        XNextEvent( env->display, &ev );
        if ( ev.xany.window == viewer->view && ev.type == Expose ) {
            viewer->redisplay( viewer );
            break;
        }
    }

    while( !env->exitLoop ) {
        XEvent ev;
        XNextEvent( env->display, &ev );
        if ( XFilterEvent( &ev, None ) == True ) {
            se_debug("IM filtered event: %s", XEventTypeString(ev.type) );
            continue;
        }
        
        if ( ev.xany.window != viewer->view ) {
            se_msg( "skip event does not forward to view" );
            continue;
        }
        
        switch( ev.type ) {
        case Expose:
            se_debug( "Expose" );
            if ( ev.xexpose.count > 0 )
                break;

            viewer->redisplay( viewer );
            break;

        case KeyPress:
        case KeyRelease:
            viewer->key_handler( viewer, &ev );
            break;

        case ConfigureNotify:
        case MapNotify:
            se_debug( "confiugration changed" );
            viewer->configure_change_handler( viewer, &ev );
            break;

        default:
            break;
        }
    }

    se_debug( "exit loop" );

    XUnsetICFocus( viewer->xic );
    XDestroyIC( viewer->xic );
    se_env_release( env );
    return 0;
}
Esempio n. 11
0
void
x_window_rep::focus_out_event () {
  if (ic_ok) XUnsetICFocus (ic);
  has_focus= false;
  notify_keyboard_focus (kbd_focus, false);
}
Esempio n. 12
0
static void
scalefilterHandleKeyPress (CompScreen *s,
			   XKeyEvent  *event)
{
    ScaleFilterInfo *info;
    Bool            needRelayout = FALSE;
    Bool            dropKeyEvent = FALSE;
    int             count, timeout;
    char            buffer[10];
    wchar_t         wbuffer[10];
    KeySym          ks;

    FILTER_DISPLAY (s->display);
    FILTER_SCREEN (s);
    SCALE_SCREEN (s);

    info = fs->filterInfo;
    memset (buffer, 0, sizeof (buffer));
    memset (wbuffer, 0, sizeof (wbuffer));

    if (fd->xic)
    {
	Status status;

	XSetICFocus (fd->xic);
	count = Xutf8LookupString (fd->xic, event, buffer, 9, &ks, &status);
	XUnsetICFocus (fd->xic);
    }
    else
    {
	count = XLookupString (event, buffer, 9, &ks, NULL);
    }

    mbstowcs (wbuffer, buffer, 9);

    if (ks == XK_Escape)
    {
	if (info)
	{
	    /* Escape key - drop current filter */
	    ss->currentMatch = info->origMatch;
	    scalefilterFiniFilterInfo (s, TRUE);
	    needRelayout = TRUE;
	    dropKeyEvent = TRUE;
	}
	else if (fs->matchApplied)
	{
	    /* remove filter applied previously
	       if currently not in input mode */
	    matchFini (&ss->match);
	    matchInit (&ss->match);
	    matchCopy (&ss->match, &fs->scaleMatch);
	    matchUpdate (s->display, &ss->match);

	    ss->currentMatch = &ss->match;
	    fs->matchApplied = FALSE;
	    needRelayout = TRUE;
	    dropKeyEvent = TRUE;
	}
    }
    else if (ks == XK_Return)
    {
	if (info)
	{
	    /* Return key - apply current filter persistently */
	    matchFini (&ss->match);
	    matchInit (&ss->match);
	    matchCopy (&ss->match, &info->match);
	    matchUpdate (s->display, &ss->match);

	    ss->currentMatch = &ss->match;
	    fs->matchApplied = TRUE;
	    dropKeyEvent = TRUE;
	    needRelayout = TRUE;
	    scalefilterFiniFilterInfo (s, TRUE);
	}
    }
    else if (ks == XK_BackSpace)
    {
	if (info && info->filterStringLength > 0)
	{
	    /* remove last character in string */
	    info->filterString[--(info->filterStringLength)] = '\0';
	    needRelayout = TRUE;
	}
    }
    else if (count > 0)
    {
	if (!info)
	{
	    fs->filterInfo = info = malloc (sizeof (ScaleFilterInfo));
	    scalefilterInitFilterInfo (s);
	}
	else if (info->timeoutHandle)
	    compRemoveTimeout (info->timeoutHandle);

	timeout = scalefilterGetTimeout (s);
	if (timeout > 0)
	    info->timeoutHandle = compAddTimeout (timeout,
				     		  scalefilterFilterTimeout, s);

	if (info->filterStringLength < MAX_FILTER_SIZE)
	{
	    info->filterString[info->filterStringLength++] = wbuffer[0];
	    info->filterString[info->filterStringLength] = '\0';
	    needRelayout = TRUE;
	}
    }

    /* set the event type invalid if we
       don't want other plugins see it */
    if (dropKeyEvent)
	event->type = LASTEvent+1;

    if (needRelayout)
    {
	scalefilterRenderFilterText (s);

	if (fs->filterInfo)
	    scalefilterUpdateFilter (s, &fs->filterInfo->match);

	scalefilterRelayout (s);
    }
}
Esempio n. 13
0
/* Create auxiliary (toplevel) windows with the current visual */
static void create_aux_windows(_THIS)
{
    int x = 0, y = 0;
    char classname[1024];
    XSetWindowAttributes xattr;
    XWMHints *hints;
    unsigned long app_event_mask;
    int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen));

    /* Look up some useful Atoms */
    WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);

    /* Don't create any extra windows if we are being managed */
    if ( SDL_windowid ) {
	FSwindow = 0;
	WMwindow = SDL_strtol(SDL_windowid, NULL, 0);
        return;
    }

    if(FSwindow)
	XDestroyWindow(SDL_Display, FSwindow);

#if SDL_VIDEO_DRIVER_X11_XINERAMA
    if ( use_xinerama ) {
        x = xinerama_info.x_org;
        y = xinerama_info.y_org;
    }
#endif
    xattr.override_redirect = True;
    xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0;
    xattr.border_pixel = 0;
    xattr.colormap = SDL_XColorMap;

    FSwindow = XCreateWindow(SDL_Display, SDL_Root,
                             x, y, 32, 32, 0,
			     this->hidden->depth, InputOutput, SDL_Visual,
			     CWOverrideRedirect | CWBackPixel | CWBorderPixel
			     | CWColormap,
			     &xattr);

    XSelectInput(SDL_Display, FSwindow, StructureNotifyMask);

    /* Tell KDE to keep the fullscreen window on top */
    {
	XEvent ev;
	long mask;

	SDL_memset(&ev, 0, sizeof(ev));
	ev.xclient.type = ClientMessage;
	ev.xclient.window = SDL_Root;
	ev.xclient.message_type = XInternAtom(SDL_Display,
					      "KWM_KEEP_ON_TOP", False);
	ev.xclient.format = 32;
	ev.xclient.data.l[0] = FSwindow;
	ev.xclient.data.l[1] = CurrentTime;
	mask = SubstructureRedirectMask;
	XSendEvent(SDL_Display, SDL_Root, False, mask, &ev);
    }

    hints = NULL;
    if(WMwindow) {
	/* All window attributes must survive the recreation */
	hints = XGetWMHints(SDL_Display, WMwindow);
	XDestroyWindow(SDL_Display, WMwindow);
    }

    /* Create the window for windowed management */
    /* (reusing the xattr structure above) */
    WMwindow = XCreateWindow(SDL_Display, SDL_Root,
                             x, y, 32, 32, 0,
			     this->hidden->depth, InputOutput, SDL_Visual,
			     CWBackPixel | CWBorderPixel | CWColormap,
			     &xattr);

    /* Set the input hints so we get keyboard input */
    if(!hints) {
	hints = XAllocWMHints();
	hints->input = True;
	hints->flags = InputHint;
    }
    XSetWMHints(SDL_Display, WMwindow, hints);
    XFree(hints);
    X11_SetCaptionNoLock(this, this->wm_title, this->wm_icon);

    app_event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask
	| PropertyChangeMask | StructureNotifyMask | KeymapStateMask;
    XSelectInput(SDL_Display, WMwindow, app_event_mask);

    /* Set the class hints so we can get an icon (AfterStep) */
    get_classname(classname, sizeof(classname));
    {
	XClassHint *classhints;
	classhints = XAllocClassHint();
	if(classhints != NULL) {
	    classhints->res_name = classname;
	    classhints->res_class = classname;
	    XSetClassHint(SDL_Display, WMwindow, classhints);
	    XFree(classhints);
	}
    }

	/* Setup the communication with the IM server */
	/* create_aux_windows may be called several times against the same
	   Display.  We should reuse the SDL_IM if one has been opened for
	   the Display, so we should not simply reset SDL_IM here.  */

	#ifdef X_HAVE_UTF8_STRING
	if (SDL_X11_HAVE_UTF8) {
		/* Discard obsolete resources if any.  */
		if (SDL_IM != NULL && SDL_Display != XDisplayOfIM(SDL_IM)) {
			/* Just a double check. I don't think this
		           code is ever executed. */
			SDL_SetError("display has changed while an IM is kept");
			if (SDL_IC) {
				XUnsetICFocus(SDL_IC);
				XDestroyIC(SDL_IC);
				SDL_IC = NULL;
			}
			XCloseIM(SDL_IM);
			SDL_IM = NULL;
		}

		/* Open an input method.  */
		if (SDL_IM == NULL) {
			char *old_locale = NULL, *old_modifiers = NULL;
			const char *p;
			size_t n;
			/* I'm not comfortable to do locale setup
			   here.  However, we need C library locale
			   (and xlib modifiers) to be set based on the
			   user's preference to use XIM, and many
			   existing game programs doesn't take care of
			   users' locale preferences, so someone other
			   than the game program should do it.
			   Moreover, ones say that some game programs
			   heavily rely on the C locale behaviour,
			   e.g., strcol()'s, and we can't change the C
			   library locale.  Given the situation, I
			   couldn't find better place to do the
			   job... */

			/* Save the current (application program's)
			   locale settings.  */
			p = setlocale(LC_ALL, NULL);
			if ( p ) {
				n = SDL_strlen(p)+1;
				old_locale = SDL_stack_alloc(char, n);
				if ( old_locale ) {
					SDL_strlcpy(old_locale, p, n);
				}
			}
			p = XSetLocaleModifiers(NULL);
			if ( p ) {
				n = SDL_strlen(p)+1;
				old_modifiers = SDL_stack_alloc(char, n);
				if ( old_modifiers ) {
					SDL_strlcpy(old_modifiers, p, n);
				}
			}

			/* Fetch the user's preferences and open the
			   input method with them.  */
			setlocale(LC_ALL, "");
			XSetLocaleModifiers("");
			SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname);

			/* Restore the application's locale settings
			   so that we don't break the application's
			   expected behaviour.  */
			if ( old_locale ) {
				/* We need to restore the C library
				   locale first, since the
				   interpretation of the X modifier
				   may depend on it.  */
				setlocale(LC_ALL, old_locale);
				SDL_stack_free(old_locale);
			}
			if ( old_modifiers ) {
				XSetLocaleModifiers(old_modifiers);
				SDL_stack_free(old_modifiers);
			}
		}

		/* Create a new input context for the new window just created.  */
		if (SDL_IM == NULL) {
			SDL_SetError("no input method could be opened");
		} else {
			if (SDL_IC != NULL) {
				/* Discard the old IC before creating new one.  */
			    XUnsetICFocus(SDL_IC);
			    XDestroyIC(SDL_IC);
			}
			/* Theoretically we should check the current IM supports
			   PreeditNothing+StatusNothing style (i.e., root window method)
			   before creating the IC.  However, it is the bottom line method,
			   and we supports any other options.  If the IM didn't support
			   root window method, the following call fails, and SDL falls
			   back to pre-XIM keyboard handling.  */
			SDL_IC = pXCreateIC(SDL_IM,
					XNClientWindow, WMwindow,
					XNFocusWindow, WMwindow,
					XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
					XNResourceName, classname,
					XNResourceClass, classname,
					NULL);

			if (SDL_IC == NULL) {
				SDL_SetError("no input context could be created");
				XCloseIM(SDL_IM);
				SDL_IM = NULL;
			} else {
				/* We need to receive X events that an IM wants and to pass
				   them to the IM through XFilterEvent. The set of events may
				   vary depending on the IM implementation and the options
				   specified through various routes. Although unlikely, the
				   xlib specification allows IM to change the event requirement
				   with its own circumstances, it is safe to call SelectInput
				   whenever we re-create an IC.  */
				unsigned long mask = 0;
				char *ret = pXGetICValues(SDL_IC, XNFilterEvents, &mask, NULL);
				if (ret != NULL) {
					XUnsetICFocus(SDL_IC);
					XDestroyIC(SDL_IC);
					SDL_IC = NULL;
					SDL_SetError("no input context could be created");
					XCloseIM(SDL_IM);
					SDL_IM = NULL;
				} else {
					XSelectInput(SDL_Display, WMwindow, app_event_mask | mask);
					XSetICFocus(SDL_IC);
				}
			}
		}
	}
Esempio n. 14
0
static void HandleEvents( void )
{
	XEvent event;
	qboolean dowarp = qfalse, was_focused = focus;
	int mwx = x11display.win_width / 2;
	int mwy = x11display.win_height / 2;
	char *p;
	int key = 0;
	int time = 0;

	assert( x11display.dpy && x11display.win );

#ifdef WSW_EVDEV
	if( mouse_active && m_evdev_num )
	{
		evdev_read();
	}
	else
#endif
		if( mouse_active && !dgamouse )
		{
			int root_x, root_y, win_x, win_y;
			unsigned int mask;
			Window root, child;

			if( XQueryPointer( x11display.dpy, x11display.win, &root, &child,
				&root_x, &root_y, &win_x, &win_y, &mask ) )
			{
				mx += ( (int)win_x - mwx );
				my += ( (int)win_y - mwy );
				mwx = win_x;
				mwy = win_y;

				if( mx || my )
					dowarp = qtrue;

				if( ignore_one )
				{
					mx = my = 0;
					ignore_one = qfalse;
				}
			}
		}


		while( XPending( x11display.dpy ) )
		{
			XNextEvent( x11display.dpy, &event );

			switch( event.type )
			{
			case KeyPress:
				time = Sys_XTimeToSysTime(event.xkey.time);
				p = XLateKey( &event.xkey, &key );
				if( key )
					Key_Event( key, qtrue, time );
				while ( p && *p )
				{
					qwchar wc = Q_GrabWCharFromUtf8String( (const char **)&p );
					Key_CharEvent( key, wc );
				}
				break;

			case KeyRelease:
				if( repeated_press( &event ) )
					break; // don't send release events when repeating

				time = Sys_XTimeToSysTime(event.xkey.time);
				XLateKey( &event.xkey, &key );
				Key_Event( key, event.type == KeyPress, time );
				break;

			case MotionNotify:
#ifdef WSW_EVDEV
				if( mouse_active && dgamouse && !m_evdev_num )
#else
				if( mouse_active && dgamouse )
#endif
				{
					mx += event.xmotion.x_root;
					my += event.xmotion.y_root;
					if( ignore_one )
					{
						mx = my = 0;
						ignore_one = qfalse;
					}
				}
				break;

			case ButtonPress:
				if( ( cls.key_dest == key_console ) && !in_grabinconsole->integer )
					break;
#ifdef WSW_EVDEV
				if( m_evdev_num )
					break;
#endif
				time = Sys_XTimeToSysTime(event.xkey.time);
				if( event.xbutton.button == 1 ) Key_MouseEvent( K_MOUSE1, 1, time );
				else if( event.xbutton.button == 2 ) Key_MouseEvent( K_MOUSE3, 1, time );
				else if( event.xbutton.button == 3 ) Key_MouseEvent( K_MOUSE2, 1, time );
				else if( event.xbutton.button == 4 ) Key_Event( K_MWHEELUP, 1, time );
				else if( event.xbutton.button == 5 ) Key_Event( K_MWHEELDOWN, 1, time );
				else if( event.xbutton.button >= 6 && event.xbutton.button <= 10 ) Key_MouseEvent( K_MOUSE4+event.xbutton.button-6, 1, time );
				break;

			case ButtonRelease:
				if( ( cls.key_dest == key_console ) && !in_grabinconsole->integer )
					break;
#ifdef WSW_EVDEV
				if( m_evdev_num )
					break;
#endif
				time = Sys_XTimeToSysTime(event.xkey.time);
				if( event.xbutton.button == 1 ) Key_MouseEvent( K_MOUSE1, 0, time );
				else if( event.xbutton.button == 2 ) Key_MouseEvent( K_MOUSE3, 0, time );
				else if( event.xbutton.button == 3 ) Key_MouseEvent( K_MOUSE2, 0, time );
				else if( event.xbutton.button == 4 ) Key_Event( K_MWHEELUP, 0, time );
				else if( event.xbutton.button == 5 ) Key_Event( K_MWHEELDOWN, 0, time );
				else if( event.xbutton.button >= 6 && event.xbutton.button <= 10 ) Key_MouseEvent( K_MOUSE4+event.xbutton.button-6, 0, time );
				break;

			case FocusIn:
				if( x11display.ic )
					XSetICFocus(x11display.ic);
				if( !focus )
				{
					focus = qtrue;
				}
				break;

			case FocusOut:
				if( x11display.ic )
					XUnsetICFocus(x11display.ic);
				if( focus )
				{
					Key_ClearStates();
					focus = qfalse;
				}
				break;

			case ClientMessage:
				if( event.xclient.data.l[0] == x11display.wmDeleteWindow )
					Cbuf_ExecuteText( EXEC_NOW, "quit" );
				break;

			case MapNotify:
				mapped = qtrue;
				if( x11display.modeset )
				{
					if ( x11display.dpy && x11display.win )
					{
						XSetInputFocus( x11display.dpy, x11display.win, RevertToPointerRoot, CurrentTime );
						x11display.modeset = qfalse;
					}
				}
				if( input_active )
				{
					uninstall_grabs();
					install_grabs();
				}
				break;

			case ConfigureNotify:
				VID_AppActivate( qtrue, qfalse );
				break;

			case PropertyNotify:
				if( event.xproperty.window == x11display.win )
				{
					if ( event.xproperty.atom == x11display.wmState )
					{
						qboolean was_minimized = minimized;

						_X11_CheckWMSTATE();

						if( minimized != was_minimized )
						{
							// FIXME: find a better place for this?..
							CL_SoundModule_Activate( !minimized );
						}
					}
				}
				break;
			}
		}

		if( dowarp )
		{
			XWarpPointer( x11display.dpy, None, x11display.win, 0, 0, 0, 0,
				x11display.win_width/2, x11display.win_height/2 );
		}

		// set fullscreen or windowed mode upon focus in/out events if:
		//  a) lost focus in fullscreen -> windowed
		//  b) received focus -> fullscreen if a)
		if( ( focus != was_focused ) )
		{
			if( x11display.features.wmStateFullscreen )
			{
				if( !focus && Cvar_Value( "vid_fullscreen" ) )
				{
					go_fullscreen_on_focus = qtrue;
					Cbuf_ExecuteText( EXEC_APPEND, "vid_fullscreen 0\n" );
				}
				else if( focus && go_fullscreen_on_focus )
				{
					go_fullscreen_on_focus = qfalse;
					Cbuf_ExecuteText( EXEC_APPEND, "vid_fullscreen 1\n" );
				}
			}
		}
}
static void
X11_DispatchEvent(_THIS)
{
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    Display *display = videodata->display;
    SDL_WindowData *data;
    XEvent xevent;
    int i;

    SDL_zero(xevent);           /* valgrind fix. --ryan. */
    XNextEvent(display, &xevent);

    /* filter events catchs XIM events and sends them to the correct
       handler */
    if (XFilterEvent(&xevent, None) == True) {
#if 0
        printf("Filtered event type = %d display = %d window = %d\n",
               xevent.type, xevent.xany.display, xevent.xany.window);
#endif
        return;
    }

    /* Send a SDL_SYSWMEVENT if the application wants them */
    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
        SDL_SysWMmsg wmmsg;

        SDL_VERSION(&wmmsg.version);
        wmmsg.subsystem = SDL_SYSWM_X11;
        wmmsg.x11.event = xevent;
        SDL_SendSysWMEvent(&wmmsg);
    }

    data = NULL;
    if (videodata && videodata->windowlist) {
        for (i = 0; i < videodata->numwindows; ++i) {
            if ((videodata->windowlist[i] != NULL) &&
                (videodata->windowlist[i]->xwindow == xevent.xany.window)) {
                data = videodata->windowlist[i];
                break;
            }
        }
    }
    if (!data) {
        return;
    }

#if 0
    printf("type = %d display = %d window = %d\n",
           xevent.type, xevent.xany.display, xevent.xany.window);
#endif
    switch (xevent.type) {

        /* Gaining mouse coverage? */
    case EnterNotify:{
#ifdef DEBUG_XEVENTS
            printf("EnterNotify! (%d,%d,%d)\n", 
                   xevent.xcrossing.x,
                   xevent.xcrossing.y,
                   xevent.xcrossing.mode);
            if (xevent.xcrossing.mode == NotifyGrab)
                printf("Mode: NotifyGrab\n");
            if (xevent.xcrossing.mode == NotifyUngrab)
                printf("Mode: NotifyUngrab\n");
#endif
            SDL_SetMouseFocus(data->window);
        }
        break;
        /* Losing mouse coverage? */
    case LeaveNotify:{
#ifdef DEBUG_XEVENTS
            printf("LeaveNotify! (%d,%d,%d)\n", 
                   xevent.xcrossing.x,
                   xevent.xcrossing.y,
                   xevent.xcrossing.mode);
            if (xevent.xcrossing.mode == NotifyGrab)
                printf("Mode: NotifyGrab\n");
            if (xevent.xcrossing.mode == NotifyUngrab)
                printf("Mode: NotifyUngrab\n");
#endif
            if (xevent.xcrossing.mode != NotifyGrab &&
                xevent.xcrossing.mode != NotifyUngrab &&
                xevent.xcrossing.detail != NotifyInferior) {
                SDL_SetMouseFocus(NULL);
            }
        }
        break;

        /* Gaining input focus? */
    case FocusIn:{
#ifdef DEBUG_XEVENTS
            printf("FocusIn!\n");
#endif
            SDL_SetKeyboardFocus(data->window);
#ifdef X_HAVE_UTF8_STRING
            if (data->ic) {
                XSetICFocus(data->ic);
            }
#endif
        }
        break;

        /* Losing input focus? */
    case FocusOut:{
#ifdef DEBUG_XEVENTS
            printf("FocusOut!\n");
#endif
            SDL_SetKeyboardFocus(NULL);
#ifdef X_HAVE_UTF8_STRING
            if (data->ic) {
                XUnsetICFocus(data->ic);
            }
#endif
        }
        break;

        /* Generated upon EnterWindow and FocusIn */
    case KeymapNotify:{
#ifdef DEBUG_XEVENTS
            printf("KeymapNotify!\n");
#endif
            /* FIXME:
               X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector);
             */
        }
        break;

        /* Has the keyboard layout changed? */
    case MappingNotify:{
#ifdef DEBUG_XEVENTS
            printf("MappingNotify!\n");
#endif
            X11_UpdateKeymap(_this);
        }
        break;

        /* Key press? */
    case KeyPress:{
            KeyCode keycode = xevent.xkey.keycode;
            KeySym keysym = NoSymbol;
            SDL_scancode scancode;
            char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
            Status status = 0;

#ifdef DEBUG_XEVENTS
            printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
#endif
            SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
#if 1
            if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
                int min_keycode, max_keycode;
                XDisplayKeycodes(display, &min_keycode, &max_keycode);
                keysym = XKeycodeToKeysym(display, keycode, 0);
                fprintf(stderr,
                        "The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list <*****@*****.**> X11 KeyCode %d (%d), X11 KeySym 0x%lX (%s).\n",
                        keycode, keycode - min_keycode, keysym,
                        XKeysymToString(keysym));
            }
#endif
            /* */
            SDL_zero(text);
#ifdef X_HAVE_UTF8_STRING
            if (data->ic) {
                Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text),
                                  &keysym, &status);
            }
#else
            XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
#endif
            if (*text) {
                SDL_SendKeyboardText(text);
            }
        }
        break;

        /* Key release? */
    case KeyRelease:{
            KeyCode keycode = xevent.xkey.keycode;

#ifdef DEBUG_XEVENTS
            printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
#endif
            if (X11_KeyRepeat(display, &xevent)) {
                /* We're about to get a repeated key down, ignore the key up */
                break;
            }
            SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]);
        }
        break;

        /* Have we been iconified? */
    case UnmapNotify:{
#ifdef DEBUG_XEVENTS
            printf("UnmapNotify!\n");
#endif
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
        }
        break;

        /* Have we been restored? */
    case MapNotify:{
#ifdef DEBUG_XEVENTS
            printf("MapNotify!\n");
#endif
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
        }
        break;

        /* Have we been resized or moved? */
    case ConfigureNotify:{
#ifdef DEBUG_XEVENTS
            printf("ConfigureNotify! (resize: %dx%d)\n",
                   xevent.xconfigure.width, xevent.xconfigure.height);
#endif
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED,
                                xevent.xconfigure.x, xevent.xconfigure.y);
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED,
                                xevent.xconfigure.width,
                                xevent.xconfigure.height);
        }
        break;

        /* Have we been requested to quit (or another client message?) */
    case ClientMessage:{
            if ((xevent.xclient.format == 32) &&
                (xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) {

                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
            }
        }
        break;

        /* Do we need to refresh ourselves? */
    case Expose:{
#ifdef DEBUG_XEVENTS
            printf("Expose (count = %d)\n", xevent.xexpose.count);
#endif
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
        }
        break;

    case MotionNotify:{
#ifdef DEBUG_MOTION
            printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y);
#endif
            SDL_SendMouseMotion(data->window, 0, xevent.xmotion.x, xevent.xmotion.y);
        }
        break;

    case ButtonPress:{
            SDL_SendMouseButton(data->window, SDL_PRESSED, xevent.xbutton.button);
        }
        break;

    case ButtonRelease:{
            SDL_SendMouseButton(data->window, SDL_RELEASED, xevent.xbutton.button);
        }
        break;

    case PropertyNotify:{
#ifdef DEBUG_XEVENTS
            unsigned char *propdata;
            int status, real_format;
            Atom real_type;
            unsigned long items_read, items_left, i;

            char *name = XGetAtomName(display, xevent.xproperty.atom);
            if (name) {
                printf("PropertyNotify: %s %s\n", name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed");
                XFree(name);
            }

            status = XGetWindowProperty(display, data->xwindow, xevent.xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata);
            if (status == Success && items_read > 0) {
                if (real_type == XA_INTEGER) {
                    int *values = (int *)propdata;

                    printf("{");
                    for (i = 0; i < items_read; i++) {
                        printf(" %d", values[i]);
                    }
                    printf(" }\n");
                } else if (real_type == XA_CARDINAL) {
                    if (real_format == 32) {
                        Uint32 *values = (Uint32 *)propdata;

                        printf("{");
                        for (i = 0; i < items_read; i++) {
                            printf(" %d", values[i]);
                        }
                        printf(" }\n");
                    } else if (real_format == 16) {
                        Uint16 *values = (Uint16 *)propdata;

                        printf("{");
                        for (i = 0; i < items_read; i++) {
                            printf(" %d", values[i]);
                        }
                        printf(" }\n");
                    } else if (real_format == 8) {
                        Uint8 *values = (Uint8 *)propdata;

                        printf("{");
                        for (i = 0; i < items_read; i++) {
                            printf(" %d", values[i]);
                        }
                        printf(" }\n");
                    }
                } else if (real_type == XA_STRING ||
                           real_type == videodata->UTF8_STRING) {
                    printf("{ \"%s\" }\n", propdata);
                } else if (real_type == XA_ATOM) {
                    Atom *atoms = (Atom *)propdata;

                    printf("{");
                    for (i = 0; i < items_read; i++) {
                        char *name = XGetAtomName(display, atoms[i]);
                        if (name) {
                            printf(" %s", name);
                            XFree(name);
                        }
                    }
                    printf(" }\n");
                } else {
                    char *name = XGetAtomName(display, real_type);
                    printf("Unknown type: %ld (%s)\n", real_type, name ? name : "UNKNOWN");
                    if (name) {
                        XFree(name);
                    }
                }
            }
#endif
        }
        break;

    /* Copy the selection from XA_CUT_BUFFER0 to the requested property */
    case SelectionRequest: {
            XSelectionRequestEvent *req;
            XEvent sevent;
            int seln_format;
            unsigned long nbytes;
            unsigned long overflow;
            unsigned char *seln_data;

            req = &xevent.xselectionrequest;
#ifdef DEBUG_XEVENTS
            printf("SelectionRequest (requestor = %ld, target = %ld)\n",
                req->requestor, req->target);
#endif

            SDL_zero(sevent);
            sevent.xany.type = SelectionNotify;
            sevent.xselection.selection = req->selection;
            sevent.xselection.target = None;
            sevent.xselection.property = None;
            sevent.xselection.requestor = req->requestor;
            sevent.xselection.time = req->time;
            if (XGetWindowProperty(display, DefaultRootWindow(display),
                    XA_CUT_BUFFER0, 0, INT_MAX/4, False, req->target,
                    &sevent.xselection.target, &seln_format, &nbytes,
                    &overflow, &seln_data) == Success) {
                if (sevent.xselection.target == req->target) {
                    XChangeProperty(display, req->requestor, req->property,
                        sevent.xselection.target, seln_format, PropModeReplace,
                        seln_data, nbytes);
                    sevent.xselection.property = req->property;
                }
                XFree(seln_data);
            }
            XSendEvent(display, req->requestor, False, 0, &sevent);
            XSync(display, False);
        }
        break;

    case SelectionNotify: {
#ifdef DEBUG_XEVENTS
            printf("SelectionNotify (requestor = %ld, target = %ld)\n",
                xevent.xselection.requestor, xevent.xselection.target);
#endif
            videodata->selection_waiting = SDL_FALSE;
        }
        break;

    default:{
#ifdef DEBUG_XEVENTS
            printf("Unhandled event %d\n", xevent.type);
#endif
        }
        break;
    }
}
bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server)
{
	if (!server)
		server=&_InternalServer;

	XWindowAttributes xwa;
	XGetWindowAttributes (_dpy, _win, &xwa);

	switch (event.type)
	{
	case ButtonPress:
	{
		//nlinfo("%d %d %d", event.xbutton.button, event.xbutton.x, event.xbutton.y);
		float fX = (float) event.xbutton.x / (float) xwa.width;
		float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height;
		TMouseButton button=getMouseButton(event.xbutton.state);
		switch(event.xbutton.button)
		{
		case Button1:
			server->postEvent(new CEventMouseDown(fX, fY, (TMouseButton)(leftButton|(button&~(leftButton|middleButton|rightButton))), this));
			break;
		case Button2:
			server->postEvent(new CEventMouseDown(fX, fY, (TMouseButton)(middleButton|(button&~(leftButton|middleButton|rightButton))), this));
			break;
		case Button3:
			server->postEvent(new CEventMouseDown(fX, fY, (TMouseButton)(rightButton|(button&~(leftButton|middleButton|rightButton))), this));
			break;
		case Button4:
			server->postEvent(new CEventMouseWheel(fX, fY, button, true, this));
			break;
		case Button5:
			server->postEvent(new CEventMouseWheel(fX, fY, button, false, this));
			break;
		}
		break;
	}
	case ButtonRelease:
	{
		//nlinfo("%d %d %d", event.xbutton.button, event.xbutton.x, event.xbutton.y);
		float fX = (float) event.xbutton.x / (float) xwa.width;
		float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height;
		switch(event.xbutton.button)
		{
		case Button1:
			server->postEvent(new CEventMouseUp(fX, fY, leftButton, this));
			break;
		case Button2:
			server->postEvent(new CEventMouseUp(fX, fY, middleButton, this));
			break;
		case Button3:
			server->postEvent(new CEventMouseUp(fX, fY, rightButton, this));
			break;
		}
		break;
	}
	case MotionNotify:
	{
		TMouseButton button=getMouseButton (event.xbutton.state);

		// if raw mode should be emulated
		if(_emulateRawMode)
		{
			// when we just wrapped back the pointer to 0.5 / 0.5, ignore event
			if(event.xbutton.x == xwa.width / 2 && event.xbutton.y == xwa.height / 2)
				break;

			// post a CGDMouseMove with the movement delta to the event server
			server->postEvent(
				new CGDMouseMove(this, NULL /* no mouse device */,
					event.xbutton.x - (xwa.width / 2),
					(xwa.height / 2) - event.xbutton.y));

			// move the pointer back to the center of the window
			XWarpPointer(_dpy, None, _win, None, None, None, None,
				(xwa.width / 2), (xwa.height / 2));
		}
		// if in normal mouse mode
		else
		{
			// get the relative mouse position
			float fX = (float) event.xbutton.x / (float) xwa.width;
			float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height;

			// post a normal mouse move event to the event server
			server->postEvent (new CEventMouseMove (fX, fY, button, this));
		}
		break;
	}
	case KeyPress:
	{
		// save keycode because XFilterEvent could set it to 0
		uint keyCode = event.xkey.keycode;
		KeySym k;
		static char Text[256];
		int c = 0;

		// check if event is filtered
		bool filtered = XFilterEvent(&event, _win);

		// if key event is filtered, we shouldn't use XLookupString to retrieve KeySym
		if (!filtered)
		{
			Status status = XLookupNone;

#ifdef X_HAVE_UTF8_STRING
			if (_ic)
				c = Xutf8LookupString(_ic, &event.xkey, Text, sizeof(Text), &k, &status);
#endif

			if (status == XLookupNone)
				c = XLookupString(&event.xkey, Text, sizeof(Text), &k, NULL);
		}
		else
		{
			k = XKeycodeToKeysym(_dpy, keyCode, 0);
		}

		// send CEventKeyDown event only if keyCode is defined
		if (keyCode)
		{
			TKey key = getKeyFromKeySym(k);
			if(key == KeyNOKEY)
				key = getKeyFromKeycode(keyCode);

			// search for key in map
			std::map<TKey, bool>::const_iterator it = _PressedKeys.find(key);

			// if key is not found or value is false, that's the first time
			bool firstTime = (it == _PressedKeys.end()) || !it->second;

			server->postEvent (new CEventKeyDown (key, getKeyButton(event.xbutton.state), firstTime, this));
			_PressedKeys[key] = true;

			// don't send a control character when deleting
			if (key == KeyDELETE)
				c = 0;
		}

		Text[c] = '\0';
		if(c>0)
		{
#ifdef X_HAVE_UTF8_STRING
			ucstring ucstr;
			ucstr.fromUtf8(Text);

			CEventChar *charEvent = new CEventChar (ucstr[0], getKeyButton(event.xbutton.state), this);

			// raw if not processed by IME
			charEvent->setRaw(keyCode != 0);

			server->postEvent (charEvent);
#else
			for (int i = 0; i < c; i++)
			{
				CEventChar *charEvent = new CEventChar ((ucchar)(unsigned char)Text[i], getKeyButton(event.xbutton.state), this);

				// raw if not processed by IME
				charEvent->setRaw(keyCode != 0);

				server->postEvent (charEvent);
			}
#endif
		}
		break;
	}
	case KeyRelease:
	{
		if (!keyRepeat(_dpy, &event))
		{
			KeySym k;
			// only need to get correct KeySym
			int c = XLookupString(&event.xkey, NULL, 0, &k, NULL);

			TKey key = getKeyFromKeySym(k);
			if(key == KeyNOKEY)
				key = getKeyFromKeycode(event.xkey.keycode);

			server->postEvent (new CEventKeyUp (key, getKeyButton(event.xbutton.state), this));
			_PressedKeys[key] = false;
		}
		break;
	}
	case SelectionRequest:
	{
		XEvent respond;
		XSelectionRequestEvent req = event.xselectionrequest;

		respond.xselection.type= SelectionNotify;
		respond.xselection.display= req.display;
		respond.xselection.requestor= req.requestor;
		respond.xselection.selection=req.selection;
		respond.xselection.target= req.target;
		respond.xselection.time = req.time;
		respond.xselection.property = req.property;

		if (req.property == None)
		{
			respond.xselection.property = req.target;
		}
		if (req.target == XA_TARGETS)
		{
			Atom targets[] =
			{
				XA_TARGETS,
				XA_STRING,
				XA_UTF8_STRING
			};

			respond.xselection.property = req.property;

			XChangeProperty(req.display, req.requestor, req.property, XA_ATOM, 32, PropModeReplace, (unsigned char *)targets, 3 /* number of element */);
		}
		else if (req.target == XA_STRING)
		{
			respond.xselection.property = req.property;
			std::string str = _CopiedString.toString();
			XChangeProperty(req.display, req.requestor, req.property, XA_STRING, 8, PropModeReplace, (const unsigned char*)str.c_str(), str.length());
		}
		else if (req.target == XA_UTF8_STRING)
		{
			respond.xselection.property = req.property;
			std::string str = _CopiedString.toUtf8();
			XChangeProperty(req.display, req.requestor, respond.xselection.property, XA_UTF8_STRING, 8, PropModeReplace, (const unsigned char*)str.c_str(), str.length());
		}
		else
		{
			// Note: Calling XGetAtomName with arbitrary value crash the client, maybe req.target have been sanitized by X11 server
			respond.xselection.property = None;
		}

		XSendEvent (_dpy, req.requestor, 0, 0, &respond);

		break;
	}
	case SelectionClear:
		_SelectionOwned = false;
		_CopiedString = "";
		break;
	case SelectionNotify:
	{
		Atom target = event.xselection.target;

		Atom actualType = 0;
		int actualFormat = 0;
		unsigned long nitems = 0, bytesLeft = 0;

		// some applications are sending ATOM and other TARGETS
		if (target == XA_TARGETS || target == XA_ATOM)
		{
			Atom *supportedTargets = NULL;

			// list NeL selection properties
			if (XGetWindowProperty(_dpy, _win, XA_NEL_SEL, 0, XMaxRequestSize(_dpy), False, AnyPropertyType, &actualType, &actualFormat, &nitems, &bytesLeft, (unsigned char**)&supportedTargets) != Success)
				return false;

			if (bytesLeft > 0)
			{
				nlwarning("Paste: Supported TARGETS list too long.");
			}

			Atom bestTarget = 0;
			sint bestTargetElect = 0;

			// Elect best type
			for (uint i=0; i < nitems; i++)
			{
				// nlwarning(" - Type=%s (%u)", XGetAtomName(_dpy, supportedTargets[i]), (uint)supportedTargets[i]);
				if (supportedTargets[i] == XA_UTF8_STRING )
				{
					if (bestTargetElect < 2)
					{
						bestTarget = XA_UTF8_STRING;
						bestTargetElect = 2;
					}
				}
				else if (supportedTargets[i] == XA_STRING )
				{
					if (bestTargetElect < 1)
					{
						bestTarget = XA_STRING;
						bestTargetElect = 1;
					}
				}
			}

			XFree(supportedTargets);

			if (!bestTargetElect)
			{
				nlwarning("Paste buffer is not a text buffer.");
				return false;
			}

			// request string conversion
			XConvertSelection(_dpy, XA_CLIPBOARD, bestTarget, XA_NEL_SEL, _win, CurrentTime);
		}
		else if (target == XA_UTF8_STRING || target == XA_STRING)
		{
			uint8 *data = NULL;

			// get selection
			if (XGetWindowProperty(_dpy, _win, XA_NEL_SEL, 0, XMaxRequestSize(_dpy), False, AnyPropertyType, &actualType, &actualFormat, &nitems, &bytesLeft, (unsigned char**)&data) != Success)
				return false;

			ucstring text;
			std::string tmpData = (const char*)data;
			XFree(data);

			// convert buffer to ucstring
			if (target == XA_UTF8_STRING)
			{
				text = ucstring::makeFromUtf8(tmpData);
			}
			else if (target == XA_STRING)
			{
				text = tmpData;
			}
			else
			{
				nlwarning("Unknow format %u", (uint)target);
			}

			// sent string event to event server
			server->postEvent (new CEventString (text, this));
		}
		else
		{
			nlwarning("Unknow target %u", (uint)target);
		}

		break;
	}
	case FocusIn:
		// keyboard focus
//		server->postEvent (new CEventSetFocus (true, this));
		if (_ic) XSetICFocus(_ic);
		break;
	case FocusOut:
		// keyboard focus
//		server->postEvent (new CEventSetFocus (false, this));
		if (_ic) XUnsetICFocus(_ic);
		break;
	case KeymapNotify:
		break;
	case MappingNotify:
		// update keymap
		XRefreshKeyboardMapping((XMappingEvent *)&event);
		break;
	case DestroyNotify:
		// XIM server has crashed
		createIM();
		break;
	case ClientMessage:
		if ((event.xclient.format == 32) && ((Atom)event.xclient.data.l[0] == XA_WM_DELETE_WINDOW))
		{
			server->postEvent(new CEventDestroyWindow(this));
		}
		break;
	default:
		//	nlinfo("UnknownEvent");
		//	XtDispatchEvent(&event);
		return false;
	}

	return true;
}
void WindowContextBase::disableIME() {
    if (xim.ic != NULL) {
        XUnsetICFocus(xim.ic);
    }
}
Esempio n. 18
0
////////////////////////////////////////////////////////////
/// Process an incoming event from the window
////////////////////////////////////////////////////////////
void WindowImplX11::ProcessEvent(XEvent WinEvent)
{
    switch (WinEvent.type)
    {
        // Destroy event
        case DestroyNotify :
        {
            // The window is about to be destroyed : we must cleanup resources
            CleanUp();
            break;
        }

        // Gain focus event
        case FocusIn :
        {
            // Update the input context
            if (myInputContext)
                XSetICFocus(myInputContext);

            Event Evt;
            Evt.Type = Event::GainedFocus;
            SendEvent(Evt);
            break;
        }

        // Lost focus event
        case FocusOut :
        {
            // Update the input context
            if (myInputContext)
                XUnsetICFocus(myInputContext);

            Event Evt;
            Evt.Type = Event::LostFocus;
            SendEvent(Evt);
            break;
        }

        // Resize event
        case ConfigureNotify :
        {
            if ((WinEvent.xconfigure.width != static_cast<int>(myWidth)) || (WinEvent.xconfigure.height != static_cast<int>(myHeight)))
            {
                myWidth  = WinEvent.xconfigure.width;
                myHeight = WinEvent.xconfigure.height;

                Event Evt;
                Evt.Type        = Event::Resized;
                Evt.Size.Width  = myWidth;
                Evt.Size.Height = myHeight;
                SendEvent(Evt);
            }
            break;
        }

        // Close event
        case ClientMessage :
        {
            if ((WinEvent.xclient.format == 32) && (WinEvent.xclient.data.l[0]) == static_cast<long>(myAtomClose))  
            {
                Event Evt;
                Evt.Type = Event::Closed;
                SendEvent(Evt);
            }
            break;
        }

        // Key down event
        case KeyPress :
        {
            // Get the keysym of the key that has been pressed
            static XComposeStatus KeyboardStatus;
            char Buffer[32];
            KeySym Sym;
            XLookupString(&WinEvent.xkey, Buffer, sizeof(Buffer), &Sym, &KeyboardStatus);

            // Fill the event parameters
            Event Evt;
            Evt.Type        = Event::KeyPressed;
            Evt.Key.Code    = KeysymToSF(Sym);
            Evt.Key.Alt     = WinEvent.xkey.state & Mod1Mask;
            Evt.Key.Control = WinEvent.xkey.state & ControlMask;
            Evt.Key.Shift   = WinEvent.xkey.state & ShiftMask;
            SendEvent(Evt);

            // Generate a TextEntered event
            if (!XFilterEvent(&WinEvent, None))
            {
                #ifdef X_HAVE_UTF8_STRING
                if (myInputContext)
                {
                    Status ReturnedStatus;
                    Uint8  KeyBuffer[16];
                    int Length = Xutf8LookupString(myInputContext, &WinEvent.xkey, reinterpret_cast<char*>(KeyBuffer), sizeof(KeyBuffer), NULL, &ReturnedStatus);
                    if (Length > 0)
                    {
                        Uint32 Unicode[2]; // just in case, but 1 character should be enough
                        const Uint32* End = Unicode::UTF8ToUTF32(KeyBuffer, KeyBuffer + Length, Unicode);

                        if (End > Unicode)
                        {
                            Event TextEvt;
                            TextEvt.Type         = Event::TextEntered;
                            TextEvt.Text.Unicode = Unicode[0];
                            SendEvent(TextEvt);
                        }
                    }
                }
                else
                #endif
                {
                    static XComposeStatus ComposeStatus;
                    char KeyBuffer[16];
                    if (XLookupString(&WinEvent.xkey, KeyBuffer, sizeof(KeyBuffer), NULL, &ComposeStatus))
                    {
                        Event TextEvt;
                        TextEvt.Type         = Event::TextEntered;
                        TextEvt.Text.Unicode = static_cast<Uint32>(KeyBuffer[0]);
                        SendEvent(TextEvt);
                    }
                }
            }

            break;
        }

        // Key up event
        case KeyRelease :
        {
            // Get the keysym of the key that has been pressed
            char Buffer[32];
            KeySym Sym;
            XLookupString(&WinEvent.xkey, Buffer, 32, &Sym, NULL);

            // Fill the event parameters
            Event Evt;
            Evt.Type        = Event::KeyReleased;
            Evt.Key.Code    = KeysymToSF(Sym);
            Evt.Key.Alt     = WinEvent.xkey.state & Mod1Mask;
            Evt.Key.Control = WinEvent.xkey.state & ControlMask;
            Evt.Key.Shift   = WinEvent.xkey.state & ShiftMask;

            SendEvent(Evt);
            break;
        }

        // Mouse button pressed
        case ButtonPress :
        {
            unsigned int Button = WinEvent.xbutton.button;
            if ((Button == Button1) || (Button == Button2) || (Button == Button3) || (Button == 8) || (Button == 9))
            {
                Event Evt;
                Evt.Type          = Event::MouseButtonPressed;
                Evt.MouseButton.X = WinEvent.xbutton.x;
                Evt.MouseButton.Y = WinEvent.xbutton.y;
                switch (Button)
                {
                    case Button1 : Evt.MouseButton.Button = Mouse::Left;     break;
                    case Button2 : Evt.MouseButton.Button = Mouse::Middle;   break;
                    case Button3 : Evt.MouseButton.Button = Mouse::Right;    break;
                    case 8 :       Evt.MouseButton.Button = Mouse::XButton1; break;
                    case 9 :       Evt.MouseButton.Button = Mouse::XButton2; break;            
                }
                SendEvent(Evt);
            }
            break;
        }

        // Mouse button released
        case ButtonRelease :
        {
            unsigned int Button = WinEvent.xbutton.button;
            if ((Button == Button1) || (Button == Button2) || (Button == Button3) || (Button == 8) || (Button == 9))
            {
                Event Evt;
                Evt.Type          = Event::MouseButtonReleased;
                Evt.MouseButton.X = WinEvent.xbutton.x;
                Evt.MouseButton.Y = WinEvent.xbutton.y;
                switch (Button)
                {
                    case Button1 : Evt.MouseButton.Button = Mouse::Left;     break;
                    case Button2 : Evt.MouseButton.Button = Mouse::Middle;   break;
                    case Button3 : Evt.MouseButton.Button = Mouse::Right;    break;
                    case 8 :       Evt.MouseButton.Button = Mouse::XButton1; break;
                    case 9 :       Evt.MouseButton.Button = Mouse::XButton2; break;            
                }
                SendEvent(Evt);
            }
            else if ((Button == Button4) || (Button == Button5))
            {
                Event Evt;
                Evt.Type             = Event::MouseWheelMoved;
                Evt.MouseWheel.Delta = WinEvent.xbutton.button == Button4 ? 1 : -1;
                SendEvent(Evt);
            }
            break;
        }

        // Mouse moved
        case MotionNotify :
        {
            Event Evt;
            Evt.Type        = Event::MouseMoved;
            Evt.MouseMove.X = WinEvent.xmotion.x;
            Evt.MouseMove.Y = WinEvent.xmotion.y;
            SendEvent(Evt);
            break;
        }

        // Mouse entered
        case EnterNotify :
        {
            Event Evt;
            Evt.Type = Event::MouseEntered;
            SendEvent(Evt);
            break;
        }

        // Mouse left
        case LeaveNotify :
        {
            Event Evt;
            Evt.Type = Event::MouseLeft;
            SendEvent(Evt);
            break;
        }
    }
}
Esempio n. 19
0
static void
X11_DispatchEvent(_THIS)
{
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    SDL_WindowData *data;
    XEvent xevent;
    int i;

    SDL_zero(xevent);           /* valgrind fix. --ryan. */
    XNextEvent(videodata->display, &xevent);

    /* filter events catchs XIM events and sends them to the correct
       handler */
    if (XFilterEvent(&xevent, None) == True) {
#if 0
        printf("Filtered event type = %d display = %d window = %d\n",
               xevent.type, xevent.xany.display, xevent.xany.window);
#endif
        return;
    }

    /* Send a SDL_SYSWMEVENT if the application wants them */
    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
        SDL_SysWMmsg wmmsg;

        SDL_VERSION(&wmmsg.version);
        wmmsg.subsystem = SDL_SYSWM_X11;
        wmmsg.event.xevent = xevent;
        SDL_SendSysWMEvent(&wmmsg);
    }

    data = NULL;
    if (videodata && videodata->windowlist) {
        for (i = 0; i < videodata->numwindows; ++i) {
            if ((videodata->windowlist[i] != NULL) &&
                (videodata->windowlist[i]->window == xevent.xany.window)) {
                data = videodata->windowlist[i];
                break;
            }
        }
    }
    if (!data) {
        return;
    }
#if 0
    printf("type = %d display = %d window = %d\n",
           xevent.type, xevent.xany.display, xevent.xany.window);
#endif
    switch (xevent.type) {

        /* Gaining mouse coverage? */
    case EnterNotify:{
#ifdef DEBUG_XEVENTS
            printf("EnterNotify! (%d,%d,%d)\n", 
	           xevent.xcrossing.x,
 	           xevent.xcrossing.y,
                   xevent.xcrossing.mode);
            if (xevent.xcrossing.mode == NotifyGrab)
                printf("Mode: NotifyGrab\n");
            if (xevent.xcrossing.mode == NotifyUngrab)
                printf("Mode: NotifyUngrab\n");
#endif
#if 1
            /* FIXME: Should we reset data for all mice? */
            for (i = 0; i < SDL_GetNumMice(); ++i) {
                SDL_Mouse *mouse = SDL_GetMouse(i);
                SDL_SetMouseFocus(mouse->id, data->windowID);
            }
#endif
        }
        break;

        /* Losing mouse coverage? */
    case LeaveNotify:{
#ifdef DEBUG_XEVENTS
            printf("LeaveNotify! (%d,%d,%d)\n", 
	           xevent.xcrossing.x,
 	           xevent.xcrossing.y,
                   xevent.xcrossing.mode);
            if (xevent.xcrossing.mode == NotifyGrab)
                printf("Mode: NotifyGrab\n");
            if (xevent.xcrossing.mode == NotifyUngrab)
                printf("Mode: NotifyUngrab\n");
#endif
            if (xevent.xcrossing.detail != NotifyInferior) {
#if 1
                /* FIXME: Should we reset data for all mice? */
	        for (i = 0; i < SDL_GetNumMice(); ++i) {
		    SDL_Mouse *mouse = SDL_GetMouse(i);
		    SDL_SetMouseFocus(mouse->id, 0);
	        }
#endif
            }
        }
        break;

        /* Gaining input focus? */
    case FocusIn:{
#ifdef DEBUG_XEVENTS
            printf("FocusIn!\n");
#endif
            SDL_SetKeyboardFocus(videodata->keyboard, data->windowID);
#ifdef X_HAVE_UTF8_STRING
            if (data->ic) {
                XSetICFocus(data->ic);
            }
#endif
        }
        break;

        /* Losing input focus? */
    case FocusOut:{
#ifdef DEBUG_XEVENTS
            printf("FocusOut!\n");
#endif
            SDL_SetKeyboardFocus(videodata->keyboard, 0);
#ifdef X_HAVE_UTF8_STRING
            if (data->ic) {
                XUnsetICFocus(data->ic);
            }
#endif
        }
        break;

        /* Generated upon EnterWindow and FocusIn */
    case KeymapNotify:{
#ifdef DEBUG_XEVENTS
            printf("KeymapNotify!\n");
#endif
            /* FIXME:
               X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector);
             */
        }
        break;

        /* Has the keyboard layout changed? */
    case MappingNotify:{
#ifdef DEBUG_XEVENTS
            printf("MappingNotify!\n");
#endif
            X11_UpdateKeymap(_this);
        }
        break;

        /* Key press? */
    case KeyPress:{
            KeyCode keycode = xevent.xkey.keycode;
            KeySym keysym = NoSymbol;
            char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
            Status status = 0;

#ifdef DEBUG_XEVENTS
            printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
#endif
            SDL_SendKeyboardKey(videodata->keyboard, SDL_PRESSED,
                                videodata->key_layout[keycode]);
#if 0
            if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
                int min_keycode, max_keycode;
                XDisplayKeycodes(videodata->display, &min_keycode,
                                 &max_keycode);
                keysym = XKeycodeToKeysym(videodata->display, keycode, 0);
                fprintf(stderr,
                        "The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list <*****@*****.**> X11 KeyCode %d (%d), X11 KeySym 0x%X (%s).\n",
                        keycode, keycode - min_keycode, keysym,
                        XKeysymToString(keysym));
            }
#endif
            /* */
            SDL_zero(text);
#ifdef X_HAVE_UTF8_STRING
            if (data->ic) {
                Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text),
                                  &keysym, &status);
            }
#else
            XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
#endif
            if (*text) {
                SDL_SendKeyboardText(videodata->keyboard, text);
            }
        }
        break;

        /* Key release? */
    case KeyRelease:{
            KeyCode keycode = xevent.xkey.keycode;

#ifdef DEBUG_XEVENTS
            printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
#endif
            SDL_SendKeyboardKey(videodata->keyboard, SDL_RELEASED,
                                videodata->key_layout[keycode]);
        }
        break;

        /* Have we been iconified? */
    case UnmapNotify:{
#ifdef DEBUG_XEVENTS
            printf("UnmapNotify!\n");
#endif
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_HIDDEN, 0, 0);
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MINIMIZED, 0,
                                0);
        }
        break;

        /* Have we been restored? */
    case MapNotify:{
#ifdef DEBUG_XEVENTS
            printf("MapNotify!\n");
#endif
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, 0, 0);
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESTORED, 0,
                                0);
        }
        break;

        /* Have we been resized or moved? */
    case ConfigureNotify:{
#ifdef DEBUG_XEVENTS
            printf("ConfigureNotify! (resize: %dx%d)\n",
                   xevent.xconfigure.width, xevent.xconfigure.height);
#endif
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MOVED,
                                xevent.xconfigure.x, xevent.xconfigure.y);
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESIZED,
                                xevent.xconfigure.width,
                                xevent.xconfigure.height);
        }
        break;

        /* Have we been requested to quit (or another client message?) */
    case ClientMessage:{
            if ((xevent.xclient.format == 32) &&
                (xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) {

                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0,
                                    0);
            }
        }
        break;

        /* Do we need to refresh ourselves? */
    case Expose:{
#ifdef DEBUG_XEVENTS
            printf("Expose (count = %d)\n", xevent.xexpose.count);
#endif
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED, 0,
                                0);
        }
        break;

    default:{
            for (i = 0; i < SDL_GetNumMice(); ++i) {
                SDL_Mouse *mouse;
#if SDL_VIDEO_DRIVER_X11_XINPUT
                X11_MouseData *data;
#endif

                mouse = SDL_GetMouse(i);
                if (!mouse->driverdata) {
                    switch (xevent.type) {
                    case MotionNotify:
#ifdef DEBUG_MOTION
                        printf("X11 motion: %d,%d\n", xevent.xmotion.x,
                               xevent.xmotion.y);
#endif
                        SDL_SendMouseMotion(mouse->id, 0, xevent.xmotion.x,
                                            xevent.xmotion.y, 0);
                        break;

                    case ButtonPress:
                        SDL_SendMouseButton(mouse->id, SDL_PRESSED,
                                            xevent.xbutton.button);
                        break;

                    case ButtonRelease:
                        SDL_SendMouseButton(mouse->id, SDL_RELEASED,
                                            xevent.xbutton.button);
                        break;
                    }
                    continue;
                }
#if SDL_VIDEO_DRIVER_X11_XINPUT
                data = (X11_MouseData *) mouse->driverdata;
                if (xevent.type == data->motion) {
                    XDeviceMotionEvent *move =
                        (XDeviceMotionEvent *) & xevent;
#ifdef DEBUG_MOTION
                    printf("X11 motion: %d,%d\n", move->x, move->y);
#endif
                    SDL_SendMouseMotion(move->deviceid, 0, move->x, move->y,
                                        move->axis_data[2]);
                    return;
                }
                if (xevent.type == data->button_pressed) {
                    XDeviceButtonPressedEvent *pressed =
                        (XDeviceButtonPressedEvent *) & xevent;
                    SDL_SendMouseButton(pressed->deviceid, SDL_PRESSED,
                                        pressed->button);
                    return;
                }
                if (xevent.type == data->button_released) {
                    XDeviceButtonReleasedEvent *released =
                        (XDeviceButtonReleasedEvent *) & xevent;
                    SDL_SendMouseButton(released->deviceid, SDL_RELEASED,
                                        released->button);
                    return;
                }
                if (xevent.type == data->proximity_in) {
                    XProximityNotifyEvent *proximity =
                        (XProximityNotifyEvent *) & xevent;
                    SDL_SendProximity(proximity->deviceid, proximity->x,
                                      proximity->y, SDL_PROXIMITYIN);
                    return;
                }
                if (xevent.type == data->proximity_out) {
                    XProximityNotifyEvent *proximity =
                        (XProximityNotifyEvent *) & xevent;
                    SDL_SendProximity(proximity->deviceid, proximity->x,
                                      proximity->y, SDL_PROXIMITYOUT);
                    return;
                }
#endif
            }
#ifdef DEBUG_XEVENTS
            printf("Unhandled event %d\n", xevent.type);
#endif
        }
        break;
    }
}
Esempio n. 20
0
void Ctrl::EventProc(XWindow& w, XEvent *event)
{
	GuiLock __; 
	eventid++;
	Ptr<Ctrl> _this = this;
	bool pressed = false;
	int  count = 1;
	switch(event->type) {
	case NoExpose:
		LLOG("NoExpose serial " << event->xnoexpose.serial);
		break;
	case GraphicsExpose:
		LLOG("GraphicsExpose serial " << event->xgraphicsexpose.serial);
	case Expose: {
			XExposeEvent& e = event->xexpose;
			w.exposed = true;
			LLOG("Expose " << RectC(e.x, e.y, e.width, e.height));
			Invalidate(w, RectC(e.x, e.y, e.width, e.height));
		}
		return;
	case ConfigureNotify: {
			XConfigureEvent& e = event->xconfigure;
			int x, y;
			Window dummy;
// 01/12/2007 - mdelfede
// added support for windowed controls
//			if(top)
//				XTranslateCoordinates(Xdisplay, top->window, Xroot, 0, 0, &x, &y, &dummy);
			if(top) {
				Window DestW = (parent ? GetParentWindow() : Xroot);
				XTranslateCoordinates(Xdisplay, top->window, DestW, 0, 0, &x, &y, &dummy);
				Rect rect = RectC(x, y, e.width, e.height);
				LLOG("CongigureNotify " << rect);
				if(GetRect() != rect)
					SetWndRect(rect);
				// Synchronizes native windows (NOT the main one)
			}
			SyncNativeWindows();
// 01/12/2007 - END

		}
		return;
	default:
		if(!IsEnabled()) return;
	}
	LTIMING("XUserInput");
	switch(event->type) {
	case FocusIn:
		if(w.xic)
			XSetICFocus(w.xic);
		break;
	case FocusOut:
		if(w.xic)
			XUnsetICFocus(w.xic);
		break;
	case KeyPress:
		pressed = true;
		LLOG("event type:" << event->type << " state:" << event->xkey.state <<
		     "keycode:" << event->xkey.keycode);
		for(;;) {
			XEvent ev1[1], ev2[1];
			bool hasev2 = false;
			if(!IsWaitingEvent()) break;
			do
				XNextEvent(Xdisplay, ev1);
			while(ev1->type == NoExpose && IsWaitingEvent());
			LLOG("ev1 type:" << ev1->type << " state:" << ev1->xkey.state <<
			     "keycode:" << ev1->xkey.keycode);
			if(ev1->type == KeyPress)
				*ev2 = *ev1;
			else {
				if(ev1->type != KeyRelease ||
				   ev1->xkey.state != event->xkey.state ||
				   ev1->xkey.keycode != event->xkey.keycode ||
				   !IsWaitingEvent()) {
				   	XPutBackEvent(Xdisplay, ev1);
				   	break;
				}
				do
					XNextEvent(Xdisplay, ev2);
				while(ev2->type == NoExpose && IsWaitingEvent());
				LLOG("ev2 type:" << ev2->type << " state:" << ev2->xkey.state <<
				     "keycode:" << ev2->xkey.keycode);
				hasev2 = true;
			}
			if(ev2->type != KeyPress ||
			   ev2->xkey.state != event->xkey.state ||
			   ev2->xkey.keycode != event->xkey.keycode) {
				if(hasev2)
					XPutBackEvent(Xdisplay, ev2);
				XPutBackEvent(Xdisplay, ev1);
				break;
			}
			else {
				XFilterEvent(ev1, None);
				if(hasev2)
					XFilterEvent(ev2, None);
			}
			count++;
		}
	case KeyRelease: {
			mousePos = Point(event->xkey.x_root, event->xkey.y_root);
			char buff[128];
			Xeventtime = event->xkey.time;
			LLOG("Key Xeventtime: " << Xeventtime << " count:" << count);
			KeySym keysym;
			int    chr = 0;
			WString wtext;
			if(pressed && w.xic) {
				Status status;
				int len = Xutf8LookupString(w.xic, &event->xkey, buff, sizeof(buff), &keysym, &status);
				buff[len] = 0;
				if(status == XLookupChars || status == XLookupBoth) {
					chr = FromUtf8(buff, len)[0];
					if(status == XLookupChars)
						wtext = FromUtf8(buff, len);
				}
				else
				if(status != XLookupKeySym && status != XLookupBoth)
				    keysym = 0;
			}
			else {
				int len = XLookupString(&event->xkey, buff, sizeof(buff), &keysym, NULL);
				buff[len] = 0;
				chr = FromUtf8(buff, len)[0];
				if(len > 1)
					wtext = FromUtf8(buff, len);
			}
			if(keysym == XK_Control_L || keysym == XK_Control_R) {
				keysym = XK_Control_L;
				if(pressed)
					sKbdState |= ControlMask;
				else
					sKbdState &= ~ControlMask;
			}
			if(keysym == XK_Shift_L || keysym == XK_Shift_R) {
				keysym = XK_Shift_L;
				if(pressed)
					sKbdState |= ShiftMask;
				else
					sKbdState &= ~ShiftMask;
			}
			if(keysym == XK_Meta_L || keysym == XK_Meta_R || keysym == XK_Alt_L ||
			   keysym == XK_Alt_R || keysym == XK_Super_L || keysym == XK_Super_R ||
			   keysym == XK_Hyper_L || keysym == XK_Hyper_R || keysym == XK_ISO_Prev_Group) {
				keysym = XK_Meta_L;
				if(pressed)
					sKbdState |= Mod1Mask;
				else
					sKbdState &= ~Mod1Mask;
			}
			LLOG("KeySym:" << FormatIntHex(keysym) << " " << (char)keysym << " " << count);
			dword up = pressed ? 0 : K_KEYUP;
			static struct { KeySym keysym; dword key; } tab[] = {
				{ XK_ISO_Left_Tab, K_TAB|K_SHIFT },
				{ XK_BackSpace, K_BACKSPACE },
				{ XK_Tab, K_TAB },
				{ XK_Return, K_ENTER },
				{ XK_KP_Enter, K_ENTER },
				{ XK_Escape, K_ESCAPE },
				{ XK_space, K_SPACE },

				{ XK_KP_Space, K_SPACE },
				{ XK_KP_Tab, K_TAB },
				{ XK_KP_Enter, K_ENTER },
				{ XK_KP_F1, K_F1 },
				{ XK_KP_F2, K_F2 },
				{ XK_KP_F3, K_F3 },
				{ XK_KP_F4, K_F4 },
				{ XK_KP_Home, K_HOME },
				{ XK_KP_Left, K_LEFT },
				{ XK_KP_Up, K_UP },
				{ XK_KP_Right, K_RIGHT },
				{ XK_KP_Down, K_DOWN },
				{ XK_KP_Page_Up, K_PAGEUP },
				{ XK_KP_Page_Down, K_PAGEDOWN },
				{ XK_KP_End, K_END },
				{ XK_KP_Begin, K_HOME },
				{ XK_KP_Insert, K_INSERT },
				{ XK_KP_Delete, K_DELETE },
			};
			for(int i = 0; i < __countof(tab); i++)
				if(tab[i].keysym == keysym) {
					DispatchKey(KEYtoK(tab[i].key)|up, count);
					return;
				}
			if(GetShift() && chr == 0) {
				static dword k[] = { 41, 33, 64, 35, 36, 37, 94, 38, 42, 40 };
				for(int i = 0; i < 10; i++)
					if(keysym == k[i]) {
						DispatchKey(KEYtoK(i + K_0)|up, count);
						return;
					}
			}
			if(keysym >= 48 && keysym <= 57 && chr == 0) {
				DispatchKey(KEYtoK(keysym - 48 + K_0)|up, count);
				return;
			}
			if(chr >= 1 && chr < 32) {
				DispatchKey(KEYtoK(chr - 1 + K_CTRL_A)|up, count);
				return;
			}
			if(keysym >= 0xff80 && keysym <= 0xffb9 && chr) {
				DispatchKey(KEYtoK(chr)|up, count);
				return;
			}
			if(keysym >= 0xff00 && chr < 128 ||
			   (GetCtrl() || GetAlt()) && keysym >= 0x20 && keysym < 0x7f) {
				if(keysym >= 'a' && keysym <= 'z')
					keysym = keysym - 'a' + 'A';
				DispatchKey(KEYtoK(keysym|K_DELTA)|up, count);
				return;
			}

			if((chr == 32 || chr == 9 || chr == 13) && !pressed)
				DispatchKey(chr|K_KEYUP, count);
			if(chr && pressed) {
				DispatchKey(chr, count);
				for(int ii = 1; ii < wtext.GetLength(); ii++)
					DispatchKey(wtext[ii], count);
			}
		}
		break;
	case ButtonPress: {
			if(!HasWndFocus() && !popup)
				SetWndFocus();
			ClickActivateWnd();
			mousePos = Point(event->xbutton.x_root, event->xbutton.y_root);
			ReleaseGrab();
			XButtonEvent& e = event->xbutton;
			sModState = e.state;
			Xeventtime = e.time;
			if(ignoreclick) break;
			Point p = Point(e.x, e.y);
			dword action = DOWN;
			if((dword)e.time - (dword)Xbuttontime < 800) {
				action = DOUBLE;
				Xbuttontime = Xeventtime - 0x80000000;
			}
			else {
				Xbuttontime = e.time;
				Xbuttonpos = mousePos;
			}
			switch(e.button) {
			case Button1:
				sModState |= Button1Mask;
				DispatchMouse(LEFT|action, p, 0);
				break;
			case Button2:
				sModState |= Button2Mask;
				if(Xbuttons < 3)
					DispatchMouse(RIGHT|action, p, 0);
				else
					DispatchMouse(MIDDLE|action, p, 0);
				break;
			case Button3:
				sModState |= Button3Mask;
				DispatchMouse(RIGHT|action, p, 0);
				break;
			}
			if(_this) PostInput();
		}
		break;
	case ButtonRelease: {
			mousePos = Point(event->xbutton.x_root, event->xbutton.y_root);
			XButtonEvent& e = event->xbutton;
			sModState = e.state;
			Xeventtime = e.time;
			Point p = Point(e.x, e.y);
			switch(e.button) {
			case Button1:
				sModState &= ~Button1Mask;
				break;
			case Button2:
				sModState &= ~Button2Mask;
				break;
			case Button3:
				sModState &= ~Button3Mask;
				break;
			}
			if(ignoreclick)
				EndIgnore();
			else
				switch(e.button) {
				case Button1:
					DispatchMouse(LEFTUP, p, 0);
					break;
				case Button2:
					if(Xbuttons < 3)
						DispatchMouse(RIGHTUP, p, 0);
					else
						DispatchMouse(MIDDLEUP, p, 0);
					break;
				case Button3:
					DispatchMouse(RIGHTUP, p, 0);
					break;
				case Button4:
					DispatchMouse(MOUSEWHEEL, p, 120);
					break;
				case Button5:
					DispatchMouse(MOUSEWHEEL, p, -120);
					break;
				}
			if(_this) PostInput();
		}
		break;
	case MotionNotify:
		while(XCheckWindowEvent(Xdisplay, top->window, PointerMotionMask, event));
		EndIgnore();
		mousePos = Point(event->xmotion.x_root, event->xmotion.y_root);
		Xeventtime = event->xmotion.time;
		Point p = mousePos - Xbuttonpos;
		if(max(abs(p.x), abs(p.y)) > 4)
			Xbuttontime = Xeventtime - 0x80000000;
		sModState = event->xmotion.state;
		DispatchMouse(MOUSEMOVE, Point(event->xmotion.x, event->xmotion.y));
		DoCursorShape();
		break;
	}
	DropEvent(w, event);
}
Esempio n. 21
0
int main(int argc, char**argv) {
    char **missing_charset_list;
    int missing_charset_count;
    XGCValues xgcv;
    unsigned long mask;
    Display* dpy;
    int scr;
    Window w, root;
    XSetWindowAttributes set_attr;
    int i;
    XIMStyle *style;
    static char buf[128];
    KeySym keysym = 0;
    Status status;
    XWMHints wm_hints;
    XClassHint class_hints;
    XIMStyle input_style = 0;
    char **font_name_list;
    char *def_string;
    XFontStruct **font_struct_list;
    char **font_encoding_list;
    int nb_font;
    int len = 0;
    int no_xim = 0;
    char **missing_charset_list_return;
    int missing_charset_count_return;
    char *def_string_return;

    if (!setlocale(LC_ALL, ""))
        puts("locale not supported by C library, locale unchanged");

    if (!XSetLocaleModifiers(""))
        puts("X locale modifiers not supported, using default");

    dpy = XOpenDisplay(0);
    scr = DefaultScreen(dpy);
    root = RootWindow(dpy, scr);
    set_attr.event_mask = KeyPressMask|FocusChangeMask;
    set_attr.background_pixel = WhitePixel(dpy, DefaultScreen(dpy));
    set_attr.border_pixel = BlackPixel(dpy, DefaultScreen(dpy));
    w = XCreateWindow(dpy, root, 10,10,200,100,0,
                      DefaultDepth(dpy, DefaultScreen(dpy)),
                      InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)),
                      CWEventMask | CWBackPixel | CWBorderPixel, &set_attr);

    class_hints.res_name = "test";
    class_hints.res_class = "Test";
    wm_hints.input = True;
    wm_hints.flags = InputHint;

    XmbSetWMProperties(dpy, w, "test", "test", NULL, 0,
                       NULL, &wm_hints, &class_hints);

    XMapWindow(dpy, w);
    xim_im = XOpenIM(dpy, NULL, "test", "Test");
    XGetIMValues(xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL);
    for (i = 0, style = xim_styles->supported_styles;
            i < xim_styles->count_styles; i++, style++) {
        if (*style == (XIMStatusNone|XIMPreeditNone)) {
            printf("this is not a XIM server !!!\n");
            no_xim = 1;
        }
        printf("input style : 0x%X\n", *style);
    }
    XFree(xim_styles);

    xim_ic = XCreateIC(xim_im,
                       XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
                       XNClientWindow, w,
                       XNFocusWindow, w,
                       NULL);
    XSetICFocus(xim_ic);

    /***************************************************************
     *  I don't recommend to use a font base name list similar
     *  to the following one in a real application ;-)
     ***************************************************************/
    fontset = XCreateFontSet(dpy,
                             "-*-*-*-*-*-*-*-*-*-*-*-*-iso8858-3," /* not valid */
                             "-*-*-medium-r-*-*-*-*-*-*-*-*-iso8859-1,"
                             "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-6,"
                             "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-8,"
                             "-*-symbol-*-*-*-*-*-*-*-*-*-*-adobe-fontspecific,"
                             "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-2,"
                             "-*-*-*-*-*-*-*-*-*-*-*-*-koi8-1,"
                             "-*-*-*-*-*-*-*-*-*-*-*-*-jisx0208.1983-0,"
                             "-*-*-*-*-*-*-*-*-*-*-*-*-jisx0212.1990-0,"
                             "-*-*-*-*-*-*-*-*-*-*-*-*-big5-0,"
                             "-*-*-*-*-*-*-*-*-*-*-*-*-jisx0201.1976-0,"
                             "-*-unifont-*-*-*-*-*-*-*-*-*-*-iso10646-1[0x300 0x400_0x500],"
                             "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
                             &missing_charset_list_return,
                             &missing_charset_count_return,
                             &def_string_return);
    mask = (GCForeground | GCBackground);
    xgcv.foreground = BlackPixel(dpy, DefaultScreen(dpy));
    xgcv.background = WhitePixel(dpy, DefaultScreen(dpy));

    gc = XCreateGC(dpy, w, mask, &xgcv);

    /***************************************************************/
    while (1) {
        int filtered;
        static XEvent xevent;
        static XVaNestedList list1 = 0;
        int r;

        XNextEvent(dpy, &xevent);
        if (xevent.type == KeyPress) {
            XKeyEvent *e = (XKeyEvent*) &xevent;
            printf ("0x%X %d\n", e->state, e->keycode);
        }
        filtered = XFilterEvent(&xevent, w);
        if (xevent.type == FocusOut) XUnsetICFocus(xim_ic);
        if (xevent.type == FocusIn) XSetICFocus(xim_ic);

        if (xevent.type == KeyPress && !filtered) {
            len = Xutf8LookupString(xim_ic, &xevent.xkey, buf, 127, &keysym, &status);
            Xutf8DrawImageString(dpy, w, fontset, gc, x, y, buf, len);
            Xutf8DrawString(dpy, w, fontset, gc, 0, 20, jp_txt, strlen(jp_txt));
            Xutf8DrawString(dpy, w, fontset, gc, 50, 90, rtl_txt, strlen(rtl_txt));
            buf[len] = 0;
            printf("'%s' %d\n", buf, keysym);
            buf[0] = 0;
            XCloseIM(xim_im);
        }
        if (filtered) {
            printf("Dead key\n");
        }
    }
    XFreeFontSet(dpy, fontset);
    return 0;
}
Esempio n. 22
0
int main(int argc, char**argv)
{
	char **missing_charset_list;
	int missing_charset_count;
	XGCValues xgcv;
	unsigned long mask;
	Display* dpy;
	int scr;
	Window w, root;
	XSetWindowAttributes set_attr;
	int i;
	XIMStyle *style;
        static char buf[128];
        KeySym keysym = 0;
        Status status;
	XWMHints wm_hints;
    	XClassHint class_hints;
	XIMStyle input_style = 0;
	char **font_name_list;
	char *def_string;
	XFontStruct **font_struct_list;
	char **font_encoding_list;
	int nb_font;
	int len = 0;
	int no_xim = 0;

	printf ("A -> %c \n", XUtf8Tolower('A'));
    	if (!setlocale(LC_ALL, ""))
        	puts("locale not supported by C library, locale unchanged");

    	if (!XSetLocaleModifiers(""))
        	puts("X locale modifiers not supported, using default");
	
	dpy = XOpenDisplay(0);
	if (!dpy) { puts("cannot open display.\n"); exit(-1); }
	scr = DefaultScreen(dpy);
	root = RootWindow(dpy, scr);
	set_attr.event_mask = KeyPressMask|FocusChangeMask;
	set_attr.background_pixel = WhitePixel(dpy, DefaultScreen(dpy));
	set_attr.border_pixel = BlackPixel(dpy, DefaultScreen(dpy));
	w = XCreateWindow(dpy, root, 10,10,200,100,0, 
		DefaultDepth(dpy, DefaultScreen(dpy)),
		InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)),
		CWEventMask | CWBackPixel | CWBorderPixel, &set_attr);
	if (!w) { puts("cannot creat window.\n"); exit(-1); }

	class_hints.res_name = "test";
    	class_hints.res_class = "Test";
	wm_hints.input = True;
    	wm_hints.flags = InputHint;

    	XmbSetWMProperties(dpy, w, "test", "test", NULL, 0,
                       NULL, &wm_hints, &class_hints);

	XMapWindow(dpy, w);
	xim_im = XOpenIM(dpy, NULL, "test", "Test");
	if (!xim_im) { 
		puts("cannot Open Input Manager: Try default.\n"); 
		XSetLocaleModifiers("@im=");
		xim_im = XOpenIM(dpy, NULL, "test", "Test");
		if (!xim_im) { puts("Failed exiting.\n"); exit(-1); }
	}
	XGetIMValues (xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL);
    	for (i = 0, style = xim_styles->supported_styles;
         	i < xim_styles->count_styles; i++, style++)
	{
		if (i == 0 && *style == (XIMStatusNone|XIMPreeditNone)) {
			printf("this is not a XIM server !!!\n");
			no_xim = 1;
		}
        	printf("input style : 0x%X\n", *style);
	}

	xim_ic = XCreateIC(xim_im,
                        XNInputStyle, 
			(XIMPreeditNothing | XIMStatusNothing),
                        XNClientWindow, w,
			XNFocusWindow, w,
                        NULL);
	if (!xim_ic) { puts("cannot create Input Context.\n"); exit(-1);}
    	XFree(xim_styles);
	XSetICFocus(xim_ic);

	/***************************************************************/
	/** I don't recommand to use a font base name list similar 
	 *  to the following one in a real application ;-) 
	 *  You should use an iso8859-1 font, plus a single font for 
	 *  your language. */
	/***************************************************************/
        fontset = XCreateUtf8FontStruct(dpy, 
		"-*-*-*-*-*-*-*-*-*-*-*-*-iso8858-3," /* not valid */
		"-*-*-medium-r-*-*-*-*-*-*-*-*-iso8859-1,"
		"-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-6,"
		"-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-8,"
		"-*-*-*-*-*-*-*-*-*-*-*-*-ksc5601.1987-0,"
		"-*-symbol-*-*-*-*-*-*-*-*-*-*-adobe-fontspecific," 
		"-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-2,"
		"-*-*-*-*-*-*-*-*-*-*-*-*-koi8-1,"
		"-*-*-*-*-*-*-*-*-*-*-*-*-jisx0208.1983-0,"
		"-*-*-*-*-*-*-*-*-*-*-*-*-jisx0212.1990-0,"
		"-*-*-*-*-*-*-*-*-*-*-*-*-big5-0,"
		"-*-*-*-*-*-*-*-*-*-*-*-*-jisx0201.1976-0,"
		"-*-unifont-*-*-*-*-*-*-*-*-*-*-iso10646-1[0x300 0x400_0x500],"
		"-*-*-*-*-*-*-*-*-*-*-*-*-*-*"); 

	/* THIS PART IS NOT REQUIERED */
	nb_font = fontset->nb_font;

        while (nb_font > 0) {
                nb_font--;
		if (fontset->fonts[nb_font]) {
               		printf("encoding=\"\" fid=%d \n  %s\n", 
			//	fontset->encodings[nb_font],
                        	fontset->fonts[nb_font]->fid,
				fontset->font_name_list[nb_font]);
		}
        }
	/* END OF NOT REQUIERED PART*/

	mask = (GCForeground | GCBackground);
	xgcv.foreground = BlackPixel(dpy, DefaultScreen(dpy));
    	xgcv.background = WhitePixel(dpy, DefaultScreen(dpy));

        gc = XCreateGC(dpy, w, mask, &xgcv);
	if (!gc) { puts("cannot create Graphic Context.\n"); exit(-1);}


	/***************************************************************/
	while (1) {
		int filtered;
	 	static XEvent xevent;
		static XVaNestedList list1 = 0;
		int r;

               	XNextEvent(dpy, &xevent);
		if (xevent.type == KeyPress) {
			XKeyEvent *e = (XKeyEvent*) &xevent;
			printf ("0x%X %d\n", e->state, e->keycode);
		}
		if (xevent.type == DestroyNotify) {
			/* XIM server has crashed */
			no_xim = 1;
			XSetLocaleModifiers("@im=");
			xim_im = XOpenIM(dpy, NULL, "test", "Test");
			if (xim_im) {
			   xim_ic = XCreateIC(xim_im,
                        	XNInputStyle, (XIMPreeditNothing | 
					XIMStatusNothing),
                        	XNClientWindow, w,
				XNFocusWindow, w,
                        	NULL);
   			} else {
				xim_ic = NULL;
			}
			if (!xim_ic) {
			 	puts("Crash recovery failed. exiting.\n");
				exit(-1);
			}
		}
		if (xevent.type != DestroyNotify) {
			filtered = XFilterEvent(&xevent, 0);
		}
		if (xevent.type == FocusOut && xim_ic) XUnsetICFocus(xim_ic);
		if (xevent.type == FocusIn && xim_ic) XSetICFocus(xim_ic);

		if (xevent.type == KeyPress && !filtered) {
 			len = XUtf8LookupString(xim_ic, &xevent.xkey, 
					buf, 127, &keysym, &status);

			if (len == 1 && buf[0] == '\b') {
				x -= XUtf8TextWidth(fontset, buf, len);
				XUtf8DrawImageString(dpy, w, fontset, gc, 
					x, y, buf, len);
			} else if (len == 1 && buf[0] == '\r') {
				y += fontset->ascent + fontset->descent;
				x = 0;
				XCloseIM(xim_im);
			} else {
				XUtf8DrawImageString(dpy, w, fontset, gc, 
					x, y, buf, len);
				x += XUtf8TextWidth(fontset, buf, len);
			}


			XUtf8DrawString(dpy, w, fontset, gc, 0, 20, 
				jp_txt, strlen(jp_txt));
	
			XUtf8DrawString(dpy, w, fontset, gc, 50, 90,
				rtl_txt, strlen(rtl_txt));
			XUtf8DrawRtlString(dpy, w, fontset, gc, 
				50, 90, rtl_txt, strlen(rtl_txt));
			buf[len] = 0;
			printf("'%s' %d %x\n", buf, keysym, keysym);
			buf[0] = 0;

                }
		if (filtered) {
			printf("Dead key\n");
		}
	}
	XFreeUtf8FontStruct(dpy, fontset);
	return 0;
}
Esempio n. 23
0
	int main(int argc, char **argv)
	{
		Display *display;
		int screen_num;
		Window win;			//窗口ID
		unsigned int width, height;	//窗口尺寸
		unsigned int border_width = 4;	//边界空白
		unsigned int display_width, display_height;//屏幕尺寸
		XEvent report;
		GC gc;
		unsigned long valuemask = 0;
		XGCValues values;
		char *display_name = NULL;
		Atom          protocols;

		//edit
		int           len = 127;
		unsigned char string[128], s_tab[ROW][127];
		KeySym        keysym;
		int           row = 0, col = 0;
		int           i, count = 0;
		Status        status;
		//字体集
		XFontSet fontset;
		char **missing_charsets;
		int num_missing_charsets;
		char *default_string;
		XFontSetExtents *fs_ext;
		int dec;    

		//XIM
		XIM im;
		XIC ic;
		//overspot
		XRectangle    spot, s_rect;
		XVaNestedList preedit_attr, status_attr;

		//设置locale	
		if((setlocale(LC_ALL, "")) == NULL){
			printf("cannot set locale\n");
			exit(1);
		}

		//判断X是否支持locale
		if(!XSupportsLocale()){
			printf("X does not support current locale\n");
			exit(1);
		}

		//设置locale修饰
		if(XSetLocaleModifiers(NULL)){
			printf("Cannot set locale modifiers\n");
			exit(1);
		}
	
		// 和X 服务器连接
		if ( (display=XOpenDisplay(display_name)) == NULL )
		{
			printf("Cannot connect to X server %s\n", 
					XDisplayName(display_name));
			exit(-1);
		}

		//获得缺省的 screen_num
		screen_num = DefaultScreen(display);

		//获得屏幕的宽度和高度
		display_width = DisplayWidth(display, screen_num);
		display_height = DisplayHeight(display, screen_num);
	
		//建立字体集
		fontset = XCreateFontSet(display, 
			"8x16,-*-song-medium-r-normal--16-*-*-*-*-*-gb2312.1980-0",
			&missing_charsets, &num_missing_charsets,
			&default_string);

		if(num_missing_charsets > 0){
			int i;
			printf("Following charsets are missing:\n");
			for(i=0; i<num_missing_charsets; i++){
				printf("Missing %d: %s\n", 
					i, missing_charsets[i]);
			}
			printf("\nDefault string:%s\n", default_string);
			XFreeStringList(missing_charsets);
		}
		//字体的Extents
		fs_ext = XExtentsOfFontSet(fontset);
		dec = fs_ext->max_logical_extent.height 
			+ fs_ext->max_logical_extent.y;

		width  = W_WIDTH;
		height = W_HEIGHT + dec;

	
		//建立窗口
		win = XCreateSimpleWindow(display, 	//display
			RootWindow(display,screen_num), //父窗口
			0, 0, width, height, 		//位置和大小
			border_width, 			//边界宽度
			BlackPixel(display,screen_num), //前景色
			WhitePixel(display,screen_num));//背景色
	
		//选择窗口感兴趣的事件掩码
		XSelectInput(display, win, 
			ExposureMask | KeyPressMask | 
			ButtonPressMask | StructureNotifyMask);

		//建立GC
		gc = XCreateGC(display, win, valuemask, &values);

		protocols = XInternAtom(display, "WM_DELETE_WINDOW", True);
		XSetWMProtocols(display, win, &protocols, 1);

		//显示窗口
		XMapWindow(display, win);

		//联接输入服务器
		if((im = XOpenIM(display, NULL, NULL, NULL)) == NULL){
			printf("Error : XOpenIM !\n");
			exit(1);
		}

		//设置输入服务器的位置
		spot.x = F_SIZE / 2 * col;
		spot.y = F_SIZE * (row + 1) - dec; 
		preedit_attr = XVaCreateNestedList(0,
			XNSpotLocation, &spot,
			XNFontSet, fontset, 
			NULL);
		s_rect.x = 0;
		s_rect.y = F_SIZE * ROW + dec + 2;
		s_rect.width = W_WIDTH;
		s_rect.height = F_SIZE;
		status_attr = XVaCreateNestedList(0,
			XNArea, &s_rect,
			XNFontSet, fontset,
			NULL);
		//建立IC
		if((ic = XCreateIC(im, 
			XNInputStyle, XIMPreeditPosition | XIMStatusNothing,
			XNClientWindow, win, 
			XNPreeditAttributes, preedit_attr,
			XNStatusAttributes, status_attr, NULL)) == NULL){
			printf("Error : XCreateIC() ! \n");
			XCloseIM(im);
			exit(0);
		}
		//释放内存
		XFree(preedit_attr);
		XFree(status_attr);


		//写屏缓冲区初始化
		for(i = 0; i < ROW; i++)s_tab[i][0] = 0;

		//进入事件循环
		while (1)  {

			//取得队列中的事件
			XNextEvent(display, &report);

			//过滤事件
			if(XFilterEvent(&report, None) == True) continue;
			switch  (report.type) {

			//聚焦发声变化
			case FocusIn:
				XSetICFocus(ic); 
				break;
			case FocusOut:
				XUnsetICFocus(ic);
				break;

			//曝光事件, 窗口应重绘
			case Expose:
				//取得最后一个曝光事件
				if (report.xexpose.count != 0) break;
				for ( i=0; i < ROW; i++)
					XmbDrawString(display, win, fontset,gc, 
					0, F_SIZE * (i +1), 
					s_tab[i], strlen(s_tab[i]));
				break;

			//窗口尺寸改变, 重新取得窗口的宽度和高度
			case ConfigureNotify:
				width = report.xconfigure.width;
				height = report.xconfigure.height;
				break;

			//鼠标点击或有按键, 释放资源则退出
			case KeyPress:
				count = XmbLookupString(ic, 
					(XKeyPressedEvent *) &report,
					string, len, &keysym, &status);
				string[count] = 0;
				if (status == XLookupBoth&&keysym == XK_Return){
					row = (++row) % ROW;
					col = 0;
					s_tab[row][0] = 0;
					XClearArea(display, win, 
						0, F_SIZE * row + dec,
						W_WIDTH, F_SIZE, False);
				} else if (status = XLookupChars 
					|| status == XLookupBoth){
					XmbDrawString(display, win, fontset, gc,
					F_SIZE / 2 * col, F_SIZE * (row + 1),
					string, count);
					for (i = 0; i < count && col < len && 
						string[i]; i++, col++)
						s_tab[row][col] = string[i];
						s_tab[row][col] = 0;
				}
				//更新输入服务器位置
				spot.x = F_SIZE / 2 * col;
				spot.y = F_SIZE * (row + 1);
				preedit_attr = XVaCreateNestedList(0,
					XNSpotLocation, &spot,
					NULL);
				XSetICValues(ic, 
					XNPreeditAttributes, preedit_attr, 
					NULL);
				XFree(preedit_attr);
				break;
			case ClientMessage:
				if (report.xclient.data.l[0] == protocols) {
					XDestroyIC(ic);
					XCloseIM(im);
					XDestroyWindow(display, win);
					XCloseDisplay(display);
					exit(0);
				}
				break;
			default:
				break;
			}
		}
	}
Esempio n. 24
0
void emX11WindowPort::HandleEvent(XEvent & event)
{
	emInputEvent inputEvent;
	emX11WindowPort * wp;
	char tmp[256];
	char keymap[32];
	KeySym ks;
	emInputKey key;
	Status status;
	int i,x,y,w,h,mask,repeat,variant,len;
	double mx,my;
	bool inside;

	// Remember:
	// - Calling InputToView may delete this window port.
	// - The grab stuff is very very tricky.

	switch (event.type) {
	case MotionNotify:
		mx=PaneX+event.xmotion.x+Screen.MouseWarpX;
		my=PaneY+event.xmotion.y+Screen.MouseWarpY;
		if (
			Screen.InputState.GetMouseX()!=mx ||
			Screen.InputState.GetMouseY()!=my
		) {
			Screen.InputState.SetMouse(mx,my);
			Screen.InputStateClock++;
		}
		for (i=0; i<3; i++) {
			if      (i==0) { key=EM_KEY_LEFT_BUTTON  ; mask=Button1Mask; }
			else if (i==1) { key=EM_KEY_MIDDLE_BUTTON; mask=Button2Mask; }
			else           { key=EM_KEY_RIGHT_BUTTON ; mask=Button3Mask; }
			if (Screen.InputState.Get(key) && (event.xmotion.state&mask)==0) {
				Screen.InputState.Set(key,false);
				Screen.InputStateClock++;
			}
		}
		return;
	case ButtonPress:
		mx=PaneX+event.xbutton.x+Screen.MouseWarpX;
		my=PaneY+event.xbutton.y+Screen.MouseWarpY;
		if (
			Screen.InputState.GetMouseX()!=mx ||
			Screen.InputState.GetMouseY()!=my
		) {
			Screen.InputState.SetMouse(mx,my);
			Screen.InputStateClock++;
		}
		wp=SearchOwnedPopupAt(mx,my);
		if (wp) {
			if (wp->Mapped) {
				event.xbutton.x+=PaneX-wp->PaneX;
				event.xbutton.y+=PaneY-wp->PaneY;
				wp->HandleEvent(event);
			}
			return;
		}
		if (ModalDescendants>0) {
			FocusModalDescendant(true);
			return;
		}
		inside=(
			mx>=PaneX && mx<PaneX+PaneW &&
			my>=PaneY && my<PaneY+PaneH
		);
		if (
			!inside &&
			Screen.GrabbingWinPort==this &&
			(GetWindowFlags()&emWindow::WF_POPUP)!=0
		) {
			XMutex.Lock();
			XAllowEvents(Disp,ReplayPointer,CurrentTime);
			XMutex.Unlock();
			Screen.GrabbingWinPort=NULL;
			LastButtonPress=EM_KEY_NONE;
			SignalWindowClosing();
		}
		for (i=Screen.WinPorts.GetCount()-1; i>=0; i--) {
			wp=Screen.WinPorts[i];
			if (
				(wp->GetWindowFlags()&emWindow::WF_POPUP)!=0 &&
				wp!=this && !wp->IsAncestorOf(this)
			) {
				wp->SignalWindowClosing();
			}
		}
		if (!inside) return;
		if (!Focused && event.xbutton.button>=1 && event.xbutton.button<=5) {
			RequestFocus();
			Screen.UpdateKeymapAndInputState();
		}
		if (event.xbutton.button>=1 && event.xbutton.button<=3) {
			if      (event.xbutton.button==1) key=EM_KEY_LEFT_BUTTON;
			else if (event.xbutton.button==2) key=EM_KEY_MIDDLE_BUTTON;
			else                              key=EM_KEY_RIGHT_BUTTON;
			if (!Screen.InputState.Get(key)) {
				Screen.InputState.Set(key,true);
				Screen.InputStateClock++;
				if (
					key==LastButtonPress &&
					event.xbutton.time>LastButtonPressTime &&
					event.xbutton.time-LastButtonPressTime<=330 &&
					event.xbutton.x>=LastButtonPressX-10 &&
					event.xbutton.x<=LastButtonPressX+10 &&
					event.xbutton.y>=LastButtonPressY-10 &&
					event.xbutton.y<=LastButtonPressY+10
				) {
					repeat=LastButtonPressRepeat+1;
				}
				else {
					repeat=0;
				}
				LastButtonPress=key;
				LastButtonPressTime=event.xbutton.time;
				LastButtonPressX=event.xbutton.x;
				LastButtonPressY=event.xbutton.y;
				LastButtonPressRepeat=repeat;
				inputEvent.Setup(key,"",repeat,0);
				InputStateClock=Screen.InputStateClock;
				InputToView(inputEvent,Screen.InputState);
				return;
			}
		}
		else if (event.xbutton.button==4) {
			inputEvent.Setup(EM_KEY_WHEEL_UP,"",0,0);
			InputStateClock=Screen.InputStateClock;
			InputToView(inputEvent,Screen.InputState);
			return;
		}
		else if (event.xbutton.button==5) {
			inputEvent.Setup(EM_KEY_WHEEL_DOWN,"",0,0);
			InputStateClock=Screen.InputStateClock;
			InputToView(inputEvent,Screen.InputState);
			return;
		}
		return;
	case ButtonRelease:
		mx=PaneX+event.xbutton.x+Screen.MouseWarpX;
		my=PaneY+event.xbutton.y+Screen.MouseWarpY;
		if (
			Screen.InputState.GetMouseX()!=mx ||
			Screen.InputState.GetMouseY()!=my
		) {
			Screen.InputState.SetMouse(mx,my);
			Screen.InputStateClock++;
		}
		if (event.xbutton.button>=1 && event.xbutton.button<=3) {
			if      (event.xbutton.button==1) key=EM_KEY_LEFT_BUTTON;
			else if (event.xbutton.button==2) key=EM_KEY_MIDDLE_BUTTON;
			else                              key=EM_KEY_RIGHT_BUTTON;
			if (Screen.InputState.Get(key)) {
				Screen.InputState.Set(key,false);
				Screen.InputStateClock++;
				inputEvent.Eat();
				InputStateClock=Screen.InputStateClock;
				InputToView(inputEvent,Screen.InputState);
				return;
			}
		}
		return;
	case KeyPress:
		i=event.xkey.keycode/8;
		mask=1<<(event.xkey.keycode&7);
		if (i<32 && (Screen.Keymap[i]&mask)==0) {
			Screen.Keymap[i]|=mask;
			Screen.UpdateInputStateFromKeymap();
		}
		if (InputContext) {
			XMutex.Lock();
			len=XmbLookupString(
				InputContext,
				&event.xkey,
				tmp,
				sizeof(tmp)-1,
				&ks,
				&status
			);
			XMutex.Unlock();
			if (status!=XLookupChars && status!=XLookupBoth) len=0;
			if (status!=XLookupKeySym && status!=XLookupBoth) ks=0;
		}
		else {
			XMutex.Lock();
			len=XLookupString(
				&event.xkey,
				tmp,
				sizeof(tmp)-1,
				&ks,
				&ComposeStatus
			);
			XMutex.Unlock();
		}
		tmp[len]=0;
		key=emX11Screen::ConvertKey(ks,&variant);
		if (key==EM_KEY_NONE && !tmp[0]) return;
		repeat=0;
		if (
			key!=EM_KEY_NONE &&
			Screen.InputState.Get(key) &&
			RepeatKey==key
		) {
			repeat=KeyRepeat+1;
		}
		if (ModalDescendants>0) return;
		RepeatKey=key;
		KeyRepeat=repeat;
		inputEvent.Setup(key,tmp,repeat,variant);
		InputStateClock=Screen.InputStateClock;
		InputToView(inputEvent,Screen.InputState);
		return;
	case KeyRelease:
		memset(keymap,0,sizeof(keymap));
		XMutex.Lock();
		XQueryKeymap(Disp,keymap);
		XMutex.Unlock();
		i=event.xkey.keycode/8;
		mask=1<<(event.xkey.keycode&7);
		if (i<32 && (keymap[i]&mask)==0) {
			RepeatKey=EM_KEY_NONE;
			if ((Screen.Keymap[i]&mask)!=0) {
				Screen.Keymap[i]&=~mask;
				Screen.UpdateInputStateFromKeymap();
			}
		}
		return;
	case Expose:
		x=event.xexpose.x;
		y=event.xexpose.y;
		w=event.xexpose.width;
		h=event.xexpose.height;
		InvalidatePainting(PaneX+x,PaneY+y,w,h);
		return;
	case FocusIn:
		if (
			event.xfocus.mode==NotifyNormal ||
			event.xfocus.mode==NotifyWhileGrabbed
		) {
			if (InputContext) {
				XMutex.Lock();
				XSetICFocus(InputContext);
				XMutex.Unlock();
			}
			Screen.UpdateKeymapAndInputState();
			RepeatKey=EM_KEY_NONE;
			if (!Focused) {
				Focused=true;
				SetViewFocused(true);
			}
			if (ModalDescendants>0) FocusModalDescendant();
		}
		return;
	case FocusOut:
		if (
			event.xfocus.mode==NotifyNormal ||
			event.xfocus.mode==NotifyWhileGrabbed
		) {
			if (InputContext) {
				XMutex.Lock();
				XUnsetICFocus(InputContext);
				XMutex.Unlock();
			}
			if (Focused) {
				Focused=false;
				SetViewFocused(false);
			}
			LastButtonPress=EM_KEY_NONE;
			RepeatKey=EM_KEY_NONE;
		}
		return;
	case ConfigureNotify:
		// The meaning of the coordinates from event.xconfigure depends on
		// the window manager. Therefore:
		GetAbsWinGeometry(Disp,Win,&x,&y,&w,&h);
		if (PaneX!=x || PaneY!=y || PaneW!=w || PaneH!=h) {
			PaneX=x;
			PaneY=y;
			PaneW=w;
			PaneH=h;
			ClipX1=PaneX;
			ClipY1=PaneY;
			ClipX2=PaneX+PaneW;
			ClipY2=PaneY+PaneH;
			InvalidRects.Set(PaneX,PaneY,PaneX+PaneW,PaneY+PaneH);
			WakeUp();
			if (!PosPending && !SizePending) {
				SetViewGeometry(
					PaneX,PaneY,
					PaneW,PaneH,
					Screen.PixelTallness
				);
			}
			else if (!PosPending) {
				SetViewGeometry(
					PaneX,PaneY,
					GetViewWidth(),GetViewHeight(),
					Screen.PixelTallness
				);
			}
			else if (!SizePending) {
				SetViewGeometry(
					GetViewX(),GetViewY(),
					PaneW,PaneH,
					Screen.PixelTallness
				);
			}
			Screen.InputStateClock++;
		}
		return;
	case MapNotify:
		if (event.xmap.window==Win && !Mapped) {
			Mapped=true;
			WakeUp();
		}
		return;
	case UnmapNotify:
		if (event.xmap.window==Win && Mapped) {
			Mapped=false;
		}
		return;
	case ClientMessage:
		if (event.xclient.data.l[0]==(long)Screen.WM_DELETE_WINDOW) {
			if (ModalDescendants<=0) SignalWindowClosing();
			else FocusModalDescendant(true);
		}
		return;
	}
}
Esempio n. 25
0
static void create_aux_windows(_THIS)
{
    int x = 0, y = 0;
    char classname[1024];
    XSetWindowAttributes xattr;
    XWMHints *hints;
    unsigned long app_event_mask;
    int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen));

    
    WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);

    
    if ( SDL_windowid ) {
	FSwindow = 0;
	WMwindow = SDL_strtol(SDL_windowid, NULL, 0);
        return;
    }

    if(FSwindow)
	XDestroyWindow(SDL_Display, FSwindow);

#if SDL_VIDEO_DRIVER_X11_XINERAMA
    if ( use_xinerama ) {
        x = xinerama_info.x_org;
        y = xinerama_info.y_org;
    }
#endif
    xattr.override_redirect = True;
    xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0;
    xattr.border_pixel = 0;
    xattr.colormap = SDL_XColorMap;

    FSwindow = XCreateWindow(SDL_Display, SDL_Root,
                             x + X11_wmXAdjust,
                             y + X11_wmYAdjust,
                             32, 32, 0,
			     this->hidden->depth, InputOutput, SDL_Visual,
			     CWOverrideRedirect | CWBackPixel | CWBorderPixel
			     | CWColormap,
			     &xattr);

    XSelectInput(SDL_Display, FSwindow, StructureNotifyMask);

    
    {
	XEvent ev;
	long mask;

	SDL_memset(&ev, 0, sizeof(ev));
	ev.xclient.type = ClientMessage;
	ev.xclient.window = SDL_Root;
	ev.xclient.message_type = XInternAtom(SDL_Display,
					      "KWM_KEEP_ON_TOP", False);
	ev.xclient.format = 32;
	ev.xclient.data.l[0] = FSwindow;
	ev.xclient.data.l[1] = CurrentTime;
	mask = SubstructureRedirectMask;
	XSendEvent(SDL_Display, SDL_Root, False, mask, &ev);
    }

    hints = NULL;
    if(WMwindow) {
	
	hints = XGetWMHints(SDL_Display, WMwindow);
	XDestroyWindow(SDL_Display, WMwindow);
    }

    
    
    WMwindow = XCreateWindow(SDL_Display, SDL_Root,
                             x, y, 32, 32, 0,
			     this->hidden->depth, InputOutput, SDL_Visual,
			     CWBackPixel | CWBorderPixel | CWColormap,
			     &xattr);

    
    if(!hints) {
	hints = XAllocWMHints();
	hints->input = True;
	hints->flags = InputHint;
    }
    XSetWMHints(SDL_Display, WMwindow, hints);
    XFree(hints);
    X11_SetCaptionNoLock(this, this->wm_title, this->wm_icon);

    app_event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask
	| PropertyChangeMask | StructureNotifyMask | KeymapStateMask;
    XSelectInput(SDL_Display, WMwindow, app_event_mask);

    
    get_classname(classname, sizeof(classname));
    {
	XClassHint *classhints;
	classhints = XAllocClassHint();
	if(classhints != NULL) {
	    classhints->res_name = classname;
	    classhints->res_class = classname;
	    XSetClassHint(SDL_Display, WMwindow, classhints);
	    XFree(classhints);
	}
    }

	{
		pid_t pid = getpid();
		char hostname[256];

		if (pid > 0 && gethostname(hostname, sizeof(hostname)) > -1) {
			Atom _NET_WM_PID = XInternAtom(SDL_Display, "_NET_WM_PID", False);
			Atom WM_CLIENT_MACHINE = XInternAtom(SDL_Display, "WM_CLIENT_MACHINE", False);
			
			hostname[sizeof(hostname)-1] = '\0';
			XChangeProperty(SDL_Display, WMwindow, _NET_WM_PID, XA_CARDINAL, 32,
					PropModeReplace, (unsigned char *)&pid, 1);
			XChangeProperty(SDL_Display, WMwindow, WM_CLIENT_MACHINE, XA_STRING, 8,
					PropModeReplace, (unsigned char *)hostname, SDL_strlen(hostname));
		}
	}

	

	#ifdef X_HAVE_UTF8_STRING
	if (SDL_X11_HAVE_UTF8) {
		
		if (SDL_IM != NULL && SDL_Display != XDisplayOfIM(SDL_IM)) {
			SDL_SetError("display has changed while an IM is kept");
			if (SDL_IC) {
				XUnsetICFocus(SDL_IC);
				XDestroyIC(SDL_IC);
				SDL_IC = NULL;
			}
			XCloseIM(SDL_IM);
			SDL_IM = NULL;
		}

		
		if (SDL_IM == NULL) {
			char *old_locale = NULL, *old_modifiers = NULL;
			const char *p;
			size_t n;

			p = setlocale(LC_ALL, NULL);
			if ( p ) {
				n = SDL_strlen(p)+1;
				old_locale = SDL_stack_alloc(char, n);
				if ( old_locale ) {
					SDL_strlcpy(old_locale, p, n);
				}
			}
			p = XSetLocaleModifiers(NULL);
			if ( p ) {
				n = SDL_strlen(p)+1;
				old_modifiers = SDL_stack_alloc(char, n);
				if ( old_modifiers ) {
					SDL_strlcpy(old_modifiers, p, n);
				}
			}

			setlocale(LC_ALL, "");
			XSetLocaleModifiers("");
			SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname);

			if ( old_locale ) {
				setlocale(LC_ALL, old_locale);
				SDL_stack_free(old_locale);
			}
			if ( old_modifiers ) {
				XSetLocaleModifiers(old_modifiers);
				SDL_stack_free(old_modifiers);
			}
		}

		
		if (SDL_IM == NULL) {
			SDL_SetError("no input method could be opened");
		} else {
			if (SDL_IC != NULL) {
				
			    XUnsetICFocus(SDL_IC);
			    XDestroyIC(SDL_IC);
			}
			SDL_IC = pXCreateIC(SDL_IM,
					XNClientWindow, WMwindow,
					XNFocusWindow, WMwindow,
					XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
					XNResourceName, classname,
					XNResourceClass, classname,
					NULL);

			if (SDL_IC == NULL) {
				SDL_SetError("no input context could be created");
				XCloseIM(SDL_IM);
				SDL_IM = NULL;
			} else {
				unsigned long mask = 0;
				char *ret = pXGetICValues(SDL_IC, XNFilterEvents, &mask, NULL);
				if (ret != NULL) {
					XUnsetICFocus(SDL_IC);
					XDestroyIC(SDL_IC);
					SDL_IC = NULL;
					SDL_SetError("no input context could be created");
					XCloseIM(SDL_IM);
					SDL_IM = NULL;
				} else {
					XSelectInput(SDL_Display, WMwindow, app_event_mask | mask);
					XSetICFocus(SDL_IC);
				}
			}
		}
	}
Esempio n. 26
0
void TInputContext::ClearFocus()
{		
	XUnsetICFocus(fXIC);
	sFocusedWindow = NULL;
}