From d210af2268c29420983cdd6937affc7a2d3f5b47 Mon Sep 17 00:00:00 2001 From: Calvin Morrison Date: Thu, 21 Jul 2022 12:21:24 -0400 Subject: first attempt at talking to MOC over it's socket. Realtime updates. Only works with -R null right now. This work will go into mocicon at some point, so can provide realtime info / feedback --- x11-moc-widget.c | 949 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 949 insertions(+) create mode 100644 x11-moc-widget.c (limited to 'x11-moc-widget.c') diff --git a/x11-moc-widget.c b/x11-moc-widget.c new file mode 100644 index 0000000..808bd85 --- /dev/null +++ b/x11-moc-widget.c @@ -0,0 +1,949 @@ +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* Maximal socket name. */ +#define UNIX_PATH_MAX 108 +#define SOCKET_NAME "socket2" + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +struct file_tags +{ + char *title; + char *artist; + char *album; + int track; + int time; + int filled; /* Which tags are filled: TAGS_COMMENTS, TAGS_TIME. */ +}; +struct event_queue +{ + struct event *head; + struct event *tail; +}; +struct event +{ + int type; /* type of the event (one of EV_*) */ + void *data; /* optional data associated with the event */ + struct event *next; +}; + +/* Flags for the info decoder function. */ +enum tags_select +{ + TAGS_COMMENTS = 0x01, /* artist, title, etc. */ + TAGS_TIME = 0x02 /* time of the file. */ +}; + + +/* Definition of events sent by server to the client. */ +#define EV_STATE 0x01 /* server has changed the state */ +#define EV_CTIME 0x02 /* current time of the song has changed */ +#define EV_SRV_ERROR 0x04 /* an error occurred */ +#define EV_BUSY 0x05 /* another client is connected to the server */ +#define EV_DATA 0x06 /* data in response to a request will arrive */ +#define EV_BITRATE 0x07 /* the bitrate has changed */ +#define EV_RATE 0x08 /* the rate has changed */ +#define EV_CHANNELS 0x09 /* the number of channels has changed */ +#define EV_EXIT 0x0a /* the server is about to exit */ +#define EV_PONG 0x0b /* response for CMD_PING */ +#define EV_OPTIONS 0x0c /* the options has changed */ +#define EV_SEND_PLIST 0x0d /* request for sending the playlist */ +#define EV_TAGS 0x0e /* tags for the current file have changed */ +#define EV_STATUS_MSG 0x0f /* followed by a status message */ +#define EV_MIXER_CHANGE 0x10 /* the mixer channel was changed */ +#define EV_FILE_TAGS 0x11 /* tags in a response for tags request */ +#define EV_AVG_BITRATE 0x12 /* average bitrate has changed (new song) */ +#define EV_AUDIO_START 0x13 /* playing of audio has started */ +#define EV_AUDIO_STOP 0x14 /* playing of audio has stopped */ + +/* Events caused by a client that wants to modify the playlist (see + * CMD_CLI_PLIST* commands). */ +#define EV_PLIST_ADD 0x50 /* add an item, followed by the file name */ +#define EV_PLIST_DEL 0x51 /* delete an item, followed by the file name */ +#define EV_PLIST_MOVE 0x52 /* move an item, followed by 2 file names */ +#define EV_PLIST_CLEAR 0x53 /* clear the playlist */ + +/* These events, though similar to the four previous are caused by server + * which takes care of clients' queue synchronization. */ +#define EV_QUEUE_ADD 0x54 +#define EV_QUEUE_DEL 0x55 +#define EV_QUEUE_MOVE 0x56 +#define EV_QUEUE_CLEAR 0x57 + +/* State of the server. */ +#define STATE_PLAY 0x01 +#define STATE_STOP 0x02 +#define STATE_PAUSE 0x03 + +/* Definition of server commands. */ +#define CMD_PLAY 0x00 /* play the first element on the list */ +#define CMD_LIST_CLEAR 0x01 /* clear the list */ +#define CMD_LIST_ADD 0x02 /* add an item to the list */ +#define CMD_STOP 0x04 /* stop playing */ +#define CMD_PAUSE 0x05 /* pause */ +#define CMD_UNPAUSE 0x06 /* unpause */ +#define CMD_SET_OPTION 0x07 /* set an option */ +#define CMD_GET_OPTION 0x08 /* get an option */ +#define CMD_GET_CTIME 0x0d /* get the current song time */ +#define CMD_GET_SNAME 0x0f /* get the stream file name */ +#define CMD_NEXT 0x10 /* start playing next song if available */ +#define CMD_QUIT 0x11 /* shutdown the server */ +#define CMD_SEEK 0x12 /* seek in the current stream */ +#define CMD_GET_STATE 0x13 /* get the state */ +#define CMD_DISCONNECT 0x15 /* disconnect from the server */ +#define CMD_GET_BITRATE 0x16 /* get the bitrate */ +#define CMD_GET_RATE 0x17 /* get the rate */ +#define CMD_GET_CHANNELS 0x18 /* get the number of channels */ +#define CMD_PING 0x19 /* request for EV_PONG */ +#define CMD_GET_MIXER 0x1a /* get the volume level */ +#define CMD_SET_MIXER 0x1b /* set the volume level */ +#define CMD_DELETE 0x1c /* delete an item from the playlist */ +#define CMD_SEND_PLIST_EVENTS 0x1d /* request for playlist events */ +#define CMD_PREV 0x20 /* start playing previous song if available */ +#define CMD_SEND_PLIST 0x21 /* send the playlist to the requesting client */ +#define CMD_GET_PLIST 0x22 /* get the playlist from one of the clients */ +#define CMD_CAN_SEND_PLIST 0x23 /* mark the client as able to send + playlist */ +#define CMD_CLI_PLIST_ADD 0x24 /* add an item to the client's playlist */ +#define CMD_CLI_PLIST_DEL 0x25 /* delete an item from the client's + playlist */ +#define CMD_CLI_PLIST_CLEAR 0x26 /* clear the client's playlist */ +#define CMD_GET_SERIAL 0x27 /* get an unique serial number */ +#define CMD_PLIST_SET_SERIAL 0x28 /* assign a serial number to the server's + playlist */ +#define CMD_LOCK 0x29 /* acquire a lock */ +#define CMD_UNLOCK 0x2a /* release the lock */ +#define CMD_PLIST_GET_SERIAL 0x2b /* get the serial number of the server's + playlist */ +#define CMD_GET_TAGS 0x2c /* get tags for the currently played file */ +#define CMD_TOGGLE_MIXER_CHANNEL 0x2d /* toggle the mixer channel */ +#define CMD_GET_MIXER_CHANNEL_NAME 0x2e /* get the mixer channel's name */ +#define CMD_GET_FILE_TAGS 0x2f /* get tags for the specified file */ +#define CMD_ABORT_TAGS_REQUESTS 0x30 /* abort previous CMD_GET_FILE_TAGS + requests up to some file */ +#define CMD_CLI_PLIST_MOVE 0x31 /* move an item */ +#define CMD_LIST_MOVE 0x32 /* move an item */ +#define CMD_GET_AVG_BITRATE 0x33 /* get the average bitrate */ + +#define CMD_TOGGLE_SOFTMIXER 0x34 /* toggle use of softmixer */ +#define CMD_TOGGLE_EQUALIZER 0x35 /* toggle use of equalizer */ +#define CMD_EQUALIZER_REFRESH 0x36 /* refresh EQ-presets */ +#define CMD_EQUALIZER_PREV 0x37 /* select previous eq-preset */ +#define CMD_EQUALIZER_NEXT 0x38 /* select next eq-preset */ + +#define CMD_TOGGLE_MAKE_MONO 0x39 /* toggle mono mixing */ +#define CMD_JUMP_TO 0x3a /* jumps to a some position in the current stream */ +#define CMD_QUEUE_ADD 0x3b /* add an item to the queue */ +#define CMD_QUEUE_DEL 0x3c /* delete an item from the queue */ +#define CMD_QUEUE_MOVE 0x3d /* move an item in the queue */ +#define CMD_QUEUE_CLEAR 0x3e /* clear the queue */ +#define CMD_GET_QUEUE 0x3f /* request the queue from the server */ + + +#define MAX_SEND_STRING 4096 + +#ifndef RANGE +#define RANGE(min, val, max) ((val) >= (min) && (val) <= (max)) +#endif + +// Functions +static int fatal(char *string); +static int server_connect (); +void *xmalloc (size_t size); + +// Raw gets +char *get_str (int sock); +int send_int (int sock, int i); +int get_int (int sock, int *i); + +//wrapper gets +static int get_data_int(); +static int get_int_from_srv(); +static char *get_str_from_srv (); +static void wait_for_data (); +static void *get_event_data (const int type); +static struct file_tags *recv_tags_from_srv(); +static struct file_tags *get_data_tags (); +struct file_tags *tags_new (); +void tags_free (struct file_tags *tags); + +// Globals. +static int srv_sock = -1; +char *socket_path = "/home/calvin/.moc/socket2"; +static struct event_queue events; + + + +static int fatal(char *string) { + fprintf(stderr, "%s\n", string); + exit(0); +} +char *sock_path() { + return socket_path; +}; +static int server_connect () +{ + char *path = socket_path; + struct sockaddr_un sock_name; + int sock; + + /* Create a socket */ + if ((sock = socket (PF_LOCAL, SOCK_STREAM, 0)) == -1) + return -1; + + sock_name.sun_family = AF_LOCAL; + strcpy (sock_name.sun_path, sock_path()); + + if (connect(sock, (struct sockaddr *)&sock_name, + SUN_LEN(&sock_name)) == -1) { + close (sock); + fprintf(stderr, "%s at (%s)\n", strerror(errno), sock_name); + return -1; + } + + return sock; +} + +char *get_str (int sock) +{ + int len; + int res, nread = 0; + char *str; + + if (!get_int(sock, &len)) + return NULL; + + if (!RANGE(0, len, MAX_SEND_STRING)) { + printf("Bad string length."); + return NULL; + } + + str = (char *)malloc (sizeof(char) * (len + 1)); + while (nread < len) { + res = recv (sock, str + nread, len - nread, 0); + if (res == -1) { + printf("recv() failed when getting string: %s\n", + strerror(errno)); + free (str); + return NULL; + } + if (res == 0) { + printf("Unexpected EOF when getting string\n"); + free (str); + return NULL; + } + nread += res; + } + str[len] = 0; + + return str; +} + +int send_str (int sock, const char *str) +{ + int len; + + len = strlen (str); + if (!send_int (sock, len)) + return 0; + + if (send (sock, str, len, 0) != len) + return 0; + + return 1; +} + +int get_int (int sock, int *i) +{ + int res; + + res = recv (sock, i, sizeof(int), 0); + if (res == -1) + printf("recv() failed when getting int: %s", strerror(errno)); + + return res == sizeof(int) ? 1 : 0; +} + +static char *get_data_str () +{ + wait_for_data (); + return get_str_from_srv (); +} + +static int get_data_int () +{ + wait_for_data (); + return get_int_from_srv (); +} + +static void send_str_to_srv (const char *str) +{ + if (!send_str(srv_sock, str)) + fatal ("Can't send() string to the server!"); +} + +struct file_tags *tags_new () +{ + struct file_tags *tags; + + tags = (struct file_tags *)xmalloc (sizeof(struct file_tags)); + tags->title = NULL; + tags->artist = NULL; + tags->album = NULL; + tags->track = -1; + tags->time = -1; + tags->filled = 0; + + return tags; +} + +void tags_free (struct file_tags *tags) +{ + assert (tags != NULL); + + if (tags->title) + free (tags->title); + if (tags->artist) + free (tags->artist); + if (tags->album) + free (tags->album); + + free (tags); +} + +struct file_tags *recv_tags (int sock) +{ + struct file_tags *tags = tags_new (); + + // filename first. + get_str(sock); + + if (!(tags->title = get_str(sock))) { + fprintf(stderr, "Error while receiving title\n"); + tags_free (tags); + return NULL; + } + + if (!(tags->artist = get_str(sock))) { + fprintf(stderr, "Error while receiving artist\n"); + tags_free (tags); + return NULL; + } + + if (!(tags->album = get_str(sock))) { + fprintf(stderr, "Error while receiving album\n"); + tags_free (tags); + return NULL; + } + + if (!get_int(sock, &tags->track)) { + fprintf(stderr, "Error while receiving track\n"); + tags_free (tags); + return NULL; + } + + if (!get_int(sock, &tags->time)) { + fprintf(stderr, "Error while receiving time\n"); + tags_free (tags); + return NULL; + } + + if (!get_int(sock, &tags->filled)) { + fprintf(stderr, "Error while receiving filled\n"); + tags_free (tags); + return NULL; + } + + /* Set NULL instead of empty tags. */ + if (!tags->title[0]) { + free (tags->title); + tags->title = NULL; + } + if (!tags->artist[0]) { + free (tags->artist); + tags->artist = NULL; + } + if (!tags->album[0]) { + free (tags->album); + tags->album = NULL; + } + + return tags; +} + +/* Send an integer value to the socket, return == 0 on error */ +int send_int (int sock, int i) +{ + int res; + + res = send (sock, &i, sizeof(int), 0); + if (res == -1) + printf("send() failed: %s", strerror(errno)); + + return res == sizeof(int) ? 1 : 0; +} +/* helper that doesn't require a socket */ +static void send_int_to_srv (const int num) +{ + if (!send_int(srv_sock, num)) + fprintf(stderr, "Can't send() int to the server!\n"); +} + +/* Returned memory is malloc()ed. */ +static char *get_str_from_srv () +{ + char *str = get_str (srv_sock); + + if (!str) + fprintf(stderr,"Can't receive string from the server!\n"); + + return str; +} + +static void *get_event_data (const int type) +{ + switch (type) { + case EV_PLIST_ADD: + case EV_QUEUE_ADD: + break; + // return recv_item_from_srv (); + case EV_PLIST_DEL: + case EV_QUEUE_DEL: + case EV_STATUS_MSG: + case EV_SRV_ERROR: + return get_str_from_srv (); + case EV_FILE_TAGS: + // return recv_tags_data_from_srv (); + break; + case EV_PLIST_MOVE: + break; + } + + return NULL; +} +/* Get an integer value from the server that will arrive after EV_DATA. */ +static void wait_for_data () +{ + int event; + + do { + event = get_int_from_srv (); + if (event == EV_EXIT) + fatal("The server exited!"); + if (event != EV_DATA) + event_push (&events, event, get_event_data(event)); + } while (event != EV_DATA); +} + + +void *xmalloc (size_t size) +{ + void *p; + + + if ((p = malloc(size)) == NULL) + fatal ("Can't allocate memory!"); + return p; +} +void event_push (struct event_queue *q, const int event, void *data) +{ + assert (q != NULL); + + if (!q->head) { + q->head = (struct event *)xmalloc (sizeof(struct event)); + q->head->next = NULL; + q->head->type = event; + q->head->data = data; + q->tail = q->head; + } + else { + assert (q->head != NULL); + assert (q->tail != NULL); + assert (q->tail->next == NULL); + + q->tail->next = (struct event *)xmalloc ( + sizeof(struct event)); + q->tail = q->tail->next; + q->tail->next = NULL; + q->tail->type = event; + q->tail->data = data; + } +} + +static int get_int_from_srv () +{ + int num; + + if (!get_int(srv_sock, &num)) + fprintf(stderr, "get_int_from_srv: Can't receive value from the server!\n"); + + return num; +} + +static struct file_tags *recv_tags_from_srv () +{ + struct file_tags *tags = recv_tags (srv_sock); + + if (!tags) + fatal ("recv_tags_from_server: Can't receive tags from the server!"); + + return tags; +} + +static struct file_tags *get_data_tags () +{ + int got_it = 0; + + while (!got_it) { + int type = get_int_from_srv (); + void *data = get_event_data (type); + + if (type == EV_FILE_TAGS) { + got_it = 1; + } + } + return recv_tags_from_srv (); +} + +/* helper functions for getting server info */ +static int get_curr_time () +{ + send_int_to_srv (CMD_GET_CTIME); + return get_data_int (); +} + +static char *get_curr_file () +{ + send_int_to_srv (CMD_GET_SNAME); + return get_data_str (); +} + +static struct file_tags *get_tags(char *file) { + + send_int_to_srv (CMD_GET_FILE_TAGS); + send_str_to_srv (file); + send_int_to_srv (TAGS_COMMENTS | TAGS_TIME); + + return get_data_tags(); + +} + +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; +} + + +/* Obtains the next X11 event with specified timeout. */ + static Bool +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; + } + } + } +} + + +int main(int argc, char** argv) +{ + Display* dpy = XOpenDisplay(NULL); + if (dpy == NULL) + { + fprintf(stderr, "Cannot open display\n"); + exit(1); + } + + srv_sock = server_connect(); + if(srv_sock == -1) { + fprintf(stderr, "Can't connect to MOCP Server at: %s\n", socket_path); + 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); + + bool uname_ok = false; + struct utsname sname; + int ret = uname(&sname); + if (ret != -1) + { + uname_ok = true; + } + + while (1) + { + char *lastfile = NULL; + XEvent e; + int state; + int ev = -1; + int cmd = -1; + + if (!send_int(srv_sock, CMD_GET_STATE)) + fatal ("Can't send commands!"); + + if (!get_int(srv_sock, &ev)) { + fatal("Can't get data from the server 1."); + } + // skip other updates... wait for our data. + while(ev != EV_DATA) { + send_int(srv_sock, CMD_GET_STATE); + if (!get_int(srv_sock, &ev)) { + fprintf(stderr, "Can't get data from the server 1.\n"); + } + } + if(!get_int(srv_sock, &state)) { + fatal ("Can't get state from the server!"); + } + + if (state == STATE_STOP) { + int got_event = XNextEventTimed(dpy, &e, 500); + XClearWindow(dpy, win); + char *no_song = "No Song is Playing."; + XDrawString(dpy, win, DefaultGC(dpy, s), 10, 20, no_song, strlen(no_song)); + } else { + + char *file = get_curr_file(); + + struct file_tags *tags= get_tags(file); + /* + printf("current_file: %s\n", file); + printf("current_title: %s\n", tags->title); + + printf("current_artist: %s\n", tags->artist); + printf("current_artist: %s\n", tags->album); + printf("current_track: %d\n", tags->track); + + printf("current_time: %s\n", time_format(get_curr_time())); + printf("current_length: %s\n", time_format(tags->time)); + */ + + char *curt = time_format(get_curr_time()); + char *curtt = time_format(tags->time); + char *timestr = xmalloc(256); + sprintf(timestr,"%s / %s", curt, curtt); + + int got_event = XNextEventTimed(dpy, &e, 250); + + XClearWindow(dpy, win); + int y_offset = 20; + int x = 10; + XDrawString(dpy, win, DefaultGC(dpy, s), x, y_offset, tags->title, strlen(tags->title)); + y_offset += 15; + XDrawString(dpy, win, DefaultGC(dpy, s), x, y_offset, tags->artist, strlen(tags->artist)); + y_offset += 15; + XDrawString(dpy, win, DefaultGC(dpy, s), x, y_offset, tags->album, strlen(tags->album)); + y_offset += 15; + XDrawString(dpy, win, DefaultGC(dpy, s), x, y_offset, timestr, strlen(timestr)); + y_offset += 15; + + tags_free(tags); + free(file); + free(curt); + free(curtt); + free(timestr); + } + + if (e.type == ButtonPress) { + if (state == STATE_PAUSE) { + cmd = CMD_UNPAUSE; + } + else if (state == STATE_PLAY) { + cmd = CMD_PAUSE; + } + printf("sending pause/play\n"); + send_int(srv_sock, cmd); + e.type=0; + } + if (e.type == KeyPress) + { + char buf[128] = {0}; + KeySym keysym; + int len = XLookupString(&e.xkey, buf, sizeof buf, &keysym, NULL); + if (keysym == XK_Escape) + break; + } + + if ((e.type == ClientMessage) && + (e.xclient.data.l[0]) == WM_DELETE_WINDOW) + { + break; + } + + } + + XDestroyWindow(dpy, win); + XCloseDisplay(dpy); + return 0; +} +/* + int main2(int argc, char** argv) + { + Display* dpy = XOpenDisplay(NULL); + if (dpy == NULL) + { + fprintf(stderr, "Cannot open display\n"); + exit(1); + } + + + srv_sock = server_connect(); + if(srv_sock == -1) { + fprintf(stderr, "Can't connect to MOCP Server at: %s\n", socket_path); + 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 | KeyPressMask); + XMapWindow(dpy, win); + + XStoreName(dpy, win, "Geeks3D.com - X11 window under Linux (Mint 10)"); + + Atom WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + XSetWMProtocols(dpy, win, &WM_DELETE_WINDOW, 1); + + bool uname_ok = false; + struct utsname sname; + int ret = uname(&sname); + if (ret != -1) + { + uname_ok = true; + } + + XEvent e; + while (1) + { + XNextEvent(dpy, &e); + if (e.type == Expose) + { + int y_offset = 20; + + const char* s1 = "X11 test app under Linux"; + + const char* s2 = "(C)2012 Geeks3D.com"; + XDrawString(dpy, win, DefaultGC(dpy, s), 10, y_offset, tags->title, strlen(tags->artist)); + y_offset += 20; + XDrawString(dpy, win, DefaultGC(dpy, s), 10, y_offset, tags->artist, strlen(tags->artist)); + y_offset += 20; + + if (uname_ok) + { + char buf[256] = {0}; + + sprintf(buf, "System information:"); + XDrawString(dpy, win, DefaultGC(dpy, s), 10, y_offset, buf, strlen(buf)); + y_offset += 15; + + sprintf(buf, "- System: %s", sname.sysname); + XDrawString(dpy, win, DefaultGC(dpy, s), 10, y_offset, buf, strlen(buf)); + y_offset += 15; + + sprintf(buf, "- Release: %s", sname.release); + XDrawString(dpy, win, DefaultGC(dpy, s), 10, y_offset, buf, strlen(buf)); + y_offset += 15; + + sprintf(buf, "- Version: %s", sname.version); + XDrawString(dpy, win, DefaultGC(dpy, s), 10, y_offset, buf, strlen(buf)); + y_offset += 15; + +sprintf(buf, "- Machine: %s", sname.machine); +XDrawString(dpy, win, DefaultGC(dpy, s), 10, y_offset, buf, strlen(buf)); +y_offset += 20; +} + + +XWindowAttributes wa; +XGetWindowAttributes(dpy, win, &wa); +int width = wa.width; +int height = wa.height; +char buf[128]={0}; +sprintf(buf, "Current window size: %dx%d", width, height); +XDrawString(dpy, win, DefaultGC(dpy, s), 10, y_offset, buf, strlen(buf)); +y_offset += 20; +} + +if (e.type == KeyPress) +{ + char buf[128] = {0}; + KeySym keysym; + int len = XLookupString(&e.xkey, buf, sizeof buf, &keysym, NULL); + if (keysym == XK_Escape) + break; +} + +if ((e.type == ClientMessage) && + (e.xclient.data.l[0]) == WM_DELETE_WINDOW) +{ + break; +} +} + +XDestroyWindow(dpy, win); +XCloseDisplay(dpy); +return 0; +} */ +/* main loop to publish on MPRIS */ +int main1() { + + srv_sock = server_connect(); + if(srv_sock == -1) { + fprintf(stderr, "Can't connect to MOCP Server at: %s\n", socket_path); + exit(1); + } + + while(1) { + int state; + int ev = -1; + int cmd = -1; + + if (!send_int(srv_sock, CMD_GET_STATE)) + fatal ("Can't send commands!"); + + if (!get_int(srv_sock, &ev)) { + fatal("Can't get data from the server 1."); + } + // skip other updates... wait for our data. + while(ev != EV_DATA) { + if (!get_int(srv_sock, &ev)) { + fatal("Can't get data from the server 1."); + } + } + if(!get_int(srv_sock, &state)) { + fatal ("Can't get state from the server!"); + } + + if (state == STATE_STOP) { + fprintf(stderr, "no song playing\n"); + exit(0); + } + //int type = get_int_from_srv (); + //void *data = get_event_data (type); + + + char *file = get_curr_file(); + printf("current_file: %s\n", file); + + struct file_tags *tags= get_tags(file); + printf("current_title: %s\n", tags->title); + + printf("current_artist: %s\n", tags->artist); + printf("current_artist: %s\n", tags->album); + printf("current_track: %d\n", tags->track); + + printf("current_time: %s\n", time_format(get_curr_time())); + printf("current_length: %s\n", time_format(tags->time)); + + tags_free(tags); + free(file); + sleep(1); + + } + /* if (state == STATE_PAUSE) { + printf("state paused\n"); + cmd = CMD_UNPAUSE; + } + else if (state == STATE_PLAY) { + printf("state paused\n"); + cmd = CMD_PAUSE; + } + + if (cmd != -1 && !send_int(sock, cmd)) + fatal ("Can't send commands!"); + if (!send_int(sock, CMD_DISCONNECT)) + fatal ("Can't send commands!"); + */ +} + +/* + * DBusError err; + DBusConnection* conn; + int ret; +// initialise the errors +dbus_error_init(&err); + +// connect to the bus +conn = dbus_bus_get(DBUS_BUS_SESSION, &err); +if (dbus_error_is_set(&err)) { +fprintf(stderr, "Connection Error (%s)\n", err.message); +dbus_error_free(&err); +} +if (NULL == conn) { +exit(1); +} + * + */ -- cgit v1.2.3