/************************************************************************** Popdown the short player list dialog version. **************************************************************************/ void popdown_players_nations_dialog(void) { if (pShort_Players_Dlg) { popdown_window_group_dialog(pShort_Players_Dlg->pBeginWidgetList, pShort_Players_Dlg->pEndWidgetList); FC_FREE(pShort_Players_Dlg->pScroll); FC_FREE(pShort_Players_Dlg); } }
/************************************************************************** Popdown a dialog asking a diplomatic unit if it wishes to bribe the given enemy unit. **************************************************************************/ void popdown_bribe_dialog(void) { if (pBribe_Dlg) { is_unit_move_blocked = FALSE; popdown_window_group_dialog(pBribe_Dlg->pdialog->pBeginWidgetList, pBribe_Dlg->pdialog->pEndWidgetList); FC_FREE(pBribe_Dlg->pdialog); FC_FREE(pBribe_Dlg); flush_dirty(); } }
/************************************************************************** Popdown a dialog giving a diplomatic unit some options when moving into the target tile. **************************************************************************/ void popdown_diplomat_dialog(void) { if (pDiplomat_Dlg) { is_unit_move_blocked = FALSE; popdown_window_group_dialog(pDiplomat_Dlg->pdialog->pBeginWidgetList, pDiplomat_Dlg->pdialog->pEndWidgetList); FC_FREE(pDiplomat_Dlg->pdialog->pScroll); FC_FREE(pDiplomat_Dlg->pdialog); FC_FREE(pDiplomat_Dlg); queue_flush(); } }
/************************************************************************** Create string16 struct with ptsize font. Font will be loaded or aliased with existing font of that size. pInTextString must be allocated in memory (MALLOC/fc_calloc) **************************************************************************/ SDL_String16 * create_string16(Uint16 *pInTextString, size_t n_alloc, Uint16 ptsize) { SDL_String16 *str = fc_calloc(1, sizeof(SDL_String16)); if (!ptsize) { str->ptsize = theme_default_font_size(theme); } else { str->ptsize = ptsize; } if ((str->font = load_font(str->ptsize)) == NULL) { log_error("create_string16: load_font failed"); FC_FREE(str); return str; } str->style = TTF_STYLE_NORMAL; str->bgcol = (SDL_Color) {0, 0, 0, 0}; str->fgcol = *get_game_colorRGB(COLOR_THEME_TEXT); str->render = 2; /* pInTextString must be allocated in memory (MALLOC/fc_calloc) */ str->text = pInTextString; str->n_alloc = n_alloc; return str; }
/************************************************************************** Do any necessary UI-specific cleanup **************************************************************************/ void ui_exit() { #if defined UNDER_CE && defined SMALL_SCREEN /* change back to window mode to restore the title bar */ set_video_mode(320, 240, SDL_SWSURFACE | SDL_ANYFORMAT); #endif free_mapcanvas_and_overview(); free_auxiliary_tech_icons(); free_intro_radar_sprites(); diplomacy_dialog_done(); intel_dialog_done(); callback_list_destroy(callbacks); unload_cursors(); FC_FREE(button_behavior.event); meswin_dialog_popdown(); del_main_list(); free_font_system(); theme_free(theme); quit_sdl(); }
/********************************************************************** Returns the correct name of the gfx file (with path and extension) Must be free'd when no longer used ***********************************************************************/ char *themespec_gfx_filename(const char *gfx_filename) { const char *gfx_current_fileext; const char **gfx_fileexts = gfx_fileextensions(); while((gfx_current_fileext = *gfx_fileexts++)) { char *full_name = fc_malloc(strlen(gfx_filename) + strlen(gfx_current_fileext) + 2); const char *real_full_name; sprintf(full_name,"%s.%s",gfx_filename,gfx_current_fileext); real_full_name = fileinfoname(get_data_dirs(), full_name); FC_FREE(full_name); if (real_full_name) { return fc_strdup(real_full_name); } } log_fatal("Couldn't find a supported gfx file extension for \"%s\".", gfx_filename); exit(EXIT_FAILURE); return NULL; }
/************************************************************************** Popdownown the player list dialog. **************************************************************************/ void popdown_players_dialog(void) { if (pPlayers_Dlg) { popdown_window_group_dialog(pPlayers_Dlg->pBeginWidgetList, pPlayers_Dlg->pEndWidgetList); FC_FREE(pPlayers_Dlg); } }
static void popdown_start_menu() { if(pStartMenu) { popdown_window_group_dialog(pStartMenu->pBeginWidgetList, pStartMenu->pEndWidgetList); FC_FREE(pStartMenu); flush_dirty(); } }
/*************************************************************************** Look up the service at hostname:port. ***************************************************************************/ struct fc_sockaddr_list *net_lookup_service(const char *name, int port, enum fc_addr_family family) { /* IPv6-enabled Freeciv always has HAVE_GETADDRINFO, IPv4-only Freeciv not * necessarily */ #ifdef HAVE_GETADDRINFO return net_lookup_getaddrinfo(name, port, family); #else /* HAVE_GETADDRINFO */ struct sockaddr_in *sock4; struct hostent *hp; struct fc_sockaddr_list *addrs = fc_sockaddr_list_new(); union fc_sockaddr *result = fc_malloc(sizeof(result)); sock4 = &result->saddr_in4; fc_assert(family != FC_ADDR_IPV6); result->saddr.sa_family = AF_INET; sock4->sin_port = htons(port); if (!name) { sock4->sin_addr.s_addr = htonl(INADDR_ANY); fc_sockaddr_list_append(addrs, result); return addrs; } #if defined(HAVE_INET_ATON) if (inet_aton(name, &sock4->sin_addr) != 0) { fc_sockaddr_list_append(addrs, result); return addrs; } #else /* HAVE_INET_ATON */ if ((sock4->sin_addr.s_addr = inet_addr(name)) != INADDR_NONE) { fc_sockaddr_list_append(addrs, result); return addrs; } #endif /* HAVE_INET_ATON */ hp = gethostbyname(name); if (!hp || hp->h_addrtype != AF_INET) { FC_FREE(result); return addrs; } memcpy(&sock4->sin_addr, hp->h_addr, hp->h_length); fc_sockaddr_list_append(addrs, result); return addrs; #endif /* !HAVE_GETADDRINFO */ }
/**************************************************************************** Called when the client first starts to free any allocated backgrounds. ****************************************************************************/ void theme_background_system_free(struct theme_background_system *backgrounds) { int i; for (i = 0; i < BACKGROUND_LAST; i++) { FC_FREE(backgrounds->backgrounds[i]); } free(backgrounds); }
/************************************************************************** Delete UniChar structure. **************************************************************************/ static void del_chain(struct UniChar *pChain) { int i, len = 0; if (!pChain) { return; } len = chainlen(pChain); if (len > 1) { pChain = pChain->next; for (i = 0; i < len - 1; i++) { FREESURFACE(pChain->prev->pTsurf); FC_FREE(pChain->prev); pChain = pChain->next; } } FC_FREE(pChain); }
/************************************************************************** Close the spaceship dialog for the given player. **************************************************************************/ void popdown_spaceship_dialog(struct player *pPlayer) { struct SMALL_DLG *pSpaceShp; if((pSpaceShp = get_spaceship_dialog(pPlayer))) { popdown_window_group_dialog(pSpaceShp->pBeginWidgetList, pSpaceShp->pEndWidgetList); dialog_list_remove(dialog_list, pSpaceShp); FC_FREE(pSpaceShp); } }
/************************************************************************** Free all fonts. **************************************************************************/ void free_font_system(void) { struct TTF_Font_Chain *Font_TAB_TMP; FC_FREE(pFont_with_FullPath); while(Font_TAB) { if (Font_TAB->next) { Font_TAB_TMP = Font_TAB; Font_TAB = Font_TAB->next; if(Font_TAB_TMP->font) { TTF_CloseFont(Font_TAB_TMP->font); } FC_FREE(Font_TAB_TMP); } else { if(Font_TAB->font) { TTF_CloseFont(Font_TAB->font); } FC_FREE(Font_TAB); } } }
/************************************************************************** Free player from use with threaded AI. **************************************************************************/ void tai_player_free(struct ai_type *ait, struct player *pplayer) { struct tai_plr *player_data = player_ai_data(pplayer, ait); /* Default AI */ dai_data_close(ait, pplayer); if (player_data != NULL) { player_set_ai_data(pplayer, ait, NULL); FC_FREE(player_data); } }
void tilespec_free_city_icons(void) { if (!pIcons) { return; } FREESURFACE(pIcons->pBIG_Food_Corr); FREESURFACE(pIcons->pBIG_Shield_Corr); FREESURFACE(pIcons->pBIG_Trade_Corr); FREESURFACE(pIcons->pBIG_Food); FREESURFACE(pIcons->pBIG_Food_Surplus); FREESURFACE(pIcons->pBIG_Shield); FREESURFACE(pIcons->pBIG_Shield_Surplus); FREESURFACE(pIcons->pBIG_Trade); FREESURFACE(pIcons->pBIG_Luxury); FREESURFACE(pIcons->pBIG_Coin); FREESURFACE(pIcons->pBIG_Colb); FREESURFACE(pIcons->pBIG_Face); FREESURFACE(pIcons->pBIG_Coin_Corr); FREESURFACE(pIcons->pBIG_Coin_UpKeep); FREESURFACE(pIcons->pFood); FREESURFACE(pIcons->pShield); FREESURFACE(pIcons->pTrade); FREESURFACE(pIcons->pFace); FREESURFACE(pIcons->pLuxury); FREESURFACE(pIcons->pCoin); FREESURFACE(pIcons->pColb); FREESURFACE(pIcons->pPollution); FREESURFACE(pIcons->pPolice); FREESURFACE(pIcons->pWorklist); /* small citizens */ FREESURFACE(pIcons->pMale_Content); FREESURFACE(pIcons->pFemale_Content); FREESURFACE(pIcons->pMale_Happy); FREESURFACE(pIcons->pFemale_Happy); FREESURFACE(pIcons->pMale_Unhappy); FREESURFACE(pIcons->pFemale_Unhappy); FREESURFACE(pIcons->pMale_Angry); FREESURFACE(pIcons->pFemale_Angry); FREESURFACE(pIcons->pSpec_Lux); /* Elvis */ FREESURFACE(pIcons->pSpec_Tax); /* TaxMan */ FREESURFACE(pIcons->pSpec_Sci); /* Scientist */ FC_FREE(pIcons); }
/************************************************************************** ... **************************************************************************/ void widget_free(struct widget **pWidget) { struct widget *pGUI = *pWidget; if ((get_wflags(pGUI) & WF_FREE_STRING) == WF_FREE_STRING) { FREESTRING16(pGUI->string16); } if ((get_wflags(pGUI) & WF_WIDGET_HAS_INFO_LABEL) == WF_WIDGET_HAS_INFO_LABEL) { FREESTRING16(pGUI->info_label); } if ((get_wflags(pGUI) & WF_FREE_GFX) == WF_FREE_GFX) { FREESURFACE(pGUI->gfx); } if ((get_wflags(pGUI) & WF_FREE_THEME) == WF_FREE_THEME) { if (get_wtype(pGUI) == WT_CHECKBOX) { FREESURFACE(pGUI->private_data.cbox->pTRUE_Theme); FREESURFACE(pGUI->private_data.cbox->pFALSE_Theme); } else { FREESURFACE(pGUI->theme); } } if ((get_wflags(pGUI) & WF_FREE_THEME2) == WF_FREE_THEME2) { FREESURFACE(pGUI->theme2); } if ((get_wflags(pGUI) & WF_FREE_DATA) == WF_FREE_DATA) { FC_FREE(pGUI->data.ptr); } if ((get_wflags(pGUI) & WF_FREE_PRIVATE_DATA) == WF_FREE_PRIVATE_DATA) { FC_FREE(pGUI->private_data.ptr); } if (NULL != pGUI->destroy) { pGUI->destroy(pGUI); } FC_FREE(*pWidget); }
/************************************************************************** Handle messages from message queue. **************************************************************************/ static enum tai_abort_msg_class tai_check_messages(void) { enum tai_abort_msg_class ret_abort= TAI_ABORT_NONE; taimsg_list_allocate_mutex(thrai.msgs_to.msglist); while(taimsg_list_size(thrai.msgs_to.msglist) > 0) { struct tai_msg *msg; enum tai_abort_msg_class new_abort = TAI_ABORT_NONE; msg = taimsg_list_get(thrai.msgs_to.msglist, 0); taimsg_list_remove(thrai.msgs_to.msglist, msg); taimsg_list_release_mutex(thrai.msgs_to.msglist); log_debug("Plr thr got %s", taimsgtype_name(msg->type)); switch(msg->type) { case TAI_MSG_FIRST_ACTIVITIES: /* Not implemented */ break; case TAI_MSG_PHASE_FINISHED: new_abort = TAI_ABORT_PHASE_END; break; case TAI_MSG_THR_EXIT: new_abort = TAI_ABORT_EXIT; break; default: log_error("Illegal message type %s (%d) for threaded ai!", taimsgtype_name(msg->type), msg->type); break; } if (new_abort < ret_abort) { ret_abort = new_abort; } FC_FREE(msg); taimsg_list_allocate_mutex(thrai.msgs_to.msglist); } taimsg_list_release_mutex(thrai.msgs_to.msglist); return ret_abort; }
/************************************************************************** ... **************************************************************************/ void unload_font(Uint16 ptsize) { int index; struct TTF_Font_Chain *Font_TAB_PREV = NULL; struct TTF_Font_Chain *Font_TAB_TMP = Font_TAB; if (Sizeof_Font_TAB == 0) { log_error("unload_font: Trying unload from empty Font ARRAY"); return; } for (index = 0; index < Sizeof_Font_TAB; index++) { if (Font_TAB_TMP->ptsize == ptsize) { break; } Font_TAB_PREV = Font_TAB_TMP; Font_TAB_TMP = Font_TAB_TMP->next; } if (index == Sizeof_Font_TAB) { log_error("unload_font: Trying unload Font which is " "not included in Font ARRAY"); return; } Font_TAB_TMP->count--; if (Font_TAB_TMP->count) { return; } TTF_CloseFont(Font_TAB_TMP->font); Font_TAB_TMP->font = NULL; if (Font_TAB_TMP == Font_TAB) { Font_TAB = Font_TAB_TMP->next; } else { Font_TAB_PREV->next = Font_TAB_TMP->next; } Font_TAB_TMP->next = NULL; Sizeof_Font_TAB--; FC_FREE(Font_TAB_TMP); }
/************************************************************************** Check for messages sent by player thread **************************************************************************/ void tai_refresh(struct ai_type *ait, struct player *pplayer) { if (thrai.thread_running) { taireq_list_allocate_mutex(thrai.reqs_from.reqlist); while(taireq_list_size(thrai.reqs_from.reqlist) > 0) { struct tai_req *req; req = taireq_list_get(thrai.reqs_from.reqlist, 0); taireq_list_remove(thrai.reqs_from.reqlist, req); taireq_list_release_mutex(thrai.reqs_from.reqlist); log_normal("Plr thr sent %s", taireqtype_name(req->type)); FC_FREE(req); taireq_list_allocate_mutex(thrai.reqs_from.reqlist); } taireq_list_release_mutex(thrai.reqs_from.reqlist); } }
/************************************************************************** Unsellect (sellected) widget and redraw this widget; **************************************************************************/ void unsellect_widget_action(void) { if (pSellected_Widget && (get_wstate(pSellected_Widget) != FC_WS_DISABLED)) { set_wstate(pSellected_Widget, FC_WS_NORMAL); if (!(get_wflags(pSellected_Widget) & WF_HIDDEN)) { pSellected_Widget->unselect(pSellected_Widget); /* turn off quick info timer/counter */ widget_info_counter = 0; } } if (pInfo_Area) { flush_rect(*pInfo_Area, FALSE); FC_FREE(pInfo_Area); FREESURFACE(pInfo_Label); } pSellected_Widget = NULL; }
/***************************************************************************** Initialize the scripting state. *****************************************************************************/ struct fc_lua *luascript_new(luascript_log_func_t output_fct) { struct fc_lua *fcl = fc_calloc(1, sizeof(*fcl)); fcl->state = luaL_newstate(); if (!fcl->state) { FC_FREE(fcl); return NULL; } fcl->output_fct = output_fct; fcl->caller = NULL; luascript_openlibs(fcl->state, luascript_lualibs); luascript_traceback_func_save(fcl->state); luascript_blacklist(fcl->state, luascript_unsafe_symbols); /* Save the freeciv lua struct in the lua state. */ lua_pushstring(fcl->state, LUASCRIPT_GLOBAL_VAR_NAME); lua_pushlightuserdata(fcl->state, fcl); lua_settable(fcl->state, LUA_REGISTRYINDEX); return fcl; }
/************************************************************************** Convert string from local encoding (8 bit char) to display encoding (16 bit unicode) and resut put in pToUniString. if pToUniString == NULL then resulting string will be allocate automaticaly. 'ulength' give real sizeof 'pToUniString' array. Function return (Uint16 *) pointer to (new) pToUniString. **************************************************************************/ Uint16 *convertcopy_to_utf16(Uint16 *pToUniString, size_t ulength, const char *pFromString) { /* Start Parametrs */ const char *pTocode = get_display_encoding(); const char *pFromcode = get_internal_encoding(); const char *pStart = pFromString; size_t length = strlen(pFromString) + 1; Uint16 *pResult = pToUniString; /* ===== */ iconv_t cd = iconv_open(pTocode, pFromcode); if (cd == (iconv_t) (-1)) { if (errno != EINVAL) { return pToUniString; } } if (!pResult) { /* From 8 bit code to UTF-16 (16 bit code) */ ulength = length * 2; pResult = fc_calloc(1, ulength); } iconv(cd, NULL, NULL, NULL, NULL); /* return to the initial state */ /* Do the conversion for real. */ { const char *pInptr = pStart; size_t Insize = length; char *pOutptr = (char *)pResult; size_t Outsize = ulength; while (Insize > 0 && Outsize > 0) { size_t Res = iconv(cd, (ICONV_CONST char **) &pInptr, &Insize, &pOutptr, &Outsize); if (Res == (size_t) (-1)) { if (errno == EINVAL) { break; } else { int saved_errno = errno; iconv_close(cd); errno = saved_errno; if (!pToUniString) { FC_FREE(pResult); } return pToUniString; } } } { size_t Res = iconv(cd, NULL, NULL, &pOutptr, &Outsize); if (Res == (size_t) (-1)) { int saved_errno = errno; iconv_close(cd); errno = saved_errno; if (!pToUniString) { FC_FREE(pResult); } return pToUniString; } } } iconv_close(cd); return (Uint16 *) pResult; }
/************************************************************************** Convert string from display encoding (16 bit unicode) to local encoding (8 bit char) and resut put in 'pToString'. if 'pToString' == NULL then resulting string will be allocate automaticaly. 'length' give real sizeof 'pToString' array. Function return (char *) pointer to (new) pToString. **************************************************************************/ char *convertcopy_to_chars(char *pToString, size_t length, const Uint16 * pFromUniString) { /* Start Parametrs */ const char *pFromcode = get_display_encoding(); const char *pTocode = get_internal_encoding(); const char *pStart = (char *) pFromUniString; size_t ulength = (unistrlen(pFromUniString) + 1) * 2; /* ===== */ char *pResult; iconv_t cd; /* ===== */ if (!pStart) { return pToString; } cd = iconv_open(pTocode, pFromcode); if (cd == (iconv_t) (-1)) { if (errno != EINVAL) { return pToString; } } if (pToString) { pResult = pToString; } else { length = ulength * 2; /* UTF-8: up to 4 bytes per char */ pResult = fc_calloc(1, length); } iconv(cd, NULL, NULL, NULL, NULL); /* return to the initial state */ /* Do the conversion for real. */ { const char *pInptr = pStart; size_t Insize = ulength; char *pOutptr = pResult; size_t Outsize = length; while (Insize > 0 && Outsize > 0) { size_t Res = iconv(cd, (ICONV_CONST char **) &pInptr, &Insize, &pOutptr, &Outsize); if (Res == (size_t) (-1)) { log_error("iconv() error: %s", fc_strerror(fc_get_errno())); if (errno == EINVAL) { break; } else { int saved_errno = errno; iconv_close(cd); errno = saved_errno; if(!pToString) { FC_FREE(pResult); } return pToString; } } } { size_t Res = iconv(cd, NULL, NULL, &pOutptr, &Outsize); if (Res == (size_t) (-1)) { int saved_errno = errno; iconv_close(cd); errno = saved_errno; if(!pToString) { FC_FREE(pResult); } return pToString; } } } iconv_close(cd); return pResult; }
/************************************************************************** ... **************************************************************************/ SDL_Rect str16size(SDL_String16 *pString16) { SDL_Rect Ret = {0, 0, 0, 0}; if (pString16 && pString16->text && pString16->text != '\0') { Uint16 *pStr16 = pString16->text; Uint16 c = *pStr16; bool new_line = FALSE; int w, h; /* find '\n' */ while (c != '\0') { if (c == 10) { new_line = TRUE; break; } pStr16++; c = *pStr16; } if (!((pString16->style & 0x0F) & TTF_STYLE_NORMAL)) { TTF_SetFontStyle(pString16->font, (pString16->style & 0x0F)); } if (new_line) { int ww, hh, count = 0; Uint16 **UniTexts = create_new_line_unistrings(pString16->text); w = 0; h = 0; while (UniTexts[count]) { if (TTF_SizeUNICODE(pString16->font, UniTexts[count], &ww, &hh) < 0) { do { FC_FREE(UniTexts[count]); count++; } while(UniTexts[count]); log_error("TTF_SizeUNICODE return ERROR !"); } w = MAX(w, ww); h += hh; FC_FREE(UniTexts[count]); count++; } } else { if (TTF_SizeUNICODE(pString16->font, pString16->text, &w, &h) < 0) { log_error("TTF_SizeUNICODE return ERROR !"); } } if (!((pString16->style & 0x0F) & TTF_STYLE_NORMAL)) { TTF_SetFontStyle(pString16->font, TTF_STYLE_NORMAL); } Ret.w = w; Ret.h = h; } else { Ret.h = (pString16 ? TTF_FontHeight(pString16->font) : 0); } return Ret; }
/************************************************************************** ... **************************************************************************/ static SDL_Surface *create_str16_multi_surf(SDL_String16 * pString) { SDL_Rect des = {0, 0, 0, 0}; SDL_Surface *pText = NULL, **pTmp = NULL; Uint16 i, w = 0, count = 0; Uint32 color; Uint16 *pBuf = pString->text; Uint16 **UniTexts = create_new_line_unistrings(pString->text); while (UniTexts[count]) { count++; } pTmp = fc_calloc(count, sizeof(SDL_Surface *)); for (i = 0; i < count; i++) { pString->text = UniTexts[i]; pTmp[i] = create_str16_surf(pString); } pString->text = pBuf; /* find max len */ for (i = 0; i < count; i++) { if (pTmp[i]->w > w) { w = pTmp[i]->w; } } /* create and fill surface */ color = pTmp[0]->format->colorkey; switch (pString->render) { case 1: pText = create_surf(w, count * pTmp[0]->h, SDL_SWSURFACE); SDL_FillRect(pText, NULL, color); SDL_SetColorKey(pText, SDL_SRCCOLORKEY, color); break; case 2: pText = create_surf_with_format(pTmp[0]->format, w, count * pTmp[0]->h, pTmp[0]->flags); SDL_FillRect(pText, NULL, color); break; default: pText = create_surf(w, count * pTmp[0]->h, SDL_SWSURFACE); SDL_FillRect(pText, NULL, color); break; } /* blit (default: center left) */ for (i = 0; i < count; i++) { if (pString->style & SF_CENTER) { des.x = (w - pTmp[i]->w) / 2; } else { if (pString->style & SF_CENTER_RIGHT) { des.x = w - pTmp[i]->w; } else { des.x = 0; } } alphablit(pTmp[i], NULL, pText, &des); des.y += pTmp[i]->h; } /* Free Memmory */ for (i = 0; i < count; i++) { FC_FREE(UniTexts[i]); FREESURFACE(pTmp[i]); } FC_FREE(pTmp); return pText; }
/************************************************************************** Create Edit Field surface ( with Text) and blit them to Main.screen, on position 'pEdit_Widget->size.x , pEdit_Widget->size.y' Graphic is taken from 'pEdit_Widget->theme' Text is taken from 'pEdit_Widget->sting16' if flag 'FW_DRAW_THEME_TRANSPARENT' is set theme will be blit transparent ( Alpha = 128 ) function return Hight of created surfaces or (-1) if theme surface can't be created. **************************************************************************/ static int redraw_edit(struct widget *pEdit_Widget) { int ret; if (get_wstate(pEdit_Widget) == FC_WS_PRESSED) { return redraw_edit_chain((struct EDIT *)pEdit_Widget->data.ptr); } else { int iRet = 0; SDL_Rect rDest = {pEdit_Widget->size.x, pEdit_Widget->size.y, 0, 0}; SDL_Surface *pEdit = NULL; SDL_Surface *pText; ret = (*baseclass_redraw)(pEdit_Widget); if (ret != 0) { return ret; } if (pEdit_Widget->string16->text && get_wflags(pEdit_Widget) & WF_PASSWD_EDIT) { Uint16 *backup = pEdit_Widget->string16->text; size_t len = unistrlen(backup) + 1; char *cBuf = fc_calloc(1, len); memset(cBuf, '*', len - 1); cBuf[len - 1] = '\0'; pEdit_Widget->string16->text = convert_to_utf16(cBuf); pText = create_text_surf_from_str16(pEdit_Widget->string16); FC_FREE(pEdit_Widget->string16->text); FC_FREE(cBuf); pEdit_Widget->string16->text = backup; } else { pText = create_text_surf_from_str16(pEdit_Widget->string16); } pEdit = create_bcgnd_surf(pEdit_Widget->theme, get_wstate(pEdit_Widget), pEdit_Widget->size.w, pEdit_Widget->size.h); if (!pEdit) { return -1; } /* blit theme */ alphablit(pEdit, NULL, pEdit_Widget->dst->surface, &rDest); /* set position and blit text */ if (pText) { rDest.y += (pEdit->h - pText->h) / 2; /* blit centred text to botton */ if (pEdit_Widget->string16->style & SF_CENTER) { rDest.x += (pEdit->w - pText->w) / 2; } else { if (pEdit_Widget->string16->style & SF_CENTER_RIGHT) { rDest.x += pEdit->w - pText->w - adj_size(5); } else { rDest.x += adj_size(5); /* cennter left */ } } alphablit(pText, NULL, pEdit_Widget->dst->surface, &rDest); } /* pText */ iRet = pEdit->h; /* Free memory */ FREESURFACE(pText); FREESURFACE(pEdit); return iRet; } return 0; }
/************************************************************************** This functions are pure madness :) Create Edit Field surface ( with Text) and blit them to Main.screen, on position 'pEdit_Widget->size.x , pEdit_Widget->size.y' Main role of this functions are been text input to GUI. This code allow you to add, del unichar from unistring. Graphic is taken from 'pEdit_Widget->theme' OldText is taken from 'pEdit_Widget->sting16' NewText is returned to 'pEdit_Widget->sting16' ( after free OldText ) if flag 'FW_DRAW_THEME_TRANSPARENT' is set theme will be blit transparent ( Alpha = 128 ) NOTE: This functions can return NULL in 'pEdit_Widget->sting16->text' but never free 'pEdit_Widget->sting16' struct. **************************************************************************/ static Uint16 edit_key_down(SDL_keysym Key, void *pData) { struct EDIT *pEdt = (struct EDIT *)pData; struct UniChar *pInputChain_TMP; bool Redraw = FALSE; /* find which key is pressed */ switch (Key.sym) { case SDLK_ESCAPE: /* exit from loop without changes */ return ED_ESC; case SDLK_RETURN: case SDLK_KP_ENTER: /* exit from loop */ return ED_RETURN; case SDLK_KP6: if(Key.mod & KMOD_NUM) { goto INPUT; } case SDLK_RIGHT: { /* move cursor right */ if (pEdt->pInputChain->next) { if (pEdt->InputChain_X >= (pEdt->pWidget->size.x + pEdt->pBg->w - adj_size(10))) { pEdt->Start_X -= pEdt->pInputChain->pTsurf->w - (pEdt->pWidget->size.x + pEdt->pBg->w - adj_size(5) - pEdt->InputChain_X); } pEdt->pInputChain = pEdt->pInputChain->next; Redraw = TRUE; } } break; case SDLK_KP4: if(Key.mod & KMOD_NUM) { goto INPUT; } case SDLK_LEFT: { /* move cursor left */ if (pEdt->pInputChain->prev) { pEdt->pInputChain = pEdt->pInputChain->prev; if ((pEdt->InputChain_X <= (pEdt->pWidget->size.x + adj_size(9))) && (pEdt->Start_X != adj_size(5))) { if (pEdt->InputChain_X != (pEdt->pWidget->size.x + adj_size(5))) { pEdt->Start_X += (pEdt->pWidget->size.x - pEdt->InputChain_X + adj_size(5)); } pEdt->Start_X += (pEdt->pInputChain->pTsurf->w); } Redraw = TRUE; } } break; case SDLK_KP7: if(Key.mod & KMOD_NUM) { goto INPUT; } case SDLK_HOME: { /* move cursor to begin of chain (and edit field) */ pEdt->pInputChain = pEdt->pBeginTextChain; Redraw = TRUE; pEdt->Start_X = adj_size(5); } break; case SDLK_KP1: if(Key.mod & KMOD_NUM) { goto INPUT; } case SDLK_END: { /* move cursor to end of chain (and edit field) */ pEdt->pInputChain = pEdt->pEndTextChain; Redraw = TRUE; if (pEdt->pWidget->size.w - pEdt->Truelength < 0) { pEdt->Start_X = pEdt->pWidget->size.w - pEdt->Truelength - adj_size(5); } } break; case SDLK_BACKSPACE: { /* del element of chain (and move cursor left) */ if (pEdt->pInputChain->prev) { if ((pEdt->InputChain_X <= (pEdt->pWidget->size.x + adj_size(9))) && (pEdt->Start_X != adj_size(5))) { if (pEdt->InputChain_X != (pEdt->pWidget->size.x + adj_size(5))) { pEdt->Start_X += (pEdt->pWidget->size.x - pEdt->InputChain_X + adj_size(5)); } pEdt->Start_X += (pEdt->pInputChain->prev->pTsurf->w); } if (pEdt->pInputChain->prev->prev) { pEdt->pInputChain->prev->prev->next = pEdt->pInputChain; pInputChain_TMP = pEdt->pInputChain->prev->prev; pEdt->Truelength -= pEdt->pInputChain->prev->pTsurf->w; FREESURFACE(pEdt->pInputChain->prev->pTsurf); FC_FREE(pEdt->pInputChain->prev); pEdt->pInputChain->prev = pInputChain_TMP; } else { pEdt->Truelength -= pEdt->pInputChain->prev->pTsurf->w; FREESURFACE(pEdt->pInputChain->prev->pTsurf); FC_FREE(pEdt->pInputChain->prev); pEdt->pBeginTextChain = pEdt->pInputChain; } pEdt->ChainLen--; Redraw = TRUE; } } break; case SDLK_KP_PERIOD: if(Key.mod & KMOD_NUM) { goto INPUT; } case SDLK_DELETE: { /* del element of chain */ if (pEdt->pInputChain->next && pEdt->pInputChain->prev) { pEdt->pInputChain->prev->next = pEdt->pInputChain->next; pEdt->pInputChain->next->prev = pEdt->pInputChain->prev; pInputChain_TMP = pEdt->pInputChain->next; pEdt->Truelength -= pEdt->pInputChain->pTsurf->w; FREESURFACE(pEdt->pInputChain->pTsurf); FC_FREE(pEdt->pInputChain); pEdt->pInputChain = pInputChain_TMP; pEdt->ChainLen--; Redraw = TRUE; } if (pEdt->pInputChain->next && !pEdt->pInputChain->prev) { pEdt->pInputChain = pEdt->pInputChain->next; pEdt->Truelength -= pEdt->pInputChain->prev->pTsurf->w; FREESURFACE(pEdt->pInputChain->prev->pTsurf); FC_FREE(pEdt->pInputChain->prev); pEdt->pBeginTextChain = pEdt->pInputChain; pEdt->ChainLen--; Redraw = TRUE; } } break; default: { INPUT:/* add new element of chain (and move cursor right) */ if (Key.unicode) { if (pEdt->pInputChain != pEdt->pBeginTextChain) { pInputChain_TMP = pEdt->pInputChain->prev; pEdt->pInputChain->prev = fc_calloc(1, sizeof(struct UniChar)); pEdt->pInputChain->prev->next = pEdt->pInputChain; pEdt->pInputChain->prev->prev = pInputChain_TMP; pInputChain_TMP->next = pEdt->pInputChain->prev; } else { pEdt->pInputChain->prev = fc_calloc(1, sizeof(struct UniChar)); pEdt->pInputChain->prev->next = pEdt->pInputChain; pEdt->pBeginTextChain = pEdt->pInputChain->prev; } pEdt->pInputChain->prev->chr[0] = Key.unicode; pEdt->pInputChain->prev->chr[1] = '\0'; if (pEdt->pInputChain->prev->chr) { if (get_wflags(pEdt->pWidget) & WF_PASSWD_EDIT) { Uint16 passwd_chr[2] = {'*', '\0'}; pEdt->pInputChain->prev->pTsurf = TTF_RenderUNICODE_Blended(pEdt->pWidget->string16->font, passwd_chr, pEdt->pWidget->string16->fgcol); } else { pEdt->pInputChain->prev->pTsurf = TTF_RenderUNICODE_Blended(pEdt->pWidget->string16->font, pEdt->pInputChain->prev->chr, pEdt->pWidget->string16->fgcol); } pEdt->Truelength += pEdt->pInputChain->prev->pTsurf->w; } if (pEdt->InputChain_X >= pEdt->pWidget->size.x + pEdt->pBg->w - adj_size(10)) { if (pEdt->pInputChain == pEdt->pEndTextChain) { pEdt->Start_X = pEdt->pBg->w - adj_size(5) - pEdt->Truelength; } else { pEdt->Start_X -= pEdt->pInputChain->prev->pTsurf->w - (pEdt->pWidget->size.x + pEdt->pBg->w - adj_size(5) - pEdt->InputChain_X); } } pEdt->ChainLen++; Redraw = TRUE; } } break; } /* key pressed switch */ if (Redraw) { redraw_edit_chain(pEdt); } return ID_ERROR; }
enum Edit_Return_Codes edit_field(struct widget *pEdit_Widget) { struct EDIT pEdt; struct UniChar ___last; struct UniChar *pInputChain_TMP = NULL; enum Edit_Return_Codes ret; void *backup = pEdit_Widget->data.ptr; pEdt.pWidget = pEdit_Widget; pEdt.ChainLen = 0; pEdt.Truelength = 0; pEdt.Start_X = adj_size(5); pEdt.InputChain_X = 0; pEdit_Widget->data.ptr = (void *)&pEdt; SDL_EnableUNICODE(1); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); pEdt.pBg = create_bcgnd_surf(pEdit_Widget->theme, 2, pEdit_Widget->size.w, pEdit_Widget->size.h); /* Creating Chain */ pEdt.pBeginTextChain = text2chain(pEdit_Widget->string16->text); /* Creating Empty (Last) pice of Chain */ pEdt.pInputChain = &___last; pEdt.pEndTextChain = pEdt.pInputChain; pEdt.pEndTextChain->chr[0] = 32; /*spacebar */ pEdt.pEndTextChain->chr[1] = 0; /*spacebar */ pEdt.pEndTextChain->next = NULL; pEdt.pEndTextChain->prev = NULL; /* set font style (if any ) */ if (!((pEdit_Widget->string16->style & 0x0F) & TTF_STYLE_NORMAL)) { TTF_SetFontStyle(pEdit_Widget->string16->font, (pEdit_Widget->string16->style & 0x0F)); } pEdt.pEndTextChain->pTsurf = TTF_RenderUNICODE_Blended(pEdit_Widget->string16->font, pEdt.pEndTextChain->chr, pEdit_Widget->string16->fgcol); /* create surface for each font in chain and find chain length */ if (pEdt.pBeginTextChain) { pInputChain_TMP = pEdt.pBeginTextChain; while (TRUE) { pEdt.ChainLen++; pInputChain_TMP->pTsurf = TTF_RenderUNICODE_Blended(pEdit_Widget->string16->font, pInputChain_TMP->chr, pEdit_Widget->string16->fgcol); pEdt.Truelength += pInputChain_TMP->pTsurf->w; if (pInputChain_TMP->next == NULL) { break; } pInputChain_TMP = pInputChain_TMP->next; } /* set terminator of list */ pInputChain_TMP->next = pEdt.pInputChain; pEdt.pInputChain->prev = pInputChain_TMP; pInputChain_TMP = NULL; } else { pEdt.pBeginTextChain = pEdt.pInputChain; } redraw_edit_chain(&pEdt); set_wstate(pEdit_Widget, FC_WS_PRESSED); { /* local loop */ Uint16 rety = gui_event_loop((void *)&pEdt, NULL, edit_key_down, NULL, edit_mouse_button_down, NULL, NULL); if (pEdt.pBeginTextChain == pEdt.pEndTextChain) { pEdt.pBeginTextChain = NULL; } if (rety == MAX_ID) { ret = ED_FORCE_EXIT; } else { ret = (enum Edit_Return_Codes) rety; /* this is here becouse we have no knowladge that pEdit_Widget exist or nor in force exit mode from gui loop */ /* reset font settings */ if (!((pEdit_Widget->string16->style & 0x0F) & TTF_STYLE_NORMAL)) { TTF_SetFontStyle(pEdit_Widget->string16->font, TTF_STYLE_NORMAL); } if(ret != ED_ESC) { FC_FREE(pEdit_Widget->string16->text); pEdit_Widget->string16->text = chain2text(pEdt.pBeginTextChain, pEdt.ChainLen); pEdit_Widget->string16->n_alloc = (pEdt.ChainLen + 1) * sizeof(Uint16); } pEdit_Widget->data.ptr = backup; set_wstate(pEdit_Widget, FC_WS_NORMAL); } } FREESURFACE(pEdt.pEndTextChain->pTsurf); del_chain(pEdt.pBeginTextChain); FREESURFACE(pEdt.pBg); /* disable repeate key */ SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL); /* disable Unicode */ SDL_EnableUNICODE(0); return ret; }
/**************************************************************************** Free any resources associated with this canvas and the canvas struct itself. ****************************************************************************/ void canvas_free(struct canvas *store) { freelog(LOG_VERBOSE, "Deleting canvas"); FC_FREE(store->data); }
/**************************************************************************** Free a sprite and all associated image data. ****************************************************************************/ void free_sprite(struct sprite *s) { fc_assert_ret(s != NULL); FREESURFACE(GET_SURF_REAL(s)); FC_FREE(s); }