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
));
61 k8t_tmFullDirty(curterm
);
62 k8t_drawTerm(curterm
, 1);
63 if (!updateTabBar
) updateTabBar
= 1;
66 //FIXME: optimize memory allocations
67 if (curterm
->sel
.clip
!= NULL
&& curterm
->sel
.bx
>= 0) {
68 if (lastSelStr
!= NULL
) {
69 if (strlen(lastSelStr
) >= strlen(curterm
->sel
.clip
)) {
70 strcpy(lastSelStr
, curterm
->sel
.clip
);
76 if (lastSelStr
== NULL
) lastSelStr
= strdup(curterm
->sel
.clip
);
77 //fprintf(stderr, "newsel: [%s]\n", lastSelStr);
80 //fprintf(stderr, "curterm #%d\n", termidx);
81 //fprintf(stderr, "needConv: %d\n", curterm->needConv);
86 static K8Term
*k8t_termalloc (void) {
89 if (term_count
>= term_array_size
) {
90 int newsz
= ((term_count
==0) ? 1 : term_array_size
+64);
91 K8Term
**n
= realloc(term_array
, sizeof(K8Term
*)*newsz
);
93 if (n
== NULL
&& term_count
== 0) k8t_die("out of memory!");
95 term_array_size
= newsz
;
97 if ((t
= calloc(1, sizeof(K8Term
))) == NULL
) return NULL
;
99 t
->wrbufsize
= K8T_WBUFSIZ
;
100 t
->deffg
= defaultFG
;
101 t
->defbg
= defaultBG
;
103 t
->needConv
= (needConversion
? 1 : 0);
104 t
->belltype
= (opt_audiblebell
?K8T_BELL_AUDIO
:0)|(opt_urgentbell
?K8T_BELL_URGENT
:0);
105 t
->curblink
= opt_cursorBlink
;
106 t
->curblinkinactive
= opt_cursorBlinkInactive
;
107 t
->fastredraw
= opt_fastredraw
;
112 term_array
[term_count
++] = t
;
118 // newer delete last terminal!
119 static void termfree (int idx
) {
120 if (idx
>= 0 && idx
< term_count
&& term_array
[idx
] != NULL
) {
121 K8Term
*t
= term_array
[idx
];
122 K8TermData
*td
= K8T_DATA(t
);
124 if (K8T_DATA(t
)->pid
!= 0) {
125 kill(K8T_DATA(t
)->pid
, SIGKILL
);
134 exitcode
= K8T_DATA(t
)->exitcode
;
136 if (K8T_DATA(t
)->waitkeypress
) return;
138 if (idx
== termidx
) {
139 if (term_count
> 1) {
141 //switchToTerm((idx > 0) ? idx-1 : 1, 0);
142 switchToTerm(findTermToSwitch(), 0);
148 for (int y
= 0; y
< t
->row
; ++y
) free(t
->alt
[y
]);
149 for (int y
= 0; y
< t
->linecount
; ++y
) free(t
->line
[y
]);
154 if (td
->execcmd
!= NULL
) free(td
->execcmd
);
156 if (termidx
> idx
) --termidx
; // it's not current, and current is at the right
157 for (int f
= idx
+1; f
< term_count
; ++f
) term_array
[f
-1] = term_array
[f
];
160 //if (td->picalloced) XFreePixmap(xw.dpy, td->picbuf);
167 static void termcleanup (void) {
168 int f
= 0, needredraw
= 0;
170 while (f
< term_count
) {
171 if (term_array
[f
]->dead
) {
181 k8t_drawTerm(curterm
, 1);