#include "cdplayer.h" int cd_desc; struct disc_info disc; struct disc_status status; struct disc_data data; struct cddb_conf conf; struct cddb_serverlist list; struct cddb_server proxy; Display *dpy; Window xRootWindow; Window WindowGroupLeader; Window IconWindow; XClassHint *classHints; XWMHints *wmHints; GC MiniWindowGC; unsigned long GCValueMask; XGCValues GCValues; Pixel xForePixel; Pixel xBackPixel; WMAppContext *Application; Icon AppIcon; Icon MiniMaskBlank; Icon MiniMask; Icon MiniPlayButtonActive; Icon MiniStopButtonActive; Icon MiniPauseButtonActive; Icon MiniBackButtonActive; Icon MiniForwardButtonActive; Icon MiniEjectButtonActive; WMPixmap *numberbtn, *numberbtnh, *recordbtn, *recordbtnd, *recordbtnh, *playbtn, *playbtnd, *playbtnh, *pausebtn, *pausebtnd, *pausebtnh, *stopbtn, *stopbtnd, *stopbtnh, *backbtn, *backbtnd, *backbtnh, *nextbtn, *nextbtnd, *nextbtnh, *ejectbtn, *ejectbtnd, *ejectbtnh, *trackbtn[20], *trackbtnh[20]; void wAbort(void) { exit(1); } void usage(const char *name) { const char *tmp; tmp = strrchr(name, '/'); if (tmp != NULL) name = tmp+1; fprintf(stderr, "Usage: %s [-hvH] [-d device]\n" "\n" "\t-h\t\tthis help.\n" "\t-v\t\tshow version.\n" "\t-H\t\tstart hidden.\n" "\t-d device\tuse alternate CDROM device (default %s)\n" "\n", name, DEFAULT_DEVICE); } void version(const char *name) { const char *tmp; tmp = strrchr(name, '/'); if (tmp != NULL) name = tmp+1; fprintf(stderr, "%s version %s\n", name, PROGRAM_VERSION); } int main(int argc, char **argv) { int ret, start_hidden; char *device; char buf[1024] = ""; WMScreen *scr; cdplayer *w; device = DEFAULT_DEVICE; start_hidden = 0; while ((ret = getopt(argc, argv, "hvHd:")) != EOF) { switch (ret) { case 'h': usage(argv[0]); return 0; case 'v': version(argv[0]); return 0; case 'H': start_hidden = 1; break; case 'd': device = optarg; break; default: usage(argv[0]); return 1; } } WMInitializeApplication("CDPlayer", &argc, argv); if (!(dpy = XOpenDisplay(""))) { fprintf(stderr, "Can't open display.\n"); return 1; } scr = WMCreateScreen(dpy, DefaultScreen(dpy)); if ((cd_desc = cd_init_device(device)) < 0) { perror(device); switch (errno) { case EBUSY: sprintf(buf, "%s appears to be mounted. CDPlayer cannot continue.", device); WMRunAlertPanel(scr, NULL, "Device Busy", buf, "OK", NULL, NULL); break; case EACCES: sprintf(buf, "You do not have permission to open the device. Make sure you have read access to %s.", device); WMRunAlertPanel(scr, NULL, "Permission Denied", buf, "OK", NULL, NULL); break; default: WMRunAlertPanel(scr, NULL, "Device Error", "Unable to open device. Run CDPlayer from a terminal window to see more information.", "OK", NULL, NULL); break; } return errno; } createMiniWindow(argc, argv); Application = WMAppCreateWithMain(dpy, DefaultScreen(dpy), WindowGroupLeader); createPixmaps(scr); w = createPlayer(scr, start_hidden); while (1) { XEvent Event; WMNextEvent(dpy, &Event); WMHandleEvent(&Event); WMProcessEvent(Application, &Event); checkMiniButtons(Event, w); XFlush(dpy); } return 0; } int disc_present(void) { if (!cd_poll(cd_desc, &status)) if (status.status_present) if (!cd_update(&disc, status)) return 1; return 0; } int stopped(void) { if (disc.disc_mode == CDAUDIO_PLAYING || disc.disc_mode == CDAUDIO_PAUSED) return 0; return 1; } void setButtonImages(WMWidget *self, WMPixmap *image, WMPixmap *altimage) { WMSetButtonImage(self, image); WMSetButtonAltImage(self, altimage); } void trackUpdate(cdplayer *w) { if (!w->track_mode) { char tmp[20]; sprintf(tmp, "%d%s", w->play_track, disc.disc_track[w->play_track-1].track_type == CDAUDIO_TRACK_DATA ? " (data)" : ""); WMSetLabelText(w->lblTrack, tmp); } } void timeUpdate(cdplayer *w) { char tmp[25]; int min, sec, length, pos, total, current; length = disc.disc_track[w->play_track-1].track_length.minutes*60+ disc.disc_track[w->play_track-1].track_length.seconds; pos = disc.disc_track_time.minutes*60+disc.disc_track_time.seconds; total = disc.disc_length.minutes*60+disc.disc_length.seconds; current = disc.disc_time.minutes*60+disc.disc_time.seconds; switch (w->time_mode) { case 0: min = disc.disc_track_time.minutes; sec = disc.disc_track_time.seconds; sprintf(tmp, "%02d:%02d", min, sec); break; case 1: min = div(length-pos, 60).quot; sec = div(length-pos, 60).rem; sprintf(tmp, "-%02d:%02d", min, sec); break; case 2: min = disc.disc_time.minutes; sec = disc.disc_time.seconds; sprintf(tmp, "%02d:%02d", min, sec); break; case 3: min = div(total-current, 60).quot; sec = div(total-current, 60).rem; sprintf(tmp, "-%02d:%02d", min, sec); break; } WMSetLabelText(w->lblTime, tmp); if (WMGetSliderMaxValue(w->sldPos) != length) WMSetSliderMaxValue(w->sldPos, length); if (!w->dragging) WMSetSliderValue(w->sldPos, pos); } void zeroOrTotal(cdplayer *w) { char tmp[25]; switch (w->time_mode) { case 1: sprintf(tmp, "-%02d:%02d", disc.disc_track[w->play_track-1].track_length.minutes, disc.disc_track[w->play_track-1].track_length.seconds); break; case 3: sprintf(tmp, "-%02d:%02d", disc.disc_length.minutes, disc.disc_length.seconds); break; default: sprintf(tmp, "00:00"); break; } WMSetLabelText(w->lblTime, tmp); if (!w->dragging) WMSetSliderValue(w->sldPos, 0); } void playerStopped(cdplayer *w) { trackUpdate(w); zeroOrTotal(w); if (disc.disc_track[w->play_track-1].track_type == CDAUDIO_TRACK_AUDIO) setButtonImages(w->btnPlay, playbtn, playbtn); else setButtonImages(w->btnPlay, playbtnd, playbtnd); setButtonImages(w->btnPause, pausebtnd, pausebtnd); setButtonImages(w->btnStop, stopbtnd, stopbtnd); if (!w->button_pressed) { miniInitAction(); redrawTrackNumber(w); } } void playerPlaying(cdplayer *w) { setButtonImages(w->btnPlay, playbtnh, playbtnh); setButtonImages(w->btnPause, pausebtn, pausebtn); setButtonImages(w->btnStop, stopbtn, stopbtnh); if (!w->button_pressed) miniPlayAction(w); } void playerPaused(cdplayer *w) { setButtonImages(w->btnPlay, playbtn, playbtn); setButtonImages(w->btnPause, pausebtnh, pausebtnh); setButtonImages(w->btnStop, stopbtn, stopbtnh); if (!w->button_pressed) miniPauseAction(w); } void playTracks(cdplayer *w) { if (disc.disc_track[w->play_track-1].track_type == CDAUDIO_TRACK_AUDIO) { if (!cd_play_track(cd_desc, w->play_track, w->end_track)) playerPlaying(w); } else if (!stopped()) if (!cd_stop(cd_desc)) playerStopped(w); } void nextTrack(cdplayer *w) { switch (w->play_mode) { case 0: w->play_track = 1; w->end_track = w->total_tracks; if (WMGetButtonSelected(w->btnRepeat)) playTracks(w); else playerStopped(w); break; case 1: if (w->random_track == w->total_tracks-1) { w->random_track = 0; w->play_track = w->play_list[0]; w->end_track = w->play_track; if (WMGetButtonSelected(w->btnRepeat)) playTracks(w); else playerStopped(w); } else { w->random_track++; w->play_track = w->play_list[w->random_track]; w->end_track = w->play_track; playTracks(w); } break; case 2: if (WMGetButtonSelected(w->btnRepeat)) playTracks(w); else playerStopped(w); break; } } void changeTrack(cdplayer *w) { if (!w->play_mode) w->end_track = w->total_tracks; else w->end_track = w->play_track; switch (disc.disc_mode) { case CDAUDIO_PLAYING: playTracks(w); break; case CDAUDIO_PAUSED: playTracks(w); if (!cd_pause(cd_desc)) playerPaused(w); break; default: playerStopped(w); break; } if (w->track_mode) { WMDeleteTimerHandler(w->scroller); w->position = 0; scrollName(w); } } void currentInfo(cdplayer *w) { if (w->play_track != disc.disc_current_track && disc.disc_current_track > 0) w->play_track = disc.disc_current_track; trackUpdate(w); timeUpdate(w); } void scrollName(void *clientData) { cdplayer *w = (cdplayer *)clientData; char *tmp = data.data_track[w->play_track-1].track_name; w->scroller = WMAddTimerHandler(SCROLL_DELAY, scrollName, w); if (WMWidthOfString(w->boldFont, tmp, strlen(tmp)) > 160) { char *tmp2, *tmp3; tmp2 = (char *)wmalloc(strlen(tmp)*2+6); sprintf(tmp2, "%s *** %s", tmp, tmp); tmp3 = &tmp2[w->position]; while (WMWidthOfString(w->boldFont, tmp3, strlen(tmp3)) > 160) tmp2[strlen(tmp2)-1] = '\0'; if (w->position < strlen(tmp)+4) w->position++; else w->position = 0; WMSetLabelText(w->lblTrack, tmp3); free(tmp2); } else { w->position = 0; WMSetLabelText(w->lblTrack, tmp); } } void updatePlayer(void *clientData) { WMHandlerID timer; cdplayer *w = (cdplayer *)clientData; timer = WMAddTimerHandler(TIMER_INTERVAL, updatePlayer, w); if (disc_present()) { switch (disc.disc_mode) { case CDAUDIO_PLAYING: currentInfo(w); playerPlaying(w); break; case CDAUDIO_PAUSED: currentInfo(w); playerPaused(w); break; #ifdef SHUFFLE_REPEAT_HACK case CDAUDIO_NOSTATUS: #else case CDAUDIO_COMPLETED: #endif nextTrack(w); break; #ifdef SHUFFLE_REPEAT_HACK case CDAUDIO_COMPLETED: #else case CDAUDIO_NOSTATUS: #endif playerStopped(w); break; } } else { int i; WMDeleteTimerHandler(timer); w->disc_present = 0; strcpy(data.data_title, ""); strcpy(data.data_artist, ""); strcpy(data.data_extended, ""); data.data_genre = CDDB_UNKNOWN; for (i = 0; i != w->total_tracks; i++) { strcpy(data.data_track[i].track_name, ""); strcpy(data.data_track[i].track_artist, ""); strcpy(data.data_track[i].track_extended, ""); } w->play_track = 0; w->total_tracks = 0; w->last_mode = w->track_mode; if (w->track_mode) { w->track_mode = 0; WMDeleteTimerHandler(w->scroller); } for (i = 0; i != 20; i++) setButtonImages(w->btnTrack[i], numberbtn, numberbtnh); WMSetLabelText(w->lblTrack, "no disc"); WMSetLabelText(w->lblTime, "--:--"); setButtonImages(w->btnPlay, playbtnd, playbtnd); setButtonImages(w->btnPause, pausebtnd, pausebtnd); setButtonImages(w->btnStop, stopbtnd, stopbtnd); setButtonImages(w->btnPrev, backbtnd, backbtnd); setButtonImages(w->btnNext, nextbtnd, nextbtnd); WMSetSliderValue(w->sldPos, 0); if (!w->tray_open) { miniInitAction(); redrawMiniWindow(&MiniMask); } lookForDisc(w); } } void lookForDisc(void *clientData) { WMHandlerID timer; cdplayer *w = (cdplayer *)clientData; timer = WMAddTimerHandler(TIMER_INTERVAL, lookForDisc, w); if (disc_present()) if (!cd_stat(cd_desc, &disc)) { int i; struct cddb_entry entry; WMDeleteTimerHandler(timer); w->tray_open = 0; w->disc_present = 1; w->play_track = 1; w->total_tracks = disc.disc_total_tracks; if (cddb_stat_disc_data(cd_desc, &entry) < 0) alert("Error", "Could not stat disc data.", w->win); if (cddb_read_disc_data(cd_desc, &data) < 0) alert("Error", "Could not read disc data.", w->win); if (!entry.entry_present && data.data_genre != CDDB_UNKNOWN) cddb_write_disc_data(cd_desc, data); for (i = 0; i != w->total_tracks; i++) if (i < 20) setButtonImages(w->btnTrack[i], trackbtn[i], trackbtnh[i]); if (w->play_mode == 1) PlayModeButton(w->btnPlayShuffle, w); if (w->last_mode) { w->track_mode = 1; w->position = 0; scrollName(w); } if (w->total_tracks > 1) { setButtonImages(w->btnPrev, backbtn, backbtnh); setButtonImages(w->btnNext, nextbtn, nextbtnh); } setButtonImages(w->btnEject, ejectbtn, ejectbtn); miniInitAction(); redrawTrackNumber(w); updatePlayer(w); } } cdplayer *createPlayer(WMScreen *scr, int start_hidden) { int i; cdplayer *w; w = (cdplayer *)wmalloc(sizeof(cdplayer)); w->tray_open = 0; w->disc_present = 0; w->dragging = 0; w->editing = 0; w->play_mode = 0; w->track_mode = 0; w->last_mode = 0; w->position = 0; w->time_mode = 0; w->play_track = 0; w->random_track = 0; w->end_track = 0; w->total_tracks = 0; w->button_pressed = 0; w->win = WMCreateWindow(scr, "cdplayer"); WMSetWindowTitle(w->win, "CDPlayer"); WMSetWindowMiniwindowTitle(w->win, "CDPlayer"); WMSetWindowCloseAction(w->win, (WMAction *)ClosePlayer, NULL); WMSetWindowMinSize(w->win, 236, 164); WMSetWindowMaxSize(w->win, 236, 164); WMResizeWidget(w->win, 236, 164); w->lblBack = WMCreateLabel(w->win); WMResizeWidget(w->lblBack, 236, 164); WMMoveWidget(w->lblBack, 0, 0); WMSetLabelRelief(w->lblBack, WRFlat); WMSetLabelImagePosition(w->lblBack, WIPImageOnly); WMSetLabelImage(w->lblBack, WMCreatePixmapFromXPMData(scr, panelgradient_xpm)); w->lblIcon = WMCreateLabel(w->lblBack); WMResizeWidget(w->lblIcon, 48, 48); WMMoveWidget(w->lblIcon, 7, 5); WMSetLabelRelief(w->lblIcon, WRFlat); WMSetLabelImagePosition(w->lblIcon, WIPImageOnly); WMSetLabelImage(w->lblIcon, WMCreatePixmapFromXPMData(scr, appicon_xpm)); WMCreateEventHandler(WMWidgetView(w->lblIcon), ButtonPressMask, IconLabelClick, w); for (i = 0; i != 10; i++) { w->btnTrack[i] = WMCreateCustomButton(w->lblBack, WBBPushChangeMask); WMResizeWidget(w->btnTrack[i], 17, 24); WMMoveWidget(w->btnTrack[i], 63+i*17, 5); WMSetButtonBordered(w->btnTrack[i], 0); WMSetButtonImagePosition(w->btnTrack[i], WIPImageOnly); setButtonImages(w->btnTrack[i], numberbtn, numberbtnh); WMSetButtonAction(w->btnTrack[i], (WMAction *)TrackButton, w); } for (i = 10; i != 20; i++) { w->btnTrack[i] = WMCreateCustomButton(w->lblBack, WBBPushChangeMask); WMResizeWidget(w->btnTrack[i], 17, 24); WMMoveWidget(w->btnTrack[i], 63+(i-10)*17, 29); WMSetButtonBordered(w->btnTrack[i], 0); WMSetButtonImagePosition(w->btnTrack[i], WIPImageOnly); setButtonImages(w->btnTrack[i], numberbtn, numberbtnh); WMSetButtonAction(w->btnTrack[i], (WMAction *)TrackButton, w); } w->btnPlayAll = WMCreateCustomButton(w->lblBack, WBBStateChangeMask); WMResizeWidget(w->btnPlayAll, 39, 25); WMMoveWidget(w->btnPlayAll, 3, 59); WMSetButtonBordered(w->btnPlayAll, 0); WMSetButtonImagePosition(w->btnPlayAll, WIPImageOnly); WMSetButtonImage(w->btnPlayAll, WMCreatePixmapFromXPMData(scr, modeplayall_xpm)); WMSetButtonAltImage(w->btnPlayAll, WMCreatePixmapFromXPMData(scr, modeplayallh_xpm)); WMSetButtonAction(w->btnPlayAll, (WMAction *)PlayModeButton, w); w->btnPlayShuffle = WMCreateCustomButton(w->lblBack, WBBStateChangeMask); WMResizeWidget(w->btnPlayShuffle, 39, 25); WMMoveWidget(w->btnPlayShuffle, 42, 59); WMSetButtonBordered(w->btnPlayShuffle, 0); WMSetButtonImagePosition(w->btnPlayShuffle, WIPImageOnly); WMSetButtonImage(w->btnPlayShuffle, WMCreatePixmapFromXPMData(scr, modeplayshuffle_xpm)); WMSetButtonAltImage(w->btnPlayShuffle, WMCreatePixmapFromXPMData(scr, modeplayshuffleh_xpm)); WMSetButtonAction(w->btnPlayShuffle, (WMAction *)PlayModeButton, w); WMGroupButtons(w->btnPlayAll, w->btnPlayShuffle); w->btnPlayTrack = WMCreateCustomButton(w->lblBack, WBBStateChangeMask); WMResizeWidget(w->btnPlayTrack, 39, 25); WMMoveWidget(w->btnPlayTrack, 81, 59); WMSetButtonBordered(w->btnPlayTrack, 0); WMSetButtonImagePosition(w->btnPlayTrack, WIPImageOnly); WMSetButtonImage(w->btnPlayTrack, WMCreatePixmapFromXPMData(scr, modeplaytrack_xpm)); WMSetButtonAltImage(w->btnPlayTrack, WMCreatePixmapFromXPMData(scr, modeplaytrackh_xpm)); WMSetButtonAction(w->btnPlayTrack, (WMAction *)PlayModeButton, w); WMGroupButtons(w->btnPlayShuffle, w->btnPlayTrack); WMSetButtonSelected(w->btnPlayAll, 1); w->btnRepeat = WMCreateCustomButton(w->lblBack, WBBStateChangeMask); WMResizeWidget(w->btnRepeat, 39, 25); WMMoveWidget(w->btnRepeat, 194, 59); WMSetButtonBordered(w->btnRepeat, 0); WMSetButtonImagePosition(w->btnRepeat, WIPImageOnly); WMSetButtonImage(w->btnRepeat, WMCreatePixmapFromXPMData(scr, moderepeat_xpm)); WMSetButtonAltImage(w->btnRepeat, WMCreatePixmapFromXPMData(scr, moderepeath_xpm)); w->boldFont = WMBoldSystemFontOfSize(scr, 12); w->lblTrack = WMCreateLabel(w->lblBack); WMResizeWidget(w->lblTrack, 170, 21); WMMoveWidget(w->lblTrack, 3, 88); WMSetLabelRelief(w->lblTrack, WRSunken); WMSetLabelTextAlignment(w->lblTrack, WACenter); WMSetWidgetBackgroundColor(w->lblTrack, WMDarkGrayColor(scr)); WMSetLabelTextColor(w->lblTrack, WMWhiteColor(scr)); WMSetLabelFont(w->lblTrack, w->boldFont); WMSetLabelText(w->lblTrack, "no disc"); WMCreateEventHandler(WMWidgetView(w->lblTrack), ButtonPressMask, TrackLabelClick, w); w->lblTime = WMCreateLabel(w->lblBack); WMResizeWidget(w->lblTime, 57, 21); WMMoveWidget(w->lblTime, 176, 88); WMSetLabelRelief(w->lblTime, WRSunken); WMSetLabelTextAlignment(w->lblTime, WACenter); WMSetWidgetBackgroundColor(w->lblTime, WMDarkGrayColor(scr)); WMSetLabelTextColor(w->lblTime, WMWhiteColor(scr)); WMSetLabelFont(w->lblTime, w->boldFont); WMSetLabelText(w->lblTime, "--:--"); WMCreateEventHandler(WMWidgetView(w->lblTime), ButtonPressMask, TimeLabelClick, w); w->btnRec = WMCreateCustomButton(w->lblBack, WBBPushChangeMask); WMResizeWidget(w->btnRec, 25, 25); WMMoveWidget(w->btnRec, 3, 114); WMSetButtonBordered(w->btnRec, 0); WMSetButtonImagePosition(w->btnRec, WIPImageOnly); setButtonImages(w->btnRec, recordbtnd, recordbtnd); w->btnPlay = WMCreateCustomButton(w->lblBack, WBBPushChangeMask); WMResizeWidget(w->btnPlay, 25, 25); WMMoveWidget(w->btnPlay, 28, 114); WMSetButtonBordered(w->btnPlay, 0); WMSetButtonImagePosition(w->btnPlay, WIPImageOnly); setButtonImages(w->btnPlay, playbtnd, playbtnd); WMSetButtonAction(w->btnPlay, (WMAction *)PlayButton, w); w->btnPause = WMCreateCustomButton(w->lblBack, WBBPushChangeMask); WMResizeWidget(w->btnPause, 25, 25); WMMoveWidget(w->btnPause, 53, 114); WMSetButtonBordered(w->btnPause, 0); WMSetButtonImagePosition(w->btnPause, WIPImageOnly); setButtonImages(w->btnPause, pausebtnd, pausebtnd); WMSetButtonAction(w->btnPause, (WMAction *)PauseButton, w); w->btnStop = WMCreateCustomButton(w->lblBack, WBBPushChangeMask); WMResizeWidget(w->btnStop, 25, 25); WMMoveWidget(w->btnStop, 78, 114); WMSetButtonBordered(w->btnStop, 0); WMSetButtonImagePosition(w->btnStop, WIPImageOnly); setButtonImages(w->btnStop, stopbtnd, stopbtnd); WMSetButtonAction(w->btnStop, (WMAction *)StopButton, w); w->btnPrev = WMCreateCustomButton(w->lblBack, WBBPushChangeMask); WMResizeWidget(w->btnPrev, 25, 25); WMMoveWidget(w->btnPrev, 118, 114); WMSetButtonBordered(w->btnPrev, 0); WMSetButtonImagePosition(w->btnPrev, WIPImageOnly); setButtonImages(w->btnPrev, backbtnd, backbtnd); WMSetButtonAction(w->btnPrev, (WMAction *)PrevButton, w); w->btnNext = WMCreateCustomButton(w->lblBack, WBBPushChangeMask); WMResizeWidget(w->btnNext, 25, 25); WMMoveWidget(w->btnNext, 143, 114); WMSetButtonBordered(w->btnNext, 0); WMSetButtonImagePosition(w->btnNext, WIPImageOnly); setButtonImages(w->btnNext, nextbtnd, nextbtnd); WMSetButtonAction(w->btnNext, (WMAction *)NextButton, w); w->btnEject = WMCreateCustomButton(w->lblBack, WBBPushChangeMask); WMResizeWidget(w->btnEject, 25, 25); WMMoveWidget(w->btnEject, 207, 114); WMSetButtonBordered(w->btnEject, 0); WMSetButtonImagePosition(w->btnEject, WIPImageOnly); setButtonImages(w->btnEject, ejectbtn, ejectbtn); WMSetButtonAction(w->btnEject, (WMAction *)EjectButton, w); w->sldPos = WMCreateSlider(w->lblBack); WMResizeWidget(w->sldPos, 229, 17); WMMoveWidget(w->sldPos, 3, 142); WMSetSliderMinValue(w->sldPos, 0); WMSetSliderValue(w->sldPos, 0); WMSetSliderKnobThickness(w->sldPos, 2); WMSetSliderImage(w->sldPos, WMCreatePixmapFromXPMData(scr, posbar_xpm)); WMCreateEventHandler(WMWidgetView(w->sldPos), ButtonPressMask, Drag, w); WMCreateEventHandler(WMWidgetView(w->sldPos), ButtonReleaseMask, Skip, w); WMMapSubwidgets(w->lblBack); WMRealizeWidget(w->win); WMMapSubwidgets(w->win); wmHints = XAllocWMHints(); wmHints->window_group = WindowGroupLeader; wmHints->flags = WindowGroupHint; XSetWMHints(dpy, WMWidgetXID(w->win), wmHints); XFree(wmHints); lookForDisc(w); WMMapWidget(w->win); if (start_hidden) WMHideApplication(Application); return w; } void ClosePlayer(WMWidget *self, cdplayer *w) { if (!cd_finish(cd_desc)) exit(0); } void PlayModeButton(WMWidget *self, cdplayer *w) { if (self == w->btnPlayAll) w->play_mode = 0; else if (self == w->btnPlayShuffle) { int i, j, k; w->play_mode = 1; w->random_track = 0; srand((unsigned int)time(NULL)); for (i = 0; i != w->total_tracks; i++) w->play_list[i] = i+1; for (i = 0; i != w->total_tracks; i++) { j = rand()%w->total_tracks; if (j > 0) { k = w->play_list[0]; w->play_list[0] = w->play_list[j]; w->play_list[j] = k; } } if (w->total_tracks > 0) w->play_track = w->play_list[0]; } else w->play_mode = 2; if (w->disc_present) changeTrack(w); } void TrackButton(WMWidget *self, cdplayer *w) { if (w->disc_present) { int i, track; track = w->total_tracks+1; for (i = 0; i != w->total_tracks; i++) if (self == w->btnTrack[i]) track = i; if (track < w->total_tracks) { w->play_track = track+1; changeTrack(w); } } } void PlayButton(WMWidget *self, cdplayer *w) { if (w->disc_present) { if (disc.disc_mode == CDAUDIO_PAUSED) { if (!cd_resume(cd_desc)) playerPlaying(w); } else { if (!w->play_mode) w->end_track = w->total_tracks; else w->end_track = w->play_track; playTracks(w); } } } void PauseButton(WMWidget *self, cdplayer *w) { if (w->disc_present) { if (disc.disc_mode == CDAUDIO_PLAYING) { if (!cd_pause(cd_desc)) playerPaused(w); } else if (disc.disc_mode == CDAUDIO_PAUSED) { if (!cd_resume(cd_desc)) playerPlaying(w); } } } void StopButton(WMWidget *self, cdplayer *w) { if (w->disc_present && !stopped()) if (!cd_stop(cd_desc)) playerStopped(w); } void PrevButton(WMWidget *self, cdplayer *w) { if (w->disc_present && w->total_tracks > 1) { if (w->play_mode == 1) { if (!w->random_track) w->random_track = w->total_tracks-1; else w->random_track--; w->play_track = w->play_list[w->random_track]; } else { if (w->play_track == 1) w->play_track = w->total_tracks; else w->play_track--; } changeTrack(w); } } void NextButton(WMWidget *self, cdplayer *w) { if (w->disc_present && w->total_tracks > 1) { if (w->play_mode == 1) { if (w->random_track == w->total_tracks-1) w->random_track = 0; else w->random_track++; w->play_track = w->play_list[w->random_track]; } else { if (w->play_track == w->total_tracks) w->play_track = 1; else w->play_track++; } changeTrack(w); } } void EjectButton(WMWidget *self, cdplayer *w) { if (w->tray_open) { if (!cd_close(cd_desc)) { w->tray_open = 0; setButtonImages(w->btnEject, ejectbtn, ejectbtn); miniInitAction(); redrawMiniWindow(&MiniMask); } } else if (!w->editing) { if (!cd_eject(cd_desc)) { w->tray_open = 1; w->disc_present = 0; setButtonImages(w->btnEject, ejectbtnh, ejectbtnh); miniEjectAction(); } } } static void Drag(XEvent *event, void *clientData) { cdplayer *w = (cdplayer *)clientData; w->dragging = 1; } static void Skip(XEvent *event, void *clientData) { cdplayer *w = (cdplayer *)clientData; if (w->disc_present && disc.disc_mode == CDAUDIO_PLAYING) { int pos; struct disc_timeval skip_time; pos = div(WMGetSliderMaxValue(w->sldPos)*event->xbutton.x, 229).quot- (disc.disc_track_time.minutes*60+disc.disc_track_time.seconds); skip_time.minutes = div(pos, 60).quot; skip_time.seconds = div(pos, 60).rem; if (!cd_track_advance(cd_desc, w->end_track, skip_time)) playerPlaying(w); } w->dragging = 0; } static void IconLabelClick(XEvent *event, void *clientData) { cdplayer *w = (cdplayer *)clientData; if (w->disc_present && !w->editing) { app *a; editor *e; a = (app *)wmalloc(sizeof(app)); a->cdplayer = w; createEditor(a); e = a->editor; memcpy(&e->data, &data, sizeof(struct disc_data)); updateEntry(a, e->data); list.list_len = 0; if (cddb_read_serverlist(&conf, &list, &proxy) < 0) alert("Error", "Could not read sites list.", w->win); conf.conf_access = CDDB_ACCESS_REMOTE; updateSites(e); WMMapWidget(e->win); setButtonImages(w->btnEject, ejectbtnd, ejectbtnd); w->editing = 1; } } static void TrackLabelClick(XEvent *event, void *clientData) { cdplayer *w = (cdplayer *)clientData; if (w->disc_present) { if (!w->track_mode) { w->track_mode = 1; w->position = 0; scrollName(w); } else { w->track_mode = 0; WMDeleteTimerHandler(w->scroller); trackUpdate(w); } } } static void TimeLabelClick(XEvent *event, void *clientData) { cdplayer *w = (cdplayer *)clientData; if (w->disc_present) { if (w->time_mode < 3) w->time_mode++; else w->time_mode = 0; if (stopped()) zeroOrTotal(w); else timeUpdate(w); } } void alert(char *title, char *text, WMWindow *owner) { WMRunAlertPanel(WMWidgetScreen(owner), owner, title, text, "OK", NULL, NULL); } char *input(char *title, char *text, char *def, WMWindow *owner) { return WMRunInputPanel(WMWidgetScreen(owner), owner, title, text, def, "OK", "Cancel"); } void updateEntry(app *a, struct disc_data indata) { int i; char *tmp; cdplayer *w = a->cdplayer; editor *e = a->editor; WMSetTextFieldText(e->txtDiscArtist, indata.data_artist); WMSetTextFieldText(e->txtDiscTitle, indata.data_title); WMSetTextFieldText(e->txtDiscExtended, indata.data_extended); WMSetPopUpButtonSelectedItem(e->popGenre, indata.data_genre); WMClearList(e->lstTrackNames); for (i = 0; i != w->total_tracks; i++) { tmp = (char *)wmalloc(strlen(indata.data_track[i].track_name)+15); sprintf(tmp, "%d. %s", i+1, indata.data_track[i].track_name); WMAddListItem(e->lstTrackNames, tmp); free(tmp); } WMSetTextFieldText(e->txtTrackName, ""); WMSetTextFieldText(e->txtTrackArtist, ""); WMSetTextFieldText(e->txtTrackExtended, ""); e->last_track = -1; } void updateSites(editor *e) { int i; WMClearList(e->lstSiteNames); for (i = 0; i != list.list_len; i++) WMAddListItem(e->lstSiteNames, list.list_host[i].host_server.server_name); WMSetPopUpButtonSelectedItem(e->popProtocol, 0); WMSetTextFieldText(e->txtName, ""); WMSetTextFieldText(e->txtPort, ""); WMSetTextFieldText(e->txtAddressing, ""); if (conf.conf_proxy) { char tmp[15]; WMSetTextFieldText(e->txtProxyServer, proxy.server_name); sprintf(tmp, "%d", proxy.server_port); WMSetTextFieldText(e->txtProxyPort, tmp); } WMSetButtonEnabled(e->btnRemove, False); e->last_site = -1; } void saveTrack(editor *e, int pos) { if (pos > -1) { strncpy(e->data.data_track[pos].track_name, WMGetTextFieldText(e->txtTrackName), 256); strncpy(e->data.data_track[pos].track_artist, WMGetTextFieldText(e->txtTrackArtist), 256); strncpy(e->data.data_track[pos].track_extended, WMGetTextFieldText(e->txtTrackExtended), EXTENDED_DATA_SIZE); } } void saveSite(editor *e, int pos) { if (pos > -1) { list.list_host[pos].host_protocol = WMGetPopUpButtonSelectedItem(e->popProtocol); strncpy(list.list_host[pos].host_server.server_name, WMGetTextFieldText(e->txtName), 256); list.list_host[pos].host_server.server_port = atoi(WMGetTextFieldText(e->txtPort)); strncpy(list.list_host[pos].host_addressing, WMGetTextFieldText(e->txtAddressing), 256); } } void createEditor(app *a) { int i; editor *e; cdplayer *w = a->cdplayer; WMTabViewItem *tab; e = (editor *)wmalloc(sizeof(editor)); a->editor = e; e->busy = 0; e->win = WMCreatePanelWithStyleForWindow(w->win, "editor", WMTitledWindowMask | WMClosableWindowMask); WMSetWindowTitle(e->win, "CDDB Editor"); WMSetWindowCloseAction(e->win, (WMAction *)CloseEditor, a); WMSetWindowMinSize(e->win, 510, 344); WMSetWindowMaxSize(e->win, 510, 344); WMResizeWidget(e->win, 510, 344); e->tabMain = WMCreateTabView(e->win); WMResizeWidget(e->tabMain, 490, 324); WMMoveWidget(e->tabMain, 10, 10); e->frmEntry = WMCreateFrame(e->win); WMSetFrameRelief(e->frmEntry, WRFlat); tab = WMCreateTabViewItemWithIdentifier(0); WMSetTabViewItemView(tab, WMWidgetView(e->frmEntry)); WMSetTabViewItemLabel(tab, "Disc"); WMAddItemInTabView(e->tabMain, tab); e->frmDiscArtist = WMCreateFrame(e->frmEntry); WMResizeWidget(e->frmDiscArtist, 230, 43); WMMoveWidget(e->frmDiscArtist, 9, 5); WMSetFrameTitle(e->frmDiscArtist, "Artist"); e->txtDiscArtist = WMCreateTextField(e->frmDiscArtist); WMResizeWidget(e->txtDiscArtist, 214, 20); WMMoveWidget(e->txtDiscArtist, 8, 15); WMMapSubwidgets(e->frmDiscArtist); e->frmDiscTitle = WMCreateFrame(e->frmEntry); WMResizeWidget(e->frmDiscTitle, 230, 43); WMMoveWidget(e->frmDiscTitle, 249, 5); WMSetFrameTitle(e->frmDiscTitle, "Title"); e->txtDiscTitle = WMCreateTextField(e->frmDiscTitle); WMResizeWidget(e->txtDiscTitle, 214, 20); WMMoveWidget(e->txtDiscTitle, 8, 15); WMMapSubwidgets(e->frmDiscTitle); e->frmDiscExtended = WMCreateFrame(e->frmEntry); WMResizeWidget(e->frmDiscExtended, 230, 43); WMMoveWidget(e->frmDiscExtended, 9, 53); WMSetFrameTitle(e->frmDiscExtended, "Extended"); e->txtDiscExtended = WMCreateTextField(e->frmDiscExtended); WMResizeWidget(e->txtDiscExtended, 214, 20); WMMoveWidget(e->txtDiscExtended, 8, 15); WMMapSubwidgets(e->frmDiscExtended); e->frmGenre = WMCreateFrame(e->frmEntry); WMResizeWidget(e->frmGenre, 230, 43); WMMoveWidget(e->frmGenre, 249, 53); WMSetFrameTitle(e->frmGenre, "Genre"); e->popGenre = WMCreatePopUpButton(e->frmGenre); WMResizeWidget(e->popGenre, 214, 20); WMMoveWidget(e->popGenre, 8, 15); for (i = 0; i != 12; i++) WMAddPopUpButtonItem(e->popGenre, cddb_genre(i)); WMMapSubwidgets(e->frmGenre); e->lstTrackNames = WMCreateList(e->frmEntry); WMResizeWidget(e->lstTrackNames, 230, 154); WMMoveWidget(e->lstTrackNames, 9, 106); WMSetListAction(e->lstTrackNames, (WMAction *)TrackClick, e); WMSetListDoubleAction(e->lstTrackNames, (WMAction *)TrackDoubleClick, w); e->frmTrackName = WMCreateFrame(e->frmEntry); WMResizeWidget(e->frmTrackName, 230, 43); WMMoveWidget(e->frmTrackName, 249, 121); WMSetFrameTitle(e->frmTrackName, "Name"); e->txtTrackName = WMCreateTextField(e->frmTrackName); WMResizeWidget(e->txtTrackName, 214, 20); WMMoveWidget(e->txtTrackName, 8, 15); WMAddNotificationObserver(ChangedTrack, e, WMTextDidChangeNotification, e->txtTrackName); WMMapSubwidgets(e->frmTrackName); e->frmTrackArtist = WMCreateFrame(e->frmEntry); WMResizeWidget(e->frmTrackArtist, 230, 43); WMMoveWidget(e->frmTrackArtist, 249, 169); WMSetFrameTitle(e->frmTrackArtist, "Artist"); e->txtTrackArtist = WMCreateTextField(e->frmTrackArtist); WMResizeWidget(e->txtTrackArtist, 214, 20); WMMoveWidget(e->txtTrackArtist, 8, 15); WMMapSubwidgets(e->frmTrackArtist); e->frmTrackExtended = WMCreateFrame(e->frmEntry); WMResizeWidget(e->frmTrackExtended, 230, 43); WMMoveWidget(e->frmTrackExtended, 249, 217); WMSetFrameTitle(e->frmTrackExtended, "Extended"); e->txtTrackExtended = WMCreateTextField(e->frmTrackExtended); WMResizeWidget(e->txtTrackExtended, 214, 20); WMMoveWidget(e->txtTrackExtended, 8, 15); WMMapSubwidgets(e->frmTrackExtended); e->btnDelete = WMCreateCommandButton(e->frmEntry); WMResizeWidget(e->btnDelete, 70, 24); WMMoveWidget(e->btnDelete, 169, 270); WMSetButtonText(e->btnDelete, "Delete"); WMSetButtonAction(e->btnDelete, (WMAction *)DeleteButton, e); e->btnSubmit = WMCreateCommandButton(e->frmEntry); WMResizeWidget(e->btnSubmit, 70, 24); WMMoveWidget(e->btnSubmit, 249, 270); WMSetButtonText(e->btnSubmit, "Submit"); WMSetButtonAction(e->btnSubmit, (WMAction *)SubmitButton, a); e->btnLookup = WMCreateCommandButton(e->frmEntry); WMResizeWidget(e->btnLookup, 70, 24); WMMoveWidget(e->btnLookup, 329, 270); WMSetButtonText(e->btnLookup, "Lookup"); WMSetButtonAction(e->btnLookup, (WMAction *)LookupButton, a); e->btnSaveEntry = WMCreateCommandButton(e->frmEntry); WMResizeWidget(e->btnSaveEntry, 70, 24); WMMoveWidget(e->btnSaveEntry, 409, 270); WMSetButtonText(e->btnSaveEntry, "Save"); WMSetButtonAction(e->btnSaveEntry, (WMAction *)SaveEntryButton, a); WMMapSubwidgets(e->frmEntry); e->frmSites = WMCreateFrame(e->win); WMSetFrameRelief(e->frmSites, WRFlat); tab = WMCreateTabViewItemWithIdentifier(1); WMSetTabViewItemView(tab, WMWidgetView(e->frmSites)); WMSetTabViewItemLabel(tab, "Sites"); WMAddItemInTabView(e->tabMain, tab); e->frmProxy = WMCreateFrame(e->frmSites); WMResizeWidget(e->frmProxy, 230, 43); WMMoveWidget(e->frmProxy, 9, 53); WMSetFrameTitle(e->frmProxy, "Proxy / Port"); e->txtProxyServer = WMCreateTextField(e->frmProxy); WMResizeWidget(e->txtProxyServer, 160, 20); WMMoveWidget(e->txtProxyServer, 8, 15); e->txtProxyPort = WMCreateTextField(e->frmProxy); WMResizeWidget(e->txtProxyPort, 48, 20); WMMoveWidget(e->txtProxyPort, 174, 15); WMMapSubwidgets(e->frmProxy); e->lstSiteNames = WMCreateList(e->frmSites); WMResizeWidget(e->lstSiteNames, 230, 154); WMMoveWidget(e->lstSiteNames, 9, 106); WMSetListAction(e->lstSiteNames, (WMAction *)SiteClick, e); e->frmProtocol = WMCreateFrame(e->frmSites); WMResizeWidget(e->frmProtocol, 230, 43); WMMoveWidget(e->frmProtocol, 249, 121); WMSetFrameTitle(e->frmProtocol, "Protocol"); e->popProtocol = WMCreatePopUpButton(e->frmProtocol); WMResizeWidget(e->popProtocol, 214, 20); WMMoveWidget(e->popProtocol, 8, 15); WMAddPopUpButtonItem(e->popProtocol, "CDDB Mode CDDBP"); WMAddPopUpButtonItem(e->popProtocol, "CDDB Mode HTTP"); WMAddPopUpButtonItem(e->popProtocol, "CDINDEX Mode HTTP"); WMMapSubwidgets(e->frmProtocol); e->frmSite = WMCreateFrame(e->frmSites); WMResizeWidget(e->frmSite, 230, 43); WMMoveWidget(e->frmSite, 249, 169); WMSetFrameTitle(e->frmSite, "Name / Port"); e->txtName = WMCreateTextField(e->frmSite); WMResizeWidget(e->txtName, 160, 20); WMMoveWidget(e->txtName, 8, 15); WMAddNotificationObserver(ChangedSite, e, WMTextDidChangeNotification, e->txtName); e->txtPort = WMCreateTextField(e->frmSite); WMResizeWidget(e->txtPort, 48, 20); WMMoveWidget(e->txtPort, 174, 15); WMMapSubwidgets(e->frmSite); e->frmAddressing = WMCreateFrame(e->frmSites); WMResizeWidget(e->frmAddressing, 230, 43); WMMoveWidget(e->frmAddressing, 249, 217); WMSetFrameTitle(e->frmAddressing, "Addressing"); e->txtAddressing = WMCreateTextField(e->frmAddressing); WMResizeWidget(e->txtAddressing, 214, 20); WMMoveWidget(e->txtAddressing, 8, 15); WMMapSubwidgets(e->frmAddressing); e->btnRemove = WMCreateCommandButton(e->frmSites); WMResizeWidget(e->btnRemove, 70, 24); WMMoveWidget(e->btnRemove, 169, 270); WMSetButtonText(e->btnRemove, "Remove"); WMSetButtonAction(e->btnRemove, (WMAction *)RemoveButton, e); e->btnAdd = WMCreateCommandButton(e->frmSites); WMResizeWidget(e->btnAdd, 70, 24); WMMoveWidget(e->btnAdd, 249, 270); WMSetButtonText(e->btnAdd, "Add"); WMSetButtonAction(e->btnAdd, (WMAction *)AddButton, e); e->btnRefresh = WMCreateCommandButton(e->frmSites); WMResizeWidget(e->btnRefresh, 70, 24); WMMoveWidget(e->btnRefresh, 329, 270); WMSetButtonText(e->btnRefresh, "Refresh"); WMSetButtonAction(e->btnRefresh, (WMAction *)RefreshButton, e); e->btnSaveSites = WMCreateCommandButton(e->frmSites); WMResizeWidget(e->btnSaveSites, 70, 24); WMMoveWidget(e->btnSaveSites, 409, 270); WMSetButtonText(e->btnSaveSites, "Save"); WMSetButtonAction(e->btnSaveSites, (WMAction *)SaveSitesButton, e); WMMapSubwidgets(e->frmSites); WMRealizeWidget(e->win); WMMapSubwidgets(e->win); WMUnmapWidget(e->frmSites); } void CloseEditor(WMWidget *self, app *a) { editor *e = a->editor; if (!e->busy) { cdplayer *w = a->cdplayer; WMUnmapWidget(self); WMDestroyWidget(self); setButtonImages(w->btnEject, ejectbtn, ejectbtn); free(e); free(a); w->editing = 0; } } void TrackClick(WMWidget *self, editor *e) { int i = WMGetListSelectedItemRow(e->lstTrackNames); saveTrack(e, e->last_track); WMSetTextFieldText(e->txtTrackName, e->data.data_track[i].track_name); WMSetTextFieldText(e->txtTrackArtist, e->data.data_track[i].track_artist); WMSetTextFieldText(e->txtTrackExtended, e->data.data_track[i].track_extended); e->last_track = i; } void TrackDoubleClick(WMWidget *self, cdplayer *w) { w->play_track = WMGetListSelectedItemRow(self)+1; changeTrack(w); } void DeleteButton(WMWidget *self, editor *e) { WMSetButtonEnabled(self, False); e->busy++; if (cddb_erase_entry(data) < 0) alert("Error", "Could not delete disc data.", e->win); WMSetButtonEnabled(self, True); e->busy--; } void SubmitButton(WMWidget *self, app *a) { int i; char *email; struct cddb_server *proxyptr; editor *e = a->editor; WMSetButtonEnabled(self, False); e->busy++; saveSite(e, e->last_site); i = 0; while (list.list_host[i].host_protocol != CDDB_MODE_HTTP && i < list.list_len) i++; if (i < list.list_len) { email = input("Submit", "Enter your e-mail address:", NULL, e->win); if (email != NULL) { SaveEntryButton(e->btnSaveEntry, a); if (conf.conf_proxy) proxyptr = &proxy; else proxyptr = NULL; if (cddb_http_submit(cd_desc, list.list_host[i], proxyptr, email) < 0) alert("Error", "Could not submit disc data.", e->win); else alert("Submit", "Success.", e->win); free(email); } } else alert("Error", "Could not locate any HTTP servers.", e->win); WMSetButtonEnabled(self, True); e->busy--; } void LookupButton(WMWidget *self, app *a) { editor *e = a->editor; WMSetButtonEnabled(self, False); e->busy++; saveSite(e, e->last_site); if (!cddb_lookup(&e->data, e->win)) updateEntry(a, e->data); WMSetButtonEnabled(self, True); e->busy--; } void SaveEntryButton(WMWidget *self, app *a) { int i; char *tmp; cdplayer *w = a->cdplayer; editor *e = a->editor; WMSetButtonEnabled(self, False); e->busy++; saveTrack(e, e->last_track); if (cddb_erase_entry(data) < 0) alert("Error", "Could not delete old disc data.", e->win); memcpy(&data, &e->data, sizeof(struct disc_data)); strncpy(data.data_title, WMGetTextFieldText(e->txtDiscTitle), 256); strncpy(data.data_artist, WMGetTextFieldText(e->txtDiscArtist), 256); strncpy(data.data_extended, WMGetTextFieldText(e->txtDiscExtended), EXTENDED_DATA_SIZE); data.data_genre = WMGetPopUpButtonSelectedItem(e->popGenre); if (cddb_write_disc_data(cd_desc, data) < 0) alert("Error", "Could not save disc data.", e->win); WMSetButtonEnabled(self, True); e->busy--; } void SiteClick(WMWidget *self, editor *e) { char tmp[15]; int i = WMGetListSelectedItemRow(self); saveSite(e, e->last_site); WMSetPopUpButtonSelectedItem(e->popProtocol, list.list_host[i].host_protocol); WMSetTextFieldText(e->txtName, list.list_host[i].host_server.server_name); sprintf(tmp, "%d", list.list_host[i].host_server.server_port); WMSetTextFieldText(e->txtPort, tmp); WMSetTextFieldText(e->txtAddressing, list.list_host[i].host_addressing); WMSetButtonEnabled(e->btnRemove, True); e->last_site = i; } void RemoveButton(WMWidget *self, editor *e) { int i, pos; pos = WMGetListSelectedItemRow(e->lstSiteNames); for (i = pos; i != list.list_len-1; i++) memcpy(&list.list_host[i], &list.list_host[i+1], sizeof(struct cddb_host)); list.list_len--; WMRemoveListItem(e->lstSiteNames, pos); WMSetButtonEnabled(self, False); e->last_site = -1; } void AddButton(WMWidget *self, editor *e) { if (list.list_len < CDDB_MAX_SERVERS) { char *name = WMGetTextFieldText(e->txtName); WMInsertListItem(e->lstSiteNames, list.list_len, name); if (list.list_len > 9) WMSetListPosition(e->lstSiteNames, list.list_len-9); WMSelectListItem(e->lstSiteNames, list.list_len); saveSite(e, e->last_site); saveSite(e, list.list_len); e->last_site = list.list_len; list.list_len++; WMSetButtonEnabled(e->btnRemove, True); free(name); } } void RefreshButton(WMWidget *self, editor *e) { char *server; WMSetButtonEnabled(self, False); e->busy++; server = input("Refresh", "Enter server URL:", DEFAULT_SERVER, e->win); if (server != NULL) { struct cddb_host host; if (cddb_process_url(&host, server) < 0) alert("Error", "Invalid server URL.", e->win); else if (!cddb_get_siteslist(host, e->win)) updateSites(e); free(server); } WMSetButtonEnabled(self, True); e->busy--; } void SaveSitesButton(WMWidget *self, editor *e) { WMSetButtonEnabled(self, False); e->busy++; saveSite(e, e->last_site); strncpy(proxy.server_name, WMGetTextFieldText(e->txtProxyServer), 256); proxy.server_port = atoi(WMGetTextFieldText(e->txtProxyPort)); if (strlen(proxy.server_name) > 0) conf.conf_proxy = 1; else conf.conf_proxy = 0; if (cddb_write_serverlist(conf, list, proxy) < 0) alert("Error", "Could not save sites list.", e->win); WMSetButtonEnabled(self, True); e->busy--; } static void ChangedTrack(void *observerData, WMNotification *notification) { editor *e = (editor *)observerData; int i = WMGetListSelectedItemRow(e->lstTrackNames); if (i > -1) { WMTextField *t = (WMTextField *)WMGetNotificationObject(notification); WMListItem *item = WMGetListItem(e->lstTrackNames, i); char *tmp = (char *)wmalloc(strlen(WMGetTextFieldText(t))+15); sprintf(tmp, "%d. %s", i+1, WMGetTextFieldText(t)); free(item->text); item->text = tmp; WMRedisplayWidget(e->lstTrackNames); } } static void ChangedSite(void *observerData, WMNotification *notification) { editor *e = (editor *)observerData; int i = WMGetListSelectedItemRow(e->lstSiteNames); if (i > -1) { WMTextField *t = (WMTextField *)WMGetNotificationObject(notification); WMListItem *item = WMGetListItem(e->lstSiteNames, i); free(item->text); item->text = WMGetTextFieldText(t); WMRedisplayWidget(e->lstSiteNames); } } int createMatches(struct cddb_query query, WMWindow *owner) { int i; char *tmp; matches *m; m = (matches *)wmalloc(sizeof(matches)); m->done = 0; m->win = WMCreatePanelWithStyleForWindow(owner, "matches", WMTitledWindowMask | WMClosableWindowMask); WMSetWindowTitle(m->win, "Matches"); WMSetWindowCloseAction(m->win, (WMAction *)CloseMatches, m); WMSetWindowMinSize(m->win, 400, 150); WMSetWindowMaxSize(m->win, 400, 150); WMResizeWidget(m->win, 400, 150); m->lstMatches = WMCreateList(m->win); WMResizeWidget(m->lstMatches, 380, 94); WMMoveWidget(m->lstMatches, 10, 10); for (i = 0; i != query.query_matches; i++) { tmp = (char *)wmalloc(strlen(query.query_list[i].list_artist)+ strlen(query.query_list[i].list_title)+4); if (strlen(query.query_list[i].list_artist) < 1) strcpy(tmp, query.query_list[i].list_title); else sprintf(tmp, "%s / %s", query.query_list[i].list_artist, query.query_list[i].list_title); WMAddListItem(m->lstMatches, tmp); free(tmp); } WMSetListAction(m->lstMatches, (WMAction *)MatchClick, m); WMSetListDoubleAction(m->lstMatches, (WMAction *)MatchSelect, m); m->btnOK = WMCreateCommandButton(m->win); WMResizeWidget(m->btnOK, 80, 26); WMMoveWidget(m->btnOK, 310, 114); WMSetButtonText(m->btnOK, "OK"); WMSetButtonEnabled(m->btnOK, False); WMSetButtonAction(m->btnOK, (WMAction *)MatchSelect, m); WMRealizeWidget(m->win); WMMapSubwidgets(m->win); WMMapWidget(m->win); while (!m->done) { XEvent event; WMNextEvent(dpy, &event); WMHandleEvent(&event); } WMUnmapWidget(m->win); WMDestroyWidget(m->win); i = m->selection; free(m); return i; } void CloseMatches(WMWidget *self, matches *m) { m->selection = -1; m->done = 1; } void MatchClick(WMWidget *self, matches *m) { WMSetButtonEnabled(m->btnOK, True); } void MatchSelect(WMWidget *self, matches *m) { m->selection = WMGetListSelectedItemRow(m->lstMatches); m->done = 1; } int cddb_lookup(struct disc_data *outdata, WMWindow *owner) { int i, selection, sock; struct cddb_entry entry; struct cddb_hello hello; struct cddb_query query; struct cddb_server *proxyptr; char http_string[512], discid[CDINDEX_ID_SIZE]; if (list.list_len < 1) { alert("Error", "No servers available.", owner); return -1; } strncpy(hello.hello_program, PROGRAM_NAME, 256); strncpy(hello.hello_version, PROGRAM_VERSION, 256); if (conf.conf_proxy) proxyptr = &proxy; else proxyptr = NULL; i = 0; sock = -1; while (i < list.list_len && sock < 0) { switch (list.list_host[i].host_protocol) { case CDDB_MODE_CDDBP: sock = cddb_connect_server(list.list_host[i], proxyptr, hello); break; case CDDB_MODE_HTTP: sock = cddb_connect_server(list.list_host[i], proxyptr, hello, http_string, 512); break; case CDINDEX_MODE_HTTP: sock = cdindex_connect_server(list.list_host[i], proxyptr, http_string, 512); break; } i++; } if (sock < 0) { alert("Error", "Could not connect to server.", owner); return -1; } i--; switch (list.list_host[i].host_protocol) { case CDDB_MODE_CDDBP: if (cddb_query(cd_desc, sock, CDDB_MODE_CDDBP, &query) < 0) { alert("Error", "Could not query disc.", owner); return -1; } break; case CDDB_MODE_HTTP: if (cddb_query(cd_desc, sock, CDDB_MODE_HTTP, &query, http_string) < 0) { alert("Error", "Could not query disc.", owner); return -1; } shutdown(sock, 2); close(sock); if ((sock = cddb_connect_server(list.list_host[i], proxyptr, hello, http_string, 512)) < 0) { alert("Error", "Could not reconnect to HTTP server.", owner); return -1; } break; case CDINDEX_MODE_HTTP: cdindex_discid(cd_desc, discid, CDINDEX_ID_SIZE); if (cdindex_read(cd_desc, sock, outdata, http_string) < 0) { alert("Error", "No match in CD Index server.", owner); return -1; } return 0; } switch (query.query_match) { case QUERY_EXACT: selection = 0; break; case QUERY_INEXACT: selection = createMatches(query, owner); break; case QUERY_NOMATCH: alert("Error", "No match in CDDB server.", owner); return -1; } if (selection > -1) { entry.entry_genre = query.query_list[selection].list_genre; entry.entry_id = query.query_list[selection].list_id; switch (list.list_host[i].host_protocol) { case CDDB_MODE_CDDBP: if (cddb_read(cd_desc, sock, CDDB_MODE_CDDBP, entry, outdata) < 0) { alert("Error", "Could not read disc data from server.", owner); return -1; } cddb_quit(sock); break; case CDDB_MODE_HTTP: if (cddb_read(cd_desc, sock, CDDB_MODE_HTTP, entry, outdata, http_string) < 0) { alert("Error", "Could not read disc data from server.", owner); return -1; } shutdown(sock, 2); close(sock); break; } return 0; } return -1; } int cddb_get_siteslist(struct cddb_host host, WMWindow *owner) { int sock; char http_string[512]; struct cddb_hello hello; struct cddb_server *proxyptr; strncpy(hello.hello_program, PROGRAM_NAME, 256); strncpy(hello.hello_version, PROGRAM_VERSION, 256); if (conf.conf_proxy) proxyptr = &proxy; else proxyptr = NULL; switch (host.host_protocol) { case CDDB_MODE_CDDBP: if ((sock = cddb_connect_server(host, proxyptr, hello)) < 0) { alert("Error", "Could not connect to server.", owner); return -1; } if (cddb_sites(sock, CDDB_MODE_CDDBP, &list) < 0) { alert("Error", "Could not get sites list from server.", owner); return -1; } break; case CDDB_MODE_HTTP: if ((sock = cddb_connect_server(host, proxyptr, hello, http_string, 512)) < 0) { alert("Error", "Could not connect to server.", owner); return -1; } if (cddb_sites(sock, CDDB_MODE_HTTP, &list, http_string) < 0) { alert("Error", "Could not get sites list from server.", owner); return -1; } break; } return 0; } void createMiniWindow(int argc, char **argv) { xRootWindow = RootWindow(dpy, DefaultScreen(dpy)); xForePixel = WhitePixel(dpy, DefaultScreen(dpy)); xBackPixel = BlackPixel(dpy, DefaultScreen(dpy)); WindowGroupLeader = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 48, 48, 0, 0, 0); IconWindow = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 48, 48, 0, 0, 0); /* set hints for class of windows */ classHints = XAllocClassHint(); classHints->res_name = "groupLeader"; classHints->res_class = "CDPlayer"; XSetClassHint(dpy, WindowGroupLeader, classHints); XFree(classHints); /* set window manager's hint to windows' leader */ loadIcon(&AppIcon, appicon_xpm); wmHints = XAllocWMHints(); wmHints->icon_pixmap = AppIcon.IconPixmap; wmHints->icon_window = IconWindow; wmHints->window_group = WindowGroupLeader; wmHints->flags = IconPixmapHint | IconWindowHint | IconPositionHint | WindowGroupHint; XSetWMHints(dpy, WindowGroupLeader, wmHints); XFree(wmHints); XSetCommand(dpy, WindowGroupLeader, argv, argc); /* for getting ButtonPress and ButtonRelease event by miniwindow */ XSelectInput(dpy, IconWindow, ButtonPress | ButtonReleaseMask | ExposureMask); createGC(); loadIcon(&MiniMaskBlank, mask_xpm); loadIcon(&MiniMask, mask_xpm); miniInitAction(); loadIcon(&MiniPlayButtonActive, play_sel_xpm); loadIcon(&MiniStopButtonActive, stop_sel_xpm); loadIcon(&MiniPauseButtonActive, pause_sel_xpm); loadIcon(&MiniBackButtonActive, back_sel_xpm); loadIcon(&MiniForwardButtonActive, forward_sel_xpm); loadIcon(&MiniEjectButtonActive, eject_sel_xpm); XShapeCombineMask(dpy, IconWindow, ShapeBounding, 0, 0, MiniMask.IconMask, ShapeSet); redrawMiniWindow(&MiniMask); } void loadIcon(Icon *IconXpm, char **icon_xpm) { int ret; IconXpm->IconAttributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions); ret = XpmCreatePixmapFromData(dpy, xRootWindow, icon_xpm, &IconXpm->IconPixmap, &IconXpm->IconMask, &IconXpm->IconAttributes); if (ret != XpmSuccess) { fprintf(stderr, "Not enough free color cells.\n"); exit(1); } } void createGC(void) { Font TrackNumberFont; TrackNumberFont = XLoadFont(dpy, "-Adobe-Helvetica-Bold-R-Normal--12-120-75-75-P-70-*-*"); GCValueMask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; GCValues.foreground = xForePixel; GCValues.background = xBackPixel; GCValues.font = TrackNumberFont; GCValues.graphics_exposures = 0; MiniWindowGC = XCreateGC(dpy, IconWindow, GCValueMask, &GCValues); } void drawIcon(Icon *IconXpm, int x, int y) { XCopyArea(dpy, IconXpm->IconPixmap, MiniMask.IconPixmap, MiniWindowGC, 0, 0, IconXpm->IconAttributes.width, IconXpm->IconAttributes.height, x, y); } void redrawMiniWindow(Icon *IconXpm) { XEvent event; XCopyArea(dpy, IconXpm->IconPixmap, IconWindow, MiniWindowGC, 0, 0, IconXpm->IconAttributes.width, IconXpm->IconAttributes.height, 0, 0); while (XCheckTypedWindowEvent(dpy, IconWindow, Expose, &event)); } void redrawTrackNumber(cdplayer *w) { char tmp[15]; sprintf(tmp, "%d", w->play_track); if (w->play_track < 10) XDrawString(dpy, MiniMask.IconPixmap, MiniWindowGC, 21, 42, tmp, strlen(tmp)); else XDrawString(dpy, MiniMask.IconPixmap, MiniWindowGC, 18, 42, tmp, strlen(tmp)); redrawMiniWindow(&MiniMask); } int whichMiniButton(int x, int y) { if (x > 2 && x < 11 && y > 0 && y < 8) return 0; if (x > 18 && x < 29 && y > 0 && y < 8) return 1; if (x > 36 && x < 45 && y > 0 && y < 8) return 2; if (x > 1 && x < 12 && y > 12 && y < 21) return 3; if (x > 18 && x < 29 && y > 12 && y < 21) return 4; if (x > 36 && x < 45 && y > 12 && y < 21) return 5; return -1; } void checkMiniButtons(XEvent Event, cdplayer *w) { switch (Event.type) { case ButtonPress: if (Event.xbutton.window == IconWindow) { w->button_pressed = 1; w->mini_button = whichMiniButton(Event.xbutton.x, Event.xbutton.y); if (w->disc_present) { switch (w->mini_button) { case 2: if (!stopped()) miniStopAction(w); break; case 3: if (w->total_tracks > 1) miniBackAction(w); break; case 4: if (w->total_tracks > 1) miniForwardAction(w); break; } } } break; case ButtonRelease: if (Event.xbutton.window == IconWindow) { w->button_pressed = 0; if (w->mini_button == whichMiniButton(Event.xbutton.x, Event.xbutton.y)) { switch (w->mini_button) { case 0: PlayButton(w->btnPlay, w); break; case 1: PauseButton(w->btnPause, w); break; case 2: StopButton(w->btnStop, w); break; case 3: PrevButton(w->btnPrev, w); break; case 4: NextButton(w->btnNext, w); break; case 5: EjectButton(w->btnEject, w); break; } } else { if (w->disc_present) { switch (disc.disc_mode) { case CDAUDIO_PLAYING: miniPlayAction(w); break; case CDAUDIO_PAUSED: miniPauseAction(w); break; default: miniInitAction(); redrawTrackNumber(w); break; } } else { if (w->tray_open) miniEjectAction(); else redrawMiniWindow(&MiniMask); } } } break; case Expose: redrawMiniWindow(&MiniMask); break; } } void miniInitAction(void) { XCopyArea(dpy, MiniMaskBlank.IconPixmap, MiniMask.IconPixmap, MiniWindowGC, 0, 0, MiniMaskBlank.IconAttributes.width, MiniMaskBlank.IconAttributes.height, 0, 0); } void miniPlayAction(cdplayer *w) { miniInitAction(); drawIcon(&MiniPlayButtonActive, 3, 0); redrawTrackNumber(w); } void miniStopAction(cdplayer *w) { miniInitAction(); drawIcon(&MiniStopButtonActive, 37, 0); redrawTrackNumber(w); } void miniPauseAction(cdplayer *w) { miniInitAction(); drawIcon(&MiniPauseButtonActive, 19, 0); redrawTrackNumber(w); } void miniBackAction(cdplayer *w) { miniInitAction(); drawIcon(&MiniBackButtonActive, 2, 13); redrawTrackNumber(w); } void miniForwardAction(cdplayer *w) { miniInitAction(); drawIcon(&MiniForwardButtonActive, 19, 13); redrawTrackNumber(w); } void miniEjectAction(void) { miniInitAction(); drawIcon(&MiniEjectButtonActive, 37, 13); redrawMiniWindow(&MiniMask); } void createPixmaps(WMScreen *scr) { numberbtn = WMCreatePixmapFromXPMData(scr, numberbutton_xpm); numberbtnh = WMCreatePixmapFromXPMData(scr, numberbuttonh_xpm); recordbtn = WMCreatePixmapFromXPMData(scr, record_xpm); recordbtnd = WMCreatePixmapFromXPMData(scr, recordd_xpm); recordbtnh = WMCreatePixmapFromXPMData(scr, recordh_xpm); playbtn = WMCreatePixmapFromXPMData(scr, play_xpm); playbtnd = WMCreatePixmapFromXPMData(scr, playd_xpm); playbtnh = WMCreatePixmapFromXPMData(scr, playh_xpm); pausebtn = WMCreatePixmapFromXPMData(scr, pause_xpm); pausebtnd = WMCreatePixmapFromXPMData(scr, paused_xpm); pausebtnh = WMCreatePixmapFromXPMData(scr, pauseh_xpm); stopbtn = WMCreatePixmapFromXPMData(scr, stop_xpm); stopbtnd = WMCreatePixmapFromXPMData(scr, stopd_xpm); stopbtnh = WMCreatePixmapFromXPMData(scr, stoph_xpm); backbtn = WMCreatePixmapFromXPMData(scr, backtrack_xpm); backbtnd = WMCreatePixmapFromXPMData(scr, backtrackd_xpm); backbtnh = WMCreatePixmapFromXPMData(scr, backtrackh_xpm); nextbtn = WMCreatePixmapFromXPMData(scr, forwardtrack_xpm); nextbtnd = WMCreatePixmapFromXPMData(scr, forwardtrackd_xpm); nextbtnh = WMCreatePixmapFromXPMData(scr, forwardtrackh_xpm); ejectbtn = WMCreatePixmapFromXPMData(scr, eject_xpm); ejectbtnd = WMCreatePixmapFromXPMData(scr, ejectd_xpm); ejectbtnh = WMCreatePixmapFromXPMData(scr, ejecth_xpm); trackbtn[0] = WMCreatePixmapFromXPMData(scr, track1button_xpm); trackbtnh[0] = WMCreatePixmapFromXPMData(scr, track1buttonh_xpm); trackbtn[1] = WMCreatePixmapFromXPMData(scr, track2button_xpm); trackbtnh[1] = WMCreatePixmapFromXPMData(scr, track2buttonh_xpm); trackbtn[2] = WMCreatePixmapFromXPMData(scr, track3button_xpm); trackbtnh[2] = WMCreatePixmapFromXPMData(scr, track3buttonh_xpm); trackbtn[3] = WMCreatePixmapFromXPMData(scr, track4button_xpm); trackbtnh[3] = WMCreatePixmapFromXPMData(scr, track4buttonh_xpm); trackbtn[4] = WMCreatePixmapFromXPMData(scr, track5button_xpm); trackbtnh[4] = WMCreatePixmapFromXPMData(scr, track5buttonh_xpm); trackbtn[5] = WMCreatePixmapFromXPMData(scr, track6button_xpm); trackbtnh[5] = WMCreatePixmapFromXPMData(scr, track6buttonh_xpm); trackbtn[6] = WMCreatePixmapFromXPMData(scr, track7button_xpm); trackbtnh[6] = WMCreatePixmapFromXPMData(scr, track7buttonh_xpm); trackbtn[7] = WMCreatePixmapFromXPMData(scr, track8button_xpm); trackbtnh[7] = WMCreatePixmapFromXPMData(scr, track8buttonh_xpm); trackbtn[8] = WMCreatePixmapFromXPMData(scr, track9button_xpm); trackbtnh[8] = WMCreatePixmapFromXPMData(scr, track9buttonh_xpm); trackbtn[9] = WMCreatePixmapFromXPMData(scr, track10button_xpm); trackbtnh[9] = WMCreatePixmapFromXPMData(scr, track10buttonh_xpm); trackbtn[10] = WMCreatePixmapFromXPMData(scr, track11button_xpm); trackbtnh[10] = WMCreatePixmapFromXPMData(scr, track11buttonh_xpm); trackbtn[11] = WMCreatePixmapFromXPMData(scr, track12button_xpm); trackbtnh[11] = WMCreatePixmapFromXPMData(scr, track12buttonh_xpm); trackbtn[12] = WMCreatePixmapFromXPMData(scr, track13button_xpm); trackbtnh[12] = WMCreatePixmapFromXPMData(scr, track13buttonh_xpm); trackbtn[13] = WMCreatePixmapFromXPMData(scr, track14button_xpm); trackbtnh[13] = WMCreatePixmapFromXPMData(scr, track14buttonh_xpm); trackbtn[14] = WMCreatePixmapFromXPMData(scr, track15button_xpm); trackbtnh[14] = WMCreatePixmapFromXPMData(scr, track15buttonh_xpm); trackbtn[15] = WMCreatePixmapFromXPMData(scr, track16button_xpm); trackbtnh[15] = WMCreatePixmapFromXPMData(scr, track16buttonh_xpm); trackbtn[16] = WMCreatePixmapFromXPMData(scr, track17button_xpm); trackbtnh[16] = WMCreatePixmapFromXPMData(scr, track17buttonh_xpm); trackbtn[17] = WMCreatePixmapFromXPMData(scr, track18button_xpm); trackbtnh[17] = WMCreatePixmapFromXPMData(scr, track18buttonh_xpm); trackbtn[18] = WMCreatePixmapFromXPMData(scr, track19button_xpm); trackbtnh[18] = WMCreatePixmapFromXPMData(scr, track19buttonh_xpm); trackbtn[19] = WMCreatePixmapFromXPMData(scr, track20button_xpm); trackbtnh[19] = WMCreatePixmapFromXPMData(scr, track20buttonh_xpm); }