1 ////////////////////////////////////////////////////////////////////////////////
2 static void fixWindowTitle (const K8Term
*t
) {
4 const char *title
= (t
!= NULL
) ? t
->title
: NULL
;
6 if (title
== NULL
|| !title
[0]) {
8 if (title
== NULL
) title
= "";
10 XStoreName(xw
.dpy
, xw
.win
, title
);
11 XChangeProperty(xw
.dpy
, xw
.win
, XA_NETWM_NAME
, XA_UTF8
, 8, PropModeReplace
, (const unsigned char *)title
, strlen(title
));
16 // find latest active terminal (but not current %-)
17 static int findTermToSwitch (void) {
18 int maxlat
= -1, idx
= -1;
20 for (int f
= 0; f
< term_count
; ++f
) {
21 if (curterm
!= term_array
[f
] && term_array
[f
]->lastActiveTime
> maxlat
) {
22 maxlat
= term_array
[f
]->lastActiveTime
;
27 if (termidx
== 0) idx
= 0; else idx
= termidx
+1;
28 if (idx
> term_count
) idx
= term_count
-1;
34 static void fixFirstTab (void) {
35 if (termidx
< firstVisibleTab
) firstVisibleTab
= termidx
;
36 else if (termidx
> firstVisibleTab
+opt_tabcount
-1) firstVisibleTab
= termidx
-opt_tabcount
+1;
37 if (firstVisibleTab
< 0) firstVisibleTab
= 0;
42 static void switchToTerm (int idx
, int redraw
) {
43 if (idx
>= 0 && idx
< term_count
&& term_array
[idx
] != NULL
&& term_array
[idx
] != curterm
) {
44 K8TTimeMSec tt
= mclock_ticks();
46 if (curterm
!= NULL
) curterm
->lastActiveTime
= tt
;
48 curterm
= term_array
[termidx
];
49 curterm
->curbhidden
= 0;
50 curterm
->lastBlinkTime
= tt
;
55 k8t_tmFullDirty(curterm
);
56 fixWindowTitle(curterm
);
58 XSetWindowBackground(xw
.dpy
, xw
.win
, getColor(curterm
->defbg
));
60 if (redraw
) { k8t_drawTerm(curterm
, 1); xdrawTabBar(); }
61 //FIXME: optimize memory allocations
62 if (curterm
->sel
.clip
!= NULL
&& curterm
->sel
.bx
>= 0) {
63 if (lastSelStr
!= NULL
) free(lastSelStr
);
64 lastSelStr
= strdup(curterm
->sel
.clip
);
65 //fprintf(stderr, "newsel: [%s]\n", lastSelStr);
68 //fprintf(stderr, "curterm #%d\n", termidx);
69 //fprintf(stderr, "needConv: %d\n", curterm->needConv);
74 static K8Term
*k8t_termalloc (void) {
77 if (term_count
>= term_array_size
) {
78 int newsz
= ((term_count
==0) ? 1 : term_array_size
+64);
79 K8Term
**n
= realloc(term_array
, sizeof(K8Term
*)*newsz
);
81 if (n
== NULL
&& term_count
== 0) k8t_die("out of memory!");
83 term_array_size
= newsz
;
85 if ((t
= calloc(1, sizeof(K8Term
))) == NULL
) return NULL
;
87 t
->wrbufsize
= K8T_WBUFSIZ
;
91 t
->needConv
= (needConversion
? 1 : 0);
92 t
->belltype
= (opt_audiblebell
?K8T_BELL_AUDIO
:0)|(opt_urgentbell
?K8T_BELL_URGENT
:0);
93 t
->curblink
= opt_cursorBlink
;
94 t
->curblinkinactive
= opt_cursorBlinkInactive
;
95 t
->fastredraw
= opt_fastredraw
;
100 term_array
[term_count
++] = t
;
106 // newer delete last terminal!
107 static void termfree (int idx
) {
108 if (idx
>= 0 && idx
< term_count
&& term_array
[idx
] != NULL
) {
109 K8Term
*t
= term_array
[idx
];
110 K8TermData
*td
= K8T_DATA(t
);
112 if (K8T_DATA(t
)->pid
!= 0) {
113 kill(K8T_DATA(t
)->pid
, SIGKILL
);
122 exitcode
= K8T_DATA(t
)->exitcode
;
124 if (K8T_DATA(t
)->waitkeypress
) return;
126 if (idx
== termidx
) {
127 if (term_count
> 1) {
129 //switchToTerm((idx > 0) ? idx-1 : 1, 0);
130 switchToTerm(findTermToSwitch(), 0);
136 for (int y
= 0; y
< t
->row
; ++y
) free(t
->alt
[y
]);
137 for (int y
= 0; y
< t
->linecount
; ++y
) free(t
->line
[y
]);
142 if (td
->execcmd
!= NULL
) free(td
->execcmd
);
144 if (termidx
> idx
) --termidx
; // it's not current, and current is at the right
145 for (int f
= idx
+1; f
< term_count
; ++f
) term_array
[f
-1] = term_array
[f
];
148 //if (td->picalloced) XFreePixmap(xw.dpy, td->picbuf);
155 static void termcleanup (void) {
156 int f
= 0, needredraw
= 0;
158 while (f
< term_count
) {
159 if (term_array
[f
]->dead
) {
169 k8t_drawTerm(curterm
, 1);