Works decently (except for issues with violent resizing).
This commit is contained in:
parent
425fa1202e
commit
a333405ac1
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
|
.*.swp
|
||||||
config.mk
|
config.mk
|
||||||
mpdart
|
mpdart
|
||||||
|
|
3
Makefile
3
Makefile
|
@ -1,9 +1,8 @@
|
||||||
.POSIX:
|
.POSIX:
|
||||||
include config.mk
|
include config.mk
|
||||||
LIBS=-lX11
|
|
||||||
all: mpdart config.mk
|
all: mpdart config.mk
|
||||||
mpdart: mpdart.c
|
mpdart: mpdart.c
|
||||||
$(CC) $(CONFIG) $(LIBS) $(CFLAGS) $(CXXFLAGS) -o $@ mpdart.c
|
$(CC) $(CONFIG) $(CFLAGS) $(CXXFLAGS) -o $@ mpdart.c
|
||||||
clean:
|
clean:
|
||||||
rm -f mpdart
|
rm -f mpdart
|
||||||
install: mpdart
|
install: mpdart
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if command -V pkg-config >/dev/null 2>&1; then
|
if command -V pkg-config >/dev/null 2>&1; then
|
||||||
printf '%s\n' "CONFIG=$(pkg-config libmpdclient --libs --cflags) $(pkg-config imlib2 --libs --cflags)" > config.mk
|
printf '%s\n' "CONFIG=$(pkg-config libmpdclient --libs --cflags || exit
|
||||||
|
) $(pkg-config imlib2 --libs --cflags || exit
|
||||||
|
) -lX11" > config.mk
|
||||||
else
|
else
|
||||||
printf '%s\n' "CONFIG=-lmpdclient -lImlib2" > config.mk
|
printf '%s\n' "CONFIG=-lmpdclient -lImlib2 -lX11" > config.mk
|
||||||
fi
|
fi
|
||||||
|
|
196
mpdart.c
196
mpdart.c
|
@ -13,9 +13,7 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
/* TODO: do Imlib, fix name changing */
|
/* TODO image metadata images */
|
||||||
|
|
||||||
/* LOADS of cleaning up to do */
|
|
||||||
|
|
||||||
/* mpd globals */
|
/* mpd globals */
|
||||||
struct mpd_connection* connection = 0;
|
struct mpd_connection* connection = 0;
|
||||||
|
@ -37,10 +35,14 @@ char* im_image_path;
|
||||||
|
|
||||||
|
|
||||||
void die(const char* msg) {
|
void die(const char* msg) {
|
||||||
fprintf(stderr, "%s\n", msg);
|
fprintf(stderr, "FATAL: %s\n", msg);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void warn(const char* msg) {
|
||||||
|
fprintf(stderr, "WARNING: %s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
/* error checking malloc */
|
/* error checking malloc */
|
||||||
void* xmalloc(size_t size) {
|
void* xmalloc(size_t size) {
|
||||||
void* ret = malloc(size);
|
void* ret = malloc(size);
|
||||||
|
@ -97,10 +99,11 @@ void update_mpd_song(void) {
|
||||||
mpd_send_current_song(connection);
|
mpd_send_current_song(connection);
|
||||||
song = mpd_recv_song(connection);
|
song = mpd_recv_song(connection);
|
||||||
|
|
||||||
|
set_image_path(0);
|
||||||
|
|
||||||
if (!song) {
|
if (!song) {
|
||||||
fprintf(stderr, "Failed to get song from mpd\n");
|
fprintf(stderr, "Failed to get song from mpd\n");
|
||||||
set_window_name("None");
|
set_window_name("None");
|
||||||
set_image_path(0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,31 +126,36 @@ void update_mpd_song(void) {
|
||||||
dirname[len] = '\0';
|
dirname[len] = '\0';
|
||||||
|
|
||||||
/* account for .cue files */
|
/* account for .cue files */
|
||||||
{
|
|
||||||
char* basename = strrchr(path, '/');
|
for (char* cue = strstr(dirname, ".cue");
|
||||||
basename = basename ? basename + 1 : path;
|
cue >= dirname; cue--) {
|
||||||
char* extension = strrchr(basename, '.');
|
if (*cue == '/') {
|
||||||
if (extension) {
|
*cue = '\0';
|
||||||
*(basename - 1) = '\0';
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DIR* dir = opendir(dirname);
|
DIR* dir = opendir(dirname);
|
||||||
|
|
||||||
struct dirent* ent;
|
if (!dir) {
|
||||||
while (ent = readdir(dir)) {
|
warn("Unable to open dir");
|
||||||
char* extension = strrchr(ent->d_name, '.');
|
} else {
|
||||||
/* TODO add more extensions */
|
struct dirent* ent;
|
||||||
if (extension && (!strcmp(extension, ".jpg") || !strcmp(extension, ".png"))) {
|
while (ent = readdir(dir)) {
|
||||||
printf("Using '%s' as album art.\n", ent->d_name);
|
char* extension = strrchr(ent->d_name, '.');
|
||||||
set_image_path(asprintf("%s/%s", dirname, ent->d_name));
|
/* TODO add more extensions and match multiple extension
|
||||||
break;
|
and select one based on list of strings such as cover COVER
|
||||||
|
art album etc */
|
||||||
|
if (extension && (!strcmp(extension, ".jpg") || !strcmp(extension, ".png"))) {
|
||||||
|
printf("Using '%s' as album art.\n", ent->d_name);
|
||||||
|
set_image_path(asprintf("%s/%s", dirname, ent->d_name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
|
|
||||||
free(pretty_name);
|
free(pretty_name);
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
|
@ -157,6 +165,57 @@ void update_mpd_song(void) {
|
||||||
mpd_song_free(song);
|
mpd_song_free(song);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void imlib_render(int up_x, int up_y, int up_w, int up_h) {
|
||||||
|
/* Imlib render */
|
||||||
|
XWindowAttributes xwindow_attrs;
|
||||||
|
XGetWindowAttributes(xdisplay, xwindow, &xwindow_attrs);
|
||||||
|
int wx = xwindow_attrs.width,
|
||||||
|
wy = xwindow_attrs.width; // ensure 1:1
|
||||||
|
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
im_buffer = imlib_create_image(up_w, up_h);
|
||||||
|
imlib_context_set_blend(1);
|
||||||
|
|
||||||
|
if (!im_buffer) {
|
||||||
|
warn("Unable to create buffer");
|
||||||
|
XClearWindow(xdisplay, xwindow);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!im_image_path) {
|
||||||
|
warn("No image path");
|
||||||
|
XClearWindow(xdisplay, xwindow);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
im_image = imlib_load_image(im_image_path);
|
||||||
|
|
||||||
|
if (!im_image) {
|
||||||
|
warn("Unable to open image");
|
||||||
|
XClearWindow(xdisplay, xwindow);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
imlib_context_set_image(im_image);
|
||||||
|
|
||||||
|
w = imlib_image_get_width();
|
||||||
|
h = imlib_image_get_height();
|
||||||
|
|
||||||
|
imlib_context_set_image(im_buffer);
|
||||||
|
|
||||||
|
imlib_blend_image_onto_image(im_image, 0,
|
||||||
|
0, 0, w, h,
|
||||||
|
up_x, up_y, wx, wy);
|
||||||
|
imlib_context_set_image(im_image);
|
||||||
|
imlib_free_image();
|
||||||
|
|
||||||
|
imlib_context_set_blend(0);
|
||||||
|
imlib_context_set_image(im_buffer);
|
||||||
|
imlib_render_image_on_drawable(up_x, up_y);
|
||||||
|
imlib_free_image();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
/* parse args */
|
/* parse args */
|
||||||
|
@ -230,6 +289,23 @@ int main(int argc, char** argv) {
|
||||||
border_color,
|
border_color,
|
||||||
background_color);
|
background_color);
|
||||||
|
|
||||||
|
XSizeHints* size_hints = XAllocSizeHints();
|
||||||
|
|
||||||
|
if (!size_hints)
|
||||||
|
die("Unable to allocate memory");
|
||||||
|
|
||||||
|
size_hints->flags = PAspect | PMinSize | PMaxSize;
|
||||||
|
size_hints->min_width = 64;
|
||||||
|
size_hints->min_height = 64;
|
||||||
|
size_hints->max_width = 1024;
|
||||||
|
size_hints->max_height = 1024;
|
||||||
|
size_hints->min_aspect.x = 1;
|
||||||
|
size_hints->max_aspect.x = 1;
|
||||||
|
size_hints->min_aspect.y = 1;
|
||||||
|
size_hints->max_aspect.y = 1;
|
||||||
|
|
||||||
|
XSetWMNormalHints(xdisplay, xwindow, size_hints);
|
||||||
|
|
||||||
XSelectInput(xdisplay, xwindow, ExposureMask);
|
XSelectInput(xdisplay, xwindow, ExposureMask);
|
||||||
XMapWindow(xdisplay, xwindow);
|
XMapWindow(xdisplay, xwindow);
|
||||||
set_window_name("mpdart");
|
set_window_name("mpdart");
|
||||||
|
@ -271,29 +347,38 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
/* mpd event loop */
|
/* mpd event loop */
|
||||||
while (1) {
|
while (1) {
|
||||||
int ready_fds = poll(fds, 2, 1000);
|
/* sleep for a day at a time */
|
||||||
|
int ready_fds = poll(fds, 2, 86400);
|
||||||
if (ready_fds < 0) {
|
if (ready_fds < 0) {
|
||||||
die("Error in poll");
|
die("Error in poll");
|
||||||
} else if (ready_fds > 0) {
|
} else if (ready_fds > 0) {
|
||||||
/* X event loop */
|
/* X event loop */
|
||||||
if (fds[0].revents & POLLIN) {
|
if (fds[0].revents & POLLIN) {
|
||||||
XEvent ev;
|
int wx, wy, ww, wh;
|
||||||
XNextEvent(xdisplay, &ev);
|
while (XPending(xdisplay)) {
|
||||||
|
XEvent ev;
|
||||||
|
XNextEvent(xdisplay, &ev);
|
||||||
|
|
||||||
switch (ev.type) {
|
switch (ev.type) {
|
||||||
case ClientMessage:
|
case ClientMessage:
|
||||||
if (ev.xclient.data.l[0] == wm_delete) {
|
|
||||||
XCloseDisplay(xdisplay);
|
XCloseDisplay(xdisplay);
|
||||||
die("Window Closed");
|
die("Window Closed");
|
||||||
}
|
break; // ?
|
||||||
break;
|
case ConfigureNotify:
|
||||||
case ConfigureNotify:
|
wx = ev.xconfigure.x;
|
||||||
case Expose:
|
wy = ev.xconfigure.y;
|
||||||
im_updates = imlib_update_append_rect(im_updates,
|
ww = ev.xconfigure.width;
|
||||||
ev.xexpose.x, ev.xexpose.y,
|
wh = ev.xconfigure.height;
|
||||||
ev.xexpose.width, ev.xexpose.height);
|
break;
|
||||||
break;
|
case Expose:
|
||||||
|
wx = ev.xexpose.x;
|
||||||
|
wy = ev.xexpose.y;
|
||||||
|
ww = ev.xexpose.width;
|
||||||
|
wh = ev.xexpose.height;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
imlib_render(wx, wy, ww, wh);
|
||||||
}
|
}
|
||||||
/* MPD event loop */
|
/* MPD event loop */
|
||||||
if (fds[1].revents & POLLIN) {
|
if (fds[1].revents & POLLIN) {
|
||||||
|
@ -302,48 +387,5 @@ int main(int argc, char** argv) {
|
||||||
mpd_send_idle_mask(connection, MPD_IDLE_PLAYER);
|
mpd_send_idle_mask(connection, MPD_IDLE_PLAYER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Imlib render */
|
|
||||||
XWindowAttributes xwindow_attrs;
|
|
||||||
XGetWindowAttributes(xdisplay, xwindow, &xwindow_attrs);
|
|
||||||
int wx = xwindow_attrs.width,
|
|
||||||
wy = xwindow_attrs.width;
|
|
||||||
/* int wx = 256, wy = 256; */
|
|
||||||
im_updates = imlib_updates_merge_for_rendering(im_updates,
|
|
||||||
wx, wy);
|
|
||||||
for (Imlib_Updates current_update = im_updates ; current_update;
|
|
||||||
current_update = imlib_updates_get_next(current_update)) {
|
|
||||||
|
|
||||||
int up_x, up_y, up_w, up_h, w, h;
|
|
||||||
imlib_updates_get_coordinates(current_update,
|
|
||||||
&up_x, &up_y, &up_w, &up_h);
|
|
||||||
|
|
||||||
im_buffer = imlib_create_image(up_w, up_h);
|
|
||||||
imlib_context_set_blend(1);
|
|
||||||
|
|
||||||
if (!im_image_path)
|
|
||||||
die("TODO null image_path");
|
|
||||||
|
|
||||||
im_image = imlib_load_image(im_image_path);
|
|
||||||
imlib_context_set_image(im_image);
|
|
||||||
|
|
||||||
w = imlib_image_get_width();
|
|
||||||
h = imlib_image_get_height();
|
|
||||||
|
|
||||||
imlib_context_set_image(im_buffer);
|
|
||||||
|
|
||||||
if (!im_image)
|
|
||||||
die("Could not open image TODO, replace with warning and clear.");
|
|
||||||
|
|
||||||
imlib_blend_image_onto_image(im_image, 0,
|
|
||||||
0, 0, w, h,
|
|
||||||
up_x, up_y, wx, wy);
|
|
||||||
imlib_context_set_image(im_image);
|
|
||||||
imlib_free_image();
|
|
||||||
|
|
||||||
imlib_context_set_blend(0);
|
|
||||||
imlib_context_set_image(im_buffer);
|
|
||||||
imlib_render_image_on_drawable(up_x, up_y);
|
|
||||||
imlib_free_image();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user