00001
00025 #include <string.h>
00026 #include <stdlib.h>
00027 #include "color.h"
00028 #include "genconmac.h"
00029 #include "hostlookup.h"
00030 #include "netstat.h"
00031 #include "text.h"
00032 #include "timesync.h"
00033 #include "net.h"
00034 #ifndef WIN32
00035 #include <sys/types.h>
00036 #include <sys/socket.h>
00037 #include <arpa/inet.h>
00038 #endif
00039
00040 char statHost[MAX_HOST_LEN];
00041
00047 struct NetStatData_t {
00051 int prevNetStat;
00056 int prevSyncStat;
00060 Bool gotHost;
00061 };
00062
00063 typedef struct NetStatData_t NetStatData;
00064
00071 #define netdat ((NetStatData*)(item->data))
00072
00073 Bool NetStatInit(MenuItem *item) {
00074
00075 if ((item->data = malloc(sizeof(NetStatData))) == NULL) {
00076
00077 return FALSE;
00078 }
00079 netdat->prevNetStat = netdat->prevSyncStat = -1;
00080
00081 item->minWidth = 480;
00082 item->minHeight = (textItems[TEXTITEM_FIREOPT].loc.h << 1) + 2;
00083 item->focus = NetStatFocus;
00084 item->input = NetStatInput;
00085 item->update = NetStatUpdate;
00086 item->active = TRUE;
00087
00088 if (textItems[TEXTITEM_NETSTAT].renderer == NULL) {
00089
00090
00091 textItems[TEXTITEM_NETSTAT].renderer = (ItemRenderer)1;
00092 }
00093 AddRenderItem(&(textItems[TEXTITEM_NETSTAT]), LAYER_TEXT);
00094 if (textItems[TEXTITEM_NETOPTS].renderer == NULL) {
00095 textItems[TEXTITEM_NETOPTS].renderer = (ItemRenderer)1;
00096 }
00097 AddRenderItem(&(textItems[TEXTITEM_NETOPTS]), LAYER_TEXT);
00098
00099
00100 return TRUE;
00101 }
00102
00103 void NetStatUninit(MenuItem *item) {
00104 free(netdat);
00105 }
00106
00107 extern SocketAddr outgoingAddr;
00108
00116 static void RenderLocalAddr(MenuItem *item) {
00117
00118 TextRenderString(&(textItems[TEXTITEM_NETOPTS]), FONT_SCORE, 0,
00119 colorFmtInd[COLOR_TEXT], strings[STRING_NETADDR], localhostAddrStr);
00120
00121 textItems[TEXTITEM_NETOPTS].loc.x = item->region.x +
00122 ((item->region.w - textItems[TEXTITEM_NETOPTS].loc.w) >> 1);
00123 textItems[TEXTITEM_NETOPTS].loc.y = item->region.y +
00124 textItems[TEXTITEM_NETOPTS].loc.h + 2;
00125 }
00126
00133 static void RenderTSync(MenuItem *item) {
00134
00135 TextRenderString(&(textItems[TEXTITEM_NETOPTS]), FONT_SCORE, 0,
00136 colorFmtInd[COLOR_TEXT], strings[STRING_NETSYNC]);
00137
00138 textItems[TEXTITEM_NETOPTS].loc.x = item->region.x +
00139 ((item->region.w - textItems[TEXTITEM_NETOPTS].loc.w) >> 1);
00140 textItems[TEXTITEM_NETOPTS].loc.y = item->region.y +
00141 textItems[TEXTITEM_NETOPTS].loc.h + 2;
00142 }
00143
00150 static void RenderLatency(MenuItem *item) {
00151
00152 TextRenderString(&(textItems[TEXTITEM_NETOPTS]), FONT_SCORE, 0,
00153 colorFmtInd[COLOR_TEXT], strings[STRING_NETLAT], timeSyncResults.latency);
00154
00155 textItems[TEXTITEM_NETOPTS].loc.x = item->region.x +
00156 ((item->region.w - textItems[TEXTITEM_NETOPTS].loc.w) >> 1);
00157 textItems[TEXTITEM_NETOPTS].loc.y = item->region.y +
00158 textItems[TEXTITEM_NETOPTS].loc.h + 2;
00159 }
00160
00161 int NetStatUpdate(MenuItem *item) {
00162
00163
00164 if (!item->isPlaced) {
00165
00166 item->isPlaced = TRUE;
00167
00168 netdat->gotHost = FALSE;
00169
00170
00171
00172 textItems[TEXTITEM_FIREOPT].loc.x = item->region.x +
00173 ((item->region.w - textItems[TEXTITEM_FIREOPT].loc.w) >> 1);
00174 textItems[TEXTITEM_FIREOPT].loc.y = item->region.y +
00175 textItems[TEXTITEM_FIREOPT].loc.h + 2;
00176
00177
00178 if (localhostAddrStr[0]) {
00179
00180 RenderLocalAddr(item);
00181 }
00182
00183
00184 if (item->hasFocus) {
00185
00186 PlaceRenderItem(&(textItems[TEXTITEM_FIREOPT]));
00187 }
00188 else if (localhostAddrStr[0]) {
00189
00190 PlaceRenderItem(&(textItems[TEXTITEM_NETOPTS]));
00191 }
00192 goto NetStatUpdate_statStr;
00193 }
00194
00195 if ((netdat->prevNetStat != networkState) ||
00196 (!netdat->gotHost && (LookupResult(NULL, NULL) != 0))) {
00197 rtsa_char const *str;
00198 #ifndef WIN32
00199 char addrstr[INET6_ADDRSTRLEN];
00200 #endif
00201 NetStatUpdate_statStr:
00202
00203 netdat->prevNetStat = networkState;
00204
00205 if ((networkState == NETSTATE_CONNECTING) ||
00206 (networkState == NETSTATE_RCVCFG) ||
00207 (networkState == NETSTATE_CLIENT) ||
00208 (networkState == NETSTATE_SRVDENY)) {
00209
00210 if ((statHost[0] == 0) &&
00211 #ifdef WIN32
00212
00213 ((str = (rtsa_char*)inet_ntoa(outgoingAddr.ipv4.sin_addr)) != NULL)) {
00214
00215 }
00216 #else
00217 (inet_ntop(outgoingAddr.addr.sa_family,
00218 (outgoingAddr.addr.sa_family == AF_INET) ?
00219 (void*)&(outgoingAddr.ipv4.sin_addr) :
00220 (void*)&(outgoingAddr.ipv6.sin6_addr),
00221 addrstr, INET6_ADDRSTRLEN) != NULL)) {
00222
00223 str = (rtsa_char*)addrstr;
00224 }
00225 #endif
00226 else {
00227
00228 str = (rtsa_char*)statHost;
00229 netdat->gotHost = TRUE;
00230 }
00231 }
00232 else if ((netdat->prevNetStat >= NETSTATE_SEARCHERR) &&
00233 (netdat->prevNetStat <= NETSTATE_CONERR)) {
00234 str = GetNetErrorString(netError);
00235 }
00236 else {
00237 str = (rtsa_char*)localhostName;
00238 }
00239
00240 TextRenderString(&(textItems[TEXTITEM_NETSTAT]), FONT_SCORE, 0,
00241 colorFmtInd[COLOR_TEXT],
00242 strings[STRING_NETLOOKING + netdat->prevNetStat - 1], str);
00243
00244 textItems[TEXTITEM_NETSTAT].loc.x = item->region.x + 2;
00245 textItems[TEXTITEM_NETSTAT].loc.y = item->region.y;
00246 PlaceRenderItem(&(textItems[TEXTITEM_NETSTAT]));
00247
00248 if (networkState == NETSTATE_DISCONN) {
00249 ClearRenderItem(&(textItems[TEXTITEM_NETOPTS]));
00250 }
00251 }
00252
00253 if (netdat->prevSyncStat != timeSyncState) {
00254
00255 netdat->prevSyncStat = timeSyncState;
00256
00257 if ((networkState == NETSTATE_RCVCFG) ||
00258 (networkState == NETSTATE_CLIENT)) {
00259
00260 switch (timeSyncState) {
00261 case TIMESYNC_INPROG:
00262 RenderTSync(item);
00263 break;
00264 case TIMESYNC_FINISHED:
00265 case TIMESYNC_POOR:
00266 RenderLatency(item);
00267 break;
00268 default:
00269 RenderLocalAddr(item);
00270 }
00271
00272 if (!item->hasFocus) {
00273 PlaceRenderItem(&(textItems[TEXTITEM_NETOPTS]));
00274 }
00275 }
00276
00277 else if (localhostAddrStr[0]) {
00278 RenderLocalAddr(item);
00279
00280 if (!item->hasFocus) {
00281 PlaceRenderItem(&(textItems[TEXTITEM_NETOPTS]));
00282 }
00283 }
00284 }
00285 return 0;
00286 }
00287
00288 void NetStatFocus(MenuItem *item) {
00289
00290 if (item->hasFocus) {
00291
00292 PlaceRenderItem(&(textItems[TEXTITEM_FIREOPT]));
00293 if (localhostAddrStr[0] || (timeSyncState &&
00294 (networkState == NETSTATE_CLIENT))) {
00295
00296 ClearRenderItem(&(textItems[TEXTITEM_NETOPTS]));
00297 }
00298 }
00299 else {
00300
00301 ClearRenderItem(&(textItems[TEXTITEM_FIREOPT]));
00302 if ((networkState != NETSTATE_DISCONN) && (localhostAddrStr[0] ||
00303 (timeSyncState && (networkState == NETSTATE_CLIENT)))) {
00304
00305 PlaceRenderItem(&(textItems[TEXTITEM_NETOPTS]));
00306 }
00307 }
00308 }
00309
00310 int NetStatInput(MenuItem *item, Uint8 *ec, rtsa_char keyval) {
00311
00312 return 0;
00313 }
00314