cache.c - ledit - Text editor (WIP) | |
git clone git://lumidify.org/ledit.git (fast, but not encrypted) | |
git clone https://lumidify.org/ledit.git (encrypted, but very slow) | |
git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/… | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
cache.c (5114B) | |
--- | |
1 #include <stdio.h> | |
2 #include <limits.h> | |
3 #include <stdlib.h> | |
4 #include <X11/Xlib.h> | |
5 #include <X11/Xutil.h> | |
6 #include <pango/pangoxft.h> | |
7 #include <X11/extensions/Xdbe.h> | |
8 | |
9 #include "util.h" | |
10 #include "common.h" | |
11 #include "memory.h" | |
12 #include "cache.h" | |
13 #include "assert.h" | |
14 | |
15 ledit_cache * | |
16 cache_create(Display *dpy) { | |
17 ledit_cache *cache = ledit_malloc(sizeof(ledit_cache)); | |
18 cache->dpy = dpy; | |
19 cache->pixmaps = ledit_reallocarray(NULL, PIXMAP_CACHE_INITIAL_S… | |
20 cache->layouts = ledit_reallocarray(NULL, LAYOUT_CACHE_SIZE, siz… | |
21 for (size_t i = 0; i < PIXMAP_CACHE_INITIAL_SIZE; i++) { | |
22 cache->pixmaps[i].pixmap = None; | |
23 cache->pixmaps[i].draw = NULL; | |
24 cache->pixmaps[i].line = 0; | |
25 cache->pixmaps[i].valid = 0; | |
26 } | |
27 for (size_t i = 0; i < LAYOUT_CACHE_SIZE; i++) { | |
28 cache->layouts[i].layout = NULL; | |
29 cache->layouts[i].line = 0; | |
30 cache->layouts[i].valid = 0; | |
31 } | |
32 cache->num_pixmaps = PIXMAP_CACHE_INITIAL_SIZE; | |
33 cache->num_layouts = LAYOUT_CACHE_SIZE; | |
34 cache->cur_pixmap_index = cache->cur_layout_index = 0; | |
35 return cache; | |
36 } | |
37 | |
38 void | |
39 cache_flush( | |
40 ledit_cache *cache, void *callback_data, | |
41 void (*invalidate_pixmap_line)(void *, size_t), | |
42 void (*invalidate_layout_line)(void *, size_t)) { | |
43 cache_invalidate_from_line( | |
44 cache, 0, callback_data, invalidate_pixmap_line, invalidate_… | |
45 ); | |
46 } | |
47 | |
48 void | |
49 cache_invalidate_from_line( | |
50 ledit_cache *cache, size_t start, void *callback_data, | |
51 void (*invalidate_pixmap_line)(void *, size_t), | |
52 void (*invalidate_layout_line)(void *, size_t)) { | |
53 for (size_t i = 0; i < cache->num_pixmaps; i++) { | |
54 if (cache->pixmaps[i].line >= start) { | |
55 invalidate_pixmap_line(callback_data, cache->pix… | |
56 cache->pixmaps[i].line = 0; | |
57 cache->pixmaps[i].valid = 0; | |
58 } | |
59 } | |
60 for (size_t i = 0; i < cache->num_layouts; i++) { | |
61 if (cache->layouts[i].line >= start) { | |
62 invalidate_layout_line(callback_data, cache->lay… | |
63 cache->layouts[i].line = 0; | |
64 cache->layouts[i].valid = 0; | |
65 } | |
66 } | |
67 } | |
68 | |
69 void | |
70 cache_destroy(ledit_cache *cache) { | |
71 for (size_t i = 0; i < cache->num_pixmaps; i++) { | |
72 if (cache->pixmaps[i].pixmap != None) | |
73 XFreePixmap(cache->dpy, cache->pixmaps[i].pixmap… | |
74 if (cache->pixmaps[i].draw != NULL) | |
75 XftDrawDestroy(cache->pixmaps[i].draw); | |
76 } | |
77 for (size_t i = 0; i < cache->num_layouts; i++) { | |
78 if (cache->layouts[i].layout != NULL) | |
79 g_object_unref(cache->layouts[i].layout); | |
80 } | |
81 free(cache->pixmaps); | |
82 free(cache->layouts); | |
83 free(cache); | |
84 } | |
85 | |
86 cache_pixmap * | |
87 cache_get_pixmap(ledit_cache *cache, size_t index) { | |
88 ledit_assert(index < cache->num_pixmaps); | |
89 return &cache->pixmaps[index]; | |
90 } | |
91 | |
92 cache_layout * | |
93 cache_get_layout(ledit_cache *cache, size_t index) { | |
94 ledit_assert(index < cache->num_layouts); | |
95 return &cache->layouts[index]; | |
96 } | |
97 | |
98 /* FIXME: max pixmap cache size */ | |
99 void | |
100 cache_assign_pixmap_index( | |
101 ledit_cache *cache, size_t line, | |
102 void *callback_data, | |
103 int (*line_needed)(void *, size_t), | |
104 void (*set_pixmap_line)(void *, size_t, size_t), | |
105 void (*invalidate_pixmap_line)(void *, size_t)) { | |
106 size_t line_index; | |
107 size_t entry_index; | |
108 for (size_t i = 0; i <= cache->num_pixmaps; i++) { | |
109 entry_index = (i + cache->cur_pixmap_index) % cache->num… | |
110 line_index = cache->pixmaps[entry_index].line; | |
111 int valid = cache->pixmaps[entry_index].valid; | |
112 /* replace line when entry isn't assigned or currently a… | |
113 if (!valid || | |
114 (valid && !line_needed(callback_data, line_index))) { | |
115 cache->cur_pixmap_index = (entry_index + 1) % ca… | |
116 cache_pixmap *pix = &cache->pixmaps[entry_index]; | |
117 if (pix->valid) | |
118 invalidate_pixmap_line(callback_data, pi… | |
119 pix->line = line; | |
120 pix->valid = 1; | |
121 set_pixmap_line(callback_data, line, entry_index… | |
122 return; | |
123 } | |
124 } | |
125 | |
126 /* no free entry found, increase cache size */ | |
127 /* FIXME: maybe have maximum cache size */ | |
128 size_t new_alloc = ideal_array_size(cache->num_pixmaps, add_sz(c… | |
129 cache->pixmaps = ledit_reallocarray(cache->pixmaps, new_alloc, s… | |
130 entry_index = cache->num_pixmaps; | |
131 for (size_t i = cache->num_pixmaps; i < cache->num_pixmaps * 2; … | |
132 cache->pixmaps[i].line = 0; | |
133 cache->pixmaps[i].valid = 0; | |
134 cache->pixmaps[i].pixmap = None; | |
135 cache->pixmaps[i].draw = NULL; | |
136 } | |
137 cache->num_pixmaps *= 2; | |
138 cache_pixmap *pix = &cache->pixmaps[entry_index]; | |
139 pix->line = line; | |
140 pix->valid = 1; | |
141 set_pixmap_line(callback_data, line, entry_index); | |
142 } | |
143 | |
144 /* FIXME: perhaps use "real" clock cache management, i.e. set a bit on a… | |
145 when it is used so it isn't invalidated yet. */ | |
146 void cache_assign_layout_index( | |
147 ledit_cache *cache, size_t line, | |
148 void *callback_data, | |
149 void (*set_layout_line)(void *, size_t, size_t), | |
150 void (*invalidate_layout_line)(void *, size_t)) { | |
151 size_t old = cache->cur_layout_index; | |
152 cache->cur_layout_index = (cache->cur_layout_index + 1) % cache-… | |
153 cache_layout *layout = &cache->layouts[old]; | |
154 if (layout->valid) | |
155 invalidate_layout_line(callback_data, layout->line); | |
156 layout->valid = 1; | |
157 layout->line = line; | |
158 set_layout_line(callback_data, line, old); | |
159 } |