176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This program is free software; you can redistribute it and/or 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * modify it under the terms of the GNU General Public License as 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * published by the Free Software Foundation; either version 2 of the 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * License, or any later version. 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This program is distributed in the hope that it will be useful, but 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * WITHOUT ANY WARRANTY; without even the implied warranty of 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * General Public License for more details. 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * You should have received a copy of the GNU General Public License 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * along with this program; if not, write to the Free Software 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER ); 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <assert.h> 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/editbox.h> 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** @file 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Editable text box widget 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EDITBOX_MIN_CHARS 3 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Initialise text box widget 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v box Editable text box widget 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v buf Text buffer 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v len Size of text buffer 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v win Containing window 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v row Row 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v col Starting column 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v width Width 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v flags Flags 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid init_editbox ( struct edit_box *box, char *buf, size_t len, 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman WINDOW *win, unsigned int row, unsigned int col, 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int width, unsigned int flags ) { 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset ( box, 0, sizeof ( *box ) ); 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman box->string.buf = buf; 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman box->string.len = len; 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman box->string.cursor = strlen ( buf ); 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman box->win = ( win ? win : stdscr ); 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman box->row = row; 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman box->col = col; 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman box->width = width; 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman box->flags = flags; 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Draw text box widget 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v box Editable text box widget 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid draw_editbox ( struct edit_box *box ) { 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t width = box->width; 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char buf[ width + 1 ]; 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman signed int cursor_offset, underflow, overflow, first; 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t len; 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Adjust starting offset so that cursor remains within box */ 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cursor_offset = ( box->string.cursor - box->first ); 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman underflow = ( EDITBOX_MIN_CHARS - cursor_offset ); 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman overflow = ( cursor_offset - ( width - 1 ) ); 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman first = box->first; 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( underflow > 0 ) { 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman first -= underflow; 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( first < 0 ) 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman first = 0; 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if ( overflow > 0 ) { 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman first += overflow; 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman box->first = first; 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cursor_offset = ( box->string.cursor - first ); 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Construct underscore-padded string portion */ 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset ( buf, '_', width ); 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman buf[width] = '\0'; 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len = ( strlen ( box->string.buf ) - first ); 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( len > width ) 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman len = width; 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( box->flags & EDITBOX_STARS ) { 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset ( buf, '*', len ); 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy ( buf, ( box->string.buf + first ), len ); 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Print box content and move cursor */ 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ! box->win ) 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman box->win = stdscr; 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mvwprintw ( box->win, box->row, box->col, "%s", buf ); 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman wmove ( box->win, box->row, ( box->col + cursor_offset ) ); 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 104