4 * Copyright (c) 2011 David Herrmann <dh.herrmann@googlemail.com>
5 * Copyright (c) 2011 University of Tuebingen
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files
9 * (the "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 * A terminal gets assigned an input stream and several output objects and then
30 * runs a fully functional terminal emulation on it.
47 struct term_out *next;
48 struct kmscon_output *output;
51 struct kmscon_terminal {
53 struct kmscon_eloop *eloop;
55 struct term_out *outputs;
56 unsigned int max_height;
58 struct kmscon_console *console;
59 struct kmscon_idle *redraw;
60 struct kmscon_vte *vte;
63 static void draw_all(struct kmscon_idle *idle, void *data)
65 struct kmscon_terminal *term = data;
66 struct term_out *iter;
67 struct kmscon_output *output;
70 kmscon_eloop_rm_idle(idle);
71 kmscon_console_draw(term->console);
74 for (; iter; iter = iter->next) {
75 output = iter->output;
76 if (!kmscon_output_is_awake(output))
79 ret = kmscon_output_use(output);
83 glClearColor(0.0, 0.0, 0.0, 1.0);
84 glClear(GL_COLOR_BUFFER_BIT);
86 kmscon_console_map(term->console);
87 kmscon_output_swap(output);
91 static void schedule_redraw(struct kmscon_terminal *term)
95 if (!term || !term->eloop)
98 ret = kmscon_eloop_add_idle(term->eloop, term->redraw, draw_all, term);
99 if (ret && ret != -EALREADY)
100 log_warning("terminal: cannot schedule redraw\n");
103 static const char help_text[] =
104 "terminal subsystem - KMS based console test\n"
105 "This is some default text to test the drawing operations.\n\n";
107 static void print_help(struct kmscon_terminal *term)
112 len = sizeof(help_text) - 1;
113 for (i = 0; i < len; ++i) {
114 ch = kmscon_symbol_make(help_text[i]);
115 kmscon_terminal_input(term, ch);
119 int kmscon_terminal_new(struct kmscon_terminal **out,
120 struct kmscon_symbol_table *st)
122 struct kmscon_terminal *term;
128 log_debug("terminal: new terminal object\n");
130 term = malloc(sizeof(*term));
134 memset(term, 0, sizeof(*term));
137 ret = kmscon_idle_new(&term->redraw);
141 ret = kmscon_console_new(&term->console, st);
145 ret = kmscon_vte_new(&term->vte);
148 kmscon_vte_bind(term->vte, term->console);
155 kmscon_console_unref(term->console);
157 kmscon_idle_unref(term->redraw);
163 void kmscon_terminal_ref(struct kmscon_terminal *term)
171 void kmscon_terminal_unref(struct kmscon_terminal *term)
173 if (!term || !term->ref)
179 kmscon_terminal_rm_all_outputs(term);
180 kmscon_vte_unref(term->vte);
181 kmscon_console_unref(term->console);
182 kmscon_terminal_disconnect_eloop(term);
184 log_debug("terminal: destroying terminal object\n");
187 int kmscon_terminal_connect_eloop(struct kmscon_terminal *term,
188 struct kmscon_eloop *eloop)
196 kmscon_eloop_ref(eloop);
202 void kmscon_terminal_disconnect_eloop(struct kmscon_terminal *term)
207 kmscon_eloop_unref(term->eloop);
211 int kmscon_terminal_add_output(struct kmscon_terminal *term,
212 struct kmscon_output *output)
214 struct term_out *out;
216 struct kmscon_mode *mode;
218 if (!term || !output)
221 mode = kmscon_output_get_current(output);
223 log_warning("terminal: invalid output added to terminal\n");
227 out = malloc(sizeof(*out));
231 memset(out, 0, sizeof(*out));
232 kmscon_output_ref(output);
233 out->output = output;
234 out->next = term->outputs;
237 height = kmscon_mode_get_height(mode);
238 if (term->max_height < height) {
239 term->max_height = height;
240 kmscon_console_resize(term->console, 0, 0, term->max_height);
243 schedule_redraw(term);
248 void kmscon_terminal_rm_all_outputs(struct kmscon_terminal *term)
250 struct term_out *tmp;
255 while (term->outputs) {
257 term->outputs = tmp->next;
258 kmscon_output_unref(tmp->output);
263 void kmscon_terminal_input(struct kmscon_terminal *term, kmscon_symbol_t ch)
265 kmscon_vte_input(term->vte, ch);
266 schedule_redraw(term);