void usb_keyboard_write_unicode(uint16_t cpoint)
{
	KEYCODE_TYPE keycode;

	keycode = unicode_to_keycode(cpoint);
	if (keycode) {
		#ifdef DEADKEYS_MASK
		KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode);
		if (deadkeycode) write_key(deadkeycode);
		#endif
		write_key(keycode);
	}
}
void usb_keyboard_press_keycode(uint16_t n)
{
	uint8_t key, mod, msb, modrestore=0;
	KEYCODE_TYPE keycode;
	#ifdef DEADKEYS_MASK
	KEYCODE_TYPE deadkeycode;
	#endif

	msb = n >> 8;
	if (msb >= 0xC2 && msb <= 0xDF) {
		n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
	} else
	if (msb == 0x80) {
		usb_keyboard_press_key(0, n);
		return;
	} else
	if (msb == 0x40) {
		usb_keyboard_press_key(n, 0);
		return;
	}
	keycode = unicode_to_keycode(n);
	if (!keycode) return;
	#ifdef DEADKEYS_MASK
	deadkeycode = deadkey_to_keycode(keycode);
	if (deadkeycode) {
		modrestore = keyboard_modifier_keys;
		if (modrestore) {
			keyboard_modifier_keys = 0;
			usb_keyboard_send();
		}
		// TODO: test if operating systems recognize
		// deadkey sequences when other keys are held
		mod = keycode_to_modifier(deadkeycode);
		key = keycode_to_key(deadkeycode);
		usb_keyboard_press_key(key, mod);
		usb_keyboard_release_key(key, mod);
	}
	#endif
	mod = keycode_to_modifier(keycode);
	key = keycode_to_key(keycode);
	usb_keyboard_press_key(key, mod | modrestore);
}
void usb_keyboard_class::release(uint16_t n)
{
	uint8_t key, mod, msb;

	msb = n >> 8;
	if (msb >= 0xC2 && msb <= 0xDF) {
		n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
	} else
	if (msb == 0x80) {
		releasekey(0, n);
		return;
	} else
	if (msb == 0x40) {
		releasekey(n, 0);
		return;
	}
	KEYCODE_TYPE keycode = unicode_to_keycode(n);
	if (!keycode) return;
	mod = keycode_to_modifier(keycode);
	key = keycode_to_key(keycode);
	releasekey(key, mod);
}