summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build5
-rw-r--r--src/compgen.c57
-rw-r--r--src/entry.c19
-rw-r--r--src/entry.h1
-rw-r--r--src/gl.c5
-rw-r--r--src/image.c96
-rw-r--r--src/image.h2
-rw-r--r--src/ipc.c3
-rw-r--r--src/main.c32
-rw-r--r--src/string_vec.c7
-rw-r--r--src/string_vec.h5
-rw-r--r--src/tofi.h5
-rw-r--r--src/xmalloc.c42
-rw-r--r--src/xmalloc.h14
14 files changed, 158 insertions, 135 deletions
diff --git a/meson.build b/meson.build
index 344cfcd..ea1db95 100644
--- a/meson.build
+++ b/meson.build
@@ -67,12 +67,12 @@ sources = files(
'src/egl.c',
'src/entry.c',
'src/gl.c',
- 'src/image.c',
'src/ipc.c',
'src/log.c',
'src/string_vec.c',
'src/surface.c',
'src/wlr-layer-shell-unstable-v1.c',
+ 'src/xmalloc.c',
)
cc = meson.get_compiler('c')
@@ -80,7 +80,6 @@ epoxy = dependency('epoxy')
glib = dependency('glib-2.0')
json = dependency('json-c')
pangocairo = dependency('pangocairo')
-png = dependency('libpng')
wayland_client = dependency('wayland-client')
wayland_egl = dependency('wayland-egl')
wayland_protocols = dependency('wayland-protocols', native: true)
@@ -119,7 +118,7 @@ endforeach
executable(
'tofi',
sources, wl_proto_src, wl_proto_headers,
- dependencies: [epoxy, json, glib, pangocairo, png, wayland_egl, xkbcommon],
+ dependencies: [epoxy, json, glib, pangocairo, wayland_egl, xkbcommon],
install: true
)
diff --git a/src/compgen.c b/src/compgen.c
index e04e0a5..8190a21 100644
--- a/src/compgen.c
+++ b/src/compgen.c
@@ -1,16 +1,71 @@
#include <dirent.h>
+#include <stdbool.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "log.h"
#include "string_vec.h"
+#include "xmalloc.h"
+
+static const char *default_state_dir = ".local/state";
+static const char *histfile_basename = "tofi-history";
+
+static char *get_histfile_path() {
+ char *histfile_name;
+ const char *state_path = getenv("XDG_STATE_HOME");
+ if (state_path == NULL) {
+ const char *home = getenv("HOME");
+ if (home == NULL) {
+ log_error("Couldn't retrieve HOME from environment.\n");
+ exit(EXIT_FAILURE);
+ }
+ size_t len = strlen(home) + 1
+ + strlen(default_state_dir) + 1
+ + strlen(histfile_basename) + 1;
+ histfile_name = xmalloc(len);
+ snprintf(
+ histfile_name,
+ len,
+ "%s/%s/%s",
+ home,
+ default_state_dir,
+ histfile_basename);
+ } else {
+ size_t len = strlen(state_path) + 1
+ + strlen(histfile_basename) + 1;
+ histfile_name = xmalloc(len);
+ snprintf(
+ histfile_name,
+ len,
+ "%s/%s",
+ state_path,
+ histfile_basename);
+ }
+ return histfile_name;
+
+}
+
+static void load_history()
+{
+ char *name = get_histfile_path();
+ FILE *histfile = fopen(name, "rb");
+
+ free(name);
+
+ if (histfile == NULL) {
+ return;
+ }
+
+}
struct string_vec compgen()
{
+ load_history();
log_debug("Retrieving PATH.\n");
const char *env_path = getenv("PATH");
if (env_path == NULL) {
- log_error("Couldn't retrieve PATH from environment.");
+ log_error("Couldn't retrieve PATH from environment.\n");
exit(EXIT_FAILURE);
}
struct string_vec programs = string_vec_create();
diff --git a/src/entry.c b/src/entry.c
index def32b2..644fe39 100644
--- a/src/entry.c
+++ b/src/entry.c
@@ -100,6 +100,24 @@ void entry_init(struct entry *entry, uint32_t width, uint32_t height, uint32_t s
pango_context_set_font_description(context, font_description);
pango_font_description_free(font_description);
+ entry->pango.prompt_layout = pango_layout_new(context);
+ pango_layout_set_text(entry->pango.prompt_layout, "run: ", -1);
+ int prompt_width;
+ int prompt_height;
+ pango_layout_get_pixel_size(entry->pango.prompt_layout, &prompt_width, &prompt_height);
+ pango_cairo_update_layout(cr, entry->pango.prompt_layout);
+
+ /* Draw the prompt now, as this only needs to be done once */
+ color = entry->foreground_color;
+ cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
+ pango_cairo_show_layout(cr, entry->pango.prompt_layout);
+
+ /* Move and clip so we don't draw over the prompt */
+ cairo_translate(cr, prompt_width, 0);
+ width -= prompt_width;
+ cairo_rectangle(cr, 0, 0, width, height);
+ cairo_clip(cr);
+
entry->pango.entry_layout = pango_layout_new(context);
pango_layout_set_text(entry->pango.entry_layout, "", -1);
@@ -123,6 +141,7 @@ void entry_destroy(struct entry *entry)
g_object_unref(entry->pango.result_layouts[i]);
}
g_object_unref(entry->pango.entry_layout);
+ g_object_unref(entry->pango.prompt_layout);
g_object_unref(entry->pango.context);
cairo_destroy(entry->cairo.cr);
cairo_surface_destroy(entry->cairo.surface);
diff --git a/src/entry.h b/src/entry.h
index a362ec9..6d4023f 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -13,6 +13,7 @@ struct entry {
struct image image;
struct {
PangoContext *context;
+ PangoLayout *prompt_layout;
PangoLayout *entry_layout;
PangoLayout *result_layouts[5];
} pango;
diff --git a/src/gl.c b/src/gl.c
index b62e59e..09c7e1d 100644
--- a/src/gl.c
+++ b/src/gl.c
@@ -5,6 +5,7 @@
#include <string.h>
#include "gl.h"
#include "log.h"
+#include "xmalloc.h"
#define max(a, b) ((a) > (b) ? (a) : (b))
@@ -197,7 +198,7 @@ void load_shader(GLuint shader, const char *filename)
exit(EXIT_FAILURE);
}
unsigned long usize = (unsigned long) size;
- GLchar *source = malloc(usize + 1);
+ GLchar *source = xmalloc(usize + 1);
rewind(fp);
if (fread(source, 1, usize, fp) != usize) {
log_error("Failed to load shader %s: %s.\n",
@@ -220,7 +221,7 @@ void load_shader(GLuint shader, const char *filename)
GLint info_length = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_length);
if (info_length > 1) {
- char *log = malloc((unsigned)info_length * sizeof(*log));
+ char *log = xmalloc((unsigned)info_length * sizeof(*log));
glGetShaderInfoLog(shader, info_length, NULL, log);
log_error("\t%s\n", log);
free(log);
diff --git a/src/image.c b/src/image.c
deleted file mode 100644
index 07195c1..0000000
--- a/src/image.c
+++ /dev/null
@@ -1,96 +0,0 @@
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <png.h>
-#include "log.h"
-#include "image.h"
-
-#define HEADER_BYTES 8
-
-void image_load(struct image *image, const char *filename)
-{
- log_debug("Loading image '%s'\n", filename);
- FILE *fp = fopen(filename, "rb");
- uint8_t header[HEADER_BYTES];
- if (!fp) {
- log_error("Couldn't open '%s': %s.\n",
- filename, strerror(errno));
- return;
- }
- if (fread(header, 1, HEADER_BYTES, fp) != HEADER_BYTES) {
- log_error("Failed to read '%s': %s.\n",
- filename, strerror(errno));
- fclose(fp);
- return;
- }
- if (png_sig_cmp(header, 0, HEADER_BYTES)) {
- log_error("'%s' isn't a PNG file.\n", filename);
- fclose(fp);
- return;
- }
-
- png_structp png_ptr = png_create_read_struct(
- PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL);
- if (!png_ptr) {
- log_error("Couldn't create PNG read struct.\n");
- fclose(fp);
- return;
- }
-
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- png_destroy_read_struct(&png_ptr, NULL, NULL);
- fclose(fp);
- log_error("Couldn't create PNG info struct.\n");
- return;
- }
-
- if (setjmp(png_jmpbuf(png_ptr)) != 0) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- fclose(fp);
- log_error("Couldn't setjmp for libpng.\n");
- return;
- }
-
- png_init_io(png_ptr, fp);
- png_set_sig_bytes(png_ptr, HEADER_BYTES);
- png_read_info(png_ptr, info_ptr);
-
- uint32_t width = png_get_image_width(png_ptr, info_ptr);
- uint32_t height = png_get_image_height(png_ptr, info_ptr);
- //uint8_t color_type = png_get_color_type(png_ptr, info_ptr);
- //uint8_t bit_depth = png_get_bit_depth(png_ptr, info_ptr);
-
- png_set_expand(png_ptr);
- png_set_gray_to_rgb(png_ptr);
- png_set_filler(png_ptr, 0xFFu, PNG_FILLER_AFTER);
-
- png_read_update_info(png_ptr, info_ptr);
-
- uint32_t row_bytes = png_get_rowbytes(png_ptr, info_ptr);
- /* Guard against integer overflow */
- if (height > PNG_SIZE_MAX / row_bytes) {
- png_error(png_ptr, "image_data buffer would be too large");
- }
-
- png_bytep buffer = malloc(height * row_bytes);
- png_bytepp row_pointers = calloc(height, sizeof(png_bytep));
- for (uint32_t y = 0; y < height; y++) {
- row_pointers[y] = &buffer[y * row_bytes];
- }
-
- png_read_image(png_ptr, row_pointers);
- png_read_end(png_ptr, NULL);
-
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- free(row_pointers);
- fclose(fp);
-
- image->width = width;
- image->height = height;
- image->buffer = buffer;
- log_debug("Image loaded.\n");
-}
diff --git a/src/image.h b/src/image.h
index 21b9100..a66e0cb 100644
--- a/src/image.h
+++ b/src/image.h
@@ -18,6 +18,4 @@ struct image {
} damage;
};
-void image_load(struct image *image, const char *filename);
-
#endif /* IMAGE_H */
diff --git a/src/ipc.c b/src/ipc.c
index 2e92097..2af5dbf 100644
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -9,6 +9,7 @@
#include <unistd.h>
#include "ipc.h"
#include "log.h"
+#include "xmalloc.h"
static int ipc_open(void);
static int ipc_send(int socket, struct json_object *request);
@@ -99,7 +100,7 @@ struct json_object *ipc_receive(int sock)
return NULL;
}
- char *buf = malloc(len + 1);
+ char *buf = xmalloc(len + 1);
if (recv(sock, buf, len, 0) != len) {
log_error("Error receiving response: %s\n", strerror(errno));
free(buf);
diff --git a/src/main.c b/src/main.c
index ed865ed..95f16dc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -53,16 +53,6 @@ static void resize(struct tofi *tofi)
* Wayland wants "surface-local" width / height, so we have to divide
* the entry's pixel size by the scale factor.
*/
- //int32_t x = (
- // tofi->window.width
- // - entry_surface->width / tofi->window.scale
- // ) / 2;
- //int32_t y = (
- // tofi->window.height
- // - entry_surface->height / tofi->window.scale
- // ) / 2;
- //wl_subsurface_set_position(tofi->window.entry.wl_subsurface, x, y);
- //wl_surface_commit(tofi->window.entry.surface.wl_surface);
}
static void zwlr_layer_surface_configure(
@@ -603,7 +593,6 @@ int main(int argc, char *argv[])
/* Option parsing with getopt. */
struct option long_options[] = {
- {"background-image", required_argument, NULL, 'b'},
{"background-color", required_argument, NULL, 'B'},
{"border-width", required_argument, NULL, 'r'},
{"border-color", required_argument, NULL, 'R'},
@@ -626,11 +615,6 @@ int main(int argc, char *argv[])
int opt = getopt_long(argc, argv, short_options, long_options, NULL);
while (opt != -1) {
switch (opt) {
- case 'b':
- image_load(
- &tofi.window.background_image,
- optarg);
- break;
case 'B':
tofi.window.background_color =
hex_to_color(optarg);
@@ -772,11 +756,11 @@ int main(int argc, char *argv[])
tofi.zwlr_layer_shell,
tofi.window.surface.wl_surface,
tofi.wl_output,
- ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
+ ZWLR_LAYER_SHELL_V1_LAYER_TOP,
"launcher");
zwlr_layer_surface_v1_set_keyboard_interactivity(
tofi.window.zwlr_layer_surface,
- ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE
+ ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND
);
zwlr_layer_surface_v1_add_listener(
tofi.window.zwlr_layer_surface,
@@ -791,6 +775,10 @@ int main(int argc, char *argv[])
zwlr_layer_surface_v1_set_exclusive_zone(
tofi.window.zwlr_layer_surface,
-1);
+ zwlr_layer_surface_v1_set_size(
+ tofi.window.zwlr_layer_surface,
+ 800,
+ 400);
wl_surface_commit(tofi.window.surface.wl_surface);
/*
@@ -834,7 +822,7 @@ int main(int argc, char *argv[])
&tofi.window.entry.image);
surface_draw(
&tofi.window.surface,
- &tofi.window.background_color,
+ &tofi.window.entry.background_color,
&tofi.window.entry.image);
/*
@@ -855,7 +843,7 @@ int main(int argc, char *argv[])
if (tofi.window.surface.redraw) {
surface_draw(
&tofi.window.surface,
- &tofi.window.background_color,
+ &tofi.window.entry.background_color,
&tofi.window.entry.image);
tofi.window.surface.redraw = false;
}
@@ -876,10 +864,6 @@ int main(int argc, char *argv[])
*/
entry_destroy(&tofi.window.entry);
surface_destroy(&tofi.window.surface);
- if (tofi.window.background_image.buffer != NULL) {
- free(tofi.window.background_image.buffer);
- tofi.window.background_image.buffer = NULL;
- }
eglTerminate(tofi.window.surface.egl.display);
wl_surface_destroy(tofi.window.surface.wl_surface);
if (tofi.wl_keyboard != NULL) {
diff --git a/src/string_vec.c b/src/string_vec.c
index f747339..d3ac9fe 100644
--- a/src/string_vec.c
+++ b/src/string_vec.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include "string_vec.h"
+#include "xmalloc.h"
static int cmpstringp(const void *restrict a, const void *restrict b)
{
@@ -29,7 +30,7 @@ struct string_vec string_vec_create(void)
struct string_vec vec = {
.count = 0,
.size = 128,
- .buf = calloc(128, sizeof(char *))
+ .buf = xcalloc(128, sizeof(char *))
};
return vec;
}
@@ -47,7 +48,7 @@ struct string_vec string_vec_copy(struct string_vec *restrict vec)
struct string_vec copy = {
.count = vec->count,
.size = vec->size,
- .buf = calloc(vec->size, sizeof(char *))
+ .buf = xcalloc(vec->size, sizeof(char *))
};
for (size_t i = 0; i < vec->count; i++) {
@@ -61,7 +62,7 @@ void string_vec_add(struct string_vec *restrict vec, const char *restrict str)
{
if (vec->count == vec->size) {
vec->size *= 2;
- vec->buf = realloc(vec->buf, vec->size * sizeof(vec->buf[0]));
+ vec->buf = xrealloc(vec->buf, vec->size * sizeof(vec->buf[0]));
}
vec->buf[vec->count] = strdup(str);
vec->count++;
diff --git a/src/string_vec.h b/src/string_vec.h
index b3395ad..7ebcb53 100644
--- a/src/string_vec.h
+++ b/src/string_vec.h
@@ -3,6 +3,11 @@
#include <stddef.h>
+struct program {
+ char *name;
+ size_t run_count;
+};
+
struct string_vec {
size_t count;
size_t size;
diff --git a/src/tofi.h b/src/tofi.h
index 586d1ca..3ea66f3 100644
--- a/src/tofi.h
+++ b/src/tofi.h
@@ -35,11 +35,10 @@ struct tofi {
struct {
struct surface surface;
struct zwlr_layer_surface_v1 *zwlr_layer_surface;
- struct image background_image;
struct color background_color;
struct entry entry;
- int32_t width;
- int32_t height;
+ uint32_t width;
+ uint32_t height;
uint32_t scale;
bool resize;
} window;
diff --git a/src/xmalloc.c b/src/xmalloc.c
new file mode 100644
index 0000000..8a08cb8
--- /dev/null
+++ b/src/xmalloc.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include "log.h"
+#include "xmalloc.h"
+
+void *xmalloc(size_t size)
+{
+ void *ptr = malloc(size);
+
+ if (ptr != NULL) {
+ log_debug("Allocated %zu bytes.\n", size);
+ return ptr;
+ } else {
+ fputs("Out of memory, exiting.", stderr);
+ exit(EXIT_FAILURE);
+ }
+}
+
+void *xcalloc(size_t nmemb, size_t size)
+{
+ void *ptr = calloc(nmemb, size);
+
+ if (ptr != NULL) {
+ log_debug("Allocated %zux%zu bytes.\n", nmemb, size);
+ return ptr;
+ } else {
+ fputs("Out of memory, exiting.", stderr);
+ exit(EXIT_FAILURE);
+ }
+}
+
+void *xrealloc(void *ptr, size_t size)
+{
+ ptr = realloc(ptr, size);
+
+ if (ptr != NULL) {
+ log_debug("Reallocated to %zu bytes.\n", size);
+ return ptr;
+ } else {
+ fputs("Out of memory, exiting.", stderr);
+ exit(EXIT_FAILURE);
+ }
+}
diff --git a/src/xmalloc.h b/src/xmalloc.h
new file mode 100644
index 0000000..a661004
--- /dev/null
+++ b/src/xmalloc.h
@@ -0,0 +1,14 @@
+#ifndef XMALLOC_H
+#define XMALLOC_H
+
+#include <stdlib.h>
+
+__attribute__((malloc))
+void *xmalloc(size_t size);
+
+__attribute__((malloc))
+void *xcalloc(size_t nmemb, size_t size);
+
+void *xrealloc(void *ptr, size_t size);
+
+#endif /* XMALLOC_H */