aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-07-08 15:22:41 +0200
committerFederico Angelilli <code@fedang.net>2024-07-08 15:22:41 +0200
commit5d170a634ead0119f6e5a9f63c23b2b064126f75 (patch)
tree0447d2dbb0da6358d184a4c62d5557d4d22f5e8d /src
parent92feb3c130966202c7caa6d9bf3a3800c97ca7a1 (diff)
Remove old files
Diffstat (limited to 'src')
-rw-r--r--src/animate.c222
-rw-r--r--src/animate.h51
-rw-r--r--src/button.c122
-rw-r--r--src/button.h77
-rw-r--r--src/comet.c464
-rw-r--r--src/connect.c408
-rw-r--r--src/connect.h42
-rw-r--r--src/draw.c391
-rw-r--r--src/draw.h69
-rw-r--r--src/dwm.c445
-rw-r--r--src/dwm.h30
-rw-r--r--src/log.h25
-rw-r--r--src/state.c137
-rw-r--r--src/state.h38
-rw-r--r--src/window.c306
-rw-r--r--src/window.h41
16 files changed, 0 insertions, 2868 deletions
diff --git a/src/animate.c b/src/animate.c
deleted file mode 100644
index 839e748..0000000
--- a/src/animate.c
+++ /dev/null
@@ -1,222 +0,0 @@
-#include <glib.h>
-#include <stdbool.h>
-#include <math.h>
-
-#include "animate.h"
-#include "state.h"
-#include "log.h"
-
-double clamp(double x, double min, double max)
-{
- const double t = x < min ? min : x;
- return t > max ? max : t;
-}
-
-double smoothstep(double x, double edge0, double edge1)
-{
- x = clamp((x - edge0) / (edge1 - edge0), 0, 1);
- return x * x * (3.0 - 2.0 * x);
-}
-
-double quadratic_bezier(double x, double a, double b, double c)
-{
- g_assert(x >= 0 && x <= 1);
- const double t = 1 - x;
- return a * t * t + 2 * b * t * x + c * x * x;
-}
-
-double cubic_bezier(double x, double a, double b, double c, double d)
-{
- g_assert(x >= 0 && x <= 1);
- const double t = 1 - x;
- return a * (t * t * t) + 3 * b * (t * t * x) + 3 * c * (t * x * x) + d * (x * x * x);
-}
-
-typedef struct {
- Animation anim;
- int width;
- cairo_pattern_t *gradient;
-} AnimationShine;
-
-static bool shine_func(AnimationShine *shine, Layout *layout, cairo_t *cr)
-{
- gint64 end = shine->anim.start + shine->anim.duration;
- gint64 now = g_get_monotonic_time();
- if (now > end) return false;
-
- double t = (double)(now - shine->anim.start) / (end - shine->anim.start);
- double pos = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0);
-
- double angle = atan((double)layout->height / layout->width);
-
- // Make it double just to be sure
- int h = 2 * (double)layout->height / cos(angle);
- int x = layout->x + pos * layout->width - shine->width;
- int y = layout->y;
-
- cairo_matrix_t matrix;
- cairo_matrix_init_translate(&matrix, -x, -y);
- cairo_pattern_set_matrix(shine->gradient, &matrix);
-
- int dx = layout->x + layout->width / 2;
- int dy = layout->y + layout->height / 2;
-
- cairo_translate(cr, dx, dy);
- cairo_rotate(cr, -angle);
- cairo_translate(cr, -dx, -dy);
-
- cairo_set_operator(cr, CAIRO_OPERATOR_ATOP);
- cairo_set_source(cr, shine->gradient);
- cairo_rectangle(cr, x, y - (h - layout->height) / 2, shine->width, h);
- cairo_fill(cr);
-
- return true;
-}
-
-Animation *animation_shine_create(gint64 duration)
-{
- // Note the 0 initialization
- AnimationShine *shine = g_malloc0(sizeof(AnimationShine));
- shine->anim.type = ANIM_SHINE;
- shine->anim.after_func = (DrawFunc)shine_func;
- shine->anim.duration = duration;
-
- // TODO: Change it depending on container size
- shine->width = 25;
-
- shine->gradient = cairo_pattern_create_linear(0, 0, shine->width, 0);
- cairo_pattern_add_color_stop_rgba(shine->gradient, 0, 1, 1, 1, 0);
- cairo_pattern_add_color_stop_rgba(shine->gradient, 0.5, 1, 1, 1, 0.2);
- cairo_pattern_add_color_stop_rgba(shine->gradient, 1, 1, 1, 1, 0);
-
- return (gpointer)shine;
-}
-
-static bool pulse_func(Animation *pulse, Layout *layout, cairo_t *cr)
-{
- gint64 end = pulse->start + pulse->duration;
- gint64 now = g_get_monotonic_time();
- if (now > end) return false;
-
- // After half the duration we invert direction
- gint64 mid = pulse->start + pulse->duration / 2;
- double t = now <= mid
- ? (double)(now - pulse->start) / (mid - pulse->start)
- : 1.0 - (double)(now - mid) / (end - mid);
-
- double pos = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0);
- int max = 0.15 * layout->height;
-
- layout->x_pad = layout->btn->x_pad + max * pos;
- layout->y_pad = layout->btn->y_pad + max * pos;
-
- return true;
-}
-
-Animation *animation_pulse_create(gint64 duration)
-{
- // Note the 0 initialization
- Animation *pulse = g_malloc0(sizeof(Animation));
- pulse->type = ANIM_PULSE;
- pulse->before_func = (DrawFunc)pulse_func;
- pulse->duration = duration;
- return pulse;
-}
-
-static bool shrink_func(Animation *shrink, Layout *layout)
-{
- g_assert_false(layout->btn->simple);
- ButtonGroup *group = (gpointer)layout->btn;
-
- gint64 end = shrink->start + shrink->duration;
- gint64 now = g_get_monotonic_time();
-
- if (now > end) {
- // NOTE: Actually remove the buttons from the group after the animation's end
- // This part is quite rough around the edges...
- if (group->children->next) {
- g_list_free(g_list_remove_link(group->children, group->children));
- g_list_free_full(g_list_remove_link(layout->children, layout->children), (GDestroyNotify)layout_destroy);
- layout->width = CAST(layout->children->data, Layout)->width;
- return true;
- }
-
- return false;
- }
-
- double t = (double)(now - shrink->start) / (end - shrink->start);
- double pos = smoothstep(t, 0, 1);
-
- int target_w = CAST(layout->children->data, Layout)->width;
- int width = layout->width - pos * (layout->width - target_w);
- layout->width = width;
-
- for (GList *it = layout->children, *next = it->next; it; it = next, next = it ? it->next : NULL) {
- Layout *child = it->data;
- if (child->x + child->width <= layout->x + width) continue;
-
- layout_destroy(it->data);
- layout->children = g_list_delete_link(layout->children, it);
- }
-
- return true;
-}
-
-Animation *animation_group_shrink_create(gint64 duration)
-{
- // Note the 0 initialization
- Animation *shrink = g_malloc0(sizeof(Animation));
- shrink->type = ANIM_GROUP_SHRINK;
- shrink->layout_func = (LayoutFunc)shrink_func;
- shrink->duration = duration;
- return shrink;
-}
-
-static bool grow_func(Animation *grow, Layout *layout)
-{
- g_assert_false(layout->btn->simple);
- ButtonGroup *group = (gpointer)layout->btn;
-
- gint64 end = grow->start + grow->duration;
- gint64 now = g_get_monotonic_time();
- if (now > end) return false;
-
- double t = (double)(now - grow->start) / (end - grow->start);
- double pos = smoothstep(t, 0, 1);
-
- int start_w = CAST(layout->children->data, Layout)->width;
- int width = start_w + pos * (layout->width - start_w);
- layout->width = width;
-
- for (GList *it = layout->children->next, *next = it->next; it; it = next, next = it ? it->next : NULL) {
- Layout *child = it->data;
- if (child->x + child->width <= layout->x + width) continue;
-
- layout_destroy(it->data);
- layout->children = g_list_delete_link(layout->children, it);
- }
-
- return true;
-}
-
-Animation *animation_group_grow_create(gint64 duration)
-{
- // Note the 0 initialization
- Animation *grow = g_malloc0(sizeof(Animation));
- grow->type = ANIM_GROUP_GROW;
- grow->layout_func = (LayoutFunc)grow_func;
- grow->duration = duration;
- return grow;
-}
-
-void animation_destroy(Animation *anim)
-{
- if (anim == NULL) return;
-
- if (anim->type == ANIM_SHINE)
- cairo_pattern_destroy(CAST(anim, AnimationShine)->gradient);
-
- g_free(anim);
-}
-
-// vim: ts=4 sw=4 et
diff --git a/src/animate.h b/src/animate.h
deleted file mode 100644
index 79b6174..0000000
--- a/src/animate.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef COMET_ANIMATE_H
-#define COMET_ANIMATE_H
-
-#include <glib.h>
-
-#include "draw.h"
-
-#define MILLIS(n) ((n) * G_TIME_SPAN_MILLISECOND)
-
-typedef struct Animation Animation;
-typedef struct State State;
-
-typedef bool (* LayoutFunc)(Animation *anim, Layout *layout);
-typedef bool (* DrawFunc)(Animation *anim, Layout *layout, cairo_t *cr);
-
-struct Animation {
- enum {
- ANIM_SHINE,
- ANIM_PULSE,
- ANIM_GROUP_SHRINK,
- ANIM_GROUP_GROW,
- } type;
- gint64 start;
- gint64 duration;
- LayoutFunc layout_func;
- // NOTE: These should not change the layout width
- DrawFunc before_func;
- DrawFunc after_func;
-};
-
-double clamp(double x, double min, double max);
-
-double smoothstep(double x, double edge0, double edge1);
-
-double quadratic_bezier(double x, double a, double b, double c);
-
-double cubic_bezier(double x, double a, double b, double c, double d);
-
-Animation *animation_shine_create(gint64 duration);
-
-Animation *animation_pulse_create(gint64 duration);
-
-Animation *animation_group_shrink_create(gint64 duration);
-
-Animation *animation_group_grow_create(gint64 duration);
-
-void animation_destroy(Animation *anim);
-
-#endif
-
-// vim: ts=4 sw=4 et
diff --git a/src/button.c b/src/button.c
deleted file mode 100644
index b11f5b1..0000000
--- a/src/button.c
+++ /dev/null
@@ -1,122 +0,0 @@
-#include <glib.h>
-
-#include "button.h"
-#include "log.h"
-
-Button *button_simple_create(PangoAlignment align, Color color)
-{
- Button *btn = g_malloc0(sizeof(ButtonSimple));
- btn->simple = true;
- btn->align = align;
- btn->color = color;
- CAST(btn, ButtonSimple)->action = NULL;
- return btn;
-}
-
-void button_simple_set_text(Button *btn, char *text, Color text_color)
-{
- g_assert(btn->simple);
- ButtonSimple *sbtn = CAST(btn, ButtonSimple);
- g_free(sbtn->text);
- sbtn->text = text;
- sbtn->text_color = text_color;
-}
-
-const char *button_simple_get_text(Button *btn)
-{
- g_assert(btn->simple);
- return CAST(btn, ButtonSimple)->text;
-}
-
-void button_simple_set_action(Button *btn, ButtonAction action, gpointer data)
-{
- g_assert(btn->simple);
- CAST(btn, ButtonSimple)->action = action;
- CAST(btn, ButtonSimple)->data = data;
-}
-
-ButtonAction button_simple_get_action(Button *btn)
-{
- g_assert(btn->simple);
- return CAST(btn, ButtonSimple)->action;
-}
-
-Button *button_group_create(PangoAlignment align, Color color)
-{
- Button *btn = g_malloc0(sizeof(ButtonGroup));
- btn->simple = false;
- btn->align = align;
- btn->color = color;
- return btn;
-}
-
-void button_group_append(Button *btn, Button *child)
-{
- g_assert(!btn->simple);
- CAST(btn, ButtonGroup)->children = g_list_append(CAST(btn, ButtonGroup)->children, child);
-}
-
-void button_set_padding(Button *btn, int x_pad, int y_pad)
-{
- g_assert(x_pad >= 0 && y_pad >= 0);
- btn->x_pad = x_pad;
- btn->y_pad = y_pad;
-}
-
-bool button_set_animation(Button *btn, Animation *anim)
-{
- if (btn->anim != NULL)
- return false;
-
- btn->anim = anim;
- return true;
-}
-
-void button_set_line(Button *btn, Color line_color, int line_width)
-{
- btn->line_color = line_color;
- btn->line_width = line_width;
-}
-
-void button_set_width(Button *btn, int max, int min)
-{
- g_assert(max == 0 || max >= min);
- g_assert(max >= 0 && min >= 0);
- btn->max_width = max;
- btn->min_width = min;
-}
-
-Button *button_copy(Button *btn)
-{
- if (btn->simple) {
- ButtonSimple *copy = g_malloc0(sizeof(ButtonSimple));
- memcpy(copy, CAST(btn, ButtonSimple), sizeof(ButtonSimple));
- copy->text = g_strdup(CAST(btn, ButtonSimple)->text);
- copy->btn.anim = NULL;
- // NOTE: What to do with data?
- return CAST(copy, Button);
- } else {
- ButtonGroup *copy = g_malloc0(sizeof(ButtonGroup));
- memcpy(copy, CAST(btn, ButtonGroup), sizeof(ButtonGroup));
- copy->btn.anim = NULL;
- copy->children = NULL;
-
- for (GList *it = CAST(btn, ButtonGroup)->children; it != NULL; it = it->next) {
- copy->children = g_list_prepend(copy->children, button_copy(it->data));
- }
- copy->children = g_list_reverse(copy->children);
- return CAST(copy, Button);
- }
-}
-
-void button_destroy(Button *btn)
-{
- animation_destroy(btn->anim);
-
- if (btn->simple)
- g_free(CAST(btn, ButtonSimple)->text);
- else
- g_list_free_full(CAST(btn, ButtonGroup)->children, (GDestroyNotify)button_destroy);
-
- g_free(btn);
-}
diff --git a/src/button.h b/src/button.h
deleted file mode 100644
index 4b6c834..0000000
--- a/src/button.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef COMET_BUTTON_H
-#define COMET_BUTTON_H
-
-#include <stdbool.h>
-#include <glib.h>
-#include <pango/pangocairo.h>
-
-#include "draw.h"
-#include "animate.h"
-
-// For pointers only
-#define CAST(ptr, type) ((type *)ptr)
-
-typedef struct Button Button;
-
-typedef void (* ButtonAction)(Button *btn);
-
-struct Button {
- bool simple;
- int x_pad;
- int y_pad;
- PangoAlignment align;
- Color color;
- Color line_color;
- int line_width;
- int max_width;
- int min_width;
- // TODO: Make animations not depend on the button
- Animation *anim;
-};
-
-typedef struct {
- Button btn;
- Color text_color;
- char *text;
- ButtonAction action;
- gpointer data;
-} ButtonSimple;
-
-typedef struct {
- Button btn;
- GList *children;
-} ButtonGroup;
-
-// NOTE: For the moment all button specific functions take a generic button
-// pointer and assert the right type, so the check should be done by the caller
-
-Button *button_simple_create(PangoAlignment align, Color color);
-
-// Takes ownership of text
-void button_simple_set_text(Button *btn, char *text, Color text_color);
-
-const char *button_simple_get_text(Button *btn);
-
-void button_simple_set_action(Button *btn, ButtonAction action, gpointer data);
-
-ButtonAction button_simple_get_action(Button *btn);
-
-Button *button_group_create(PangoAlignment align, Color color);
-
-void button_group_append(Button *btn, Button *child);
-
-void button_set_padding(Button *btn, int x_pad, int y_pad);
-
-bool button_set_animation(Button *btn, Animation *anim);
-
-void button_set_line(Button *btn, Color line_color, int line_width);
-
-void button_set_width(Button *btn, int max, int min);
-
-Button *button_copy(Button *btn);
-
-void button_destroy(Button *btn);
-
-#endif
-
-// vim: ts=4 sw=4 et
diff --git a/src/comet.c b/src/comet.c
deleted file mode 100644
index b97f8bd..0000000
--- a/src/comet.c
+++ /dev/null
@@ -1,464 +0,0 @@
-#include <math.h>
-#include <glib.h>
-#include <glib-unix.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/statvfs.h>
-#include <locale.h>
-
-#include "window.h"
-#include "log.h"
-#include "draw.h"
-#include "connect.h"
-#include "state.h"
-#include "dwm.h"
-
-#define EVEN(n) ((int)(n) - ((int)(n) % 2 != 0))
-
-static void log_handler(const char *log_domain,
- GLogLevelFlags level,
- const char *message,
- gpointer log_level)
-{
- GLogLevelFlags message_level = level & G_LOG_LEVEL_MASK;
-
- if ((GLogLevelFlags)log_level < message_level)
- return;
-
- if (message_level <= G_LOG_LEVEL_WARNING)
- g_printerr("%s\n", message);
- else
- g_print("%s\n", message);
-}
-
-
-static gboolean mainloop_quit(gpointer data)
-{
- g_main_loop_quit(data);
- return G_SOURCE_CONTINUE;
-}
-
-// Taken from slstatus
-// XXX: Change with something more robust
-char *cpu_percentage(void)
-{
- static long double a[7];
- long double b[7], sum;
- memcpy(b, a, sizeof(b));
-
- FILE *stat = fopen("/proc/stat", "rb");
- g_assert_nonnull(stat);
-
- /* cpu user nice system idle iowait irq softirq */
- g_assert(7 == fscanf(stat, "%*s %Lf %Lf %Lf %Lf %Lf %Lf %Lf",
- &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6]));
-
- fclose(stat);
- if (b[0] == 0) return NULL;
-
- sum = (b[0] + b[1] + b[2] + b[3] + b[4] + b[5] + b[6]) -
- (a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6]);
-
- if (sum == 0) return NULL;
-
- return g_strdup_printf(" %d%%", (int)(100 *
- ((b[0] + b[1] + b[2] + b[5] + b[6]) -
- (a[0] + a[1] + a[2] + a[5] + a[6])) / sum));
-}
-
-static gboolean cpu_update(Button *btn)
-{
- char *perc = cpu_percentage();
-
- // Don't update on error
- if (perc == NULL)
- return G_SOURCE_CONTINUE;
-
- ButtonSimple *sbtn = CAST(btn, ButtonSimple);
- bool update = g_strcmp0(perc, sbtn->text) != 0;
- button_simple_set_text(btn, perc, sbtn->text_color);
-
- if (update)
- state_request_redraw(sbtn->data, false);
-
- return G_SOURCE_CONTINUE;
-}
-
-static gboolean ram_update(Button *btn)
-{
- FILE *meminfo = fopen("/proc/meminfo", "rb");
- g_assert_nonnull(meminfo);
-
- uintmax_t total, unused, buffers, cached;
- g_assert(5 == fscanf(meminfo,
- "MemTotal: %ju kB\n"
- "MemFree: %ju kB\n"
- "MemAvailable: %ju kB\n"
- "Buffers: %ju kB\n"
- "Cached: %ju kB\n",
- &total, &unused, &buffers, &buffers, &cached));
-
- int usage = 100 * (total - unused - buffers - cached) / total;
- fclose(meminfo);
-
-
- ButtonSimple *sbtn = CAST(btn, ButtonSimple);
- char *ram = g_strdup_printf(" %d%%", usage);
- bool update = g_strcmp0(ram, sbtn->text) != 0;
- button_simple_set_text(btn, ram, sbtn->text_color);
-
- if (update)
- state_request_redraw(sbtn->data, false);
-
- return G_SOURCE_CONTINUE;
-}
-
-static gboolean temp_update(Button *btn)
-{
- FILE *thermal = fopen("/sys/class/thermal/thermal_zone2/temp", "rb");
- g_assert_nonnull(thermal);
-
- uintmax_t value;
- g_assert(1 == fscanf(thermal, "%ju\n", &value));
- fclose(thermal);
-
- ButtonSimple *sbtn = CAST(btn, ButtonSimple);
- char *temp = g_strdup_printf(" %d °C", (int)(value / 1000));
- bool update = g_strcmp0(temp, sbtn->text) != 0;
- button_simple_set_text(btn, temp, sbtn->text_color);
-
- if (update)
- state_request_redraw(sbtn->data, false);
-
- return G_SOURCE_CONTINUE;
-}
-
-static gboolean disk_update(Button *btn)
-{
- struct statvfs buffer;
- g_assert(statvfs("/", &buffer) == 0);
- const double used = 1.0 - ((double)buffer.f_bavail / (double)buffer.f_blocks);
-
- ButtonSimple *sbtn = CAST(btn, ButtonSimple);
- char *disk = g_strdup_printf(" %d%%", (int)round(used * 100.0));
- bool update = g_strcmp0(disk, sbtn->text) != 0;
- button_simple_set_text(btn, disk, sbtn->text_color);
-
- if (update)
- state_request_redraw(sbtn->data, false);
-
- return G_SOURCE_CONTINUE;
-}
-
-static gboolean date_update(Button *btn)
-{
- GDateTime *dt = g_date_time_new_now_local();
- char *text = g_date_time_format(dt, "%A %d %H:%M");
- g_date_time_unref(dt);
-
- g_assert_nonnull(text);
- button_simple_set_text(btn, text, CAST(btn, ButtonSimple)->text_color);
-
- struct {
- State *state;
- timer_t timer;
- } *date_ctx = CAST(btn, ButtonSimple)->data;
-
- log_debug("Updated date and time");
- state_request_redraw(date_ctx->state, false);
-
- struct timespec current;
- clock_gettime(CLOCK_REALTIME, &current);
-
- struct itimerspec its = { 0 };
- its.it_value.tv_sec = 60 - (current.tv_sec % 60);
- timer_settime(date_ctx->timer, 0, &its, NULL);
-
- return G_SOURCE_CONTINUE;
-}
-
-static void show_action(Button *btn)
-{
- log_info("Called action: %s", button_simple_get_text(btn));
-}
-
-static void quit_action(Button *btn)
-{
- log_info("Quit button pressed");
- g_main_loop_quit(CAST(btn, ButtonSimple)->data);
-}
-
-static void menu_action(Button *btn)
-{
- struct {
- State *state;
- ButtonGroup *group;
- char *strings[2];
- GList *toggled;
- bool closed;
- } *menu_ctx = CAST(btn, ButtonSimple)->data;
-
- // NOTE: Clear the previous animation, if any
- g_list_free(menu_ctx->group->children);
- g_clear_pointer(&menu_ctx->group->btn.anim, animation_destroy);
- menu_ctx->group->children = g_list_copy(menu_ctx->toggled);
-
- char *text = g_strdup(menu_ctx->strings[menu_ctx->closed]);
- button_simple_set_text(btn, text, CAST(btn, ButtonSimple)->text_color);
-
- Animation *anim = menu_ctx->closed
- ? animation_group_grow_create(MILLIS(600))
- : animation_group_shrink_create(MILLIS(600));
-
- g_assert(button_set_animation((gpointer)menu_ctx->group, anim));
- state_request_animation(menu_ctx->state);
-
- log_debug("%s menu", menu_ctx->closed ? "Opened" : "Closed");
- menu_ctx->closed = !menu_ctx->closed;
-}
-
-static void register_buttons(State *state, Color color, Color text_color, Color line_color, int line_w)
-{
- // Precompute max button size
- int text_w;
- draw_compute_text_size(state->draw, " 100%", &text_w, NULL);
- int min_w = text_w + line_w + state->draw->height;
-
- // Cpu usage button
- Button *cpu_btn = button_simple_create(PANGO_ALIGN_RIGHT, color);
- button_simple_set_text(cpu_btn, g_strdup(" 0%"), text_color);
- button_simple_set_action(cpu_btn, show_action, state);
- button_set_line(cpu_btn, line_color, line_w);
- button_set_width(cpu_btn, 0, min_w);
- state_add_button(state, cpu_btn);
-
- cpu_update(cpu_btn);
- g_timeout_add(MILLIS(1), G_SOURCE_FUNC(cpu_update), cpu_btn);
-
- // Temperature button
- Button *temp_btn = button_simple_create(PANGO_ALIGN_RIGHT, color);
- button_simple_set_text(temp_btn, NULL, text_color);
- button_simple_set_action(temp_btn, show_action, state);
- button_set_line(temp_btn, line_color, line_w);
- button_set_width(temp_btn, 0, min_w);
- state_add_button(state, temp_btn);
-
- temp_update(temp_btn);
- g_timeout_add(MILLIS(20), G_SOURCE_FUNC(temp_update), temp_btn);
-
- // Ram usage button
- Button *ram_btn = button_simple_create(PANGO_ALIGN_RIGHT, color);
- button_simple_set_text(ram_btn, NULL, text_color);
- button_simple_set_action(ram_btn, show_action, state);
- button_set_line(ram_btn, line_color, line_w);
- button_set_width(ram_btn, 0, min_w);
- state_add_button(state, ram_btn);
-
- ram_update(ram_btn);
- g_timeout_add(MILLIS(10), G_SOURCE_FUNC(ram_update), ram_btn);
-
- // Disk usage button
- Button *disk_btn = button_simple_create(PANGO_ALIGN_RIGHT, color);
- button_simple_set_text(disk_btn, NULL, text_color);
- button_simple_set_action(disk_btn, show_action, state);
- button_set_line(disk_btn, line_color, line_w);
- button_set_width(disk_btn, 0, min_w);
- state_add_button(state, disk_btn);
-
- disk_update(disk_btn);
- g_timeout_add(MILLIS(60), G_SOURCE_FUNC(disk_update), disk_btn);
-}
-
-int main(int argc, char **argv)
-{
- setlocale(LC_CTYPE, "");
- g_log_set_default_handler(log_handler, (gpointer)G_LOG_LEVEL_DEBUG);
-
- GMainLoop *mainloop = g_main_loop_new(NULL, FALSE);
-
- Connection *con = connect_create();
-
- Window *win = window_create(con);
-
- int screen_width = con->screen_size->width;
- int screen_height = con->screen_size->height;
- double scale = window_get_scale(win);
-
- int height = EVEN(round(screen_height * 0.021));
- int x_padding = EVEN(round(screen_width * 0.005));
- int y_padding = EVEN(round(screen_height * 0.004));
-
- log_debug("Calculated dimensions [height=%d, x_pad=%d, y_pad=%d]", height, x_padding, y_padding);
-
- Color background_all = { 0.3, 0.3, 0.3, 1 };
- PangoContext *context = pango_cairo_create_context(window_get_context(win));
-
- Drawer *draw = draw_create();
- draw_set_background(draw, background_all);
- draw_set_separator(draw, 10);
- draw_set_font(draw, "Hack 13 Bold");
- draw_set_context(draw, context);
- draw_set_size(draw, height, x_padding, x_padding, y_padding);
-
- State *state = state_create("$1", win, draw);
-
- Window *win2 = window_create(con);
- int x_padding2 = EVEN(round(screen_width * 0.025));
- int y_padding2 = screen_height - height - EVEN(round(screen_height * 0.005));
-
- PangoContext *context2 = pango_cairo_create_context(window_get_context(win2));
-
- Drawer *draw2 = draw_create();
- draw_set_background(draw2, background_all);
- draw_set_separator(draw2, 10);
- draw_set_font(draw2, "Hack 13 Bold");
- draw_set_context(draw2, context);
- draw_set_size(draw2, height, x_padding2, x_padding2 * 3, y_padding2);
-
- State *state2 = state_create("$2", win2, draw2);
-
- Color color = { 0.4, 0.4, 0.4, 1 };
- Color purple = { 0.502, 0.168, 0.886, 1 };
- Color line_color = { 0.8, 0.8, 0.8, 1 };
- Color text_color = { 0.9, 0.9, 0.9, 1 };
-
- // Dwm tags
- DwmIpc *dwm = dwm_create(state, "/tmp/dwm.sock");
- dwm_register_tags(dwm, color, purple, text_color);
-
- int line_w = 0;
- register_buttons(state, color, text_color, line_color, line_w);
-
- // Buttons with special handling
-
- struct {
- State *state;
- timer_t timer;
- } date_ctx = { state, 0 };
-
- int text_w;
- draw_compute_text_size(state->draw, "Wednesday 31 12:34", &text_w, NULL);
- int min_w = text_w + line_w + state->draw->height;
-
- // Date & time button
- Button *date_btn = button_simple_create(PANGO_ALIGN_CENTER, color);
- button_simple_set_text(date_btn, NULL, text_color);
- button_simple_set_action(date_btn, NULL, &date_ctx);
- button_set_width(date_btn, 0, min_w);
- state_add_button(state, date_btn);
-
- struct sigevent sev = { 0 };
- sev.sigev_notify = SIGEV_SIGNAL;
- sev.sigev_signo = SIGUSR1;
-
- g_assert(timer_create(CLOCK_REALTIME, &sev, &date_ctx.timer) == 0);
- date_update(date_btn);
-
- // Quit button
- Button *q_btn = button_simple_create(PANGO_ALIGN_RIGHT, purple);
- button_simple_set_text(q_btn, g_strdup(""), text_color);
- button_simple_set_action(q_btn, quit_action, mainloop);
- state_add_button(state, q_btn);
-
- // Menu button(s)
- Color grey = { 0.5, 0.5, 0.5, 1 };
- Button *group = button_group_create(PANGO_ALIGN_LEFT, grey);
-
- Button *child1 = button_simple_create(PANGO_ALIGN_CENTER, color);
- button_set_padding(child1, 1, 1);
- button_simple_set_text(child1, g_strdup("C1"), text_color);
- button_simple_set_action(child1, show_action, NULL);
-
- Button *child2 = button_simple_create(PANGO_ALIGN_CENTER, color);
- button_set_padding(child2, 1, 1);
- button_simple_set_text(child2, g_strdup("C2"), text_color);
- button_simple_set_action(child2, show_action, NULL);
-
- Button *child3 = button_simple_create(PANGO_ALIGN_CENTER, color);
- button_set_padding(child3, 1, 1);
- button_simple_set_text(child3, g_strdup("C3"), text_color);
- button_simple_set_action(child3, show_action, NULL);
-
- struct {
- State *state;
- ButtonGroup *group;
- char *strings[2];
- GList *toggled;
- bool closed;
- } menu_ctx = { state, (gpointer)group, {"", ""}, NULL, true };
-
- Button *menu = button_simple_create(PANGO_ALIGN_LEFT, color);
- button_simple_set_text(menu, g_strdup(menu_ctx.strings[0]), text_color);
- button_simple_set_action(menu, menu_action, &menu_ctx);
-
- menu_ctx.toggled = g_list_append(menu_ctx.toggled, menu);
- menu_ctx.toggled = g_list_append(menu_ctx.toggled, child1);
- menu_ctx.toggled = g_list_append(menu_ctx.toggled, child2);
- menu_ctx.toggled = g_list_append(menu_ctx.toggled, child3);
-
- button_group_append(group, menu);
- state_add_button(state, group);
-
- state_order_button(state);
-
- Button *btn2 = button_simple_create(PANGO_ALIGN_LEFT, color);
- button_set_padding(btn2, 1, 1);
- button_simple_set_text(btn2, g_strdup("YAY"), text_color);
- button_simple_set_action(btn2, show_action, NULL);
-
- state_add_button(state2, btn2);
- state_order_button(state2);
-
- // TODO: Mirroring
- //for (GList *it = state->btns; it != NULL; it = it->next) {
- // state_add_button(state2, button_copy(it->data));
- //}
-
- connect_add_state(con, state);
- connect_add_state(con, state2);
- connect_attach_source(con);
-
- guint source_alrm = g_unix_signal_add(SIGUSR1, G_SOURCE_FUNC(date_update), date_btn);
- guint source_term = g_unix_signal_add(SIGTERM, mainloop_quit, mainloop);
- guint source_int = g_unix_signal_add(SIGINT, mainloop_quit, mainloop);
-
- state_request_redraw(state, true);
-
- log_debug("Starting main loop");
- g_main_loop_run(mainloop);
-
- log_debug("Cleaning main loop");
- g_clear_pointer(&mainloop, g_main_loop_unref);
-
- g_source_remove(source_alrm);
- g_source_remove(source_term);
- g_source_remove(source_int);
-
- // NOTE: Skip the first element (the open/close button)
- if (menu_ctx.closed)
- g_list_free_full(g_list_delete_link(menu_ctx.toggled, menu_ctx.toggled), (GDestroyNotify)button_destroy);
- else
- g_list_free(menu_ctx.toggled);
-
- timer_delete(date_ctx.timer);
- g_object_unref(context);
-
- // NOTE: Buttons are freed by state_destroy
- dwm_destroy(dwm);
-
- g_list_free_full(state->btns, (GDestroyNotify)button_destroy);
-
- state_destroy(state);
- draw_destroy(draw);
- window_destroy(win);
-
- state_destroy(state2);
- draw_destroy(draw2);
- window_destroy(win2);
-
- connect_destroy(con);
-
- return 0;
-}
-
-// vim: ts=4 sw=4 et
diff --git a/src/connect.c b/src/connect.c
deleted file mode 100644
index aaced77..0000000
--- a/src/connect.c
+++ /dev/null
@@ -1,408 +0,0 @@
-#include <glib.h>
-#include <xcb/xcb.h>
-#include <xcb/xcb_aux.h>
-#include <xcb/xcb_ewmh.h>
-#include <xcb/xcb_xrm.h>
-#include <xcb/xcb_errors.h>
-#include <xcb/randr.h>
-
-#include "log.h"
-#include "connect.h"
-#include "state.h"
-
-static bool query_xrm(Connection *con, const char *res, char **value)
-{
- if (xcb_xrm_resource_get_string(con->database, res, res, value) >= 0) {
- log_debug("Xrm query '%s' found '%s'", res, *value);
- return true;
- }
-
- log_debug("Xrm query '%s' not found", res);
- return false;
-}
-
-static void update_xrm(Connection *con)
-{
- xcb_flush(con->connection);
- xcb_xrm_database_t *database = xcb_xrm_database_from_default(con->connection);
-
- if (database == NULL) {
- log_warning("Xrm database couldn't be updated");
- return;
- }
-
- xcb_xrm_database_free(con->database);
- con->database = database;
- log_debug("Xrm database updated");
-}
-
-static void update_scale(Connection *con)
-{
- char *dpi_value;
- if (query_xrm(con, "Xft.dpi", &dpi_value)) {
- con->screen_dpi = strtod(dpi_value, NULL);
- g_free(dpi_value);
- } else {
- con->screen_dpi = (double)con->screen_size->height * 25.4 / (double)con->screen_size->mheight;
- log_debug("Fallback dpi value '%.2lf'", con->screen_dpi);
- }
-}
-
-// Check if point (px, py) is inside a rectangle in (x, y), (x+w, y), (x, y+h) and (w+h, y+h)
-static inline bool in_rect(int px, int py, int x, int y, int w, int h)
-{
- return px >= x && px <= x + w && py >= y && py <= y + h;
-}
-
-// Check if point (px, py) is inside a circle of radius r and center (x, y)
-static inline bool in_circle(int px, int py, int x, int y, int r)
-{
- int dx = x - px;
- int dy = y - py;
- return (dx * dx + dy * dy) <= r * r;
-}
-
-// Check if point (px, py) is inside a capsule in (x, y), (x+w, y), (x, y+h) and (w+h, y+h)
-static inline bool in_capsule(int px, int py, int x, int y, int w, int h)
-{
- g_assert(w >= h);
- int radius = h / 2;
-
- // Circle case
- if (w == h) return in_circle(px, py, x + radius, y + radius, radius);
-
- // Capsule case
- return in_circle(px, py, x + radius, y + radius, radius)
- || in_circle(px, py, x + w - radius, y + radius, radius)
- || in_rect(px, py, x + radius, y, w - 2 * radius, h);
-}
-
-static bool button_action_find(State *state, GList *layouts, int x, int y)
-{
- for (GList *it = layouts; it; it = it->next) {
- const Layout *layout = it->data;
-
- // Skip
- if (layout->x + layout->width < x) continue;
- if (layout->x > x) break;
-
- // Bound check click coordinates
- int w = layout->width - 2 * layout->x_pad;
- int h = layout->height - 2 * layout->y_pad;
-
- if (!in_capsule(x, y, layout->x + layout->x_pad, layout->y + layout->y_pad, w, h))
- continue;
-
- Button *btn = layout->btn;
- if (!layout->btn->simple) {
- log_debug("Button group layout [x=%d, y=%d, w=%d, h=%d, button=%p]",
- layout->x, layout->y, layout->width, layout->height, btn);
-
- // Check the group children
- return button_action_find(state, layout->children, x, y);
- }
-
- log_debug("Button layout [x=%d, y=%d, w=%d, h=%d, button=%p]",
- layout->x, layout->y, layout->width, layout->height, btn);
-
- ButtonAction action = button_simple_get_action(btn);
- if (action == NULL) {
- // TODO: Button labels
- log_debug("Ignoring button without action [button=%p]", btn);
- return true;
- }
-
- // NOTE: Animations may change the layouts!
- Animation *anim = animation_shine_create(MILLIS(250));
- //Animation *anim = animation_pulse_create(MILLIS(200));
-
- if (button_set_animation(btn, anim))
- state_request_animation(state);
- else
- animation_destroy(anim);
-
- log_info("Triggering action for button [text=\"%s\", button=%p]", button_simple_get_text(btn), btn);
- action(btn);
- return true;
- }
-
- return false;
-}
-
-static void button_action(State *state, const char *event, int x, int y)
-{
- double scale = window_get_scale(state->win);
- int digital_x = x / scale;
- int digital_y = y / scale;
-
- log_debug("Checking %s event [device_x=%d, device_y=%d, x=%d, y=%d]", event, x, y, digital_x, digital_y);
- if (!button_action_find(state, state->draw->layouts, digital_x, digital_y))
- log_debug("Ignoring %s", event);
-}
-
-typedef struct {
- GSource source;
- Connection *con;
- gpointer fd_tag;
- xcb_generic_event_t *event;
-} EventSource;
-
-static gboolean source_check(GSource *source)
-{
- EventSource *xsource = (EventSource *)source;
- xcb_flush(xsource->con->connection);
- g_assert_null(xsource->event);
-
- GIOCondition flags = g_source_query_unix_fd(source, xsource->fd_tag);
- if (flags & G_IO_IN) {
- g_assert_false(xcb_connection_has_error(xsource->con->connection));
- xsource->event = xcb_poll_for_event(xsource->con->connection);
- }
-
- return xsource->event != NULL;
-}
-
-static gboolean source_dispatch(GSource *source, GSourceFunc callback, gpointer data)
-{
- EventSource *xsource = (EventSource *)source;
- g_assert_nonnull(xsource->event);
-
- do {
- switch (xsource->event->response_type & ~0x80) {
- case 0: {
- xcb_generic_error_t *error = (xcb_generic_error_t *)xsource->event;
-
- const char *extension;
- const char *name = xcb_errors_get_name_for_error(xsource->con->errors, error->error_code, &extension);
- const char *major = xcb_errors_get_name_for_major_code(xsource->con->errors, error->major_code);
- const char *minor = xcb_errors_get_name_for_minor_code(xsource->con->errors, error->major_code, error->minor_code);
-
- // TODO: Handle errors instead of aborting
- log_error("Xcb error '%s' [extension=%s, major=%s, minor=%s, resource=%u, sequence=%u]",
- name,
- extension ? extension : "none",
- major,
- minor ? minor : "none",
- (unsigned int)error->resource_id,
- (unsigned int)error->sequence);
- break;
- }
-
- case XCB_EXPOSE: {
- xcb_expose_event_t *expose = (xcb_expose_event_t *)xsource->event;
- log_debug("Processing event 'Expose' [type=%d]", XCB_EXPOSE);
-
- for (GList *it = xsource->con->states; it != NULL; it = it->next) {
- State *state = it->data;
- if (state->win->window == expose->window) {
- state_request_redraw(state, true);
- break;
- }
- }
- break;
- }
-
- case XCB_CREATE_NOTIFY: {
- xcb_create_notify_event_t *create = (xcb_create_notify_event_t *)xsource->event;
- log_debug("Processing event 'CreateNotify' [type=%d]", XCB_CREATE_NOTIFY);
-
- // TODO: Circulate top the window if override_redirect == 0
-
- break;
- }
-
- case XCB_BUTTON_RELEASE: {
- xcb_button_release_event_t *button = (xcb_button_release_event_t *)xsource->event;
- log_debug("Processing event 'ButtonRelease' [type=%d]", XCB_BUTTON_RELEASE);
-
- // TODO: Handle different actions properly
- switch (button->detail) {
- case XCB_BUTTON_INDEX_2: // left click
- case XCB_BUTTON_INDEX_1: // right click
- case XCB_BUTTON_INDEX_3: // middle click
- for (GList *it = xsource->con->states; it != NULL; it = it->next) {
- State *state = it->data;
- if (state->win->window == button->event) {
- button_action(state, "button release", button->event_x, button->event_y);
- break;
- }
- }
- break;
-
- default:
- log_debug("Ignoring button release [button=%d]", button->detail);
- break;
- }
- break;
- }
-
- // TODO: Implement correctly hovering
- //case XCB_MOTION_NOTIFY: {
- // xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xsource->event;
- // log_debug("Processing event 'MotionNotify' [type=%d]", XCB_MOTION_NOTIFY);
- // button_action(xsource->con->state, "motion notify", motion->event_x, motion->event_y);
- // break;
- //}
-
- case XCB_PROPERTY_NOTIFY: {
- xcb_property_notify_event_t *property = (xcb_property_notify_event_t *)xsource->event;
- log_debug("Processing event 'PropertyNotify' [type=%d]", XCB_PROPERTY_NOTIFY);
-
- if (property->atom == XCB_ATOM_RESOURCE_MANAGER) {
- update_xrm(xsource->con);
- update_scale(xsource->con);
- for (GList *it = xsource->con->states; it != NULL; it = it->next)
- state_request_redraw(it->data, true);
- }
- break;
- }
-
- default: {
- const char *extension;
- const char *name = xcb_errors_get_name_for_xcb_event(xsource->con->errors, xsource->event, &extension);
-
- // TODO: Handle XCB_RANDR_SCREEN_CHANGE_NOTIFY
-
- log_debug("Ignoring event '%s' [type=%d, extension=%s]",
- name,
- xsource->event->response_type & 0x7f,
- extension ? extension : "none");
- }
- }
- g_free(xsource->event);
- } while ((xsource->event = xcb_poll_for_event(xsource->con->connection)) != NULL);
-
- return G_SOURCE_CONTINUE;
-}
-
-static GSourceFuncs source_fns = {
- NULL,
- source_check,
- source_dispatch,
- NULL,
-};
-
-static void attach_source(Connection *con)
-{
- EventSource *source = (EventSource *)g_source_new(&source_fns, sizeof(EventSource));
- con->source = (GSource *)source;
- g_source_set_static_name(con->source, "EventSource");
-
- source->con = con;
- source->event = NULL;
- source->fd_tag = g_source_add_unix_fd(con->source, xcb_get_file_descriptor(con->connection), G_IO_IN | G_IO_HUP | G_IO_ERR);
-
- g_source_attach(con->source, NULL);
-}
-
-Connection *connect_create()
-{
- Connection *con = g_malloc0(sizeof(Connection));
- g_assert_nonnull(con);
-
- int preferred_screen = 0;
- con->connection = xcb_connect(NULL, &preferred_screen);
- g_assert_true(con->connection != NULL && !xcb_connection_has_error(con->connection));
- log_debug("Xcb connection established");
-
- log_debug("Default screen '%d'", preferred_screen);
- xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(con->connection));
-
- while (preferred_screen != 0 && iter.rem) {
- xcb_screen_next(&iter);
- preferred_screen--;
- }
-
- con->screen = iter.data;
- xcb_generic_error_t *error;
-
- xcb_randr_query_version_cookie_t version_cookie = xcb_randr_query_version(con->connection,
- XCB_RANDR_MAJOR_VERSION,
- XCB_RANDR_MINOR_VERSION);
-
- xcb_randr_query_version_reply_t *randr_version = xcb_randr_query_version_reply(con->connection,
- version_cookie,
- &error);
-
- g_assert_null(error);
- log_debug("RandR loaded [version=%d.%d]", randr_version->major_version, randr_version->minor_version);
- g_assert_cmpint(randr_version->major_version, >=, 1);
- g_free(randr_version);
-
- xcb_randr_get_screen_info_cookie_t cookie = xcb_randr_get_screen_info(con->connection, con->screen->root);
- con->info_reply = xcb_randr_get_screen_info_reply(con->connection, cookie, &error);
- g_assert_null(error);
-
- con->screen_size = xcb_randr_get_screen_info_sizes(con->info_reply);
- g_assert_nonnull(con->screen_size);
- log_debug("Screen size [width=%d, height=%d]", con->screen_size->width, con->screen_size->height);
-
- xcb_randr_select_input(con->connection,
- con->screen->root,
- XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE |
- XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE |
- XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY);
-
- log_debug("Xcb searching 32 bit visual");
- con->visual_type = xcb_aux_find_visual_by_attrs(con->screen, XCB_VISUAL_CLASS_TRUE_COLOR, 32);
- con->screen_depth = 32;
-
- if (con->visual_type == NULL) {
- // NOTE: 24 bit visuals don't have the alpha channel for transparency
- log_debug("Fallback to 24 bit visual");
- con->visual_type = xcb_aux_find_visual_by_attrs(con->screen, XCB_VISUAL_CLASS_TRUE_COLOR, 24);
- con->screen_depth = 24;
- }
-
- g_assert_nonnull(con->visual_type);
- log_debug("Xcb visual type found [id=%u]", con->visual_type->visual_id);
-
- xcb_intern_atom_cookie_t *ewmh_cookie = xcb_ewmh_init_atoms(con->connection, &con->ewmh);
- g_assert_true(xcb_ewmh_init_atoms_replies(&con->ewmh, ewmh_cookie, &error));
- g_assert_null(error);
- log_debug("Xcb ewmh initialized");
-
- con->database = xcb_xrm_database_from_default(con->connection);
- g_assert_nonnull(con->database);
-
- // TODO: Dpi aware scaling
- update_scale(con);
-
- g_assert(xcb_errors_context_new(con->connection, &con->errors) == 0);
- log_debug("Xcb errors loaded");
-
- xcb_flush(con->connection);
- log_debug("Xcb set up");
-
- return con;
-}
-
-void connect_attach_source(Connection *con)
-{
- g_assert_null(con->source);
- attach_source(con);
- log_debug("Xcb event loop attached");
-}
-
-void connect_add_state(Connection *con, State *state)
-{
- g_assert_nonnull(state);
- con->states = g_list_append(con->states, state);
- log_debug("Add state to event loop [state=%p, state=\"%s\"]", state, state->label);
-}
-
-void connect_destroy(Connection *con)
-{
- g_source_destroy(con->source);
- g_source_unref(con->source);
-
- xcb_ewmh_connection_wipe(&con->ewmh);
- xcb_errors_context_free(con->errors);
- xcb_xrm_database_free(con->database);
- xcb_disconnect(con->connection);
-
- g_free(con->info_reply);
- g_free(con);
-}
-
-// vim: ts=4 sw=4 et
diff --git a/src/connect.h b/src/connect.h
deleted file mode 100644
index dbb650c..0000000
--- a/src/connect.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef COMET_CONNEC_H
-#define COMET_CONNEC_H
-
-#include <glib.h>
-#include <xcb/xcb.h>
-#include <xcb/xcb_ewmh.h>
-#include <xcb/xcb_xrm.h>
-#include <xcb/xcb_errors.h>
-#include <xcb/randr.h>
-
-// Forward declaration
-typedef struct State State;
-
-typedef struct Connection Connection;
-
-// TODO: Make this opaque
-struct Connection {
- xcb_connection_t *connection;
- xcb_screen_t *screen;
- xcb_randr_get_screen_info_reply_t *info_reply;
- xcb_randr_screen_size_t *screen_size;
- double screen_dpi;
- int screen_depth;
- xcb_visualtype_t *visual_type;
- xcb_xrm_database_t *database;
- xcb_errors_context_t *errors;
- xcb_ewmh_connection_t ewmh;
- GSource *source;
- GList *states;
-};
-
-Connection *connect_create();
-
-void connect_attach_source(Connection *con);
-
-void connect_add_state(Connection *con, State *state);
-
-void connect_destroy(Connection *con);
-
-#endif
-
-// vim: ts=4 sw=4 et
diff --git a/src/draw.c b/src/draw.c
deleted file mode 100644
index 44baba6..0000000
--- a/src/draw.c
+++ /dev/null
@@ -1,391 +0,0 @@
-#include <glib.h>
-#include <math.h>
-#include <pango/pangocairo.h>
-#include <pango/pango-font.h>
-#include <pango/pango-types.h>
-
-#include "draw.h"
-#include "button.h"
-#include "log.h"
-
-#define ANIMATION(btn, which, ...) \
- do { \
- if ((btn)->anim != NULL && (btn)->anim->which##_func != NULL) { \
- if ((btn)->anim->start == 0) { \
- (btn)->anim->start = g_get_monotonic_time(); \
- log_debug("Starting animation [type=%d, func=%s, start=%ld, duration=%ld, button=%p]", \
- (btn)->anim->type, #which, (btn)->anim->start, (btn)->anim->duration, (btn)); \
- } \
- if (!(btn)->anim->which##_func((btn)->anim, __VA_ARGS__)) \
- (btn)->anim->which##_func = NULL; \
- } \
- } while (false)
-
-Drawer *draw_create()
-{
- Drawer *draw = g_malloc0(sizeof(Drawer));
- g_assert_nonnull(draw);
- return draw;
-}
-
-static void paint_button(cairo_t *cr, const Layout *layout)
-{
- double degree = M_PI / 180.0;
- int radius = (layout->height - 2 * layout->y_pad) / 2;
- int line_radius = radius - layout->line_w / 2;
-
-#if 0
- // Debug lines
-
- // Layout size
- cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_move_to(cr, layout->x, layout->y);
- cairo_line_to(cr, layout->x, layout->y + layout->height);
- cairo_stroke(cr);
-
- cairo_move_to(cr, layout->x + layout->width, layout->y);
- cairo_line_to(cr, layout->x + layout->width, layout->y + layout->height);
- cairo_stroke(cr);
-
- // Layout padding
- cairo_set_source_rgb(cr, 0.5, 0.1, 0.1);
- cairo_rectangle(cr, layout->x + layout->x_pad, layout->y + layout->y_pad, layout->width - 2 * layout->x_pad, layout->height - 2 * layout->y_pad);
- cairo_stroke(cr);
-#endif
-
- cairo_set_line_width(cr, layout->line_w);
-
- // Button background
- Color color = layout->btn->color;
- cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
- cairo_new_sub_path(cr);
- cairo_arc(cr, layout->x + layout->x_pad + radius, layout->y + layout->y_pad + radius, radius, 90 * degree, 270 * degree);
- cairo_arc(cr, layout->x + layout->width - layout->x_pad - radius, layout->y + layout->y_pad + radius, radius, 270 * degree, 450 * degree);
- cairo_close_path(cr);
- cairo_fill(cr);
-
- // Button border
- color = layout->btn->line_color;
- cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
- cairo_new_sub_path(cr);
- cairo_arc(cr, layout->x + layout->x_pad + radius, layout->y + layout->y_pad + radius, line_radius, 90 * degree, 270 * degree);
- cairo_arc(cr, layout->x + layout->width - layout->x_pad - radius, layout->y + layout->y_pad + radius, line_radius, 270 * degree, 450 * degree);
- cairo_close_path(cr);
- cairo_stroke(cr);
-}
-
-static void paint_text(cairo_t *cr, const Layout *layout)
-{
- int text_x = layout->x + layout->width / 2 - layout->text_w / 2;
- int text_y = layout->y + layout->height / 2 - layout->text_h / 2;
-
- Color color = CAST(layout->btn, ButtonSimple)->text_color;
- cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
- cairo_move_to(cr, text_x, text_y);
-
- // NOTE: This works only if the text didn't change in size after the layouting
- pango_layout_set_text(layout->pl, CAST(layout->btn, ButtonSimple)->text, -1);
- pango_cairo_update_layout(cr, layout->pl);
- pango_cairo_show_layout(cr, layout->pl);
-}
-
-static void paint_button_list(cairo_t *cr, GList *layouts)
-{
- for (GList *it = layouts; it; it = it->next) {
- Layout *layout = it->data;
- Button *btn = layout->btn;
-
- cairo_push_group(cr);
-
- // Apply before_func on the layout and cairo context
- ANIMATION(btn, before, layout, cr);
-
- paint_button(cr, layout);
-
- if (btn->simple) {
- g_assert_null(layout->children);
- paint_text(cr, layout);
- } else {
- g_assert_nonnull(layout->children);
- paint_button_list(cr, layout->children);
- }
-
- // Apply after_func on the layout and cairo context
- ANIMATION(btn, after, layout, cr);
-
- cairo_pop_group_to_source(cr);
- cairo_paint(cr);
- }
-}
-
-void draw_paint(Drawer *draw, Window *win)
-{
- // Back buffering
- cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, draw->width, draw->height);
-
- cairo_t *cr = cairo_create(surface);
- cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
-
- // Fill the background
- cairo_set_source_rgba(cr, draw->background.r, draw->background.g, draw->background.b, draw->background.a);
- cairo_paint(cr);
-
- // Treat the top-level buttons similarly to a button group
- paint_button_list(cr, draw->layouts);
- cairo_destroy(cr);
-
- // Use device pixels
- double scale = window_get_scale(win);
- window_move(win, draw->left_pad * scale, draw->top_pad * scale);
- window_resize(win, draw->width * scale, draw->height * scale);
-
- window_paint_surface(win, surface, draw->width * scale, draw->height * scale);
- cairo_surface_destroy(surface);
-}
-
-void layout_destroy(Layout *layout)
-{
- if (layout->pl != NULL)
- g_object_unref(layout->pl);
-
- g_list_free_full(layout->children, (GDestroyNotify)layout_destroy);
- g_free(layout);
-}
-
-static void layout_invalidate(GList *layouts)
-{
- g_list_free_full(layouts, (GDestroyNotify)layout_destroy);
-}
-
-static void layout_adjust(GList *start, GList *end, int off)
-{
- // NOTE: end must be present in the list or segfault
- for (GList *it = start; it != end; it = it->next) {
- Layout *layout = it->data;
- layout->x += off;
- layout_adjust(layout->children, NULL, off);
- }
-}
-
-static void layout_set_text(Layout *layout, PangoFontDescription *desc, int height)
-{
- g_assert(layout->btn->simple);
- const char *text = CAST(layout->btn, ButtonSimple)->text;
-
- pango_layout_set_font_description(layout->pl, desc);
- pango_layout_set_alignment(layout->pl, PANGO_ALIGN_CENTER);
- pango_layout_set_height(layout->pl, 0);
- pango_layout_set_text(layout->pl, text, -1);
- pango_layout_get_pixel_size(layout->pl, &layout->text_w, &layout->text_h);
-
- // If there is only one glyph the button should be round
- size_t text_l = g_utf8_strlen(text, -1);
- layout->width = text_l == 1 ? height : layout->text_w + height;
-}
-
-static void compute_width(Drawer *draw, Window *win)
-{
- int screen_width = win->con->screen_size->width;
- double scale = window_get_scale(win);
- draw->width = (screen_width - draw->right_pad - draw->left_pad) / scale;
- log_debug("Draw context width calculated [scale=%lf, width=%d]", scale, draw->width);
-}
-
-static void layout_check_width(Layout *layout)
-{
- // FIXME: Max width is not implemented correctly
- if (layout->btn->max_width > 0)
- layout->width = MIN(layout->btn->max_width, layout->width);
-
- if (layout->btn->min_width > 0)
- layout->width = MAX(layout->btn->min_width, layout->width);
-}
-
-static GList *compute_group_layout(Drawer *draw, GList *btns, int bx, bool root)
-{
- GList *layouts = NULL;
- for (GList *it = btns; it; it = it->next) {
- Button *btn = it->data;
- PangoAlignment align = btn->align;
-
- Layout *layout = g_malloc0(sizeof(Layout));
- layouts = g_list_prepend(layouts, layout);
-
- layout->btn = btn;
- layout->height = draw->height;
- layout->line_w = btn->line_width;
- layout->x_pad = btn->x_pad;
- layout->y_pad = btn->y_pad;
- layout->x = bx;
- layout->y = 0;
-
-retry:
- if (!btn->simple) {
- ButtonGroup *group = CAST(btn, ButtonGroup);
- g_assert_nonnull(group->children);
-
- // NOTE: If a group has only one children treat it as a single button
- // As a consequence btn->align can't be trusted
- if (group->children->next == NULL) {
- // XXX: We should also keep track of the group animation
- // Is this the right way to do it? Can it loop?
- ANIMATION(btn, layout, layout);
-
- layout->btn = btn = group->children->data;
- goto retry;
- } else {
- layout->children = compute_group_layout(draw, group->children, bx, false);
- g_assert_nonnull(layout->children);
-
- Layout *last = g_list_last(layout->children)->data;
- layout->width = last->x + last->width - bx;
-
- // FIXME: Temporary solution to make the antialiasing (or the circles not
- // overlapping correctly) problem less noticeable
- bool fix_left = CAST(layout->children->data, Layout)->x_pad == 0;
- if (fix_left) {
- layout->x += 1;
- layout->width -= 1;
- }
-
- bool fix_right = last->x_pad == 0;
- if (fix_right)
- layout->width -= 1;
- }
- } else {
- layout->pl = pango_layout_new(draw->context);
- layout_set_text(layout, draw->desc, draw->height);
- }
-
- // NOTE: We add half a line width on both sides
- layout->width += layout->line_w;
- layout_check_width(layout);
-
- // Apply layout_func on the layout
- ANIMATION(btn, layout, layout);
-
- bx += layout->width;
- if (root) {
- draw->layout_bx[align] = bx;
- draw->layout_end[align] = layouts;
- }
-
- if (it->next != NULL && (!root || CAST(it->next->data, Button)->align == align))
- bx += draw->sep;
- }
-
- // Otherwise button_action_find will not work!
- layouts = g_list_reverse(layouts);
- return layouts;
-}
-
-void draw_compute_layout(Drawer *draw, Window *win, GList *btns)
-{
- // Move this somewhere else
- compute_width(draw, win);
-
- double scale = window_get_scale(win);
- cairo_surface_set_device_scale(win->surface, scale, scale);
- pango_cairo_context_set_resolution(draw->context, scale * 96);
- pango_cairo_update_context(win->cr, draw->context);
-
- memset(draw->layout_end, 0, sizeof(draw->layout_end));
- memset(draw->layout_bx, 0, sizeof(draw->layout_bx));
-
- g_clear_pointer(&draw->layouts, layout_invalidate);
- draw->layouts = compute_group_layout(draw, btns, 0, true);
-
- draw->layout_width[PANGO_ALIGN_LEFT] = draw->layout_bx[PANGO_ALIGN_LEFT];
- draw->layout_width[PANGO_ALIGN_CENTER] = draw->layout_bx[PANGO_ALIGN_CENTER] - draw->layout_bx[PANGO_ALIGN_LEFT];
- draw->layout_width[PANGO_ALIGN_RIGHT] = draw->layout_bx[PANGO_ALIGN_RIGHT] - MAX(draw->layout_bx[PANGO_ALIGN_CENTER], draw->layout_bx[PANGO_ALIGN_LEFT]);
-
- if (draw->layout_bx[PANGO_ALIGN_RIGHT] > draw->width) {
- log_error("Layout is bigger than the window (%d vs %d)", draw->layout_bx[PANGO_ALIGN_RIGHT], draw->width);
- }
-
- bool has_left = draw->layout_end[PANGO_ALIGN_LEFT] != NULL;
- bool has_center = draw->layout_end[PANGO_ALIGN_CENTER] != NULL;
-
- GList *center_start = has_left ? draw->layout_end[PANGO_ALIGN_LEFT]->next : draw->layouts;
- GList *right_start = has_center ? draw->layout_end[PANGO_ALIGN_CENTER]->next :
- has_left ? draw->layout_end[PANGO_ALIGN_LEFT]->next : draw->layouts;
-
- if (center_start != NULL) {
- int center = round(draw->width / 2);
- int center_off = center - draw->layout_width[PANGO_ALIGN_CENTER] / 2 - draw->layout_bx[PANGO_ALIGN_LEFT];
-
- log_debug("Aligning center layout [center=%d, off=%d]", center, center_off);
- layout_adjust(center_start, right_start, center_off);
- }
-
- if (right_start != NULL) {
- int right = draw->width - draw->layout_width[PANGO_ALIGN_RIGHT];
- int right_off = right - MAX(draw->layout_bx[PANGO_ALIGN_LEFT], draw->layout_bx[PANGO_ALIGN_CENTER]);
-
- log_debug("Aligning right layout [x=%d, off=%d]", right, right_off);
- layout_adjust(right_start, NULL, right_off);
- }
-
- log_debug("Updated layouts");
-}
-
-void draw_compute_text_size(Drawer *draw, const char *text, int *text_w, int *text_h)
-{
- PangoLayout *pl = pango_layout_new(draw->context);
- pango_layout_set_font_description(pl, draw->desc);
- pango_layout_set_height(pl, 0);
- pango_layout_set_alignment(pl, PANGO_ALIGN_CENTER);
- pango_layout_set_text(pl, text, -1);
- pango_layout_get_pixel_size(pl, text_w, text_h);
- g_object_unref(pl);
-}
-
-void draw_set_background(Drawer *draw, Color background)
-{
- draw->background = background;
-}
-
-void draw_set_separator(Drawer *draw, int sep)
-{
- g_assert(sep >= 0);
- draw->sep = sep;
-}
-
-void draw_set_font(Drawer *draw, const char *font)
-{
- log_debug("Pango loading font description '%s'", font);
- draw->desc = pango_font_description_from_string(font);
- g_assert_nonnull(draw->desc);
- log_debug("Pango found matching font '%s'", pango_font_description_get_family(draw->desc));
-}
-
-// NOTE: Don't call this between layout and paint!
-void draw_set_context(Drawer *draw, PangoContext *context)
-{
- g_assert_nonnull(context);
- draw->context = context;
- log_debug("Pango context updated [context=%p]", context);
-}
-
-void draw_set_size(Drawer *draw, int height, int left_pad, int right_pad, int top_pad)
-{
- g_assert(height > 0);
-
- draw->height = height;
- draw->left_pad = left_pad;
- draw->right_pad = right_pad;
- draw->top_pad = top_pad;
-
- log_debug("Draw context size updated [height=%d, left_pad=%d, right_pad=%d, top_pad=%d]",
- height, left_pad, right_pad, top_pad);
-}
-
-void draw_destroy(Drawer *draw)
-{
- g_clear_pointer(&draw->layouts, layout_invalidate);
- pango_font_description_free(draw->desc);
- g_free(draw);
-}
-
-// vim: ts=4 sw=4 et
diff --git a/src/draw.h b/src/draw.h
deleted file mode 100644
index 6d0119f..0000000
--- a/src/draw.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef COMET_DRAW_H
-#define COMET_DRAW_H
-
-#include <glib.h>
-#include <pango/pango-font.h>
-#include <pango/pangocairo.h>
-
-#include "window.h"
-
-typedef struct {
- double r, g, b, a;
-} Color;
-
-// The one who draws ('o')7
-
-typedef struct {
- PangoFontDescription *desc;
- PangoContext *context;
- int height;
- int width;
- int left_pad;
- int right_pad;
- int top_pad;
- int sep;
- Color background;
- GList *layouts;
- // Calculated by draw_compute_layout
- GList *layout_end[3];
- int layout_bx[3];
- int layout_width[3];
-} Drawer;
-
-typedef struct {
- struct Button *btn;
- int x, y;
- int width, height;
- int text_w, text_h;
- int x_pad, y_pad;
- int line_w;
- PangoLayout *pl;
- GList *children;
-} Layout;
-
-Drawer *draw_create();
-
-void draw_paint(Drawer *draw, Window *win);
-
-void layout_destroy(Layout *layout);
-
-// TODO: Rework the api so that we don't need to pass the window
-void draw_compute_layout(Drawer *draw, Window *win, GList *btns);
-
-void draw_compute_text_size(Drawer *draw, const char *text, int *text_w, int *text_h);
-
-void draw_set_background(Drawer *draw, Color background);
-
-void draw_set_separator(Drawer *draw, int sep);
-
-void draw_set_font(Drawer *draw, const char *font);
-
-void draw_set_context(Drawer *draw, PangoContext *context);
-
-void draw_set_size(Drawer *draw, int height, int left_pad, int right_pad, int top_pad);
-
-void draw_destroy(Drawer *draw);
-
-#endif
-
-// vim: ts=4 sw=4 et
diff --git a/src/dwm.c b/src/dwm.c
deleted file mode 100644
index eda553e..0000000
--- a/src/dwm.c
+++ /dev/null
@@ -1,445 +0,0 @@
-#include <stdbool.h>
-#include <stdint.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <json-glib/json-glib.h>
-#include <json-glib/json-builder.h>
-
-#include "dwm.h"
-#include "log.h"
-
-#define IPC_MAGIC "DWM-IPC"
-#define IPC_MAGIC_LEN 7
-
-typedef struct {
- uint8_t magic[IPC_MAGIC_LEN];
- uint32_t size;
- uint8_t type;
-} __attribute__((packed)) DwmIpcHeader;
-
-typedef enum {
- IPC_TYPE_RUN_COMMAND = 0,
- IPC_TYPE_GET_MONITORS = 1,
- IPC_TYPE_GET_TAGS = 2,
- IPC_TYPE_GET_LAYOUTS = 3,
- IPC_TYPE_GET_DWM_CLIENT = 4,
- IPC_TYPE_SUBSCRIBE = 5,
- IPC_TYPE_EVENT = 6
-} DwmIpcMessage;
-
-#define IPC_EVENT_TAG_CHANGE "tag_change_event"
-#define IPC_EVENT_CLIENT_FOCUS_CHANGE "client_focus_change_event"
-#define IPC_EVENT_LAYOUT_CHANGE "layout_change_event"
-#define IPC_EVENT_MONITOR_FOCUS_CHANGE "monitor_focus_change_event"
-#define IPC_EVENT_FOCUSED_TITLE_CHANGE "focused_title_change_event"
-#define IPC_EVENT_FOCUSED_STATE_CHANGE "focused_state_change_event"
-
-static void ipc_send(DwmIpc *dwm, DwmIpcMessage msg_type, uint8_t *msg, uint32_t msg_size)
-{
- DwmIpcHeader header;
- memcpy(header.magic, IPC_MAGIC, IPC_MAGIC_LEN);
- header.size = msg_size;
- header.type = msg_type;
-
- GError *error = NULL;
-
- gssize size = 0;
- while (size < sizeof(DwmIpcHeader)) {
- gssize sent = g_socket_send(dwm->socket, (void *)&header + size, sizeof(DwmIpcHeader) - size, NULL, &error);
- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
- g_error_free(error);
- continue;
- }
- g_assert(sent != -1);
- size += sent;
- }
-
- size = 0;
- while (size < msg_size) {
- gssize sent = g_socket_send(dwm->socket, msg + size, msg_size - size, NULL, &error);
- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
- g_error_free(error);
- continue;
- }
- g_assert(sent != -1);
- size += sent;
- }
-
- log_debug("Sent ipc message [type=%d, size=%d]", msg_type, msg_size);
-}
-
-static void ipc_subscribe(DwmIpc *dwm, const char *event)
-{
- // {
- // "event": "<event>",
- // "action": "subscribe"
- // }
-
- JsonBuilder *builder = json_builder_new();
-
- json_builder_begin_object(builder);
-
- json_builder_set_member_name(builder, "event");
- json_builder_add_string_value(builder, event);
-
- json_builder_set_member_name(builder, "action");
- json_builder_add_string_value(builder, "subscribe");
-
- json_builder_end_object(builder);
-
- JsonNode *root = json_builder_get_root(builder);
-
- JsonGenerator *gen = json_generator_new();
- json_generator_set_root(gen, root);
-
- gsize msg_len = 0;
- gchar *msg = json_generator_to_data(gen, &msg_len);
-
- log_debug("Subscribing to dwm ipc: %s", msg);
- ipc_send(dwm, IPC_TYPE_SUBSCRIBE, msg, msg_len);
-
- json_node_free(root);
- g_object_unref(gen);
- g_object_unref(builder);
- g_free(msg);
-}
-
-static void ipc_run_command(DwmIpc *dwm, const char *cmd, JsonNode **args)
-{
- // {
- // "command": "<name>",
- // "args": [ ... ]
- // }
-
- JsonBuilder *builder = json_builder_new();
-
- json_builder_begin_object(builder);
-
- json_builder_set_member_name(builder, "command");
- json_builder_add_string_value(builder, cmd);
-
- json_builder_set_member_name(builder, "args");
- json_builder_begin_array(builder);
-
- while (*args != NULL) {
- json_builder_add_value(builder, *args++);
- }
-
- json_builder_end_array(builder);
- json_builder_end_object(builder);
-
- JsonNode *root = json_builder_get_root(builder);
-
- JsonGenerator *gen = json_generator_new();
- json_generator_set_root(gen, root);
-
- gsize msg_len = 0;
- gchar *msg = json_generator_to_data(gen, &msg_len);
-
- log_debug("Sending run_command to dwm ipc: %s", msg);
- ipc_send(dwm, IPC_TYPE_RUN_COMMAND, msg, msg_len);
-
- json_node_free(root);
- g_object_unref(gen);
- g_object_unref(builder);
- g_free(msg);
-}
-
-static void ipc_get_tags(DwmIpc *dwm)
-{
- log_debug("Sending get_tags to dwm ipc");
- ipc_send(dwm, IPC_TYPE_GET_TAGS, "", 1);
-}
-
-#define JSON_FIELD(reader, member) (json_reader_end_member(reader), json_reader_read_member(reader, member))
-
-static void ipc_handle(DwmIpc *dwm, DwmIpcMessage type, char *reply, uint32_t reply_size)
-{
- GError *error = NULL;
- JsonParser *parser = json_parser_new();
- if (!json_parser_load_from_data(parser, reply, reply_size - 1, &error)) {
- log_warning("Failed to parse dwm ipc reply: %s", error->message);
- g_error_free(error);
- return;
- }
-
- JsonReader *reader = json_reader_new(json_parser_get_root(parser));
-
- switch (type) {
- case IPC_TYPE_EVENT:
- {
- if (json_reader_read_member(reader, IPC_EVENT_TAG_CHANGE)) {
- log_debug("Handling dwm ipc event [event=%s]", IPC_EVENT_TAG_CHANGE);
-
- json_reader_read_member(reader, "new_state");
- json_reader_read_member(reader, "selected");
- long selected = json_reader_get_int_value(reader);
- json_reader_end_member(reader);
- json_reader_end_member(reader);
- json_reader_end_member(reader);
-
- log_debug("Selected tag mask: %ld", selected);
-
- if (dwm->tags[0] != NULL) {
- for (int i = 0; i < 9; i++)
- dwm->tags[i]->color = selected & (1 << i) ? dwm->selected : dwm->color;
-
- state_request_redraw(dwm->state, false);
- }
- } else if (JSON_FIELD(reader, IPC_EVENT_CLIENT_FOCUS_CHANGE)) {
- log_debug("Handling dwm ipc event [event=%s]", IPC_EVENT_CLIENT_FOCUS_CHANGE);
-
- json_reader_read_member(reader, "new_win_id");
- long win_id = json_reader_get_int_value(reader);
- json_reader_end_member(reader);
- json_reader_end_member(reader);
-
- char *msg = g_strdup_printf("{ \"client_window_id\": %ld }\n", win_id);
- dwm->change_title = true;
- ipc_send(dwm, IPC_TYPE_GET_DWM_CLIENT, msg, strlen(msg));
- g_free(msg);
- } else if (JSON_FIELD(reader, IPC_EVENT_LAYOUT_CHANGE)) {
- log_debug("Ignoring dwm ipc event [event=%s]", IPC_EVENT_LAYOUT_CHANGE);
- // TODO
-
- } else if (JSON_FIELD(reader, IPC_EVENT_MONITOR_FOCUS_CHANGE)) {
- log_debug("Ignoring dwm ipc event [event=%s]", IPC_EVENT_MONITOR_FOCUS_CHANGE);
- // TODO
-
- } else if (JSON_FIELD(reader, IPC_EVENT_FOCUSED_TITLE_CHANGE)) {
- log_debug("Ignoring dwm ipc event [event=%s]", IPC_EVENT_FOCUSED_TITLE_CHANGE);
- // TODO
-
- } else if (JSON_FIELD(reader, IPC_EVENT_FOCUSED_STATE_CHANGE)) {
- log_debug("Ignoring dwm ipc event [event=%s]", IPC_EVENT_FOCUSED_STATE_CHANGE);
- // TODO
-
- } else {
- const char *event = "?";
- if (json_reader_read_element(reader, 0))
- event = json_reader_get_string_value(reader);
-
- log_warning("Unrecognized dwm ipc event: %s", event);
- }
- break;
- }
-
- case IPC_TYPE_GET_DWM_CLIENT:
- {
- log_debug("Received dwm client information message [type=%d]", type);
-
- if (dwm->change_title) {
- json_reader_read_member(reader, "name");
- const char *title = json_reader_get_string_value(reader);
-
- log_debug("Changing current program title: %s", title ? title : "?");
- if (title == NULL || *title == '\0') {
- state_remove_button(dwm->state, dwm->title);
- dwm->hidden_title = true;
- } else {
- button_simple_set_text(dwm->title, g_strdup(title), dwm->text_color);
- if (dwm->hidden_title) {
- state_add_button(dwm->state, dwm->title);
- state_order_button(dwm->state);
- dwm->hidden_title = false;
- }
- }
-
- dwm->change_title = false;
- state_request_redraw(dwm->state, true);
- json_reader_end_member(reader);
- }
- break;
- }
-
- case IPC_TYPE_GET_TAGS:
- {
- log_debug("Received dwm tag information message [type=%d]", type);
-
- guint index = 0;
- while (json_reader_read_element(reader, index)) {
-
- json_reader_read_member(reader, "bit_mask");
- int mask = json_reader_get_int_value(reader);
- json_reader_end_element(reader);
-
- // XXX: Handle nicely
- g_assert_cmpint(mask, ==, 1 << index);
-
- // Set the tag names accordingly
- json_reader_read_member(reader, "name");
- const char *name = json_reader_get_string_value(reader);
- json_reader_end_element(reader);
-
- g_assert(index < 9);
- button_simple_set_text(dwm->tags[index], g_strdup(name), dwm->text_color);
-
- json_reader_end_element(reader);
- index++;
- }
-
- break;
- }
-
- default:
- {
- log_debug("Ignoring dwm ipc message [type=%d]", type);
- //log_debug("%s", reply);
- break;
- }
- }
-
- g_object_unref(reader);
- g_object_unref(parser);
-}
-
-static gboolean socket_callback(GSocket *socket, GIOCondition condition, gpointer data)
-{
- if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) return G_SOURCE_REMOVE;
- GError *error = NULL;
-
- DwmIpcHeader header;
- gssize size = 0;
- while (size < sizeof(DwmIpcHeader)) {
- gssize read = g_socket_receive(socket, (void *)&header + size, sizeof(DwmIpcHeader) - size, NULL, &error);
- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
- g_error_free(error);
- continue;
- }
- g_assert(read != -1);
- size += read;
- }
-
- if (memcmp(&header, IPC_MAGIC, IPC_MAGIC_LEN) != 0) {
- log_warning("Malformed dwm ipc message");
- return G_SOURCE_CONTINUE;;
- }
-
- uint32_t reply_size;
- memcpy(&reply_size, (void *)&header + IPC_MAGIC_LEN, sizeof(uint32_t));
-
- uint8_t msg_type;
- memcpy(&msg_type, (void *)&header + IPC_MAGIC_LEN + sizeof(uint32_t), sizeof(uint8_t));
-
- char *reply = g_malloc(reply_size);
- size = 0;
- while (size < reply_size) {
- gssize read = g_socket_receive(socket, reply + size, reply_size - size, NULL, NULL);
- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
- g_error_free(error);
- continue;
- }
- g_assert(read != -1);
- size += read;
- }
-
- //log_debug("Received dwm ipc response: %s", reply);
- ipc_handle(data, msg_type, reply, reply_size);
- g_free(reply);
-
- return G_SOURCE_CONTINUE;
-}
-
-DwmIpc *dwm_create(State *state, const char *socket)
-{
- DwmIpc *dwm = g_malloc0(sizeof(DwmIpc));
- dwm->state = state;
-
- GError *error = NULL;
- dwm->socket = g_socket_new(G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0, &error);
- g_assert_nonnull(dwm->socket);
-
- GSocketAddress *addr = g_unix_socket_address_new(socket);
- if (!g_socket_connect(dwm->socket, addr, NULL, &error)) {
- g_assert_nonnull(error);
- log_debug("Failed to connect socket %s: %s", socket, error->message);
- log_info("Skipped dwm ipc [socket=%s]", socket);
-
- g_error_free(error);
- g_object_unref(dwm->socket);
- g_free(dwm);
- return NULL;
- }
-
- dwm->source = g_socket_create_source(dwm->socket, G_IO_IN, NULL);
- g_source_set_static_name(dwm->source, "DwmIpcSource");
- g_source_set_callback(dwm->source, (GSourceFunc)socket_callback, dwm, NULL);
-
- const char *events[] = {
- IPC_EVENT_TAG_CHANGE,
- IPC_EVENT_CLIENT_FOCUS_CHANGE,
- IPC_EVENT_LAYOUT_CHANGE,
- IPC_EVENT_MONITOR_FOCUS_CHANGE,
- IPC_EVENT_FOCUSED_TITLE_CHANGE,
- IPC_EVENT_FOCUSED_STATE_CHANGE,
- };
- for (int i = 0; i < G_N_ELEMENTS(events); ++i)
- ipc_subscribe(dwm, events[i]);
-
- g_source_attach(dwm->source, NULL);
- log_info("Attached dwm ipc source [socket=%s]", socket);
-
- g_object_unref(addr);
- return dwm;
-}
-
-static void change_tag_action(Button *btn)
-{
- ButtonSimple *sbtn = CAST(btn, ButtonSimple);
- DwmIpc *dwm = sbtn->data;
-
- int n = sbtn->text[0] - '0';
- g_assert(n >= 1 && n <= 9);
-
- log_info("Toggled tag %d", n);
-
- JsonNode *args[] = {
- json_node_init_int(json_node_alloc(), 1 << (n - 1)),
- NULL
- };
- ipc_run_command(dwm, "view", args);
-}
-
-void dwm_register_tags(DwmIpc *dwm, Color color, Color selected, Color text_color)
-{
- if (dwm == NULL) return;
-
- dwm->color = color;
- dwm->text_color = text_color;
- dwm->selected = selected;
-
- // Tags button
- for (int i = 0; i < 9; ++i) {
- char text[] = { '1' + i, '\0' };
- dwm->tags[i] = button_simple_create(PANGO_ALIGN_LEFT, color);
- button_simple_set_text(dwm->tags[i], g_strdup(text), text_color);
- button_simple_set_action(dwm->tags[i], change_tag_action, dwm);
- state_add_button(dwm->state, dwm->tags[i]);
- }
-
- // This will set the tag names
- ipc_get_tags(dwm);
-
- dwm->title = button_simple_create(PANGO_ALIGN_CENTER, color);
- dwm->hidden_title = true;
-
- // FIXME: Set the first tag
- CAST(dwm->tags[0], ButtonSimple)->action(dwm->tags[0]);
- dwm->tags[0]->color = dwm->selected;
-}
-
-void dwm_destroy(DwmIpc *dwm)
-{
- if (dwm == NULL) return;
-
- g_source_destroy(dwm->source);
- g_source_unref(dwm->source);
- g_object_unref(dwm->socket);
-
- if (dwm->hidden_title)
- button_destroy(dwm->title);
-
- g_free(dwm);
-}
-
-// vim: ts=4 sw=4 et
diff --git a/src/dwm.h b/src/dwm.h
deleted file mode 100644
index 2ce055c..0000000
--- a/src/dwm.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef COMET_DWM_H
-#define COMET_DWM_H
-
-#include <glib.h>
-#include <gio/gio.h>
-
-#include "state.h"
-
-typedef struct {
- GSocket *socket;
- GSource *source;
- State *state;
- Color color;
- Color text_color;
- Color selected;
- Button *tags[9];
- Button *title;
- bool change_title;
- bool hidden_title;
-} DwmIpc;
-
-DwmIpc *dwm_create(State *state, const char *socket);
-
-void dwm_register_tags(DwmIpc *dwm, Color color, Color selected, Color text_color);
-
-void dwm_destroy(DwmIpc *dwm);
-
-#endif
-
-// vim: ts=4 sw=4 et
diff --git a/src/log.h b/src/log.h
deleted file mode 100644
index 8ee600f..0000000
--- a/src/log.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef COMET_LOG_H
-#define COMET_LOG_H
-
-#include <glib.h>
-
-#define DEBUG_FORMAT(format, ...) \
- "[%s] \x1b[1mdebug\x1b[0m: " format, __func__, ## __VA_ARGS__
-
-#define INFO_FORMAT(format, ...) \
- "[%s] \x1b[1;96minfo\x1b[0m: " format, __func__, ## __VA_ARGS__
-
-#define WARNING_FORMAT(format, ...) \
- "[%s] \x1b[1;33mwarning\x1b[0m: " format, __func__, ## __VA_ARGS__
-
-#define ERROR_FORMAT(format, ...) \
- "[%s] \x1b[1;31merror\x1b[0m: " format, __func__, ## __VA_ARGS__
-
-#define log_debug(...) g_debug(DEBUG_FORMAT(__VA_ARGS__))
-#define log_info(...) g_info(INFO_FORMAT(__VA_ARGS__))
-#define log_warning(...) g_warning(WARNING_FORMAT(__VA_ARGS__))
-#define log_error(...) g_error(ERROR_FORMAT(__VA_ARGS__))
-
-#endif
-
-// vim: ts=4 sw=4 et
diff --git a/src/state.c b/src/state.c
deleted file mode 100644
index c8fe0df..0000000
--- a/src/state.c
+++ /dev/null
@@ -1,137 +0,0 @@
-#include <glib.h>
-
-#include "state.h"
-#include "log.h"
-
-State *state_create(const char *label, Window *win, Drawer *draw)
-{
- State *state = g_malloc0(sizeof(State));
- g_assert_nonnull(state);
- state->label = label ? label : "comet";
- state->win = win;
- state->draw = draw;
- return state;
-}
-
-void state_add_button(State *state, Button *btn)
-{
- state->btns = g_list_append(state->btns, btn);
-}
-
-void state_remove_button(State *state, Button *btn)
-{
- state->btns = g_list_remove(state->btns, btn);
-}
-
-static gint align_compare(gconstpointer a, gconstpointer b)
-{
- PangoAlignment a_align = CAST(a, Button)->align;
- PangoAlignment b_align = CAST(b, Button)->align;
-
- if (a_align < b_align) return -1;
- if (a_align > b_align) return 1;
- return 0;
-}
-
-void state_order_button(State *state)
-{
- state->btns = g_list_sort(state->btns, align_compare);
-}
-
-static gboolean redraw_handler(State *state)
-{
- log_debug("Redrawing once [relayout=%d, state=\"%s\"]", state->relayout, state->label);
-
- if (state->relayout) {
- draw_compute_layout(state->draw, state->win, state->btns);
- state->relayout = false;
- }
-
- draw_paint(state->draw, state->win);
-
- state->idle_id = 0;
- return G_SOURCE_REMOVE;
-}
-
-void state_request_redraw(State *state, bool relayout)
-{
- // Override old redraw
- if (state->idle_id != 0)
- g_source_remove(state->idle_id);
-
- state->relayout = relayout;
-
- if (state->anim_id != 0) return;
-
- state->idle_id = g_idle_add(G_SOURCE_FUNC(redraw_handler), state);
-}
-
-static bool anim_check_more(State *state, GList *btns)
-{
- bool more = false;
- for (GList *it = btns; it; it = it->next) {
- Button *btn = it->data;
-
- if (btn->anim != NULL) {
- bool layout = btn->anim->layout_func != NULL;
- bool before = btn->anim->before_func != NULL;
- bool after = btn->anim->after_func != NULL;
-
- // Remove animation if all functions finished
- if (!layout && !before && !after) {
- log_debug("Removing animation [type=%d, end=%ld, button=%p, state=\"%s\"]",
- btn->anim->type, btn->anim->start + btn->anim->duration, btn, state->label);
-
- g_clear_pointer(&btn->anim, animation_destroy);
- } else {
- more = true;
- state->relayout |= layout;
- }
- }
-
- if (!btn->simple && anim_check_more(state, CAST(btn, ButtonGroup)->children))
- more = true;
- }
- return more;
-}
-
-static gboolean anim_handler(State *state)
-{
- bool more = anim_check_more(state, state->btns);
- log_debug("Redrawing animation [relayout=%d, more=%d, state=\"%s\"]",
- state->relayout, more, state->label);
-
- if (state->relayout) {
- draw_compute_layout(state->draw, state->win, state->btns);
- state->relayout = false;
- }
-
- draw_paint(state->draw, state->win);
-
- if (!more) state->anim_id = 0;
- return more;
-}
-
-// FIXME: When spamming animations there seem to be occasional
-// race condition that block animations from playing
-// (the animation timeout eagerly quits)
-void state_request_animation(State *state)
-{
- if (state->idle_id != 0) {
- g_source_remove(state->idle_id);
- state->idle_id = 0;
- }
-
- if (state->anim_id != 0) return;
- if (!anim_handler(state)) return;
-
- const int fps = 60;
- state->anim_id = g_timeout_add(1000 / fps, G_SOURCE_FUNC(anim_handler), state);
-}
-
-void state_destroy(State *state)
-{
- g_free(state);
-}
-
-// vim: ts=4 sw=4 et
diff --git a/src/state.h b/src/state.h
deleted file mode 100644
index 6ea331f..0000000
--- a/src/state.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef COMET_STATE_H
-#define COMET_STATE_H
-
-#include <glib.h>
-
-#include "window.h"
-#include "draw.h"
-#include "button.h"
-
-typedef struct State State;
-
-struct State {
- const char *label;
- Window *win;
- Drawer *draw;
- GList *btns;
- gint idle_id;
- gint anim_id;
- bool relayout;
-};
-
-State *state_create(const char *label, Window *win, Drawer *draw);
-
-void state_add_button(State *state, Button *btn);
-
-void state_remove_button(State *state, Button *btn);
-
-void state_order_button(State *state);
-
-void state_request_redraw(State *state, bool relayout);
-
-void state_request_animation(State *state);
-
-void state_destroy(State *state);
-
-#endif
-
-// vim: ts=4 sw=4 et
diff --git a/src/window.c b/src/window.c
deleted file mode 100644
index b3577c3..0000000
--- a/src/window.c
+++ /dev/null
@@ -1,306 +0,0 @@
-#include <glib.h>
-#include <unistd.h>
-#include <math.h>
-#include <cairo.h>
-#include <cairo-xcb.h>
-#include <xcb/xcb.h>
-#include <xcb/xproto.h>
-#include <xcb/xcb_aux.h>
-#include <xcb/xcb_icccm.h>
-#include <xcb/xcb_ewmh.h>
-#include <xcb/xcb_xrm.h>
-#include <xcb/xcb_errors.h>
-#include <xcb/randr.h>
-#include <xcb/shape.h>
-
-#include "window.h"
-#include "log.h"
-
-static xcb_atom_t intern_atom(Window *win, const char *atom)
-{
- xcb_generic_error_t *error;
- xcb_intern_atom_cookie_t cookie = xcb_intern_atom(win->con->connection, false, strlen(atom), atom);
- xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(win->con->connection, cookie, &error);
-
- g_assert_null(error);
- xcb_atom_t id = reply->atom;
- g_free(reply);
- return id;
-}
-
-static void wm_set_size(Window *win)
-{
- xcb_size_hints_t hints = { 0 };
- xcb_icccm_size_hints_set_size(&hints, false, win->width, win->height);
- xcb_icccm_size_hints_set_min_size(&hints, win->width, win->height);
- xcb_icccm_size_hints_set_max_size(&hints, win->width, win->height);
- xcb_icccm_size_hints_set_base_size(&hints, win->width, win->height);
- xcb_icccm_size_hints_set_position(&hints, false, win->x, win->y);
-
- xcb_icccm_set_wm_size_hints(win->con->connection, win->window, XCB_ATOM_WM_NORMAL_HINTS, &hints);
- log_debug("Xcb icccm size hints updated");
-}
-
-static void wm_set_struts(Window *win)
-{
- const uint32_t end = MAX(0, win->x + win->width - 1);
-
- const uint32_t values[12] = {
- 0, 0, win->height, 0, // left, right, top, bottom
- 0, 0, 0, 0, // left y0, left y1, right y0, right y1
- win->x, end, 0, 0, // top y0, top y1, bottom y0, bottom y1
- };
-
- xcb_change_property(win->con->connection,
- XCB_PROP_MODE_REPLACE,
- win->window,
- win->con->ewmh._NET_WM_STRUT,
- XCB_ATOM_CARDINAL,
- 32,
- 4,
- values);
-
- xcb_change_property(win->con->connection,
- XCB_PROP_MODE_REPLACE,
- win->window,
- win->con->ewmh._NET_WM_STRUT_PARTIAL,
- XCB_ATOM_CARDINAL,
- 32,
- 12,
- values);
-
- log_debug("Xcb ewmh struts updated");
-}
-
-static void wm_setup(Window *win)
-{
- const char *title = "comet";
- xcb_icccm_set_wm_name(win->con->connection, win->window, XCB_ATOM_STRING, 8, strlen(title), title);
- log_debug("Window updated title [%s]", title);
-
- const char class[] = "comet\0Comet";
- xcb_icccm_set_wm_class(win->con->connection, win->window, strlen(class), class);
- log_debug("Window updated class [%s]", "comet\\0Comet");
-
- xcb_generic_error_t *error;
- xcb_intern_atom_cookie_t *ewmh_cookie = xcb_ewmh_init_atoms(win->con->connection, &win->con->ewmh);
-
- g_assert_true(xcb_ewmh_init_atoms_replies(&win->con->ewmh, ewmh_cookie, &error));
- g_assert_null(error);
- log_debug("Xcb ewmh connected");
-
- xcb_ewmh_set_wm_window_type(&win->con->ewmh, win->window, 1, &win->con->ewmh._NET_WM_WINDOW_TYPE_DOCK);
- xcb_ewmh_set_wm_desktop(&win->con->ewmh, win->window, 0xFFFFFFFF);
- xcb_ewmh_set_wm_pid(&win->con->ewmh, win->window, getpid());
-
- xcb_atom_t state[] = {
- win->con->ewmh._NET_WM_STATE_STICKY,
- win->con->ewmh._NET_WM_STATE_ABOVE
- };
- xcb_ewmh_set_wm_state(&win->con->ewmh, win->window, G_N_ELEMENTS(state), state);
-
- // TODO: These should be updated depdending on the situation!
- wm_set_size(win);
- wm_set_struts(win);
-}
-
-Window *window_create(Connection *con)
-{
- Window *win = g_malloc0(sizeof(Window));
- g_assert_nonnull(win);
- win->con = con;
-
- // Set mask and params for CreateWindow
- win->cw_mask = XCB_CW_BACK_PIXMAP | XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL
- | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
-
- uint32_t event_mask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY
- | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_FOCUS_CHANGE
- | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS;
- // TODO: Implement hovering
- //| XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_POINTER_MOTION_HINT;
-
- xcb_colormap_t colormap = xcb_generate_id(con->connection);
- xcb_create_colormap(con->connection, XCB_COLORMAP_ALLOC_NONE, colormap, con->screen->root, con->visual_type->visual_id);
- log_debug("Xcb colormap created [id=%u]", colormap);
-
- XCB_AUX_ADD_PARAM(&win->cw_mask, &win->cw_params, back_pixmap, XCB_NONE);
- XCB_AUX_ADD_PARAM(&win->cw_mask, &win->cw_params, back_pixel, 0x00000000);
- XCB_AUX_ADD_PARAM(&win->cw_mask, &win->cw_params, border_pixel, 0x00000000);
- XCB_AUX_ADD_PARAM(&win->cw_mask, &win->cw_params, override_redirect, true);
- XCB_AUX_ADD_PARAM(&win->cw_mask, &win->cw_params, event_mask, event_mask);
- XCB_AUX_ADD_PARAM(&win->cw_mask, &win->cw_params, colormap, colormap);
-
- win->width = win->height = 1;
- log_debug("Window temporary size [width=%d, height=%d]", win->width, win->height);
-
- win->x = win->y = 0;
- log_debug("Window temporary position [x=%d, y=%d]", win->x, win->y);
-
- win->window = xcb_generate_id(con->connection);
- xcb_aux_create_window(con->connection,
- con->screen_depth,
- win->window,
- con->screen->root,
- win->x, win->y,
- win->width, win->height,
- 0, // border
- XCB_WINDOW_CLASS_COPY_FROM_PARENT,
- con->visual_type->visual_id,
- win->cw_mask,
- &win->cw_params);
-
- log_debug("Xcb window created [id=%u]", win->window);
-
- wm_setup(win);
- log_debug("Window wm options completed");
-
- xcb_map_window(con->connection, win->window);
- xcb_flush(con->connection);
- log_debug("Xcb initialized");
-
- win->surface = cairo_xcb_surface_create(con->connection,
- win->window,
- con->visual_type,
- con->screen_size->width,
- con->screen_size->height);
-
- g_assert_cmpint(cairo_surface_status(win->surface), ==, CAIRO_STATUS_SUCCESS);
- log_debug("Cairo surface created");
-
- win->cr = cairo_create(win->surface);
- g_assert_cmpint(cairo_status(win->cr), ==, CAIRO_STATUS_SUCCESS);
- log_debug("Cairo context created");
-
- return win;
-}
-
-cairo_t *window_get_context(Window *win)
-{
- return win->cr;
-}
-
-double window_get_scale(Window *win)
-{
- const int n = 4;
- return MAX(1, floor((win->con->screen_dpi / 96.0) * n) * (1.0 / n));
-}
-
-void window_get_screen_size(Window *win, int *width, int *height)
-{
- *width = win->con->screen_size->width;
- *height = win->con->screen_size->height;
-}
-
-void window_move(Window *win, int x, int y)
-{
- if (win->x == x && win->y == y) return;
-
- win->x = x;
- win->y = y;
-
- const uint32_t values[] = { x, y };
- xcb_configure_window(win->con->connection,
- win->window,
- XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
- values);
-
- log_debug("Window updated position [x=%d, y=%d]", win->x, win->y);
-}
-
-static void window_paint_corners(Window *win)
-{
- // TODO: Actually make this a parameter
- int radius = win->height / 2;
- double degree = M_PI / 180.0;
-
- // TODO: Check this value
- int depth = 1;
-
- xcb_pixmap_t bitmap = xcb_generate_id(win->con->connection);
- xcb_create_pixmap(win->con->connection, depth, bitmap, win->window, win->width, win->height);
- log_debug("Xcb pixmap created [id=%u]", bitmap);
-
- cairo_surface_t *surface = cairo_xcb_surface_create_for_bitmap(win->con->connection,
- win->con->screen,
- bitmap,
- win->width,
- win->height);
-
- cairo_t *cr = cairo_create(surface);
-
- // TODO: Fix antialiasing situation
- //cairo_set_antialias(cr, CAIRO_ANTIALIAS_GOOD);
-
- cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
-
- cairo_set_source_rgba(cr, 0, 0, 0, 0);
- cairo_paint(cr);
-
- cairo_set_source_rgba(cr, 1, 1, 1, 1);
- cairo_arc(cr, radius, radius, radius, 90.0 * degree, 270 * degree);
- cairo_arc(cr, win->width - radius, radius, radius, 270 * degree, 450 * degree);
- cairo_fill(cr);
-
- log_debug("Xcb shape painted");
-
- cairo_show_page(cr);
- cairo_destroy(cr);
- cairo_surface_flush(surface);
- cairo_surface_destroy(surface);
-
- xcb_shape_mask(win->con->connection, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, win->window, 0, 0, bitmap);
- xcb_shape_select_input(win->con->connection, win->window, XCB_SHAPE_NOTIFY);
- log_debug("Xcb shape mask configured");
-
- xcb_free_pixmap(win->con->connection, bitmap);
-}
-
-void window_resize(Window *win, int width, int height)
-{
- if (win->width == width && win->height == height) return;
-
- win->width = width;
- win->height = height;
-
- const uint32_t values[] = { width, height };
- xcb_configure_window(win->con->connection,
- win->window,
- XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
- values);
-
- log_debug("Window updated size [width=%d, height=%d]", win->width, win->height);
-
- wm_set_size(win);
-
- // Update shape mask
- window_paint_corners(win);
-}
-
-void window_paint_surface(Window *win, cairo_surface_t *surface, int width, int height)
-{
- cairo_xcb_surface_set_size(win->surface, width, height);
- xcb_clear_area(win->con->connection, false, win->window, 0, 0, 0, 0);
-
- cairo_save(win->cr);
- cairo_set_source_surface(win->cr, surface, 0, 0);
-
- cairo_paint(win->cr);
- cairo_show_page(win->cr);
-
- cairo_surface_flush(win->surface);
- cairo_restore(win->cr);
-
- xcb_circulate_window(win->con->connection, XCB_CIRCULATE_RAISE_LOWEST, win->window);
- xcb_flush(win->con->connection);
-}
-
-void window_destroy(Window *win)
-{
- cairo_destroy(win->cr);
- cairo_surface_destroy(win->surface);
- g_free(win);
-}
-
-// vim: ts=4 sw=4 et
diff --git a/src/window.h b/src/window.h
deleted file mode 100644
index ea1209a..0000000
--- a/src/window.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef COMET_WINDOW_H
-#define COMET_WINDOW_H
-
-#include <cairo.h>
-#include <xcb/xcb.h>
-#include <xcb/xcb_aux.h>
-
-#include "connect.h"
-
-typedef struct Window Window;
-
-struct Window {
- Connection *con;
- xcb_drawable_t window;
- uint32_t cw_mask;
- xcb_params_cw_t cw_params;
- cairo_surface_t *surface;
- cairo_t *cr;
- int x, y;
- int width, height;
-};
-
-Window *window_create(Connection *con);
-
-cairo_t *window_get_context(Window *win);
-
-double window_get_scale(Window *win);
-
-void window_get_screen_size(Window *win, int *width, int *height);
-
-void window_move(Window *win, int x, int y);
-
-void window_resize(Window *win, int width, int height);
-
-void window_paint_surface(Window *win, cairo_surface_t *surface, int width, int height);
-
-void window_destroy(Window *win);
-
-#endif
-
-// vim: ts=4 sw=4 et