+ the copyright date appears twice, once in the About box and
once in the Licence box. Don't forget to change both!
- putty/mac/mac_res.r
+ - putty/unix/gtkdlg.c
+ + the copyright date appears twice, once in the About box and
+ once in the Licence box. Don't forget to change both!
The documentation (both the preamble blurb and the licence appendix):
The website:
- putty-website/licence.html
-
+
Before tagging a release
------------------------
pterm : [X] pterm terminal wcwidth uxucs uxmisc tree234 misc ldisc ldiscucs
+ logging uxprint settings pty uxsel be_none uxstore signal CHARSET
- + cmdline ptermm
+ + cmdline ptermm UXCFG version
putty : [X] pterm terminal wcwidth uxucs uxmisc tree234 misc ldisc ldiscucs
+ logging uxprint settings pty uxsel be_all uxstore signal CHARSET
+ uxputty NONSSH UXSSH UXMISC logging ux_x11 UXCFG
extern const int be_default_protocol;
/*
+ * Name of this particular application, for use in the config box
+ * and other pieces of text.
+ */
+extern const char *const appname;
+
+/*
* IMPORTANT POLICY POINT: everything in this structure which wants
* to be treated like an integer must be an actual, honest-to-
* goodness `int'. No enum-typed variables. This is because parts
sfree(msg);
cleanup_exit(1);
}
+
+static GtkWidget *aboutbox = NULL;
+
+static void about_close_clicked(GtkButton *button, gpointer data)
+{
+ gtk_widget_destroy(aboutbox);
+ aboutbox = NULL;
+}
+
+static void licence_clicked(GtkButton *button, gpointer data)
+{
+ char *title;
+
+ char *licence =
+ "Copyright 1997-2003 Simon Tatham.\n\n"
+
+ "Portions copyright Robert de Bath, Joris van Rantwijk, Delian "
+ "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas "
+ "Barry, Justin Bradford, Ben Harris, and CORE SDI S.A.\n\n"
+
+ "Permission is hereby granted, free of charge, to any person "
+ "obtaining a copy of this software and associated documentation "
+ "files (the ""Software""), to deal in the Software without restriction, "
+ "including without limitation the rights to use, copy, modify, merge, "
+ "publish, distribute, sublicense, and/or sell copies of the Software, "
+ "and to permit persons to whom the Software is furnished to do so, "
+ "subject to the following conditions:\n\n"
+
+ "The above copyright notice and this permission notice shall be "
+ "included in all copies or substantial portions of the Software.\n\n"
+
+ "THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT "
+ "WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, "
+ "INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF "
+ "MERCHANTABILITY, FITNESS FOR A PARTICULAR "
+ "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE "
+ "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES "
+ "OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, "
+ "TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN "
+ "CONNECTION WITH THE SOFTWARE OR THE USE OR "
+ "OTHER DEALINGS IN THE SOFTWARE.";
+
+ title = dupcat(appname, " Licence", NULL);
+ assert(aboutbox != NULL);
+ messagebox(aboutbox, title, licence,
+ string_width("LONGISH LINE OF TEXT SO THE LICENCE"
+ " BOX ISN'T EXCESSIVELY TALL AND THIN"),
+ "OK", 'o', 1, 1, NULL);
+ sfree(title);
+}
+
+void about_box(void)
+{
+ GtkWidget *w;
+ char *title;
+
+ if (aboutbox) {
+ gtk_widget_grab_focus(aboutbox);
+ return;
+ }
+
+ aboutbox = gtk_dialog_new();
+ gtk_container_set_border_width(GTK_CONTAINER(aboutbox), 10);
+ title = dupcat("About ", appname, NULL);
+ gtk_window_set_title(GTK_WINDOW(aboutbox), title);
+ sfree(title);
+
+ w = gtk_button_new_with_label("Close");
+ GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
+ gtk_window_set_default(GTK_WINDOW(aboutbox), w);
+ gtk_box_pack_end(GTK_BOX(GTK_DIALOG(aboutbox)->action_area),
+ w, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(w), "clicked",
+ GTK_SIGNAL_FUNC(about_close_clicked), NULL);
+ gtk_widget_show(w);
+
+ w = gtk_button_new_with_label("View Licence");
+ GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
+ gtk_box_pack_end(GTK_BOX(GTK_DIALOG(aboutbox)->action_area),
+ w, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(w), "clicked",
+ GTK_SIGNAL_FUNC(licence_clicked), NULL);
+ gtk_widget_show(w);
+
+ w = gtk_label_new(appname);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(aboutbox)->vbox),
+ w, FALSE, FALSE, 0);
+ gtk_widget_show(w);
+
+ w = gtk_label_new(ver);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(aboutbox)->vbox),
+ w, FALSE, FALSE, 5);
+ gtk_widget_show(w);
+
+ w = gtk_label_new("Copyright 1997-2003 Simon Tatham. All rights reserved");
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(aboutbox)->vbox),
+ w, FALSE, FALSE, 5);
+ gtk_widget_show(w);
+
+ gtk_widget_show(aboutbox);
+}
GtkWidget *window, *area, *sbar;
GtkBox *hbox;
GtkAdjustment *sbar_adjust;
+ GtkWidget *menu, *specialsmenu, *specialsitem1, *specialsitem2;
GdkPixmap *pixmap;
GdkFont *fonts[4]; /* normal, bold, wide, widebold */
struct {
*/
}
-void update_specials_menu(void *frontend)
-{
- /*
- * When I implement a context menu in pterm, I will need to
- * support this function properly.
- */
-}
-
int askappend(void *frontend, Filename filename)
{
/*
shift = event->state & GDK_SHIFT_MASK;
ctrl = event->state & GDK_CONTROL_MASK;
alt = event->state & GDK_MOD1_MASK;
+
+ if (event->button == 3 && ctrl) {
+ gtk_menu_popup(GTK_MENU(inst->menu), NULL, NULL, NULL, NULL,
+ event->button, event->time);
+ return TRUE;
+ }
+
if (event->button == 1)
button = MBT_LEFT;
else if (event->button == 2)
gdk_input_remove(id);
}
+void clear_scrollback_menuitem(GtkMenuItem *item, gpointer data)
+{
+ struct gui_data *inst = (struct gui_data *)data;
+ term_clrsb(inst->term);
+}
+
+void reset_terminal_menuitem(GtkMenuItem *item, gpointer data)
+{
+ struct gui_data *inst = (struct gui_data *)data;
+ term_pwron(inst->term);
+ ldisc_send(inst->ldisc, NULL, 0, 0);
+}
+
+void special_menuitem(GtkMenuItem *item, gpointer data)
+{
+ struct gui_data *inst = (struct gui_data *)data;
+ int code = (int)gtk_object_get_data(GTK_OBJECT(item), "user-data");
+
+ inst->back->special(inst->backhandle, code);
+}
+
+void about_menuitem(GtkMenuItem *item, gpointer data)
+{
+ /* struct gui_data *inst = (struct gui_data *)data; */
+ about_box();
+}
+
+void update_specials_menu(void *frontend)
+{
+ Terminal *term = (Terminal *)frontend;
+ struct gui_data *inst = (struct gui_data *)term->frontend;
+
+ const struct telnet_special *specials;
+
+ specials = inst->back->get_specials(inst->backhandle);
+ 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) {
+ menuitem = gtk_menu_item_new_with_label(specials[i].name);
+ gtk_object_set_data(GTK_OBJECT(menuitem), "user-data",
+ (gpointer)specials[i].code);
+ gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
+ GTK_SIGNAL_FUNC(special_menuitem), inst);
+ } else
+ menuitem = gtk_menu_item_new();
+ gtk_container_add(GTK_CONTAINER(inst->specialsmenu), menuitem);
+ gtk_widget_show(menuitem);
+ }
+ gtk_widget_show(inst->specialsitem1);
+ gtk_widget_show(inst->specialsitem2);
+ } else {
+ gtk_widget_hide(inst->specialsitem1);
+ gtk_widget_hide(inst->specialsitem2);
+ }
+}
+
int pt_main(int argc, char **argv)
{
extern Backend *select_backend(Config *cfg);
set_window_background(inst);
+ /*
+ * Set up the Ctrl+rightclick context menu.
+ */
+ {
+ GtkWidget *menuitem;
+ char *s;
+
+ inst->menu = gtk_menu_new();
+
+#define MKMENUITEM(title, func) do { \
+ menuitem = title ? gtk_menu_item_new_with_label(title) : \
+ gtk_menu_item_new(); \
+ gtk_container_add(GTK_CONTAINER(inst->menu), menuitem); \
+ gtk_widget_show(menuitem); \
+ if (func != NULL) \
+ gtk_signal_connect(GTK_OBJECT(menuitem), "activate", \
+ GTK_SIGNAL_FUNC(func), inst); \
+} while (0)
+ MKMENUITEM("Special Commands", NULL);
+ inst->specialsmenu = gtk_menu_new();
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), inst->specialsmenu);
+ inst->specialsitem1 = menuitem;
+ MKMENUITEM(NULL, NULL);
+ inst->specialsitem2 = menuitem;
+ MKMENUITEM("Clear Scrollback", clear_scrollback_menuitem);
+ MKMENUITEM("Reset Terminal", reset_terminal_menuitem);
+ MKMENUITEM(NULL, NULL);
+ s = dupcat("About ", appname, NULL);
+ MKMENUITEM(s, about_menuitem);
+ sfree(s);
+#undef MKMENUITEM
+ }
+
inst->textcursor = make_mouse_ptr(inst, GDK_XTERM);
inst->rawcursor = make_mouse_ptr(inst, GDK_LEFT_PTR);
inst->blankcursor = make_mouse_ptr(inst, -1);
}
}
inst->back->provide_logctx(inst->backhandle, inst->logctx);
+ update_specials_menu(inst->term);
term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle);
#include "putty.h"
+const char *const appname = "pterm";
+
+/*
+ * Another bunch of temporary stub functions. These ones will want
+ * removing by means of implementing them properly: libcharset
+ * should invent its own sensible format for codepage names and a
+ * means of enumerating them, and printer_enum needs to be dealt
+ * with somehow or other too.
+ */
+
+char *cp_name(int codepage)
+{
+ return "";
+}
+char *cp_enumerate(int index)
+{
+ return NULL;
+}
+int decode_codepage(char *cp_name)
+{
+ return -2;
+}
+
+printer_enum *printer_start_enum(int *nprinters_ptr) {
+ *nprinters_ptr = 0;
+ return NULL;
+}
+char *printer_get_name(printer_enum *pe, int i) { return NULL;
+}
+void printer_finish_enum(printer_enum *pe) { }
+
Backend *select_backend(Config *cfg)
{
return &pty_backend;
return 1; /* no-op in pterm */
}
-void fatal_message_box(void *window, char *msg)
-{
- /* also a no-op in pterm */
-}
-
void cleanup_exit(int code)
{
exit(code);
/* Things pterm.c needs from gtkdlg.c */
void fatal_message_box(void *window, char *msg);
+void about_box(void);
/* Things pterm.c needs from {ptermm,uxputty}.c */
char *make_default_wintitle(char *hostname);
#include "dialog.h"
#include "storage.h"
+static void about_handler(union control *ctrl, void *dlg,
+ void *data, int event)
+{
+ if (event == EVENT_ACTION) {
+ about_box();
+ }
+}
+
void unix_setup_config_box(struct controlbox *b, int midsession)
{
struct controlset *s, *s2;
union control *c;
int i;
-#ifdef FIXME
if (!midsession) {
/*
* Add the About button to the standard panel.
*/
s = ctrl_getset(b, "", "", "");
c = ctrl_pushbutton(s, "About", 'a', HELPCTX(no_help),
- about_handler, P(hwndp));
+ about_handler, P(NULL));
c->generic.column = 0;
}
-#endif
/*
* The Config structure contains two Unix-specific elements
* have uxcfg.c remove the drop-down list completely, since you
* can't sensibly provide an enumerated list of lpr commands!).
*
- * - Ctrl+right-click for a context menu (also in Windows for
- * consistency, I think). This should contain pretty much
- * everything in the Windows PuTTY menu, and a subset of that in
- * pterm:
- *
- * - Telnet special commands (not in pterm :-)
+ * - Remainder of the context menu:
*
* - Event Log (this means we must implement the Event Log; not
* in pterm)
* to get hold of the application name.
*
* - Copy All to Clipboard (for what that's worth)
- *
- * - Clear Scrollback and Reset Terminal
- *
- * - About (and uxcfg.c must also supply the about box)
*/
/*
}
void printer_finish_enum(printer_enum *pe) { }
+const char *const appname = "PuTTY";
+
Backend *select_backend(Config *cfg)
{
int i;