/* A modified port initialization - seems to work everytime */ void irapp_init_port(gchar * ir_port) { gint i; for (i = 0; i < 2; i++) { if (ir_open_port(ir_port) < 0) fprintf(stderr, _("unable to open port `%s' (%s)\n"), ir_port, strerror(errno)); else { ir_write_char('I'); ir_usleep(IR_HANDSHAKE_GAP); ir_write_char('R'); ir_set_enabled(1); ir_clear_buffer(); /* Take the 'OK' */ } } }
static int ir_init (char *filename) { int rdchar; if (ir_enabled) { errno = EBUSY; /* we already have a high level ir setup */ return -1; } if (ir_open_port(filename) < 0) { return -1; } ir_clear_buffer(); if (ir_write_char('I') < 0) { return -1; } ir_usleep(IR_HANDSHAKE_GAP); if (ir_write_char('R') < 0) { return -1; } /* we'll be nice and give the box a good chance to send an 'O' */ while ((rdchar = ir_read_char(IR_HANDSHAKE_TIMEOUT)) != 'O') { if (rdchar < 0) { /* error or timeout */ return -1; } } /* as regards the 'K', however, that really must be the next character */ rdchar = ir_read_char(IR_HANDSHAKE_TIMEOUT); if (rdchar < 0) { return -1; } /* ENOEXEC is the closest error I could find, that would also not be * generated by ir_read_char(). Anyway, ENOEXEC does more or less mean * "I don't understand this data I've been given" */ if (rdchar != 'K') { errno = ENOEXEC; return -1; } /* we are now ready to roll */ ir_enabled = 1; return 0; }
/* * A future avenue might be to set the settings to 0 and work from there. * Also check for other names for the serial port as in IRIX -- maybe * Solaris does that (I tried ttya) */ static int ir_open_port (char *filename) { int parnum = 0; int baudrate = B9600; /* get a file descriptor */ if ((portfd = open(filename, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) { return -1; } /* check to see that the file is a terminal */ if (!isatty(portfd)) { return -1; } /* get port attributes, store in oldterm */ if (tcgetattr(portfd, &oldterm) < 0) { return -1; } /* get port flags, save in oldflags */ if ((oldflags = fcntl(portfd, F_GETFL)) < 0) { return -1; } /* now we have read the old attributes for the port, we can restore them * upon exit. if we had done this bfore, and exited beore reading in the * old attributes, we would have overwritten the old settings with zeros. * * this way, if we do exit before we get here, we simply rely on the OS closing * the port for us, which is fine as we haven't changed anything yet. */ /* copy old attrs into new structure */ portterm = oldterm; portflags = oldflags; /* remove old parity setting, size and stop setting */ portterm.c_cflag &= ~PARENB; portterm.c_cflag &= ~PARODD; portterm.c_cflag &= ~CSTOPB; portterm.c_cflag &= ~CSIZE; /* set character size, stop bits and parity */ portterm.c_cflag |= CS8; portterm.c_cflag |= parnum; /* enable receiver, and don't change ownership */ portterm.c_cflag |= CREAD | CLOCAL; /* disable flow control */ #ifdef CNEW_RTSCTS portterm.c_cflag &= ~CNEW_RTSCTS; #else #ifdef CRTSCTS portterm.c_cflag &= ~CRTSCTS; #endif #ifdef CRTSXOFF portterm.c_cflag &= ~CRTSXOFF; #endif #endif /* read characters immediately in non-canonical mode */ /* Thanks to Bill Ryder, <*****@*****.**> */ portterm.c_cc[VMIN] = 1; portterm.c_cc[VTIME] = 1; /* set the input and output baud rate */ cfsetispeed(&portterm, baudrate); cfsetospeed(&portterm, baudrate); /* set non-canonical mode (we don't want any fancy terminal processing!) */ portterm.c_lflag = 0; /* Ignore breaks and make terminal raw and dumb. */ portterm.c_iflag = 0; portterm.c_iflag |= IGNBRK; portterm.c_oflag &= ~OPOST; /* set the input and output baud rate */ cfsetispeed(&portterm, baudrate); cfsetospeed(&portterm, baudrate); /* now clean the serial line and activate the new settings */ tcflush(portfd, TCIOFLUSH); if (tcsetattr(portfd, TCSANOW, &portterm) < 0) { return -1; } /* set non-blocking */ if (fcntl(portfd, F_SETFL, (portflags |= O_NONBLOCK)) < 0) { return -1; } /* wait a little while for everything to settle through */ ir_usleep(IR_POWER_ON_LATENCY); /* it has been suggested that ir_open_port() returns the portfd, however * this would mean breaking the current convention where returning 0 means * success. Also it might encourage people to play with the fd, with is * probably a bad idea unless you know what you are doing. * however for people who _do_ know what they are doing -- * use ir_get_portfd() * Thanks to mumble, <*****@*****.**> for the suggestion. (sorry I forgot * your name/address -- email me and I'll put it in!) */ return 0; }
/* Our main thread */ static void *xmms_irapp_routine(void *arg) { unsigned char *code; char *text; gint playlist_time, playlist_pos, output_time, vl, vr, i; gint ir_numpress = -1; gint ir_hundreds = 0; gboolean ir_playlist_mode = FALSE; GList *ir_playlist; GTimer *timer1, *timer2; #define S_PAUSE 0.2 #define L_PAUSE 0.4 #define PL_PAUSE 2.0 timer1 = g_timer_new(); timer2 = g_timer_new(); g_timer_start(timer1); while (keepGoing) { if (!irconf_is_going) { code = ir_poll_code(); if (code) { text = ir_code_to_text(code); if (!strcmp(text, ircfg.button_play) && g_timer_elapsed(timer1, NULL) > L_PAUSE) { xmms_remote_play(ir_gp.xmms_session); g_timer_reset(timer1); g_timer_reset(timer2); g_timer_stop(timer2); ir_hundreds = 0; } else if (!strcmp(text, ircfg.button_stop) && g_timer_elapsed(timer1, NULL) > L_PAUSE) { xmms_remote_stop(ir_gp.xmms_session); g_timer_reset(timer1); g_timer_reset(timer2); g_timer_stop(timer2); ir_hundreds = 0; } else if (!strcmp(text, ircfg.button_pause) && g_timer_elapsed(timer1, NULL) > L_PAUSE) { xmms_remote_pause(ir_gp.xmms_session); g_timer_reset(timer1); g_timer_reset(timer2); g_timer_stop(timer2); ir_hundreds = 0; } else if (!strcmp(text, ircfg.button_shuffle) && g_timer_elapsed(timer1, NULL) > L_PAUSE) { xmms_remote_toggle_shuffle(ir_gp.xmms_session); g_timer_reset(timer1); g_timer_reset(timer2); g_timer_stop(timer2); ir_hundreds = 0; } else if (!strcmp(text, ircfg.button_repeat) && g_timer_elapsed(timer1, NULL) > L_PAUSE) { xmms_remote_toggle_repeat(ir_gp.xmms_session); g_timer_reset(timer1); g_timer_reset(timer2); g_timer_stop(timer2); ir_hundreds = 0; } else if (!strcmp(text, ircfg.button_playlist) && g_timer_elapsed(timer1, NULL) > L_PAUSE) { ir_playlist_mode = !ir_playlist_mode; g_timer_reset(timer1); g_timer_reset(timer2); g_timer_stop(timer2); ir_hundreds = 0; } else if (!strcmp(text, ircfg.button_next) && g_timer_elapsed(timer1, NULL) > L_PAUSE) { xmms_remote_playlist_next(ir_gp.xmms_session); g_timer_reset(timer1); g_timer_reset(timer2); g_timer_stop(timer2); ir_hundreds = 0; } else if (!strcmp(text, ircfg.button_prev) && g_timer_elapsed(timer1, NULL) > L_PAUSE) { xmms_remote_playlist_prev(ir_gp.xmms_session); g_timer_reset(timer1); g_timer_reset(timer2); g_timer_stop(timer2); ir_hundreds = 0; } else if (!strcmp(text, ircfg.button_seekf) && g_timer_elapsed(timer1, NULL) > S_PAUSE / 2) { output_time = xmms_remote_get_output_time(ir_gp.xmms_session); playlist_pos = xmms_remote_get_playlist_pos(ir_gp.xmms_session); playlist_time = xmms_remote_get_playlist_time(ir_gp.xmms_session, playlist_pos); if (playlist_time - output_time < 5000) output_time = playlist_time - 5000; xmms_remote_jump_to_time(ir_gp.xmms_session, output_time + 5000); g_timer_reset(timer1); g_timer_reset(timer2); g_timer_stop(timer2); ir_hundreds = 0; } else if (!strcmp(text, ircfg.button_seekb) && g_timer_elapsed(timer1, NULL) > S_PAUSE / 2) { output_time = xmms_remote_get_output_time(ir_gp.xmms_session); if (output_time < 5000) output_time = 5000; xmms_remote_jump_to_time(ir_gp.xmms_session, output_time - 5000); g_timer_reset(timer1); g_timer_reset(timer2); g_timer_stop(timer2); ir_hundreds = 0; } else if (!strcmp(text, ircfg.button_volup) && g_timer_elapsed(timer1, NULL) > S_PAUSE) { xmms_remote_get_volume(ir_gp.xmms_session, &vl, &vr); if (vl > 95) vl = 95; if (vr > 95) vr = 95; xmms_remote_set_volume(ir_gp.xmms_session, vl + 5, vr + 5); g_timer_reset(timer1); } else if (!strcmp(text, ircfg.button_voldown) && g_timer_elapsed(timer1, NULL) > S_PAUSE) { xmms_remote_get_volume(ir_gp.xmms_session, &vl, &vr); if (vl < 5) vl = 5; if (vr < 5) vr = 5; xmms_remote_set_volume(ir_gp.xmms_session, vl - 5, vr - 5); g_timer_reset(timer1); } else if (!strcmp(text, ircfg.button_plus100) && g_timer_elapsed(timer1, NULL) > S_PAUSE) { ir_hundreds += 1; g_timer_reset(timer1); g_timer_reset(timer2); g_timer_start(timer2); } else { for (i = 0; i < 10; i++) { if (!strcmp(text, ircfg.button[i]) && g_timer_elapsed(timer1, NULL) > S_PAUSE) { g_timer_reset(timer2); if (ir_numpress >= 0) { g_timer_stop(timer2); if (ir_playlist_mode) { if (strcmp(ircfg.playlist[(10 * ir_numpress) + i], "")) { ir_playlist = NULL; ir_playlist = g_list_append(ir_playlist, ircfg.playlist[(10 * ir_numpress) + i]); xmms_remote_play_files(ir_gp.xmms_session, ir_playlist); g_list_free(ir_playlist); } ir_playlist_mode = FALSE; } else { ir_numpress = (100 * ir_hundreds) + (10 * ir_numpress) + i; if (ir_numpress == 0) xmms_remote_set_playlist_pos(ir_gp.xmms_session, xmms_remote_get_playlist_length(ir_gp.xmms_session) - 1); else xmms_remote_set_playlist_pos(ir_gp.xmms_session, ir_numpress - 1); } ir_numpress = -1; ir_hundreds = 0; } else { g_timer_start(timer2); ir_numpress = i; } g_timer_reset(timer1); } } } } if (g_timer_elapsed(timer2, NULL) > PL_PAUSE) { if (ir_numpress >= 0 || ir_hundreds > 0) { if (ir_playlist_mode) { if (strcmp(ircfg.playlist[ir_numpress], "")) { ir_playlist = NULL; ir_playlist = g_list_append(ir_playlist, ircfg.playlist[ir_numpress]); xmms_remote_play_files(ir_gp.xmms_session, ir_playlist); g_list_free(ir_playlist); } } else if (ir_numpress <= 0) if (ir_hundreds > 0) xmms_remote_set_playlist_pos(ir_gp.xmms_session, (100 * ir_hundreds) - 1); else xmms_remote_set_playlist_pos(ir_gp.xmms_session, xmms_remote_get_playlist_length(ir_gp.xmms_session) - 1); else xmms_remote_set_playlist_pos(ir_gp.xmms_session, (100 * ir_hundreds) + ir_numpress - 1); } ir_numpress = -1; ir_hundreds = 0; ir_playlist_mode = FALSE; g_timer_reset(timer2); g_timer_stop(timer2); } } ir_usleep(20000L); } g_timer_destroy(timer1); ir_close_port(); pthread_exit(NULL); }