1 /* rxvt.c - terminal emulator widget top-level functions
2 Copyright (C) 1996-2017 Paul Sheer
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307, USA.
18 */
19
20 #include "rxvt/rxvtlib.h"
21 #include "mad.h"
22 #include "coolwidget.h"
23 #include "font.h"
24
25 struct rxvts {
26 rxvtlib *rxvt;
27 struct rxvts *next;
28 int killed;
29 } *rxvt_list = 0;
30
31 extern void rxvt_fd_write_watch (int fd, fd_set * reading, fd_set * writing, fd_set * error,
32 void *data);
33 extern void rxvt_fd_read_watch (int fd, fd_set * reading, fd_set * writing, fd_set * error,
34 void *data);
35
rxvt_event(XEvent * xevent)36 int rxvt_event (XEvent * xevent)
37 {
38 Window win;
39 struct rxvts *l, *prev = 0;
40 if (!rxvt_list)
41 return 0;
42 win = xevent->xany.window;
43 for (l = rxvt_list->next, prev = rxvt_list; l; l = l->next) {
44 l->killed |= CChildExitted (l->rxvt->cmd_pid, 0);
45 if (l->killed || l->rxvt->killed) {
46 struct rxvts *next;
47 next = l->next;
48 CRemoveWatch (l->rxvt->cmd_fd, rxvt_fd_read_watch, 1);
49 CRemoveWatch (l->rxvt->cmd_fd, rxvt_fd_write_watch, 2);
50 close (l->rxvt->cmd_fd);
51 if (l->killed) {
52 XDestroyWindow (l->rxvt->Xdisplay,
53 l->rxvt->TermWin.parent[0]);
54 XDestroyWindow (l->rxvt->Xdisplay, l->rxvt->TermWin.vt);
55 XDestroyWindow (l->rxvt->Xdisplay, l->rxvt->scrollBar.win);
56 }
57 prev->next = next;
58 rxvtlib_shut (l->rxvt);
59 free (l->rxvt);
60 memset (l, 0, sizeof (*l));
61 free (l);
62 l = prev;
63 } else if (win && (l->rxvt->TermWin.parent[0] == win
64 || l->rxvt->TermWin.parent[1] == win
65 || l->rxvt->TermWin.parent[2] == win
66 || l->rxvt->TermWin.parent[3] == win
67 || l->rxvt->TermWin.parent[4] == win
68 || l->rxvt->scrollBar.win == win
69 || l->rxvt->menuBar.win == win)) {
70 l->rxvt->x_events_pending = 1;
71 memcpy (&l->rxvt->xevent, xevent, sizeof (*xevent));
72 l->rxvt->fds_available++;
73 if (XFilterEvent(xevent, 0)) {
74 xevent->type = 0;
75 xevent->xany.window = 0;
76 return 1;
77 }
78 rxvt_process_x_event (l->rxvt);
79 if (l->rxvt->killed) {
80 CRemoveWatch (l->rxvt->cmd_fd, 0, 3);
81 CRemoveWatch (l->rxvt->cmd_fd, 0, 3);
82 return 1;
83 }
84 rxvtlib_update_screen (l->rxvt);
85 if (win != DefaultRootWindow (l->rxvt->Xdisplay)
86 && xevent->type != ClientMessage
87 && xevent->type != SelectionNotify
88 && xevent->type != SelectionRequest
89 && xevent->type != SelectionClear) {
90 xevent->type = 0;
91 xevent->xany.window = 0;
92 return 1;
93 }
94 return 0;
95 }
96 prev = l;
97 }
98 return 0;
99 }
100
rxvt_have_pid(pid_t pid)101 int rxvt_have_pid (pid_t pid)
102 {
103 struct rxvts *l;
104 if (!rxvt_list)
105 return 0;
106 for (l = rxvt_list->next; l; l = l->next)
107 if (l->rxvt->cmd_pid == pid)
108 return 1;
109 return 0;
110 }
111
112 /* rxvt's need to interoperate */
rxvt_selection_clear(void)113 void rxvt_selection_clear (void)
114 {
115 struct rxvts *l;
116 if (!rxvt_list)
117 return;
118 for (l = rxvt_list->next; l; l = l->next) {
119 rxvtlib *o;
120 o = l->rxvt;
121 if (o->selection.text)
122 FREE (o->selection.text);
123 o->selection.text = NULL;
124 o->selection.len = 0;
125 }
126 return;
127 }
128
129 #if 0
130 int rxvt_alive (pid_t p)
131 {
132 struct rxvts *l;
133 if (!rxvt_list)
134 return 0;
135 for (l = rxvt_list->next; l; l = l->next)
136 if (l->rxvt->cmd_pid == p && !l->killed && !l->rxvt->killed)
137 return 1;
138 return 0;
139 }
140 #endif
141
142 extern void (*user_selection_clear) (void);
143
rxvt_allocate(Window win,int c,char ** a,int do_sleep)144 rxvtlib *rxvt_allocate (Window win, int c, char **a, int do_sleep)
145 {
146 rxvtlib *rxvt;
147 struct rxvts *l;
148 rxvt = (rxvtlib *) malloc (sizeof (rxvtlib));
149 rxvtlib_init (rxvt);
150 user_selection_clear = (void (*)(void)) rxvt_selection_clear;
151 rxvt->parent_window = win;
152 rxvtlib_main (rxvt, c, (const char *const *) a, do_sleep);
153 if (rxvt->killed) {
154 free (rxvt);
155 return 0;
156 }
157 if (!rxvt_list) {
158 rxvt_list = l = malloc (sizeof (struct rxvts));
159 rxvt_list->next = 0;
160 rxvt_list->rxvt = 0;
161 rxvt_list->killed = 0;
162 }
163 for (l = rxvt_list; l->next; l = l->next);
164 l = (l->next = malloc (sizeof (struct rxvts)));
165 l->next = 0;
166 l->killed = 0;
167 l->rxvt = rxvt;
168 return rxvt;
169 }
170
171 extern char *init_font;
172
rxvt_args(char ** argv)173 char **rxvt_args (char **argv)
174 {
175 char **a;
176 char *b[] =
177 { "rxvt", "-fg", "white", "-bg", "black", "-font", "8x13bold", "-sl", "5000", "-si", "+sk", "-e", 0 };
178 int i = 0, j, k;
179 if (argv)
180 for (i = 0; argv[i]; i++);
181 CPushFont ("editor", 0);
182 if (CIsFixedFont () && init_font) {
183 for (k = 0; b[k] && strcmp (b[k], "-font"); k++);
184 if (k != i)
185 b[k + 1] = init_font;
186 }
187 CPopFont ();
188 for (j = 0; b[j]; j++);
189 a = malloc ((i + j + 1) * sizeof (char *));
190 memcpy (a, b, j * sizeof (char *));
191 if (argv)
192 memcpy (a + j, argv, (i + 1) * sizeof (char *));
193 if (!i)
194 a[--j] = 0; /* shell */
195 return a;
196 }
197
198 #if 0
199 void rxvt_resize_window (rxvtlib * rxvt, int w, int h)
200 {
201 XResizeWindow (rxvt->Xdisplay, rxvt->TermWin.parent[0], w, h);
202 rxvtlib_resize_window (rxvt, w, h);
203 }
204 #endif
205
rxvtlib_shutall(void)206 void rxvtlib_shutall (void)
207 {
208 struct rxvts *l;
209 if (!rxvt_list)
210 return;
211 l = rxvt_list->next;
212 free (rxvt_list);
213 rxvt_list = 0;
214 while (l) {
215 struct rxvts *next;
216 next = l->next;
217 CRemoveWatch (l->rxvt->cmd_fd, 0, 3);
218 CRemoveWatch (l->rxvt->cmd_fd, 0, 3);
219 if (!l->killed)
220 close (l->rxvt->cmd_fd);
221 XDestroyWindow (l->rxvt->Xdisplay, l->rxvt->TermWin.parent[0]);
222 XDestroyWindow (l->rxvt->Xdisplay, l->rxvt->TermWin.vt);
223 XDestroyWindow (l->rxvt->Xdisplay, l->rxvt->scrollBar.win);
224 rxvtlib_shut (l->rxvt);
225 free (l->rxvt);
226 memset (l, 0, sizeof (*l));
227 free (l);
228 l = next;
229 }
230 }
231
rxvt_start(Window win,char ** argv,int do_sleep)232 rxvtlib *rxvt_start (Window win, char **argv, int do_sleep)
233 {
234 int a = 0;
235 rxvtlib *rxvt;
236 char **b;
237 b = rxvt_args (argv);
238 while (b[a])
239 a++;
240 rxvt = rxvt_allocate (win, a, b, do_sleep);
241 if (rxvt) {
242 rxvtlib_main_loop (rxvt);
243 rxvtlib_update_screen (rxvt);
244 }
245 free (b);
246 return rxvt;
247 }
248
rxvt_get_tty_name(rxvtlib * rxvt,char * p)249 void rxvt_get_tty_name (rxvtlib * rxvt, char *p)
250 {
251 strcpy (p, rxvt->ttydev);
252 }
253
rxvt_get_pid(rxvtlib * rxvt)254 pid_t rxvt_get_pid (rxvtlib * rxvt)
255 {
256 return rxvt->cmd_pid;
257 }
258
259 #if 0
260 Window rxvt_get_main_window (rxvtlib *rxvt)
261 {
262 return rxvt->TermWin.parent[0];
263 }
264 #endif
265
266