Replaced typo that caused unnecessary regeneration of fc_gitrev_gen.h
[freeciv.git] / client / gui-sdl / connectdlg.c
blobc083f7a08147d7eddc4d60a9d45ff676f5b4ebee
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 /**********************************************************************
15 connectdlg.c - description
16 -------------------
17 begin : Mon Jul 1 2002
18 copyright : (C) 2002 by Rafał Bursig
19 email : Rafał Bursig <bursig@poczta.fm>
20 **********************************************************************/
22 #ifdef HAVE_CONFIG_H
23 #include <fc_config.h>
24 #endif
26 #include <stdlib.h>
28 /* SDL */
29 #include <SDL/SDL.h>
31 /* utility */
32 #include "fcintl.h"
33 #include "log.h"
35 /* client */
36 #include "client_main.h"
37 #include "clinet.h" /* connect_to_server() */
38 #include "packhand.h"
39 #include "servers.h"
41 /* gui-sdl */
42 #include "chatline.h"
43 #include "colors.h"
44 #include "graphics.h"
45 #include "gui_iconv.h"
46 #include "gui_id.h"
47 #include "gui_main.h"
48 #include "gui_tilespec.h"
49 #include "mapview.h"
50 #include "messagewin.h"
51 #include "optiondlg.h"
52 #include "pages.h"
53 #include "themespec.h"
54 #include "widget.h"
56 #include "connectdlg.h"
58 static struct server_list *pServer_list = NULL;
59 static struct server_scan *pServer_scan = NULL;
61 static struct ADVANCED_DLG *pMeta_Severs = NULL;
62 static struct SMALL_DLG *pConnectDlg = NULL;
64 static int connect_callback(struct widget *pWidget);
65 static int convert_portnr_callback(struct widget *pWidget);
66 static int convert_playername_callback(struct widget *pWidget);
67 static int convert_servername_callback(struct widget *pWidget);
68 static void popup_new_user_passwd_dialog(const char *pMessage);
71 THESE FUNCTIONS ARE ONE BIG TMP SOLUTION AND SHOULD BE FULLY REWRITTEN !!
74 /**************************************************************************
75 really close and destroy the dialog.
76 **************************************************************************/
77 void really_close_connection_dialog(void)
79 /* PORTME */
82 /**************************************************************************
83 provide a packet handler for packet_game_load
84 **************************************************************************/
85 void handle_game_load(bool load_successful, const char *filename)
87 /* PORTME */
90 /**************************************************************************
91 User interacted with connect -widget
92 **************************************************************************/
93 static int connect_callback(struct widget *pWidget)
95 if (Main.event.button.button == SDL_BUTTON_LEFT) {
96 char errbuf[512];
98 if (connect_to_server(user_name, server_host, server_port,
99 errbuf, sizeof(errbuf)) != -1) {
100 } else {
101 output_window_append(ftc_any, errbuf);
103 /* button up */
104 unsellect_widget_action();
105 set_wstate(pWidget, FC_WS_SELLECTED);
106 pSellected_Widget = pWidget;
107 widget_redraw(pWidget);
108 widget_flush(pWidget);
111 return -1;
113 /* ======================================================== */
116 /**************************************************************************
117 User interacted with server list window.
118 **************************************************************************/
119 static int meta_severs_window_callback(struct widget *pWindow)
121 return -1;
124 /**************************************************************************
125 Close servers dialog.
126 **************************************************************************/
127 static int exit_meta_severs_dlg_callback(struct widget *pWidget)
129 if (Main.event.button.button == SDL_BUTTON_LEFT) {
130 queue_flush();
132 server_scan_finish(pServer_scan);
133 pServer_scan = NULL;
134 pServer_list = NULL;
136 set_client_page(PAGE_NETWORK);
137 meswin_dialog_popup(TRUE);
139 return -1;
143 /**************************************************************************
144 Server selected from dialog.
145 **************************************************************************/
146 static int sellect_meta_severs_callback(struct widget *pWidget)
148 if (Main.event.button.button == SDL_BUTTON_LEFT) {
149 struct server *pServer = (struct server *)pWidget->data.ptr;
151 sz_strlcpy(server_host, pServer->host);
152 server_port = pServer->port;
154 exit_meta_severs_dlg_callback(NULL);
156 return -1;
159 /**************************************************************************
160 Callback function for when there's an error in the server scan.
161 **************************************************************************/
162 static void server_scan_error(struct server_scan *scan,
163 const char *message)
165 output_window_append(ftc_client, message);
166 log_normal("%s", message);
168 switch (server_scan_get_type(scan)) {
169 case SERVER_SCAN_LOCAL:
170 server_scan_finish(pServer_scan);
171 pServer_scan = NULL;
172 pServer_list = NULL;
173 break;
174 case SERVER_SCAN_GLOBAL:
175 server_scan_finish(pServer_scan);
176 pServer_scan = NULL;
177 pServer_list = NULL;
178 break;
179 case SERVER_SCAN_LAST:
180 break;
184 /**************************************************************************
185 SDL wrapper on create_server_list(...) function witch add
186 same functionality for LAN server dettection.
187 WARING !: for LAN scan use "finish_lanserver_scan()" to free server list.
188 **************************************************************************/
189 static struct srv_list *sdl_create_server_list(bool lan)
191 struct srv_list *list = NULL;
192 int i;
194 if (lan) {
195 pServer_scan = server_scan_begin(SERVER_SCAN_LOCAL, server_scan_error);
196 } else {
197 pServer_scan = server_scan_begin(SERVER_SCAN_GLOBAL, server_scan_error);
200 if (!pServer_scan) {
201 return NULL;
204 SDL_Delay(5000);
206 for (i = 0; i < 100; i++) {
207 server_scan_poll(pServer_scan);
208 list = server_scan_get_list(pServer_scan);
209 if (list) {
210 break;
212 SDL_Delay(100);
215 return list;
218 /**************************************************************************
219 Open connection dialog for either meta or lan scan.
220 **************************************************************************/
221 void popup_connection_dialog(bool lan_scan)
223 SDL_Color bg_color = {255, 255, 255, 128};
225 char cBuf[512];
226 int w = 0, h = 0, count = 0, meta_h;
227 struct widget *pNewWidget, *pWindow, *pLabelWindow;
228 SDL_String16 *pStr;
229 SDL_Surface *pLogo;
230 SDL_Rect area, area2;
231 struct srv_list *srvrs;
233 queue_flush();
234 close_connection_dialog();
235 meswin_dialog_popdown();
237 /* Text Label */
238 pLabelWindow = create_window_skeleton(NULL, NULL, 0);
239 add_to_gui_list(ID_WINDOW, pLabelWindow);
241 area = pLabelWindow->area;
243 fc_snprintf(cBuf, sizeof(cBuf), _("Creating Server List..."));
244 pStr = create_str16_from_char(cBuf, adj_font(16));
245 pStr->style = TTF_STYLE_BOLD;
246 pStr->bgcol = (SDL_Color) {0, 0, 0, 0};
247 pNewWidget = create_iconlabel(NULL, pLabelWindow->dst, pStr,
248 (WF_RESTORE_BACKGROUND | WF_DRAW_TEXT_LABEL_WITH_SPACE));
249 add_to_gui_list(ID_LABEL, pNewWidget);
251 area.w = MAX(area.w, pNewWidget->size.w + (adj_size(60) -
252 (pLabelWindow->size.w - pLabelWindow->area.w)));
253 area.h += pNewWidget->size.h + (adj_size(30) -
254 (pLabelWindow->size.w - pLabelWindow->area.w));
256 resize_window(pLabelWindow, NULL, &bg_color,
257 (pLabelWindow->size.w - pLabelWindow->area.w) + area.w,
258 (pLabelWindow->size.h - pLabelWindow->area.h) + area.h);
260 area = pLabelWindow->area;
262 widget_set_position(pLabelWindow,
263 (Main.screen->w - pLabelWindow->size.w) / 2,
264 (Main.screen->h - pLabelWindow->size.h) / 2);
266 widget_set_area(pNewWidget, area);
267 widget_set_position(pNewWidget,
268 area.x + (area.w - pNewWidget->size.w)/2,
269 area.y + (area.h - pNewWidget->size.h)/2);
271 redraw_group(pNewWidget, pLabelWindow, TRUE);
272 flush_dirty();
274 /* create server list */
275 srvrs = sdl_create_server_list(lan_scan);
277 /* Copy list */
278 pServer_list = server_list_new();
279 fc_allocate_mutex(&srvrs->mutex);
280 server_list_iterate(srvrs->servers, pserver) {
281 server_list_append(pServer_list, pserver);
282 } server_list_iterate_end;
283 fc_release_mutex(&srvrs->mutex);
285 /* clear label */
286 popdown_window_group_dialog(pNewWidget, pLabelWindow);
288 meswin_dialog_popup(TRUE);
290 if(!pServer_list) {
291 if (lan_scan) {
292 output_window_append(ftc_client, _("No LAN servers found"));
293 } else {
294 output_window_append(ftc_client, _("No public servers found"));
296 set_client_page(PAGE_NETWORK);
297 return;
300 /* Server list window */
301 pMeta_Severs = fc_calloc(1, sizeof(struct ADVANCED_DLG));
303 pWindow = create_window_skeleton(NULL, NULL, 0);
304 pWindow->action = meta_severs_window_callback;
305 set_wstate(pWindow, FC_WS_NORMAL);
306 clear_wflag(pWindow, WF_DRAW_FRAME_AROUND_WIDGET);
307 if (lan_scan)
309 add_to_gui_list(ID_LAN_SERVERS_WINDOW, pWindow);
310 } else {
311 add_to_gui_list(ID_META_SERVERS_WINDOW, pWindow);
313 pMeta_Severs->pEndWidgetList = pWindow;
315 area = pWindow->area;
317 /* Cancel button */
318 pNewWidget = create_themeicon_button_from_chars(current_theme->CANCEL_Icon,
319 pWindow->dst, _("Cancel"),
320 adj_font(14), 0);
321 pNewWidget->action = exit_meta_severs_dlg_callback;
322 set_wstate(pNewWidget, FC_WS_NORMAL);
323 add_to_gui_list(ID_BUTTON, pNewWidget);
325 /* servers */
326 server_list_iterate(pServer_list, pServer) {
328 /* TRANS: "host.example.com Port 5556 Ver: 2.2.0 Running Players 3\n
329 * [server message]" */
330 fc_snprintf(cBuf, sizeof(cBuf), _("%s Port %d Ver: %s %s %s %d\n%s"),
331 pServer->host, pServer->port, pServer->version, _(pServer->state),
332 Q_("?count:Players"), pServer->nplayers, pServer->message);
334 pNewWidget = create_iconlabel_from_chars(NULL, pWindow->dst, cBuf, adj_font(10),
335 WF_FREE_STRING|WF_DRAW_TEXT_LABEL_WITH_SPACE|WF_RESTORE_BACKGROUND);
337 pNewWidget->string16->style |= SF_CENTER;
338 pNewWidget->string16->bgcol = (SDL_Color) {0, 0, 0, 0};
340 pNewWidget->action = sellect_meta_severs_callback;
341 set_wstate(pNewWidget, FC_WS_NORMAL);
342 pNewWidget->data.ptr = (void *)pServer;
344 add_to_gui_list(ID_BUTTON, pNewWidget);
346 w = MAX(w, pNewWidget->size.w);
347 h = MAX(h, pNewWidget->size.h);
348 count++;
350 if(count > 10) {
351 set_wflag(pNewWidget, WF_HIDDEN);
354 } server_list_iterate_end;
356 if(!count) {
357 if (lan_scan) {
358 output_window_append(ftc_client, _("No LAN servers found"));
359 } else {
360 output_window_append(ftc_client, _("No public servers found"));
362 set_client_page(PAGE_NETWORK);
363 return;
366 pMeta_Severs->pBeginWidgetList = pNewWidget;
367 pMeta_Severs->pBeginActiveWidgetList = pMeta_Severs->pBeginWidgetList;
368 pMeta_Severs->pEndActiveWidgetList = pMeta_Severs->pEndWidgetList->prev->prev;
369 pMeta_Severs->pActiveWidgetList = pMeta_Severs->pEndActiveWidgetList;
371 if (count > 10) {
372 meta_h = 10 * h;
374 count = create_vertical_scrollbar(pMeta_Severs, 1, 10, TRUE, TRUE);
375 w += count;
376 } else {
377 meta_h = count * h;
380 w += adj_size(20);
381 area2.h = meta_h;
383 meta_h += pMeta_Severs->pEndWidgetList->prev->size.h + adj_size(10) + adj_size(20);
385 pLogo = theme_get_background(theme, BACKGROUND_CONNECTDLG);
386 if (resize_window(pWindow , pLogo , NULL , w , meta_h)) {
387 FREESURFACE(pLogo);
390 area = pWindow->area;
392 widget_set_position(pWindow,
393 (Main.screen->w - w) / 2,
394 (Main.screen->h - meta_h) / 2);
396 w -= adj_size(20);
398 area2.w = w + 1;
400 if(pMeta_Severs->pScroll) {
401 w -= count;
404 /* exit button */
405 pNewWidget = pWindow->prev;
406 pNewWidget->size.x = area.x + area.w - pNewWidget->size.w - adj_size(10);
407 pNewWidget->size.y = area.y + area.h - pNewWidget->size.h - adj_size(10);
409 /* meta labels */
410 pNewWidget = pNewWidget->prev;
412 pNewWidget->size.x = area.x + adj_size(10);
413 pNewWidget->size.y = area.y + adj_size(10);
414 pNewWidget->size.w = w;
415 pNewWidget->size.h = h;
416 pNewWidget = convert_iconlabel_to_themeiconlabel2(pNewWidget);
418 pNewWidget = pNewWidget->prev;
419 while(pNewWidget)
422 pNewWidget->size.w = w;
423 pNewWidget->size.h = h;
424 pNewWidget->size.x = pNewWidget->next->size.x;
425 pNewWidget->size.y = pNewWidget->next->size.y + pNewWidget->next->size.h;
426 pNewWidget = convert_iconlabel_to_themeiconlabel2(pNewWidget);
428 if (pNewWidget == pMeta_Severs->pBeginActiveWidgetList) {
429 break;
431 pNewWidget = pNewWidget->prev;
434 if(pMeta_Severs->pScroll) {
435 setup_vertical_scrollbar_area(pMeta_Severs->pScroll,
436 area.x + area.w - adj_size(6),
437 pMeta_Severs->pEndActiveWidgetList->size.y,
438 area.h - adj_size(24) - pWindow->prev->size.h, TRUE);
441 /* -------------------- */
442 /* redraw */
444 widget_redraw(pWindow);
446 area2.x = pMeta_Severs->pEndActiveWidgetList->size.x;
447 area2.y = pMeta_Severs->pEndActiveWidgetList->size.y;
449 SDL_FillRectAlpha(pWindow->dst->surface, &area2, &bg_color);
451 putframe(pWindow->dst->surface,
452 area2.x - 1, area2.y - 1, area2.x + area2.w, area2.y + area2.h,
453 get_theme_color(COLOR_THEME_CONNECTDLG_INNERFRAME));
455 redraw_group(pMeta_Severs->pBeginWidgetList, pWindow->prev, 0);
457 putframe(pWindow->dst->surface,
458 pWindow->size.x, pWindow->size.y,
459 area.x + area.w - 1, area.y + area.h - 1,
460 get_theme_color(COLOR_THEME_CONNECTDLG_FRAME));
462 widget_flush(pWindow);
465 /**************************************************************************
466 User interacted with playername widget.
467 **************************************************************************/
468 static int convert_playername_callback(struct widget *pWidget)
470 if (Main.event.button.button == SDL_BUTTON_LEFT) {
471 char *tmp = convert_to_chars(pWidget->string16->text);
473 if (tmp) {
474 sz_strlcpy(user_name, tmp);
475 FC_FREE(tmp);
476 } else {
477 /* empty input -> restore previous content */
478 copy_chars_to_string16(pWidget->string16, user_name);
479 widget_redraw(pWidget);
480 widget_mark_dirty(pWidget);
481 flush_dirty();
484 return -1;
487 /**************************************************************************
488 User interacted with servername widget.
489 **************************************************************************/
490 static int convert_servername_callback(struct widget *pWidget)
492 if (Main.event.button.button == SDL_BUTTON_LEFT) {
493 char *tmp = convert_to_chars(pWidget->string16->text);
495 if (tmp) {
496 sz_strlcpy(server_host, tmp);
497 FC_FREE(tmp);
498 } else {
499 /* empty input -> restore previous content */
500 copy_chars_to_string16(pWidget->string16, server_host);
501 widget_redraw(pWidget);
502 widget_mark_dirty(pWidget);
503 flush_dirty();
506 return -1;
509 /**************************************************************************
510 User interacted with port number widget.
511 **************************************************************************/
512 static int convert_portnr_callback(struct widget *pWidget)
514 if (Main.event.button.button == SDL_BUTTON_LEFT) {
515 char pCharPort[6];
516 char *tmp = convert_to_chars(pWidget->string16->text);
518 if (tmp) {
519 sscanf(tmp, "%d", &server_port);
520 FC_FREE(tmp);
521 } else {
522 /* empty input -> restore previous content */
523 fc_snprintf(pCharPort, sizeof(pCharPort), "%d", server_port);
524 copy_chars_to_string16(pWidget->string16, pCharPort);
525 widget_redraw(pWidget);
526 widget_mark_dirty(pWidget);
527 flush_dirty();
530 return -1;
533 /**************************************************************************
534 User interacted with cancel -button
535 **************************************************************************/
536 static int cancel_connect_dlg_callback(struct widget *pWidget)
538 if (Main.event.button.button == SDL_BUTTON_LEFT) {
539 close_connection_dialog();
540 set_client_page(PAGE_MAIN);
542 return -1;
545 /**************************************************************************
546 Open dialog for joining to game.
547 **************************************************************************/
548 void popup_join_game_dialog()
550 char pCharPort[6];
551 struct widget *pBuf, *pWindow;
552 SDL_String16 *pPlayer_name = NULL;
553 SDL_String16 *pServer_name = NULL;
554 SDL_String16 *pPort_nr = NULL;
555 SDL_Surface *pLogo;
556 SDL_Rect area;
558 int start_x;
559 int pos_y;
560 int dialog_w, dialog_h;
562 queue_flush();
563 close_connection_dialog();
565 pConnectDlg = fc_calloc(1, sizeof(struct SMALL_DLG));
567 /* window */
568 pWindow = create_window_skeleton(NULL, NULL, 0);
569 add_to_gui_list(ID_WINDOW, pWindow);
570 pConnectDlg->pEndWidgetList = pWindow;
572 area = pWindow->area;
574 /* player name label */
575 pPlayer_name = create_str16_from_char(_("Player Name :"), adj_font(10));
576 pPlayer_name->fgcol = *get_theme_color(COLOR_THEME_JOINGAMEDLG_TEXT);
577 pBuf = create_iconlabel(NULL, pWindow->dst, pPlayer_name,
578 (WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
579 add_to_gui_list(ID_LABEL, pBuf);
580 area.h += pBuf->size.h + adj_size(20);
582 /* player name edit */
583 pBuf = create_edit_from_chars(NULL, pWindow->dst, user_name, adj_font(14), adj_size(210),
584 (WF_RESTORE_BACKGROUND|WF_FREE_DATA));
585 pBuf->action = convert_playername_callback;
586 set_wstate(pBuf, FC_WS_NORMAL);
587 add_to_gui_list(ID_PLAYER_NAME_EDIT, pBuf);
588 area.h += pBuf->size.h + adj_size(5);
590 /* server name label */
591 pServer_name = create_str16_from_char(_("Freeciv Server :"), adj_font(10));
592 pServer_name->fgcol = *get_theme_color(COLOR_THEME_JOINGAMEDLG_TEXT);
593 pBuf = create_iconlabel(NULL, pWindow->dst, pServer_name,
594 (WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
595 add_to_gui_list(ID_LABEL, pBuf);
596 area.h += pBuf->size.h + adj_size(5);
598 /* server name edit */
599 pBuf = create_edit_from_chars(NULL, pWindow->dst, server_host, adj_font(14), adj_size(210),
600 WF_RESTORE_BACKGROUND);
602 pBuf->action = convert_servername_callback;
603 set_wstate(pBuf, FC_WS_NORMAL);
604 add_to_gui_list(ID_SERVER_NAME_EDIT, pBuf);
605 area.h += pBuf->size.h + adj_size(5);
607 /* port label */
608 pPort_nr = create_str16_from_char(_("Port :"), adj_font(10));
609 pPort_nr->fgcol = *get_theme_color(COLOR_THEME_JOINGAMEDLG_TEXT);
610 pBuf = create_iconlabel(NULL, pWindow->dst, pPort_nr,
611 (WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
612 add_to_gui_list(ID_LABEL, pBuf);
613 area.h += pBuf->size.h + adj_size(5);
615 /* port edit */
616 fc_snprintf(pCharPort, sizeof(pCharPort), "%d", server_port);
618 pBuf = create_edit_from_chars(NULL, pWindow->dst, pCharPort, adj_font(14), adj_size(210),
619 WF_RESTORE_BACKGROUND);
621 pBuf->action = convert_portnr_callback;
622 set_wstate(pBuf, FC_WS_NORMAL);
623 add_to_gui_list(ID_PORT_EDIT, pBuf);
624 area.h += pBuf->size.h + adj_size(20);
626 /* Connect button */
627 pBuf = create_themeicon_button_from_chars(current_theme->OK_Icon, pWindow->dst,
628 _("Connect"), adj_font(14), 0);
629 pBuf->action = connect_callback;
630 set_wstate(pBuf, FC_WS_NORMAL);
631 pBuf->key = SDLK_RETURN;
632 add_to_gui_list(ID_CONNECT_BUTTON, pBuf);
634 /* Cancel button */
635 pBuf = create_themeicon_button_from_chars(current_theme->CANCEL_Icon, pWindow->dst,
636 _("Cancel"), adj_font(14), 0);
637 pBuf->action = cancel_connect_dlg_callback;
638 set_wstate(pBuf, FC_WS_NORMAL);
639 pBuf->key = SDLK_ESCAPE;
640 add_to_gui_list(ID_CANCEL_BUTTON, pBuf);
641 pBuf->size.w = MAX(pBuf->size.w, pBuf->next->size.w);
642 pBuf->next->size.w = pBuf->size.w;
643 area.h += pBuf->size.h + adj_size(10);
644 /* ------------------------------ */
646 pConnectDlg->pBeginWidgetList = pBuf;
648 dialog_w = MAX(adj_size(40) + pBuf->size.w * 2, adj_size(210)) + adj_size(80);
650 #ifdef SMALL_SCREEN
651 dialog_h = area.h + (pWindow->size.h - pWindow->area.h);
652 #else
653 dialog_h = area.h + (pWindow->size.h - pWindow->area.h);
654 #endif
656 pLogo = theme_get_background(theme, BACKGROUND_JOINGAMEDLG);
657 if (resize_window(pWindow, pLogo, NULL, dialog_w, dialog_h)) {
658 FREESURFACE(pLogo);
661 area = pWindow->area;
663 widget_set_position(pWindow,
664 (Main.screen->w - pWindow->size.w)/ 2,
665 (Main.screen->h - pWindow->size.h)/ 2 + adj_size(40));
667 /* player name label */
668 pBuf = pConnectDlg->pEndWidgetList->prev;
670 start_x = area.x + (area.w - pBuf->prev->size.w) / 2;
671 pos_y = area.y + adj_size(20);
673 pBuf->size.x = start_x + adj_size(5);
674 pBuf->size.y = pos_y;
676 pos_y += pBuf->size.h;
678 pBuf = pBuf->prev;
679 pBuf->size.x = start_x;
680 pBuf->size.y = pos_y;
682 pos_y += pBuf->size.h + adj_size(5);
684 /* server name label */
685 pBuf = pBuf->prev;
686 pBuf->size.x = start_x + adj_size(5);
687 pBuf->size.y = pos_y;
689 pos_y += pBuf->size.h;
691 /* server name edit */
692 pBuf = pBuf->prev;
693 pBuf->size.x = start_x;
694 pBuf->size.y = pos_y;
696 pos_y += pBuf->size.h + adj_size(5);
698 /* port label */
699 pBuf = pBuf->prev;
700 pBuf->size.x = start_x + adj_size(5);
701 pBuf->size.y = pos_y;
703 pos_y += pBuf->size.h;
705 /* port edit */
706 pBuf = pBuf->prev;
707 pBuf->size.x = start_x;
708 pBuf->size.y = pos_y;
710 pos_y += pBuf->size.h + adj_size(20);
712 /* connect button */
713 pBuf = pBuf->prev;
714 pBuf->size.x = area.x + (dialog_w - (adj_size(40) + pBuf->size.w * 2)) / 2;
715 pBuf->size.y = pos_y;
717 /* cancel button */
718 pBuf = pBuf->prev;
719 pBuf->size.x = pBuf->next->size.x + pBuf->size.w + adj_size(40);
720 pBuf->size.y = pos_y;
722 redraw_group(pConnectDlg->pBeginWidgetList, pConnectDlg->pEndWidgetList, FALSE);
724 flush_all();
727 /**************************************************************************
728 User interacted with password widget
729 **************************************************************************/
730 static int convert_passwd_callback(struct widget *pWidget)
732 if (Main.event.button.button == SDL_BUTTON_LEFT) {
733 char *tmp = convert_to_chars(pWidget->string16->text);
734 if(tmp) {
735 fc_snprintf(password, MAX_LEN_NAME, "%s", tmp);
736 FC_FREE(tmp);
739 return -1;
742 /**************************************************************************
743 User interacted with "Next" -button after entering password.
744 **************************************************************************/
745 static int send_passwd_callback(struct widget *pWidget)
747 if (Main.event.button.button == SDL_BUTTON_LEFT) {
748 struct packet_authentication_reply reply;
750 sz_strlcpy(reply.password, password);
752 memset(password, 0, MAX_LEN_NAME);
753 password[0] = '\0';
755 set_wstate(pWidget, FC_WS_DISABLED);
757 widget_redraw(pWidget);
759 widget_mark_dirty(pWidget);
761 flush_dirty();
763 send_packet_authentication_reply(&client.conn, &reply);
765 return -1;
768 /**************************************************************************
769 Open password dialog.
770 **************************************************************************/
771 static int cancel_passwd_callback(struct widget *pWidget)
773 memset(password, 0, MAX_LEN_NAME);
774 password[0] = '\0';
775 disconnect_from_server();
776 return cancel_connect_dlg_callback(pWidget);
779 /**************************************************************************
781 **************************************************************************/
782 static void popup_user_passwd_dialog(const char *pMessage)
784 struct widget *pBuf, *pWindow;
785 SDL_String16 *pLabelStr = NULL;
786 SDL_Surface *pBackground;
787 int start_x, start_y;
788 int start_button_y;
789 SDL_Rect area;
791 queue_flush();
792 close_connection_dialog();
794 pConnectDlg = fc_calloc(1, sizeof(struct SMALL_DLG));
796 pWindow = create_window_skeleton(NULL, NULL, 0);
797 add_to_gui_list(ID_WINDOW, pWindow);
798 pConnectDlg->pEndWidgetList = pWindow;
800 area = pWindow->area;
802 /* text label */
803 pLabelStr = create_str16_from_char(pMessage, adj_font(12));
804 pLabelStr->fgcol = *get_theme_color(COLOR_THEME_USERPASSWDDLG_TEXT);
805 pBuf = create_iconlabel(NULL, pWindow->dst, pLabelStr,
806 (WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
807 add_to_gui_list(ID_LABEL, pBuf);
808 area.h += adj_size(10) + pBuf->size.h + adj_size(5);
810 /* password edit */
811 pBuf = create_edit(NULL, pWindow->dst, create_string16(NULL, 0, adj_font(16)),
812 adj_size(210),
813 (WF_PASSWD_EDIT|WF_RESTORE_BACKGROUND|WF_FREE_DATA));
814 pBuf->action = convert_passwd_callback;
815 set_wstate(pBuf, FC_WS_NORMAL);
816 add_to_gui_list(ID_EDIT, pBuf);
817 area.h += pBuf->size.h + adj_size(10);
819 /* Next button */
820 pBuf = create_themeicon_button_from_chars(current_theme->OK_Icon, pWindow->dst,
821 _("Next"), adj_font(14), 0);
822 pBuf->action = send_passwd_callback;
823 set_wstate(pBuf, FC_WS_NORMAL);
824 pBuf->key = SDLK_RETURN;
825 add_to_gui_list(ID_BUTTON, pBuf);
827 /* Cancel button */
828 pBuf = create_themeicon_button_from_chars(current_theme->CANCEL_Icon, pWindow->dst,
829 _("Cancel"), adj_font(14), 0);
830 pBuf->action = cancel_passwd_callback;
831 set_wstate(pBuf, FC_WS_NORMAL);
832 pBuf->key = SDLK_ESCAPE;
833 add_to_gui_list(ID_CANCEL_BUTTON, pBuf);
834 pBuf->size.w = MAX(pBuf->size.w, pBuf->next->size.w);
835 pBuf->next->size.w = pBuf->size.w;
836 area.h += pBuf->size.h + adj_size(10);
838 /* ------------------------------ */
840 pConnectDlg->pBeginWidgetList = pBuf;
842 area.w = MAX(area.w, pBuf->size.w * 2 + adj_size(40));
843 area.w = MAX(area.w, adj_size(210) - (pWindow->size.w - pWindow->area.w));
844 area.w = MAX(area.w, pWindow->prev->size.w);
845 area.w += adj_size(80);
847 pBackground = theme_get_background(theme, BACKGROUND_USERPASSWDDLG);
848 if (resize_window(pWindow, pBackground, NULL,
849 (pWindow->size.w - pWindow->area.w) + area.w,
850 (pWindow->size.h - pWindow->area.h) + area.h)) {
851 FREESURFACE(pBackground);
854 area = pWindow->area;
856 widget_set_position(pWindow,
857 (Main.screen->w - pWindow->size.w)/ 2,
858 (Main.screen->h - pWindow->size.h)/ 2);
860 /* text label */
861 pBuf = pConnectDlg->pEndWidgetList->prev;
863 start_x = area.x + (area.w - pBuf->size.w) / 2;
864 start_y = area.y + adj_size(10);
866 widget_set_area(pBuf, area);
867 widget_set_position(pBuf, start_x, start_y);
869 start_y += pBuf->size.h + adj_size(5);
871 /* password edit */
872 pBuf = pBuf->prev;
873 start_x = area.x + (area.w - pBuf->size.w) / 2;
875 widget_set_area(pBuf, area);
876 widget_set_position(pBuf, start_x, start_y);
878 /* --------------------------------- */
879 start_button_y = pBuf->size.y + pBuf->size.h + adj_size(10);
881 /* connect button */
882 pBuf = pBuf->prev;
883 widget_set_area(pBuf, area);
884 widget_set_position(pBuf,
885 area.x + (area.w - (adj_size(40) + pBuf->size.w * 2)) / 2,
886 start_button_y);
888 /* cancel button */
889 pBuf = pBuf->prev;
890 widget_set_area(pBuf, area);
891 widget_set_position(pBuf,
892 pBuf->next->size.x + pBuf->size.w + adj_size(40),
893 start_button_y);
895 redraw_group(pConnectDlg->pBeginWidgetList, pConnectDlg->pEndWidgetList, FALSE);
897 flush_all();
901 /**************************************************************************
902 New Password
903 **************************************************************************/
904 static int convert_first_passwd_callback(struct widget *pWidget)
906 if (Main.event.button.button == SDL_BUTTON_LEFT) {
907 char *tmp = convert_to_chars(pWidget->string16->text);
909 if(tmp) {
910 fc_snprintf(password, MAX_LEN_NAME, "%s", tmp);
911 FC_FREE(tmp);
912 set_wstate(pWidget->prev, FC_WS_NORMAL);
913 widget_redraw(pWidget->prev);
914 widget_flush(pWidget->prev);
917 return -1;
920 /**************************************************************************
921 Verify Password
922 **************************************************************************/
923 static int convert_secound_passwd_callback(struct widget *pWidget)
925 if (Main.event.button.button == SDL_BUTTON_LEFT) {
926 char *tmp = convert_to_chars(pWidget->string16->text);
928 if (tmp && strncmp(password, tmp, MAX_LEN_NAME) == 0) {
929 set_wstate(pWidget->prev, FC_WS_NORMAL); /* next button */
930 widget_redraw(pWidget->prev);
931 widget_flush(pWidget->prev);
932 } else {
933 memset(password, 0, MAX_LEN_NAME);
934 password[0] = '\0';
936 FC_FREE(pWidget->next->string16->text);/* first edit */
937 FC_FREE(pWidget->string16->text); /* secound edit */
939 popup_new_user_passwd_dialog(_("Passwords don't match, enter password."));
942 return -1;
945 /**************************************************************************
946 Open dialog for new password.
947 **************************************************************************/
948 static void popup_new_user_passwd_dialog(const char *pMessage)
950 struct widget *pBuf, *pWindow;
951 SDL_String16 *pLabelStr = NULL;
952 SDL_Surface *pBackground;
953 int start_x, start_y;
954 int start_button_y;
955 SDL_Rect area;
957 queue_flush();
958 close_connection_dialog();
960 pConnectDlg = fc_calloc(1, sizeof(struct SMALL_DLG));
962 pWindow = create_window_skeleton(NULL, NULL, 0);
963 add_to_gui_list(ID_WINDOW, pWindow);
964 pConnectDlg->pEndWidgetList = pWindow;
966 area = pWindow->area;
968 /* text label */
969 pLabelStr = create_str16_from_char(pMessage, adj_font(12));
970 pLabelStr->fgcol = *get_theme_color(COLOR_THEME_USERPASSWDDLG_TEXT);
971 pBuf = create_iconlabel(NULL, pWindow->dst, pLabelStr,
972 (WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
973 add_to_gui_list(ID_LABEL, pBuf);
974 area.h += adj_size(10) + pBuf->size.h + adj_size(5);
976 /* password edit */
977 pBuf = create_edit(NULL, pWindow->dst, create_string16(NULL, 0, adj_font(16)),
978 adj_size(210),
979 (WF_PASSWD_EDIT|WF_RESTORE_BACKGROUND|WF_FREE_DATA));
980 pBuf->action = convert_first_passwd_callback;
981 set_wstate(pBuf, FC_WS_NORMAL);
982 add_to_gui_list(ID_EDIT, pBuf);
983 area.h += pBuf->size.h + adj_size(5);
985 /* second password edit */
986 pBuf = create_edit(NULL, pWindow->dst, create_string16(NULL, 0, adj_font(16)),
987 adj_size(210),
988 (WF_PASSWD_EDIT|WF_RESTORE_BACKGROUND|WF_FREE_DATA));
989 pBuf->action = convert_secound_passwd_callback;
990 add_to_gui_list(ID_EDIT, pBuf);
991 area.h += pBuf->size.h + adj_size(10);
993 /* Next button */
994 pBuf = create_themeicon_button_from_chars(current_theme->OK_Icon, pWindow->dst,
995 _("Next"), adj_font(14), 0);
996 pBuf->action = send_passwd_callback;
997 pBuf->key = SDLK_RETURN;
998 add_to_gui_list(ID_BUTTON, pBuf);
1000 /* Cancel button */
1001 pBuf = create_themeicon_button_from_chars(current_theme->CANCEL_Icon, pWindow->dst,
1002 _("Cancel"), adj_font(14), 0);
1003 pBuf->action = cancel_passwd_callback;
1004 set_wstate(pBuf, FC_WS_NORMAL);
1005 pBuf->key = SDLK_ESCAPE;
1006 add_to_gui_list(ID_CANCEL_BUTTON, pBuf);
1007 pBuf->size.w = MAX(pBuf->size.w, pBuf->next->size.w);
1008 pBuf->next->size.w = pBuf->size.w;
1009 area.h += pBuf->size.h + adj_size(10);
1011 /* ------------------------------ */
1013 pConnectDlg->pBeginWidgetList = pBuf;
1015 area.w = pBuf->size.w * 2 + adj_size(40);
1016 area.w = MAX(area.w, adj_size(210) - (pWindow->size.w - pWindow->area.w));
1017 area.w = MAX(area.w, pWindow->prev->size.w);
1018 area.w += adj_size(80);
1020 pBackground = theme_get_background(theme, BACKGROUND_USERPASSWDDLG);
1021 if (resize_window(pWindow, pBackground, NULL,
1022 (pWindow->size.w - pWindow->area.w) + area.w,
1023 (pWindow->size.h - pWindow->area.h) + area.h)) {
1024 FREESURFACE(pBackground);
1027 area = pWindow->area;
1029 widget_set_position(pWindow,
1030 (Main.screen->w - pWindow->size.w)/ 2,
1031 (Main.screen->h - pWindow->size.h)/ 2);
1033 /* text label */
1034 pBuf = pConnectDlg->pEndWidgetList->prev;
1036 start_x = area.x + (area.w - pBuf->size.w) / 2;
1037 start_y = area.y + adj_size(10);
1039 widget_set_area(pBuf, area);
1040 widget_set_position(pBuf, start_x, start_y);
1042 start_y += pBuf->size.h + adj_size(5);
1044 /* passwd edit */
1045 pBuf = pBuf->prev;
1046 start_x = area.x + (area.w - pBuf->size.w) / 2;
1048 widget_set_area(pBuf, area);
1049 widget_set_position(pBuf, start_x, start_y);
1051 start_y += pBuf->size.h + adj_size(5);
1053 /* retype passwd */
1054 pBuf = pBuf->prev;
1055 widget_set_area(pBuf, area);
1056 widget_set_position(pBuf, start_x, start_y);
1058 start_button_y = pBuf->size.y + pBuf->size.h + adj_size(10);
1060 /* connect button */
1061 pBuf = pBuf->prev;
1062 widget_set_area(pBuf, area);
1063 widget_set_position(pBuf,
1064 area.x + (area.w - (adj_size(40) + pBuf->size.w * 2)) / 2,
1065 start_button_y);
1067 /* cancel button */
1068 pBuf = pBuf->prev;
1069 widget_set_area(pBuf, area);
1070 widget_set_position(pBuf,
1071 pBuf->next->size.x + pBuf->size.w + adj_size(40),
1072 start_button_y);
1074 redraw_group(pConnectDlg->pBeginWidgetList, pConnectDlg->pEndWidgetList, FALSE);
1076 flush_all();
1079 /* ======================================================================== */
1081 /**************************************************************************
1082 close and destroy the dialog.
1083 **************************************************************************/
1084 void close_connection_dialog(void)
1086 if(pConnectDlg) {
1087 popdown_window_group_dialog(pConnectDlg->pBeginWidgetList,
1088 pConnectDlg->pEndWidgetList);
1089 FC_FREE(pConnectDlg);
1091 if(pMeta_Severs) {
1092 popdown_window_group_dialog(pMeta_Severs->pBeginWidgetList,
1093 pMeta_Severs->pEndWidgetList);
1094 FC_FREE(pMeta_Severs->pScroll);
1095 FC_FREE(pMeta_Severs);
1096 if(pServer_list) {
1097 server_scan_finish(pServer_scan);
1098 pServer_scan = NULL;
1099 pServer_list = NULL;
1104 /**************************************************************************
1105 popup passwd dialog depending on what type of authentication request the
1106 server is making.
1107 **************************************************************************/
1108 void handle_authentication_req(enum authentication_type type,
1109 const char *message)
1111 switch (type) {
1112 case AUTH_NEWUSER_FIRST:
1113 case AUTH_NEWUSER_RETRY:
1114 popup_new_user_passwd_dialog(message);
1115 return;
1116 case AUTH_LOGIN_FIRST:
1117 /* if we magically have a password already present in 'password'
1118 * then, use that and skip the password entry dialog */
1119 if (password[0] != '\0') {
1120 struct packet_authentication_reply reply;
1122 sz_strlcpy(reply.password, password);
1123 send_packet_authentication_reply(&client.conn, &reply);
1124 return;
1125 } else {
1126 popup_user_passwd_dialog(message);
1128 return;
1129 case AUTH_LOGIN_RETRY:
1130 popup_user_passwd_dialog(message);
1131 return;
1134 log_error("Not supported authentication type %d: %s.", type, message);
1137 /**************************************************************************
1138 Provide an interface for connecting to a Freeciv server.
1139 sdl-client does it as popup main start menu which != connecting dlg.
1140 **************************************************************************/
1141 void server_connect(void)