Diff

Differences From Artifact [cbc2ff850a]:

To Artifact [cad0cb698f]:


40
41
42
43
44
45
46
47


48
49
50
51
52
53
54
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55







-
+
+







extern char **pty_argv;	       /* declared in pty.c */
extern int use_pty_argv;

struct gui_data {
    GtkWidget *window, *area, *sbar;
    GtkBox *hbox;
    GtkAdjustment *sbar_adjust;
    GtkWidget *menu, *specialsmenu, *specialsitem1, *specialsitem2;
    GtkWidget *menu, *specialsmenu, *specialsitem1, *specialsitem2,
	*restartitem;
    GtkWidget *sessionsmenu;
    GdkPixmap *pixmap;
    GdkFont *fonts[4];                 /* normal, bold, wide, widebold */
    struct {
	int charset;
	int is_wide;
    } fontinfo[4];
89
90
91
92
93
94
95


96
97
98
99
100
101
102
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105







+
+







    GdkGC *gc;
    struct gui_data *inst;
};

static int send_raw_mouse;

static char *app_name = "pterm";

static void start_backend(struct gui_data *inst);

char *x_get_default(const char *key)
{
    return XGetDefault(GDK_DISPLAY(), app_name, key);
}

void connection_fatal(void *frontend, char *p, ...)
977
978
979
980
981
982
983

984

985
986
987
988
989
990
991
992
993
994
995
996
997
998

999
1000


1001
1002
1003
1004
1005

1006

1007
1008
1009
1010
1011
1012

1013

1014
1015
1016
1017
1018
1019
1020
980
981
982
983
984
985
986
987

988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003


1004
1005
1006
1007
1008
1009
1010
1011

1012
1013
1014
1015
1016
1017
1018
1019

1020
1021
1022
1023
1024
1025
1026
1027







+
-
+














+
-
-
+
+





+
-
+






+
-
+








	if (special) {
	    /*
	     * For special control characters, the character set
	     * should never matter.
	     */
	    output[end] = '\0';	       /* NUL-terminate */
	    if (inst->ldisc)
	    ldisc_send(inst->ldisc, output+start, -2, 1);
		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);
		    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)
		luni_send(inst->ldisc, ucsoutput+start, end-start, 1);
		    luni_send(inst->ldisc, ucsoutput+start, end-start, 1);
	    }
	} else {
	    /*
	     * In direct-to-font mode, we just send the string
	     * exactly as we received it.
	     */
	    if (inst->ldisc)
	    ldisc_send(inst->ldisc, output+start, end-start, 1);
		ldisc_send(inst->ldisc, output+start, end-start, 1);
	}

	show_mouseptr(inst, 0);
	term_seen_key_event(inst->term);
	term_out(inst->term);
    }

1130
1131
1132
1133
1134
1135
1136











1137
1138
1139
1140
1141
1142
1143
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161







+
+
+
+
+
+
+
+
+
+
+








    if (!inst->exited &&
        (exitcode = inst->back->exitcode(inst->backhandle)) >= 0) {
	inst->exited = TRUE;
	if (inst->cfg.close_on_exit == FORCE_ON ||
	    (inst->cfg.close_on_exit == AUTO && exitcode == 0))
	    exit(0);		       /* just go. */
	if (inst->ldisc) {
	    ldisc_free(inst->ldisc);
	    inst->ldisc = NULL;
	}
	if (inst->back) {
	    inst->back->free(inst->backhandle);
	    inst->backhandle = NULL;
	    inst->back = NULL;
	    update_specials_menu(inst);
	}
	gtk_widget_show(inst->restartitem);
    }

    term_update(inst->term);
    term_blink(inst->term, 0);
    return TRUE;
}

2728
2729
2730
2731
2732
2733
2734

2735

2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749

2750

2751
2752
2753
2754
2755
2756
2757
2746
2747
2748
2749
2750
2751
2752
2753

2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769

2770
2771
2772
2773
2774
2775
2776
2777







+
-
+














+
-
+







    term_clrsb(inst->term);
}

void reset_terminal_menuitem(GtkMenuItem *item, gpointer data)
{
    struct gui_data *inst = (struct gui_data *)data;
    term_pwron(inst->term);
    if (inst->ldisc)
    ldisc_send(inst->ldisc, NULL, 0, 0);
	ldisc_send(inst->ldisc, NULL, 0, 0);
}

void copy_all_menuitem(GtkMenuItem *item, gpointer data)
{
    struct gui_data *inst = (struct gui_data *)data;
    term_copyall(inst->term);
}

void special_menuitem(GtkMenuItem *item, gpointer data)
{
    struct gui_data *inst = (struct gui_data *)data;
    int code = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(item),
						   "user-data"));

    if (inst->back)
    inst->back->special(inst->backhandle, code);
	inst->back->special(inst->backhandle, code);
}

void about_menuitem(GtkMenuItem *item, gpointer data)
{
    struct gui_data *inst = (struct gui_data *)data;
    about_box(inst->window);
}
2784
2785
2786
2787
2788
2789
2790

2791

2792
2793
2794

2795

2796
2797
2798
2799
2800
2801
2802
2804
2805
2806
2807
2808
2809
2810
2811

2812
2813
2814
2815
2816

2817
2818
2819
2820
2821
2822
2823
2824







+
-
+



+
-
+








        /* Pass new config data to the logging module */
        log_reconfig(inst->logctx, &cfg2);
        /*
         * Flush the line discipline's edit buffer in the case
         * where local editing has just been disabled.
         */
        if (inst->ldisc)
        ldisc_send(inst->ldisc, NULL, 0, 0);
	    ldisc_send(inst->ldisc, NULL, 0, 0);
        /* Pass new config data to the terminal */
        term_reconfig(inst->term, &cfg2);
        /* Pass new config data to the back end */
        if (inst->back)
        inst->back->reconfig(inst->backhandle, &cfg2);
	    inst->back->reconfig(inst->backhandle, &cfg2);

        /*
         * Just setting inst->cfg is sufficient to cause colour
         * setting changes to appear on the next ESC]R palette
         * reset. But we should also check whether any colour
         * settings have been changed, and revert the ones that
         * have to the new default, on the assumption that the user
3078
3079
3080
3081
3082
3083
3084











3085
3086
3087
3088
3089
3090
3091
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124







+
+
+
+
+
+
+
+
+
+
+








void new_session_menuitem(GtkMenuItem *item, gpointer data)
{
    struct gui_data *inst = (struct gui_data *)data;

    fork_and_exec_self(inst, -1, NULL);
}

void restart_session_menuitem(GtkMenuItem *item, gpointer data)
{
    struct gui_data *inst = (struct gui_data *)data;

    if (!inst->back) {
	logevent(inst, "----- Session restarted -----");
	start_backend(inst);
	inst->exited = FALSE;
    }
}

void saved_session_menuitem(GtkMenuItem *item, gpointer data)
{
    struct gui_data *inst = (struct gui_data *)data;
    char *str = (char *)gtk_object_get_data(GTK_OBJECT(item), "user-data");

    fork_and_exec_self(inst, -1, "-load", str, NULL);
3100
3101
3102
3103
3104
3105
3106

3107




3108
3109
3110
3111
3112
3113
3114
3133
3134
3135
3136
3137
3138
3139
3140

3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151







+
-
+
+
+
+








void update_specials_menu(void *frontend)
{
    struct gui_data *inst = (struct gui_data *)frontend;

    const struct telnet_special *specials;

    if (inst->back)
    specials = inst->back->get_specials(inst->backhandle);
	specials = inst->back->get_specials(inst->backhandle);
    else
	specials = NULL;

    gtk_container_foreach(GTK_CONTAINER(inst->specialsmenu),
			  (GtkCallback)gtk_widget_destroy, NULL);
    if (specials) {
	int i;
	GtkWidget *menuitem;
	for (i = 0; specials[i].name; i++) {
	    if (*specials[i].name) {
3126
3127
3128
3129
3130
3131
3132
3133

3134
3135










































3136
3137
3138
3139
3140
3141
3142
3163
3164
3165
3166
3167
3168
3169

3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221







-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	gtk_widget_show(inst->specialsitem2);
    } else {
	gtk_widget_hide(inst->specialsitem1);
	gtk_widget_hide(inst->specialsitem2);
    }
}

int pt_main(int argc, char **argv)
static void start_backend(struct gui_data *inst)
{
    extern Backend *select_backend(Config *cfg);
    char *realhost;
    const char *error;

    inst->back = select_backend(&inst->cfg);

    error = inst->back->init((void *)inst, &inst->backhandle,
			     &inst->cfg, inst->cfg.host, inst->cfg.port,
			     &realhost, inst->cfg.tcp_nodelay,
			     inst->cfg.tcp_keepalives);

    if (error) {
	char *msg = dupprintf("Unable to open connection to %s:\n%s",
			      inst->cfg.host, error);
	inst->exited = TRUE;
	fatal_message_box(inst->window, msg);
	sfree(msg);
	exit(0);
    }

    if (inst->cfg.wintitle[0]) {
	set_title(inst, inst->cfg.wintitle);
	set_icon(inst, inst->cfg.wintitle);
    } else {
	char *title = make_default_wintitle(realhost);
	set_title(inst, title);
	set_icon(inst, title);
	sfree(title);
    }
    inst->back->provide_logctx(inst->backhandle, inst->logctx);
    update_specials_menu(inst);

    term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle);

    inst->ldisc =
	ldisc_create(&inst->cfg, inst->term, inst->back, inst->backhandle,
		     inst);

    gtk_widget_hide(inst->restartitem);
}

int pt_main(int argc, char **argv)
{
    extern int cfgbox(Config *cfg);
    struct gui_data *inst;

    /*
     * Create an instance structure and initialise to zeroes
     */
    inst = snew(struct gui_data);
3294
3295
3296
3297
3298
3299
3300



3301
3302
3303
3304
3305
3306
3307
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389







+
+
+







    gtk_widget_show(menuitem); \
    if (func != NULL) \
	gtk_signal_connect(GTK_OBJECT(menuitem), "activate", \
			       GTK_SIGNAL_FUNC(func), inst); \
} while (0)
	if (new_session)
	    MKMENUITEM("New Session", new_session_menuitem);
        MKMENUITEM("Restart Session", restart_session_menuitem);
	inst->restartitem = menuitem;
	gtk_widget_hide(inst->restartitem);
        MKMENUITEM("Duplicate Session", dup_session_menuitem);
	if (saved_sessions) {
	    struct sesslist sesslist;
	    int i;

	    inst->sessionsmenu = gtk_menu_new();

3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370

3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3441
3442
3443
3444
3445
3446
3447





3448




3449


























3450
3451
3452
3453
3454
3455
3456







-
-
-
-
-
+
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    inst->logctx = log_init(inst, &inst->cfg);
    term_provide_logctx(inst->term, inst->logctx);

    uxsel_init();

    term_size(inst->term, inst->cfg.height, inst->cfg.width, inst->cfg.savelines);

    inst->back = select_backend(&inst->cfg);
    {
	char *realhost;
	const char *error;

    start_backend(inst);
	error = inst->back->init((void *)inst, &inst->backhandle,
                                 &inst->cfg, inst->cfg.host, inst->cfg.port,
                                 &realhost, inst->cfg.tcp_nodelay,
				 inst->cfg.tcp_keepalives);

	if (error) {
	    char *msg = dupprintf("Unable to open connection to %s:\n%s",
                                  inst->cfg.host, error);
            inst->exited = TRUE;
	    fatal_message_box(inst->window, msg);
            sfree(msg);
	    return 0;
	}

        if (inst->cfg.wintitle[0]) {
            set_title(inst, inst->cfg.wintitle);
            set_icon(inst, inst->cfg.wintitle);
	} else {
            char *title = make_default_wintitle(realhost);
            set_title(inst, title);
            set_icon(inst, title);
            sfree(title);
        }
    }
    inst->back->provide_logctx(inst->backhandle, inst->logctx);
    update_specials_menu(inst);

    term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle);

    inst->ldisc =
	ldisc_create(&inst->cfg, inst->term, inst->back, inst->backhandle, inst);
    ldisc_send(inst->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */

    /* now we're reday to deal with the child exit handler being
     * called */
    block_signal(SIGCHLD, 0);

    /*