Mercurial > audlegacy
view Plugins/General/lirc/lirc.c @ 554:8a7a6dda6add trunk
[svn] make lirc strings translatable
author | nenolod |
---|---|
date | Wed, 01 Feb 2006 13:09:25 -0800 |
parents | 894e9c4a0051 |
children | 3770123787c2 |
line wrap: on
line source
/* Lirc plugin Copyright (C) 2005 Audacious development team Copyright (c) 1998-1999 Carl van Schaik (carl@leg.uct.ac.za) Copyright (C) 2000 Christoph Bartelmus (xmms@bartelmus.de) some code was stolen from: IRman plugin for xmms by Charles Sielski (stray@teklabs.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <signal.h> #include <stdlib.h> #include <ctype.h> #include <gtk/gtk.h> #include <glib.h> #include <glib/gi18n.h> #include "audacious/plugin.h" #include "libaudacious/configdb.h" #include "libaudacious/beepctrl.h" #include <lirc/lirc_client.h> #include "lirc.h" const char *plugin_name="LIRC Plugin " VERSION; GeneralPlugin lirc_plugin = { NULL, NULL, -1, NULL, init, about, configure, cleanup, }; GeneralPlugin *get_gplugin_info(void) { lirc_plugin.description = g_strdup_printf(_("LIRC Plugin")); return(&lirc_plugin); } int lirc_fd=-1; struct lirc_config *config=NULL; gint tracknr=0; gint mute=0; /* mute flag */ gint mute_vol=0; /* holds volume before mute */ gint input_tag; int select_tag=0; GtkWidget *select_popup=NULL; GtkStyle *popup_style=NULL; GList *select_list=NULL; GtkWidget *fsd; gchar *fontname; struct select_info { char *s; size_t common; }; struct title_info { char *s; int pos; }; void clear_select_list(GList **list) { GList *l; l=*list; while(l!=NULL) { free(((struct select_info *) (l->data))->s); free(l->data); l=g_list_remove_link(l,l); } *list=NULL; } void clear_title_list(GList **list) { GList *l; l=*list; while(l!=NULL) { free(((struct title_info *) (l->data))->s); free(l->data); l=g_list_remove_link(l,l); } *list=NULL; } gchar *get_title_postfix(gchar *title) { gchar *match; GList *scan_list; struct select_info *si; size_t skip; match=title; scan_list=select_list; si=(struct select_info *) (scan_list->data); while(*match) { if(!isalnum(*match)) { match++; } else { if(strchr(si->s,toupper(*match))!=NULL) { skip=si->common; while(skip>0) { if(isalnum(*match)) { skip--; } match++; if(!*match) { break; } } scan_list=g_list_next(scan_list); if(scan_list==NULL) { while(!isalnum(*match) && *match) { match++; } return(match); } si=(struct select_info *) (scan_list->data); } else { break; } } } return(NULL); } #define SELECT_BORDER 8 gint remove_select_popup(GtkWidget **select_popup) { gtk_widget_destroy(*select_popup); *select_popup=NULL; select_tag=0; return(FALSE); } /*void select_title(char *s,int num) { GdkFont *font; GtkStyle *style; int gap,baseline_skip; int width,height,x,y; GList *new_list,*scan_list; GList *title_list=NULL; int length,i; gchar *title; struct select_info *si; struct title_info *ti; if(select_tag!=0) { gtk_timeout_remove(select_tag); remove_select_popup(&select_popup); } if(s!=NULL) { si=malloc(sizeof(*si)); if(si==NULL) { return; } si->s=strdup(s); si->common=1; if(si->s==NULL) { free(si); return; } new_list=g_list_append(select_list,si); if(new_list==NULL) { free(si->s); free(si); return; } select_list=new_list; } scan_list=select_list; while(scan_list) { scan_list=g_list_next(scan_list); } length=xmms_remote_get_playlist_length (lirc_plugin.xmms_session); for(i=0;i<length;i++) { title=xmms_remote_get_playlist_title (lirc_plugin.xmms_session,i); if(get_title_postfix(title)!=NULL) { ti=malloc(sizeof(*ti)); if(ti==NULL) break; ti->s=strdup(title); if(ti->s==NULL) { free(ti); break; } ti->pos=i; new_list=g_list_append(title_list,ti); if(new_list==NULL) { free(ti->s); free(ti); break; } title_list=new_list; } } select_popup=gtk_window_new(GTK_WINDOW_POPUP); if(popup_style) { if(fontname!=NULL) { font=gdk_font_load(fontname); } else { font=gdk_font_load ("-xxl-*-medium-r-semicondensed-*-*-*-75-75-*-*-*-*"); } if(font) popup_style->font=font; gtk_widget_set_style(select_popup,popup_style); } gtk_widget_set_app_paintable(select_popup,TRUE); gtk_window_set_policy(GTK_WINDOW(select_popup),FALSE,FALSE,TRUE); gtk_widget_set_name(select_popup,"LIRC select list"); style=select_popup->style; font=style->font; gap=(font->ascent+font->descent)/4; if(gap<2) gap=2; baseline_skip=font->ascent+font->descent+gap; if(title_list==NULL) { gchar *text="No match."; x=gdk_string_width(font,text); width=SELECT_BORDER*2+x; height=SELECT_BORDER*2+baseline_skip-gap; gtk_widget_set_usize(select_popup,width,height); x=(gdk_screen_width()-width)/2; if(x<0) x=0; y=(gdk_screen_height()-height)/2; if(y<0) y=0; gtk_widget_popup(select_popup,x,y); gtk_paint_box(select_popup->style,select_popup->window, GTK_STATE_NORMAL,GTK_SHADOW_OUT, NULL,GTK_WIDGET(select_popup), "LIRC select list",0,0,-1,-1); gtk_paint_string(style,select_popup->window, GTK_STATE_NORMAL,NULL, GTK_WIDGET(select_popup), "LIRC select item", SELECT_BORDER, SELECT_BORDER+font->ascent, "No match."); clear_select_list(&select_list); } else { int count; int common; int pass; int x1,x2,x3; if(s==NULL && num>0) { scan_list=title_list; while(scan_list!=NULL) { num--; if(num==0) { clear_select_list(&select_list); xmms_remote_set_playlist_pos (lirc_plugin.xmms_session, ((struct title_info *) (scan_list->data))->pos); break; } scan_list=g_list_next(scan_list); } clear_title_list(&title_list); return; } check how many chars are common scan_list=title_list; title=get_title_postfix (((struct title_info *) scan_list->data)->s); common=0; count=strlen(title); for(i=0;i<count;i++) { if(isalnum(title[i])) common++; } scan_list=g_list_next(scan_list); while(scan_list!=NULL) { gchar *title1,*title2; count=0; title1=title; title2=get_title_postfix (((struct title_info *) scan_list->data)->s); while(*title1 && *title2) { if(!isalnum(*title1)) {title1++;continue;} if(!isalnum(*title2)) {title2++;continue;} if(toupper(*title1)==toupper(*title2)) { count++; title1++; title2++; } else { break; } } if(count<common) common=count; scan_list=g_list_next(scan_list); } scan_list=select_list; while(g_list_next(scan_list)!=NULL) { scan_list=g_list_next(scan_list); } ((struct select_info *) (scan_list->data))->common=common+1; print out selected titles x1=x2=x3=0; count=0; pass=1; scan_list=title_list; while(scan_list!=NULL || pass==1) { gchar *title,*postfix,help; char buffer[20]; count++; title=((struct title_info *) scan_list->data)->s; postfix=get_title_postfix(title); help=postfix[0]; postfix[0]=0; snprintf(buffer,20,"%2d:",count); if(pass==1) { x=gdk_string_width (select_popup->style->font,buffer); if(x>x1) x1=x; x2=gdk_string_width (select_popup->style->font,title); postfix[0]=help; x=gdk_string_width(select_popup->style->font, postfix); if(x>x3) x3=x; } else { gtk_paint_string(style,select_popup->window, GTK_STATE_NORMAL,NULL, GTK_WIDGET(select_popup), "LIRC select item", SELECT_BORDER, SELECT_BORDER+font->ascent+ (count-1)*baseline_skip, buffer); gtk_paint_string(style,select_popup->window, GTK_STATE_NORMAL,NULL, GTK_WIDGET(select_popup), "LIRC select item", SELECT_BORDER+x1, SELECT_BORDER+font->ascent+ (count-1)*baseline_skip, title); postfix[0]=help; gtk_paint_string(style,select_popup->window, GTK_STATE_NORMAL,NULL, GTK_WIDGET(select_popup), "LIRC select item", SELECT_BORDER+x1+x2+10, SELECT_BORDER+font->ascent+ (count-1)*baseline_skip, postfix); } scan_list=g_list_next(scan_list); if(scan_list==NULL) { if(pass==1) { int x,y; width=SELECT_BORDER*2+x1+x2+10+x3; height=SELECT_BORDER*2+count*baseline_skip-gap; gtk_widget_set_usize(select_popup, width, height); x=(gdk_screen_width()-width)/2; if(x<0) x=0; y=(gdk_screen_height()-height)/2; if(y<0) y=0; gtk_widget_popup(select_popup,x,y); gtk_paint_box(style,select_popup->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL,GTK_WIDGET(select_popup), "LIRC select list", 0,0,-1,-1); scan_list=title_list; count=0; } pass++; } } if(count==1) { clear_select_list(&select_list); xmms_remote_set_playlist_pos (lirc_plugin.xmms_session, ((struct title_info *) title_list->data) ->pos); } clear_title_list(&title_list); } select_tag=gtk_timeout_add(3000,(GtkFunction) remove_select_popup, (gpointer) &select_popup); } */ void init(void) { int flags; ConfigDb *db; if((lirc_fd=lirc_init("audacious",1))==-1) { fprintf(stderr,_("%s: could not init LIRC support\n"), plugin_name); return; } if(lirc_readconfig(NULL,&config,NULL)==-1) { lirc_deinit(); fprintf(stderr, _("%s: could not read LIRC config file\n" "%s: please read the documentation of LIRC\n" "%s: how to create a proper config file\n"), plugin_name,plugin_name,plugin_name); return; } input_tag=gdk_input_add(lirc_fd,GDK_INPUT_READ, lirc_input_callback,NULL); fcntl(lirc_fd,F_SETOWN,getpid()); flags=fcntl(lirc_fd,F_GETFL,0); if(flags!=-1) { fcntl(lirc_fd,F_SETFL,flags|O_NONBLOCK); } fflush(stdout); db = bmp_cfg_db_open(); bmp_cfg_db_get_string(db,"LIRC","font",&fontname); bmp_cfg_db_close(db); popup_style=gtk_style_new(); } void lirc_input_callback(gpointer data,gint source, GdkInputCondition condition) { char *code; char *c; gint playlist_time,playlist_pos,output_time,v; int ret; char *ptr; gint balance; gboolean show_pl; int n; while((ret=lirc_nextcode(&code))==0 && code!=NULL) { while((ret=lirc_code2char(config,code,&c))==0 && c!=NULL) { if(strcasecmp("PLAY",c)==0) { xmms_remote_play(lirc_plugin.xmms_session); } else if(strcasecmp("STOP",c)==0) { xmms_remote_stop(lirc_plugin.xmms_session); } else if(strcasecmp("PAUSE",c)==0) { xmms_remote_pause(lirc_plugin.xmms_session); } else if(strcasecmp("PLAYPAUSE",c) == 0) { if(xmms_remote_is_playing(lirc_plugin. xmms_session)) xmms_remote_pause (lirc_plugin.xmms_session); else xmms_remote_play (lirc_plugin.xmms_session); } else if(strncasecmp("NEXT",c,4)==0) { ptr=c+4; while(isspace(*ptr)) ptr++; n=atoi(ptr); if(n<=0) n=1; for(;n>0;n--) { xmms_remote_playlist_next (lirc_plugin.xmms_session); } } else if(strncasecmp("PREV",c,4)==0) { ptr=c+4; while(isspace(*ptr)) ptr++; n=atoi(ptr); if(n<=0) n=1; for(;n>0;n--) { xmms_remote_playlist_prev (lirc_plugin.xmms_session); } } else if(strcasecmp("SHUFFLE",c)==0) { xmms_remote_toggle_shuffle(lirc_plugin.xmms_session); } else if(strcasecmp("REPEAT",c)==0) { xmms_remote_toggle_repeat(lirc_plugin.xmms_session); } else if(strncasecmp("FWD",c,3)==0) { ptr=c+3; while(isspace(*ptr)) ptr++; n=atoi(ptr)*1000; if(n<=0) n=5000; output_time=xmms_remote_get_output_time (lirc_plugin.xmms_session); playlist_pos=xmms_remote_get_playlist_pos (lirc_plugin.xmms_session); playlist_time=xmms_remote_get_playlist_time (lirc_plugin.xmms_session, playlist_pos); if(playlist_time-output_time<n) output_time=playlist_time-n; xmms_remote_jump_to_time (lirc_plugin.xmms_session, output_time+n); } else if(strncasecmp("BWD",c,3)==0) { ptr=c+3; while(isspace(*ptr)) ptr++; n=atoi(ptr)*1000; if(n<=0) n=5000; output_time=xmms_remote_get_output_time (lirc_plugin.xmms_session); if(output_time<n) output_time=n; xmms_remote_jump_to_time (lirc_plugin.xmms_session, output_time-n); } else if(strncasecmp("VOL_UP",c,6)==0) { ptr=c+6; while(isspace(*ptr)) ptr++; n=atoi(ptr); if(n<=0) n=5; v = xmms_remote_get_main_volume (lirc_plugin.xmms_session); if(v > (100-n)) v=100-n; xmms_remote_set_main_volume (lirc_plugin.xmms_session,v+n); } else if(strncasecmp("VOL_DOWN",c,8)==0) { ptr=c+8; while (isspace(*ptr)) ptr++; n=atoi(ptr); if(n<=0) n=5; v = xmms_remote_get_main_volume (lirc_plugin.xmms_session); if(v<n) v=n; xmms_remote_set_main_volume (lirc_plugin.xmms_session,v-n); } else if(strcasecmp("QUIT",c)==0) { #ifdef HAVE_XMMS_REMOTE_QUIT xmms_remote_quit(lirc_plugin.xmms_session); #else raise(SIGTERM); #endif } else if(strcasecmp("SETPOS",c)==0) { xmms_remote_set_playlist_pos(lirc_plugin.xmms_session,tracknr-1); xmms_remote_play(lirc_plugin.xmms_session); tracknr=0; } else if(strcasecmp("ONE",c)==0) { if(select_list!=NULL) { /* select_title(NULL,1); */ } else { tracknr=tracknr*10+1; } } else if(strcasecmp("TWO",c)==0) { if(select_list!=NULL) { /* select_title(NULL,2); */ } else { tracknr=tracknr*10+2; } } else if(strcasecmp("THREE",c)==0) { if(select_list!=NULL) { /* select_title(NULL,3);*/ } else { tracknr=tracknr*10+3; } } else if(strcasecmp("FOUR",c)==0) { if(select_list!=NULL) { /* select_title(NULL,4);*/ } else { tracknr=tracknr*10+4; } } else if(strcasecmp("FIVE",c)==0) { if(select_list!=NULL) { /*select_title(NULL,5);*/ } else { tracknr=tracknr*10+5; } } else if(strcasecmp("SIX",c)==0) { if(select_list!=NULL) { /*select_title(NULL,6);*/ } else { tracknr=tracknr*10+6; } } else if(strcasecmp("SEVEN",c)==0) { if(select_list!=NULL) { /*select_title(NULL,7);*/ } else { tracknr=tracknr*10+7; } } else if(strcasecmp("EIGHT",c)==0) { if(select_list!=NULL) { /*select_title(NULL,8);*/ } else { tracknr=tracknr*10+8; } } else if(strcasecmp("NINE",c)==0) { if(select_list!=NULL) { /*select_title(NULL,9);*/ } else { tracknr=tracknr*10+9; } } else if(strcasecmp("ZERO",c)==0) { if(select_list!=NULL) { /*select_title(NULL,10);*/ } else { tracknr=tracknr*10; } } else if(strcasecmp("MUTE",c)==0) { if(mute==0) { mute=1; /* store the master volume so we can restore it on unmute. */ mute_vol = xmms_remote_get_main_volume (lirc_plugin.xmms_session); xmms_remote_set_main_volume (lirc_plugin.xmms_session, 0); } else { mute=0; xmms_remote_set_main_volume (lirc_plugin.xmms_session, mute_vol); } } else if(strncasecmp("BAL_LEFT",c,8)==0) { ptr=c+8; while(isspace(*ptr)) ptr++; n=atoi(ptr); if(n<=0) n=5; balance=xmms_remote_get_balance (lirc_plugin.xmms_session); balance-=n; if(balance<-100) balance=-100; xmms_remote_set_balance (lirc_plugin.xmms_session,balance); } else if(strncasecmp("BAL_RIGHT",c,9)==0) { ptr=c+9; while(isspace(*ptr)) ptr++; n=atoi(ptr); if(n<=0) n=5; balance=xmms_remote_get_balance (lirc_plugin.xmms_session); balance+=n; if(balance>100) balance=100; xmms_remote_set_balance (lirc_plugin.xmms_session,balance); } else if(strcasecmp("BAL_CENTER",c)==0) { balance=0; xmms_remote_set_balance (lirc_plugin.xmms_session,balance); } else if(strcasecmp("LIST",c)==0) { show_pl=xmms_remote_is_pl_win (lirc_plugin.xmms_session); show_pl=(show_pl) ? 0:1; xmms_remote_pl_win_toggle (lirc_plugin.xmms_session,show_pl); } else if(strcasecmp("PLAYLIST_CLEAR",c)==0) { gboolean pl_visible; pl_visible=xmms_remote_is_pl_win (lirc_plugin.xmms_session); xmms_remote_stop(lirc_plugin.xmms_session); xmms_remote_playlist_clear (lirc_plugin.xmms_session); /* This is to refresh window content */ xmms_remote_pl_win_toggle (lirc_plugin.xmms_session,pl_visible); } else if(strncasecmp("PLAYLIST_ADD ",c,13)==0) { gboolean pl_visible; GList list; pl_visible=xmms_remote_is_pl_win (lirc_plugin.xmms_session); list.prev=list.next=NULL; list.data=c+13; xmms_remote_playlist_add (lirc_plugin.xmms_session,&list); /* This is to refresh window content */ xmms_remote_pl_win_toggle (lirc_plugin.xmms_session,pl_visible); } else if(strncasecmp("SELECT",c,6)==0) { char *sel; int i; ptr=c+6; while(isspace(*ptr)) ptr++; sel=ptr; for(i=0;*ptr;ptr++) { if(isalnum(*ptr)) { sel[i]=toupper(*ptr); i++; } } sel[i]=0; if(strlen(sel)>0) { /*select_title(sel,0);*/ } } else { fprintf(stderr,_("%s: unknown command \"%s\"\n"), plugin_name,c); } } free(code); if(ret==-1) break; } if(ret==-1) { /* something went badly wrong */ fprintf(stderr,_("%s: disconnected from LIRC\n"),plugin_name); cleanup(); return; } } void configure(void) { if(!fsd) { GtkWidget *window; window=gtk_font_selection_dialog_new (_("Please choose font for SELECT popup.")); g_return_if_fail(GTK_IS_FONT_SELECTION_DIALOG(window)); fsd=window; gtk_window_position(GTK_WINDOW(fsd),GTK_WIN_POS_MOUSE); gtk_signal_connect(GTK_OBJECT(fsd), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &fsd); gtk_signal_connect(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG (fsd)->ok_button), "clicked", GTK_SIGNAL_FUNC(font_selection_ok), NULL); gtk_signal_connect_object(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fsd)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(fsd)); } if(!GTK_WIDGET_VISIBLE(fsd)) gtk_widget_show(fsd); else gtk_widget_destroy(fsd); } void font_selection_ok(GtkWidget *button,gpointer *data) { gchar *new_fontname; new_fontname=gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG(fsd)); if(new_fontname) { if(fontname) free(fontname); fontname=new_fontname; } gtk_widget_destroy(fsd); fsd=NULL; } void cleanup() { ConfigDb *db; if(config) { gtk_input_remove(input_tag); lirc_freeconfig(config); config=NULL; } if(lirc_fd!=-1) { lirc_deinit(); lirc_fd=-1; } clear_select_list(&select_list); if(fontname) { db = bmp_cfg_db_open(); bmp_cfg_db_set_string(db,"LIRC","font",fontname); bmp_cfg_db_close(db); free(fontname); } }