Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

terminal.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      terminal.cc
00004  *
00005  *      Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include <stdlib.h>
00022 #include <string.h>
00023 // #include <sys/select.h>
00024 
00025 #include "htctrl.h"
00026 #include "htidle.h"
00027 #include "htiobox.h"
00028 #include "htsys.h"
00029 #include "terminal.h"
00030 #include <unistd.h>
00031 
00032 /*
00033  *      CLASS Terminal
00034  */
00035 
00036 void Terminal::init(ht_streamfile *_in, ht_streamfile *_out, ht_streamfile *_err, int _sys_ipc_handle)
00037 {
00038         ht_mem_file *m = new ht_mem_file();
00039         m->init();
00040         ht_ltextfile::init(m, true, NULL);
00041         in = _in;
00042         out = _out;
00043         err = _err;
00044         sys_ipc_handle = _sys_ipc_handle;
00045 }
00046 
00047 void Terminal::done()
00048 {
00049         in->done();
00050         delete in;
00051         out->done();
00052         delete out;
00053         err->done();
00054         delete err;
00055         sys_ipc_terminate(sys_ipc_handle);
00056         ht_ltextfile::done();
00057 }
00058 
00059 bool Terminal::append(ht_streamfile *file)
00060 {
00061 #define STREAM_COPYBUF_SIZE     (128)
00062         const int bufsize=STREAM_COPYBUF_SIZE;
00063         byte *buf=(byte*)malloc(bufsize);
00064         int r, w = 0;
00065         do {
00066                 r = file->read(buf, bufsize);
00067                 if (r<0) break;
00068                 w += r;
00069                 ht_ltextfile::write(buf, r);
00070         } while (r == bufsize);
00071         free(buf);
00072         return w != 0;
00073 }
00074 
00075 bool Terminal::connected()
00076 {
00077         return sys_ipc_is_valid(sys_ipc_handle);
00078 }
00079 
00080 UINT Terminal::write(const void *buf, UINT size)
00081 {
00082         if (connected()) {
00083                 UINT r = ht_ltextfile::write(buf, size);
00084                 in->write(buf, size);
00085                 return r;
00086         }
00087         return 0;               
00088 }
00089 
00090 bool Terminal::update()
00091 {
00092 #if 0
00093         fd_set rfds, wfds;
00094         FD_ZERO(&rfds);
00095         FD_ZERO(&wfds);
00096         FD_SET(out, &wfds);
00097         FD_SET(err, &wfds);
00098         FD_SET(in, &rfds);
00099         // FIXME: FreeBSD problems here
00100         struct timeval timeout;
00101         
00102         timeout.tv_sec = 0;
00103         timeout.tv_usec = 0;
00104         
00105 /*      int n =*/ select(FD_SETSIZE, &rfds, &wfds, NULL, &timeout);
00106 #endif
00107         bool worked = false;
00108 //      if (FD_ISSET(err, &wfds)/* && (!feof(err))*/) {
00109                 seek(get_size());
00110                 worked |= append(err);
00111 //      }
00112 //      if (FD_ISSET(out, &wfds)/* && (!feof(out))*/) {
00113                 seek(get_size());
00114                 worked |= append(out);
00115 //      }
00116         return worked;
00117 }
00118 
00119 /*
00120  *      CLASS TerminalViewer
00121  */
00122 
00123 void TerminalViewer::init(bounds *b, Terminal *t, bool ot)
00124 {
00125         ht_text_viewer::init(b, ot, t, NULL);
00126         term = t;
00127         register_idle_object(this);
00128 }
00129 
00130 void TerminalViewer::done()
00131 {
00132         unregister_idle_object(this);
00133         ht_text_viewer::done();
00134 }
00135 
00136 void TerminalViewer::do_update()
00137 {
00138         UINT l = term->linecount();
00139         if (l) {
00140                 goto_line(l-1);
00141                 cursor_end();
00142         }
00143         dirtyview();
00144         app->sendmsg(msg_draw, 0);
00145 }
00146 
00147 void TerminalViewer::handlemsg(htmsg *msg)
00148 {
00149         switch (msg->msg) {
00150                 case msg_keypressed:
00151                         switch (msg->data1.integer) {
00152                                 case K_F8: {
00153                                         char buf[128];
00154                                         buf[0] = 0;
00155                                         if (inputbox("input", "input", buf, sizeof buf) == button_ok) {
00156                                                 term->seek(term->get_size());
00157                                                 term->write(buf, strlen(buf));
00158                                                 do_update();
00159                                         }
00160                                         clearmsg(msg);
00161                                         return;
00162                                 }
00163                                 case K_Return: {
00164                                         term->seek(term->get_size());
00165                                         term->write("\n", 1);
00166                                         do_update();
00167                                         clearmsg(msg);
00168                                         return;
00169                                 }
00170 // FIXME: unsupported...                                
00171 /*                              case K_BackSpace: {
00172                                         term->seek(term->get_size());
00173                                         term->write("a\t", 2);
00174                                         term->write("b\v", 2);
00175                                         do_update();
00176                                         clearmsg(msg);
00177                                         return;
00178                                 }*/
00179                                 default: {
00180                                         int ch = msg->data1.integer;
00181                                         if ((ch >= 32) && (ch<=0x7f)) {
00182                                                 char buf[2];
00183                                                 buf[0] = ch;
00184                                                 buf[1] = 0;
00185                                                 term->seek(term->get_size());
00186                                                 term->write(buf, 1);
00187                                                 do_update();
00188                                                 clearmsg(msg);
00189                                                 return;
00190                                         }                                               
00191                                         break;
00192                                 }
00193                         }
00194                         break;
00195         }
00196         return ht_text_viewer::handlemsg(msg);
00197 }
00198 
00199 bool TerminalViewer::idle()
00200 {
00201         if (term->update()) {
00202                 do_update();
00203                 return true;
00204         }
00205         return false;
00206 }
00207 
00208 void TerminalViewer::get_pindicator_str(char *buf)
00209 {
00210         sprintf(buf, term->connected() ? " connected " : " disconnected ");
00211 }
00212 

Generated on Fri May 7 21:15:44 2004 by doxygen 1.3.5