ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/command.C
(Generate patch)

Comparing rxvt-unicode/src/command.C (file contents):
Revision 1.97 by root, Mon Jul 26 18:01:19 2004 UTC vs.
Revision 1.183 by root, Tue Dec 21 06:43:00 2004 UTC

48#include "../config.h" /* NECESSARY */ 48#include "../config.h" /* NECESSARY */
49#include "rxvt.h" /* NECESSARY */ 49#include "rxvt.h" /* NECESSARY */
50#include "version.h" 50#include "version.h"
51#include "command.h" 51#include "command.h"
52 52
53#include <wchar.h> 53#include <cwchar>
54#include <csignal>
54 55
55/*----------------------------------------------------------------------*/ 56/*----------------------------------------------------------------------*/
56 57
57#define IS_CONTROL(ch) !((ch) & 0xffffff60UL) 58#define IS_CONTROL(ch) !((ch) & 0xffffff60UL)
58 59
59// exception thrown when the command parser runs out of input data 60// exception thrown when the command parser runs out of input data
60class out_of_input { } out_of_input; 61class out_of_input { } out_of_input;
62
63#if ENABLE_FRILLS || ISO_14755
64
65#define ISO_14755_STARTED 0x80000000UL
66#define ISO_14755_51 0x40000000UL // basic (section 5.1)
67#define ISO_14755_52 0x20000000UL // keycap (section 5.2)
68#define ISO_14755_54 0x10000000UL // code feedback (section 5.4)
69#define ISO_14755_MASK 0x0fffffffUL
70
71#if ISO_14755
72static unsigned short iso14755_symtab[] = {
73 // keysym, unicode
74 XK_Left, 0x2190,
75 XK_KP_Left, 0x2190,
76 XK_Up, 0x2191,
77 XK_KP_Up, 0x2191,
78 XK_Right, 0x2192,
79 XK_KP_Right, 0x2192,
80 XK_Down, 0x2193,
81 XK_KP_Down, 0x2193,
82 XK_Linefeed, 0x21b4,
83 XK_Return, 0x21b5,
84 XK_KP_Enter, 0x21b5,
85
86 XK_Prior, 0x21de,
87 XK_Next, 0x21df,
88 XK_Tab, 0x21e5,
89 XK_ISO_Left_Tab, 0x21e6,
90 XK_Shift_L, 0x21e7,
91 XK_Shift_R, 0x21e7,
92
93 XK_Shift_Lock, 0x21eb,
94 XK_ISO_Lock, 0x21eb,
95 XK_ISO_Lock, 0x21eb,
96 XK_Caps_Lock, 0x21ec,
97 XK_Num_Lock, 0x21ed,
98 XK_ISO_Level3_Shift, 0x21ee,
99 XK_ISO_Level3_Lock, 0x21ef,
100 XK_ISO_Group_Lock, 0x21f0,
101 XK_Home, 0x21f1,
102 XK_End, 0x21f2,
103
104 XK_Execute, 0x2318,
105 XK_Begin, 0x2320,
106 XK_Delete, 0x2326,
107 XK_Clear, 0x2327,
108 XK_BackSpace, 0x232b,
109 XK_Insert, 0x2380,
110 XK_Control_L, 0x2388,
111 XK_Control_R, 0x2388,
112 XK_Pause, 0x2389,
113 XK_Break, 0x238a,
114 XK_Escape, 0x238b,
115 XK_Undo, 0x238c,
116 XK_Print, 0x2399,
117
118 XK_space, 0x2423,
119 XK_KP_Space, 0x2422,
120 0,
121};
122
123void
124rxvt_term::iso14755_54 (int x, int y)
125{
126 x = Pixel2Col (x);
127 y = Pixel2Row (y);
128
129 if (x < 0 || x >= TermWin.ncol
130 || y < 0 || y >= TermWin.nrow)
131 return;
132
133 for (;;)
134 {
135 text_t t = screen.text[y + TermWin.saveLines - TermWin.view_start][x];
136
137 if (t != NOCHAR || !x)
138 {
139 iso14755_51 (screen.text[y + TermWin.saveLines - TermWin.view_start][x],
140 screen.rend[y + TermWin.saveLines - TermWin.view_start][x]);
141 iso14755buf = ISO_14755_54;
142 break;
143 }
144
145 x--;
146 }
147
148}
149#endif
150
151#if ENABLE_OVERLAY
152void
153rxvt_term::iso14755_51 (unicode_t ch, rend_t r)
154{
155 rxvt_fontset *fs = FONTSET (r);
156 rxvt_font *f = (*fs)[fs->find_font (ch)];
157 wchar_t *chr, *alloc, ch2;
158 int len;
159
160#if ENABLE_COMBINING
161 if (IS_COMPOSE (ch))
162 {
163 len = rxvt_composite.expand (ch, 0);
164 alloc = chr = new wchar_t[len];
165 rxvt_composite.expand (ch, chr);
166 }
167 else
168#endif
169 {
170 ch2 = ch;
171
172 alloc = 0;
173 chr = &ch2;
174 len = 1;
175 }
176
177 int width = strlen (f->name);
178
179 scr_overlay_new (0, -1, width < 8+5 ? 8+5 : width, len + 1);
180
181 r = SET_STYLE (OVERLAY_RSTYLE, GET_STYLE (r));
182
183 for (int y = 0; y < len; y++)
184 {
185 char buf[9];
186
187 ch = *chr++;
188
189 sprintf (buf, "%8x", ch);
190 scr_overlay_set (0, y, buf);
191 scr_overlay_set (9, y, '=');
192#if !UNICODE3
193 if (ch >= 0x10000)
194 ch = 0xfffd;
195#endif
196 scr_overlay_set (11, y, ch, r);
197 scr_overlay_set (12, y, NOCHAR, r);
198 }
199
200 scr_overlay_set (0, len, f->name);
201
202#if ENABLE_COMBINING
203 if (alloc)
204 delete [] alloc;
205#endif
206}
207#endif
208
209void
210rxvt_term::commit_iso14755 ()
211{
212 wchar_t ch[2];
213
214 ch[0] = iso14755buf & ISO_14755_MASK;
215 ch[1] = 0;
216
217 if (iso14755buf & ISO_14755_51)
218 {
219 char mb[16];
220 int len;
221
222 // allow verbatim 0-bytes and control-bytes to be entered
223 if (ch[0] >= 0x20)
224 len = wcstombs (mb, ch, 16);
225 else
226 {
227 mb[0] = ch[0];
228 len = 1;
229 }
230
231 if (len > 0)
232 tt_write ((unsigned char *)mb, len);
233 else
234 scr_bell ();
235 }
236
237 iso14755buf = 0;
238}
239
240int
241rxvt_term::hex_keyval (XKeyEvent &ev)
242{
243 // check wether this event corresponds to a hex digit
244 // if the modifiers had not been pressed.
245 for (int index = 0; index < 8; index++)
246 {
247 KeySym k = XLookupKeysym (&ev, index);
248
249 if (k >= XK_KP_0 && k <= XK_KP_9) return k - XK_KP_0;
250 else if (k >= XK_0 && k <= XK_9) return k - XK_0;
251 else if (k >= XK_a && k <= XK_f) return k - XK_a + 10;
252 else if (k >= XK_A && k <= XK_F) return k - XK_A + 10;
253 }
254
255 return -1;
256}
257#endif
61 258
62/*{{{ Convert the keypress event into a string */ 259/*{{{ Convert the keypress event into a string */
63void 260void
64rxvt_term::lookup_key (XKeyEvent &ev) 261rxvt_term::lookup_key (XKeyEvent &ev)
65{ 262{
151 { 348 {
152 if (TermWin.saveLines) 349 if (TermWin.saveLines)
153 { 350 {
154#ifdef UNSHIFTED_SCROLLKEYS 351#ifdef UNSHIFTED_SCROLLKEYS
155 if (!ctrl && !meta) 352 if (!ctrl && !meta)
156 {
157#else 353#else
158 if (IS_SCROLL_MOD) 354 if (IS_SCROLL_MOD)
355#endif
159 { 356 {
160#endif
161 int lnsppg; 357 int lnsppg;
162 358
163#ifdef PAGING_CONTEXT_LINES 359#ifdef PAGING_CONTEXT_LINES
164 lnsppg = TermWin.nrow - PAGING_CONTEXT_LINES; 360 lnsppg = TermWin.nrow - PAGING_CONTEXT_LINES;
165#else 361#else
214 if (keysym >= XK_F1 && keysym <= XK_F10) 410 if (keysym >= XK_F1 && keysym <= XK_F10)
215 { 411 {
216 keysym += (XK_F11 - XK_F1); 412 keysym += (XK_F11 - XK_F1);
217 shft = 0; /* turn off Shift */ 413 shft = 0; /* turn off Shift */
218 } 414 }
219 else if (!ctrl && !meta && (PrivateModes & PrivMode_ShiftKeys)) 415 else if (!ctrl && !meta && (priv_modes & PrivMode_ShiftKeys))
220 { 416 {
221 switch (keysym) 417 switch (keysym)
222 { 418 {
223 /* normal XTerm key bindings */ 419 /* normal XTerm key bindings */
224 case XK_Insert: /* Shift+Insert = paste mouse selection */ 420 case XK_Insert: /* Shift+Insert = paste mouse selection */
225 selection_request (ev.time, 0, 0); 421 selection_request (ev.time, 0, 0);
226 return; 422 return;
423#if TODO
227 /* rxvt extras */ 424 /* rxvt extras */
228 case XK_KP_Add: /* Shift+KP_Add = bigger font */ 425 case XK_KP_Add: /* Shift+KP_Add = bigger font */
229 change_font (FONT_UP); 426 change_font (FONT_UP);
230 return; 427 return;
231 case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */ 428 case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */
232 change_font (FONT_DN); 429 change_font (FONT_DN);
233 return; 430 return;
431#endif
234 } 432 }
235 } 433 }
236 } 434 }
435
436#if ENABLE_FRILLS || ISO_14755
437 // ISO 14755 support
438 if (shft && ctrl)
439 {
440 int hv;
441
442 if (iso14755buf & ISO_14755_51
443 && (keysym == XK_space || keysym == XK_KP_Space
444 || keysym == XK_Return || keysym == XK_KP_Enter))
445 {
446 commit_iso14755 ();
447 iso14755buf = ISO_14755_51;
448# if ISO_14755
449 iso14755_51 (0);
450# endif
451 return;
452 }
453 else if ((hv = hex_keyval (ev)) >= 0)
454 {
455 iso14755buf = ((iso14755buf << 4) & ISO_14755_MASK)
456 | hv | ISO_14755_51;
457# if ISO_14755
458 iso14755_51 (iso14755buf & ISO_14755_MASK);
459# endif
460 return;
461 }
462 else
463 {
464# if ENABLE_OVERLAY
465 scr_overlay_off ();
466# endif
467 iso14755buf = 0;
468 }
469 }
470 else if ((ctrl && (keysym == XK_Shift_L || keysym == XK_Shift_R))
471 || (shft && (keysym == XK_Control_L || keysym == XK_Control_R)))
472 if (!(iso14755buf & ISO_14755_STARTED))
473 {
474 iso14755buf |= ISO_14755_STARTED;
475# if ENABLE_OVERLAY
476 scr_overlay_new (0, -1, sizeof ("ISO 14755 mode") - 1, 1);
477 scr_overlay_set (0, 0, "ISO 14755 mode");
478# endif
479 }
480#endif
481
237#ifdef PRINTPIPE 482#ifdef PRINTPIPE
238 if (keysym == XK_Print) 483 if (keysym == XK_Print)
239 { 484 {
240 scr_printscreen (ctrl | shft); 485 scr_printscreen (ctrl | shft);
241 return; 486 return;
243#endif 488#endif
244 489
245 if (keysym >= 0xFF00 && keysym <= 0xFFFF) 490 if (keysym >= 0xFF00 && keysym <= 0xFFFF)
246 { 491 {
247#ifdef KEYSYM_RESOURCE 492#ifdef KEYSYM_RESOURCE
248 if (! (shft | ctrl) && Keysym_map[keysym & 0xFF] != NULL) 493 if (!(shft | ctrl) && Keysym_map[keysym & 0xFF] != NULL)
249 { 494 {
250 unsigned int l; 495 unsigned int l;
251 const unsigned char *kbuf0; 496 const unsigned char *kbuf0;
252 497
253 kbuf0 = (Keysym_map[keysym & 0xFF]); 498 kbuf0 = (Keysym_map[keysym & 0xFF]);
273 newlen = 1; 518 newlen = 1;
274 switch (keysym) 519 switch (keysym)
275 { 520 {
276#ifndef NO_BACKSPACE_KEY 521#ifndef NO_BACKSPACE_KEY
277 case XK_BackSpace: 522 case XK_BackSpace:
278 if (PrivateModes & PrivMode_HaveBackSpace) 523 if (priv_modes & PrivMode_HaveBackSpace)
279 { 524 {
280 kbuf[0] = (!! (PrivateModes & PrivMode_BackSpace) 525 kbuf[0] = (!! (priv_modes & PrivMode_BackSpace)
281 ^ !!ctrl) ? '\b' : '\177'; 526 ^ !!ctrl) ? '\b' : '\177';
282 kbuf[1] = '\0'; 527 kbuf[1] = '\0';
283 } 528 }
284 else 529 else
285 STRCPY (kbuf, key_backspace); 530 strcpy (kbuf, key_backspace);
286 break; 531 break;
287#endif 532#endif
288#ifndef NO_DELETE_KEY 533#ifndef NO_DELETE_KEY
289 case XK_Delete: 534 case XK_Delete:
290 STRCPY (kbuf, key_delete); 535 strcpy (kbuf, key_delete);
291 break; 536 break;
292#endif 537#endif
293 case XK_Tab: 538 case XK_Tab:
294 if (shft) 539 if (shft)
295 STRCPY (kbuf, "\033[Z"); 540 strcpy (kbuf, "\033[Z");
296 else 541 else
297 { 542 {
298#ifdef CTRL_TAB_MAKES_META 543#ifdef CTRL_TAB_MAKES_META
299 if (ctrl) 544 if (ctrl)
300 meta = 1; 545 meta = 1;
306 newlen = 0; 551 newlen = 0;
307 } 552 }
308 break; 553 break;
309 554
310#ifdef XK_KP_Left 555#ifdef XK_KP_Left
311 case XK_KP_Up: /* \033Ox or standard */ 556 case XK_KP_Up: /* \033Ox or standard */
312 case XK_KP_Down: /* \033Or or standard */ 557 case XK_KP_Down: /* \033Or or standard */
313 case XK_KP_Right: /* \033Ov or standard */ 558 case XK_KP_Right: /* \033Ov or standard */
314 case XK_KP_Left: /* \033Ot or standard */ 559 case XK_KP_Left: /* \033Ot or standard */
315 if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) 560 if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
316 { 561 {
317 STRCPY (kbuf, "\033OZ"); 562 strcpy (kbuf, "\033OZ");
318 kbuf[2] = "txvr"[keysym - XK_KP_Left]; 563 kbuf[2] = "txvr"[keysym - XK_KP_Left];
319 break; 564 break;
320 } 565 }
321 else 566 else
322 /* translate to std. cursor key */ 567 /* translate to std. cursor key */
325#endif 570#endif
326 case XK_Up: /* "\033[A" */ 571 case XK_Up: /* "\033[A" */
327 case XK_Down: /* "\033[B" */ 572 case XK_Down: /* "\033[B" */
328 case XK_Right: /* "\033[C" */ 573 case XK_Right: /* "\033[C" */
329 case XK_Left: /* "\033[D" */ 574 case XK_Left: /* "\033[D" */
330 STRCPY (kbuf, "\033[Z"); 575 strcpy (kbuf, "\033[Z");
331 kbuf[2] = "DACB"[keysym - XK_Left]; 576 kbuf[2] = "DACB"[keysym - XK_Left];
332 /* do Shift first */ 577 /* do Shift first */
333 if (shft) 578 if (shft)
334 kbuf[2] = "dacb"[keysym - XK_Left]; 579 kbuf[2] = "dacb"[keysym - XK_Left];
335 else if (ctrl) 580 else if (ctrl)
336 { 581 {
337 kbuf[1] = 'O'; 582 kbuf[1] = 'O';
338 kbuf[2] = "dacb"[keysym - XK_Left]; 583 kbuf[2] = "dacb"[keysym - XK_Left];
339 } 584 }
340 else if (PrivateModes & PrivMode_aplCUR) 585 else if (priv_modes & PrivMode_aplCUR)
341 kbuf[1] = 'O'; 586 kbuf[1] = 'O';
342 break; 587 break;
343 588
344#ifndef UNSHIFTED_SCROLLKEYS 589#ifndef UNSHIFTED_SCROLLKEYS
345# ifdef XK_KP_Prior 590# ifdef XK_KP_Prior
346 case XK_KP_Prior: 591 case XK_KP_Prior:
347 /* allow shift to override */ 592 /* allow shift to override */
348 if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) 593 if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
349 { 594 {
350 STRCPY (kbuf, "\033Oy"); 595 strcpy (kbuf, "\033Oy");
351 break; 596 break;
352 } 597 }
353 /* FALLTHROUGH */ 598 /* FALLTHROUGH */
354# endif 599# endif
355 case XK_Prior: 600 case XK_Prior:
356 STRCPY (kbuf, "\033[5~"); 601 strcpy (kbuf, "\033[5~");
357 break; 602 break;
358# ifdef XK_KP_Next 603# ifdef XK_KP_Next
359 case XK_KP_Next: 604 case XK_KP_Next:
360 /* allow shift to override */ 605 /* allow shift to override */
361 if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) 606 if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
362 { 607 {
363 STRCPY (kbuf, "\033Os"); 608 strcpy (kbuf, "\033Os");
364 break; 609 break;
365 } 610 }
366 /* FALLTHROUGH */ 611 /* FALLTHROUGH */
367# endif 612# endif
368 case XK_Next: 613 case XK_Next:
369 STRCPY (kbuf, "\033[6~"); 614 strcpy (kbuf, "\033[6~");
370 break; 615 break;
371#endif 616#endif
372 case XK_KP_Enter: 617 case XK_KP_Enter:
373 /* allow shift to override */ 618 /* allow shift to override */
374 if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) 619 if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
375 { 620 {
376 STRCPY (kbuf, "\033OM"); 621 strcpy (kbuf, "\033OM");
622 break;
623 }
624
625 /* FALLTHROUGH */
626
627 case XK_Return:
628 if (priv_modes & PrivMode_LFNL)
629 {
630 kbuf[0] = '\015';
631 kbuf[1] = '\012';
632 kbuf[2] = '\0';
377 } 633 }
378 else 634 else
379 { 635 {
380 kbuf[0] = '\r'; 636 kbuf[0] = '\015';
381 kbuf[1] = '\0'; 637 kbuf[1] = '\0';
382 } 638 }
383 break; 639 break;
384 640
385#ifdef XK_KP_Begin 641#ifdef XK_KP_Begin
386 case XK_KP_Begin: 642 case XK_KP_Begin:
387 STRCPY (kbuf, "\033Ou"); 643 strcpy (kbuf, "\033Ou");
388 break; 644 break;
389 645
390 case XK_KP_Insert: 646 case XK_KP_Insert:
391 STRCPY (kbuf, "\033Op"); 647 strcpy (kbuf, "\033Op");
392 break; 648 break;
393 649
394 case XK_KP_Delete: 650 case XK_KP_Delete:
395 STRCPY (kbuf, "\033On"); 651 strcpy (kbuf, "\033On");
396 break; 652 break;
397#endif 653#endif
398 case XK_KP_F1: /* "\033OP" */ 654 case XK_KP_F1: /* "\033OP" */
399 case XK_KP_F2: /* "\033OQ" */ 655 case XK_KP_F2: /* "\033OQ" */
400 case XK_KP_F3: /* "\033OR" */ 656 case XK_KP_F3: /* "\033OR" */
401 case XK_KP_F4: /* "\033OS" */ 657 case XK_KP_F4: /* "\033OS" */
402 STRCPY (kbuf, "\033OP"); 658 strcpy (kbuf, "\033OP");
403 kbuf[2] += (keysym - XK_KP_F1); 659 kbuf[2] += (keysym - XK_KP_F1);
404 break; 660 break;
405 661
406 case XK_KP_Multiply: /* "\033Oj" : "*" */ 662 case XK_KP_Multiply: /* "\033Oj" : "*" */
407 case XK_KP_Add: /* "\033Ok" : "+" */ 663 case XK_KP_Add: /* "\033Ok" : "+" */
418 case XK_KP_6: /* "\033Ov" : "6" */ 674 case XK_KP_6: /* "\033Ov" : "6" */
419 case XK_KP_7: /* "\033Ow" : "7" */ 675 case XK_KP_7: /* "\033Ow" : "7" */
420 case XK_KP_8: /* "\033Ox" : "8" */ 676 case XK_KP_8: /* "\033Ox" : "8" */
421 case XK_KP_9: /* "\033Oy" : "9" */ 677 case XK_KP_9: /* "\033Oy" : "9" */
422 /* allow shift to override */ 678 /* allow shift to override */
423 if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) 679 if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
424 { 680 {
425 STRCPY (kbuf, "\033Oj"); 681 strcpy (kbuf, "\033Oj");
426 kbuf[2] += (keysym - XK_KP_Multiply); 682 kbuf[2] += (keysym - XK_KP_Multiply);
427 } 683 }
428 else 684 else
429 { 685 {
430 kbuf[0] = ('*' + (keysym - XK_KP_Multiply)); 686 kbuf[0] = ('*' + (keysym - XK_KP_Multiply));
431 kbuf[1] = '\0'; 687 kbuf[1] = '\0';
432 } 688 }
433 break; 689 break;
434 690
435 case XK_Find: 691 case XK_Find:
436 STRCPY (kbuf, "\033[1~"); 692 strcpy (kbuf, "\033[1~");
437 break; 693 break;
438 case XK_Insert: 694 case XK_Insert:
439 STRCPY (kbuf, "\033[2~"); 695 strcpy (kbuf, "\033[2~");
440 break; 696 break;
441#ifdef DXK_Remove /* support for DEC remove like key */ 697#ifdef DXK_Remove /* support for DEC remove like key */
442 case DXK_Remove: 698 case DXK_Remove:
443 /* FALLTHROUGH */ 699 /* FALLTHROUGH */
444#endif 700#endif
445 case XK_Execute: 701 case XK_Execute:
446 STRCPY (kbuf, "\033[3~"); 702 strcpy (kbuf, "\033[3~");
447 break; 703 break;
448 case XK_Select: 704 case XK_Select:
449 STRCPY (kbuf, "\033[4~"); 705 strcpy (kbuf, "\033[4~");
450 break; 706 break;
451#ifdef XK_KP_End 707#ifdef XK_KP_End
452 case XK_KP_End: 708 case XK_KP_End:
453 /* allow shift to override */ 709 /* allow shift to override */
454 if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) 710 if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
455 { 711 {
456 STRCPY (kbuf, "\033Oq"); 712 strcpy (kbuf, "\033Oq");
457 break; 713 break;
458 } 714 }
459 /* FALLTHROUGH */ 715 /* FALLTHROUGH */
460#endif 716#endif
461 case XK_End: 717 case XK_End:
462 STRCPY (kbuf, KS_END); 718 strcpy (kbuf, KS_END);
463 break; 719 break;
464#ifdef XK_KP_Home 720#ifdef XK_KP_Home
465 case XK_KP_Home: 721 case XK_KP_Home:
466 /* allow shift to override */ 722 /* allow shift to override */
467 if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) 723 if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
468 { 724 {
469 STRCPY (kbuf, "\033Ow"); 725 strcpy (kbuf, "\033Ow");
470 break; 726 break;
471 } 727 }
472 /* FALLTHROUGH */ 728 /* FALLTHROUGH */
473#endif 729#endif
474 case XK_Home: 730 case XK_Home:
475 STRCPY (kbuf, KS_HOME); 731 strcpy (kbuf, KS_HOME);
476 break; 732 break;
477 733
478#define FKEY(n, fkey) \ 734#define FKEY(n, fkey) \
479 sprintf ((char *)kbuf,"\033[%2d~", (int) ((n) + (keysym - fkey))) 735 sprintf ((char *)kbuf,"\033[%2d~", (int) ((n) + (keysym - fkey)))
480 736
529 case XK_F35: /* "\033[49~" */ 785 case XK_F35: /* "\033[49~" */
530 FKEY (31, XK_F17); 786 FKEY (31, XK_F17);
531 break; 787 break;
532#undef FKEY 788#undef FKEY
533 default: 789 default:
534 newlen = 0; 790 if (len == 0
535 break; 791 && (keysym & 0xfff0) != 0xff70
792 && (keysym & 0xfff0) != 0xffe0)
793 /* generate a keycode for every remaining keypress */
794 sprintf ((char *)kbuf, "\033[%x;%xA", (unsigned char)ev.state, (unsigned short)keysym);
536 } 795 }
796
537 if (newlen) 797 if (newlen)
538 len = STRLEN (kbuf); 798 len = strlen (kbuf);
539 } 799 }
540 800
541 /* 801 /*
542 * Pass meta for all function keys, if 'meta' option set 802 * Pass meta for all function keys, if 'meta' option set
543 */ 803 */
550 else if (ctrl && keysym == XK_minus) 810 else if (ctrl && keysym == XK_minus)
551 { 811 {
552 len = 1; 812 len = 1;
553 kbuf[0] = '\037'; /* Ctrl-Minus generates ^_ (31) */ 813 kbuf[0] = '\037'; /* Ctrl-Minus generates ^_ (31) */
554 } 814 }
815 else if (keysym == XK_ISO_Left_Tab)
816 {
817 strcpy (kbuf, "\033[Z");
818 len = 3;
819 }
820 else if (len == 0
821 && (keysym & 0xffe0) != 0xfe00
822 && (keysym < 0xfe50 || keysym > 0xfe6f))
823 {
824 /* generate a keycode for every remaining keypress */
825 len = sprintf ((char *)kbuf, "\033[%x;%xA", (unsigned char)ev.state, (unsigned short)keysym);
826 }
555 else 827 else
556 { 828 {
557#ifdef META8_OPTION 829#ifdef META8_OPTION
558 /* set 8-bit on */ 830 /* set 8-bit on */
559 if (meta && (meta_char == 0x80)) 831 if (meta && (meta_char == 0x80))
571 } 843 }
572 844
573 if (len <= 0) 845 if (len <= 0)
574 return; /* not mapped */ 846 return; /* not mapped */
575 847
576 if (Options & Opt_scrollTtyKeypress) 848 if (options & Opt_scrollTtyKeypress)
577 if (TermWin.view_start) 849 if (TermWin.view_start)
578 { 850 {
579 TermWin.view_start = 0; 851 TermWin.view_start = 0;
580 want_refresh = 1; 852 want_refresh = 1;
581 } 853 }
630 n = cmdbuf_ptr - cmdbuf_base; 902 n = cmdbuf_ptr - cmdbuf_base;
631 s = cmdbuf_base + CBUFSIZ - 1 - cmdbuf_endp; 903 s = cmdbuf_base + CBUFSIZ - 1 - cmdbuf_endp;
632 904
633 if (n > 0 && s < count) 905 if (n > 0 && s < count)
634 { 906 {
635 MEMMOVE (cmdbuf_base, cmdbuf_ptr, 907 memmove (cmdbuf_base, cmdbuf_ptr,
636 (unsigned int) (cmdbuf_endp - cmdbuf_ptr)); 908 (unsigned int) (cmdbuf_endp - cmdbuf_ptr));
637 cmdbuf_ptr = cmdbuf_base; 909 cmdbuf_ptr = cmdbuf_base;
638 cmdbuf_endp -= n; 910 cmdbuf_endp -= n;
639 s += n; 911 s += n;
640 } 912 }
655#endif /* MENUBAR_MAX */ 927#endif /* MENUBAR_MAX */
656 928
657void 929void
658rxvt_term::flush () 930rxvt_term::flush ()
659{ 931{
932 flush_ev.stop ();
933
660#ifdef TRANSPARENT 934#ifdef TRANSPARENT
661 if (want_full_refresh) 935 if (want_full_refresh)
662 { 936 {
663 want_full_refresh = 0; 937 want_full_refresh = 0;
664 scr_clear (); 938 scr_clear ();
665 scr_touch (false); 939 scr_touch (false);
666 want_refresh = 1;
667 } 940 }
668#endif 941#endif
669 942
670 if (want_refresh) 943 if (want_refresh)
671 { 944 {
683rxvt_term::check_cb (check_watcher &w) 956rxvt_term::check_cb (check_watcher &w)
684{ 957{
685 SET_R (this); 958 SET_R (this);
686 SET_LOCALE (locale); 959 SET_LOCALE (locale);
687 960
961 display->flush ();
962
963 if (want_refresh && !flush_ev.active)
964 flush_ev.start (NOW + 0.01);
965}
966
967void
968rxvt_term::flush_cb (time_watcher &w)
969{
970 SET_R (this);
971 SET_LOCALE (locale);
972
973 refresh_limit = 1;
974 refresh_count = 0;
688 flush (); 975 flush ();
689} 976}
690 977
691#ifdef CURSOR_BLINK 978#ifdef CURSOR_BLINK
692void 979void
768 1055
769 memmove (cmdbuf_base, cmdbuf_ptr, n); 1056 memmove (cmdbuf_base, cmdbuf_ptr, n);
770 cmdbuf_ptr = cmdbuf_base; 1057 cmdbuf_ptr = cmdbuf_base;
771 cmdbuf_endp = cmdbuf_ptr + n; 1058 cmdbuf_endp = cmdbuf_ptr + n;
772 1059
773 n = read (cmd_fd, cmdbuf_endp, CBUFSIZ - n); 1060 n = read (pty.pty, cmdbuf_endp, CBUFSIZ - n);
774 1061
775 if (n > 0) 1062 if (n > 0)
776 { 1063 {
777 cmdbuf_endp += n; 1064 cmdbuf_endp += n;
778 return true; 1065 return true;
787rxvt_term::pty_cb (io_watcher &w, short revents) 1074rxvt_term::pty_cb (io_watcher &w, short revents)
788{ 1075{
789 SET_R (this); 1076 SET_R (this);
790 SET_LOCALE (locale); 1077 SET_LOCALE (locale);
791 1078
792 if (revents & EVENT_WRITE)
793 tt_write (0, 0);
794 else if (revents & EVENT_READ) 1079 if (revents & EVENT_READ)
795 // loop, but don't allow a single term to monopolize us 1080 // loop, but don't allow a single term to monopolize us
796 while (pty_fill ()) 1081 while (pty_fill ())
797 if (cmd_parse ()) 1082 if (cmd_parse ())
798 break; 1083 break;
1084
1085 if (revents & EVENT_WRITE)
1086 pty_write ();
1087}
1088
1089void
1090rxvt_term::pointer_unblank ()
1091{
1092 XDefineCursor (display->display, TermWin.vt, TermWin_cursor);
1093 recolour_cursor ();
1094
1095#ifdef POINTER_BLANK
1096 hidden_pointer = 0;
1097
1098 if (options & Opt_pointerBlank)
1099 pointer_ev.start (NOW + pointerBlankDelay);
1100#endif
799} 1101}
800 1102
801#ifdef POINTER_BLANK 1103#ifdef POINTER_BLANK
802void 1104void
803rxvt_term::pointer_unblank ()
804{
805 XDefineCursor (display->display, TermWin.vt, TermWin_cursor);
806 recolour_cursor ();
807
808 hidden_pointer = 0;
809
810 if (Options & Opt_pointerBlank)
811 pointer_ev.start (NOW + pointerBlankDelay);
812}
813
814void
815rxvt_term::pointer_blank () 1105rxvt_term::pointer_blank ()
816{ 1106{
817 if (! (Options & Opt_pointerBlank)) 1107 if (! (options & Opt_pointerBlank))
818 return; 1108 return;
819 1109
820 XDefineCursor (display->display, TermWin.vt, blank_cursor); 1110 XDefineCursor (display->display, TermWin.vt, blank_cursor);
821 XFlush (display->display); 1111 XFlush (display->display);
822 1112
842 x = ev.x; 1132 x = ev.x;
843 y = ev.y; 1133 y = ev.y;
844 pixel_position (&x, &y); 1134 pixel_position (&x, &y);
845 1135
846 if (MEvent.button == AnyButton) 1136 if (MEvent.button == AnyButton)
847 {
848 button_number = 3; 1137 button_number = 3;
849 }
850 else 1138 else
851 { 1139 {
852 button_number = MEvent.button - Button1; 1140 button_number = MEvent.button - Button1;
853 /* add 0x3D for wheel events, like xterm does */ 1141 /* add 0x3D for wheel events, like xterm does */
854 if (button_number >= 3) 1142 if (button_number >= 3)
855 button_number += (64 - 3); 1143 button_number += (64 - 3);
856 } 1144 }
857 1145
858 if (PrivateModes & PrivMode_MouseX10) 1146 if (priv_modes & PrivMode_MouseX10)
859 { 1147 {
860 /* 1148 /*
861 * do not report ButtonRelease 1149 * do not report ButtonRelease
862 * no state info allowed 1150 * no state info allowed
863 */ 1151 */
878 + ((MEvent.state & ModMetaMask) ? 8 : 0) 1166 + ((MEvent.state & ModMetaMask) ? 8 : 0)
879 + ((MEvent.state & ControlMask) ? 16 : 0); 1167 + ((MEvent.state & ControlMask) ? 16 : 0);
880#ifdef MOUSE_REPORT_DOUBLECLICK 1168#ifdef MOUSE_REPORT_DOUBLECLICK
881 key_state += ((MEvent.clicks > 1) ? 32 : 0); 1169 key_state += ((MEvent.clicks > 1) ? 32 : 0);
882#endif 1170#endif
883
884 } 1171 }
885 1172
886#ifdef DEBUG_MOUSEREPORT 1173#if DEBUG_MOUSEREPORT
887 fprintf (stderr, "Mouse ["); 1174 fprintf (stderr, "Mouse [");
888 if (key_state & 16) 1175 if (key_state & 16)
889 fputc ('C', stderr); 1176 fputc ('C', stderr);
890 if (key_state & 4) 1177 if (key_state & 4)
891 fputc ('S', stderr); 1178 fputc ('S', stderr);
895 fputc ('2', stderr); 1182 fputc ('2', stderr);
896 fprintf (stderr, "]: <%d>, %d/%d\n", 1183 fprintf (stderr, "]: <%d>, %d/%d\n",
897 button_number, 1184 button_number,
898 x + 1, 1185 x + 1,
899 y + 1); 1186 y + 1);
900#else 1187#endif
1188
901 tt_printf ("\033[M%c%c%c", 1189 tt_printf ("\033[M%c%c%c",
902 (32 + button_number + key_state), 1190 (32 + button_number + key_state),
903 (32 + x + 1), 1191 (32 + x + 1),
904 (32 + y + 1)); 1192 (32 + y + 1));
905#endif
906} 1193}
907 1194
908#ifdef USING_W11LIB 1195#ifdef USING_W11LIB
909void 1196void
910rxvt_W11_process_x_event (XEvent *ev) 1197rxvt_W11_process_x_event (XEvent *ev)
921{ 1208{
922 SET_R (this); 1209 SET_R (this);
923 SET_LOCALE (locale); 1210 SET_LOCALE (locale);
924 1211
925#if defined(CURSOR_BLINK) 1212#if defined(CURSOR_BLINK)
926 if ((Options & Opt_cursorBlink) && ev.type == KeyPress) 1213 if ((options & Opt_cursorBlink) && ev.type == KeyPress)
927 { 1214 {
928 if (hidden_cursor) 1215 if (hidden_cursor)
929 { 1216 {
930 hidden_cursor = 0; 1217 hidden_cursor = 0;
931 want_refresh = 1; 1218 want_refresh = 1;
934 cursor_blink_ev.start (NOW + BLINK_INTERVAL); 1221 cursor_blink_ev.start (NOW + BLINK_INTERVAL);
935 } 1222 }
936#endif 1223#endif
937 1224
938#if defined(POINTER_BLANK) 1225#if defined(POINTER_BLANK)
939 if ((Options & Opt_pointerBlank) && pointerBlankDelay > 0) 1226 if ((options & Opt_pointerBlank) && pointerBlankDelay > 0)
940 { 1227 {
941 if (ev.type == MotionNotify 1228 if (ev.type == MotionNotify
942 || ev.type == ButtonPress 1229 || ev.type == ButtonPress
943 || ev.type == ButtonRelease) 1230 || ev.type == ButtonRelease)
944 if (hidden_pointer) 1231 if (hidden_pointer)
947 if (ev.type == KeyPress && hidden_pointer == 0) 1234 if (ev.type == KeyPress && hidden_pointer == 0)
948 pointer_blank (); 1235 pointer_blank ();
949 } 1236 }
950#endif 1237#endif
951 1238
952#ifdef USE_XIM
953 if (XFilterEvent (&ev, None))
954 return;
955#endif
956
957 Window unused_root, unused_child; 1239 Window unused_root, unused_child;
958 int unused_root_x, unused_root_y; 1240 int unused_root_x, unused_root_y;
959 unsigned int unused_mask; 1241 unsigned int unused_mask;
960
961#ifdef DEBUG_X
962 const char *const eventnames[] =
963 { /* mason - this matches my system */
964 "",
965 "",
966 "KeyPress",
967 "KeyRelease",
968 "ButtonPress",
969 "ButtonRelease",
970 "MotionNotify",
971 "EnterNotify",
972 "LeaveNotify",
973 "FocusIn",
974 "FocusOut",
975 "KeymapNotify",
976 "Expose",
977 "GraphicsExpose",
978 "NoExpose",
979 "VisibilityNotify",
980 "CreateNotify",
981 "DestroyNotify",
982 "UnmapNotify",
983 "MapNotify",
984 "MapRequest",
985 "ReparentNotify",
986 "ConfigureNotify",
987 "ConfigureRequest",
988 "GravityNotify",
989 "ResizeRequest",
990 "CirculateNotify",
991 "CirculateRequest",
992 "PropertyNotify",
993 "SelectionClear",
994 "SelectionRequest",
995 "SelectionNotify",
996 "ColormapNotify",
997 "ClientMessage",
998 "MappingNotify"
999 };
1000#endif
1001
1002#ifdef DEBUG_X
1003 struct timeval tp;
1004 struct tm *ltt;
1005 (void)gettimeofday (&tp, NULL);
1006 ltt = localtime (& (tp.tv_sec));
1007 D_X ((stderr, "Event: %-16s %-7s %08lx (%4d-%02d-%02d %02d:%02d:%02d.%.6ld) %s %lu", eventnames[ev.type], (ev.xany.window == TermWin.parent[0] ? "parent" : (ev.xany.window == TermWin.vt ? "vt" : (ev.xany.window == scrollBar.win ? "scroll" : (ev.xany.window == menuBar.win ? "menubar" : "UNKNOWN")))), (ev.xany.window == TermWin.parent[0] ? TermWin.parent[0] : (ev.xany.window == TermWin.vt ? TermWin.vt : (ev.xany.window == scrollBar.win ? scrollBar.win : (ev.xany.window == menuBar.win ? menuBar.win : 0)))), ltt->tm_year + 1900, ltt->tm_mon + 1, ltt->tm_mday, ltt->tm_hour, ltt->tm_min, ltt->tm_sec, tp.tv_usec, ev.xany.send_event ? "S" : " ", ev.xany.serial));
1008#endif
1009 1242
1010 switch (ev.type) 1243 switch (ev.type)
1011 { 1244 {
1012 case KeyPress: 1245 case KeyPress:
1246#if ISO_14755
1247 if (!(iso14755buf & ISO_14755_52))
1248#endif
1013 lookup_key (ev.xkey); 1249 lookup_key (ev.xkey);
1250
1251 break;
1252
1253 case KeyRelease:
1254 {
1255#if (MOUSE_WHEEL && MOUSE_SLIP_WHEELING) || ISO_14755
1256 KeySym ks;
1257
1258 ks = XLookupKeysym (&ev.xkey, ev.xkey.state & ShiftMask ? 1 : 0); // sorry, only shift supported :/
1259#endif
1260
1261#if ENABLE_FRILLS || ISO_14755
1262 // ISO 14755 support
1263 if (iso14755buf)
1264 if (iso14755buf & ISO_14755_52)
1265 {
1266# if ENABLE_OVERLAY
1267 scr_overlay_off ();
1268# endif
1269# if ISO_14755
1270 // iso14755 part 5.2 handling: release time
1271 // first: controls
1272 if ((ev.xkey.state & ControlMask)
1273 && ((ks >= 0x40 && ks <= 0x5f)
1274 || (ks >= 0x61 && ks <= 0x7f)))
1275 {
1276 iso14755buf = ISO_14755_51 | 0x2400 | (ks & 0x1f);
1277 commit_iso14755 ();
1278 return; // case-break;
1279 }
1280
1281 for (unsigned short *i = iso14755_symtab; i[0]; i+= 2)
1282 if (i[0] == ks)
1283 {
1284 iso14755buf = ISO_14755_51 | i[1];
1285 commit_iso14755 ();
1286 return; // case-break;
1287 }
1288
1289 scr_bell ();
1290# endif
1291 iso14755buf = 0;
1014 break; 1292 break;
1293 }
1294 else if ((ev.xkey.state & (ShiftMask | ControlMask)) != (ShiftMask | ControlMask))
1295 {
1296# if ENABLE_OVERLAY
1297 scr_overlay_off ();
1298# endif
1299 if (iso14755buf & ISO_14755_51)
1300 commit_iso14755 ();
1301#if ISO_14755
1302 else if (iso14755buf & ISO_14755_STARTED)
1303 {
1304 iso14755buf = ISO_14755_52; // iso14755 part 5.2: remember empty begin/end pair
1305
1306 scr_overlay_new (0, -1, sizeof ("KEYCAP PICTURE INSERT MODE") - 1, 1);
1307 scr_overlay_set (0, 0, "KEYCAP PICTURE INSERT MODE");
1308 }
1309# endif
1310 else
1311 iso14755buf = 0;
1312 }
1313#endif
1015 1314
1016#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING) 1315#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING)
1017 case KeyRelease:
1018 {
1019 if (!(ev.xkey.state & ControlMask)) 1316 if (!(ev.xkey.state & ControlMask))
1020 slip_wheel_ev.stop (); 1317 slip_wheel_ev.stop ();
1021 else
1022 {
1023 KeySym ks;
1024
1025 ks = XKeycodeToKeysym (display->display, ev.xkey.keycode, 0);
1026 if (ks == XK_Control_L || ks == XK_Control_R) 1318 else if (ks == XK_Control_L || ks == XK_Control_R)
1027 mouse_slip_wheel_speed = 0; 1319 mouse_slip_wheel_speed = 0;
1028 } 1320#endif
1029 break; 1321 break;
1030 } 1322 }
1031#endif
1032 1323
1033 case ButtonPress: 1324 case ButtonPress:
1034 button_press (ev.xbutton); 1325 button_press (ev.xbutton);
1035 break; 1326 break;
1036 1327
1060 0L, 1000000L, 1351 0L, 1000000L,
1061 False, AnyPropertyType, 1352 False, AnyPropertyType,
1062 &ActualType, &ActualFormat, 1353 &ActualType, &ActualFormat,
1063 &Size, &RemainingBytes, 1354 &Size, &RemainingBytes,
1064 &data); 1355 &data);
1065 XChangeProperty (display->display, display->root, 1356 set_string_property (XA_CUT_BUFFER0, data);
1066 XA_CUT_BUFFER0, XA_STRING,
1067 8, PropModeReplace,
1068 data, STRLEN (data));
1069 XFree (data); 1357 XFree (data);
1070 selection_paste (display->root, XA_CUT_BUFFER0, True); 1358 selection_paste (display->root, XA_CUT_BUFFER0, true);
1071 XSetInputFocus (display->display, display->root, RevertToNone, CurrentTime); 1359 XSetInputFocus (display->display, display->root, RevertToNone, CurrentTime);
1072 } 1360 }
1073#endif /* OFFIX_DND */ 1361#endif /* OFFIX_DND */
1074 break; 1362 break;
1075 1363
1076 case MappingNotify: 1364 case MappingNotify:
1077 XRefreshKeyboardMapping (& (ev.xmapping)); 1365 XRefreshKeyboardMapping (&ev.xmapping);
1078 break; 1366 break;
1079 1367
1080 /* 1368 /*
1081 * XXX: this is not the _current_ arrangement 1369 * XXX: this is not the _current_ arrangement
1082 * Here's my conclusion: 1370 * Here's my conclusion:
1107 { 1395 {
1108 TermWin.focus = 1; 1396 TermWin.focus = 1;
1109 want_refresh = 1; 1397 want_refresh = 1;
1110#ifdef USE_XIM 1398#ifdef USE_XIM
1111 if (Input_Context != NULL) 1399 if (Input_Context != NULL)
1400 {
1401 IMSetStatusPosition ();
1112 XSetICFocus (Input_Context); 1402 XSetICFocus (Input_Context);
1403 }
1113#endif 1404#endif
1114#ifdef CURSOR_BLINK 1405#ifdef CURSOR_BLINK
1115 if (Options & Opt_cursorBlink) 1406 if (options & Opt_cursorBlink)
1116 cursor_blink_ev.start (NOW + BLINK_INTERVAL); 1407 cursor_blink_ev.start (NOW + BLINK_INTERVAL);
1408#endif
1409#ifdef OFF_FOCUS_FADING
1410 if (rs[Rs_fade])
1411 {
1412 pix_colors = pix_colors_focused;
1413 scr_recolour ();
1414 }
1117#endif 1415#endif
1118 1416
1119 } 1417 }
1120 break; 1418 break;
1121 1419
1122 case FocusOut: 1420 case FocusOut:
1123 if (TermWin.focus) 1421 if (TermWin.focus)
1124 { 1422 {
1125 TermWin.focus = 0; 1423 TermWin.focus = 0;
1126 want_refresh = 1; 1424 want_refresh = 1;
1425
1426#if ENABLE_FRILLS || ISO_14755
1427 iso14755buf = 0;
1428#endif
1429#if ENABLE_OVERLAY
1430 scr_overlay_off ();
1431#endif
1127#ifdef USE_XIM 1432#ifdef USE_XIM
1128 if (Input_Context != NULL) 1433 if (Input_Context != NULL)
1129 XUnsetICFocus (Input_Context); 1434 XUnsetICFocus (Input_Context);
1130#endif 1435#endif
1131#ifdef CURSOR_BLINK 1436#ifdef CURSOR_BLINK
1132 if (Options & Opt_cursorBlink) 1437 if (options & Opt_cursorBlink)
1133 cursor_blink_ev.stop (); 1438 cursor_blink_ev.stop ();
1134 hidden_cursor = 0; 1439 hidden_cursor = 0;
1135#endif 1440#endif
1136 1441#ifdef OFF_FOCUS_FADING
1442 if (rs[Rs_fade])
1443 {
1444 pix_colors = pix_colors_unfocused;
1445 scr_recolour ();
1446 }
1447#endif
1137 } 1448 }
1138 break; 1449 break;
1139 1450
1140 case ConfigureNotify: 1451 case ConfigureNotify:
1141 if (ev.xconfigure.window == TermWin.parent[0]) 1452 if (ev.xconfigure.window == TermWin.parent[0])
1150 } 1461 }
1151 while (XCheckTypedWindowEvent (display->display, ev.xconfigure.window, ConfigureNotify, &ev)); 1462 while (XCheckTypedWindowEvent (display->display, ev.xconfigure.window, ConfigureNotify, &ev));
1152 1463
1153 if (szHint.width != width || szHint.height != height) 1464 if (szHint.width != width || szHint.height != height)
1154 { 1465 {
1155 D_SIZE ((stderr, "Size: Resizing from: %4d x %4d", szHint.width, szHint.height)); 1466 seen_resize = 1;
1156 resize_all_windows (width, height, 1); 1467 resize_all_windows (width, height, 1);
1157 } 1468 }
1158#ifdef DEBUG_SIZE 1469
1159 else
1160 {
1161 D_SIZE ((stderr, "Size: Not resizing"));
1162 }
1163#endif
1164#ifdef TRANSPARENT /* XXX: maybe not needed - leave in for now */ 1470#ifdef TRANSPARENT /* XXX: maybe not needed - leave in for now */
1165 if (Options & Opt_transparent) 1471 if (options & Opt_transparent)
1166 {
1167 check_our_parents (); 1472 check_our_parents ();
1168 if (am_transparent)
1169 want_full_refresh = 1;
1170 }
1171#endif 1473#endif
1172 } 1474 }
1475 break;
1476
1477 case PropertyNotify:
1478 if (ev.xproperty.atom == xa[XA_VT_SELECTION]
1479 && ev.xproperty.state == PropertyNewValue)
1480 selection_property (ev.xproperty.window, ev.xproperty.atom);
1481
1173 break; 1482 break;
1174 1483
1175 case SelectionClear: 1484 case SelectionClear:
1176 selection_clear (); 1485 selection_clear ();
1177 break; 1486 break;
1178 1487
1179 case SelectionNotify: 1488 case SelectionNotify:
1180 if (selection_wait == Sel_normal) 1489 if (selection_wait == Sel_normal)
1181 selection_paste (ev.xselection.requestor, 1490 selection_paste (ev.xselection.requestor, ev.xselection.property, true);
1182 ev.xselection.property, True);
1183 break; 1491 break;
1184 1492
1185 case SelectionRequest: 1493 case SelectionRequest:
1186 selection_send (ev.xselectionrequest); 1494 selection_send (ev.xselectionrequest);
1187 break; 1495 break;
1208 1516
1209 case GraphicsExpose: 1517 case GraphicsExpose:
1210 case Expose: 1518 case Expose:
1211 if (ev.xany.window == TermWin.vt) 1519 if (ev.xany.window == TermWin.vt)
1212 { 1520 {
1213#ifdef NO_SLOW_LINK_SUPPORT 1521 do
1214 scr_expose (ev.xexpose.x, ev.xexpose.y, 1522 scr_expose (ev.xexpose.x, ev.xexpose.y,
1215 ev.xexpose.width, ev.xexpose.height, False); 1523 ev.xexpose.width, ev.xexpose.height, False);
1216#else 1524 while (XCheckTypedWindowEvent (display->display, TermWin.vt, ev.xany.type, &ev));
1217 // I don't understand this, so I changed it :) 1525
1526 ev.xany.type = ev.xany.type == Expose ? GraphicsExpose : Expose;
1527
1528 while (XCheckTypedWindowEvent (display->display, TermWin.vt, ev.xany.type, &ev))
1218 scr_expose (ev.xexpose.x, ev.xexpose.y, 1529 scr_expose (ev.xexpose.x, ev.xexpose.y,
1219 ev.xexpose.width, ev.xexpose.height, False); 1530 ev.xexpose.width, ev.xexpose.height, False);
1220 //scr_expose (ev.xexpose.x, 0, 1531
1221 // ev.xexpose.width, TermWin.height, False); 1532 scr_refresh (refresh_type);
1222#endif
1223 want_refresh = 1;
1224 } 1533 }
1225 else 1534 else
1226 { 1535 {
1227 XEvent unused_event; 1536 XEvent unused_event;
1228 1537
1238 } 1547 }
1239#ifdef MENUBAR 1548#ifdef MENUBAR
1240 if (menubar_visible () && isMenuBarWindow (ev.xany.window)) 1549 if (menubar_visible () && isMenuBarWindow (ev.xany.window))
1241 menubar_expose (); 1550 menubar_expose ();
1242#endif 1551#endif
1552
1553#ifdef TRANSPARENT
1554 if (am_transparent && ev.xany.window == TermWin.parent[0])
1555 XClearWindow (display->display, ev.xany.window);
1556#endif
1243 } 1557 }
1244 break; 1558 break;
1245 1559
1246 case MotionNotify: 1560 case MotionNotify:
1247#ifdef POINTER_BLANK 1561#ifdef POINTER_BLANK
1253 { 1567 {
1254 menubar_control (ev.xbutton); 1568 menubar_control (ev.xbutton);
1255 break; 1569 break;
1256 } 1570 }
1257#endif 1571#endif
1258 if ((PrivateModes & PrivMode_mouse_report) && ! (bypass_keystate)) 1572 if ((priv_modes & PrivMode_mouse_report) && !bypass_keystate)
1259 break; 1573 break;
1260 1574
1261 if (ev.xany.window == TermWin.vt) 1575 if (ev.xany.window == TermWin.vt)
1262 { 1576 {
1263 if ((ev.xbutton.state & (Button1Mask | Button3Mask))) 1577 if (ev.xbutton.state & (Button1Mask | Button3Mask))
1264 { 1578 {
1265 while (XCheckTypedWindowEvent (display->display, TermWin.vt, MotionNotify, &ev)) 1579 while (XCheckTypedWindowEvent (display->display, TermWin.vt, MotionNotify, &ev))
1266 ; 1580 ;
1267 1581
1268 XQueryPointer (display->display, TermWin.vt, 1582 XQueryPointer (display->display, TermWin.vt,
1269 &unused_root, &unused_child, 1583 &unused_root, &unused_child,
1270 &unused_root_x, &unused_root_y, 1584 &unused_root_x, &unused_root_y,
1271 & (ev.xbutton.x), & (ev.xbutton.y), 1585 &ev.xbutton.x, &ev.xbutton.y,
1272 &unused_mask); 1586 &ev.xbutton.state);
1273#ifdef MOUSE_THRESHOLD 1587#ifdef MOUSE_THRESHOLD
1274 /* deal with a `jumpy' mouse */ 1588 /* deal with a `jumpy' mouse */
1275 if ((ev.xmotion.time - MEvent.time) > MOUSE_THRESHOLD) 1589 if ((ev.xmotion.time - MEvent.time) > MOUSE_THRESHOLD)
1276 { 1590 {
1277#endif 1591#endif
1592#if ISO_14755
1593 // 5.4
1594 if (iso14755buf & (ISO_14755_STARTED | ISO_14755_54))
1595 {
1596 iso14755_54 (ev.xbutton.x, ev.xbutton.y);
1597 break;
1598 }
1599#endif
1278 selection_extend ((ev.xbutton.x), (ev.xbutton.y), 1600 selection_extend (ev.xbutton.x, ev.xbutton.y,
1279 (ev.xbutton.state & Button3Mask) ? 2 : 0); 1601 ev.xbutton.state & Button3Mask ? 2 : 0);
1602
1280#ifdef SELECTION_SCROLLING 1603#ifdef SELECTION_SCROLLING
1281 if (ev.xbutton.y < TermWin.int_bwidth 1604 if (ev.xbutton.y < TermWin.int_bwidth
1282 || Pixel2Row (ev.xbutton.y) > (TermWin.nrow-1)) 1605 || Pixel2Row (ev.xbutton.y) > (TermWin.nrow-1))
1283 { 1606 {
1284 int dist; 1607 int dist;
1290 sel_scroll_ev.start (NOW + SCROLLBAR_INITIAL_DELAY); 1613 sel_scroll_ev.start (NOW + SCROLLBAR_INITIAL_DELAY);
1291 1614
1292 /* save the event params so we can highlight 1615 /* save the event params so we can highlight
1293 * the selection in the pending-scroll loop 1616 * the selection in the pending-scroll loop
1294 */ 1617 */
1295 selection_save_x=ev.xbutton.x; 1618 selection_save_x = ev.xbutton.x;
1296 selection_save_y=ev.xbutton.y; 1619 selection_save_y = ev.xbutton.y;
1297 selection_save_state=
1298 (ev.xbutton.state & Button3Mask) ? 2 : 0; 1620 selection_save_state = (ev.xbutton.state & Button3Mask) ? 2 : 0;
1299 1621
1300 /* calc number of lines to scroll */ 1622 /* calc number of lines to scroll */
1301 if (ev.xbutton.y<TermWin.int_bwidth) 1623 if (ev.xbutton.y < TermWin.int_bwidth)
1302 { 1624 {
1303 scroll_selection_dir = UP; 1625 scroll_selection_dir = UP;
1304 dist = TermWin.int_bwidth - ev.xbutton.y; 1626 dist = TermWin.int_bwidth - ev.xbutton.y;
1305 } 1627 }
1306 else 1628 else
1307 { 1629 {
1308 scroll_selection_dir = DN; 1630 scroll_selection_dir = DN;
1309 dist = ev.xbutton.y -
1310 (TermWin.int_bwidth + TermWin.height); 1631 dist = ev.xbutton.y - (TermWin.int_bwidth + TermWin.height);
1311 } 1632 }
1633
1312 scroll_selection_lines= (Pixel2Height (dist)/ 1634 scroll_selection_lines = Pixel2Height (dist)
1313 SELECTION_SCROLL_LINE_SPEEDUP)+1; 1635 / SELECTION_SCROLL_LINE_SPEEDUP
1636 + 1;
1314 MIN_IT (scroll_selection_lines, 1637 MIN_IT (scroll_selection_lines,
1315 SELECTION_SCROLL_MAX_LINES); 1638 SELECTION_SCROLL_MAX_LINES);
1316 } 1639 }
1317 else 1640 else
1318 { 1641 {
1319 /* we are within the text window, so we 1642 /* we are within the text window, so we
1320 * shouldn't be scrolling 1643 * shouldn't be scrolling
1322 if (sel_scroll_ev.active) 1645 if (sel_scroll_ev.active)
1323 sel_scroll_ev.stop(); 1646 sel_scroll_ev.stop();
1324 } 1647 }
1325#endif 1648#endif
1326#ifdef MOUSE_THRESHOLD 1649#ifdef MOUSE_THRESHOLD
1327
1328 } 1650 }
1329#endif 1651#endif
1330
1331 } 1652 }
1332 } 1653 }
1333 else if (isScrollbarWindow (ev.xany.window) && scrollbar_isMotion ()) 1654 else if (isScrollbarWindow (ev.xany.window) && scrollbar_isMotion ())
1334 { 1655 {
1335 while (XCheckTypedWindowEvent (display->display, scrollBar.win, 1656 while (XCheckTypedWindowEvent (display->display, scrollBar.win,
1336 MotionNotify, &ev)) ; 1657 MotionNotify, &ev))
1658 ;
1659
1337 XQueryPointer (display->display, scrollBar.win, 1660 XQueryPointer (display->display, scrollBar.win,
1338 &unused_root, &unused_child, 1661 &unused_root, &unused_child,
1339 &unused_root_x, &unused_root_y, 1662 &unused_root_x, &unused_root_y,
1340 & (ev.xbutton.x), & (ev.xbutton.y), 1663 &ev.xbutton.x, &ev.xbutton.y,
1341 &unused_mask); 1664 &unused_mask);
1342 scr_move_to (scrollbar_position (ev.xbutton.y) - csrO, 1665 scr_move_to (scrollbar_position (ev.xbutton.y) - csrO,
1343 scrollbar_size ()); 1666 scrollbar_size ());
1344 scr_refresh (refresh_type); 1667 scr_refresh (refresh_type);
1345 refresh_limit = 0; 1668 refresh_limit = 0;
1347 } 1670 }
1348 break; 1671 break;
1349 } 1672 }
1350} 1673}
1351 1674
1675#if TRANSPARENT
1352void 1676void
1353rxvt_term::rootwin_cb (XEvent &ev) 1677rxvt_term::rootwin_cb (XEvent &ev)
1354{ 1678{
1355 SET_R (this); 1679 SET_R (this);
1356 SET_LOCALE (locale); 1680 SET_LOCALE (locale);
1357 1681
1358 switch (ev.type) 1682 switch (ev.type)
1359 { 1683 {
1360 case PropertyNotify: 1684 case PropertyNotify:
1361 if (ev.xproperty.atom == xa[XA_VT_SELECTION])
1362 {
1363 if (ev.xproperty.state == PropertyNewValue)
1364 selection_property (ev.xproperty.window, ev.xproperty.atom);
1365 break;
1366 }
1367#ifdef TRANSPARENT
1368 else
1369 {
1370 /* 1685 /*
1371 * if user used some Esetroot compatible prog to set the root bg, 1686 * if user used some Esetroot compatible prog to set the root bg,
1372 * use the property to determine the pixmap. We use it later on. 1687 * use the property to determine the pixmap. We use it later on.
1373 */ 1688 */
1374 if (xa[XA_XROOTPMAPID] == 0)
1375 xa[XA_XROOTPMAPID] = XInternAtom (display->display, "_XROOTPMAP_ID", False);
1376
1377 if (ev.xproperty.atom != xa[XA_XROOTPMAPID]) 1689 if (ev.xproperty.atom != xa[XA_XROOTPMAP_ID]
1690 && ev.xproperty.atom != xa[XA_ESETROOT_PMAP_ID])
1378 return; 1691 return;
1379 }
1380 1692
1381 /* FALLTHROUGH */ 1693 /* FALLTHROUGH */
1382 case ReparentNotify: 1694 case ReparentNotify:
1383 if ((Options & Opt_transparent) && check_our_parents () && am_transparent) 1695 if ((options & Opt_transparent) && check_our_parents () && am_transparent)
1384 want_full_refresh = 1; 1696 want_refresh = want_full_refresh = 1;
1385 break; 1697 break;
1386#endif
1387 } 1698 }
1388} 1699}
1700#endif
1389 1701
1390void 1702void
1391rxvt_term::button_press (XButtonEvent &ev) 1703rxvt_term::button_press (XButtonEvent &ev)
1392{ 1704{
1393 int reportmode = 0, clickintime; 1705 int reportmode = 0, clickintime;
1394 1706
1395 bypass_keystate = ev.state & (ModMetaMask | ShiftMask); 1707 bypass_keystate = ev.state & (ModMetaMask | ShiftMask);
1396 if (!bypass_keystate) 1708 if (!bypass_keystate)
1397 reportmode = !! (PrivateModes & PrivMode_mouse_report); 1709 reportmode = !! (priv_modes & PrivMode_mouse_report);
1710
1398 /* 1711 /*
1399 * VT window processing of button press 1712 * VT window processing of button press
1400 */ 1713 */
1401 if (ev.window == TermWin.vt) 1714 if (ev.window == TermWin.vt)
1402 { 1715 {
1716#if ISO_14755
1717 // 5.4
1718 if (iso14755buf & (ISO_14755_STARTED | ISO_14755_54))
1719 {
1720 iso14755_54 (ev.x, ev.y);
1721 return;
1722 }
1723#endif
1724
1403 clickintime = ev.time - MEvent.time < MULTICLICK_TIME; 1725 clickintime = ev.time - MEvent.time < MULTICLICK_TIME;
1726
1404 if (reportmode) 1727 if (reportmode)
1405 { 1728 {
1406 /* mouse report from vt window */ 1729 /* mouse report from vt window */
1407 /* save the xbutton state (for ButtonRelease) */ 1730 /* save the xbutton state (for ButtonRelease) */
1408 MEvent.state = ev.state; 1731 MEvent.state = ev.state;
1437 } 1760 }
1438 else 1761 else
1439 { 1762 {
1440 if (ev.button != MEvent.button) 1763 if (ev.button != MEvent.button)
1441 MEvent.clicks = 0; 1764 MEvent.clicks = 0;
1765
1442 switch (ev.button) 1766 switch (ev.button)
1443 { 1767 {
1444 case Button1: 1768 case Button1:
1769 /* allow meta + click to select rectangular areas */
1770 /* should be done in screen.C */
1771#if ENABLE_FRILLS
1772 selection.rect = !! (ev.state & ModMetaMask);
1773#else
1774 selection.rect = false;
1775#endif
1776
1445 /* allow shift+left click to extend selection */ 1777 /* allow shift+left click to extend selection */
1446 if (ev.state & ShiftMask && ! (PrivateModes & PrivMode_mouse_report)) 1778 if (ev.state & ShiftMask && ! (priv_modes & PrivMode_mouse_report))
1447 { 1779 {
1448 if (MEvent.button == Button1 && clickintime) 1780 if (MEvent.button == Button1 && clickintime)
1449 selection_rotate (ev.x, ev.y); 1781 selection_rotate (ev.x, ev.y);
1450 else 1782 else
1451 selection_extend (ev.x, ev.y, 1); 1783 selection_extend (ev.x, ev.y, 1);
1466 case Button3: 1798 case Button3:
1467 if (MEvent.button == Button3 && clickintime) 1799 if (MEvent.button == Button3 && clickintime)
1468 selection_rotate (ev.x, ev.y); 1800 selection_rotate (ev.x, ev.y);
1469 else 1801 else
1470 selection_extend (ev.x, ev.y, 1); 1802 selection_extend (ev.x, ev.y, 1);
1803
1471 MEvent.button = Button3; 1804 MEvent.button = Button3;
1472 break; 1805 break;
1473 } 1806 }
1474 } 1807 }
1808
1475 MEvent.time = ev.time; 1809 MEvent.time = ev.time;
1476 return; 1810 return;
1477 } 1811 }
1478 1812
1479 /* 1813 /*
1571 break; 1905 break;
1572 case R_SB_ALIGN_BOTTOM: 1906 case R_SB_ALIGN_BOTTOM:
1573 csrO = scrollBar.bot - scrollBar.top; 1907 csrO = scrollBar.bot - scrollBar.top;
1574 break; 1908 break;
1575 } 1909 }
1910
1576 if (scrollBar.style == R_SB_XTERM 1911 if (scrollBar.style == R_SB_XTERM
1577 || scrollbar_above_slider (ev.y) 1912 || scrollbar_above_slider (ev.y)
1578 || scrollbar_below_slider (ev.y)) 1913 || scrollbar_below_slider (ev.y))
1579 scr_move_to ( scrollbar_position (ev.y) - csrO, 1914 scr_move_to (scrollbar_position (ev.y) - csrO, scrollbar_size ());
1580 scrollbar_size ()); 1915
1581 scrollBar.setMotion (); 1916 scrollBar.setMotion ();
1582 break; 1917 break;
1583 1918
1584 case Button1: 1919 case Button1:
1585 if (scrollbar_align == R_SB_ALIGN_CENTRE) 1920 if (scrollbar_align == R_SB_ALIGN_CENTRE)
1609 scr_page ((ev.button == Button1 ? DN : UP), 1944 scr_page ((ev.button == Button1 ? DN : UP),
1610 (TermWin.nrow 1945 (TermWin.nrow
1611 * scrollbar_position (ev.y) 1946 * scrollbar_position (ev.y)
1612 / scrollbar_size ())); 1947 / scrollbar_size ()));
1613 } 1948 }
1949
1614 break; 1950 break;
1615 } 1951 }
1616 } 1952 }
1617 return; 1953 return;
1618 } 1954 }
1630{ 1966{
1631 int reportmode = 0; 1967 int reportmode = 0;
1632 1968
1633 csrO = 0; /* reset csr Offset */ 1969 csrO = 0; /* reset csr Offset */
1634 if (!bypass_keystate) 1970 if (!bypass_keystate)
1635 reportmode = !! (PrivateModes & PrivMode_mouse_report); 1971 reportmode = !! (priv_modes & PrivMode_mouse_report);
1636 1972
1637 if (scrollbar_isUpDn ()) 1973 if (scrollbar_isUpDn ())
1638 { 1974 {
1639 scrollBar.setIdle (); 1975 scrollBar.setIdle ();
1640 scrollbar_show (0); 1976 scrollbar_show (0);
1641#ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING 1977#ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING
1642 refresh_type &= ~SMOOTH_REFRESH; 1978 refresh_type &= ~SMOOTH_REFRESH;
1643#endif 1979#endif
1644
1645 } 1980 }
1981
1646#ifdef SELECTION_SCROLLING 1982#ifdef SELECTION_SCROLLING
1647 if (sel_scroll_ev.active) 1983 if (sel_scroll_ev.active)
1648 sel_scroll_ev.stop(); 1984 sel_scroll_ev.stop();
1649#endif 1985#endif
1986
1650 if (ev.window == TermWin.vt) 1987 if (ev.window == TermWin.vt)
1651 { 1988 {
1989#if ISO_14755
1990 // 5.4
1991 if (iso14755buf & (ISO_14755_STARTED | ISO_14755_54))
1992 return;
1993#endif
1652 if (reportmode) 1994 if (reportmode)
1653 { 1995 {
1654 /* mouse report from vt window */ 1996 /* mouse report from vt window */
1655 /* don't report release of wheel "buttons" */ 1997 /* don't report release of wheel "buttons" */
1656 if (ev.button >= 4) 1998 if (ev.button >= 4)
1670 MEvent.button = AnyButton; 2012 MEvent.button = AnyButton;
1671 mouse_report (ev); 2013 mouse_report (ev);
1672#endif /* MOUSE_REPORT_DOUBLECLICK */ 2014#endif /* MOUSE_REPORT_DOUBLECLICK */
1673 return; 2015 return;
1674 } 2016 }
2017
1675 /* 2018 /*
1676 * dumb hack to compensate for the failure of click-and-drag 2019 * dumb hack to compensate for the failure of click-and-drag
1677 * when overriding mouse reporting 2020 * when overriding mouse reporting
1678 */ 2021 */
1679 if (PrivateModes & PrivMode_mouse_report 2022 if (priv_modes & PrivMode_mouse_report
1680 && bypass_keystate 2023 && bypass_keystate
1681 && ev.button == Button1 && MEvent.clicks <= 1) 2024 && ev.button == Button1 && MEvent.clicks <= 1)
1682 selection_extend (ev.x, ev.y, 0); 2025 selection_extend (ev.x, ev.y, 0);
1683 2026
1684 switch (ev.button) 2027 switch (ev.button)
1699 2042
1700 v = ev.button == Button4 ? UP : DN; 2043 v = ev.button == Button4 ? UP : DN;
1701 2044
1702 if (ev.state & ShiftMask) 2045 if (ev.state & ShiftMask)
1703 i = 1; 2046 i = 1;
1704 else if (Options & Opt_mouseWheelScrollPage) 2047 else if (options & Opt_mouseWheelScrollPage)
1705 i = TermWin.nrow - 1; 2048 i = TermWin.nrow - 1;
1706 else 2049 else
1707 i = 5; 2050 i = 5;
1708 2051
1709# ifdef MOUSE_SLIP_WHEELING 2052# ifdef MOUSE_SLIP_WHEELING
1710 if (ev.state & ControlMask) 2053 if (ev.state & ControlMask)
1711 { 2054 {
1712 mouse_slip_wheel_speed += v ? -1 : 1; 2055 mouse_slip_wheel_speed += v ? -1 : 1;
2056 if (mouse_slip_wheel_speed < -TermWin.nrow) mouse_slip_wheel_speed = -TermWin.nrow;
2057 if (mouse_slip_wheel_speed > +TermWin.nrow) mouse_slip_wheel_speed = +TermWin.nrow;
2058
2059 if (slip_wheel_ev.at < NOW)
1713 slip_wheel_ev.start (NOW + SCROLLBAR_CONTINUOUS_DELAY); 2060 slip_wheel_ev.at = NOW + SCROLLBAR_CONTINUOUS_DELAY;
2061
2062 slip_wheel_ev.start ();
1714 } 2063 }
2064 else
2065 {
1715# endif 2066# endif
1716# ifdef JUMP_MOUSE_WHEEL 2067# ifdef JUMP_MOUSE_WHEEL
1717 scr_page (v, i);
1718 scr_refresh (SMOOTH_REFRESH);
1719 scrollbar_show (1);
1720# else
1721 while (i--)
1722 {
1723 scr_page (v, 1); 2068 scr_page (v, i);
1724 scr_refresh (SMOOTH_REFRESH); 2069 scr_refresh (SMOOTH_REFRESH);
1725 scrollbar_show (1); 2070 scrollbar_show (1);
2071# else
2072 while (i--)
2073 {
2074 scr_page (v, 1);
2075 scr_refresh (SMOOTH_REFRESH);
2076 scrollbar_show (1);
2077 }
2078# endif
2079# ifdef MOUSE_SLIP_WHEELING
1726 } 2080 }
1727# endif 2081#endif
1728
1729 } 2082 }
1730 break; 2083 break;
1731#endif 2084#endif
1732
1733 } 2085 }
1734 } 2086 }
1735#ifdef MENUBAR 2087#ifdef MENUBAR
1736 else if (isMenuBarWindow (ev.window)) 2088 else if (isMenuBarWindow (ev.window))
1737 menubar_control (ev); 2089 menubar_control (ev);
1738#endif 2090#endif
1739} 2091}
1740 2092
1741#ifdef TRANSPARENT 2093#ifdef TRANSPARENT
1742#if TINTING 2094#if TINTING
1743/* shading taken from eterm-0.9.2 */ 2095/* taken from aterm-0.4.2 */
1744/* RGB 15 */
1745 2096
1746static void 2097typedef uint32_t RUINT32T;
1747shade_ximage_15(void *data, int bpl, int w, int h, int rm, int gm, int bm)
1748{
1749 unsigned char *ptr;
1750 int x, y;
1751 2098
1752 ptr = (unsigned char *)data + (w * sizeof(uint16_t)); 2099void ShadeXImage(rxvt_display *display, XImage* srcImage, int shade, int rm, int gm, int bm)
1753 if ((rm <= 256) && (gm <= 256) && (bm <= 256)) { 2100{
1754 /* No saturation */ 2101 int sh_r, sh_g, sh_b;
1755 for (y = h; --y >= 0;) { 2102 RUINT32T mask_r, mask_g, mask_b;
1756 for (x = -w; x < 0; x++) { 2103 RUINT32T *lookup, *lookup_r, *lookup_g, *lookup_b;
1757 int r, g, b; 2104 unsigned int lower_lim_r, lower_lim_g, lower_lim_b;
2105 unsigned int upper_lim_r, upper_lim_g, upper_lim_b;
2106 int i;
1758 2107
1759 b = ((uint16_t *) ptr)[x]; 2108 Visual* visual = display->visual;
1760 r = (b & 0x7c00) * rm; 2109
1761 g = (b & 0x3e0) * gm; 2110 if( visual->c_class != TrueColor || srcImage->format != ZPixmap ) return ;
1762 b = (b & 0x1f) * bm; 2111
1763 ((uint16_t *) ptr)[x] = ((r >> 8) & 0x7c00) 2112 /* for convenience */
1764 | ((g >> 8) & 0x3e0) 2113 mask_r = visual->red_mask;
1765 | ((b >> 8) & 0x1f); 2114 mask_g = visual->green_mask;
1766 } 2115 mask_b = visual->blue_mask;
1767 ptr += bpl; 2116
1768 } 2117 /* boring lookup table pre-initialization */
2118 switch (srcImage->bits_per_pixel) {
2119 case 15:
2120 if ((mask_r != 0x7c00) ||
2121 (mask_g != 0x03e0) ||
2122 (mask_b != 0x001f))
2123 return;
2124 lookup = (RUINT32T *) malloc (sizeof (RUINT32T)*(32+32+32));
2125 lookup_r = lookup;
2126 lookup_g = lookup+32;
2127 lookup_b = lookup+32+32;
2128 sh_r = 10;
2129 sh_g = 5;
2130 sh_b = 0;
2131 break;
2132 case 16:
2133 if ((mask_r != 0xf800) ||
2134 (mask_g != 0x07e0) ||
2135 (mask_b != 0x001f))
2136 return;
2137 lookup = (RUINT32T *) malloc (sizeof (RUINT32T)*(32+64+32));
2138 lookup_r = lookup;
2139 lookup_g = lookup+32;
2140 lookup_b = lookup+32+64;
2141 sh_r = 11;
2142 sh_g = 5;
2143 sh_b = 0;
2144 break;
2145 case 24:
2146 if ((mask_r != 0xff0000) ||
2147 (mask_g != 0x00ff00) ||
2148 (mask_b != 0x0000ff))
2149 return;
2150 lookup = (RUINT32T *) malloc (sizeof (RUINT32T)*(256+256+256));
2151 lookup_r = lookup;
2152 lookup_g = lookup+256;
2153 lookup_b = lookup+256+256;
2154 sh_r = 16;
2155 sh_g = 8;
2156 sh_b = 0;
2157 break;
2158 case 32:
2159 if ((mask_r != 0xff0000) ||
2160 (mask_g != 0x00ff00) ||
2161 (mask_b != 0x0000ff))
2162 return;
2163 lookup = (RUINT32T *) malloc (sizeof (RUINT32T)*(256+256+256));
2164 lookup_r = lookup;
2165 lookup_g = lookup+256;
2166 lookup_b = lookup+256+256;
2167 sh_r = 16;
2168 sh_g = 8;
2169 sh_b = 0;
2170 break;
2171 default:
2172 return; /* we do not support this color depth */
2173 }
2174
2175 /* prepare limits for color transformation (each channel is handled separately) */
2176 if (shade < 0) {
2177 shade = -shade;
2178 if (shade < 0) shade = 0;
2179 if (shade > 100) shade = 100;
2180
2181 lower_lim_r = 65535-rm;
2182 lower_lim_g = 65535-gm;
2183 lower_lim_b = 65535-bm;
2184
2185 lower_lim_r = 65535-(unsigned int)(((RUINT32T)lower_lim_r)*((RUINT32T)shade)/100);
2186 lower_lim_g = 65535-(unsigned int)(((RUINT32T)lower_lim_g)*((RUINT32T)shade)/100);
2187 lower_lim_b = 65535-(unsigned int)(((RUINT32T)lower_lim_b)*((RUINT32T)shade)/100);
2188
2189 upper_lim_r = upper_lim_g = upper_lim_b = 65535;
1769 } else { 2190 } else {
1770 for (y = h; --y >= 0;) { 2191 if (shade < 0) shade = 0;
1771 for (x = -w; x < 0; x++) { 2192 if (shade > 100) shade = 100;
1772 int r, g, b;
1773 2193
1774 b = ((uint16_t *) ptr)[x]; 2194 lower_lim_r = lower_lim_g = lower_lim_b = 0;
1775 r = (b & 0x7c00) * rm; 2195
1776 g = (b & 0x3e0) * gm; 2196 upper_lim_r = (unsigned int)((((RUINT32T)rm)*((RUINT32T)shade))/100);
1777 b = (b & 0x1f) * bm; 2197 upper_lim_g = (unsigned int)((((RUINT32T)gm)*((RUINT32T)shade))/100);
1778 r |= (!(r >> 15) - 1); 2198 upper_lim_b = (unsigned int)((((RUINT32T)bm)*((RUINT32T)shade))/100);
1779 g |= (!(g >> 10) - 1); 2199 }
1780 b |= (!(b >> 5) - 1); 2200
1781 ((uint16_t *) ptr)[x] = ((r >> 8) & 0x7c00) 2201 /* switch red and blue bytes if necessary, we need it for some weird XServers like XFree86 3.3.3.1 */
1782 | ((g >> 8) & 0x3e0) 2202 if ((srcImage->bits_per_pixel == 24) && (mask_r >= 0xFF0000 ))
1783 | ((b >> 8) & 0x1f); 2203 {
1784 } 2204 unsigned int tmp;
1785 ptr += bpl; 2205
2206 tmp = lower_lim_r;
2207 lower_lim_r = lower_lim_b;
2208 lower_lim_b = tmp;
2209
2210 tmp = upper_lim_r;
2211 upper_lim_r = upper_lim_b;
2212 upper_lim_b = tmp;
2213 }
2214
2215 /* fill our lookup tables */
2216 for (i = 0; i <= mask_r>>sh_r; i++)
2217 {
2218 RUINT32T tmp;
2219 tmp = ((RUINT32T)i)*((RUINT32T)(upper_lim_r-lower_lim_r));
2220 tmp += ((RUINT32T)(mask_r>>sh_r))*((RUINT32T)lower_lim_r);
2221 lookup_r[i] = (tmp/65535)<<sh_r;
2222 }
2223 for (i = 0; i <= mask_g>>sh_g; i++)
2224 {
2225 RUINT32T tmp;
2226 tmp = ((RUINT32T)i)*((RUINT32T)(upper_lim_g-lower_lim_g));
2227 tmp += ((RUINT32T)(mask_g>>sh_g))*((RUINT32T)lower_lim_g);
2228 lookup_g[i] = (tmp/65535)<<sh_g;
2229 }
2230 for (i = 0; i <= mask_b>>sh_b; i++)
2231 {
2232 RUINT32T tmp;
2233 tmp = ((RUINT32T)i)*((RUINT32T)(upper_lim_b-lower_lim_b));
2234 tmp += ((RUINT32T)(mask_b>>sh_b))*((RUINT32T)lower_lim_b);
2235 lookup_b[i] = (tmp/65535)<<sh_b;
2236 }
2237
2238 /* apply table to input image (replacing colors by newly calculated ones) */
2239 switch (srcImage->bits_per_pixel)
2240 {
2241 case 15:
2242 {
2243 unsigned short *p1, *pf, *p, *pl;
2244 p1 = (unsigned short *) srcImage->data;
2245 pf = (unsigned short *) (srcImage->data + srcImage->height * srcImage->bytes_per_line);
2246 while (p1 < pf)
2247 {
2248 p = p1;
2249 pl = p1 + srcImage->width;
2250 for (; p < pl; p++)
1786 } 2251 {
2252 *p = lookup_r[(*p & 0x7c00)>>10] |
2253 lookup_g[(*p & 0x03e0)>> 5] |
2254 lookup_b[(*p & 0x001f)];
2255 }
2256 p1 = (unsigned short *) ((char *) p1 + srcImage->bytes_per_line);
1787 } 2257 }
1788} 2258 break;
1789 2259 }
1790/* RGB 16 */ 2260 case 16:
1791static void 2261 {
1792shade_ximage_16(void *data, int bpl, int w, int h, int rm, int gm, int bm) 2262 unsigned short *p1, *pf, *p, *pl;
1793{ 2263 p1 = (unsigned short *) srcImage->data;
1794 unsigned char *ptr; 2264 pf = (unsigned short *) (srcImage->data + srcImage->height * srcImage->bytes_per_line);
1795 int x, y; 2265 while (p1 < pf)
1796 2266 {
1797 ptr = (unsigned char *)data + (w * sizeof(uint16_t)); 2267 p = p1;
1798 if ((rm <= 256) && (gm <= 256) && (bm <= 256)) { 2268 pl = p1 + srcImage->width;
1799 /* No saturation */ 2269 for (; p < pl; p++)
1800 for (y = h; --y >= 0;) {
1801 for (x = -w; x < 0; x++) {
1802 int r, g, b;
1803
1804 b = ((uint16_t *) ptr)[x];
1805 r = (b & 0xf800) * rm;
1806 g = (b & 0x7e0) * gm;
1807 b = (b & 0x1f) * bm;
1808 ((uint16_t *) ptr)[x] = ((r >> 8) & 0xf800)
1809 | ((g >> 8) & 0x7e0)
1810 | ((b >> 8) & 0x1f);
1811 }
1812 ptr += bpl;
1813 } 2270 {
1814 } else { 2271 *p = lookup_r[(*p & 0xf800)>>11] |
1815 for (y = h; --y >= 0;) { 2272 lookup_g[(*p & 0x07e0)>> 5] |
1816 for (x = -w; x < 0; x++) { 2273 lookup_b[(*p & 0x001f)];
1817 int r, g, b;
1818
1819 b = ((uint16_t *) ptr)[x];
1820 r = (b & 0xf800) * rm;
1821 g = (b & 0x7e0) * gm;
1822 b = (b & 0x1f) * bm;
1823 r |= (!(r >> 16) - 1);
1824 g |= (!(g >> 11) - 1);
1825 b |= (!(b >> 5) - 1);
1826 ((uint16_t *) ptr)[x] = ((r >> 8) & 0xf800)
1827 | ((g >> 8) & 0x7e0)
1828 | ((b >> 8) & 0x1f);
1829 } 2274 }
1830 ptr += bpl; 2275 p1 = (unsigned short *) ((char *) p1 + srcImage->bytes_per_line);
2276 }
2277 break;
2278 }
2279 case 24:
2280 {
2281 unsigned char *p1, *pf, *p, *pl;
2282 p1 = (unsigned char *) srcImage->data;
2283 pf = (unsigned char *) (srcImage->data + srcImage->height * srcImage->bytes_per_line);
2284 while (p1 < pf)
2285 {
2286 p = p1;
2287 pl = p1 + srcImage->width * 3;
2288 for (; p < pl; p += 3)
1831 } 2289 {
2290 p[0] = lookup_r[(p[0] & 0xff0000)>>16];
2291 p[1] = lookup_r[(p[1] & 0x00ff00)>> 8];
2292 p[2] = lookup_r[(p[2] & 0x0000ff)];
2293 }
2294 p1 = (unsigned char *) ((char *) p1 + srcImage->bytes_per_line);
1832 } 2295 }
1833} 2296 break;
2297 }
2298 case 32:
2299 {
2300 RUINT32T *p1, *pf, *p, *pl;
2301 p1 = (RUINT32T *) srcImage->data;
2302 pf = (RUINT32T *) (srcImage->data + srcImage->height * srcImage->bytes_per_line);
1834 2303
1835/* RGB 24 */ 2304 while (p1 < pf)
1836static void 2305 {
1837shade_ximage_24(void *data, int bpl, int w, int h, int rm, int gm, int bm) 2306 p = p1;
1838{ 2307 pl = p1 + srcImage->width;
1839 unsigned char *ptr; 2308 for (; p < pl; p++)
1840 int x, y;
1841
1842 ptr = (unsigned char *)data + (w * 3);
1843 if ((rm <= 256) && (gm <= 256) && (bm <= 256)) {
1844 /* No saturation */
1845 for (y = h; --y >= 0;) {
1846 for (x = -(w * 3); x < 0; x += 3) {
1847 int r, g, b;
1848
1849 if (byteorder.big_endian()) {
1850 r = (ptr[x + 0] * rm) >> 8;
1851 g = (ptr[x + 1] * gm) >> 8;
1852 b = (ptr[x + 2] * bm) >> 8;
1853 ptr[x + 0] = r;
1854 ptr[x + 1] = g;
1855 ptr[x + 2] = b;
1856 } else {
1857 r = (ptr[x + 2] * rm) >> 8;
1858 g = (ptr[x + 1] * gm) >> 8;
1859 b = (ptr[x + 0] * bm) >> 8;
1860 ptr[x + 2] = r;
1861 ptr[x + 1] = g;
1862 ptr[x + 0] = b;
1863 }
1864 }
1865 ptr += bpl;
1866 } 2309 {
1867 } else { 2310 *p = lookup_r[(*p & 0xff0000)>>16] |
1868 for (y = h; --y >= 0;) { 2311 lookup_g[(*p & 0x00ff00)>> 8] |
1869 for (x = -(w * 3); x < 0; x += 3) { 2312 lookup_b[(*p & 0x0000ff)] |
1870 int r, g, b; 2313 (*p & ~0xffffff);
1871
1872 if (byteorder.big_endian()) {
1873 r = (ptr[x + 0] * rm) >> 8;
1874 g = (ptr[x + 1] * gm) >> 8;
1875 b = (ptr[x + 2] * bm) >> 8;
1876
1877 r |= (!(r >> 8) - 1);
1878 g |= (!(g >> 8) - 1);
1879 b |= (!(b >> 8) - 1);
1880
1881 ptr[x + 0] = r;
1882 ptr[x + 1] = g;
1883 ptr[x + 2] = b;
1884 } else {
1885 r = (ptr[x + 2] * rm) >> 8;
1886 g = (ptr[x + 1] * gm) >> 8;
1887 b = (ptr[x + 0] * bm) >> 8;
1888
1889 r |= (!(r >> 8) - 1);
1890 g |= (!(g >> 8) - 1);
1891 b |= (!(b >> 8) - 1);
1892
1893 ptr[x + 2] = r;
1894 ptr[x + 1] = g;
1895 ptr[x + 0] = b;
1896 }
1897 } 2314 }
1898 ptr += bpl; 2315 p1 = (RUINT32T *) ((char *) p1 + srcImage->bytes_per_line);
1899 } 2316 }
2317 break;
2318 }
1900 } 2319 }
1901}
1902 2320
1903/* RGB 32 */ 2321 free (lookup);
1904static void
1905shade_ximage_32(void *data, int bpl, int w, int h, int rm, int gm, int bm)
1906{
1907 unsigned char *ptr;
1908 int x, y;
1909
1910 ptr = (unsigned char *)data + (w * 4);
1911 if ((rm <= 256) && (gm <= 256) && (bm <= 256)) {
1912 /* No saturation */
1913 for (y = h; --y >= 0;) {
1914 if (byteorder.big_endian()) {
1915 for (x = -(w * 4); x < 0; x += 4) {
1916 int r, g, b;
1917
1918 r = (ptr[x + 1] * rm) >> 8;
1919 g = (ptr[x + 2] * gm) >> 8;
1920 b = (ptr[x + 3] * bm) >> 8;
1921 ptr[x + 1] = r;
1922 ptr[x + 2] = g;
1923 ptr[x + 3] = b;
1924 }
1925 } else {
1926 for (x = -(w * 4); x < 0; x += 4) {
1927 int r, g, b;
1928
1929 r = (ptr[x + 2] * rm) >> 8;
1930 g = (ptr[x + 1] * gm) >> 8;
1931 b = (ptr[x + 0] * bm) >> 8;
1932 ptr[x + 2] = r;
1933 ptr[x + 1] = g;
1934 ptr[x + 0] = b;
1935 }
1936 }
1937 ptr += bpl;
1938 }
1939 } else {
1940 for (y = h; --y >= 0;) {
1941 for (x = -(w * 4); x < 0; x += 4) {
1942 int r, g, b;
1943
1944 if (byteorder.big_endian()) {
1945 r = (ptr[x + 1] * rm) >> 8;
1946 g = (ptr[x + 2] * gm) >> 8;
1947 b = (ptr[x + 3] * bm) >> 8;
1948
1949 r |= (!(r >> 8) - 1);
1950 g |= (!(g >> 8) - 1);
1951 b |= (!(b >> 8) - 1);
1952
1953 ptr[x + 1] = r;
1954 ptr[x + 2] = g;
1955 ptr[x + 3] = b;
1956 } else {
1957 r = (ptr[x + 2] * rm) >> 8;
1958 g = (ptr[x + 1] * gm) >> 8;
1959 b = (ptr[x + 0] * bm) >> 8;
1960
1961 r |= (!(r >> 8) - 1);
1962 g |= (!(g >> 8) - 1);
1963 b |= (!(b >> 8) - 1);
1964
1965 ptr[x + 2] = r;
1966 ptr[x + 1] = g;
1967 ptr[x + 0] = b;
1968 }
1969 }
1970 ptr += bpl;
1971 }
1972 }
1973} 2322}
1974
1975#endif 2323#endif
1976 2324
1977/* 2325/*
1978 * Check our parents are still who we think they are. 2326 * Check our parents are still who we think they are.
1979 * Do transparency updates if required 2327 * Do transparency updates if required
1989 Pixmap rootpixmap = None; 2337 Pixmap rootpixmap = None;
1990 XWindowAttributes wattr, wrootattr; 2338 XWindowAttributes wattr, wrootattr;
1991 2339
1992 pchanged = 0; 2340 pchanged = 0;
1993 2341
1994 if (!(Options & Opt_transparent)) 2342 if (!(options & Opt_transparent))
1995 return pchanged; /* Don't try any more */ 2343 return pchanged; /* Don't try any more */
1996 2344
1997 XGetWindowAttributes (display->display, display->root, &wrootattr); 2345 XGetWindowAttributes (display->display, display->root, &wrootattr);
1998 rootdepth = wrootattr.depth; 2346 rootdepth = wrootattr.depth;
1999 2347
2002 if (rootdepth != wattr.depth) 2350 if (rootdepth != wattr.depth)
2003 { 2351 {
2004 if (am_transparent) 2352 if (am_transparent)
2005 { 2353 {
2006 pchanged = 1; 2354 pchanged = 1;
2007 XSetWindowBackground (display->display, TermWin.vt, PixColors[Color_bg]); 2355 XSetWindowBackground (display->display, TermWin.vt, pix_colors_focused[Color_bg]);
2008 am_transparent = am_pixmap_trans = 0; 2356 am_transparent = am_pixmap_trans = 0;
2009 } 2357 }
2010 2358
2011 return pchanged; /* Don't try any more */ 2359 return pchanged; /* Don't try any more */
2012 } 2360 }
2017 /* 2365 /*
2018 * Make the frame window set by the window manager have 2366 * Make the frame window set by the window manager have
2019 * the root background. Some window managers put multiple nested frame 2367 * the root background. Some window managers put multiple nested frame
2020 * windows for each client, so we have to take care about that. 2368 * windows for each client, so we have to take care about that.
2021 */ 2369 */
2022 i = (xa[XA_XROOTPMAPID] 2370 i = (xa[XA_XROOTPMAP_ID]
2023 && XGetWindowProperty (display->display, display->root, xa[XA_XROOTPMAPID], 2371 && XGetWindowProperty (display->display, display->root, xa[XA_XROOTPMAP_ID],
2024 0L, 1L, False, XA_PIXMAP, &atype, &aformat, 2372 0L, 1L, False, XA_PIXMAP, &atype, &aformat,
2025 &nitems, &bytes_after, &prop) == Success); 2373 &nitems, &bytes_after, &prop) == Success);
2026 2374
2027 if (!i || prop == NULL) 2375 if (!i || prop == NULL)
2028 i = (xa[XA_XSETROOTID] 2376 i = (xa[XA_ESETROOT_PMAP_ID]
2029 && XGetWindowProperty (display->display, display->root, xa[XA_XSETROOTID], 2377 && XGetWindowProperty (display->display, display->root, xa[XA_ESETROOT_PMAP_ID],
2030 0L, 1L, False, XA_PIXMAP, &atype, &aformat, 2378 0L, 1L, False, XA_PIXMAP, &atype, &aformat,
2031 &nitems, &bytes_after, &prop) == Success); 2379 &nitems, &bytes_after, &prop) == Success);
2032 2380
2033 if (!i || prop == NULL) 2381 if (!i || prop == NULL
2382#if TINTING
2383 || !rs[Rs_color + Color_tint]
2384#endif
2385 )
2034 have_pixmap = 0; 2386 have_pixmap = 0;
2035 else 2387 else
2036 { 2388 {
2037 have_pixmap = 1; 2389 have_pixmap = 1;
2038 rootpixmap = *(Pixmap *)prop; 2390 rootpixmap = *(Pixmap *)prop;
2071 sy = 0; 2423 sy = 0;
2072 } 2424 }
2073 2425
2074 MIN_IT (nw, (unsigned int) (wrootattr.width - sx)); 2426 MIN_IT (nw, (unsigned int) (wrootattr.width - sx));
2075 MIN_IT (nh, (unsigned int) (wrootattr.height - sy)); 2427 MIN_IT (nh, (unsigned int) (wrootattr.height - sy));
2428
2429 XSync (display->display, False);
2076 allowedxerror = -1; 2430 allowedxerror = -1;
2077 image = XGetImage (display->display, rootpixmap, sx, sy, nw, nh, AllPlanes, ZPixmap); 2431 image = XGetImage (display->display, rootpixmap, sx, sy, nw, nh, AllPlanes, ZPixmap);
2078 2432
2079 /* XXX: handle BadMatch - usually because we're outside the pixmap */ 2433 /* XXX: handle BadMatch - usually because we're outside the pixmap */
2080 /* XXX: may need a delay here? */ 2434 /* XXX: may need a delay here? */
2100 XFreePixmap (display->display, TermWin.pixmap); 2454 XFreePixmap (display->display, TermWin.pixmap);
2101 2455
2102#if TINTING 2456#if TINTING
2103 if (ISSET_PIXCOLOR (Color_tint)) 2457 if (ISSET_PIXCOLOR (Color_tint))
2104 { 2458 {
2105 unsigned short shade, rm, gm, bm; 2459 unsigned short rm, gm, bm;
2460 int shade = rs[Rs_shade] ? atoi (rs[Rs_shade]) : 100;
2106 2461
2107 PixColors[Color_tint].get (display, rm, gm, bm); 2462 pix_colors_focused[Color_tint].get (display, rm, gm, bm);
2108 2463
2109 rm >>= 8; gm >>= 8; bm >>= 8; // not 100% correct, but... 2464 ShadeXImage (display, image, shade, rm, gm, bm);
2110
2111 /* Determine bitshift and bitmask values */
2112 switch (image->bits_per_pixel)
2113 {
2114 case 15: shade_ximage_15 (image->data, image->bytes_per_line, image->width, image->height, rm, gm, bm); break;
2115 case 16: shade_ximage_16 (image->data, image->bytes_per_line, image->width, image->height, rm, gm, bm); break;
2116 case 24: shade_ximage_24 (image->data, image->bytes_per_line, image->width, image->height, rm, gm, bm); break;
2117 case 32: shade_ximage_32 (image->data, image->bytes_per_line, image->width, image->height, rm, gm, bm); break;
2118 }
2119 } 2465 }
2120#endif 2466#endif
2121 2467
2122 TermWin.pixmap = XCreatePixmap (display->display, TermWin.vt, 2468 TermWin.pixmap = XCreatePixmap (display->display, TermWin.vt,
2123 szHint.width, szHint.height, image->depth); 2469 szHint.width, szHint.height, image->depth);
2124 gc = XCreateGC (display->display, TermWin.vt, 0UL, &gcvalue); 2470 gc = XCreateGC (display->display, TermWin.vt, 0UL, &gcvalue);
2125 XPutImage (display->display, TermWin.pixmap, gc, image, 0, 0, 2471 XPutImage (display->display, TermWin.pixmap, gc, image, 0, 0,
2126 nx, ny, image->width, image->height); 2472 nx, ny, image->width, image->height);
2127 XFreeGC (display->display, gc); 2473 XFreeGC (display->display, gc);
2128 XDestroyImage (image); 2474 XDestroyImage (image);
2129 XSetWindowBackgroundPixmap (display->display, TermWin.vt, 2475 XSetWindowBackgroundPixmap (display->display, TermWin.parent[0], TermWin.pixmap);
2130 TermWin.pixmap); 2476 XClearWindow (display->display, TermWin.parent[0]);
2131 2477
2132 if (!am_transparent || !am_pixmap_trans) 2478 if (!am_transparent || !am_pixmap_trans)
2133 pchanged = 1; 2479 pchanged = 1;
2134 2480
2135 am_transparent = am_pixmap_trans = 1; 2481 am_transparent = am_pixmap_trans = 1;
2136 } 2482 }
2137 } 2483 }
2138 2484
2139 if (!am_pixmap_trans) 2485 if (am_pixmap_trans)
2486 XSetWindowBackgroundPixmap (display->display, TermWin.vt, ParentRelative);
2487 else
2140 { 2488 {
2141 unsigned int n; 2489 unsigned int n;
2142 /* 2490 /*
2143 * InheritPixmap transparency 2491 * InheritPixmap transparency
2144 */ 2492 */
2145 D_X ((stderr, "InheritPixmap Seeking to %08lx", display->root));
2146 for (i = 1; i < (int) (sizeof (TermWin.parent) / sizeof (Window)); i++) 2493 for (i = 1; i < (int) (sizeof (TermWin.parent) / sizeof (Window)); i++)
2147 { 2494 {
2148 oldp = TermWin.parent[i]; 2495 oldp = TermWin.parent[i];
2149 XQueryTree (display->display, TermWin.parent[i - 1], &root, 2496 XQueryTree (display->display, TermWin.parent[i - 1], &root,
2150 &TermWin.parent[i], &list, &n); 2497 &TermWin.parent[i], &list, &n);
2151 XFree (list); 2498 XFree (list);
2152 D_X ((stderr, "InheritPixmap Parent[%d] = %08lx", i, TermWin.parent[i]));
2153 2499
2154 if (TermWin.parent[i] == display->root) 2500 if (TermWin.parent[i] == display->root)
2155 { 2501 {
2156 if (oldp != None) 2502 if (oldp != None)
2157 pchanged = 1; 2503 pchanged = 1;
2168 if (pchanged) 2514 if (pchanged)
2169 { 2515 {
2170 for (; n < (unsigned int)i; n++) 2516 for (; n < (unsigned int)i; n++)
2171 { 2517 {
2172 XGetWindowAttributes (display->display, TermWin.parent[n], &wattr); 2518 XGetWindowAttributes (display->display, TermWin.parent[n], &wattr);
2173 D_X ((stderr, "InheritPixmap Checking Parent[%d]: %s", n, (wattr.depth == rootdepth && wattr.class != InputOnly) ? "OK" : "FAIL"));
2174 if (wattr.depth != rootdepth || wattr.c_class == InputOnly) 2519 if (wattr.depth != rootdepth || wattr.c_class == InputOnly)
2175 { 2520 {
2176 n = (int) (sizeof (TermWin.parent) / sizeof (Window)) + 1; 2521 n = (int) (sizeof (TermWin.parent) / sizeof (Window)) + 1;
2177 break; 2522 break;
2178 } 2523 }
2179 } 2524 }
2180 } 2525 }
2181 2526
2182 if (n > (int) (sizeof (TermWin.parent) / sizeof (TermWin.parent[0]))) 2527 if (n > (int) (sizeof (TermWin.parent) / sizeof (TermWin.parent[0])))
2183 { 2528 {
2184 D_X ((stderr, "InheritPixmap Turning off"));
2185 XSetWindowBackground (display->display, TermWin.parent[0], PixColors[Color_fg]); 2529 XSetWindowBackground (display->display, TermWin.parent[0], pix_colors_focused[Color_fg]);
2186 XSetWindowBackground (display->display, TermWin.vt, PixColors[Color_bg]); 2530 XSetWindowBackground (display->display, TermWin.vt, pix_colors_focused[Color_bg]);
2187 am_transparent = 0; 2531 am_transparent = 0;
2188 /* XXX: also turn off Opt_transparent? */ 2532 /* XXX: also turn off Opt_transparent? */
2189 } 2533 }
2190 else 2534 else
2191 { 2535 {
2192#if WAIT_FOR_WM 2536#if WAIT_FOR_WM
2193 /* wait (an arbitrary period) for the WM to do its thing 2537 /* wait (an arbitrary period) for the WM to do its thing
2194 * needed for fvwm2.2.2 (and before?) */ 2538 * needed for fvwm2.2.2 (and before?) */
2195 sleep (1); 2539 sleep (1);
2196#endif 2540#endif
2197 D_X ((stderr, "InheritPixmap Turning on (%d parents)", i - 1));
2198 for (n = 0; n < (unsigned int)i; n++) 2541 for (n = 0; n < (unsigned int)i; n++)
2542 {
2199 XSetWindowBackgroundPixmap (display->display, TermWin.parent[n], ParentRelative); 2543 XSetWindowBackgroundPixmap (display->display, TermWin.parent[n], ParentRelative);
2544 XClearWindow (display->display, TermWin.parent[n]);
2545 }
2200 2546
2201 XSetWindowBackgroundPixmap (display->display, TermWin.vt, ParentRelative); 2547 XSetWindowBackgroundPixmap (display->display, TermWin.vt, ParentRelative);
2202 am_transparent = 1; 2548 am_transparent = 1;
2203 } 2549 }
2204 2550
2205 for (; i < (int) (sizeof (TermWin.parent) / sizeof (Window)); i++) 2551 for (; i < (int) (sizeof (TermWin.parent) / sizeof (Window)); i++)
2206 TermWin.parent[i] = None; 2552 TermWin.parent[i] = None;
2553 }
2554
2555 if (scrollBar.win)
2556 {
2557 XSetWindowBackgroundPixmap (display->display, scrollBar.win, ParentRelative);
2558 scrollBar.setIdle ();
2559 scrollbar_show (0);
2560 }
2561
2562 if (am_transparent)
2563 {
2564 want_refresh = want_full_refresh = 1;
2565 if (am_pixmap_trans)
2566 flush ();
2207 } 2567 }
2208 2568
2209 return pchanged; 2569 return pchanged;
2210} 2570}
2211#endif 2571#endif
2230 if (ch == NOCHAR) // TODO: improve 2590 if (ch == NOCHAR) // TODO: improve
2231 break; 2591 break;
2232 2592
2233 if (!IS_CONTROL (ch) || ch == C0_LF || ch == C0_CR || ch == C0_HT) 2593 if (!IS_CONTROL (ch) || ch == C0_LF || ch == C0_CR || ch == C0_HT)
2234 { 2594 {
2595 if (!seen_input)
2596 {
2597 seen_input = 1;
2598 // many badly-written programs (e.g. jed) contain a race condition:
2599 // they first read the screensize and then install a SIGWINCH handler.
2600 // some window managers resize the window early, and these programs
2601 // then sometimes get the size wrong.
2602 // unfortunately other programs are even more buggy and dislike
2603 // being sent SIGWINCH, so only do it when we were in fact being
2604 // resized.
2605 if (seen_resize)
2606 kill (-cmd_pid, SIGWINCH);
2607 }
2608
2235 /* Read a text string from the input buffer */ 2609 /* Read a text string from the input buffer */
2236 unicode_t buf[UBUFSIZ]; 2610 unicode_t buf[UBUFSIZ];
2237 bool refreshnow = false; 2611 bool refreshnow = false;
2238 int nlines = 0; 2612 int nlines = 0;
2239 unicode_t *str = buf; 2613 unicode_t *str = buf;
2240 2614
2241 *str++ = ch;
2242
2243 for (;;) 2615 for (;;)
2244 { 2616 {
2245 seq_begin = cmdbuf_ptr;
2246 ch = next_char ();
2247
2248 if (ch == NOCHAR || (IS_CONTROL (ch) && ch != C0_LF && ch != C0_CR && ch != C0_HT)) 2617 if (ch == NOCHAR || (IS_CONTROL (ch) && ch != C0_LF && ch != C0_CR && ch != C0_HT))
2249 break; 2618 break;
2250 2619
2251 *str++ = ch; 2620 *str++ = ch;
2252 2621
2253 if (ch == C0_LF) 2622 if (ch == C0_LF)
2254 { 2623 {
2255 nlines++; 2624 nlines++;
2256 refresh_count++; 2625 refresh_count++;
2257 2626
2258 if (! (Options & Opt_jumpScroll) 2627 if (!(options & Opt_jumpScroll)
2259 || (refresh_count >= (refresh_limit * (TermWin.nrow - 1)))) 2628 || (refresh_count >= refresh_limit * (TermWin.nrow - 1)))
2260 { 2629 {
2261 refreshnow = true; 2630 refreshnow = true;
2262 flag = true;
2263 ch = NOCHAR; 2631 ch = NOCHAR;
2264 break; 2632 break;
2265 } 2633 }
2266 2634
2267 // scr_add_lines only works for nlines < TermWin.nrow - 1. 2635 // scr_add_lines only works for nlines <= TermWin.nrow - 1.
2268 if (nlines >= TermWin.nrow - 1) 2636 if (nlines >= TermWin.nrow - 1)
2269 { 2637 {
2270 scr_add_lines (buf, nlines, str - buf); 2638 scr_add_lines (buf, nlines, str - buf);
2271 nlines = 0; 2639 nlines = 0;
2272 str = buf; 2640 str = buf;
2276 if (str >= buf + UBUFSIZ) 2644 if (str >= buf + UBUFSIZ)
2277 { 2645 {
2278 ch = NOCHAR; 2646 ch = NOCHAR;
2279 break; 2647 break;
2280 } 2648 }
2649
2650 seq_begin = cmdbuf_ptr;
2651 ch = next_char ();
2281 } 2652 }
2282 2653
2283 scr_add_lines (buf, nlines, str - buf); 2654 scr_add_lines (buf, nlines, str - buf);
2284 2655
2285 /* 2656 /*
2286 * If there have been a lot of new lines, then update the screen 2657 * If there have been a lot of new lines, then update the screen
2287 * What the heck I'll cheat and only refresh less than every page-full. 2658 * What the heck I'll cheat and only refresh less than every page-full.
2288 * the number of pages between refreshes is refresh_limit, which 2659 * the number of pages between refreshes is refresh_limit, which
2289 * is incremented here because we must be doing flat-out scrolling. 2660 * is incremented here because we must be doing flat-out scrolling.
2290 *
2291 * refreshing should be correct for small scrolls, because of the
2292 * time-out
2293 */ 2661 */
2294 if (refreshnow) 2662 if (refreshnow)
2295 { 2663 {
2296 if ((Options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD) 2664 if ((options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD)
2297 refresh_limit++; 2665 refresh_limit++;
2298 else 2666 else
2667 {
2668 flag = true;
2299 scr_refresh (refresh_type); 2669 scr_refresh (refresh_type);
2670 }
2300 } 2671 }
2301 2672
2302 } 2673 }
2303 else 2674 else
2304 { 2675 {
2352 if (len == (size_t)-1) 2723 if (len == (size_t)-1)
2353 return *cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through 2724 return *cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through
2354 2725
2355 // assume wchar == unicode 2726 // assume wchar == unicode
2356 cmdbuf_ptr += len; 2727 cmdbuf_ptr += len;
2357 return wc; 2728 return wc & UNICODE_MASK;
2358 } 2729 }
2359 2730
2360 return NOCHAR; 2731 return NOCHAR;
2361} 2732}
2362 2733
2488 process_escape_seq (); 2859 process_escape_seq ();
2489 break; 2860 break;
2490 case C0_ENQ: /* terminal Status */ 2861 case C0_ENQ: /* terminal Status */
2491 if (rs[Rs_answerbackstring]) 2862 if (rs[Rs_answerbackstring])
2492 tt_write ((const unsigned char *)rs[Rs_answerbackstring], 2863 tt_write ((const unsigned char *)rs[Rs_answerbackstring],
2493 (unsigned int)STRLEN (rs[Rs_answerbackstring])); 2864 (unsigned int)strlen (rs[Rs_answerbackstring]));
2494 else 2865 else
2495 tt_write ((unsigned char *)VT100_ANS, 2866 tt_write ((unsigned char *)VT100_ANS,
2496 (unsigned int)STRLEN (VT100_ANS)); 2867 (unsigned int)strlen (VT100_ANS));
2497 break; 2868 break;
2498 case C0_BEL: /* bell */ 2869 case C0_BEL: /* bell */
2499 scr_bell (); 2870 scr_bell ();
2500 break; 2871 break;
2501 case C0_BS: /* backspace */ 2872 case C0_BS: /* backspace */
2600void 2971void
2601rxvt_term::process_escape_seq () 2972rxvt_term::process_escape_seq ()
2602{ 2973{
2603 unicode_t ch = cmd_getc (); 2974 unicode_t ch = cmd_getc ();
2604 2975
2605 if (PrivateModes & PrivMode_vt52) 2976 if (priv_modes & PrivMode_vt52)
2606 { 2977 {
2607 process_escape_vt52 (ch); 2978 process_escape_vt52 (ch);
2608 return; 2979 return;
2609 } 2980 }
2610 2981
2625 scr_charset_set (2, (unsigned int)cmd_getc ()); 2996 scr_charset_set (2, (unsigned int)cmd_getc ());
2626 break; 2997 break;
2627 case '+': 2998 case '+':
2628 scr_charset_set (3, (unsigned int)cmd_getc ()); 2999 scr_charset_set (3, (unsigned int)cmd_getc ());
2629 break; 3000 break;
2630#ifndef NO_FRILLS 3001#if ENABLE_FRILLS
2631 case '6': 3002 case '6':
2632 scr_backindex (); 3003 scr_backindex ();
2633 break; 3004 break;
2634#endif 3005#endif
2635 case '7': 3006 case '7':
2636 scr_cursor (SAVE); 3007 scr_cursor (SAVE);
2637 break; 3008 break;
2638 case '8': 3009 case '8':
2639 scr_cursor (RESTORE); 3010 scr_cursor (RESTORE);
2640 break; 3011 break;
2641#ifndef NO_FRILLS 3012#if ENABLE_FRILLS
2642 case '9': 3013 case '9':
2643 scr_forwardindex (); 3014 scr_forwardindex ();
2644 break; 3015 break;
2645#endif 3016#endif
2646 case '=': 3017 case '=':
2945 scr_scroll_text (screen.tscroll, screen.bscroll, arg[0], 0); 3316 scr_scroll_text (screen.tscroll, screen.bscroll, arg[0], 0);
2946 break; 3317 break;
2947 3318
2948 case CSI_DA: /* 8.3.24: (0) DEVICE ATTRIBUTES */ 3319 case CSI_DA: /* 8.3.24: (0) DEVICE ATTRIBUTES */
2949 tt_write ((const unsigned char *)VT100_ANS, 3320 tt_write ((const unsigned char *)VT100_ANS,
2950 (unsigned int) (sizeof (VT100_ANS) - 1)); 3321 (unsigned int) (sizeof (VT100_ANS) - 1));
2951 break; 3322 break;
2952 3323
2953 case CSI_SGR: /* 8.3.118: (0) SELECT GRAPHIC RENDITION */ 3324 case CSI_SGR: /* 8.3.118: (0) SELECT GRAPHIC RENDITION */
2954 process_sgr_mode (nargs, arg); 3325 process_sgr_mode (nargs, arg);
2955 break; 3326 break;
2962 break; 3333 break;
2963 case 6: /* CPR requested */ 3334 case 6: /* CPR requested */
2964 scr_report_position (); 3335 scr_report_position ();
2965 break; 3336 break;
2966 case 7: /* unofficial extension */ 3337 case 7: /* unofficial extension */
2967 if (Options & Opt_insecure) 3338 if (options & Opt_insecure)
2968 tt_printf ("%-.250s\n", rs[Rs_display_name]); 3339 tt_printf ("%-.250s\012", rs[Rs_display_name]);
2969 break; 3340 break;
2970 case 8: /* unofficial extension */ 3341 case 8: /* unofficial extension */
2971 process_xterm_seq (XTerm_title, RESNAME "-" VERSION, CHAR_ST); 3342 process_xterm_seq (XTerm_title, RESNAME "-" VERSION, CHAR_ST);
2972 break; 3343 break;
2973 } 3344 }
3009 break; 3380 break;
3010 3381
3011 case CSI_RM: /* 8.3.107: RESET MODE */ 3382 case CSI_RM: /* 8.3.107: RESET MODE */
3012 if (arg[0] == 4) 3383 if (arg[0] == 4)
3013 scr_insert_mode (0); 3384 scr_insert_mode (0);
3385 else if (arg[0] == 20)
3386 priv_modes &= ~PrivMode_LFNL;
3014 break; 3387 break;
3015 3388
3016 case CSI_SM: /* 8.3.126: SET MODE */ 3389 case CSI_SM: /* 8.3.126: SET MODE */
3017 if (arg[0] == 4) 3390 if (arg[0] == 4)
3018 scr_insert_mode (1); 3391 scr_insert_mode (1);
3392 else if (arg[0] == 20)
3393 priv_modes |= PrivMode_LFNL;
3019 break; 3394 break;
3020 3395
3021 /* 3396 /*
3022 * PRIVATE USE beyond this point. All CSI_7? sequences here 3397 * PRIVATE USE beyond this point. All CSI_7? sequences here
3023 */ 3398 */
3035 break; 3410 break;
3036 case CSI_75: 3411 case CSI_75:
3037 scr_cursor (RESTORE); 3412 scr_cursor (RESTORE);
3038 break; 3413 break;
3039 3414
3040#ifndef NO_FRILLS 3415#if ENABLE_FRILLS
3041 case CSI_74: 3416 case CSI_74:
3042 process_window_ops (arg, nargs); 3417 process_window_ops (arg, nargs);
3043 break; 3418 break;
3044#endif 3419#endif
3045 3420
3052 break; 3427 break;
3053 } 3428 }
3054} 3429}
3055/*}}} */ 3430/*}}} */
3056 3431
3057#ifndef NO_FRILLS 3432#if ENABLE_FRILLS
3058/* ARGSUSED */ 3433/* ARGSUSED */
3059void 3434void
3060rxvt_term::process_window_ops (const int *args, unsigned int nargs) 3435rxvt_term::process_window_ops (const int *args, unsigned int nargs)
3061{ 3436{
3062 int x, y; 3437 int x, y;
3129 break; 3504 break;
3130 case 19: /* report window size (chars) */ 3505 case 19: /* report window size (chars) */
3131 tt_printf ("\033[9;%d;%dt", TermWin.nrow, TermWin.ncol); 3506 tt_printf ("\033[9;%d;%dt", TermWin.nrow, TermWin.ncol);
3132 break; 3507 break;
3133 case 20: /* report icon label */ 3508 case 20: /* report icon label */
3134 if (Options & Opt_insecure)
3135 { 3509 {
3136 char *s; 3510 char *s;
3137 XGetIconName (display->display, TermWin.parent[0], &s); 3511 XGetIconName (display->display, TermWin.parent[0], &s);
3138 tt_printf ("\033]L%-.200s\234", s ? s : ""); /* 8bit ST */ 3512 tt_printf ("\033]L%-.250s\234", (options & Opt_insecure) && s ? s : ""); /* 8bit ST */
3513 XFree (s);
3139 } 3514 }
3140 break; 3515 break;
3141 case 21: /* report window title */ 3516 case 21: /* report window title */
3142 if (Options & Opt_insecure)
3143 { 3517 {
3144 char *s; 3518 char *s;
3145 XFetchName (display->display, TermWin.parent[0], &s); 3519 XFetchName (display->display, TermWin.parent[0], &s);
3146 tt_printf ("\033]l%-.200s\234", s ? s : ""); /* 8bit ST */ 3520 tt_printf ("\033]l%-.250s\234", (options & Opt_insecure) && s ? s : ""); /* 8bit ST */
3521 XFree (s);
3147 } 3522 }
3148 break; 3523 break;
3149 } 3524 }
3150} 3525}
3151#endif 3526#endif
3152 3527
3156 * ends_how is terminator used. returned input must be free()'d 3531 * ends_how is terminator used. returned input must be free()'d
3157 */ 3532 */
3158unsigned char * 3533unsigned char *
3159rxvt_term::get_to_st (unicode_t &ends_how) 3534rxvt_term::get_to_st (unicode_t &ends_how)
3160{ 3535{
3161 unicode_t prev = 0, ch; 3536 unicode_t ch;
3537 bool seen_esc = false;
3162 unsigned int n = 0; 3538 unsigned int n = 0;
3163 unsigned char *s;
3164 unsigned char string[STRING_MAX]; 3539 wchar_t string[STRING_MAX];
3165 3540
3166 while ((ch = cmd_getc ()) != NOCHAR) 3541 while ((ch = cmd_getc ()) != NOCHAR)
3167 { 3542 {
3168 if (prev == C0_ESC) 3543 if (seen_esc)
3169 { 3544 {
3170 if (ch == 0x5c) /* 7bit ST */ 3545 if (ch == 0x5c) /* 7bit ST */
3171 break; 3546 break;
3172 else 3547 else
3173 return NULL; 3548 return NULL;
3174 } 3549 }
3550 else if (ch == C0_ESC)
3551 {
3552 seen_esc = true;
3553 continue;
3554 }
3175 else if (ch == C0_BEL || ch == CHAR_ST) 3555 else if (ch == C0_BEL || ch == CHAR_ST)
3176 break; 3556 break;
3177 else if (ch < 0x20) 3557 else if (ch < 0x20)
3178 return NULL; /* other control character - exit */ 3558 return NULL; /* other control character - exit */
3559
3560 seen_esc = false;
3179 3561
3180 if (n >= sizeof (string) - 1) 3562 if (n >= sizeof (string) - 1)
3181 // stop at some sane length 3563 // stop at some sane length
3182 return NULL; 3564 return NULL;
3183 3565
3184 if (ch == C0_SYN) 3566 if (ch == C0_SYN)
3185 {
3186 string[n++] = cmd_get8 (); 3567 string[n++] = cmd_get8 ();
3187 prev = 0;
3188 }
3189 else 3568 else
3190 string[n++] = prev = ch; 3569 string[n++] = ch;
3191 } 3570 }
3192 3571
3193 string[n++] = '\0'; 3572 string[n++] = '\0';
3194 3573
3195 if ((s = (unsigned char *)rxvt_malloc (n)) == NULL)
3196 return NULL;
3197
3198 ends_how = (ch == 0x5c ? C0_ESC : ch); 3574 ends_how = (ch == 0x5c ? C0_ESC : ch);
3199 STRNCPY (s, string, n); 3575
3200 return s; 3576 return (unsigned char *)rxvt_wcstombs (string);
3201} 3577}
3202 3578
3203/*----------------------------------------------------------------------*/ 3579/*----------------------------------------------------------------------*/
3204/* 3580/*
3205 * process DEVICE CONTROL STRING `ESC P ... (ST|BEL)' or `0x90 ... (ST|BEL)' 3581 * process DEVICE CONTROL STRING `ESC P ... (ST|BEL)' or `0x90 ... (ST|BEL)'
3249void 3625void
3250rxvt_term::process_color_seq (int report, int color, const char *str, unsigned char resp) 3626rxvt_term::process_color_seq (int report, int color, const char *str, unsigned char resp)
3251{ 3627{
3252 if (str[0] == '?' && !str[1]) 3628 if (str[0] == '?' && !str[1])
3253 { 3629 {
3254 if (Options & Opt_insecure)
3255 {
3256 unsigned short r, g, b; 3630 unsigned short r, g, b;
3257 PixColors[color].get (display, r, g, b); 3631 pix_colors_focused[color].get (display, r, g, b);
3258 tt_printf ("\033]%d;rgb:%04x/%04x/%04x%c", report, r, g, b, resp); 3632 tt_printf ("\033]%d;rgb:%04x/%04x/%04x%c", report, r, g, b, resp);
3259 }
3260 } 3633 }
3261 else 3634 else
3262 set_window_color (color, str); 3635 set_window_color (color, str);
3263} 3636}
3264 3637
3292{ 3665{
3293 int changed = 0; 3666 int changed = 0;
3294 int color; 3667 int color;
3295 char *buf, *name; 3668 char *buf, *name;
3296 bool query = str[0] == '?' && !str[1]; 3669 bool query = str[0] == '?' && !str[1];
3670 int saveop = op;
3297 3671
3298 assert (str != NULL); 3672 assert (str != NULL);
3299 switch (op) 3673 switch (op)
3300 { 3674 {
3301 case XTerm_name: 3675 case XTerm_name:
3308 set_title (str); 3682 set_title (str);
3309 break; 3683 break;
3310 case XTerm_property: 3684 case XTerm_property:
3311 if (str[0] == '?') 3685 if (str[0] == '?')
3312 { 3686 {
3313 Atom prop = XInternAtom (display->display, str + 1, True); 3687 Atom prop = display->atom (str + 1);
3314 Atom actual_type; 3688 Atom actual_type;
3315 int actual_format; 3689 int actual_format;
3316 unsigned long nitems; 3690 unsigned long nitems;
3317 unsigned long bytes_after; 3691 unsigned long bytes_after;
3318 unsigned char *value = 0; 3692 unsigned char *value = 0;
3336 char *eq = strchr (str, '='); // constness lost, but verified to be ok 3710 char *eq = strchr (str, '='); // constness lost, but verified to be ok
3337 3711
3338 if (eq) 3712 if (eq)
3339 { 3713 {
3340 *eq = 0; 3714 *eq = 0;
3341 XChangeProperty (display->display, TermWin.parent[0], 3715 set_utf8_property (display->atom (str), eq + 1);
3342 display->atom (str), XA_STRING, 8,
3343 PropModeReplace, (unsigned char *)eq + 1,
3344 strlen (eq + 1));
3345 } 3716 }
3346 else 3717 else
3347 XDeleteProperty (display->display, TermWin.parent[0], 3718 XDeleteProperty (display->display, TermWin.parent[0],
3348 display->atom (str)); 3719 display->atom (str));
3349 } 3720 }
3350 break; 3721 break;
3351 3722
3352 case XTerm_Color: 3723 case XTerm_Color:
3353 for (buf = (char *)str; buf && *buf;) 3724 for (buf = (char *)str; buf && *buf;)
3354 { 3725 {
3355 if ((name = STRCHR (buf, ';')) == NULL) 3726 if ((name = strchr (buf, ';')) == NULL)
3356 break; 3727 break;
3357 3728
3358 *name++ = '\0'; 3729 *name++ = '\0';
3359 color = atoi (buf); 3730 color = atoi (buf);
3360 3731
3361 if (color < 0 || color >= TOTAL_COLORS) 3732 if (color < 0 || color >= TOTAL_COLORS)
3362 break; 3733 break;
3363 3734
3364 if ((buf = STRCHR (name, ';')) != NULL) 3735 if ((buf = strchr (name, ';')) != NULL)
3365 *buf++ = '\0'; 3736 *buf++ = '\0';
3366 3737
3367 if (name[0] == '?' && !name[1]) 3738 if (name[0] == '?' && !name[1])
3368 { 3739 {
3369 if (Options & Opt_insecure)
3370 {
3371 unsigned short r, g, b; 3740 unsigned short r, g, b;
3372 PixColors[color + minCOLOR].get (display, r, g, b); 3741 pix_colors_focused[color + minCOLOR].get (display, r, g, b);
3373 tt_printf ("\033]%d;%d;rgb:%04x/%04x/%04x%c", XTerm_Color, color, r, g, b, resp); 3742 tt_printf ("\033]%d;%d;rgb:%04x/%04x/%04x%c", XTerm_Color, color, r, g, b, resp);
3374 }
3375 } 3743 }
3376 else 3744 else
3377 set_window_color (color + minCOLOR, name); 3745 set_window_color (color + minCOLOR, name);
3378 } 3746 }
3379 break; 3747 break;
3396 break; 3764 break;
3397#ifndef NO_BOLD_UNDERLINE_REVERSE 3765#ifndef NO_BOLD_UNDERLINE_REVERSE
3398 case XTerm_Color_BD: 3766 case XTerm_Color_BD:
3399 process_color_seq (XTerm_Color_BD, Color_BD, str, resp); 3767 process_color_seq (XTerm_Color_BD, Color_BD, str, resp);
3400 break; 3768 break;
3769 case XTerm_Color_IT:
3770 process_color_seq (XTerm_Color_IT, Color_IT, str, resp);
3771 break;
3401 case XTerm_Color_UL: 3772 case XTerm_Color_UL:
3402 process_color_seq (XTerm_Color_UL, Color_UL, str, resp); 3773 process_color_seq (XTerm_Color_UL, Color_UL, str, resp);
3403 break; 3774 break;
3404 case XTerm_Color_RV: 3775 case XTerm_Color_RV:
3405 process_color_seq (XTerm_Color_RV, Color_RV, str, resp); 3776 process_color_seq (XTerm_Color_RV, Color_RV, str, resp);
3777 break;
3778#endif
3779#if TRANSPARENT && TINTING
3780 case XTerm_Color_tint:
3781 process_color_seq (XTerm_Color_tint, Color_tint, str, resp);
3782 check_our_parents ();
3783 if (am_transparent)
3784 want_full_refresh = want_refresh = 1;
3406 break; 3785 break;
3407#endif 3786#endif
3408 3787
3409 case XTerm_Pixmap: 3788 case XTerm_Pixmap:
3410 if (*str != ';') 3789 if (*str != ';')
3413 scale_pixmap (""); /* reset to default scaling */ 3792 scale_pixmap (""); /* reset to default scaling */
3414 set_bgPixmap (str); /* change pixmap */ 3793 set_bgPixmap (str); /* change pixmap */
3415#endif 3794#endif
3416 scr_touch (true); 3795 scr_touch (true);
3417 } 3796 }
3418 while ((str = STRCHR (str, ';')) != NULL) 3797 while ((str = strchr (str, ';')) != NULL)
3419 { 3798 {
3420 str++; 3799 str++;
3421#if XPM_BACKGROUND 3800#if XPM_BACKGROUND
3422 changed += scale_pixmap (str); 3801 changed += scale_pixmap (str);
3423#endif 3802#endif
3442 case XTerm_logfile: 3821 case XTerm_logfile:
3443 // TODO, when secure mode? 3822 // TODO, when secure mode?
3444 break; 3823 break;
3445 3824
3446 case XTerm_font: 3825 case XTerm_font:
3826 op = URxvt_font;
3827 case URxvt_font:
3828#if ENABLE_STYLES
3829 case URxvt_boldFont:
3830 case URxvt_italicFont:
3831 case URxvt_boldItalicFont:
3832#endif
3447 if (query) 3833 if (query)
3834 tt_printf ("\33]%d;%-.250s%c", saveop,
3835 (options & Opt_insecure) && TermWin.fontset[op - URxvt_font]->fontdesc
3836 ? TermWin.fontset[op - URxvt_font]->fontdesc : "",
3837 resp);
3838 else
3448 { 3839 {
3449 if (Options & Opt_insecure) 3840 const char *&res = rs[Rs_font + (op - URxvt_font)];
3450 tt_printf ("\33]%d;%-.250s%c", XTerm_font, 3841
3451 TermWin.fontset->fontdesc 3842 res = strdup (str);
3452 ? TermWin.fontset->fontdesc 3843 allocated.push_back ((void *)res);
3453 : "", 3844 set_fonts ();
3454 resp);
3455 } 3845 }
3456 else
3457 change_font (str);
3458 break; 3846 break;
3459 3847
3460#ifndef NO_FRILLS 3848#if ENABLE_FRILLS
3461 case XTerm_locale: 3849 case XTerm_locale:
3462 if (query) 3850 if (query)
3463 {
3464 if (Options & Opt_insecure)
3465 tt_printf ("\33]%d;%-.250s%c", XTerm_locale, locale, resp); 3851 tt_printf ("\33]%d;%-.250s%c", XTerm_locale, (options & Opt_insecure) ? locale : "", resp);
3466 }
3467 else 3852 else
3468 { 3853 {
3469 set_locale (str); 3854 set_locale (str);
3470# ifdef USE_XIM 3855# ifdef USE_XIM
3471 im_cb (); 3856 im_cb ();
3472# endif 3857# endif
3473 } 3858 }
3474 break; 3859 break;
3475
3476 case XTerm_findfont:
3477 if (Options & Opt_insecure)
3478 {
3479 int fid = TermWin.fontset->find_font (atoi (str));
3480 tt_printf ("\33]%d;%d;%-.250s%c", XTerm_findfont,
3481 fid, (*TermWin.fontset)[fid]->name, resp);
3482 }
3483 break;
3484#endif 3860#endif
3485 3861
3486#ifdef MENUBAR 3862#ifdef MENUBAR
3487 case XTerm_Menu: 3863 case XTerm_Menu:
3488 if (Options & Opt_insecure) 3864 if (options & Opt_insecure)
3489 menubar_dispatch (const_cast<char *>(str)); // casting away constness is checked 3865 menubar_dispatch (const_cast<char *>(str)); // casting away constness is checked
3490 break; 3866 break;
3491#endif 3867#endif
3492#if 0 3868#if 0
3493 case XTerm_dumpscreen: /* no error notices */ 3869 case XTerm_dumpscreen: /* no error notices */
3520{ 3896{
3521 int state; 3897 int state;
3522 3898
3523 if (mode == 's') 3899 if (mode == 's')
3524 { 3900 {
3525 SavedModes |= (PrivateModes & bit); 3901 SavedModes |= (priv_modes & bit);
3526 return -1; 3902 return -1;
3527 } 3903 }
3528 else 3904 else
3529 { 3905 {
3530 if (mode == 'r') 3906 if (mode == 'r')
3531 state = (SavedModes & bit) ? 1 : 0; /* no overlapping */ 3907 state = (SavedModes & bit) ? 1 : 0; /* no overlapping */
3532 else 3908 else
3533 state = (mode == 't') ? ! (PrivateModes & bit) : mode; 3909 state = (mode == 't') ? ! (priv_modes & bit) : mode;
3534 PrivMode (state, bit); 3910 PrivMode (state, bit);
3535 } 3911 }
3536 3912
3537 return state; 3913 return state;
3538} 3914}
3556 { 3, PrivMode_132 }, 3932 { 3, PrivMode_132 },
3557 { 4, PrivMode_smoothScroll }, 3933 { 4, PrivMode_smoothScroll },
3558 { 5, PrivMode_rVideo }, 3934 { 5, PrivMode_rVideo },
3559 { 6, PrivMode_relOrigin }, 3935 { 6, PrivMode_relOrigin },
3560 { 7, PrivMode_Autowrap }, 3936 { 7, PrivMode_Autowrap },
3937 // 8, bi-directional support mode
3561 { 9, PrivMode_MouseX10 }, 3938 { 9, PrivMode_MouseX10 },
3562#ifdef menuBar_esc 3939#ifdef menuBar_esc
3563 { menuBar_esc, PrivMode_menuBar }, 3940 { menuBar_esc, PrivMode_menuBar },
3564#endif 3941#endif
3942 // 18, 19 printing-related
3943 { 25, PrivMode_VisibleCursor },
3565#ifdef scrollBar_esc 3944#ifdef scrollBar_esc
3566 { scrollBar_esc, PrivMode_scrollBar }, 3945 { scrollBar_esc, PrivMode_scrollBar },
3567#endif 3946#endif
3568 // 18, 19 printing-related
3569 { 25, PrivMode_VisibleCursor },
3570 // 30 show scrollbar rxvt. extension
3571 { 35, PrivMode_ShiftKeys }, // rxvt extension 3947 { 35, PrivMode_ShiftKeys }, // rxvt extension
3572 { 40, PrivMode_132OK }, 3948 { 40, PrivMode_132OK },
3573 // 41 xterm more fixes NYI 3949 // 41 xterm more fixes NYI
3574 // 45 margin bell NYI 3950 // 45 margin bell NYI
3575 // 46 start logging 3951 // 46 start logging
3616 3992
3617 /* extra handling for values with state unkept */ 3993 /* extra handling for values with state unkept */
3618 switch (arg[i]) 3994 switch (arg[i])
3619 { 3995 {
3620 case 1048: /* alternative cursor save */ 3996 case 1048: /* alternative cursor save */
3997 case 1049:
3621 if (Options & Opt_secondaryScreen) 3998 if (options & Opt_secondaryScreen)
3622 if (mode == 0) 3999 if (mode == 0)
3623 scr_cursor (RESTORE); 4000 scr_cursor (RESTORE);
3624 else if (mode == 1) 4001 else if (mode == 1)
3625 scr_cursor (SAVE); 4002 scr_cursor (SAVE);
3626 break; 4003 break;
3637 * within VT52 mode 4014 * within VT52 mode
3638 */ 4015 */
3639 PrivMode (1, PrivMode_vt52); 4016 PrivMode (1, PrivMode_vt52);
3640 break; 4017 break;
3641 case 3: /* 80/132 */ 4018 case 3: /* 80/132 */
3642 if (PrivateModes & PrivMode_132OK) 4019 if (priv_modes & PrivMode_132OK)
3643 set_widthheight (((state ? 132 : 80) * TermWin.fwidth), TermWin.height); 4020 set_widthheight (((state ? 132 : 80) * TermWin.fwidth), TermWin.height);
3644 break; 4021 break;
3645 case 4: /* smooth scrolling */ 4022 case 4: /* smooth scrolling */
3646 if (state) 4023 if (state)
3647 Options &= ~Opt_jumpScroll; 4024 options &= ~Opt_jumpScroll;
3648 else 4025 else
3649 Options |= Opt_jumpScroll; 4026 options |= Opt_jumpScroll;
3650 break; 4027 break;
3651 case 5: /* reverse video */ 4028 case 5: /* reverse video */
3652 scr_rvideo_mode (state); 4029 scr_rvideo_mode (state);
3653 break; 4030 break;
3654 case 6: /* relative/absolute origins */ 4031 case 6: /* relative/absolute origins */
3658 scr_autowrap (state); 4035 scr_autowrap (state);
3659 break; 4036 break;
3660 /* case 8: - auto repeat, can't do on a per window basis */ 4037 /* case 8: - auto repeat, can't do on a per window basis */
3661 case 9: /* X10 mouse reporting */ 4038 case 9: /* X10 mouse reporting */
3662 if (state) /* orthogonal */ 4039 if (state) /* orthogonal */
3663 PrivateModes &= ~PrivMode_MouseX11; 4040 priv_modes &= ~PrivMode_MouseX11;
3664 break; 4041 break;
3665#ifdef menuBar_esc 4042#ifdef menuBar_esc
3666 case menuBar_esc: 4043 case menuBar_esc:
3667#ifdef MENUBAR 4044#ifdef MENUBAR
3668 map_menuBar (state); 4045 map_menuBar (state);
3688 break; 4065 break;
3689 /* case 66: - application key pad */ 4066 /* case 66: - application key pad */
3690 /* case 67: - backspace key */ 4067 /* case 67: - backspace key */
3691 case 1000: /* X11 mouse reporting */ 4068 case 1000: /* X11 mouse reporting */
3692 if (state) /* orthogonal */ 4069 if (state) /* orthogonal */
3693 PrivateModes &= ~PrivMode_MouseX10; 4070 priv_modes &= ~PrivMode_MouseX10;
3694 break; 4071 break;
3695#if 0 4072#if 0
3696 case 1001: 4073 case 1001:
3697 break; /* X11 mouse highlighting */ 4074 break; /* X11 mouse highlighting */
3698#endif 4075#endif
3699 case 1010: /* scroll to bottom on TTY output inhibit */ 4076 case 1010: /* scroll to bottom on TTY output inhibit */
3700 if (state) 4077 if (state)
3701 Options &= ~Opt_scrollTtyOutput; 4078 options &= ~Opt_scrollTtyOutput;
3702 else 4079 else
3703 Options |= Opt_scrollTtyOutput; 4080 options |= Opt_scrollTtyOutput;
3704 break; 4081 break;
3705 case 1011: /* scroll to bottom on key press */ 4082 case 1011: /* scroll to bottom on key press */
3706 if (state) 4083 if (state)
3707 Options |= Opt_scrollTtyKeypress; 4084 options |= Opt_scrollTtyKeypress;
3708 else 4085 else
3709 Options &= ~Opt_scrollTtyKeypress; 4086 options &= ~Opt_scrollTtyKeypress;
3710 break; 4087 break;
3711 case 1047: /* secondary screen w/ clearing last */ 4088 case 1047: /* secondary screen w/ clearing last */
3712 if (Options & Opt_secondaryScreen) 4089 if (options & Opt_secondaryScreen)
3713 if (current_screen != PRIMARY) 4090 if (current_screen != PRIMARY)
3714 scr_erase_screen (2); 4091 scr_erase_screen (2);
3715 scr_change_screen (state); 4092 scr_change_screen (state);
3716 break; 4093 break;
3717 case 1049: /* secondary screen w/ clearing first */ 4094 case 1049: /* secondary screen w/ clearing first */
3718 scr_change_screen (state); 4095 scr_change_screen (state);
3719 if (Options & Opt_secondaryScreen) 4096 if (options & Opt_secondaryScreen)
3720 if (current_screen != PRIMARY) 4097 if (current_screen != PRIMARY)
3721 scr_erase_screen (2); 4098 scr_erase_screen (2);
3722 break; 4099 break;
3723 default: 4100 default:
3724 break; 4101 break;
3750 rendset = 0, rendstyle = ~RS_None; 4127 rendset = 0, rendstyle = ~RS_None;
3751 break; 4128 break;
3752 case 1: 4129 case 1:
3753 rendset = 1, rendstyle = RS_Bold; 4130 rendset = 1, rendstyle = RS_Bold;
3754 break; 4131 break;
4132 //case 2: // low intensity
4133 case 3:
4134 rendset = 1, rendstyle = RS_Italic;
4135 break;
3755 case 4: 4136 case 4:
3756 rendset = 1, rendstyle = RS_Uline; 4137 rendset = 1, rendstyle = RS_Uline;
3757 break; 4138 break;
3758 case 5: 4139 case 5: // slowly blinking
4140 case 6: // rapidly blinking
3759 rendset = 1, rendstyle = RS_Blink; 4141 rendset = 1, rendstyle = RS_Blink;
3760 break; 4142 break;
3761 //case 6: // scoansi light background 4143 //case 6: // scoansi light background
3762 case 7: 4144 case 7:
3763 rendset = 1, rendstyle = RS_RVid; 4145 rendset = 1, rendstyle = RS_RVid;
3764 break; 4146 break;
3765 case 8: 4147 case 8:
3766 // invisible. NYI 4148 // invisible. NYI
3767 break; 4149 break;
4150 //case 9: // crossed out
3768 //case 10: // scoansi acs off 4151 //case 10: // scoansi acs off, primary font
3769 //case 11: // scoansi acs on 4152 //case 11: // scoansi acs on, first alt font
3770 //case 12: // scoansi acs on, |0x80 4153 //case 12: // scoansi acs on, |0x80, second alt font
3771 case 21: // disable bold, blink and invis (some terminals use this) 4154 //...
4155 //case 19: // ninth alt font
4156 //case 20: // gothic
4157 case 21: // disable bold, faint, sometimes doubly underlined (iso 8613)
3772 rendset = 0, rendstyle = RS_Bold | RS_Blink; 4158 rendset = 0, rendstyle = RS_Bold;
3773 break; 4159 break;
3774 case 22: 4160 case 22: // normal intensity
3775 rendset = 0, rendstyle = RS_Bold; 4161 rendset = 0, rendstyle = RS_Bold;
4162 break;
4163 case 23: // disable italic
4164 rendset = 0, rendstyle = RS_Italic;
3776 break; 4165 break;
3777 case 24: 4166 case 24:
3778 rendset = 0, rendstyle = RS_Uline; 4167 rendset = 0, rendstyle = RS_Uline;
3779 break; 4168 break;
3780 case 25: 4169 case 25:
3781 rendset = 0, rendstyle = RS_Blink; 4170 rendset = 0, rendstyle = RS_Blink;
3782 break; 4171 break;
4172 case 26: // variable spacing (iso 8613)
4173 rendset = 0, rendstyle = RS_Blink;
4174 break;
3783 case 27: 4175 case 27:
3784 rendset = 0, rendstyle = RS_RVid; 4176 rendset = 0, rendstyle = RS_RVid;
3785 break; 4177 break;
3786 case 28:
3787 // visible. NYI 4178 //case 28: // visible. NYI
3788 break; 4179 //case 29: // not crossed-out
3789 } 4180 }
3790 4181
3791 if (rendset != -1) 4182 if (rendset != -1)
3792 { 4183 {
3793 scr_rendition (rendset, rendstyle); 4184 scr_rendition (rendset, rendstyle);
3804 case 35: 4195 case 35:
3805 case 36: 4196 case 36:
3806 case 37: 4197 case 37:
3807 scr_color ((unsigned int) (minCOLOR + (arg[i] - 30)), Color_fg); 4198 scr_color ((unsigned int) (minCOLOR + (arg[i] - 30)), Color_fg);
3808 break; 4199 break;
3809#ifdef TTY_256COLOR 4200 case 38: // set fg color, ISO 8613-6
3810 case 38:
3811 if (nargs > i + 2 && arg[i + 1] == 5) 4201 if (nargs > i + 2 && arg[i + 1] == 5)
3812 { 4202 {
3813 scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_fg); 4203 scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_fg);
3814 i += 2; 4204 i += 2;
3815 } 4205 }
3816 break; 4206 break;
3817#endif
3818 case 39: /* default fg */ 4207 case 39: /* default fg */
3819 scr_color (Color_fg, Color_fg); 4208 scr_color (Color_fg, Color_fg);
3820 break; 4209 break;
3821 4210
3822 case 40: 4211 case 40:
3827 case 45: 4216 case 45:
3828 case 46: 4217 case 46:
3829 case 47: 4218 case 47:
3830 scr_color ((unsigned int) (minCOLOR + (arg[i] - 40)), Color_bg); 4219 scr_color ((unsigned int) (minCOLOR + (arg[i] - 40)), Color_bg);
3831 break; 4220 break;
3832#ifdef TTY_256COLOR 4221 case 48: // set bg color, ISO 8613-6
3833 case 48:
3834 if (nargs > i + 2 && arg[i + 1] == 5) 4222 if (nargs > i + 2 && arg[i + 1] == 5)
3835 { 4223 {
3836 scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_bg); 4224 scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_bg);
3837 i += 2; 4225 i += 2;
3838 } 4226 }
3839 break; 4227 break;
3840#endif
3841 case 49: /* default bg */ 4228 case 49: /* default bg */
3842 scr_color (Color_bg, Color_bg); 4229 scr_color (Color_bg, Color_bg);
3843 break; 4230 break;
4231
4232 //case 50: // not variable spacing
3844 4233
3845#ifndef NO_BRIGHTCOLOR 4234#ifndef NO_BRIGHTCOLOR
3846 case 90: 4235 case 90:
3847 case 91: /* set bright fg color */ 4236 case 91: /* set bright fg color */
3848 case 92: 4237 case 92:
3849 case 93: 4238 case 93:
3850 case 94: 4239 case 94:
3851 case 95: 4240 case 95:
3852 case 96: 4241 case 96:
3853 case 97: 4242 case 97:
3854 scr_color ((unsigned int) (minBrightCOLOR + (arg[i] - 90)), 4243 scr_color ((unsigned int) (minBrightCOLOR + (arg[i] - 90)), Color_fg);
3855 Color_fg);
3856 break; 4244 break;
3857 case 100: 4245 case 100:
3858 case 101: /* set bright bg color */ 4246 case 101: /* set bright bg color */
3859 case 102: 4247 case 102:
3860 case 103: 4248 case 103:
3861 case 104: 4249 case 104:
3862 case 105: 4250 case 105:
3863 case 106: 4251 case 106:
3864 case 107: 4252 case 107:
3865 scr_color ((unsigned int) (minBrightCOLOR + (arg[i] - 100)), 4253 scr_color ((unsigned int) (minBrightCOLOR + (arg[i] - 100)), Color_bg);
3866 Color_bg);
3867 break; 4254 break;
3868#endif 4255#endif
3869 4256
3870 } 4257 }
3871 } 4258 }
3878{ 4265{
3879 unicode_t ch, cmd = cmd_getc (); 4266 unicode_t ch, cmd = cmd_getc ();
3880 4267
3881 if (cmd == 'Q') 4268 if (cmd == 'Q')
3882 { /* query graphics */ 4269 { /* query graphics */
3883 tt_printf ("\033G0\n"); /* no graphics */ 4270 tt_printf ("\033G0\012"); /* no graphics */
3884 return; 4271 return;
3885 } 4272 }
3886 /* swallow other graphics sequences until terminating ':' */ 4273 /* swallow other graphics sequences until terminating ':' */
3887 do 4274 do
3888 ch = cmd_getc (); 4275 ch = cmd_getc ();
3903 unsigned char buf[256]; 4290 unsigned char buf[256];
3904 4291
3905 va_start (arg_ptr, fmt); 4292 va_start (arg_ptr, fmt);
3906 vsnprintf ((char *)buf, 256, fmt, arg_ptr); 4293 vsnprintf ((char *)buf, 256, fmt, arg_ptr);
3907 va_end (arg_ptr); 4294 va_end (arg_ptr);
3908 tt_write (buf, STRLEN (buf)); 4295 tt_write (buf, strlen (buf));
3909} 4296}
3910 4297
3911/* ---------------------------------------------------------------------- */ 4298/* ---------------------------------------------------------------------- */
3912/* Write data to the pty as typed by the user, pasted with the mouse, 4299/* Write data to the pty as typed by the user, pasted with the mouse,
3913 * or generated by us in response to a query ESC sequence. 4300 * or generated by us in response to a query ESC sequence.
3914 */ 4301 */
4302const unsigned int MAX_PTY_WRITE = 255; // minimum MAX_INPUT
4303
3915void 4304void
3916rxvt_term::tt_write (const unsigned char *data, unsigned int len) 4305rxvt_term::tt_write (const unsigned char *data, unsigned int len)
3917{ 4306{
3918 enum { MAX_PTY_WRITE = 255 }; // minimum MAX_INPUT 4307 if (v_buflen == 0)
4308 {
4309 ssize_t written = write (pty.pty, data, min (len, MAX_PTY_WRITE));
3919 4310
3920 if (len) 4311 if ((unsigned int)written == len)
4312 return;
4313
4314 data += written;
4315 len -= written;
3921 { 4316 }
4317
4318 v_buffer = (unsigned char *)realloc (v_buffer, v_buflen + len);
4319
4320 memcpy (v_buffer + v_buflen, data, len);
4321 v_buflen += len;
4322
4323 pty_ev.set (EVENT_READ | EVENT_WRITE);
4324}
4325
4326void rxvt_term::pty_write ()
4327{
4328 int written = write (pty.pty, v_buffer, min (v_buflen, MAX_PTY_WRITE));
4329
4330 if (written > 0)
4331 {
4332 v_buflen -= written;
4333
3922 if (v_buflen == 0) 4334 if (v_buflen == 0)
3923 { 4335 {
3924 ssize_t written = write (cmd_fd, data, min (MAX_PTY_WRITE, len));
3925
3926 if ((unsigned int)written == len)
3927 return;
3928
3929 data += written;
3930 len -= written;
3931 }
3932
3933
3934 v_buffer = (unsigned char *)realloc (v_buffer, v_buflen + len);
3935
3936 memcpy (v_buffer + v_buflen, data, len);
3937 v_buflen += len;
3938 }
3939
3940 for (;;)
3941 {
3942 int written = write (cmd_fd, v_buffer, min (MAX_PTY_WRITE, v_buflen));
3943
3944 if (written > 0)
3945 {
3946 v_buflen -= written;
3947
3948 if (v_buflen == 0)
3949 {
3950 free (v_buffer); 4336 free (v_buffer);
3951 v_buffer = 0; 4337 v_buffer = 0;
3952 v_buflen = 0; 4338 v_buflen = 0;
3953 4339
3954 pty_ev.set (EVENT_READ); 4340 pty_ev.set (EVENT_READ);
3955 return;
3956 }
3957
3958 memmove (v_buffer, v_buffer + written, v_buflen);
3959 }
3960 else if (written != -1 || (errno != EAGAIN && errno != EINTR))
3961 // original code just ignores this...
3962 destroy ();
3963 else
3964 {
3965 pty_ev.set (EVENT_READ | EVENT_WRITE);
3966 return; 4341 return;
3967 } 4342 }
4343
4344 memmove (v_buffer, v_buffer + written, v_buflen);
3968 } 4345 }
4346 else if (written != -1 || (errno != EAGAIN && errno != EINTR))
4347 // original code just ignores this...
4348 destroy ();
3969} 4349}
3970 4350
3971/*----------------------- end-of-file (C source) -----------------------*/ 4351/*----------------------- end-of-file (C source) -----------------------*/
3972 4352

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines