f7f27309 |
1 | /* |
2 | * pterm - a fusion of the PuTTY terminal emulator with a Unix pty |
3 | * back end, all running as a GTK application. Wish me luck. |
4 | */ |
5 | |
6 | #include <string.h> |
7 | #include <stdlib.h> |
8 | #include <time.h> |
9 | #include <gtk/gtk.h> |
10 | |
11 | #define CAT2(x,y) x ## y |
12 | #define CAT(x,y) CAT2(x,y) |
13 | #define ASSERT(x) enum {CAT(assertion_,__LINE__) = 1 / (x)} |
14 | |
15 | #define lenof(x) (sizeof((x))/sizeof(*(x))) |
16 | |
17 | struct gui_data { |
18 | GtkWidget *area; |
19 | GdkFont *fonts[2]; /* normal and bold (for now!) */ |
20 | GdkGC *black_gc, *white_gc; |
21 | }; |
22 | |
23 | gint delete_window(GtkWidget *widget, GdkEvent *event, gpointer data) |
24 | { |
25 | /* |
26 | * FIXME: warn on close? |
27 | */ |
28 | return FALSE; |
29 | } |
30 | |
31 | gint configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data) |
32 | { |
33 | struct gui_data *inst = (struct gui_data *)data; |
34 | |
35 | inst->fonts[0] = gdk_font_load("9x15t"); /* XXCONFIG */ |
36 | inst->fonts[1] = NULL; /* XXCONFIG */ |
37 | inst->black_gc = widget->style->black_gc; |
38 | inst->white_gc = widget->style->white_gc; |
39 | |
40 | #if 0 /* FIXME: get cmap from settings */ |
41 | /* |
42 | * Set up the colour map. |
43 | */ |
44 | inst->colmap = gdk_colormap_get_system(); |
45 | { |
46 | char *colours[] = { |
47 | "#cc0000", "#880000", "#ff0000", |
48 | "#cc6600", "#884400", "#ff7f00", |
49 | "#cc9900", "#886600", "#ffbf00", |
50 | "#cccc00", "#888800", "#ffff00", |
51 | "#00cc00", "#008800", "#00ff00", |
52 | "#008400", "#005800", "#00b000", |
53 | "#008484", "#005858", "#00b0b0", |
54 | "#00cccc", "#008888", "#00ffff", |
55 | "#0066cc", "#004488", "#007fff", |
56 | "#9900cc", "#660088", "#bf00ff", |
57 | "#cc00cc", "#880088", "#ff00ff", |
58 | "#cc9999", "#886666", "#ffbfbf", |
59 | "#cccc99", "#888866", "#ffffbf", |
60 | "#99cc99", "#668866", "#bfffbf", |
61 | "#9999cc", "#666688", "#bfbfff", |
62 | "#757575", "#4e4e4e", "#9c9c9c", |
63 | "#999999", "#666666", "#bfbfbf", |
64 | "#cccccc", "#888888", "#ffffff", |
65 | }; |
66 | ASSERT(sizeof(colours)/sizeof(*colours)==3*NCOLOURS); |
67 | gboolean success[3*NCOLOURS]; |
68 | int i; |
69 | |
70 | for (i = 0; i < 3*NCOLOURS; i++) { |
71 | if (!gdk_color_parse(colours[i], &inst->cols[i])) |
72 | g_error("4tris: couldn't parse colour \"%s\"\n", colours[i]); |
73 | } |
74 | |
75 | gdk_colormap_alloc_colors(inst->colmap, inst->cols, 3*NCOLOURS, |
76 | FALSE, FALSE, success); |
77 | for (i = 0; i < 3*NCOLOURS; i++) { |
78 | if (!success[i]) |
79 | g_error("4tris: couldn't allocate colour \"%s\"\n", colours[i]); |
80 | } |
81 | } |
82 | #endif |
83 | |
84 | return TRUE; |
85 | } |
86 | |
87 | gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data) |
88 | { |
89 | struct gui_data *inst = (struct gui_data *)data; |
90 | |
91 | /* |
92 | * FIXME: pass the exposed rect to terminal.c which will call |
93 | * us back to do the actual painting. |
94 | */ |
95 | return FALSE; |
96 | } |
97 | |
98 | #define KEY_PRESSED(k) \ |
99 | (inst->keystate[(k) / 32] & (1 << ((k) % 32))) |
100 | |
101 | gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data) |
102 | { |
103 | struct gui_data *inst = (struct gui_data *)data; |
104 | |
105 | /* |
106 | * FIXME: all sorts of fun keyboard handling required here. |
107 | */ |
108 | } |
109 | |
110 | gint timer_func(gpointer data) |
111 | { |
112 | struct gui_data *inst = (struct gui_data *)data; |
113 | |
114 | /* |
115 | * FIXME: we're bound to need this sooner or later! |
116 | */ |
117 | return TRUE; |
118 | } |
119 | |
120 | void destroy(GtkWidget *widget, gpointer data) |
121 | { |
122 | gtk_main_quit(); |
123 | } |
124 | |
125 | gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data) |
126 | { |
127 | /* |
128 | * FIXME: need to faff with the cursor shape. |
129 | */ |
130 | } |
131 | |
132 | int main(int argc, char **argv) |
133 | { |
134 | GtkWidget *window; |
135 | struct gui_data the_inst; |
136 | struct gui_data *inst = &the_inst; /* so we always write `inst->' */ |
137 | |
138 | gtk_init(&argc, &argv); |
139 | |
140 | window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
141 | inst->area = gtk_drawing_area_new(); |
142 | gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area), |
143 | 9*80, 15*24);/* FIXME: proper resizing stuff */ |
144 | |
145 | gtk_container_add(GTK_CONTAINER(window), inst->area); |
146 | |
147 | gtk_signal_connect(GTK_OBJECT(window), "destroy", |
148 | GTK_SIGNAL_FUNC(destroy), inst); |
149 | gtk_signal_connect(GTK_OBJECT(window), "delete_event", |
150 | GTK_SIGNAL_FUNC(delete_window), inst); |
151 | gtk_signal_connect(GTK_OBJECT(window), "key_press_event", |
152 | GTK_SIGNAL_FUNC(key_event), inst); |
153 | gtk_signal_connect(GTK_OBJECT(window), "key_release_event", |
154 | GTK_SIGNAL_FUNC(key_event), inst); |
155 | gtk_signal_connect(GTK_OBJECT(window), "focus_in_event", |
156 | GTK_SIGNAL_FUNC(focus_event), inst); |
157 | gtk_signal_connect(GTK_OBJECT(window), "focus_out_event", |
158 | GTK_SIGNAL_FUNC(focus_event), inst); |
159 | gtk_signal_connect(GTK_OBJECT(inst->area), "configure_event", |
160 | GTK_SIGNAL_FUNC(configure_area), inst); |
161 | gtk_signal_connect(GTK_OBJECT(inst->area), "expose_event", |
162 | GTK_SIGNAL_FUNC(expose_area), inst); |
163 | gtk_timeout_add(20, timer_func, inst); |
164 | gtk_widget_add_events(GTK_WIDGET(inst->area), |
165 | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); |
166 | |
167 | gtk_widget_show(inst->area); |
168 | gtk_widget_show(window); |
169 | |
170 | gtk_main(); |
171 | |
172 | return 0; |
173 | } |