Diff

Differences From Artifact [d2e496d221]:

To Artifact [d683705790]:


497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531





532
533
534
535
536
537
538

#define KEY_PRESSED(k) \
    (inst->keystate[(k) / 32] & (1 << ((k) % 32)))

gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
    struct gui_data *inst = (struct gui_data *)data;
    char output[32];
    wchar_t ucsoutput[2];
    int ucsval, start, end, special, use_ucsoutput;

    /* Remember the timestamp. */
    inst->input_event_time = event->time;

    /* By default, nothing is generated. */
    end = start = 0;
    special = use_ucsoutput = FALSE;


    /*
     * If Alt is being released after typing an Alt+numberpad
     * sequence, we should generate the code that was typed.
     * 
     * Note that we only do this if more than one key was actually
     * pressed - I don't think Alt+NumPad4 should be ^D or that
     * Alt+NumPad3 should be ^C, for example. There's no serious
     * inconvenience in having to type a zero before a single-digit
     * character code.
     */
    if (event->type == GDK_KEY_RELEASE &&
	(event->keyval == GDK_Meta_L || event->keyval == GDK_Alt_L ||
	 event->keyval == GDK_Meta_R || event->keyval == GDK_Alt_R) &&
	inst->alt_keycode >= 0 && inst->alt_digits > 1) {
#ifdef KEY_DEBUGGING
	printf("Alt key up, keycode = %d\n", inst->alt_keycode);
#endif





	output[0] = inst->alt_keycode;
	end = 1;
	goto done;
    }

    if (event->type == GDK_KEY_PRESS) {
#ifdef KEY_DEBUGGING







|

|







>


















>
>
>
>
>







497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544

#define KEY_PRESSED(k) \
    (inst->keystate[(k) / 32] & (1 << ((k) % 32)))

gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
    struct gui_data *inst = (struct gui_data *)data;
    char output[256];
    wchar_t ucsoutput[2];
    int ucsval, start, end, special, output_charset, use_ucsoutput;

    /* Remember the timestamp. */
    inst->input_event_time = event->time;

    /* By default, nothing is generated. */
    end = start = 0;
    special = use_ucsoutput = FALSE;
    output_charset = CS_ISO8859_1;

    /*
     * If Alt is being released after typing an Alt+numberpad
     * sequence, we should generate the code that was typed.
     * 
     * Note that we only do this if more than one key was actually
     * pressed - I don't think Alt+NumPad4 should be ^D or that
     * Alt+NumPad3 should be ^C, for example. There's no serious
     * inconvenience in having to type a zero before a single-digit
     * character code.
     */
    if (event->type == GDK_KEY_RELEASE &&
	(event->keyval == GDK_Meta_L || event->keyval == GDK_Alt_L ||
	 event->keyval == GDK_Meta_R || event->keyval == GDK_Alt_R) &&
	inst->alt_keycode >= 0 && inst->alt_digits > 1) {
#ifdef KEY_DEBUGGING
	printf("Alt key up, keycode = %d\n", inst->alt_keycode);
#endif
	/*
	 * FIXME: we might usefully try to do something clever here
	 * about interpreting the generated key code in a way that's
	 * appropriate to the line code page.
	 */
	output[0] = inst->alt_keycode;
	end = 1;
	goto done;
    }

    if (event->type == GDK_KEY_PRESS) {
#ifdef KEY_DEBUGGING
632
633
634
635
636
637
638









639























640










641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
	}

	special = FALSE;
	use_ucsoutput = FALSE;

	/* ALT+things gives leading Escape. */
	output[0] = '\033';









	strncpy(output+1, event->string, 31);























	if (!*event->string &&










	    (ucsval = keysym_to_unicode(event->keyval)) >= 0) {
	    ucsoutput[0] = '\033';
	    ucsoutput[1] = ucsval;
	    use_ucsoutput = TRUE;
	    end = 2;
	} else {
	    output[31] = '\0';
	    end = strlen(output);
	}
	if (event->state & GDK_MOD1_MASK) {
	    start = 0;
	    if (end == 1) end = 0;
	} else
	    start = 1;

	/* Control-` is the same as Control-\ (unless gtk has a better idea) */
	if (!event->string[0] && event->keyval == '`' &&
	    (event->state & GDK_CONTROL_MASK)) {
	    output[1] = '\x1C';
	    use_ucsoutput = FALSE;
	    end = 2;
	}

	/* Control-Break sends a Break special to the backend */







>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>






|









|







638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
	}

	special = FALSE;
	use_ucsoutput = FALSE;

	/* ALT+things gives leading Escape. */
	output[0] = '\033';
#if !GTK_CHECK_VERSION(2,0,0)
	/*
	 * In vanilla X, and hence also GDK 1.2, the string received
	 * as part of a keyboard event is assumed to be in
	 * ISO-8859-1. (Seems woefully shortsighted in i18n terms,
	 * but it's true: see the man page for XLookupString(3) for
	 * confirmation.)
	 */
	output_charset = CS_ISO8859_1;
	strncpy(output+1, event->string, lenof(output)-1);
#else
	/*
	 * GDK 2.0 arranges to have done some translation for us: in
	 * GDK 2.0, event->string is encoded in the current locale.
	 *
	 * (However, it's also deprecated; we really ought to be
	 * using a GTKIMContext.)
	 *
	 * So we use the standard C library function mbstowcs() to
	 * convert from the current locale into Unicode; from there
	 * we can convert to whatever PuTTY is currently working in.
	 * (In fact I convert straight back to UTF-8 from
	 * wide-character Unicode, for the sake of simplicity: that
	 * way we can still use exactly the same code to manipulate
	 * the string, such as prefixing ESC.)
	 */
	output_charset = CS_UTF8;
	{
	    wchar_t widedata[32], *wp;
	    int wlen;
	    int ulen;

	    wlen = mb_to_wc(DEFAULT_CODEPAGE, 0,
			    event->string, strlen(event->string),
			    widedata, lenof(widedata)-1);

	    wp = widedata;
	    ulen = charset_from_unicode(&wp, &wlen, output+1, lenof(output)-2,
					CS_UTF8, NULL, NULL, 0);
	    output[1+ulen] = '\0';
	}
#endif

	if (!output[1] &&
	    (ucsval = keysym_to_unicode(event->keyval)) >= 0) {
	    ucsoutput[0] = '\033';
	    ucsoutput[1] = ucsval;
	    use_ucsoutput = TRUE;
	    end = 2;
	} else {
	    output[lenof(output)-1] = '\0';
	    end = strlen(output);
	}
	if (event->state & GDK_MOD1_MASK) {
	    start = 0;
	    if (end == 1) end = 0;
	} else
	    start = 1;

	/* Control-` is the same as Control-\ (unless gtk has a better idea) */
	if (!output[1] && event->keyval == '`' &&
	    (event->state & GDK_CONTROL_MASK)) {
	    output[1] = '\x1C';
	    use_ucsoutput = FALSE;
	    end = 2;
	}

	/* Control-Break sends a Break special to the backend */
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696

697
698
699
700
701
702
703
	    output[1] = '\015';
	    use_ucsoutput = FALSE;
	    end = 2;
	    special = TRUE;
	}

	/* Control-2, Control-Space and Control-@ are NUL */
	if (!event->string[0] &&
	    (event->keyval == ' ' || event->keyval == '2' ||
	     event->keyval == '@') &&
	    (event->state & (GDK_SHIFT_MASK |
			     GDK_CONTROL_MASK)) == GDK_CONTROL_MASK) {
	    output[1] = '\0';
	    use_ucsoutput = FALSE;
	    end = 2;
	}

	/* Control-Shift-Space is 160 (ISO8859 nonbreaking space) */
	if (!event->string[0] && event->keyval == ' ' &&
	    (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) ==
	    (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) {
	    output[1] = '\240';

	    use_ucsoutput = FALSE;
	    end = 2;
	}

	/* We don't let GTK tell us what Backspace is! We know better. */
	if (event->keyval == GDK_BackSpace &&
	    !(event->state & GDK_SHIFT_MASK)) {







|










|



>







723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
	    output[1] = '\015';
	    use_ucsoutput = FALSE;
	    end = 2;
	    special = TRUE;
	}

	/* Control-2, Control-Space and Control-@ are NUL */
	if (!output[1] &&
	    (event->keyval == ' ' || event->keyval == '2' ||
	     event->keyval == '@') &&
	    (event->state & (GDK_SHIFT_MASK |
			     GDK_CONTROL_MASK)) == GDK_CONTROL_MASK) {
	    output[1] = '\0';
	    use_ucsoutput = FALSE;
	    end = 2;
	}

	/* Control-Shift-Space is 160 (ISO8859 nonbreaking space) */
	if (!output[1] && event->keyval == ' ' &&
	    (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) ==
	    (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) {
	    output[1] = '\240';
	    output_charset = CS_ISO8859_1;
	    use_ucsoutput = FALSE;
	    end = 2;
	}

	/* We don't let GTK tell us what Backspace is! We know better. */
	if (event->keyval == GDK_BackSpace &&
	    !(event->state & GDK_SHIFT_MASK)) {
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
	     * should never matter.
	     */
	    output[end] = '\0';	       /* NUL-terminate */
	    if (inst->ldisc)
		ldisc_send(inst->ldisc, output+start, -2, 1);
	} else if (!inst->direct_to_font) {
	    if (!use_ucsoutput) {
		/*
		 * The stuff we've just generated is assumed to be
		 * ISO-8859-1! This sounds insane, but `man
		 * XLookupString' agrees: strings of this type
		 * returned from the X server are hardcoded to
		 * 8859-1. Strictly speaking we should be doing
		 * this using some sort of GtkIMContext, which (if
		 * we're lucky) would give us our data directly in
		 * Unicode; but that's not supported in GTK 1.2 as
		 * far as I can tell, and it's poorly documented
		 * even in 2.0, so it'll have to wait.
		 */
		if (inst->ldisc)
		    lpage_send(inst->ldisc, CS_ISO8859_1, output+start,
			       end-start, 1);
	    } else {
		/*
		 * We generated our own Unicode key data from the
		 * keysym, so use that instead.
		 */
		if (inst->ldisc)







<
<
<
<
<
<
<
<
<
<
<
<

|







1094
1095
1096
1097
1098
1099
1100












1101
1102
1103
1104
1105
1106
1107
1108
1109
	     * should never matter.
	     */
	    output[end] = '\0';	       /* NUL-terminate */
	    if (inst->ldisc)
		ldisc_send(inst->ldisc, output+start, -2, 1);
	} else if (!inst->direct_to_font) {
	    if (!use_ucsoutput) {












		if (inst->ldisc)
		    lpage_send(inst->ldisc, output_charset, output+start,
			       end-start, 1);
	    } else {
		/*
		 * We generated our own Unicode key data from the
		 * keysym, so use that instead.
		 */
		if (inst->ldisc)