static void headersAction(Widget w, XtPointer client_data, XtPointer call_data) { uschar buffer[256]; header_line *h, *next; Widget text = text_create(US client_data, text_depth); void *reset_point; w = w; /* Keep picky compilers happy */ call_data = call_data; /* Remember the point in the dynamic store so we can recover to it afterwards. Then use Exim's function to read the header. */ reset_point = store_get(0); sprintf(CS buffer, "%s-H", US client_data); if (spool_read_header(buffer, TRUE, FALSE) != spool_read_OK) { if (errno == ERRNO_SPOOLFORMAT) { struct stat statbuf; sprintf(CS big_buffer, "%s/input/%s", spool_directory, buffer); if (Ustat(big_buffer, &statbuf) == 0) text_showf(text, "Format error in spool file %s: size=%d\n", buffer, statbuf.st_size); else text_showf(text, "Format error in spool file %s\n", buffer); } else text_showf(text, "Read error for spool file %s\n", buffer); store_reset(reset_point); return; } if (sender_address != NULL) { text_showf(text, "%s sender: <%s>\n", f.sender_local ? "Local" : "Remote", sender_address); } if (recipients_list != NULL) { int i; text_show(text, US"Recipients:\n"); for (i = 0; i < recipients_count; i++) { text_showf(text, " %s %s\n", (tree_search(tree_nonrecipients, recipients_list[i].address) == NULL)? " ":"*", recipients_list[i].address); } text_show(text, US"\n"); } for (h = header_list; h != NULL; h = next) { next = h->next; text_showf(text, "%c ", h->type); /* Don't push h->text through a %s */ text_show(text, h->text); /* expansion as it may be v large */ } store_reset(reset_point); }
/** @copydoc popup_struct::draw_func */ static int popup_draw_func(popup_struct *popup) { if (popup->redraw) { SDL_Rect box; surface_show(popup->surface, 0, 0, NULL, texture_surface(popup->texture)); /* Draw the book name. */ box.w = BOOK_TITLE_WIDTH; box.h = BOOK_TITLE_HEIGHT; text_show(popup->surface, FONT_SERIF16, book_name, BOOK_TITLE_STARTX, BOOK_TITLE_STARTY, COLOR_HGOLD, TEXT_WORD_WRAP | TEXT_MARKUP | TEXT_ALIGN_CENTER, &box); /* Draw the content. */ box.w = BOOK_TEXT_WIDTH; box.h = BOOK_TEXT_HEIGHT; box.y = book_scroll; text_color_set(0, 0, 255); text_set_selection(&popup->selection_start, &popup->selection_end, &popup->selection_started); text_show(popup->surface, FONT_ARIAL11, book_content, BOOK_TEXT_STARTX, BOOK_TEXT_STARTY, COLOR_BLACK, TEXT_WORD_WRAP | TEXT_MARKUP | TEXT_LINES_SKIP, &box); text_set_selection(NULL, NULL, NULL); popup->redraw = 0; } return 1; }
static void msglogAction(Widget w, XtPointer client_data, XtPointer call_data) { int i; Widget text = text_create(US client_data, text_depth); uschar * fname = NULL; FILE * f = NULL; w = w; /* Keep picky compilers happy */ call_data = call_data; /* End up with the split version, so message looks right when non-exist */ for (i = 0; i < (spool_is_split ? 2:1); i++) { message_subdir[0] = i != 0 ? (US client_data)[5] : 0; fname = spool_fname(US"msglog", message_subdir, US client_data, US""); if ((f = fopen(CS fname, "r"))) break; } if (!f) text_showf(text, "%s: %s\n", fname, strerror(errno)); else { uschar buffer[256]; while (Ufgets(buffer, sizeof(buffer), f) != NULL) text_show(text, buffer); fclose(f); } }
void text_showf(Widget w, char *s, ...) { va_list ap; uschar buffer[1024]; va_start(ap, s); vsprintf(CS buffer, s, ap); va_end(ap); text_show(w, buffer); }
static void bodyAction(Widget w, XtPointer client_data, XtPointer call_data) { int i; Widget text = text_create(US client_data, text_depth); FILE *f = NULL; w = w; /* Keep picky compilers happy */ call_data = call_data; for (i = 0; i < (spool_is_split? 2:1); i++) { uschar * fname; message_subdir[0] = i != 0 ? (US client_data)[5] : 0; fname = spool_fname(US"input", message_subdir, US client_data, US"-D"); if ((f = fopen(CS fname, "r"))) break; } if (f == NULL) text_showf(text, "Failed to open file: %s\n", strerror(errno)); else { uschar buffer[256]; int count = 0; while (Ufgets(buffer, sizeof(buffer), f) != NULL) { text_show(text, buffer); count += Ustrlen(buffer); if (count > body_max) { text_show(text, US"\n*** Message length exceeds BODY_MAX ***\n"); break; } } fclose(f); } }
/** * Render a button. * @param button * Button to render. * @param text * Optional text to render. */ void button_show(button_struct *button, const char *text) { SDL_Surface *texture; (void) button_need_redraw(button); if (button->pressed_forced) { button->pressed = 1; } texture = texture_surface(button_determine_texture(button)); surface_show(button->surface, button->x, button->y, NULL, texture); if (text) { const char *color, *color_shadow; int x, y; if (button->disabled) { color = COLOR_GRAY; color_shadow = COLOR_BLACK; } else if (button->mouse_over) { color = button->color_over; color_shadow = button->color_over_shadow; } else { color = button->color; color_shadow = button->color_shadow; } x = button->x; y = button->y; if (button->center) { x += texture->w / 2 - text_get_width(button->font, text, button->flags) / 2; y += texture->h / 2 - FONT_HEIGHT(button->font) / 2; } if (!color_shadow) { text_show(button->surface, button->font, text, x, y, color, button->flags, NULL); } else { text_show_shadow(button->surface, button->font, text, x, y - 2, color, color_shadow, button->flags, NULL); } } if (button->repeat_func && button->pressed && SDL_GetTicks() - button->pressed_ticks > button->pressed_repeat_ticks) { button->repeat_func(button); button->pressed_ticks = SDL_GetTicks(); button->pressed_repeat_ticks = 150; } button->redraw = 0; }
/** @copydoc widgetdata::draw_func */ static void widget_draw(widgetdata *widget) { SDL_Rect box; size_t i; /* Create the skill list. */ if (!list_skills) { list_skills = list_create(5, 4, 8); list_skills->post_column_func = list_post_column; list_skills->row_color_func = list_row_color; list_skills->row_selected_func = NULL; list_skills->row_highlight_func = NULL; list_skills->surface = widget->surface; list_skills->row_height_adjust = INVENTORY_ICON_SIZE; list_set_font(list_skills, NULL); list_scrollbar_enable(list_skills); list_set_column(list_skills, 0, INVENTORY_ICON_SIZE, 0, NULL, -1); list_set_column(list_skills, 1, INVENTORY_ICON_SIZE, 0, NULL, -1); list_set_column(list_skills, 2, INVENTORY_ICON_SIZE, 0, NULL, -1); list_set_column(list_skills, 3, INVENTORY_ICON_SIZE, 0, NULL, -1); skill_list_reload(); for (i = 0; i < BUTTON_NUM; i++) { button_create(&buttons[i]); buttons[i].texture = texture_get(TEXTURE_TYPE_CLIENT, "button_round"); buttons[i].texture_pressed = texture_get(TEXTURE_TYPE_CLIENT, "button_round_down"); buttons[i].texture_over = texture_get(TEXTURE_TYPE_CLIENT, "button_round_over"); } } if (widget->redraw) { box.h = 0; box.w = widget->w; text_show(widget->surface, FONT_SERIF12, "Skills", 0, 3, COLOR_HGOLD, TEXT_ALIGN_CENTER, &box); list_set_parent(list_skills, widget->x, widget->y); list_show(list_skills, 10, 2); for (i = 0; i < BUTTON_NUM; i++) { buttons[i].surface = widget->surface; button_set_parent(&buttons[i], widget->x, widget->y); } buttons[BUTTON_CLOSE].x = widget->w - texture_surface(buttons[BUTTON_CLOSE].texture)->w - 4; buttons[BUTTON_CLOSE].y = 4; button_show(&buttons[BUTTON_CLOSE], "X"); buttons[BUTTON_HELP].x = widget->w - texture_surface(buttons[BUTTON_HELP].texture)->w * 2 - 4; buttons[BUTTON_HELP].y = 4; button_show(&buttons[BUTTON_HELP], "?"); } }
/** @copydoc widgetdata::draw_func */ static void widget_draw(widgetdata *widget) { SDL_Rect box; size_t i; if (widget->redraw) { box.h = 0; box.w = widget->w; text_show(widget->surface, FONT_SERIF12, "Party", 0, 3, COLOR_HGOLD, TEXT_ALIGN_CENTER, &box); if (list_party) { list_party->surface = widget->surface; list_set_parent(list_party, widget->x, widget->y); list_show(list_party, 10, 23); } for (i = 0; i < BUTTON_NUM; i++) { buttons[i].surface = widget->surface; button_set_parent(&buttons[i], widget->x, widget->y); } /* Render the various buttons. */ buttons[BUTTON_CLOSE].x = widget->w - TEXTURE_CLIENT("button_round")->w - 4; buttons[BUTTON_CLOSE].y = 4; button_show(&buttons[BUTTON_CLOSE], "X"); buttons[BUTTON_HELP].x = widget->w - TEXTURE_CLIENT("button_round")->w * 2 - 4; buttons[BUTTON_HELP].y = 4; button_show(&buttons[BUTTON_HELP], "?"); buttons[BUTTON_PARTIES].x = 244; buttons[BUTTON_PARTIES].y = 38; button_show(&buttons[BUTTON_PARTIES], list_contents == CMD_PARTY_LIST ? "[u]Parties[/u]" : "Parties"); buttons[BUTTON_MEMBERS].x = buttons[BUTTON_FORM].x = 244; buttons[BUTTON_MEMBERS].y = buttons[BUTTON_FORM].y = 60; if (cpl.partyname[0] == '\0') { button_show(&buttons[BUTTON_FORM], "Form"); } else { button_show(&buttons[BUTTON_MEMBERS], list_contents == CMD_PARTY_WHO ? "[u]Members[/u]" : "Members"); buttons[BUTTON_LEAVE].x = buttons[BUTTON_PASSWORD].x = buttons[BUTTON_CHAT].x = 244; buttons[BUTTON_LEAVE].y = 82; buttons[BUTTON_PASSWORD].y = 104; buttons[BUTTON_CHAT].y = 126; button_show(&buttons[BUTTON_LEAVE], "Leave"); button_show(&buttons[BUTTON_PASSWORD], "Password"); button_show(&buttons[BUTTON_CHAT], "Chat"); } } }
/** @copydoc list_struct::post_column_func */ static void list_post_column(list_struct *list, uint32_t row, uint32_t col) { size_t skill_id; SDL_Rect box; skill_id = row * list->cols + col; if (skill_id >= skill_list_num) { return; } if (!FaceList[skill_list[skill_id]->skill->face].sprite) { return; } box.x = list->x + list->frame_offset + INVENTORY_ICON_SIZE * col; box.y = LIST_ROWS_START(list) + (LIST_ROW_OFFSET(row, list) * LIST_ROW_HEIGHT(list)); box.w = INVENTORY_ICON_SIZE; box.h = INVENTORY_ICON_SIZE; surface_show(list->surface, box.x, box.y, NULL, FaceList[skill_list[skill_id]->skill->face].sprite->bitmap); if (selected_skill != skill_id) { return; } border_create_color(list->surface, &box, 1, "ff0000"); char buf[MAX_BUF]; snprintf(VS(buf), "%s", skill_list[skill_id]->skill->s_name); string_title(buf); box.w = 160; text_show(list->surface, FONT_SERIF12, buf, 150, 18, COLOR_HGOLD, TEXT_ALIGN_CENTER | TEXT_OUTLINE, &box); box.h = 100; text_show(list->surface, FONT_ARIAL11, skill_list[skill_id]->msg, 150, 38, COLOR_WHITE, TEXT_WORD_WRAP, &box); if (skill_list[skill_id]->level == 0) { return; } widgetdata *widget = widget_find(NULL, -1, NULL, list->surface); SOFT_ASSERT(widget != NULL, "Could not find widget"); text_show(list->surface, FONT("arial", 10), "[b]Experience[/b]", 167, widget->h - 47, COLOR_WHITE, TEXT_MARKUP, NULL); player_draw_exp_progress(list->surface, 160, widget->h - 32, skill_list[skill_id]->exp, skill_list[skill_id]->level); box.h = 30; box.w = 35; text_show(list->surface, FONT("arial", 10), "[b]Level[/b]", widget->w - 45, widget->h - 47, COLOR_WHITE, TEXT_MARKUP | TEXT_ALIGN_CENTER, &box); text_show_format(list->surface, FONT_SERIF18, widget->w - 45, widget->h - 30, COLOR_HGOLD, TEXT_MARKUP | TEXT_OUTLINE | TEXT_ALIGN_CENTER, &box, "%" PRIu8, skill_list[skill_id]->level); }
/** * Show one list. * @param list * List to show. * @param x * X position. * @param y * Y position. */ void list_show(list_struct *list, int x, int y) { uint32_t row, col; int w = 0, extra_width = 0; SDL_Rect box; if (!list) { return; } list->x = x; list->y = y; /* Draw a frame, if needed. */ if (list->draw_frame_func) { list->draw_frame_func(list); } /* Draw the column names. */ for (col = 0; col < list->cols; col++) { extra_width = 0; /* Center it? */ if (list->col_centered[col]) { extra_width = list->col_widths[col] / 2 - text_get_width(list->font, list->col_names[col], 0) / 2; } /* Actually draw the column name. */ if (list->col_names[col]) { text_show_shadow(list->surface, list->font, list->col_names[col], list->x + w + extra_width, list->y, list->focus ? COLOR_WHITE : COLOR_GRAY, COLOR_BLACK, 0, NULL); } w += list->col_widths[col] + list->col_spacings[col]; } /* Initialize default values for coloring rows. */ box.x = list->x + list->frame_offset; box.w = list->width; box.h = LIST_ROW_HEIGHT(list); if (list->scrollbar_enabled) { scrollbar_show(&list->scrollbar, list->surface, list->x + list->frame_offset + 1 + w, LIST_ROWS_START(list)); } /* Doing coloring of each row? */ if (list->row_color_func) { for (row = 0; row < list->max_rows; row++) { box.y = LIST_ROWS_START(list) + (row * LIST_ROW_HEIGHT(list)); list->row_color_func(list, row, box); } } /* Start printing out rows from the offset to the maximum. */ for (row = list->row_offset; row < list->rows; row++) { /* Stop if we reached maximum number of visible rows. */ if (LIST_ROW_OFFSET(row, list) == list->max_rows) { break; } if (list->row_selected_func && (row + 1) == list->row_selected) { /* Color selected row. */ box.y = LIST_ROWS_START(list) + (LIST_ROW_OFFSET(row, list) * LIST_ROW_HEIGHT(list)); list->row_selected_func(list, box); } else if (list->row_highlight_func && (row + 1) == list->row_highlighted) { /* Color highlighted row. */ box.y = LIST_ROWS_START(list) + (LIST_ROW_OFFSET(row, list) * LIST_ROW_HEIGHT(list)); list->row_highlight_func(list, box); } w = 0; /* Show all the columns. */ for (col = 0; col < list->cols; col++) { /* Is there any text to show? */ if (list->text[row][col] && list->font != NULL) { const char *text_color, *text_color_shadow; SDL_Rect text_rect; extra_width = 0; /* Center it. */ if (list->col_centered[col]) { extra_width = list->col_widths[col] / 2 - text_get_width(list->font, list->text[row][col], TEXT_WORD_WRAP) / 2; } text_color = list->focus ? COLOR_WHITE : COLOR_GRAY; text_color_shadow = COLOR_BLACK; if (list->text_color_hook) { list->text_color_hook(list, row, col, &text_color, &text_color_shadow); } /* Add width limit on the string. */ text_rect.x = list->x + w + extra_width; text_rect.y = LIST_ROWS_START(list) + (LIST_ROW_OFFSET(row, list) * LIST_ROW_HEIGHT(list)); text_rect.w = list->col_widths[col] + list->col_spacings[col]; text_rect.h = LIST_ROW_HEIGHT(list); /* Output the text. */ if (text_color_shadow) { text_show_shadow(list->surface, list->font, list->text[row][col], text_rect.x, text_rect.y, text_color, text_color_shadow, TEXT_WORD_WRAP | list->text_flags, &text_rect); } else if (text_color) { text_show(list->surface, list->font, list->text[row][col], text_rect.x, text_rect.y, text_color, TEXT_WORD_WRAP | list->text_flags, &text_rect); } } if (list->post_column_func) { list->post_column_func(list, row, col); } w += list->col_widths[col] + list->col_spacings[col]; } } }
/** @copydoc widgetdata::draw_func */ static void widget_draw(widgetdata *widget) { SDL_Rect box; char buf[HUGE_BUF]; size_t i; /* The list doesn't exist yet, create it. */ if (!list_mplayer) { char version[MAX_BUF]; /* Create the list and set up settings. */ list_mplayer = list_create(12, 1, 8); list_mplayer->handle_enter_func = list_handle_enter; list_mplayer->text_color_hook = list_text_color_hook; list_mplayer->surface = widget->surface; list_scrollbar_enable(list_mplayer); list_set_column(list_mplayer, 0, 130, 7, NULL, -1); list_set_font(list_mplayer, FONT_ARIAL10); /* Add default media directory songs. */ get_data_dir_file(buf, sizeof(buf), DIRECTORY_MEDIA); mplayer_list_init(list_mplayer, buf, 0); /* Now add custom ones, but ignore duplicates. */ snprintf(buf, sizeof(buf), "%s/.atrinik/%s/"DIRECTORY_MEDIA, get_config_dir(), package_get_version_partial(version, sizeof(version))); mplayer_list_init(list_mplayer, buf, 1); /* If we added any, sort the list alphabetically and add an entry * to disable background music. */ if (list_mplayer->rows) { FILE *fp; /* Allocate the blacklist. + 1 is for the last entry added * further down. It is not actually used by the blacklist as * it's not possible to toggle it on/off using the button, but * it simplifies other logic checks. */ shuffle_blacklist = ecalloc(1, sizeof(*shuffle_blacklist) * (list_mplayer->rows + 1)); /* Sort the list. */ list_sort(list_mplayer, LIST_SORT_ALPHA); /* Read the blacklist file contents. */ fp = path_fopen(FILE_MPLAYER_BLACKLIST, "r"); if (fp) { size_t row; while (fgets(buf, sizeof(buf) - 1, fp)) { for (row = 0; row < list_mplayer->rows; row++) { if (!strncmp(buf, list_mplayer->text[row][0], strlen(buf) - 1)) { shuffle_blacklist[row] = 1; break; } } } fclose(fp); } list_add(list_mplayer, list_mplayer->rows, 0, "Disable music"); } scrollbar_create(&scrollbar_progress, 130, 11, &scrollbar_progress_info.scroll_offset, &scrollbar_progress_info.num_lines, 1); scrollbar_progress.redraw = &scrollbar_progress_info.redraw; } if (widget->redraw) { const char *bg_music; box.h = 0; box.w = widget->w; text_show(widget->surface, FONT_SERIF12, "Music Player", 0, 3, COLOR_HGOLD, TEXT_ALIGN_CENTER, &box); list_set_parent(list_mplayer, widget->x, widget->y); list_show(list_mplayer, 10, 2); box.w /= 2; text_show(widget->surface, FONT_SANS10, "Currently playing:", widget->w / 2, 22, COLOR_WHITE, TEXT_ALIGN_CENTER, &box); bg_music = sound_get_bg_music_basename(); box.h = 0; box.w = widget->w / 2; /* Store the background music file name in temporary buffer and * make sure it won't overflow by truncating it if necessary. */ if (bg_music) { strncpy(buf, bg_music, sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; text_truncate_overflow(FONT_SANS11, buf, 150); } /* Show the music that is being played. */ text_show(widget->surface, FONT_SANS11, bg_music ? buf : "No music", widget->w / 2 - 5, 34, COLOR_HGOLD, TEXT_ALIGN_CENTER, &box); scrollbar_progress.px = widget->x; scrollbar_progress.py = widget->y; scrollbar_show(&scrollbar_progress, widget->surface, 170, 50); box.h = 120; box.w -= 6 * 2; text_show(widget->surface, FONT_ARIAL10, "You can use the music player to play your favorite tunes from the game, or play them all one-by-one in random order (shuffle).\n\nNote that if you use the music player, in-game areas won't change your music until you click [b]Stop[/b].", widget->w / 2 + 6, 62, COLOR_WHITE, TEXT_WORD_WRAP | TEXT_MARKUP, &box); for (i = 0; i < BUTTON_NUM; i++) { buttons[i].surface = widget->surface; button_set_parent(&buttons[i], widget->x, widget->y); } buttons[BUTTON_PLAY].x = 10; buttons[BUTTON_PLAY].y = widget->h - TEXTURE_CLIENT("button")->h - 4; button_show(&buttons[BUTTON_PLAY], sound_map_background(-1) ? "Stop" : "Play"); buttons[BUTTON_SHUFFLE].x = 10 + TEXTURE_CLIENT("button")->w + 5; buttons[BUTTON_SHUFFLE].y = widget->h - TEXTURE_CLIENT("button")->h - 4; buttons[BUTTON_SHUFFLE].pressed_forced = shuffle; button_show(&buttons[BUTTON_SHUFFLE], "Shuffle"); buttons[BUTTON_BLACKLIST].x = 10 + TEXTURE_CLIENT("button")->w * 2 + 5 * 2; buttons[BUTTON_BLACKLIST].y = widget->h - TEXTURE_CLIENT("button_round")->h - 5; buttons[BUTTON_BLACKLIST].disabled = list_mplayer->row_selected == list_mplayer->rows; button_show(&buttons[BUTTON_BLACKLIST], mplayer_blacklisted(list_mplayer) ? "+" : "-"); /* Show close button. */ buttons[BUTTON_CLOSE].x = widget->w - TEXTURE_CLIENT("button_round")->w - 4; buttons[BUTTON_CLOSE].y = 4; button_show(&buttons[BUTTON_CLOSE], "X"); /* Show help button. */ buttons[BUTTON_HELP].x = widget->w - TEXTURE_CLIENT("button_round")->w * 2 - 4; buttons[BUTTON_HELP].y = 4; button_show(&buttons[BUTTON_HELP], "?"); } }
void muste_show(int argc,char *argv[]) { int i; int space_break0; long li; rdisp=0; ndisp=0; mdisp=0; j=jmax=0; edit=ted1=ted2=0; tedshad=0; shad_int=NULL; n_shad=0; jj=0; cdisp=0; testi=0; text=NULL; alut=NULL; jjmax=0; last_line32=0; alut32=NULL; s98_file=0; copyfile=NULL; empty32=0; disp_frame=0; win_conv=0; text_found=0; codes=NULL; extern int s_init_extrasplit(); if (argc==1) return; s_init(argv[1]); s_init_extrasplit(); // RS ADD word[2]=word_org[2]; // RS ADD second parameter should remain quoted labels(); tut_init(); if (r_soft) r3+=r_soft+1; strcpy(siirtop,argv[1]); space_break0=space_break; space_break=0; jmax=1000000L; if (hae_apu("max_show_lines",sbuf)) jmax=atol(sbuf); // 22.1.2007 i=avaa_alut(); if (i<0) return; talleta_alku(1L,0L); i=spec_find("WINCONV",sbuf,LLENGTH); if (i>=0 && atoi(sbuf)>0) { win_conv=1; w_codes_load(2); } i=spec_find("ENCODING",muste_encoding,LLENGTH-1); // RS 26.1.2014 if (i<0) win_conv=0; else win_conv=999; jj=r1+r; if (g==1) { strcpy(tfile,eout); if (*tfile==EOS) // 28.10.2002 { sur_print("\nNo output file in use!"); WAIT; return; } text_show(1L); } else { strcpy(tfile,word[1]); subst_survo_path(tfile); li=1L; if (g>2) li=atol(word[2]); if (li<1) li=1L; if (g>2 && !isdigit((int)*word[2]) && *word[2]!='"') { li=get_editline_from_file(tfile,word[2],1); if (li<0) return; // RS ADD if (li==0) { sprintf(sbuf,"\n%s not found!",word[2]); sur_print(sbuf); WAIT; } } i=text_show(li); if (i>0 && edit>=0 && edit!=2) muste_fclose(text); } poista_alut(); space_break=space_break0; tut_end(); if (r_soft) r3-=r_soft+1; s_end(argv[1]); }
static void ActOnMessage(uschar *id, uschar *action, uschar *address_arg) { int pid; int pipe_fd[2]; int delivery = Ustrcmp(action + Ustrlen(action) - 2, "-M") == 0; uschar *quote = US""; uschar *at = US""; uschar *qualify = US""; uschar buffer[256]; queue_item *qq; Widget text = NULL; /* If the address arg is not empty and does not contain @ and there is a qualify domain, qualify it. (But don't qualify '<>'.)*/ if (address_arg[0] != 0) { quote = US"\'"; if (Ustrchr(address_arg, '@') == NULL && Ustrcmp(address_arg, "<>") != 0 && qualify_domain != NULL && qualify_domain[0] != 0) { at = US"@"; qualify = qualify_domain; } } sprintf(CS buffer, "%s %s %s %s %s %s%s%s%s%s", exim_path, (alternate_config == NULL)? US"" : US"-C", (alternate_config == NULL)? US"" : alternate_config, action, id, quote, address_arg, at, qualify, quote); /* If we know we are going to need the window, create it now. */ if (action_output || delivery) { text = text_create(id, text_depth); text_showf(text, "%s\n", buffer); } /* Create the pipe for output. Remember, on most systems pipe[0] is for reading and pipe[1] is for writing! Solaris, with its two-way pipes is a trap! */ if (pipe(pipe_fd) != 0) { if (text == NULL) { text = text_create(id, text_depth); text_showf(text, "%s\n", buffer); } text_show(text, US"*** Failed to create pipe ***\n"); return; } if ( fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK) || fcntl(pipe_fd[1], F_SETFL, O_NONBLOCK)) { perror("set nonblocking on pipe"); exit(1); } /* Delivering a message can take some time, and we want to show the output as it goes along. This requires subprocesses and is coded below. For other commands, we can assume an immediate response, and so need not waste resources with subprocesses. If action_output is FALSE, don't show the output at all. */ if (!delivery) { int count, rc; int save_stdout = dup(1); int save_stderr = dup(2); close(1); close(2); dup2(pipe_fd[1], 1); dup2(pipe_fd[1], 2); close(pipe_fd[1]); rc = system(CS buffer); close(1); close(2); if (action_output || rc != 0) { if (text == NULL) { text = text_create(id, text_depth); text_showf(text, "%s\n", buffer); } while ((count = read(pipe_fd[0], buffer, 254)) > 0) { buffer[count] = 0; text_show(text, buffer); } } close(pipe_fd[0]); dup2(save_stdout, 1); dup2(save_stderr, 2); close(save_stdout); close(save_stderr); /* If action was to change the sender, and it succeeded, we have to update the in-store data. */ if (rc == 0 && Ustrcmp(action + Ustrlen(action) - 4, "-Mes") == 0) { queue_item *q = find_queue(id, queue_noop, 0); if (q) { if (q->sender) store_free(q->sender); q->sender = store_malloc(Ustrlen(address_arg) + 1); Ustrcpy(q->sender, address_arg); } } /* If configured, cause a display update and return */ if (action_queue_update) tick_queue_accumulator = 999999; return; } /* Message is to be delivered. Ensure that it is marked unfrozen, because nothing will get written to the log to show that this has happened. (Other freezing/unfreezings get logged and picked up from there.) */ qq = find_queue(id, queue_noop, 0); if (qq != NULL) qq->frozen = FALSE; /* New, asynchronous code runs in a subprocess for commands that will take some time. The main process does not wait. There is a SIGCHLD handler in the main program that cleans up any terminating sub processes. */ if ((pid = fork()) == 0) { close(1); close(2); dup2(pipe_fd[1], 1); dup2(pipe_fd[1], 2); close(pipe_fd[1]); system(CS buffer); close(1); close(2); close(pipe_fd[0]); _exit(0); } /* Main process - set up an item for the main ticker to watch. */ if (pid < 0) text_showf(text, "Failed to fork: %s\n", strerror(errno)); else { pipe_item *p = (pipe_item *)store_malloc(sizeof(pipe_item)); if (p == NULL) { text_show(text, US"Run out of store\n"); return; } p->widget = text; p->fd = pipe_fd[0]; p->next = pipe_chain; pipe_chain = p; close(pipe_fd[1]); } }
/** * Load the book interface. * @param data * Book's content. * @param len * Length of 'data'. */ void book_load(const char *data, int len) { SDL_Rect box; int pos; /* Nothing to do. */ if (!data || !len) { return; } /* Free old book data and reset the values. */ if (book_content != NULL) { efree(book_content); } book_lines = 0; book_scroll_lines = 0; book_scroll = 0; /* Store the data. */ book_content = estrdup(data); book_name_change("Book", 4); /* Strip trailing newlines. */ for (pos = len - 1; pos >= 0; pos--) { if (book_content[pos] != '\n') { break; } book_content[pos] = '\0'; } /* No data... */ if (book_content[0] == '\0') { return; } /* Calculate the line numbers. */ box.w = BOOK_TEXT_WIDTH; box.h = BOOK_TEXT_HEIGHT; text_show(NULL, FONT_ARIAL11, book_content, BOOK_TEXT_STARTX, BOOK_TEXT_STARTY, COLOR_WHITE, TEXT_WORD_WRAP | TEXT_MARKUP | TEXT_LINES_CALC, &box); book_lines = box.h; book_scroll_lines = box.y; /* Create the book popup if it doesn't exist yet. */ if (!popup_get_head() || popup_get_head()->texture != texture_get(TEXTURE_TYPE_CLIENT, "book")) { popup_struct *popup; popup = popup_create(texture_get(TEXTURE_TYPE_CLIENT, "book")); popup->draw_func = popup_draw_func; popup->draw_post_func = popup_draw_post_func; popup->event_func = popup_event_func; popup->destroy_callback_func = popup_destroy_callback; popup->clipboard_copy_func = popup_clipboard_copy_func; popup->disable_texture_drawing = 1; popup->button_left.x = 25; popup->button_left.y = 25; if (book_help_history_enabled) { popup->button_left.event_func = popup_button_event_func; popup_button_set_text(&popup->button_left, "<"); } popup->button_right.x = 649; popup->button_right.y = 25; } scrollbar_create(&scrollbar, BOOK_SCROLLBAR_WIDTH, BOOK_SCROLLBAR_HEIGHT, &book_scroll, &book_lines, book_scroll_lines); scrollbar.redraw = &popup_get_head()->redraw; popup_get_head()->redraw = 1; }
/** * Show the main GUI after starting the client -- servers list, chat box, * connecting to server, etc. */ void intro_show(void) { SDL_Surface *texture; int x, y; size_t server_count; server_struct *node; char buf[MAX_BUF]; SDL_Rect box; sound_start_bg_music("intro.ogg", setting_get_int(OPT_CAT_SOUND, OPT_VOLUME_MUSIC), -1); texture = TEXTURE_CLIENT("intro"); /* Background */ surface_show(ScreenSurface, 0, 0, NULL, texture); textwin_show(ScreenSurface, texture->w, 1, ScreenSurface->w - texture->w - 2, ScreenSurface->h - 3); /* Calculate whether to show the eyes or not. Blinks every * EYES_BLINK_TIME ticks, then waits EYES_BLINK_DELAY ticks until * showing the eyes again. */ if (SDL_GetTicks() - eyes_blink_ticks >= (eyes_draw ? EYES_BLINK_TIME : EYES_BLINK_DELAY)) { eyes_blink_ticks = SDL_GetTicks(); eyes_draw++; } if (eyes_draw) { SDL_Rect src_box; src_box.x = 0; src_box.y = eyes_draw - 1; src_box.w = TEXTURE_CLIENT("eyes")->w; src_box.h = TEXTURE_CLIENT("eyes")->h; surface_show(ScreenSurface, texture->w - 90, 310 + src_box.y, &src_box, TEXTURE_CLIENT("eyes")); if (eyes_draw > 1) { eyes_draw++; if (eyes_draw > src_box.h) { eyes_draw = 1; } } } texture = TEXTURE_CLIENT("servers_bg"); x = 15; y = ScreenSurface->h - texture->h - 5; surface_show(ScreenSurface, x, y, NULL, texture); server_count = server_get_count(); /* Create the buttons. */ if (!list_servers) { button_create(&button_play); button_create(&button_refresh); button_create(&button_server); button_create(&button_settings); button_create(&button_update); button_create(&button_help); button_create(&button_credits); button_create(&button_quit); } /* List doesn't exist or the count changed? Create new list. */ if (!list_servers || last_server_count != server_count) { size_t i; /* Remove it if it exists already. */ if (list_servers) { list_remove(list_servers); } /* Create the servers list. */ list_servers = list_create(11, 3, 8); list_servers->handle_enter_func = list_handle_enter; list_servers->handle_esc_func = list_handle_esc; list_servers->text_color_hook = list_text_color; list_scrollbar_enable(list_servers); list_set_column(list_servers, 0, 295, 7, "Server", -1); list_set_column(list_servers, 1, 50, 9, "Port", 1); list_set_column(list_servers, 2, 46, 7, "Players", 1); /* Add the servers to the list. */ for (i = 0; i < server_count; i++) { node = server_get_id(i); list_add(list_servers, i, 0, node->name); snprintf(VS(buf), "%d", node->port_crypto == -1 ? node->port : node->port_crypto); list_add(list_servers, i, 1, buf); if (node->player >= 0) { snprintf(buf, sizeof(buf), "%d", node->player); } else { strcpy(buf, "-"); } list_add(list_servers, i, 2, buf); } /* Store the new count. */ last_server_count = server_count; } /* Actually draw the list. */ list_show(list_servers, x + 12, y + 8); node = server_get_id(list_servers->row_selected - 1); /* Do we have any selected server? If so, show its version and * description. */ if (node) { snprintf(buf, sizeof(buf), "Version: %s", node->version); text_show_shadow(ScreenSurface, FONT_ARIAL10, buf, x + 13, y + 185, COLOR_HGOLD, COLOR_BLACK, 0, NULL); box.w = 410; box.h = 48; text_show(ScreenSurface, FONT_ARIAL10, node->desc, x + 13, y + 197, COLOR_WHITE, TEXT_WORD_WRAP | TEXT_MARKUP, &box); } /* Show whether we are connecting to the metaserver or not. */ if (ms_connecting(-1)) { text_show_shadow(ScreenSurface, FONT_ARIAL10, "Connecting to metaserver, please wait...", x + 105, y + 8, COLOR_HGOLD, COLOR_BLACK, 0, NULL); } else { text_show_shadow(ScreenSurface, FONT_ARIAL10, "Select a secure server.", x + 196, y + 8, COLOR_GREEN, COLOR_BLACK, 0, NULL); } texture = TEXTURE_CLIENT("servers_bg_over"); surface_show(ScreenSurface, x, y, NULL, texture); x += texture->w + 20; texture = TEXTURE_CLIENT("news_bg"); surface_show(ScreenSurface, x, y, NULL, texture); box.w = texture->w; box.h = 0; text_show_shadow(ScreenSurface, FONT_SERIF12, "Game News", x, y + 10, COLOR_HGOLD, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); /* No list yet, make one and start downloading the data. */ if (!list_news) { /* Start downloading. */ news_request = curl_request_create(clioption_settings.game_news_url, CURL_PKEY_TRUST_ULTIMATE); curl_request_start_get(news_request); list_news = list_create(18, 1, 8); list_news->focus = 0; list_news->handle_enter_func = list_handle_enter; list_news->handle_esc_func = list_handle_esc; list_set_column(list_news, 0, 150, 7, NULL, -1); list_set_font(list_news, FONT_ARIAL10); } /* Download in progress? */ if (news_request != NULL) { curl_state_t state = curl_request_get_state(news_request); /* Finished downloading, parse the data. */ if (state == CURL_STATE_OK) { char *body = curl_request_get_body(news_request, NULL); if (body != NULL) { uint32_t i = 0; char *cp = strtok(body, "\n"); while (cp != NULL) { list_add(list_news, i++, 0, cp); cp = strtok(NULL, "\n"); } } } /* Finished downloading or there was an error: clean up in either * case. */ if (state != CURL_STATE_INPROGRESS) { curl_request_free(news_request); news_request = NULL; } } /* Show the news list. */ list_show(list_news, x + 13, y + 10); button_play.x = button_refresh.x = button_server.x = button_settings.x = button_update.x = button_help.x = button_credits.x = button_quit.x = 489; y += 2; button_play.y = y + 10; button_show(&button_play, "Play"); button_refresh.y = y + 35; button_show(&button_refresh, "Refresh"); button_server.y = y + 60; button_show(&button_server, "Server"); button_settings.y = y + 86; button_show(&button_settings, "Settings"); button_update.y = y + 110; button_show(&button_update, "Update"); button_help.y = y + 135; button_show(&button_help, "Help"); button_credits.y = y + 160; button_show(&button_credits, "Credits"); button_quit.y = y + 224; button_show(&button_quit, "Quit"); if (clioption_settings.connect[0] && cpl.state < ST_STARTCONNECT) { size_t i; for (i = 0; i < server_count; i++) { node = server_get_id(i); if (strcasecmp(clioption_settings.connect[0], node->name) == 0) { list_servers->row_selected = i + 1; if (!clioption_settings.reconnect) { efree(clioption_settings.connect[0]); clioption_settings.connect[0] = NULL; } event_push_key_once(SDLK_RETURN, 0); break; } } } }