[Goodies-commits] r2124 - in xfce4-mpc-plugin/trunk: . panel-plugin

Landry Breuil landry at xfce.org
Mon Oct 23 19:29:09 CEST 2006


Author: landry
Date: 2006-10-23 17:29:06 +0000 (Mon, 23 Oct 2006)
New Revision: 2124

Added:
   xfce4-mpc-plugin/trunk/panel-plugin/simple-libmpd.c
   xfce4-mpc-plugin/trunk/panel-plugin/simple-libmpd.h
Modified:
   xfce4-mpc-plugin/trunk/configure.ac
   xfce4-mpc-plugin/trunk/panel-plugin/Makefile.am
   xfce4-mpc-plugin/trunk/panel-plugin/xfce4-mpc-plugin.c
   xfce4-mpc-plugin/trunk/panel-plugin/xfce4-mpc-plugin.h
Log:
* modularized mpd interface rewrite (works fine now)
* => everything is now in simple-libmpd.{c,h}
* conditional compilation/linking with simple-libmpd (use std libmpd if found)
* added random/repeat CheckMenuItem in right-click-menu
* test it, and release 0.2.0 soon if not too much bugs :)


Modified: xfce4-mpc-plugin/trunk/configure.ac
===================================================================
--- xfce4-mpc-plugin/trunk/configure.ac	2006-10-23 08:45:16 UTC (rev 2123)
+++ xfce4-mpc-plugin/trunk/configure.ac	2006-10-23 17:29:06 UTC (rev 2124)
@@ -31,7 +31,7 @@
 XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-1.0], [4.3.22])
 
 dnl check for libmpd presence
-AM_CONDITIONAL(HAVE_LIBMPD, true)
+AM_CONDITIONAL(HAVE_LIBMPD, false)
 AC_ARG_WITH(libmpd,
     AC_HELP_STRING([--with-libmpd=path], [path to libmpd base directory]),
         LIBMPD_PATH="$withval", LIBMPD_PATH="")

Modified: xfce4-mpc-plugin/trunk/panel-plugin/Makefile.am
===================================================================
--- xfce4-mpc-plugin/trunk/panel-plugin/Makefile.am	2006-10-23 08:45:16 UTC (rev 2123)
+++ xfce4-mpc-plugin/trunk/panel-plugin/Makefile.am	2006-10-23 17:29:06 UTC (rev 2124)
@@ -3,14 +3,19 @@
 
 xfce4_mpc_plugin_CFLAGS =						\
 	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
-	@LIBXFCE4PANEL_CFLAGS@						\
-	@LIBMPD_CFLAGS@
+	@LIBXFCE4PANEL_CFLAGS@
 
 xfce4_mpc_plugin_LDFLAGS =						\
-	@LIBXFCE4PANEL_LIBS@						\
-	@LIBMPD_LIBS@
-	
+	@LIBXFCE4PANEL_LIBS@
+
+
 xfce4_mpc_plugin_SOURCES = xfce4-mpc-plugin.c
+if HAVE_LIBMPD
+xfce4_mpc_plugin_CFLAGS += @LIBMPD_CFLAGS@
+xfce4_mpc_plugin_LDFLAGS += @LIBMPD_LIBS@
+else
+xfce4_mpc_plugin_SOURCES += simple-libmpd.c
+endif
 
 # .desktop file
 #

Added: xfce4-mpc-plugin/trunk/panel-plugin/simple-libmpd.c
===================================================================
--- xfce4-mpc-plugin/trunk/panel-plugin/simple-libmpd.c	                        (rev 0)
+++ xfce4-mpc-plugin/trunk/panel-plugin/simple-libmpd.c	2006-10-23 17:29:06 UTC (rev 2124)
@@ -0,0 +1,489 @@
+/* simple-libmpd.c
+ * 
+ * Copyright (c) 2006 Landry Breuil (landry at fr.homeunix.org / gaston at gcu.info)
+ * This code is licenced under a BSD-style licence. 
+ * (OpenBSD variant modeled after the ISC licence)
+ * All rights reserved.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* double inclusion ?*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "simple-libmpd.h"
+
+/* for DBG(..) macros */
+#include <libxfce4util/libxfce4util.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#define STRLENGTH 32
+
+MpdObj* mpd_new(char* host, int port, char* pass)
+{
+   MpdObj* mo = g_new0(MpdObj,1);
+
+   DBG("host=%s, port=%d, pass=%s", host, port, pass);
+   
+   mo->host = g_strndup(host,STRLENGTH);
+   mo->port = port;
+   mo->pass = g_strndup(pass,STRLENGTH);
+   mo->socket = 0;
+   mo->status = 0;
+   mo->repeat = 0;
+   mo->random = 0;
+   mo->curvol = 0;
+   mo->error = 0;
+   mo->buffer[0] = '\0';
+   mo->buflen = 0;
+
+   return mo;
+}
+
+void mpd_free(MpdObj* mo)
+{
+   DBG("!");
+   
+   if (mo->socket)
+      close(mo->socket);
+   g_free(mo->host);
+   g_free(mo->pass);
+   g_free(mo);
+}
+
+void mpd_connect(MpdObj* mo)
+{
+   struct hostent* remote_he;
+   struct sockaddr* remote_sa;
+   struct sockaddr_in remote_si;
+   int flags,err,nbread;
+   struct timeval tv;
+   fd_set fds;
+
+   mo->buffer[0] = '\0';
+   mo->buflen = 0;
+
+   /* ??? */
+   if (mo->socket) close(mo->socket);
+
+   DBG("!");
+  
+   if (!(remote_he = (struct hostent*) gethostbyname(mo->host)))
+   {
+      mo->error = MPD_ERROR_UNKHOST;
+      DBG("ERROR @gethostbyname(), err=%s",strerror(errno));
+      return;
+   }
+   memset(&remote_si, 0, sizeof(struct sockaddr_in));
+   remote_si.sin_family = AF_INET;
+   remote_si.sin_port = htons(mo->port);
+   memcpy((char *)&remote_si.sin_addr.s_addr,( char *)remote_he->h_addr, remote_he->h_length);
+
+   remote_sa = (struct sockaddr *)&remote_si;
+
+   if ((mo->socket = socket(AF_INET,SOCK_STREAM,0)) < 0)
+   {
+      mo->error = MPD_ERROR_NOSOCK;
+      DBG("ERROR @socket(), err=%s",strerror(errno));
+      return;
+   }
+   
+   flags = fcntl(mo->socket, F_GETFL, 0);
+   fcntl(mo->socket, F_SETFL, flags | O_NONBLOCK);
+   if (connect(mo->socket,remote_sa, sizeof(struct sockaddr_in)) < 0 && errno != EINPROGRESS)
+   {
+      mo->error = MPD_ERROR_CONNPORT;
+      DBG("ERROR @connect(), err=%s",strerror(errno));
+      return;
+   }
+
+   tv.tv_sec = 1;
+   tv.tv_usec = 0;
+   FD_ZERO(&fds);
+   FD_SET(mo->socket,&fds);
+   if((err = select(mo->socket+1,&fds,NULL,NULL,&tv)) == 1) 
+   {
+      if ((nbread = recv(mo->socket, mo->buffer, MAXBUFLEN, 0)) < 0)
+      {
+         mo->error = MPD_ERROR_NORESPONSE;
+         DBG("ERROR @recv(), err=%s",strerror(errno));
+         return;
+      }
+      if (nbread == 0)
+      {   
+          mo->error = MPD_ERROR_CONNCLOSED;
+          DBG("ERROR @recv(), connection closed by server");
+          return;
+      } 
+      mo->buflen = nbread;
+      mo->buffer[mo->buflen] = '\0';
+   }
+   else if(err < 0)
+   {
+      mo->error = MPD_ERROR_CONNPORT;
+      DBG("ERROR @select(), err=%s",strerror(errno));
+      return;
+   }
+   else
+   {
+      mo->error = MPD_ERROR_NORESPONSE;
+      DBG("ERROR @select(), timeoute'ed -> err=%s",strerror(errno));
+      return;
+   }
+
+   if (strncmp(mo->buffer,MPD_WELCOME_MESSAGE, strlen(MPD_WELCOME_MESSAGE)))
+   {
+      mo->error = MPD_ERROR_NOTMPD;
+      DBG("ERROR @strncmp() -> answer didn't come from mpd");
+      return;
+   }
+
+   DBG("Received %d bytes = welcome message :\"%s\"", mo->buflen, mo->buffer);
+   
+   *mo->buffer = '\0';
+   mo->buflen = 0;
+   mo->error = 0;
+}
+
+void mpd_disconnect(MpdObj* mo)
+{
+   DBG("!");
+   if (mo->socket) 
+      close(mo->socket);
+}
+
+int mpd_status_get_volume(MpdObj* mo)
+{
+   DBG("! return %d",mo->curvol);
+   return mo->curvol;
+}
+
+void mpd_wait_for_answer(MpdObj *mo)
+{
+   struct timeval tv;
+   int err,nbread;
+   err = nbread = 0;
+   fd_set fds;
+   
+   DBG("!");
+   
+   tv.tv_sec = 1;
+   tv.tv_usec = 0;
+   FD_ZERO(&fds);
+   FD_SET(mo->socket,&fds);
+   if((err = select(mo->socket+1,&fds,NULL,NULL,&tv)) == 1) 
+   {
+      if ((nbread = recv(mo->socket, mo->buffer, MAXBUFLEN, 0)) < 0)
+      {
+         mo->error = MPD_ERROR_NORESPONSE;
+         DBG("ERROR @recv(), err=%s",strerror(errno));
+         return;
+      }
+      if (nbread == 0)
+      {   
+         mo->error = MPD_ERROR_CONNCLOSED;
+         DBG("ERROR @recv(), connection closed by server");
+         return;
+      }
+ 
+      DBG("Read %d bytes, buff=\"%s\"", nbread, mo->buffer);
+      mo->buflen = nbread;
+      mo->buffer[mo->buflen] = '\0';
+   }
+   else if(err < 0)
+   {
+      mo->error = MPD_ERROR_CONNPORT;
+      DBG("ERROR @select(), err=%s",strerror(errno));
+      return;
+   }
+   else
+   {
+      mo->error = MPD_ERROR_NORESPONSE;
+      DBG("ERROR @select(), timeoute'ed -> err=%s",strerror(errno));
+      return;
+   }
+   if (!strncmp(mo->buffer,"ACK",3))
+      mo->error = MPD_NOTOK; 
+   else
+      mo->error = MPD_OK;
+}
+
+int mpd_send_single_cmd(MpdObj*mo, char* cmd)
+{
+   int nbwri = 0;
+
+   if (mo->socket) 
+   {
+      DBG("Sending \"%s\"",cmd);
+      if ((nbwri = send(mo->socket, cmd, strlen(cmd), 0)) <= 0)
+      {
+         mo->error = MPD_ERROR_SENDING;
+         DBG("ERROR @send(), err=%s",strerror(errno));
+      }
+      DBG("Sent %d bytes",nbwri);
+      /* wait for OK */
+      mpd_wait_for_answer(mo);
+      
+      if(!mo->error)
+      {
+         if (strcmp(mo->buffer,"OK\n") != 0)
+         {
+            mo->error = MPD_FAILED;
+            DBG("ERROR : did not received OK");
+         }
+      }
+      *mo->buffer = '\0';
+      mo->buflen = 0;
+   }
+   else
+   {
+      mo->error = MPD_ERROR_NOSOCK;
+      DBG("ERROR : socket == NULL ?");
+   }
+   return ((!mo->error) ? MPD_OK : MPD_FAILED);
+}
+
+void* send_complex_cmd(MpdObj* mo, char* cmd, void* (*parse_answer_fct)())
+{
+   int nbwri;
+   void *res = NULL;
+   /* write 'status' to socket */
+   if (mo->socket) 
+   {
+      DBG("Sending \"%s\"",cmd);
+      if ((nbwri = send(mo->socket, cmd, strlen(cmd), 0)) < 0)
+      {
+         mo->error = MPD_ERROR_SENDING;
+         DBG("ERROR @send(), err=%s",strerror(errno));
+         return NULL;
+      }
+      DBG("Sent %d bytes",nbwri);
+      
+      mpd_wait_for_answer(mo);
+      
+      if (!mo->error)
+         res = (*parse_answer_fct)(mo);
+
+      *mo->buffer = '\0';
+      mo->buflen = 0;
+   }
+   else
+   {
+      mo->error = MPD_ERROR_NOSOCK;
+      DBG("ERROR : socket == NULL ?");
+   }
+   /* return NULL if error */
+   return res;
+}
+
+void * parse_status_answer(MpdObj *mo)
+{
+   char *eol,*ptr;
+   char key[15], value[200];
+
+   while (strcmp(mo->buffer,"OK\n"))
+   {
+      /*HACK @#!*/
+      ptr = strstr(mo->buffer, ":");
+      eol = strstr(mo->buffer, "\n");
+      strncpy(key, mo->buffer, ptr - mo->buffer);
+      key[ptr - mo->buffer]='\0';
+      strncpy(value,ptr + 2 , eol - ptr - 2);
+      value[eol - ptr - 2]='\0';
+ 
+      DBG("key=\"%s\",value=\"%s\"", key, value);
+      if      (0 == strcmp("volume",key)) mo->curvol = atoi(value);
+      else if (0 == strcmp("repeat",key)) mo->repeat = atoi(value);
+      else if (0 == strcmp("random",key)) mo->random = atoi(value);
+      else if (0 == strcmp("state", key)) 
+      {
+         if      (0 == strcmp("play", value)) mo->status = MPD_PLAYER_PLAY;
+         else if (0 == strcmp("pause",value)) mo->status = MPD_PLAYER_PAUSE;
+         else if (0 == strcmp("stop", value)) mo->status = MPD_PLAYER_STOP;
+      }
+      *eol = '\0';
+      strcpy(mo->buffer, eol+1);
+      mo->buflen = strlen(mo->buffer);
+   }
+   return NULL;
+}
+
+int mpd_status_update(MpdObj* mo)
+{
+   mo->status = 0;
+   DBG("!");
+   send_complex_cmd(mo, "status\n", parse_status_answer);
+   return ((!mo->error) ? MPD_OK : MPD_FAILED);
+}
+   
+
+void* parse_currentsong_answer(MpdObj *mo)
+{
+   mpd_Song* ms = g_new0(mpd_Song,1);
+   char *eol,*ptr;
+   char key[15], value[200];
+
+   ms->artist= ms->album = ms->title = ms->track = NULL;
+   while (strcmp(mo->buffer,"OK\n"))
+   {
+      /*HACK @#!*/
+      ptr = strstr(mo->buffer, ":");
+      eol = strstr(mo->buffer, "\n");
+      strncpy(key, mo->buffer, ptr - mo->buffer);
+      key[ptr - mo->buffer]='\0';
+      strncpy(value,ptr + 2 , eol - ptr - 2);
+      value[eol - ptr - 2]='\0';
+
+      DBG("key=\"%s\",value=\"%s\"", key, value);
+      if      (!ms->artist && 0 == strcmp("Artist",key)) ms->artist= strdup(value);
+      else if (!ms->album  && 0 == strcmp("Album", key)) ms->album = strdup(value);
+      else if (!ms->title  && 0 == strcmp("Title", key)) ms->title = strdup(value);
+      else if (!ms->track  && 0 == strcmp("Track", key)) ms->track = strdup(value);
+      *eol = '\0';
+      strcpy(mo->buffer, eol+1);
+      mo->buflen = strlen(mo->buffer);
+   }
+   return (void*) ms;
+}
+
+mpd_Song* mpd_playlist_get_current_song(MpdObj* mo)
+{
+   mpd_Song* ms;
+   DBG("!");
+   ms = (mpd_Song*) send_complex_cmd(mo, "currentsong\n", parse_currentsong_answer);
+   /* return NULL if error */
+   return ((!mo->error) ? ms : NULL);
+}
+
+void mpd_status_set_volume(MpdObj* mo, int newvol)
+{
+   char outbuf[15];
+   /* write setvol 'newvol' to socket */
+   DBG("!");
+   sprintf(outbuf,"setvol %d\n",newvol);
+   mpd_send_single_cmd(mo,outbuf);
+}
+
+int mpd_player_get_state(MpdObj* mo)
+{
+   DBG("! return %d",mo->status);
+   return mo->status;
+}
+
+int mpd_player_get_random(MpdObj* mo)
+{
+   DBG("! return %d",mo->random);
+   return mo->random;
+}
+
+int mpd_player_set_random(MpdObj* mo, int random)
+{
+   char outbuf[15];
+   DBG("!");
+   sprintf(outbuf,"random %d\n",random);
+   return mpd_send_single_cmd(mo,outbuf);
+
+}
+
+int mpd_player_set_repeat(MpdObj* mo, int repeat)
+{
+   char outbuf[15];
+   DBG("!");
+   sprintf(outbuf,"repeat %d\n",repeat);
+   return mpd_send_single_cmd(mo,outbuf);
+}
+
+int mpd_player_get_repeat(MpdObj* mo)
+{
+   DBG("! return %d",mo->repeat);
+   return mo->repeat;
+}
+
+int mpd_player_prev(MpdObj* mo)
+{
+   DBG("!");
+   return mpd_send_single_cmd(mo,"previous\n");
+}
+
+int mpd_player_next(MpdObj* mo)
+{
+   DBG("!");
+   return mpd_send_single_cmd(mo,"next\n");
+}
+
+int mpd_player_stop(MpdObj* mo)
+{
+   DBG("!");
+   return mpd_send_single_cmd(mo,"stop\n");
+}
+
+int mpd_player_pause(MpdObj* mo)
+{
+   DBG("!");
+   if (mo->status != MPD_PLAYER_PLAY)
+      return mpd_send_single_cmd(mo,"pause 0\n");
+   else
+      return mpd_send_single_cmd(mo,"pause 1\n");
+}
+
+int mpd_player_play(MpdObj* mo)
+{
+   DBG("!");
+   return mpd_send_single_cmd(mo,"play\n");
+}
+
+int mpd_check_error(MpdObj* mo)
+{
+   DBG("! return %d",mo->error);
+   return mo->error;
+}
+
+void mpd_send_password(MpdObj* mo)
+{
+   DBG("!");
+   char outbuf[30];
+   /* write password 'password' to socket */
+   sprintf(outbuf,"password %s\n",mo->pass);
+   mpd_send_single_cmd(mo,outbuf);
+}
+
+void mpd_set_hostname(MpdObj* mo, char* host)
+{
+   DBG("! new hostname=%s",host);
+   g_free(mo->host);
+   mo->host = g_strndup(host,STRLENGTH);
+}
+
+void mpd_set_password(MpdObj* mo, char* pass)
+{
+   DBG("! new password=%s",pass);
+   g_free(mo->pass);
+   mo->pass = g_strndup(pass,STRLENGTH);
+}
+
+void mpd_set_port(MpdObj* mo,int port)
+{
+   DBG("! new port=%d",port);
+   mo->port = port;
+}
+

Added: xfce4-mpc-plugin/trunk/panel-plugin/simple-libmpd.h
===================================================================
--- xfce4-mpc-plugin/trunk/panel-plugin/simple-libmpd.h	                        (rev 0)
+++ xfce4-mpc-plugin/trunk/panel-plugin/simple-libmpd.h	2006-10-23 17:29:06 UTC (rev 2124)
@@ -0,0 +1,85 @@
+/* simple-libmpd.h
+ * 
+ * Copyright (c) 2006 Landry Breuil (landry at fr.homeunix.org / gaston at gcu.info)
+ * This code is licenced under a BSD-style licence. 
+ * (OpenBSD variant modeled after the ISC licence)
+ * All rights reserved.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* for gchar and g_new conveniences */ 
+#include <gtk/gtk.h>
+
+#define MPD_PLAYER_STOP 1
+#define MPD_PLAYER_PLAY 2
+#define MPD_PLAYER_PAUSE 3
+#define MPD_OK 0
+#define MPD_FAILED 1
+#define MPD_NOTOK 2
+#define MPD_WELCOME_MESSAGE "OK MPD "
+#define MAXBUFLEN 1000
+
+#define MPD_ERROR_NOSOCK      9
+#define MPD_ERROR_TIMEOUT     10 /* timeout trying to talk to mpd */
+#define MPD_ERROR_SYSTEM      11 /* system error */
+#define MPD_ERROR_UNKHOST     12 /* unknown host */
+#define MPD_ERROR_CONNPORT    13 /* problems connecting to port on host */
+#define MPD_ERROR_NOTMPD      14 /* mpd not running on port at host */
+#define MPD_ERROR_NORESPONSE  15 /* no response on attempting to connect */
+#define MPD_ERROR_SENDING     16 /* error sending command */
+#define MPD_ERROR_CONNCLOSED  17 /* connection closed by mpd */
+
+typedef struct {
+   gchar* host;
+   int port;
+   gchar* pass;
+   int socket;
+   int status;
+   int curvol;
+   int repeat;
+   int random;
+   int error;
+   char buffer[MAXBUFLEN+1];
+   int buflen;
+} MpdObj;
+
+typedef struct {
+   char* artist;
+   char* album;
+   char* track;
+   char* title;
+} mpd_Song;
+
+MpdObj* mpd_new(char*, int, char*);
+void mpd_free(MpdObj*);
+void mpd_connect(MpdObj*);
+void mpd_disconnect(MpdObj*);
+int mpd_status_get_volume(MpdObj*);
+void mpd_status_set_volume(MpdObj*, int);
+int mpd_status_update(MpdObj*);
+int mpd_player_get_state(MpdObj*);
+int mpd_player_prev(MpdObj*);
+int mpd_player_next(MpdObj*);
+int mpd_player_stop(MpdObj*);
+int mpd_player_pause(MpdObj*);
+int mpd_player_play(MpdObj*);
+mpd_Song* mpd_playlist_get_current_song(MpdObj*);
+int mpd_check_error(MpdObj*);
+void mpd_set_hostname(MpdObj*, char*);
+void mpd_set_password(MpdObj*, char*);
+void mpd_send_password(MpdObj*);
+void mpd_set_port(MpdObj*, int);
+int mpd_player_set_random(MpdObj*,int);
+int mpd_player_get_random(MpdObj*);
+int mpd_player_set_repeat(MpdObj*,int);
+int mpd_player_get_repeat(MpdObj*);

Modified: xfce4-mpc-plugin/trunk/panel-plugin/xfce4-mpc-plugin.c
===================================================================
--- xfce4-mpc-plugin/trunk/panel-plugin/xfce4-mpc-plugin.c	2006-10-23 08:45:16 UTC (rev 2123)
+++ xfce4-mpc-plugin/trunk/panel-plugin/xfce4-mpc-plugin.c	2006-10-23 17:29:06 UTC (rev 2124)
@@ -17,15 +17,13 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
  
-#include <stdio.h>
-#include <string.h>
-
 /* double inclusion ?*/
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
 #include <libxfcegui4/libxfcegui4.h>
+#include <string.h>
 
 #define DEFAULT_MPD_HOST "localhost"
 #define DEFAULT_MPD_PORT 6600
@@ -34,432 +32,6 @@
 
 #include "xfce4-mpc-plugin.h"
 
-#ifndef HAVE_LIBMPD
-
-#include <netinet/in.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <errno.h>
-#include <fcntl.h>
-
-MpdObj* mpd_new(char* host, int port, char* pass)
-{
-   MpdObj* mo = g_new0(MpdObj,1);
-
-   DBG("host=%s, port=%d, pass=%s", host, port, pass);
-   
-   mo->host = g_strndup(host,STRLENGTH);
-   mo->port = port;
-   mo->pass = g_strndup(pass,STRLENGTH);
-   mo->socket = 0;
-   mo->status = 0;
-   mo->curvol = 0;
-   mo->error = 0;
-   mo->buffer[0] = '\0';
-   mo->buflen = 0;
-
-   return mo;
-}
-
-void mpd_free(MpdObj* mo)
-{
-   DBG("!");
-   
-   if (mo->socket)
-      close(mo->socket);
-   g_free(mo->host);
-   g_free(mo->pass);
-   g_free(mo);
-}
-
-void mpd_connect(MpdObj* mo)
-{
-   struct hostent* remote_he;
-   struct sockaddr* remote_sa;
-   struct sockaddr_in remote_si;
-   int flags,err,nbread;
-   struct timeval tv;
-   fd_set fds;
-
-   mo->buffer[0] = '\0';
-   mo->buflen = 0;
-
-   /* ??? */
-   if (mo->socket) close(mo->socket);
-
-   DBG("!");
-  
-   if (!(remote_he = (struct hostent*) gethostbyname(mo->host)))
-   {
-      mo->error = MPD_ERROR_UNKHOST;
-      DBG("ERROR @gethostbyname(), err=%s",strerror(errno));
-      return;
-   }
-   memset(&remote_si, 0, sizeof(struct sockaddr_in));
-   remote_si.sin_family = AF_INET;
-   remote_si.sin_port = htons(mo->port);
-   memcpy((char *)&remote_si.sin_addr.s_addr,( char *)remote_he->h_addr, remote_he->h_length);
-
-   remote_sa = (struct sockaddr *)&remote_si;
-
-   if ((mo->socket = socket(AF_INET,SOCK_STREAM,0)) < 0)
-   {
-      mo->error = MPD_ERROR_NOSOCK;
-      DBG("ERROR @socket(), err=%s",strerror(errno));
-      return;
-   }
-   
-   flags = fcntl(mo->socket, F_GETFL, 0);
-   fcntl(mo->socket, F_SETFL, flags | O_NONBLOCK);
-   if (connect(mo->socket,remote_sa, sizeof(struct sockaddr_in)) < 0 && errno != EINPROGRESS)
-   {
-      mo->error = MPD_ERROR_CONNPORT;
-      DBG("ERROR @connect(), err=%s",strerror(errno));
-      return;
-   }
-
-   tv.tv_sec = 1;
-   tv.tv_usec = 0;
-   FD_ZERO(&fds);
-   FD_SET(mo->socket,&fds);
-   if((err = select(mo->socket+1,&fds,NULL,NULL,&tv)) == 1) 
-   {
-      if ((nbread = recv(mo->socket, mo->buffer, MAXBUFLEN, 0)) < 0)
-      {
-         mo->error = MPD_ERROR_NORESPONSE;
-         DBG("ERROR @recv(), err=%s",strerror(errno));
-         return;
-      }
-      if (nbread == 0)
-      {   
-          mo->error = MPD_ERROR_CONNCLOSED;
-          DBG("ERROR @recv(), connection closed by server");
-          return;
-      } 
-      mo->buflen = nbread;
-      mo->buffer[mo->buflen] = '\0';
-   }
-   else if(err < 0)
-   {
-      mo->error = MPD_ERROR_CONNPORT;
-      DBG("ERROR @select(), err=%s",strerror(errno));
-      return;
-   }
-   else
-   {
-      mo->error = MPD_ERROR_NORESPONSE;
-      DBG("ERROR @select(), timeoute'ed -> err=%s",strerror(errno));
-      return;
-   }
-
-   if (strncmp(mo->buffer,MPD_WELCOME_MESSAGE, strlen(MPD_WELCOME_MESSAGE)))
-   {
-      mo->error = MPD_ERROR_NOTMPD;
-      DBG("ERROR @strncmp() -> answer didn't come from mpd");
-      return;
-   }
-
-   DBG("Received %d bytes = welcome message :\"%s\"", mo->buflen, mo->buffer);
-   
-   *mo->buffer = '\0';
-   mo->buflen = 0;
-   mo->error = 0;
-}
-
-void mpd_disconnect(MpdObj* mo)
-{
-   DBG("!");
-   if (mo->socket) 
-      close(mo->socket);
-}
-
-int mpd_status_get_volume(MpdObj* mo)
-{
-   DBG("! return %d",mo->curvol);
-   return mo->curvol;
-}
-
-void mpd_wait_for_answer(MpdObj *mo)
-{
-   struct timeval tv;
-   int err,nbread;
-   err = nbread = 0;
-   fd_set fds;
-   
-   DBG("!");
-   
-   tv.tv_sec = 1;
-   tv.tv_usec = 0;
-   FD_ZERO(&fds);
-   FD_SET(mo->socket,&fds);
-   if((err = select(mo->socket+1,&fds,NULL,NULL,&tv)) == 1) 
-   {
-      if ((nbread = recv(mo->socket, mo->buffer, MAXBUFLEN, 0)) < 0)
-      {
-         mo->error = MPD_ERROR_NORESPONSE;
-         DBG("ERROR @recv(), err=%s",strerror(errno));
-         return;
-      }
-      if (nbread == 0)
-      {   
-         mo->error = MPD_ERROR_CONNCLOSED;
-         DBG("ERROR @recv(), connection closed by server");
-         return;
-      }
- 
-      DBG("Read %d bytes, buff=\"%s\"", nbread, mo->buffer);
-      mo->buflen = nbread;
-      mo->buffer[mo->buflen] = '\0';
-   }
-   else if(err < 0)
-   {
-      mo->error = MPD_ERROR_CONNPORT;
-      DBG("ERROR @select(), err=%s",strerror(errno));
-      return;
-   }
-   else
-   {
-      mo->error = MPD_ERROR_NORESPONSE;
-      DBG("ERROR @select(), timeoute'ed -> err=%s",strerror(errno));
-      return;
-   }
-   if (!strncmp(mo->buffer,"ACK",3))
-      mo->error = MPD_NOTOK; 
-   else
-      mo->error = MPD_OK;
-}
-
-int mpd_send_single_cmd(MpdObj*mo, char* cmd)
-{
-   int nbwri = 0;
-
-   if (mo->socket) 
-   {
-      DBG("Sending \"%s\"",cmd);
-      if ((nbwri = send(mo->socket, cmd, strlen(cmd), 0)) <= 0)
-      {
-         mo->error = MPD_ERROR_SENDING;
-         DBG("ERROR @send(), err=%s",strerror(errno));
-      }
-      DBG("Sent %d bytes",nbwri);
-      /* wait for OK */
-      mpd_wait_for_answer(mo);
-      
-      if(!mo->error)
-      {
-         if (strcmp(mo->buffer,"OK\n") != 0)
-         {
-            mo->error = MPD_FAILED;
-            DBG("ERROR : did not received OK");
-         }
-      }
-      *mo->buffer = '\0';
-      mo->buflen = 0;
-   }
-   else
-   {
-      mo->error = MPD_ERROR_NOSOCK;
-      DBG("ERROR : socket == NULL ?");
-   }
-   return ((!mo->error) ? MPD_OK : MPD_FAILED);
-}
-
-void mpd_status_set_volume(MpdObj* mo, int newvol)
-{
-   char outbuf[15];
-   /* write setvol 'newvol' to socket */
-   DBG("!");
-   sprintf(outbuf,"setvol %d\n",newvol);
-   mpd_send_single_cmd(mo,outbuf);
-}
-
-void* send_complex_cmd(MpdObj* mo, char* cmd, void* (*parse_answer_fct)())
-{
-   int nbwri;
-   void *res = NULL;
-   /* write 'status' to socket */
-   if (mo->socket) 
-   {
-      DBG("Sending \"%s\"",cmd);
-      if ((nbwri = send(mo->socket, cmd, strlen(cmd), 0)) < 0)
-      {
-         mo->error = MPD_ERROR_SENDING;
-         DBG("ERROR @send(), err=%s",strerror(errno));
-         return NULL;
-      }
-      DBG("Sent %d bytes",nbwri);
-      
-      mpd_wait_for_answer(mo);
-      
-      if (!mo->error)
-         res = (*parse_answer_fct)(mo);
-
-      *mo->buffer = '\0';
-      mo->buflen = 0;
-   }
-   else
-   {
-      mo->error = MPD_ERROR_NOSOCK;
-      DBG("ERROR : socket == NULL ?");
-   }
-   /* return NULL if error */
-   return res;
-}
-
-void * parse_status_answer(MpdObj *mo)
-{
-   char *eol,*ptr;
-   char key[15], value[200];
-
-   while (strcmp(mo->buffer,"OK\n"))
-   {
-      /*HACK @#!*/
-      ptr = strstr(mo->buffer, ":");
-      eol = strstr(mo->buffer, "\n");
-      strncpy(key, mo->buffer, ptr - mo->buffer);
-      key[ptr - mo->buffer]='\0';
-      strncpy(value,ptr + 2 , eol - ptr - 2);
-      value[eol - ptr - 2]='\0';
- 
-      DBG("key=\"%s\",value=\"%s\"", key, value);
-      if      (0 == strcmp("volume",key)) mo->curvol = atoi(value);
-      else if (0 == strcmp("state", key)) 
-      {
-         if      (0 == strcmp("play", value)) mo->status = MPD_PLAYER_PLAY;
-         else if (0 == strcmp("pause",value)) mo->status = MPD_PLAYER_PAUSE;
-         else if (0 == strcmp("stop", value)) mo->status = MPD_PLAYER_STOP;
-      }
-      *eol = '\0';
-      strcpy(mo->buffer, eol+1);
-      mo->buflen = strlen(mo->buffer);
-   }
-   return NULL;
-}
-
-int mpd_status_update(MpdObj* mo)
-{
-   mo->status = 0;
-   DBG("!");
-   send_complex_cmd(mo, "status\n", parse_status_answer);
-   return ((!mo->error) ? MPD_OK : MPD_FAILED);
-}
-   
-
-void* parse_currentsong_answer(MpdObj *mo)
-{
-   mpd_Song* ms = g_new0(mpd_Song,1);
-   char *eol,*ptr;
-   char key[15], value[200];
-
-   ms->artist= ms->album = ms->title = ms->track = NULL;
-   while (strcmp(mo->buffer,"OK\n"))
-   {
-      /*HACK @#!*/
-      ptr = strstr(mo->buffer, ":");
-      eol = strstr(mo->buffer, "\n");
-      strncpy(key, mo->buffer, ptr - mo->buffer);
-      key[ptr - mo->buffer]='\0';
-      strncpy(value,ptr + 2 , eol - ptr - 2);
-      value[eol - ptr - 2]='\0';
-
-      DBG("key=\"%s\",value=\"%s\"", key, value);
-      if      (!ms->artist && 0 == strcmp("Artist",key)) ms->artist= strdup(value);
-      else if (!ms->album  && 0 == strcmp("Album", key)) ms->album = strdup(value);
-      else if (!ms->title  && 0 == strcmp("Title", key)) ms->title = strdup(value);
-      else if (!ms->track  && 0 == strcmp("Track", key)) ms->track = strdup(value);
-      *eol = '\0';
-      strcpy(mo->buffer, eol+1);
-      mo->buflen = strlen(mo->buffer);
-   }
-   return (void*) ms;
-}
-
-mpd_Song* mpd_playlist_get_current_song(MpdObj* mo)
-{
-   mpd_Song* ms;
-   DBG("!");
-   ms = (mpd_Song*) send_complex_cmd(mo, "currentsong\n", parse_currentsong_answer);
-   /* return NULL if error */
-   return ((!mo->error) ? ms : NULL);
-}
-
-
-int mpd_player_get_state(MpdObj* mo)
-{
-   DBG("! return %d",mo->status);
-   return mo->status;
-}
-
-int mpd_player_prev(MpdObj* mo)
-{
-   DBG("!");
-   return mpd_send_single_cmd(mo,"previous\n");
-}
-
-int mpd_player_next(MpdObj* mo)
-{
-   DBG("!");
-   return mpd_send_single_cmd(mo,"next\n");
-}
-
-int mpd_player_stop(MpdObj* mo)
-{
-   DBG("!");
-   return mpd_send_single_cmd(mo,"stop\n");
-}
-
-int mpd_player_pause(MpdObj* mo)
-{
-   DBG("!");
-   if (mo->status != MPD_PLAYER_PLAY)
-      return mpd_send_single_cmd(mo,"pause 0\n");
-   else
-      return mpd_send_single_cmd(mo,"pause 1\n");
-}
-
-int mpd_player_play(MpdObj* mo)
-{
-   DBG("!");
-   return mpd_send_single_cmd(mo,"play\n");
-}
-
-int mpd_check_error(MpdObj* mo)
-{
-   DBG("! return %d",mo->error);
-   return mo->error;
-}
-
-void mpd_send_password(MpdObj* mo)
-{
-   DBG("!");
-   char outbuf[30];
-   /* write password 'password' to socket */
-   sprintf(outbuf,"password %s\n",mo->pass);
-   mpd_send_single_cmd(mo,outbuf);
-}
-
-void mpd_set_hostname(MpdObj* mo, char* host)
-{
-   DBG("! new hostname=%s",host);
-   g_free(mo->host);
-   mo->host = g_strndup(host,STRLENGTH);
-}
-
-void mpd_set_password(MpdObj* mo, char* pass)
-{
-   DBG("! new password=%s",pass);
-   g_free(mo->pass);
-   mo->pass = g_strndup(pass,STRLENGTH);
-}
-
-void mpd_set_port(MpdObj* mo,int port)
-{
-   DBG("! new port=%d",port);
-   mo->port = port;
-}
-#endif /* !HAVE_LIBMPD */ 
-
 static void
 mpc_free (XfcePanelPlugin * plugin, t_mpc * mpc)
 {
@@ -688,6 +260,20 @@
 }
 
 static void 
+mpc_random_toggled(GtkWidget *widget, t_mpc* mpc)
+{
+   DBG("!");
+   mpd_player_set_random(mpc->mo, gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
+}
+
+static void 
+mpc_repeat_toggled(GtkWidget *widget, t_mpc* mpc)
+{
+   DBG("!");
+   mpd_player_set_repeat(mpc->mo, gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
+}
+
+static void 
 enter_cb(GtkWidget *widget, GdkEventCrossing* event, t_mpc* mpc) 
 {
    mpd_Song *song;
@@ -724,8 +310,12 @@
       g_sprintf(str,"%s - [%s - %s] -/- (#%s) %s", str, song->artist, song->album, song->track, song->title);
    else
       g_sprintf(str,"%s - Failed to get song info ?", str);
+   
+   gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mpc->random), mpd_player_get_random(mpc->mo));
+   gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mpc->repeat), mpd_player_get_repeat(mpc->mo));
+
    gtk_tooltips_set_tip (mpc->tips, widget, str, NULL);
-   g_free(song); /*??*/
+   /* g_free(song); FIXME ?? */
 }
 
 static void 
@@ -855,7 +445,6 @@
    mpc = g_new0 (t_mpc, 1);
    
    mpc->plugin = plugin;
-
    mpc->tips = gtk_tooltips_new ();
    g_object_ref (mpc->tips);
    gtk_object_sink (GTK_OBJECT (mpc->tips));
@@ -878,7 +467,15 @@
    new_button_with_img(plugin, mpc->box, mpc->stop, GTK_STOCK_MEDIA_STOP, G_CALLBACK(stop), mpc);
    new_button_with_img(plugin, mpc->box, mpc->toggle, GTK_STOCK_MEDIA_PAUSE, G_CALLBACK(toggle), mpc);
    new_button_with_img(plugin, mpc->box, mpc->next, GTK_STOCK_MEDIA_NEXT, G_CALLBACK(next), mpc);
-
+   
+   mpc->random = gtk_check_menu_item_new_with_label (_("Random"));
+   g_signal_connect (G_OBJECT(mpc->random), "toggled", G_CALLBACK (mpc_random_toggled), mpc);
+   mpc->repeat = gtk_check_menu_item_new_with_label (_("Repeat"));
+   g_signal_connect (G_OBJECT(mpc->repeat), "toggled", G_CALLBACK (mpc_repeat_toggled), mpc);
+   xfce_panel_plugin_menu_insert_item(plugin,GTK_MENU_ITEM(mpc->random));
+   xfce_panel_plugin_menu_insert_item(plugin,GTK_MENU_ITEM(mpc->repeat));
+   gtk_widget_show (mpc->repeat);
+   gtk_widget_show (mpc->random);
    gtk_widget_show_all (mpc->box);
     
    return mpc;
@@ -926,6 +523,7 @@
    g_signal_connect (plugin, "orientation-changed", G_CALLBACK (mpc_set_orientation), mpc);
    /* the configure and about menu items are hidden by default */
    xfce_panel_plugin_menu_show_configure (plugin);
+
    g_signal_connect (plugin, "configure-plugin", G_CALLBACK (mpc_create_options), mpc);
 }
 

Modified: xfce4-mpc-plugin/trunk/panel-plugin/xfce4-mpc-plugin.h
===================================================================
--- xfce4-mpc-plugin/trunk/panel-plugin/xfce4-mpc-plugin.h	2006-10-23 08:45:16 UTC (rev 2123)
+++ xfce4-mpc-plugin/trunk/panel-plugin/xfce4-mpc-plugin.h	2006-10-23 17:29:06 UTC (rev 2124)
@@ -28,76 +28,21 @@
 #include <libmpd/debug_printf.h>
 #endif
 #else
-
-#define MPD_PLAYER_STOP 1
-#define MPD_PLAYER_PLAY 2
-#define MPD_PLAYER_PAUSE 3
-#define MPD_OK 0
-#define MPD_FAILED 1
-#define MPD_NOTOK 2
-#define MPD_WELCOME_MESSAGE "OK MPD "
-#define MAXBUFLEN 1000
-
-#define MPD_ERROR_NOSOCK      9
-#define MPD_ERROR_TIMEOUT     10 /* timeout trying to talk to mpd */
-#define MPD_ERROR_SYSTEM      11 /* system error */
-#define MPD_ERROR_UNKHOST     12 /* unknown host */
-#define MPD_ERROR_CONNPORT    13 /* problems connecting to port on host */
-#define MPD_ERROR_NOTMPD      14 /* mpd not running on port at host */
-#define MPD_ERROR_NORESPONSE  15 /* no response on attempting to connect */
-#define MPD_ERROR_SENDING     16 /* error sending command */
-#define MPD_ERROR_CONNCLOSED  17 /* connection closed by mpd */
-
-typedef struct {
-   gchar* host;
-   int port;
-   gchar* pass;
-   int socket;
-   int status;
-   int curvol;
-   int error;
-   char buffer[MAXBUFLEN+1];
-   int buflen;
-} MpdObj;
-
-typedef struct {
-   char* artist;
-   char* album;
-   char* track;
-   char* title;
-} mpd_Song;
-
-MpdObj* mpd_new(char*,int,char*);
-void mpd_free(MpdObj*);
-void mpd_connect(MpdObj*);
-void mpd_disconnect(MpdObj*);
-int mpd_status_get_volume(MpdObj*);
-void mpd_status_set_volume(MpdObj*,int);
-int mpd_status_update(MpdObj*);
-int mpd_player_get_state(MpdObj*);
-int mpd_player_prev(MpdObj*);
-int mpd_player_next(MpdObj*);
-int mpd_player_stop(MpdObj*);
-int mpd_player_pause(MpdObj*);
-mpd_Song* mpd_playlist_get_current_song(MpdObj*);
-int mpd_check_error(MpdObj*);
-void mpd_set_hostname(MpdObj*,char*);
-void mpd_set_password(MpdObj*,char*);
-void mpd_send_password(MpdObj*);
-void mpd_set_port(MpdObj*,int);
-
+#include "simple-libmpd.h"
 #endif /* !HAVE_LIBMPD */
 
 typedef struct {
    XfcePanelPlugin *plugin;
    GtkTooltips *tips;
-   GtkWidget *frame,*ebox,*box,*prev,*stop,*toggle,*next;
+   GtkWidget *frame,*ebox,*box,*prev,*stop,*toggle,*next,*random,*repeat;
+   gboolean show_frame;
    /* mpd handle */
    MpdObj *mo;
    gchar* mpd_host;
    gint mpd_port;
    gchar * mpd_password;
-   gboolean show_frame;
+   gboolean mpd_repeat;
+   gboolean mpd_random;
 } t_mpc;
 
 typedef struct {




More information about the Goodies-commits mailing list