1c72fcc34Sopenharmony_ci/* 2c72fcc34Sopenharmony_ci * widget.c - handles widget objects and the widget stack 3c72fcc34Sopenharmony_ci * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 4c72fcc34Sopenharmony_ci * 5c72fcc34Sopenharmony_ci * This program is free software: you can redistribute it and/or modify 6c72fcc34Sopenharmony_ci * it under the terms of the GNU General Public License as published by 7c72fcc34Sopenharmony_ci * the Free Software Foundation, either version 2 of the License, or 8c72fcc34Sopenharmony_ci * (at your option) any later version. 9c72fcc34Sopenharmony_ci * 10c72fcc34Sopenharmony_ci * This program is distributed in the hope that it will be useful, 11c72fcc34Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 12c72fcc34Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13c72fcc34Sopenharmony_ci * GNU General Public License for more details. 14c72fcc34Sopenharmony_ci * 15c72fcc34Sopenharmony_ci * You should have received a copy of the GNU General Public License 16c72fcc34Sopenharmony_ci * along with this program. If not, see <http://www.gnu.org/licenses/>. 17c72fcc34Sopenharmony_ci */ 18c72fcc34Sopenharmony_ci 19c72fcc34Sopenharmony_ci#include "aconfig.h" 20c72fcc34Sopenharmony_ci#include <stdlib.h> 21c72fcc34Sopenharmony_ci#include <term.h> 22c72fcc34Sopenharmony_ci#include <unistd.h> 23c72fcc34Sopenharmony_ci#include <sys/ioctl.h> 24c72fcc34Sopenharmony_ci#include "die.h" 25c72fcc34Sopenharmony_ci#include "widget.h" 26c72fcc34Sopenharmony_ci 27c72fcc34Sopenharmony_ciint screen_lines; 28c72fcc34Sopenharmony_ciint screen_cols; 29c72fcc34Sopenharmony_ci 30c72fcc34Sopenharmony_cistatic int cursor_visibility = -1; 31c72fcc34Sopenharmony_ci 32c72fcc34Sopenharmony_cistatic void update_cursor_visibility(void) 33c72fcc34Sopenharmony_ci{ 34c72fcc34Sopenharmony_ci const struct widget *active_widget; 35c72fcc34Sopenharmony_ci 36c72fcc34Sopenharmony_ci active_widget = get_active_widget(); 37c72fcc34Sopenharmony_ci if (active_widget && 38c72fcc34Sopenharmony_ci active_widget->cursor_visibility != cursor_visibility) { 39c72fcc34Sopenharmony_ci cursor_visibility = active_widget->cursor_visibility; 40c72fcc34Sopenharmony_ci curs_set(cursor_visibility); 41c72fcc34Sopenharmony_ci } 42c72fcc34Sopenharmony_ci} 43c72fcc34Sopenharmony_ci 44c72fcc34Sopenharmony_civoid widget_init(struct widget *widget, int lines_, int cols, int y, int x, 45c72fcc34Sopenharmony_ci chtype bkgd, unsigned int flags) 46c72fcc34Sopenharmony_ci{ 47c72fcc34Sopenharmony_ci WINDOW *old_window; 48c72fcc34Sopenharmony_ci 49c72fcc34Sopenharmony_ci if (y == SCREEN_CENTER) 50c72fcc34Sopenharmony_ci y = (screen_lines - lines_) / 2; 51c72fcc34Sopenharmony_ci if (x == SCREEN_CENTER) 52c72fcc34Sopenharmony_ci x = (screen_cols - cols) / 2; 53c72fcc34Sopenharmony_ci 54c72fcc34Sopenharmony_ci old_window = widget->window; 55c72fcc34Sopenharmony_ci widget->window = newwin(lines_, cols, y, x); 56c72fcc34Sopenharmony_ci if (!widget->window) 57c72fcc34Sopenharmony_ci fatal_error("cannot create window"); 58c72fcc34Sopenharmony_ci keypad(widget->window, TRUE); 59c72fcc34Sopenharmony_ci nodelay(widget->window, TRUE); 60c72fcc34Sopenharmony_ci leaveok(widget->window, !(flags & WIDGET_CURSOR_VISIBLE)); 61c72fcc34Sopenharmony_ci wbkgdset(widget->window, bkgd); 62c72fcc34Sopenharmony_ci werase(widget->window); 63c72fcc34Sopenharmony_ci 64c72fcc34Sopenharmony_ci if (flags & WIDGET_BORDER) 65c72fcc34Sopenharmony_ci box(widget->window, 0, 0); 66c72fcc34Sopenharmony_ci if (flags & WIDGET_SUBWINDOW) { 67c72fcc34Sopenharmony_ci if (widget->subwindow) 68c72fcc34Sopenharmony_ci delwin(widget->subwindow); 69c72fcc34Sopenharmony_ci widget->subwindow = derwin(widget->window, 70c72fcc34Sopenharmony_ci lines_ - 2, cols - 2, 1, 1); 71c72fcc34Sopenharmony_ci if (!widget->subwindow) 72c72fcc34Sopenharmony_ci fatal_error("cannot create subwindow"); 73c72fcc34Sopenharmony_ci wbkgdset(widget->subwindow, bkgd); 74c72fcc34Sopenharmony_ci } 75c72fcc34Sopenharmony_ci widget->cursor_visibility = !!(flags & WIDGET_CURSOR_VISIBLE); 76c72fcc34Sopenharmony_ci 77c72fcc34Sopenharmony_ci if (widget->panel) { 78c72fcc34Sopenharmony_ci replace_panel(widget->panel, widget->window); 79c72fcc34Sopenharmony_ci } else { 80c72fcc34Sopenharmony_ci widget->panel = new_panel(widget->window); 81c72fcc34Sopenharmony_ci if (!widget->panel) 82c72fcc34Sopenharmony_ci fatal_error("cannot create panel"); 83c72fcc34Sopenharmony_ci set_panel_userptr(widget->panel, widget); 84c72fcc34Sopenharmony_ci } 85c72fcc34Sopenharmony_ci 86c72fcc34Sopenharmony_ci if (old_window) 87c72fcc34Sopenharmony_ci delwin(old_window); 88c72fcc34Sopenharmony_ci 89c72fcc34Sopenharmony_ci update_cursor_visibility(); 90c72fcc34Sopenharmony_ci} 91c72fcc34Sopenharmony_ci 92c72fcc34Sopenharmony_civoid widget_free(struct widget *widget) 93c72fcc34Sopenharmony_ci{ 94c72fcc34Sopenharmony_ci if (widget->panel) { 95c72fcc34Sopenharmony_ci del_panel(widget->panel); 96c72fcc34Sopenharmony_ci widget->panel = NULL; 97c72fcc34Sopenharmony_ci } 98c72fcc34Sopenharmony_ci if (widget->subwindow) { 99c72fcc34Sopenharmony_ci delwin(widget->subwindow); 100c72fcc34Sopenharmony_ci widget->subwindow = NULL; 101c72fcc34Sopenharmony_ci } 102c72fcc34Sopenharmony_ci if (widget->window) { 103c72fcc34Sopenharmony_ci delwin(widget->window); 104c72fcc34Sopenharmony_ci widget->window = NULL; 105c72fcc34Sopenharmony_ci } 106c72fcc34Sopenharmony_ci 107c72fcc34Sopenharmony_ci update_cursor_visibility(); 108c72fcc34Sopenharmony_ci} 109c72fcc34Sopenharmony_ci 110c72fcc34Sopenharmony_ciconst struct widget *get_active_widget(void) 111c72fcc34Sopenharmony_ci{ 112c72fcc34Sopenharmony_ci PANEL *active_panel; 113c72fcc34Sopenharmony_ci 114c72fcc34Sopenharmony_ci active_panel = panel_below(NULL); 115c72fcc34Sopenharmony_ci if (active_panel) 116c72fcc34Sopenharmony_ci return panel_userptr(active_panel); 117c72fcc34Sopenharmony_ci else 118c72fcc34Sopenharmony_ci return NULL; 119c72fcc34Sopenharmony_ci} 120c72fcc34Sopenharmony_ci 121c72fcc34Sopenharmony_civoid window_size_changed(void) 122c72fcc34Sopenharmony_ci{ 123c72fcc34Sopenharmony_ci PANEL *panel, *below; 124c72fcc34Sopenharmony_ci const struct widget *widget; 125c72fcc34Sopenharmony_ci struct winsize size; 126c72fcc34Sopenharmony_ci 127c72fcc34Sopenharmony_ci if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &size) == 0) 128c72fcc34Sopenharmony_ci resize_term(size.ws_row, size.ws_col); 129c72fcc34Sopenharmony_ci 130c72fcc34Sopenharmony_ci getmaxyx(stdscr, screen_lines, screen_cols); 131c72fcc34Sopenharmony_ci if (tigetflag("xenl") != 1 && tigetflag("am") != 1) 132c72fcc34Sopenharmony_ci --screen_lines; 133c72fcc34Sopenharmony_ci 134c72fcc34Sopenharmony_ci for (panel = panel_below(NULL); panel; panel = below) { 135c72fcc34Sopenharmony_ci below = panel_below(panel); 136c72fcc34Sopenharmony_ci widget = panel_userptr(panel); 137c72fcc34Sopenharmony_ci widget->window_size_changed(); 138c72fcc34Sopenharmony_ci } 139c72fcc34Sopenharmony_ci} 140