tfrbox.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tfrbox.c (3008B) | |
--- | |
1 #include <u.h> | |
2 #include <libc.h> | |
3 #include <draw.h> | |
4 #include <mouse.h> | |
5 #include <frame.h> | |
6 | |
7 #define SLOP 25 | |
8 | |
9 void | |
10 _fraddbox(Frame *f, int bn, int n) /* add n boxes after bn, shift… | |
11 * box[bn+n]==box[bn] */ | |
12 { | |
13 int i; | |
14 | |
15 if(bn > f->nbox) | |
16 drawerror(f->display, "_fraddbox"); | |
17 if(f->nbox+n > f->nalloc) | |
18 _frgrowbox(f, n+SLOP); | |
19 for(i=f->nbox; --i>=bn; ) | |
20 f->box[i+n] = f->box[i]; | |
21 f->nbox+=n; | |
22 } | |
23 | |
24 void | |
25 _frclosebox(Frame *f, int n0, int n1) /* inclusive */ | |
26 { | |
27 int i; | |
28 | |
29 if(n0>=f->nbox || n1>=f->nbox || n1<n0) | |
30 drawerror(f->display, "_frclosebox"); | |
31 n1++; | |
32 for(i=n1; i<f->nbox; i++) | |
33 f->box[i-(n1-n0)] = f->box[i]; | |
34 f->nbox -= n1-n0; | |
35 } | |
36 | |
37 void | |
38 _frdelbox(Frame *f, int n0, int n1) /* inclusive */ | |
39 { | |
40 if(n0>=f->nbox || n1>=f->nbox || n1<n0) | |
41 drawerror(f->display, "_frdelbox"); | |
42 _frfreebox(f, n0, n1); | |
43 _frclosebox(f, n0, n1); | |
44 } | |
45 | |
46 void | |
47 _frfreebox(Frame *f, int n0, int n1) /* inclusive */ | |
48 { | |
49 int i; | |
50 | |
51 if(n1<n0) | |
52 return; | |
53 if(n0>=f->nbox || n1>=f->nbox) | |
54 drawerror(f->display, "_frfreebox"); | |
55 n1++; | |
56 for(i=n0; i<n1; i++) | |
57 if(f->box[i].nrune >= 0) | |
58 free(f->box[i].ptr); | |
59 } | |
60 | |
61 void | |
62 _frgrowbox(Frame *f, int delta) | |
63 { | |
64 f->nalloc += delta; | |
65 f->box = realloc(f->box, f->nalloc*sizeof(Frbox)); | |
66 if(f->box == 0) | |
67 drawerror(f->display, "_frgrowbox"); | |
68 } | |
69 | |
70 static | |
71 void | |
72 dupbox(Frame *f, int bn) | |
73 { | |
74 uchar *p; | |
75 | |
76 if(f->box[bn].nrune < 0) | |
77 drawerror(f->display, "dupbox"); | |
78 _fraddbox(f, bn, 1); | |
79 if(f->box[bn].nrune >= 0){ | |
80 p = _frallocstr(f, NBYTE(&f->box[bn])+1); | |
81 strcpy((char*)p, (char*)f->box[bn].ptr); | |
82 f->box[bn+1].ptr = p; | |
83 } | |
84 } | |
85 | |
86 static | |
87 uchar* | |
88 runeindex(uchar *p, int n) | |
89 { | |
90 int i, w; | |
91 Rune rune; | |
92 | |
93 for(i=0; i<n; i++,p+=w) | |
94 if(*p < Runeself) | |
95 w = 1; | |
96 else{ | |
97 w = chartorune(&rune, (char*)p); | |
98 USED(rune); | |
99 } | |
100 return p; | |
101 } | |
102 | |
103 static | |
104 void | |
105 truncatebox(Frame *f, Frbox *b, int n) /* drop last n chars; no a… | |
106 { | |
107 if(b->nrune<0 || b->nrune<n) | |
108 drawerror(f->display, "truncatebox"); | |
109 b->nrune -= n; | |
110 runeindex(b->ptr, b->nrune)[0] = 0; | |
111 b->wid = stringwidth(f->font, (char *)b->ptr); | |
112 } | |
113 | |
114 static | |
115 void | |
116 chopbox(Frame *f, Frbox *b, int n) /* drop first n chars; no allo… | |
117 { | |
118 char *p; | |
119 | |
120 if(b->nrune<0 || b->nrune<n) | |
121 drawerror(f->display, "chopbox"); | |
122 p = (char*)runeindex(b->ptr, n); | |
123 memmove((char*)b->ptr, p, strlen(p)+1); | |
124 b->nrune -= n; | |
125 b->wid = stringwidth(f->font, (char *)b->ptr); | |
126 } | |
127 | |
128 void | |
129 _frsplitbox(Frame *f, int bn, int n) | |
130 { | |
131 dupbox(f, bn); | |
132 truncatebox(f, &f->box[bn], f->box[bn].nrune-n); | |
133 chopbox(f, &f->box[bn+1], n); | |
134 } | |
135 | |
136 void | |
137 _frmergebox(Frame *f, int bn) /* merge bn and bn+1 */ | |
138 { | |
139 Frbox *b; | |
140 | |
141 b = &f->box[bn]; | |
142 _frinsure(f, bn, NBYTE(&b[0])+NBYTE(&b[1])+1); | |
143 strcpy((char*)runeindex(b[0].ptr, b[0].nrune), (char*)b[1].ptr); | |
144 b[0].wid += b[1].wid; | |
145 b[0].nrune += b[1].nrune; | |
146 _frdelbox(f, bn+1, bn+1); | |
147 } | |
148 | |
149 int | |
150 _frfindbox(Frame *f, int bn, ulong p, ulong q) /* find box contai… | |
151 { | |
152 Frbox *b; | |
153 | |
154 for(b = &f->box[bn]; bn<f->nbox && p+NRUNE(b)<=q; bn++, b++) | |
155 p += NRUNE(b); | |
156 if(p != q) | |
157 _frsplitbox(f, bn++, (int)(q-p)); | |
158 return bn; | |
159 } |