Askelon
July 24th, 2008, 06:14 PM
Hi!
http://img371.imageshack.us/img371/5118/capture32ph2.th.jpg (http://img371.imageshack.us/my.php?image=capture32ph2.jpg)
Yep, it's done! Since conky doesn't provide image support, I decided to write a little program that would help me getting my Amarok cover on my desk as well as other informations like artist or title :) It's actually pretty simple ; I based my work on some pieces of conky's sources, to display the cover image on a small window, at a position we specify, as for the refresh delay.
There's still a few points to be improved :
+ I failed to make the window sticky, you still can move it with Alt+right clic ;
+ big issue is that the window can only be displayed on one desk, whereas conky can be displayed on all desks ;
+ the window still appears on windows list Alt+Tab
That's some details that can be meliorate, feel free if you a nice way to it :)
So, here is the code, writen in C :
/*
*
* acd.c
* -------
* Amarok Cover Display
* 21st July 2008 - Charlie Merland
* charlie.merland@gmail.com
* ----------------------------
*
* Utility: displays Amarok cover Image at argv[1] delay,
* at position given in argv[2] and argv[3].
*
* Use: ./acd 5 25 25
*
* Compilation: this program uses Xlib to display the window
* and Imlib2 to display the cover. You must have Imlib2 installed,
* and you need to add the flags to the compilation command:
*
* cc acd.c -lX11 -lImlib2 -o acd
*
*
* Feel free to use/modify/share this code, I made it in that intention =)
*
*
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <Imlib2.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#include "acd.h"
int main( int argc, char **argv )
{
int inter = atoi( argv[1] );
int pos_x = atoi( argv[2] );
int pos_y = atoi( argv[3] );
char cmd[30] = "dcop amarok player coverImage";
char cmd_status[26] = "dcop amarok player status";
char path[128];
char *fin;
/* put here the color of the "border" around the cover, depending on your
own wallpaper. Here I use grey, since my wallpaper is very dark */
unsigned long bg_color = 0x505050;
FILE *fd;
Atom xa, xa_prop;
/* checking Amarok status : if running and actually playing a song */
fd=popen(cmd_status,"r");
if(!fd)
{
fprintf(stderr,"Error popen\nQuitting.\n" );
return 1;
}
/* we get Amarok status using dcop */
if(!fgets(path,128,fd))
{
fprintf(stderr,"Error fgets\nQuitting.\n" );
return 1;
}
/* here I was testing if Amarok was actually running, but as a matter of facts,
if it's not, dcop request failed, making fgets fail too and stop */
/*if(strstr(path,"ERROR")!=NULL)
{
fprintf(stderr,"Error: Amarok is not running");
return 1;
}
else */if(strstr(path,"0")!=NULL)
{
printf("Amarok status is 0 : not playing\nQuitting.\n");
return 1;
}
// checking necessary arguments
if( argc < 3 )
{
printf(" Usage: ./acd intervalle x y");
printf(" Exemple: ./acd 10 580 480");
return 1;
}
/* define the display to use, the screen, etc, */
/* and get the root windows. Basic Xlib programming. */
Display *display = XOpenDisplay( NULL );
int screen = DefaultScreen( display );
Visual *visuel = DefaultVisual( display, screen );
Colormap colormap = DefaultColormap( display, screen );
Window fenetre_root = RootWindow( display, screen );
/* we set the attibutes, create the windows and make a grey background */
XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0,
Always, 0L, 0L, False, ExposureMask | OwnerGrabButtonMask, 0L, True, 0, 0 };
Window fenetre = XCreateWindow(display, fenetre_root, pos_x, pos_y, 154, 154, 0,
CopyFromParent, InputOutput, CopyFromParent, CWEventMask, &attrs);
XSetWindowBackground(display, fenetre, bg_color);
/* Imlib */
Imlib_Load_Error *error_return;
Imlib_Image cover;
imlib_context_set_display(display);
imlib_context_set_visual(visuel);
imlib_context_set_colormap(colormap);
imlib_context_set_drawable(fenetre);
/* window display */
XMapWindow( display, fenetre );
XSelectInput( display, fenetre, ExposureMask | OwnerGrabButtonMask );
/* kicking window's decorations */
xa = ATOM(_MOTIF_WM_HINTS);
long prop2[5] = { 2, 0, 0, 0, 0 };
XChangeProperty(display, fenetre, xa, xa, 32, PropModeReplace, (unsigned char *) prop2, 5);
/* move */
XMoveWindow(display, fenetre, pos_x, pos_y);
for(;;)
{
/* skipping taskbar */
xa = ATOM(_NET_WM_STATE);
xa_prop = ATOM(_NET_WM_STATE_SKIP_TASKBAR);
XChangeProperty(display, fenetre, xa, XA_ATOM, 32, PropModeAppend, (unsigned char *) &xa_prop, 1);
/* window above all others */
XLowerWindow(display, fenetre);
/* get cmd command result */
fd = popen(cmd,"r");
if(!fd)
{
fprintf(stderr,"Error popen\nQuitting.\n");
return 1;
}
if(!fgets(path,128,fd))
{
fprintf(stderr,"Error fgets\nQuitting.\n" );
return 1;
}
fin = strrchr(path, '\n');
if(fin != NULL) *fin = '\0';
/* load, resize and show the cover */
cover = imlib_load_image_with_error_return(path,error_retu rn);
if(!cover)
{
printf("Error %d loading image : %s\nQuitting.\n", *error_return, error[*error_return]);
return 1;
}
imlib_context_set_image(cover);
imlib_render_image_on_drawable_at_size(2,2,150,150 );
/*wait... */
usleep(inter*50000);
pclose(fd);
}
/* and destroy the window */
XDestroyWindow(display,fenetre);
return 0;
}
As mentioned in comments, this program uses Xlib and Imlib2, you must have it installed and adapt compilation command :
sudo apt-get install libimlib2 libimlib2-dev
cc acd.c -lX11 -lImlib2 -o acd
Well, that's it, hope it will be useful to someone =)
PS: so sorry for my (very) poor english skills :oops:
http://img371.imageshack.us/img371/5118/capture32ph2.th.jpg (http://img371.imageshack.us/my.php?image=capture32ph2.jpg)
Yep, it's done! Since conky doesn't provide image support, I decided to write a little program that would help me getting my Amarok cover on my desk as well as other informations like artist or title :) It's actually pretty simple ; I based my work on some pieces of conky's sources, to display the cover image on a small window, at a position we specify, as for the refresh delay.
There's still a few points to be improved :
+ I failed to make the window sticky, you still can move it with Alt+right clic ;
+ big issue is that the window can only be displayed on one desk, whereas conky can be displayed on all desks ;
+ the window still appears on windows list Alt+Tab
That's some details that can be meliorate, feel free if you a nice way to it :)
So, here is the code, writen in C :
/*
*
* acd.c
* -------
* Amarok Cover Display
* 21st July 2008 - Charlie Merland
* charlie.merland@gmail.com
* ----------------------------
*
* Utility: displays Amarok cover Image at argv[1] delay,
* at position given in argv[2] and argv[3].
*
* Use: ./acd 5 25 25
*
* Compilation: this program uses Xlib to display the window
* and Imlib2 to display the cover. You must have Imlib2 installed,
* and you need to add the flags to the compilation command:
*
* cc acd.c -lX11 -lImlib2 -o acd
*
*
* Feel free to use/modify/share this code, I made it in that intention =)
*
*
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <Imlib2.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#include "acd.h"
int main( int argc, char **argv )
{
int inter = atoi( argv[1] );
int pos_x = atoi( argv[2] );
int pos_y = atoi( argv[3] );
char cmd[30] = "dcop amarok player coverImage";
char cmd_status[26] = "dcop amarok player status";
char path[128];
char *fin;
/* put here the color of the "border" around the cover, depending on your
own wallpaper. Here I use grey, since my wallpaper is very dark */
unsigned long bg_color = 0x505050;
FILE *fd;
Atom xa, xa_prop;
/* checking Amarok status : if running and actually playing a song */
fd=popen(cmd_status,"r");
if(!fd)
{
fprintf(stderr,"Error popen\nQuitting.\n" );
return 1;
}
/* we get Amarok status using dcop */
if(!fgets(path,128,fd))
{
fprintf(stderr,"Error fgets\nQuitting.\n" );
return 1;
}
/* here I was testing if Amarok was actually running, but as a matter of facts,
if it's not, dcop request failed, making fgets fail too and stop */
/*if(strstr(path,"ERROR")!=NULL)
{
fprintf(stderr,"Error: Amarok is not running");
return 1;
}
else */if(strstr(path,"0")!=NULL)
{
printf("Amarok status is 0 : not playing\nQuitting.\n");
return 1;
}
// checking necessary arguments
if( argc < 3 )
{
printf(" Usage: ./acd intervalle x y");
printf(" Exemple: ./acd 10 580 480");
return 1;
}
/* define the display to use, the screen, etc, */
/* and get the root windows. Basic Xlib programming. */
Display *display = XOpenDisplay( NULL );
int screen = DefaultScreen( display );
Visual *visuel = DefaultVisual( display, screen );
Colormap colormap = DefaultColormap( display, screen );
Window fenetre_root = RootWindow( display, screen );
/* we set the attibutes, create the windows and make a grey background */
XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0,
Always, 0L, 0L, False, ExposureMask | OwnerGrabButtonMask, 0L, True, 0, 0 };
Window fenetre = XCreateWindow(display, fenetre_root, pos_x, pos_y, 154, 154, 0,
CopyFromParent, InputOutput, CopyFromParent, CWEventMask, &attrs);
XSetWindowBackground(display, fenetre, bg_color);
/* Imlib */
Imlib_Load_Error *error_return;
Imlib_Image cover;
imlib_context_set_display(display);
imlib_context_set_visual(visuel);
imlib_context_set_colormap(colormap);
imlib_context_set_drawable(fenetre);
/* window display */
XMapWindow( display, fenetre );
XSelectInput( display, fenetre, ExposureMask | OwnerGrabButtonMask );
/* kicking window's decorations */
xa = ATOM(_MOTIF_WM_HINTS);
long prop2[5] = { 2, 0, 0, 0, 0 };
XChangeProperty(display, fenetre, xa, xa, 32, PropModeReplace, (unsigned char *) prop2, 5);
/* move */
XMoveWindow(display, fenetre, pos_x, pos_y);
for(;;)
{
/* skipping taskbar */
xa = ATOM(_NET_WM_STATE);
xa_prop = ATOM(_NET_WM_STATE_SKIP_TASKBAR);
XChangeProperty(display, fenetre, xa, XA_ATOM, 32, PropModeAppend, (unsigned char *) &xa_prop, 1);
/* window above all others */
XLowerWindow(display, fenetre);
/* get cmd command result */
fd = popen(cmd,"r");
if(!fd)
{
fprintf(stderr,"Error popen\nQuitting.\n");
return 1;
}
if(!fgets(path,128,fd))
{
fprintf(stderr,"Error fgets\nQuitting.\n" );
return 1;
}
fin = strrchr(path, '\n');
if(fin != NULL) *fin = '\0';
/* load, resize and show the cover */
cover = imlib_load_image_with_error_return(path,error_retu rn);
if(!cover)
{
printf("Error %d loading image : %s\nQuitting.\n", *error_return, error[*error_return]);
return 1;
}
imlib_context_set_image(cover);
imlib_render_image_on_drawable_at_size(2,2,150,150 );
/*wait... */
usleep(inter*50000);
pclose(fd);
}
/* and destroy the window */
XDestroyWindow(display,fenetre);
return 0;
}
As mentioned in comments, this program uses Xlib and Imlib2, you must have it installed and adapt compilation command :
sudo apt-get install libimlib2 libimlib2-dev
cc acd.c -lX11 -lImlib2 -o acd
Well, that's it, hope it will be useful to someone =)
PS: so sorry for my (very) poor english skills :oops: