APPROVE COMMIT
NOTE: This patch has been committed
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1513634686 0
# Mon Dec 18 22:04:46 2017 +0000
# Node ID a5b21ebab055b2b74f16e61d09c57d88d268a74c
# Parent 9bdc40b8fb78fe1b9605e4e5129b4002b3a9835a
Split out stuff that has become X- or GTK-specific, post GTK-1.2.
src/ChangeLog addition:
2017-12-18 Aidan Kehoe <kehoea(a)parhasard.net>
* event-Xt.c:
* event-Xt.c (USE_UNICODE_MAP):
Add support for Hangul, Armenian, Georgian, Azeri, Vietnamese
support here.
Merge the unicode-internal changes into this file.
* event-Xt.c (x_keysym_to_character):
As above.
* event-xlike-inc.c:
Move the Hangule, Armenian, Georgian, Azeri, Vietnamese support in
here.
* redisplay-gtk.c:
* redisplay-x.c:
* redisplay-x.c (separate_textual_runs_nomule):
* redisplay-x.c (separate_textual_runs_xft_nomule):
* redisplay-x.c (separate_textual_runs_xft_mule):
* redisplay-x.c (separate_textual_runs_mule):
* redisplay-x.c (x_text_width_single_run):
* redisplay-x.c (x_text_width):
* redisplay-x.c (x_window_output_begin):
* redisplay-x.c (x_window_output_end):
* redisplay-x.c (x_clear_region):
* redisplay-x.c (x_clear_frame):
* redisplay-x.c (x_bevel_area):
* redisplay-x.c (x_output_horizontal_line):
* redisplay-x.c (x_output_vertical_divider):
* redisplay-x.c (x_ring_bell):
* redisplay-x.c (x_flash):
* redisplay-x.c (x_output_blank):
* redisplay-x.c (x_output_eol_cursor):
* redisplay-x.c (x_output_xlike_pixmap):
* redisplay-x.c (x_output_string):
Move all the X-specific stuff here from redisplay-xlike-inc.c,
since it is no longer helpful on GTK with the end of support for
GTK 1.0.
* redisplay-xlike-inc.c:
Delete all the newly-X-specific stuff from here.
diff -r 9bdc40b8fb78 -r a5b21ebab055 src/ChangeLog
--- a/src/ChangeLog Sun Dec 17 12:20:06 2017 +0000
+++ b/src/ChangeLog Mon Dec 18 22:04:46 2017 +0000
@@ -1,3 +1,42 @@
+2017-12-18 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * event-Xt.c:
+ * event-Xt.c (USE_UNICODE_MAP):
+ Add support for Hangul, Armenian, Georgian, Azeri, Vietnamese
+ support here.
+ Merge the unicode-internal changes into this file.
+ * event-Xt.c (x_keysym_to_character):
+ As above.
+ * event-xlike-inc.c:
+ Move the Hangule, Armenian, Georgian, Azeri, Vietnamese support in
+ here.
+ * redisplay-gtk.c:
+ * redisplay-x.c:
+ * redisplay-x.c (separate_textual_runs_nomule):
+ * redisplay-x.c (separate_textual_runs_xft_nomule):
+ * redisplay-x.c (separate_textual_runs_xft_mule):
+ * redisplay-x.c (separate_textual_runs_mule):
+ * redisplay-x.c (x_text_width_single_run):
+ * redisplay-x.c (x_text_width):
+ * redisplay-x.c (x_window_output_begin):
+ * redisplay-x.c (x_window_output_end):
+ * redisplay-x.c (x_clear_region):
+ * redisplay-x.c (x_clear_frame):
+ * redisplay-x.c (x_bevel_area):
+ * redisplay-x.c (x_output_horizontal_line):
+ * redisplay-x.c (x_output_vertical_divider):
+ * redisplay-x.c (x_ring_bell):
+ * redisplay-x.c (x_flash):
+ * redisplay-x.c (x_output_blank):
+ * redisplay-x.c (x_output_eol_cursor):
+ * redisplay-x.c (x_output_xlike_pixmap):
+ * redisplay-x.c (x_output_string):
+ Move all the X-specific stuff here from redisplay-xlike-inc.c,
+ since it is no longer helpful on GTK with the end of support for
+ GTK 1.0.
+ * redisplay-xlike-inc.c:
+ Delete all the newly-X-specific stuff from here.
+
2017-12-17 Aidan Kehoe <kehoea(a)parhasard.net>
* console-gtk.c (gtk_perhaps_init_unseen_key_defaults):
diff -r 9bdc40b8fb78 -r a5b21ebab055 src/event-Xt.c
--- a/src/event-Xt.c Sun Dec 17 12:20:06 2017 +0000
+++ b/src/event-Xt.c Mon Dec 18 22:04:46 2017 +0000
@@ -147,7 +147,13 @@
&& map[keysym - FIRST_KNOWN_##map ]) do \
{ \
keysym -= FIRST_KNOWN_##map ; \
- return Funicode_to_char (make_fixnum (map[keysym]), Qnil); \
+ return make_char (buffer_unicode_to_ichar ((int) map[keysym], \
+ /* @@#### need to get some sort \
+ of buffer to compute this off; \
+ only applies in the old-Mule \
+ world */ \
+ current_buffer, \
+ CONVERR_SUCCEED)); \
} while (0)
/* Maps to Unicode for X11 KeySyms, where we don't have a direct internal
@@ -155,11 +161,7 @@
Kuhn's X11.keysyms--if you're ever comparing with that file, note the
sequences of KeySyms often leave out entries, so you'll have to fill them
in. Doesn't include support for Hangul, which it should, if the X11
- Hangul keysyms have ever been used anywhere.
-
- I'm not #ifdef'ing this based on wheter MULE is defined, because it's a
- matter of 324 bytes in a stripped executable, and I want the
- testing. :-P */
+ Hangul keysyms have ever been used anywhere. */
static UINT_16_BIT const TECHNICAL[] =
{
@@ -433,6 +435,444 @@
0x22A3, /* #x0BFC RIGHT TACK APL */
};
+static UINT_16_BIT const HANGUL[] =
+ {
+#define FIRST_KNOWN_HANGUL 0xEA1
+ 0x3131, /* #x0EA1 Hangul_Kiyeog */
+ 0x3132, /* #x0EA2 Hangul_SsangKiyeog */
+ 0x3133, /* #x0EA3 Hangul_KiyeogSios */
+ 0x3134, /* #x0EA4 Hangul_Nieun */
+ 0x3135, /* #x0EA5 Hangul_NieunJieuj */
+ 0x3136, /* #x0EA6 Hangul_NieunHieuh */
+ 0x3137, /* #x0EA7 Hangul_Dikeud */
+ 0x3138, /* #x0EA8 Hangul_SsangDikeud */
+ 0x3139, /* #x0EA9 Hangul_Rieul */
+ 0x313a, /* #x0EAA Hangul_RieulKiyeog */
+ 0x313b, /* #x0EAB Hangul_RieulMieum */
+ 0x313c, /* #x0EAC Hangul_RieulPieub */
+ 0x313d, /* #x0EAD Hangul_RieulSios */
+ 0x313e, /* #x0EAE Hangul_RieulTieut */
+ 0x313f, /* #x0EAF Hangul_RieulPhieuf */
+ 0x3140, /* #x0EB0 Hangul_RieulHieuh */
+ 0x3141, /* #x0EB1 Hangul_Mieum */
+ 0x3142, /* #x0EB2 Hangul_Pieub */
+ 0x3143, /* #x0EB3 Hangul_SsangPieub */
+ 0x3144, /* #x0EB4 Hangul_PieubSios */
+ 0x3145, /* #x0EB5 Hangul_Sios */
+ 0x3146, /* #x0EB6 Hangul_SsangSios */
+ 0x3147, /* #x0EB7 Hangul_Ieung */
+ 0x3148, /* #x0EB8 Hangul_Jieuj */
+ 0x3149, /* #x0EB9 Hangul_SsangJieuj */
+ 0x314a, /* #x0EBA Hangul_Cieuc */
+ 0x314b, /* #x0EBB Hangul_Khieuq */
+ 0x314c, /* #x0EBC Hangul_Tieut */
+ 0x314d, /* #x0EBD Hangul_Phieuf */
+ 0x314e, /* #x0EBE Hangul_Hieuh */
+ 0x314f, /* #x0EBF Hangul_A */
+ 0x3150, /* #x0EC0 Hangul_AE */
+ 0x3151, /* #x0EC1 Hangul_YA */
+ 0x3152, /* #x0EC2 Hangul_YAE */
+ 0x3153, /* #x0EC3 Hangul_EO */
+ 0x3154, /* #x0EC4 Hangul_E */
+ 0x3155, /* #x0EC5 Hangul_YEO */
+ 0x3156, /* #x0EC6 Hangul_YE */
+ 0x3157, /* #x0EC7 Hangul_O */
+ 0x3158, /* #x0EC8 Hangul_WA */
+ 0x3159, /* #x0EC9 Hangul_WAE */
+ 0x315a, /* #x0ECA Hangul_OE */
+ 0x315b, /* #x0ECB Hangul_YO */
+ 0x315c, /* #x0ECC Hangul_U */
+ 0x315d, /* #x0ECD Hangul_WEO */
+ 0x315e, /* #x0ECE Hangul_WE */
+ 0x315f, /* #x0ECF Hangul_WI */
+ 0x3160, /* #x0ED0 Hangul_YU */
+ 0x3161, /* #x0ED1 Hangul_EU */
+ 0x3162, /* #x0ED2 Hangul_YI */
+ 0x3163, /* #x0ED3 Hangul_I */
+ 0x11a8, /* #x0ED4 Hangul_J_Kiyeog */
+ 0x11a9, /* #x0ED5 Hangul_J_SsangKiyeog */
+ 0x11aa, /* #x0ED6 Hangul_J_KiyeogSios */
+ 0x11ab, /* #x0ED7 Hangul_J_Nieun */
+ 0x11ac, /* #x0ED8 Hangul_J_NieunJieuj */
+ 0x11ad, /* #x0ED9 Hangul_J_NieunHieuh */
+ 0x11ae, /* #x0EDA Hangul_J_Dikeud */
+ 0x11af, /* #x0EDB Hangul_J_Rieul */
+ 0x11b0, /* #x0EDC Hangul_J_RieulKiyeog */
+ 0x11b1, /* #x0EDD Hangul_J_RieulMieum */
+ 0x11b2, /* #x0EDE Hangul_J_RieulPieub */
+ 0x11b3, /* #x0EDF Hangul_J_RieulSios */
+ 0x11b4, /* #x0EE0 Hangul_J_RieulTieut */
+ 0x11b5, /* #x0EE1 Hangul_J_RieulPhieuf */
+ 0x11b6, /* #x0EE2 Hangul_J_RieulHieuh */
+ 0x11b7, /* #x0EE3 Hangul_J_Mieum */
+ 0x11b8, /* #x0EE4 Hangul_J_Pieub */
+ 0x11b9, /* #x0EE5 Hangul_J_PieubSios */
+ 0x11ba, /* #x0EE6 Hangul_J_Sios */
+ 0x11bb, /* #x0EE7 Hangul_J_SsangSios */
+ 0x11bc, /* #x0EE8 Hangul_J_Ieung */
+ 0x11bd, /* #x0EE9 Hangul_J_Jieuj */
+ 0x11be, /* #x0EEA Hangul_J_Cieuc */
+ 0x11bf, /* #x0EEB Hangul_J_Khieuq */
+ 0x11c0, /* #x0EEC Hangul_J_Tieut */
+ 0x11c1, /* #x0EED Hangul_J_Phieuf */
+ 0x11c2, /* #x0EEE Hangul_J_Hieuh */
+ 0x316d, /* #x0EEF Hangul_RieulYeorinHieuh */
+ 0x3171, /* #x0EF0 Hangul_SunkyeongeumMieum */
+ 0x3178, /* #x0EF1 Hangul_SunkyeongeumPieub */
+ 0x317f, /* #x0EF2 Hangul_PanSios */
+ 0x3181, /* #x0EF3 Hangul_KkogjiDalrinIeung */
+ 0x3184, /* #x0EF4 Hangul_SunkyeongeumPhieuf */
+ 0x3186, /* #x0EF5 Hangul_YeorinHieuh */
+ 0x318d, /* #x0EF6 Hangul_AraeA */
+ 0x318e, /* #x0EF7 Hangul_AraeAE */
+ 0x11eb, /* #x0EF8 Hangul_J_PanSios */
+ 0x11f0, /* #x0EF9 Hangul_J_KkogjiDalrinIeung */
+ 0x11f9, /* #x0EFA Hangul_J_YeorinHieuh */
+ 0x0000, /* #x0EFB */
+ 0x0000, /* #x0EFC */
+ 0x0000, /* #x0EFD */
+ 0x0000, /* #x0EFE */
+ 0x20a9, /* #x0EFF Korean_Won */
+ };
+
+static UINT_16_BIT const ARMENIAN[] =
+ {
+#define FIRST_KNOWN_ARMENIAN 0x14A1
+ 0x0000, /* #x14A1 Armenian_eternity */
+ 0x0587, /* #x14A2 Armenian_ligature_ew */
+ 0x0589, /* #x14A3 Armenian_verjaket */
+ 0x0029, /* #x14A4 Armenian_parenright */
+ 0x0028, /* #x14A5 Armenian_parenleft */
+ 0x00bb, /* #x14A6 Armenian_guillemotright */
+ 0x00ab, /* #x14A7 Armenian_guillemotleft */
+ 0x2014, /* #x14A8 Armenian_em_dash */
+ 0x002e, /* #x14A9 Armenian_mijaket */
+ 0x055d, /* #x14AA Armenian_but */
+ 0x002c, /* #x14AB Armenian_comma */
+ 0x2013, /* #x14AC Armenian_en_dash */
+ 0x058a, /* #x14AD Armenian_yentamna */
+ 0x2026, /* #x14AE Armenian_ellipsis */
+ 0x055c, /* #x14AF Armenian_amanak */
+ 0x055b, /* #x14B0 Armenian_shesht */
+ 0x055e, /* #x14B1 Armenian_paruyk */
+ 0x0531, /* #x14B2 Armenian_AYB */
+ 0x0561, /* #x14B3 Armenian_ayb */
+ 0x0532, /* #x14B4 Armenian_BEN */
+ 0x0562, /* #x14B5 Armenian_ben */
+ 0x0533, /* #x14B6 Armenian_GIM */
+ 0x0563, /* #x14B7 Armenian_gim */
+ 0x0534, /* #x14B8 Armenian_DA */
+ 0x0564, /* #x14B9 Armenian_da */
+ 0x0535, /* #x14BA Armenian_YECH */
+ 0x0565, /* #x14BB Armenian_yech */
+ 0x0536, /* #x14BC Armenian_ZA */
+ 0x0566, /* #x14BD Armenian_za */
+ 0x0537, /* #x14BE Armenian_E */
+ 0x0567, /* #x14BF Armenian_e */
+ 0x0538, /* #x14C0 Armenian_AT */
+ 0x0568, /* #x14C1 Armenian_at */
+ 0x0539, /* #x14C2 Armenian_TO */
+ 0x0569, /* #x14C3 Armenian_to */
+ 0x053a, /* #x14C4 Armenian_ZHE */
+ 0x056a, /* #x14C5 Armenian_zhe */
+ 0x053b, /* #x14C6 Armenian_INI */
+ 0x056b, /* #x14C7 Armenian_ini */
+ 0x053c, /* #x14C8 Armenian_LYUN */
+ 0x056c, /* #x14C9 Armenian_lyun */
+ 0x053d, /* #x14CA Armenian_KHE */
+ 0x056d, /* #x14CB Armenian_khe */
+ 0x053e, /* #x14CC Armenian_TSA */
+ 0x056e, /* #x14CD Armenian_tsa */
+ 0x053f, /* #x14CE Armenian_KEN */
+ 0x056f, /* #x14CF Armenian_ken */
+ 0x0540, /* #x14D0 Armenian_HO */
+ 0x0570, /* #x14D1 Armenian_ho */
+ 0x0541, /* #x14D2 Armenian_DZA */
+ 0x0571, /* #x14D3 Armenian_dza */
+ 0x0542, /* #x14D4 Armenian_GHAT */
+ 0x0572, /* #x14D5 Armenian_ghat */
+ 0x0543, /* #x14D6 Armenian_TCHE */
+ 0x0573, /* #x14D7 Armenian_tche */
+ 0x0544, /* #x14D8 Armenian_MEN */
+ 0x0574, /* #x14D9 Armenian_men */
+ 0x0545, /* #x14DA Armenian_HI */
+ 0x0575, /* #x14DB Armenian_hi */
+ 0x0546, /* #x14DC Armenian_NU */
+ 0x0576, /* #x14DD Armenian_nu */
+ 0x0547, /* #x14DE Armenian_SHA */
+ 0x0577, /* #x14DF Armenian_sha */
+ 0x0548, /* #x14E0 Armenian_VO */
+ 0x0578, /* #x14E1 Armenian_vo */
+ 0x0549, /* #x14E2 Armenian_CHA */
+ 0x0579, /* #x14E3 Armenian_cha */
+ 0x054a, /* #x14E4 Armenian_PE */
+ 0x057a, /* #x14E5 Armenian_pe */
+ 0x054b, /* #x14E6 Armenian_JE */
+ 0x057b, /* #x14E7 Armenian_je */
+ 0x054c, /* #x14E8 Armenian_RA */
+ 0x057c, /* #x14E9 Armenian_ra */
+ 0x054d, /* #x14EA Armenian_SE */
+ 0x057d, /* #x14EB Armenian_se */
+ 0x054e, /* #x14EC Armenian_VEV */
+ 0x057e, /* #x14ED Armenian_vev */
+ 0x054f, /* #x14EE Armenian_TYUN */
+ 0x057f, /* #x14EF Armenian_tyun */
+ 0x0550, /* #x14F0 Armenian_RE */
+ 0x0580, /* #x14F1 Armenian_re */
+ 0x0551, /* #x14F2 Armenian_TSO */
+ 0x0581, /* #x14F3 Armenian_tso */
+ 0x0552, /* #x14F4 Armenian_VYUN */
+ 0x0582, /* #x14F5 Armenian_vyun */
+ 0x0553, /* #x14F6 Armenian_PYUR */
+ 0x0583, /* #x14F7 Armenian_pyur */
+ 0x0554, /* #x14F8 Armenian_KE */
+ 0x0584, /* #x14F9 Armenian_ke */
+ 0x0555, /* #x14FA Armenian_O */
+ 0x0585, /* #x14FB Armenian_o */
+ 0x0556, /* #x14FC Armenian_FE */
+ 0x0586, /* #x14FD Armenian_fe */
+ 0x055a, /* #x14FE Armenian_apostrophe */
+ 0x00a7, /* #x14FF Armenian_section_sign */
+ };
+
+static UINT_16_BIT const GEORGIAN[] =
+ {
+#define FIRST_KNOWN_GEORGIAN 0x15D0
+ 0x10d0, /* #x15D0 Georgian_an */
+ 0x10d1, /* #x15D1 Georgian_ban */
+ 0x10d2, /* #x15D2 Georgian_gan */
+ 0x10d3, /* #x15D3 Georgian_don */
+ 0x10d4, /* #x15D4 Georgian_en */
+ 0x10d5, /* #x15D5 Georgian_vin */
+ 0x10d6, /* #x15D6 Georgian_zen */
+ 0x10d7, /* #x15D7 Georgian_tan */
+ 0x10d8, /* #x15D8 Georgian_in */
+ 0x10d9, /* #x15D9 Georgian_kan */
+ 0x10da, /* #x15DA Georgian_las */
+ 0x10db, /* #x15DB Georgian_man */
+ 0x10dc, /* #x15DC Georgian_nar */
+ 0x10dd, /* #x15DD Georgian_on */
+ 0x10de, /* #x15DE Georgian_par */
+ 0x10df, /* #x15DF Georgian_zhar */
+ 0x10e0, /* #x15E0 Georgian_rae */
+ 0x10e1, /* #x15E1 Georgian_san */
+ 0x10e2, /* #x15E2 Georgian_tar */
+ 0x10e3, /* #x15E3 Georgian_un */
+ 0x10e4, /* #x15E4 Georgian_phar */
+ 0x10e5, /* #x15E5 Georgian_khar */
+ 0x10e6, /* #x15E6 Georgian_ghan */
+ 0x10e7, /* #x15E7 Georgian_qar */
+ 0x10e8, /* #x15E8 Georgian_shin */
+ 0x10e9, /* #x15E9 Georgian_chin */
+ 0x10ea, /* #x15EA Georgian_can */
+ 0x10eb, /* #x15EB Georgian_jil */
+ 0x10ec, /* #x15EC Georgian_cil */
+ 0x10ed, /* #x15ED Georgian_char */
+ 0x10ee, /* #x15EE Georgian_xan */
+ 0x10ef, /* #x15EF Georgian_jhan */
+ 0x10f0, /* #x15F0 Georgian_hae */
+ 0x10f1, /* #x15F1 Georgian_he */
+ 0x10f2, /* #x15F2 Georgian_hie */
+ 0x10f3, /* #x15F3 Georgian_we */
+ 0x10f4, /* #x15F4 Georgian_har */
+ 0x10f5, /* #x15F5 Georgian_hoe */
+ 0x10f6, /* #x15F6 Georgian_fi */
+ };
+
+static UINT_16_BIT const AZERI_ETC[] =
+ {
+#define FIRST_KNOWN_AZERI_ETC 0x16A2
+ 0x0000, /* #x16A2 Ccedillaabovedot */
+ 0x1e8a, /* #x16A3 Xabovedot */
+ 0x0000, /* #x16A4 */
+ 0x0000, /* #x16A5 Qabovedot */
+ 0x012c, /* #x16A6 Ibreve */
+ 0x0000, /* #x16A7 IE */
+ 0x0000, /* #x16A8 UO */
+ 0x01b5, /* #x16A9 Zstroke */
+ 0x01e6, /* #x16AA Gcaron */
+ 0x0000, /* #x16AB */
+ 0x0000, /* #x16AC */
+ 0x0000, /* #x16AD */
+ 0x0000, /* #x16AE */
+ 0x019f, /* #x16AF Obarred */
+ 0x0000, /* #x16B0 */
+ 0x0000, /* #x16B1 */
+ 0x0000, /* #x16B2 ccedillaabovedot */
+ 0x1e8b, /* #x16B3 xabovedot */
+ 0x0000, /* #x16B4 Ocaron */
+ 0x0000, /* #x16B5 qabovedot */
+ 0x012d, /* #x16B6 ibreve */
+ 0x0000, /* #x16B7 ie */
+ 0x0000, /* #x16B8 uo */
+ 0x01b6, /* #x16B9 zstroke */
+ 0x01e7, /* #x16BA gcaron */
+ 0x0000, /* #x16BB */
+ 0x0000, /* #x16BC */
+ 0x01d2, /* #x16BD ocaron */
+ 0x0000, /* #x16BE */
+ 0x0275, /* #x16BF obarred */
+ 0x0000, /* #x16C0 */
+ 0x0000, /* #x16C1 */
+ 0x0000, /* #x16C2 */
+ 0x0000, /* #x16C3 */
+ 0x0000, /* #x16C4 */
+ 0x0000, /* #x16C5 */
+ 0x018f, /* #x16C6 SCHWA */
+ 0x0000, /* #x16C7 */
+ 0x0000, /* #x16C8 */
+ 0x0000, /* #x16C9 */
+ 0x0000, /* #x16CA */
+ 0x0000, /* #x16CB */
+ 0x0000, /* #x16CC */
+ 0x0000, /* #x16CD */
+ 0x0000, /* #x16CE */
+ 0x0000, /* #x16CF */
+ 0x0000, /* #x16D0 */
+ 0x1e36, /* #x16D1 Lbelowdot */
+ 0x0000, /* #x16D2 Lstrokebelowdot */
+ 0x0000, /* #x16D3 Gtilde */
+ 0x0000, /* #x16D4 */
+ 0x0000, /* #x16D5 */
+ 0x0000, /* #x16D6 */
+ 0x0000, /* #x16D7 */
+ 0x0000, /* #x16D8 */
+ 0x0000, /* #x16D9 */
+ 0x0000, /* #x16DA */
+ 0x0000, /* #x16DB */
+ 0x0000, /* #x16DC */
+ 0x0000, /* #x16DD */
+ 0x0000, /* #x16DE */
+ 0x0000, /* #x16DF */
+ 0x0000, /* #x16E0 */
+ 0x1e37, /* #x16E1 lbelowdot */
+ 0x0000, /* #x16E2 lstrokebelowdot */
+ 0x0000, /* #x16E3 gtilde */
+ 0x0000, /* #x16E4 */
+ 0x0000, /* #x16E5 */
+ 0x0000, /* #x16E6 */
+ 0x0000, /* #x16E7 */
+ 0x0000, /* #x16E8 */
+ 0x0000, /* #x16E9 */
+ 0x0000, /* #x16EA */
+ 0x0000, /* #x16EB */
+ 0x0000, /* #x16EC */
+ 0x0000, /* #x16ED */
+ 0x0000, /* #x16EE */
+ 0x0000, /* #x16EF */
+ 0x0000, /* #x16F0 */
+ 0x0000, /* #x16F1 */
+ 0x0000, /* #x16F2 */
+ 0x0000, /* #x16F3 */
+ 0x0000, /* #x16F4 */
+ 0x0000, /* #x16F5 */
+ 0x0259, /* #x16F6 schwa */
+ };
+
+static UINT_16_BIT const VIETNAMESE[] =
+ {
+#define FIRST_KNOWN_VIETNAMESE 0x1E9F
+ 0x0303, /* #x1E9F combining_tilde */
+ 0x1ea0, /* #x1EA0 Abelowdot */
+ 0x1ea1, /* #x1EA1 abelowdot */
+ 0x1ea2, /* #x1EA2 Ahook */
+ 0x1ea3, /* #x1EA3 ahook */
+ 0x1ea4, /* #x1EA4 Acircumflexacute */
+ 0x1ea5, /* #x1EA5 acircumflexacute */
+ 0x1ea6, /* #x1EA6 Acircumflexgrave */
+ 0x1ea7, /* #x1EA7 acircumflexgrave */
+ 0x1ea8, /* #x1EA8 Acircumflexhook */
+ 0x1ea9, /* #x1EA9 acircumflexhook */
+ 0x1eaa, /* #x1EAA Acircumflextilde */
+ 0x1eab, /* #x1EAB acircumflextilde */
+ 0x1eac, /* #x1EAC Acircumflexbelowdot */
+ 0x1ead, /* #x1EAD acircumflexbelowdot */
+ 0x1eae, /* #x1EAE Abreveacute */
+ 0x1eaf, /* #x1EAF abreveacute */
+ 0x1eb0, /* #x1EB0 Abrevegrave */
+ 0x1eb1, /* #x1EB1 abrevegrave */
+ 0x1eb2, /* #x1EB2 Abrevehook */
+ 0x1eb3, /* #x1EB3 abrevehook */
+ 0x1eb4, /* #x1EB4 Abrevetilde */
+ 0x1eb5, /* #x1EB5 abrevetilde */
+ 0x1eb6, /* #x1EB6 Abrevebelowdot */
+ 0x1eb7, /* #x1EB7 abrevebelowdot */
+ 0x1eb8, /* #x1EB8 Ebelowdot */
+ 0x1eb9, /* #x1EB9 ebelowdot */
+ 0x1eba, /* #x1EBA Ehook */
+ 0x1ebb, /* #x1EBB ehook */
+ 0x1ebc, /* #x1EBC Etilde */
+ 0x1ebd, /* #x1EBD etilde */
+ 0x1ebe, /* #x1EBE Ecircumflexacute */
+ 0x1ebf, /* #x1EBF ecircumflexacute */
+ 0x1ec0, /* #x1EC0 Ecircumflexgrave */
+ 0x1ec1, /* #x1EC1 ecircumflexgrave */
+ 0x1ec2, /* #x1EC2 Ecircumflexhook */
+ 0x1ec3, /* #x1EC3 ecircumflexhook */
+ 0x1ec4, /* #x1EC4 Ecircumflextilde */
+ 0x1ec5, /* #x1EC5 ecircumflextilde */
+ 0x1ec6, /* #x1EC6 Ecircumflexbelowdot */
+ 0x1ec7, /* #x1EC7 ecircumflexbelowdot */
+ 0x1ec8, /* #x1EC8 Ihook */
+ 0x1ec9, /* #x1EC9 ihook */
+ 0x1eca, /* #x1ECA Ibelowdot */
+ 0x1ecb, /* #x1ECB ibelowdot */
+ 0x1ecc, /* #x1ECC Obelowdot */
+ 0x1ecd, /* #x1ECD obelowdot */
+ 0x1ece, /* #x1ECE Ohook */
+ 0x1ecf, /* #x1ECF ohook */
+ 0x1ed0, /* #x1ED0 Ocircumflexacute */
+ 0x1ed1, /* #x1ED1 ocircumflexacute */
+ 0x1ed2, /* #x1ED2 Ocircumflexgrave */
+ 0x1ed3, /* #x1ED3 ocircumflexgrave */
+ 0x1ed4, /* #x1ED4 Ocircumflexhook */
+ 0x1ed5, /* #x1ED5 ocircumflexhook */
+ 0x1ed6, /* #x1ED6 Ocircumflextilde */
+ 0x1ed7, /* #x1ED7 ocircumflextilde */
+ 0x1ed8, /* #x1ED8 Ocircumflexbelowdot */
+ 0x1ed9, /* #x1ED9 ocircumflexbelowdot */
+ 0x1eda, /* #x1EDA Ohornacute */
+ 0x1edb, /* #x1EDB ohornacute */
+ 0x1edc, /* #x1EDC Ohorngrave */
+ 0x1edd, /* #x1EDD ohorngrave */
+ 0x1ede, /* #x1EDE Ohornhook */
+ 0x1edf, /* #x1EDF ohornhook */
+ 0x1ee0, /* #x1EE0 Ohorntilde */
+ 0x1ee1, /* #x1EE1 ohorntilde */
+ 0x1ee2, /* #x1EE2 Ohornbelowdot */
+ 0x1ee3, /* #x1EE3 ohornbelowdot */
+ 0x1ee4, /* #x1EE4 Ubelowdot */
+ 0x1ee5, /* #x1EE5 ubelowdot */
+ 0x1ee6, /* #x1EE6 Uhook */
+ 0x1ee7, /* #x1EE7 uhook */
+ 0x1ee8, /* #x1EE8 Uhornacute */
+ 0x1ee9, /* #x1EE9 uhornacute */
+ 0x1eea, /* #x1EEA Uhorngrave */
+ 0x1eeb, /* #x1EEB uhorngrave */
+ 0x1eec, /* #x1EEC Uhornhook */
+ 0x1eed, /* #x1EED uhornhook */
+ 0x1eee, /* #x1EEE Uhorntilde */
+ 0x1eef, /* #x1EEF uhorntilde */
+ 0x1ef0, /* #x1EF0 Uhornbelowdot */
+ 0x1ef1, /* #x1EF1 uhornbelowdot */
+ 0x0300, /* #x1EF2 combining_grave */
+ 0x0301, /* #x1EF3 combining_acute */
+ 0x1ef4, /* #x1EF4 Ybelowdot */
+ 0x1ef5, /* #x1EF5 ybelowdot */
+ 0x1ef6, /* #x1EF6 Yhook */
+ 0x1ef7, /* #x1EF7 yhook */
+ 0x1ef8, /* #x1EF8 Ytilde */
+ 0x1ef9, /* #x1EF9 ytilde */
+
+ 0x01a0, /* #x1EFA Ohorn */
+ 0x01a1, /* #x1EFB ohorn */
+ 0x01af, /* #x1EFC Uhorn */
+ 0x01b0, /* #x1EFD uhorn */
+
+ 0x0309, /* #x1EFE combining_hook */
+ 0x0323, /* #x1EFF combining_belowdot */
+ };
+
static UINT_16_BIT const CYRILLIC[] =
{
0x0452, /* #x06A1 CYRILLIC SMALL LETTER DJE */
@@ -559,8 +999,16 @@
static Lisp_Object
x_keysym_to_character (KeySym keysym)
{
+#ifdef MULE
Lisp_Object charset = Qzero;
int code = 0;
+#endif /* MULE */
+
+ /* @@#### Add support for 0xFE?? and 0xFF?? keysyms
+ Add support for KOI8-U extensions in the 0x06?? range
+
+ See
http://www.cl.cam.ac.uk/~mgk25/ucs/keysyms.txt
+ */
/* Markus Kuhn's spec says keysyms in the range #x01000100 to #x0110FFFF
and only those should correspond directly to Unicode code points, in
@@ -568,42 +1016,48 @@
code points do the same thing with keysyms
#x01000000-#x01000100. */
+#ifndef MULE
+ if (keysym >= 0x01000000 && keysym <= 0x010000FF)
+ return make_char (keysym & 0xFFFFFF);
+#else
if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
- return Funicode_to_char (make_fixnum (keysym & 0xffffff), Qnil);
+ return make_char (buffer_unicode_to_ichar
+ ((int) (keysym & 0xFFFFFF),
+ /* @@#### need to get some sort of buffer to compute
+ this off; only applies in the old-Mule world */
+ current_buffer, CONVERR_SUCCEED));
+#endif /* not MULE */
if ((keysym & 0xff) < 0xa0)
return Qnil;
+#ifdef MULE
switch (keysym >> 8)
{
-
-#define USE_CHARSET(var,cs) \
- ((var) = charset_by_leading_byte (LEADING_BYTE_##cs))
-
case 0: /* ASCII + Latin1 */
- USE_CHARSET (charset, LATIN_ISO8859_1);
- code = keysym & 0x7f;
+ charset = Vcharset_latin_iso8859_1;
+ code = keysym & 0xff;
break;
case 1: /* Latin2 */
- USE_CHARSET (charset, LATIN_ISO8859_2);
- code = keysym & 0x7f;
+ charset = Vcharset_latin_iso8859_2;
+ code = keysym & 0xff;
break;
case 2: /* Latin3 */
- USE_CHARSET (charset, LATIN_ISO8859_3);
- code = keysym & 0x7f;
+ charset = Vcharset_latin_iso8859_3;
+ code = keysym & 0xff;
break;
case 3: /* Latin4 */
- USE_CHARSET (charset, LATIN_ISO8859_4);
- code = keysym & 0x7f;
+ charset = Vcharset_latin_iso8859_4;
+ code = keysym & 0xff;
break;
case 4: /* Katakana */
- USE_CHARSET (charset, KATAKANA_JISX0201);
+ charset = Vcharset_katakana_jisx0201;
if ((keysym & 0xff) > 0xa0)
- code = keysym & 0x7f;
+ code = keysym & 0xff;
break;
case 5: /* Arabic */
- USE_CHARSET (charset, ARABIC_ISO8859_6);
- code = keysym & 0x7f;
+ charset = Vcharset_arabic_iso8859_6;
+ code = keysym & 0xff;
break;
case 6: /* Cyrillic */
{
@@ -612,20 +1066,20 @@
}
case 7: /* Greek */
{
- static UExtbyte const greek[] = /* 0x20 - 0x7f */
- {0x00, 0x36, 0x38, 0x39, 0x3a, 0x5a, 0x00, 0x3c,
- 0x3e, 0x5b, 0x00, 0x3f, 0x00, 0x00, 0x35, 0x2f,
- 0x00, 0x5c, 0x5d, 0x5e, 0x5f, 0x7a, 0x40, 0x7c,
- 0x7d, 0x7b, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x53, 0x00, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x73, 0x72, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- USE_CHARSET (charset, GREEK_ISO8859_7);
+ static UExtbyte const greek[] = /* 0xa0 - 0xff */
+ {0x00, 0xb6, 0xb8, 0xb9, 0xba, 0xda, 0x00, 0xbc,
+ 0xbe, 0xdb, 0x00, 0xbf, 0x00, 0x00, 0xb5, 0xaf,
+ 0x00, 0xdc, 0xdd, 0xde, 0xdf, 0xfa, 0xc0, 0xfc,
+ 0xfd, 0xfb, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd3, 0x00, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf3, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ charset = Vcharset_greek_iso8859_7;
code = greek[(keysym & 0x7f) - 0x20];
break;
}
@@ -642,29 +1096,110 @@
USE_UNICODE_MAP (keysym, APL);
break;
case 12: /* Hebrew */
- USE_CHARSET (charset, HEBREW_ISO8859_8);
- code = keysym & 0x7f;
+ charset = Vcharset_hebrew_iso8859_8;
+ code = keysym & 0xff;
break;
case 13: /* Thai */
/* #### This needs to deal with character composition.
- Are you sure we can't leave it to the X server? */
- USE_CHARSET (charset, THAI_TIS620);
- code = keysym & 0x7f;
+ Are you sure we can't leave it to the X server? */
+ charset = Vcharset_thai_tis620;
+ code = keysym & 0xff;
+ break;
+ case 14: /* Korean Hangul. */
+ USE_UNICODE_MAP (keysym, HANGUL);
+ break;
+ case 18: /* Latin 8 - ISO8859-14. */
+ charset = Ffind_charset (intern ("latin-iso8859-14"));
+ code = keysym & 0xff;
break;
- case 14: /* Korean Hangul. Would like some information on whether this
- is worth doing--there don't appear to be any Korean keyboard
- layouts in the XKB data files. */
+ case 19: /* Latin 9 - ISO8859-15. */
+ charset = Vcharset_latin_iso8859_15;
+ code = keysym & 0xff;
+ break;
+ case 20: /* Armenian. */
+ USE_UNICODE_MAP (keysym, ARMENIAN);
break;
-
- case 19: /* Latin 9 - ISO8859-15. */
- USE_CHARSET (charset, LATIN_ISO8859_15);
- code = keysym & 0x7f;
+ case 21: /* Georgian. */
+ USE_UNICODE_MAP (keysym, GEORGIAN);
+ break;
+ case 22: /* Azeri (and other Turkic or Caucasian languages of ex-USSR) */
+ USE_UNICODE_MAP (keysym, AZERI_ETC);
+ break;
+ case 30: /* Vietnamese */
+ USE_UNICODE_MAP (keysym, VIETNAMESE);
break;
case 32: /* Currency. The lower sixteen bits of these keysyms happily
correspond exactly to the Unicode code points of the
associated characters */
- return Funicode_to_char (make_fixnum (keysym & 0xffff), Qnil);
- break;
+ return make_char (buffer_unicode_to_ichar
+ ((int) (keysym & 0xffff),
+ /* @@#### need to get some sort of buffer to
+ compute this off; only applies in the old-Mule
+ world */
+ current_buffer, CONVERR_SUCCEED));
+
+/* @@#### Support me!
+
+ Actually, these are somewhat already supported by x-init.el/x-compose.el,
+ but only acute, grave, circum(flex), cedilla, diaeresis, tilde. We
+ should try to eliminate that code and use general Unicode support for
+ converting to precomposed sequences.
+
+0xfe50 U0300 f # dead_grave
+0xfe51 U0301 f # dead_acute
+0xfe52 U0302 f # dead_circumflex
+0xfe53 U0303 f # dead_tilde
+0xfe54 U0304 f # dead_macron
+0xfe55 U0306 f # dead_breve
+0xfe56 U0307 f # dead_abovedot
+0xfe57 U0308 f # dead_diaeresis
+0xfe58 U030a f # dead_abovering
+0xfe59 U030b f # dead_doubleacute
+0xfe5a U030c f # dead_caron
+0xfe5b U0327 f # dead_cedilla
+0xfe5c U0328 f # dead_ogonek
+0xfe5d U0345 f # dead_iota
+0xfe5e U3099 f # dead_voiced_sound
+0xfe5f U309a f # dead_semivoiced_sound
+0xfe60 U0323 f # dead_belowdot
+0xfe61 U0309 f # dead_hook
+0xfe62 U031b f # dead_horn
+
+What about these? We don't have to convert these to ASCII but make sure we
+handle all of the KP-foo things and get them to behave like plain foo when
+KP-foo isn't bound (which includes self-inserting the associated character
+if necessary). DOCUMENT the existing system that does this.
+
+0xff08 U0008 f # BackSpace /- back space, back char -/
+0xff09 U0009 f # Tab
+0xff0a U000a f # Linefeed /- Linefeed, LF -/
+0xff0b U000b f # Clear
+0xff0d U000d f # Return /- Return, enter -/
+0xff13 U0013 f # Pause /- Pause, hold -/
+0xff14 U0014 f # Scroll_Lock
+0xff15 U0015 f # Sys_Req
+0xff1b U001b f # Escape
+0xff80 U0020 f # KP_Space /- space -/
+0xff89 U0009 f # KP_Tab
+0xff8d U000d f # KP_Enter /- enter -/
+0xffaa U002a f # KP_Multiply
+0xffab U002b f # KP_Add
+0xffac U002c f # KP_Separator /- separator, often comma -/
+0xffad U002d f # KP_Subtract
+0xffae U002e f # KP_Decimal
+0xffaf U002f f # KP_Divide
+0xffb0 U0030 f # KP_0
+0xffb1 U0031 f # KP_1
+0xffb2 U0032 f # KP_2
+0xffb3 U0033 f # KP_3
+0xffb4 U0034 f # KP_4
+0xffb5 U0035 f # KP_5
+0xffb6 U0036 f # KP_6
+0xffb7 U0037 f # KP_7
+0xffb8 U0038 f # KP_8
+0xffb9 U0039 f # KP_9
+0xffbd U003d f # KP_Equal /- equals -/
+*/
default:
break;
}
@@ -672,19 +1207,35 @@
if (code == 0)
return Qnil;
-#ifdef MULE
- {
- Lisp_Object unified = Funicode_to_char
- (Fchar_to_unicode (make_char (make_ichar (charset, code, 0))), Qnil);
- if (!NILP (unified))
- {
- return unified;
- }
- return make_char (make_ichar (charset, code, 0));
- }
-#else
- return make_char (code + 0x80);
-#endif
+ /* #### Is this check on !NILP (charset) needed? Maybe should be assert? */
+ if (!NILP (charset))
+ {
+ /* First try to generate a unified character by converting through
+ Unicode, then try converting directly to an Ichar (only matters
+ when non-Unicode-internal, else we get same results both ways). */
+ int ucs = charset_codepoint_to_unicode (charset, 0, code, CONVERR_FAIL);
+ if (ucs >= 0)
+ {
+ /* @@#### current_buffer dependency */
+ Ichar ich = buffer_unicode_to_ichar (ucs, current_buffer,
+ CONVERR_FAIL);
+ if (ich >= 0)
+ return make_char (ich);
+ }
+ else
+ {
+ Ichar ich =
+ charset_codepoint_to_ichar (charset, 0, code, CONVERR_FAIL);
+ if (ich >= 0)
+ return make_char (ich);
+ }
+ }
+ return Qnil;
+#else /* not MULE */
+ if (keysym >= 0x100)
+ return Qnil;
+ return make_char (keysym);
+#endif /* (not) MULE */
}
/************************************************************************/
diff -r 9bdc40b8fb78 -r a5b21ebab055 src/event-xlike-inc.c
--- a/src/event-xlike-inc.c Sun Dec 17 12:20:06 2017 +0000
+++ b/src/event-xlike-inc.c Mon Dec 18 22:04:46 2017 +0000
@@ -162,1121 +162,3 @@
return 0;
}
-#if defined (THIS_IS_X) || !defined (__GDK_KEYS_H__)
-
-#ifdef MULE
-
-/* Use an appropriate map to Unicode within x_keysym_to_character. Arguments
- are evaluated multiple times.
-
- Breaks if an X11 keysym maps to zero in Unicode. */
-
-#define USE_UNICODE_MAP(keysym, map) \
- if (keysym >= FIRST_KNOWN_##map \
- && (keysym < (FIRST_KNOWN_##map + countof (map))) \
- && map[keysym - FIRST_KNOWN_##map ]) do \
- { \
- keysym -= FIRST_KNOWN_##map ; \
- return make_char (buffer_unicode_to_ichar ((int) map[keysym], \
- /* @@#### need to get some sort \
- of buffer to compute this off; \
- only applies in the old-Mule \
- world */ \
- current_buffer, \
- CONVERR_SUCCEED)); \
- } while (0)
-
-/* Maps to Unicode for X11 KeySyms, where we don't have a direct internal
- mapping based on a Mule character set, or whatever. Taken from Markus
- Kuhn's X11.keysyms--if you're ever comparing with that file, note the
- sequences of KeySyms often leave out entries, so you'll have to fill them
- in. Doesn't include support for Hangul, which it should, if the X11
- Hangul keysyms have ever been used anywhere.
-*/
-
-static UINT_16_BIT const TECHNICAL[] =
- {
- 0x23B7, /* #x08A1 LEFT RADICAL Technical */
-
-#define FIRST_KNOWN_TECHNICAL 0x8A1
-
- 0x0, /* #x08A2 TOP LEFT RADICAL Technical */
- 0x0, /* #x08A3 HORIZONTAL CONNECTOR Technical */
- 0x2320, /* #x08A4 TOP INTEGRAL Technical */
- 0x2321, /* #x08A5 BOTTOM INTEGRAL Technical */
- 0x0, /* #x08A6 VERTICAL CONNECTOR Technical */
- 0x23A1, /* #x08A7 TOP LEFT SQUARE BRACKET Technical */
- 0x23A3, /* #x08A8 BOTTOM LEFT SQUARE BRACKET Technical */
- 0x23A4, /* #x08A9 TOP RIGHT SQUARE BRACKET Technical */
- 0x23A6, /* #x08AA BOTTOM RIGHT SQUARE BRACKET Technical */
- 0x239B, /* #x08AB TOP LEFT PARENTHESIS Technical */
- 0x239D, /* #x08AC BOTTOM LEFT PARENTHESIS Technical */
- 0x239E, /* #x08AD TOP RIGHT PARENTHESIS Technical */
- 0x23A0, /* #x08AE BOTTOM RIGHT PARENTHESIS Technical */
- 0x23A8, /* #x08AF LEFT MIDDLE CURLY BRACE Technical */
- 0x23AC, /* #x08B0 RIGHT MIDDLE CURLY BRACE Technical */
- 0x0, /* #x08B1 TOP LEFT SUMMATION Technical */
- 0x0, /* #x08B2 BOTTOM LEFT SUMMATION Technical */
- 0x0, /* #x08B3 TOP VERTICAL SUMMATION CONNECTOR Technical */
- 0x0, /* #x08B4 BOTTOM VERTICAL SUMMATION CONNECTOR Technical */
- 0x0, /* #x08B5 TOP RIGHT SUMMATION Technical */
- 0x0, /* #x08B6 BOTTOM RIGHT SUMMATION Technical */
- 0x0, /* #x08B7 RIGHT MIDDLE SUMMATION Technical */
- 0x0, /* #x08B8 */
- 0x0, /* #x08B9 */
- 0x0, /* #x08BA */
- 0x0, /* #x08BB */
- 0x2264, /* #x08BC LESS THAN OR EQUAL SIGN Technical */
- 0x2260, /* #x08BD NOT EQUAL SIGN Technical */
- 0x2265, /* #x08BE GREATER THAN OR EQUAL SIGN Technical */
- 0x222B, /* #x08BF INTEGRAL Technical */
- 0x2234, /* #x08C0 THEREFORE Technical */
- 0x221D, /* #x08C1 VARIATION, PROPORTIONAL TO Technical */
- 0x221E, /* #x08C2 INFINITY Technical */
- 0x0, /* #x08C3 */
- 0x0, /* #x08C4 */
- 0x2207, /* #x08C5 NABLA, DEL Technical */
- 0x0, /* #x08C6 */
- 0x0, /* #x08C7 */
- 0x223C, /* #x08C8 IS APPROXIMATE TO Technical */
- 0x2243, /* #x08C9 SIMILAR OR EQUAL TO Technical */
- 0x0, /* #x08CA */
- 0x0, /* #x08CB */
- 0x0, /* #x08CC */
- 0x21D4, /* #x08CD IF AND ONLY IF Technical */
- 0x21D2, /* #x08CE IMPLIES Technical */
- 0x2261, /* #x08CF IDENTICAL TO Technical */
- 0x0, /* #x08D0 */
- 0x0, /* #x08D1 */
- 0x0, /* #x08D2 */
- 0x0, /* #x08D3 */
- 0x0, /* #x08D4 */
- 0x0, /* #x08D5 */
- 0x221A, /* #x08D6 RADICAL Technical */
- 0x0, /* #x08D7 */
- 0x0, /* #x08D8 */
- 0x0, /* #x08D9 */
- 0x2282, /* #x08DA IS INCLUDED IN Technical */
- 0x2283, /* #x08DB INCLUDES Technical */
- 0x2229, /* #x08DC INTERSECTION Technical */
- 0x222A, /* #x08DD UNION Technical */
- 0x2227, /* #x08DE LOGICAL AND Technical */
- 0x2228, /* #x08DF LOGICAL OR Technical */
- 0x0, /* #x08E0 */
- 0x0, /* #x08E1 */
- 0x0, /* #x08E2 */
- 0x0, /* #x08E3 */
- 0x0, /* #x08E4 */
- 0x0, /* #x08E5 */
- 0x0, /* #x08E6 */
- 0x0, /* #x08E7 */
- 0x0, /* #x08E8 */
- 0x0, /* #x08E9 */
- 0x0, /* #x08Ea */
- 0x0, /* #x08Eb */
- 0x0, /* #x08Ec */
- 0x0, /* #x08Ed */
- 0x0, /* #x08Ee */
- 0x2202, /* #x08EF PARTIAL DERIVATIVE Technical */
- 0x0, /* #x08F0 */
- 0x0, /* #x08F1 */
- 0x0, /* #x08F2 */
- 0x0, /* #x08F3 */
- 0x0, /* #x08F4 */
- 0x0, /* #x08F5 */
- 0x0192, /* #x08F6 FUNCTION Technical */
- 0x0, /* #x08F7 */
- 0x0, /* #x08F8 */
- 0x0, /* #x08F9 */
- 0x0, /* #x08FA */
- 0x2190, /* #x08FB LEFT ARROW Technical */
- 0x2191, /* #x08FC UPWARD ARROW Technical */
- 0x2192, /* #x08FD RIGHT ARROW Technical */
- 0x2193, /* #x08FE DOWNWARD ARROW Technical */
- };
-
-static UINT_16_BIT const SPECIAL[] =
- {
- 0x25C6, /* #x09E0 SOLID DIAMOND Special */
-
-#define FIRST_KNOWN_SPECIAL 0x9E0
-
- 0x2592, /* #x09E1 CHECKERBOARD Special */
- 0x2409, /* #x09E2 ``HT'' Special */
- 0x240C, /* #x09E3 ``FF'' Special */
- 0x240D, /* #x09E4 ``CR'' Special */
- 0x240A, /* #x09E5 ``LF'' Special */
- 0x0, /* #x09E6 */
- 0x0, /* #x09E7 */
- 0x2424, /* #x09E8 ``NL'' Special */
- 0x240B, /* #x09E9 ``VT'' Special */
- 0x2518, /* #x09EA LOWER-RIGHT CORNER Special */
- 0x2510, /* #x09EB UPPER-RIGHT CORNER Special */
- 0x250C, /* #x09EC UPPER-LEFT CORNER Special */
- 0x2514, /* #x09ED LOWER-LEFT CORNER Special */
- 0x253C, /* #x09EE CROSSING-LINES Special */
- 0x23BA, /* #x09EF HORIZONTAL LINE, SCAN 1 Special */
- 0x23BB, /* #x09F0 HORIZONTAL LINE, SCAN 3 Special */
- 0x2500, /* #x09F1 HORIZONTAL LINE, SCAN 5 Special */
- 0x23BC, /* #x09F2 HORIZONTAL LINE, SCAN 7 Special */
- 0x23BD, /* #x09F3 HORIZONTAL LINE, SCAN 9 Special */
- 0x251C, /* #x09F4 LEFT ``T'' Special */
- 0x2524, /* #x09F5 RIGHT ``T'' Special */
- 0x2534, /* #x09F6 BOTTOM ``T'' Special */
- 0x252C, /* #x09F7 TOP ``T'' Special */
- 0x2502 /* #x09F8 VERTICAL BAR Special */
- };
-
-static UINT_16_BIT const PUBLISHING[] =
- {
- 0x2003, /* #x0AA1 EM SPACE Publish */
-
-#define FIRST_KNOWN_PUBLISHING 0xAA1
-
- 0x2002, /* #x0AA2 EN SPACE Publish */
- 0x2004, /* #x0AA3 3/EM SPACE Publish */
- 0x2005, /* #x0AA4 4/EM SPACE Publish */
- 0x2007, /* #x0AA5 DIGIT SPACE Publish */
- 0x2008, /* #x0AA6 PUNCTUATION SPACE Publish */
- 0x2009, /* #x0AA7 THIN SPACE Publish */
- 0x200A, /* #x0AA8 HAIR SPACE Publish */
- 0x2014, /* #x0AA9 EM DASH Publish */
- 0x2013, /* #x0AAA EN DASH Publish */
- 0x0, /* #x0AAB */
- 0x0, /* #x0AAC SIGNIFICANT BLANK SYMBOL Publish */
- 0x0, /* #x0AAD */
- 0x2026, /* #x0AAE ELLIPSIS Publish */
- 0x2025, /* #x0AAF DOUBLE BASELINE DOT Publish */
- 0x2153, /* #x0AB0 VULGAR FRACTION ONE THIRD Publish */
- 0x2154, /* #x0AB1 VULGAR FRACTION TWO THIRDS Publish */
- 0x2155, /* #x0AB2 VULGAR FRACTION ONE FIFTH Publish */
- 0x2156, /* #x0AB3 VULGAR FRACTION TWO FIFTHS Publish */
- 0x2157, /* #x0AB4 VULGAR FRACTION THREE FIFTHS Publish */
- 0x2158, /* #x0AB5 VULGAR FRACTION FOUR FIFTHS Publish */
- 0x2159, /* #x0AB6 VULGAR FRACTION ONE SIXTH Publish */
- 0x215A, /* #x0AB7 VULGAR FRACTION FIVE SIXTHS Publish */
- 0x2105, /* #x0AB8 CARE OF Publish */
- 0x0, /* #x0AB9 */
- 0x0, /* #x0ABA */
- 0x2012, /* #x0ABB FIGURE DASH Publish */
- 0x3008, /* #x0ABC LEFT ANGLE BRACKET Publish */
- 0x002E, /* #x0ABD DECIMAL POINT Publish */
- 0x3009, /* #x0ABE RIGHT ANGLE BRACKET Publish */
- 0x0, /* #x0ABF MARKER Publish */
- 0x0, /* #x0AC0 */
- 0x0, /* #x0AC1 */
- 0x0, /* #x0AC2 */
- 0x215B, /* #x0AC3 VULGAR FRACTION ONE EIGHTH Publish */
- 0x215C, /* #x0AC4 VULGAR FRACTION THREE EIGHTHS Publish */
- 0x215D, /* #x0AC5 VULGAR FRACTION FIVE EIGHTHS Publish */
- 0x215E, /* #x0AC6 VULGAR FRACTION SEVEN EIGHTHS Publish */
- 0x0, /* #x0AC7 */
- 0x0, /* #x0AC8 */
- 0x2122, /* #x0AC9 TRADEMARK SIGN Publish */
- 0x0, /* #x0ACA SIGNATURE MARK Publish */
- 0x0, /* #x0ACB TRADEMARK SIGN IN CIRCLE Publish */
- 0x0, /* #x0ACC LEFT OPEN TRIANGLE Publish */
- 0x0, /* #x0ACD RIGHT OPEN TRIANGLE Publish */
- 0x0, /* #x0ACE EM OPEN CIRCLE Publish */
- 0x0, /* #x0ACF EM OPEN RECTANGLE Publish */
- 0x2018, /* #x0AD0 LEFT SINGLE QUOTATION MARK Publish */
- 0x2019, /* #x0AD1 RIGHT SINGLE QUOTATION MARK Publish */
- 0x201C, /* #x0AD2 LEFT DOUBLE QUOTATION MARK Publish */
- 0x201D, /* #x0AD3 RIGHT DOUBLE QUOTATION MARK Publish */
- 0x211E, /* #x0AD4 PRESCRIPTION, TAKE, RECIPE Publish */
- 0x0, /* #x0AD5 */
- 0x2032, /* #x0AD6 MINUTES Publish */
- 0x2033, /* #x0AD7 SECONDS Publish */
- 0x0, /* #x0AD8 */
- 0x271D, /* #x0AD9 LATIN CROSS Publish */
- 0x0, /* #x0ADA HEXAGRAM Publish */
- 0x0, /* #x0ADB FILLED RECTANGLE BULLET Publish */
- 0x0, /* #x0ADC FILLED LEFT TRIANGLE BULLET Publish */
- 0x0, /* #x0ADD FILLED RIGHT TRIANGLE BULLET Publish */
- 0x0, /* #x0ADE EM FILLED CIRCLE Publish */
- 0x0, /* #x0ADF EM FILLED RECTANGLE Publish */
- 0x0, /* #x0AE0 EN OPEN CIRCLE BULLET Publish */
- 0x0, /* #x0AE1 EN OPEN SQUARE BULLET Publish */
- 0x0, /* #x0AE2 OPEN RECTANGULAR BULLET Publish */
- 0x0, /* #x0AE3 OPEN TRIANGULAR BULLET UP Publish */
- 0x0, /* #x0AE4 OPEN TRIANGULAR BULLET DOWN Publish */
- 0x0, /* #x0AE5 OPEN STAR Publish */
- 0x0, /* #x0AE6 EN FILLED CIRCLE BULLET Publish */
- 0x0, /* #x0AE7 EN FILLED SQUARE BULLET Publish */
- 0x0, /* #x0AE8 FILLED TRIANGULAR BULLET UP Publish */
- 0x0, /* #x0AE9 FILLED TRIANGULAR BULLET DOWN Publish */
- 0x0, /* #x0AEA LEFT POINTER Publish */
- 0x0, /* #x0AEB RIGHT POINTER Publish */
- 0x2663, /* #x0AEC CLUB Publish */
- 0x2666, /* #x0AED DIAMOND Publish */
- 0x2665, /* #x0AEE HEART Publish */
- 0x0, /* #x0AEF */
- 0x2720, /* #x0AF0 MALTESE CROSS Publish */
- 0x2020, /* #x0AF1 DAGGER Publish */
- 0x2021, /* #x0AF2 DOUBLE DAGGER Publish */
- 0x2713, /* #x0AF3 CHECK MARK, TICK Publish */
- 0x2717, /* #x0AF4 BALLOT CROSS Publish */
- 0x266F, /* #x0AF5 MUSICAL SHARP Publish */
- 0x266D, /* #x0AF6 MUSICAL FLAT Publish */
- 0x2642, /* #x0AF7 MALE SYMBOL Publish */
- 0x2640, /* #x0AF8 FEMALE SYMBOL Publish */
- 0x260E, /* #x0AF9 TELEPHONE SYMBOL Publish */
- 0x2315, /* #x0AFA TELEPHONE RECORDER SYMBOL Publish */
- 0x2117, /* #x0AFB PHONOGRAPH COPYRIGHT SIGN Publish */
- 0x2038, /* #x0AFC CARET Publish */
- 0x201A, /* #x0AFD SINGLE LOW QUOTATION MARK Publish */
- 0x201E, /* #x0AFE DOUBLE LOW QUOTATION MARK Publish */
- };
-
-static UINT_16_BIT const APL[] =
- {
- 0x22A5, /* #x0BC2 DOWN TACK APL */
-#define FIRST_KNOWN_APL 0xBC2
- 0x0, /* #x0BC3 UP SHOE (CAP) APL */
- 0x230A, /* #x0BC4 DOWN STILE APL */
- 0x0, /* #x0BC5 */
- 0x0, /* #x0BC6 UNDERBAR APL */
- 0x0, /* #x0BC7 */
- 0x0, /* #x0BC8 */
- 0x0, /* #x0BC9 */
- 0x2218, /* #x0BCA JOT APL */
- 0x0, /* #x0BCB */
- 0x2395, /* #x0BCC QUAD APL */
- 0x0, /* #x0BCD */
- 0x22A4, /* #x0BCE UP TACK APL */
- 0x25CB, /* #x0BCF CIRCLE APL */
- 0x0, /* #x0BD0 */
- 0x0, /* #x0BD1 */
- 0x0, /* #x0BD2 */
- 0x2308, /* #x0BD3 UP STILE APL */
- 0x0, /* #x0BD4 */
- 0x0, /* #x0BD5 */
- 0x0, /* #x0BD6 DOWN SHOE (CUP) APL */
- 0x0, /* #x0BD7 */
- 0x0, /* #x0BD8 RIGHT SHOE APL */
- 0x0, /* #x0BD9 */
- 0x0, /* #x0BDA LEFT SHOE APL */
- 0x0, /* #x0BDB */
- 0x0, /* #x0BDC */
- 0x22A2, /* #x0BDC LEFT TACK APL */
- 0x0, /* #x0BDE */
- 0x0, /* #x0BDF */
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 0x0BB0--0x0BBB */
- 0x0, 0x0, 0x0, 0x0,
- 0x22A3, /* #x0BFC RIGHT TACK APL */
- };
-
-static UINT_16_BIT const HANGUL[] =
- {
-#define FIRST_KNOWN_HANGUL 0xEA1
- 0x3131, /* #x0EA1 Hangul_Kiyeog */
- 0x3132, /* #x0EA2 Hangul_SsangKiyeog */
- 0x3133, /* #x0EA3 Hangul_KiyeogSios */
- 0x3134, /* #x0EA4 Hangul_Nieun */
- 0x3135, /* #x0EA5 Hangul_NieunJieuj */
- 0x3136, /* #x0EA6 Hangul_NieunHieuh */
- 0x3137, /* #x0EA7 Hangul_Dikeud */
- 0x3138, /* #x0EA8 Hangul_SsangDikeud */
- 0x3139, /* #x0EA9 Hangul_Rieul */
- 0x313a, /* #x0EAA Hangul_RieulKiyeog */
- 0x313b, /* #x0EAB Hangul_RieulMieum */
- 0x313c, /* #x0EAC Hangul_RieulPieub */
- 0x313d, /* #x0EAD Hangul_RieulSios */
- 0x313e, /* #x0EAE Hangul_RieulTieut */
- 0x313f, /* #x0EAF Hangul_RieulPhieuf */
- 0x3140, /* #x0EB0 Hangul_RieulHieuh */
- 0x3141, /* #x0EB1 Hangul_Mieum */
- 0x3142, /* #x0EB2 Hangul_Pieub */
- 0x3143, /* #x0EB3 Hangul_SsangPieub */
- 0x3144, /* #x0EB4 Hangul_PieubSios */
- 0x3145, /* #x0EB5 Hangul_Sios */
- 0x3146, /* #x0EB6 Hangul_SsangSios */
- 0x3147, /* #x0EB7 Hangul_Ieung */
- 0x3148, /* #x0EB8 Hangul_Jieuj */
- 0x3149, /* #x0EB9 Hangul_SsangJieuj */
- 0x314a, /* #x0EBA Hangul_Cieuc */
- 0x314b, /* #x0EBB Hangul_Khieuq */
- 0x314c, /* #x0EBC Hangul_Tieut */
- 0x314d, /* #x0EBD Hangul_Phieuf */
- 0x314e, /* #x0EBE Hangul_Hieuh */
- 0x314f, /* #x0EBF Hangul_A */
- 0x3150, /* #x0EC0 Hangul_AE */
- 0x3151, /* #x0EC1 Hangul_YA */
- 0x3152, /* #x0EC2 Hangul_YAE */
- 0x3153, /* #x0EC3 Hangul_EO */
- 0x3154, /* #x0EC4 Hangul_E */
- 0x3155, /* #x0EC5 Hangul_YEO */
- 0x3156, /* #x0EC6 Hangul_YE */
- 0x3157, /* #x0EC7 Hangul_O */
- 0x3158, /* #x0EC8 Hangul_WA */
- 0x3159, /* #x0EC9 Hangul_WAE */
- 0x315a, /* #x0ECA Hangul_OE */
- 0x315b, /* #x0ECB Hangul_YO */
- 0x315c, /* #x0ECC Hangul_U */
- 0x315d, /* #x0ECD Hangul_WEO */
- 0x315e, /* #x0ECE Hangul_WE */
- 0x315f, /* #x0ECF Hangul_WI */
- 0x3160, /* #x0ED0 Hangul_YU */
- 0x3161, /* #x0ED1 Hangul_EU */
- 0x3162, /* #x0ED2 Hangul_YI */
- 0x3163, /* #x0ED3 Hangul_I */
- 0x11a8, /* #x0ED4 Hangul_J_Kiyeog */
- 0x11a9, /* #x0ED5 Hangul_J_SsangKiyeog */
- 0x11aa, /* #x0ED6 Hangul_J_KiyeogSios */
- 0x11ab, /* #x0ED7 Hangul_J_Nieun */
- 0x11ac, /* #x0ED8 Hangul_J_NieunJieuj */
- 0x11ad, /* #x0ED9 Hangul_J_NieunHieuh */
- 0x11ae, /* #x0EDA Hangul_J_Dikeud */
- 0x11af, /* #x0EDB Hangul_J_Rieul */
- 0x11b0, /* #x0EDC Hangul_J_RieulKiyeog */
- 0x11b1, /* #x0EDD Hangul_J_RieulMieum */
- 0x11b2, /* #x0EDE Hangul_J_RieulPieub */
- 0x11b3, /* #x0EDF Hangul_J_RieulSios */
- 0x11b4, /* #x0EE0 Hangul_J_RieulTieut */
- 0x11b5, /* #x0EE1 Hangul_J_RieulPhieuf */
- 0x11b6, /* #x0EE2 Hangul_J_RieulHieuh */
- 0x11b7, /* #x0EE3 Hangul_J_Mieum */
- 0x11b8, /* #x0EE4 Hangul_J_Pieub */
- 0x11b9, /* #x0EE5 Hangul_J_PieubSios */
- 0x11ba, /* #x0EE6 Hangul_J_Sios */
- 0x11bb, /* #x0EE7 Hangul_J_SsangSios */
- 0x11bc, /* #x0EE8 Hangul_J_Ieung */
- 0x11bd, /* #x0EE9 Hangul_J_Jieuj */
- 0x11be, /* #x0EEA Hangul_J_Cieuc */
- 0x11bf, /* #x0EEB Hangul_J_Khieuq */
- 0x11c0, /* #x0EEC Hangul_J_Tieut */
- 0x11c1, /* #x0EED Hangul_J_Phieuf */
- 0x11c2, /* #x0EEE Hangul_J_Hieuh */
- 0x316d, /* #x0EEF Hangul_RieulYeorinHieuh */
- 0x3171, /* #x0EF0 Hangul_SunkyeongeumMieum */
- 0x3178, /* #x0EF1 Hangul_SunkyeongeumPieub */
- 0x317f, /* #x0EF2 Hangul_PanSios */
- 0x3181, /* #x0EF3 Hangul_KkogjiDalrinIeung */
- 0x3184, /* #x0EF4 Hangul_SunkyeongeumPhieuf */
- 0x3186, /* #x0EF5 Hangul_YeorinHieuh */
- 0x318d, /* #x0EF6 Hangul_AraeA */
- 0x318e, /* #x0EF7 Hangul_AraeAE */
- 0x11eb, /* #x0EF8 Hangul_J_PanSios */
- 0x11f0, /* #x0EF9 Hangul_J_KkogjiDalrinIeung */
- 0x11f9, /* #x0EFA Hangul_J_YeorinHieuh */
- 0x0000, /* #x0EFB */
- 0x0000, /* #x0EFC */
- 0x0000, /* #x0EFD */
- 0x0000, /* #x0EFE */
- 0x20a9, /* #x0EFF Korean_Won */
- };
-
-static UINT_16_BIT const ARMENIAN[] =
- {
-#define FIRST_KNOWN_ARMENIAN 0x14A1
- 0x0000, /* #x14A1 Armenian_eternity */
- 0x0587, /* #x14A2 Armenian_ligature_ew */
- 0x0589, /* #x14A3 Armenian_verjaket */
- 0x0029, /* #x14A4 Armenian_parenright */
- 0x0028, /* #x14A5 Armenian_parenleft */
- 0x00bb, /* #x14A6 Armenian_guillemotright */
- 0x00ab, /* #x14A7 Armenian_guillemotleft */
- 0x2014, /* #x14A8 Armenian_em_dash */
- 0x002e, /* #x14A9 Armenian_mijaket */
- 0x055d, /* #x14AA Armenian_but */
- 0x002c, /* #x14AB Armenian_comma */
- 0x2013, /* #x14AC Armenian_en_dash */
- 0x058a, /* #x14AD Armenian_yentamna */
- 0x2026, /* #x14AE Armenian_ellipsis */
- 0x055c, /* #x14AF Armenian_amanak */
- 0x055b, /* #x14B0 Armenian_shesht */
- 0x055e, /* #x14B1 Armenian_paruyk */
- 0x0531, /* #x14B2 Armenian_AYB */
- 0x0561, /* #x14B3 Armenian_ayb */
- 0x0532, /* #x14B4 Armenian_BEN */
- 0x0562, /* #x14B5 Armenian_ben */
- 0x0533, /* #x14B6 Armenian_GIM */
- 0x0563, /* #x14B7 Armenian_gim */
- 0x0534, /* #x14B8 Armenian_DA */
- 0x0564, /* #x14B9 Armenian_da */
- 0x0535, /* #x14BA Armenian_YECH */
- 0x0565, /* #x14BB Armenian_yech */
- 0x0536, /* #x14BC Armenian_ZA */
- 0x0566, /* #x14BD Armenian_za */
- 0x0537, /* #x14BE Armenian_E */
- 0x0567, /* #x14BF Armenian_e */
- 0x0538, /* #x14C0 Armenian_AT */
- 0x0568, /* #x14C1 Armenian_at */
- 0x0539, /* #x14C2 Armenian_TO */
- 0x0569, /* #x14C3 Armenian_to */
- 0x053a, /* #x14C4 Armenian_ZHE */
- 0x056a, /* #x14C5 Armenian_zhe */
- 0x053b, /* #x14C6 Armenian_INI */
- 0x056b, /* #x14C7 Armenian_ini */
- 0x053c, /* #x14C8 Armenian_LYUN */
- 0x056c, /* #x14C9 Armenian_lyun */
- 0x053d, /* #x14CA Armenian_KHE */
- 0x056d, /* #x14CB Armenian_khe */
- 0x053e, /* #x14CC Armenian_TSA */
- 0x056e, /* #x14CD Armenian_tsa */
- 0x053f, /* #x14CE Armenian_KEN */
- 0x056f, /* #x14CF Armenian_ken */
- 0x0540, /* #x14D0 Armenian_HO */
- 0x0570, /* #x14D1 Armenian_ho */
- 0x0541, /* #x14D2 Armenian_DZA */
- 0x0571, /* #x14D3 Armenian_dza */
- 0x0542, /* #x14D4 Armenian_GHAT */
- 0x0572, /* #x14D5 Armenian_ghat */
- 0x0543, /* #x14D6 Armenian_TCHE */
- 0x0573, /* #x14D7 Armenian_tche */
- 0x0544, /* #x14D8 Armenian_MEN */
- 0x0574, /* #x14D9 Armenian_men */
- 0x0545, /* #x14DA Armenian_HI */
- 0x0575, /* #x14DB Armenian_hi */
- 0x0546, /* #x14DC Armenian_NU */
- 0x0576, /* #x14DD Armenian_nu */
- 0x0547, /* #x14DE Armenian_SHA */
- 0x0577, /* #x14DF Armenian_sha */
- 0x0548, /* #x14E0 Armenian_VO */
- 0x0578, /* #x14E1 Armenian_vo */
- 0x0549, /* #x14E2 Armenian_CHA */
- 0x0579, /* #x14E3 Armenian_cha */
- 0x054a, /* #x14E4 Armenian_PE */
- 0x057a, /* #x14E5 Armenian_pe */
- 0x054b, /* #x14E6 Armenian_JE */
- 0x057b, /* #x14E7 Armenian_je */
- 0x054c, /* #x14E8 Armenian_RA */
- 0x057c, /* #x14E9 Armenian_ra */
- 0x054d, /* #x14EA Armenian_SE */
- 0x057d, /* #x14EB Armenian_se */
- 0x054e, /* #x14EC Armenian_VEV */
- 0x057e, /* #x14ED Armenian_vev */
- 0x054f, /* #x14EE Armenian_TYUN */
- 0x057f, /* #x14EF Armenian_tyun */
- 0x0550, /* #x14F0 Armenian_RE */
- 0x0580, /* #x14F1 Armenian_re */
- 0x0551, /* #x14F2 Armenian_TSO */
- 0x0581, /* #x14F3 Armenian_tso */
- 0x0552, /* #x14F4 Armenian_VYUN */
- 0x0582, /* #x14F5 Armenian_vyun */
- 0x0553, /* #x14F6 Armenian_PYUR */
- 0x0583, /* #x14F7 Armenian_pyur */
- 0x0554, /* #x14F8 Armenian_KE */
- 0x0584, /* #x14F9 Armenian_ke */
- 0x0555, /* #x14FA Armenian_O */
- 0x0585, /* #x14FB Armenian_o */
- 0x0556, /* #x14FC Armenian_FE */
- 0x0586, /* #x14FD Armenian_fe */
- 0x055a, /* #x14FE Armenian_apostrophe */
- 0x00a7, /* #x14FF Armenian_section_sign */
- };
-
-static UINT_16_BIT const GEORGIAN[] =
- {
-#define FIRST_KNOWN_GEORGIAN 0x15D0
- 0x10d0, /* #x15D0 Georgian_an */
- 0x10d1, /* #x15D1 Georgian_ban */
- 0x10d2, /* #x15D2 Georgian_gan */
- 0x10d3, /* #x15D3 Georgian_don */
- 0x10d4, /* #x15D4 Georgian_en */
- 0x10d5, /* #x15D5 Georgian_vin */
- 0x10d6, /* #x15D6 Georgian_zen */
- 0x10d7, /* #x15D7 Georgian_tan */
- 0x10d8, /* #x15D8 Georgian_in */
- 0x10d9, /* #x15D9 Georgian_kan */
- 0x10da, /* #x15DA Georgian_las */
- 0x10db, /* #x15DB Georgian_man */
- 0x10dc, /* #x15DC Georgian_nar */
- 0x10dd, /* #x15DD Georgian_on */
- 0x10de, /* #x15DE Georgian_par */
- 0x10df, /* #x15DF Georgian_zhar */
- 0x10e0, /* #x15E0 Georgian_rae */
- 0x10e1, /* #x15E1 Georgian_san */
- 0x10e2, /* #x15E2 Georgian_tar */
- 0x10e3, /* #x15E3 Georgian_un */
- 0x10e4, /* #x15E4 Georgian_phar */
- 0x10e5, /* #x15E5 Georgian_khar */
- 0x10e6, /* #x15E6 Georgian_ghan */
- 0x10e7, /* #x15E7 Georgian_qar */
- 0x10e8, /* #x15E8 Georgian_shin */
- 0x10e9, /* #x15E9 Georgian_chin */
- 0x10ea, /* #x15EA Georgian_can */
- 0x10eb, /* #x15EB Georgian_jil */
- 0x10ec, /* #x15EC Georgian_cil */
- 0x10ed, /* #x15ED Georgian_char */
- 0x10ee, /* #x15EE Georgian_xan */
- 0x10ef, /* #x15EF Georgian_jhan */
- 0x10f0, /* #x15F0 Georgian_hae */
- 0x10f1, /* #x15F1 Georgian_he */
- 0x10f2, /* #x15F2 Georgian_hie */
- 0x10f3, /* #x15F3 Georgian_we */
- 0x10f4, /* #x15F4 Georgian_har */
- 0x10f5, /* #x15F5 Georgian_hoe */
- 0x10f6, /* #x15F6 Georgian_fi */
- };
-
-static UINT_16_BIT const AZERI_ETC[] =
- {
-#define FIRST_KNOWN_AZERI_ETC 0x16A2
- 0x0000, /* #x16A2 Ccedillaabovedot */
- 0x1e8a, /* #x16A3 Xabovedot */
- 0x0000, /* #x16A4 */
- 0x0000, /* #x16A5 Qabovedot */
- 0x012c, /* #x16A6 Ibreve */
- 0x0000, /* #x16A7 IE */
- 0x0000, /* #x16A8 UO */
- 0x01b5, /* #x16A9 Zstroke */
- 0x01e6, /* #x16AA Gcaron */
- 0x0000, /* #x16AB */
- 0x0000, /* #x16AC */
- 0x0000, /* #x16AD */
- 0x0000, /* #x16AE */
- 0x019f, /* #x16AF Obarred */
- 0x0000, /* #x16B0 */
- 0x0000, /* #x16B1 */
- 0x0000, /* #x16B2 ccedillaabovedot */
- 0x1e8b, /* #x16B3 xabovedot */
- 0x0000, /* #x16B4 Ocaron */
- 0x0000, /* #x16B5 qabovedot */
- 0x012d, /* #x16B6 ibreve */
- 0x0000, /* #x16B7 ie */
- 0x0000, /* #x16B8 uo */
- 0x01b6, /* #x16B9 zstroke */
- 0x01e7, /* #x16BA gcaron */
- 0x0000, /* #x16BB */
- 0x0000, /* #x16BC */
- 0x01d2, /* #x16BD ocaron */
- 0x0000, /* #x16BE */
- 0x0275, /* #x16BF obarred */
- 0x0000, /* #x16C0 */
- 0x0000, /* #x16C1 */
- 0x0000, /* #x16C2 */
- 0x0000, /* #x16C3 */
- 0x0000, /* #x16C4 */
- 0x0000, /* #x16C5 */
- 0x018f, /* #x16C6 SCHWA */
- 0x0000, /* #x16C7 */
- 0x0000, /* #x16C8 */
- 0x0000, /* #x16C9 */
- 0x0000, /* #x16CA */
- 0x0000, /* #x16CB */
- 0x0000, /* #x16CC */
- 0x0000, /* #x16CD */
- 0x0000, /* #x16CE */
- 0x0000, /* #x16CF */
- 0x0000, /* #x16D0 */
- 0x1e36, /* #x16D1 Lbelowdot */
- 0x0000, /* #x16D2 Lstrokebelowdot */
- 0x0000, /* #x16D3 Gtilde */
- 0x0000, /* #x16D4 */
- 0x0000, /* #x16D5 */
- 0x0000, /* #x16D6 */
- 0x0000, /* #x16D7 */
- 0x0000, /* #x16D8 */
- 0x0000, /* #x16D9 */
- 0x0000, /* #x16DA */
- 0x0000, /* #x16DB */
- 0x0000, /* #x16DC */
- 0x0000, /* #x16DD */
- 0x0000, /* #x16DE */
- 0x0000, /* #x16DF */
- 0x0000, /* #x16E0 */
- 0x1e37, /* #x16E1 lbelowdot */
- 0x0000, /* #x16E2 lstrokebelowdot */
- 0x0000, /* #x16E3 gtilde */
- 0x0000, /* #x16E4 */
- 0x0000, /* #x16E5 */
- 0x0000, /* #x16E6 */
- 0x0000, /* #x16E7 */
- 0x0000, /* #x16E8 */
- 0x0000, /* #x16E9 */
- 0x0000, /* #x16EA */
- 0x0000, /* #x16EB */
- 0x0000, /* #x16EC */
- 0x0000, /* #x16ED */
- 0x0000, /* #x16EE */
- 0x0000, /* #x16EF */
- 0x0000, /* #x16F0 */
- 0x0000, /* #x16F1 */
- 0x0000, /* #x16F2 */
- 0x0000, /* #x16F3 */
- 0x0000, /* #x16F4 */
- 0x0000, /* #x16F5 */
- 0x0259, /* #x16F6 schwa */
- };
-
-static UINT_16_BIT const VIETNAMESE[] =
- {
-#define FIRST_KNOWN_VIETNAMESE 0x1E9F
- 0x0303, /* #x1E9F combining_tilde */
- 0x1ea0, /* #x1EA0 Abelowdot */
- 0x1ea1, /* #x1EA1 abelowdot */
- 0x1ea2, /* #x1EA2 Ahook */
- 0x1ea3, /* #x1EA3 ahook */
- 0x1ea4, /* #x1EA4 Acircumflexacute */
- 0x1ea5, /* #x1EA5 acircumflexacute */
- 0x1ea6, /* #x1EA6 Acircumflexgrave */
- 0x1ea7, /* #x1EA7 acircumflexgrave */
- 0x1ea8, /* #x1EA8 Acircumflexhook */
- 0x1ea9, /* #x1EA9 acircumflexhook */
- 0x1eaa, /* #x1EAA Acircumflextilde */
- 0x1eab, /* #x1EAB acircumflextilde */
- 0x1eac, /* #x1EAC Acircumflexbelowdot */
- 0x1ead, /* #x1EAD acircumflexbelowdot */
- 0x1eae, /* #x1EAE Abreveacute */
- 0x1eaf, /* #x1EAF abreveacute */
- 0x1eb0, /* #x1EB0 Abrevegrave */
- 0x1eb1, /* #x1EB1 abrevegrave */
- 0x1eb2, /* #x1EB2 Abrevehook */
- 0x1eb3, /* #x1EB3 abrevehook */
- 0x1eb4, /* #x1EB4 Abrevetilde */
- 0x1eb5, /* #x1EB5 abrevetilde */
- 0x1eb6, /* #x1EB6 Abrevebelowdot */
- 0x1eb7, /* #x1EB7 abrevebelowdot */
- 0x1eb8, /* #x1EB8 Ebelowdot */
- 0x1eb9, /* #x1EB9 ebelowdot */
- 0x1eba, /* #x1EBA Ehook */
- 0x1ebb, /* #x1EBB ehook */
- 0x1ebc, /* #x1EBC Etilde */
- 0x1ebd, /* #x1EBD etilde */
- 0x1ebe, /* #x1EBE Ecircumflexacute */
- 0x1ebf, /* #x1EBF ecircumflexacute */
- 0x1ec0, /* #x1EC0 Ecircumflexgrave */
- 0x1ec1, /* #x1EC1 ecircumflexgrave */
- 0x1ec2, /* #x1EC2 Ecircumflexhook */
- 0x1ec3, /* #x1EC3 ecircumflexhook */
- 0x1ec4, /* #x1EC4 Ecircumflextilde */
- 0x1ec5, /* #x1EC5 ecircumflextilde */
- 0x1ec6, /* #x1EC6 Ecircumflexbelowdot */
- 0x1ec7, /* #x1EC7 ecircumflexbelowdot */
- 0x1ec8, /* #x1EC8 Ihook */
- 0x1ec9, /* #x1EC9 ihook */
- 0x1eca, /* #x1ECA Ibelowdot */
- 0x1ecb, /* #x1ECB ibelowdot */
- 0x1ecc, /* #x1ECC Obelowdot */
- 0x1ecd, /* #x1ECD obelowdot */
- 0x1ece, /* #x1ECE Ohook */
- 0x1ecf, /* #x1ECF ohook */
- 0x1ed0, /* #x1ED0 Ocircumflexacute */
- 0x1ed1, /* #x1ED1 ocircumflexacute */
- 0x1ed2, /* #x1ED2 Ocircumflexgrave */
- 0x1ed3, /* #x1ED3 ocircumflexgrave */
- 0x1ed4, /* #x1ED4 Ocircumflexhook */
- 0x1ed5, /* #x1ED5 ocircumflexhook */
- 0x1ed6, /* #x1ED6 Ocircumflextilde */
- 0x1ed7, /* #x1ED7 ocircumflextilde */
- 0x1ed8, /* #x1ED8 Ocircumflexbelowdot */
- 0x1ed9, /* #x1ED9 ocircumflexbelowdot */
- 0x1eda, /* #x1EDA Ohornacute */
- 0x1edb, /* #x1EDB ohornacute */
- 0x1edc, /* #x1EDC Ohorngrave */
- 0x1edd, /* #x1EDD ohorngrave */
- 0x1ede, /* #x1EDE Ohornhook */
- 0x1edf, /* #x1EDF ohornhook */
- 0x1ee0, /* #x1EE0 Ohorntilde */
- 0x1ee1, /* #x1EE1 ohorntilde */
- 0x1ee2, /* #x1EE2 Ohornbelowdot */
- 0x1ee3, /* #x1EE3 ohornbelowdot */
- 0x1ee4, /* #x1EE4 Ubelowdot */
- 0x1ee5, /* #x1EE5 ubelowdot */
- 0x1ee6, /* #x1EE6 Uhook */
- 0x1ee7, /* #x1EE7 uhook */
- 0x1ee8, /* #x1EE8 Uhornacute */
- 0x1ee9, /* #x1EE9 uhornacute */
- 0x1eea, /* #x1EEA Uhorngrave */
- 0x1eeb, /* #x1EEB uhorngrave */
- 0x1eec, /* #x1EEC Uhornhook */
- 0x1eed, /* #x1EED uhornhook */
- 0x1eee, /* #x1EEE Uhorntilde */
- 0x1eef, /* #x1EEF uhorntilde */
- 0x1ef0, /* #x1EF0 Uhornbelowdot */
- 0x1ef1, /* #x1EF1 uhornbelowdot */
- 0x0300, /* #x1EF2 combining_grave */
- 0x0301, /* #x1EF3 combining_acute */
- 0x1ef4, /* #x1EF4 Ybelowdot */
- 0x1ef5, /* #x1EF5 ybelowdot */
- 0x1ef6, /* #x1EF6 Yhook */
- 0x1ef7, /* #x1EF7 yhook */
- 0x1ef8, /* #x1EF8 Ytilde */
- 0x1ef9, /* #x1EF9 ytilde */
-
- 0x01a0, /* #x1EFA Ohorn */
- 0x01a1, /* #x1EFB ohorn */
- 0x01af, /* #x1EFC Uhorn */
- 0x01b0, /* #x1EFD uhorn */
-
- 0x0309, /* #x1EFE combining_hook */
- 0x0323, /* #x1EFF combining_belowdot */
- };
-#endif /* MULE */
-
-static UINT_16_BIT const CYRILLIC[] =
- {
- 0x0452, /* #x06A1 CYRILLIC SMALL LETTER DJE */
-#define FIRST_KNOWN_CYRILLIC 0x6A1
- 0x0453, /* #x06A2 CYRILLIC SMALL LETTER GJE */
- 0x0451, /* #x06A3 CYRILLIC SMALL LETTER IO */
- 0x0454, /* #x06A4 CYRILLIC SMALL LETTER UKRAINIAN IE */
- 0x0455, /* #x06A5 CYRILLIC SMALL LETTER DZE */
- 0x0456, /* #x06A6 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
- 0x0457, /* #x06A7 CYRILLIC SMALL LETTER YI */
- 0x0458, /* #x06A8 CYRILLIC SMALL LETTER JE */
- 0x0459, /* #x06A9 CYRILLIC SMALL LETTER LJE */
- 0x045A, /* #x06AA CYRILLIC SMALL LETTER NJE */
- 0x045B, /* #x06AB CYRILLIC SMALL LETTER TSHE */
- 0x045C, /* #x06AC CYRILLIC SMALL LETTER KJE */
- 0x0491, /* #x06AD CYRILLIC SMALL LETTER GHE WITH UPTURN */
- 0x045E, /* #x06AE CYRILLIC SMALL LETTER SHORT U */
- 0x045F, /* #x06AF CYRILLIC SMALL LETTER DZHE */
- 0x2116, /* #x06B0 NUMERO SIGN */
- 0x0402, /* #x06B1 CYRILLIC CAPITAL LETTER DJE */
- 0x0403, /* #x06B2 CYRILLIC CAPITAL LETTER GJE */
- 0x0401, /* #x06B3 CYRILLIC CAPITAL LETTER IO */
- 0x0404, /* #x06B4 CYRILLIC CAPITAL LETTER UKRAINIAN IE */
- 0x0405, /* #x06B5 CYRILLIC CAPITAL LETTER DZE */
- 0x0406, /* #x06B6 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
- 0x0407, /* #x06B7 CYRILLIC CAPITAL LETTER YI */
- 0x0408, /* #x06B8 CYRILLIC CAPITAL LETTER JE */
- 0x0409, /* #x06B9 CYRILLIC CAPITAL LETTER LJE */
- 0x040A, /* #x06BA CYRILLIC CAPITAL LETTER NJE */
- 0x040B, /* #x06BB CYRILLIC CAPITAL LETTER TSHE */
- 0x040C, /* #x06BC CYRILLIC CAPITAL LETTER KJE */
- 0x0490, /* #x06BD CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
- 0x040E, /* #x06BE CYRILLIC CAPITAL LETTER SHORT U */
- 0x040F, /* #x06BF CYRILLIC CAPITAL LETTER DZHE */
- 0x044E, /* #x06C0 CYRILLIC SMALL LETTER YU */
- 0x0430, /* #x06C1 CYRILLIC SMALL LETTER A */
- 0x0431, /* #x06C2 CYRILLIC SMALL LETTER BE */
- 0x0446, /* #x06C3 CYRILLIC SMALL LETTER TSE */
- 0x0434, /* #x06C4 CYRILLIC SMALL LETTER DE */
- 0x0435, /* #x06C5 CYRILLIC SMALL LETTER IE */
- 0x0444, /* #x06C6 CYRILLIC SMALL LETTER EF */
- 0x0433, /* #x06C7 CYRILLIC SMALL LETTER GHE */
- 0x0445, /* #x06C8 CYRILLIC SMALL LETTER HA */
- 0x0438, /* #x06C9 CYRILLIC SMALL LETTER I */
- 0x0439, /* #x06CA CYRILLIC SMALL LETTER SHORT I */
- 0x043A, /* #x06CB CYRILLIC SMALL LETTER KA */
- 0x043B, /* #x06CC CYRILLIC SMALL LETTER EL */
- 0x043C, /* #x06CD CYRILLIC SMALL LETTER EM */
- 0x043D, /* #x06CE CYRILLIC SMALL LETTER EN */
- 0x043E, /* #x06CF CYRILLIC SMALL LETTER O */
- 0x043F, /* #x06D0 CYRILLIC SMALL LETTER PE */
- 0x044F, /* #x06D1 CYRILLIC SMALL LETTER YA */
- 0x0440, /* #x06D2 CYRILLIC SMALL LETTER ER */
- 0x0441, /* #x06D3 CYRILLIC SMALL LETTER ES */
- 0x0442, /* #x06D4 CYRILLIC SMALL LETTER TE */
- 0x0443, /* #x06D5 CYRILLIC SMALL LETTER U */
- 0x0436, /* #x06D6 CYRILLIC SMALL LETTER ZHE */
- 0x0432, /* #x06D7 CYRILLIC SMALL LETTER VE */
- 0x044C, /* #x06D8 CYRILLIC SMALL LETTER SOFT SIGN */
- 0x044B, /* #x06D9 CYRILLIC SMALL LETTER YERU */
- 0x0437, /* #x06DA CYRILLIC SMALL LETTER ZE */
- 0x0448, /* #x06DB CYRILLIC SMALL LETTER SHA */
- 0x044D, /* #x06DC CYRILLIC SMALL LETTER E */
- 0x0449, /* #x06DD CYRILLIC SMALL LETTER SHCHA */
- 0x0447, /* #x06DE CYRILLIC SMALL LETTER CHE */
- 0x044A, /* #x06DF CYRILLIC SMALL LETTER HARD SIGN */
- 0x042E, /* #x06E0 CYRILLIC CAPITAL LETTER YU */
- 0x0410, /* #x06E1 CYRILLIC CAPITAL LETTER A */
- 0x0411, /* #x06E2 CYRILLIC CAPITAL LETTER BE */
- 0x0426, /* #x06E3 CYRILLIC CAPITAL LETTER TSE */
- 0x0414, /* #x06E4 CYRILLIC CAPITAL LETTER DE */
- 0x0415, /* #x06E5 CYRILLIC CAPITAL LETTER IE */
- 0x0424, /* #x06E6 CYRILLIC CAPITAL LETTER EF */
- 0x0413, /* #x06E7 CYRILLIC CAPITAL LETTER GHE */
- 0x0425, /* #x06E8 CYRILLIC CAPITAL LETTER HA */
- 0x0418, /* #x06E9 CYRILLIC CAPITAL LETTER I */
- 0x0419, /* #x06EA CYRILLIC CAPITAL LETTER SHORT I */
- 0x041A, /* #x06EB CYRILLIC CAPITAL LETTER KA */
- 0x041B, /* #x06EC CYRILLIC CAPITAL LETTER EL */
- 0x041C, /* #x06ED CYRILLIC CAPITAL LETTER EM */
- 0x041D, /* #x06EE CYRILLIC CAPITAL LETTER EN */
- 0x041E, /* #x06EF CYRILLIC CAPITAL LETTER O */
- 0x041F, /* #x06F0 CYRILLIC CAPITAL LETTER PE */
- 0x042F, /* #x06F1 CYRILLIC CAPITAL LETTER YA */
- 0x0420, /* #x06F2 CYRILLIC CAPITAL LETTER ER */
- 0x0421, /* #x06F3 CYRILLIC CAPITAL LETTER ES */
- 0x0422, /* #x06F4 CYRILLIC CAPITAL LETTER TE */
- 0x0423, /* #x06F5 CYRILLIC CAPITAL LETTER U */
- 0x0416, /* #x06F6 CYRILLIC CAPITAL LETTER ZHE */
- 0x0412, /* #x06F7 CYRILLIC CAPITAL LETTER VE */
- 0x042C, /* #x06F8 CYRILLIC CAPITAL LETTER SOFT SIGN */
- 0x042B, /* #x06F9 CYRILLIC CAPITAL LETTER YERU */
- 0x0417, /* #x06FA CYRILLIC CAPITAL LETTER ZE */
- 0x0428, /* #x06FB CYRILLIC CAPITAL LETTER SHA */
- 0x042D, /* #x06FC CYRILLIC CAPITAL LETTER E */
- 0x0429, /* #x06FD CYRILLIC CAPITAL LETTER SHCHA */
- 0x0427, /* #x06FE CYRILLIC CAPITAL LETTER CHE */
- 0x042A, /* #x06FF CYRILLIC CAPITAL LETTER HARD SIGN */
- };
-
-/* For every key on the keyboard that has a known character correspondence,
- we define the character-of-keysym property of its XEmacs keysym, and make
- the default binding for the key be self-insert-command.
-
- The following magic is based on intimate knowledge of some of
- X11/keysymdef.h. The keysym mappings defined by X11 are based on the
- iso8859 standards, except for Cyrillic and Greek.
-
- In a non-Mule world, a user can still have a multi-lingual editor, by
- doing (set-face-font "...-iso8859-2" (current-buffer)) for all their
- Latin-2 buffers, etc. and the X11 keysyms corresponding to characters in
- those character sets will still do the right thing (because of the
- make_char (code + 0x80) non-Mule case below.) Of course, X11 keysyms in
- other character sets will not do the right thing, because XEmacs won't
- support the right thing.
-
- This code is also called when a command lookup is about to fail, and the
- X11 platform code has worked out that it previously wasn't aware the
- keysym of that command could be generated by the user's keyboard; in that
- case, we bind its XEmacs keysym to self-insert-command if it has a
- character correspondence we know about, and tell the general event code
- that we've done so, so it can try the lookup again.
-
- Called from the GTK code because GTK 1 has no defined way of doing the
- same thing, and this works for it on X11. It should be moved back into
- event-Xt.c when and if the GTK port moves to GTK 2. */
-
-#ifndef THIS_IS_GTK
-static Lisp_Object
-x_keysym_to_character (KeySym keysym)
-#else
-Lisp_Object
-gtk_keysym_to_character (guint keysym)
-#endif
-{
-#ifdef MULE
- Lisp_Object charset = Qzero;
- int code = 0;
-#endif /* MULE */
-
- /* @@#### Add support for 0xFE?? and 0xFF?? keysyms
- Add support for KOI8-U extensions in the 0x06?? range
-
- See
http://www.cl.cam.ac.uk/~mgk25/ucs/keysyms.txt
- */
-
- /* Markus Kuhn's spec says keysyms in the range #x01000100 to #x0110FFFF
- and only those should correspond directly to Unicode code points, in
- the range #x100-#x10FFFF; actual implementations can have the Latin 1
- code points do the same thing with keysyms
- #x01000000-#x01000100. */
-
-#ifndef MULE
- if (keysym >= 0x01000000 && keysym <= 0x010000FF)
- return make_char (keysym & 0xFFFFFF);
-#else
- if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
- return make_char (buffer_unicode_to_ichar
- ((int) (keysym & 0xFFFFFF),
- /* @@#### need to get some sort of buffer to compute
- this off; only applies in the old-Mule world */
- current_buffer, CONVERR_SUCCEED));
-#endif /* not MULE */
-
- if ((keysym & 0xff) < 0xa0)
- return Qnil;
-
-#ifdef MULE
- switch (keysym >> 8)
- {
- case 0: /* ASCII + Latin1 */
- charset = Vcharset_latin_iso8859_1;
- code = keysym & 0xff;
- break;
- case 1: /* Latin2 */
- charset = Vcharset_latin_iso8859_2;
- code = keysym & 0xff;
- break;
- case 2: /* Latin3 */
- charset = Vcharset_latin_iso8859_3;
- code = keysym & 0xff;
- break;
- case 3: /* Latin4 */
- charset = Vcharset_latin_iso8859_4;
- code = keysym & 0xff;
- break;
- case 4: /* Katakana */
- charset = Vcharset_katakana_jisx0201;
- if ((keysym & 0xff) > 0xa0)
- code = keysym & 0xff;
- break;
- case 5: /* Arabic */
- charset = Vcharset_arabic_iso8859_6;
- code = keysym & 0xff;
- break;
- case 6: /* Cyrillic */
- {
- USE_UNICODE_MAP (keysym, CYRILLIC);
- break;
- }
- case 7: /* Greek */
- {
- static UExtbyte const greek[] = /* 0xa0 - 0xff */
- {0x00, 0xb6, 0xb8, 0xb9, 0xba, 0xda, 0x00, 0xbc,
- 0xbe, 0xdb, 0x00, 0xbf, 0x00, 0x00, 0xb5, 0xaf,
- 0x00, 0xdc, 0xdd, 0xde, 0xdf, 0xfa, 0xc0, 0xfc,
- 0xfd, 0xfb, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd3, 0x00, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf3, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- charset = Vcharset_greek_iso8859_7;
- code = greek[(keysym & 0x7f) - 0x20];
- break;
- }
- case 8:
- USE_UNICODE_MAP (keysym, TECHNICAL);
- break;
- case 9:
- USE_UNICODE_MAP (keysym, SPECIAL);
- break;
- case 10:
- USE_UNICODE_MAP (keysym, PUBLISHING);
- break;
- case 11:
- USE_UNICODE_MAP (keysym, APL);
- break;
- case 12: /* Hebrew */
- charset = Vcharset_hebrew_iso8859_8;
- code = keysym & 0xff;
- break;
- case 13: /* Thai */
- /* #### This needs to deal with character composition.
- Are you sure we can't leave it to the X server? */
- charset = Vcharset_thai_tis620;
- code = keysym & 0xff;
- break;
- case 14: /* Korean Hangul. */
- USE_UNICODE_MAP (keysym, HANGUL);
- break;
- case 18: /* Latin 8 - ISO8859-14. */
- charset = Ffind_charset (intern ("latin-iso8859-14"));
- code = keysym & 0xff;
- break;
- case 19: /* Latin 9 - ISO8859-15. */
- charset = Vcharset_latin_iso8859_15;
- code = keysym & 0xff;
- break;
- case 20: /* Armenian. */
- USE_UNICODE_MAP (keysym, ARMENIAN);
- break;
- case 21: /* Georgian. */
- USE_UNICODE_MAP (keysym, GEORGIAN);
- break;
- case 22: /* Azeri (and other Turkic or Caucasian languages of ex-USSR) */
- USE_UNICODE_MAP (keysym, AZERI_ETC);
- break;
- case 30: /* Vietnamese */
- USE_UNICODE_MAP (keysym, VIETNAMESE);
- break;
- case 32: /* Currency. The lower sixteen bits of these keysyms happily
- correspond exactly to the Unicode code points of the
- associated characters */
- return make_char (buffer_unicode_to_ichar
- ((int) (keysym & 0xffff),
- /* @@#### need to get some sort of buffer to
- compute this off; only applies in the old-Mule
- world */
- current_buffer, CONVERR_SUCCEED));
-
-/* @@#### Support me!
-
- Actually, these are somewhat already supported by x-init.el/x-compose.el,
- but only acute, grave, circum(flex), cedilla, diaeresis, tilde. We
- should try to eliminate that code and use general Unicode support for
- converting to precomposed sequences.
-
-0xfe50 U0300 f # dead_grave
-0xfe51 U0301 f # dead_acute
-0xfe52 U0302 f # dead_circumflex
-0xfe53 U0303 f # dead_tilde
-0xfe54 U0304 f # dead_macron
-0xfe55 U0306 f # dead_breve
-0xfe56 U0307 f # dead_abovedot
-0xfe57 U0308 f # dead_diaeresis
-0xfe58 U030a f # dead_abovering
-0xfe59 U030b f # dead_doubleacute
-0xfe5a U030c f # dead_caron
-0xfe5b U0327 f # dead_cedilla
-0xfe5c U0328 f # dead_ogonek
-0xfe5d U0345 f # dead_iota
-0xfe5e U3099 f # dead_voiced_sound
-0xfe5f U309a f # dead_semivoiced_sound
-0xfe60 U0323 f # dead_belowdot
-0xfe61 U0309 f # dead_hook
-0xfe62 U031b f # dead_horn
-
-What about these? We don't have to convert these to ASCII but make sure we
-Handle all of the KP-foo things and get them to behave like plain foo when
-KP-foo isn't bound (which includes self-inserting the associated character
-if necessary). DOCUMENT the existing system that does this.
-
-0xff08 U0008 f # BackSpace /- back space, back char -/
-0xff09 U0009 f # Tab
-0xff0a U000a f # Linefeed /- Linefeed, LF -/
-0xff0b U000b f # Clear
-0xff0d U000d f # Return /- Return, enter -/
-0xff13 U0013 f # Pause /- Pause, hold -/
-0xff14 U0014 f # Scroll_Lock
-0xff15 U0015 f # Sys_Req
-0xff1b U001b f # Escape
-0xff80 U0020 f # KP_Space /- space -/
-0xff89 U0009 f # KP_Tab
-0xff8d U000d f # KP_Enter /- enter -/
-0xffaa U002a f # KP_Multiply
-0xffab U002b f # KP_Add
-0xffac U002c f # KP_Separator /- separator, often comma -/
-0xffad U002d f # KP_Subtract
-0xffae U002e f # KP_Decimal
-0xffaf U002f f # KP_Divide
-0xffb0 U0030 f # KP_0
-0xffb1 U0031 f # KP_1
-0xffb2 U0032 f # KP_2
-0xffb3 U0033 f # KP_3
-0xffb4 U0034 f # KP_4
-0xffb5 U0035 f # KP_5
-0xffb6 U0036 f # KP_6
-0xffb7 U0037 f # KP_7
-0xffb8 U0038 f # KP_8
-0xffb9 U0039 f # KP_9
-0xffbd U003d f # KP_Equal /- equals -/
-*/
- default:
- break;
- }
-
- if (code == 0)
- return Qnil;
-
- /* #### Is this check on !NILP (charset) needed? Maybe should be assert? */
- if (!NILP (charset))
- {
- /* First try to generate a unified character by converting through
- Unicode, then try converting directly to an Ichar (only matters
- when non-Unicode-internal, else we get same results both ways). */
- int ucs = charset_codepoint_to_unicode (charset, 0, code, CONVERR_FAIL);
- if (ucs >= 0)
- {
- /* @@#### current_buffer dependency */
- Ichar ich = buffer_unicode_to_ichar (ucs, current_buffer,
- CONVERR_FAIL);
- if (ich >= 0)
- return make_char (ich);
- }
- else
- {
- Ichar ich =
- charset_codepoint_to_ichar (charset, 0, code, CONVERR_FAIL);
- if (ich >= 0)
- return make_char (ich);
- }
- }
- return Qnil;
-#else /* not MULE */
- if (keysym >= 0x100)
- return Qnil;
- return make_char (keysym);
-#endif /* (not) MULE */
-}
-
-#endif /* defined (THIS_IS_X) || !defined (__GDK_KEYS_H__) */
diff -r 9bdc40b8fb78 -r a5b21ebab055 src/redisplay-gtk.c
--- a/src/redisplay-gtk.c Sun Dec 17 12:20:06 2017 +0000
+++ b/src/redisplay-gtk.c Mon Dec 18 22:04:46 2017 +0000
@@ -875,6 +875,40 @@
#endif
}
+/*****************************************************************************
+ gtk_output_string
+
+ Given a string and a starting position, output that string in the
+ given face. If cursor is true, draw a cursor around the string.
+ Correctly handles multiple charsets in the string.
+
+ The meaning of the parameters is something like this:
+
+ W Window that the text is to be displayed in.
+ DL Display line that this text is on. The values in the
+ structure are used to determine the vertical position and
+ clipping range of the text.
+ BUF Pointer to those Ibytes to be output.
+ LEN Number of those Ibytes to be output
+ XPOS X position in pixels where the text should start being drawn.
+ XOFFSET Number of pixels to be chopped off the left side of the
+ text. The effect is as if the text were shifted to the
+ left this many pixels and clipped at XPOS.
+ CLIP_START Clip everything left of this X position.
+ WIDTH Clip everything right of XPOS + WIDTH.
+ FINDEX Index for the face cache element describing how to display
+ the text.
+ CURSOR #### I don't understand this. There's something
+ strange and overcomplexified with this variable.
+ Chuck, explain please?
+ CURSOR_START Starting X position of cursor.
+ CURSOR_WIDTH Width of cursor in pixels.
+ CURSOR_HEIGHT Height of cursor in pixels.
+
+ Starting Y position of cursor is the top of the text line.
+ The cursor is drawn sometimes whether or not CURSOR is set. ???
+ ****************************************************************************/
+
void
gtk_output_string (struct window *w, struct display_line *dl,
const Ibyte *buf, Bytecount len,
diff -r 9bdc40b8fb78 -r a5b21ebab055 src/redisplay-x.c
--- a/src/redisplay-x.c Sun Dec 17 12:20:06 2017 +0000
+++ b/src/redisplay-x.c Mon Dec 18 22:04:46 2017 +0000
@@ -32,29 +32,466 @@
#define THIS_IS_X
#include "redisplay-xlike-inc.c"
-/*
- XLIKE_text_width
+/****************************************************************************/
+/* */
+/* Separate textual runs */
+/* */
+/****************************************************************************/
+
+
+/* Note: We do not use the Xmb*() functions and XFontSets, nor the Motif
+ XFontLists and CompoundStrings. Those functions are generally losing for a
+ number of reasons. Most important, they only support one locale (e.g. you
+ could display Japanese and ASCII text, but not mixed Japanese/Chinese
+ text). You could maybe call setlocale() frequently to try to deal with
+ this, but that would generally fail because an XFontSet is tied to one
+ locale and won't have the other character sets in it.
+
+ fontconfig (the font database for Xft) has some specifier-like properties,
+ but it's not sufficient (witness the existence of Pango). Pango might do
+ the trick, but it's not a cross-platform solution; it would need
+ significant advantages to be worth the effort. */
+
+struct textual_run
+{
+ Lisp_Object charset;
+ Extbyte *ptr;
+ int len;
+ int dimension;
+};
- Given a string and a merged face, return the string's length in pixels
- when displayed in the fonts associated with the face.
+/* Separate out the text in STR of length LEN into a series of runs, stored in
+ RUN_STORAGE. RUN_STORAGE is guaranteed to hold enough space for all runs
+ that could be generated from this text. Each run points to the a stretch
+ of text given simply by the position codes TEXT_STORAGE into a series of
+ textual runs of a particular charset. Also convert the characters as
+ necessary into the format needed by XDrawImageString(),
+ XDrawImageString16(), et al. This means converting to one or two byte
+ format, possibly tweaking the high bits, and possibly running a CCL
+ program. You must pre-allocate the space used and pass in a pointer,
+ TEXT_STORAGE, and the ALLOCATE_RUNS_TEXT () macro is provided to do this
+ using stack space. Some of the window-system-specific implementations take
+ advantage of this step to do coding sytem translation, and the specific
+ amount of space needed depends on the window system.
+
+ bufchar might not be fixed width (in the case of UTF-8).
+
+ Returns the number of runs actually used. */
+
+/* Notes on Xft implementation
+
+ - With Unicode, we're no longer going to have repertoires reified as
+ charsets. (Not that we ever really did, what with corporate variants,
+ and so on.) So we really should be querying the face for the desired
+ font, rather than the character for the charset, and that's what would
+ determine the separation into runs.
+ - The widechar versions of fontconfig (and therefore Xft) functions
+ seem to be just bigendian Unicode. So there's actually no need to use
+ the 8-bit versions in computing runs and runes, it would seem.
*/
+#if !defined (USE_XFT) && !defined (MULE)
+
+#define ALLOCATE_RUNS_TEXT(storage, storage_len, str, len) \
+ (storage = alloca_extbytes (len))
+
static int
-XLIKE_text_width (struct frame *f, struct face_cachel *cachel,
- const Ichar *str, Charcount len)
+separate_textual_runs_nomule (struct buffer * UNUSED (buf),
+ Extbyte *text_storage,
+ struct textual_run *run_storage,
+ const Ibyte *str, Bytecount len,
+ struct face_cachel *UNUSED(cachel))
+{
+ if (!len)
+ return 0;
+
+ run_storage[0].ptr = text_storage;
+ run_storage[0].len = len;
+ run_storage[0].dimension = 1;
+ run_storage[0].charset = Qnil;
+
+ memcpy (text_storage, str, len);
+
+ return 1;
+}
+#endif
+
+#ifdef USE_XFT
+#ifdef WORDS_BIGENDIAN
+#define ALLOCATE_RUNS_TEXT(storage, storage_len, str, len) \
+ TO_EXTERNAL_FORMAT (DATA, (str, len), \
+ ALLOCA, (storage, storage_len), \
+ Qutf_16)
+#else
+extern Lisp_Object Qutf_16_little_endian;
+#define ALLOCATE_RUNS_TEXT(storage, storage_len, str, len) \
+ TO_EXTERNAL_FORMAT (DATA, (str, len), \
+ ALLOCA, (storage, storage_len), \
+ Qutf_16_little_endian)
+#endif
+#endif /* USE_XFT */
+
+#if defined (USE_XFT) && !defined (MULE)
+/*
+ Note that in this configuration the "Croatian hack" of using an 8-bit,
+ non-Latin-1 font to get localized display without Mule simply isn't
+ available. That's by design -- Unicode does not aid or abet that kind
+ of punning.
+ This means that the cast to XftChar16 gives the correct "conversion" to
+ UCS-2. */
+static int
+separate_textual_runs_xft_nomule (struct buffer * UNUSED (buf),
+ Extbyte *text_storage,
+ struct textual_run *run_storage,
+ const Ibyte *str, Bytecount len,
+ struct face_cachel *UNUSED (cachel))
+{
+ int i;
+ if (!len)
+ return 0;
+
+ run_storage[0].ptr = text_storage;
+ run_storage[0].len = len;
+ run_storage[0].dimension = 2;
+ run_storage[0].charset = Qnil;
+
+ return 1;
+}
+#endif
+
+#if defined (USE_XFT) && defined (MULE)
+static int
+separate_textual_runs_xft_mule (struct buffer *buf,
+ Extbyte *text_storage,
+ struct textual_run *run_storage,
+ const Ibyte *str, Bytecount len,
+ struct face_cachel *UNUSED (cachel))
+{
+ Lisp_Object prev_charset = Qunbound;
+ const Ibyte *end = str + len;
+ Elemcount runs_so_far = 0;
+
+ run_storage[0].ptr = text_storage;
+ run_storage[0].len = len;
+ run_storage[0].dimension = 2;
+ run_storage[0].charset = Qnil;
+
+ while (str < end)
+ {
+ Ichar ch = itext_ichar (str);
+ Lisp_Object charset;
+ int byte1, byte2;
+
+ /* @@#### This use of CONVERR_SUBSTITUTE is somewhat bogus.
+ It will substitute a '?' if we can't convert. Not clear whether
+ this will work or not. Problem is that we really shouldn't
+ be doing things on a charset level. */
+ buffer_ichar_to_charset_codepoint (ch, buf, &charset, &byte1, &byte2,
+ CONVERR_SUBSTITUTE);
+
+ if (!EQ (charset, prev_charset))
+ {
+ if (runs_so_far)
+ run_storage[runs_so_far-1].len =
+ (text_storage - run_storage[runs_so_far-1].ptr) >> 1;
+ run_storage[runs_so_far].ptr = text_storage;
+ run_storage[runs_so_far].dimension = 2;
+ run_storage[runs_so_far].charset = charset;
+ prev_charset = charset;
+ runs_so_far++;
+ }
+
+ if (valid_unicode_leading_surrogate (*((XftChar16 *) (text_storage))))
+ {
+ text_storage += sizeof (XftChar16);
+ }
+ text_storage += sizeof (XftChar16);
+ INC_IBYTEPTR (str);
+ }
+
+ if (runs_so_far)
+ run_storage[runs_so_far-1].len =
+ (text_storage - run_storage[runs_so_far-1].ptr) >> 1;
+ return runs_so_far;
+}
+#endif
+
+#if !defined(USE_XFT) && defined(MULE)
+
+#define ALLOCATE_RUNS_TEXT(storage, storage_len, str, len) \
+ (storage = alloca_extbytes ((storage_len = (2 * len))))
+
+/*
+ This is the most complex function of this group, due to the various
+ indexing schemes used by different fonts. For our purposes, they
+ fall into three classes. Some fonts are indexed compatibly with ISO
+ 2022; those fonts just use the Mule internal representation directly
+ (typically the high bit must be reset; this is determined by the `graphic'
+ flag). Some fonts are indexed by Unicode, specifically by UCS-2. These
+ are all translated using `ichar_to_unicode'. Finally some fonts have
+ irregular indexes, and must be translated ad hoc. In XEmacs ad hoc
+ translations are accomplished with CCL programs. */
+static Elemcount
+separate_textual_runs_mule (struct buffer *buf,
+ Extbyte *text_storage,
+ struct textual_run *run_storage,
+ const Ibyte *str, Bytecount len,
+ struct face_cachel *cachel)
{
- /* !!#### Needs review */
- int width_so_far = 0;
- unsigned char *text_storage = (unsigned char *) ALLOCA (2 * len);
+ Lisp_Object prev_charset = Qunbound, ccl_prog;
+ int runs_so_far = 0;
+ const Ibyte *end = str + len;
+ int dimension = 1, need_ccl_conversion = 0;
+ struct ccl_program char_converter;
+
+ int translate_to_ucs_2 = 0;
+
+ while (str < end)
+ {
+ Ichar ch = itext_ichar (str);
+ Lisp_Object charset;
+ int byte1, byte2;
+
+ buffer_ichar_to_charset_codepoint (ch, buf, &charset, &byte1, &byte2,
+ CONVERR_FAIL);
+
+ /* If we can't convert, substitute a '~' (CANT_DISPLAY_CHAR). */
+ /* @@#### This is extremely bogus. We want it to substitute the
+ Unicode replacement character, but there's no charset for this.
+ We really shouldn't be doing things on a charset level. */
+ if (NILP (charset))
+ {
+ charset = Vcharset_ascii;
+ byte1 = 0;
+ byte2 = CANT_DISPLAY_CHAR;
+ }
+
+ /* NOTE: Formerly we used to retrieve the XCHARSET_GRAPHIC() here
+ and use it below to determine whether to push the bytes into
+ the 128-255 range. This is now handled automatically by the
+ `offset' property of charsets, which should agree with `graphic'.
+ Logically, the `offset' property describes the numeric indices
+ of the characters, such as when they are used to index an array
+ or font, while the `graphic' property indicates which register
+ to select when encoding using iso2022. */
+
+ if (!EQ (charset, prev_charset))
+ {
+ int offs;
+
+ /* At this point, dimension' and `prev_charset' refer to just-
+ completed run. `runs_so_far' and `text_storage' refer to the
+ run about to start. */
+ if (runs_so_far)
+ {
+ /* Update metadata for previous run. */
+ run_storage[runs_so_far - 1].len =
+ text_storage - run_storage[runs_so_far - 1].ptr;
+ if (2 == dimension) run_storage[runs_so_far - 1].len >>= 1;
+ }
+
+ /* Compute metadata for current run.
+ First, classify font.
+ If the font is indexed by UCS-2, set `translate_to_ucs_2'.
+ Else if the charset has a CCL program, set `need_ccl_conversion'.
+ These flags are almost mutually exclusive, but we're sloppy
+ about resetting "shadowed" flags. So the flags must be checked
+ in the proper order in computing byte1 and byte2, below. */
+
+ offs = FACE_CACHEL_OFFSET_ENSURE (cachel, charset);
+
+ translate_to_ucs_2 = Stynarr_at (cachel->font_final_stage, offs);
+ if (translate_to_ucs_2)
+ {
+ dimension = 2;
+ }
+ else
+ {
+ dimension = XCHARSET_DIMENSION (charset);
+
+ /* Check for CCL charset.
+ If setup_ccl_program fails, we'll get a garbaged display.
+ This should never happen, and even if it does, it should
+ be harmless (unless the X server has buggy handling of
+ characters undefined in the font). It may be marginally
+ more useful to users and debuggers than substituting a
+ fixed replacement character. */
+ ccl_prog = XCHARSET_CCL_PROGRAM (charset);
+ if ((!NILP (ccl_prog))
+ && (setup_ccl_program (&char_converter, ccl_prog) >= 0))
+ {
+ need_ccl_conversion = 1;
+ }
+ /* Else, the charset must have an ISO 2022-compatible font index.
+ */
+ }
+
+ /* Initialize metadata for current run. */
+ run_storage[runs_so_far].ptr = text_storage;
+ run_storage[runs_so_far].charset = charset;
+ run_storage[runs_so_far].dimension = dimension;
+
+ /* Update loop variables. */
+ prev_charset = charset;
+ runs_so_far++;
+ }
+
+ /* Must check flags in this order. See comment above. */
+ if (translate_to_ucs_2)
+ {
+ int ucs = ichar_to_unicode (ch, CONVERR_SUBSTITUTE);
+ /* If UCS is less than zero or greater than 0xFFFF, set ucs2 to
+ REPLACEMENT CHARACTER. */
+ ucs = (ucs & ~0xFFFF) ? UNICODE_REPLACEMENT_CHAR : ucs;
+
+ byte1 = ucs >> 8;
+ byte2 = ucs & 0xFF;
+ }
+ else if (need_ccl_conversion)
+ {
+ internal_to_external_charset_codepoint (charset, byte1, byte2,
+ &byte1, &byte2, 1);
+ char_converter.reg[0] = XCHARSET_ID (charset);
+ char_converter.reg[1] = byte1;
+ char_converter.reg[2] = byte2;
+ ccl_driver (&char_converter, 0, buf, 0, 0, 0, CCL_MODE_ENCODING);
+ byte1 = char_converter.reg[1];
+ byte2 = char_converter.reg[2];
+ get_external_charset_codepoint (charset, make_fixnum (byte1),
+ make_fixnum (byte2),
+ &byte1, &byte2, 1);
+ }
+ else if (EQ (charset, Vcharset_ascii) && byte2 != CANT_DISPLAY_CHAR)
+ {
+ const Ibyte *nonascii;
+
+ nonascii = skip_ascii (str, end);
+ memcpy (text_storage, str, nonascii - str);
+ text_storage += nonascii - str;
+ str = nonascii;
+ continue;
+ }
+
+ if (2 == dimension)
+ {
+ *text_storage++ = (Extbyte) byte1;
+ }
+
+ *text_storage++ = (Extbyte) byte2;
+ INC_IBYTEPTR (str);
+ }
+
+ if (runs_so_far)
+ {
+ run_storage[runs_so_far - 1].len =
+ text_storage - run_storage[runs_so_far - 1].ptr;
+ /* Dimension retains the relevant value for the run before it. */
+ if (2 == dimension)
+ run_storage[runs_so_far - 1].len >>= 1;
+ }
+
+ assert (runs_so_far < 0xFFFF);
+
+ return runs_so_far;
+}
+#endif
+
+static int
+separate_textual_runs (struct buffer *buf,
+ Extbyte *text_storage,
+ struct textual_run *run_storage,
+ const Ibyte *str, Bytecount len,
+ struct face_cachel *cachel)
+{
+#if defined (USE_XFT) && defined (MULE)
+ return separate_textual_runs_xft_mule (buf, text_storage, run_storage,
+ str, len, cachel);
+#endif
+#if defined (USE_XFT) && !defined (MULE)
+ return separate_textual_runs_xft_nomule (buf, text_storage, run_storage,
+ str, len, cachel);
+#endif
+#if !defined (USE_XFT) && defined (MULE)
+ return separate_textual_runs_mule (buf, text_storage, run_storage,
+ str, len, cachel);
+#endif
+#if !defined (USE_XFT) && !defined (MULE)
+ return separate_textual_runs_nomule (buf, text_storage, run_storage,
+ str, len, cachel);
+#endif
+}
+
+/****************************************************************************/
+/* */
+/* X output routines */
+/* */
+/****************************************************************************/
+
+static int
+x_text_width_single_run (Display * USED_IF_XFT (dpy),
+ struct face_cachel *cachel,
+ struct textual_run *run)
+{
+ Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset);
+ Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst);
+
+ if (!fi->proportional_p)
+ return fi->width * run->len;
+#ifdef USE_XFT
+ else if (FONT_INSTANCE_X_XFTFONT (fi))
+ {
+ XGlyphInfo glyphinfo;
+
+ assert (run->dimension == 2);
+
+ XftTextExtents16 (dpy, FONT_INSTANCE_X_XFTFONT (fi),
+ (XftChar16 *) run->ptr, run->len, &glyphinfo);
+
+ return glyphinfo.xOff;
+ }
+#endif
+ else if (FONT_INSTANCE_X_FONT (fi))
+ {
+ if (run->dimension == 2)
+ {
+ /* stderr_out ("Measuring wide characters\n"); */
+ return XTextWidth16 (FONT_INSTANCE_X_FONT (fi),
+ (XChar2b *) (run->ptr), run->len);
+ }
+ else
+ {
+ return XTextWidth (FONT_INSTANCE_X_FONT (fi), run->ptr, run->len);
+ }
+ }
+ else
+ abort();
+ return 0; /* shut up GCC */
+}
+
+/* x_text_width
+
+ Given a string and a merged face, return the string's length in pixels
+ when displayed in the fonts associated with the face. */
+
+static int
+x_text_width (struct frame *f, struct face_cachel *cachel, const Ibyte *str,
+ Bytecount len)
+{
+ Extbyte *text_storage = NULL;
+ int width_so_far = 0, text_storage_len = 0;
struct textual_run *runs = alloca_array (struct textual_run, len);
+ Display *dpy = DEVICE_X_DISPLAY (XDEVICE (f->device));
int nruns;
int i;
- nruns = separate_textual_runs (text_storage, runs, str, len,
- cachel);
+ ALLOCATE_RUNS_TEXT (text_storage, text_storage_len, str, len);
+ nruns = separate_textual_runs (WINDOW_XBUFFER (FRAME_SELECTED_XWINDOW (f)),
+ text_storage, runs, str, len, cachel);
+
+ USED (text_storage_len);
for (i = 0; i < nruns; i++)
- width_so_far += XLIKE_text_width_single_run (f, cachel, runs + i);
+ width_so_far += x_text_width_single_run (dpy, cachel, runs + i);
return width_so_far;
}
@@ -70,7 +507,7 @@
Perform any necessary initialization prior to an update.
****************************************************************************/
static void
-XLIKE_window_output_begin (struct window *UNUSED (w))
+x_window_output_begin (struct window *UNUSED (w))
{
}
@@ -80,47 +517,47 @@
Perform any necessary flushing of queues when an update has completed.
****************************************************************************/
static void
-XLIKE_window_output_end (struct window *w)
+x_window_output_end (struct window *w)
{
if (!(check_if_pending_expose_event (WINDOW_XDEVICE (w))))
XFlush (DEVICE_X_DISPLAY (WINDOW_XDEVICE (w)));
}
/****************************************************************************
- XLIKE_clear_region
+ x_clear_region
Clear the area in the box defined by the given parameters using the
given face.
****************************************************************************/
static void
-XLIKE_clear_region (Lisp_Object UNUSED (locale), struct frame* f,
+x_clear_region (Lisp_Object UNUSED (locale), struct frame* f,
face_index UNUSED (findex),
int x, int y, int width, int height,
Lisp_Object fcolor, Lisp_Object bcolor,
Lisp_Object background_pixmap,
Lisp_Object background_placement)
{
- XLIKE_DISPLAY dpy = GET_XLIKE_DISPLAY (XDEVICE (f->device));
- XLIKE_WINDOW x_win = GET_XLIKE_WINDOW (f);
- XLIKE_GC gc = NULL;
+ Display *dpy = DEVICE_X_DISPLAY (XDEVICE (f->device));
+ Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
+ GC gc = NULL;
if (!UNBOUNDP (background_pixmap))
{
- gc = XLIKE_get_gc (f, Qnil, fcolor, bcolor,
- background_pixmap, background_placement, Qnil);
- XLIKE_FILL_RECTANGLE (dpy, x_win, gc, x, y, width, height);
+ gc = x_get_gc (f, Qnil, fcolor, bcolor, background_pixmap,
+ background_placement, Qnil);
+ XFillRectangle (dpy, x_win, gc, x, y, width, height);
}
else
{
- XLIKE_CLEAR_AREA (dpy, x_win, x, y, width, height);
+ XClearArea (dpy, x_win, x, y, width, height, False);
}
}
static void
-XLIKE_clear_frame (struct frame *f)
+x_clear_frame (struct frame *f)
{
- XLIKE_DISPLAY dpy = GET_XLIKE_X_DISPLAY (XDEVICE (f->device));
- XLIKE_WINDOW x_win = GET_XLIKE_WINDOW (f);
+ Display *dpy = DEVICE_X_DISPLAY (XDEVICE (f->device));
+ Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
int x, y, width, height;
Lisp_Object frame;
@@ -135,7 +572,7 @@
y = FRAME_TOP_INTERNAL_BORDER_START (f) - 1;
height = (FRAME_BOTTOM_INTERNAL_BORDER_END (f) - y);
- XLIKE_CLEAR_AREA (dpy, x_win, x, y, width, height);
+ XClearArea (dpy, x_win, x, y, width, height, False);
frame = wrap_frame (f);
@@ -159,7 +596,7 @@
Draw shadows for the given area in the given face.
****************************************************************************/
static void
-XLIKE_bevel_area (struct window *w, face_index findex,
+x_bevel_area (struct window *w, face_index findex,
int x, int y, int width, int height,
int shadow_thickness, int edges, enum edge_style style)
{
@@ -431,22 +868,22 @@
}
/*****************************************************************************
- XLIKE_output_horizontal_line
+ x_output_horizontal_line
Output a horizontal line in the foreground of its face.
****************************************************************************/
static void
-XLIKE_output_horizontal_line (struct window *w, struct display_line *dl,
- struct rune *rb)
+x_output_horizontal_line (struct window *w, struct display_line *dl,
+ struct rune *rb)
{
struct frame *f = XFRAME (w->frame);
struct device *d = XDEVICE (f->device);
- XLIKE_DISPLAY dpy = GET_XLIKE_X_DISPLAY (d);
- XLIKE_WINDOW x_win = GET_XLIKE_WINDOW (f);
- XLIKE_GC gc;
+ Display *dpy = DEVICE_X_DISPLAY (d);
+ Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
+ GC gc;
int x = rb->xpos;
int width = rb->width;
- int height = XLIKE_DISPLAY_LINE_HEIGHT (dl);
+ int height = DISPLAY_LINE_HEIGHT (dl);
int ypos1, ypos2, ypos3, ypos4;
ypos1 = XLIKE_DISPLAY_LINE_YPOS (dl);
@@ -463,9 +900,9 @@
Qnil, Qnil, Qnil, Qnil);
if (ypos2 - ypos1 > 0)
- XLIKE_FILL_RECTANGLE (dpy, x_win, gc, x, ypos1, width, ypos2 - ypos1);
+ XFillRectangle (dpy, x_win, gc, x, ypos1, width, ypos2 - ypos1);
if (ypos4 - ypos3 > 0)
- XLIKE_FILL_RECTANGLE (dpy, x_win, gc, x, ypos3, width, ypos4 - ypos3);
+ XFillRectangle (dpy, x_win, gc, x, ypos3, width, ypos4 - ypos3);
}
/* Now draw the line. */
@@ -479,27 +916,27 @@
if (ypos3 - ypos2 > 0)
{
- XLIKE_FILL_RECTANGLE (dpy, x_win, gc, x, ypos3, width,
- rb->object.hline.thickness);
+ XFillRectangle (dpy, x_win, gc, x, ypos3, width,
+ rb->object.hline.thickness);
}
}
/*****************************************************************************
- XLIKE_output_vertical_divider
+ x_output_vertical_divider
Draw a vertical divider down the right side of the given window.
****************************************************************************/
static void
-XLIKE_output_vertical_divider (struct window *w, int USED_IF_X (clear))
+x_output_vertical_divider (struct window *w, int USED_IF_X (clear))
{
struct frame *f = XFRAME (w->frame);
struct device *d = XDEVICE (f->device);
- XLIKE_DISPLAY dpy = GET_XLIKE_X_DISPLAY (d);
- XLIKE_WINDOW x_win = GET_XLIKE_WINDOW (f);
+ Display *dpy = DEVICE_X_DISPLAY (d);
+ Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
Lisp_Object tmp_pixel;
- XLIKE_GCVALUES gcv;
- XLIKE_GC background_gc;
+ XGCValues gcv;
+ GC background_gc;
enum edge_style style;
unsigned long mask;
int x, ytop, ybottom, width, shadow_thickness, spacing, line_width;
@@ -521,7 +958,7 @@
/* First, get the GC's. */
XLIKE_SET_GC_COLOR (gcv.background, XCOLOR_INSTANCE_XLIKE_COLOR (tmp_pixel));
gcv.foreground = gcv.background;
- gcv.graphics_exposures = XLIKE_FALSE;
+ gcv.graphics_exposures = False;
mask = XLIKE_GC_FOREGROUND | XLIKE_GC_BACKGROUND | XLIKE_GC_EXPOSURES;
background_gc = gc_cache_lookup (DEVICE_XLIKE_GC_CACHE (d), &gcv, mask);
@@ -532,9 +969,8 @@
XClearArea (dpy, x_win, x, ytop, width, ybottom - ytop, False);
/* Draw the divider line. */
- XLIKE_FILL_RECTANGLE (dpy, x_win, background_gc,
- x + spacing + shadow_thickness, ytop,
- line_width, ybottom - ytop);
+ XFillRectangle (dpy, x_win, background_gc, x + spacing + shadow_thickness,
+ ytop, line_width, ybottom - ytop);
if (shadow_thickness < 0)
{
shadow_thickness = -shadow_thickness;
@@ -554,7 +990,7 @@
/* Make audible bell. */
static void
-XLIKE_ring_bell (struct device *d, int volume, int pitch, int duration)
+x_ring_bell (struct device *d, int volume, int pitch, int duration)
{
Display *display = DEVICE_X_DISPLAY (d);
@@ -591,13 +1027,13 @@
/* briefly swap the foreground and background colors.
*/
static int
-XLIKE_flash (struct device *d)
+x_flash (struct device *d)
{
struct frame *f = device_selected_frame (d);
- XLIKE_DISPLAY dpy = GET_XLIKE_X_DISPLAY (d);
- XLIKE_WINDOW win = GET_XLIKE_WINDOW (f);
- XLIKE_GC gc = NULL;
- XLIKE_GCVALUES gcv;
+ Display *dpy = DEVICE_X_DISPLAY (d);
+ Window win = XtWindow (FRAME_X_TEXT_WIDGET (f));
+ GC gc = NULL;
+ XGCValues gcv;
XLIKE_PIXEL tmp_fcolor, tmp_bcolor;
Lisp_Object tmp_pixel, frame;
struct window *w = XWINDOW (FRAME_ROOT_WINDOW (f));
@@ -612,7 +1048,7 @@
memset (&gcv, ~0, sizeof (gcv)); /* initialize all slots to ~0 */
XLIKE_SET_GC_PIXEL (gcv.foreground, tmp_fcolor ^ tmp_bcolor);
gcv.function = XLIKE_GX_XOR;
- gcv.graphics_exposures = XLIKE_FALSE;
+ gcv.graphics_exposures = False;
gc = gc_cache_lookup (DEVICE_XLIKE_GC_CACHE (XDEVICE (f->device)), &gcv,
XLIKE_GC_FOREGROUND | XLIKE_GC_FUNCTION | XLIKE_GC_EXPOSURES);
default_face_width_and_height (frame, 0, &flash_height);
@@ -620,16 +1056,16 @@
/* If window is tall, flash top and bottom line. */
if (EQ (Vvisible_bell, Qtop_bottom) && w->pixel_height > 3 *
flash_height)
{
- XLIKE_FILL_RECTANGLE (dpy, win, gc, w->pixel_left, w->pixel_top,
- w->pixel_width, flash_height);
- XLIKE_FILL_RECTANGLE (dpy, win, gc, w->pixel_left,
- w->pixel_top + w->pixel_height - flash_height,
- w->pixel_width, flash_height);
+ XFillRectangle (dpy, win, gc, w->pixel_left, w->pixel_top,
+ w->pixel_width, flash_height);
+ XFillRectangle (dpy, win, gc, w->pixel_left,
+ w->pixel_top + w->pixel_height - flash_height,
+ w->pixel_width, flash_height);
}
else
/* If it is short, flash it all. */
- XLIKE_FILL_RECTANGLE (dpy, win, gc, w->pixel_left, w->pixel_top,
- w->pixel_width, w->pixel_height);
+ XFillRectangle (dpy, win, gc, w->pixel_left, w->pixel_top, w->pixel_width,
+ w->pixel_height);
XLIKE_FLUSH (dpy);
@@ -653,16 +1089,16 @@
/* If window is tall, flash top and bottom line. */
if (EQ (Vvisible_bell, Qtop_bottom) && w->pixel_height > 3 *
flash_height)
{
- XLIKE_FILL_RECTANGLE (dpy, win, gc, w->pixel_left, w->pixel_top,
- w->pixel_width, flash_height);
- XLIKE_FILL_RECTANGLE (dpy, win, gc, w->pixel_left,
- w->pixel_top + w->pixel_height - flash_height,
- w->pixel_width, flash_height);
+ XFillRectangle (dpy, win, gc, w->pixel_left, w->pixel_top,
+ w->pixel_width, flash_height);
+ XFillRectangle (dpy, win, gc, w->pixel_left,
+ w->pixel_top + w->pixel_height - flash_height,
+ w->pixel_width, flash_height);
}
else
/* If it is short, flash it all. */
- XLIKE_FILL_RECTANGLE (dpy, win, gc, w->pixel_left, w->pixel_top,
- w->pixel_width, w->pixel_height);
+ XFillRectangle (dpy, win, gc, w->pixel_left, w->pixel_top, w->pixel_width,
+ w->pixel_height);
XLIKE_FLUSH (dpy);
@@ -670,21 +1106,21 @@
}
/*****************************************************************************
- XLIKE_output_blank
+ x_output_blank
Output a blank by clearing the area it covers in the foreground color
of its face.
****************************************************************************/
static void
-XLIKE_output_blank (struct window *w, struct display_line *dl, struct rune *rb,
- int start_pixpos, int cursor_start, int cursor_width)
+x_output_blank (struct window *w, struct display_line *dl, struct rune *rb,
+ int start_pixpos, int cursor_start, int cursor_width)
{
struct frame *f = XFRAME (w->frame);
struct device *d = XDEVICE (f->device);
- XLIKE_DISPLAY dpy = GET_XLIKE_X_DISPLAY (d);
- XLIKE_WINDOW x_win = GET_XLIKE_WINDOW (f);
- XLIKE_GC gc;
+ Display *dpy = DEVICE_X_DISPLAY (d);
+ Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
+ GC gc;
struct face_cachel *cursor_cachel =
WINDOW_FACE_CACHEL (w,
get_builtin_face_cache_index
@@ -729,7 +1165,7 @@
WINDOW_FACE_CACHEL_BACKGROUND_PLACEMENT (w, rb->findex),
Qnil);
- XLIKE_FILL_RECTANGLE (dpy, x_win, gc, x, y, width, height);
+ XFillRectangle (dpy, x_win, gc, x, y, width, height);
/* If this rune is marked as having the cursor, then it is actually
representing a tab. */
@@ -759,8 +1195,8 @@
{
if (NILP (bar_cursor_value))
{
- XLIKE_FILL_RECTANGLE (dpy, x_win, gc, cursor_start, cursor_y,
- fi->width, cursor_height);
+ XFillRectangle (dpy, x_win, gc, cursor_start, cursor_y,
+ fi->width, cursor_height);
}
else
{
@@ -769,9 +1205,9 @@
gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background,
Qnil, Qnil, Qnil,
make_fixnum (bar_width));
- XLIKE_DRAW_LINE (dpy, x_win, gc, cursor_start + bar_width - 1,
- cursor_y, cursor_start + bar_width - 1,
- cursor_y + cursor_height - 1);
+ XDrawLine (dpy, x_win, gc, cursor_start + bar_width - 1,
+ cursor_y, cursor_start + bar_width - 1,
+ cursor_y + cursor_height - 1);
}
}
else if (NILP (bar_cursor_value))
@@ -784,16 +1220,16 @@
/* The end-of-line cursor is narrower than the normal cursor. */
static void
-XLIKE_output_eol_cursor (struct window *w, struct display_line *dl, int xpos,
- face_index findex)
+x_output_eol_cursor (struct window *w, struct display_line *dl, int xpos,
+ face_index findex)
{
struct frame *f = XFRAME (w->frame);
struct device *d = XDEVICE (f->device);
Lisp_Object window;
- XLIKE_DISPLAY dpy = GET_XLIKE_X_DISPLAY (d);
- XLIKE_WINDOW x_win = GET_XLIKE_WINDOW (f);
- XLIKE_GC gc = NULL;
+ Display *dpy = DEVICE_X_DISPLAY (d);
+ Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
+ GC gc = NULL;
face_index elt = get_builtin_face_cache_index (w, Vtext_cursor_face);
struct face_cachel *cursor_cachel = WINDOW_FACE_CACHEL (w, elt);
@@ -832,8 +1268,7 @@
if (NILP (bar_cursor_value))
{
- XLIKE_FILL_RECTANGLE (dpy, x_win, gc, x, cursor_y, width,
- cursor_height);
+ XFillRectangle (dpy, x_win, gc, x, cursor_y, width, cursor_height);
}
else
{
@@ -842,8 +1277,8 @@
gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil,
Qnil, Qnil,
make_fixnum (bar_width));
- XLIKE_DRAW_LINE (dpy, x_win, gc, x + bar_width - 1, cursor_y,
- x + bar_width - 1, cursor_y + cursor_height - 1);
+ XDrawLine (dpy, x_win, gc, x + bar_width - 1, cursor_y,
+ x + bar_width - 1, cursor_y + cursor_height - 1);
}
}
else if (NILP (bar_cursor_value))
@@ -854,20 +1289,19 @@
}
static void
-XLIKE_output_xlike_pixmap (struct frame *f, Lisp_Image_Instance *p, int x,
- int y, int xoffset, int yoffset,
- int width, int height,
- XLIKE_COLOR fg, XLIKE_COLOR bg)
+x_output_xlike_pixmap (struct frame *f, Lisp_Image_Instance *p, int x, int y,
+ int xoffset, int yoffset, int width, int height,
+ XColor fg, XColor bg)
{
struct device *d = XDEVICE (f->device);
- XLIKE_DISPLAY dpy = GET_XLIKE_X_DISPLAY (d);
- XLIKE_WINDOW x_win = GET_XLIKE_WINDOW (f);
- XLIKE_GC gc;
- XLIKE_GCVALUES gcv;
+ Display *dpy = DEVICE_X_DISPLAY (d);
+ Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
+ GC gc;
+ XGCValues gcv;
unsigned long pixmap_mask;
memset (&gcv, ~0, sizeof (gcv));
- gcv.graphics_exposures = XLIKE_FALSE;
+ gcv.graphics_exposures = False;
XLIKE_SET_GC_COLOR (gcv.foreground, fg);
XLIKE_SET_GC_COLOR (gcv.background, bg);
pixmap_mask = XLIKE_GC_FOREGROUND | XLIKE_GC_BACKGROUND | XLIKE_GC_EXPOSURES;
@@ -914,3 +1348,587 @@
}
}
+/*****************************************************************************
+ x_output_string
+
+ Given a string and a starting position, output that string in the
+ given face. If cursor is true, draw a cursor around the string.
+ Correctly handles multiple charsets in the string.
+
+ The meaning of the parameters is something like this:
+
+ W Window that the text is to be displayed in.
+ DL Display line that this text is on. The values in the
+ structure are used to determine the vertical position and
+ clipping range of the text.
+ BUF Pointer to those Ibytes to be output.
+ LEN Number of those Ibytes to be output
+ XPOS X position in pixels where the text should start being drawn.
+ XOFFSET Number of pixels to be chopped off the left side of the
+ text. The effect is as if the text were shifted to the
+ left this many pixels and clipped at XPOS.
+ CLIP_START Clip everything left of this X position.
+ WIDTH Clip everything right of XPOS + WIDTH.
+ FINDEX Index for the face cache element describing how to display
+ the text.
+ CURSOR #### I don't understand this. There's something
+ strange and overcomplexified with this variable.
+ Chuck, explain please?
+ CURSOR_START Starting X position of cursor.
+ CURSOR_WIDTH Width of cursor in pixels.
+ CURSOR_HEIGHT Height of cursor in pixels.
+
+ Starting Y position of cursor is the top of the text line.
+ The cursor is drawn sometimes whether or not CURSOR is set. ???
+ ****************************************************************************/
+
+void
+x_output_string (struct window *w, struct display_line *dl, const Ibyte *buf,
+ Bytecount len, int xpos, int xoffset, int clip_start,
+ int width, face_index findex, int cursor, int cursor_start,
+ int cursor_width, int cursor_height)
+{
+ /* General variables */
+ struct frame *f = XFRAME (w->frame);
+ struct device *d = XDEVICE (f->device);
+ Display *dpy = DEVICE_X_DISPLAY (d);
+ Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
+ Lisp_Object window = wrap_window (w);
+
+ int clip_end;
+
+ /* Cursor-related variables */
+ int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
+ int cursor_clip;
+ Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor,
+ WINDOW_BUFFER (w));
+ struct face_cachel *cursor_cachel = 0;
+
+ /* Text-related variables */
+ Lisp_Object bg_pmap;
+ GC gc, bgc;
+ int height = XLIKE_DISPLAY_LINE_HEIGHT (dl);
+ int ypos = XLIKE_DISPLAY_LINE_YPOS (dl);
+ Extbyte *text_storage;
+ struct textual_run *runs = alloca_array (struct textual_run, len);
+ int nruns, text_storage_len;
+ int i;
+ struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex);
+
+#ifdef THIS_IS_X
+ int use_x_font = 1; /* #### bogus!!
+ The logic of this function needs review! */
+#endif
+#ifdef USE_XFT
+ Colormap cmap = DEVICE_X_COLORMAP (d);
+ Visual *visual = DEVICE_X_VISUAL (d);
+ static XftColor fg, bg;
+ XftDraw *xftDraw;
+
+ /* Lazily initialize frame's xftDraw member. */
+ if (!FRAME_X_XFTDRAW (f)) {
+ FRAME_X_XFTDRAW (f) = XftDrawCreate (dpy, x_win, visual, cmap);
+ }
+ xftDraw = FRAME_X_XFTDRAW (f);
+
+ /* #### This will probably cause asserts when passed a Lisp integer for a
+ color. See ca. line 759 this file.
+ #### Maybe xft_convert_color should take an XColor, not a pixel. */
+#define XFT_FROB_LISP_COLOR(color, dim) \
+ xft_convert_color_1 (dpy, cmap, visual, \
+ &(XCOLOR_INSTANCE_X_COLOR (color)), (dim))
+#endif /* USE_XFT */
+
+ if (width < 0)
+ width = XLIKE_text_width (f, cachel, buf, len);
+
+ /* Regularize the variables passed in. */
+ clip_start = min (clip_start, xpos);
+ clip_end = xpos + width;
+ if (clip_start >= clip_end)
+ /* It's all clipped out. */
+ return;
+
+ xpos -= xoffset;
+
+ /* make sure the area we are about to display is subwindow free. */
+ redisplay_unmap_subwindows_maybe (f, clip_start, ypos,
+ clip_end - clip_start, height);
+
+ cursor_clip = (cursor_start >= clip_start &&
+ cursor_start < clip_end);
+
+ /* This cursor code is really a mess. */
+ if (!NILP (w->text_cursor_visible_p)
+ && (cursor
+ || cursor_clip
+ || (cursor_width
+ && (cursor_start + cursor_width >= clip_start)
+ && !NILP (bar_cursor_value))))
+ {
+ /* These have to be in separate statements in order to avoid a
+ compiler bug. */
+ face_index sucks = get_builtin_face_cache_index (w, Vtext_cursor_face);
+ cursor_cachel = WINDOW_FACE_CACHEL (w, sucks);
+
+ /* We have to reset this since any call to WINDOW_FACE_CACHEL
+ may cause the cache to resize and any pointers to it to
+ become invalid. */
+ cachel = WINDOW_FACE_CACHEL (w, findex);
+ }
+
+#ifdef HAVE_XIM
+ if (cursor && focus && (cursor_start == clip_start) &&
cursor_height)
+ XIM_SetSpotLocation (f, xpos - 2, dl->ypos + dl->descent - 2);
+#endif /* HAVE_XIM */
+
+ bg_pmap = cachel->background_pixmap;
+ if (!IMAGE_INSTANCEP (bg_pmap)
+ || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap)))
+ bg_pmap = Qnil;
+
+ if ((cursor && focus && NILP (bar_cursor_value)
+ && !NILP (w->text_cursor_visible_p)) || NILP (bg_pmap))
+ bgc = 0;
+ else
+ {
+ /* Clear the cursor location? */
+ bgc = XLIKE_get_gc (f, Qnil, cachel->background, cachel->background,
+ bg_pmap, cachel->background_placement, Qnil);
+ XFillRectangle (dpy, x_win, bgc, clip_start, ypos,
+ clip_end - clip_start, height);
+ }
+
+ ALLOCATE_RUNS_TEXT (text_storage, text_storage_len, buf, len);
+
+ nruns = separate_textual_runs (WINDOW_XBUFFER (w), text_storage, runs,
+ buf, len, cachel);
+
+ USED (text_storage_len);
+
+ for (i = 0; i < nruns; i++)
+ {
+ Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset);
+ Lisp_Font_Instance *fi = XFONT_INSTANCE (font);
+ int this_width;
+ int need_clipping;
+
+ if (EQ (font, Vthe_null_font_instance))
+ continue;
+
+ this_width = x_text_width_single_run (dpy, cachel, runs + i);
+ need_clipping = (dl->clip || clip_start > xpos ||
+ clip_end < xpos + this_width);
+
+ /* XDrawImageString only clears the area equal to the height of
+ the given font. It is possible that a font is being displayed
+ on a line taller than it is, so this would cause us to fail to
+ clear some areas. */
+ if ((int) fi->height < (int) (height + dl->clip +
+ XLIKE_DISPLAY_LINE_TOP_CLIP (dl)))
+ {
+ int clear_start = max (xpos, clip_start);
+ int clear_end = min (xpos + this_width, clip_end);
+
+ if (cursor)
+ {
+ int ypos1_line, ypos1_string, ypos2_line, ypos2_string;
+
+ ypos1_string = dl->ypos - fi->ascent;
+ ypos2_string = dl->ypos + fi->descent;
+ ypos1_line = ypos;
+ ypos2_line = ypos1_line + height;
+
+ /* Make sure we don't clear below the real bottom of the
+ line. */
+ ypos1_string = min (ypos1_string, ypos2_line);
+ ypos2_string = min (ypos2_string, ypos2_line);
+
+ if (ypos1_line < ypos1_string)
+ {
+ redisplay_clear_region (window, findex, clear_start, ypos1_line,
+ clear_end - clear_start,
+ ypos1_string - ypos1_line);
+ }
+
+ if (ypos2_line > ypos2_string)
+ {
+ redisplay_clear_region (window, findex, clear_start, ypos2_string,
+ clear_end - clear_start,
+ ypos2_line - ypos2_string);
+ }
+ }
+ else
+ {
+ redisplay_clear_region (window, findex, clear_start,
+ ypos, clear_end - clear_start,
+ height);
+ }
+ }
+
+ if (cursor && cursor_cachel && focus && NILP
(bar_cursor_value))
+ {
+#ifdef USE_XFT
+ fg = XFT_FROB_LISP_COLOR (cursor_cachel->foreground, 0);
+ bg = XFT_FROB_LISP_COLOR (cursor_cachel->background, 0);
+#endif
+ gc = XLIKE_get_gc (f, font, cursor_cachel->foreground,
+ cursor_cachel->background, Qnil, Qnil, Qnil);
+ }
+ else if (cachel->dim)
+ {
+ /* Ensure the gray bitmap exists */
+ if (DEVICE_X_GRAY_PIXMAP (d) == None)
+ {
+ DEVICE_X_GRAY_PIXMAP (d)
+ = XCreateBitmapFromData (dpy, x_win, (char *)gray_bits,
+ gray_width, gray_height);
+ }
+
+ /* Request a GC with the gray stipple pixmap to draw dimmed text */
+#ifdef USE_XFT
+ fg = XFT_FROB_LISP_COLOR (cachel->foreground, 1);
+ bg = XFT_FROB_LISP_COLOR (cachel->background, 0);
+#endif
+ gc = XLIKE_get_gc (f, font, cachel->foreground, cachel->background,
+ bg_pmap, cachel->background_placement, Qnil);
+ }
+ else
+ {
+#ifdef USE_XFT
+ fg = XFT_FROB_LISP_COLOR (cachel->foreground, 0);
+ bg = XFT_FROB_LISP_COLOR (cachel->background, 0);
+#endif
+ gc = XLIKE_get_gc (f, font, cachel->foreground, cachel->background,
+ Qnil, Qnil, Qnil);
+ }
+#ifdef USE_XFT
+ {
+ XftFont *rf = FONT_INSTANCE_X_XFTFONT (fi);
+
+ if (rf)
+ {
+ use_x_font = 0;
+ if (need_clipping)
+ {
+ Region clip_reg = XCreateRegion();
+ XRectangle clip_box = { clip_start, ypos,
+ clip_end - clip_start, height };
+
+ XUnionRectWithRegion (&clip_box, clip_reg, clip_reg);
+ XftDrawSetClip (xftDraw, clip_reg);
+ XDestroyRegion (clip_reg);
+ }
+
+ if (!bgc)
+ {
+ /* #### Neither rect_height nor XftTextExtents as computed
+ below handles the vertical space taken up by antialiasing,
+ which for some fonts (eg, Bitstream Vera Sans Mono-16 on
+ my Mac PowerBook G4) leaves behind orphaned dots on
+ insertion or deletion earlier in the line, especially in
+ the case of the underscore character.
+ Interestingly, insertion or deletion of a single character
+ immediately after a refresh does not leave any droppings,
+ but any further insertions or deletions do.
+ While adding a pixel to rect_height (mostly) takes care of
+ this, it trashes aggressively laid-out elements like the
+ modeline (overwriting part of the bevel).
+ OK, unconditionally redraw the bevel, and increment
+ rect_height by 1. See x_output_display_block. -- sjt */
+ struct textual_run *run = &runs[i];
+ int rect_width
+ = x_text_width_single_run (dpy, cachel, run);
+#ifndef USE_XFTTEXTENTS_TO_AVOID_FONT_DROPPINGS
+ int rect_height = FONT_INSTANCE_ASCENT (fi)
+ + FONT_INSTANCE_DESCENT (fi) + 1;
+#else
+ int rect_height = FONT_INSTANCE_ASCENT (fi)
+ + FONT_INSTANCE_DESCENT (fi);
+ XGlyphInfo gi;
+
+ XftTextExtents16 (dpy, FONT_INSTANCE_X_XFTFONT (fi),
+ (const XftChar16 *) run->ptr, run->len,
+ &gi);
+ rect_height = max (rect_height, gi.height);
+#endif
+
+ XftDrawRect (xftDraw, &bg,
+ xpos, ypos, rect_width, rect_height);
+ }
+
+ assert (runs[i].dimension == 2);
+
+ XftDrawString16 (xftDraw, &fg, rf, xpos, dl->ypos,
+ (const XftChar16 *) runs[i].ptr, runs[i].len);
+ }
+ }
+#endif /* USE_XFT */
+
+ if (use_x_font)
+ {
+ if (need_clipping)
+ {
+ XRectangle clip_box;
+
+ clip_box.x = 0;
+ clip_box.y = 0;
+ clip_box.width = clip_end - clip_start;
+ clip_box.height = height;
+
+ XLIKE_SET_CLIP_RECTANGLE (dpy, gc, clip_start, ypos, &clip_box);
+ }
+
+ if (runs[i].dimension == 1)
+ (bgc ? XDrawString : XDrawImageString)
+ (dpy, x_win, gc, xpos, dl->ypos,
+ (char *) runs[i].ptr, runs[i].len);
+ else
+ (bgc ? XDrawString16 : XDrawImageString16)
+ (dpy, x_win, gc, xpos, dl->ypos,
+ (XChar2b *) runs[i].ptr, runs[i].len);
+ }
+
+ /* We draw underlines in the same color as the text. */
+ if (cachel->underline)
+ {
+ int upos, uthick;
+ unsigned long upos_ext, uthick_ext;
+ XFontStruct *fs =
+ use_x_font ? FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)) : 0;
+ /* #### the logic of the next two may be suboptimal: we may want
+ to use the POSITION and/or THICKNESS information with Xft */
+ if (fs && XGetFontProperty (fs, XA_UNDERLINE_POSITION, &upos_ext))
+ upos = (int) upos_ext;
+ else
+ upos = dl->descent / 2;
+ if (fs && XGetFontProperty (fs, XA_UNDERLINE_THICKNESS, &uthick_ext))
+ uthick = (int) uthick_ext;
+ else
+ uthick = 1;
+
+ if (dl->ypos + upos < dl->ypos + dl->descent - dl->clip)
+ {
+ if (dl->ypos + upos + uthick > dl->ypos + dl->descent - dl->clip)
+ uthick = dl->descent - dl->clip - upos;
+
+ if (uthick == 1)
+ {
+ XDrawLine (dpy, x_win, gc, xpos, dl->ypos + upos,
+ xpos + this_width, dl->ypos + upos);
+ }
+ else if (uthick > 1)
+ {
+ XFillRectangle (dpy, x_win, gc, xpos, dl->ypos + upos,
+ this_width, uthick);
+ }
+ }
+ }
+
+ if (cachel->strikethru)
+ {
+ int ascent, descent, upos, uthick;
+ unsigned long ascent_ext, descent_ext, uthick_ext;
+ XFontStruct *fs = FONT_INSTANCE_X_FONT (fi);
+
+ if (!use_x_font)
+ {
+ ascent = dl->ascent;
+ descent = dl->descent;
+ uthick = 1;
+ }
+ else
+ {
+ if (!XGetFontProperty (fs, XA_STRIKEOUT_ASCENT, &ascent_ext))
+ ascent = fs->ascent;
+ else
+ ascent = (int) ascent_ext;
+ if (!XGetFontProperty (fs, XA_STRIKEOUT_DESCENT, &descent_ext))
+ descent = fs->descent;
+ else
+ descent = (int) descent_ext;
+ if (!XGetFontProperty (fs, XA_UNDERLINE_THICKNESS, &uthick_ext))
+ uthick = 1;
+ else
+ uthick = (int) uthick_ext;
+ }
+ upos = ascent - ((ascent + descent) / 2) + 1;
+
+ /* Generally, upos will be positive (above the baseline),so
+ subtract */
+ if (dl->ypos - upos < dl->ypos + dl->descent - dl->clip)
+ {
+ if (dl->ypos - upos + uthick > dl->ypos + dl->descent - dl->clip)
+ uthick = dl->descent - dl->clip + upos;
+
+ if (uthick == 1)
+ XDrawLine (dpy, x_win, gc, xpos, dl->ypos - upos,
+ xpos + this_width, dl->ypos - upos);
+ else if (uthick > 1)
+ XFillRectangle (dpy, x_win, gc, xpos, dl->ypos + upos,
+ this_width, uthick);
+ }
+ }
+ /* Restore the GC */
+ if (need_clipping)
+ {
+#ifdef USE_XFT
+ if (!use_x_font)
+ {
+ XftDrawSetClip (xftDraw, 0);
+ }
+ else
+#endif
+ XLIKE_CLEAR_CLIP_MASK (dpy, gc);
+ }
+
+ /* If we are actually superimposing the cursor then redraw with just
+ the appropriate section highlighted. */
+ if (cursor_clip && !cursor && focus && cursor_cachel)
+ {
+#ifdef USE_XFT
+ if (!use_x_font) /* Xft */
+ {
+ XftFont *rf = FONT_INSTANCE_X_XFTFONT (fi);
+
+ { /* set up clipping */
+ Region clip_reg = XCreateRegion();
+ XRectangle clip_box = { cursor_start, ypos,
+ cursor_width, height };
+
+ XUnionRectWithRegion (&clip_box, clip_reg, clip_reg);
+ XftDrawSetClip (xftDraw, clip_reg);
+ XDestroyRegion (clip_reg);
+ }
+ { /* draw background rectangle & draw text */
+ int rect_height = FONT_INSTANCE_ASCENT (fi)
+ + FONT_INSTANCE_DESCENT (fi);
+ int rect_width
+ = x_text_width_single_run (dpy, cachel, &runs[i]);
+ XftColor xft_color;
+
+ xft_color = XFT_FROB_LISP_COLOR (cursor_cachel->background, 0);
+ XftDrawRect (xftDraw, &xft_color,
+ xpos, ypos, rect_width, rect_height);
+
+ xft_color = XFT_FROB_LISP_COLOR (cursor_cachel->foreground, 0);
+ assert (runs[i].dimension == 2);
+
+ XftDrawString16 (xftDraw, &xft_color, rf, xpos, dl->ypos,
+ (XftChar16 *) runs[i].ptr, runs[i].len);
+ }
+
+ XftDrawSetClip (xftDraw, 0);
+ }
+ else /* core font, not Xft */
+#endif /* USE_XFT */
+ {
+ XRectangle clip_box;
+ GC cgc;
+ cgc = XLIKE_get_gc (f, font, cursor_cachel->foreground,
+ cursor_cachel->background, Qnil, Qnil, Qnil);
+
+ clip_box.x = 0;
+ clip_box.y = 0;
+ clip_box.width = cursor_width;
+ clip_box.height = height;
+
+ XLIKE_SET_CLIP_RECTANGLE (dpy, cgc, cursor_start, ypos,
+ &clip_box);
+ if (runs[i].dimension == 1)
+ XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos,
+ (char *) runs[i].ptr, runs[i].len);
+ else
+ XDrawImageString16 (dpy, x_win, cgc, xpos, dl->ypos,
+ (XChar2b *) runs[i].ptr, runs[i].len);
+
+ XLIKE_CLEAR_CLIP_MASK (dpy, cgc);
+ }
+ }
+
+ xpos += this_width;
+ }
+
+ /* Draw the non-focus box or bar-cursor as needed. */
+ /* Can't this logic be simplified? */
+ if (cursor_cachel
+ && ((cursor && !focus && NILP (bar_cursor_value))
+ || (cursor_width
+ && (cursor_start + cursor_width >= clip_start)
+ && !NILP (bar_cursor_value))))
+ {
+ int tmp_height, tmp_y;
+ int bar_width = EQ (bar_cursor_value, Qt) ? 1 : 2;
+ int need_clipping = (cursor_start < clip_start
+ || clip_end < cursor_start + cursor_width);
+
+ /* #### This value is correct (as far as I know) because
+ all of the times we need to draw this cursor, we will
+ be called with exactly one character, so we know we
+ can always use runs[0].
+
+ This is bogus as all hell, however. The cursor handling in
+ this function is way bogus and desperately needs to be
+ cleaned up. (In particular, the drawing of the cursor should
+ really really be separated out of this function. This may be
+ a bit tricky now because this function itself does way too
+ much stuff, a lot of which needs to be moved into
+ redisplay.c.) This is the only way to be able to easily add
+ new cursor types or (e.g.) make the bar cursor be able to
+ span two characters instead of overlaying just one. */
+ int bogusly_obtained_ascent_value =
+ XFONT_INSTANCE (FACE_CACHEL_FONT (cachel, runs[0].charset))->ascent;
+
+ if (!NILP (bar_cursor_value))
+ {
+ gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil,
+ Qnil, Qnil,
+ make_fixnum (bar_width));
+ }
+ else
+ {
+ gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background,
+ Qnil, Qnil, Qnil, Qnil);
+ }
+ tmp_y = dl->ypos - bogusly_obtained_ascent_value;
+
+ tmp_height = cursor_height;
+ if (tmp_y + tmp_height > (int) (ypos + height))
+ {
+ tmp_y = ypos + height - tmp_height;
+ tmp_y = min (tmp_y, ypos);
+ tmp_height = ypos + height - tmp_y;
+ }
+
+ if (need_clipping)
+ {
+ XRectangle clip_box;
+ clip_box.x = 0;
+ clip_box.y = 0;
+ clip_box.width = clip_end - clip_start;
+ clip_box.height = tmp_height;
+ XLIKE_SET_CLIP_RECTANGLE (dpy, gc, clip_start, tmp_y, &clip_box);
+ }
+
+ if (!focus && NILP (bar_cursor_value))
+ {
+ XLIKE_DRAW_RECTANGLE (dpy, x_win, gc, cursor_start, tmp_y,
+ cursor_width - 1, tmp_height - 1);
+ }
+ else if (focus && !NILP (bar_cursor_value))
+ {
+ XDrawLine (dpy, x_win, gc, cursor_start + bar_width - 1, tmp_y,
+ cursor_start + bar_width - 1, tmp_y + tmp_height - 1);
+ }
+
+ /* Restore the GC */
+ if (need_clipping)
+ {
+ XLIKE_CLEAR_CLIP_MASK (dpy, gc);
+ }
+ }
+
+#ifdef USE_XFT
+#undef XFT_FROB_LISP_COLOR
+#endif
+}
diff -r 9bdc40b8fb78 -r a5b21ebab055 src/redisplay-xlike-inc.c
--- a/src/redisplay-xlike-inc.c Sun Dec 17 12:20:06 2017 +0000
+++ b/src/redisplay-xlike-inc.c Mon Dec 18 22:04:46 2017 +0000
@@ -102,12 +102,10 @@
#define console_type_create_redisplay_XLIKE XLIKE_PASTE (console_type_create_redisplay,
XLIKE_NAME)
#define XLIKE_get_gc XFUN (get_gc)
#define XLIKE_output_blank XFUN (output_blank)
-#define XLIKE_text_width_single_run XFUN (text_width_single_run)
#define XLIKE_output_horizontal_line XFUN (output_horizontal_line)
#define XLIKE_output_eol_cursor XFUN (output_eol_cursor)
#define XLIKE_clear_frame_window XFUN (clear_frame_window)
#define XLIKE_clear_frame_windows XFUN (clear_frame_windows)
-#define XLIKE_text_width XFUN (text_width)
static int XLIKE_text_width (struct frame *f, struct face_cachel *cachel,
const Ibyte *str, Bytecount len);
@@ -149,452 +147,6 @@
static void XLIKE_window_output_end (struct window *w);
#endif /* THIS_IS_X */
-
-/****************************************************************************/
-/* */
-/* Separate textual runs */
-/* */
-/****************************************************************************/
-
-
- /* Note: We do not use the Xmb*() functions and XFontSets, nor the
- Motif XFontLists and CompoundStrings.
- Those functions are generally losing for a number of reasons.
- Most important, they only support one locale (e.g. you could
- display Japanese and ASCII text, but not mixed Japanese/Chinese
- text). You could maybe call setlocale() frequently to try to deal
- with this, but that would generally fail because an XFontSet is
- tied to one locale and won't have the other character sets in it.
-
- fontconfig (the font database for Xft) has some specifier-like
- properties, but it's not sufficient (witness the existence of
- Pango). Pango might do the trick, but it's not a cross-platform
- solution; it would need significant advantages to be worth the
- effort.
- */
-
-struct textual_run
-{
- Lisp_Object charset;
- Extbyte *ptr;
- int len;
- int dimension;
-};
-
-/* Separate out the text in STR of length LEN into a series of runs, stored in
- RUN_STORAGE. RUN_STORAGE is guaranteed to hold enough space for all runs
- that could be generated from this text. Each run points to the a stretch
- of text given simply by the position codes TEXT_STORAGE into a series of
- textual runs of a particular charset. Also convert the characters as
- necessary into the format needed by XDrawImageString(),
- XDrawImageString16(), et al. This means converting to one or two byte
- format, possibly tweaking the high bits, and possibly running a CCL
- program. You must pre-allocate the space used and pass in a pointer,
- TEXT_STORAGE, and the ALLOCATE_RUNS_TEXT () macro is provided to do this
- using stack space. Some of the window-system-specific implementations take
- advantage of this step to do coding sytem translation, and the specific
- amount of space needed depends on the window system.
-
- bufchar might not be fixed width (in the case of UTF-8).
-
- Returns the number of runs actually used. */
-
-/* Notes on Xft implementation
-
- - With Unicode, we're no longer going to have repertoires reified as
- charsets. (Not that we ever really did, what with corporate variants,
- and so on.) So we really should be querying the face for the desired
- font, rather than the character for the charset, and that's what would
- determine the separation into runs.
- - The widechar versions of fontconfig (and therefore Xft) functions
- seem to be just bigendian Unicode. So there's actually no need to use
- the 8-bit versions in computing runs and runes, it would seem.
-*/
-
-#if !defined(THIS_IS_GTK)
-#if !defined(USE_XFT) && !defined(MULE)
-
-#define ALLOCATE_RUNS_TEXT(storage, storage_len, str, len) \
- (storage = alloca_extbytes (len))
-
-static int
-separate_textual_runs_nomule (struct buffer * UNUSED (buf),
- Extbyte *text_storage,
- struct textual_run *run_storage,
- const Ibyte *str, Bytecount len,
- struct face_cachel *UNUSED(cachel))
-{
- if (!len)
- return 0;
-
- run_storage[0].ptr = text_storage;
- run_storage[0].len = len;
- run_storage[0].dimension = 1;
- run_storage[0].charset = Qnil;
-
- memcpy (text_storage, str, len);
-
- return 1;
-}
-#endif
-
-#ifdef USE_XFT
-#ifdef WORDS_BIGENDIAN
-#define ALLOCATE_RUNS_TEXT(storage, storage_len, str, len) \
- TO_EXTERNAL_FORMAT (DATA, (str, len), \
- ALLOCA, (storage, storage_len), \
- Qutf_16)
-#else
-extern Lisp_Object Qutf_16_little_endian;
-#define ALLOCATE_RUNS_TEXT(storage, storage_len, str, len) \
- TO_EXTERNAL_FORMAT (DATA, (str, len), \
- ALLOCA, (storage, storage_len), \
- Qutf_16_little_endian)
-#endif
-#endif /* USE_XFT */
-
-#if defined (USE_XFT) && !defined (MULE)
-/*
- Note that in this configuration the "Croatian hack" of using an 8-bit,
- non-Latin-1 font to get localized display without Mule simply isn't
- available. That's by design -- Unicode does not aid or abet that kind
- of punning.
- This means that the cast to XftChar16 gives the correct "conversion" to
- UCS-2. */
-static int
-separate_textual_runs_xft_nomule (struct buffer * UNUSED (buf),
- Extbyte *text_storage,
- struct textual_run *run_storage,
- const Ibyte *str, Bytecount len,
- struct face_cachel *UNUSED (cachel))
-{
- int i;
- if (!len)
- return 0;
-
- run_storage[0].ptr = text_storage;
- run_storage[0].len = len;
- run_storage[0].dimension = 2;
- run_storage[0].charset = Qnil;
-
- return 1;
-}
-#endif
-
-#if defined (USE_XFT) && defined (MULE)
-static int
-separate_textual_runs_xft_mule (struct buffer *buf,
- Extbyte *text_storage,
- struct textual_run *run_storage,
- const Ibyte *str, Bytecount len,
- struct face_cachel *UNUSED (cachel))
-{
- Lisp_Object prev_charset = Qunbound;
- const Ibyte *end = str + len;
- Elemcount runs_so_far = 0;
-
- run_storage[0].ptr = text_storage;
- run_storage[0].len = len;
- run_storage[0].dimension = 2;
- run_storage[0].charset = Qnil;
-
- while (str < end)
- {
- Ichar ch = itext_ichar (str);
- Lisp_Object charset;
- int byte1, byte2;
-
- /* @@#### This use of CONVERR_SUBSTITUTE is somewhat bogus.
- It will substitute a '?' if we can't convert. Not clear whether
- this will work or not. Problem is that we really shouldn't
- be doing things on a charset level. */
- buffer_ichar_to_charset_codepoint (ch, buf, &charset, &byte1, &byte2,
- CONVERR_SUBSTITUTE);
-
- if (!EQ (charset, prev_charset))
- {
- if (runs_so_far)
- run_storage[runs_so_far-1].len =
- (text_storage - run_storage[runs_so_far-1].ptr) >> 1;
- run_storage[runs_so_far].ptr = text_storage;
- run_storage[runs_so_far].dimension = 2;
- run_storage[runs_so_far].charset = charset;
- prev_charset = charset;
- runs_so_far++;
- }
-
- if (valid_unicode_leading_surrogate (*((XftChar16 *) (text_storage))))
- {
- text_storage += sizeof (XftChar16);
- }
- text_storage += sizeof (XftChar16);
- INC_IBYTEPTR (str);
- }
-
- if (runs_so_far)
- run_storage[runs_so_far-1].len =
- (text_storage - run_storage[runs_so_far-1].ptr) >> 1;
- return runs_so_far;
-}
-#endif
-
-#if !defined(USE_XFT) && defined(MULE)
-
-#define ALLOCATE_RUNS_TEXT(storage, storage_len, str, len) \
- (storage = alloca_extbytes ((storage_len = (2 * len))))
-
-/*
- This is the most complex function of this group, due to the various
- indexing schemes used by different fonts. For our purposes, they
- fall into three classes. Some fonts are indexed compatibly with ISO
- 2022; those fonts just use the Mule internal representation directly
- (typically the high bit must be reset; this is determined by the `graphic'
- flag). Some fonts are indexed by Unicode, specifically by UCS-2. These
- are all translated using `ichar_to_unicode'. Finally some fonts have
- irregular indexes, and must be translated ad hoc. In XEmacs ad hoc
- translations are accomplished with CCL programs. */
-static Elemcount
-separate_textual_runs_mule (struct buffer *buf,
- Extbyte *text_storage,
- struct textual_run *run_storage,
- const Ibyte *str, Bytecount len,
- struct face_cachel *cachel)
-{
- Lisp_Object prev_charset = Qunbound, ccl_prog;
- int runs_so_far = 0;
- const Ibyte *end = str + len;
- int dimension = 1, need_ccl_conversion = 0;
- struct ccl_program char_converter;
-
- int translate_to_ucs_2 = 0;
-
- while (str < end)
- {
- Ichar ch = itext_ichar (str);
- Lisp_Object charset;
- int byte1, byte2;
-
- buffer_ichar_to_charset_codepoint (ch, buf, &charset, &byte1, &byte2,
- CONVERR_FAIL);
-
- /* If we can't convert, substitute a '~' (CANT_DISPLAY_CHAR). */
- /* @@#### This is extremely bogus. We want it to substitute the
- Unicode replacement character, but there's no charset for this.
- We really shouldn't be doing things on a charset level. */
- if (NILP (charset))
- {
- charset = Vcharset_ascii;
- byte1 = 0;
- byte2 = CANT_DISPLAY_CHAR;
- }
-
- /* NOTE: Formerly we used to retrieve the XCHARSET_GRAPHIC() here
- and use it below to determine whether to push the bytes into
- the 128-255 range. This is now handled automatically by the
- `offset' property of charsets, which should agree with `graphic'.
- Logically, the `offset' property describes the numeric indices
- of the characters, such as when they are used to index an array
- or font, while the `graphic' property indicates which register
- to select when encoding using iso2022. */
-
- if (!EQ (charset, prev_charset))
- {
- int offs;
-
- /* At this point, dimension' and `prev_charset' refer to just-
- completed run. `runs_so_far' and `text_storage' refer to the
- run about to start. */
- if (runs_so_far)
- {
- /* Update metadata for previous run. */
- run_storage[runs_so_far - 1].len =
- text_storage - run_storage[runs_so_far - 1].ptr;
- if (2 == dimension) run_storage[runs_so_far - 1].len >>= 1;
- }
-
- /* Compute metadata for current run.
- First, classify font.
- If the font is indexed by UCS-2, set `translate_to_ucs_2'.
- Else if the charset has a CCL program, set `need_ccl_conversion'.
- These flags are almost mutually exclusive, but we're sloppy
- about resetting "shadowed" flags. So the flags must be checked
- in the proper order in computing byte1 and byte2, below. */
-
- offs = FACE_CACHEL_OFFSET_ENSURE (cachel, charset);
-
- translate_to_ucs_2 = Stynarr_at (cachel->font_final_stage, offs);
- if (translate_to_ucs_2)
- {
- dimension = 2;
- }
- else
- {
- dimension = XCHARSET_DIMENSION (charset);
-
- /* Check for CCL charset.
- If setup_ccl_program fails, we'll get a garbaged display.
- This should never happen, and even if it does, it should
- be harmless (unless the X server has buggy handling of
- characters undefined in the font). It may be marginally
- more useful to users and debuggers than substituting a
- fixed replacement character. */
- ccl_prog = XCHARSET_CCL_PROGRAM (charset);
- if ((!NILP (ccl_prog))
- && (setup_ccl_program (&char_converter, ccl_prog) >= 0))
- {
- need_ccl_conversion = 1;
- }
- /* Else, the charset must have an ISO 2022-compatible font index.
- */
- }
-
- /* Initialize metadata for current run. */
- run_storage[runs_so_far].ptr = text_storage;
- run_storage[runs_so_far].charset = charset;
- run_storage[runs_so_far].dimension = dimension;
-
- /* Update loop variables. */
- prev_charset = charset;
- runs_so_far++;
- }
-
- /* Must check flags in this order. See comment above. */
- if (translate_to_ucs_2)
- {
- int ucs = ichar_to_unicode (ch, CONVERR_SUBSTITUTE);
- /* If UCS is less than zero or greater than 0xFFFF, set ucs2 to
- REPLACEMENT CHARACTER. */
- ucs = (ucs & ~0xFFFF) ? UNICODE_REPLACEMENT_CHAR : ucs;
-
- byte1 = ucs >> 8;
- byte2 = ucs & 0xFF;
- }
- else if (need_ccl_conversion)
- {
- internal_to_external_charset_codepoint (charset, byte1, byte2,
- &byte1, &byte2, 1);
- char_converter.reg[0] = XCHARSET_ID (charset);
- char_converter.reg[1] = byte1;
- char_converter.reg[2] = byte2;
- ccl_driver (&char_converter, 0, buf, 0, 0, 0, CCL_MODE_ENCODING);
- byte1 = char_converter.reg[1];
- byte2 = char_converter.reg[2];
- get_external_charset_codepoint (charset, make_fixnum (byte1),
- make_fixnum (byte2),
- &byte1, &byte2, 1);
- }
- else if (EQ (charset, Vcharset_ascii) && byte2 != CANT_DISPLAY_CHAR)
- {
- const Ibyte *nonascii;
-
- nonascii = skip_ascii (str, end);
- memcpy (text_storage, str, nonascii - str);
- text_storage += nonascii - str;
- str = nonascii;
- continue;
- }
-
- if (2 == dimension)
- {
- *text_storage++ = (Extbyte) byte1;
- }
-
- *text_storage++ = (Extbyte) byte2;
- INC_IBYTEPTR (str);
- }
-
- if (runs_so_far)
- {
- run_storage[runs_so_far - 1].len =
- text_storage - run_storage[runs_so_far - 1].ptr;
- /* Dimension retains the relevant value for the run before it. */
- if (2 == dimension)
- run_storage[runs_so_far - 1].len >>= 1;
- }
-
- assert (runs_so_far < 0xFFFF);
-
- return runs_so_far;
-}
-#endif
-
-static int
-separate_textual_runs (struct buffer *buf,
- Extbyte *text_storage,
- struct textual_run *run_storage,
- const Ibyte *str, Bytecount len,
- struct face_cachel *cachel)
-{
-#if defined (USE_XFT) && defined (MULE)
- return separate_textual_runs_xft_mule (buf, text_storage, run_storage,
- str, len, cachel);
-#endif
-#if defined (USE_XFT) && !defined (MULE)
- return separate_textual_runs_xft_nomule (buf, text_storage, run_storage,
- str, len, cachel);
-#endif
-#if !defined (USE_XFT) && defined (MULE)
- return separate_textual_runs_mule (buf, text_storage, run_storage,
- str, len, cachel);
-#endif
-#if !defined (USE_XFT) && !defined (MULE)
- return separate_textual_runs_nomule (buf, text_storage, run_storage,
- str, len, cachel);
-#endif
-}
-
-/* !THIS_IS_GTK */
-#endif
-
-/****************************************************************************/
-/* */
-/* Xlike output routines */
-/* */
-/****************************************************************************/
-#ifndef THIS_IS_GTK
-static int
-XLIKE_text_width_single_run (struct frame * USED_IF_XFT (f),
- struct face_cachel *cachel,
- struct textual_run *run)
-{
- Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset);
- Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst);
-
- if (!fi->proportional_p)
- return fi->width * run->len;
-#ifdef USE_XFT
- else if (FONT_INSTANCE_X_XFTFONT (fi))
- {
- static XGlyphInfo glyphinfo;
-
- assert (run->dimension == 2);
-
- XftTextExtents16 (dpy, FONT_INSTANCE_X_XFTFONT (fi),
- (XftChar16 *) run->ptr, run->len, &glyphinfo);
-
- return glyphinfo.xOff;
- }
-#endif
- else if (FONT_INSTANCE_XLIKE_FONT (fi))
- {
- if (run->dimension == 2)
- {
- /* stderr_out ("Measuring wide characters\n"); */
- return XLIKE_TEXT_WIDTH_WIDE (FONT_INSTANCE_XLIKE_FONT (fi),
- run->ptr, run->len);
- }
- else
- {
- return XLIKE_TEXT_WIDTH (FONT_INSTANCE_XLIKE_FONT (fi),
- run->ptr, run->len);
- }
- }
- else
- abort();
- return 0; /* shut up GCC */
-}
-#endif
-
/*****************************************************************************
XLIKE_divider_height
@@ -1005,594 +557,6 @@
#endif
-/*****************************************************************************
- XLIKE_output_string
-
- Given a string and a starting position, output that string in the
- given face. If cursor is true, draw a cursor around the string.
- Correctly handles multiple charsets in the string.
-
- The meaning of the parameters is something like this:
-
- W Window that the text is to be displayed in.
- DL Display line that this text is on. The values in the
- structure are used to determine the vertical position and
- clipping range of the text.
- BUF Pointer to those Ibytes to be output.
- LEN Number of those Ibytes to be output
- XPOS X position in pixels where the text should start being drawn.
- XOFFSET Number of pixels to be chopped off the left side of the
- text. The effect is as if the text were shifted to the
- left this many pixels and clipped at XPOS.
- CLIP_START Clip everything left of this X position.
- WIDTH Clip everything right of XPOS + WIDTH.
- FINDEX Index for the face cache element describing how to display
- the text.
- CURSOR #### I don't understand this. There's something
- strange and overcomplexified with this variable.
- Chuck, explain please?
- CURSOR_START Starting X position of cursor.
- CURSOR_WIDTH Width of cursor in pixels.
- CURSOR_HEIGHT Height of cursor in pixels.
-
- Starting Y position of cursor is the top of the text line.
- The cursor is drawn sometimes whether or not CURSOR is set. ???
- ****************************************************************************/
-#ifndef THIS_IS_GTK
-void
-XLIKE_output_string (struct window *w, struct display_line *dl,
- const Ibyte *buf, Bytecount len,
- int xpos, int xoffset, int clip_start,
- int width, face_index findex, int cursor,
- int cursor_start, int cursor_width, int cursor_height)
-{
- /* General variables */
- struct frame *f = XFRAME (w->frame);
- struct device *d = XDEVICE (f->device);
- XLIKE_DISPLAY dpy = GET_XLIKE_X_DISPLAY (d);
- XLIKE_WINDOW x_win = GET_XLIKE_WINDOW (f);
- Lisp_Object window = wrap_window (w);
-
- int clip_end;
-
- /* Cursor-related variables */
- int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
- int cursor_clip;
- Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor,
- WINDOW_BUFFER (w));
- struct face_cachel *cursor_cachel = 0;
-
- /* Text-related variables */
- Lisp_Object bg_pmap;
- XLIKE_GC gc, bgc;
- int height = XLIKE_DISPLAY_LINE_HEIGHT (dl);
- int ypos = XLIKE_DISPLAY_LINE_YPOS (dl);
- Extbyte *text_storage;
- struct textual_run *runs = alloca_array (struct textual_run, len);
- int nruns, text_storage_len;
- int i;
- struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex);
-
-#ifdef THIS_IS_X
- int use_x_font = 1; /* #### bogus!!
- The logic of this function needs review! */
-#endif
-#ifdef USE_XFT
- Colormap cmap = DEVICE_X_COLORMAP (d);
- Visual *visual = DEVICE_X_VISUAL (d);
- static XftColor fg, bg;
- XftDraw *xftDraw;
-
- /* Lazily initialize frame's xftDraw member. */
- if (!FRAME_X_XFTDRAW (f)) {
- FRAME_X_XFTDRAW (f) = XftDrawCreate (dpy, x_win, visual, cmap);
- }
- xftDraw = FRAME_X_XFTDRAW (f);
-
- /* #### This will probably cause asserts when passed a Lisp integer for a
- color. See ca. line 759 this file.
- #### Maybe xft_convert_color should take an XColor, not a pixel. */
-#define XFT_FROB_LISP_COLOR(color, dim) \
- xft_convert_color_1 (dpy, cmap, visual, \
- &(XCOLOR_INSTANCE_X_COLOR (color)), (dim))
-#endif /* USE_XFT */
-
- if (width < 0)
- width = XLIKE_text_width (f, cachel, buf, len);
-
- /* Regularize the variables passed in. */
- clip_start = min (clip_start, xpos);
- clip_end = xpos + width;
- if (clip_start >= clip_end)
- /* It's all clipped out. */
- return;
-
- xpos -= xoffset;
-
- /* make sure the area we are about to display is subwindow free. */
- redisplay_unmap_subwindows_maybe (f, clip_start, ypos,
- clip_end - clip_start, height);
-
- cursor_clip = (cursor_start >= clip_start &&
- cursor_start < clip_end);
-
- /* This cursor code is really a mess. */
- if (!NILP (w->text_cursor_visible_p)
- && (cursor
- || cursor_clip
- || (cursor_width
- && (cursor_start + cursor_width >= clip_start)
- && !NILP (bar_cursor_value))))
- {
- /* These have to be in separate statements in order to avoid a
- compiler bug. */
- face_index sucks = get_builtin_face_cache_index (w, Vtext_cursor_face);
- cursor_cachel = WINDOW_FACE_CACHEL (w, sucks);
-
- /* We have to reset this since any call to WINDOW_FACE_CACHEL
- may cause the cache to resize and any pointers to it to
- become invalid. */
- cachel = WINDOW_FACE_CACHEL (w, findex);
- }
-
-#ifdef HAVE_XIM
- if (cursor && focus && (cursor_start == clip_start) &&
cursor_height)
- XIM_SetSpotLocation (f, xpos - 2, dl->ypos + dl->descent - 2);
-#endif /* HAVE_XIM */
-
- bg_pmap = cachel->background_pixmap;
- if (!IMAGE_INSTANCEP (bg_pmap)
- || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap)))
- bg_pmap = Qnil;
-
- if ((cursor && focus && NILP (bar_cursor_value)
- && !NILP (w->text_cursor_visible_p)) || NILP (bg_pmap))
- bgc = 0;
- else
- {
- /* Clear the cursor location? */
- bgc = XLIKE_get_gc (f, Qnil, cachel->background, cachel->background,
- bg_pmap, cachel->background_placement, Qnil);
- XLIKE_FILL_RECTANGLE (dpy, x_win, bgc, clip_start,
- ypos, clip_end - clip_start,
- height);
- }
-
- ALLOCATE_RUNS_TEXT (text_storage, text_storage_len, buf, len);
-
- nruns = separate_textual_runs (WINDOW_XBUFFER (w), text_storage, runs,
- buf, len, cachel);
-
- USED (text_storage_len);
-
- for (i = 0; i < nruns; i++)
- {
- Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset);
- Lisp_Font_Instance *fi = XFONT_INSTANCE (font);
- int this_width;
- int need_clipping;
-
- if (EQ (font, Vthe_null_font_instance))
- continue;
-
- this_width = XLIKE_text_width_single_run (f, cachel, runs + i);
- need_clipping = (dl->clip || clip_start > xpos ||
- clip_end < xpos + this_width);
-
- /* XDrawImageString only clears the area equal to the height of
- the given font. It is possible that a font is being displayed
- on a line taller than it is, so this would cause us to fail to
- clear some areas. */
- if ((int) fi->height < (int) (height + dl->clip +
- XLIKE_DISPLAY_LINE_TOP_CLIP (dl)))
- {
- int clear_start = max (xpos, clip_start);
- int clear_end = min (xpos + this_width, clip_end);
-
- if (cursor)
- {
- int ypos1_line, ypos1_string, ypos2_line, ypos2_string;
-
- ypos1_string = dl->ypos - fi->ascent;
- ypos2_string = dl->ypos + fi->descent;
- ypos1_line = ypos;
- ypos2_line = ypos1_line + height;
-
- /* Make sure we don't clear below the real bottom of the
- line. */
- ypos1_string = min (ypos1_string, ypos2_line);
- ypos2_string = min (ypos2_string, ypos2_line);
-
- if (ypos1_line < ypos1_string)
- {
- redisplay_clear_region (window, findex, clear_start, ypos1_line,
- clear_end - clear_start,
- ypos1_string - ypos1_line);
- }
-
- if (ypos2_line > ypos2_string)
- {
- redisplay_clear_region (window, findex, clear_start, ypos2_string,
- clear_end - clear_start,
- ypos2_line - ypos2_string);
- }
- }
- else
- {
- redisplay_clear_region (window, findex, clear_start,
- ypos, clear_end - clear_start,
- height);
- }
- }
-
- if (cursor && cursor_cachel && focus && NILP
(bar_cursor_value))
- {
-#ifdef USE_XFT
- fg = XFT_FROB_LISP_COLOR (cursor_cachel->foreground, 0);
- bg = XFT_FROB_LISP_COLOR (cursor_cachel->background, 0);
-#endif
- gc = XLIKE_get_gc (f, font, cursor_cachel->foreground,
- cursor_cachel->background, Qnil, Qnil, Qnil);
- }
- else if (cachel->dim)
- {
- /* Ensure the gray bitmap exists */
- if (DEVICE_XLIKE_GRAY_PIXMAP (d) == XLIKE_NONE)
- DEVICE_XLIKE_GRAY_PIXMAP (d) =
- XCreateBitmapFromData (dpy, x_win, (char *)gray_bits,
- gray_width, gray_height);
-
- /* Request a GC with the gray stipple pixmap to draw dimmed text */
-#ifdef USE_XFT
- fg = XFT_FROB_LISP_COLOR (cachel->foreground, 1);
- bg = XFT_FROB_LISP_COLOR (cachel->background, 0);
-#endif
- gc = XLIKE_get_gc (f, font, cachel->foreground, cachel->background,
- bg_pmap, cachel->background_placement, Qnil);
- }
- else
- {
-#ifdef USE_XFT
- fg = XFT_FROB_LISP_COLOR (cachel->foreground, 0);
- bg = XFT_FROB_LISP_COLOR (cachel->background, 0);
-#endif
- gc = XLIKE_get_gc (f, font, cachel->foreground, cachel->background,
- Qnil, Qnil, Qnil);
- }
-#ifdef USE_XFT
- {
- XftFont *rf = FONT_INSTANCE_X_XFTFONT (fi);
-
- if (rf)
- {
- use_x_font = 0;
- if (need_clipping)
- {
- Region clip_reg = XCreateRegion();
- XRectangle clip_box = { clip_start, ypos,
- clip_end - clip_start, height };
-
- XUnionRectWithRegion (&clip_box, clip_reg, clip_reg);
- XftDrawSetClip (xftDraw, clip_reg);
- XDestroyRegion (clip_reg);
- }
-
- if (!bgc)
- {
- /* #### Neither rect_height nor XftTextExtents as computed
- below handles the vertical space taken up by antialiasing,
- which for some fonts (eg, Bitstream Vera Sans Mono-16 on
- my Mac PowerBook G4) leaves behind orphaned dots on
- insertion or deletion earlier in the line, especially in
- the case of the underscore character.
- Interestingly, insertion or deletion of a single character
- immediately after a refresh does not leave any droppings,
- but any further insertions or deletions do.
- While adding a pixel to rect_height (mostly) takes care of
- this, it trashes aggressively laid-out elements like the
- modeline (overwriting part of the bevel).
- OK, unconditionally redraw the bevel, and increment
- rect_height by 1. See x_output_display_block. -- sjt */
- struct textual_run *run = &runs[i];
- int rect_width
- = XLIKE_text_width_single_run (f, cachel, run);
-#ifndef USE_XFTTEXTENTS_TO_AVOID_FONT_DROPPINGS
- int rect_height = FONT_INSTANCE_ASCENT (fi)
- + FONT_INSTANCE_DESCENT (fi) + 1;
-#else
- int rect_height = FONT_INSTANCE_ASCENT (fi)
- + FONT_INSTANCE_DESCENT (fi);
- XGlyphInfo gi;
-
- XftTextExtents16 (dpy, FONT_INSTANCE_X_XFTFONT (fi),
- (const XftChar16 *) run->ptr, run->len,
- &gi);
- rect_height = max (rect_height, gi.height);
-#endif
-
- XftDrawRect (xftDraw, &bg,
- xpos, ypos, rect_width, rect_height);
- }
-
- assert (runs[i].dimension == 2);
-
- XftDrawString16 (xftDraw, &fg, rf, xpos, dl->ypos,
- (const XftChar16 *) runs[i].ptr, runs[i].len);
- }
- }
-#endif /* USE_XFT */
-
- if (use_x_font)
- {
- if (need_clipping)
- {
- XLIKE_RECTANGLE clip_box;
-
- clip_box.x = 0;
- clip_box.y = 0;
- clip_box.width = clip_end - clip_start;
- clip_box.height = height;
-
- XLIKE_SET_CLIP_RECTANGLE (dpy, gc, clip_start, ypos, &clip_box);
- }
-
- if (runs[i].dimension == 1)
- (bgc ? XDrawString : XDrawImageString)
- (dpy, x_win, gc, xpos, dl->ypos,
- (char *) runs[i].ptr, runs[i].len);
- else
- (bgc ? XDrawString16 : XDrawImageString16)
- (dpy, x_win, gc, xpos, dl->ypos,
- (XChar2b *) runs[i].ptr, runs[i].len);
- }
-
- /* We draw underlines in the same color as the text. */
- if (cachel->underline)
- {
- int upos, uthick;
- unsigned long upos_ext, uthick_ext;
- XFontStruct *fs =
- use_x_font ? FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)) : 0;
- /* #### the logic of the next two may be suboptimal: we may want
- to use the POSITION and/or THICKNESS information with Xft */
- if (fs && XGetFontProperty (fs, XA_UNDERLINE_POSITION, &upos_ext))
- upos = (int) upos_ext;
- else
- upos = dl->descent / 2;
- if (fs && XGetFontProperty (fs, XA_UNDERLINE_THICKNESS, &uthick_ext))
- uthick = (int) uthick_ext;
- else
- uthick = 1;
-
- if (dl->ypos + upos < dl->ypos + dl->descent - dl->clip)
- {
- if (dl->ypos + upos + uthick > dl->ypos + dl->descent - dl->clip)
- uthick = dl->descent - dl->clip - upos;
-
- if (uthick == 1)
- {
- XLIKE_DRAW_LINE (dpy, x_win, gc, xpos, dl->ypos + upos,
- xpos + this_width, dl->ypos + upos);
- }
- else if (uthick > 1)
- {
- XLIKE_FILL_RECTANGLE (dpy, x_win, gc, xpos,
- dl->ypos + upos, this_width, uthick);
- }
- }
- }
-
- if (cachel->strikethru)
- {
- int ascent, descent, upos, uthick;
- unsigned long ascent_ext, descent_ext, uthick_ext;
- XFontStruct *fs = FONT_INSTANCE_X_FONT (fi);
-
- if (!use_x_font)
- {
- ascent = dl->ascent;
- descent = dl->descent;
- uthick = 1;
- }
- else
- {
- if (!XGetFontProperty (fs, XA_STRIKEOUT_ASCENT, &ascent_ext))
- ascent = fs->ascent;
- else
- ascent = (int) ascent_ext;
- if (!XGetFontProperty (fs, XA_STRIKEOUT_DESCENT, &descent_ext))
- descent = fs->descent;
- else
- descent = (int) descent_ext;
- if (!XGetFontProperty (fs, XA_UNDERLINE_THICKNESS, &uthick_ext))
- uthick = 1;
- else
- uthick = (int) uthick_ext;
- }
- upos = ascent - ((ascent + descent) / 2) + 1;
-
- /* Generally, upos will be positive (above the baseline),so
- subtract */
- if (dl->ypos - upos < dl->ypos + dl->descent - dl->clip)
- {
- if (dl->ypos - upos + uthick > dl->ypos + dl->descent - dl->clip)
- uthick = dl->descent - dl->clip + upos;
-
- if (uthick == 1)
- XLIKE_DRAW_LINE (dpy, x_win, gc, xpos, dl->ypos - upos,
- xpos + this_width, dl->ypos - upos);
- else if (uthick > 1)
- XLIKE_FILL_RECTANGLE (dpy, x_win, gc, xpos, dl->ypos + upos,
- this_width, uthick);
- }
- }
- /* Restore the GC */
- if (need_clipping)
- {
-#ifdef USE_XFT
- if (!use_x_font)
- {
- XftDrawSetClip (xftDraw, 0);
- }
- else
-#endif
- XLIKE_CLEAR_CLIP_MASK (dpy, gc);
- }
-
- /* If we are actually superimposing the cursor then redraw with just
- the appropriate section highlighted. */
- if (cursor_clip && !cursor && focus && cursor_cachel)
- {
-#ifdef USE_XFT
- if (!use_x_font) /* Xft */
- {
- XftFont *rf = FONT_INSTANCE_X_XFTFONT (fi);
-
- { /* set up clipping */
- Region clip_reg = XCreateRegion();
- XRectangle clip_box = { cursor_start, ypos,
- cursor_width, height };
-
- XUnionRectWithRegion (&clip_box, clip_reg, clip_reg);
- XftDrawSetClip (xftDraw, clip_reg);
- XDestroyRegion (clip_reg);
- }
- { /* draw background rectangle & draw text */
- int rect_height = FONT_INSTANCE_ASCENT (fi)
- + FONT_INSTANCE_DESCENT (fi);
- int rect_width
- = XLIKE_text_width_single_run (f, cachel, &runs[i]);
- XftColor xft_color;
-
- xft_color = XFT_FROB_LISP_COLOR (cursor_cachel->background, 0);
- XftDrawRect (xftDraw, &xft_color,
- xpos, ypos, rect_width, rect_height);
-
- xft_color = XFT_FROB_LISP_COLOR (cursor_cachel->foreground, 0);
- assert (runs[i].dimension == 2);
-
- XftDrawString16 (xftDraw, &xft_color, rf, xpos, dl->ypos,
- (XftChar16 *) runs[i].ptr, runs[i].len);
- }
-
- XftDrawSetClip (xftDraw, 0);
- }
- else /* core font, not Xft */
-#endif /* USE_XFT */
- {
- XLIKE_RECTANGLE clip_box;
- XLIKE_GC cgc;
- cgc = XLIKE_get_gc (f, font, cursor_cachel->foreground,
- cursor_cachel->background, Qnil, Qnil, Qnil);
-
- clip_box.x = 0;
- clip_box.y = 0;
- clip_box.width = cursor_width;
- clip_box.height = height;
-
- XLIKE_SET_CLIP_RECTANGLE (dpy, cgc, cursor_start, ypos,
- &clip_box);
- if (runs[i].dimension == 1)
- XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos,
- (char *) runs[i].ptr, runs[i].len);
- else
- XDrawImageString16 (dpy, x_win, cgc, xpos, dl->ypos,
- (XChar2b *) runs[i].ptr, runs[i].len);
-
- XLIKE_CLEAR_CLIP_MASK (dpy, cgc);
- }
- }
-
- xpos += this_width;
- }
-
- /* Draw the non-focus box or bar-cursor as needed. */
- /* Can't this logic be simplified? */
- if (cursor_cachel
- && ((cursor && !focus && NILP (bar_cursor_value))
- || (cursor_width
- && (cursor_start + cursor_width >= clip_start)
- && !NILP (bar_cursor_value))))
- {
- int tmp_height, tmp_y;
- int bar_width = EQ (bar_cursor_value, Qt) ? 1 : 2;
- int need_clipping = (cursor_start < clip_start
- || clip_end < cursor_start + cursor_width);
-
- /* #### This value is correct (as far as I know) because
- all of the times we need to draw this cursor, we will
- be called with exactly one character, so we know we
- can always use runs[0].
-
- This is bogus as all hell, however. The cursor handling in
- this function is way bogus and desperately needs to be
- cleaned up. (In particular, the drawing of the cursor should
- really really be separated out of this function. This may be
- a bit tricky now because this function itself does way too
- much stuff, a lot of which needs to be moved into
- redisplay.c.) This is the only way to be able to easily add
- new cursor types or (e.g.) make the bar cursor be able to
- span two characters instead of overlaying just one. */
- int bogusly_obtained_ascent_value =
- XFONT_INSTANCE (FACE_CACHEL_FONT (cachel, runs[0].charset))->ascent;
-
- if (!NILP (bar_cursor_value))
- {
- gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil,
- Qnil, Qnil,
- make_fixnum (bar_width));
- }
- else
- {
- gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background,
- Qnil, Qnil, Qnil, Qnil);
- }
- tmp_y = dl->ypos - bogusly_obtained_ascent_value;
-
- tmp_height = cursor_height;
- if (tmp_y + tmp_height > (int) (ypos + height))
- {
- tmp_y = ypos + height - tmp_height;
- tmp_y = min (tmp_y, ypos);
- tmp_height = ypos + height - tmp_y;
- }
-
- if (need_clipping)
- {
- XLIKE_RECTANGLE clip_box;
- clip_box.x = 0;
- clip_box.y = 0;
- clip_box.width = clip_end - clip_start;
- clip_box.height = tmp_height;
- XLIKE_SET_CLIP_RECTANGLE (dpy, gc, clip_start, tmp_y, &clip_box);
- }
-
- if (!focus && NILP (bar_cursor_value))
- {
- XLIKE_DRAW_RECTANGLE (dpy, x_win, gc, cursor_start, tmp_y,
- cursor_width - 1, tmp_height - 1);
- }
- else if (focus && !NILP (bar_cursor_value))
- {
- XLIKE_DRAW_LINE (dpy, x_win, gc, cursor_start + bar_width - 1, tmp_y,
- cursor_start + bar_width - 1,
- tmp_y + tmp_height - 1);
- }
-
- /* Restore the GC */
- if (need_clipping)
- {
- XLIKE_CLEAR_CLIP_MASK (dpy, gc);
- }
- }
-
-#ifdef USE_XFT
-#undef XFT_FROB_LISP_COLOR
-#endif
-}
-/* not THIS_IS_GTK */
-#endif
-
static void
XLIKE_output_pixmap (struct window *w, Lisp_Object image_instance,
struct display_box *db, struct display_glyph_area *dga,
--
‘As I sat looking up at the Guinness ad, I could never figure out /
How your man stayed up on the surfboard after forty pints of stout’
(C. Moore)