xim.c

来自「具有IDE功能的编辑器」· C语言 代码 · 共 609 行 · 第 1/2 页

C
609
字号
#endif}static long destroy_input_context (CWidget * w){    w->input_context = 0;    return 0;}void IMDestroyCallback (XIM xim, XPointer client_data, XPointer call_data){    XRegisterIMInstantiateCallback (CDisplay, NULL, NULL, NULL,				    IMInstantiateCallback, NULL);    for_all_widgets ((void *) destroy_input_context, 0, 0);    CIC = 0;}/* returns zero on error */XIMStyle get_input_style (void){    int found = 0;    char tmp[1024] = "", *s = 0;    char *end = 0, *next_s = 0;    XIMStyle input_style = 0;    XIMStyles *xim_styles = NULL;    if (!CIM) {	if (option_use_xim)	    xim_print_error ("Trying to get input_style, but Input Method is null.");	return 0;    }    if (XGetIMValues (CIM, XNQueryInputStyle, &xim_styles, NULL)	|| !xim_styles) {	xim_print_error ("input method doesn't support any style");	return 0;    }#ifdef RXVT_SOURCE    strncpy (tmp, (rs[Rs_preeditType] ? rs[Rs_preeditType]		   : "OverTheSpot,OffTheSpot,Root"),	     sizeof (tmp) - 1);#else    strncpy (tmp, "OverTheSpot,OffTheSpot,Root",	     sizeof (tmp) - 1);#endif    for (found = 0, s = tmp; *s && !found; s = next_s + 1) {	unsigned short i;	for (; *s && isspace (*s); s++);	if (!*s)	    break;	for (end = s; (*end && (*end != ',')); end++);	for (next_s = end--; ((end >= s) && isspace (*end)); end--);	*(end + 1) = '\0';	if (!strcmp (s, "OverTheSpot"))	    input_style = (XIMPreeditPosition | XIMStatusNothing);	else if (!strcmp (s, "OffTheSpot"))	    input_style = (XIMPreeditArea | XIMStatusArea);	else if (!strcmp (s, "Root"))	    input_style = (XIMPreeditNothing | XIMStatusNothing);	for (i = 0; i < xim_styles->count_styles; i++)	    if (input_style == xim_styles->supported_styles[i]) {		found = 1;		break;	    }    }    XFree (xim_styles);    if (found == 0) {	xim_print_error ("input method doesn't support my preedit type");	return 0;    }    if ((input_style != (XIMPreeditNothing | XIMStatusNothing))	&& (input_style != (XIMPreeditArea | XIMStatusArea))	&& (input_style != (XIMPreeditPosition | XIMStatusNothing))) {	xim_print_error ("This program does not support the preedit type");	return 0;    }    return input_style;}long create_input_context (CWidget * w, XIMStyle input_style){    XVaNestedList preedit_attr = 0;    XVaNestedList status_attr = 0;    XPoint spot;    XRectangle rect, status_rect, needed_rect;    XIMCallback ximcallback;    unsigned long fg, bg;    if (w->kind != C_WINDOW_WIDGET)	return 0;    if (w->mainid)	return 0;    if (w->input_context)	return 0;    if (!CIM)	return 1;    if (!input_style)	return 1;    ximcallback.callback = IMDestroyCallback;    ximcallback.client_data = NULL;    if (input_style & XIMPreeditPosition) {	setSize (w, &rect);	setPosition (0, w, &spot);	setColor (w, &fg, &bg);	preedit_attr = XVaCreateNestedList (0, XNArea, &rect,					    XNSpotLocation, &spot,					    XNForeground, fg,					    XNBackground, bg,				       XNFontSet, current_font->font_set,					    NULL);    } else if (input_style & XIMPreeditArea) {	setColor (w, &fg, &bg);	/* 	 * The necessary width of preedit area is unknown	 * until create input context.	 */	needed_rect.width = 0;	setPreeditArea (w, &rect, &status_rect, &needed_rect);	preedit_attr = XVaCreateNestedList (0, XNArea, &rect,					    XNForeground, fg,					    XNBackground, bg,				       XNFontSet, current_font->font_set,					    NULL);	status_attr = XVaCreateNestedList (0, XNArea, &status_rect,					   XNForeground, fg,					   XNBackground, bg,				       XNFontSet, current_font->font_set,					   NULL);    }    w->input_context = XCreateIC (CIM, XNInputStyle, input_style,				  XNClientWindow, w->winid,				  XNFocusWindow, w->winid,				  XNDestroyCallback, &ximcallback,			       preedit_attr ? XNPreeditAttributes : NULL,				  preedit_attr,				  status_attr ? XNStatusAttributes : NULL,				  status_attr,				  NULL);    if (preedit_attr)	XFree (preedit_attr);    if (status_attr)	XFree (status_attr);    if (!w->input_context) {	xim_print_error ("Failed to create input context for widget %s", w->ident);	return 1;    }    return 0;}long set_status_position (CWidget * w){    XIMStyle input_style;    XRectangle preedit_rect, status_rect, *needed_rect = 0;    XVaNestedList preedit_attr, status_attr;    if (!w->input_context)	return 0;    XGetICValues (w->input_context, XNInputStyle, &input_style, NULL);    if (input_style & XIMPreeditArea) {	/* Getting the necessary width of preedit area */	status_attr = XVaCreateNestedList (0, XNAreaNeeded, &needed_rect, NULL);	XGetICValues (w->input_context, XNStatusAttributes, status_attr, NULL);	XFree (status_attr);	setPreeditArea (w, &preedit_rect, &status_rect, needed_rect);	preedit_attr = XVaCreateNestedList (0, XNArea, &preedit_rect, NULL);	status_attr = XVaCreateNestedList (0, XNArea, &status_rect, NULL);	XSetICValues (w->input_context,		      XNPreeditAttributes, preedit_attr,		      XNStatusAttributes, status_attr, NULL);	XFree (preedit_attr);	XFree (status_attr);    }    return 0;}static void IMInstantiateCallback (Display * display, XPointer client_data, XPointer call_data){    char *p;    XIMStyle input_style = 0;    XIMCallback ximcallback;    if (CIC)	return;    ximcallback.callback = IMDestroyCallback;    ximcallback.client_data = NULL;#ifdef RXVT_SOURCE    if (rs[Rs_inputMethod] && *rs[Rs_inputMethod]) {	strncpy (tmp, option_imput_method, sizeof (tmp) - 1);	for (s = tmp; *s; s = next_s + 1) {	    for (; *s && isspace (*s); s++);	    if (!*s)		break;	    for (end = s; (*end && (*end != ',')); end++);	    for (next_s = end--; ((end >= s) && isspace (*end)); end--);	    *(end + 1) = '\0';	    if (*s) {		strcpy (buf, "@im=");		strncat (buf, s, sizeof (buf) - 4 - 1);		if ((p = XSetLocaleModifiers (buf)) != NULL && *p		 && (CIM = XOpenIM (CDisplay, NULL, NULL, NULL)) != NULL)		    break;	    }	    if (!*next_s)		break;	}    }#endif    /* try with XMODIFIERS env. var. */    if (CIM == NULL && (p = XSetLocaleModifiers ("")) != NULL && *p)	CIM = XOpenIM (CDisplay, NULL, NULL, NULL);    /* try with XMODIFIERS env. var. */    if (CIM == NULL && (p = XSetLocaleModifiers ("@im=control")) != NULL && *p)	CIM = XOpenIM (CDisplay, NULL, NULL, NULL);    /* try with no modifiers base */    if (CIM == NULL && (p = XSetLocaleModifiers ("@im=none")) != NULL && *p)	CIM = XOpenIM (CDisplay, NULL, NULL, NULL);    if (!CIM)	return;/* got the Input Method, now set up all dialogs */    XSetIMValues (CIM, XNDestroyCallback, &ximcallback, NULL);    if (!(input_style = get_input_style ())) {	XCloseIM (CIM);	CIM = 0;    }    CPushFont ("editor", 0);    if (for_all_widgets ((void *) create_input_context, (void *) input_style, 0)) {	input_style = 0;	XCloseIM (CIM);	CIM = 0;    }    CPopFont ();    if (input_style & XIMPreeditArea)	for_all_widgets ((void *) set_status_position, 0, 0);}#elseint option_use_xim = 0;KeySym key_sym_xlat (XEvent * ev, char *x_lat){    static int len = 0;    static KeySym keysym = 0;    static XComposeStatus compose =    {NULL, 0};    static unsigned char kbuf[512] = "";    static Time time = 0;    static int valid_keysym = 1;    Status status_return = 0;    if (x_lat)	*x_lat = '\0';    if (ev->type != KeyPress && ev->type != KeyRelease)	return 0;/* we mustn't call this twice with the same event */    if (time == ev->xkey.time)	goto no_repeat_call;    time = ev->xkey.time;    keysym = 0;    len = 0;    if (ev->type == KeyRelease) {	len = XLookupString (&ev->xkey, (char *) kbuf, sizeof (kbuf), &keysym, 0);	if (!len && (keysym >= 0x0100) && (keysym < 0x0800)) {	    len = 1;	    kbuf[0] = (keysym & 0xFF);	}    } else {	keysym = 0;	len = XLookupString (&ev->xkey, (char *) kbuf, sizeof (kbuf), &keysym, &compose);	if (!len && (keysym >= 0x0100) && (keysym < 0x0800)) {	    len = 1;	    kbuf[0] = (keysym & 0xFF);	}    }  no_repeat_call:    if (x_lat) {	if (len > 0) {	    if (len > 7)		len = 7;	    memcpy (x_lat, kbuf, len);	    x_lat[len] = '\0';	}    }    return valid_keysym ? keysym : 0;}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?