/* All functions that have to do with loading, managing, or writing the playlist are here. */ #include "cmp3funcs.h" #include "keydef.h" /* Static Prototypes */ static void pl_swap(char *first); static void pl_print(); extern char dolist() { int spot=1; /* Element number */ int cmd=0, /* Key pressed */ topline=0, /* Top of shown window */ held=0; /* If element is held */ char *element; /* Actual element name */ element = shmptr->plhead; if (shmptr->listlen > 0) element += strlen(element) + 1; redrawwin(win_list); wrefresh(win_list); pl_print(); while(1) { cmd=getch(); switch(cmd) { /**************************************************************************** * Q (quit) */ case CMP3_KEY_LISTQUIT: wattron(pad_list,COLOR_PAIR(CCOLOR_LIST)); return(0); /**************************************************************************** * Up */ case CMP3_KEY_UP1: case CMP3_KEY_UP2: if (spot < 2) break; if (!held) { mvwprintw(pad_list,spot,0,"%s\n", strrchr(element,'/')+1); spot--; for (element -= 2; *element != '\0'; element -= 1) ; element += 1; wattron(pad_list,A_REVERSE); mvwprintw(pad_list,spot,0,"%s\n", strrchr(element,'/')+1); wattroff(pad_list,A_REVERSE); } else { char *temp; for (element -= 2; *element != '\0'; element -= 1) ; element += 1; pl_swap(element); spot--; wattron(pad_list,COLOR_PAIR(CCOLOR_HIGHLIGHT)); wattron(pad_list,A_REVERSE); mvwprintw(pad_list,spot,0,"%s", strrchr(element,'/')+1); wattroff(pad_list,A_REVERSE); wattron(pad_list,COLOR_PAIR(CCOLOR_LIST)); wprintw(pad_list, " %c\n", held ? '*' : ' '); for (temp = element; *temp != '\0'; temp += 1) ; temp += 1; mvwprintw(pad_list, spot+1, 0,"%s\n", strrchr(temp,'/')+1); } if (spot - 1 < topline) topline--; prefresh(pad_list,topline,0,4,3,LINES-8,COLS-4); break; /**************************************************************************** * Down */ case CMP3_KEY_DOWN1: case CMP3_KEY_DOWN2: if (spot >= shmptr->listlen - 1) break; if (!held) { mvwprintw(pad_list,spot,0,"%s\n", strrchr(element,'/')+1); spot++; for (element += 1; *element != '\0'; element += 1) ; element += 1; wattron(pad_list,A_REVERSE); mvwprintw(pad_list,spot,0,"%s\n", strrchr(element,'/')+1); wattroff(pad_list,A_REVERSE); } else { pl_swap(element); mvwprintw(pad_list, spot, 0,"%s\n", strrchr(element,'/')+1); for (element += 1; *element != '\0'; element += 1) ; element += 1; spot++; wattron(pad_list,COLOR_PAIR(CCOLOR_HIGHLIGHT)); wattron(pad_list,A_REVERSE); mvwprintw(pad_list,spot,0,"%s", strrchr(element,'/')+1); wattroff(pad_list,A_REVERSE); wattron(pad_list,COLOR_PAIR(CCOLOR_LIST)); wprintw(pad_list, " %c\n", held ? '*' : ' '); } if ((topline+(LINES-13) < spot) && (spot != shmptr->listlen - 1)) { topline++; } prefresh(pad_list,topline,0,4,3,LINES-8,COLS-4); break; /**************************************************************************** * G (grab) */ case CMP3_KEY_GRABFILE: held = held ? 0 : 1; if (held) wattron(pad_list,COLOR_PAIR(CCOLOR_HIGHLIGHT)); else wattron(pad_list,COLOR_PAIR(CCOLOR_LIST)); wattron(pad_list,A_REVERSE); mvwprintw(pad_list, spot, 0, "%s", strrchr(element ,'/')+1); wattroff(pad_list,A_REVERSE); wattron(pad_list,COLOR_PAIR(CCOLOR_LIST)); wprintw(pad_list, " %c\n", held ? '*' : ' '); prefresh(pad_list,topline,0,4,3,LINES-8,COLS-4); break; /**************************************************************************** * D (delete) */ case CMP3_KEY_LISTDEL: case CMP3_KEY_DELETE: if (shmptr->listlen < 2) break; { char *ptr; int i; ptr = element; if (spot == shmptr->listlen - 1) { for (element -= 2; *element != '\0'; element -= 1) ; element += 1; spot -= 1; } pl_delentry(ptr); if (spot == 0) mvwprintw(pad_list, 1, 0, "\n"); else { ptr = element; wattron(pad_list, A_REVERSE); mvwprintw(pad_list, spot, 0, "%s\n", strrchr(ptr,'/')+1); wattroff(pad_list, A_REVERSE); for (i = spot + 1; i < shmptr->listlen; i++) { for (ptr += 1; *ptr != '\0'; ptr += 1) ; ptr += 1; wprintw(pad_list, "%s\n", strrchr(ptr,'/')+1); } wprintw(pad_list, "\n"); } if (spot - 1 < topline) topline--; prefresh(pad_list,topline,0,4,3,LINES-8,COLS-4); } break; /**************************************************************************** * R (randomize) */ case CMP3_KEY_RANDOMIZE: if (held) pl_randomize(spot); else pl_randomize(1); wattron(pad_list,COLOR_PAIR(CCOLOR_LIST)); return(0); break; /**************************************************************************** * F1 (help) */ case CMP3_KEY_HELP: showhelp(); redrawwin(win_list); wrefresh(win_list); prefresh(pad_list,topline,0,4,3,LINES-8,COLS-4); break; /**************************************************************************** * Default */ default: wattron(pad_list,COLOR_PAIR(CCOLOR_LIST)); ungetch(cmd); return(cmd); break; } } } /**************************************************************************** * Swap two songs around * Pass in the first of the two *adjacent* songs * Returns: nothing ****************************************************************************/ static void pl_swap(char *first) { char *temp, *second; temp = Strdup(first); for (second = first; *second != '\0'; second += 1) ; second += 1; memmove(first, second, strlen(second) + 1); strcpy(first + strlen(first) + 1, temp); free(temp); } /**************************************************************************** * Add a song to the playlist * Returns: nothing ****************************************************************************/ extern void pl_addentry(char *name) { int length; length = strlen(name); if ((length + 1 + shmptr->pltail) > (shmptr->plhead + PLAYLIST_SIZE)) { /* XXX playlist size has been overflowed */ return; } if (shmptr->pltail == NULL) shmptr->pltail = shmptr->plhead; strcpy(shmptr->pltail, name); shmptr->pltail += length + 1; shmptr->listlen += 1; /* first reap dead pid's (HACK!) */ if(kill(shmptr->pid,0)){ shmptr->pid = 0; } if (!shmptr->pid) kill(shmptr->managpid, SIGUSR1); } /**************************************************************************** * Duplicate currently playing song as the next entry * Used for restarting song * Returns: nothing ****************************************************************************/ extern void pl_dupfirst() { int length; length = strlen(shmptr->plhead); if ((length + 1 + shmptr->pltail) > (shmptr->plhead + PLAYLIST_SIZE)) { /* XXX playlist size has been overflowed */ return; } memmove(shmptr->plhead + length + 1, shmptr->plhead, shmptr->pltail - shmptr->plhead + 1); shmptr->pltail += length + 1; shmptr->listlen += 1; } /**************************************************************************** * Remove a song from the playlist * Returns: nothing ****************************************************************************/ extern void pl_delentry(char *name) { int length; if (shmptr->listlen == 0) return; length = strlen(name); if (name + length + 1 == shmptr->pltail) { *name = '\0'; /* XXX force segfault */ shmptr->pltail = name; } else { memmove(name, name + length + 1, shmptr->pltail - name - length); shmptr->pltail -= length + 1; } shmptr->listlen -= 1; } /**************************************************************************** * Clear all but the first entry * Returns: void ****************************************************************************/ extern void pl_clear() { if ((shmptr->listlen == 0) || (shmptr->listlen == 1)) return; shmptr->pltail = shmptr->plhead + strlen(shmptr->plhead) + 1; shmptr->listlen = 1; } /**************************************************************************** * Print playlist to list pad * Returns: nothing ****************************************************************************/ static void pl_print() { int i; char *ptr; wclear(pad_list); if (shmptr->listlen > 0) { if (shmptr->pid) { mvwprintw(pad_list,0,0,"%s -> ", shmptr->pause ? "Paused " : "Playing"); wprintw(pad_list,"%s\n", strrchr(shmptr->plhead,'/')+1); } ptr = shmptr->plhead + strlen(shmptr->plhead) + 1; for(i = 1; i < shmptr->listlen; i++) { if (*ptr == '/') { if (i == 1) wattron(pad_list,A_REVERSE); wprintw(pad_list,"%s\n", strrchr(ptr,'/')+1); if (i == 1) wattroff(pad_list,A_REVERSE); } else { /* XXX Handle alternate entries here */ } ptr += strlen(ptr) + 1; } } prefresh(pad_list,0,0,4,3,LINES-8,COLS-4); } /**************************************************************************** * Randomize the playlist starting at start * Playlist is a block of memory separated by NULL chars. So swapping * can't be done directly. So we make an array of random numbers, then * copy the songs in that order. * Returns: nothing ****************************************************************************/ extern void pl_randomize(int start) { int i, j, k, /* Counter variables */ loc, /* Random number, how many 0s to skip */ num, /* Number to add/check for in the array */ length, /* listlen - start */ *order; /* Array of random numbers */ char *playlist, /* Copy of playlist */ *endstart, /* The end of the start songs */ *temp; /* Pointer to next song to add */ srand(time(NULL)); length = shmptr->listlen - start; playlist = (char*) Malloc((shmptr->pltail - shmptr->plhead) * sizeof(char)); memcpy(playlist, shmptr->plhead, shmptr->pltail - shmptr->plhead); order = (int*) Malloc(length * sizeof(int)); /* Fill the order array with random numbers starting from 1 */ num = 1; for(i = 0; i < length; i++) { loc = (rand() % length); j = 0; while (loc) { if (order[j] == 0) loc--; j++; if (j > length-1) j = 0; } while (order[j] != 0) if (++j > length-1) j=0; order[j] = num++; } /* Copy over all songs before the start */ shmptr->pltail = shmptr->plhead; shmptr->listlen = 0; endstart = playlist; for (i=0; i < start; i++) { pl_addentry(endstart); for (endstart += 1; *endstart != '\0'; endstart += 1) ; endstart += 1; } /* Add the randomized songs in order */ num = 1; for (i = 0; i < length; i++) { for (j = 0; order[j] != num; j++) ; num++; temp = endstart; for (k=0; k < j; k++) { for (temp += 1; *temp != '\0'; temp += 1) ; temp += 1; } pl_addentry(temp); } free(playlist); free(order); } /* EOF */