我一直在尝试和阅读Internet上的大量资源,试图找到一种从X显示器获取UTF-8键盘(组合)输入的方法。但是我无法使其工作。
我已经尝试过此链接中的示例代码(例如11-4),但没有成功。
我还写了一个简单的示例(如下),试图使其工作。我的简单测试用例是打印一个“é”,这是通过先键入“ a”然后再键入e来实现的。
怎么了?
谢谢,
这是我的示例:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/Xlocale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{
int screen_num, width, height;
unsigned long background, border;
Window win;
XEvent ev;
Display *dpy;
XIM im;
XIC ic;
char *failed_arg;
XIMStyles *styles;
XIMStyle xim_requested_style;
/* First connect to the display server, as specified in the DISPLAY
environment variable. */
if (setlocale(LC_ALL, "") == NULL) {
return 9;
}
if (!XSupportsLocale()) {
return 10;
}
if (XSetLocaleModifiers("") == NULL) {
return 11;
}
dpy = XOpenDisplay(NULL);
if (!dpy) {
fprintf(stderr, "unable to connect to display");
return 7;
}
/* these are macros that pull useful data out of the display object */
/* we use these bits of info enough to want them in their own variables */
screen_num = DefaultScreen(dpy);
background = BlackPixel(dpy, screen_num);
border = WhitePixel(dpy, screen_num);
width = 400; /* start with a small window */
height = 200;
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), /* display, parent */
0,0, /* x, y: the window manager will place the window elsewhere */
width, height, /* width, height */
2, border, /* border width & colour, unless you have a window manager */
background); /* background colour */
/* tell the display server what kind of events we would like to see */
XSelectInput(dpy, win, ButtonPressMask|StructureNotifyMask|KeyPressMask|KeyReleaseMask|KeymapStateMask);
/* okay, put the window on the screen, please */
XMapWindow(dpy, win);
im = XOpenIM(dpy, NULL, NULL, NULL);
if (im == NULL) {
fputs("Could not open input method\n", stdout);
return 2;
}
failed_arg = XGetIMValues(im, XNQueryInputStyle, &styles, NULL);
if (failed_arg != NULL) {
fputs("XIM Can't get styles\n", stdout);
return 3;
}
int i;
for (i = 0; i < styles->count_styles; i++) {
printf("style %d\n", styles->supported_styles[i]);
}
ic = XCreateIC(im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, NULL);
if (ic == NULL) {
printf("Could not open IC\n");
return 4;
}
XSetICFocus(ic);
/* as each event that we asked about occurs, we respond. In this
* case we note if the window's shape changed, and exit if a button
* is pressed inside the window */
while(1) {
XNextEvent(dpy, &ev);
switch(ev.type){
case KeymapNotify:
XRefreshKeyboardMapping(&ev.xmapping);
break;
case KeyPress:
{
int count = 0;
KeySym keysym = 0;
char buf[20];
Status status = 0;
count = Xutf8LookupString(ic, (XKeyPressedEvent*)&ev, buf, 20, &keysym, &status);
printf("count: %d\n", count);
if (status==XBufferOverflow)
printf("BufferOverflow\n");
if (count)
printf("buffer: %s\n", buf);
if (status == XLookupKeySym || status == XLookupBoth) {
printf("status: %d\n", status);
}
printf("pressed KEY: %d\n", keysym);
}
break;
case KeyRelease:
{
int count = 0;
KeySym keysym = 0;
char buf[20];
Status status = 0;
count = XLookupString((XKeyEvent*)&ev, buf, 20, &keysym, NULL);
if (count)
printf("in release buffer: %s\n", buf);
printf("released KEY: %d\n", keysym);
}
break;
case ConfigureNotify:
if (width != ev.xconfigure.width
|| height != ev.xconfigure.height) {
width = ev.xconfigure.width;
height = ev.xconfigure.height;
printf("Size changed to: %d by %d", width, height);
}
break;
case ButtonPress:
XCloseDisplay(dpy);
return 0;
}
fflush(stdout);
}
}
您必须这样做:
if (XFilterEvent(&ev, win))
continue;
在您的事件循环中。这将运行输入法机制,没有它,您将获得原始X事件。例如,当您按一个重音符号后跟一个字母键,并且不进行调用时XFilterEvent
,您将像往常一样获得两个KeyPress事件。但是,如果您拨打电话,您将获得
三个 事件。有两个原始事件,需要为其XFilterEvent(&ev, win)
返回True
。然后,通过输入法合成了一个事件,针对该事件XFilterEvent(&ev, win)
返回False
。这是第三个事件,其中包含重音字符。
如果您既想要原始事件,又想要通过输入法合成的原始事件,则当然可以使用自己做原始事件处理continue
。
请注意buf[count] = 0;
,为了buf
正确打印(或显式使用长度),您将需要Xutf8LookupString
不对输出进行null终止。
最后,如评论中所述,对于X11的最新版本,您将需要指定对的修改,XSetLocaleModifiers
例如XSetLocaleModifiers("@im=none")
,否则将不会生成额外的事件。
这是代码的更正版本:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/Xlocale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{
int screen_num, width, height;
unsigned long background, border;
Window win;
XEvent ev;
Display *dpy;
XIM im;
XIC ic;
char *failed_arg;
XIMStyles *styles;
XIMStyle xim_requested_style;
/* First connect to the display server, as specified in the DISPLAY
environment variable. */
if (setlocale(LC_ALL, "") == NULL) {
return 9;
}
if (!XSupportsLocale()) {
return 10;
}
if (XSetLocaleModifiers("@im=none") == NULL) {
return 11;
}
dpy = XOpenDisplay(NULL);
if (!dpy) {
fprintf(stderr, "unable to connect to display");
return 7;
}
/* these are macros that pull useful data out of the display object */
/* we use these bits of info enough to want them in their own variables */
screen_num = DefaultScreen(dpy);
background = BlackPixel(dpy, screen_num);
border = WhitePixel(dpy, screen_num);
width = 400; /* start with a small window */
height = 200;
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), /* display, parent */
0,0, /* x, y: the window manager will place the window elsewhere */
width, height, /* width, height */
2, border, /* border width & colour, unless you have a window manager */
background); /* background colour */
/* tell the display server what kind of events we would like to see */
XSelectInput(dpy, win, ButtonPressMask|StructureNotifyMask|KeyPressMask|KeyReleaseMask);
/* okay, put the window on the screen, please */
XMapWindow(dpy, win);
im = XOpenIM(dpy, NULL, NULL, NULL);
if (im == NULL) {
fputs("Could not open input method\n", stdout);
return 2;
}
failed_arg = XGetIMValues(im, XNQueryInputStyle, &styles, NULL);
if (failed_arg != NULL) {
fputs("XIM Can't get styles\n", stdout);
return 3;
}
int i;
for (i = 0; i < styles->count_styles; i++) {
printf("style %d\n", (int)styles->supported_styles[i]);
}
ic = XCreateIC(im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, NULL);
if (ic == NULL) {
printf("Could not open IC\n");
return 4;
}
XSetICFocus(ic);
/* as each event that we asked about occurs, we respond. In this
* case we note if the window's shape changed, and exit if a button
* is pressed inside the window */
while(1) {
XNextEvent(dpy, &ev);
if (XFilterEvent(&ev, win))
continue;
switch(ev.type){
case MappingNotify:
XRefreshKeyboardMapping(&ev.xmapping);
break;
case KeyPress:
{
int count = 0;
KeySym keysym = 0;
char buf[20];
Status status = 0;
count = Xutf8LookupString(ic, (XKeyPressedEvent*)&ev, buf, 20, &keysym, &status);
printf("count: %d\n", count);
if (status==XBufferOverflow)
printf("BufferOverflow\n");
if (count)
printf("buffer: %.*s\n", count, buf);
if (status == XLookupKeySym || status == XLookupBoth) {
printf("status: %d\n", status);
}
printf("pressed KEY: %d\n", (int)keysym);
}
break;
case KeyRelease:
{
int count = 0;
KeySym keysym = 0;
char buf[20];
Status status = 0;
count = XLookupString((XKeyEvent*)&ev, buf, 20, &keysym, NULL);
if (count)
printf("in release buffer: %.*s\n", count, buf);
printf("released KEY: %d\n", (int)keysym);
}
break;
case ConfigureNotify:
if (width != ev.xconfigure.width
|| height != ev.xconfigure.height) {
width = ev.xconfigure.width;
height = ev.xconfigure.height;
printf("Size changed to: %d by %d", width, height);
}
break;
case ButtonPress:
XCloseDisplay(dpy);
return 0;
}
fflush(stdout);
}
}
问题内容: 我已经阅读了一段时间的Unicode和UTF-8编码,并且我想我理解了,所以希望这不会是一个愚蠢的问题: 我有一个文件,其中包含一些CJK字符,并且已另存为UTF-8。我安装了各种亚洲语言包,并且其他应用程序可以正确显示这些字符,因此我知道可以做很多工作。 在我的Java应用程序中,我读取文件的方式如下: 输出将CJK字符显示为’???’。进行呼叫以确认它肯定是在使用UTF-8。我缺少
问题内容: 如何在我的API上获得UTF-8支持?此刻,一个字符串输出如下: 代替: 在以下结帐app.js: 问题答案: 连接到响应生成器或创建执行以下操作的中间件: 否则,浏览器将以他喜欢的编码显示内容。 如果这不能帮助您,则DB可能编码错误。 编辑: 由于答案将近5年,API已更改。对于当前的node.js版本,请使用:
问题内容: 因此,我已经处理这个问题已有一个多月了,并且我还在google以及Google上检查了几乎所有可能的相关解决方案,但找不到任何能够真正解决我问题的方法。我的问题是我正在尝试从网站下载html源,但是在大多数情况下,我得到的是某些文本显示一些“?” 其中的字符,很可能是因为该站点位于希伯来语中。这是我的代码, 谢谢。 问题答案: 要使用给定的编码从字节流中读取字符,请使用。在您的情况下,
问题内容: 我的数据库已正确设置为UTF-8,并且正在处理包含日语字符的数据库。如果我从mysql命令行执行SELECT * …,我会正确看到日语字符。当将数据从数据库中拉出并显示在网页上时,我可以正确地看到它。 但是,在phpMyAdmin中查看表数据时,我只会看到垃圾文本。即。 ç§ã日本料ç†ãŒå¥½ããããã㥥œœ¬æ–™ç†ã… 如何获取phpMyAdmin以日语显示字
我有一个任务: 当我使用命令时: 文本显示不正确。如何修复?谢谢
问题内容: 是否可以在JavaScript中使用textarea元素的值,还是应该使用? 谢谢。 问题答案: 您应该使用.value