commit eaee011ce47b2f57527a241a53dded691735770f
parent 1207520e0aa5ec1696924646f850b1c4a8bc57ed
Author: lumidify <nobody@lumidify.org>
Date: Fri, 29 May 2020 20:22:21 +0200
Add preparations for adding dropdowns
Diffstat:
M | button.c | | | 23 | ++++++++++++----------- |
M | grid.c | | | 6 | +++--- |
M | ltk.c | | | 220 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ |
M | ltk.h | | | 38 | ++++++++++++++++++-------------------- |
M | text_buffer.c | | | 28 | ++++++++++++++-------------- |
M | text_common.c | | | 2 | -- |
M | text_edit.c | | | 21 | ++++++++++++--------- |
7 files changed, 229 insertions(+), 109 deletions(-)
diff --git a/button.c b/button.c
@@ -36,8 +36,6 @@
#include "text_buffer.h"
#include "button.h"
-extern Ltk *ltk_global;
-
void
ltk_button_ini_handler(LtkTheme *theme, const char *prop, const char *value) {
if (theme->button == NULL) {
@@ -78,7 +76,8 @@ ltk_button_ini_handler(LtkTheme *theme, const char *prop, const char *value) {
void
ltk_button_draw(LtkButton *button) {
- LtkButtonTheme *theme = ltk_global->theme->button;
+ LtkTheme *global_theme = ltk_get_theme();
+ LtkButtonTheme *theme = global_theme->button;
LtkWindow *window = button->widget.window;
LtkRect rect = button->widget.rect;
int bw = theme->border_width;
@@ -116,15 +115,17 @@ ltk_button_draw(LtkButton *button) {
default:
ltk_fatal("No style found for button!\n");
}
- XSetForeground(ltk_global->display, window->gc, fill.pixel);
- XFillRectangle(ltk_global->display, window->xwindow, window->gc, rect.x, rect.y, rect.w, rect.h);
+ Display *display = ltk_get_display();
+ Colormap colormap = ltk_get_colormap();
+ XSetForeground(display, window->gc, fill.pixel);
+ XFillRectangle(display, window->xwindow, window->gc, rect.x, rect.y, rect.w, rect.h);
/* FIXME: Why did I do this? */
if (bw < 1) return;
- XSetForeground(ltk_global->display, window->gc, border.pixel);
- XSetLineAttributes(ltk_global->display, window->gc, bw, LineSolid, CapButt, JoinMiter);
- XDrawRectangle(ltk_global->display, window->xwindow, window->gc, rect.x + bw / 2, rect.y + bw / 2, rect.w - bw, rect.h - bw);
+ XSetForeground(display, window->gc, border.pixel);
+ XSetLineAttributes(display, window->gc, bw, LineSolid, CapButt, JoinMiter);
+ XDrawRectangle(display, window->xwindow, window->gc, rect.x + bw / 2, rect.y + bw / 2, rect.w - bw, rect.h - bw);
if (!img) {
- img = ltk_text_line_render(button->tl, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, theme->text_color, fill);
+ img = ltk_text_line_render(button->tl, display, window->xwindow, window->gc, colormap, theme->text_color, fill);
/* FIXME: any nicer way to do this? */
switch (button->widget.state) {
case LTK_NORMAL:
@@ -147,7 +148,7 @@ ltk_button_draw(LtkButton *button) {
}
text_x = rect.x + (rect.w - button->tl->w) / 2;
text_y = rect.y + (rect.h - button->tl->h) / 2;
- XPutImage(ltk_global->display, window->xwindow, window->gc, img, 0, 0, text_x, text_y, button->tl->w, button->tl->h);
+ XPutImage(display, window->xwindow, window->gc, img, 0, 0, text_x, text_y, button->tl->w, button->tl->h);
}
LtkButton *
@@ -163,7 +164,7 @@ ltk_button_create(LtkWindow *window, const char *text, void (*callback) (void *,
button->callback = callback;
button->data = data;
- LtkTheme *theme = ltk_global->theme;
+ LtkTheme *theme = ltk_get_theme();
button->tl = ltk_text_line_create(theme->button->font_size);
/* FIXME: support font size */
ltk_text_line_insert_utf8(button->tl, 0, text);
diff --git a/grid.c b/grid.c
@@ -247,7 +247,7 @@ void ltk_grid_mouse_press(LtkGrid *grid, XEvent event)
return;
LtkWidget *ptr = grid->widget_grid[row * grid->columns + column];
if (ptr && ltk_collide_rect(ptr->rect, x, y)) {
- ltk_mouse_press_event(ptr, event);
+ ltk_widget_mouse_press_event(ptr, event);
}
}
@@ -262,7 +262,7 @@ void ltk_grid_mouse_release(LtkGrid *grid, XEvent event)
LtkWidget *ptr = grid->widget_grid[row * grid->columns + column];
if (ptr) {
if (ltk_collide_rect(ptr->rect, x, y)) {
- ltk_mouse_release_event(ptr, event);
+ ltk_widget_mouse_release_event(ptr, event);
} else {
ltk_remove_hover_widget(grid);
ltk_change_active_widget_state(grid, LTK_ACTIVE);
@@ -284,7 +284,7 @@ void ltk_grid_motion_notify(LtkGrid *grid, XEvent event)
LtkWidget *ptr = grid->widget_grid[row * grid->columns + column];
if (ptr) {
if (ltk_collide_rect(ptr->rect, x, y))
- ltk_motion_notify_event(ptr, event);
+ ltk_widget_motion_notify_event(ptr, event);
else if (!pressed)
ltk_remove_hover_widget(grid);
}
diff --git a/ltk.c b/ltk.c
@@ -27,22 +27,54 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "khash.h"
-#include "ltk.h"
#include "stb_truetype.h"
#include <fribidi.h>
#include <harfbuzz/hb.h>
#include <fontconfig/fontconfig.h>
#include "array.h"
#include "text_common.h"
+#include "ltk.h"
#include "text_buffer.h"
-Ltk *ltk_global;
+/* Window hash */
+KHASH_MAP_INIT_INT(winhash, LtkWindow*)
+
+static struct {
+ LtkTheme *theme;
+ LtkTextManager *tm;
+ Display *display;
+ int screen;
+ Colormap colormap;
+ khash_t(winhash) *window_hash;
+ int window_num;
+ Atom wm_delete_msg;
+} ltk_global;
struct ltk_redraw_queue {
LtkWindow *window;
LtkRect rect;
};
+LtkTextManager *
+ltk_get_text_manager(void) {
+ return ltk_global.tm;
+}
+
+LtkTheme *
+ltk_get_theme(void) {
+ return ltk_global.theme;
+}
+
+Display *
+ltk_get_display(void) {
+ return ltk_global.display;
+}
+
+Colormap
+ltk_get_colormap(void) {
+ return ltk_global.colormap;
+}
+
static struct ltk_redraw_queue *redraw_queue = NULL;
static int num_redraws = 0;
static int redraw_queue_bufsize = 0;
@@ -93,31 +125,65 @@ error:
}
void
+ltk_widget_set_floating_collision(LtkWidget *widget) {
+ LtkWindow *window = widget->window;
+ for (int i = 0; i < window->num_float_widgets; i++) {
+ if (window->float_widgets[i] == widget)
+ return;
+ }
+ if (window->num_float_widgets + 1 > window->max_float_widgets) {
+ LtkWidget **new = realloc(
+ window->float_widgets,
+ sizeof(LtkWidget *) * (window->max_float_widgets + 1));
+ if (!new) goto error;
+ window->float_widgets = new;
+ window->max_float_widgets++;
+ }
+ window->float_widgets[window->num_float_widgets] = widget;
+ window->num_float_widgets++;
+ return;
+error:
+ (void)fprintf(stderr, "Out of memory\n");
+ exit(1);
+}
+
+void
+ltk_widget_unset_floating_collision(LtkWidget *widget) {
+ LtkWindow *window = widget->window;
+ for (int i = 0; i < window->num_float_widgets; i++) {
+ if (window->float_widgets[i] == widget) {
+ for (int j = i + 1; j < window->num_float_widgets; j++) {
+ window->float_widgets[j - 1] = window->float_widgets[j];
+ }
+ window->num_float_widgets--;
+ break;
+ }
+ }
+}
+
+void
ltk_init(const char *theme_path) {
- ltk_global = malloc(sizeof(Ltk));
- Ltk *ltk = ltk_global; /* For convenience */
- ltk->display = XOpenDisplay(NULL);
- ltk->screen = DefaultScreen(ltk->display);
- ltk->colormap = DefaultColormap(ltk->display, ltk->screen);
- ltk->theme = ltk_load_theme(theme_path);
- ltk->window_hash = kh_init(winhash);
- ltk->wm_delete_msg = XInternAtom(ltk->display, "WM_DELETE_WINDOW", False);
- ltk->tm = ltk_init_text(ltk->theme->window->font);
+ ltk_global.display = XOpenDisplay(NULL);
+ ltk_global.screen = DefaultScreen(ltk_global.display);
+ ltk_global.colormap = DefaultColormap(ltk_global.display, ltk_global.screen);
+ ltk_global.theme = ltk_load_theme(theme_path);
+ ltk_global.window_hash = kh_init(winhash);
+ ltk_global.wm_delete_msg = XInternAtom(ltk_global.display, "WM_DELETE_WINDOW", False);
+ ltk_global.tm = ltk_init_text(ltk_global.theme->window->font);
}
void
ltk_clean_up(void) {
LtkWindow *window;
- for (int k = kh_begin(ltk_global->window_hash); k != kh_end(ltk_global->window_hash); k++) {
- if (kh_exist(ltk_global->window_hash, k)) {
- ltk_destroy_window(kh_value(ltk_global->window_hash, k));
+ for (int k = kh_begin(ltk_global.window_hash); k != kh_end(ltk_global.window_hash); k++) {
+ if (kh_exist(ltk_global.window_hash, k)) {
+ ltk_destroy_window(kh_value(ltk_global.window_hash, k));
}
}
- kh_destroy(winhash, ltk_global->window_hash);
- XCloseDisplay(ltk_global->display);
- ltk_destroy_theme(ltk_global->theme);
- ltk_destroy_text_manager(ltk_global->tm);
- free(ltk_global);
+ kh_destroy(winhash, ltk_global.window_hash);
+ XCloseDisplay(ltk_global.display);
+ ltk_destroy_theme(ltk_global.theme);
+ ltk_destroy_text_manager(ltk_global.tm);
if (redraw_queue) free(redraw_queue);
}
@@ -137,9 +203,9 @@ ltk_fatal(const char *msg) {
XColor
ltk_create_xcolor(const char *hex) {
XColor color;
- XParseColor(ltk_global->display, ltk_global->colormap, hex,
+ XParseColor(ltk_global.display, ltk_global.colormap, hex,
&color);
- XAllocColor(ltk_global->display, ltk_global->colormap, &color);
+ XAllocColor(ltk_global.display, ltk_global.colormap, &color);
return color;
}
@@ -152,8 +218,8 @@ ltk_mainloop(void) {
/* FIXME: compress motion events */
while (1) {
- if (XPending(ltk_global->display) || !num_redraws) {
- XNextEvent(ltk_global->display, &event);
+ if (XPending(ltk_global.display) || !num_redraws) {
+ XNextEvent(ltk_global.display, &event);
ltk_handle_event(event);
} else if (num_redraws) {
for (int i = 0; i < num_redraws; i++)
@@ -173,7 +239,7 @@ ltk_redraw_window(LtkWindow *window, LtkRect rect) {
rect.w -= rect.x + rect.w - window->rect.w;
if (rect.y + rect.h > window->rect.h)
rect.h -= rect.y + rect.h - window->rect.h;
- XClearArea(ltk_global->display, window->xwindow, rect.x, rect.y, rect.w, rect.h, False);
+ XClearArea(ltk_global.display, window->xwindow, rect.x, rect.y, rect.w, rect.h, False);
if (!window->root_widget) return;
ptr = window->root_widget;
ptr->draw(ptr);
@@ -184,8 +250,8 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int
LtkWindow *window = malloc(sizeof(LtkWindow));
if (!window)
ltk_fatal("Not enough memory left for window!\n");
- LtkWindowTheme *wtheme = ltk_global->theme->window; /* For convenience */
- Display *display = ltk_global->display; /* For convenience */
+ LtkWindowTheme *wtheme = ltk_global.theme->window; /* For convenience */
+ Display *display = ltk_global.display; /* For convenience */
window->xwindow =
XCreateSimpleWindow(display, DefaultRootWindow(display), x, y,
w, h, wtheme->border_width,
@@ -196,7 +262,7 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int
XSetStandardProperties(display, window->xwindow, title, NULL, None,
NULL, 0, NULL);
XSetWMProtocols(display, window->xwindow,
- <k_global->wm_delete_msg, 1);
+ <k_global.wm_delete_msg, 1);
window->root_widget = NULL;
window->other_event = <k_window_other_event;
@@ -206,6 +272,10 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int
window->rect.x = 0;
window->rect.y = 0;
+ window->num_float_widgets = 0;
+ window->max_float_widgets = 0;
+ window->float_widgets = NULL;
+
XClearWindow(display, window->xwindow);
XMapRaised(display, window->xwindow);
XSelectInput(display, window->xwindow,
@@ -214,9 +284,9 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int
StructureNotifyMask | PointerMotionMask);
int ret;
- int k = kh_put(winhash, ltk_global->window_hash, window->xwindow, &ret);
- kh_value(ltk_global->window_hash, k) = window;
- ltk_global->window_num++;
+ int k = kh_put(winhash, ltk_global.window_hash, window->xwindow, &ret);
+ kh_value(ltk_global.window_hash, k) = window;
+ ltk_global.window_num++;
return window;
}
@@ -225,20 +295,20 @@ void
ltk_remove_window(LtkWindow *window) {
/* FIXME: also remove from event queue */
ltk_destroy_window(window);
- if (ltk_global->window_num == 0)
+ if (ltk_global.window_num == 0)
ltk_quit();
}
void
ltk_destroy_window(LtkWindow * window) {
- int k = kh_get(winhash, ltk_global->window_hash, window->xwindow);
- kh_del(winhash, ltk_global->window_hash, k);
+ int k = kh_get(winhash, ltk_global.window_hash, window->xwindow);
+ kh_del(winhash, ltk_global.window_hash, k);
LtkWidget *ptr = window->root_widget;
if (ptr)
ptr->destroy(ptr);
- XDestroyWindow(ltk_global->display, window->xwindow);
+ XDestroyWindow(ltk_global.display, window->xwindow);
free(window);
- ltk_global->window_num--;
+ ltk_global.window_num--;
}
void
@@ -267,7 +337,7 @@ ltk_window_other_event(LtkWindow *window, XEvent event) {
r.h = event.xexpose.height;
ltk_window_invalidate_rect(window, r);
} else if (event.type == ClientMessage
- && event.xclient.data.l[0] == ltk_global->wm_delete_msg) {
+ && event.xclient.data.l[0] == ltk_global.wm_delete_msg) {
ltk_remove_window(window);
}
}
@@ -405,6 +475,10 @@ ltk_fill_widget_defaults(LtkWidget *widget, LtkWindow *window,
widget->rect.y = 0;
widget->rect.w = 100;
widget->rect.h = 100;
+ widget->collision_rect.x = 0;
+ widget->collision_rect.y = 0;
+ widget->collision_rect.w = 0;
+ widget->collision_rect.h = 0;
widget->row = NULL;
widget->column = NULL;
@@ -414,7 +488,7 @@ ltk_fill_widget_defaults(LtkWidget *widget, LtkWindow *window,
}
void
-ltk_mouse_press_event(void *widget, XEvent event) {
+ltk_widget_mouse_press_event(void *widget, XEvent event) {
LtkWidget *ptr = widget;
if (!ptr || ptr->state == LTK_DISABLED)
return;
@@ -434,7 +508,24 @@ ltk_mouse_press_event(void *widget, XEvent event) {
}
void
-ltk_mouse_release_event(void *widget, XEvent event) {
+ltk_window_mouse_press_event(LtkWindow *window, XEvent event) {
+ if (window->float_widgets) {
+ int x = event.xbutton.x;
+ int y = event.xbutton.y;
+ for (int i = 0; i < window->num_float_widgets; i++) {
+ if (ltk_collide_rect(window->float_widgets[i]->collision_rect, x, y)) {
+ ltk_widget_mouse_press_event(window->float_widgets[i], event);
+ return;
+ }
+ }
+ }
+ if (window->root_widget) {
+ ltk_widget_mouse_press_event(window->root_widget, event);
+ }
+}
+
+void
+ltk_widget_mouse_release_event(void *widget, XEvent event) {
LtkWidget *ptr = widget;
if (!ptr || ptr->state == LTK_DISABLED)
return;
@@ -449,11 +540,27 @@ ltk_mouse_release_event(void *widget, XEvent event) {
}
void
-ltk_motion_notify_event(void *widget, XEvent event) {
+ltk_window_mouse_release_event(LtkWindow *window, XEvent event) {
+ if (window->float_widgets) {
+ int x = event.xbutton.x;
+ int y = event.xbutton.y;
+ for (int i = 0; i < window->num_float_widgets; i++) {
+ if (ltk_collide_rect(window->float_widgets[i]->collision_rect, x, y)) {
+ ltk_widget_mouse_release_event(window->float_widgets[i], event);
+ return;
+ }
+ }
+ }
+ if (window->root_widget) {
+ ltk_widget_mouse_release_event(window->root_widget, event);
+ }
+}
+
+void
+ltk_widget_motion_notify_event(void *widget, XEvent event) {
LtkWidget *ptr = widget;
LtkWidget *parent;
- if (!ptr)
- return;
+ if (!ptr) return;
short pressed = (event.xmotion.state & Button1Mask) == Button1Mask;
if ((ptr->state == LTK_NORMAL || ptr->state == LTK_ACTIVE)
&& !pressed) {
@@ -472,28 +579,41 @@ ltk_motion_notify_event(void *widget, XEvent event) {
}
void
+ltk_window_motion_notify_event(LtkWindow *window, XEvent event) {
+ if (window->float_widgets) {
+ int x = event.xbutton.x;
+ int y = event.xbutton.y;
+ for (int i = 0; i < window->num_float_widgets; i++) {
+ if (ltk_collide_rect(window->float_widgets[i]->collision_rect, x, y)) {
+ ltk_widget_motion_notify_event(window->float_widgets[i], event);
+ return;
+ }
+ }
+ }
+ if (window->root_widget) {
+ ltk_widget_motion_notify_event(window->root_widget, event);
+ }
+}
+
+void
ltk_handle_event(XEvent event) {
LtkWidget *root_widget;
- int k = kh_get(winhash, ltk_global->window_hash, event.xany.window);
- LtkWindow *window = kh_value(ltk_global->window_hash, k);
+ int k = kh_get(winhash, ltk_global.window_hash, event.xany.window);
+ LtkWindow *window = kh_value(ltk_global.window_hash, k);
if (!window) return;
- root_widget = window->root_widget;
switch (event.type) {
case KeyPress:
break;
case KeyRelease:
break;
case ButtonPress:
- if (root_widget)
- ltk_mouse_press_event(root_widget, event);
+ ltk_window_mouse_press_event(window, event);
break;
case ButtonRelease:
- if (root_widget)
- ltk_mouse_release_event(root_widget, event);
+ ltk_window_mouse_release_event(window, event);
break;
case MotionNotify:
- if (root_widget)
- ltk_motion_notify_event(root_widget, event);
+ ltk_window_motion_notify_event(window, event);
break;
default:
/* FIXME: users should be able to register other events like closing the window */
diff --git a/ltk.h b/ltk.h
@@ -24,7 +24,7 @@
#ifndef _LTK_H_
#define _LTK_H_
-/* Requires the following includes: <X11/Xlib.h>, <X11/Xutil.h>, "khash.h" */
+/* Requires the following includes: <X11/Xlib.h>, <X11/Xutil.h> */
typedef struct {
int x;
@@ -64,12 +64,15 @@ typedef struct LtkWidget {
void (*mouse_press) (void *, XEvent event);
void (*mouse_release) (void *, XEvent event);
void (*motion_notify) (void *, XEvent event);
+ void (*mouse_leave) (void *, XEvent event);
+ void (*mouse_enter) (void *, XEvent event);
void (*resize) (void *, int, int);
void (*draw) (void *);
void (*destroy) (void *);
- LtkRect rect;
+ LtkRect collision_rect; /* rect for collision with mouse */
+ LtkRect rect; /* rect in grid - this is only different when the widget is floating */
unsigned int row;
unsigned int column;
unsigned int row_span;
@@ -82,9 +85,12 @@ typedef struct LtkWidget {
typedef struct LtkWindow {
Window xwindow;
GC gc;
- void *root_widget;
+ LtkWidget *root_widget;
int (*other_event) (LtkWindow *, XEvent event);
LtkRect rect;
+ LtkWidget **float_widgets;
+ int num_float_widgets;
+ int max_float_widgets;
} LtkWindow;
typedef struct LtkWindowTheme {
@@ -101,23 +107,15 @@ typedef struct {
LtkButtonTheme *button;
} LtkTheme;
-LtkTheme *ltk_load_theme(const char *path);
-
typedef struct LtkTextManager LtkTextManager;
+LtkTextManager *ltk_get_text_manager(void);
+LtkTheme *ltk_get_theme(void);
+Display *ltk_get_display(void);
+Colormap ltk_get_colormap(void);
-/* Window hash */
-KHASH_MAP_INIT_INT(winhash, LtkWindow*)
+LtkTheme *ltk_load_theme(const char *path);
-typedef struct {
- LtkTheme *theme;
- LtkTextManager *tm;
- Display *display;
- int screen;
- Colormap colormap;
- khash_t(winhash) *window_hash;
- int window_num;
- Atom wm_delete_msg;
-} Ltk;
+typedef struct LtkTextManager LtkTextManager;
void ltk_window_invalidate_rect(LtkWindow *window, LtkRect rect);
@@ -155,11 +153,11 @@ void ltk_remove_hover_widget(void *widget);
void ltk_fill_widget_defaults(LtkWidget *widget, LtkWindow * window,
void (*draw) (void *), void (*destroy) (void *), unsigned int needs_redraw);
-void ltk_mouse_press_event(void *widget, XEvent event);
+void ltk_widget_mouse_press_event(void *widget, XEvent event);
-void ltk_mouse_release_event(void *widget, XEvent event);
+void ltk_widget_mouse_release_event(void *widget, XEvent event);
-void ltk_motion_notify_event(void *widget, XEvent event);
+void ltk_widget_motion_notify_event(void *widget, XEvent event);
void ltk_handle_event(XEvent event);
diff --git a/text_buffer.c b/text_buffer.c
@@ -38,8 +38,6 @@
#include "text_buffer.h"
#include "ltk.h"
-extern Ltk *ltk_global;
-
LTK_ARRAY_INIT_IMPL(uint32, uint32_t)
LTK_ARRAY_INIT_IMPL(script, hb_script_t)
LTK_ARRAY_INIT_IMPL(level, FriBidiLevel)
@@ -623,8 +621,9 @@ ltk_text_line_itemize(struct ltk_text_line *tl) {
}
static void
-ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
+ltk_text_run_shape(struct ltk_text_run *tr,
struct ltk_text_line *tl, uint16_t font_size, uint16_t font_id, int *ret_y_max) {
+ LtkTextManager *tm = ltk_get_text_manager();
khash_t(glyphinfo) *glyph_cache;
khint_t k;
@@ -707,7 +706,8 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
}
static void
-ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
+ltk_text_line_shape(struct ltk_text_line *tl) {
+ LtkTextManager *tm = ltk_get_text_manager();
struct ltk_text_run *run = tl->first_run;
tl->w = tl->h = 0;
int y_max;
@@ -735,7 +735,7 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
run->font = kh_value(tm->font_cache, k);
FcPatternDestroy(match);
FcPatternDestroy(pat);
- ltk_text_run_shape(tm, run, tl, tl->font_size, font_id, &y_max);
+ ltk_text_run_shape(run, tl, tl->font_size, font_id, &y_max);
if (y_max_overall < y_max)
y_max_overall = y_max;
/* tr->start_y is -y_min */
@@ -771,8 +771,9 @@ ltk_text_run_destroy(struct ltk_text_run *tr) {
LtkFont *font;
LtkGlyph *glyph;
khint_t k;
- k = kh_get(glyphinfo, ltk_global->tm->glyph_cache, tr->font_id << 16 + tr->font_size);
- gcache = kh_value(ltk_global->tm->glyph_cache, k);
+ LtkTextManager *tm = ltk_get_text_manager();
+ k = kh_get(glyphinfo, tm->glyph_cache, tr->font_id << 16 + tr->font_size);
+ gcache = kh_value(tm->glyph_cache, k);
for (int i = 0; i < tr->num_glyphs; i++) {
glyph = &tr->glyphs[i];
if (--glyph->info->refs < 1) {
@@ -781,10 +782,10 @@ ltk_text_run_destroy(struct ltk_text_run *tr) {
ltk_destroy_glyph_info(glyph->info);
}
}
- k = kh_get(fontstruct, ltk_global->tm->font_cache, tr->font_id);
- font = kh_value(ltk_global->tm->font_cache, k);
+ k = kh_get(fontstruct, tm->font_cache, tr->font_id);
+ font = kh_value(tm->font_cache, k);
if (--font->refs < 1) {
- kh_del(fontstruct, ltk_global->tm->font_cache, k);
+ kh_del(fontstruct, tm->font_cache, k);
ltk_destroy_font(font);
}
free(tr->glyphs);
@@ -803,7 +804,7 @@ ltk_text_line_destroy_runs(struct ltk_text_run *runs) {
}
static void
-ltk_text_line_recalculate(LtkTextManager *tm, struct ltk_text_line *tl) {
+ltk_text_line_recalculate(struct ltk_text_line *tl) {
FriBidiCharType par_dir = FRIBIDI_TYPE_ON;
fribidi_log2vis(
tl->log_buf->buf, tl->log_buf->len,
@@ -816,7 +817,7 @@ ltk_text_line_recalculate(LtkTextManager *tm, struct ltk_text_line *tl) {
struct ltk_text_run *old_runs = tl->first_run;
ltk_text_line_itemize(tl);
struct ltk_text_run *cur = tl->first_run;
- ltk_text_line_shape(tm, tl);
+ ltk_text_line_shape(tl);
/* this needs to be done after shaping so the fonts, etc. aren't
removed if their reference counts drop and then loaded again
right afterwards */
@@ -837,8 +838,7 @@ ltk_text_line_insert_utf32(struct ltk_text_line *tl, size_t index, uint32_t *tex
ltk_array_resize_int(tl->vis2log, tl->len + len);
ltk_array_resize_level(tl->bidi_levels, tl->len + len);
tl->len += len;
- /* FIXME: Why am I passing tm? It's global anyways */
- ltk_text_line_recalculate(ltk_global->tm, tl);
+ ltk_text_line_recalculate(tl);
}
/* must be NULL-terminated */
diff --git a/text_common.c b/text_common.c
@@ -36,8 +36,6 @@
#include "text_common.h"
#include "ltk.h"
-extern Ltk *ltk_global;
-
/* These unicode routines are taken from
* https://github.com/JeffBezanson/cutef8 */
diff --git a/text_edit.c b/text_edit.c
@@ -26,21 +26,21 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "khash.h"
-#include "ltk.h"
#include "stb_truetype.h"
#include <fribidi.h>
#include <harfbuzz/hb.h>
#include <fontconfig/fontconfig.h>
#include "text_common.h"
+#include "ltk.h"
#include "array.h"
#include "text_buffer.h"
#include "text_edit.h"
#include "grid.h"
-extern Ltk *ltk_global;
-
void
ltk_text_edit_draw(LtkTextEdit *te) {
+ Display *display = ltk_get_display();
+ LtkTheme *theme = ltk_get_theme();
if (!te->img)
ltk_text_edit_resize(te, 0, 0);
LtkRect rect = te->widget.rect;
@@ -48,10 +48,10 @@ ltk_text_edit_draw(LtkTextEdit *te) {
int x = rect.x;
if (te->tl->dir == HB_DIRECTION_RTL)
x += rect.w - te->img->width;
- XSetForeground(ltk_global->display, window->gc, ltk_global->theme->window->bg.pixel);
- XFillRectangle(ltk_global->display, window->xwindow, window->gc, rect.x, rect.y, rect.w, rect.h);
+ XSetForeground(display, window->gc, theme->window->bg.pixel);
+ XFillRectangle(display, window->xwindow, window->gc, rect.x, rect.y, rect.w, rect.h);
XPutImage(
- ltk_global->display,
+ display,
window->xwindow,
window->gc,
te->img,
@@ -67,12 +67,15 @@ ltk_text_edit_resize(LtkTextEdit *te, int orig_w, int orig_h) {
if (te->tl->soft_lines->len == 1 &&
te->widget.rect.w >= te->img->width && orig_w >= te->img->width)
return;
- XColor fg = ltk_global->theme->window->fg;
- XColor bg = ltk_global->theme->window->bg;
+ LtkTheme *theme = ltk_get_theme();
+ Display *display = ltk_get_display();
+ Colormap colormap = ltk_get_colormap();
+ XColor fg = theme->window->fg;
+ XColor bg = theme->window->bg;
LtkWindow *window = te->widget.window;
ltk_text_line_wrap(te->tl, te->widget.rect.w);
if (te->img) XDestroyImage(te->img);
- te->img = ltk_text_line_render(te->tl, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, fg, bg);
+ te->img = ltk_text_line_render(te->tl, display, window->xwindow, window->gc, colormap, fg, bg);
}
#if 0