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.
48 struct term_out *next;
49 struct kmscon_output *output;
52 struct kmscon_terminal {
54 struct kmscon_eloop *eloop;
56 struct term_out *outputs;
57 unsigned int max_height;
59 struct kmscon_console *console;
60 struct kmscon_idle *redraw;
61 struct kmscon_vte *vte;
64 static void draw_all(struct kmscon_idle *idle, void *data)
66 struct kmscon_terminal *term = data;
67 struct term_out *iter;
68 struct kmscon_output *output;
71 kmscon_eloop_rm_idle(idle);
72 kmscon_console_draw(term->console);
75 for (; iter; iter = iter->next) {
76 output = iter->output;
77 if (!kmscon_output_is_awake(output))
80 ret = kmscon_output_use(output);
84 glClearColor(0.0, 0.0, 0.0, 1.0);
85 glClear(GL_COLOR_BUFFER_BIT);
87 kmscon_console_map(term->console);
88 kmscon_output_swap(output);
92 static void schedule_redraw(struct kmscon_terminal *term)
96 if (!term || !term->eloop)
99 ret = kmscon_eloop_add_idle(term->eloop, term->redraw, draw_all, term);
100 if (ret && ret != -EALREADY)
101 log_warning("terminal: cannot schedule redraw\n");
104 static const char help_text[] =
105 "terminal subsystem - KMS based console test\n"
106 "This is some default text to test the drawing operations.\n\n";
108 static void print_help(struct kmscon_terminal *term)
113 len = sizeof(help_text) - 1;
114 for (i = 0; i < len; ++i) {
115 ch = kmscon_symbol_make(help_text[i]);
116 kmscon_terminal_input(term, ch);
120 int kmscon_terminal_new(struct kmscon_terminal **out,
121 struct kmscon_font_factory *ff)
123 struct kmscon_terminal *term;
129 log_debug("terminal: new terminal object\n");
131 term = malloc(sizeof(*term));
135 memset(term, 0, sizeof(*term));
138 ret = kmscon_idle_new(&term->redraw);
142 ret = kmscon_console_new(&term->console, ff);
146 ret = kmscon_vte_new(&term->vte);
149 kmscon_vte_bind(term->vte, term->console);
156 kmscon_console_unref(term->console);
158 kmscon_idle_unref(term->redraw);
164 void kmscon_terminal_ref(struct kmscon_terminal *term)
172 void kmscon_terminal_unref(struct kmscon_terminal *term)
174 if (!term || !term->ref)
180 kmscon_terminal_rm_all_outputs(term);
181 kmscon_vte_unref(term->vte);
182 kmscon_console_unref(term->console);
183 kmscon_terminal_disconnect_eloop(term);
185 log_debug("terminal: destroying terminal object\n");
188 int kmscon_terminal_connect_eloop(struct kmscon_terminal *term,
189 struct kmscon_eloop *eloop)
197 kmscon_eloop_ref(eloop);
203 void kmscon_terminal_disconnect_eloop(struct kmscon_terminal *term)
208 kmscon_eloop_unref(term->eloop);
212 int kmscon_terminal_add_output(struct kmscon_terminal *term,
213 struct kmscon_output *output)
215 struct term_out *out;
217 struct kmscon_mode *mode;
219 if (!term || !output)
222 mode = kmscon_output_get_current(output);
224 log_warning("terminal: invalid output added to terminal\n");
228 out = malloc(sizeof(*out));
232 memset(out, 0, sizeof(*out));
233 kmscon_output_ref(output);
234 out->output = output;
235 out->next = term->outputs;
238 height = kmscon_mode_get_height(mode);
239 if (term->max_height < height) {
240 term->max_height = height;
241 kmscon_console_resize(term->console, 0, 0, term->max_height);
244 schedule_redraw(term);
249 void kmscon_terminal_rm_all_outputs(struct kmscon_terminal *term)
251 struct term_out *tmp;
256 while (term->outputs) {
258 term->outputs = tmp->next;
259 kmscon_output_unref(tmp->output);
264 void kmscon_terminal_input(struct kmscon_terminal *term, kmscon_symbol_t ch)
266 kmscon_vte_input(term->vte, ch);
267 schedule_redraw(term);