diff options
author | Calvin Morrison <calvin@fastmailteam.com> | 2022-07-27 20:58:28 -0400 |
---|---|---|
committer | Calvin Morrison <calvin@fastmailteam.com> | 2022-07-27 20:58:28 -0400 |
commit | bcd8da8b1a3d02a90b3c9c8ca73d8b26760bb219 (patch) | |
tree | a89057557b9076306864428ff542c672b5ce7eb4 /moc_x11.c | |
parent | d210af2268c29420983cdd6937affc7a2d3f5b47 (diff) |
libmoc
our previous attempt ran into issues where we have two loops, a GUI loop and the MOC loop.
I rewrote this into lib_moc which has it's own thread that manages the MOC socket connection
and exposes the interface to a client program via a moc object. all you need to do is call
moc_init();
Pretty cool, still runs into issues regarding autoconnect and some other problems.
Diffstat (limited to 'moc_x11.c')
-rw-r--r-- | moc_x11.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/moc_x11.c b/moc_x11.c new file mode 100644 index 0000000..efc4ce3 --- /dev/null +++ b/moc_x11.c @@ -0,0 +1,142 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> //Header file for sleep(). man 3 sleep for details. +#include <errno.h> + +#include <pthread.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xos.h> + +#include "moc_library.h" + +void *xmalloc (size_t size) +{ + void *p; + + + if ((p = malloc(size)) == NULL) { + fprintf(stderr, "Can't allocate memory!"); + exit(0); + } + return p; +} + +/* Obtains the next X11 event with specified timeout. */ + static int XNextEventTimed(Display* dsp, XEvent* event_return, long millis) { + if (millis == 0) + { + XNextEvent(dsp, event_return); + return True; + } + + struct timeval tv; + tv.tv_sec = millis / 1000; + tv.tv_usec = (millis % 1000) * 1000; + + XFlush(dsp); + if (XPending(dsp)) + { + XNextEvent(dsp, event_return); + return True; + } + else + { + int fd = ConnectionNumber(dsp); + fd_set readset; + FD_ZERO(&readset); + FD_SET(fd, &readset); + if (select(fd+1, &readset, NULL, NULL, &tv) <= 0) + { + return False; + } + else + { + if (XPending(dsp)) + { + XNextEvent(dsp, event_return); + return True; + } + else + { + return False; + } + } + } +} + +char *time_format(int sec) { + + int h = (sec/3600); + int m = (sec -(3600*h))/60; + int s = (sec -(3600*h)-(m*60)); + + char *str = xmalloc(256); + if(h) { + sprintf(str, "%d:%2d:%02d",h,m,s); + } else { + sprintf(str, "%02d:%02d",m,s); + } + return str; +} + +int main() { + + Display* dpy = XOpenDisplay(NULL); + if (dpy == NULL) + { + fprintf(stderr, "Cannot open display\n"); + exit(1); + } + + int s = DefaultScreen(dpy); + Window win = XCreateSimpleWindow(dpy, RootWindow(dpy, s), 10, 10, 660, 200, 1, + BlackPixel(dpy, s), WhitePixel(dpy, s)); + XSelectInput(dpy, win, ExposureMask | ButtonPress | KeyPressMask); + XMapWindow(dpy, win); + + XStoreName(dpy, win, "mocicon"); + + Atom WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + XSetWMProtocols(dpy, win, &WM_DELETE_WINDOW, 1); + + struct moc *mh = moc_init(); + if(mh == NULL) { + return 1; + } + + XEvent e; + while(1) { + int got_event = XNextEventTimed(dpy, &e, 250); + + if(mh->status != CONNECTED) { + printf("can't connect\n"); + } + + XClearWindow(dpy, win); + int y_offset = 20; + int x = 10; + pthread_mutex_lock(&mh->lock); + if(mh->state == PLAYING || mh->state == PAUSED) { + char *timestr= time_format(mh->time); + + XDrawString(dpy, win, DefaultGC(dpy, s), x, y_offset, mh->title, strlen(mh->title)); + y_offset += 15; + XDrawString(dpy, win, DefaultGC(dpy, s), x, y_offset, mh->artist, strlen(mh->artist)); + y_offset += 15; + XDrawString(dpy, win, DefaultGC(dpy, s), x, y_offset, mh->album, strlen(mh->album)); + y_offset += 15; + XDrawString(dpy, win, DefaultGC(dpy, s), x, y_offset, timestr, strlen(timestr)); + y_offset += 15; + + + free(timestr); + + } + pthread_mutex_unlock(&mh->lock); + + } + }; |