1 | /*--------------------------------*-C-*--------------------------------------* |
1 | /*--------------------------------*-C-*--------------------------------------* |
2 | * File: screen.c |
2 | * File: screen.c |
3 | *---------------------------------------------------------------------------* |
3 | *---------------------------------------------------------------------------* |
4 | * $Id: screen.C,v 1.4 2003/11/25 15:25:17 pcg Exp $ |
4 | * $Id: screen.C,v 1.8 2003/12/17 09:00:35 pcg Exp $ |
5 | * |
5 | * |
6 | * Copyright (c) 1997-2001 Geoff Wing <gcw@pobox.com> |
6 | * Copyright (c) 1997-2001 Geoff Wing <gcw@pobox.com> |
7 | * |
7 | * |
8 | * This program is free software; you can redistribute it and/or modify |
8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
9 | * it under the terms of the GNU General Public License as published by |
… | |
… | |
31 | #include <X11/Xmd.h> /* get the typedef for CARD32 */ |
31 | #include <X11/Xmd.h> /* get the typedef for CARD32 */ |
32 | |
32 | |
33 | #include <stdint.h> |
33 | #include <stdint.h> |
34 | #include <wchar.h> |
34 | #include <wchar.h> |
35 | |
35 | |
|
|
36 | #include "salloc.C" // HACK!! |
|
|
37 | |
36 | inline void fill_text (text_t *start, text_t value, int len) |
38 | inline void fill_text (text_t *start, text_t value, int len) |
37 | { |
39 | { |
38 | while (len--) |
40 | while (len--) |
39 | *start++ = value; |
41 | *start++ = value; |
40 | } |
42 | } |
41 | |
|
|
42 | #define RESET_CHSTAT(H) \ |
|
|
43 | if ((H)->chstat == WBYTE) \ |
|
|
44 | (H)->chstat = SBYTE, (H)->lost_multi = 1 |
|
|
45 | |
43 | |
46 | /* ------------------------------------------------------------------------- */ |
44 | /* ------------------------------------------------------------------------- */ |
47 | #define PROP_SIZE 16384 |
45 | #define PROP_SIZE 16384 |
48 | #define TABSIZE 8 /* default tab size */ |
46 | #define TABSIZE 8 /* default tab size */ |
49 | |
47 | |
… | |
… | |
115 | |
113 | |
116 | /* ------------------------------------------------------------------------- * |
114 | /* ------------------------------------------------------------------------- * |
117 | * SCREEN `COMMON' ROUTINES * |
115 | * SCREEN `COMMON' ROUTINES * |
118 | * ------------------------------------------------------------------------- */ |
116 | * ------------------------------------------------------------------------- */ |
119 | /* Fill part/all of a line with blanks. */ |
117 | /* Fill part/all of a line with blanks. */ |
120 | /* INTPROTO */ |
|
|
121 | void |
118 | void |
122 | rxvt_blank_line(pR_ text_t *et, rend_t *er, unsigned int width, rend_t efs) |
119 | rxvt_term::scr_blank_line (text_t *et, rend_t *er, unsigned int width, rend_t efs) |
123 | { |
120 | { |
124 | efs &= ~RS_baseattrMask; |
121 | efs &= ~RS_baseattrMask; |
125 | efs = SET_FONT (efs, R->TermWin.fontset->find_font (' ')); |
122 | efs = SET_FONT (efs, TermWin.fontset->find_font (' ')); |
126 | |
123 | |
127 | while (width--) |
124 | while (width--) |
128 | { |
125 | { |
129 | *et++ = ' '; |
126 | *et++ = ' '; |
130 | *er++ = efs; |
127 | *er++ = efs; |
131 | } |
128 | } |
132 | } |
129 | } |
133 | |
130 | |
134 | /* ------------------------------------------------------------------------- */ |
131 | /* ------------------------------------------------------------------------- */ |
135 | /* Fill a full line with blanks - make sure it is allocated first */ |
132 | /* Fill a full line with blanks - make sure it is allocated first */ |
136 | /* INTPROTO */ |
|
|
137 | void |
133 | void |
138 | rxvt_blank_screen_mem(pR_ text_t **tp, rend_t **rp, unsigned int row, rend_t efs) |
134 | rxvt_term::scr_blank_screen_mem (text_t **tp, rend_t **rp, unsigned int row, rend_t efs) |
139 | { |
135 | { |
140 | int width = R->TermWin.ncol; |
|
|
141 | rend_t *er; |
|
|
142 | |
|
|
143 | #ifdef DEBUG_STRICT |
136 | #ifdef DEBUG_STRICT |
144 | assert((tp[row] && rp[row]) || (tp[row] == NULL && rp[row] == NULL)); |
137 | assert((tp[row] && rp[row]) || (tp[row] == NULL && rp[row] == NULL)); |
145 | #endif |
138 | #endif |
146 | if (tp[row] == NULL) { |
139 | if (tp[row] == NULL) |
147 | tp[row] = (text_t *)rxvt_malloc(sizeof(text_t) * width); |
|
|
148 | rp[row] = (rend_t *)rxvt_malloc(sizeof(rend_t) * width); |
|
|
149 | } |
140 | { |
|
|
141 | tp[row] = (text_t *)talloc->alloc (); |
|
|
142 | rp[row] = (rend_t *)ralloc->alloc (); |
|
|
143 | } |
|
|
144 | |
150 | rxvt_blank_line (aR_ tp[row], rp[row], width, efs); |
145 | scr_blank_line (tp[row], rp[row], TermWin.ncol, efs); |
151 | } |
146 | } |
152 | |
147 | |
153 | /* ------------------------------------------------------------------------- * |
148 | /* ------------------------------------------------------------------------- * |
154 | * SCREEN INITIALISATION * |
149 | * SCREEN INITIALISATION * |
155 | * ------------------------------------------------------------------------- */ |
150 | * ------------------------------------------------------------------------- */ |
156 | /* EXTPROTO */ |
|
|
157 | void |
151 | void |
158 | rxvt_scr_reset(pR) |
152 | rxvt_term::scr_reset () |
159 | { |
153 | { |
160 | unsigned int ncol, nrow, prev_ncol, prev_nrow, |
154 | unsigned int ncol, nrow, total_rows, prev_total_rows; |
161 | total_rows, prev_total_rows; |
|
|
162 | unsigned int p, q; |
155 | unsigned int p, q; |
163 | int k; |
156 | int k; |
164 | rend_t setrstyle; |
157 | rend_t setrstyle; |
165 | |
158 | |
166 | D_SCREEN((stderr, "rxvt_scr_reset()")); |
159 | D_SCREEN((stderr, "rxvt_scr_reset()")); |
167 | |
160 | |
168 | R->TermWin.view_start = 0; |
161 | TermWin.view_start = 0; |
169 | RESET_CHSTAT(R); |
|
|
170 | R->num_scr = 0; |
162 | num_scr = 0; |
171 | |
163 | |
172 | prev_ncol = R->prev_ncol; |
|
|
173 | prev_nrow = R->prev_nrow; |
|
|
174 | if (R->TermWin.ncol == 0) |
164 | if (TermWin.ncol == 0) |
175 | R->TermWin.ncol = 80; |
165 | TermWin.ncol = 80; |
|
|
166 | |
176 | if (R->TermWin.nrow == 0) |
167 | if (TermWin.nrow == 0) |
177 | R->TermWin.nrow = 24; |
168 | TermWin.nrow = 24; |
|
|
169 | |
178 | ncol = R->TermWin.ncol; |
170 | ncol = TermWin.ncol; |
179 | nrow = R->TermWin.nrow; |
171 | nrow = TermWin.nrow; |
|
|
172 | |
180 | if (ncol == prev_ncol && nrow == prev_nrow) |
173 | if (ncol == prev_ncol && nrow == prev_nrow) |
181 | return; |
174 | return; |
182 | |
175 | |
183 | R->want_refresh = 1; |
176 | want_refresh = 1; |
184 | |
177 | |
185 | total_rows = nrow + R->TermWin.saveLines; |
178 | total_rows = nrow + TermWin.saveLines; |
186 | prev_total_rows = prev_nrow + R->TermWin.saveLines; |
179 | prev_total_rows = prev_nrow + TermWin.saveLines; |
187 | |
180 | |
188 | R->screen.tscroll = 0; |
181 | screen.tscroll = 0; |
189 | R->screen.bscroll = nrow - 1; |
182 | screen.bscroll = nrow - 1; |
190 | |
183 | |
|
|
184 | if (!talloc) |
|
|
185 | { |
|
|
186 | talloc = new rxvt_salloc (ncol * sizeof (text_t)); |
|
|
187 | ralloc = new rxvt_salloc (ncol * sizeof (rend_t)); |
|
|
188 | } |
|
|
189 | |
191 | if (prev_nrow == 0) { |
190 | if (prev_nrow == 0) |
192 | /* |
191 | { |
|
|
192 | /* |
193 | * A: first time called so just malloc everything : don't rely on realloc |
193 | * first time called so just malloc everything : don't rely on realloc |
194 | * Note: this is still needed so that all the scrollback lines are NULL |
194 | * Note: this is still needed so that all the scrollback lines are NULL |
195 | */ |
195 | */ |
196 | R->screen.text = (text_t **)rxvt_calloc(total_rows, sizeof(text_t *)); |
196 | screen.text = (text_t **)rxvt_calloc(total_rows, sizeof(text_t *)); |
197 | R->buf_text = (text_t **)rxvt_calloc(total_rows, sizeof(text_t *)); |
197 | buf_text = (text_t **)rxvt_calloc(total_rows, sizeof(text_t *)); |
198 | R->drawn_text = (text_t **)rxvt_calloc(nrow, sizeof(text_t *)); |
198 | drawn_text = (text_t **)rxvt_calloc(nrow, sizeof(text_t *)); |
199 | R->swap.text = (text_t **)rxvt_calloc(nrow, sizeof(text_t *)); |
199 | swap.text = (text_t **)rxvt_calloc(nrow, sizeof(text_t *)); |
200 | |
200 | |
201 | R->screen.tlen = (int16_t *)rxvt_calloc(total_rows, sizeof(int16_t)); |
201 | screen.tlen = (int16_t *)rxvt_calloc(total_rows, sizeof(int16_t)); |
202 | R->swap.tlen = (int16_t *)rxvt_calloc(nrow, sizeof(int16_t)); |
202 | swap.tlen = (int16_t *)rxvt_calloc(nrow, sizeof(int16_t)); |
203 | |
203 | |
204 | R->screen.rend = (rend_t **)rxvt_calloc(total_rows, sizeof(rend_t *)); |
204 | screen.rend = (rend_t **)rxvt_calloc(total_rows, sizeof(rend_t *)); |
205 | R->buf_rend = (rend_t **)rxvt_calloc(total_rows, sizeof(rend_t *)); |
205 | buf_rend = (rend_t **)rxvt_calloc(total_rows, sizeof(rend_t *)); |
206 | R->drawn_rend = (rend_t **)rxvt_calloc(nrow, sizeof(rend_t *)); |
206 | drawn_rend = (rend_t **)rxvt_calloc(nrow, sizeof(rend_t *)); |
207 | R->swap.rend = (rend_t **)rxvt_calloc(nrow, sizeof(rend_t *)); |
207 | swap.rend = (rend_t **)rxvt_calloc(nrow, sizeof(rend_t *)); |
208 | |
208 | |
209 | for (p = 0; p < nrow; p++) { |
209 | for (p = 0; p < nrow; p++) |
|
|
210 | { |
210 | q = p + R->TermWin.saveLines; |
211 | q = p + TermWin.saveLines; |
211 | rxvt_blank_screen_mem(aR_ R->screen.text, R->screen.rend, |
212 | scr_blank_screen_mem (screen.text, screen.rend, q, DEFAULT_RSTYLE); |
212 | q, DEFAULT_RSTYLE); |
213 | scr_blank_screen_mem (swap.text, swap.rend, p, DEFAULT_RSTYLE); |
213 | rxvt_blank_screen_mem(aR_ R->swap.text, R->swap.rend, |
|
|
214 | p, DEFAULT_RSTYLE); |
|
|
215 | R->screen.tlen[q] = R->swap.tlen[p] = 0; |
214 | screen.tlen[q] = swap.tlen[p] = 0; |
216 | rxvt_blank_screen_mem(aR_ R->drawn_text, R->drawn_rend, |
215 | scr_blank_screen_mem (drawn_text, drawn_rend, p, DEFAULT_RSTYLE); |
217 | p, DEFAULT_RSTYLE); |
|
|
218 | } |
216 | } |
|
|
217 | |
219 | MEMSET(R->charsets, 'B', sizeof(R->charsets)); |
218 | MEMSET(charsets, 'B', sizeof(charsets)); |
220 | R->TermWin.nscrolled = 0; /* no saved lines */ |
219 | TermWin.nscrolled = 0; /* no saved lines */ |
221 | R->rstyle = DEFAULT_RSTYLE; |
220 | rstyle = DEFAULT_RSTYLE; |
222 | R->screen.flags = Screen_DefaultFlags; |
221 | screen.flags = Screen_DefaultFlags; |
223 | R->screen.cur.row = R->screen.cur.col = 0; |
222 | screen.cur.row = screen.cur.col = 0; |
224 | R->screen.charset = 0; |
223 | screen.charset = 0; |
225 | R->current_screen = PRIMARY; |
224 | current_screen = PRIMARY; |
226 | rxvt_scr_cursor(aR_ SAVE); |
225 | rxvt_scr_cursor (this, SAVE); |
|
|
226 | |
227 | #if NSCREENS |
227 | #if NSCREENS |
228 | R->swap.flags = Screen_DefaultFlags; |
228 | swap.flags = Screen_DefaultFlags; |
229 | R->swap.cur.row = R->swap.cur.col = 0; |
229 | swap.cur.row = swap.cur.col = 0; |
230 | R->swap.charset = 0; |
230 | swap.charset = 0; |
231 | R->current_screen = SECONDARY; |
231 | current_screen = SECONDARY; |
232 | rxvt_scr_cursor(aR_ SAVE); |
232 | rxvt_scr_cursor(aR_ SAVE); |
233 | R->current_screen = PRIMARY; |
233 | current_screen = PRIMARY; |
234 | #endif |
234 | #endif |
|
|
235 | |
235 | R->selection.text = NULL; |
236 | selection.text = NULL; |
236 | R->selection.len = 0; |
237 | selection.len = 0; |
237 | R->selection.op = SELECTION_CLEAR; |
238 | selection.op = SELECTION_CLEAR; |
238 | R->selection.screen = PRIMARY; |
239 | selection.screen = PRIMARY; |
239 | R->selection.clicks = 0; |
240 | selection.clicks = 0; |
240 | CLEAR_ALL_SELECTION(R); |
241 | CLEAR_ALL_SELECTION (this); |
241 | R->rvideo = 0; |
242 | rvideo = 0; |
242 | |
243 | } |
243 | } else { |
244 | else |
244 | /* |
245 | { |
|
|
246 | /* |
245 | * B1: add or delete rows as appropriate |
247 | * add or delete rows as appropriate |
246 | */ |
248 | */ |
247 | setrstyle = DEFAULT_RSTYLE; |
249 | setrstyle = DEFAULT_RSTYLE; |
248 | |
250 | |
249 | if (nrow < prev_nrow) { |
251 | if (nrow < prev_nrow) |
|
|
252 | { |
250 | /* delete rows */ |
253 | /* delete rows */ |
251 | k = min(R->TermWin.nscrolled, prev_nrow - nrow); |
254 | k = min (TermWin.nscrolled, prev_nrow - nrow); |
252 | rxvt_scroll_text(aR_ 0, (int)prev_nrow - 1, k, 1); |
255 | scr_scroll_text (0, (int)prev_nrow - 1, k, 1); |
|
|
256 | |
253 | for (p = nrow; p < prev_nrow; p++) { |
257 | for (p = nrow; p < prev_nrow; p++) |
|
|
258 | { |
254 | q = p + R->TermWin.saveLines; |
259 | q = p + TermWin.saveLines; |
255 | if (R->screen.text[q]) { |
260 | if (screen.text[q]) |
|
|
261 | { |
256 | #ifdef DEBUG_STRICT |
262 | #ifdef DEBUG_STRICT |
257 | assert(R->screen.rend[q]); |
263 | assert (screen.rend[q]); |
258 | #endif |
264 | #endif |
259 | free(R->screen.text[q]); |
265 | talloc->free (screen.text[q]); |
260 | free(R->screen.rend[q]); |
266 | ralloc->free (screen.rend[q]); |
261 | } |
267 | } |
262 | if (R->swap.text[p]) { |
268 | if (swap.text[p]) |
|
|
269 | { |
263 | #ifdef DEBUG_STRICT |
270 | #ifdef DEBUG_STRICT |
264 | assert(R->swap.rend[p]); |
271 | assert (swap.rend[p]); |
265 | #endif |
272 | #endif |
266 | free(R->swap.text[p]); |
273 | talloc->free (swap.text[p]); |
267 | free(R->swap.rend[p]); |
274 | ralloc->free (swap.rend[p]); |
268 | } |
275 | } |
269 | #ifdef DEBUG_STRICT |
276 | #ifdef DEBUG_STRICT |
270 | assert(R->drawn_text[p] && R->drawn_rend[p]); |
277 | assert (drawn_text[p] && drawn_rend[p]); |
271 | #endif |
278 | #endif |
272 | free(R->drawn_text[p]); |
279 | talloc->free (drawn_text[p]); |
273 | free(R->drawn_rend[p]); |
280 | ralloc->free (drawn_rend[p]); |
274 | } |
281 | } |
|
|
282 | |
275 | /* we have fewer rows so fix up cursor position */ |
283 | /* we have fewer rows so fix up cursor position */ |
276 | MIN_IT(R->screen.cur.row, (int32_t)nrow - 1); |
284 | MIN_IT (screen.cur.row, (int32_t)nrow - 1); |
277 | MIN_IT(R->swap.cur.row, (int32_t)nrow - 1); |
285 | MIN_IT (swap.cur.row, (int32_t)nrow - 1); |
278 | |
286 | |
279 | rxvt_scr_reset_realloc(aR); /* realloc _last_ */ |
287 | scr_reset_realloc (); /* realloc _last_ */ |
280 | |
288 | } |
281 | } else if (nrow > prev_nrow) { |
289 | else if (nrow > prev_nrow) |
|
|
290 | { |
282 | /* add rows */ |
291 | /* add rows */ |
283 | rxvt_scr_reset_realloc(aR); /* realloc _first_ */ |
292 | scr_reset_realloc (); /* realloc _first_ */ |
284 | |
293 | |
|
|
294 | TermWin.ncol = prev_ncol; // save b/c scr_blank_screen_mem uses this |
|
|
295 | |
285 | k = min(R->TermWin.nscrolled, nrow - prev_nrow); |
296 | k = min (TermWin.nscrolled, nrow - prev_nrow); |
|
|
297 | |
286 | for (p = prev_total_rows; p < total_rows; p++) { |
298 | for (p = prev_total_rows; p < total_rows; p++) |
|
|
299 | { |
287 | R->screen.tlen[p] = 0; |
300 | screen.tlen[p] = 0; |
288 | R->screen.text[p] = NULL; |
301 | screen.text[p] = NULL; |
289 | R->screen.rend[p] = NULL; |
302 | screen.rend[p] = NULL; |
290 | } |
303 | } |
|
|
304 | |
291 | for (p = prev_total_rows; p < total_rows - k; p++) |
305 | for (p = prev_total_rows; p < total_rows - k; p++) |
292 | rxvt_blank_screen_mem(aR_ R->screen.text, R->screen.rend, |
306 | scr_blank_screen_mem (screen.text, screen.rend, p, setrstyle); |
293 | p, setrstyle); |
307 | |
294 | for (p = prev_nrow; p < nrow; p++) { |
308 | for (p = prev_nrow; p < nrow; p++) |
|
|
309 | { |
295 | R->swap.tlen[p] = 0; |
310 | swap.tlen[p] = 0; |
296 | R->swap.text[p] = NULL; |
311 | swap.text[p] = NULL; |
297 | R->swap.rend[p] = NULL; |
312 | swap.rend[p] = NULL; |
298 | R->drawn_text[p] = NULL; |
313 | drawn_text[p] = NULL; |
299 | R->drawn_rend[p] = NULL; |
314 | drawn_rend[p] = NULL; |
300 | rxvt_blank_screen_mem(aR_ R->swap.text, R->swap.rend, |
315 | scr_blank_screen_mem (swap.text, swap.rend, p, setrstyle); |
301 | p, setrstyle); |
|
|
302 | rxvt_blank_screen_mem(aR_ R->drawn_text, R->drawn_rend, |
316 | scr_blank_screen_mem (drawn_text, drawn_rend, p, setrstyle); |
303 | p, setrstyle); |
|
|
304 | } |
317 | } |
|
|
318 | |
305 | if (k > 0) { |
319 | if (k > 0) |
|
|
320 | { |
306 | rxvt_scroll_text(aR_ 0, (int)nrow - 1, -k, 1); |
321 | scr_scroll_text (0, (int)nrow - 1, -k, 1); |
307 | R->screen.cur.row += k; |
322 | screen.cur.row += k; |
308 | R->screen.s_cur.row += k; |
323 | screen.s_cur.row += k; |
309 | R->TermWin.nscrolled -= k; |
324 | TermWin.nscrolled -= k; |
310 | } |
325 | } |
311 | #ifdef DEBUG_STRICT |
326 | #ifdef DEBUG_STRICT |
312 | assert(R->screen.cur.row < R->TermWin.nrow); |
327 | assert(screen.cur.row < TermWin.nrow); |
313 | assert(R->swap.cur.row < R->TermWin.nrow); |
328 | assert(swap.cur.row < TermWin.nrow); |
314 | #else /* drive with your eyes closed */ |
329 | #else /* drive with your eyes closed */ |
|
|
330 | |
315 | MIN_IT(R->screen.cur.row, nrow - 1); |
331 | MIN_IT(screen.cur.row, nrow - 1); |
316 | MIN_IT(R->swap.cur.row, nrow - 1); |
332 | MIN_IT(swap.cur.row, nrow - 1); |
317 | #endif |
333 | #endif |
|
|
334 | TermWin.ncol = ncol; // save b/c scr_blank_screen_mem uses this |
318 | } |
335 | } |
|
|
336 | |
319 | /* B2: resize columns */ |
337 | /* resize columns */ |
320 | if (ncol != prev_ncol) { |
338 | if (ncol != prev_ncol) |
|
|
339 | { |
|
|
340 | int common = min (prev_ncol, ncol); |
|
|
341 | rxvt_salloc *ta = new rxvt_salloc (ncol * sizeof (text_t)); |
|
|
342 | rxvt_salloc *ra = new rxvt_salloc (ncol * sizeof (rend_t)); |
|
|
343 | |
321 | for (p = 0; p < total_rows; p++) { |
344 | for (p = 0; p < total_rows; p++) |
|
|
345 | { |
322 | if (R->screen.text[p]) { |
346 | if (screen.text[p]) |
323 | R->screen.text[p] = (text_t *)rxvt_realloc(R->screen.text[p], ncol * sizeof(text_t)); |
347 | { |
324 | R->screen.rend[p] = (rend_t *)rxvt_realloc(R->screen.rend[p], ncol * sizeof(rend_t)); |
348 | text_t *t = (text_t *)ta->alloc (); memcpy (t, screen.text[p], common * sizeof (text_t)); screen.text[p] = t; |
|
|
349 | rend_t *r = (rend_t *)ra->alloc (); memcpy (r, screen.rend[p], common * sizeof (rend_t)); screen.rend[p] = r; |
|
|
350 | |
325 | MIN_IT(R->screen.tlen[p], (int16_t)ncol); |
351 | MIN_IT(screen.tlen[p], (int16_t)ncol); |
|
|
352 | |
326 | if (ncol > prev_ncol) |
353 | if (ncol > prev_ncol) |
327 | rxvt_blank_line(aR_ |
354 | scr_blank_line (&(screen.text[p][prev_ncol]), |
328 | &(R->screen.text[p][prev_ncol]), |
|
|
329 | &(R->screen.rend[p][prev_ncol]), |
355 | &(screen.rend[p][prev_ncol]), |
330 | ncol - prev_ncol, |
356 | ncol - prev_ncol, |
331 | setrstyle); |
357 | setrstyle); |
332 | } |
358 | } |
333 | } |
359 | } |
|
|
360 | |
334 | for (p = 0; p < nrow; p++) { |
361 | for (p = 0; p < nrow; p++) |
335 | R->drawn_text[p] = (text_t *)rxvt_realloc(R->drawn_text[p], ncol * sizeof(text_t)); |
362 | { |
336 | R->drawn_rend[p] = (rend_t *)rxvt_realloc(R->drawn_rend[p], ncol * sizeof(rend_t)); |
363 | text_t *t = (text_t *)ta->alloc (); memcpy (t, drawn_text[p], common * sizeof (text_t)); drawn_text[p] = t; |
|
|
364 | rend_t *r = (rend_t *)ra->alloc (); memcpy (r, drawn_rend[p], common * sizeof (rend_t)); drawn_rend[p] = r; |
|
|
365 | |
|
|
366 | if (ncol > prev_ncol) |
|
|
367 | scr_blank_line (&(drawn_text[p][prev_ncol]), |
|
|
368 | &(drawn_rend[p][prev_ncol]), |
|
|
369 | ncol - prev_ncol, setrstyle); |
|
|
370 | |
337 | if (R->swap.text[p]) { |
371 | if (swap.text[p]) |
338 | R->swap.text[p] = (text_t *)rxvt_realloc(R->swap.text[p], ncol * sizeof(text_t)); |
372 | { |
339 | R->swap.rend[p] = (rend_t *)rxvt_realloc(R->swap.rend[p], ncol * sizeof(rend_t)); |
373 | text_t *t = (text_t *)ta->alloc (); memcpy (t, swap.text[p], common * sizeof (text_t)); swap.text[p] = t; |
|
|
374 | rend_t *r = (rend_t *)ra->alloc (); memcpy (r, swap.rend[p], common * sizeof (rend_t)); swap.rend[p] = r; |
|
|
375 | |
340 | MIN_IT(R->swap.tlen[p], (int16_t)ncol); |
376 | MIN_IT(swap.tlen[p], (int16_t)ncol); |
|
|
377 | |
341 | if (ncol > prev_ncol) |
378 | if (ncol > prev_ncol) |
342 | rxvt_blank_line(aR_ |
379 | scr_blank_line (&(swap.text[p][prev_ncol]), |
343 | &(R->swap.text[p][prev_ncol]), |
|
|
344 | &(R->swap.rend[p][prev_ncol]), |
380 | &(swap.rend[p][prev_ncol]), |
345 | ncol - prev_ncol, setrstyle); |
381 | ncol - prev_ncol, setrstyle); |
346 | } |
382 | } |
347 | if (ncol > prev_ncol) |
383 | |
348 | rxvt_blank_line(aR_ |
|
|
349 | &(R->drawn_text[p][prev_ncol]), |
|
|
350 | &(R->drawn_rend[p][prev_ncol]), |
|
|
351 | ncol - prev_ncol, setrstyle); |
|
|
352 | } |
384 | } |
|
|
385 | |
353 | MIN_IT(R->screen.cur.col, (int16_t)ncol - 1); |
386 | MIN_IT (screen.cur.col, (int16_t)ncol - 1); |
354 | MIN_IT(R->swap.cur.col, (int16_t)ncol - 1); |
387 | MIN_IT (swap.cur.col, (int16_t)ncol - 1); |
|
|
388 | |
|
|
389 | delete talloc; talloc = ta; |
|
|
390 | delete ralloc; ralloc = ra; |
355 | } |
391 | } |
|
|
392 | |
356 | if (R->tabs) |
393 | if (tabs) |
357 | free(R->tabs); |
394 | free(tabs); |
358 | } |
395 | } |
359 | |
396 | |
|
|
397 | prev_nrow = nrow; |
|
|
398 | prev_ncol = ncol; |
|
|
399 | |
360 | R->tabs = (char *)rxvt_malloc(ncol * sizeof(char)); |
400 | tabs = (char *)rxvt_malloc (ncol * sizeof(char)); |
361 | |
401 | |
362 | for (p = 0; p < ncol; p++) |
402 | for (p = 0; p < ncol; p++) |
363 | R->tabs[p] = (p % TABSIZE == 0) ? 1 : 0; |
403 | tabs[p] = (p % TABSIZE == 0) ? 1 : 0; |
364 | |
404 | |
365 | R->prev_nrow = nrow; |
405 | tt_winch (); |
366 | R->prev_ncol = ncol; |
|
|
367 | |
|
|
368 | rxvt_tt_winsize(R->cmd_fd, R->TermWin.ncol, R->TermWin.nrow, R->cmd_pid); |
|
|
369 | } |
406 | } |
370 | |
407 | |
371 | /* INTPROTO */ |
|
|
372 | void |
408 | void |
373 | rxvt_scr_reset_realloc(pR) |
409 | rxvt_term::scr_reset_realloc() |
374 | { |
410 | { |
375 | uint16_t total_rows, nrow; |
411 | uint16_t total_rows, nrow; |
376 | |
412 | |
377 | nrow = R->TermWin.nrow; |
413 | nrow = TermWin.nrow; |
378 | total_rows = nrow + R->TermWin.saveLines; |
414 | total_rows = nrow + TermWin.saveLines; |
379 | /* *INDENT-OFF* */ |
415 | /* *INDENT-OFF* */ |
380 | R->screen.text = (text_t **)rxvt_realloc(R->screen.text, total_rows * sizeof(text_t *)); |
416 | screen.text = (text_t **)rxvt_realloc(screen.text, total_rows * sizeof(text_t *)); |
381 | R->buf_text = (text_t **)rxvt_realloc(R->buf_text , total_rows * sizeof(text_t *)); |
417 | buf_text = (text_t **)rxvt_realloc(buf_text , total_rows * sizeof(text_t *)); |
382 | R->drawn_text = (text_t **)rxvt_realloc(R->drawn_text , nrow * sizeof(text_t *)); |
418 | drawn_text = (text_t **)rxvt_realloc(drawn_text , nrow * sizeof(text_t *)); |
383 | R->swap.text = (text_t **)rxvt_realloc(R->swap.text , nrow * sizeof(text_t *)); |
419 | swap.text = (text_t **)rxvt_realloc(swap.text , nrow * sizeof(text_t *)); |
384 | |
420 | |
385 | R->screen.tlen = (int16_t *)rxvt_realloc(R->screen.tlen, total_rows * sizeof(int16_t)); |
421 | screen.tlen = (int16_t *)rxvt_realloc(screen.tlen, total_rows * sizeof(int16_t)); |
386 | R->swap.tlen = (int16_t *)rxvt_realloc(R->swap.tlen , total_rows * sizeof(int16_t)); |
422 | swap.tlen = (int16_t *)rxvt_realloc(swap.tlen , total_rows * sizeof(int16_t)); |
387 | |
423 | |
388 | R->screen.rend = (rend_t **)rxvt_realloc(R->screen.rend, total_rows * sizeof(rend_t *)); |
424 | screen.rend = (rend_t **)rxvt_realloc(screen.rend, total_rows * sizeof(rend_t *)); |
389 | R->buf_rend = (rend_t **)rxvt_realloc(R->buf_rend , total_rows * sizeof(rend_t *)); |
425 | buf_rend = (rend_t **)rxvt_realloc(buf_rend , total_rows * sizeof(rend_t *)); |
390 | R->drawn_rend = (rend_t **)rxvt_realloc(R->drawn_rend , nrow * sizeof(rend_t *)); |
426 | drawn_rend = (rend_t **)rxvt_realloc(drawn_rend , nrow * sizeof(rend_t *)); |
391 | R->swap.rend = (rend_t **)rxvt_realloc(R->swap.rend , nrow * sizeof(rend_t *)); |
427 | swap.rend = (rend_t **)rxvt_realloc(swap.rend , nrow * sizeof(rend_t *)); |
392 | /* *INDENT-ON* */ |
428 | /* *INDENT-ON* */ |
393 | } |
429 | } |
394 | |
430 | |
395 | /* ------------------------------------------------------------------------- */ |
431 | /* ------------------------------------------------------------------------- */ |
396 | /* |
432 | /* |
397 | * Free everything. That way malloc debugging can find leakage. |
433 | * Free everything. That way malloc debugging can find leakage. |
398 | */ |
434 | */ |
399 | /* EXTPROTO */ |
|
|
400 | void |
435 | void |
401 | rxvt_scr_release(pR) |
436 | rxvt_term::scr_release() |
402 | { |
437 | { |
403 | uint16_t total_rows; |
438 | uint16_t total_rows; |
404 | int i; |
439 | int i; |
405 | |
440 | |
406 | total_rows = R->TermWin.nrow + R->TermWin.saveLines; |
441 | total_rows = TermWin.nrow + TermWin.saveLines; |
407 | for (i = 0; i < total_rows; i++) { |
442 | |
408 | if (R->screen.text[i]) { /* then so is R->screen.rend[i] */ |
|
|
409 | free(R->screen.text[i]); |
|
|
410 | #ifdef DEBUG_STRICT |
443 | #ifdef DEBUG_STRICT |
|
|
444 | for (i = 0; i < total_rows; i++) |
|
|
445 | { |
|
|
446 | if (screen.text[i]) |
|
|
447 | /* then so is screen.rend[i] */ |
411 | assert(R->screen.rend[i]); |
448 | assert(screen.rend[i]); |
412 | #endif |
|
|
413 | free(R->screen.rend[i]); |
|
|
414 | } |
|
|
415 | } |
449 | } |
416 | for (i = 0; i < R->TermWin.nrow; i++) { |
450 | #endif |
417 | free(R->drawn_text[i]); |
451 | |
418 | free(R->drawn_rend[i]); |
452 | delete talloc; |
419 | free(R->swap.text[i]); |
453 | delete ralloc; |
420 | free(R->swap.rend[i]); |
454 | |
421 | } |
|
|
422 | free(R->screen.text); |
455 | free (screen.text); |
423 | free(R->screen.tlen); |
456 | free (screen.tlen); |
424 | free(R->screen.rend); |
457 | free (screen.rend); |
425 | free(R->drawn_text); |
458 | free (drawn_text); |
426 | free(R->drawn_rend); |
459 | free (drawn_rend); |
427 | free(R->swap.text); |
460 | free (swap.text); |
428 | free(R->swap.tlen); |
461 | free (swap.tlen); |
429 | free(R->swap.rend); |
462 | free (swap.rend); |
430 | free(R->buf_text); |
463 | free (buf_text); |
431 | free(R->buf_rend); |
464 | free (buf_rend); |
432 | free(R->tabs); |
465 | free (tabs); |
433 | |
466 | |
434 | /* NULL these so if anything tries to use them, we'll know about it */ |
467 | /* NULL these so if anything tries to use them, we'll know about it */ |
435 | R->screen.text = R->drawn_text = R->swap.text = NULL; |
468 | screen.text = drawn_text = swap.text = NULL; |
436 | R->screen.rend = R->drawn_rend = R->swap.rend = NULL; |
469 | screen.rend = drawn_rend = swap.rend = NULL; |
437 | R->screen.tlen = R->swap.tlen = NULL; |
470 | screen.tlen = swap.tlen = NULL; |
438 | R->buf_text = NULL; |
471 | buf_text = NULL; |
439 | R->buf_rend = NULL; |
472 | buf_rend = NULL; |
440 | R->tabs = NULL; |
473 | tabs = NULL; |
441 | } |
474 | } |
442 | |
475 | |
443 | /* ------------------------------------------------------------------------- */ |
476 | /* ------------------------------------------------------------------------- */ |
444 | /* |
477 | /* |
445 | * Hard reset |
478 | * Hard reset |
446 | */ |
479 | */ |
447 | /* EXTPROTO */ |
480 | /* EXTPROTO */ |
448 | void |
481 | void |
449 | rxvt_scr_poweron(pR) |
482 | rxvt_scr_poweron(pR) |
450 | { |
483 | { |
451 | D_SCREEN((stderr, "rxvt_scr_poweron()")); |
484 | D_SCREEN((stderr, "rxvt_scr_poweron()")); |
452 | |
485 | |
453 | rxvt_scr_release(aR); |
486 | R->scr_release (); |
454 | R->prev_nrow = R->prev_ncol = 0; |
487 | R->prev_nrow = R->prev_ncol = 0; |
455 | rxvt_scr_reset(aR); |
488 | R->scr_reset (); |
456 | |
489 | |
457 | rxvt_scr_clear(aR); |
490 | rxvt_scr_clear (aR); |
458 | rxvt_scr_refresh(aR_ SLOW_REFRESH); |
491 | rxvt_scr_refresh (aR_ SLOW_REFRESH); |
459 | #ifdef RXVT_GRAPHICS |
492 | #ifdef RXVT_GRAPHICS |
460 | rxvt_Gr_reset(aR); |
493 | rxvt_Gr_reset (aR); |
461 | #endif |
494 | #endif |
462 | } |
495 | } |
463 | |
496 | |
464 | /* ------------------------------------------------------------------------- * |
497 | /* ------------------------------------------------------------------------- * |
465 | * PROCESS SCREEN COMMANDS * |
498 | * PROCESS SCREEN COMMANDS * |
… | |
… | |
532 | R->want_refresh = 1; |
565 | R->want_refresh = 1; |
533 | |
566 | |
534 | D_SCREEN((stderr, "rxvt_scr_change_screen(%d)", scrn)); |
567 | D_SCREEN((stderr, "rxvt_scr_change_screen(%d)", scrn)); |
535 | |
568 | |
536 | R->TermWin.view_start = 0; |
569 | R->TermWin.view_start = 0; |
537 | RESET_CHSTAT(R); |
|
|
538 | |
570 | |
539 | if (R->current_screen == scrn) |
571 | if (R->current_screen == scrn) |
540 | return R->current_screen; |
572 | return R->current_screen; |
541 | |
573 | |
542 | rxvt_selection_check(aR_ 2); /* check for boundary cross */ |
574 | rxvt_selection_check(aR_ 2); /* check for boundary cross */ |
… | |
… | |
582 | if (R->current_screen == PRIMARY |
614 | if (R->current_screen == PRIMARY |
583 | # ifdef RXVT_GRAPHICS |
615 | # ifdef RXVT_GRAPHICS |
584 | && !rxvt_Gr_Displayed(aR) |
616 | && !rxvt_Gr_Displayed(aR) |
585 | # endif |
617 | # endif |
586 | ) |
618 | ) |
587 | rxvt_scroll_text(aR_ 0, (R->prev_nrow - 1), R->prev_nrow, 0); |
619 | R->scr_scroll_text(0, (R->prev_nrow - 1), R->prev_nrow, 0); |
588 | # endif |
620 | # endif |
589 | #endif |
621 | #endif |
590 | return scrn; |
622 | return scrn; |
591 | } |
623 | } |
592 | |
624 | |
… | |
… | |
626 | * Scroll text between <row1> and <row2> inclusive, by <count> lines |
658 | * Scroll text between <row1> and <row2> inclusive, by <count> lines |
627 | * count positive ==> scroll up |
659 | * count positive ==> scroll up |
628 | * count negative ==> scroll down |
660 | * count negative ==> scroll down |
629 | * spec == 0 for normal routines |
661 | * spec == 0 for normal routines |
630 | */ |
662 | */ |
631 | /* EXTPROTO */ |
|
|
632 | int |
663 | int |
633 | rxvt_scroll_text(pR_ int row1, int row2, int count, int spec) |
664 | rxvt_term::scr_scroll_text (int row1, int row2, int count, int spec) |
634 | { |
665 | { |
635 | int i, j; |
666 | int i, j; |
636 | long nscrolled; |
667 | long nscrolled; |
637 | |
668 | |
638 | if (count == 0 || (row1 > row2)) |
669 | if (count == 0 || (row1 > row2)) |
639 | return 0; |
670 | return 0; |
640 | |
671 | |
641 | R->want_refresh = 1; |
672 | want_refresh = 1; |
642 | D_SCREEN((stderr, "rxvt_scroll_text(%d,%d,%d,%d): %s", row1, row2, count, spec, (R->current_screen == PRIMARY) ? "Primary" : "Secondary")); |
673 | D_SCREEN((stderr, "rxvt_scroll_text(%d,%d,%d,%d): %s", row1, row2, count, spec, (current_screen == PRIMARY) ? "Primary" : "Secondary")); |
643 | |
674 | |
644 | if ((count > 0) && (row1 == 0) && (R->current_screen == PRIMARY)) { |
675 | if ((count > 0) && (row1 == 0) && (current_screen == PRIMARY)) |
|
|
676 | { |
645 | nscrolled = (long)R->TermWin.nscrolled + (long)count;; |
677 | nscrolled = (long)TermWin.nscrolled + (long)count; |
|
|
678 | |
646 | if (nscrolled > (long)R->TermWin.saveLines) |
679 | if (nscrolled > (long)TermWin.saveLines) |
647 | R->TermWin.nscrolled = R->TermWin.saveLines; |
680 | TermWin.nscrolled = TermWin.saveLines; |
648 | else |
681 | else |
649 | R->TermWin.nscrolled = (uint16_t)nscrolled; |
682 | TermWin.nscrolled = (uint16_t)nscrolled; |
|
|
683 | |
650 | if ((R->Options & Opt_scrollWithBuffer) |
684 | if ((Options & Opt_scrollWithBuffer) |
651 | && R->TermWin.view_start != 0 |
685 | && TermWin.view_start != 0 |
652 | && R->TermWin.view_start != R->TermWin.saveLines) |
686 | && TermWin.view_start != TermWin.saveLines) |
653 | rxvt_scr_page(aR_ UP, count); |
687 | rxvt_scr_page (this, UP, count); |
|
|
688 | } |
654 | } else if (!spec) |
689 | else if (!spec) |
655 | row1 += R->TermWin.saveLines; |
|
|
656 | row2 += R->TermWin.saveLines; |
690 | row1 += TermWin.saveLines; |
657 | |
691 | |
|
|
692 | row2 += TermWin.saveLines; |
|
|
693 | |
658 | if (R->selection.op && R->current_screen == R->selection.screen) { |
694 | if (selection.op && current_screen == selection.screen) |
|
|
695 | { |
659 | i = R->selection.beg.row + R->TermWin.saveLines; |
696 | i = selection.beg.row + TermWin.saveLines; |
660 | j = R->selection.end.row + R->TermWin.saveLines; |
697 | j = selection.end.row + TermWin.saveLines; |
661 | if ((i < row1 && j > row1) |
698 | if ((i < row1 && j > row1) |
662 | || (i < row2 && j > row2) |
699 | || (i < row2 && j > row2) |
663 | || (i - count < row1 && i >= row1) |
700 | || (i - count < row1 && i >= row1) |
664 | || (i - count > row2 && i <= row2) |
701 | || (i - count > row2 && i <= row2) |
665 | || (j - count < row1 && j >= row1) |
702 | || (j - count < row1 && j >= row1) |
666 | || (j - count > row2 && j <= row2)) { |
703 | || (j - count > row2 && j <= row2)) |
|
|
704 | { |
667 | CLEAR_ALL_SELECTION(R); |
705 | CLEAR_ALL_SELECTION (this); |
668 | R->selection.op = SELECTION_CLEAR; /* XXX: too aggressive? */ |
706 | selection.op = SELECTION_CLEAR; /* XXX: too aggressive? */ |
|
|
707 | } |
669 | } else if (j >= row1 && j <= row2) { |
708 | else if (j >= row1 && j <= row2) |
|
|
709 | { |
670 | /* move selected region too */ |
710 | /* move selected region too */ |
671 | R->selection.beg.row -= count; |
711 | selection.beg.row -= count; |
672 | R->selection.end.row -= count; |
712 | selection.end.row -= count; |
673 | R->selection.mark.row -= count; |
713 | selection.mark.row -= count; |
674 | } |
714 | } |
675 | } |
715 | } |
|
|
716 | |
676 | rxvt_selection_check(aR_ 0); /* _after_ R->TermWin.nscrolled update */ |
717 | rxvt_selection_check (this, 0); /* _after_ TermWin.nscrolled update */ |
677 | |
718 | |
678 | R->num_scr += count; |
719 | num_scr += count; |
679 | j = count; |
720 | j = count; |
|
|
721 | |
680 | if (count < 0) |
722 | if (count < 0) |
681 | count = -count; |
723 | count = -count; |
|
|
724 | |
682 | i = row2 - row1 + 1; |
725 | i = row2 - row1 + 1; |
683 | MIN_IT(count, i); |
726 | MIN_IT(count, i); |
684 | |
727 | |
685 | if (j > 0) { |
728 | if (j > 0) |
|
|
729 | { |
686 | /* A: scroll up */ |
730 | /* A: scroll up */ |
687 | |
731 | |
688 | /* A1: Copy lines that will get clobbered by the rotation */ |
732 | /* A1: Copy lines that will get clobbered by the rotation */ |
689 | for (i = 0, j = row1; i < count; i++, j++) { |
733 | for (i = 0, j = row1; i < count; i++, j++) |
|
|
734 | { |
690 | R->buf_text[i] = R->screen.text[j]; |
735 | buf_text[i] = screen.text[j]; |
691 | R->buf_rend[i] = R->screen.rend[j]; |
736 | buf_rend[i] = screen.rend[j]; |
692 | } |
737 | } |
693 | /* A2: Rotate lines */ |
738 | /* A2: Rotate lines */ |
694 | for (j = row1, i = j + count; i <= row2; i++, j++) { |
739 | for (j = row1, i = j + count; i <= row2; i++, j++) |
|
|
740 | { |
695 | R->screen.tlen[j] = R->screen.tlen[i]; |
741 | screen.tlen[j] = screen.tlen[i]; |
696 | R->screen.text[j] = R->screen.text[i]; |
742 | screen.text[j] = screen.text[i]; |
697 | R->screen.rend[j] = R->screen.rend[i]; |
743 | screen.rend[j] = screen.rend[i]; |
698 | } |
744 | } |
699 | j = row2 - count + 1, i = count; |
745 | j = row2 - count + 1, i = count; |
|
|
746 | } |
700 | } else /* if (j < 0) */ { |
747 | else /* if (j < 0) */ |
|
|
748 | { |
701 | /* B: scroll down */ |
749 | /* B: scroll down */ |
702 | |
750 | |
703 | /* B1: Copy lines that will get clobbered by the rotation */ |
751 | /* B1: Copy lines that will get clobbered by the rotation */ |
704 | for (i = 0, j = row2; i < count; i++, j--) { |
752 | for (i = 0, j = row2; i < count; i++, j--) |
|
|
753 | { |
705 | R->buf_text[i] = R->screen.text[j]; |
754 | buf_text[i] = screen.text[j]; |
706 | R->buf_rend[i] = R->screen.rend[j]; |
755 | buf_rend[i] = screen.rend[j]; |
707 | } |
756 | } |
708 | /* B2: Rotate lines */ |
757 | /* B2: Rotate lines */ |
709 | for (j = row2, i = j - count; i >= row1; i--, j--) { |
758 | for (j = row2, i = j - count; i >= row1; i--, j--) |
|
|
759 | { |
710 | R->screen.tlen[j] = R->screen.tlen[i]; |
760 | screen.tlen[j] = screen.tlen[i]; |
711 | R->screen.text[j] = R->screen.text[i]; |
761 | screen.text[j] = screen.text[i]; |
712 | R->screen.rend[j] = R->screen.rend[i]; |
762 | screen.rend[j] = screen.rend[i]; |
713 | } |
763 | } |
714 | j = row1, i = count; |
764 | j = row1, i = count; |
715 | count = -count; |
765 | count = -count; |
716 | } |
766 | } |
717 | |
767 | |
718 | /* C: Resurrect lines */ |
768 | /* C: Resurrect lines */ |
719 | for (; i--; j++) { |
769 | for (; i--; j++) |
|
|
770 | { |
720 | R->screen.tlen[j] = 0; |
771 | screen.tlen[j] = 0; |
721 | R->screen.text[j] = R->buf_text[i]; |
772 | screen.text[j] = buf_text[i]; |
722 | R->screen.rend[j] = R->buf_rend[i]; |
773 | screen.rend[j] = buf_rend[i]; |
|
|
774 | |
723 | if (!spec) /* line length may not equal TermWin.ncol */ |
775 | if (!spec) /* line length may not equal TermWin.ncol */ |
724 | rxvt_blank_screen_mem(aR_ R->screen.text, R->screen.rend, |
776 | scr_blank_screen_mem (screen.text, screen.rend, |
725 | (unsigned int)j, R->rstyle); |
777 | (unsigned int)j, rstyle); |
726 | } |
778 | } |
727 | |
779 | |
728 | #ifdef RXVT_GRAPHICS |
780 | #ifdef RXVT_GRAPHICS |
729 | if (rxvt_Gr_Displayed(aR)) |
781 | if (rxvt_Gr_Displayed (this)) |
730 | rxvt_Gr_scroll(aR_ count); |
782 | rxvt_Gr_scroll(this, count); |
731 | #endif |
783 | #endif |
|
|
784 | |
732 | return count; |
785 | return count; |
733 | } |
786 | } |
734 | |
787 | |
735 | /* ------------------------------------------------------------------------- */ |
788 | /* ------------------------------------------------------------------------- */ |
736 | /* |
789 | /* |
737 | * Add text given in <str> of length <len> to screen struct |
790 | * Add text given in <str> of length <len> to screen struct |
… | |
… | |
758 | nlines += (R->screen.cur.row - R->screen.bscroll); |
811 | nlines += (R->screen.cur.row - R->screen.bscroll); |
759 | if ((nlines > 0) |
812 | if ((nlines > 0) |
760 | && (R->screen.tscroll == 0) |
813 | && (R->screen.tscroll == 0) |
761 | && (R->screen.bscroll == (R->TermWin.nrow - 1))) { |
814 | && (R->screen.bscroll == (R->TermWin.nrow - 1))) { |
762 | /* _at least_ this many lines need to be scrolled */ |
815 | /* _at least_ this many lines need to be scrolled */ |
763 | rxvt_scroll_text(aR_ R->screen.tscroll, R->screen.bscroll, nlines, |
816 | R->scr_scroll_text(R->screen.tscroll, R->screen.bscroll, nlines, 0); |
764 | 0); |
|
|
765 | R->screen.cur.row -= nlines; |
817 | R->screen.cur.row -= nlines; |
766 | } |
818 | } |
767 | } |
819 | } |
768 | #ifdef DEBUG_STRICT |
820 | #ifdef DEBUG_STRICT |
769 | assert(R->screen.cur.col < last_col); |
821 | assert(R->screen.cur.col < last_col); |
… | |
… | |
785 | |
837 | |
786 | for (i = 0; i < len;) { |
838 | for (i = 0; i < len;) { |
787 | c = str[i++]; |
839 | c = str[i++]; |
788 | switch (c) { |
840 | switch (c) { |
789 | case '\t': |
841 | case '\t': |
790 | rxvt_scr_tab(aR_ 1); |
842 | rxvt_scr_tab (aR_ 1); |
791 | continue; |
843 | continue; |
792 | case '\n': |
844 | case '\n': |
793 | if (R->screen.tlen[row] != -1) /* XXX: think about this */ |
845 | if (R->screen.tlen[row] != -1) /* XXX: think about this */ |
794 | MAX_IT(R->screen.tlen[row], R->screen.cur.col); |
846 | MAX_IT(R->screen.tlen[row], R->screen.cur.col); |
795 | R->screen.flags &= ~Screen_WrapNext; |
847 | R->screen.flags &= ~Screen_WrapNext; |
796 | if (R->screen.cur.row == R->screen.bscroll) |
848 | if (R->screen.cur.row == R->screen.bscroll) |
797 | rxvt_scroll_text(aR_ R->screen.tscroll, R->screen.bscroll, 1, 0); |
849 | R->scr_scroll_text (R->screen.tscroll, R->screen.bscroll, 1, 0); |
798 | else if (R->screen.cur.row < (R->TermWin.nrow - 1)) |
850 | else if (R->screen.cur.row < (R->TermWin.nrow - 1)) |
799 | row = (++R->screen.cur.row) + R->TermWin.saveLines; |
851 | row = (++R->screen.cur.row) + R->TermWin.saveLines; |
800 | stp = R->screen.text[row]; /* _must_ refresh */ |
852 | stp = R->screen.text[row]; /* _must_ refresh */ |
801 | srp = R->screen.rend[row]; /* _must_ refresh */ |
853 | srp = R->screen.rend[row]; /* _must_ refresh */ |
802 | RESET_CHSTAT(R); |
|
|
803 | continue; |
854 | continue; |
804 | case '\r': |
855 | case '\r': |
805 | if (R->screen.tlen[row] != -1) /* XXX: think about this */ |
856 | if (R->screen.tlen[row] != -1) /* XXX: think about this */ |
806 | MAX_IT(R->screen.tlen[row], R->screen.cur.col); |
857 | MAX_IT(R->screen.tlen[row], R->screen.cur.col); |
807 | R->screen.flags &= ~Screen_WrapNext; |
858 | R->screen.flags &= ~Screen_WrapNext; |
808 | R->screen.cur.col = 0; |
859 | R->screen.cur.col = 0; |
809 | RESET_CHSTAT(R); |
|
|
810 | continue; |
860 | continue; |
811 | default: |
861 | default: |
812 | if (c == 127) |
862 | if (c == 127) |
813 | continue; /* yummmm..... */ |
863 | continue; /* yummmm..... */ |
814 | break; |
864 | break; |
… | |
… | |
821 | clearsel = 1; |
871 | clearsel = 1; |
822 | } |
872 | } |
823 | if (R->screen.flags & Screen_WrapNext) { |
873 | if (R->screen.flags & Screen_WrapNext) { |
824 | R->screen.tlen[row] = -1; |
874 | R->screen.tlen[row] = -1; |
825 | if (R->screen.cur.row == R->screen.bscroll) |
875 | if (R->screen.cur.row == R->screen.bscroll) |
826 | rxvt_scroll_text(aR_ R->screen.tscroll, R->screen.bscroll, 1, 0); |
876 | R->scr_scroll_text(R->screen.tscroll, R->screen.bscroll, 1, 0); |
827 | else if (R->screen.cur.row < (R->TermWin.nrow - 1)) |
877 | else if (R->screen.cur.row < (R->TermWin.nrow - 1)) |
828 | row = (++R->screen.cur.row) + R->TermWin.saveLines; |
878 | row = (++R->screen.cur.row) + R->TermWin.saveLines; |
829 | stp = R->screen.text[row]; /* _must_ refresh */ |
879 | stp = R->screen.text[row]; /* _must_ refresh */ |
830 | srp = R->screen.rend[row]; /* _must_ refresh */ |
880 | srp = R->screen.rend[row]; /* _must_ refresh */ |
831 | R->screen.cur.col = 0; |
881 | R->screen.cur.col = 0; |
… | |
… | |
907 | */ |
957 | */ |
908 | /* EXTPROTO */ |
958 | /* EXTPROTO */ |
909 | void |
959 | void |
910 | rxvt_scr_backspace(pR) |
960 | rxvt_scr_backspace(pR) |
911 | { |
961 | { |
912 | RESET_CHSTAT(R); |
|
|
913 | R->want_refresh = 1; |
962 | R->want_refresh = 1; |
914 | if (R->screen.cur.col == 0) { |
963 | if (R->screen.cur.col == 0) { |
915 | if (R->screen.cur.row > 0) { |
964 | if (R->screen.cur.row > 0) { |
916 | #ifdef TERMCAP_HAS_BW |
965 | #ifdef TERMCAP_HAS_BW |
917 | R->screen.cur.col = R->TermWin.ncol - 1; |
966 | R->screen.cur.col = R->TermWin.ncol - 1; |
… | |
… | |
936 | { |
985 | { |
937 | int i, x; |
986 | int i, x; |
938 | |
987 | |
939 | D_SCREEN((stderr, "rxvt_scr_tab(%d)", count)); |
988 | D_SCREEN((stderr, "rxvt_scr_tab(%d)", count)); |
940 | R->want_refresh = 1; |
989 | R->want_refresh = 1; |
941 | RESET_CHSTAT(R); |
|
|
942 | i = x = R->screen.cur.col; |
990 | i = x = R->screen.cur.col; |
943 | if (count == 0) |
991 | if (count == 0) |
944 | return; |
992 | return; |
945 | else if (count > 0) { |
993 | else if (count > 0) { |
946 | for (; ++i < R->TermWin.ncol; ) |
994 | for (; ++i < R->TermWin.ncol; ) |
… | |
… | |
1023 | void |
1071 | void |
1024 | rxvt_scr_gotorc(pR_ int row, int col, int relative) |
1072 | rxvt_scr_gotorc(pR_ int row, int col, int relative) |
1025 | { |
1073 | { |
1026 | R->want_refresh = 1; |
1074 | R->want_refresh = 1; |
1027 | ZERO_SCROLLBACK(R); |
1075 | ZERO_SCROLLBACK(R); |
1028 | RESET_CHSTAT(R); |
|
|
1029 | #ifdef RXVT_GRAPHICS |
1076 | #ifdef RXVT_GRAPHICS |
1030 | if (rxvt_Gr_Displayed(aR)) |
1077 | if (rxvt_Gr_Displayed(aR)) |
1031 | rxvt_Gr_scroll(aR_ 0); |
1078 | rxvt_Gr_scroll(aR_ 0); |
1032 | #endif |
1079 | #endif |
1033 | |
1080 | |
… | |
… | |
1077 | R->want_refresh = 1; |
1124 | R->want_refresh = 1; |
1078 | dirn = ((direction == UP) ? 1 : -1); |
1125 | dirn = ((direction == UP) ? 1 : -1); |
1079 | D_SCREEN((stderr, "rxvt_scr_index(%d)", dirn)); |
1126 | D_SCREEN((stderr, "rxvt_scr_index(%d)", dirn)); |
1080 | |
1127 | |
1081 | ZERO_SCROLLBACK(R); |
1128 | ZERO_SCROLLBACK(R); |
1082 | RESET_CHSTAT(R); |
|
|
1083 | |
1129 | |
1084 | #ifdef RXVT_GRAPHICS |
1130 | #ifdef RXVT_GRAPHICS |
1085 | if (rxvt_Gr_Displayed(aR)) |
1131 | if (rxvt_Gr_Displayed(aR)) |
1086 | rxvt_Gr_scroll(aR_ 0); |
1132 | rxvt_Gr_scroll(aR_ 0); |
1087 | #endif |
1133 | #endif |
1088 | |
1134 | |
1089 | R->screen.flags &= ~Screen_WrapNext; |
1135 | R->screen.flags &= ~Screen_WrapNext; |
1090 | if ((R->screen.cur.row == R->screen.bscroll && direction == UP) |
1136 | if ((R->screen.cur.row == R->screen.bscroll && direction == UP) |
1091 | || (R->screen.cur.row == R->screen.tscroll && direction == DN)) |
1137 | || (R->screen.cur.row == R->screen.tscroll && direction == DN)) |
1092 | rxvt_scroll_text(aR_ R->screen.tscroll, R->screen.bscroll, dirn, 0); |
1138 | R->scr_scroll_text(R->screen.tscroll, R->screen.bscroll, dirn, 0); |
1093 | else |
1139 | else |
1094 | R->screen.cur.row += dirn; |
1140 | R->screen.cur.row += dirn; |
1095 | MAX_IT(R->screen.cur.row, 0); |
1141 | MAX_IT(R->screen.cur.row, 0); |
1096 | MIN_IT(R->screen.cur.row, (int32_t)R->TermWin.nrow - 1); |
1142 | MIN_IT(R->screen.cur.row, (int32_t)R->TermWin.nrow - 1); |
1097 | rxvt_selection_check(aR_ 0); |
1143 | rxvt_selection_check(aR_ 0); |
… | |
… | |
1106 | */ |
1152 | */ |
1107 | /* EXTPROTO */ |
1153 | /* EXTPROTO */ |
1108 | void |
1154 | void |
1109 | rxvt_scr_erase_line(pR_ int mode) |
1155 | rxvt_scr_erase_line(pR_ int mode) |
1110 | { |
1156 | { |
1111 | unsigned int row, col, num; |
1157 | unsigned int row, col, num; |
1112 | |
1158 | |
1113 | R->want_refresh = 1; |
1159 | R->want_refresh = 1; |
1114 | D_SCREEN((stderr, "rxvt_scr_erase_line(%d) at screen row: %d", mode, R->screen.cur.row)); |
1160 | D_SCREEN((stderr, "rxvt_scr_erase_line(%d) at screen row: %d", mode, R->screen.cur.row)); |
1115 | ZERO_SCROLLBACK(R); |
1161 | ZERO_SCROLLBACK (R); |
1116 | RESET_CHSTAT(R); |
|
|
1117 | |
1162 | |
1118 | #ifdef RXVT_GRAPHICS |
1163 | #ifdef RXVT_GRAPHICS |
1119 | if (rxvt_Gr_Displayed(aR)) |
1164 | if (rxvt_Gr_Displayed (aR)) |
1120 | rxvt_Gr_scroll(aR_ 0); |
1165 | rxvt_Gr_scroll (aR_ 0); |
1121 | #endif |
1166 | #endif |
1122 | |
1167 | |
1123 | rxvt_selection_check(aR_ 1); |
1168 | rxvt_selection_check (aR_ 1); |
1124 | |
1169 | |
1125 | R->screen.flags &= ~Screen_WrapNext; |
1170 | R->screen.flags &= ~Screen_WrapNext; |
1126 | |
1171 | |
1127 | row = R->TermWin.saveLines + R->screen.cur.row; |
1172 | row = R->TermWin.saveLines + R->screen.cur.row; |
1128 | switch (mode) { |
1173 | switch (mode) |
|
|
1174 | { |
1129 | case 0: /* erase to end of line */ |
1175 | case 0: /* erase to end of line */ |
1130 | col = R->screen.cur.col; |
1176 | col = R->screen.cur.col; |
1131 | num = R->TermWin.ncol - col; |
1177 | num = R->TermWin.ncol - col; |
1132 | MIN_IT(R->screen.tlen[row], (int16_t)col); |
1178 | MIN_IT(R->screen.tlen[row], (int16_t)col); |
1133 | if (ROWCOL_IN_ROW_AT_OR_AFTER(R->selection.beg, R->screen.cur) |
1179 | if (ROWCOL_IN_ROW_AT_OR_AFTER(R->selection.beg, R->screen.cur) |
1134 | || ROWCOL_IN_ROW_AT_OR_AFTER(R->selection.end, R->screen.cur)) |
1180 | || ROWCOL_IN_ROW_AT_OR_AFTER(R->selection.end, R->screen.cur)) |
1135 | CLEAR_SELECTION(R); |
1181 | CLEAR_SELECTION(R); |
1136 | break; |
1182 | break; |
1137 | case 1: /* erase to beginning of line */ |
1183 | case 1: /* erase to beginning of line */ |
1138 | col = 0; |
1184 | col = 0; |
1139 | num = R->screen.cur.col + 1; |
1185 | num = R->screen.cur.col + 1; |
1140 | if (ROWCOL_IN_ROW_AT_OR_BEFORE(R->selection.beg, R->screen.cur) |
1186 | if (ROWCOL_IN_ROW_AT_OR_BEFORE(R->selection.beg, R->screen.cur) |
1141 | || ROWCOL_IN_ROW_AT_OR_BEFORE(R->selection.end, R->screen.cur)) |
1187 | || ROWCOL_IN_ROW_AT_OR_BEFORE(R->selection.end, R->screen.cur)) |
1142 | CLEAR_SELECTION(R); |
1188 | CLEAR_SELECTION(R); |
1143 | break; |
1189 | break; |
1144 | case 2: /* erase whole line */ |
1190 | case 2: /* erase whole line */ |
1145 | col = 0; |
1191 | col = 0; |
1146 | num = R->TermWin.ncol; |
1192 | num = R->TermWin.ncol; |
1147 | R->screen.tlen[row] = 0; |
1193 | R->screen.tlen[row] = 0; |
1148 | if (R->selection.beg.row <= R->screen.cur.row |
1194 | if (R->selection.beg.row <= R->screen.cur.row |
1149 | && R->selection.end.row >= R->screen.cur.row) |
1195 | && R->selection.end.row >= R->screen.cur.row) |
1150 | CLEAR_SELECTION(R); |
1196 | CLEAR_SELECTION(R); |
1151 | break; |
1197 | break; |
1152 | default: |
1198 | default: |
1153 | return; |
1199 | return; |
1154 | } |
1200 | } |
|
|
1201 | |
1155 | if (R->screen.text[row]) |
1202 | if (R->screen.text[row]) |
1156 | rxvt_blank_line(aR_ |
1203 | R->scr_blank_line (&(R->screen.text[row][col]), |
1157 | &(R->screen.text[row][col]), |
|
|
1158 | &(R->screen.rend[row][col]), num, R->rstyle); |
1204 | &(R->screen.rend[row][col]), num, R->rstyle); |
1159 | else |
1205 | else |
1160 | rxvt_blank_screen_mem(aR_ R->screen.text, R->screen.rend, row, |
1206 | R->scr_blank_screen_mem (R->screen.text, R->screen.rend, row, R->rstyle); |
1161 | R->rstyle); |
|
|
1162 | } |
1207 | } |
1163 | |
1208 | |
1164 | /* ------------------------------------------------------------------------- */ |
1209 | /* ------------------------------------------------------------------------- */ |
1165 | /* |
1210 | /* |
1166 | * Erase part of whole of the screen |
1211 | * Erase part of whole of the screen |
… | |
… | |
1178 | XGCValues gcvalue; |
1223 | XGCValues gcvalue; |
1179 | |
1224 | |
1180 | R->want_refresh = 1; |
1225 | R->want_refresh = 1; |
1181 | D_SCREEN((stderr, "rxvt_scr_erase_screen(%d) at screen row: %d", mode, R->screen.cur.row)); |
1226 | D_SCREEN((stderr, "rxvt_scr_erase_screen(%d) at screen row: %d", mode, R->screen.cur.row)); |
1182 | ZERO_SCROLLBACK(R); |
1227 | ZERO_SCROLLBACK(R); |
1183 | RESET_CHSTAT(R); |
|
|
1184 | row_offset = (int32_t)R->TermWin.saveLines; |
1228 | row_offset = (int32_t)R->TermWin.saveLines; |
1185 | |
1229 | |
1186 | switch (mode) { |
1230 | switch (mode) { |
1187 | case 0: /* erase to end of screen */ |
1231 | case 0: /* erase to end of screen */ |
1188 | rxvt_selection_check(aR_ 1); |
1232 | rxvt_selection_check(aR_ 1); |
… | |
… | |
1228 | ERASE_ROWS(row, num); |
1272 | ERASE_ROWS(row, num); |
1229 | gcvalue.foreground = R->PixColors[Color_fg]; |
1273 | gcvalue.foreground = R->PixColors[Color_fg]; |
1230 | XChangeGC(R->Xdisplay, R->TermWin.gc, GCForeground, &gcvalue); |
1274 | XChangeGC(R->Xdisplay, R->TermWin.gc, GCForeground, &gcvalue); |
1231 | } |
1275 | } |
1232 | for (; num--; row++) { |
1276 | for (; num--; row++) { |
1233 | rxvt_blank_screen_mem(aR_ R->screen.text, R->screen.rend, |
1277 | R->scr_blank_screen_mem (R->screen.text, R->screen.rend, |
1234 | (unsigned int)(row + row_offset), R->rstyle); |
1278 | (unsigned int)(row + row_offset), R->rstyle); |
1235 | R->screen.tlen[row + row_offset] = 0; |
1279 | R->screen.tlen[row + row_offset] = 0; |
1236 | rxvt_blank_line(aR_ |
1280 | R->scr_blank_line (R->drawn_text[row], R->drawn_rend[row], |
1237 | R->drawn_text[row], R->drawn_rend[row], |
|
|
1238 | (unsigned int)R->TermWin.ncol, ren); |
1281 | (unsigned int)R->TermWin.ncol, ren); |
1239 | } |
1282 | } |
1240 | } |
1283 | } |
1241 | |
1284 | |
1242 | /* ------------------------------------------------------------------------- */ |
1285 | /* ------------------------------------------------------------------------- */ |
1243 | /* |
1286 | /* |
… | |
… | |
1252 | rend_t *r1, fs; |
1295 | rend_t *r1, fs; |
1253 | |
1296 | |
1254 | R->want_refresh = 1; |
1297 | R->want_refresh = 1; |
1255 | R->num_scr_allow = 0; |
1298 | R->num_scr_allow = 0; |
1256 | ZERO_SCROLLBACK(R); |
1299 | ZERO_SCROLLBACK(R); |
1257 | RESET_CHSTAT(R); |
|
|
1258 | rxvt_selection_check(aR_ 3); |
1300 | rxvt_selection_check(aR_ 3); |
1259 | |
1301 | |
1260 | fs = SET_FONT (R->rstyle, R->TermWin.fontset->find_font ('E')); |
1302 | fs = SET_FONT (R->rstyle, R->TermWin.fontset->find_font ('E')); |
1261 | for (k = R->TermWin.saveLines, i = R->TermWin.nrow; i--; k++) { |
1303 | for (k = R->TermWin.saveLines, i = R->TermWin.nrow; i--; k++) { |
1262 | R->screen.tlen[k] = R->TermWin.ncol; /* make the `E's selectable */ |
1304 | R->screen.tlen[k] = R->TermWin.ncol; /* make the `E's selectable */ |
… | |
… | |
1275 | rxvt_scr_insdel_lines(pR_ int count, int insdel) |
1317 | rxvt_scr_insdel_lines(pR_ int count, int insdel) |
1276 | { |
1318 | { |
1277 | int end; |
1319 | int end; |
1278 | |
1320 | |
1279 | ZERO_SCROLLBACK(R); |
1321 | ZERO_SCROLLBACK(R); |
1280 | RESET_CHSTAT(R); |
|
|
1281 | |
1322 | |
1282 | #ifdef RXVT_GRAPHICS |
1323 | #ifdef RXVT_GRAPHICS |
1283 | if (rxvt_Gr_Displayed(aR)) |
1324 | if (rxvt_Gr_Displayed(aR)) |
1284 | rxvt_Gr_scroll(aR_ 0); |
1325 | rxvt_Gr_scroll(aR_ 0); |
1285 | #endif |
1326 | #endif |
… | |
… | |
1296 | else if (insdel == INSERT) |
1337 | else if (insdel == INSERT) |
1297 | count = end; |
1338 | count = end; |
1298 | } |
1339 | } |
1299 | R->screen.flags &= ~Screen_WrapNext; |
1340 | R->screen.flags &= ~Screen_WrapNext; |
1300 | |
1341 | |
1301 | rxvt_scroll_text(aR_ R->screen.cur.row, R->screen.bscroll, insdel * count, |
1342 | R->scr_scroll_text(R->screen.cur.row, R->screen.bscroll, insdel * count, 0); |
1302 | 0); |
|
|
1303 | } |
1343 | } |
1304 | |
1344 | |
1305 | /* ------------------------------------------------------------------------- */ |
1345 | /* ------------------------------------------------------------------------- */ |
1306 | /* |
1346 | /* |
1307 | * Insert/Delete <count> characters from the current position |
1347 | * Insert/Delete <count> characters from the current position |
… | |
… | |
1316 | rend_t *srp; |
1356 | rend_t *srp; |
1317 | int16_t *slp; |
1357 | int16_t *slp; |
1318 | |
1358 | |
1319 | R->want_refresh = 1; |
1359 | R->want_refresh = 1; |
1320 | ZERO_SCROLLBACK(R); |
1360 | ZERO_SCROLLBACK(R); |
1321 | #if 0 |
|
|
1322 | RESET_CHSTAT(R); |
|
|
1323 | #endif |
|
|
1324 | |
1361 | |
1325 | #ifdef RXVT_GRAPHICS |
1362 | #ifdef RXVT_GRAPHICS |
1326 | if (rxvt_Gr_Displayed(aR)) |
1363 | if (rxvt_Gr_Displayed(aR)) |
1327 | rxvt_Gr_scroll(aR_ 0); |
1364 | rxvt_Gr_scroll(aR_ 0); |
1328 | #endif |
1365 | #endif |
… | |
… | |
1359 | R->selection.beg.col += count; |
1396 | R->selection.beg.col += count; |
1360 | R->selection.mark.col += count; /* XXX: yes? */ |
1397 | R->selection.mark.col += count; /* XXX: yes? */ |
1361 | R->selection.end.col += count; |
1398 | R->selection.end.col += count; |
1362 | } |
1399 | } |
1363 | } |
1400 | } |
1364 | rxvt_blank_line(aR_ &(stp[R->screen.cur.col]), &(srp[R->screen.cur.col]), |
1401 | R->scr_blank_line (&(stp[R->screen.cur.col]), &(srp[R->screen.cur.col]), |
1365 | (unsigned int)count, R->rstyle); |
1402 | (unsigned int)count, R->rstyle); |
1366 | break; |
1403 | break; |
1367 | case ERASE: |
1404 | case ERASE: |
1368 | R->screen.cur.col += count; /* don't worry if > R->TermWin.ncol */ |
1405 | R->screen.cur.col += count; /* don't worry if > R->TermWin.ncol */ |
1369 | rxvt_selection_check(aR_ 1); |
1406 | rxvt_selection_check(aR_ 1); |
1370 | R->screen.cur.col -= count; |
1407 | R->screen.cur.col -= count; |
1371 | rxvt_blank_line(aR_ &(stp[R->screen.cur.col]), &(srp[R->screen.cur.col]), |
1408 | R->scr_blank_line (&(stp[R->screen.cur.col]), &(srp[R->screen.cur.col]), |
1372 | (unsigned int)count, R->rstyle); |
1409 | (unsigned int)count, R->rstyle); |
1373 | break; |
1410 | break; |
1374 | case DELETE: |
1411 | case DELETE: |
1375 | tr = srp[R->TermWin.ncol - 1] |
1412 | tr = srp[R->TermWin.ncol - 1] |
1376 | & (RS_fgMask | RS_bgMask | RS_baseattrMask); |
1413 | & (RS_fgMask | RS_bgMask | RS_baseattrMask); |
1377 | for (col = R->screen.cur.col; (col + count) < R->TermWin.ncol; col++) { |
1414 | for (col = R->screen.cur.col; (col + count) < R->TermWin.ncol; col++) { |
1378 | stp[col] = stp[col + count]; |
1415 | stp[col] = stp[col + count]; |
1379 | srp[col] = srp[col + count]; |
1416 | srp[col] = srp[col + count]; |
1380 | } |
1417 | } |
1381 | rxvt_blank_line(aR_ |
1418 | R->scr_blank_line (&(stp[R->TermWin.ncol - count]), |
1382 | &(stp[R->TermWin.ncol - count]), |
|
|
1383 | &(srp[R->TermWin.ncol - count]), |
1419 | &(srp[R->TermWin.ncol - count]), |
1384 | (unsigned int)count, tr); |
1420 | (unsigned int)count, tr); |
1385 | if (*slp == -1) /* break line continuation */ |
1421 | if (*slp == -1) /* break line continuation */ |
1386 | *slp = R->TermWin.ncol; |
1422 | *slp = R->TermWin.ncol; |
1387 | *slp -= count; |
1423 | *slp -= count; |
1388 | MAX_IT(*slp, 0); |
1424 | MAX_IT(*slp, 0); |
1389 | if (R->selection.op && R->current_screen == R->selection.screen |
1425 | if (R->selection.op && R->current_screen == R->selection.screen |
… | |
… | |
1548 | */ |
1584 | */ |
1549 | /* EXTPROTO */ |
1585 | /* EXTPROTO */ |
1550 | void |
1586 | void |
1551 | rxvt_scr_report_position(pR) |
1587 | rxvt_scr_report_position(pR) |
1552 | { |
1588 | { |
1553 | rxvt_tt_printf(aR_ "\033[%d;%dR", R->screen.cur.row + 1, |
1589 | R->tt_printf("\033[%d;%dR", R->screen.cur.row + 1, R->screen.cur.col + 1); |
1554 | R->screen.cur.col + 1); |
|
|
1555 | } |
1590 | } |
1556 | |
1591 | |
1557 | /* ------------------------------------------------------------------------- * |
1592 | /* ------------------------------------------------------------------------- * |
1558 | * FONTS * |
1593 | * FONTS * |
1559 | * ------------------------------------------------------------------------- */ |
1594 | * ------------------------------------------------------------------------- */ |
… | |
… | |
2415 | |
2450 | |
2416 | /* ------------------------------------------------------------------------- */ |
2451 | /* ------------------------------------------------------------------------- */ |
2417 | /* |
2452 | /* |
2418 | * Paste a selection direct to the command fd |
2453 | * Paste a selection direct to the command fd |
2419 | */ |
2454 | */ |
2420 | /* INTPROTO */ |
|
|
2421 | void |
2455 | void |
2422 | rxvt_PasteIt(pR_ const unsigned char *data, unsigned int nitems) |
2456 | rxvt_term::paste (const unsigned char *data, unsigned int len) |
2423 | { |
2457 | { |
2424 | unsigned int i, j, n; |
2458 | unsigned int i, j, n; |
2425 | unsigned char *ds = (unsigned char *)rxvt_malloc(PROP_SIZE); |
2459 | unsigned char *ds = (unsigned char *)rxvt_malloc (PROP_SIZE); |
2426 | |
2460 | |
2427 | /* convert normal newline chars into common keyboard Return key sequence */ |
2461 | /* convert normal newline chars into common keyboard Return key sequence */ |
2428 | for (i = 0; i < nitems; i += PROP_SIZE) { |
2462 | for (i = 0; i < len; i += PROP_SIZE) |
|
|
2463 | { |
2429 | n = min(nitems - i, PROP_SIZE); |
2464 | n = min (len - i, PROP_SIZE); |
2430 | MEMCPY(ds, data + i, n); |
2465 | MEMCPY (ds, data + i, n); |
|
|
2466 | |
2431 | for (j = 0; j < n; j++) |
2467 | for (j = 0; j < n; j++) |
2432 | if (ds[j] == '\n') |
2468 | if (ds[j] == '\n') |
2433 | ds[j] = '\r'; |
2469 | ds[j] = '\r'; |
|
|
2470 | |
2434 | rxvt_tt_write(aR_ ds, (int)n); |
2471 | tt_write (ds, (int)n); |
2435 | } |
2472 | } |
|
|
2473 | |
2436 | free(ds); |
2474 | free(ds); |
2437 | } |
2475 | } |
2438 | |
2476 | |
2439 | /* ------------------------------------------------------------------------- */ |
2477 | /* ------------------------------------------------------------------------- */ |
2440 | /* |
2478 | /* |
2441 | * Respond to a notification that a primary selection has been sent |
2479 | * Respond to a notification that a primary selection has been sent |
… | |
… | |
2443 | */ |
2481 | */ |
2444 | /* EXTPROTO */ |
2482 | /* EXTPROTO */ |
2445 | int |
2483 | int |
2446 | rxvt_selection_paste(pR_ Window win, Atom prop, Bool delete_prop) |
2484 | rxvt_selection_paste(pR_ Window win, Atom prop, Bool delete_prop) |
2447 | { |
2485 | { |
2448 | long nread = 0; |
2486 | long nread = 0; |
2449 | unsigned long bytes_after; |
2487 | unsigned long bytes_after; |
2450 | XTextProperty ct; |
2488 | XTextProperty ct; |
2451 | #ifdef MULTICHAR_SET |
2489 | int dummy_count; |
2452 | int dummy_count; |
2490 | char **cl; |
2453 | char **cl; |
|
|
2454 | #endif |
|
|
2455 | |
2491 | |
2456 | D_SELECT((stderr, "rxvt_selection_paste(%08lx, %lu, %d), wait=%2x", win, (unsigned long)prop, (int)delete_prop, R->selection_wait)); |
2492 | D_SELECT((stderr, "rxvt_selection_paste(%08lx, %lu, %d), wait=%2x", win, (unsigned long)prop, (int)delete_prop, R->selection_wait)); |
2457 | |
2493 | |
2458 | if (prop == None) { /* check for failed XConvertSelection */ |
2494 | if (prop == None) /* check for failed XConvertSelection */ |
2459 | #ifdef MULTICHAR_SET |
2495 | { |
2460 | if ((R->selection_type & Sel_CompoundText)) { |
2496 | if ((R->selection_type & Sel_CompoundText)) |
|
|
2497 | { |
2461 | int selnum = R->selection_type & Sel_whereMask; |
2498 | int selnum = R->selection_type & Sel_whereMask; |
2462 | |
2499 | |
2463 | R->selection_type = 0; |
2500 | R->selection_type = 0; |
2464 | if (selnum != Sel_direct) |
2501 | if (selnum != Sel_direct) |
2465 | rxvt_selection_request_other(aR_ XA_STRING, selnum); |
2502 | rxvt_selection_request_other(aR_ XA_STRING, selnum); |
|
|
2503 | } |
2466 | } |
2504 | |
2467 | #endif |
|
|
2468 | return 0; |
2505 | return 0; |
2469 | } |
2506 | } |
|
|
2507 | |
2470 | for (;;) { |
2508 | for (;;) |
|
|
2509 | { |
2471 | if (XGetWindowProperty(R->Xdisplay, win, prop, (long)(nread / 4), |
2510 | if (XGetWindowProperty(R->Xdisplay, win, prop, (long)(nread / 4), |
2472 | (long)(PROP_SIZE / 4), delete_prop, |
2511 | (long)(PROP_SIZE / 4), delete_prop, |
2473 | AnyPropertyType, &ct.encoding, &ct.format, |
2512 | AnyPropertyType, &ct.encoding, &ct.format, |
2474 | &ct.nitems, &bytes_after, |
2513 | &ct.nitems, &bytes_after, |
2475 | &ct.value) != Success) |
2514 | &ct.value) != Success) |
2476 | break; |
2515 | break; |
|
|
2516 | |
2477 | if (ct.encoding == 0) { |
2517 | if (ct.encoding == 0) |
|
|
2518 | { |
2478 | D_SELECT((stderr, "rxvt_selection_paste: property didn't exist!")); |
2519 | D_SELECT((stderr, "rxvt_selection_paste: property didn't exist!")); |
2479 | break; |
2520 | break; |
2480 | } |
2521 | } |
|
|
2522 | |
2481 | if (ct.value == NULL) { |
2523 | if (ct.value == NULL) |
|
|
2524 | { |
2482 | D_SELECT((stderr, "rxvt_selection_paste: property shooting blanks!")); |
2525 | D_SELECT((stderr, "rxvt_selection_paste: property shooting blanks!")); |
2483 | continue; |
2526 | continue; |
2484 | } |
2527 | } |
|
|
2528 | |
2485 | if (ct.nitems == 0) { |
2529 | if (ct.nitems == 0) |
|
|
2530 | { |
2486 | D_SELECT((stderr, "rxvt_selection_paste: property empty - also INCR end")); |
2531 | D_SELECT((stderr, "rxvt_selection_paste: property empty - also INCR end")); |
2487 | if (R->selection_wait == Sel_normal && nread == 0) { |
2532 | if (R->selection_wait == Sel_normal && nread == 0) |
|
|
2533 | { |
2488 | /* |
2534 | /* |
2489 | * pass through again trying CUT_BUFFER0 if we've come from |
2535 | * pass through again trying CUT_BUFFER0 if we've come from |
2490 | * XConvertSelection() but nothing was presented |
2536 | * XConvertSelection() but nothing was presented |
2491 | */ |
2537 | */ |
2492 | D_SELECT((stderr, "rxvt_selection_request: pasting CUT_BUFFER0")); |
2538 | D_SELECT((stderr, "rxvt_selection_request: pasting CUT_BUFFER0")); |
2493 | rxvt_selection_paste(aR_ Xroot, XA_CUT_BUFFER0, False); |
2539 | rxvt_selection_paste (aR_ Xroot, XA_CUT_BUFFER0, False); |
2494 | } |
2540 | } |
|
|
2541 | |
2495 | nread = -1; /* discount any previous stuff */ |
2542 | nread = -1; /* discount any previous stuff */ |
2496 | break; |
2543 | break; |
2497 | } |
2544 | } |
|
|
2545 | |
2498 | nread += ct.nitems; |
2546 | nread += ct.nitems; |
2499 | #ifdef MULTICHAR_SET |
|
|
2500 | if (XmbTextPropertyToTextList(R->Xdisplay, &ct, &cl, |
2547 | if (XmbTextPropertyToTextList (R->Xdisplay, &ct, &cl, |
2501 | &dummy_count) == Success && cl) { |
2548 | &dummy_count) == Success && cl) |
2502 | rxvt_PasteIt(aR_ cl[0], STRLEN(cl[0])); |
2549 | { |
|
|
2550 | R->paste ((unsigned char *)cl[0], STRLEN (cl[0])); |
2503 | XFreeStringList(cl); |
2551 | XFreeStringList (cl); |
|
|
2552 | } |
2504 | } else |
2553 | else |
2505 | #endif |
2554 | R->paste (ct.value, ct.nitems); |
2506 | rxvt_PasteIt(aR_ ct.value, (unsigned int)ct.nitems); |
2555 | |
2507 | if (bytes_after == 0) |
2556 | if (bytes_after == 0) |
2508 | break; |
2557 | break; |
|
|
2558 | |
2509 | XFree(ct.value); |
2559 | XFree (ct.value); |
2510 | } |
2560 | } |
|
|
2561 | |
2511 | if (ct.value) |
2562 | if (ct.value) |
2512 | XFree(ct.value); |
2563 | XFree (ct.value); |
|
|
2564 | |
2513 | if (R->selection_wait == Sel_normal) |
2565 | if (R->selection_wait == Sel_normal) |
2514 | R->selection_wait = Sel_none; |
2566 | R->selection_wait = Sel_none; |
|
|
2567 | |
2515 | D_SELECT((stderr, "rxvt_selection_paste: bytes written: %ld", nread)); |
2568 | D_SELECT((stderr, "rxvt_selection_paste: bytes written: %ld", nread)); |
2516 | return (int)nread; |
2569 | return (int)nread; |
|
|
2570 | } |
|
|
2571 | |
|
|
2572 | void |
|
|
2573 | rxvt_term::incr_cb (time_watcher &w) |
|
|
2574 | { |
|
|
2575 | w.stop (); |
|
|
2576 | selection_wait = Sel_none; |
|
|
2577 | |
|
|
2578 | rxvt_print_error("data loss: timeout on INCR selection paste"); |
2517 | } |
2579 | } |
2518 | |
2580 | |
2519 | /* |
2581 | /* |
2520 | * INCR support originally provided by Paul Sheer <psheer@obsidian.co.za> |
2582 | * INCR support originally provided by Paul Sheer <psheer@obsidian.co.za> |
2521 | */ |
2583 | */ |
… | |
… | |
2553 | } else if (R->selection_wait == Sel_incr) { |
2615 | } else if (R->selection_wait == Sel_incr) { |
2554 | reget_time = 1; |
2616 | reget_time = 1; |
2555 | if (rxvt_selection_paste(aR_ win, prop, True) == -1) { |
2617 | if (rxvt_selection_paste(aR_ win, prop, True) == -1) { |
2556 | D_SELECT((stderr, "rxvt_selection_property: INCR: clean end")); |
2618 | D_SELECT((stderr, "rxvt_selection_property: INCR: clean end")); |
2557 | R->selection_wait = Sel_none; |
2619 | R->selection_wait = Sel_none; |
2558 | R->timeout[TIMEOUT_INCR].tv_sec = 0; /* turn off timer */ |
2620 | R->incr_ev.stop (); |
2559 | } |
2621 | } |
2560 | } |
2622 | } |
2561 | if (reget_time) { /* received more data so reget time */ |
2623 | if (reget_time) /* received more data so reget time */ |
2562 | (void)gettimeofday(&(R->timeout[TIMEOUT_INCR]), NULL); |
2624 | R->incr_ev.start (NOW + 10); |
2563 | R->timeout[TIMEOUT_INCR].tv_sec += 10; /* ten seconds wait */ |
|
|
2564 | } |
|
|
2565 | } |
2625 | } |
2566 | /* ------------------------------------------------------------------------- */ |
2626 | /* ------------------------------------------------------------------------- */ |
2567 | /* |
2627 | /* |
2568 | * Request the current selection: |
2628 | * Request the current selection: |
2569 | * Order: > internal selection if available |
2629 | * Order: > internal selection if available |
… | |
… | |
2581 | if (x < 0 || x >= R->TermWin.width || y < 0 || y >= R->TermWin.height) |
2641 | if (x < 0 || x >= R->TermWin.width || y < 0 || y >= R->TermWin.height) |
2582 | return; /* outside window */ |
2642 | return; /* outside window */ |
2583 | |
2643 | |
2584 | if (R->selection.text != NULL) { /* internal selection */ |
2644 | if (R->selection.text != NULL) { /* internal selection */ |
2585 | D_SELECT((stderr, "rxvt_selection_request: pasting internal")); |
2645 | D_SELECT((stderr, "rxvt_selection_request: pasting internal")); |
2586 | rxvt_PasteIt(aR_ R->selection.text, R->selection.len); |
2646 | R->paste (R->selection.text, R->selection.len); |
2587 | return; |
2647 | return; |
2588 | } else { |
2648 | } else { |
2589 | int i; |
2649 | int i; |
2590 | |
2650 | |
2591 | R->selection_request_time = tm; |
2651 | R->selection_request_time = tm; |
2592 | R->selection_wait = Sel_normal; |
2652 | R->selection_wait = Sel_normal; |
2593 | for (i = Sel_Primary; i <= Sel_Clipboard; i++) { |
2653 | for (i = Sel_Primary; i <= Sel_Clipboard; i++) { |
2594 | #ifdef MULTICHAR_SET |
|
|
2595 | R->selection_type = Sel_CompoundText; |
2654 | R->selection_type = Sel_CompoundText; |
2596 | #else |
|
|
2597 | R->selection_type = 0; |
|
|
2598 | #endif |
|
|
2599 | if (rxvt_selection_request_other(aR_ |
2655 | if (rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], i)) |
2600 | #ifdef MULTICHAR_SET |
|
|
2601 | R->xa[XA_COMPOUND_TEXT], |
|
|
2602 | #else |
|
|
2603 | XA_STRING, |
|
|
2604 | #endif |
|
|
2605 | i)) |
|
|
2606 | return; |
2656 | return; |
2607 | } |
2657 | } |
2608 | } |
2658 | } |
2609 | R->selection_wait = Sel_none; /* don't loop in rxvt_selection_paste() */ |
2659 | R->selection_wait = Sel_none; /* don't loop in rxvt_selection_paste() */ |
2610 | D_SELECT((stderr, "rxvt_selection_request: pasting CUT_BUFFER0")); |
2660 | D_SELECT((stderr, "rxvt_selection_request: pasting CUT_BUFFER0")); |
… | |
… | |
2819 | */ |
2869 | */ |
2820 | |
2870 | |
2821 | /* what do we want: spaces/tabs are delimiters or cutchars or non-cutchars */ |
2871 | /* what do we want: spaces/tabs are delimiters or cutchars or non-cutchars */ |
2822 | #define DELIMIT_TEXT(x) \ |
2872 | #define DELIMIT_TEXT(x) \ |
2823 | (((x) == ' ' || (x) == '\t') ? 2 : (STRCHR(R->rs[Rs_cutchars], (x)) != NULL)) |
2873 | (((x) == ' ' || (x) == '\t') ? 2 : (STRCHR(R->rs[Rs_cutchars], (x)) != NULL)) |
2824 | #ifdef MULTICHAR_SET |
|
|
2825 | # define DELIMIT_REND(x) (((x) & RS_multiMask) ? 1 : 0) |
|
|
2826 | #else |
|
|
2827 | # define DELIMIT_REND(x) 1 |
2874 | #define DELIMIT_REND(x) 1 |
2828 | #endif |
|
|
2829 | |
2875 | |
2830 | /* INTPROTO */ |
2876 | /* INTPROTO */ |
2831 | void |
2877 | void |
2832 | rxvt_selection_delimit_word(pR_ enum page_dirn dirn, const row_col_t *mark, row_col_t *ret) |
2878 | rxvt_selection_delimit_word(pR_ enum page_dirn dirn, const row_col_t *mark, row_col_t *ret) |
2833 | { |
2879 | { |