Example #1
0
static void dofile(FILE * inf, char name[])
{
    unsigned char seq[7];
    uint32_t cdpt;
    size_t n = 0;
    size_t l = 0;
    int len;

    memset(seq, '\0', sizeof(seq) * sizeof(seq[0]));

    while (next_sequence(inf, seq) != -1) {
        n += seqlen(seq[0]);
        sequence_to_ucs4(seq, &cdpt);
        if ('\n' == cdpt)
            l++;
        cdpt = rot(cdpt);
        len = utf8encode(cdpt, (uint8_t *) seq);
        fwrite(seq, 1, len, stdout);
    }

    if (!valid_sequence(seq) && !feof(inf))
        fprintf(stderr,
                "rot32768: invalid UTF-8 sequence at line %llu (byte %llu) in %s\n",
                (unsigned long long int) l, (unsigned long long int) n,
                name);
}
Example #2
0
// decode message return UTF8z
LPSTR __cdecl cpp_decodeU(HANDLE context, LPCSTR szEncMsg)
{
	pCNTX ptr = get_context_on_id(context);
	if (!ptr) return NULL;
	cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA)ptr->pdata;
	if (!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; }

	LPSTR szNewMsg = NULL;
	LPSTR szOldMsg = cpp_decrypt(ptr, szEncMsg);

	if (szOldMsg) {
		if (ptr->features & FEATURES_UTF8) {
			// utf8 message: copy
			szNewMsg = mir_strdup(szOldMsg);
		}
		else {
			// ansi message: convert to utf8
			int slen = (int)strlen(szOldMsg) + 1;
			LPWSTR wstring = (LPWSTR)alloca(slen*sizeof(WCHAR));
			MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR));
			szNewMsg = mir_strdup(utf8encode(wstring));
		}
	}
	replaceStr(ptr->tmp, szNewMsg);
	return szNewMsg;
}
Example #3
0
// encode message from ANSI into UTF8 if need
LPSTR __cdecl cpp_encodeA(HANDLE context, LPCSTR msg)
{
	pCNTX ptr = get_context_on_id(context);
	if (!ptr) return NULL;
	cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA)ptr->pdata;
	if (!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; }

	LPSTR szNewMsg = NULL;
	LPSTR szOldMsg = (LPSTR)msg;

	if (ptr->features & FEATURES_UTF8) {
		// ansi message: convert to unicode->utf-8 and encrypt.
		int slen = (int)strlen(szOldMsg) + 1;
		LPWSTR wstring = (LPWSTR)alloca(slen*sizeof(WCHAR));
		MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR));
		// encrypt
		szNewMsg = cpp_encrypt(ptr, utf8encode(wstring));
	}
	else {
		// ansi message: encrypt.
		szNewMsg = cpp_encrypt(ptr, szOldMsg);
	}

	return szNewMsg;
}
Example #4
0
/* Recode a UTF-16 string with big-endian byte ordering to UTF-8 */
unsigned char* utf16BEdecode(const unsigned char *utf16, unsigned char *utf8,
        int count)
{
    unsigned long ucs;

    while (count > 0) {
        if (*utf16 >= 0xD8 && *utf16 < 0xE0) { /* Check for a surrogate pair */
            ucs = 0x10000 + (((utf16[0] - 0xD8) << 18) | (utf16[1] << 10)
                    | ((utf16[2] - 0xDC) << 8) | utf16[3]);
            utf16 += 4;
            count -= 2;
        } else {
            ucs = (utf16[0] << 8) | utf16[1];
            utf16 += 2;
            count -= 1;
        }
        utf8 = utf8encode(ucs, utf8);
    }
    return utf8;
}
Example #5
0
int main(int argc, char *argv[])
{
    unsigned long int codepoint;
    unsigned char buf[6];
    int i, j, len, res;

    if (argc < 2) {
        fprintf(stderr, "usage: %s num...\n", argv[0]);
        return 0;
    }

    for (i = 1; i < argc; i++) {
        if ((res = parse_codepoint(argv[i], &codepoint)) < 0) {
            switch (res) {
            case -1:
                fprintf(stderr, "%s: invalid codepoint %s.\n", argv[0],
                        argv[i]);
                break;
            case -2:
                fprintf(stderr, "%s: codepoint %s too large.\n", argv[0],
                        argv[i]);
                break;
            }

            continue;
        }

        len = utf8encode((uint32_t) codepoint, (uint8_t *) buf);

        fwrite(buf, 1, len, stdout);

        printf("\t%02x", buf[0]);

        for (j = 1; j < len; j++)
            printf(" %02x", buf[j]);

        printf("\t%08x\n", codepoint);
    }

    return 0;
}
Example #6
0
LPSTR __cdecl pgp_decode(HANDLE context, LPCSTR szEncMsg)
{
	pCNTX ptr = get_context_on_id(context);
	if(!ptr) return NULL;

	LPSTR szNewMsg = NULL;
	LPSTR szOldMsg = pgp_decrypt(ptr, szEncMsg);

	if(szOldMsg) {
		if( !is_7bit_string(szOldMsg) && !is_utf8_string(szOldMsg) ) {
			int slen = strlen(szOldMsg)+1;
			LPWSTR wszMsg = (LPWSTR) alloca(slen*sizeof(WCHAR));
			MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wszMsg, slen*sizeof(WCHAR));
			szNewMsg = _strdup(utf8encode(wszMsg));
		}
		else {
			szNewMsg = _strdup(szOldMsg);
		}
	}
	SAFE_FREE(ptr->tmp);
	ptr->tmp = szNewMsg;
	return szNewMsg;
}
Example #7
0
// encode message from UNICODE into UTF8 if need
LPSTR __cdecl cpp_encodeW(HANDLE context, LPWSTR msg)
{
	pCNTX ptr = get_context_on_id(context);
	if (!ptr) return NULL;
	cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA)ptr->pdata;
	if (!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; }

	LPSTR szNewMsg = NULL;
	LPSTR szOldMsg = (LPSTR)msg;

	if (ptr->features & FEATURES_UTF8) {
		// unicode message: convert to utf-8 and encrypt.
		szNewMsg = cpp_encrypt(ptr, utf8encode((LPWSTR)szOldMsg));
	}
	else {
		// unicode message: convert to ansi and encrypt.
		int wlen = (int)wcslen((LPWSTR)szOldMsg) + 1;
		LPSTR astring = (LPSTR)alloca(wlen);
		WideCharToMultiByte(CP_ACP, 0, (LPWSTR)szOldMsg, -1, astring, wlen, 0, 0);
		szNewMsg = cpp_encrypt(ptr, astring);
	}

	return szNewMsg;
}
Example #8
0
int main(int argc, char **argv) {

    QCoreApplication app(argc, argv);
    if (argc < 3) {
        printf("\nusage: %s inputFile outputFile\n\n", argv[0]);
        printf("'inputFile' should be a list of effective TLDs, one per line,\n");
        printf("as obtained from http://publicsuffix.org . To create indices and data file\n");
        printf("file, do the following:\n\n");
        printf("       wget http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1 -O effective_tld_names.dat\n");
        printf("       grep '^[^\\/\\/]' effective_tld_names.dat > effective_tld_names.dat.trimmed\n");
        printf("       %s effective_tld_names.dat.trimmed effective_tld_names.dat.qt\n\n", argv[0]);
        printf("Now copy the data from effective_tld_names.dat.qt to the file src/network/access/qnetworkcookiejartlds_p.h in your Qt repo\n\n");
        exit(1);
    }
    QFile file(argv[1]);
    QFile outFile(argv[2]);
    file.open(QIODevice::ReadOnly);
    outFile.open(QIODevice::WriteOnly);

    QByteArray outIndicesBufferBA;
    QBuffer outIndicesBuffer(&outIndicesBufferBA);
    outIndicesBuffer.open(QIODevice::WriteOnly);

    QByteArray outDataBufferBA;
    QBuffer outDataBuffer(&outDataBufferBA);
    outDataBuffer.open(QIODevice::WriteOnly);

    int lineCount = 0;
    while (!file.atEnd()) {
        file.readLine();
        lineCount++;
    }
    file.reset();
    QVector<QString> strings(lineCount);
    while (!file.atEnd()) {
        QString s = QString::fromUtf8(file.readLine());
        QString st = s.trimmed();
        int num = qHash(st) % lineCount;

        QString utf8String = utf8encode(st.toUtf8());

        // for domain 1.com, we could get something like
        // a.com\01.com, which would be interpreted as octal 01,
        // so we need to separate those strings with quotes
        QRegExp regexpOctalEscape(QLatin1String("^[0-9]"));
        if (!strings.at(num).isEmpty() && st.contains(regexpOctalEscape))
            strings[num].append("\"\"");

        strings[num].append(utf8String);
        strings[num].append("\\0");
    }

    outIndicesBuffer.write("static const quint16 tldCount = ");
    outIndicesBuffer.write(QByteArray::number(lineCount));
    outIndicesBuffer.write(";\n");
    outIndicesBuffer.write("static const quint16 tldIndices[");
//    outIndicesBuffer.write(QByteArray::number(lineCount+1)); // not needed
    outIndicesBuffer.write("] = {\n");

    int utf8Size = 0;
//    int charSize = 0;
    for (int a = 0; a < lineCount; a++) {
        bool lineIsEmpty = strings.at(a).isEmpty();
        if (!lineIsEmpty) {
            strings[a].prepend("\"");
            strings[a].append("\"");
        }
        int zeroCount = strings.at(a).count(QLatin1String("\\0"));
        int utf8CharsCount = strings.at(a).count(QLatin1String("\\x"));
        int quoteCount = strings.at(a).count('"');
        outDataBuffer.write(strings.at(a).toUtf8());
        if (!lineIsEmpty)
            outDataBuffer.write("\n");
        outIndicesBuffer.write(QByteArray::number(utf8Size));
        outIndicesBuffer.write(",\n");
        utf8Size += strings.at(a).count() - (zeroCount + quoteCount + utf8CharsCount * 3);
//        charSize += strings.at(a).count();
    }
    outIndicesBuffer.write(QByteArray::number(utf8Size));
    outIndicesBuffer.write("};\n");
    outIndicesBuffer.close();
    outFile.write(outIndicesBufferBA);

    outDataBuffer.close();
    outFile.write("\nstatic const char tldData[");
//    outFile.write(QByteArray::number(charSize)); // not needed
    outFile.write("] = {\n");
    outFile.write(outDataBufferBA);
    outFile.write("};\n");
    outFile.close();
    printf("data generated to %s . Now copy the data from this file to src/network/access/qnetworkcookiejartlds_p.h in your Qt repo\n", argv[2]);
    exit(0);
}
Example #9
0
static void asf_utf16LEdecode(int fd,
                              uint16_t utf16bytes,
                              unsigned char **utf8,
                              int* utf8bytes
                             )
{
    unsigned long ucs;
    int n;
    unsigned char utf16buf[256];
    unsigned char* utf16 = utf16buf;
    unsigned char* newutf8;

    n = read(fd, utf16buf, MIN(sizeof(utf16buf), utf16bytes));
    utf16bytes -= n;

    while (n > 0) {
        /* Check for a surrogate pair */
        if (utf16[1] >= 0xD8 && utf16[1] < 0xE0) {
            if (n < 4) {
                /* Run out of utf16 bytes, read some more */
                utf16buf[0] = utf16[0];
                utf16buf[1] = utf16[1];

                n = read(fd, utf16buf + 2, MIN(sizeof(utf16buf)-2, utf16bytes));
                utf16 = utf16buf;
                utf16bytes -= n;
                n += 2;
            }

            if (n < 4) {
                /* Truncated utf16 string, abort */
                break;
            }
            ucs = 0x10000 + ((utf16[0] << 10) | ((utf16[1] - 0xD8) << 18)
                             | utf16[2] | ((utf16[3] - 0xDC) << 8));
            utf16 += 4;
            n -= 4;
        } else {
            ucs = (utf16[0] | (utf16[1] << 8));
            utf16 += 2;
            n -= 2;
        }

        if (*utf8bytes > 6) {
            newutf8 = utf8encode(ucs, *utf8);
            *utf8bytes -= (newutf8 - *utf8);
            *utf8 += (newutf8 - *utf8);
        }

        /* We have run out of utf16 bytes, read more if available */
        if ((n == 0) && (utf16bytes > 0)) {
            n = read(fd, utf16buf, MIN(sizeof(utf16buf), utf16bytes));
            utf16 = utf16buf;
            utf16bytes -= n;
        }
    }

    *utf8[0] = 0;
    --*utf8bytes;

    if (utf16bytes > 0) {
        /* Skip any remaining bytes */
        lseek(fd, utf16bytes, SEEK_CUR);
    }
    return;
}
Example #10
0
static void processkey(WINDISPLAY *mod, WINWINDOW *win, TUINT type, TINT code)
{
	TIMSG *imsg;
	TINT numchars = 0;
	WCHAR buff[2];

	getqualifier(mod, win);

	switch (code)
	{
		case VK_LEFT:
			code = TKEYC_CRSRLEFT;
			break;
		case VK_UP:
			code = TKEYC_CRSRUP;
			break;
		case VK_RIGHT:
			code = TKEYC_CRSRRIGHT;
			break;
		case VK_DOWN:
			code = TKEYC_CRSRDOWN;
			break;

		case VK_ESCAPE:
			code = TKEYC_ESC;
			break;
		case VK_DELETE:
			code = TKEYC_DEL;
			break;
		case VK_BACK:
			code = TKEYC_BCKSPC;
			break;
		case VK_TAB:
			code = TKEYC_TAB;
			break;
		case VK_RETURN:
			code = TKEYC_RETURN;
			break;

		case VK_HELP:
			code = TKEYC_HELP;
			break;
		case VK_INSERT:
			code = TKEYC_INSERT;
			break;
		case VK_PRIOR:
			code = TKEYC_PAGEUP;
			break;
		case VK_NEXT:
			code = TKEYC_PAGEDOWN;
			break;
		case VK_HOME:
			code = TKEYC_POSONE;
			break;
		case VK_END:
			code = TKEYC_POSEND;
			break;
		case VK_PRINT:
			code = TKEYC_PRINT;
			break;
		case VK_SCROLL:
			code = TKEYC_SCROLL;
			break;
		case VK_PAUSE:
			code = TKEYC_PAUSE;
			break;
		case VK_DECIMAL:
			code = '.';
			imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
			break;
		case VK_ADD:
			code = '+';
			imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
			break;
		case VK_SUBTRACT:
			code = '-';
			imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
			break;
		case VK_MULTIPLY:
			code = '*';
			imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
			break;
		case VK_DIVIDE:
			code = '/';
			imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
			break;

		case VK_F1: case VK_F2: case VK_F3: case VK_F4:
		case VK_F5: case VK_F6: case VK_F7: case VK_F8:
		case VK_F9: case VK_F10: case VK_F11: case VK_F12:
			code = (TUINT) (code - VK_F1) + TKEYC_F1;
			break;
		default:
			numchars = ToUnicode(code, 0, win->fbv_KeyState,
				buff, 2, 0);
			if (numchars > 0)
				code = buff[0];
	}

	if ((win->fbv_InputMask & type) &&
		fb_getimsg(mod, win, &imsg, type))
	{
		ptrdiff_t len;
		imsg->timsg_Code = code;
		len = (ptrdiff_t)
			utf8encode(imsg->timsg_KeyCode, imsg->timsg_Code) -
			(ptrdiff_t) imsg->timsg_KeyCode;
		imsg->timsg_KeyCode[len] = 0;
		fb_sendimsg(mod, win, imsg);
	}
}
Example #11
0
File: x11.c Project: aki5/libdraw3
/*
 *	drawevents2 calls flush to display anything that was drawn.
 */
static Input *
drawevents2(int block, int *ninp)
{
	static int flushing;

	if(!flushing){
		if(screen.dirty){
			drawflush(screen.r);
			flushing = 1;
			screen.dirty = 0;
		}
		ninputs = 0;
	}
	while((block && (flushing || ninputs == 0)) || XPending(display)){
		XEvent ev;
		XNextEvent(display, &ev);
		switch(ev.type){
		case MapNotify:
		case ReparentNotify:
			addredraw();
			continue;
		case Expose:
			addredraw();
			continue;
		case KeyPress:
		case KeyRelease:
			{
				XKeyEvent *ep = &ev.xkey;
				if(0)fprintf(
					stderr,
					"key %s %d (%x) '%c' at (%d,%d) state %x\n",
					ev.type == KeyPress ? "pressed" : "released",
					ep->keycode,
					ep->keycode,
					isprint(ep->keycode) ? ep->keycode : '.',
					ep->x, ep->y,
					ep->state
				);

				u64int mod;
				KeySym keysym;
				int code;
				char keystr[8] = {0};

				keysym = XLookupKeysym(ep, ep->state & (ShiftMask|LockMask));
				if((code = keysym2ucs(keysym)) != -1)
					utf8encode(keystr, sizeof keystr-1, code);
				else
					keystr[0] = '\0';

				switch(keysym){
				case XK_Return:
				case XK_KP_Enter:
					strncpy(keystr, "\n", sizeof keystr-1);
					mod = KeyStr;
					break;
				case XK_Tab:
				case XK_KP_Tab:
				case XK_ISO_Left_Tab:
					strncpy(keystr, "\t", sizeof keystr-1);
					mod = KeyStr;
					break;
				case XK_Break:
					mod = KeyBreak;
					break;
				case XK_BackSpace:
					mod = KeyBackSpace;
					break;
				case XK_Down:
					mod = KeyDown;
					break;
				case XK_End:
					mod = KeyEnd;
					break;
				case XK_Home:
					mod = KeyHome;
					break;
				case XK_Left:
					mod = KeyLeft;
					break;
				case XK_Page_Down:
					mod = KeyPageDown;
					break;
				case XK_Page_Up:
					mod = KeyPageUp;
					break;
				case XK_Right:
					mod = KeyRight;
					break;
				case XK_Up:
					mod = KeyUp;
					break;
				case XK_Shift_L:
				case XK_Shift_R:
					mod = KeyShift;
					break;
				case XK_Control_L:
				case XK_Control_R:
					mod = KeyControl;
					break;
				case XK_Meta_L:
				case XK_Meta_R: 
					mod = KeyMeta;	/* mac command key */
					break;
				case XK_Alt_L:
				case XK_Alt_R:
					mod = KeyAlt;
					break;
				case XK_Super_L:
				case XK_Super_R:
fprintf(stderr, "super\n");
					mod = KeySuper;
					break;
				case XK_Hyper_L:
				case XK_Hyper_R:
fprintf(stderr, "hyper\n");
					mod = KeyHyper;
					break;
				case XK_KP_Insert:
				case XK_Insert:
					mod = KeyIns;
					break;
				case XK_KP_Delete:
				case XK_Delete:
					mod = KeyDel;
					break;
				case XK_Caps_Lock:
					mod = KeyCapsLock;
					break;
				default:
					mod = 0;
					break;
				}

				addinput(
					0, 0,
					keystr,
					mod,
					ev.type == KeyPress,
					ev.type == KeyRelease
				);
			}
			continue;
		case ButtonPress:
		case ButtonRelease:
			{
				XButtonEvent *ep = &ev.xbutton;
				u64int mod;
				switch(ep->button){
				case 0:case 1:case 2:case 3:case 4:
				case 5:case 6:case 7:case 9:case 10:
					mod = Mouse0 << ep->button;
					break;
				default:
					fprintf(stderr, "unsupported mouse button %d\n", ep->button);
					mod = 0;
					break;
				}
				if(mod != 0){
					addinput(
						ep->x, ep->y,
						NULL,
						mod,
						ev.type == ButtonPress,
						ev.type == ButtonRelease
					);
				}
			}
			continue;	
		case EnterNotify:
		case LeaveNotify:
			fprintf(stderr, "enter/leave\n");
			continue;
		case MotionNotify:
			if(input_prevmod != 0){
				XMotionEvent *ep = &ev.xmotion;
				u64int m;
				if(0)fprintf(
					stderr,
					"motion at (%d,%d) state %x\n",
					ep->x, ep->y,
					ep->state
				);
				for(m = Mouse0; m <= LastMouse; m <<= 1){
					addinput(
						ep->x, ep->y,
						NULL,
						m,
						0,0
					);
				}
			}
			continue;
		case ConfigureNotify:
			{
				XConfigureEvent *ce = &ev.xconfigure;
				if(ce->width != width || ce->height != height){
					shmfree();
					width = ce->width;
					height = ce->height;
					if(shminit() == -1){
						*ninp = 0;
						return NULL;
					}
					addredraw();
				}
				continue;
			}
		}
		if(ev.type == XShmGetEventBase(display) + ShmCompletion){
			flushing = 0;
			if(animating){
				addredraw();
			}
			continue;
		}
		fprintf(stderr, "unknown xevent %d\n", ev.type);
	}

	if(!flushing && ninputs > 0){
		*ninp = ninputs;
		return inputs;
	}

	*ninp = 0;
	return NULL;
}
Example #12
0
/* Recode an iso encoded string to UTF-8 */
unsigned char* iso_decode(const unsigned char *iso, unsigned char *utf8,
                          int cp, int count)
{
    unsigned short ucs, tmp;

    if (cp == -1) /* use default codepage */
        cp = default_codepage;

    if (!load_cp_table(cp)) cp = 0;

    while (count--) {
        if (*iso < 128 || cp == UTF_8) /* Already UTF-8 */
            *utf8++ = *iso++;

        else {

            /* cp tells us which codepage to convert from */
            switch (cp) {
                case ISO_8859_7:  /* Greek */
                case WIN_1251:    /* Cyrillic */
                case ISO_8859_9:  /* Turkish */
                case ISO_8859_2:  /* Latin Extended */
                case WIN_1250:    /* Central European */
#ifdef HAVE_LCD_BITMAP
                case ISO_8859_8:  /* Hebrew */
                case ISO_8859_11: /* Thai */
                case WIN_1256:    /* Arabic */
#endif
                    tmp = ((cp-1)*128) + (*iso++ - 128);
                    ucs = codepage_table[tmp];
                    break;

#ifdef HAVE_LCD_BITMAP
                case SJIS: /* Japanese */
                    if (*iso > 0xA0 && *iso < 0xE0) {
                        tmp = *iso++ | (0xA100 - 0x8000);
                        ucs = codepage_table[tmp];
                        break;
                    }

                case GB_2312:  /* Simplified Chinese */
                case KSX_1001: /* Korean */
                case BIG_5:    /* Traditional Chinese */
                    if (count < 1 || !iso[1]) {
                        ucs = *iso++;
                        break;
                    }

                    /* we assume all cjk strings are written
                       in big endian order */
                    tmp = *iso++ << 8;
                    tmp |= *iso++;
                    tmp -= 0x8000;
                    ucs = codepage_table[tmp];
                    count--;
                    break;
#endif /* HAVE_LCD_BITMAP */

                default:
                    ucs = *iso++;
                    break;
            }

            if (ucs == 0) /* unknown char, use replacement char */
                ucs = 0xfffd;
            utf8 = utf8encode(ucs, utf8);
        }
    }
    return utf8;
}
Example #13
0
static TBOOL x11_processkey(struct X11Display *mod, struct X11Window *v,
	XKeyEvent *ev, TBOOL keydown)
{
	KeySym keysym;
	XComposeStatus compose;
	char buffer[10];

	TIMSG *imsg;
	TUINT evtype = 0;
	TUINT newqual;
	TUINT evmask = v->eventmask;
	TBOOL newkey = TFALSE;

	x11_setmousepos(mod, v, ev->x, ev->y);

	XLookupString(ev, buffer, 10, &keysym, &compose);

	switch (keysym)
	{
		case XK_Shift_L:
			newqual = TKEYQ_LSHIFT;
			break;
		case XK_Shift_R:
			newqual = TKEYQ_RSHIFT;
			break;
		case XK_Control_L:
			newqual = TKEYQ_LCTRL;
			break;
		case XK_Control_R:
			newqual = TKEYQ_RCTRL;
			break;
		case XK_Alt_L:
			newqual = TKEYQ_LALT;
			break;
		case XK_Alt_R:
			newqual = TKEYQ_RALT;
			break;
		default:
			newqual = 0;
	}

	if (newqual != 0)
	{
		if (keydown)
			mod->x11_KeyQual |= newqual;
		else
			mod->x11_KeyQual &= ~newqual;
	}

	if (keydown && (evmask & TITYPE_KEYDOWN))
		evtype = TITYPE_KEYDOWN;
	else if (!keydown && (evmask & TITYPE_KEYUP))
		evtype = TITYPE_KEYUP;

	if (evtype && x11_getimsg(mod, v, &imsg, evtype))
	{
		imsg->timsg_Qualifier = mod->x11_KeyQual;

		if (keysym >= XK_F1 && keysym <= XK_F12)
		{
			imsg->timsg_Code = (TUINT) (keysym - XK_F1) + TKEYC_F1;
			newkey = TTRUE;
		}
		else if (keysym < 256)
		{
			/* cooked ASCII/Latin-1 code */
			imsg->timsg_Code = keysym;
			newkey = TTRUE;
		}
		else if (keysym >= XK_KP_0 && keysym <= XK_KP_9)
		{
			imsg->timsg_Code = (TUINT) (keysym - XK_KP_0) + 48;
			imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
			newkey = TTRUE;
		}
		else
		{
			newkey = TTRUE;
			switch (keysym)
			{
				case XK_Left:
					imsg->timsg_Code = TKEYC_CRSRLEFT;
					break;
				case XK_Right:
					imsg->timsg_Code = TKEYC_CRSRRIGHT;
					break;
				case XK_Up:
					imsg->timsg_Code = TKEYC_CRSRUP;
					break;
				case XK_Down:
					imsg->timsg_Code = TKEYC_CRSRDOWN;
					break;

				case XK_Escape:
					imsg->timsg_Code = TKEYC_ESC;
					break;
				case XK_Delete:
					imsg->timsg_Code = TKEYC_DEL;
					break;
				case XK_BackSpace:
					imsg->timsg_Code = TKEYC_BCKSPC;
					break;
				case XK_ISO_Left_Tab:
				case XK_Tab:
					imsg->timsg_Code = TKEYC_TAB;
					break;
				case XK_Return:
					imsg->timsg_Code = TKEYC_RETURN;
					break;

				case XK_Help:
					imsg->timsg_Code = TKEYC_HELP;
					break;
				case XK_Insert:
					imsg->timsg_Code = TKEYC_INSERT;
					break;
				case XK_Page_Up:
					imsg->timsg_Code = TKEYC_PAGEUP;
					break;
				case XK_Page_Down:
					imsg->timsg_Code = TKEYC_PAGEDOWN;
					break;
				case XK_Home:
					imsg->timsg_Code = TKEYC_POSONE;
					break;
				case XK_End:
					imsg->timsg_Code = TKEYC_POSEND;
					break;
				case XK_Print:
					imsg->timsg_Code = TKEYC_PRINT;
					break;
				case XK_Scroll_Lock:
					imsg->timsg_Code = TKEYC_SCROLL;
					break;
				case XK_Pause:
					imsg->timsg_Code = TKEYC_PAUSE;
					break;
				case XK_KP_Enter:
					imsg->timsg_Code = TKEYC_RETURN;
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				case XK_KP_Decimal:
					imsg->timsg_Code = '.';
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				case XK_KP_Add:
					imsg->timsg_Code = '+';
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				case XK_KP_Subtract:
					imsg->timsg_Code = '-';
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				case XK_KP_Multiply:
					imsg->timsg_Code = '*';
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				case XK_KP_Divide:
					imsg->timsg_Code = '/';
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				default:
					if (keysym > 31 && keysym <= 0x20ff)
						imsg->timsg_Code = keysym;
					else if (keysym >= 0x01000100 && keysym <= 0x0110ffff)
						imsg->timsg_Code = keysym - 0x01000000;
					else
						newkey = TFALSE;
					break;
			}
		}

		if (!newkey && newqual)
		{
			imsg->timsg_Code = TKEYC_NONE;
			newkey = TTRUE;
		}

		if (newkey)
		{
			ptrdiff_t len =
				(ptrdiff_t) utf8encode(imsg->timsg_KeyCode, imsg->timsg_Code) -
				(ptrdiff_t) imsg->timsg_KeyCode;
			imsg->timsg_KeyCode[len] = 0;
			TAddTail(&v->imsgqueue, &imsg->timsg_Node);
		}
		else
		{
			/* put back message: */
			TAddTail(&mod->x11_imsgpool, &imsg->timsg_Node);
		}
	}

	return newkey;
}