void metainput(void) /* Wait for actions in the meta-server window. * * This is really the meta-server window's own little input() function. It is * needed so we don't have to use all the bull in the main input(). Plus to * use it I'd have to call mapAll() first and the client would read in the * default server and then call it up before I can select a server. */ { W_Event data; (void) SIGNAL(SIGCHLD, sigchld); while (W_IsMapped(metaWin)) { while (1) { W_Flush(); if (W_EventsPending()) break; if (ReadMetasRecv(W_Socket()) || metareap_needed) { metareap(); metaHeight = num_servers + N_OVERHEAD; metawindow(); W_Flush(); } refresh_cyclic(); } W_NextEvent(&data); switch ((int) data.type) { case W_EV_KEY: if (data.Window == metaList || data.Window == metaWin) if (key(&data)) return; if (data.Window == metaHelpWin) hide_help(); break; case W_EV_BUTTON: if (data.Window == metaList) if (button(&data)) return; if (data.Window == metaHelpWin) hide_help(); if (data.Window == metaWin && data.y < 200) W_NextScreenShot(metaWin, 0, 0); break; case W_EV_EXPOSE: if (data.Window == metaHelpWin) expo_help(); if (data.Window == metaWin) { W_DrawScreenShot(metaWin, 0, 0); W_DrawImage(200, 9, logo); } break; case W_EV_CLOSED: if (data.Window == metaWin) { fprintf(stderr, "you quit, by closing the server list window\n"); terminate(0); } break; default: break; } } }
/*! @brief Check if a child process, a playing client, has terminated. @details Attempts a no hang wait on each active client process in the server list and clears the pid entry if a child has terminated. @return activity count, number of processes seen to have terminated. */ static int metareap(void) { struct servers *sp; int i, status, activity; pid_t pid; metareap_needed = 0; activity = 0; for (i=0;i<num_servers;i++) { sp = serverlist + i; if (sp->pid != -1) { pid = waitpid(sp->pid, &status, WNOHANG); if (pid == sp->pid) { sp->pid = -1; if (WIFEXITED(status)) { activity++; sp->exitstatus = WEXITSTATUS(status); } redraw(i); W_Flush(); } } } return activity; }
static void refresh() { W_WriteText(metaList, 0, metaHeight-B_REFRESH, W_Red, "Refresh (in progress)", -1, 0); W_NextScreenShot(metaWin, 0, 0); W_Flush(); ReadMetasSend(); }
void redraw(void) { /* erase warning line if necessary */ if ((warntimer <= udcounter && hwarncount <= udcounter) && (warncount || hwarncount)) { W_ClearWindow(warnw); } if (warntimer <= udcounter && warncount) { W_MaskText(w, center - (warncount / 2) * W_Textwidth, winside - W_Textheight - HUD_Y, backColor, warningbuf, warncount, W_RegularFont); warncount = 0; } if (hwarntimer <= udcounter && hwarncount) { W_MaskText(w, center - (hwarncount / 2) * W_Textwidth, HUD_Y, backColor, hwarningbuf, hwarncount, W_BoldFont); hwarncount = 0; } if(W_IsBuffered(w)) { /* buffered, clear the entire buffer [BDyess] */ W_ClearBuffer(w); clearcount = 0; clearlcount = 0; tractcurrent = tracthead; } else { if (W_FastClear) { W_ClearWindow(w); clearcount = 0; clearlcount = 0; tractcurrent = tracthead; } else { while (clearcount) { clearcount--; /* XFIX */ W_CacheClearArea(w, clearzone[clearcount].x, clearzone[clearcount].y, clearzone[clearcount].width, clearzone[clearcount].height); } while (clearlcount) { clearlcount--; /* XFIX */ W_CacheLine(w, clearline[0][clearlcount], clearline[1][clearlcount], clearline[2][clearlcount], clearline[3][clearlcount], backColor); } /* XFIX */ W_FlushClearAreaCache(w); W_FlushLineCaches(w); /* erase the tractor lines [BDyess] */ for (tractrunner = tracthead; tractrunner != tractcurrent; tractrunner = tractrunner->next) { W_MakeTractLine(w, tractrunner->sx, tractrunner->sy, tractrunner->d1x, tractrunner->d1y, backColor); W_MakeTractLine(w, tractrunner->sx, tractrunner->sy, tractrunner->d2x, tractrunner->d2y, backColor); } tractcurrent = tracthead; } } local(); /* redraw local window */ /* XFIX */ W_FlushLineCaches(w); stline(0); /* draw dashboard [BDyess] */ /* flush buffers [BDyess] */ W_DisplayBuffer(tstatw); /* dashboard [BDyess] */ W_DisplayBuffer(w); /* local [BDyess] */ /* would do it in W_EventsPending, just have it here so the display is updated sooner. */ W_Flush(); if (W_IsMapped(statwin)) { updateStats(); } if (W_IsMapped(newstatwin)) { updateNewStats(); } updateInform(); /* check and update info window [BDyess] */ /* XFIX: last since its least accurate information */ if (mapmode) { map(); /* write the buffered data, if any [BDyess] */ W_DisplayBuffer(mapw); } }
static int chose(int which, unsigned char key) { struct servers *sp; pid_t pid; if (which != chosen) { int was; was = chosen; chosen = which; if (was != -1) redraw(was); redraw(chosen); } sp = serverlist + which; xtrekPort = sp->port; if (key == W_RBUTTON) { /* Guess at an observer port */ xtrekPort++; fprintf(stderr, "you chose to observe on %s, guessing port %d\n", sp->address, xtrekPort); } serverName = strdup(sp->address); sp->pid = -1; sp->exitstatus = EXIT_UNKNOWN; fprintf(stderr, "you chose server %s port %d\n", serverName, xtrekPort); if ((pid = fork()) == 0) { char *args[16]; int argc = 0; setpgid(0, 0); args[argc++] = program; args[argc++] = "--server"; args[argc++] = serverName; if (xtrekPort != DEFAULT_PORT) { char port[32]; sprintf(port, "%d", xtrekPort); args[argc++] = "--port"; args[argc++] = strdup(port); } if (key == W_MBUTTON) args[argc++] = "--fast-guest"; args[argc++] = NULL; execvp(program, args); perror("execvp"); _exit(1); } /* we are the parent, did the fork fail? */ if (pid < 0) { perror("fork"); sp->exitstatus = EXIT_FORK_FAILURE; } else { sp->pid = pid; sp->observer = (key == W_RBUTTON); } redraw(which); W_Flush(); return 0; }