aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin/termpty.h
blob: 26c55e2b746809b43ef6a4213ac84fd719f13404 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#ifndef _TERMPTY_H__
#define _TERMPTY_H__ 1

#include "config.h"

typedef struct _Termpty       Termpty;
typedef struct _Termcell      Termcell;
typedef struct _Termatt       Termatt;
typedef struct _Termsave      Termsave;
typedef struct _Termsavecomp  Termsavecomp;
typedef struct _Termblock     Termblock;
typedef struct _Termexp       Termexp;

#define COL_DEF        0
#define COL_BLACK      1
#define COL_RED        2
#define COL_GREEN      3
#define COL_YELLOW     4
#define COL_BLUE       5
#define COL_MAGENTA    6
#define COL_CYAN       7
#define COL_WHITE      8
#define COL_INVIS      9

#define COL_INVERSE   10
#define COL_INVERSEBG 11

#define MOUSE_OFF              0
#define MOUSE_X10              1 // Press only
#define MOUSE_NORMAL           2 // Press+release only
#define MOUSE_NORMAL_BTN_MOVE  3 // Press+release+motion while pressed
#define MOUSE_NORMAL_ALL_MOVE  4 // Press+release+all motion

#define MOUSE_EXT_NONE         0
#define MOUSE_EXT_UTF8         1
#define MOUSE_EXT_SGR          2
#define MOUSE_EXT_URXVT        3

// Only for testing purpose
//#define SUPPORT_80_132_COLUMNS 1

#define MOVIE_STATE_PLAY   0
#define MOVIE_STATE_PAUSE  1
#define MOVIE_STATE_STOP   2

struct _Termatt
{
   unsigned char fg, bg;
   unsigned short bold : 1;
   unsigned short faint : 1;
   unsigned short italic : 1;
   unsigned short dblwidth : 1;
   unsigned short underline : 1;
   unsigned short blink : 1; // don't intend to support this currently
   unsigned short blink2 : 1; // don't intend to support this currently
   unsigned short inverse : 1;
   unsigned short invisible : 1;
   unsigned short strike : 1;
   unsigned short fg256 : 1;
   unsigned short bg256 : 1;
   unsigned short fgintense : 1;
   unsigned short bgintense : 1;
   // below used for working out text from selections
   unsigned short autowrapped : 1;
   unsigned short newline : 1;
   unsigned short fraktur : 1;
#if defined(SUPPORT_80_132_COLUMNS)
   unsigned short is_80_132_mode_allowed : 1;
   unsigned short bit_padding : 14;
#else
   unsigned short bit_padding : 15;
#endif
};

struct _Termpty
{
   Evas_Object *obj;
   Ecore_Event_Handler *hand_exe_exit;
   Ecore_Fd_Handler *hand_fd;
   struct {
      struct {
         void (*func) (void *data);
         void *data;
      } change, set_title, set_icon, cancel_sel, exited, bell, command;
   } cb;
   struct {
      const char *title, *icon, *user_title;
   } prop;
   const char *cur_cmd;
   Termcell *screen, *screen2;
   unsigned int *tabs;
   int circular_offset;
   int circular_offset2;
   Eina_Unicode *buf;
   size_t buflen;
   unsigned char oldbuf[4];
   Termsave *back;
   size_t backsize, backpos;
   /* this beacon in the backlog tells about the top line in screen
    * coordinates that maps to a line in the backlog */
   struct {
        int screen_y;
        int backlog_y;
   } backlog_beacon;
   int w, h;
   int fd, slavefd;
#ifdef ENABLE_FUZZING
   int fd_dev_null;
#endif
   struct {
      int curid;
      Eina_Hash *blocks;
      Eina_Hash *chid_map;
      Eina_List *active;
      Eina_List *expecting;
      unsigned char on : 1;
   } block;
   struct {
      /* start is always the start of the selection
       * so end.y can be < start.y */
      struct {
         int x, y;
      } start, end, orig;
      time_t last_click;
      unsigned char is_active : 1;
      unsigned char is_box    : 1;
      unsigned char makesel   : 1;
      unsigned char by_word   : 1;
      unsigned char by_line   : 1;
      unsigned char is_top_to_bottom : 1;
   } selection;
   struct {
        Termatt       att;
        unsigned char charset;
        unsigned char charsetch;
        unsigned char chset[4];
        int           scroll_y1, scroll_y2;
        int           had_cr_x, had_cr_y;
        int           margin_top; // soon, more to come...
        unsigned int  multibyte : 1;
        unsigned int  alt_kp : 1;
        unsigned int  insert : 1;
        unsigned int  appcursor : 1;
        unsigned int  wrap : 1;
        unsigned int  wrapnext : 1;
        unsigned int  crlf : 1;
        unsigned int  had_cr : 1;
        unsigned int  send_bs : 1;
        unsigned int  kbd_lock : 1;
        unsigned int  reverse : 1;
        unsigned int  no_autorepeat : 1;
        unsigned int  cjk_ambiguous_wide : 1;
        unsigned int  hide_cursor : 1;
        unsigned int  combining_strike : 1;
   } termstate;
   struct {
        int           cx, cy;
   } cursor_state, cursor_save[2];
   int exit_code;
   pid_t pid;
   unsigned int altbuf     : 1;
   unsigned int mouse_mode : 3;
   unsigned int mouse_ext  : 2;
   unsigned int bracketed_paste : 1;
};

struct _Termcell
{
   Eina_Unicode   codepoint;
   Termatt        att;
   unsigned char padding[2];
};

struct _Termsave
{
   unsigned int   gen  : 8;
   unsigned int   comp : 1;
   unsigned int   z    : 1;
   unsigned int   w    : 22;
   /* TODO: union ? */
   Termcell       *cells;
};

/* TODO: RESIZE rewrite Termsavecomp */
struct _Termsavecomp
{
   unsigned int   gen  : 8;
   unsigned int   comp : 1;
   unsigned int   z    : 1;
   unsigned int   w    : 22; // compressed size in bytes
   unsigned int   wout; // output width in Termcells
};

struct _Termblock
{
   Termpty     *pty;
   const char  *path, *link, *chid;
   Evas_Object *obj;
   Eina_List   *cmds;
   int          id;
   int          type;
   int          refs;
   short        w, h;
   short        x, y;
   unsigned char scale_stretch : 1;
   unsigned char scale_center : 1;
   unsigned char scale_fill : 1;
   unsigned char thumb : 1;
   unsigned char edje : 1;

   unsigned char active : 1;
   unsigned char was_active : 1;
   unsigned char was_active_before : 1;

   unsigned char mov_state : 2;  // movie state marker
};

struct _Termexp
{
   int ch, left, id;
   int x, y, w, h;
};

void       termpty_init(void);
void       termpty_shutdown(void);

Termpty   *termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd,
                      int w, int h, int backscroll, Eina_Bool xterm_256color,
                      Eina_Bool erase_is_del, const char *emotion_mod);
void       termpty_free(Termpty *ty);

void       termpty_backlog_lock(void);
void       termpty_backlog_unlock(void);

Termcell  *termpty_cellrow_get(Termpty *ty, int y, ssize_t *wret);
ssize_t termpty_row_length(Termpty *ty, int y);
void       termpty_write(Termpty *ty, const char *input, int len);
void       termpty_resize(Termpty *ty, int new_w, int new_h);
void       termpty_backlog_size_set(Termpty *ty, size_t size);
ssize_t    termpty_backlog_length(Termpty *ty);
void       termpty_backscroll_adjust(Termpty *ty, int *scroll);

pid_t      termpty_pid_get(const Termpty *ty);
void       termpty_block_free(Termblock *tb);
Termblock *termpty_block_new(Termpty *ty, int w, int h, const char *path, const char *link);
void       termpty_block_insert(Termpty *ty, int ch, Termblock *blk);
int        termpty_block_id_get(Termcell *cell, int *x, int *y);
Termblock *termpty_block_get(Termpty *ty, int id);
void       termpty_block_chid_update(Termpty *ty, Termblock *blk);
Termblock *termpty_block_chid_get(Termpty *ty, const char *chid);

void       termpty_cell_copy(Termpty *ty, Termcell *src, Termcell *dst, int n);
void       termpty_cell_fill(Termpty *ty, Termcell *src, Termcell *dst, int n);
void       termpty_cell_codepoint_att_fill(Termpty *ty, Eina_Unicode codepoint, Termatt att, Termcell *dst, int n);
void       termpty_screen_swap(Termpty *ty);

ssize_t termpty_line_length(const Termcell *cells, ssize_t nb_cells);

Config *termpty_config_get(const Termpty *ty);
void termpty_handle_buf(Termpty *ty, const Eina_Unicode *codepoints, int len);

extern int _termpty_log_dom;

#define TERMPTY_SCREEN(Tpty, X, Y) \
  Tpty->screen[X + (((Y + Tpty->circular_offset) % Tpty->h) * Tpty->w)]
#define TERMPTY_FMTCLR(Tatt) \
   (Tatt).autowrapped = (Tatt).newline = 0

#define TERMPTY_RESTRICT_FIELD(Field, Min, Max) \
   do {                                         \
   if (Field >= Max)                            \
     Field = Max - 1;                           \
   else if (Field < Min)                        \
     Field = Min;                               \
   } while (0)

#endif