node *find_intersection(node *first_node_pointer, node *second_node_pointer) { node *first_tail = first_node_pointer, *second_tail = second_node_pointer; int first_length = 0, second_length = 0, i; find_tail(first_tail, first_length, first_node_pointer); find_tail(second_tail, second_length, second_node_pointer); if (first_tail != second_tail) { /* If the tails do not point to the same memory location, * then there is no intersection. If there was an intersection * both linked lists would end in the same node (they can have * different beginnings but must have the same end) */ return NULL; } if (first_length > second_length) { first_node_pointer = fast_forward( first_node_pointer, first_length - second_length ); } else { second_node_pointer = fast_forward( second_node_pointer, second_length - first_length ); } while (first_node_pointer != NULL && second_node_pointer != NULL) { if (first_node_pointer == second_node_pointer) { return first_node_pointer; } first_node_pointer = first_node_pointer->next; second_node_pointer = second_node_pointer->next; } fprintf( stderr, "Fell of the end of one of the linked lists! That should " "never happen, you made a programming error!\n" ); exit(1); }
int nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr) { int r,_status; char *orig = 0; char *str; orig = str = attr; if (!strncasecmp(str, "ice-ufrag:", 10)) { fast_forward(&str, 10); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &stream->ufrag))) ABORT(r); } else if (!strncasecmp(str, "ice-pwd:", 8)) { fast_forward(&str, 8); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &stream->pwd))) ABORT(r); } else { ABORT(R_BAD_DATA); } skip_whitespace(&str); /* RFC 5245 grammar doesn't have an extension point for ice-pwd or ice-ufrag: if there's anything left on the line, we treat it as bad. */ if (str[0] != '\0') { ABORT(R_BAD_DATA); } _status=0; abort: if (_status) { if (orig) r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig); } return(_status); }
int nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr) { int r,_status; char *orig = 0; char *str; orig = str = attr; if (!strncasecmp(str, "ice-ufrag:", 10)) { fast_forward(&str, 10); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &stream->ufrag))) ABORT(r); } else if (!strncasecmp(str, "ice-pwd:", 8)) { fast_forward(&str, 8); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &stream->pwd))) ABORT(r); } else { ABORT(R_BAD_DATA); } skip_whitespace(&str); /* it's expected to be at EOD at this point */ assert(strlen(str) == 0); _status=0; abort: if (_status) { if (orig) r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig); } return(_status); }
void task_scheduler(void) { int i; timestamp_t now; task_started = 1; while (1) { now = get_time(); i = TASK_ID_COUNT - 1; while (i >= 0) { /* * Only tasks with spawned threads are valid to be * resumed. */ if (tasks[i].thread) { if (tasks[i].event || now.val >= tasks[i].wake_time.val) break; } --i; } if (i < 0) i = fast_forward(); tasks[i].wake_time.val = ~0ull; running_task_id = i; tasks[i].started = 1; pthread_cond_signal(&tasks[i].resume); pthread_cond_wait(&scheduler_cond, &run_lock); } }
int main() { struct item *dll = create_dll(); fast_forward(&dll); ___sl_plot("03-ff-done"); return 0; }
int main() { struct item *dll = create_dll(); __VERIFIER_plot("01-before-fast-forward"); fast_forward(&dll); __VERIFIER_plot("02-after-fast-forward"); return 0; }
int nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int attr_ct) { int r,_status; int i; char *orig = 0; char *str; char *component_id; char *connection_address; unsigned int port; in_addr_t addr; char *ice_option_tag; for(i=0;i<attr_ct;i++){ orig = str = attrs[i]; component_id = 0; connection_address = 0; ice_option_tag = 0; if (!strncasecmp(str, "remote-candidates:", 18)) { fast_forward(&str, 18); skip_whitespace(&str); while (*str != '\0') { if ((r=grab_token(&str, &component_id))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &connection_address))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); addr = inet_addr(connection_address); if (addr == INADDR_NONE) ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (sscanf(str, "%u", &port) != 1) ABORT(R_BAD_DATA); if (port < 1 || port > 0x0FFFF) ABORT(R_BAD_DATA); skip_to_past_space(&str); #if 0 /* TODO: !nn! just drop on the floor for now, later put somewhere */ /* Assume v4 for now */ if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&candidate->base)) ABORT(r); TAILQ_INSERT_TAIL(head, elm, field); #endif component_id = 0; /* prevent free */ RFREE(connection_address); connection_address = 0; /* prevent free */ } } else if (!strncasecmp(str, "ice-lite", 8)) { pctx->peer_lite = 1; fast_forward(&str, 8); } else if (!strncasecmp(str, "ice-mismatch", 12)) { pctx->peer_ice_mismatch = 1; fast_forward(&str, 12); } else if (!strncasecmp(str, "ice-ufrag:", 10)) { fast_forward(&str, 10); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &pctx->peer_ufrag))) ABORT(r); } else if (!strncasecmp(str, "ice-pwd:", 8)) { fast_forward(&str, 8); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &pctx->peer_pwd))) ABORT(r); } else if (!strncasecmp(str, "ice-options:", 12)) { fast_forward(&str, 12); skip_whitespace(&str); while (*str != '\0') { if ((r=grab_token(&str, &ice_option_tag))) ABORT(r); skip_whitespace(&str); #if 0 //TODO: !nn! for now, just drop on the floor, later put somewhere #endif ice_option_tag = 0; /* prevent free */ } } else { ABORT(R_BAD_DATA); } skip_whitespace(&str); /* it's expected to be at EOD at this point */ assert(strlen(str) == 0); } _status=0; abort: if (_status) { if (orig) r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig); } RFREE(connection_address); RFREE(component_id); RFREE(ice_option_tag); return(_status); }
int nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_stream *stream,nr_ice_candidate **candp) { int r,_status; char* str = orig; nr_ice_candidate *cand; char *connection_address=0; unsigned int port; in_addr_t addr; int i; unsigned int component_id; char *rel_addr=0; if(!(cand=RCALLOC(sizeof(nr_ice_candidate)))) ABORT(R_NO_MEMORY); if(!(cand->label=r_strdup(orig))) ABORT(R_NO_MEMORY); cand->ctx=ctx; cand->isock=0; cand->state=NR_ICE_CAND_PEER_CANDIDATE; cand->stream=stream; skip_whitespace(&str); /* Candidate attr */ if (strncasecmp(str, "candidate:", 10)) ABORT(R_BAD_DATA); fast_forward(&str, 10); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* Foundation */ if ((r=grab_token(&str, &cand->foundation))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* component */ if (sscanf(str, "%u", &component_id) != 1) ABORT(R_BAD_DATA); if (component_id < 1 || component_id > 256) ABORT(R_BAD_DATA); cand->component_id = (UCHAR)component_id; skip_to_past_space(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* Protocol */ if (strncasecmp(str, "UDP", 3)) ABORT(R_BAD_DATA); fast_forward(&str, 3); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* priority */ if (sscanf(str, "%u", &cand->priority) != 1) ABORT(R_BAD_DATA); if (cand->priority < 1) ABORT(R_BAD_DATA); skip_to_past_space(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* Peer address/port */ if ((r=grab_token(&str, &connection_address))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); addr = inet_addr(connection_address); if (addr == INADDR_NONE) ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (sscanf(str, "%u", &port) != 1) ABORT(R_BAD_DATA); if (port < 1 || port > 0x0FFFF) ABORT(R_BAD_DATA); /* Assume v4 for now */ if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&cand->addr)) ABORT(r); skip_to_past_space(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* Type */ if (strncasecmp("typ", str, 3)) ABORT(R_BAD_DATA); fast_forward(&str, 3); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); assert(nr_ice_candidate_type_names[0] == 0); for (i = 1; nr_ice_candidate_type_names[i]; ++i) { if(!strncasecmp(nr_ice_candidate_type_names[i], str, strlen(nr_ice_candidate_type_names[i]))) { cand->type=i; break; } } if (nr_ice_candidate_type_names[i] == 0) ABORT(R_BAD_DATA); fast_forward(&str, strlen(nr_ice_candidate_type_names[i])); /* Look for the other side's raddr, rport */ /* raddr, rport */ switch (cand->type) { case HOST: break; case SERVER_REFLEXIVE: case PEER_REFLEXIVE: case RELAYED: skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (strncasecmp("raddr", str, 5)) ABORT(R_BAD_DATA); fast_forward(&str, 5); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &rel_addr))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); addr = inet_addr(rel_addr); if (addr == INADDR_NONE) ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (strncasecmp("rport", str, 5)) ABORT(R_BAD_DATA); fast_forward(&str, 5); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (sscanf(str, "%u", &port) != 1) ABORT(R_BAD_DATA); if (port < 1 || port > 0x0FFFF) ABORT(R_BAD_DATA); /* Assume v4 for now */ if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&cand->base)) ABORT(r); skip_to_past_space(&str); /* it's expected to be at EOD at this point */ break; default: ABORT(R_INTERNAL); break; } skip_whitespace(&str); assert(strlen(str) == 0); *candp=cand; _status=0; abort: if (_status) r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Error parsing attribute: %s",ctx->label,orig); RFREE(connection_address); RFREE(rel_addr); return(_status); }
/* * _bitmap_union() -- union 'numBatches' bitmaps * * All bitmap words are HRL compressed. The result bitmap words are also * HRL compressed, except that fill unset words may be lossily compressed. */ void _bitmap_union(BMBatchWords **batches, uint32 numBatches, BMBatchWords *result) { bool done = false; uint32 *prevstarts; uint64 nextReadNo; uint64 batchNo; Assert ((int)numBatches >= 0); if (numBatches == 0) return; /* save batch->startNo for each input bitmap vector */ prevstarts = (uint32 *)palloc0(numBatches * sizeof(uint32)); /* * Compute the next read offset. We fast forward compressed * zero words when possible. */ nextReadNo = fast_forward(numBatches, batches, result); while (!done && result->nwords < result->maxNumOfWords) { BM_HRL_WORD orWord = LITERAL_ALL_ZERO; BM_HRL_WORD word; bool orWordIsLiteral = true; for (batchNo = 0; batchNo < numBatches; batchNo++) { BMBatchWords *bch = batches[batchNo]; /* skip nextReadNo - nwordsread - 1 words */ _bitmap_findnextword(bch, nextReadNo); if (bch->nwords == 0) { done = true; break; } Assert(bch->nwordsread == nextReadNo - 1); /* Here, startNo should point to the word to be read. */ word = bch->cwords[bch->startNo]; if (CUR_WORD_IS_FILL(bch) && GET_FILL_BIT(word) == 1) { /* Fill word represents matches */ bch->nwordsread += FILL_LENGTH(word); orWord = BM_MAKE_FILL_WORD(1, bch->nwordsread - nextReadNo + 1); orWordIsLiteral = false; nextReadNo = bch->nwordsread + 1; bch->startNo++; bch->nwords--; break; } else if (CUR_WORD_IS_FILL(bch) && GET_FILL_BIT(word) == 0) { /* Fill word represents no matches */ bch->nwordsread++; prevstarts[batchNo] = bch->startNo; if (FILL_LENGTH(word) == 1) { bch->startNo++; bch->nwords--; } else bch->cwords[bch->startNo]--; orWordIsLiteral = true; } else if (!CUR_WORD_IS_FILL(bch)) { /* word is literal */ prevstarts[batchNo] = bch->startNo; orWord |= word; bch->nwordsread++; bch->startNo++; bch->nwords--; orWordIsLiteral = true; } } if (done) { uint32 i; /* reset the attributes before batchNo */ for (i = 0; i < batchNo; i++) _bitmap_resetWord(batches[i], prevstarts[i]); break; } else { if (!orWordIsLiteral) { /* Word is not literal, update the result header */ uint32 offs = result->nwords/BM_HRL_WORD_SIZE; uint32 n = result->nwords; result->hwords[offs] |= WORDNO_GET_HEADER_BIT(n); } result->cwords[result->nwords] = orWord; result->nwords++; } if (orWordIsLiteral) nextReadNo++; /* we just processed the last batch and it was empty */ if (batchNo == numBatches - 1 && batches[batchNo]->nwords == 0) done = true; } /* set the next word to read for all input vectors */ for (batchNo = 0; batchNo < numBatches; batchNo++) batches[batchNo]->nextread = nextReadNo; pfree(prevstarts); }
int main(int argc, char *argv[]) { char inkey=0, *prgdir, *curdir, *program_name; bool ext, validcfg, quit = false, bkgply = false, batchply = false; unsigned int opt, prgdrive, i; CWindow *focus; #ifdef DEBUG f_log = fopen(DEBUG_FILE,"wt"); #endif std::cout << ADPLAYVERS << ", Copyright (c) 2000 - 2006 Simon Peter <*****@*****.**>" << std::endl << std::endl; // check that no other instance is running { char *adplayenv = getenv("ADPLAY"); if(adplayenv && !strcmp(adplayenv,"S")) { std::cout << "AdPlay already running!" << std::endl; exit(EXIT_FAILURE); } else setenv("ADPLAY","S",1); // flag our instance } // Build program executable name program_name = strrchr(argv[0], '\\') ? strrchr(argv[0], '\\') + 1 : argv[0]; CAdPlug::debug_output("debug.log"); // Redirect AdPlug's debug to file // Build path to default configuration file (in program's directory) SPLITPATH(argv[0],configfile,configfile+2,NULL,NULL); strcat(configfile,CONFIGFILE); loadconfig(configfile,DEFCONFIG); // load default configuration // parse commandline for general options while((opt = getopt(argc,argv))) switch(opt) { case 1: // display help case 2: std::cout << "Usage: " << program_name << " [options]" << std::endl << std::endl; std::cout << "Options can be set with '-' or '/' respectively." << std::endl << std::endl; std::cout << " -?, -h Display commandline help" << std::endl << " -p port Set OPL2 port" << std::endl << " -o Force OPL2 port" << std::endl << " -f file Use alternate configuration file" << std::endl << " -c section Load another configuration section" << std::endl << " -b file Immediate background playback using " << "specified file" << std::endl << " -q files Immediate (batch mode) playback using " << "specified files" << std::endl; showcursor(); exit(EXIT_SUCCESS); case 3: // set OPL2 port opl.setport(atoi(argv[myoptind++])); break; case 4: // force OPL2 port oplforce = true; break; case 7: // background playback bkgply = true; break; case 8: // batch mode playback batchply = true; break; } // Bail out if OPL2 not detected and not force if(!opl.detect() && !oplforce) { std::cout << "No OPL2 detected!" << std::endl; showcursor(); exit(EXIT_FAILURE); } // Hand our database to AdPlug CAdPlug::set_database(&mydb); /*** Background playback mode ***/ if(bkgply) if(!(p = CAdPlug::factory(argv[myoptind],&opl))) { std::cout << "[" << argv[myoptind] << "]: unsupported file type!" << std::endl; exit(EXIT_FAILURE); } else { std::cout << "Background playback... (type EXIT to stop)" << std::endl; #ifdef HAVE_WCC_TIMER_H tmInit(poll_player,0xffff,DEFSTACK); #elif defined HAVE_GCC_TIMER_H timer_init(poll_player); #endif dopoll = true; #ifdef __WATCOMC__ _heapshrink(); #endif system(getenv("COMSPEC")); #ifdef HAVE_WCC_TIMER_H tmClose(); #elif defined HAVE_GCC_TIMER_H timer_deinit(); #endif stop(); exit(EXIT_SUCCESS); } /*** Batch playback mode ***/ if(batchply) { #ifdef HAVE_WCC_TIMER_H tmInit(poll_player,0xffff,DEFSTACK); #elif defined HAVE_GCC_TIMER_H timer_init(poll_player); #endif for(i = myoptind; i < argc; i++) if(!(p = CAdPlug::factory(argv[i],&opl))) { std::cout << "[" << argv[i] << "]: unsupported file type!" << std::endl; #ifdef HAVE_WCC_TIMER_H tmClose(); #elif defined HAVE_GCC_TIMER_H timer_deinit(); #endif exit(EXIT_FAILURE); } else { dopoll = firsttime = true; std::cout << "Playing [" << argv[i] << "] ..." << std::endl; while(firsttime) ; // busy waiting stop(); dopoll = false; } #ifdef HAVE_WCC_TIMER_H tmClose(); #elif defined HAVE_GCC_TIMER_H timer_deinit(); #endif exit(EXIT_SUCCESS); } /*** interactive (GUI) mode ***/ getvideoinfo(&dosvideo); // Save previous video state // register our windows with the window manager wnds.reg(titlebar); wnds.reg(filesel); wnds.reg(songwnd); wnds.reg(instwnd); wnds.reg(volbars); wnds.reg(mastervol); wnds.reg(infownd); // load default GUI layout validcfg = loadcolors(configfile,DEFCONFIG); // reparse commandline for GUI options myoptind = 1; // reset option parser while((opt = getopt(argc,argv))) switch(opt) { case 5: // set config file strcpy(configfile,argv[myoptind++]); if(loadcolors(configfile,DEFCONFIG)) validcfg = true; break; case 6: // load config section loadcolors(configfile,argv[myoptind++]); break; } // bail out if no configfile could be loaded if(!validcfg) { std::cout << "No valid default GUI layout could be loaded!" << std::endl; exit(EXIT_FAILURE); } // init GUI if((tmpfn = TEMPNAM(getenv("TEMP"),"_AP"))) #ifdef __WATCOMC__ mkdir(tmpfn); #else mkdir(tmpfn, S_IWUSR); #endif prgdir = getcwd(NULL, PATH_MAX); _dos_getdrive(&prgdrive); setadplugvideo(); #ifdef HAVE_WCC_TIMER_H tmInit(poll_player,0xffff,DEFSTACK); #elif defined HAVE_GCC_TIMER_H timer_init(poll_player); #endif songwnd.setcaption("Song Info"); volbars.setcaption("VBars"); titlebar.setcaption(ADPLAYVERS); filesel.setcaption("Directory"); mastervol.setcaption("Vol"); filesel.refresh(); mastervol.set(63); display_help(infownd); filesel.setfocus(); reset_windows(); // main loop do { if(p) { // auto-update windows // wait_retrace(); idle_ms(1000/70); refresh_songinfo(songwnd); refresh_volbars(volbars,opl); if(onsongend && !firsttime) { // song ended switch(onsongend) { case 1: // auto-rewind dopoll = false; while(inpoll) ; // critical section... p->rewind(subsong); last_ms = time_ms = 0.0f; dopoll = true; // ...End critical section break; case 2: // stop playback stop(); reset_windows(); break; } } } // Check for keypress and read in, if any if(kbhit()) { if(!(inkey = toupper(getch()))) { ext = true; inkey = toupper(getch()); } else ext = false; focus = CWindow::getfocus(); // cache focused window dbg_printf("main(): Key pressed: %d %s\n", inkey, ext ? "(Ext)" : "(Norm)"); } else inkey = 0; if(ext) // handle all extended keys switch(inkey) { case 15: // [Shift]+[TAB] - Back cycle windows window_cycle(true); break; case 59: // [F1] - display help display_help(infownd); infownd.setfocus(); wnds.update(); break; case 60: // [F2] - change screen layout curdir = getcwd(NULL, PATH_MAX); chdir(prgdir); select_colors(); chdir(curdir); free(curdir); clearscreen(backcol); filesel.refresh(); wnds.update(); break; case 72: // [Up Arrow] - scroll up if(focus == &filesel) { filesel.select_prev(); filesel.update(); } else if(focus == &infownd) { infownd.scroll_up(); infownd.update(); } else if(focus == &instwnd) { instwnd.scroll_up(); instwnd.update(); } break; case 80: // [Down Arrow] - scroll down if(focus == &filesel) { filesel.select_next(); filesel.update(); } else if(focus == &infownd) { infownd.scroll_down(); infownd.update(); } else if(focus == &instwnd) { instwnd.scroll_down(); instwnd.update(); } break; case 75: // [Left Arrow] - previous subsong if(p && subsong) { subsong--; dopoll = false; while(inpoll) ; // critical section... totaltime = p->songlength(subsong); p->rewind(subsong); last_ms = time_ms = 0.0f; dopoll = true; // ...End critical section } break; case 77: // [Right Arrow] - next subsong if(p && subsong < p->getsubsongs()-1) { subsong++; dopoll = false; while(inpoll) ; // critical section... totaltime = p->songlength(subsong); p->rewind(subsong); last_ms = time_ms = 0.0f; dopoll = true; // ...End critical section } break; case 73: // [Page Up] - scroll up half window if(focus == &filesel) { filesel.select_prev(filesel.getsizey() / 2); filesel.update(); } else if(focus == &infownd) { infownd.scroll_up(infownd.getsizey() / 2); infownd.update(); } else if(focus == &instwnd) { instwnd.scroll_up(instwnd.getsizey() / 2); instwnd.update(); } break; case 81: // [Page Down] - scroll down half window if(focus == &filesel) { filesel.select_next(filesel.getsizey() / 2); filesel.update(); } else if(focus == &infownd) { infownd.scroll_down(infownd.getsizey() / 2); infownd.update(); } else if(focus == &instwnd) { instwnd.scroll_down(instwnd.getsizey() / 2); instwnd.update(); } break; case 71: // [Home] - scroll to start if(focus == &filesel) { filesel.setselection(0); filesel.update(); } else if(focus == &infownd) { infownd.scroll_set(0); infownd.update(); } else if(focus == &instwnd) { instwnd.scroll_set(0); instwnd.update(); } break; case 79: // [End] - scroll to end if(focus == &filesel) { filesel.setselection(0xffff); filesel.update(); } else if(focus == &infownd) { infownd.scroll_set(0xffff); infownd.update(); } else if(focus == &instwnd) { instwnd.scroll_set(0xffff); instwnd.update(); } break; } else // handle all normal keys switch(inkey) { case 9: // [TAB] - Cycle through windows window_cycle(); break; case 13: // [Return] - Activate if(focus == &filesel) activate(); break; case 27: // [ESC] - Stop music / Exit to DOS if(p) { stop(); reset_windows(); } else quit = true; break; case ' ': // [Space] - fast forward fast_forward(FF_MSEC); break; case 'M': // refresh song info refresh_songdesc(infownd); break; case 'D': // shell to DOS dosshell(getenv("COMSPEC")); filesel.refresh(); wnds.update(); break; case '+': // [+] - Increase volume adjust_volume(-1); break; case '-': // [-] - Decrease volume adjust_volume(+1); break; } } while(!quit); // deinit #ifdef HAVE_WCC_TIMER_H tmClose(); #elif defined HAVE_GCC_TIMER_H timer_deinit(); #endif stop(); setvideoinfo(&dosvideo); { unsigned int dummy; _dos_setdrive(prgdrive, &dummy); } chdir(prgdir); free(prgdir); if(tmpfn) { rmdir(tmpfn); free(tmpfn); } #ifdef DEBUG dbg_printf("main(): clean shutdown.\n"); fclose(f_log); #endif return EXIT_SUCCESS; }