Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | And that's it! pty.c is now a real pty backend rather than a loopback interface; pterm now runs $SHELL and gives every impression of being not a bad terminal emulator. I'm quite pleased with that. :-) |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
df838b2e568b426978f34d761bc99efc |
| User & Date: | simon 2002-10-10 07:40:05.000 |
Context
|
2002-10-10
| ||
| 09:39 | Update to reflect 0.53 release. check-in: 79f1b92c1c user: jacob tags: trunk | |
| 07:40 | And that's it! pty.c is now a real pty backend rather than a loopback interface; pterm now runs $SHELL and gives every impression of being not a bad terminal emulator. I'm quite pleased with that. :-) check-in: df838b2e56 user: simon tags: trunk | |
| 07:14 | Half-decent keyboard handling for pterm. Not very well done - it would have been better to abstract the general key-handling rules away from the platform-specific keysyms rather than doing clone- and-hack as I've done - but it'll serve for now. Now all I need is a real pty back end and pterm should be a just-about-usable prototype. check-in: 85cfc8acc0 user: simon tags: trunk | |
Changes
Changes to unix/pterm.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* * pterm - a fusion of the PuTTY terminal emulator with a Unix pty * back end, all running as a GTK application. Wish me luck. */ #include <string.h> #include <assert.h> #include <stdlib.h> #include <stdio.h> #include <time.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #define PUTTY_DO_GLOBALS /* actually _define_ globals */ #include "putty.h" #define CAT2(x,y) x ## y | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * pterm - a fusion of the PuTTY terminal emulator with a Unix pty * back end, all running as a GTK application. Wish me luck. */ #include <string.h> #include <assert.h> #include <stdlib.h> #include <stdio.h> #include <time.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #define PUTTY_DO_GLOBALS /* actually _define_ globals */ #include "putty.h" #define CAT2(x,y) x ## y |
| ︙ | ︙ | |||
588 589 590 591 592 593 594 595 596 597 598 599 600 601 |
gint timer_func(gpointer data)
{
/* struct gui_data *inst = (struct gui_data *)data; */
term_update();
return TRUE;
}
void destroy(GtkWidget *widget, gpointer data)
{
gtk_main_quit();
}
gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
| > > > > > > > > > > > > > > > > > > > > > > > > > > | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 |
gint timer_func(gpointer data)
{
/* struct gui_data *inst = (struct gui_data *)data; */
term_update();
return TRUE;
}
void pty_input_func(gpointer data, gint sourcefd, GdkInputCondition condition)
{
/* struct gui_data *inst = (struct gui_data *)data; */
char buf[4096];
int ret;
ret = read(sourcefd, buf, sizeof(buf));
/*
* Clean termination condition is that either ret == 0, or ret
* < 0 and errno == EIO. Not sure why the latter, but it seems
* to happen. Boo.
*/
if (ret == 0 || (ret < 0 && errno == EIO)) {
exit(0);
}
if (ret < 0) {
perror("read pty master");
exit(1);
}
if (ret > 0)
from_backend(0, buf, ret);
term_out();
}
void destroy(GtkWidget *widget, gpointer data)
{
gtk_main_quit();
}
gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
|
| ︙ | ︙ | |||
789 790 791 792 793 794 795 796 797 798 799 800 801 802 |
fputc('\n', stderr);
exit(1);
}
int main(int argc, char **argv)
{
GtkWidget *window;
gtk_init(&argc, &argv);
do_defaults(NULL, &cfg);
init_ucs();
| > | 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 |
fputc('\n', stderr);
exit(1);
}
int main(int argc, char **argv)
{
GtkWidget *window;
extern int pty_master_fd; /* declared in pty.c */
gtk_init(&argc, &argv);
do_defaults(NULL, &cfg);
init_ucs();
|
| ︙ | ︙ | |||
821 822 823 824 825 826 827 828 829 830 831 832 833 834 |
gtk_signal_connect(GTK_OBJECT(window), "focus_out_event",
GTK_SIGNAL_FUNC(focus_event), inst);
gtk_signal_connect(GTK_OBJECT(inst->area), "configure_event",
GTK_SIGNAL_FUNC(configure_area), inst);
gtk_signal_connect(GTK_OBJECT(inst->area), "expose_event",
GTK_SIGNAL_FUNC(expose_area), inst);
gtk_timeout_add(20, timer_func, inst);
gtk_widget_add_events(GTK_WIDGET(inst->area),
GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
gtk_widget_show(inst->area);
gtk_widget_show(window);
inst->textcursor = gdk_cursor_new(GDK_XTERM);
| > | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 |
gtk_signal_connect(GTK_OBJECT(window), "focus_out_event",
GTK_SIGNAL_FUNC(focus_event), inst);
gtk_signal_connect(GTK_OBJECT(inst->area), "configure_event",
GTK_SIGNAL_FUNC(configure_area), inst);
gtk_signal_connect(GTK_OBJECT(inst->area), "expose_event",
GTK_SIGNAL_FUNC(expose_area), inst);
gtk_timeout_add(20, timer_func, inst);
gdk_input_add(pty_master_fd, GDK_INPUT_READ, pty_input_func, inst);
gtk_widget_add_events(GTK_WIDGET(inst->area),
GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
gtk_widget_show(inst->area);
gtk_widget_show(window);
inst->textcursor = gdk_cursor_new(GDK_XTERM);
|
| ︙ | ︙ |
Changes to unix/pty.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <stdio.h>
#include <stdlib.h>
#include "putty.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
static void pty_size(void);
static void c_write(char *buf, int len)
{
from_backend(0, buf, len);
}
/*
* Called to set up the pty.
*
* Returns an error message, or NULL on success.
*
* Also places the canonical host name into `realhost'. It must be
* freed by the caller.
*/
static char *pty_init(char *host, int port, char **realhost, int nodelay)
{
| > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
#define _XOPEN_SOURCE
#include <features.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "putty.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
int pty_master_fd;
static void pty_size(void);
static void c_write(char *buf, int len)
{
from_backend(0, buf, len);
}
/*
* Called to set up the pty.
*
* Returns an error message, or NULL on success.
*
* Also places the canonical host name into `realhost'. It must be
* freed by the caller.
*/
static char *pty_init(char *host, int port, char **realhost, int nodelay)
{
int slavefd;
char name[FILENAME_MAX];
pid_t pid;
pty_master_fd = open("/dev/ptmx", O_RDWR);
if (pty_master_fd < 0) {
perror("/dev/ptmx: open");
exit(1);
}
if (grantpt(pty_master_fd) < 0) {
perror("grantpt");
exit(1);
}
if (unlockpt(pty_master_fd) < 0) {
perror("unlockpt");
exit(1);
}
name[FILENAME_MAX-1] = '\0';
strncpy(name, ptsname(pty_master_fd), FILENAME_MAX-1);
slavefd = open(name, O_RDWR);
if (slavefd < 0) {
perror("slave pty: open");
return 1;
}
/*
* Fork and execute the command.
*/
pid = fork();
if (pid < 0) {
perror("fork");
return 1;
}
if (pid == 0) {
int i;
/*
* We are the child.
*/
close(pty_master_fd);
close(0);
close(1);
close(2);
fcntl(slavefd, F_SETFD, 0); /* don't close on exec */
dup2(slavefd, 0);
dup2(slavefd, 1);
dup2(slavefd, 2);
setsid();
setpgrp();
tcsetpgrp(0, getpgrp());
/* Close everything _else_, for tidiness. */
for (i = 3; i < 1024; i++)
close(i);
execl(getenv("SHELL"), getenv("SHELL"), NULL);
/*
* If we're here, exec has gone badly foom.
*/
perror("exec");
exit(127);
} else {
close(slavefd);
}
return NULL;
}
/*
* Called to send data down the pty.
*/
static int pty_send(char *buf, int len)
{
while (len > 0) {
int ret = write(pty_master_fd, buf, len);
if (ret < 0) {
perror("write pty master");
exit(1);
}
buf += ret;
len -= ret;
}
return 0;
}
/*
* Called to query the current socket sendability status.
*/
static int pty_sendbuffer(void)
|
| ︙ | ︙ |